mirror of
https://github.com/itflow-org/itflow
synced 2026-08-05 15:17:17 +00:00
Statuses can be flagged to pause the resolution clock; sla_history records the intervals a ticket's clock actually ran and the deadline is re-based on remaining budget when it resumes. Adds SLA Summary and SLA by Client reports, an SLA state filter on the ticket list, SLA colouring on kanban cards, and an Urgent column on the Tickets by Client report. DB update 2.5.1. Also fixes resolution SLA verdicts being skipped when resolving via kanban or the client portal.
475 lines
26 KiB
PHP
475 lines
26 KiB
PHP
<?php
|
|
|
|
// Default Column Sortby Filter
|
|
$sort = "ticket_number";
|
|
$order = "DESC";
|
|
|
|
// If client_id is in URI then show client Side Bar and client header
|
|
if (isset($_GET['client_id'])) {
|
|
require_once "includes/inc_all_client.php";
|
|
$client_query = "AND ticket_client_id = $client_id";
|
|
$client_url = "client_id=$client_id&";
|
|
} else {
|
|
require_once "includes/inc_all.php";
|
|
$client_query = '';
|
|
$client_url = '';
|
|
}
|
|
|
|
// Perms
|
|
enforceUserPermission('module_support');
|
|
|
|
// Ticket status from GET
|
|
if (isset($_GET['status']) && is_array($_GET['status']) && !empty($_GET['status'])) {
|
|
// Sanitize each element of the status array
|
|
$sanitizedStatuses = array();
|
|
foreach ($_GET['status'] as $status) {
|
|
// Escape each status to prevent SQL injection
|
|
$sanitizedStatuses[] = "'" . intval($status) . "'";
|
|
}
|
|
|
|
// Convert the sanitized statuses into a comma-separated string
|
|
$sanitizedStatusesString = implode(",", $sanitizedStatuses);
|
|
$ticket_status_snippet = "ticket_status IN ($sanitizedStatusesString)";
|
|
|
|
} else {
|
|
|
|
// TODO: Convert this to use the status IDs
|
|
if (isset($_GET['status']) && ($_GET['status']) == 'Closed') {
|
|
$status = 'Closed';
|
|
$ticket_status_snippet = "ticket_resolved_at IS NOT NULL";
|
|
} else {
|
|
// Default - Show open tickets
|
|
$status = 'Open';
|
|
$ticket_status_snippet = "ticket_resolved_at IS NULL";
|
|
}
|
|
}
|
|
|
|
if (isset($_GET['billable']) && ($_GET['billable']) == '1') {
|
|
if (isset($_GET['unbilled'])) {
|
|
$billable = 1;
|
|
$ticket_billable_snippet = "AND ticket_billable = 1 AND ticket_invoice_id = 0";
|
|
$ticket_status_snippet = '1 = 1';
|
|
}
|
|
} else {
|
|
$billable = 0;
|
|
$ticket_billable_snippet = '';
|
|
}
|
|
|
|
// Category Filter
|
|
if (isset($_GET['category']) & !empty($_GET['category'])) {
|
|
$category_query = 'AND (ticket_category = ' . intval($_GET['category']) . ')';
|
|
$category_filter = intval($_GET['category']);
|
|
} else {
|
|
// Default - any
|
|
$category_query = '';
|
|
$category_filter = '';
|
|
}
|
|
|
|
// Ticket assignment status filter
|
|
// Default - any
|
|
$ticket_assigned_query = '';
|
|
$ticket_assigned_filter_id = '';
|
|
// SLA state filter - breached / at risk / met / no SLA
|
|
$ticket_sla_query = '';
|
|
$ticket_sla_filter = '';
|
|
if (isset($_GET['sla']) && !empty($_GET['sla'])) {
|
|
$ticket_sla_filter = $_GET['sla'];
|
|
if ($ticket_sla_filter == 'breached') {
|
|
$ticket_sla_query = 'AND ticket_sla_id > 0 AND (ticket_response_sla_alert_stage = 2 OR ticket_resolution_sla_alert_stage = 2 OR ticket_response_sla_met = 0 OR ticket_resolution_sla_met = 0)';
|
|
} elseif ($ticket_sla_filter == 'at_risk') {
|
|
$ticket_sla_query = 'AND ticket_sla_id > 0 AND COALESCE(ticket_status_pauses_sla, 0) = 0 AND (ticket_response_sla_alert_stage = 1 OR ticket_resolution_sla_alert_stage = 1)';
|
|
} elseif ($ticket_sla_filter == 'paused') {
|
|
$ticket_sla_query = 'AND ticket_sla_id > 0 AND ticket_status_pauses_sla = 1';
|
|
} elseif ($ticket_sla_filter == 'met') {
|
|
$ticket_sla_query = 'AND ticket_sla_id > 0 AND ticket_response_sla_met = 1 AND (ticket_resolution_sla_met = 1 OR ticket_resolution_due_at IS NULL)';
|
|
} elseif ($ticket_sla_filter == 'none') {
|
|
$ticket_sla_query = 'AND ticket_sla_id = 0';
|
|
}
|
|
}
|
|
|
|
if (isset($_GET['assigned']) & !empty($_GET['assigned'])) {
|
|
if ($_GET['assigned'] == 'unassigned') {
|
|
$ticket_assigned_query = 'AND ticket_assigned_to = 0';
|
|
$ticket_assigned_filter_id = 0;
|
|
} else {
|
|
$ticket_assigned_query = 'AND ticket_assigned_to = ' . intval($_GET['assigned']);
|
|
$ticket_assigned_filter_id = intval($_GET['assigned']);
|
|
}
|
|
}
|
|
|
|
// Project filter
|
|
// Default - any (including tickets without a project)
|
|
$ticket_project_snippet = '';
|
|
$ticket_project_filter_id = '';
|
|
if (isset($_GET['project']) & !empty($_GET['project']) && $_GET['project'] > '0') {
|
|
$ticket_project_snippet = 'AND ticket_project_id = ' . intval($_GET['project']);
|
|
$ticket_project_filter_id = intval($_GET['project']);
|
|
}
|
|
|
|
// Ticket client access overide - This is the only way to show tickets without a client to agents with restricted client access
|
|
$access_permission_query_overide = '';
|
|
if ($client_access_string) {
|
|
$access_permission_query_overide = "AND ticket_client_id IN (0,$client_access_string)";
|
|
}
|
|
|
|
// Main ticket query:
|
|
$query =
|
|
"SELECT SQL_CALC_FOUND_ROWS * FROM tickets
|
|
LEFT JOIN clients ON ticket_client_id = client_id
|
|
LEFT JOIN contacts ON ticket_contact_id = contact_id
|
|
LEFT JOIN users ON ticket_assigned_to = user_id
|
|
LEFT JOIN assets ON ticket_asset_id = asset_id
|
|
LEFT JOIN locations ON ticket_location_id = location_id
|
|
LEFT JOIN vendors ON ticket_vendor_id = vendor_id
|
|
LEFT JOIN ticket_statuses ON ticket_status = ticket_status_id
|
|
LEFT JOIN categories ON ticket_category = category_id
|
|
WHERE $ticket_status_snippet " . $ticket_assigned_query . "
|
|
$category_query
|
|
AND DATE(ticket_created_at) BETWEEN '$dtf' AND '$dtt'
|
|
AND (CONCAT(ticket_prefix,ticket_number) LIKE '%$q%' OR client_name LIKE '%$q%' OR ticket_subject LIKE '%$q%' OR ticket_status_name LIKE '%$q%' OR ticket_priority LIKE '%$q%' OR user_name LIKE '%$q%' OR contact_name LIKE '%$q%' OR asset_name LIKE '%$q%' OR vendor_name LIKE '%$q%' OR ticket_vendor_ticket_number LIKE '%q%')
|
|
$ticket_sla_query
|
|
$ticket_billable_snippet
|
|
$ticket_project_snippet
|
|
$access_permission_query_overide
|
|
$client_query
|
|
ORDER BY
|
|
CASE
|
|
WHEN '$sort' = 'ticket_priority' THEN
|
|
CASE ticket_priority
|
|
WHEN 'Urgent' THEN 0
|
|
WHEN 'High' THEN 1
|
|
WHEN 'Medium' THEN 2
|
|
WHEN 'Low' THEN 3
|
|
ELSE 4 -- Optional: for unexpected priority values
|
|
END
|
|
ELSE NULL
|
|
END $order,
|
|
$sort $order -- Apply normal sorting by $sort and $order
|
|
LIMIT $record_from, $record_to";
|
|
|
|
$sql = mysqli_query($mysqli,$query);
|
|
|
|
$num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
|
|
|
|
//Get Total tickets open
|
|
$sql_total_tickets_open = mysqli_query($mysqli, "SELECT COUNT(ticket_id) AS total_tickets_open FROM tickets WHERE ticket_resolved_at IS NULL $client_query $access_permission_query_overide");
|
|
$row = mysqli_fetch_assoc($sql_total_tickets_open);
|
|
$total_tickets_open = intval($row['total_tickets_open']);
|
|
|
|
//Get Total tickets closed
|
|
$sql_total_tickets_closed = mysqli_query($mysqli, "SELECT COUNT(ticket_id) AS total_tickets_closed FROM tickets WHERE ticket_resolved_at IS NOT NULL $client_query $access_permission_query_overide");
|
|
$row = mysqli_fetch_assoc($sql_total_tickets_closed);
|
|
$total_tickets_closed = intval($row['total_tickets_closed']);
|
|
|
|
//Get Unassigned tickets
|
|
$sql_total_tickets_unassigned = mysqli_query($mysqli, "SELECT COUNT(ticket_id) AS total_tickets_unassigned FROM tickets WHERE ticket_assigned_to = '0' AND ticket_resolved_at IS NULL $client_query $access_permission_query_overide");
|
|
$row = mysqli_fetch_assoc($sql_total_tickets_unassigned);
|
|
$total_tickets_unassigned = intval($row['total_tickets_unassigned']);
|
|
|
|
//Get Total tickets assigned to me
|
|
$sql_total_tickets_assigned = mysqli_query($mysqli, "SELECT COUNT(ticket_id) AS total_tickets_assigned FROM tickets WHERE ticket_assigned_to = $session_user_id AND ticket_resolved_at IS NULL $client_query $access_permission_query_overide");
|
|
$row = mysqli_fetch_assoc($sql_total_tickets_assigned);
|
|
$user_active_assigned_tickets = intval($row['total_tickets_assigned']);
|
|
|
|
$sql_categories_filter = mysqli_query(
|
|
$mysqli,
|
|
"SELECT * FROM categories
|
|
WHERE category_type = 'Ticket'
|
|
AND category_archived_at IS NULL
|
|
ORDER BY category_name"
|
|
);
|
|
|
|
?>
|
|
<style>
|
|
.popover {
|
|
max-width: 600px;
|
|
}
|
|
</style>
|
|
<div class="card card-dark">
|
|
<div class="card-header py-2">
|
|
<h3 class="card-title mt-2"><i class="fa fa-fw fa-life-ring mr-2"></i>Tickets
|
|
<small class="ml-3">
|
|
<a href="?<?= $client_url ?>status=Open" class="badge badge-pill text-light p-1 <?php if($status == 'Open') { echo "badge-light text-dark"; } ?>"><strong><?= $total_tickets_open ?></strong> Open</a> |
|
|
<a href="?<?= $client_url ?>status=Closed" class="badge badge-pill text-light p-1 <?php if($status == 'Closed') { echo "badge-light text-dark"; } ?>"><strong><?= $total_tickets_closed ?></strong> Closed</a>
|
|
</small>
|
|
</h3>
|
|
<?php if (lookupUserPermission("module_support") >= 2) { ?>
|
|
<div class="card-tools">
|
|
<div class="btn-group">
|
|
<button type="button" class="btn btn-primary ajax-modal" data-modal-url="modals/ticket/ticket_add_v2.php?<?= $client_url ?>" data-modal-size="lg">
|
|
<i class="fas fa-plus"></i><span class="d-none d-lg-inline ml-2">New Ticket</span>
|
|
</button>
|
|
<?php if ($num_rows[0] > 0) { ?>
|
|
<button type="button" class="btn btn-primary dropdown-toggle dropdown-toggle-split" data-toggle="dropdown"></button>
|
|
<div class="dropdown-menu">
|
|
<a class="dropdown-item text-dark ajax-modal" href="#"
|
|
data-modal-url="modals/ticket/ticket_export.php?<?= $client_url ?>">
|
|
<i class="fa fa-fw fa-download mr-2"></i>Export
|
|
</a>
|
|
</div>
|
|
<?php } ?>
|
|
</div>
|
|
</div>
|
|
<?php } ?>
|
|
</div>
|
|
<div class="card-body">
|
|
<form autocomplete="off">
|
|
<?php if ($client_url) { ?>
|
|
<input type="hidden" name="client_id" value="<?= $client_id ?>">
|
|
<?php } ?>
|
|
<input type="hidden" name="status" value="<?= $status ?>">
|
|
<input type="hidden" name="view" value="<?= escapeHtml($_GET['view'] ?? 'list') ?>">
|
|
<div class="row">
|
|
<div class="col-sm-4">
|
|
<div class="input-group mb-3 mb-sm-0">
|
|
<input type="search" class="form-control" name="q" value="<?php if (isset($q)) { echo stripslashes(escapeHtml($q)); } ?>" placeholder="Search Tickets">
|
|
<div class="input-group-append">
|
|
<button class="btn btn-secondary" type="button" data-toggle="collapse" data-target="#advancedFilter"><i class="fas fa-filter"></i></button>
|
|
<button class="btn btn-primary"><i class="fa fa-search"></i></button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<?php
|
|
// Only offer the SLA filter once SLAs are actually in use
|
|
$sla_filter_in_use = mysqli_fetch_row(mysqli_query($mysqli, "SELECT COUNT(sla_id) FROM slas WHERE sla_archived_at IS NULL"))[0] > 0;
|
|
if ($sla_filter_in_use) { ?>
|
|
<div class="col-sm-3">
|
|
<div class="form-group">
|
|
<select class="form-control select2" name="sla" onchange="this.form.submit()">
|
|
<option value="">- All SLA States -</option>
|
|
<option <?php if ($ticket_sla_filter == 'breached') { echo "selected"; } ?> value="breached">SLA breached</option>
|
|
<option <?php if ($ticket_sla_filter == 'at_risk') { echo "selected"; } ?> value="at_risk">SLA at risk</option>
|
|
<option <?php if ($ticket_sla_filter == 'paused') { echo "selected"; } ?> value="paused">SLA paused</option>
|
|
<option <?php if ($ticket_sla_filter == 'met') { echo "selected"; } ?> value="met">SLA met</option>
|
|
<option <?php if ($ticket_sla_filter == 'none') { echo "selected"; } ?> value="none">No SLA</option>
|
|
</select>
|
|
</div>
|
|
</div>
|
|
<?php } ?>
|
|
|
|
<div class="col-sm-3">
|
|
<div class="form-group">
|
|
<select class="form-control select2" name="category" onchange="this.form.submit()">
|
|
<option value="">- All Categories -</option>
|
|
|
|
<?php
|
|
while ($row = mysqli_fetch_assoc($sql_categories_filter)) {
|
|
$category_id = intval($row['category_id']);
|
|
$category_name = escapeHtml($row['category_name']);
|
|
?>
|
|
<option <?php if ($category_filter == $category_id) { echo "selected"; } ?> value="<?= $category_id ?>"><?= $category_name ?></option>
|
|
<?php
|
|
}
|
|
?>
|
|
|
|
</select>
|
|
</div>
|
|
</div>
|
|
<div class="col-sm-5">
|
|
<div class="btn-group float-right">
|
|
<div class="btn-group">
|
|
<button class="btn btn-outline-dark dropdown-toggle" id="dropdownMenuButton" data-toggle="dropdown">
|
|
<i class="fa fa-fw fa-eye"></i>
|
|
<span class="d-none d-xl-inline ml-2">View</span>
|
|
</button>
|
|
<div class="dropdown-menu">
|
|
<a class="dropdown-item" href="<?=htmlspecialchars('?' . http_build_query(array_merge($_GET, ['view' => 'list']))); ?>">List</a>
|
|
<?php if ($status !== 'Closed') {?>
|
|
<div class="dropdown-divider"></div>
|
|
<a class="dropdown-item " href="<?=htmlspecialchars('?' . http_build_query(array_merge($_GET, ['view' => 'kanban']))); ?>">Kanban</a>
|
|
<?php } ?>
|
|
</div>
|
|
</div>
|
|
<div class="btn-group">
|
|
<button class="btn btn-outline-dark dropdown-toggle" id="categoriesDropdownMenuButton" data-toggle="dropdown">
|
|
<i class="fa fa-fw fa-envelope"></i>
|
|
<span class="d-none d-xl-inline ml-2">My Tickets</span>
|
|
</button>
|
|
<div class="dropdown-menu">
|
|
<a class="dropdown-item" href="?<?= $client_url ?>status=Open&assigned=<?= $session_user_id ?>">Active tickets (<?= $user_active_assigned_tickets ?>)</a>
|
|
<div class="dropdown-divider"></div>
|
|
<a class="dropdown-item " href="?<?= $client_url ?>status=Closed&assigned=<?= $session_user_id ?>">Closed tickets</a>
|
|
</div>
|
|
</div>
|
|
<a href="?<?= $client_url ?>assigned=unassigned" class="btn btn-outline-danger">
|
|
<i class="fa fa-fw fa-exclamation-triangle"></i>
|
|
<span class="d-none d-xl-inline ml-2">Unassigned</span> | <strong> <?= $total_tickets_unassigned ?></strong>
|
|
</a>
|
|
|
|
<?php if (lookupUserPermission("module_support") >= 2) { ?>
|
|
<div class="dropdown ml-2" id="bulkActionButton" hidden>
|
|
<button class="btn btn-secondary dropdown-toggle" type="button" data-toggle="dropdown">
|
|
<i class="fas fa-fw fa-layer-group mr-2"></i>Bulk Action (<span id="selectedCount">0</span>)
|
|
</button>
|
|
<div class="dropdown-menu">
|
|
<a class="dropdown-item ajax-modal" href="#"
|
|
data-modal-url="modals/ticket/ticket_bulk_assign.php"
|
|
data-bulk="true">
|
|
<i class="fas fa-fw fa-user-check mr-2"></i>Assign Agent
|
|
</a>
|
|
<div class="dropdown-divider"></div>
|
|
<a class="dropdown-item ajax-modal" href="#"
|
|
data-modal-url="modals/ticket/ticket_bulk_edit_category.php"
|
|
data-bulk="true">
|
|
<i class="fas fa-fw fa-layer-group mr-2"></i>Set Category
|
|
</a>
|
|
<div class="dropdown-divider"></div>
|
|
<a class="dropdown-item ajax-modal" href="#"
|
|
data-modal-url="modals/ticket/ticket_bulk_edit_priority.php"
|
|
data-bulk="true">
|
|
<i class="fas fa-fw fa-thermometer-half mr-2"></i>Set Priority
|
|
</a>
|
|
<div class="dropdown-divider"></div>
|
|
<a class="dropdown-item ajax-modal" href="#"
|
|
data-modal-url="modals/ticket/ticket_bulk_reply.php"
|
|
data-modal-size="lg"
|
|
data-bulk="true">
|
|
<i class="fas fa-fw fa-paper-plane mr-2"></i>Update/Reply
|
|
</a>
|
|
<div class="dropdown-divider"></div>
|
|
<a class="dropdown-item ajax-modal" href="#"
|
|
data-modal-url="modals/ticket/ticket_bulk_add_project.php"
|
|
data-bulk="true">
|
|
<i class="fas fa-fw fa-project-diagram mr-2"></i>Set Project
|
|
</a>
|
|
<div class="dropdown-divider"></div>
|
|
<a class="dropdown-item ajax-modal" href="#"
|
|
data-modal-url="modals/ticket/ticket_bulk_merge.php"
|
|
data-bulk="true">
|
|
<i class="fas fa-fw fa-clone mr-2"></i>Merge
|
|
</a>
|
|
<div class="dropdown-divider"></div>
|
|
<a class="dropdown-item ajax-modal" href="#"
|
|
data-modal-url="modals/ticket/ticket_bulk_resolve.php"
|
|
data-modal-size="lg"
|
|
data-bulk="true">
|
|
<i class="fas fa-fw fa-check mr-2"></i>Resolve
|
|
</a>
|
|
<?php if (lookupUserPermission("module_support") === 3) { ?>
|
|
<div class="dropdown-divider"></div>
|
|
<button class="dropdown-item text-danger text-bold confirm-link" type="submit" form="bulkActions" name="bulk_delete_tickets">
|
|
<i class="fas fa-fw fa-trash mr-2"></i>Delete
|
|
</button>
|
|
<?php } ?>
|
|
</div>
|
|
</div>
|
|
<?php } ?>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
</div>
|
|
|
|
<div
|
|
class="collapse mt-3
|
|
<?php
|
|
if (isset($_GET['dtf']) && $_GET['dtf'] !== '1970-01-01'
|
|
|| (isset($_GET['status']) && is_array($_GET['status'])
|
|
|| (isset($_GET['assigned']) && $_GET['assigned']
|
|
)))
|
|
{ echo "show"; }
|
|
?>"
|
|
id="advancedFilter"
|
|
>
|
|
<div class="row">
|
|
<div class="col-md-3">
|
|
<div class="form-group">
|
|
<label>Date range</label>
|
|
<input type="text" id="dateFilter" class="form-control" autocomplete="off">
|
|
<input type="hidden" name="canned_date" id="canned_date" value="<?= escapeHtml($_GET['canned_date']) ?? '' ?>">
|
|
<input type="hidden" name="dtf" id="dtf" value="<?= escapeHtml($dtf ?? '') ?>">
|
|
<input type="hidden" name="dtt" id="dtt" value="<?= escapeHtml($dtt ?? '') ?>">
|
|
</div>
|
|
</div>
|
|
<div class="col-md-3">
|
|
<div class="form-group">
|
|
<label>Ticket Status</label>
|
|
<select onchange="this.form.submit()" class="form-control select2" name="status[]" data-placeholder="Select Status" multiple>
|
|
|
|
<?php $sql_ticket_status = mysqli_query($mysqli, "SELECT * FROM ticket_statuses WHERE ticket_status_active = 1 ORDER BY ticket_status_order");
|
|
while ($row = mysqli_fetch_assoc($sql_ticket_status)) {
|
|
$ticket_status_id = intval($row['ticket_status_id']);
|
|
$ticket_status_name = escapeHtml($row['ticket_status_name']); ?>
|
|
|
|
<option value="<?= $ticket_status_id ?>" <?php if (isset($_GET['status']) && is_array($_GET['status']) && in_array($ticket_status_id, $_GET['status'])) { echo 'selected'; } ?>> <?= $ticket_status_name ?> </option>
|
|
|
|
<?php } ?>
|
|
</select>
|
|
</div>
|
|
</div>
|
|
<div class="col-md-3">
|
|
<div class="form-group">
|
|
<label>Assigned to</label>
|
|
<select onchange="this.form.submit()" class="form-control select2" name="assigned">
|
|
<option value="" <?php if ($ticket_assigned_filter_id == "") { echo "selected"; } ?>>Any</option>
|
|
<option value="unassigned" <?php if ($ticket_assigned_filter_id == "0") { echo "selected"; } ?>>Unassigned</option>
|
|
|
|
<?php
|
|
$sql_assign_to = mysqli_query($mysqli, "SELECT * FROM users WHERE user_type = 1 AND user_archived_at IS NULL ORDER BY user_name ASC");
|
|
while ($row = mysqli_fetch_assoc($sql_assign_to)) {
|
|
$user_id = intval($row['user_id']);
|
|
$user_name = escapeHtml($row['user_name']);
|
|
?>
|
|
<option <?php if ($ticket_assigned_filter_id == $user_id) { echo "selected"; } ?> value="<?= $user_id ?>"><?= $user_name ?></option>
|
|
<?php
|
|
}
|
|
?>
|
|
|
|
</select>
|
|
</div>
|
|
</div>
|
|
<div class="col-md-3">
|
|
<div class="form-group">
|
|
<label>Project</label>
|
|
<select onchange="this.form.submit()" class="form-control select2" name="project">
|
|
<option value="" <?php if ($ticket_project_filter_id == "") { echo "selected"; } ?>>Any</option>
|
|
|
|
<?php
|
|
$sql_projects = mysqli_query($mysqli, "SELECT * FROM projects WHERE project_completed_at IS NULL and project_archived_at IS NULL ORDER BY project_name ASC");
|
|
while ($row = mysqli_fetch_assoc($sql_projects)) {
|
|
$project_id = intval($row['project_id']);
|
|
$project_prefix = escapeHtml($row['project_prefix']);
|
|
$project_number = intval($row['project_number']);
|
|
$project_name = escapeHtml($row['project_name']);
|
|
?>
|
|
<option <?php if ($ticket_project_filter_id == $project_id) { echo "selected"; } ?> value="<?= $project_id ?>"><?= $project_prefix . $project_number . " - " . $project_name ?></option>
|
|
<?php
|
|
}
|
|
?>
|
|
|
|
</select>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
|
|
<?php
|
|
|
|
if (isset($_GET["view"])) {
|
|
if ($_GET["view"] == "list") {
|
|
require_once "ticket_list.php";
|
|
} elseif ($_GET["view"] == "kanban") {
|
|
require_once "ticket_kanban.php";
|
|
}
|
|
} else {
|
|
// here we have to get default view setting
|
|
if ($config_ticket_default_view === 0) {
|
|
require_once "ticket_list.php";
|
|
} elseif ($config_ticket_default_view === 2) {
|
|
require_once "ticket_kanban.php";
|
|
} else {
|
|
require_once "ticket_list.php";
|
|
}
|
|
}
|
|
|
|
?>
|
|
|
|
<script src="../js/bulk_actions.js"></script>
|
|
|
|
<?php
|
|
require_once "../includes/footer.php";
|