mirror of
https://github.com/itflow-org/itflow
synced 2026-08-05 07:07:14 +00:00
Feature: Add Dynamic Task editing in add ticket and add recurring ticket, recurring tickets now have their own task table as well
This commit is contained in:
53
agent/includes/inc_ticket_tasks_section.php
Normal file
53
agent/includes/inc_ticket_tasks_section.php
Normal file
@@ -0,0 +1,53 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* ITFlow - Editable task rows
|
||||
*
|
||||
* Shared by the ticket add modal and the recurring ticket add/edit modals. Rows
|
||||
* are added and removed in the browser by agent/js/ticket_tasks_modal.js and
|
||||
* submit as parallel tasks[] / task_estimates[] arrays, read back by
|
||||
* parseSubmittedTasks().
|
||||
*
|
||||
* Set $existing_tasks before including to pre-fill rows - a list of
|
||||
* ['name' => string, 'estimate' => int]. Defaults to none.
|
||||
*
|
||||
* The tasks_submitted marker distinguishes "the user cleared every row" from
|
||||
* "this form has no task section", which an empty tasks[] cannot express because
|
||||
* a form with no inputs of that name posts nothing at all.
|
||||
*/
|
||||
|
||||
$existing_tasks = $existing_tasks ?? [];
|
||||
|
||||
?>
|
||||
|
||||
<input type="hidden" name="tasks_submitted" value="1">
|
||||
|
||||
<div class="form-group">
|
||||
<label>Tasks</label>
|
||||
|
||||
<div class="form-row mb-1 text-muted small">
|
||||
<div class="col-7">Task</div>
|
||||
<div class="col-3">Estimate (mins)</div>
|
||||
<div class="col-2"></div>
|
||||
</div>
|
||||
|
||||
<div id="ticketTasksContainer">
|
||||
<?php foreach ($existing_tasks as $existing_task) { ?>
|
||||
<div class="form-row mb-2 ticket-task-row">
|
||||
<div class="col-7">
|
||||
<input type="text" class="form-control" name="tasks[]" placeholder="Task name" maxlength="255" value="<?= escapeHtml($existing_task['name']) ?>">
|
||||
</div>
|
||||
<div class="col-3">
|
||||
<input type="number" class="form-control" name="task_estimates[]" placeholder="Mins" min="0" value="<?= intval($existing_task['estimate']) ?: '' ?>">
|
||||
</div>
|
||||
<div class="col-2">
|
||||
<button type="button" class="btn btn-secondary btn-block ticket-task-remove" title="Remove task"><i class="fa fa-fw fa-trash"></i></button>
|
||||
</div>
|
||||
</div>
|
||||
<?php } ?>
|
||||
</div>
|
||||
|
||||
<button type="button" class="btn btn-secondary" id="ticketTaskAdd"><i class="fas fa-plus mr-2"></i>Add Task</button>
|
||||
|
||||
<small class="form-text text-muted">Leave the estimate blank if you don't track one. Blank task names are ignored.</small>
|
||||
</div>
|
||||
73
agent/includes/inc_ticket_template_select.php
Normal file
73
agent/includes/inc_ticket_template_select.php
Normal file
@@ -0,0 +1,73 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* ITFlow - Ticket template picker
|
||||
*
|
||||
* Shared by the ticket add modal and the recurring ticket add/edit modals. Each
|
||||
* option carries the template's subject, details and task list as data
|
||||
* attributes, which agent/js/ticket_tasks_modal.js applies to the form when the
|
||||
* template is picked.
|
||||
*
|
||||
* Set $selected_ticket_template_id before including to pre-select a template (an
|
||||
* archived one stays listed while it is the one selected, so an existing link
|
||||
* remains visible). Defaults to none.
|
||||
*/
|
||||
|
||||
$selected_ticket_template_id = intval($selected_ticket_template_id ?? 0);
|
||||
|
||||
// Every template's tasks in one pass, rather than a query per option
|
||||
$ticket_template_tasks = [];
|
||||
|
||||
$sql_ticket_template_tasks = mysqli_query(
|
||||
$mysqli,
|
||||
"SELECT task_template_ticket_template_id, task_template_name, task_template_completion_estimate
|
||||
FROM task_templates
|
||||
ORDER BY task_template_order ASC, task_template_id ASC"
|
||||
);
|
||||
|
||||
while ($row = mysqli_fetch_assoc($sql_ticket_template_tasks)) {
|
||||
$ticket_template_tasks[intval($row['task_template_ticket_template_id'])][] = [
|
||||
'name' => $row['task_template_name'],
|
||||
'estimate' => intval($row['task_template_completion_estimate'])
|
||||
];
|
||||
}
|
||||
|
||||
?>
|
||||
|
||||
<div class="form-group">
|
||||
<label>Template</label>
|
||||
<div class="input-group">
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text"><i class="fa fa-fw fa-cube"></i></span>
|
||||
</div>
|
||||
<select class="form-control select2" id="ticket_template_select" name="ticket_template_id">
|
||||
<option value="0">- No Template -</option>
|
||||
<?php
|
||||
$sql_ticket_templates = mysqli_query(
|
||||
$mysqli,
|
||||
"SELECT ticket_template_id, ticket_template_name, ticket_template_subject, ticket_template_details
|
||||
FROM ticket_templates
|
||||
WHERE ticket_template_archived_at IS NULL OR ticket_template_id = $selected_ticket_template_id
|
||||
ORDER BY ticket_template_name ASC"
|
||||
);
|
||||
|
||||
while ($row = mysqli_fetch_assoc($sql_ticket_templates)) {
|
||||
$ticket_template_id_select = intval($row['ticket_template_id']);
|
||||
$ticket_template_name_select = escapeHtml($row['ticket_template_name']);
|
||||
$ticket_template_subject_select = escapeHtml($row['ticket_template_subject']);
|
||||
$ticket_template_details_select = escapeHtml($row['ticket_template_details']);
|
||||
$ticket_template_task_list = $ticket_template_tasks[$ticket_template_id_select] ?? [];
|
||||
$task_count = count($ticket_template_task_list);
|
||||
?>
|
||||
<option value="<?= $ticket_template_id_select ?>"
|
||||
data-subject="<?= $ticket_template_subject_select ?>"
|
||||
data-details="<?= $ticket_template_details_select ?>"
|
||||
data-tasks="<?= escapeHtml(json_encode($ticket_template_task_list)) ?>"
|
||||
<?php if ($selected_ticket_template_id == $ticket_template_id_select) { echo "selected"; } ?>>
|
||||
<?= $ticket_template_name_select ?> (<?= $task_count ?> tasks)
|
||||
</option>
|
||||
<?php } ?>
|
||||
</select>
|
||||
</div>
|
||||
<small class="form-text text-muted">Picking a template fills in the subject, details and tasks below. You can edit them afterwards.</small>
|
||||
</div>
|
||||
Reference in New Issue
Block a user