style: auto-fix 1340 phpcs PSR-12 violations via phpcbf; exclude MissingNamespace and SideEffects
This commit is contained in:
+157
-136
@@ -1,4 +1,5 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* DashboardView.php — Main ticket dashboard, redesigned for TDS v1.2.
|
||||
*
|
||||
@@ -53,21 +54,26 @@ if (!empty($_GET['type'])) {
|
||||
$activeFilters[] = ['type' => 'type', 'value' => $_GET['type'], 'label' => 'Type: ' . htmlspecialchars($_GET['type'])];
|
||||
}
|
||||
if (!empty($_GET['assigned_to'])) {
|
||||
$label = match($_GET['assigned_to']) { 'unassigned' => 'Unassigned', 'me' => 'Me', default => 'User #' . htmlspecialchars($_GET['assigned_to']) };
|
||||
$label = match ($_GET['assigned_to']) {
|
||||
'unassigned' => 'Unassigned', 'me' => 'Me', default => 'User #' . htmlspecialchars($_GET['assigned_to'])
|
||||
};
|
||||
$activeFilters[] = ['type' => 'assigned_to', 'value' => $_GET['assigned_to'], 'label' => 'Assigned: ' . $label];
|
||||
}
|
||||
if (!empty($_GET['created_from']) || !empty($_GET['created_to'])) {
|
||||
$from = $_GET['created_from'] ?? ''; $to = $_GET['created_to'] ?? '';
|
||||
$from = $_GET['created_from'] ?? '';
|
||||
$to = $_GET['created_to'] ?? '';
|
||||
$label = $from === $to && $from ? 'Created: ' . $from : 'Created: ' . ($from ?: '…') . ' – ' . ($to ?: '…');
|
||||
$activeFilters[] = ['type' => 'created_from', 'value' => $from, 'label' => $label];
|
||||
}
|
||||
if (!empty($_GET['updated_from']) || !empty($_GET['updated_to'])) {
|
||||
$from = $_GET['updated_from'] ?? ''; $to = $_GET['updated_to'] ?? '';
|
||||
$from = $_GET['updated_from'] ?? '';
|
||||
$to = $_GET['updated_to'] ?? '';
|
||||
$label = $from === $to && $from ? 'Updated: ' . $from : 'Updated: ' . ($from ?: '…') . ' – ' . ($to ?: '…');
|
||||
$activeFilters[] = ['type' => 'updated_from', 'value' => $from, 'label' => $label];
|
||||
}
|
||||
if (!empty($_GET['closed_from']) || !empty($_GET['closed_to'])) {
|
||||
$from = $_GET['closed_from'] ?? ''; $to = $_GET['closed_to'] ?? '';
|
||||
$from = $_GET['closed_from'] ?? '';
|
||||
$to = $_GET['closed_to'] ?? '';
|
||||
$label = $from === $to && $from ? 'Closed: ' . $from : 'Closed: ' . ($from ?: '…') . ' – ' . ($to ?: '…');
|
||||
$activeFilters[] = ['type' => 'closed_from', 'value' => $from, 'label' => $label];
|
||||
}
|
||||
@@ -99,19 +105,19 @@ include __DIR__ . '/layout_header.php';
|
||||
<!-- ═══════════════════════════════════════════════════════════
|
||||
STATS GRID
|
||||
═══════════════════════════════════════════════════════════ -->
|
||||
<?php if (isset($stats)): ?>
|
||||
<?php if (isset($stats)) : ?>
|
||||
<div class="lt-stats-grid" id="statsGrid">
|
||||
|
||||
<?php
|
||||
<?php
|
||||
// Trend indicators — derived from existing stats without extra DB query
|
||||
// Logic: if more closed today than created → improving (green), if more created → warn, else idle
|
||||
$trendOpen = ($stats['closed_today'] > $stats['created_today']) ? 'lt-dot-up' :
|
||||
$trendOpen = ($stats['closed_today'] > $stats['created_today']) ? 'lt-dot-up' :
|
||||
($stats['created_today'] > $stats['closed_today'] ? 'lt-dot-warn' : 'lt-dot-idle');
|
||||
$trendCrit = ($stats['critical'] > 0) ? 'lt-dot-warn' : 'lt-dot-up';
|
||||
$trendUnassi = ($stats['unassigned'] > 0) ? 'lt-dot-warn' : 'lt-dot-idle';
|
||||
$trendToday = ($stats['created_today'] > 0) ? 'lt-dot-warn' : 'lt-dot-idle';
|
||||
$trendClosed = ($stats['closed_today'] > 0) ? 'lt-dot-up' : 'lt-dot-idle';
|
||||
?>
|
||||
$trendCrit = ($stats['critical'] > 0) ? 'lt-dot-warn' : 'lt-dot-up';
|
||||
$trendUnassi = ($stats['unassigned'] > 0) ? 'lt-dot-warn' : 'lt-dot-idle';
|
||||
$trendToday = ($stats['created_today'] > 0) ? 'lt-dot-warn' : 'lt-dot-idle';
|
||||
$trendClosed = ($stats['closed_today'] > 0) ? 'lt-dot-up' : 'lt-dot-idle';
|
||||
?>
|
||||
|
||||
<div class="lt-stat-card stat-open" role="button" tabindex="0"
|
||||
data-filter-key="status" data-filter-val="Open,Pending,In Progress"
|
||||
@@ -177,21 +183,26 @@ include __DIR__ . '/layout_header.php';
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?php
|
||||
$avgHours = $stats['avg_resolution_hours'] ?? 0;
|
||||
if ($avgHours <= 0) {
|
||||
$avgDisplay = '—'; $avgUnit = '';
|
||||
} elseif ($avgHours < 1) {
|
||||
$avgDisplay = (string)max(1, (int)round($avgHours * 60)); $avgUnit = 'min';
|
||||
} elseif ($avgHours < 48) {
|
||||
$avgDisplay = (string)(int)round($avgHours); $avgUnit = 'hr';
|
||||
} elseif ($avgHours < 336) { // <14 days
|
||||
$avgDisplay = number_format($avgHours / 24, 1); $avgUnit = 'days';
|
||||
} else {
|
||||
$avgDisplay = number_format($avgHours / 168, 1); $avgUnit = 'wks';
|
||||
}
|
||||
$avgTitle = $avgHours > 0 ? number_format($avgHours, 1) . ' hours' : 'No data';
|
||||
?>
|
||||
<?php
|
||||
$avgHours = $stats['avg_resolution_hours'] ?? 0;
|
||||
if ($avgHours <= 0) {
|
||||
$avgDisplay = '—';
|
||||
$avgUnit = '';
|
||||
} elseif ($avgHours < 1) {
|
||||
$avgDisplay = (string)max(1, (int)round($avgHours * 60));
|
||||
$avgUnit = 'min';
|
||||
} elseif ($avgHours < 48) {
|
||||
$avgDisplay = (string)(int)round($avgHours);
|
||||
$avgUnit = 'hr';
|
||||
} elseif ($avgHours < 336) { // <14 days
|
||||
$avgDisplay = number_format($avgHours / 24, 1);
|
||||
$avgUnit = 'days';
|
||||
} else {
|
||||
$avgDisplay = number_format($avgHours / 168, 1);
|
||||
$avgUnit = 'wks';
|
||||
}
|
||||
$avgTitle = $avgHours > 0 ? number_format($avgHours, 1) . ' hours' : 'No data';
|
||||
?>
|
||||
<div class="lt-stat-card stat-time" title="Average resolution time: <?= htmlspecialchars($avgTitle) ?>" aria-label="Avg resolution time">
|
||||
<div class="lt-stat-icon lt-text-muted">⏱</div>
|
||||
<div class="lt-stat-info">
|
||||
@@ -332,7 +343,7 @@ include __DIR__ . '/layout_header.php';
|
||||
})();
|
||||
</script>
|
||||
|
||||
<?php if (!empty($stats['by_assignee'])): ?>
|
||||
<?php if (!empty($stats['by_assignee'])) : ?>
|
||||
<!-- ═══════════════════════════════════════════════════════════
|
||||
TEAM WORKLOAD PANEL
|
||||
═══════════════════════════════════════════════════════════ -->
|
||||
@@ -347,7 +358,7 @@ include __DIR__ . '/layout_header.php';
|
||||
$maxLoad = max(array_column($byAssignee, 'open_count') ?: [1]);
|
||||
?>
|
||||
<div class="workload-grid">
|
||||
<?php foreach ($byAssignee as $a):
|
||||
<?php foreach ($byAssignee as $a) :
|
||||
$count = (int)$a['open_count'];
|
||||
$name = $a['display_name'] ?? $a['username'] ?? 'Unknown';
|
||||
$pct = $maxLoad > 0 ? round(($count / $maxLoad) * 100) : 0;
|
||||
@@ -357,10 +368,10 @@ include __DIR__ . '/layout_header.php';
|
||||
$avatarColors = ['lt-avatar--orange', 'lt-avatar--green', 'lt-avatar--purple', ''];
|
||||
$avatarColor = $avatarColors[abs(crc32($name)) % count($avatarColors)];
|
||||
$userId = (int)($a['user_id'] ?? 0);
|
||||
?>
|
||||
?>
|
||||
<div class="workload-item">
|
||||
<div class="lt-avatar lt-avatar--sm <?= $avatarColor ?>" aria-hidden="true" title="<?= htmlspecialchars($name) ?>">
|
||||
<?php if ($userId > 0): ?>
|
||||
<?php if ($userId > 0) : ?>
|
||||
<img src="/api/user_avatar.php?user_id=<?= $userId ?>" alt="" class="lt-avatar-img">
|
||||
<?php endif ?>
|
||||
<span class="lt-avatar-initials"><?= htmlspecialchars($initials) ?></span>
|
||||
@@ -415,7 +426,7 @@ include __DIR__ . '/layout_header.php';
|
||||
<!-- Status Filter -->
|
||||
<fieldset class="lt-filter-group">
|
||||
<legend class="lt-filter-label">Status</legend>
|
||||
<?php foreach ($GLOBALS['config']['TICKET_STATUSES'] as $s): ?>
|
||||
<?php foreach ($GLOBALS['config']['TICKET_STATUSES'] as $s) : ?>
|
||||
<label class="lt-filter-option">
|
||||
<input type="checkbox" class="lt-checkbox sidebar-filter"
|
||||
name="status" value="<?= htmlspecialchars($s) ?>"
|
||||
@@ -426,32 +437,32 @@ include __DIR__ . '/layout_header.php';
|
||||
</fieldset>
|
||||
|
||||
<!-- Category Filter -->
|
||||
<?php if (!empty($categories)): ?>
|
||||
<?php if (!empty($categories)) : ?>
|
||||
<fieldset class="lt-filter-group">
|
||||
<legend class="lt-filter-label">Category</legend>
|
||||
<?php foreach ($categories as $cat): ?>
|
||||
<?php foreach ($categories as $cat) : ?>
|
||||
<label class="lt-filter-option">
|
||||
<input type="checkbox" class="lt-checkbox sidebar-filter"
|
||||
name="category" value="<?= htmlspecialchars($cat) ?>"
|
||||
<?= in_array($cat, $currentCategories) ? 'checked' : '' ?>>
|
||||
<?= htmlspecialchars($cat) ?>
|
||||
<?= htmlspecialchars($cat) ?>
|
||||
</label>
|
||||
<?php endforeach ?>
|
||||
<?php endforeach ?>
|
||||
</fieldset>
|
||||
<?php endif ?>
|
||||
|
||||
<!-- Type Filter -->
|
||||
<?php if (!empty($types)): ?>
|
||||
<?php if (!empty($types)) : ?>
|
||||
<fieldset class="lt-filter-group">
|
||||
<legend class="lt-filter-label">Type</legend>
|
||||
<?php foreach ($types as $type): ?>
|
||||
<?php foreach ($types as $type) : ?>
|
||||
<label class="lt-filter-option">
|
||||
<input type="checkbox" class="lt-checkbox sidebar-filter"
|
||||
name="type" value="<?= htmlspecialchars($type) ?>"
|
||||
<?= in_array($type, $currentTypes) ? 'checked' : '' ?>>
|
||||
<?= htmlspecialchars($type) ?>
|
||||
<?= htmlspecialchars($type) ?>
|
||||
</label>
|
||||
<?php endforeach ?>
|
||||
<?php endforeach ?>
|
||||
</fieldset>
|
||||
<?php endif ?>
|
||||
|
||||
@@ -503,10 +514,10 @@ include __DIR__ . '/layout_header.php';
|
||||
<button type="button" id="lt-sidebar-toggle-btn" class="lt-btn lt-btn-ghost lt-btn-sm"
|
||||
aria-label="Toggle filter sidebar" title="Toggle filters">⋮⋮ Filters</button>
|
||||
<form method="GET" action="" class="lt-search-form" role="search">
|
||||
<?php foreach (['status','category','type','sort','dir'] as $p): ?>
|
||||
<?php if (isset($_GET[$p])): ?>
|
||||
<?php foreach (['status','category','type','sort','dir'] as $p) : ?>
|
||||
<?php if (isset($_GET[$p])) : ?>
|
||||
<input type="hidden" name="<?= $p ?>" value="<?= htmlspecialchars($_GET[$p]) ?>">
|
||||
<?php endif ?>
|
||||
<?php endif ?>
|
||||
<?php endforeach ?>
|
||||
<div class="lt-search">
|
||||
<input type="text" name="search" class="lt-input lt-search-input"
|
||||
@@ -519,7 +530,7 @@ include __DIR__ . '/layout_header.php';
|
||||
<button type="button" class="lt-btn lt-btn-sm lt-btn-ghost" data-action="open-advanced-search">
|
||||
FILTER
|
||||
</button>
|
||||
<?php if (!empty($_GET['search'])): ?>
|
||||
<?php if (!empty($_GET['search'])) : ?>
|
||||
<a href="?" class="lt-btn lt-btn-sm lt-btn-ghost" aria-label="Clear search">✕</a>
|
||||
<?php endif ?>
|
||||
</form>
|
||||
@@ -529,7 +540,7 @@ include __DIR__ . '/layout_header.php';
|
||||
<?= $totalTickets ?> ticket<?= $totalTickets !== 1 ? 's' : '' ?>
|
||||
</span>
|
||||
<!-- Export dropdown (admin + selection) -->
|
||||
<?php if ($isAdmin): ?>
|
||||
<?php if ($isAdmin) : ?>
|
||||
<div class="lt-dropdown-wrap" id="exportDropdown" style="display:none">
|
||||
<button type="button" class="lt-btn lt-btn-sm lt-btn-ghost lt-dropdown-trigger"
|
||||
id="exportDropdownTrigger"
|
||||
@@ -554,28 +565,28 @@ include __DIR__ . '/layout_header.php';
|
||||
<div id="savedFilterPills" class="saved-filter-pills lt-flex lt-flex-wrap lt-flex-gap-sm" style="display:none;padding:0.35rem 0 0.1rem" aria-label="Saved filters"></div>
|
||||
|
||||
<!-- Active filters bar -->
|
||||
<?php if (!empty($activeFilters)): ?>
|
||||
<?php if (!empty($activeFilters)) : ?>
|
||||
<div class="active-filters-bar lt-flex lt-flex-wrap lt-flex-gap-sm" role="group" aria-label="Active filters">
|
||||
<span class="lt-text-xs lt-text-muted">Active:</span>
|
||||
<?php foreach ($activeFilters as $f): ?>
|
||||
<?php foreach ($activeFilters as $f) : ?>
|
||||
<span class="lt-badge filter-badge"
|
||||
data-filter-type="<?= htmlspecialchars($f['type']) ?>"
|
||||
data-filter-value="<?= htmlspecialchars($f['value']) ?>">
|
||||
<?= htmlspecialchars($f['label']) ?>
|
||||
<?= htmlspecialchars($f['label']) ?>
|
||||
<button type="button" class="filter-remove"
|
||||
data-action="remove-filter"
|
||||
data-filter-type="<?= htmlspecialchars($f['type']) ?>"
|
||||
data-filter-value="<?= htmlspecialchars($f['value']) ?>"
|
||||
aria-label="Remove <?= htmlspecialchars($f['label']) ?> filter">✕</button>
|
||||
</span>
|
||||
<?php endforeach ?>
|
||||
<?php endforeach ?>
|
||||
<button type="button" class="lt-btn lt-btn-ghost lt-btn-sm"
|
||||
data-action="clear-all-filters">CLEAR ALL</button>
|
||||
</div>
|
||||
<?php endif ?>
|
||||
|
||||
<!-- Search results info -->
|
||||
<?php if (!empty($_GET['search'])): ?>
|
||||
<?php if (!empty($_GET['search'])) : ?>
|
||||
<div class="lt-msg lt-msg-info">
|
||||
Showing results for: <strong><?= htmlspecialchars($_GET['search']) ?></strong>
|
||||
— <?= $totalTickets ?> ticket<?= $totalTickets !== 1 ? 's' : '' ?> found
|
||||
@@ -588,7 +599,7 @@ include __DIR__ . '/layout_header.php';
|
||||
<div id="tab-table" class="lt-tab-panel active" role="tabpanel" aria-labelledby="tableViewBtn">
|
||||
|
||||
<!-- Bulk actions (admin only, shown when tickets selected) -->
|
||||
<?php if ($isAdmin): ?>
|
||||
<?php if ($isAdmin) : ?>
|
||||
<div class="bulk-actions-inline" style="display:none" aria-live="polite">
|
||||
<span id="selected-count" class="lt-text-amber lt-text-sm">0</span>
|
||||
<span class="lt-text-xs lt-text-muted"> tickets selected</span>
|
||||
@@ -616,7 +627,7 @@ include __DIR__ . '/layout_header.php';
|
||||
<div id="colTogglePanel" class="col-toggle-panel" aria-hidden="true" role="dialog" aria-label="Column visibility">
|
||||
<div class="col-toggle-title">Visible Columns</div>
|
||||
<?php
|
||||
$toggleableCols = [
|
||||
$toggleableCols = [
|
||||
'ticket_id' => 'Ticket ID',
|
||||
'category' => 'Category',
|
||||
'type' => 'Type',
|
||||
@@ -624,14 +635,14 @@ include __DIR__ . '/layout_header.php';
|
||||
'assigned_to' => 'Assigned To',
|
||||
'created_at' => 'Created',
|
||||
'updated_at' => 'Updated',
|
||||
];
|
||||
foreach ($toggleableCols as $colKey => $colName): ?>
|
||||
];
|
||||
foreach ($toggleableCols as $colKey => $colName) : ?>
|
||||
<label class="col-toggle-row">
|
||||
<input type="checkbox" class="lt-checkbox col-toggle-cb"
|
||||
data-col="<?= $colKey ?>" checked>
|
||||
<span><?= $colName ?></span>
|
||||
</label>
|
||||
<?php endforeach ?>
|
||||
<?php endforeach ?>
|
||||
<div class="col-toggle-footer">
|
||||
<button type="button" class="lt-btn lt-btn-ghost lt-btn-sm lt-w-full" id="colToggleReset">Reset</button>
|
||||
</div>
|
||||
@@ -643,7 +654,7 @@ include __DIR__ . '/layout_header.php';
|
||||
<caption class="lt-sr-only">Ticket queue sorted by <?= htmlspecialchars($currentSort) ?> <?= $currentDir ?></caption>
|
||||
<thead>
|
||||
<tr>
|
||||
<?php if ($isAdmin): ?>
|
||||
<?php if ($isAdmin) : ?>
|
||||
<th scope="col" class="col-checkbox">
|
||||
<input type="checkbox" class="lt-checkbox" id="selectAllCheckbox"
|
||||
data-action="toggle-select-all" aria-label="Select all tickets">
|
||||
@@ -663,16 +674,16 @@ include __DIR__ . '/layout_header.php';
|
||||
'updated_at' => 'Updated',
|
||||
'_actions' => 'Actions',
|
||||
];
|
||||
foreach ($columns as $col => $label):
|
||||
if ($col === '_actions'): ?>
|
||||
foreach ($columns as $col => $label) :
|
||||
if ($col === '_actions') : ?>
|
||||
<th scope="col" class="col-actions" data-col="_actions">Actions</th>
|
||||
<?php else:
|
||||
$newDir = ($currentSort === $col && $currentDir === 'asc') ? 'desc' : 'asc';
|
||||
$sortClass = ($currentSort === $col) ? 'sort-' . $currentDir : '';
|
||||
$ariaSort = ($currentSort === $col) ? 'aria-sort="' . ($currentDir === 'asc' ? 'ascending' : 'descending') . '"' : '';
|
||||
$sortParams = array_merge($_GET, ['sort' => $col, 'dir' => $newDir, 'page' => 1]);
|
||||
$sortUrl = htmlspecialchars('?' . http_build_query($sortParams), ENT_QUOTES, 'UTF-8');
|
||||
?>
|
||||
<?php else :
|
||||
$newDir = ($currentSort === $col && $currentDir === 'asc') ? 'desc' : 'asc';
|
||||
$sortClass = ($currentSort === $col) ? 'sort-' . $currentDir : '';
|
||||
$ariaSort = ($currentSort === $col) ? 'aria-sort="' . ($currentDir === 'asc' ? 'ascending' : 'descending') . '"' : '';
|
||||
$sortParams = array_merge($_GET, ['sort' => $col, 'dir' => $newDir, 'page' => 1]);
|
||||
$sortUrl = htmlspecialchars('?' . http_build_query($sortParams), ENT_QUOTES, 'UTF-8');
|
||||
?>
|
||||
<th scope="col" class="<?= $sortClass ?>" data-col="<?= $col ?>"
|
||||
data-action="navigate" data-url="<?= $sortUrl ?>"
|
||||
<?= $ariaSort ?>
|
||||
@@ -682,45 +693,47 @@ include __DIR__ . '/layout_header.php';
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php if (empty($tickets)): ?>
|
||||
<?php if (empty($tickets)) : ?>
|
||||
<tr>
|
||||
<td colspan="<?= $colCount ?>" class="lt-empty">
|
||||
<div class="lt-empty-state">
|
||||
<div class="lt-empty-state-icon">📭</div>
|
||||
<div class="lt-empty-state-title">No Tickets Found</div>
|
||||
<div class="lt-empty-state-body">No tickets match your current filters.</div>
|
||||
<?php if (!empty($activeFilters) || !empty($_GET['search'])): ?>
|
||||
<?php if (!empty($activeFilters) || !empty($_GET['search'])) : ?>
|
||||
<a href="?" class="lt-btn lt-btn-sm lt-btn-ghost">Clear Filters</a>
|
||||
<?php endif ?>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<?php else: ?>
|
||||
<?php foreach ($tickets as $row):
|
||||
$creator = htmlspecialchars($row['creator_display_name'] ?? $row['creator_username'] ?? 'System');
|
||||
$assignedTo = htmlspecialchars($row['assigned_display_name'] ?? $row['assigned_username'] ?? 'Unassigned');
|
||||
$pNum = (int)$row['priority'];
|
||||
$rowStatusSlug = strtolower(str_replace(' ', '-', $row['status']));
|
||||
$critClass = ($pNum === 1) ? ' lt-row-critical' : '';
|
||||
$warnClass = ($pNum === 2) ? ' lt-row-warning' : '';
|
||||
$createdFmt = date('Y-m-d H:i', strtotime($row['created_at']));
|
||||
$updatedFmt = date('Y-m-d H:i', strtotime($row['updated_at']));
|
||||
?>
|
||||
<?php else : ?>
|
||||
<?php foreach ($tickets as $row) :
|
||||
$creator = htmlspecialchars($row['creator_display_name'] ?? $row['creator_username'] ?? 'System');
|
||||
$assignedTo = htmlspecialchars($row['assigned_display_name'] ?? $row['assigned_username'] ?? 'Unassigned');
|
||||
$pNum = (int)$row['priority'];
|
||||
$rowStatusSlug = strtolower(str_replace(' ', '-', $row['status']));
|
||||
$critClass = ($pNum === 1) ? ' lt-row-critical' : '';
|
||||
$warnClass = ($pNum === 2) ? ' lt-row-warning' : '';
|
||||
$createdFmt = date('Y-m-d H:i', strtotime($row['created_at']));
|
||||
$updatedFmt = date('Y-m-d H:i', strtotime($row['updated_at']));
|
||||
?>
|
||||
<tr class="lt-row-p<?= $pNum ?><?= $critClass ?><?= $warnClass ?>">
|
||||
<?php if ($isAdmin): ?>
|
||||
<?php if ($isAdmin) : ?>
|
||||
<td data-label="Select" data-action="toggle-row-checkbox" class="checkbox-cell">
|
||||
<input type="checkbox" class="lt-checkbox ticket-checkbox"
|
||||
value="<?= htmlspecialchars($row['ticket_id']) ?>"
|
||||
data-action="update-selection"
|
||||
aria-label="Select ticket <?= htmlspecialchars($row['ticket_id']) ?>">
|
||||
</td>
|
||||
<?php endif ?>
|
||||
<?php endif ?>
|
||||
<td data-label="Ticket ID" data-col="ticket_id">
|
||||
<a href="/ticket/<?= htmlspecialchars($row['ticket_id']) ?>"
|
||||
class="ticket-link"><?= htmlspecialchars($row['ticket_id']) ?></a>
|
||||
</td>
|
||||
<td data-label="Priority" data-col="priority">
|
||||
<?php $badgeClass = match($pNum) { 1 => 'lt-badge-p1', 2 => 'lt-badge-p2', 3 => 'lt-badge-p3', default => 'lt-badge-p4' }; ?>
|
||||
<?php $badgeClass = match ($pNum) {
|
||||
1 => 'lt-badge-p1', 2 => 'lt-badge-p2', 3 => 'lt-badge-p3', default => 'lt-badge-p4'
|
||||
}; ?>
|
||||
<span class="lt-badge <?= $badgeClass ?>">P<?= $pNum ?></span>
|
||||
</td>
|
||||
<td data-label="Title" data-col="title" class="col-title">
|
||||
@@ -729,24 +742,24 @@ include __DIR__ . '/layout_header.php';
|
||||
<td data-label="Category" data-col="category" class="lt-text-muted lt-text-xs"><?= htmlspecialchars($row['category']) ?></td>
|
||||
<td data-label="Type" data-col="type" class="lt-text-muted lt-text-xs"><?= htmlspecialchars($row['type']) ?></td>
|
||||
<td data-label="Status" data-col="status">
|
||||
<?php $rowDotClass = match($row['status']) {
|
||||
'Open' => 'lt-dot-up',
|
||||
'In Progress' => 'lt-dot-warn',
|
||||
'Pending' => 'lt-dot--orange',
|
||||
'Closed' => 'lt-dot-idle',
|
||||
default => 'lt-dot-idle',
|
||||
}; ?>
|
||||
<?php $rowDotClass = match ($row['status']) {
|
||||
'Open' => 'lt-dot-up',
|
||||
'In Progress' => 'lt-dot-warn',
|
||||
'Pending' => 'lt-dot--orange',
|
||||
'Closed' => 'lt-dot-idle',
|
||||
default => 'lt-dot-idle',
|
||||
}; ?>
|
||||
<span class="lt-dot <?= $rowDotClass ?>" aria-hidden="true" style="vertical-align:middle;margin-right:0.3rem"></span>
|
||||
<span class="lt-status lt-status-<?= $rowStatusSlug ?>"><?= htmlspecialchars($row['status']) ?></span>
|
||||
</td>
|
||||
<td data-label="Created By" data-col="created_by" class="lt-text-xs"><?= $creator ?></td>
|
||||
<td data-label="Assigned To" data-col="assigned_to" class="lt-text-xs">
|
||||
<?php $assigneeDisplay = $row['assigned_display_name'] ?? $row['assigned_username'] ?? null; ?>
|
||||
<?php if ($assigneeDisplay): ?>
|
||||
<?php $assigneeDisplay = $row['assigned_display_name'] ?? $row['assigned_username'] ?? null; ?>
|
||||
<?php if ($assigneeDisplay) : ?>
|
||||
<span data-tooltip="<?= htmlspecialchars($assigneeDisplay, ENT_QUOTES, 'UTF-8') ?>"><?= htmlspecialchars($assigneeDisplay) ?></span>
|
||||
<?php else: ?>
|
||||
<?php else : ?>
|
||||
<span class="lt-text-muted">Unassigned</span>
|
||||
<?php endif ?>
|
||||
<?php endif ?>
|
||||
</td>
|
||||
<td data-label="Created" data-col="created_at" class="lt-text-xs lt-text-muted ts-cell"
|
||||
data-ts="<?= htmlspecialchars($row['created_at'], ENT_QUOTES, 'UTF-8') ?>"
|
||||
@@ -772,7 +785,7 @@ include __DIR__ . '/layout_header.php';
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<?php endforeach ?>
|
||||
<?php endforeach ?>
|
||||
<?php endif ?>
|
||||
</tbody>
|
||||
</table>
|
||||
@@ -780,40 +793,44 @@ include __DIR__ . '/layout_header.php';
|
||||
</div><!-- /.lt-frame -->
|
||||
|
||||
<!-- Pagination -->
|
||||
<?php if ($totalPages > 1): ?>
|
||||
<?php if ($totalPages > 1) : ?>
|
||||
<div class="lt-pagination" role="navigation" aria-label="Ticket pagination">
|
||||
<?php
|
||||
$currentParams = $_GET;
|
||||
if ($page > 1) {
|
||||
$currentParams['page'] = $page - 1;
|
||||
$prevUrl = htmlspecialchars('?' . http_build_query($currentParams), ENT_QUOTES, 'UTF-8');
|
||||
echo '<button class="lt-btn lt-btn-sm" data-action="navigate" data-url="' . $prevUrl . '" aria-label="Previous page">«</button>';
|
||||
}
|
||||
$range = range(max(1, $page - 2), min($totalPages, $page + 2));
|
||||
if (!in_array(1, $range)) {
|
||||
$currentParams['page'] = 1;
|
||||
$url1 = htmlspecialchars('?' . http_build_query($currentParams), ENT_QUOTES, 'UTF-8');
|
||||
echo '<button class="lt-btn lt-btn-sm" data-action="navigate" data-url="' . $url1 . '">1</button>';
|
||||
if ($range[0] > 2) echo '<span class="lt-text-muted lt-text-xs" style="padding:0 0.25rem">…</span>';
|
||||
}
|
||||
foreach ($range as $i) {
|
||||
$currentParams['page'] = $i;
|
||||
$iUrl = htmlspecialchars('?' . http_build_query($currentParams), ENT_QUOTES, 'UTF-8');
|
||||
$activeClass = ($i === $page) ? ' lt-btn-primary' : '';
|
||||
echo '<button class="lt-btn lt-btn-sm' . $activeClass . '" data-action="navigate" data-url="' . $iUrl . '" ' . ($i === $page ? 'aria-current="page"' : '') . '>' . $i . '</button>';
|
||||
}
|
||||
if (!in_array($totalPages, $range)) {
|
||||
if ($range[count($range)-1] < $totalPages - 1) echo '<span class="lt-text-muted lt-text-xs" style="padding:0 0.25rem">…</span>';
|
||||
$currentParams['page'] = $totalPages;
|
||||
$urlLast = htmlspecialchars('?' . http_build_query($currentParams), ENT_QUOTES, 'UTF-8');
|
||||
echo '<button class="lt-btn lt-btn-sm" data-action="navigate" data-url="' . $urlLast . '">' . $totalPages . '</button>';
|
||||
}
|
||||
if ($page < $totalPages) {
|
||||
$currentParams['page'] = $page + 1;
|
||||
$nextUrl = htmlspecialchars('?' . http_build_query($currentParams), ENT_QUOTES, 'UTF-8');
|
||||
echo '<button class="lt-btn lt-btn-sm" data-action="navigate" data-url="' . $nextUrl . '" aria-label="Next page">»</button>';
|
||||
}
|
||||
?>
|
||||
<?php
|
||||
$currentParams = $_GET;
|
||||
if ($page > 1) {
|
||||
$currentParams['page'] = $page - 1;
|
||||
$prevUrl = htmlspecialchars('?' . http_build_query($currentParams), ENT_QUOTES, 'UTF-8');
|
||||
echo '<button class="lt-btn lt-btn-sm" data-action="navigate" data-url="' . $prevUrl . '" aria-label="Previous page">«</button>';
|
||||
}
|
||||
$range = range(max(1, $page - 2), min($totalPages, $page + 2));
|
||||
if (!in_array(1, $range)) {
|
||||
$currentParams['page'] = 1;
|
||||
$url1 = htmlspecialchars('?' . http_build_query($currentParams), ENT_QUOTES, 'UTF-8');
|
||||
echo '<button class="lt-btn lt-btn-sm" data-action="navigate" data-url="' . $url1 . '">1</button>';
|
||||
if ($range[0] > 2) {
|
||||
echo '<span class="lt-text-muted lt-text-xs" style="padding:0 0.25rem">…</span>';
|
||||
}
|
||||
}
|
||||
foreach ($range as $i) {
|
||||
$currentParams['page'] = $i;
|
||||
$iUrl = htmlspecialchars('?' . http_build_query($currentParams), ENT_QUOTES, 'UTF-8');
|
||||
$activeClass = ($i === $page) ? ' lt-btn-primary' : '';
|
||||
echo '<button class="lt-btn lt-btn-sm' . $activeClass . '" data-action="navigate" data-url="' . $iUrl . '" ' . ($i === $page ? 'aria-current="page"' : '') . '>' . $i . '</button>';
|
||||
}
|
||||
if (!in_array($totalPages, $range)) {
|
||||
if ($range[count($range) - 1] < $totalPages - 1) {
|
||||
echo '<span class="lt-text-muted lt-text-xs" style="padding:0 0.25rem">…</span>';
|
||||
}
|
||||
$currentParams['page'] = $totalPages;
|
||||
$urlLast = htmlspecialchars('?' . http_build_query($currentParams), ENT_QUOTES, 'UTF-8');
|
||||
echo '<button class="lt-btn lt-btn-sm" data-action="navigate" data-url="' . $urlLast . '">' . $totalPages . '</button>';
|
||||
}
|
||||
if ($page < $totalPages) {
|
||||
$currentParams['page'] = $page + 1;
|
||||
$nextUrl = htmlspecialchars('?' . http_build_query($currentParams), ENT_QUOTES, 'UTF-8');
|
||||
echo '<button class="lt-btn lt-btn-sm" data-action="navigate" data-url="' . $nextUrl . '" aria-label="Next page">»</button>';
|
||||
}
|
||||
?>
|
||||
</div>
|
||||
<?php endif ?>
|
||||
|
||||
@@ -904,11 +921,11 @@ include __DIR__ . '/layout_header.php';
|
||||
<div class="lt-kv-row">
|
||||
<span class="lt-kv-label">Default status filters</span>
|
||||
<span class="lt-kv-value lt-flex lt-flex-wrap lt-flex-gap-sm">
|
||||
<?php foreach ($_lt_statuses as $sf): ?>
|
||||
<?php foreach ($_lt_statuses as $sf) : ?>
|
||||
<label class="lt-filter-option">
|
||||
<input type="checkbox" class="lt-checkbox" name="defaultFilters" value="<?= htmlspecialchars($sf) ?>"
|
||||
<?= in_array($sf, ['Open','Pending','In Progress']) ? 'checked' : '' ?>>
|
||||
<?= htmlspecialchars($sf) ?>
|
||||
<?= htmlspecialchars($sf) ?>
|
||||
</label>
|
||||
<?php endforeach ?>
|
||||
</span>
|
||||
@@ -986,14 +1003,14 @@ include __DIR__ . '/layout_header.php';
|
||||
<span class="lt-kv-label">Groups</span>
|
||||
<span class="lt-kv-value">
|
||||
<?php
|
||||
$groups = array_filter(array_map('trim', explode(',', $GLOBALS['currentUser']['groups'] ?? '')));
|
||||
if ($groups):
|
||||
foreach ($groups as $g): ?>
|
||||
$groups = array_filter(array_map('trim', explode(',', $GLOBALS['currentUser']['groups'] ?? '')));
|
||||
if ($groups) :
|
||||
foreach ($groups as $g) : ?>
|
||||
<span class="lt-badge lt-badge-sm"><?= htmlspecialchars($g) ?></span>
|
||||
<?php endforeach;
|
||||
else: ?>
|
||||
<?php endforeach;
|
||||
else : ?>
|
||||
<span class="lt-text-muted">No groups assigned</span>
|
||||
<?php endif ?>
|
||||
<?php endif ?>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
@@ -1086,12 +1103,16 @@ include __DIR__ . '/layout_header.php';
|
||||
<span class="lt-kv-value lt-flex lt-flex-gap-sm lt-flex-align-center">
|
||||
<select id="adv-priority-min" class="lt-select lt-select-sm">
|
||||
<option value="">Any</option>
|
||||
<?php foreach (range(1,5) as $p): ?><option value="<?= $p ?>">P<?= $p ?></option><?php endforeach ?>
|
||||
<?php foreach (range(1, 5) as $p) :
|
||||
?><option value="<?= $p ?>">P<?= $p ?></option><?php
|
||||
endforeach ?>
|
||||
</select>
|
||||
<span class="lt-text-xs lt-text-muted">to</span>
|
||||
<select id="adv-priority-max" class="lt-select lt-select-sm">
|
||||
<option value="">Any</option>
|
||||
<?php foreach (range(1,5) as $p): ?><option value="<?= $p ?>">P<?= $p ?></option><?php endforeach ?>
|
||||
<?php foreach (range(1, 5) as $p) :
|
||||
?><option value="<?= $p ?>">P<?= $p ?></option><?php
|
||||
endforeach ?>
|
||||
</select>
|
||||
</span>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user