|
@@ -224,14 +224,67 @@ if (!function_exists('fmt_days')) {
|
|
|
<option value="2">Prio 2 only</option>
|
|
<option value="2">Prio 2 only</option>
|
|
|
</select>
|
|
</select>
|
|
|
|
|
|
|
|
- <select data-owner-filter
|
|
|
|
|
- class="rounded border border-slate-300 px-2 py-1 text-sm bg-white focus:outline-none focus:ring-2 focus:ring-slate-400">
|
|
|
|
|
- <option value="">All owners</option>
|
|
|
|
|
- <option value="__none__">No owner</option>
|
|
|
|
|
- <?php foreach ($ownerChoices as $ow): ?>
|
|
|
|
|
- <option value="<?= (int) $ow->id ?>"><?= e($ow->name) ?></option>
|
|
|
|
|
- <?php endforeach; ?>
|
|
|
|
|
- </select>
|
|
|
|
|
|
|
+ <!-- Multi-select owner filter -->
|
|
|
|
|
+ <div class="relative" data-owner-filter-root>
|
|
|
|
|
+ <button type="button" data-owner-filter-trigger
|
|
|
|
|
+ class="rounded border border-slate-300 px-2 py-1 text-sm bg-white hover:bg-slate-50 focus:outline-none focus:ring-2 focus:ring-slate-400">
|
|
|
|
|
+ Owners <span data-owner-filter-count class="text-slate-500"></span>
|
|
|
|
|
+ </button>
|
|
|
|
|
+ <div data-owner-filter-dropdown
|
|
|
|
|
+ class="hidden absolute right-0 z-20 mt-1 w-56 rounded-md border border-slate-200 bg-white shadow-lg">
|
|
|
|
|
+ <div class="px-3 py-2 text-xs text-slate-500 flex items-center justify-between">
|
|
|
|
|
+ <span>Owner</span>
|
|
|
|
|
+ <button type="button" data-owner-filter-clear
|
|
|
|
|
+ class="text-blue-700 hover:underline">Clear</button>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <div class="max-h-64 overflow-y-auto">
|
|
|
|
|
+ <label class="flex items-center gap-2 px-3 py-1.5 text-sm hover:bg-slate-50">
|
|
|
|
|
+ <input type="checkbox" data-owner-filter-opt value="__none__"
|
|
|
|
|
+ class="rounded border-slate-300">
|
|
|
|
|
+ <span class="text-slate-500 italic">No owner</span>
|
|
|
|
|
+ </label>
|
|
|
|
|
+ <?php foreach ($ownerChoices as $ow): ?>
|
|
|
|
|
+ <label class="flex items-center gap-2 px-3 py-1.5 text-sm hover:bg-slate-50">
|
|
|
|
|
+ <input type="checkbox" data-owner-filter-opt value="<?= (int) $ow->id ?>"
|
|
|
|
|
+ class="rounded border-slate-300">
|
|
|
|
|
+ <span><?= e($ow->name) ?></span>
|
|
|
|
|
+ </label>
|
|
|
|
|
+ <?php endforeach; ?>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+
|
|
|
|
|
+ <!-- Column visibility -->
|
|
|
|
|
+ <div class="relative" data-columns-root>
|
|
|
|
|
+ <button type="button" data-columns-trigger
|
|
|
|
|
+ class="rounded border border-slate-300 px-2 py-1 text-sm bg-white hover:bg-slate-50 focus:outline-none focus:ring-2 focus:ring-slate-400">
|
|
|
|
|
+ Columns
|
|
|
|
|
+ </button>
|
|
|
|
|
+ <div data-columns-dropdown
|
|
|
|
|
+ class="hidden absolute right-0 z-20 mt-1 w-56 rounded-md border border-slate-200 bg-white shadow-lg">
|
|
|
|
|
+ <div class="px-3 py-2 text-xs text-slate-500">Show columns</div>
|
|
|
|
|
+ <div class="max-h-64 overflow-y-auto">
|
|
|
|
|
+ <label class="flex items-center gap-2 px-3 py-1.5 text-sm hover:bg-slate-50">
|
|
|
|
|
+ <input type="checkbox" data-column-opt value="owner" checked class="rounded border-slate-300">
|
|
|
|
|
+ <span>Owner</span>
|
|
|
|
|
+ </label>
|
|
|
|
|
+ <label class="flex items-center gap-2 px-3 py-1.5 text-sm hover:bg-slate-50">
|
|
|
|
|
+ <input type="checkbox" data-column-opt value="prio" checked class="rounded border-slate-300">
|
|
|
|
|
+ <span>Prio</span>
|
|
|
|
|
+ </label>
|
|
|
|
|
+ <label class="flex items-center gap-2 px-3 py-1.5 text-sm hover:bg-slate-50">
|
|
|
|
|
+ <input type="checkbox" data-column-opt value="tot" checked class="rounded border-slate-300">
|
|
|
|
|
+ <span>Tot</span>
|
|
|
|
|
+ </label>
|
|
|
|
|
+ <?php foreach ($sprintWorkers as $sw): ?>
|
|
|
|
|
+ <label class="flex items-center gap-2 px-3 py-1.5 text-sm hover:bg-slate-50">
|
|
|
|
|
+ <input type="checkbox" data-column-opt value="sw-<?= (int) $sw->id ?>" checked class="rounded border-slate-300">
|
|
|
|
|
+ <span><?= e($sw->workerName) ?></span>
|
|
|
|
|
+ </label>
|
|
|
|
|
+ <?php endforeach; ?>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </div>
|
|
|
|
|
|
|
|
<?php if ($currentUser->isAdmin): ?>
|
|
<?php if ($currentUser->isAdmin): ?>
|
|
|
<button type="button" data-add-task
|
|
<button type="button" data-add-task
|
|
@@ -250,14 +303,14 @@ if (!function_exists('fmt_days')) {
|
|
|
<th class="text-left px-2 py-2 font-semibold cursor-pointer select-none"
|
|
<th class="text-left px-2 py-2 font-semibold cursor-pointer select-none"
|
|
|
data-sort-col="title">Task <span class="sort-ind opacity-30">↕</span></th>
|
|
data-sort-col="title">Task <span class="sort-ind opacity-30">↕</span></th>
|
|
|
<th class="text-left px-2 py-2 font-semibold cursor-pointer select-none"
|
|
<th class="text-left px-2 py-2 font-semibold cursor-pointer select-none"
|
|
|
- data-sort-col="owner">Owner <span class="sort-ind opacity-30">↕</span></th>
|
|
|
|
|
|
|
+ data-sort-col="owner" data-col="owner">Owner <span class="sort-ind opacity-30">↕</span></th>
|
|
|
<th class="text-center px-2 py-2 font-semibold cursor-pointer select-none"
|
|
<th class="text-center px-2 py-2 font-semibold cursor-pointer select-none"
|
|
|
- data-sort-col="prio">Prio <span class="sort-ind opacity-30">↕</span></th>
|
|
|
|
|
|
|
+ data-sort-col="prio" data-col="prio">Prio <span class="sort-ind opacity-30">↕</span></th>
|
|
|
<th class="text-center px-2 py-2 font-semibold cursor-pointer select-none"
|
|
<th class="text-center px-2 py-2 font-semibold cursor-pointer select-none"
|
|
|
- data-sort-col="tot">Tot <span class="sort-ind opacity-30">↕</span></th>
|
|
|
|
|
|
|
+ data-sort-col="tot" data-col="tot">Tot <span class="sort-ind opacity-30">↕</span></th>
|
|
|
<?php foreach ($sprintWorkers as $sw): ?>
|
|
<?php foreach ($sprintWorkers as $sw): ?>
|
|
|
<th class="text-center px-2 py-2 font-semibold cursor-pointer select-none whitespace-nowrap"
|
|
<th class="text-center px-2 py-2 font-semibold cursor-pointer select-none whitespace-nowrap"
|
|
|
- data-sort-col="sw-<?= (int) $sw->id ?>">
|
|
|
|
|
|
|
+ data-sort-col="sw-<?= (int) $sw->id ?>" data-col="sw-<?= (int) $sw->id ?>">
|
|
|
<?= e($sw->workerName) ?>
|
|
<?= e($sw->workerName) ?>
|
|
|
<span class="sort-ind opacity-30">↕</span>
|
|
<span class="sort-ind opacity-30">↕</span>
|
|
|
</th>
|
|
</th>
|
|
@@ -297,7 +350,7 @@ if (!function_exists('fmt_days')) {
|
|
|
<span><?= e($t->title) ?></span>
|
|
<span><?= e($t->title) ?></span>
|
|
|
<?php endif; ?>
|
|
<?php endif; ?>
|
|
|
</td>
|
|
</td>
|
|
|
- <td class="px-2 py-1">
|
|
|
|
|
|
|
+ <td class="px-2 py-1" data-col="owner">
|
|
|
<?php if ($currentUser->isAdmin): ?>
|
|
<?php if ($currentUser->isAdmin): ?>
|
|
|
<select data-owner-select
|
|
<select data-owner-select
|
|
|
class="w-full rounded border border-slate-200 px-2 py-1 bg-white focus:outline-none focus:ring-2 focus:ring-slate-400">
|
|
class="w-full rounded border border-slate-200 px-2 py-1 bg-white focus:outline-none focus:ring-2 focus:ring-slate-400">
|
|
@@ -318,7 +371,7 @@ if (!function_exists('fmt_days')) {
|
|
|
?>
|
|
?>
|
|
|
<?php endif; ?>
|
|
<?php endif; ?>
|
|
|
</td>
|
|
</td>
|
|
|
- <td class="px-2 py-1 text-center">
|
|
|
|
|
|
|
+ <td class="px-2 py-1 text-center" data-col="prio">
|
|
|
<?php if ($currentUser->isAdmin): ?>
|
|
<?php if ($currentUser->isAdmin): ?>
|
|
|
<select data-prio-select
|
|
<select data-prio-select
|
|
|
class="rounded border border-slate-200 px-2 py-1 bg-white font-mono focus:outline-none focus:ring-2 focus:ring-slate-400">
|
|
class="rounded border border-slate-200 px-2 py-1 bg-white font-mono focus:outline-none focus:ring-2 focus:ring-slate-400">
|
|
@@ -330,11 +383,12 @@ if (!function_exists('fmt_days')) {
|
|
|
<?php endif; ?>
|
|
<?php endif; ?>
|
|
|
</td>
|
|
</td>
|
|
|
<td class="px-2 py-1 text-center font-mono font-semibold"
|
|
<td class="px-2 py-1 text-center font-mono font-semibold"
|
|
|
- data-task-tot>
|
|
|
|
|
|
|
+ data-col="tot" data-task-tot>
|
|
|
<?= e(fmt_days($tot)) ?>
|
|
<?= e(fmt_days($tot)) ?>
|
|
|
</td>
|
|
</td>
|
|
|
<?php foreach ($sprintWorkers as $sw): $d = (float) ($assign[$sw->id] ?? 0.0); ?>
|
|
<?php foreach ($sprintWorkers as $sw): $d = (float) ($assign[$sw->id] ?? 0.0); ?>
|
|
|
<td class="px-1 py-1 text-center"
|
|
<td class="px-1 py-1 text-center"
|
|
|
|
|
+ data-col="sw-<?= (int) $sw->id ?>"
|
|
|
data-sort-value-sw-<?= (int) $sw->id ?>="<?= e(number_format($d, 2, '.', '')) ?>">
|
|
data-sort-value-sw-<?= (int) $sw->id ?>="<?= e(number_format($d, 2, '.', '')) ?>">
|
|
|
<?php if ($currentUser->isAdmin): ?>
|
|
<?php if ($currentUser->isAdmin): ?>
|
|
|
<input type="number" min="0" step="0.5"
|
|
<input type="number" min="0" step="0.5"
|