oip-common 0.0.36 → 0.0.38

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,11 +1,11 @@
1
1
  import * as i0 from '@angular/core';
2
- import { Injectable, inject, signal, computed, effect, ChangeDetectorRef, Component, Input, PLATFORM_ID, InjectionToken, HostBinding, EventEmitter, Output, ViewChild, Renderer2, Pipe } from '@angular/core';
3
- import * as i2$5 from 'primeng/api';
2
+ import { Injectable, inject, signal, computed, effect, ChangeDetectorRef, Component, Input, PLATFORM_ID, InjectionToken, HostBinding, EventEmitter, Output, ViewChild, Renderer2, SecurityContext, ChangeDetectionStrategy, Pipe } from '@angular/core';
3
+ import * as i2$6 from 'primeng/api';
4
4
  import { MessageService, ConfirmationService, PrimeIcons, SharedModule } from 'primeng/api';
5
5
  import { HttpErrorResponse, HttpClient as HttpClient$1, HttpHeaders } from '@angular/common/http';
6
- import * as i2$3 from '@ngx-translate/core';
6
+ import * as i2$4 from '@ngx-translate/core';
7
7
  import { TranslateService, TranslatePipe, TranslateModule } from '@ngx-translate/core';
8
- import * as i1$2 from '@angular/router';
8
+ import * as i1$3 from '@angular/router';
9
9
  import { ActivatedRoute, Router, RouterModule, NavigationEnd, RouterLinkActive, RouterLink } from '@angular/router';
10
10
  import { lastValueFrom, BehaviorSubject, Subject, filter as filter$1, combineLatest, of, map as map$1, Observable } from 'rxjs';
11
11
  import { Title, DomSanitizer } from '@angular/platform-browser';
@@ -13,12 +13,12 @@ import * as i1 from 'primeng/multiselect';
13
13
  import { MultiSelectModule } from 'primeng/multiselect';
14
14
  import * as i2 from 'primeng/tooltip';
15
15
  import { TooltipModule, Tooltip } from 'primeng/tooltip';
16
- import * as i1$1 from 'primeng/button';
16
+ import * as i1$2 from 'primeng/button';
17
17
  import { ButtonModule, Button } from 'primeng/button';
18
- import * as i5 from '@angular/forms';
18
+ import * as i1$1 from '@angular/forms';
19
19
  import { FormsModule, ReactiveFormsModule } from '@angular/forms';
20
20
  import * as i2$1 from '@angular/common';
21
- import { isPlatformBrowser, CommonModule, NgComponentOutlet, NgClass } from '@angular/common';
21
+ import { isPlatformBrowser, CommonModule, NgComponentOutlet, NgClass, DatePipe } from '@angular/common';
22
22
  import * as i3$1 from 'primeng/styleclass';
23
23
  import { StyleClassModule } from 'primeng/styleclass';
24
24
  import { updatePreset, updateSurfacePalette, $t } from '@primeng/themes';
@@ -31,11 +31,11 @@ import { SelectButtonModule } from 'primeng/selectbutton';
31
31
  import { OidcSecurityService, PublicEventsService, EventTypes, StsConfigHttpLoader } from 'angular-auth-oidc-client';
32
32
  import { filter, map, switchMap, catchError } from 'rxjs/operators';
33
33
  import { Tabs, TabList, Tab } from 'primeng/tabs';
34
- import * as i4 from 'primeng/avatar';
34
+ import * as i2$2 from 'primeng/avatar';
35
35
  import { AvatarModule } from 'primeng/avatar';
36
- import * as i1$3 from 'primeng/contextmenu';
36
+ import * as i1$4 from 'primeng/contextmenu';
37
37
  import { ContextMenuModule, ContextMenu } from 'primeng/contextmenu';
38
- import * as i2$2 from 'primeng/dialog';
38
+ import * as i2$3 from 'primeng/dialog';
39
39
  import { DialogModule } from 'primeng/dialog';
40
40
  import * as i3$3 from 'primeng/inputtext';
41
41
  import { InputTextModule } from 'primeng/inputtext';
@@ -43,19 +43,29 @@ import { trigger, state, transition, style, animate } from '@angular/animations'
43
43
  import * as i3$2 from 'primeng/ripple';
44
44
  import { RippleModule } from 'primeng/ripple';
45
45
  import { ConfirmDialog } from 'primeng/confirmdialog';
46
- import * as i4$1 from 'primeng/select';
46
+ import * as i4 from 'primeng/select';
47
47
  import { SelectModule, Select } from 'primeng/select';
48
- import * as i1$4 from 'primeng/fileupload';
48
+ import * as i1$5 from 'primeng/fileupload';
49
49
  import { FileUploadModule } from 'primeng/fileupload';
50
50
  import { ImageModule } from 'primeng/image';
51
- import * as i1$5 from 'primeng/table';
51
+ import * as i1$6 from 'primeng/table';
52
52
  import { TableModule } from 'primeng/table';
53
- import * as i2$4 from 'primeng/toggleswitch';
53
+ import * as i2$5 from 'primeng/toggleswitch';
54
54
  import { ToggleSwitchModule } from 'primeng/toggleswitch';
55
+ import * as i9 from 'primeng/tag';
55
56
  import { TagModule, Tag } from 'primeng/tag';
56
- import { TextareaModule } from 'primeng/textarea';
57
- import * as i4$2 from 'primeng/toolbar';
57
+ import { TextareaModule, Textarea } from 'primeng/textarea';
58
+ import * as i4$1 from 'primeng/toolbar';
58
59
  import { ToolbarModule } from 'primeng/toolbar';
60
+ import * as i5 from 'primeng/card';
61
+ import { CardModule } from 'primeng/card';
62
+ import { DividerModule } from 'primeng/divider';
63
+ import * as i6 from 'primeng/panel';
64
+ import { PanelModule } from 'primeng/panel';
65
+ import * as i7 from 'primeng/popover';
66
+ import { PopoverModule } from 'primeng/popover';
67
+ import * as i8 from 'primeng/progressspinner';
68
+ import { ProgressSpinnerModule } from 'primeng/progressspinner';
59
69
  import * as signalR from '@microsoft/signalr';
60
70
 
61
71
  class TopBarService {
@@ -145,6 +155,24 @@ class MsgService {
145
155
  life: life
146
156
  });
147
157
  }
158
+ extractErrorMessage(error, fallback) {
159
+ if (typeof error === 'object' &&
160
+ error &&
161
+ 'error' in error &&
162
+ typeof error.error === 'object' &&
163
+ error.error &&
164
+ 'message' in error.error &&
165
+ typeof error.error.message === 'string') {
166
+ return error.error.message;
167
+ }
168
+ if (typeof error === 'object' && error && 'message' in error && typeof error.message === 'string') {
169
+ return error.message;
170
+ }
171
+ return fallback;
172
+ }
173
+ errorFromException(error, fallback, summary = fallback, life = this.lifetime) {
174
+ this.error(this.extractErrorMessage(error, fallback), summary, life);
175
+ }
148
176
  contrast(detail, summary = this.translate.instant('msgService.error'), life = this.lifetime) {
149
177
  this.messageService.add({
150
178
  severity: 'contrast',
@@ -537,6 +565,9 @@ class BaseModuleComponent {
537
565
  if (localStorageSettingsString != null) {
538
566
  this.localSettings.set(JSON.parse(localStorageSettingsString));
539
567
  }
568
+ else {
569
+ this.localSettings.set({});
570
+ }
540
571
  }
541
572
  catch (error) {
542
573
  this.msgService.error(error, 'Error parsing layoutConfig:');
@@ -568,6 +599,8 @@ class BaseModuleComponent {
568
599
  * Initializes the component and subscribes to local settings updates.
569
600
  */
570
601
  constructor() {
602
+ this.isInitialized = false;
603
+ this.moduleInstanceReloadPromise = Promise.resolve();
571
604
  /**
572
605
  * Provide access to app settings
573
606
  */
@@ -653,8 +686,14 @@ class BaseModuleComponent {
653
686
  this.controller = url[0].path;
654
687
  }));
655
688
  this.subscriptions.push(this.route.paramMap.subscribe((params) => {
656
- this.id = +params.get('id');
689
+ const routeId = params.get('id');
690
+ const nextId = routeId != null ? +routeId : undefined;
691
+ const idChanged = this.id !== nextId;
692
+ this.id = nextId;
657
693
  this.getLocalStorageSettings();
694
+ if (this.isInitialized && idChanged) {
695
+ void this.reloadModuleInstance();
696
+ }
658
697
  }));
659
698
  }
660
699
  /**
@@ -682,7 +721,8 @@ class BaseModuleComponent {
682
721
  }));
683
722
  this.topBarService.setTopBarItems(this.topBarItems);
684
723
  this.topBarService.activeId = this.topBarItems[0].id;
685
- await this.getSettings();
724
+ this.isInitialized = true;
725
+ await this.reloadModuleInstance();
686
726
  this.subscriptions.push(this.appTitleService.title$.subscribe((title) => {
687
727
  this.title = title;
688
728
  this.changeDetectorRef.detectChanges();
@@ -718,6 +758,18 @@ class BaseModuleComponent {
718
758
  this.msgService.error(error);
719
759
  });
720
760
  }
761
+ /**
762
+ * Called whenever the module instance changes, including the first load.
763
+ * Derived components can override this to refresh module-specific data.
764
+ */
765
+ async onModuleInstanceChange() { }
766
+ async reloadModuleInstance() {
767
+ this.moduleInstanceReloadPromise = this.moduleInstanceReloadPromise.then(async () => {
768
+ await this.getSettings();
769
+ await this.onModuleInstanceChange();
770
+ });
771
+ await this.moduleInstanceReloadPromise;
772
+ }
721
773
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: BaseModuleComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
722
774
  static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.16", type: BaseModuleComponent, isStandalone: true, selector: "ng-component", ngImport: i0, template: '', isInline: true }); }
723
775
  }
@@ -814,7 +866,7 @@ class SecurityComponent {
814
866
  </div>
815
867
  </div>
816
868
  </div>
817
- `, isInline: true, dependencies: [{ kind: "ngmodule", type: MultiSelectModule }, { kind: "component", type: i1.MultiSelect, selector: "p-multiSelect, p-multiselect, p-multi-select", inputs: ["id", "ariaLabel", "styleClass", "panelStyle", "panelStyleClass", "inputId", "readonly", "group", "filter", "filterPlaceHolder", "filterLocale", "overlayVisible", "tabindex", "dataKey", "ariaLabelledBy", "displaySelectedLabel", "maxSelectedLabels", "selectionLimit", "selectedItemsLabel", "showToggleAll", "emptyFilterMessage", "emptyMessage", "resetFilterOnHide", "dropdownIcon", "chipIcon", "optionLabel", "optionValue", "optionDisabled", "optionGroupLabel", "optionGroupChildren", "showHeader", "filterBy", "scrollHeight", "lazy", "virtualScroll", "loading", "virtualScrollItemSize", "loadingIcon", "virtualScrollOptions", "overlayOptions", "ariaFilterLabel", "filterMatchMode", "tooltip", "tooltipPosition", "tooltipPositionStyle", "tooltipStyleClass", "autofocusFilter", "display", "autocomplete", "showClear", "autofocus", "placeholder", "options", "filterValue", "selectAll", "focusOnHover", "filterFields", "selectOnFocus", "autoOptionFocus", "highlightOnSelect", "size", "variant", "fluid", "appendTo"], outputs: ["onChange", "onFilter", "onFocus", "onBlur", "onClick", "onClear", "onPanelShow", "onPanelHide", "onLazyLoad", "onRemove", "onSelectAllChange"] }, { kind: "ngmodule", type: TooltipModule }, { kind: "directive", type: i2.Tooltip, selector: "[pTooltip]", inputs: ["tooltipPosition", "tooltipEvent", "positionStyle", "tooltipStyleClass", "tooltipZIndex", "escape", "showDelay", "hideDelay", "life", "positionTop", "positionLeft", "autoHide", "fitContent", "hideOnEscape", "pTooltip", "tooltipDisabled", "tooltipOptions", "appendTo", "ptTooltip"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i5.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i5.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: ButtonModule }, { kind: "component", type: i1$1.Button, selector: "p-button", inputs: ["hostName", "type", "badge", "disabled", "raised", "rounded", "text", "plain", "outlined", "link", "tabindex", "size", "variant", "style", "styleClass", "badgeClass", "badgeSeverity", "ariaLabel", "autofocus", "iconPos", "icon", "label", "loading", "loadingIcon", "severity", "buttonProps", "fluid"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }] }); }
869
+ `, isInline: true, dependencies: [{ kind: "ngmodule", type: MultiSelectModule }, { kind: "component", type: i1.MultiSelect, selector: "p-multiSelect, p-multiselect, p-multi-select", inputs: ["id", "ariaLabel", "styleClass", "panelStyle", "panelStyleClass", "inputId", "readonly", "group", "filter", "filterPlaceHolder", "filterLocale", "overlayVisible", "tabindex", "dataKey", "ariaLabelledBy", "displaySelectedLabel", "maxSelectedLabels", "selectionLimit", "selectedItemsLabel", "showToggleAll", "emptyFilterMessage", "emptyMessage", "resetFilterOnHide", "dropdownIcon", "chipIcon", "optionLabel", "optionValue", "optionDisabled", "optionGroupLabel", "optionGroupChildren", "showHeader", "filterBy", "scrollHeight", "lazy", "virtualScroll", "loading", "virtualScrollItemSize", "loadingIcon", "virtualScrollOptions", "overlayOptions", "ariaFilterLabel", "filterMatchMode", "tooltip", "tooltipPosition", "tooltipPositionStyle", "tooltipStyleClass", "autofocusFilter", "display", "autocomplete", "showClear", "autofocus", "placeholder", "options", "filterValue", "selectAll", "focusOnHover", "filterFields", "selectOnFocus", "autoOptionFocus", "highlightOnSelect", "size", "variant", "fluid", "appendTo"], outputs: ["onChange", "onFilter", "onFocus", "onBlur", "onClick", "onClear", "onPanelShow", "onPanelHide", "onLazyLoad", "onRemove", "onSelectAllChange"] }, { kind: "ngmodule", type: TooltipModule }, { kind: "directive", type: i2.Tooltip, selector: "[pTooltip]", inputs: ["tooltipPosition", "tooltipEvent", "positionStyle", "tooltipStyleClass", "tooltipZIndex", "escape", "showDelay", "hideDelay", "life", "positionTop", "positionLeft", "autoHide", "fitContent", "hideOnEscape", "pTooltip", "tooltipDisabled", "tooltipOptions", "appendTo", "ptTooltip"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: ButtonModule }, { kind: "component", type: i1$2.Button, selector: "p-button", inputs: ["hostName", "type", "badge", "disabled", "raised", "rounded", "text", "plain", "outlined", "link", "tabindex", "size", "variant", "style", "styleClass", "badgeClass", "badgeSeverity", "ariaLabel", "autofocus", "iconPos", "icon", "label", "loading", "loadingIcon", "severity", "buttonProps", "fluid"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }] }); }
818
870
  }
819
871
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: SecurityComponent, decorators: [{
820
872
  type: Component,
@@ -1293,7 +1345,7 @@ class AppConfiguratorComponent {
1293
1345
  </div>
1294
1346
  }
1295
1347
  </div>
1296
- `, isInline: true, dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i2$1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i5.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i5.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: SelectButtonModule }, { kind: "component", type: i3.SelectButton, selector: "p-selectButton, p-selectbutton, p-select-button", inputs: ["options", "optionLabel", "optionValue", "optionDisabled", "unselectable", "tabindex", "multiple", "allowEmpty", "styleClass", "ariaLabelledBy", "dataKey", "autofocus", "size", "fluid"], outputs: ["onOptionClick", "onChange"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }] }); }
1348
+ `, isInline: true, dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i2$1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: SelectButtonModule }, { kind: "component", type: i3.SelectButton, selector: "p-selectButton, p-selectbutton, p-select-button", inputs: ["options", "optionLabel", "optionValue", "optionDisabled", "unselectable", "tabindex", "multiple", "allowEmpty", "styleClass", "ariaLabelledBy", "dataKey", "autofocus", "size", "fluid"], outputs: ["onOptionClick", "onChange"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }] }); }
1297
1349
  }
