Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Minor changes and bugfixes #33

Merged
merged 24 commits into from
Jan 14, 2025
Merged
Show file tree
Hide file tree
Changes from 21 commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
3333be2
Added borders for sticky tds
jeppekroghitk Jan 10, 2025
e152982
Removed tickettype from table
jeppekroghitk Jan 10, 2025
c0ae2b2
Added task to tippy popover
jeppekroghitk Jan 10, 2025
99b0dca
Added task text only when todo is not a task, and corrected borders
jeppekroghitk Jan 10, 2025
fe58611
Added include weekend checkbox when copying entries
jeppekroghitk Jan 10, 2025
9ce4e1e
Added weekends to be optional when copying entry forward
jeppekroghitk Jan 13, 2025
9e67dfa
Coding standards
jeppekroghitk Jan 13, 2025
b9837ff
Submit form when writing comment on timelog
jeppekroghitk Jan 13, 2025
1ff79d9
Unchecking include weekends when closing modal
jeppekroghitk Jan 13, 2025
8d57331
Updated changelog
jeppekroghitk Jan 13, 2025
0ba4797
Coding standards
jeppekroghitk Jan 13, 2025
df61a5b
Reverted phpstan config
jeppekroghitk Jan 13, 2025
d48ab16
Coding standards
jeppekroghitk Jan 13, 2025
fd3ae1a
Increased memory limit for code-analysis action
jeppekroghitk Jan 13, 2025
cc5dfc9
Formatted blade
jeppekroghitk Jan 13, 2025
a5c8e23
Formatted blade
jeppekroghitk Jan 13, 2025
157669c
Fixed error in blade
jeppekroghitk Jan 13, 2025
436f305
Changed approach when deleting timelog, to handling things frontend
jeppekroghitk Jan 13, 2025
d34e5de
Updated changelog
jeppekroghitk Jan 13, 2025
b65e0e9
Coding standards
jeppekroghitk Jan 13, 2025
187fd0a
Formatted blade
jeppekroghitk Jan 13, 2025
38d6db9
Added translations and comment describing choice regarding displaying…
jeppekroghitk Jan 14, 2025
9e41789
Coding standards
jeppekroghitk Jan 14, 2025
02fde95
Formatted blade
jeppekroghitk Jan 14, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,11 @@

## [Unreleased]

