@posiwise/admin-module 0.0.253 → 0.0.254

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.
@@ -9336,14 +9336,15 @@ i0.ɵɵngDeclareClassMetadata({
9336
9336
  ]
9337
9337
  });
9338
9338
  var FeatureFlagsListComponent = class FeatureFlagsListComponent extends AppBaseComponent {
9339
- constructor(injector, adminService, confirmDialog) {
9339
+ constructor(injector, adminService, confirmDialog, cdr) {
9340
9340
  super(injector);
9341
9341
  this.adminService = adminService;
9342
9342
  this.confirmDialog = confirmDialog;
9343
+ this.cdr = cdr;
9343
9344
  this.PAGE_SIZE = PAGE_SIZE;
9344
9345
  this.routers = ROUTERS;
9345
9346
  this.buttonBusy = false;
9346
- this.isLoaded = true;
9347
+ this.isLoaded = false;
9347
9348
  this.loading = true;
9348
9349
  this.searchText = "";
9349
9350
  this.featureFlags = [];
@@ -9366,12 +9367,19 @@ var FeatureFlagsListComponent = class FeatureFlagsListComponent extends AppBaseC
9366
9367
  loadFeatureFlags(paging) {
9367
9368
  this.isLoaded = false;
9368
9369
  this.loading = true;
9369
- this.adminService.getFeatureFlags(paging).subscribe({ next: (response) => {
9370
- this.featureFlags = response.feature_flags ?? [];
9371
- this.totalRecords = response.object_count ?? this.featureFlags.length;
9372
- } }).add(() => {
9373
- this.isLoaded = true;
9374
- this.loading = false;
9370
+ this.adminService.getFeatureFlags(paging).subscribe({
9371
+ next: (response) => {
9372
+ this.featureFlags = response.feature_flags ?? [];
9373
+ this.totalRecords = response.object_count ?? this.featureFlags.length;
9374
+ this.isLoaded = true;
9375
+ this.loading = false;
9376
+ this.cdr.markForCheck();
9377
+ },
9378
+ error: () => {
9379
+ this.isLoaded = true;
9380
+ this.loading = false;
9381
+ this.cdr.markForCheck();
9382
+ }
9375
9383
  });
9376
9384
  }
9377
9385
  navigateToEdit(item) {
@@ -9415,7 +9423,8 @@ var FeatureFlagsListComponent = class FeatureFlagsListComponent extends AppBaseC
9415
9423
  deps: [
9416
9424
  { token: i0.Injector },
9417
9425
  { token: i1$1.AdminService },
9418
- { token: i6$2.ConfirmDialogService }
9426
+ { token: i6$2.ConfirmDialogService },
9427
+ { token: i0.ChangeDetectorRef }
9419
9428
  ],
9420
9429
  target: i0.ɵɵFactoryTarget.Component
9421
9430
  });
@@ -9429,7 +9438,7 @@ var FeatureFlagsListComponent = class FeatureFlagsListComponent extends AppBaseC
9429
9438
  selector: "pw-feature-flags-list",
9430
9439
  usesInheritance: true,
9431
9440
  ngImport: i0,
9432
- template: "<div class=\"row\" [class.custom-disable-wrapper]=\"buttonBusy\">\n <div class=\"col-12 d-flex flex-wrap justify-content-between align-items-baseline\">\n <h2 class=\"card-title p-0\">Feature Flags</h2>\n <a [routerLink]=\"[routers.featureFlagsDetails + 'add']\" class=\"btn btn-sm btn-outline-primary\">\n <i class=\"fa fa-plus-circle\" aria-hidden=\"true\"></i> {{ 'Label.AddNew' | transloco }} Feature Flag\n </a>\n </div>\n <div class=\"col-12 mb-3\">\n <p>Manage feature flags for controlled rollout, testing, and admin-driven enablement.</p>\n </div>\n</div>\n\n@if (!isLoaded) {\n<div class=\"w-100 text-center mt-3\">\n <p-progress-spinner strokeWidth=\"2\"></p-progress-spinner>\n</div>\n}\n<div class=\"row primeng-datatable-container actions-collapsed mt-0\" [class.d-none]=\"!isLoaded\" [class.hideTable]=\"totalRecords === 0 && isLoaded\" [class.custom-disable-wrapper]=\"buttonBusy\">\n <div class=\"col-12 px-0\">\n <p-table\n [value]=\"featureFlags\"\n [paginator]=\"totalRecords !== 0\"\n [lazy]=\"true\"\n [loading]=\"loading\"\n [rows]=\"PAGE_SIZE\"\n [totalRecords]=\"totalRecords\"\n [filterDelay]=\"300\"\n (onLazyLoad)=\"onLazyLoad($event)\">\n <ng-template #caption>\n <div class=\"text-end\">\n <p-iconfield iconPosition=\"left\">\n <p-inputicon><i class=\"fa fa-search\" aria-hidden=\"true\"></i></p-inputicon>\n <input type=\"text\"\n [(ngModel)]=\"searchText\"\n pInputText\n placeholder=\"Search feature flags...\"\n aria-label=\"Search feature flags...\" />\n </p-iconfield>\n </div>\n </ng-template>\n <ng-template #header>\n <tr>\n <th scope=\"col\">Key</th>\n <th scope=\"col\">Name</th>\n <th scope=\"col\">Status</th>\n <th scope=\"col\">Type</th>\n <th scope=\"col\">Owner</th>\n <th scope=\"col\">Expires</th>\n <th scope=\"col\" class=\"actions-list-two\">{{ 'Label.Actions' | transloco }}</th>\n </tr>\n </ng-template>\n <ng-template #body let-flag>\n <tr>\n <td>{{ flag.key }}</td>\n <td>{{ flag.name }}</td>\n <td><span class=\"badge\" [ngClass]=\"flag.status === 'active' ? 'bg-success' : 'bg-blue-grey'\">{{ flag.status || 'draft' }}</span></td>\n <td>{{ flag.flag_type || '-' }}</td>\n <td>{{ flag.owner || '-' }}</td>\n <td>{{ flag.expires_at ? (flag.expires_at | date:'dd-MMM-yyyy HH:mm') : '-' }}</td>\n <td data-head=\"Action\">\n <ul class=\"list-unstyled list-inline list-action\">\n <li pTooltip=\"Edit\" tooltipPosition=\"top\" appendTo=\"body\" class=\"me-2 me-sm-2\">\n <button\n type=\"button\"\n class=\"btn p-0 border-0 bg-transparent\"\n aria-label=\"Edit feature flag\"\n (click)=\"navigateToEdit(flag)\">\n <i class=\"fa fa-edit edit-icon\"></i>\n </button>\n </li>\n <li pTooltip=\"Rules\" tooltipPosition=\"top\" appendTo=\"body\" class=\"me-2 me-sm-2\">\n <button\n type=\"button\"\n class=\"btn p-0 border-0 bg-transparent\"\n aria-label=\"Manage feature flag rules\"\n (click)=\"navigateToRules(flag)\">\n <i class=\"fa fa-list-ul edit-icon\"></i>\n </button>\n </li>\n <li pTooltip=\"Delete\" tooltipPosition=\"top\" appendTo=\"body\" class=\"me-2 me-sm-2\">\n <button\n type=\"button\"\n class=\"btn p-0 border-0 bg-transparent\"\n aria-label=\"Delete feature flag\"\n (click)=\"onDelete(flag)\">\n <i class=\"fa fa-trash delete-icon\"></i>\n </button>\n </li>\n </ul>\n </td>\n </tr>\n </ng-template>\n </p-table>\n </div>\n</div>\n@if (totalRecords === 0 && isLoaded) {\n<div class=\"col-12 text-center\">\n <pw-no-data [withImage]=\"true\" [message]=\"'No feature flags found'\"></pw-no-data>\n</div>\n}",
9441
+ template: "<div class=\"row\" [class.custom-disable-wrapper]=\"buttonBusy\">\n <div class=\"col-12 d-flex flex-wrap justify-content-between align-items-baseline\">\n <h2 class=\"card-title p-0\">Feature Flags</h2>\n <a [routerLink]=\"[routers.featureFlagsDetails + 'add']\" class=\"btn btn-sm btn-outline-primary\">\n <i class=\"fa fa-plus-circle\" aria-hidden=\"true\"></i> {{ 'Label.AddNew' | transloco }} Feature Flag\n </a>\n </div>\n <div class=\"col-12 mb-3\">\n <p>Manage feature flags for controlled rollout, testing, and admin-driven enablement.</p>\n </div>\n</div>\n\n@if (!isLoaded) {\n<div class=\"w-100 text-center mt-3\">\n <p-progress-spinner strokeWidth=\"2\"></p-progress-spinner>\n</div>\n}\n<div class=\"row primeng-datatable-container actions-collapsed mt-0\" [class.d-none]=\"!isLoaded\" [class.hideTable]=\"totalRecords === 0 && isLoaded\" [class.custom-disable-wrapper]=\"buttonBusy\">\n <div class=\"col-12 px-0\">\n <p-table\n stateKey=\"pw-table.admin-feature-flags-list\"\n stateStorage=\"session\"\n [resizableColumns]=\"true\"\n columnResizeMode=\"expand\"\n [value]=\"featureFlags\"\n [paginator]=\"totalRecords !== 0\"\n [lazy]=\"true\"\n [loading]=\"loading\"\n [rows]=\"PAGE_SIZE\"\n [totalRecords]=\"totalRecords\"\n [filterDelay]=\"300\"\n (onLazyLoad)=\"onLazyLoad($event)\">\n <ng-template #caption>\n <div class=\"text-end\">\n <p-iconfield iconPosition=\"left\">\n <p-inputicon><i class=\"fa fa-search\" aria-hidden=\"true\"></i></p-inputicon>\n <input type=\"text\"\n [(ngModel)]=\"searchText\"\n pInputText\n placeholder=\"Search feature flags...\"\n aria-label=\"Search feature flags...\" />\n </p-iconfield>\n </div>\n </ng-template>\n <ng-template #header>\n <tr>\n <th pResizableColumn scope=\"col\">Key</th>\n <th pResizableColumn scope=\"col\">Name</th>\n <th pResizableColumn scope=\"col\">Status</th>\n <th pResizableColumn scope=\"col\">Type</th>\n <th pResizableColumn scope=\"col\">Owner</th>\n <th pResizableColumn scope=\"col\">Expires</th>\n <th scope=\"col\" class=\"actions-list-two\">{{ 'Label.Actions' | transloco }}</th>\n </tr>\n </ng-template>\n <ng-template #body let-flag>\n <tr>\n <td>{{ flag.key }}</td>\n <td>{{ flag.name }}</td>\n <td><span class=\"badge\" [ngClass]=\"flag.status === 'active' ? 'bg-success' : 'bg-blue-grey'\">{{ flag.status || 'draft' }}</span></td>\n <td>{{ flag.flag_type || '-' }}</td>\n <td>{{ flag.owner || '-' }}</td>\n <td>{{ flag.expires_at ? (flag.expires_at | date:'dd-MMM-yyyy HH:mm') : '-' }}</td>\n <td data-head=\"Action\">\n <ul class=\"list-unstyled list-inline list-action\">\n <li pTooltip=\"Edit\" tooltipPosition=\"top\" appendTo=\"body\" class=\"me-2 me-sm-2\">\n <button\n type=\"button\"\n class=\"btn p-0 border-0 bg-transparent\"\n aria-label=\"Edit feature flag\"\n (click)=\"navigateToEdit(flag)\">\n <i class=\"fa fa-edit edit-icon\"></i>\n </button>\n </li>\n <li pTooltip=\"Rules\" tooltipPosition=\"top\" appendTo=\"body\" class=\"me-2 me-sm-2\">\n <button\n type=\"button\"\n class=\"btn p-0 border-0 bg-transparent\"\n aria-label=\"Manage feature flag rules\"\n (click)=\"navigateToRules(flag)\">\n <i class=\"fa fa-list-ul edit-icon\"></i>\n </button>\n </li>\n <li pTooltip=\"Delete\" tooltipPosition=\"top\" appendTo=\"body\" class=\"me-2 me-sm-2\">\n <button\n type=\"button\"\n class=\"btn p-0 border-0 bg-transparent\"\n aria-label=\"Delete feature flag\"\n (click)=\"onDelete(flag)\">\n <i class=\"fa fa-trash delete-icon\"></i>\n </button>\n </li>\n </ul>\n </td>\n </tr>\n </ng-template>\n </p-table>\n </div>\n</div>\n@if (totalRecords === 0 && isLoaded) {\n<div class=\"col-12 text-center\">\n <pw-no-data [withImage]=\"true\" [message]=\"'No feature flags found'\"></pw-no-data>\n</div>\n}",
9433
9442
  dependencies: [
9434
9443
  {
9435
9444
  kind: "component",
@@ -9544,6 +9553,12 @@ var FeatureFlagsListComponent = class FeatureFlagsListComponent extends AppBaseC
9544
9553
  "onStateRestore"
9545
9554
  ]
9546
9555
  },
9556
+ {
9557
+ kind: "directive",
9558
+ type: i2$3.ResizableColumn,
9559
+ selector: "[pResizableColumn]",
9560
+ inputs: ["pResizableColumnDisabled"]
9561
+ },
9547
9562
  {
9548
9563
  kind: "directive",
9549
9564
  type: i3$3.Tooltip,
@@ -9694,13 +9709,14 @@ i0.ɵɵngDeclareClassMetadata({
9694
9709
  args: [{
9695
9710
  selector: "pw-feature-flags-list",
9696
9711
  standalone: false,
9697
- template: "<div class=\"row\" [class.custom-disable-wrapper]=\"buttonBusy\">\n <div class=\"col-12 d-flex flex-wrap justify-content-between align-items-baseline\">\n <h2 class=\"card-title p-0\">Feature Flags</h2>\n <a [routerLink]=\"[routers.featureFlagsDetails + 'add']\" class=\"btn btn-sm btn-outline-primary\">\n <i class=\"fa fa-plus-circle\" aria-hidden=\"true\"></i> {{ 'Label.AddNew' | transloco }} Feature Flag\n </a>\n </div>\n <div class=\"col-12 mb-3\">\n <p>Manage feature flags for controlled rollout, testing, and admin-driven enablement.</p>\n </div>\n</div>\n\n@if (!isLoaded) {\n<div class=\"w-100 text-center mt-3\">\n <p-progress-spinner strokeWidth=\"2\"></p-progress-spinner>\n</div>\n}\n<div class=\"row primeng-datatable-container actions-collapsed mt-0\" [class.d-none]=\"!isLoaded\" [class.hideTable]=\"totalRecords === 0 && isLoaded\" [class.custom-disable-wrapper]=\"buttonBusy\">\n <div class=\"col-12 px-0\">\n <p-table\n [value]=\"featureFlags\"\n [paginator]=\"totalRecords !== 0\"\n [lazy]=\"true\"\n [loading]=\"loading\"\n [rows]=\"PAGE_SIZE\"\n [totalRecords]=\"totalRecords\"\n [filterDelay]=\"300\"\n (onLazyLoad)=\"onLazyLoad($event)\">\n <ng-template #caption>\n <div class=\"text-end\">\n <p-iconfield iconPosition=\"left\">\n <p-inputicon><i class=\"fa fa-search\" aria-hidden=\"true\"></i></p-inputicon>\n <input type=\"text\"\n [(ngModel)]=\"searchText\"\n pInputText\n placeholder=\"Search feature flags...\"\n aria-label=\"Search feature flags...\" />\n </p-iconfield>\n </div>\n </ng-template>\n <ng-template #header>\n <tr>\n <th scope=\"col\">Key</th>\n <th scope=\"col\">Name</th>\n <th scope=\"col\">Status</th>\n <th scope=\"col\">Type</th>\n <th scope=\"col\">Owner</th>\n <th scope=\"col\">Expires</th>\n <th scope=\"col\" class=\"actions-list-two\">{{ 'Label.Actions' | transloco }}</th>\n </tr>\n </ng-template>\n <ng-template #body let-flag>\n <tr>\n <td>{{ flag.key }}</td>\n <td>{{ flag.name }}</td>\n <td><span class=\"badge\" [ngClass]=\"flag.status === 'active' ? 'bg-success' : 'bg-blue-grey'\">{{ flag.status || 'draft' }}</span></td>\n <td>{{ flag.flag_type || '-' }}</td>\n <td>{{ flag.owner || '-' }}</td>\n <td>{{ flag.expires_at ? (flag.expires_at | date:'dd-MMM-yyyy HH:mm') : '-' }}</td>\n <td data-head=\"Action\">\n <ul class=\"list-unstyled list-inline list-action\">\n <li pTooltip=\"Edit\" tooltipPosition=\"top\" appendTo=\"body\" class=\"me-2 me-sm-2\">\n <button\n type=\"button\"\n class=\"btn p-0 border-0 bg-transparent\"\n aria-label=\"Edit feature flag\"\n (click)=\"navigateToEdit(flag)\">\n <i class=\"fa fa-edit edit-icon\"></i>\n </button>\n </li>\n <li pTooltip=\"Rules\" tooltipPosition=\"top\" appendTo=\"body\" class=\"me-2 me-sm-2\">\n <button\n type=\"button\"\n class=\"btn p-0 border-0 bg-transparent\"\n aria-label=\"Manage feature flag rules\"\n (click)=\"navigateToRules(flag)\">\n <i class=\"fa fa-list-ul edit-icon\"></i>\n </button>\n </li>\n <li pTooltip=\"Delete\" tooltipPosition=\"top\" appendTo=\"body\" class=\"me-2 me-sm-2\">\n <button\n type=\"button\"\n class=\"btn p-0 border-0 bg-transparent\"\n aria-label=\"Delete feature flag\"\n (click)=\"onDelete(flag)\">\n <i class=\"fa fa-trash delete-icon\"></i>\n </button>\n </li>\n </ul>\n </td>\n </tr>\n </ng-template>\n </p-table>\n </div>\n</div>\n@if (totalRecords === 0 && isLoaded) {\n<div class=\"col-12 text-center\">\n <pw-no-data [withImage]=\"true\" [message]=\"'No feature flags found'\"></pw-no-data>\n</div>\n}"
9712
+ template: "<div class=\"row\" [class.custom-disable-wrapper]=\"buttonBusy\">\n <div class=\"col-12 d-flex flex-wrap justify-content-between align-items-baseline\">\n <h2 class=\"card-title p-0\">Feature Flags</h2>\n <a [routerLink]=\"[routers.featureFlagsDetails + 'add']\" class=\"btn btn-sm btn-outline-primary\">\n <i class=\"fa fa-plus-circle\" aria-hidden=\"true\"></i> {{ 'Label.AddNew' | transloco }} Feature Flag\n </a>\n </div>\n <div class=\"col-12 mb-3\">\n <p>Manage feature flags for controlled rollout, testing, and admin-driven enablement.</p>\n </div>\n</div>\n\n@if (!isLoaded) {\n<div class=\"w-100 text-center mt-3\">\n <p-progress-spinner strokeWidth=\"2\"></p-progress-spinner>\n</div>\n}\n<div class=\"row primeng-datatable-container actions-collapsed mt-0\" [class.d-none]=\"!isLoaded\" [class.hideTable]=\"totalRecords === 0 && isLoaded\" [class.custom-disable-wrapper]=\"buttonBusy\">\n <div class=\"col-12 px-0\">\n <p-table\n stateKey=\"pw-table.admin-feature-flags-list\"\n stateStorage=\"session\"\n [resizableColumns]=\"true\"\n columnResizeMode=\"expand\"\n [value]=\"featureFlags\"\n [paginator]=\"totalRecords !== 0\"\n [lazy]=\"true\"\n [loading]=\"loading\"\n [rows]=\"PAGE_SIZE\"\n [totalRecords]=\"totalRecords\"\n [filterDelay]=\"300\"\n (onLazyLoad)=\"onLazyLoad($event)\">\n <ng-template #caption>\n <div class=\"text-end\">\n <p-iconfield iconPosition=\"left\">\n <p-inputicon><i class=\"fa fa-search\" aria-hidden=\"true\"></i></p-inputicon>\n <input type=\"text\"\n [(ngModel)]=\"searchText\"\n pInputText\n placeholder=\"Search feature flags...\"\n aria-label=\"Search feature flags...\" />\n </p-iconfield>\n </div>\n </ng-template>\n <ng-template #header>\n <tr>\n <th pResizableColumn scope=\"col\">Key</th>\n <th pResizableColumn scope=\"col\">Name</th>\n <th pResizableColumn scope=\"col\">Status</th>\n <th pResizableColumn scope=\"col\">Type</th>\n <th pResizableColumn scope=\"col\">Owner</th>\n <th pResizableColumn scope=\"col\">Expires</th>\n <th scope=\"col\" class=\"actions-list-two\">{{ 'Label.Actions' | transloco }}</th>\n </tr>\n </ng-template>\n <ng-template #body let-flag>\n <tr>\n <td>{{ flag.key }}</td>\n <td>{{ flag.name }}</td>\n <td><span class=\"badge\" [ngClass]=\"flag.status === 'active' ? 'bg-success' : 'bg-blue-grey'\">{{ flag.status || 'draft' }}</span></td>\n <td>{{ flag.flag_type || '-' }}</td>\n <td>{{ flag.owner || '-' }}</td>\n <td>{{ flag.expires_at ? (flag.expires_at | date:'dd-MMM-yyyy HH:mm') : '-' }}</td>\n <td data-head=\"Action\">\n <ul class=\"list-unstyled list-inline list-action\">\n <li pTooltip=\"Edit\" tooltipPosition=\"top\" appendTo=\"body\" class=\"me-2 me-sm-2\">\n <button\n type=\"button\"\n class=\"btn p-0 border-0 bg-transparent\"\n aria-label=\"Edit feature flag\"\n (click)=\"navigateToEdit(flag)\">\n <i class=\"fa fa-edit edit-icon\"></i>\n </button>\n </li>\n <li pTooltip=\"Rules\" tooltipPosition=\"top\" appendTo=\"body\" class=\"me-2 me-sm-2\">\n <button\n type=\"button\"\n class=\"btn p-0 border-0 bg-transparent\"\n aria-label=\"Manage feature flag rules\"\n (click)=\"navigateToRules(flag)\">\n <i class=\"fa fa-list-ul edit-icon\"></i>\n </button>\n </li>\n <li pTooltip=\"Delete\" tooltipPosition=\"top\" appendTo=\"body\" class=\"me-2 me-sm-2\">\n <button\n type=\"button\"\n class=\"btn p-0 border-0 bg-transparent\"\n aria-label=\"Delete feature flag\"\n (click)=\"onDelete(flag)\">\n <i class=\"fa fa-trash delete-icon\"></i>\n </button>\n </li>\n </ul>\n </td>\n </tr>\n </ng-template>\n </p-table>\n </div>\n</div>\n@if (totalRecords === 0 && isLoaded) {\n<div class=\"col-12 text-center\">\n <pw-no-data [withImage]=\"true\" [message]=\"'No feature flags found'\"></pw-no-data>\n</div>\n}"
9698
9713
  }]
9699
9714
  }],
9700
9715
  ctorParameters: () => [
9701
9716
  { type: i0.Injector },
9702
9717
  { type: i1$1.AdminService },
9703
- { type: i6$2.ConfirmDialogService }
9718
+ { type: i6$2.ConfirmDialogService },
9719
+ { type: i0.ChangeDetectorRef }
9704
9720
  ]
9705
9721
  });
9706
9722
  var FeatureFlagsTabsComponent = class FeatureFlagsTabsComponent {
@@ -11046,7 +11062,7 @@ var IncidentListComponent = class IncidentListComponent extends AppBaseComponent
11046
11062
  selector: "pw-admin-incident-list",
11047
11063
  usesInheritance: true,
11048
11064
  ngImport: i0,
11049
- template: "<div class=\"row\">\n <div *rbacAllow=\"'Pages.Admin.Incident.Create'\"\n class=\"col-12 d-flex flex-wrap justify-content-between align-items-baseline\">\n <h2 class=\"card-title p-0\">Incidents</h2>\n <a [routerLink]=\"[routers.incidentDetails + 'add']\"\n (click)=\"showList = !showList\"\n (keydown.enter)=\"showList = !showList\"\n class=\"btn btn-sm btn-outline-primary\"\n aria-expanded=\"false\">\n <i class=\"fa fa-plus-circle\"\n aria-hidden=\"true\"></i>\n {{ 'Label.AddNew' | transloco }} Incident\n </a>\n </div>\n <div class=\"col-12 mb-3\">\n <p>The <strong>Incidents</strong> module lets you create and manage incident statuses. These incidents are publicly\n visible at the <strong>/status</strong> endpoint.</p>\n </div>\n</div>\n@if (!isLoaded) {\n <div class=\"w-100 text-center mt-3\">\n <p-progress-spinner strokeWidth=\"2\"></p-progress-spinner>\n </div>\n}\n@if (showList) {\n<div class=\"row faqlist primeng-datatable-container actions-collapsed mt-0\" [class.hideTable]=\"totalRecordsUnFiltered === 0\">\n <div class=\"col-12 px-0\">\n <p-table #tt\n [paginator]=\"totalRecords !== 0\"\n [rows]=\"PAGE_SIZE\"\n [totalRecords]=\"totalRecords\"\n [loading]=\"loading\"\n [lazy]=\"true\"\n [filterDelay]=\"1000\"\n [customSort]=\"true\"\n [value]=\"openIncidents\"\n (onLazyLoad)=\"onLazyLoad($event)\">\n <ng-template #caption>\n <div class=\"search-filter justify-content-end\">\n <div class=\"text-end\">\n <label for=\"incidents-list-search\" class=\"visually-hidden\">Search Incident</label>\n <p-iconfield iconPosition=\"left\">\n <p-inputicon><i class=\"fa fa-search\" aria-hidden=\"true\"></i></p-inputicon>\n <input id=\"incidents-list-search\"\n name=\"incidents-list-search\"\n [(ngModel)]=\"searchText\"\n (input)=\"tt.filterGlobal($event.target.value, 'contains')\"\n type=\"text\"\n pInputText\n placeholder=\"Search incidents...\"\n data-cy=\"incident-search\"\n aria-label=\"Search incidents...\" />\n </p-iconfield>\n </div>\n </div>\n </ng-template>\n <ng-template #header>\n <tr>\n <th scope=\"true\">\n {{ 'Admin.Incident.Description' | transloco }}\n </th>\n <th scope=\"true\">\n {{ 'Admin.Incident.ServiceImpacted' | transloco }}\n </th>\n <th scope=\"true\"\n pSortableColumn=\"started_at\">\n {{ 'Admin.Incident.StartedAt' | transloco }}\n <p-sort-icon field=\"started_at\"></p-sort-icon>\n </th>\n <th scope=\"true\"\n pSortableColumn=\"resolved_at\">\n {{ 'Admin.Incident.ResolvedAt' | transloco }}\n <p-sort-icon field=\"resolved_at\"></p-sort-icon>\n </th>\n <th scope=\"true\"\n pSortableColumn=\"last_check_at\">\n {{ 'Admin.Incident.LastCheckedAt' | transloco }}\n <p-sort-icon field=\"last_check_at\"></p-sort-icon>\n </th>\n <th scope=\"true\">\n {{ 'Admin.Incident.Duration' | transloco }}\n </th>\n <th scope=\"true\"\n class=\"actions-list-two\">\n {{ 'Label.Actions' | transloco }}\n </th>\n </tr>\n </ng-template>\n <ng-template #body\n let-incident>\n <tr>\n <td data-head=\"description\"\n class=\"description\">\n {{(incident?.description | removeHtml: 'quill')|textTruncate: 200}}\n </td>\n <td data-head=\"serviceImpacted\">\n {{ incident?.service_impacted ? incident?.service_impacted :\n incident?.url_impacted }}\n </td>\n <td data-head=\"startedAt\">\n <span class=\"text-nowrap\">\n {{ incident?.started_at | date: 'dd-MMM-yyyy, h:mm a' }}\n </span>\n </td>\n <td data-head=\"resolvedAt\">\n <span class=\"text-nowrap\">\n {{ incident?.resolved_at | date: 'dd-MMM-yyyy, h:mm a' }}\n </span>\n </td>\n <td data-head=\"lastCheckedAt\">\n <span class=\"text-nowrap\">\n {{ incident?.last_check_at | date: 'dd-MMM-yyyy, h:mm a' }}\n </span>\n </td>\n <td data-head=\"Duration\">\n <!-- {{ calculateDuration(incident?.resolved_at ? incident?.resolved_at :\n incident?.last_check_at, incident?.started_at) }} -->\n {{ calculateDuration(incident?.resolved_at,\n incident?.started_at) }}\n </td>\n <td data-head=\"Action\">\n <ul class=\"list-unstyled list-inline list-action\">\n <li pTooltip=\"Edit\" tooltipPosition=\"top\" appendTo=\"body\"\n class=\"me-2 me-sm-2\">\n <i (click)=\"navigateToEdit(incident)\"\n (keydown.enter)=\"navigateToEdit(incident)\"\n class=\"fa fa-edit edit-icon\"\n aria-hidden=\"true\"></i>\n </li>\n <li pTooltip=\"Delete\" tooltipPosition=\"top\" appendTo=\"body\"\n class=\"me-2 me-sm-2\">\n <i\n (keydown.enter)=\"onDelete(incident)\"\n (click)=\"onDelete(incident)\"\n class=\"fa fa-trash delete-icon\"\n aria-hidden=\"true\"></i>\n </li>\n </ul>\n </td>\n </tr>\n </ng-template>\n </p-table>\n @if (openIncidents.length === 0 && totalRecordsUnFiltered !== 0) {\n <div>\n <pw-no-data [withImage]=\"true\" [message]=\"'Search.NoDataMessage' | transloco\"\n [description]=\"'Search.NoDataDescription' | transloco\">\n </pw-no-data>\n </div>\n }\n @if (openIncidents.length !== 0) {\n <pw-records-summary [showing]=\"tt?.value?.length ?? 0\" [total]=\"openIncidents.length\" />\n }\n </div>\n</div>\n}\n@if (totalRecordsUnFiltered === 0 && isLoaded) {\n<pw-no-data [withImage]=\"true\"\n [message]=\"'Admin.Incident.NoDataMessage' | transloco\">\n</pw-no-data>\n}\n",
11065
+ template: "<div class=\"row\">\n <div *rbacAllow=\"'Pages.Admin.Incident.Create'\"\n class=\"col-12 d-flex flex-wrap justify-content-between align-items-baseline\">\n <h2 class=\"card-title p-0\">Incidents</h2>\n <a [routerLink]=\"[routers.incidentDetails + 'add']\"\n (click)=\"showList = !showList\"\n (keydown.enter)=\"showList = !showList\"\n class=\"btn btn-sm btn-outline-primary\"\n aria-expanded=\"false\">\n <i class=\"fa fa-plus-circle\"\n aria-hidden=\"true\"></i>\n {{ 'Label.AddNew' | transloco }} Incident\n </a>\n </div>\n <div class=\"col-12 mb-3\">\n <p>The <strong>Incidents</strong> module lets you create and manage incident statuses. These incidents are publicly\n visible at the <strong>/status</strong> endpoint.</p>\n </div>\n</div>\n@if (!isLoaded) {\n <div class=\"w-100 text-center mt-3\">\n <p-progress-spinner strokeWidth=\"2\"></p-progress-spinner>\n </div>\n}\n@if (showList) {\n<div class=\"row faqlist primeng-datatable-container actions-collapsed mt-0\" [class.hideTable]=\"totalRecordsUnFiltered === 0\">\n <div class=\"col-12 px-0\">\n <p-table #tt\n stateKey=\"pw-table.admin-incidents-list\"\n stateStorage=\"session\"\n [resizableColumns]=\"true\"\n columnResizeMode=\"expand\"\n [paginator]=\"totalRecords !== 0\"\n [rows]=\"PAGE_SIZE\"\n [totalRecords]=\"totalRecords\"\n [loading]=\"loading\"\n [lazy]=\"true\"\n [filterDelay]=\"1000\"\n [customSort]=\"true\"\n [value]=\"openIncidents\"\n (onLazyLoad)=\"onLazyLoad($event)\">\n <ng-template #caption>\n <div class=\"search-filter justify-content-end\">\n <div class=\"text-end\">\n <label for=\"incidents-list-search\" class=\"visually-hidden\">Search Incident</label>\n <p-iconfield iconPosition=\"left\">\n <p-inputicon><i class=\"fa fa-search\" aria-hidden=\"true\"></i></p-inputicon>\n <input id=\"incidents-list-search\"\n name=\"incidents-list-search\"\n [(ngModel)]=\"searchText\"\n (input)=\"tt.filterGlobal($event.target.value, 'contains')\"\n type=\"text\"\n pInputText\n placeholder=\"Search incidents...\"\n data-cy=\"incident-search\"\n aria-label=\"Search incidents...\" />\n </p-iconfield>\n </div>\n </div>\n </ng-template>\n <ng-template #header>\n <tr>\n <th pResizableColumn scope=\"true\">\n {{ 'Admin.Incident.Description' | transloco }}\n </th>\n <th pResizableColumn scope=\"true\">\n {{ 'Admin.Incident.ServiceImpacted' | transloco }}\n </th>\n <th pResizableColumn scope=\"true\"\n pSortableColumn=\"started_at\">\n {{ 'Admin.Incident.StartedAt' | transloco }}\n <p-sort-icon field=\"started_at\"></p-sort-icon>\n </th>\n <th pResizableColumn scope=\"true\"\n pSortableColumn=\"resolved_at\">\n {{ 'Admin.Incident.ResolvedAt' | transloco }}\n <p-sort-icon field=\"resolved_at\"></p-sort-icon>\n </th>\n <th pResizableColumn scope=\"true\"\n pSortableColumn=\"last_check_at\">\n {{ 'Admin.Incident.LastCheckedAt' | transloco }}\n <p-sort-icon field=\"last_check_at\"></p-sort-icon>\n </th>\n <th pResizableColumn scope=\"true\">\n {{ 'Admin.Incident.Duration' | transloco }}\n </th>\n <th scope=\"true\"\n class=\"actions-list-two\">\n {{ 'Label.Actions' | transloco }}\n </th>\n </tr>\n </ng-template>\n <ng-template #body\n let-incident>\n <tr>\n <td data-head=\"description\"\n class=\"description\">\n {{(incident?.description | removeHtml: 'quill')|textTruncate: 200}}\n </td>\n <td data-head=\"serviceImpacted\">\n {{ incident?.service_impacted ? incident?.service_impacted :\n incident?.url_impacted }}\n </td>\n <td data-head=\"startedAt\">\n <span class=\"text-nowrap\">\n {{ incident?.started_at | date: 'dd-MMM-yyyy, h:mm a' }}\n </span>\n </td>\n <td data-head=\"resolvedAt\">\n <span class=\"text-nowrap\">\n {{ incident?.resolved_at | date: 'dd-MMM-yyyy, h:mm a' }}\n </span>\n </td>\n <td data-head=\"lastCheckedAt\">\n <span class=\"text-nowrap\">\n {{ incident?.last_check_at | date: 'dd-MMM-yyyy, h:mm a' }}\n </span>\n </td>\n <td data-head=\"Duration\">\n <!-- {{ calculateDuration(incident?.resolved_at ? incident?.resolved_at :\n incident?.last_check_at, incident?.started_at) }} -->\n {{ calculateDuration(incident?.resolved_at,\n incident?.started_at) }}\n </td>\n <td data-head=\"Action\">\n <ul class=\"list-unstyled list-inline list-action\">\n <li pTooltip=\"Edit\" tooltipPosition=\"top\" appendTo=\"body\"\n class=\"me-2 me-sm-2\">\n <i (click)=\"navigateToEdit(incident)\"\n (keydown.enter)=\"navigateToEdit(incident)\"\n class=\"fa fa-edit edit-icon\"\n aria-hidden=\"true\"></i>\n </li>\n <li pTooltip=\"Delete\" tooltipPosition=\"top\" appendTo=\"body\"\n class=\"me-2 me-sm-2\">\n <i\n (keydown.enter)=\"onDelete(incident)\"\n (click)=\"onDelete(incident)\"\n class=\"fa fa-trash delete-icon\"\n aria-hidden=\"true\"></i>\n </li>\n </ul>\n </td>\n </tr>\n </ng-template>\n </p-table>\n @if (openIncidents.length === 0 && totalRecordsUnFiltered !== 0) {\n <div>\n <pw-no-data [withImage]=\"true\" [message]=\"'Search.NoDataMessage' | transloco\"\n [description]=\"'Search.NoDataDescription' | transloco\">\n </pw-no-data>\n </div>\n }\n @if (openIncidents.length !== 0) {\n <pw-records-summary [showing]=\"tt?.value?.length ?? 0\" [total]=\"openIncidents.length\" />\n }\n </div>\n</div>\n}\n@if (totalRecordsUnFiltered === 0 && isLoaded) {\n<pw-no-data [withImage]=\"true\"\n [message]=\"'Admin.Incident.NoDataMessage' | transloco\">\n</pw-no-data>\n}\n",
11050
11066
  styles: ["@charset \"UTF-8\";:root{--first: rgb(23 105 225);--second: rgb(54 194 131);--third: rgb(255 171 0);--text: rgb(34 34 34);--tabs_bg: rgb(23 105 225);--tabs_sub_bg: color-mix(in srgb, var(--first, rgb(23 105 225)) 85%, #000000);--tabs_text: rgb(255 255 255);--titles: rgb(34 34 34);--sidebar_bg: rgb(0, 48, 63);--sidebar_text: rgb(255 255 255);--dashboard_bg: rgb(255 255 255);--public-btn-radius: 24px}.incidents-wrapper .table thead th{border:0;border-bottom:1px solid rgb(222,226,230)}.incident-item{color:#3f3f44;font-size:14px;line-height:1.42857;padding:10px 0}.incident-item .description{color:var(--first)}.incident-item:last-child{border-bottom:0!important}.ql-editor.safe-html{margin:0;font-size:13px;padding:0}.safe-html p{margin:0;font-size:13px}\n"],
11051
11067
  dependencies: [
11052
11068
  {
@@ -11168,6 +11184,12 @@ var IncidentListComponent = class IncidentListComponent extends AppBaseComponent
11168
11184
  selector: "[pSortableColumn]",
11169
11185
  inputs: ["pSortableColumn", "pSortableColumnDisabled"]
11170
11186
  },
11187
+ {
11188
+ kind: "directive",
11189
+ type: i2$3.ResizableColumn,
11190
+ selector: "[pResizableColumn]",
11191
+ inputs: ["pResizableColumnDisabled"]
11192
+ },
11171
11193
  {
11172
11194
  kind: "component",
11173
11195
  type: i2$3.SortIcon,
@@ -11340,7 +11362,7 @@ i0.ɵɵngDeclareClassMetadata({
11340
11362
  args: [{
11341
11363
  selector: "pw-admin-incident-list",
11342
11364
  standalone: false,
11343
- template: "<div class=\"row\">\n <div *rbacAllow=\"'Pages.Admin.Incident.Create'\"\n class=\"col-12 d-flex flex-wrap justify-content-between align-items-baseline\">\n <h2 class=\"card-title p-0\">Incidents</h2>\n <a [routerLink]=\"[routers.incidentDetails + 'add']\"\n (click)=\"showList = !showList\"\n (keydown.enter)=\"showList = !showList\"\n class=\"btn btn-sm btn-outline-primary\"\n aria-expanded=\"false\">\n <i class=\"fa fa-plus-circle\"\n aria-hidden=\"true\"></i>\n {{ 'Label.AddNew' | transloco }} Incident\n </a>\n </div>\n <div class=\"col-12 mb-3\">\n <p>The <strong>Incidents</strong> module lets you create and manage incident statuses. These incidents are publicly\n visible at the <strong>/status</strong> endpoint.</p>\n </div>\n</div>\n@if (!isLoaded) {\n <div class=\"w-100 text-center mt-3\">\n <p-progress-spinner strokeWidth=\"2\"></p-progress-spinner>\n </div>\n}\n@if (showList) {\n<div class=\"row faqlist primeng-datatable-container actions-collapsed mt-0\" [class.hideTable]=\"totalRecordsUnFiltered === 0\">\n <div class=\"col-12 px-0\">\n <p-table #tt\n [paginator]=\"totalRecords !== 0\"\n [rows]=\"PAGE_SIZE\"\n [totalRecords]=\"totalRecords\"\n [loading]=\"loading\"\n [lazy]=\"true\"\n [filterDelay]=\"1000\"\n [customSort]=\"true\"\n [value]=\"openIncidents\"\n (onLazyLoad)=\"onLazyLoad($event)\">\n <ng-template #caption>\n <div class=\"search-filter justify-content-end\">\n <div class=\"text-end\">\n <label for=\"incidents-list-search\" class=\"visually-hidden\">Search Incident</label>\n <p-iconfield iconPosition=\"left\">\n <p-inputicon><i class=\"fa fa-search\" aria-hidden=\"true\"></i></p-inputicon>\n <input id=\"incidents-list-search\"\n name=\"incidents-list-search\"\n [(ngModel)]=\"searchText\"\n (input)=\"tt.filterGlobal($event.target.value, 'contains')\"\n type=\"text\"\n pInputText\n placeholder=\"Search incidents...\"\n data-cy=\"incident-search\"\n aria-label=\"Search incidents...\" />\n </p-iconfield>\n </div>\n </div>\n </ng-template>\n <ng-template #header>\n <tr>\n <th scope=\"true\">\n {{ 'Admin.Incident.Description' | transloco }}\n </th>\n <th scope=\"true\">\n {{ 'Admin.Incident.ServiceImpacted' | transloco }}\n </th>\n <th scope=\"true\"\n pSortableColumn=\"started_at\">\n {{ 'Admin.Incident.StartedAt' | transloco }}\n <p-sort-icon field=\"started_at\"></p-sort-icon>\n </th>\n <th scope=\"true\"\n pSortableColumn=\"resolved_at\">\n {{ 'Admin.Incident.ResolvedAt' | transloco }}\n <p-sort-icon field=\"resolved_at\"></p-sort-icon>\n </th>\n <th scope=\"true\"\n pSortableColumn=\"last_check_at\">\n {{ 'Admin.Incident.LastCheckedAt' | transloco }}\n <p-sort-icon field=\"last_check_at\"></p-sort-icon>\n </th>\n <th scope=\"true\">\n {{ 'Admin.Incident.Duration' | transloco }}\n </th>\n <th scope=\"true\"\n class=\"actions-list-two\">\n {{ 'Label.Actions' | transloco }}\n </th>\n </tr>\n </ng-template>\n <ng-template #body\n let-incident>\n <tr>\n <td data-head=\"description\"\n class=\"description\">\n {{(incident?.description | removeHtml: 'quill')|textTruncate: 200}}\n </td>\n <td data-head=\"serviceImpacted\">\n {{ incident?.service_impacted ? incident?.service_impacted :\n incident?.url_impacted }}\n </td>\n <td data-head=\"startedAt\">\n <span class=\"text-nowrap\">\n {{ incident?.started_at | date: 'dd-MMM-yyyy, h:mm a' }}\n </span>\n </td>\n <td data-head=\"resolvedAt\">\n <span class=\"text-nowrap\">\n {{ incident?.resolved_at | date: 'dd-MMM-yyyy, h:mm a' }}\n </span>\n </td>\n <td data-head=\"lastCheckedAt\">\n <span class=\"text-nowrap\">\n {{ incident?.last_check_at | date: 'dd-MMM-yyyy, h:mm a' }}\n </span>\n </td>\n <td data-head=\"Duration\">\n <!-- {{ calculateDuration(incident?.resolved_at ? incident?.resolved_at :\n incident?.last_check_at, incident?.started_at) }} -->\n {{ calculateDuration(incident?.resolved_at,\n incident?.started_at) }}\n </td>\n <td data-head=\"Action\">\n <ul class=\"list-unstyled list-inline list-action\">\n <li pTooltip=\"Edit\" tooltipPosition=\"top\" appendTo=\"body\"\n class=\"me-2 me-sm-2\">\n <i (click)=\"navigateToEdit(incident)\"\n (keydown.enter)=\"navigateToEdit(incident)\"\n class=\"fa fa-edit edit-icon\"\n aria-hidden=\"true\"></i>\n </li>\n <li pTooltip=\"Delete\" tooltipPosition=\"top\" appendTo=\"body\"\n class=\"me-2 me-sm-2\">\n <i\n (keydown.enter)=\"onDelete(incident)\"\n (click)=\"onDelete(incident)\"\n class=\"fa fa-trash delete-icon\"\n aria-hidden=\"true\"></i>\n </li>\n </ul>\n </td>\n </tr>\n </ng-template>\n </p-table>\n @if (openIncidents.length === 0 && totalRecordsUnFiltered !== 0) {\n <div>\n <pw-no-data [withImage]=\"true\" [message]=\"'Search.NoDataMessage' | transloco\"\n [description]=\"'Search.NoDataDescription' | transloco\">\n </pw-no-data>\n </div>\n }\n @if (openIncidents.length !== 0) {\n <pw-records-summary [showing]=\"tt?.value?.length ?? 0\" [total]=\"openIncidents.length\" />\n }\n </div>\n</div>\n}\n@if (totalRecordsUnFiltered === 0 && isLoaded) {\n<pw-no-data [withImage]=\"true\"\n [message]=\"'Admin.Incident.NoDataMessage' | transloco\">\n</pw-no-data>\n}\n",
11365
+ template: "<div class=\"row\">\n <div *rbacAllow=\"'Pages.Admin.Incident.Create'\"\n class=\"col-12 d-flex flex-wrap justify-content-between align-items-baseline\">\n <h2 class=\"card-title p-0\">Incidents</h2>\n <a [routerLink]=\"[routers.incidentDetails + 'add']\"\n (click)=\"showList = !showList\"\n (keydown.enter)=\"showList = !showList\"\n class=\"btn btn-sm btn-outline-primary\"\n aria-expanded=\"false\">\n <i class=\"fa fa-plus-circle\"\n aria-hidden=\"true\"></i>\n {{ 'Label.AddNew' | transloco }} Incident\n </a>\n </div>\n <div class=\"col-12 mb-3\">\n <p>The <strong>Incidents</strong> module lets you create and manage incident statuses. These incidents are publicly\n visible at the <strong>/status</strong> endpoint.</p>\n </div>\n</div>\n@if (!isLoaded) {\n <div class=\"w-100 text-center mt-3\">\n <p-progress-spinner strokeWidth=\"2\"></p-progress-spinner>\n </div>\n}\n@if (showList) {\n<div class=\"row faqlist primeng-datatable-container actions-collapsed mt-0\" [class.hideTable]=\"totalRecordsUnFiltered === 0\">\n <div class=\"col-12 px-0\">\n <p-table #tt\n stateKey=\"pw-table.admin-incidents-list\"\n stateStorage=\"session\"\n [resizableColumns]=\"true\"\n columnResizeMode=\"expand\"\n [paginator]=\"totalRecords !== 0\"\n [rows]=\"PAGE_SIZE\"\n [totalRecords]=\"totalRecords\"\n [loading]=\"loading\"\n [lazy]=\"true\"\n [filterDelay]=\"1000\"\n [customSort]=\"true\"\n [value]=\"openIncidents\"\n (onLazyLoad)=\"onLazyLoad($event)\">\n <ng-template #caption>\n <div class=\"search-filter justify-content-end\">\n <div class=\"text-end\">\n <label for=\"incidents-list-search\" class=\"visually-hidden\">Search Incident</label>\n <p-iconfield iconPosition=\"left\">\n <p-inputicon><i class=\"fa fa-search\" aria-hidden=\"true\"></i></p-inputicon>\n <input id=\"incidents-list-search\"\n name=\"incidents-list-search\"\n [(ngModel)]=\"searchText\"\n (input)=\"tt.filterGlobal($event.target.value, 'contains')\"\n type=\"text\"\n pInputText\n placeholder=\"Search incidents...\"\n data-cy=\"incident-search\"\n aria-label=\"Search incidents...\" />\n </p-iconfield>\n </div>\n </div>\n </ng-template>\n <ng-template #header>\n <tr>\n <th pResizableColumn scope=\"true\">\n {{ 'Admin.Incident.Description' | transloco }}\n </th>\n <th pResizableColumn scope=\"true\">\n {{ 'Admin.Incident.ServiceImpacted' | transloco }}\n </th>\n <th pResizableColumn scope=\"true\"\n pSortableColumn=\"started_at\">\n {{ 'Admin.Incident.StartedAt' | transloco }}\n <p-sort-icon field=\"started_at\"></p-sort-icon>\n </th>\n <th pResizableColumn scope=\"true\"\n pSortableColumn=\"resolved_at\">\n {{ 'Admin.Incident.ResolvedAt' | transloco }}\n <p-sort-icon field=\"resolved_at\"></p-sort-icon>\n </th>\n <th pResizableColumn scope=\"true\"\n pSortableColumn=\"last_check_at\">\n {{ 'Admin.Incident.LastCheckedAt' | transloco }}\n <p-sort-icon field=\"last_check_at\"></p-sort-icon>\n </th>\n <th pResizableColumn scope=\"true\">\n {{ 'Admin.Incident.Duration' | transloco }}\n </th>\n <th scope=\"true\"\n class=\"actions-list-two\">\n {{ 'Label.Actions' | transloco }}\n </th>\n </tr>\n </ng-template>\n <ng-template #body\n let-incident>\n <tr>\n <td data-head=\"description\"\n class=\"description\">\n {{(incident?.description | removeHtml: 'quill')|textTruncate: 200}}\n </td>\n <td data-head=\"serviceImpacted\">\n {{ incident?.service_impacted ? incident?.service_impacted :\n incident?.url_impacted }}\n </td>\n <td data-head=\"startedAt\">\n <span class=\"text-nowrap\">\n {{ incident?.started_at | date: 'dd-MMM-yyyy, h:mm a' }}\n </span>\n </td>\n <td data-head=\"resolvedAt\">\n <span class=\"text-nowrap\">\n {{ incident?.resolved_at | date: 'dd-MMM-yyyy, h:mm a' }}\n </span>\n </td>\n <td data-head=\"lastCheckedAt\">\n <span class=\"text-nowrap\">\n {{ incident?.last_check_at | date: 'dd-MMM-yyyy, h:mm a' }}\n </span>\n </td>\n <td data-head=\"Duration\">\n <!-- {{ calculateDuration(incident?.resolved_at ? incident?.resolved_at :\n incident?.last_check_at, incident?.started_at) }} -->\n {{ calculateDuration(incident?.resolved_at,\n incident?.started_at) }}\n </td>\n <td data-head=\"Action\">\n <ul class=\"list-unstyled list-inline list-action\">\n <li pTooltip=\"Edit\" tooltipPosition=\"top\" appendTo=\"body\"\n class=\"me-2 me-sm-2\">\n <i (click)=\"navigateToEdit(incident)\"\n (keydown.enter)=\"navigateToEdit(incident)\"\n class=\"fa fa-edit edit-icon\"\n aria-hidden=\"true\"></i>\n </li>\n <li pTooltip=\"Delete\" tooltipPosition=\"top\" appendTo=\"body\"\n class=\"me-2 me-sm-2\">\n <i\n (keydown.enter)=\"onDelete(incident)\"\n (click)=\"onDelete(incident)\"\n class=\"fa fa-trash delete-icon\"\n aria-hidden=\"true\"></i>\n </li>\n </ul>\n </td>\n </tr>\n </ng-template>\n </p-table>\n @if (openIncidents.length === 0 && totalRecordsUnFiltered !== 0) {\n <div>\n <pw-no-data [withImage]=\"true\" [message]=\"'Search.NoDataMessage' | transloco\"\n [description]=\"'Search.NoDataDescription' | transloco\">\n </pw-no-data>\n </div>\n }\n @if (openIncidents.length !== 0) {\n <pw-records-summary [showing]=\"tt?.value?.length ?? 0\" [total]=\"openIncidents.length\" />\n }\n </div>\n</div>\n}\n@if (totalRecordsUnFiltered === 0 && isLoaded) {\n<pw-no-data [withImage]=\"true\"\n [message]=\"'Admin.Incident.NoDataMessage' | transloco\">\n</pw-no-data>\n}\n",
11344
11366
  styles: ["@charset \"UTF-8\";:root{--first: rgb(23 105 225);--second: rgb(54 194 131);--third: rgb(255 171 0);--text: rgb(34 34 34);--tabs_bg: rgb(23 105 225);--tabs_sub_bg: color-mix(in srgb, var(--first, rgb(23 105 225)) 85%, #000000);--tabs_text: rgb(255 255 255);--titles: rgb(34 34 34);--sidebar_bg: rgb(0, 48, 63);--sidebar_text: rgb(255 255 255);--dashboard_bg: rgb(255 255 255);--public-btn-radius: 24px}.incidents-wrapper .table thead th{border:0;border-bottom:1px solid rgb(222,226,230)}.incident-item{color:#3f3f44;font-size:14px;line-height:1.42857;padding:10px 0}.incident-item .description{color:var(--first)}.incident-item:last-child{border-bottom:0!important}.ql-editor.safe-html{margin:0;font-size:13px;padding:0}.safe-html p{margin:0;font-size:13px}\n"]
11345
11367
  }]
11346
11368
  }],
@@ -12072,7 +12094,7 @@ var LoginNotificationsListComponent = class LoginNotificationsListComponent exte
12072
12094
  selector: "pw-login-notifications-list",
12073
12095
  usesInheritance: true,
12074
12096
  ngImport: i0,
12075
- template: "<div class=\"row\">\n <div class=\"col-12 d-flex flex-wrap justify-content-between align-items-baseline\">\n <h2 class=\"card-title p-0\">Dashboard Notifications</h2>\n <button class=\"btn btn-outline-primary btn-sm\"\n [routerLink]=\"[routers.loginNotifications + 'add']\">\n <i class=\"fa fa-plus-circle\" aria-hidden=\"true\"></i> Add Dashboard Notification\n </button>\n </div>\n <div class=\"col-12 mb-3\">\n <p>The <strong>Dashboard Notification</strong> module lets you create banner messages that appear at the top of every page.<br/>\n Use these banners to communicate important updates — like <strong>new feature announcements</strong> or <strong>known issues</strong> — directly to your active users. </p>\n </div>\n</div>\n@if (!isLoaded) {\n <div class=\"w-100 text-center mt-3\"\n >\n <p-progress-spinner strokeWidth=\"2\"> </p-progress-spinner>\n </div>\n}\n<div class=\"primeng-datatable-container actions-collapsed table-responsive mt-0\"\n [class.hideTable]=\"data.unfiltered_count === 0\">\n <p-table #tt\n [value]=\"data.notifications\"\n [paginator]=\"data.object_count !== 0\"\n [rows]=\"PAGE_SIZE\"\n [totalRecords]=\"data.object_count\"\n [loading]=\"loading\"\n [lazy]=\"true\"\n [filterDelay]=\"1000\"\n (onLazyLoad)=\"onLazyLoad($event)\"\n [customSort]=\"true\">\n <!--sort order should be default empty when page load-->\n\n <!-- Caption Header, Search Bar -->\n <ng-template #caption>\n <div class=\"text-end\">\n <p-iconfield iconPosition=\"left\">\n <p-inputicon><i class=\"fa fa-search\" aria-hidden=\"true\"></i></p-inputicon>\n <input type=\"text\"\n id=\"login-notifications-list-search\"\n name=\"login-notifications-list-search\"\n pInputText\n placeholder=\"Search notifications...\"\n [(ngModel)]=\"searchText\"\n (input)=\"onSearchChange($any($event.target).value)\"\n aria-label=\"Search notifications...\" />\n </p-iconfield>\n </div>\n </ng-template>\n\n <!-- Column Header -->\n <ng-template #header>\n <tr>\n <th scope=\"true\"\n pSortableColumn=\"notification_type\">\n {{ 'Admin.LoginNotification.NotificationType' | transloco }}\n <p-sort-icon field=\"notification_type\"></p-sort-icon>\n </th>\n <th scope=\"true\"\n pSortableColumn=\"body\">\n {{ 'Admin.LoginNotification.Body' | transloco }}\n <p-sort-icon field=\"body\"></p-sort-icon>\n </th>\n <th scope=\"true\">\n {{ 'Admin.LoginNotification.IsPermanent' | transloco }}\n </th>\n <th scope=\"true\"\n class=\"w-25\">\n {{ 'Admin.LoginNotification.FeatureKeys' | transloco }}\n </th>\n <th scope=\"true\"\n pSortableColumn=\"visible_from\">\n {{ 'Admin.LoginNotification.VisibleFrom' | transloco }}\n <p-sort-icon field=\"visible_from\"></p-sort-icon>\n </th>\n <th scope=\"true\"\n pSortableColumn=\"visible_until\">\n {{ 'Admin.LoginNotification.VisibleUntil' | transloco }}\n <p-sort-icon field=\"visible_until\"></p-sort-icon>\n </th>\n <th class=\"actions-list-two\"\n scope=\"true\">{{ 'Label.Actions' | transloco }}</th>\n </tr>\n </ng-template>\n\n <!-- Table Body -->\n <ng-template #body\n let-item>\n <tr>\n <td data-head=\"notification_type\">\n @if (item?.notification_type) {\n <span\n class=\"badge\"\n [ngClass]=\"'bg-' + item.notification_type\">\n {{ item.notification_type }}\n </span>\n }\n </td>\n <td\n data-head=\"body\"\n >\n <span [pTooltip]=\"item?.body\"\n tooltipStyleClass=\"custom-tooltip\"\n tooltipPosition=\"top\" appendTo=\"body\"> {{ item?.body | textTruncate: 30 }}</span>\n\n </td>\n <td data-head=\"Is Permanent\">\n <span [appDynamicBadge]=\"{\n itemsArray: [true, false],\n item: item?.is_permanent\n }\"\n color=\"success-danger\"\n class=\"badge\">{{ item?.is_permanent ? 'Yes' : 'No' }}</span>\n </td>\n <td data-head=\"feature_keys\">\n @for (data of item?.feature_keys.slice(0, 3); track data) {\n <span\n class=\"badge m-1\"\n [appDynamicBadge]=\"{ itemsArray: item?.feature_keys, item: data }\"\n [colorByName]=\"true\"\n [dataName]=\"data\"\n color=\"cyan\">{{ data }}</span>\n }\n\n @if (item.expanded) {\n <span>\n @for (data of item?.feature_keys.slice(3); track data) {\n <span\n class=\"badge m-1\"\n [appDynamicBadge]=\"{ itemsArray: item?.feature_keys, item: data }\"\n [colorByName]=\"true\"\n [dataName]=\"data\"\n color=\"cyan\">{{ data }}</span>\n }\n </span>\n }\n\n @if (item?.feature_keys.length > 3) {\n <span class=\"fw-bold\">\n <a (click)=\"item.expanded = !item.expanded\">\n <span>...</span>\n </a>\n </span>\n }\n\n </td>\n <td\n data-head=\"visible_from\"\n [ngClass]=\"{ 'text-success-muted fw-bold': isDateInPast(item?.visible_from) }\"\n >\n {{ item?.visible_from | dateFormat }}\n </td>\n <td\n data-head=\"visible_until\"\n [ngClass]=\"{ 'text-success-muted fw-bold': isDateInFuture(item?.visible_until) }\"\n >\n {{ item?.visible_until | dateFormat }}\n </td>\n <td data-head=\"Action\">\n <ul class=\"list-unstyled list-inline list-action\">\n <li pTooltip=\"Edit\" tooltipPosition=\"top\" appendTo=\"body\"\n [routerLink]=\"[routers.loginNotifications + item?.id]\"\n class=\"me-2 me-sm-3\">\n <i class=\"fa fa-edit edit-icon\" aria-hidden=\"true\"></i>\n </li>\n <li pTooltip=\"Delete\" tooltipPosition=\"top\" appendTo=\"body\"\n class=\"me-2 me-sm-3\"\n (keydown.enter)=\"onDelete(item?.id)\"\n (click)=\"onDelete(item?.id)\">\n <i class=\"fa fa-trash delete-icon\" aria-hidden=\"true\"></i>\n </li>\n </ul>\n </td>\n </tr>\n </ng-template>\n </p-table>\n @if (data.object_count === 0 && data.unfiltered_count !== 0) {\n <div>\n <pw-no-data [withImage]=\"true\" [message]=\"'Search.NoDataMessage' | transloco\" [description]=\"'Search.NoDataDescription' | transloco\" >\n </pw-no-data>\n </div>\n }\n @if (data.object_count !== 0) {\n <pw-records-summary [showing]=\"tt?.value?.length ?? 0\" [total]=\"data.object_count\" />\n }\n</div>\n@if (data.unfiltered_count === 0 && isLoaded) {\n <div>\n <pw-no-data [withImage]=\"true\" [message]=\"'Admin.LoginNotification.NoDataMessage' | transloco\"> </pw-no-data>\n </div>\n}\n",
12097
+ template: "<div class=\"row\">\n <div class=\"col-12 d-flex flex-wrap justify-content-between align-items-baseline\">\n <h2 class=\"card-title p-0\">Dashboard Notifications</h2>\n <button class=\"btn btn-outline-primary btn-sm\"\n [routerLink]=\"[routers.loginNotifications + 'add']\">\n <i class=\"fa fa-plus-circle\" aria-hidden=\"true\"></i> Add Dashboard Notification\n </button>\n </div>\n <div class=\"col-12 mb-3\">\n <p>The <strong>Dashboard Notification</strong> module lets you create banner messages that appear at the top of every page.<br/>\n Use these banners to communicate important updates — like <strong>new feature announcements</strong> or <strong>known issues</strong> — directly to your active users. </p>\n </div>\n</div>\n@if (!isLoaded) {\n <div class=\"w-100 text-center mt-3\"\n >\n <p-progress-spinner strokeWidth=\"2\"> </p-progress-spinner>\n </div>\n}\n<div class=\"primeng-datatable-container actions-collapsed table-responsive mt-0\"\n [class.hideTable]=\"data.unfiltered_count === 0\">\n <p-table #tt\n stateKey=\"pw-table.admin-login-notifications-list\"\n stateStorage=\"session\"\n [resizableColumns]=\"true\"\n columnResizeMode=\"expand\"\n [value]=\"data.notifications\"\n [paginator]=\"data.object_count !== 0\"\n [rows]=\"PAGE_SIZE\"\n [totalRecords]=\"data.object_count\"\n [loading]=\"loading\"\n [lazy]=\"true\"\n [filterDelay]=\"1000\"\n (onLazyLoad)=\"onLazyLoad($event)\"\n [customSort]=\"true\">\n <!--sort order should be default empty when page load-->\n\n <!-- Caption Header, Search Bar -->\n <ng-template #caption>\n <div class=\"text-end\">\n <p-iconfield iconPosition=\"left\">\n <p-inputicon><i class=\"fa fa-search\" aria-hidden=\"true\"></i></p-inputicon>\n <input type=\"text\"\n id=\"login-notifications-list-search\"\n name=\"login-notifications-list-search\"\n pInputText\n placeholder=\"Search notifications...\"\n [(ngModel)]=\"searchText\"\n (input)=\"onSearchChange($any($event.target).value)\"\n aria-label=\"Search notifications...\" />\n </p-iconfield>\n </div>\n </ng-template>\n\n <!-- Column Header -->\n <ng-template #header>\n <tr>\n <th pResizableColumn scope=\"true\"\n pSortableColumn=\"notification_type\">\n {{ 'Admin.LoginNotification.NotificationType' | transloco }}\n <p-sort-icon field=\"notification_type\"></p-sort-icon>\n </th>\n <th pResizableColumn scope=\"true\"\n pSortableColumn=\"body\">\n {{ 'Admin.LoginNotification.Body' | transloco }}\n <p-sort-icon field=\"body\"></p-sort-icon>\n </th>\n <th pResizableColumn scope=\"true\">\n {{ 'Admin.LoginNotification.IsPermanent' | transloco }}\n </th>\n <th pResizableColumn scope=\"true\"\n class=\"w-25\">\n {{ 'Admin.LoginNotification.FeatureKeys' | transloco }}\n </th>\n <th pResizableColumn scope=\"true\"\n pSortableColumn=\"visible_from\">\n {{ 'Admin.LoginNotification.VisibleFrom' | transloco }}\n <p-sort-icon field=\"visible_from\"></p-sort-icon>\n </th>\n <th pResizableColumn scope=\"true\"\n pSortableColumn=\"visible_until\">\n {{ 'Admin.LoginNotification.VisibleUntil' | transloco }}\n <p-sort-icon field=\"visible_until\"></p-sort-icon>\n </th>\n <th class=\"actions-list-two\"\n scope=\"true\">{{ 'Label.Actions' | transloco }}</th>\n </tr>\n </ng-template>\n\n <!-- Table Body -->\n <ng-template #body\n let-item>\n <tr>\n <td data-head=\"notification_type\">\n @if (item?.notification_type) {\n <span\n class=\"badge\"\n [ngClass]=\"'bg-' + item.notification_type\">\n {{ item.notification_type }}\n </span>\n }\n </td>\n <td\n data-head=\"body\"\n >\n <span [pTooltip]=\"item?.body\"\n tooltipStyleClass=\"custom-tooltip\"\n tooltipPosition=\"top\" appendTo=\"body\"> {{ item?.body | textTruncate: 30 }}</span>\n\n </td>\n <td data-head=\"Is Permanent\">\n <span [appDynamicBadge]=\"{\n itemsArray: [true, false],\n item: item?.is_permanent\n }\"\n color=\"success-danger\"\n class=\"badge\">{{ item?.is_permanent ? 'Yes' : 'No' }}</span>\n </td>\n <td data-head=\"feature_keys\">\n @for (data of item?.feature_keys.slice(0, 3); track data) {\n <span\n class=\"badge m-1\"\n [appDynamicBadge]=\"{ itemsArray: item?.feature_keys, item: data }\"\n [colorByName]=\"true\"\n [dataName]=\"data\"\n color=\"cyan\">{{ data }}</span>\n }\n\n @if (item.expanded) {\n <span>\n @for (data of item?.feature_keys.slice(3); track data) {\n <span\n class=\"badge m-1\"\n [appDynamicBadge]=\"{ itemsArray: item?.feature_keys, item: data }\"\n [colorByName]=\"true\"\n [dataName]=\"data\"\n color=\"cyan\">{{ data }}</span>\n }\n </span>\n }\n\n @if (item?.feature_keys.length > 3) {\n <span class=\"fw-bold\">\n <a (click)=\"item.expanded = !item.expanded\">\n <span>...</span>\n </a>\n </span>\n }\n\n </td>\n <td\n data-head=\"visible_from\"\n [ngClass]=\"{ 'text-success-muted fw-bold': isDateInPast(item?.visible_from) }\"\n >\n {{ item?.visible_from | dateFormat }}\n </td>\n <td\n data-head=\"visible_until\"\n [ngClass]=\"{ 'text-success-muted fw-bold': isDateInFuture(item?.visible_until) }\"\n >\n {{ item?.visible_until | dateFormat }}\n </td>\n <td data-head=\"Action\">\n <ul class=\"list-unstyled list-inline list-action\">\n <li pTooltip=\"Edit\" tooltipPosition=\"top\" appendTo=\"body\"\n [routerLink]=\"[routers.loginNotifications + item?.id]\"\n class=\"me-2 me-sm-3\">\n <i class=\"fa fa-edit edit-icon\" aria-hidden=\"true\"></i>\n </li>\n <li pTooltip=\"Delete\" tooltipPosition=\"top\" appendTo=\"body\"\n class=\"me-2 me-sm-3\"\n (keydown.enter)=\"onDelete(item?.id)\"\n (click)=\"onDelete(item?.id)\">\n <i class=\"fa fa-trash delete-icon\" aria-hidden=\"true\"></i>\n </li>\n </ul>\n </td>\n </tr>\n </ng-template>\n </p-table>\n @if (data.object_count === 0 && data.unfiltered_count !== 0) {\n <div>\n <pw-no-data [withImage]=\"true\" [message]=\"'Search.NoDataMessage' | transloco\" [description]=\"'Search.NoDataDescription' | transloco\" >\n </pw-no-data>\n </div>\n }\n @if (data.object_count !== 0) {\n <pw-records-summary [showing]=\"tt?.value?.length ?? 0\" [total]=\"data.object_count\" />\n }\n</div>\n@if (data.unfiltered_count === 0 && isLoaded) {\n <div>\n <pw-no-data [withImage]=\"true\" [message]=\"'Admin.LoginNotification.NoDataMessage' | transloco\"> </pw-no-data>\n </div>\n}\n",
12076
12098
  dependencies: [
12077
12099
  {
12078
12100
  kind: "component",
@@ -12193,6 +12215,12 @@ var LoginNotificationsListComponent = class LoginNotificationsListComponent exte
12193
12215
  selector: "[pSortableColumn]",
12194
12216
  inputs: ["pSortableColumn", "pSortableColumnDisabled"]
12195
12217
  },
12218
+ {
12219
+ kind: "directive",
12220
+ type: i2$3.ResizableColumn,
12221
+ selector: "[pResizableColumn]",
12222
+ inputs: ["pResizableColumnDisabled"]
12223
+ },
12196
12224
  {
12197
12225
  kind: "component",
12198
12226
  type: i2$3.SortIcon,
@@ -12371,7 +12399,7 @@ i0.ɵɵngDeclareClassMetadata({
12371
12399
  args: [{
12372
12400
  selector: "pw-login-notifications-list",
12373
12401
  standalone: false,
12374
- template: "<div class=\"row\">\n <div class=\"col-12 d-flex flex-wrap justify-content-between align-items-baseline\">\n <h2 class=\"card-title p-0\">Dashboard Notifications</h2>\n <button class=\"btn btn-outline-primary btn-sm\"\n [routerLink]=\"[routers.loginNotifications + 'add']\">\n <i class=\"fa fa-plus-circle\" aria-hidden=\"true\"></i> Add Dashboard Notification\n </button>\n </div>\n <div class=\"col-12 mb-3\">\n <p>The <strong>Dashboard Notification</strong> module lets you create banner messages that appear at the top of every page.<br/>\n Use these banners to communicate important updates — like <strong>new feature announcements</strong> or <strong>known issues</strong> — directly to your active users. </p>\n </div>\n</div>\n@if (!isLoaded) {\n <div class=\"w-100 text-center mt-3\"\n >\n <p-progress-spinner strokeWidth=\"2\"> </p-progress-spinner>\n </div>\n}\n<div class=\"primeng-datatable-container actions-collapsed table-responsive mt-0\"\n [class.hideTable]=\"data.unfiltered_count === 0\">\n <p-table #tt\n [value]=\"data.notifications\"\n [paginator]=\"data.object_count !== 0\"\n [rows]=\"PAGE_SIZE\"\n [totalRecords]=\"data.object_count\"\n [loading]=\"loading\"\n [lazy]=\"true\"\n [filterDelay]=\"1000\"\n (onLazyLoad)=\"onLazyLoad($event)\"\n [customSort]=\"true\">\n <!--sort order should be default empty when page load-->\n\n <!-- Caption Header, Search Bar -->\n <ng-template #caption>\n <div class=\"text-end\">\n <p-iconfield iconPosition=\"left\">\n <p-inputicon><i class=\"fa fa-search\" aria-hidden=\"true\"></i></p-inputicon>\n <input type=\"text\"\n id=\"login-notifications-list-search\"\n name=\"login-notifications-list-search\"\n pInputText\n placeholder=\"Search notifications...\"\n [(ngModel)]=\"searchText\"\n (input)=\"onSearchChange($any($event.target).value)\"\n aria-label=\"Search notifications...\" />\n </p-iconfield>\n </div>\n </ng-template>\n\n <!-- Column Header -->\n <ng-template #header>\n <tr>\n <th scope=\"true\"\n pSortableColumn=\"notification_type\">\n {{ 'Admin.LoginNotification.NotificationType' | transloco }}\n <p-sort-icon field=\"notification_type\"></p-sort-icon>\n </th>\n <th scope=\"true\"\n pSortableColumn=\"body\">\n {{ 'Admin.LoginNotification.Body' | transloco }}\n <p-sort-icon field=\"body\"></p-sort-icon>\n </th>\n <th scope=\"true\">\n {{ 'Admin.LoginNotification.IsPermanent' | transloco }}\n </th>\n <th scope=\"true\"\n class=\"w-25\">\n {{ 'Admin.LoginNotification.FeatureKeys' | transloco }}\n </th>\n <th scope=\"true\"\n pSortableColumn=\"visible_from\">\n {{ 'Admin.LoginNotification.VisibleFrom' | transloco }}\n <p-sort-icon field=\"visible_from\"></p-sort-icon>\n </th>\n <th scope=\"true\"\n pSortableColumn=\"visible_until\">\n {{ 'Admin.LoginNotification.VisibleUntil' | transloco }}\n <p-sort-icon field=\"visible_until\"></p-sort-icon>\n </th>\n <th class=\"actions-list-two\"\n scope=\"true\">{{ 'Label.Actions' | transloco }}</th>\n </tr>\n </ng-template>\n\n <!-- Table Body -->\n <ng-template #body\n let-item>\n <tr>\n <td data-head=\"notification_type\">\n @if (item?.notification_type) {\n <span\n class=\"badge\"\n [ngClass]=\"'bg-' + item.notification_type\">\n {{ item.notification_type }}\n </span>\n }\n </td>\n <td\n data-head=\"body\"\n >\n <span [pTooltip]=\"item?.body\"\n tooltipStyleClass=\"custom-tooltip\"\n tooltipPosition=\"top\" appendTo=\"body\"> {{ item?.body | textTruncate: 30 }}</span>\n\n </td>\n <td data-head=\"Is Permanent\">\n <span [appDynamicBadge]=\"{\n itemsArray: [true, false],\n item: item?.is_permanent\n }\"\n color=\"success-danger\"\n class=\"badge\">{{ item?.is_permanent ? 'Yes' : 'No' }}</span>\n </td>\n <td data-head=\"feature_keys\">\n @for (data of item?.feature_keys.slice(0, 3); track data) {\n <span\n class=\"badge m-1\"\n [appDynamicBadge]=\"{ itemsArray: item?.feature_keys, item: data }\"\n [colorByName]=\"true\"\n [dataName]=\"data\"\n color=\"cyan\">{{ data }}</span>\n }\n\n @if (item.expanded) {\n <span>\n @for (data of item?.feature_keys.slice(3); track data) {\n <span\n class=\"badge m-1\"\n [appDynamicBadge]=\"{ itemsArray: item?.feature_keys, item: data }\"\n [colorByName]=\"true\"\n [dataName]=\"data\"\n color=\"cyan\">{{ data }}</span>\n }\n </span>\n }\n\n @if (item?.feature_keys.length > 3) {\n <span class=\"fw-bold\">\n <a (click)=\"item.expanded = !item.expanded\">\n <span>...</span>\n </a>\n </span>\n }\n\n </td>\n <td\n data-head=\"visible_from\"\n [ngClass]=\"{ 'text-success-muted fw-bold': isDateInPast(item?.visible_from) }\"\n >\n {{ item?.visible_from | dateFormat }}\n </td>\n <td\n data-head=\"visible_until\"\n [ngClass]=\"{ 'text-success-muted fw-bold': isDateInFuture(item?.visible_until) }\"\n >\n {{ item?.visible_until | dateFormat }}\n </td>\n <td data-head=\"Action\">\n <ul class=\"list-unstyled list-inline list-action\">\n <li pTooltip=\"Edit\" tooltipPosition=\"top\" appendTo=\"body\"\n [routerLink]=\"[routers.loginNotifications + item?.id]\"\n class=\"me-2 me-sm-3\">\n <i class=\"fa fa-edit edit-icon\" aria-hidden=\"true\"></i>\n </li>\n <li pTooltip=\"Delete\" tooltipPosition=\"top\" appendTo=\"body\"\n class=\"me-2 me-sm-3\"\n (keydown.enter)=\"onDelete(item?.id)\"\n (click)=\"onDelete(item?.id)\">\n <i class=\"fa fa-trash delete-icon\" aria-hidden=\"true\"></i>\n </li>\n </ul>\n </td>\n </tr>\n </ng-template>\n </p-table>\n @if (data.object_count === 0 && data.unfiltered_count !== 0) {\n <div>\n <pw-no-data [withImage]=\"true\" [message]=\"'Search.NoDataMessage' | transloco\" [description]=\"'Search.NoDataDescription' | transloco\" >\n </pw-no-data>\n </div>\n }\n @if (data.object_count !== 0) {\n <pw-records-summary [showing]=\"tt?.value?.length ?? 0\" [total]=\"data.object_count\" />\n }\n</div>\n@if (data.unfiltered_count === 0 && isLoaded) {\n <div>\n <pw-no-data [withImage]=\"true\" [message]=\"'Admin.LoginNotification.NoDataMessage' | transloco\"> </pw-no-data>\n </div>\n}\n"
12402
+ template: "<div class=\"row\">\n <div class=\"col-12 d-flex flex-wrap justify-content-between align-items-baseline\">\n <h2 class=\"card-title p-0\">Dashboard Notifications</h2>\n <button class=\"btn btn-outline-primary btn-sm\"\n [routerLink]=\"[routers.loginNotifications + 'add']\">\n <i class=\"fa fa-plus-circle\" aria-hidden=\"true\"></i> Add Dashboard Notification\n </button>\n </div>\n <div class=\"col-12 mb-3\">\n <p>The <strong>Dashboard Notification</strong> module lets you create banner messages that appear at the top of every page.<br/>\n Use these banners to communicate important updates — like <strong>new feature announcements</strong> or <strong>known issues</strong> — directly to your active users. </p>\n </div>\n</div>\n@if (!isLoaded) {\n <div class=\"w-100 text-center mt-3\"\n >\n <p-progress-spinner strokeWidth=\"2\"> </p-progress-spinner>\n </div>\n}\n<div class=\"primeng-datatable-container actions-collapsed table-responsive mt-0\"\n [class.hideTable]=\"data.unfiltered_count === 0\">\n <p-table #tt\n stateKey=\"pw-table.admin-login-notifications-list\"\n stateStorage=\"session\"\n [resizableColumns]=\"true\"\n columnResizeMode=\"expand\"\n [value]=\"data.notifications\"\n [paginator]=\"data.object_count !== 0\"\n [rows]=\"PAGE_SIZE\"\n [totalRecords]=\"data.object_count\"\n [loading]=\"loading\"\n [lazy]=\"true\"\n [filterDelay]=\"1000\"\n (onLazyLoad)=\"onLazyLoad($event)\"\n [customSort]=\"true\">\n <!--sort order should be default empty when page load-->\n\n <!-- Caption Header, Search Bar -->\n <ng-template #caption>\n <div class=\"text-end\">\n <p-iconfield iconPosition=\"left\">\n <p-inputicon><i class=\"fa fa-search\" aria-hidden=\"true\"></i></p-inputicon>\n <input type=\"text\"\n id=\"login-notifications-list-search\"\n name=\"login-notifications-list-search\"\n pInputText\n placeholder=\"Search notifications...\"\n [(ngModel)]=\"searchText\"\n (input)=\"onSearchChange($any($event.target).value)\"\n aria-label=\"Search notifications...\" />\n </p-iconfield>\n </div>\n </ng-template>\n\n <!-- Column Header -->\n <ng-template #header>\n <tr>\n <th pResizableColumn scope=\"true\"\n pSortableColumn=\"notification_type\">\n {{ 'Admin.LoginNotification.NotificationType' | transloco }}\n <p-sort-icon field=\"notification_type\"></p-sort-icon>\n </th>\n <th pResizableColumn scope=\"true\"\n pSortableColumn=\"body\">\n {{ 'Admin.LoginNotification.Body' | transloco }}\n <p-sort-icon field=\"body\"></p-sort-icon>\n </th>\n <th pResizableColumn scope=\"true\">\n {{ 'Admin.LoginNotification.IsPermanent' | transloco }}\n </th>\n <th pResizableColumn scope=\"true\"\n class=\"w-25\">\n {{ 'Admin.LoginNotification.FeatureKeys' | transloco }}\n </th>\n <th pResizableColumn scope=\"true\"\n pSortableColumn=\"visible_from\">\n {{ 'Admin.LoginNotification.VisibleFrom' | transloco }}\n <p-sort-icon field=\"visible_from\"></p-sort-icon>\n </th>\n <th pResizableColumn scope=\"true\"\n pSortableColumn=\"visible_until\">\n {{ 'Admin.LoginNotification.VisibleUntil' | transloco }}\n <p-sort-icon field=\"visible_until\"></p-sort-icon>\n </th>\n <th class=\"actions-list-two\"\n scope=\"true\">{{ 'Label.Actions' | transloco }}</th>\n </tr>\n </ng-template>\n\n <!-- Table Body -->\n <ng-template #body\n let-item>\n <tr>\n <td data-head=\"notification_type\">\n @if (item?.notification_type) {\n <span\n class=\"badge\"\n [ngClass]=\"'bg-' + item.notification_type\">\n {{ item.notification_type }}\n </span>\n }\n </td>\n <td\n data-head=\"body\"\n >\n <span [pTooltip]=\"item?.body\"\n tooltipStyleClass=\"custom-tooltip\"\n tooltipPosition=\"top\" appendTo=\"body\"> {{ item?.body | textTruncate: 30 }}</span>\n\n </td>\n <td data-head=\"Is Permanent\">\n <span [appDynamicBadge]=\"{\n itemsArray: [true, false],\n item: item?.is_permanent\n }\"\n color=\"success-danger\"\n class=\"badge\">{{ item?.is_permanent ? 'Yes' : 'No' }}</span>\n </td>\n <td data-head=\"feature_keys\">\n @for (data of item?.feature_keys.slice(0, 3); track data) {\n <span\n class=\"badge m-1\"\n [appDynamicBadge]=\"{ itemsArray: item?.feature_keys, item: data }\"\n [colorByName]=\"true\"\n [dataName]=\"data\"\n color=\"cyan\">{{ data }}</span>\n }\n\n @if (item.expanded) {\n <span>\n @for (data of item?.feature_keys.slice(3); track data) {\n <span\n class=\"badge m-1\"\n [appDynamicBadge]=\"{ itemsArray: item?.feature_keys, item: data }\"\n [colorByName]=\"true\"\n [dataName]=\"data\"\n color=\"cyan\">{{ data }}</span>\n }\n </span>\n }\n\n @if (item?.feature_keys.length > 3) {\n <span class=\"fw-bold\">\n <a (click)=\"item.expanded = !item.expanded\">\n <span>...</span>\n </a>\n </span>\n }\n\n </td>\n <td\n data-head=\"visible_from\"\n [ngClass]=\"{ 'text-success-muted fw-bold': isDateInPast(item?.visible_from) }\"\n >\n {{ item?.visible_from | dateFormat }}\n </td>\n <td\n data-head=\"visible_until\"\n [ngClass]=\"{ 'text-success-muted fw-bold': isDateInFuture(item?.visible_until) }\"\n >\n {{ item?.visible_until | dateFormat }}\n </td>\n <td data-head=\"Action\">\n <ul class=\"list-unstyled list-inline list-action\">\n <li pTooltip=\"Edit\" tooltipPosition=\"top\" appendTo=\"body\"\n [routerLink]=\"[routers.loginNotifications + item?.id]\"\n class=\"me-2 me-sm-3\">\n <i class=\"fa fa-edit edit-icon\" aria-hidden=\"true\"></i>\n </li>\n <li pTooltip=\"Delete\" tooltipPosition=\"top\" appendTo=\"body\"\n class=\"me-2 me-sm-3\"\n (keydown.enter)=\"onDelete(item?.id)\"\n (click)=\"onDelete(item?.id)\">\n <i class=\"fa fa-trash delete-icon\" aria-hidden=\"true\"></i>\n </li>\n </ul>\n </td>\n </tr>\n </ng-template>\n </p-table>\n @if (data.object_count === 0 && data.unfiltered_count !== 0) {\n <div>\n <pw-no-data [withImage]=\"true\" [message]=\"'Search.NoDataMessage' | transloco\" [description]=\"'Search.NoDataDescription' | transloco\" >\n </pw-no-data>\n </div>\n }\n @if (data.object_count !== 0) {\n <pw-records-summary [showing]=\"tt?.value?.length ?? 0\" [total]=\"data.object_count\" />\n }\n</div>\n@if (data.unfiltered_count === 0 && isLoaded) {\n <div>\n <pw-no-data [withImage]=\"true\" [message]=\"'Admin.LoginNotification.NoDataMessage' | transloco\"> </pw-no-data>\n </div>\n}\n"
12375
12403
  }]
12376
12404
  }],
12377
12405
  ctorParameters: () => [
@@ -12796,7 +12824,7 @@ var MailerListComponent = class MailerListComponent extends AppBaseComponent {
12796
12824
  selector: "pw-mailer-list",
12797
12825
  usesInheritance: true,
12798
12826
  ngImport: i0,
12799
- template: "<div class=\"row\">\n <div class=\"col-12 d-flex flex-wrap justify-content-between align-items-baseline\">\n <h2 class=\"card-title p-0\">Mailers</h2>\n <button *rbacAllow=\"'SubscriptionSuperAdmin || SubscriptionOwner'\"\n class=\"btn btn-outline-primary btn-sm\"\n [routerLink]=\"[routers.mailerDetails + 'add']\">\n <i class=\"fa fa-plus-circle\" aria-hidden=\"true\"></i> Add Mailer Configuration\n </button>\n </div>\n <div class=\"col-12 mb-3\">\n <p>The <strong>Mailer</strong> module lets you set up and customize templates for outgoing emails such as sign-up, password reset, and more.</p>\n </div>\n</div>\n@if (!isLoaded) {\n <div class=\"w-100 text-center mt-3\"\n >\n <p-progress-spinner strokeWidth=\"2\"> </p-progress-spinner>\n </div>\n}\n<div class=\"primeng-datatable-container actions-collapsed table-responsive mt-3\"\n [class.hideTable]=\"data.unfiltered_count === 0\">\n <p-table #tt\n [value]=\"data.custom_emails\"\n [paginator]=\"data.object_count !== 0\"\n [rows]=\"PAGE_SIZE\"\n [totalRecords]=\"data.object_count\"\n [loading]=\"loading\"\n [lazy]=\"true\"\n [filterDelay]=\"1000\"\n (onLazyLoad)=\"onLazyLoad($event)\"\n [customSort]=\"true\">\n <!--sort order should be default empty when page load-->\n\n <!-- Caption Header, Search Bar -->\n <ng-template #caption>\n <div class=\"text-end\">\n <label for=\"mailer-list-search\" class=\"visually-hidden\">Search</label>\n <p-iconfield iconPosition=\"left\">\n <p-inputicon><i class=\"fa fa-search\" aria-hidden=\"true\"></i></p-inputicon>\n <input type=\"text\"\n id=\"mailer-list-search\"\n name=\"mailer-list-search\"\n pInputText\n placeholder=\"Search emails...\"\n [(ngModel)]=\"searchText\"\n (input)=\"tt.filterGlobal($event.target.value, 'contains')\"\n aria-label=\"Search emails...\" />\n </p-iconfield>\n </div>\n </ng-template>\n\n <!-- Column Header -->\n <ng-template #header>\n <tr>\n <th scope=\"true\"\n pSortableColumn=\"name\">\n {{'Label.Subject' | transloco}}\n </th>\n <th scope=\"true\"\n pSortableColumn=\"active\">\n {{'Label.Body' | transloco}}\n </th>\n <th scope=\"true\"\n pSortableColumn=\"name\">\n {{'Label.TemplateName' | transloco}}\n </th>\n <th class=\"actions-list-two\"\n scope=\"true\">{{ 'Label.Actions' | transloco }}</th>\n </tr>\n </ng-template>\n\n <!-- Table Body -->\n <ng-template #body\n let-item>\n <tr>\n <td data-head=\"Name\">\n {{item.subject}}\n </td>\n <td data-head=\"Body\">\n {{(item.body|removeHtml: 'quill')|textTruncate: 200}}\n </td>\n <td data-head=\"Name\">\n <span [appDynamicBadge]=\"{ itemsArray: availableMailerTypes, item: item.template_name }\"\n color=\"cyan\"\n class=\"badge\"> {{item.template_name}}</span>\n </td>\n <td data-head=\"Action\">\n <ul class=\"list-unstyled list-inline list-action\"\n *rbacAllow=\"'SubscriptionSuperAdmin || SubscriptionOwner'\">\n <li pTooltip=\"Edit\" tooltipPosition=\"top\" appendTo=\"body\"\n class=\"me-2 me-sm-3\"\n [routerLink]=\"[routers.mailerDetails + item.id]\">\n <i class=\"fa fa-edit edit-icon\" aria-hidden=\"true\"></i>\n </li>\n <li pTooltip=\"Delete\" tooltipPosition=\"top\" appendTo=\"body\"\n class=\"me-2 me-sm-3\"\n (keydown.enter)=\"onDelete(item)\"\n (click)=\"onDelete(item)\">\n <i class=\"fa fa-trash delete-icon\" aria-hidden=\"true\"></i>\n </li>\n </ul>\n </td>\n </tr>\n </ng-template>\n </p-table>\n @if (data.object_count === 0 && data.unfiltered_count !== 0) {\n <div>\n <pw-no-data [withImage]=\"true\" [message]=\"'Search.NoDataMessage' | transloco\" [description]=\"'Search.NoDataDescription' | transloco\" >\n </pw-no-data>\n </div>\n }\n @if (data.object_count !== 0) {\n <pw-records-summary [showing]=\"tt?.value?.length ?? 0\" [total]=\"data.object_count\" />\n }\n</div>\n@if (data.unfiltered_count === 0 && isLoaded) {\n <div>\n <pw-no-data [withImage]=\"true\" [message]=\"'Admin.Mailer.NoDataMessage' | transloco\"> </pw-no-data>\n </div>\n}\n",
12827
+ template: "<div class=\"row\">\n <div class=\"col-12 d-flex flex-wrap justify-content-between align-items-baseline\">\n <h2 class=\"card-title p-0\">Mailers</h2>\n <button *rbacAllow=\"'SubscriptionSuperAdmin || SubscriptionOwner'\"\n class=\"btn btn-outline-primary btn-sm\"\n [routerLink]=\"[routers.mailerDetails + 'add']\">\n <i class=\"fa fa-plus-circle\" aria-hidden=\"true\"></i> Add Mailer Configuration\n </button>\n </div>\n <div class=\"col-12 mb-3\">\n <p>The <strong>Mailer</strong> module lets you set up and customize templates for outgoing emails such as sign-up, password reset, and more.</p>\n </div>\n</div>\n@if (!isLoaded) {\n <div class=\"w-100 text-center mt-3\"\n >\n <p-progress-spinner strokeWidth=\"2\"> </p-progress-spinner>\n </div>\n}\n<div class=\"primeng-datatable-container actions-collapsed table-responsive mt-3\"\n [class.hideTable]=\"data.unfiltered_count === 0\">\n <p-table #tt\n stateKey=\"pw-table.admin-mailer-list\"\n stateStorage=\"session\"\n [resizableColumns]=\"true\"\n columnResizeMode=\"expand\"\n [value]=\"data.custom_emails\"\n [paginator]=\"data.object_count !== 0\"\n [rows]=\"PAGE_SIZE\"\n [totalRecords]=\"data.object_count\"\n [loading]=\"loading\"\n [lazy]=\"true\"\n [filterDelay]=\"1000\"\n (onLazyLoad)=\"onLazyLoad($event)\"\n [customSort]=\"true\">\n <!--sort order should be default empty when page load-->\n\n <!-- Caption Header, Search Bar -->\n <ng-template #caption>\n <div class=\"text-end\">\n <label for=\"mailer-list-search\" class=\"visually-hidden\">Search</label>\n <p-iconfield iconPosition=\"left\">\n <p-inputicon><i class=\"fa fa-search\" aria-hidden=\"true\"></i></p-inputicon>\n <input type=\"text\"\n id=\"mailer-list-search\"\n name=\"mailer-list-search\"\n pInputText\n placeholder=\"Search emails...\"\n [(ngModel)]=\"searchText\"\n (input)=\"tt.filterGlobal($event.target.value, 'contains')\"\n aria-label=\"Search emails...\" />\n </p-iconfield>\n </div>\n </ng-template>\n\n <!-- Column Header -->\n <ng-template #header>\n <tr>\n <th pResizableColumn scope=\"true\"\n pSortableColumn=\"name\">\n {{'Label.Subject' | transloco}}\n </th>\n <th pResizableColumn scope=\"true\"\n pSortableColumn=\"active\">\n {{'Label.Body' | transloco}}\n </th>\n <th pResizableColumn scope=\"true\"\n pSortableColumn=\"name\">\n {{'Label.TemplateName' | transloco}}\n </th>\n <th class=\"actions-list-two\"\n scope=\"true\">{{ 'Label.Actions' | transloco }}</th>\n </tr>\n </ng-template>\n\n <!-- Table Body -->\n <ng-template #body\n let-item>\n <tr>\n <td data-head=\"Name\">\n {{item.subject}}\n </td>\n <td data-head=\"Body\">\n {{(item.body|removeHtml: 'quill')|textTruncate: 200}}\n </td>\n <td data-head=\"Name\">\n <span [appDynamicBadge]=\"{ itemsArray: availableMailerTypes, item: item.template_name }\"\n color=\"cyan\"\n class=\"badge\"> {{item.template_name}}</span>\n </td>\n <td data-head=\"Action\">\n <ul class=\"list-unstyled list-inline list-action\"\n *rbacAllow=\"'SubscriptionSuperAdmin || SubscriptionOwner'\">\n <li pTooltip=\"Edit\" tooltipPosition=\"top\" appendTo=\"body\"\n class=\"me-2 me-sm-3\"\n [routerLink]=\"[routers.mailerDetails + item.id]\">\n <i class=\"fa fa-edit edit-icon\" aria-hidden=\"true\"></i>\n </li>\n <li pTooltip=\"Delete\" tooltipPosition=\"top\" appendTo=\"body\"\n class=\"me-2 me-sm-3\"\n (keydown.enter)=\"onDelete(item)\"\n (click)=\"onDelete(item)\">\n <i class=\"fa fa-trash delete-icon\" aria-hidden=\"true\"></i>\n </li>\n </ul>\n </td>\n </tr>\n </ng-template>\n </p-table>\n @if (data.object_count === 0 && data.unfiltered_count !== 0) {\n <div>\n <pw-no-data [withImage]=\"true\" [message]=\"'Search.NoDataMessage' | transloco\" [description]=\"'Search.NoDataDescription' | transloco\" >\n </pw-no-data>\n </div>\n }\n @if (data.object_count !== 0) {\n <pw-records-summary [showing]=\"tt?.value?.length ?? 0\" [total]=\"data.object_count\" />\n }\n</div>\n@if (data.unfiltered_count === 0 && isLoaded) {\n <div>\n <pw-no-data [withImage]=\"true\" [message]=\"'Admin.Mailer.NoDataMessage' | transloco\"> </pw-no-data>\n </div>\n}\n",
12800
12828
  dependencies: [
12801
12829
  {
12802
12830
  kind: "component",
@@ -12917,6 +12945,12 @@ var MailerListComponent = class MailerListComponent extends AppBaseComponent {
12917
12945
  selector: "[pSortableColumn]",
12918
12946
  inputs: ["pSortableColumn", "pSortableColumnDisabled"]
12919
12947
  },
12948
+ {
12949
+ kind: "directive",
12950
+ type: i2$3.ResizableColumn,
12951
+ selector: "[pResizableColumn]",
12952
+ inputs: ["pResizableColumnDisabled"]
12953
+ },
12920
12954
  {
12921
12955
  kind: "directive",
12922
12956
  type: i3$3.Tooltip,
@@ -13089,7 +13123,7 @@ i0.ɵɵngDeclareClassMetadata({
13089
13123
  args: [{
13090
13124
  selector: "pw-mailer-list",
13091
13125
  standalone: false,
13092
- template: "<div class=\"row\">\n <div class=\"col-12 d-flex flex-wrap justify-content-between align-items-baseline\">\n <h2 class=\"card-title p-0\">Mailers</h2>\n <button *rbacAllow=\"'SubscriptionSuperAdmin || SubscriptionOwner'\"\n class=\"btn btn-outline-primary btn-sm\"\n [routerLink]=\"[routers.mailerDetails + 'add']\">\n <i class=\"fa fa-plus-circle\" aria-hidden=\"true\"></i> Add Mailer Configuration\n </button>\n </div>\n <div class=\"col-12 mb-3\">\n <p>The <strong>Mailer</strong> module lets you set up and customize templates for outgoing emails such as sign-up, password reset, and more.</p>\n </div>\n</div>\n@if (!isLoaded) {\n <div class=\"w-100 text-center mt-3\"\n >\n <p-progress-spinner strokeWidth=\"2\"> </p-progress-spinner>\n </div>\n}\n<div class=\"primeng-datatable-container actions-collapsed table-responsive mt-3\"\n [class.hideTable]=\"data.unfiltered_count === 0\">\n <p-table #tt\n [value]=\"data.custom_emails\"\n [paginator]=\"data.object_count !== 0\"\n [rows]=\"PAGE_SIZE\"\n [totalRecords]=\"data.object_count\"\n [loading]=\"loading\"\n [lazy]=\"true\"\n [filterDelay]=\"1000\"\n (onLazyLoad)=\"onLazyLoad($event)\"\n [customSort]=\"true\">\n <!--sort order should be default empty when page load-->\n\n <!-- Caption Header, Search Bar -->\n <ng-template #caption>\n <div class=\"text-end\">\n <label for=\"mailer-list-search\" class=\"visually-hidden\">Search</label>\n <p-iconfield iconPosition=\"left\">\n <p-inputicon><i class=\"fa fa-search\" aria-hidden=\"true\"></i></p-inputicon>\n <input type=\"text\"\n id=\"mailer-list-search\"\n name=\"mailer-list-search\"\n pInputText\n placeholder=\"Search emails...\"\n [(ngModel)]=\"searchText\"\n (input)=\"tt.filterGlobal($event.target.value, 'contains')\"\n aria-label=\"Search emails...\" />\n </p-iconfield>\n </div>\n </ng-template>\n\n <!-- Column Header -->\n <ng-template #header>\n <tr>\n <th scope=\"true\"\n pSortableColumn=\"name\">\n {{'Label.Subject' | transloco}}\n </th>\n <th scope=\"true\"\n pSortableColumn=\"active\">\n {{'Label.Body' | transloco}}\n </th>\n <th scope=\"true\"\n pSortableColumn=\"name\">\n {{'Label.TemplateName' | transloco}}\n </th>\n <th class=\"actions-list-two\"\n scope=\"true\">{{ 'Label.Actions' | transloco }}</th>\n </tr>\n </ng-template>\n\n <!-- Table Body -->\n <ng-template #body\n let-item>\n <tr>\n <td data-head=\"Name\">\n {{item.subject}}\n </td>\n <td data-head=\"Body\">\n {{(item.body|removeHtml: 'quill')|textTruncate: 200}}\n </td>\n <td data-head=\"Name\">\n <span [appDynamicBadge]=\"{ itemsArray: availableMailerTypes, item: item.template_name }\"\n color=\"cyan\"\n class=\"badge\"> {{item.template_name}}</span>\n </td>\n <td data-head=\"Action\">\n <ul class=\"list-unstyled list-inline list-action\"\n *rbacAllow=\"'SubscriptionSuperAdmin || SubscriptionOwner'\">\n <li pTooltip=\"Edit\" tooltipPosition=\"top\" appendTo=\"body\"\n class=\"me-2 me-sm-3\"\n [routerLink]=\"[routers.mailerDetails + item.id]\">\n <i class=\"fa fa-edit edit-icon\" aria-hidden=\"true\"></i>\n </li>\n <li pTooltip=\"Delete\" tooltipPosition=\"top\" appendTo=\"body\"\n class=\"me-2 me-sm-3\"\n (keydown.enter)=\"onDelete(item)\"\n (click)=\"onDelete(item)\">\n <i class=\"fa fa-trash delete-icon\" aria-hidden=\"true\"></i>\n </li>\n </ul>\n </td>\n </tr>\n </ng-template>\n </p-table>\n @if (data.object_count === 0 && data.unfiltered_count !== 0) {\n <div>\n <pw-no-data [withImage]=\"true\" [message]=\"'Search.NoDataMessage' | transloco\" [description]=\"'Search.NoDataDescription' | transloco\" >\n </pw-no-data>\n </div>\n }\n @if (data.object_count !== 0) {\n <pw-records-summary [showing]=\"tt?.value?.length ?? 0\" [total]=\"data.object_count\" />\n }\n</div>\n@if (data.unfiltered_count === 0 && isLoaded) {\n <div>\n <pw-no-data [withImage]=\"true\" [message]=\"'Admin.Mailer.NoDataMessage' | transloco\"> </pw-no-data>\n </div>\n}\n"
13126
+ template: "<div class=\"row\">\n <div class=\"col-12 d-flex flex-wrap justify-content-between align-items-baseline\">\n <h2 class=\"card-title p-0\">Mailers</h2>\n <button *rbacAllow=\"'SubscriptionSuperAdmin || SubscriptionOwner'\"\n class=\"btn btn-outline-primary btn-sm\"\n [routerLink]=\"[routers.mailerDetails + 'add']\">\n <i class=\"fa fa-plus-circle\" aria-hidden=\"true\"></i> Add Mailer Configuration\n </button>\n </div>\n <div class=\"col-12 mb-3\">\n <p>The <strong>Mailer</strong> module lets you set up and customize templates for outgoing emails such as sign-up, password reset, and more.</p>\n </div>\n</div>\n@if (!isLoaded) {\n <div class=\"w-100 text-center mt-3\"\n >\n <p-progress-spinner strokeWidth=\"2\"> </p-progress-spinner>\n </div>\n}\n<div class=\"primeng-datatable-container actions-collapsed table-responsive mt-3\"\n [class.hideTable]=\"data.unfiltered_count === 0\">\n <p-table #tt\n stateKey=\"pw-table.admin-mailer-list\"\n stateStorage=\"session\"\n [resizableColumns]=\"true\"\n columnResizeMode=\"expand\"\n [value]=\"data.custom_emails\"\n [paginator]=\"data.object_count !== 0\"\n [rows]=\"PAGE_SIZE\"\n [totalRecords]=\"data.object_count\"\n [loading]=\"loading\"\n [lazy]=\"true\"\n [filterDelay]=\"1000\"\n (onLazyLoad)=\"onLazyLoad($event)\"\n [customSort]=\"true\">\n <!--sort order should be default empty when page load-->\n\n <!-- Caption Header, Search Bar -->\n <ng-template #caption>\n <div class=\"text-end\">\n <label for=\"mailer-list-search\" class=\"visually-hidden\">Search</label>\n <p-iconfield iconPosition=\"left\">\n <p-inputicon><i class=\"fa fa-search\" aria-hidden=\"true\"></i></p-inputicon>\n <input type=\"text\"\n id=\"mailer-list-search\"\n name=\"mailer-list-search\"\n pInputText\n placeholder=\"Search emails...\"\n [(ngModel)]=\"searchText\"\n (input)=\"tt.filterGlobal($event.target.value, 'contains')\"\n aria-label=\"Search emails...\" />\n </p-iconfield>\n </div>\n </ng-template>\n\n <!-- Column Header -->\n <ng-template #header>\n <tr>\n <th pResizableColumn scope=\"true\"\n pSortableColumn=\"name\">\n {{'Label.Subject' | transloco}}\n </th>\n <th pResizableColumn scope=\"true\"\n pSortableColumn=\"active\">\n {{'Label.Body' | transloco}}\n </th>\n <th pResizableColumn scope=\"true\"\n pSortableColumn=\"name\">\n {{'Label.TemplateName' | transloco}}\n </th>\n <th class=\"actions-list-two\"\n scope=\"true\">{{ 'Label.Actions' | transloco }}</th>\n </tr>\n </ng-template>\n\n <!-- Table Body -->\n <ng-template #body\n let-item>\n <tr>\n <td data-head=\"Name\">\n {{item.subject}}\n </td>\n <td data-head=\"Body\">\n {{(item.body|removeHtml: 'quill')|textTruncate: 200}}\n </td>\n <td data-head=\"Name\">\n <span [appDynamicBadge]=\"{ itemsArray: availableMailerTypes, item: item.template_name }\"\n color=\"cyan\"\n class=\"badge\"> {{item.template_name}}</span>\n </td>\n <td data-head=\"Action\">\n <ul class=\"list-unstyled list-inline list-action\"\n *rbacAllow=\"'SubscriptionSuperAdmin || SubscriptionOwner'\">\n <li pTooltip=\"Edit\" tooltipPosition=\"top\" appendTo=\"body\"\n class=\"me-2 me-sm-3\"\n [routerLink]=\"[routers.mailerDetails + item.id]\">\n <i class=\"fa fa-edit edit-icon\" aria-hidden=\"true\"></i>\n </li>\n <li pTooltip=\"Delete\" tooltipPosition=\"top\" appendTo=\"body\"\n class=\"me-2 me-sm-3\"\n (keydown.enter)=\"onDelete(item)\"\n (click)=\"onDelete(item)\">\n <i class=\"fa fa-trash delete-icon\" aria-hidden=\"true\"></i>\n </li>\n </ul>\n </td>\n </tr>\n </ng-template>\n </p-table>\n @if (data.object_count === 0 && data.unfiltered_count !== 0) {\n <div>\n <pw-no-data [withImage]=\"true\" [message]=\"'Search.NoDataMessage' | transloco\" [description]=\"'Search.NoDataDescription' | transloco\" >\n </pw-no-data>\n </div>\n }\n @if (data.object_count !== 0) {\n <pw-records-summary [showing]=\"tt?.value?.length ?? 0\" [total]=\"data.object_count\" />\n }\n</div>\n@if (data.unfiltered_count === 0 && isLoaded) {\n <div>\n <pw-no-data [withImage]=\"true\" [message]=\"'Admin.Mailer.NoDataMessage' | transloco\"> </pw-no-data>\n </div>\n}\n"
13093
13127
  }]
13094
13128
  }],
13095
13129
  ctorParameters: () => [
@@ -15444,7 +15478,7 @@ var NewslettersListComponent = class NewslettersListComponent extends AppBaseCom
15444
15478
  selector: "pw-newsletters-list",
15445
15479
  usesInheritance: true,
15446
15480
  ngImport: i0,
15447
- template: "<div class=\"row\">\n <div class=\"col-12 d-flex flex-wrap justify-content-between align-items-center gap-2\">\n <h2 class=\"card-title p-0\">Newsletter Categories</h2>\n <button class=\"btn btn-outline-primary btn-sm\"\n [routerLink]=\"[routers.newsletterDetails + 'add']\">\n <i class=\"fa fa-plus-circle\" aria-hidden=\"true\"></i> Add Newsletter Category\n </button>\n </div>\n <div class=\"col-12 mb-3\">\n <p>The <strong>Newsletter</strong> module allows you to quickly launch and tailor email campaigns to your existing users or newsletter subscribers. <br />\n You can <strong>precisely target recipients</strong> to boost deliverability and engagement.</p>\n </div>\n</div>\n@if (!isLoaded) {\n <div class=\"w-100 text-center mt-3\"\n >\n <p-progress-spinner strokeWidth=\"2\"> </p-progress-spinner>\n </div>\n}\n<div class=\"primeng-datatable-container actions-collapsed table-responsive mt-3\"\n [class.hideTable]=\"data.unfiltered_count === 0\">\n <p-table #tt\n [value]=\"data.newsletters\"\n [paginator]=\"data.object_count !== 0\"\n [rows]=\"PAGE_SIZE\"\n [totalRecords]=\"data.object_count\"\n [loading]=\"loading\"\n [lazy]=\"true\"\n [filterDelay]=\"1000\"\n (onLazyLoad)=\"onLazyLoad($event)\"\n [customSort]=\"true\">\n <!--sort order should be default empty when page load-->\n\n <!-- Caption Header, Search Bar -->\n <ng-template #caption>\n <div class=\"text-end\">\n <p-iconfield iconPosition=\"left\">\n <p-inputicon><i class=\"fa fa-search\" aria-hidden=\"true\"></i></p-inputicon>\n <input type=\"text\"\n id=\"newsletters-list-search\"\n name=\"newsletters-list-search\"\n pInputText\n placeholder=\"Search newsletters...\"\n [(ngModel)]=\"searchText\"\n (input)=\"tt.filterGlobal($event.target.value, 'contains')\"\n aria-label=\"Search newsletters...\" />\n </p-iconfield>\n </div>\n </ng-template>\n\n <!-- Column Header -->\n <ng-template #header>\n <tr>\n <th scope=\"true\"\n pSortableColumn=\"name\">\n {{ 'Label.Name' | transloco }}\n <p-sort-icon field=\"name\"></p-sort-icon>\n </th>\n <th scope=\"true\"\n pSortableColumn=\"active\">\n {{ 'Label.IsActive' | transloco }}\n <p-sort-icon field=\"active\"></p-sort-icon>\n </th>\n <th scope=\"true\"\n pSortableColumn=\"visible\">\n {{ 'Label.IsVisible' | transloco }}\n <p-sort-icon field=\"visible\"></p-sort-icon>\n </th>\n <th class=\"actions-list-two\"\n scope=\"true\">{{ 'Label.Actions' | transloco }}</th>\n </tr>\n </ng-template>\n\n <!-- Table Body -->\n <ng-template #body\n let-item>\n <tr>\n <td data-head=\"Name\">\n <a (click)=\"navigateNewsletterItems(item.id)\">\n <span class=\"item-hoverable\">{{ item.name }}</span>\n </a>\n </td>\n <td data-head=\"Active\">\n <span [appDynamicBadge]=\"{ itemsArray: [true, false], item: item?.active }\"\n color=\"success-danger\"\n class=\"badge\">{{ item?.active ? 'Yes' : 'No' }}</span>\n </td>\n <td data-head=\"Visible\">\n <span [appDynamicBadge]=\"{ itemsArray: [true, false], item: item?.visible }\"\n color=\"success-danger\"\n class=\"badge\">{{ item?.visible ? 'Yes' : 'No' }}</span>\n </td>\n <td data-head=\"Action\">\n <ul class=\"list-unstyled list-inline list-action\">\n <li pTooltip=\"Edit\" tooltipPosition=\"top\" appendTo=\"body\"\n class=\"me-2 me-sm-3\"\n [routerLink]=\"[routers.newsletterDetails + item.id]\">\n <i class=\"fa fa-edit edit-icon\" aria-hidden=\"true\"></i>\n </li>\n <li pTooltip=\"Delete\" tooltipPosition=\"top\" appendTo=\"body\"\n class=\"me-2 me-sm-3\"\n (keydown.enter)=\"onDelete(item)\"\n (click)=\"onDelete(item)\">\n <i class=\"fa fa-trash delete-icon\" aria-hidden=\"true\"></i>\n </li>\n <li pTooltip=\"Newsletter Items\" tooltipPosition=\"top\" appendTo=\"body\"\n class=\"me-2 me-sm-3\"\n [routerLink]=\"'/admin/newsletter/items'\"\n [queryParams]=\"{ newsletter_id: item.id }\">\n <i class=\"fa fa-tasks cta1-icon\" aria-hidden=\"true\"></i>\n </li>\n </ul>\n </td>\n </tr>\n </ng-template>\n </p-table>\n @if (data.object_count === 0 && data.unfiltered_count !== 0) {\n <div>\n <pw-no-data [withImage]=\"true\" [message]=\"'Search.NoDataMessage' | transloco\" [description]=\"'Search.NoDataDescription' | transloco\" >\n </pw-no-data>\n </div>\n }\n @if (data.object_count !== 0) {\n <pw-records-summary [showing]=\"tt?.value?.length ?? 0\" [total]=\"data.object_count\" />\n }\n</div>\n@if (data.unfiltered_count === 0 && isLoaded) {\n <div>\n <pw-no-data [withImage]=\"true\" [message]=\"'Admin.Newsletter.NoDataMessage' | transloco\"> </pw-no-data>\n </div>\n}\n",
15481
+ template: "<div class=\"row\">\n <div class=\"col-12 d-flex flex-wrap justify-content-between align-items-center gap-2\">\n <h2 class=\"card-title p-0\">Newsletter Categories</h2>\n <button class=\"btn btn-outline-primary btn-sm\"\n [routerLink]=\"[routers.newsletterDetails + 'add']\">\n <i class=\"fa fa-plus-circle\" aria-hidden=\"true\"></i> Add Newsletter Category\n </button>\n </div>\n <div class=\"col-12 mb-3\">\n <p>The <strong>Newsletter</strong> module allows you to quickly launch and tailor email campaigns to your existing users or newsletter subscribers. <br />\n You can <strong>precisely target recipients</strong> to boost deliverability and engagement.</p>\n </div>\n</div>\n@if (!isLoaded) {\n <div class=\"w-100 text-center mt-3\"\n >\n <p-progress-spinner strokeWidth=\"2\"> </p-progress-spinner>\n </div>\n}\n<div class=\"primeng-datatable-container actions-collapsed table-responsive mt-3\"\n [class.hideTable]=\"data.unfiltered_count === 0\">\n <p-table #tt\n stateKey=\"pw-table.admin-newsletters-list\"\n stateStorage=\"session\"\n [resizableColumns]=\"true\"\n columnResizeMode=\"expand\"\n [value]=\"data.newsletters\"\n [paginator]=\"data.object_count !== 0\"\n [rows]=\"PAGE_SIZE\"\n [totalRecords]=\"data.object_count\"\n [loading]=\"loading\"\n [lazy]=\"true\"\n [filterDelay]=\"1000\"\n (onLazyLoad)=\"onLazyLoad($event)\"\n [customSort]=\"true\">\n <!--sort order should be default empty when page load-->\n\n <!-- Caption Header, Search Bar -->\n <ng-template #caption>\n <div class=\"text-end\">\n <p-iconfield iconPosition=\"left\">\n <p-inputicon><i class=\"fa fa-search\" aria-hidden=\"true\"></i></p-inputicon>\n <input type=\"text\"\n id=\"newsletters-list-search\"\n name=\"newsletters-list-search\"\n pInputText\n placeholder=\"Search newsletters...\"\n [(ngModel)]=\"searchText\"\n (input)=\"tt.filterGlobal($event.target.value, 'contains')\"\n aria-label=\"Search newsletters...\" />\n </p-iconfield>\n </div>\n </ng-template>\n\n <!-- Column Header -->\n <ng-template #header>\n <tr>\n <th pResizableColumn scope=\"true\"\n pSortableColumn=\"name\">\n {{ 'Label.Name' | transloco }}\n <p-sort-icon field=\"name\"></p-sort-icon>\n </th>\n <th pResizableColumn scope=\"true\"\n pSortableColumn=\"active\">\n {{ 'Label.IsActive' | transloco }}\n <p-sort-icon field=\"active\"></p-sort-icon>\n </th>\n <th pResizableColumn scope=\"true\"\n pSortableColumn=\"visible\">\n {{ 'Label.IsVisible' | transloco }}\n <p-sort-icon field=\"visible\"></p-sort-icon>\n </th>\n <th class=\"actions-list-two\"\n scope=\"true\">{{ 'Label.Actions' | transloco }}</th>\n </tr>\n </ng-template>\n\n <!-- Table Body -->\n <ng-template #body\n let-item>\n <tr>\n <td data-head=\"Name\">\n <a (click)=\"navigateNewsletterItems(item.id)\">\n <span class=\"item-hoverable\">{{ item.name }}</span>\n </a>\n </td>\n <td data-head=\"Active\">\n <span [appDynamicBadge]=\"{ itemsArray: [true, false], item: item?.active }\"\n color=\"success-danger\"\n class=\"badge\">{{ item?.active ? 'Yes' : 'No' }}</span>\n </td>\n <td data-head=\"Visible\">\n <span [appDynamicBadge]=\"{ itemsArray: [true, false], item: item?.visible }\"\n color=\"success-danger\"\n class=\"badge\">{{ item?.visible ? 'Yes' : 'No' }}</span>\n </td>\n <td data-head=\"Action\">\n <ul class=\"list-unstyled list-inline list-action\">\n <li pTooltip=\"Edit\" tooltipPosition=\"top\" appendTo=\"body\"\n class=\"me-2 me-sm-3\"\n [routerLink]=\"[routers.newsletterDetails + item.id]\">\n <i class=\"fa fa-edit edit-icon\" aria-hidden=\"true\"></i>\n </li>\n <li pTooltip=\"Delete\" tooltipPosition=\"top\" appendTo=\"body\"\n class=\"me-2 me-sm-3\"\n (keydown.enter)=\"onDelete(item)\"\n (click)=\"onDelete(item)\">\n <i class=\"fa fa-trash delete-icon\" aria-hidden=\"true\"></i>\n </li>\n <li pTooltip=\"Newsletter Items\" tooltipPosition=\"top\" appendTo=\"body\"\n class=\"me-2 me-sm-3\"\n [routerLink]=\"'/admin/newsletter/items'\"\n [queryParams]=\"{ newsletter_id: item.id }\">\n <i class=\"fa fa-tasks cta1-icon\" aria-hidden=\"true\"></i>\n </li>\n </ul>\n </td>\n </tr>\n </ng-template>\n </p-table>\n @if (data.object_count === 0 && data.unfiltered_count !== 0) {\n <div>\n <pw-no-data [withImage]=\"true\" [message]=\"'Search.NoDataMessage' | transloco\" [description]=\"'Search.NoDataDescription' | transloco\" >\n </pw-no-data>\n </div>\n }\n @if (data.object_count !== 0) {\n <pw-records-summary [showing]=\"tt?.value?.length ?? 0\" [total]=\"data.object_count\" />\n }\n</div>\n@if (data.unfiltered_count === 0 && isLoaded) {\n <div>\n <pw-no-data [withImage]=\"true\" [message]=\"'Admin.Newsletter.NoDataMessage' | transloco\"> </pw-no-data>\n </div>\n}\n",
15448
15482
  dependencies: [
15449
15483
  {
15450
15484
  kind: "component",
@@ -15565,6 +15599,12 @@ var NewslettersListComponent = class NewslettersListComponent extends AppBaseCom
15565
15599
  selector: "[pSortableColumn]",
15566
15600
  inputs: ["pSortableColumn", "pSortableColumnDisabled"]
15567
15601
  },
15602
+ {
15603
+ kind: "directive",
15604
+ type: i2$3.ResizableColumn,
15605
+ selector: "[pResizableColumn]",
15606
+ inputs: ["pResizableColumnDisabled"]
15607
+ },
15568
15608
  {
15569
15609
  kind: "component",
15570
15610
  type: i2$3.SortIcon,
@@ -15727,7 +15767,7 @@ i0.ɵɵngDeclareClassMetadata({
15727
15767
  args: [{
15728
15768
  selector: "pw-newsletters-list",
15729
15769
  standalone: false,
15730
- template: "<div class=\"row\">\n <div class=\"col-12 d-flex flex-wrap justify-content-between align-items-center gap-2\">\n <h2 class=\"card-title p-0\">Newsletter Categories</h2>\n <button class=\"btn btn-outline-primary btn-sm\"\n [routerLink]=\"[routers.newsletterDetails + 'add']\">\n <i class=\"fa fa-plus-circle\" aria-hidden=\"true\"></i> Add Newsletter Category\n </button>\n </div>\n <div class=\"col-12 mb-3\">\n <p>The <strong>Newsletter</strong> module allows you to quickly launch and tailor email campaigns to your existing users or newsletter subscribers. <br />\n You can <strong>precisely target recipients</strong> to boost deliverability and engagement.</p>\n </div>\n</div>\n@if (!isLoaded) {\n <div class=\"w-100 text-center mt-3\"\n >\n <p-progress-spinner strokeWidth=\"2\"> </p-progress-spinner>\n </div>\n}\n<div class=\"primeng-datatable-container actions-collapsed table-responsive mt-3\"\n [class.hideTable]=\"data.unfiltered_count === 0\">\n <p-table #tt\n [value]=\"data.newsletters\"\n [paginator]=\"data.object_count !== 0\"\n [rows]=\"PAGE_SIZE\"\n [totalRecords]=\"data.object_count\"\n [loading]=\"loading\"\n [lazy]=\"true\"\n [filterDelay]=\"1000\"\n (onLazyLoad)=\"onLazyLoad($event)\"\n [customSort]=\"true\">\n <!--sort order should be default empty when page load-->\n\n <!-- Caption Header, Search Bar -->\n <ng-template #caption>\n <div class=\"text-end\">\n <p-iconfield iconPosition=\"left\">\n <p-inputicon><i class=\"fa fa-search\" aria-hidden=\"true\"></i></p-inputicon>\n <input type=\"text\"\n id=\"newsletters-list-search\"\n name=\"newsletters-list-search\"\n pInputText\n placeholder=\"Search newsletters...\"\n [(ngModel)]=\"searchText\"\n (input)=\"tt.filterGlobal($event.target.value, 'contains')\"\n aria-label=\"Search newsletters...\" />\n </p-iconfield>\n </div>\n </ng-template>\n\n <!-- Column Header -->\n <ng-template #header>\n <tr>\n <th scope=\"true\"\n pSortableColumn=\"name\">\n {{ 'Label.Name' | transloco }}\n <p-sort-icon field=\"name\"></p-sort-icon>\n </th>\n <th scope=\"true\"\n pSortableColumn=\"active\">\n {{ 'Label.IsActive' | transloco }}\n <p-sort-icon field=\"active\"></p-sort-icon>\n </th>\n <th scope=\"true\"\n pSortableColumn=\"visible\">\n {{ 'Label.IsVisible' | transloco }}\n <p-sort-icon field=\"visible\"></p-sort-icon>\n </th>\n <th class=\"actions-list-two\"\n scope=\"true\">{{ 'Label.Actions' | transloco }}</th>\n </tr>\n </ng-template>\n\n <!-- Table Body -->\n <ng-template #body\n let-item>\n <tr>\n <td data-head=\"Name\">\n <a (click)=\"navigateNewsletterItems(item.id)\">\n <span class=\"item-hoverable\">{{ item.name }}</span>\n </a>\n </td>\n <td data-head=\"Active\">\n <span [appDynamicBadge]=\"{ itemsArray: [true, false], item: item?.active }\"\n color=\"success-danger\"\n class=\"badge\">{{ item?.active ? 'Yes' : 'No' }}</span>\n </td>\n <td data-head=\"Visible\">\n <span [appDynamicBadge]=\"{ itemsArray: [true, false], item: item?.visible }\"\n color=\"success-danger\"\n class=\"badge\">{{ item?.visible ? 'Yes' : 'No' }}</span>\n </td>\n <td data-head=\"Action\">\n <ul class=\"list-unstyled list-inline list-action\">\n <li pTooltip=\"Edit\" tooltipPosition=\"top\" appendTo=\"body\"\n class=\"me-2 me-sm-3\"\n [routerLink]=\"[routers.newsletterDetails + item.id]\">\n <i class=\"fa fa-edit edit-icon\" aria-hidden=\"true\"></i>\n </li>\n <li pTooltip=\"Delete\" tooltipPosition=\"top\" appendTo=\"body\"\n class=\"me-2 me-sm-3\"\n (keydown.enter)=\"onDelete(item)\"\n (click)=\"onDelete(item)\">\n <i class=\"fa fa-trash delete-icon\" aria-hidden=\"true\"></i>\n </li>\n <li pTooltip=\"Newsletter Items\" tooltipPosition=\"top\" appendTo=\"body\"\n class=\"me-2 me-sm-3\"\n [routerLink]=\"'/admin/newsletter/items'\"\n [queryParams]=\"{ newsletter_id: item.id }\">\n <i class=\"fa fa-tasks cta1-icon\" aria-hidden=\"true\"></i>\n </li>\n </ul>\n </td>\n </tr>\n </ng-template>\n </p-table>\n @if (data.object_count === 0 && data.unfiltered_count !== 0) {\n <div>\n <pw-no-data [withImage]=\"true\" [message]=\"'Search.NoDataMessage' | transloco\" [description]=\"'Search.NoDataDescription' | transloco\" >\n </pw-no-data>\n </div>\n }\n @if (data.object_count !== 0) {\n <pw-records-summary [showing]=\"tt?.value?.length ?? 0\" [total]=\"data.object_count\" />\n }\n</div>\n@if (data.unfiltered_count === 0 && isLoaded) {\n <div>\n <pw-no-data [withImage]=\"true\" [message]=\"'Admin.Newsletter.NoDataMessage' | transloco\"> </pw-no-data>\n </div>\n}\n"
15770
+ template: "<div class=\"row\">\n <div class=\"col-12 d-flex flex-wrap justify-content-between align-items-center gap-2\">\n <h2 class=\"card-title p-0\">Newsletter Categories</h2>\n <button class=\"btn btn-outline-primary btn-sm\"\n [routerLink]=\"[routers.newsletterDetails + 'add']\">\n <i class=\"fa fa-plus-circle\" aria-hidden=\"true\"></i> Add Newsletter Category\n </button>\n </div>\n <div class=\"col-12 mb-3\">\n <p>The <strong>Newsletter</strong> module allows you to quickly launch and tailor email campaigns to your existing users or newsletter subscribers. <br />\n You can <strong>precisely target recipients</strong> to boost deliverability and engagement.</p>\n </div>\n</div>\n@if (!isLoaded) {\n <div class=\"w-100 text-center mt-3\"\n >\n <p-progress-spinner strokeWidth=\"2\"> </p-progress-spinner>\n </div>\n}\n<div class=\"primeng-datatable-container actions-collapsed table-responsive mt-3\"\n [class.hideTable]=\"data.unfiltered_count === 0\">\n <p-table #tt\n stateKey=\"pw-table.admin-newsletters-list\"\n stateStorage=\"session\"\n [resizableColumns]=\"true\"\n columnResizeMode=\"expand\"\n [value]=\"data.newsletters\"\n [paginator]=\"data.object_count !== 0\"\n [rows]=\"PAGE_SIZE\"\n [totalRecords]=\"data.object_count\"\n [loading]=\"loading\"\n [lazy]=\"true\"\n [filterDelay]=\"1000\"\n (onLazyLoad)=\"onLazyLoad($event)\"\n [customSort]=\"true\">\n <!--sort order should be default empty when page load-->\n\n <!-- Caption Header, Search Bar -->\n <ng-template #caption>\n <div class=\"text-end\">\n <p-iconfield iconPosition=\"left\">\n <p-inputicon><i class=\"fa fa-search\" aria-hidden=\"true\"></i></p-inputicon>\n <input type=\"text\"\n id=\"newsletters-list-search\"\n name=\"newsletters-list-search\"\n pInputText\n placeholder=\"Search newsletters...\"\n [(ngModel)]=\"searchText\"\n (input)=\"tt.filterGlobal($event.target.value, 'contains')\"\n aria-label=\"Search newsletters...\" />\n </p-iconfield>\n </div>\n </ng-template>\n\n <!-- Column Header -->\n <ng-template #header>\n <tr>\n <th pResizableColumn scope=\"true\"\n pSortableColumn=\"name\">\n {{ 'Label.Name' | transloco }}\n <p-sort-icon field=\"name\"></p-sort-icon>\n </th>\n <th pResizableColumn scope=\"true\"\n pSortableColumn=\"active\">\n {{ 'Label.IsActive' | transloco }}\n <p-sort-icon field=\"active\"></p-sort-icon>\n </th>\n <th pResizableColumn scope=\"true\"\n pSortableColumn=\"visible\">\n {{ 'Label.IsVisible' | transloco }}\n <p-sort-icon field=\"visible\"></p-sort-icon>\n </th>\n <th class=\"actions-list-two\"\n scope=\"true\">{{ 'Label.Actions' | transloco }}</th>\n </tr>\n </ng-template>\n\n <!-- Table Body -->\n <ng-template #body\n let-item>\n <tr>\n <td data-head=\"Name\">\n <a (click)=\"navigateNewsletterItems(item.id)\">\n <span class=\"item-hoverable\">{{ item.name }}</span>\n </a>\n </td>\n <td data-head=\"Active\">\n <span [appDynamicBadge]=\"{ itemsArray: [true, false], item: item?.active }\"\n color=\"success-danger\"\n class=\"badge\">{{ item?.active ? 'Yes' : 'No' }}</span>\n </td>\n <td data-head=\"Visible\">\n <span [appDynamicBadge]=\"{ itemsArray: [true, false], item: item?.visible }\"\n color=\"success-danger\"\n class=\"badge\">{{ item?.visible ? 'Yes' : 'No' }}</span>\n </td>\n <td data-head=\"Action\">\n <ul class=\"list-unstyled list-inline list-action\">\n <li pTooltip=\"Edit\" tooltipPosition=\"top\" appendTo=\"body\"\n class=\"me-2 me-sm-3\"\n [routerLink]=\"[routers.newsletterDetails + item.id]\">\n <i class=\"fa fa-edit edit-icon\" aria-hidden=\"true\"></i>\n </li>\n <li pTooltip=\"Delete\" tooltipPosition=\"top\" appendTo=\"body\"\n class=\"me-2 me-sm-3\"\n (keydown.enter)=\"onDelete(item)\"\n (click)=\"onDelete(item)\">\n <i class=\"fa fa-trash delete-icon\" aria-hidden=\"true\"></i>\n </li>\n <li pTooltip=\"Newsletter Items\" tooltipPosition=\"top\" appendTo=\"body\"\n class=\"me-2 me-sm-3\"\n [routerLink]=\"'/admin/newsletter/items'\"\n [queryParams]=\"{ newsletter_id: item.id }\">\n <i class=\"fa fa-tasks cta1-icon\" aria-hidden=\"true\"></i>\n </li>\n </ul>\n </td>\n </tr>\n </ng-template>\n </p-table>\n @if (data.object_count === 0 && data.unfiltered_count !== 0) {\n <div>\n <pw-no-data [withImage]=\"true\" [message]=\"'Search.NoDataMessage' | transloco\" [description]=\"'Search.NoDataDescription' | transloco\" >\n </pw-no-data>\n </div>\n }\n @if (data.object_count !== 0) {\n <pw-records-summary [showing]=\"tt?.value?.length ?? 0\" [total]=\"data.object_count\" />\n }\n</div>\n@if (data.unfiltered_count === 0 && isLoaded) {\n <div>\n <pw-no-data [withImage]=\"true\" [message]=\"'Admin.Newsletter.NoDataMessage' | transloco\"> </pw-no-data>\n </div>\n}\n"
15731
15771
  }]
15732
15772
  }],
15733
15773
  ctorParameters: () => [
@@ -19135,7 +19175,7 @@ var ProductsListComponent = class ProductsListComponent extends AppBaseComponent
19135
19175
  }],
19136
19176
  usesInheritance: true,
19137
19177
  ngImport: i0,
19138
- template: "<div class=\"col-xs-12 text-end d-flex justify-content-between align-items-center\">\n <h2 class=\"card-title p-0\">Products</h2>\n <button *rbacAllow=\"'Pages.Admin.Product.Create'\"\n class=\"btn btn-sm btn-outline-primary\"\n [routerLink]=\"[routers.productDetails + 'add']\">\n <i class=\"fa fa-plus-circle\" aria-hidden=\"true\"></i> Setup New Product\n </button>\n</div>\n@if (loading) {\n <div class=\"w-100 text-center mt-3\">\n <p-progress-spinner> </p-progress-spinner>\n </div>\n}\n<div class=\"primeng-datatable-container actions-collapsed table-responsive mt-0\"\n [class.hideTable]=\"totalRecordsUnFiltered === 0\">\n <p-table #dt\n [value]=\"products\"\n [paginator]=\"totalRecords !== 0\"\n [lazy]=\"true\"\n [rows]=\"PAGE_SIZE\"\n [totalRecords]=\"totalRecords\"\n [loading]=\"loading\"\n [filterDelay]=\"1000\"\n (onLazyLoad)=\"onLazyLoad($event)\"\n [customSort]=\"true\">\n <ng-template #caption>\n <div class=\"search-filter\">\n <div class=\"col-12 col-sm-4\">\n <p-multiselect class=\"pw-filter-select\" inputId=\"products-list-feature-keys\" placeholder=\"Filter by feature keys\"\n [options]=\"featureKeysList\"\n (onChange)=\"onSearchOptionChange($event)\"\n [showHeader]=\"true\"\n appendTo=\"body\">\n </p-multiselect>\n </div>\n <div class=\"text-end\">\n <label for=\"products-list-search\" class=\"visually-hidden\">Search Product</label>\n <p-iconfield iconPosition=\"left\">\n <p-inputicon><i class=\"fa fa-search\" aria-hidden=\"true\"></i></p-inputicon>\n <input type=\"text\"\n id=\"products-list-search\"\n name=\"products-list-search\"\n [(ngModel)]=\"searchText\"\n pInputText\n placeholder=\"Search products...\"\n (input)=\"dt.filterGlobal($event.target.value, 'contains')\"\n aria-label=\"Search products...\" />\n </p-iconfield>\n </div>\n </div>\n </ng-template>\n <ng-template #header>\n <tr class=\"head\">\n <th scope=\"true\"\n pSortableColumn=\"name\">\n {{ 'Label.Name' | transloco }}\n <p-sort-icon field=\"name\"></p-sort-icon>\n </th>\n <th scope=\"true\"\n pSortableColumn=\"stripe_plan_id\">\n {{ 'Admin.Products.StripePlan' | transloco }}\n <p-sort-icon field=\"stripe_plan_id\"></p-sort-icon>\n </th>\n <th scope=\"true\"\n pSortableColumn=\"permission_key\">\n {{ 'Admin.Products.PermissionKey' | transloco }}\n <p-sort-icon field=\"permission_key\"></p-sort-icon>\n </th>\n <th scope=\"true\"\n pSortableColumn=\"feature_key\">\n {{ 'Admin.Products.FeatureKey' | transloco }}\n <p-sort-icon field=\"feature_key\"></p-sort-icon>\n </th>\n <th scope=\"true\"\n pSortableColumn=\"product_key\">\n {{ 'Admin.Products.ProductKey' | transloco }}\n <p-sort-icon field=\"product_key\"></p-sort-icon>\n </th>\n <th scope=\"true\"\n pSortableColumn=\"category\">\n {{ 'Admin.Products.Category' | transloco }}\n <p-sort-icon field=\"category\"></p-sort-icon>\n </th>\n <th scope=\"true\"\n pSortableColumn=\"region\">\n {{ 'Admin.Products.Region' | transloco }}\n <p-sort-icon field=\"region\"></p-sort-icon>\n </th>\n <th scope=\"true\"\n pSortableColumn=\"currency\">\n {{ 'Admin.Products.Currency' | transloco }}\n <p-sort-icon field=\"currency\"></p-sort-icon>\n </th>\n <th scope=\"true\"\n pSortableColumn=\"price_per_unit\">\n {{ 'Admin.Products.Price' | transloco }}\n <p-sort-icon field=\"price_per_unit\"></p-sort-icon>\n </th>\n <th scope=\"true\"\n pSortableColumn=\"active\">\n {{ 'Label.IsActive' | transloco }}\n <p-sort-icon field=\"active\"></p-sort-icon>\n </th>\n <th scope=\"true\"\n pSortableColumn=\"billing_frequency\">\n {{ 'Admin.Products.Billing' | transloco }}\n <p-sort-icon field=\"billing_frequency\"></p-sort-icon>\n </th>\n <th scope=\"true\"\n class=\"actions-list-two\">{{ 'Label.Actions' | transloco }}</th>\n </tr>\n </ng-template>\n <ng-template #body\n let-item>\n <tr>\n <td data-head=\"Name\">{{ item.name }}</td>\n <td data-head=\"Stripe Plan\">{{ item.stripe_plan_id }}</td>\n <td data-head=\"Permission Key\">{{ item.permission_key }}</td>\n <td data-head=\"Feature Key\">{{ item.feature_key }}</td>\n <td data-head=\"Product Key\">{{ item.product_key }}</td>\n <td data-head=\"Category\">\n <span [appDynamicBadge]=\"{ itemsArray: categories, item: item.category }\"\n color=\"warning\"\n class=\"badge\">{{ item.category }}</span>\n </td>\n <td data-head=\"Region\">\n <span [appDynamicBadge]=\"{ itemsArray: regions, item: item.region }\"\n color=\"cyan\"\n class=\"badge\">{{ item.region }}</span>\n </td>\n <td data-head=\"Currency\">\n <span [appDynamicBadge]=\"{ itemsArray: currency, item: item.currency }\"\n color=\"blue-grey\"\n class=\"badge\">{{ item.currency }}</span>\n </td>\n <td data-head=\"Price\">{{ item.price_per_unit }}</td>\n <td data-head=\"Active\">\n <span [appDynamicBadge]=\"{ itemsArray: [true, false], item: item?.active }\"\n color=\"success-danger\"\n class=\"badge\">{{ item?.active ? 'Yes' : 'No' }}</span>\n </td>\n <td data-head=\"Billing\">\n <span class=\"badge\"\n [appDynamicBadge]=\"{\n itemsArray: billingFrequency,\n item: item?.billing_frequency\n }\"\n color=\"blue-grey\">{{ item.billing_frequency }}</span>\n </td>\n <td data-head=\"Action\">\n <ul class=\"list-unstyled list-inline width-max-content\">\n <li pTooltip=\"Edit\" tooltipPosition=\"top\" appendTo=\"body\"\n class=\"me-2 me-sm-3\"\n *rbacAllow=\"'Pages.Admin.Product.Edit'\"\n [routerLink]=\"[routers.productDetails + item.id]\">\n <i class=\"fa fa-edit edit-icon\" aria-hidden=\"true\"></i>\n </li>\n <li pTooltip=\"Delete\" tooltipPosition=\"top\" appendTo=\"body\"\n class=\"me-2 me-sm-3\"\n *rbacAllow=\"'Pages.Admin.Product.Delete'\"\n (keydown.enter)=\"onDelete(item)\"\n (click)=\"onDelete(item)\">\n <i class=\"fa fa-trash delete-icon\" aria-hidden=\"true\"></i>\n </li>\n <li pTooltip=\"Users List\" tooltipPosition=\"top\" appendTo=\"body\"\n class=\"me-2 me-sm-3\"\n *rbacAllow=\"'Pages.Admin.Product.Edit'\"\n [routerLink]=\"[routers.productsUserList + item.id]\">\n <i class=\"fa fa-tasks cta1-icon\" aria-hidden=\"true\"></i>\n </li>\n <li pTooltip=\"Duplicate The Product\" tooltipPosition=\"top\" appendTo=\"body\"\n class=\"me-sm-3\"\n [routerLink]=\"[routers.productDetails + 'add']\"\n [queryParams]=\"{ duplicate_product_id: item.id }\">\n <i class=\"fa fa-clone edit-icon\" aria-hidden=\"true\"></i>\n </li>\n <li pTooltip=\"Feedback Questions\" tooltipPosition=\"top\"\n appendTo=\"body\"\n class=\"me-2 me-sm-3\"\n [routerLink]=\"[routers.feedbackQuestions]\"\n [queryParams]=\"{ product_id: item.id }\">\n <i class=\"fa fa-comments edit-icon\" aria-hidden=\"true\"></i>\n </li>\n </ul>\n </td>\n </tr>\n </ng-template>\n </p-table>\n @if (totalRecords === 0 && totalRecordsUnFiltered !== 0) {\n <div>\n <pw-no-data [withImage]=\"true\" [message]=\"'Search.NoDataMessage' | transloco\" [description]=\"'Search.NoDataDescription' | transloco\" >\n </pw-no-data>\n </div>\n }\n @if (totalRecords !== 0) {\n <pw-records-summary [showing]=\"dt?.value?.length ?? 0\" [total]=\"totalRecords\" />\n }\n</div>\n@if (!loading && totalRecordsUnFiltered === 0) {\n <pw-no-data [withImage]=\"true\" [message]=\"'Admin.Products.NoDataMessage' | transloco\"> </pw-no-data>\n}\n<!-- password validation modal for delete product -->\n<pw-password-validation #passwordValidationModalForProductDelete\n [destructive]=\"true\"\n (successEvent)=\"deleteProduct($event)\">\n</pw-password-validation>\n",
19178
+ template: "<div class=\"col-xs-12 text-end d-flex justify-content-between align-items-center\">\n <h2 class=\"card-title p-0\">Products</h2>\n <button *rbacAllow=\"'Pages.Admin.Product.Create'\"\n class=\"btn btn-sm btn-outline-primary\"\n [routerLink]=\"[routers.productDetails + 'add']\">\n <i class=\"fa fa-plus-circle\" aria-hidden=\"true\"></i> Setup New Product\n </button>\n</div>\n@if (loading) {\n <div class=\"w-100 text-center mt-3\">\n <p-progress-spinner> </p-progress-spinner>\n </div>\n}\n<div class=\"primeng-datatable-container actions-collapsed table-responsive mt-0\"\n [class.hideTable]=\"totalRecordsUnFiltered === 0\">\n <p-table #dt\n stateKey=\"pw-table.admin-products-list\"\n stateStorage=\"session\"\n [resizableColumns]=\"true\"\n columnResizeMode=\"expand\"\n [value]=\"products\"\n [paginator]=\"totalRecords !== 0\"\n [lazy]=\"true\"\n [rows]=\"PAGE_SIZE\"\n [totalRecords]=\"totalRecords\"\n [loading]=\"loading\"\n [filterDelay]=\"1000\"\n (onLazyLoad)=\"onLazyLoad($event)\"\n [customSort]=\"true\">\n <ng-template #caption>\n <div class=\"search-filter\">\n <div class=\"col-12 col-sm-4\">\n <p-multiselect class=\"pw-filter-select\" inputId=\"products-list-feature-keys\" placeholder=\"Filter by feature keys\"\n [options]=\"featureKeysList\"\n (onChange)=\"onSearchOptionChange($event)\"\n [showHeader]=\"true\"\n appendTo=\"body\">\n </p-multiselect>\n </div>\n <div class=\"text-end\">\n <label for=\"products-list-search\" class=\"visually-hidden\">Search Product</label>\n <p-iconfield iconPosition=\"left\">\n <p-inputicon><i class=\"fa fa-search\" aria-hidden=\"true\"></i></p-inputicon>\n <input type=\"text\"\n id=\"products-list-search\"\n name=\"products-list-search\"\n [(ngModel)]=\"searchText\"\n pInputText\n placeholder=\"Search products...\"\n (input)=\"dt.filterGlobal($event.target.value, 'contains')\"\n aria-label=\"Search products...\" />\n </p-iconfield>\n </div>\n </div>\n </ng-template>\n <ng-template #header>\n <tr class=\"head\">\n <th pResizableColumn scope=\"true\"\n pSortableColumn=\"name\">\n {{ 'Label.Name' | transloco }}\n <p-sort-icon field=\"name\"></p-sort-icon>\n </th>\n <th pResizableColumn scope=\"true\"\n pSortableColumn=\"stripe_plan_id\">\n {{ 'Admin.Products.StripePlan' | transloco }}\n <p-sort-icon field=\"stripe_plan_id\"></p-sort-icon>\n </th>\n <th pResizableColumn scope=\"true\"\n pSortableColumn=\"permission_key\">\n {{ 'Admin.Products.PermissionKey' | transloco }}\n <p-sort-icon field=\"permission_key\"></p-sort-icon>\n </th>\n <th pResizableColumn scope=\"true\"\n pSortableColumn=\"feature_key\">\n {{ 'Admin.Products.FeatureKey' | transloco }}\n <p-sort-icon field=\"feature_key\"></p-sort-icon>\n </th>\n <th pResizableColumn scope=\"true\"\n pSortableColumn=\"product_key\">\n {{ 'Admin.Products.ProductKey' | transloco }}\n <p-sort-icon field=\"product_key\"></p-sort-icon>\n </th>\n <th pResizableColumn scope=\"true\"\n pSortableColumn=\"category\">\n {{ 'Admin.Products.Category' | transloco }}\n <p-sort-icon field=\"category\"></p-sort-icon>\n </th>\n <th pResizableColumn scope=\"true\"\n pSortableColumn=\"region\">\n {{ 'Admin.Products.Region' | transloco }}\n <p-sort-icon field=\"region\"></p-sort-icon>\n </th>\n <th pResizableColumn scope=\"true\"\n pSortableColumn=\"currency\">\n {{ 'Admin.Products.Currency' | transloco }}\n <p-sort-icon field=\"currency\"></p-sort-icon>\n </th>\n <th pResizableColumn scope=\"true\"\n pSortableColumn=\"price_per_unit\">\n {{ 'Admin.Products.Price' | transloco }}\n <p-sort-icon field=\"price_per_unit\"></p-sort-icon>\n </th>\n <th pResizableColumn scope=\"true\"\n pSortableColumn=\"active\">\n {{ 'Label.IsActive' | transloco }}\n <p-sort-icon field=\"active\"></p-sort-icon>\n </th>\n <th pResizableColumn scope=\"true\"\n pSortableColumn=\"billing_frequency\">\n {{ 'Admin.Products.Billing' | transloco }}\n <p-sort-icon field=\"billing_frequency\"></p-sort-icon>\n </th>\n <th scope=\"true\"\n class=\"actions-list-two\">{{ 'Label.Actions' | transloco }}</th>\n </tr>\n </ng-template>\n <ng-template #body\n let-item>\n <tr>\n <td data-head=\"Name\">{{ item.name }}</td>\n <td data-head=\"Stripe Plan\">{{ item.stripe_plan_id }}</td>\n <td data-head=\"Permission Key\">{{ item.permission_key }}</td>\n <td data-head=\"Feature Key\">{{ item.feature_key }}</td>\n <td data-head=\"Product Key\">{{ item.product_key }}</td>\n <td data-head=\"Category\">\n <span [appDynamicBadge]=\"{ itemsArray: categories, item: item.category }\"\n color=\"warning\"\n class=\"badge\">{{ item.category }}</span>\n </td>\n <td data-head=\"Region\">\n <span [appDynamicBadge]=\"{ itemsArray: regions, item: item.region }\"\n color=\"cyan\"\n class=\"badge\">{{ item.region }}</span>\n </td>\n <td data-head=\"Currency\">\n <span [appDynamicBadge]=\"{ itemsArray: currency, item: item.currency }\"\n color=\"blue-grey\"\n class=\"badge\">{{ item.currency }}</span>\n </td>\n <td data-head=\"Price\">{{ item.price_per_unit }}</td>\n <td data-head=\"Active\">\n <span [appDynamicBadge]=\"{ itemsArray: [true, false], item: item?.active }\"\n color=\"success-danger\"\n class=\"badge\">{{ item?.active ? 'Yes' : 'No' }}</span>\n </td>\n <td data-head=\"Billing\">\n <span class=\"badge\"\n [appDynamicBadge]=\"{\n itemsArray: billingFrequency,\n item: item?.billing_frequency\n }\"\n color=\"blue-grey\">{{ item.billing_frequency }}</span>\n </td>\n <td data-head=\"Action\">\n <ul class=\"list-unstyled list-inline width-max-content\">\n <li pTooltip=\"Edit\" tooltipPosition=\"top\" appendTo=\"body\"\n class=\"me-2 me-sm-3\"\n *rbacAllow=\"'Pages.Admin.Product.Edit'\"\n [routerLink]=\"[routers.productDetails + item.id]\">\n <i class=\"fa fa-edit edit-icon\" aria-hidden=\"true\"></i>\n </li>\n <li pTooltip=\"Delete\" tooltipPosition=\"top\" appendTo=\"body\"\n class=\"me-2 me-sm-3\"\n *rbacAllow=\"'Pages.Admin.Product.Delete'\"\n (keydown.enter)=\"onDelete(item)\"\n (click)=\"onDelete(item)\">\n <i class=\"fa fa-trash delete-icon\" aria-hidden=\"true\"></i>\n </li>\n <li pTooltip=\"Users List\" tooltipPosition=\"top\" appendTo=\"body\"\n class=\"me-2 me-sm-3\"\n *rbacAllow=\"'Pages.Admin.Product.Edit'\"\n [routerLink]=\"[routers.productsUserList + item.id]\">\n <i class=\"fa fa-tasks cta1-icon\" aria-hidden=\"true\"></i>\n </li>\n <li pTooltip=\"Duplicate The Product\" tooltipPosition=\"top\" appendTo=\"body\"\n class=\"me-sm-3\"\n [routerLink]=\"[routers.productDetails + 'add']\"\n [queryParams]=\"{ duplicate_product_id: item.id }\">\n <i class=\"fa fa-clone edit-icon\" aria-hidden=\"true\"></i>\n </li>\n <li pTooltip=\"Feedback Questions\" tooltipPosition=\"top\"\n appendTo=\"body\"\n class=\"me-2 me-sm-3\"\n [routerLink]=\"[routers.feedbackQuestions]\"\n [queryParams]=\"{ product_id: item.id }\">\n <i class=\"fa fa-comments edit-icon\" aria-hidden=\"true\"></i>\n </li>\n </ul>\n </td>\n </tr>\n </ng-template>\n </p-table>\n @if (totalRecords === 0 && totalRecordsUnFiltered !== 0) {\n <div>\n <pw-no-data [withImage]=\"true\" [message]=\"'Search.NoDataMessage' | transloco\" [description]=\"'Search.NoDataDescription' | transloco\" >\n </pw-no-data>\n </div>\n }\n @if (totalRecords !== 0) {\n <pw-records-summary [showing]=\"dt?.value?.length ?? 0\" [total]=\"totalRecords\" />\n }\n</div>\n@if (!loading && totalRecordsUnFiltered === 0) {\n <pw-no-data [withImage]=\"true\" [message]=\"'Admin.Products.NoDataMessage' | transloco\"> </pw-no-data>\n}\n<!-- password validation modal for delete product -->\n<pw-password-validation #passwordValidationModalForProductDelete\n [destructive]=\"true\"\n (successEvent)=\"deleteProduct($event)\">\n</pw-password-validation>\n",
19139
19179
  styles: ["@charset \"UTF-8\";:root{--first: rgb(23 105 225);--second: rgb(54 194 131);--third: rgb(255 171 0);--text: rgb(34 34 34);--tabs_bg: rgb(23 105 225);--tabs_sub_bg: color-mix(in srgb, var(--first, rgb(23 105 225)) 85%, #000000);--tabs_text: rgb(255 255 255);--titles: rgb(34 34 34);--sidebar_bg: rgb(0, 48, 63);--sidebar_text: rgb(255 255 255);--dashboard_bg: rgb(255 255 255);--public-btn-radius: 24px}.table-responsive td{padding:6px 10px!important;line-height:1.4;vertical-align:middle;overflow-wrap:break-word}.table-responsive th{vertical-align:bottom}.table-responsive td[data-head=Name]{font-weight:600;color:#1a1d21}.table-responsive td[data-head=\"Stripe Plan\"],.table-responsive td[data-head=\"Permission Key\"],.table-responsive td[data-head=\"Feature Key\"],.table-responsive td[data-head=\"Product Key\"]{color:#5a6473;font-variant-numeric:tabular-nums}.table-responsive td[data-head=Price]{white-space:nowrap;font-variant-numeric:tabular-nums;text-align:right}.table-responsive th:nth-child(9){text-align:right}.table-responsive .badge{font-size:11px;font-weight:600;padding:2px 8px;border-radius:4px;letter-spacing:.01em}.table-responsive .badge[class*=bg-success]{background-color:#e6f4ec!important;color:#0f6b3a!important}.table-responsive .badge[class*=bg-danger]{background-color:#fbeae8!important;color:#c0392b!important}.table-responsive .badge.bg-warning{background-color:#efebe6!important;color:#725731!important}.table-responsive .badge.bg-warning-1{background-color:#edefe6!important;color:#627231!important}.table-responsive .badge.bg-warning-2{background-color:#e7efe6!important;color:#367231!important}.table-responsive .badge.bg-warning-3{background-color:#e6efeb!important;color:#317257!important}.table-responsive .badge.bg-warning-4{background-color:#e6edef!important;color:#316272!important}.table-responsive .badge.bg-warning-5{background-color:#e6e7ef!important;color:#313672!important}.table-responsive .badge.bg-warning-6{background-color:#ebe6ef!important;color:#573172!important}.table-responsive .badge.bg-warning-7{background-color:#efe6ed!important;color:#723162!important}.table-responsive .badge.bg-warning-8{background-color:#efe6e7!important;color:#723136!important}.table-responsive .badge.bg-warning-9{background-color:#efebe6!important;color:#725731!important}.table-responsive .badge.bg-warning-10{background-color:#edefe6!important;color:#627231!important}.table-responsive .badge.bg-warning-11{background-color:#e7efe6!important;color:#367231!important}.table-responsive .badge.bg-warning-12{background-color:#e6efeb!important;color:#317257!important}.table-responsive .badge.bg-warning-13{background-color:#e6edef!important;color:#316272!important}.table-responsive .badge.bg-warning-14{background-color:#e6e7ef!important;color:#313672!important}.table-responsive .badge.bg-warning-15{background-color:#ebe6ef!important;color:#573172!important}.table-responsive .badge.bg-warning-16{background-color:#efe6ed!important;color:#723162!important}.table-responsive .badge.bg-warning-17{background-color:#efe6e7!important;color:#723136!important}.table-responsive .badge.bg-warning-18{background-color:#efebe6!important;color:#725731!important}.table-responsive .badge.bg-warning-19{background-color:#edefe6!important;color:#627231!important}.table-responsive .badge.bg-warning-20{background-color:#e7efe6!important;color:#367231!important}.table-responsive .badge.bg-warning-21{background-color:#e6efeb!important;color:#317257!important}.table-responsive .badge.bg-warning-22{background-color:#e6edef!important;color:#316272!important}.table-responsive .badge.bg-warning-23{background-color:#e6e7ef!important;color:#313672!important}.table-responsive .badge.bg-warning-24{background-color:#ebe6ef!important;color:#573172!important}.table-responsive .badge.bg-cyan{background-color:#e6eeef!important;color:#316772!important}.table-responsive .badge.bg-cyan-1{background-color:#e6e8ef!important;color:#313c72!important}.table-responsive .badge.bg-cyan-2{background-color:#ebe6ef!important;color:#523172!important}.table-responsive .badge.bg-cyan-3{background-color:#efe6ee!important;color:#723167!important}.table-responsive .badge.bg-cyan-4{background-color:#efe6e8!important;color:#72313c!important}.table-responsive .badge.bg-cyan-5{background-color:#efebe6!important;color:#725231!important}.table-responsive .badge.bg-cyan-6{background-color:#eeefe6!important;color:#677231!important}.table-responsive .badge.bg-cyan-7{background-color:#e8efe6!important;color:#3c7231!important}.table-responsive .badge.bg-cyan-8{background-color:#e6efeb!important;color:#317252!important}.table-responsive .badge.bg-cyan-9{background-color:#e6eeef!important;color:#316772!important}.table-responsive .badge.bg-cyan-10{background-color:#e6e8ef!important;color:#313c72!important}.table-responsive .badge.bg-cyan-11{background-color:#ebe6ef!important;color:#523172!important}.table-responsive .badge.bg-cyan-12{background-color:#efe6ee!important;color:#723167!important}.table-responsive .badge.bg-cyan-13{background-color:#efe6e8!important;color:#72313c!important}.table-responsive .badge.bg-cyan-14{background-color:#efebe6!important;color:#725231!important}.table-responsive .badge.bg-cyan-15{background-color:#eeefe6!important;color:#677231!important}.table-responsive .badge.bg-cyan-16{background-color:#e8efe6!important;color:#3c7231!important}.table-responsive .badge.bg-cyan-17{background-color:#e6efeb!important;color:#317252!important}.table-responsive .badge.bg-cyan-18{background-color:#e6eeef!important;color:#316772!important}.table-responsive .badge.bg-cyan-19{background-color:#e6e8ef!important;color:#313c72!important}.table-responsive .badge.bg-cyan-20{background-color:#ebe6ef!important;color:#523172!important}.table-responsive .badge.bg-cyan-21{background-color:#efe6ee!important;color:#723167!important}.table-responsive .badge.bg-cyan-22{background-color:#efe6e8!important;color:#72313c!important}.table-responsive .badge.bg-cyan-23{background-color:#efebe6!important;color:#725231!important}.table-responsive .badge.bg-cyan-24{background-color:#eeefe6!important;color:#677231!important}.table-responsive .badge.bg-blue-grey{background-color:#e6e9ef!important;color:#314772!important}.table-responsive .badge.bg-blue-grey-1{background-color:#e9e6ef!important;color:#473172!important}.table-responsive .badge.bg-blue-grey-2{background-color:#efe6ef!important;color:#723172!important}.table-responsive .badge.bg-blue-grey-3{background-color:#efe6e9!important;color:#723147!important}.table-responsive .badge.bg-blue-grey-4{background-color:#efe9e6!important;color:#724731!important}.table-responsive .badge.bg-blue-grey-5{background-color:#efefe6!important;color:#727231!important}.table-responsive .badge.bg-blue-grey-6{background-color:#e9efe6!important;color:#477231!important}.table-responsive .badge.bg-blue-grey-7{background-color:#e6efe9!important;color:#317247!important}.table-responsive .badge.bg-blue-grey-8{background-color:#e6efef!important;color:#317272!important}.table-responsive .badge.bg-blue-grey-9{background-color:#e6e9ef!important;color:#314772!important}.table-responsive .badge.bg-blue-grey-10{background-color:#e9e6ef!important;color:#473172!important}.table-responsive .badge.bg-blue-grey-11{background-color:#efe6ef!important;color:#723172!important}.table-responsive .badge.bg-blue-grey-12{background-color:#efe6e9!important;color:#723147!important}.table-responsive .badge.bg-blue-grey-13{background-color:#efe9e6!important;color:#724731!important}.table-responsive .badge.bg-blue-grey-14{background-color:#efefe6!important;color:#727231!important}.table-responsive .badge.bg-blue-grey-15{background-color:#e9efe6!important;color:#477231!important}.table-responsive .badge.bg-blue-grey-16{background-color:#e6efe9!important;color:#317247!important}.table-responsive .badge.bg-blue-grey-17{background-color:#e6efef!important;color:#317272!important}.table-responsive .badge.bg-blue-grey-18{background-color:#e6e9ef!important;color:#314772!important}.table-responsive .badge.bg-blue-grey-19{background-color:#e9e6ef!important;color:#473172!important}.table-responsive .badge.bg-blue-grey-20{background-color:#efe6ef!important;color:#723172!important}.table-responsive .badge.bg-blue-grey-21{background-color:#efe6e9!important;color:#723147!important}.table-responsive .badge.bg-blue-grey-22{background-color:#efe9e6!important;color:#724731!important}.table-responsive .badge.bg-blue-grey-23{background-color:#efefe6!important;color:#727231!important}.table-responsive .badge.bg-blue-grey-24{background-color:#e9efe6!important;color:#477231!important}.table-responsive .badge.bg-cyan-default{background-color:#e6eeef!important;color:#316772!important}.table-responsive .badge.bg-cyan-default-change{background-color:#e6efeb!important;color:#317252!important}.table-responsive .badge.bg-success:before,.table-responsive .badge.bg-danger:before{content:\"\";display:inline-block;box-sizing:border-box;width:7px;height:7px;margin-right:6px;border-radius:50%;vertical-align:middle}.table-responsive .badge.bg-success:before{background-color:currentColor}.table-responsive .badge.bg-danger:before{background-color:transparent;border:1.5px solid currentColor}.width-max-content{width:max-content}\n"],
19140
19180
  dependencies: [
19141
19181
  {
@@ -19257,6 +19297,12 @@ var ProductsListComponent = class ProductsListComponent extends AppBaseComponent
19257
19297
  selector: "[pSortableColumn]",
19258
19298
  inputs: ["pSortableColumn", "pSortableColumnDisabled"]
19259
19299
  },
19300
+ {
19301
+ kind: "directive",
19302
+ type: i2$3.ResizableColumn,
19303
+ selector: "[pResizableColumn]",
19304
+ inputs: ["pResizableColumnDisabled"]
19305
+ },
19260
19306
  {
19261
19307
  kind: "component",
19262
19308
  type: i2$3.SortIcon,
@@ -19517,7 +19563,7 @@ i0.ɵɵngDeclareClassMetadata({
19517
19563
  args: [{
19518
19564
  selector: "pw-admin-products-list",
19519
19565
  standalone: false,
19520
- template: "<div class=\"col-xs-12 text-end d-flex justify-content-between align-items-center\">\n <h2 class=\"card-title p-0\">Products</h2>\n <button *rbacAllow=\"'Pages.Admin.Product.Create'\"\n class=\"btn btn-sm btn-outline-primary\"\n [routerLink]=\"[routers.productDetails + 'add']\">\n <i class=\"fa fa-plus-circle\" aria-hidden=\"true\"></i> Setup New Product\n </button>\n</div>\n@if (loading) {\n <div class=\"w-100 text-center mt-3\">\n <p-progress-spinner> </p-progress-spinner>\n </div>\n}\n<div class=\"primeng-datatable-container actions-collapsed table-responsive mt-0\"\n [class.hideTable]=\"totalRecordsUnFiltered === 0\">\n <p-table #dt\n [value]=\"products\"\n [paginator]=\"totalRecords !== 0\"\n [lazy]=\"true\"\n [rows]=\"PAGE_SIZE\"\n [totalRecords]=\"totalRecords\"\n [loading]=\"loading\"\n [filterDelay]=\"1000\"\n (onLazyLoad)=\"onLazyLoad($event)\"\n [customSort]=\"true\">\n <ng-template #caption>\n <div class=\"search-filter\">\n <div class=\"col-12 col-sm-4\">\n <p-multiselect class=\"pw-filter-select\" inputId=\"products-list-feature-keys\" placeholder=\"Filter by feature keys\"\n [options]=\"featureKeysList\"\n (onChange)=\"onSearchOptionChange($event)\"\n [showHeader]=\"true\"\n appendTo=\"body\">\n </p-multiselect>\n </div>\n <div class=\"text-end\">\n <label for=\"products-list-search\" class=\"visually-hidden\">Search Product</label>\n <p-iconfield iconPosition=\"left\">\n <p-inputicon><i class=\"fa fa-search\" aria-hidden=\"true\"></i></p-inputicon>\n <input type=\"text\"\n id=\"products-list-search\"\n name=\"products-list-search\"\n [(ngModel)]=\"searchText\"\n pInputText\n placeholder=\"Search products...\"\n (input)=\"dt.filterGlobal($event.target.value, 'contains')\"\n aria-label=\"Search products...\" />\n </p-iconfield>\n </div>\n </div>\n </ng-template>\n <ng-template #header>\n <tr class=\"head\">\n <th scope=\"true\"\n pSortableColumn=\"name\">\n {{ 'Label.Name' | transloco }}\n <p-sort-icon field=\"name\"></p-sort-icon>\n </th>\n <th scope=\"true\"\n pSortableColumn=\"stripe_plan_id\">\n {{ 'Admin.Products.StripePlan' | transloco }}\n <p-sort-icon field=\"stripe_plan_id\"></p-sort-icon>\n </th>\n <th scope=\"true\"\n pSortableColumn=\"permission_key\">\n {{ 'Admin.Products.PermissionKey' | transloco }}\n <p-sort-icon field=\"permission_key\"></p-sort-icon>\n </th>\n <th scope=\"true\"\n pSortableColumn=\"feature_key\">\n {{ 'Admin.Products.FeatureKey' | transloco }}\n <p-sort-icon field=\"feature_key\"></p-sort-icon>\n </th>\n <th scope=\"true\"\n pSortableColumn=\"product_key\">\n {{ 'Admin.Products.ProductKey' | transloco }}\n <p-sort-icon field=\"product_key\"></p-sort-icon>\n </th>\n <th scope=\"true\"\n pSortableColumn=\"category\">\n {{ 'Admin.Products.Category' | transloco }}\n <p-sort-icon field=\"category\"></p-sort-icon>\n </th>\n <th scope=\"true\"\n pSortableColumn=\"region\">\n {{ 'Admin.Products.Region' | transloco }}\n <p-sort-icon field=\"region\"></p-sort-icon>\n </th>\n <th scope=\"true\"\n pSortableColumn=\"currency\">\n {{ 'Admin.Products.Currency' | transloco }}\n <p-sort-icon field=\"currency\"></p-sort-icon>\n </th>\n <th scope=\"true\"\n pSortableColumn=\"price_per_unit\">\n {{ 'Admin.Products.Price' | transloco }}\n <p-sort-icon field=\"price_per_unit\"></p-sort-icon>\n </th>\n <th scope=\"true\"\n pSortableColumn=\"active\">\n {{ 'Label.IsActive' | transloco }}\n <p-sort-icon field=\"active\"></p-sort-icon>\n </th>\n <th scope=\"true\"\n pSortableColumn=\"billing_frequency\">\n {{ 'Admin.Products.Billing' | transloco }}\n <p-sort-icon field=\"billing_frequency\"></p-sort-icon>\n </th>\n <th scope=\"true\"\n class=\"actions-list-two\">{{ 'Label.Actions' | transloco }}</th>\n </tr>\n </ng-template>\n <ng-template #body\n let-item>\n <tr>\n <td data-head=\"Name\">{{ item.name }}</td>\n <td data-head=\"Stripe Plan\">{{ item.stripe_plan_id }}</td>\n <td data-head=\"Permission Key\">{{ item.permission_key }}</td>\n <td data-head=\"Feature Key\">{{ item.feature_key }}</td>\n <td data-head=\"Product Key\">{{ item.product_key }}</td>\n <td data-head=\"Category\">\n <span [appDynamicBadge]=\"{ itemsArray: categories, item: item.category }\"\n color=\"warning\"\n class=\"badge\">{{ item.category }}</span>\n </td>\n <td data-head=\"Region\">\n <span [appDynamicBadge]=\"{ itemsArray: regions, item: item.region }\"\n color=\"cyan\"\n class=\"badge\">{{ item.region }}</span>\n </td>\n <td data-head=\"Currency\">\n <span [appDynamicBadge]=\"{ itemsArray: currency, item: item.currency }\"\n color=\"blue-grey\"\n class=\"badge\">{{ item.currency }}</span>\n </td>\n <td data-head=\"Price\">{{ item.price_per_unit }}</td>\n <td data-head=\"Active\">\n <span [appDynamicBadge]=\"{ itemsArray: [true, false], item: item?.active }\"\n color=\"success-danger\"\n class=\"badge\">{{ item?.active ? 'Yes' : 'No' }}</span>\n </td>\n <td data-head=\"Billing\">\n <span class=\"badge\"\n [appDynamicBadge]=\"{\n itemsArray: billingFrequency,\n item: item?.billing_frequency\n }\"\n color=\"blue-grey\">{{ item.billing_frequency }}</span>\n </td>\n <td data-head=\"Action\">\n <ul class=\"list-unstyled list-inline width-max-content\">\n <li pTooltip=\"Edit\" tooltipPosition=\"top\" appendTo=\"body\"\n class=\"me-2 me-sm-3\"\n *rbacAllow=\"'Pages.Admin.Product.Edit'\"\n [routerLink]=\"[routers.productDetails + item.id]\">\n <i class=\"fa fa-edit edit-icon\" aria-hidden=\"true\"></i>\n </li>\n <li pTooltip=\"Delete\" tooltipPosition=\"top\" appendTo=\"body\"\n class=\"me-2 me-sm-3\"\n *rbacAllow=\"'Pages.Admin.Product.Delete'\"\n (keydown.enter)=\"onDelete(item)\"\n (click)=\"onDelete(item)\">\n <i class=\"fa fa-trash delete-icon\" aria-hidden=\"true\"></i>\n </li>\n <li pTooltip=\"Users List\" tooltipPosition=\"top\" appendTo=\"body\"\n class=\"me-2 me-sm-3\"\n *rbacAllow=\"'Pages.Admin.Product.Edit'\"\n [routerLink]=\"[routers.productsUserList + item.id]\">\n <i class=\"fa fa-tasks cta1-icon\" aria-hidden=\"true\"></i>\n </li>\n <li pTooltip=\"Duplicate The Product\" tooltipPosition=\"top\" appendTo=\"body\"\n class=\"me-sm-3\"\n [routerLink]=\"[routers.productDetails + 'add']\"\n [queryParams]=\"{ duplicate_product_id: item.id }\">\n <i class=\"fa fa-clone edit-icon\" aria-hidden=\"true\"></i>\n </li>\n <li pTooltip=\"Feedback Questions\" tooltipPosition=\"top\"\n appendTo=\"body\"\n class=\"me-2 me-sm-3\"\n [routerLink]=\"[routers.feedbackQuestions]\"\n [queryParams]=\"{ product_id: item.id }\">\n <i class=\"fa fa-comments edit-icon\" aria-hidden=\"true\"></i>\n </li>\n </ul>\n </td>\n </tr>\n </ng-template>\n </p-table>\n @if (totalRecords === 0 && totalRecordsUnFiltered !== 0) {\n <div>\n <pw-no-data [withImage]=\"true\" [message]=\"'Search.NoDataMessage' | transloco\" [description]=\"'Search.NoDataDescription' | transloco\" >\n </pw-no-data>\n </div>\n }\n @if (totalRecords !== 0) {\n <pw-records-summary [showing]=\"dt?.value?.length ?? 0\" [total]=\"totalRecords\" />\n }\n</div>\n@if (!loading && totalRecordsUnFiltered === 0) {\n <pw-no-data [withImage]=\"true\" [message]=\"'Admin.Products.NoDataMessage' | transloco\"> </pw-no-data>\n}\n<!-- password validation modal for delete product -->\n<pw-password-validation #passwordValidationModalForProductDelete\n [destructive]=\"true\"\n (successEvent)=\"deleteProduct($event)\">\n</pw-password-validation>\n",
19566
+ template: "<div class=\"col-xs-12 text-end d-flex justify-content-between align-items-center\">\n <h2 class=\"card-title p-0\">Products</h2>\n <button *rbacAllow=\"'Pages.Admin.Product.Create'\"\n class=\"btn btn-sm btn-outline-primary\"\n [routerLink]=\"[routers.productDetails + 'add']\">\n <i class=\"fa fa-plus-circle\" aria-hidden=\"true\"></i> Setup New Product\n </button>\n</div>\n@if (loading) {\n <div class=\"w-100 text-center mt-3\">\n <p-progress-spinner> </p-progress-spinner>\n </div>\n}\n<div class=\"primeng-datatable-container actions-collapsed table-responsive mt-0\"\n [class.hideTable]=\"totalRecordsUnFiltered === 0\">\n <p-table #dt\n stateKey=\"pw-table.admin-products-list\"\n stateStorage=\"session\"\n [resizableColumns]=\"true\"\n columnResizeMode=\"expand\"\n [value]=\"products\"\n [paginator]=\"totalRecords !== 0\"\n [lazy]=\"true\"\n [rows]=\"PAGE_SIZE\"\n [totalRecords]=\"totalRecords\"\n [loading]=\"loading\"\n [filterDelay]=\"1000\"\n (onLazyLoad)=\"onLazyLoad($event)\"\n [customSort]=\"true\">\n <ng-template #caption>\n <div class=\"search-filter\">\n <div class=\"col-12 col-sm-4\">\n <p-multiselect class=\"pw-filter-select\" inputId=\"products-list-feature-keys\" placeholder=\"Filter by feature keys\"\n [options]=\"featureKeysList\"\n (onChange)=\"onSearchOptionChange($event)\"\n [showHeader]=\"true\"\n appendTo=\"body\">\n </p-multiselect>\n </div>\n <div class=\"text-end\">\n <label for=\"products-list-search\" class=\"visually-hidden\">Search Product</label>\n <p-iconfield iconPosition=\"left\">\n <p-inputicon><i class=\"fa fa-search\" aria-hidden=\"true\"></i></p-inputicon>\n <input type=\"text\"\n id=\"products-list-search\"\n name=\"products-list-search\"\n [(ngModel)]=\"searchText\"\n pInputText\n placeholder=\"Search products...\"\n (input)=\"dt.filterGlobal($event.target.value, 'contains')\"\n aria-label=\"Search products...\" />\n </p-iconfield>\n </div>\n </div>\n </ng-template>\n <ng-template #header>\n <tr class=\"head\">\n <th pResizableColumn scope=\"true\"\n pSortableColumn=\"name\">\n {{ 'Label.Name' | transloco }}\n <p-sort-icon field=\"name\"></p-sort-icon>\n </th>\n <th pResizableColumn scope=\"true\"\n pSortableColumn=\"stripe_plan_id\">\n {{ 'Admin.Products.StripePlan' | transloco }}\n <p-sort-icon field=\"stripe_plan_id\"></p-sort-icon>\n </th>\n <th pResizableColumn scope=\"true\"\n pSortableColumn=\"permission_key\">\n {{ 'Admin.Products.PermissionKey' | transloco }}\n <p-sort-icon field=\"permission_key\"></p-sort-icon>\n </th>\n <th pResizableColumn scope=\"true\"\n pSortableColumn=\"feature_key\">\n {{ 'Admin.Products.FeatureKey' | transloco }}\n <p-sort-icon field=\"feature_key\"></p-sort-icon>\n </th>\n <th pResizableColumn scope=\"true\"\n pSortableColumn=\"product_key\">\n {{ 'Admin.Products.ProductKey' | transloco }}\n <p-sort-icon field=\"product_key\"></p-sort-icon>\n </th>\n <th pResizableColumn scope=\"true\"\n pSortableColumn=\"category\">\n {{ 'Admin.Products.Category' | transloco }}\n <p-sort-icon field=\"category\"></p-sort-icon>\n </th>\n <th pResizableColumn scope=\"true\"\n pSortableColumn=\"region\">\n {{ 'Admin.Products.Region' | transloco }}\n <p-sort-icon field=\"region\"></p-sort-icon>\n </th>\n <th pResizableColumn scope=\"true\"\n pSortableColumn=\"currency\">\n {{ 'Admin.Products.Currency' | transloco }}\n <p-sort-icon field=\"currency\"></p-sort-icon>\n </th>\n <th pResizableColumn scope=\"true\"\n pSortableColumn=\"price_per_unit\">\n {{ 'Admin.Products.Price' | transloco }}\n <p-sort-icon field=\"price_per_unit\"></p-sort-icon>\n </th>\n <th pResizableColumn scope=\"true\"\n pSortableColumn=\"active\">\n {{ 'Label.IsActive' | transloco }}\n <p-sort-icon field=\"active\"></p-sort-icon>\n </th>\n <th pResizableColumn scope=\"true\"\n pSortableColumn=\"billing_frequency\">\n {{ 'Admin.Products.Billing' | transloco }}\n <p-sort-icon field=\"billing_frequency\"></p-sort-icon>\n </th>\n <th scope=\"true\"\n class=\"actions-list-two\">{{ 'Label.Actions' | transloco }}</th>\n </tr>\n </ng-template>\n <ng-template #body\n let-item>\n <tr>\n <td data-head=\"Name\">{{ item.name }}</td>\n <td data-head=\"Stripe Plan\">{{ item.stripe_plan_id }}</td>\n <td data-head=\"Permission Key\">{{ item.permission_key }}</td>\n <td data-head=\"Feature Key\">{{ item.feature_key }}</td>\n <td data-head=\"Product Key\">{{ item.product_key }}</td>\n <td data-head=\"Category\">\n <span [appDynamicBadge]=\"{ itemsArray: categories, item: item.category }\"\n color=\"warning\"\n class=\"badge\">{{ item.category }}</span>\n </td>\n <td data-head=\"Region\">\n <span [appDynamicBadge]=\"{ itemsArray: regions, item: item.region }\"\n color=\"cyan\"\n class=\"badge\">{{ item.region }}</span>\n </td>\n <td data-head=\"Currency\">\n <span [appDynamicBadge]=\"{ itemsArray: currency, item: item.currency }\"\n color=\"blue-grey\"\n class=\"badge\">{{ item.currency }}</span>\n </td>\n <td data-head=\"Price\">{{ item.price_per_unit }}</td>\n <td data-head=\"Active\">\n <span [appDynamicBadge]=\"{ itemsArray: [true, false], item: item?.active }\"\n color=\"success-danger\"\n class=\"badge\">{{ item?.active ? 'Yes' : 'No' }}</span>\n </td>\n <td data-head=\"Billing\">\n <span class=\"badge\"\n [appDynamicBadge]=\"{\n itemsArray: billingFrequency,\n item: item?.billing_frequency\n }\"\n color=\"blue-grey\">{{ item.billing_frequency }}</span>\n </td>\n <td data-head=\"Action\">\n <ul class=\"list-unstyled list-inline width-max-content\">\n <li pTooltip=\"Edit\" tooltipPosition=\"top\" appendTo=\"body\"\n class=\"me-2 me-sm-3\"\n *rbacAllow=\"'Pages.Admin.Product.Edit'\"\n [routerLink]=\"[routers.productDetails + item.id]\">\n <i class=\"fa fa-edit edit-icon\" aria-hidden=\"true\"></i>\n </li>\n <li pTooltip=\"Delete\" tooltipPosition=\"top\" appendTo=\"body\"\n class=\"me-2 me-sm-3\"\n *rbacAllow=\"'Pages.Admin.Product.Delete'\"\n (keydown.enter)=\"onDelete(item)\"\n (click)=\"onDelete(item)\">\n <i class=\"fa fa-trash delete-icon\" aria-hidden=\"true\"></i>\n </li>\n <li pTooltip=\"Users List\" tooltipPosition=\"top\" appendTo=\"body\"\n class=\"me-2 me-sm-3\"\n *rbacAllow=\"'Pages.Admin.Product.Edit'\"\n [routerLink]=\"[routers.productsUserList + item.id]\">\n <i class=\"fa fa-tasks cta1-icon\" aria-hidden=\"true\"></i>\n </li>\n <li pTooltip=\"Duplicate The Product\" tooltipPosition=\"top\" appendTo=\"body\"\n class=\"me-sm-3\"\n [routerLink]=\"[routers.productDetails + 'add']\"\n [queryParams]=\"{ duplicate_product_id: item.id }\">\n <i class=\"fa fa-clone edit-icon\" aria-hidden=\"true\"></i>\n </li>\n <li pTooltip=\"Feedback Questions\" tooltipPosition=\"top\"\n appendTo=\"body\"\n class=\"me-2 me-sm-3\"\n [routerLink]=\"[routers.feedbackQuestions]\"\n [queryParams]=\"{ product_id: item.id }\">\n <i class=\"fa fa-comments edit-icon\" aria-hidden=\"true\"></i>\n </li>\n </ul>\n </td>\n </tr>\n </ng-template>\n </p-table>\n @if (totalRecords === 0 && totalRecordsUnFiltered !== 0) {\n <div>\n <pw-no-data [withImage]=\"true\" [message]=\"'Search.NoDataMessage' | transloco\" [description]=\"'Search.NoDataDescription' | transloco\" >\n </pw-no-data>\n </div>\n }\n @if (totalRecords !== 0) {\n <pw-records-summary [showing]=\"dt?.value?.length ?? 0\" [total]=\"totalRecords\" />\n }\n</div>\n@if (!loading && totalRecordsUnFiltered === 0) {\n <pw-no-data [withImage]=\"true\" [message]=\"'Admin.Products.NoDataMessage' | transloco\"> </pw-no-data>\n}\n<!-- password validation modal for delete product -->\n<pw-password-validation #passwordValidationModalForProductDelete\n [destructive]=\"true\"\n (successEvent)=\"deleteProduct($event)\">\n</pw-password-validation>\n",
19521
19567
  styles: ["@charset \"UTF-8\";:root{--first: rgb(23 105 225);--second: rgb(54 194 131);--third: rgb(255 171 0);--text: rgb(34 34 34);--tabs_bg: rgb(23 105 225);--tabs_sub_bg: color-mix(in srgb, var(--first, rgb(23 105 225)) 85%, #000000);--tabs_text: rgb(255 255 255);--titles: rgb(34 34 34);--sidebar_bg: rgb(0, 48, 63);--sidebar_text: rgb(255 255 255);--dashboard_bg: rgb(255 255 255);--public-btn-radius: 24px}.table-responsive td{padding:6px 10px!important;line-height:1.4;vertical-align:middle;overflow-wrap:break-word}.table-responsive th{vertical-align:bottom}.table-responsive td[data-head=Name]{font-weight:600;color:#1a1d21}.table-responsive td[data-head=\"Stripe Plan\"],.table-responsive td[data-head=\"Permission Key\"],.table-responsive td[data-head=\"Feature Key\"],.table-responsive td[data-head=\"Product Key\"]{color:#5a6473;font-variant-numeric:tabular-nums}.table-responsive td[data-head=Price]{white-space:nowrap;font-variant-numeric:tabular-nums;text-align:right}.table-responsive th:nth-child(9){text-align:right}.table-responsive .badge{font-size:11px;font-weight:600;padding:2px 8px;border-radius:4px;letter-spacing:.01em}.table-responsive .badge[class*=bg-success]{background-color:#e6f4ec!important;color:#0f6b3a!important}.table-responsive .badge[class*=bg-danger]{background-color:#fbeae8!important;color:#c0392b!important}.table-responsive .badge.bg-warning{background-color:#efebe6!important;color:#725731!important}.table-responsive .badge.bg-warning-1{background-color:#edefe6!important;color:#627231!important}.table-responsive .badge.bg-warning-2{background-color:#e7efe6!important;color:#367231!important}.table-responsive .badge.bg-warning-3{background-color:#e6efeb!important;color:#317257!important}.table-responsive .badge.bg-warning-4{background-color:#e6edef!important;color:#316272!important}.table-responsive .badge.bg-warning-5{background-color:#e6e7ef!important;color:#313672!important}.table-responsive .badge.bg-warning-6{background-color:#ebe6ef!important;color:#573172!important}.table-responsive .badge.bg-warning-7{background-color:#efe6ed!important;color:#723162!important}.table-responsive .badge.bg-warning-8{background-color:#efe6e7!important;color:#723136!important}.table-responsive .badge.bg-warning-9{background-color:#efebe6!important;color:#725731!important}.table-responsive .badge.bg-warning-10{background-color:#edefe6!important;color:#627231!important}.table-responsive .badge.bg-warning-11{background-color:#e7efe6!important;color:#367231!important}.table-responsive .badge.bg-warning-12{background-color:#e6efeb!important;color:#317257!important}.table-responsive .badge.bg-warning-13{background-color:#e6edef!important;color:#316272!important}.table-responsive .badge.bg-warning-14{background-color:#e6e7ef!important;color:#313672!important}.table-responsive .badge.bg-warning-15{background-color:#ebe6ef!important;color:#573172!important}.table-responsive .badge.bg-warning-16{background-color:#efe6ed!important;color:#723162!important}.table-responsive .badge.bg-warning-17{background-color:#efe6e7!important;color:#723136!important}.table-responsive .badge.bg-warning-18{background-color:#efebe6!important;color:#725731!important}.table-responsive .badge.bg-warning-19{background-color:#edefe6!important;color:#627231!important}.table-responsive .badge.bg-warning-20{background-color:#e7efe6!important;color:#367231!important}.table-responsive .badge.bg-warning-21{background-color:#e6efeb!important;color:#317257!important}.table-responsive .badge.bg-warning-22{background-color:#e6edef!important;color:#316272!important}.table-responsive .badge.bg-warning-23{background-color:#e6e7ef!important;color:#313672!important}.table-responsive .badge.bg-warning-24{background-color:#ebe6ef!important;color:#573172!important}.table-responsive .badge.bg-cyan{background-color:#e6eeef!important;color:#316772!important}.table-responsive .badge.bg-cyan-1{background-color:#e6e8ef!important;color:#313c72!important}.table-responsive .badge.bg-cyan-2{background-color:#ebe6ef!important;color:#523172!important}.table-responsive .badge.bg-cyan-3{background-color:#efe6ee!important;color:#723167!important}.table-responsive .badge.bg-cyan-4{background-color:#efe6e8!important;color:#72313c!important}.table-responsive .badge.bg-cyan-5{background-color:#efebe6!important;color:#725231!important}.table-responsive .badge.bg-cyan-6{background-color:#eeefe6!important;color:#677231!important}.table-responsive .badge.bg-cyan-7{background-color:#e8efe6!important;color:#3c7231!important}.table-responsive .badge.bg-cyan-8{background-color:#e6efeb!important;color:#317252!important}.table-responsive .badge.bg-cyan-9{background-color:#e6eeef!important;color:#316772!important}.table-responsive .badge.bg-cyan-10{background-color:#e6e8ef!important;color:#313c72!important}.table-responsive .badge.bg-cyan-11{background-color:#ebe6ef!important;color:#523172!important}.table-responsive .badge.bg-cyan-12{background-color:#efe6ee!important;color:#723167!important}.table-responsive .badge.bg-cyan-13{background-color:#efe6e8!important;color:#72313c!important}.table-responsive .badge.bg-cyan-14{background-color:#efebe6!important;color:#725231!important}.table-responsive .badge.bg-cyan-15{background-color:#eeefe6!important;color:#677231!important}.table-responsive .badge.bg-cyan-16{background-color:#e8efe6!important;color:#3c7231!important}.table-responsive .badge.bg-cyan-17{background-color:#e6efeb!important;color:#317252!important}.table-responsive .badge.bg-cyan-18{background-color:#e6eeef!important;color:#316772!important}.table-responsive .badge.bg-cyan-19{background-color:#e6e8ef!important;color:#313c72!important}.table-responsive .badge.bg-cyan-20{background-color:#ebe6ef!important;color:#523172!important}.table-responsive .badge.bg-cyan-21{background-color:#efe6ee!important;color:#723167!important}.table-responsive .badge.bg-cyan-22{background-color:#efe6e8!important;color:#72313c!important}.table-responsive .badge.bg-cyan-23{background-color:#efebe6!important;color:#725231!important}.table-responsive .badge.bg-cyan-24{background-color:#eeefe6!important;color:#677231!important}.table-responsive .badge.bg-blue-grey{background-color:#e6e9ef!important;color:#314772!important}.table-responsive .badge.bg-blue-grey-1{background-color:#e9e6ef!important;color:#473172!important}.table-responsive .badge.bg-blue-grey-2{background-color:#efe6ef!important;color:#723172!important}.table-responsive .badge.bg-blue-grey-3{background-color:#efe6e9!important;color:#723147!important}.table-responsive .badge.bg-blue-grey-4{background-color:#efe9e6!important;color:#724731!important}.table-responsive .badge.bg-blue-grey-5{background-color:#efefe6!important;color:#727231!important}.table-responsive .badge.bg-blue-grey-6{background-color:#e9efe6!important;color:#477231!important}.table-responsive .badge.bg-blue-grey-7{background-color:#e6efe9!important;color:#317247!important}.table-responsive .badge.bg-blue-grey-8{background-color:#e6efef!important;color:#317272!important}.table-responsive .badge.bg-blue-grey-9{background-color:#e6e9ef!important;color:#314772!important}.table-responsive .badge.bg-blue-grey-10{background-color:#e9e6ef!important;color:#473172!important}.table-responsive .badge.bg-blue-grey-11{background-color:#efe6ef!important;color:#723172!important}.table-responsive .badge.bg-blue-grey-12{background-color:#efe6e9!important;color:#723147!important}.table-responsive .badge.bg-blue-grey-13{background-color:#efe9e6!important;color:#724731!important}.table-responsive .badge.bg-blue-grey-14{background-color:#efefe6!important;color:#727231!important}.table-responsive .badge.bg-blue-grey-15{background-color:#e9efe6!important;color:#477231!important}.table-responsive .badge.bg-blue-grey-16{background-color:#e6efe9!important;color:#317247!important}.table-responsive .badge.bg-blue-grey-17{background-color:#e6efef!important;color:#317272!important}.table-responsive .badge.bg-blue-grey-18{background-color:#e6e9ef!important;color:#314772!important}.table-responsive .badge.bg-blue-grey-19{background-color:#e9e6ef!important;color:#473172!important}.table-responsive .badge.bg-blue-grey-20{background-color:#efe6ef!important;color:#723172!important}.table-responsive .badge.bg-blue-grey-21{background-color:#efe6e9!important;color:#723147!important}.table-responsive .badge.bg-blue-grey-22{background-color:#efe9e6!important;color:#724731!important}.table-responsive .badge.bg-blue-grey-23{background-color:#efefe6!important;color:#727231!important}.table-responsive .badge.bg-blue-grey-24{background-color:#e9efe6!important;color:#477231!important}.table-responsive .badge.bg-cyan-default{background-color:#e6eeef!important;color:#316772!important}.table-responsive .badge.bg-cyan-default-change{background-color:#e6efeb!important;color:#317252!important}.table-responsive .badge.bg-success:before,.table-responsive .badge.bg-danger:before{content:\"\";display:inline-block;box-sizing:border-box;width:7px;height:7px;margin-right:6px;border-radius:50%;vertical-align:middle}.table-responsive .badge.bg-success:before{background-color:currentColor}.table-responsive .badge.bg-danger:before{background-color:transparent;border:1.5px solid currentColor}.width-max-content{width:max-content}\n"]
19522
19568
  }]
19523
19569
  }],
@@ -23094,7 +23140,7 @@ var SubscriptionUsersComponent = class SubscriptionUsersComponent extends AppBas
23094
23140
  ],
23095
23141
  usesInheritance: true,
23096
23142
  ngImport: i0,
23097
- template: "<div class=\"w-100 text-center mt-3\">\n @if (!isLoaded) {\n <p-progress-spinner></p-progress-spinner>\n }\n</div>\n@if (!isAddEnabled && canShowSubscriptionActions && isUserSubscriptionSuperAdmin) {\n <div class=\"text-end mb-2\">\n <button class=\"btn btn-sm btn-outline-primary\" (click)=\"isAddEnabled = true\">\n <i class=\"fa fa-plus-circle\" aria-hidden=\"true\"></i> Add Members\n </button>\n </div>\n}\n@if (!isAddEnabled) {\n <section id=\"members\"\n >\n <div [class.hideTable]=\"totalUnfilteredCount === 0\"\n class=\"primeng-datatable-container actions-collapsed table-responsive mt-0\">\n <p-table #dt\n [value]=\"subscriptionMembers\"\n [paginator]=\"totalRecords !== 0\"\n [rows]=\"PAGE_SIZE\"\n [lazy]=\"true\"\n [totalRecords]=\"totalRecords\"\n [loading]=\"loading\"\n [filterDelay]=\"1000\"\n [customSort]=\"true\"\n (onLazyLoad)=\"onLazyLoad($event)\">\n <ng-template #caption>\n <div class=\"text-end\">\n <label for=\"subscription-users-search\" class=\"visually-hidden\">Search subscription users</label>\n <p-iconfield iconPosition=\"left\">\n <p-inputicon><i class=\"fa fa-search\" aria-hidden=\"true\"></i></p-inputicon>\n <input id=\"subscription-users-search\"\n name=\"subscription-users-search\"\n [(ngModel)]=\"searchText\"\n (input)=\"dt.filterGlobal($event.target.value, 'contains')\"\n type=\"text\"\n pInputText\n placeholder=\"Search subscription users...\"\n aria-label=\"Search subscription users...\" />\n </p-iconfield>\n </div>\n </ng-template>\n <ng-template #header>\n <tr>\n <th scope=\"true\"\n pSortableColumn=\"id\">\n {{ 'Admin.Users.Id' | transloco }}\n <p-sort-icon field=\"id\"></p-sort-icon>\n </th>\n <th scope=\"true\"\n pSortableColumn=\"first_name\">\n {{ 'Label.FirstName' | transloco }}\n </th>\n <th scope=\"true\"\n pSortableColumn=\"last_name\">\n {{ 'Label.LastName' | transloco }}\n <p-sort-icon field=\"last_name\"></p-sort-icon>\n </th>\n <th scope=\"true\"\n pSortableColumn=\"email\">\n {{ 'Label.Email' | transloco }}\n <p-sort-icon field=\"email\"></p-sort-icon>\n </th>\n <th scope=\"true\"\n pSortableColumn=\"slug\">\n {{ 'Admin.Subscriptions.NickName' | transloco }}\n <p-sort-icon field=\"slug\"></p-sort-icon>\n </th>\n <th scope=\"true\"\n pSortableColumn=\"has_password\">\n {{ 'Admin.Subscriptions.EmailConfirmed' | transloco }}\n <p-sort-icon field=\"has_password\"></p-sort-icon>\n </th>\n <th scope=\"true\"\n pSortableColumn=\"last_sign_in_at\">\n {{ 'Admin.Subscriptions.LastLogin' | transloco }}\n <p-sort-icon field=\"last_sign_in_at\"></p-sort-icon>\n </th>\n <th scope=\"true\" class=\"actions-list-two\">\n {{ 'Label.Actions' | transloco }}\n </th>\n </tr>\n </ng-template>\n <ng-template #body\n let-user>\n <tr>\n <td data-head=\"Id\">{{ user.id }}</td>\n <td data-head=\"First Name\">\n <span class=\"first-name\">{{ user.first_name }}</span>\n @if (subscriptionOwnerUserId === user.id) {\n <span *rbacAllow=\"'Pages.Alpha'\" class=\"badge bg-primary mx-1\"> Owner </span>\n }\n @if (subscriptionAdmins?.includes(user?.id)) {\n <span class=\"badge bg-success mx-1 admin-badge\"> Admin </span>\n }\n \n </td>\n <td data-head=\"Last Name\">\n {{ user.last_name }}\n @if (user?.alpha) {\n <span\n [pTooltip]=\"'Admin.Users.Tooltip.AlphaIcon'|transloco\"\n tooltipPosition=\"top\"\n appendTo=\"body\">\n <i class=\"fa-regular fa-square-a alpha-beta text-warning\"></i>\n </span>\n }\n @if (user?.beta) {\n <span\n [pTooltip]=\"'Admin.Users.Tooltip.BetaIcon'|transloco\"\n class=\"ms-2\"\n tooltipPosition=\"top\"\n appendTo=\"body\">\n <i class=\"fa-regular fa-square-b alpha-beta text-primary\"></i>\n </span>\n }\n @if (user?.cognito_sso_activated) {\n <span\n class=\"ms-2\"\n [pTooltip]=\"'Admin.Users.Tooltip.Cognito' | transloco\"\n tooltipPosition=\"top\"\n appendTo=\"body\">\n <i class=\"fa fa-cloud success\" ></i>\n </span>\n }\n </td>\n <td data-head=\"Email\">{{ user.email }}</td>\n <td data-head=\"Nick Name\">\n <a [routerLink]=\"['/members', user.slug]\">{{ user.slug }}</a>\n </td>\n <td data-head=\"Email Confirm\">\n <span [appDynamicBadge]=\"{ itemsArray: [true, false], item: user?.has_password }\"\n color=\"success-danger\"\n class=\"badge\">\n {{ user?.has_password ? 'Yes' : 'No' }}\n </span>\n @if (user?.blocked) {\n <span\n [pTooltip]=\"'This user has been blocked'\"\n class=\"ms-2\"\n tooltipPosition=\"top\"\n appendTo=\"body\">\n <i class=\"fa-solid fa-hexagon-exclamation text-danger hexa-warning\"></i>\n </span>\n }\n </td>\n <td data-head=\"Last Login\">\n @if (user?.current_sign_in_at | isOnline) {\n <pw-online-indicator [lastSeen]=\"user.current_sign_in_at\" />\n } @else if (user?.current_sign_in_at) {\n <span>\n <span>\n {{ user.current_sign_in_at | dateFormat }}\n </span>\n <span>\n &nbsp;({{ user.current_sign_in_at | sinceAgo }})\n </span>\n </span>\n } @else {\n <span>\n <span>\n {{ user.last_sign_in_at | dateFormat }}\n </span>\n @if (user.last_sign_in_at) {\n <span>\n &nbsp;({{ user.last_sign_in_at | sinceAgo }})\n </span>\n }\n </span>\n }\n </td>\n <td data-head=\"Action\">\n <ul class=\"list-unstyled list-inline list-action\">\n <li *rbacAllow=\"'Pages.Alpha'\" pTooltip=\"Impersonate this user\" tooltipPosition=\"top\" appendTo=\"body\" class=\"me-2 me-sm-3\">\n <i (click)=\"onImpersonate(user)\" (keydown.enter)=\"onImpersonate(user)\" class=\"fas fa-people-arrows fa-lg\" aria-hidden=\"true\"></i>\n </li>\n @if (subscriptionOwnerUserId !== user.id) {\n <li *rbacAllow=\"'Pages.Alpha'\" pTooltip=\"Set this user as new owner\" tooltipPosition=\"top\" appendTo=\"body\" class=\"me-2 me-sm-3\">\n <i (click)=\"onChangeOwner(user)\" (keydown.enter)=\"onChangeOwner(user)\" class=\"fa fa-key warning fa-lg\" aria-hidden=\"true\"></i>\n </li>\n }\n @if (user?.enable_two_factor_authenticator) {\n <li *rbacAllow=\"'Pages.Alpha'\"\n (click)=\"disable2fa(user?.id)\"\n (keydown.enter)=\"disable2fa(user?.id)\"\n pTooltip=\"Disable 2FA\"\n tooltipPosition=\"top\"\n appendTo=\"body\"\n class=\"me-2 me-sm-3 success\">\n <i class=\"fa fa-lock\"\n aria-hidden=\"true\"></i>\n </li>\n }\n @if (canShowSubscriptionActions && isUserSubscriptionSuperAdmin) {\n <!-- Make Admin -->\n @if (!subscriptionAdmins?.includes(user.id)) {\n <li pTooltip=\"Make Admin\"\n tooltipPosition=\"top\"\n appendTo=\"body\"\n class=\"me-2 me-sm-3 mx-2\"\n >\n <i\n class=\"fa fa-user-crown fa-lg success\"\n (click)=\"makeAdmin(user, true)\"\n (keydown.enter)=\"makeAdmin(users, true)\"\n aria-hidden=\"true\"\n ></i>\n </li>\n }\n <li></li>\n <!-- Remove Admin -->\n @if (subscriptionAdmins?.includes(user.id)) {\n <li pTooltip=\"Remove Admin\"\n tooltipPosition=\"top\"\n appendTo=\"body\"\n class=\"me-2 me-sm-3 mx-2\"\n >\n <i\n class=\"fa fa-ban warning fa-lg\"\n (keydown.enter)=\"makeAdmin(user, false)\"\n (click)=\"makeAdmin(user, false)\"\n aria-hidden=\"true\"\n ></i>\n </li>\n }\n } @else {\n <li class=\"mx-3\"></li>\n }\n @if (canShowSubscriptionActions) {\n <li\n [routerLink]=\"[routers.usersDetails + user.id]\"\n pTooltip=\"Edit\"\n tooltipPosition=\"top\"\n appendTo=\"body\"\n class=\"me-2 me-sm-3\">\n <i class=\"fa fa-edit edit-icon\"\n aria-hidden=\"true\"></i>\n </li>\n }\n @if (canShowSubscriptionActions && isGranted('Pages.Admin.Users.Delete')) {\n <li\n pTooltip=\"Remove user from subscription\"\n tooltipPosition=\"top\"\n appendTo=\"body\"\n class=\"me-2 me-sm-3\">\n <i (click)=\"onDelete(user)\"\n (keydown.enter)=\"onDelete(user)\"\n class=\"fa fa-trash delete-icon\"\n aria-hidden=\"true\"></i>\n </li>\n }\n </ul>\n </td>\n </tr>\n </ng-template>\n </p-table>\n @if (totalRecords === 0 && totalUnfilteredCount !== 0) {\n <div>\n <pw-no-data [withImage]=\"true\" [message]=\"'Search.NoDataMessage' | transloco\" [description]=\"'Search.NoDataDescription' | transloco\" >\n </pw-no-data>\n </div>\n }\n @if (totalRecords !== 0) {\n <pw-records-summary [showing]=\"dt?.value?.length ?? 0\" [total]=\"totalRecords\" />\n }\n </div>\n @if (totalUnfilteredCount === 0 && isLoaded) {\n <div>\n <pw-no-data [withImage]=\"true\" [message]=\"'Admin.Subscriptions.NoSubscriptionUsersMessage' | transloco\">\n </pw-no-data>\n </div>\n }\n </section>\n}\n\n@if (isAddEnabled) {\n <section id=\"manage-members\"\n >\n <pw-add-members (membersAdded)=\"onMembersAdded()\"\n ></pw-add-members>\n </section>\n}\n\n<!-- password validation modal for impersonate -->\n<pw-password-validation #passwordValidationModalForImpersonate\n (successEvent)=\"onUserImpersonation($event)\">\n</pw-password-validation>\n<!-- password validation modal for delete user -->\n\n<!-- password validation modal for remove2fa -->\n<pw-password-validation #passwordValidationModalForRemove2fa\n (successEvent)=\"remove2fa($event)\">\n</pw-password-validation>\n",
23143
+ template: "<div class=\"w-100 text-center mt-3\">\n @if (!isLoaded) {\n <p-progress-spinner></p-progress-spinner>\n }\n</div>\n@if (!isAddEnabled && canShowSubscriptionActions && isUserSubscriptionSuperAdmin) {\n <div class=\"text-end mb-2\">\n <button class=\"btn btn-sm btn-outline-primary\" (click)=\"isAddEnabled = true\">\n <i class=\"fa fa-plus-circle\" aria-hidden=\"true\"></i> Add Members\n </button>\n </div>\n}\n@if (!isAddEnabled) {\n <section id=\"members\"\n >\n <div [class.hideTable]=\"totalUnfilteredCount === 0\"\n class=\"primeng-datatable-container actions-collapsed table-responsive mt-0\">\n <p-table #dt\n stateKey=\"pw-table.admin-subscription-users\"\n stateStorage=\"session\"\n [resizableColumns]=\"true\"\n columnResizeMode=\"expand\"\n [value]=\"subscriptionMembers\"\n [paginator]=\"totalRecords !== 0\"\n [rows]=\"PAGE_SIZE\"\n [lazy]=\"true\"\n [totalRecords]=\"totalRecords\"\n [loading]=\"loading\"\n [filterDelay]=\"1000\"\n [customSort]=\"true\"\n (onLazyLoad)=\"onLazyLoad($event)\">\n <ng-template #caption>\n <div class=\"text-end\">\n <label for=\"subscription-users-search\" class=\"visually-hidden\">Search subscription users</label>\n <p-iconfield iconPosition=\"left\">\n <p-inputicon><i class=\"fa fa-search\" aria-hidden=\"true\"></i></p-inputicon>\n <input id=\"subscription-users-search\"\n name=\"subscription-users-search\"\n [(ngModel)]=\"searchText\"\n (input)=\"dt.filterGlobal($event.target.value, 'contains')\"\n type=\"text\"\n pInputText\n placeholder=\"Search subscription users...\"\n aria-label=\"Search subscription users...\" />\n </p-iconfield>\n </div>\n </ng-template>\n <ng-template #header>\n <tr>\n <th pResizableColumn scope=\"true\"\n pSortableColumn=\"id\">\n {{ 'Admin.Users.Id' | transloco }}\n <p-sort-icon field=\"id\"></p-sort-icon>\n </th>\n <th pResizableColumn scope=\"true\"\n pSortableColumn=\"first_name\">\n {{ 'Label.FirstName' | transloco }}\n </th>\n <th pResizableColumn scope=\"true\"\n pSortableColumn=\"last_name\">\n {{ 'Label.LastName' | transloco }}\n <p-sort-icon field=\"last_name\"></p-sort-icon>\n </th>\n <th pResizableColumn scope=\"true\"\n pSortableColumn=\"email\">\n {{ 'Label.Email' | transloco }}\n <p-sort-icon field=\"email\"></p-sort-icon>\n </th>\n <th pResizableColumn scope=\"true\"\n pSortableColumn=\"slug\">\n {{ 'Admin.Subscriptions.NickName' | transloco }}\n <p-sort-icon field=\"slug\"></p-sort-icon>\n </th>\n <th pResizableColumn scope=\"true\"\n pSortableColumn=\"has_password\">\n {{ 'Admin.Subscriptions.EmailConfirmed' | transloco }}\n <p-sort-icon field=\"has_password\"></p-sort-icon>\n </th>\n <th pResizableColumn scope=\"true\"\n pSortableColumn=\"last_sign_in_at\">\n {{ 'Admin.Subscriptions.LastLogin' | transloco }}\n <p-sort-icon field=\"last_sign_in_at\"></p-sort-icon>\n </th>\n <th scope=\"true\" class=\"actions-list-two\">\n {{ 'Label.Actions' | transloco }}\n </th>\n </tr>\n </ng-template>\n <ng-template #body\n let-user>\n <tr>\n <td data-head=\"Id\">{{ user.id }}</td>\n <td data-head=\"First Name\">\n <span class=\"first-name\">{{ user.first_name }}</span>\n @if (subscriptionOwnerUserId === user.id) {\n <span *rbacAllow=\"'Pages.Alpha'\" class=\"badge bg-primary mx-1\"> Owner </span>\n }\n @if (subscriptionAdmins?.includes(user?.id)) {\n <span class=\"badge bg-success mx-1 admin-badge\"> Admin </span>\n }\n \n </td>\n <td data-head=\"Last Name\">\n {{ user.last_name }}\n @if (user?.alpha) {\n <span\n [pTooltip]=\"'Admin.Users.Tooltip.AlphaIcon'|transloco\"\n tooltipPosition=\"top\"\n appendTo=\"body\">\n <i class=\"fa-regular fa-square-a alpha-beta text-warning\"></i>\n </span>\n }\n @if (user?.beta) {\n <span\n [pTooltip]=\"'Admin.Users.Tooltip.BetaIcon'|transloco\"\n class=\"ms-2\"\n tooltipPosition=\"top\"\n appendTo=\"body\">\n <i class=\"fa-regular fa-square-b alpha-beta text-primary\"></i>\n </span>\n }\n @if (user?.cognito_sso_activated) {\n <span\n class=\"ms-2\"\n [pTooltip]=\"'Admin.Users.Tooltip.Cognito' | transloco\"\n tooltipPosition=\"top\"\n appendTo=\"body\">\n <i class=\"fa fa-cloud success\" ></i>\n </span>\n }\n </td>\n <td data-head=\"Email\">{{ user.email }}</td>\n <td data-head=\"Nick Name\">\n <a [routerLink]=\"['/members', user.slug]\">{{ user.slug }}</a>\n </td>\n <td data-head=\"Email Confirm\">\n <span [appDynamicBadge]=\"{ itemsArray: [true, false], item: user?.has_password }\"\n color=\"success-danger\"\n class=\"badge\">\n {{ user?.has_password ? 'Yes' : 'No' }}\n </span>\n @if (user?.blocked) {\n <span\n [pTooltip]=\"'This user has been blocked'\"\n class=\"ms-2\"\n tooltipPosition=\"top\"\n appendTo=\"body\">\n <i class=\"fa-solid fa-hexagon-exclamation text-danger hexa-warning\"></i>\n </span>\n }\n </td>\n <td data-head=\"Last Login\">\n @if (user?.current_sign_in_at | isOnline) {\n <pw-online-indicator [lastSeen]=\"user.current_sign_in_at\" />\n } @else if (user?.current_sign_in_at) {\n <span>\n <span>\n {{ user.current_sign_in_at | dateFormat }}\n </span>\n <span>\n &nbsp;({{ user.current_sign_in_at | sinceAgo }})\n </span>\n </span>\n } @else {\n <span>\n <span>\n {{ user.last_sign_in_at | dateFormat }}\n </span>\n @if (user.last_sign_in_at) {\n <span>\n &nbsp;({{ user.last_sign_in_at | sinceAgo }})\n </span>\n }\n </span>\n }\n </td>\n <td data-head=\"Action\">\n <ul class=\"list-unstyled list-inline list-action\">\n <li *rbacAllow=\"'Pages.Alpha'\" pTooltip=\"Impersonate this user\" tooltipPosition=\"top\" appendTo=\"body\" class=\"me-2 me-sm-3\">\n <i (click)=\"onImpersonate(user)\" (keydown.enter)=\"onImpersonate(user)\" class=\"fas fa-people-arrows fa-lg\" aria-hidden=\"true\"></i>\n </li>\n @if (subscriptionOwnerUserId !== user.id) {\n <li *rbacAllow=\"'Pages.Alpha'\" pTooltip=\"Set this user as new owner\" tooltipPosition=\"top\" appendTo=\"body\" class=\"me-2 me-sm-3\">\n <i (click)=\"onChangeOwner(user)\" (keydown.enter)=\"onChangeOwner(user)\" class=\"fa fa-key warning fa-lg\" aria-hidden=\"true\"></i>\n </li>\n }\n @if (user?.enable_two_factor_authenticator) {\n <li *rbacAllow=\"'Pages.Alpha'\"\n (click)=\"disable2fa(user?.id)\"\n (keydown.enter)=\"disable2fa(user?.id)\"\n pTooltip=\"Disable 2FA\"\n tooltipPosition=\"top\"\n appendTo=\"body\"\n class=\"me-2 me-sm-3 success\">\n <i class=\"fa fa-lock\"\n aria-hidden=\"true\"></i>\n </li>\n }\n @if (canShowSubscriptionActions && isUserSubscriptionSuperAdmin) {\n <!-- Make Admin -->\n @if (!subscriptionAdmins?.includes(user.id)) {\n <li pTooltip=\"Make Admin\"\n tooltipPosition=\"top\"\n appendTo=\"body\"\n class=\"me-2 me-sm-3 mx-2\"\n >\n <i\n class=\"fa fa-user-crown fa-lg success\"\n (click)=\"makeAdmin(user, true)\"\n (keydown.enter)=\"makeAdmin(users, true)\"\n aria-hidden=\"true\"\n ></i>\n </li>\n }\n <li></li>\n <!-- Remove Admin -->\n @if (subscriptionAdmins?.includes(user.id)) {\n <li pTooltip=\"Remove Admin\"\n tooltipPosition=\"top\"\n appendTo=\"body\"\n class=\"me-2 me-sm-3 mx-2\"\n >\n <i\n class=\"fa fa-ban warning fa-lg\"\n (keydown.enter)=\"makeAdmin(user, false)\"\n (click)=\"makeAdmin(user, false)\"\n aria-hidden=\"true\"\n ></i>\n </li>\n }\n } @else {\n <li class=\"mx-3\"></li>\n }\n @if (canShowSubscriptionActions) {\n <li\n [routerLink]=\"[routers.usersDetails + user.id]\"\n pTooltip=\"Edit\"\n tooltipPosition=\"top\"\n appendTo=\"body\"\n class=\"me-2 me-sm-3\">\n <i class=\"fa fa-edit edit-icon\"\n aria-hidden=\"true\"></i>\n </li>\n }\n @if (canShowSubscriptionActions && isGranted('Pages.Admin.Users.Delete')) {\n <li\n pTooltip=\"Remove user from subscription\"\n tooltipPosition=\"top\"\n appendTo=\"body\"\n class=\"me-2 me-sm-3\">\n <i (click)=\"onDelete(user)\"\n (keydown.enter)=\"onDelete(user)\"\n class=\"fa fa-trash delete-icon\"\n aria-hidden=\"true\"></i>\n </li>\n }\n </ul>\n </td>\n </tr>\n </ng-template>\n </p-table>\n @if (totalRecords === 0 && totalUnfilteredCount !== 0) {\n <div>\n <pw-no-data [withImage]=\"true\" [message]=\"'Search.NoDataMessage' | transloco\" [description]=\"'Search.NoDataDescription' | transloco\" >\n </pw-no-data>\n </div>\n }\n @if (totalRecords !== 0) {\n <pw-records-summary [showing]=\"dt?.value?.length ?? 0\" [total]=\"totalRecords\" />\n }\n </div>\n @if (totalUnfilteredCount === 0 && isLoaded) {\n <div>\n <pw-no-data [withImage]=\"true\" [message]=\"'Admin.Subscriptions.NoSubscriptionUsersMessage' | transloco\">\n </pw-no-data>\n </div>\n }\n </section>\n}\n\n@if (isAddEnabled) {\n <section id=\"manage-members\"\n >\n <pw-add-members (membersAdded)=\"onMembersAdded()\"\n ></pw-add-members>\n </section>\n}\n\n<!-- password validation modal for impersonate -->\n<pw-password-validation #passwordValidationModalForImpersonate\n (successEvent)=\"onUserImpersonation($event)\">\n</pw-password-validation>\n<!-- password validation modal for delete user -->\n\n<!-- password validation modal for remove2fa -->\n<pw-password-validation #passwordValidationModalForRemove2fa\n (successEvent)=\"remove2fa($event)\">\n</pw-password-validation>\n",
23098
23144
  styles: [".hexa-warning{font-size:18px;vertical-align:middle}.alpha-beta{font-size:14px}.info-icon{vertical-align:middle;margin-left:5px}.first-name{margin-right:5px}\n"],
23099
23145
  dependencies: [
23100
23146
  {
@@ -23216,6 +23262,12 @@ var SubscriptionUsersComponent = class SubscriptionUsersComponent extends AppBas
23216
23262
  selector: "[pSortableColumn]",
23217
23263
  inputs: ["pSortableColumn", "pSortableColumnDisabled"]
23218
23264
  },
23265
+ {
23266
+ kind: "directive",
23267
+ type: i2$3.ResizableColumn,
23268
+ selector: "[pResizableColumn]",
23269
+ inputs: ["pResizableColumnDisabled"]
23270
+ },
23219
23271
  {
23220
23272
  kind: "component",
23221
23273
  type: i2$3.SortIcon,
@@ -23418,7 +23470,7 @@ i0.ɵɵngDeclareClassMetadata({
23418
23470
  args: [{
23419
23471
  selector: "pw-subscription-users",
23420
23472
  standalone: false,
23421
- template: "<div class=\"w-100 text-center mt-3\">\n @if (!isLoaded) {\n <p-progress-spinner></p-progress-spinner>\n }\n</div>\n@if (!isAddEnabled && canShowSubscriptionActions && isUserSubscriptionSuperAdmin) {\n <div class=\"text-end mb-2\">\n <button class=\"btn btn-sm btn-outline-primary\" (click)=\"isAddEnabled = true\">\n <i class=\"fa fa-plus-circle\" aria-hidden=\"true\"></i> Add Members\n </button>\n </div>\n}\n@if (!isAddEnabled) {\n <section id=\"members\"\n >\n <div [class.hideTable]=\"totalUnfilteredCount === 0\"\n class=\"primeng-datatable-container actions-collapsed table-responsive mt-0\">\n <p-table #dt\n [value]=\"subscriptionMembers\"\n [paginator]=\"totalRecords !== 0\"\n [rows]=\"PAGE_SIZE\"\n [lazy]=\"true\"\n [totalRecords]=\"totalRecords\"\n [loading]=\"loading\"\n [filterDelay]=\"1000\"\n [customSort]=\"true\"\n (onLazyLoad)=\"onLazyLoad($event)\">\n <ng-template #caption>\n <div class=\"text-end\">\n <label for=\"subscription-users-search\" class=\"visually-hidden\">Search subscription users</label>\n <p-iconfield iconPosition=\"left\">\n <p-inputicon><i class=\"fa fa-search\" aria-hidden=\"true\"></i></p-inputicon>\n <input id=\"subscription-users-search\"\n name=\"subscription-users-search\"\n [(ngModel)]=\"searchText\"\n (input)=\"dt.filterGlobal($event.target.value, 'contains')\"\n type=\"text\"\n pInputText\n placeholder=\"Search subscription users...\"\n aria-label=\"Search subscription users...\" />\n </p-iconfield>\n </div>\n </ng-template>\n <ng-template #header>\n <tr>\n <th scope=\"true\"\n pSortableColumn=\"id\">\n {{ 'Admin.Users.Id' | transloco }}\n <p-sort-icon field=\"id\"></p-sort-icon>\n </th>\n <th scope=\"true\"\n pSortableColumn=\"first_name\">\n {{ 'Label.FirstName' | transloco }}\n </th>\n <th scope=\"true\"\n pSortableColumn=\"last_name\">\n {{ 'Label.LastName' | transloco }}\n <p-sort-icon field=\"last_name\"></p-sort-icon>\n </th>\n <th scope=\"true\"\n pSortableColumn=\"email\">\n {{ 'Label.Email' | transloco }}\n <p-sort-icon field=\"email\"></p-sort-icon>\n </th>\n <th scope=\"true\"\n pSortableColumn=\"slug\">\n {{ 'Admin.Subscriptions.NickName' | transloco }}\n <p-sort-icon field=\"slug\"></p-sort-icon>\n </th>\n <th scope=\"true\"\n pSortableColumn=\"has_password\">\n {{ 'Admin.Subscriptions.EmailConfirmed' | transloco }}\n <p-sort-icon field=\"has_password\"></p-sort-icon>\n </th>\n <th scope=\"true\"\n pSortableColumn=\"last_sign_in_at\">\n {{ 'Admin.Subscriptions.LastLogin' | transloco }}\n <p-sort-icon field=\"last_sign_in_at\"></p-sort-icon>\n </th>\n <th scope=\"true\" class=\"actions-list-two\">\n {{ 'Label.Actions' | transloco }}\n </th>\n </tr>\n </ng-template>\n <ng-template #body\n let-user>\n <tr>\n <td data-head=\"Id\">{{ user.id }}</td>\n <td data-head=\"First Name\">\n <span class=\"first-name\">{{ user.first_name }}</span>\n @if (subscriptionOwnerUserId === user.id) {\n <span *rbacAllow=\"'Pages.Alpha'\" class=\"badge bg-primary mx-1\"> Owner </span>\n }\n @if (subscriptionAdmins?.includes(user?.id)) {\n <span class=\"badge bg-success mx-1 admin-badge\"> Admin </span>\n }\n \n </td>\n <td data-head=\"Last Name\">\n {{ user.last_name }}\n @if (user?.alpha) {\n <span\n [pTooltip]=\"'Admin.Users.Tooltip.AlphaIcon'|transloco\"\n tooltipPosition=\"top\"\n appendTo=\"body\">\n <i class=\"fa-regular fa-square-a alpha-beta text-warning\"></i>\n </span>\n }\n @if (user?.beta) {\n <span\n [pTooltip]=\"'Admin.Users.Tooltip.BetaIcon'|transloco\"\n class=\"ms-2\"\n tooltipPosition=\"top\"\n appendTo=\"body\">\n <i class=\"fa-regular fa-square-b alpha-beta text-primary\"></i>\n </span>\n }\n @if (user?.cognito_sso_activated) {\n <span\n class=\"ms-2\"\n [pTooltip]=\"'Admin.Users.Tooltip.Cognito' | transloco\"\n tooltipPosition=\"top\"\n appendTo=\"body\">\n <i class=\"fa fa-cloud success\" ></i>\n </span>\n }\n </td>\n <td data-head=\"Email\">{{ user.email }}</td>\n <td data-head=\"Nick Name\">\n <a [routerLink]=\"['/members', user.slug]\">{{ user.slug }}</a>\n </td>\n <td data-head=\"Email Confirm\">\n <span [appDynamicBadge]=\"{ itemsArray: [true, false], item: user?.has_password }\"\n color=\"success-danger\"\n class=\"badge\">\n {{ user?.has_password ? 'Yes' : 'No' }}\n </span>\n @if (user?.blocked) {\n <span\n [pTooltip]=\"'This user has been blocked'\"\n class=\"ms-2\"\n tooltipPosition=\"top\"\n appendTo=\"body\">\n <i class=\"fa-solid fa-hexagon-exclamation text-danger hexa-warning\"></i>\n </span>\n }\n </td>\n <td data-head=\"Last Login\">\n @if (user?.current_sign_in_at | isOnline) {\n <pw-online-indicator [lastSeen]=\"user.current_sign_in_at\" />\n } @else if (user?.current_sign_in_at) {\n <span>\n <span>\n {{ user.current_sign_in_at | dateFormat }}\n </span>\n <span>\n &nbsp;({{ user.current_sign_in_at | sinceAgo }})\n </span>\n </span>\n } @else {\n <span>\n <span>\n {{ user.last_sign_in_at | dateFormat }}\n </span>\n @if (user.last_sign_in_at) {\n <span>\n &nbsp;({{ user.last_sign_in_at | sinceAgo }})\n </span>\n }\n </span>\n }\n </td>\n <td data-head=\"Action\">\n <ul class=\"list-unstyled list-inline list-action\">\n <li *rbacAllow=\"'Pages.Alpha'\" pTooltip=\"Impersonate this user\" tooltipPosition=\"top\" appendTo=\"body\" class=\"me-2 me-sm-3\">\n <i (click)=\"onImpersonate(user)\" (keydown.enter)=\"onImpersonate(user)\" class=\"fas fa-people-arrows fa-lg\" aria-hidden=\"true\"></i>\n </li>\n @if (subscriptionOwnerUserId !== user.id) {\n <li *rbacAllow=\"'Pages.Alpha'\" pTooltip=\"Set this user as new owner\" tooltipPosition=\"top\" appendTo=\"body\" class=\"me-2 me-sm-3\">\n <i (click)=\"onChangeOwner(user)\" (keydown.enter)=\"onChangeOwner(user)\" class=\"fa fa-key warning fa-lg\" aria-hidden=\"true\"></i>\n </li>\n }\n @if (user?.enable_two_factor_authenticator) {\n <li *rbacAllow=\"'Pages.Alpha'\"\n (click)=\"disable2fa(user?.id)\"\n (keydown.enter)=\"disable2fa(user?.id)\"\n pTooltip=\"Disable 2FA\"\n tooltipPosition=\"top\"\n appendTo=\"body\"\n class=\"me-2 me-sm-3 success\">\n <i class=\"fa fa-lock\"\n aria-hidden=\"true\"></i>\n </li>\n }\n @if (canShowSubscriptionActions && isUserSubscriptionSuperAdmin) {\n <!-- Make Admin -->\n @if (!subscriptionAdmins?.includes(user.id)) {\n <li pTooltip=\"Make Admin\"\n tooltipPosition=\"top\"\n appendTo=\"body\"\n class=\"me-2 me-sm-3 mx-2\"\n >\n <i\n class=\"fa fa-user-crown fa-lg success\"\n (click)=\"makeAdmin(user, true)\"\n (keydown.enter)=\"makeAdmin(users, true)\"\n aria-hidden=\"true\"\n ></i>\n </li>\n }\n <li></li>\n <!-- Remove Admin -->\n @if (subscriptionAdmins?.includes(user.id)) {\n <li pTooltip=\"Remove Admin\"\n tooltipPosition=\"top\"\n appendTo=\"body\"\n class=\"me-2 me-sm-3 mx-2\"\n >\n <i\n class=\"fa fa-ban warning fa-lg\"\n (keydown.enter)=\"makeAdmin(user, false)\"\n (click)=\"makeAdmin(user, false)\"\n aria-hidden=\"true\"\n ></i>\n </li>\n }\n } @else {\n <li class=\"mx-3\"></li>\n }\n @if (canShowSubscriptionActions) {\n <li\n [routerLink]=\"[routers.usersDetails + user.id]\"\n pTooltip=\"Edit\"\n tooltipPosition=\"top\"\n appendTo=\"body\"\n class=\"me-2 me-sm-3\">\n <i class=\"fa fa-edit edit-icon\"\n aria-hidden=\"true\"></i>\n </li>\n }\n @if (canShowSubscriptionActions && isGranted('Pages.Admin.Users.Delete')) {\n <li\n pTooltip=\"Remove user from subscription\"\n tooltipPosition=\"top\"\n appendTo=\"body\"\n class=\"me-2 me-sm-3\">\n <i (click)=\"onDelete(user)\"\n (keydown.enter)=\"onDelete(user)\"\n class=\"fa fa-trash delete-icon\"\n aria-hidden=\"true\"></i>\n </li>\n }\n </ul>\n </td>\n </tr>\n </ng-template>\n </p-table>\n @if (totalRecords === 0 && totalUnfilteredCount !== 0) {\n <div>\n <pw-no-data [withImage]=\"true\" [message]=\"'Search.NoDataMessage' | transloco\" [description]=\"'Search.NoDataDescription' | transloco\" >\n </pw-no-data>\n </div>\n }\n @if (totalRecords !== 0) {\n <pw-records-summary [showing]=\"dt?.value?.length ?? 0\" [total]=\"totalRecords\" />\n }\n </div>\n @if (totalUnfilteredCount === 0 && isLoaded) {\n <div>\n <pw-no-data [withImage]=\"true\" [message]=\"'Admin.Subscriptions.NoSubscriptionUsersMessage' | transloco\">\n </pw-no-data>\n </div>\n }\n </section>\n}\n\n@if (isAddEnabled) {\n <section id=\"manage-members\"\n >\n <pw-add-members (membersAdded)=\"onMembersAdded()\"\n ></pw-add-members>\n </section>\n}\n\n<!-- password validation modal for impersonate -->\n<pw-password-validation #passwordValidationModalForImpersonate\n (successEvent)=\"onUserImpersonation($event)\">\n</pw-password-validation>\n<!-- password validation modal for delete user -->\n\n<!-- password validation modal for remove2fa -->\n<pw-password-validation #passwordValidationModalForRemove2fa\n (successEvent)=\"remove2fa($event)\">\n</pw-password-validation>\n",
23473
+ template: "<div class=\"w-100 text-center mt-3\">\n @if (!isLoaded) {\n <p-progress-spinner></p-progress-spinner>\n }\n</div>\n@if (!isAddEnabled && canShowSubscriptionActions && isUserSubscriptionSuperAdmin) {\n <div class=\"text-end mb-2\">\n <button class=\"btn btn-sm btn-outline-primary\" (click)=\"isAddEnabled = true\">\n <i class=\"fa fa-plus-circle\" aria-hidden=\"true\"></i> Add Members\n </button>\n </div>\n}\n@if (!isAddEnabled) {\n <section id=\"members\"\n >\n <div [class.hideTable]=\"totalUnfilteredCount === 0\"\n class=\"primeng-datatable-container actions-collapsed table-responsive mt-0\">\n <p-table #dt\n stateKey=\"pw-table.admin-subscription-users\"\n stateStorage=\"session\"\n [resizableColumns]=\"true\"\n columnResizeMode=\"expand\"\n [value]=\"subscriptionMembers\"\n [paginator]=\"totalRecords !== 0\"\n [rows]=\"PAGE_SIZE\"\n [lazy]=\"true\"\n [totalRecords]=\"totalRecords\"\n [loading]=\"loading\"\n [filterDelay]=\"1000\"\n [customSort]=\"true\"\n (onLazyLoad)=\"onLazyLoad($event)\">\n <ng-template #caption>\n <div class=\"text-end\">\n <label for=\"subscription-users-search\" class=\"visually-hidden\">Search subscription users</label>\n <p-iconfield iconPosition=\"left\">\n <p-inputicon><i class=\"fa fa-search\" aria-hidden=\"true\"></i></p-inputicon>\n <input id=\"subscription-users-search\"\n name=\"subscription-users-search\"\n [(ngModel)]=\"searchText\"\n (input)=\"dt.filterGlobal($event.target.value, 'contains')\"\n type=\"text\"\n pInputText\n placeholder=\"Search subscription users...\"\n aria-label=\"Search subscription users...\" />\n </p-iconfield>\n </div>\n </ng-template>\n <ng-template #header>\n <tr>\n <th pResizableColumn scope=\"true\"\n pSortableColumn=\"id\">\n {{ 'Admin.Users.Id' | transloco }}\n <p-sort-icon field=\"id\"></p-sort-icon>\n </th>\n <th pResizableColumn scope=\"true\"\n pSortableColumn=\"first_name\">\n {{ 'Label.FirstName' | transloco }}\n </th>\n <th pResizableColumn scope=\"true\"\n pSortableColumn=\"last_name\">\n {{ 'Label.LastName' | transloco }}\n <p-sort-icon field=\"last_name\"></p-sort-icon>\n </th>\n <th pResizableColumn scope=\"true\"\n pSortableColumn=\"email\">\n {{ 'Label.Email' | transloco }}\n <p-sort-icon field=\"email\"></p-sort-icon>\n </th>\n <th pResizableColumn scope=\"true\"\n pSortableColumn=\"slug\">\n {{ 'Admin.Subscriptions.NickName' | transloco }}\n <p-sort-icon field=\"slug\"></p-sort-icon>\n </th>\n <th pResizableColumn scope=\"true\"\n pSortableColumn=\"has_password\">\n {{ 'Admin.Subscriptions.EmailConfirmed' | transloco }}\n <p-sort-icon field=\"has_password\"></p-sort-icon>\n </th>\n <th pResizableColumn scope=\"true\"\n pSortableColumn=\"last_sign_in_at\">\n {{ 'Admin.Subscriptions.LastLogin' | transloco }}\n <p-sort-icon field=\"last_sign_in_at\"></p-sort-icon>\n </th>\n <th scope=\"true\" class=\"actions-list-two\">\n {{ 'Label.Actions' | transloco }}\n </th>\n </tr>\n </ng-template>\n <ng-template #body\n let-user>\n <tr>\n <td data-head=\"Id\">{{ user.id }}</td>\n <td data-head=\"First Name\">\n <span class=\"first-name\">{{ user.first_name }}</span>\n @if (subscriptionOwnerUserId === user.id) {\n <span *rbacAllow=\"'Pages.Alpha'\" class=\"badge bg-primary mx-1\"> Owner </span>\n }\n @if (subscriptionAdmins?.includes(user?.id)) {\n <span class=\"badge bg-success mx-1 admin-badge\"> Admin </span>\n }\n \n </td>\n <td data-head=\"Last Name\">\n {{ user.last_name }}\n @if (user?.alpha) {\n <span\n [pTooltip]=\"'Admin.Users.Tooltip.AlphaIcon'|transloco\"\n tooltipPosition=\"top\"\n appendTo=\"body\">\n <i class=\"fa-regular fa-square-a alpha-beta text-warning\"></i>\n </span>\n }\n @if (user?.beta) {\n <span\n [pTooltip]=\"'Admin.Users.Tooltip.BetaIcon'|transloco\"\n class=\"ms-2\"\n tooltipPosition=\"top\"\n appendTo=\"body\">\n <i class=\"fa-regular fa-square-b alpha-beta text-primary\"></i>\n </span>\n }\n @if (user?.cognito_sso_activated) {\n <span\n class=\"ms-2\"\n [pTooltip]=\"'Admin.Users.Tooltip.Cognito' | transloco\"\n tooltipPosition=\"top\"\n appendTo=\"body\">\n <i class=\"fa fa-cloud success\" ></i>\n </span>\n }\n </td>\n <td data-head=\"Email\">{{ user.email }}</td>\n <td data-head=\"Nick Name\">\n <a [routerLink]=\"['/members', user.slug]\">{{ user.slug }}</a>\n </td>\n <td data-head=\"Email Confirm\">\n <span [appDynamicBadge]=\"{ itemsArray: [true, false], item: user?.has_password }\"\n color=\"success-danger\"\n class=\"badge\">\n {{ user?.has_password ? 'Yes' : 'No' }}\n </span>\n @if (user?.blocked) {\n <span\n [pTooltip]=\"'This user has been blocked'\"\n class=\"ms-2\"\n tooltipPosition=\"top\"\n appendTo=\"body\">\n <i class=\"fa-solid fa-hexagon-exclamation text-danger hexa-warning\"></i>\n </span>\n }\n </td>\n <td data-head=\"Last Login\">\n @if (user?.current_sign_in_at | isOnline) {\n <pw-online-indicator [lastSeen]=\"user.current_sign_in_at\" />\n } @else if (user?.current_sign_in_at) {\n <span>\n <span>\n {{ user.current_sign_in_at | dateFormat }}\n </span>\n <span>\n &nbsp;({{ user.current_sign_in_at | sinceAgo }})\n </span>\n </span>\n } @else {\n <span>\n <span>\n {{ user.last_sign_in_at | dateFormat }}\n </span>\n @if (user.last_sign_in_at) {\n <span>\n &nbsp;({{ user.last_sign_in_at | sinceAgo }})\n </span>\n }\n </span>\n }\n </td>\n <td data-head=\"Action\">\n <ul class=\"list-unstyled list-inline list-action\">\n <li *rbacAllow=\"'Pages.Alpha'\" pTooltip=\"Impersonate this user\" tooltipPosition=\"top\" appendTo=\"body\" class=\"me-2 me-sm-3\">\n <i (click)=\"onImpersonate(user)\" (keydown.enter)=\"onImpersonate(user)\" class=\"fas fa-people-arrows fa-lg\" aria-hidden=\"true\"></i>\n </li>\n @if (subscriptionOwnerUserId !== user.id) {\n <li *rbacAllow=\"'Pages.Alpha'\" pTooltip=\"Set this user as new owner\" tooltipPosition=\"top\" appendTo=\"body\" class=\"me-2 me-sm-3\">\n <i (click)=\"onChangeOwner(user)\" (keydown.enter)=\"onChangeOwner(user)\" class=\"fa fa-key warning fa-lg\" aria-hidden=\"true\"></i>\n </li>\n }\n @if (user?.enable_two_factor_authenticator) {\n <li *rbacAllow=\"'Pages.Alpha'\"\n (click)=\"disable2fa(user?.id)\"\n (keydown.enter)=\"disable2fa(user?.id)\"\n pTooltip=\"Disable 2FA\"\n tooltipPosition=\"top\"\n appendTo=\"body\"\n class=\"me-2 me-sm-3 success\">\n <i class=\"fa fa-lock\"\n aria-hidden=\"true\"></i>\n </li>\n }\n @if (canShowSubscriptionActions && isUserSubscriptionSuperAdmin) {\n <!-- Make Admin -->\n @if (!subscriptionAdmins?.includes(user.id)) {\n <li pTooltip=\"Make Admin\"\n tooltipPosition=\"top\"\n appendTo=\"body\"\n class=\"me-2 me-sm-3 mx-2\"\n >\n <i\n class=\"fa fa-user-crown fa-lg success\"\n (click)=\"makeAdmin(user, true)\"\n (keydown.enter)=\"makeAdmin(users, true)\"\n aria-hidden=\"true\"\n ></i>\n </li>\n }\n <li></li>\n <!-- Remove Admin -->\n @if (subscriptionAdmins?.includes(user.id)) {\n <li pTooltip=\"Remove Admin\"\n tooltipPosition=\"top\"\n appendTo=\"body\"\n class=\"me-2 me-sm-3 mx-2\"\n >\n <i\n class=\"fa fa-ban warning fa-lg\"\n (keydown.enter)=\"makeAdmin(user, false)\"\n (click)=\"makeAdmin(user, false)\"\n aria-hidden=\"true\"\n ></i>\n </li>\n }\n } @else {\n <li class=\"mx-3\"></li>\n }\n @if (canShowSubscriptionActions) {\n <li\n [routerLink]=\"[routers.usersDetails + user.id]\"\n pTooltip=\"Edit\"\n tooltipPosition=\"top\"\n appendTo=\"body\"\n class=\"me-2 me-sm-3\">\n <i class=\"fa fa-edit edit-icon\"\n aria-hidden=\"true\"></i>\n </li>\n }\n @if (canShowSubscriptionActions && isGranted('Pages.Admin.Users.Delete')) {\n <li\n pTooltip=\"Remove user from subscription\"\n tooltipPosition=\"top\"\n appendTo=\"body\"\n class=\"me-2 me-sm-3\">\n <i (click)=\"onDelete(user)\"\n (keydown.enter)=\"onDelete(user)\"\n class=\"fa fa-trash delete-icon\"\n aria-hidden=\"true\"></i>\n </li>\n }\n </ul>\n </td>\n </tr>\n </ng-template>\n </p-table>\n @if (totalRecords === 0 && totalUnfilteredCount !== 0) {\n <div>\n <pw-no-data [withImage]=\"true\" [message]=\"'Search.NoDataMessage' | transloco\" [description]=\"'Search.NoDataDescription' | transloco\" >\n </pw-no-data>\n </div>\n }\n @if (totalRecords !== 0) {\n <pw-records-summary [showing]=\"dt?.value?.length ?? 0\" [total]=\"totalRecords\" />\n }\n </div>\n @if (totalUnfilteredCount === 0 && isLoaded) {\n <div>\n <pw-no-data [withImage]=\"true\" [message]=\"'Admin.Subscriptions.NoSubscriptionUsersMessage' | transloco\">\n </pw-no-data>\n </div>\n }\n </section>\n}\n\n@if (isAddEnabled) {\n <section id=\"manage-members\"\n >\n <pw-add-members (membersAdded)=\"onMembersAdded()\"\n ></pw-add-members>\n </section>\n}\n\n<!-- password validation modal for impersonate -->\n<pw-password-validation #passwordValidationModalForImpersonate\n (successEvent)=\"onUserImpersonation($event)\">\n</pw-password-validation>\n<!-- password validation modal for delete user -->\n\n<!-- password validation modal for remove2fa -->\n<pw-password-validation #passwordValidationModalForRemove2fa\n (successEvent)=\"remove2fa($event)\">\n</pw-password-validation>\n",
23422
23474
  styles: [".hexa-warning{font-size:18px;vertical-align:middle}.alpha-beta{font-size:14px}.info-icon{vertical-align:middle;margin-left:5px}.first-name{margin-right:5px}\n"]
23423
23475
  }]
23424
23476
  }],
@@ -23594,7 +23646,7 @@ var SubscriptionAgentsListComponent = class SubscriptionAgentsListComponent exte
23594
23646
  selector: "pw-subscription-agents-list",
23595
23647
  usesInheritance: true,
23596
23648
  ngImport: i0,
23597
- template: "@if (!newEmbass) {\n <div class=\"w-100 text-center mt-3 mb-3\">\n <div class=\"d-flex align-items-center\">\n <div class=\"ms-auto col-xs-12\">\n <a class=\"btn btn-sm btn-outline-primary float-end\"\n (click)=\"newEmbass = true\"\n id=\"btn-create\">\n <i class=\"fa fa-plus-circle me-2\" aria-hidden=\"true\"></i>Add Ambassadors\n </a>\n </div>\n </div>\n @if (!isLoaded) {\n <p-progress-spinner> </p-progress-spinner>\n }\n </div>\n <div class=\"primeng-datatable-container actions-collapsed table-responsive mt-0\"\n [class.hideTable]=\"totalUnfilteredCount === 0\">\n <p-table #dt\n [value]=\"allAgents\"\n [paginator]=\"totalRecords !== 0\"\n [rows]=\"PAGE_SIZE\"\n [lazy]=\"true\"\n [totalRecords]=\"totalRecords\"\n [loading]=\"loading\"\n [filterDelay]=\"1000\"\n [customSort]=\"true\">\n <ng-template #caption>\n <div class=\"text-end\">\n <p-iconfield iconPosition=\"left\">\n <p-inputicon><i class=\"fa fa-search\" aria-hidden=\"true\"></i></p-inputicon>\n <input type=\"text\"\n id=\"subscription-agents-list-search\"\n name=\"subscription-agents-list-search\"\n [(ngModel)]=\"searchText\"\n pInputText\n placeholder=\"Search ambassadors...\"\n (input)=\"dt.filterGlobal($event.target.value, 'contains')\"\n aria-label=\"Search ambassadors...\" />\n </p-iconfield>\n </div>\n </ng-template>\n <ng-template #header>\n <tr>\n <th scope=\"true\">{{ 'Admin.Subscriptions.AgentName' | transloco }}</th>\n <th scope=\"true\">{{ 'Label.Email' | transloco }}</th>\n <th scope=\"true\">{{ 'Admin.Subscriptions.Percentage' | transloco }}</th>\n <th scope=\"true\">{{ 'Admin.Subscriptions.EndDate' | transloco }}</th>\n <th scope=\"true\">{{ 'Admin.Subscriptions.Status' | transloco }}</th>\n <th scope=\"true\" class=\"actions-list-two\">{{ 'Label.Actions' | transloco }}</th>\n </tr>\n </ng-template>\n <ng-template #body\n let-agent>\n <tr>\n <td data-head=\"Ambassador Name\">\n <a [routerLink]=\"['/admin/users', agent.user_id]\">{{ agent.user.first_name ?? 'N/A' }}</a>\n </td>\n <td data-head=\"Email\">\n {{ agent.user.email !== null ? agent.user.email : 'N/A' }}\n </td>\n <td data-head=\"Percentage\">{{ agent.percentage }}</td>\n <td data-head=\"End Date\">{{ agent.end_date | dateFormat }}</td>\n <td data-head=\"Status\">\n <span class=\"badge\"\n color=\"success-grey\"\n [appDynamicBadge]=\"{ itemsArray: [true, false], item: agent.active }\">\n {{ (agent.active ? 'Admin.Subscriptions.Active' : 'Admin.Subscriptions.Inactive') | transloco }}\n </span>\n </td>\n <td data-head=\"Action\">\n <ul class=\"list-unstyled list-inline list-action\">\n <li pTooltip=\"Edit\"\n tooltipPosition=\"top\"\n appendTo=\"body\"\n class=\"me-2 me-sm-3\"\n [routerLink]=\"[\n '/admin/subscriptions/',\n agent.subscription_id,\n 'agent_details',\n agent.user_id\n ]\">\n <i class=\"fa fa-edit edit-icon\" aria-hidden=\"true\"></i>\n </li>\n <li pTooltip=\"Delete\"\n tooltipPosition=\"top\"\n appendTo=\"body\"\n class=\"me-2 me-sm-3\"\n (keydown.enter)=\"onDelete(agent?.user_id)\"\n (click)=\"onDelete(agent?.user_id)\">\n <i class=\"fa fa-trash delete-icon\" aria-hidden=\"true\"></i>\n </li>\n </ul>\n </td>\n </tr>\n </ng-template>\n </p-table>\n @if (totalRecords !== 0) {\n <pw-records-summary [showing]=\"dt?.value?.length ?? 0\" [total]=\"totalRecords\" />\n }\n </div>\n @if (totalRecords === 0 && isLoaded) {\n <div>\n <pw-no-data [withImage]=\"true\" [message]=\"'Admin.Subscriptions.NoAmbassadorsMessage' | transloco\">\n </pw-no-data>\n </div>\n }\n}\n@if (newEmbass) {\n <form [formGroup]=\"formEmbassador\"\n id=\"mainFrom\"\n class=\"mt-4 p-2\"\n (ngSubmit)=\"onAddEmbassador()\">\n\n <h3>{{ 'Admin.Subscriptions.Section.Ambassador' | transloco }}</h3>\n <div class=\"row\">\n <div class=\"col-12 col-md-4\">\n <div class=\"mb-3 ui-fluid skills-modal\">\n <pw-input-container\n [label]=\"'Admin.Subscriptions.Ambassador' | transloco\"\n [showTooltip]=\"true\"\n [tooltipText]=\"'Admin.Subscriptions.Tooltip.AmbassadorAdd' | transloco\"\n [useAriaLabelledbyOnly]=\"true\"\n controlId=\"subscription-agents-list-ambassador\">\n <p-auto-complete class=\"w-100\" appendTo=\"body\" [suggestions]=\"filteredUsers\"\n [attr.aria-labelledby]=\"'subscription-agents-list-ambassador-label'\"\n formControlName=\"email\"\n dataKey=\"id\"\n optionLabel=\"displayName\"\n (completeMethod)=\"search($event)\"\n [dropdown]=\"true\"\n placeholder=\"Search ambassadors...\"\n [multiple]=\"false\">\n </p-auto-complete>\n </pw-input-container>\n </div>\n </div>\n\n <div class=\"col-12 col-md-4\">\n <div class=\"mb-3\">\n <pw-input-container\n [label]=\"'Admin.Subscriptions.Percentage' | transloco\"\n [showTooltip]=\"true\"\n [tooltipText]=\"'Admin.Subscriptions.Tooltip.Percentage' | transloco\"\n name=\"percentage\"\n controlId=\"subscription-agents-list-percentage\"\n [errorMsg]=\"'Admin.Subscriptions.Validation.Percentage' | transloco\">\n <input type=\"number\"\n id=\"subscription-agents-list-percentage\"\n formControlName=\"percentage\"\n class=\"form-control\"\n name=\"input_percentage_2\"\n [attr.aria-label]=\"'Admin.Subscriptions.Percentage' | transloco\" />\n </pw-input-container>\n </div>\n </div>\n\n <div class=\"col-12 col-md-4\">\n <div class=\"mb-3\">\n <pw-input-container\n [label]=\"'Admin.Subscriptions.EndDate' | transloco\"\n [showTooltip]=\"true\"\n [tooltipText]=\"'Admin.Subscriptions.Tooltip.EndDate' | transloco\"\n name=\"endDate\"\n controlId=\"subscription-agents-list-endDate\"\n [errorMsg]=\"'Admin.Subscriptions.Validation.EndDate' | transloco\">\n <div class=\"input-group\">\n <input class=\"form-control\"\n id=\"subscription-agents-list-endDate\"\n name=\"endDate\"\n [placeholder]=\"'Admin.Subscriptions.Placeholder.EndDate' | transloco\"\n formControlName=\"endDate\"\n ngbDatepicker\n #d=\"ngbDatepicker\"\n (click)=\"d.open()\"\n [minDate]=\"{ day: 1, month: 1, year: 1950 }\"\n [maxDate]=\"{ day: 31, month: 12, year: 2050 }\"\n [attr.aria-label]=\"'Admin.Subscriptions.EndDate' | transloco\" />\n <button class=\"btn btn-primary\"\n type=\"button\"\n aria-label=\"Open date picker\"\n (click)=\"d.toggle()\">\n <i class=\"fa fa-calendar\" aria-hidden=\"true\"></i>\n </button>\n </div>\n </pw-input-container>\n </div>\n </div>\n </div>\n\n <!-- Payout destination (#951): the provider drives which fields render.\n Destination fields only show for a single selection — a bulk add would\n share one address across several people, so bulk-added ambassadors set\n their destination from the edit screen. -->\n <h3>{{ 'Admin.Subscriptions.Section.Payout' | transloco }}</h3>\n <div class=\"row\">\n <div class=\"col-12 col-md-4\">\n <div class=\"mb-3\">\n <pw-input-container\n [label]=\"'Admin.Subscriptions.Payout.Provider' | transloco\"\n [showTooltip]=\"true\"\n [tooltipText]=\"'Admin.Subscriptions.Tooltip.PayoutProvider' | transloco\"\n name=\"payout_provider\"\n controlId=\"subscription-agents-list-payout_provider\">\n <p-select\n class=\"w-100\"\n inputId=\"subscription-agents-list-payout_provider\"\n appendTo=\"body\"\n [options]=\"payoutProviders\"\n optionLabel=\"label\"\n optionValue=\"value\"\n formControlName=\"payout_provider\"\n [placeholder]=\"'Admin.Subscriptions.Payout.SelectProvider' | transloco\"\n (onChange)=\"onPayoutProviderChange($event.value)\">\n </p-select>\n </pw-input-container>\n </div>\n </div>\n\n @if (isSingleAmbassadorSelected) {\n @for (field of payoutFields; track field.control) {\n <div class=\"col-12 col-md-4\">\n <div class=\"mb-3\">\n <pw-input-container\n [label]=\"field.labelKey | transloco\"\n [showTooltip]=\"true\"\n [tooltipText]=\"'Admin.Subscriptions.Tooltip.PayoutDetails' | transloco\"\n [name]=\"field.control\"\n [controlId]=\"'subscription-agents-list-' + field.control\"\n [errorMsg]=\"'Admin.Subscriptions.Payout.FieldRequired' | transloco\">\n <input type=\"text\"\n class=\"form-control\"\n [id]=\"'subscription-agents-list-' + field.control\"\n [formControlName]=\"field.control\"\n [placeholder]=\"field.placeholderKey | transloco\"\n autocomplete=\"off\"\n [attr.aria-label]=\"field.labelKey | transloco\"/>\n </pw-input-container>\n </div>\n </div>\n }\n }\n </div>\n\n <!-- Provider caveat, driven by PAYOUT_PROVIDERS[].noticeKey so no provider is\n named in the template. Shown for a bulk selection too: the provider\n applies to every ambassador being created here, so the limitation is if\n anything more consequential than on the single-ambassador form. -->\n @if (payoutNoticeKey) {\n <div class=\"row mt-3\">\n <div class=\"col-12 col-md-8\">\n <div class=\"alert alert-warning mb-0\">\n {{ payoutNoticeKey | transloco }}\n </div>\n </div>\n </div>\n }\n\n <div class=\"row text-end mt-4\">\n <div class=\"col-12\">\n <button type=\"button\"\n (click)=\"newEmbass = false\"\n class=\"btn btn-outline-default me-2\">\n {{ 'Button.Cancel' | transloco }}\n </button>\n <button type=\"submit\"\n [buttonBusy]=\"submitted\"\n class=\"btn btn-primary\">\n Add Ambassador\n </button>\n </div>\n </div>\n </form>\n}\n",
23649
+ template: "@if (!newEmbass) {\n <div class=\"w-100 text-center mt-3 mb-3\">\n <div class=\"d-flex align-items-center\">\n <div class=\"ms-auto col-xs-12\">\n <a class=\"btn btn-sm btn-outline-primary float-end\"\n (click)=\"newEmbass = true\"\n id=\"btn-create\">\n <i class=\"fa fa-plus-circle me-2\" aria-hidden=\"true\"></i>Add Ambassadors\n </a>\n </div>\n </div>\n @if (!isLoaded) {\n <p-progress-spinner> </p-progress-spinner>\n }\n </div>\n <div class=\"primeng-datatable-container actions-collapsed table-responsive mt-0\"\n [class.hideTable]=\"totalUnfilteredCount === 0\">\n <p-table #dt\n stateKey=\"pw-table.admin-subscription-agents-list\"\n stateStorage=\"session\"\n [resizableColumns]=\"true\"\n columnResizeMode=\"expand\"\n [value]=\"allAgents\"\n [paginator]=\"totalRecords !== 0\"\n [rows]=\"PAGE_SIZE\"\n [lazy]=\"true\"\n [totalRecords]=\"totalRecords\"\n [loading]=\"loading\"\n [filterDelay]=\"1000\"\n [customSort]=\"true\">\n <ng-template #caption>\n <div class=\"text-end\">\n <p-iconfield iconPosition=\"left\">\n <p-inputicon><i class=\"fa fa-search\" aria-hidden=\"true\"></i></p-inputicon>\n <input type=\"text\"\n id=\"subscription-agents-list-search\"\n name=\"subscription-agents-list-search\"\n [(ngModel)]=\"searchText\"\n pInputText\n placeholder=\"Search ambassadors...\"\n (input)=\"dt.filterGlobal($event.target.value, 'contains')\"\n aria-label=\"Search ambassadors...\" />\n </p-iconfield>\n </div>\n </ng-template>\n <ng-template #header>\n <tr>\n <th pResizableColumn scope=\"true\">{{ 'Admin.Subscriptions.AgentName' | transloco }}</th>\n <th pResizableColumn scope=\"true\">{{ 'Label.Email' | transloco }}</th>\n <th pResizableColumn scope=\"true\">{{ 'Admin.Subscriptions.Percentage' | transloco }}</th>\n <th pResizableColumn scope=\"true\">{{ 'Admin.Subscriptions.EndDate' | transloco }}</th>\n <th pResizableColumn scope=\"true\">{{ 'Admin.Subscriptions.Status' | transloco }}</th>\n <th scope=\"true\" class=\"actions-list-two\">{{ 'Label.Actions' | transloco }}</th>\n </tr>\n </ng-template>\n <ng-template #body\n let-agent>\n <tr>\n <td data-head=\"Ambassador Name\">\n <a [routerLink]=\"['/admin/users', agent.user_id]\">{{ agent.user.first_name ?? 'N/A' }}</a>\n </td>\n <td data-head=\"Email\">\n {{ agent.user.email !== null ? agent.user.email : 'N/A' }}\n </td>\n <td data-head=\"Percentage\">{{ agent.percentage }}</td>\n <td data-head=\"End Date\">{{ agent.end_date | dateFormat }}</td>\n <td data-head=\"Status\">\n <span class=\"badge\"\n color=\"success-grey\"\n [appDynamicBadge]=\"{ itemsArray: [true, false], item: agent.active }\">\n {{ (agent.active ? 'Admin.Subscriptions.Active' : 'Admin.Subscriptions.Inactive') | transloco }}\n </span>\n </td>\n <td data-head=\"Action\">\n <ul class=\"list-unstyled list-inline list-action\">\n <li pTooltip=\"Edit\"\n tooltipPosition=\"top\"\n appendTo=\"body\"\n class=\"me-2 me-sm-3\"\n [routerLink]=\"[\n '/admin/subscriptions/',\n agent.subscription_id,\n 'agent_details',\n agent.user_id\n ]\">\n <i class=\"fa fa-edit edit-icon\" aria-hidden=\"true\"></i>\n </li>\n <li pTooltip=\"Delete\"\n tooltipPosition=\"top\"\n appendTo=\"body\"\n class=\"me-2 me-sm-3\"\n (keydown.enter)=\"onDelete(agent?.user_id)\"\n (click)=\"onDelete(agent?.user_id)\">\n <i class=\"fa fa-trash delete-icon\" aria-hidden=\"true\"></i>\n </li>\n </ul>\n </td>\n </tr>\n </ng-template>\n </p-table>\n @if (totalRecords !== 0) {\n <pw-records-summary [showing]=\"dt?.value?.length ?? 0\" [total]=\"totalRecords\" />\n }\n </div>\n @if (totalRecords === 0 && isLoaded) {\n <div>\n <pw-no-data [withImage]=\"true\" [message]=\"'Admin.Subscriptions.NoAmbassadorsMessage' | transloco\">\n </pw-no-data>\n </div>\n }\n}\n@if (newEmbass) {\n <form [formGroup]=\"formEmbassador\"\n id=\"mainFrom\"\n class=\"mt-4 p-2\"\n (ngSubmit)=\"onAddEmbassador()\">\n\n <h3>{{ 'Admin.Subscriptions.Section.Ambassador' | transloco }}</h3>\n <div class=\"row\">\n <div class=\"col-12 col-md-4\">\n <div class=\"mb-3 ui-fluid skills-modal\">\n <pw-input-container\n [label]=\"'Admin.Subscriptions.Ambassador' | transloco\"\n [showTooltip]=\"true\"\n [tooltipText]=\"'Admin.Subscriptions.Tooltip.AmbassadorAdd' | transloco\"\n [useAriaLabelledbyOnly]=\"true\"\n controlId=\"subscription-agents-list-ambassador\">\n <p-auto-complete class=\"w-100\" appendTo=\"body\" [suggestions]=\"filteredUsers\"\n [attr.aria-labelledby]=\"'subscription-agents-list-ambassador-label'\"\n formControlName=\"email\"\n dataKey=\"id\"\n optionLabel=\"displayName\"\n (completeMethod)=\"search($event)\"\n [dropdown]=\"true\"\n placeholder=\"Search ambassadors...\"\n [multiple]=\"false\">\n </p-auto-complete>\n </pw-input-container>\n </div>\n </div>\n\n <div class=\"col-12 col-md-4\">\n <div class=\"mb-3\">\n <pw-input-container\n [label]=\"'Admin.Subscriptions.Percentage' | transloco\"\n [showTooltip]=\"true\"\n [tooltipText]=\"'Admin.Subscriptions.Tooltip.Percentage' | transloco\"\n name=\"percentage\"\n controlId=\"subscription-agents-list-percentage\"\n [errorMsg]=\"'Admin.Subscriptions.Validation.Percentage' | transloco\">\n <input type=\"number\"\n id=\"subscription-agents-list-percentage\"\n formControlName=\"percentage\"\n class=\"form-control\"\n name=\"input_percentage_2\"\n [attr.aria-label]=\"'Admin.Subscriptions.Percentage' | transloco\" />\n </pw-input-container>\n </div>\n </div>\n\n <div class=\"col-12 col-md-4\">\n <div class=\"mb-3\">\n <pw-input-container\n [label]=\"'Admin.Subscriptions.EndDate' | transloco\"\n [showTooltip]=\"true\"\n [tooltipText]=\"'Admin.Subscriptions.Tooltip.EndDate' | transloco\"\n name=\"endDate\"\n controlId=\"subscription-agents-list-endDate\"\n [errorMsg]=\"'Admin.Subscriptions.Validation.EndDate' | transloco\">\n <div class=\"input-group\">\n <input class=\"form-control\"\n id=\"subscription-agents-list-endDate\"\n name=\"endDate\"\n [placeholder]=\"'Admin.Subscriptions.Placeholder.EndDate' | transloco\"\n formControlName=\"endDate\"\n ngbDatepicker\n #d=\"ngbDatepicker\"\n (click)=\"d.open()\"\n [minDate]=\"{ day: 1, month: 1, year: 1950 }\"\n [maxDate]=\"{ day: 31, month: 12, year: 2050 }\"\n [attr.aria-label]=\"'Admin.Subscriptions.EndDate' | transloco\" />\n <button class=\"btn btn-primary\"\n type=\"button\"\n aria-label=\"Open date picker\"\n (click)=\"d.toggle()\">\n <i class=\"fa fa-calendar\" aria-hidden=\"true\"></i>\n </button>\n </div>\n </pw-input-container>\n </div>\n </div>\n </div>\n\n <!-- Payout destination (#951): the provider drives which fields render.\n Destination fields only show for a single selection — a bulk add would\n share one address across several people, so bulk-added ambassadors set\n their destination from the edit screen. -->\n <h3>{{ 'Admin.Subscriptions.Section.Payout' | transloco }}</h3>\n <div class=\"row\">\n <div class=\"col-12 col-md-4\">\n <div class=\"mb-3\">\n <pw-input-container\n [label]=\"'Admin.Subscriptions.Payout.Provider' | transloco\"\n [showTooltip]=\"true\"\n [tooltipText]=\"'Admin.Subscriptions.Tooltip.PayoutProvider' | transloco\"\n name=\"payout_provider\"\n controlId=\"subscription-agents-list-payout_provider\">\n <p-select\n class=\"w-100\"\n inputId=\"subscription-agents-list-payout_provider\"\n appendTo=\"body\"\n [options]=\"payoutProviders\"\n optionLabel=\"label\"\n optionValue=\"value\"\n formControlName=\"payout_provider\"\n [placeholder]=\"'Admin.Subscriptions.Payout.SelectProvider' | transloco\"\n (onChange)=\"onPayoutProviderChange($event.value)\">\n </p-select>\n </pw-input-container>\n </div>\n </div>\n\n @if (isSingleAmbassadorSelected) {\n @for (field of payoutFields; track field.control) {\n <div class=\"col-12 col-md-4\">\n <div class=\"mb-3\">\n <pw-input-container\n [label]=\"field.labelKey | transloco\"\n [showTooltip]=\"true\"\n [tooltipText]=\"'Admin.Subscriptions.Tooltip.PayoutDetails' | transloco\"\n [name]=\"field.control\"\n [controlId]=\"'subscription-agents-list-' + field.control\"\n [errorMsg]=\"'Admin.Subscriptions.Payout.FieldRequired' | transloco\">\n <input type=\"text\"\n class=\"form-control\"\n [id]=\"'subscription-agents-list-' + field.control\"\n [formControlName]=\"field.control\"\n [placeholder]=\"field.placeholderKey | transloco\"\n autocomplete=\"off\"\n [attr.aria-label]=\"field.labelKey | transloco\"/>\n </pw-input-container>\n </div>\n </div>\n }\n }\n </div>\n\n <!-- Provider caveat, driven by PAYOUT_PROVIDERS[].noticeKey so no provider is\n named in the template. Shown for a bulk selection too: the provider\n applies to every ambassador being created here, so the limitation is if\n anything more consequential than on the single-ambassador form. -->\n @if (payoutNoticeKey) {\n <div class=\"row mt-3\">\n <div class=\"col-12 col-md-8\">\n <div class=\"alert alert-warning mb-0\">\n {{ payoutNoticeKey | transloco }}\n </div>\n </div>\n </div>\n }\n\n <div class=\"row text-end mt-4\">\n <div class=\"col-12\">\n <button type=\"button\"\n (click)=\"newEmbass = false\"\n class=\"btn btn-outline-default me-2\">\n {{ 'Button.Cancel' | transloco }}\n </button>\n <button type=\"submit\"\n [buttonBusy]=\"submitted\"\n class=\"btn btn-primary\">\n Add Ambassador\n </button>\n </div>\n </div>\n </form>\n}\n",
23598
23650
  styles: ["#mainFrom{padding-bottom:144px}#mainFrom>h3{display:block;border-top:1px solid #e2e5ea;margin-top:2rem;padding-top:1.25rem}#mainFrom>h3:first-child{border-top:0;margin-top:.5rem;padding-top:0}.input-group>.form-control{border-top-right-radius:0!important;border-bottom-right-radius:0!important}.input-group>.btn{border-top-left-radius:0;border-bottom-left-radius:0}\n"],
23599
23651
  dependencies: [
23600
23652
  {
@@ -23710,6 +23762,12 @@ var SubscriptionAgentsListComponent = class SubscriptionAgentsListComponent exte
23710
23762
  "onStateRestore"
23711
23763
  ]
23712
23764
  },
23765
+ {
23766
+ kind: "directive",
23767
+ type: i2$3.ResizableColumn,
23768
+ selector: "[pResizableColumn]",
23769
+ inputs: ["pResizableColumnDisabled"]
23770
+ },
23713
23771
  {
23714
23772
  kind: "directive",
23715
23773
  type: i3$3.Tooltip,
@@ -24118,7 +24176,7 @@ i0.ɵɵngDeclareClassMetadata({
24118
24176
  args: [{
24119
24177
  selector: "pw-subscription-agents-list",
24120
24178
  standalone: false,
24121
- template: "@if (!newEmbass) {\n <div class=\"w-100 text-center mt-3 mb-3\">\n <div class=\"d-flex align-items-center\">\n <div class=\"ms-auto col-xs-12\">\n <a class=\"btn btn-sm btn-outline-primary float-end\"\n (click)=\"newEmbass = true\"\n id=\"btn-create\">\n <i class=\"fa fa-plus-circle me-2\" aria-hidden=\"true\"></i>Add Ambassadors\n </a>\n </div>\n </div>\n @if (!isLoaded) {\n <p-progress-spinner> </p-progress-spinner>\n }\n </div>\n <div class=\"primeng-datatable-container actions-collapsed table-responsive mt-0\"\n [class.hideTable]=\"totalUnfilteredCount === 0\">\n <p-table #dt\n [value]=\"allAgents\"\n [paginator]=\"totalRecords !== 0\"\n [rows]=\"PAGE_SIZE\"\n [lazy]=\"true\"\n [totalRecords]=\"totalRecords\"\n [loading]=\"loading\"\n [filterDelay]=\"1000\"\n [customSort]=\"true\">\n <ng-template #caption>\n <div class=\"text-end\">\n <p-iconfield iconPosition=\"left\">\n <p-inputicon><i class=\"fa fa-search\" aria-hidden=\"true\"></i></p-inputicon>\n <input type=\"text\"\n id=\"subscription-agents-list-search\"\n name=\"subscription-agents-list-search\"\n [(ngModel)]=\"searchText\"\n pInputText\n placeholder=\"Search ambassadors...\"\n (input)=\"dt.filterGlobal($event.target.value, 'contains')\"\n aria-label=\"Search ambassadors...\" />\n </p-iconfield>\n </div>\n </ng-template>\n <ng-template #header>\n <tr>\n <th scope=\"true\">{{ 'Admin.Subscriptions.AgentName' | transloco }}</th>\n <th scope=\"true\">{{ 'Label.Email' | transloco }}</th>\n <th scope=\"true\">{{ 'Admin.Subscriptions.Percentage' | transloco }}</th>\n <th scope=\"true\">{{ 'Admin.Subscriptions.EndDate' | transloco }}</th>\n <th scope=\"true\">{{ 'Admin.Subscriptions.Status' | transloco }}</th>\n <th scope=\"true\" class=\"actions-list-two\">{{ 'Label.Actions' | transloco }}</th>\n </tr>\n </ng-template>\n <ng-template #body\n let-agent>\n <tr>\n <td data-head=\"Ambassador Name\">\n <a [routerLink]=\"['/admin/users', agent.user_id]\">{{ agent.user.first_name ?? 'N/A' }}</a>\n </td>\n <td data-head=\"Email\">\n {{ agent.user.email !== null ? agent.user.email : 'N/A' }}\n </td>\n <td data-head=\"Percentage\">{{ agent.percentage }}</td>\n <td data-head=\"End Date\">{{ agent.end_date | dateFormat }}</td>\n <td data-head=\"Status\">\n <span class=\"badge\"\n color=\"success-grey\"\n [appDynamicBadge]=\"{ itemsArray: [true, false], item: agent.active }\">\n {{ (agent.active ? 'Admin.Subscriptions.Active' : 'Admin.Subscriptions.Inactive') | transloco }}\n </span>\n </td>\n <td data-head=\"Action\">\n <ul class=\"list-unstyled list-inline list-action\">\n <li pTooltip=\"Edit\"\n tooltipPosition=\"top\"\n appendTo=\"body\"\n class=\"me-2 me-sm-3\"\n [routerLink]=\"[\n '/admin/subscriptions/',\n agent.subscription_id,\n 'agent_details',\n agent.user_id\n ]\">\n <i class=\"fa fa-edit edit-icon\" aria-hidden=\"true\"></i>\n </li>\n <li pTooltip=\"Delete\"\n tooltipPosition=\"top\"\n appendTo=\"body\"\n class=\"me-2 me-sm-3\"\n (keydown.enter)=\"onDelete(agent?.user_id)\"\n (click)=\"onDelete(agent?.user_id)\">\n <i class=\"fa fa-trash delete-icon\" aria-hidden=\"true\"></i>\n </li>\n </ul>\n </td>\n </tr>\n </ng-template>\n </p-table>\n @if (totalRecords !== 0) {\n <pw-records-summary [showing]=\"dt?.value?.length ?? 0\" [total]=\"totalRecords\" />\n }\n </div>\n @if (totalRecords === 0 && isLoaded) {\n <div>\n <pw-no-data [withImage]=\"true\" [message]=\"'Admin.Subscriptions.NoAmbassadorsMessage' | transloco\">\n </pw-no-data>\n </div>\n }\n}\n@if (newEmbass) {\n <form [formGroup]=\"formEmbassador\"\n id=\"mainFrom\"\n class=\"mt-4 p-2\"\n (ngSubmit)=\"onAddEmbassador()\">\n\n <h3>{{ 'Admin.Subscriptions.Section.Ambassador' | transloco }}</h3>\n <div class=\"row\">\n <div class=\"col-12 col-md-4\">\n <div class=\"mb-3 ui-fluid skills-modal\">\n <pw-input-container\n [label]=\"'Admin.Subscriptions.Ambassador' | transloco\"\n [showTooltip]=\"true\"\n [tooltipText]=\"'Admin.Subscriptions.Tooltip.AmbassadorAdd' | transloco\"\n [useAriaLabelledbyOnly]=\"true\"\n controlId=\"subscription-agents-list-ambassador\">\n <p-auto-complete class=\"w-100\" appendTo=\"body\" [suggestions]=\"filteredUsers\"\n [attr.aria-labelledby]=\"'subscription-agents-list-ambassador-label'\"\n formControlName=\"email\"\n dataKey=\"id\"\n optionLabel=\"displayName\"\n (completeMethod)=\"search($event)\"\n [dropdown]=\"true\"\n placeholder=\"Search ambassadors...\"\n [multiple]=\"false\">\n </p-auto-complete>\n </pw-input-container>\n </div>\n </div>\n\n <div class=\"col-12 col-md-4\">\n <div class=\"mb-3\">\n <pw-input-container\n [label]=\"'Admin.Subscriptions.Percentage' | transloco\"\n [showTooltip]=\"true\"\n [tooltipText]=\"'Admin.Subscriptions.Tooltip.Percentage' | transloco\"\n name=\"percentage\"\n controlId=\"subscription-agents-list-percentage\"\n [errorMsg]=\"'Admin.Subscriptions.Validation.Percentage' | transloco\">\n <input type=\"number\"\n id=\"subscription-agents-list-percentage\"\n formControlName=\"percentage\"\n class=\"form-control\"\n name=\"input_percentage_2\"\n [attr.aria-label]=\"'Admin.Subscriptions.Percentage' | transloco\" />\n </pw-input-container>\n </div>\n </div>\n\n <div class=\"col-12 col-md-4\">\n <div class=\"mb-3\">\n <pw-input-container\n [label]=\"'Admin.Subscriptions.EndDate' | transloco\"\n [showTooltip]=\"true\"\n [tooltipText]=\"'Admin.Subscriptions.Tooltip.EndDate' | transloco\"\n name=\"endDate\"\n controlId=\"subscription-agents-list-endDate\"\n [errorMsg]=\"'Admin.Subscriptions.Validation.EndDate' | transloco\">\n <div class=\"input-group\">\n <input class=\"form-control\"\n id=\"subscription-agents-list-endDate\"\n name=\"endDate\"\n [placeholder]=\"'Admin.Subscriptions.Placeholder.EndDate' | transloco\"\n formControlName=\"endDate\"\n ngbDatepicker\n #d=\"ngbDatepicker\"\n (click)=\"d.open()\"\n [minDate]=\"{ day: 1, month: 1, year: 1950 }\"\n [maxDate]=\"{ day: 31, month: 12, year: 2050 }\"\n [attr.aria-label]=\"'Admin.Subscriptions.EndDate' | transloco\" />\n <button class=\"btn btn-primary\"\n type=\"button\"\n aria-label=\"Open date picker\"\n (click)=\"d.toggle()\">\n <i class=\"fa fa-calendar\" aria-hidden=\"true\"></i>\n </button>\n </div>\n </pw-input-container>\n </div>\n </div>\n </div>\n\n <!-- Payout destination (#951): the provider drives which fields render.\n Destination fields only show for a single selection — a bulk add would\n share one address across several people, so bulk-added ambassadors set\n their destination from the edit screen. -->\n <h3>{{ 'Admin.Subscriptions.Section.Payout' | transloco }}</h3>\n <div class=\"row\">\n <div class=\"col-12 col-md-4\">\n <div class=\"mb-3\">\n <pw-input-container\n [label]=\"'Admin.Subscriptions.Payout.Provider' | transloco\"\n [showTooltip]=\"true\"\n [tooltipText]=\"'Admin.Subscriptions.Tooltip.PayoutProvider' | transloco\"\n name=\"payout_provider\"\n controlId=\"subscription-agents-list-payout_provider\">\n <p-select\n class=\"w-100\"\n inputId=\"subscription-agents-list-payout_provider\"\n appendTo=\"body\"\n [options]=\"payoutProviders\"\n optionLabel=\"label\"\n optionValue=\"value\"\n formControlName=\"payout_provider\"\n [placeholder]=\"'Admin.Subscriptions.Payout.SelectProvider' | transloco\"\n (onChange)=\"onPayoutProviderChange($event.value)\">\n </p-select>\n </pw-input-container>\n </div>\n </div>\n\n @if (isSingleAmbassadorSelected) {\n @for (field of payoutFields; track field.control) {\n <div class=\"col-12 col-md-4\">\n <div class=\"mb-3\">\n <pw-input-container\n [label]=\"field.labelKey | transloco\"\n [showTooltip]=\"true\"\n [tooltipText]=\"'Admin.Subscriptions.Tooltip.PayoutDetails' | transloco\"\n [name]=\"field.control\"\n [controlId]=\"'subscription-agents-list-' + field.control\"\n [errorMsg]=\"'Admin.Subscriptions.Payout.FieldRequired' | transloco\">\n <input type=\"text\"\n class=\"form-control\"\n [id]=\"'subscription-agents-list-' + field.control\"\n [formControlName]=\"field.control\"\n [placeholder]=\"field.placeholderKey | transloco\"\n autocomplete=\"off\"\n [attr.aria-label]=\"field.labelKey | transloco\"/>\n </pw-input-container>\n </div>\n </div>\n }\n }\n </div>\n\n <!-- Provider caveat, driven by PAYOUT_PROVIDERS[].noticeKey so no provider is\n named in the template. Shown for a bulk selection too: the provider\n applies to every ambassador being created here, so the limitation is if\n anything more consequential than on the single-ambassador form. -->\n @if (payoutNoticeKey) {\n <div class=\"row mt-3\">\n <div class=\"col-12 col-md-8\">\n <div class=\"alert alert-warning mb-0\">\n {{ payoutNoticeKey | transloco }}\n </div>\n </div>\n </div>\n }\n\n <div class=\"row text-end mt-4\">\n <div class=\"col-12\">\n <button type=\"button\"\n (click)=\"newEmbass = false\"\n class=\"btn btn-outline-default me-2\">\n {{ 'Button.Cancel' | transloco }}\n </button>\n <button type=\"submit\"\n [buttonBusy]=\"submitted\"\n class=\"btn btn-primary\">\n Add Ambassador\n </button>\n </div>\n </div>\n </form>\n}\n",
24179
+ template: "@if (!newEmbass) {\n <div class=\"w-100 text-center mt-3 mb-3\">\n <div class=\"d-flex align-items-center\">\n <div class=\"ms-auto col-xs-12\">\n <a class=\"btn btn-sm btn-outline-primary float-end\"\n (click)=\"newEmbass = true\"\n id=\"btn-create\">\n <i class=\"fa fa-plus-circle me-2\" aria-hidden=\"true\"></i>Add Ambassadors\n </a>\n </div>\n </div>\n @if (!isLoaded) {\n <p-progress-spinner> </p-progress-spinner>\n }\n </div>\n <div class=\"primeng-datatable-container actions-collapsed table-responsive mt-0\"\n [class.hideTable]=\"totalUnfilteredCount === 0\">\n <p-table #dt\n stateKey=\"pw-table.admin-subscription-agents-list\"\n stateStorage=\"session\"\n [resizableColumns]=\"true\"\n columnResizeMode=\"expand\"\n [value]=\"allAgents\"\n [paginator]=\"totalRecords !== 0\"\n [rows]=\"PAGE_SIZE\"\n [lazy]=\"true\"\n [totalRecords]=\"totalRecords\"\n [loading]=\"loading\"\n [filterDelay]=\"1000\"\n [customSort]=\"true\">\n <ng-template #caption>\n <div class=\"text-end\">\n <p-iconfield iconPosition=\"left\">\n <p-inputicon><i class=\"fa fa-search\" aria-hidden=\"true\"></i></p-inputicon>\n <input type=\"text\"\n id=\"subscription-agents-list-search\"\n name=\"subscription-agents-list-search\"\n [(ngModel)]=\"searchText\"\n pInputText\n placeholder=\"Search ambassadors...\"\n (input)=\"dt.filterGlobal($event.target.value, 'contains')\"\n aria-label=\"Search ambassadors...\" />\n </p-iconfield>\n </div>\n </ng-template>\n <ng-template #header>\n <tr>\n <th pResizableColumn scope=\"true\">{{ 'Admin.Subscriptions.AgentName' | transloco }}</th>\n <th pResizableColumn scope=\"true\">{{ 'Label.Email' | transloco }}</th>\n <th pResizableColumn scope=\"true\">{{ 'Admin.Subscriptions.Percentage' | transloco }}</th>\n <th pResizableColumn scope=\"true\">{{ 'Admin.Subscriptions.EndDate' | transloco }}</th>\n <th pResizableColumn scope=\"true\">{{ 'Admin.Subscriptions.Status' | transloco }}</th>\n <th scope=\"true\" class=\"actions-list-two\">{{ 'Label.Actions' | transloco }}</th>\n </tr>\n </ng-template>\n <ng-template #body\n let-agent>\n <tr>\n <td data-head=\"Ambassador Name\">\n <a [routerLink]=\"['/admin/users', agent.user_id]\">{{ agent.user.first_name ?? 'N/A' }}</a>\n </td>\n <td data-head=\"Email\">\n {{ agent.user.email !== null ? agent.user.email : 'N/A' }}\n </td>\n <td data-head=\"Percentage\">{{ agent.percentage }}</td>\n <td data-head=\"End Date\">{{ agent.end_date | dateFormat }}</td>\n <td data-head=\"Status\">\n <span class=\"badge\"\n color=\"success-grey\"\n [appDynamicBadge]=\"{ itemsArray: [true, false], item: agent.active }\">\n {{ (agent.active ? 'Admin.Subscriptions.Active' : 'Admin.Subscriptions.Inactive') | transloco }}\n </span>\n </td>\n <td data-head=\"Action\">\n <ul class=\"list-unstyled list-inline list-action\">\n <li pTooltip=\"Edit\"\n tooltipPosition=\"top\"\n appendTo=\"body\"\n class=\"me-2 me-sm-3\"\n [routerLink]=\"[\n '/admin/subscriptions/',\n agent.subscription_id,\n 'agent_details',\n agent.user_id\n ]\">\n <i class=\"fa fa-edit edit-icon\" aria-hidden=\"true\"></i>\n </li>\n <li pTooltip=\"Delete\"\n tooltipPosition=\"top\"\n appendTo=\"body\"\n class=\"me-2 me-sm-3\"\n (keydown.enter)=\"onDelete(agent?.user_id)\"\n (click)=\"onDelete(agent?.user_id)\">\n <i class=\"fa fa-trash delete-icon\" aria-hidden=\"true\"></i>\n </li>\n </ul>\n </td>\n </tr>\n </ng-template>\n </p-table>\n @if (totalRecords !== 0) {\n <pw-records-summary [showing]=\"dt?.value?.length ?? 0\" [total]=\"totalRecords\" />\n }\n </div>\n @if (totalRecords === 0 && isLoaded) {\n <div>\n <pw-no-data [withImage]=\"true\" [message]=\"'Admin.Subscriptions.NoAmbassadorsMessage' | transloco\">\n </pw-no-data>\n </div>\n }\n}\n@if (newEmbass) {\n <form [formGroup]=\"formEmbassador\"\n id=\"mainFrom\"\n class=\"mt-4 p-2\"\n (ngSubmit)=\"onAddEmbassador()\">\n\n <h3>{{ 'Admin.Subscriptions.Section.Ambassador' | transloco }}</h3>\n <div class=\"row\">\n <div class=\"col-12 col-md-4\">\n <div class=\"mb-3 ui-fluid skills-modal\">\n <pw-input-container\n [label]=\"'Admin.Subscriptions.Ambassador' | transloco\"\n [showTooltip]=\"true\"\n [tooltipText]=\"'Admin.Subscriptions.Tooltip.AmbassadorAdd' | transloco\"\n [useAriaLabelledbyOnly]=\"true\"\n controlId=\"subscription-agents-list-ambassador\">\n <p-auto-complete class=\"w-100\" appendTo=\"body\" [suggestions]=\"filteredUsers\"\n [attr.aria-labelledby]=\"'subscription-agents-list-ambassador-label'\"\n formControlName=\"email\"\n dataKey=\"id\"\n optionLabel=\"displayName\"\n (completeMethod)=\"search($event)\"\n [dropdown]=\"true\"\n placeholder=\"Search ambassadors...\"\n [multiple]=\"false\">\n </p-auto-complete>\n </pw-input-container>\n </div>\n </div>\n\n <div class=\"col-12 col-md-4\">\n <div class=\"mb-3\">\n <pw-input-container\n [label]=\"'Admin.Subscriptions.Percentage' | transloco\"\n [showTooltip]=\"true\"\n [tooltipText]=\"'Admin.Subscriptions.Tooltip.Percentage' | transloco\"\n name=\"percentage\"\n controlId=\"subscription-agents-list-percentage\"\n [errorMsg]=\"'Admin.Subscriptions.Validation.Percentage' | transloco\">\n <input type=\"number\"\n id=\"subscription-agents-list-percentage\"\n formControlName=\"percentage\"\n class=\"form-control\"\n name=\"input_percentage_2\"\n [attr.aria-label]=\"'Admin.Subscriptions.Percentage' | transloco\" />\n </pw-input-container>\n </div>\n </div>\n\n <div class=\"col-12 col-md-4\">\n <div class=\"mb-3\">\n <pw-input-container\n [label]=\"'Admin.Subscriptions.EndDate' | transloco\"\n [showTooltip]=\"true\"\n [tooltipText]=\"'Admin.Subscriptions.Tooltip.EndDate' | transloco\"\n name=\"endDate\"\n controlId=\"subscription-agents-list-endDate\"\n [errorMsg]=\"'Admin.Subscriptions.Validation.EndDate' | transloco\">\n <div class=\"input-group\">\n <input class=\"form-control\"\n id=\"subscription-agents-list-endDate\"\n name=\"endDate\"\n [placeholder]=\"'Admin.Subscriptions.Placeholder.EndDate' | transloco\"\n formControlName=\"endDate\"\n ngbDatepicker\n #d=\"ngbDatepicker\"\n (click)=\"d.open()\"\n [minDate]=\"{ day: 1, month: 1, year: 1950 }\"\n [maxDate]=\"{ day: 31, month: 12, year: 2050 }\"\n [attr.aria-label]=\"'Admin.Subscriptions.EndDate' | transloco\" />\n <button class=\"btn btn-primary\"\n type=\"button\"\n aria-label=\"Open date picker\"\n (click)=\"d.toggle()\">\n <i class=\"fa fa-calendar\" aria-hidden=\"true\"></i>\n </button>\n </div>\n </pw-input-container>\n </div>\n </div>\n </div>\n\n <!-- Payout destination (#951): the provider drives which fields render.\n Destination fields only show for a single selection — a bulk add would\n share one address across several people, so bulk-added ambassadors set\n their destination from the edit screen. -->\n <h3>{{ 'Admin.Subscriptions.Section.Payout' | transloco }}</h3>\n <div class=\"row\">\n <div class=\"col-12 col-md-4\">\n <div class=\"mb-3\">\n <pw-input-container\n [label]=\"'Admin.Subscriptions.Payout.Provider' | transloco\"\n [showTooltip]=\"true\"\n [tooltipText]=\"'Admin.Subscriptions.Tooltip.PayoutProvider' | transloco\"\n name=\"payout_provider\"\n controlId=\"subscription-agents-list-payout_provider\">\n <p-select\n class=\"w-100\"\n inputId=\"subscription-agents-list-payout_provider\"\n appendTo=\"body\"\n [options]=\"payoutProviders\"\n optionLabel=\"label\"\n optionValue=\"value\"\n formControlName=\"payout_provider\"\n [placeholder]=\"'Admin.Subscriptions.Payout.SelectProvider' | transloco\"\n (onChange)=\"onPayoutProviderChange($event.value)\">\n </p-select>\n </pw-input-container>\n </div>\n </div>\n\n @if (isSingleAmbassadorSelected) {\n @for (field of payoutFields; track field.control) {\n <div class=\"col-12 col-md-4\">\n <div class=\"mb-3\">\n <pw-input-container\n [label]=\"field.labelKey | transloco\"\n [showTooltip]=\"true\"\n [tooltipText]=\"'Admin.Subscriptions.Tooltip.PayoutDetails' | transloco\"\n [name]=\"field.control\"\n [controlId]=\"'subscription-agents-list-' + field.control\"\n [errorMsg]=\"'Admin.Subscriptions.Payout.FieldRequired' | transloco\">\n <input type=\"text\"\n class=\"form-control\"\n [id]=\"'subscription-agents-list-' + field.control\"\n [formControlName]=\"field.control\"\n [placeholder]=\"field.placeholderKey | transloco\"\n autocomplete=\"off\"\n [attr.aria-label]=\"field.labelKey | transloco\"/>\n </pw-input-container>\n </div>\n </div>\n }\n }\n </div>\n\n <!-- Provider caveat, driven by PAYOUT_PROVIDERS[].noticeKey so no provider is\n named in the template. Shown for a bulk selection too: the provider\n applies to every ambassador being created here, so the limitation is if\n anything more consequential than on the single-ambassador form. -->\n @if (payoutNoticeKey) {\n <div class=\"row mt-3\">\n <div class=\"col-12 col-md-8\">\n <div class=\"alert alert-warning mb-0\">\n {{ payoutNoticeKey | transloco }}\n </div>\n </div>\n </div>\n }\n\n <div class=\"row text-end mt-4\">\n <div class=\"col-12\">\n <button type=\"button\"\n (click)=\"newEmbass = false\"\n class=\"btn btn-outline-default me-2\">\n {{ 'Button.Cancel' | transloco }}\n </button>\n <button type=\"submit\"\n [buttonBusy]=\"submitted\"\n class=\"btn btn-primary\">\n Add Ambassador\n </button>\n </div>\n </div>\n </form>\n}\n",
24122
24180
  styles: ["#mainFrom{padding-bottom:144px}#mainFrom>h3{display:block;border-top:1px solid #e2e5ea;margin-top:2rem;padding-top:1.25rem}#mainFrom>h3:first-child{border-top:0;margin-top:.5rem;padding-top:0}.input-group>.form-control{border-top-right-radius:0!important;border-bottom-right-radius:0!important}.input-group>.btn{border-top-left-radius:0;border-bottom-left-radius:0}\n"]
24123
24181
  }]
24124
24182
  }],
@@ -24191,6 +24249,9 @@ var SubscriptionInvoicesComponent = class SubscriptionInvoicesComponent extends
24191
24249
  amount(cents) {
24192
24250
  return (cents ?? 0) / 100;
24193
24251
  }
24252
+ isUnrecorded(cents) {
24253
+ return cents === null || cents === void 0;
24254
+ }
24194
24255
  getInvoices() {
24195
24256
  if (!this.id) return;
24196
24257
  this.loading = true;
@@ -24232,8 +24293,8 @@ var SubscriptionInvoicesComponent = class SubscriptionInvoicesComponent extends
24232
24293
  selector: "pw-subscription-invoices",
24233
24294
  usesInheritance: true,
24234
24295
  ngImport: i0,
24235
- template: "<pw-loader [isVisible]=\"!isLoaded\"></pw-loader>\n@if (isLoaded) {\n @if (loadFailed) {\n <pw-no-data [withImage]=\"true\" [message]=\"'Admin.Subscriptions.Invoices.LoadError' | transloco\" />\n } @else if (data.unfiltered_count === 0) {\n <pw-no-data [withImage]=\"true\"\n [message]=\"'Admin.Subscriptions.Invoices.NoDataMessage' | transloco\"\n [description]=\"'Admin.Subscriptions.Invoices.NoDataDescription' | transloco\" />\n } @else {\n <div class=\"primeng-datatable-container actions-collapsed mt table-responsive subscription-invoices\">\n <p-table #dt\n [value]=\"data.invoices\"\n [paginator]=\"data.object_count > PAGE_SIZE\"\n [lazy]=\"true\"\n [lazyLoadOnInit]=\"false\"\n [rows]=\"PAGE_SIZE\"\n [totalRecords]=\"data.object_count\"\n [loading]=\"loading\"\n (onLazyLoad)=\"onLazyLoad($event)\">\n <ng-template #caption>\n <div class=\"search-filter\">\n <div class=\"col-12 col-sm-4\">\n <p-select inputId=\"subscription-invoices-payment-type\"\n [options]=\"paymentTypeOptions\"\n optionLabel=\"label\"\n optionValue=\"value\"\n [(ngModel)]=\"paymentType\"\n (onChange)=\"onPaymentTypeChange()\"\n [showClear]=\"true\"\n [placeholder]=\"'Admin.Subscriptions.Invoices.FilterPaymentType' | transloco\"\n appendTo=\"body\">\n </p-select>\n </div>\n </div>\n </ng-template>\n <ng-template #header>\n <tr>\n <th scope=\"col\">{{ 'Admin.Subscriptions.Invoices.Number' | transloco }}</th>\n <th scope=\"col\">{{ 'Admin.Subscriptions.Invoices.Date' | transloco }}</th>\n <th scope=\"col\">{{ 'Label.Product' | transloco }}</th>\n <th scope=\"col\">{{ 'Admin.Subscriptions.Invoices.PaymentTypeColumn' | transloco }}</th>\n <th scope=\"col\">{{ 'Admin.Subscriptions.Invoices.PaidVia' | transloco }}</th>\n <th scope=\"col\" class=\"text-end\">{{ 'Label.Total' | transloco }}</th>\n <th scope=\"col\" class=\"actions-list-two\">{{ 'Label.Actions' | transloco }}</th>\n </tr>\n </ng-template>\n <ng-template #body let-invoice>\n <tr>\n <td [attr.data-head]=\"'Admin.Subscriptions.Invoices.Number' | transloco\"><span class=\"invoice-number\">{{ invoice.number }}</span></td>\n <td class=\"col-date\" [attr.data-head]=\"'Admin.Subscriptions.Invoices.Date' | transloco\">{{ invoice.date ? (invoice.date | dateFormat) : '-' }}</td>\n <td class=\"col-product\" [attr.data-head]=\"'Label.Product' | transloco\">\n @if (invoice.product && canOpenProduct) {\n <a [routerLink]=\"[routers.productDetails + invoice.product.id]\">{{ invoice.product.name }}</a>\n } @else {\n {{ invoice.product?.name || '-' }}\n }\n </td>\n <td class=\"col-type\" [attr.data-head]=\"'Admin.Subscriptions.Invoices.PaymentTypeColumn' | transloco\">\n <span class=\"badge\" [ngClass]=\"invoice.payment_type === 'primary' ? 'bg-cyan' : 'bg-warning'\">\n {{ 'Admin.Subscriptions.Invoices.PaymentType.' + invoice.payment_type | transloco }}\n </span>\n </td>\n <td [attr.data-head]=\"'Admin.Subscriptions.Invoices.PaidVia' | transloco\"><span class=\"text-capitalize\">{{ invoice.paid_via }}</span></td>\n <td class=\"col-total text-end\" [attr.data-head]=\"'Label.Total' | transloco\">\n {{ amount(invoice.total_in_cents) | currency: (invoice.currency || 'USD') : 'symbol' : '1.2-2' }}\n </td>\n <td class=\"col-action\" data-head=\"Action\">\n <ul class=\"list-unstyled list-inline list-action\">\n @if (invoice.downloadable) {\n <li role=\"button\" tabindex=\"0\"\n data-cy=\"download-subscription-invoice\"\n [pTooltip]=\"'Admin.Subscriptions.Invoices.Download' | transloco\"\n tooltipPosition=\"top\" appendTo=\"body\"\n [attr.aria-label]=\"'Admin.Subscriptions.Invoices.Download' | transloco\"\n (click)=\"download(invoice)\" (keydown.enter)=\"download(invoice)\">\n <i class=\"fa fa-download edit-icon\" aria-hidden=\"true\"></i>\n </li>\n } @else {\n <li class=\"invoice-download-disabled\" role=\"img\"\n [pTooltip]=\"'Admin.Subscriptions.Invoices.NoFile' | transloco\"\n tooltipPosition=\"top\" appendTo=\"body\"\n [attr.aria-label]=\"'Admin.Subscriptions.Invoices.NoFile' | transloco\">\n <i class=\"fa fa-download edit-icon\" aria-hidden=\"true\"></i>\n </li>\n }\n </ul>\n </td>\n </tr>\n </ng-template>\n </p-table>\n @if (data.object_count === 0) {\n <pw-no-data [withImage]=\"true\"\n [message]=\"'Search.NoDataMessage' | transloco\"\n [description]=\"'Search.NoDataDescription' | transloco\" />\n } @else {\n <pw-records-summary [showing]=\"data.invoices.length\" [total]=\"data.object_count\" />\n }\n </div>\n }\n}\n",
24236
- styles: [".subscription-invoices .invoice-number{color:#5a6473;font-variant-numeric:tabular-nums}.subscription-invoices td.col-total,.subscription-invoices td.col-date{white-space:nowrap;font-variant-numeric:tabular-nums}.subscription-invoices .invoice-download-disabled{cursor:not-allowed}.subscription-invoices .invoice-download-disabled .edit-icon,.subscription-invoices .invoice-download-disabled:hover .edit-icon{color:#a8afbc!important}\n"],
24296
+ template: "<pw-loader [isVisible]=\"!isLoaded\"></pw-loader>\n@if (isLoaded) {\n @if (loadFailed) {\n <pw-no-data [withImage]=\"true\" [message]=\"'Admin.Subscriptions.Invoices.LoadError' | transloco\" />\n } @else if (data.unfiltered_count === 0) {\n <pw-no-data [withImage]=\"true\"\n [message]=\"'Admin.Subscriptions.Invoices.NoDataMessage' | transloco\"\n [description]=\"'Admin.Subscriptions.Invoices.NoDataDescription' | transloco\" />\n } @else {\n <div class=\"primeng-datatable-container actions-collapsed mt table-responsive subscription-invoices\">\n <p-table #dt\n [value]=\"data.invoices\"\n [paginator]=\"data.object_count > PAGE_SIZE\"\n [lazy]=\"true\"\n [lazyLoadOnInit]=\"false\"\n [rows]=\"PAGE_SIZE\"\n [totalRecords]=\"data.object_count\"\n [loading]=\"loading\"\n (onLazyLoad)=\"onLazyLoad($event)\">\n <ng-template #caption>\n <div class=\"search-filter\">\n <div class=\"col-12 col-sm-4\">\n <p-select inputId=\"subscription-invoices-payment-type\"\n [options]=\"paymentTypeOptions\"\n optionLabel=\"label\"\n optionValue=\"value\"\n [(ngModel)]=\"paymentType\"\n (onChange)=\"onPaymentTypeChange()\"\n [showClear]=\"true\"\n [placeholder]=\"'Admin.Subscriptions.Invoices.FilterPaymentType' | transloco\"\n appendTo=\"body\">\n </p-select>\n </div>\n </div>\n </ng-template>\n <ng-template #header>\n <tr>\n <th scope=\"col\">{{ 'Admin.Subscriptions.Invoices.Number' | transloco }}</th>\n <th scope=\"col\">{{ 'Admin.Subscriptions.Invoices.Date' | transloco }}</th>\n <th scope=\"col\">{{ 'Label.Product' | transloco }}</th>\n <th scope=\"col\">{{ 'Admin.Subscriptions.Invoices.PaymentTypeColumn' | transloco }}</th>\n <th scope=\"col\">{{ 'Admin.Subscriptions.Invoices.PaidVia' | transloco }}</th>\n <th scope=\"col\" class=\"col-total-excl text-end\">{{ 'Admin.Subscriptions.Invoices.TotalExclGst' | transloco }}</th>\n <th scope=\"col\" class=\"col-gst text-end\">{{ 'Admin.Subscriptions.Invoices.Gst' | transloco }}</th>\n <th scope=\"col\" class=\"col-total text-end\">{{ 'Label.Total' | transloco }}</th>\n <th scope=\"col\" class=\"actions-list-two\">{{ 'Label.Actions' | transloco }}</th>\n </tr>\n </ng-template>\n <ng-template #body let-invoice>\n <tr>\n <td [attr.data-head]=\"'Admin.Subscriptions.Invoices.Number' | transloco\"><span class=\"invoice-number\">{{ invoice.number }}</span></td>\n <td class=\"col-date\" [attr.data-head]=\"'Admin.Subscriptions.Invoices.Date' | transloco\">{{ invoice.date ? (invoice.date | dateFormat) : '-' }}</td>\n <td class=\"col-product\" [attr.data-head]=\"'Label.Product' | transloco\">\n @if (invoice.product && canOpenProduct) {\n <a [routerLink]=\"[routers.productDetails + invoice.product.id]\">{{ invoice.product.name }}</a>\n } @else {\n {{ invoice.product?.name || '-' }}\n }\n </td>\n <td class=\"col-type\" [attr.data-head]=\"'Admin.Subscriptions.Invoices.PaymentTypeColumn' | transloco\">\n <span class=\"badge\" [ngClass]=\"invoice.payment_type === 'primary' ? 'bg-cyan' : 'bg-warning'\">\n {{ 'Admin.Subscriptions.Invoices.PaymentType.' + invoice.payment_type | transloco }}\n </span>\n </td>\n <td [attr.data-head]=\"'Admin.Subscriptions.Invoices.PaidVia' | transloco\"><span class=\"text-capitalize\">{{ invoice.paid_via }}</span></td>\n <td class=\"col-total-excl text-end\" [attr.data-head]=\"'Admin.Subscriptions.Invoices.TotalExclGst' | transloco\">\n @if (isUnrecorded(invoice.total_excl_gst_in_cents)) {\n -\n } @else {\n {{ amount(invoice.total_excl_gst_in_cents) | currency: (invoice.currency || 'USD') : 'symbol' : '1.2-2' }}\n }\n </td>\n <td class=\"col-gst text-end\" [attr.data-head]=\"'Admin.Subscriptions.Invoices.Gst' | transloco\">\n @if (isUnrecorded(invoice.gst_in_cents)) {\n -\n } @else {\n {{ amount(invoice.gst_in_cents) | currency: (invoice.currency || 'USD') : 'symbol' : '1.2-2' }}\n }\n </td>\n <td class=\"col-total text-end\" [attr.data-head]=\"'Label.Total' | transloco\">\n {{ amount(invoice.total_in_cents) | currency: (invoice.currency || 'USD') : 'symbol' : '1.2-2' }}\n </td>\n <td class=\"col-action\" data-head=\"Action\">\n <ul class=\"list-unstyled list-inline list-action\">\n @if (invoice.downloadable) {\n <li data-cy=\"download-subscription-invoice\"\n [pTooltip]=\"'Admin.Subscriptions.Invoices.Download' | transloco\"\n tooltipPosition=\"top\" appendTo=\"body\"\n [attr.aria-label]=\"'Admin.Subscriptions.Invoices.Download' | transloco\"\n (click)=\"download(invoice)\" (keydown.enter)=\"download(invoice)\">\n <i class=\"fa fa-download edit-icon\" aria-hidden=\"true\"></i>\n </li>\n } @else {\n <li class=\"invoice-download-disabled\"\n [pTooltip]=\"'Admin.Subscriptions.Invoices.NoFile' | transloco\"\n tooltipPosition=\"top\" appendTo=\"body\"\n [attr.aria-label]=\"'Admin.Subscriptions.Invoices.NoFile' | transloco\">\n <i class=\"fa fa-download edit-icon\" aria-hidden=\"true\"></i>\n </li>\n }\n </ul>\n </td>\n </tr>\n </ng-template>\n </p-table>\n @if (data.object_count === 0) {\n <pw-no-data [withImage]=\"true\"\n [message]=\"'Search.NoDataMessage' | transloco\"\n [description]=\"'Search.NoDataDescription' | transloco\" />\n } @else {\n <pw-records-summary [showing]=\"data.invoices.length\" [total]=\"data.object_count\" />\n }\n </div>\n }\n}\n",
24297
+ styles: [".subscription-invoices .invoice-number{color:#5a6473;font-variant-numeric:tabular-nums}.subscription-invoices td.col-total-excl,.subscription-invoices td.col-gst,.subscription-invoices td.col-total,.subscription-invoices td.col-date{white-space:nowrap;font-variant-numeric:tabular-nums}@media(min-width:426px){.subscription-invoices .col-total-excl,.subscription-invoices .col-gst,.subscription-invoices .col-total{width:1%;white-space:nowrap}}@media(min-width:1200px){.subscription-invoices .col-total-excl,.subscription-invoices .col-gst,.subscription-invoices .col-total{width:120px}}.subscription-invoices .invoice-download-disabled{cursor:not-allowed}.subscription-invoices .invoice-download-disabled .edit-icon,.subscription-invoices .invoice-download-disabled:hover .edit-icon{color:#a8afbc!important}\n"],
24237
24298
  dependencies: [
24238
24299
  {
24239
24300
  kind: "component",
@@ -24544,8 +24605,8 @@ i0.ɵɵngDeclareClassMetadata({
24544
24605
  args: [{
24545
24606
  selector: "pw-subscription-invoices",
24546
24607
  standalone: false,
24547
- template: "<pw-loader [isVisible]=\"!isLoaded\"></pw-loader>\n@if (isLoaded) {\n @if (loadFailed) {\n <pw-no-data [withImage]=\"true\" [message]=\"'Admin.Subscriptions.Invoices.LoadError' | transloco\" />\n } @else if (data.unfiltered_count === 0) {\n <pw-no-data [withImage]=\"true\"\n [message]=\"'Admin.Subscriptions.Invoices.NoDataMessage' | transloco\"\n [description]=\"'Admin.Subscriptions.Invoices.NoDataDescription' | transloco\" />\n } @else {\n <div class=\"primeng-datatable-container actions-collapsed mt table-responsive subscription-invoices\">\n <p-table #dt\n [value]=\"data.invoices\"\n [paginator]=\"data.object_count > PAGE_SIZE\"\n [lazy]=\"true\"\n [lazyLoadOnInit]=\"false\"\n [rows]=\"PAGE_SIZE\"\n [totalRecords]=\"data.object_count\"\n [loading]=\"loading\"\n (onLazyLoad)=\"onLazyLoad($event)\">\n <ng-template #caption>\n <div class=\"search-filter\">\n <div class=\"col-12 col-sm-4\">\n <p-select inputId=\"subscription-invoices-payment-type\"\n [options]=\"paymentTypeOptions\"\n optionLabel=\"label\"\n optionValue=\"value\"\n [(ngModel)]=\"paymentType\"\n (onChange)=\"onPaymentTypeChange()\"\n [showClear]=\"true\"\n [placeholder]=\"'Admin.Subscriptions.Invoices.FilterPaymentType' | transloco\"\n appendTo=\"body\">\n </p-select>\n </div>\n </div>\n </ng-template>\n <ng-template #header>\n <tr>\n <th scope=\"col\">{{ 'Admin.Subscriptions.Invoices.Number' | transloco }}</th>\n <th scope=\"col\">{{ 'Admin.Subscriptions.Invoices.Date' | transloco }}</th>\n <th scope=\"col\">{{ 'Label.Product' | transloco }}</th>\n <th scope=\"col\">{{ 'Admin.Subscriptions.Invoices.PaymentTypeColumn' | transloco }}</th>\n <th scope=\"col\">{{ 'Admin.Subscriptions.Invoices.PaidVia' | transloco }}</th>\n <th scope=\"col\" class=\"text-end\">{{ 'Label.Total' | transloco }}</th>\n <th scope=\"col\" class=\"actions-list-two\">{{ 'Label.Actions' | transloco }}</th>\n </tr>\n </ng-template>\n <ng-template #body let-invoice>\n <tr>\n <td [attr.data-head]=\"'Admin.Subscriptions.Invoices.Number' | transloco\"><span class=\"invoice-number\">{{ invoice.number }}</span></td>\n <td class=\"col-date\" [attr.data-head]=\"'Admin.Subscriptions.Invoices.Date' | transloco\">{{ invoice.date ? (invoice.date | dateFormat) : '-' }}</td>\n <td class=\"col-product\" [attr.data-head]=\"'Label.Product' | transloco\">\n @if (invoice.product && canOpenProduct) {\n <a [routerLink]=\"[routers.productDetails + invoice.product.id]\">{{ invoice.product.name }}</a>\n } @else {\n {{ invoice.product?.name || '-' }}\n }\n </td>\n <td class=\"col-type\" [attr.data-head]=\"'Admin.Subscriptions.Invoices.PaymentTypeColumn' | transloco\">\n <span class=\"badge\" [ngClass]=\"invoice.payment_type === 'primary' ? 'bg-cyan' : 'bg-warning'\">\n {{ 'Admin.Subscriptions.Invoices.PaymentType.' + invoice.payment_type | transloco }}\n </span>\n </td>\n <td [attr.data-head]=\"'Admin.Subscriptions.Invoices.PaidVia' | transloco\"><span class=\"text-capitalize\">{{ invoice.paid_via }}</span></td>\n <td class=\"col-total text-end\" [attr.data-head]=\"'Label.Total' | transloco\">\n {{ amount(invoice.total_in_cents) | currency: (invoice.currency || 'USD') : 'symbol' : '1.2-2' }}\n </td>\n <td class=\"col-action\" data-head=\"Action\">\n <ul class=\"list-unstyled list-inline list-action\">\n @if (invoice.downloadable) {\n <li role=\"button\" tabindex=\"0\"\n data-cy=\"download-subscription-invoice\"\n [pTooltip]=\"'Admin.Subscriptions.Invoices.Download' | transloco\"\n tooltipPosition=\"top\" appendTo=\"body\"\n [attr.aria-label]=\"'Admin.Subscriptions.Invoices.Download' | transloco\"\n (click)=\"download(invoice)\" (keydown.enter)=\"download(invoice)\">\n <i class=\"fa fa-download edit-icon\" aria-hidden=\"true\"></i>\n </li>\n } @else {\n <li class=\"invoice-download-disabled\" role=\"img\"\n [pTooltip]=\"'Admin.Subscriptions.Invoices.NoFile' | transloco\"\n tooltipPosition=\"top\" appendTo=\"body\"\n [attr.aria-label]=\"'Admin.Subscriptions.Invoices.NoFile' | transloco\">\n <i class=\"fa fa-download edit-icon\" aria-hidden=\"true\"></i>\n </li>\n }\n </ul>\n </td>\n </tr>\n </ng-template>\n </p-table>\n @if (data.object_count === 0) {\n <pw-no-data [withImage]=\"true\"\n [message]=\"'Search.NoDataMessage' | transloco\"\n [description]=\"'Search.NoDataDescription' | transloco\" />\n } @else {\n <pw-records-summary [showing]=\"data.invoices.length\" [total]=\"data.object_count\" />\n }\n </div>\n }\n}\n",
24548
- styles: [".subscription-invoices .invoice-number{color:#5a6473;font-variant-numeric:tabular-nums}.subscription-invoices td.col-total,.subscription-invoices td.col-date{white-space:nowrap;font-variant-numeric:tabular-nums}.subscription-invoices .invoice-download-disabled{cursor:not-allowed}.subscription-invoices .invoice-download-disabled .edit-icon,.subscription-invoices .invoice-download-disabled:hover .edit-icon{color:#a8afbc!important}\n"]
24608
+ template: "<pw-loader [isVisible]=\"!isLoaded\"></pw-loader>\n@if (isLoaded) {\n @if (loadFailed) {\n <pw-no-data [withImage]=\"true\" [message]=\"'Admin.Subscriptions.Invoices.LoadError' | transloco\" />\n } @else if (data.unfiltered_count === 0) {\n <pw-no-data [withImage]=\"true\"\n [message]=\"'Admin.Subscriptions.Invoices.NoDataMessage' | transloco\"\n [description]=\"'Admin.Subscriptions.Invoices.NoDataDescription' | transloco\" />\n } @else {\n <div class=\"primeng-datatable-container actions-collapsed mt table-responsive subscription-invoices\">\n <p-table #dt\n [value]=\"data.invoices\"\n [paginator]=\"data.object_count > PAGE_SIZE\"\n [lazy]=\"true\"\n [lazyLoadOnInit]=\"false\"\n [rows]=\"PAGE_SIZE\"\n [totalRecords]=\"data.object_count\"\n [loading]=\"loading\"\n (onLazyLoad)=\"onLazyLoad($event)\">\n <ng-template #caption>\n <div class=\"search-filter\">\n <div class=\"col-12 col-sm-4\">\n <p-select inputId=\"subscription-invoices-payment-type\"\n [options]=\"paymentTypeOptions\"\n optionLabel=\"label\"\n optionValue=\"value\"\n [(ngModel)]=\"paymentType\"\n (onChange)=\"onPaymentTypeChange()\"\n [showClear]=\"true\"\n [placeholder]=\"'Admin.Subscriptions.Invoices.FilterPaymentType' | transloco\"\n appendTo=\"body\">\n </p-select>\n </div>\n </div>\n </ng-template>\n <ng-template #header>\n <tr>\n <th scope=\"col\">{{ 'Admin.Subscriptions.Invoices.Number' | transloco }}</th>\n <th scope=\"col\">{{ 'Admin.Subscriptions.Invoices.Date' | transloco }}</th>\n <th scope=\"col\">{{ 'Label.Product' | transloco }}</th>\n <th scope=\"col\">{{ 'Admin.Subscriptions.Invoices.PaymentTypeColumn' | transloco }}</th>\n <th scope=\"col\">{{ 'Admin.Subscriptions.Invoices.PaidVia' | transloco }}</th>\n <th scope=\"col\" class=\"col-total-excl text-end\">{{ 'Admin.Subscriptions.Invoices.TotalExclGst' | transloco }}</th>\n <th scope=\"col\" class=\"col-gst text-end\">{{ 'Admin.Subscriptions.Invoices.Gst' | transloco }}</th>\n <th scope=\"col\" class=\"col-total text-end\">{{ 'Label.Total' | transloco }}</th>\n <th scope=\"col\" class=\"actions-list-two\">{{ 'Label.Actions' | transloco }}</th>\n </tr>\n </ng-template>\n <ng-template #body let-invoice>\n <tr>\n <td [attr.data-head]=\"'Admin.Subscriptions.Invoices.Number' | transloco\"><span class=\"invoice-number\">{{ invoice.number }}</span></td>\n <td class=\"col-date\" [attr.data-head]=\"'Admin.Subscriptions.Invoices.Date' | transloco\">{{ invoice.date ? (invoice.date | dateFormat) : '-' }}</td>\n <td class=\"col-product\" [attr.data-head]=\"'Label.Product' | transloco\">\n @if (invoice.product && canOpenProduct) {\n <a [routerLink]=\"[routers.productDetails + invoice.product.id]\">{{ invoice.product.name }}</a>\n } @else {\n {{ invoice.product?.name || '-' }}\n }\n </td>\n <td class=\"col-type\" [attr.data-head]=\"'Admin.Subscriptions.Invoices.PaymentTypeColumn' | transloco\">\n <span class=\"badge\" [ngClass]=\"invoice.payment_type === 'primary' ? 'bg-cyan' : 'bg-warning'\">\n {{ 'Admin.Subscriptions.Invoices.PaymentType.' + invoice.payment_type | transloco }}\n </span>\n </td>\n <td [attr.data-head]=\"'Admin.Subscriptions.Invoices.PaidVia' | transloco\"><span class=\"text-capitalize\">{{ invoice.paid_via }}</span></td>\n <td class=\"col-total-excl text-end\" [attr.data-head]=\"'Admin.Subscriptions.Invoices.TotalExclGst' | transloco\">\n @if (isUnrecorded(invoice.total_excl_gst_in_cents)) {\n -\n } @else {\n {{ amount(invoice.total_excl_gst_in_cents) | currency: (invoice.currency || 'USD') : 'symbol' : '1.2-2' }}\n }\n </td>\n <td class=\"col-gst text-end\" [attr.data-head]=\"'Admin.Subscriptions.Invoices.Gst' | transloco\">\n @if (isUnrecorded(invoice.gst_in_cents)) {\n -\n } @else {\n {{ amount(invoice.gst_in_cents) | currency: (invoice.currency || 'USD') : 'symbol' : '1.2-2' }}\n }\n </td>\n <td class=\"col-total text-end\" [attr.data-head]=\"'Label.Total' | transloco\">\n {{ amount(invoice.total_in_cents) | currency: (invoice.currency || 'USD') : 'symbol' : '1.2-2' }}\n </td>\n <td class=\"col-action\" data-head=\"Action\">\n <ul class=\"list-unstyled list-inline list-action\">\n @if (invoice.downloadable) {\n <li data-cy=\"download-subscription-invoice\"\n [pTooltip]=\"'Admin.Subscriptions.Invoices.Download' | transloco\"\n tooltipPosition=\"top\" appendTo=\"body\"\n [attr.aria-label]=\"'Admin.Subscriptions.Invoices.Download' | transloco\"\n (click)=\"download(invoice)\" (keydown.enter)=\"download(invoice)\">\n <i class=\"fa fa-download edit-icon\" aria-hidden=\"true\"></i>\n </li>\n } @else {\n <li class=\"invoice-download-disabled\"\n [pTooltip]=\"'Admin.Subscriptions.Invoices.NoFile' | transloco\"\n tooltipPosition=\"top\" appendTo=\"body\"\n [attr.aria-label]=\"'Admin.Subscriptions.Invoices.NoFile' | transloco\">\n <i class=\"fa fa-download edit-icon\" aria-hidden=\"true\"></i>\n </li>\n }\n </ul>\n </td>\n </tr>\n </ng-template>\n </p-table>\n @if (data.object_count === 0) {\n <pw-no-data [withImage]=\"true\"\n [message]=\"'Search.NoDataMessage' | transloco\"\n [description]=\"'Search.NoDataDescription' | transloco\" />\n } @else {\n <pw-records-summary [showing]=\"data.invoices.length\" [total]=\"data.object_count\" />\n }\n </div>\n }\n}\n",
24609
+ styles: [".subscription-invoices .invoice-number{color:#5a6473;font-variant-numeric:tabular-nums}.subscription-invoices td.col-total-excl,.subscription-invoices td.col-gst,.subscription-invoices td.col-total,.subscription-invoices td.col-date{white-space:nowrap;font-variant-numeric:tabular-nums}@media(min-width:426px){.subscription-invoices .col-total-excl,.subscription-invoices .col-gst,.subscription-invoices .col-total{width:1%;white-space:nowrap}}@media(min-width:1200px){.subscription-invoices .col-total-excl,.subscription-invoices .col-gst,.subscription-invoices .col-total{width:120px}}.subscription-invoices .invoice-download-disabled{cursor:not-allowed}.subscription-invoices .invoice-download-disabled .edit-icon,.subscription-invoices .invoice-download-disabled:hover .edit-icon{color:#a8afbc!important}\n"]
24549
24610
  }]
24550
24611
  }],
24551
24612
  ctorParameters: () => [
@@ -28036,7 +28097,6 @@ var SubscriptionsListComponent = class SubscriptionsListComponent extends AppBas
28036
28097
  this.cdr = cdr;
28037
28098
  this.commonService = commonService;
28038
28099
  this.confirmDialog = confirmDialog;
28039
- this.totalRecords = 0;
28040
28100
  this.loading = true;
28041
28101
  this.searchText = "";
28042
28102
  this.subscriptions = [];
@@ -28323,7 +28383,7 @@ var SubscriptionsListComponent = class SubscriptionsListComponent extends AppBas
28323
28383
  }],
28324
28384
  usesInheritance: true,
28325
28385
  ngImport: i0,
28326
- template: "<div class=\"row\">\n <div\n class=\"col-12 d-flex flex-wrap justify-content-between align-items-baseline\">\n <h2 class=\"card-title p-0\">Subscriptions</h2>\n <a class=\"btn btn-sm btn-outline-primary\"\n id=\"btn-create\"\n [routerLink]=\"[routers.inviteUsers]\">\n <i class=\"fa fa-plus-circle\" aria-hidden=\"true\"></i> Invite a User to a Trial\n </a>\n </div>\n</div>\n<div class=\"p-2 mt-2\">\n <div class=\"w-100 text-center\">\n @if (!isLoaded) {\n <p-progress-spinner> </p-progress-spinner>\n }\n </div>\n <div class=\"primeng-datatable-container actions-collapsed table-responsive mt-0\"\n [class.hideTable]=\"totalRecordsUnFiltered === 0\">\n <p-table #dt\n [value]=\"subscriptions\"\n [paginator]=\"totalRecords !== 0\"\n [rows]=\"PAGE_SIZE\"\n [lazy]=\"true\"\n [totalRecords]=\"totalRecords\"\n [loading]=\"loading\"\n [filterDelay]=\"1000\"\n (onLazyLoad)=\"onLazyLoad($event)\"\n [customSort]=\"true\">\n <ng-template #caption>\n @if (subscriptionInsights) {\n <div class=\"row mb-4\">\n @for (temp of objectKeys(subscriptionInsights); track temp) {\n <div class=\"col-12 col-lg-3 summary\">\n <div class=\"card\">\n <div class=\"card-body\">\n @for (item of subscriptionInsights[temp]; track item) {\n @let k = item | kpiInsight;\n <div class=\"kpi\">\n <p class=\"kpi-label\">{{ k.name }}@if (item?.info) {<span [pTooltip]=\"item?.info\" tooltipPosition=\"top\" appendTo=\"body\"><i class=\"far fa-info-circle text-muted\"></i></span>}</p>\n <div class=\"kpi-value\">{{ k.primary }}</div>\n @if (k.secondary) {<div class=\"kpi-comp\">{{ k.comp }} <b>{{ k.secondary }}</b></div>}\n </div>\n }\n </div>\n </div>\n </div>\n }\n </div>\n }\n <div class=\"search-filter\">\n <div class=\"col-12 col-sm-4\">\n <p-multiselect class=\"pw-filter-select\" inputId=\"subscriptions-list-feature-keys\"\n placeholder=\"Filter by feature keys\"\n [showToggleAll]=\"true\"\n [showHeader]=\"true\"\n [maxSelectedLabels]=\"2\"\n selectedItemsLabel=\"{0} feature keys selected\"\n [(ngModel)]=\"selectedFeatureKeys\"\n [options]=\"searchOptions\"\n (onChange)=\"onSearchOptionChange($event)\"\n appendTo=\"body\">\n </p-multiselect>\n </div>\n <div class=\"col-12 col-sm-4\">\n <p-select class=\"pw-filter-select\"\n inputId=\"subscriptions-list-status\"\n [options]=\"subscriptionStatus\"\n [placeholder]=\"'Filter by status'\"\n (onChange)=\"filterByStatus($event.value)\"\n [(ngModel)]=\"status\"\n appendTo=\"body\">\n </p-select>\n </div>\n <div class=\"text-end\">\n <label for=\"subscriptions-list-search\" class=\"visually-hidden\">Search Subscription</label>\n <p-iconfield iconPosition=\"left\">\n <p-inputicon><i class=\"fa fa-search\" aria-hidden=\"true\"></i></p-inputicon>\n <input type=\"text\"\n id=\"subscriptions-list-search\"\n name=\"subscriptions-list-search\"\n [(ngModel)]=\"searchText\"\n pInputText\n placeholder=\"Search subscriptions...\"\n (input)=\"dt.filterGlobal($event.target.value, 'contains')\"\n aria-label=\"Search subscriptions...\" />\n </p-iconfield>\n </div>\n </div>\n </ng-template>\n <ng-template #header>\n <tr>\n <th scope=\"true\"\n pSortableColumn=\"id\">\n {{ 'Admin.Subscriptions.Id' | transloco }}\n <p-sort-icon field=\"id\"></p-sort-icon>\n </th>\n <th scope=\"true\"\n pSortableColumn=\"organisation\">\n {{ 'Admin.Subscriptions.Organization' | transloco }}\n <p-sort-icon field=\"organisation\"></p-sort-icon>\n </th>\n <th scope=\"true\"\n pSortableColumn=\"contact_name\">\n {{ 'Admin.Subscriptions.ContactName' | transloco }}\n <p-sort-icon field=\"contact_name\"></p-sort-icon>\n </th>\n <th scope=\"true\"\n pSortableColumn=\"contact_email\">\n {{ 'Admin.Subscriptions.ContactEmail' | transloco }}\n <p-sort-icon field=\"contact_email\"></p-sort-icon>\n </th>\n <th scope=\"true\">{{ 'Admin.Subscriptions.Product' | transloco }}</th>\n <th scope=\"true\">{{ 'Admin.Subscriptions.Currency' | transloco }}</th>\n <th scope=\"true\">{{ 'Admin.Subscriptions.PricePerMonth' | transloco }}</th>\n <th scope=\"true\"\n pSortableColumn=\"stripe_customer_id\">\n {{ 'Admin.Subscriptions.Paid' | transloco }}\n <p-sort-icon field=\"stripe_customer_id\"></p-sort-icon>\n </th>\n <th scope=\"true\">{{ 'Admin.Subscriptions.Billing' | transloco }}</th>\n <th scope=\"true\"\n class=\"expires-at-width\">\n {{ 'Admin.Subscriptions.ExpiresAt' | transloco }}\n </th>\n <th scope=\"true\"\n pSortableColumn=\"sessions_total\">\n {{ 'Admin.Subscriptions.SessionsTotal' | transloco }}\n <p-sort-icon field=\"sessions_total\"></p-sort-icon>\n </th>\n <th scope=\"true\"\n pSortableColumn=\"sessions_last_month\">\n {{ 'Admin.Subscriptions.SessionsTotalLastMonth' | transloco }}\n <p-sort-icon field=\"sessions_last_month\"></p-sort-icon>\n </th>\n <th scope=\"true\"\n pSortableColumn=\"deleted_at\">\n {{ 'Admin.Subscriptions.Deleted' | transloco }}\n <p-sort-icon field=\"deleted_at\"></p-sort-icon>\n </th>\n <th class=\"actions-list-two\"\n scope=\"true\">{{ 'Label.Actions' | transloco }}</th>\n </tr>\n </ng-template>\n <ng-template #body\n let-item>\n <tr>\n <td data-head=\"id\">{{ item.id }}</td>\n <td data-head=\"Organization\">\n <span class=\"cursor-pointer custom-break-word\"\n [pTooltip]=\"item.organisation\"\n appendTo=\"body\"\n tooltipPosition=\"top\">{{ item.organisation | textTruncate: 20 }}</span>\n </td>\n <td data-head=\"ContactName\" class=\"custom-break-word\">\n <span [pTooltip]=\"item.contact_name\" tooltipPosition=\"top\" appendTo=\"body\">{{ item.contact_name | textTruncate: 20 }}</span>\n </td>\n <td data-head=\"ContactEmail\">\n <span [pTooltip]=\"item.contact_email\" tooltipPosition=\"top\" appendTo=\"body\">{{ item.contact_email | textTruncate: 20 }}</span>\n </td>\n <td data-head=\"Name\">\n <span class=\"cursor-pointer custom-break-word\"\n [pTooltip]=\"item.productName\"\n appendTo=\"body\"\n tooltipPosition=\"top\">{{ item.productName | textTruncate: 20 }}</span>\n </td>\n <td data-head=\"Currency\">\n <span [appDynamicBadge]=\"{ itemsArray: currency, item: item.currency }\"\n color=\"blue-grey\"\n class=\"badge\">{{ item.currency }}</span>\n </td>\n <td data-head=\"Price/M\">\n <span>{{ (item.price / 100).toFixed(2) | currency:item.currency }}\n @if (item?.discount && objectKeys(item?.discount)?.length) {\n <i\n class=\"far fa-info-circle text-muted\"\n aria-hidden=\"true\"\n [pTooltip]=\"item?.discount | json\"\n tooltipPosition=\"top\"\n appendTo=\"body\"\n ></i>\n }\n </span>\n </td>\n <td data-head=\"Paid\">\n @if (item?.unsubscribed_at) {\n <span class=\"badge bg-warning d-inline-flex align-items-center\">\n Unsub\n @if (item?.reason_to_cancel) {\n <i class=\"far fa-info-circle ms-2 text-muted\"\n [pTooltip]=\"item.reason_to_cancel\"\n tooltipPosition=\"top\"\n appendTo=\"body\"\n aria-hidden=\"true\"></i>\n }\n </span>\n }\n @if (!item?.unsubscribed_at) {\n @if ((item?.stripe_customer_id || item?.external_payment) && item?.signed_up_at) {\n <span class=\"badge bg-success\">Yes</span>\n } @else {\n <span class=\"badge bg-blue-grey\">No</span>\n }\n }\n @if (item?.pause_collection && objectKeys(item?.pause_collection)?.length) {\n <span\n class=\"ms-2\"\n [pTooltip]=\"item?.pause_collection | json\"\n tooltipPosition=\"top\"\n appendTo=\"body\">\n <i class=\"fas fa-exclamation-triangle text-warning\"></i>\n </span>\n }\n </td>\n <td data-head=\"Billing\">\n <span class=\"badge\"\n [appDynamicBadge]=\"{\n itemsArray: billingFrequency,\n item: item?.billingFrequency\n }\"\n color=\"blue-grey\">{{ item.billingFrequency }}</span>\n </td>\n <td data-head=\"Expires\">\n <span [ngClass]=\"getExpiresAtColor(item)\">{{item?.expires_at | dateFormat}}</span>\n <span>&nbsp;({{item?.created_at | sinceAgo:true}})</span>\n </td>\n <td data-head=\"S#\">{{ item?.sessions_total }}</td>\n <td data-head=\"S/m #\">\n <span [ngClass]=\"{\n 'text-danger fw-bold': item?.sessions_last_month < 3\n }\">{{ item?.sessions_last_month }}</span>\n </td>\n <td data-head=\"Deleted\">\n @if (item?.deleted_at) {\n <span\n class=\"badge bg-danger\">Yes</span>\n }\n @if (!item?.deleted_at) {\n <span\n class=\"badge bg-blue-grey\">No</span>\n }\n </td>\n <td data-head=\"Action\">\n <ul class=\"list-unstyled list-inline list-action\">\n <li pTooltip=\"Edit\"\n tooltipPosition=\"top\"\n appendTo=\"body\"\n class=\"me-2 me-sm-3\"\n [routerLink]=\"[routers.subscriptionDetails, item.id]\">\n <i class=\"fa fa-edit edit-icon\" aria-hidden=\"true\"></i>\n </li>\n @if (item.deleted) {\n <li pTooltip=\"Reactivate subscription\"\n tooltipPosition=\"top\"\n appendTo=\"body\"\n class=\"me-2 me-sm-3\"\n *rbacAllow=\"'Pages.Alpha'\"\n (keydown.enter)=\"openRecoverSubscriptionModal(item)\"\n (click)=\"openRecoverSubscriptionModal(item)\">\n <i class=\"fa fa-trash delete-icon text-success\" aria-hidden=\"true\"></i>\n </li>\n } @else {\n <li pTooltip=\"Delete\"\n tooltipPosition=\"top\"\n appendTo=\"body\"\n class=\"me-2 me-sm-3\"\n *rbacAllow=\"'Pages.Admin.Subscription.Delete'\"\n (keydown.enter)=\"onDelete(item)\"\n (click)=\"onDelete(item)\">\n <i class=\"fa fa-trash delete-icon\" aria-hidden=\"true\"></i>\n </li>\n }\n </ul>\n </td>\n </tr>\n </ng-template>\n </p-table>\n @if (totalRecords === 0 && totalRecordsUnFiltered !== 0) {\n <div>\n <pw-no-data [withImage]=\"true\" [message]=\"'Search.NoDataMessage' | transloco\" [description]=\"'Search.NoDataDescription' | transloco\" >\n </pw-no-data>\n </div>\n }\n @if (totalRecords !== 0) {\n <pw-records-summary [showing]=\"dt?.value?.length ?? 0\" [total]=\"totalRecords\" />\n }\n </div>\n</div>\n@if (totalRecordsUnFiltered === 0 && isLoaded) {\n <pw-no-data [withImage]=\"true\" [message]=\"'Admin.Subscriptions.NoSubscriptionMessage' | transloco\">\n </pw-no-data>\n}\n<pw-password-validation\n #recoverSubscriptionPasswordModal\n (successEvent)=\"onRecoverConfirmed()\">\n</pw-password-validation>\n\n",
28386
+ template: "<div class=\"row\">\n <div\n class=\"col-12 d-flex flex-wrap justify-content-between align-items-baseline\">\n <h2 class=\"card-title p-0\">Subscriptions</h2>\n <a class=\"btn btn-sm btn-outline-primary\"\n id=\"btn-create\"\n [routerLink]=\"[routers.inviteUsers]\">\n <i class=\"fa fa-plus-circle\" aria-hidden=\"true\"></i> Invite a User to a Trial\n </a>\n </div>\n</div>\n<div class=\"p-2 mt-2\">\n <div class=\"w-100 text-center\">\n @if (!isLoaded) {\n <p-progress-spinner> </p-progress-spinner>\n }\n </div>\n <div class=\"primeng-datatable-container actions-collapsed table-responsive mt-0\"\n [class.hideTable]=\"totalRecordsUnFiltered === 0\">\n <p-table #dt\n [value]=\"subscriptions\"\n [paginator]=\"totalRecords !== 0\"\n [rows]=\"PAGE_SIZE\"\n [lazy]=\"true\"\n [totalRecords]=\"totalRecords\"\n [loading]=\"loading\"\n [filterDelay]=\"1000\"\n (onLazyLoad)=\"onLazyLoad($event)\"\n stateKey=\"pw-table.admin-subscriptions-list\"\n stateStorage=\"session\"\n [resizableColumns]=\"true\"\n columnResizeMode=\"expand\"\n [customSort]=\"true\">\n <ng-template #caption>\n @if (subscriptionInsights) {\n <div class=\"row mb-4\">\n @for (temp of objectKeys(subscriptionInsights); track temp) {\n <div class=\"col-12 col-lg-3 summary\">\n <div class=\"card\">\n <div class=\"card-body\">\n @for (item of subscriptionInsights[temp]; track item) {\n @let k = item | kpiInsight;\n <div class=\"kpi\">\n <p class=\"kpi-label\">{{ k.name }}@if (item?.info) {<span [pTooltip]=\"item?.info\" tooltipPosition=\"top\" appendTo=\"body\"><i class=\"far fa-info-circle text-muted\"></i></span>}</p>\n <div class=\"kpi-value\">{{ k.primary }}</div>\n @if (k.secondary) {<div class=\"kpi-comp\">{{ k.comp }} <b>{{ k.secondary }}</b></div>}\n </div>\n }\n </div>\n </div>\n </div>\n }\n </div>\n }\n <div class=\"search-filter\">\n <div class=\"col-12 col-sm-4\">\n <p-multiselect class=\"pw-filter-select\" inputId=\"subscriptions-list-feature-keys\"\n placeholder=\"Filter by feature keys\"\n [showToggleAll]=\"true\"\n [showHeader]=\"true\"\n [maxSelectedLabels]=\"2\"\n selectedItemsLabel=\"{0} feature keys selected\"\n [(ngModel)]=\"selectedFeatureKeys\"\n [options]=\"searchOptions\"\n (onChange)=\"onSearchOptionChange($event)\"\n appendTo=\"body\">\n </p-multiselect>\n </div>\n <div class=\"col-12 col-sm-4\">\n <p-select class=\"pw-filter-select\"\n inputId=\"subscriptions-list-status\"\n [options]=\"subscriptionStatus\"\n [placeholder]=\"'Filter by status'\"\n (onChange)=\"filterByStatus($event.value)\"\n [(ngModel)]=\"status\"\n appendTo=\"body\">\n </p-select>\n </div>\n <div class=\"text-end\">\n <label for=\"subscriptions-list-search\" class=\"visually-hidden\">Search Subscription</label>\n <p-iconfield iconPosition=\"left\">\n <p-inputicon><i class=\"fa fa-search\" aria-hidden=\"true\"></i></p-inputicon>\n <input type=\"text\"\n id=\"subscriptions-list-search\"\n name=\"subscriptions-list-search\"\n [(ngModel)]=\"searchText\"\n pInputText\n placeholder=\"Search subscriptions...\"\n (input)=\"dt.filterGlobal($event.target.value, 'contains')\"\n aria-label=\"Search subscriptions...\" />\n </p-iconfield>\n </div>\n </div>\n </ng-template>\n <ng-template #header>\n <tr>\n <th pResizableColumn scope=\"true\"\n pSortableColumn=\"id\">\n {{ 'Admin.Subscriptions.Id' | transloco }}\n <p-sort-icon field=\"id\"></p-sort-icon>\n </th>\n <th pResizableColumn scope=\"true\"\n pSortableColumn=\"organisation\">\n {{ 'Admin.Subscriptions.Organization' | transloco }}\n <p-sort-icon field=\"organisation\"></p-sort-icon>\n </th>\n <th pResizableColumn scope=\"true\"\n pSortableColumn=\"contact_name\">\n {{ 'Admin.Subscriptions.ContactName' | transloco }}\n <p-sort-icon field=\"contact_name\"></p-sort-icon>\n </th>\n <th pResizableColumn scope=\"true\"\n pSortableColumn=\"contact_email\">\n {{ 'Admin.Subscriptions.ContactEmail' | transloco }}\n <p-sort-icon field=\"contact_email\"></p-sort-icon>\n </th>\n <th pResizableColumn scope=\"true\">{{ 'Admin.Subscriptions.Product' | transloco }}</th>\n <th pResizableColumn scope=\"true\">{{ 'Admin.Subscriptions.Currency' | transloco }}</th>\n <th pResizableColumn scope=\"true\">{{ 'Admin.Subscriptions.PricePerMonth' | transloco }}</th>\n <th pResizableColumn scope=\"true\"\n pSortableColumn=\"stripe_customer_id\">\n {{ 'Admin.Subscriptions.Paid' | transloco }}\n <p-sort-icon field=\"stripe_customer_id\"></p-sort-icon>\n </th>\n <th pResizableColumn scope=\"true\">{{ 'Admin.Subscriptions.Billing' | transloco }}</th>\n <th pResizableColumn scope=\"true\"\n class=\"expires-at-width\">\n {{ 'Admin.Subscriptions.ExpiresAt' | transloco }}\n </th>\n <th pResizableColumn scope=\"true\"\n pSortableColumn=\"sessions_total\">\n {{ 'Admin.Subscriptions.SessionsTotal' | transloco }}\n <p-sort-icon field=\"sessions_total\"></p-sort-icon>\n </th>\n <th pResizableColumn scope=\"true\"\n pSortableColumn=\"sessions_last_month\">\n {{ 'Admin.Subscriptions.SessionsTotalLastMonth' | transloco }}\n <p-sort-icon field=\"sessions_last_month\"></p-sort-icon>\n </th>\n <th pResizableColumn scope=\"true\"\n pSortableColumn=\"deleted_at\">\n {{ 'Admin.Subscriptions.Deleted' | transloco }}\n <p-sort-icon field=\"deleted_at\"></p-sort-icon>\n </th>\n <th class=\"actions-list-two\"\n scope=\"true\">{{ 'Label.Actions' | transloco }}</th>\n </tr>\n </ng-template>\n <ng-template #body\n let-item>\n <tr>\n <td data-head=\"id\">{{ item.id }}</td>\n <td data-head=\"Organization\">\n <span class=\"cursor-pointer custom-break-word\"\n [pTooltip]=\"item.organisation\"\n appendTo=\"body\"\n tooltipPosition=\"top\">{{ item.organisation | textTruncate: 20 }}</span>\n </td>\n <td data-head=\"ContactName\" class=\"custom-break-word\">\n <span [pTooltip]=\"item.contact_name\" tooltipPosition=\"top\" appendTo=\"body\">{{ item.contact_name | textTruncate: 20 }}</span>\n </td>\n <td data-head=\"ContactEmail\">\n <span [pTooltip]=\"item.contact_email\" tooltipPosition=\"top\" appendTo=\"body\">{{ item.contact_email | textTruncate: 20 }}</span>\n </td>\n <td data-head=\"Name\">\n <span class=\"cursor-pointer custom-break-word\"\n [pTooltip]=\"item.productName\"\n appendTo=\"body\"\n tooltipPosition=\"top\">{{ item.productName | textTruncate: 20 }}</span>\n </td>\n <td data-head=\"Currency\">\n <span [appDynamicBadge]=\"{ itemsArray: currency, item: item.currency }\"\n color=\"blue-grey\"\n class=\"badge\">{{ item.currency }}</span>\n </td>\n <td data-head=\"Price/M\">\n <span>{{ (item.price / 100).toFixed(2) | currency:item.currency }}\n @if (item?.discount && objectKeys(item?.discount)?.length) {\n <i\n class=\"far fa-info-circle text-muted\"\n aria-hidden=\"true\"\n [pTooltip]=\"item?.discount | json\"\n tooltipPosition=\"top\"\n appendTo=\"body\"\n ></i>\n }\n </span>\n </td>\n <td data-head=\"Paid\">\n @if (item?.unsubscribed_at) {\n <span class=\"badge bg-warning d-inline-flex align-items-center\">\n Unsub\n @if (item?.reason_to_cancel) {\n <i class=\"far fa-info-circle ms-2 text-muted\"\n [pTooltip]=\"item.reason_to_cancel\"\n tooltipPosition=\"top\"\n appendTo=\"body\"\n aria-hidden=\"true\"></i>\n }\n </span>\n }\n @if (!item?.unsubscribed_at) {\n @if ((item?.stripe_customer_id || item?.external_payment) && item?.signed_up_at) {\n <span class=\"badge bg-success\">Yes</span>\n } @else {\n <span class=\"badge bg-blue-grey\">No</span>\n }\n }\n @if (item?.pause_collection && objectKeys(item?.pause_collection)?.length) {\n <span\n class=\"ms-2\"\n [pTooltip]=\"item?.pause_collection | json\"\n tooltipPosition=\"top\"\n appendTo=\"body\">\n <i class=\"fas fa-exclamation-triangle text-warning\"></i>\n </span>\n }\n </td>\n <td data-head=\"Billing\">\n <span class=\"badge\"\n [appDynamicBadge]=\"{\n itemsArray: billingFrequency,\n item: item?.billingFrequency\n }\"\n color=\"blue-grey\">{{ item.billingFrequency }}</span>\n </td>\n <td data-head=\"Expires\">\n <span [ngClass]=\"getExpiresAtColor(item)\">{{item?.expires_at | dateFormat}}</span>\n <span>&nbsp;({{item?.created_at | sinceAgo:true}})</span>\n </td>\n <td data-head=\"S#\">{{ item?.sessions_total }}</td>\n <td data-head=\"S/m #\">\n <span [ngClass]=\"{\n 'text-danger fw-bold': item?.sessions_last_month < 3\n }\">{{ item?.sessions_last_month }}</span>\n </td>\n <td data-head=\"Deleted\">\n @if (item?.deleted_at) {\n <span\n class=\"badge bg-danger\">Yes</span>\n }\n @if (!item?.deleted_at) {\n <span\n class=\"badge bg-blue-grey\">No</span>\n }\n </td>\n <td data-head=\"Action\">\n <ul class=\"list-unstyled list-inline list-action\">\n <li pTooltip=\"Edit\"\n tooltipPosition=\"top\"\n appendTo=\"body\"\n class=\"me-2 me-sm-3\"\n [routerLink]=\"[routers.subscriptionDetails, item.id]\">\n <i class=\"fa fa-edit edit-icon\" aria-hidden=\"true\"></i>\n </li>\n @if (item.deleted) {\n <li pTooltip=\"Reactivate subscription\"\n tooltipPosition=\"top\"\n appendTo=\"body\"\n class=\"me-2 me-sm-3\"\n *rbacAllow=\"'Pages.Alpha'\"\n (keydown.enter)=\"openRecoverSubscriptionModal(item)\"\n (click)=\"openRecoverSubscriptionModal(item)\">\n <i class=\"fa fa-trash delete-icon text-success\" aria-hidden=\"true\"></i>\n </li>\n } @else {\n <li pTooltip=\"Delete\"\n tooltipPosition=\"top\"\n appendTo=\"body\"\n class=\"me-2 me-sm-3\"\n *rbacAllow=\"'Pages.Admin.Subscription.Delete'\"\n (keydown.enter)=\"onDelete(item)\"\n (click)=\"onDelete(item)\">\n <i class=\"fa fa-trash delete-icon\" aria-hidden=\"true\"></i>\n </li>\n }\n </ul>\n </td>\n </tr>\n </ng-template>\n </p-table>\n @if (totalRecords === 0 && totalRecordsUnFiltered !== 0) {\n <div>\n <pw-no-data [withImage]=\"true\" [message]=\"'Search.NoDataMessage' | transloco\" [description]=\"'Search.NoDataDescription' | transloco\" >\n </pw-no-data>\n </div>\n }\n @if (totalRecords !== 0) {\n <pw-records-summary [showing]=\"dt?.value?.length ?? 0\" [total]=\"totalRecords\" />\n }\n </div>\n</div>\n@if (totalRecordsUnFiltered === 0 && isLoaded) {\n <pw-no-data [withImage]=\"true\" [message]=\"'Admin.Subscriptions.NoSubscriptionMessage' | transloco\">\n </pw-no-data>\n}\n<pw-password-validation\n #recoverSubscriptionPasswordModal\n (successEvent)=\"onRecoverConfirmed()\">\n</pw-password-validation>\n\n",
28327
28387
  styles: ["@charset \"UTF-8\";:root{--first: rgb(23 105 225);--second: rgb(54 194 131);--third: rgb(255 171 0);--text: rgb(34 34 34);--tabs_bg: rgb(23 105 225);--tabs_sub_bg: color-mix(in srgb, var(--first, rgb(23 105 225)) 85%, #000000);--tabs_text: rgb(255 255 255);--titles: rgb(34 34 34);--sidebar_bg: rgb(0, 48, 63);--sidebar_text: rgb(255 255 255);--dashboard_bg: rgb(255 255 255);--public-btn-radius: 24px}.table-responsive td{padding:6px 10px!important;font-size:12px!important;line-height:1.35;vertical-align:top;overflow-wrap:break-word}.table-responsive th{font-size:12px!important;vertical-align:bottom}.table-responsive td[data-head=Organization],.table-responsive td[data-head=Name],.table-responsive td[data-head=ContactName],.table-responsive td[data-head=ContactEmail],.table-responsive td[data-head=id],.table-responsive td[data-head=\"Price/M\"],.table-responsive td[data-head=\"S#\"],.table-responsive td[data-head=\"S/m #\"]{white-space:nowrap}.table-responsive td[data-head=id]{font-variant-numeric:tabular-nums;color:#7c8696}.table-responsive td[data-head=\"Price/M\"],.table-responsive td[data-head=\"S#\"],.table-responsive td[data-head=\"S/m #\"]{font-variant-numeric:tabular-nums;text-align:right}.table-responsive th:nth-child(7),.table-responsive th:nth-child(11),.table-responsive th:nth-child(12){text-align:right}.table-responsive .badge{font-size:11px;font-weight:600;padding:2px 8px;border-radius:4px;letter-spacing:.01em}.table-responsive .badge[class*=bg-success]{background-color:#e6f4ec!important;color:#0f6b3a!important}.table-responsive .badge[class*=bg-danger]{background-color:#fbeae8!important;color:#c0392b!important}.table-responsive .badge[class*=bg-warning]{background-color:#fbf1e3!important;color:#8a5a00!important}.table-responsive .badge.bg-blue-grey{background-color:#eef0f3!important;color:#5a6473!important}.table-responsive .badge.bg-blue-grey-1{background-color:#e9e6ef!important;color:#473172!important}.table-responsive .badge.bg-blue-grey-2{background-color:#efe6ef!important;color:#723172!important}.table-responsive .badge.bg-blue-grey-3{background-color:#efe6e9!important;color:#723147!important}.table-responsive .badge.bg-blue-grey-4{background-color:#efe9e6!important;color:#724731!important}.table-responsive .badge.bg-blue-grey-5{background-color:#efefe6!important;color:#727231!important}.table-responsive .badge.bg-blue-grey-6{background-color:#e9efe6!important;color:#477231!important}.table-responsive .badge.bg-blue-grey-7{background-color:#e6efe9!important;color:#317247!important}.table-responsive .badge.bg-blue-grey-8{background-color:#e6efef!important;color:#317272!important}.table-responsive .badge.bg-blue-grey-9{background-color:#e6e9ef!important;color:#314772!important}.table-responsive .badge.bg-blue-grey-10{background-color:#e9e6ef!important;color:#473172!important}.table-responsive .badge.bg-blue-grey-11{background-color:#efe6ef!important;color:#723172!important}.table-responsive .badge.bg-blue-grey-12{background-color:#efe6e9!important;color:#723147!important}.table-responsive .badge.bg-blue-grey-13{background-color:#efe9e6!important;color:#724731!important}.table-responsive .badge.bg-blue-grey-14{background-color:#efefe6!important;color:#727231!important}.table-responsive .badge.bg-blue-grey-15{background-color:#e9efe6!important;color:#477231!important}.table-responsive .badge.bg-blue-grey-16{background-color:#e6efe9!important;color:#317247!important}.table-responsive .badge.bg-blue-grey-17{background-color:#e6efef!important;color:#317272!important}.table-responsive .badge.bg-blue-grey-18{background-color:#e6e9ef!important;color:#314772!important}.table-responsive .badge.bg-blue-grey-19{background-color:#e9e6ef!important;color:#473172!important}.table-responsive .badge.bg-blue-grey-20{background-color:#efe6ef!important;color:#723172!important}.table-responsive .badge.bg-blue-grey-21{background-color:#efe6e9!important;color:#723147!important}.table-responsive .badge.bg-blue-grey-22{background-color:#efe9e6!important;color:#724731!important}.table-responsive .badge.bg-blue-grey-23{background-color:#efefe6!important;color:#727231!important}.table-responsive .badge.bg-blue-grey-24{background-color:#e9efe6!important;color:#477231!important}.table-responsive .badge[class*=bg-success]:before,.table-responsive .badge[class*=bg-danger]:before,.table-responsive .badge[class*=bg-warning]:before{content:\"\";display:inline-block;width:6px;height:6px;margin-right:6px;border-radius:50%;background-color:currentColor;vertical-align:middle}.table-responsive tbody tr:hover{background-color:#f5f7fa}.table-responsive td[data-head=Organization] span,.table-responsive td[data-head=Name] span{font-weight:600;color:#1a1d21}.table-responsive td[data-head=Expires] span~span{font-weight:600}.table-responsive .list-action .edit-icon{color:#5a6473}.table-responsive .list-action .delete-icon{color:#c0392b!important}.table-responsive .list-action .delete-icon.text-success{color:#0f6b3a!important}@media(max-width:1199.98px){.table-responsive td,.table-responsive th{white-space:nowrap;word-break:normal}}.expires-at-width{width:8%}.custom-break-word{overflow-wrap:break-word!important}.summary{display:flex}.summary .card{width:100%;margin-top:0;margin-bottom:0;padding-bottom:0!important;border:1px solid #e2e5ea;border-radius:8px;background-color:#fff;transition:background-color .12s ease,border-color .12s ease}.summary .card:hover{background-color:#fafbfc;border-color:#cfd4dc}.summary .card-body{display:flex;flex-direction:column;padding:2px 0}.summary .kpi{display:grid;grid-template-columns:auto minmax(0,1fr);column-gap:12px;align-items:baseline;padding:10px 16px}.summary .kpi+.kpi{border-top:1px solid #eef0f3}.summary .kpi-label{grid-column:1/-1;margin:0 0 4px;font-size:10px;font-weight:600;line-height:1.3;letter-spacing:.05em;text-transform:uppercase;color:#5a6473}.summary .kpi-label .fa-info-circle{margin-left:4px;font-size:15px;color:#a8afbc}.summary .kpi-value{grid-column:1;font-size:18px;font-weight:700;line-height:1.1;color:#1a1d21;font-variant-numeric:tabular-nums}.summary .kpi-comp{grid-column:2;text-align:right;font-size:12px;color:#7c8696;font-variant-numeric:tabular-nums;white-space:normal}.summary .kpi-comp:before{content:\"\\b7\";margin-right:4px;color:#a8afbc}.summary .kpi-comp b{font-weight:600;color:#5a6473}@media(min-width:320px)and (max-width:720px){.primeng-datatable-container .search-filter{display:flex;flex-direction:column;gap:.5rem;justify-content:space-between}}\n"],
28328
28388
  dependencies: [
28329
28389
  {
@@ -28445,6 +28505,12 @@ var SubscriptionsListComponent = class SubscriptionsListComponent extends AppBas
28445
28505
  selector: "[pSortableColumn]",
28446
28506
  inputs: ["pSortableColumn", "pSortableColumnDisabled"]
28447
28507
  },
28508
+ {
28509
+ kind: "directive",
28510
+ type: i2$3.ResizableColumn,
28511
+ selector: "[pResizableColumn]",
28512
+ inputs: ["pResizableColumnDisabled"]
28513
+ },
28448
28514
  {
28449
28515
  kind: "component",
28450
28516
  type: i2$3.SortIcon,
@@ -28811,7 +28877,7 @@ i0.ɵɵngDeclareClassMetadata({
28811
28877
  args: [{
28812
28878
  selector: "pw-subscriptions-list",
28813
28879
  standalone: false,
28814
- template: "<div class=\"row\">\n <div\n class=\"col-12 d-flex flex-wrap justify-content-between align-items-baseline\">\n <h2 class=\"card-title p-0\">Subscriptions</h2>\n <a class=\"btn btn-sm btn-outline-primary\"\n id=\"btn-create\"\n [routerLink]=\"[routers.inviteUsers]\">\n <i class=\"fa fa-plus-circle\" aria-hidden=\"true\"></i> Invite a User to a Trial\n </a>\n </div>\n</div>\n<div class=\"p-2 mt-2\">\n <div class=\"w-100 text-center\">\n @if (!isLoaded) {\n <p-progress-spinner> </p-progress-spinner>\n }\n </div>\n <div class=\"primeng-datatable-container actions-collapsed table-responsive mt-0\"\n [class.hideTable]=\"totalRecordsUnFiltered === 0\">\n <p-table #dt\n [value]=\"subscriptions\"\n [paginator]=\"totalRecords !== 0\"\n [rows]=\"PAGE_SIZE\"\n [lazy]=\"true\"\n [totalRecords]=\"totalRecords\"\n [loading]=\"loading\"\n [filterDelay]=\"1000\"\n (onLazyLoad)=\"onLazyLoad($event)\"\n [customSort]=\"true\">\n <ng-template #caption>\n @if (subscriptionInsights) {\n <div class=\"row mb-4\">\n @for (temp of objectKeys(subscriptionInsights); track temp) {\n <div class=\"col-12 col-lg-3 summary\">\n <div class=\"card\">\n <div class=\"card-body\">\n @for (item of subscriptionInsights[temp]; track item) {\n @let k = item | kpiInsight;\n <div class=\"kpi\">\n <p class=\"kpi-label\">{{ k.name }}@if (item?.info) {<span [pTooltip]=\"item?.info\" tooltipPosition=\"top\" appendTo=\"body\"><i class=\"far fa-info-circle text-muted\"></i></span>}</p>\n <div class=\"kpi-value\">{{ k.primary }}</div>\n @if (k.secondary) {<div class=\"kpi-comp\">{{ k.comp }} <b>{{ k.secondary }}</b></div>}\n </div>\n }\n </div>\n </div>\n </div>\n }\n </div>\n }\n <div class=\"search-filter\">\n <div class=\"col-12 col-sm-4\">\n <p-multiselect class=\"pw-filter-select\" inputId=\"subscriptions-list-feature-keys\"\n placeholder=\"Filter by feature keys\"\n [showToggleAll]=\"true\"\n [showHeader]=\"true\"\n [maxSelectedLabels]=\"2\"\n selectedItemsLabel=\"{0} feature keys selected\"\n [(ngModel)]=\"selectedFeatureKeys\"\n [options]=\"searchOptions\"\n (onChange)=\"onSearchOptionChange($event)\"\n appendTo=\"body\">\n </p-multiselect>\n </div>\n <div class=\"col-12 col-sm-4\">\n <p-select class=\"pw-filter-select\"\n inputId=\"subscriptions-list-status\"\n [options]=\"subscriptionStatus\"\n [placeholder]=\"'Filter by status'\"\n (onChange)=\"filterByStatus($event.value)\"\n [(ngModel)]=\"status\"\n appendTo=\"body\">\n </p-select>\n </div>\n <div class=\"text-end\">\n <label for=\"subscriptions-list-search\" class=\"visually-hidden\">Search Subscription</label>\n <p-iconfield iconPosition=\"left\">\n <p-inputicon><i class=\"fa fa-search\" aria-hidden=\"true\"></i></p-inputicon>\n <input type=\"text\"\n id=\"subscriptions-list-search\"\n name=\"subscriptions-list-search\"\n [(ngModel)]=\"searchText\"\n pInputText\n placeholder=\"Search subscriptions...\"\n (input)=\"dt.filterGlobal($event.target.value, 'contains')\"\n aria-label=\"Search subscriptions...\" />\n </p-iconfield>\n </div>\n </div>\n </ng-template>\n <ng-template #header>\n <tr>\n <th scope=\"true\"\n pSortableColumn=\"id\">\n {{ 'Admin.Subscriptions.Id' | transloco }}\n <p-sort-icon field=\"id\"></p-sort-icon>\n </th>\n <th scope=\"true\"\n pSortableColumn=\"organisation\">\n {{ 'Admin.Subscriptions.Organization' | transloco }}\n <p-sort-icon field=\"organisation\"></p-sort-icon>\n </th>\n <th scope=\"true\"\n pSortableColumn=\"contact_name\">\n {{ 'Admin.Subscriptions.ContactName' | transloco }}\n <p-sort-icon field=\"contact_name\"></p-sort-icon>\n </th>\n <th scope=\"true\"\n pSortableColumn=\"contact_email\">\n {{ 'Admin.Subscriptions.ContactEmail' | transloco }}\n <p-sort-icon field=\"contact_email\"></p-sort-icon>\n </th>\n <th scope=\"true\">{{ 'Admin.Subscriptions.Product' | transloco }}</th>\n <th scope=\"true\">{{ 'Admin.Subscriptions.Currency' | transloco }}</th>\n <th scope=\"true\">{{ 'Admin.Subscriptions.PricePerMonth' | transloco }}</th>\n <th scope=\"true\"\n pSortableColumn=\"stripe_customer_id\">\n {{ 'Admin.Subscriptions.Paid' | transloco }}\n <p-sort-icon field=\"stripe_customer_id\"></p-sort-icon>\n </th>\n <th scope=\"true\">{{ 'Admin.Subscriptions.Billing' | transloco }}</th>\n <th scope=\"true\"\n class=\"expires-at-width\">\n {{ 'Admin.Subscriptions.ExpiresAt' | transloco }}\n </th>\n <th scope=\"true\"\n pSortableColumn=\"sessions_total\">\n {{ 'Admin.Subscriptions.SessionsTotal' | transloco }}\n <p-sort-icon field=\"sessions_total\"></p-sort-icon>\n </th>\n <th scope=\"true\"\n pSortableColumn=\"sessions_last_month\">\n {{ 'Admin.Subscriptions.SessionsTotalLastMonth' | transloco }}\n <p-sort-icon field=\"sessions_last_month\"></p-sort-icon>\n </th>\n <th scope=\"true\"\n pSortableColumn=\"deleted_at\">\n {{ 'Admin.Subscriptions.Deleted' | transloco }}\n <p-sort-icon field=\"deleted_at\"></p-sort-icon>\n </th>\n <th class=\"actions-list-two\"\n scope=\"true\">{{ 'Label.Actions' | transloco }}</th>\n </tr>\n </ng-template>\n <ng-template #body\n let-item>\n <tr>\n <td data-head=\"id\">{{ item.id }}</td>\n <td data-head=\"Organization\">\n <span class=\"cursor-pointer custom-break-word\"\n [pTooltip]=\"item.organisation\"\n appendTo=\"body\"\n tooltipPosition=\"top\">{{ item.organisation | textTruncate: 20 }}</span>\n </td>\n <td data-head=\"ContactName\" class=\"custom-break-word\">\n <span [pTooltip]=\"item.contact_name\" tooltipPosition=\"top\" appendTo=\"body\">{{ item.contact_name | textTruncate: 20 }}</span>\n </td>\n <td data-head=\"ContactEmail\">\n <span [pTooltip]=\"item.contact_email\" tooltipPosition=\"top\" appendTo=\"body\">{{ item.contact_email | textTruncate: 20 }}</span>\n </td>\n <td data-head=\"Name\">\n <span class=\"cursor-pointer custom-break-word\"\n [pTooltip]=\"item.productName\"\n appendTo=\"body\"\n tooltipPosition=\"top\">{{ item.productName | textTruncate: 20 }}</span>\n </td>\n <td data-head=\"Currency\">\n <span [appDynamicBadge]=\"{ itemsArray: currency, item: item.currency }\"\n color=\"blue-grey\"\n class=\"badge\">{{ item.currency }}</span>\n </td>\n <td data-head=\"Price/M\">\n <span>{{ (item.price / 100).toFixed(2) | currency:item.currency }}\n @if (item?.discount && objectKeys(item?.discount)?.length) {\n <i\n class=\"far fa-info-circle text-muted\"\n aria-hidden=\"true\"\n [pTooltip]=\"item?.discount | json\"\n tooltipPosition=\"top\"\n appendTo=\"body\"\n ></i>\n }\n </span>\n </td>\n <td data-head=\"Paid\">\n @if (item?.unsubscribed_at) {\n <span class=\"badge bg-warning d-inline-flex align-items-center\">\n Unsub\n @if (item?.reason_to_cancel) {\n <i class=\"far fa-info-circle ms-2 text-muted\"\n [pTooltip]=\"item.reason_to_cancel\"\n tooltipPosition=\"top\"\n appendTo=\"body\"\n aria-hidden=\"true\"></i>\n }\n </span>\n }\n @if (!item?.unsubscribed_at) {\n @if ((item?.stripe_customer_id || item?.external_payment) && item?.signed_up_at) {\n <span class=\"badge bg-success\">Yes</span>\n } @else {\n <span class=\"badge bg-blue-grey\">No</span>\n }\n }\n @if (item?.pause_collection && objectKeys(item?.pause_collection)?.length) {\n <span\n class=\"ms-2\"\n [pTooltip]=\"item?.pause_collection | json\"\n tooltipPosition=\"top\"\n appendTo=\"body\">\n <i class=\"fas fa-exclamation-triangle text-warning\"></i>\n </span>\n }\n </td>\n <td data-head=\"Billing\">\n <span class=\"badge\"\n [appDynamicBadge]=\"{\n itemsArray: billingFrequency,\n item: item?.billingFrequency\n }\"\n color=\"blue-grey\">{{ item.billingFrequency }}</span>\n </td>\n <td data-head=\"Expires\">\n <span [ngClass]=\"getExpiresAtColor(item)\">{{item?.expires_at | dateFormat}}</span>\n <span>&nbsp;({{item?.created_at | sinceAgo:true}})</span>\n </td>\n <td data-head=\"S#\">{{ item?.sessions_total }}</td>\n <td data-head=\"S/m #\">\n <span [ngClass]=\"{\n 'text-danger fw-bold': item?.sessions_last_month < 3\n }\">{{ item?.sessions_last_month }}</span>\n </td>\n <td data-head=\"Deleted\">\n @if (item?.deleted_at) {\n <span\n class=\"badge bg-danger\">Yes</span>\n }\n @if (!item?.deleted_at) {\n <span\n class=\"badge bg-blue-grey\">No</span>\n }\n </td>\n <td data-head=\"Action\">\n <ul class=\"list-unstyled list-inline list-action\">\n <li pTooltip=\"Edit\"\n tooltipPosition=\"top\"\n appendTo=\"body\"\n class=\"me-2 me-sm-3\"\n [routerLink]=\"[routers.subscriptionDetails, item.id]\">\n <i class=\"fa fa-edit edit-icon\" aria-hidden=\"true\"></i>\n </li>\n @if (item.deleted) {\n <li pTooltip=\"Reactivate subscription\"\n tooltipPosition=\"top\"\n appendTo=\"body\"\n class=\"me-2 me-sm-3\"\n *rbacAllow=\"'Pages.Alpha'\"\n (keydown.enter)=\"openRecoverSubscriptionModal(item)\"\n (click)=\"openRecoverSubscriptionModal(item)\">\n <i class=\"fa fa-trash delete-icon text-success\" aria-hidden=\"true\"></i>\n </li>\n } @else {\n <li pTooltip=\"Delete\"\n tooltipPosition=\"top\"\n appendTo=\"body\"\n class=\"me-2 me-sm-3\"\n *rbacAllow=\"'Pages.Admin.Subscription.Delete'\"\n (keydown.enter)=\"onDelete(item)\"\n (click)=\"onDelete(item)\">\n <i class=\"fa fa-trash delete-icon\" aria-hidden=\"true\"></i>\n </li>\n }\n </ul>\n </td>\n </tr>\n </ng-template>\n </p-table>\n @if (totalRecords === 0 && totalRecordsUnFiltered !== 0) {\n <div>\n <pw-no-data [withImage]=\"true\" [message]=\"'Search.NoDataMessage' | transloco\" [description]=\"'Search.NoDataDescription' | transloco\" >\n </pw-no-data>\n </div>\n }\n @if (totalRecords !== 0) {\n <pw-records-summary [showing]=\"dt?.value?.length ?? 0\" [total]=\"totalRecords\" />\n }\n </div>\n</div>\n@if (totalRecordsUnFiltered === 0 && isLoaded) {\n <pw-no-data [withImage]=\"true\" [message]=\"'Admin.Subscriptions.NoSubscriptionMessage' | transloco\">\n </pw-no-data>\n}\n<pw-password-validation\n #recoverSubscriptionPasswordModal\n (successEvent)=\"onRecoverConfirmed()\">\n</pw-password-validation>\n\n",
28880
+ template: "<div class=\"row\">\n <div\n class=\"col-12 d-flex flex-wrap justify-content-between align-items-baseline\">\n <h2 class=\"card-title p-0\">Subscriptions</h2>\n <a class=\"btn btn-sm btn-outline-primary\"\n id=\"btn-create\"\n [routerLink]=\"[routers.inviteUsers]\">\n <i class=\"fa fa-plus-circle\" aria-hidden=\"true\"></i> Invite a User to a Trial\n </a>\n </div>\n</div>\n<div class=\"p-2 mt-2\">\n <div class=\"w-100 text-center\">\n @if (!isLoaded) {\n <p-progress-spinner> </p-progress-spinner>\n }\n </div>\n <div class=\"primeng-datatable-container actions-collapsed table-responsive mt-0\"\n [class.hideTable]=\"totalRecordsUnFiltered === 0\">\n <p-table #dt\n [value]=\"subscriptions\"\n [paginator]=\"totalRecords !== 0\"\n [rows]=\"PAGE_SIZE\"\n [lazy]=\"true\"\n [totalRecords]=\"totalRecords\"\n [loading]=\"loading\"\n [filterDelay]=\"1000\"\n (onLazyLoad)=\"onLazyLoad($event)\"\n stateKey=\"pw-table.admin-subscriptions-list\"\n stateStorage=\"session\"\n [resizableColumns]=\"true\"\n columnResizeMode=\"expand\"\n [customSort]=\"true\">\n <ng-template #caption>\n @if (subscriptionInsights) {\n <div class=\"row mb-4\">\n @for (temp of objectKeys(subscriptionInsights); track temp) {\n <div class=\"col-12 col-lg-3 summary\">\n <div class=\"card\">\n <div class=\"card-body\">\n @for (item of subscriptionInsights[temp]; track item) {\n @let k = item | kpiInsight;\n <div class=\"kpi\">\n <p class=\"kpi-label\">{{ k.name }}@if (item?.info) {<span [pTooltip]=\"item?.info\" tooltipPosition=\"top\" appendTo=\"body\"><i class=\"far fa-info-circle text-muted\"></i></span>}</p>\n <div class=\"kpi-value\">{{ k.primary }}</div>\n @if (k.secondary) {<div class=\"kpi-comp\">{{ k.comp }} <b>{{ k.secondary }}</b></div>}\n </div>\n }\n </div>\n </div>\n </div>\n }\n </div>\n }\n <div class=\"search-filter\">\n <div class=\"col-12 col-sm-4\">\n <p-multiselect class=\"pw-filter-select\" inputId=\"subscriptions-list-feature-keys\"\n placeholder=\"Filter by feature keys\"\n [showToggleAll]=\"true\"\n [showHeader]=\"true\"\n [maxSelectedLabels]=\"2\"\n selectedItemsLabel=\"{0} feature keys selected\"\n [(ngModel)]=\"selectedFeatureKeys\"\n [options]=\"searchOptions\"\n (onChange)=\"onSearchOptionChange($event)\"\n appendTo=\"body\">\n </p-multiselect>\n </div>\n <div class=\"col-12 col-sm-4\">\n <p-select class=\"pw-filter-select\"\n inputId=\"subscriptions-list-status\"\n [options]=\"subscriptionStatus\"\n [placeholder]=\"'Filter by status'\"\n (onChange)=\"filterByStatus($event.value)\"\n [(ngModel)]=\"status\"\n appendTo=\"body\">\n </p-select>\n </div>\n <div class=\"text-end\">\n <label for=\"subscriptions-list-search\" class=\"visually-hidden\">Search Subscription</label>\n <p-iconfield iconPosition=\"left\">\n <p-inputicon><i class=\"fa fa-search\" aria-hidden=\"true\"></i></p-inputicon>\n <input type=\"text\"\n id=\"subscriptions-list-search\"\n name=\"subscriptions-list-search\"\n [(ngModel)]=\"searchText\"\n pInputText\n placeholder=\"Search subscriptions...\"\n (input)=\"dt.filterGlobal($event.target.value, 'contains')\"\n aria-label=\"Search subscriptions...\" />\n </p-iconfield>\n </div>\n </div>\n </ng-template>\n <ng-template #header>\n <tr>\n <th pResizableColumn scope=\"true\"\n pSortableColumn=\"id\">\n {{ 'Admin.Subscriptions.Id' | transloco }}\n <p-sort-icon field=\"id\"></p-sort-icon>\n </th>\n <th pResizableColumn scope=\"true\"\n pSortableColumn=\"organisation\">\n {{ 'Admin.Subscriptions.Organization' | transloco }}\n <p-sort-icon field=\"organisation\"></p-sort-icon>\n </th>\n <th pResizableColumn scope=\"true\"\n pSortableColumn=\"contact_name\">\n {{ 'Admin.Subscriptions.ContactName' | transloco }}\n <p-sort-icon field=\"contact_name\"></p-sort-icon>\n </th>\n <th pResizableColumn scope=\"true\"\n pSortableColumn=\"contact_email\">\n {{ 'Admin.Subscriptions.ContactEmail' | transloco }}\n <p-sort-icon field=\"contact_email\"></p-sort-icon>\n </th>\n <th pResizableColumn scope=\"true\">{{ 'Admin.Subscriptions.Product' | transloco }}</th>\n <th pResizableColumn scope=\"true\">{{ 'Admin.Subscriptions.Currency' | transloco }}</th>\n <th pResizableColumn scope=\"true\">{{ 'Admin.Subscriptions.PricePerMonth' | transloco }}</th>\n <th pResizableColumn scope=\"true\"\n pSortableColumn=\"stripe_customer_id\">\n {{ 'Admin.Subscriptions.Paid' | transloco }}\n <p-sort-icon field=\"stripe_customer_id\"></p-sort-icon>\n </th>\n <th pResizableColumn scope=\"true\">{{ 'Admin.Subscriptions.Billing' | transloco }}</th>\n <th pResizableColumn scope=\"true\"\n class=\"expires-at-width\">\n {{ 'Admin.Subscriptions.ExpiresAt' | transloco }}\n </th>\n <th pResizableColumn scope=\"true\"\n pSortableColumn=\"sessions_total\">\n {{ 'Admin.Subscriptions.SessionsTotal' | transloco }}\n <p-sort-icon field=\"sessions_total\"></p-sort-icon>\n </th>\n <th pResizableColumn scope=\"true\"\n pSortableColumn=\"sessions_last_month\">\n {{ 'Admin.Subscriptions.SessionsTotalLastMonth' | transloco }}\n <p-sort-icon field=\"sessions_last_month\"></p-sort-icon>\n </th>\n <th pResizableColumn scope=\"true\"\n pSortableColumn=\"deleted_at\">\n {{ 'Admin.Subscriptions.Deleted' | transloco }}\n <p-sort-icon field=\"deleted_at\"></p-sort-icon>\n </th>\n <th class=\"actions-list-two\"\n scope=\"true\">{{ 'Label.Actions' | transloco }}</th>\n </tr>\n </ng-template>\n <ng-template #body\n let-item>\n <tr>\n <td data-head=\"id\">{{ item.id }}</td>\n <td data-head=\"Organization\">\n <span class=\"cursor-pointer custom-break-word\"\n [pTooltip]=\"item.organisation\"\n appendTo=\"body\"\n tooltipPosition=\"top\">{{ item.organisation | textTruncate: 20 }}</span>\n </td>\n <td data-head=\"ContactName\" class=\"custom-break-word\">\n <span [pTooltip]=\"item.contact_name\" tooltipPosition=\"top\" appendTo=\"body\">{{ item.contact_name | textTruncate: 20 }}</span>\n </td>\n <td data-head=\"ContactEmail\">\n <span [pTooltip]=\"item.contact_email\" tooltipPosition=\"top\" appendTo=\"body\">{{ item.contact_email | textTruncate: 20 }}</span>\n </td>\n <td data-head=\"Name\">\n <span class=\"cursor-pointer custom-break-word\"\n [pTooltip]=\"item.productName\"\n appendTo=\"body\"\n tooltipPosition=\"top\">{{ item.productName | textTruncate: 20 }}</span>\n </td>\n <td data-head=\"Currency\">\n <span [appDynamicBadge]=\"{ itemsArray: currency, item: item.currency }\"\n color=\"blue-grey\"\n class=\"badge\">{{ item.currency }}</span>\n </td>\n <td data-head=\"Price/M\">\n <span>{{ (item.price / 100).toFixed(2) | currency:item.currency }}\n @if (item?.discount && objectKeys(item?.discount)?.length) {\n <i\n class=\"far fa-info-circle text-muted\"\n aria-hidden=\"true\"\n [pTooltip]=\"item?.discount | json\"\n tooltipPosition=\"top\"\n appendTo=\"body\"\n ></i>\n }\n </span>\n </td>\n <td data-head=\"Paid\">\n @if (item?.unsubscribed_at) {\n <span class=\"badge bg-warning d-inline-flex align-items-center\">\n Unsub\n @if (item?.reason_to_cancel) {\n <i class=\"far fa-info-circle ms-2 text-muted\"\n [pTooltip]=\"item.reason_to_cancel\"\n tooltipPosition=\"top\"\n appendTo=\"body\"\n aria-hidden=\"true\"></i>\n }\n </span>\n }\n @if (!item?.unsubscribed_at) {\n @if ((item?.stripe_customer_id || item?.external_payment) && item?.signed_up_at) {\n <span class=\"badge bg-success\">Yes</span>\n } @else {\n <span class=\"badge bg-blue-grey\">No</span>\n }\n }\n @if (item?.pause_collection && objectKeys(item?.pause_collection)?.length) {\n <span\n class=\"ms-2\"\n [pTooltip]=\"item?.pause_collection | json\"\n tooltipPosition=\"top\"\n appendTo=\"body\">\n <i class=\"fas fa-exclamation-triangle text-warning\"></i>\n </span>\n }\n </td>\n <td data-head=\"Billing\">\n <span class=\"badge\"\n [appDynamicBadge]=\"{\n itemsArray: billingFrequency,\n item: item?.billingFrequency\n }\"\n color=\"blue-grey\">{{ item.billingFrequency }}</span>\n </td>\n <td data-head=\"Expires\">\n <span [ngClass]=\"getExpiresAtColor(item)\">{{item?.expires_at | dateFormat}}</span>\n <span>&nbsp;({{item?.created_at | sinceAgo:true}})</span>\n </td>\n <td data-head=\"S#\">{{ item?.sessions_total }}</td>\n <td data-head=\"S/m #\">\n <span [ngClass]=\"{\n 'text-danger fw-bold': item?.sessions_last_month < 3\n }\">{{ item?.sessions_last_month }}</span>\n </td>\n <td data-head=\"Deleted\">\n @if (item?.deleted_at) {\n <span\n class=\"badge bg-danger\">Yes</span>\n }\n @if (!item?.deleted_at) {\n <span\n class=\"badge bg-blue-grey\">No</span>\n }\n </td>\n <td data-head=\"Action\">\n <ul class=\"list-unstyled list-inline list-action\">\n <li pTooltip=\"Edit\"\n tooltipPosition=\"top\"\n appendTo=\"body\"\n class=\"me-2 me-sm-3\"\n [routerLink]=\"[routers.subscriptionDetails, item.id]\">\n <i class=\"fa fa-edit edit-icon\" aria-hidden=\"true\"></i>\n </li>\n @if (item.deleted) {\n <li pTooltip=\"Reactivate subscription\"\n tooltipPosition=\"top\"\n appendTo=\"body\"\n class=\"me-2 me-sm-3\"\n *rbacAllow=\"'Pages.Alpha'\"\n (keydown.enter)=\"openRecoverSubscriptionModal(item)\"\n (click)=\"openRecoverSubscriptionModal(item)\">\n <i class=\"fa fa-trash delete-icon text-success\" aria-hidden=\"true\"></i>\n </li>\n } @else {\n <li pTooltip=\"Delete\"\n tooltipPosition=\"top\"\n appendTo=\"body\"\n class=\"me-2 me-sm-3\"\n *rbacAllow=\"'Pages.Admin.Subscription.Delete'\"\n (keydown.enter)=\"onDelete(item)\"\n (click)=\"onDelete(item)\">\n <i class=\"fa fa-trash delete-icon\" aria-hidden=\"true\"></i>\n </li>\n }\n </ul>\n </td>\n </tr>\n </ng-template>\n </p-table>\n @if (totalRecords === 0 && totalRecordsUnFiltered !== 0) {\n <div>\n <pw-no-data [withImage]=\"true\" [message]=\"'Search.NoDataMessage' | transloco\" [description]=\"'Search.NoDataDescription' | transloco\" >\n </pw-no-data>\n </div>\n }\n @if (totalRecords !== 0) {\n <pw-records-summary [showing]=\"dt?.value?.length ?? 0\" [total]=\"totalRecords\" />\n }\n </div>\n</div>\n@if (totalRecordsUnFiltered === 0 && isLoaded) {\n <pw-no-data [withImage]=\"true\" [message]=\"'Admin.Subscriptions.NoSubscriptionMessage' | transloco\">\n </pw-no-data>\n}\n<pw-password-validation\n #recoverSubscriptionPasswordModal\n (successEvent)=\"onRecoverConfirmed()\">\n</pw-password-validation>\n\n",
28815
28881
  styles: ["@charset \"UTF-8\";:root{--first: rgb(23 105 225);--second: rgb(54 194 131);--third: rgb(255 171 0);--text: rgb(34 34 34);--tabs_bg: rgb(23 105 225);--tabs_sub_bg: color-mix(in srgb, var(--first, rgb(23 105 225)) 85%, #000000);--tabs_text: rgb(255 255 255);--titles: rgb(34 34 34);--sidebar_bg: rgb(0, 48, 63);--sidebar_text: rgb(255 255 255);--dashboard_bg: rgb(255 255 255);--public-btn-radius: 24px}.table-responsive td{padding:6px 10px!important;font-size:12px!important;line-height:1.35;vertical-align:top;overflow-wrap:break-word}.table-responsive th{font-size:12px!important;vertical-align:bottom}.table-responsive td[data-head=Organization],.table-responsive td[data-head=Name],.table-responsive td[data-head=ContactName],.table-responsive td[data-head=ContactEmail],.table-responsive td[data-head=id],.table-responsive td[data-head=\"Price/M\"],.table-responsive td[data-head=\"S#\"],.table-responsive td[data-head=\"S/m #\"]{white-space:nowrap}.table-responsive td[data-head=id]{font-variant-numeric:tabular-nums;color:#7c8696}.table-responsive td[data-head=\"Price/M\"],.table-responsive td[data-head=\"S#\"],.table-responsive td[data-head=\"S/m #\"]{font-variant-numeric:tabular-nums;text-align:right}.table-responsive th:nth-child(7),.table-responsive th:nth-child(11),.table-responsive th:nth-child(12){text-align:right}.table-responsive .badge{font-size:11px;font-weight:600;padding:2px 8px;border-radius:4px;letter-spacing:.01em}.table-responsive .badge[class*=bg-success]{background-color:#e6f4ec!important;color:#0f6b3a!important}.table-responsive .badge[class*=bg-danger]{background-color:#fbeae8!important;color:#c0392b!important}.table-responsive .badge[class*=bg-warning]{background-color:#fbf1e3!important;color:#8a5a00!important}.table-responsive .badge.bg-blue-grey{background-color:#eef0f3!important;color:#5a6473!important}.table-responsive .badge.bg-blue-grey-1{background-color:#e9e6ef!important;color:#473172!important}.table-responsive .badge.bg-blue-grey-2{background-color:#efe6ef!important;color:#723172!important}.table-responsive .badge.bg-blue-grey-3{background-color:#efe6e9!important;color:#723147!important}.table-responsive .badge.bg-blue-grey-4{background-color:#efe9e6!important;color:#724731!important}.table-responsive .badge.bg-blue-grey-5{background-color:#efefe6!important;color:#727231!important}.table-responsive .badge.bg-blue-grey-6{background-color:#e9efe6!important;color:#477231!important}.table-responsive .badge.bg-blue-grey-7{background-color:#e6efe9!important;color:#317247!important}.table-responsive .badge.bg-blue-grey-8{background-color:#e6efef!important;color:#317272!important}.table-responsive .badge.bg-blue-grey-9{background-color:#e6e9ef!important;color:#314772!important}.table-responsive .badge.bg-blue-grey-10{background-color:#e9e6ef!important;color:#473172!important}.table-responsive .badge.bg-blue-grey-11{background-color:#efe6ef!important;color:#723172!important}.table-responsive .badge.bg-blue-grey-12{background-color:#efe6e9!important;color:#723147!important}.table-responsive .badge.bg-blue-grey-13{background-color:#efe9e6!important;color:#724731!important}.table-responsive .badge.bg-blue-grey-14{background-color:#efefe6!important;color:#727231!important}.table-responsive .badge.bg-blue-grey-15{background-color:#e9efe6!important;color:#477231!important}.table-responsive .badge.bg-blue-grey-16{background-color:#e6efe9!important;color:#317247!important}.table-responsive .badge.bg-blue-grey-17{background-color:#e6efef!important;color:#317272!important}.table-responsive .badge.bg-blue-grey-18{background-color:#e6e9ef!important;color:#314772!important}.table-responsive .badge.bg-blue-grey-19{background-color:#e9e6ef!important;color:#473172!important}.table-responsive .badge.bg-blue-grey-20{background-color:#efe6ef!important;color:#723172!important}.table-responsive .badge.bg-blue-grey-21{background-color:#efe6e9!important;color:#723147!important}.table-responsive .badge.bg-blue-grey-22{background-color:#efe9e6!important;color:#724731!important}.table-responsive .badge.bg-blue-grey-23{background-color:#efefe6!important;color:#727231!important}.table-responsive .badge.bg-blue-grey-24{background-color:#e9efe6!important;color:#477231!important}.table-responsive .badge[class*=bg-success]:before,.table-responsive .badge[class*=bg-danger]:before,.table-responsive .badge[class*=bg-warning]:before{content:\"\";display:inline-block;width:6px;height:6px;margin-right:6px;border-radius:50%;background-color:currentColor;vertical-align:middle}.table-responsive tbody tr:hover{background-color:#f5f7fa}.table-responsive td[data-head=Organization] span,.table-responsive td[data-head=Name] span{font-weight:600;color:#1a1d21}.table-responsive td[data-head=Expires] span~span{font-weight:600}.table-responsive .list-action .edit-icon{color:#5a6473}.table-responsive .list-action .delete-icon{color:#c0392b!important}.table-responsive .list-action .delete-icon.text-success{color:#0f6b3a!important}@media(max-width:1199.98px){.table-responsive td,.table-responsive th{white-space:nowrap;word-break:normal}}.expires-at-width{width:8%}.custom-break-word{overflow-wrap:break-word!important}.summary{display:flex}.summary .card{width:100%;margin-top:0;margin-bottom:0;padding-bottom:0!important;border:1px solid #e2e5ea;border-radius:8px;background-color:#fff;transition:background-color .12s ease,border-color .12s ease}.summary .card:hover{background-color:#fafbfc;border-color:#cfd4dc}.summary .card-body{display:flex;flex-direction:column;padding:2px 0}.summary .kpi{display:grid;grid-template-columns:auto minmax(0,1fr);column-gap:12px;align-items:baseline;padding:10px 16px}.summary .kpi+.kpi{border-top:1px solid #eef0f3}.summary .kpi-label{grid-column:1/-1;margin:0 0 4px;font-size:10px;font-weight:600;line-height:1.3;letter-spacing:.05em;text-transform:uppercase;color:#5a6473}.summary .kpi-label .fa-info-circle{margin-left:4px;font-size:15px;color:#a8afbc}.summary .kpi-value{grid-column:1;font-size:18px;font-weight:700;line-height:1.1;color:#1a1d21;font-variant-numeric:tabular-nums}.summary .kpi-comp{grid-column:2;text-align:right;font-size:12px;color:#7c8696;font-variant-numeric:tabular-nums;white-space:normal}.summary .kpi-comp:before{content:\"\\b7\";margin-right:4px;color:#a8afbc}.summary .kpi-comp b{font-weight:600;color:#5a6473}@media(min-width:320px)and (max-width:720px){.primeng-datatable-container .search-filter{display:flex;flex-direction:column;gap:.5rem;justify-content:space-between}}\n"]
28816
28882
  }]
28817
28883
  }],
@@ -36089,7 +36155,7 @@ var UserListComponent = class UserListComponent extends UsersListBaseComponent {
36089
36155
  ],
36090
36156
  usesInheritance: true,
36091
36157
  ngImport: i0,
36092
- template: "<div class=\"row\">\n <div class=\"col-12 d-flex flex-wrap justify-content-between align-items-baseline\">\n <h2 class=\"card-title p-0\">Users</h2>\n <a class=\"btn btn-sm btn-outline-primary\"\n id=\"btn-create\"\n *rbacAllow=\"'SuperAdmin'\"\n [routerLink]=\"[routers.usersDetails + 'add']\">\n <i class=\"fa fa-plus-circle\" aria-hidden=\"true\"></i> Add User\n </a>\n </div>\n</div>\n<div class=\"w-100 text-center mt-3\">\n @if (!isLoaded) {\n <p-progress-spinner> </p-progress-spinner>\n }\n</div>\n<div class=\"primeng-datatable-container actions-collapsed mt-0\" [class.hideTable]=\"totalRecordsUnFiltered === 0\">\n <div class=\"user-management-table table-responsive\">\n <p-table #dt\n [value]=\"users\"\n [paginator]=\"totalRecords !== 0\"\n [lazy]=\"true\"\n [rows]=\"PAGE_SIZE\"\n [totalRecords]=\"totalRecords\"\n [loading]=\"loading\"\n [filterDelay]=\"1000\"\n (onLazyLoad)=\"onLazyLoad($event)\"\n [customSort]=\"true\">\n <ng-template #caption>\n <div class=\"search-filter\">\n <div class=\"col-sm-4\">\n <p-multiselect class=\"pw-filter-select\" inputId=\"users-list-filter-role-product\"\n [options]=\"searchOptions\"\n (onChange)=\"onSearchOptionChange($event)\"\n placeholder=\"Filter users by role, product, or feature\"\n [selectionLimit]=\"1\"\n [(ngModel)]=\"filterSource\"\n [showToggleAll]=\"true\"\n [showHeader]=\"true\"\n appendTo=\"body\">\n </p-multiselect>\n </div>\n @if (selectedOption) {\n <div class=\"col-4\"\n >\n <p-multiselect class=\"pw-filter-select\" inputId=\"users-list-filter-criteria\"\n [options]=\"searchDataSource\"\n (onChange)=\"onSearchCriteria($event)\"\n [showToggleAll]=\"true\"\n [(ngModel)]=\"criteria\"\n [showHeader]=\"true\"\n placeholder=\"Filter by {{ selectedOption.value }}s\"\n maxSelectedLabels=\"2\"\n appendTo=\"body\">\n </p-multiselect>\n </div>\n }\n <div class=\"col-auto d-flex align-items-center\">\n <span class=\"ambassadors-only-toggle\"\n [pTooltip]=\"'Admin.Users.AmbassadorsOnly' | transloco\"\n tooltipPosition=\"top\" appendTo=\"body\">\n <ui-switch\n [checked]=\"showAmbassadorsOnly\"\n (change)=\"showAmbassadorsOnly = $event; onAmbassadorsOnlyToggle()\"\n [attr.aria-label]=\"'Admin.Users.AmbassadorsOnly' | transloco\">\n </ui-switch>\n </span>\n </div>\n <div class=\"text-end\">\n <label for=\"users-list-search\" class=\"visually-hidden\">Search User</label>\n <p-iconfield iconPosition=\"left\">\n <p-inputicon><i class=\"fa fa-search\" aria-hidden=\"true\"></i></p-inputicon>\n <input type=\"text\"\n id=\"users-list-search\"\n name=\"users-list-search\"\n [(ngModel)]=\"searchText\"\n pInputText\n placeholder=\"Search users...\"\n data-cy=\"user-search\"\n (input)=\"dt.filterGlobal($event.target.value, 'contains')\"\n class=\"wd-90\"\n aria-label=\"Search users...\" />\n </p-iconfield>\n </div>\n </div>\n </ng-template>\n <ng-template #header>\n <tr>\n <th scope=\"true\"\n pSortableColumn=\"id\">\n {{ 'Admin.Users.Id' | transloco }}\n <p-sort-icon field=\"id\"></p-sort-icon>\n </th>\n <th scope=\"true\"\n pSortableColumn=\"first_name\">\n {{ 'Label.FirstName' | transloco }}\n <p-sort-icon field=\"first_name\"></p-sort-icon>\n </th>\n <th scope=\"true\"\n pSortableColumn=\"last_name\">\n {{ 'Label.LastName' | transloco }}\n <p-sort-icon field=\"last_name\"></p-sort-icon>\n </th>\n <th scope=\"true\"\n pSortableColumn=\"email\">\n {{ 'Label.Email' | transloco }}\n <p-sort-icon field=\"email\"></p-sort-icon>\n </th>\n <th scope=\"true\"\n pSortableColumn=\"slug\">\n {{ 'Admin.Users.Slug' | transloco }}\n <p-sort-icon field=\"slug\"></p-sort-icon>\n </th>\n <th scope=\"true\"\n pSortableColumn=\"encrypted_password\">\n {{ 'Admin.Users.EmailConfirm' | transloco }}\n <p-sort-icon field=\"encrypted_password\"></p-sort-icon>\n </th>\n\n <th scope=\"true\"\n pSortableColumn=\"sessions_last_month\">\n {{ 'Admin.Subscriptions.SessionsTotalLastMonth' | transloco }}\n <p-sort-icon field=\"sessions_last_month\"></p-sort-icon>\n </th>\n <th scope=\"true\"\n pSortableColumn=\"last_sign_in_at\">\n {{ 'Admin.Users.LastLogin' | transloco }}\n <p-sort-icon field=\"last_sign_in_at\"></p-sort-icon>\n </th>\n <th scope=\"true\"\n pSortableColumn=\"signed_up_at\">\n {{ 'Admin.Users.RegisteredOn' | transloco }}\n <p-sort-icon field=\"signed_up_at\"></p-sort-icon>\n </th>\n <th scope=\"true\"\n class=\"actions-list-four\">\n {{ 'Label.Actions' | transloco }}\n </th>\n </tr>\n </ng-template>\n <ng-template #body\n let-user>\n <tr>\n <td data-head=\"id\"> {{ user.id }}</td>\n <td data-head=\"First Name\"><a [routerLink]=\"['/members', user.slug]\">{{ user.first_name }}</a></td>\n <td data-head=\"Last Name\">{{ user.last_name }}\n @if (user?.alpha) {\n <span\n [pTooltip]=\"'Admin.Users.Tooltip.AlphaIcon'|transloco\"\n tooltipPosition=\"top\" appendTo=\"body\">\n <i class=\"fa-regular fa-square-a alpha-beta text-warning\"></i>\n </span>\n }\n @if (user?.beta) {\n <span class=\"ms-2\"\n [pTooltip]=\"'Admin.Users.Tooltip.BetaIcon'|transloco\"\n tooltipPosition=\"top\" appendTo=\"body\">\n <i class=\"fa-regular fa-square-b alpha-beta text-primary\" ></i>\n </span>\n }\n @if (user?.cognito_sso_activated) {\n <span\n class=\"ms-2\"\n [pTooltip]=\"'Admin.Users.Tooltip.Cognito' | transloco\"\n tooltipPosition=\"top\" appendTo=\"body\">\n <i class=\"fa fa-cloud success\" ></i>\n </span>\n }\n @if (user?.ambassador_count > 0) {\n <span\n class=\"ms-2\"\n [pTooltip]=\"'Admin.Users.Tooltip.Ambassador' | transloco\"\n tooltipPosition=\"top\" appendTo=\"body\">\n <i class=\"fa fa-handshake alpha-beta text-primary\" aria-hidden=\"true\"></i>\n </span>\n }\n </td>\n <td data-head=\"Email\">{{ user.email }}</td>\n <td data-head=\"Slug\">{{ user.slug }}</td>\n <td data-head=\"Email Confirm\">\n <span [appDynamicBadge]=\"{\n itemsArray: [true, false],\n item: user?.has_password\n }\"\n color=\"success-danger\"\n class=\"badge\">{{ user?.has_password ? 'Yes' : 'No' }}</span>\n @if (user?.blocked) {\n <span class=\"ms-2\" [pTooltip]=\"'This user has been blocked'\" tooltipPosition=\"top\" appendTo=\"body\">\n <i class=\"fa-solid fa-hexagon-exclamation text-danger hexa-warning\"></i>\n </span>\n }\n </td>\n <td data-head=\"S/m #\">\n <span [ngClass]=\"{\n 'text-danger fw-bold': user?.sessions_last_month < 3\n }\">{{ user?.sessions_last_month }}</span>\n </td>\n <td data-head=\"Last Login\">\n @if (user?.current_sign_in_at | isOnline) {\n <pw-online-indicator [lastSeen]=\"user.current_sign_in_at\" />\n } @else if (user?.current_sign_in_at) {\n <span>\n {{ user.current_sign_in_at | dateFormat }}\n </span>\n } @else {\n {{ user.last_sign_in_at | dateFormat }}\n }\n </td>\n <td data-head=\"Registered On\">{{ user.signed_up_at | dateFormat }}</td>\n <td data-head=\"Action\">\n <ul class=\"list-unstyled list-inline list-action\">\n <li pTooltip=\"Impersonate this user\" tooltipPosition=\"top\" appendTo=\"body\"\n *rbacAllow=\"'Pages.Alpha'\"\n class=\"me-2 me-sm-3\">\n <i\n class=\"fas fa-people-arrows fa-lg\"\n (click)=\"onImpersonate(user)\"\n (keydown.enter)=\"onImpersonate(user)\"\n aria-hidden=\"true\"\n ></i>\n </li>\n @if (user?.enable_two_factor_authenticator) {\n <li pTooltip=\"Disable 2FA\" tooltipPosition=\"top\" appendTo=\"body\"\n (click)=\"disable2fa(user?.id)\"\n (keydown.enter)=\"disable2fa(user?.id)\"\n *rbacAllow=\"'Pages.Alpha'\"\n class=\"me-2 me-sm-3\">\n <i class=\"fa fa-lock fa-lg success\" aria-hidden=\"true\"></i>\n </li>\n }\n @if (currentUser && user.id !== currentUser.id) {\n <li pTooltip=\"Message\" tooltipPosition=\"top\" appendTo=\"body\"\n *rbacAllow=\"chatPermission\"\n class=\"me-2 me-sm-3\"\n [routerLink]=\"['/message']\"\n [fragment]=\"user.slug\">\n <i class=\"fa fa-comments cta1-icon\" aria-hidden=\"true\"></i>\n </li>\n }\n <li pTooltip=\"Edit\" tooltipPosition=\"top\" appendTo=\"body\"\n *rbacAllow=\"'Pages.Admin.Users.Edit'\"\n class=\"me-2 me-sm-3\"\n [routerLink]=\"[routers.usersDetails + user.id]\">\n <i class=\"fa fa-edit edit-icon\" aria-hidden=\"true\"></i>\n </li>\n <li pTooltip=\"Delete\" tooltipPosition=\"top\" appendTo=\"body\"\n *rbacAllow=\"'Pages.Admin.Users.Delete'\"\n class=\"me-2 me-sm-3\">\n <i\n class=\"fa fa-trash delete-icon\"\n (keydown.enter)=\"onDelete(user)\"\n (keydown.space)=\"onDelete(user)\"\n (click)=\"onDelete(user)\"\n aria-hidden=\"true\"\n ></i>\n </li>\n </ul>\n </td>\n </tr>\n </ng-template>\n </p-table>\n @if (totalRecords === 0 && totalRecordsUnFiltered !== 0) {\n <div>\n <pw-no-data [withImage]=\"true\" [message]=\"'Search.NoDataMessage' | transloco\" [description]=\"'Search.NoDataDescription' | transloco\">\n </pw-no-data>\n </div>\n }\n @if (totalRecords !== 0) {\n <pw-records-summary [showing]=\"dt?.value?.length ?? 0\" [total]=\"totalRecords\" />\n }\n </div>\n</div>\n@if (!loading && totalRecordsUnFiltered === 0) {\n <div>\n <pw-no-data [withImage]=\"true\" [message]=\"'Admin.Users.NoDataMessage' | transloco\"> </pw-no-data>\n </div>\n}\n<!-- password validation modal for delete user -->\n<pw-password-validation #passwordValidationModalForUserDelete\n [destructive]=\"true\"\n (successEvent)=\"deleteUser($event)\">\n</pw-password-validation>\n<!-- password validation modal for impersonate -->\n<pw-password-validation #passwordValidationModalForImpersonate\n (successEvent)=\"onUserImpersonation($event)\">\n</pw-password-validation>\n<!-- password validation modal for remove2fa -->\n<pw-password-validation #passwordValidationModalForRemove2fa\n (successEvent)=\"remove2fa($event)\">\n</pw-password-validation>\n",
36158
+ template: "<div class=\"row\">\n <div class=\"col-12 d-flex flex-wrap justify-content-between align-items-baseline\">\n <h2 class=\"card-title p-0\">Users</h2>\n <a class=\"btn btn-sm btn-outline-primary\"\n id=\"btn-create\"\n *rbacAllow=\"'SuperAdmin'\"\n [routerLink]=\"[routers.usersDetails + 'add']\">\n <i class=\"fa fa-plus-circle\" aria-hidden=\"true\"></i> Add User\n </a>\n </div>\n</div>\n<div class=\"w-100 text-center mt-3\">\n @if (!isLoaded) {\n <p-progress-spinner> </p-progress-spinner>\n }\n</div>\n<div class=\"primeng-datatable-container actions-collapsed mt-0\" [class.hideTable]=\"totalRecordsUnFiltered === 0\">\n <div class=\"user-management-table table-responsive\">\n <p-table #dt\n stateKey=\"pw-table.admin-users-list\"\n stateStorage=\"session\"\n [resizableColumns]=\"true\"\n columnResizeMode=\"expand\"\n [value]=\"users\"\n [paginator]=\"totalRecords !== 0\"\n [lazy]=\"true\"\n [rows]=\"PAGE_SIZE\"\n [totalRecords]=\"totalRecords\"\n [loading]=\"loading\"\n [filterDelay]=\"1000\"\n (onLazyLoad)=\"onLazyLoad($event)\"\n [customSort]=\"true\">\n <ng-template #caption>\n <div class=\"search-filter\">\n <div class=\"col-sm-4\">\n <p-multiselect class=\"pw-filter-select\" inputId=\"users-list-filter-role-product\"\n [options]=\"searchOptions\"\n (onChange)=\"onSearchOptionChange($event)\"\n placeholder=\"Filter users by role, product, or feature\"\n [selectionLimit]=\"1\"\n [(ngModel)]=\"filterSource\"\n [showToggleAll]=\"true\"\n [showHeader]=\"true\"\n appendTo=\"body\">\n </p-multiselect>\n </div>\n @if (selectedOption) {\n <div class=\"col-4\"\n >\n <p-multiselect class=\"pw-filter-select\" inputId=\"users-list-filter-criteria\"\n [options]=\"searchDataSource\"\n (onChange)=\"onSearchCriteria($event)\"\n [showToggleAll]=\"true\"\n [(ngModel)]=\"criteria\"\n [showHeader]=\"true\"\n placeholder=\"Filter by {{ selectedOption.value }}s\"\n maxSelectedLabels=\"2\"\n appendTo=\"body\">\n </p-multiselect>\n </div>\n }\n <div class=\"col-auto d-flex align-items-center\">\n <span class=\"ambassadors-only-toggle\"\n [pTooltip]=\"'Admin.Users.AmbassadorsOnly' | transloco\"\n tooltipPosition=\"top\" appendTo=\"body\">\n <ui-switch\n [checked]=\"showAmbassadorsOnly\"\n (change)=\"showAmbassadorsOnly = $event; onAmbassadorsOnlyToggle()\"\n [attr.aria-label]=\"'Admin.Users.AmbassadorsOnly' | transloco\">\n </ui-switch>\n </span>\n </div>\n <div class=\"text-end\">\n <label for=\"users-list-search\" class=\"visually-hidden\">Search User</label>\n <p-iconfield iconPosition=\"left\">\n <p-inputicon><i class=\"fa fa-search\" aria-hidden=\"true\"></i></p-inputicon>\n <input type=\"text\"\n id=\"users-list-search\"\n name=\"users-list-search\"\n [(ngModel)]=\"searchText\"\n pInputText\n placeholder=\"Search users...\"\n data-cy=\"user-search\"\n (input)=\"dt.filterGlobal($event.target.value, 'contains')\"\n class=\"wd-90\"\n aria-label=\"Search users...\" />\n </p-iconfield>\n </div>\n </div>\n </ng-template>\n <ng-template #header>\n <tr>\n <th pResizableColumn scope=\"true\"\n pSortableColumn=\"id\">\n {{ 'Admin.Users.Id' | transloco }}\n <p-sort-icon field=\"id\"></p-sort-icon>\n </th>\n <th pResizableColumn scope=\"true\"\n pSortableColumn=\"first_name\">\n {{ 'Label.FirstName' | transloco }}\n <p-sort-icon field=\"first_name\"></p-sort-icon>\n </th>\n <th pResizableColumn scope=\"true\"\n pSortableColumn=\"last_name\">\n {{ 'Label.LastName' | transloco }}\n <p-sort-icon field=\"last_name\"></p-sort-icon>\n </th>\n <th pResizableColumn scope=\"true\"\n pSortableColumn=\"email\">\n {{ 'Label.Email' | transloco }}\n <p-sort-icon field=\"email\"></p-sort-icon>\n </th>\n <th pResizableColumn scope=\"true\"\n pSortableColumn=\"slug\">\n {{ 'Admin.Users.Slug' | transloco }}\n <p-sort-icon field=\"slug\"></p-sort-icon>\n </th>\n <th pResizableColumn scope=\"true\"\n pSortableColumn=\"encrypted_password\">\n {{ 'Admin.Users.EmailConfirm' | transloco }}\n <p-sort-icon field=\"encrypted_password\"></p-sort-icon>\n </th>\n\n <th pResizableColumn scope=\"true\"\n pSortableColumn=\"sessions_last_month\">\n {{ 'Admin.Subscriptions.SessionsTotalLastMonth' | transloco }}\n <p-sort-icon field=\"sessions_last_month\"></p-sort-icon>\n </th>\n <th pResizableColumn scope=\"true\"\n pSortableColumn=\"last_sign_in_at\">\n {{ 'Admin.Users.LastLogin' | transloco }}\n <p-sort-icon field=\"last_sign_in_at\"></p-sort-icon>\n </th>\n <th pResizableColumn scope=\"true\"\n pSortableColumn=\"signed_up_at\">\n {{ 'Admin.Users.RegisteredOn' | transloco }}\n <p-sort-icon field=\"signed_up_at\"></p-sort-icon>\n </th>\n <th scope=\"true\"\n class=\"actions-list-four\">\n {{ 'Label.Actions' | transloco }}\n </th>\n </tr>\n </ng-template>\n <ng-template #body\n let-user>\n <tr>\n <td data-head=\"id\"> {{ user.id }}</td>\n <td data-head=\"First Name\"><a [routerLink]=\"['/members', user.slug]\">{{ user.first_name }}</a></td>\n <td data-head=\"Last Name\">{{ user.last_name }}\n @if (user?.alpha) {\n <span\n [pTooltip]=\"'Admin.Users.Tooltip.AlphaIcon'|transloco\"\n tooltipPosition=\"top\" appendTo=\"body\">\n <i class=\"fa-regular fa-square-a alpha-beta text-warning\"></i>\n </span>\n }\n @if (user?.beta) {\n <span class=\"ms-2\"\n [pTooltip]=\"'Admin.Users.Tooltip.BetaIcon'|transloco\"\n tooltipPosition=\"top\" appendTo=\"body\">\n <i class=\"fa-regular fa-square-b alpha-beta text-primary\" ></i>\n </span>\n }\n @if (user?.cognito_sso_activated) {\n <span\n class=\"ms-2\"\n [pTooltip]=\"'Admin.Users.Tooltip.Cognito' | transloco\"\n tooltipPosition=\"top\" appendTo=\"body\">\n <i class=\"fa fa-cloud success\" ></i>\n </span>\n }\n @if (user?.ambassador_count > 0) {\n <span\n class=\"ms-2\"\n [pTooltip]=\"'Admin.Users.Tooltip.Ambassador' | transloco\"\n tooltipPosition=\"top\" appendTo=\"body\">\n <i class=\"fa fa-handshake alpha-beta text-primary\" aria-hidden=\"true\"></i>\n </span>\n }\n </td>\n <td data-head=\"Email\">{{ user.email }}</td>\n <td data-head=\"Slug\">{{ user.slug }}</td>\n <td data-head=\"Email Confirm\">\n <span [appDynamicBadge]=\"{\n itemsArray: [true, false],\n item: user?.has_password\n }\"\n color=\"success-danger\"\n class=\"badge\">{{ user?.has_password ? 'Yes' : 'No' }}</span>\n @if (user?.blocked) {\n <span class=\"ms-2\" [pTooltip]=\"'This user has been blocked'\" tooltipPosition=\"top\" appendTo=\"body\">\n <i class=\"fa-solid fa-hexagon-exclamation text-danger hexa-warning\"></i>\n </span>\n }\n </td>\n <td data-head=\"S/m #\">\n <span [ngClass]=\"{\n 'text-danger fw-bold': user?.sessions_last_month < 3\n }\">{{ user?.sessions_last_month }}</span>\n </td>\n <td data-head=\"Last Login\">\n @if (user?.current_sign_in_at | isOnline) {\n <pw-online-indicator [lastSeen]=\"user.current_sign_in_at\" />\n } @else if (user?.current_sign_in_at) {\n <span>\n {{ user.current_sign_in_at | dateFormat }}\n </span>\n } @else {\n {{ user.last_sign_in_at | dateFormat }}\n }\n </td>\n <td data-head=\"Registered On\">{{ user.signed_up_at | dateFormat }}</td>\n <td data-head=\"Action\">\n <ul class=\"list-unstyled list-inline list-action\">\n <li pTooltip=\"Impersonate this user\" tooltipPosition=\"top\" appendTo=\"body\"\n *rbacAllow=\"'Pages.Alpha'\"\n class=\"me-2 me-sm-3\">\n <i\n class=\"fas fa-people-arrows fa-lg\"\n (click)=\"onImpersonate(user)\"\n (keydown.enter)=\"onImpersonate(user)\"\n aria-hidden=\"true\"\n ></i>\n </li>\n @if (user?.enable_two_factor_authenticator) {\n <li pTooltip=\"Disable 2FA\" tooltipPosition=\"top\" appendTo=\"body\"\n (click)=\"disable2fa(user?.id)\"\n (keydown.enter)=\"disable2fa(user?.id)\"\n *rbacAllow=\"'Pages.Alpha'\"\n class=\"me-2 me-sm-3\">\n <i class=\"fa fa-lock fa-lg success\" aria-hidden=\"true\"></i>\n </li>\n }\n @if (currentUser && user.id !== currentUser.id) {\n <li pTooltip=\"Message\" tooltipPosition=\"top\" appendTo=\"body\"\n *rbacAllow=\"chatPermission\"\n class=\"me-2 me-sm-3\"\n [routerLink]=\"['/message']\"\n [fragment]=\"user.slug\">\n <i class=\"fa fa-comments cta1-icon\" aria-hidden=\"true\"></i>\n </li>\n }\n <li pTooltip=\"Edit\" tooltipPosition=\"top\" appendTo=\"body\"\n *rbacAllow=\"'Pages.Admin.Users.Edit'\"\n class=\"me-2 me-sm-3\"\n [routerLink]=\"[routers.usersDetails + user.id]\">\n <i class=\"fa fa-edit edit-icon\" aria-hidden=\"true\"></i>\n </li>\n <li pTooltip=\"Delete\" tooltipPosition=\"top\" appendTo=\"body\"\n *rbacAllow=\"'Pages.Admin.Users.Delete'\"\n class=\"me-2 me-sm-3\">\n <i\n class=\"fa fa-trash delete-icon\"\n (keydown.enter)=\"onDelete(user)\"\n (keydown.space)=\"onDelete(user)\"\n (click)=\"onDelete(user)\"\n aria-hidden=\"true\"\n ></i>\n </li>\n </ul>\n </td>\n </tr>\n </ng-template>\n </p-table>\n @if (totalRecords === 0 && totalRecordsUnFiltered !== 0) {\n <div>\n <pw-no-data [withImage]=\"true\" [message]=\"'Search.NoDataMessage' | transloco\" [description]=\"'Search.NoDataDescription' | transloco\">\n </pw-no-data>\n </div>\n }\n @if (totalRecords !== 0) {\n <pw-records-summary [showing]=\"dt?.value?.length ?? 0\" [total]=\"totalRecords\" />\n }\n </div>\n</div>\n@if (!loading && totalRecordsUnFiltered === 0) {\n <div>\n <pw-no-data [withImage]=\"true\" [message]=\"'Admin.Users.NoDataMessage' | transloco\"> </pw-no-data>\n </div>\n}\n<!-- password validation modal for delete user -->\n<pw-password-validation #passwordValidationModalForUserDelete\n [destructive]=\"true\"\n (successEvent)=\"deleteUser($event)\">\n</pw-password-validation>\n<!-- password validation modal for impersonate -->\n<pw-password-validation #passwordValidationModalForImpersonate\n (successEvent)=\"onUserImpersonation($event)\">\n</pw-password-validation>\n<!-- password validation modal for remove2fa -->\n<pw-password-validation #passwordValidationModalForRemove2fa\n (successEvent)=\"remove2fa($event)\">\n</pw-password-validation>\n",
36093
36159
  styles: ["@charset \"UTF-8\";:root{--first: rgb(23 105 225);--second: rgb(54 194 131);--third: rgb(255 171 0);--text: rgb(34 34 34);--tabs_bg: rgb(23 105 225);--tabs_sub_bg: color-mix(in srgb, var(--first, rgb(23 105 225)) 85%, #000000);--tabs_text: rgb(255 255 255);--titles: rgb(34 34 34);--sidebar_bg: rgb(0, 48, 63);--sidebar_text: rgb(255 255 255);--dashboard_bg: rgb(255 255 255);--public-btn-radius: 24px}.search-input input{width:100%}.w-150{width:150px}.table-responsive td[data-head=id]{font-variant-numeric:tabular-nums;color:#7c8696}.hexa-warning{font-size:18px;vertical-align:middle}.alpha-beta{font-size:14px}.ambassadors-only-toggle{display:inline-flex;align-items:center}.ambassadors-only-toggle ::ng-deep .switch small{display:flex;align-items:center;justify-content:center}.ambassadors-only-toggle ::ng-deep .switch small:after{content:\"\\f2b5\";font-family:\"Font Awesome 6 Pro\",sans-serif;font-weight:900;font-size:12px;line-height:1;color:var(--first)}\n"],
36094
36160
  dependencies: [
36095
36161
  {
@@ -36211,6 +36277,12 @@ var UserListComponent = class UserListComponent extends UsersListBaseComponent {
36211
36277
  selector: "[pSortableColumn]",
36212
36278
  inputs: ["pSortableColumn", "pSortableColumnDisabled"]
36213
36279
  },
36280
+ {
36281
+ kind: "directive",
36282
+ type: i2$3.ResizableColumn,
36283
+ selector: "[pResizableColumn]",
36284
+ inputs: ["pResizableColumnDisabled"]
36285
+ },
36214
36286
  {
36215
36287
  kind: "component",
36216
36288
  type: i2$3.SortIcon,
@@ -36521,7 +36593,7 @@ i0.ɵɵngDeclareClassMetadata({
36521
36593
  args: [{
36522
36594
  selector: "pw-admin-user-list",
36523
36595
  standalone: false,
36524
- template: "<div class=\"row\">\n <div class=\"col-12 d-flex flex-wrap justify-content-between align-items-baseline\">\n <h2 class=\"card-title p-0\">Users</h2>\n <a class=\"btn btn-sm btn-outline-primary\"\n id=\"btn-create\"\n *rbacAllow=\"'SuperAdmin'\"\n [routerLink]=\"[routers.usersDetails + 'add']\">\n <i class=\"fa fa-plus-circle\" aria-hidden=\"true\"></i> Add User\n </a>\n </div>\n</div>\n<div class=\"w-100 text-center mt-3\">\n @if (!isLoaded) {\n <p-progress-spinner> </p-progress-spinner>\n }\n</div>\n<div class=\"primeng-datatable-container actions-collapsed mt-0\" [class.hideTable]=\"totalRecordsUnFiltered === 0\">\n <div class=\"user-management-table table-responsive\">\n <p-table #dt\n [value]=\"users\"\n [paginator]=\"totalRecords !== 0\"\n [lazy]=\"true\"\n [rows]=\"PAGE_SIZE\"\n [totalRecords]=\"totalRecords\"\n [loading]=\"loading\"\n [filterDelay]=\"1000\"\n (onLazyLoad)=\"onLazyLoad($event)\"\n [customSort]=\"true\">\n <ng-template #caption>\n <div class=\"search-filter\">\n <div class=\"col-sm-4\">\n <p-multiselect class=\"pw-filter-select\" inputId=\"users-list-filter-role-product\"\n [options]=\"searchOptions\"\n (onChange)=\"onSearchOptionChange($event)\"\n placeholder=\"Filter users by role, product, or feature\"\n [selectionLimit]=\"1\"\n [(ngModel)]=\"filterSource\"\n [showToggleAll]=\"true\"\n [showHeader]=\"true\"\n appendTo=\"body\">\n </p-multiselect>\n </div>\n @if (selectedOption) {\n <div class=\"col-4\"\n >\n <p-multiselect class=\"pw-filter-select\" inputId=\"users-list-filter-criteria\"\n [options]=\"searchDataSource\"\n (onChange)=\"onSearchCriteria($event)\"\n [showToggleAll]=\"true\"\n [(ngModel)]=\"criteria\"\n [showHeader]=\"true\"\n placeholder=\"Filter by {{ selectedOption.value }}s\"\n maxSelectedLabels=\"2\"\n appendTo=\"body\">\n </p-multiselect>\n </div>\n }\n <div class=\"col-auto d-flex align-items-center\">\n <span class=\"ambassadors-only-toggle\"\n [pTooltip]=\"'Admin.Users.AmbassadorsOnly' | transloco\"\n tooltipPosition=\"top\" appendTo=\"body\">\n <ui-switch\n [checked]=\"showAmbassadorsOnly\"\n (change)=\"showAmbassadorsOnly = $event; onAmbassadorsOnlyToggle()\"\n [attr.aria-label]=\"'Admin.Users.AmbassadorsOnly' | transloco\">\n </ui-switch>\n </span>\n </div>\n <div class=\"text-end\">\n <label for=\"users-list-search\" class=\"visually-hidden\">Search User</label>\n <p-iconfield iconPosition=\"left\">\n <p-inputicon><i class=\"fa fa-search\" aria-hidden=\"true\"></i></p-inputicon>\n <input type=\"text\"\n id=\"users-list-search\"\n name=\"users-list-search\"\n [(ngModel)]=\"searchText\"\n pInputText\n placeholder=\"Search users...\"\n data-cy=\"user-search\"\n (input)=\"dt.filterGlobal($event.target.value, 'contains')\"\n class=\"wd-90\"\n aria-label=\"Search users...\" />\n </p-iconfield>\n </div>\n </div>\n </ng-template>\n <ng-template #header>\n <tr>\n <th scope=\"true\"\n pSortableColumn=\"id\">\n {{ 'Admin.Users.Id' | transloco }}\n <p-sort-icon field=\"id\"></p-sort-icon>\n </th>\n <th scope=\"true\"\n pSortableColumn=\"first_name\">\n {{ 'Label.FirstName' | transloco }}\n <p-sort-icon field=\"first_name\"></p-sort-icon>\n </th>\n <th scope=\"true\"\n pSortableColumn=\"last_name\">\n {{ 'Label.LastName' | transloco }}\n <p-sort-icon field=\"last_name\"></p-sort-icon>\n </th>\n <th scope=\"true\"\n pSortableColumn=\"email\">\n {{ 'Label.Email' | transloco }}\n <p-sort-icon field=\"email\"></p-sort-icon>\n </th>\n <th scope=\"true\"\n pSortableColumn=\"slug\">\n {{ 'Admin.Users.Slug' | transloco }}\n <p-sort-icon field=\"slug\"></p-sort-icon>\n </th>\n <th scope=\"true\"\n pSortableColumn=\"encrypted_password\">\n {{ 'Admin.Users.EmailConfirm' | transloco }}\n <p-sort-icon field=\"encrypted_password\"></p-sort-icon>\n </th>\n\n <th scope=\"true\"\n pSortableColumn=\"sessions_last_month\">\n {{ 'Admin.Subscriptions.SessionsTotalLastMonth' | transloco }}\n <p-sort-icon field=\"sessions_last_month\"></p-sort-icon>\n </th>\n <th scope=\"true\"\n pSortableColumn=\"last_sign_in_at\">\n {{ 'Admin.Users.LastLogin' | transloco }}\n <p-sort-icon field=\"last_sign_in_at\"></p-sort-icon>\n </th>\n <th scope=\"true\"\n pSortableColumn=\"signed_up_at\">\n {{ 'Admin.Users.RegisteredOn' | transloco }}\n <p-sort-icon field=\"signed_up_at\"></p-sort-icon>\n </th>\n <th scope=\"true\"\n class=\"actions-list-four\">\n {{ 'Label.Actions' | transloco }}\n </th>\n </tr>\n </ng-template>\n <ng-template #body\n let-user>\n <tr>\n <td data-head=\"id\"> {{ user.id }}</td>\n <td data-head=\"First Name\"><a [routerLink]=\"['/members', user.slug]\">{{ user.first_name }}</a></td>\n <td data-head=\"Last Name\">{{ user.last_name }}\n @if (user?.alpha) {\n <span\n [pTooltip]=\"'Admin.Users.Tooltip.AlphaIcon'|transloco\"\n tooltipPosition=\"top\" appendTo=\"body\">\n <i class=\"fa-regular fa-square-a alpha-beta text-warning\"></i>\n </span>\n }\n @if (user?.beta) {\n <span class=\"ms-2\"\n [pTooltip]=\"'Admin.Users.Tooltip.BetaIcon'|transloco\"\n tooltipPosition=\"top\" appendTo=\"body\">\n <i class=\"fa-regular fa-square-b alpha-beta text-primary\" ></i>\n </span>\n }\n @if (user?.cognito_sso_activated) {\n <span\n class=\"ms-2\"\n [pTooltip]=\"'Admin.Users.Tooltip.Cognito' | transloco\"\n tooltipPosition=\"top\" appendTo=\"body\">\n <i class=\"fa fa-cloud success\" ></i>\n </span>\n }\n @if (user?.ambassador_count > 0) {\n <span\n class=\"ms-2\"\n [pTooltip]=\"'Admin.Users.Tooltip.Ambassador' | transloco\"\n tooltipPosition=\"top\" appendTo=\"body\">\n <i class=\"fa fa-handshake alpha-beta text-primary\" aria-hidden=\"true\"></i>\n </span>\n }\n </td>\n <td data-head=\"Email\">{{ user.email }}</td>\n <td data-head=\"Slug\">{{ user.slug }}</td>\n <td data-head=\"Email Confirm\">\n <span [appDynamicBadge]=\"{\n itemsArray: [true, false],\n item: user?.has_password\n }\"\n color=\"success-danger\"\n class=\"badge\">{{ user?.has_password ? 'Yes' : 'No' }}</span>\n @if (user?.blocked) {\n <span class=\"ms-2\" [pTooltip]=\"'This user has been blocked'\" tooltipPosition=\"top\" appendTo=\"body\">\n <i class=\"fa-solid fa-hexagon-exclamation text-danger hexa-warning\"></i>\n </span>\n }\n </td>\n <td data-head=\"S/m #\">\n <span [ngClass]=\"{\n 'text-danger fw-bold': user?.sessions_last_month < 3\n }\">{{ user?.sessions_last_month }}</span>\n </td>\n <td data-head=\"Last Login\">\n @if (user?.current_sign_in_at | isOnline) {\n <pw-online-indicator [lastSeen]=\"user.current_sign_in_at\" />\n } @else if (user?.current_sign_in_at) {\n <span>\n {{ user.current_sign_in_at | dateFormat }}\n </span>\n } @else {\n {{ user.last_sign_in_at | dateFormat }}\n }\n </td>\n <td data-head=\"Registered On\">{{ user.signed_up_at | dateFormat }}</td>\n <td data-head=\"Action\">\n <ul class=\"list-unstyled list-inline list-action\">\n <li pTooltip=\"Impersonate this user\" tooltipPosition=\"top\" appendTo=\"body\"\n *rbacAllow=\"'Pages.Alpha'\"\n class=\"me-2 me-sm-3\">\n <i\n class=\"fas fa-people-arrows fa-lg\"\n (click)=\"onImpersonate(user)\"\n (keydown.enter)=\"onImpersonate(user)\"\n aria-hidden=\"true\"\n ></i>\n </li>\n @if (user?.enable_two_factor_authenticator) {\n <li pTooltip=\"Disable 2FA\" tooltipPosition=\"top\" appendTo=\"body\"\n (click)=\"disable2fa(user?.id)\"\n (keydown.enter)=\"disable2fa(user?.id)\"\n *rbacAllow=\"'Pages.Alpha'\"\n class=\"me-2 me-sm-3\">\n <i class=\"fa fa-lock fa-lg success\" aria-hidden=\"true\"></i>\n </li>\n }\n @if (currentUser && user.id !== currentUser.id) {\n <li pTooltip=\"Message\" tooltipPosition=\"top\" appendTo=\"body\"\n *rbacAllow=\"chatPermission\"\n class=\"me-2 me-sm-3\"\n [routerLink]=\"['/message']\"\n [fragment]=\"user.slug\">\n <i class=\"fa fa-comments cta1-icon\" aria-hidden=\"true\"></i>\n </li>\n }\n <li pTooltip=\"Edit\" tooltipPosition=\"top\" appendTo=\"body\"\n *rbacAllow=\"'Pages.Admin.Users.Edit'\"\n class=\"me-2 me-sm-3\"\n [routerLink]=\"[routers.usersDetails + user.id]\">\n <i class=\"fa fa-edit edit-icon\" aria-hidden=\"true\"></i>\n </li>\n <li pTooltip=\"Delete\" tooltipPosition=\"top\" appendTo=\"body\"\n *rbacAllow=\"'Pages.Admin.Users.Delete'\"\n class=\"me-2 me-sm-3\">\n <i\n class=\"fa fa-trash delete-icon\"\n (keydown.enter)=\"onDelete(user)\"\n (keydown.space)=\"onDelete(user)\"\n (click)=\"onDelete(user)\"\n aria-hidden=\"true\"\n ></i>\n </li>\n </ul>\n </td>\n </tr>\n </ng-template>\n </p-table>\n @if (totalRecords === 0 && totalRecordsUnFiltered !== 0) {\n <div>\n <pw-no-data [withImage]=\"true\" [message]=\"'Search.NoDataMessage' | transloco\" [description]=\"'Search.NoDataDescription' | transloco\">\n </pw-no-data>\n </div>\n }\n @if (totalRecords !== 0) {\n <pw-records-summary [showing]=\"dt?.value?.length ?? 0\" [total]=\"totalRecords\" />\n }\n </div>\n</div>\n@if (!loading && totalRecordsUnFiltered === 0) {\n <div>\n <pw-no-data [withImage]=\"true\" [message]=\"'Admin.Users.NoDataMessage' | transloco\"> </pw-no-data>\n </div>\n}\n<!-- password validation modal for delete user -->\n<pw-password-validation #passwordValidationModalForUserDelete\n [destructive]=\"true\"\n (successEvent)=\"deleteUser($event)\">\n</pw-password-validation>\n<!-- password validation modal for impersonate -->\n<pw-password-validation #passwordValidationModalForImpersonate\n (successEvent)=\"onUserImpersonation($event)\">\n</pw-password-validation>\n<!-- password validation modal for remove2fa -->\n<pw-password-validation #passwordValidationModalForRemove2fa\n (successEvent)=\"remove2fa($event)\">\n</pw-password-validation>\n",
36596
+ template: "<div class=\"row\">\n <div class=\"col-12 d-flex flex-wrap justify-content-between align-items-baseline\">\n <h2 class=\"card-title p-0\">Users</h2>\n <a class=\"btn btn-sm btn-outline-primary\"\n id=\"btn-create\"\n *rbacAllow=\"'SuperAdmin'\"\n [routerLink]=\"[routers.usersDetails + 'add']\">\n <i class=\"fa fa-plus-circle\" aria-hidden=\"true\"></i> Add User\n </a>\n </div>\n</div>\n<div class=\"w-100 text-center mt-3\">\n @if (!isLoaded) {\n <p-progress-spinner> </p-progress-spinner>\n }\n</div>\n<div class=\"primeng-datatable-container actions-collapsed mt-0\" [class.hideTable]=\"totalRecordsUnFiltered === 0\">\n <div class=\"user-management-table table-responsive\">\n <p-table #dt\n stateKey=\"pw-table.admin-users-list\"\n stateStorage=\"session\"\n [resizableColumns]=\"true\"\n columnResizeMode=\"expand\"\n [value]=\"users\"\n [paginator]=\"totalRecords !== 0\"\n [lazy]=\"true\"\n [rows]=\"PAGE_SIZE\"\n [totalRecords]=\"totalRecords\"\n [loading]=\"loading\"\n [filterDelay]=\"1000\"\n (onLazyLoad)=\"onLazyLoad($event)\"\n [customSort]=\"true\">\n <ng-template #caption>\n <div class=\"search-filter\">\n <div class=\"col-sm-4\">\n <p-multiselect class=\"pw-filter-select\" inputId=\"users-list-filter-role-product\"\n [options]=\"searchOptions\"\n (onChange)=\"onSearchOptionChange($event)\"\n placeholder=\"Filter users by role, product, or feature\"\n [selectionLimit]=\"1\"\n [(ngModel)]=\"filterSource\"\n [showToggleAll]=\"true\"\n [showHeader]=\"true\"\n appendTo=\"body\">\n </p-multiselect>\n </div>\n @if (selectedOption) {\n <div class=\"col-4\"\n >\n <p-multiselect class=\"pw-filter-select\" inputId=\"users-list-filter-criteria\"\n [options]=\"searchDataSource\"\n (onChange)=\"onSearchCriteria($event)\"\n [showToggleAll]=\"true\"\n [(ngModel)]=\"criteria\"\n [showHeader]=\"true\"\n placeholder=\"Filter by {{ selectedOption.value }}s\"\n maxSelectedLabels=\"2\"\n appendTo=\"body\">\n </p-multiselect>\n </div>\n }\n <div class=\"col-auto d-flex align-items-center\">\n <span class=\"ambassadors-only-toggle\"\n [pTooltip]=\"'Admin.Users.AmbassadorsOnly' | transloco\"\n tooltipPosition=\"top\" appendTo=\"body\">\n <ui-switch\n [checked]=\"showAmbassadorsOnly\"\n (change)=\"showAmbassadorsOnly = $event; onAmbassadorsOnlyToggle()\"\n [attr.aria-label]=\"'Admin.Users.AmbassadorsOnly' | transloco\">\n </ui-switch>\n </span>\n </div>\n <div class=\"text-end\">\n <label for=\"users-list-search\" class=\"visually-hidden\">Search User</label>\n <p-iconfield iconPosition=\"left\">\n <p-inputicon><i class=\"fa fa-search\" aria-hidden=\"true\"></i></p-inputicon>\n <input type=\"text\"\n id=\"users-list-search\"\n name=\"users-list-search\"\n [(ngModel)]=\"searchText\"\n pInputText\n placeholder=\"Search users...\"\n data-cy=\"user-search\"\n (input)=\"dt.filterGlobal($event.target.value, 'contains')\"\n class=\"wd-90\"\n aria-label=\"Search users...\" />\n </p-iconfield>\n </div>\n </div>\n </ng-template>\n <ng-template #header>\n <tr>\n <th pResizableColumn scope=\"true\"\n pSortableColumn=\"id\">\n {{ 'Admin.Users.Id' | transloco }}\n <p-sort-icon field=\"id\"></p-sort-icon>\n </th>\n <th pResizableColumn scope=\"true\"\n pSortableColumn=\"first_name\">\n {{ 'Label.FirstName' | transloco }}\n <p-sort-icon field=\"first_name\"></p-sort-icon>\n </th>\n <th pResizableColumn scope=\"true\"\n pSortableColumn=\"last_name\">\n {{ 'Label.LastName' | transloco }}\n <p-sort-icon field=\"last_name\"></p-sort-icon>\n </th>\n <th pResizableColumn scope=\"true\"\n pSortableColumn=\"email\">\n {{ 'Label.Email' | transloco }}\n <p-sort-icon field=\"email\"></p-sort-icon>\n </th>\n <th pResizableColumn scope=\"true\"\n pSortableColumn=\"slug\">\n {{ 'Admin.Users.Slug' | transloco }}\n <p-sort-icon field=\"slug\"></p-sort-icon>\n </th>\n <th pResizableColumn scope=\"true\"\n pSortableColumn=\"encrypted_password\">\n {{ 'Admin.Users.EmailConfirm' | transloco }}\n <p-sort-icon field=\"encrypted_password\"></p-sort-icon>\n </th>\n\n <th pResizableColumn scope=\"true\"\n pSortableColumn=\"sessions_last_month\">\n {{ 'Admin.Subscriptions.SessionsTotalLastMonth' | transloco }}\n <p-sort-icon field=\"sessions_last_month\"></p-sort-icon>\n </th>\n <th pResizableColumn scope=\"true\"\n pSortableColumn=\"last_sign_in_at\">\n {{ 'Admin.Users.LastLogin' | transloco }}\n <p-sort-icon field=\"last_sign_in_at\"></p-sort-icon>\n </th>\n <th pResizableColumn scope=\"true\"\n pSortableColumn=\"signed_up_at\">\n {{ 'Admin.Users.RegisteredOn' | transloco }}\n <p-sort-icon field=\"signed_up_at\"></p-sort-icon>\n </th>\n <th scope=\"true\"\n class=\"actions-list-four\">\n {{ 'Label.Actions' | transloco }}\n </th>\n </tr>\n </ng-template>\n <ng-template #body\n let-user>\n <tr>\n <td data-head=\"id\"> {{ user.id }}</td>\n <td data-head=\"First Name\"><a [routerLink]=\"['/members', user.slug]\">{{ user.first_name }}</a></td>\n <td data-head=\"Last Name\">{{ user.last_name }}\n @if (user?.alpha) {\n <span\n [pTooltip]=\"'Admin.Users.Tooltip.AlphaIcon'|transloco\"\n tooltipPosition=\"top\" appendTo=\"body\">\n <i class=\"fa-regular fa-square-a alpha-beta text-warning\"></i>\n </span>\n }\n @if (user?.beta) {\n <span class=\"ms-2\"\n [pTooltip]=\"'Admin.Users.Tooltip.BetaIcon'|transloco\"\n tooltipPosition=\"top\" appendTo=\"body\">\n <i class=\"fa-regular fa-square-b alpha-beta text-primary\" ></i>\n </span>\n }\n @if (user?.cognito_sso_activated) {\n <span\n class=\"ms-2\"\n [pTooltip]=\"'Admin.Users.Tooltip.Cognito' | transloco\"\n tooltipPosition=\"top\" appendTo=\"body\">\n <i class=\"fa fa-cloud success\" ></i>\n </span>\n }\n @if (user?.ambassador_count > 0) {\n <span\n class=\"ms-2\"\n [pTooltip]=\"'Admin.Users.Tooltip.Ambassador' | transloco\"\n tooltipPosition=\"top\" appendTo=\"body\">\n <i class=\"fa fa-handshake alpha-beta text-primary\" aria-hidden=\"true\"></i>\n </span>\n }\n </td>\n <td data-head=\"Email\">{{ user.email }}</td>\n <td data-head=\"Slug\">{{ user.slug }}</td>\n <td data-head=\"Email Confirm\">\n <span [appDynamicBadge]=\"{\n itemsArray: [true, false],\n item: user?.has_password\n }\"\n color=\"success-danger\"\n class=\"badge\">{{ user?.has_password ? 'Yes' : 'No' }}</span>\n @if (user?.blocked) {\n <span class=\"ms-2\" [pTooltip]=\"'This user has been blocked'\" tooltipPosition=\"top\" appendTo=\"body\">\n <i class=\"fa-solid fa-hexagon-exclamation text-danger hexa-warning\"></i>\n </span>\n }\n </td>\n <td data-head=\"S/m #\">\n <span [ngClass]=\"{\n 'text-danger fw-bold': user?.sessions_last_month < 3\n }\">{{ user?.sessions_last_month }}</span>\n </td>\n <td data-head=\"Last Login\">\n @if (user?.current_sign_in_at | isOnline) {\n <pw-online-indicator [lastSeen]=\"user.current_sign_in_at\" />\n } @else if (user?.current_sign_in_at) {\n <span>\n {{ user.current_sign_in_at | dateFormat }}\n </span>\n } @else {\n {{ user.last_sign_in_at | dateFormat }}\n }\n </td>\n <td data-head=\"Registered On\">{{ user.signed_up_at | dateFormat }}</td>\n <td data-head=\"Action\">\n <ul class=\"list-unstyled list-inline list-action\">\n <li pTooltip=\"Impersonate this user\" tooltipPosition=\"top\" appendTo=\"body\"\n *rbacAllow=\"'Pages.Alpha'\"\n class=\"me-2 me-sm-3\">\n <i\n class=\"fas fa-people-arrows fa-lg\"\n (click)=\"onImpersonate(user)\"\n (keydown.enter)=\"onImpersonate(user)\"\n aria-hidden=\"true\"\n ></i>\n </li>\n @if (user?.enable_two_factor_authenticator) {\n <li pTooltip=\"Disable 2FA\" tooltipPosition=\"top\" appendTo=\"body\"\n (click)=\"disable2fa(user?.id)\"\n (keydown.enter)=\"disable2fa(user?.id)\"\n *rbacAllow=\"'Pages.Alpha'\"\n class=\"me-2 me-sm-3\">\n <i class=\"fa fa-lock fa-lg success\" aria-hidden=\"true\"></i>\n </li>\n }\n @if (currentUser && user.id !== currentUser.id) {\n <li pTooltip=\"Message\" tooltipPosition=\"top\" appendTo=\"body\"\n *rbacAllow=\"chatPermission\"\n class=\"me-2 me-sm-3\"\n [routerLink]=\"['/message']\"\n [fragment]=\"user.slug\">\n <i class=\"fa fa-comments cta1-icon\" aria-hidden=\"true\"></i>\n </li>\n }\n <li pTooltip=\"Edit\" tooltipPosition=\"top\" appendTo=\"body\"\n *rbacAllow=\"'Pages.Admin.Users.Edit'\"\n class=\"me-2 me-sm-3\"\n [routerLink]=\"[routers.usersDetails + user.id]\">\n <i class=\"fa fa-edit edit-icon\" aria-hidden=\"true\"></i>\n </li>\n <li pTooltip=\"Delete\" tooltipPosition=\"top\" appendTo=\"body\"\n *rbacAllow=\"'Pages.Admin.Users.Delete'\"\n class=\"me-2 me-sm-3\">\n <i\n class=\"fa fa-trash delete-icon\"\n (keydown.enter)=\"onDelete(user)\"\n (keydown.space)=\"onDelete(user)\"\n (click)=\"onDelete(user)\"\n aria-hidden=\"true\"\n ></i>\n </li>\n </ul>\n </td>\n </tr>\n </ng-template>\n </p-table>\n @if (totalRecords === 0 && totalRecordsUnFiltered !== 0) {\n <div>\n <pw-no-data [withImage]=\"true\" [message]=\"'Search.NoDataMessage' | transloco\" [description]=\"'Search.NoDataDescription' | transloco\">\n </pw-no-data>\n </div>\n }\n @if (totalRecords !== 0) {\n <pw-records-summary [showing]=\"dt?.value?.length ?? 0\" [total]=\"totalRecords\" />\n }\n </div>\n</div>\n@if (!loading && totalRecordsUnFiltered === 0) {\n <div>\n <pw-no-data [withImage]=\"true\" [message]=\"'Admin.Users.NoDataMessage' | transloco\"> </pw-no-data>\n </div>\n}\n<!-- password validation modal for delete user -->\n<pw-password-validation #passwordValidationModalForUserDelete\n [destructive]=\"true\"\n (successEvent)=\"deleteUser($event)\">\n</pw-password-validation>\n<!-- password validation modal for impersonate -->\n<pw-password-validation #passwordValidationModalForImpersonate\n (successEvent)=\"onUserImpersonation($event)\">\n</pw-password-validation>\n<!-- password validation modal for remove2fa -->\n<pw-password-validation #passwordValidationModalForRemove2fa\n (successEvent)=\"remove2fa($event)\">\n</pw-password-validation>\n",
36525
36597
  styles: ["@charset \"UTF-8\";:root{--first: rgb(23 105 225);--second: rgb(54 194 131);--third: rgb(255 171 0);--text: rgb(34 34 34);--tabs_bg: rgb(23 105 225);--tabs_sub_bg: color-mix(in srgb, var(--first, rgb(23 105 225)) 85%, #000000);--tabs_text: rgb(255 255 255);--titles: rgb(34 34 34);--sidebar_bg: rgb(0, 48, 63);--sidebar_text: rgb(255 255 255);--dashboard_bg: rgb(255 255 255);--public-btn-radius: 24px}.search-input input{width:100%}.w-150{width:150px}.table-responsive td[data-head=id]{font-variant-numeric:tabular-nums;color:#7c8696}.hexa-warning{font-size:18px;vertical-align:middle}.alpha-beta{font-size:14px}.ambassadors-only-toggle{display:inline-flex;align-items:center}.ambassadors-only-toggle ::ng-deep .switch small{display:flex;align-items:center;justify-content:center}.ambassadors-only-toggle ::ng-deep .switch small:after{content:\"\\f2b5\";font-family:\"Font Awesome 6 Pro\",sans-serif;font-weight:900;font-size:12px;line-height:1;color:var(--first)}\n"]
36526
36598
  }]
36527
36599
  }],