1298
1350
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: AppConfiguratorComponent, decorators: [{
1299
1351
  type: Component,
@@ -1734,7 +1786,7 @@ class AppTopbar {
1734
1786
  </div>
1735
1787
  </div>
1736
1788
  </div>
1737
- </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: CommonModule }, { kind: "directive", type: i2$1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i2$1.NgComponentOutlet, selector: "[ngComponentOutlet]", inputs: ["ngComponentOutlet", "ngComponentOutletInputs", "ngComponentOutletInjector", "ngComponentOutletEnvironmentInjector", "ngComponentOutletContent", "ngComponentOutletNgModule", "ngComponentOutletNgModuleFactory"], exportAs: ["ngComponentOutlet"] }, { kind: "ngmodule", type: StyleClassModule }, { kind: "directive", type: i3$1.StyleClass, selector: "[pStyleClass]", inputs: ["pStyleClass", "enterFromClass", "enterActiveClass", "enterToClass", "leaveFromClass", "leaveActiveClass", "leaveToClass", "hideOnOutsideClick", "toggleClass", "hideOnEscape", "hideOnResize", "resizeSelector"] }, { kind: "component", type: AppConfiguratorComponent, selector: "app-configurator" }, { kind: "component", type: Tabs, selector: "p-tabs", inputs: ["value", "scrollable", "lazy", "selectOnFocus", "showNavigators", "tabindex"], outputs: ["valueChange"] }, { kind: "component", type: TabList, selector: "p-tablist" }, { kind: "component", type: Tab, selector: "p-tab", inputs: ["value", "disabled"], outputs: ["valueChange"] }, { kind: "ngmodule", type: AvatarModule }, { kind: "component", type: i4.Avatar, selector: "p-avatar", inputs: ["label", "icon", "image", "size", "shape", "styleClass", "ariaLabel", "ariaLabelledBy"], outputs: ["onImageError"] }, { kind: "ngmodule", type: ButtonModule }, { kind: "component", type: i1$1.Button, selector: "p-button", inputs: ["hostName", "type", "badge", "disabled", "raised", "rounded", "text", "plain", "outlined", "link", "tabindex", "size", "variant", "style", "styleClass", "badgeClass", "badgeSeverity", "ariaLabel", "autofocus", "iconPos", "icon", "label", "loading", "loadingIcon", "severity", "buttonProps", "fluid"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }] }); }
1789
+ </div>`, isInline: true, dependencies: [{ kind: "ngmodule", type: RouterModule }, { kind: "directive", type: i1$3.RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "routerLink"] }, { kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i2$1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i2$1.NgComponentOutlet, selector: "[ngComponentOutlet]", inputs: ["ngComponentOutlet", "ngComponentOutletInputs", "ngComponentOutletInjector", "ngComponentOutletEnvironmentInjector", "ngComponentOutletContent", "ngComponentOutletNgModule", "ngComponentOutletNgModuleFactory"], exportAs: ["ngComponentOutlet"] }, { kind: "ngmodule", type: StyleClassModule }, { kind: "directive", type: i3$1.StyleClass, selector: "[pStyleClass]", inputs: ["pStyleClass", "enterFromClass", "enterActiveClass", "enterToClass", "leaveFromClass", "leaveActiveClass", "leaveToClass", "hideOnOutsideClick", "toggleClass", "hideOnEscape", "hideOnResize", "resizeSelector"] }, { kind: "component", type: AppConfiguratorComponent, selector: "app-configurator" }, { kind: "component", type: Tabs, selector: "p-tabs", inputs: ["value", "scrollable", "lazy", "selectOnFocus", "showNavigators", "tabindex"], outputs: ["valueChange"] }, { kind: "component", type: TabList, selector: "p-tablist" }, { kind: "component", type: Tab, selector: "p-tab", inputs: ["value", "disabled"], outputs: ["valueChange"] }, { kind: "ngmodule", type: AvatarModule }, { kind: "component", type: i2$2.Avatar, selector: "p-avatar", inputs: ["label", "icon", "image", "size", "shape", "styleClass", "ariaLabel", "ariaLabelledBy"], outputs: ["onImageError"] }, { kind: "ngmodule", type: ButtonModule }, { kind: "component", type: i1$2.Button, selector: "p-button", inputs: ["hostName", "type", "badge", "disabled", "raised", "rounded", "text", "plain", "outlined", "link", "tabindex", "size", "variant", "style", "styleClass", "badgeClass", "badgeSeverity", "ariaLabel", "autofocus", "iconPos", "icon", "label", "loading", "loadingIcon", "severity", "buttonProps", "fluid"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }] }); }
1738
1790
  }
1739
1791
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: AppTopbar, decorators: [{
1740
1792
  type: Component,
@@ -1903,9 +1955,20 @@ var ContentType;
1903
1955
  ContentType["Text"] = "text/plain";
1904
1956
  })(ContentType || (ContentType = {}));
1905
1957
  class HttpClient {
1906
- constructor(apiConfig = {}) {
1958
+ constructor() {
1959
+ this.securityService = inject(SecurityService);
1960
+ this.layoutService = inject(LayoutService);
1907
1961
  this.baseUrl = "";
1908
1962
  this.securityData = null;
1963
+ this.securityWorker = (securityData) => ({
1964
+ headers: {
1965
+ "Accept-language": this.layoutService.language()
1966
+ ? this.layoutService.language()
1967
+ : "en",
1968
+ "X-Timezone": this.layoutService.timeZone(),
1969
+ Authorization: `Bearer ${securityData}`,
1970
+ },
1971
+ });
1909
1972
  this.abortControllers = new Map();
1910
1973
  this.customFetch = (...fetchParams) => fetch(...fetchParams);
1911
1974
  this.baseApiParams = {
@@ -1970,7 +2033,7 @@ class HttpClient {
1970
2033
  const requestParams = this.mergeRequestParams(params, secureParams);
1971
2034
  const queryString = query && this.toQueryString(query);
1972
2035
  const payloadFormatter = this.contentFormatters[type || ContentType.Json];
1973
- const responseFormat = format || requestParams.format;
2036
+ let responseFormat = format || requestParams.format;
1974
2037
  return this.customFetch(`${baseUrl || this.baseUrl || ""}${path}${queryString ? `?${queryString}` : ""}`, {
1975
2038
  ...requestParams,
1976
2039
  headers: {
@@ -2016,7 +2079,9 @@ class HttpClient {
2016
2079
  return data.data;
2017
2080
  });
2018
2081
  };
2019
- Object.assign(this, apiConfig);
2082
+ this.securityService.getAccessToken().subscribe((token) => {
2083
+ this.securityData = token;
2084
+ });
2020
2085
  }
2021
2086
  encodeQueryParam(key, value) {
2022
2087
  const encodedKey = encodeURIComponent(key);
@@ -2054,13 +2119,13 @@ class HttpClient {
2054
2119
  },
2055
2120
  };
2056
2121
  }
2057
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: HttpClient, deps: "invalid", target: i0.ɵɵFactoryTarget.Injectable }); }
2122
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: HttpClient, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
2058
2123
  static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: HttpClient, providedIn: "root" }); }
2059
2124
  }
2060
2125
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: HttpClient, decorators: [{
2061
2126
  type: Injectable,
2062
2127
  args: [{ providedIn: "root" }]
2063
- }], ctorParameters: () => [{ type: undefined }] });
2128
+ }], ctorParameters: () => [] });
2064
2129
 
2065
2130
  /* eslint-disable */
2066
2131
  /* tslint:disable */
@@ -2359,7 +2424,7 @@ class MenuItemComponent {
2359
2424
  },
2360
2425
  { separator: true, visible: this.hasVisibleNext(item) || this.hasVisiblePrev(item) },
2361
2426
  {
2362
- label: 'Up',
2427
+ label: this.localization.moveUp,
2363
2428
  icon: PrimeIcons.ANGLE_UP,
2364
2429
  command: (event) => {
2365
2430
  this.moveUp(item);
@@ -2369,7 +2434,7 @@ class MenuItemComponent {
2369
2434
  visible: this.hasVisiblePrev(item)
2370
2435
  },
2371
2436
  {
2372
- label: 'Down',
2437
+ label: this.localization.moveDown,
2373
2438
  icon: PrimeIcons.ANGLE_DOWN,
2374
2439
  command: (event) => {
2375
2440
  this.moveDown(item);
@@ -2470,79 +2535,79 @@ class MenuItemComponent {
2470
2535
  const currentIndex = items.findIndex((item) => item.moduleInstanceId == currentItem.moduleInstanceId);
2471
2536
  return currentIndex < items.length - 1;
2472
2537
  }
2473
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: MenuItemComponent, deps: [{ token: i0.ChangeDetectorRef }, { token: i1$2.Router }, { token: MenuService }], target: i0.ɵɵFactoryTarget.Component }); }
2474
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.16", type: MenuItemComponent, isStandalone: true, selector: "[app-menuitem]", inputs: { item: "item", index: "index", root: "root", parentKey: "parentKey", menuItemCreateDialogComponent: "menuItemCreateDialogComponent", menuItemEditDialogComponent: "menuItemEditDialogComponent", contextMenu: "contextMenu" }, host: { properties: { "class.layout-root-menuitem": "this.root", "class.active-menuitem": "this.activeClass" } }, providers: [ConfirmationService], ngImport: i0, template: `
2475
- <ng-container>
2476
- <p-confirm-dialog />
2477
- @if (root && item.visible !== false) {
2478
- <div class="layout-menuitem-root-text" (contextmenu)="onContextMenu($event, item)">
2479
- {{ item.label }}
2480
- </div>
2481
- }
2482
- @if ((!item.routerLink || item.items) && item.visible !== false) {
2483
- <a
2484
- pRipple
2485
- tabindex="0"
2486
- [attr.href]="item.url"
2487
- [attr.target]="item.target"
2488
- [ngClass]="item.class"
2489
- (click)="itemClick($event)">
2490
- <i class="layout-menuitem-icon" [ngClass]="item.icon"></i>
2491
- <span class="layout-menuitem-text">{{ item.label }}</span>
2492
- @if (item.items) {
2493
- <i class="pi pi-fw pi-angle-down layout-submenu-toggler"></i>
2494
- }
2495
- </a>
2496
- }
2497
- @if (item.routerLink && !item.items && item.visible !== false) {
2498
- <a
2499
- pRipple
2500
- routerLinkActive="active-route"
2501
- tabindex="0"
2502
- [attr.target]="item.target"
2503
- [fragment]="item.fragment"
2504
- [ngClass]="item.class"
2505
- [preserveFragment]="item.preserveFragment"
2506
- [queryParams]="item.queryParams"
2507
- [queryParamsHandling]="item.queryParamsHandling"
2508
- [replaceUrl]="item.replaceUrl"
2509
- [routerLink]="item.routerLink"
2510
- [routerLinkActiveOptions]="
2511
- item.routerLinkActiveOptions || {
2512
- paths: 'exact',
2513
- queryParams: 'ignored',
2514
- matrixParams: 'ignored',
2515
- fragment: 'ignored'
2516
- }
2517
- "
2518
- [skipLocationChange]="item.skipLocationChange"
2519
- [state]="item.state"
2520
- (click)="itemClick($event)"
2521
- (contextmenu)="onContextMenu($event, item)">
2522
- <i class="layout-menuitem-icon" [ngClass]="item.icon"></i>
2523
- <span class="layout-menuitem-text">{{ item.label }}</span>
2524
- @if (item.items) {
2525
- <i class="pi pi-fw pi-angle-down layout-submenu-toggler"></i>
2526
- }
2527
- </a>
2528
- }
2529
-
2530
- @if (item.items && item.visible !== false) {
2531
- <ul [@children]="submenuAnimation" (contextmenu)="onContextMenu($event, item)">
2532
- @for (child of item.items; track child; let i = $index) {
2533
- <li
2534
- app-menuitem
2535
- [class]="child.badgeClass"
2536
- [contextMenu]="contextMenu"
2537
- [index]="i"
2538
- [item]="child"
2539
- [menuItemCreateDialogComponent]="menuItemCreateDialogComponent"
2540
- [menuItemEditDialogComponent]="menuItemEditDialogComponent"
2541
- [parentKey]="key"></li>
2542
- }
2543
- </ul>
2544
- }
2545
- </ng-container>
2538
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: MenuItemComponent, deps: [{ token: i0.ChangeDetectorRef }, { token: i1$3.Router }, { token: MenuService }], target: i0.ɵɵFactoryTarget.Component }); }
2539
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.16", type: MenuItemComponent, isStandalone: true, selector: "[app-menuitem]", inputs: { item: "item", index: "index", root: "root", parentKey: "parentKey", menuItemCreateDialogComponent: "menuItemCreateDialogComponent", menuItemEditDialogComponent: "menuItemEditDialogComponent", contextMenu: "contextMenu" }, host: { properties: { "class.layout-root-menuitem": "this.root", "class.active-menuitem": "this.activeClass" } }, providers: [ConfirmationService], ngImport: i0, template: `
2540
+ <ng-container>
2541
+ <p-confirm-dialog />
2542
+ @if (root && item.visible !== false) {
2543
+ <div class="layout-menuitem-root-text" (contextmenu)="onContextMenu($event, item)">
2544
+ {{ item.label }}
2545
+ </div>
2546
+ }
2547
+ @if ((!item.routerLink || item.items) && item.visible !== false) {
2548
+ <a
2549
+ pRipple
2550
+ tabindex="0"
2551
+ [attr.href]="item.url"
2552
+ [attr.target]="item.target"
2553
+ [ngClass]="item.class"
2554
+ (click)="itemClick($event)">
2555
+ <i class="layout-menuitem-icon" [ngClass]="item.icon"></i>
2556
+ <span class="layout-menuitem-text">{{ item.label }}</span>
2557
+ @if (item.items) {
2558
+ <i class="pi pi-fw pi-angle-down layout-submenu-toggler"></i>
2559
+ }
2560
+ </a>
2561
+ }
2562
+ @if (item.routerLink && !item.items && item.visible !== false) {
2563
+ <a
2564
+ pRipple
2565
+ routerLinkActive="active-route"
2566
+ tabindex="0"
2567
+ [attr.target]="item.target"
2568
+ [fragment]="item.fragment"
2569
+ [ngClass]="item.class"
2570
+ [preserveFragment]="item.preserveFragment"
2571
+ [queryParams]="item.queryParams"
2572
+ [queryParamsHandling]="item.queryParamsHandling"
2573
+ [replaceUrl]="item.replaceUrl"
2574
+ [routerLink]="item.routerLink"
2575
+ [routerLinkActiveOptions]="
2576
+ item.routerLinkActiveOptions || {
2577
+ paths: 'exact',
2578
+ queryParams: 'ignored',
2579
+ matrixParams: 'ignored',
2580
+ fragment: 'ignored'
2581
+ }
2582
+ "
2583
+ [skipLocationChange]="item.skipLocationChange"
2584
+ [state]="item.state"
2585
+ (click)="itemClick($event)"
2586
+ (contextmenu)="onContextMenu($event, item)">
2587
+ <i class="layout-menuitem-icon" [ngClass]="item.icon"></i>
2588
+ <span class="layout-menuitem-text">{{ item.label }}</span>
2589
+ @if (item.items) {
2590
+ <i class="pi pi-fw pi-angle-down layout-submenu-toggler"></i>
2591
+ }
2592
+ </a>
2593
+ }
2594
+
2595
+ @if (item.items && item.visible !== false) {
2596
+ <ul [@children]="submenuAnimation" (contextmenu)="onContextMenu($event, item)">
2597
+ @for (child of item.items; track child; let i = $index) {
2598
+ <li
2599
+ app-menuitem
2600
+ [class]="child.badgeClass"
2601
+ [contextMenu]="contextMenu"
2602
+ [index]="i"
2603
+ [item]="child"
2604
+ [menuItemCreateDialogComponent]="menuItemCreateDialogComponent"
2605
+ [menuItemEditDialogComponent]="menuItemEditDialogComponent"
2606
+ [parentKey]="key"></li>
2607
+ }
2608
+ </ul>
2609
+ }
2610
+ </ng-container>
2546
2611
  `, isInline: true, dependencies: [{ kind: "component", type: MenuItemComponent, selector: "[app-menuitem]", inputs: ["item", "index", "root", "parentKey", "menuItemCreateDialogComponent", "menuItemEditDialogComponent", "contextMenu"] }, { kind: "ngmodule", type: RippleModule }, { kind: "directive", type: i3$2.Ripple, selector: "[pRipple]" }, { kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: RouterLinkActive, selector: "[routerLinkActive]", inputs: ["routerLinkActiveOptions", "ariaCurrentWhenActive", "routerLinkActive"], outputs: ["isActiveChange"], exportAs: ["routerLinkActive"] }, { kind: "directive", type: RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "routerLink"] }, { kind: "ngmodule", type: ContextMenuModule }, { kind: "component", type: ConfirmDialog, selector: "p-confirmDialog, p-confirmdialog, p-confirm-dialog", inputs: ["header", "icon", "message", "style", "styleClass", "maskStyleClass", "acceptIcon", "acceptLabel", "closeAriaLabel", "acceptAriaLabel", "acceptVisible", "rejectIcon", "rejectLabel", "rejectAriaLabel", "rejectVisible", "acceptButtonStyleClass", "rejectButtonStyleClass", "closeOnEscape", "dismissableMask", "blockScroll", "rtl", "closable", "appendTo", "key", "autoZIndex", "baseZIndex", "transitionOptions", "focusTrap", "defaultFocus", "breakpoints", "modal", "visible", "position", "draggable"], outputs: ["onHide"] }], animations: [
2547
2612
  trigger('children', [
2548
2613
  state('collapsed', style({
@@ -2560,78 +2625,78 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
2560
2625
  args: [{
2561
2626
  // eslint-disable-next-line @angular-eslint/component-selector
2562
2627
  selector: '[app-menuitem]',
2563
- template: `
2564
- <ng-container>
2565
- <p-confirm-dialog />
2566
- @if (root && item.visible !== false) {
2567
- <div class="layout-menuitem-root-text" (contextmenu)="onContextMenu($event, item)">
2568
- {{ item.label }}
2569
- </div>
2570
- }
2571
- @if ((!item.routerLink || item.items) && item.visible !== false) {
2572
- <a
2573
- pRipple
2574
- tabindex="0"
2575
- [attr.href]="item.url"
2576
- [attr.target]="item.target"
2577
- [ngClass]="item.class"
2578
- (click)="itemClick($event)">
2579
- <i class="layout-menuitem-icon" [ngClass]="item.icon"></i>
2580
- <span class="layout-menuitem-text">{{ item.label }}</span>
2581
- @if (item.items) {
2582
- <i class="pi pi-fw pi-angle-down layout-submenu-toggler"></i>
2583
- }
2584
- </a>
2585
- }
2586
- @if (item.routerLink && !item.items && item.visible !== false) {
2587
- <a
2588
- pRipple
2589
- routerLinkActive="active-route"
2590
- tabindex="0"
2591
- [attr.target]="item.target"
2592
- [fragment]="item.fragment"
2593
- [ngClass]="item.class"
2594
- [preserveFragment]="item.preserveFragment"
2595
- [queryParams]="item.queryParams"
2596
- [queryParamsHandling]="item.queryParamsHandling"
2597
- [replaceUrl]="item.replaceUrl"
2598
- [routerLink]="item.routerLink"
2599
- [routerLinkActiveOptions]="
2600
- item.routerLinkActiveOptions || {
2601
- paths: 'exact',
2602
- queryParams: 'ignored',
2603
- matrixParams: 'ignored',
2604
- fragment: 'ignored'
2605
- }
2606
- "
2607
- [skipLocationChange]="item.skipLocationChange"
2608
- [state]="item.state"
2609
- (click)="itemClick($event)"
2610
- (contextmenu)="onContextMenu($event, item)">
2611
- <i class="layout-menuitem-icon" [ngClass]="item.icon"></i>
2612
- <span class="layout-menuitem-text">{{ item.label }}</span>
2613
- @if (item.items) {
2614
- <i class="pi pi-fw pi-angle-down layout-submenu-toggler"></i>
2615
- }
2616
- </a>
2617
- }
2618
-
2619
- @if (item.items && item.visible !== false) {
2620
- <ul [@children]="submenuAnimation" (contextmenu)="onContextMenu($event, item)">
2621
- @for (child of item.items; track child; let i = $index) {
2622
- <li
2623
- app-menuitem
2624
- [class]="child.badgeClass"
2625
- [contextMenu]="contextMenu"
2626
- [index]="i"
2627
- [item]="child"
2628
- [menuItemCreateDialogComponent]="menuItemCreateDialogComponent"
2629
- [menuItemEditDialogComponent]="menuItemEditDialogComponent"
2630
- [parentKey]="key"></li>
2631
- }
2632
- </ul>
2633
- }
2634
- </ng-container>
2628
+ template: `
2629
+ <ng-container>
2630
+ <p-confirm-dialog />
2631
+ @if (root && item.visible !== false) {
2632
+ <div class="layout-menuitem-root-text" (contextmenu)="onContextMenu($event, item)">
2633
+ {{ item.label }}
2634
+ </div>
2635
+ }
2636
+ @if ((!item.routerLink || item.items) && item.visible !== false) {
2637
+ <a
2638
+ pRipple
2639
+ tabindex="0"
2640
+ [attr.href]="item.url"
2641
+ [attr.target]="item.target"
2642
+ [ngClass]="item.class"
2643
+ (click)="itemClick($event)">
2644
+ <i class="layout-menuitem-icon" [ngClass]="item.icon"></i>
2645
+ <span class="layout-menuitem-text">{{ item.label }}</span>
2646
+ @if (item.items) {
2647
+ <i class="pi pi-fw pi-angle-down layout-submenu-toggler"></i>
2648
+ }
2649
+ </a>
2650
+ }
2651
+ @if (item.routerLink && !item.items && item.visible !== false) {
2652
+ <a
2653
+ pRipple
2654
+ routerLinkActive="active-route"
2655
+ tabindex="0"
2656
+ [attr.target]="item.target"
2657
+ [fragment]="item.fragment"
2658
+ [ngClass]="item.class"
2659
+ [preserveFragment]="item.preserveFragment"
2660
+ [queryParams]="item.queryParams"
2661
+ [queryParamsHandling]="item.queryParamsHandling"
2662
+ [replaceUrl]="item.replaceUrl"
2663
+ [routerLink]="item.routerLink"
2664
+ [routerLinkActiveOptions]="
2665
+ item.routerLinkActiveOptions || {
2666
+ paths: 'exact',
2667
+ queryParams: 'ignored',
2668
+ matrixParams: 'ignored',
2669
+ fragment: 'ignored'
2670
+ }
2671
+ "
2672
+ [skipLocationChange]="item.skipLocationChange"
2673
+ [state]="item.state"
2674
+ (click)="itemClick($event)"
2675
+ (contextmenu)="onContextMenu($event, item)">
2676
+ <i class="layout-menuitem-icon" [ngClass]="item.icon"></i>
2677
+ <span class="layout-menuitem-text">{{ item.label }}</span>
2678
+ @if (item.items) {
2679
+ <i class="pi pi-fw pi-angle-down layout-submenu-toggler"></i>
2680
+ }
2681
+ </a>
2682
+ }
2683
+
2684
+ @if (item.items && item.visible !== false) {
2685
+ <ul [@children]="submenuAnimation" (contextmenu)="onContextMenu($event, item)">
2686
+ @for (child of item.items; track child; let i = $index) {
2687
+ <li
2688
+ app-menuitem
2689
+ [class]="child.badgeClass"
2690
+ [contextMenu]="contextMenu"
2691
+ [index]="i"
2692
+ [item]="child"
2693
+ [menuItemCreateDialogComponent]="menuItemCreateDialogComponent"
2694
+ [menuItemEditDialogComponent]="menuItemEditDialogComponent"
2695
+ [parentKey]="key"></li>
2696
+ }
2697
+ </ul>
2698
+ }
2699
+ </ng-container>
2635
2700
  `,
