Extend users detail empty states to remaining non-list areas

This commit is contained in:
2026-03-11 22:05:03 +01:00
parent 4885135849
commit 71b2d4a696
2 changed files with 179 additions and 137 deletions

View File

@@ -312,54 +312,64 @@ foreach ($tenants as $tenant) {
<details name="security-password-resets" data-details-key="security-password-resets"> <details name="security-password-resets" data-details-key="security-password-resets">
<summary><?php e(t('Password resets')); ?></summary> <summary><?php e(t('Password resets')); ?></summary>
<hr> <hr>
<div class="overflow-auto white-space-nowrap"> <?php if (!$passwordResets): ?>
<table> <?php
<thead> $emptyState = [
<tr> 'message' => t('No entries found'),
<th><?php e(t('Requested at')); ?></th> 'size' => 'compact',
<th><?php e(t('Expires at')); ?></th> ];
<th><?php e(t('Used at')); ?></th> require templatePath('partials/app-empty-state.phtml');
<th><?php e(t('Attempts')); ?></th> ?>
<th><?php e(t('Status')); ?></th> <?php else: ?>
</tr> <div class="overflow-auto white-space-nowrap">
</thead> <table>
<tbody> <thead>
<?php foreach ($passwordResets as $reset): ?>
<?php
$expiresAt = (string) ($reset['expires_at'] ?? '');
$usedAt = (string) ($reset['used_at'] ?? '');
$status = t('Active');
$statusVariant = 'success';
if ($usedAt !== '') {
$status = t('Used');
$statusVariant = 'neutral';
} elseif ($expiresAt !== '') {
try {
$expired = (new \DateTimeImmutable($expiresAt)) <= new \DateTimeImmutable('now');
if ($expired) {
$status = t('Expired');
$statusVariant = 'warning';
}
} catch (\Exception $e) {
// fallback: keep Active
}
}
?>
<tr> <tr>
<td><?php e(dt($reset['created'] ?? '')); ?></td> <th><?php e(t('Requested at')); ?></th>
<td><?php e($expiresAt !== '' ? dt($expiresAt) : '-'); ?></td> <th><?php e(t('Expires at')); ?></th>
<td><?php e($usedAt !== '' ? dt($usedAt) : '-'); ?></td> <th><?php e(t('Used at')); ?></th>
<td><?php e((string) ($reset['attempts'] ?? 0)); ?></td> <th><?php e(t('Attempts')); ?></th>
<td> <th><?php e(t('Status')); ?></th>
<span class="badge" data-variant="<?php e($statusVariant); ?>">
<?php e($status); ?>
</span>
</td>
</tr> </tr>
<?php endforeach; ?> </thead>
</tbody> <tbody>
</table> <?php foreach ($passwordResets as $reset): ?>
</div> <?php
$expiresAt = (string) ($reset['expires_at'] ?? '');
$usedAt = (string) ($reset['used_at'] ?? '');
$status = t('Active');
$statusVariant = 'success';
if ($usedAt !== '') {
$status = t('Used');
$statusVariant = 'neutral';
} elseif ($expiresAt !== '') {
try {
$expired = (new \DateTimeImmutable($expiresAt)) <= new \DateTimeImmutable('now');
if ($expired) {
$status = t('Expired');
$statusVariant = 'warning';
}
} catch (\Exception $e) {
// fallback: keep Active
}
}
?>
<tr>
<td><?php e(dt($reset['created'] ?? '')); ?></td>
<td><?php e($expiresAt !== '' ? dt($expiresAt) : '-'); ?></td>
<td><?php e($usedAt !== '' ? dt($usedAt) : '-'); ?></td>
<td><?php e((string) ($reset['attempts'] ?? 0)); ?></td>
<td>
<span class="badge" data-variant="<?php e($statusVariant); ?>">
<?php e($status); ?>
</span>
</td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
</div>
<?php endif; ?>
</details> </details>
<?php endif; ?> <?php endif; ?>
<?php if ($showRememberTokens): ?> <?php if ($showRememberTokens): ?>
@@ -367,55 +377,65 @@ foreach ($tenants as $tenant) {
<details name="security-login-tokens" data-details-key="security-login-tokens"> <details name="security-login-tokens" data-details-key="security-login-tokens">
<summary><?php e(t('Login tokens')); ?></summary> <summary><?php e(t('Login tokens')); ?></summary>
<hr> <hr>
<div class="overflow-auto white-space-nowrap"> <?php if (!$rememberTokens): ?>
<table> <?php
<thead> $emptyState = [
<tr> 'message' => t('No entries found'),
<th><?php e(t('Created at')); ?></th> 'size' => 'compact',
<th><?php e(t('Expires at')); ?></th> ];
<th><?php e(t('Last used')); ?></th> require templatePath('partials/app-empty-state.phtml');
<th><?php e(t('Status')); ?></th> ?>
</tr> <?php else: ?>
</thead> <div class="overflow-auto white-space-nowrap">
<tbody> <table>
<?php foreach ($rememberTokens as $token): ?> <thead>
<?php
$expiresAt = (string) ($token['expires_at'] ?? '');
$expiredByAdminAt = (string) ($token['expired_by_admin_at'] ?? '');
$lastUsed = (string) ($token['last_used'] ?? '');
$status = t('Active');
$statusVariant = 'success';
if ($expiresAt !== '') {
try {
$expired = (new \DateTimeImmutable($expiresAt)) <= new \DateTimeImmutable('now');
if ($expired) {
if ($expiredByAdminAt !== '') {
$status = t('Expired by admin');
$statusVariant = 'warning';
} else {
$status = t('Expired');
$statusVariant = 'warning';
}
}
} catch (\Exception $e) {
// fallback: keep Active
}
}
?>
<tr> <tr>
<td><?php e(dt($token['created'] ?? '')); ?></td> <th><?php e(t('Created at')); ?></th>
<td><?php e($expiresAt !== '' ? dt($expiresAt) : '-'); ?></td> <th><?php e(t('Expires at')); ?></th>
<td><?php e($lastUsed !== '' ? dt($lastUsed) : '-'); ?></td> <th><?php e(t('Last used')); ?></th>
<td> <th><?php e(t('Status')); ?></th>
<span class="badge" data-variant="<?php e($statusVariant); ?>">
<?php e($status); ?>
</span>
</td>
</tr> </tr>
<?php endforeach; ?> </thead>
</tbody> <tbody>
</table> <?php foreach ($rememberTokens as $token): ?>
</div> <?php
$expiresAt = (string) ($token['expires_at'] ?? '');
$expiredByAdminAt = (string) ($token['expired_by_admin_at'] ?? '');
$lastUsed = (string) ($token['last_used'] ?? '');
$status = t('Active');
$statusVariant = 'success';
if ($expiresAt !== '') {
try {
$expired = (new \DateTimeImmutable($expiresAt)) <= new \DateTimeImmutable('now');
if ($expired) {
if ($expiredByAdminAt !== '') {
$status = t('Expired by admin');
$statusVariant = 'warning';
} else {
$status = t('Expired');
$statusVariant = 'warning';
}
}
} catch (\Exception $e) {
// fallback: keep Active
}
}
?>
<tr>
<td><?php e(dt($token['created'] ?? '')); ?></td>
<td><?php e($expiresAt !== '' ? dt($expiresAt) : '-'); ?></td>
<td><?php e($lastUsed !== '' ? dt($lastUsed) : '-'); ?></td>
<td>
<span class="badge" data-variant="<?php e($statusVariant); ?>">
<?php e($status); ?>
</span>
</td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
</div>
<?php endif; ?>
</details> </details>
<?php endif; ?> <?php endif; ?>
<?php if ($showApiTokens): ?> <?php if ($showApiTokens): ?>
@@ -590,7 +610,13 @@ foreach ($tenants as $tenant) {
} }
?> ?>
<?php if (!$selectedTenantMap): ?> <?php if (!$selectedTenantMap): ?>
<p class="muted"><?php e(t('Assign tenants first to select departments')); ?></p> <?php
$emptyState = [
'message' => t('Assign tenants first to select departments'),
'size' => 'compact',
];
require templatePath('partials/app-empty-state.phtml');
?>
<?php else: ?> <?php else: ?>
<?php foreach ($selectedTenantMap as $tenantId => $tenant): ?> <?php foreach ($selectedTenantMap as $tenantId => $tenant): ?>
<?php $tenantDepartments = $departmentOptionsByTenant[$tenantId] ?? []; ?> <?php $tenantDepartments = $departmentOptionsByTenant[$tenantId] ?? []; ?>
@@ -638,47 +664,57 @@ foreach ($tenants as $tenant) {
<details name="assignments-permissions" data-details-key="assignments-permissions"> <details name="assignments-permissions" data-details-key="assignments-permissions">
<summary><?php e(t('Permissions')); ?></summary> <summary><?php e(t('Permissions')); ?></summary>
<hr> <hr>
<div class="overflow-auto white-space-nowrap"> <?php if (!$permissionRows): ?>
<table> <?php
<thead> $emptyState = [
<tr> 'message' => t('No entries found'),
<th><?php e(t('Description')); ?></th> 'size' => 'compact',
<th><?php e(t('Permission key')); ?></th> ];
<th><?php e(t('Permission origin')); ?></th> require templatePath('partials/app-empty-state.phtml');
</tr> ?>
</thead> <?php else: ?>
<tbody> <div class="overflow-auto white-space-nowrap">
<?php foreach ($permissionRows as $permissionRow): ?> <table>
<?php <thead>
$permissionKey = (string) ($permissionRow['key'] ?? '');
$labelKey = 'perm.' . $permissionKey;
$label = t($labelKey);
if ($label === $labelKey) {
$label = (string) ($permissionRow['description'] ?? '');
if ($label === '') {
$label = $permissionKey;
}
}
$rolesList = [];
if (!empty($permissionRow['roles']) && is_array($permissionRow['roles'])) {
$rolesList = $permissionRow['roles'];
}
?>
<tr> <tr>
<td><?php e($label); ?></td> <th><?php e(t('Description')); ?></th>
<td><code><?php e($permissionKey); ?></code></td> <th><?php e(t('Permission key')); ?></th>
<td> <th><?php e(t('Permission origin')); ?></th>
<?php if ($rolesList): ?>
<?php foreach ($rolesList as $roleLabel): ?>
<span class="badge" data-variant="neutral"><?php e($roleLabel); ?></span>
<?php endforeach; ?>
<?php endif; ?>
</td>
</tr> </tr>
<?php endforeach; ?> </thead>
</tbody> <tbody>
</table> <?php foreach ($permissionRows as $permissionRow): ?>
</div> <?php
$permissionKey = (string) ($permissionRow['key'] ?? '');
$labelKey = 'perm.' . $permissionKey;
$label = t($labelKey);
if ($label === $labelKey) {
$label = (string) ($permissionRow['description'] ?? '');
if ($label === '') {
$label = $permissionKey;
}
}
$rolesList = [];
if (!empty($permissionRow['roles']) && is_array($permissionRow['roles'])) {
$rolesList = $permissionRow['roles'];
}
?>
<tr>
<td><?php e($label); ?></td>
<td><code><?php e($permissionKey); ?></code></td>
<td>
<?php if ($rolesList): ?>
<?php foreach ($rolesList as $roleLabel): ?>
<span class="badge" data-variant="neutral"><?php e($roleLabel); ?></span>
<?php endforeach; ?>
<?php endif; ?>
</td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
</div>
<?php endif; ?>
</details> </details>
<?php endif; ?> <?php endif; ?>
</div> </div>
@@ -687,7 +723,13 @@ foreach ($tenants as $tenant) {
<?php if ($showCustomFieldsTab): ?> <?php if ($showCustomFieldsTab): ?>
<div data-tab-panel="custom_fields"> <div data-tab-panel="custom_fields">
<?php if (!$customFieldTenantMap): ?> <?php if (!$customFieldTenantMap): ?>
<p class="muted"><?php e(t('Assign tenants first to edit custom fields')); ?></p> <?php
$emptyState = [
'message' => t('Assign tenants first to edit custom fields'),
'size' => 'compact',
];
require templatePath('partials/app-empty-state.phtml');
?>
<?php else: ?> <?php else: ?>
<?php $hasRenderedCustomFields = false; ?> <?php $hasRenderedCustomFields = false; ?>
<?php $hasConfiguredTenantDefinitions = false; ?> <?php $hasConfiguredTenantDefinitions = false; ?>

View File

@@ -136,11 +136,11 @@ if ($lastLoginAt !== '') {
$isReadOnly = !$canEditUser; $isReadOnly = !$canEditUser;
$canEditAssignments = $canEditAssignments ?? false; $canEditAssignments = $canEditAssignments ?? false;
$permissionRows = $permissionRows ?? []; $permissionRows = $permissionRows ?? [];
$showPermissions = !empty($permissionRows) && $canViewPermissionsTable; $showPermissions = $canViewPermissionsTable;
$passwordResets = $passwordResets ?? []; $passwordResets = $passwordResets ?? [];
$showPasswordResets = $canViewSecurityArtifacts && !empty($passwordResets); $showPasswordResets = $canViewSecurityArtifacts;
$rememberTokens = $rememberTokens ?? []; $rememberTokens = $rememberTokens ?? [];
$showRememberTokens = $canViewSecurityArtifacts && !empty($rememberTokens); $showRememberTokens = $canViewSecurityArtifacts;
$showDangerZone = $canDeleteUser; $showDangerZone = $canDeleteUser;
$dangerZoneDeleteFormId = $showDangerZone ? 'user-delete-form' : ''; $dangerZoneDeleteFormId = $showDangerZone ? 'user-delete-form' : '';
$dangerZoneWarning = t('This will permanently delete this user.'); $dangerZoneWarning = t('This will permanently delete this user.');