@flusys/ng-layout 4.1.1 → 5.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.
@@ -1386,7 +1386,9 @@ class AppCompanyBranchSelector {
1386
1386
  authState = inject(LAYOUT_AUTH_STATE, { optional: true });
1387
1387
  authApi = inject(LAYOUT_AUTH_API, { optional: true });
1388
1388
  messageService = inject(MessageService);
1389
- translateAdapter = inject(TRANSLATE_ADAPTER, { optional: true });
1389
+ translateAdapter = inject(TRANSLATE_ADAPTER, {
1390
+ optional: true,
1391
+ });
1390
1392
  document = inject(DOCUMENT$1);
1391
1393
  elementRef = inject(ElementRef);
1392
1394
  _isActive = signal(false, ...(ngDevMode ? [{ debugName: "_isActive" }] : []));
@@ -1401,7 +1403,8 @@ class AppCompanyBranchSelector {
1401
1403
  }
1402
1404
  });
1403
1405
  }
1404
- currentCompanyName = computed(() => this.authState?.currentCompanyInfo()?.name ?? this.translate('layout.company.branch.selector.no.company'), ...(ngDevMode ? [{ debugName: "currentCompanyName" }] : []));
1406
+ currentCompanyName = computed(() => this.authState?.currentCompanyInfo()?.name ??
1407
+ this.translate('layout.company.branch.selector.no.company'), ...(ngDevMode ? [{ debugName: "currentCompanyName" }] : []));
1405
1408
  currentBranchName = computed(() => this.authState?.currentBranchInfo()?.name ?? null, ...(ngDevMode ? [{ debugName: "currentBranchName" }] : []));
1406
1409
  _companies = signal([], ...(ngDevMode ? [{ debugName: "_companies" }] : []));
1407
1410
  companies = this._companies.asReadonly();
@@ -1424,7 +1427,7 @@ class AppCompanyBranchSelector {
1424
1427
  const currentCompanyId = this.authState?.currentCompanyInfo()?.id;
1425
1428
  const currentBranchId = this.authState?.currentBranchInfo()?.id;
1426
1429
  const selectedBranch = this.selectedBranchId();
1427
- return selectedCompany !== currentCompanyId || selectedBranch !== currentBranchId;
1430
+ return (selectedCompany !== currentCompanyId || selectedBranch !== currentBranchId);
1428
1431
  }, ...(ngDevMode ? [{ debugName: "canSwitch" }] : []));
