@opendevstack/ngx-appshell 19.0.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +131 -0
- package/fesm2022/opendevstack-ngx-appshell.mjs +727 -0
- package/fesm2022/opendevstack-ngx-appshell.mjs.map +1 -0
- package/index.d.ts +5 -0
- package/lib/components/appshell-breadcrumb/appshell-breadcrumb.component.d.ts +7 -0
- package/lib/components/appshell-chip/appshell-chip.component.d.ts +6 -0
- package/lib/components/appshell-filters/appshell-filters.component.d.ts +12 -0
- package/lib/components/appshell-header/appshell-header.component.d.ts +24 -0
- package/lib/components/appshell-icon/appshell-icon.component.d.ts +12 -0
- package/lib/components/appshell-layout/appshell-layout.component.d.ts +25 -0
- package/lib/components/appshell-page-header/appshell-page-header.component.d.ts +18 -0
- package/lib/components/appshell-platform-header/appshell-platform-header.component.d.ts +37 -0
- package/lib/components/appshell-platform-layout/appshell-platform-layout.component.d.ts +30 -0
- package/lib/components/appshell-product-card/appshell-product-card.component.d.ts +23 -0
- package/lib/components/appshell-product-card-v2/appshell-product-card-v2.component.d.ts +16 -0
- package/lib/components/appshell-select/appshell-select.component.d.ts +9 -0
- package/lib/components/appshell-sidebar-menu/appshell-sidebar-menu.component.d.ts +12 -0
- package/lib/components/appshell-toast/appshell-toast.component.d.ts +9 -0
- package/lib/components/appshell-toasts/appshell-toasts.component.d.ts +14 -0
- package/lib/components/index.d.ts +15 -0
- package/lib/directives/appshell-link.directive.d.ts +15 -0
- package/lib/directives/index.d.ts +1 -0
- package/lib/models/appshell-button.d.ts +5 -0
- package/lib/models/appshell-filter.d.ts +4 -0
- package/lib/models/appshell-link.d.ts +6 -0
- package/lib/models/appshell-links-group.d.ts +5 -0
- package/lib/models/appshell-notification.d.ts +10 -0
- package/lib/models/appshell-picker.d.ts +9 -0
- package/lib/models/appshell-product.d.ts +12 -0
- package/lib/models/appshell-tag.d.ts +4 -0
- package/lib/models/appshell-toast.d.ts +6 -0
- package/lib/models/appshell-user.d.ts +5 -0
- package/lib/models/index.d.ts +10 -0
- package/lib/screens/appshell-notifications-screen/appshell-notifications-screen.component.d.ts +23 -0
- package/lib/screens/appshell-product-catalog-screen/appshell-product-catalog-screen.component.d.ts +16 -0
- package/lib/screens/appshell-product-view-screen/appshell-product-view-screen.component.d.ts +19 -0
- package/lib/screens/index.d.ts +3 -0
- package/lib/services/appshell-toast.service.d.ts +12 -0
- package/lib/services/icon-registry.service.d.ts +14 -0
- package/lib/services/index.d.ts +2 -0
- package/opendevstack-ngx-appshell-19.0.5.tgz +0 -0
- package/package.json +44 -0
- package/public-api.d.ts +5 -0
- package/schematics/azure-login/files/app-config/config.json.template +12 -0
- package/schematics/azure-login/files/app-config-service/app-config.service.spec.ts.template +48 -0
- package/schematics/azure-login/files/app-config-service/app-config.service.ts.template +39 -0
- package/schematics/azure-login/files/azure-config/azure.config.ts.template +94 -0
- package/schematics/azure-login/files/azure-service/azure.service.spec.ts.template +311 -0
- package/schematics/azure-login/files/azure-service/azure.service.ts.template +161 -0
- package/schematics/azure-login/index.d.ts +2 -0
- package/schematics/azure-login/index.js +325 -0
- package/schematics/azure-login/index.js.map +1 -0
- package/schematics/azure-login/schema.json +8 -0
- package/schematics/collection.json +19 -0
- package/schematics/nats-notifications/files/nats-service/nats.service.spec.ts.template +473 -0
- package/schematics/nats-notifications/files/nats-service/nats.service.ts.template +255 -0
- package/schematics/nats-notifications/files/notifications-screen/notifications-screen.component.html.template +7 -0
- package/schematics/nats-notifications/files/notifications-screen/notifications-screen.component.spec.ts.template +152 -0
- package/schematics/nats-notifications/files/notifications-screen/notifications-screen.component.ts.template +61 -0
- package/schematics/nats-notifications/index.d.ts +2 -0
- package/schematics/nats-notifications/index.js +502 -0
- package/schematics/nats-notifications/index.js.map +1 -0
- package/schematics/nats-notifications/schema.json +8 -0
- package/schematics/ng-add/files/_fonts.scss +85 -0
- package/schematics/ng-add/files/styles.scss +47 -0
- package/schematics/ng-add/index.d.ts +2 -0
- package/schematics/ng-add/index.js +442 -0
- package/schematics/ng-add/index.js.map +1 -0
- package/styles/appshell-typography-config.scss +19 -0
- package/styles/appshell.theme.scss +75 -0
- package/styles/palette.css +92 -0
|
@@ -0,0 +1,727 @@
|
|
|
1
|
+
import * as i0 from '@angular/core';
|
|
2
|
+
import { HostListener, Input, Directive, input, signal, effect, ViewEncapsulation, Component, output, ElementRef, ViewChild, Injectable, computed } from '@angular/core';
|
|
3
|
+
import * as i1 from '@angular/router';
|
|
4
|
+
import { RouterOutlet } from '@angular/router';
|
|
5
|
+
import * as i1$1 from '@angular/material/icon';
|
|
6
|
+
import { MatIconModule } from '@angular/material/icon';
|
|
7
|
+
import * as i1$2 from '@angular/material/chips';
|
|
8
|
+
import { MatChipsModule } from '@angular/material/chips';
|
|
9
|
+
import * as i1$3 from '@angular/material/button';
|
|
10
|
+
import { MatButtonModule } from '@angular/material/button';
|
|
11
|
+
import * as i3 from '@angular/material/menu';
|
|
12
|
+
import { MatMenuModule } from '@angular/material/menu';
|
|
13
|
+
import * as i2 from '@angular/material/tooltip';
|
|
14
|
+
import { MatTooltipModule } from '@angular/material/tooltip';
|
|
15
|
+
import * as i1$4 from '@angular/material/select';
|
|
16
|
+
import { MatSelectModule } from '@angular/material/select';
|
|
17
|
+
import { CommonModule, SlicePipe, DatePipe } from '@angular/common';
|
|
18
|
+
import * as i1$5 from '@angular/material/sidenav';
|
|
19
|
+
import { MatSidenavModule } from '@angular/material/sidenav';
|
|
20
|
+
import * as i4 from '@angular/forms';
|
|
21
|
+
import { FormsModule } from '@angular/forms';
|
|
22
|
+
import { MatFormFieldModule } from '@angular/material/form-field';
|
|
23
|
+
import * as i6 from '@angular/material/input';
|
|
24
|
+
import { MatInputModule } from '@angular/material/input';
|
|
25
|
+
import * as i2$1 from '@angular/material/card';
|
|
26
|
+
import { MatCardModule } from '@angular/material/card';
|
|
27
|
+
import { BehaviorSubject } from 'rxjs';
|
|
28
|
+
import * as i1$6 from 'ngx-markdown';
|
|
29
|
+
import { MarkdownComponent } from 'ngx-markdown';
|
|
30
|
+
import * as i1$7 from '@angular/common/http';
|
|
31
|
+
import { HttpClient } from '@angular/common/http';
|
|
32
|
+
import * as i3$1 from '@angular/platform-browser';
|
|
33
|
+
|
|
34
|
+
class AppShellLinkDirective {
|
|
35
|
+
el;
|
|
36
|
+
router;
|
|
37
|
+
renderer;
|
|
38
|
+
link;
|
|
39
|
+
constructor(el, router, renderer) {
|
|
40
|
+
this.el = el;
|
|
41
|
+
this.router = router;
|
|
42
|
+
this.renderer = renderer;
|
|
43
|
+
}
|
|
44
|
+
ngOnChanges(changes) {
|
|
45
|
+
if (changes['link']?.currentValue) {
|
|
46
|
+
this.renderer.setAttribute(this.el.nativeElement, 'href', this.link);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
onClick(event) {
|
|
50
|
+
if (!this.isExternalLink()) {
|
|
51
|
+
event.preventDefault();
|
|
52
|
+
this.router.navigate([this.link]);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
isExternalLink() {
|
|
56
|
+
return this.link.startsWith('http') || this.link.startsWith('www.');
|
|
57
|
+
}
|
|
58
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.11", ngImport: i0, type: AppShellLinkDirective, deps: [{ token: i0.ElementRef }, { token: i1.Router }, { token: i0.Renderer2 }], target: i0.ɵɵFactoryTarget.Directive });
|
|
59
|
+
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "19.2.11", type: AppShellLinkDirective, isStandalone: true, selector: "[appShellLink]", inputs: { link: ["appShellLink", "link"] }, host: { listeners: { "click": "onClick($event)" } }, usesOnChanges: true, ngImport: i0 });
|
|
60
|
+
}
|
|
61
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.11", ngImport: i0, type: AppShellLinkDirective, decorators: [{
|
|
62
|
+
type: Directive,
|
|
63
|
+
args: [{
|
|
64
|
+
selector: '[appShellLink]',
|
|
65
|
+
standalone: true
|
|
66
|
+
}]
|
|
67
|
+
}], ctorParameters: () => [{ type: i0.ElementRef }, { type: i1.Router }, { type: i0.Renderer2 }], propDecorators: { link: [{
|
|
68
|
+
type: Input,
|
|
69
|
+
args: ['appShellLink']
|
|
70
|
+
}], onClick: [{
|
|
71
|
+
type: HostListener,
|
|
72
|
+
args: ['click', ['$event']]
|
|
73
|
+
}] } });
|
|
74
|
+
|
|
75
|
+
class AppShellIconComponent {
|
|
76
|
+
iconRegistry;
|
|
77
|
+
icon = input.required();
|
|
78
|
+
namespace = 'appshell';
|
|
79
|
+
// Resolved values for template rendering
|
|
80
|
+
resolvedSvgIcon = signal('');
|
|
81
|
+
resolvedFontIcon = signal('');
|
|
82
|
+
constructor(iconRegistry) {
|
|
83
|
+
this.iconRegistry = iconRegistry;
|
|
84
|
+
effect((onCleanup) => {
|
|
85
|
+
const iconName = this.icon();
|
|
86
|
+
// Try to resolve namespaced appshell icon; fall back to material font icon
|
|
87
|
+
// getNamedSvgIcon emits if the icon exists, errors if it doesn't.
|
|
88
|
+
let sub;
|
|
89
|
+
sub = this.iconRegistry.getNamedSvgIcon(iconName, this.namespace).subscribe({
|
|
90
|
+
next: () => {
|
|
91
|
+
this.resolvedSvgIcon.set(`${this.namespace}:${iconName}`);
|
|
92
|
+
this.resolvedFontIcon.set('');
|
|
93
|
+
},
|
|
94
|
+
error: () => {
|
|
95
|
+
this.resolvedSvgIcon.set('');
|
|
96
|
+
this.resolvedFontIcon.set(iconName);
|
|
97
|
+
}
|
|
98
|
+
});
|
|
99
|
+
onCleanup(() => sub?.unsubscribe());
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.11", ngImport: i0, type: AppShellIconComponent, deps: [{ token: i1$1.MatIconRegistry }], target: i0.ɵɵFactoryTarget.Component });
|
|
103
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.11", type: AppShellIconComponent, isStandalone: true, selector: "appshell-icon", inputs: { icon: { classPropertyName: "icon", publicName: "icon", isSignal: true, isRequired: true, transformFunction: null } }, ngImport: i0, template: "@if (resolvedSvgIcon()) {\n <mat-icon [svgIcon]=\"resolvedSvgIcon()\"></mat-icon>\n} @else {\n <mat-icon>{{ resolvedFontIcon() }}</mat-icon>\n}", styles: ["appshell-icon{height:1.5rem;display:flex}mat-icon svg path{fill:currentColor!important}\n"], dependencies: [{ kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i1$1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }], encapsulation: i0.ViewEncapsulation.None });
|
|
104
|
+
}
|
|
105
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.11", ngImport: i0, type: AppShellIconComponent, decorators: [{
|
|
106
|
+
type: Component,
|
|
107
|
+
args: [{ selector: 'appshell-icon', imports: [MatIconModule], encapsulation: ViewEncapsulation.None, template: "@if (resolvedSvgIcon()) {\n <mat-icon [svgIcon]=\"resolvedSvgIcon()\"></mat-icon>\n} @else {\n <mat-icon>{{ resolvedFontIcon() }}</mat-icon>\n}", styles: ["appshell-icon{height:1.5rem;display:flex}mat-icon svg path{fill:currentColor!important}\n"] }]
|
|
108
|
+
}], ctorParameters: () => [{ type: i1$1.MatIconRegistry }] });
|
|
109
|
+
|
|
110
|
+
class AppShellBreadcrumbComponent {
|
|
111
|
+
links = input();
|
|
112
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.11", ngImport: i0, type: AppShellBreadcrumbComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
113
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.11", type: AppShellBreadcrumbComponent, isStandalone: true, selector: "appshell-breadcrumb", inputs: { links: { classPropertyName: "links", publicName: "links", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "<nav>\n @for (link of links(); track link.label) {\n @if ($index > 0) {\n <appshell-icon class=\"separator\" aria-hidden=\"true\" [icon]=\"'chevron_right'\" />\n }\n @if (link.icon) {\n @if (link.anchor !== '') {\n <a [appShellLink]=\"link.anchor\" target=\"{{link.target || '_self'}}\">\n <appshell-icon [icon]=\"link.icon\" />\n </a>\n } @else {\n <appshell-icon [icon]=\"link.icon\" />\n }\n } @else {\n @if (link.anchor !== '') {\n <a [appShellLink]=\"link.anchor\" target=\"{{link.target || '_self'}}\">{{ link.label }}</a>\n } @else {\n <span>{{ link.label }}</span>\n }\n }\n }\n</nav>", styles: ["nav{margin-bottom:.5rem;display:flex;align-items:center;gap:.25rem}nav a,nav span{color:var(--appshell-color-secondary-main);font-size:.875rem;text-decoration:none}nav .separator,nav .separator>mat-icon{height:1.25rem;width:1.25rem}nav a:hover{text-decoration:underline}\n"], dependencies: [{ kind: "directive", type: AppShellLinkDirective, selector: "[appShellLink]", inputs: ["appShellLink"] }, { kind: "component", type: AppShellIconComponent, selector: "appshell-icon", inputs: ["icon"] }], encapsulation: i0.ViewEncapsulation.None });
|
|
114
|
+
}
|
|
115
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.11", ngImport: i0, type: AppShellBreadcrumbComponent, decorators: [{
|
|
116
|
+
type: Component,
|
|
117
|
+
args: [{ selector: 'appshell-breadcrumb', imports: [AppShellLinkDirective, AppShellIconComponent], encapsulation: ViewEncapsulation.None, template: "<nav>\n @for (link of links(); track link.label) {\n @if ($index > 0) {\n <appshell-icon class=\"separator\" aria-hidden=\"true\" [icon]=\"'chevron_right'\" />\n }\n @if (link.icon) {\n @if (link.anchor !== '') {\n <a [appShellLink]=\"link.anchor\" target=\"{{link.target || '_self'}}\">\n <appshell-icon [icon]=\"link.icon\" />\n </a>\n } @else {\n <appshell-icon [icon]=\"link.icon\" />\n }\n } @else {\n @if (link.anchor !== '') {\n <a [appShellLink]=\"link.anchor\" target=\"{{link.target || '_self'}}\">{{ link.label }}</a>\n } @else {\n <span>{{ link.label }}</span>\n }\n }\n }\n</nav>", styles: ["nav{margin-bottom:.5rem;display:flex;align-items:center;gap:.25rem}nav a,nav span{color:var(--appshell-color-secondary-main);font-size:.875rem;text-decoration:none}nav .separator,nav .separator>mat-icon{height:1.25rem;width:1.25rem}nav a:hover{text-decoration:underline}\n"] }]
|
|
118
|
+
}] });
|
|
119
|
+
|
|
120
|
+
class AppShellChipComponent {
|
|
121
|
+
label = input.required();
|
|
122
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.11", ngImport: i0, type: AppShellChipComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
123
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "19.2.11", type: AppShellChipComponent, isStandalone: true, selector: "appshell-chip", inputs: { label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: true, transformFunction: null } }, ngImport: i0, template: "<mat-chip class=\"appshell-chip\" disableRipple>{{label()}}</mat-chip>", styles: [".appshell-chip{--mdc-chip-disabled-label-text-color: var(--appshell-color-sky-blue-contrast)!important;--mdc-chip-elevated-container-color: var(--appshell-color-sky-blue-light)!important;--mdc-chip-elevated-disabled-container-color: var(--appshell-color-sky-blue-light)!important;--mdc-chip-focus-state-layer-color: black;--mdc-chip-focus-state-layer-opacity: .12;--mdc-chip-label-text-color: var(--appshell-color-sky-blue-contrast)!important;--mdc-chip-with-icon-icon-color: var(--appshell-color-sky-blue-contrast)!important;--mdc-chip-with-icon-disabled-icon-color: var(--appshell-color-sky-blue-contrast)!important;--mdc-chip-with-icon-selected-icon-color: var(--appshell-color-sky-blue-contrast)!important;--mdc-chip-with-trailing-icon-disabled-trailing-icon-color: var(--appshell-color-sky-blue-contrast)!important;--mdc-chip-with-trailing-icon-trailing-icon-color: var(--appshell-color-sky-blue-contrast)!important;--mdc-chip-focus-state-layer-color: var(--appshell-color-sky-blue-light)!important;--mdc-chip-focus-state-layer-opacity: 0;--mdc-chip-label-text-size: .875rem}.appshell-chip.mat-mdc-standard-chip{margin:0}.appshell-chip.mat-mdc-standard-chip .mdc-evolution-chip__action{cursor:unset}\n"], dependencies: [{ kind: "ngmodule", type: MatChipsModule }, { kind: "component", type: i1$2.MatChip, selector: "mat-basic-chip, [mat-basic-chip], mat-chip, [mat-chip]", inputs: ["role", "id", "aria-label", "aria-description", "value", "color", "removable", "highlighted", "disableRipple", "disabled"], outputs: ["removed", "destroyed"], exportAs: ["matChip"] }], encapsulation: i0.ViewEncapsulation.None });
|
|
124
|
+
}
|
|
125
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.11", ngImport: i0, type: AppShellChipComponent, decorators: [{
|
|
126
|
+
type: Component,
|
|
127
|
+
args: [{ selector: 'appshell-chip', imports: [MatChipsModule], encapsulation: ViewEncapsulation.None, template: "<mat-chip class=\"appshell-chip\" disableRipple>{{label()}}</mat-chip>", styles: [".appshell-chip{--mdc-chip-disabled-label-text-color: var(--appshell-color-sky-blue-contrast)!important;--mdc-chip-elevated-container-color: var(--appshell-color-sky-blue-light)!important;--mdc-chip-elevated-disabled-container-color: var(--appshell-color-sky-blue-light)!important;--mdc-chip-focus-state-layer-color: black;--mdc-chip-focus-state-layer-opacity: .12;--mdc-chip-label-text-color: var(--appshell-color-sky-blue-contrast)!important;--mdc-chip-with-icon-icon-color: var(--appshell-color-sky-blue-contrast)!important;--mdc-chip-with-icon-disabled-icon-color: var(--appshell-color-sky-blue-contrast)!important;--mdc-chip-with-icon-selected-icon-color: var(--appshell-color-sky-blue-contrast)!important;--mdc-chip-with-trailing-icon-disabled-trailing-icon-color: var(--appshell-color-sky-blue-contrast)!important;--mdc-chip-with-trailing-icon-trailing-icon-color: var(--appshell-color-sky-blue-contrast)!important;--mdc-chip-focus-state-layer-color: var(--appshell-color-sky-blue-light)!important;--mdc-chip-focus-state-layer-opacity: 0;--mdc-chip-label-text-size: .875rem}.appshell-chip.mat-mdc-standard-chip{margin:0}.appshell-chip.mat-mdc-standard-chip .mdc-evolution-chip__action{cursor:unset}\n"] }]
|
|
128
|
+
}] });
|
|
129
|
+
|
|
130
|
+
class AppShellPageHeaderComponent {
|
|
131
|
+
breadcrumbLinks = input();
|
|
132
|
+
title = input();
|
|
133
|
+
button = input();
|
|
134
|
+
buttonClicked = output();
|
|
135
|
+
secondaryButton = input();
|
|
136
|
+
secondaryButtonClicked = output();
|
|
137
|
+
picker = input();
|
|
138
|
+
pick = output();
|
|
139
|
+
clickButton() {
|
|
140
|
+
this.buttonClicked.emit();
|
|
141
|
+
}
|
|
142
|
+
clickSecondaryButton() {
|
|
143
|
+
this.secondaryButtonClicked.emit();
|
|
144
|
+
}
|
|
145
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.11", ngImport: i0, type: AppShellPageHeaderComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
146
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.11", type: AppShellPageHeaderComponent, isStandalone: true, selector: "appshell-page-header", inputs: { breadcrumbLinks: { classPropertyName: "breadcrumbLinks", publicName: "breadcrumbLinks", isSignal: true, isRequired: false, transformFunction: null }, title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: false, transformFunction: null }, button: { classPropertyName: "button", publicName: "button", isSignal: true, isRequired: false, transformFunction: null }, secondaryButton: { classPropertyName: "secondaryButton", publicName: "secondaryButton", isSignal: true, isRequired: false, transformFunction: null }, picker: { classPropertyName: "picker", publicName: "picker", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { buttonClicked: "buttonClicked", secondaryButtonClicked: "secondaryButtonClicked", pick: "pick" }, ngImport: i0, template: "<div class=\"top-section\">\n <div class=\"left-ctn\">\n <appshell-breadcrumb [links]=\"breadcrumbLinks()\"></appshell-breadcrumb>\n <h2>{{title()}}</h2>\n </div>\n @if (picker() && picker()?.label && picker()?.options && picker()?.options!.length > 0) {\n <button [matMenuTriggerFor]=\"pickerMenu\" #pickerTrigger=\"matMenuTrigger\" mat-button class=\"action-picker-btn\">\n <span class=\"action-picker-label\">\n {{picker()!.label}}\n <appshell-icon [icon]=\"pickerTrigger.menuOpen ? 'expand_less' : 'expand_more'\" />\n </span>\n </button>\n <mat-menu #pickerMenu=\"matMenu\" xPosition=\"after\" class=\"appshell-picker-panel\">\n @for (opt of picker()!.options; track opt; let index = $index) {\n <button mat-menu-item (click)=\"pick.emit(opt)\" (keypress)=\"pick.emit(opt)\" [class.active]=\"picker()?.selected === opt\" attr.aria-label=\"{{opt}}\">{{ opt }}</button>\n }\n </mat-menu>\n }\n @if (secondaryButton()) {\n <div [matTooltip]=\"secondaryButton()?.tooltip || ''\" class=\"btn-ctn\">\n <button mat-flat-button color=\"secondary\" (click)=\"clickSecondaryButton()\" [disabled]=\"secondaryButton()?.disabled\">{{secondaryButton()?.label}}</button>\n </div>\n }\n @if (button()) {\n <div [matTooltip]=\"button()?.tooltip || ''\" class=\"btn-ctn\">\n <button mat-flat-button color=\"accent\" (click)=\"clickButton()\" [disabled]=\"button()?.disabled\">{{button()?.label}}</button>\n </div>\n }\n</div>", styles: [".top-section{display:flex;flex-direction:row;justify-content:space-between;align-items:end;padding:1.5rem;gap:2rem}.top-section>.left-ctn{flex:1}.top-section>.left-ctn h2{font-size:1.5rem;color:var(--appshell-color-secondary-main);line-height:150%;margin:0}.top-section>.btn-ctn>button,.top-section .action-picker-btn{--mdc-filled-button-container-height: unset!important;display:inline-flex;align-items:center;padding:.75rem 1.5rem;border-radius:.125rem;font-size:.875rem;font-style:normal;font-weight:500;line-height:1.25rem;height:auto;color:var(--appshell-color-secondary-main)!important;text-decoration:none;font-family:AppShellTextFont;border:2px solid var(--mdc-filled-button-container-color)}.top-section>.btn-ctn>button:disabled,.top-section .action-picker-btn:disabled{border-color:transparent;color:var(--appshell-color-grey-main)!important}.top-section>.btn-ctn>button.mat-secondary,.top-section .action-picker-btn.mat-secondary{border:2px solid var(--appshell-color-secondary-main)}.top-section>.btn-ctn>button.mat-secondary:disabled,.top-section .action-picker-btn.mat-secondary:disabled{border-color:var(--mdc-filled-button-disabled-container-color);background-color:transparent;color:var(--appshell-color-grey-main)!important}.top-section>.btn-ctn>button.action-picker-btn,.top-section .action-picker-btn.action-picker-btn{border-bottom:2px solid var(--appshell-color-accent-green-main);padding:.5rem 1rem;min-width:10rem;--mat-text-button-hover-state-layer-opacity: 0;--mat-text-button-focus-state-layer-opacity: 0;--mat-text-button-pressed-state-layer-opacity: 0;--mat-text-button-ripple-color: transparent}.top-section>.btn-ctn>button.action-picker-btn>span,.top-section .action-picker-btn.action-picker-btn>span{width:100%}.top-section>.btn-ctn>button.action-picker-btn:hover,.top-section .action-picker-btn.action-picker-btn:hover{color:var(--appshell-color-secondary-medium);background-color:transparent;border-bottom:2px solid var(--appshell-color-accent-green-medium)}.top-section>.btn-ctn>button.action-picker-btn .action-picker-label,.top-section .action-picker-btn.action-picker-btn .action-picker-label{display:flex;gap:.5rem;justify-content:space-between}.appshell-picker-panel{padding:.75rem 0;margin-top:.4rem;border-radius:.125rem!important;border:1px solid var(--appshell-color-grey-main);box-shadow:none!important}.appshell-picker-panel>div{padding:0}.appshell-picker-panel button.active{background-color:var(--appshell-color-grey-neutral);border-left:2px solid var(--appshell-color-accent-green-main)}.appshell-picker-panel button:focus-visible{outline:2px solid #0069E5;outline-offset:-.1rem}.appshell-picker-panel button:hover{background-color:var(--appshell-color-grey-light)}\n"], dependencies: [{ kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i1$3.MatButton, selector: " button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ", exportAs: ["matButton"] }, { kind: "component", type: AppShellBreadcrumbComponent, selector: "appshell-breadcrumb", inputs: ["links"] }, { kind: "ngmodule", type: MatMenuModule }, { kind: "component", type: i3.MatMenu, selector: "mat-menu", inputs: ["backdropClass", "aria-label", "aria-labelledby", "aria-describedby", "xPosition", "yPosition", "overlapTrigger", "hasBackdrop", "class", "classList"], outputs: ["closed", "close"], exportAs: ["matMenu"] }, { kind: "component", type: i3.MatMenuItem, selector: "[mat-menu-item]", inputs: ["role", "disabled", "disableRipple"], exportAs: ["matMenuItem"] }, { kind: "directive", type: i3.MatMenuTrigger, selector: "[mat-menu-trigger-for], [matMenuTriggerFor]", inputs: ["mat-menu-trigger-for", "matMenuTriggerFor", "matMenuTriggerData", "matMenuTriggerRestoreFocus"], outputs: ["menuOpened", "onMenuOpen", "menuClosed", "onMenuClose"], exportAs: ["matMenuTrigger"] }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i2.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "component", type: AppShellIconComponent, selector: "appshell-icon", inputs: ["icon"] }], encapsulation: i0.ViewEncapsulation.None });
|
|
147
|
+
}
|
|
148
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.11", ngImport: i0, type: AppShellPageHeaderComponent, decorators: [{
|
|
149
|
+
type: Component,
|
|
150
|
+
args: [{ selector: 'appshell-page-header', imports: [MatButtonModule, AppShellBreadcrumbComponent, MatMenuModule, MatTooltipModule, AppShellIconComponent], encapsulation: ViewEncapsulation.None, template: "<div class=\"top-section\">\n <div class=\"left-ctn\">\n <appshell-breadcrumb [links]=\"breadcrumbLinks()\"></appshell-breadcrumb>\n <h2>{{title()}}</h2>\n </div>\n @if (picker() && picker()?.label && picker()?.options && picker()?.options!.length > 0) {\n <button [matMenuTriggerFor]=\"pickerMenu\" #pickerTrigger=\"matMenuTrigger\" mat-button class=\"action-picker-btn\">\n <span class=\"action-picker-label\">\n {{picker()!.label}}\n <appshell-icon [icon]=\"pickerTrigger.menuOpen ? 'expand_less' : 'expand_more'\" />\n </span>\n </button>\n <mat-menu #pickerMenu=\"matMenu\" xPosition=\"after\" class=\"appshell-picker-panel\">\n @for (opt of picker()!.options; track opt; let index = $index) {\n <button mat-menu-item (click)=\"pick.emit(opt)\" (keypress)=\"pick.emit(opt)\" [class.active]=\"picker()?.selected === opt\" attr.aria-label=\"{{opt}}\">{{ opt }}</button>\n }\n </mat-menu>\n }\n @if (secondaryButton()) {\n <div [matTooltip]=\"secondaryButton()?.tooltip || ''\" class=\"btn-ctn\">\n <button mat-flat-button color=\"secondary\" (click)=\"clickSecondaryButton()\" [disabled]=\"secondaryButton()?.disabled\">{{secondaryButton()?.label}}</button>\n </div>\n }\n @if (button()) {\n <div [matTooltip]=\"button()?.tooltip || ''\" class=\"btn-ctn\">\n <button mat-flat-button color=\"accent\" (click)=\"clickButton()\" [disabled]=\"button()?.disabled\">{{button()?.label}}</button>\n </div>\n }\n</div>", styles: [".top-section{display:flex;flex-direction:row;justify-content:space-between;align-items:end;padding:1.5rem;gap:2rem}.top-section>.left-ctn{flex:1}.top-section>.left-ctn h2{font-size:1.5rem;color:var(--appshell-color-secondary-main);line-height:150%;margin:0}.top-section>.btn-ctn>button,.top-section .action-picker-btn{--mdc-filled-button-container-height: unset!important;display:inline-flex;align-items:center;padding:.75rem 1.5rem;border-radius:.125rem;font-size:.875rem;font-style:normal;font-weight:500;line-height:1.25rem;height:auto;color:var(--appshell-color-secondary-main)!important;text-decoration:none;font-family:AppShellTextFont;border:2px solid var(--mdc-filled-button-container-color)}.top-section>.btn-ctn>button:disabled,.top-section .action-picker-btn:disabled{border-color:transparent;color:var(--appshell-color-grey-main)!important}.top-section>.btn-ctn>button.mat-secondary,.top-section .action-picker-btn.mat-secondary{border:2px solid var(--appshell-color-secondary-main)}.top-section>.btn-ctn>button.mat-secondary:disabled,.top-section .action-picker-btn.mat-secondary:disabled{border-color:var(--mdc-filled-button-disabled-container-color);background-color:transparent;color:var(--appshell-color-grey-main)!important}.top-section>.btn-ctn>button.action-picker-btn,.top-section .action-picker-btn.action-picker-btn{border-bottom:2px solid var(--appshell-color-accent-green-main);padding:.5rem 1rem;min-width:10rem;--mat-text-button-hover-state-layer-opacity: 0;--mat-text-button-focus-state-layer-opacity: 0;--mat-text-button-pressed-state-layer-opacity: 0;--mat-text-button-ripple-color: transparent}.top-section>.btn-ctn>button.action-picker-btn>span,.top-section .action-picker-btn.action-picker-btn>span{width:100%}.top-section>.btn-ctn>button.action-picker-btn:hover,.top-section .action-picker-btn.action-picker-btn:hover{color:var(--appshell-color-secondary-medium);background-color:transparent;border-bottom:2px solid var(--appshell-color-accent-green-medium)}.top-section>.btn-ctn>button.action-picker-btn .action-picker-label,.top-section .action-picker-btn.action-picker-btn .action-picker-label{display:flex;gap:.5rem;justify-content:space-between}.appshell-picker-panel{padding:.75rem 0;margin-top:.4rem;border-radius:.125rem!important;border:1px solid var(--appshell-color-grey-main);box-shadow:none!important}.appshell-picker-panel>div{padding:0}.appshell-picker-panel button.active{background-color:var(--appshell-color-grey-neutral);border-left:2px solid var(--appshell-color-accent-green-main)}.appshell-picker-panel button:focus-visible{outline:2px solid #0069E5;outline-offset:-.1rem}.appshell-picker-panel button:hover{background-color:var(--appshell-color-grey-light)}\n"] }]
|
|
151
|
+
}] });
|
|
152
|
+
|
|
153
|
+
class AppShellSelectComponent {
|
|
154
|
+
label = input.required();
|
|
155
|
+
options = input.required();
|
|
156
|
+
placeholder = input.required();
|
|
157
|
+
selectValueChange = output();
|
|
158
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.11", ngImport: i0, type: AppShellSelectComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
159
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.11", type: AppShellSelectComponent, isStandalone: true, selector: "appshell-select", inputs: { label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: true, transformFunction: null }, options: { classPropertyName: "options", publicName: "options", isSignal: true, isRequired: true, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: true, transformFunction: null } }, outputs: { selectValueChange: "selectValueChange" }, ngImport: i0, template: "<mat-label>{{label()}}</mat-label>\n<mat-form-field appearance=\"outline\">\n <mat-select (selectionChange)=\"selectValueChange.emit($event.value)\" multiple [placeholder]=\"placeholder()\" panelClass=\"appshell-select-panel\" attr.aria-label=\"{{label()}}\">\n @for (option of options(); track option) {\n <mat-option value=\"{{option}}\">{{option}}</mat-option>\n }\n </mat-select>\n</mat-form-field>", styles: ["appshell-select{display:flex;flex-direction:column;--mat-select-enabled-trigger-text-color: var(--appshell-color-secondary-main);--mdc-outlined-text-field-focus-outline-color: var(--appshell-color-accent-green-main);--mat-form-field-subscript-text-line-height: 1.5rem;--mdc-outlined-text-field-container-shape: .125rem}appshell-select mat-label{margin-bottom:.5rem;color:var(--appshell-color-secondary-main);font-size:.875rem;font-style:normal;font-weight:400;line-height:1.25rem}appshell-select .mat-mdc-form-field-type-mat-select .mat-mdc-text-field-wrapper{height:3rem}appshell-select .mat-mdc-form-field-type-mat-select .mat-mdc-text-field-wrapper .mat-mdc-form-field-flex{height:100%}appshell-select .mat-mdc-form-field-type-mat-select .mat-mdc-text-field-wrapper .mat-mdc-form-field-infix{height:100%;min-height:unset;padding:.75rem 0}.appshell-select-panel{border:1px solid var(--appshell-color-grey-dark);margin-top:.5rem;box-shadow:none!important;border-radius:.125rem!important;padding:.75rem 0!important;--mat-option-label-text-color: var(--appshell-color-secondary-main)}\n"], dependencies: [{ kind: "ngmodule", type: MatSelectModule }, { kind: "component", type: i1$4.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i1$4.MatLabel, selector: "mat-label" }, { kind: "component", type: i1$4.MatSelect, selector: "mat-select", inputs: ["aria-describedby", "panelClass", "disabled", "disableRipple", "tabIndex", "hideSingleSelectionIndicator", "placeholder", "required", "multiple", "disableOptionCentering", "compareWith", "value", "aria-label", "aria-labelledby", "errorStateMatcher", "typeaheadDebounceInterval", "sortComparator", "id", "panelWidth", "canSelectNullableOptions"], outputs: ["openedChange", "opened", "closed", "selectionChange", "valueChange"], exportAs: ["matSelect"] }, { kind: "component", type: i1$4.MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }], encapsulation: i0.ViewEncapsulation.None });
|
|
160
|
+
}
|
|
161
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.11", ngImport: i0, type: AppShellSelectComponent, decorators: [{
|
|
162
|
+
type: Component,
|
|
163
|
+
args: [{ selector: 'appshell-select', imports: [MatSelectModule], encapsulation: ViewEncapsulation.None, template: "<mat-label>{{label()}}</mat-label>\n<mat-form-field appearance=\"outline\">\n <mat-select (selectionChange)=\"selectValueChange.emit($event.value)\" multiple [placeholder]=\"placeholder()\" panelClass=\"appshell-select-panel\" attr.aria-label=\"{{label()}}\">\n @for (option of options(); track option) {\n <mat-option value=\"{{option}}\">{{option}}</mat-option>\n }\n </mat-select>\n</mat-form-field>", styles: ["appshell-select{display:flex;flex-direction:column;--mat-select-enabled-trigger-text-color: var(--appshell-color-secondary-main);--mdc-outlined-text-field-focus-outline-color: var(--appshell-color-accent-green-main);--mat-form-field-subscript-text-line-height: 1.5rem;--mdc-outlined-text-field-container-shape: .125rem}appshell-select mat-label{margin-bottom:.5rem;color:var(--appshell-color-secondary-main);font-size:.875rem;font-style:normal;font-weight:400;line-height:1.25rem}appshell-select .mat-mdc-form-field-type-mat-select .mat-mdc-text-field-wrapper{height:3rem}appshell-select .mat-mdc-form-field-type-mat-select .mat-mdc-text-field-wrapper .mat-mdc-form-field-flex{height:100%}appshell-select .mat-mdc-form-field-type-mat-select .mat-mdc-text-field-wrapper .mat-mdc-form-field-infix{height:100%;min-height:unset;padding:.75rem 0}.appshell-select-panel{border:1px solid var(--appshell-color-grey-dark);margin-top:.5rem;box-shadow:none!important;border-radius:.125rem!important;padding:.75rem 0!important;--mat-option-label-text-color: var(--appshell-color-secondary-main)}\n"] }]
|
|
164
|
+
}] });
|
|
165
|
+
|
|
166
|
+
class AppShellFiltersComponent {
|
|
167
|
+
filters = input();
|
|
168
|
+
activeFilters = new Map();
|
|
169
|
+
activeFiltersChange = output();
|
|
170
|
+
ngOnChanges(changes) {
|
|
171
|
+
if (changes['filters']) {
|
|
172
|
+
this.activeFilters.clear();
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
onFilterChange(label, values) {
|
|
176
|
+
if (typeof values === 'string') {
|
|
177
|
+
if (values === '') {
|
|
178
|
+
this.activeFilters.delete(label);
|
|
179
|
+
}
|
|
180
|
+
else {
|
|
181
|
+
this.activeFilters.set(label, [values]);
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
else if (values.length === 0) {
|
|
185
|
+
this.activeFilters.delete(label);
|
|
186
|
+
}
|
|
187
|
+
else {
|
|
188
|
+
this.activeFilters.set(label, values);
|
|
189
|
+
}
|
|
190
|
+
this.activeFiltersChange.emit(this.activeFilters);
|
|
191
|
+
}
|
|
192
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.11", ngImport: i0, type: AppShellFiltersComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
193
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.11", type: AppShellFiltersComponent, isStandalone: true, selector: "appshell-filters", inputs: { filters: { classPropertyName: "filters", publicName: "filters", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { activeFiltersChange: "activeFiltersChange" }, usesOnChanges: true, ngImport: i0, template: "<div class=\"filters-ctn\">\n @for (filter of filters(); track filter.label) {\n <appshell-select [label]=\"filter.label\" \n [options]=\"filter.options\" \n [placeholder]=\"filter.placeholder\" \n (selectValueChange)=\"onFilterChange(filter.label, $event)\">\n </appshell-select>\n }\n</div>", styles: [".filters-ctn{padding:.5rem 1.5rem 0;display:flex;flex-direction:row;flex-wrap:wrap;column-gap:2.5rem}\n"], dependencies: [{ kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: AppShellSelectComponent, selector: "appshell-select", inputs: ["label", "options", "placeholder"], outputs: ["selectValueChange"] }] });
|
|
194
|
+
}
|
|
195
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.11", ngImport: i0, type: AppShellFiltersComponent, decorators: [{
|
|
196
|
+
type: Component,
|
|
197
|
+
args: [{ selector: 'appshell-filters', imports: [MatButtonModule, AppShellSelectComponent], template: "<div class=\"filters-ctn\">\n @for (filter of filters(); track filter.label) {\n <appshell-select [label]=\"filter.label\" \n [options]=\"filter.options\" \n [placeholder]=\"filter.placeholder\" \n (selectValueChange)=\"onFilterChange(filter.label, $event)\">\n </appshell-select>\n }\n</div>", styles: [".filters-ctn{padding:.5rem 1.5rem 0;display:flex;flex-direction:row;flex-wrap:wrap;column-gap:2.5rem}\n"] }]
|
|
198
|
+
}] });
|
|
199
|
+
|
|
200
|
+
class AppShellHeaderComponent {
|
|
201
|
+
router;
|
|
202
|
+
applicationName = input.required();
|
|
203
|
+
symbol = input();
|
|
204
|
+
applicationNameLink = input();
|
|
205
|
+
helpLink = input();
|
|
206
|
+
notificationsLink = input();
|
|
207
|
+
notificationsCount = input(0);
|
|
208
|
+
links = input.required();
|
|
209
|
+
picker = input();
|
|
210
|
+
loggedUser = input();
|
|
211
|
+
userLoggedIn = output();
|
|
212
|
+
userLoggedOut = output();
|
|
213
|
+
userPick = output();
|
|
214
|
+
constructor(router) {
|
|
215
|
+
this.router = router;
|
|
216
|
+
}
|
|
217
|
+
getCurrentUrlPath() {
|
|
218
|
+
return this.router.url;
|
|
219
|
+
}
|
|
220
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.11", ngImport: i0, type: AppShellHeaderComponent, deps: [{ token: i1.Router }], target: i0.ɵɵFactoryTarget.Component });
|
|
221
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.11", type: AppShellHeaderComponent, isStandalone: true, selector: "appshell-header", inputs: { applicationName: { classPropertyName: "applicationName", publicName: "applicationName", isSignal: true, isRequired: true, transformFunction: null }, symbol: { classPropertyName: "symbol", publicName: "symbol", isSignal: true, isRequired: false, transformFunction: null }, applicationNameLink: { classPropertyName: "applicationNameLink", publicName: "applicationNameLink", isSignal: true, isRequired: false, transformFunction: null }, helpLink: { classPropertyName: "helpLink", publicName: "helpLink", isSignal: true, isRequired: false, transformFunction: null }, notificationsLink: { classPropertyName: "notificationsLink", publicName: "notificationsLink", isSignal: true, isRequired: false, transformFunction: null }, notificationsCount: { classPropertyName: "notificationsCount", publicName: "notificationsCount", isSignal: true, isRequired: false, transformFunction: null }, links: { classPropertyName: "links", publicName: "links", isSignal: true, isRequired: true, transformFunction: null }, picker: { classPropertyName: "picker", publicName: "picker", isSignal: true, isRequired: false, transformFunction: null }, loggedUser: { classPropertyName: "loggedUser", publicName: "loggedUser", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { userLoggedIn: "userLoggedIn", userLoggedOut: "userLoggedOut", userPick: "userPick" }, ngImport: i0, template: "<nav class=\"appshell-meta-navigation\" aria-label=\"Top of the header navigation\">\n @if (applicationNameLink() && applicationNameLink() !== '') {\n <a class=\"app-id-ctn\" [href]=\"applicationNameLink()\">\n @if (symbol()) {\n <img src=\"assets/logo/{{symbol()}}\" alt=\"App symbol in the header\" />\n }\n <h1>{{applicationName()}}</h1>\n </a>\n } @else {\n <div class=\"app-id-ctn\">\n @if (symbol()) {\n <img src=\"assets/logo/{{symbol()}}\" alt=\"App symbol in the header\" />\n }\n <h1>{{applicationName()}}</h1>\n </div>\n }\n <div class=\"header-space\"></div>\n @for (link of links(); track link.label; let index = $index) {\n <a class=\"header-link\" [appShellLink]=\"link.anchor\" [class.active]=\"getCurrentUrlPath() === link.anchor\" target=\"{{link!.target || '_self'}}\" [class.last]=\"index+1 === links().length\">\n {{link.label}}\n </a>\n }\n @if (picker() && picker()?.label && picker()?.options && picker()?.options!.length > 0) {\n <button [matMenuTriggerFor]=\"pickerMenu\" #pickerTrigger=\"matMenuTrigger\" class=\"header-picker\">\n {{picker()!.label}}\n <appshell-icon [icon]=\"pickerTrigger.menuOpen ? 'expand_less' : 'expand_more'\" />\n </button>\n <mat-menu #pickerMenu=\"matMenu\" xPosition=\"after\" class=\"appshell-picker-panel\">\n @for (opt of picker()!.options; track opt; let index = $index) {\n <button mat-menu-item (click)=\"userPick.emit(opt)\" (keypress)=\"userPick.emit(opt)\" [class.active]=\"picker()?.selected === opt\" attr.aria-label=\"{{opt}}\">{{ opt }}</button>\n }\n </mat-menu>\n }\n @if (helpLink() && helpLink()?.icon) {\n <a class=\"header-icon\" [appShellLink]=\"helpLink()!.anchor\" target=\"{{helpLink()!.target || '_self'}}\" [matTooltip]=\"helpLink()!.label\" aria-label=\"Visit the help page\">\n <appshell-icon [icon]=\"helpLink()!.icon!\" aria-label=\"Help icon\" />\n </a>\n }\n @if (notificationsLink() && notificationsLink()?.icon) {\n <a class=\"header-icon\" [appShellLink]=\"notificationsLink()!.anchor\" target=\"{{notificationsLink()!.target || '_self'}}\" [matTooltip]=\"notificationsLink()!.label\" aria-label=\"Visit the notifications page\">\n <appshell-icon [icon]=\"notificationsLink()!.icon!\" aria-label=\"Notifications icon\" />\n @if (notificationsCount() > 0) {\n <div class=\"notification-count\" aria-label=\"Number of notifications\">\n {{notificationsCount() > 9 ? '9+' : notificationsCount()}}\n </div>\n }\n </a>\n }\n <div class=\"separator\"></div>\n <div class=\"user-ctn\">\n @if (loggedUser() !== null) {\n <button [matMenuTriggerFor]=\"logoutMenu\">\n @if (loggedUser()!.avatarSrc) {\n <div class=\"header-profile-picture\" [style.backgroundImage]=\"'url('+loggedUser()!.avatarSrc+')'\"></div>\n } @else {\n <appshell-icon [icon]=\"'person'\" aria-label=\"Guest user icon\" />\n }\n <div class=\"user-text\">{{loggedUser()?.fullName}}</div>\n </button>\n <mat-menu #logoutMenu=\"matMenu\" xPosition=\"before\" class=\"appshell-logout-panel\">\n <button mat-menu-item (click)=\"userLoggedOut.emit()\" (keypress)=\"userLoggedOut.emit()\" aria-label=\"Logout\">Log Out</button>\n </mat-menu>\n } @else {\n <button (click)=\"userLoggedIn.emit()\" (keypress)=\"userLoggedIn.emit()\" aria-label=\"Login\">\n <appshell-icon [icon]=\"'person'\" aria-label=\"Guest user icon\" />\n <div class=\"user-text\">Login</div>\n </button>\n }\n </div>\n</nav>", styles: ["appshell-header{width:100%;--header-bg-color: var(--appshell-color-dark-green-main);--header-text-color: var(--text-color-on-main-color);--header-separator-color: var(--appshell-color-dark-green-light);--header-link-color: var(--appshell-color-dark-green-light);--header-link-hover-color: #ffffff;--header-link-selected-color: var(--appshell-color-accent-green-main);--header-border-bottom-color: var(--appshell-color-dark-green-main);--header-app-name-color: var(--appshell-color-grey-medium)}appshell-header.theme-white{--header-bg-color: #ffffff;--header-text-color: var(--appshell-color-dark-green-main);--header-separator-color: var(--appshell-color-grey-strong);--header-link-color: var(--appshell-color-grey-strong);--header-link-hover-color: var(--appshell-color-dark-green-main);--header-link-selected-color: var(--appshell-color-dark-green-main);--header-border-bottom-color: var(--appshell-color-grey-warm);--header-app-name-color: var(--appshell-color-dark-green-main)}appshell-header.theme-purple{--header-bg-color: var(--appshell-color-violet-dark);--header-text-color: #ffffff;--header-separator-color: var(--appshell-color-violet-light);--header-link-color: var(--appshell-color-violet-light);--header-link-hover-color: #ffffff;--header-link-selected-color: #ffffff;--header-border-bottom-color: var(--appshell-color-violet-dark);--header-app-name-color: var(--appshell-color-grey-medium)}appshell-header.theme-blue{--header-bg-color: var(--appshell-color-sky-blue-dark);--header-text-color: #ffffff;--header-separator-color: var(--appshell-color-sky-blue-medium);--header-link-color: var(--appshell-color-sky-blue-medium);--header-link-hover-color: #ffffff;--header-link-selected-color: #ffffff;--header-border-bottom-color: var(--appshell-color-sky-blue-dark);--header-app-name-color: var(--appshell-color-grey-medium)}.appshell-meta-navigation{width:100%;display:flex;flex-direction:row;align-items:center;height:3rem;background-color:var(--header-bg-color);color:var(--header-text-color);padding:0;box-sizing:border-box;font-size:.875rem;line-height:1.25rem;font-weight:400;font-style:normal;border-bottom:1px solid var(--header-border-bottom-color)}.appshell-meta-navigation .app-id-ctn{margin-left:2rem;box-sizing:border-box;display:flex;align-items:center;text-decoration:none}.appshell-meta-navigation .app-id-ctn img{height:1.5rem;width:1.5rem;margin-right:.5rem}.appshell-meta-navigation .app-id-ctn h1{color:var(--header-app-name-color);font-weight:500;margin:auto 0;font-size:1rem}.appshell-meta-navigation a.app-id-ctn:hover h1{color:var(--header-link-hover-color)}.appshell-meta-navigation .header-link{color:var(--header-link-color);margin-left:2rem;text-decoration:none;font-size:1rem;font-style:normal;font-weight:500}.appshell-meta-navigation .header-link.last{margin-right:1.25rem}.appshell-meta-navigation .header-link:hover{color:var(--header-link-hover-color)}.appshell-meta-navigation .header-link.active{color:var(--header-link-selected-color);text-decoration:underline}.appshell-meta-navigation .separator{width:1px;height:70%;margin:auto 1rem;background-color:var(--header-separator-color)}.appshell-meta-navigation .header-picker{cursor:pointer;display:flex;flex-direction:row;align-items:center;background-color:transparent;border:none;color:var(--header-link-color);font-size:1rem;font-style:normal;font-weight:500;font-family:AppShellTextFont;line-height:1.5rem;gap:.25rem;padding:0 1rem;height:85%;margin:auto 1.5rem}.appshell-meta-navigation .header-picker appshell-icon,.appshell-meta-navigation .header-picker mat-icon{width:1rem;height:1rem;display:flex;justify-content:center;align-items:center}.appshell-meta-navigation .header-picker:hover{color:var(--header-link-hover-color)}.appshell-meta-navigation .header-icon{border-radius:50%;display:flex;height:3rem;width:3rem;justify-content:center;align-items:center;color:var(--header-link-color);position:relative}.appshell-meta-navigation .header-icon:hover{color:var(--header-link-hover-color)}.appshell-meta-navigation .header-icon .notification-count{height:1.25rem;width:1.25rem;border-radius:50%;background-color:#e10a0a;color:#fff;font-family:AppShellTextFont;font-size:.75rem;font-style:normal;font-weight:400;line-height:1.5rem;text-decoration:none;display:flex;align-items:center;justify-content:center;position:absolute;top:.25rem;right:.25rem}.appshell-meta-navigation .user-ctn{padding-left:.5rem;padding-right:1.25rem;display:flex;flex-direction:row;align-items:center;height:100%}.appshell-meta-navigation .user-ctn button{cursor:pointer;display:flex;flex-direction:row;align-items:center;background-color:transparent;border:none;width:100%;gap:.5rem;color:var(--header-link-color)}.appshell-meta-navigation .user-ctn button:hover{color:var(--header-link-hover-color)}.appshell-meta-navigation .user-ctn button .header-profile-picture{width:1.5rem;height:1.5rem;border-radius:50%;background-size:cover;background-position:center;border:1px solid var(--appshell-color-grey-warm);aspect-ratio:1}.appshell-meta-navigation .user-ctn button .user-text{white-space:nowrap;overflow:hidden;text-overflow:ellipsis;font-size:.875rem;font-style:normal;font-weight:400;font-family:AppShellTextFont;width:10rem;line-height:1.25rem;text-align:start}.header-space{flex:1}.appshell-logout-panel,.appshell-picker-panel{border-radius:.125rem!important;border:1px solid var(--appshell-color-grey-main);box-shadow:none!important;width:13rem}.appshell-logout-panel>div,.appshell-picker-panel>div{padding:0}.appshell-logout-panel{margin-top:.7rem}.appshell-picker-panel{padding:.75rem 0;margin-top:.4rem}.appshell-picker-panel button.active{background-color:var(--appshell-color-grey-neutral);border-left:2px solid var(--appshell-color-accent-green-main)}.appshell-picker-panel button:focus-visible{outline:2px solid #0069E5;outline-offset:-.1rem}.appshell-picker-panel button:hover{background-color:var(--appshell-color-grey-light)}\n"], dependencies: [{ kind: "directive", type: AppShellLinkDirective, selector: "[appShellLink]", inputs: ["appShellLink"] }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i2.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: MatMenuModule }, { kind: "component", type: i3.MatMenu, selector: "mat-menu", inputs: ["backdropClass", "aria-label", "aria-labelledby", "aria-describedby", "xPosition", "yPosition", "overlapTrigger", "hasBackdrop", "class", "classList"], outputs: ["closed", "close"], exportAs: ["matMenu"] }, { kind: "component", type: i3.MatMenuItem, selector: "[mat-menu-item]", inputs: ["role", "disabled", "disableRipple"], exportAs: ["matMenuItem"] }, { kind: "directive", type: i3.MatMenuTrigger, selector: "[mat-menu-trigger-for], [matMenuTriggerFor]", inputs: ["mat-menu-trigger-for", "matMenuTriggerFor", "matMenuTriggerData", "matMenuTriggerRestoreFocus"], outputs: ["menuOpened", "onMenuOpen", "menuClosed", "onMenuClose"], exportAs: ["matMenuTrigger"] }, { kind: "component", type: AppShellIconComponent, selector: "appshell-icon", inputs: ["icon"] }], encapsulation: i0.ViewEncapsulation.None });
|
|
222
|
+
}
|
|
223
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.11", ngImport: i0, type: AppShellHeaderComponent, decorators: [{
|
|
224
|
+
type: Component,
|
|
225
|
+
args: [{ selector: 'appshell-header', imports: [AppShellLinkDirective, MatTooltipModule, CommonModule, MatMenuModule, AppShellIconComponent], encapsulation: ViewEncapsulation.None, template: "<nav class=\"appshell-meta-navigation\" aria-label=\"Top of the header navigation\">\n @if (applicationNameLink() && applicationNameLink() !== '') {\n <a class=\"app-id-ctn\" [href]=\"applicationNameLink()\">\n @if (symbol()) {\n <img src=\"assets/logo/{{symbol()}}\" alt=\"App symbol in the header\" />\n }\n <h1>{{applicationName()}}</h1>\n </a>\n } @else {\n <div class=\"app-id-ctn\">\n @if (symbol()) {\n <img src=\"assets/logo/{{symbol()}}\" alt=\"App symbol in the header\" />\n }\n <h1>{{applicationName()}}</h1>\n </div>\n }\n <div class=\"header-space\"></div>\n @for (link of links(); track link.label; let index = $index) {\n <a class=\"header-link\" [appShellLink]=\"link.anchor\" [class.active]=\"getCurrentUrlPath() === link.anchor\" target=\"{{link!.target || '_self'}}\" [class.last]=\"index+1 === links().length\">\n {{link.label}}\n </a>\n }\n @if (picker() && picker()?.label && picker()?.options && picker()?.options!.length > 0) {\n <button [matMenuTriggerFor]=\"pickerMenu\" #pickerTrigger=\"matMenuTrigger\" class=\"header-picker\">\n {{picker()!.label}}\n <appshell-icon [icon]=\"pickerTrigger.menuOpen ? 'expand_less' : 'expand_more'\" />\n </button>\n <mat-menu #pickerMenu=\"matMenu\" xPosition=\"after\" class=\"appshell-picker-panel\">\n @for (opt of picker()!.options; track opt; let index = $index) {\n <button mat-menu-item (click)=\"userPick.emit(opt)\" (keypress)=\"userPick.emit(opt)\" [class.active]=\"picker()?.selected === opt\" attr.aria-label=\"{{opt}}\">{{ opt }}</button>\n }\n </mat-menu>\n }\n @if (helpLink() && helpLink()?.icon) {\n <a class=\"header-icon\" [appShellLink]=\"helpLink()!.anchor\" target=\"{{helpLink()!.target || '_self'}}\" [matTooltip]=\"helpLink()!.label\" aria-label=\"Visit the help page\">\n <appshell-icon [icon]=\"helpLink()!.icon!\" aria-label=\"Help icon\" />\n </a>\n }\n @if (notificationsLink() && notificationsLink()?.icon) {\n <a class=\"header-icon\" [appShellLink]=\"notificationsLink()!.anchor\" target=\"{{notificationsLink()!.target || '_self'}}\" [matTooltip]=\"notificationsLink()!.label\" aria-label=\"Visit the notifications page\">\n <appshell-icon [icon]=\"notificationsLink()!.icon!\" aria-label=\"Notifications icon\" />\n @if (notificationsCount() > 0) {\n <div class=\"notification-count\" aria-label=\"Number of notifications\">\n {{notificationsCount() > 9 ? '9+' : notificationsCount()}}\n </div>\n }\n </a>\n }\n <div class=\"separator\"></div>\n <div class=\"user-ctn\">\n @if (loggedUser() !== null) {\n <button [matMenuTriggerFor]=\"logoutMenu\">\n @if (loggedUser()!.avatarSrc) {\n <div class=\"header-profile-picture\" [style.backgroundImage]=\"'url('+loggedUser()!.avatarSrc+')'\"></div>\n } @else {\n <appshell-icon [icon]=\"'person'\" aria-label=\"Guest user icon\" />\n }\n <div class=\"user-text\">{{loggedUser()?.fullName}}</div>\n </button>\n <mat-menu #logoutMenu=\"matMenu\" xPosition=\"before\" class=\"appshell-logout-panel\">\n <button mat-menu-item (click)=\"userLoggedOut.emit()\" (keypress)=\"userLoggedOut.emit()\" aria-label=\"Logout\">Log Out</button>\n </mat-menu>\n } @else {\n <button (click)=\"userLoggedIn.emit()\" (keypress)=\"userLoggedIn.emit()\" aria-label=\"Login\">\n <appshell-icon [icon]=\"'person'\" aria-label=\"Guest user icon\" />\n <div class=\"user-text\">Login</div>\n </button>\n }\n </div>\n</nav>", styles: ["appshell-header{width:100%;--header-bg-color: var(--appshell-color-dark-green-main);--header-text-color: var(--text-color-on-main-color);--header-separator-color: var(--appshell-color-dark-green-light);--header-link-color: var(--appshell-color-dark-green-light);--header-link-hover-color: #ffffff;--header-link-selected-color: var(--appshell-color-accent-green-main);--header-border-bottom-color: var(--appshell-color-dark-green-main);--header-app-name-color: var(--appshell-color-grey-medium)}appshell-header.theme-white{--header-bg-color: #ffffff;--header-text-color: var(--appshell-color-dark-green-main);--header-separator-color: var(--appshell-color-grey-strong);--header-link-color: var(--appshell-color-grey-strong);--header-link-hover-color: var(--appshell-color-dark-green-main);--header-link-selected-color: var(--appshell-color-dark-green-main);--header-border-bottom-color: var(--appshell-color-grey-warm);--header-app-name-color: var(--appshell-color-dark-green-main)}appshell-header.theme-purple{--header-bg-color: var(--appshell-color-violet-dark);--header-text-color: #ffffff;--header-separator-color: var(--appshell-color-violet-light);--header-link-color: var(--appshell-color-violet-light);--header-link-hover-color: #ffffff;--header-link-selected-color: #ffffff;--header-border-bottom-color: var(--appshell-color-violet-dark);--header-app-name-color: var(--appshell-color-grey-medium)}appshell-header.theme-blue{--header-bg-color: var(--appshell-color-sky-blue-dark);--header-text-color: #ffffff;--header-separator-color: var(--appshell-color-sky-blue-medium);--header-link-color: var(--appshell-color-sky-blue-medium);--header-link-hover-color: #ffffff;--header-link-selected-color: #ffffff;--header-border-bottom-color: var(--appshell-color-sky-blue-dark);--header-app-name-color: var(--appshell-color-grey-medium)}.appshell-meta-navigation{width:100%;display:flex;flex-direction:row;align-items:center;height:3rem;background-color:var(--header-bg-color);color:var(--header-text-color);padding:0;box-sizing:border-box;font-size:.875rem;line-height:1.25rem;font-weight:400;font-style:normal;border-bottom:1px solid var(--header-border-bottom-color)}.appshell-meta-navigation .app-id-ctn{margin-left:2rem;box-sizing:border-box;display:flex;align-items:center;text-decoration:none}.appshell-meta-navigation .app-id-ctn img{height:1.5rem;width:1.5rem;margin-right:.5rem}.appshell-meta-navigation .app-id-ctn h1{color:var(--header-app-name-color);font-weight:500;margin:auto 0;font-size:1rem}.appshell-meta-navigation a.app-id-ctn:hover h1{color:var(--header-link-hover-color)}.appshell-meta-navigation .header-link{color:var(--header-link-color);margin-left:2rem;text-decoration:none;font-size:1rem;font-style:normal;font-weight:500}.appshell-meta-navigation .header-link.last{margin-right:1.25rem}.appshell-meta-navigation .header-link:hover{color:var(--header-link-hover-color)}.appshell-meta-navigation .header-link.active{color:var(--header-link-selected-color);text-decoration:underline}.appshell-meta-navigation .separator{width:1px;height:70%;margin:auto 1rem;background-color:var(--header-separator-color)}.appshell-meta-navigation .header-picker{cursor:pointer;display:flex;flex-direction:row;align-items:center;background-color:transparent;border:none;color:var(--header-link-color);font-size:1rem;font-style:normal;font-weight:500;font-family:AppShellTextFont;line-height:1.5rem;gap:.25rem;padding:0 1rem;height:85%;margin:auto 1.5rem}.appshell-meta-navigation .header-picker appshell-icon,.appshell-meta-navigation .header-picker mat-icon{width:1rem;height:1rem;display:flex;justify-content:center;align-items:center}.appshell-meta-navigation .header-picker:hover{color:var(--header-link-hover-color)}.appshell-meta-navigation .header-icon{border-radius:50%;display:flex;height:3rem;width:3rem;justify-content:center;align-items:center;color:var(--header-link-color);position:relative}.appshell-meta-navigation .header-icon:hover{color:var(--header-link-hover-color)}.appshell-meta-navigation .header-icon .notification-count{height:1.25rem;width:1.25rem;border-radius:50%;background-color:#e10a0a;color:#fff;font-family:AppShellTextFont;font-size:.75rem;font-style:normal;font-weight:400;line-height:1.5rem;text-decoration:none;display:flex;align-items:center;justify-content:center;position:absolute;top:.25rem;right:.25rem}.appshell-meta-navigation .user-ctn{padding-left:.5rem;padding-right:1.25rem;display:flex;flex-direction:row;align-items:center;height:100%}.appshell-meta-navigation .user-ctn button{cursor:pointer;display:flex;flex-direction:row;align-items:center;background-color:transparent;border:none;width:100%;gap:.5rem;color:var(--header-link-color)}.appshell-meta-navigation .user-ctn button:hover{color:var(--header-link-hover-color)}.appshell-meta-navigation .user-ctn button .header-profile-picture{width:1.5rem;height:1.5rem;border-radius:50%;background-size:cover;background-position:center;border:1px solid var(--appshell-color-grey-warm);aspect-ratio:1}.appshell-meta-navigation .user-ctn button .user-text{white-space:nowrap;overflow:hidden;text-overflow:ellipsis;font-size:.875rem;font-style:normal;font-weight:400;font-family:AppShellTextFont;width:10rem;line-height:1.25rem;text-align:start}.header-space{flex:1}.appshell-logout-panel,.appshell-picker-panel{border-radius:.125rem!important;border:1px solid var(--appshell-color-grey-main);box-shadow:none!important;width:13rem}.appshell-logout-panel>div,.appshell-picker-panel>div{padding:0}.appshell-logout-panel{margin-top:.7rem}.appshell-picker-panel{padding:.75rem 0;margin-top:.4rem}.appshell-picker-panel button.active{background-color:var(--appshell-color-grey-neutral);border-left:2px solid var(--appshell-color-accent-green-main)}.appshell-picker-panel button:focus-visible{outline:2px solid #0069E5;outline-offset:-.1rem}.appshell-picker-panel button:hover{background-color:var(--appshell-color-grey-light)}\n"] }]
|
|
226
|
+
}], ctorParameters: () => [{ type: i1.Router }] });
|
|
227
|
+
|
|
228
|
+
class AppShellSidebarMenuComponent {
|
|
229
|
+
router;
|
|
230
|
+
sections = input.required();
|
|
231
|
+
links = input();
|
|
232
|
+
constructor(router) {
|
|
233
|
+
this.router = router;
|
|
234
|
+
}
|
|
235
|
+
getCurrentUrlPath() {
|
|
236
|
+
return this.router.url;
|
|
237
|
+
}
|
|
238
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.11", ngImport: i0, type: AppShellSidebarMenuComponent, deps: [{ token: i1.Router }], target: i0.ɵɵFactoryTarget.Component });
|
|
239
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.11", type: AppShellSidebarMenuComponent, isStandalone: true, selector: "appshell-sidebar-menu", inputs: { sections: { classPropertyName: "sections", publicName: "sections", isSignal: true, isRequired: true, transformFunction: null }, links: { classPropertyName: "links", publicName: "links", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "<div class=\"appshell-sidebar-menu-ctn\">\n @for (section of sections(); track $index) {\n <div class=\"link-group\">\n @if (section.label !== '') {\n <div class=\"menu-item link-group-header\">\n {{section.label}}\n </div>\n }\n <nav attr.aria-label=\"Sidebar menu for {{section.label}}\">\n @for (page of section.links; track $index) {\n <div class=\"menu-item link\" [class.active]=\"getCurrentUrlPath() === page.anchor\">\n <a [appShellLink]=\"page.anchor\" target=\"{{page.target || '_self'}}\">\n @if (page.icon) {\n <appshell-icon [icon]=\"page.icon\" aria-hidden=\"true\" />\n }\n {{page.label}}\n </a>\n </div>\n }\n </nav>\n </div>\n }\n @if (links() && links()!.links.length > 0) {\n <nav class=\"links\" aria-label=\"Links from sidebar menu\">\n <div class=\"links-separator\"></div>\n @if (links()!.label !== '') {\n <div class=\"links-header\">\n {{links()!.label}}\n </div>\n }\n @for (link of links()!.links; track $index) {\n <div class=\"menu-item link\">\n <a [appShellLink]=\"link.anchor\" target=\"{{link.target || '_self'}}\">\n @if (link.icon) {\n <appshell-icon [icon]=\"link.icon\" aria-hidden=\"true\" />\n }\n {{link.label}}\n </a>\n </div>\n }\n </nav>\n }\n</div>", styles: [".appshell-sidebar-menu-ctn{width:15rem;height:100%;background:var(--background-color);display:flex;box-sizing:border-box;padding:1.5rem 1rem;flex-direction:column;gap:.5rem;align-items:flex-start;color:var(--text-color-on-background)}.appshell-sidebar-menu-ctn .link-group{display:flex;flex-direction:column;align-items:flex-start;width:100%;gap:.5rem}.appshell-sidebar-menu-ctn .link-group nav{width:100%;display:flex;flex-direction:column;gap:.5rem}.appshell-sidebar-menu-ctn .link-group .appshell-sidebar-icon path{fill:var(--text-color-on-background)!important}.appshell-sidebar-menu-ctn .links{width:100%;display:flex;flex-direction:column;align-items:flex-start;gap:.5rem}.appshell-sidebar-menu-ctn .links .links-separator{height:.125rem;width:calc(100% - 2rem);margin:.5rem auto;background-color:var(--appshell-color-grey-medium)}.appshell-sidebar-menu-ctn .links .links-header{padding-left:1rem;font-size:.75rem;font-style:normal;font-weight:500;line-height:1.25rem}.appshell-sidebar-menu-ctn .menu-item{display:flex;flex-direction:row;box-sizing:border-box;align-items:center;gap:.75rem;align-self:stretch}.appshell-sidebar-menu-ctn .menu-item.link-group-header{font-size:1rem;line-height:1.25rem;height:2.25rem;padding:.5rem;font-family:AppShellHeadingFont;font-style:normal;font-weight:500}.appshell-sidebar-menu-ctn .link{font-weight:400;line-height:1.75rem}.appshell-sidebar-menu-ctn .link.active{border-radius:.125rem 0rem 0rem .125rem;background-color:var(--appshell-color-grey-neutral);border-left:2px solid var(--appshell-color-accent-green-main)}.appshell-sidebar-menu-ctn .link:hover{background-color:var(--appshell-color-grey-light)}.appshell-sidebar-menu-ctn .link span{display:flex;width:1.5rem;height:1.5rem;justify-content:center;align-items:center}.appshell-sidebar-menu-ctn .link a{text-decoration:none;color:var(--text-color-on-background);display:flex;flex-direction:row;align-items:center;gap:.5rem;width:100%;padding:.5rem 1rem}\n"], dependencies: [{ kind: "directive", type: AppShellLinkDirective, selector: "[appShellLink]", inputs: ["appShellLink"] }, { kind: "component", type: AppShellIconComponent, selector: "appshell-icon", inputs: ["icon"] }], encapsulation: i0.ViewEncapsulation.None });
|
|
240
|
+
}
|
|
241
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.11", ngImport: i0, type: AppShellSidebarMenuComponent, decorators: [{
|
|
242
|
+
type: Component,
|
|
243
|
+
args: [{ selector: 'appshell-sidebar-menu', imports: [AppShellLinkDirective, AppShellIconComponent], encapsulation: ViewEncapsulation.None, template: "<div class=\"appshell-sidebar-menu-ctn\">\n @for (section of sections(); track $index) {\n <div class=\"link-group\">\n @if (section.label !== '') {\n <div class=\"menu-item link-group-header\">\n {{section.label}}\n </div>\n }\n <nav attr.aria-label=\"Sidebar menu for {{section.label}}\">\n @for (page of section.links; track $index) {\n <div class=\"menu-item link\" [class.active]=\"getCurrentUrlPath() === page.anchor\">\n <a [appShellLink]=\"page.anchor\" target=\"{{page.target || '_self'}}\">\n @if (page.icon) {\n <appshell-icon [icon]=\"page.icon\" aria-hidden=\"true\" />\n }\n {{page.label}}\n </a>\n </div>\n }\n </nav>\n </div>\n }\n @if (links() && links()!.links.length > 0) {\n <nav class=\"links\" aria-label=\"Links from sidebar menu\">\n <div class=\"links-separator\"></div>\n @if (links()!.label !== '') {\n <div class=\"links-header\">\n {{links()!.label}}\n </div>\n }\n @for (link of links()!.links; track $index) {\n <div class=\"menu-item link\">\n <a [appShellLink]=\"link.anchor\" target=\"{{link.target || '_self'}}\">\n @if (link.icon) {\n <appshell-icon [icon]=\"link.icon\" aria-hidden=\"true\" />\n }\n {{link.label}}\n </a>\n </div>\n }\n </nav>\n }\n</div>", styles: [".appshell-sidebar-menu-ctn{width:15rem;height:100%;background:var(--background-color);display:flex;box-sizing:border-box;padding:1.5rem 1rem;flex-direction:column;gap:.5rem;align-items:flex-start;color:var(--text-color-on-background)}.appshell-sidebar-menu-ctn .link-group{display:flex;flex-direction:column;align-items:flex-start;width:100%;gap:.5rem}.appshell-sidebar-menu-ctn .link-group nav{width:100%;display:flex;flex-direction:column;gap:.5rem}.appshell-sidebar-menu-ctn .link-group .appshell-sidebar-icon path{fill:var(--text-color-on-background)!important}.appshell-sidebar-menu-ctn .links{width:100%;display:flex;flex-direction:column;align-items:flex-start;gap:.5rem}.appshell-sidebar-menu-ctn .links .links-separator{height:.125rem;width:calc(100% - 2rem);margin:.5rem auto;background-color:var(--appshell-color-grey-medium)}.appshell-sidebar-menu-ctn .links .links-header{padding-left:1rem;font-size:.75rem;font-style:normal;font-weight:500;line-height:1.25rem}.appshell-sidebar-menu-ctn .menu-item{display:flex;flex-direction:row;box-sizing:border-box;align-items:center;gap:.75rem;align-self:stretch}.appshell-sidebar-menu-ctn .menu-item.link-group-header{font-size:1rem;line-height:1.25rem;height:2.25rem;padding:.5rem;font-family:AppShellHeadingFont;font-style:normal;font-weight:500}.appshell-sidebar-menu-ctn .link{font-weight:400;line-height:1.75rem}.appshell-sidebar-menu-ctn .link.active{border-radius:.125rem 0rem 0rem .125rem;background-color:var(--appshell-color-grey-neutral);border-left:2px solid var(--appshell-color-accent-green-main)}.appshell-sidebar-menu-ctn .link:hover{background-color:var(--appshell-color-grey-light)}.appshell-sidebar-menu-ctn .link span{display:flex;width:1.5rem;height:1.5rem;justify-content:center;align-items:center}.appshell-sidebar-menu-ctn .link a{text-decoration:none;color:var(--text-color-on-background);display:flex;flex-direction:row;align-items:center;gap:.5rem;width:100%;padding:.5rem 1rem}\n"] }]
|
|
244
|
+
}], ctorParameters: () => [{ type: i1.Router }] });
|
|
245
|
+
|
|
246
|
+
class AppShellLayoutComponent {
|
|
247
|
+
headerVariant = input('');
|
|
248
|
+
applicationSymbol = input.required();
|
|
249
|
+
applicationName = input.required();
|
|
250
|
+
applicationNameLink = input();
|
|
251
|
+
appShellHelpLink = input();
|
|
252
|
+
appShellNotificationsLink = input();
|
|
253
|
+
appShellNotificationsCount = input(0);
|
|
254
|
+
headerLinks = input.required();
|
|
255
|
+
headerPicker = input();
|
|
256
|
+
sidenavSections = input.required();
|
|
257
|
+
sidenavLinks = input();
|
|
258
|
+
loggedUser = input.required();
|
|
259
|
+
userLoggedIn = output();
|
|
260
|
+
userLoggedOut = output();
|
|
261
|
+
userPick = output();
|
|
262
|
+
constructor() { }
|
|
263
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.11", ngImport: i0, type: AppShellLayoutComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
264
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.11", type: AppShellLayoutComponent, isStandalone: true, selector: "appshell-layout", inputs: { headerVariant: { classPropertyName: "headerVariant", publicName: "headerVariant", isSignal: true, isRequired: false, transformFunction: null }, applicationSymbol: { classPropertyName: "applicationSymbol", publicName: "applicationSymbol", isSignal: true, isRequired: true, transformFunction: null }, applicationName: { classPropertyName: "applicationName", publicName: "applicationName", isSignal: true, isRequired: true, transformFunction: null }, applicationNameLink: { classPropertyName: "applicationNameLink", publicName: "applicationNameLink", isSignal: true, isRequired: false, transformFunction: null }, appShellHelpLink: { classPropertyName: "appShellHelpLink", publicName: "appShellHelpLink", isSignal: true, isRequired: false, transformFunction: null }, appShellNotificationsLink: { classPropertyName: "appShellNotificationsLink", publicName: "appShellNotificationsLink", isSignal: true, isRequired: false, transformFunction: null }, appShellNotificationsCount: { classPropertyName: "appShellNotificationsCount", publicName: "appShellNotificationsCount", isSignal: true, isRequired: false, transformFunction: null }, headerLinks: { classPropertyName: "headerLinks", publicName: "headerLinks", isSignal: true, isRequired: true, transformFunction: null }, headerPicker: { classPropertyName: "headerPicker", publicName: "headerPicker", isSignal: true, isRequired: false, transformFunction: null }, sidenavSections: { classPropertyName: "sidenavSections", publicName: "sidenavSections", isSignal: true, isRequired: true, transformFunction: null }, sidenavLinks: { classPropertyName: "sidenavLinks", publicName: "sidenavLinks", isSignal: true, isRequired: false, transformFunction: null }, loggedUser: { classPropertyName: "loggedUser", publicName: "loggedUser", isSignal: true, isRequired: true, transformFunction: null } }, outputs: { userLoggedIn: "userLoggedIn", userLoggedOut: "userLoggedOut", userPick: "userPick" }, ngImport: i0, template: "<appshell-header\n [class]=\"headerVariant()\"\n [symbol]=\"applicationSymbol()\"\n [applicationName]=\"applicationName()\"\n [applicationNameLink]=\"applicationNameLink()\"\n [helpLink]=\"appShellHelpLink()\"\n [notificationsLink]=\"appShellNotificationsLink()\"\n [notificationsCount]=\"appShellNotificationsCount()\"\n [links]=\"headerLinks()\"\n [picker]=\"headerPicker()\"\n [loggedUser]=\"loggedUser()\"\n (userLoggedIn)=\"userLoggedIn.emit()\"\n (userLoggedOut)=\"userLoggedOut.emit()\"\n (userPick)=\"userPick.emit($event)\">\n</appshell-header>\n\n<section id=\"appshell-layout-content\">\n <mat-sidenav-container>\n @if (sidenavSections() && sidenavSections().length) {\n <mat-sidenav opened mode=\"side\" disableClose [fixedInViewport]=\"true\" [fixedTopGap]=\"48\">\n <appshell-sidebar-menu [sections]=\"sidenavSections()\" [links]=\"sidenavLinks()\"></appshell-sidebar-menu>\n </mat-sidenav>\n }\n <mat-sidenav-content>\n <main>\n <router-outlet></router-outlet>\n </main>\n </mat-sidenav-content>\n </mat-sidenav-container>\n</section>", styles: ["appshell-header{display:flex;position:fixed;z-index:99;width:100%}appshell-navigation{display:flex;flex-direction:row}#appshell-layout-content{flex-grow:1;display:flex;height:100%;padding-top:3rem}#appshell-layout-content mat-sidenav-container{width:100%}#appshell-layout-content appshell-sidebar-menu{display:flex;flex-direction:column;z-index:2}#appshell-layout-content mat-sidenav-content{box-sizing:border-box;background-color:var(--background-color)}#appshell-layout-content mat-sidenav-content main{display:flex;height:100%}\n"], dependencies: [{ kind: "component", type: AppShellSidebarMenuComponent, selector: "appshell-sidebar-menu", inputs: ["sections", "links"] }, { kind: "directive", type: RouterOutlet, selector: "router-outlet", inputs: ["name", "routerOutletData"], outputs: ["activate", "deactivate", "attach", "detach"], exportAs: ["outlet"] }, { kind: "ngmodule", type: MatSidenavModule }, { kind: "component", type: i1$5.MatSidenav, selector: "mat-sidenav", inputs: ["fixedInViewport", "fixedTopGap", "fixedBottomGap"], exportAs: ["matSidenav"] }, { kind: "component", type: i1$5.MatSidenavContainer, selector: "mat-sidenav-container", exportAs: ["matSidenavContainer"] }, { kind: "component", type: i1$5.MatSidenavContent, selector: "mat-sidenav-content" }, { kind: "component", type: AppShellHeaderComponent, selector: "appshell-header", inputs: ["applicationName", "symbol", "applicationNameLink", "helpLink", "notificationsLink", "notificationsCount", "links", "picker", "loggedUser"], outputs: ["userLoggedIn", "userLoggedOut", "userPick"] }] });
|
|
265
|
+
}
|
|
266
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.11", ngImport: i0, type: AppShellLayoutComponent, decorators: [{
|
|
267
|
+
type: Component,
|
|
268
|
+
args: [{ selector: 'appshell-layout', imports: [AppShellSidebarMenuComponent, RouterOutlet, MatSidenavModule, AppShellHeaderComponent], template: "<appshell-header\n [class]=\"headerVariant()\"\n [symbol]=\"applicationSymbol()\"\n [applicationName]=\"applicationName()\"\n [applicationNameLink]=\"applicationNameLink()\"\n [helpLink]=\"appShellHelpLink()\"\n [notificationsLink]=\"appShellNotificationsLink()\"\n [notificationsCount]=\"appShellNotificationsCount()\"\n [links]=\"headerLinks()\"\n [picker]=\"headerPicker()\"\n [loggedUser]=\"loggedUser()\"\n (userLoggedIn)=\"userLoggedIn.emit()\"\n (userLoggedOut)=\"userLoggedOut.emit()\"\n (userPick)=\"userPick.emit($event)\">\n</appshell-header>\n\n<section id=\"appshell-layout-content\">\n <mat-sidenav-container>\n @if (sidenavSections() && sidenavSections().length) {\n <mat-sidenav opened mode=\"side\" disableClose [fixedInViewport]=\"true\" [fixedTopGap]=\"48\">\n <appshell-sidebar-menu [sections]=\"sidenavSections()\" [links]=\"sidenavLinks()\"></appshell-sidebar-menu>\n </mat-sidenav>\n }\n <mat-sidenav-content>\n <main>\n <router-outlet></router-outlet>\n </main>\n </mat-sidenav-content>\n </mat-sidenav-container>\n</section>", styles: ["appshell-header{display:flex;position:fixed;z-index:99;width:100%}appshell-navigation{display:flex;flex-direction:row}#appshell-layout-content{flex-grow:1;display:flex;height:100%;padding-top:3rem}#appshell-layout-content mat-sidenav-container{width:100%}#appshell-layout-content appshell-sidebar-menu{display:flex;flex-direction:column;z-index:2}#appshell-layout-content mat-sidenav-content{box-sizing:border-box;background-color:var(--background-color)}#appshell-layout-content mat-sidenav-content main{display:flex;height:100%}\n"] }]
|
|
269
|
+
}], ctorParameters: () => [] });
|
|
270
|
+
|
|
271
|
+
class AppShellPlatformHeaderComponent {
|
|
272
|
+
router;
|
|
273
|
+
applicationName = input.required();
|
|
274
|
+
symbol = input();
|
|
275
|
+
logo = input();
|
|
276
|
+
applicationNameLink = input();
|
|
277
|
+
helpLink = input();
|
|
278
|
+
notificationsLink = input();
|
|
279
|
+
notificationsCount = input(0);
|
|
280
|
+
links = input.required();
|
|
281
|
+
projectPicker = input();
|
|
282
|
+
secondaryPicker = input();
|
|
283
|
+
loggedUser = input();
|
|
284
|
+
userLoggedIn = output();
|
|
285
|
+
userLoggedOut = output();
|
|
286
|
+
userProjectPick = output();
|
|
287
|
+
userProjectPickChoice = null;
|
|
288
|
+
userSecondaryPick = output();
|
|
289
|
+
userSecondaryPickChoice = null;
|
|
290
|
+
isPlatformPickerOpened = input(null);
|
|
291
|
+
platformPickerClick = output();
|
|
292
|
+
projectPickerSearch = '';
|
|
293
|
+
constructor(router) {
|
|
294
|
+
this.router = router;
|
|
295
|
+
effect(() => {
|
|
296
|
+
if (this.projectPicker()) {
|
|
297
|
+
this.userProjectPickChoice = this.projectPicker().selected ?? null;
|
|
298
|
+
}
|
|
299
|
+
});
|
|
300
|
+
effect(() => {
|
|
301
|
+
if (this.secondaryPicker()) {
|
|
302
|
+
this.userSecondaryPickChoice = this.secondaryPicker().selected ?? null;
|
|
303
|
+
}
|
|
304
|
+
});
|
|
305
|
+
}
|
|
306
|
+
getCurrentUrlPath() {
|
|
307
|
+
return this.router.url;
|
|
308
|
+
}
|
|
309
|
+
filteredProjectPickerOptions() {
|
|
310
|
+
const picker = this.projectPicker();
|
|
311
|
+
if (!picker?.options) {
|
|
312
|
+
return [];
|
|
313
|
+
}
|
|
314
|
+
if (!this.projectPickerSearch) {
|
|
315
|
+
return picker.options;
|
|
316
|
+
}
|
|
317
|
+
return picker.options.filter(opt => opt.toLowerCase().includes(this.projectPickerSearch.toLowerCase()));
|
|
318
|
+
}
|
|
319
|
+
pickProject(option) {
|
|
320
|
+
this.userProjectPickChoice = option;
|
|
321
|
+
this.userProjectPick.emit(option);
|
|
322
|
+
this.projectPickerSearch = '';
|
|
323
|
+
}
|
|
324
|
+
pickSecondChoice(option) {
|
|
325
|
+
this.userSecondaryPickChoice = option;
|
|
326
|
+
this.userSecondaryPick.emit(option);
|
|
327
|
+
}
|
|
328
|
+
openPlatformPicker() {
|
|
329
|
+
this.platformPickerClick.emit();
|
|
330
|
+
}
|
|
331
|
+
onSearchKeydown(event) {
|
|
332
|
+
// Prevent mat-menu's keyboard navigation from interfering
|
|
333
|
+
event.stopPropagation();
|
|
334
|
+
}
|
|
335
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.11", ngImport: i0, type: AppShellPlatformHeaderComponent, deps: [{ token: i1.Router }], target: i0.ɵɵFactoryTarget.Component });
|
|
336
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.11", type: AppShellPlatformHeaderComponent, isStandalone: true, selector: "appshell-platform-header", inputs: { applicationName: { classPropertyName: "applicationName", publicName: "applicationName", isSignal: true, isRequired: true, transformFunction: null }, symbol: { classPropertyName: "symbol", publicName: "symbol", isSignal: true, isRequired: false, transformFunction: null }, logo: { classPropertyName: "logo", publicName: "logo", isSignal: true, isRequired: false, transformFunction: null }, applicationNameLink: { classPropertyName: "applicationNameLink", publicName: "applicationNameLink", isSignal: true, isRequired: false, transformFunction: null }, helpLink: { classPropertyName: "helpLink", publicName: "helpLink", isSignal: true, isRequired: false, transformFunction: null }, notificationsLink: { classPropertyName: "notificationsLink", publicName: "notificationsLink", isSignal: true, isRequired: false, transformFunction: null }, notificationsCount: { classPropertyName: "notificationsCount", publicName: "notificationsCount", isSignal: true, isRequired: false, transformFunction: null }, links: { classPropertyName: "links", publicName: "links", isSignal: true, isRequired: true, transformFunction: null }, projectPicker: { classPropertyName: "projectPicker", publicName: "projectPicker", isSignal: true, isRequired: false, transformFunction: null }, secondaryPicker: { classPropertyName: "secondaryPicker", publicName: "secondaryPicker", isSignal: true, isRequired: false, transformFunction: null }, loggedUser: { classPropertyName: "loggedUser", publicName: "loggedUser", isSignal: true, isRequired: false, transformFunction: null }, isPlatformPickerOpened: { classPropertyName: "isPlatformPickerOpened", publicName: "isPlatformPickerOpened", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { userLoggedIn: "userLoggedIn", userLoggedOut: "userLoggedOut", userProjectPick: "userProjectPick", userSecondaryPick: "userSecondaryPick", platformPickerClick: "platformPickerClick" }, ngImport: i0, template: "<nav class=\"appshell-meta-navigation\" aria-label=\"Top of the header navigation\">\n @if(isPlatformPickerOpened() !== null) {\n <div class=\"platform-picker-trigger\" [class.opened-widget]=\"isPlatformPickerOpened()\" (click)=\"openPlatformPicker()\" (keypress)=\"openPlatformPicker()\">\n <svg width=\"24\" height=\"24\" viewBox=\"0 0 100 100\" xmlns=\"http://www.w3.org/2000/svg\"><rect x=\"10\" y=\"10\" width=\"20\" height=\"20\" fill=\"#FFFFFF\"/><rect x=\"40\" y=\"10\" width=\"20\" height=\"20\" fill=\"#FFFFFF\"/><rect x=\"70\" y=\"10\" width=\"20\" height=\"20\" fill=\"#FFFFFF\"/><rect x=\"10\" y=\"40\" width=\"20\" height=\"20\" fill=\"#FFFFFF\"/><rect x=\"40\" y=\"40\" width=\"20\" height=\"20\" fill=\"#FFFFFF\"/><rect x=\"70\" y=\"40\" width=\"20\" height=\"20\" fill=\"#FFFFFF\"/><rect x=\"10\" y=\"70\" width=\"20\" height=\"20\" fill=\"#FFFFFF\"/><rect x=\"40\" y=\"70\" width=\"20\" height=\"20\" fill=\"#FFFFFF\"/><rect x=\"70\" y=\"70\" width=\"20\" height=\"20\" fill=\"#FFFFFF\"/></svg>\n </div>\n }\n\n <div class=\"app-id-ctn\">\n @if (symbol()) {\n <img src=\"assets/logo/{{symbol()}}\" alt=\"App symbol in the header\" class=\"header-symbol\" />\n }\n @if (logo()) {\n <img src=\"assets/logo/{{logo()}}\" alt=\"App logo in the header\" class=\"header-logo\" />\n }\n <h1>{{applicationName()}}</h1>\n </div>\n @if (projectPicker() && projectPicker()?.label) {\n <div class=\"header-picker\">\n <button [matMenuTriggerFor]=\"projectPickerMenu\" #projectPickerTrigger=\"matMenuTrigger\" (menuOpened)=\"projectPickerSearchInput?.focus()\"\n [class.active]=\"projectPickerTrigger.menuOpen\">\n {{userProjectPickChoice && projectPicker()?.options && projectPicker()?.options!.length > 0 ? projectPicker()!.label + userProjectPickChoice : projectPicker()!.label}}\n <appshell-icon [icon]=\"projectPickerTrigger.menuOpen ? 'expand_less' : 'expand_more'\" />\n </button>\n </div>\n <mat-menu #projectPickerMenu=\"matMenu\" xPosition=\"after\" class=\"appshell-platform-header-picker-panel\">\n <div class=\"picker-search-ctn\" \n (click)=\"$event.stopPropagation()\" \n (mousedown)=\"$event.stopPropagation()\" \n [hidden]=\"!projectPicker()?.options || projectPicker()?.options!.length === 0\">\n <mat-form-field>\n @if (!projectPickerSearch) {\n <appshell-icon matPrefix class=\"prefix-icon\" aria-label=\"Search icon\" [icon]=\"'search'\" />\n }\n <input matInput type=\"text\" placeholder=\"Search for ...\" aria-label=\"Search options\"\n [(ngModel)]=\"projectPickerSearch\" (keydown)=\"onSearchKeydown($event)\"\n #projectPickerSearchInput />\n @if (projectPickerSearch) {\n <button matSuffix aria-label=\"Clear\" (click)=\"projectPickerSearch=''\">\n <appshell-icon [icon]=\"'close'\" aria-hidden=\"true\" />\n </button>\n }\n </mat-form-field>\n </div>\n <div class=\"picker-options-ctn\">\n @for (opt of filteredProjectPickerOptions(); track opt; let index = $index) {\n <button mat-menu-item (click)=\"pickProject(opt)\" (keypress)=\"pickProject(opt)\" [class.active]=\"projectPicker()?.selected === opt\" attr.aria-label=\"{{opt}}\">{{ opt }}</button>\n }\n @if (!projectPicker()?.options || projectPicker()?.options!.length === 0) {\n <div class=\"no-options-text\">\n @if(projectPicker()?.noOptionsTitle) {\n <b>{{ projectPicker()?.noOptionsTitle }}</b>\n }\n @if(projectPicker()?.noOptionsMessage) {\n <div [innerHTML]=\"projectPicker()?.noOptionsMessage\"></div>\n }\n </div>\n } @else if (filteredProjectPickerOptions().length === 0) {\n <div class=\"no-options-text\">\n @if(projectPicker()?.noFilteredOptionsTitle) {\n <b>{{ projectPicker()?.noFilteredOptionsTitle }}</b>\n }\n @if(projectPicker()?.noFilteredOptionsMessage) {\n <div [innerHTML]=\"projectPicker()?.noFilteredOptionsMessage\"></div>\n }\n </div>\n <button class=\"clear-search-btn\" mat-button (click)=\"projectPickerSearch=''; $event.stopPropagation()\" aria-label=\"Clear search\">Clear search</button>\n }\n </div>\n </mat-menu>\n }\n @if (secondaryPicker() && secondaryPicker()?.label && secondaryPicker()?.options && secondaryPicker()?.options!.length > 0) {\n <div class=\"header-picker\">\n <button [matMenuTriggerFor]=\"pickerMenu\" #pickerTrigger=\"matMenuTrigger\"\n [class.active]=\"pickerTrigger.menuOpen\">\n {{userSecondaryPickChoice ? secondaryPicker()!.label + userSecondaryPickChoice : secondaryPicker()!.label}}\n <appshell-icon [icon]=\"pickerTrigger.menuOpen ? 'expand_less' : 'expand_more'\" />\n </button>\n </div>\n <mat-menu #pickerMenu=\"matMenu\" xPosition=\"after\" class=\"appshell-platform-header-picker-panel\">\n @for (opt of secondaryPicker()!.options; track opt; let index = $index) {\n <button mat-menu-item (click)=\"pickSecondChoice(opt)\" (keypress)=\"pickSecondChoice(opt)\" [class.active]=\"secondaryPicker()?.selected === opt\" attr.aria-label=\"{{opt}}\">{{ opt }}</button>\n }\n </mat-menu>\n }\n <div class=\"header-space\"></div>\n @for (link of links(); track link.label; let index = $index) {\n <a class=\"header-link\" [appShellLink]=\"link.anchor\" [class.active]=\"getCurrentUrlPath() === link.anchor\" target=\"{{link!.target || '_self'}}\" [class.last]=\"index+1 === links().length\">\n {{link.label}}\n </a>\n }\n @if (helpLink() && helpLink()?.icon) {\n <a class=\"header-icon\" [appShellLink]=\"helpLink()!.anchor\" target=\"{{helpLink()!.target || '_self'}}\" [matTooltip]=\"helpLink()!.label\" aria-label=\"Visit the help page\">\n <appshell-icon [icon]=\"helpLink()!.icon!\" aria-label=\"Help icon\" />\n </a>\n }\n @if (notificationsLink() && notificationsLink()?.icon) {\n <a class=\"header-icon\" [appShellLink]=\"notificationsLink()!.anchor\" target=\"{{notificationsLink()!.target || '_self'}}\" [matTooltip]=\"notificationsLink()!.label\" aria-label=\"Visit the notifications page\">\n <appshell-icon [icon]=\"notificationsLink()!.icon!\" aria-label=\"Notifications icon\" />\n @if (notificationsCount() > 0) {\n <div class=\"notification-count\" aria-label=\"Number of notifications\">\n {{notificationsCount() > 9 ? '9+' : notificationsCount()}}\n </div>\n }\n </a>\n }\n <div class=\"separator\"></div>\n <div class=\"user-ctn\">\n @if (loggedUser() !== null) {\n <button [matMenuTriggerFor]=\"logoutMenu\">\n @if (loggedUser()!.avatarSrc) {\n <div class=\"header-profile-picture\" [style.backgroundImage]=\"'url('+loggedUser()!.avatarSrc+')'\"></div>\n } @else {\n <appshell-icon [icon]=\"'person'\" aria-label=\"Guest user icon\" />\n }\n <div class=\"user-text\">{{loggedUser()?.fullName}}</div>\n </button>\n <mat-menu #logoutMenu=\"matMenu\" xPosition=\"before\" class=\"appshell-logout-panel\">\n <button mat-menu-item (click)=\"userLoggedOut.emit()\" (keypress)=\"userLoggedOut.emit()\" aria-label=\"Logout\">Log Out</button>\n </mat-menu>\n } @else {\n <button (click)=\"userLoggedIn.emit()\" (keypress)=\"userLoggedIn.emit()\" aria-label=\"Login\">\n <appshell-icon [icon]=\"'person'\" aria-label=\"Guest user icon\" />\n <div class=\"user-text\">Login</div>\n </button>\n }\n </div>\n</nav>", styles: ["appshell-platform-header{width:100%;--header-bg-color: var(--appshell-color-dark-green-main);--header-text-color: var(--text-color-on-main-color);--header-separator-color: var(--appshell-color-dark-green-light);--header-link-color: var(--appshell-color-dark-green-light);--header-link-hover-color: #ffffff;--header-link-selected-color: var(--appshell-color-accent-green-main);--header-border-bottom-color: var(--appshell-color-dark-green-main);--header-app-name-color: var(--appshell-color-grey-medium)}appshell-platform-header.theme-white{--header-bg-color: #ffffff;--header-text-color: var(--appshell-color-dark-green-main);--header-separator-color: var(--appshell-color-grey-strong);--header-link-color: var(--appshell-color-grey-strong);--header-link-hover-color: var(--appshell-color-dark-green-main);--header-link-selected-color: var(--appshell-color-dark-green-main);--header-border-bottom-color: var(--appshell-color-grey-warm);--header-app-name-color: var(--appshell-color-dark-green-main)}appshell-platform-header.theme-purple{--header-bg-color: var(--appshell-color-violet-dark);--header-text-color: #ffffff;--header-separator-color: var(--appshell-color-violet-light);--header-link-color: var(--appshell-color-violet-light);--header-link-hover-color: #ffffff;--header-link-selected-color: #ffffff;--header-border-bottom-color: var(--appshell-color-violet-dark);--header-app-name-color: var(--appshell-color-grey-medium)}appshell-platform-header.theme-blue{--header-bg-color: var(--appshell-color-sky-blue-dark);--header-text-color: #ffffff;--header-separator-color: var(--appshell-color-sky-blue-medium);--header-link-color: var(--appshell-color-sky-blue-medium);--header-link-hover-color: #ffffff;--header-link-selected-color: #ffffff;--header-border-bottom-color: var(--appshell-color-sky-blue-dark);--header-app-name-color: var(--appshell-color-grey-medium)}.appshell-meta-navigation{width:100%;display:flex;flex-direction:row;align-items:center;height:4rem;background-color:var(--header-bg-color);color:var(--header-text-color);padding:0;box-sizing:border-box;font-size:.875rem;line-height:1.25rem;font-weight:400;font-style:normal;border-bottom:1px solid var(--header-border-bottom-color)}.appshell-meta-navigation .platform-picker-trigger{height:4rem;width:4rem;display:flex;justify-content:center;align-items:center;cursor:pointer}.appshell-meta-navigation .platform-picker-trigger:hover,.appshell-meta-navigation .platform-picker-trigger.opened-widget{background-color:var(--appshell-color-dark-green-dark)}.appshell-meta-navigation .app-id-ctn{margin-left:2.25rem;margin-right:4rem;box-sizing:border-box;display:flex;align-items:center;text-decoration:none}.appshell-meta-navigation .app-id-ctn img{margin-right:.5rem}.appshell-meta-navigation .app-id-ctn img.header-symbol{height:1.5rem;width:1.5rem}.appshell-meta-navigation .app-id-ctn img.header-logo{height:2rem;width:auto;max-width:6rem;margin-right:4rem}.appshell-meta-navigation .app-id-ctn h1{color:var(--header-app-name-color);font-weight:500;margin:auto 0;font-size:1rem}.appshell-meta-navigation .header-link{color:var(--header-link-color);margin-left:2rem;text-decoration:none;font-size:1rem;font-style:normal;font-weight:500}.appshell-meta-navigation .header-link.last{margin-right:1.25rem}.appshell-meta-navigation .header-link:hover{color:var(--header-link-hover-color)}.appshell-meta-navigation .header-link.active{color:var(--header-link-selected-color);text-decoration:underline}.appshell-meta-navigation .separator{width:1px;height:2rem;margin:auto 1rem;background-color:var(--header-separator-color)}.appshell-meta-navigation .header-picker{min-width:13rem;margin-right:1.5rem}.appshell-meta-navigation .header-picker button{cursor:pointer;display:flex;flex-direction:row;align-items:center;background-color:transparent;border:none;color:var(--header-link-color);font-size:1rem;font-style:normal;font-weight:400;font-family:AppShellTextFont;line-height:1.5rem;text-align:start;gap:.25rem;padding:.5rem;height:85%;border:1px solid transparent}.appshell-meta-navigation .header-picker button appshell-icon,.appshell-meta-navigation .header-picker button mat-icon{width:1rem;height:1rem;display:flex;justify-content:center;align-items:center}.appshell-meta-navigation .header-picker button:hover{color:var(--header-link-hover-color)}.appshell-meta-navigation .header-picker button.active{color:var(--header-link-selected-color);border-bottom:1px solid var(--header-link-selected-color)}.appshell-meta-navigation .header-icon{border-radius:50%;display:flex;height:4rem;width:4rem;justify-content:center;align-items:center;color:var(--header-link-color);position:relative}.appshell-meta-navigation .header-icon:hover{color:var(--header-link-hover-color)}.appshell-meta-navigation .header-icon .notification-count{height:1.25rem;width:1.25rem;border-radius:50%;background-color:#e10a0a;color:#fff;font-family:AppShellTextFont;font-size:.75rem;font-style:normal;font-weight:400;line-height:1.5rem;text-decoration:none;display:flex;align-items:center;justify-content:center;position:absolute;top:.75rem;right:.75rem}.appshell-meta-navigation .user-ctn{padding-left:.5rem;padding-right:1.25rem;display:flex;flex-direction:row;align-items:center;height:100%}.appshell-meta-navigation .user-ctn button{cursor:pointer;display:flex;flex-direction:row;align-items:center;background-color:transparent;border:none;width:100%;gap:.5rem;color:var(--header-link-color)}.appshell-meta-navigation .user-ctn button:hover{color:var(--header-link-hover-color)}.appshell-meta-navigation .user-ctn button .header-profile-picture{width:1.5rem;height:1.5rem;border-radius:50%;background-size:cover;background-position:center;border:1px solid var(--appshell-color-grey-warm);aspect-ratio:1}.appshell-meta-navigation .user-ctn button .user-text{white-space:nowrap;overflow:hidden;text-overflow:ellipsis;font-size:.875rem;font-style:normal;font-weight:400;font-family:AppShellTextFont;width:10rem;line-height:1.25rem;text-align:start}.header-space{flex:1}.appshell-logout-panel,.appshell-platform-header-picker-panel{border-radius:.125rem!important;border:1px solid var(--appshell-color-grey-main);box-shadow:none!important;width:13rem}.appshell-logout-panel>div,.appshell-platform-header-picker-panel>div{padding:0}.appshell-logout-panel{margin-top:1.1rem}.appshell-platform-header-picker-panel{padding:.75rem 0;margin-top:.9rem;--mat-menu-item-label-text-color: var(--appshell-color-dark-green-main)}.appshell-platform-header-picker-panel .picker-search-ctn{height:3.75rem;width:100%;border-bottom:1px solid var(--appshell-color-grey-strong)}.appshell-platform-header-picker-panel .picker-search-ctn mat-form-field{width:86%;margin:0 7%;--mdc-filled-text-field-container-color: var(--appshell-color-grey-light);--mat-form-field-state-layer-color: transparent;--mdc-filled-text-field-active-indicator-color: var(--appshell-color-grey-main);--mdc-filled-text-field-hover-active-indicator-color: var(--appshell-color-grey-strong);--mdc-filled-text-field-focus-active-indicator-color: var(--appshell-color-accent-green-main);--mat-form-field-container-vertical-padding: .75rem;--mat-form-field-container-height: 2.75rem}.appshell-platform-header-picker-panel .picker-search-ctn mat-form-field .prefix-icon{margin:0 .5rem}.appshell-platform-header-picker-panel .picker-search-ctn mat-form-field button{background:transparent;border:none;cursor:pointer}.appshell-platform-header-picker-panel .picker-options-ctn{max-height:18rem;overflow-y:auto;color:var(--mat-menu-item-label-text-color)}.appshell-platform-header-picker-panel .picker-options-ctn .no-options-text{padding:1rem;font-family:AppShellTextFont;font-size:.875rem;font-style:normal;font-weight:400;line-height:1.25rem;text-align:center}.appshell-platform-header-picker-panel .picker-options-ctn .no-options-text b{display:block}.appshell-platform-header-picker-panel .picker-options-ctn .no-options-text a{color:#00e}.appshell-platform-header-picker-panel .picker-options-ctn .clear-search-btn{padding:.75rem;height:3rem;width:100%;background:none;border:none;text-decoration:underline;text-underline-offset:.4rem;text-decoration-color:var(--appshell-color-accent-green-main);color:var(--appshell-color-dark-green-main);font-family:AppShellTextFont;font-size:.875rem;font-style:normal;font-weight:500;line-height:1.25rem;text-decoration-thickness:2px;cursor:pointer}.appshell-platform-header-picker-panel button.active{background-color:var(--appshell-color-grey-neutral);border-left:2px solid var(--appshell-color-accent-green-main)}.appshell-platform-header-picker-panel button:focus-visible{outline:2px solid #0069E5;outline-offset:-.1rem}.appshell-platform-header-picker-panel button:hover{background-color:var(--appshell-color-grey-light)}\n"], dependencies: [{ kind: "directive", type: AppShellLinkDirective, selector: "[appShellLink]", inputs: ["appShellLink"] }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i2.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: MatMenuModule }, { kind: "component", type: i3.MatMenu, selector: "mat-menu", inputs: ["backdropClass", "aria-label", "aria-labelledby", "aria-describedby", "xPosition", "yPosition", "overlapTrigger", "hasBackdrop", "class", "classList"], outputs: ["closed", "close"], exportAs: ["matMenu"] }, { kind: "component", type: i3.MatMenuItem, selector: "[mat-menu-item]", inputs: ["role", "disabled", "disableRipple"], exportAs: ["matMenuItem"] }, { kind: "directive", type: i3.MatMenuTrigger, selector: "[mat-menu-trigger-for], [matMenuTriggerFor]", inputs: ["mat-menu-trigger-for", "matMenuTriggerFor", "matMenuTriggerData", "matMenuTriggerRestoreFocus"], outputs: ["menuOpened", "onMenuOpen", "menuClosed", "onMenuClose"], exportAs: ["matMenuTrigger"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i4.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i4.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i4.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: MatFormFieldModule }, { kind: "component", type: i1$4.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i1$4.MatPrefix, selector: "[matPrefix], [matIconPrefix], [matTextPrefix]", inputs: ["matTextPrefix"] }, { kind: "directive", type: i1$4.MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i6.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly", "disabledInteractive"], exportAs: ["matInput"] }, { kind: "component", type: AppShellIconComponent, selector: "appshell-icon", inputs: ["icon"] }], encapsulation: i0.ViewEncapsulation.None });
|
|
337
|
+
}
|
|
338
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.11", ngImport: i0, type: AppShellPlatformHeaderComponent, decorators: [{
|
|
339
|
+
type: Component,
|
|
340
|
+
args: [{ selector: 'appshell-platform-header', imports: [AppShellLinkDirective, MatTooltipModule, CommonModule, MatMenuModule, FormsModule, MatFormFieldModule, MatInputModule, AppShellIconComponent], encapsulation: ViewEncapsulation.None, template: "<nav class=\"appshell-meta-navigation\" aria-label=\"Top of the header navigation\">\n @if(isPlatformPickerOpened() !== null) {\n <div class=\"platform-picker-trigger\" [class.opened-widget]=\"isPlatformPickerOpened()\" (click)=\"openPlatformPicker()\" (keypress)=\"openPlatformPicker()\">\n <svg width=\"24\" height=\"24\" viewBox=\"0 0 100 100\" xmlns=\"http://www.w3.org/2000/svg\"><rect x=\"10\" y=\"10\" width=\"20\" height=\"20\" fill=\"#FFFFFF\"/><rect x=\"40\" y=\"10\" width=\"20\" height=\"20\" fill=\"#FFFFFF\"/><rect x=\"70\" y=\"10\" width=\"20\" height=\"20\" fill=\"#FFFFFF\"/><rect x=\"10\" y=\"40\" width=\"20\" height=\"20\" fill=\"#FFFFFF\"/><rect x=\"40\" y=\"40\" width=\"20\" height=\"20\" fill=\"#FFFFFF\"/><rect x=\"70\" y=\"40\" width=\"20\" height=\"20\" fill=\"#FFFFFF\"/><rect x=\"10\" y=\"70\" width=\"20\" height=\"20\" fill=\"#FFFFFF\"/><rect x=\"40\" y=\"70\" width=\"20\" height=\"20\" fill=\"#FFFFFF\"/><rect x=\"70\" y=\"70\" width=\"20\" height=\"20\" fill=\"#FFFFFF\"/></svg>\n </div>\n }\n\n <div class=\"app-id-ctn\">\n @if (symbol()) {\n <img src=\"assets/logo/{{symbol()}}\" alt=\"App symbol in the header\" class=\"header-symbol\" />\n }\n @if (logo()) {\n <img src=\"assets/logo/{{logo()}}\" alt=\"App logo in the header\" class=\"header-logo\" />\n }\n <h1>{{applicationName()}}</h1>\n </div>\n @if (projectPicker() && projectPicker()?.label) {\n <div class=\"header-picker\">\n <button [matMenuTriggerFor]=\"projectPickerMenu\" #projectPickerTrigger=\"matMenuTrigger\" (menuOpened)=\"projectPickerSearchInput?.focus()\"\n [class.active]=\"projectPickerTrigger.menuOpen\">\n {{userProjectPickChoice && projectPicker()?.options && projectPicker()?.options!.length > 0 ? projectPicker()!.label + userProjectPickChoice : projectPicker()!.label}}\n <appshell-icon [icon]=\"projectPickerTrigger.menuOpen ? 'expand_less' : 'expand_more'\" />\n </button>\n </div>\n <mat-menu #projectPickerMenu=\"matMenu\" xPosition=\"after\" class=\"appshell-platform-header-picker-panel\">\n <div class=\"picker-search-ctn\" \n (click)=\"$event.stopPropagation()\" \n (mousedown)=\"$event.stopPropagation()\" \n [hidden]=\"!projectPicker()?.options || projectPicker()?.options!.length === 0\">\n <mat-form-field>\n @if (!projectPickerSearch) {\n <appshell-icon matPrefix class=\"prefix-icon\" aria-label=\"Search icon\" [icon]=\"'search'\" />\n }\n <input matInput type=\"text\" placeholder=\"Search for ...\" aria-label=\"Search options\"\n [(ngModel)]=\"projectPickerSearch\" (keydown)=\"onSearchKeydown($event)\"\n #projectPickerSearchInput />\n @if (projectPickerSearch) {\n <button matSuffix aria-label=\"Clear\" (click)=\"projectPickerSearch=''\">\n <appshell-icon [icon]=\"'close'\" aria-hidden=\"true\" />\n </button>\n }\n </mat-form-field>\n </div>\n <div class=\"picker-options-ctn\">\n @for (opt of filteredProjectPickerOptions(); track opt; let index = $index) {\n <button mat-menu-item (click)=\"pickProject(opt)\" (keypress)=\"pickProject(opt)\" [class.active]=\"projectPicker()?.selected === opt\" attr.aria-label=\"{{opt}}\">{{ opt }}</button>\n }\n @if (!projectPicker()?.options || projectPicker()?.options!.length === 0) {\n <div class=\"no-options-text\">\n @if(projectPicker()?.noOptionsTitle) {\n <b>{{ projectPicker()?.noOptionsTitle }}</b>\n }\n @if(projectPicker()?.noOptionsMessage) {\n <div [innerHTML]=\"projectPicker()?.noOptionsMessage\"></div>\n }\n </div>\n } @else if (filteredProjectPickerOptions().length === 0) {\n <div class=\"no-options-text\">\n @if(projectPicker()?.noFilteredOptionsTitle) {\n <b>{{ projectPicker()?.noFilteredOptionsTitle }}</b>\n }\n @if(projectPicker()?.noFilteredOptionsMessage) {\n <div [innerHTML]=\"projectPicker()?.noFilteredOptionsMessage\"></div>\n }\n </div>\n <button class=\"clear-search-btn\" mat-button (click)=\"projectPickerSearch=''; $event.stopPropagation()\" aria-label=\"Clear search\">Clear search</button>\n }\n </div>\n </mat-menu>\n }\n @if (secondaryPicker() && secondaryPicker()?.label && secondaryPicker()?.options && secondaryPicker()?.options!.length > 0) {\n <div class=\"header-picker\">\n <button [matMenuTriggerFor]=\"pickerMenu\" #pickerTrigger=\"matMenuTrigger\"\n [class.active]=\"pickerTrigger.menuOpen\">\n {{userSecondaryPickChoice ? secondaryPicker()!.label + userSecondaryPickChoice : secondaryPicker()!.label}}\n <appshell-icon [icon]=\"pickerTrigger.menuOpen ? 'expand_less' : 'expand_more'\" />\n </button>\n </div>\n <mat-menu #pickerMenu=\"matMenu\" xPosition=\"after\" class=\"appshell-platform-header-picker-panel\">\n @for (opt of secondaryPicker()!.options; track opt; let index = $index) {\n <button mat-menu-item (click)=\"pickSecondChoice(opt)\" (keypress)=\"pickSecondChoice(opt)\" [class.active]=\"secondaryPicker()?.selected === opt\" attr.aria-label=\"{{opt}}\">{{ opt }}</button>\n }\n </mat-menu>\n }\n <div class=\"header-space\"></div>\n @for (link of links(); track link.label; let index = $index) {\n <a class=\"header-link\" [appShellLink]=\"link.anchor\" [class.active]=\"getCurrentUrlPath() === link.anchor\" target=\"{{link!.target || '_self'}}\" [class.last]=\"index+1 === links().length\">\n {{link.label}}\n </a>\n }\n @if (helpLink() && helpLink()?.icon) {\n <a class=\"header-icon\" [appShellLink]=\"helpLink()!.anchor\" target=\"{{helpLink()!.target || '_self'}}\" [matTooltip]=\"helpLink()!.label\" aria-label=\"Visit the help page\">\n <appshell-icon [icon]=\"helpLink()!.icon!\" aria-label=\"Help icon\" />\n </a>\n }\n @if (notificationsLink() && notificationsLink()?.icon) {\n <a class=\"header-icon\" [appShellLink]=\"notificationsLink()!.anchor\" target=\"{{notificationsLink()!.target || '_self'}}\" [matTooltip]=\"notificationsLink()!.label\" aria-label=\"Visit the notifications page\">\n <appshell-icon [icon]=\"notificationsLink()!.icon!\" aria-label=\"Notifications icon\" />\n @if (notificationsCount() > 0) {\n <div class=\"notification-count\" aria-label=\"Number of notifications\">\n {{notificationsCount() > 9 ? '9+' : notificationsCount()}}\n </div>\n }\n </a>\n }\n <div class=\"separator\"></div>\n <div class=\"user-ctn\">\n @if (loggedUser() !== null) {\n <button [matMenuTriggerFor]=\"logoutMenu\">\n @if (loggedUser()!.avatarSrc) {\n <div class=\"header-profile-picture\" [style.backgroundImage]=\"'url('+loggedUser()!.avatarSrc+')'\"></div>\n } @else {\n <appshell-icon [icon]=\"'person'\" aria-label=\"Guest user icon\" />\n }\n <div class=\"user-text\">{{loggedUser()?.fullName}}</div>\n </button>\n <mat-menu #logoutMenu=\"matMenu\" xPosition=\"before\" class=\"appshell-logout-panel\">\n <button mat-menu-item (click)=\"userLoggedOut.emit()\" (keypress)=\"userLoggedOut.emit()\" aria-label=\"Logout\">Log Out</button>\n </mat-menu>\n } @else {\n <button (click)=\"userLoggedIn.emit()\" (keypress)=\"userLoggedIn.emit()\" aria-label=\"Login\">\n <appshell-icon [icon]=\"'person'\" aria-label=\"Guest user icon\" />\n <div class=\"user-text\">Login</div>\n </button>\n }\n </div>\n</nav>", styles: ["appshell-platform-header{width:100%;--header-bg-color: var(--appshell-color-dark-green-main);--header-text-color: var(--text-color-on-main-color);--header-separator-color: var(--appshell-color-dark-green-light);--header-link-color: var(--appshell-color-dark-green-light);--header-link-hover-color: #ffffff;--header-link-selected-color: var(--appshell-color-accent-green-main);--header-border-bottom-color: var(--appshell-color-dark-green-main);--header-app-name-color: var(--appshell-color-grey-medium)}appshell-platform-header.theme-white{--header-bg-color: #ffffff;--header-text-color: var(--appshell-color-dark-green-main);--header-separator-color: var(--appshell-color-grey-strong);--header-link-color: var(--appshell-color-grey-strong);--header-link-hover-color: var(--appshell-color-dark-green-main);--header-link-selected-color: var(--appshell-color-dark-green-main);--header-border-bottom-color: var(--appshell-color-grey-warm);--header-app-name-color: var(--appshell-color-dark-green-main)}appshell-platform-header.theme-purple{--header-bg-color: var(--appshell-color-violet-dark);--header-text-color: #ffffff;--header-separator-color: var(--appshell-color-violet-light);--header-link-color: var(--appshell-color-violet-light);--header-link-hover-color: #ffffff;--header-link-selected-color: #ffffff;--header-border-bottom-color: var(--appshell-color-violet-dark);--header-app-name-color: var(--appshell-color-grey-medium)}appshell-platform-header.theme-blue{--header-bg-color: var(--appshell-color-sky-blue-dark);--header-text-color: #ffffff;--header-separator-color: var(--appshell-color-sky-blue-medium);--header-link-color: var(--appshell-color-sky-blue-medium);--header-link-hover-color: #ffffff;--header-link-selected-color: #ffffff;--header-border-bottom-color: var(--appshell-color-sky-blue-dark);--header-app-name-color: var(--appshell-color-grey-medium)}.appshell-meta-navigation{width:100%;display:flex;flex-direction:row;align-items:center;height:4rem;background-color:var(--header-bg-color);color:var(--header-text-color);padding:0;box-sizing:border-box;font-size:.875rem;line-height:1.25rem;font-weight:400;font-style:normal;border-bottom:1px solid var(--header-border-bottom-color)}.appshell-meta-navigation .platform-picker-trigger{height:4rem;width:4rem;display:flex;justify-content:center;align-items:center;cursor:pointer}.appshell-meta-navigation .platform-picker-trigger:hover,.appshell-meta-navigation .platform-picker-trigger.opened-widget{background-color:var(--appshell-color-dark-green-dark)}.appshell-meta-navigation .app-id-ctn{margin-left:2.25rem;margin-right:4rem;box-sizing:border-box;display:flex;align-items:center;text-decoration:none}.appshell-meta-navigation .app-id-ctn img{margin-right:.5rem}.appshell-meta-navigation .app-id-ctn img.header-symbol{height:1.5rem;width:1.5rem}.appshell-meta-navigation .app-id-ctn img.header-logo{height:2rem;width:auto;max-width:6rem;margin-right:4rem}.appshell-meta-navigation .app-id-ctn h1{color:var(--header-app-name-color);font-weight:500;margin:auto 0;font-size:1rem}.appshell-meta-navigation .header-link{color:var(--header-link-color);margin-left:2rem;text-decoration:none;font-size:1rem;font-style:normal;font-weight:500}.appshell-meta-navigation .header-link.last{margin-right:1.25rem}.appshell-meta-navigation .header-link:hover{color:var(--header-link-hover-color)}.appshell-meta-navigation .header-link.active{color:var(--header-link-selected-color);text-decoration:underline}.appshell-meta-navigation .separator{width:1px;height:2rem;margin:auto 1rem;background-color:var(--header-separator-color)}.appshell-meta-navigation .header-picker{min-width:13rem;margin-right:1.5rem}.appshell-meta-navigation .header-picker button{cursor:pointer;display:flex;flex-direction:row;align-items:center;background-color:transparent;border:none;color:var(--header-link-color);font-size:1rem;font-style:normal;font-weight:400;font-family:AppShellTextFont;line-height:1.5rem;text-align:start;gap:.25rem;padding:.5rem;height:85%;border:1px solid transparent}.appshell-meta-navigation .header-picker button appshell-icon,.appshell-meta-navigation .header-picker button mat-icon{width:1rem;height:1rem;display:flex;justify-content:center;align-items:center}.appshell-meta-navigation .header-picker button:hover{color:var(--header-link-hover-color)}.appshell-meta-navigation .header-picker button.active{color:var(--header-link-selected-color);border-bottom:1px solid var(--header-link-selected-color)}.appshell-meta-navigation .header-icon{border-radius:50%;display:flex;height:4rem;width:4rem;justify-content:center;align-items:center;color:var(--header-link-color);position:relative}.appshell-meta-navigation .header-icon:hover{color:var(--header-link-hover-color)}.appshell-meta-navigation .header-icon .notification-count{height:1.25rem;width:1.25rem;border-radius:50%;background-color:#e10a0a;color:#fff;font-family:AppShellTextFont;font-size:.75rem;font-style:normal;font-weight:400;line-height:1.5rem;text-decoration:none;display:flex;align-items:center;justify-content:center;position:absolute;top:.75rem;right:.75rem}.appshell-meta-navigation .user-ctn{padding-left:.5rem;padding-right:1.25rem;display:flex;flex-direction:row;align-items:center;height:100%}.appshell-meta-navigation .user-ctn button{cursor:pointer;display:flex;flex-direction:row;align-items:center;background-color:transparent;border:none;width:100%;gap:.5rem;color:var(--header-link-color)}.appshell-meta-navigation .user-ctn button:hover{color:var(--header-link-hover-color)}.appshell-meta-navigation .user-ctn button .header-profile-picture{width:1.5rem;height:1.5rem;border-radius:50%;background-size:cover;background-position:center;border:1px solid var(--appshell-color-grey-warm);aspect-ratio:1}.appshell-meta-navigation .user-ctn button .user-text{white-space:nowrap;overflow:hidden;text-overflow:ellipsis;font-size:.875rem;font-style:normal;font-weight:400;font-family:AppShellTextFont;width:10rem;line-height:1.25rem;text-align:start}.header-space{flex:1}.appshell-logout-panel,.appshell-platform-header-picker-panel{border-radius:.125rem!important;border:1px solid var(--appshell-color-grey-main);box-shadow:none!important;width:13rem}.appshell-logout-panel>div,.appshell-platform-header-picker-panel>div{padding:0}.appshell-logout-panel{margin-top:1.1rem}.appshell-platform-header-picker-panel{padding:.75rem 0;margin-top:.9rem;--mat-menu-item-label-text-color: var(--appshell-color-dark-green-main)}.appshell-platform-header-picker-panel .picker-search-ctn{height:3.75rem;width:100%;border-bottom:1px solid var(--appshell-color-grey-strong)}.appshell-platform-header-picker-panel .picker-search-ctn mat-form-field{width:86%;margin:0 7%;--mdc-filled-text-field-container-color: var(--appshell-color-grey-light);--mat-form-field-state-layer-color: transparent;--mdc-filled-text-field-active-indicator-color: var(--appshell-color-grey-main);--mdc-filled-text-field-hover-active-indicator-color: var(--appshell-color-grey-strong);--mdc-filled-text-field-focus-active-indicator-color: var(--appshell-color-accent-green-main);--mat-form-field-container-vertical-padding: .75rem;--mat-form-field-container-height: 2.75rem}.appshell-platform-header-picker-panel .picker-search-ctn mat-form-field .prefix-icon{margin:0 .5rem}.appshell-platform-header-picker-panel .picker-search-ctn mat-form-field button{background:transparent;border:none;cursor:pointer}.appshell-platform-header-picker-panel .picker-options-ctn{max-height:18rem;overflow-y:auto;color:var(--mat-menu-item-label-text-color)}.appshell-platform-header-picker-panel .picker-options-ctn .no-options-text{padding:1rem;font-family:AppShellTextFont;font-size:.875rem;font-style:normal;font-weight:400;line-height:1.25rem;text-align:center}.appshell-platform-header-picker-panel .picker-options-ctn .no-options-text b{display:block}.appshell-platform-header-picker-panel .picker-options-ctn .no-options-text a{color:#00e}.appshell-platform-header-picker-panel .picker-options-ctn .clear-search-btn{padding:.75rem;height:3rem;width:100%;background:none;border:none;text-decoration:underline;text-underline-offset:.4rem;text-decoration-color:var(--appshell-color-accent-green-main);color:var(--appshell-color-dark-green-main);font-family:AppShellTextFont;font-size:.875rem;font-style:normal;font-weight:500;line-height:1.25rem;text-decoration-thickness:2px;cursor:pointer}.appshell-platform-header-picker-panel button.active{background-color:var(--appshell-color-grey-neutral);border-left:2px solid var(--appshell-color-accent-green-main)}.appshell-platform-header-picker-panel button:focus-visible{outline:2px solid #0069E5;outline-offset:-.1rem}.appshell-platform-header-picker-panel button:hover{background-color:var(--appshell-color-grey-light)}\n"] }]
|
|
341
|
+
}], ctorParameters: () => [{ type: i1.Router }] });
|
|
342
|
+
|
|
343
|
+
class AppShellPlatformLayoutComponent {
|
|
344
|
+
headerVariant = input('');
|
|
345
|
+
applicationSymbol = input();
|
|
346
|
+
applicationLogo = input();
|
|
347
|
+
applicationName = input.required();
|
|
348
|
+
applicationNameLink = input();
|
|
349
|
+
appShellHelpLink = input();
|
|
350
|
+
appShellNotificationsLink = input();
|
|
351
|
+
appShellNotificationsCount = input(0);
|
|
352
|
+
headerLinks = input.required();
|
|
353
|
+
headerProjectPicker = input();
|
|
354
|
+
headerSecondaryPicker = input();
|
|
355
|
+
sidenavSections = input.required();
|
|
356
|
+
sidenavLinks = input();
|
|
357
|
+
loggedUser = input.required();
|
|
358
|
+
isPlatformPickerOpened = input(null);
|
|
359
|
+
userLoggedIn = output();
|
|
360
|
+
userLoggedOut = output();
|
|
361
|
+
userProjectPick = output();
|
|
362
|
+
userSecondaryPick = output();
|
|
363
|
+
platformPickerClick = output();
|
|
364
|
+
constructor() { }
|
|
365
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.11", ngImport: i0, type: AppShellPlatformLayoutComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
366
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.11", type: AppShellPlatformLayoutComponent, isStandalone: true, selector: "appshell-platform-layout", inputs: { headerVariant: { classPropertyName: "headerVariant", publicName: "headerVariant", isSignal: true, isRequired: false, transformFunction: null }, applicationSymbol: { classPropertyName: "applicationSymbol", publicName: "applicationSymbol", isSignal: true, isRequired: false, transformFunction: null }, applicationLogo: { classPropertyName: "applicationLogo", publicName: "applicationLogo", isSignal: true, isRequired: false, transformFunction: null }, applicationName: { classPropertyName: "applicationName", publicName: "applicationName", isSignal: true, isRequired: true, transformFunction: null }, applicationNameLink: { classPropertyName: "applicationNameLink", publicName: "applicationNameLink", isSignal: true, isRequired: false, transformFunction: null }, appShellHelpLink: { classPropertyName: "appShellHelpLink", publicName: "appShellHelpLink", isSignal: true, isRequired: false, transformFunction: null }, appShellNotificationsLink: { classPropertyName: "appShellNotificationsLink", publicName: "appShellNotificationsLink", isSignal: true, isRequired: false, transformFunction: null }, appShellNotificationsCount: { classPropertyName: "appShellNotificationsCount", publicName: "appShellNotificationsCount", isSignal: true, isRequired: false, transformFunction: null }, headerLinks: { classPropertyName: "headerLinks", publicName: "headerLinks", isSignal: true, isRequired: true, transformFunction: null }, headerProjectPicker: { classPropertyName: "headerProjectPicker", publicName: "headerProjectPicker", isSignal: true, isRequired: false, transformFunction: null }, headerSecondaryPicker: { classPropertyName: "headerSecondaryPicker", publicName: "headerSecondaryPicker", isSignal: true, isRequired: false, transformFunction: null }, sidenavSections: { classPropertyName: "sidenavSections", publicName: "sidenavSections", isSignal: true, isRequired: true, transformFunction: null }, sidenavLinks: { classPropertyName: "sidenavLinks", publicName: "sidenavLinks", isSignal: true, isRequired: false, transformFunction: null }, loggedUser: { classPropertyName: "loggedUser", publicName: "loggedUser", isSignal: true, isRequired: true, transformFunction: null }, isPlatformPickerOpened: { classPropertyName: "isPlatformPickerOpened", publicName: "isPlatformPickerOpened", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { userLoggedIn: "userLoggedIn", userLoggedOut: "userLoggedOut", userProjectPick: "userProjectPick", userSecondaryPick: "userSecondaryPick", platformPickerClick: "platformPickerClick" }, ngImport: i0, template: "<appshell-platform-header\n [class]=\"headerVariant()\"\n [symbol]=\"applicationSymbol()\"\n [logo]=\"applicationLogo()\"\n [applicationName]=\"applicationName()\"\n [applicationNameLink]=\"applicationNameLink()\"\n [helpLink]=\"appShellHelpLink()\"\n [notificationsLink]=\"appShellNotificationsLink()\"\n [notificationsCount]=\"appShellNotificationsCount()\"\n [links]=\"headerLinks()\"\n [projectPicker]=\"headerProjectPicker()\"\n [secondaryPicker]=\"headerSecondaryPicker()\"\n [loggedUser]=\"loggedUser()\"\n [isPlatformPickerOpened]=\"isPlatformPickerOpened()\"\n (userLoggedIn)=\"userLoggedIn.emit()\"\n (userLoggedOut)=\"userLoggedOut.emit()\"\n (platformPickerClick)=\"platformPickerClick.emit()\"\n (userProjectPick)=\"userProjectPick.emit($event)\"\n (userSecondaryPick)=\"userSecondaryPick.emit($event)\">\n</appshell-platform-header>\n\n<section id=\"appshell-layout-content\">\n <mat-sidenav-container>\n @if (sidenavSections() && sidenavSections().length) {\n <mat-sidenav opened mode=\"side\" disableClose [fixedInViewport]=\"true\" [fixedTopGap]=\"64\">\n <appshell-sidebar-menu [sections]=\"sidenavSections()\" [links]=\"sidenavLinks()\"></appshell-sidebar-menu>\n </mat-sidenav>\n }\n <mat-sidenav-content>\n <main>\n <router-outlet></router-outlet>\n </main>\n </mat-sidenav-content>\n </mat-sidenav-container>\n</section>", styles: ["appshell-platform-header{display:flex;position:fixed;z-index:99;width:100%}appshell-navigation{display:flex;flex-direction:row}#appshell-layout-content{flex-grow:1;display:flex;height:100%;padding-top:4rem}#appshell-layout-content mat-sidenav-container{width:100%}#appshell-layout-content appshell-sidebar-menu{display:flex;flex-direction:column;z-index:2}#appshell-layout-content mat-sidenav-content{box-sizing:border-box;background-color:var(--background-color)}#appshell-layout-content mat-sidenav-content main{display:flex;height:100%}\n"], dependencies: [{ kind: "component", type: AppShellSidebarMenuComponent, selector: "appshell-sidebar-menu", inputs: ["sections", "links"] }, { kind: "directive", type: RouterOutlet, selector: "router-outlet", inputs: ["name", "routerOutletData"], outputs: ["activate", "deactivate", "attach", "detach"], exportAs: ["outlet"] }, { kind: "ngmodule", type: MatSidenavModule }, { kind: "component", type: i1$5.MatSidenav, selector: "mat-sidenav", inputs: ["fixedInViewport", "fixedTopGap", "fixedBottomGap"], exportAs: ["matSidenav"] }, { kind: "component", type: i1$5.MatSidenavContainer, selector: "mat-sidenav-container", exportAs: ["matSidenavContainer"] }, { kind: "component", type: i1$5.MatSidenavContent, selector: "mat-sidenav-content" }, { kind: "component", type: AppShellPlatformHeaderComponent, selector: "appshell-platform-header", inputs: ["applicationName", "symbol", "logo", "applicationNameLink", "helpLink", "notificationsLink", "notificationsCount", "links", "projectPicker", "secondaryPicker", "loggedUser", "isPlatformPickerOpened"], outputs: ["userLoggedIn", "userLoggedOut", "userProjectPick", "userSecondaryPick", "platformPickerClick"] }] });
|
|
367
|
+
}
|
|
368
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.11", ngImport: i0, type: AppShellPlatformLayoutComponent, decorators: [{
|
|
369
|
+
type: Component,
|
|
370
|
+
args: [{ selector: 'appshell-platform-layout', imports: [AppShellSidebarMenuComponent, RouterOutlet, MatSidenavModule, AppShellPlatformHeaderComponent], template: "<appshell-platform-header\n [class]=\"headerVariant()\"\n [symbol]=\"applicationSymbol()\"\n [logo]=\"applicationLogo()\"\n [applicationName]=\"applicationName()\"\n [applicationNameLink]=\"applicationNameLink()\"\n [helpLink]=\"appShellHelpLink()\"\n [notificationsLink]=\"appShellNotificationsLink()\"\n [notificationsCount]=\"appShellNotificationsCount()\"\n [links]=\"headerLinks()\"\n [projectPicker]=\"headerProjectPicker()\"\n [secondaryPicker]=\"headerSecondaryPicker()\"\n [loggedUser]=\"loggedUser()\"\n [isPlatformPickerOpened]=\"isPlatformPickerOpened()\"\n (userLoggedIn)=\"userLoggedIn.emit()\"\n (userLoggedOut)=\"userLoggedOut.emit()\"\n (platformPickerClick)=\"platformPickerClick.emit()\"\n (userProjectPick)=\"userProjectPick.emit($event)\"\n (userSecondaryPick)=\"userSecondaryPick.emit($event)\">\n</appshell-platform-header>\n\n<section id=\"appshell-layout-content\">\n <mat-sidenav-container>\n @if (sidenavSections() && sidenavSections().length) {\n <mat-sidenav opened mode=\"side\" disableClose [fixedInViewport]=\"true\" [fixedTopGap]=\"64\">\n <appshell-sidebar-menu [sections]=\"sidenavSections()\" [links]=\"sidenavLinks()\"></appshell-sidebar-menu>\n </mat-sidenav>\n }\n <mat-sidenav-content>\n <main>\n <router-outlet></router-outlet>\n </main>\n </mat-sidenav-content>\n </mat-sidenav-container>\n</section>", styles: ["appshell-platform-header{display:flex;position:fixed;z-index:99;width:100%}appshell-navigation{display:flex;flex-direction:row}#appshell-layout-content{flex-grow:1;display:flex;height:100%;padding-top:4rem}#appshell-layout-content mat-sidenav-container{width:100%}#appshell-layout-content appshell-sidebar-menu{display:flex;flex-direction:column;z-index:2}#appshell-layout-content mat-sidenav-content{box-sizing:border-box;background-color:var(--background-color)}#appshell-layout-content mat-sidenav-content main{display:flex;height:100%}\n"] }]
|
|
371
|
+
}], ctorParameters: () => [] });
|
|
372
|
+
|
|
373
|
+
class AppShellProductCardComponent {
|
|
374
|
+
router;
|
|
375
|
+
ngZone;
|
|
376
|
+
labelsChipSet;
|
|
377
|
+
title = input.required();
|
|
378
|
+
description = input.required();
|
|
379
|
+
image = input();
|
|
380
|
+
labels = input();
|
|
381
|
+
redirectTo = input();
|
|
382
|
+
resizeObserver = new ResizeObserver(this.debounce(() => {
|
|
383
|
+
this.ngZone.run(() => {
|
|
384
|
+
window.requestAnimationFrame(() => {
|
|
385
|
+
this.hideOverflowingLabels();
|
|
386
|
+
});
|
|
387
|
+
});
|
|
388
|
+
}, 100));
|
|
389
|
+
constructor(router, ngZone) {
|
|
390
|
+
this.router = router;
|
|
391
|
+
this.ngZone = ngZone;
|
|
392
|
+
}
|
|
393
|
+
debounce(func, wait) {
|
|
394
|
+
let timeout;
|
|
395
|
+
return (...args) => {
|
|
396
|
+
clearTimeout(timeout);
|
|
397
|
+
timeout = window.setTimeout(() => func.apply(this, args), wait);
|
|
398
|
+
};
|
|
399
|
+
}
|
|
400
|
+
ngAfterViewChecked() {
|
|
401
|
+
this.hideOverflowingLabels();
|
|
402
|
+
this.resizeObserver.observe(this.labelsChipSet.nativeElement);
|
|
403
|
+
}
|
|
404
|
+
onClick() {
|
|
405
|
+
this.router.navigate([this.redirectTo()]);
|
|
406
|
+
}
|
|
407
|
+
hideOverflowingLabels() {
|
|
408
|
+
const twoLinesHeight = 4.5 * 16; // Each label uses 2 rem with a gap of .5 rem where 1 rem = 16px
|
|
409
|
+
const labelsChipSetDiv = this.labelsChipSet.nativeElement.firstChild;
|
|
410
|
+
const chipsChildren = Array.from(labelsChipSetDiv.children).filter((child) => child.tagName.toLowerCase() === 'appshell-chip');
|
|
411
|
+
chipsChildren.forEach((child) => {
|
|
412
|
+
if (child.id === 'extra-labels') {
|
|
413
|
+
child.style.display = 'none';
|
|
414
|
+
}
|
|
415
|
+
else {
|
|
416
|
+
child.style.display = 'block';
|
|
417
|
+
}
|
|
418
|
+
});
|
|
419
|
+
if (chipsChildren.length <= 2) {
|
|
420
|
+
return;
|
|
421
|
+
}
|
|
422
|
+
let index = chipsChildren.length - 2; // Start from the second last child
|
|
423
|
+
const hiddenLabels = [];
|
|
424
|
+
const extraLabels = labelsChipSetDiv.querySelector('#extra-labels');
|
|
425
|
+
if (labelsChipSetDiv.scrollHeight > twoLinesHeight && extraLabels) {
|
|
426
|
+
extraLabels.style.display = 'block';
|
|
427
|
+
}
|
|
428
|
+
while (labelsChipSetDiv.scrollHeight > twoLinesHeight && index >= 0) {
|
|
429
|
+
const label = chipsChildren[index];
|
|
430
|
+
label.style.display = 'none';
|
|
431
|
+
const labelText = label.querySelector('.mdc-evolution-chip__text-label.mat-mdc-chip-action-label')?.textContent;
|
|
432
|
+
if (labelText) {
|
|
433
|
+
hiddenLabels.push(labelText);
|
|
434
|
+
index--;
|
|
435
|
+
}
|
|
436
|
+
}
|
|
437
|
+
if (hiddenLabels.length > 0 && extraLabels) {
|
|
438
|
+
this.changeExtraLabel(extraLabels, hiddenLabels);
|
|
439
|
+
}
|
|
440
|
+
}
|
|
441
|
+
changeExtraLabel(labelEl, removedLabels) {
|
|
442
|
+
labelEl.classList.add('tooltip-chip');
|
|
443
|
+
let existingSpan = labelEl.querySelector('.tooltip-text');
|
|
444
|
+
if (existingSpan) {
|
|
445
|
+
labelEl.removeChild(existingSpan);
|
|
446
|
+
}
|
|
447
|
+
existingSpan = document.createElement('span');
|
|
448
|
+
existingSpan.classList.add('tooltip-text');
|
|
449
|
+
existingSpan.textContent = `${[...removedLabels].reverse().join(', ')}`;
|
|
450
|
+
labelEl.appendChild(existingSpan);
|
|
451
|
+
const textLabel = labelEl?.querySelector('.mdc-evolution-chip__text-label.mat-mdc-chip-action-label');
|
|
452
|
+
if (textLabel) {
|
|
453
|
+
textLabel.textContent = `+${removedLabels.length}`;
|
|
454
|
+
}
|
|
455
|
+
}
|
|
456
|
+
ngOnDestroy() {
|
|
457
|
+
if (this.resizeObserver) {
|
|
458
|
+
this.resizeObserver.disconnect();
|
|
459
|
+
}
|
|
460
|
+
}
|
|
461
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.11", ngImport: i0, type: AppShellProductCardComponent, deps: [{ token: i1.Router }, { token: i0.NgZone }], target: i0.ɵɵFactoryTarget.Component });
|
|
462
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.11", type: AppShellProductCardComponent, isStandalone: true, selector: "appshell-product-card", inputs: { title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: true, transformFunction: null }, description: { classPropertyName: "description", publicName: "description", isSignal: true, isRequired: true, transformFunction: null }, image: { classPropertyName: "image", publicName: "image", isSignal: true, isRequired: false, transformFunction: null }, labels: { classPropertyName: "labels", publicName: "labels", isSignal: true, isRequired: false, transformFunction: null }, redirectTo: { classPropertyName: "redirectTo", publicName: "redirectTo", isSignal: true, isRequired: false, transformFunction: null } }, viewQueries: [{ propertyName: "labelsChipSet", first: true, predicate: ["labelsChipSet"], descendants: true, read: ElementRef, static: true }], ngImport: i0, template: "<mat-card class=\"appshell-product-card\" appearance=\"outlined\" tabindex=\"0\" (click)=\"onClick()\" (keydown.enter)=\"onClick()\" (keydown.space)=\"onClick()\">\n <mat-card-header>\n <mat-card-title-group>\n <mat-card-title>{{title()}}</mat-card-title>\n @if (image()) {\n <img mat-card-image [src]=\"image()\" alt=\"\">\n }\n </mat-card-title-group>\n </mat-card-header>\n <mat-card-content>\n {{description()}}\n </mat-card-content>\n <mat-card-actions>\n <mat-chip-set attr.aria-label=\"{{title()}} label\" class=\"appshell-product-card-labels\" #labelsChipSet>\n @for (label of labels(); track label) {\n <appshell-chip [label]=\"label\"></appshell-chip>\n }\n <appshell-chip id=\"extra-labels\" class=\"tooltip-chip\" label=\"+X\"></appshell-chip>\n </mat-chip-set>\n </mat-card-actions>\n</mat-card>", styles: [".appshell-product-card{padding:.5rem;border-radius:.15rem!important;border-width:1px!important;border-color:var(--appshell-color-grey-warm)!important;text-decoration:none;cursor:pointer;color:var(--appshell-color-secondary-main);height:100%;max-width:35rem}.appshell-product-card:hover{color:var(--appshell-color-secondary-medium)}.appshell-product-card mat-card-header{height:3rem;padding:1rem}.appshell-product-card mat-card-header mat-card-title-group{gap:1rem;align-items:center}.appshell-product-card mat-card-header mat-card-title-group mat-card-title{font-family:AppShellHeadingFont;font-size:1.25rem;font-style:normal;font-weight:500;line-height:120%;letter-spacing:.00625rem;overflow:hidden;display:-webkit-box;line-clamp:2;-webkit-line-clamp:2;-webkit-box-orient:vertical}.appshell-product-card mat-card-header mat-card-title-group img{width:2.5rem;height:2.5rem}.appshell-product-card mat-card-content{font-family:AppShellTextFont;font-size:.875rem;font-style:normal;font-weight:400;line-height:120%;letter-spacing:.00625rem;overflow:hidden;display:-webkit-box;line-clamp:3;-webkit-line-clamp:3;-webkit-box-orient:vertical;height:3rem}.appshell-product-card mat-card-actions{padding:0 1rem;display:flex;flex-direction:column;align-items:start;gap:1rem;margin:1.5rem 0 1rem;min-height:unset}.appshell-product-card mat-card-actions .appshell-product-card-labels{max-height:4.5rem;width:100%}.appshell-product-card mat-card-actions .appshell-product-card-labels>div{row-gap:.5rem;column-gap:1rem}.appshell-product-card mat-card-actions .appshell-product-card-labels>div .tooltip-chip{position:relative}.appshell-product-card mat-card-actions .appshell-product-card-labels>div .tooltip-chip .tooltip-text{visibility:hidden;font-size:.875rem;width:10rem;background-color:#000;color:#fff;text-align:center;border-radius:6px;padding:.5rem;position:absolute;z-index:1;bottom:130%;left:50%;margin-left:-5.5rem}.appshell-product-card mat-card-actions .appshell-product-card-labels>div .tooltip-chip .tooltip-text:after{content:\"\";position:absolute;top:100%;left:50%;margin-left:-5px;border-width:5px;border-style:solid;border-color:black transparent transparent transparent}.appshell-product-card mat-card-actions .appshell-product-card-labels>div .tooltip-chip:hover .tooltip-text{visibility:visible}\n"], dependencies: [{ kind: "ngmodule", type: MatCardModule }, { kind: "component", type: i2$1.MatCard, selector: "mat-card", inputs: ["appearance"], exportAs: ["matCard"] }, { kind: "directive", type: i2$1.MatCardActions, selector: "mat-card-actions", inputs: ["align"], exportAs: ["matCardActions"] }, { kind: "directive", type: i2$1.MatCardContent, selector: "mat-card-content" }, { kind: "component", type: i2$1.MatCardHeader, selector: "mat-card-header" }, { kind: "directive", type: i2$1.MatCardImage, selector: "[mat-card-image], [matCardImage]" }, { kind: "directive", type: i2$1.MatCardTitle, selector: "mat-card-title, [mat-card-title], [matCardTitle]" }, { kind: "component", type: i2$1.MatCardTitleGroup, selector: "mat-card-title-group" }, { kind: "ngmodule", type: MatButtonModule }, { kind: "ngmodule", type: MatChipsModule }, { kind: "component", type: i1$2.MatChipSet, selector: "mat-chip-set", inputs: ["disabled", "role", "tabIndex"] }, { kind: "component", type: AppShellChipComponent, selector: "appshell-chip", inputs: ["label"] }, { kind: "ngmodule", type: MatTooltipModule }], encapsulation: i0.ViewEncapsulation.None });
|
|
463
|
+
}
|
|
464
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.11", ngImport: i0, type: AppShellProductCardComponent, decorators: [{
|
|
465
|
+
type: Component,
|
|
466
|
+
args: [{ selector: 'appshell-product-card', imports: [MatCardModule, MatButtonModule, MatChipsModule, AppShellChipComponent, AppShellChipComponent, MatTooltipModule], encapsulation: ViewEncapsulation.None, template: "<mat-card class=\"appshell-product-card\" appearance=\"outlined\" tabindex=\"0\" (click)=\"onClick()\" (keydown.enter)=\"onClick()\" (keydown.space)=\"onClick()\">\n <mat-card-header>\n <mat-card-title-group>\n <mat-card-title>{{title()}}</mat-card-title>\n @if (image()) {\n <img mat-card-image [src]=\"image()\" alt=\"\">\n }\n </mat-card-title-group>\n </mat-card-header>\n <mat-card-content>\n {{description()}}\n </mat-card-content>\n <mat-card-actions>\n <mat-chip-set attr.aria-label=\"{{title()}} label\" class=\"appshell-product-card-labels\" #labelsChipSet>\n @for (label of labels(); track label) {\n <appshell-chip [label]=\"label\"></appshell-chip>\n }\n <appshell-chip id=\"extra-labels\" class=\"tooltip-chip\" label=\"+X\"></appshell-chip>\n </mat-chip-set>\n </mat-card-actions>\n</mat-card>", styles: [".appshell-product-card{padding:.5rem;border-radius:.15rem!important;border-width:1px!important;border-color:var(--appshell-color-grey-warm)!important;text-decoration:none;cursor:pointer;color:var(--appshell-color-secondary-main);height:100%;max-width:35rem}.appshell-product-card:hover{color:var(--appshell-color-secondary-medium)}.appshell-product-card mat-card-header{height:3rem;padding:1rem}.appshell-product-card mat-card-header mat-card-title-group{gap:1rem;align-items:center}.appshell-product-card mat-card-header mat-card-title-group mat-card-title{font-family:AppShellHeadingFont;font-size:1.25rem;font-style:normal;font-weight:500;line-height:120%;letter-spacing:.00625rem;overflow:hidden;display:-webkit-box;line-clamp:2;-webkit-line-clamp:2;-webkit-box-orient:vertical}.appshell-product-card mat-card-header mat-card-title-group img{width:2.5rem;height:2.5rem}.appshell-product-card mat-card-content{font-family:AppShellTextFont;font-size:.875rem;font-style:normal;font-weight:400;line-height:120%;letter-spacing:.00625rem;overflow:hidden;display:-webkit-box;line-clamp:3;-webkit-line-clamp:3;-webkit-box-orient:vertical;height:3rem}.appshell-product-card mat-card-actions{padding:0 1rem;display:flex;flex-direction:column;align-items:start;gap:1rem;margin:1.5rem 0 1rem;min-height:unset}.appshell-product-card mat-card-actions .appshell-product-card-labels{max-height:4.5rem;width:100%}.appshell-product-card mat-card-actions .appshell-product-card-labels>div{row-gap:.5rem;column-gap:1rem}.appshell-product-card mat-card-actions .appshell-product-card-labels>div .tooltip-chip{position:relative}.appshell-product-card mat-card-actions .appshell-product-card-labels>div .tooltip-chip .tooltip-text{visibility:hidden;font-size:.875rem;width:10rem;background-color:#000;color:#fff;text-align:center;border-radius:6px;padding:.5rem;position:absolute;z-index:1;bottom:130%;left:50%;margin-left:-5.5rem}.appshell-product-card mat-card-actions .appshell-product-card-labels>div .tooltip-chip .tooltip-text:after{content:\"\";position:absolute;top:100%;left:50%;margin-left:-5px;border-width:5px;border-style:solid;border-color:black transparent transparent transparent}.appshell-product-card mat-card-actions .appshell-product-card-labels>div .tooltip-chip:hover .tooltip-text{visibility:visible}\n"] }]
|
|
467
|
+
}], ctorParameters: () => [{ type: i1.Router }, { type: i0.NgZone }], propDecorators: { labelsChipSet: [{
|
|
468
|
+
type: ViewChild,
|
|
469
|
+
args: ['labelsChipSet', { static: true, read: ElementRef }]
|
|
470
|
+
}] } });
|
|
471
|
+
|
|
472
|
+
class AppShellProductCardV2Component {
|
|
473
|
+
router;
|
|
474
|
+
title = input.required();
|
|
475
|
+
description = input.required();
|
|
476
|
+
image = input();
|
|
477
|
+
link = input();
|
|
478
|
+
buttonText = input();
|
|
479
|
+
labels = input();
|
|
480
|
+
redirectTo = input();
|
|
481
|
+
constructor(router) {
|
|
482
|
+
this.router = router;
|
|
483
|
+
}
|
|
484
|
+
onClick() {
|
|
485
|
+
this.router.navigate([this.redirectTo()]);
|
|
486
|
+
}
|
|
487
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.11", ngImport: i0, type: AppShellProductCardV2Component, deps: [{ token: i1.Router }], target: i0.ɵɵFactoryTarget.Component });
|
|
488
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.11", type: AppShellProductCardV2Component, isStandalone: true, selector: "appshell-product-card-v2", inputs: { title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: true, transformFunction: null }, description: { classPropertyName: "description", publicName: "description", isSignal: true, isRequired: true, transformFunction: null }, image: { classPropertyName: "image", publicName: "image", isSignal: true, isRequired: false, transformFunction: null }, link: { classPropertyName: "link", publicName: "link", isSignal: true, isRequired: false, transformFunction: null }, buttonText: { classPropertyName: "buttonText", publicName: "buttonText", isSignal: true, isRequired: false, transformFunction: null }, labels: { classPropertyName: "labels", publicName: "labels", isSignal: true, isRequired: false, transformFunction: null }, redirectTo: { classPropertyName: "redirectTo", publicName: "redirectTo", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "<mat-card class=\"appshell-product-card-v2\" appearance=\"outlined\" tabindex=\"0\" (click)=\"onClick()\" (keydown.enter)=\"onClick()\" (keydown.space)=\"onClick()\">\n <mat-card-content>\n <div class=\"appshell-product-card-v2-img\">\n <img mat-card-image [src]=\"image()\" alt=\"\">\n </div>\n <div class=\"appshell-product-card-v2-data\">\n <div class=\"labels\">\n @for (label of labels(); track label; let index = $index) {\n <span>\n {{label}}\n </span>\n }\n </div>\n <span class=\"title\">{{title()}}</span>\n <div class=\"description\">{{description()}}</div>\n </div>\n </mat-card-content>\n</mat-card>", styles: [".appshell-product-card-v2{border-radius:.15rem!important;border-width:1px!important;border-color:var(--appshell-color-grey-warm)!important;gap:1rem;text-decoration:none;cursor:pointer}.appshell-product-card-v2 mat-card-content{color:var(--appshell-color-secondary-main);letter-spacing:.00625rem;display:flex;flex-direction:row;height:10rem;padding:0!important}.appshell-product-card-v2 mat-card-content:hover{color:var(--appshell-color-secondary-medium)}.appshell-product-card-v2 mat-card-content .appshell-product-card-v2-img{padding:1.5rem}.appshell-product-card-v2 mat-card-content .appshell-product-card-v2-img img{width:7rem;height:7rem}.appshell-product-card-v2 mat-card-content .appshell-product-card-v2-data{display:flex;flex-direction:column;justify-content:start;padding:1rem}.appshell-product-card-v2 mat-card-content .appshell-product-card-v2-data .labels{display:-webkit-box;-webkit-box-orient:vertical;overflow:hidden;text-overflow:ellipsis;font-size:.875rem;font-style:normal;font-weight:400;line-height:1.25rem;height:1.25rem}.appshell-product-card-v2 mat-card-content .appshell-product-card-v2-data .labels span{display:inline-block;white-space:nowrap}.appshell-product-card-v2 mat-card-content .appshell-product-card-v2-data .labels span:before{content:\"-\";margin-right:.1rem;margin-left:.1rem}.appshell-product-card-v2 mat-card-content .appshell-product-card-v2-data .labels span:first-child:before{content:\"\";margin-right:0;margin-left:0}.appshell-product-card-v2 mat-card-content .appshell-product-card-v2-data .title{font-size:1.5rem;font-style:normal;font-weight:700;line-height:2.25rem;display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:1;line-clamp:1;overflow:hidden;text-overflow:ellipsis}.appshell-product-card-v2 mat-card-content .appshell-product-card-v2-data .description{margin-top:.5rem;overflow:hidden;text-overflow:ellipsis;font-size:.875rem;font-style:normal;font-weight:400;line-height:1.25rem;display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:3;line-clamp:3}\n"], dependencies: [{ kind: "ngmodule", type: MatCardModule }, { kind: "component", type: i2$1.MatCard, selector: "mat-card", inputs: ["appearance"], exportAs: ["matCard"] }, { kind: "directive", type: i2$1.MatCardContent, selector: "mat-card-content" }, { kind: "directive", type: i2$1.MatCardImage, selector: "[mat-card-image], [matCardImage]" }, { kind: "ngmodule", type: MatButtonModule }, { kind: "ngmodule", type: MatChipsModule }], encapsulation: i0.ViewEncapsulation.None });
|
|
489
|
+
}
|
|
490
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.11", ngImport: i0, type: AppShellProductCardV2Component, decorators: [{
|
|
491
|
+
type: Component,
|
|
492
|
+
args: [{ selector: 'appshell-product-card-v2', imports: [MatCardModule, MatButtonModule, MatChipsModule], encapsulation: ViewEncapsulation.None, template: "<mat-card class=\"appshell-product-card-v2\" appearance=\"outlined\" tabindex=\"0\" (click)=\"onClick()\" (keydown.enter)=\"onClick()\" (keydown.space)=\"onClick()\">\n <mat-card-content>\n <div class=\"appshell-product-card-v2-img\">\n <img mat-card-image [src]=\"image()\" alt=\"\">\n </div>\n <div class=\"appshell-product-card-v2-data\">\n <div class=\"labels\">\n @for (label of labels(); track label; let index = $index) {\n <span>\n {{label}}\n </span>\n }\n </div>\n <span class=\"title\">{{title()}}</span>\n <div class=\"description\">{{description()}}</div>\n </div>\n </mat-card-content>\n</mat-card>", styles: [".appshell-product-card-v2{border-radius:.15rem!important;border-width:1px!important;border-color:var(--appshell-color-grey-warm)!important;gap:1rem;text-decoration:none;cursor:pointer}.appshell-product-card-v2 mat-card-content{color:var(--appshell-color-secondary-main);letter-spacing:.00625rem;display:flex;flex-direction:row;height:10rem;padding:0!important}.appshell-product-card-v2 mat-card-content:hover{color:var(--appshell-color-secondary-medium)}.appshell-product-card-v2 mat-card-content .appshell-product-card-v2-img{padding:1.5rem}.appshell-product-card-v2 mat-card-content .appshell-product-card-v2-img img{width:7rem;height:7rem}.appshell-product-card-v2 mat-card-content .appshell-product-card-v2-data{display:flex;flex-direction:column;justify-content:start;padding:1rem}.appshell-product-card-v2 mat-card-content .appshell-product-card-v2-data .labels{display:-webkit-box;-webkit-box-orient:vertical;overflow:hidden;text-overflow:ellipsis;font-size:.875rem;font-style:normal;font-weight:400;line-height:1.25rem;height:1.25rem}.appshell-product-card-v2 mat-card-content .appshell-product-card-v2-data .labels span{display:inline-block;white-space:nowrap}.appshell-product-card-v2 mat-card-content .appshell-product-card-v2-data .labels span:before{content:\"-\";margin-right:.1rem;margin-left:.1rem}.appshell-product-card-v2 mat-card-content .appshell-product-card-v2-data .labels span:first-child:before{content:\"\";margin-right:0;margin-left:0}.appshell-product-card-v2 mat-card-content .appshell-product-card-v2-data .title{font-size:1.5rem;font-style:normal;font-weight:700;line-height:2.25rem;display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:1;line-clamp:1;overflow:hidden;text-overflow:ellipsis}.appshell-product-card-v2 mat-card-content .appshell-product-card-v2-data .description{margin-top:.5rem;overflow:hidden;text-overflow:ellipsis;font-size:.875rem;font-style:normal;font-weight:400;line-height:1.25rem;display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:3;line-clamp:3}\n"] }]
|
|
493
|
+
}], ctorParameters: () => [{ type: i1.Router }] });
|
|
494
|
+
|
|
495
|
+
class AppShellToastComponent {
|
|
496
|
+
notification = input();
|
|
497
|
+
closed = output();
|
|
498
|
+
closeToast() {
|
|
499
|
+
this.closed.emit(true);
|
|
500
|
+
}
|
|
501
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.11", ngImport: i0, type: AppShellToastComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
502
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "19.2.11", type: AppShellToastComponent, isStandalone: true, selector: "appshell-toast", inputs: { notification: { classPropertyName: "notification", publicName: "notification", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { closed: "closed" }, ngImport: i0, template: "<div class=\"appshell-toast\">\n <div class=\"appshell-toast-content\">\n <h4>{{ notification()?.title }}</h4>\n <p>{{ notification()?.message }}</p>\n </div>\n <button (click)=\"closeToast()\">\n <appshell-icon [icon]=\"'close'\"></appshell-icon>\n </button>\n</div>", styles: [".appshell-toast{display:flex;flex-direction:row;justify-content:space-between;width:17rem;padding:.75rem .5rem .75rem 1rem;align-items:center;gap:.5rem;flex-shrink:0;border-radius:.125rem;border:1px solid #EFEEEB;background:#fff;box-shadow:0 2px 12px #0000000d}.appshell-toast .appshell-toast-content{height:100%}.appshell-toast .appshell-toast-content h4{overflow:hidden;color:var(--black, #191919);text-overflow:ellipsis;margin:0;font-family:AppShellTextFont;font-size:.875rem;font-style:normal;font-weight:700;line-height:1.25rem;display:-webkit-box;-webkit-box-orient:vertical;line-clamp:1;-webkit-line-clamp:1}.appshell-toast .appshell-toast-content p{margin:0;overflow:hidden;color:var(--appshell-color-grey-main);text-overflow:ellipsis;font-family:AppShellTextFont;font-size:.875rem;font-style:normal;font-weight:400;line-height:1.25rem;display:-webkit-box;-webkit-box-orient:vertical;line-clamp:1;-webkit-line-clamp:1}.appshell-toast button{width:2rem;height:2rem;background:transparent;border:none;cursor:pointer}\n"], dependencies: [{ kind: "component", type: AppShellIconComponent, selector: "appshell-icon", inputs: ["icon"] }] });
|
|
503
|
+
}
|
|
504
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.11", ngImport: i0, type: AppShellToastComponent, decorators: [{
|
|
505
|
+
type: Component,
|
|
506
|
+
args: [{ selector: 'appshell-toast', imports: [AppShellIconComponent], template: "<div class=\"appshell-toast\">\n <div class=\"appshell-toast-content\">\n <h4>{{ notification()?.title }}</h4>\n <p>{{ notification()?.message }}</p>\n </div>\n <button (click)=\"closeToast()\">\n <appshell-icon [icon]=\"'close'\"></appshell-icon>\n </button>\n</div>", styles: [".appshell-toast{display:flex;flex-direction:row;justify-content:space-between;width:17rem;padding:.75rem .5rem .75rem 1rem;align-items:center;gap:.5rem;flex-shrink:0;border-radius:.125rem;border:1px solid #EFEEEB;background:#fff;box-shadow:0 2px 12px #0000000d}.appshell-toast .appshell-toast-content{height:100%}.appshell-toast .appshell-toast-content h4{overflow:hidden;color:var(--black, #191919);text-overflow:ellipsis;margin:0;font-family:AppShellTextFont;font-size:.875rem;font-style:normal;font-weight:700;line-height:1.25rem;display:-webkit-box;-webkit-box-orient:vertical;line-clamp:1;-webkit-line-clamp:1}.appshell-toast .appshell-toast-content p{margin:0;overflow:hidden;color:var(--appshell-color-grey-main);text-overflow:ellipsis;font-family:AppShellTextFont;font-size:.875rem;font-style:normal;font-weight:400;line-height:1.25rem;display:-webkit-box;-webkit-box-orient:vertical;line-clamp:1;-webkit-line-clamp:1}.appshell-toast button{width:2rem;height:2rem;background:transparent;border:none;cursor:pointer}\n"] }]
|
|
507
|
+
}] });
|
|
508
|
+
|
|
509
|
+
class AppShellToastService {
|
|
510
|
+
toastsSubject = new BehaviorSubject([]);
|
|
511
|
+
toasts$ = this.toastsSubject.asObservable();
|
|
512
|
+
currentId = 0;
|
|
513
|
+
showToast(notification, duration, closeFn) {
|
|
514
|
+
if (closeFn) {
|
|
515
|
+
const originalCloseFn = closeFn;
|
|
516
|
+
closeFn = () => {
|
|
517
|
+
originalCloseFn();
|
|
518
|
+
this.removeToast(this.currentId);
|
|
519
|
+
};
|
|
520
|
+
}
|
|
521
|
+
else {
|
|
522
|
+
closeFn = () => this.removeToast(this.currentId);
|
|
523
|
+
}
|
|
524
|
+
const toast = { id: this.currentId++, notification, closeFn: () => closeFn() };
|
|
525
|
+
this.toastsSubject.next([...this.toastsSubject.value, toast]);
|
|
526
|
+
if (duration) {
|
|
527
|
+
setTimeout(() => this.removeToast(toast.id), duration);
|
|
528
|
+
}
|
|
529
|
+
}
|
|
530
|
+
removeToast(id) {
|
|
531
|
+
this.toastsSubject.next(this.toastsSubject.value.filter(toast => toast.id !== id));
|
|
532
|
+
}
|
|
533
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.11", ngImport: i0, type: AppShellToastService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
534
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.2.11", ngImport: i0, type: AppShellToastService, providedIn: 'root' });
|
|
535
|
+
}
|
|
536
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.11", ngImport: i0, type: AppShellToastService, decorators: [{
|
|
537
|
+
type: Injectable,
|
|
538
|
+
args: [{
|
|
539
|
+
providedIn: 'root'
|
|
540
|
+
}]
|
|
541
|
+
}] });
|
|
542
|
+
|
|
543
|
+
class AppShellToastsComponent {
|
|
544
|
+
toastService;
|
|
545
|
+
toastsLimit = input(3);
|
|
546
|
+
toasts = [];
|
|
547
|
+
constructor(toastService) {
|
|
548
|
+
this.toastService = toastService;
|
|
549
|
+
}
|
|
550
|
+
ngOnInit() {
|
|
551
|
+
this.toastService.toasts$.subscribe((toasts) => this.toasts = toasts);
|
|
552
|
+
}
|
|
553
|
+
closeToast(id) {
|
|
554
|
+
this.toastService.removeToast(id);
|
|
555
|
+
}
|
|
556
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.11", ngImport: i0, type: AppShellToastsComponent, deps: [{ token: AppShellToastService }], target: i0.ɵɵFactoryTarget.Component });
|
|
557
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.11", type: AppShellToastsComponent, isStandalone: true, selector: "appshell-toasts", inputs: { toastsLimit: { classPropertyName: "toastsLimit", publicName: "toastsLimit", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "<div class=\"toast-container\">\n @for (toast of toasts | slice:0:toastsLimit(); track toast.id) {\n <appshell-toast [notification]=\"toast.notification\" (closed)=\"closeToast(toast.id)\"></appshell-toast>\n }\n</div>", styles: [".toast-container{position:fixed;top:4.5rem;right:1rem;display:flex;flex-direction:column-reverse;align-items:flex-end;z-index:9999}.toast-container appshell-toast{margin-bottom:1rem}\n"], dependencies: [{ kind: "component", type: AppShellToastComponent, selector: "appshell-toast", inputs: ["notification"], outputs: ["closed"] }, { kind: "pipe", type: SlicePipe, name: "slice" }] });
|
|
558
|
+
}
|
|
559
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.11", ngImport: i0, type: AppShellToastsComponent, decorators: [{
|
|
560
|
+
type: Component,
|
|
561
|
+
args: [{ selector: 'appshell-toasts', imports: [AppShellToastComponent, SlicePipe], template: "<div class=\"toast-container\">\n @for (toast of toasts | slice:0:toastsLimit(); track toast.id) {\n <appshell-toast [notification]=\"toast.notification\" (closed)=\"closeToast(toast.id)\"></appshell-toast>\n }\n</div>", styles: [".toast-container{position:fixed;top:4.5rem;right:1rem;display:flex;flex-direction:column-reverse;align-items:flex-end;z-index:9999}.toast-container appshell-toast{margin-bottom:1rem}\n"] }]
|
|
562
|
+
}], ctorParameters: () => [{ type: AppShellToastService }] });
|
|
563
|
+
|
|
564
|
+
class AppShellProductCatalogScreenComponent {
|
|
565
|
+
pageTitle = input.required();
|
|
566
|
+
breadcrumbLinks = input.required();
|
|
567
|
+
products = input.required();
|
|
568
|
+
filters = input.required();
|
|
569
|
+
noProductsIcon = input();
|
|
570
|
+
noProductsHtmlMessage = input();
|
|
571
|
+
activeFiltersChange = output();
|
|
572
|
+
getProductLabels(product) {
|
|
573
|
+
return product.tags?.flatMap(tag => tag.options) || [];
|
|
574
|
+
}
|
|
575
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.11", ngImport: i0, type: AppShellProductCatalogScreenComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
576
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.11", type: AppShellProductCatalogScreenComponent, isStandalone: true, selector: "appshell-product-catalog-screen", inputs: { pageTitle: { classPropertyName: "pageTitle", publicName: "pageTitle", isSignal: true, isRequired: true, transformFunction: null }, breadcrumbLinks: { classPropertyName: "breadcrumbLinks", publicName: "breadcrumbLinks", isSignal: true, isRequired: true, transformFunction: null }, products: { classPropertyName: "products", publicName: "products", isSignal: true, isRequired: true, transformFunction: null }, filters: { classPropertyName: "filters", publicName: "filters", isSignal: true, isRequired: true, transformFunction: null }, noProductsIcon: { classPropertyName: "noProductsIcon", publicName: "noProductsIcon", isSignal: true, isRequired: false, transformFunction: null }, noProductsHtmlMessage: { classPropertyName: "noProductsHtmlMessage", publicName: "noProductsHtmlMessage", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { activeFiltersChange: "activeFiltersChange" }, ngImport: i0, template: "<appshell-page-header \n [title]=\"pageTitle()\"\n [breadcrumbLinks]=\"breadcrumbLinks()\"></appshell-page-header>\n<appshell-filters\n [filters]=\"filters()\"\n (activeFiltersChange)=\"activeFiltersChange.emit($event)\"></appshell-filters>\n<section class=\"catalog-main\">\n @if(products().length > 0) {\n <div class=\"products-ctn\">\n @for (product of products(); track product.id) {\n <appshell-product-card\n [title]=\"product.title\"\n [description]=\"product.shortDescription\"\n [image]=\"product.image\"\n [labels]=\"getProductLabels(product)\"\n [redirectTo]=\"product.link\"\n ></appshell-product-card>\n }\n </div>\n }\n @if(products().length === 0 && (noProductsHtmlMessage() || noProductsIcon())) {\n <div class=\"no-results-ctn\" role=\"status\" aria-live=\"polite\" tabindex=\"0\">\n @if(noProductsIcon()) {\n <appshell-icon [class]=\"'no-results-icon'\" [icon]=\"noProductsIcon()!\" />\n }\n <div [innerHTML]=\"noProductsHtmlMessage()\"></div>\n </div>\n }\n</section>", styles: ["appshell-product-catalog-screen{display:flex;flex-direction:column;height:100%}.catalog-main{flex:1;background-color:var(--appshell-color-grey-light)}.catalog-main .products-ctn{display:grid;grid-template-columns:repeat(auto-fill,minmax(25rem,1fr));grid-auto-rows:1fr;gap:1.5rem;padding:1.5rem;box-sizing:border-box;max-width:127.5rem}.catalog-main .products-ctn>*{width:100%;min-width:25rem;max-width:35rem}.catalog-main .no-results-ctn{width:100%;height:100%;max-width:120rem;display:flex;flex-direction:column;align-items:center;padding-top:4.5rem;color:var(--appshell-color-secondary-main);text-align:center;font-size:1rem;font-style:normal;font-weight:400;line-height:1.5rem}.catalog-main .no-results-ctn .no-results-icon{width:6rem;height:6rem;color:var(--appshell-color-secondary-light);margin-bottom:1.25rem}.catalog-main .no-results-ctn .no-results-icon mat-icon{height:6rem;width:6rem}\n"], dependencies: [{ kind: "component", type: AppShellProductCardComponent, selector: "appshell-product-card", inputs: ["title", "description", "image", "labels", "redirectTo"] }, { kind: "ngmodule", type: MatFormFieldModule }, { kind: "ngmodule", type: MatInputModule }, { kind: "ngmodule", type: MatButtonModule }, { kind: "ngmodule", type: MatChipsModule }, { kind: "component", type: AppShellPageHeaderComponent, selector: "appshell-page-header", inputs: ["breadcrumbLinks", "title", "button", "secondaryButton", "picker"], outputs: ["buttonClicked", "secondaryButtonClicked", "pick"] }, { kind: "component", type: AppShellFiltersComponent, selector: "appshell-filters", inputs: ["filters"], outputs: ["activeFiltersChange"] }, { kind: "component", type: AppShellIconComponent, selector: "appshell-icon", inputs: ["icon"] }], encapsulation: i0.ViewEncapsulation.None });
|
|
577
|
+
}
|
|
578
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.11", ngImport: i0, type: AppShellProductCatalogScreenComponent, decorators: [{
|
|
579
|
+
type: Component,
|
|
580
|
+
args: [{ selector: 'appshell-product-catalog-screen', standalone: true, imports: [AppShellProductCardComponent, MatFormFieldModule, MatInputModule, MatButtonModule, MatChipsModule, AppShellPageHeaderComponent, AppShellFiltersComponent, AppShellIconComponent], encapsulation: ViewEncapsulation.None, template: "<appshell-page-header \n [title]=\"pageTitle()\"\n [breadcrumbLinks]=\"breadcrumbLinks()\"></appshell-page-header>\n<appshell-filters\n [filters]=\"filters()\"\n (activeFiltersChange)=\"activeFiltersChange.emit($event)\"></appshell-filters>\n<section class=\"catalog-main\">\n @if(products().length > 0) {\n <div class=\"products-ctn\">\n @for (product of products(); track product.id) {\n <appshell-product-card\n [title]=\"product.title\"\n [description]=\"product.shortDescription\"\n [image]=\"product.image\"\n [labels]=\"getProductLabels(product)\"\n [redirectTo]=\"product.link\"\n ></appshell-product-card>\n }\n </div>\n }\n @if(products().length === 0 && (noProductsHtmlMessage() || noProductsIcon())) {\n <div class=\"no-results-ctn\" role=\"status\" aria-live=\"polite\" tabindex=\"0\">\n @if(noProductsIcon()) {\n <appshell-icon [class]=\"'no-results-icon'\" [icon]=\"noProductsIcon()!\" />\n }\n <div [innerHTML]=\"noProductsHtmlMessage()\"></div>\n </div>\n }\n</section>", styles: ["appshell-product-catalog-screen{display:flex;flex-direction:column;height:100%}.catalog-main{flex:1;background-color:var(--appshell-color-grey-light)}.catalog-main .products-ctn{display:grid;grid-template-columns:repeat(auto-fill,minmax(25rem,1fr));grid-auto-rows:1fr;gap:1.5rem;padding:1.5rem;box-sizing:border-box;max-width:127.5rem}.catalog-main .products-ctn>*{width:100%;min-width:25rem;max-width:35rem}.catalog-main .no-results-ctn{width:100%;height:100%;max-width:120rem;display:flex;flex-direction:column;align-items:center;padding-top:4.5rem;color:var(--appshell-color-secondary-main);text-align:center;font-size:1rem;font-style:normal;font-weight:400;line-height:1.5rem}.catalog-main .no-results-ctn .no-results-icon{width:6rem;height:6rem;color:var(--appshell-color-secondary-light);margin-bottom:1.25rem}.catalog-main .no-results-ctn .no-results-icon mat-icon{height:6rem;width:6rem}\n"] }]
|
|
581
|
+
}] });
|
|
582
|
+
|
|
583
|
+
class AppShellProductViewScreenComponent {
|
|
584
|
+
pageTitle = input.required();
|
|
585
|
+
breadcrumbLinks = input.required();
|
|
586
|
+
actionButton = input();
|
|
587
|
+
actionButtonClicked = output();
|
|
588
|
+
product = input.required();
|
|
589
|
+
secondaryButton = input();
|
|
590
|
+
secondaryButtonClicked = output();
|
|
591
|
+
actionPicker = input();
|
|
592
|
+
actionPick = output();
|
|
593
|
+
productLabels = computed(() => this.product().tags?.flatMap(tag => tag.options) || []);
|
|
594
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.11", ngImport: i0, type: AppShellProductViewScreenComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
595
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.11", type: AppShellProductViewScreenComponent, isStandalone: true, selector: "appshell-product-view-screen", inputs: { pageTitle: { classPropertyName: "pageTitle", publicName: "pageTitle", isSignal: true, isRequired: true, transformFunction: null }, breadcrumbLinks: { classPropertyName: "breadcrumbLinks", publicName: "breadcrumbLinks", isSignal: true, isRequired: true, transformFunction: null }, actionButton: { classPropertyName: "actionButton", publicName: "actionButton", isSignal: true, isRequired: false, transformFunction: null }, product: { classPropertyName: "product", publicName: "product", isSignal: true, isRequired: true, transformFunction: null }, secondaryButton: { classPropertyName: "secondaryButton", publicName: "secondaryButton", isSignal: true, isRequired: false, transformFunction: null }, actionPicker: { classPropertyName: "actionPicker", publicName: "actionPicker", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { actionButtonClicked: "actionButtonClicked", secondaryButtonClicked: "secondaryButtonClicked", actionPick: "actionPick" }, ngImport: i0, template: "<appshell-page-header \n [breadcrumbLinks]=\"breadcrumbLinks()\"\n [title]=\"pageTitle()\"\n [button]=\"actionButton()\"\n (buttonClicked)=\"actionButtonClicked.emit()\"\n [secondaryButton]=\"secondaryButton()\"\n (secondaryButtonClicked)=\"secondaryButtonClicked.emit()\"\n [picker]=\"actionPicker()\"\n (pick)=\"actionPick.emit($event)\"></appshell-page-header>\n<div class=\"product-ctn\">\n @if (product().image) {\n <div class=\"product-img\">\n <img [src]=\"product().image\" [alt]=\"'Product image for ' + product().title\">\n </div>\n }\n <div class=\"product-metadata\">\n <h2>{{ product().title }}</h2>\n <div class=\"subheadline\">\n @if (product().authors && product().authors!.length > 0) {\n <span>{{ product().authors.join(', ') }}</span>\n }\n @if (product().authors && product().authors!.length > 0 && product().date) {\n <div class=\"row-separator\"></div>\n }\n @if (product().date) {\n <span>{{ product().date!.toJSON().slice(0,10) }}</span>\n }\n </div>\n @if (product().tags && product().tags!.length > 0) {\n <div class=\"tags-ctn\">\n <mat-chip-set aria-label=\"Product categories\">\n @for (tag of productLabels(); track tag) {\n <appshell-chip [label]=\"tag\"></appshell-chip>\n }\n </mat-chip-set>\n </div>\n }\n </div>\n <div class=\"description\">\n <markdown\n [data]=\"product().description\"\n [disableSanitizer]=\"true\">\n </markdown>\n </div>\n</div>", styles: [".product-ctn{padding:.5rem 1.5rem 1.5rem;display:flex;flex-direction:column;gap:1.5rem;max-width:50rem}.product-ctn .product-img img{max-height:7.5rem;max-width:7.5rem;aspect-ratio:1;height:fit-content;width:fit-content;min-height:4rem;min-width:4rem}.product-ctn .product-metadata{display:flex;flex-direction:column;gap:.5rem}.product-ctn .product-metadata h2{margin:0;overflow:hidden;color:var(--appshell-color-secondary-main);font-size:1.375rem;font-style:normal;font-weight:500;line-height:150%;letter-spacing:0rem}.product-ctn .product-metadata .subheadline{display:flex;flex-direction:row}.product-ctn .product-metadata .subheadline>span{color:var(--appshell-color-grey-strong);font-size:.875rem;font-style:normal;font-weight:500;line-height:150%;letter-spacing:0rem}.product-ctn .product-metadata .subheadline .row-separator{width:.0625rem;background-color:var(--appshell-color-accent-green-dark);margin:0 .5rem}.product-ctn .product-metadata mat-chip-set>div[role=presentation]{gap:.5rem}.product-ctn .description{line-height:150%;max-width:50rem;color:var(--appshell-color-secondary-main)}.product-ctn .description *{max-width:100%;text-wrap:auto;overflow-wrap:anywhere}\n"], dependencies: [{ kind: "component", type: AppShellPageHeaderComponent, selector: "appshell-page-header", inputs: ["breadcrumbLinks", "title", "button", "secondaryButton", "picker"], outputs: ["buttonClicked", "secondaryButtonClicked", "pick"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "ngmodule", type: MatChipsModule }, { kind: "component", type: i1$2.MatChipSet, selector: "mat-chip-set", inputs: ["disabled", "role", "tabIndex"] }, { kind: "component", type: AppShellChipComponent, selector: "appshell-chip", inputs: ["label"] }, { kind: "component", type: MarkdownComponent, selector: "markdown, [markdown]", inputs: ["data", "src", "disableSanitizer", "inline", "clipboard", "clipboardButtonComponent", "clipboardButtonTemplate", "emoji", "katex", "katexOptions", "mermaid", "mermaidOptions", "lineHighlight", "line", "lineOffset", "lineNumbers", "start", "commandLine", "filterOutput", "host", "prompt", "output", "user"], outputs: ["error", "load", "ready"] }], encapsulation: i0.ViewEncapsulation.None });
|
|
596
|
+
}
|
|
597
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.11", ngImport: i0, type: AppShellProductViewScreenComponent, decorators: [{
|
|
598
|
+
type: Component,
|
|
599
|
+
args: [{ selector: 'appshell-product-view-screen', standalone: true, imports: [AppShellPageHeaderComponent, MatButtonModule, MatChipsModule, AppShellChipComponent, MarkdownComponent], encapsulation: ViewEncapsulation.None, template: "<appshell-page-header \n [breadcrumbLinks]=\"breadcrumbLinks()\"\n [title]=\"pageTitle()\"\n [button]=\"actionButton()\"\n (buttonClicked)=\"actionButtonClicked.emit()\"\n [secondaryButton]=\"secondaryButton()\"\n (secondaryButtonClicked)=\"secondaryButtonClicked.emit()\"\n [picker]=\"actionPicker()\"\n (pick)=\"actionPick.emit($event)\"></appshell-page-header>\n<div class=\"product-ctn\">\n @if (product().image) {\n <div class=\"product-img\">\n <img [src]=\"product().image\" [alt]=\"'Product image for ' + product().title\">\n </div>\n }\n <div class=\"product-metadata\">\n <h2>{{ product().title }}</h2>\n <div class=\"subheadline\">\n @if (product().authors && product().authors!.length > 0) {\n <span>{{ product().authors.join(', ') }}</span>\n }\n @if (product().authors && product().authors!.length > 0 && product().date) {\n <div class=\"row-separator\"></div>\n }\n @if (product().date) {\n <span>{{ product().date!.toJSON().slice(0,10) }}</span>\n }\n </div>\n @if (product().tags && product().tags!.length > 0) {\n <div class=\"tags-ctn\">\n <mat-chip-set aria-label=\"Product categories\">\n @for (tag of productLabels(); track tag) {\n <appshell-chip [label]=\"tag\"></appshell-chip>\n }\n </mat-chip-set>\n </div>\n }\n </div>\n <div class=\"description\">\n <markdown\n [data]=\"product().description\"\n [disableSanitizer]=\"true\">\n </markdown>\n </div>\n</div>", styles: [".product-ctn{padding:.5rem 1.5rem 1.5rem;display:flex;flex-direction:column;gap:1.5rem;max-width:50rem}.product-ctn .product-img img{max-height:7.5rem;max-width:7.5rem;aspect-ratio:1;height:fit-content;width:fit-content;min-height:4rem;min-width:4rem}.product-ctn .product-metadata{display:flex;flex-direction:column;gap:.5rem}.product-ctn .product-metadata h2{margin:0;overflow:hidden;color:var(--appshell-color-secondary-main);font-size:1.375rem;font-style:normal;font-weight:500;line-height:150%;letter-spacing:0rem}.product-ctn .product-metadata .subheadline{display:flex;flex-direction:row}.product-ctn .product-metadata .subheadline>span{color:var(--appshell-color-grey-strong);font-size:.875rem;font-style:normal;font-weight:500;line-height:150%;letter-spacing:0rem}.product-ctn .product-metadata .subheadline .row-separator{width:.0625rem;background-color:var(--appshell-color-accent-green-dark);margin:0 .5rem}.product-ctn .product-metadata mat-chip-set>div[role=presentation]{gap:.5rem}.product-ctn .description{line-height:150%;max-width:50rem;color:var(--appshell-color-secondary-main)}.product-ctn .description *{max-width:100%;text-wrap:auto;overflow-wrap:anywhere}\n"] }]
|
|
600
|
+
}] });
|
|
601
|
+
|
|
602
|
+
class AppShellNotificationsScreenComponent {
|
|
603
|
+
markdownService;
|
|
604
|
+
pageTitle = input.required();
|
|
605
|
+
breadcrumbLinks = input.required();
|
|
606
|
+
notifications = input.required();
|
|
607
|
+
computedNotifications = computed(() => {
|
|
608
|
+
return this.notifications().map((notification) => {
|
|
609
|
+
notification.expanded = this.expandedNotifications.includes(notification.id);
|
|
610
|
+
if (notification.message) {
|
|
611
|
+
const parsed = this.markdownService.parse(notification.message.replace(/\\n/g, '\n'), { markedOptions: { gfm: true, breaks: false } });
|
|
612
|
+
notification.message = parsed;
|
|
613
|
+
}
|
|
614
|
+
return notification;
|
|
615
|
+
});
|
|
616
|
+
});
|
|
617
|
+
readNotification = output();
|
|
618
|
+
readAllNotifications = output();
|
|
619
|
+
expandedNotifications = [];
|
|
620
|
+
constructor(markdownService) {
|
|
621
|
+
this.markdownService = markdownService;
|
|
622
|
+
}
|
|
623
|
+
getIcon(notification) {
|
|
624
|
+
if (notification.type === 'success') {
|
|
625
|
+
return 'check_circle';
|
|
626
|
+
}
|
|
627
|
+
if (notification.type === 'error') {
|
|
628
|
+
return 'x_circle';
|
|
629
|
+
}
|
|
630
|
+
// Default to info
|
|
631
|
+
return 'info';
|
|
632
|
+
}
|
|
633
|
+
getIconClasses(notification) {
|
|
634
|
+
if (notification.type === 'success') {
|
|
635
|
+
return 'notification success';
|
|
636
|
+
}
|
|
637
|
+
if (notification.type === 'error') {
|
|
638
|
+
return 'notification error';
|
|
639
|
+
}
|
|
640
|
+
return 'notification';
|
|
641
|
+
}
|
|
642
|
+
expandNotification(notification) {
|
|
643
|
+
const index = this.expandedNotifications.indexOf(notification.id);
|
|
644
|
+
if (index === -1) {
|
|
645
|
+
this.expandedNotifications.push(notification.id);
|
|
646
|
+
}
|
|
647
|
+
else {
|
|
648
|
+
this.expandedNotifications.splice(index, 1);
|
|
649
|
+
}
|
|
650
|
+
}
|
|
651
|
+
isNotificationExpanded(notification) {
|
|
652
|
+
return this.expandedNotifications.includes(notification.id);
|
|
653
|
+
}
|
|
654
|
+
markAsRead(notification) {
|
|
655
|
+
this.readNotification.emit(notification);
|
|
656
|
+
}
|
|
657
|
+
markAllAsRead() {
|
|
658
|
+
this.readAllNotifications.emit();
|
|
659
|
+
}
|
|
660
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.11", ngImport: i0, type: AppShellNotificationsScreenComponent, deps: [{ token: i1$6.MarkdownService }], target: i0.ɵɵFactoryTarget.Component });
|
|
661
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.11", type: AppShellNotificationsScreenComponent, isStandalone: true, selector: "appshell-notifications-screen", inputs: { pageTitle: { classPropertyName: "pageTitle", publicName: "pageTitle", isSignal: true, isRequired: true, transformFunction: null }, breadcrumbLinks: { classPropertyName: "breadcrumbLinks", publicName: "breadcrumbLinks", isSignal: true, isRequired: true, transformFunction: null }, notifications: { classPropertyName: "notifications", publicName: "notifications", isSignal: true, isRequired: true, transformFunction: null } }, outputs: { readNotification: "readNotification", readAllNotifications: "readAllNotifications" }, ngImport: i0, template: "<appshell-page-header \n [breadcrumbLinks]=\"breadcrumbLinks()\"\n [title]=\"pageTitle()\"></appshell-page-header>\n<div class=\"notifications-ctn\">\n <button class=\"mark-all-read-btn\" mat-button (click)=\"markAllAsRead()\">Mark all as read</button>\n @for (notification of computedNotifications(); track notification.date) {\n <div class=\"notification-ctn\" [class.unread]=\"!notification.read\" (click)=\"markAsRead(notification)\">\n <div class=\"notification-icon\">\n <appshell-icon [icon]=\"getIcon(notification)\" [class]=\"getIconClasses(notification)\" />\n </div>\n <div class=\"notification-content\">\n <span class=\"notification-title\">{{ notification.title }}</span>\n <span class=\"notification-body\" [class.expanded]=\"notification.expanded\">\n @if (notification.message && notification.message.length > 80) {\n @if (notification.expanded) {\n <span [innerHTML]=\"notification.message\"></span>\n } @else {\n <span [innerHTML]=\"notification.message | slice:0:70\" class=\"sliced-message\"></span>...\n }\n <span class=\"read-more-less\" (click)=\"expandNotification(notification)\">{{ notification.expanded ? 'Show less' : 'Read more' }}</span>\n } @else {\n <span [innerHTML]=\"notification.message\"></span>\n }\n </span>\n </div>\n <span class=\"notification-date\">{{ notification.date | date:'dd/MM/YY' }}</span>\n </div>\n }\n</div>", styles: [".notifications-ctn{box-sizing:border-box;padding:0 1.5rem 1.5rem;width:50rem}.notifications-ctn .mark-all-read-btn{display:block;margin-left:auto;margin-bottom:1rem;color:var(--appshell-color-secondary-main);font-family:AppShellTextFont;font-size:.875rem;font-style:normal;font-weight:500;line-height:1.25rem;text-decoration-line:underline;text-decoration-color:var(--appshell-color-accent-green-main);text-decoration-thickness:3px;text-underline-offset:6px;--mat-text-button-hover-state-layer-opacity: 0;--mat-text-button-focus-state-layer-opacity: 0;--mat-text-button-pressed-state-layer-opacity: 0;--mat-text-button-ripple-color: transparent}.notifications-ctn .mark-all-read-btn:hover{color:var(--appshell-color-secondary-medium);background-color:transparent;text-decoration-color:var(--appshell-color-accent-green-medium)}.notifications-ctn .notification-ctn{border-top:1px solid #B7B6B2;padding:1rem;box-sizing:border-box;display:flex;flex-direction:row;gap:.75rem;background-color:transparent}.notifications-ctn .notification-ctn:hover{background-color:var(--appshell-color-tertiary-neutral)}.notifications-ctn .notification-ctn:last-of-type{border-bottom:1px solid #B7B6B2}.notifications-ctn .notification-ctn.unread{background-color:var(--appshell-color-sky-blue-light)}.notifications-ctn .notification-ctn.unread:hover{background-color:var(--appshell-color-sky-blue-medium)}.notifications-ctn .notification-ctn .notification-icon .notification{color:#0069e5}.notifications-ctn .notification-ctn .notification-icon .notification.success{color:#168215}.notifications-ctn .notification-ctn .notification-icon .notification.error{color:#e10a0a}.notifications-ctn .notification-ctn .notification-content{width:100%;display:flex;flex-direction:column;gap:.75rem}.notifications-ctn .notification-ctn .notification-content .notification-title{color:var(--appshell-color-secondary-main);font-family:AppShellHeadingFont;font-size:1rem;font-style:normal;font-weight:400;line-height:1.5rem;word-break:break-word}.notifications-ctn .notification-ctn .notification-content .notification-body{color:var(--appshell-color-secondary-main);font-family:AppShellTextFont;font-size:.875rem;font-style:normal;font-weight:400;line-height:1.5rem;letter-spacing:.00625rem;word-break:break-word}.notifications-ctn .notification-ctn .notification-content .notification-body .sliced-message{display:inline-flex}.notifications-ctn .notification-ctn .notification-content .notification-body .read-more-less{color:#0069e5;margin-left:.2rem;display:inline}.notifications-ctn .notification-ctn .notification-content .notification-body .read-more-less:hover{cursor:pointer;text-decoration:underline}.notifications-ctn .notification-ctn .notification-content .notification-body.expanded .read-more-less{margin-left:0;display:block}.notifications-ctn .notification-ctn .notification-date{color:var(--appshell-color-secondary-main);font-family:AppShellTextFont;font-size:.875rem;font-style:normal;font-weight:400;line-height:1.5rem}\n"], dependencies: [{ kind: "component", type: AppShellPageHeaderComponent, selector: "appshell-page-header", inputs: ["breadcrumbLinks", "title", "button", "secondaryButton", "picker"], outputs: ["buttonClicked", "secondaryButtonClicked", "pick"] }, { kind: "pipe", type: DatePipe, name: "date" }, { kind: "pipe", type: SlicePipe, name: "slice" }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i1$3.MatButton, selector: " button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ", exportAs: ["matButton"] }, { kind: "component", type: AppShellIconComponent, selector: "appshell-icon", inputs: ["icon"] }] });
|
|
662
|
+
}
|
|
663
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.11", ngImport: i0, type: AppShellNotificationsScreenComponent, decorators: [{
|
|
664
|
+
type: Component,
|
|
665
|
+
args: [{ selector: 'appshell-notifications-screen', standalone: true, imports: [AppShellPageHeaderComponent, DatePipe, SlicePipe, MatButtonModule, AppShellIconComponent], template: "<appshell-page-header \n [breadcrumbLinks]=\"breadcrumbLinks()\"\n [title]=\"pageTitle()\"></appshell-page-header>\n<div class=\"notifications-ctn\">\n <button class=\"mark-all-read-btn\" mat-button (click)=\"markAllAsRead()\">Mark all as read</button>\n @for (notification of computedNotifications(); track notification.date) {\n <div class=\"notification-ctn\" [class.unread]=\"!notification.read\" (click)=\"markAsRead(notification)\">\n <div class=\"notification-icon\">\n <appshell-icon [icon]=\"getIcon(notification)\" [class]=\"getIconClasses(notification)\" />\n </div>\n <div class=\"notification-content\">\n <span class=\"notification-title\">{{ notification.title }}</span>\n <span class=\"notification-body\" [class.expanded]=\"notification.expanded\">\n @if (notification.message && notification.message.length > 80) {\n @if (notification.expanded) {\n <span [innerHTML]=\"notification.message\"></span>\n } @else {\n <span [innerHTML]=\"notification.message | slice:0:70\" class=\"sliced-message\"></span>...\n }\n <span class=\"read-more-less\" (click)=\"expandNotification(notification)\">{{ notification.expanded ? 'Show less' : 'Read more' }}</span>\n } @else {\n <span [innerHTML]=\"notification.message\"></span>\n }\n </span>\n </div>\n <span class=\"notification-date\">{{ notification.date | date:'dd/MM/YY' }}</span>\n </div>\n }\n</div>", styles: [".notifications-ctn{box-sizing:border-box;padding:0 1.5rem 1.5rem;width:50rem}.notifications-ctn .mark-all-read-btn{display:block;margin-left:auto;margin-bottom:1rem;color:var(--appshell-color-secondary-main);font-family:AppShellTextFont;font-size:.875rem;font-style:normal;font-weight:500;line-height:1.25rem;text-decoration-line:underline;text-decoration-color:var(--appshell-color-accent-green-main);text-decoration-thickness:3px;text-underline-offset:6px;--mat-text-button-hover-state-layer-opacity: 0;--mat-text-button-focus-state-layer-opacity: 0;--mat-text-button-pressed-state-layer-opacity: 0;--mat-text-button-ripple-color: transparent}.notifications-ctn .mark-all-read-btn:hover{color:var(--appshell-color-secondary-medium);background-color:transparent;text-decoration-color:var(--appshell-color-accent-green-medium)}.notifications-ctn .notification-ctn{border-top:1px solid #B7B6B2;padding:1rem;box-sizing:border-box;display:flex;flex-direction:row;gap:.75rem;background-color:transparent}.notifications-ctn .notification-ctn:hover{background-color:var(--appshell-color-tertiary-neutral)}.notifications-ctn .notification-ctn:last-of-type{border-bottom:1px solid #B7B6B2}.notifications-ctn .notification-ctn.unread{background-color:var(--appshell-color-sky-blue-light)}.notifications-ctn .notification-ctn.unread:hover{background-color:var(--appshell-color-sky-blue-medium)}.notifications-ctn .notification-ctn .notification-icon .notification{color:#0069e5}.notifications-ctn .notification-ctn .notification-icon .notification.success{color:#168215}.notifications-ctn .notification-ctn .notification-icon .notification.error{color:#e10a0a}.notifications-ctn .notification-ctn .notification-content{width:100%;display:flex;flex-direction:column;gap:.75rem}.notifications-ctn .notification-ctn .notification-content .notification-title{color:var(--appshell-color-secondary-main);font-family:AppShellHeadingFont;font-size:1rem;font-style:normal;font-weight:400;line-height:1.5rem;word-break:break-word}.notifications-ctn .notification-ctn .notification-content .notification-body{color:var(--appshell-color-secondary-main);font-family:AppShellTextFont;font-size:.875rem;font-style:normal;font-weight:400;line-height:1.5rem;letter-spacing:.00625rem;word-break:break-word}.notifications-ctn .notification-ctn .notification-content .notification-body .sliced-message{display:inline-flex}.notifications-ctn .notification-ctn .notification-content .notification-body .read-more-less{color:#0069e5;margin-left:.2rem;display:inline}.notifications-ctn .notification-ctn .notification-content .notification-body .read-more-less:hover{cursor:pointer;text-decoration:underline}.notifications-ctn .notification-ctn .notification-content .notification-body.expanded .read-more-less{margin-left:0;display:block}.notifications-ctn .notification-ctn .notification-date{color:var(--appshell-color-secondary-main);font-family:AppShellTextFont;font-size:.875rem;font-style:normal;font-weight:400;line-height:1.5rem}\n"] }]
|
|
666
|
+
}], ctorParameters: () => [{ type: i1$6.MarkdownService }] });
|
|
667
|
+
|
|
668
|
+
class IconRegistryService {
|
|
669
|
+
matIconRegistry;
|
|
670
|
+
sanitizer;
|
|
671
|
+
namespace = 'appshell';
|
|
672
|
+
http;
|
|
673
|
+
constructor(httpBackend, matIconRegistry, sanitizer) {
|
|
674
|
+
this.matIconRegistry = matIconRegistry;
|
|
675
|
+
this.sanitizer = sanitizer;
|
|
676
|
+
this.http = new HttpClient(httpBackend);
|
|
677
|
+
}
|
|
678
|
+
registerIconsFromManifest(manifestUrl = 'assets/icons/icons.json') {
|
|
679
|
+
return new Promise((resolve) => {
|
|
680
|
+
this.http.get(manifestUrl).subscribe({
|
|
681
|
+
next: (manifest) => {
|
|
682
|
+
const basePath = manifestUrl.substring(0, manifestUrl.lastIndexOf('/') + 1);
|
|
683
|
+
if (Array.isArray(manifest)) {
|
|
684
|
+
manifest
|
|
685
|
+
.filter((f) => typeof f === 'string' && f.endsWith('.svg'))
|
|
686
|
+
.forEach((file) => {
|
|
687
|
+
const iconName = file.replace(/\.svg$/i, '');
|
|
688
|
+
const url = basePath + file;
|
|
689
|
+
this.matIconRegistry.addSvgIconInNamespace(this.namespace, iconName, this.sanitizer.bypassSecurityTrustResourceUrl(url));
|
|
690
|
+
});
|
|
691
|
+
}
|
|
692
|
+
else if (manifest && typeof manifest === 'object') {
|
|
693
|
+
Object.entries(manifest).forEach(([iconName, relativePath]) => {
|
|
694
|
+
if (typeof relativePath !== 'string' || !relativePath.endsWith('.svg')) {
|
|
695
|
+
return;
|
|
696
|
+
}
|
|
697
|
+
const isAbsolute = /^https?:\/\//i.test(relativePath);
|
|
698
|
+
const url = isAbsolute ? relativePath : basePath + relativePath;
|
|
699
|
+
this.matIconRegistry.addSvgIconInNamespace(this.namespace, iconName, this.sanitizer.bypassSecurityTrustResourceUrl(url));
|
|
700
|
+
});
|
|
701
|
+
}
|
|
702
|
+
resolve();
|
|
703
|
+
},
|
|
704
|
+
error: () => {
|
|
705
|
+
resolve();
|
|
706
|
+
},
|
|
707
|
+
});
|
|
708
|
+
});
|
|
709
|
+
}
|
|
710
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.11", ngImport: i0, type: IconRegistryService, deps: [{ token: i1$7.HttpBackend }, { token: i1$1.MatIconRegistry }, { token: i3$1.DomSanitizer }], target: i0.ɵɵFactoryTarget.Injectable });
|
|
711
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.2.11", ngImport: i0, type: IconRegistryService, providedIn: 'root' });
|
|
712
|
+
}
|
|
713
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.11", ngImport: i0, type: IconRegistryService, decorators: [{
|
|
714
|
+
type: Injectable,
|
|
715
|
+
args: [{ providedIn: 'root' }]
|
|
716
|
+
}], ctorParameters: () => [{ type: i1$7.HttpBackend }, { type: i1$1.MatIconRegistry }, { type: i3$1.DomSanitizer }] });
|
|
717
|
+
|
|
718
|
+
/*
|
|
719
|
+
* Public API Surface of ngx-appshell
|
|
720
|
+
*/
|
|
721
|
+
|
|
722
|
+
/**
|
|
723
|
+
* Generated bundle index. Do not edit.
|
|
724
|
+
*/
|
|
725
|
+
|
|
726
|
+
export { AppShellBreadcrumbComponent, AppShellChipComponent, AppShellFiltersComponent, AppShellHeaderComponent, AppShellIconComponent, AppShellLayoutComponent, AppShellLinkDirective, AppShellNotificationsScreenComponent, AppShellPageHeaderComponent, AppShellPlatformHeaderComponent, AppShellPlatformLayoutComponent, AppShellProductCardComponent, AppShellProductCardV2Component, AppShellProductCatalogScreenComponent, AppShellProductViewScreenComponent, AppShellSelectComponent, AppShellSidebarMenuComponent, AppShellToastComponent, AppShellToastService, AppShellToastsComponent, IconRegistryService };
|
|
727
|
+
//# sourceMappingURL=opendevstack-ngx-appshell.mjs.map
|