Fix remaining UX inconsistencies: eyebrow, duplicate headings, delete confirm

EYE1 + NAME1: Notifications page
- Remove "Operations" inline eyebrow paragraph
- Rename "Notification Operations" → "Notifications" to match sidebar label

DUP1: Remove "Channels" h2 from Notifications tab panel (tab label suffices)
DUP2: Remove "Users" h2 from Identity & Access tab panel (tab label suffices)

DEST2: Notifications channel delete confirmation
- Replace unguarded deleteChannel() with confirmDeleteChannel() + app-confirm-dialog
- Confirmation message names the channel being deleted

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
master
2026-03-27 17:06:17 +02:00
parent cc9ce3ff5e
commit 410e780eee
3 changed files with 22 additions and 6 deletions

View File

@@ -1,8 +1,7 @@
<section class="np">
<header class="np__header">
<div>
<p class="np__eyebrow">Operations</p>
<h1 class="np__title">Notification Operations</h1>
<h1 class="np__title">Notifications</h1>
<p class="np__lede">Monitor delivery health, test channels, and verify live notification outcomes.</p>
</div>
<div class="np__actions">
@@ -58,7 +57,6 @@
@case ('channels') {
<div class="np__panel">
<div class="np__panel-header">
<h2>Channels</h2>
<button type="button" class="np__btn np__btn--primary" (click)="createChannelDraft()">
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><line x1="12" y1="5" x2="12" y2="19"/><line x1="5" y1="12" x2="19" y2="12"/></svg>
New channel
@@ -153,7 +151,7 @@
<div class="np__form-actions">
<button type="button" class="np__btn np__btn--secondary" (click)="createChannelDraft()">Reset</button>
<button type="button" class="np__btn np__btn--danger" (click)="deleteChannel()" [disabled]="channelLoading() || !selectedChannelId()">Delete</button>
<button type="button" class="np__btn np__btn--danger" (click)="confirmDeleteChannel()" [disabled]="channelLoading() || !selectedChannelId()">Delete</button>
<button type="submit" class="np__btn np__btn--primary" [disabled]="channelLoading()">Save channel</button>
</div>
</form>
@@ -391,4 +389,10 @@
}
}
</stella-page-tabs>
<app-confirm-dialog #deleteChannelConfirm
title="Delete Channel"
[message]="deleteChannelMessage()"
confirmLabel="Delete" cancelLabel="Cancel" variant="danger"
(confirmed)="deleteChannel()" />
</section>

View File

@@ -4,6 +4,7 @@ import {
Component,
OnDestroy,
OnInit,
ViewChild,
computed,
inject,
signal,
@@ -36,6 +37,7 @@ import {
StellaPageTab,
} from '../../shared/components/stella-page-tabs/stella-page-tabs.component';
import { PageActionOutletComponent } from '../../shared/components/page-action-outlet/page-action-outlet.component';
import { ConfirmDialogComponent } from '../../shared/components/confirm-dialog/confirm-dialog.component';
type NotifyTab = 'channels' | 'rules' | 'deliveries';
@@ -68,7 +70,7 @@ type DeliveryFilter =
@Component({
selector: 'app-notify-panel',
imports: [CommonModule, ReactiveFormsModule, RouterLink, StellaPageTabsComponent, PageActionOutletComponent],
imports: [CommonModule, ReactiveFormsModule, RouterLink, StellaPageTabsComponent, PageActionOutletComponent, ConfirmDialogComponent],
templateUrl: './notify-panel.component.html',
styleUrls: ['./notify-panel.component.scss'],
changeDetection: ChangeDetectionStrategy.OnPush
@@ -348,6 +350,17 @@ export class NotifyPanelComponent implements OnInit, OnDestroy {
}
}
@ViewChild('deleteChannelConfirm') deleteChannelConfirm!: ConfirmDialogComponent;
readonly deleteChannelMessage = computed(() => {
const name = this.channelForm.get('name')?.value ?? 'this channel';
return `Delete channel '${name}'? This cannot be undone.`;
});
confirmDeleteChannel(): void {
this.deleteChannelConfirm.open();
}
async deleteChannel(): Promise<void> {
const channelId = this.selectedChannelId();
if (!channelId) {

View File

@@ -100,7 +100,6 @@ const TABS: readonly StellaPageTab[] = [
@case ('users') {
<div class="section-head">
<div>
<h2>Users</h2>
<p class="muted">Least privilege is selected first, and the form explains how credentials are completed after account creation.</p>
</div>
<button type="button" class="btn primary" (click)="openCreateUserEditor()">Add User</button>