Skip to content

Commit 89baa08

Browse files
feat(#2885): add work side menu item popover notification
1 parent 762d405 commit 89baa08

41 files changed

Lines changed: 3433 additions & 208 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

apps/prs/angular/project.json

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,12 @@
1717
"tsConfig": "apps/prs/angular/tsconfig.app.json",
1818
"assets": [
1919
"apps/prs/angular/src/favicon.ico",
20-
"apps/prs/angular/src/assets"
20+
"apps/prs/angular/src/assets",
21+
{
22+
"glob": "tokens.css",
23+
"input": "node_modules/@abgov/design-tokens-v2/dist",
24+
"output": "/v2-tokens"
25+
}
2126
],
2227
"styles": ["apps/prs/angular/src/styles.css"],
2328
"scripts": []

apps/prs/angular/src/app/app.component.html

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
<div style="min-height: 100vh; display: flex; flex-direction: column">
1+
<div *ngIf="!isFullPage" style="min-height: 100vh; display: flex; flex-direction: column">
22
<section slot="header" class="width" role="header" style="flex: 0 0 auto">
33
<goab-microsite-header type="alpha" version="UAT" />
44
<goab-app-header>
@@ -73,6 +73,8 @@
7373
<a href="/features/2722">2722</a>
7474
<a href="/features/2730">2730</a>
7575
<a href="/features/2829">2829</a>
76+
<a href="/features/2885">2885 WorkSpace Notification</a>
77+
<a href="/features/2885-navigation-tabs">2885 Navigation Tabs</a>
7678
<a href="/features/3102">3102</a>
7779
<a href="/features/3306">3306</a>
7880
<a href="/features/1908">1908</a>
@@ -92,3 +94,5 @@
9294
<goab-app-footer maxContentWidth="100%" />
9395
</section>
9496
</div>
97+
98+
<router-outlet *ngIf="isFullPage"></router-outlet>
Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,25 @@
11
import { Component } from "@angular/core";
2+
import { Router, NavigationEnd } from "@angular/router";
3+
import { filter } from "rxjs/operators";
24

35
@Component({
46
selector: "abgov-root",
57
templateUrl: "./app.component.html",
68
styles: ``,
79
standalone: false,
810
})
9-
export class AppComponent {}
11+
export class AppComponent {
12+
isFullPage = false;
13+
14+
private fullPageRoutes = ["/features/2885"];
15+
16+
constructor(private router: Router) {
17+
this.router.events
18+
.pipe(filter((event) => event instanceof NavigationEnd))
19+
.subscribe((event) => {
20+
this.isFullPage = this.fullPageRoutes.includes(
21+
(event as NavigationEnd).urlAfterRedirects,
22+
);
23+
});
24+
}
25+
}

apps/prs/angular/src/app/app.routes.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,8 @@ import { Feat3241Component } from "../routes/features/feat3241/feat3241.componen
6363
import { FeatV2IconsComponent } from "../routes/features/featV2Icons/feat-v2-icons.component";
6464
import { Feat3137Component } from "../routes/features/feat3137/feat3137.component";
6565
import { Feat3306Component } from "../routes/features/feat3306/feat3306.component";
66+
import { Feat2885Component } from "../routes/features/feat2885/feat2885.component";
67+
import { Feat2885NavigationTabsComponent } from "../routes/features/feat2885-navigation-tabs/feat2885-navigation-tabs.component";
6668

6769
export const appRoutes: Route[] = [
6870
{ path: "everything", component: EverythingComponent },
@@ -130,4 +132,6 @@ export const appRoutes: Route[] = [
130132
{ path: "features/3137", component: Feat3137Component },
131133
{ path: "features/1908", component: Feat1908Component },
132134
{ path: "features/3306", component: Feat3306Component },
135+
{ path: "features/2885", component: Feat2885Component },
136+
{ path: "features/2885-navigation-tabs", component: Feat2885NavigationTabsComponent },
133137
];
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
<h1>Feature #2885: Tabs navigation prop</h1>
2+
<p>
3+
Showcases the new <code>navigation</code> prop on <code>goabx-tabs</code>.
4+
When set to <code>"none"</code>, tabs act as a UI switcher without updating the browser URL hash.
5+
</p>
6+
7+
<hr style="margin: 24px 0" />
8+
9+
<h2>Test 1: Segmented + navigation="none"</h2>
10+
<p>Tabs switch content without changing the URL hash. Used inside notification panels.</p>
11+
<goabx-tabs variant="segmented" navigation="none" (_change)="onTabChange($event)">
12+
<goab-tab heading="Unread">
13+
<p>Unread notifications content</p>
14+
</goab-tab>
15+
<goab-tab heading="Urgent">
16+
<p>Urgent notifications content</p>
17+
</goab-tab>
18+
<goab-tab heading="All">
19+
<p>All notifications content</p>
20+
</goab-tab>
21+
</goabx-tabs>
22+
23+
<hr style="margin: 24px 0" />
24+
25+
<h2>Test 2: Segmented + navigation="url" (default)</h2>
26+
<p>Default behavior: tabs update the browser URL hash when switched.</p>
27+
<goabx-tabs variant="segmented" (_change)="onTabChange($event)">
28+
<goab-tab heading="Tab A">
29+
<p>Tab A content with URL navigation</p>
30+
</goab-tab>
31+
<goab-tab heading="Tab B">
32+
<p>Tab B content with URL navigation</p>
33+
</goab-tab>
34+
<goab-tab heading="Tab C">
35+
<p>Tab C content with URL navigation</p>
36+
</goab-tab>
37+
</goabx-tabs>
38+
39+
<hr style="margin: 24px 0" />
40+
41+
<h2>Test 3: Default (non-segmented) + navigation="none"</h2>
42+
<p>Standard tab style with URL navigation disabled.</p>
43+
<goabx-tabs navigation="none" (_change)="onTabChange($event)">
44+
<goab-tab heading="Overview">
45+
<p>Overview content</p>
46+
</goab-tab>
47+
<goab-tab heading="Details">
48+
<p>Details content</p>
49+
</goab-tab>
50+
<goab-tab heading="History">
51+
<p>History content</p>
52+
</goab-tab>
53+
</goabx-tabs>
54+
55+
<hr style="margin: 24px 0" />
56+
57+
<h2>Test 4: Default (non-segmented) + navigation="url" (default)</h2>
58+
<p>Standard tab style with default URL navigation.</p>
59+
<goabx-tabs (_change)="onTabChange($event)">
60+
<goab-tab heading="Section 1">
61+
<p>Section 1 content with URL navigation</p>
62+
</goab-tab>
63+
<goab-tab heading="Section 2">
64+
<p>Section 2 content with URL navigation</p>
65+
</goab-tab>
66+
<goab-tab heading="Section 3">
67+
<p>Section 3 content with URL navigation</p>
68+
</goab-tab>
69+
</goabx-tabs>
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import { Component, CUSTOM_ELEMENTS_SCHEMA } from "@angular/core";
2+
import { GoabTab, GoabxTabs } from "@abgov/angular-components";
3+
4+
@Component({
5+
standalone: true,
6+
selector: "abgov-feat2885-navigation-tabs",
7+
templateUrl: "./feat2885-navigation-tabs.component.html",
8+
imports: [GoabTab, GoabxTabs],
9+
schemas: [CUSTOM_ELEMENTS_SCHEMA],
10+
})
11+
export class Feat2885NavigationTabsComponent {
12+
onTabChange(event: Event) {
13+
const detail = (event as CustomEvent).detail;
14+
console.log("Tab changed:", detail);
15+
}
16+
}
Lines changed: 179 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,179 @@
1+
<div style="display: flex; height: 100vh">
2+
<goabx-work-side-menu
3+
heading="Workspace Demo"
4+
url="/"
5+
userName="John Doe"
6+
userSecondaryText="john.doe@gov.ab.ca"
7+
[open]="menuOpen"
8+
(onToggle)="toggleMenu()"
9+
[primaryContent]="primaryTpl"
10+
[secondaryContent]="secondaryTpl"
11+
[accountContent]="accountTpl"
12+
/>
13+
14+
<ng-template #primaryTpl>
15+
<goabx-work-side-menu-item
16+
icon="grid"
17+
label="Dashboard"
18+
url="/features/2885"
19+
/>
20+
<goabx-work-side-menu-item
21+
icon="search"
22+
label="Search"
23+
url="/features/2885/search"
24+
/>
25+
<goabx-work-side-menu-item
26+
icon="list"
27+
label="Cases"
28+
url="/features/2885/cases"
29+
badge="5"
30+
type="success"
31+
/>
32+
<goabx-work-side-menu-item
33+
icon="document"
34+
label="Documents"
35+
url="/features/2885/documents"
36+
[divider]="true"
37+
/>
38+
<goabx-work-side-menu-item
39+
icon="alert-circle"
40+
label="Alerts"
41+
badge="3"
42+
type="emergency"
43+
[popoverContent]="alertsTpl"
44+
/>
45+
</ng-template>
46+
47+
<ng-template #alertsTpl>
48+
<div style="padding: 1rem; width: 280px">
49+
<h3 style="margin: 0 0 0.5rem 0; font-size: 1rem">
50+
Custom Popover Content
51+
</h3>
52+
<p style="margin: 0 0 1rem 0; color: #666; font-size: 0.875rem">
53+
This demonstrates that <code>popoverContent</code> accepts any Angular
54+
template, not just
55+
<code>GoabxWorkSideNotificationPanel</code>.
56+
</p>
57+
<ul style="margin: 0; padding-left: 1.25rem; font-size: 0.875rem">
58+
<li>Custom alerts</li>
59+
<li>Quick actions</li>
60+
<li>Mini dashboards</li>
61+
<li>Any custom UI</li>
62+
</ul>
63+
<div style="margin-top: 1rem; text-align: right">
64+
<goa-button type="tertiary" size="compact" action="close">
65+
Close
66+
</goa-button>
67+
</div>
68+
</div>
69+
</ng-template>
70+
71+
<ng-template #secondaryTpl>
72+
<goabx-work-side-menu-item
73+
icon="notifications"
74+
label="Notifications"
75+
badge="12"
76+
type="success"
77+
[popoverContent]="notificationsTpl"
78+
/>
79+
<goabx-work-side-menu-item
80+
icon="help-circle"
81+
label="Help"
82+
url="/features/2885/help"
83+
/>
84+
</ng-template>
85+
86+
<ng-template #notificationsTpl>
87+
<goabx-work-side-notification-panel
88+
heading="Notifications"
89+
activeTab="unread"
90+
(onMarkAllRead)="handleMarkAllRead()"
91+
(onViewAll)="handleViewAll()"
92+
>
93+
<goabx-work-side-notification-item
94+
*ngFor="let notif of notifications; trackBy: trackById"
95+
[title]="notif.title"
96+
[description]="notif.description"
97+
[timestamp]="notif.timestamp"
98+
[type]="notif.type"
99+
[readStatus]="notif.readStatus"
100+
[priority]="notif.priority"
101+
(onClick)="handleNotificationClick(notif.id)"
102+
/>
103+
</goabx-work-side-notification-panel>
104+
</ng-template>
105+
106+
<ng-template #accountTpl>
107+
<goabx-work-side-menu-item
108+
icon="settings"
109+
label="Settings"
110+
url="/features/2885/settings"
111+
/>
112+
<goabx-work-side-menu-item
113+
icon="log-out"
114+
label="Log out"
115+
url="/logout"
116+
/>
117+
</ng-template>
118+
119+
<main
120+
style="
121+
flex: 1;
122+
padding: 2rem;
123+
background-color: #f3f3f3;
124+
overflow: auto;
125+
"
126+
>
127+
<div class="mobile-menu-toggle">
128+
<goab-icon-button
129+
icon="menu"
130+
variant="dark"
131+
(onClick)="openMenu()"
132+
/>
133+
</div>
134+
135+
<h1>Feature #2885: Work Side Menu with Notification Popover</h1>
136+
<p>
137+
This demonstrates the <code>GoabxWorkSideMenu</code> with the new
138+
notification popover feature.
139+
</p>
140+
141+
<h2>New Features</h2>
142+
<ul>
143+
<li>
144+
<strong>Notification Popover</strong> - Click the "Notifications" menu
145+
item to see the popover panel
146+
</li>
147+
<li>
148+
<strong>Custom Popover Content</strong> - Click the "Alerts" menu item
149+
to see a custom div, demonstrating that <code>popoverContent</code>
150+
accepts any Angular template
151+
</li>
152+
<li>
153+
<strong>GoabxWorkSideNotificationPanel</strong> - Panel with tabs
154+
(Unread, Urgent, All)
155+
</li>
156+
<li>
157+
<strong>GoabxWorkSideNotificationItem</strong> - Individual notification
158+
cards with:
159+
<ul>
160+
<li>Title and description</li>
161+
<li>Smart timestamp formatting (e.g., "5 min ago", "2 h ago")</li>
162+
<li>Type badges (info, success, warning, critical)</li>
163+
<li>Read/unread status indicator (green dot)</li>
164+
<li>Urgent priority styling</li>
165+
</ul>
166+
</li>
167+
<li>
168+
<strong>Footer actions</strong> - "View all" and "Mark all as read"
169+
buttons
170+
</li>
171+
</ul>
172+
173+
<h2>Console Output</h2>
174+
<p>
175+
Open the browser console to see events when clicking notifications or
176+
footer actions.
177+
</p>
178+
</main>
179+
</div>

0 commit comments

Comments
 (0)