This is an automated email from the ASF dual-hosted git repository. wu-sheng pushed a commit to branch fix/local-draft-prompt-login-reset in repository https://gitbox.apache.org/repos/asf/skywalking-horizon-ui.git
commit accb21b76793dfd696d4ef5c18061c3a3be04cbc Author: Wu Sheng <[email protected]> AuthorDate: Sat May 23 23:27:30 2026 +0800 fix(admin): unpublished-edits prompt re-shows after login + align verb gates Two small, related fixes for the "You have unpublished local edits" prompt that appears for editors with browser-local template drafts. - auth.login() now clears the prompt's `sessionStorage` dismissal key on every successful login. Previously the per-tab dismissal carried across the logout / login boundary in the same browser tab, so an operator who had dismissed the modal earlier would log back in and not see the reminder for drafts they hadn't pushed. Since /login lives outside AppShell, the next AppShell mount re-reads the (now-clean) sessionStorage and the modal opens reliably whenever drafts exist. - TemplateConflictPrompt's gate for layer drafts is now `dashboard:write` (was `dashboard:read`), matching the symmetric `overview:write` check used for overview drafts. The comment above the component already said "kinds the user can edit"; the prior read-verb worked in the default role policy only because dashboard:read and dashboard:write resolve to the same roles (operator + admin). A future role that grants read-only dashboard access would have seen the prompt without being able to act on it. Net effect: viewers + maintainers see no prompt (unchanged — they can't push drafts anyway); operator + admin see the prompt reliably on every fresh login, whatever they did in a prior session. --- apps/ui/src/shell/TemplateConflictPrompt.vue | 6 +++++- apps/ui/src/state/auth.ts | 10 ++++++++++ 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/apps/ui/src/shell/TemplateConflictPrompt.vue b/apps/ui/src/shell/TemplateConflictPrompt.vue index 24af840..e0fec2a 100644 --- a/apps/ui/src/shell/TemplateConflictPrompt.vue +++ b/apps/ui/src/shell/TemplateConflictPrompt.vue @@ -40,7 +40,11 @@ const { bundle } = useConfigBundle(); const auth = useAuthStore(); const { edits } = useLocalTemplateEdits(); -const canEditLayers = computed<boolean>(() => auth.hasVerb('dashboard:read')); +// Both checks are `:write` for symmetry — the prompt nudges operators +// who can act on the draft (publish or discard). `dashboard:read` would +// resolve to the same roles in the default policy today, but a role with +// read-only dashboard access shouldn't be nagged about edits it can't push. +const canEditLayers = computed<boolean>(() => auth.hasVerb('dashboard:write')); const canEditOverviews = computed<boolean>(() => auth.hasVerb('overview:write')); interface DraftItem { diff --git a/apps/ui/src/state/auth.ts b/apps/ui/src/state/auth.ts index b3249a9..d08c15b 100644 --- a/apps/ui/src/state/auth.ts +++ b/apps/ui/src/state/auth.ts @@ -42,6 +42,16 @@ export const useAuthStore = defineStore('auth', () => { user.value = await bffClient.session.login(username, password); // New login session → re-prompt the local-vs-remote template choice. useTemplatePreference().reset(); + // Clear the per-session "unpublished local edits" prompt dismissal + // so a fresh login sees the reminder reliably. Without this, a + // dismissal from an earlier session in the same browser tab keeps + // the modal hidden across the logout / login boundary — operators + // log back in to find drafts they pushed nothing about. + try { + sessionStorage.removeItem('horizon:localDraftPrompt:dismissed'); + } catch { + /* private mode — module-level state still resets on AppShell re-mount */ + } return true; } catch (err) { if (err instanceof BffApiError && err.status === 401) {