2636
2701
  animations: [
2637
2702
  trigger('children', [
@@ -2647,7 +2712,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
2647
2712
  imports: [RippleModule, NgClass, RouterLinkActive, RouterLink, ContextMenuModule, ConfirmDialog],
2648
2713
  providers: [ConfirmationService]
2649
2714
  }]
2650
- }], ctorParameters: () => [{ type: i0.ChangeDetectorRef }, { type: i1$2.Router }, { type: MenuService }], propDecorators: { item: [{
2715
+ }], ctorParameters: () => [{ type: i0.ChangeDetectorRef }, { type: i1$3.Router }, { type: MenuService }], propDecorators: { item: [{
2651
2716
  type: Input
2652
2717
  }], index: [{
2653
2718
  type: Input
@@ -2704,68 +2769,68 @@ class MenuItemCreateDialogComponent {
2704
2769
  this.visibleChange.emit(this.visible);
2705
2770
  }
2706
2771
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: MenuItemCreateDialogComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
2707
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.16", type: MenuItemCreateDialogComponent, isStandalone: true, selector: "menu-item-create-dialog", inputs: { visible: "visible" }, outputs: { visibleChange: "visibleChange" }, ngImport: i0, template: `
2708
- <p-dialog
2709
- header="{{ 'menuItemCreateDialogComponent.header' | translate }}"
2710
- [modal]="true"
2711
- [style]="{ width: '40rem' }"
2712
- [(visible)]="visible">
2713
- @if (menuService.contextMenuItem) {
2714
- <div class="flex items-center gap-4 mb-4 mt-1">
2715
- <label class="font-semibold w-1/3" for="oip-menu-item-create-dialog-parent-input">
2716
- {{ 'menuItemCreateDialogComponent.parentLabel' | translate }}
2717
- </label>
2718
- <input
2719
- autocomplete="off"
2720
- class="flex-auto"
2721
- id="oip-menu-item-create-dialog-parent-input"
2722
- pInputText
2723
- readonly
2724
- [ngModel]="menuService.contextMenuItem?.label" />
2725
- </div>
2726
- }
2727
- <div class="flex items-center gap-4 mb-4">
2728
- <label class="font-semibold w-1/3" for="oip-menu-item-create-label">
2729
- {{ 'menuItemCreateDialogComponent.label' | translate }}
2730
- </label>
2731
- <input autocomplete="off" class="flex-auto" id="oip-menu-item-create-label" pInputText [(ngModel)]="label" />
2732
- </div>
2733
- <div class="flex items-center gap-4 mb-4">
2734
- <label class="font-semibold w-1/3" for="oip-menu-item-create-module">
2735
- {{ 'menuItemCreateDialogComponent.module' | translate }}
2736
- </label>
2737
- <p-select
2738
- appendTo="body"
2739
- class="flex-auto"
2740
- id="oip-menu-item-create-module"
2741
- optionLabel="value"
2742
- optionValue="key"
2743
- placeholder="{{ 'menuItemCreateDialogComponent.selectModule' | translate }}"
2744
- [options]="modules"
2745
- [(ngModel)]="selectModule" />
2746
- </div>
2747
- <div class="flex items-center gap-4 mb-4">
2748
- <label class="font-semibold w-1/3" for="oip-menu-item-create-dialog-icon">
2749
- {{ 'menuItemCreateDialogComponent.icon' | translate }}
2750
- </label>
2751
- <i class="{{ selectIcon }}"></i>
2752
- <input class="flex-auto" id="oip-menu-item-create-dialog-icon" pInputText [(ngModel)]="selectIcon" />
2753
- </div>
2754
- <div class="flex justify-end gap-2">
2755
- <p-button
2756
- id="oip-menu-item-create-cancel"
2757
- label="{{ 'menuItemCreateDialogComponent.cancel' | translate }}"
2758
- severity="secondary"
2759
- (click)="changeVisible()"
2760
- (keydown)="changeVisible()" />
2761
- <p-button
2762
- id="oip-menu-item-create-save"
2763
- label="{{ 'menuItemCreateDialogComponent.save' | translate }}"
2764
- (click)="save()"
2765
- (keydown)="save()" />
2766
- </div>
2767
- </p-dialog>
2768
- `, isInline: true, dependencies: [{ kind: "ngmodule", type: ButtonModule }, { kind: "component", type: i1$1.Button, selector: "p-button", inputs: ["hostName", "type", "badge", "disabled", "raised", "rounded", "text", "plain", "outlined", "link", "tabindex", "size", "variant", "style", "styleClass", "badgeClass", "badgeSeverity", "ariaLabel", "autofocus", "iconPos", "icon", "label", "loading", "loadingIcon", "severity", "buttonProps", "fluid"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "ngmodule", type: DialogModule }, { kind: "component", type: i2$2.Dialog, selector: "p-dialog", inputs: ["hostName", "header", "draggable", "resizable", "contentStyle", "contentStyleClass", "modal", "closeOnEscape", "dismissableMask", "rtl", "closable", "breakpoints", "styleClass", "maskStyleClass", "maskStyle", "showHeader", "blockScroll", "autoZIndex", "baseZIndex", "minX", "minY", "focusOnShow", "maximizable", "keepInViewport", "focusTrap", "transitionOptions", "closeIcon", "closeAriaLabel", "closeTabindex", "minimizeIcon", "maximizeIcon", "closeButtonProps", "maximizeButtonProps", "visible", "style", "position", "role", "appendTo", "content", "contentTemplate", "footerTemplate", "closeIconTemplate", "maximizeIconTemplate", "minimizeIconTemplate", "headlessTemplate"], outputs: ["onShow", "onHide", "visibleChange", "onResizeInit", "onResizeEnd", "onDragEnd", "onMaximize"] }, { kind: "ngmodule", type: InputTextModule }, { kind: "directive", type: i3$3.InputText, selector: "[pInputText]", inputs: ["hostName", "ptInputText", "pSize", "variant", "fluid", "invalid"] }, { kind: "ngmodule", type: SelectModule }, { kind: "component", type: i4$1.Select, selector: "p-select", inputs: ["id", "scrollHeight", "filter", "panelStyle", "styleClass", "panelStyleClass", "readonly", "editable", "tabindex", "placeholder", "loadingIcon", "filterPlaceholder", "filterLocale", "inputId", "dataKey", "filterBy", "filterFields", "autofocus", "resetFilterOnHide", "checkmark", "dropdownIcon", "loading", "optionLabel", "optionValue", "optionDisabled", "optionGroupLabel", "optionGroupChildren", "group", "showClear", "emptyFilterMessage", "emptyMessage", "lazy", "virtualScroll", "virtualScrollItemSize", "virtualScrollOptions", "overlayOptions", "ariaFilterLabel", "ariaLabel", "ariaLabelledBy", "filterMatchMode", "tooltip", "tooltipPosition", "tooltipPositionStyle", "tooltipStyleClass", "focusOnHover", "selectOnFocus", "autoOptionFocus", "autofocusFilter", "filterValue", "options", "appendTo"], outputs: ["onChange", "onFilter", "onFocus", "onBlur", "onClick", "onShow", "onHide", "onClear", "onLazyLoad"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i5.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i5.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i5.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }] }); }
2772
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.16", type: MenuItemCreateDialogComponent, isStandalone: true, selector: "menu-item-create-dialog", inputs: { visible: "visible" }, outputs: { visibleChange: "visibleChange" }, ngImport: i0, template: `
2773
+ <p-dialog
2774
+ header="{{ 'menuItemCreateDialogComponent.header' | translate }}"
2775
+ [modal]="true"
2776
+ [style]="{ width: '40rem' }"
2777
+ [(visible)]="visible">
2778
+ @if (menuService.contextMenuItem) {
2779
+ <div class="flex items-center gap-4 mb-4 mt-1">
2780
+ <label class="font-semibold w-1/3" for="oip-menu-item-create-dialog-parent-input">
2781
+ {{ 'menuItemCreateDialogComponent.parentLabel' | translate }}
2782
+ </label>
2783
+ <input
2784
+ autocomplete="off"
2785
+ class="flex-auto"
2786
+ id="oip-menu-item-create-dialog-parent-input"
2787
+ pInputText
2788
+ readonly
2789
+ [ngModel]="menuService.contextMenuItem?.label" />
2790
+ </div>
2791
+ }
2792
+ <div class="flex items-center gap-4 mb-4">
2793
+ <label class="font-semibold w-1/3" for="oip-menu-item-create-label">
2794
+ {{ 'menuItemCreateDialogComponent.label' | translate }}
2795
+ </label>
2796
+ <input autocomplete="off" class="flex-auto" id="oip-menu-item-create-label" pInputText [(ngModel)]="label" />
2797
+ </div>
2798
+ <div class="flex items-center gap-4 mb-4">
2799
+ <label class="font-semibold w-1/3" for="oip-menu-item-create-module">
2800
+ {{ 'menuItemCreateDialogComponent.module' | translate }}
2801
+ </label>
2802
+ <p-select
2803
+ appendTo="body"
2804
+ class="flex-auto"
2805
+ id="oip-menu-item-create-module"
2806
+ optionLabel="value"
2807
+ optionValue="key"
2808
+ placeholder="{{ 'menuItemCreateDialogComponent.selectModule' | translate }}"
2809
+ [options]="modules"
2810
+ [(ngModel)]="selectModule" />
2811
+ </div>
2812
+ <div class="flex items-center gap-4 mb-4">
2813
+ <label class="font-semibold w-1/3" for="oip-menu-item-create-dialog-icon">
2814
+ {{ 'menuItemCreateDialogComponent.icon' | translate }}
2815
+ </label>
2816
+ <i class="{{ selectIcon }}"></i>
2817
+ <input class="flex-auto" id="oip-menu-item-create-dialog-icon" pInputText [(ngModel)]="selectIcon" />
2818
+ </div>
2819
+ <div class="flex justify-end gap-2">
2820
+ <p-button
2821
+ id="oip-menu-item-create-cancel"
2822
+ label="{{ 'menuItemCreateDialogComponent.cancel' | translate }}"
2823
+ severity="secondary"
2824
+ (click)="changeVisible()"
2825
+ (keydown)="changeVisible()" />
2826
+ <p-button
2827
+ id="oip-menu-item-create-save"
2828
+ label="{{ 'menuItemCreateDialogComponent.save' | translate }}"
2829
+ (click)="save()"
2830
+ (keydown)="save()" />
2831
+ </div>
2832
+ </p-dialog>
2833
+ `, isInline: true, dependencies: [{ kind: "ngmodule", type: ButtonModule }, { kind: "component", type: i1$2.Button, selector: "p-button", inputs: ["hostName", "type", "badge", "disabled", "raised", "rounded", "text", "plain", "outlined", "link", "tabindex", "size", "variant", "style", "styleClass", "badgeClass", "badgeSeverity", "ariaLabel", "autofocus", "iconPos", "icon", "label", "loading", "loadingIcon", "severity", "buttonProps", "fluid"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "ngmodule", type: DialogModule }, { kind: "component", type: i2$3.Dialog, selector: "p-dialog", inputs: ["hostName", "header", "draggable", "resizable", "contentStyle", "contentStyleClass", "modal", "closeOnEscape", "dismissableMask", "rtl", "closable", "breakpoints", "styleClass", "maskStyleClass", "maskStyle", "showHeader", "blockScroll", "autoZIndex", "baseZIndex", "minX", "minY", "focusOnShow", "maximizable", "keepInViewport", "focusTrap", "transitionOptions", "closeIcon", "closeAriaLabel", "closeTabindex", "minimizeIcon", "maximizeIcon", "closeButtonProps", "maximizeButtonProps", "visible", "style", "position", "role", "appendTo", "content", "contentTemplate", "footerTemplate", "closeIconTemplate", "maximizeIconTemplate", "minimizeIconTemplate", "headlessTemplate"], outputs: ["onShow", "onHide", "visibleChange", "onResizeInit", "onResizeEnd", "onDragEnd", "onMaximize"] }, { kind: "ngmodule", type: InputTextModule }, { kind: "directive", type: i3$3.InputText, selector: "[pInputText]", inputs: ["hostName", "ptInputText", "pSize", "variant", "fluid", "invalid"] }, { kind: "ngmodule", type: SelectModule }, { kind: "component", type: i4.Select, selector: "p-select", inputs: ["id", "scrollHeight", "filter", "panelStyle", "styleClass", "panelStyleClass", "readonly", "editable", "tabindex", "placeholder", "loadingIcon", "filterPlaceholder", "filterLocale", "inputId", "dataKey", "filterBy", "filterFields", "autofocus", "resetFilterOnHide", "checkmark", "dropdownIcon", "loading", "optionLabel", "optionValue", "optionDisabled", "optionGroupLabel", "optionGroupChildren", "group", "showClear", "emptyFilterMessage", "emptyMessage", "lazy", "virtualScroll", "virtualScrollItemSize", "virtualScrollOptions", "overlayOptions", "ariaFilterLabel", "ariaLabel", "ariaLabelledBy", "filterMatchMode", "tooltip", "tooltipPosition", "tooltipPositionStyle", "tooltipStyleClass", "focusOnHover", "selectOnFocus", "autoOptionFocus", "autofocusFilter", "filterValue", "options", "appendTo"], outputs: ["onChange", "onFilter", "onFocus", "onBlur", "onClick", "onShow", "onHide", "onClear", "onLazyLoad"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }] }); }
2769
2834
  }
2770
2835
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: MenuItemCreateDialogComponent, decorators: [{
2771
2836
  type: Component,
@@ -2773,67 +2838,67 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
2773
2838
  selector: 'menu-item-create-dialog',
2774
2839
  standalone: true,
2775
2840
  imports: [ButtonModule, DialogModule, InputTextModule, SelectModule, FormsModule, TranslatePipe],
2776
- template: `
2777
- <p-dialog
2778
- header="{{ 'menuItemCreateDialogComponent.header' | translate }}"
2779
- [modal]="true"
2780
- [style]="{ width: '40rem' }"
2781
- [(visible)]="visible">
2782
- @if (menuService.contextMenuItem) {
2783
- <div class="flex items-center gap-4 mb-4 mt-1">
2784
- <label class="font-semibold w-1/3" for="oip-menu-item-create-dialog-parent-input">
2785
- {{ 'menuItemCreateDialogComponent.parentLabel' | translate }}
2786
- </label>
2787
- <input
2788
- autocomplete="off"
2789
- class="flex-auto"
2790
- id="oip-menu-item-create-dialog-parent-input"
2791
- pInputText
2792
- readonly
2793
- [ngModel]="menuService.contextMenuItem?.label" />
2794
- </div>
2795
- }
2796
- <div class="flex items-center gap-4 mb-4">
2797
- <label class="font-semibold w-1/3" for="oip-menu-item-create-label">
2798
- {{ 'menuItemCreateDialogComponent.label' | translate }}
2799
- </label>
2800
- <input autocomplete="off" class="flex-auto" id="oip-menu-item-create-label" pInputText [(ngModel)]="label" />
2801
- </div>
2802
- <div class="flex items-center gap-4 mb-4">
2803
- <label class="font-semibold w-1/3" for="oip-menu-item-create-module">
2804
- {{ 'menuItemCreateDialogComponent.module' | translate }}
2805
- </label>
2806
- <p-select
2807
- appendTo="body"
2808
- class="flex-auto"
2809
- id="oip-menu-item-create-module"
2810
- optionLabel="value"
2811
- optionValue="key"
2812
- placeholder="{{ 'menuItemCreateDialogComponent.selectModule' | translate }}"
2813
- [options]="modules"
2814
- [(ngModel)]="selectModule" />
2815
- </div>
2816
- <div class="flex items-center gap-4 mb-4">
2817
- <label class="font-semibold w-1/3" for="oip-menu-item-create-dialog-icon">
2818
- {{ 'menuItemCreateDialogComponent.icon' | translate }}
2819
- </label>
2820
- <i class="{{ selectIcon }}"></i>
2821
- <input class="flex-auto" id="oip-menu-item-create-dialog-icon" pInputText [(ngModel)]="selectIcon" />
2822
- </div>
2823
- <div class="flex justify-end gap-2">
2824
- <p-button
2825
- id="oip-menu-item-create-cancel"
2826
- label="{{ 'menuItemCreateDialogComponent.cancel' | translate }}"
2827
- severity="secondary"
2828
- (click)="changeVisible()"
2829
- (keydown)="changeVisible()" />
2830
- <p-button
2831
- id="oip-menu-item-create-save"
2832
- label="{{ 'menuItemCreateDialogComponent.save' | translate }}"
2833
- (click)="save()"
2834
- (keydown)="save()" />
2835
- </div>
2836
- </p-dialog>
2841
+ template: `
2842
+ <p-dialog
2843
+ header="{{ 'menuItemCreateDialogComponent.header' | translate }}"
2844
+ [modal]="true"
2845
+ [style]="{ width: '40rem' }"
2846
+ [(visible)]="visible">
2847
+ @if (menuService.contextMenuItem) {
2848
+ <div class="flex items-center gap-4 mb-4 mt-1">
2849
+ <label class="font-semibold w-1/3" for="oip-menu-item-create-dialog-parent-input">
2850
+ {{ 'menuItemCreateDialogComponent.parentLabel' | translate }}
2851
+ </label>
2852
+ <input
2853
+ autocomplete="off"
2854
+ class="flex-auto"
2855
+ id="oip-menu-item-create-dialog-parent-input"
2856
+ pInputText
2857
+ readonly
2858
+ [ngModel]="menuService.contextMenuItem?.label" />
2859
+ </div>
2860
+ }
2861
+ <div class="flex items-center gap-4 mb-4">
2862
+ <label class="font-semibold w-1/3" for="oip-menu-item-create-label">
2863
+ {{ 'menuItemCreateDialogComponent.label' | translate }}
2864
+ </label>
2865
+ <input autocomplete="off" class="flex-auto" id="oip-menu-item-create-label" pInputText [(ngModel)]="label" />
2866
+ </div>
2867
+ <div class="flex items-center gap-4 mb-4">
2868
+ <label class="font-semibold w-1/3" for="oip-menu-item-create-module">
2869
+ {{ 'menuItemCreateDialogComponent.module' | translate }}
2870
+ </label>
2871
+ <p-select
2872
+ appendTo="body"
2873
+ class="flex-auto"
2874
+ id="oip-menu-item-create-module"
2875
+ optionLabel="value"
2876
+ optionValue="key"
2877
+ placeholder="{{ 'menuItemCreateDialogComponent.selectModule' | translate }}"
2878
+ [options]="modules"
2879
+ [(ngModel)]="selectModule" />
2880
+ </div>
2881
+ <div class="flex items-center gap-4 mb-4">
2882
+ <label class="font-semibold w-1/3" for="oip-menu-item-create-dialog-icon">
2883
+ {{ 'menuItemCreateDialogComponent.icon' | translate }}
2884
+ </label>
2885
+ <i class="{{ selectIcon }}"></i>
2886
+ <input class="flex-auto" id="oip-menu-item-create-dialog-icon" pInputText [(ngModel)]="selectIcon" />
2887
+ </div>
2888
+ <div class="flex justify-end gap-2">
2889
+ <p-button
2890
+ id="oip-menu-item-create-cancel"
2891
+ label="{{ 'menuItemCreateDialogComponent.cancel' | translate }}"
2892
+ severity="secondary"
2893
+ (click)="changeVisible()"
2894
+ (keydown)="changeVisible()" />
2895
+ <p-button
2896
+ id="oip-menu-item-create-save"
2897
+ label="{{ 'menuItemCreateDialogComponent.save' | translate }}"
2898
+ (click)="save()"
2899
+ (keydown)="save()" />
2900
+ </div>
2901
+ </p-dialog>
2837
2902
  `
2838
2903
  }]
2839
2904
  }], propDecorators: { visible: [{
@@ -2888,61 +2953,61 @@ class MenuItemEditDialogComponent {
2888
2953
  this.visibleChange.emit(this.visible);
2889
2954
  }
2890
2955
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: MenuItemEditDialogComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
2891
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.16", type: MenuItemEditDialogComponent, isStandalone: true, selector: "menu-item-edit-dialog", inputs: { visible: "visible" }, outputs: { visibleChange: "visibleChange" }, ngImport: i0, template: `
2892
- <p-dialog
2893
- header="{{ 'menuItemEditDialogComponent.header' | translate }}"
2894
- [modal]="true"
2895
- [style]="{ width: '40rem' }"
2896
- [(visible)]="visible">
2897
- <div class="flex items-center gap-4 mb-4 mt-1">
2898
- <label class="font-semibold w-1/3" for="oip-menu-item-edit-dialog-menu-input">
2899
- {{ 'menuItemEditDialogComponent.label' | translate }}
2900
- </label>
2901
- <input
2902
- autocomplete="off"
2903
- class="flex-auto"
2904
- id="oip-menu-item-edit-dialog-menu-input"
2905
- pInputText
2906
- [(ngModel)]="item.label" />
2907
- </div>
2908
-
2909
- <div class="flex items-center gap-4 mb-4">
2910
- <label class="font-semibold w-1/3" for="oip-menu-item-edit-dialog-icon">
2911
- {{ 'menuItemEditDialogComponent.icon' | translate }}
2912
- </label>
2913
- <i class="{{ item.icon }}"></i>
2914
- <input class="flex-auto" id="oip-menu-item-edit-dialog-icon" pInputText [(ngModel)]="item.icon" />
2915
- </div>
2916
-
2917
- <div class="flex items-center gap-4 mb-4">
2918
- <label class="font-semibold w-1/3" for="security">
2919
- {{ 'menuItemEditDialogComponent.security' | translate }}
2920
- </label>
2921
- <p-multiSelect
2922
- appendTo="body"
2923
- class="flex-auto"
2924
- id="oip-menu-item-edit-dialog-roles-multi-select"
2925
- placeholder="Select roles"
2926
- [maxSelectedLabels]="10"
2927
- [options]="roles"
2928
- [(ngModel)]="item.viewRoles" />
2929
- </div>
2930
-
2931
- <div class="flex justify-end gap-2">
2932
- <p-button
2933
- id="oip-menu-item-edit-dialog-cancel-edit-button"
2934
- label="{{ 'menuItemEditDialogComponent.cancel' | translate }}"
2935
- severity="secondary"
2936
- (click)="changeVisible()"
2937
- (keydown)="changeVisible()" />
2938
- <p-button
2939
- id="oip-menu-item-edit-dialog-save-edit-button"
2940
- label="{{ 'menuItemEditDialogComponent.save' | translate }}"
2941
- (click)="save()"
2942
- (keydown)="save()" />
2943
- </div>
2944
- </p-dialog>
2945
- `, isInline: true, dependencies: [{ kind: "ngmodule", type: ButtonModule }, { kind: "component", type: i1$1.Button, selector: "p-button", inputs: ["hostName", "type", "badge", "disabled", "raised", "rounded", "text", "plain", "outlined", "link", "tabindex", "size", "variant", "style", "styleClass", "badgeClass", "badgeSeverity", "ariaLabel", "autofocus", "iconPos", "icon", "label", "loading", "loadingIcon", "severity", "buttonProps", "fluid"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "ngmodule", type: DialogModule }, { kind: "component", type: i2$2.Dialog, selector: "p-dialog", inputs: ["hostName", "header", "draggable", "resizable", "contentStyle", "contentStyleClass", "modal", "closeOnEscape", "dismissableMask", "rtl", "closable", "breakpoints", "styleClass", "maskStyleClass", "maskStyle", "showHeader", "blockScroll", "autoZIndex", "baseZIndex", "minX", "minY", "focusOnShow", "maximizable", "keepInViewport", "focusTrap", "transitionOptions", "closeIcon", "closeAriaLabel", "closeTabindex", "minimizeIcon", "maximizeIcon", "closeButtonProps", "maximizeButtonProps", "visible", "style", "position", "role", "appendTo", "content", "contentTemplate", "footerTemplate", "closeIconTemplate", "maximizeIconTemplate", "minimizeIconTemplate", "headlessTemplate"], outputs: ["onShow", "onHide", "visibleChange", "onResizeInit", "onResizeEnd", "onDragEnd", "onMaximize"] }, { kind: "ngmodule", type: InputTextModule }, { kind: "directive", type: i3$3.InputText, selector: "[pInputText]", inputs: ["hostName", "ptInputText", "pSize", "variant", "fluid", "invalid"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i5.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i5.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i5.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: MultiSelectModule }, { kind: "component", type: i1.MultiSelect, selector: "p-multiSelect, p-multiselect, p-multi-select", inputs: ["id", "ariaLabel", "styleClass", "panelStyle", "panelStyleClass", "inputId", "readonly", "group", "filter", "filterPlaceHolder", "filterLocale", "overlayVisible", "tabindex", "dataKey", "ariaLabelledBy", "displaySelectedLabel", "maxSelectedLabels", "selectionLimit", "selectedItemsLabel", "showToggleAll", "emptyFilterMessage", "emptyMessage", "resetFilterOnHide", "dropdownIcon", "chipIcon", "optionLabel", "optionValue", "optionDisabled", "optionGroupLabel", "optionGroupChildren", "showHeader", "filterBy", "scrollHeight", "lazy", "virtualScroll", "loading", "virtualScrollItemSize", "loadingIcon", "virtualScrollOptions", "overlayOptions", "ariaFilterLabel", "filterMatchMode", "tooltip", "tooltipPosition", "tooltipPositionStyle", "tooltipStyleClass", "autofocusFilter", "display", "autocomplete", "showClear", "autofocus", "placeholder", "options", "filterValue", "selectAll", "focusOnHover", "filterFields", "selectOnFocus", "autoOptionFocus", "highlightOnSelect", "size", "variant", "fluid", "appendTo"], outputs: ["onChange", "onFilter", "onFocus", "onBlur", "onClick", "onClear", "onPanelShow", "onPanelHide", "onLazyLoad", "onRemove", "onSelectAllChange"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }] }); }
2956
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.16", type: MenuItemEditDialogComponent, isStandalone: true, selector: "menu-item-edit-dialog", inputs: { visible: "visible" }, outputs: { visibleChange: "visibleChange" }, ngImport: i0, template: `
2957
+ <p-dialog
2958
+ header="{{ 'menuItemEditDialogComponent.header' | translate }}"
2959
+ [modal]="true"
2960
+ [style]="{ width: '40rem' }"
2961
+ [(visible)]="visible">
2962
+ <div class="flex items-center gap-4 mb-4 mt-1">
2963
+ <label class="font-semibold w-1/3" for="oip-menu-item-edit-dialog-menu-input">
2964
+ {{ 'menuItemEditDialogComponent.label' | translate }}
2965
+ </label>
2966
+ <input
2967
+ autocomplete="off"
2968
+ class="flex-auto"
2969
+ id="oip-menu-item-edit-dialog-menu-input"
2970
+ pInputText
2971
+ [(ngModel)]="item.label" />
2972
+ </div>
2973
+
2974
+ <div class="flex items-center gap-4 mb-4">
2975
+ <label class="font-semibold w-1/3" for="oip-menu-item-edit-dialog-icon">
2976
+ {{ 'menuItemEditDialogComponent.icon' | translate }}
2977
+ </label>
2978
+ <i class="{{ item.icon }}"></i>
2979
+ <input class="flex-auto" id="oip-menu-item-edit-dialog-icon" pInputText [(ngModel)]="item.icon" />
2980
+ </div>
2981
+
2982
+ <div class="flex items-center gap-4 mb-4">
2983
+ <label class="font-semibold w-1/3" for="security">
2984
+ {{ 'menuItemEditDialogComponent.security' | translate }}
2985
+ </label>
2986
+ <p-multiSelect
2987
+ appendTo="body"
2988
+ class="flex-auto"
2989
+ id="oip-menu-item-edit-dialog-roles-multi-select"
2990
+ placeholder="Select roles"
2991
+ [maxSelectedLabels]="10"
2992
+ [options]="roles"
2993
+ [(ngModel)]="item.viewRoles" />
2994
+ </div>
2995
+
2996
+ <div class="flex justify-end gap-2">
2997
+ <p-button
2998
+ id="oip-menu-item-edit-dialog-cancel-edit-button"
2999
+ label="{{ 'menuItemEditDialogComponent.cancel' | translate }}"
3000
+ severity="secondary"
3001
+ (click)="changeVisible()"
3002
+ (keydown)="changeVisible()" />
3003
+ <p-button
3004
+ id="oip-menu-item-edit-dialog-save-edit-button"
3005
+ label="{{ 'menuItemEditDialogComponent.save' | translate }}"
3006
+ (click)="save()"
3007
+ (keydown)="save()" />
3008
+ </div>
3009
+ </p-dialog>
3010
+ `, isInline: true, dependencies: [{ kind: "ngmodule", type: ButtonModule }, { kind: "component", type: i1$2.Button, selector: "p-button", inputs: ["hostName", "type", "badge", "disabled", "raised", "rounded", "text", "plain", "outlined", "link", "tabindex", "size", "variant", "style", "styleClass", "badgeClass", "badgeSeverity", "ariaLabel", "autofocus", "iconPos", "icon", "label", "loading", "loadingIcon", "severity", "buttonProps", "fluid"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "ngmodule", type: DialogModule }, { kind: "component", type: i2$3.Dialog, selector: "p-dialog", inputs: ["hostName", "header", "draggable", "resizable", "contentStyle", "contentStyleClass", "modal", "closeOnEscape", "dismissableMask", "rtl", "closable", "breakpoints", "styleClass", "maskStyleClass", "maskStyle", "showHeader", "blockScroll", "autoZIndex", "baseZIndex", "minX", "minY", "focusOnShow", "maximizable", "keepInViewport", "focusTrap", "transitionOptions", "closeIcon", "closeAriaLabel", "closeTabindex", "minimizeIcon", "maximizeIcon", "closeButtonProps", "maximizeButtonProps", "visible", "style", "position", "role", "appendTo", "content", "contentTemplate", "footerTemplate", "closeIconTemplate", "maximizeIconTemplate", "minimizeIconTemplate", "headlessTemplate"], outputs: ["onShow", "onHide", "visibleChange", "onResizeInit", "onResizeEnd", "onDragEnd", "onMaximize"] }, { kind: "ngmodule", type: InputTextModule }, { kind: "directive", type: i3$3.InputText, selector: "[pInputText]", inputs: ["hostName", "ptInputText", "pSize", "variant", "fluid", "invalid"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: MultiSelectModule }, { kind: "component", type: i1.MultiSelect, selector: "p-multiSelect, p-multiselect, p-multi-select", inputs: ["id", "ariaLabel", "styleClass", "panelStyle", "panelStyleClass", "inputId", "readonly", "group", "filter", "filterPlaceHolder", "filterLocale", "overlayVisible", "tabindex", "dataKey", "ariaLabelledBy", "displaySelectedLabel", "maxSelectedLabels", "selectionLimit", "selectedItemsLabel", "showToggleAll", "emptyFilterMessage", "emptyMessage", "resetFilterOnHide", "dropdownIcon", "chipIcon", "optionLabel", "optionValue", "optionDisabled", "optionGroupLabel", "optionGroupChildren", "showHeader", "filterBy", "scrollHeight", "lazy", "virtualScroll", "loading", "virtualScrollItemSize", "loadingIcon", "virtualScrollOptions", "overlayOptions", "ariaFilterLabel", "filterMatchMode", "tooltip", "tooltipPosition", "tooltipPositionStyle", "tooltipStyleClass", "autofocusFilter", "display", "autocomplete", "showClear", "autofocus", "placeholder", "options", "filterValue", "selectAll", "focusOnHover", "filterFields", "selectOnFocus", "autoOptionFocus", "highlightOnSelect", "size", "variant", "fluid", "appendTo"], outputs: ["onChange", "onFilter", "onFocus", "onBlur", "onClick", "onClear", "onPanelShow", "onPanelHide", "onLazyLoad", "onRemove", "onSelectAllChange"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }] }); }
2946
3011
  }
2947
3012
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: MenuItemEditDialogComponent, decorators: [{
2948
3013
  type: Component,
@@ -2950,60 +3015,60 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
2950
3015
  imports: [ButtonModule, DialogModule, InputTextModule, FormsModule, TranslatePipe, MultiSelectModule],
2951
3016
  selector: 'menu-item-edit-dialog',
2952
3017
  standalone: true,
2953
- template: `
2954
- <p-dialog
2955
- header="{{ 'menuItemEditDialogComponent.header' | translate }}"
2956
- [modal]="true"
2957
- [style]="{ width: '40rem' }"
2958
- [(visible)]="visible">
2959
- <div class="flex items-center gap-4 mb-4 mt-1">
2960
- <label class="font-semibold w-1/3" for="oip-menu-item-edit-dialog-menu-input">
2961
- {{ 'menuItemEditDialogComponent.label' | translate }}
2962
- </label>
2963
- <input
2964
- autocomplete="off"
2965
- class="flex-auto"
2966
- id="oip-menu-item-edit-dialog-menu-input"
2967
- pInputText
2968
- [(ngModel)]="item.label" />
2969
- </div>
2970
-
2971
- <div class="flex items-center gap-4 mb-4">
2972
- <label class="font-semibold w-1/3" for="oip-menu-item-edit-dialog-icon">
2973
- {{ 'menuItemEditDialogComponent.icon' | translate }}
2974
- </label>
2975
- <i class="{{ item.icon }}"></i>
2976
- <input class="flex-auto" id="oip-menu-item-edit-dialog-icon" pInputText [(ngModel)]="item.icon" />
2977
- </div>
2978
-
2979
- <div class="flex items-center gap-4 mb-4">
2980
- <label class="font-semibold w-1/3" for="security">
2981
- {{ 'menuItemEditDialogComponent.security' | translate }}
2982
- </label>
2983
- <p-multiSelect
2984
- appendTo="body"
2985
- class="flex-auto"
2986
- id="oip-menu-item-edit-dialog-roles-multi-select"
2987
- placeholder="Select roles"
2988
- [maxSelectedLabels]="10"
2989
- [options]="roles"
2990
- [(ngModel)]="item.viewRoles" />
2991
- </div>
2992
-
2993
- <div class="flex justify-end gap-2">
2994
- <p-button
2995
- id="oip-menu-item-edit-dialog-cancel-edit-button"
2996
- label="{{ 'menuItemEditDialogComponent.cancel' | translate }}"
2997
- severity="secondary"
2998
- (click)="changeVisible()"
2999
- (keydown)="changeVisible()" />
3000
- <p-button
3001
- id="oip-menu-item-edit-dialog-save-edit-button"
3002
- label="{{ 'menuItemEditDialogComponent.save' | translate }}"
3003
- (click)="save()"
3004
- (keydown)="save()" />
3005
- </div>
3006
- </p-dialog>
3018
+ template: `
3019
+ <p-dialog
3020
+ header="{{ 'menuItemEditDialogComponent.header' | translate }}"
3021
+ [modal]="true"
3022
+ [style]="{ width: '40rem' }"
3023
+ [(visible)]="visible">
3024
+ <div class="flex items-center gap-4 mb-4 mt-1">
3025
+ <label class="font-semibold w-1/3" for="oip-menu-item-edit-dialog-menu-input">
3026
+ {{ 'menuItemEditDialogComponent.label' | translate }}
3027
+ </label>
3028
+ <input
3029
+ autocomplete="off"
3030
+ class="flex-auto"
3031
+ id="oip-menu-item-edit-dialog-menu-input"
3032
+ pInputText
3033
+ [(ngModel)]="item.label" />
3034
+ </div>
3035
+
3036
+ <div class="flex items-center gap-4 mb-4">
3037
+ <label class="font-semibold w-1/3" for="oip-menu-item-edit-dialog-icon">
3038
+ {{ 'menuItemEditDialogComponent.icon' | translate }}
3039
+ </label>
3040
+ <i class="{{ item.icon }}"></i>
3041
+ <input class="flex-auto" id="oip-menu-item-edit-dialog-icon" pInputText [(ngModel)]="item.icon" />
3042
+ </div>
3043
+
3044
+ <div class="flex items-center gap-4 mb-4">
3045
+ <label class="font-semibold w-1/3" for="security">
3046
+ {{ 'menuItemEditDialogComponent.security' | translate }}
3047
+ </label>
3048
+ <p-multiSelect
3049
+ appendTo="body"
3050
+ class="flex-auto"
3051
+ id="oip-menu-item-edit-dialog-roles-multi-select"
3052
+ placeholder="Select roles"
3053
+ [maxSelectedLabels]="10"
3054
+ [options]="roles"
3055
+ [(ngModel)]="item.viewRoles" />
3056
+ </div>
3057
+
3058
+ <div class="flex justify-end gap-2">
3059
+ <p-button
3060
+ id="oip-menu-item-edit-dialog-cancel-edit-button"
3061
+ label="{{ 'menuItemEditDialogComponent.cancel' | translate }}"
3062
+ severity="secondary"
3063
+ (click)="changeVisible()"
3064
+ (keydown)="changeVisible()" />
3065
+ <p-button
3066
+ id="oip-menu-item-edit-dialog-save-edit-button"
3067
+ label="{{ 'menuItemEditDialogComponent.save' | translate }}"
3068
+ (click)="save()"
3069
+ (keydown)="save()" />
3070
+ </div>
3071
+ </p-dialog>
3007
3072
  `
3008
3073
  }]
3009
3074
  }], propDecorators: { visible: [{
@@ -3035,31 +3100,31 @@ class MenuComponent {
3035
3100
  ];
3036
3101
  }
3037
3102
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: MenuComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
3038
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.16", type: MenuComponent, isStandalone: true, selector: "app-menu", providers: [MenuApi], viewQueries: [{ propertyName: "menuItemCreateDialogComponent", first: true, predicate: MenuItemCreateDialogComponent, descendants: true }, { propertyName: "menuItemEditDialogComponent", first: true, predicate: MenuItemEditDialogComponent, descendants: true }, { propertyName: "contextMenu", first: true, predicate: ContextMenu, descendants: true }], ngImport: i0, template: ` <div #empty class="layout-sidebar" (contextmenu)="onContextMenu($event)">
3039
- <ul class="layout-menu">
3040
- @for (item of menuService.menu; track item; let i = $index) {
3041
- <ng-container>
3042
- @if (item.separator) {
3043
- <li class="menu-separator"></li>
3044
- } @else {
3045
- <li
3046
- app-menuitem
3047
- [contextMenu]="contextMenu"
3048
- [index]="i"
3049
- [item]="item"
3050
- [menuItemCreateDialogComponent]="menuItemCreateDialogComponent"
3051
- [menuItemEditDialogComponent]="menuItemEditDialogComponent"
3052
- [root]="true"></li>
3053
- }
3054
- </ng-container>
3055
- }
3056
- </ul>
3057
- </div>
3058
- <p-contextMenu [target]="empty" />
3059
- @if (securityService.isAdmin) {
3060
- <menu-item-create-dialog />
3061
- <menu-item-edit-dialog />
3062
- }`, isInline: true, dependencies: [{ kind: "component", type: MenuItemComponent, selector: "[app-menuitem]", inputs: ["item", "index", "root", "parentKey", "menuItemCreateDialogComponent", "menuItemEditDialogComponent", "contextMenu"] }, { kind: "ngmodule", type: ButtonModule }, { kind: "ngmodule", type: ContextMenuModule }, { kind: "component", type: i1$3.ContextMenu, selector: "p-contextMenu, p-contextmenu, p-context-menu", inputs: ["model", "triggerEvent", "target", "global", "style", "styleClass", "autoZIndex", "baseZIndex", "id", "breakpoint", "ariaLabel", "ariaLabelledBy", "pressDelay", "appendTo"], outputs: ["onShow", "onHide"] }, { kind: "ngmodule", type: DialogModule }, { kind: "ngmodule", type: InputTextModule }, { kind: "component", type: MenuItemCreateDialogComponent, selector: "menu-item-create-dialog", inputs: ["visible"], outputs: ["visibleChange"] }, { kind: "ngmodule", type: FormsModule }, { kind: "component", type: MenuItemEditDialogComponent, selector: "menu-item-edit-dialog", inputs: ["visible"], outputs: ["visibleChange"] }] }); }
3103
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.16", type: MenuComponent, isStandalone: true, selector: "app-menu", providers: [MenuApi], viewQueries: [{ propertyName: "menuItemCreateDialogComponent", first: true, predicate: MenuItemCreateDialogComponent, descendants: true }, { propertyName: "menuItemEditDialogComponent", first: true, predicate: MenuItemEditDialogComponent, descendants: true }, { propertyName: "contextMenu", first: true, predicate: ContextMenu, descendants: true }], ngImport: i0, template: ` <div #empty class="layout-sidebar" (contextmenu)="onContextMenu($event)">
3104
+ <ul class="layout-menu">
3105
+ @for (item of menuService.menu; track item; let i = $index) {
3106
+ <ng-container>
3107
+ @if (item.separator) {
3108
+ <li class="menu-separator"></li>
3109
+ } @else {
3110
+ <li
3111
+ app-menuitem
3112
+ [contextMenu]="contextMenu"
3113
+ [index]="i"
3114
+ [item]="item"
3115
+ [menuItemCreateDialogComponent]="menuItemCreateDialogComponent"
3116
+ [menuItemEditDialogComponent]="menuItemEditDialogComponent"
3117
+ [root]="true"></li>
3118
+ }
3119
+ </ng-container>
3120
+ }
3121
+ </ul>
3122
+ </div>
3123
+ <p-contextMenu [target]="empty" />
3124
+ @if (securityService.isAdmin) {
3125
+ <menu-item-create-dialog />
3126
+ <menu-item-edit-dialog />
3127
+ }`, isInline: true, dependencies: [{ kind: "component", type: MenuItemComponent, selector: "[app-menuitem]", inputs: ["item", "index", "root", "parentKey", "menuItemCreateDialogComponent", "menuItemEditDialogComponent", "contextMenu"] }, { kind: "ngmodule", type: ButtonModule }, { kind: "ngmodule", type: ContextMenuModule }, { kind: "component", type: i1$4.ContextMenu, selector: "p-contextMenu, p-contextmenu, p-context-menu", inputs: ["model", "triggerEvent", "target", "global", "style", "styleClass", "autoZIndex", "baseZIndex", "id", "breakpoint", "ariaLabel", "ariaLabelledBy", "pressDelay", "appendTo"], outputs: ["onShow", "onHide"] }, { kind: "ngmodule", type: DialogModule }, { kind: "ngmodule", type: InputTextModule }, { kind: "component", type: MenuItemCreateDialogComponent, selector: "menu-item-create-dialog", inputs: ["visible"], outputs: ["visibleChange"] }, { kind: "ngmodule", type: FormsModule }, { kind: "component", type: MenuItemEditDialogComponent, selector: "menu-item-edit-dialog", inputs: ["visible"], outputs: ["visibleChange"] }] }); }
3063
3128
  }
3064
3129
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: MenuComponent, decorators: [{
3065
3130
  type: Component,
@@ -3077,30 +3142,30 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
3077
3142
  providers: [MenuApi],
3078
3143
  selector: 'app-menu',
3079
3144
  standalone: true,
3080
- template: ` <div #empty class="layout-sidebar" (contextmenu)="onContextMenu($event)">
3081
- <ul class="layout-menu">
3082
- @for (item of menuService.menu; track item; let i = $index) {
3083
- <ng-container>
3084
- @if (item.separator) {
3085
- <li class="menu-separator"></li>
3086
- } @else {
3087
- <li
3088
- app-menuitem
3089
- [contextMenu]="contextMenu"
3090
- [index]="i"
3091
- [item]="item"
3092
- [menuItemCreateDialogComponent]="menuItemCreateDialogComponent"
3093
- [menuItemEditDialogComponent]="menuItemEditDialogComponent"
3094
- [root]="true"></li>
3095
- }
3096
- </ng-container>
3097
- }
3098
- </ul>
3099
- </div>
3100
- <p-contextMenu [target]="empty" />
3101
- @if (securityService.isAdmin) {
3102
- <menu-item-create-dialog />
3103
- <menu-item-edit-dialog />
3145
+ template: ` <div #empty class="layout-sidebar" (contextmenu)="onContextMenu($event)">
3146
+ <ul class="layout-menu">
3147
+ @for (item of menuService.menu; track item; let i = $index) {
3148
+ <ng-container>
3149
+ @if (item.separator) {
3150
+ <li class="menu-separator"></li>
3151
+ } @else {
3152
+ <li
3153
+ app-menuitem
3154
+ [contextMenu]="contextMenu"
3155
+ [index]="i"
3156
+ [item]="item"
3157
+ [menuItemCreateDialogComponent]="menuItemCreateDialogComponent"
3158
+ [menuItemEditDialogComponent]="menuItemEditDialogComponent"
3159
+ [root]="true"></li>
3160
+ }
3161
+ </ng-container>
3162
+ }
3163
+ </ul>
3164
+ </div>
3165
+ <p-contextMenu [target]="empty" />
3166
+ @if (securityService.isAdmin) {
3167
+ <menu-item-create-dialog />
3168
+ <menu-item-edit-dialog />
3104
3169
  }`
3105
3170
  }]
3106
3171
  }], propDecorators: { menuItemCreateDialogComponent: [{
@@ -3207,19 +3272,19 @@ class AppLayoutComponent {
3207
3272
  }
3208
3273
  }
3209
3274
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: AppLayoutComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
3210
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.16", type: AppLayoutComponent, isStandalone: true, selector: "app-layout", providers: [MenuService, MenuApi], viewQueries: [{ propertyName: "appSidebar", first: true, predicate: SidebarComponent, descendants: true }, { propertyName: "appTopBar", first: true, predicate: AppTopbar, descendants: true }], ngImport: i0, template: `
3211
- <div class="layout-wrapper" [ngClass]="containerClass">
3212
- <app-topbar></app-topbar>
3213
- <app-sidebar></app-sidebar>
3214
- <div class="layout-main-container">
3215
- <div class="layout-main">
3216
- <router-outlet></router-outlet>
3217
- </div>
3218
- <app-footer></app-footer>
3219
- </div>
3220
- <div class="layout-mask animate-fadein"></div>
3221
- </div>
3222
- `, isInline: true, dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i2$1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "component", type: AppTopbar, selector: "app-topbar" }, { kind: "component", type: SidebarComponent, selector: "app-sidebar" }, { kind: "ngmodule", type: RouterModule }, { kind: "directive", type: i1$2.RouterOutlet, selector: "router-outlet", inputs: ["name", "routerOutletData"], outputs: ["activate", "deactivate", "attach", "detach"], exportAs: ["outlet"] }, { kind: "component", type: FooterComponent, selector: "app-footer" }] }); }
3275
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.16", type: AppLayoutComponent, isStandalone: true, selector: "app-layout", providers: [MenuService, MenuApi], viewQueries: [{ propertyName: "appSidebar", first: true, predicate: SidebarComponent, descendants: true }, { propertyName: "appTopBar", first: true, predicate: AppTopbar, descendants: true }], ngImport: i0, template: `
3276
+ <div class="layout-wrapper" [ngClass]="containerClass">
3277
+ <app-topbar></app-topbar>
3278
+ <app-sidebar></app-sidebar>
3279
+ <div class="layout-main-container">
3280
+ <div class="layout-main">
3281
+ <router-outlet></router-outlet>
3282
+ </div>
3283
+ <app-footer></app-footer>
3284
+ </div>
3285
+ <div class="layout-mask animate-fadein"></div>
3286
+ </div>
3287
+ `, isInline: true, dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i2$1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "component", type: AppTopbar, selector: "app-topbar" }, { kind: "component", type: SidebarComponent, selector: "app-sidebar" }, { kind: "ngmodule", type: RouterModule }, { kind: "directive", type: i1$3.RouterOutlet, selector: "router-outlet", inputs: ["name", "routerOutletData"], outputs: ["activate", "deactivate", "attach", "detach"], exportAs: ["outlet"] }, { kind: "component", type: FooterComponent, selector: "app-footer" }] }); }
3223
3288
  }
3224
3289
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: AppLayoutComponent, decorators: [{
3225
3290
  type: Component,
@@ -3227,18 +3292,18 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
3227
3292
  selector: 'app-layout',
3228
3293
  standalone: true,
3229
3294
  imports: [CommonModule, AppTopbar, SidebarComponent, RouterModule, FooterComponent],
3230
- template: `
3231
- <div class="layout-wrapper" [ngClass]="containerClass">
3232
- <app-topbar></app-topbar>
3233
- <app-sidebar></app-sidebar>
3234
- <div class="layout-main-container">
3235
- <div class="layout-main">
3236
- <router-outlet></router-outlet>
3237
- </div>
3238
- <app-footer></app-footer>
3239
- </div>
3240
- <div class="layout-mask animate-fadein"></div>
3241
- </div>
3295
+ template: `
3296
+ <div class="layout-wrapper" [ngClass]="containerClass">
3297
+ <app-topbar></app-topbar>
3298
+ <app-sidebar></app-sidebar>
3299
+ <div class="layout-main-container">
3300
+ <div class="layout-main">
3301
+ <router-outlet></router-outlet>
3302
+ </div>
3303
+ <app-footer></app-footer>
3304
+ </div>
3305
+ <div class="layout-mask animate-fadein"></div>
3306
+ </div>
3242
3307
  `,
3243
3308
  providers: [MenuService, MenuApi]
3244
3309
  }]
