@flusys/ng-layout 5.1.3 → 5.3.0
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.
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
|
-
import { inject, PLATFORM_ID, Injectable, DOCUMENT, signal, computed, effect, Component,
|
|
2
|
+
import { inject, PLATFORM_ID, Injectable, DOCUMENT, signal, computed, effect, Component, InjectionToken, input, DestroyRef, viewChild, ElementRef, Renderer2 } from '@angular/core';
|
|
3
3
|
import * as i2$3 from '@flusys/ng-shared';
|
|
4
|
-
import { evaluateLogicNode, PermissionValidatorService, TranslatePipe, TranslateService, IconComponent, AngularModule, PrimeModule } from '@flusys/ng-shared';
|
|
4
|
+
import { evaluateLogicNode, PermissionValidatorService, InlineSvgComponent, TranslatePipe, TranslateService, IconComponent, AngularModule, PrimeModule } from '@flusys/ng-shared';
|
|
5
5
|
import { isPlatformBrowser, NgComponentOutlet, DOCUMENT as DOCUMENT$1, NgClass } from '@angular/common';
|
|
6
6
|
import { APP_CONFIG, DEFAULT_APP_NAME, DEFAULT_AUTHOR, isCompanyFeatureEnabled, isSignUpEnabled } from '@flusys/ng-core';
|
|
7
7
|
import { Subject, fromEvent, filter as filter$1 } from 'rxjs';
|
|
@@ -9,7 +9,7 @@ import * as i1 from '@angular/forms';
|
|
|
9
9
|
import { FormsModule } from '@angular/forms';
|
|
10
10
|
import * as i1$2 from '@angular/router';
|
|
11
11
|
import { Router, NavigationEnd, RouterModule } from '@angular/router';
|
|
12
|
-
import { updatePreset, updateSurfacePalette, $t
|
|
12
|
+
import { definePreset, updatePreset, updateSurfacePalette, $t } from '@primeuix/themes';
|
|
13
13
|
import Aura from '@primeuix/themes/aura';
|
|
14
14
|
import Lara from '@primeuix/themes/lara';
|
|
15
15
|
import Nora from '@primeuix/themes/nora';
|
|
@@ -92,36 +92,11 @@ function filterMenuItem(item, permissionCode) {
|
|
|
92
92
|
|
|
93
93
|
const STORAGE_KEY = 'flusys.layout.config';
|
|
94
94
|
const STORAGE_VERSION = 1;
|
|
95
|
-
/**
|
|
96
|
-
* Service for persisting layout configuration to localStorage.
|
|
97
|
-
* Handles loading, saving, and validation of layout preferences with SSR-safe checks.
|
|
98
|
-
*
|
|
99
|
-
* @example
|
|
100
|
-
* ```typescript
|
|
101
|
-
* const persistence = inject(LayoutPersistenceService);
|
|
102
|
-
*
|
|
103
|
-
* // Load saved config
|
|
104
|
-
* const config = persistence.load();
|
|
105
|
-
*
|
|
106
|
-
* // Save config
|
|
107
|
-
* persistence.save({ darkTheme: true, preset: 'Aura' });
|
|
108
|
-
*
|
|
109
|
-
* // Clear saved config
|
|
110
|
-
* persistence.clear();
|
|
111
|
-
* ```
|
|
112
|
-
*/
|
|
113
95
|
class LayoutPersistenceService {
|
|
114
96
|
platformId = inject(PLATFORM_ID);
|
|
115
97
|
isBrowser = isPlatformBrowser(this.platformId);
|
|
116
98
|
validPresets = ['Aura', 'Lara', 'Nora'];
|
|
117
99
|
validMenuModes = ['static', 'overlay', 'topbar'];
|
|
118
|
-
/**
|
|
119
|
-
* Load configuration from localStorage.
|
|
120
|
-
* Returns null if no saved config or invalid data.
|
|
121
|
-
* SSR-safe (returns null on server).
|
|
122
|
-
*
|
|
123
|
-
* @returns Validated layout configuration or null
|
|
124
|
-
*/
|
|
125
100
|
load() {
|
|
126
101
|
if (!this.isBrowser)
|
|
127
102
|
return null;
|
|
@@ -137,12 +112,6 @@ class LayoutPersistenceService {
|
|
|
137
112
|
return null;
|
|
138
113
|
}
|
|
139
114
|
}
|
|
140
|
-
/**
|
|
141
|
-
* Save configuration to localStorage.
|
|
142
|
-
* SSR-safe (no-op on server).
|
|
143
|
-
*
|
|
144
|
-
* @param config Layout configuration to save
|
|
145
|
-
*/
|
|
146
115
|
save(config) {
|
|
147
116
|
if (!this.isBrowser)
|
|
148
117
|
return;
|
|
@@ -157,41 +126,25 @@ class LayoutPersistenceService {
|
|
|
157
126
|
// Silent fail - localStorage may be full or disabled
|
|
158
127
|
}
|
|
159
128
|
}
|
|
160
|
-
/**
|
|
161
|
-
* Clear stored configuration.
|
|
162
|
-
* SSR-safe (no-op on server).
|
|
163
|
-
*/
|
|
164
129
|
clear() {
|
|
165
130
|
if (!this.isBrowser)
|
|
166
131
|
return;
|
|
167
132
|
localStorage.removeItem(STORAGE_KEY);
|
|
168
133
|
}
|
|
169
|
-
/**
|
|
170
|
-
* Validate and sanitize configuration.
|
|
171
|
-
* Returns null if version mismatch.
|
|
172
|
-
*
|
|
173
|
-
* @param config Configuration to validate
|
|
174
|
-
* @returns Validated configuration or null
|
|
175
|
-
*/
|
|
176
134
|
validateConfig(config) {
|
|
177
|
-
// Version mismatch - clear and return null
|
|
178
135
|
if (config._version && config._version !== STORAGE_VERSION) {
|
|
179
136
|
this.clear();
|
|
180
137
|
return null;
|
|
181
138
|
}
|
|
182
|
-
// Validate preset - silently fix invalid values
|
|
183
139
|
if (config.preset && !this.validPresets.includes(config.preset)) {
|
|
184
140
|
config.preset = 'Aura';
|
|
185
141
|
}
|
|
186
|
-
// Validate menuMode - silently fix invalid values
|
|
187
142
|
if (config.menuMode && !this.validMenuModes.includes(config.menuMode)) {
|
|
188
143
|
config.menuMode = 'static';
|
|
189
144
|
}
|
|
190
|
-
// Validate darkTheme
|
|
191
145
|
if (typeof config.darkTheme !== 'boolean') {
|
|
192
146
|
config.darkTheme = false;
|
|
193
147
|
}
|
|
194
|
-
// Remove version field from returned config
|
|
195
148
|
const { _version, ...cleanConfig } = config;
|
|
196
149
|
return cleanConfig;
|
|
197
150
|
}
|
|
@@ -200,21 +153,18 @@ class LayoutPersistenceService {
|
|
|
200
153
|
}
|
|
201
154
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.5", ngImport: i0, type: LayoutPersistenceService, decorators: [{
|
|
202
155
|
type: Injectable,
|
|
203
|
-
args: [{
|
|
204
|
-
providedIn: 'root',
|
|
205
|
-
}]
|
|
156
|
+
args: [{ providedIn: 'root' }]
|
|
206
157
|
}] });
|
|
207
158
|
|
|
208
|
-
/** Layout configuration and state management service */
|
|
209
159
|
class LayoutService {
|
|
210
160
|
document = inject(DOCUMENT);
|
|
211
161
|
platformId = inject(PLATFORM_ID);
|
|
212
162
|
isBrowser = isPlatformBrowser(this.platformId);
|
|
213
163
|
persistence = inject(LayoutPersistenceService);
|
|
214
164
|
appConfig = inject(APP_CONFIG, { optional: true });
|
|
215
|
-
DEFAULT_CONFIG = {
|
|
165
|
+
DEFAULT_CONFIG = this.appConfig?.layoutConfig ?? {
|
|
216
166
|
preset: 'Aura',
|
|
217
|
-
primary: '
|
|
167
|
+
primary: 'violet',
|
|
218
168
|
surface: null,
|
|
219
169
|
darkTheme: false,
|
|
220
170
|
menuMode: 'static',
|
|
@@ -227,9 +177,10 @@ class LayoutService {
|
|
|
227
177
|
menuHoverActive: false,
|
|
228
178
|
topbarMenuVisible: true,
|
|
229
179
|
};
|
|
180
|
+
memorable = this.DEFAULT_CONFIG.isMemorable !== false;
|
|
230
181
|
_layoutConfig = signal({
|
|
231
182
|
...this.DEFAULT_CONFIG,
|
|
232
|
-
...this.persistence.load(),
|
|
183
|
+
...(this.memorable ? this.persistence.load() : null),
|
|
233
184
|
}, ...(ngDevMode ? [{ debugName: "_layoutConfig" }] : []));
|
|
234
185
|
_layoutState = signal(this.DEFAULT_STATE, ...(ngDevMode ? [{ debugName: "_layoutState" }] : []));
|
|
235
186
|
_transitionComplete = signal(false, ...(ngDevMode ? [{ debugName: "_transitionComplete" }] : []));
|
|
@@ -243,24 +194,19 @@ class LayoutService {
|
|
|
243
194
|
permissionValidator = inject(PermissionValidatorService);
|
|
244
195
|
userProfile = this._userProfile.asReadonly();
|
|
245
196
|
companyProfile = this._companyProfile.asReadonly();
|
|
246
|
-
// Static app info from config
|
|
247
197
|
appName = this.appConfig?.appName ?? DEFAULT_APP_NAME;
|
|
248
198
|
appLogo = this.appConfig?.appLogo ?? '';
|
|
199
|
+
isAppLogoSvg = this.appLogo.toLowerCase().endsWith('.svg');
|
|
249
200
|
authorName = this.appConfig?.author?.name ?? DEFAULT_AUTHOR.name;
|
|
250
201
|
authorUrl = this.appConfig?.author?.url ?? DEFAULT_AUTHOR.url;
|
|
251
|
-
// Permission-filtered menu and apps
|
|
252
202
|
menu = computed(() => filterMenuByPermissions(this._rawMenu(), this.permissionValidator.permissions()), ...(ngDevMode ? [{ debugName: "menu" }] : []));
|
|
253
203
|
apps = computed(() => filterAppsByPermissions(this._rawApps(), this.permissionValidator.permissions()), ...(ngDevMode ? [{ debugName: "apps" }] : []));
|
|
254
204
|
hasApps = computed(() => this.apps().length > 0, ...(ngDevMode ? [{ debugName: "hasApps" }] : []));
|
|
255
|
-
// Computed signals - Layout
|
|
256
205
|
isSidebarActive = computed(() => this._layoutState().overlayMenuActive ||
|
|
257
206
|
this._layoutState().staticMenuMobileActive, ...(ngDevMode ? [{ debugName: "isSidebarActive" }] : []));
|
|
258
207
|
isDarkTheme = computed(() => this._layoutConfig().darkTheme, ...(ngDevMode ? [{ debugName: "isDarkTheme" }] : []));
|
|
259
|
-
getPrimary = computed(() => this._layoutConfig().primary, ...(ngDevMode ? [{ debugName: "getPrimary" }] : []));
|
|
260
|
-
getSurface = computed(() => this._layoutConfig().surface, ...(ngDevMode ? [{ debugName: "getSurface" }] : []));
|
|
261
208
|
isOverlay = computed(() => this._layoutConfig().menuMode === 'overlay', ...(ngDevMode ? [{ debugName: "isOverlay" }] : []));
|
|
262
209
|
isTopbar = computed(() => this._layoutConfig().menuMode === 'topbar', ...(ngDevMode ? [{ debugName: "isTopbar" }] : []));
|
|
263
|
-
// User profile computed signals
|
|
264
210
|
userName = computed(() => this._userProfile()?.name ?? 'Guest', ...(ngDevMode ? [{ debugName: "userName" }] : []));
|
|
265
211
|
userEmail = computed(() => this._userProfile()?.email ?? '', ...(ngDevMode ? [{ debugName: "userEmail" }] : []));
|
|
266
212
|
userProfilePictureUrl = computed(() => this._userProfile()?.profilePictureUrl ?? null, ...(ngDevMode ? [{ debugName: "userProfilePictureUrl" }] : []));
|
|
@@ -272,23 +218,21 @@ class LayoutService {
|
|
|
272
218
|
return this._companyProfile()?.name ?? this.appName;
|
|
273
219
|
}, ...(ngDevMode ? [{ debugName: "companyName" }] : []));
|
|
274
220
|
displayLogo = computed(() => this.companyLogoUrl() ?? this.appLogo, ...(ngDevMode ? [{ debugName: "displayLogo" }] : []));
|
|
275
|
-
|
|
276
|
-
configUpdate = new Subject();
|
|
221
|
+
isDisplayLogoSvg = computed(() => this.displayLogo().toLowerCase().endsWith('.svg'), ...(ngDevMode ? [{ debugName: "isDisplayLogoSvg" }] : []));
|
|
277
222
|
overlayOpen = new Subject();
|
|
278
223
|
menuSource = new Subject();
|
|
279
224
|
resetSource = new Subject();
|
|
280
225
|
menuSource$ = this.menuSource.asObservable();
|
|
281
226
|
resetSource$ = this.resetSource.asObservable();
|
|
282
|
-
configUpdate$ = this.configUpdate.asObservable();
|
|
283
227
|
overlayOpen$ = this.overlayOpen.asObservable();
|
|
284
228
|
initialized = false;
|
|
285
229
|
constructor() {
|
|
286
230
|
effect(() => {
|
|
287
231
|
const config = this._layoutConfig();
|
|
288
|
-
this.configUpdate.next(config);
|
|
289
232
|
if (this.initialized) {
|
|
290
233
|
this.handleDarkModeTransition(config);
|
|
291
|
-
this.
|
|
234
|
+
if (this.memorable)
|
|
235
|
+
this.persistence.save(config);
|
|
292
236
|
}
|
|
293
237
|
this.initialized = true;
|
|
294
238
|
});
|
|
@@ -365,21 +309,18 @@ class LayoutService {
|
|
|
365
309
|
reset() {
|
|
366
310
|
this.resetSource.next(true);
|
|
367
311
|
}
|
|
368
|
-
// Config & state updates
|
|
369
312
|
updateLayoutConfig(config) {
|
|
370
313
|
this._layoutConfig.update((prev) => ({ ...prev, ...config }));
|
|
371
314
|
}
|
|
372
315
|
updateLayoutState(state) {
|
|
373
316
|
this._layoutState.update((prev) => ({ ...prev, ...state }));
|
|
374
317
|
}
|
|
375
|
-
// Profile setters
|
|
376
318
|
setUserProfile(profile) {
|
|
377
319
|
this._userProfile.set(profile);
|
|
378
320
|
}
|
|
379
321
|
setCompanyProfile(profile) {
|
|
380
322
|
this._companyProfile.set(profile);
|
|
381
323
|
}
|
|
382
|
-
// Menu & apps
|
|
383
324
|
setMenu(items) {
|
|
384
325
|
this._rawMenu.set(items);
|
|
385
326
|
}
|
|
@@ -404,12 +345,17 @@ class AppFooter {
|
|
|
404
345
|
layoutService = inject(LayoutService);
|
|
405
346
|
appName = this.layoutService.appName;
|
|
406
347
|
displayLogo = this.layoutService.appLogo;
|
|
348
|
+
isLogoSvg = this.layoutService.isAppLogoSvg;
|
|
407
349
|
authorName = this.layoutService.authorName;
|
|
408
350
|
authorUrl = this.layoutService.authorUrl;
|
|
409
351
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.5", ngImport: i0, type: AppFooter, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
410
352
|
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.5", type: AppFooter, isStandalone: true, selector: "app-footer", ngImport: i0, template: `<div class="layout-footer">
|
|
411
353
|
@if (displayLogo) {
|
|
412
|
-
|
|
354
|
+
@if (isLogoSvg) {
|
|
355
|
+
<inline-svg [src]="displayLogo" class="logo-image" />
|
|
356
|
+
} @else {
|
|
357
|
+
<img [src]="displayLogo" [alt]="appName" class="logo-image" />
|
|
358
|
+
}
|
|
413
359
|
}
|
|
414
360
|
<span class="hidden sm:inline">
|
|
415
361
|
{{ appName }} {{ 'layout.footer.by' | translate }}
|
|
@@ -421,16 +367,20 @@ class AppFooter {
|
|
|
421
367
|
>{{ authorName }}</a
|
|
422
368
|
>
|
|
423
369
|
</span>
|
|
424
|
-
</div>`, isInline: true, dependencies: [{ kind: "pipe", type: TranslatePipe, name: "translate" }] });
|
|
370
|
+
</div>`, isInline: true, dependencies: [{ kind: "component", type: InlineSvgComponent, selector: "inline-svg", inputs: ["src"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }] });
|
|
425
371
|
}
|
|
426
372
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.5", ngImport: i0, type: AppFooter, decorators: [{
|
|
427
373
|
type: Component,
|
|
428
374
|
args: [{
|
|
429
375
|
selector: 'app-footer',
|
|
430
|
-
imports: [TranslatePipe],
|
|
376
|
+
imports: [TranslatePipe, InlineSvgComponent],
|
|
431
377
|
template: `<div class="layout-footer">
|
|
432
378
|
@if (displayLogo) {
|
|
433
|
-
|
|
379
|
+
@if (isLogoSvg) {
|
|
380
|
+
<inline-svg [src]="displayLogo" class="logo-image" />
|
|
381
|
+
} @else {
|
|
382
|
+
<img [src]="displayLogo" [alt]="appName" class="logo-image" />
|
|
383
|
+
}
|
|
434
384
|
}
|
|
435
385
|
<span class="hidden sm:inline">
|
|
436
386
|
{{ appName }} {{ 'layout.footer.by' | translate }}
|
|
@@ -446,6 +396,82 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.5", ngImpor
|
|
|
446
396
|
}]
|
|
447
397
|
}] });
|
|
448
398
|
|
|
399
|
+
const _presets = { Aura, Lara, Nora };
|
|
400
|
+
const _noirPrimary = {
|
|
401
|
+
50: '{surface.50}', 100: '{surface.100}', 200: '{surface.200}',
|
|
402
|
+
300: '{surface.300}', 400: '{surface.400}', 500: '{surface.500}',
|
|
403
|
+
600: '{surface.600}', 700: '{surface.700}', 800: '{surface.800}',
|
|
404
|
+
900: '{surface.900}', 950: '{surface.950}',
|
|
405
|
+
};
|
|
406
|
+
const _noraScheme = {
|
|
407
|
+
light: {
|
|
408
|
+
primary: { color: '{primary.600}', contrastColor: '#ffffff', hoverColor: '{primary.700}', activeColor: '{primary.800}' },
|
|
409
|
+
highlight: { background: '{primary.600}', focusBackground: '{primary.700}', color: '#ffffff', focusColor: '#ffffff' },
|
|
410
|
+
},
|
|
411
|
+
dark: {
|
|
412
|
+
primary: { color: '{primary.500}', contrastColor: '{surface.900}', hoverColor: '{primary.400}', activeColor: '{primary.300}' },
|
|
413
|
+
highlight: { background: '{primary.500}', focusBackground: '{primary.400}', color: '{surface.900}', focusColor: '{surface.900}' },
|
|
414
|
+
},
|
|
415
|
+
};
|
|
416
|
+
const _defaultScheme = {
|
|
417
|
+
light: {
|
|
418
|
+
primary: { color: '{primary.500}', contrastColor: '#ffffff', hoverColor: '{primary.600}', activeColor: '{primary.700}' },
|
|
419
|
+
highlight: { background: '{primary.50}', focusBackground: '{primary.100}', color: '{primary.700}', focusColor: '{primary.800}' },
|
|
420
|
+
},
|
|
421
|
+
dark: {
|
|
422
|
+
primary: { color: '{primary.400}', contrastColor: '{surface.900}', hoverColor: '{primary.300}', activeColor: '{primary.200}' },
|
|
423
|
+
highlight: {
|
|
424
|
+
background: 'color-mix(in srgb, {primary.400}, transparent 84%)',
|
|
425
|
+
focusBackground: 'color-mix(in srgb, {primary.400}, transparent 76%)',
|
|
426
|
+
color: 'rgba(255,255,255,.87)',
|
|
427
|
+
focusColor: 'rgba(255,255,255,.87)',
|
|
428
|
+
},
|
|
429
|
+
},
|
|
430
|
+
};
|
|
431
|
+
function buildSemanticExt(palette, presetName) {
|
|
432
|
+
if (palette === null) {
|
|
433
|
+
return {
|
|
434
|
+
semantic: {
|
|
435
|
+
primary: _noirPrimary,
|
|
436
|
+
colorScheme: {
|
|
437
|
+
light: {
|
|
438
|
+
primary: { color: '{primary.950}', contrastColor: '#ffffff', hoverColor: '{primary.800}', activeColor: '{primary.700}' },
|
|
439
|
+
highlight: { background: '{primary.950}', focusBackground: '{primary.700}', color: '#ffffff', focusColor: '#ffffff' },
|
|
440
|
+
},
|
|
441
|
+
dark: {
|
|
442
|
+
primary: { color: '{primary.50}', contrastColor: '{primary.950}', hoverColor: '{primary.200}', activeColor: '{primary.300}' },
|
|
443
|
+
highlight: { background: '{primary.50}', focusBackground: '{primary.300}', color: '{primary.950}', focusColor: '{primary.950}' },
|
|
444
|
+
},
|
|
445
|
+
},
|
|
446
|
+
},
|
|
447
|
+
};
|
|
448
|
+
}
|
|
449
|
+
return { semantic: { primary: palette, colorScheme: presetName === 'Nora' ? _noraScheme : _defaultScheme } };
|
|
450
|
+
}
|
|
451
|
+
function buildPreset(presetName, primary) {
|
|
452
|
+
const base = _presets[presetName in _presets ? presetName : 'Aura'];
|
|
453
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
454
|
+
const palette = primary === 'noir' ? null : base.primitive?.[primary];
|
|
455
|
+
if (primary !== 'noir' && !palette)
|
|
456
|
+
return base;
|
|
457
|
+
return definePreset(base, buildSemanticExt(palette, presetName));
|
|
458
|
+
}
|
|
459
|
+
function buildBootstrapPreset(envConfig) {
|
|
460
|
+
const preset = envConfig?.preset ?? 'Aura';
|
|
461
|
+
const primary = envConfig?.primary ?? 'violet';
|
|
462
|
+
if (envConfig?.isMemorable !== false) {
|
|
463
|
+
try {
|
|
464
|
+
const stored = localStorage.getItem('flusys.layout.config');
|
|
465
|
+
if (stored) {
|
|
466
|
+
const parsed = JSON.parse(stored);
|
|
467
|
+
return buildPreset(parsed.preset ?? preset, parsed.primary ?? primary);
|
|
468
|
+
}
|
|
469
|
+
}
|
|
470
|
+
catch { /* SSR or storage disabled */ }
|
|
471
|
+
}
|
|
472
|
+
return buildPreset(preset, primary);
|
|
473
|
+
}
|
|
474
|
+
|
|
449
475
|
const presets = {
|
|
450
476
|
Aura,
|
|
451
477
|
Lara,
|
|
@@ -453,9 +479,8 @@ const presets = {
|
|
|
453
479
|
};
|
|
454
480
|
class AppConfigurator {
|
|
455
481
|
router = inject(Router);
|
|
456
|
-
translateAdapter = inject(TranslateService, {
|
|
457
|
-
|
|
458
|
-
});
|
|
482
|
+
translateAdapter = inject(TranslateService, { optional: true });
|
|
483
|
+
platformId = inject(PLATFORM_ID);
|
|
459
484
|
layoutService = inject(LayoutService);
|
|
460
485
|
presets = Object.keys(presets);
|
|
461
486
|
showMenuModeButton = signal(!this.router.url.includes('auth'), ...(ngDevMode ? [{ debugName: "showMenuModeButton" }] : []));
|
|
@@ -470,7 +495,6 @@ class AppConfigurator {
|
|
|
470
495
|
value: 'overlay',
|
|
471
496
|
},
|
|
472
497
|
];
|
|
473
|
-
// Only show topbar mode on desktop
|
|
474
498
|
if (this.layoutService.isDesktop()) {
|
|
475
499
|
options.push({
|
|
476
500
|
label: this.translate('layout.configurator.menu.mode.topbar'),
|
|
@@ -480,11 +504,10 @@ class AppConfigurator {
|
|
|
480
504
|
return options;
|
|
481
505
|
}, ...(ngDevMode ? [{ debugName: "menuModeOptions" }] : []));
|
|
482
506
|
constructor() {
|
|
483
|
-
|
|
484
|
-
afterNextRender(() => {
|
|
507
|
+
if (isPlatformBrowser(this.platformId)) {
|
|
485
508
|
const preset = this.layoutService.layoutConfig().preset ?? 'Aura';
|
|
486
509
|
this.onPresetChange(preset);
|
|
487
|
-
}
|
|
510
|
+
}
|
|
488
511
|
}
|
|
489
512
|
surfaces = [
|
|
490
513
|
{
|
|
@@ -624,9 +647,7 @@ class AppConfigurator {
|
|
|
624
647
|
},
|
|
625
648
|
},
|
|
626
649
|
];
|
|
627
|
-
selectedPrimaryColor = computed(() => {
|
|
628
|
-
return this.layoutService.layoutConfig().primary;
|
|
629
|
-
}, ...(ngDevMode ? [{ debugName: "selectedPrimaryColor" }] : []));
|
|
650
|
+
selectedPrimaryColor = computed(() => this.layoutService.layoutConfig().primary, ...(ngDevMode ? [{ debugName: "selectedPrimaryColor" }] : []));
|
|
630
651
|
selectedSurfaceColor = computed(() => this.layoutService.layoutConfig().surface, ...(ngDevMode ? [{ debugName: "selectedSurfaceColor" }] : []));
|
|
631
652
|
isSurfaceSelected(surfaceName) {
|
|
632
653
|
const selectedSurface = this.selectedSurfaceColor();
|
|
@@ -670,133 +691,10 @@ class AppConfigurator {
|
|
|
670
691
|
return palettes;
|
|
671
692
|
}, ...(ngDevMode ? [{ debugName: "primaryColors" }] : []));
|
|
672
693
|
getPresetExt() {
|
|
673
|
-
const color = this.primaryColors().find(
|
|
674
|
-
const preset = this.layoutService.layoutConfig().preset;
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
semantic: {
|
|
678
|
-
primary: {
|
|
679
|
-
50: '{surface.50}',
|
|
680
|
-
100: '{surface.100}',
|
|
681
|
-
200: '{surface.200}',
|
|
682
|
-
300: '{surface.300}',
|
|
683
|
-
400: '{surface.400}',
|
|
684
|
-
500: '{surface.500}',
|
|
685
|
-
600: '{surface.600}',
|
|
686
|
-
700: '{surface.700}',
|
|
687
|
-
800: '{surface.800}',
|
|
688
|
-
900: '{surface.900}',
|
|
689
|
-
950: '{surface.950}',
|
|
690
|
-
},
|
|
691
|
-
colorScheme: {
|
|
692
|
-
light: {
|
|
693
|
-
primary: {
|
|
694
|
-
color: '{primary.950}',
|
|
695
|
-
contrastColor: '#ffffff',
|
|
696
|
-
hoverColor: '{primary.800}',
|
|
697
|
-
activeColor: '{primary.700}',
|
|
698
|
-
},
|
|
699
|
-
highlight: {
|
|
700
|
-
background: '{primary.950}',
|
|
701
|
-
focusBackground: '{primary.700}',
|
|
702
|
-
color: '#ffffff',
|
|
703
|
-
focusColor: '#ffffff',
|
|
704
|
-
},
|
|
705
|
-
},
|
|
706
|
-
dark: {
|
|
707
|
-
primary: {
|
|
708
|
-
color: '{primary.50}',
|
|
709
|
-
contrastColor: '{primary.950}',
|
|
710
|
-
hoverColor: '{primary.200}',
|
|
711
|
-
activeColor: '{primary.300}',
|
|
712
|
-
},
|
|
713
|
-
highlight: {
|
|
714
|
-
background: '{primary.50}',
|
|
715
|
-
focusBackground: '{primary.300}',
|
|
716
|
-
color: '{primary.950}',
|
|
717
|
-
focusColor: '{primary.950}',
|
|
718
|
-
},
|
|
719
|
-
},
|
|
720
|
-
},
|
|
721
|
-
},
|
|
722
|
-
};
|
|
723
|
-
}
|
|
724
|
-
else {
|
|
725
|
-
if (preset === 'Nora') {
|
|
726
|
-
return {
|
|
727
|
-
semantic: {
|
|
728
|
-
primary: color.palette,
|
|
729
|
-
colorScheme: {
|
|
730
|
-
light: {
|
|
731
|
-
primary: {
|
|
732
|
-
color: '{primary.600}',
|
|
733
|
-
contrastColor: '#ffffff',
|
|
734
|
-
hoverColor: '{primary.700}',
|
|
735
|
-
activeColor: '{primary.800}',
|
|
736
|
-
},
|
|
737
|
-
highlight: {
|
|
738
|
-
background: '{primary.600}',
|
|
739
|
-
focusBackground: '{primary.700}',
|
|
740
|
-
color: '#ffffff',
|
|
741
|
-
focusColor: '#ffffff',
|
|
742
|
-
},
|
|
743
|
-
},
|
|
744
|
-
dark: {
|
|
745
|
-
primary: {
|
|
746
|
-
color: '{primary.500}',
|
|
747
|
-
contrastColor: '{surface.900}',
|
|
748
|
-
hoverColor: '{primary.400}',
|
|
749
|
-
activeColor: '{primary.300}',
|
|
750
|
-
},
|
|
751
|
-
highlight: {
|
|
752
|
-
background: '{primary.500}',
|
|
753
|
-
focusBackground: '{primary.400}',
|
|
754
|
-
color: '{surface.900}',
|
|
755
|
-
focusColor: '{surface.900}',
|
|
756
|
-
},
|
|
757
|
-
},
|
|
758
|
-
},
|
|
759
|
-
},
|
|
760
|
-
};
|
|
761
|
-
}
|
|
762
|
-
else {
|
|
763
|
-
return {
|
|
764
|
-
semantic: {
|
|
765
|
-
primary: color.palette,
|
|
766
|
-
colorScheme: {
|
|
767
|
-
light: {
|
|
768
|
-
primary: {
|
|
769
|
-
color: '{primary.500}',
|
|
770
|
-
contrastColor: '#ffffff',
|
|
771
|
-
hoverColor: '{primary.600}',
|
|
772
|
-
activeColor: '{primary.700}',
|
|
773
|
-
},
|
|
774
|
-
highlight: {
|
|
775
|
-
background: '{primary.50}',
|
|
776
|
-
focusBackground: '{primary.100}',
|
|
777
|
-
color: '{primary.700}',
|
|
778
|
-
focusColor: '{primary.800}',
|
|
779
|
-
},
|
|
780
|
-
},
|
|
781
|
-
dark: {
|
|
782
|
-
primary: {
|
|
783
|
-
color: '{primary.400}',
|
|
784
|
-
contrastColor: '{surface.900}',
|
|
785
|
-
hoverColor: '{primary.300}',
|
|
786
|
-
activeColor: '{primary.200}',
|
|
787
|
-
},
|
|
788
|
-
highlight: {
|
|
789
|
-
background: 'color-mix(in srgb, {primary.400}, transparent 84%)',
|
|
790
|
-
focusBackground: 'color-mix(in srgb, {primary.400}, transparent 76%)',
|
|
791
|
-
color: 'rgba(255,255,255,.87)',
|
|
792
|
-
focusColor: 'rgba(255,255,255,.87)',
|
|
793
|
-
},
|
|
794
|
-
},
|
|
795
|
-
},
|
|
796
|
-
},
|
|
797
|
-
};
|
|
798
|
-
}
|
|
799
|
-
}
|
|
694
|
+
const color = this.primaryColors().find(c => c.name === this.selectedPrimaryColor()) ?? {};
|
|
695
|
+
const preset = this.layoutService.layoutConfig().preset ?? 'Aura';
|
|
696
|
+
const palette = color.name === 'noir' ? null : (color.palette ?? {});
|
|
697
|
+
return buildSemanticExt(palette, preset);
|
|
800
698
|
}
|
|
801
699
|
updateColors(event, type, color) {
|
|
802
700
|
if (type === 'primary') {
|
|
@@ -2555,7 +2453,15 @@ class AppTopbar {
|
|
|
2555
2453
|
}
|
|
2556
2454
|
<a class="layout-topbar-logo" routerLink="/">
|
|
2557
2455
|
@if (displayLogo()) {
|
|
2558
|
-
|
|
2456
|
+
@if (layoutService.isDisplayLogoSvg()) {
|
|
2457
|
+
<inline-svg [src]="displayLogo()" class="logo-image" />
|
|
2458
|
+
} @else {
|
|
2459
|
+
<img
|
|
2460
|
+
[src]="displayLogo()"
|
|
2461
|
+
[alt]="companyName()"
|
|
2462
|
+
class="logo-image"
|
|
2463
|
+
/>
|
|
2464
|
+
}
|
|
2559
2465
|
}
|
|
2560
2466
|
<span class="hidden sm:inline">{{ companyName() }}</span>
|
|
2561
2467
|
</a>
|
|
@@ -2649,7 +2555,7 @@ class AppTopbar {
|
|
|
2649
2555
|
</div>
|
|
2650
2556
|
</div>
|
|
2651
2557
|
</div>
|
|
2652
|
-
</div>`, isInline: true, dependencies: [{ kind: "ngmodule", type: RouterModule }, { kind: "directive", type: i1$2.RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "routerLink"] }, { kind: "ngmodule", type: StyleClassModule }, { kind: "directive", type: i2$1.StyleClass, selector: "[pStyleClass]", inputs: ["pStyleClass", "enterFromClass", "enterActiveClass", "enterToClass", "leaveFromClass", "leaveActiveClass", "leaveToClass", "hideOnOutsideClick", "toggleClass", "hideOnEscape", "hideOnResize", "resizeSelector"] }, { kind: "directive", type: NgComponentOutlet, selector: "[ngComponentOutlet]", inputs: ["ngComponentOutlet", "ngComponentOutletInputs", "ngComponentOutletInjector", "ngComponentOutletEnvironmentInjector", "ngComponentOutletContent", "ngComponentOutletNgModule"], exportAs: ["ngComponentOutlet"] }, { kind: "component", type: AppConfigurator, selector: "app-configurator" }, { kind: "component", type: AppMenu, selector: "app-menu" }, { kind: "component", type: AppProfile, selector: "app-profile" }, { kind: "component", type: AppCompanyBranchSelector, selector: "app-company-branch-selector" }, { kind: "component", type: AppLauncher, selector: "app-launcher" }, { kind: "component", type: AppSearchbar, selector: "app-searchbar" }, { kind: "pipe", type: TranslatePipe, name: "translate" }] });
|
|
2558
|
+
</div>`, isInline: true, dependencies: [{ kind: "ngmodule", type: RouterModule }, { kind: "directive", type: i1$2.RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "routerLink"] }, { kind: "ngmodule", type: StyleClassModule }, { kind: "directive", type: i2$1.StyleClass, selector: "[pStyleClass]", inputs: ["pStyleClass", "enterFromClass", "enterActiveClass", "enterToClass", "leaveFromClass", "leaveActiveClass", "leaveToClass", "hideOnOutsideClick", "toggleClass", "hideOnEscape", "hideOnResize", "resizeSelector"] }, { kind: "directive", type: NgComponentOutlet, selector: "[ngComponentOutlet]", inputs: ["ngComponentOutlet", "ngComponentOutletInputs", "ngComponentOutletInjector", "ngComponentOutletEnvironmentInjector", "ngComponentOutletContent", "ngComponentOutletNgModule"], exportAs: ["ngComponentOutlet"] }, { kind: "component", type: InlineSvgComponent, selector: "inline-svg", inputs: ["src"] }, { kind: "component", type: AppConfigurator, selector: "app-configurator" }, { kind: "component", type: AppMenu, selector: "app-menu" }, { kind: "component", type: AppProfile, selector: "app-profile" }, { kind: "component", type: AppCompanyBranchSelector, selector: "app-company-branch-selector" }, { kind: "component", type: AppLauncher, selector: "app-launcher" }, { kind: "component", type: AppSearchbar, selector: "app-searchbar" }, { kind: "pipe", type: TranslatePipe, name: "translate" }] });
|
|
2653
2559
|
}
|
|
2654
2560
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.5", ngImport: i0, type: AppTopbar, decorators: [{
|
|
2655
2561
|
type: Component,
|
|
@@ -2660,6 +2566,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.5", ngImpor
|
|
|
2660
2566
|
StyleClassModule,
|
|
2661
2567
|
NgComponentOutlet,
|
|
2662
2568
|
TranslatePipe,
|
|
2569
|
+
InlineSvgComponent,
|
|
2663
2570
|
AppConfigurator,
|
|
2664
2571
|
AppMenu,
|
|
2665
2572
|
AppProfile,
|
|
@@ -2683,7 +2590,15 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.5", ngImpor
|
|
|
2683
2590
|
}
|
|
2684
2591
|
<a class="layout-topbar-logo" routerLink="/">
|
|
2685
2592
|
@if (displayLogo()) {
|
|
2686
|
-
|
|
2593
|
+
@if (layoutService.isDisplayLogoSvg()) {
|
|
2594
|
+
<inline-svg [src]="displayLogo()" class="logo-image" />
|
|
2595
|
+
} @else {
|
|
2596
|
+
<img
|
|
2597
|
+
[src]="displayLogo()"
|
|
2598
|
+
[alt]="companyName()"
|
|
2599
|
+
class="logo-image"
|
|
2600
|
+
/>
|
|
2601
|
+
}
|
|
2687
2602
|
}
|
|
2688
2603
|
<span class="hidden sm:inline">{{ companyName() }}</span>
|
|
2689
2604
|
</a>
|
|
@@ -2997,8 +2912,13 @@ const LAYOUT_MESSAGES = {
|
|
|
2997
2912
|
'menu.forms': 'Forms',
|
|
2998
2913
|
'menu.email': 'Email',
|
|
2999
2914
|
'menu.event.manager': 'Event Manager',
|
|
2915
|
+
'menu.task.manager': 'Task Manager',
|
|
3000
2916
|
'menu.notifications': 'Notifications',
|
|
3001
2917
|
'menu.localization': 'Localization',
|
|
2918
|
+
'menu.projects': 'Projects',
|
|
2919
|
+
'menu.projects.active': 'Active Projects',
|
|
2920
|
+
'menu.projects.archived': 'Archived',
|
|
2921
|
+
'menu.projects.reports': 'Reports',
|
|
3002
2922
|
// Those are layout part from notification module, but we put them here to avoid circular dependency between layout and notification module
|
|
3003
2923
|
// components/notification-bell/notification-bell.component.ts
|
|
3004
2924
|
'notification.title': 'Notifications',
|
|
@@ -3019,5 +2939,5 @@ const LAYOUT_MESSAGES = {
|
|
|
3019
2939
|
* Generated bundle index. Do not edit.
|
|
3020
2940
|
*/
|
|
3021
2941
|
|
|
3022
|
-
export { AppCompanyBranchSelector, AppConfigurator, AppFloatingConfigurator, AppFooter, AppLauncher, AppLayout, AppMenu, AppMenuitem, AppProfile, AppSearchbar, AppSidebar, AppTopbar, GreenTheme, LAYOUT_AUTH_API, LAYOUT_AUTH_STATE, LAYOUT_IS_RTL, LAYOUT_LANGUAGE_SELECTOR, LAYOUT_LANGUAGE_SELECTOR_PANEL, LAYOUT_MESSAGES, LAYOUT_NOTIFICATION_BELL, LAYOUT_SEARCHBAR, LAYOUT_SEARCH_ADAPTER, LayoutPersistenceService, LayoutService, NavyBlueTheme, filterAppsByPermissions, filterMenuByPermissions };
|
|
2942
|
+
export { AppCompanyBranchSelector, AppConfigurator, AppFloatingConfigurator, AppFooter, AppLauncher, AppLayout, AppMenu, AppMenuitem, AppProfile, AppSearchbar, AppSidebar, AppTopbar, GreenTheme, LAYOUT_AUTH_API, LAYOUT_AUTH_STATE, LAYOUT_IS_RTL, LAYOUT_LANGUAGE_SELECTOR, LAYOUT_LANGUAGE_SELECTOR_PANEL, LAYOUT_MESSAGES, LAYOUT_NOTIFICATION_BELL, LAYOUT_SEARCHBAR, LAYOUT_SEARCH_ADAPTER, LayoutPersistenceService, LayoutService, NavyBlueTheme, buildBootstrapPreset, buildPreset, buildSemanticExt, filterAppsByPermissions, filterMenuByPermissions };
|
|
3023
2943
|
//# sourceMappingURL=flusys-ng-layout.mjs.map
|