@flusys/ng-layout 4.1.0 → 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.
@@ -405,14 +405,16 @@ class AppFooter {
405
405
  @if (displayLogo) {
406
406
  <img [src]="displayLogo" [alt]="appName" class="logo-image" />
407
407
  }
408
- {{ appName }} {{ 'layout.footer.by' | translate }}
409
- <a
410
- [href]="authorUrl"
411
- target="_blank"
412
- rel="noopener noreferrer"
413
- class="text-primary font-bold hover:underline"
414
- >{{ authorName }}</a
415
- >
408
+ <span class="hidden sm:inline">
409
+ {{ appName }} {{ 'layout.footer.by' | translate }}
410
+ <a
411
+ [href]="authorUrl"
412
+ target="_blank"
413
+ rel="noopener noreferrer"
414
+ class="text-primary font-bold hover:underline"
415
+ >{{ authorName }}</a
416
+ >
417
+ </span>
416
418
  </div>`, isInline: true, dependencies: [{ kind: "pipe", type: TranslatePipe, name: "translate" }] });
417
419
  }
418
420
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.5", ngImport: i0, type: AppFooter, decorators: [{
@@ -424,14 +426,16 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.5", ngImpor
424
426
  @if (displayLogo) {
425
427
  <img [src]="displayLogo" [alt]="appName" class="logo-image" />
426
428
  }
427
- {{ appName }} {{ 'layout.footer.by' | translate }}
428
- <a
429
- [href]="authorUrl"
430
- target="_blank"
431
- rel="noopener noreferrer"
432
- class="text-primary font-bold hover:underline"
433
- >{{ authorName }}</a
434
- >
429
+ <span class="hidden sm:inline">
430
+ {{ appName }} {{ 'layout.footer.by' | translate }}
431
+ <a
432
+ [href]="authorUrl"
433
+ target="_blank"
434
+ rel="noopener noreferrer"
435
+ class="text-primary font-bold hover:underline"
436
+ >{{ authorName }}</a
437
+ >
438
+ </span>
435
439
  </div>`,
436
440
  }]
437
441
  }] });
@@ -1135,7 +1139,7 @@ class AppMenuitem {
1135
1139
  }