@@ -3286,7 +3351,7 @@ class AppFloatingConfiguratorComponent {
3286
3351
  <app-configurator />
3287
3352
  </div>
3288
3353
  </div>
3289
- `, isInline: true, dependencies: [{ kind: "ngmodule", type: ButtonModule }, { kind: "component", type: i1$1.Button, selector: "p-button", inputs: ["hostName", "type", "badge", "disabled", "raised", "rounded", "text", "plain", "outlined", "link", "tabindex", "size", "variant", "style", "styleClass", "badgeClass", "badgeSeverity", "ariaLabel", "autofocus", "iconPos", "icon", "label", "loading", "loadingIcon", "severity", "buttonProps", "fluid"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "ngmodule", type: StyleClassModule }, { kind: "directive", type: i3$1.StyleClass, selector: "[pStyleClass]", inputs: ["pStyleClass", "enterFromClass", "enterActiveClass", "enterToClass", "leaveFromClass", "leaveActiveClass", "leaveToClass", "hideOnOutsideClick", "toggleClass", "hideOnEscape", "hideOnResize", "resizeSelector"] }, { kind: "component", type: AppConfiguratorComponent, selector: "app-configurator" }] }); }
3354
+ `, isInline: true, dependencies: [{ kind: "ngmodule", type: ButtonModule }, { kind: "component", type: i1$2.Button, selector: "p-button", inputs: ["hostName", "type", "badge", "disabled", "raised", "rounded", "text", "plain", "outlined", "link", "tabindex", "size", "variant", "style", "styleClass", "badgeClass", "badgeSeverity", "ariaLabel", "autofocus", "iconPos", "icon", "label", "loading", "loadingIcon", "severity", "buttonProps", "fluid"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "ngmodule", type: StyleClassModule }, { kind: "directive", type: i3$1.StyleClass, selector: "[pStyleClass]", inputs: ["pStyleClass", "enterFromClass", "enterActiveClass", "enterToClass", "leaveFromClass", "leaveActiveClass", "leaveToClass", "hideOnOutsideClick", "toggleClass", "hideOnEscape", "hideOnResize", "resizeSelector"] }, { kind: "component", type: AppConfiguratorComponent, selector: "app-configurator" }] }); }
3290
3355
  }
3291
3356
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: AppFloatingConfiguratorComponent, decorators: [{
3292
3357
  type: Component,
@@ -3425,7 +3490,7 @@ class NotfoundComponent {
3425
3490
  </div>
3426
3491
  </div>
3427
3492
  </div>
3428
- </div>`, isInline: true, dependencies: [{ kind: "directive", type: RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "routerLink"] }, { kind: "component", type: LogoComponent, selector: "logo", inputs: ["width", "height"] }, { kind: "component", type: Button, selector: "p-button", inputs: ["hostName", "type", "badge", "disabled", "raised", "rounded", "text", "plain", "outlined", "link", "tabindex", "size", "variant", "style", "styleClass", "badgeClass", "badgeSeverity", "ariaLabel", "autofocus", "iconPos", "icon", "label", "loading", "loadingIcon", "severity", "buttonProps", "fluid"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "component", type: AppFloatingConfiguratorComponent, selector: "app-floating-configurator" }, { kind: "ngmodule", type: TranslateModule }, { kind: "pipe", type: i2$3.TranslatePipe, name: "translate" }] }); }
3493
+ </div>`, isInline: true, dependencies: [{ kind: "directive", type: RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "routerLink"] }, { kind: "component", type: LogoComponent, selector: "logo", inputs: ["width", "height"] }, { kind: "component", type: Button, selector: "p-button", inputs: ["hostName", "type", "badge", "disabled", "raised", "rounded", "text", "plain", "outlined", "link", "tabindex", "size", "variant", "style", "styleClass", "badgeClass", "badgeSeverity", "ariaLabel", "autofocus", "iconPos", "icon", "label", "loading", "loadingIcon", "severity", "buttonProps", "fluid"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "component", type: AppFloatingConfiguratorComponent, selector: "app-floating-configurator" }, { kind: "ngmodule", type: TranslateModule }, { kind: "pipe", type: i2$4.TranslatePipe, name: "translate" }] }); }
3429
3494
  }
3430
3495
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: NotfoundComponent, decorators: [{
3431
3496
  type: Component,
@@ -3490,7 +3555,7 @@ class UnauthorizedComponent {
3490
3555
  </div>
3491
3556
  </div>
3492
3557
  </div>
3493
- `, isInline: true, dependencies: [{ kind: "ngmodule", type: ButtonModule }, { kind: "component", type: i1$1.Button, selector: "p-button", inputs: ["hostName", "type", "badge", "disabled", "raised", "rounded", "text", "plain", "outlined", "link", "tabindex", "size", "variant", "style", "styleClass", "badgeClass", "badgeSeverity", "ariaLabel", "autofocus", "iconPos", "icon", "label", "loading", "loadingIcon", "severity", "buttonProps", "fluid"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "ngmodule", type: RippleModule }, { kind: "component", type: LogoComponent, selector: "logo", inputs: ["width", "height"] }, { kind: "component", type: AppFloatingConfiguratorComponent, selector: "app-floating-configurator" }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "pipe", type: TranslatePipe, name: "translate" }] }); }
3558
+ `, isInline: true, dependencies: [{ kind: "ngmodule", type: ButtonModule }, { kind: "component", type: i1$2.Button, selector: "p-button", inputs: ["hostName", "type", "badge", "disabled", "raised", "rounded", "text", "plain", "outlined", "link", "tabindex", "size", "variant", "style", "styleClass", "badgeClass", "badgeSeverity", "ariaLabel", "autofocus", "iconPos", "icon", "label", "loading", "loadingIcon", "severity", "buttonProps", "fluid"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "ngmodule", type: RippleModule }, { kind: "component", type: LogoComponent, selector: "logo", inputs: ["width", "height"] }, { kind: "component", type: AppFloatingConfiguratorComponent, selector: "app-floating-configurator" }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "pipe", type: TranslatePipe, name: "translate" }] }); }
3494
3559
  }
3495
3560
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: UnauthorizedComponent, decorators: [{
3496
3561
  type: Component,
@@ -3567,7 +3632,7 @@ class ErrorComponent {
3567
3632
  </div>
3568
3633
  </div>
3569
3634
  </div>
3570
- </div>`, isInline: true, dependencies: [{ kind: "ngmodule", type: ButtonModule }, { kind: "directive", type: i1$1.ButtonDirective, selector: "[pButton]", inputs: ["ptButtonDirective", "hostName", "text", "plain", "raised", "size", "outlined", "rounded", "iconPos", "loadingIcon", "fluid", "label", "icon", "loading", "buttonProps", "severity"] }, { kind: "ngmodule", type: RippleModule }, { kind: "directive", type: i3$2.Ripple, selector: "[pRipple]" }, { kind: "directive", type: RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "routerLink"] }] }); }
3635
+ </div>`, isInline: true, dependencies: [{ kind: "ngmodule", type: ButtonModule }, { kind: "directive", type: i1$2.ButtonDirective, selector: "[pButton]", inputs: ["ptButtonDirective", "hostName", "text", "plain", "raised", "size", "outlined", "rounded", "iconPos", "loadingIcon", "fluid", "label", "icon", "loading", "buttonProps", "severity"] }, { kind: "ngmodule", type: RippleModule }, { kind: "directive", type: i3$2.Ripple, selector: "[pRipple]" }, { kind: "directive", type: RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "routerLink"] }] }); }
3571
3636
  }
3572
3637
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: ErrorComponent, decorators: [{
3573
3638
  type: Component,
@@ -3640,7 +3705,7 @@ class ProfileComponent {
3640
3705
  [auto]="true"
3641
3706
  (onUpload)="onBasicUploadAuto($event)" />
3642
3707
  </div>
3643
- `, isInline: true, dependencies: [{ kind: "ngmodule", type: FileUploadModule }, { kind: "component", type: i1$4.FileUpload, selector: "p-fileupload, p-fileUpload", inputs: ["name", "url", "method", "multiple", "accept", "disabled", "auto", "withCredentials", "maxFileSize", "invalidFileSizeMessageSummary", "invalidFileSizeMessageDetail", "invalidFileTypeMessageSummary", "invalidFileTypeMessageDetail", "invalidFileLimitMessageDetail", "invalidFileLimitMessageSummary", "style", "styleClass", "previewWidth", "chooseLabel", "uploadLabel", "cancelLabel", "chooseIcon", "uploadIcon", "cancelIcon", "showUploadButton", "showCancelButton", "mode", "headers", "customUpload", "fileLimit", "uploadStyleClass", "cancelStyleClass", "removeStyleClass", "chooseStyleClass", "chooseButtonProps", "uploadButtonProps", "cancelButtonProps", "files"], outputs: ["onBeforeUpload", "onSend", "onUpload", "onError", "onClear", "onRemove", "onSelect", "onProgress", "uploadHandler", "onImageError", "onRemoveUploadedFile"] }, { kind: "ngmodule", type: ImageModule }, { kind: "ngmodule", type: AvatarModule }, { kind: "component", type: i4.Avatar, selector: "p-avatar", inputs: ["label", "icon", "image", "size", "shape", "styleClass", "ariaLabel", "ariaLabelledBy"], outputs: ["onImageError"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }] }); }
3708
+ `, isInline: true, dependencies: [{ kind: "ngmodule", type: FileUploadModule }, { kind: "component", type: i1$5.FileUpload, selector: "p-fileupload, p-fileUpload", inputs: ["name", "url", "method", "multiple", "accept", "disabled", "auto", "withCredentials", "maxFileSize", "invalidFileSizeMessageSummary", "invalidFileSizeMessageDetail", "invalidFileTypeMessageSummary", "invalidFileTypeMessageDetail", "invalidFileLimitMessageDetail", "invalidFileLimitMessageSummary", "style", "styleClass", "previewWidth", "chooseLabel", "uploadLabel", "cancelLabel", "chooseIcon", "uploadIcon", "cancelIcon", "showUploadButton", "showCancelButton", "mode", "headers", "customUpload", "fileLimit", "uploadStyleClass", "cancelStyleClass", "removeStyleClass", "chooseStyleClass", "chooseButtonProps", "uploadButtonProps", "cancelButtonProps", "files"], outputs: ["onBeforeUpload", "onSend", "onUpload", "onError", "onClear", "onRemove", "onSelect", "onProgress", "uploadHandler", "onImageError", "onRemoveUploadedFile"] }, { kind: "ngmodule", type: ImageModule }, { kind: "ngmodule", type: AvatarModule }, { kind: "component", type: i2$2.Avatar, selector: "p-avatar", inputs: ["label", "icon", "image", "size", "shape", "styleClass", "ariaLabel", "ariaLabelledBy"], outputs: ["onImageError"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }] }); }
3644
3709
  }
