added details card component

This commit is contained in:
2026-03-09 21:57:52 +01:00
parent af8ee10930
commit 1b872f145c
9 changed files with 179 additions and 97 deletions

View File

@@ -29,6 +29,7 @@ return [
'css/components/app-details-validation-summary.css',
'css/components/app-dashboard-titlebar.css',
'css/components/app-details.css',
'css/components/app-details-card.css',
'css/components/app-list-table.css',
'css/components/app-list-tabs.css',
'css/components/app-tabs.css',

View File

@@ -1018,16 +1018,17 @@
"Counters": "Zähler",
"User lifecycle policy": "Benutzer-Lifecycle-Regel",
"Session policy": "Sitzungsrichtlinie",
"Session limits define how long logged-in users stay signed in.": "Hier legen Sie Inaktivitäts- und Absolute-Timeout für aktive Sitzungen fest.",
"Idle timeout signs users out after no activity.": "Inaktivitäts-Timeout beendet inaktive Sitzungen, absolutes Timeout beendet lange Sitzungen auch bei Aktivität.",
"Registration controls whether new users can create an account.": "Hier wird gesteuert, ob neue Benutzer ein Konto erstellen dürfen.",
"Session limits define how long logged-in users stay signed in.": "Hier werden Inaktivitäts- und Absolute-Timeout für aktive Sitzungen festgelegt.",
"Absolute timeout signs users out after total session duration, even with activity.": "Das absolute Timeout meldet Benutzer nach der gesamten Sitzungsdauer ab, auch bei Aktivität.",
"New limits apply on each user's next request.": "Änderungen gelten ab der nächsten Anfrage je Benutzer. Angemeldet-bleiben-Tokens bleiben aktiv.",
"User lifecycle defines when inactive users are deactivated or deleted.": "Hier wird festgelegt, wann inaktive Benutzer deaktiviert oder gelöscht werden.",
"System audit controls whether security events are logged and how long they are kept.": "Hier wird gesteuert, ob Sicherheitsereignisse protokolliert werden und wie lange sie aufbewahrt werden.",
"Session idle timeout (minutes)": "Sitzungs-Inaktivitäts-Timeout (Minuten)",
"Session absolute timeout (hours)": "Absolutes Sitzungs-Timeout (Stunden)",
"Allowed range: 5-1440 minutes (default: 30)": "Erlaubter Bereich: 5-1440 Minuten (Standard: 30)",
"Allowed range: 1-72 hours (default: 8)": "Erlaubter Bereich: 1-72 Stunden (Standard: 8)",
"Deactivate users after inactivity (days)": "Benutzer nach Inaktivität deaktivieren (Tage)",
"Delete inactive users after (days)": "Inaktive Benutzer löschen nach (Tagen)",
"Deactivate users after inactivity (days)": "Nach Inaktivität deaktivieren (Tage)",
"Delete inactive users after (days)": "Inaktive löschen nach (Tagen)",
"0 disables this rule": "0 deaktiviert diese Regel",
"Deletion starts after user was set inactive": "Löschung startet erst nach Inaktivsetzung",
"Privileged admins are excluded from automatic lifecycle actions": "Privilegierte Admins sind von automatischen Lifecycle-Aktionen ausgenommen",

View File

@@ -1018,10 +1018,11 @@
"Counters": "Counters",
"User lifecycle policy": "User lifecycle policy",
"Session policy": "Session policy",
"Registration controls whether new users can create an account.": "Registration controls whether new users can create an account.",
"Session limits define how long logged-in users stay signed in.": "Set idle and absolute limits for active sessions.",
"Idle timeout signs users out after no activity.": "Idle timeout ends inactive sessions; absolute timeout ends long sessions even with activity.",
"Absolute timeout signs users out after total session duration, even with activity.": "Absolute timeout signs users out after total session duration, even with activity.",
"New limits apply on each user's next request.": "Changes apply from each user's next request. Remember-me tokens stay active.",
"User lifecycle defines when inactive users are deactivated or deleted.": "User lifecycle defines when inactive users are deactivated or deleted.",
"System audit controls whether security events are logged and how long they are kept.": "System audit controls whether security events are logged and how long they are kept.",
"Session idle timeout (minutes)": "Session idle timeout (minutes)",
"Session absolute timeout (hours)": "Session absolute timeout (hours)",
"Allowed range: 5-1440 minutes (default: 30)": "Allowed range: 5-1440 minutes (default: 30)",

View File

@@ -282,99 +282,128 @@ $disabledAttr = $isReadOnly ? 'disabled' : '';
</div>
<div data-tab-panel="security">
<fieldset>
<legend>
<small>
<?php e(t($appRegistrationDesc)); ?>
</small>
</legend>
<label class="app-field">
<input type="checkbox" name="app_registration" value="1" <?php e($appRegistration ? 'checked' : ''); ?>
<?php e($disabledAttr); ?>>
<span><?php e(t('Allow registration')); ?> <span class="badge" data-variant="info"><?php e(t('Cached')); ?></span></span>
</label>
</fieldset>
<hr>
<fieldset>
<legend><small><?php e(t('User lifecycle policy')); ?></small></legend>
<div class="grid">
<label class="app-field">
<span><?php e(t('Deactivate users after inactivity (days)')); ?></span>
<input type="number" name="user_inactivity_deactivate_days"
value="<?php e((string) $userInactivityDeactivateDays); ?>" min="0" max="3650" step="1"
<?php e($readonlyAttr); ?>>
<small><?php e(t($userInactivityDeactivateDaysDesc)); ?></small>
</label>
<label class="app-field">
<span><?php e(t('Delete inactive users after (days)')); ?></span>
<input type="number" name="user_inactivity_delete_days"
value="<?php e((string) $userInactivityDeleteDays); ?>" min="0" max="3650" step="1"
<?php e($readonlyAttr); ?>>
<small><?php e(t($userInactivityDeleteDaysDesc)); ?></small>
</label>
<details class="app-details-card" name="settings-security-registration" data-details-key="settings-security-registration">
<summary>
<?php e(t('Allow registration')); ?>:
<?php e($appRegistration ? t('Enabled') : t('Disabled')); ?>
</summary>
<div class="app-details-card-container">
<blockquote data-variant="info">
<small><?php e(t('Registration controls whether new users can create an account.')); ?></small>
</blockquote>
<fieldset>
<legend>
<small>
<?php e(t($appRegistrationDesc)); ?>
</small>
</legend>
<label class="app-field">
<input type="checkbox" name="app_registration" value="1" <?php e($appRegistration ? 'checked' : ''); ?>
<?php e($disabledAttr); ?>>
<span><?php e(t('Allow registration')); ?> <span class="badge" data-variant="info"><?php e(t('Cached')); ?></span></span>
</label>
</fieldset>
</div>
<small class="muted"><?php e(t('0 disables this rule')); ?></small>
<small class="muted"><?php e(t('Deletion starts after user was set inactive')); ?></small>
<small class="muted"><?php e(t('Privileged admins are excluded from automatic lifecycle actions')); ?></small>
<?php if ($canUpdateSettings): ?>
</details>
<details class="app-details-card" name="settings-security-session" data-details-key="settings-security-session" open>
<summary>
<?php e(t('Session policy')); ?>:
<?php e((string) $sessionIdleTimeoutMinutes); ?> / <?php e((string) $sessionAbsoluteTimeoutHours); ?>
</summary>
<div class="app-details-card-container">
<blockquote data-variant="info">
<small>
<?php e(t('Session limits define how long logged-in users stay signed in.')); ?>
</small>
</blockquote>
<div class="grid">
<label class="app-field">
<span><?php e(t('Session idle timeout (minutes)')); ?></span>
<input type="number" name="session_idle_timeout_minutes"
value="<?php e((string) $sessionIdleTimeoutMinutes); ?>" min="5" max="1440" step="1"
<?php e($readonlyAttr); ?>>
<small><?php e(t($sessionIdleTimeoutMinutesDesc)); ?></small>
<small class="muted"><?php e(t('Allowed range: 5-1440 minutes (default: 30)')); ?></small>
</label>
<label class="app-field">
<span><?php e(t('Session absolute timeout (hours)')); ?></span>
<input type="number" name="session_absolute_timeout_hours"
value="<?php e((string) $sessionAbsoluteTimeoutHours); ?>" min="1" max="72" step="1"
<?php e($readonlyAttr); ?>>
<small><?php e(t($sessionAbsoluteTimeoutHoursDesc)); ?></small>
<small class="muted"><?php e(t('Allowed range: 1-72 hours (default: 8)')); ?></small>
</label>
</div>
</div>
</details>
<details class="app-details-card" name="settings-security-user-lifecycle" data-details-key="settings-security-user-lifecycle">
<summary>
<?php e(t('User lifecycle policy')); ?>:
<?php e((string) $userInactivityDeactivateDays); ?> / <?php e((string) $userInactivityDeleteDays); ?>
</summary>
<div class="app-details-card-container">
<blockquote data-variant="info">
<small><?php e(t('User lifecycle defines when inactive users are deactivated or deleted.')); ?></small>
</blockquote>
<div class="grid">
<label class="app-field">
<span><?php e(t('Deactivate users after inactivity (days)')); ?></span>
<input type="number" name="user_inactivity_deactivate_days"
value="<?php e((string) $userInactivityDeactivateDays); ?>" min="0" max="3650" step="1"
<?php e($readonlyAttr); ?>>
<small><?php e(t($userInactivityDeactivateDaysDesc)); ?> - <?php e(t('0 disables this rule')); ?></small>
</label>
<label class="app-field">
<span><?php e(t('Delete inactive users after (days)')); ?></span>
<input type="number" name="user_inactivity_delete_days"
value="<?php e((string) $userInactivityDeleteDays); ?>" min="0" max="3650" step="1"
<?php e($readonlyAttr); ?>>
<small><?php e(t($userInactivityDeleteDaysDesc)); ?> - <?php e(t('0 disables this rule')); ?></small>
</label>
</div>
<?php if ($canUpdateSettings): ?>
<button type="submit" class="danger" formnovalidate
formaction="admin/settings/run-user-lifecycle"
formmethod="post"
data-detail-confirm-message="<?php e(t('Run user lifecycle now?')); ?>"
data-detail-action-kind="danger">
<?php e(t('Run user lifecycle now')); ?>
</button>
<?php endif; ?>
</div>
</details>
<details class="app-details-card" name="settings-security-system-audit" data-details-key="settings-security-system-audit">
<summary>
<?php e(t('System audit')); ?>:
<?php e($systemAuditEnabled ? t('Enabled') : t('Disabled')); ?>
</summary>
<div class="app-details-card-container">
<blockquote data-variant="info">
<small><?php e(t('System audit controls whether security events are logged and how long they are kept.')); ?></small>
</blockquote>
<label class="app-field">
<input type="checkbox" name="system_audit_enabled" value="1" <?php e($systemAuditEnabled ? 'checked' : ''); ?> <?php e($disabledAttr); ?>>
<span><?php e(t('Enable system audit log')); ?></span>
</label>
<hr>
<button type="submit" class="outline warning" formnovalidate
formaction="admin/settings/run-user-lifecycle"
formmethod="post"
data-detail-confirm-message="<?php e(t('Run user lifecycle now?')); ?>"
data-detail-action-kind="danger">
<?php e(t('Run user lifecycle now')); ?>
</button>
<?php endif; ?>
</fieldset>
<hr>
<fieldset>
<legend><small><?php e(t('Session policy')); ?></small></legend>
<blockquote data-variant="info">
<?php e(t('Session limits define how long logged-in users stay signed in.')); ?>
</blockquote>
<small class="muted"><?php e(t('Idle timeout signs users out after no activity.')); ?></small>
<small class="muted"><?php e(t('New limits apply on each user\'s next request.')); ?></small>
<div class="grid">
<label class="app-field">
<span><?php e(t('Session idle timeout (minutes)')); ?></span>
<input type="number" name="session_idle_timeout_minutes"
value="<?php e((string) $sessionIdleTimeoutMinutes); ?>" min="5" max="1440" step="1"
<span><?php e(t('Retention (days)')); ?></span>
<input
type="number"
name="system_audit_retention_days"
value="<?php e((string) $systemAuditRetentionDays); ?>"
min="30"
max="1095"
step="1"
<?php e($readonlyAttr); ?>>
<small><?php e(t($sessionIdleTimeoutMinutesDesc)); ?></small>
<small class="muted"><?php e(t('Allowed range: 5-1440 minutes (default: 30)')); ?></small>
</label>
<label class="app-field">
<span><?php e(t('Session absolute timeout (hours)')); ?></span>
<input type="number" name="session_absolute_timeout_hours"
value="<?php e((string) $sessionAbsoluteTimeoutHours); ?>" min="1" max="72" step="1"
<?php e($readonlyAttr); ?>>
<small><?php e(t($sessionAbsoluteTimeoutHoursDesc)); ?></small>
<small class="muted"><?php e(t('Allowed range: 1-72 hours (default: 8)')); ?></small>
<small><?php e(t($systemAuditRetentionDaysDesc)); ?></small>
</label>
</div>
</fieldset>
<hr>
<fieldset>
<legend><small><?php e(t('System audit')); ?></small></legend>
<label class="app-field">
<input type="checkbox" name="system_audit_enabled" value="1" <?php e($systemAuditEnabled ? 'checked' : ''); ?> <?php e($disabledAttr); ?>>
<span><?php e(t('Enable system audit log')); ?></span>
<small><?php e(t($systemAuditEnabledDesc)); ?></small>
</label>
<label class="app-field">
<span><?php e(t('Retention (days)')); ?></span>
<input
type="number"
name="system_audit_retention_days"
value="<?php e((string) $systemAuditRetentionDays); ?>"
min="30"
max="1095"
step="1"
<?php e($readonlyAttr); ?>>
<small><?php e(t($systemAuditRetentionDaysDesc)); ?></small>
</label>
</fieldset>
</details>
</div>
<div data-tab-panel="telemetry">

View File

@@ -310,6 +310,7 @@
--app-card-border-color: var(--app-muted-border-color);
--app-card-box-shadow: var(--app-box-shadow);
--app-card-sectioning-background-color: rgb(251, 251.5, 252.25);
--app-details-card-open-summary-bg: var(--app-card-sectioning-background-color);
--app-dropdown-background-color: #fff;
--app-dropdown-border-color: #eff1f4;
--app-dropdown-box-shadow: var(--app-box-shadow);
@@ -543,6 +544,7 @@
--app-card-border-color: var(--app-card-background-color);
--app-card-box-shadow: var(--app-box-shadow);
--app-card-sectioning-background-color: rgb(26, 30.5, 40.25);
--app-details-card-open-summary-bg: var(--app-card-sectioning-background-color);
--app-dropdown-background-color: #181c25;
--app-dropdown-border-color: #202632;
--app-dropdown-box-shadow: var(--app-box-shadow);
@@ -777,6 +779,7 @@
--app-card-border-color: var(--app-card-background-color);
--app-card-box-shadow: var(--app-box-shadow);
--app-card-sectioning-background-color: rgb(26, 30.5, 40.25);
--app-details-card-open-summary-bg: var(--app-card-sectioning-background-color);
--app-dropdown-background-color: #181c25;
--app-dropdown-border-color: #202632;
--app-dropdown-box-shadow: var(--app-box-shadow);

View File

@@ -15,6 +15,7 @@
--app-card-background-color: #141f19;
--app-card-border-color: #223028;
--app-card-sectioning-background-color: #1a261f;
--app-details-card-open-summary-bg: #203026;
--app-dropdown-background-color: #141f19;
--app-dropdown-border-color: #223028;
--app-dropdown-hover-background-color: #1f2a24;

View File

@@ -18,6 +18,9 @@
border-inline-start-color: var(--blockquote-border);
border-radius: var(--app-border-radius);
}
blockquote:has(small) {
padding: 6px 8px;
}
blockquote p:last-child {
margin: 0;
}