1136
1140
  updateSubmenuPosition() {
1137
1141
  const linkEl = this.parentLink()?.nativeElement;
1138
- if (!linkEl)
1142
+ if (!linkEl || typeof linkEl.getBoundingClientRect !== 'function')
1139
1143
  return;
1140
1144
  const rect = linkEl.getBoundingClientRect();
1141
1145
  const hostEl = linkEl.closest('[app-menuitem]');
@@ -1183,7 +1187,6 @@ class AppMenuitem {
1183
1187
  #parentLink
1184
1188
  tabindex="0"
1185
1189
  pRipple
1186
- [style.cursor]="layoutService.isTopbar() ? 'default' : 'pointer'"
1187
1190
  >
1188
1191
  @if (item().icon) {
1189
1192
  <lib-icon
@@ -1259,7 +1262,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.5", ngImpor
1259
1262
  #parentLink
1260
1263
  tabindex="0"
1261
1264
  pRipple
1262
- [style.cursor]="layoutService.isTopbar() ? 'default' : 'pointer'"
1263
1265
  >
1264
1266
  @if (item().icon) {
1265
1267
  <lib-icon
@@ -1384,7 +1386,9 @@ class AppCompanyBranchSelector {
1384
1386
  authState = inject(LAYOUT_AUTH_STATE, { optional: true });
1385
1387
  authApi = inject(LAYOUT_AUTH_API, { optional: true });
1386
1388
  messageService = inject(MessageService);
1387
- translateAdapter = inject(TRANSLATE_ADAPTER, { optional: true });
1389
+ translateAdapter = inject(TRANSLATE_ADAPTER, {
1390
+ optional: true,
1391
+ });
1388
1392
  document = inject(DOCUMENT$1);
1389
1393
  elementRef = inject(ElementRef);
1390
1394
  _isActive = signal(false, ...(ngDevMode ? [{ debugName: "_isActive" }] : []));
@@ -1399,7 +1403,8 @@ class AppCompanyBranchSelector {
1399
1403
  }
1400
1404
  });
1401
1405
  }
1402
- 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" }] : []));
1403
1408
  currentBranchName = computed(() => this.authState?.currentBranchInfo()?.name ?? null, ...(ngDevMode ? [{ debugName: "currentBranchName" }] : []));
1404
1409
  _companies = signal([], ...(ngDevMode ? [{ debugName: "_companies" }] : []));
1405
1410
  companies = this._companies.asReadonly();
@@ -1422,7 +1427,7 @@ class AppCompanyBranchSelector {
1422
1427
  const currentCompanyId = this.authState?.currentCompanyInfo()?.id;
1423
1428
  const currentBranchId = this.authState?.currentBranchInfo()?.id;
1424
1429
  const selectedBranch = this.selectedBranchId();
1425
- return selectedCompany !== currentCompanyId || selectedBranch !== currentBranchId;
1430
+ return (selectedCompany !== currentCompanyId || selectedBranch !== currentBranchId);
1426
1431
  }, ...(ngDevMode ? [{ debugName: "canSwitch" }] : []));
1427
1432
  onPanelToggle() {
1428
1433
  this._isActive.update((v) => !v);
@@ -1536,20 +1541,24 @@ class AppCompanyBranchSelector {
1536
1541
  style="background-color: var(--surface-overlay); inset-inline-end: 0;"
1537
1542
  >
1538
1543
  <div class="flex flex-col gap-4">
1539
- <span class="text-sm text-muted-color font-semibold"
1540
- >{{ 'layout.company.branch.selector.title' | translate }}</span
1541
- >
1544
+ <span class="text-sm text-muted-color font-semibold">{{
1545
+ 'layout.company.branch.selector.title' | translate
1546
+ }}</span>
1542
1547
 
1543
1548
  <!-- Company Selector -->
1544
1549
  <div class="flex flex-col gap-2">
1545
- <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>
1546
1553
  <p-select
1547
1554
  [options]="companies()"
1548
1555
  [ngModel]="selectedCompanyId()"
1549
1556
  (ngModelChange)="onCompanyChange($event)"
1550
1557
  optionLabel="name"
1551
1558
  optionValue="id"
1552
- [placeholder]="'layout.company.branch.selector.select.company' | translate"
1559
+ [placeholder]="
1560
+ 'layout.company.branch.selector.select.company' | translate
1561
+ "
1553
1562
  class="w-full"
1554
1563
  [loading]="isLoadingCompanies()"
1555
1564
  />
@@ -1558,14 +1567,18 @@ class AppCompanyBranchSelector {
1558
1567
  <!-- Branch Selector -->
1559
1568
  @if (selectedCompanyId() && branches().length > 0) {
1560
1569
  <div class="flex flex-col gap-2">
1561
- <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>
1562
1573
  <p-select
1563
1574
  [options]="branches()"
1564
1575
  [ngModel]="selectedBranchId()"
1565
1576
  (ngModelChange)="onBranchChange($event)"
1566
1577
  optionLabel="name"
1567
1578
  optionValue="id"
1568
- [placeholder]="'layout.company.branch.selector.select.branch' | translate"
1579
+ [placeholder]="
1580
+ 'layout.company.branch.selector.select.branch' | translate
1581
+ "
1569
1582
  class="w-full"
1570
1583
  [loading]="isLoadingBranches()"
1571
1584
  />
@@ -1591,7 +1604,13 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.5", ngImpor
1591
1604
  type: Component,
1592
1605
  args: [{
1593
1606
  selector: 'app-company-branch-selector',
1594
- imports: [AngularModule, StyleClassModule, ButtonModule, SelectModule, TranslatePipe],
1607
+ imports: [
1608
+ AngularModule,
1609
+ StyleClassModule,
1610
+ ButtonModule,
1611
+ SelectModule,
1612
+ TranslatePipe,
1613
+ ],
1595
1614
  host: { class: 'relative' },
1596
1615
  template: `
1597
1616
  <button
@@ -1617,20 +1636,24 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.5", ngImpor
1617
1636
  style="background-color: var(--surface-overlay); inset-inline-end: 0;"
1618
1637
  >
1619
1638
  <div class="flex flex-col gap-4">
1620
- <span class="text-sm text-muted-color font-semibold"
1621
- >{{ 'layout.company.branch.selector.title' | translate }}</span
1622
- >
1639
+ <span class="text-sm text-muted-color font-semibold">{{
1640
+ 'layout.company.branch.selector.title' | translate
1641
+ }}</span>
1623
1642
 
1624
1643
  <!-- Company Selector -->
1625
1644
  <div class="flex flex-col gap-2">
1626
- <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>
1627
1648
  <p-select
1628
1649
  [options]="companies()"
1629
1650
  [ngModel]="selectedCompanyId()"
1630
1651
  (ngModelChange)="onCompanyChange($event)"
1631
1652
  optionLabel="name"
1632
1653
  optionValue="id"
1633
- [placeholder]="'layout.company.branch.selector.select.company' | translate"
1654
+ [placeholder]="
1655
+ 'layout.company.branch.selector.select.company' | translate
1656
+ "
1634
1657
  class="w-full"
1635
1658
  [loading]="isLoadingCompanies()"
1636
1659
  />
@@ -1639,14 +1662,18 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.5", ngImpor
1639
1662
  <!-- Branch Selector -->
1640
1663
  @if (selectedCompanyId() && branches().length > 0) {
1641
1664
  <div class="flex flex-col gap-2">
1642
- <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>
1643
1668
  <p-select
1644
1669
  [options]="branches()"
1645
1670
  [ngModel]="selectedBranchId()"
1646
1671
  (ngModelChange)="onBranchChange($event)"
1647
1672
  optionLabel="name"
1648
1673
  optionValue="id"
1649
- [placeholder]="'layout.company.branch.selector.select.branch' | translate"
1674
+ [placeholder]="
1675
+ 'layout.company.branch.selector.select.branch' | translate
1676
+ "
1650
1677
  class="w-full"
1651
1678
  [loading]="isLoadingBranches()"
1652
1679
  />
@@ -1712,7 +1739,9 @@ class AppLauncher {
1712
1739
  style="background-color: var(--surface-overlay); inset-inline-end: 0;"
1713
1740
  >
1714
1741
  <div class="flex flex-col gap-2">
1715
- <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>
1716
1745
  <div class="grid grid-cols-2 sm:grid-cols-3 gap-2">
1717
1746
  @for (app of layoutService.apps(); track app.id) {
1718
1747
  <a
@@ -1768,7 +1797,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.5", ngImpor
1768
1797
  style="background-color: var(--surface-overlay); inset-inline-end: 0;"
1769
1798
  >
1770
1799
  <div class="flex flex-col gap-2">
1771
- <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>
1772
1803
  <div class="grid grid-cols-2 sm:grid-cols-3 gap-2">
1773
1804
  @for (app of layoutService.apps(); track app.id) {
1774
1805
  <a
@@ -1805,7 +1836,9 @@ class AppProfile {
1805
1836
  authApi = inject(LAYOUT_AUTH_API, { optional: true });
1806
1837
  layoutService = inject(LayoutService);
1807
1838
  messageService = inject(MessageService);
1808
- translateAdapter = inject(TRANSLATE_ADAPTER, { optional: true });
1839
+ translateAdapter = inject(TRANSLATE_ADAPTER, {
1840
+ optional: true,
1841
+ });
1809
1842
  appConfig = inject(APP_CONFIG, { optional: true });
1810
1843
  document = inject(DOCUMENT$1);
1811
1844
  elementRef = inject(ElementRef);
@@ -1824,7 +1857,8 @@ class AppProfile {
1824
1857
  togglePanel() {
1825
1858
  this._isActive.update((v) => !v);
1826
1859
  }
1827
- 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" }] : []));
1828
1862
  userEmail = computed(() => this.authState?.loginUserData()?.email ?? '', ...(ngDevMode ? [{ debugName: "userEmail" }] : []));
1829
1863
  profilePicture = computed(() => this.layoutService.userProfilePictureUrl() ?? '', ...(ngDevMode ? [{ debugName: "profilePicture" }] : []));
1830
1864
  signUpEnabled = computed(() => this.appConfig ? isSignUpEnabled(this.appConfig) : false, ...(ngDevMode ? [{ debugName: "signUpEnabled" }] : []));
@@ -1836,10 +1870,13 @@ class AppProfile {
1836
1870
  .pipe(takeUntilDestroyed(this.destroyRef))
1837
1871
  .subscribe({
1838
1872
  next: (result) => {
1873
+ const r = result;
1839
1874
  this.messageService.add({
1840
1875
  severity: 'success',
1841
1876
  summary: this.translate('shared.success'),
1842
- detail: result.message,
1877
+ detail: r?.messageKey
1878
+ ? this.translate(r.messageKey, r.messageVariables)
1879
+ : (r?.message ?? ''),
1843
1880
  });
1844
1881
  this.authApi?.navigateLogin(false);
1845
1882
  },
@@ -1868,8 +1905,8 @@ class AppProfile {
1868
1905
  });
1869
1906
  });
1870
1907
  }
1871
- translate(key) {
1872
- return this.translateAdapter?.translate(key) ?? key;
1908
+ translate(key, vars) {
1909
+ return this.translateAdapter?.translate(key, vars) ?? key;
1873
1910
  }
1874
1911
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.5", ngImport: i0, type: AppProfile, deps: [], target: i0.ɵɵFactoryTarget.Component });
1875
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: `
@@ -1912,8 +1949,12 @@ class AppProfile {
1912
1949
  </div>
1913
1950
  }
1914
1951
  <div class="flex flex-col min-w-0 flex-1">
1915
- <span class="font-semibold text-color truncate">{{ userName() }}</span>
1916
- <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>
1917
1958
  </div>
1918
1959
  </a>
1919
1960
 
@@ -1989,8 +2030,12 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.5", ngImpor
1989
2030
  </div>
1990
2031
  }
1991
2032
  <div class="flex flex-col min-w-0 flex-1">
1992
- <span class="font-semibold text-color truncate">{{ userName() }}</span>
1993
- <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>
1994
2039
  </div>
1995
2040
  </a>
1996
2041
 
@@ -2148,7 +2193,10 @@ class AppSearchbar {
2148
2193
  this.closeSuggestions();
2149
2194
  }
2150
2195
  onSearch() {
2151
- // Implement global search if needed
2196
+ const query = this.searchTerm();
2197
+ if (this.searchAdapter?.onSearch && query.trim()) {
2198
+ this.searchAdapter.onSearch(query);
2199
+ }
2152
2200
  }
2153
2201
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.5", ngImport: i0, type: AppSearchbar, deps: [], target: i0.ɵɵFactoryTarget.Component });
2154
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: `
@@ -2454,7 +2502,7 @@ class AppTopbar {
2454
2502
  @if (displayLogo()) {
2455
2503
  <img [src]="displayLogo()" [alt]="companyName()" class="logo-image" />
2456
2504
  }
2457
- <span>{{ companyName() }}</span>
2505
+ <span class="hidden sm:inline">{{ companyName() }}</span>
2458
2506
  </a>
2459
2507
  @if (!layoutService.isTopbar() && layoutService.isDesktop()) {
2460
2508
  <button
@@ -2582,7 +2630,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.5", ngImpor
2582
2630
  @if (displayLogo()) {
2583
2631
  <img [src]="displayLogo()" [alt]="companyName()" class="logo-image" />
2584
2632
  }
2585
- <span>{{ companyName() }}</span>
2633
+ <span class="hidden sm:inline">{{ companyName() }}</span>
2586
2634
  </a>
2587
2635
  @if (!layoutService.isTopbar() && layoutService.isDesktop()) {
2588
2636
  <button
@@ -2847,43 +2895,36 @@ const GreenTheme = definePreset(Material, {
2847
2895
  });
2848
2896
 
2849
2897
  const LAYOUT_MESSAGES = {
2850
- // Menu items
2851
- 'menu.dashboard': 'Dashboard',
2852
- 'menu.administration': 'Administration',
2853
- 'menu.iam': 'IAM',
2854
- 'menu.storage': 'Storage',
2855
- 'menu.forms': 'Forms',
2856
- 'menu.email': 'Email',
2857
- 'menu.event.manager': 'Event Manager',
2858
- 'menu.notifications': 'Notifications',
2859
- 'menu.localization': 'Localization',
2860
- 'menu.projects': 'Projects',
2861
- 'menu.projects.active': 'Active Projects',
2862
- 'menu.projects.archived': 'Archived Projects',
2863
- 'menu.projects.reports': 'Project Reports',
2864
- // Profile
2898
+ // components/top-bar/app.profile.ts
2865
2899
  'layout.profile.title': 'Profile',
2866
2900
  'layout.profile.profile.picture.alt': 'Profile picture',
2867
2901
  'layout.profile.copy.sign.up.link': 'Copy SignUp Link',
2868
2902
  'layout.profile.logout': 'Logout',
2903
+ 'layout.profile.guest': 'Guest',
2869
2904
  'layout.profile.link.copied': 'Link Copied',
2870
2905
  'layout.profile.sign.up.link.copied': 'Sign Up Link copied.',
2871
2906
  'layout.profile.failed.copy.sign.up.link': 'Failed to copy signup link.',
2872
- 'layout.profile.guest': 'Guest',
2873
- // 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
2874
2911
  'layout.company.branch.selector.title': 'Switch Company & Branch',
2875
- 'layout.company.branch.selector.company': 'Company',
2876
2912
  'layout.company.branch.selector.select.company': 'Select Company',
2877
2913
  'layout.company.branch.selector.branch': 'Branch',
2878
2914
  'layout.company.branch.selector.select.branch': 'Select Branch',
2879
2915
  'layout.company.branch.selector.switch.button': 'Switch',
2916
+ 'layout.company.branch.selector.no.company': 'No Company',
2880
2917
  'layout.company.branch.selector.branch.required': 'Branch Required',
2881
2918
  'layout.company.branch.selector.please.select.branch': 'Please select a branch',
2882
- 'layout.company.branch.selector.no.company': 'No Company',
2883
- // Launcher
2884
- 'layout.launcher.apps': 'Apps',
2885
- 'layout.launcher.applications': 'Applications',
2886
- // 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
2887
2928
  'layout.configurator.primary': 'Primary',
2888
2929
  'layout.configurator.surface': 'Surface',
2889
2930
  'layout.configurator.presets': 'Presets',
@@ -2891,26 +2932,30 @@ const LAYOUT_MESSAGES = {
2891
2932
  'layout.configurator.menu.mode.static': 'Static',
2892
2933
  'layout.configurator.menu.mode.overlay': 'Overlay',
2893
2934
  'layout.configurator.menu.mode.topbar': 'Topbar',
2894
- // Topbar accessibility
2895
- 'layout.topbar.toggle.menu': 'Toggle menu',
2896
- 'layout.topbar.toggle.dark.mode': 'Toggle dark mode',
2897
- 'layout.topbar.open.theme.settings': 'Open theme settings',
2898
- 'layout.topbar.more.options': 'More options',
2899
- // Footer
2935
+ // components/app.footer.ts
2900
2936
  'layout.footer.by': 'by',
2901
- // 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
2902
2949
  'notification.title': 'Notifications',
2903
- 'notification.mark.all.read': 'Mark all as read',
2904
- '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
2905
2955
  'notification.time.just.now': 'Just now',
2906
2956
  'notification.time.minutes.ago': '{{count}}m ago',
2907
2957
  'notification.time.hours.ago': '{{count}}h ago',
2908
2958
  'notification.time.days.ago': '{{count}}d ago',
2909
- 'notification.empty': 'No notifications',
2910
- // Home/Dashboard
2911
- 'home.where.users.from': 'Where users are from',
2912
- 'layout.topbar.search': 'Search',
2913
- 'layout.topbar.search.placeholder': 'Search for content...',
2914
2959
  };
2915
2960
 
2916
2961
  // Components