3645
3710
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: ProfileComponent, decorators: [{
3646
3711
  type: Component,
@@ -3807,7 +3872,7 @@ class ConfigComponent {
3807
3872
  </div>
3808
3873
  }
3809
3874
  </div>
3810
- `, isInline: true, dependencies: [{ kind: "component", type: ProfileComponent, selector: "user-profile" }, { kind: "directive", type: Tooltip, selector: "[pTooltip]", inputs: ["tooltipPosition", "tooltipEvent", "positionStyle", "tooltipStyleClass", "tooltipZIndex", "escape", "showDelay", "hideDelay", "life", "positionTop", "positionLeft", "autoHide", "fitContent", "hideOnEscape", "pTooltip", "tooltipDisabled", "tooltipOptions", "appendTo", "ptTooltip"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i5.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i5.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: Select, selector: "p-select", inputs: ["id", "scrollHeight", "filter", "panelStyle", "styleClass", "panelStyleClass", "readonly", "editable", "tabindex", "placeholder", "loadingIcon", "filterPlaceholder", "filterLocale", "inputId", "dataKey", "filterBy", "filterFields", "autofocus", "resetFilterOnHide", "checkmark", "dropdownIcon", "loading", "optionLabel", "optionValue", "optionDisabled", "optionGroupLabel", "optionGroupChildren", "group", "showClear", "emptyFilterMessage", "emptyMessage", "lazy", "virtualScroll", "virtualScrollItemSize", "virtualScrollOptions", "overlayOptions", "ariaFilterLabel", "ariaLabel", "ariaLabelledBy", "filterMatchMode", "tooltip", "tooltipPosition", "tooltipPositionStyle", "tooltipStyleClass", "focusOnHover", "selectOnFocus", "autoOptionFocus", "autofocusFilter", "filterValue", "options", "appendTo"], outputs: ["onChange", "onFilter", "onFocus", "onBlur", "onClick", "onShow", "onHide", "onClear", "onLazyLoad"] }, { kind: "ngmodule", type: TableModule }, { kind: "ngmodule", type: ToggleSwitchModule }, { kind: "component", type: i2$4.ToggleSwitch, selector: "p-toggleswitch, p-toggleSwitch, p-toggle-switch", inputs: ["styleClass", "tabindex", "inputId", "readonly", "trueValue", "falseValue", "ariaLabel", "size", "ariaLabelledBy", "autofocus"], outputs: ["onChange"] }, { kind: "component", type: Button, selector: "p-button", inputs: ["hostName", "type", "badge", "disabled", "raised", "rounded", "text", "plain", "outlined", "link", "tabindex", "size", "variant", "style", "styleClass", "badgeClass", "badgeSeverity", "ariaLabel", "autofocus", "iconPos", "icon", "label", "loading", "loadingIcon", "severity", "buttonProps", "fluid"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "directive", type: RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "routerLink"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }] }); }
3875
+ `, isInline: true, dependencies: [{ kind: "component", type: ProfileComponent, selector: "user-profile" }, { kind: "directive", type: Tooltip, selector: "[pTooltip]", inputs: ["tooltipPosition", "tooltipEvent", "positionStyle", "tooltipStyleClass", "tooltipZIndex", "escape", "showDelay", "hideDelay", "life", "positionTop", "positionLeft", "autoHide", "fitContent", "hideOnEscape", "pTooltip", "tooltipDisabled", "tooltipOptions", "appendTo", "ptTooltip"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: Select, selector: "p-select", inputs: ["id", "scrollHeight", "filter", "panelStyle", "styleClass", "panelStyleClass", "readonly", "editable", "tabindex", "placeholder", "loadingIcon", "filterPlaceholder", "filterLocale", "inputId", "dataKey", "filterBy", "filterFields", "autofocus", "resetFilterOnHide", "checkmark", "dropdownIcon", "loading", "optionLabel", "optionValue", "optionDisabled", "optionGroupLabel", "optionGroupChildren", "group", "showClear", "emptyFilterMessage", "emptyMessage", "lazy", "virtualScroll", "virtualScrollItemSize", "virtualScrollOptions", "overlayOptions", "ariaFilterLabel", "ariaLabel", "ariaLabelledBy", "filterMatchMode", "tooltip", "tooltipPosition", "tooltipPositionStyle", "tooltipStyleClass", "focusOnHover", "selectOnFocus", "autoOptionFocus", "autofocusFilter", "filterValue", "options", "appendTo"], outputs: ["onChange", "onFilter", "onFocus", "onBlur", "onClick", "onShow", "onHide", "onClear", "onLazyLoad"] }, { kind: "ngmodule", type: TableModule }, { kind: "ngmodule", type: ToggleSwitchModule }, { kind: "component", type: i2$5.ToggleSwitch, selector: "p-toggleswitch, p-toggleSwitch, p-toggle-switch", inputs: ["styleClass", "tabindex", "inputId", "readonly", "trueValue", "falseValue", "ariaLabel", "size", "ariaLabelledBy", "autofocus"], outputs: ["onChange"] }, { kind: "component", type: Button, selector: "p-button", inputs: ["hostName", "type", "badge", "disabled", "raised", "rounded", "text", "plain", "outlined", "link", "tabindex", "size", "variant", "style", "styleClass", "badgeClass", "badgeSeverity", "ariaLabel", "autofocus", "iconPos", "icon", "label", "loading", "loadingIcon", "severity", "buttonProps", "fluid"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "directive", type: RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "routerLink"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }] }); }
3811
3876
  }
3812
3877
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: ConfigComponent, decorators: [{
3813
3878
  type: Component,
@@ -4030,7 +4095,7 @@ class DbMigrationComponent extends BaseModuleComponent {
4030
4095
  } @else if (isSecurity) {
4031
4096
  <security [controller]="controller" [id]="id" />
4032
4097
  }
4033
- `, isInline: true, dependencies: [{ kind: "ngmodule", type: TableModule }, { kind: "component", type: i1$5.Table, selector: "p-table", inputs: ["frozenColumns", "frozenValue", "styleClass", "tableStyle", "tableStyleClass", "paginator", "pageLinks", "rowsPerPageOptions", "alwaysShowPaginator", "paginatorPosition", "paginatorStyleClass", "paginatorDropdownAppendTo", "paginatorDropdownScrollHeight", "currentPageReportTemplate", "showCurrentPageReport", "showJumpToPageDropdown", "showJumpToPageInput", "showFirstLastIcon", "showPageLinks", "defaultSortOrder", "sortMode", "resetPageOnSort", "selectionMode", "selectionPageOnly", "contextMenuSelection", "contextMenuSelectionMode", "dataKey", "metaKeySelection", "rowSelectable", "rowTrackBy", "lazy", "lazyLoadOnInit", "compareSelectionBy", "csvSeparator", "exportFilename", "filters", "globalFilterFields", "filterDelay", "filterLocale", "expandedRowKeys", "editingRowKeys", "rowExpandMode", "scrollable", "rowGroupMode", "scrollHeight", "virtualScroll", "virtualScrollItemSize", "virtualScrollOptions", "virtualScrollDelay", "frozenWidth", "contextMenu", "resizableColumns", "columnResizeMode", "reorderableColumns", "loading", "loadingIcon", "showLoader", "rowHover", "customSort", "showInitialSortBadge", "exportFunction", "exportHeader", "stateKey", "stateStorage", "editMode", "groupRowsBy", "size", "showGridlines", "stripedRows", "groupRowsByOrder", "responsiveLayout", "breakpoint", "paginatorLocale", "value", "columns", "first", "rows", "totalRecords", "sortField", "sortOrder", "multiSortMeta", "selection", "selectAll"], outputs: ["contextMenuSelectionChange", "selectAllChange", "selectionChange", "onRowSelect", "onRowUnselect", "onPage", "onSort", "onFilter", "onLazyLoad", "onRowExpand", "onRowCollapse", "onContextMenuSelect", "onColResize", "onColReorder", "onRowReorder", "onEditInit", "onEditComplete", "onEditCancel", "onHeaderCheckboxToggle", "sortFunction", "firstChange", "rowsChange", "onStateSave", "onStateRestore"] }, { kind: "directive", type: i2$5.PrimeTemplate, selector: "[pTemplate]", inputs: ["type", "pTemplate"] }, { kind: "directive", type: i1$5.SortableColumn, selector: "[pSortableColumn]", inputs: ["pSortableColumn", "pSortableColumnDisabled"] }, { kind: "directive", type: i1$5.EditableRow, selector: "[pEditableRow]", inputs: ["pEditableRow", "pEditableRowDisabled"] }, { kind: "directive", type: i1$5.CancelEditableRow, selector: "[pCancelEditableRow]" }, { kind: "component", type: i1$5.ColumnFilter, selector: "p-columnFilter, p-column-filter, p-columnfilter", inputs: ["field", "type", "display", "showMenu", "matchMode", "operator", "showOperator", "showClearButton", "showApplyButton", "showMatchModes", "showAddButton", "hideOnClear", "placeholder", "matchModeOptions", "maxConstraints", "minFractionDigits", "maxFractionDigits", "prefix", "suffix", "locale", "localeMatcher", "currency", "currencyDisplay", "filterOn", "useGrouping", "showButtons", "ariaLabel", "filterButtonProps"], outputs: ["onShow", "onHide"] }, { kind: "ngmodule", type: SharedModule }, { kind: "ngmodule", type: TagModule }, { kind: "ngmodule", type: InputTextModule }, { kind: "ngmodule", type: TextareaModule }, { kind: "ngmodule", type: ButtonModule }, { kind: "component", type: i1$1.Button, selector: "p-button", inputs: ["hostName", "type", "badge", "disabled", "raised", "rounded", "text", "plain", "outlined", "link", "tabindex", "size", "variant", "style", "styleClass", "badgeClass", "badgeSeverity", "ariaLabel", "autofocus", "iconPos", "icon", "label", "loading", "loadingIcon", "severity", "buttonProps", "fluid"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "ngmodule", type: FormsModule }, { kind: "component", type: ConfirmDialog, selector: "p-confirmDialog, p-confirmdialog, p-confirm-dialog", inputs: ["header", "icon", "message", "style", "styleClass", "maskStyleClass", "acceptIcon", "acceptLabel", "closeAriaLabel", "acceptAriaLabel", "acceptVisible", "rejectIcon", "rejectLabel", "rejectAriaLabel", "rejectVisible", "acceptButtonStyleClass", "rejectButtonStyleClass", "closeOnEscape", "dismissableMask", "blockScroll", "rtl", "closable", "appendTo", "key", "autoZIndex", "baseZIndex", "transitionOptions", "focusTrap", "defaultFocus", "breakpoints", "modal", "visible", "position", "draggable"], outputs: ["onHide"] }, { kind: "component", type: SecurityComponent, selector: "security", inputs: ["id", "controller"] }, { kind: "directive", type: Tooltip, selector: "[pTooltip]", inputs: ["tooltipPosition", "tooltipEvent", "positionStyle", "tooltipStyleClass", "tooltipZIndex", "escape", "showDelay", "hideDelay", "life", "positionTop", "positionLeft", "autoHide", "fitContent", "hideOnEscape", "pTooltip", "tooltipDisabled", "tooltipOptions", "appendTo", "ptTooltip"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }] }); }
4098
+ `, isInline: true, dependencies: [{ kind: "ngmodule", type: TableModule }, { kind: "component", type: i1$6.Table, selector: "p-table", inputs: ["frozenColumns", "frozenValue", "styleClass", "tableStyle", "tableStyleClass", "paginator", "pageLinks", "rowsPerPageOptions", "alwaysShowPaginator", "paginatorPosition", "paginatorStyleClass", "paginatorDropdownAppendTo", "paginatorDropdownScrollHeight", "currentPageReportTemplate", "showCurrentPageReport", "showJumpToPageDropdown", "showJumpToPageInput", "showFirstLastIcon", "showPageLinks", "defaultSortOrder", "sortMode", "resetPageOnSort", "selectionMode", "selectionPageOnly", "contextMenuSelection", "contextMenuSelectionMode", "dataKey", "metaKeySelection", "rowSelectable", "rowTrackBy", "lazy", "lazyLoadOnInit", "compareSelectionBy", "csvSeparator", "exportFilename", "filters", "globalFilterFields", "filterDelay", "filterLocale", "expandedRowKeys", "editingRowKeys", "rowExpandMode", "scrollable", "rowGroupMode", "scrollHeight", "virtualScroll", "virtualScrollItemSize", "virtualScrollOptions", "virtualScrollDelay", "frozenWidth", "contextMenu", "resizableColumns", "columnResizeMode", "reorderableColumns", "loading", "loadingIcon", "showLoader", "rowHover", "customSort", "showInitialSortBadge", "exportFunction", "exportHeader", "stateKey", "stateStorage", "editMode", "groupRowsBy", "size", "showGridlines", "stripedRows", "groupRowsByOrder", "responsiveLayout", "breakpoint", "paginatorLocale", "value", "columns", "first", "rows", "totalRecords", "sortField", "sortOrder", "multiSortMeta", "selection", "selectAll"], outputs: ["contextMenuSelectionChange", "selectAllChange", "selectionChange", "onRowSelect", "onRowUnselect", "onPage", "onSort", "onFilter", "onLazyLoad", "onRowExpand", "onRowCollapse", "onContextMenuSelect", "onColResize", "onColReorder", "onRowReorder", "onEditInit", "onEditComplete", "onEditCancel", "onHeaderCheckboxToggle", "sortFunction", "firstChange", "rowsChange", "onStateSave", "onStateRestore"] }, { kind: "directive", type: i2$6.PrimeTemplate, selector: "[pTemplate]", inputs: ["type", "pTemplate"] }, { kind: "directive", type: i1$6.SortableColumn, selector: "[pSortableColumn]", inputs: ["pSortableColumn", "pSortableColumnDisabled"] }, { kind: "directive", type: i1$6.EditableRow, selector: "[pEditableRow]", inputs: ["pEditableRow", "pEditableRowDisabled"] }, { kind: "directive", type: i1$6.CancelEditableRow, selector: "[pCancelEditableRow]" }, { kind: "component", type: i1$6.ColumnFilter, selector: "p-columnFilter, p-column-filter, p-columnfilter", inputs: ["field", "type", "display", "showMenu", "matchMode", "operator", "showOperator", "showClearButton", "showApplyButton", "showMatchModes", "showAddButton", "hideOnClear", "placeholder", "matchModeOptions", "maxConstraints", "minFractionDigits", "maxFractionDigits", "prefix", "suffix", "locale", "localeMatcher", "currency", "currencyDisplay", "filterOn", "useGrouping", "showButtons", "ariaLabel", "filterButtonProps"], outputs: ["onShow", "onHide"] }, { kind: "ngmodule", type: SharedModule }, { kind: "ngmodule", type: TagModule }, { kind: "ngmodule", type: InputTextModule }, { kind: "ngmodule", type: TextareaModule }, { kind: "ngmodule", type: ButtonModule }, { kind: "component", type: i1$2.Button, selector: "p-button", inputs: ["hostName", "type", "badge", "disabled", "raised", "rounded", "text", "plain", "outlined", "link", "tabindex", "size", "variant", "style", "styleClass", "badgeClass", "badgeSeverity", "ariaLabel", "autofocus", "iconPos", "icon", "label", "loading", "loadingIcon", "severity", "buttonProps", "fluid"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "ngmodule", type: FormsModule }, { kind: "component", type: ConfirmDialog, selector: "p-confirmDialog, p-confirmdialog, p-confirm-dialog", inputs: ["header", "icon", "message", "style", "styleClass", "maskStyleClass", "acceptIcon", "acceptLabel", "closeAriaLabel", "acceptAriaLabel", "acceptVisible", "rejectIcon", "rejectLabel", "rejectAriaLabel", "rejectVisible", "acceptButtonStyleClass", "rejectButtonStyleClass", "closeOnEscape", "dismissableMask", "blockScroll", "rtl", "closable", "appendTo", "key", "autoZIndex", "baseZIndex", "transitionOptions", "focusTrap", "defaultFocus", "breakpoints", "modal", "visible", "position", "draggable"], outputs: ["onHide"] }, { kind: "component", type: SecurityComponent, selector: "security", inputs: ["id", "controller"] }, { kind: "directive", type: Tooltip, selector: "[pTooltip]", inputs: ["tooltipPosition", "tooltipEvent", "positionStyle", "tooltipStyleClass", "tooltipZIndex", "escape", "showDelay", "hideDelay", "life", "positionTop", "positionLeft", "autoHide", "fitContent", "hideOnEscape", "pTooltip", "tooltipDisabled", "tooltipOptions", "appendTo", "ptTooltip"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }] }); }
4034
4099
  }
4035
4100
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: DbMigrationComponent, decorators: [{
4036
4101
  type: Component,
@@ -4271,61 +4336,61 @@ class AppModulesComponent {
4271
4336
  });
4272
4337
  }
