Admin UI: dock the attachment panel right of the dialog (below on narrow screens); related-origin setup moves into it
This commit is contained in:
@@ -453,8 +453,19 @@ function onRemoveOrigin(i) {
|
|||||||
<template>
|
<template>
|
||||||
<Modal v-if="dialog.type" @close="$emit('closeDialog')">
|
<Modal v-if="dialog.type" @close="$emit('closeDialog')">
|
||||||
<template #attached>
|
<template #attached>
|
||||||
<div v-if="dialog?.type === 'domain-edit' && hasDiagnostics" class="diag-panel" @click.stop>
|
<div v-if="dialog?.type === 'domain-edit' && (relatedEntries.length || hasDiagnostics)" class="attach-panel" @click.stop>
|
||||||
<ul class="diag-list">
|
<template v-if="relatedEntries.length">
|
||||||
|
<p class="small muted">
|
||||||
|
Related origins are verified by browsers against
|
||||||
|
<a :href="wellKnownUrl" target="_blank" rel="noopener noreferrer">{{ wellKnownUrl }}</a>
|
||||||
|
— served automatically when this instance hosts {{ dialog.data.rp_id }}; otherwise publish this document there:
|
||||||
|
</p>
|
||||||
|
<div class="wellknown-doc">
|
||||||
|
<pre>{{ wellKnownJson }}</pre>
|
||||||
|
<button type="button" class="icon-btn" @click="copyText(wellKnownJson, 'Well-known document')" aria-label="Copy well-known document" title="Copy">📋</button>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<ul v-if="hasDiagnostics" class="diag-list">
|
||||||
<li v-if="dialog.data.originValidation.some(v => v === 'invalid')" class="small error">Some entries are invalid — check for typos in the hostname; a bare '*' or '**' is not allowed, and wildcards only within the domain.</li>
|
<li v-if="dialog.data.originValidation.some(v => v === 'invalid')" class="small error">Some entries are invalid — check for typos in the hostname; a bare '*' or '**' is not allowed, and wildcards only within the domain.</li>
|
||||||
<li v-if="dialog.data.originValidation.some(v => v === 'unreachable')" class="small">Some sites are unreachable — make sure they are routed to this instance.</li>
|
<li v-if="dialog.data.originValidation.some(v => v === 'unreachable')" class="small">Some sites are unreachable — make sure they are routed to this instance.</li>
|
||||||
<li v-else-if="dialog.data.originValidation.some(v => v === 'mismatch')" class="small">Some sites are reachable but do not serve this domain.</li>
|
<li v-else-if="dialog.data.originValidation.some(v => v === 'mismatch')" class="small">Some sites are reachable but do not serve this domain.</li>
|
||||||
@@ -575,18 +586,6 @@ function onRemoveOrigin(i) {
|
|||||||
<p class="small muted">
|
<p class="small muted">
|
||||||
Only the listed sites may sign in with {{ dialog.data.rp_id }} passkeys. Wildcards may be used: <strong>**.{{ dialog.data.rp_id }}</strong> allows the whole domain, <strong>*.{{ dialog.data.rp_id }}</strong> only a single subdomain level.<template v-if="relatedEntries.length"> 🔗 means related host requiring WebAuthn ROR setup.</template><template v-if="dialog.data.auth_host"> 🔑 is the dedicated Paskia host for all account management.</template>
|
Only the listed sites may sign in with {{ dialog.data.rp_id }} passkeys. Wildcards may be used: <strong>**.{{ dialog.data.rp_id }}</strong> allows the whole domain, <strong>*.{{ dialog.data.rp_id }}</strong> only a single subdomain level.<template v-if="relatedEntries.length"> 🔗 means related host requiring WebAuthn ROR setup.</template><template v-if="dialog.data.auth_host"> 🔑 is the dedicated Paskia host for all account management.</template>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<template v-if="relatedEntries.length">
|
|
||||||
<p class="small muted">
|
|
||||||
Related origins are verified by browsers against
|
|
||||||
<a :href="wellKnownUrl" target="_blank" rel="noopener noreferrer">{{ wellKnownUrl }}</a>
|
|
||||||
— served automatically when this instance hosts {{ dialog.data.rp_id }}; otherwise publish this document there:
|
|
||||||
</p>
|
|
||||||
<div class="wellknown-doc">
|
|
||||||
<pre>{{ wellKnownJson }}</pre>
|
|
||||||
<button type="button" class="icon-btn" @click="copyText(wellKnownJson, 'Well-known document')" aria-label="Copy well-known document" title="Copy">📋</button>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
</template>
|
</template>
|
||||||
<template v-else-if="dialog.type==='confirm'">
|
<template v-else-if="dialog.type==='confirm'">
|
||||||
<p>{{ dialog.data.message }}</p>
|
<p>{{ dialog.data.message }}</p>
|
||||||
@@ -630,7 +629,7 @@ function onRemoveOrigin(i) {
|
|||||||
.row-menu-popup .delete-menu-icon { filter: saturate(1.4); }
|
.row-menu-popup .delete-menu-icon { filter: saturate(1.4); }
|
||||||
|
|
||||||
.wellknown-doc { display: flex; align-items: flex-start; gap: var(--space-xs); }
|
.wellknown-doc { display: flex; align-items: flex-start; gap: var(--space-xs); }
|
||||||
.wellknown-doc pre { flex: 1; margin: 0; padding: var(--space-xs) var(--space-sm); font-size: 0.8rem; background: var(--color-bg-soft, rgba(127,127,127,0.08)); border-radius: 4px; overflow-x: auto; }
|
.wellknown-doc pre { flex: 1; min-width: 0; margin: 0; padding: var(--space-xs) var(--space-sm); font-size: 0.8rem; background: var(--color-bg-soft, rgba(127,127,127,0.08)); border-radius: 4px; white-space: pre-wrap; overflow-wrap: anywhere; }
|
||||||
|
|
||||||
.input-error {
|
.input-error {
|
||||||
border-color: var(--color-error);
|
border-color: var(--color-error);
|
||||||
|
|||||||
@@ -490,9 +490,10 @@ th {
|
|||||||
left: 0;
|
left: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* The diagnostics panel attaches below the dialog, so feedback appearing
|
/* Dialog attachment panel (runtime diagnostics, related-origin setup):
|
||||||
or disappearing never shifts the dialog's layout or position */
|
docked on the right of the dialog, so appearing or disappearing never
|
||||||
.diag-panel {
|
shifts the dialog itself. On narrow screens it hangs below instead. */
|
||||||
|
.attach-panel {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: calc(100% + 0.5rem);
|
top: calc(100% + 0.5rem);
|
||||||
left: 0;
|
left: 0;
|
||||||
@@ -506,6 +507,21 @@ th {
|
|||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.attach-panel > * + * {
|
||||||
|
margin-top: var(--space-md);
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (min-width: 1200px) {
|
||||||
|
.attach-panel {
|
||||||
|
top: 0;
|
||||||
|
left: calc(100% + 0.75rem);
|
||||||
|
right: auto;
|
||||||
|
/* Never wider than the space right of the centered 500px dialog */
|
||||||
|
width: min(340px, calc(50vw - 286px));
|
||||||
|
max-height: calc(100vh - 3rem);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.icon-btn {
|
.icon-btn {
|
||||||
background: none;
|
background: none;
|
||||||
border: none;
|
border: none;
|
||||||
|
|||||||
Reference in New Issue
Block a user