Admin OIDC Client editing moved to its own page.

This commit is contained in:
Leo Vasanko
2026-02-16 20:32:55 +00:00
parent 09049d3094
commit 30aeb9a310
12 changed files with 603 additions and 173 deletions
+28 -7
View File
@@ -12,7 +12,7 @@ const props = defineProps({
navigationDisabled: { type: Boolean, default: false }
})
const emit = defineEmits(['createOrg', 'openOrg', 'updateOrg', 'deleteOrg', 'toggleOrgPermission', 'openDialog', 'deletePermission', 'renamePermissionDisplay', 'createOidcClient', 'editOidcClient', 'deleteOidcClient', 'navigateOut'])
const emit = defineEmits(['createOrg', 'openOrg', 'updateOrg', 'deleteOrg', 'toggleOrgPermission', 'openDialog', 'deletePermission', 'renamePermissionDisplay', 'createOidcClient', 'openOidcClient', 'deleteOidcClient', 'navigateOut'])
// Template refs for navigation
const orgSection = ref(null)
@@ -39,6 +39,23 @@ function domainDisplay(domain) {
if (!domain) return '—'
return oidcClientNames.value[domain] || domain
}
// Map OIDC client UUIDs to their group permissions (sorted by scope)
const clientGroups = computed(() => {
const map = {}
for (const p of props.permissions || []) {
if (p.domain) {
if (!map[p.domain]) map[p.domain] = []
map[p.domain].push(p)
}
}
// Sort each group array by scope
for (const key in map) {
map[key].sort((a, b) => a.scope.localeCompare(b.scope))
}
return map
})
const sortedPermissions = computed(() => [...props.permissions].sort((a,b)=> a.scope.localeCompare(b.scope)))
// Derive admin status from permissions (info contains ctx from validate response)
@@ -379,25 +396,29 @@ defineExpose({ focusFirstElement })
<thead>
<tr>
<th scope="col">Client</th>
<th scope="col">Redirect URI</th>
<th scope="col">Groups</th>
<th scope="col" class="center">Sessions</th>
<th scope="col" class="center">Actions</th>
</tr>
</thead>
<tbody>
<tr v-if="!oidcClients || oidcClients.length === 0">
<td colspan="3" class="center muted">No OIDC clients configured</td>
<td colspan="4" class="center muted">No OIDC clients configured</td>
</tr>
<tr v-for="client in oidcClients" :key="client.uuid">
<td class="perm-name-cell">
<div class="perm-title">
<span class="display-text">{{ client.name }}</span>
<button @click="$emit('editOidcClient', client)" class="icon-btn edit-display-btn" aria-label="Edit OIDC client" title="Edit OIDC client"></button>
<a :href="'#oidc:' + client.uuid" @click.prevent="$emit('openOidcClient', client)">{{ client.name }}</a>
</div>
<div class="perm-id-info">
<span class="id-text">{{ client.uuid }}</span>
</div>
</td>
<td class="redirect-uris">{{ client.redirect_uris.join(', ') }}</td>
<td class="client-groups">
<span v-if="clientGroups[client.uuid]?.length">{{ clientGroups[client.uuid].map(g => g.scope).join(' ') }}</span>
<span v-else class="muted"></span>
</td>
<td class="center">{{ client.active_sessions || 0 }}</td>
<td class="center">
<button @click="$emit('deleteOidcClient', client)" class="icon-btn delete-icon" aria-label="Delete OIDC client" title="Delete OIDC client"></button>
</td>
@@ -428,5 +449,5 @@ defineExpose({ focusFirstElement })
/* OIDC Clients Section */
.oidc-clients-section { margin-bottom: var(--space-xl); margin-top: var(--space-2xl); }
.oidc-clients-section .section-header { display: flex; flex-direction: column; gap: 0.4rem; margin-bottom: var(--space-md); }
.redirect-uris { font-size: 0.9rem; max-width: 300px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.client-groups { font-size: 0.85rem; color: var(--color-text-muted); max-width: 200px; font-family: var(--font-mono, monospace); }
</style>