4273
4338
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: AppModulesComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
4274
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.16", type: AppModulesComponent, isStandalone: true, selector: "app-modules", providers: [ConfirmationService, ModuleApi], ngImport: i0, template: `
4275
- <p-confirmDialog></p-confirmDialog>
4276
- <div class="flex flex-col md:flex-row gap-4">
4277
- <div class="card w-full">
4278
- <div class="font-semibold text-xl mb-4">
4279
- {{ l10n.title }}
4280
- </div>
4281
- <div class="mb-4">
4282
- <p-toolbar>
4283
- <p-button
4284
- icon="pi pi-refresh"
4285
- rounded="true"
4286
- severity="secondary"
4287
- text="true"
4288
- tooltipPosition="bottom"
4289
- [pTooltip]="'app-modules.refreshTooltip' | translate"
4290
- (onClick)="refreshAction()"></p-button>
4291
- </p-toolbar>
4292
- </div>
4293
- <p-table class="mt-4" [paginator]="true" [rows]="100" [value]="modules">
4294
- <ng-template pTemplate="header">
4295
- <tr>
4296
- <th>{{ 'app-modules.table.moduleId' | translate }}</th>
4297
- <th>{{ 'app-modules.table.name' | translate }}</th>
4298
- <th>{{ 'app-modules.table.currentlyLoaded' | translate }}</th>
4299
- <th style="width: 4rem"></th>
4300
- </tr>
4301
- </ng-template>
4302
- <ng-template let-module pTemplate="body">
4303
- <tr>
4304
- <td>{{ module.moduleId }}</td>
4305
- <td>{{ module.name }}</td>
4306
- <td>
4307
- <p-tag
4308
- [severity]="module.currentlyLoaded ? 'success' : 'danger'"
4309
- [value]="
4310
- (module.currentlyLoaded ? 'app-modules.table.yes' : 'app-modules.table.no') | translate
4311
- "></p-tag>
4312
- </td>
4313
- <td>
4314
- <p-button
4315
- icon="pi pi-trash"
4316
- rounded="true"
4317
- severity="danger"
4318
- text="true"
4319
- tooltipPosition="bottom"
4320
- [pTooltip]="'app-modules.table.deleteTooltip' | translate"
4321
- (onClick)="deleteModule(module)"></p-button>
4322
- </td>
4323
- </tr>
4324
- </ng-template>
4325
- </p-table>
4326
- </div>
4327
- </div>
4328
- `, isInline: true, dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "ngmodule", type: TableModule }, { kind: "component", type: i1$5.Table, selector: "p-table", inputs: ["frozenColumns", "frozenValue", "styleClass", "tableStyle", "tableStyleClass", "paginator", "pageLinks", "rowsPerPageOptions", "alwaysShowPaginator", "paginatorPosition", "paginatorStyleClass", "paginatorDropdownAppendTo", "paginatorDropdownScrollHeight", "currentPageReportTemplate", "showCurrentPageReport", "showJumpToPageDropdown", "showJumpToPageInput", "showFirstLastIcon", "showPageLinks", "defaultSortOrder", "sortMode", "resetPageOnSort", "selectionMode", "selectionPageOnly", "contextMenuSelection", "contextMenuSelectionMode", "dataKey", "metaKeySelection", "rowSelectable", "rowTrackBy", "lazy", "lazyLoadOnInit", "compareSelectionBy", "csvSeparator", "exportFilename", "filters", "globalFilterFields", "filterDelay", "filterLocale", "expandedRowKeys", "editingRowKeys", "rowExpandMode", "scrollable", "rowGroupMode", "scrollHeight", "virtualScroll", "virtualScrollItemSize", "virtualScrollOptions", "virtualScrollDelay", "frozenWidth", "contextMenu", "resizableColumns", "columnResizeMode", "reorderableColumns", "loading", "loadingIcon", "showLoader", "rowHover", "customSort", "showInitialSortBadge", "exportFunction", "exportHeader", "stateKey", "stateStorage", "editMode", "groupRowsBy", "size", "showGridlines", "stripedRows", "groupRowsByOrder", "responsiveLayout", "breakpoint", "paginatorLocale", "value", "columns", "first", "rows", "totalRecords", "sortField", "sortOrder", "multiSortMeta", "selection", "selectAll"], outputs: ["contextMenuSelectionChange", "selectAllChange", "selectionChange", "onRowSelect", "onRowUnselect", "onPage", "onSort", "onFilter", "onLazyLoad", "onRowExpand", "onRowCollapse", "onContextMenuSelect", "onColResize", "onColReorder", "onRowReorder", "onEditInit", "onEditComplete", "onEditCancel", "onHeaderCheckboxToggle", "sortFunction", "firstChange", "rowsChange", "onStateSave", "onStateRestore"] }, { kind: "directive", type: i2$5.PrimeTemplate, selector: "[pTemplate]", inputs: ["type", "pTemplate"] }, { kind: "component", type: Tag, selector: "p-tag", inputs: ["styleClass", "severity", "value", "icon", "rounded"] }, { kind: "ngmodule", type: ButtonModule }, { kind: "component", type: i1$1.Button, selector: "p-button", inputs: ["hostName", "type", "badge", "disabled", "raised", "rounded", "text", "plain", "outlined", "link", "tabindex", "size", "variant", "style", "styleClass", "badgeClass", "badgeSeverity", "ariaLabel", "autofocus", "iconPos", "icon", "label", "loading", "loadingIcon", "severity", "buttonProps", "fluid"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "ngmodule", type: ToolbarModule }, { kind: "component", type: i4$2.Toolbar, selector: "p-toolbar", inputs: ["styleClass", "ariaLabelledBy"] }, { kind: "directive", type: Tooltip, selector: "[pTooltip]", inputs: ["tooltipPosition", "tooltipEvent", "positionStyle", "tooltipStyleClass", "tooltipZIndex", "escape", "showDelay", "hideDelay", "life", "positionTop", "positionLeft", "autoHide", "fitContent", "hideOnEscape", "pTooltip", "tooltipDisabled", "tooltipOptions", "appendTo", "ptTooltip"] }, { kind: "component", type: ConfirmDialog, selector: "p-confirmDialog, p-confirmdialog, p-confirm-dialog", inputs: ["header", "icon", "message", "style", "styleClass", "maskStyleClass", "acceptIcon", "acceptLabel", "closeAriaLabel", "acceptAriaLabel", "acceptVisible", "rejectIcon", "rejectLabel", "rejectAriaLabel", "rejectVisible", "acceptButtonStyleClass", "rejectButtonStyleClass", "closeOnEscape", "dismissableMask", "blockScroll", "rtl", "closable", "appendTo", "key", "autoZIndex", "baseZIndex", "transitionOptions", "focusTrap", "defaultFocus", "breakpoints", "modal", "visible", "position", "draggable"], outputs: ["onHide"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }] }); }
4339
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.16", type: AppModulesComponent, isStandalone: true, selector: "app-modules", providers: [ConfirmationService, ModuleApi], ngImport: i0, template: `
4340
+ <p-confirmDialog></p-confirmDialog>
4341
+ <div class="flex flex-col md:flex-row gap-4">
4342
+ <div class="card w-full">
4343
+ <div class="font-semibold text-xl mb-4">
4344
+ {{ l10n.title }}
4345
+ </div>
4346
+ <div class="mb-4">
4347
+ <p-toolbar>
4348
+ <p-button
4349
+ icon="pi pi-refresh"
4350
+ rounded="true"
4351
+ severity="secondary"
4352
+ text="true"
4353
+ tooltipPosition="bottom"
4354
+ [pTooltip]="'app-modules.refreshTooltip' | translate"
4355
+ (onClick)="refreshAction()"></p-button>
4356
+ </p-toolbar>
4357
+ </div>
4358
+ <p-table class="mt-4" [paginator]="true" [rows]="100" [value]="modules">
4359
+ <ng-template pTemplate="header">
4360
+ <tr>
4361
+ <th>{{ 'app-modules.table.moduleId' | translate }}</th>
4362
+ <th>{{ 'app-modules.table.name' | translate }}</th>
4363
+ <th>{{ 'app-modules.table.currentlyLoaded' | translate }}</th>
4364
+ <th style="width: 4rem"></th>
4365
+ </tr>
4366
+ </ng-template>
4367
+ <ng-template let-module pTemplate="body">
4368
+ <tr>
4369
+ <td>{{ module.moduleId }}</td>
4370
+ <td>{{ module.name }}</td>
4371
+ <td>
4372
+ <p-tag
4373
+ [severity]="module.currentlyLoaded ? 'success' : 'danger'"
4374
+ [value]="
4375
+ (module.currentlyLoaded ? 'app-modules.table.yes' : 'app-modules.table.no') | translate
4376
+ "></p-tag>
4377
+ </td>
4378
+ <td>
4379
+ <p-button
4380
+ icon="pi pi-trash"
4381
+ rounded="true"
4382
+ severity="danger"
4383
+ text="true"
4384
+ tooltipPosition="bottom"
4385
+ [pTooltip]="'app-modules.table.deleteTooltip' | translate"
4386
+ (onClick)="deleteModule(module)"></p-button>
4387
+ </td>
4388
+ </tr>
4389
+ </ng-template>
4390
+ </p-table>
4391
+ </div>
4392
+ </div>
4393
+ `, isInline: true, dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "ngmodule", type: TableModule }, { kind: "component", type: i1$6.Table, selector: "p-table", inputs: ["frozenColumns", "frozenValue", "styleClass", "tableStyle", "tableStyleClass", "paginator", "pageLinks", "rowsPerPageOptions", "alwaysShowPaginator", "paginatorPosition", "paginatorStyleClass", "paginatorDropdownAppendTo", "paginatorDropdownScrollHeight", "currentPageReportTemplate", "showCurrentPageReport", "showJumpToPageDropdown", "showJumpToPageInput", "showFirstLastIcon", "showPageLinks", "defaultSortOrder", "sortMode", "resetPageOnSort", "selectionMode", "selectionPageOnly", "contextMenuSelection", "contextMenuSelectionMode", "dataKey", "metaKeySelection", "rowSelectable", "rowTrackBy", "lazy", "lazyLoadOnInit", "compareSelectionBy", "csvSeparator", "exportFilename", "filters", "globalFilterFields", "filterDelay", "filterLocale", "expandedRowKeys", "editingRowKeys", "rowExpandMode", "scrollable", "rowGroupMode", "scrollHeight", "virtualScroll", "virtualScrollItemSize", "virtualScrollOptions", "virtualScrollDelay", "frozenWidth", "contextMenu", "resizableColumns", "columnResizeMode", "reorderableColumns", "loading", "loadingIcon", "showLoader", "rowHover", "customSort", "showInitialSortBadge", "exportFunction", "exportHeader", "stateKey", "stateStorage", "editMode", "groupRowsBy", "size", "showGridlines", "stripedRows", "groupRowsByOrder", "responsiveLayout", "breakpoint", "paginatorLocale", "value", "columns", "first", "rows", "totalRecords", "sortField", "sortOrder", "multiSortMeta", "selection", "selectAll"], outputs: ["contextMenuSelectionChange", "selectAllChange", "selectionChange", "onRowSelect", "onRowUnselect", "onPage", "onSort", "onFilter", "onLazyLoad", "onRowExpand", "onRowCollapse", "onContextMenuSelect", "onColResize", "onColReorder", "onRowReorder", "onEditInit", "onEditComplete", "onEditCancel", "onHeaderCheckboxToggle", "sortFunction", "firstChange", "rowsChange", "onStateSave", "onStateRestore"] }, { kind: "directive", type: i2$6.PrimeTemplate, selector: "[pTemplate]", inputs: ["type", "pTemplate"] }, { kind: "component", type: Tag, selector: "p-tag", inputs: ["styleClass", "severity", "value", "icon", "rounded"] }, { kind: "ngmodule", type: ButtonModule }, { kind: "component", type: i1$2.Button, selector: "p-button", inputs: ["hostName", "type", "badge", "disabled", "raised", "rounded", "text", "plain", "outlined", "link", "tabindex", "size", "variant", "style", "styleClass", "badgeClass", "badgeSeverity", "ariaLabel", "autofocus", "iconPos", "icon", "label", "loading", "loadingIcon", "severity", "buttonProps", "fluid"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "ngmodule", type: ToolbarModule }, { kind: "component", type: i4$1.Toolbar, selector: "p-toolbar", inputs: ["styleClass", "ariaLabelledBy"] }, { kind: "directive", type: Tooltip, selector: "[pTooltip]", inputs: ["tooltipPosition", "tooltipEvent", "positionStyle", "tooltipStyleClass", "tooltipZIndex", "escape", "showDelay", "hideDelay", "life", "positionTop", "positionLeft", "autoHide", "fitContent", "hideOnEscape", "pTooltip", "tooltipDisabled", "tooltipOptions", "appendTo", "ptTooltip"] }, { kind: "component", type: ConfirmDialog, selector: "p-confirmDialog, p-confirmdialog, p-confirm-dialog", inputs: ["header", "icon", "message", "style", "styleClass", "maskStyleClass", "acceptIcon", "acceptLabel", "closeAriaLabel", "acceptAriaLabel", "acceptVisible", "rejectIcon", "rejectLabel", "rejectAriaLabel", "rejectVisible", "acceptButtonStyleClass", "rejectButtonStyleClass", "closeOnEscape", "dismissableMask", "blockScroll", "rtl", "closable", "appendTo", "key", "autoZIndex", "baseZIndex", "transitionOptions", "focusTrap", "defaultFocus", "breakpoints", "modal", "visible", "position", "draggable"], outputs: ["onHide"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }] }); }
4329
4394
  }
4330
4395
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: AppModulesComponent, decorators: [{
4331
4396
  type: Component,
@@ -4333,64 +4398,1429 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
4333
4398
  imports: [FormsModule, TableModule, Tag, ButtonModule, ToolbarModule, Tooltip, ConfirmDialog, TranslatePipe],
4334
4399
  providers: [ConfirmationService, ModuleApi],
4335
4400
  selector: 'app-modules',
4336
- template: `
4337
- <p-confirmDialog></p-confirmDialog>
4338
- <div class="flex flex-col md:flex-row gap-4">
4339
- <div class="card w-full">
4340
- <div class="font-semibold text-xl mb-4">
4341
- {{ l10n.title }}
4342
- </div>
4343
- <div class="mb-4">
4344
- <p-toolbar>
4345
- <p-button
4346
- icon="pi pi-refresh"
4347
- rounded="true"
4348
- severity="secondary"
4349
- text="true"
4350
- tooltipPosition="bottom"
4351
- [pTooltip]="'app-modules.refreshTooltip' | translate"
4352
- (onClick)="refreshAction()"></p-button>
4353
- </p-toolbar>
4354
- </div>
4355
- <p-table class="mt-4" [paginator]="true" [rows]="100" [value]="modules">
4356
- <ng-template pTemplate="header">
4357
- <tr>
4358
- <th>{{ 'app-modules.table.moduleId' | translate }}</th>
4359
- <th>{{ 'app-modules.table.name' | translate }}</th>
4360
- <th>{{ 'app-modules.table.currentlyLoaded' | translate }}</th>
4361
- <th style="width: 4rem"></th>
4362
- </tr>
4363
- </ng-template>
4364
- <ng-template let-module pTemplate="body">
4365
- <tr>
4366
- <td>{{ module.moduleId }}</td>
4367
- <td>{{ module.name }}</td>
4368
- <td>
4369
- <p-tag
4370
- [severity]="module.currentlyLoaded ? 'success' : 'danger'"
4371
- [value]="
4372
- (module.currentlyLoaded ? 'app-modules.table.yes' : 'app-modules.table.no') | translate
4373
- "></p-tag>
4374
- </td>
4375
- <td>
4376
- <p-button
4377
- icon="pi pi-trash"
4378
- rounded="true"
4379
- severity="danger"
4380
- text="true"
4381
- tooltipPosition="bottom"
4382
- [pTooltip]="'app-modules.table.deleteTooltip' | translate"
4383
- (onClick)="deleteModule(module)"></p-button>
4384
- </td>
4385
- </tr>
4386
- </ng-template>
4387
- </p-table>
4388
- </div>
4389
- </div>
4401
+ template: `
4402
+ <p-confirmDialog></p-confirmDialog>
4403
+ <div class="flex flex-col md:flex-row gap-4">
4404
+ <div class="card w-full">
4405
+ <div class="font-semibold text-xl mb-4">
4406
+ {{ l10n.title }}
4407
+ </div>
4408
+ <div class="mb-4">
4409
+ <p-toolbar>
4410
+ <p-button
4411
+ icon="pi pi-refresh"
4412
+ rounded="true"
4413
+ severity="secondary"
4414
+ text="true"
4415
+ tooltipPosition="bottom"
4416
+ [pTooltip]="'app-modules.refreshTooltip' | translate"
4417
+ (onClick)="refreshAction()"></p-button>
4418
+ </p-toolbar>
4419
+ </div>
4420
+ <p-table class="mt-4" [paginator]="true" [rows]="100" [value]="modules">
4421
+ <ng-template pTemplate="header">
4422
+ <tr>
4423
+ <th>{{ 'app-modules.table.moduleId' | translate }}</th>
4424
+ <th>{{ 'app-modules.table.name' | translate }}</th>
4425
+ <th>{{ 'app-modules.table.currentlyLoaded' | translate }}</th>
4426
+ <th style="width: 4rem"></th>
4427
+ </tr>
4428
+ </ng-template>
4429
+ <ng-template let-module pTemplate="body">
4430
+ <tr>
4431
+ <td>{{ module.moduleId }}</td>
4432
+ <td>{{ module.name }}</td>
4433
+ <td>
4434
+ <p-tag
4435
+ [severity]="module.currentlyLoaded ? 'success' : 'danger'"
4436
+ [value]="
4437
+ (module.currentlyLoaded ? 'app-modules.table.yes' : 'app-modules.table.no') | translate
4438
+ "></p-tag>
4439
+ </td>
4440
+ <td>
4441
+ <p-button
4442
+ icon="pi pi-trash"
4443
+ rounded="true"
4444
+ severity="danger"
4445
+ text="true"
4446
+ tooltipPosition="bottom"
4447
+ [pTooltip]="'app-modules.table.deleteTooltip' | translate"
4448
+ (onClick)="deleteModule(module)"></p-button>
4449
+ </td>
4450
+ </tr>
4451
+ </ng-template>
4452
+ </p-table>
4453
+ </div>
4454
+ </div>
4390
4455
  `
4391
4456
  }]
4392
4457
  }] });
4393
4458
 
