@flusys/ng-layout 1.0.0-rc → 1.0.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.
package/README.md CHANGED
@@ -708,5 +708,5 @@ Layout automatically handles responsive behavior. Ensure you're using the `AppLa
708
708
 
709
709
  ---
710
710
 
711
- **Last Updated:** 2026-02-18
711
+ **Last Updated:** 2026-02-21
712
712
  **Angular Version:** 21
@@ -1,6 +1,10 @@
1
- import { isPlatformBrowser, NgClass, DOCUMENT as DOCUMENT$1 } from '@angular/common';
2
1
  import * as i0 from '@angular/core';
3
- import { inject, PLATFORM_ID, Injectable, DOCUMENT, signal, computed, effect, afterNextRender, ChangeDetectionStrategy, Component, InjectionToken, DestroyRef, ElementRef, viewChild, input, Renderer2 } from '@angular/core';
2
+ import { inject, PLATFORM_ID, Injectable, DOCUMENT, signal, computed, effect, ChangeDetectionStrategy, Component, afterNextRender, InjectionToken, DestroyRef, ElementRef, viewChild, input, Renderer2 } from '@angular/core';
3
+ import { isPlatformBrowser, NgClass, DOCUMENT as DOCUMENT$1 } from '@angular/common';
4
+ import { APP_CONFIG, DEFAULT_APP_NAME, DEFAULT_AUTHOR, isCompanyFeatureEnabled } from '@flusys/ng-core';
5
+ import * as i2$2 from '@flusys/ng-shared';
6
+ import { evaluateLogicNode, PermissionValidatorService, AngularModule, IconComponent } from '@flusys/ng-shared';
7
+ import { Subject, fromEvent, filter as filter$1 } from 'rxjs';
4
8
  import * as i1 from '@angular/forms';
5
9
  import { FormsModule } from '@angular/forms';
6
10
  import * as i1$2 from '@angular/router';
@@ -11,10 +15,6 @@ import Lara from '@primeuix/themes/lara';
11
15
  import Nora from '@primeuix/themes/nora';
12
16
  import * as i2 from 'primeng/selectbutton';
13
17
  import { SelectButtonModule } from 'primeng/selectbutton';
14
- import { APP_CONFIG, DEFAULT_APP_NAME, DEFAULT_AUTHOR, isCompanyFeatureEnabled } from '@flusys/ng-core';
15
- import * as i2$2 from '@flusys/ng-shared';
16
- import { evaluateLogicNode, PermissionValidatorService, AngularModule, IconComponent } from '@flusys/ng-shared';
17
- import { Subject, fromEvent, filter as filter$1 } from 'rxjs';
18
18
  import * as i1$1 from 'primeng/button';
19
19
  import { ButtonModule } from 'primeng/button';
20
20
  import * as i2$1 from 'primeng/styleclass';
@@ -202,80 +202,51 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.3", ngImpor
202
202
  }]
203
203
  }] });
204
204
 
