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"> <section class="np">
<header class="np__header"> <header class="np__header">
<div> <div>
<p class="np__eyebrow">Operations</p> <h1 class="np__title">Notifications</h1>
<h1 class="np__title">Notification Operations</h1>
<p class="np__lede">Monitor delivery health, test channels, and verify live notification outcomes.</p> <p class="np__lede">Monitor delivery health, test channels, and verify live notification outcomes.</p>
</div> </div>
<div class="np__actions"> <div class="np__actions">
@@ -58,7 +57,6 @@
@case ('channels') { @case ('channels') {
<div class="np__panel"> <div class="np__panel">
<div class="np__panel-header"> <div class="np__panel-header">
<h2>Channels</h2>
<button type="button" class="np__btn np__btn--primary" (click)="createChannelDraft()"> <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> <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 New channel
@@ -153,7 +151,7 @@
<div class="np__form-actions"> <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--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> <button type="submit" class="np__btn np__btn--primary" [disabled]="channelLoading()">Save channel</button>
</div> </div>
</form> </form>
@@ -391,4 +389,10 @@
} }
} }
</stella-page-tabs> </stella-page-tabs>
<app-confirm-dialog #deleteChannelConfirm
title="Delete Channel"
[message]="deleteChannelMessage()"
confirmLabel="Delete" cancelLabel="Cancel" variant="danger"
(confirmed)="deleteChannel()" />
</section> </section>

View File

@@ -4,6 +4,7 @@ import {
Component, Component,
OnDestroy, OnDestroy,
OnInit, OnInit,
ViewChild,
computed, computed,
inject, inject,
signal, signal,
@@ -36,6 +37,7 @@ import {
StellaPageTab, StellaPageTab,
} from '../../shared/components/stella-page-tabs/stella-page-tabs.component'; } from '../../shared/components/stella-page-tabs/stella-page-tabs.component';
import { PageActionOutletComponent } from '../../shared/components/page-action-outlet/page-action-outlet.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'; type NotifyTab = 'channels' | 'rules' | 'deliveries';
@@ -68,7 +70,7 @@ type DeliveryFilter =
@Component({ @Component({
selector: 'app-notify-panel', selector: 'app-notify-panel',
imports: [CommonModule, ReactiveFormsModule, RouterLink, StellaPageTabsComponent, PageActionOutletComponent], imports: [CommonModule, ReactiveFormsModule, RouterLink, StellaPageTabsComponent, PageActionOutletComponent, ConfirmDialogComponent],
templateUrl: './notify-panel.component.html', templateUrl: './notify-panel.component.html',
styleUrls: ['./notify-panel.component.scss'], styleUrls: ['./notify-panel.component.scss'],
changeDetection: ChangeDetectionStrategy.OnPush 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> { async deleteChannel(): Promise<void> {
const channelId = this.selectedChannelId(); const channelId = this.selectedChannelId();
if (!channelId) { if (!channelId) {

View File

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