4459
+ /* eslint-disable */
4460
+ /* tslint:disable */
4461
+ // @ts-nocheck
4462
+ class DiscussionApi extends HttpClient {
4463
+ constructor() {
4464
+ super(...arguments);
4465
+ /**
4466
+ * @description Gets comments by object type and object identifier.
4467
+ *
4468
+ * @tags Discussion
4469
+ * @name getByObject
4470
+ * @summary Gets comments by object type and object identifier.
4471
+ * @request GET:/api/discussion/get-by-object
4472
+ * @secure
4473
+ * @response `200` `(CommentDto)[]` OK
4474
+ * @response `401` `ApiExceptionResponse` Unauthorized
4475
+ */
4476
+ this.getByObject = (query, params = {}) => this.request({
4477
+ path: `/api/discussion/get-by-object`,
4478
+ method: "GET",
4479
+ query: query,
4480
+ secure: true,
4481
+ format: "json",
4482
+ ...params,
4483
+ });
4484
+ /**
4485
+ * @description Gets a comment by identifier.
4486
+ *
4487
+ * @tags Discussion
4488
+ * @name getById
4489
+ * @summary Gets a comment by identifier.
4490
+ * @request GET:/api/discussion/get-by-id
4491
+ * @secure
4492
+ * @response `200` `CommentDto` OK
4493
+ * @response `401` `ApiExceptionResponse` Unauthorized
4494
+ * @response `404` `ApiExceptionResponse` Not Found
4495
+ */
4496
+ this.getById = (query, params = {}) => this.request({
4497
+ path: `/api/discussion/get-by-id`,
4498
+ method: "GET",
4499
+ query: query,
4500
+ secure: true,
4501
+ format: "json",
4502
+ ...params,
4503
+ });
4504
+ /**
4505
+ * @description Creates a new comment
4506
+ *
4507
+ * @tags Discussion
4508
+ * @name create
4509
+ * @summary Creates a new comment
4510
+ * @request POST:/api/discussion/create
4511
+ * @secure
4512
+ * @response `200` `CommentDto` OK
4513
+ * @response `400` `ApiExceptionResponse` Bad Request
4514
+ * @response `401` `ApiExceptionResponse` Unauthorized
4515
+ */
4516
+ this.create = (data, params = {}) => this.request({
4517
+ path: `/api/discussion/create`,
4518
+ method: "POST",
4519
+ body: data,
4520
+ secure: true,
4521
+ type: ContentType.Json,
4522
+ format: "json",
4523
+ ...params,
4524
+ });
4525
+ /**
4526
+ * @description Updates an existing comment.
4527
+ *
4528
+ * @tags Discussion
4529
+ * @name update
4530
+ * @summary Updates an existing comment.
4531
+ * @request PUT:/api/discussion/update/{id}
4532
+ * @secure
4533
+ * @response `200` `CommentDto` OK
4534
+ * @response `400` `ApiExceptionResponse` Bad Request
4535
+ * @response `401` `ApiExceptionResponse` Unauthorized
4536
+ * @response `403` `ApiExceptionResponse` Forbidden
4537
+ * @response `404` `ApiExceptionResponse` Not Found
4538
+ */
4539
+ this.update = ({ id, ...query }, data, params = {}) => this.request({
4540
+ path: `/api/discussion/update/${id}`,
4541
+ method: "PUT",
4542
+ body: data,
4543
+ secure: true,
4544
+ type: ContentType.Json,
4545
+ format: "json",
4546
+ ...params,
4547
+ });
4548
+ /**
4549
+ * @description Soft deletes a comment.
4550
+ *
4551
+ * @tags Discussion
4552
+ * @name delete
4553
+ * @summary Soft deletes a comment.
4554
+ * @request DELETE:/api/discussion/delete/{id}
4555
+ * @secure
4556
+ * @response `204` `void` No Content
4557
+ * @response `401` `ApiExceptionResponse` Unauthorized
4558
+ * @response `403` `ApiExceptionResponse` Forbidden
4559
+ * @response `404` `ApiExceptionResponse` Not Found
4560
+ */
4561
+ this.delete = ({ id, ...query }, params = {}) => this.request({
4562
+ path: `/api/discussion/delete/${id}`,
4563
+ method: "DELETE",
4564
+ secure: true,
4565
+ ...params,
4566
+ });
4567
+ /**
4568
+ * @description Gets edit history for a comment.
4569
+ *
4570
+ * @tags Discussion
4571
+ * @name getHistory
4572
+ * @summary Gets edit history for a comment.
4573
+ * @request GET:/api/discussion/get-history/{id}
4574
+ * @secure
4575
+ * @response `200` `(CommentHistoryDto)[]` OK
4576
+ * @response `401` `ApiExceptionResponse` Unauthorized
4577
+ * @response `404` `ApiExceptionResponse` Not Found
4578
+ */
4579
+ this.getHistory = ({ id, ...query }, params = {}) => this.request({
4580
+ path: `/api/discussion/get-history/${id}`,
4581
+ method: "GET",
4582
+ secure: true,
4583
+ format: "json",
4584
+ ...params,
4585
+ });
4586
+ /**
4587
+ * @description Uploads an attachment for a comment.
4588
+ *
4589
+ * @tags Discussion
4590
+ * @name uploadAttachment
4591
+ * @summary Uploads an attachment for a comment.
4592
+ * @request POST:/api/discussion/upload-attachment
4593
+ * @secure
4594
+ * @response `200` `AttachmentDto` OK
4595
+ * @response `400` `ApiExceptionResponse` Bad Request
4596
+ * @response `401` `ApiExceptionResponse` Unauthorized
4597
+ * @response `403` `ApiExceptionResponse` Forbidden
4598
+ * @response `404` `ApiExceptionResponse` Not Found
4599
+ */
4600
+ this.uploadAttachment = (data, params = {}) => this.request({
4601
+ path: `/api/discussion/upload-attachment`,
4602
+ method: "POST",
4603
+ body: data,
4604
+ secure: true,
4605
+ type: ContentType.FormData,
4606
+ format: "json",
4607
+ ...params,
4608
+ });
4609
+ /**
4610
+ * @description Deletes an attachment.
4611
+ *
4612
+ * @tags Discussion
4613
+ * @name deleteAttachment
4614
+ * @summary Deletes an attachment.
4615
+ * @request DELETE:/api/discussion/delete-attachment/{id}
4616
+ * @secure
4617
+ * @response `204` `void` No Content
4618
+ * @response `401` `ApiExceptionResponse` Unauthorized
4619
+ * @response `403` `ApiExceptionResponse` Forbidden
4620
+ * @response `404` `ApiExceptionResponse` Not Found
4621
+ */
4622
+ this.deleteAttachment = ({ id, ...query }, params = {}) => this.request({
4623
+ path: `/api/discussion/delete-attachment/${id}`,
4624
+ method: "DELETE",
4625
+ secure: true,
4626
+ ...params,
4627
+ });
4628
+ /**
4629
+ * @description Downloads attachment content.
4630
+ *
4631
+ * @tags Discussion
4632
+ * @name getAttachmentContent
4633
+ * @summary Downloads attachment content.
4634
+ * @request GET:/api/discussion/get-attachment-content/{id}
4635
+ * @secure
4636
+ * @response `200` `void` OK
4637
+ * @response `401` `ApiExceptionResponse` Unauthorized
4638
+ * @response `404` `ApiExceptionResponse` Not Found
4639
+ */
4640
+ this.getAttachmentContent = ({ id, ...query }, params = {}) => this.request({
4641
+ path: `/api/discussion/get-attachment-content/${id}`,
4642
+ method: "GET",
4643
+ secure: true,
4644
+ ...params,
4645
+ });
4646
+ /**
4647
+ * @description Adds or toggles a reaction for a comment.
4648
+ *
4649
+ * @tags Discussion
4650
+ * @name addReaction
4651
+ * @summary Adds or toggles a reaction for a comment.
4652
+ * @request POST:/api/discussion/add-reaction
4653
+ * @secure
4654
+ * @response `200` `(CommentReactionDto)[]` OK
4655
+ * @response `400` `ApiExceptionResponse` Bad Request
4656
+ * @response `401` `ApiExceptionResponse` Unauthorized
4657
+ * @response `404` `ApiExceptionResponse` Not Found
4658
+ */
4659
+ this.addReaction = (data, params = {}) => this.request({
4660
+ path: `/api/discussion/add-reaction`,
4661
+ method: "POST",
4662
+ body: data,
4663
+ secure: true,
4664
+ type: ContentType.Json,
4665
+ format: "json",
4666
+ ...params,
4667
+ });
4668
+ /**
4669
+ * @description Removes a reaction from a comment.
4670
+ *
4671
+ * @tags Discussion
4672
+ * @name removeReaction
4673
+ * @summary Removes a reaction from a comment.
4674
+ * @request DELETE:/api/discussion/remove-reaction
4675
+ * @secure
4676
+ * @response `200` `(CommentReactionDto)[]` OK
4677
+ * @response `401` `ApiExceptionResponse` Unauthorized
4678
+ * @response `404` `ApiExceptionResponse` Not Found
4679
+ */
4680
+ this.removeReaction = (query, params = {}) => this.request({
4681
+ path: `/api/discussion/remove-reaction`,
4682
+ method: "DELETE",
4683
+ query: query,
4684
+ secure: true,
4685
+ format: "json",
4686
+ ...params,
4687
+ });
4688
+ /**
4689
+ * @description Searches users that can be mentioned in a comment.
4690
+ *
4691
+ * @tags Discussion
4692
+ * @name searchMentionUsers
4693
+ * @summary Searches users that can be mentioned in a comment.
4694
+ * @request GET:/api/discussion/search-mention-users
4695
+ * @secure
4696
+ * @response `200` `(MentionUserDto)[]` OK
4697
+ * @response `400` `ApiExceptionResponse` Bad Request
4698
+ * @response `401` `ApiExceptionResponse` Unauthorized
4699
+ */
4700
+ this.searchMentionUsers = (query, params = {}) => this.request({
4701
+ path: `/api/discussion/search-mention-users`,
4702
+ method: "GET",
4703
+ query: query,
4704
+ secure: true,
4705
+ format: "json",
4706
+ ...params,
4707
+ });
4708
+ }
4709
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: DiscussionApi, deps: null, target: i0.ɵɵFactoryTarget.Injectable }); }
4710
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: DiscussionApi }); }
4711
+ }
4712
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: DiscussionApi, decorators: [{
4713
+ type: Injectable
4714
+ }] });
4715
+
4716
+ function getInitialsFromString(input) {
4717
+ if (!input || input.trim().length === 0) {
4718
+ return '';
4719
+ }
4720
+ const words = input.trim().split(/\s+/);
4721
+ if (words.length === 1) {
4722
+ return words[0].charAt(0).toUpperCase();
4723
+ }
4724
+ const firstInitial = words[0].charAt(0).toUpperCase();
4725
+ const lastInitial = words[words.length - 1].charAt(0).toUpperCase();
4726
+ return firstInitial + lastInitial;
4727
+ }
4728
+
4729
+ class DiscussionComponent {
4730
+ constructor() {
4731
+ this.msgService = inject(MsgService);
4732
+ this.discussionApi = inject(DiscussionApi);
4733
+ this.sanitizer = inject(DomSanitizer);
4734
+ this.translateService = inject(TranslateService);
4735
+ this.cdr = inject(ChangeDetectorRef);
4736
+ this.confirmationService = inject(ConfirmationService);
4737
+ this.layoutService = inject(LayoutService);
4738
+ this.objectTypeId = 1;
4739
+ this.objectId = 1;
4740
+ this.comments = [];
4741
+ this.loading = false;
4742
+ this.submitting = false;
4743
+ this.previewMode = false;
4744
+ this.newComment = '';
4745
+ this.editContent = '';
4746
+ this.editingCommentId = null;
4747
+ this.pendingFiles = [];
4748
+ this.mentionSuggestions = [];
4749
+ this.historyByComment = {};
4750
+ this.emojiPalette = ['👍', '👎', '🐳', '🍆', '🍑'];
4751
+ this.mentionSearchTimer = null;
4752
+ this.getInitialsFromString = getInitialsFromString;
4753
+ }
4754
+ ngOnChanges(changes) {
4755
+ if ((changes['objectTypeId'] || changes['objectId']) && this.objectTypeId && this.objectId) {
4756
+ this.loadComments().then();
4757
+ }
4758
+ }
4759
+ async ngOnInit() {
4760
+ await this.loadComments();
4761
+ }
4762
+ ngOnDestroy() {
4763
+ if (this.mentionSearchTimer) {
4764
+ clearTimeout(this.mentionSearchTimer);
4765
+ }
4766
+ }
4767
+ async loadComments() {
4768
+ if (!this.objectTypeId || !this.objectId) {
4769
+ return;
4770
+ }
4771
+ this.loading = true;
4772
+ this.cdr.markForCheck();
4773
+ try {
4774
+ const items = await this.discussionApi.getByObject({
4775
+ objectTypeId: this.objectTypeId,
4776
+ objectId: this.objectId,
4777
+ skip: 0,
4778
+ take: 50
4779
+ });
4780
+ this.comments = items.map((item) => this.normalizeComment(item));
4781
+ }
4782
+ catch (error) {
4783
+ this.msgService.errorFromException(error, this.translateService.instant('discussionComponent.errors.loadComments'));
4784
+ }
4785
+ finally {
4786
+ this.loading = false;
4787
+ this.cdr.markForCheck();
4788
+ }
4789
+ }
4790
+ async createComment() {
4791
+ const content = this.newComment.trim();
4792
+ if (!content) {
4793
+ return;
4794
+ }
4795
+ this.submitting = true;
4796
+ this.cdr.markForCheck();
4797
+ try {
4798
+ const created = await this.discussionApi.create({
4799
+ objectTypeId: this.objectTypeId,
4800
+ objectId: this.objectId,
4801
+ content
4802
+ });
4803
+ if (this.pendingFiles.length > 0) {
4804
+ for (const file of this.pendingFiles) {
4805
+ await this.discussionApi.uploadAttachment({
4806
+ CommentId: created.commentId,
4807
+ File: file
4808
+ });
4809
+ }
4810
+ }
4811
+ this.newComment = '';
4812
+ this.pendingFiles = [];
4813
+ this.previewMode = false;
4814
+ this.mentionSuggestions = [];
4815
+ await this.loadComments();
4816
+ }
4817
+ catch (error) {
4818
+ this.msgService.errorFromException(error, this.translateService.instant('discussionComponent.errors.createComment'));
4819
+ }
4820
+ finally {
4821
+ this.submitting = false;
4822
+ this.cdr.markForCheck();
4823
+ }
4824
+ }
4825
+ startEdit(comment) {
4826
+ this.editingCommentId = comment.commentId;
4827
+ this.editContent = comment.content;
4828
+ }
4829
+ cancelEdit() {
4830
+ this.editingCommentId = null;
4831
+ this.editContent = '';
4832
+ }
4833
+ async saveEdit(comment) {
4834
+ try {
4835
+ const updated = await this.discussionApi.update({ id: comment.commentId }, { content: this.editContent.trim() });
4836
+ this.comments = this.comments.map((item) => item.commentId === comment.commentId ? this.normalizeComment(updated) : item);
4837
+ this.cancelEdit();
4838
+ }
4839
+ catch (error) {
4840
+ this.msgService.errorFromException(error, this.translateService.instant('discussionComponent.errors.updateComment'));
4841
+ }
4842
+ finally {
4843
+ this.cdr.markForCheck();
4844
+ }
4845
+ }
4846
+ deleteComment(comment) {
4847
+ this.confirmationService.confirm({
4848
+ header: this.translateService.instant('discussionComponent.warning'),
4849
+ message: this.translateService.instant('discussionComponent.confirmDeleteComment'),
4850
+ icon: 'pi pi-trash',
4851
+ rejectButtonProps: {
4852
+ label: this.translateService.instant('discussionComponent.cancel'),
4853
+ severity: 'secondary',
4854
+ outlined: true
4855
+ },
4856
+ acceptButtonProps: {
4857
+ label: this.translateService.instant('discussionComponent.delete'),
4858
+ severity: 'danger'
4859
+ },
4860
+ accept: async () => {
4861
+ await this.performDeleteComment(comment);
4862
+ }
4863
+ });
4864
+ }
4865
+ async toggleHistory(comment) {
4866
+ const current = this.historyByComment[comment.commentId];
4867
+ if (current?.opened) {
4868
+ this.historyByComment[comment.commentId] = { ...current, opened: false };
4869
+ return;
4870
+ }
4871
+ this.historyByComment[comment.commentId] = {
4872
+ opened: true,
4873
+ loading: true,
4874
+ items: current?.items ?? []
4875
+ };
4876
+ this.cdr.markForCheck();
4877
+ try {
4878
+ const items = await this.discussionApi.getHistory({ id: comment.commentId });
4879
+ this.historyByComment[comment.commentId] = {
4880
+ opened: true,
4881
+ loading: false,
4882
+ items: items.map((item) => this.normalizeHistoryItem(item))
4883
+ };
4884
+ }
4885
+ catch (error) {
4886
+ this.msgService.errorFromException(error, this.translateService.instant('discussionComponent.errors.loadEditHistory'));
4887
+ this.historyByComment[comment.commentId] = {
4888
+ opened: false,
4889
+ loading: false,
4890
+ items: []
4891
+ };
4892
+ }
4893
+ finally {
4894
+ this.cdr.markForCheck();
4895
+ }
4896
+ }
4897
+ onFilesSelected(event) {
4898
+ const input = event.target;
4899
+ this.pendingFiles = [...this.pendingFiles, ...Array.from(input.files ?? [])];
4900
+ input.value = '';
4901
+ }
4902
+ removePendingFile(file) {
4903
+ this.pendingFiles = this.pendingFiles.filter((item) => item !== file);
4904
+ }
4905
+ async onInlineFilesSelected(comment, event) {
4906
+ const input = event.target;
4907
+ const files = Array.from(input.files ?? []);
4908
+ input.value = '';
4909
+ try {
4910
+ for (const file of files) {
4911
+ await this.discussionApi.uploadAttachment({
4912
+ CommentId: comment.commentId,
4913
+ File: file
4914
+ });
4915
+ }
4916
+ await this.loadComments();
4917
+ }
4918
+ catch (error) {
4919
+ this.msgService.errorFromException(error, this.translateService.instant('discussionComponent.errors.uploadAttachment'));
4920
+ this.cdr.markForCheck();
4921
+ }
4922
+ }
4923
+ deleteAttachment(comment, attachment) {
4924
+ this.confirmationService.confirm({
4925
+ header: this.translateService.instant('discussionComponent.warning'),
4926
+ message: this.translateService.instant('discussionComponent.confirmDeleteFile', { fileName: attachment.fileName }),
4927
+ icon: 'pi pi-trash',
4928
+ rejectButtonProps: {
4929
+ label: this.translateService.instant('discussionComponent.cancel'),
4930
+ severity: 'secondary',
4931
+ outlined: true
4932
+ },
4933
+ acceptButtonProps: {
4934
+ label: this.translateService.instant('discussionComponent.delete'),
4935
+ severity: 'danger'
4936
+ },
4937
+ accept: async () => {
4938
+ await this.performDeleteAttachment(comment, attachment);
4939
+ }
4940
+ });
4941
+ }
4942
+ async performDeleteComment(comment) {
4943
+ try {
4944
+ await this.discussionApi.delete({ id: comment.commentId });
4945
+ this.comments = this.comments.filter((item) => item.commentId !== comment.commentId);
4946
+ }
4947
+ catch (error) {
4948
+ this.msgService.errorFromException(error, this.translateService.instant('discussionComponent.errors.deleteComment'));
4949
+ }
4950
+ finally {
4951
+ this.cdr.markForCheck();
4952
+ }
4953
+ }
4954
+ async performDeleteAttachment(comment, attachment) {
4955
+ try {
4956
+ await this.discussionApi.deleteAttachment({ id: attachment.attachmentId });
4957
+ this.comments = this.comments.map((item) => item.commentId === comment.commentId
4958
+ ? { ...item, attachments: item.attachments.filter((entry) => entry.attachmentId !== attachment.attachmentId) }
4959
+ : item);
4960
+ }
4961
+ catch (error) {
4962
+ this.msgService.errorFromException(error, this.translateService.instant('discussionComponent.errors.deleteAttachment'));
4963
+ }
4964
+ finally {
4965
+ this.cdr.markForCheck();
4966
+ }
4967
+ }
4968
+ async downloadAttachment(attachment) {
4969
+ try {
4970
+ const blob = (await this.discussionApi.getAttachmentContent({ id: attachment.attachmentId }, { format: 'blob' }));
4971
+ const url = URL.createObjectURL(blob);
4972
+ const link = document.createElement('a');
4973
+ link.href = url;
4974
+ link.download = attachment.fileName;
4975
+ link.click();
4976
+ URL.revokeObjectURL(url);
4977
+ }
4978
+ catch (error) {
4979
+ this.msgService.errorFromException(error, this.translateService.instant('discussionComponent.errors.downloadAttachment'));
4980
+ this.cdr.markForCheck();
4981
+ }
4982
+ }
4983
+ async toggleReaction(comment, reaction) {
4984
+ try {
4985
+ const reactions = reaction.reactedByCurrentUser
4986
+ ? await this.discussionApi.removeReaction({ commentId: comment.commentId, emojiCode: reaction.emojiCode })
4987
+ : await this.discussionApi.addReaction({ commentId: comment.commentId, emojiCode: reaction.emojiCode });
4988
+ this.applyReactions(comment.commentId, reactions.map((item) => this.normalizeReaction(item)));
4989
+ }
4990
+ catch (error) {
4991
+ this.msgService.errorFromException(error, this.translateService.instant('discussionComponent.errors.updateReaction'));
4992
+ }
4993
+ finally {
4994
+ this.cdr.markForCheck();
4995
+ }
4996
+ }
4997
+ async reactWithEmoji(comment, emojiCode, popover) {
4998
+ try {
4999
+ const reactions = await this.discussionApi.addReaction({ commentId: comment.commentId, emojiCode });
5000
+ this.applyReactions(comment.commentId, reactions.map((item) => this.normalizeReaction(item)));
5001
+ popover?.hide();
5002
+ }
5003
+ catch (error) {
5004
+ this.msgService.errorFromException(error, this.translateService.instant('discussionComponent.errors.addReaction'));
5005
+ }
5006
+ finally {
5007
+ this.cdr.markForCheck();
5008
+ }
5009
+ }
5010
+ onComposerInput() {
5011
+ if (this.mentionSearchTimer) {
5012
+ clearTimeout(this.mentionSearchTimer);
5013
+ }
5014
+ const token = this.extractMentionQuery(this.newComment);
5015
+ if (!token || token.length < 2) {
5016
+ this.mentionSuggestions = [];
5017
+ this.cdr.markForCheck();
5018
+ return;
5019
+ }
5020
+ this.mentionSearchTimer = setTimeout(async () => {
5021
+ try {
5022
+ const users = await this.discussionApi.searchMentionUsers({ term: token });
5023
+ this.mentionSuggestions = users.map((item) => this.normalizeMentionUser(item));
5024
+ }
5025
+ catch {
5026
+ this.mentionSuggestions = [];
5027
+ }
5028
+ finally {
5029
+ this.cdr.markForCheck();
5030
+ }
5031
+ }, 250);
5032
+ }
5033
+ insertMention(candidate) {
5034
+ const query = this.extractMentionQuery(this.newComment);
5035
+ if (!query) {
5036
+ return;
5037
+ }
5038
+ this.newComment = this.newComment.replace(/@[\w.+\-@]*$/, `@${candidate.email} `);
5039
+ this.mentionSuggestions = [];
5040
+ }
5041
+ renderMarkdown(markdown) {
5042
+ const escaped = markdown.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;');
5043
+ const html = escaped
5044
+ .replace(/^### (.*)$/gm, '<h3>$1</h3>')
5045
+ .replace(/^## (.*)$/gm, '<h2>$1</h2>')
5046
+ .replace(/^# (.*)$/gm, '<h1>$1</h1>')
5047
+ .replace(/\*\*(.+?)\*\*/g, '<strong>$1</strong>')
5048
+ .replace(/\*(.+?)\*/g, '<em>$1</em>')
5049
+ .replace(/`(.+?)`/g, '<code>$1</code>')
5050
+ .replace(/\[([^\]]+)\]\((https?:\/\/[^\s]+)\)/g, '<a href="$2" target="_blank" rel="noopener">$1</a>')
5051
+ .replace(/(^|\s)@([A-Za-z0-9._+\-@]+)/g, '$1<span class="mention-token">@$2</span>')
5052
+ .replace(/\n/g, '<br>');
5053
+ return this.sanitizer.sanitize(SecurityContext.HTML, html) ?? '';
5054
+ }
5055
+ formatBytes(value) {
5056
+ if (value < 1024) {
5057
+ return `${value} ${this.translateService.instant('discussionComponent.units.bytes')}`;
5058
+ }
5059
+ if (value < 1024 * 1024) {
5060
+ return `${(value / 1024).toFixed(1)} ${this.translateService.instant('discussionComponent.units.kilobytes')}`;
5061
+ }
5062
+ return `${(value / (1024 * 1024)).toFixed(1)} ${this.translateService.instant('discussionComponent.units.megabytes')}`;
5063
+ }
5064
+ hasUserReaction(comment) {
5065
+ return comment.reactions.some((reaction) => reaction.reactedByCurrentUser);
5066
+ }
5067
+ getReactions(comment) {
5068
+ return comment.reactions;
5069
+ }
5070
+ applyReactions(commentId, reactions) {
5071
+ this.comments = this.comments.map((item) => (item.commentId === commentId ? { ...item, reactions } : item));
5072
+ }
5073
+ normalizeComment(comment) {
5074
+ return {
5075
+ ...comment,
5076
+ commentId: comment.commentId ?? 0,
5077
+ content: comment.content ?? '',
5078
+ authorDisplayName: comment.authorDisplayName ?? '',
5079
+ authorEmail: comment.authorEmail ?? '',
5080
+ isEdited: comment.isEdited ?? false,
5081
+ historyCount: comment.historyCount ?? 0,
5082
+ canEdit: comment.canEdit ?? false,
5083
+ canDelete: comment.canDelete ?? false,
5084
+ attachments: (comment.attachments ?? []).map((item) => this.normalizeAttachment(item)),
5085
+ reactions: (comment.reactions ?? []).map((item) => this.normalizeReaction(item))
5086
+ };
5087
+ }
5088
+ normalizeAttachment(attachment) {
5089
+ return {
5090
+ attachmentId: attachment.attachmentId ?? 0,
5091
+ fileName: attachment.fileName ?? '',
5092
+ fileType: attachment.fileType ?? '',
5093
+ fileSize: attachment.fileSize ?? 0,
5094
+ uploadedAt: attachment.uploadedAt ?? new Date(0),
5095
+ storageFileId: attachment.storageFileId ?? '',
5096
+ downloadUrl: attachment.downloadUrl ?? ''
5097
+ };
5098
+ }
5099
+ normalizeReaction(reaction) {
5100
+ return {
5101
+ emojiCode: reaction.emojiCode ?? '',
5102
+ count: reaction.count ?? 0,
5103
+ reactedByCurrentUser: reaction.reactedByCurrentUser ?? false
5104
+ };
5105
+ }
5106
+ normalizeMentionUser(user) {
5107
+ return {
5108
+ userId: user.userId ?? 0,
5109
+ displayName: user.displayName ?? '',
5110
+ email: user.email ?? ''
5111
+ };
5112
+ }
5113
+ normalizeHistoryItem(item) {
5114
+ return {
5115
+ commentEditHistoryId: item.commentEditHistoryId ?? 0,
5116
+ oldContent: item.oldContent ?? '',
5117
+ newContent: item.newContent ?? '',
5118
+ editedByUserId: item.editedByUserId ?? 0,
5119
+ editedByDisplayName: item.editedByDisplayName ?? '',
5120
+ editedAt: item.editedAt ?? new Date(0)
5121
+ };
5122
+ }
5123
+ extractMentionQuery(value) {
5124
+ const match = value.match(/@([A-Za-z0-9._+\-@]*)$/);
5125
+ return match?.[1] ?? null;
5126
+ }
5127
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: DiscussionComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
5128
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.16", type: DiscussionComponent, isStandalone: true, selector: "discussion", inputs: { objectTypeId: "objectTypeId", objectId: "objectId" }, providers: [ConfirmationService, DiscussionApi], usesOnChanges: true, ngImport: i0, template: `
5129
+ <p-confirmDialog/>
5130
+
5131
+ <section class="flex flex-col gap-4">
5132
+
5133
+ <p-card class="block">
5134
+ <div class="flex flex-col gap-4">
5135
+ @if (!previewMode) {
5136
+ <textarea
5137
+ pTextarea
5138
+ class="min-h-28 w-full"
5139
+ [autoResize]="true"
5140
+ rows="5"
5141
+ [(ngModel)]="newComment"
5142
+ (ngModelChange)="onComposerInput()"
5143
+ [placeholder]="'discussionComponent.writeCommentPlaceholder' | translate"
5144
+ ></textarea>
5145
+ } @else {
5146
+ <div
5147
+ class="markdown-preview min-h-28 rounded-2xl border border-surface-200 bg-surface-50 px-4 py-3 leading-7 dark:border-surface-700 dark:bg-surface-900/40"
5148
+ [innerHTML]="renderMarkdown(newComment)"
5149
+ ></div>
5150
+ }
5151
+
5152
+ @if (mentionSuggestions.length > 0) {
5153
+ <p-panel class="block">
5154
+ <ng-template pTemplate="header">
5155
+ <div class="inline-flex items-center gap-2 text-sm font-medium">
5156
+ <i class="pi pi-at"></i>
5157
+ <span>{{ 'discussionComponent.mentionSuggestions' | translate }}</span>
5158
+ </div>
5159
+ </ng-template>
5160
+
5161
+ <div class="flex flex-col gap-3">
5162
+ @for (candidate of mentionSuggestions; track candidate.userId) {
5163
+ <button
5164
+ type="button"
5165
+ class="flex w-full items-center justify-between gap-4 rounded-xl border border-transparent px-3 py-3 text-left transition hover:border-primary-200 hover:bg-primary-50 dark:hover:border-primary-800 dark:hover:bg-primary-950/30"
5166
+ (click)="insertMention(candidate)"
5167
+ >
5168
+ <div class="min-w-0">
5169
+ <strong>{{ candidate.displayName }}</strong>
5170
+ <small class="mt-1 block text-surface-500">{{ candidate.email }}</small>
5171
+ </div>
5172
+ <i class="pi pi-arrow-up-left shrink-0 text-surface-400"></i>
5173
+ </button>
5174
+ }
5175
+ </div>
5176
+ </p-panel>
5177
+ }
5178
+
5179
+ @if (pendingFiles.length > 0) {
5180
+ <div class="flex flex-col gap-3">
5181
+ @for (file of pendingFiles; track file.name + file.size) {
5182
+ <div
5183
+ class="flex flex-col gap-3 rounded-2xl border border-surface-200 px-4 py-3 sm:flex-row sm:items-center sm:justify-between dark:border-surface-700">
5184
+ <div class="inline-flex items-center gap-2">
5185
+ <i class="pi pi-file"></i>
5186
+ <span class="break-all">{{ file.name }}</span>
5187
+ <p-tag [value]="formatBytes(file.size)" severity="contrast"/>
5188
+ </div>
5189
+ <p-button
5190
+ icon="pi pi-times"
5191
+ severity="danger"
5192
+ [rounded]="true"
5193
+ [text]="true"
5194
+ (onClick)="removePendingFile(file)"
5195
+ />
5196
+ </div>
5197
+ }
5198
+ </div>
5199
+ }
5200
+
5201
+ <div class="flex flex-col gap-2 sm:flex-row sm:justify-end">
5202
+ <p-button
5203
+ [label]="
5204
+ previewMode
5205
+ ? ('discussionComponent.edit' | translate)
5206
+ : ('discussionComponent.preview' | translate)
5207
+ "
5208
+ [icon]="previewMode ? 'pi pi-pencil' : 'pi pi-eye'"
5209
+ severity="secondary"
5210
+ [text]="true"
5211
+ (onClick)="previewMode = !previewMode"
5212
+ />
5213
+
5214
+ <label class="file-trigger">
5215
+ <p-button
5216
+ [label]="'discussionComponent.attachFiles' | translate"
5217
+ icon="pi pi-paperclip"
5218
+ severity="secondary"
5219
+ [text]="true"
5220
+ />
5221
+ <input type="file" multiple (change)="onFilesSelected($event)"/>
5222
+ </label>
5223
+ <p-button
5224
+ [label]="'discussionComponent.send' | translate"
5225
+ icon="pi pi-send"
5226
+ [loading]="submitting"
5227
+ [disabled]="submitting || !newComment.trim()"
5228
+ (onClick)="createComment()"
5229
+ />
5230
+ </div>
5231
+ </div>
5232
+ </p-card>
5233
+
5234
+ @if (loading) {
5235
+ <div
5236
+ class="flex min-h-20 flex-col items-center justify-center gap-3 rounded-2xl border border-surface-200 px-4 py-5 text-surface-500 dark:border-surface-700">
5237
+ <p-progressSpinner strokeWidth="4"/>
5238
+ <span>{{ 'discussionComponent.loadingComments' | translate }}</span>
5239
+ </div>
5240
+ } @else if (comments.length === 0) {
5241
+ <div
5242
+ class="flex min-h-20 items-center justify-center gap-3 rounded-2xl border border-surface-200 px-4 py-5 text-surface-500 dark:border-surface-700">
5243
+ <i class="pi pi-inbox"></i>
5244
+ <span>{{ 'discussionComponent.noCommentsYet' | translate }}</span>
5245
+ </div>
5246
+ } @else {
5247
+ <div class="flex flex-col gap-4">
5248
+ @for (comment of comments; track comment.commentId) {
5249
+ <p-card class="block">
5250
+ <ng-template pTemplate="content">
5251
+ <div class="grid gap-4 md:grid-cols-[3.2rem_minmax(0,1fr)]">
5252
+ <div>
5253
+ <p-avatar
5254
+ [label]="getInitialsFromString(comment.authorDisplayName)"
5255
+ shape="circle"
5256
+ />
5257
+ </div>
5258
+
5259
+ <div class="flex flex-col gap-2">
5260
+ <div class="flex flex-row gap-3 justify-between">
5261
+ <div class="flex flex-wrap items-center gap-2">
5262
+ <strong>{{ comment.authorDisplayName }}</strong>
5263
+ <span
5264
+ class="text-sm text-surface-500">{{ comment.createdAt | date: layoutService.dateTimeFormat() }}</span>
5265
+ </div>
5266
+
5267
+ <div class="flex flex-wrap items-center justify-end gap-2">
5268
+ <div class="flex flex-wrap items-center">
5269
+ @if (comment.isEdited) {
5270
+ <p-tag [value]="'discussionComponent.edited' | translate" icon="pi pi-pencil" severity="warn"/>
5271
+ }
5272
+ </div>
5273
+ @if (comment.canEdit) {
5274
+ <p-button
5275
+ icon="pi pi-pencil"
5276
+ severity="secondary"
5277
+ [rounded]="true"
5278
+ [text]="true"
5279
+ (onClick)="startEdit(comment)"
5280
+ />
5281
+ }
5282
+ @if (comment.historyCount > 0) {
5283
+ <p-button
5284
+ icon="pi pi-history"
5285
+ severity="secondary"
5286
+ [rounded]="true"
5287
+ [text]="true"
5288
+ (onClick)="toggleHistory(comment)"
5289
+ />
5290
+ }
5291
+ @if (comment.canDelete) {
5292
+ <p-button
5293
+ icon="pi pi-trash"
5294
+ severity="danger"
5295
+ [rounded]="true"
5296
+ [text]="true"
5297
+ (onClick)="deleteComment(comment)"
5298
+ />
5299
+ }
5300
+ </div>
5301
+ </div>
5302
+ @if (editingCommentId === comment.commentId) {
5303
+ <div class="flex flex-col gap-4">
5304
+ <textarea
5305
+ pTextarea
5306
+ class="min-h-24 w-full"
5307
+ [autoResize]="true"
5308
+ rows="4"
5309
+ [(ngModel)]="editContent"
5310
+ [placeholder]="'discussionComponent.editCommentPlaceholder' | translate"
5311
+ ></textarea>
5312
+ <div class="flex flex-col gap-2 sm:flex-row sm:justify-end">
5313
+ <div>
5314
+ <label class="file-trigger">
5315
+ <p-button
5316
+ [label]="'discussionComponent.addAttachment' | translate"
5317
+ icon="pi pi-paperclip"
5318
+ [text]="true"
5319
+ severity="secondary"
5320
+ />
5321
+ <input type="file" multiple (change)="onInlineFilesSelected(comment, $event)"/>
5322
+ </label>
5323
+ </div>
5324
+
5325
+ <p-button
5326
+ [label]="'discussionComponent.save' | translate"
5327
+ icon="pi pi-check"
5328
+ [disabled]="!editContent.trim()"
5329
+ (onClick)="saveEdit(comment)"
5330
+ />
5331
+ <p-button
5332
+ [label]="'discussionComponent.cancel' | translate"
5333
+ icon="pi pi-times"
5334
+ severity="secondary"
5335
+ [text]="true"
5336
+ (onClick)="cancelEdit()"
5337
+ />
5338
+ </div>
5339
+ </div>
5340
+ } @else {
5341
+ <div class="markdown-preview" [innerHTML]="renderMarkdown(comment.content)"></div>
5342
+ }
5343
+
5344
+ @if (comment.attachments.length > 0) {
5345
+ <div class="flex flex-col gap-3">
5346
+ <div class="flex flex-col gap-3">
5347
+ @for (attachment of comment.attachments; track attachment.attachmentId) {
5348
+ <div class="flex flex-col gap-3 sm:flex-row sm:items-center sm:justify-end">
5349
+ <div class="inline-flex items-center gap-2">
5350
+ <i class="pi pi-file"></i>
5351
+ <button
5352
+ type="button"
5353
+ class="break-all bg-transparent p-0 text-left font-semibold text-primary-600 transition hover:text-primary-500"
5354
+ (click)="downloadAttachment(attachment)"
5355
+ >
5356
+ {{ attachment.fileName }}
5357
+ </button>
5358
+ <p-tag [value]="formatBytes(attachment.fileSize)" severity="contrast"/>
5359
+ </div>
5360
+
5361
+ @if (comment.canEdit) {
5362
+ <p-button
5363
+ icon="pi pi-times"
5364
+ severity="danger"
5365
+ [rounded]="true"
5366
+ [text]="true"
5367
+ (onClick)="deleteAttachment(comment, attachment)"
5368
+ />
5369
+ }
5370
+ </div>
5371
+ }
5372
+ </div>
5373
+ </div>
5374
+ }
5375
+
5376
+ <div class="flex flex-wrap items-center gap-2">
5377
+ @for (reaction of getReactions(comment); track reaction.emojiCode) {
5378
+ <p-button
5379
+ [label]="reaction.emojiCode + ' ' + reaction.count"
5380
+ severity="secondary"
5381
+ [outlined]="false"
5382
+ (onClick)="toggleReaction(comment, reaction)"
5383
+ />
5384
+ }
5385
+
5386
+ @if (!hasUserReaction(comment)) {
5387
+ <p-button
5388
+ icon="pi pi-face-smile"
5389
+ severity="secondary"
5390
+ [rounded]="true"
5391
+ [text]="true"
5392
+ (onClick)="reactionPopover.toggle($event)"
5393
+ />
5394
+ <p-popover #reactionPopover>
5395
+ <div class="emoji-popover">
5396
+ @for (emoji of emojiPalette; track emoji) {
5397
+ <button
5398
+ type="button"
5399
+ class="emoji-option"
5400
+ (click)="reactWithEmoji(comment, emoji, reactionPopover)"
5401
+ >
5402
+ {{ emoji }}
5403
+ </button>
5404
+ }
5405
+ </div>
5406
+ </p-popover>
5407
+ }
5408
+ </div>
5409
+
5410
+ @if (historyByComment[comment.commentId]?.opened) {
5411
+ <p-panel class="block" [toggleable]="true" [collapsed]="false">
5412
+ <ng-template pTemplate="header">
5413
+ <div class="inline-flex items-center gap-2 text-sm font-medium">
5414
+ <i class="pi pi-history"></i>
5415
+ <span>{{ 'discussionComponent.editHistory' | translate }}</span>
5416
+ </div>
5417
+ </ng-template>
5418
+
5419
+ @if (historyByComment[comment.commentId]?.loading) {
5420
+ <div class="flex items-center gap-3 text-surface-500">
5421
+ <p-progressSpinner strokeWidth="4"/>
5422
+ <span>{{ 'discussionComponent.loadingHistory' | translate }}</span>
5423
+ </div>
5424
+ } @else {
5425
+ <div class="flex flex-col gap-4">
5426
+ @for (item of historyByComment[comment.commentId]?.items ?? []; track item.commentEditHistoryId) {
5427
+ <div class="rounded-2xl border border-surface-200 px-4 py-4 dark:border-surface-700">
5428
+ <div class="mb-3 inline-flex items-center gap-2 text-sm font-semibold">
5429
+ <i class="pi pi-clock"></i>
5430
+ <span>{{ item.editedByDisplayName }} · {{ item.editedAt | date: 'short' }}</span>
5431
+ </div>
5432
+ <div class="grid gap-4 lg:grid-cols-2">
5433
+ <div class="flex flex-col gap-2">
5434
+ <p-tag [value]="'discussionComponent.before' | translate" severity="secondary"/>
5435
+ <div
5436
+ class="history-markdown rounded-2xl bg-surface-50 px-4 py-3 leading-7 dark:bg-surface-900/40"
5437
+ [innerHTML]="renderMarkdown(item.oldContent)"
5438
+ ></div>
5439
+ </div>
5440
+ <div class="flex flex-col gap-2">
5441
+ <p-tag [value]="'discussionComponent.after' | translate" severity="success"/>
5442
+ <div
5443
+ class="history-markdown rounded-2xl bg-surface-50 px-4 py-3 leading-7 dark:bg-surface-900/40"
5444
+ [innerHTML]="renderMarkdown(item.newContent)"
5445
+ ></div>
5446
+ </div>
5447
+ </div>
5448
+ </div>
5449
+ }
5450
+ </div>
5451
+ }
5452
+ </p-panel>
5453
+ }
5454
+ </div>
5455
+ </div>
5456
+ </ng-template>
5457
+ </p-card>
5458
+ }
5459
+ </div>
5460
+ }
5461
+ </section>
5462
+ `, isInline: true, styles: [":host{display:block}.file-trigger{position:relative;display:inline-flex}.file-trigger input{position:absolute;inset:0;opacity:0;cursor:pointer}.markdown-preview,.history-markdown{word-break:break-word}.markdown-preview :is(h1,h2,h3),.history-markdown :is(h1,h2,h3){margin:0 0 .75rem;font-weight:600}.markdown-preview a,.history-markdown a{color:#2563eb;text-decoration:underline;text-underline-offset:.18em}.emoji-popover{display:flex;flex-wrap:wrap;gap:.5rem;max-width:16rem}.emoji-option{display:inline-flex;align-items:center;justify-content:center;width:2.5rem;height:2.5rem;font-size:1.25rem;cursor:pointer}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: AvatarModule }, { kind: "component", type: i2$2.Avatar, selector: "p-avatar", inputs: ["label", "icon", "image", "size", "shape", "styleClass", "ariaLabel", "ariaLabelledBy"], outputs: ["onImageError"] }, { kind: "directive", type: i2$6.PrimeTemplate, selector: "[pTemplate]", inputs: ["type", "pTemplate"] }, { kind: "ngmodule", type: ButtonModule }, { kind: "component", type: i1$2.Button, selector: "p-button", inputs: ["hostName", "type", "badge", "disabled", "raised", "rounded", "text", "plain", "outlined", "link", "tabindex", "size", "variant", "style", "styleClass", "badgeClass", "badgeSeverity", "ariaLabel", "autofocus", "iconPos", "icon", "label", "loading", "loadingIcon", "severity", "buttonProps", "fluid"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "ngmodule", type: CardModule }, { kind: "component", type: i5.Card, selector: "p-card", inputs: ["header", "subheader", "style", "styleClass"] }, { kind: "component", type: ConfirmDialog, selector: "p-confirmDialog, p-confirmdialog, p-confirm-dialog", inputs: ["header", "icon", "message", "style", "styleClass", "maskStyleClass", "acceptIcon", "acceptLabel", "closeAriaLabel", "acceptAriaLabel", "acceptVisible", "rejectIcon", "rejectLabel", "rejectAriaLabel", "rejectVisible", "acceptButtonStyleClass", "rejectButtonStyleClass", "closeOnEscape", "dismissableMask", "blockScroll", "rtl", "closable", "appendTo", "key", "autoZIndex", "baseZIndex", "transitionOptions", "focusTrap", "defaultFocus", "breakpoints", "modal", "visible", "position", "draggable"], outputs: ["onHide"] }, { kind: "ngmodule", type: DividerModule }, { kind: "ngmodule", type: PanelModule }, { kind: "component", type: i6.Panel, selector: "p-panel", inputs: ["id", "toggleable", "header", "collapsed", "styleClass", "iconPos", "showHeader", "toggler", "transitionOptions", "toggleButtonProps"], outputs: ["collapsedChange", "onBeforeToggle", "onAfterToggle"] }, { kind: "ngmodule", type: PopoverModule }, { kind: "component", type: i7.Popover, selector: "p-popover", inputs: ["ariaLabel", "ariaLabelledBy", "dismissable", "style", "styleClass", "appendTo", "autoZIndex", "ariaCloseLabel", "baseZIndex", "focusOnShow", "showTransitionOptions", "hideTransitionOptions"], outputs: ["onShow", "onHide"] }, { kind: "ngmodule", type: ProgressSpinnerModule }, { kind: "component", type: i8.ProgressSpinner, selector: "p-progressSpinner, p-progress-spinner, p-progressspinner", inputs: ["styleClass", "strokeWidth", "fill", "animationDuration", "ariaLabel"] }, { kind: "ngmodule", type: TagModule }, { kind: "component", type: i9.Tag, selector: "p-tag", inputs: ["styleClass", "severity", "value", "icon", "rounded"] }, { kind: "directive", type: Textarea, selector: "[pTextarea], [pInputTextarea]", inputs: ["autoResize", "pSize", "variant", "fluid", "invalid"], outputs: ["onResize"] }, { kind: "pipe", type: i2$1.DatePipe, name: "date" }, { kind: "pipe", type: TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
5463
+ }
5464
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: DiscussionComponent, decorators: [{
5465
+ type: Component,
5466
+ args: [{ selector: 'discussion', standalone: true, providers: [ConfirmationService, DiscussionApi], imports: [
5467
+ CommonModule,
5468
+ FormsModule,
5469
+ AvatarModule,
5470
+ ButtonModule,
5471
+ CardModule,
5472
+ ConfirmDialog,
5473
+ DividerModule,
5474
+ PanelModule,
5475
+ PopoverModule,
5476
+ ProgressSpinnerModule,
5477
+ TagModule,
5478
+ Textarea,
5479
+ DatePipe,
5480
+ TranslatePipe
5481
+ ], template: `
5482
+ <p-confirmDialog/>
5483
+
5484
+ <section class="flex flex-col gap-4">
5485
+
5486
+ <p-card class="block">
5487
+ <div class="flex flex-col gap-4">
5488
+ @if (!previewMode) {
5489
+ <textarea
5490
+ pTextarea
5491
+ class="min-h-28 w-full"
5492
+ [autoResize]="true"
5493
+ rows="5"
5494
+ [(ngModel)]="newComment"
5495
+ (ngModelChange)="onComposerInput()"
5496
+ [placeholder]="'discussionComponent.writeCommentPlaceholder' | translate"
5497
+ ></textarea>
5498
+ } @else {
5499
+ <div
5500
+ class="markdown-preview min-h-28 rounded-2xl border border-surface-200 bg-surface-50 px-4 py-3 leading-7 dark:border-surface-700 dark:bg-surface-900/40"
5501
+ [innerHTML]="renderMarkdown(newComment)"
5502
+ ></div>
5503
+ }
5504
+
5505
+ @if (mentionSuggestions.length > 0) {
5506
+ <p-panel class="block">
5507
+ <ng-template pTemplate="header">
5508
+ <div class="inline-flex items-center gap-2 text-sm font-medium">
5509
+ <i class="pi pi-at"></i>
5510
+ <span>{{ 'discussionComponent.mentionSuggestions' | translate }}</span>
5511
+ </div>
5512
+ </ng-template>
5513
+
5514
+ <div class="flex flex-col gap-3">
5515
+ @for (candidate of mentionSuggestions; track candidate.userId) {
5516
+ <button
5517
+ type="button"
5518
+ class="flex w-full items-center justify-between gap-4 rounded-xl border border-transparent px-3 py-3 text-left transition hover:border-primary-200 hover:bg-primary-50 dark:hover:border-primary-800 dark:hover:bg-primary-950/30"
5519
+ (click)="insertMention(candidate)"
5520
+ >
5521
+ <div class="min-w-0">
5522
+ <strong>{{ candidate.displayName }}</strong>
5523
+ <small class="mt-1 block text-surface-500">{{ candidate.email }}</small>
5524
+ </div>
5525
+ <i class="pi pi-arrow-up-left shrink-0 text-surface-400"></i>
5526
+ </button>
5527
+ }
5528
+ </div>
5529
+ </p-panel>
5530
+ }
5531
+
5532
+ @if (pendingFiles.length > 0) {
5533
+ <div class="flex flex-col gap-3">
5534
+ @for (file of pendingFiles; track file.name + file.size) {
5535
+ <div
5536
+ class="flex flex-col gap-3 rounded-2xl border border-surface-200 px-4 py-3 sm:flex-row sm:items-center sm:justify-between dark:border-surface-700">
5537
+ <div class="inline-flex items-center gap-2">
5538
+ <i class="pi pi-file"></i>
5539
+ <span class="break-all">{{ file.name }}</span>
5540
+ <p-tag [value]="formatBytes(file.size)" severity="contrast"/>
5541
+ </div>
5542
+ <p-button
5543
+ icon="pi pi-times"
5544
+ severity="danger"
5545
+ [rounded]="true"
5546
+ [text]="true"
5547
+ (onClick)="removePendingFile(file)"
5548
+ />
5549
+ </div>
5550
+ }
5551
+ </div>
5552
+ }
5553
+
5554
+ <div class="flex flex-col gap-2 sm:flex-row sm:justify-end">
5555
+ <p-button
5556
+ [label]="
5557
+ previewMode
5558
+ ? ('discussionComponent.edit' | translate)
5559
+ : ('discussionComponent.preview' | translate)
5560
+ "
5561
+ [icon]="previewMode ? 'pi pi-pencil' : 'pi pi-eye'"
5562
+ severity="secondary"
5563
+ [text]="true"
5564
+ (onClick)="previewMode = !previewMode"
5565
+ />
5566
+
5567
+ <label class="file-trigger">
5568
+ <p-button
5569
+ [label]="'discussionComponent.attachFiles' | translate"
5570
+ icon="pi pi-paperclip"
5571
+ severity="secondary"
5572
+ [text]="true"
5573
+ />
5574
+ <input type="file" multiple (change)="onFilesSelected($event)"/>
5575
+ </label>
5576
+ <p-button
5577
+ [label]="'discussionComponent.send' | translate"
5578
+ icon="pi pi-send"
5579
+ [loading]="submitting"
5580
+ [disabled]="submitting || !newComment.trim()"
5581
+ (onClick)="createComment()"
5582
+ />
5583
+ </div>
5584
+ </div>
5585
+ </p-card>
5586
+
5587
+ @if (loading) {
5588
+ <div
5589
+ class="flex min-h-20 flex-col items-center justify-center gap-3 rounded-2xl border border-surface-200 px-4 py-5 text-surface-500 dark:border-surface-700">
5590
+ <p-progressSpinner strokeWidth="4"/>
5591
+ <span>{{ 'discussionComponent.loadingComments' | translate }}</span>
5592
+ </div>
5593
+ } @else if (comments.length === 0) {
5594
+ <div
5595
+ class="flex min-h-20 items-center justify-center gap-3 rounded-2xl border border-surface-200 px-4 py-5 text-surface-500 dark:border-surface-700">
5596
+ <i class="pi pi-inbox"></i>
5597
+ <span>{{ 'discussionComponent.noCommentsYet' | translate }}</span>
5598
+ </div>
5599
+ } @else {
5600
+ <div class="flex flex-col gap-4">
5601
+ @for (comment of comments; track comment.commentId) {
5602
+ <p-card class="block">
5603
+ <ng-template pTemplate="content">
5604
+ <div class="grid gap-4 md:grid-cols-[3.2rem_minmax(0,1fr)]">
5605
+ <div>
5606
+ <p-avatar
5607
+ [label]="getInitialsFromString(comment.authorDisplayName)"
5608
+ shape="circle"
5609
+ />
5610
+ </div>
5611
+
5612
+ <div class="flex flex-col gap-2">
5613
+ <div class="flex flex-row gap-3 justify-between">
5614
+ <div class="flex flex-wrap items-center gap-2">
5615
+ <strong>{{ comment.authorDisplayName }}</strong>
5616
+ <span
5617
+ class="text-sm text-surface-500">{{ comment.createdAt | date: layoutService.dateTimeFormat() }}</span>
5618
+ </div>
5619
+
5620
+ <div class="flex flex-wrap items-center justify-end gap-2">
5621
+ <div class="flex flex-wrap items-center">
5622
+ @if (comment.isEdited) {
5623
+ <p-tag [value]="'discussionComponent.edited' | translate" icon="pi pi-pencil" severity="warn"/>
5624
+ }
5625
+ </div>
5626
+ @if (comment.canEdit) {
5627
+ <p-button
5628
+ icon="pi pi-pencil"
5629
+ severity="secondary"
5630
+ [rounded]="true"
5631
+ [text]="true"
5632
+ (onClick)="startEdit(comment)"
5633
+ />
5634
+ }
5635
+ @if (comment.historyCount > 0) {
5636
+ <p-button
5637
+ icon="pi pi-history"
5638
+ severity="secondary"
5639
+ [rounded]="true"
5640
+ [text]="true"
5641
+ (onClick)="toggleHistory(comment)"
5642
+ />
5643
+ }
5644
+ @if (comment.canDelete) {
5645
+ <p-button
5646
+ icon="pi pi-trash"
5647
+ severity="danger"
5648
+ [rounded]="true"
5649
+ [text]="true"
5650
+ (onClick)="deleteComment(comment)"
5651
+ />
5652
+ }
5653
+ </div>
5654
+ </div>
5655
+ @if (editingCommentId === comment.commentId) {
5656
+ <div class="flex flex-col gap-4">
5657
+ <textarea
5658
+ pTextarea
5659
+ class="min-h-24 w-full"
5660
+ [autoResize]="true"
5661
+ rows="4"
5662
+ [(ngModel)]="editContent"
5663
+ [placeholder]="'discussionComponent.editCommentPlaceholder' | translate"
5664
+ ></textarea>
5665
+ <div class="flex flex-col gap-2 sm:flex-row sm:justify-end">
5666
+ <div>
5667
+ <label class="file-trigger">
5668
+ <p-button
5669
+ [label]="'discussionComponent.addAttachment' | translate"
5670
+ icon="pi pi-paperclip"
5671
+ [text]="true"
5672
+ severity="secondary"
5673
+ />
5674
+ <input type="file" multiple (change)="onInlineFilesSelected(comment, $event)"/>
5675
+ </label>
5676
+ </div>
5677
+
5678
+ <p-button
5679
+ [label]="'discussionComponent.save' | translate"
5680
+ icon="pi pi-check"
5681
+ [disabled]="!editContent.trim()"
5682
+ (onClick)="saveEdit(comment)"
5683
+ />
5684
+ <p-button
5685
+ [label]="'discussionComponent.cancel' | translate"
5686
+ icon="pi pi-times"
5687
+ severity="secondary"
5688
+ [text]="true"
5689
+ (onClick)="cancelEdit()"
5690
+ />
5691
+ </div>
5692
+ </div>
5693
+ } @else {
5694
+ <div class="markdown-preview" [innerHTML]="renderMarkdown(comment.content)"></div>
5695
+ }
5696
+
5697
+ @if (comment.attachments.length > 0) {
5698
+ <div class="flex flex-col gap-3">
5699
+ <div class="flex flex-col gap-3">
5700
+ @for (attachment of comment.attachments; track attachment.attachmentId) {
5701
+ <div class="flex flex-col gap-3 sm:flex-row sm:items-center sm:justify-end">
5702
+ <div class="inline-flex items-center gap-2">
5703
+ <i class="pi pi-file"></i>
5704
+ <button
5705
+ type="button"
5706
+ class="break-all bg-transparent p-0 text-left font-semibold text-primary-600 transition hover:text-primary-500"
5707
+ (click)="downloadAttachment(attachment)"
5708
+ >
5709
+ {{ attachment.fileName }}
5710
+ </button>
5711
+ <p-tag [value]="formatBytes(attachment.fileSize)" severity="contrast"/>
5712
+ </div>
5713
+
5714
+ @if (comment.canEdit) {
5715
+ <p-button
5716
+ icon="pi pi-times"
5717
+ severity="danger"
5718
+ [rounded]="true"
5719
+ [text]="true"
5720
+ (onClick)="deleteAttachment(comment, attachment)"
5721
+ />
5722
+ }
5723
+ </div>
5724
+ }
5725
+ </div>
5726
+ </div>
5727
+ }
5728
+
5729
+ <div class="flex flex-wrap items-center gap-2">
5730
+ @for (reaction of getReactions(comment); track reaction.emojiCode) {
5731
+ <p-button
5732
+ [label]="reaction.emojiCode + ' ' + reaction.count"
5733
+ severity="secondary"
5734
+ [outlined]="false"
5735
+ (onClick)="toggleReaction(comment, reaction)"
5736
+ />
5737
+ }
5738
+
5739
+ @if (!hasUserReaction(comment)) {
5740
+ <p-button
5741
+ icon="pi pi-face-smile"
5742
+ severity="secondary"
5743
+ [rounded]="true"
5744
+ [text]="true"
5745
+ (onClick)="reactionPopover.toggle($event)"
5746
+ />
5747
+ <p-popover #reactionPopover>
5748
+ <div class="emoji-popover">
5749
+ @for (emoji of emojiPalette; track emoji) {
5750
+ <button
5751
+ type="button"
5752
+ class="emoji-option"
5753
+ (click)="reactWithEmoji(comment, emoji, reactionPopover)"
5754
+ >
5755
+ {{ emoji }}
5756
+ </button>
5757
+ }
5758
+ </div>
5759
+ </p-popover>
5760
+ }
5761
+ </div>
5762
+
5763
+ @if (historyByComment[comment.commentId]?.opened) {
5764
+ <p-panel class="block" [toggleable]="true" [collapsed]="false">
5765
+ <ng-template pTemplate="header">
5766
+ <div class="inline-flex items-center gap-2 text-sm font-medium">
5767
+ <i class="pi pi-history"></i>
5768
+ <span>{{ 'discussionComponent.editHistory' | translate }}</span>
5769
+ </div>
5770
+ </ng-template>
5771
+
5772
+ @if (historyByComment[comment.commentId]?.loading) {
5773
+ <div class="flex items-center gap-3 text-surface-500">
5774
+ <p-progressSpinner strokeWidth="4"/>
5775
+ <span>{{ 'discussionComponent.loadingHistory' | translate }}</span>
5776
+ </div>
5777
+ } @else {
5778
+ <div class="flex flex-col gap-4">
5779
+ @for (item of historyByComment[comment.commentId]?.items ?? []; track item.commentEditHistoryId) {
5780
+ <div class="rounded-2xl border border-surface-200 px-4 py-4 dark:border-surface-700">
5781
+ <div class="mb-3 inline-flex items-center gap-2 text-sm font-semibold">
5782
+ <i class="pi pi-clock"></i>
5783
+ <span>{{ item.editedByDisplayName }} · {{ item.editedAt | date: 'short' }}</span>
5784
+ </div>
5785
+ <div class="grid gap-4 lg:grid-cols-2">
5786
+ <div class="flex flex-col gap-2">
5787
+ <p-tag [value]="'discussionComponent.before' | translate" severity="secondary"/>
5788
+ <div
5789
+ class="history-markdown rounded-2xl bg-surface-50 px-4 py-3 leading-7 dark:bg-surface-900/40"
5790
+ [innerHTML]="renderMarkdown(item.oldContent)"
5791
+ ></div>
5792
+ </div>
5793
+ <div class="flex flex-col gap-2">
5794
+ <p-tag [value]="'discussionComponent.after' | translate" severity="success"/>
5795
+ <div
5796
+ class="history-markdown rounded-2xl bg-surface-50 px-4 py-3 leading-7 dark:bg-surface-900/40"
5797
+ [innerHTML]="renderMarkdown(item.newContent)"
5798
+ ></div>
5799
+ </div>
5800
+ </div>
5801
+ </div>
5802
+ }
5803
+ </div>
5804
+ }
5805
+ </p-panel>
5806
+ }
5807
+ </div>
5808
+ </div>
5809
+ </ng-template>
5810
+ </p-card>
5811
+ }
5812
+ </div>
5813
+ }
5814
+ </section>
5815
+ `, changeDetection: ChangeDetectionStrategy.OnPush, styles: [":host{display:block}.file-trigger{position:relative;display:inline-flex}.file-trigger input{position:absolute;inset:0;opacity:0;cursor:pointer}.markdown-preview,.history-markdown{word-break:break-word}.markdown-preview :is(h1,h2,h3),.history-markdown :is(h1,h2,h3){margin:0 0 .75rem;font-weight:600}.markdown-preview a,.history-markdown a{color:#2563eb;text-decoration:underline;text-underline-offset:.18em}.emoji-popover{display:flex;flex-wrap:wrap;gap:.5rem;max-width:16rem}.emoji-option{display:inline-flex;align-items:center;justify-content:center;width:2.5rem;height:2.5rem;font-size:1.25rem;cursor:pointer}\n"] }]
5816
+ }], propDecorators: { objectTypeId: [{
5817
+ type: Input,
5818
+ args: [{ required: true }]
5819
+ }], objectId: [{
5820
+ type: Input,
5821
+ args: [{ required: true }]
5822
+ }] } });
5823
+
4394
5824
  /**
4395
5825
  * A route guard that ensures the user is authenticated and has a valid access token.
4396
5826
  * If the access token is expired, it attempts to refresh the session.
@@ -4630,5 +6060,5 @@ const httpLoaderAuthFactory = (httpClient) => {
4630
6060
  * Generated bundle index. Do not edit.
4631
6061
  */
4632
6062
 
4633
- export { AppConfiguratorComponent, AppFloatingConfiguratorComponent, AppLayoutComponent, AppModulesComponent, AppTopbar, AuthGuardService, BaseDataService, BaseModuleComponent, ConfigComponent, ContentType, DbMigrationComponent, ErrorComponent, FooterComponent, HttpClient, KeycloakSecurityService, L10nService, LOGO_COMPONENT_TOKEN, LayoutService, LogoComponent, LogoService, MenuComponent, MenuService, MsgService, NotfoundComponent, NotificationService, ProfileComponent, SecurePipe, SecurityComponent, SecurityDataService, SecurityService, SecurityStorageService, SidebarComponent, TableFilterService, TopBarService, UnauthorizedComponent, UserService, httpLoaderAuthFactory, langIntercept, provideLogoComponent };
6063
+ export { AppConfiguratorComponent, AppFloatingConfiguratorComponent, AppLayoutComponent, AppModulesComponent, AppTopbar, AuthGuardService, BaseDataService, BaseModuleComponent, ConfigComponent, ContentType, DbMigrationComponent, DiscussionComponent, ErrorComponent, FooterComponent, HttpClient, KeycloakSecurityService, L10nService, LOGO_COMPONENT_TOKEN, LayoutService, LogoComponent, LogoService, MenuComponent, MenuService, MsgService, NotfoundComponent, NotificationService, ProfileComponent, SecurePipe, SecurityComponent, SecurityDataService, SecurityService, SecurityStorageService, SidebarComponent, TableFilterService, TopBarService, UnauthorizedComponent, UserService, httpLoaderAuthFactory, langIntercept, provideLogoComponent };
4634
6064
  //# sourceMappingURL=oip-common.mjs.map