205
- /**
206
- * Service managing layout configuration and state.
207
- * Provides signals for reactive layout updates.
208
- */
205
+ /** Layout configuration and state management service */
209
206
  class LayoutService {
210
207
  document = inject(DOCUMENT);
211
208
  platformId = inject(PLATFORM_ID);
212
209
  isBrowser = isPlatformBrowser(this.platformId);
213
210
  persistence = inject(LayoutPersistenceService);
214
211
  appConfig = inject(APP_CONFIG, { optional: true });
215
- defaultConfig = {
212
+ DEFAULT_CONFIG = {
216
213
  preset: 'Aura',
217
214
  primary: 'emerald',
218
215
  surface: null,
219
216
  darkTheme: false,
220
217
  menuMode: 'static',
221
218
  };
222
- // Load persisted config merged with defaults
223
- initialConfig = (() => {
224
- const persisted = this.persistence.load();
225
- return persisted
226
- ? { ...this.defaultConfig, ...persisted }
227
- : this.defaultConfig;
228
- })();
229
- defaultState = {
219
+ DEFAULT_STATE = {
230
220
  staticMenuDesktopInactive: false,
231
221
  overlayMenuActive: false,
232
222
  configSidebarVisible: false,
233
223
  staticMenuMobileActive: false,
234
224
  menuHoverActive: false,
235
225
  };
236
- // Private writable signals with public readonly accessors
237
- _layoutConfig = signal(this.initialConfig, ...(ngDevMode ? [{ debugName: "_layoutConfig" }] : []));
238
- _layoutState = signal(this.defaultState, ...(ngDevMode ? [{ debugName: "_layoutState" }] : []));
226
+ _layoutConfig = signal({
227
+ ...this.DEFAULT_CONFIG,
228
+ ...this.persistence.load(),
229
+ }, ...(ngDevMode ? [{ debugName: "_layoutConfig" }] : []));
230
+ _layoutState = signal(this.DEFAULT_STATE, ...(ngDevMode ? [{ debugName: "_layoutState" }] : []));
239
231
  _transitionComplete = signal(false, ...(ngDevMode ? [{ debugName: "_transitionComplete" }] : []));
240
232
  layoutConfig = this._layoutConfig.asReadonly();
241
233
  layoutState = this._layoutState.asReadonly();
242
234
  transitionComplete = this._transitionComplete.asReadonly();
243
- // User Profile Signals (private writable, public readonly)
244
235
  _userProfile = signal(null, ...(ngDevMode ? [{ debugName: "_userProfile" }] : []));
245
236
  _companyProfile = signal(null, ...(ngDevMode ? [{ debugName: "_companyProfile" }] : []));
246
- _appName = signal(this.appConfig?.appName ?? DEFAULT_APP_NAME, ...(ngDevMode ? [{ debugName: "_appName" }] : []));
247
- userProfile = this._userProfile.asReadonly();
248
- companyProfile = this._companyProfile.asReadonly();
249
- appName = this._appName.asReadonly();
250
- // Author/Brand Signals (private writable, public readonly)
251
- _authorName = signal(this.appConfig?.author?.name ?? DEFAULT_AUTHOR.name, ...(ngDevMode ? [{ debugName: "_authorName" }] : []));
252
- _authorUrl = signal(this.appConfig?.author?.url ?? DEFAULT_AUTHOR.url, ...(ngDevMode ? [{ debugName: "_authorUrl" }] : []));
253
- authorName = this._authorName.asReadonly();
254
- authorUrl = this._authorUrl.asReadonly();
255
- // App Launcher Signals
256
- _rawApps = signal([], ...(ngDevMode ? [{ debugName: "_rawApps" }] : []));
257
- /**
258
- * Filtered launcher apps based on user permissions.
259
- * Automatically recomputes when raw apps or permissions change.
260
- */
261
- apps = computed(() => {
262
- const raw = this._rawApps();
263
- const permission = this.permissionValidator.permissions();
264
- return filterAppsByPermissions(raw, permission);
265
- }, ...(ngDevMode ? [{ debugName: "apps" }] : []));
266
- // Menu Signals
267
237
  _rawMenu = signal([], ...(ngDevMode ? [{ debugName: "_rawMenu" }] : []));
238
+ _rawApps = signal([], ...(ngDevMode ? [{ debugName: "_rawApps" }] : []));
268
239
  permissionValidator = inject(PermissionValidatorService);
269
- /**
270
- * Filtered menu items based on user permissions.
271
- * Automatically recomputes when raw menu or permission checker changes.
272
- * Role checker is optional - if not set, role-based permissions will be denied.
273
- */
274
- menu = computed(() => {
275
- const raw = this._rawMenu(); // Track permission changes
276
- const permission = this.permissionValidator.permissions();
277
- return filterMenuByPermissions(raw, permission);
278
- }, ...(ngDevMode ? [{ debugName: "menu" }] : []));
240
+ userProfile = this._userProfile.asReadonly();
241
+ companyProfile = this._companyProfile.asReadonly();
242
+ // Static app info from config
243
+ appName = this.appConfig?.appName ?? DEFAULT_APP_NAME;
244
+ authorName = this.appConfig?.author?.name ?? DEFAULT_AUTHOR.name;
245
+ authorUrl = this.appConfig?.author?.url ?? DEFAULT_AUTHOR.url;
246
+ // Permission-filtered menu and apps
247
+ menu = computed(() => filterMenuByPermissions(this._rawMenu(), this.permissionValidator.permissions()), ...(ngDevMode ? [{ debugName: "menu" }] : []));
248
+ apps = computed(() => filterAppsByPermissions(this._rawApps(), this.permissionValidator.permissions()), ...(ngDevMode ? [{ debugName: "apps" }] : []));
249
+ hasApps = computed(() => this.apps().length > 0, ...(ngDevMode ? [{ debugName: "hasApps" }] : []));
279
250
  // Computed signals - Layout
280
251
  isSidebarActive = computed(() => this._layoutState().overlayMenuActive ||
281
252
  this._layoutState().staticMenuMobileActive, ...(ngDevMode ? [{ debugName: "isSidebarActive" }] : []));
@@ -283,21 +254,17 @@ class LayoutService {
283
254
  getPrimary = computed(() => this._layoutConfig().primary, ...(ngDevMode ? [{ debugName: "getPrimary" }] : []));
284
255
  getSurface = computed(() => this._layoutConfig().surface, ...(ngDevMode ? [{ debugName: "getSurface" }] : []));
285
256
  isOverlay = computed(() => this._layoutConfig().menuMode === 'overlay', ...(ngDevMode ? [{ debugName: "isOverlay" }] : []));
286
- // Computed signals - User Profile
257
+ // User profile computed signals
287
258
  userName = computed(() => this._userProfile()?.name ?? 'User', ...(ngDevMode ? [{ debugName: "userName" }] : []));
288
259
  userEmail = computed(() => this._userProfile()?.email ?? '', ...(ngDevMode ? [{ debugName: "userEmail" }] : []));
289
260
  userProfilePictureUrl = computed(() => this._userProfile()?.profilePictureUrl ?? null, ...(ngDevMode ? [{ debugName: "userProfilePictureUrl" }] : []));
290
- companyName = computed(() => {
291
- // If company feature is disabled, always show app name
292
- if (!this.appConfig || !isCompanyFeatureEnabled(this.appConfig)) {
293
- return this._appName();
294
- }
295
- return this._companyProfile()?.name ?? this._appName();
296
- }, ...(ngDevMode ? [{ debugName: "companyName" }] : []));
297
261
  companyLogoUrl = computed(() => this._companyProfile()?.logoUrl ?? null, ...(ngDevMode ? [{ debugName: "companyLogoUrl" }] : []));
298
262
  isAuthenticated = computed(() => !!this._userProfile(), ...(ngDevMode ? [{ debugName: "isAuthenticated" }] : []));
299
- // Computed signals - App Launcher
300
- hasApps = computed(() => this.apps().length > 0, ...(ngDevMode ? [{ debugName: "hasApps" }] : []));
263
+ companyName = computed(() => {
264
+ if (!this.appConfig || !isCompanyFeatureEnabled(this.appConfig))
265
+ return this.appName;
266
+ return this._companyProfile()?.name ?? this.appName;
267
+ }, ...(ngDevMode ? [{ debugName: "companyName" }] : []));
301
268
  // RxJS Subjects for event communication
302
269
  configUpdate = new Subject();
303
270
  overlayOpen = new Subject();
@@ -311,80 +278,55 @@ class LayoutService {
311
278
  constructor() {
312
279
  effect(() => {
313
280
  const config = this._layoutConfig();
314
- if (config) {
315
- this.onConfigUpdate();
316
- }
317
- });
318
- effect(() => {
319
- const config = this._layoutConfig();
320
- if (!this.initialized || !config) {
321
- this.initialized = true;
322
- return;
323
- }
324
- this.handleDarkModeTransition(config);
325
- });
326
- // Auto-save configuration changes to localStorage
327
- effect(() => {
328
- const config = this._layoutConfig();
329
- if (config && this.initialized) {
281
+ this.configUpdate.next(config);
282
+ if (this.initialized) {
283
+ this.handleDarkModeTransition(config);
330
284
  this.persistence.save(config);
331
285
  }
286
+ this.initialized = true;
332
287
  });
333
288
  }
289
+ toggleDarkMode(config) {
290
+ const isDark = (config ?? this._layoutConfig()).darkTheme;
291
+ this.document.documentElement.classList.toggle('app-dark', isDark);
292
+ }
334
293
  handleDarkModeTransition(config) {
335
294
  const doc = this.document;
336
- // Check for View Transitions API support (not all browsers support it)
337
295
  if ('startViewTransition' in doc && typeof doc.startViewTransition === 'function') {
338
- this.startViewTransition(config, doc);
296
+ doc
297
+ .startViewTransition(() => this.toggleDarkMode(config))
298
+ .ready.then(() => this.onTransitionEnd())
299
+ .catch(() => { });
339
300
  }
340
301
  else {
341
302
  this.toggleDarkMode(config);
342
303
  this.onTransitionEnd();
343
304
  }
344
305
  }
345
- startViewTransition(config, doc) {
346
- const transition = doc.startViewTransition(() => {
347
- this.toggleDarkMode(config);
348
- });
349
- transition.ready.then(() => this.onTransitionEnd()).catch(() => { });
350
- }
351
- toggleDarkMode(config) {
352
- const _config = config || this._layoutConfig();
353
- if (_config.darkTheme) {
354
- this.document.documentElement.classList.add('app-dark');
355
- }
356
- else {
357
- this.document.documentElement.classList.remove('app-dark');
358
- }
359
- }
360
306
  onTransitionEnd() {
361
307
  this._transitionComplete.set(true);
362
308
  setTimeout(() => this._transitionComplete.set(false));
363
309
  }
364
310
  onMenuToggle() {
311
+ const state = this._layoutState();
365
312
  if (this.isOverlay()) {
366
- this._layoutState.update((prev) => ({
367
- ...prev,
368
- overlayMenuActive: !this._layoutState().overlayMenuActive,
369
- }));
370
- if (this._layoutState().overlayMenuActive) {
313
+ const newOverlayActive = !state.overlayMenuActive;
314
+ this._layoutState.update((prev) => ({ ...prev, overlayMenuActive: newOverlayActive }));
315
+ if (newOverlayActive)
371
316
  this.overlayOpen.next();
372
- }
317
+ return;
373
318
  }
374
319
  if (this.isDesktop()) {
375
320
  this._layoutState.update((prev) => ({
376
321
  ...prev,
377
- staticMenuDesktopInactive: !this._layoutState().staticMenuDesktopInactive,
322
+ staticMenuDesktopInactive: !state.staticMenuDesktopInactive,
378
323
  }));
379
324
  }
380
325
  else {
381
- this._layoutState.update((prev) => ({
382
- ...prev,
383
- staticMenuMobileActive: !this._layoutState().staticMenuMobileActive,
384
- }));
385
- if (this._layoutState().staticMenuMobileActive) {
326
+ const newMobileActive = !state.staticMenuMobileActive;
327
+ this._layoutState.update((prev) => ({ ...prev, staticMenuMobileActive: newMobileActive }));
328
+ if (newMobileActive)
386
329
  this.overlayOpen.next();
387
- }
388
330
  }
389
331
  }
390
332
  isDesktop() {
@@ -393,82 +335,36 @@ class LayoutService {
393
335
  isMobile() {
394
336
  return !this.isDesktop();
395
337
  }
396
- onConfigUpdate() {
397
- this.configUpdate.next(this._layoutConfig());
398
- }
399
338
  onMenuStateChange(event) {
400
339
  this.menuSource.next(event);
401
340
  }
402
341
  reset() {
403
342
  this.resetSource.next(true);
404
343
  }
405
- // ==========================================================================
406
- // Layout Config Methods
407
- // ==========================================================================
408
- /**
409
- * Update layout configuration.
410
- * Called by configurator component.
411
- */
344
+ // Config & state updates
412
345
  updateLayoutConfig(config) {
413
346
  this._layoutConfig.update((prev) => ({ ...prev, ...config }));
414
347
  }
415
- /**
416
- * Update layout state.
417
- * Called internally and by layout components.
418
- */
419
348
  updateLayoutState(state) {
420
349
  this._layoutState.update((prev) => ({ ...prev, ...state }));
421
350
  }
422
- // ==========================================================================
423
- // User Profile Methods
424
- // ==========================================================================
425
- /**
426
- * Set the current user profile for display in layout.
427
- * Called by auth integration to sync user data.
428
- */
351
+ // Profile setters
429
352
  setUserProfile(profile) {
430
353
  this._userProfile.set(profile);
431
354
  }
432
- /**
433
- * Set the current company profile for display in layout.
434
- * Called by auth integration to sync company data.
435
- */
436
355
  setCompanyProfile(profile) {
437
356
  this._companyProfile.set(profile);
438
357
  }
439
- // ==========================================================================
440
- // Menu Methods
441
- // ==========================================================================
442
- /**
443
- * Set the raw menu items (unfiltered).
444
- * Menu will be automatically filtered based on permission checker.
445
- * Called by app initialization to set menu from IAM or other source.
446
- */
358
+ // Menu & apps
447
359
  setMenu(items) {
448
360
  this._rawMenu.set(items);
449
361
  }
450
- /**
451
- * Clear menu and permission/role checkers.
452
- * Called on logout.
453
- */
454
362
  clearMenu() {
455
363
  this._rawMenu.set([]);
456
364
  }
457
- // ==========================================================================
458
- // App Launcher Methods
459
- // ==========================================================================
460
- /**
461
- * Set launcher apps for display in header.
462
- * Apps will be automatically filtered based on user permissions.
463
- * If empty after filtering, the app launcher button is hidden.
464
- */
465
365
  setApps(apps) {
466
366
  this._rawApps.set(apps);
467
367
  }
468
- /**
469
- * Clear launcher apps.
470
- * Called on logout.
471
- */
472
368
  clearApps() {
473
369
  this._rawApps.set([]);
474
370
  }
@@ -477,10 +373,32 @@ class LayoutService {
477
373
  }
478
374
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: LayoutService, decorators: [{
479
375
  type: Injectable,
376
+ args: [{ providedIn: 'root' }]
377
+ }], ctorParameters: () => [] });
378
+
379
+ class AppFooter {
380
+ layoutService = inject(LayoutService);
381
+ // Footer shows product branding (appName), not user's company
382
+ appName = this.layoutService.appName;
383
+ authorName = this.layoutService.authorName;
384
+ authorUrl = this.layoutService.authorUrl;
385
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: AppFooter, deps: [], target: i0.ɵɵFactoryTarget.Component });
386
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.1.3", type: AppFooter, isStandalone: true, selector: "app-footer", ngImport: i0, template: `<div class="layout-footer">
387
+ {{ appName }} by
388
+ <a [href]="authorUrl" target="_blank" rel="noopener noreferrer" class="text-primary font-bold hover:underline">{{ authorName }}</a>
389
+ </div>`, isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush });
390
+ }
391
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: AppFooter, decorators: [{
392
+ type: Component,
480
393
  args: [{
481
- providedIn: 'root',
394
+ selector: 'app-footer',
395
+ changeDetection: ChangeDetectionStrategy.OnPush,
396
+ template: `<div class="layout-footer">
397
+ {{ appName }} by
398
+ <a [href]="authorUrl" target="_blank" rel="noopener noreferrer" class="text-primary font-bold hover:underline">{{ authorName }}</a>
399
+ </div>`,
482
400
  }]
483
- }], ctorParameters: () => [] });
401
+ }] });
484
402
 
485
403
  const presets = {
486
404
  Aura,
@@ -913,7 +831,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.3", ngImpor
913
831
  type: Component,
914
832
  args: [{
915
833
  selector: 'app-configurator',
916
- standalone: true,
917
834
  changeDetection: ChangeDetectionStrategy.OnPush,
918
835
  imports: [NgClass, FormsModule, SelectButtonModule],
919
836
  template: `
@@ -1013,7 +930,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.3", ngImpor
1013
930
  type: Component,
1014
931
  args: [{
1015
932
  selector: 'app-floating-configurator',
1016
- standalone: true,
1017
933
  changeDetection: ChangeDetectionStrategy.OnPush,
1018
934
  imports: [ButtonModule, StyleClassModule, AppConfigurator],
1019
935
  template: `
@@ -1028,31 +944,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.3", ngImpor
1028
944
  }]
1029
945
  }] });
1030
946
 
1031
- class AppFooter {
1032
- layoutService = inject(LayoutService);
1033
- // Footer shows product branding (appName), not user's company
1034
- appName = this.layoutService.appName;
1035
- authorName = this.layoutService.authorName;
1036
- authorUrl = this.layoutService.authorUrl;
1037
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: AppFooter, deps: [], target: i0.ɵɵFactoryTarget.Component });
1038
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.1.3", type: AppFooter, isStandalone: true, selector: "app-footer", ngImport: i0, template: `<div class="layout-footer">
1039
- {{ appName() }} by
1040
- <a [href]="authorUrl()" target="_blank" rel="noopener noreferrer" class="text-primary font-bold hover:underline">{{ authorName() }}</a>
1041
- </div>`, isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush });
1042
- }
1043
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: AppFooter, decorators: [{
1044
- type: Component,
1045
- args: [{
1046
- standalone: true,
1047
- selector: 'app-footer',
1048
- changeDetection: ChangeDetectionStrategy.OnPush,
1049
- template: `<div class="layout-footer">
1050
- {{ appName() }} by
1051
- <a [href]="authorUrl()" target="_blank" rel="noopener noreferrer" class="text-primary font-bold hover:underline">{{ authorName() }}</a>
1052
- </div>`,
1053
- }]
1054
- }] });
1055
-
1056
947
  const LAYOUT_AUTH_STATE = new InjectionToken('LAYOUT_AUTH_STATE');
1057
948
  const LAYOUT_AUTH_API = new InjectionToken('LAYOUT_AUTH_API');
1058
949
 
@@ -1270,7 +1161,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.3", ngImpor
1270
1161
  type: Component,
1271
1162
  args: [{
1272
1163
  selector: 'app-company-branch-selector',
1273
- standalone: true,
1274
1164
  changeDetection: ChangeDetectionStrategy.OnPush,
1275
1165
  imports: [AngularModule, StyleClassModule, ButtonModule, SelectModule],
1276
1166
  host: { class: 'relative' },
@@ -1426,7 +1316,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.3", ngImpor
1426
1316
  type: Component,
1427
1317
  args: [{
1428
1318
  selector: 'app-launcher',
1429
- standalone: true,
1430
1319
  changeDetection: ChangeDetectionStrategy.OnPush,
1431
1320
  imports: [StyleClassModule, IconComponent],
1432
1321
  host: { class: 'relative' },
@@ -1622,7 +1511,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.3", ngImpor
1622
1511
  type: Component,
1623
1512
  args: [{
1624
1513
  selector: 'app-profile',
1625
- standalone: true,
1626
1514
  changeDetection: ChangeDetectionStrategy.OnPush,
1627
1515
  imports: [AngularModule, StyleClassModule],
1628
1516
  host: { class: 'relative' },
@@ -1804,7 +1692,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.3", ngImpor
1804
1692
  type: Component,
1805
1693
  args: [{
1806
1694
  selector: 'app-topbar',
1807
- standalone: true,
1808
1695
  changeDetection: ChangeDetectionStrategy.OnPush,
1809
1696
  imports: [
1810
1697
  RouterModule,
@@ -2042,7 +1929,7 @@ class AppMenuitem {
2042
1929
  }
2043
1930
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: AppMenuitem, decorators: [{
2044
1931
  type: Component,
2045
- args: [{ selector: '[app-menuitem]', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, imports: [IconComponent, RouterModule, RippleModule], template: `
1932
+ args: [{ selector: '[app-menuitem]', changeDetection: ChangeDetectionStrategy.OnPush, imports: [IconComponent, RouterModule, RippleModule], template: `
2046
1933
  <ng-container>
2047
1934
  @if (item().children?.length) {
2048
1935
  <a (click)="itemClick()" tabindex="0" pRipple>
@@ -2134,7 +2021,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.3", ngImpor
2134
2021
  type: Component,
2135
2022
  args: [{
2136
2023
  selector: 'app-menu',
2137
- standalone: true,
2138
2024
  changeDetection: ChangeDetectionStrategy.OnPush,
2139
2025
  imports: [AppMenuitem, RouterModule],
2140
2026
  template: `<div class="layout-menu">
@@ -2163,7 +2049,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.3", ngImpor
2163
2049
  type: Component,
2164
2050
  args: [{
2165
2051
  selector: 'app-sidebar',
2166
- standalone: true,
2167
2052
  changeDetection: ChangeDetectionStrategy.OnPush,
2168
2053
  imports: [AppMenu],
2169
2054
  template: `
@@ -2257,7 +2142,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.3", ngImpor
2257
2142
  type: Component,
2258
2143
  args: [{
2259
2144
  selector: 'app-layout',
2260
- standalone: true,
2261
2145
  changeDetection: ChangeDetectionStrategy.OnPush,
2262
2146
  imports: [NgClass, AppTopbar, AppSidebar, RouterModule, AppFooter],
2263
2147
  template: `
@@ -2276,42 +2160,42 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.3", ngImpor
2276
2160
  }]
2277
2161
  }], ctorParameters: () => [] });
2278
2162
 
2279
- const GreenTheme = definePreset(Material, {
2163
+ const NavyBlueTheme = definePreset(Material, {
2280
2164
  semantic: {
2281
2165
  colorScheme: {
2282
2166
  light: {
2283
2167
  primary: {
2284
- color: '#01712c',
2285
- inverseColor: '#119744',
2286
- hoverColor: '#119744',
2287
- activeColor: '#119744',
2168
+ color: '#3535cd',
2169
+ inverseColor: '#0707a9',
2170
+ hoverColor: '#0707a9',
2171
+ activeColor: '#0707a9',
2288
2172
  },
2289
2173
  highlight: {
2290
2174
  background: '#e2e8f0',
2291
2175
  focusBackground: '#e2e8f0',
2292
- color: '#01712c',
2293
- focusColor: '#01712c',
2176
+ color: '#3535cd',
2177
+ focusColor: '#3535cd',
2294
2178
  },
2295
2179
  },
2296
2180
  },
2297
2181
  },
2298
2182
  });
2299
2183
 
2300
- const NavyBlueTheme = definePreset(Material, {
2184
+ const GreenTheme = definePreset(Material, {
2301
2185
  semantic: {
2302
2186
  colorScheme: {
2303
2187
  light: {
2304
2188
  primary: {
2305
- color: '#3535cd',
2306
- inverseColor: '#0707a9',
2307
- hoverColor: '#0707a9',
2308
- activeColor: '#0707a9',
2189
+ color: '#01712c',
2190
+ inverseColor: '#119744',
2191
+ hoverColor: '#119744',
2192
+ activeColor: '#119744',
2309
2193
  },
2310
2194
  highlight: {
2311
2195
  background: '#e2e8f0',
2312
2196
  focusBackground: '#e2e8f0',
2313
- color: '#3535cd',
2314
- focusColor: '#3535cd',
2197
+ color: '#01712c',
2198
+ focusColor: '#01712c',
2315
2199
  },
2316
2200
  },
2317
2201
  },