feat(helpdesk): simplify settings by merging recommendations and controlling into automation tab
Merge 'System recommendations' (5 rules × 3-4 fields) and 'Controlling' (4 rules × 2 fields) into a single 'Automation' tab with two sections: Recommendations and Risk monitoring. Each rule now shows only a toggle and help text; priority fields removed (hardcoded in action). Advanced disclosure for recommendation thresholds. Fix nav highlighting bug where 'Kunden' was also highlighted when Settings was active. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -268,5 +268,21 @@
|
||||
"Last 30 days": "Letzte 30 Tage",
|
||||
"Last 90 days": "Letzte 90 Tage",
|
||||
"Last 180 days": "Letzte 180 Tage",
|
||||
"Last 365 days": "Letzte 365 Tage"
|
||||
"Last 365 days": "Letzte 365 Tage",
|
||||
"Automation": "Automatisierung",
|
||||
"Risk monitoring": "Risiko-Monitoring",
|
||||
"rule_help_escalation_overdue": "Empfiehlt Aktion, wenn SLA-Eskalationsfristen überschritten sind.",
|
||||
"rule_help_high_risk_aging": "Erkennt kritische Tickets mit bestimmten Eskalationscodes, die zu lange offen sind.",
|
||||
"rule_help_unassigned_open": "Weist auf offene Tickets hin, die keinem Bearbeiter zugewiesen sind.",
|
||||
"rule_help_stale_open": "Markiert offene Tickets ohne aktuelle Aktivität zur Nachverfolgung.",
|
||||
"rule_help_customer_backlog": "Warnt, wenn ein Kunde zu viele offene Tickets gleichzeitig hat.",
|
||||
"rule_help_ticket_volume": "Löst aus, wenn das Ticketvolumen im Vergleich zur Vorperiode ungewöhnlich ansteigt.",
|
||||
"rule_help_avg_resolution": "Warnt, wenn die durchschnittliche Bearbeitungszeit einen Schwellwert überschreitet.",
|
||||
"rule_help_open_aging": "Erkennt offene Tickets, die zu lange ohne Bearbeitung sind.",
|
||||
"rule_help_unassigned_ratio": "Warnt, wenn zu viele offene Tickets keinem Bearbeiter zugewiesen sind.",
|
||||
"Automation configuration was invalid. Defaults were applied.": "Die Automatisierungskonfiguration war ungültig. Es wurden Standardwerte geladen.",
|
||||
"Advanced options": "Erweiterte Optionen",
|
||||
"Min. overdue": "Mind. überfällig",
|
||||
"Min. age": "Mindestalter",
|
||||
"Min. open": "Mind. offen"
|
||||
}
|
||||
|
||||
@@ -268,5 +268,21 @@
|
||||
"Last 30 days": "Last 30 days",
|
||||
"Last 90 days": "Last 90 days",
|
||||
"Last 180 days": "Last 180 days",
|
||||
"Last 365 days": "Last 365 days"
|
||||
"Last 365 days": "Last 365 days",
|
||||
"Automation": "Automation",
|
||||
"Risk monitoring": "Risk monitoring",
|
||||
"rule_help_escalation_overdue": "Recommends action when SLA escalation deadlines are exceeded.",
|
||||
"rule_help_high_risk_aging": "Detects critical tickets with specific escalation codes that have been open too long.",
|
||||
"rule_help_unassigned_open": "Flags open tickets that are not assigned to any support agent.",
|
||||
"rule_help_stale_open": "Marks open tickets without recent activity for follow-up.",
|
||||
"rule_help_customer_backlog": "Warns when a customer has too many open tickets at once.",
|
||||
"rule_help_ticket_volume": "Triggers when ticket volume rises significantly compared to the previous period.",
|
||||
"rule_help_avg_resolution": "Warns when average resolution time exceeds the threshold.",
|
||||
"rule_help_open_aging": "Detects open tickets that have been without activity for too long.",
|
||||
"rule_help_unassigned_ratio": "Warns when too many open tickets lack an assigned agent.",
|
||||
"Automation configuration was invalid. Defaults were applied.": "Automation configuration was invalid. Defaults were applied.",
|
||||
"Advanced options": "Advanced options",
|
||||
"Min. overdue": "Min. overdue",
|
||||
"Min. age": "Min. age",
|
||||
"Min. open": "Min. open"
|
||||
}
|
||||
|
||||
@@ -72,28 +72,28 @@ if ($request->isMethod('POST')) {
|
||||
'rules' => [
|
||||
'escalation_overdue' => [
|
||||
'enabled' => isset($post['recommendations_escalation_overdue_enabled']),
|
||||
'priority' => (int) ($post['recommendations_escalation_overdue_priority'] ?? 100),
|
||||
'priority' => 100,
|
||||
'min_overdue_minutes' => (int) ($post['recommendations_escalation_overdue_min_overdue_minutes'] ?? 0),
|
||||
],
|
||||
'high_risk_aging' => [
|
||||
'enabled' => isset($post['recommendations_high_risk_aging_enabled']),
|
||||
'priority' => (int) ($post['recommendations_high_risk_aging_priority'] ?? 90),
|
||||
'priority' => 90,
|
||||
'codes' => trim((string) ($post['recommendations_high_risk_aging_codes'] ?? 'MAX,HOCH')),
|
||||
'min_age_hours' => (int) ($post['recommendations_high_risk_aging_min_age_hours'] ?? 8),
|
||||
],
|
||||
'unassigned_open' => [
|
||||
'enabled' => isset($post['recommendations_unassigned_open_enabled']),
|
||||
'priority' => (int) ($post['recommendations_unassigned_open_priority'] ?? 80),
|
||||
'priority' => 80,
|
||||
'min_age_hours' => (int) ($post['recommendations_unassigned_open_min_age_hours'] ?? 2),
|
||||
],
|
||||
'stale_open' => [
|
||||
'enabled' => isset($post['recommendations_stale_open_enabled']),
|
||||
'priority' => (int) ($post['recommendations_stale_open_priority'] ?? 70),
|
||||
'priority' => 70,
|
||||
'min_age_hours' => (int) ($post['recommendations_stale_open_min_age_hours'] ?? 48),
|
||||
],
|
||||
'customer_backlog' => [
|
||||
'enabled' => isset($post['recommendations_customer_backlog_enabled']),
|
||||
'priority' => (int) ($post['recommendations_customer_backlog_priority'] ?? 60),
|
||||
'priority' => 60,
|
||||
'min_open_tickets' => (int) ($post['recommendations_customer_backlog_min_open_tickets'] ?? 6),
|
||||
],
|
||||
],
|
||||
|
||||
@@ -91,15 +91,9 @@ $isOAuth2 = $authMode === HelpdeskSettingsGateway::AUTH_MODE_OAUTH2;
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if ($recommendationsConfigSource === 'fallback_invalid_json'): ?>
|
||||
<?php if ($recommendationsConfigSource === 'fallback_invalid_json' || $controllingConfigSource === 'fallback_invalid_json'): ?>
|
||||
<div class="notice" data-variant="warning" role="alert">
|
||||
<p><?php e(t('System recommendation configuration was invalid. Defaults were applied.')); ?></p>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if ($controllingConfigSource === 'fallback_invalid_json'): ?>
|
||||
<div class="notice" data-variant="warning" role="alert">
|
||||
<p><?php e(t('Controlling risk configuration was invalid. Defaults were applied.')); ?></p>
|
||||
<p><?php e(t('Automation configuration was invalid. Defaults were applied.')); ?></p>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
@@ -116,12 +110,11 @@ $isOAuth2 = $authMode === HelpdeskSettingsGateway::AUTH_MODE_OAUTH2;
|
||||
>
|
||||
<?php Session::getCsrfInput(); ?>
|
||||
|
||||
<div class="app-tabs" data-tabs data-app-component="tabs" data-tabs-param="tab" data-tabs-storage-key="helpdesk-settings-tabs-v1">
|
||||
<div class="app-tabs" data-tabs data-app-component="tabs" data-tabs-param="tab" data-tabs-storage-key="helpdesk-settings-tabs-v2">
|
||||
<div class="app-tabs-nav">
|
||||
<button type="button" data-tab="connection" data-tab-default><?php e(t('Connection')); ?></button>
|
||||
<button type="button" data-tab="auth"><?php e(t('Authentication')); ?></button>
|
||||
<button type="button" data-tab="recommendations"><?php e(t('System recommendations')); ?></button>
|
||||
<button type="button" data-tab="controlling"><?php e(t('Controlling')); ?></button>
|
||||
<button type="button" data-tab="automation"><?php e(t('Automation')); ?></button>
|
||||
</div>
|
||||
|
||||
<div data-tab-panel="connection" class="helpdesk-settings-panel">
|
||||
@@ -282,193 +275,135 @@ $isOAuth2 = $authMode === HelpdeskSettingsGateway::AUTH_MODE_OAUTH2;
|
||||
</details>
|
||||
</div>
|
||||
|
||||
<div data-tab-panel="recommendations" class="helpdesk-settings-panel">
|
||||
<details class="app-details-card" name="helpdesk-recommendations-limits" data-details-key="helpdesk-settings-recommendations-limits" open>
|
||||
<div data-tab-panel="automation" class="helpdesk-settings-panel">
|
||||
<details class="app-details-card" name="helpdesk-recommendations" data-details-key="helpdesk-settings-recommendations-v2" open>
|
||||
<summary>
|
||||
<span class="app-details-card-summary-title"><?php e(t('Maximum recommendations')); ?></span>
|
||||
<span class="app-details-card-summary-title"><?php e(t('Recommendations')); ?></span>
|
||||
</summary>
|
||||
<div class="app-details-card-container">
|
||||
<label class="app-field" for="recommendations_max_items">
|
||||
<span><?php e(t('Maximum recommendations')); ?></span>
|
||||
<input
|
||||
type="number"
|
||||
id="recommendations_max_items"
|
||||
name="recommendations_max_items"
|
||||
min="1"
|
||||
max="20"
|
||||
value="<?php e($recommendationsMaxItems); ?>"
|
||||
>
|
||||
<input type="number" id="recommendations_max_items" name="recommendations_max_items" min="1" max="20" value="<?php e($recommendationsMaxItems); ?>">
|
||||
</label>
|
||||
|
||||
<div class="helpdesk-settings-rules">
|
||||
<label class="helpdesk-settings-rule">
|
||||
<input type="checkbox" role="switch" name="recommendations_escalation_overdue_enabled" <?php if (($ruleEscalationOverdue['enabled'] ?? true) === true): ?>checked<?php endif; ?>>
|
||||
<span class="helpdesk-settings-rule-label"><?php e(t('Escalation overdue')); ?></span>
|
||||
<small><?php e(t('rule_help_escalation_overdue')); ?></small>
|
||||
</label>
|
||||
|
||||
<label class="helpdesk-settings-rule">
|
||||
<input type="checkbox" role="switch" name="recommendations_high_risk_aging_enabled" <?php if (($ruleHighRiskAging['enabled'] ?? true) === true): ?>checked<?php endif; ?>>
|
||||
<span class="helpdesk-settings-rule-label"><?php e(t('High-risk aging')); ?></span>
|
||||
<small><?php e(t('rule_help_high_risk_aging')); ?></small>
|
||||
</label>
|
||||
|
||||
<label class="helpdesk-settings-rule">
|
||||
<input type="checkbox" role="switch" name="recommendations_unassigned_open_enabled" <?php if (($ruleUnassignedOpen['enabled'] ?? true) === true): ?>checked<?php endif; ?>>
|
||||
<span class="helpdesk-settings-rule-label"><?php e(t('Unassigned open')); ?></span>
|
||||
<small><?php e(t('rule_help_unassigned_open')); ?></small>
|
||||
</label>
|
||||
|
||||
<label class="helpdesk-settings-rule">
|
||||
<input type="checkbox" role="switch" name="recommendations_stale_open_enabled" <?php if (($ruleStaleOpen['enabled'] ?? true) === true): ?>checked<?php endif; ?>>
|
||||
<span class="helpdesk-settings-rule-label"><?php e(t('Stale open')); ?></span>
|
||||
<small><?php e(t('rule_help_stale_open')); ?></small>
|
||||
</label>
|
||||
|
||||
<label class="helpdesk-settings-rule">
|
||||
<input type="checkbox" role="switch" name="recommendations_customer_backlog_enabled" <?php if (($ruleCustomerBacklog['enabled'] ?? true) === true): ?>checked<?php endif; ?>>
|
||||
<span class="helpdesk-settings-rule-label"><?php e(t('Customer backlog')); ?></span>
|
||||
<small><?php e(t('rule_help_customer_backlog')); ?></small>
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<details class="helpdesk-settings-advanced" data-details-key="helpdesk-settings-recommendations-advanced">
|
||||
<summary><?php e(t('Advanced options')); ?></summary>
|
||||
<div class="helpdesk-settings-advanced-grid">
|
||||
<label class="app-field">
|
||||
<span><?php e(t('Min. overdue')); ?> (min)</span>
|
||||
<input type="number" name="recommendations_escalation_overdue_min_overdue_minutes" min="0" max="43200" value="<?php e((int) ($ruleEscalationOverdue['min_overdue_minutes'] ?? 0)); ?>">
|
||||
</label>
|
||||
<label class="app-field">
|
||||
<span><?php e(t('High-risk codes (comma separated)')); ?></span>
|
||||
<input type="text" name="recommendations_high_risk_aging_codes" value="<?php e($highRiskCodes); ?>">
|
||||
</label>
|
||||
<label class="app-field">
|
||||
<span><?php e(t('Min. age')); ?> — <?php e(t('High-risk aging')); ?> (h)</span>
|
||||
<input type="number" name="recommendations_high_risk_aging_min_age_hours" min="0" max="720" value="<?php e((int) ($ruleHighRiskAging['min_age_hours'] ?? 8)); ?>">
|
||||
</label>
|
||||
<label class="app-field">
|
||||
<span><?php e(t('Min. age')); ?> — <?php e(t('Unassigned open')); ?> (h)</span>
|
||||
<input type="number" name="recommendations_unassigned_open_min_age_hours" min="0" max="720" value="<?php e((int) ($ruleUnassignedOpen['min_age_hours'] ?? 2)); ?>">
|
||||
</label>
|
||||
<label class="app-field">
|
||||
<span><?php e(t('Min. age')); ?> — <?php e(t('Stale open')); ?> (h)</span>
|
||||
<input type="number" name="recommendations_stale_open_min_age_hours" min="0" max="1440" value="<?php e((int) ($ruleStaleOpen['min_age_hours'] ?? 48)); ?>">
|
||||
</label>
|
||||
<label class="app-field">
|
||||
<span><?php e(t('Min. open')); ?> — <?php e(t('Customer backlog')); ?></span>
|
||||
<input type="number" name="recommendations_customer_backlog_min_open_tickets" min="1" max="500" value="<?php e((int) ($ruleCustomerBacklog['min_open_tickets'] ?? 6)); ?>">
|
||||
</label>
|
||||
</div>
|
||||
</details>
|
||||
</div>
|
||||
</details>
|
||||
|
||||
<details class="app-details-card" name="helpdesk-rule-escalation-overdue" data-details-key="helpdesk-settings-rule-escalation-overdue" open>
|
||||
<details class="app-details-card" name="helpdesk-risk-monitoring" data-details-key="helpdesk-settings-risk-monitoring-v2" open>
|
||||
<summary>
|
||||
<span class="app-details-card-summary-title"><?php e(t('Escalation overdue')); ?></span>
|
||||
<span class="app-details-card-summary-title"><?php e(t('Risk monitoring')); ?></span>
|
||||
</summary>
|
||||
<div class="app-details-card-container helpdesk-settings-rule-grid">
|
||||
<label class="app-field">
|
||||
<input type="checkbox" role="switch" name="recommendations_escalation_overdue_enabled" <?php if (($ruleEscalationOverdue['enabled'] ?? true) === true): ?>checked<?php endif; ?>>
|
||||
<span><?php e(t('Enabled')); ?></span>
|
||||
</label>
|
||||
<label class="app-field">
|
||||
<span><?php e(t('Priority')); ?></span>
|
||||
<input type="number" name="recommendations_escalation_overdue_priority" min="1" max="999" value="<?php e((int) ($ruleEscalationOverdue['priority'] ?? 100)); ?>">
|
||||
</label>
|
||||
<label class="app-field helpdesk-settings-rule-grid-full">
|
||||
<span><?php e(t('Minimum overdue (minutes)')); ?></span>
|
||||
<input type="number" name="recommendations_escalation_overdue_min_overdue_minutes" min="0" max="43200" value="<?php e((int) ($ruleEscalationOverdue['min_overdue_minutes'] ?? 0)); ?>">
|
||||
</label>
|
||||
</div>
|
||||
</details>
|
||||
<div class="app-details-card-container">
|
||||
<div class="helpdesk-settings-rules">
|
||||
<div class="helpdesk-settings-rule helpdesk-settings-rule-with-threshold">
|
||||
<label class="helpdesk-settings-rule-toggle">
|
||||
<input type="checkbox" role="switch" name="controlling_ticket_volume_increase_enabled" <?php if (($ctrlTicketVolume['enabled'] ?? true) === true): ?>checked<?php endif; ?>>
|
||||
<span class="helpdesk-settings-rule-label"><?php e(t('Ticket volume increase')); ?></span>
|
||||
<small><?php e(t('rule_help_ticket_volume')); ?></small>
|
||||
</label>
|
||||
<label class="app-field helpdesk-settings-rule-threshold">
|
||||
<span><?php e(t('Threshold (%)')); ?></span>
|
||||
<input type="number" name="controlling_ticket_volume_increase_threshold" min="5" max="200" value="<?php e((int) ($ctrlTicketVolume['threshold_percent'] ?? 30)); ?>">
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<details class="app-details-card" name="helpdesk-rule-high-risk" data-details-key="helpdesk-settings-rule-high-risk" open>
|
||||
<summary>
|
||||
<span class="app-details-card-summary-title"><?php e(t('High-risk aging')); ?></span>
|
||||
</summary>
|
||||
<div class="app-details-card-container helpdesk-settings-rule-grid">
|
||||
<label class="app-field">
|
||||
<input type="checkbox" role="switch" name="recommendations_high_risk_aging_enabled" <?php if (($ruleHighRiskAging['enabled'] ?? true) === true): ?>checked<?php endif; ?>>
|
||||
<span><?php e(t('Enabled')); ?></span>
|
||||
</label>
|
||||
<label class="app-field">
|
||||
<span><?php e(t('Priority')); ?></span>
|
||||
<input type="number" name="recommendations_high_risk_aging_priority" min="1" max="999" value="<?php e((int) ($ruleHighRiskAging['priority'] ?? 90)); ?>">
|
||||
</label>
|
||||
<label class="app-field helpdesk-settings-rule-grid-full">
|
||||
<span><?php e(t('High-risk codes (comma separated)')); ?></span>
|
||||
<input type="text" name="recommendations_high_risk_aging_codes" value="<?php e($highRiskCodes); ?>">
|
||||
</label>
|
||||
<label class="app-field helpdesk-settings-rule-grid-full">
|
||||
<span><?php e(t('Minimum age (hours)')); ?></span>
|
||||
<input type="number" name="recommendations_high_risk_aging_min_age_hours" min="0" max="720" value="<?php e((int) ($ruleHighRiskAging['min_age_hours'] ?? 8)); ?>">
|
||||
</label>
|
||||
</div>
|
||||
</details>
|
||||
<div class="helpdesk-settings-rule helpdesk-settings-rule-with-threshold">
|
||||
<label class="helpdesk-settings-rule-toggle">
|
||||
<input type="checkbox" role="switch" name="controlling_avg_resolution_high_enabled" <?php if (($ctrlAvgResolution['enabled'] ?? true) === true): ?>checked<?php endif; ?>>
|
||||
<span class="helpdesk-settings-rule-label"><?php e(t('High avg. resolution time')); ?></span>
|
||||
<small><?php e(t('rule_help_avg_resolution')); ?></small>
|
||||
</label>
|
||||
<label class="app-field helpdesk-settings-rule-threshold">
|
||||
<span><?php e(t('Threshold (hours)')); ?></span>
|
||||
<input type="number" name="controlling_avg_resolution_high_threshold" min="1" max="720" value="<?php e((int) ($ctrlAvgResolution['threshold_hours'] ?? 72)); ?>">
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<details class="app-details-card" name="helpdesk-rule-unassigned-open" data-details-key="helpdesk-settings-rule-unassigned-open" open>
|
||||
<summary>
|
||||
<span class="app-details-card-summary-title"><?php e(t('Unassigned open')); ?></span>
|
||||
</summary>
|
||||
<div class="app-details-card-container helpdesk-settings-rule-grid">
|
||||
<label class="app-field">
|
||||
<input type="checkbox" role="switch" name="recommendations_unassigned_open_enabled" <?php if (($ruleUnassignedOpen['enabled'] ?? true) === true): ?>checked<?php endif; ?>>
|
||||
<span><?php e(t('Enabled')); ?></span>
|
||||
</label>
|
||||
<label class="app-field">
|
||||
<span><?php e(t('Priority')); ?></span>
|
||||
<input type="number" name="recommendations_unassigned_open_priority" min="1" max="999" value="<?php e((int) ($ruleUnassignedOpen['priority'] ?? 80)); ?>">
|
||||
</label>
|
||||
<label class="app-field helpdesk-settings-rule-grid-full">
|
||||
<span><?php e(t('Minimum age (hours)')); ?></span>
|
||||
<input type="number" name="recommendations_unassigned_open_min_age_hours" min="0" max="720" value="<?php e((int) ($ruleUnassignedOpen['min_age_hours'] ?? 2)); ?>">
|
||||
</label>
|
||||
</div>
|
||||
</details>
|
||||
<div class="helpdesk-settings-rule helpdesk-settings-rule-with-threshold">
|
||||
<label class="helpdesk-settings-rule-toggle">
|
||||
<input type="checkbox" role="switch" name="controlling_open_aging_enabled" <?php if (($ctrlOpenAging['enabled'] ?? true) === true): ?>checked<?php endif; ?>>
|
||||
<span class="helpdesk-settings-rule-label"><?php e(t('Open ticket aging')); ?></span>
|
||||
<small><?php e(t('rule_help_open_aging')); ?></small>
|
||||
</label>
|
||||
<label class="app-field helpdesk-settings-rule-threshold">
|
||||
<span><?php e(t('Threshold (hours)')); ?></span>
|
||||
<input type="number" name="controlling_open_aging_threshold" min="1" max="2160" value="<?php e((int) ($ctrlOpenAging['threshold_hours'] ?? 168)); ?>">
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<details class="app-details-card" name="helpdesk-rule-stale-open" data-details-key="helpdesk-settings-rule-stale-open" open>
|
||||
<summary>
|
||||
<span class="app-details-card-summary-title"><?php e(t('Stale open')); ?></span>
|
||||
</summary>
|
||||
<div class="app-details-card-container helpdesk-settings-rule-grid">
|
||||
<label class="app-field">
|
||||
<input type="checkbox" role="switch" name="recommendations_stale_open_enabled" <?php if (($ruleStaleOpen['enabled'] ?? true) === true): ?>checked<?php endif; ?>>
|
||||
<span><?php e(t('Enabled')); ?></span>
|
||||
</label>
|
||||
<label class="app-field">
|
||||
<span><?php e(t('Priority')); ?></span>
|
||||
<input type="number" name="recommendations_stale_open_priority" min="1" max="999" value="<?php e((int) ($ruleStaleOpen['priority'] ?? 70)); ?>">
|
||||
</label>
|
||||
<label class="app-field helpdesk-settings-rule-grid-full">
|
||||
<span><?php e(t('Minimum age (hours)')); ?></span>
|
||||
<input type="number" name="recommendations_stale_open_min_age_hours" min="0" max="1440" value="<?php e((int) ($ruleStaleOpen['min_age_hours'] ?? 48)); ?>">
|
||||
</label>
|
||||
</div>
|
||||
</details>
|
||||
|
||||
<details class="app-details-card" name="helpdesk-rule-customer-backlog" data-details-key="helpdesk-settings-rule-customer-backlog" open>
|
||||
<summary>
|
||||
<span class="app-details-card-summary-title"><?php e(t('Customer backlog')); ?></span>
|
||||
</summary>
|
||||
<div class="app-details-card-container helpdesk-settings-rule-grid">
|
||||
<label class="app-field">
|
||||
<input type="checkbox" role="switch" name="recommendations_customer_backlog_enabled" <?php if (($ruleCustomerBacklog['enabled'] ?? true) === true): ?>checked<?php endif; ?>>
|
||||
<span><?php e(t('Enabled')); ?></span>
|
||||
</label>
|
||||
<label class="app-field">
|
||||
<span><?php e(t('Priority')); ?></span>
|
||||
<input type="number" name="recommendations_customer_backlog_priority" min="1" max="999" value="<?php e((int) ($ruleCustomerBacklog['priority'] ?? 60)); ?>">
|
||||
</label>
|
||||
<label class="app-field helpdesk-settings-rule-grid-full">
|
||||
<span><?php e(t('Minimum open tickets')); ?></span>
|
||||
<input type="number" name="recommendations_customer_backlog_min_open_tickets" min="1" max="500" value="<?php e((int) ($ruleCustomerBacklog['min_open_tickets'] ?? 6)); ?>">
|
||||
</label>
|
||||
</div>
|
||||
</details>
|
||||
</div>
|
||||
|
||||
<div data-tab-panel="controlling" class="helpdesk-settings-panel">
|
||||
<details class="app-details-card" name="helpdesk-ctrl-ticket-volume" data-details-key="helpdesk-settings-ctrl-ticket-volume" open>
|
||||
<summary>
|
||||
<span class="app-details-card-summary-title"><?php e(t('Ticket volume increase')); ?></span>
|
||||
</summary>
|
||||
<div class="app-details-card-container helpdesk-settings-rule-grid">
|
||||
<label class="app-field">
|
||||
<input type="checkbox" role="switch" name="controlling_ticket_volume_increase_enabled" <?php if (($ctrlTicketVolume['enabled'] ?? true) === true): ?>checked<?php endif; ?>>
|
||||
<span><?php e(t('Enabled')); ?></span>
|
||||
</label>
|
||||
<label class="app-field">
|
||||
<span><?php e(t('Threshold (%)')); ?></span>
|
||||
<input type="number" name="controlling_ticket_volume_increase_threshold" min="5" max="200" value="<?php e((int) ($ctrlTicketVolume['threshold_percent'] ?? 30)); ?>">
|
||||
</label>
|
||||
</div>
|
||||
</details>
|
||||
|
||||
<details class="app-details-card" name="helpdesk-ctrl-avg-resolution" data-details-key="helpdesk-settings-ctrl-avg-resolution" open>
|
||||
<summary>
|
||||
<span class="app-details-card-summary-title"><?php e(t('High avg. resolution time')); ?></span>
|
||||
</summary>
|
||||
<div class="app-details-card-container helpdesk-settings-rule-grid">
|
||||
<label class="app-field">
|
||||
<input type="checkbox" role="switch" name="controlling_avg_resolution_high_enabled" <?php if (($ctrlAvgResolution['enabled'] ?? true) === true): ?>checked<?php endif; ?>>
|
||||
<span><?php e(t('Enabled')); ?></span>
|
||||
</label>
|
||||
<label class="app-field">
|
||||
<span><?php e(t('Threshold (hours)')); ?></span>
|
||||
<input type="number" name="controlling_avg_resolution_high_threshold" min="1" max="720" value="<?php e((int) ($ctrlAvgResolution['threshold_hours'] ?? 72)); ?>">
|
||||
</label>
|
||||
</div>
|
||||
</details>
|
||||
|
||||
<details class="app-details-card" name="helpdesk-ctrl-open-aging" data-details-key="helpdesk-settings-ctrl-open-aging" open>
|
||||
<summary>
|
||||
<span class="app-details-card-summary-title"><?php e(t('Open ticket aging')); ?></span>
|
||||
</summary>
|
||||
<div class="app-details-card-container helpdesk-settings-rule-grid">
|
||||
<label class="app-field">
|
||||
<input type="checkbox" role="switch" name="controlling_open_aging_enabled" <?php if (($ctrlOpenAging['enabled'] ?? true) === true): ?>checked<?php endif; ?>>
|
||||
<span><?php e(t('Enabled')); ?></span>
|
||||
</label>
|
||||
<label class="app-field">
|
||||
<span><?php e(t('Threshold (hours)')); ?></span>
|
||||
<input type="number" name="controlling_open_aging_threshold" min="1" max="2160" value="<?php e((int) ($ctrlOpenAging['threshold_hours'] ?? 168)); ?>">
|
||||
</label>
|
||||
</div>
|
||||
</details>
|
||||
|
||||
<details class="app-details-card" name="helpdesk-ctrl-unassigned" data-details-key="helpdesk-settings-ctrl-unassigned" open>
|
||||
<summary>
|
||||
<span class="app-details-card-summary-title"><?php e(t('Unassigned ticket ratio')); ?></span>
|
||||
</summary>
|
||||
<div class="app-details-card-container helpdesk-settings-rule-grid">
|
||||
<label class="app-field">
|
||||
<input type="checkbox" role="switch" name="controlling_unassigned_ratio_enabled" <?php if (($ctrlUnassigned['enabled'] ?? true) === true): ?>checked<?php endif; ?>>
|
||||
<span><?php e(t('Enabled')); ?></span>
|
||||
</label>
|
||||
<label class="app-field">
|
||||
<span><?php e(t('Threshold (%)')); ?></span>
|
||||
<input type="number" name="controlling_unassigned_ratio_threshold" min="1" max="100" value="<?php e((int) ($ctrlUnassigned['threshold_percent'] ?? 20)); ?>">
|
||||
</label>
|
||||
<div class="helpdesk-settings-rule helpdesk-settings-rule-with-threshold">
|
||||
<label class="helpdesk-settings-rule-toggle">
|
||||
<input type="checkbox" role="switch" name="controlling_unassigned_ratio_enabled" <?php if (($ctrlUnassigned['enabled'] ?? true) === true): ?>checked<?php endif; ?>>
|
||||
<span class="helpdesk-settings-rule-label"><?php e(t('Unassigned ticket ratio')); ?></span>
|
||||
<small><?php e(t('rule_help_unassigned_ratio')); ?></small>
|
||||
</label>
|
||||
<label class="app-field helpdesk-settings-rule-threshold">
|
||||
<span><?php e(t('Threshold (%)')); ?></span>
|
||||
<input type="number" name="controlling_unassigned_ratio_threshold" min="1" max="100" value="<?php e((int) ($ctrlUnassigned['threshold_percent'] ?? 20)); ?>">
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</details>
|
||||
</div>
|
||||
|
||||
@@ -4,17 +4,23 @@ $layoutNav = is_array($layoutNav ?? null) ? $layoutNav : [];
|
||||
$helpdeskNav = is_array($layoutNav['helpdesk.nav'] ?? null) ? $layoutNav['helpdesk.nav'] : [];
|
||||
$canManageSettings = !empty($helpdeskNav['can_manage_settings']);
|
||||
|
||||
$settingsActive = navActive('helpdesk/settings', true);
|
||||
$customersActive = navActive('helpdesk', true);
|
||||
if ($settingsActive['isActive']) {
|
||||
$customersActive = ['class' => '', 'aria' => '', 'isActive' => false];
|
||||
}
|
||||
|
||||
$helpdeskNavItems = [
|
||||
[
|
||||
'label' => t('Customers'),
|
||||
'path' => 'helpdesk',
|
||||
'active' => navActive('helpdesk', true),
|
||||
'active' => $customersActive,
|
||||
'visible' => true,
|
||||
],
|
||||
[
|
||||
'label' => t('Settings'),
|
||||
'path' => 'helpdesk/settings',
|
||||
'active' => navActive('helpdesk/settings', true),
|
||||
'active' => $settingsActive,
|
||||
'visible' => $canManageSettings,
|
||||
],
|
||||
];
|
||||
|
||||
@@ -26,6 +26,115 @@
|
||||
}
|
||||
}
|
||||
|
||||
/* Automation tab: compact rule list */
|
||||
.helpdesk-settings-rules {
|
||||
display: grid;
|
||||
gap: calc(var(--app-spacing) * 0.5);
|
||||
margin-top: calc(var(--app-spacing) * 0.5);
|
||||
}
|
||||
|
||||
.helpdesk-settings-rule {
|
||||
display: grid;
|
||||
grid-template-columns: auto 1fr;
|
||||
gap: 0 calc(var(--app-spacing) * 0.5);
|
||||
align-items: center;
|
||||
padding: calc(var(--app-spacing) * 0.4) 0;
|
||||
border-bottom: 1px solid color-mix(in srgb, var(--app-contrast, #000) 8%, transparent);
|
||||
}
|
||||
|
||||
.helpdesk-settings-rule:last-child {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
.helpdesk-settings-rule > input[type="checkbox"] {
|
||||
grid-row: 1 / 3;
|
||||
}
|
||||
|
||||
.helpdesk-settings-rule-label {
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.helpdesk-settings-rule > small {
|
||||
grid-column: 2;
|
||||
opacity: 0.65;
|
||||
}
|
||||
|
||||
/* Risk monitoring: rule with inline threshold */
|
||||
.helpdesk-settings-rule-with-threshold {
|
||||
grid-template-columns: auto 1fr auto;
|
||||
}
|
||||
|
||||
.helpdesk-settings-rule-toggle {
|
||||
display: grid;
|
||||
grid-template-columns: auto 1fr;
|
||||
gap: 0 calc(var(--app-spacing) * 0.5);
|
||||
align-items: center;
|
||||
grid-column: 1 / 3;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.helpdesk-settings-rule-toggle > input[type="checkbox"] {
|
||||
grid-row: 1 / 3;
|
||||
}
|
||||
|
||||
.helpdesk-settings-rule-toggle > small {
|
||||
grid-column: 2;
|
||||
opacity: 0.65;
|
||||
}
|
||||
|
||||
.helpdesk-settings-rule-threshold {
|
||||
grid-row: 1 / 3;
|
||||
min-width: 6rem;
|
||||
max-width: 8rem;
|
||||
}
|
||||
|
||||
.helpdesk-settings-rule-threshold > span {
|
||||
font-size: 0.8em;
|
||||
opacity: 0.65;
|
||||
}
|
||||
|
||||
@media (max-width: 760px) {
|
||||
.helpdesk-settings-rule-with-threshold {
|
||||
grid-template-columns: auto 1fr;
|
||||
}
|
||||
|
||||
.helpdesk-settings-rule-threshold {
|
||||
grid-column: 1 / -1;
|
||||
max-width: none;
|
||||
}
|
||||
}
|
||||
|
||||
/* Advanced options disclosure */
|
||||
.helpdesk-settings-advanced {
|
||||
margin-top: calc(var(--app-spacing) * 0.5);
|
||||
border-top: 1px solid color-mix(in srgb, var(--app-contrast, #000) 8%, transparent);
|
||||
padding-top: calc(var(--app-spacing) * 0.4);
|
||||
}
|
||||
|
||||
.helpdesk-settings-advanced > summary {
|
||||
cursor: pointer;
|
||||
font-size: 0.85em;
|
||||
opacity: 0.7;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.helpdesk-settings-advanced > summary:hover {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.helpdesk-settings-advanced-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(2, minmax(0, 1fr));
|
||||
gap: calc(var(--app-spacing) * 0.5);
|
||||
margin-top: calc(var(--app-spacing) * 0.5);
|
||||
}
|
||||
|
||||
@media (max-width: 760px) {
|
||||
.helpdesk-settings-advanced-grid {
|
||||
grid-template-columns: minmax(0, 1fr);
|
||||
}
|
||||
}
|
||||
|
||||
/* Clickable rows — shared between search results and ticket list */
|
||||
.app-clickable-row {
|
||||
cursor: pointer;
|
||||
|
||||
Reference in New Issue
Block a user