Skip to content

Commit

Permalink
Merge pull request #36 from ITK-Leantime/feature/2965-sort-by-column
Browse files Browse the repository at this point in the history
2965: Sort by column
  • Loading branch information
jeppekroghitk authored Jan 14, 2025
2 parents 34a18ef + 7e41a5e commit 155abf2
Show file tree
Hide file tree
Showing 4 changed files with 134 additions and 17 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@

## [Unreleased]

* [PR-36](https://github.com/ITK-Leantime/project-overview/pull/36)
* Added sort by column

## [2.2.1] - 2025-01-14

* [PR-34](https://github.com/ITK-Leantime/project-overview/pull/34)
Expand Down
41 changes: 24 additions & 17 deletions Templates/projectOverview.blade.php
Original file line number Diff line number Diff line change
Expand Up @@ -45,20 +45,20 @@
</div>
</form>
</div>
<table class="table table-striped">
<table id="sortable-table" class="table table-striped">
<thead>
<tr>
<th scope="col">{{ __('projectOverview.id_table_header') }}</th>
<th scope="col">{{ __('projectOverview.project_table_header') }}</th>
<th scope="col">{{ __('projectOverview.todo_table_header') }}</th>
<th scope="col">{{ __('projectOverview.status_table_header') }}</th>
<th scope="col">{{ __('projectOverview.priority_table_header') }}</th>
<th scope="col">{{ __('projectOverview.due_date_table_header') }}</th>
<th scope="col">{{ __('projectOverview.todo_assigned_table_header') }}</th>
<th scope="col">{{ __('projectOverview.todo_planned_hours_table_header') }}</th>
<th scope="col">{{ __('projectOverview.todo_remaining_hours_table_header') }}</th>
<th scope="col">{{ __('projectOverview.todo_milestone_table_header') }}</th>
<th scope="col">{{ __('projectOverview.todo_tags_table_header') }}</th>
<th data-sort="number" scope="col">{{ __('projectOverview.id_table_header') }}</th>
<th data-sort="string" scope="col">{{ __('projectOverview.project_table_header') }}</th>
<th data-sort="string" scope="col">{{ __('projectOverview.todo_table_header') }}</th>
<th data-sort="string" scope="col">{{ __('projectOverview.status_table_header') }}</th>
<th data-sort="string" scope="col">{{ __('projectOverview.priority_table_header') }}</th>
<th data-sort="date" scope="col">{{ __('projectOverview.due_date_table_header') }}</th>
<th data-sort="user" scope="col">{{ __('projectOverview.todo_assigned_table_header') }}</th>
<th data-sort="number-input" scope="col">{{ __('projectOverview.todo_planned_hours_table_header') }}</th>
<th data-sort="number-input" scope="col">{{ __('projectOverview.todo_remaining_hours_table_header') }}</th>
<th data-sort="select" scope="col">{{ __('projectOverview.todo_milestone_table_header') }}</th>
<th data-sort="text-input" scope="col">{{ __('projectOverview.todo_tags_table_header') }}</th>
</tr>
</thead>
<tbody>
Expand Down Expand Up @@ -128,14 +128,21 @@ class="table-button priority priority-bg-{!! $newPriorityId !!}">
<input type="date" data-ticketid="{{ $row['id'] }}" id="due-date-{{ $row['id'] }}"
value="{{ date($row['dueDate']) }}"/>
</td>
<td class="spacious">
<select class="form-select" id="assigned-user-{{ $row['id'] }}">
@php
$selectedUser = $row['editorId'] !== null && $row['editorId'] !== -1
? collect($row['projectUsers'])->firstWhere('id', $row['editorId'])
: null;
@endphp

<td class="spacious"
data-selected-name="{{ $selectedUser ? $selectedUser['firstname'] . ' ' . $selectedUser['lastname'] : '' }}">

<select class="form-select assigned-user-select" id="assigned-user-{{ $row['id'] }}" data-ticket-id="{{ $row['id'] }}">
<option value="-1"></option>
@foreach ($row['projectUsers'] as $projectUser)
<option value={{ $projectUser['id'] }}
<option value="{{ $projectUser['id'] }}"
{{ (int) $row['editorId'] === (int) $projectUser['id'] ? 'selected' : '' }}>
{{ $projectUser['firstname'] }}
{{ $projectUser['lastname'] }}
{{ $projectUser['firstname'] }} {{ $projectUser['lastname'] }}
</option>
@endforeach
</select>
Expand Down
39 changes: 39 additions & 0 deletions assets/project-overview.css
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,45 @@
margin-bottom: 30px;
}

th {
position: relative;
text-align: left;
cursor: pointer;
user-select: none;
}

th[data-order]:after {
content: '';
position: absolute;
right: 8px;
top: 50%;
transform: translateY(0);
font-family: Arial, sans-serif;
font-size: 12px;
pointer-events: none;
}

th[data-order='asc']:after {
content: '\f0d7';
font-family: 'Font Awesome 5 Free';
font-weight: 900;
position: absolute;
right: 8px;
top: 50%;
transform: translateY(0);
color: #000;
}

th[data-order='desc']:after {
content: '\f0d8';
font-family: 'Font Awesome 5 Free';
font-weight: 900;
position: absolute;
right: 8px;
top: 50%;
transform: translateY(0);
color: #000;
}
td {
&.spacious {
min-width: 130px;
Expand Down
68 changes: 68 additions & 0 deletions assets/project-overview.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,74 @@ import { Danish } from 'flatpickr/dist/l10n/da.js';
import 'flatpickr/dist/flatpickr.min.css';

$(document).ready(function () {
const table = document.getElementById('sortable-table');
const headers = table.querySelectorAll('thead th');
const tbody = table.querySelector('tbody');

headers.forEach((header, columnIndex) => {
header.addEventListener('click', () => {
const isAscending = header.dataset.order !== 'asc';
const type = header.dataset.sort || 'string';

const sortedRows = Array.from(tbody.querySelectorAll('tr')).sort(
(a, b) => {
const cellA = a.children[columnIndex];
const cellB = b.children[columnIndex];

const getValue = (cell) => {
switch (type) {
case 'number':
return parseFloat(cell.textContent.trim()) || 0;
case 'date':
return new Date(
cell.querySelector("input[type='date']")?.value || ''
);
case 'user':
return cell.dataset.selectedName?.toLowerCase() || '';
case 'select':
return (
cell
.querySelector('select')
?.selectedOptions[0]?.textContent.trim()
.toLowerCase() || ''
);
case 'text-input':
return (
cell
.querySelector("input[type='text']")
?.value.toLowerCase() || ''
);
case 'number-input':
return (
parseFloat(
cell.querySelector("input[type='number']")?.value
) || 0
);
default:
return cell.textContent.trim().toLowerCase();
}
};

const valueA = getValue(cellA);
const valueB = getValue(cellB);

if (type === 'number' || type === 'date' || type === 'number-input') {
return isAscending ? valueA - valueB : valueB - valueA;
}
return isAscending
? valueA.localeCompare(valueB)
: valueB.localeCompare(valueA);
}
);

tbody.innerHTML = '';
sortedRows.forEach((row) => tbody.appendChild(row));

headers.forEach((h) => delete h.dataset.order);
header.dataset.order = isAscending ? 'asc' : 'desc';
});
});

flatpickr('#dateRange', {
mode: 'range',
dateFormat: 'd-m-Y',
Expand Down

0 comments on commit 155abf2

Please sign in to comment.