1429
1432
  onPanelToggle() {
1430
1433
  this._isActive.update((v) => !v);
@@ -1538,20 +1541,24 @@ class AppCompanyBranchSelector {
1538
1541
  style="background-color: var(--surface-overlay); inset-inline-end: 0;"
1539
1542
  >
1540
1543
  <div class="flex flex-col gap-4">
1541
- <span class="text-sm text-muted-color font-semibold"
1542
- >{{ 'layout.company.branch.selector.title' | translate }}</span
1543
- >
1544
+ <span class="text-sm text-muted-color font-semibold">{{
1545
+ 'layout.company.branch.selector.title' | translate
1546
+ }}</span>
1544
1547
 
1545
1548
  <!-- Company Selector -->
1546
1549
  <div class="flex flex-col gap-2">
1547
- <label class="text-sm text-muted-color font-semibold">{{ 'layout.company.branch.selector.company' | translate }}</label>
1550
+ <label class="text-sm text-muted-color font-semibold">{{
1551
+ 'shared.company' | translate
1552
+ }}</label>
1548
1553
  <p-select
1549
1554
  [options]="companies()"
1550
1555
  [ngModel]="selectedCompanyId()"
1551
1556
  (ngModelChange)="onCompanyChange($event)"
1552
1557
  optionLabel="name"
1553
1558
  optionValue="id"
1554
- [placeholder]="'layout.company.branch.selector.select.company' | translate"
1559
+ [placeholder]="
1560
+ 'layout.company.branch.selector.select.company' | translate
1561
+ "
1555
1562
  class="w-full"
1556
1563
  [loading]="isLoadingCompanies()"
1557
1564
  />
@@ -1560,14 +1567,18 @@ class AppCompanyBranchSelector {
1560
1567
  <!-- Branch Selector -->
1561
1568
  @if (selectedCompanyId() && branches().length > 0) {
1562
1569
  <div class="flex flex-col gap-2">
1563
- <label class="text-sm text-muted-color font-semibold">{{ 'layout.company.branch.selector.branch' | translate }}</label>
1570
+ <label class="text-sm text-muted-color font-semibold">{{
1571
+ 'layout.company.branch.selector.branch' | translate
1572
+ }}</label>
1564
1573
  <p-select
1565
1574
  [options]="branches()"
1566
1575
  [ngModel]="selectedBranchId()"
1567
1576
  (ngModelChange)="onBranchChange($event)"
1568
1577
  optionLabel="name"
1569
1578
  optionValue="id"
1570
- [placeholder]="'layout.company.branch.selector.select.branch' | translate"
1579
+ [placeholder]="
1580
+ 'layout.company.branch.selector.select.branch' | translate
1581
+ "
1571
1582
  class="w-full"
1572
1583
  [loading]="isLoadingBranches()"
1573
1584
  />
@@ -1593,7 +1604,13 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.5", ngImpor
1593
1604
  type: Component,
1594
1605
  args: [{
1595
1606
  selector: 'app-company-branch-selector',
1596
- imports: [AngularModule, StyleClassModule, ButtonModule, SelectModule, TranslatePipe],
1607
+ imports: [
1608
+ AngularModule,
1609
+ StyleClassModule,
1610
+ ButtonModule,
1611
+ SelectModule,
1612
+ TranslatePipe,
1613
+ ],
1597
1614
  host: { class: 'relative' },
1598
1615
  template: `
1599
1616
  <button
@@ -1619,20 +1636,24 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.5", ngImpor
1619
1636
  style="background-color: var(--surface-overlay); inset-inline-end: 0;"
1620
1637
  >
1621
1638
  <div class="flex flex-col gap-4">
1622
- <span class="text-sm text-muted-color font-semibold"
1623
- >{{ 'layout.company.branch.selector.title' | translate }}</span
1624
- >
1639
+ <span class="text-sm text-muted-color font-semibold">{{
1640
+ 'layout.company.branch.selector.title' | translate
1641
+ }}</span>
1625
1642
 
1626
1643
  <!-- Company Selector -->
1627
1644
  <div class="flex flex-col gap-2">
1628
- <label class="text-sm text-muted-color font-semibold">{{ 'layout.company.branch.selector.company' | translate }}</label>
1645
+ <label class="text-sm text-muted-color font-semibold">{{
1646
+ 'shared.company' | translate
1647
+ }}</label>
1629
1648
  <p-select
1630
1649
  [options]="companies()"
1631
1650
  [ngModel]="selectedCompanyId()"
1632
1651
  (ngModelChange)="onCompanyChange($event)"
1633
1652
  optionLabel="name"
1634
1653
  optionValue="id"
1635
- [placeholder]="'layout.company.branch.selector.select.company' | translate"
1654
+ [placeholder]="
1655
+ 'layout.company.branch.selector.select.company' | translate
1656
+ "
1636
1657
  class="w-full"
1637
1658
  [loading]="isLoadingCompanies()"
1638
1659
  />
@@ -1641,14 +1662,18 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.5", ngImpor
1641
1662
  <!-- Branch Selector -->
1642
1663
  @if (selectedCompanyId() && branches().length > 0) {
1643
1664
  <div class="flex flex-col gap-2">
1644
- <label class="text-sm text-muted-color font-semibold">{{ 'layout.company.branch.selector.branch' | translate }}</label>
1665
+ <label class="text-sm text-muted-color font-semibold">{{
1666
+ 'layout.company.branch.selector.branch' | translate
1667
+ }}</label>
1645
1668
  <p-select
1646
1669
  [options]="branches()"
1647
1670
  [ngModel]="selectedBranchId()"
1648
1671
  (ngModelChange)="onBranchChange($event)"
1649
1672
  optionLabel="name"
1650
1673
  optionValue="id"
1651
- [placeholder]="'layout.company.branch.selector.select.branch' | translate"
1674
+ [placeholder]="
1675
+ 'layout.company.branch.selector.select.branch' | translate
1676
+ "
1652
1677
  class="w-full"
1653
1678
  [loading]="isLoadingBranches()"
1654
1679
  />
@@ -1714,7 +1739,9 @@ class AppLauncher {
1714
1739
  style="background-color: var(--surface-overlay); inset-inline-end: 0;"
1715
1740
  >
1716
1741
  <div class="flex flex-col gap-2">
1717
- <span class="text-sm text-muted-color font-semibold">{{ 'layout.launcher.applications' | translate }}</span>
1742
+ <span class="text-sm text-muted-color font-semibold">{{
1743
+ 'layout.launcher.applications' | translate
1744
+ }}</span>
1718
1745
  <div class="grid grid-cols-2 sm:grid-cols-3 gap-2">
1719
1746
  @for (app of layoutService.apps(); track app.id) {
1720
1747
  <a
@@ -1770,7 +1797,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.5", ngImpor
1770
1797
  style="background-color: var(--surface-overlay); inset-inline-end: 0;"
1771
1798
  >
1772
1799
  <div class="flex flex-col gap-2">
1773
- <span class="text-sm text-muted-color font-semibold">{{ 'layout.launcher.applications' | translate }}</span>
1800
+ <span class="text-sm text-muted-color font-semibold">{{
1801
+ 'layout.launcher.applications' | translate
1802
+ }}</span>
1774
1803
  <div class="grid grid-cols-2 sm:grid-cols-3 gap-2">
1775
1804
  @for (app of layoutService.apps(); track app.id) {
1776
1805
  <a
@@ -1807,7 +1836,9 @@ class AppProfile {
1807
1836
  authApi = inject(LAYOUT_AUTH_API, { optional: true });
1808
1837
  layoutService = inject(LayoutService);
1809
1838
  messageService = inject(MessageService);
1810
- translateAdapter = inject(TRANSLATE_ADAPTER, { optional: true });
1839
+ translateAdapter = inject(TRANSLATE_ADAPTER, {
1840
+ optional: true,
1841
+ });
1811
1842
  appConfig = inject(APP_CONFIG, { optional: true });
1812
1843
  document = inject(DOCUMENT$1);
1813
1844
  elementRef = inject(ElementRef);
@@ -1826,7 +1857,8 @@ class AppProfile {
1826
1857
  togglePanel() {
1827
1858
  this._isActive.update((v) => !v);
1828
1859
  }
1829
- userName = computed(() => this.authState?.loginUserData()?.name ?? this.translate('layout.profile.guest'), ...(ngDevMode ? [{ debugName: "userName" }] : []));
1860
+ userName = computed(() => this.authState?.loginUserData()?.name ??
1861
+ this.translate('layout.profile.guest'), ...(ngDevMode ? [{ debugName: "userName" }] : []));
1830
1862
  userEmail = computed(() => this.authState?.loginUserData()?.email ?? '', ...(ngDevMode ? [{ debugName: "userEmail" }] : []));
1831
1863
  profilePicture = computed(() => this.layoutService.userProfilePictureUrl() ?? '', ...(ngDevMode ? [{ debugName: "profilePicture" }] : []));
1832
1864
  signUpEnabled = computed(() => this.appConfig ? isSignUpEnabled(this.appConfig) : false, ...(ngDevMode ? [{ debugName: "signUpEnabled" }] : []));
@@ -1838,10 +1870,13 @@ class AppProfile {
1838
1870
  .pipe(takeUntilDestroyed(this.destroyRef))
1839
1871
  .subscribe({
1840
1872
  next: (result) => {
1873
+ const r = result;
1841
1874
  this.messageService.add({
1842
1875
  severity: 'success',
1843
1876
  summary: this.translate('shared.success'),
1844
- detail: result.message,
1877
+ detail: r?.messageKey
1878
+ ? this.translate(r.messageKey, r.messageVariables)
1879
+ : (r?.message ?? ''),
1845
1880
  });
1846
1881
  this.authApi?.navigateLogin(false);
1847
1882
  },
@@ -1870,8 +1905,8 @@ class AppProfile {
1870
1905
  });
1871
1906
  });
1872
1907
  }
1873
- translate(key) {
1874
- return this.translateAdapter?.translate(key) ?? key;
1908
+ translate(key, vars) {
1909
+ return this.translateAdapter?.translate(key, vars) ?? key;
1875
1910
  }
1876
1911
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.5", ngImport: i0, type: AppProfile, deps: [], target: i0.ɵɵFactoryTarget.Component });
1877
1912
  static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.5", type: AppProfile, isStandalone: true, selector: "app-profile", host: { classAttribute: "relative" }, ngImport: i0, template: `
@@ -1914,8 +1949,12 @@ class AppProfile {
1914
1949
  </div>
1915
1950
  }
1916
1951
  <div class="flex flex-col min-w-0 flex-1">
1917
- <span class="font-semibold text-color truncate">{{ userName() }}</span>
1918
- <span class="text-sm text-muted-color truncate">{{ userEmail() }}</span>
1952
+ <span class="font-semibold text-color truncate">{{
1953
+ userName()
1954
+ }}</span>
1955
+ <span class="text-sm text-muted-color truncate">{{
1956
+ userEmail()
1957
+ }}</span>
1919
1958
  </div>
1920
1959
  </a>
1921
1960
 
@@ -1991,8 +2030,12 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.5", ngImpor
1991
2030
  </div>
1992
2031
  }
1993
2032
  <div class="flex flex-col min-w-0 flex-1">
1994
- <span class="font-semibold text-color truncate">{{ userName() }}</span>
1995
- <span class="text-sm text-muted-color truncate">{{ userEmail() }}</span>
2033
+ <span class="font-semibold text-color truncate">{{
2034
+ userName()
2035
+ }}</span>
2036
+ <span class="text-sm text-muted-color truncate">{{
2037
+ userEmail()
2038
+ }}</span>
1996
2039
  </div>
1997
2040
  </a>
1998
2041
 
@@ -2150,7 +2193,10 @@ class AppSearchbar {
2150
2193
  this.closeSuggestions();
2151
2194
  }
2152
2195
  onSearch() {
2153
- // Implement global search if needed
2196
+ const query = this.searchTerm();
2197
+ if (this.searchAdapter?.onSearch && query.trim()) {
2198
+ this.searchAdapter.onSearch(query);
2199
+ }
2154
2200
  }
2155
2201
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.5", ngImport: i0, type: AppSearchbar, deps: [], target: i0.ɵɵFactoryTarget.Component });
2156
2202
  static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.5", type: AppSearchbar, isStandalone: true, selector: "app-searchbar", viewQueries: [{ propertyName: "searchWrapper", first: true, predicate: ["searchWrapper"], descendants: true, isSignal: true }, { propertyName: "searchInput", first: true, predicate: ["searchInput"], descendants: true, isSignal: true }], ngImport: i0, template: `
@@ -2849,43 +2895,36 @@ const GreenTheme = definePreset(Material, {
2849
2895
  });
2850
2896
 
2851
2897
  const LAYOUT_MESSAGES = {
2852
- // Menu items
2853
- 'menu.dashboard': 'Dashboard',
2854
- 'menu.administration': 'Administration',
2855
- 'menu.iam': 'IAM',
2856
- 'menu.storage': 'Storage',
2857
- 'menu.forms': 'Forms',
2858
- 'menu.email': 'Email',
2859
- 'menu.event.manager': 'Event Manager',
2860
- 'menu.notifications': 'Notifications',
2861
- 'menu.localization': 'Localization',
2862
- 'menu.projects': 'Projects',
2863
- 'menu.projects.active': 'Active Projects',
2864
- 'menu.projects.archived': 'Archived Projects',
2865
- 'menu.projects.reports': 'Project Reports',
2866
- // Profile
2898
+ // components/top-bar/app.profile.ts
2867
2899
  'layout.profile.title': 'Profile',
2868
2900
  'layout.profile.profile.picture.alt': 'Profile picture',
2869
2901
  'layout.profile.copy.sign.up.link': 'Copy SignUp Link',
2870
2902
  'layout.profile.logout': 'Logout',
2903
+ 'layout.profile.guest': 'Guest',
2871
2904
  'layout.profile.link.copied': 'Link Copied',
2872
2905
  'layout.profile.sign.up.link.copied': 'Sign Up Link copied.',
2873
2906
  'layout.profile.failed.copy.sign.up.link': 'Failed to copy signup link.',
2874
- 'layout.profile.guest': 'Guest',
2875
- // Company/Branch Selector
2907
+ // components/top-bar/app.launcher.ts
2908
+ 'layout.launcher.apps': 'Apps',
2909
+ 'layout.launcher.applications': 'Applications',
2910
+ // components/top-bar/app.company-branch-selector.ts
2876
2911
  'layout.company.branch.selector.title': 'Switch Company & Branch',
2877
- 'layout.company.branch.selector.company': 'Company',
2878
2912
  'layout.company.branch.selector.select.company': 'Select Company',
2879
2913
  'layout.company.branch.selector.branch': 'Branch',
2880
2914
  'layout.company.branch.selector.select.branch': 'Select Branch',
2881
2915
  'layout.company.branch.selector.switch.button': 'Switch',
2916
+ 'layout.company.branch.selector.no.company': 'No Company',
2882
2917
  'layout.company.branch.selector.branch.required': 'Branch Required',
2883
2918
  'layout.company.branch.selector.please.select.branch': 'Please select a branch',
2884
- 'layout.company.branch.selector.no.company': 'No Company',
2885
- // Launcher
2886
- 'layout.launcher.apps': 'Apps',
2887
- 'layout.launcher.applications': 'Applications',
2888
- // Configurator
2919
+ // components/top-bar/app.searchbar.ts
2920
+ 'layout.topbar.search': 'Search',
2921
+ 'layout.topbar.search.placeholder': 'Search for content...',
2922
+ // components/app.topbar.ts
2923
+ 'layout.topbar.toggle.menu': 'Toggle menu',
2924
+ 'layout.topbar.toggle.dark.mode': 'Toggle dark mode',
2925
+ 'layout.topbar.open.theme.settings': 'Open theme settings',
2926
+ 'layout.topbar.more.options': 'More options',
2927
+ // components/app.configurator.ts
2889
2928
  'layout.configurator.primary': 'Primary',
2890
2929
  'layout.configurator.surface': 'Surface',
2891
2930
  'layout.configurator.presets': 'Presets',
@@ -2893,26 +2932,30 @@ const LAYOUT_MESSAGES = {
2893
2932
  'layout.configurator.menu.mode.static': 'Static',
2894
2933
  'layout.configurator.menu.mode.overlay': 'Overlay',
2895
2934
  'layout.configurator.menu.mode.topbar': 'Topbar',
2896
- // Topbar accessibility
2897
- 'layout.topbar.toggle.menu': 'Toggle menu',
2898
- 'layout.topbar.toggle.dark.mode': 'Toggle dark mode',
2899
- 'layout.topbar.open.theme.settings': 'Open theme settings',
2900
- 'layout.topbar.more.options': 'More options',
2901
- // Footer
2935
+ // components/app.footer.ts
2902
2936
  'layout.footer.by': 'by',
2903
- // Notifications
2937
+ // app-menu.config.ts (main app menu configuration)
2938
+ 'menu.dashboard': 'Dashboard',
2939
+ 'menu.administration': 'Administration',
2940
+ 'menu.iam': 'IAM',
2941
+ 'menu.storage': 'Storage',
2942
+ 'menu.forms': 'Forms',
2943
+ 'menu.email': 'Email',
2944
+ 'menu.event.manager': 'Event Manager',
2945
+ 'menu.notifications': 'Notifications',
2946
+ 'menu.localization': 'Localization',
2947
+ // Those are layout part from notification module, but we put them here to avoid circular dependency between layout and notification module
2948
+ // components/notification-bell/notification-bell.component.ts
2904
2949
  'notification.title': 'Notifications',
2905
- 'notification.mark.all.read': 'Mark all as read',
2906
- 'notification.view.all': 'View all',
2950
+ // components/notification-list/notification-list.component.ts
2951
+ 'notification.mark.all.read': 'Mark all read',
2952
+ 'notification.view.all': 'View all notifications',
2953
+ 'notification.empty': 'No notifications',
2954
+ // components/notification-item/notification-item.component.ts
2907
2955
  'notification.time.just.now': 'Just now',
2908
2956
  'notification.time.minutes.ago': '{{count}}m ago',
2909
2957
  'notification.time.hours.ago': '{{count}}h ago',
2910
2958
  'notification.time.days.ago': '{{count}}d ago',
2911
- 'notification.empty': 'No notifications',
2912
- // Home/Dashboard
2913
- 'home.where.users.from': 'Where users are from',
2914
- 'layout.topbar.search': 'Search',
2915
- 'layout.topbar.search.placeholder': 'Search for content...',
2916
2959
  };
2917
2960
 
2918
2961
  // Components