View File

@@ -0,0 +1,45 @@
@layer components {
details.app-details-card {
margin-bottom: calc(var(--app-spacing) * 0.75);
border: 1px solid
var(--app-card-border-color, var(--app-accordion-border-color));
border-radius: var(--app-border-radius);
background: var(--app-card-background-color);
overflow: hidden;
}
details.app-details-card > summary {
margin: 0;
padding: calc(var(--app-spacing) * 0.75) var(--app-spacing);
font-size: 0.85rem;
line-height: 1.25;
text-transform: none;
background: var(--app-card-sectioning-background-color);
}
details.app-details-card > summary::after {
margin-inline-start: calc(var(--app-spacing) * 0.5);
}
details.app-details-card[open] > summary {
margin-bottom: var(--app-spacing);
border-bottom: 1px solid
var(--app-card-border-color, var(--app-accordion-border-color));
background: var(
--app-details-card-open-summary-bg,
var(--app-card-sectioning-background-color)
);
}
.app-details-card-container {
padding-inline: var(--app-spacing);
padding-bottom: var(--app-spacing);
}
.app-details-card-container > *:last-child {
margin-bottom: 0;
}
details.app-details-card[open] {
border-width: 2px;
}
}

View File

@@ -97,7 +97,5 @@
fieldset[aria-disabled="true"] legend small {
color: var(--app-muted-color);
}
label:has(.badge) > span {
margin-bottom: 5px;
}
}