feat(helpdesk): redesign handover edit page sidebar
- JOIN users table in findById for created/updated-by display names - Fix row mapping to handle merged JOIN results - Use product name instead of debitor name in page title - Sidebar: collapsible customer/product sections, status dropdown, audit partial with user attribution Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -41,7 +41,13 @@ class HandoverRepository
|
|||||||
}
|
}
|
||||||
|
|
||||||
$row = DB::selectOne(
|
$row = DB::selectOne(
|
||||||
'SELECT * FROM helpdesk_handovers WHERE id = ? AND tenant_id = ? LIMIT 1',
|
'SELECT h.*,'
|
||||||
|
. ' uc.display_name AS created_by_label, uc.uuid AS created_by_uuid,'
|
||||||
|
. ' uu.display_name AS updated_by_label, uu.uuid AS updated_by_uuid'
|
||||||
|
. ' FROM helpdesk_handovers h'
|
||||||
|
. ' LEFT JOIN users uc ON uc.id = h.created_by'
|
||||||
|
. ' LEFT JOIN users uu ON uu.id = h.updated_by'
|
||||||
|
. ' WHERE h.id = ? AND h.tenant_id = ? LIMIT 1',
|
||||||
(string) $id,
|
(string) $id,
|
||||||
(string) $tenantId
|
(string) $tenantId
|
||||||
);
|
);
|
||||||
@@ -140,8 +146,18 @@ class HandoverRepository
|
|||||||
if (!is_array($row)) {
|
if (!is_array($row)) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
$item = $row['helpdesk_handovers'] ?? $row;
|
|
||||||
if (!is_array($item) || !isset($item['id'])) {
|
// JOIN queries return nested arrays keyed by table name — merge all sub-arrays
|
||||||
|
$item = [];
|
||||||
|
foreach ($row as $key => $value) {
|
||||||
|
if (is_array($value)) {
|
||||||
|
$item = array_merge($item, $value);
|
||||||
|
} else {
|
||||||
|
$item[$key] = $value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!isset($item['id'])) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -111,8 +111,12 @@ if ($request->isMethod('POST') && $canEdit) {
|
|||||||
$validationSummaryErrors = $errorBag->toArray();
|
$validationSummaryErrors = $errorBag->toArray();
|
||||||
$errors = $errorBag->toFlatList();
|
$errors = $errorBag->toFlatList();
|
||||||
|
|
||||||
$displayName = trim((string) ($handover['debitor_name'] ?? ''));
|
$productCode = (string) ($handover['product_code'] ?? '');
|
||||||
$titleText = $displayName !== '' ? $displayName : (t('Handover') . ' #' . $handoverId);
|
$product = app(\MintyPHP\Module\Helpdesk\Service\SoftwareProductService::class)->findByCode($productCode);
|
||||||
|
$productName = trim((string) ($product['name'] ?? '')) !== ''
|
||||||
|
? $product['name']
|
||||||
|
: (trim((string) ($product['bc_description'] ?? '')) !== '' ? $product['bc_description'] : $productCode);
|
||||||
|
$titleText = t('Handover') . ' ' . $productName;
|
||||||
Buffer::set('title', $titleText);
|
Buffer::set('title', $titleText);
|
||||||
Buffer::set('style_groups', json_encode(['helpdesk']));
|
Buffer::set('style_groups', json_encode(['helpdesk']));
|
||||||
$breadcrumbs = [
|
$breadcrumbs = [
|
||||||
|
|||||||
@@ -58,10 +58,6 @@ $readonly = !$canEdit;
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<?php if ($allowedStatuses && count($allowedStatuses) > 1): ?>
|
|
||||||
<input type="hidden" name="status" value="<?php e($currentStatus); ?>">
|
|
||||||
<?php endif; ?>
|
|
||||||
|
|
||||||
<?php \MintyPHP\Session::getCsrfInput(); ?>
|
<?php \MintyPHP\Session::getCsrfInput(); ?>
|
||||||
</form>
|
</form>
|
||||||
<?php else: ?>
|
<?php else: ?>
|
||||||
@@ -80,8 +76,8 @@ $readonly = !$canEdit;
|
|||||||
<aside id="app-details-aside-section">
|
<aside id="app-details-aside-section">
|
||||||
<div class="app-details-aside-section">
|
<div class="app-details-aside-section">
|
||||||
<hgroup>
|
<hgroup>
|
||||||
<h2><?php e(t('Handover')); ?> #<?php e($handover['id'] ?? ''); ?></h2>
|
<h2>#<?php e($handover['id'] ?? ''); ?></h2>
|
||||||
<p><?php e($handover['product_code'] ?? ''); ?></p>
|
<p><?php e(t('Handover')); ?></p>
|
||||||
</hgroup>
|
</hgroup>
|
||||||
|
|
||||||
<div class="badge-list">
|
<div class="badge-list">
|
||||||
@@ -92,35 +88,59 @@ $readonly = !$canEdit;
|
|||||||
|
|
||||||
<?php if ($canEdit && $allowedStatuses && count($allowedStatuses) > 1): ?>
|
<?php if ($canEdit && $allowedStatuses && count($allowedStatuses) > 1): ?>
|
||||||
<hr>
|
<hr>
|
||||||
<p><small><?php e(t('Change status')); ?></small></p>
|
<label for="handover-status"><small><?php e(t('Status')); ?></small></label>
|
||||||
<div class="helpdesk-handover-status-actions">
|
<select id="handover-status" name="status" form="<?php e($formId); ?>">
|
||||||
<?php foreach ($allowedStatuses as $status):
|
<?php foreach ($allowedStatuses as $status): ?>
|
||||||
if ($status === $currentStatus) {
|
<option value="<?php e($status); ?>"<?php if ($status === $currentStatus): ?> selected<?php endif; ?>>
|
||||||
continue;
|
|
||||||
}
|
|
||||||
?>
|
|
||||||
<button
|
|
||||||
type="button"
|
|
||||||
class="secondary outline small"
|
|
||||||
onclick="document.querySelector('input[name=status]').value='<?php e($status); ?>';document.getElementById('<?php e($formId); ?>').requestSubmit();"
|
|
||||||
>
|
|
||||||
<?php e(HandoverService::statusLabel($status)); ?>
|
<?php e(HandoverService::statusLabel($status)); ?>
|
||||||
</button>
|
</option>
|
||||||
<?php endforeach; ?>
|
<?php endforeach; ?>
|
||||||
</div>
|
</select>
|
||||||
<?php endif; ?>
|
<?php endif; ?>
|
||||||
|
|
||||||
|
<?php
|
||||||
|
$debitorNo = trim((string) ($handover['debitor_no'] ?? ''));
|
||||||
|
$debitorName = trim((string) ($handover['debitor_name'] ?? ''));
|
||||||
|
?>
|
||||||
|
<details name="handover-aside" open>
|
||||||
|
<summary><?php e(t('Customer')); ?></summary>
|
||||||
|
<hr>
|
||||||
|
<p>
|
||||||
|
<?php if ($debitorNo !== ''): ?>
|
||||||
|
<a href="<?php e(lurl('helpdesk/debitor/' . rawurlencode($debitorNo))); ?>"><?php e($debitorName !== '' ? $debitorName : $debitorNo); ?></a>
|
||||||
|
<?php else: ?>
|
||||||
|
<?php e($debitorName); ?>
|
||||||
|
<?php endif; ?>
|
||||||
|
</p>
|
||||||
|
<?php if ($debitorNo !== '' && $debitorName !== ''): ?>
|
||||||
|
<p><small><?php e(t('Debitor No.')); ?></small><br><?php e($debitorNo); ?></p>
|
||||||
|
<?php endif; ?>
|
||||||
|
</details>
|
||||||
<hr>
|
<hr>
|
||||||
<p><small><?php e(t('Customer')); ?></small><br><?php e($handover['debitor_name'] ?? ''); ?></p>
|
|
||||||
<p><small><?php e(t('Debitor No.')); ?></small><br><?php e($handover['debitor_no'] ?? ''); ?></p>
|
|
||||||
|
|
||||||
|
<details name="handover-aside" open>
|
||||||
|
<summary><?php e(t('Software product')); ?></summary>
|
||||||
|
<hr>
|
||||||
|
<p><?php e($productName ?? ($handover['product_code'] ?? '')); ?></p>
|
||||||
|
<?php if (($productName ?? '') !== ($handover['product_code'] ?? '')): ?>
|
||||||
|
<p><small><?php e(t('Code')); ?></small><br><span class="badge" data-variant="neutral"><?php e($handover['product_code'] ?? ''); ?></span></p>
|
||||||
|
<?php endif; ?>
|
||||||
|
</details>
|
||||||
<hr>
|
<hr>
|
||||||
<?php if (!empty($handover['created_at'])): ?>
|
|
||||||
<p><small><?php e(t('Created')); ?></small><br><?php e(dt($handover['created_at'])); ?></p>
|
<?php
|
||||||
<?php endif; ?>
|
$asideAuditDetailsName = 'handover-aside';
|
||||||
<?php if (!empty($handover['updated_at'])): ?>
|
$asideAuditOpen = false;
|
||||||
<p><small><?php e(t('Modified')); ?></small><br><?php e(dt($handover['updated_at'])); ?></p>
|
$asideAuditCreated = (string) ($handover['created_at'] ?? '');
|
||||||
<?php endif; ?>
|
$asideAuditCreatedByLabel = (string) ($handover['created_by_label'] ?? '');
|
||||||
|
$asideAuditCreatedById = $handover['created_by'] ?? null;
|
||||||
|
$asideAuditCreatedByUuid = (string) ($handover['created_by_uuid'] ?? '');
|
||||||
|
$asideAuditModified = (string) ($handover['updated_at'] ?? '');
|
||||||
|
$asideAuditModifiedByLabel = (string) ($handover['updated_by_label'] ?? '');
|
||||||
|
$asideAuditModifiedById = $handover['updated_by'] ?? null;
|
||||||
|
$asideAuditModifiedByUuid = (string) ($handover['updated_by_uuid'] ?? '');
|
||||||
|
require templatePath('partials/app-details-aside-audit.phtml');
|
||||||
|
?>
|
||||||
<hr>
|
<hr>
|
||||||
</div>
|
</div>
|
||||||
</aside>
|
</aside>
|
||||||
|
|||||||
Reference in New Issue
Block a user