* [PR-33](https://github.com/ITK-Leantime/leantime-timetable/pull/33)
* Made weekends optional when copying an entry forward
* Enter now submits the entry when creating or editing
* Now only updating frontend when deleting timelog

## [3.0.0] - 2025-01-10

* [PR-31](https://github.com/ITK-Leantime/leantime-timetable/pull/31)
Expand Down
57 changes: 33 additions & 24 deletions Controllers/TimeTable.php
Original file line number Diff line number Diff line change
Expand Up @@ -85,60 +85,69 @@ public function get(): Response
$searchTermForFilter = null;
$now = CarbonImmutable::now();
$ticketCacheExpiration = $this->settings->getSetting('itk-leantime-timetable.ticketCacheExpiration') ?? 1200;
$fromDate = CarbonImmutable::now()->startOfWeek()->startOfDay();
$toDate = CarbonImmutable::now()->endOfWeek()->startOfDay();

try {
if (isset($_GET['fromDate']) && $_GET['fromDate'] !== '') {
if ($_GET['fromDate'][0] === '+' || $_GET['fromDate'][0] === '-') {
// If relative date format
$fromDate = CarbonImmutable::now()->startOfDay()->modify($_GET['fromDate']);
} else {
// Try specific date format
$fromDate = CarbonImmutable::createFromFormat('Y-m-d', $_GET['fromDate'])->startOfDay();
if ($fromDate === false) {
// If 'Y-m-d' format fails, try 'd/m/Y' format
$fromDate = CarbonImmutable::createFromFormat('d/m/Y', $_GET['fromDate'])->startOfDay();
$fromDate = CarbonImmutable::createFromFormat('Y-m-d', $_GET['fromDate']);
if ($fromDate !== false) {
$fromDate = $fromDate->startOfDay();
} else {
$fromDate = CarbonImmutable::createFromFormat('d/m/Y', $_GET['fromDate']);
$fromDate = $fromDate !== false ? $fromDate->startOfDay() : CarbonImmutable::now()->startOfWeek()->startOfDay();
}
}
} else {
// Default to start of current week
$fromDate = CarbonImmutable::now()->startOfWeek()->startOfDay();
}

if (isset($_GET['toDate']) && $_GET['toDate'] !== '') {
if ($_GET['toDate'][0] === '+' || $_GET['toDate'][0] === '-') {
// If relative date format
$toDate = CarbonImmutable::now()->startOfDay()->modify($_GET['toDate']);
} else {
// Try specific date format
$toDate = CarbonImmutable::createFromFormat('Y-m-d', $_GET['toDate'])->startOfDay();
if ($toDate === false) {
// If 'Y-m-d' format fails, try 'd/m/Y' format
$toDate = CarbonImmutable::createFromFormat('d/m/Y', $_GET['toDate'])->startOfDay();
$toDate = CarbonImmutable::createFromFormat('Y-m-d', $_GET['toDate']);
if ($toDate !== false) {
$toDate = $toDate->startOfDay();
} else {
$toDate = CarbonImmutable::createFromFormat('d/m/Y', $_GET['toDate']);
$toDate = $toDate !== false ? $toDate->startOfDay() : CarbonImmutable::now()->endOfWeek()->startOfDay();
}
}
} else {
// Default to end of current week
$toDate = CarbonImmutable::now()->endOfWeek()->startOfDay();
}
} catch (\Exception $e) {
// Log error
Log::error($e);

// Assign fallback date span
$fromDate = CarbonImmutable::now()->startOfWeek()->startOfDay();
$toDate = CarbonImmutable::now()->endOfWeek()->startOfDay();
}

$weekStartDateDb = $fromDate->setToDbTimezone();
$weekEndDateDb = $toDate->setToDbTimezone();
if ($fromDate instanceof CarbonImmutable) {
$weekStartDateDb = $fromDate->setToDbTimezone();
} else {
// Handle invalid $fromDate gracefully
$weekStartDateDb = null; // Or define your fallback behavior
}

if ($toDate instanceof CarbonImmutable) {
$weekEndDateDb = $toDate->setToDbTimezone();
} else {
// Handle invalid $toDate gracefully
$weekEndDateDb = null; // Or define your fallback behavior
}

$this->template->assign('currentSearchTerm', $searchTermForFilter);

$days = explode(',', mb_strtolower($this->language->__('language.dayNames')));
$days[] = array_shift($days);

$weekDates = [];
$dateIterator = $fromDate->setToUserTimezone()->copy();
if ($fromDate instanceof CarbonImmutable) {
$dateIterator = $fromDate->setToUserTimezone()->copy();
} else {
// Handle invalid $fromDate gracefully
$dateIterator = null; // Or define fallback behavior
}

while ($dateIterator <= $toDate) {
$dayOfWeek = strtolower($dateIterator->locale(session('usersettings.language'))->dayName);
Expand Down
14 changes: 10 additions & 4 deletions Helpers/TimeTableActionHandler.php
Original file line number Diff line number Diff line change
Expand Up @@ -186,11 +186,17 @@ public function copyEntryForward(array $postData, string $redirectUrl): string
$hours = $postData['entryCopyHours'];
$description = $postData['entryCopyDescription'];


// Move to the next day to skip the first date
$currentDate = $copyFromDate->addDay();

while ($currentDate <= $copyToDate) {
$currentDate = $copyFromDate;
$currentDate->addDay();
$copyToDateUserTimezone = $copyToDate->setToUserTimezone();
while ($currentDate <= $copyToDateUserTimezone) {
$currentDateUserTimezone = $currentDate->setToUserTimezone();
// Skip weekends if 'entryCopyWeekend' is not set
if (!isset($postData['entryCopyWeekend']) && ($currentDateUserTimezone->isSaturday() || $currentDateUserTimezone->isSunday())) {
$currentDate = $currentDate->addDay();
continue;
}
$values = [
'userId' => session('userdata.id'),
'ticketId' => $ticketId,
Expand Down
1 change: 1 addition & 0 deletions Language/da-DK.ini
Original file line number Diff line number Diff line change
Expand Up @@ -22,3 +22,4 @@ timeTable.button_show_this_week="Vis denne uge"
timeTable.hours_left="Resterende timer:"
timeTable.entry_copy_button_close="Annuller"
timeTable.entry_copy_button_apply="Kopier"
timeTable.update_to_show_correct_sums="Opdater siden for at få vist de korrekte summer"
1 change: 1 addition & 0 deletions Language/en-US.ini
Original file line number Diff line number Diff line change
Expand Up @@ -22,3 +22,4 @@ timeTable.button_show_this_week="Show this week"
timeTable.hours_left="Hours left:"
timeTable.entry_copy_button_close="Cancel"
timeTable.entry_copy_button_apply="Copy"
timeTable.update_to_show_correct_sums="Please reload the page to get the correct sums"
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,8 @@ docker run --rm --volume "$PWD:/app" --workdir /app peterdavehello/shellcheck sh
### Code analysis

```shell name=code-analysis
docker run --interactive --rm --volume ${PWD}:/app itkdev/php8.3-fpm:latest composer code-analysis
# This analysis takes a bit more than the default allocated ram.
docker run --interactive --rm --volume ${PWD}:/app --env PHP_MEMORY_LIMIT=256M itkdev/php8.3-fpm:latest composer code-analysis
```

## Test release build
Expand Down
31 changes: 20 additions & 11 deletions Repositories/TimeTable.php
Original file line number Diff line number Diff line change
Expand Up @@ -53,10 +53,18 @@ public function getUniqueTicketIds(CarbonInterface $dateFrom, CarbonInterface $d

return $values;
}

/**
* @return array<array<string, string>>
* getTimesheetByTicketIdAndWorkDate - Retrieves timesheet data based on a given ticket ID and work date,
* optionally filtering by a search term.
*
* @access public
* @param string $ticketId The ticket ID to filter the timesheet data.
* @param CarbonInterface $workDate The specific work date to filter the timesheet data.
* @param string|null $searchTerm An optional search term to further filter results by ticket ID or headline.
* @return array<string, mixed> Returns an array of matching timesheet data.
*/
public function getTimesheetByTicketIdAndWorkDate(string $ticketId, CarbonImmutable $workDate, ?string $searchTerm): array
public function getTimesheetByTicketIdAndWorkDate(string $ticketId, CarbonInterface $workDate, ?string $searchTerm): array
{

$searchTermQuery = isset($searchTerm)
Expand Down Expand Up @@ -110,7 +118,7 @@ public function getTimesheetByTicketIdAndWorkDate(string $ticketId, CarbonImmuta
* @return void
* @access public
*/
public function updateOrAddTimelogOnTicket(array $values, int $originalId = null): void
public function updateOrAddTimelogOnTicket(array $values, ?int $originalId = null): void
{
$sql = 'SELECT * FROM zp_timesheets WHERE ticketId = :ticketId AND workDate = :date AND userId = :userId';

Expand Down Expand Up @@ -180,14 +188,15 @@ public function updateOrAddTimelogOnTicket(array $values, int $originalId = null
* If an entry for the same date, ticket, and user already exists, it checks
* whether the entry should be overwritten or prevents duplicate insertion.
*
* @param array $values An associative array containing the following keys:
* - 'userId' (int): The ID of the user creating the timelog.
* - 'ticketId' (int): The ID of the ticket associated with the timelog.
* - 'workDate' (DateTime): The date and time the timelog is being created for.
* - 'hours' (float): The number of hours being logged.
* - 'description' (string): The description of the work done.
* - 'kind' (string): The type of work being logged.
* - 'entryCopyOverwrite' (string, optional): A flag to indicate if existing entries should be overwritten.
* @param array<string, mixed> $values An associative array containing the following keys:
* - 'userId' (int): The ID of the user creating the timelog.
* - 'ticketId' (int): The ID of the ticket associated with the timelog.
* - 'workDate' (DateTime): The date and time the timelog is being created for.
* - 'hours' (float): The number of hours being logged.
* - 'description' (string): The description of the work done.
* - 'kind' (string): The type of work being logged.
* - 'entryCopyOverwrite' (string|null, optional): A flag to indicate if existing entries should be overwritten.
*
* @return void
*/
public function addTimelogOnTicket(array $values)
Expand Down
2 changes: 1 addition & 1 deletion Services/TimeTable.php
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ public function updateOrAddTimelogOnTicket(array $values, int $originalId): void
/**
* Adds a timelog to a ticket.
*
* @param array $values The data required to add the timelog on the ticket.
* @param array<string, mixed> $values The data required to add the timelog on the ticket.
* @return void
*/
public function addTimelogOnTicket(array $values)
Expand Down
26 changes: 15 additions & 11 deletions Templates/timetable.blade.php
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@
class="timetable-to-today btn btn-default">{{ __('timeTable.button_show_this_week') }}</button>
</div>
</form>
<p class="recently-deleted-timelog-info hidden"><i class="fas fa-info-circle"></i>
{{ __('timeTable.update_to_show_correct_sums') }}</p>
<div class="timetable-scroll-container">
<table id="timetable" class="table">
<thead>
Expand Down Expand Up @@ -67,12 +69,9 @@ class="timetable-to-today btn btn-default">{{ __('timeTable.button_show_this_wee
@foreach ($timesheetsByTicket as $ticketId => $timesheet)
<tr data-ticketId="{{ $ticketId }}">
<td class="ticket-title" scope="row"><a href="{{ $timesheet['ticketLink'] }}"
data-tippy-content="#{{ $timesheet['ticketId'] }} - {{ $timesheet['ticketTitle'] }}"
data-tippy-content="#{{ $timesheet['ticketId'] }} - {{ $timesheet['ticketTitle'] }} {{ $timesheet['ticketType'] !== 'task' ? '[ ' . $timesheet['ticketType'] . ' ]' : '' }} "
data-tippy-placement="top">{{ $timesheet['ticketTitle'] }}</a>
<span>{{ $timesheet['projectName'] }}</span>
<?php if ($timesheet['ticketType'] !== "task"): ?>
<small>(<?php echo $timesheet['ticketType']; ?>)</small>
<?php endif; ?>
</td>
<?php $rowTotal = 0; ?>
<!-- initializing row total -->
Expand Down Expand Up @@ -127,10 +126,9 @@ class="timetable-edit-entry {{ $weekendClass }} {{ $todayClass }} {{ $newWeekCla
</tr>
@else
<!-- A little something for when the week has no logs -->
<tr class="empty-row"">
<td class=" empty-row"
colspan="{{ count($weekDates) + 2 }}">
{{ __("It seems the 'WORK-IT' fairy forgot to sprinkle her magic dust here! 🧚‍🪄✨") }}
<tr class="empty-row">
<td class="empty-row" colspan="{{ count($weekDates) + 2 }}">
{{ __("It seems the 'WORK-IT' fairy forgot to sprinkle her magic dust here! 🧚‍🪄✨") }}
</td>
</tr>
<tr>
Expand Down Expand Up @@ -222,9 +220,15 @@ class="timetable-modal-submit btn btn-primary">{{ __('timeTable.button_modal_sav
<input type="hidden" name="entryCopyToDate" />
<p class="entry-copy-headline"></p>
<p class="entry-copy-text"></p>
<div class="entry-copy-overwrite-checkbox">
<input type="checkbox" name="entryCopyOverwrite" id="entry-copy-overwrite" />
<label for="entry-copy-overwrite"><small>Overskriv allerede registrerede felter</small></label>
<div class="entry-copy-checkboxes">
<div class="entry-copy-overwrite-checkbox">
<input type="checkbox" name="entryCopyOverwrite" id="entry-copy-overwrite" />
<label for="entry-copy-overwrite"><small>Overskriv allerede registrerede felter</small></label>
</div>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

{{ __("Overskriv allerede registrerede felter") }}

<div class="entry-copy-weekend-checkbox">
<input type="checkbox" name="entryCopyWeekend" id="entry-copy-weekend" />
<label for="entry-copy-weekend"><small>Inkluder weekender</small></label>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

{{ __("Inkluder weekender") }}

</div>
</div>
<div class="buttons flex-container gap-1">
<button type="button"
Expand Down
57 changes: 46 additions & 11 deletions assets/timeTable.css
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@
--itk-color-success-100: hsla(141, 84%, 93%, 1);
--itk-color-danger: hsla(0, 72%, 51%, 1);
--itk-color-danger-800: hsla(0, 70%, 35%, 1);
--itk-color-info: hsla(45, 90%, 51%, 1);
--itk-color-info-800: hsla(45, 80%, 35%, 1);
--itk-color-white: white;
--itk-color-gray-50: hsla(210, 40%, 98%, 1);
--itk-color-gray-100: hsla(214, 32%, 91%, 1);
Expand All @@ -39,6 +41,9 @@
}

.timetable {
.recently-deleted-timelog-info > i {
color: var(--itk-color-info);
}
.timetable-scroll-container {
overflow-x: auto;
}
Expand Down Expand Up @@ -70,7 +75,7 @@
left: 0;
width: 20px;
height: 20px;
background-color: #ccc;
background-color: var(--itk-border-color);
border-radius: 50%;
transform: translate(-50%, -50%);
display: flex;
Expand Down Expand Up @@ -123,8 +128,8 @@
z-index: 2;
}

th:last-child::before,
td:last-child::before {
th:last-child::after,
td:last-child::after {
content: "";
position: absolute;
top: 0;
Expand Down Expand Up @@ -430,7 +435,7 @@
width: 10px;
height: 18px;
top: calc(50% - 9px);
left: calc(40% - 5px);
left: calc(50% - 5px);
color: var(--itk-color-success);
opacity: 0.8;
transition:
Expand All @@ -441,6 +446,7 @@
&:not([data-hours=""]) {
&:before {
content: "✎";
left: calc(40% - 5px);
}
}
}
Expand Down Expand Up @@ -833,7 +839,30 @@
display: block;
font-size: 12px;
}

.ticket-title::before,
td.add-new::before,
tr.tr-total > td:first-child::before,
th.th-ticket-title::before {
content: "";
position: absolute;
top: 0;
left: -1px;
height: 100% !important;
width: 1px;
background-color: var(--itk-border-color);
z-index: 1;
}
.table > thead > tr > th:last-child::before,
.table > tbody > tr > td:last-child::before {
content: "";
position: absolute;
top: 0;
right: -1px;
height: 100% !important;
width: 1px;
background-color: var(--itk-border-color);
z-index: 1;
}
.timetable-ticket-search.ticket-loading {
pointer-events: none;
user-select: none;
Expand Down Expand Up @@ -872,7 +901,6 @@
#entry-copy-modal {
.entry-copy-form {
display: flex;
height: 150px;
flex-direction: column;
background-color: #fefefe;
margin: auto;
Expand All @@ -887,16 +915,22 @@
margin-top: 2px;
}
.entry-copy-headline {
margin-bottom: 7px;
margin-bottom: var(--itk-spacing-xs);
}

.entry-copy-overwrite-checkbox {
.entry-copy-checkboxes {
display: flex;
flex-direction: column;
margin: var(--itk-spacing-xs) 0 var(--itk-spacing) 0;
}
.entry-copy-overwrite-checkbox,
.entry-copy-weekend-checkbox {
display: flex;
align-items: center;
margin: 5px 0;
}

.entry-copy-overwrite-checkbox label {
.entry-copy-overwrite-checkbox label,
.entry-copy-weekend-checkbox label {
margin-left: 8px;
font-size: 0.875rem;
color: #333;
Expand All @@ -908,7 +942,8 @@
user-select: none;
}

.entry-copy-overwrite-checkbox input[type="checkbox"] {
.entry-copy-overwrite-checkbox input[type="checkbox"],
.entry-copy-weekend-checkbox input[type="checkbox"] {
cursor: pointer;
margin: 0;
}
Expand Down
Loading
Loading