ngx-techlify-core 18.76.0 → 18.77.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -12,9 +12,10 @@ import { MatIconModule, MatIcon } from '@angular/material/icon';
12
12
  import { debounceTime, finalize as finalize$1, catchError, switchMap, map as map$1, distinctUntilChanged, startWith } from 'rxjs/operators';
13
13
  import * as i1$6 from '@angular/platform-browser';
14
14
  import { Title } from '@angular/platform-browser';
15
- import moment from 'moment';
16
15
  import * as i1$2 from '@angular/router';
17
16
  import { RouteReuseStrategy, RouterModule, RouterLink } from '@angular/router';
17
+ import * as i3 from '@angular/common';
18
+ import { DatePipe, CommonModule, NgIf, NgTemplateOutlet, NgOptimizedImage, CurrencyPipe } from '@angular/common';
18
19
  import { fakeAsync, tick } from '@angular/core/testing';
19
20
  import { __decorate } from 'tslib';
20
21
  import * as i11 from '@angular/material/sort';
@@ -22,8 +23,6 @@ import { MatSort, MatSortModule } from '@angular/material/sort';
22
23
  import { untilDestroyed, UntilDestroy } from '@ngneat/until-destroy';
23
24
  import * as i6$1 from '@angular/flex-layout/flex';
24
25
  import * as i2 from '@angular/flex-layout/extended';
25
- import * as i3 from '@angular/common';
26
- import { DatePipe, CommonModule, NgIf, NgTemplateOutlet, NgOptimizedImage, CurrencyPipe } from '@angular/common';
27
26
  import * as i6$2 from 'ngx-infinite-scroll';
28
27
  import { InfiniteScrollModule, InfiniteScrollDirective } from 'ngx-infinite-scroll';
29
28
  import * as i8$1 from '@angular/material/checkbox';
@@ -63,7 +62,7 @@ import * as i11$2 from '@angular/material/progress-bar';
63
62
  import { MatProgressBarModule, MatProgressBar } from '@angular/material/progress-bar';
64
63
  import * as i11$3 from '@angular/material/progress-spinner';
65
64
  import { MatProgressSpinnerModule } from '@angular/material/progress-spinner';
66
- import * as i9$2 from '@angular/material/select';
65
+ import * as i9$1 from '@angular/material/select';
67
66
  import { MatSelectModule } from '@angular/material/select';
68
67
  import * as i6$3 from '@angular/material/divider';
69
68
  import { MatDividerModule } from '@angular/material/divider';
@@ -76,7 +75,8 @@ import * as i8$5 from '@angular/material/slide-toggle';
76
75
  import { MatSlideToggleModule } from '@angular/material/slide-toggle';
77
76
  import * as i9$3 from '@angular/material/tabs';
78
77
  import { MatTabsModule } from '@angular/material/tabs';
79
- import * as i9$1 from '@angular/cdk/scrolling';
78
+ import moment from 'moment';
79
+ import * as i9$2 from '@angular/cdk/scrolling';
80
80
  import { FlexLayoutModule, FlexModule } from '@angular/flex-layout';
81
81
  import * as i14 from 'ngx-editor';
82
82
  import { Editor, NgxEditorModule } from 'ngx-editor';
@@ -615,9 +615,10 @@ function parseLocalDate(dateStr) {
615
615
 
616
616
  /* tslint:disable:radix */
617
617
  class RequestHelperService {
618
- constructor(router, activatedRoute) {
618
+ constructor(router, activatedRoute, datePipe) {
619
619
  this.router = router;
620
620
  this.activatedRoute = activatedRoute;
621
+ this.datePipe = datePipe;
621
622
  }
622
623
  /**
623
624
  * Update the form values from the URL query params.
@@ -636,10 +637,9 @@ class RequestHelperService {
636
637
  /**
637
638
  * Convert the object to form data for the request.
638
639
  * @param data Data Object
639
- * @param config Optional
640
640
  * @return Object
641
641
  */
642
- convertToFormData(data, config) {
642
+ convertToFormData(data) {
643
643
  const newData = {};
644
644
  for (const prop in data) {
645
645
  if (Object.prototype.hasOwnProperty.call(data, prop)) {
@@ -648,10 +648,10 @@ class RequestHelperService {
648
648
  newData[prop] = data[prop].join(',');
649
649
  }
650
650
  else if (this.isDateString(data[prop])) {
651
- newData[prop] = moment(data[prop]).format('Y-MM-DD');
651
+ newData[prop] = this.datePipe.transform(data[prop], 'yyyy-MM-dd');
652
652
  }
653
653
  else {
654
- newData[prop] = data[prop];
654
+ newData[prop] = data[prop] ?? ''; //Don't pass null into request, it will break the filters
655
655
  }
656
656
  }
657
657
  }
@@ -719,7 +719,7 @@ class RequestHelperService {
719
719
  }
720
720
  return /^\d{4}[-/](0[1-9]|1[0-2])[-/](0[1-9]|[12]\d|3[01])([T\s].*)?$/.test(value);
721
721
  }
722
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: RequestHelperService, deps: [{ token: i1$2.Router }, { token: i1$2.ActivatedRoute }], target: i0.ɵɵFactoryTarget.Injectable }); }
722
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: RequestHelperService, deps: [{ token: i1$2.Router }, { token: i1$2.ActivatedRoute }, { token: i3.DatePipe }], target: i0.ɵɵFactoryTarget.Injectable }); }
723
723
  static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: RequestHelperService, providedIn: 'root' }); }
724
724
  }
725
725
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: RequestHelperService, decorators: [{
@@ -727,7 +727,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
727
727
  args: [{
728
728
  providedIn: 'root'
729
729
  }]
730
- }], ctorParameters: () => [{ type: i1$2.Router }, { type: i1$2.ActivatedRoute }] });
730
+ }], ctorParameters: () => [{ type: i1$2.Router }, { type: i1$2.ActivatedRoute }, { type: i3.DatePipe }] });
731
731
 
732
732
  /**
733
733
  * Interface used to ensure we have a consistent structure across our listing pages
@@ -804,7 +804,7 @@ class TechlifyListComponent {
804
804
  .subscribe((_) => {
805
805
  if (this.isFilterPatchFromRoute) {
806
806
  const unformatedFilters = JSON.parse(JSON.stringify(this.filterForm.value));
807
- this.filters = this.requestHelperService?.convertToFormData(unformatedFilters, this.filterFormConfiguration);
807
+ this.filters = this.requestHelperService?.convertToFormData(unformatedFilters);
808
808
  this.requestHelperService?.updateQueryParams(this.filters);
809
809
  }
810
810
  this.reload();
@@ -830,7 +830,7 @@ class TechlifyListComponent {
830
830
  * Convert to form data gives flexibility to convert the form array values to string
831
831
  * No need to override the loadData method in child class to convert array values to string.
832
832
  * */
833
- filters = this.requestHelperService?.convertToFormData(JSON.parse(JSON.stringify(this.filterForm.value)), this.filterFormConfiguration);
833
+ filters = this.requestHelperService?.convertToFormData(JSON.parse(JSON.stringify(this.filterForm.value)));
834
834
  filters.page = this.page;
835
835
  filters.per_page = this.perPage;
836
836
  }
@@ -990,7 +990,7 @@ class TechlifyListComponent {
990
990
  if (view) {
991
991
  //If there is a view, then set it.
992
992
  //Setup view filters
993
- this.filterForm.setValue(this.requestHelperService?.convertToFormData(view?.filters, this.filterFormConfiguration));
993
+ this.filterForm.patchValue(this.requestHelperService?.convertToFormData(view?.filters));
994
994
  //Setup view columns
995
995
  this.columnConfigs.forEach(column => {
996
996
  column.isSelected = (view?.columns).some(col => col === column.def);
@@ -3474,1249 +3474,993 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
3474
3474
  ], template: "<app-techlify-icon role='button' name='delete' (click)=\"open()\"></app-techlify-icon>" }]
3475
3475
  }], ctorParameters: () => [{ type: i1.MatDialog }, { type: AlertService }, { type: ErrorHandlerService }] });
3476
3476
 
3477
- class TechlifyFormButtonComponent {
3478
- constructor(matDialog) {
3479
- this.matDialog = matDialog;
3480
- this.component = input.required();
3481
- this.model = input();
3482
- this.data = input({});
3483
- this.width = input('700px');
3484
- this.saved = output();
3485
- }
3486
- open() {
3487
- const ref = this.matDialog.open(this.component(), {
3488
- width: this.width(),
3489
- data: { model: this.model(), ...this.data() }
3490
- });
3491
- ref.afterClosed().subscribe((result) => {
3492
- if (result) {
3493
- this.saved.emit(result);
3494
- }
3495
- });
3496
- }
3497
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: TechlifyFormButtonComponent, deps: [{ token: i1.MatDialog }], target: i0.ɵɵFactoryTarget.Component }); }
3498
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "18.2.14", type: TechlifyFormButtonComponent, isStandalone: true, selector: "app-techlify-form-button", inputs: { component: { classPropertyName: "component", publicName: "component", isSignal: true, isRequired: true, transformFunction: null }, model: { classPropertyName: "model", publicName: "model", isSignal: true, isRequired: false, transformFunction: null }, data: { classPropertyName: "data", publicName: "data", isSignal: true, isRequired: false, transformFunction: null }, width: { classPropertyName: "width", publicName: "width", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { saved: "saved" }, ngImport: i0, template: "<app-techlify-icon role=\"button\" [name]=\"model() ? 'edit' : 'add'\" (click)=\"open()\"></app-techlify-icon>\r\n", dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: MaterialModule }, { kind: "ngmodule", type: TechlifyIconModule }, { kind: "component", type: TechlifyIconComponent, selector: "app-techlify-icon", inputs: ["name", "size"] }] }); }
3477
+ class Timeline {
3478
+ static { this.CUSTOM = 1; }
3479
+ static { this.TODAY = 2; }
3480
+ static { this.YESTERDAY = 3; }
3481
+ static { this.THIS_WEEK = 4; }
3482
+ static { this.LAST_WEEK = 5; }
3483
+ static { this.THIS_MONTH = 6; }
3484
+ static { this.LAST_MONTH = 7; }
3485
+ static { this.THIS_QUARTER = 8; }
3486
+ static { this.LAST_QUARTER = 9; }
3487
+ static { this.THIS_YEAR = 10; }
3488
+ static { this.LAST_YEAR = 11; }
3489
+ static { this.ALL = 12; }
3490
+ static { this.TOMMOROW = 13; }
3491
+ static { this.NEXT_WEEK = 14; }
3492
+ static { this.NEXT_MONTH = 15; }
3499
3493
  }
3500
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: TechlifyFormButtonComponent, decorators: [{
3501
- type: Component,
3502
- args: [{ selector: 'app-techlify-form-button', standalone: true, imports: [
3503
- CommonModule,
3504
- MaterialModule,
3505
- TechlifyIconModule
3506
- ], template: "<app-techlify-icon role=\"button\" [name]=\"model() ? 'edit' : 'add'\" (click)=\"open()\"></app-techlify-icon>\r\n" }]
3507
- }], ctorParameters: () => [{ type: i1.MatDialog }] });
3508
3494
 
3509
- class ReadMoreComponent {
3510
- constructor() {
3511
- this.maxLength = 100;
3512
- this.hideToggle = true;
3513
- this.isCollapsed = true;
3514
- }
3515
- ngOnInit() {
3516
- this.determineView();
3517
- }
3518
- toggleView() {
3519
- this.isCollapsed = !this.isCollapsed;
3520
- this.determineView();
3521
- }
3522
- determineView() {
3523
- if (!this.text || this.text.length <= this.maxLength) {
3524
- this.currentText = this.text;
3525
- this.isCollapsed = false;
3526
- this.hideToggle = true;
3527
- return;
3495
+ function calculateTimeline(value, dateFrom, dateTo) {
3496
+ const date = new Date();
3497
+ const data = {
3498
+ date_from: date,
3499
+ date_to: date,
3500
+ show_custom_field: false
3501
+ };
3502
+ switch (value) {
3503
+ case Timeline.CUSTOM: { // Custom
3504
+ data.show_custom_field = true;
3505
+ data.date_from = dateFrom ? moment(dateFrom).toISOString() : '';
3506
+ data.date_to = dateTo ? moment(dateTo).toISOString() : '';
3507
+ break;
3528
3508
  }
3529
- this.hideToggle = false;
3530
- if (this.isCollapsed == true) {
3531
- this.currentText = this.text.substring(0, this.maxLength) + "...";
3509
+ case Timeline.TODAY: { // Today
3510
+ const now = moment();
3511
+ data.date_from = now.startOf('day').toISOString();
3512
+ data.date_to = now.endOf('day').toISOString();
3513
+ break;
3532
3514
  }
3533
- else if (this.isCollapsed == false) {
3534
- this.currentText = this.text;
3515
+ case Timeline.YESTERDAY: { // Yesterday
3516
+ const now = moment().subtract(1, 'day');
3517
+ data.date_from = now.startOf('day').toISOString();
3518
+ data.date_to = now.endOf('day').toISOString();
3519
+ break;
3535
3520
  }
3536
- }
3537
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ReadMoreComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
3538
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.14", type: ReadMoreComponent, selector: "app-read-more", inputs: { text: "text", maxLength: "maxLength" }, ngImport: i0, template: "<div [innerHTML]=\"currentText\"></div>\n<a href=\"javascript:;\" *ngIf=\"!hideToggle\" class=\"primary-color hoverable\" (click)=\"toggleView()\">Read\n {{ isCollapsed ? \"more\" : \"less\" }}</a>", styles: ["div.collapsed{height:250px;overflow:hidden}.primary-color{color:#009fdd!important}\n"], dependencies: [{ kind: "directive", type: i3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }] }); }
3539
- }
3540
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ReadMoreComponent, decorators: [{
3541
- type: Component,
3542
- args: [{ selector: "app-read-more", template: "<div [innerHTML]=\"currentText\"></div>\n<a href=\"javascript:;\" *ngIf=\"!hideToggle\" class=\"primary-color hoverable\" (click)=\"toggleView()\">Read\n {{ isCollapsed ? \"more\" : \"less\" }}</a>", styles: ["div.collapsed{height:250px;overflow:hidden}.primary-color{color:#009fdd!important}\n"] }]
3543
- }], ctorParameters: () => [], propDecorators: { text: [{
3544
- type: Input
3545
- }], maxLength: [{
3546
- type: Input
3547
- }] } });
3548
-
3549
- class WrapPipe {
3550
- transform(value, length = 50) {
3551
- if (!value) {
3552
- return '';
3521
+ case Timeline.THIS_WEEK: { // This Week
3522
+ const now = moment();
3523
+ data.date_from = now.startOf('isoWeek').toISOString();
3524
+ data.date_to = now.endOf('isoWeek').toISOString();
3525
+ break;
3553
3526
  }
3554
- return value.length > length ? value.substring(0, length) + '...' : value;
3555
- }
3556
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: WrapPipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe }); }
3557
- static { this.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "18.2.14", ngImport: i0, type: WrapPipe, isStandalone: true, name: "wrap" }); }
3558
- }
3559
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: WrapPipe, decorators: [{
3560
- type: Pipe,
3561
- args: [{
3562
- name: 'wrap',
3563
- standalone: true
3564
- }]
3565
- }] });
3566
-
3567
- class FileSizePipe {
3568
- transform(bytes) {
3569
- if (!bytes) {
3570
- return '0.00 B';
3527
+ case Timeline.LAST_WEEK: { // Last Week
3528
+ const now = moment().subtract(1, 'week');
3529
+ data.date_from = now.startOf('isoWeek').toISOString();
3530
+ data.date_to = now.endOf('isoWeek').toISOString();
3531
+ break;
3532
+ }
3533
+ case Timeline.THIS_MONTH: { // This Month
3534
+ const now = moment();
3535
+ data.date_from = now.startOf('month').toISOString();
3536
+ data.date_to = now.endOf('month').toISOString();
3537
+ break;
3538
+ }
3539
+ case Timeline.LAST_MONTH: { // Last Month
3540
+ const now = moment().subtract(1, 'month');
3541
+ data.date_from = now.startOf('month').toISOString();
3542
+ data.date_to = now.endOf('month').toISOString();
3543
+ break;
3544
+ }
3545
+ case Timeline.THIS_QUARTER: { // This Quarter
3546
+ const now = moment();
3547
+ data.date_from = now.startOf('quarter').toISOString();
3548
+ data.date_to = now.endOf('quarter').toISOString();
3549
+ break;
3550
+ }
3551
+ case Timeline.LAST_QUARTER: { // Last Quarter
3552
+ const now = moment().subtract(1, 'quarter');
3553
+ data.date_from = now.startOf('quarter').toISOString();
3554
+ data.date_to = now.endOf('quarter').toISOString();
3555
+ break;
3556
+ }
3557
+ case Timeline.THIS_YEAR: { // This Year
3558
+ const now = moment();
3559
+ data.date_from = now.startOf('year').toISOString();
3560
+ data.date_to = now.endOf('year').toISOString();
3561
+ break;
3562
+ }
3563
+ case Timeline.LAST_YEAR: { // Last Year
3564
+ const now = moment().subtract(1, 'year');
3565
+ data.date_from = now.startOf('year').toISOString();
3566
+ data.date_to = now.endOf('year').toISOString();
3567
+ break;
3568
+ }
3569
+ case Timeline.TOMMOROW: {
3570
+ const now = moment().add(1, 'day');
3571
+ data.date_from = now.startOf('day').toISOString();
3572
+ data.date_to = now.endOf('day').toISOString();
3573
+ break;
3574
+ }
3575
+ case Timeline.NEXT_WEEK: {
3576
+ const now = moment().add(1, 'week');
3577
+ data.date_from = now.startOf('isoWeek').toISOString();
3578
+ data.date_to = now.endOf('isoWeek').toISOString();
3579
+ break;
3580
+ }
3581
+ case Timeline.NEXT_MONTH: {
3582
+ const now = moment().add(1, 'month');
3583
+ data.date_from = now.startOf('month').toISOString();
3584
+ data.date_to = now.endOf('month').toISOString();
3585
+ break;
3586
+ }
3587
+ default: { // All
3588
+ data.date_from = '';
3589
+ data.date_to = '';
3590
+ break;
3571
3591
  }
3572
- const exponent = Math.floor(Math.log(bytes) / Math.log(1024));
3573
- return (bytes / Math.pow(1024, exponent)).toFixed(2) + ' ' + ' KMGTP'.charAt(exponent) + 'B';
3574
3592
  }
3575
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: FileSizePipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe }); }
3576
- static { this.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "18.2.14", ngImport: i0, type: FileSizePipe, isStandalone: true, name: "fileSize" }); }
3593
+ return data;
3577
3594
  }
3578
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: FileSizePipe, decorators: [{
3579
- type: Pipe,
3580
- args: [{
3581
- name: 'fileSize',
3582
- standalone: true
3583
- }]
3584
- }] });
3585
3595
 
3586
- /**
3587
- * We are using both app-entity-file-list and app-entity-files-view-all
3588
- * to ensure backward compatibility with older projects `ngx-techlify-documents, ngx-techlify-checksheets`
3589
- * etc. `app-entity-files-view-all` will be removed by `v18.80.0`
3590
- */
3591
- class EntityFileListComponent extends TechlifyListComponent {
3592
- set isFilterPatchFromRoute(value) {
3593
- this._isFilterPatchFromRoute = value;
3596
+ var TimelineFilterComponent_1;
3597
+ let TimelineFilterComponent = class TimelineFilterComponent {
3598
+ static { TimelineFilterComponent_1 = this; }
3599
+ set defaultValue(value) {
3600
+ this.value = value;
3594
3601
  }
3595
- get isFilterPatchFromRoute() {
3596
- return this._isFilterPatchFromRoute;
3602
+ get empty() {
3603
+ const { value: { select_value } } = this.selectorForm;
3604
+ return !select_value;
3597
3605
  }
3598
- constructor(service, alertService, fb, errorHandler, permissionsService) {
3599
- super(service);
3600
- this.service = service;
3601
- this.alertService = alertService;
3602
- this.fb = fb;
3603
- this.errorHandler = errorHandler;
3604
- this.permissionsService = permissionsService;
3605
- this.viewOnly = false;
3606
- this.allowMultipleFiles = false;
3607
- this.allowBulkUpdate = false;
3608
- this.viewMode = 'list';
3609
- this.fileDropperHeight = '500px';
3610
- this.isShowDragDropSection = true;
3611
- /**
3612
- * Should we allow tagging entity-files?
3613
- */
3614
- this.useTechlifyTags = false;
3615
- this.techlifyTagCategories = [];
3616
- this.techlifyTagConfig = new TechlifyTaggerTagFormConfigModel();
3617
- this.entityFileForm = signal(EntityFileFormComponent);
3618
- this.formData = {};
3619
- this.title = "File";
3620
- this.displayedColumns = [
3621
- 'index',
3622
- 'title',
3623
- 'details',
3624
- 'file_size',
3625
- 'uploaded_on',
3626
- ];
3627
- this.isShowCreateAction = true;
3628
- this.isShowUpdateAction = true;
3629
- this.isShowDeleteAction = true;
3630
- this.isShowReadAction = true;
3631
- this.filterFormConfiguration = {
3632
- tag_ids: { multiple: true }
3633
- };
3634
- this.filterForm = this.fb.group({
3635
- title: [""],
3636
- tag_ids: [[]]
3637
- });
3638
- this.updateRowForm = this.fb.group({
3639
- title: [''],
3640
- details: [''],
3641
- tag_ids: [''],
3642
- });
3643
- }
3644
- async ngOnInit() {
3645
- /**
3646
- * The reason we are setting permissions this way is because the user can pass what permissions are to be used
3647
- * when manipulating the files/documents. If they are a client admin we will skip this
3648
- */
3649
- if (!await this.permissionsService.hasPermission('client_admin')) {
3650
- this.isShowCreateAction = this.permission?.create ? await this.permissionsService.hasPermission(this.permission.create) : true;
3651
- this.isShowUpdateAction = this.permission?.update ? await this.permissionsService.hasPermission(this.permission.update) : true;
3652
- this.isShowReadAction = this.permission?.read ? await this.permissionsService.hasPermission(this.permission.read) : true;
3653
- this.isShowDeleteAction = this.permission?.delete ? await this.permissionsService.hasPermission(this.permission.delete) : true;
3654
- }
3655
- this.formData = {
3656
- entity: {
3657
- entity_type: this.entityType,
3658
- entity_id: this.entityId
3659
- },
3660
- hideTitleAndDetails: this.hideTitleAndDetails,
3661
- useTechlifyTags: this.useTechlifyTags,
3662
- techlifyTagCategories: this.techlifyTagCategories,
3663
- techlifyTagConfig: this.techlifyTagConfig,
3664
- };
3665
- // File dropper config
3666
- this.fileConfig = {
3667
- fileId: "entityDashboardDropper",
3668
- containerId: "entityDashboardDropperContainer",
3669
- styles: {
3670
- height: this.fileDropperHeight
3671
- },
3672
- multiple: this.allowMultipleFiles,
3673
- acceptFile: "*",
3674
- maxSize: 10,
3675
- acceptFileText: "All Files"
3676
- };
3677
- this.viewerConfig = {
3678
- imageStyle: {
3679
- height: '200px',
3680
- width: '200px'
3681
- },
3682
- viewerStyle: {
3683
- height: ' 160px',
3684
- width: '200px'
3685
- },
3686
- hideRemove: true
3687
- };
3688
- if (this.hideTitleAndDetails) {
3689
- this.displayedColumns = this.displayedColumns.filter(x => (x !== 'details') && (x !== 'title'));
3690
- }
3691
- if (!this.viewOnly) {
3692
- this.displayedColumns.push('actions');
3693
- }
3694
- if (this.allowBulkUpdate) {
3695
- this.displayedColumns.push('select');
3696
- }
3697
- if (this.isFilterPatchFromRoute) {
3698
- this.patchFiltersFromRoute();
3699
- }
3700
- this.listenFilterChanges();
3701
- this.loadData();
3606
+ get shouldLabelFloat() { return this.focused || !this.empty; }
3607
+ get required() { return this._required; }
3608
+ set required(value) {
3609
+ this.selectorForm?.get('select_value')?.setValidators(Validators.required);
3610
+ this._required = coerceBooleanProperty(value);
3611
+ this.stateChanges.next();
3702
3612
  }
3703
- loadData() {
3704
- this.filters = {
3705
- ...this.requestHelperService?.convertToFormData(JSON.parse(JSON.stringify(this.filterForm.value)), this.filterFormConfiguration),
3706
- entity_type: this.entityType,
3707
- entity_id: this.entityId,
3708
- with: 'creator,tags',
3709
- page: this.page,
3710
- per_page: this.perPage
3711
- };
3712
- super.loadData(this.filters);
3613
+ get disabled() { return this._disabled; }
3614
+ set disabled(value) {
3615
+ this._disabled = coerceBooleanProperty(value);
3616
+ this._disabled
3617
+ ? this.selectorForm.disable({ emitEvent: false })
3618
+ : this.selectorForm.enable({ emitEvent: false });
3619
+ this.stateChanges.next();
3713
3620
  }
3714
- async fileChanged(event) {
3715
- const files = event;
3716
- if (files.length > 0) {
3717
- for (const file of files) {
3718
- await this.service.uploadEntityFile(file, {
3719
- entity_type: this.entityType,
3720
- entity_id: this.entityId,
3721
- });
3722
- }
3723
- this.reload();
3724
- this.alertService.addAlert('Files uploaded successfully!', 'success');
3621
+ get value() {
3622
+ if (this.selectorForm.valid) {
3623
+ return this.selectorForm.value.select_value;
3725
3624
  }
3625
+ return '';
3726
3626
  }
3727
- async bulkUpdate(fieldName) {
3728
- const data = this.updateRowForm.value;
3729
- this.isWorking = true;
3730
- data.field_name = fieldName;
3731
- data.document_ids = this.selectedModelIds;
3732
- try {
3733
- await this.service.bulkUpdate(data).then(() => {
3734
- this.alertService.addAlert("Successfully updated", "success");
3735
- this.isWorking = false;
3736
- this.reload();
3737
- });
3627
+ set value(data) {
3628
+ this.selectorForm.patchValue({ select_value: parseInt(data) || '' }, { emitEvent: false });
3629
+ this.stateChanges.next();
3630
+ //If the selection is custom, validate if date is selected
3631
+ if (this.value == Timeline.CUSTOM) {
3632
+ if (this.isInitialised) {
3633
+ //If initialised already, open the calendar
3634
+ this.openCalendar();
3635
+ }
3636
+ else {
3637
+ //Apply default ranges from form if exist
3638
+ this.applyRange((this.getFieldValue(this.dateFrom) ?? null), (this.getFieldValue(this.dateTo) ?? null));
3639
+ }
3738
3640
  }
3739
- catch (error) {
3740
- this.errorHandler.handleError(error);
3741
- this.isWorking = false;
3641
+ else {
3642
+ this.changeTimeline(parseInt(data) || '');
3742
3643
  }
3644
+ this.isInitialised = true;
3743
3645
  }
3744
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: EntityFileListComponent, deps: [{ token: EntityFileService }, { token: AlertService }, { token: i1$5.UntypedFormBuilder }, { token: ErrorHandlerService }, { token: i5$1.NgxPermissionsService }], target: i0.ɵɵFactoryTarget.Component }); }
3745
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.14", type: EntityFileListComponent, selector: "app-entity-file-list, app-entity-files-view-all", inputs: { entityId: "entityId", entityType: "entityType", viewOnly: "viewOnly", removeSearch: "removeSearch", hideTitleAndDetails: "hideTitleAndDetails", displayMode: "displayMode", allowMultipleFiles: "allowMultipleFiles", allowBulkUpdate: "allowBulkUpdate", viewMode: "viewMode", fileDropperHeight: "fileDropperHeight", isShowDragDropSection: "isShowDragDropSection", isFilterPatchFromRoute: "isFilterPatchFromRoute", useTechlifyTags: "useTechlifyTags", techlifyTagCategories: "techlifyTagCategories", techlifyTagConfig: "techlifyTagConfig", title: "title", permission: "permission" }, usesInheritance: true, ngImport: i0, template: "<div *ngIf=\"viewMode === 'list'\">\n <div *ngIf=\"this.selectedModelIds.length\" class=\"d-none d-md-flex flex-column\">\n <mat-card class=\"update_card\" *ngIf=\"this.selectedModelIds.length\">\n <mat-card-header>\n <mat-card-title>\n <div mat-dialog-title class=\"mt-2 ml-2 text-center\">\n <div>Update Selected Rows</div>\n </div>\n </mat-card-title>\n </mat-card-header>\n <mat-card-content class=\"d-flex flex-column\">\n <form [formGroup]=\"updateRowForm\">\n <div class=\"d-flex flex-column\">\n\n <mat-form-field class=\"w-100 px-1\">\n <input matInput formControlName=\"title\" placeholder=\"Title\" autocomplete=\"off\" />\n <button *ngIf=\"updateRowForm.get('title').value || updateRowForm.get('title').value===0\" matSuffix\n mat-icon-button style=\"color:red\" (click)=\"updateRowForm.get('title').setValue('')\">\n <mat-icon>close</mat-icon>\n </button>\n <button matSuffix mat-icon-button type=\"button\" style=\"color:green\" *ngIf=\"(updateRowForm.get('title').value || updateRowForm.get('title').value===0)\n && updateRowForm.get('title').valid\" (click)=\"bulkUpdate('title')\">\n <mat-icon>done</mat-icon>\n </button>\n </mat-form-field>\n\n <mat-form-field class=\"w-100 px-1\">\n <textarea matInput formControlName=\"details\" placeholder=\"Details\" autocomplete=\"off\"></textarea>\n <button *ngIf=\"updateRowForm.get('details').value || updateRowForm.get('details').value===0\" matSuffix\n mat-icon-button style=\"color:red\" (click)=\"updateRowForm.get('details').setValue('')\">\n <mat-icon>close</mat-icon>\n </button>\n <button matSuffix mat-icon-button type=\"button\" style=\"color:green\" *ngIf=\"(updateRowForm.get('details').value || updateRowForm.get('details').value===0)\n && updateRowForm.get('details').valid\" (click)=\"bulkUpdate('details')\">\n <mat-icon>done</mat-icon>\n </button>\n </mat-form-field>\n\n <ng-container *ngIf=\"useTechlifyTags\">\n <mat-form-field>\n <mat-label>Tag</mat-label>\n <app-techlify-tagger-tag-form-field modelType=\"entity-file\" formControlName=\"tag_ids\"\n placeholder=\"Enter new tag\">\n </app-techlify-tagger-tag-form-field>\n <button *ngIf=\"updateRowForm.get('tag_ids').value || updateRowForm.get('tag_ids').value===0\" matSuffix\n mat-icon-button style=\"color:red\" (click)=\"updateRowForm.get('tag_ids').setValue('')\">\n <mat-icon>close</mat-icon>\n </button>\n <button matSuffix mat-icon-button type=\"button\" style=\"color:green\" *ngIf=\"(updateRowForm.get('tag_ids').value || updateRowForm.get('tag_ids').value===0)\n && updateRowForm.get('tag_ids').valid\" (click)=\"bulkUpdate('tag_ids')\">\n <mat-icon>done</mat-icon>\n </button>\n </mat-form-field>\n </ng-container>\n </div>\n </form>\n </mat-card-content>\n </mat-card>\n\n </div>\n\n <div>\n <div class=\"mat-typography\" *ngIf=\"!displayMode\">\n <div class=\"d-flex flex-row gap-3\">\n <div class=\"d-flex flex-column gap-2 flex-grow-1\">\n <mat-card>\n <mat-card-content>\n <div class=\"d-flex gap-2 align-items-center\">\n <mat-icon>\n description\n </mat-icon>\n <h3 class=\"font-weight-bold mb-0\">\n {{title}}s\n </h3>\n <app-techlify-form-button class=\"ms-2\" *ngIf=\"!viewOnly && isShowCreateAction && entityId\"\n [component]=\"entityFileForm()\" [data]=\"formData\"\n (saved)=\"modelCreated($event)\"></app-techlify-form-button>\n <span class=\"flex-grow-1\"></span>\n <form [formGroup]=\"filterForm\" class=\"d-flex gap-2\">\n <mat-form-field *ngIf=\"!removeSearch\" appearance=\"outline\">\n <mat-label>Search</mat-label>\n <input type=\"text\" matInput formControlName=\"title\" placeholder=\"Search\" name=\"title\"\n autocomplete=\"off\" />\n <button *ngIf=\"filterForm.get('title').value\" matSuffix mat-icon-button\n (click)=\"resetFilter('title')\">\n <mat-icon>close</mat-icon>\n </button>\n </mat-form-field>\n\n <ng-container *ngIf=\"useTechlifyTags\">\n <mat-form-field>\n <mat-label>Tag</mat-label>\n <app-techlify-tagger-tag-form-field [categories]=\"techlifyTagCategories\" formControlName=\"tag_ids\"\n placeholder=\"Select Tags\" [config]=\"techlifyTagConfig\"></app-techlify-tagger-tag-form-field>\n </mat-form-field>\n </ng-container>\n\n </form>\n </div>\n </mat-card-content>\n <mat-card-content class=\"entity-file-card p-0\" *ngIf=\"entityId\">\n <ng-container *ngTemplateOutlet=\"tableView\"></ng-container>\n </mat-card-content>\n </mat-card>\n\n <mat-card *ngIf=\"!entityId\">\n <mat-card-content class=\"entity-file-card p-0\">\n <ng-container *ngTemplateOutlet=\"tableView\"></ng-container>\n </mat-card-content>\n </mat-card>\n </div>\n <ng-container *ngIf=\"isShowDragDropSection && entityId\">\n <section style=\"flex: 0 1 30%;\" *ngIf=\"!this.selectedModelIds.length && !viewOnly && isShowCreateAction\">\n <app-file-dropper [config]=\"fileConfig\" (fileChanged)=\"fileChanged($event)\">\n </app-file-dropper>\n </section>\n </ng-container>\n </div>\n </div>\n </div>\n\n <ng-template #tableView>\n <table mat-table [dataSource]=\"models\" class=\"w-100\" matSort multiTemplateDataRows infiniteScroll\n [infiniteScrollDistance]=\"1.5\" [infiniteScrollThrottle]=\"50\" (scrolled)=\"onScroll()\">\n\n <!-- Select Column -->\n <ng-container matColumnDef=\"select\">\n <th mat-header-cell *matHeaderCellDef style=\"width:30px\">\n <mat-checkbox name=\"employee\" [(ngModel)]=\"isAllSelected\" (change)=\"selectAll()\">\n </mat-checkbox>\n </th>\n <td mat-cell *matCellDef=\"let element\" style=\"width:30px\">\n <mat-checkbox name=\"employee[{{element?.id}}]\" (click)=\"$event.stopPropagation()\"\n [(ngModel)]=\"element.is_selected\" (change)=\"isSelectionModified($event, element)\"\n [disabled]=\"!models.length\">\n </mat-checkbox>\n </td>\n </ng-container>\n\n <!-- Index Column -->\n <ng-container matColumnDef=\"index\">\n <th mat-header-cell *matHeaderCellDef> # </th>\n <td mat-cell *matCellDef=\"let element; let i = dataIndex\"> {{ i+1 }} </td>\n </ng-container>\n\n <!-- Title Column -->\n <ng-container matColumnDef=\"title\">\n <th mat-header-cell *matHeaderCellDef> Title </th>\n <td mat-cell *matCellDef=\"let element\">\n {{element.title}}\n <ng-container *ngIf=\"useTechlifyTags\">\n <br>\n <small class=\"badge badge-secondary mr-1\" *ngFor=\"let tag of element?.tags\">{{tag?.title}}</small>\n </ng-container>\n\n </td>\n </ng-container>\n\n <!-- Details Column -->\n <ng-container matColumnDef=\"details\">\n <th mat-header-cell *matHeaderCellDef> Details </th>\n <td mat-cell *matCellDef=\"let element\">\n <app-read-more [text]=\"element.details\" [maxLength]=\"50\"></app-read-more>\n </td>\n </ng-container>\n\n <!-- File size Column -->\n <ng-container matColumnDef=\"file_size\">\n <th mat-header-cell *matHeaderCellDef> File Size </th>\n <td mat-cell *matCellDef=\"let element\"> {{ element.file_size | fileSize }} </td>\n </ng-container>\n\n <!-- Uploaded On Column -->\n <ng-container matColumnDef=\"uploaded_on\">\n <th mat-header-cell *matHeaderCellDef> Uploaded On </th>\n <td mat-cell *matCellDef=\"let element\">\n <div>\n {{element.created_at | date: 'mediumDate'}}\n </div>\n <div class=\"text-muted\">\n By {{element.creator?.name}}\n </div>\n </td>\n </ng-container>\n\n <!-- Actions Column -->\n <ng-container matColumnDef=\"actions\">\n <th mat-header-cell *matHeaderCellDef> Actions </th>\n <td mat-cell *matCellDef=\"let element\" class=\"text-muted\">\n <div class=\"d-flex flex-row gap-2 text-secondary align-items-center\">\n <a href=\"{{element.url}}\" target=\"_blank\" class=\"text-decoration-none text-muted clickable\">\n <mat-icon>download</mat-icon>\n </a>\n <app-techlify-form-button *ngIf=\"!viewOnly && isShowUpdateAction\" [component]=\"entityFileForm()\"\n [model]=\"element\" [data]=\"formData\" (saved)=\"modelsUpdatedById($event)\"></app-techlify-form-button>\n <app-techlify-delete-button *ngIf=\"!viewOnly && isShowDeleteAction\" [model]=\"element\" [service]=\"service\"\n message=\"Are you sure to proceed delete the file {{element.title}}\"\n (deleted)=\"modelsDeletedById(element)\">\n </app-techlify-delete-button>\n </div>\n </td>\n </ng-container>\n\n <tr mat-header-row *matHeaderRowDef=\"displayedColumns\"></tr>\n <tr mat-row *matRowDef=\"let row; columns: displayedColumns;\"></tr>\n </table>\n\n <mat-progress-bar mode=\"indeterminate\" *ngIf=\"isWorking\"></mat-progress-bar>\n </ng-template>\n\n <div class=\"d-flex flex-wrap gap-3 mat-typography p-4\" *ngIf=\"displayMode\">\n <div *ngFor=\"let efile of models\">\n <app-document-viewer [file]=\"efile.file\" [fileUrl]=\"efile.url\" [config]=\"this.viewerConfig\" [disableEdit]=\"true\">\n </app-document-viewer>\n <a href=\"{{efile.url}}\" target=\"_blank\">\n <button mat-button type=\"button\">View</button>\n </a>\n </div>\n </div>\n</div>\n\n<mat-card *ngIf=\"viewMode === 'timeline'\">\n <mat-card-content>\n <div class=\"d-flex justify-content-start align-items-center gap-2\">\n <mat-icon>\n description\n </mat-icon>\n <h3 class=\"font-weight-bold mb-0\">\n {{title}}s\n </h3>\n <app-techlify-form-button *ngIf=\"!viewOnly && isShowCreateAction\" [component]=\"entityFileForm()\" [data]=\"formData\"\n (saved)=\"modelCreated($event)\"></app-techlify-form-button>\n </div>\n </mat-card-content>\n <mat-card-content *ngIf=\"!this.selectedModelIds.length && !viewOnly && isShowCreateAction\" class=\"mt-3\">\n <app-file-dropper [config]=\"fileConfig\" (fileChanged)=\"fileChanged($event)\">\n </app-file-dropper>\n </mat-card-content>\n\n <mat-card-content class=\"mt-3\">\n <div *ngFor=\"let entityFile of models\" class=\"d-flex flex-column gap-0\">\n <div class=\"d-flex flex-column gap-0\">\n <div class=\"d-flex justify-content-between align-items-center gap-1\">\n <p class=\"mb-0 fw-bold text-wrap\">{{ entityFile?.title | wrap:20 }}</p>\n <span class=\"badge bg-dark\" *ngFor=\"let tag of entityFile?.tags\">\n {{ tag?.title }}\n </span>\n <small class=\"text-dark\">{{ entityFile.file_size | fileSize }}</small>\n </div>\n </div>\n <app-read-more [text]=\"entityFile?.details\" [maxLength]=\"50\"></app-read-more>\n <div class=\"d-flex justify-content-between gap-2\">\n <small class=\"text-secondary\" style=\"max-width: 70%\">\n <i>Uploaded By {{ entityFile?.creator?.name }} {{ entityFile?.created_at | date: 'mediumDate'}}</i>\n </small>\n <div class=\"d-flex justify-content-end align-items-center gap-1\">\n <a href=\"{{entityFile?.url}}\" target=\"_blank\" class=\"text-decoration-none text-secondary mt-2\">\n <mat-icon>download</mat-icon>\n </a>\n <app-techlify-form-button class=\"text-secondary\" *ngIf=\"!viewOnly && isShowUpdateAction\"\n [component]=\"entityFileForm()\" [model]=\"entityFile\" [data]=\"formData\"\n (saved)=\"modelsUpdatedById($event)\"></app-techlify-form-button>\n <app-techlify-delete-button *ngIf=\"!viewOnly && isShowDeleteAction\" class='text-secondary ms-1'\n [model]=\"entityFile\" [service]=\"service\"\n message=\"Are you sure to proceed delete the file {{entityFile.title}}\"\n (deleted)=\"modelsDeletedById(entityFile)\">\n </app-techlify-delete-button>\n </div>\n </div>\n <hr style=\"margin: 0.5rem 0\">\n </div>\n <mat-progress-bar mode=\"indeterminate\" *ngIf=\"isWorking\"></mat-progress-bar>\n </mat-card-content>\n</mat-card>", styles: ["th.mat-header-cell,td.mat-cell,td.mat-footer-cell{padding:2px}.entity-file-card{overflow-x:auto}.clickable:hover{cursor:pointer}\n"], dependencies: [{ kind: "directive", type: i3.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i3.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: i1$5.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1$5.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$5.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$5.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1$5.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: i6$2.InfiniteScrollDirective, selector: "[infiniteScroll], [infinite-scroll], [data-infinite-scroll]", inputs: ["infiniteScrollDistance", "infiniteScrollUpDistance", "infiniteScrollThrottle", "infiniteScrollDisabled", "infiniteScrollContainer", "scrollWindow", "immediateCheck", "horizontal", "alwaysCallback", "fromRoot"], outputs: ["scrolled", "scrolledUp"] }, { kind: "component", type: i6.MatButton, selector: " button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ", exportAs: ["matButton"] }, { kind: "component", type: i6.MatIconButton, selector: "button[mat-icon-button]", exportAs: ["matButton"] }, { kind: "component", type: i8$1.MatCheckbox, selector: "mat-checkbox", inputs: ["aria-label", "aria-labelledby", "aria-describedby", "id", "required", "labelPosition", "name", "value", "disableRipple", "tabIndex", "color", "disabledInteractive", "checked", "disabled", "indeterminate"], outputs: ["change", "indeterminateChange"], exportAs: ["matCheckbox"] }, { kind: "directive", type: i1.MatDialogTitle, selector: "[mat-dialog-title], [matDialogTitle]", inputs: ["id"], exportAs: ["matDialogTitle"] }, { kind: "component", type: i8$4.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i8$4.MatLabel, selector: "mat-label" }, { kind: "directive", type: i8$4.MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { kind: "component", type: i8.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "directive", type: i9.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly"], exportAs: ["matInput"] }, { kind: "directive", type: i11.MatSort, selector: "[matSort]", inputs: ["matSortActive", "matSortStart", "matSortDirection", "matSortDisableClear", "matSortDisabled"], outputs: ["matSortChange"], exportAs: ["matSort"] }, { kind: "component", type: i12.MatTable, selector: "mat-table, table[mat-table]", exportAs: ["matTable"] }, { kind: "directive", type: i12.MatHeaderCellDef, selector: "[matHeaderCellDef]" }, { kind: "directive", type: i12.MatHeaderRowDef, selector: "[matHeaderRowDef]", inputs: ["matHeaderRowDef", "matHeaderRowDefSticky"] }, { kind: "directive", type: i12.MatColumnDef, selector: "[matColumnDef]", inputs: ["matColumnDef"] }, { kind: "directive", type: i12.MatCellDef, selector: "[matCellDef]" }, { kind: "directive", type: i12.MatRowDef, selector: "[matRowDef]", inputs: ["matRowDefColumns", "matRowDefWhen"] }, { kind: "directive", type: i12.MatHeaderCell, selector: "mat-header-cell, th[mat-header-cell]" }, { kind: "directive", type: i12.MatCell, selector: "mat-cell, td[mat-cell]" }, { kind: "component", type: i12.MatHeaderRow, selector: "mat-header-row, tr[mat-header-row]", exportAs: ["matHeaderRow"] }, { kind: "component", type: i12.MatRow, selector: "mat-row, tr[mat-row]", exportAs: ["matRow"] }, { kind: "component", type: i4.MatCard, selector: "mat-card", inputs: ["appearance"], exportAs: ["matCard"] }, { kind: "directive", type: i4.MatCardContent, selector: "mat-card-content" }, { kind: "component", type: i4.MatCardHeader, selector: "mat-card-header" }, { kind: "directive", type: i4.MatCardTitle, selector: "mat-card-title, [mat-card-title], [matCardTitle]" }, { kind: "component", type: i11$2.MatProgressBar, selector: "mat-progress-bar", inputs: ["color", "value", "bufferValue", "mode"], outputs: ["animationEnd"], exportAs: ["matProgressBar"] }, { kind: "directive", type: i1$5.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$5.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "component", type: TechlifyDeleteButtonComponent, selector: "app-techlify-delete-button", inputs: ["data", "model", "message", "service"], outputs: ["deleted"] }, { kind: "component", type: TechlifyFormButtonComponent, selector: "app-techlify-form-button", inputs: ["component", "model", "data", "width"], outputs: ["saved"] }, { kind: "component", type: FileDropperComponent, selector: "app-file-dropper", inputs: ["fileArray", "config", "styles"], outputs: ["fileChanged"] }, { kind: "component", type: DocumentViewerComponent, selector: "app-document-viewer", inputs: ["config", "file", "fileUrl", "disableEdit"], outputs: ["remove"] }, { kind: "component", type: TechlifyTaggerTagFormFieldComponent, selector: "app-techlify-tagger-tag-form-field", inputs: ["config", "modelType", "modelId", "allTags", "categories", "defaultCreateCategory", "required", "disabled", "value", "placeholder"] }, { kind: "component", type: ReadMoreComponent, selector: "app-read-more", inputs: ["text", "maxLength"] }, { kind: "pipe", type: i3.DatePipe, name: "date" }, { kind: "pipe", type: WrapPipe, name: "wrap" }, { kind: "pipe", type: FileSizePipe, name: "fileSize" }] }); }
3746
- }
3747
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: EntityFileListComponent, decorators: [{
3748
- type: Component,
3749
- args: [{ selector: 'app-entity-file-list, app-entity-files-view-all', template: "<div *ngIf=\"viewMode === 'list'\">\n <div *ngIf=\"this.selectedModelIds.length\" class=\"d-none d-md-flex flex-column\">\n <mat-card class=\"update_card\" *ngIf=\"this.selectedModelIds.length\">\n <mat-card-header>\n <mat-card-title>\n <div mat-dialog-title class=\"mt-2 ml-2 text-center\">\n <div>Update Selected Rows</div>\n </div>\n </mat-card-title>\n </mat-card-header>\n <mat-card-content class=\"d-flex flex-column\">\n <form [formGroup]=\"updateRowForm\">\n <div class=\"d-flex flex-column\">\n\n <mat-form-field class=\"w-100 px-1\">\n <input matInput formControlName=\"title\" placeholder=\"Title\" autocomplete=\"off\" />\n <button *ngIf=\"updateRowForm.get('title').value || updateRowForm.get('title').value===0\" matSuffix\n mat-icon-button style=\"color:red\" (click)=\"updateRowForm.get('title').setValue('')\">\n <mat-icon>close</mat-icon>\n </button>\n <button matSuffix mat-icon-button type=\"button\" style=\"color:green\" *ngIf=\"(updateRowForm.get('title').value || updateRowForm.get('title').value===0)\n && updateRowForm.get('title').valid\" (click)=\"bulkUpdate('title')\">\n <mat-icon>done</mat-icon>\n </button>\n </mat-form-field>\n\n <mat-form-field class=\"w-100 px-1\">\n <textarea matInput formControlName=\"details\" placeholder=\"Details\" autocomplete=\"off\"></textarea>\n <button *ngIf=\"updateRowForm.get('details').value || updateRowForm.get('details').value===0\" matSuffix\n mat-icon-button style=\"color:red\" (click)=\"updateRowForm.get('details').setValue('')\">\n <mat-icon>close</mat-icon>\n </button>\n <button matSuffix mat-icon-button type=\"button\" style=\"color:green\" *ngIf=\"(updateRowForm.get('details').value || updateRowForm.get('details').value===0)\n && updateRowForm.get('details').valid\" (click)=\"bulkUpdate('details')\">\n <mat-icon>done</mat-icon>\n </button>\n </mat-form-field>\n\n <ng-container *ngIf=\"useTechlifyTags\">\n <mat-form-field>\n <mat-label>Tag</mat-label>\n <app-techlify-tagger-tag-form-field modelType=\"entity-file\" formControlName=\"tag_ids\"\n placeholder=\"Enter new tag\">\n </app-techlify-tagger-tag-form-field>\n <button *ngIf=\"updateRowForm.get('tag_ids').value || updateRowForm.get('tag_ids').value===0\" matSuffix\n mat-icon-button style=\"color:red\" (click)=\"updateRowForm.get('tag_ids').setValue('')\">\n <mat-icon>close</mat-icon>\n </button>\n <button matSuffix mat-icon-button type=\"button\" style=\"color:green\" *ngIf=\"(updateRowForm.get('tag_ids').value || updateRowForm.get('tag_ids').value===0)\n && updateRowForm.get('tag_ids').valid\" (click)=\"bulkUpdate('tag_ids')\">\n <mat-icon>done</mat-icon>\n </button>\n </mat-form-field>\n </ng-container>\n </div>\n </form>\n </mat-card-content>\n </mat-card>\n\n </div>\n\n <div>\n <div class=\"mat-typography\" *ngIf=\"!displayMode\">\n <div class=\"d-flex flex-row gap-3\">\n <div class=\"d-flex flex-column gap-2 flex-grow-1\">\n <mat-card>\n <mat-card-content>\n <div class=\"d-flex gap-2 align-items-center\">\n <mat-icon>\n description\n </mat-icon>\n <h3 class=\"font-weight-bold mb-0\">\n {{title}}s\n </h3>\n <app-techlify-form-button class=\"ms-2\" *ngIf=\"!viewOnly && isShowCreateAction && entityId\"\n [component]=\"entityFileForm()\" [data]=\"formData\"\n (saved)=\"modelCreated($event)\"></app-techlify-form-button>\n <span class=\"flex-grow-1\"></span>\n <form [formGroup]=\"filterForm\" class=\"d-flex gap-2\">\n <mat-form-field *ngIf=\"!removeSearch\" appearance=\"outline\">\n <mat-label>Search</mat-label>\n <input type=\"text\" matInput formControlName=\"title\" placeholder=\"Search\" name=\"title\"\n autocomplete=\"off\" />\n <button *ngIf=\"filterForm.get('title').value\" matSuffix mat-icon-button\n (click)=\"resetFilter('title')\">\n <mat-icon>close</mat-icon>\n </button>\n </mat-form-field>\n\n <ng-container *ngIf=\"useTechlifyTags\">\n <mat-form-field>\n <mat-label>Tag</mat-label>\n <app-techlify-tagger-tag-form-field [categories]=\"techlifyTagCategories\" formControlName=\"tag_ids\"\n placeholder=\"Select Tags\" [config]=\"techlifyTagConfig\"></app-techlify-tagger-tag-form-field>\n </mat-form-field>\n </ng-container>\n\n </form>\n </div>\n </mat-card-content>\n <mat-card-content class=\"entity-file-card p-0\" *ngIf=\"entityId\">\n <ng-container *ngTemplateOutlet=\"tableView\"></ng-container>\n </mat-card-content>\n </mat-card>\n\n <mat-card *ngIf=\"!entityId\">\n <mat-card-content class=\"entity-file-card p-0\">\n <ng-container *ngTemplateOutlet=\"tableView\"></ng-container>\n </mat-card-content>\n </mat-card>\n </div>\n <ng-container *ngIf=\"isShowDragDropSection && entityId\">\n <section style=\"flex: 0 1 30%;\" *ngIf=\"!this.selectedModelIds.length && !viewOnly && isShowCreateAction\">\n <app-file-dropper [config]=\"fileConfig\" (fileChanged)=\"fileChanged($event)\">\n </app-file-dropper>\n </section>\n </ng-container>\n </div>\n </div>\n </div>\n\n <ng-template #tableView>\n <table mat-table [dataSource]=\"models\" class=\"w-100\" matSort multiTemplateDataRows infiniteScroll\n [infiniteScrollDistance]=\"1.5\" [infiniteScrollThrottle]=\"50\" (scrolled)=\"onScroll()\">\n\n <!-- Select Column -->\n <ng-container matColumnDef=\"select\">\n <th mat-header-cell *matHeaderCellDef style=\"width:30px\">\n <mat-checkbox name=\"employee\" [(ngModel)]=\"isAllSelected\" (change)=\"selectAll()\">\n </mat-checkbox>\n </th>\n <td mat-cell *matCellDef=\"let element\" style=\"width:30px\">\n <mat-checkbox name=\"employee[{{element?.id}}]\" (click)=\"$event.stopPropagation()\"\n [(ngModel)]=\"element.is_selected\" (change)=\"isSelectionModified($event, element)\"\n [disabled]=\"!models.length\">\n </mat-checkbox>\n </td>\n </ng-container>\n\n <!-- Index Column -->\n <ng-container matColumnDef=\"index\">\n <th mat-header-cell *matHeaderCellDef> # </th>\n <td mat-cell *matCellDef=\"let element; let i = dataIndex\"> {{ i+1 }} </td>\n </ng-container>\n\n <!-- Title Column -->\n <ng-container matColumnDef=\"title\">\n <th mat-header-cell *matHeaderCellDef> Title </th>\n <td mat-cell *matCellDef=\"let element\">\n {{element.title}}\n <ng-container *ngIf=\"useTechlifyTags\">\n <br>\n <small class=\"badge badge-secondary mr-1\" *ngFor=\"let tag of element?.tags\">{{tag?.title}}</small>\n </ng-container>\n\n </td>\n </ng-container>\n\n <!-- Details Column -->\n <ng-container matColumnDef=\"details\">\n <th mat-header-cell *matHeaderCellDef> Details </th>\n <td mat-cell *matCellDef=\"let element\">\n <app-read-more [text]=\"element.details\" [maxLength]=\"50\"></app-read-more>\n </td>\n </ng-container>\n\n <!-- File size Column -->\n <ng-container matColumnDef=\"file_size\">\n <th mat-header-cell *matHeaderCellDef> File Size </th>\n <td mat-cell *matCellDef=\"let element\"> {{ element.file_size | fileSize }} </td>\n </ng-container>\n\n <!-- Uploaded On Column -->\n <ng-container matColumnDef=\"uploaded_on\">\n <th mat-header-cell *matHeaderCellDef> Uploaded On </th>\n <td mat-cell *matCellDef=\"let element\">\n <div>\n {{element.created_at | date: 'mediumDate'}}\n </div>\n <div class=\"text-muted\">\n By {{element.creator?.name}}\n </div>\n </td>\n </ng-container>\n\n <!-- Actions Column -->\n <ng-container matColumnDef=\"actions\">\n <th mat-header-cell *matHeaderCellDef> Actions </th>\n <td mat-cell *matCellDef=\"let element\" class=\"text-muted\">\n <div class=\"d-flex flex-row gap-2 text-secondary align-items-center\">\n <a href=\"{{element.url}}\" target=\"_blank\" class=\"text-decoration-none text-muted clickable\">\n <mat-icon>download</mat-icon>\n </a>\n <app-techlify-form-button *ngIf=\"!viewOnly && isShowUpdateAction\" [component]=\"entityFileForm()\"\n [model]=\"element\" [data]=\"formData\" (saved)=\"modelsUpdatedById($event)\"></app-techlify-form-button>\n <app-techlify-delete-button *ngIf=\"!viewOnly && isShowDeleteAction\" [model]=\"element\" [service]=\"service\"\n message=\"Are you sure to proceed delete the file {{element.title}}\"\n (deleted)=\"modelsDeletedById(element)\">\n </app-techlify-delete-button>\n </div>\n </td>\n </ng-container>\n\n <tr mat-header-row *matHeaderRowDef=\"displayedColumns\"></tr>\n <tr mat-row *matRowDef=\"let row; columns: displayedColumns;\"></tr>\n </table>\n\n <mat-progress-bar mode=\"indeterminate\" *ngIf=\"isWorking\"></mat-progress-bar>\n </ng-template>\n\n <div class=\"d-flex flex-wrap gap-3 mat-typography p-4\" *ngIf=\"displayMode\">\n <div *ngFor=\"let efile of models\">\n <app-document-viewer [file]=\"efile.file\" [fileUrl]=\"efile.url\" [config]=\"this.viewerConfig\" [disableEdit]=\"true\">\n </app-document-viewer>\n <a href=\"{{efile.url}}\" target=\"_blank\">\n <button mat-button type=\"button\">View</button>\n </a>\n </div>\n </div>\n</div>\n\n<mat-card *ngIf=\"viewMode === 'timeline'\">\n <mat-card-content>\n <div class=\"d-flex justify-content-start align-items-center gap-2\">\n <mat-icon>\n description\n </mat-icon>\n <h3 class=\"font-weight-bold mb-0\">\n {{title}}s\n </h3>\n <app-techlify-form-button *ngIf=\"!viewOnly && isShowCreateAction\" [component]=\"entityFileForm()\" [data]=\"formData\"\n (saved)=\"modelCreated($event)\"></app-techlify-form-button>\n </div>\n </mat-card-content>\n <mat-card-content *ngIf=\"!this.selectedModelIds.length && !viewOnly && isShowCreateAction\" class=\"mt-3\">\n <app-file-dropper [config]=\"fileConfig\" (fileChanged)=\"fileChanged($event)\">\n </app-file-dropper>\n </mat-card-content>\n\n <mat-card-content class=\"mt-3\">\n <div *ngFor=\"let entityFile of models\" class=\"d-flex flex-column gap-0\">\n <div class=\"d-flex flex-column gap-0\">\n <div class=\"d-flex justify-content-between align-items-center gap-1\">\n <p class=\"mb-0 fw-bold text-wrap\">{{ entityFile?.title | wrap:20 }}</p>\n <span class=\"badge bg-dark\" *ngFor=\"let tag of entityFile?.tags\">\n {{ tag?.title }}\n </span>\n <small class=\"text-dark\">{{ entityFile.file_size | fileSize }}</small>\n </div>\n </div>\n <app-read-more [text]=\"entityFile?.details\" [maxLength]=\"50\"></app-read-more>\n <div class=\"d-flex justify-content-between gap-2\">\n <small class=\"text-secondary\" style=\"max-width: 70%\">\n <i>Uploaded By {{ entityFile?.creator?.name }} {{ entityFile?.created_at | date: 'mediumDate'}}</i>\n </small>\n <div class=\"d-flex justify-content-end align-items-center gap-1\">\n <a href=\"{{entityFile?.url}}\" target=\"_blank\" class=\"text-decoration-none text-secondary mt-2\">\n <mat-icon>download</mat-icon>\n </a>\n <app-techlify-form-button class=\"text-secondary\" *ngIf=\"!viewOnly && isShowUpdateAction\"\n [component]=\"entityFileForm()\" [model]=\"entityFile\" [data]=\"formData\"\n (saved)=\"modelsUpdatedById($event)\"></app-techlify-form-button>\n <app-techlify-delete-button *ngIf=\"!viewOnly && isShowDeleteAction\" class='text-secondary ms-1'\n [model]=\"entityFile\" [service]=\"service\"\n message=\"Are you sure to proceed delete the file {{entityFile.title}}\"\n (deleted)=\"modelsDeletedById(entityFile)\">\n </app-techlify-delete-button>\n </div>\n </div>\n <hr style=\"margin: 0.5rem 0\">\n </div>\n <mat-progress-bar mode=\"indeterminate\" *ngIf=\"isWorking\"></mat-progress-bar>\n </mat-card-content>\n</mat-card>", styles: ["th.mat-header-cell,td.mat-cell,td.mat-footer-cell{padding:2px}.entity-file-card{overflow-x:auto}.clickable:hover{cursor:pointer}\n"] }]
3750
- }], ctorParameters: () => [{ type: EntityFileService }, { type: AlertService }, { type: i1$5.UntypedFormBuilder }, { type: ErrorHandlerService }, { type: i5$1.NgxPermissionsService }], propDecorators: { entityId: [{
3751
- type: Input
3752
- }], entityType: [{
3753
- type: Input
3754
- }], viewOnly: [{
3755
- type: Input
3756
- }], removeSearch: [{
3757
- type: Input
3758
- }], hideTitleAndDetails: [{
3759
- type: Input
3760
- }], displayMode: [{
3761
- type: Input
3762
- }], allowMultipleFiles: [{
3763
- type: Input
3764
- }], allowBulkUpdate: [{
3765
- type: Input
3766
- }], viewMode: [{
3767
- type: Input
3768
- }], fileDropperHeight: [{
3769
- type: Input
3770
- }], isShowDragDropSection: [{
3771
- type: Input
3772
- }], isFilterPatchFromRoute: [{
3773
- type: Input
3774
- }], useTechlifyTags: [{
3775
- type: Input
3776
- }], techlifyTagCategories: [{
3777
- type: Input
3778
- }], techlifyTagConfig: [{
3779
- type: Input
3780
- }], title: [{
3781
- type: Input
3782
- }], permission: [{
3783
- type: Input
3784
- }] } });
3785
-
3786
- class FileDropperConfig {
3787
- }
3788
-
3789
- class NoteService {
3790
- constructor(http) {
3791
- this.http = http;
3792
- }
3793
- getNotes(filterModel) {
3794
- return this.http.get('api/notes', { params: filterModel }).toPromise();
3795
- }
3796
- addNote(note) {
3797
- return this.http.post('api/notes', note).toPromise();
3798
- }
3799
- editNote(note) {
3800
- return this.http.put(`api/notes/${note.id}`, note).toPromise();
3646
+ static { this.nextId = 0; }
3647
+ get timelineValue() {
3648
+ return this.selectorForm.get('select_value');
3801
3649
  }
3802
- deleteNote(note) {
3803
- return this.http.delete(`api/notes/${note.id}`).toPromise();
3650
+ get isCustomSelected() {
3651
+ return this.value == Timeline.CUSTOM;
3804
3652
  }
3805
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: NoteService, deps: [{ token: HttpService }], target: i0.ɵɵFactoryTarget.Injectable }); }
3806
- static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: NoteService, providedIn: 'root' }); }
3807
- }
3808
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: NoteService, decorators: [{
3809
- type: Injectable,
3810
- args: [{
3811
- providedIn: 'root'
3812
- }]
3813
- }], ctorParameters: () => [{ type: HttpService }] });
3814
-
3815
- const errorMessages$b = {
3816
- note: {
3817
- required: "Note is required"
3653
+ get customDateFrom() {
3654
+ return this.selectorForm.get('custom_date_from');
3818
3655
  }
3819
- };
3820
- class NoteFormComponent {
3821
- constructor(dialogRef, data, fb, formValidatorService, alertService, noteService) {
3822
- this.dialogRef = dialogRef;
3823
- this.data = data;
3824
- this.fb = fb;
3825
- this.formValidatorService = formValidatorService;
3826
- this.alertService = alertService;
3827
- this.noteService = noteService;
3828
- this.createForm();
3656
+ get customDateTo() {
3657
+ return this.selectorForm.get('custom_date_to');
3829
3658
  }
3830
- /** Method to create a form **/
3831
- createForm() {
3832
- //TODO: Finialize and add more validations.
3833
- this.noteFormGroup = this.fb.group({
3834
- id: [""],
3835
- note: ["", Validators.compose([Validators.required])],
3836
- model_type: [""],
3837
- related_model_id: [""],
3659
+ constructor(formBuilder, ngControl, datePipe) {
3660
+ this.ngControl = ngControl;
3661
+ this.datePipe = datePipe;
3662
+ this.isInitialised = false;
3663
+ this.timelines = [
3664
+ { value: Timeline.CUSTOM, viewValue: 'Custom' },
3665
+ { value: Timeline.TODAY, viewValue: 'Today' },
3666
+ { value: Timeline.YESTERDAY, viewValue: 'Yesterday' },
3667
+ { value: Timeline.TOMMOROW, viewValue: 'Tomorrow' },
3668
+ { value: Timeline.THIS_WEEK, viewValue: 'This Week' },
3669
+ { value: Timeline.LAST_WEEK, viewValue: 'Last Week' },
3670
+ { value: Timeline.NEXT_WEEK, viewValue: 'Next Week' },
3671
+ { value: Timeline.THIS_MONTH, viewValue: 'This Month' },
3672
+ { value: Timeline.LAST_MONTH, viewValue: 'Last Month' },
3673
+ { value: Timeline.NEXT_MONTH, viewValue: 'Next Month' },
3674
+ { value: Timeline.THIS_QUARTER, viewValue: 'This Quarter' },
3675
+ { value: Timeline.LAST_QUARTER, viewValue: 'Last Quarter' },
3676
+ { value: Timeline.THIS_YEAR, viewValue: 'This Year' },
3677
+ { value: Timeline.LAST_YEAR, viewValue: 'Last Year' },
3678
+ { value: Timeline.ALL, viewValue: 'All dates' },
3679
+ ];
3680
+ this.dateFrom = 'date_from';
3681
+ this.dateTo = 'date_to';
3682
+ this.appearance = 'fill';
3683
+ this.showClearButton = false;
3684
+ this.labelText = 'Select Timeline';
3685
+ this.selectionChange = new EventEmitter();
3686
+ this.stateChanges = new Subject();
3687
+ this.controlType = 'timeline-filter';
3688
+ this.id = `timeline-filter-${TimelineFilterComponent_1.nextId++}`;
3689
+ this.describedBy = '';
3690
+ this.focused = false;
3691
+ this._required = false;
3692
+ this._disabled = false;
3693
+ this.onChange = () => { };
3694
+ this.onTouched = () => { };
3695
+ //Custom range
3696
+ this.selectedRangeLabel = '';
3697
+ this.selectorForm = formBuilder.group({
3698
+ select_value: [''],
3699
+ custom_date_from: [''],
3700
+ custom_date_to: [''],
3838
3701
  });
3702
+ if (this.ngControl != null) {
3703
+ this.ngControl.valueAccessor = this;
3704
+ }
3839
3705
  }
3840
3706
  ngOnInit() {
3841
- if (this.data.update) {
3842
- this.updateMode = true;
3843
- }
3844
- this.noteFormGroup.patchValue(this.data.note);
3707
+ this.timelineValue.valueChanges.
3708
+ pipe(debounceTime(100), distinctUntilChanged(), untilDestroyed(this)).subscribe(value => this.value = value);
3709
+ //Listen only to custom date to, since it is range selector it always safe to listen date to
3710
+ this.customDateTo.valueChanges.pipe(distinctUntilChanged(), untilDestroyed(this)).subscribe(val => {
3711
+ if (val && !this.isCustomDatePatching) {
3712
+ this.applyRange();
3713
+ }
3714
+ });
3845
3715
  }
3846
- //Method to trigger login
3847
- async submit() {
3848
- this.noteFormFirstAttempt = true;
3849
- if (this.noteFormGroup.valid) {
3850
- const model = this.noteFormGroup.value;
3851
- const result = this.updateMode
3852
- ? await this.noteService.editNote(model)
3853
- : await this.noteService.addNote(model);
3854
- this.alertService.addAlert(`${this.data?.labelText} saved successfully`, "success");
3855
- this.dialogRef.close(result);
3856
- }
3716
+ resetFieldValue(field) {
3717
+ this.form?.get(field)?.setValue('');
3857
3718
  }
3858
- cancel() {
3859
- this.dialogRef.close();
3719
+ getFieldValue(field) {
3720
+ return this.form?.get(field)?.value;
3860
3721
  }
3861
- /**Method to evaluate form fields*/
3862
- isFieldValid(field) {
3863
- return this.formValidatorService.isFieldValid(field, this.noteFormGroup, this.noteFormFirstAttempt);
3722
+ setFieldValue(field, value, emitEvent = true) {
3723
+ this.form?.get(field)?.setValue(value, { emitEvent: emitEvent });
3864
3724
  }
3865
- /**Method to find error in form fields*/
3866
- getErrorMessage(field) {
3867
- return this.formValidatorService.getErrorMessage(field, this.noteFormGroup, errorMessages$b);
3725
+ changeTimeline(value) {
3726
+ value = parseInt(value);
3727
+ this.selectedRangeLabel = '';
3728
+ const timeline = calculateTimeline(value, this.dateFrom, this.dateTo);
3729
+ if (timeline) {
3730
+ this.setCustomDates('', '');
3731
+ this.setFieldValue(this.dateFrom, this.datePipe.transform(timeline.date_from, 'yyyy-MM-dd'));
3732
+ this.setFieldValue(this.dateTo, this.datePipe.transform(timeline.date_to, 'yyyy-MM-dd'));
3733
+ }
3734
+ this.onChange(this.value);
3735
+ this.selectionChange.emit(timeline);
3868
3736
  }
3869
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: NoteFormComponent, deps: [{ token: i1.MatDialogRef }, { token: MAT_DIALOG_DATA }, { token: i1$5.UntypedFormBuilder }, { token: FormValidatorService }, { token: AlertService }, { token: NoteService }], target: i0.ɵɵFactoryTarget.Component }); }
3870
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.14", type: NoteFormComponent, selector: "app-note-form", ngImport: i0, template: "<form [formGroup]=\"noteFormGroup\" (ngSubmit)=\"submit()\">\n <div fxLayout=\"column\" class=\"mat-typography\">\n <div mat-dialog-title class=\"text-center\">\n <div>{{data?.labelText}}</div>\n </div>\n\n <div mat-dialog-content fxLayout=\"column\">\n <div fxLayout=\"row wrap\" fxLayoutAlign=\"space-between\">\n <mat-form-field fxFlex=\"100%\">\n <textarea matInput formControlName=\"note\" placeholder=\"{{data?.labelText}}\" autocomplete=\"off\"\n required></textarea>\n <mat-error *ngIf=\"isFieldValid('note')\">{{\n getErrorMessage(\"note\")\n }}</mat-error>\n </mat-form-field>\n\n <div class=\"my-2\" fxLayout=\"row\" fxLayoutGap=\"30px\" fxLayoutAlign=\"end\" fxFlex=\"100%\">\n <button mat-raised-button type=\"button\" (click)=\"cancel()\">\n Cancel\n </button>\n <button mat-raised-button type=\"submit\" color=\"primary\">Save</button>\n </div>\n </div>\n </div>\n </div>\n</form>", styles: [""], dependencies: [{ kind: "directive", type: i3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1$5.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1$5.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$5.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$5.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1$5.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i1$5.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$5.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "directive", type: i6$1.DefaultLayoutDirective, selector: " [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]", inputs: ["fxLayout", "fxLayout.xs", "fxLayout.sm", "fxLayout.md", "fxLayout.lg", "fxLayout.xl", "fxLayout.lt-sm", "fxLayout.lt-md", "fxLayout.lt-lg", "fxLayout.lt-xl", "fxLayout.gt-xs", "fxLayout.gt-sm", "fxLayout.gt-md", "fxLayout.gt-lg"] }, { kind: "directive", type: i6$1.DefaultLayoutGapDirective, selector: " [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]", inputs: ["fxLayoutGap", "fxLayoutGap.xs", "fxLayoutGap.sm", "fxLayoutGap.md", "fxLayoutGap.lg", "fxLayoutGap.xl", "fxLayoutGap.lt-sm", "fxLayoutGap.lt-md", "fxLayoutGap.lt-lg", "fxLayoutGap.lt-xl", "fxLayoutGap.gt-xs", "fxLayoutGap.gt-sm", "fxLayoutGap.gt-md", "fxLayoutGap.gt-lg"] }, { kind: "directive", type: i6$1.DefaultLayoutAlignDirective, selector: " [fxLayoutAlign], [fxLayoutAlign.xs], [fxLayoutAlign.sm], [fxLayoutAlign.md], [fxLayoutAlign.lg], [fxLayoutAlign.xl], [fxLayoutAlign.lt-sm], [fxLayoutAlign.lt-md], [fxLayoutAlign.lt-lg], [fxLayoutAlign.lt-xl], [fxLayoutAlign.gt-xs], [fxLayoutAlign.gt-sm], [fxLayoutAlign.gt-md], [fxLayoutAlign.gt-lg]", inputs: ["fxLayoutAlign", "fxLayoutAlign.xs", "fxLayoutAlign.sm", "fxLayoutAlign.md", "fxLayoutAlign.lg", "fxLayoutAlign.xl", "fxLayoutAlign.lt-sm", "fxLayoutAlign.lt-md", "fxLayoutAlign.lt-lg", "fxLayoutAlign.lt-xl", "fxLayoutAlign.gt-xs", "fxLayoutAlign.gt-sm", "fxLayoutAlign.gt-md", "fxLayoutAlign.gt-lg"] }, { kind: "directive", type: i6$1.DefaultFlexDirective, selector: " [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]", inputs: ["fxFlex", "fxFlex.xs", "fxFlex.sm", "fxFlex.md", "fxFlex.lg", "fxFlex.xl", "fxFlex.lt-sm", "fxFlex.lt-md", "fxFlex.lt-lg", "fxFlex.lt-xl", "fxFlex.gt-xs", "fxFlex.gt-sm", "fxFlex.gt-md", "fxFlex.gt-lg"] }, { kind: "component", type: i6.MatButton, selector: " button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ", exportAs: ["matButton"] }, { kind: "directive", type: i1.MatDialogTitle, selector: "[mat-dialog-title], [matDialogTitle]", inputs: ["id"], exportAs: ["matDialogTitle"] }, { kind: "directive", type: i1.MatDialogContent, selector: "[mat-dialog-content], mat-dialog-content, [matDialogContent]" }, { kind: "component", type: i8$4.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i8$4.MatError, selector: "mat-error, [matError]", inputs: ["id"] }, { kind: "directive", type: i9.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly"], exportAs: ["matInput"] }] }); }
3871
- }
3872
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: NoteFormComponent, decorators: [{
3873
- type: Component,
3874
- args: [{ selector: 'app-note-form', template: "<form [formGroup]=\"noteFormGroup\" (ngSubmit)=\"submit()\">\n <div fxLayout=\"column\" class=\"mat-typography\">\n <div mat-dialog-title class=\"text-center\">\n <div>{{data?.labelText}}</div>\n </div>\n\n <div mat-dialog-content fxLayout=\"column\">\n <div fxLayout=\"row wrap\" fxLayoutAlign=\"space-between\">\n <mat-form-field fxFlex=\"100%\">\n <textarea matInput formControlName=\"note\" placeholder=\"{{data?.labelText}}\" autocomplete=\"off\"\n required></textarea>\n <mat-error *ngIf=\"isFieldValid('note')\">{{\n getErrorMessage(\"note\")\n }}</mat-error>\n </mat-form-field>\n\n <div class=\"my-2\" fxLayout=\"row\" fxLayoutGap=\"30px\" fxLayoutAlign=\"end\" fxFlex=\"100%\">\n <button mat-raised-button type=\"button\" (click)=\"cancel()\">\n Cancel\n </button>\n <button mat-raised-button type=\"submit\" color=\"primary\">Save</button>\n </div>\n </div>\n </div>\n </div>\n</form>" }]
3875
- }], ctorParameters: () => [{ type: i1.MatDialogRef }, { type: undefined, decorators: [{
3876
- type: Inject,
3877
- args: [MAT_DIALOG_DATA]
3878
- }] }, { type: i1$5.UntypedFormBuilder }, { type: FormValidatorService }, { type: AlertService }, { type: NoteService }] });
3879
-
3880
- class CommentFormComponent {
3881
- set commentData(data) {
3882
- this.view = !!data;
3883
- this._commentData = data;
3884
- this.commentFormGroup.patchValue(data);
3737
+ openCalendar() {
3738
+ this.picker.open();
3885
3739
  }
3886
- constructor(fb, credentialService) {
3887
- this.fb = fb;
3888
- this.credentialService = credentialService;
3889
- this.action = new EventEmitter();
3890
- this.createForm();
3740
+ applyRange(defaultFrom, defaultTo) {
3741
+ const from = defaultFrom ?? this.selectorForm.get('custom_date_from')?.value;
3742
+ const to = defaultTo ?? this.selectorForm.get('custom_date_to')?.value;
3743
+ if (from && to) {
3744
+ this.selectedRangeLabel = `<b>${this.datePipe.transform(from, 'yyyy-MM-dd')}</b>:<b>${this.datePipe.transform(to, 'yyyy-MM-dd')}</b`;
3745
+ this.setFieldValue(this.dateFrom, this.datePipe.transform(from, 'yyyy-MM-dd'));
3746
+ this.setFieldValue(this.dateTo, this.datePipe.transform(to, 'yyyy-MM-dd'));
3747
+ this.onChange(this.value);
3748
+ this.selectionChange.emit(this.value);
3749
+ this.setCustomDates(from, to);
3750
+ }
3891
3751
  }
3892
- ngOnInit() { }
3893
- get isLoggedIn() {
3894
- return this.credentialService.isAuthenticated;
3752
+ setCustomDates(from, to) {
3753
+ // update form fields silently
3754
+ this.isCustomDatePatching = true;
3755
+ this.selectorForm.get('custom_date_from')?.setValue(from, { emitEvent: false });
3756
+ this.selectorForm.get('custom_date_to')?.setValue(to, { emitEvent: false });
3757
+ this.isCustomDatePatching = false;
3895
3758
  }
3896
- get currentUser() {
3897
- return this.credentialService.credentials.user;
3759
+ setDescribedByIds(ids) {
3760
+ this.describedBy = ids.join(' ');
3898
3761
  }
3899
- createForm() {
3900
- //TODO: Finialize and add more validations.
3901
- this.commentFormGroup = this.fb.group({
3902
- id: [""],
3903
- note: [""],
3904
- model_type: [""],
3905
- related_model_id: [""],
3906
- });
3762
+ onContainerClick(event) {
3763
+ event.stopPropagation();
3907
3764
  }
3908
- submit() {
3909
- if (this.commentFormGroup.get("note").value) {
3910
- if (this._commentData) {
3911
- this.view = !this.view;
3912
- }
3913
- this.action.emit({ type: "save", value: this.commentFormGroup.value });
3914
- this.commentFormGroup.reset();
3915
- }
3916
- else if (this.commentFormGroup.get("id").value) {
3917
- this.deleteComment();
3918
- }
3765
+ writeValue(data) {
3766
+ this.value = data;
3919
3767
  }
3920
- hideEdit() {
3921
- if (this.commentFormGroup.get("id").value) {
3922
- this.view = !this.view;
3923
- }
3768
+ registerOnChange(fn) {
3769
+ this.onChange = fn;
3924
3770
  }
3925
- editComment() {
3926
- this.view = !this.view;
3927
- this.commentFormGroup.patchValue(this._commentData);
3771
+ registerOnTouched(fn) {
3772
+ this.onTouched = fn;
3928
3773
  }
3929
- deleteComment() {
3930
- this.action.emit({ type: "delete", value: this.commentFormGroup.value });
3774
+ setDisabledState(isDisabled) {
3775
+ this.disabled = isDisabled;
3931
3776
  }
3932
- ngOnDestroy() { }
3933
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: CommentFormComponent, deps: [{ token: i1$5.UntypedFormBuilder }, { token: CredentialsService }], target: i0.ɵɵFactoryTarget.Component }); }
3934
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.14", type: CommentFormComponent, selector: "app-comment-form", inputs: { commentData: "commentData" }, outputs: { action: "action" }, ngImport: i0, template: "<form (ngSubmit)=\"submit()\" [formGroup]=\"commentFormGroup\">\n <div fxLayout=\"column\" class=\"my-2\" [ngClass]=\"{ 'border border-primary shadow rounded ': view}\">\n <div *ngIf=\"!view\" fxLayout=\"column\">\n <mat-form-field appearance=\"outline\" style=\"background-color:white;\">\n <mat-label>Comment</mat-label>\n <textarea matInput rows=\"5\" placeholder=\"Add a comment...\" formControlName=\"note\" autocomplete=\"off\"></textarea>\n </mat-form-field>\n\n <div fxLayout fxLayoutGap=\"1rem\" class=\"mt-2\">\n <span fxFlex></span>\n <button *ngIf=\"_commentData\" mat-button type=\"button\" (click)=\"view = !view\">\n Cancel\n </button>\n <button mat-raised-button color=\"primary\" type=\"submit\">\n {{ _commentData ? \"Update\" : \"Post comment\" }}\n </button>\n </div>\n </div>\n\n <div fxLayout=\"column\" *ngIf=\"view\" class=\"p-2 m-2\">\n <div fxLayout=\"row wrap\" fxLayoutGap=\".5rem\">\n <div fxFlex=\"20%\" fxLayoutAlign=\"start\">\n <button mat-icon-button type=\"button\" style=\"color:grey\">\n <mat-icon style=\"font-size:60px\">account_circle</mat-icon>\n </button>\n </div>\n <div fxFlex=\"75%\">\n <div fxLayout=\"column\" fxLayoutGap=\".5rem\">\n <div class=\"font-weight-bold\">{{ _commentData?.creator?.name }}</div>\n <div class=\"text-muted\">{{ _commentData.updated_at | date:'medium' }}</div>\n </div>\n </div>\n </div>\n <app-read-more class=\"mt-2\" [text]=\"_commentData.note\"></app-read-more>\n <div fxLayout class=\"mt-1\" fxLayoutGap=\"1rem\" *ngIf=\"isLoggedIn && currentUser.id === _commentData.creator_id\">\n <a href=\"javascript:;\" (click)=\"editComment()\">\n Edit\n </a>\n <a href=\"javascript:;\" (click)=\"deleteComment()\">\n Delete\n </a>\n </div>\n </div>\n </div>\n</form>", styles: [":host ::ng-deep .mat-form-field-wrapper{padding-bottom:0!important;margin:0!important}\n"], dependencies: [{ kind: "directive", type: i3.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1$5.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1$5.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$5.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$5.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1$5.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$5.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "directive", type: i6$1.DefaultLayoutDirective, selector: " [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]", inputs: ["fxLayout", "fxLayout.xs", "fxLayout.sm", "fxLayout.md", "fxLayout.lg", "fxLayout.xl", "fxLayout.lt-sm", "fxLayout.lt-md", "fxLayout.lt-lg", "fxLayout.lt-xl", "fxLayout.gt-xs", "fxLayout.gt-sm", "fxLayout.gt-md", "fxLayout.gt-lg"] }, { kind: "directive", type: i6$1.DefaultLayoutGapDirective, selector: " [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]", inputs: ["fxLayoutGap", "fxLayoutGap.xs", "fxLayoutGap.sm", "fxLayoutGap.md", "fxLayoutGap.lg", "fxLayoutGap.xl", "fxLayoutGap.lt-sm", "fxLayoutGap.lt-md", "fxLayoutGap.lt-lg", "fxLayoutGap.lt-xl", "fxLayoutGap.gt-xs", "fxLayoutGap.gt-sm", "fxLayoutGap.gt-md", "fxLayoutGap.gt-lg"] }, { kind: "directive", type: i6$1.DefaultLayoutAlignDirective, selector: " [fxLayoutAlign], [fxLayoutAlign.xs], [fxLayoutAlign.sm], [fxLayoutAlign.md], [fxLayoutAlign.lg], [fxLayoutAlign.xl], [fxLayoutAlign.lt-sm], [fxLayoutAlign.lt-md], [fxLayoutAlign.lt-lg], [fxLayoutAlign.lt-xl], [fxLayoutAlign.gt-xs], [fxLayoutAlign.gt-sm], [fxLayoutAlign.gt-md], [fxLayoutAlign.gt-lg]", inputs: ["fxLayoutAlign", "fxLayoutAlign.xs", "fxLayoutAlign.sm", "fxLayoutAlign.md", "fxLayoutAlign.lg", "fxLayoutAlign.xl", "fxLayoutAlign.lt-sm", "fxLayoutAlign.lt-md", "fxLayoutAlign.lt-lg", "fxLayoutAlign.lt-xl", "fxLayoutAlign.gt-xs", "fxLayoutAlign.gt-sm", "fxLayoutAlign.gt-md", "fxLayoutAlign.gt-lg"] }, { kind: "directive", type: i6$1.DefaultFlexDirective, selector: " [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]", inputs: ["fxFlex", "fxFlex.xs", "fxFlex.sm", "fxFlex.md", "fxFlex.lg", "fxFlex.xl", "fxFlex.lt-sm", "fxFlex.lt-md", "fxFlex.lt-lg", "fxFlex.lt-xl", "fxFlex.gt-xs", "fxFlex.gt-sm", "fxFlex.gt-md", "fxFlex.gt-lg"] }, { kind: "directive", type: i2.DefaultClassDirective, selector: " [ngClass], [ngClass.xs], [ngClass.sm], [ngClass.md], [ngClass.lg], [ngClass.xl], [ngClass.lt-sm], [ngClass.lt-md], [ngClass.lt-lg], [ngClass.lt-xl], [ngClass.gt-xs], [ngClass.gt-sm], [ngClass.gt-md], [ngClass.gt-lg]", inputs: ["ngClass", "ngClass.xs", "ngClass.sm", "ngClass.md", "ngClass.lg", "ngClass.xl", "ngClass.lt-sm", "ngClass.lt-md", "ngClass.lt-lg", "ngClass.lt-xl", "ngClass.gt-xs", "ngClass.gt-sm", "ngClass.gt-md", "ngClass.gt-lg"] }, { kind: "component", type: i6.MatButton, selector: " button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ", exportAs: ["matButton"] }, { kind: "component", type: i6.MatIconButton, selector: "button[mat-icon-button]", exportAs: ["matButton"] }, { kind: "component", type: i8$4.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i8$4.MatLabel, selector: "mat-label" }, { kind: "component", type: i8.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "directive", type: i9.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly"], exportAs: ["matInput"] }, { kind: "component", type: ReadMoreComponent, selector: "app-read-more", inputs: ["text", "maxLength"] }, { kind: "pipe", type: i3.DatePipe, name: "date" }] }); }
3935
- }
3936
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: CommentFormComponent, decorators: [{
3777
+ ngOnDestroy() {
3778
+ this.stateChanges.complete();
3779
+ }
3780
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: TimelineFilterComponent, deps: [{ token: i1$5.UntypedFormBuilder }, { token: i1$5.NgControl, optional: true, self: true }, { token: i3.DatePipe }], target: i0.ɵɵFactoryTarget.Component }); }
3781
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.14", type: TimelineFilterComponent, selector: "app-timeline-filter", inputs: { defaultValue: "defaultValue", required: "required", disabled: "disabled", value: "value", timelines: "timelines", dateFrom: "dateFrom", dateTo: "dateTo", appearance: "appearance", showClearButton: "showClearButton", form: "form", labelText: "labelText" }, outputs: { selectionChange: "selectionChange" }, providers: [
3782
+ DatePipe,
3783
+ {
3784
+ provide: MatFormFieldControl,
3785
+ useExisting: TimelineFilterComponent
3786
+ }
3787
+ ], viewQueries: [{ propertyName: "picker", first: true, predicate: ["picker"], descendants: true }], ngImport: i0, template: "<ng-container [formGroup]=\"selectorForm\">\n <mat-form-field [appearance]=\"appearance\" class=\"fl-sm\">\n <mat-label>{{labelText}}</mat-label>\n <mat-select formControlName=\"select_value\">\n <mat-option *ngFor=\"let timeline of timelines\" [value]=\"timeline.value\">\n {{timeline.viewValue}}\n </mat-option>\n </mat-select>\n <button *ngIf=\"showClearButton && timelineValue.value\" matSuffix mat-icon-button\n (click)=\"timelineValue.setValue('')\">\n <mat-icon>close</mat-icon>\n </button>\n <mat-hint *ngIf=\"isCustomSelected && selectedRangeLabel\" (click)=\"openCalendar()\" class=\"clickable\" fxLayout>\n <span [innerHTML]=\"selectedRangeLabel\" style=\"font-size: 10px;\"></span>\n <app-techlify-icon name=\"edit\" class=\"clickable\" size=\"xs\" style=\"margin-left:2px\"></app-techlify-icon>\n </mat-hint>\n <mat-hint *ngIf=\"isCustomSelected && !selectedRangeLabel\" (click)=\"openCalendar()\" class=\"clickable\" fxLayout>\n <span style=\"font-size: 10px;\">Select Range</span>\n <app-techlify-icon name=\"edit\" class=\"clickable\" size=\"xs\" style=\"margin-left:2px\"></app-techlify-icon>\n </mat-hint>\n <mat-date-range-input class=\"offscreen-range-input\" [rangePicker]=\"picker\">\n <input matStartDate formControlName=\"custom_date_from\" placeholder=\"From date\" readonly />\n <input matEndDate formControlName=\"custom_date_to\" placeholder=\"To date\" readonly />\n </mat-date-range-input>\n <mat-date-range-picker #picker></mat-date-range-picker>\n </mat-form-field>\n</ng-container>", styles: [".icon-md{height:24px!important;width:24px!important;font-size:24px!important;margin:0 1px}.icon-sm{height:20px!important;width:20px!important;font-size:20px!important}.icon-xs{height:16px!important;width:16px!important;font-size:16px!important}.fl-md{width:200px!important}.fl-md .mat-mdc-form-field{width:100%!important}.fl-sm{width:150px!important}.fl-sm .mat-mdc-form-field{width:100%!important}.mat-btn-md{height:25px!important;padding:0 8px!important}.fs-12{font-size:12px!important}.fs-16{font-size:16px!important}.fs-13{font-size:13px!important}.fs-18{font-size:18px!important}.clickable:hover{cursor:pointer}.mat-mdc-form-field-hint-wrapper{padding:0 4px!important}.nil-subscript-wrapper .mat-mdc-form-field-subscript-wrapper{height:0!important}.create-another .mat-mdc-checkbox label{margin:0!important}.create-another .mdc-checkbox{padding:0!important}.create-another .mdc-checkbox__background{position:relative;top:0;left:0}.offscreen-range-input{position:absolute;opacity:0;pointer-events:none;display:flex!important}\n"], dependencies: [{ kind: "directive", type: i3.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i6$1.DefaultLayoutDirective, selector: " [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]", inputs: ["fxLayout", "fxLayout.xs", "fxLayout.sm", "fxLayout.md", "fxLayout.lg", "fxLayout.xl", "fxLayout.lt-sm", "fxLayout.lt-md", "fxLayout.lt-lg", "fxLayout.lt-xl", "fxLayout.gt-xs", "fxLayout.gt-sm", "fxLayout.gt-md", "fxLayout.gt-lg"] }, { kind: "directive", type: i1$5.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$5.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$5.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1$5.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$5.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "component", type: i8$4.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i8$4.MatLabel, selector: "mat-label" }, { kind: "directive", type: i8$4.MatHint, selector: "mat-hint", inputs: ["align", "id"] }, { kind: "directive", type: i8$4.MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { kind: "component", type: i9$1.MatSelect, selector: "mat-select", inputs: ["aria-describedby", "panelClass", "disabled", "disableRipple", "tabIndex", "hideSingleSelectionIndicator", "placeholder", "required", "multiple", "disableOptionCentering", "compareWith", "value", "aria-label", "aria-labelledby", "errorStateMatcher", "typeaheadDebounceInterval", "sortComparator", "id", "panelWidth"], outputs: ["openedChange", "opened", "closed", "selectionChange", "valueChange"], exportAs: ["matSelect"] }, { kind: "component", type: i5.MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "component", type: i6.MatIconButton, selector: "button[mat-icon-button]", exportAs: ["matButton"] }, { kind: "component", type: i8.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: i11$1.MatDateRangeInput, selector: "mat-date-range-input", inputs: ["rangePicker", "required", "dateFilter", "min", "max", "disabled", "separator", "comparisonStart", "comparisonEnd"], exportAs: ["matDateRangeInput"] }, { kind: "directive", type: i11$1.MatStartDate, selector: "input[matStartDate]", outputs: ["dateChange", "dateInput"] }, { kind: "directive", type: i11$1.MatEndDate, selector: "input[matEndDate]", outputs: ["dateChange", "dateInput"] }, { kind: "component", type: i11$1.MatDateRangePicker, selector: "mat-date-range-picker", exportAs: ["matDateRangePicker"] }, { kind: "component", type: TechlifyIconComponent, selector: "app-techlify-icon", inputs: ["name", "size"] }] }); }
3788
+ };
3789
+ TimelineFilterComponent = TimelineFilterComponent_1 = __decorate([
3790
+ UntilDestroy()
3791
+ ], TimelineFilterComponent);
3792
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: TimelineFilterComponent, decorators: [{
3937
3793
  type: Component,
3938
- args: [{ selector: "app-comment-form", template: "<form (ngSubmit)=\"submit()\" [formGroup]=\"commentFormGroup\">\n <div fxLayout=\"column\" class=\"my-2\" [ngClass]=\"{ 'border border-primary shadow rounded ': view}\">\n <div *ngIf=\"!view\" fxLayout=\"column\">\n <mat-form-field appearance=\"outline\" style=\"background-color:white;\">\n <mat-label>Comment</mat-label>\n <textarea matInput rows=\"5\" placeholder=\"Add a comment...\" formControlName=\"note\" autocomplete=\"off\"></textarea>\n </mat-form-field>\n\n <div fxLayout fxLayoutGap=\"1rem\" class=\"mt-2\">\n <span fxFlex></span>\n <button *ngIf=\"_commentData\" mat-button type=\"button\" (click)=\"view = !view\">\n Cancel\n </button>\n <button mat-raised-button color=\"primary\" type=\"submit\">\n {{ _commentData ? \"Update\" : \"Post comment\" }}\n </button>\n </div>\n </div>\n\n <div fxLayout=\"column\" *ngIf=\"view\" class=\"p-2 m-2\">\n <div fxLayout=\"row wrap\" fxLayoutGap=\".5rem\">\n <div fxFlex=\"20%\" fxLayoutAlign=\"start\">\n <button mat-icon-button type=\"button\" style=\"color:grey\">\n <mat-icon style=\"font-size:60px\">account_circle</mat-icon>\n </button>\n </div>\n <div fxFlex=\"75%\">\n <div fxLayout=\"column\" fxLayoutGap=\".5rem\">\n <div class=\"font-weight-bold\">{{ _commentData?.creator?.name }}</div>\n <div class=\"text-muted\">{{ _commentData.updated_at | date:'medium' }}</div>\n </div>\n </div>\n </div>\n <app-read-more class=\"mt-2\" [text]=\"_commentData.note\"></app-read-more>\n <div fxLayout class=\"mt-1\" fxLayoutGap=\"1rem\" *ngIf=\"isLoggedIn && currentUser.id === _commentData.creator_id\">\n <a href=\"javascript:;\" (click)=\"editComment()\">\n Edit\n </a>\n <a href=\"javascript:;\" (click)=\"deleteComment()\">\n Delete\n </a>\n </div>\n </div>\n </div>\n</form>", styles: [":host ::ng-deep .mat-form-field-wrapper{padding-bottom:0!important;margin:0!important}\n"] }]
3939
- }], ctorParameters: () => [{ type: i1$5.UntypedFormBuilder }, { type: CredentialsService }], propDecorators: { commentData: [{
3794
+ args: [{ selector: 'app-timeline-filter', providers: [
3795
+ DatePipe,
3796
+ {
3797
+ provide: MatFormFieldControl,
3798
+ useExisting: TimelineFilterComponent
3799
+ }
3800
+ ], template: "<ng-container [formGroup]=\"selectorForm\">\n <mat-form-field [appearance]=\"appearance\" class=\"fl-sm\">\n <mat-label>{{labelText}}</mat-label>\n <mat-select formControlName=\"select_value\">\n <mat-option *ngFor=\"let timeline of timelines\" [value]=\"timeline.value\">\n {{timeline.viewValue}}\n </mat-option>\n </mat-select>\n <button *ngIf=\"showClearButton && timelineValue.value\" matSuffix mat-icon-button\n (click)=\"timelineValue.setValue('')\">\n <mat-icon>close</mat-icon>\n </button>\n <mat-hint *ngIf=\"isCustomSelected && selectedRangeLabel\" (click)=\"openCalendar()\" class=\"clickable\" fxLayout>\n <span [innerHTML]=\"selectedRangeLabel\" style=\"font-size: 10px;\"></span>\n <app-techlify-icon name=\"edit\" class=\"clickable\" size=\"xs\" style=\"margin-left:2px\"></app-techlify-icon>\n </mat-hint>\n <mat-hint *ngIf=\"isCustomSelected && !selectedRangeLabel\" (click)=\"openCalendar()\" class=\"clickable\" fxLayout>\n <span style=\"font-size: 10px;\">Select Range</span>\n <app-techlify-icon name=\"edit\" class=\"clickable\" size=\"xs\" style=\"margin-left:2px\"></app-techlify-icon>\n </mat-hint>\n <mat-date-range-input class=\"offscreen-range-input\" [rangePicker]=\"picker\">\n <input matStartDate formControlName=\"custom_date_from\" placeholder=\"From date\" readonly />\n <input matEndDate formControlName=\"custom_date_to\" placeholder=\"To date\" readonly />\n </mat-date-range-input>\n <mat-date-range-picker #picker></mat-date-range-picker>\n </mat-form-field>\n</ng-container>", styles: [".icon-md{height:24px!important;width:24px!important;font-size:24px!important;margin:0 1px}.icon-sm{height:20px!important;width:20px!important;font-size:20px!important}.icon-xs{height:16px!important;width:16px!important;font-size:16px!important}.fl-md{width:200px!important}.fl-md .mat-mdc-form-field{width:100%!important}.fl-sm{width:150px!important}.fl-sm .mat-mdc-form-field{width:100%!important}.mat-btn-md{height:25px!important;padding:0 8px!important}.fs-12{font-size:12px!important}.fs-16{font-size:16px!important}.fs-13{font-size:13px!important}.fs-18{font-size:18px!important}.clickable:hover{cursor:pointer}.mat-mdc-form-field-hint-wrapper{padding:0 4px!important}.nil-subscript-wrapper .mat-mdc-form-field-subscript-wrapper{height:0!important}.create-another .mat-mdc-checkbox label{margin:0!important}.create-another .mdc-checkbox{padding:0!important}.create-another .mdc-checkbox__background{position:relative;top:0;left:0}.offscreen-range-input{position:absolute;opacity:0;pointer-events:none;display:flex!important}\n"] }]
3801
+ }], ctorParameters: () => [{ type: i1$5.UntypedFormBuilder }, { type: i1$5.NgControl, decorators: [{
3802
+ type: Optional
3803
+ }, {
3804
+ type: Self
3805
+ }] }, { type: i3.DatePipe }], propDecorators: { defaultValue: [{
3940
3806
  type: Input
3941
- }], action: [{
3807
+ }], required: [{
3808
+ type: Input
3809
+ }], disabled: [{
3810
+ type: Input
3811
+ }], value: [{
3812
+ type: Input
3813
+ }], picker: [{
3814
+ type: ViewChild,
3815
+ args: ['picker']
3816
+ }], timelines: [{
3817
+ type: Input
3818
+ }], dateFrom: [{
3819
+ type: Input
3820
+ }], dateTo: [{
3821
+ type: Input
3822
+ }], appearance: [{
3823
+ type: Input
3824
+ }], showClearButton: [{
3825
+ type: Input
3826
+ }], form: [{
3827
+ type: Input
3828
+ }], labelText: [{
3829
+ type: Input
3830
+ }], selectionChange: [{
3942
3831
  type: Output
3943
3832
  }] } });
3944
3833
 
3945
- class NoteListComponent extends TechlifyListComponent {
3946
- constructor(noteService, dialog, alertService) {
3947
- super();
3948
- this.noteService = noteService;
3949
- this.dialog = dialog;
3950
- this.alertService = alertService;
3951
- this.readonly = false;
3952
- this.labelText = 'Note';
3953
- this.commentsView = false;
3954
- this.viewMode = 'list';
3955
- this.displayedColumns = [
3956
- 'index',
3957
- 'note',
3958
- 'actions'
3959
- ];
3960
- this.isSaving = false;
3961
- this.total = 0;
3962
- this.lastPage = 0;
3963
- this.filters = {};
3964
- this.filters.sort_by = 'created_at|DESC';
3965
- }
3966
- ngOnInit() {
3967
- if (this.readonly) {
3968
- this.displayedColumns = this.displayedColumns.filter(x => x !== 'actions');
3969
- }
3970
- this.filters.related_model_id = this.relatedModelId;
3971
- this.filters.model_type = this.modelType;
3972
- this.loadData();
3973
- }
3974
- loadData() {
3975
- this.isWorking = true;
3976
- this.noteService.getNotes({
3977
- ...this.filters,
3978
- page: this.page,
3979
- with: 'creator'
3980
- }).then((result) => {
3981
- this.models = this.models.concat(result?.data);
3982
- this.lastPage = result?.last_page;
3983
- this.isWorking = false;
3984
- this.total = result?.total;
3985
- }, () => {
3986
- this.isWorking = false;
3987
- });
3834
+ class TechlifyFormButtonComponent {
3835
+ constructor(matDialog) {
3836
+ this.matDialog = matDialog;
3837
+ this.component = input.required();
3838
+ this.model = input();
3839
+ this.data = input({});
3840
+ this.width = input('700px');
3841
+ this.saved = output();
3988
3842
  }
3989
- addNote() {
3990
- const dialogRef = this.dialog.open(NoteFormComponent, {
3991
- width: '400px',
3992
- data: {
3993
- note: { related_model_id: this.relatedModelId, model_type: this.modelType },
3994
- labelText: this.labelText,
3995
- },
3996
- autoFocus: false
3843
+ open() {
3844
+ const ref = this.matDialog.open(this.component(), {
3845
+ width: this.width(),
3846
+ data: { model: this.model(), ...this.data() }
3997
3847
  });
3998
- dialogRef.afterClosed().subscribe(result => {
3848
+ ref.afterClosed().subscribe((result) => {
3999
3849
  if (result) {
4000
- this.reload();
3850
+ this.saved.emit(result);
4001
3851
  }
4002
3852
  });
4003
3853
  }
4004
- editNote(note) {
4005
- const dialogRef = this.dialog.open(NoteFormComponent, {
4006
- width: '400px',
4007
- data: {
4008
- note,
4009
- update: true,
4010
- labelText: this.labelText
4011
- },
4012
- autoFocus: false
4013
- });
4014
- dialogRef.afterClosed().subscribe(result => {
4015
- if (result) {
4016
- this.reload();
4017
- }
4018
- });
3854
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: TechlifyFormButtonComponent, deps: [{ token: i1.MatDialog }], target: i0.ɵɵFactoryTarget.Component }); }
3855
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "18.2.14", type: TechlifyFormButtonComponent, isStandalone: true, selector: "app-techlify-form-button", inputs: { component: { classPropertyName: "component", publicName: "component", isSignal: true, isRequired: true, transformFunction: null }, model: { classPropertyName: "model", publicName: "model", isSignal: true, isRequired: false, transformFunction: null }, data: { classPropertyName: "data", publicName: "data", isSignal: true, isRequired: false, transformFunction: null }, width: { classPropertyName: "width", publicName: "width", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { saved: "saved" }, ngImport: i0, template: "<app-techlify-icon role=\"button\" [name]=\"model() ? 'edit' : 'add'\" (click)=\"open()\"></app-techlify-icon>\r\n", dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: MaterialModule }, { kind: "ngmodule", type: TechlifyIconModule }, { kind: "component", type: TechlifyIconComponent, selector: "app-techlify-icon", inputs: ["name", "size"] }] }); }
3856
+ }
3857
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: TechlifyFormButtonComponent, decorators: [{
3858
+ type: Component,
3859
+ args: [{ selector: 'app-techlify-form-button', standalone: true, imports: [
3860
+ CommonModule,
3861
+ MaterialModule,
3862
+ TechlifyIconModule
3863
+ ], template: "<app-techlify-icon role=\"button\" [name]=\"model() ? 'edit' : 'add'\" (click)=\"open()\"></app-techlify-icon>\r\n" }]
3864
+ }], ctorParameters: () => [{ type: i1.MatDialog }] });
3865
+
3866
+ class ReadMoreComponent {
3867
+ constructor() {
3868
+ this.maxLength = 100;
3869
+ this.hideToggle = true;
3870
+ this.isCollapsed = true;
4019
3871
  }
4020
- async deleteNote(note) {
4021
- const dialogRef = this.dialog.open(ActionPopupComponent, {
4022
- width: '400px',
4023
- data: {
4024
- title: `Delete ${this.labelText}`,
4025
- message: `Are you sure to delete?`
4026
- },
4027
- autoFocus: false
4028
- });
4029
- dialogRef.afterClosed().subscribe(async (result) => {
4030
- if (result) {
4031
- // Action confirmed
4032
- await this.noteService.deleteNote(note);
4033
- this.models = this.models.filter((item) => item.id !== note.id);
4034
- }
4035
- });
3872
+ ngOnInit() {
3873
+ this.determineView();
4036
3874
  }
4037
- commentAction(event) {
4038
- if (event.type === 'save') {
4039
- if (event.value.id) {
4040
- this.editComment(event.value);
4041
- return;
4042
- }
4043
- this.addComment(event.value);
3875
+ toggleView() {
3876
+ this.isCollapsed = !this.isCollapsed;
3877
+ this.determineView();
3878
+ }
3879
+ determineView() {
3880
+ if (!this.text || this.text.length <= this.maxLength) {
3881
+ this.currentText = this.text;
3882
+ this.isCollapsed = false;
3883
+ this.hideToggle = true;
4044
3884
  return;
4045
3885
  }
4046
- this.deleteNote(event.value);
4047
- }
4048
- async editComment(comment) {
4049
- const result = await this.noteService.editNote(comment);
4050
- const index = this.models.findIndex((x) => x.id === comment.id);
4051
- if (index !== -1) {
4052
- this.models[index] = result.item;
3886
+ this.hideToggle = false;
3887
+ if (this.isCollapsed == true) {
3888
+ this.currentText = this.text.substring(0, this.maxLength) + "...";
4053
3889
  }
4054
- }
4055
- async addComment(comment) {
4056
- comment.related_model_id = this.relatedModelId;
4057
- comment.model_type = this.modelType;
4058
- const result = await this.noteService.addNote(comment);
4059
- this.models.push(result.item);
4060
- }
4061
- saveNote() {
4062
- if (!this.note) {
4063
- this.alertService.addAlert('Please enter the note', 'error');
4064
- return;
3890
+ else if (this.isCollapsed == false) {
3891
+ this.currentText = this.text;
4065
3892
  }
4066
- const data = {
4067
- note: this.note,
4068
- model_type: this.modelType,
4069
- related_model_id: this.relatedModelId,
4070
- with: 'creator',
4071
- };
4072
- this.isSaving = true;
4073
- this.noteService.addNote(data).then((response) => {
4074
- this.modelCreated(response?.item);
4075
- this.alertService.addAlert('The note saved successfully.', 'success');
4076
- this.note = '';
4077
- this.isSaving = false;
4078
- this.total += 1;
4079
- }).catch(() => (this.isSaving = false));
4080
3893
  }
4081
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: NoteListComponent, deps: [{ token: NoteService }, { token: i1.MatDialog }, { token: AlertService }], target: i0.ɵɵFactoryTarget.Component }); }
4082
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.14", type: NoteListComponent, selector: "app-note-list", inputs: { relatedModelId: "relatedModelId", modelType: "modelType", readonly: "readonly", labelText: "labelText", commentsView: "commentsView", viewMode: "viewMode" }, usesInheritance: true, ngImport: i0, template: "<div fxLayout=\"column\" fxLayoutGap=\"1.5rem\" *ngIf=\"!commentsView\">\n\n <ng-container *ngIf=\"viewMode === 'list'\">\n <div class=\"d-flex align-items-center\">\n <h5 class=\"m-0\">{{ labelText }}s</h5>\n <app-techlify-icon name=\"add\" class=\"clickable d-print-none ml-1\" matTooltip=\"Add\"\n (click)=\"addNote()\"></app-techlify-icon>\n </div>\n\n <div class=\"w-100 scroll-container\" infiniteScroll [infiniteScrollDistance]=\"1\" [infiniteScrollThrottle]=\"50\"\n (scrolled)=\"onScroll()\" [scrollWindow]=\"false\">\n <table mat-table [dataSource]=\"models\" class=\"w-100\" multiTemplateDataRows>\n\n <!-- Index Column -->\n <ng-container matColumnDef=\"index\">\n <th mat-header-cell *matHeaderCellDef> #</th>\n <td mat-cell *matCellDef=\"let note; let i = dataIndex\"> {{ i + 1 }}</td>\n </ng-container>\n\n\n <ng-container matColumnDef=\"note\">\n <th mat-header-cell *matHeaderCellDef> {{ labelText }}</th>\n <td mat-cell *matCellDef=\"let note\">\n {{ note?.note }}\n </td>\n </ng-container>\n\n <ng-container matColumnDef=\"actions\">\n <th mat-header-cell *matHeaderCellDef class=\"d-print-none\"> Actions</th>\n <td mat-cell *matCellDef=\"let note\" class=\"d-print-none text-secondary\">\n <div fxLayoutAlign=\"start center\">\n <app-techlify-icon name=\"edit\" class=\"clickable\" matTooltip=\"Update\"\n (click)=\"editNote(note)\"></app-techlify-icon>\n <app-techlify-icon name=\"delete\" class=\"clickable ml-1\" matTooltip=\"Delete\"\n (click)=\"deleteNote(note)\"></app-techlify-icon>\n </div>\n </td>\n </ng-container>\n <tr mat-header-row *matHeaderRowDef=\"displayedColumns\"></tr>\n <tr mat-row *matRowDef=\"let row; columns: displayedColumns;\"></tr>\n </table>\n <mat-progress-bar mode=\"indeterminate\" *ngIf=\"isWorking\"></mat-progress-bar>\n </div>\n </ng-container>\n\n <ng-container *ngIf=\"viewMode === 'timeline'\">\n <mat-card>\n <mat-card-content class=\"d-flex justify-content-start align-items-center gap-2\">\n <h5 class=\"mb-0\">Notes</h5>\n <span class=\"badge badge-info ml-1\" *ngIf=\"total\">{{ total }}</span>\n </mat-card-content>\n <mat-card-content class=\"mt-2\">\n <form (ngSubmit)=\"saveNote()\">\n <mat-form-field class=\"w-100\" appearance=\"outline\">\n <input [(ngModel)]=\"note\" [ngModelOptions]=\"{standalone: true}\" type=\"text\" matInput\n placeholder=\"Write your notes here...\" [disabled]=\"isSaving\">\n <mat-icon *ngIf=\"!isSaving\" matSuffix class=\"cursor-pointer\" (click)=\"saveNote()\">send</mat-icon>\n <mat-progress-spinner matSuffix mode=\"indeterminate\" diameter=\"20\" *ngIf=\"isSaving\"></mat-progress-spinner>\n </mat-form-field>\n </form>\n </mat-card-content>\n <mat-card-content>\n <div *ngFor=\"let note of models;last as isLast\">\n <div class=\"d-flex justify-content-between align-items-center gap-2\">\n <div class=\"d-flex flex-column\">\n <p class=\"mb-0\">{{ note?.creator?.name }}</p>\n <small class=\"text-secondary\">On {{ note?.created_at | date: 'medium' }}</small>\n </div>\n <div class=\"d-flex justify-content-end align-items-center gap-1\">\n <app-techlify-icon name=\"edit\" class=\"clickable\" matTooltip=\"Update\"\n (click)=\"editNote(note)\"></app-techlify-icon>\n <app-techlify-icon name=\"delete\" class=\"clickable\" matTooltip=\"Delete\"\n (click)=\"deleteNote(note)\"></app-techlify-icon>\n </div>\n </div>\n <div>{{ note?.note }}</div>\n <mat-divider class=\"my-2\" *ngIf=\"!isLast\"></mat-divider>\n </div>\n <mat-progress-bar mode=\"indeterminate\" *ngIf=\"isWorking\"></mat-progress-bar>\n </mat-card-content>\n </mat-card>\n </ng-container>\n\n</div>\n\n<div fxLayout=\"column\" fxLayoutGap=\"1.5rem\" *ngIf=\"commentsView\">\n <div fxLayout fxLayoutAlign=\"center center\" fxLayoutGap=\"1rem\">\n <h5 class=\"m-0\">{{ labelText }}s</h5>\n </div>\n\n <div fxLayout=\"column\" fxLayoutAlign=\"start\" fxFlex=\"100%\">\n <div class=\"w-100 scroll-container jumbotron\" infiniteScroll [infiniteScrollDistance]=\"1\"\n [infiniteScrollThrottle]=\"50\" (scrolled)=\"onScroll()\" [scrollWindow]=\"false\">\n <app-comment-form [commentData]=\"comment\" (action)=\"commentAction($event)\" *ngFor=\"let comment of models\">\n </app-comment-form>\n <app-comment-form (action)=\"commentAction($event)\"></app-comment-form>\n </div>\n </div>\n</div>", styles: [".scroll-container{max-height:400px;overflow-y:auto}\n"], dependencies: [{ kind: "directive", type: i3.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1$5.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1$5.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$5.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$5.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i6$2.InfiniteScrollDirective, selector: "[infiniteScroll], [infinite-scroll], [data-infinite-scroll]", inputs: ["infiniteScrollDistance", "infiniteScrollUpDistance", "infiniteScrollThrottle", "infiniteScrollDisabled", "infiniteScrollContainer", "scrollWindow", "immediateCheck", "horizontal", "alwaysCallback", "fromRoot"], outputs: ["scrolled", "scrolledUp"] }, { kind: "directive", type: i6$1.DefaultLayoutDirective, selector: " [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]", inputs: ["fxLayout", "fxLayout.xs", "fxLayout.sm", "fxLayout.md", "fxLayout.lg", "fxLayout.xl", "fxLayout.lt-sm", "fxLayout.lt-md", "fxLayout.lt-lg", "fxLayout.lt-xl", "fxLayout.gt-xs", "fxLayout.gt-sm", "fxLayout.gt-md", "fxLayout.gt-lg"] }, { kind: "directive", type: i6$1.DefaultLayoutGapDirective, selector: " [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]", inputs: ["fxLayoutGap", "fxLayoutGap.xs", "fxLayoutGap.sm", "fxLayoutGap.md", "fxLayoutGap.lg", "fxLayoutGap.xl", "fxLayoutGap.lt-sm", "fxLayoutGap.lt-md", "fxLayoutGap.lt-lg", "fxLayoutGap.lt-xl", "fxLayoutGap.gt-xs", "fxLayoutGap.gt-sm", "fxLayoutGap.gt-md", "fxLayoutGap.gt-lg"] }, { kind: "directive", type: i6$1.DefaultLayoutAlignDirective, selector: " [fxLayoutAlign], [fxLayoutAlign.xs], [fxLayoutAlign.sm], [fxLayoutAlign.md], [fxLayoutAlign.lg], [fxLayoutAlign.xl], [fxLayoutAlign.lt-sm], [fxLayoutAlign.lt-md], [fxLayoutAlign.lt-lg], [fxLayoutAlign.lt-xl], [fxLayoutAlign.gt-xs], [fxLayoutAlign.gt-sm], [fxLayoutAlign.gt-md], [fxLayoutAlign.gt-lg]", inputs: ["fxLayoutAlign", "fxLayoutAlign.xs", "fxLayoutAlign.sm", "fxLayoutAlign.md", "fxLayoutAlign.lg", "fxLayoutAlign.xl", "fxLayoutAlign.lt-sm", "fxLayoutAlign.lt-md", "fxLayoutAlign.lt-lg", "fxLayoutAlign.lt-xl", "fxLayoutAlign.gt-xs", "fxLayoutAlign.gt-sm", "fxLayoutAlign.gt-md", "fxLayoutAlign.gt-lg"] }, { kind: "directive", type: i6$1.DefaultFlexDirective, selector: " [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]", inputs: ["fxFlex", "fxFlex.xs", "fxFlex.sm", "fxFlex.md", "fxFlex.lg", "fxFlex.xl", "fxFlex.lt-sm", "fxFlex.lt-md", "fxFlex.lt-lg", "fxFlex.lt-xl", "fxFlex.gt-xs", "fxFlex.gt-sm", "fxFlex.gt-md", "fxFlex.gt-lg"] }, { kind: "component", type: i8$4.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i8$4.MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { kind: "component", type: i8.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "directive", type: i9.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly"], exportAs: ["matInput"] }, { kind: "component", type: i11$3.MatProgressSpinner, selector: "mat-progress-spinner, mat-spinner", inputs: ["color", "mode", "value", "diameter", "strokeWidth"], exportAs: ["matProgressSpinner"] }, { kind: "component", type: i12.MatTable, selector: "mat-table, table[mat-table]", exportAs: ["matTable"] }, { kind: "directive", type: i12.MatHeaderCellDef, selector: "[matHeaderCellDef]" }, { kind: "directive", type: i12.MatHeaderRowDef, selector: "[matHeaderRowDef]", inputs: ["matHeaderRowDef", "matHeaderRowDefSticky"] }, { kind: "directive", type: i12.MatColumnDef, selector: "[matColumnDef]", inputs: ["matColumnDef"] }, { kind: "directive", type: i12.MatCellDef, selector: "[matCellDef]" }, { kind: "directive", type: i12.MatRowDef, selector: "[matRowDef]", inputs: ["matRowDefColumns", "matRowDefWhen"] }, { kind: "directive", type: i12.MatHeaderCell, selector: "mat-header-cell, th[mat-header-cell]" }, { kind: "directive", type: i12.MatCell, selector: "mat-cell, td[mat-cell]" }, { kind: "component", type: i12.MatHeaderRow, selector: "mat-header-row, tr[mat-header-row]", exportAs: ["matHeaderRow"] }, { kind: "component", type: i12.MatRow, selector: "mat-row, tr[mat-row]", exportAs: ["matRow"] }, { kind: "component", type: i4.MatCard, selector: "mat-card", inputs: ["appearance"], exportAs: ["matCard"] }, { kind: "directive", type: i4.MatCardContent, selector: "mat-card-content" }, { kind: "component", type: i6$3.MatDivider, selector: "mat-divider", inputs: ["vertical", "inset"] }, { kind: "directive", type: i10.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "component", type: i11$2.MatProgressBar, selector: "mat-progress-bar", inputs: ["color", "value", "bufferValue", "mode"], outputs: ["animationEnd"], exportAs: ["matProgressBar"] }, { kind: "directive", type: i1$5.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: i1$5.NgForm, selector: "form:not([ngNoForm]):not([formGroup]),ng-form,[ngForm]", inputs: ["ngFormOptions"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "component", type: TechlifyIconComponent, selector: "app-techlify-icon", inputs: ["name", "size"] }, { kind: "component", type: CommentFormComponent, selector: "app-comment-form", inputs: ["commentData"], outputs: ["action"] }, { kind: "pipe", type: i3.DatePipe, name: "date" }] }); }
3894
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ReadMoreComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
3895
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.14", type: ReadMoreComponent, selector: "app-read-more", inputs: { text: "text", maxLength: "maxLength" }, ngImport: i0, template: "<div [innerHTML]=\"currentText\"></div>\n<a href=\"javascript:;\" *ngIf=\"!hideToggle\" class=\"primary-color hoverable\" (click)=\"toggleView()\">Read\n {{ isCollapsed ? \"more\" : \"less\" }}</a>", styles: ["div.collapsed{height:250px;overflow:hidden}.primary-color{color:#009fdd!important}\n"], dependencies: [{ kind: "directive", type: i3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }] }); }
4083
3896
  }
4084
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: NoteListComponent, decorators: [{
3897
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ReadMoreComponent, decorators: [{
4085
3898
  type: Component,
4086
- args: [{ selector: 'app-note-list', template: "<div fxLayout=\"column\" fxLayoutGap=\"1.5rem\" *ngIf=\"!commentsView\">\n\n <ng-container *ngIf=\"viewMode === 'list'\">\n <div class=\"d-flex align-items-center\">\n <h5 class=\"m-0\">{{ labelText }}s</h5>\n <app-techlify-icon name=\"add\" class=\"clickable d-print-none ml-1\" matTooltip=\"Add\"\n (click)=\"addNote()\"></app-techlify-icon>\n </div>\n\n <div class=\"w-100 scroll-container\" infiniteScroll [infiniteScrollDistance]=\"1\" [infiniteScrollThrottle]=\"50\"\n (scrolled)=\"onScroll()\" [scrollWindow]=\"false\">\n <table mat-table [dataSource]=\"models\" class=\"w-100\" multiTemplateDataRows>\n\n <!-- Index Column -->\n <ng-container matColumnDef=\"index\">\n <th mat-header-cell *matHeaderCellDef> #</th>\n <td mat-cell *matCellDef=\"let note; let i = dataIndex\"> {{ i + 1 }}</td>\n </ng-container>\n\n\n <ng-container matColumnDef=\"note\">\n <th mat-header-cell *matHeaderCellDef> {{ labelText }}</th>\n <td mat-cell *matCellDef=\"let note\">\n {{ note?.note }}\n </td>\n </ng-container>\n\n <ng-container matColumnDef=\"actions\">\n <th mat-header-cell *matHeaderCellDef class=\"d-print-none\"> Actions</th>\n <td mat-cell *matCellDef=\"let note\" class=\"d-print-none text-secondary\">\n <div fxLayoutAlign=\"start center\">\n <app-techlify-icon name=\"edit\" class=\"clickable\" matTooltip=\"Update\"\n (click)=\"editNote(note)\"></app-techlify-icon>\n <app-techlify-icon name=\"delete\" class=\"clickable ml-1\" matTooltip=\"Delete\"\n (click)=\"deleteNote(note)\"></app-techlify-icon>\n </div>\n </td>\n </ng-container>\n <tr mat-header-row *matHeaderRowDef=\"displayedColumns\"></tr>\n <tr mat-row *matRowDef=\"let row; columns: displayedColumns;\"></tr>\n </table>\n <mat-progress-bar mode=\"indeterminate\" *ngIf=\"isWorking\"></mat-progress-bar>\n </div>\n </ng-container>\n\n <ng-container *ngIf=\"viewMode === 'timeline'\">\n <mat-card>\n <mat-card-content class=\"d-flex justify-content-start align-items-center gap-2\">\n <h5 class=\"mb-0\">Notes</h5>\n <span class=\"badge badge-info ml-1\" *ngIf=\"total\">{{ total }}</span>\n </mat-card-content>\n <mat-card-content class=\"mt-2\">\n <form (ngSubmit)=\"saveNote()\">\n <mat-form-field class=\"w-100\" appearance=\"outline\">\n <input [(ngModel)]=\"note\" [ngModelOptions]=\"{standalone: true}\" type=\"text\" matInput\n placeholder=\"Write your notes here...\" [disabled]=\"isSaving\">\n <mat-icon *ngIf=\"!isSaving\" matSuffix class=\"cursor-pointer\" (click)=\"saveNote()\">send</mat-icon>\n <mat-progress-spinner matSuffix mode=\"indeterminate\" diameter=\"20\" *ngIf=\"isSaving\"></mat-progress-spinner>\n </mat-form-field>\n </form>\n </mat-card-content>\n <mat-card-content>\n <div *ngFor=\"let note of models;last as isLast\">\n <div class=\"d-flex justify-content-between align-items-center gap-2\">\n <div class=\"d-flex flex-column\">\n <p class=\"mb-0\">{{ note?.creator?.name }}</p>\n <small class=\"text-secondary\">On {{ note?.created_at | date: 'medium' }}</small>\n </div>\n <div class=\"d-flex justify-content-end align-items-center gap-1\">\n <app-techlify-icon name=\"edit\" class=\"clickable\" matTooltip=\"Update\"\n (click)=\"editNote(note)\"></app-techlify-icon>\n <app-techlify-icon name=\"delete\" class=\"clickable\" matTooltip=\"Delete\"\n (click)=\"deleteNote(note)\"></app-techlify-icon>\n </div>\n </div>\n <div>{{ note?.note }}</div>\n <mat-divider class=\"my-2\" *ngIf=\"!isLast\"></mat-divider>\n </div>\n <mat-progress-bar mode=\"indeterminate\" *ngIf=\"isWorking\"></mat-progress-bar>\n </mat-card-content>\n </mat-card>\n </ng-container>\n\n</div>\n\n<div fxLayout=\"column\" fxLayoutGap=\"1.5rem\" *ngIf=\"commentsView\">\n <div fxLayout fxLayoutAlign=\"center center\" fxLayoutGap=\"1rem\">\n <h5 class=\"m-0\">{{ labelText }}s</h5>\n </div>\n\n <div fxLayout=\"column\" fxLayoutAlign=\"start\" fxFlex=\"100%\">\n <div class=\"w-100 scroll-container jumbotron\" infiniteScroll [infiniteScrollDistance]=\"1\"\n [infiniteScrollThrottle]=\"50\" (scrolled)=\"onScroll()\" [scrollWindow]=\"false\">\n <app-comment-form [commentData]=\"comment\" (action)=\"commentAction($event)\" *ngFor=\"let comment of models\">\n </app-comment-form>\n <app-comment-form (action)=\"commentAction($event)\"></app-comment-form>\n </div>\n </div>\n</div>", styles: [".scroll-container{max-height:400px;overflow-y:auto}\n"] }]
4087
- }], ctorParameters: () => [{ type: NoteService }, { type: i1.MatDialog }, { type: AlertService }], propDecorators: { relatedModelId: [{
4088
- type: Input
4089
- }], modelType: [{
4090
- type: Input
4091
- }], readonly: [{
4092
- type: Input
4093
- }], labelText: [{
4094
- type: Input
4095
- }], commentsView: [{
3899
+ args: [{ selector: "app-read-more", template: "<div [innerHTML]=\"currentText\"></div>\n<a href=\"javascript:;\" *ngIf=\"!hideToggle\" class=\"primary-color hoverable\" (click)=\"toggleView()\">Read\n {{ isCollapsed ? \"more\" : \"less\" }}</a>", styles: ["div.collapsed{height:250px;overflow:hidden}.primary-color{color:#009fdd!important}\n"] }]
3900
+ }], ctorParameters: () => [], propDecorators: { text: [{
4096
3901
  type: Input
4097
- }], viewMode: [{
3902
+ }], maxLength: [{
4098
3903
  type: Input
4099
3904
  }] } });
4100
3905
 
4101
- class SearchableSelectorComponent {
4102
- static { this.nextId = 0; }
4103
- get empty() {
4104
- const { value: { select_value } } = this.selectorForm;
4105
- return !select_value;
4106
- }
4107
- get shouldLabelFloat() { return this.focused || !this.empty; }
4108
- get required() { return this._required; }
4109
- set required(value) {
4110
- this.selectorForm.get('select_value').setValidators(Validators.required);
4111
- this._required = coerceBooleanProperty(value);
4112
- this.stateChanges.next();
3906
+ class WrapPipe {
3907
+ transform(value, length = 50) {
3908
+ if (!value) {
3909
+ return '';
3910
+ }
3911
+ return value.length > length ? value.substring(0, length) + '...' : value;
4113
3912
  }
4114
- get disabled() { return this._disabled; }
4115
- set disabled(value) {
4116
- this._disabled = coerceBooleanProperty(value);
4117
- this._disabled ? this.selectorForm.disable() : this.selectorForm.enable();
4118
- this.stateChanges.next();
3913
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: WrapPipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe }); }
3914
+ static { this.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "18.2.14", ngImport: i0, type: WrapPipe, isStandalone: true, name: "wrap" }); }
3915
+ }
3916
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: WrapPipe, decorators: [{
3917
+ type: Pipe,
3918
+ args: [{
3919
+ name: 'wrap',
3920
+ standalone: true
3921
+ }]
3922
+ }] });
3923
+
3924
+ class FileSizePipe {
3925
+ transform(bytes) {
3926
+ if (!bytes) {
3927
+ return '0.00 B';
3928
+ }
3929
+ const exponent = Math.floor(Math.log(bytes) / Math.log(1024));
3930
+ return (bytes / Math.pow(1024, exponent)).toFixed(2) + ' ' + ' KMGTP'.charAt(exponent) + 'B';
4119
3931
  }
4120
- get value() {
4121
- return this.selectorForm.get('select_value')?.value || '';
3932
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: FileSizePipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe }); }
3933
+ static { this.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "18.2.14", ngImport: i0, type: FileSizePipe, isStandalone: true, name: "fileSize" }); }
3934
+ }
3935
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: FileSizePipe, decorators: [{
3936
+ type: Pipe,
3937
+ args: [{
3938
+ name: 'fileSize',
3939
+ standalone: true
3940
+ }]
3941
+ }] });
3942
+
3943
+ /**
3944
+ * We are using both app-entity-file-list and app-entity-files-view-all
3945
+ * to ensure backward compatibility with older projects `ngx-techlify-documents, ngx-techlify-checksheets`
3946
+ * etc. `app-entity-files-view-all` will be removed by `v18.80.0`
3947
+ */
3948
+ class EntityFileListComponent extends TechlifyListComponent {
3949
+ set isFilterPatchFromRoute(value) {
3950
+ this._isFilterPatchFromRoute = value;
4122
3951
  }
4123
- set value(data) {
4124
- this.selectorForm.patchValue({ select_value: data || '' });
4125
- this.stateChanges.next();
3952
+ get isFilterPatchFromRoute() {
3953
+ return this._isFilterPatchFromRoute;
4126
3954
  }
4127
- constructor(formBuilder, _focusMonitor, http, _elementRef, dialog, ngControl) {
4128
- this._focusMonitor = _focusMonitor;
4129
- this.http = http;
4130
- this._elementRef = _elementRef;
4131
- this.dialog = dialog;
4132
- this.ngControl = ngControl;
4133
- this.valueField = 'id';
4134
- this.titleField = 'title';
4135
- this.multiple = false;
4136
- this.selectedValueChange = new EventEmitter();
4137
- this.enableSearch = true;
4138
- this.add = false;
4139
- this.edit = false;
4140
- this.sort = true;
4141
- this.items = [];
4142
- this.apiDataProperty = 'data';
4143
- this.cache = false;
4144
- this.perPage = 50;
4145
- this.inDataSearch = false;
4146
- this.panelWidth = '';
4147
- this.selectionChange = new EventEmitter();
4148
- this.itemsChange = new EventEmitter();
4149
- this.focusSearchOnOpen = false;
4150
- this.isItemsEmpty = new EventEmitter();
3955
+ constructor(service, alertService, fb, errorHandler, permissionsService) {
3956
+ super(service);
3957
+ this.service = service;
3958
+ this.alertService = alertService;
3959
+ this.fb = fb;
3960
+ this.errorHandler = errorHandler;
3961
+ this.permissionsService = permissionsService;
3962
+ this.viewOnly = false;
3963
+ this.allowMultipleFiles = false;
3964
+ this.allowBulkUpdate = false;
3965
+ this.viewMode = 'list';
3966
+ this.fileDropperHeight = '500px';
3967
+ this.isShowDragDropSection = true;
4151
3968
  /**
4152
- * If this is set to true, if there is a pre-selected entity,
4153
- * the entity that is populated will be emitted when it is set
3969
+ * Should we allow tagging entity-files?
4154
3970
  */
4155
- this.isEmitInitialEvent = false;
4156
- this.isLoading = false;
4157
- this.onChange = () => { };
4158
- this.onTouched = () => { };
4159
- this.stateChanges = new Subject();
4160
- this.focused = false;
4161
- this.controlType = 'searchable-selctor';
4162
- this.id = `searchable-selctor-${SearchableSelectorComponent.nextId++}`;
4163
- this.describedBy = '';
4164
- this.cachedItems = [];
4165
- this.subscriptions = new Subscription();
4166
- this._required = false;
4167
- this._disabled = false;
4168
- this.selectorForm = formBuilder.group({
4169
- select_value: [null],
4170
- search: ''
3971
+ this.useTechlifyTags = false;
3972
+ this.techlifyTagCategories = [];
3973
+ this.techlifyTagConfig = new TechlifyTaggerTagFormConfigModel();
3974
+ this.entityFileForm = signal(EntityFileFormComponent);
3975
+ this.formData = {};
3976
+ this.title = "File";
3977
+ this.displayedColumns = [
3978
+ 'index',
3979
+ 'title',
3980
+ 'expires_on',
3981
+ 'details',
3982
+ 'file_size',
3983
+ 'uploaded_on',
3984
+ ];
3985
+ this.isShowCreateAction = true;
3986
+ this.isShowUpdateAction = true;
3987
+ this.isShowDeleteAction = true;
3988
+ this.isShowReadAction = true;
3989
+ this.filterFormConfiguration = {
3990
+ tag_ids: { multiple: true }
3991
+ };
3992
+ this.filterForm = this.fb.group({
3993
+ title: [""],
3994
+ tag_ids: [[]],
3995
+ period_id: [''],
3996
+ expires_on_from: [''],
3997
+ expires_on_to: ['']
3998
+ });
3999
+ this.updateRowForm = this.fb.group({
4000
+ title: [''],
4001
+ details: [''],
4002
+ tag_ids: [''],
4171
4003
  });
4172
- this.subscriptions.add(_focusMonitor.monitor(_elementRef, true).subscribe(origin => {
4173
- if (this.focused && !origin) {
4174
- this.onTouched();
4175
- }
4176
- this.focused = !!origin;
4177
- this.stateChanges.next();
4178
- }));
4179
- if (this.ngControl != null) {
4180
- this.ngControl.valueAccessor = this;
4181
- }
4182
4004
  }
4183
- openedChange(opened) {
4184
- if (this.dataItems.length === 0 && this.selectorForm.get('search').value) {
4185
- this.selectorForm.get('search').setValue('');
4005
+ async ngOnInit() {
4006
+ /**
4007
+ * The reason we are setting permissions this way is because the user can pass what permissions are to be used
4008
+ * when manipulating the files/documents. If they are a client admin we will skip this
4009
+ */
4010
+ if (!await this.permissionsService.hasPermission('client_admin')) {
4011
+ this.isShowCreateAction = this.permission?.create ? await this.permissionsService.hasPermission(this.permission.create) : true;
4012
+ this.isShowUpdateAction = this.permission?.update ? await this.permissionsService.hasPermission(this.permission.update) : true;
4013
+ this.isShowReadAction = this.permission?.read ? await this.permissionsService.hasPermission(this.permission.read) : true;
4014
+ this.isShowDeleteAction = this.permission?.delete ? await this.permissionsService.hasPermission(this.permission.delete) : true;
4186
4015
  }
4187
- if (opened && this.enableSearch && this.focusSearchOnOpen) {
4188
- // Focus the search input field
4189
- setTimeout(() => this.searchInput.nativeElement.focus(), 0);
4016
+ this.formData = {
4017
+ entity: {
4018
+ entity_type: this.entityType,
4019
+ entity_id: this.entityId
4020
+ },
4021
+ hideTitleAndDetails: this.hideTitleAndDetails,
4022
+ useTechlifyTags: this.useTechlifyTags,
4023
+ techlifyTagCategories: this.techlifyTagCategories,
4024
+ techlifyTagConfig: this.techlifyTagConfig,
4025
+ };
4026
+ // File dropper config
4027
+ this.fileConfig = {
4028
+ fileId: "entityDashboardDropper",
4029
+ containerId: "entityDashboardDropperContainer",
4030
+ styles: {
4031
+ height: this.fileDropperHeight
4032
+ },
4033
+ multiple: this.allowMultipleFiles,
4034
+ acceptFile: "*",
4035
+ maxSize: 10,
4036
+ acceptFileText: "All Files"
4037
+ };
4038
+ this.viewerConfig = {
4039
+ imageStyle: {
4040
+ height: '200px',
4041
+ width: '200px'
4042
+ },
4043
+ viewerStyle: {
4044
+ height: ' 160px',
4045
+ width: '200px'
4046
+ },
4047
+ hideRemove: true
4048
+ };
4049
+ if (this.hideTitleAndDetails) {
4050
+ this.displayedColumns = this.displayedColumns.filter(x => (x !== 'details') && (x !== 'title'));
4190
4051
  }
4052
+ if (!this.viewOnly) {
4053
+ this.displayedColumns.push('actions');
4054
+ }
4055
+ if (this.allowBulkUpdate) {
4056
+ this.displayedColumns.push('select');
4057
+ }
4058
+ if (this.isFilterPatchFromRoute) {
4059
+ this.patchFiltersFromRoute();
4060
+ }
4061
+ this.listenFilterChanges();
4062
+ this.loadData();
4191
4063
  }
4192
- get dataItems() {
4193
- let items = [];
4194
- if (this.multiple && this.selectedValue && (this.selectedValue.length > 0))
4195
- items = [...this.selectedValue, ...this.items];
4196
- else if ((!this.multiple) && this.selectedValue)
4197
- items = [this.selectedValue, ...this.items];
4198
- else
4199
- items = this.items;
4200
- items = items.filter((v, i, a) => a.findIndex(v => v[this.valueField] === a[i][this.valueField]) === i);
4201
- //Emit the items to any child component
4202
- this.itemsChange.emit(items);
4203
- return items;
4204
- }
4205
- ngOnInit() {
4206
- this.subscriptions.add(this.selectorForm.get('search').valueChanges
4207
- .pipe(debounceTime(500), distinctUntilChanged()).subscribe(value => {
4208
- if (this.enableSearch)
4209
- this.search(value);
4210
- }));
4064
+ loadData() {
4211
4065
  this.filters = {
4212
- perPage: this.perPage,
4213
- search: '',
4214
- page: 1,
4215
- lastPage: 1
4066
+ ...this.requestHelperService?.convertToFormData(JSON.parse(JSON.stringify(this.filterForm.value))),
4067
+ entity_type: this.entityType,
4068
+ entity_id: this.entityId,
4069
+ with: 'creator,tags',
4070
+ page: this.page,
4071
+ per_page: this.perPage
4216
4072
  };
4217
- if (this.sort) {
4218
- this.filters.sort_by = this.sortBy || `${this.titleField}|asc`;
4219
- }
4220
- //Fetch Items only if it is not present, can be used in places where we load many entries.
4221
- if (this.items.length === 0) {
4222
- this.fetchItemList();
4073
+ super.loadData(this.filters);
4074
+ }
4075
+ async fileChanged(event) {
4076
+ const files = event;
4077
+ if (files.length > 0) {
4078
+ for (const file of files) {
4079
+ await this.service.uploadEntityFile(file, {
4080
+ entity_type: this.entityType,
4081
+ entity_id: this.entityId,
4082
+ });
4083
+ }
4084
+ this.reload();
4085
+ this.alertService.addAlert('Files uploaded successfully!', 'success');
4223
4086
  }
4224
4087
  }
4225
- fetchItemList() {
4226
- this.isLoading = true;
4227
- let request = this.http.get(this.apiUrl, { params: this.filters });
4228
- if (this.cache) {
4229
- request = this.http.cache().get(this.apiUrl, { params: this.filters });
4088
+ async bulkUpdate(fieldName) {
4089
+ const data = this.updateRowForm.value;
4090
+ this.isWorking = true;
4091
+ data.field_name = fieldName;
4092
+ data.document_ids = this.selectedModelIds;
4093
+ try {
4094
+ await this.service.bulkUpdate(data).then(() => {
4095
+ this.alertService.addAlert("Successfully updated", "success");
4096
+ this.isWorking = false;
4097
+ this.reload();
4098
+ });
4099
+ }
4100
+ catch (error) {
4101
+ this.errorHandler.handleError(error);
4102
+ this.isWorking = false;
4230
4103
  }
4231
- this.subscriptions.add(of().pipe(startWith(true), switchMap((_) => from(request)), finalize$1(() => this.isLoading = false)).subscribe((result) => {
4232
- this.items = this.items.concat(result[this.apiDataProperty]);
4233
- if (this.items.length == 0 && (!this.filters?.search)) {
4234
- //If there is no items and search is empty, then we emit items empty event.
4235
- this.isItemsEmpty.emit(true);
4236
- }
4237
- if (this.cache) {
4238
- this.cachedItems = this.items;
4239
- }
4240
- this.filters.page = result?.current_page || 1;
4241
- this.filters.lastPage = result?.last_page || 1;
4242
- /**
4243
- * If we are required to emit the selected entity when it is initially set,
4244
- * let's go ahead and emit it.
4245
- **/
4246
- if (this.isEmitInitialEvent && this.value) {
4247
- this._handleInput();
4248
- //Once the initial event is emitted, reset back to avoid continuous events
4249
- this.isEmitInitialEvent = false;
4250
- }
4251
- }));
4252
4104
  }
4253
- setDescribedByIds(ids) {
4254
- this.describedBy = ids.join(' ');
4105
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: EntityFileListComponent, deps: [{ token: EntityFileService }, { token: AlertService }, { token: i1$5.UntypedFormBuilder }, { token: ErrorHandlerService }, { token: i5$1.NgxPermissionsService }], target: i0.ɵɵFactoryTarget.Component }); }
4106
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.14", type: EntityFileListComponent, selector: "app-entity-file-list, app-entity-files-view-all", inputs: { entityId: "entityId", entityType: "entityType", viewOnly: "viewOnly", removeSearch: "removeSearch", hideTitleAndDetails: "hideTitleAndDetails", displayMode: "displayMode", allowMultipleFiles: "allowMultipleFiles", allowBulkUpdate: "allowBulkUpdate", viewMode: "viewMode", fileDropperHeight: "fileDropperHeight", isShowDragDropSection: "isShowDragDropSection", isFilterPatchFromRoute: "isFilterPatchFromRoute", useTechlifyTags: "useTechlifyTags", techlifyTagCategories: "techlifyTagCategories", techlifyTagConfig: "techlifyTagConfig", title: "title", permission: "permission" }, usesInheritance: true, ngImport: i0, template: "<div *ngIf=\"viewMode === 'list'\">\n <div *ngIf=\"this.selectedModelIds.length\" class=\"d-none d-md-flex flex-column\">\n <mat-card class=\"update_card\" *ngIf=\"this.selectedModelIds.length\">\n <mat-card-header>\n <mat-card-title>\n <div mat-dialog-title class=\"mt-2 ml-2 text-center\">\n <div>Update Selected Rows</div>\n </div>\n </mat-card-title>\n </mat-card-header>\n <mat-card-content class=\"d-flex flex-column\">\n <form [formGroup]=\"updateRowForm\">\n <div class=\"d-flex flex-column\">\n\n <mat-form-field class=\"w-100 px-1\">\n <input matInput formControlName=\"title\" placeholder=\"Title\" autocomplete=\"off\" />\n <button *ngIf=\"updateRowForm.get('title').value || updateRowForm.get('title').value===0\" matSuffix\n mat-icon-button style=\"color:red\" (click)=\"updateRowForm.get('title').setValue('')\">\n <mat-icon>close</mat-icon>\n </button>\n <button matSuffix mat-icon-button type=\"button\" style=\"color:green\" *ngIf=\"(updateRowForm.get('title').value || updateRowForm.get('title').value===0)\n && updateRowForm.get('title').valid\" (click)=\"bulkUpdate('title')\">\n <mat-icon>done</mat-icon>\n </button>\n </mat-form-field>\n\n <mat-form-field class=\"w-100 px-1\">\n <textarea matInput formControlName=\"details\" placeholder=\"Details\" autocomplete=\"off\"></textarea>\n <button *ngIf=\"updateRowForm.get('details').value || updateRowForm.get('details').value===0\" matSuffix\n mat-icon-button style=\"color:red\" (click)=\"updateRowForm.get('details').setValue('')\">\n <mat-icon>close</mat-icon>\n </button>\n <button matSuffix mat-icon-button type=\"button\" style=\"color:green\" *ngIf=\"(updateRowForm.get('details').value || updateRowForm.get('details').value===0)\n && updateRowForm.get('details').valid\" (click)=\"bulkUpdate('details')\">\n <mat-icon>done</mat-icon>\n </button>\n </mat-form-field>\n\n <ng-container *ngIf=\"useTechlifyTags\">\n <mat-form-field>\n <mat-label>Tag</mat-label>\n <app-techlify-tagger-tag-form-field modelType=\"entity-file\" formControlName=\"tag_ids\"\n placeholder=\"Enter new tag\">\n </app-techlify-tagger-tag-form-field>\n <button *ngIf=\"updateRowForm.get('tag_ids').value || updateRowForm.get('tag_ids').value===0\" matSuffix\n mat-icon-button style=\"color:red\" (click)=\"updateRowForm.get('tag_ids').setValue('')\">\n <mat-icon>close</mat-icon>\n </button>\n <button matSuffix mat-icon-button type=\"button\" style=\"color:green\" *ngIf=\"(updateRowForm.get('tag_ids').value || updateRowForm.get('tag_ids').value===0)\n && updateRowForm.get('tag_ids').valid\" (click)=\"bulkUpdate('tag_ids')\">\n <mat-icon>done</mat-icon>\n </button>\n </mat-form-field>\n </ng-container>\n </div>\n </form>\n </mat-card-content>\n </mat-card>\n\n </div>\n\n <div>\n <div class=\"mat-typography\" *ngIf=\"!displayMode\">\n <div class=\"d-flex flex-row gap-3\">\n <div class=\"d-flex flex-column gap-2 flex-grow-1\">\n <mat-card>\n <mat-card-content>\n <div class=\"d-flex gap-2 align-items-center\">\n <mat-icon>\n description\n </mat-icon>\n <h3 class=\"font-weight-bold mb-0\">\n {{title}}s\n </h3>\n <app-techlify-form-button class=\"ms-2\" *ngIf=\"!viewOnly && isShowCreateAction && entityId\"\n [component]=\"entityFileForm()\" [data]=\"formData\"\n (saved)=\"modelCreated($event)\"></app-techlify-form-button>\n <span class=\"flex-grow-1\"></span>\n <form [formGroup]=\"filterForm\" class=\"d-flex gap-2\">\n <mat-form-field *ngIf=\"!removeSearch\" appearance=\"outline\">\n <mat-label>Search</mat-label>\n <input type=\"text\" matInput formControlName=\"title\" placeholder=\"Search\" name=\"title\"\n autocomplete=\"off\" />\n <button *ngIf=\"filterForm.get('title').value\" matSuffix mat-icon-button\n (click)=\"resetFilter('title')\">\n <mat-icon>close</mat-icon>\n </button>\n </mat-form-field>\n\n <ng-container *ngIf=\"useTechlifyTags\">\n <mat-form-field>\n <mat-label>Tag</mat-label>\n <app-techlify-tagger-tag-form-field [categories]=\"techlifyTagCategories\" formControlName=\"tag_ids\"\n placeholder=\"Select Tags\" [config]=\"techlifyTagConfig\"></app-techlify-tagger-tag-form-field>\n </mat-form-field>\n </ng-container>\n\n <app-timeline-filter class=\"fl-sm\" formControlName='period_id' labelText=\"Expires On\"\n dateFrom=\"expires_on_from\" dateTo=\"expires_on_to\" [form]=\"filterForm\"></app-timeline-filter>\n </form>\n </div>\n </mat-card-content>\n <mat-card-content class=\"entity-file-card p-0\" *ngIf=\"entityId\">\n <ng-container *ngTemplateOutlet=\"tableView\"></ng-container>\n </mat-card-content>\n </mat-card>\n\n <mat-card *ngIf=\"!entityId\">\n <mat-card-content class=\"entity-file-card p-0\">\n <ng-container *ngTemplateOutlet=\"tableView\"></ng-container>\n </mat-card-content>\n </mat-card>\n </div>\n <ng-container *ngIf=\"isShowDragDropSection && entityId\">\n <section style=\"flex: 0 1 30%;\" *ngIf=\"!this.selectedModelIds.length && !viewOnly && isShowCreateAction\">\n <app-file-dropper [config]=\"fileConfig\" (fileChanged)=\"fileChanged($event)\">\n </app-file-dropper>\n </section>\n </ng-container>\n </div>\n </div>\n </div>\n\n <ng-template #tableView>\n <table mat-table [dataSource]=\"models\" class=\"w-100\" matSort multiTemplateDataRows infiniteScroll\n [infiniteScrollDistance]=\"1.5\" [infiniteScrollThrottle]=\"50\" (scrolled)=\"onScroll()\">\n\n <!-- Select Column -->\n <ng-container matColumnDef=\"select\">\n <th mat-header-cell *matHeaderCellDef style=\"width:30px\">\n <mat-checkbox name=\"employee\" [(ngModel)]=\"isAllSelected\" (change)=\"selectAll()\">\n </mat-checkbox>\n </th>\n <td mat-cell *matCellDef=\"let element\" style=\"width:30px\">\n <mat-checkbox name=\"employee[{{element?.id}}]\" (click)=\"$event.stopPropagation()\"\n [(ngModel)]=\"element.is_selected\" (change)=\"isSelectionModified($event, element)\"\n [disabled]=\"!models.length\">\n </mat-checkbox>\n </td>\n </ng-container>\n\n <!-- Index Column -->\n <ng-container matColumnDef=\"index\">\n <th mat-header-cell *matHeaderCellDef> # </th>\n <td mat-cell *matCellDef=\"let element; let i = dataIndex\"> {{ i+1 }} </td>\n </ng-container>\n\n <!-- Title Column -->\n <ng-container matColumnDef=\"title\">\n <th mat-header-cell *matHeaderCellDef> Title </th>\n <td mat-cell *matCellDef=\"let element\">\n {{element.title}}\n <ng-container *ngIf=\"useTechlifyTags\">\n <br>\n <small class=\"badge badge-secondary mr-1\" *ngFor=\"let tag of element?.tags\">{{tag?.title}}</small>\n </ng-container>\n\n </td>\n </ng-container>\n\n <ng-container matColumnDef=\"expires_on\">\n <th mat-header-cell *matHeaderCellDef> Expires On </th>\n <td mat-cell *matCellDef=\"let element\">\n {{element?.expires_on | date:'mediumDate'}}\n </td>\n </ng-container>\n\n <!-- Details Column -->\n <ng-container matColumnDef=\"details\">\n <th mat-header-cell *matHeaderCellDef> Details </th>\n <td mat-cell *matCellDef=\"let element\">\n <app-read-more [text]=\"element.details\" [maxLength]=\"50\"></app-read-more>\n </td>\n </ng-container>\n\n <!-- File size Column -->\n <ng-container matColumnDef=\"file_size\">\n <th mat-header-cell *matHeaderCellDef> File Size </th>\n <td mat-cell *matCellDef=\"let element\"> {{ element.file_size | fileSize }} </td>\n </ng-container>\n\n <!-- Uploaded On Column -->\n <ng-container matColumnDef=\"uploaded_on\">\n <th mat-header-cell *matHeaderCellDef> Uploaded On </th>\n <td mat-cell *matCellDef=\"let element\">\n <div>\n {{element.created_at | date: 'mediumDate'}}\n </div>\n <div class=\"text-muted\">\n By {{element.creator?.name}}\n </div>\n </td>\n </ng-container>\n\n <!-- Actions Column -->\n <ng-container matColumnDef=\"actions\">\n <th mat-header-cell *matHeaderCellDef> Actions </th>\n <td mat-cell *matCellDef=\"let element\" class=\"text-muted\">\n <div class=\"d-flex flex-row gap-2 text-secondary align-items-center\">\n <a href=\"{{element.url}}\" target=\"_blank\" class=\"text-decoration-none text-muted clickable\">\n <mat-icon>download</mat-icon>\n </a>\n <app-techlify-form-button *ngIf=\"!viewOnly && isShowUpdateAction\" [component]=\"entityFileForm()\"\n [model]=\"element\" [data]=\"formData\" (saved)=\"modelsUpdatedById($event)\"></app-techlify-form-button>\n <app-techlify-delete-button *ngIf=\"!viewOnly && isShowDeleteAction\" [model]=\"element\" [service]=\"service\"\n message=\"Are you sure to proceed delete the file {{element.title}}\"\n (deleted)=\"modelsDeletedById(element)\">\n </app-techlify-delete-button>\n </div>\n </td>\n </ng-container>\n\n <tr mat-header-row *matHeaderRowDef=\"displayedColumns\"></tr>\n <tr mat-row *matRowDef=\"let row; columns: displayedColumns;\"></tr>\n </table>\n\n <mat-progress-bar mode=\"indeterminate\" *ngIf=\"isWorking\"></mat-progress-bar>\n </ng-template>\n\n <div class=\"d-flex flex-wrap gap-3 mat-typography p-4\" *ngIf=\"displayMode\">\n <div *ngFor=\"let efile of models\">\n <app-document-viewer [file]=\"efile.file\" [fileUrl]=\"efile.url\" [config]=\"this.viewerConfig\" [disableEdit]=\"true\">\n </app-document-viewer>\n <a href=\"{{efile.url}}\" target=\"_blank\">\n <button mat-button type=\"button\">View</button>\n </a>\n </div>\n </div>\n</div>\n\n<mat-card *ngIf=\"viewMode === 'timeline'\">\n <mat-card-content>\n <div class=\"d-flex justify-content-start align-items-center gap-2\">\n <mat-icon>\n description\n </mat-icon>\n <h3 class=\"font-weight-bold mb-0\">\n {{title}}s\n </h3>\n <app-techlify-form-button *ngIf=\"!viewOnly && isShowCreateAction\" [component]=\"entityFileForm()\" [data]=\"formData\"\n (saved)=\"modelCreated($event)\"></app-techlify-form-button>\n </div>\n </mat-card-content>\n <mat-card-content *ngIf=\"!this.selectedModelIds.length && !viewOnly && isShowCreateAction\" class=\"mt-3\">\n <app-file-dropper [config]=\"fileConfig\" (fileChanged)=\"fileChanged($event)\">\n </app-file-dropper>\n </mat-card-content>\n\n <mat-card-content class=\"mt-3\">\n <div *ngFor=\"let entityFile of models\" class=\"d-flex flex-column gap-0\">\n <div class=\"d-flex flex-column gap-0\">\n <div class=\"d-flex justify-content-between align-items-center gap-1\">\n <p class=\"mb-0 fw-bold text-wrap\">{{ entityFile?.title | wrap:20 }}</p>\n <span class=\"badge bg-dark\" *ngFor=\"let tag of entityFile?.tags\">\n {{ tag?.title }}\n </span>\n <small class=\"text-dark\">{{ entityFile.file_size | fileSize }}</small>\n </div>\n </div>\n <app-read-more [text]=\"entityFile?.details\" [maxLength]=\"50\"></app-read-more>\n <div class=\"d-flex justify-content-between gap-2\">\n <small class=\"text-secondary\" style=\"max-width: 70%\">\n <i>Uploaded By {{ entityFile?.creator?.name }} {{ entityFile?.created_at | date: 'mediumDate'}}</i>\n </small>\n <div class=\"d-flex justify-content-end align-items-center gap-1\">\n <a href=\"{{entityFile?.url}}\" target=\"_blank\" class=\"text-decoration-none text-secondary mt-2\">\n <mat-icon>download</mat-icon>\n </a>\n <app-techlify-form-button class=\"text-secondary\" *ngIf=\"!viewOnly && isShowUpdateAction\"\n [component]=\"entityFileForm()\" [model]=\"entityFile\" [data]=\"formData\"\n (saved)=\"modelsUpdatedById($event)\"></app-techlify-form-button>\n <app-techlify-delete-button *ngIf=\"!viewOnly && isShowDeleteAction\" class='text-secondary ms-1'\n [model]=\"entityFile\" [service]=\"service\"\n message=\"Are you sure to proceed delete the file {{entityFile.title}}\"\n (deleted)=\"modelsDeletedById(entityFile)\">\n </app-techlify-delete-button>\n </div>\n </div>\n <hr style=\"margin: 0.5rem 0\">\n </div>\n <mat-progress-bar mode=\"indeterminate\" *ngIf=\"isWorking\"></mat-progress-bar>\n </mat-card-content>\n</mat-card>", styles: ["th.mat-header-cell,td.mat-cell,td.mat-footer-cell{padding:2px}.entity-file-card{overflow-x:auto}.clickable:hover{cursor:pointer}\n"], dependencies: [{ kind: "directive", type: i3.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i3.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: i1$5.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1$5.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$5.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$5.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1$5.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: i6$2.InfiniteScrollDirective, selector: "[infiniteScroll], [infinite-scroll], [data-infinite-scroll]", inputs: ["infiniteScrollDistance", "infiniteScrollUpDistance", "infiniteScrollThrottle", "infiniteScrollDisabled", "infiniteScrollContainer", "scrollWindow", "immediateCheck", "horizontal", "alwaysCallback", "fromRoot"], outputs: ["scrolled", "scrolledUp"] }, { kind: "component", type: i6.MatButton, selector: " button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ", exportAs: ["matButton"] }, { kind: "component", type: i6.MatIconButton, selector: "button[mat-icon-button]", exportAs: ["matButton"] }, { kind: "component", type: i8$1.MatCheckbox, selector: "mat-checkbox", inputs: ["aria-label", "aria-labelledby", "aria-describedby", "id", "required", "labelPosition", "name", "value", "disableRipple", "tabIndex", "color", "disabledInteractive", "checked", "disabled", "indeterminate"], outputs: ["change", "indeterminateChange"], exportAs: ["matCheckbox"] }, { kind: "directive", type: i1.MatDialogTitle, selector: "[mat-dialog-title], [matDialogTitle]", inputs: ["id"], exportAs: ["matDialogTitle"] }, { kind: "component", type: i8$4.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i8$4.MatLabel, selector: "mat-label" }, { kind: "directive", type: i8$4.MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { kind: "component", type: i8.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "directive", type: i9.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly"], exportAs: ["matInput"] }, { kind: "directive", type: i11.MatSort, selector: "[matSort]", inputs: ["matSortActive", "matSortStart", "matSortDirection", "matSortDisableClear", "matSortDisabled"], outputs: ["matSortChange"], exportAs: ["matSort"] }, { kind: "component", type: i12.MatTable, selector: "mat-table, table[mat-table]", exportAs: ["matTable"] }, { kind: "directive", type: i12.MatHeaderCellDef, selector: "[matHeaderCellDef]" }, { kind: "directive", type: i12.MatHeaderRowDef, selector: "[matHeaderRowDef]", inputs: ["matHeaderRowDef", "matHeaderRowDefSticky"] }, { kind: "directive", type: i12.MatColumnDef, selector: "[matColumnDef]", inputs: ["matColumnDef"] }, { kind: "directive", type: i12.MatCellDef, selector: "[matCellDef]" }, { kind: "directive", type: i12.MatRowDef, selector: "[matRowDef]", inputs: ["matRowDefColumns", "matRowDefWhen"] }, { kind: "directive", type: i12.MatHeaderCell, selector: "mat-header-cell, th[mat-header-cell]" }, { kind: "directive", type: i12.MatCell, selector: "mat-cell, td[mat-cell]" }, { kind: "component", type: i12.MatHeaderRow, selector: "mat-header-row, tr[mat-header-row]", exportAs: ["matHeaderRow"] }, { kind: "component", type: i12.MatRow, selector: "mat-row, tr[mat-row]", exportAs: ["matRow"] }, { kind: "component", type: i4.MatCard, selector: "mat-card", inputs: ["appearance"], exportAs: ["matCard"] }, { kind: "directive", type: i4.MatCardContent, selector: "mat-card-content" }, { kind: "component", type: i4.MatCardHeader, selector: "mat-card-header" }, { kind: "directive", type: i4.MatCardTitle, selector: "mat-card-title, [mat-card-title], [matCardTitle]" }, { kind: "component", type: i11$2.MatProgressBar, selector: "mat-progress-bar", inputs: ["color", "value", "bufferValue", "mode"], outputs: ["animationEnd"], exportAs: ["matProgressBar"] }, { kind: "directive", type: i1$5.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$5.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "component", type: TechlifyDeleteButtonComponent, selector: "app-techlify-delete-button", inputs: ["data", "model", "message", "service"], outputs: ["deleted"] }, { kind: "component", type: TimelineFilterComponent, selector: "app-timeline-filter", inputs: ["defaultValue", "required", "disabled", "value", "timelines", "dateFrom", "dateTo", "appearance", "showClearButton", "form", "labelText"], outputs: ["selectionChange"] }, { kind: "component", type: TechlifyFormButtonComponent, selector: "app-techlify-form-button", inputs: ["component", "model", "data", "width"], outputs: ["saved"] }, { kind: "component", type: FileDropperComponent, selector: "app-file-dropper", inputs: ["fileArray", "config", "styles"], outputs: ["fileChanged"] }, { kind: "component", type: DocumentViewerComponent, selector: "app-document-viewer", inputs: ["config", "file", "fileUrl", "disableEdit"], outputs: ["remove"] }, { kind: "component", type: TechlifyTaggerTagFormFieldComponent, selector: "app-techlify-tagger-tag-form-field", inputs: ["config", "modelType", "modelId", "allTags", "categories", "defaultCreateCategory", "required", "disabled", "value", "placeholder"] }, { kind: "component", type: ReadMoreComponent, selector: "app-read-more", inputs: ["text", "maxLength"] }, { kind: "pipe", type: i3.DatePipe, name: "date" }, { kind: "pipe", type: WrapPipe, name: "wrap" }, { kind: "pipe", type: FileSizePipe, name: "fileSize" }] }); }
4107
+ }
4108
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: EntityFileListComponent, decorators: [{
4109
+ type: Component,
4110
+ args: [{ selector: 'app-entity-file-list, app-entity-files-view-all', template: "<div *ngIf=\"viewMode === 'list'\">\n <div *ngIf=\"this.selectedModelIds.length\" class=\"d-none d-md-flex flex-column\">\n <mat-card class=\"update_card\" *ngIf=\"this.selectedModelIds.length\">\n <mat-card-header>\n <mat-card-title>\n <div mat-dialog-title class=\"mt-2 ml-2 text-center\">\n <div>Update Selected Rows</div>\n </div>\n </mat-card-title>\n </mat-card-header>\n <mat-card-content class=\"d-flex flex-column\">\n <form [formGroup]=\"updateRowForm\">\n <div class=\"d-flex flex-column\">\n\n <mat-form-field class=\"w-100 px-1\">\n <input matInput formControlName=\"title\" placeholder=\"Title\" autocomplete=\"off\" />\n <button *ngIf=\"updateRowForm.get('title').value || updateRowForm.get('title').value===0\" matSuffix\n mat-icon-button style=\"color:red\" (click)=\"updateRowForm.get('title').setValue('')\">\n <mat-icon>close</mat-icon>\n </button>\n <button matSuffix mat-icon-button type=\"button\" style=\"color:green\" *ngIf=\"(updateRowForm.get('title').value || updateRowForm.get('title').value===0)\n && updateRowForm.get('title').valid\" (click)=\"bulkUpdate('title')\">\n <mat-icon>done</mat-icon>\n </button>\n </mat-form-field>\n\n <mat-form-field class=\"w-100 px-1\">\n <textarea matInput formControlName=\"details\" placeholder=\"Details\" autocomplete=\"off\"></textarea>\n <button *ngIf=\"updateRowForm.get('details').value || updateRowForm.get('details').value===0\" matSuffix\n mat-icon-button style=\"color:red\" (click)=\"updateRowForm.get('details').setValue('')\">\n <mat-icon>close</mat-icon>\n </button>\n <button matSuffix mat-icon-button type=\"button\" style=\"color:green\" *ngIf=\"(updateRowForm.get('details').value || updateRowForm.get('details').value===0)\n && updateRowForm.get('details').valid\" (click)=\"bulkUpdate('details')\">\n <mat-icon>done</mat-icon>\n </button>\n </mat-form-field>\n\n <ng-container *ngIf=\"useTechlifyTags\">\n <mat-form-field>\n <mat-label>Tag</mat-label>\n <app-techlify-tagger-tag-form-field modelType=\"entity-file\" formControlName=\"tag_ids\"\n placeholder=\"Enter new tag\">\n </app-techlify-tagger-tag-form-field>\n <button *ngIf=\"updateRowForm.get('tag_ids').value || updateRowForm.get('tag_ids').value===0\" matSuffix\n mat-icon-button style=\"color:red\" (click)=\"updateRowForm.get('tag_ids').setValue('')\">\n <mat-icon>close</mat-icon>\n </button>\n <button matSuffix mat-icon-button type=\"button\" style=\"color:green\" *ngIf=\"(updateRowForm.get('tag_ids').value || updateRowForm.get('tag_ids').value===0)\n && updateRowForm.get('tag_ids').valid\" (click)=\"bulkUpdate('tag_ids')\">\n <mat-icon>done</mat-icon>\n </button>\n </mat-form-field>\n </ng-container>\n </div>\n </form>\n </mat-card-content>\n </mat-card>\n\n </div>\n\n <div>\n <div class=\"mat-typography\" *ngIf=\"!displayMode\">\n <div class=\"d-flex flex-row gap-3\">\n <div class=\"d-flex flex-column gap-2 flex-grow-1\">\n <mat-card>\n <mat-card-content>\n <div class=\"d-flex gap-2 align-items-center\">\n <mat-icon>\n description\n </mat-icon>\n <h3 class=\"font-weight-bold mb-0\">\n {{title}}s\n </h3>\n <app-techlify-form-button class=\"ms-2\" *ngIf=\"!viewOnly && isShowCreateAction && entityId\"\n [component]=\"entityFileForm()\" [data]=\"formData\"\n (saved)=\"modelCreated($event)\"></app-techlify-form-button>\n <span class=\"flex-grow-1\"></span>\n <form [formGroup]=\"filterForm\" class=\"d-flex gap-2\">\n <mat-form-field *ngIf=\"!removeSearch\" appearance=\"outline\">\n <mat-label>Search</mat-label>\n <input type=\"text\" matInput formControlName=\"title\" placeholder=\"Search\" name=\"title\"\n autocomplete=\"off\" />\n <button *ngIf=\"filterForm.get('title').value\" matSuffix mat-icon-button\n (click)=\"resetFilter('title')\">\n <mat-icon>close</mat-icon>\n </button>\n </mat-form-field>\n\n <ng-container *ngIf=\"useTechlifyTags\">\n <mat-form-field>\n <mat-label>Tag</mat-label>\n <app-techlify-tagger-tag-form-field [categories]=\"techlifyTagCategories\" formControlName=\"tag_ids\"\n placeholder=\"Select Tags\" [config]=\"techlifyTagConfig\"></app-techlify-tagger-tag-form-field>\n </mat-form-field>\n </ng-container>\n\n <app-timeline-filter class=\"fl-sm\" formControlName='period_id' labelText=\"Expires On\"\n dateFrom=\"expires_on_from\" dateTo=\"expires_on_to\" [form]=\"filterForm\"></app-timeline-filter>\n </form>\n </div>\n </mat-card-content>\n <mat-card-content class=\"entity-file-card p-0\" *ngIf=\"entityId\">\n <ng-container *ngTemplateOutlet=\"tableView\"></ng-container>\n </mat-card-content>\n </mat-card>\n\n <mat-card *ngIf=\"!entityId\">\n <mat-card-content class=\"entity-file-card p-0\">\n <ng-container *ngTemplateOutlet=\"tableView\"></ng-container>\n </mat-card-content>\n </mat-card>\n </div>\n <ng-container *ngIf=\"isShowDragDropSection && entityId\">\n <section style=\"flex: 0 1 30%;\" *ngIf=\"!this.selectedModelIds.length && !viewOnly && isShowCreateAction\">\n <app-file-dropper [config]=\"fileConfig\" (fileChanged)=\"fileChanged($event)\">\n </app-file-dropper>\n </section>\n </ng-container>\n </div>\n </div>\n </div>\n\n <ng-template #tableView>\n <table mat-table [dataSource]=\"models\" class=\"w-100\" matSort multiTemplateDataRows infiniteScroll\n [infiniteScrollDistance]=\"1.5\" [infiniteScrollThrottle]=\"50\" (scrolled)=\"onScroll()\">\n\n <!-- Select Column -->\n <ng-container matColumnDef=\"select\">\n <th mat-header-cell *matHeaderCellDef style=\"width:30px\">\n <mat-checkbox name=\"employee\" [(ngModel)]=\"isAllSelected\" (change)=\"selectAll()\">\n </mat-checkbox>\n </th>\n <td mat-cell *matCellDef=\"let element\" style=\"width:30px\">\n <mat-checkbox name=\"employee[{{element?.id}}]\" (click)=\"$event.stopPropagation()\"\n [(ngModel)]=\"element.is_selected\" (change)=\"isSelectionModified($event, element)\"\n [disabled]=\"!models.length\">\n </mat-checkbox>\n </td>\n </ng-container>\n\n <!-- Index Column -->\n <ng-container matColumnDef=\"index\">\n <th mat-header-cell *matHeaderCellDef> # </th>\n <td mat-cell *matCellDef=\"let element; let i = dataIndex\"> {{ i+1 }} </td>\n </ng-container>\n\n <!-- Title Column -->\n <ng-container matColumnDef=\"title\">\n <th mat-header-cell *matHeaderCellDef> Title </th>\n <td mat-cell *matCellDef=\"let element\">\n {{element.title}}\n <ng-container *ngIf=\"useTechlifyTags\">\n <br>\n <small class=\"badge badge-secondary mr-1\" *ngFor=\"let tag of element?.tags\">{{tag?.title}}</small>\n </ng-container>\n\n </td>\n </ng-container>\n\n <ng-container matColumnDef=\"expires_on\">\n <th mat-header-cell *matHeaderCellDef> Expires On </th>\n <td mat-cell *matCellDef=\"let element\">\n {{element?.expires_on | date:'mediumDate'}}\n </td>\n </ng-container>\n\n <!-- Details Column -->\n <ng-container matColumnDef=\"details\">\n <th mat-header-cell *matHeaderCellDef> Details </th>\n <td mat-cell *matCellDef=\"let element\">\n <app-read-more [text]=\"element.details\" [maxLength]=\"50\"></app-read-more>\n </td>\n </ng-container>\n\n <!-- File size Column -->\n <ng-container matColumnDef=\"file_size\">\n <th mat-header-cell *matHeaderCellDef> File Size </th>\n <td mat-cell *matCellDef=\"let element\"> {{ element.file_size | fileSize }} </td>\n </ng-container>\n\n <!-- Uploaded On Column -->\n <ng-container matColumnDef=\"uploaded_on\">\n <th mat-header-cell *matHeaderCellDef> Uploaded On </th>\n <td mat-cell *matCellDef=\"let element\">\n <div>\n {{element.created_at | date: 'mediumDate'}}\n </div>\n <div class=\"text-muted\">\n By {{element.creator?.name}}\n </div>\n </td>\n </ng-container>\n\n <!-- Actions Column -->\n <ng-container matColumnDef=\"actions\">\n <th mat-header-cell *matHeaderCellDef> Actions </th>\n <td mat-cell *matCellDef=\"let element\" class=\"text-muted\">\n <div class=\"d-flex flex-row gap-2 text-secondary align-items-center\">\n <a href=\"{{element.url}}\" target=\"_blank\" class=\"text-decoration-none text-muted clickable\">\n <mat-icon>download</mat-icon>\n </a>\n <app-techlify-form-button *ngIf=\"!viewOnly && isShowUpdateAction\" [component]=\"entityFileForm()\"\n [model]=\"element\" [data]=\"formData\" (saved)=\"modelsUpdatedById($event)\"></app-techlify-form-button>\n <app-techlify-delete-button *ngIf=\"!viewOnly && isShowDeleteAction\" [model]=\"element\" [service]=\"service\"\n message=\"Are you sure to proceed delete the file {{element.title}}\"\n (deleted)=\"modelsDeletedById(element)\">\n </app-techlify-delete-button>\n </div>\n </td>\n </ng-container>\n\n <tr mat-header-row *matHeaderRowDef=\"displayedColumns\"></tr>\n <tr mat-row *matRowDef=\"let row; columns: displayedColumns;\"></tr>\n </table>\n\n <mat-progress-bar mode=\"indeterminate\" *ngIf=\"isWorking\"></mat-progress-bar>\n </ng-template>\n\n <div class=\"d-flex flex-wrap gap-3 mat-typography p-4\" *ngIf=\"displayMode\">\n <div *ngFor=\"let efile of models\">\n <app-document-viewer [file]=\"efile.file\" [fileUrl]=\"efile.url\" [config]=\"this.viewerConfig\" [disableEdit]=\"true\">\n </app-document-viewer>\n <a href=\"{{efile.url}}\" target=\"_blank\">\n <button mat-button type=\"button\">View</button>\n </a>\n </div>\n </div>\n</div>\n\n<mat-card *ngIf=\"viewMode === 'timeline'\">\n <mat-card-content>\n <div class=\"d-flex justify-content-start align-items-center gap-2\">\n <mat-icon>\n description\n </mat-icon>\n <h3 class=\"font-weight-bold mb-0\">\n {{title}}s\n </h3>\n <app-techlify-form-button *ngIf=\"!viewOnly && isShowCreateAction\" [component]=\"entityFileForm()\" [data]=\"formData\"\n (saved)=\"modelCreated($event)\"></app-techlify-form-button>\n </div>\n </mat-card-content>\n <mat-card-content *ngIf=\"!this.selectedModelIds.length && !viewOnly && isShowCreateAction\" class=\"mt-3\">\n <app-file-dropper [config]=\"fileConfig\" (fileChanged)=\"fileChanged($event)\">\n </app-file-dropper>\n </mat-card-content>\n\n <mat-card-content class=\"mt-3\">\n <div *ngFor=\"let entityFile of models\" class=\"d-flex flex-column gap-0\">\n <div class=\"d-flex flex-column gap-0\">\n <div class=\"d-flex justify-content-between align-items-center gap-1\">\n <p class=\"mb-0 fw-bold text-wrap\">{{ entityFile?.title | wrap:20 }}</p>\n <span class=\"badge bg-dark\" *ngFor=\"let tag of entityFile?.tags\">\n {{ tag?.title }}\n </span>\n <small class=\"text-dark\">{{ entityFile.file_size | fileSize }}</small>\n </div>\n </div>\n <app-read-more [text]=\"entityFile?.details\" [maxLength]=\"50\"></app-read-more>\n <div class=\"d-flex justify-content-between gap-2\">\n <small class=\"text-secondary\" style=\"max-width: 70%\">\n <i>Uploaded By {{ entityFile?.creator?.name }} {{ entityFile?.created_at | date: 'mediumDate'}}</i>\n </small>\n <div class=\"d-flex justify-content-end align-items-center gap-1\">\n <a href=\"{{entityFile?.url}}\" target=\"_blank\" class=\"text-decoration-none text-secondary mt-2\">\n <mat-icon>download</mat-icon>\n </a>\n <app-techlify-form-button class=\"text-secondary\" *ngIf=\"!viewOnly && isShowUpdateAction\"\n [component]=\"entityFileForm()\" [model]=\"entityFile\" [data]=\"formData\"\n (saved)=\"modelsUpdatedById($event)\"></app-techlify-form-button>\n <app-techlify-delete-button *ngIf=\"!viewOnly && isShowDeleteAction\" class='text-secondary ms-1'\n [model]=\"entityFile\" [service]=\"service\"\n message=\"Are you sure to proceed delete the file {{entityFile.title}}\"\n (deleted)=\"modelsDeletedById(entityFile)\">\n </app-techlify-delete-button>\n </div>\n </div>\n <hr style=\"margin: 0.5rem 0\">\n </div>\n <mat-progress-bar mode=\"indeterminate\" *ngIf=\"isWorking\"></mat-progress-bar>\n </mat-card-content>\n</mat-card>", styles: ["th.mat-header-cell,td.mat-cell,td.mat-footer-cell{padding:2px}.entity-file-card{overflow-x:auto}.clickable:hover{cursor:pointer}\n"] }]
4111
+ }], ctorParameters: () => [{ type: EntityFileService }, { type: AlertService }, { type: i1$5.UntypedFormBuilder }, { type: ErrorHandlerService }, { type: i5$1.NgxPermissionsService }], propDecorators: { entityId: [{
4112
+ type: Input
4113
+ }], entityType: [{
4114
+ type: Input
4115
+ }], viewOnly: [{
4116
+ type: Input
4117
+ }], removeSearch: [{
4118
+ type: Input
4119
+ }], hideTitleAndDetails: [{
4120
+ type: Input
4121
+ }], displayMode: [{
4122
+ type: Input
4123
+ }], allowMultipleFiles: [{
4124
+ type: Input
4125
+ }], allowBulkUpdate: [{
4126
+ type: Input
4127
+ }], viewMode: [{
4128
+ type: Input
4129
+ }], fileDropperHeight: [{
4130
+ type: Input
4131
+ }], isShowDragDropSection: [{
4132
+ type: Input
4133
+ }], isFilterPatchFromRoute: [{
4134
+ type: Input
4135
+ }], useTechlifyTags: [{
4136
+ type: Input
4137
+ }], techlifyTagCategories: [{
4138
+ type: Input
4139
+ }], techlifyTagConfig: [{
4140
+ type: Input
4141
+ }], title: [{
4142
+ type: Input
4143
+ }], permission: [{
4144
+ type: Input
4145
+ }] } });
4146
+
4147
+ class FileDropperConfig {
4148
+ }
4149
+
4150
+ class NoteService {
4151
+ constructor(http) {
4152
+ this.http = http;
4255
4153
  }
4256
- onContainerClick(event) {
4257
- event.stopPropagation();
4154
+ getNotes(filterModel) {
4155
+ return this.http.get('api/notes', { params: filterModel }).toPromise();
4258
4156
  }
4259
- writeValue(data) {
4260
- this.value = data;
4157
+ addNote(note) {
4158
+ return this.http.post('api/notes', note).toPromise();
4261
4159
  }
4262
- registerOnChange(fn) {
4263
- this.onChange = fn;
4160
+ editNote(note) {
4161
+ return this.http.put(`api/notes/${note.id}`, note).toPromise();
4264
4162
  }
4265
- registerOnTouched(fn) {
4266
- this.onTouched = fn;
4163
+ deleteNote(note) {
4164
+ return this.http.delete(`api/notes/${note.id}`).toPromise();
4267
4165
  }
4268
- setDisabledState(isDisabled) {
4269
- this.disabled = isDisabled;
4166
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: NoteService, deps: [{ token: HttpService }], target: i0.ɵɵFactoryTarget.Injectable }); }
4167
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: NoteService, providedIn: 'root' }); }
4168
+ }
4169
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: NoteService, decorators: [{
4170
+ type: Injectable,
4171
+ args: [{
4172
+ providedIn: 'root'
4173
+ }]
4174
+ }], ctorParameters: () => [{ type: HttpService }] });
4175
+
4176
+ const errorMessages$b = {
4177
+ note: {
4178
+ required: "Note is required"
4270
4179
  }
4271
- getPropertyValue(ele, keyString) {
4272
- keyString = keyString.replace(/\[(\w+)\]/g, ".$1"); // convert indexes to properties
4273
- keyString = keyString.replace(/^\./, ""); // strip a leading dot
4274
- const keyList = keyString.split(".");
4275
- for (let i = 0, n = keyList.length; i < n; ++i) {
4276
- const key = keyList[i];
4277
- if (ele && key in ele) {
4278
- ele = ele[key];
4279
- }
4280
- else {
4281
- return;
4282
- }
4180
+ };
4181
+ class NoteFormComponent {
4182
+ constructor(dialogRef, data, fb, formValidatorService, alertService, noteService) {
4183
+ this.dialogRef = dialogRef;
4184
+ this.data = data;
4185
+ this.fb = fb;
4186
+ this.formValidatorService = formValidatorService;
4187
+ this.alertService = alertService;
4188
+ this.noteService = noteService;
4189
+ this.createForm();
4190
+ }
4191
+ /** Method to create a form **/
4192
+ createForm() {
4193
+ //TODO: Finialize and add more validations.
4194
+ this.noteFormGroup = this.fb.group({
4195
+ id: [""],
4196
+ note: ["", Validators.compose([Validators.required])],
4197
+ model_type: [""],
4198
+ related_model_id: [""],
4199
+ });
4200
+ }
4201
+ ngOnInit() {
4202
+ if (this.data.update) {
4203
+ this.updateMode = true;
4283
4204
  }
4284
- return ele;
4205
+ this.noteFormGroup.patchValue(this.data.note);
4285
4206
  }
4286
- _handleInput() {
4287
- //Trigger on change only when initial event is false, to avoid double loading
4288
- if (!this.isEmitInitialEvent) {
4289
- this.onChange(this.value);
4207
+ //Method to trigger login
4208
+ async submit() {
4209
+ this.noteFormFirstAttempt = true;
4210
+ if (this.noteFormGroup.valid) {
4211
+ const model = this.noteFormGroup.value;
4212
+ const result = this.updateMode
4213
+ ? await this.noteService.editNote(model)
4214
+ : await this.noteService.addNote(model);
4215
+ this.alertService.addAlert(`${this.data?.labelText} saved successfully`, "success");
4216
+ this.dialogRef.close(result);
4290
4217
  }
4291
- if (this.multiple)
4292
- this.selectedValue = (this.value || []).map(x => this.dataItems.find(y => y[this.valueField] === x));
4293
- else
4294
- this.selectedValue = this.dataItems.find(x => x[this.valueField] === this.value);
4295
- this.selectedValueChange.emit(this.selectedValue);
4296
- this.selectionChange.emit(this.value);
4297
4218
  }
4298
- get errorState() {
4299
- return (this.ngControl && this.ngControl.invalid && (this.ngControl.touched || this.ngControl.dirty));
4219
+ cancel() {
4220
+ this.dialogRef.close();
4300
4221
  }
4301
- onScroll() {
4302
- if (!this.isLoading && this.filters.lastPage > this.filters.page) {
4303
- this.filters.page += 1;
4304
- this.fetchItemList();
4305
- }
4222
+ /**Method to evaluate form fields*/
4223
+ isFieldValid(field) {
4224
+ return this.formValidatorService.isFieldValid(field, this.noteFormGroup, this.noteFormFirstAttempt);
4306
4225
  }
4307
- reloadData() {
4308
- this.items = [];
4309
- this.filters.page = 1;
4310
- this.filters.lastPage = 1;
4311
- this.fetchItemList();
4226
+ /**Method to find error in form fields*/
4227
+ getErrorMessage(field) {
4228
+ return this.formValidatorService.getErrorMessage(field, this.noteFormGroup, errorMessages$b);
4312
4229
  }
4313
- search(event) {
4314
- if (this.searchField) {
4315
- this.filters[this.searchField] = event;
4316
- }
4317
- else {
4318
- this.filters.search = event;
4319
- }
4320
- // we need search field to search in data
4321
- if (this.inDataSearch && this.searchField) {
4322
- this.filterItems(event);
4323
- }
4324
- else {
4325
- this.reloadData();
4326
- }
4230
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: NoteFormComponent, deps: [{ token: i1.MatDialogRef }, { token: MAT_DIALOG_DATA }, { token: i1$5.UntypedFormBuilder }, { token: FormValidatorService }, { token: AlertService }, { token: NoteService }], target: i0.ɵɵFactoryTarget.Component }); }
4231
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.14", type: NoteFormComponent, selector: "app-note-form", ngImport: i0, template: "<form [formGroup]=\"noteFormGroup\" (ngSubmit)=\"submit()\">\n <div fxLayout=\"column\" class=\"mat-typography\">\n <div mat-dialog-title class=\"text-center\">\n <div>{{data?.labelText}}</div>\n </div>\n\n <div mat-dialog-content fxLayout=\"column\">\n <div fxLayout=\"row wrap\" fxLayoutAlign=\"space-between\">\n <mat-form-field fxFlex=\"100%\">\n <textarea matInput formControlName=\"note\" placeholder=\"{{data?.labelText}}\" autocomplete=\"off\"\n required></textarea>\n <mat-error *ngIf=\"isFieldValid('note')\">{{\n getErrorMessage(\"note\")\n }}</mat-error>\n </mat-form-field>\n\n <div class=\"my-2\" fxLayout=\"row\" fxLayoutGap=\"30px\" fxLayoutAlign=\"end\" fxFlex=\"100%\">\n <button mat-raised-button type=\"button\" (click)=\"cancel()\">\n Cancel\n </button>\n <button mat-raised-button type=\"submit\" color=\"primary\">Save</button>\n </div>\n </div>\n </div>\n </div>\n</form>", styles: [""], dependencies: [{ kind: "directive", type: i3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1$5.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1$5.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$5.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$5.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1$5.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i1$5.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$5.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "directive", type: i6$1.DefaultLayoutDirective, selector: " [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]", inputs: ["fxLayout", "fxLayout.xs", "fxLayout.sm", "fxLayout.md", "fxLayout.lg", "fxLayout.xl", "fxLayout.lt-sm", "fxLayout.lt-md", "fxLayout.lt-lg", "fxLayout.lt-xl", "fxLayout.gt-xs", "fxLayout.gt-sm", "fxLayout.gt-md", "fxLayout.gt-lg"] }, { kind: "directive", type: i6$1.DefaultLayoutGapDirective, selector: " [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]", inputs: ["fxLayoutGap", "fxLayoutGap.xs", "fxLayoutGap.sm", "fxLayoutGap.md", "fxLayoutGap.lg", "fxLayoutGap.xl", "fxLayoutGap.lt-sm", "fxLayoutGap.lt-md", "fxLayoutGap.lt-lg", "fxLayoutGap.lt-xl", "fxLayoutGap.gt-xs", "fxLayoutGap.gt-sm", "fxLayoutGap.gt-md", "fxLayoutGap.gt-lg"] }, { kind: "directive", type: i6$1.DefaultLayoutAlignDirective, selector: " [fxLayoutAlign], [fxLayoutAlign.xs], [fxLayoutAlign.sm], [fxLayoutAlign.md], [fxLayoutAlign.lg], [fxLayoutAlign.xl], [fxLayoutAlign.lt-sm], [fxLayoutAlign.lt-md], [fxLayoutAlign.lt-lg], [fxLayoutAlign.lt-xl], [fxLayoutAlign.gt-xs], [fxLayoutAlign.gt-sm], [fxLayoutAlign.gt-md], [fxLayoutAlign.gt-lg]", inputs: ["fxLayoutAlign", "fxLayoutAlign.xs", "fxLayoutAlign.sm", "fxLayoutAlign.md", "fxLayoutAlign.lg", "fxLayoutAlign.xl", "fxLayoutAlign.lt-sm", "fxLayoutAlign.lt-md", "fxLayoutAlign.lt-lg", "fxLayoutAlign.lt-xl", "fxLayoutAlign.gt-xs", "fxLayoutAlign.gt-sm", "fxLayoutAlign.gt-md", "fxLayoutAlign.gt-lg"] }, { kind: "directive", type: i6$1.DefaultFlexDirective, selector: " [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]", inputs: ["fxFlex", "fxFlex.xs", "fxFlex.sm", "fxFlex.md", "fxFlex.lg", "fxFlex.xl", "fxFlex.lt-sm", "fxFlex.lt-md", "fxFlex.lt-lg", "fxFlex.lt-xl", "fxFlex.gt-xs", "fxFlex.gt-sm", "fxFlex.gt-md", "fxFlex.gt-lg"] }, { kind: "component", type: i6.MatButton, selector: " button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ", exportAs: ["matButton"] }, { kind: "directive", type: i1.MatDialogTitle, selector: "[mat-dialog-title], [matDialogTitle]", inputs: ["id"], exportAs: ["matDialogTitle"] }, { kind: "directive", type: i1.MatDialogContent, selector: "[mat-dialog-content], mat-dialog-content, [matDialogContent]" }, { kind: "component", type: i8$4.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i8$4.MatError, selector: "mat-error, [matError]", inputs: ["id"] }, { kind: "directive", type: i9.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly"], exportAs: ["matInput"] }] }); }
4232
+ }
4233
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: NoteFormComponent, decorators: [{
4234
+ type: Component,
4235
+ args: [{ selector: 'app-note-form', template: "<form [formGroup]=\"noteFormGroup\" (ngSubmit)=\"submit()\">\n <div fxLayout=\"column\" class=\"mat-typography\">\n <div mat-dialog-title class=\"text-center\">\n <div>{{data?.labelText}}</div>\n </div>\n\n <div mat-dialog-content fxLayout=\"column\">\n <div fxLayout=\"row wrap\" fxLayoutAlign=\"space-between\">\n <mat-form-field fxFlex=\"100%\">\n <textarea matInput formControlName=\"note\" placeholder=\"{{data?.labelText}}\" autocomplete=\"off\"\n required></textarea>\n <mat-error *ngIf=\"isFieldValid('note')\">{{\n getErrorMessage(\"note\")\n }}</mat-error>\n </mat-form-field>\n\n <div class=\"my-2\" fxLayout=\"row\" fxLayoutGap=\"30px\" fxLayoutAlign=\"end\" fxFlex=\"100%\">\n <button mat-raised-button type=\"button\" (click)=\"cancel()\">\n Cancel\n </button>\n <button mat-raised-button type=\"submit\" color=\"primary\">Save</button>\n </div>\n </div>\n </div>\n </div>\n</form>" }]
4236
+ }], ctorParameters: () => [{ type: i1.MatDialogRef }, { type: undefined, decorators: [{
4237
+ type: Inject,
4238
+ args: [MAT_DIALOG_DATA]
4239
+ }] }, { type: i1$5.UntypedFormBuilder }, { type: FormValidatorService }, { type: AlertService }, { type: NoteService }] });
4240
+
4241
+ class CommentFormComponent {
4242
+ set commentData(data) {
4243
+ this.view = !!data;
4244
+ this._commentData = data;
4245
+ this.commentFormGroup.patchValue(data);
4327
4246
  }
4328
- filterItems(event) {
4329
- if (event) {
4330
- this.items = this.cachedItems.filter((value) => {
4331
- return value[this.searchField].toLowerCase().search(event.toLowerCase()) != -1;
4332
- });
4247
+ constructor(fb, credentialService) {
4248
+ this.fb = fb;
4249
+ this.credentialService = credentialService;
4250
+ this.action = new EventEmitter();
4251
+ this.createForm();
4252
+ }
4253
+ ngOnInit() { }
4254
+ get isLoggedIn() {
4255
+ return this.credentialService.isAuthenticated;
4256
+ }
4257
+ get currentUser() {
4258
+ return this.credentialService.credentials.user;
4259
+ }
4260
+ createForm() {
4261
+ //TODO: Finialize and add more validations.
4262
+ this.commentFormGroup = this.fb.group({
4263
+ id: [""],
4264
+ note: [""],
4265
+ model_type: [""],
4266
+ related_model_id: [""],
4267
+ });
4268
+ }
4269
+ submit() {
4270
+ if (this.commentFormGroup.get("note").value) {
4271
+ if (this._commentData) {
4272
+ this.view = !this.view;
4273
+ }
4274
+ this.action.emit({ type: "save", value: this.commentFormGroup.value });
4275
+ this.commentFormGroup.reset();
4333
4276
  }
4334
- else {
4335
- this.items = this.cachedItems;
4277
+ else if (this.commentFormGroup.get("id").value) {
4278
+ this.deleteComment();
4336
4279
  }
4337
4280
  }
4338
- addItem(event) {
4339
- const dialogRef = this.dialog.open(this.itemComponent, {
4340
- width: '400px',
4341
- autoFocus: false,
4342
- data: {},
4343
- ...this.addConfig
4344
- });
4345
- dialogRef.afterClosed().subscribe((model) => {
4346
- if (model) {
4347
- this.items.push(model);
4348
- this.selectorForm.get('select_value').setValue(model[this.valueField]);
4349
- this._handleInput();
4350
- }
4351
- });
4352
- event.stopPropagation();
4281
+ hideEdit() {
4282
+ if (this.commentFormGroup.get("id").value) {
4283
+ this.view = !this.view;
4284
+ }
4353
4285
  }
4354
- editItem(event) {
4355
- const dialogRef = this.dialog.open(this.itemComponent, {
4356
- width: '400px',
4357
- autoFocus: false,
4358
- data: {
4359
- item: this.selectedValue
4360
- },
4361
- ...this.editConfig
4362
- });
4363
- dialogRef.afterClosed().subscribe((result) => {
4364
- if (result) {
4365
- this.items = this.items.filter(x => x[this.valueField] !== this.selectedValue[this.valueField]);
4366
- this.items.push(result.item);
4367
- this.selectedValue = null;
4368
- this.selectorForm.get('select_value').setValue(result.item[this.valueField]);
4369
- this._handleInput();
4370
- }
4371
- });
4372
- event.stopPropagation();
4286
+ editComment() {
4287
+ this.view = !this.view;
4288
+ this.commentFormGroup.patchValue(this._commentData);
4373
4289
  }
4374
- ngOnDestroy() {
4375
- this.stateChanges.complete();
4376
- this._focusMonitor.stopMonitoring(this._elementRef);
4377
- this.subscriptions.unsubscribe();
4290
+ deleteComment() {
4291
+ this.action.emit({ type: "delete", value: this.commentFormGroup.value });
4378
4292
  }
4379
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: SearchableSelectorComponent, deps: [{ token: i1$5.UntypedFormBuilder }, { token: i1$4.FocusMonitor }, { token: HttpService }, { token: i0.ElementRef }, { token: i1.MatDialog }, { token: i1$5.NgControl, optional: true, self: true }], target: i0.ɵɵFactoryTarget.Component }); }
4380
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.14", type: SearchableSelectorComponent, selector: "app-searchable-selector", inputs: { valueField: "valueField", titleField: "titleField", subtitleField: "subtitleField", apiUrl: "apiUrl", multiple: "multiple", selectedValue: "selectedValue", enableSearch: "enableSearch", add: "add", addConfig: "addConfig", edit: "edit", editConfig: "editConfig", sort: "sort", sortBy: "sortBy", searchField: "searchField", itemComponent: "itemComponent", items: "items", apiDataProperty: "apiDataProperty", cache: "cache", perPage: "perPage", inDataSearch: "inDataSearch", panelWidth: "panelWidth", focusSearchOnOpen: "focusSearchOnOpen", isEmitInitialEvent: "isEmitInitialEvent", required: "required", disabled: "disabled", value: "value" }, outputs: { selectedValueChange: "selectedValueChange", selectionChange: "selectionChange", itemsChange: "itemsChange", isItemsEmpty: "isItemsEmpty" }, providers: [
4381
- {
4382
- provide: MatFormFieldControl,
4383
- useExisting: SearchableSelectorComponent
4384
- }
4385
- ], viewQueries: [{ propertyName: "searchInput", first: true, predicate: ["searchInput"], descendants: true }], ngImport: i0, template: "<ng-container [formGroup]=\"selectorForm\">\n <div class=\"searchable-selector-container\">\n <!-- Selector and Suffix Icons -->\n <mat-select formControlName=\"select_value\" [multiple]=\"multiple\" [required]=\"required\"\n (selectionChange)=\"this.isEmitInitialEvent = false;_handleInput()\" (openedChange)=\"openedChange($event)\"\n [panelWidth]=\"panelWidth\">\n <!-- Search Field -->\n <mat-form-field *ngIf=\"enableSearch\" class=\"p-1 w-100\">\n <input matInput formControlName=\"search\" placeholder=\"Search...\" (keydown)=\"$event.stopPropagation();\"\n autocomplete=\"off\" #searchInput>\n </mat-form-field>\n\n <!-- Options with Scrollable Container -->\n <div class=\"searchable-selector-scrollable-container\" cdkScrollable (scrollend)=\"onScroll()\">\n <mat-option *ngFor=\"let item of dataItems\" [value]=\"getPropertyValue(item, valueField)\">\n <span>{{ getPropertyValue(item, titleField) }}</span>\n <span *ngIf=\"subtitleField\" class=\"text-secondary\" style=\"font-size: 14px;\">\n - {{ getPropertyValue(item, subtitleField) }}\n </span>\n </mat-option>\n <mat-progress-bar *ngIf=\"isLoading\" color=\"primary\" mode=\"indeterminate\"></mat-progress-bar>\n </div>\n </mat-select>\n\n <!-- Add and Edit Buttons -->\n <mat-icon class=\"cursor-pointer\" *ngIf=\"add\" (click)=\"addItem($event)\">\n add\n </mat-icon>\n <mat-icon class=\"cursor-pointer\" *ngIf=\"edit && selectedValue\" (click)=\"editItem($event)\">\n edit\n </mat-icon>\n </div>\n</ng-container>", styles: [".searchable-selector-container{display:flex;align-items:center}.searchable-selector-container mat-select{flex-grow:1}.searchable-selector-container mat-icon{margin-left:2px}.relative-icon{position:relative;top:-4px}.searchable-selector-scrollable-container{max-height:175px;overflow-y:auto}:host ::ng-deep .mat-mdc-floating-label{pointer-events:none!important}\n"], dependencies: [{ kind: "directive", type: i3.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1$5.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$5.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$5.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1$5.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i1$5.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$5.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "component", type: i8$4.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "component", type: i8.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "directive", type: i9.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly"], exportAs: ["matInput"] }, { kind: "directive", type: i9$1.CdkScrollable, selector: "[cdk-scrollable], [cdkScrollable]" }, { kind: "component", type: i5.MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "component", type: i9$2.MatSelect, selector: "mat-select", inputs: ["aria-describedby", "panelClass", "disabled", "disableRipple", "tabIndex", "hideSingleSelectionIndicator", "placeholder", "required", "multiple", "disableOptionCentering", "compareWith", "value", "aria-label", "aria-labelledby", "errorStateMatcher", "typeaheadDebounceInterval", "sortComparator", "id", "panelWidth"], outputs: ["openedChange", "opened", "closed", "selectionChange", "valueChange"], exportAs: ["matSelect"] }, { kind: "component", type: i11$2.MatProgressBar, selector: "mat-progress-bar", inputs: ["color", "value", "bufferValue", "mode"], outputs: ["animationEnd"], exportAs: ["matProgressBar"] }] }); }
4293
+ ngOnDestroy() { }
4294
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: CommentFormComponent, deps: [{ token: i1$5.UntypedFormBuilder }, { token: CredentialsService }], target: i0.ɵɵFactoryTarget.Component }); }
4295
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.14", type: CommentFormComponent, selector: "app-comment-form", inputs: { commentData: "commentData" }, outputs: { action: "action" }, ngImport: i0, template: "<form (ngSubmit)=\"submit()\" [formGroup]=\"commentFormGroup\">\n <div fxLayout=\"column\" class=\"my-2\" [ngClass]=\"{ 'border border-primary shadow rounded ': view}\">\n <div *ngIf=\"!view\" fxLayout=\"column\">\n <mat-form-field appearance=\"outline\" style=\"background-color:white;\">\n <mat-label>Comment</mat-label>\n <textarea matInput rows=\"5\" placeholder=\"Add a comment...\" formControlName=\"note\" autocomplete=\"off\"></textarea>\n </mat-form-field>\n\n <div fxLayout fxLayoutGap=\"1rem\" class=\"mt-2\">\n <span fxFlex></span>\n <button *ngIf=\"_commentData\" mat-button type=\"button\" (click)=\"view = !view\">\n Cancel\n </button>\n <button mat-raised-button color=\"primary\" type=\"submit\">\n {{ _commentData ? \"Update\" : \"Post comment\" }}\n </button>\n </div>\n </div>\n\n <div fxLayout=\"column\" *ngIf=\"view\" class=\"p-2 m-2\">\n <div fxLayout=\"row wrap\" fxLayoutGap=\".5rem\">\n <div fxFlex=\"20%\" fxLayoutAlign=\"start\">\n <button mat-icon-button type=\"button\" style=\"color:grey\">\n <mat-icon style=\"font-size:60px\">account_circle</mat-icon>\n </button>\n </div>\n <div fxFlex=\"75%\">\n <div fxLayout=\"column\" fxLayoutGap=\".5rem\">\n <div class=\"font-weight-bold\">{{ _commentData?.creator?.name }}</div>\n <div class=\"text-muted\">{{ _commentData.updated_at | date:'medium' }}</div>\n </div>\n </div>\n </div>\n <app-read-more class=\"mt-2\" [text]=\"_commentData.note\"></app-read-more>\n <div fxLayout class=\"mt-1\" fxLayoutGap=\"1rem\" *ngIf=\"isLoggedIn && currentUser.id === _commentData.creator_id\">\n <a href=\"javascript:;\" (click)=\"editComment()\">\n Edit\n </a>\n <a href=\"javascript:;\" (click)=\"deleteComment()\">\n Delete\n </a>\n </div>\n </div>\n </div>\n</form>", styles: [":host ::ng-deep .mat-form-field-wrapper{padding-bottom:0!important;margin:0!important}\n"], dependencies: [{ kind: "directive", type: i3.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1$5.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1$5.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$5.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$5.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1$5.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$5.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "directive", type: i6$1.DefaultLayoutDirective, selector: " [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]", inputs: ["fxLayout", "fxLayout.xs", "fxLayout.sm", "fxLayout.md", "fxLayout.lg", "fxLayout.xl", "fxLayout.lt-sm", "fxLayout.lt-md", "fxLayout.lt-lg", "fxLayout.lt-xl", "fxLayout.gt-xs", "fxLayout.gt-sm", "fxLayout.gt-md", "fxLayout.gt-lg"] }, { kind: "directive", type: i6$1.DefaultLayoutGapDirective, selector: " [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]", inputs: ["fxLayoutGap", "fxLayoutGap.xs", "fxLayoutGap.sm", "fxLayoutGap.md", "fxLayoutGap.lg", "fxLayoutGap.xl", "fxLayoutGap.lt-sm", "fxLayoutGap.lt-md", "fxLayoutGap.lt-lg", "fxLayoutGap.lt-xl", "fxLayoutGap.gt-xs", "fxLayoutGap.gt-sm", "fxLayoutGap.gt-md", "fxLayoutGap.gt-lg"] }, { kind: "directive", type: i6$1.DefaultLayoutAlignDirective, selector: " [fxLayoutAlign], [fxLayoutAlign.xs], [fxLayoutAlign.sm], [fxLayoutAlign.md], [fxLayoutAlign.lg], [fxLayoutAlign.xl], [fxLayoutAlign.lt-sm], [fxLayoutAlign.lt-md], [fxLayoutAlign.lt-lg], [fxLayoutAlign.lt-xl], [fxLayoutAlign.gt-xs], [fxLayoutAlign.gt-sm], [fxLayoutAlign.gt-md], [fxLayoutAlign.gt-lg]", inputs: ["fxLayoutAlign", "fxLayoutAlign.xs", "fxLayoutAlign.sm", "fxLayoutAlign.md", "fxLayoutAlign.lg", "fxLayoutAlign.xl", "fxLayoutAlign.lt-sm", "fxLayoutAlign.lt-md", "fxLayoutAlign.lt-lg", "fxLayoutAlign.lt-xl", "fxLayoutAlign.gt-xs", "fxLayoutAlign.gt-sm", "fxLayoutAlign.gt-md", "fxLayoutAlign.gt-lg"] }, { kind: "directive", type: i6$1.DefaultFlexDirective, selector: " [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]", inputs: ["fxFlex", "fxFlex.xs", "fxFlex.sm", "fxFlex.md", "fxFlex.lg", "fxFlex.xl", "fxFlex.lt-sm", "fxFlex.lt-md", "fxFlex.lt-lg", "fxFlex.lt-xl", "fxFlex.gt-xs", "fxFlex.gt-sm", "fxFlex.gt-md", "fxFlex.gt-lg"] }, { kind: "directive", type: i2.DefaultClassDirective, selector: " [ngClass], [ngClass.xs], [ngClass.sm], [ngClass.md], [ngClass.lg], [ngClass.xl], [ngClass.lt-sm], [ngClass.lt-md], [ngClass.lt-lg], [ngClass.lt-xl], [ngClass.gt-xs], [ngClass.gt-sm], [ngClass.gt-md], [ngClass.gt-lg]", inputs: ["ngClass", "ngClass.xs", "ngClass.sm", "ngClass.md", "ngClass.lg", "ngClass.xl", "ngClass.lt-sm", "ngClass.lt-md", "ngClass.lt-lg", "ngClass.lt-xl", "ngClass.gt-xs", "ngClass.gt-sm", "ngClass.gt-md", "ngClass.gt-lg"] }, { kind: "component", type: i6.MatButton, selector: " button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ", exportAs: ["matButton"] }, { kind: "component", type: i6.MatIconButton, selector: "button[mat-icon-button]", exportAs: ["matButton"] }, { kind: "component", type: i8$4.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i8$4.MatLabel, selector: "mat-label" }, { kind: "component", type: i8.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "directive", type: i9.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly"], exportAs: ["matInput"] }, { kind: "component", type: ReadMoreComponent, selector: "app-read-more", inputs: ["text", "maxLength"] }, { kind: "pipe", type: i3.DatePipe, name: "date" }] }); }
4386
4296
  }
4387
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: SearchableSelectorComponent, decorators: [{
4297
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: CommentFormComponent, decorators: [{
4388
4298
  type: Component,
4389
- args: [{ selector: 'app-searchable-selector', providers: [
4390
- {
4391
- provide: MatFormFieldControl,
4392
- useExisting: SearchableSelectorComponent
4393
- }
4394
- ], template: "<ng-container [formGroup]=\"selectorForm\">\n <div class=\"searchable-selector-container\">\n <!-- Selector and Suffix Icons -->\n <mat-select formControlName=\"select_value\" [multiple]=\"multiple\" [required]=\"required\"\n (selectionChange)=\"this.isEmitInitialEvent = false;_handleInput()\" (openedChange)=\"openedChange($event)\"\n [panelWidth]=\"panelWidth\">\n <!-- Search Field -->\n <mat-form-field *ngIf=\"enableSearch\" class=\"p-1 w-100\">\n <input matInput formControlName=\"search\" placeholder=\"Search...\" (keydown)=\"$event.stopPropagation();\"\n autocomplete=\"off\" #searchInput>\n </mat-form-field>\n\n <!-- Options with Scrollable Container -->\n <div class=\"searchable-selector-scrollable-container\" cdkScrollable (scrollend)=\"onScroll()\">\n <mat-option *ngFor=\"let item of dataItems\" [value]=\"getPropertyValue(item, valueField)\">\n <span>{{ getPropertyValue(item, titleField) }}</span>\n <span *ngIf=\"subtitleField\" class=\"text-secondary\" style=\"font-size: 14px;\">\n - {{ getPropertyValue(item, subtitleField) }}\n </span>\n </mat-option>\n <mat-progress-bar *ngIf=\"isLoading\" color=\"primary\" mode=\"indeterminate\"></mat-progress-bar>\n </div>\n </mat-select>\n\n <!-- Add and Edit Buttons -->\n <mat-icon class=\"cursor-pointer\" *ngIf=\"add\" (click)=\"addItem($event)\">\n add\n </mat-icon>\n <mat-icon class=\"cursor-pointer\" *ngIf=\"edit && selectedValue\" (click)=\"editItem($event)\">\n edit\n </mat-icon>\n </div>\n</ng-container>", styles: [".searchable-selector-container{display:flex;align-items:center}.searchable-selector-container mat-select{flex-grow:1}.searchable-selector-container mat-icon{margin-left:2px}.relative-icon{position:relative;top:-4px}.searchable-selector-scrollable-container{max-height:175px;overflow-y:auto}:host ::ng-deep .mat-mdc-floating-label{pointer-events:none!important}\n"] }]
4395
- }], ctorParameters: () => [{ type: i1$5.UntypedFormBuilder }, { type: i1$4.FocusMonitor }, { type: HttpService }, { type: i0.ElementRef }, { type: i1.MatDialog }, { type: i1$5.NgControl, decorators: [{
4396
- type: Optional
4397
- }, {
4398
- type: Self
4399
- }] }], propDecorators: { searchInput: [{
4400
- type: ViewChild,
4401
- args: ['searchInput']
4402
- }], valueField: [{
4403
- type: Input
4404
- }], titleField: [{
4405
- type: Input
4406
- }], subtitleField: [{
4407
- type: Input
4408
- }], apiUrl: [{
4409
- type: Input
4410
- }], multiple: [{
4411
- type: Input
4412
- }], selectedValue: [{
4413
- type: Input
4414
- }], selectedValueChange: [{
4415
- type: Output
4416
- }], enableSearch: [{
4417
- type: Input
4418
- }], add: [{
4419
- type: Input
4420
- }], addConfig: [{
4421
- type: Input
4422
- }], edit: [{
4423
- type: Input
4424
- }], editConfig: [{
4425
- type: Input
4426
- }], sort: [{
4427
- type: Input
4428
- }], sortBy: [{
4429
- type: Input
4430
- }], searchField: [{
4431
- type: Input
4432
- }], itemComponent: [{
4433
- type: Input
4434
- }], items: [{
4435
- type: Input
4436
- }], apiDataProperty: [{
4437
- type: Input
4438
- }], cache: [{
4439
- type: Input
4440
- }], perPage: [{
4441
- type: Input
4442
- }], inDataSearch: [{
4443
- type: Input
4444
- }], panelWidth: [{
4445
- type: Input
4446
- }], selectionChange: [{
4447
- type: Output
4448
- }], itemsChange: [{
4449
- type: Output
4450
- }], focusSearchOnOpen: [{
4299
+ args: [{ selector: "app-comment-form", template: "<form (ngSubmit)=\"submit()\" [formGroup]=\"commentFormGroup\">\n <div fxLayout=\"column\" class=\"my-2\" [ngClass]=\"{ 'border border-primary shadow rounded ': view}\">\n <div *ngIf=\"!view\" fxLayout=\"column\">\n <mat-form-field appearance=\"outline\" style=\"background-color:white;\">\n <mat-label>Comment</mat-label>\n <textarea matInput rows=\"5\" placeholder=\"Add a comment...\" formControlName=\"note\" autocomplete=\"off\"></textarea>\n </mat-form-field>\n\n <div fxLayout fxLayoutGap=\"1rem\" class=\"mt-2\">\n <span fxFlex></span>\n <button *ngIf=\"_commentData\" mat-button type=\"button\" (click)=\"view = !view\">\n Cancel\n </button>\n <button mat-raised-button color=\"primary\" type=\"submit\">\n {{ _commentData ? \"Update\" : \"Post comment\" }}\n </button>\n </div>\n </div>\n\n <div fxLayout=\"column\" *ngIf=\"view\" class=\"p-2 m-2\">\n <div fxLayout=\"row wrap\" fxLayoutGap=\".5rem\">\n <div fxFlex=\"20%\" fxLayoutAlign=\"start\">\n <button mat-icon-button type=\"button\" style=\"color:grey\">\n <mat-icon style=\"font-size:60px\">account_circle</mat-icon>\n </button>\n </div>\n <div fxFlex=\"75%\">\n <div fxLayout=\"column\" fxLayoutGap=\".5rem\">\n <div class=\"font-weight-bold\">{{ _commentData?.creator?.name }}</div>\n <div class=\"text-muted\">{{ _commentData.updated_at | date:'medium' }}</div>\n </div>\n </div>\n </div>\n <app-read-more class=\"mt-2\" [text]=\"_commentData.note\"></app-read-more>\n <div fxLayout class=\"mt-1\" fxLayoutGap=\"1rem\" *ngIf=\"isLoggedIn && currentUser.id === _commentData.creator_id\">\n <a href=\"javascript:;\" (click)=\"editComment()\">\n Edit\n </a>\n <a href=\"javascript:;\" (click)=\"deleteComment()\">\n Delete\n </a>\n </div>\n </div>\n </div>\n</form>", styles: [":host ::ng-deep .mat-form-field-wrapper{padding-bottom:0!important;margin:0!important}\n"] }]
4300
+ }], ctorParameters: () => [{ type: i1$5.UntypedFormBuilder }, { type: CredentialsService }], propDecorators: { commentData: [{
4451
4301
  type: Input
4452
- }], isItemsEmpty: [{
4302
+ }], action: [{
4453
4303
  type: Output
4454
- }], isEmitInitialEvent: [{
4455
- type: Input
4456
- }], required: [{
4457
- type: Input
4458
- }], disabled: [{
4459
- type: Input
4460
- }], value: [{
4461
- type: Input
4462
4304
  }] } });
4463
4305
 
4464
- /**
4465
- * Component to generate a num items selector
4466
- *
4467
- * @author Floyd Kissoon
4468
- * @since 20170817
4469
- */
4470
- class NumItemsSelector {
4471
- constructor() {
4472
- this.numItemsChange = new EventEmitter();
4306
+ class NoteListComponent extends TechlifyListComponent {
4307
+ constructor(noteService, dialog, alertService) {
4308
+ super();
4309
+ this.noteService = noteService;
4310
+ this.dialog = dialog;
4311
+ this.alertService = alertService;
4312
+ this.readonly = false;
4313
+ this.labelText = 'Note';
4314
+ this.commentsView = false;
4315
+ this.viewMode = 'list';
4316
+ this.displayedColumns = [
4317
+ 'index',
4318
+ 'note',
4319
+ 'actions'
4320
+ ];
4321
+ this.isSaving = false;
4322
+ this.total = 0;
4323
+ this.lastPage = 0;
4324
+ this.filters = {};
4325
+ this.filters.sort_by = 'created_at|DESC';
4473
4326
  }
4474
- /**
4475
- * Called when an item has been selected
4476
- */
4477
- numItemsChanged() {
4478
- this.numItemsChange.emit(this.numItems);
4327
+ ngOnInit() {
4328
+ if (this.readonly) {
4329
+ this.displayedColumns = this.displayedColumns.filter(x => x !== 'actions');
4330
+ }
4331
+ this.filters.related_model_id = this.relatedModelId;
4332
+ this.filters.model_type = this.modelType;
4333
+ this.loadData();
4479
4334
  }
4480
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: NumItemsSelector, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
4481
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.14", type: NumItemsSelector, selector: "num-items-selector", inputs: { numItems: "numItems" }, outputs: { numItemsChange: "numItemsChange" }, ngImport: i0, template: "<select [(ngModel)]=\"numItems\" class=\"form-control\" id=\"numItems\" name=\"numItems\" (change)=\"numItemsChanged()\">\r\n <option value=\"25\">25</option>\r\n <option value=\"50\">50</option>\r\n <option value=\"100\">100</option>\r\n <option value=\"250\">250</option>\r\n <option value=\"500\">500</option>\r\n <option value=\"1000\">1000</option>\r\n <option value=\"2000\">2000</option>\r\n <option value=\"3000\">3000</option>\r\n <option value=\"4000\">4000</option>\r\n <option value=\"5000\">5000</option>\r\n <option value=\"5000000000\">All</option>\r\n</select> ", dependencies: [{ kind: "directive", type: i1$5.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i1$5.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i1$5.SelectControlValueAccessor, selector: "select:not([multiple])[formControlName],select:not([multiple])[formControl],select:not([multiple])[ngModel]", inputs: ["compareWith"] }, { kind: "directive", type: i1$5.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$5.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }] }); }
4482
- }
4483
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: NumItemsSelector, decorators: [{
4484
- type: Component,
4485
- args: [{ selector: "num-items-selector", template: "<select [(ngModel)]=\"numItems\" class=\"form-control\" id=\"numItems\" name=\"numItems\" (change)=\"numItemsChanged()\">\r\n <option value=\"25\">25</option>\r\n <option value=\"50\">50</option>\r\n <option value=\"100\">100</option>\r\n <option value=\"250\">250</option>\r\n <option value=\"500\">500</option>\r\n <option value=\"1000\">1000</option>\r\n <option value=\"2000\">2000</option>\r\n <option value=\"3000\">3000</option>\r\n <option value=\"4000\">4000</option>\r\n <option value=\"5000\">5000</option>\r\n <option value=\"5000000000\">All</option>\r\n</select> " }]
4486
- }], ctorParameters: () => [], propDecorators: { numItems: [{
4487
- type: Input
4488
- }], numItemsChange: [{
4489
- type: Output
4490
- }] } });
4491
-
4492
- /**
4493
- * Service that provides utility functions for dates
4494
- *
4495
- * @author Joshua Kissoon
4496
- * @since 20170726
4497
- */
4498
- class DateUtils {
4499
- /**
4500
- * Takes in a date object and outputs the string value
4501
- */
4502
- getYYYYMMDDString(inputDate) {
4503
- var year = inputDate.getFullYear();
4504
- var month = (inputDate.getMonth() + 1) < 10 ? ("0" + (inputDate.getMonth() + 1)) : (inputDate.getMonth() + 1);
4505
- var date = inputDate.getDate() < 10 ? ("0" + inputDate.getDate()) : inputDate.getDate();
4506
- return year + "-" + month + "-" + date;
4335
+ loadData() {
4336
+ this.isWorking = true;
4337
+ this.noteService.getNotes({
4338
+ ...this.filters,
4339
+ page: this.page,
4340
+ with: 'creator'
4341
+ }).then((result) => {
4342
+ this.models = this.models.concat(result?.data);
4343
+ this.lastPage = result?.last_page;
4344
+ this.isWorking = false;
4345
+ this.total = result?.total;
4346
+ }, () => {
4347
+ this.isWorking = false;
4348
+ });
4507
4349
  }
4508
- /**
4509
- * Takes in a date object and outputs the year
4510
- */
4511
- getYYYY(inputDate) {
4512
- var year = inputDate.getFullYear();
4513
- return year;
4350
+ addNote() {
4351
+ const dialogRef = this.dialog.open(NoteFormComponent, {
4352
+ width: '400px',
4353
+ data: {
4354
+ note: { related_model_id: this.relatedModelId, model_type: this.modelType },
4355
+ labelText: this.labelText,
4356
+ },
4357
+ autoFocus: false
4358
+ });
4359
+ dialogRef.afterClosed().subscribe(result => {
4360
+ if (result) {
4361
+ this.reload();
4362
+ }
4363
+ });
4514
4364
  }
4515
- /**
4516
- * Takes in a date object and outputs the Month
4517
- */
4518
- getMM(inputDate) {
4519
- var month = inputDate.getMonth() + 1;
4520
- return month;
4365
+ editNote(note) {
4366
+ const dialogRef = this.dialog.open(NoteFormComponent, {
4367
+ width: '400px',
4368
+ data: {
4369
+ note,
4370
+ update: true,
4371
+ labelText: this.labelText
4372
+ },
4373
+ autoFocus: false
4374
+ });
4375
+ dialogRef.afterClosed().subscribe(result => {
4376
+ if (result) {
4377
+ this.reload();
4378
+ }
4379
+ });
4521
4380
  }
4522
- // var n = this.rfidCardUseManualEntry.manual_date.toLocaleTimeString();
4523
- getDateTime(inputDate) {
4524
- var year = inputDate.getFullYear();
4525
- var month = (inputDate.getMonth() + 1) < 10 ? ("0" + (inputDate.getMonth() + 1)) : (inputDate.getMonth() + 1);
4526
- var date = inputDate.getDate() < 10 ? ("0" + inputDate.getDate()) : inputDate.getDate();
4527
- var time = inputDate.toLocaleTimeString();
4528
- return year + "-" + month + "-" + date + " " + time;
4381
+ async deleteNote(note) {
4382
+ const dialogRef = this.dialog.open(ActionPopupComponent, {
4383
+ width: '400px',
4384
+ data: {
4385
+ title: `Delete ${this.labelText}`,
4386
+ message: `Are you sure to delete?`
4387
+ },
4388
+ autoFocus: false
4389
+ });
4390
+ dialogRef.afterClosed().subscribe(async (result) => {
4391
+ if (result) {
4392
+ // Action confirmed
4393
+ await this.noteService.deleteNote(note);
4394
+ this.models = this.models.filter((item) => item.id !== note.id);
4395
+ }
4396
+ });
4529
4397
  }
4530
- getMonthName(month) {
4531
- const months = [
4532
- 'January',
4533
- 'February',
4534
- 'March',
4535
- 'April',
4536
- 'May',
4537
- 'June',
4538
- 'July',
4539
- 'August',
4540
- 'September',
4541
- 'October',
4542
- 'November',
4543
- 'December'
4544
- ];
4545
- return months[month - 1] ?? '';
4398
+ commentAction(event) {
4399
+ if (event.type === 'save') {
4400
+ if (event.value.id) {
4401
+ this.editComment(event.value);
4402
+ return;
4403
+ }
4404
+ this.addComment(event.value);
4405
+ return;
4406
+ }
4407
+ this.deleteNote(event.value);
4546
4408
  }
4547
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: DateUtils, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
4548
- static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: DateUtils, providedIn: 'root' }); }
4549
- }
4550
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: DateUtils, decorators: [{
4551
- type: Injectable,
4552
- args: [{
4553
- providedIn: 'root'
4554
- }]
4555
- }] });
4556
-
4557
- /**
4558
- * Component to generate a number selector
4559
- *
4560
- * @author Floyd Kissoon
4561
- * @since 20180628
4562
- */
4563
- class NumberSelector {
4564
- constructor() {
4565
- this.items = new Array();
4566
- this.selectedValueChange = new EventEmitter();
4409
+ async editComment(comment) {
4410
+ const result = await this.noteService.editNote(comment);
4411
+ const index = this.models.findIndex((x) => x.id === comment.id);
4412
+ if (index !== -1) {
4413
+ this.models[index] = result.item;
4414
+ }
4567
4415
  }
4568
- /**
4569
- * Called when an item has been selected
4570
- */
4571
- numChanged() {
4572
- this.selectedValueChange.emit(this.selectedValue);
4416
+ async addComment(comment) {
4417
+ comment.related_model_id = this.relatedModelId;
4418
+ comment.model_type = this.modelType;
4419
+ const result = await this.noteService.addNote(comment);
4420
+ this.models.push(result.item);
4573
4421
  }
4574
- ngOnInit() {
4575
- for (var i = this.start_value; i < this.end_value + 1; i++) {
4576
- this.items.push(i);
4422
+ saveNote() {
4423
+ if (!this.note) {
4424
+ this.alertService.addAlert('Please enter the note', 'error');
4425
+ return;
4577
4426
  }
4427
+ const data = {
4428
+ note: this.note,
4429
+ model_type: this.modelType,
4430
+ related_model_id: this.relatedModelId,
4431
+ with: 'creator',
4432
+ };
4433
+ this.isSaving = true;
4434
+ this.noteService.addNote(data).then((response) => {
4435
+ this.modelCreated(response?.item);
4436
+ this.alertService.addAlert('The note saved successfully.', 'success');
4437
+ this.note = '';
4438
+ this.isSaving = false;
4439
+ this.total += 1;
4440
+ }).catch(() => (this.isSaving = false));
4578
4441
  }
4579
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: NumberSelector, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
4580
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.14", type: NumberSelector, selector: "number-selector", inputs: { start_value: "start_value", end_value: "end_value", selectedValue: "selectedValue" }, outputs: { selectedValueChange: "selectedValueChange" }, ngImport: i0, template: "<div class=\"number-selector-wrapper\">\n <select name=\"selectedValue\" [(ngModel)]=\"selectedValue\" class=\"form-control\" (change)=\"numChanged()\">\n <option value=\"\">-- Student Status --</option>\n <option *ngFor=\"let start_value of items;\" value=\"{{start_value}}\">{{start_value}}</option>\n </select>\n</div>", dependencies: [{ kind: "directive", type: i3.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1$5.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i1$5.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i1$5.SelectControlValueAccessor, selector: "select:not([multiple])[formControlName],select:not([multiple])[formControl],select:not([multiple])[ngModel]", inputs: ["compareWith"] }, { kind: "directive", type: i1$5.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$5.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }] }); }
4442
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: NoteListComponent, deps: [{ token: NoteService }, { token: i1.MatDialog }, { token: AlertService }], target: i0.ɵɵFactoryTarget.Component }); }
4443
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.14", type: NoteListComponent, selector: "app-note-list", inputs: { relatedModelId: "relatedModelId", modelType: "modelType", readonly: "readonly", labelText: "labelText", commentsView: "commentsView", viewMode: "viewMode" }, usesInheritance: true, ngImport: i0, template: "<div fxLayout=\"column\" fxLayoutGap=\"1.5rem\" *ngIf=\"!commentsView\">\n\n <ng-container *ngIf=\"viewMode === 'list'\">\n <div class=\"d-flex align-items-center\">\n <h5 class=\"m-0\">{{ labelText }}s</h5>\n <app-techlify-icon name=\"add\" class=\"clickable d-print-none ml-1\" matTooltip=\"Add\"\n (click)=\"addNote()\"></app-techlify-icon>\n </div>\n\n <div class=\"w-100 scroll-container\" infiniteScroll [infiniteScrollDistance]=\"1\" [infiniteScrollThrottle]=\"50\"\n (scrolled)=\"onScroll()\" [scrollWindow]=\"false\">\n <table mat-table [dataSource]=\"models\" class=\"w-100\" multiTemplateDataRows>\n\n <!-- Index Column -->\n <ng-container matColumnDef=\"index\">\n <th mat-header-cell *matHeaderCellDef> #</th>\n <td mat-cell *matCellDef=\"let note; let i = dataIndex\"> {{ i + 1 }}</td>\n </ng-container>\n\n\n <ng-container matColumnDef=\"note\">\n <th mat-header-cell *matHeaderCellDef> {{ labelText }}</th>\n <td mat-cell *matCellDef=\"let note\">\n {{ note?.note }}\n </td>\n </ng-container>\n\n <ng-container matColumnDef=\"actions\">\n <th mat-header-cell *matHeaderCellDef class=\"d-print-none\"> Actions</th>\n <td mat-cell *matCellDef=\"let note\" class=\"d-print-none text-secondary\">\n <div fxLayoutAlign=\"start center\">\n <app-techlify-icon name=\"edit\" class=\"clickable\" matTooltip=\"Update\"\n (click)=\"editNote(note)\"></app-techlify-icon>\n <app-techlify-icon name=\"delete\" class=\"clickable ml-1\" matTooltip=\"Delete\"\n (click)=\"deleteNote(note)\"></app-techlify-icon>\n </div>\n </td>\n </ng-container>\n <tr mat-header-row *matHeaderRowDef=\"displayedColumns\"></tr>\n <tr mat-row *matRowDef=\"let row; columns: displayedColumns;\"></tr>\n </table>\n <mat-progress-bar mode=\"indeterminate\" *ngIf=\"isWorking\"></mat-progress-bar>\n </div>\n </ng-container>\n\n <ng-container *ngIf=\"viewMode === 'timeline'\">\n <mat-card>\n <mat-card-content class=\"d-flex justify-content-start align-items-center gap-2\">\n <h5 class=\"mb-0\">Notes</h5>\n <span class=\"badge badge-info ml-1\" *ngIf=\"total\">{{ total }}</span>\n </mat-card-content>\n <mat-card-content class=\"mt-2\">\n <form (ngSubmit)=\"saveNote()\">\n <mat-form-field class=\"w-100\" appearance=\"outline\">\n <input [(ngModel)]=\"note\" [ngModelOptions]=\"{standalone: true}\" type=\"text\" matInput\n placeholder=\"Write your notes here...\" [disabled]=\"isSaving\">\n <mat-icon *ngIf=\"!isSaving\" matSuffix class=\"cursor-pointer\" (click)=\"saveNote()\">send</mat-icon>\n <mat-progress-spinner matSuffix mode=\"indeterminate\" diameter=\"20\" *ngIf=\"isSaving\"></mat-progress-spinner>\n </mat-form-field>\n </form>\n </mat-card-content>\n <mat-card-content>\n <div *ngFor=\"let note of models;last as isLast\">\n <div class=\"d-flex justify-content-between align-items-center gap-2\">\n <div class=\"d-flex flex-column\">\n <p class=\"mb-0\">{{ note?.creator?.name }}</p>\n <small class=\"text-secondary\">On {{ note?.created_at | date: 'medium' }}</small>\n </div>\n <div class=\"d-flex justify-content-end align-items-center gap-1\">\n <app-techlify-icon name=\"edit\" class=\"clickable\" matTooltip=\"Update\"\n (click)=\"editNote(note)\"></app-techlify-icon>\n <app-techlify-icon name=\"delete\" class=\"clickable\" matTooltip=\"Delete\"\n (click)=\"deleteNote(note)\"></app-techlify-icon>\n </div>\n </div>\n <div>{{ note?.note }}</div>\n <mat-divider class=\"my-2\" *ngIf=\"!isLast\"></mat-divider>\n </div>\n <mat-progress-bar mode=\"indeterminate\" *ngIf=\"isWorking\"></mat-progress-bar>\n </mat-card-content>\n </mat-card>\n </ng-container>\n\n</div>\n\n<div fxLayout=\"column\" fxLayoutGap=\"1.5rem\" *ngIf=\"commentsView\">\n <div fxLayout fxLayoutAlign=\"center center\" fxLayoutGap=\"1rem\">\n <h5 class=\"m-0\">{{ labelText }}s</h5>\n </div>\n\n <div fxLayout=\"column\" fxLayoutAlign=\"start\" fxFlex=\"100%\">\n <div class=\"w-100 scroll-container jumbotron\" infiniteScroll [infiniteScrollDistance]=\"1\"\n [infiniteScrollThrottle]=\"50\" (scrolled)=\"onScroll()\" [scrollWindow]=\"false\">\n <app-comment-form [commentData]=\"comment\" (action)=\"commentAction($event)\" *ngFor=\"let comment of models\">\n </app-comment-form>\n <app-comment-form (action)=\"commentAction($event)\"></app-comment-form>\n </div>\n </div>\n</div>", styles: [".scroll-container{max-height:400px;overflow-y:auto}\n"], dependencies: [{ kind: "directive", type: i3.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1$5.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1$5.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$5.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$5.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i6$2.InfiniteScrollDirective, selector: "[infiniteScroll], [infinite-scroll], [data-infinite-scroll]", inputs: ["infiniteScrollDistance", "infiniteScrollUpDistance", "infiniteScrollThrottle", "infiniteScrollDisabled", "infiniteScrollContainer", "scrollWindow", "immediateCheck", "horizontal", "alwaysCallback", "fromRoot"], outputs: ["scrolled", "scrolledUp"] }, { kind: "directive", type: i6$1.DefaultLayoutDirective, selector: " [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]", inputs: ["fxLayout", "fxLayout.xs", "fxLayout.sm", "fxLayout.md", "fxLayout.lg", "fxLayout.xl", "fxLayout.lt-sm", "fxLayout.lt-md", "fxLayout.lt-lg", "fxLayout.lt-xl", "fxLayout.gt-xs", "fxLayout.gt-sm", "fxLayout.gt-md", "fxLayout.gt-lg"] }, { kind: "directive", type: i6$1.DefaultLayoutGapDirective, selector: " [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]", inputs: ["fxLayoutGap", "fxLayoutGap.xs", "fxLayoutGap.sm", "fxLayoutGap.md", "fxLayoutGap.lg", "fxLayoutGap.xl", "fxLayoutGap.lt-sm", "fxLayoutGap.lt-md", "fxLayoutGap.lt-lg", "fxLayoutGap.lt-xl", "fxLayoutGap.gt-xs", "fxLayoutGap.gt-sm", "fxLayoutGap.gt-md", "fxLayoutGap.gt-lg"] }, { kind: "directive", type: i6$1.DefaultLayoutAlignDirective, selector: " [fxLayoutAlign], [fxLayoutAlign.xs], [fxLayoutAlign.sm], [fxLayoutAlign.md], [fxLayoutAlign.lg], [fxLayoutAlign.xl], [fxLayoutAlign.lt-sm], [fxLayoutAlign.lt-md], [fxLayoutAlign.lt-lg], [fxLayoutAlign.lt-xl], [fxLayoutAlign.gt-xs], [fxLayoutAlign.gt-sm], [fxLayoutAlign.gt-md], [fxLayoutAlign.gt-lg]", inputs: ["fxLayoutAlign", "fxLayoutAlign.xs", "fxLayoutAlign.sm", "fxLayoutAlign.md", "fxLayoutAlign.lg", "fxLayoutAlign.xl", "fxLayoutAlign.lt-sm", "fxLayoutAlign.lt-md", "fxLayoutAlign.lt-lg", "fxLayoutAlign.lt-xl", "fxLayoutAlign.gt-xs", "fxLayoutAlign.gt-sm", "fxLayoutAlign.gt-md", "fxLayoutAlign.gt-lg"] }, { kind: "directive", type: i6$1.DefaultFlexDirective, selector: " [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]", inputs: ["fxFlex", "fxFlex.xs", "fxFlex.sm", "fxFlex.md", "fxFlex.lg", "fxFlex.xl", "fxFlex.lt-sm", "fxFlex.lt-md", "fxFlex.lt-lg", "fxFlex.lt-xl", "fxFlex.gt-xs", "fxFlex.gt-sm", "fxFlex.gt-md", "fxFlex.gt-lg"] }, { kind: "component", type: i8$4.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i8$4.MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { kind: "component", type: i8.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "directive", type: i9.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly"], exportAs: ["matInput"] }, { kind: "component", type: i11$3.MatProgressSpinner, selector: "mat-progress-spinner, mat-spinner", inputs: ["color", "mode", "value", "diameter", "strokeWidth"], exportAs: ["matProgressSpinner"] }, { kind: "component", type: i12.MatTable, selector: "mat-table, table[mat-table]", exportAs: ["matTable"] }, { kind: "directive", type: i12.MatHeaderCellDef, selector: "[matHeaderCellDef]" }, { kind: "directive", type: i12.MatHeaderRowDef, selector: "[matHeaderRowDef]", inputs: ["matHeaderRowDef", "matHeaderRowDefSticky"] }, { kind: "directive", type: i12.MatColumnDef, selector: "[matColumnDef]", inputs: ["matColumnDef"] }, { kind: "directive", type: i12.MatCellDef, selector: "[matCellDef]" }, { kind: "directive", type: i12.MatRowDef, selector: "[matRowDef]", inputs: ["matRowDefColumns", "matRowDefWhen"] }, { kind: "directive", type: i12.MatHeaderCell, selector: "mat-header-cell, th[mat-header-cell]" }, { kind: "directive", type: i12.MatCell, selector: "mat-cell, td[mat-cell]" }, { kind: "component", type: i12.MatHeaderRow, selector: "mat-header-row, tr[mat-header-row]", exportAs: ["matHeaderRow"] }, { kind: "component", type: i12.MatRow, selector: "mat-row, tr[mat-row]", exportAs: ["matRow"] }, { kind: "component", type: i4.MatCard, selector: "mat-card", inputs: ["appearance"], exportAs: ["matCard"] }, { kind: "directive", type: i4.MatCardContent, selector: "mat-card-content" }, { kind: "component", type: i6$3.MatDivider, selector: "mat-divider", inputs: ["vertical", "inset"] }, { kind: "directive", type: i10.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "component", type: i11$2.MatProgressBar, selector: "mat-progress-bar", inputs: ["color", "value", "bufferValue", "mode"], outputs: ["animationEnd"], exportAs: ["matProgressBar"] }, { kind: "directive", type: i1$5.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: i1$5.NgForm, selector: "form:not([ngNoForm]):not([formGroup]),ng-form,[ngForm]", inputs: ["ngFormOptions"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "component", type: TechlifyIconComponent, selector: "app-techlify-icon", inputs: ["name", "size"] }, { kind: "component", type: CommentFormComponent, selector: "app-comment-form", inputs: ["commentData"], outputs: ["action"] }, { kind: "pipe", type: i3.DatePipe, name: "date" }] }); }
4581
4444
  }
4582
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: NumberSelector, decorators: [{
4445
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: NoteListComponent, decorators: [{
4583
4446
  type: Component,
4584
- args: [{ selector: "number-selector", template: "<div class=\"number-selector-wrapper\">\n <select name=\"selectedValue\" [(ngModel)]=\"selectedValue\" class=\"form-control\" (change)=\"numChanged()\">\n <option value=\"\">-- Student Status --</option>\n <option *ngFor=\"let start_value of items;\" value=\"{{start_value}}\">{{start_value}}</option>\n </select>\n</div>" }]
4585
- }], ctorParameters: () => [], propDecorators: { start_value: [{
4447
+ args: [{ selector: 'app-note-list', template: "<div fxLayout=\"column\" fxLayoutGap=\"1.5rem\" *ngIf=\"!commentsView\">\n\n <ng-container *ngIf=\"viewMode === 'list'\">\n <div class=\"d-flex align-items-center\">\n <h5 class=\"m-0\">{{ labelText }}s</h5>\n <app-techlify-icon name=\"add\" class=\"clickable d-print-none ml-1\" matTooltip=\"Add\"\n (click)=\"addNote()\"></app-techlify-icon>\n </div>\n\n <div class=\"w-100 scroll-container\" infiniteScroll [infiniteScrollDistance]=\"1\" [infiniteScrollThrottle]=\"50\"\n (scrolled)=\"onScroll()\" [scrollWindow]=\"false\">\n <table mat-table [dataSource]=\"models\" class=\"w-100\" multiTemplateDataRows>\n\n <!-- Index Column -->\n <ng-container matColumnDef=\"index\">\n <th mat-header-cell *matHeaderCellDef> #</th>\n <td mat-cell *matCellDef=\"let note; let i = dataIndex\"> {{ i + 1 }}</td>\n </ng-container>\n\n\n <ng-container matColumnDef=\"note\">\n <th mat-header-cell *matHeaderCellDef> {{ labelText }}</th>\n <td mat-cell *matCellDef=\"let note\">\n {{ note?.note }}\n </td>\n </ng-container>\n\n <ng-container matColumnDef=\"actions\">\n <th mat-header-cell *matHeaderCellDef class=\"d-print-none\"> Actions</th>\n <td mat-cell *matCellDef=\"let note\" class=\"d-print-none text-secondary\">\n <div fxLayoutAlign=\"start center\">\n <app-techlify-icon name=\"edit\" class=\"clickable\" matTooltip=\"Update\"\n (click)=\"editNote(note)\"></app-techlify-icon>\n <app-techlify-icon name=\"delete\" class=\"clickable ml-1\" matTooltip=\"Delete\"\n (click)=\"deleteNote(note)\"></app-techlify-icon>\n </div>\n </td>\n </ng-container>\n <tr mat-header-row *matHeaderRowDef=\"displayedColumns\"></tr>\n <tr mat-row *matRowDef=\"let row; columns: displayedColumns;\"></tr>\n </table>\n <mat-progress-bar mode=\"indeterminate\" *ngIf=\"isWorking\"></mat-progress-bar>\n </div>\n </ng-container>\n\n <ng-container *ngIf=\"viewMode === 'timeline'\">\n <mat-card>\n <mat-card-content class=\"d-flex justify-content-start align-items-center gap-2\">\n <h5 class=\"mb-0\">Notes</h5>\n <span class=\"badge badge-info ml-1\" *ngIf=\"total\">{{ total }}</span>\n </mat-card-content>\n <mat-card-content class=\"mt-2\">\n <form (ngSubmit)=\"saveNote()\">\n <mat-form-field class=\"w-100\" appearance=\"outline\">\n <input [(ngModel)]=\"note\" [ngModelOptions]=\"{standalone: true}\" type=\"text\" matInput\n placeholder=\"Write your notes here...\" [disabled]=\"isSaving\">\n <mat-icon *ngIf=\"!isSaving\" matSuffix class=\"cursor-pointer\" (click)=\"saveNote()\">send</mat-icon>\n <mat-progress-spinner matSuffix mode=\"indeterminate\" diameter=\"20\" *ngIf=\"isSaving\"></mat-progress-spinner>\n </mat-form-field>\n </form>\n </mat-card-content>\n <mat-card-content>\n <div *ngFor=\"let note of models;last as isLast\">\n <div class=\"d-flex justify-content-between align-items-center gap-2\">\n <div class=\"d-flex flex-column\">\n <p class=\"mb-0\">{{ note?.creator?.name }}</p>\n <small class=\"text-secondary\">On {{ note?.created_at | date: 'medium' }}</small>\n </div>\n <div class=\"d-flex justify-content-end align-items-center gap-1\">\n <app-techlify-icon name=\"edit\" class=\"clickable\" matTooltip=\"Update\"\n (click)=\"editNote(note)\"></app-techlify-icon>\n <app-techlify-icon name=\"delete\" class=\"clickable\" matTooltip=\"Delete\"\n (click)=\"deleteNote(note)\"></app-techlify-icon>\n </div>\n </div>\n <div>{{ note?.note }}</div>\n <mat-divider class=\"my-2\" *ngIf=\"!isLast\"></mat-divider>\n </div>\n <mat-progress-bar mode=\"indeterminate\" *ngIf=\"isWorking\"></mat-progress-bar>\n </mat-card-content>\n </mat-card>\n </ng-container>\n\n</div>\n\n<div fxLayout=\"column\" fxLayoutGap=\"1.5rem\" *ngIf=\"commentsView\">\n <div fxLayout fxLayoutAlign=\"center center\" fxLayoutGap=\"1rem\">\n <h5 class=\"m-0\">{{ labelText }}s</h5>\n </div>\n\n <div fxLayout=\"column\" fxLayoutAlign=\"start\" fxFlex=\"100%\">\n <div class=\"w-100 scroll-container jumbotron\" infiniteScroll [infiniteScrollDistance]=\"1\"\n [infiniteScrollThrottle]=\"50\" (scrolled)=\"onScroll()\" [scrollWindow]=\"false\">\n <app-comment-form [commentData]=\"comment\" (action)=\"commentAction($event)\" *ngFor=\"let comment of models\">\n </app-comment-form>\n <app-comment-form (action)=\"commentAction($event)\"></app-comment-form>\n </div>\n </div>\n</div>", styles: [".scroll-container{max-height:400px;overflow-y:auto}\n"] }]
4448
+ }], ctorParameters: () => [{ type: NoteService }, { type: i1.MatDialog }, { type: AlertService }], propDecorators: { relatedModelId: [{
4586
4449
  type: Input
4587
- }], end_value: [{
4450
+ }], modelType: [{
4588
4451
  type: Input
4589
- }], selectedValueChange: [{
4590
- type: Output
4591
- }], selectedValue: [{
4452
+ }], readonly: [{
4453
+ type: Input
4454
+ }], labelText: [{
4455
+ type: Input
4456
+ }], commentsView: [{
4457
+ type: Input
4458
+ }], viewMode: [{
4592
4459
  type: Input
4593
4460
  }] } });
4594
4461
 
4595
- class Timeline {
4596
- static { this.CUSTOM = 1; }
4597
- static { this.TODAY = 2; }
4598
- static { this.YESTERDAY = 3; }
4599
- static { this.THIS_WEEK = 4; }
4600
- static { this.LAST_WEEK = 5; }
4601
- static { this.THIS_MONTH = 6; }
4602
- static { this.LAST_MONTH = 7; }
4603
- static { this.THIS_QUARTER = 8; }
4604
- static { this.LAST_QUARTER = 9; }
4605
- static { this.THIS_YEAR = 10; }
4606
- static { this.LAST_YEAR = 11; }
4607
- static { this.ALL = 12; }
4608
- static { this.TOMMOROW = 13; }
4609
- static { this.NEXT_WEEK = 14; }
4610
- static { this.NEXT_MONTH = 15; }
4611
- }
4612
-
4613
- function calculateTimeline(value, dateFrom, dateTo) {
4614
- const date = new Date();
4615
- const data = {
4616
- date_from: date,
4617
- date_to: date,
4618
- show_custom_field: false
4619
- };
4620
- switch (value) {
4621
- case Timeline.CUSTOM: { // Custom
4622
- data.show_custom_field = true;
4623
- data.date_from = dateFrom ? moment(dateFrom).toISOString() : '';
4624
- data.date_to = dateTo ? moment(dateTo).toISOString() : '';
4625
- break;
4626
- }
4627
- case Timeline.TODAY: { // Today
4628
- const now = moment();
4629
- data.date_from = now.startOf('day').toISOString();
4630
- data.date_to = now.endOf('day').toISOString();
4631
- break;
4632
- }
4633
- case Timeline.YESTERDAY: { // Yesterday
4634
- const now = moment().subtract(1, 'day');
4635
- data.date_from = now.startOf('day').toISOString();
4636
- data.date_to = now.endOf('day').toISOString();
4637
- break;
4638
- }
4639
- case Timeline.THIS_WEEK: { // This Week
4640
- const now = moment();
4641
- data.date_from = now.startOf('isoWeek').toISOString();
4642
- data.date_to = now.endOf('isoWeek').toISOString();
4643
- break;
4644
- }
4645
- case Timeline.LAST_WEEK: { // Last Week
4646
- const now = moment().subtract(1, 'week');
4647
- data.date_from = now.startOf('isoWeek').toISOString();
4648
- data.date_to = now.endOf('isoWeek').toISOString();
4649
- break;
4650
- }
4651
- case Timeline.THIS_MONTH: { // This Month
4652
- const now = moment();
4653
- data.date_from = now.startOf('month').toISOString();
4654
- data.date_to = now.endOf('month').toISOString();
4655
- break;
4656
- }
4657
- case Timeline.LAST_MONTH: { // Last Month
4658
- const now = moment().subtract(1, 'month');
4659
- data.date_from = now.startOf('month').toISOString();
4660
- data.date_to = now.endOf('month').toISOString();
4661
- break;
4662
- }
4663
- case Timeline.THIS_QUARTER: { // This Quarter
4664
- const now = moment();
4665
- data.date_from = now.startOf('quarter').toISOString();
4666
- data.date_to = now.endOf('quarter').toISOString();
4667
- break;
4668
- }
4669
- case Timeline.LAST_QUARTER: { // Last Quarter
4670
- const now = moment().subtract(1, 'quarter');
4671
- data.date_from = now.startOf('quarter').toISOString();
4672
- data.date_to = now.endOf('quarter').toISOString();
4673
- break;
4674
- }
4675
- case Timeline.THIS_YEAR: { // This Year
4676
- const now = moment();
4677
- data.date_from = now.startOf('year').toISOString();
4678
- data.date_to = now.endOf('year').toISOString();
4679
- break;
4680
- }
4681
- case Timeline.LAST_YEAR: { // Last Year
4682
- const now = moment().subtract(1, 'year');
4683
- data.date_from = now.startOf('year').toISOString();
4684
- data.date_to = now.endOf('year').toISOString();
4685
- break;
4686
- }
4687
- case Timeline.TOMMOROW: {
4688
- const now = moment().add(1, 'day');
4689
- data.date_from = now.startOf('day').toISOString();
4690
- data.date_to = now.endOf('day').toISOString();
4691
- break;
4692
- }
4693
- case Timeline.NEXT_WEEK: {
4694
- const now = moment().add(1, 'week');
4695
- data.date_from = now.startOf('isoWeek').toISOString();
4696
- data.date_to = now.endOf('isoWeek').toISOString();
4697
- break;
4698
- }
4699
- case Timeline.NEXT_MONTH: {
4700
- const now = moment().add(1, 'month');
4701
- data.date_from = now.startOf('month').toISOString();
4702
- data.date_to = now.endOf('month').toISOString();
4703
- break;
4704
- }
4705
- default: { // All
4706
- data.date_from = '';
4707
- data.date_to = '';
4708
- break;
4709
- }
4710
- }
4711
- return data;
4712
- }
4713
-
4714
- var TimelineFilterComponent_1;
4715
- let TimelineFilterComponent = class TimelineFilterComponent {
4716
- static { TimelineFilterComponent_1 = this; }
4717
- set defaultValue(value) {
4718
- this.value = value;
4719
- }
4462
+ class SearchableSelectorComponent {
4463
+ static { this.nextId = 0; }
4720
4464
  get empty() {
4721
4465
  const { value: { select_value } } = this.selectorForm;
4722
4466
  return !select_value;
@@ -4724,227 +4468,491 @@ let TimelineFilterComponent = class TimelineFilterComponent {
4724
4468
  get shouldLabelFloat() { return this.focused || !this.empty; }
4725
4469
  get required() { return this._required; }
4726
4470
  set required(value) {
4727
- this.selectorForm?.get('select_value')?.setValidators(Validators.required);
4471
+ this.selectorForm.get('select_value').setValidators(Validators.required);
4728
4472
  this._required = coerceBooleanProperty(value);
4729
4473
  this.stateChanges.next();
4730
4474
  }
4731
4475
  get disabled() { return this._disabled; }
4732
4476
  set disabled(value) {
4733
4477
  this._disabled = coerceBooleanProperty(value);
4734
- this._disabled ? this.selectorForm.disable() : this.selectorForm.enable();
4478
+ this._disabled
4479
+ ? this.selectorForm.disable({ emitEvent: false })
4480
+ : this.selectorForm.enable({ emitEvent: false });
4735
4481
  this.stateChanges.next();
4736
4482
  }
4737
4483
  get value() {
4738
- if (this.selectorForm.valid) {
4739
- return this.selectorForm.value.select_value;
4740
- }
4741
- return '';
4484
+ return this.selectorForm.get('select_value')?.value || '';
4742
4485
  }
4743
4486
  set value(data) {
4744
- this.selectorForm.patchValue({ select_value: parseInt(data) || '' }, { emitEvent: false });
4487
+ this.selectorForm.patchValue({ select_value: data || '' });
4745
4488
  this.stateChanges.next();
4746
- //If the selection is custom, validate if date is selected
4747
- if (this.value == Timeline.CUSTOM) {
4748
- if (this.isInitialised) {
4749
- //If initialised already, open the calendar
4750
- this.openCalendar();
4751
- }
4752
- else {
4753
- //Apply default ranges from form if exist
4754
- this.applyRange((this.getFieldValue(this.dateFrom) ?? null), (this.getFieldValue(this.dateTo) ?? null));
4755
- }
4756
- }
4757
- else {
4758
- this.changeTimeline(parseInt(data) || '');
4759
- }
4760
- this.isInitialised = true;
4761
4489
  }
4762
- static { this.nextId = 0; }
4763
- get timelineValue() {
4764
- return this.selectorForm.get('select_value');
4765
- }
4766
- get isCustomSelected() {
4767
- return this.value == Timeline.CUSTOM;
4768
- }
4769
- get customDateFrom() {
4770
- return this.selectorForm.get('custom_date_from');
4771
- }
4772
- get customDateTo() {
4773
- return this.selectorForm.get('custom_date_to');
4774
- }
4775
- constructor(formBuilder, ngControl, datePipe) {
4490
+ constructor(formBuilder, _focusMonitor, http, _elementRef, dialog, ngControl) {
4491
+ this._focusMonitor = _focusMonitor;
4492
+ this.http = http;
4493
+ this._elementRef = _elementRef;
4494
+ this.dialog = dialog;
4776
4495
  this.ngControl = ngControl;
4777
- this.datePipe = datePipe;
4778
- this.isInitialised = false;
4779
- this.timelines = [
4780
- { value: Timeline.CUSTOM, viewValue: 'Custom' },
4781
- { value: Timeline.TODAY, viewValue: 'Today' },
4782
- { value: Timeline.YESTERDAY, viewValue: 'Yesterday' },
4783
- { value: Timeline.TOMMOROW, viewValue: 'Tomorrow' },
4784
- { value: Timeline.THIS_WEEK, viewValue: 'This Week' },
4785
- { value: Timeline.LAST_WEEK, viewValue: 'Last Week' },
4786
- { value: Timeline.NEXT_WEEK, viewValue: 'Next Week' },
4787
- { value: Timeline.THIS_MONTH, viewValue: 'This Month' },
4788
- { value: Timeline.LAST_MONTH, viewValue: 'Last Month' },
4789
- { value: Timeline.NEXT_MONTH, viewValue: 'Next Month' },
4790
- { value: Timeline.THIS_QUARTER, viewValue: 'This Quarter' },
4791
- { value: Timeline.LAST_QUARTER, viewValue: 'Last Quarter' },
4792
- { value: Timeline.THIS_YEAR, viewValue: 'This Year' },
4793
- { value: Timeline.LAST_YEAR, viewValue: 'Last Year' },
4794
- { value: Timeline.ALL, viewValue: 'All dates' },
4795
- ];
4796
- this.dateFrom = 'date_from';
4797
- this.dateTo = 'date_to';
4798
- this.appearance = 'fill';
4799
- this.showClearButton = false;
4800
- this.labelText = 'Select Timeline';
4496
+ this.valueField = 'id';
4497
+ this.titleField = 'title';
4498
+ this.multiple = false;
4499
+ this.selectedValueChange = new EventEmitter();
4500
+ this.enableSearch = true;
4501
+ this.add = false;
4502
+ this.edit = false;
4503
+ this.sort = true;
4504
+ this.items = [];
4505
+ this.apiDataProperty = 'data';
4506
+ this.cache = false;
4507
+ this.perPage = 50;
4508
+ this.inDataSearch = false;
4509
+ this.panelWidth = '';
4801
4510
  this.selectionChange = new EventEmitter();
4511
+ this.itemsChange = new EventEmitter();
4512
+ this.focusSearchOnOpen = false;
4513
+ this.isItemsEmpty = new EventEmitter();
4514
+ /**
4515
+ * If this is set to true, if there is a pre-selected entity,
4516
+ * the entity that is populated will be emitted when it is set
4517
+ */
4518
+ this.isEmitInitialEvent = false;
4519
+ this.isLoading = false;
4520
+ this.onChange = () => { };
4521
+ this.onTouched = () => { };
4802
4522
  this.stateChanges = new Subject();
4803
- this.controlType = 'timeline-filter';
4804
- this.id = `timeline-filter-${TimelineFilterComponent_1.nextId++}`;
4805
- this.describedBy = '';
4806
4523
  this.focused = false;
4524
+ this.controlType = 'searchable-selctor';
4525
+ this.id = `searchable-selctor-${SearchableSelectorComponent.nextId++}`;
4526
+ this.describedBy = '';
4527
+ this.cachedItems = [];
4528
+ this.subscriptions = new Subscription();
4807
4529
  this._required = false;
4808
4530
  this._disabled = false;
4809
- this.onChange = () => { };
4810
- this.onTouched = () => { };
4811
- //Custom range
4812
- this.selectedRangeLabel = '';
4813
4531
  this.selectorForm = formBuilder.group({
4814
- select_value: [''],
4815
- custom_date_from: [''],
4816
- custom_date_to: [''],
4532
+ select_value: [null],
4533
+ search: ''
4817
4534
  });
4535
+ this.subscriptions.add(_focusMonitor.monitor(_elementRef, true).subscribe(origin => {
4536
+ if (this.focused && !origin) {
4537
+ this.onTouched();
4538
+ }
4539
+ this.focused = !!origin;
4540
+ this.stateChanges.next();
4541
+ }));
4818
4542
  if (this.ngControl != null) {
4819
4543
  this.ngControl.valueAccessor = this;
4820
4544
  }
4821
4545
  }
4822
- ngOnInit() {
4823
- this.timelineValue.valueChanges.
4824
- pipe(debounceTime(100), distinctUntilChanged(), untilDestroyed(this)).subscribe(value => this.value = value);
4825
- //Listen only to custom date to, since it is range selector it always safe to listen date to
4826
- this.customDateTo.valueChanges.pipe(distinctUntilChanged(), untilDestroyed(this)).subscribe(val => {
4827
- if (val && !this.isCustomDatePatching) {
4828
- this.applyRange();
4546
+ openedChange(opened) {
4547
+ if (this.dataItems.length === 0 && this.selectorForm.get('search').value) {
4548
+ this.selectorForm.get('search').setValue('');
4549
+ }
4550
+ if (opened && this.enableSearch && this.focusSearchOnOpen) {
4551
+ // Focus the search input field
4552
+ setTimeout(() => this.searchInput.nativeElement.focus(), 0);
4553
+ }
4554
+ }
4555
+ get dataItems() {
4556
+ let items = [];
4557
+ if (this.multiple && this.selectedValue && (this.selectedValue.length > 0))
4558
+ items = [...this.selectedValue, ...this.items];
4559
+ else if ((!this.multiple) && this.selectedValue)
4560
+ items = [this.selectedValue, ...this.items];
4561
+ else
4562
+ items = this.items;
4563
+ items = items.filter((v, i, a) => a.findIndex(v => v[this.valueField] === a[i][this.valueField]) === i);
4564
+ //Emit the items to any child component
4565
+ this.itemsChange.emit(items);
4566
+ return items;
4567
+ }
4568
+ ngOnInit() {
4569
+ this.subscriptions.add(this.selectorForm.get('search').valueChanges
4570
+ .pipe(debounceTime(500), distinctUntilChanged()).subscribe(value => {
4571
+ if (this.enableSearch)
4572
+ this.search(value);
4573
+ }));
4574
+ this.filters = {
4575
+ perPage: this.perPage,
4576
+ search: '',
4577
+ page: 1,
4578
+ lastPage: 1
4579
+ };
4580
+ if (this.sort) {
4581
+ this.filters.sort_by = this.sortBy || `${this.titleField}|asc`;
4582
+ }
4583
+ //Fetch Items only if it is not present, can be used in places where we load many entries.
4584
+ if (this.items.length === 0) {
4585
+ this.fetchItemList();
4586
+ }
4587
+ }
4588
+ fetchItemList() {
4589
+ this.isLoading = true;
4590
+ let request = this.http.get(this.apiUrl, { params: this.filters });
4591
+ if (this.cache) {
4592
+ request = this.http.cache().get(this.apiUrl, { params: this.filters });
4593
+ }
4594
+ this.subscriptions.add(of().pipe(startWith(true), switchMap((_) => from(request)), finalize$1(() => this.isLoading = false)).subscribe((result) => {
4595
+ this.items = this.items.concat(result[this.apiDataProperty]);
4596
+ if (this.items.length == 0 && (!this.filters?.search)) {
4597
+ //If there is no items and search is empty, then we emit items empty event.
4598
+ this.isItemsEmpty.emit(true);
4599
+ }
4600
+ if (this.cache) {
4601
+ this.cachedItems = this.items;
4602
+ }
4603
+ this.filters.page = result?.current_page || 1;
4604
+ this.filters.lastPage = result?.last_page || 1;
4605
+ /**
4606
+ * If we are required to emit the selected entity when it is initially set,
4607
+ * let's go ahead and emit it.
4608
+ **/
4609
+ if (this.isEmitInitialEvent && this.value) {
4610
+ this._handleInput();
4611
+ //Once the initial event is emitted, reset back to avoid continuous events
4612
+ this.isEmitInitialEvent = false;
4613
+ }
4614
+ }));
4615
+ }
4616
+ setDescribedByIds(ids) {
4617
+ this.describedBy = ids.join(' ');
4618
+ }
4619
+ onContainerClick(event) {
4620
+ event.stopPropagation();
4621
+ }
4622
+ writeValue(data) {
4623
+ this.value = data;
4624
+ }
4625
+ registerOnChange(fn) {
4626
+ this.onChange = fn;
4627
+ }
4628
+ registerOnTouched(fn) {
4629
+ this.onTouched = fn;
4630
+ }
4631
+ setDisabledState(isDisabled) {
4632
+ this.disabled = isDisabled;
4633
+ }
4634
+ getPropertyValue(ele, keyString) {
4635
+ keyString = keyString.replace(/\[(\w+)\]/g, ".$1"); // convert indexes to properties
4636
+ keyString = keyString.replace(/^\./, ""); // strip a leading dot
4637
+ const keyList = keyString.split(".");
4638
+ for (let i = 0, n = keyList.length; i < n; ++i) {
4639
+ const key = keyList[i];
4640
+ if (ele && key in ele) {
4641
+ ele = ele[key];
4642
+ }
4643
+ else {
4644
+ return;
4645
+ }
4646
+ }
4647
+ return ele;
4648
+ }
4649
+ _handleInput() {
4650
+ //Trigger on change only when initial event is false, to avoid double loading
4651
+ if (!this.isEmitInitialEvent) {
4652
+ this.onChange(this.value);
4653
+ }
4654
+ if (this.multiple)
4655
+ this.selectedValue = (this.value || []).map(x => this.dataItems.find(y => y[this.valueField] === x));
4656
+ else
4657
+ this.selectedValue = this.dataItems.find(x => x[this.valueField] === this.value);
4658
+ this.selectedValueChange.emit(this.selectedValue);
4659
+ this.selectionChange.emit(this.value);
4660
+ }
4661
+ get errorState() {
4662
+ return (this.ngControl && this.ngControl.invalid && (this.ngControl.touched || this.ngControl.dirty));
4663
+ }
4664
+ onScroll() {
4665
+ if (!this.isLoading && this.filters.lastPage > this.filters.page) {
4666
+ this.filters.page += 1;
4667
+ this.fetchItemList();
4668
+ }
4669
+ }
4670
+ reloadData() {
4671
+ this.items = [];
4672
+ this.filters.page = 1;
4673
+ this.filters.lastPage = 1;
4674
+ this.fetchItemList();
4675
+ }
4676
+ search(event) {
4677
+ if (this.searchField) {
4678
+ this.filters[this.searchField] = event;
4679
+ }
4680
+ else {
4681
+ this.filters.search = event;
4682
+ }
4683
+ // we need search field to search in data
4684
+ if (this.inDataSearch && this.searchField) {
4685
+ this.filterItems(event);
4686
+ }
4687
+ else {
4688
+ this.reloadData();
4689
+ }
4690
+ }
4691
+ filterItems(event) {
4692
+ if (event) {
4693
+ this.items = this.cachedItems.filter((value) => {
4694
+ return value[this.searchField].toLowerCase().search(event.toLowerCase()) != -1;
4695
+ });
4696
+ }
4697
+ else {
4698
+ this.items = this.cachedItems;
4699
+ }
4700
+ }
4701
+ addItem(event) {
4702
+ const dialogRef = this.dialog.open(this.itemComponent, {
4703
+ width: '400px',
4704
+ autoFocus: false,
4705
+ data: {},
4706
+ ...this.addConfig
4707
+ });
4708
+ dialogRef.afterClosed().subscribe((model) => {
4709
+ if (model) {
4710
+ this.items.push(model);
4711
+ this.selectorForm.get('select_value').setValue(model[this.valueField]);
4712
+ this._handleInput();
4829
4713
  }
4830
4714
  });
4715
+ event.stopPropagation();
4831
4716
  }
4832
- resetFieldValue(field) {
4833
- this.form?.get(field)?.setValue('');
4834
- }
4835
- getFieldValue(field) {
4836
- return this.form?.get(field)?.value;
4837
- }
4838
- setFieldValue(field, value, emitEvent = true) {
4839
- this.form?.get(field)?.setValue(value, { emitEvent: emitEvent });
4717
+ editItem(event) {
4718
+ const dialogRef = this.dialog.open(this.itemComponent, {
4719
+ width: '400px',
4720
+ autoFocus: false,
4721
+ data: {
4722
+ item: this.selectedValue
4723
+ },
4724
+ ...this.editConfig
4725
+ });
4726
+ dialogRef.afterClosed().subscribe((result) => {
4727
+ if (result) {
4728
+ this.items = this.items.filter(x => x[this.valueField] !== this.selectedValue[this.valueField]);
4729
+ this.items.push(result.item);
4730
+ this.selectedValue = null;
4731
+ this.selectorForm.get('select_value').setValue(result.item[this.valueField]);
4732
+ this._handleInput();
4733
+ }
4734
+ });
4735
+ event.stopPropagation();
4840
4736
  }
4841
- changeTimeline(value) {
4842
- value = parseInt(value);
4843
- this.selectedRangeLabel = '';
4844
- const timeline = calculateTimeline(value, this.dateFrom, this.dateTo);
4845
- if (timeline) {
4846
- this.setCustomDates('', '');
4847
- this.setFieldValue(this.dateFrom, this.datePipe.transform(timeline.date_from, 'yyyy-MM-dd'));
4848
- this.setFieldValue(this.dateTo, this.datePipe.transform(timeline.date_to, 'yyyy-MM-dd'));
4849
- }
4850
- this.onChange(this.value);
4851
- this.selectionChange.emit(timeline);
4737
+ ngOnDestroy() {
4738
+ this.stateChanges.complete();
4739
+ this._focusMonitor.stopMonitoring(this._elementRef);
4740
+ this.subscriptions.unsubscribe();
4852
4741
  }
4853
- openCalendar() {
4854
- this.picker.open();
4742
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: SearchableSelectorComponent, deps: [{ token: i1$5.UntypedFormBuilder }, { token: i1$4.FocusMonitor }, { token: HttpService }, { token: i0.ElementRef }, { token: i1.MatDialog }, { token: i1$5.NgControl, optional: true, self: true }], target: i0.ɵɵFactoryTarget.Component }); }
4743
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.14", type: SearchableSelectorComponent, selector: "app-searchable-selector", inputs: { valueField: "valueField", titleField: "titleField", subtitleField: "subtitleField", apiUrl: "apiUrl", multiple: "multiple", selectedValue: "selectedValue", enableSearch: "enableSearch", add: "add", addConfig: "addConfig", edit: "edit", editConfig: "editConfig", sort: "sort", sortBy: "sortBy", searchField: "searchField", itemComponent: "itemComponent", items: "items", apiDataProperty: "apiDataProperty", cache: "cache", perPage: "perPage", inDataSearch: "inDataSearch", panelWidth: "panelWidth", focusSearchOnOpen: "focusSearchOnOpen", isEmitInitialEvent: "isEmitInitialEvent", required: "required", disabled: "disabled", value: "value" }, outputs: { selectedValueChange: "selectedValueChange", selectionChange: "selectionChange", itemsChange: "itemsChange", isItemsEmpty: "isItemsEmpty" }, providers: [
4744
+ {
4745
+ provide: MatFormFieldControl,
4746
+ useExisting: SearchableSelectorComponent
4747
+ }
4748
+ ], viewQueries: [{ propertyName: "searchInput", first: true, predicate: ["searchInput"], descendants: true }], ngImport: i0, template: "<ng-container [formGroup]=\"selectorForm\">\n <div class=\"searchable-selector-container\">\n <!-- Selector and Suffix Icons -->\n <mat-select formControlName=\"select_value\" [multiple]=\"multiple\" [required]=\"required\"\n (selectionChange)=\"this.isEmitInitialEvent = false;_handleInput()\" (openedChange)=\"openedChange($event)\"\n [panelWidth]=\"panelWidth\">\n <!-- Search Field -->\n <mat-form-field *ngIf=\"enableSearch\" class=\"p-1 w-100\">\n <input matInput formControlName=\"search\" placeholder=\"Search...\" (keydown)=\"$event.stopPropagation();\"\n autocomplete=\"off\" #searchInput>\n </mat-form-field>\n\n <!-- Options with Scrollable Container -->\n <div class=\"searchable-selector-scrollable-container\" cdkScrollable (scrollend)=\"onScroll()\">\n <mat-option *ngFor=\"let item of dataItems\" [value]=\"getPropertyValue(item, valueField)\">\n <span>{{ getPropertyValue(item, titleField) }}</span>\n <span *ngIf=\"subtitleField\" class=\"text-secondary\" style=\"font-size: 14px;\">\n - {{ getPropertyValue(item, subtitleField) }}\n </span>\n </mat-option>\n <mat-progress-bar *ngIf=\"isLoading\" color=\"primary\" mode=\"indeterminate\"></mat-progress-bar>\n </div>\n </mat-select>\n\n <!-- Add and Edit Buttons -->\n <mat-icon class=\"cursor-pointer\" *ngIf=\"add\" (click)=\"addItem($event)\">\n add\n </mat-icon>\n <mat-icon class=\"cursor-pointer\" *ngIf=\"edit && selectedValue\" (click)=\"editItem($event)\">\n edit\n </mat-icon>\n </div>\n</ng-container>", styles: [".searchable-selector-container{display:flex;align-items:center}.searchable-selector-container mat-select{flex-grow:1}.searchable-selector-container mat-icon{margin-left:2px}.relative-icon{position:relative;top:-4px}.searchable-selector-scrollable-container{max-height:175px;overflow-y:auto}:host ::ng-deep .mat-mdc-floating-label{pointer-events:none!important}\n"], dependencies: [{ kind: "directive", type: i3.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1$5.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$5.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$5.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1$5.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i1$5.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$5.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "component", type: i8$4.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "component", type: i8.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "directive", type: i9.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly"], exportAs: ["matInput"] }, { kind: "directive", type: i9$2.CdkScrollable, selector: "[cdk-scrollable], [cdkScrollable]" }, { kind: "component", type: i5.MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "component", type: i9$1.MatSelect, selector: "mat-select", inputs: ["aria-describedby", "panelClass", "disabled", "disableRipple", "tabIndex", "hideSingleSelectionIndicator", "placeholder", "required", "multiple", "disableOptionCentering", "compareWith", "value", "aria-label", "aria-labelledby", "errorStateMatcher", "typeaheadDebounceInterval", "sortComparator", "id", "panelWidth"], outputs: ["openedChange", "opened", "closed", "selectionChange", "valueChange"], exportAs: ["matSelect"] }, { kind: "component", type: i11$2.MatProgressBar, selector: "mat-progress-bar", inputs: ["color", "value", "bufferValue", "mode"], outputs: ["animationEnd"], exportAs: ["matProgressBar"] }] }); }
4749
+ }
4750
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: SearchableSelectorComponent, decorators: [{
4751
+ type: Component,
4752
+ args: [{ selector: 'app-searchable-selector', providers: [
4753
+ {
4754
+ provide: MatFormFieldControl,
4755
+ useExisting: SearchableSelectorComponent
4756
+ }
4757
+ ], template: "<ng-container [formGroup]=\"selectorForm\">\n <div class=\"searchable-selector-container\">\n <!-- Selector and Suffix Icons -->\n <mat-select formControlName=\"select_value\" [multiple]=\"multiple\" [required]=\"required\"\n (selectionChange)=\"this.isEmitInitialEvent = false;_handleInput()\" (openedChange)=\"openedChange($event)\"\n [panelWidth]=\"panelWidth\">\n <!-- Search Field -->\n <mat-form-field *ngIf=\"enableSearch\" class=\"p-1 w-100\">\n <input matInput formControlName=\"search\" placeholder=\"Search...\" (keydown)=\"$event.stopPropagation();\"\n autocomplete=\"off\" #searchInput>\n </mat-form-field>\n\n <!-- Options with Scrollable Container -->\n <div class=\"searchable-selector-scrollable-container\" cdkScrollable (scrollend)=\"onScroll()\">\n <mat-option *ngFor=\"let item of dataItems\" [value]=\"getPropertyValue(item, valueField)\">\n <span>{{ getPropertyValue(item, titleField) }}</span>\n <span *ngIf=\"subtitleField\" class=\"text-secondary\" style=\"font-size: 14px;\">\n - {{ getPropertyValue(item, subtitleField) }}\n </span>\n </mat-option>\n <mat-progress-bar *ngIf=\"isLoading\" color=\"primary\" mode=\"indeterminate\"></mat-progress-bar>\n </div>\n </mat-select>\n\n <!-- Add and Edit Buttons -->\n <mat-icon class=\"cursor-pointer\" *ngIf=\"add\" (click)=\"addItem($event)\">\n add\n </mat-icon>\n <mat-icon class=\"cursor-pointer\" *ngIf=\"edit && selectedValue\" (click)=\"editItem($event)\">\n edit\n </mat-icon>\n </div>\n</ng-container>", styles: [".searchable-selector-container{display:flex;align-items:center}.searchable-selector-container mat-select{flex-grow:1}.searchable-selector-container mat-icon{margin-left:2px}.relative-icon{position:relative;top:-4px}.searchable-selector-scrollable-container{max-height:175px;overflow-y:auto}:host ::ng-deep .mat-mdc-floating-label{pointer-events:none!important}\n"] }]
4758
+ }], ctorParameters: () => [{ type: i1$5.UntypedFormBuilder }, { type: i1$4.FocusMonitor }, { type: HttpService }, { type: i0.ElementRef }, { type: i1.MatDialog }, { type: i1$5.NgControl, decorators: [{
4759
+ type: Optional
4760
+ }, {
4761
+ type: Self
4762
+ }] }], propDecorators: { searchInput: [{
4763
+ type: ViewChild,
4764
+ args: ['searchInput']
4765
+ }], valueField: [{
4766
+ type: Input
4767
+ }], titleField: [{
4768
+ type: Input
4769
+ }], subtitleField: [{
4770
+ type: Input
4771
+ }], apiUrl: [{
4772
+ type: Input
4773
+ }], multiple: [{
4774
+ type: Input
4775
+ }], selectedValue: [{
4776
+ type: Input
4777
+ }], selectedValueChange: [{
4778
+ type: Output
4779
+ }], enableSearch: [{
4780
+ type: Input
4781
+ }], add: [{
4782
+ type: Input
4783
+ }], addConfig: [{
4784
+ type: Input
4785
+ }], edit: [{
4786
+ type: Input
4787
+ }], editConfig: [{
4788
+ type: Input
4789
+ }], sort: [{
4790
+ type: Input
4791
+ }], sortBy: [{
4792
+ type: Input
4793
+ }], searchField: [{
4794
+ type: Input
4795
+ }], itemComponent: [{
4796
+ type: Input
4797
+ }], items: [{
4798
+ type: Input
4799
+ }], apiDataProperty: [{
4800
+ type: Input
4801
+ }], cache: [{
4802
+ type: Input
4803
+ }], perPage: [{
4804
+ type: Input
4805
+ }], inDataSearch: [{
4806
+ type: Input
4807
+ }], panelWidth: [{
4808
+ type: Input
4809
+ }], selectionChange: [{
4810
+ type: Output
4811
+ }], itemsChange: [{
4812
+ type: Output
4813
+ }], focusSearchOnOpen: [{
4814
+ type: Input
4815
+ }], isItemsEmpty: [{
4816
+ type: Output
4817
+ }], isEmitInitialEvent: [{
4818
+ type: Input
4819
+ }], required: [{
4820
+ type: Input
4821
+ }], disabled: [{
4822
+ type: Input
4823
+ }], value: [{
4824
+ type: Input
4825
+ }] } });
4826
+
4827
+ /**
4828
+ * Component to generate a num items selector
4829
+ *
4830
+ * @author Floyd Kissoon
4831
+ * @since 20170817
4832
+ */
4833
+ class NumItemsSelector {
4834
+ constructor() {
4835
+ this.numItemsChange = new EventEmitter();
4855
4836
  }
4856
- applyRange(defaultFrom, defaultTo) {
4857
- const from = defaultFrom ?? this.selectorForm.get('custom_date_from')?.value;
4858
- const to = defaultTo ?? this.selectorForm.get('custom_date_to')?.value;
4859
- if (from && to) {
4860
- this.selectedRangeLabel = `<b>${this.datePipe.transform(from, 'yyyy-MM-dd')}</b>:<b>${this.datePipe.transform(to, 'yyyy-MM-dd')}</b`;
4861
- this.setFieldValue(this.dateFrom, this.datePipe.transform(from, 'yyyy-MM-dd'));
4862
- this.setFieldValue(this.dateTo, this.datePipe.transform(to, 'yyyy-MM-dd'));
4863
- this.onChange(this.value);
4864
- this.selectionChange.emit(this.value);
4865
- this.setCustomDates(from, to);
4866
- }
4837
+ /**
4838
+ * Called when an item has been selected
4839
+ */
4840
+ numItemsChanged() {
4841
+ this.numItemsChange.emit(this.numItems);
4867
4842
  }
4868
- setCustomDates(from, to) {
4869
- // update form fields silently
4870
- this.isCustomDatePatching = true;
4871
- this.selectorForm.get('custom_date_from')?.setValue(from, { emitEvent: false });
4872
- this.selectorForm.get('custom_date_to')?.setValue(to, { emitEvent: false });
4873
- this.isCustomDatePatching = false;
4843
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: NumItemsSelector, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
4844
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.14", type: NumItemsSelector, selector: "num-items-selector", inputs: { numItems: "numItems" }, outputs: { numItemsChange: "numItemsChange" }, ngImport: i0, template: "<select [(ngModel)]=\"numItems\" class=\"form-control\" id=\"numItems\" name=\"numItems\" (change)=\"numItemsChanged()\">\r\n <option value=\"25\">25</option>\r\n <option value=\"50\">50</option>\r\n <option value=\"100\">100</option>\r\n <option value=\"250\">250</option>\r\n <option value=\"500\">500</option>\r\n <option value=\"1000\">1000</option>\r\n <option value=\"2000\">2000</option>\r\n <option value=\"3000\">3000</option>\r\n <option value=\"4000\">4000</option>\r\n <option value=\"5000\">5000</option>\r\n <option value=\"5000000000\">All</option>\r\n</select> ", dependencies: [{ kind: "directive", type: i1$5.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i1$5.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i1$5.SelectControlValueAccessor, selector: "select:not([multiple])[formControlName],select:not([multiple])[formControl],select:not([multiple])[ngModel]", inputs: ["compareWith"] }, { kind: "directive", type: i1$5.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$5.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }] }); }
4845
+ }
4846
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: NumItemsSelector, decorators: [{
4847
+ type: Component,
4848
+ args: [{ selector: "num-items-selector", template: "<select [(ngModel)]=\"numItems\" class=\"form-control\" id=\"numItems\" name=\"numItems\" (change)=\"numItemsChanged()\">\r\n <option value=\"25\">25</option>\r\n <option value=\"50\">50</option>\r\n <option value=\"100\">100</option>\r\n <option value=\"250\">250</option>\r\n <option value=\"500\">500</option>\r\n <option value=\"1000\">1000</option>\r\n <option value=\"2000\">2000</option>\r\n <option value=\"3000\">3000</option>\r\n <option value=\"4000\">4000</option>\r\n <option value=\"5000\">5000</option>\r\n <option value=\"5000000000\">All</option>\r\n</select> " }]
4849
+ }], ctorParameters: () => [], propDecorators: { numItems: [{
4850
+ type: Input
4851
+ }], numItemsChange: [{
4852
+ type: Output
4853
+ }] } });
4854
+
4855
+ /**
4856
+ * Service that provides utility functions for dates
4857
+ *
4858
+ * @author Joshua Kissoon
4859
+ * @since 20170726
4860
+ */
4861
+ class DateUtils {
4862
+ /**
4863
+ * Takes in a date object and outputs the string value
4864
+ */
4865
+ getYYYYMMDDString(inputDate) {
4866
+ var year = inputDate.getFullYear();
4867
+ var month = (inputDate.getMonth() + 1) < 10 ? ("0" + (inputDate.getMonth() + 1)) : (inputDate.getMonth() + 1);
4868
+ var date = inputDate.getDate() < 10 ? ("0" + inputDate.getDate()) : inputDate.getDate();
4869
+ return year + "-" + month + "-" + date;
4874
4870
  }
4875
- setDescribedByIds(ids) {
4876
- this.describedBy = ids.join(' ');
4871
+ /**
4872
+ * Takes in a date object and outputs the year
4873
+ */
4874
+ getYYYY(inputDate) {
4875
+ var year = inputDate.getFullYear();
4876
+ return year;
4877
4877
  }
4878
- onContainerClick(event) {
4879
- event.stopPropagation();
4878
+ /**
4879
+ * Takes in a date object and outputs the Month
4880
+ */
4881
+ getMM(inputDate) {
4882
+ var month = inputDate.getMonth() + 1;
4883
+ return month;
4880
4884
  }
4881
- writeValue(data) {
4882
- this.value = data;
4885
+ // var n = this.rfidCardUseManualEntry.manual_date.toLocaleTimeString();
4886
+ getDateTime(inputDate) {
4887
+ var year = inputDate.getFullYear();
4888
+ var month = (inputDate.getMonth() + 1) < 10 ? ("0" + (inputDate.getMonth() + 1)) : (inputDate.getMonth() + 1);
4889
+ var date = inputDate.getDate() < 10 ? ("0" + inputDate.getDate()) : inputDate.getDate();
4890
+ var time = inputDate.toLocaleTimeString();
4891
+ return year + "-" + month + "-" + date + " " + time;
4883
4892
  }
4884
- registerOnChange(fn) {
4885
- this.onChange = fn;
4893
+ getMonthName(month) {
4894
+ const months = [
4895
+ 'January',
4896
+ 'February',
4897
+ 'March',
4898
+ 'April',
4899
+ 'May',
4900
+ 'June',
4901
+ 'July',
4902
+ 'August',
4903
+ 'September',
4904
+ 'October',
4905
+ 'November',
4906
+ 'December'
4907
+ ];
4908
+ return months[month - 1] ?? '';
4886
4909
  }
4887
- registerOnTouched(fn) {
4888
- this.onTouched = fn;
4910
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: DateUtils, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
4911
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: DateUtils, providedIn: 'root' }); }
4912
+ }
4913
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: DateUtils, decorators: [{
4914
+ type: Injectable,
4915
+ args: [{
4916
+ providedIn: 'root'
4917
+ }]
4918
+ }] });
4919
+
4920
+ /**
4921
+ * Component to generate a number selector
4922
+ *
4923
+ * @author Floyd Kissoon
4924
+ * @since 20180628
4925
+ */
4926
+ class NumberSelector {
4927
+ constructor() {
4928
+ this.items = new Array();
4929
+ this.selectedValueChange = new EventEmitter();
4889
4930
  }
4890
- setDisabledState(isDisabled) {
4891
- this.disabled = isDisabled;
4931
+ /**
4932
+ * Called when an item has been selected
4933
+ */
4934
+ numChanged() {
4935
+ this.selectedValueChange.emit(this.selectedValue);
4892
4936
  }
4893
- ngOnDestroy() {
4894
- this.stateChanges.complete();
4937
+ ngOnInit() {
4938
+ for (var i = this.start_value; i < this.end_value + 1; i++) {
4939
+ this.items.push(i);
4940
+ }
4895
4941
  }
4896
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: TimelineFilterComponent, deps: [{ token: i1$5.UntypedFormBuilder }, { token: i1$5.NgControl, optional: true, self: true }, { token: i3.DatePipe }], target: i0.ɵɵFactoryTarget.Component }); }
4897
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.14", type: TimelineFilterComponent, selector: "app-timeline-filter", inputs: { defaultValue: "defaultValue", required: "required", disabled: "disabled", value: "value", timelines: "timelines", dateFrom: "dateFrom", dateTo: "dateTo", appearance: "appearance", showClearButton: "showClearButton", form: "form", labelText: "labelText" }, outputs: { selectionChange: "selectionChange" }, providers: [
4898
- DatePipe,
4899
- {
4900
- provide: MatFormFieldControl,
4901
- useExisting: TimelineFilterComponent
4902
- }
4903
- ], viewQueries: [{ propertyName: "picker", first: true, predicate: ["picker"], descendants: true }], ngImport: i0, template: "<ng-container [formGroup]=\"selectorForm\">\n <mat-form-field [appearance]=\"appearance\" class=\"fl-sm\">\n <mat-label>{{labelText}}</mat-label>\n <mat-select formControlName=\"select_value\">\n <mat-option *ngFor=\"let timeline of timelines\" [value]=\"timeline.value\">\n {{timeline.viewValue}}\n </mat-option>\n </mat-select>\n <button *ngIf=\"showClearButton && timelineValue.value\" matSuffix mat-icon-button\n (click)=\"timelineValue.setValue('')\">\n <mat-icon>close</mat-icon>\n </button>\n <mat-hint *ngIf=\"isCustomSelected && selectedRangeLabel\" (click)=\"openCalendar()\" class=\"clickable\" fxLayout>\n <span [innerHTML]=\"selectedRangeLabel\" style=\"font-size: 10px;\"></span>\n <app-techlify-icon name=\"edit\" class=\"clickable\" size=\"xs\" style=\"margin-left:2px\"></app-techlify-icon>\n </mat-hint>\n <mat-hint *ngIf=\"isCustomSelected && !selectedRangeLabel\" (click)=\"openCalendar()\" class=\"clickable\" fxLayout>\n <span style=\"font-size: 10px;\">Select Range</span>\n <app-techlify-icon name=\"edit\" class=\"clickable\" size=\"xs\" style=\"margin-left:2px\"></app-techlify-icon>\n </mat-hint>\n <mat-date-range-input class=\"offscreen-range-input\" [rangePicker]=\"picker\">\n <input matStartDate formControlName=\"custom_date_from\" placeholder=\"From date\" readonly />\n <input matEndDate formControlName=\"custom_date_to\" placeholder=\"To date\" readonly />\n </mat-date-range-input>\n <mat-date-range-picker #picker></mat-date-range-picker>\n </mat-form-field>\n</ng-container>", styles: [".icon-md{height:24px!important;width:24px!important;font-size:24px!important;margin:0 1px}.icon-sm{height:20px!important;width:20px!important;font-size:20px!important}.icon-xs{height:16px!important;width:16px!important;font-size:16px!important}.fl-md{width:200px!important}.fl-md .mat-mdc-form-field{width:100%!important}.fl-sm{width:150px!important}.fl-sm .mat-mdc-form-field{width:100%!important}.mat-btn-md{height:25px!important;padding:0 8px!important}.fs-12{font-size:12px!important}.fs-16{font-size:16px!important}.fs-13{font-size:13px!important}.fs-18{font-size:18px!important}.clickable:hover{cursor:pointer}.mat-mdc-form-field-hint-wrapper{padding:0 4px!important}.nil-subscript-wrapper .mat-mdc-form-field-subscript-wrapper{height:0!important}.create-another .mat-mdc-checkbox label{margin:0!important}.create-another .mdc-checkbox{padding:0!important}.create-another .mdc-checkbox__background{position:relative;top:0;left:0}.offscreen-range-input{position:absolute;opacity:0;pointer-events:none;display:flex!important}\n"], dependencies: [{ kind: "directive", type: i3.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i6$1.DefaultLayoutDirective, selector: " [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]", inputs: ["fxLayout", "fxLayout.xs", "fxLayout.sm", "fxLayout.md", "fxLayout.lg", "fxLayout.xl", "fxLayout.lt-sm", "fxLayout.lt-md", "fxLayout.lt-lg", "fxLayout.lt-xl", "fxLayout.gt-xs", "fxLayout.gt-sm", "fxLayout.gt-md", "fxLayout.gt-lg"] }, { kind: "directive", type: i1$5.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$5.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$5.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1$5.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$5.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "component", type: i8$4.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i8$4.MatLabel, selector: "mat-label" }, { kind: "directive", type: i8$4.MatHint, selector: "mat-hint", inputs: ["align", "id"] }, { kind: "directive", type: i8$4.MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { kind: "component", type: i9$2.MatSelect, selector: "mat-select", inputs: ["aria-describedby", "panelClass", "disabled", "disableRipple", "tabIndex", "hideSingleSelectionIndicator", "placeholder", "required", "multiple", "disableOptionCentering", "compareWith", "value", "aria-label", "aria-labelledby", "errorStateMatcher", "typeaheadDebounceInterval", "sortComparator", "id", "panelWidth"], outputs: ["openedChange", "opened", "closed", "selectionChange", "valueChange"], exportAs: ["matSelect"] }, { kind: "component", type: i5.MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "component", type: i6.MatIconButton, selector: "button[mat-icon-button]", exportAs: ["matButton"] }, { kind: "component", type: i8.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: i11$1.MatDateRangeInput, selector: "mat-date-range-input", inputs: ["rangePicker", "required", "dateFilter", "min", "max", "disabled", "separator", "comparisonStart", "comparisonEnd"], exportAs: ["matDateRangeInput"] }, { kind: "directive", type: i11$1.MatStartDate, selector: "input[matStartDate]", outputs: ["dateChange", "dateInput"] }, { kind: "directive", type: i11$1.MatEndDate, selector: "input[matEndDate]", outputs: ["dateChange", "dateInput"] }, { kind: "component", type: i11$1.MatDateRangePicker, selector: "mat-date-range-picker", exportAs: ["matDateRangePicker"] }, { kind: "component", type: TechlifyIconComponent, selector: "app-techlify-icon", inputs: ["name", "size"] }] }); }
4904
- };
4905
- TimelineFilterComponent = TimelineFilterComponent_1 = __decorate([
4906
- UntilDestroy()
4907
- ], TimelineFilterComponent);
4908
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: TimelineFilterComponent, decorators: [{
4942
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: NumberSelector, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
4943
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.14", type: NumberSelector, selector: "number-selector", inputs: { start_value: "start_value", end_value: "end_value", selectedValue: "selectedValue" }, outputs: { selectedValueChange: "selectedValueChange" }, ngImport: i0, template: "<div class=\"number-selector-wrapper\">\n <select name=\"selectedValue\" [(ngModel)]=\"selectedValue\" class=\"form-control\" (change)=\"numChanged()\">\n <option value=\"\">-- Student Status --</option>\n <option *ngFor=\"let start_value of items;\" value=\"{{start_value}}\">{{start_value}}</option>\n </select>\n</div>", dependencies: [{ kind: "directive", type: i3.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1$5.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i1$5.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i1$5.SelectControlValueAccessor, selector: "select:not([multiple])[formControlName],select:not([multiple])[formControl],select:not([multiple])[ngModel]", inputs: ["compareWith"] }, { kind: "directive", type: i1$5.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$5.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }] }); }
4944
+ }
4945
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: NumberSelector, decorators: [{
4909
4946
  type: Component,
4910
- args: [{ selector: 'app-timeline-filter', providers: [
4911
- DatePipe,
4912
- {
4913
- provide: MatFormFieldControl,
4914
- useExisting: TimelineFilterComponent
4915
- }
4916
- ], template: "<ng-container [formGroup]=\"selectorForm\">\n <mat-form-field [appearance]=\"appearance\" class=\"fl-sm\">\n <mat-label>{{labelText}}</mat-label>\n <mat-select formControlName=\"select_value\">\n <mat-option *ngFor=\"let timeline of timelines\" [value]=\"timeline.value\">\n {{timeline.viewValue}}\n </mat-option>\n </mat-select>\n <button *ngIf=\"showClearButton && timelineValue.value\" matSuffix mat-icon-button\n (click)=\"timelineValue.setValue('')\">\n <mat-icon>close</mat-icon>\n </button>\n <mat-hint *ngIf=\"isCustomSelected && selectedRangeLabel\" (click)=\"openCalendar()\" class=\"clickable\" fxLayout>\n <span [innerHTML]=\"selectedRangeLabel\" style=\"font-size: 10px;\"></span>\n <app-techlify-icon name=\"edit\" class=\"clickable\" size=\"xs\" style=\"margin-left:2px\"></app-techlify-icon>\n </mat-hint>\n <mat-hint *ngIf=\"isCustomSelected && !selectedRangeLabel\" (click)=\"openCalendar()\" class=\"clickable\" fxLayout>\n <span style=\"font-size: 10px;\">Select Range</span>\n <app-techlify-icon name=\"edit\" class=\"clickable\" size=\"xs\" style=\"margin-left:2px\"></app-techlify-icon>\n </mat-hint>\n <mat-date-range-input class=\"offscreen-range-input\" [rangePicker]=\"picker\">\n <input matStartDate formControlName=\"custom_date_from\" placeholder=\"From date\" readonly />\n <input matEndDate formControlName=\"custom_date_to\" placeholder=\"To date\" readonly />\n </mat-date-range-input>\n <mat-date-range-picker #picker></mat-date-range-picker>\n </mat-form-field>\n</ng-container>", styles: [".icon-md{height:24px!important;width:24px!important;font-size:24px!important;margin:0 1px}.icon-sm{height:20px!important;width:20px!important;font-size:20px!important}.icon-xs{height:16px!important;width:16px!important;font-size:16px!important}.fl-md{width:200px!important}.fl-md .mat-mdc-form-field{width:100%!important}.fl-sm{width:150px!important}.fl-sm .mat-mdc-form-field{width:100%!important}.mat-btn-md{height:25px!important;padding:0 8px!important}.fs-12{font-size:12px!important}.fs-16{font-size:16px!important}.fs-13{font-size:13px!important}.fs-18{font-size:18px!important}.clickable:hover{cursor:pointer}.mat-mdc-form-field-hint-wrapper{padding:0 4px!important}.nil-subscript-wrapper .mat-mdc-form-field-subscript-wrapper{height:0!important}.create-another .mat-mdc-checkbox label{margin:0!important}.create-another .mdc-checkbox{padding:0!important}.create-another .mdc-checkbox__background{position:relative;top:0;left:0}.offscreen-range-input{position:absolute;opacity:0;pointer-events:none;display:flex!important}\n"] }]
4917
- }], ctorParameters: () => [{ type: i1$5.UntypedFormBuilder }, { type: i1$5.NgControl, decorators: [{
4918
- type: Optional
4919
- }, {
4920
- type: Self
4921
- }] }, { type: i3.DatePipe }], propDecorators: { defaultValue: [{
4922
- type: Input
4923
- }], required: [{
4924
- type: Input
4925
- }], disabled: [{
4926
- type: Input
4927
- }], value: [{
4928
- type: Input
4929
- }], picker: [{
4930
- type: ViewChild,
4931
- args: ['picker']
4932
- }], timelines: [{
4933
- type: Input
4934
- }], dateFrom: [{
4935
- type: Input
4936
- }], dateTo: [{
4937
- type: Input
4938
- }], appearance: [{
4939
- type: Input
4940
- }], showClearButton: [{
4941
- type: Input
4942
- }], form: [{
4947
+ args: [{ selector: "number-selector", template: "<div class=\"number-selector-wrapper\">\n <select name=\"selectedValue\" [(ngModel)]=\"selectedValue\" class=\"form-control\" (change)=\"numChanged()\">\n <option value=\"\">-- Student Status --</option>\n <option *ngFor=\"let start_value of items;\" value=\"{{start_value}}\">{{start_value}}</option>\n </select>\n</div>" }]
4948
+ }], ctorParameters: () => [], propDecorators: { start_value: [{
4943
4949
  type: Input
4944
- }], labelText: [{
4950
+ }], end_value: [{
4945
4951
  type: Input
4946
- }], selectionChange: [{
4952
+ }], selectedValueChange: [{
4947
4953
  type: Output
4954
+ }], selectedValue: [{
4955
+ type: Input
4948
4956
  }] } });
4949
4957
 
4950
4958
  class LoaderComponent {
@@ -5174,6 +5182,69 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
5174
5182
  }]
5175
5183
  }] });
5176
5184
 
5185
+ const routes$J = [];
5186
+ class TimelineFilterRoutingModule {
5187
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: TimelineFilterRoutingModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
5188
+ static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "18.2.14", ngImport: i0, type: TimelineFilterRoutingModule, imports: [i1$2.RouterModule], exports: [RouterModule] }); }
5189
+ static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: TimelineFilterRoutingModule, imports: [RouterModule.forChild(routes$J), RouterModule] }); }
5190
+ }
5191
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: TimelineFilterRoutingModule, decorators: [{
5192
+ type: NgModule,
5193
+ args: [{
5194
+ imports: [RouterModule.forChild(routes$J)],
5195
+ exports: [RouterModule]
5196
+ }]
5197
+ }] });
5198
+
5199
+ class TimelineFilterModule {
5200
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: TimelineFilterModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
5201
+ static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "18.2.14", ngImport: i0, type: TimelineFilterModule, declarations: [TimelineFilterComponent], imports: [CommonModule,
5202
+ TimelineFilterRoutingModule,
5203
+ FlexLayoutModule,
5204
+ ReactiveFormsModule,
5205
+ MatFormFieldModule,
5206
+ MatSelectModule,
5207
+ MatButtonModule,
5208
+ MatIconModule,
5209
+ MatInputModule,
5210
+ MatDatepickerModule,
5211
+ MatNativeDateModule,
5212
+ TechlifyIconModule], exports: [TimelineFilterComponent] }); }
5213
+ static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: TimelineFilterModule, imports: [CommonModule,
5214
+ TimelineFilterRoutingModule,
5215
+ FlexLayoutModule,
5216
+ ReactiveFormsModule,
5217
+ MatFormFieldModule,
5218
+ MatSelectModule,
5219
+ MatButtonModule,
5220
+ MatIconModule,
5221
+ MatInputModule,
5222
+ MatDatepickerModule,
5223
+ MatNativeDateModule,
5224
+ TechlifyIconModule] }); }
5225
+ }
5226
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: TimelineFilterModule, decorators: [{
5227
+ type: NgModule,
5228
+ args: [{
5229
+ declarations: [TimelineFilterComponent],
5230
+ imports: [
5231
+ CommonModule,
5232
+ TimelineFilterRoutingModule,
5233
+ FlexLayoutModule,
5234
+ ReactiveFormsModule,
5235
+ MatFormFieldModule,
5236
+ MatSelectModule,
5237
+ MatButtonModule,
5238
+ MatIconModule,
5239
+ MatInputModule,
5240
+ MatDatepickerModule,
5241
+ MatNativeDateModule,
5242
+ TechlifyIconModule
5243
+ ],
5244
+ exports: [TimelineFilterComponent]
5245
+ }]
5246
+ }] });
5247
+
5177
5248
  class SearchableSelectorModule {
5178
5249
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: SearchableSelectorModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
5179
5250
  static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "18.2.14", ngImport: i0, type: SearchableSelectorModule, declarations: [SearchableSelectorComponent], imports: [CommonModule,
@@ -5240,6 +5311,7 @@ class SharedModule {
5240
5311
  ReactiveFormsModule,
5241
5312
  SearchableSelectorModule,
5242
5313
  TechlifyDeleteButtonComponent,
5314
+ TimelineFilterModule,
5243
5315
  TechlifyFormButtonComponent,
5244
5316
  TechlifyIconModule] }); }
5245
5317
  static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: SharedModule, imports: [TechlifyDeleteButtonComponent,
@@ -5249,6 +5321,7 @@ class SharedModule {
5249
5321
  MaterialModule,
5250
5322
  ReactiveFormsModule,
5251
5323
  SearchableSelectorModule,
5324
+ TimelineFilterModule,
5252
5325
  TechlifyIconModule] }); }
5253
5326
  }
5254
5327
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: SharedModule, decorators: [{
@@ -5268,6 +5341,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
5268
5341
  ReactiveFormsModule,
5269
5342
  SearchableSelectorModule,
5270
5343
  TechlifyDeleteButtonComponent,
5344
+ TimelineFilterModule,
5271
5345
  TechlifyFormButtonComponent,
5272
5346
  TechlifyIconModule,
5273
5347
  ]
@@ -5384,69 +5458,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
5384
5458
  }]
5385
5459
  }] });
5386
5460
 
5387
- const routes$J = [];
5388
- class TimelineFilterRoutingModule {
5389
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: TimelineFilterRoutingModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
5390
- static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "18.2.14", ngImport: i0, type: TimelineFilterRoutingModule, imports: [i1$2.RouterModule], exports: [RouterModule] }); }
5391
- static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: TimelineFilterRoutingModule, imports: [RouterModule.forChild(routes$J), RouterModule] }); }
5392
- }
5393
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: TimelineFilterRoutingModule, decorators: [{
5394
- type: NgModule,
5395
- args: [{
5396
- imports: [RouterModule.forChild(routes$J)],
5397
- exports: [RouterModule]
5398
- }]
5399
- }] });
5400
-
5401
- class TimelineFilterModule {
5402
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: TimelineFilterModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
5403
- static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "18.2.14", ngImport: i0, type: TimelineFilterModule, declarations: [TimelineFilterComponent], imports: [CommonModule,
5404
- TimelineFilterRoutingModule,
5405
- FlexLayoutModule,
5406
- ReactiveFormsModule,
5407
- MatFormFieldModule,
5408
- MatSelectModule,
5409
- MatButtonModule,
5410
- MatIconModule,
5411
- MatInputModule,
5412
- MatDatepickerModule,
5413
- MatNativeDateModule,
5414
- TechlifyIconModule], exports: [TimelineFilterComponent] }); }
5415
- static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: TimelineFilterModule, imports: [CommonModule,
5416
- TimelineFilterRoutingModule,
5417
- FlexLayoutModule,
5418
- ReactiveFormsModule,
5419
- MatFormFieldModule,
5420
- MatSelectModule,
5421
- MatButtonModule,
5422
- MatIconModule,
5423
- MatInputModule,
5424
- MatDatepickerModule,
5425
- MatNativeDateModule,
5426
- TechlifyIconModule] }); }
5427
- }
5428
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: TimelineFilterModule, decorators: [{
5429
- type: NgModule,
5430
- args: [{
5431
- declarations: [TimelineFilterComponent],
5432
- imports: [
5433
- CommonModule,
5434
- TimelineFilterRoutingModule,
5435
- FlexLayoutModule,
5436
- ReactiveFormsModule,
5437
- MatFormFieldModule,
5438
- MatSelectModule,
5439
- MatButtonModule,
5440
- MatIconModule,
5441
- MatInputModule,
5442
- MatDatepickerModule,
5443
- MatNativeDateModule,
5444
- TechlifyIconModule
5445
- ],
5446
- exports: [TimelineFilterComponent]
5447
- }]
5448
- }] });
5449
-
5450
5461
  class LoaderModule {
5451
5462
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: LoaderModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
5452
5463
  static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "18.2.14", ngImport: i0, type: LoaderModule, declarations: [LoaderComponent], imports: [CommonModule,
@@ -5982,7 +5993,7 @@ let EmailSubscriptionUserListComponent = class EmailSubscriptionUserListComponen
5982
5993
  //Until destroyed uses it
5983
5994
  }
5984
5995
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: EmailSubscriptionUserListComponent, deps: [{ token: i1.MatDialog }, { token: HttpService }, { token: i1$2.Router }], target: i0.ɵɵFactoryTarget.Component }); }
5985
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.14", type: EmailSubscriptionUserListComponent, selector: "app-email-subscription-user-list", viewQueries: [{ propertyName: "sort", first: true, predicate: MatSort, descendants: true, static: true }], ngImport: i0, template: "<div class=\"mat-typography m-4\">\n <div fxLayout=\"row\" fxLayoutAlign=\"start center\">\n <app-email-subscription-user-list-filter (valueChange)=\"filterChange($event)\">\n </app-email-subscription-user-list-filter>\n <div class=\"ml-2\">\n <button mat-raised-button color=\"primary\" type=\"button\" (click)=\"addEmailSubscriptionUser()\">+\n User Subscription</button>\n </div>\n <span fxFlex></span>\n <mat-form-field appearance=\"outline\" class=\"no-padding\">\n <mat-label>Columns</mat-label>\n <mat-select [formControl]=\"displayColumns\" multiple (selectionChange)=\"columnsChange()\">\n <mat-option *ngFor=\"let column of availableDisplayColumns\" [value]=\"column.value\">{{column.name}}\n </mat-option>\n </mat-select>\n </mat-form-field>\n </div>\n\n\n\n <section>\n <div class=\"scroll-container\" infiniteScroll [infiniteScrollDistance]=\"2\" [infiniteScrollThrottle]=\"50\"\n (scrolled)=\"onScroll()\" [scrollWindow]=\"false\">\n <table mat-table [dataSource]=\"esUserList\" matSort class=\"w-100 mt-1\" multiTemplateDataRows\n id=\"email-subscription-user-table\">\n\n <!-- Index Column -->\n <ng-container matColumnDef=\"index\">\n <th mat-header-cell *matHeaderCellDef> # </th>\n <td mat-cell *matCellDef=\"let esUser; let i = dataIndex\"> {{ i+1 }} </td>\n </ng-container>\n <ng-container matColumnDef=\"user.name\">\n <th mat-header-cell *matHeaderCellDef mat-sort-header> User </th>\n <td mat-cell *matCellDef=\"let esUser;\"> {{ esUser?.user?.name }} </td>\n </ng-container>\n\n <ng-container matColumnDef=\"email_type.title\">\n <th mat-header-cell *matHeaderCellDef> Email Type </th>\n <td mat-cell *matCellDef=\"let esUser;\"> {{ esUser?.email_type?.title }} </td>\n </ng-container>\n\n <ng-container matColumnDef=\"creator.name\">\n <th mat-header-cell *matHeaderCellDef mat-sort-header> Creator</th>\n <td mat-cell *matCellDef=\"let esUser;\">\n {{esUser?.creator?.name }}\n </td>\n </ng-container>\n\n <ng-container matColumnDef=\"created_at\">\n <th mat-header-cell *matHeaderCellDef mat-sort-header> Created On</th>\n <td mat-cell *matCellDef=\"let esUser;\">\n {{esUser?.created_at | date:'medium' }}\n </td>\n </ng-container>\n\n <!-- Actions Column -->\n <ng-container matColumnDef=\"actions\">\n <th mat-header-cell *matHeaderCellDef> Actions </th>\n <td mat-cell *matCellDef=\"let esUser\">\n <button type=\"button\" mat-icon-button (click)=\"deleteEmailSubscriptionUser($event,esUser)\">\n <mat-icon>delete</mat-icon>\n </button>\n <button type=\"button\" mat-icon-button (click)=\"editEmailSubscriptionUser($event,esUser)\">\n <mat-icon>edit</mat-icon>\n </button>\n </td>\n </ng-container>\n <tr mat-header-row *matHeaderRowDef=\"displayedColumns;\"></tr>\n <tr mat-row *matRowDef=\"let row; columns: displayedColumns;\"></tr>\n </table>\n </div>\n\n </section>\n</div>", styles: [".scroll-container{max-height:800px;overflow-y:auto}\n"], dependencies: [{ kind: "directive", type: i3.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i6$2.InfiniteScrollDirective, selector: "[infiniteScroll], [infinite-scroll], [data-infinite-scroll]", inputs: ["infiniteScrollDistance", "infiniteScrollUpDistance", "infiniteScrollThrottle", "infiniteScrollDisabled", "infiniteScrollContainer", "scrollWindow", "immediateCheck", "horizontal", "alwaysCallback", "fromRoot"], outputs: ["scrolled", "scrolledUp"] }, { kind: "component", type: i6.MatButton, selector: " button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ", exportAs: ["matButton"] }, { kind: "component", type: i6.MatIconButton, selector: "button[mat-icon-button]", exportAs: ["matButton"] }, { kind: "component", type: i8$4.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i8$4.MatLabel, selector: "mat-label" }, { kind: "component", type: i8.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: i5.MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "component", type: i9$2.MatSelect, selector: "mat-select", inputs: ["aria-describedby", "panelClass", "disabled", "disableRipple", "tabIndex", "hideSingleSelectionIndicator", "placeholder", "required", "multiple", "disableOptionCentering", "compareWith", "value", "aria-label", "aria-labelledby", "errorStateMatcher", "typeaheadDebounceInterval", "sortComparator", "id", "panelWidth"], outputs: ["openedChange", "opened", "closed", "selectionChange", "valueChange"], exportAs: ["matSelect"] }, { kind: "directive", type: i11.MatSort, selector: "[matSort]", inputs: ["matSortActive", "matSortStart", "matSortDirection", "matSortDisableClear", "matSortDisabled"], outputs: ["matSortChange"], exportAs: ["matSort"] }, { kind: "component", type: i11.MatSortHeader, selector: "[mat-sort-header]", inputs: ["mat-sort-header", "arrowPosition", "start", "disabled", "sortActionDescription", "disableClear"], exportAs: ["matSortHeader"] }, { kind: "component", type: i12.MatTable, selector: "mat-table, table[mat-table]", exportAs: ["matTable"] }, { kind: "directive", type: i12.MatHeaderCellDef, selector: "[matHeaderCellDef]" }, { kind: "directive", type: i12.MatHeaderRowDef, selector: "[matHeaderRowDef]", inputs: ["matHeaderRowDef", "matHeaderRowDefSticky"] }, { kind: "directive", type: i12.MatColumnDef, selector: "[matColumnDef]", inputs: ["matColumnDef"] }, { kind: "directive", type: i12.MatCellDef, selector: "[matCellDef]" }, { kind: "directive", type: i12.MatRowDef, selector: "[matRowDef]", inputs: ["matRowDefColumns", "matRowDefWhen"] }, { kind: "directive", type: i12.MatHeaderCell, selector: "mat-header-cell, th[mat-header-cell]" }, { kind: "directive", type: i12.MatCell, selector: "mat-cell, td[mat-cell]" }, { kind: "component", type: i12.MatHeaderRow, selector: "mat-header-row, tr[mat-header-row]", exportAs: ["matHeaderRow"] }, { kind: "component", type: i12.MatRow, selector: "mat-row, tr[mat-row]", exportAs: ["matRow"] }, { kind: "directive", type: i6$1.DefaultLayoutDirective, selector: " [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]", inputs: ["fxLayout", "fxLayout.xs", "fxLayout.sm", "fxLayout.md", "fxLayout.lg", "fxLayout.xl", "fxLayout.lt-sm", "fxLayout.lt-md", "fxLayout.lt-lg", "fxLayout.lt-xl", "fxLayout.gt-xs", "fxLayout.gt-sm", "fxLayout.gt-md", "fxLayout.gt-lg"] }, { kind: "directive", type: i6$1.DefaultLayoutAlignDirective, selector: " [fxLayoutAlign], [fxLayoutAlign.xs], [fxLayoutAlign.sm], [fxLayoutAlign.md], [fxLayoutAlign.lg], [fxLayoutAlign.xl], [fxLayoutAlign.lt-sm], [fxLayoutAlign.lt-md], [fxLayoutAlign.lt-lg], [fxLayoutAlign.lt-xl], [fxLayoutAlign.gt-xs], [fxLayoutAlign.gt-sm], [fxLayoutAlign.gt-md], [fxLayoutAlign.gt-lg]", inputs: ["fxLayoutAlign", "fxLayoutAlign.xs", "fxLayoutAlign.sm", "fxLayoutAlign.md", "fxLayoutAlign.lg", "fxLayoutAlign.xl", "fxLayoutAlign.lt-sm", "fxLayoutAlign.lt-md", "fxLayoutAlign.lt-lg", "fxLayoutAlign.lt-xl", "fxLayoutAlign.gt-xs", "fxLayoutAlign.gt-sm", "fxLayoutAlign.gt-md", "fxLayoutAlign.gt-lg"] }, { kind: "directive", type: i6$1.DefaultFlexDirective, selector: " [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]", inputs: ["fxFlex", "fxFlex.xs", "fxFlex.sm", "fxFlex.md", "fxFlex.lg", "fxFlex.xl", "fxFlex.lt-sm", "fxFlex.lt-md", "fxFlex.lt-lg", "fxFlex.lt-xl", "fxFlex.gt-xs", "fxFlex.gt-sm", "fxFlex.gt-md", "fxFlex.gt-lg"] }, { kind: "directive", type: i1$5.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$5.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "component", type: EmailSubscriptionUserListFilterComponent, selector: "app-email-subscription-user-list-filter", outputs: ["valueChange"] }, { kind: "pipe", type: i3.DatePipe, name: "date" }] }); }
5996
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.14", type: EmailSubscriptionUserListComponent, selector: "app-email-subscription-user-list", viewQueries: [{ propertyName: "sort", first: true, predicate: MatSort, descendants: true, static: true }], ngImport: i0, template: "<div class=\"mat-typography m-4\">\n <div fxLayout=\"row\" fxLayoutAlign=\"start center\">\n <app-email-subscription-user-list-filter (valueChange)=\"filterChange($event)\">\n </app-email-subscription-user-list-filter>\n <div class=\"ml-2\">\n <button mat-raised-button color=\"primary\" type=\"button\" (click)=\"addEmailSubscriptionUser()\">+\n User Subscription</button>\n </div>\n <span fxFlex></span>\n <mat-form-field appearance=\"outline\" class=\"no-padding\">\n <mat-label>Columns</mat-label>\n <mat-select [formControl]=\"displayColumns\" multiple (selectionChange)=\"columnsChange()\">\n <mat-option *ngFor=\"let column of availableDisplayColumns\" [value]=\"column.value\">{{column.name}}\n </mat-option>\n </mat-select>\n </mat-form-field>\n </div>\n\n\n\n <section>\n <div class=\"scroll-container\" infiniteScroll [infiniteScrollDistance]=\"2\" [infiniteScrollThrottle]=\"50\"\n (scrolled)=\"onScroll()\" [scrollWindow]=\"false\">\n <table mat-table [dataSource]=\"esUserList\" matSort class=\"w-100 mt-1\" multiTemplateDataRows\n id=\"email-subscription-user-table\">\n\n <!-- Index Column -->\n <ng-container matColumnDef=\"index\">\n <th mat-header-cell *matHeaderCellDef> # </th>\n <td mat-cell *matCellDef=\"let esUser; let i = dataIndex\"> {{ i+1 }} </td>\n </ng-container>\n <ng-container matColumnDef=\"user.name\">\n <th mat-header-cell *matHeaderCellDef mat-sort-header> User </th>\n <td mat-cell *matCellDef=\"let esUser;\"> {{ esUser?.user?.name }} </td>\n </ng-container>\n\n <ng-container matColumnDef=\"email_type.title\">\n <th mat-header-cell *matHeaderCellDef> Email Type </th>\n <td mat-cell *matCellDef=\"let esUser;\"> {{ esUser?.email_type?.title }} </td>\n </ng-container>\n\n <ng-container matColumnDef=\"creator.name\">\n <th mat-header-cell *matHeaderCellDef mat-sort-header> Creator</th>\n <td mat-cell *matCellDef=\"let esUser;\">\n {{esUser?.creator?.name }}\n </td>\n </ng-container>\n\n <ng-container matColumnDef=\"created_at\">\n <th mat-header-cell *matHeaderCellDef mat-sort-header> Created On</th>\n <td mat-cell *matCellDef=\"let esUser;\">\n {{esUser?.created_at | date:'medium' }}\n </td>\n </ng-container>\n\n <!-- Actions Column -->\n <ng-container matColumnDef=\"actions\">\n <th mat-header-cell *matHeaderCellDef> Actions </th>\n <td mat-cell *matCellDef=\"let esUser\">\n <button type=\"button\" mat-icon-button (click)=\"deleteEmailSubscriptionUser($event,esUser)\">\n <mat-icon>delete</mat-icon>\n </button>\n <button type=\"button\" mat-icon-button (click)=\"editEmailSubscriptionUser($event,esUser)\">\n <mat-icon>edit</mat-icon>\n </button>\n </td>\n </ng-container>\n <tr mat-header-row *matHeaderRowDef=\"displayedColumns;\"></tr>\n <tr mat-row *matRowDef=\"let row; columns: displayedColumns;\"></tr>\n </table>\n </div>\n\n </section>\n</div>", styles: [".scroll-container{max-height:800px;overflow-y:auto}\n"], dependencies: [{ kind: "directive", type: i3.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i6$2.InfiniteScrollDirective, selector: "[infiniteScroll], [infinite-scroll], [data-infinite-scroll]", inputs: ["infiniteScrollDistance", "infiniteScrollUpDistance", "infiniteScrollThrottle", "infiniteScrollDisabled", "infiniteScrollContainer", "scrollWindow", "immediateCheck", "horizontal", "alwaysCallback", "fromRoot"], outputs: ["scrolled", "scrolledUp"] }, { kind: "component", type: i6.MatButton, selector: " button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ", exportAs: ["matButton"] }, { kind: "component", type: i6.MatIconButton, selector: "button[mat-icon-button]", exportAs: ["matButton"] }, { kind: "component", type: i8$4.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i8$4.MatLabel, selector: "mat-label" }, { kind: "component", type: i8.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: i5.MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "component", type: i9$1.MatSelect, selector: "mat-select", inputs: ["aria-describedby", "panelClass", "disabled", "disableRipple", "tabIndex", "hideSingleSelectionIndicator", "placeholder", "required", "multiple", "disableOptionCentering", "compareWith", "value", "aria-label", "aria-labelledby", "errorStateMatcher", "typeaheadDebounceInterval", "sortComparator", "id", "panelWidth"], outputs: ["openedChange", "opened", "closed", "selectionChange", "valueChange"], exportAs: ["matSelect"] }, { kind: "directive", type: i11.MatSort, selector: "[matSort]", inputs: ["matSortActive", "matSortStart", "matSortDirection", "matSortDisableClear", "matSortDisabled"], outputs: ["matSortChange"], exportAs: ["matSort"] }, { kind: "component", type: i11.MatSortHeader, selector: "[mat-sort-header]", inputs: ["mat-sort-header", "arrowPosition", "start", "disabled", "sortActionDescription", "disableClear"], exportAs: ["matSortHeader"] }, { kind: "component", type: i12.MatTable, selector: "mat-table, table[mat-table]", exportAs: ["matTable"] }, { kind: "directive", type: i12.MatHeaderCellDef, selector: "[matHeaderCellDef]" }, { kind: "directive", type: i12.MatHeaderRowDef, selector: "[matHeaderRowDef]", inputs: ["matHeaderRowDef", "matHeaderRowDefSticky"] }, { kind: "directive", type: i12.MatColumnDef, selector: "[matColumnDef]", inputs: ["matColumnDef"] }, { kind: "directive", type: i12.MatCellDef, selector: "[matCellDef]" }, { kind: "directive", type: i12.MatRowDef, selector: "[matRowDef]", inputs: ["matRowDefColumns", "matRowDefWhen"] }, { kind: "directive", type: i12.MatHeaderCell, selector: "mat-header-cell, th[mat-header-cell]" }, { kind: "directive", type: i12.MatCell, selector: "mat-cell, td[mat-cell]" }, { kind: "component", type: i12.MatHeaderRow, selector: "mat-header-row, tr[mat-header-row]", exportAs: ["matHeaderRow"] }, { kind: "component", type: i12.MatRow, selector: "mat-row, tr[mat-row]", exportAs: ["matRow"] }, { kind: "directive", type: i6$1.DefaultLayoutDirective, selector: " [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]", inputs: ["fxLayout", "fxLayout.xs", "fxLayout.sm", "fxLayout.md", "fxLayout.lg", "fxLayout.xl", "fxLayout.lt-sm", "fxLayout.lt-md", "fxLayout.lt-lg", "fxLayout.lt-xl", "fxLayout.gt-xs", "fxLayout.gt-sm", "fxLayout.gt-md", "fxLayout.gt-lg"] }, { kind: "directive", type: i6$1.DefaultLayoutAlignDirective, selector: " [fxLayoutAlign], [fxLayoutAlign.xs], [fxLayoutAlign.sm], [fxLayoutAlign.md], [fxLayoutAlign.lg], [fxLayoutAlign.xl], [fxLayoutAlign.lt-sm], [fxLayoutAlign.lt-md], [fxLayoutAlign.lt-lg], [fxLayoutAlign.lt-xl], [fxLayoutAlign.gt-xs], [fxLayoutAlign.gt-sm], [fxLayoutAlign.gt-md], [fxLayoutAlign.gt-lg]", inputs: ["fxLayoutAlign", "fxLayoutAlign.xs", "fxLayoutAlign.sm", "fxLayoutAlign.md", "fxLayoutAlign.lg", "fxLayoutAlign.xl", "fxLayoutAlign.lt-sm", "fxLayoutAlign.lt-md", "fxLayoutAlign.lt-lg", "fxLayoutAlign.lt-xl", "fxLayoutAlign.gt-xs", "fxLayoutAlign.gt-sm", "fxLayoutAlign.gt-md", "fxLayoutAlign.gt-lg"] }, { kind: "directive", type: i6$1.DefaultFlexDirective, selector: " [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]", inputs: ["fxFlex", "fxFlex.xs", "fxFlex.sm", "fxFlex.md", "fxFlex.lg", "fxFlex.xl", "fxFlex.lt-sm", "fxFlex.lt-md", "fxFlex.lt-lg", "fxFlex.lt-xl", "fxFlex.gt-xs", "fxFlex.gt-sm", "fxFlex.gt-md", "fxFlex.gt-lg"] }, { kind: "directive", type: i1$5.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$5.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "component", type: EmailSubscriptionUserListFilterComponent, selector: "app-email-subscription-user-list-filter", outputs: ["valueChange"] }, { kind: "pipe", type: i3.DatePipe, name: "date" }] }); }
5986
5997
  };
5987
5998
  EmailSubscriptionUserListComponent = __decorate([
5988
5999
  UntilDestroy()
@@ -6394,7 +6405,7 @@ let EmailSubscriptionTypeListComponent = class EmailSubscriptionTypeListComponen
6394
6405
  //Until destroyed uses it
6395
6406
  }
6396
6407
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: EmailSubscriptionTypeListComponent, deps: [{ token: i1.MatDialog }, { token: HttpService }], target: i0.ɵɵFactoryTarget.Component }); }
6397
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.14", type: EmailSubscriptionTypeListComponent, selector: "app-email-subscription-type-list", viewQueries: [{ propertyName: "sort", first: true, predicate: MatSort, descendants: true, static: true }], ngImport: i0, template: "<div class=\"mat-typography m-4\">\n <div fxLayout=\"row wrap\" fxLayoutAlign=\"start center\">\n <mat-form-field>\n <input matInput [formControl]=\"search\" placeholder=\"Email Type\" autocomplete=\"off\" />\n <button matSuffix mat-icon-button>\n <mat-icon>search</mat-icon>\n </button>\n <button *ngIf=\"search.value\" matSuffix mat-icon-button (click)=\"search.setValue('')\">\n <mat-icon>close</mat-icon>\n </button>\n </mat-form-field>\n <div class=\"ml-2\">\n <button mat-raised-button color=\"primary\" type=\"button\" (click)=\"addEmailSubscriptionType()\">+ Email\n Type</button>\n </div>\n <span fxFlex></span>\n <mat-form-field appearance=\"outline\" class=\"no-padding\">\n <mat-label>Columns</mat-label>\n <mat-select [formControl]=\"displayColumns\" multiple (selectionChange)=\"columnsChange()\">\n <mat-option *ngFor=\"let column of availableDisplayColumns\" [value]=\"column.value\">{{column.name}}\n </mat-option>\n </mat-select>\n </mat-form-field>\n </div>\n\n <section>\n <div class=\"scroll-container\" infiniteScroll [infiniteScrollDistance]=\"2\" [infiniteScrollThrottle]=\"50\"\n (scrolled)=\"onScroll()\" [scrollWindow]=\"false\">\n <table mat-table [dataSource]=\"emailSubscriptionTypeList\" matSort class=\"w-100 mt-1\" multiTemplateDataRows\n id=\"email-subscription-type-table\">\n\n <!-- Index Column -->\n <ng-container matColumnDef=\"index\">\n <th mat-header-cell *matHeaderCellDef> # </th>\n <td mat-cell *matCellDef=\"let emailSubscriptionType; let i = dataIndex\"> {{ i+1 }} </td>\n </ng-container>\n <ng-container matColumnDef=\"title\">\n <th mat-header-cell *matHeaderCellDef mat-sort-header> Title </th>\n <td mat-cell *matCellDef=\"let emailSubscriptionType;\"> {{ emailSubscriptionType?.title }} </td>\n </ng-container>\n <ng-container matColumnDef=\"code\">\n <th mat-header-cell *matHeaderCellDef mat-sort-header> Code </th>\n <td mat-cell *matCellDef=\"let emailSubscriptionType;\"> {{ emailSubscriptionType?.code }}\n </td>\n </ng-container>\n <ng-container matColumnDef=\"frequency.title\">\n <th mat-header-cell *matHeaderCellDef mat-sort-header> Frequency </th>\n <td mat-cell *matCellDef=\"let emailSubscriptionType;\"> {{ emailSubscriptionType?.frequency?.title }}\n </td>\n </ng-container>\n <ng-container matColumnDef=\"description\">\n <th mat-header-cell *matHeaderCellDef> Description </th>\n <td mat-cell *matCellDef=\"let emailSubscriptionType;\"> {{ emailSubscriptionType?.description }}\n </td>\n </ng-container>\n\n <!-- Actions Column -->\n <ng-container matColumnDef=\"actions\">\n <th mat-header-cell *matHeaderCellDef> Actions </th>\n <td mat-cell *matCellDef=\"let emailSubscriptionType\">\n <button type=\"button\" mat-icon-button\n (click)=\"deleteEmailSubscriptionType($event,emailSubscriptionType)\">\n <mat-icon>delete</mat-icon>\n </button>\n <button type=\"button\" mat-icon-button\n (click)=\"editEmailSubscriptionType($event,emailSubscriptionType)\">\n <mat-icon>edit</mat-icon>\n </button>\n </td>\n </ng-container>\n <tr mat-header-row *matHeaderRowDef=\"displayedColumns; sticky:true\"></tr>\n <tr mat-row *matRowDef=\"let row; columns: displayedColumns;\"></tr>\n </table>\n </div>\n </section>\n</div>", styles: [".scroll-container{max-height:800px;overflow-y:auto}\n"], dependencies: [{ kind: "directive", type: i3.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: i6.MatButton, selector: " button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ", exportAs: ["matButton"] }, { kind: "component", type: i6.MatIconButton, selector: "button[mat-icon-button]", exportAs: ["matButton"] }, { kind: "component", type: i8$4.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i8$4.MatLabel, selector: "mat-label" }, { kind: "directive", type: i8$4.MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { kind: "component", type: i8.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "directive", type: i9.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly"], exportAs: ["matInput"] }, { kind: "component", type: i5.MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "component", type: i9$2.MatSelect, selector: "mat-select", inputs: ["aria-describedby", "panelClass", "disabled", "disableRipple", "tabIndex", "hideSingleSelectionIndicator", "placeholder", "required", "multiple", "disableOptionCentering", "compareWith", "value", "aria-label", "aria-labelledby", "errorStateMatcher", "typeaheadDebounceInterval", "sortComparator", "id", "panelWidth"], outputs: ["openedChange", "opened", "closed", "selectionChange", "valueChange"], exportAs: ["matSelect"] }, { kind: "directive", type: i11.MatSort, selector: "[matSort]", inputs: ["matSortActive", "matSortStart", "matSortDirection", "matSortDisableClear", "matSortDisabled"], outputs: ["matSortChange"], exportAs: ["matSort"] }, { kind: "component", type: i11.MatSortHeader, selector: "[mat-sort-header]", inputs: ["mat-sort-header", "arrowPosition", "start", "disabled", "sortActionDescription", "disableClear"], exportAs: ["matSortHeader"] }, { kind: "component", type: i12.MatTable, selector: "mat-table, table[mat-table]", exportAs: ["matTable"] }, { kind: "directive", type: i12.MatHeaderCellDef, selector: "[matHeaderCellDef]" }, { kind: "directive", type: i12.MatHeaderRowDef, selector: "[matHeaderRowDef]", inputs: ["matHeaderRowDef", "matHeaderRowDefSticky"] }, { kind: "directive", type: i12.MatColumnDef, selector: "[matColumnDef]", inputs: ["matColumnDef"] }, { kind: "directive", type: i12.MatCellDef, selector: "[matCellDef]" }, { kind: "directive", type: i12.MatRowDef, selector: "[matRowDef]", inputs: ["matRowDefColumns", "matRowDefWhen"] }, { kind: "directive", type: i12.MatHeaderCell, selector: "mat-header-cell, th[mat-header-cell]" }, { kind: "directive", type: i12.MatCell, selector: "mat-cell, td[mat-cell]" }, { kind: "component", type: i12.MatHeaderRow, selector: "mat-header-row, tr[mat-header-row]", exportAs: ["matHeaderRow"] }, { kind: "component", type: i12.MatRow, selector: "mat-row, tr[mat-row]", exportAs: ["matRow"] }, { kind: "directive", type: i6$1.DefaultLayoutDirective, selector: " [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]", inputs: ["fxLayout", "fxLayout.xs", "fxLayout.sm", "fxLayout.md", "fxLayout.lg", "fxLayout.xl", "fxLayout.lt-sm", "fxLayout.lt-md", "fxLayout.lt-lg", "fxLayout.lt-xl", "fxLayout.gt-xs", "fxLayout.gt-sm", "fxLayout.gt-md", "fxLayout.gt-lg"] }, { kind: "directive", type: i6$1.DefaultLayoutAlignDirective, selector: " [fxLayoutAlign], [fxLayoutAlign.xs], [fxLayoutAlign.sm], [fxLayoutAlign.md], [fxLayoutAlign.lg], [fxLayoutAlign.xl], [fxLayoutAlign.lt-sm], [fxLayoutAlign.lt-md], [fxLayoutAlign.lt-lg], [fxLayoutAlign.lt-xl], [fxLayoutAlign.gt-xs], [fxLayoutAlign.gt-sm], [fxLayoutAlign.gt-md], [fxLayoutAlign.gt-lg]", inputs: ["fxLayoutAlign", "fxLayoutAlign.xs", "fxLayoutAlign.sm", "fxLayoutAlign.md", "fxLayoutAlign.lg", "fxLayoutAlign.xl", "fxLayoutAlign.lt-sm", "fxLayoutAlign.lt-md", "fxLayoutAlign.lt-lg", "fxLayoutAlign.lt-xl", "fxLayoutAlign.gt-xs", "fxLayoutAlign.gt-sm", "fxLayoutAlign.gt-md", "fxLayoutAlign.gt-lg"] }, { kind: "directive", type: i6$1.DefaultFlexDirective, selector: " [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]", inputs: ["fxFlex", "fxFlex.xs", "fxFlex.sm", "fxFlex.md", "fxFlex.lg", "fxFlex.xl", "fxFlex.lt-sm", "fxFlex.lt-md", "fxFlex.lt-lg", "fxFlex.lt-xl", "fxFlex.gt-xs", "fxFlex.gt-sm", "fxFlex.gt-md", "fxFlex.gt-lg"] }, { kind: "directive", type: i1$5.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$5.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$5.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "directive", type: i6$2.InfiniteScrollDirective, selector: "[infiniteScroll], [infinite-scroll], [data-infinite-scroll]", inputs: ["infiniteScrollDistance", "infiniteScrollUpDistance", "infiniteScrollThrottle", "infiniteScrollDisabled", "infiniteScrollContainer", "scrollWindow", "immediateCheck", "horizontal", "alwaysCallback", "fromRoot"], outputs: ["scrolled", "scrolledUp"] }] }); }
6408
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.14", type: EmailSubscriptionTypeListComponent, selector: "app-email-subscription-type-list", viewQueries: [{ propertyName: "sort", first: true, predicate: MatSort, descendants: true, static: true }], ngImport: i0, template: "<div class=\"mat-typography m-4\">\n <div fxLayout=\"row wrap\" fxLayoutAlign=\"start center\">\n <mat-form-field>\n <input matInput [formControl]=\"search\" placeholder=\"Email Type\" autocomplete=\"off\" />\n <button matSuffix mat-icon-button>\n <mat-icon>search</mat-icon>\n </button>\n <button *ngIf=\"search.value\" matSuffix mat-icon-button (click)=\"search.setValue('')\">\n <mat-icon>close</mat-icon>\n </button>\n </mat-form-field>\n <div class=\"ml-2\">\n <button mat-raised-button color=\"primary\" type=\"button\" (click)=\"addEmailSubscriptionType()\">+ Email\n Type</button>\n </div>\n <span fxFlex></span>\n <mat-form-field appearance=\"outline\" class=\"no-padding\">\n <mat-label>Columns</mat-label>\n <mat-select [formControl]=\"displayColumns\" multiple (selectionChange)=\"columnsChange()\">\n <mat-option *ngFor=\"let column of availableDisplayColumns\" [value]=\"column.value\">{{column.name}}\n </mat-option>\n </mat-select>\n </mat-form-field>\n </div>\n\n <section>\n <div class=\"scroll-container\" infiniteScroll [infiniteScrollDistance]=\"2\" [infiniteScrollThrottle]=\"50\"\n (scrolled)=\"onScroll()\" [scrollWindow]=\"false\">\n <table mat-table [dataSource]=\"emailSubscriptionTypeList\" matSort class=\"w-100 mt-1\" multiTemplateDataRows\n id=\"email-subscription-type-table\">\n\n <!-- Index Column -->\n <ng-container matColumnDef=\"index\">\n <th mat-header-cell *matHeaderCellDef> # </th>\n <td mat-cell *matCellDef=\"let emailSubscriptionType; let i = dataIndex\"> {{ i+1 }} </td>\n </ng-container>\n <ng-container matColumnDef=\"title\">\n <th mat-header-cell *matHeaderCellDef mat-sort-header> Title </th>\n <td mat-cell *matCellDef=\"let emailSubscriptionType;\"> {{ emailSubscriptionType?.title }} </td>\n </ng-container>\n <ng-container matColumnDef=\"code\">\n <th mat-header-cell *matHeaderCellDef mat-sort-header> Code </th>\n <td mat-cell *matCellDef=\"let emailSubscriptionType;\"> {{ emailSubscriptionType?.code }}\n </td>\n </ng-container>\n <ng-container matColumnDef=\"frequency.title\">\n <th mat-header-cell *matHeaderCellDef mat-sort-header> Frequency </th>\n <td mat-cell *matCellDef=\"let emailSubscriptionType;\"> {{ emailSubscriptionType?.frequency?.title }}\n </td>\n </ng-container>\n <ng-container matColumnDef=\"description\">\n <th mat-header-cell *matHeaderCellDef> Description </th>\n <td mat-cell *matCellDef=\"let emailSubscriptionType;\"> {{ emailSubscriptionType?.description }}\n </td>\n </ng-container>\n\n <!-- Actions Column -->\n <ng-container matColumnDef=\"actions\">\n <th mat-header-cell *matHeaderCellDef> Actions </th>\n <td mat-cell *matCellDef=\"let emailSubscriptionType\">\n <button type=\"button\" mat-icon-button\n (click)=\"deleteEmailSubscriptionType($event,emailSubscriptionType)\">\n <mat-icon>delete</mat-icon>\n </button>\n <button type=\"button\" mat-icon-button\n (click)=\"editEmailSubscriptionType($event,emailSubscriptionType)\">\n <mat-icon>edit</mat-icon>\n </button>\n </td>\n </ng-container>\n <tr mat-header-row *matHeaderRowDef=\"displayedColumns; sticky:true\"></tr>\n <tr mat-row *matRowDef=\"let row; columns: displayedColumns;\"></tr>\n </table>\n </div>\n </section>\n</div>", styles: [".scroll-container{max-height:800px;overflow-y:auto}\n"], dependencies: [{ kind: "directive", type: i3.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: i6.MatButton, selector: " button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ", exportAs: ["matButton"] }, { kind: "component", type: i6.MatIconButton, selector: "button[mat-icon-button]", exportAs: ["matButton"] }, { kind: "component", type: i8$4.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i8$4.MatLabel, selector: "mat-label" }, { kind: "directive", type: i8$4.MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { kind: "component", type: i8.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "directive", type: i9.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly"], exportAs: ["matInput"] }, { kind: "component", type: i5.MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "component", type: i9$1.MatSelect, selector: "mat-select", inputs: ["aria-describedby", "panelClass", "disabled", "disableRipple", "tabIndex", "hideSingleSelectionIndicator", "placeholder", "required", "multiple", "disableOptionCentering", "compareWith", "value", "aria-label", "aria-labelledby", "errorStateMatcher", "typeaheadDebounceInterval", "sortComparator", "id", "panelWidth"], outputs: ["openedChange", "opened", "closed", "selectionChange", "valueChange"], exportAs: ["matSelect"] }, { kind: "directive", type: i11.MatSort, selector: "[matSort]", inputs: ["matSortActive", "matSortStart", "matSortDirection", "matSortDisableClear", "matSortDisabled"], outputs: ["matSortChange"], exportAs: ["matSort"] }, { kind: "component", type: i11.MatSortHeader, selector: "[mat-sort-header]", inputs: ["mat-sort-header", "arrowPosition", "start", "disabled", "sortActionDescription", "disableClear"], exportAs: ["matSortHeader"] }, { kind: "component", type: i12.MatTable, selector: "mat-table, table[mat-table]", exportAs: ["matTable"] }, { kind: "directive", type: i12.MatHeaderCellDef, selector: "[matHeaderCellDef]" }, { kind: "directive", type: i12.MatHeaderRowDef, selector: "[matHeaderRowDef]", inputs: ["matHeaderRowDef", "matHeaderRowDefSticky"] }, { kind: "directive", type: i12.MatColumnDef, selector: "[matColumnDef]", inputs: ["matColumnDef"] }, { kind: "directive", type: i12.MatCellDef, selector: "[matCellDef]" }, { kind: "directive", type: i12.MatRowDef, selector: "[matRowDef]", inputs: ["matRowDefColumns", "matRowDefWhen"] }, { kind: "directive", type: i12.MatHeaderCell, selector: "mat-header-cell, th[mat-header-cell]" }, { kind: "directive", type: i12.MatCell, selector: "mat-cell, td[mat-cell]" }, { kind: "component", type: i12.MatHeaderRow, selector: "mat-header-row, tr[mat-header-row]", exportAs: ["matHeaderRow"] }, { kind: "component", type: i12.MatRow, selector: "mat-row, tr[mat-row]", exportAs: ["matRow"] }, { kind: "directive", type: i6$1.DefaultLayoutDirective, selector: " [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]", inputs: ["fxLayout", "fxLayout.xs", "fxLayout.sm", "fxLayout.md", "fxLayout.lg", "fxLayout.xl", "fxLayout.lt-sm", "fxLayout.lt-md", "fxLayout.lt-lg", "fxLayout.lt-xl", "fxLayout.gt-xs", "fxLayout.gt-sm", "fxLayout.gt-md", "fxLayout.gt-lg"] }, { kind: "directive", type: i6$1.DefaultLayoutAlignDirective, selector: " [fxLayoutAlign], [fxLayoutAlign.xs], [fxLayoutAlign.sm], [fxLayoutAlign.md], [fxLayoutAlign.lg], [fxLayoutAlign.xl], [fxLayoutAlign.lt-sm], [fxLayoutAlign.lt-md], [fxLayoutAlign.lt-lg], [fxLayoutAlign.lt-xl], [fxLayoutAlign.gt-xs], [fxLayoutAlign.gt-sm], [fxLayoutAlign.gt-md], [fxLayoutAlign.gt-lg]", inputs: ["fxLayoutAlign", "fxLayoutAlign.xs", "fxLayoutAlign.sm", "fxLayoutAlign.md", "fxLayoutAlign.lg", "fxLayoutAlign.xl", "fxLayoutAlign.lt-sm", "fxLayoutAlign.lt-md", "fxLayoutAlign.lt-lg", "fxLayoutAlign.lt-xl", "fxLayoutAlign.gt-xs", "fxLayoutAlign.gt-sm", "fxLayoutAlign.gt-md", "fxLayoutAlign.gt-lg"] }, { kind: "directive", type: i6$1.DefaultFlexDirective, selector: " [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]", inputs: ["fxFlex", "fxFlex.xs", "fxFlex.sm", "fxFlex.md", "fxFlex.lg", "fxFlex.xl", "fxFlex.lt-sm", "fxFlex.lt-md", "fxFlex.lt-lg", "fxFlex.lt-xl", "fxFlex.gt-xs", "fxFlex.gt-sm", "fxFlex.gt-md", "fxFlex.gt-lg"] }, { kind: "directive", type: i1$5.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$5.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$5.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "directive", type: i6$2.InfiniteScrollDirective, selector: "[infiniteScroll], [infinite-scroll], [data-infinite-scroll]", inputs: ["infiniteScrollDistance", "infiniteScrollUpDistance", "infiniteScrollThrottle", "infiniteScrollDisabled", "infiniteScrollContainer", "scrollWindow", "immediateCheck", "horizontal", "alwaysCallback", "fromRoot"], outputs: ["scrolled", "scrolledUp"] }] }); }
6398
6409
  };
6399
6410
  EmailSubscriptionTypeListComponent = __decorate([
6400
6411
  UntilDestroy()
@@ -7606,7 +7617,7 @@ let AuditLogListFilterComponent = class AuditLogListFilterComponent {
7606
7617
  ngOnDestroy() {
7607
7618
  }
7608
7619
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: AuditLogListFilterComponent, deps: [{ token: FormValidatorService }], target: i0.ɵɵFactoryTarget.Component }); }
7609
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.14", type: AuditLogListFilterComponent, selector: "app-audit-log-list-filter", inputs: { filterForm: "filterForm", objectId: "objectId", objectType: "objectType" }, outputs: { valueChange: "valueChange" }, ngImport: i0, template: "<form [formGroup]=\"filterForm\" class=\"d-flex justify-content-end align-items-center gap-2 w-100\">\n <mat-form-field class='fl-md'>\n <mat-label>Search Changes</mat-label>\n <input type=\"text\" matInput formControlName=\"change_search\" />\n <button *ngIf=\"getFieldValue('change_search')\" matSuffix mat-icon-button (click)=\"resetFieldValue('change_search')\">\n <mat-icon>close</mat-icon>\n </button>\n </mat-form-field>\n\n <app-timeline-filter class='fl-sm' labelText=\"Activity Date\" formControlName=\"duration\"\n [form]=\"filterForm\" [showClearButton]=\"true\" appearance=\"outline\"></app-timeline-filter>\n\n <mat-form-field class='fl-sm'>\n <mat-label>Action</mat-label>\n <mat-select formControlName=\"action\" [multiple]=\"true\">\n <mat-option value=\"created\">Created</mat-option>\n <mat-option value=\"updated\">Updated</mat-option>\n <mat-option value=\"deleted\">Deleted</mat-option>\n </mat-select>\n <button *ngIf=\"getFieldValue('action')\" matSuffix mat-icon-button (click)=\"resetFieldValue('action')\">\n <mat-icon>close</mat-icon>\n </button>\n </mat-form-field>\n\n <mat-form-field class='fl-sm' *ngIf=\"showObjectFilter\">\n <mat-label>Model Type</mat-label>\n <app-searchable-selector formControlName=\"object_type\" apiUrl=\"api/audit-log-types\" titleField=\"object_type\"\n valueField=\"object_type\" [sort]=\"false\" [multiple]=\"true\">\n </app-searchable-selector>\n <button *ngIf=\"getFieldValue('object_type')\" matSuffix mat-icon-button (click)=\"resetFieldValue('object_type')\">\n <mat-icon>close</mat-icon>\n </button>\n </mat-form-field>\n\n <mat-form-field class='fl-sm'>\n <mat-label>Model #</mat-label>\n <input type=\"text\" matInput formControlName=\"model_search\" />\n <button *ngIf=\"getFieldValue('model_search')\" matSuffix mat-icon-button (click)=\"resetFieldValue('model_search')\">\n <mat-icon>close</mat-icon>\n </button>\n </mat-form-field>\n\n <mat-form-field class='fl-sm'>\n <mat-label>Creator</mat-label>\n <app-searchable-selector formControlName=\"creator_ids\" [multiple]=\"true\" apiUrl=\"api/users\"\n titleField=\"name\"></app-searchable-selector>\n <button *ngIf=\"getFieldValue('creator_ids')\" matSuffix mat-icon-button (click)=\"resetFieldValue('creator_ids')\">\n <mat-icon>close</mat-icon>\n </button>\n </mat-form-field>\n\n</form>", styles: [""], dependencies: [{ kind: "directive", type: i3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1$5.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1$5.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$5.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$5.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1$5.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$5.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "component", type: i6.MatIconButton, selector: "button[mat-icon-button]", exportAs: ["matButton"] }, { kind: "component", type: i8$4.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i8$4.MatLabel, selector: "mat-label" }, { kind: "directive", type: i8$4.MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { kind: "component", type: i8.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "directive", type: i9.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly"], exportAs: ["matInput"] }, { kind: "component", type: i5.MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "component", type: i9$2.MatSelect, selector: "mat-select", inputs: ["aria-describedby", "panelClass", "disabled", "disableRipple", "tabIndex", "hideSingleSelectionIndicator", "placeholder", "required", "multiple", "disableOptionCentering", "compareWith", "value", "aria-label", "aria-labelledby", "errorStateMatcher", "typeaheadDebounceInterval", "sortComparator", "id", "panelWidth"], outputs: ["openedChange", "opened", "closed", "selectionChange", "valueChange"], exportAs: ["matSelect"] }, { kind: "component", type: SearchableSelectorComponent, selector: "app-searchable-selector", inputs: ["valueField", "titleField", "subtitleField", "apiUrl", "multiple", "selectedValue", "enableSearch", "add", "addConfig", "edit", "editConfig", "sort", "sortBy", "searchField", "itemComponent", "items", "apiDataProperty", "cache", "perPage", "inDataSearch", "panelWidth", "focusSearchOnOpen", "isEmitInitialEvent", "required", "disabled", "value"], outputs: ["selectedValueChange", "selectionChange", "itemsChange", "isItemsEmpty"] }, { kind: "component", type: TimelineFilterComponent, selector: "app-timeline-filter", inputs: ["defaultValue", "required", "disabled", "value", "timelines", "dateFrom", "dateTo", "appearance", "showClearButton", "form", "labelText"], outputs: ["selectionChange"] }] }); }
7620
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.14", type: AuditLogListFilterComponent, selector: "app-audit-log-list-filter", inputs: { filterForm: "filterForm", objectId: "objectId", objectType: "objectType" }, outputs: { valueChange: "valueChange" }, ngImport: i0, template: "<form [formGroup]=\"filterForm\" class=\"d-flex justify-content-end align-items-center gap-2 w-100\">\n <mat-form-field class='fl-md'>\n <mat-label>Search Changes</mat-label>\n <input type=\"text\" matInput formControlName=\"change_search\" />\n <button *ngIf=\"getFieldValue('change_search')\" matSuffix mat-icon-button (click)=\"resetFieldValue('change_search')\">\n <mat-icon>close</mat-icon>\n </button>\n </mat-form-field>\n\n <app-timeline-filter class='fl-sm' labelText=\"Activity Date\" formControlName=\"duration\"\n [form]=\"filterForm\" [showClearButton]=\"true\" appearance=\"outline\"></app-timeline-filter>\n\n <mat-form-field class='fl-sm'>\n <mat-label>Action</mat-label>\n <mat-select formControlName=\"action\" [multiple]=\"true\">\n <mat-option value=\"created\">Created</mat-option>\n <mat-option value=\"updated\">Updated</mat-option>\n <mat-option value=\"deleted\">Deleted</mat-option>\n </mat-select>\n <button *ngIf=\"getFieldValue('action')\" matSuffix mat-icon-button (click)=\"resetFieldValue('action')\">\n <mat-icon>close</mat-icon>\n </button>\n </mat-form-field>\n\n <mat-form-field class='fl-sm' *ngIf=\"showObjectFilter\">\n <mat-label>Model Type</mat-label>\n <app-searchable-selector formControlName=\"object_type\" apiUrl=\"api/audit-log-types\" titleField=\"object_type\"\n valueField=\"object_type\" [sort]=\"false\" [multiple]=\"true\">\n </app-searchable-selector>\n <button *ngIf=\"getFieldValue('object_type')\" matSuffix mat-icon-button (click)=\"resetFieldValue('object_type')\">\n <mat-icon>close</mat-icon>\n </button>\n </mat-form-field>\n\n <mat-form-field class='fl-sm'>\n <mat-label>Model #</mat-label>\n <input type=\"text\" matInput formControlName=\"model_search\" />\n <button *ngIf=\"getFieldValue('model_search')\" matSuffix mat-icon-button (click)=\"resetFieldValue('model_search')\">\n <mat-icon>close</mat-icon>\n </button>\n </mat-form-field>\n\n <mat-form-field class='fl-sm'>\n <mat-label>Creator</mat-label>\n <app-searchable-selector formControlName=\"creator_ids\" [multiple]=\"true\" apiUrl=\"api/users\"\n titleField=\"name\"></app-searchable-selector>\n <button *ngIf=\"getFieldValue('creator_ids')\" matSuffix mat-icon-button (click)=\"resetFieldValue('creator_ids')\">\n <mat-icon>close</mat-icon>\n </button>\n </mat-form-field>\n\n</form>", styles: [""], dependencies: [{ kind: "directive", type: i3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1$5.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1$5.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$5.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$5.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1$5.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$5.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "component", type: i6.MatIconButton, selector: "button[mat-icon-button]", exportAs: ["matButton"] }, { kind: "component", type: i8$4.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i8$4.MatLabel, selector: "mat-label" }, { kind: "directive", type: i8$4.MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { kind: "component", type: i8.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "directive", type: i9.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly"], exportAs: ["matInput"] }, { kind: "component", type: i5.MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "component", type: i9$1.MatSelect, selector: "mat-select", inputs: ["aria-describedby", "panelClass", "disabled", "disableRipple", "tabIndex", "hideSingleSelectionIndicator", "placeholder", "required", "multiple", "disableOptionCentering", "compareWith", "value", "aria-label", "aria-labelledby", "errorStateMatcher", "typeaheadDebounceInterval", "sortComparator", "id", "panelWidth"], outputs: ["openedChange", "opened", "closed", "selectionChange", "valueChange"], exportAs: ["matSelect"] }, { kind: "component", type: SearchableSelectorComponent, selector: "app-searchable-selector", inputs: ["valueField", "titleField", "subtitleField", "apiUrl", "multiple", "selectedValue", "enableSearch", "add", "addConfig", "edit", "editConfig", "sort", "sortBy", "searchField", "itemComponent", "items", "apiDataProperty", "cache", "perPage", "inDataSearch", "panelWidth", "focusSearchOnOpen", "isEmitInitialEvent", "required", "disabled", "value"], outputs: ["selectedValueChange", "selectionChange", "itemsChange", "isItemsEmpty"] }, { kind: "component", type: TimelineFilterComponent, selector: "app-timeline-filter", inputs: ["defaultValue", "required", "disabled", "value", "timelines", "dateFrom", "dateTo", "appearance", "showClearButton", "form", "labelText"], outputs: ["selectionChange"] }] }); }
7610
7621
  };
7611
7622
  AuditLogListFilterComponent = __decorate([
7612
7623
  UntilDestroy()
@@ -8360,7 +8371,7 @@ class FieldMappingComponent {
8360
8371
  this.onReUpload.emit(true);
8361
8372
  }
8362
8373
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: FieldMappingComponent, deps: [{ token: i1$5.UntypedFormBuilder }, { token: FormValidatorService }, { token: i0.ChangeDetectorRef }, { token: i3.Location }], target: i0.ɵɵFactoryTarget.Component }); }
8363
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.14", type: FieldMappingComponent, selector: "app-field-mapping", inputs: { data: "data", config: "config" }, outputs: { onSave: "onSave", onReUpload: "onReUpload" }, ngImport: i0, template: "<div class=\"d-flex flex-column mt-2\">\n <div class=\"d-flex flex-row flex-wrap pb-3\">\n <h5 style=\"flex: 0 0 30%;\" class=\"primary-color\">Summary</h5>\n <div style=\"flex: 0 0 70%;\" class=\"d-flex align-items-center\">\n <h5 class=\"secondary-color mb-0\">\n <span class=\"font-weight-bold\">{{data.length}} &nbsp;</span>\n </h5>\n <span class=\"text-muted ml-2\"> Records Found In Uploaded File</span>\n </div>\n </div>\n\n <div>\n <mat-divider></mat-divider>\n </div>\n\n <form [formGroup]=\"importMappingForm\" (ngSubmit)=\"next()\" class=\"d-flex flex-column pt-3\">\n <h5 class=\"primary-color pb-2\">Properties</h5>\n <table style=\"width: 100%;\" class=\"table table-sm table-striped\">\n <tr class=\"table-header-row\">\n <th>Column Headers From File</th>\n <th>Preview Information</th>\n <th>Property</th>\n </tr>\n <ng-container formArrayName=\"fields\">\n <tr *ngFor=\"let field of fieldsArray.controls; let i = index\" [formGroupName]=\"i\">\n <td>{{ field.get('label').value }}</td>\n <td>{{ field.get('value').value }}</td>\n <td>\n <div class=\"d-flex align-items-center\">\n <mat-form-field class=\"flex-grow-1\" appearance=\"outline\">\n <mat-label>Select Property</mat-label>\n <mat-select placeholder=\"Select Property\" formControlName=\"property\" required\n (selectionChange)=\"updatePropertyType($event, i)\">\n <mat-option *ngFor=\"let property of properties\" [value]=\"property.value\">\n {{property.label}}\n </mat-option>\n </mat-select>\n <mat-error *ngIf=\"isFieldValid('property', fieldsArray.controls[i])\">\n {{getErrorMessage('property', fieldsArray.controls[i])}}\n </mat-error>\n </mat-form-field>\n\n <mat-icon role=\"button\" class=\"ms-3 text-danger\" type=\"button\" mat-icon-button (click)=\"removeField(i)\"\n *ngIf=\"fieldsArray.length > 1\" matTooltip=\"Remove column\" matTooltipPosition=\"right\"\n style=\"margin-bottom: 1.25em;\">remove_circle</mat-icon>\n </div>\n </td>\n </tr>\n </ng-container>\n </table>\n\n <div class=\"mt-1 d-flex flex-row gap-2 justify-content-end align-items-center\">\n <button mat-button class=\"mt-2 mr-2\" type=\"button\" (click)=\"location.back()\">\n Cancel\n </button>\n <button mat-stroked-button class=\"mt-2 mr-2 primary-color\" type=\"button\" (click)=\"reUpload()\">\n <mat-icon>\n <span class=\"material-icons-outlined\">\n file_upload\n </span>\n </mat-icon>\n Re-upload\n </button>\n <button mat-stroked-button class=\"mt-2 primary-bg\" type=\"submit\">\n Next\n <mat-icon>\n chevron_right\n </mat-icon>\n </button>\n </div>\n </form>\n</div>", styles: ["table{width:100%}th,td{padding:1%}.table-header-row{background-color:#e6e4e4;color:#000;font-weight:bolder}\n"], dependencies: [{ kind: "directive", type: i3.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1$5.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1$5.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$5.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1$5.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i1$5.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$5.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "directive", type: i1$5.FormGroupName, selector: "[formGroupName]", inputs: ["formGroupName"] }, { kind: "directive", type: i1$5.FormArrayName, selector: "[formArrayName]", inputs: ["formArrayName"] }, { kind: "component", type: i6.MatButton, selector: " button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ", exportAs: ["matButton"] }, { kind: "component", type: i8$4.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i8$4.MatLabel, selector: "mat-label" }, { kind: "directive", type: i8$4.MatError, selector: "mat-error, [matError]", inputs: ["id"] }, { kind: "component", type: i8.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: i5.MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "component", type: i9$2.MatSelect, selector: "mat-select", inputs: ["aria-describedby", "panelClass", "disabled", "disableRipple", "tabIndex", "hideSingleSelectionIndicator", "placeholder", "required", "multiple", "disableOptionCentering", "compareWith", "value", "aria-label", "aria-labelledby", "errorStateMatcher", "typeaheadDebounceInterval", "sortComparator", "id", "panelWidth"], outputs: ["openedChange", "opened", "closed", "selectionChange", "valueChange"], exportAs: ["matSelect"] }, { kind: "component", type: i6$3.MatDivider, selector: "mat-divider", inputs: ["vertical", "inset"] }, { kind: "directive", type: i10.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }] }); }
8374
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.14", type: FieldMappingComponent, selector: "app-field-mapping", inputs: { data: "data", config: "config" }, outputs: { onSave: "onSave", onReUpload: "onReUpload" }, ngImport: i0, template: "<div class=\"d-flex flex-column mt-2\">\n <div class=\"d-flex flex-row flex-wrap pb-3\">\n <h5 style=\"flex: 0 0 30%;\" class=\"primary-color\">Summary</h5>\n <div style=\"flex: 0 0 70%;\" class=\"d-flex align-items-center\">\n <h5 class=\"secondary-color mb-0\">\n <span class=\"font-weight-bold\">{{data.length}} &nbsp;</span>\n </h5>\n <span class=\"text-muted ml-2\"> Records Found In Uploaded File</span>\n </div>\n </div>\n\n <div>\n <mat-divider></mat-divider>\n </div>\n\n <form [formGroup]=\"importMappingForm\" (ngSubmit)=\"next()\" class=\"d-flex flex-column pt-3\">\n <h5 class=\"primary-color pb-2\">Properties</h5>\n <table style=\"width: 100%;\" class=\"table table-sm table-striped\">\n <tr class=\"table-header-row\">\n <th>Column Headers From File</th>\n <th>Preview Information</th>\n <th>Property</th>\n </tr>\n <ng-container formArrayName=\"fields\">\n <tr *ngFor=\"let field of fieldsArray.controls; let i = index\" [formGroupName]=\"i\">\n <td>{{ field.get('label').value }}</td>\n <td>{{ field.get('value').value }}</td>\n <td>\n <div class=\"d-flex align-items-center\">\n <mat-form-field class=\"flex-grow-1\" appearance=\"outline\">\n <mat-label>Select Property</mat-label>\n <mat-select placeholder=\"Select Property\" formControlName=\"property\" required\n (selectionChange)=\"updatePropertyType($event, i)\">\n <mat-option *ngFor=\"let property of properties\" [value]=\"property.value\">\n {{property.label}}\n </mat-option>\n </mat-select>\n <mat-error *ngIf=\"isFieldValid('property', fieldsArray.controls[i])\">\n {{getErrorMessage('property', fieldsArray.controls[i])}}\n </mat-error>\n </mat-form-field>\n\n <mat-icon role=\"button\" class=\"ms-3 text-danger\" type=\"button\" mat-icon-button (click)=\"removeField(i)\"\n *ngIf=\"fieldsArray.length > 1\" matTooltip=\"Remove column\" matTooltipPosition=\"right\"\n style=\"margin-bottom: 1.25em;\">remove_circle</mat-icon>\n </div>\n </td>\n </tr>\n </ng-container>\n </table>\n\n <div class=\"mt-1 d-flex flex-row gap-2 justify-content-end align-items-center\">\n <button mat-button class=\"mt-2 mr-2\" type=\"button\" (click)=\"location.back()\">\n Cancel\n </button>\n <button mat-stroked-button class=\"mt-2 mr-2 primary-color\" type=\"button\" (click)=\"reUpload()\">\n <mat-icon>\n <span class=\"material-icons-outlined\">\n file_upload\n </span>\n </mat-icon>\n Re-upload\n </button>\n <button mat-stroked-button class=\"mt-2 primary-bg\" type=\"submit\">\n Next\n <mat-icon>\n chevron_right\n </mat-icon>\n </button>\n </div>\n </form>\n</div>", styles: ["table{width:100%}th,td{padding:1%}.table-header-row{background-color:#e6e4e4;color:#000;font-weight:bolder}\n"], dependencies: [{ kind: "directive", type: i3.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1$5.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1$5.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$5.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1$5.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i1$5.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$5.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "directive", type: i1$5.FormGroupName, selector: "[formGroupName]", inputs: ["formGroupName"] }, { kind: "directive", type: i1$5.FormArrayName, selector: "[formArrayName]", inputs: ["formArrayName"] }, { kind: "component", type: i6.MatButton, selector: " button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ", exportAs: ["matButton"] }, { kind: "component", type: i8$4.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i8$4.MatLabel, selector: "mat-label" }, { kind: "directive", type: i8$4.MatError, selector: "mat-error, [matError]", inputs: ["id"] }, { kind: "component", type: i8.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: i5.MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "component", type: i9$1.MatSelect, selector: "mat-select", inputs: ["aria-describedby", "panelClass", "disabled", "disableRipple", "tabIndex", "hideSingleSelectionIndicator", "placeholder", "required", "multiple", "disableOptionCentering", "compareWith", "value", "aria-label", "aria-labelledby", "errorStateMatcher", "typeaheadDebounceInterval", "sortComparator", "id", "panelWidth"], outputs: ["openedChange", "opened", "closed", "selectionChange", "valueChange"], exportAs: ["matSelect"] }, { kind: "component", type: i6$3.MatDivider, selector: "mat-divider", inputs: ["vertical", "inset"] }, { kind: "directive", type: i10.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }] }); }
8364
8375
  }
8365
8376
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: FieldMappingComponent, decorators: [{
8366
8377
  type: Component,
@@ -9498,6 +9509,9 @@ class UserFormComponent {
9498
9509
  get roleForms() {
9499
9510
  return this.userForm.get('roles');
9500
9511
  }
9512
+ get canUpdateUserCredential() {
9513
+ return (this.user?.user_clients || [])?.length <= 1;
9514
+ }
9501
9515
  ngOnInit() {
9502
9516
  this.userTypes = this.config.userConfig.showUserTypes
9503
9517
  ? this.config.userConfig.userTypes
@@ -9542,6 +9556,10 @@ class UserFormComponent {
9542
9556
  width: '100%'
9543
9557
  }
9544
9558
  };
9559
+ if (!this.canUpdateUserCredential) {
9560
+ this.userForm.get('email').disable();
9561
+ this.userForm.get('password').disable();
9562
+ }
9545
9563
  }
9546
9564
  loadRoles() {
9547
9565
  this.isWorking = true;
@@ -9639,7 +9657,7 @@ class UserFormComponent {
9639
9657
  .post('api/entity-files-upload', formData).toPromise();
9640
9658
  }
9641
9659
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: UserFormComponent, deps: [{ token: i1.MatDialogRef }, { token: MAT_DIALOG_DATA }, { token: HttpService }, { token: AlertService }, { token: ErrorHandlerService }, { token: i1$5.UntypedFormBuilder }, { token: FormValidatorService }, { token: UserService }, { token: UserConfigService }], target: i0.ɵɵFactoryTarget.Component }); }
9642
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.14", type: UserFormComponent, selector: "user-form", inputs: { userId: "userId" }, outputs: { onSave: "onSave" }, ngImport: i0, template: "<form [formGroup]=\"userForm\" (ngSubmit)=\"save()\">\n <div class=\"d-flex flex-column justify-content-start align-items center gap-1\" mat-dialog-content>\n <h5 class=\"fw-bold text-center\">{{ updateMode ? 'Edit' : 'Create ' }} User</h5>\n <div fxLayout>\n <div fxLayout=\"column\" fxFlex fxLayoutGap=\"0.25rem\">\n <mat-form-field>\n <mat-label>Full name</mat-label>\n <input [required]=\"!!userForm.get('name').validator\" autocomplete=\"off\" formControlName=\"name\" matInput\n placeholder=\"Full Name\" type=\"text\" />\n <mat-error *ngIf=\"isFieldValid('name') && !!userForm.get('name').validator\">{{ getErrorMessage('name') }}\n </mat-error>\n </mat-form-field>\n <mat-form-field>\n <mat-label>Email</mat-label>\n <input [required]=\"!!userForm.get('email').validator\" formControlName=\"email\" matInput placeholder=\"Email\"\n type=\"email\" />\n <mat-error *ngIf=\"isFieldValid('email') && !!userForm.get('email').validator\">\n {{ getErrorMessage('email') }}\n </mat-error>\n </mat-form-field>\n <mat-form-field *ngIf=\"this.config.userConfig.showPhone\">\n <mat-label>Phone</mat-label>\n <input autocomplete=\"off\" formControlName=\"phone\" matInput placeholder=\"Phone\" type=\"text\" />\n </mat-form-field>\n <mat-form-field>\n <mat-label>Password</mat-label>\n <input [required]=\"isPasswordRequired && !!userForm.get('password').validator\" autocomplete=\"off\"\n formControlName=\"password\" matInput placeholder=\"Password\" type=\"password\" />\n <mat-error *ngIf=\"isFieldValid('password') && !!userForm.get('password').validator\">\n {{ getErrorMessage('password') }}\n </mat-error>\n </mat-form-field>\n\n <div class=\"d-flex flex-column justify-content-start gap-1\">\n <mat-checkbox formControlName=\"is_temporary_password\">Is Temporary Password?</mat-checkbox>\n <small class=\"text-secondary\">Should this user to update password on first login?</small>\n </div>\n\n <div *ngIf=\"this.config.userConfig.showSignature\">\n <ng-template #fileUpload>\n <section class=\"col-12\">\n <div>User Signature</div>\n <app-file-dropper (fileChanged)=\"fileChanged($event)\" [config]=\"fileConfig\" [fileArray]=\"fileList\">\n </app-file-dropper>\n </section>\n </ng-template>\n <div *ngIf=\"userForm.get('signature').value;else fileUpload;\" class=\"col-12\">\n <app-document-viewer (remove)=\"removeFile()\" [config]=\"this.viewerConfig\"\n [fileUrl]=\"userForm.get('signature_url').value\" [file]=\"userForm.get('signature').value\">\n </app-document-viewer>\n </div>\n </div>\n <mat-form-field *ngIf=\"this.config.userConfig.showUserTypes\">\n <mat-label>User Type</mat-label>\n <mat-select autocomplete=\"off\" formControlName=\"user_type_id\" required>\n <mat-option *ngFor=\"let userType of userTypes\" [value]=\"userType.value\">\n {{ userType.title }}\n </mat-option>\n </mat-select>\n <mat-error *ngIf=\"isFieldValid('user_type_id')\">{{ getErrorMessage('user_type_id') }}</mat-error>\n </mat-form-field>\n </div>\n\n <div\n *ngIf=\"(this.config.userConfig.showRoles || this.config.userConfig.showFormRoles) && this.userForm.get('user_type_id').value == 3\"\n fxFlex class=\"ml-4\">\n <p class=\"mb-0 fw-bold\">\n Roles\n </p>\n <div *ngFor=\"let role of roles\" fxLayout=\"column\">\n <mat-checkbox (change)=\"roleSelected($event, role.id)\" [checked]=\"role.selected\">\n {{ role.label }}\n </mat-checkbox>\n </div>\n </div>\n\n </div>\n <div class=\"d-flex justify-content-end align-items-center gap-3\">\n <button [disabled]=\"isWorking\" color=\"primary\" mat-raised-button type=\"submit\">\n Save\n </button>\n <button (click)=\"closeDialog()\" [disabled]=\"isWorking\" mat-flat-button type=\"button\">\n Cancel\n </button>\n </div>\n </div>\n</form>", dependencies: [{ kind: "directive", type: i3.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: i6.MatButton, selector: " button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ", exportAs: ["matButton"] }, { kind: "component", type: i8$1.MatCheckbox, selector: "mat-checkbox", inputs: ["aria-label", "aria-labelledby", "aria-describedby", "id", "required", "labelPosition", "name", "value", "disableRipple", "tabIndex", "color", "disabledInteractive", "checked", "disabled", "indeterminate"], outputs: ["change", "indeterminateChange"], exportAs: ["matCheckbox"] }, { kind: "directive", type: i1.MatDialogContent, selector: "[mat-dialog-content], mat-dialog-content, [matDialogContent]" }, { kind: "component", type: i8$4.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i8$4.MatLabel, selector: "mat-label" }, { kind: "directive", type: i8$4.MatError, selector: "mat-error, [matError]", inputs: ["id"] }, { kind: "directive", type: i9.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly"], exportAs: ["matInput"] }, { kind: "component", type: i5.MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "component", type: i9$2.MatSelect, selector: "mat-select", inputs: ["aria-describedby", "panelClass", "disabled", "disableRipple", "tabIndex", "hideSingleSelectionIndicator", "placeholder", "required", "multiple", "disableOptionCentering", "compareWith", "value", "aria-label", "aria-labelledby", "errorStateMatcher", "typeaheadDebounceInterval", "sortComparator", "id", "panelWidth"], outputs: ["openedChange", "opened", "closed", "selectionChange", "valueChange"], exportAs: ["matSelect"] }, { kind: "directive", type: i6$1.DefaultLayoutDirective, selector: " [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]", inputs: ["fxLayout", "fxLayout.xs", "fxLayout.sm", "fxLayout.md", "fxLayout.lg", "fxLayout.xl", "fxLayout.lt-sm", "fxLayout.lt-md", "fxLayout.lt-lg", "fxLayout.lt-xl", "fxLayout.gt-xs", "fxLayout.gt-sm", "fxLayout.gt-md", "fxLayout.gt-lg"] }, { kind: "directive", type: i6$1.DefaultLayoutGapDirective, selector: " [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]", inputs: ["fxLayoutGap", "fxLayoutGap.xs", "fxLayoutGap.sm", "fxLayoutGap.md", "fxLayoutGap.lg", "fxLayoutGap.xl", "fxLayoutGap.lt-sm", "fxLayoutGap.lt-md", "fxLayoutGap.lt-lg", "fxLayoutGap.lt-xl", "fxLayoutGap.gt-xs", "fxLayoutGap.gt-sm", "fxLayoutGap.gt-md", "fxLayoutGap.gt-lg"] }, { kind: "directive", type: i6$1.DefaultFlexDirective, selector: " [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]", inputs: ["fxFlex", "fxFlex.xs", "fxFlex.sm", "fxFlex.md", "fxFlex.lg", "fxFlex.xl", "fxFlex.lt-sm", "fxFlex.lt-md", "fxFlex.lt-lg", "fxFlex.lt-xl", "fxFlex.gt-xs", "fxFlex.gt-sm", "fxFlex.gt-md", "fxFlex.gt-lg"] }, { kind: "directive", type: i1$5.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1$5.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$5.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$5.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1$5.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i1$5.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$5.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "component", type: FileDropperComponent, selector: "app-file-dropper", inputs: ["fileArray", "config", "styles"], outputs: ["fileChanged"] }, { kind: "component", type: DocumentViewerComponent, selector: "app-document-viewer", inputs: ["config", "file", "fileUrl", "disableEdit"], outputs: ["remove"] }] }); }
9660
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.14", type: UserFormComponent, selector: "user-form", inputs: { userId: "userId" }, outputs: { onSave: "onSave" }, ngImport: i0, template: "<form [formGroup]=\"userForm\" (ngSubmit)=\"save()\">\n <div class=\"d-flex flex-column justify-content-start align-items center gap-1\" mat-dialog-content>\n <h5 class=\"fw-bold text-center\">{{ updateMode ? 'Edit' : 'Create ' }} User</h5>\n <div fxLayout>\n <div fxLayout=\"column\" fxFlex fxLayoutGap=\"0.25rem\">\n <mat-form-field>\n <mat-label>Full name</mat-label>\n <input [required]=\"!!userForm.get('name').validator\" autocomplete=\"off\" formControlName=\"name\" matInput\n placeholder=\"Full Name\" type=\"text\" />\n <mat-error *ngIf=\"isFieldValid('name') && !!userForm.get('name').validator\">{{ getErrorMessage('name') }}\n </mat-error>\n </mat-form-field>\n <mat-form-field>\n <mat-label>Email</mat-label>\n <input [required]=\"!!userForm.get('email').validator\" formControlName=\"email\" matInput placeholder=\"Email\"\n type=\"email\" />\n <mat-error *ngIf=\"isFieldValid('email') && !!userForm.get('email').validator\">\n {{ getErrorMessage('email') }}\n </mat-error>\n </mat-form-field>\n <mat-form-field *ngIf=\"this.config.userConfig.showPhone\">\n <mat-label>Phone</mat-label>\n <input autocomplete=\"off\" formControlName=\"phone\" matInput placeholder=\"Phone\" type=\"text\" />\n </mat-form-field>\n <mat-form-field>\n <mat-label>Password</mat-label>\n <input [required]=\"isPasswordRequired && !!userForm.get('password').validator\" autocomplete=\"off\"\n formControlName=\"password\" matInput placeholder=\"Password\" type=\"password\" />\n <mat-error *ngIf=\"isFieldValid('password') && !!userForm.get('password').validator\">\n {{ getErrorMessage('password') }}\n </mat-error>\n </mat-form-field>\n\n <div class=\"d-flex flex-column justify-content-start gap-1\">\n <mat-checkbox formControlName=\"is_temporary_password\">Is Temporary Password?</mat-checkbox>\n <small class=\"text-secondary\">Should this user to update password on first login?</small>\n </div>\n\n <div *ngIf=\"this.config.userConfig.showSignature\">\n <ng-template #fileUpload>\n <section class=\"col-12\">\n <div>User Signature</div>\n <app-file-dropper (fileChanged)=\"fileChanged($event)\" [config]=\"fileConfig\" [fileArray]=\"fileList\">\n </app-file-dropper>\n </section>\n </ng-template>\n <div *ngIf=\"userForm.get('signature').value;else fileUpload;\" class=\"col-12\">\n <app-document-viewer (remove)=\"removeFile()\" [config]=\"this.viewerConfig\"\n [fileUrl]=\"userForm.get('signature_url').value\" [file]=\"userForm.get('signature').value\">\n </app-document-viewer>\n </div>\n </div>\n <mat-form-field *ngIf=\"this.config.userConfig.showUserTypes\">\n <mat-label>User Type</mat-label>\n <mat-select autocomplete=\"off\" formControlName=\"user_type_id\" required>\n <mat-option *ngFor=\"let userType of userTypes\" [value]=\"userType.value\">\n {{ userType.title }}\n </mat-option>\n </mat-select>\n <mat-error *ngIf=\"isFieldValid('user_type_id')\">{{ getErrorMessage('user_type_id') }}</mat-error>\n </mat-form-field>\n </div>\n\n <div\n *ngIf=\"(this.config.userConfig.showRoles || this.config.userConfig.showFormRoles) && this.userForm.get('user_type_id').value == 3\"\n fxFlex class=\"ml-4\">\n <p class=\"mb-0 fw-bold\">\n Roles\n </p>\n <div *ngFor=\"let role of roles\" fxLayout=\"column\">\n <mat-checkbox (change)=\"roleSelected($event, role.id)\" [checked]=\"role.selected\">\n {{ role.label }}\n </mat-checkbox>\n </div>\n </div>\n\n </div>\n <div class=\"d-flex justify-content-end align-items-center gap-3\">\n <button [disabled]=\"isWorking\" color=\"primary\" mat-raised-button type=\"submit\">\n Save\n </button>\n <button (click)=\"closeDialog()\" [disabled]=\"isWorking\" mat-flat-button type=\"button\">\n Cancel\n </button>\n </div>\n </div>\n</form>", dependencies: [{ kind: "directive", type: i3.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: i6.MatButton, selector: " button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ", exportAs: ["matButton"] }, { kind: "component", type: i8$1.MatCheckbox, selector: "mat-checkbox", inputs: ["aria-label", "aria-labelledby", "aria-describedby", "id", "required", "labelPosition", "name", "value", "disableRipple", "tabIndex", "color", "disabledInteractive", "checked", "disabled", "indeterminate"], outputs: ["change", "indeterminateChange"], exportAs: ["matCheckbox"] }, { kind: "directive", type: i1.MatDialogContent, selector: "[mat-dialog-content], mat-dialog-content, [matDialogContent]" }, { kind: "component", type: i8$4.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i8$4.MatLabel, selector: "mat-label" }, { kind: "directive", type: i8$4.MatError, selector: "mat-error, [matError]", inputs: ["id"] }, { kind: "directive", type: i9.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly"], exportAs: ["matInput"] }, { kind: "component", type: i5.MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "component", type: i9$1.MatSelect, selector: "mat-select", inputs: ["aria-describedby", "panelClass", "disabled", "disableRipple", "tabIndex", "hideSingleSelectionIndicator", "placeholder", "required", "multiple", "disableOptionCentering", "compareWith", "value", "aria-label", "aria-labelledby", "errorStateMatcher", "typeaheadDebounceInterval", "sortComparator", "id", "panelWidth"], outputs: ["openedChange", "opened", "closed", "selectionChange", "valueChange"], exportAs: ["matSelect"] }, { kind: "directive", type: i6$1.DefaultLayoutDirective, selector: " [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]", inputs: ["fxLayout", "fxLayout.xs", "fxLayout.sm", "fxLayout.md", "fxLayout.lg", "fxLayout.xl", "fxLayout.lt-sm", "fxLayout.lt-md", "fxLayout.lt-lg", "fxLayout.lt-xl", "fxLayout.gt-xs", "fxLayout.gt-sm", "fxLayout.gt-md", "fxLayout.gt-lg"] }, { kind: "directive", type: i6$1.DefaultLayoutGapDirective, selector: " [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]", inputs: ["fxLayoutGap", "fxLayoutGap.xs", "fxLayoutGap.sm", "fxLayoutGap.md", "fxLayoutGap.lg", "fxLayoutGap.xl", "fxLayoutGap.lt-sm", "fxLayoutGap.lt-md", "fxLayoutGap.lt-lg", "fxLayoutGap.lt-xl", "fxLayoutGap.gt-xs", "fxLayoutGap.gt-sm", "fxLayoutGap.gt-md", "fxLayoutGap.gt-lg"] }, { kind: "directive", type: i6$1.DefaultFlexDirective, selector: " [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]", inputs: ["fxFlex", "fxFlex.xs", "fxFlex.sm", "fxFlex.md", "fxFlex.lg", "fxFlex.xl", "fxFlex.lt-sm", "fxFlex.lt-md", "fxFlex.lt-lg", "fxFlex.lt-xl", "fxFlex.gt-xs", "fxFlex.gt-sm", "fxFlex.gt-md", "fxFlex.gt-lg"] }, { kind: "directive", type: i1$5.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1$5.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$5.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$5.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1$5.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i1$5.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$5.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "component", type: FileDropperComponent, selector: "app-file-dropper", inputs: ["fileArray", "config", "styles"], outputs: ["fileChanged"] }, { kind: "component", type: DocumentViewerComponent, selector: "app-document-viewer", inputs: ["config", "file", "fileUrl", "disableEdit"], outputs: ["remove"] }] }); }
9643
9661
  }
9644
9662
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: UserFormComponent, decorators: [{
9645
9663
  type: Component,
@@ -11235,11 +11253,11 @@ class PermissionsManagementComponent {
11235
11253
  }
11236
11254
  }
11237
11255
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: PermissionsManagementComponent, deps: [{ token: HttpService }, { token: AlertService }, { token: i1$2.ActivatedRoute }, { token: CredentialsService }, { token: ErrorHandlerService }, { token: UserConfigService }, { token: i1$5.FormBuilder }], target: i0.ɵɵFactoryTarget.Component }); }
11238
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.14", type: PermissionsManagementComponent, selector: "role-permissions-management", inputs: { clientId: "clientId" }, ngImport: i0, template: "<div class=\"d-flex flex-column justify-content-start m-2\">\n <mat-card>\n <mat-card-content class=\"d-flex justify-content-between align-items-center gap-2\">\n <div class=\"d-flex justify-content-start align-items-center gap-2\">\n <h5 class=\"m-0 fw-bold\">\n Manage Role Permissions\n </h5>\n <button *ngIf=\"!config.permissionConfig.disableUsers\" [routerLink]=\"['../users']\" class=\"ml-1\"\n mat-raised-button>\n <i class=\"icon fas fa-users\"></i> Users\n </button>\n <button *ngIf=\"!config.permissionConfig.disableRoles\" [routerLink]=\"['../roles']\" class=\"ml-1\"\n mat-raised-button>\n <i class=\"fas fa-user-md\"></i> Manage Roles\n </button>\n </div>\n <form [formGroup]=\"filterForm\" class=\"d-flex justify-content-end align-items-center gap-2\">\n <mat-form-field appearance=\"outline\">\n <mat-label>Search</mat-label>\n <input autocomplete=\"off\" formControlName=\"search\" matInput placeholder=\"Search Permissions\" type=\"text\" />\n <button (click)=\"filterForm.get('search').setValue('')\" *ngIf=\"filterForm.get('search').value\" mat-icon-button\n matSuffix type=\"button\">\n <mat-icon>clear</mat-icon>\n </button>\n </mat-form-field>\n\n <mat-form-field *ngIf=\"roles\" appearance=\"outline\" class=\"ml-2\">\n <mat-label>Show Roles</mat-label>\n <mat-select formControlName='role_ids' multiple>\n <mat-option *ngFor=\"let role of roles\" [value]=\"role?.id\">\n {{ role.label }}\n </mat-option>\n </mat-select>\n </mat-form-field>\n </form>\n </mat-card-content>\n </mat-card>\n\n <mat-card class=\"mt-2 p-0\">\n <form>\n <table aria-describedby=\"Role Permissions\" class=\"table table-sm table-bordered table-condensed table-striped\">\n <thead>\n <tr>\n <th>Permissions</th>\n <ng-container *ngFor=\"let role of roles\">\n <th *ngIf=\"filterForm.get('role_ids').value.includes(role.id)\" class=\"text-center\">\n {{ role.label }}\n </th>\n </ng-container>\n </tr>\n </thead>\n <tbody>\n <tr *ngFor=\"let permission of filteredPermissions\">\n <td>\n {{ permission.label }}\n </td>\n <ng-container *ngFor=\"let role of roles\">\n <td *ngIf=\"filterForm.get('role_ids').value.includes(role.id)\" class=\"text-center align-middle\">\n <div class=\"d-flex justify-content-center align-items-center h-100\">\n <input (change)=\"updateRolePermission(role, permission)\"\n [checked]=\"role.hasPermission(permission.slug)\" name=\"{{role.id}}[{{permission?.label}}]\"\n type=\"checkbox\" />\n </div>\n </td>\n </ng-container>\n </tr>\n </tbody>\n </table>\n </form>\n </mat-card>\n</div>", dependencies: [{ kind: "directive", type: i3.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1$2.RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "routerLink"] }, { kind: "component", type: i6.MatButton, selector: " button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ", exportAs: ["matButton"] }, { kind: "component", type: i6.MatIconButton, selector: "button[mat-icon-button]", exportAs: ["matButton"] }, { kind: "component", type: i8$4.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i8$4.MatLabel, selector: "mat-label" }, { kind: "directive", type: i8$4.MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { kind: "component", type: i8.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "directive", type: i9.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly"], exportAs: ["matInput"] }, { kind: "component", type: i5.MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "component", type: i9$2.MatSelect, selector: "mat-select", inputs: ["aria-describedby", "panelClass", "disabled", "disableRipple", "tabIndex", "hideSingleSelectionIndicator", "placeholder", "required", "multiple", "disableOptionCentering", "compareWith", "value", "aria-label", "aria-labelledby", "errorStateMatcher", "typeaheadDebounceInterval", "sortComparator", "id", "panelWidth"], outputs: ["openedChange", "opened", "closed", "selectionChange", "valueChange"], exportAs: ["matSelect"] }, { kind: "component", type: i4.MatCard, selector: "mat-card", inputs: ["appearance"], exportAs: ["matCard"] }, { kind: "directive", type: i4.MatCardContent, selector: "mat-card-content" }, { kind: "directive", type: i1$5.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1$5.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$5.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$5.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1$5.NgForm, selector: "form:not([ngNoForm]):not([formGroup]),ng-form,[ngForm]", inputs: ["ngFormOptions"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$5.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$5.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }] }); }
11256
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.14", type: PermissionsManagementComponent, selector: "role-permissions-management", inputs: { clientId: "clientId" }, ngImport: i0, template: "<div class=\"d-flex flex-column justify-content-start m-2\">\n <mat-card>\n <mat-card-content class=\"d-flex justify-content-between align-items-center gap-2\">\n <div class=\"d-flex justify-content-start align-items-center gap-2\">\n <h5 class=\"m-0 fw-bold\">\n Manage Role Permissions\n </h5>\n <button *ngIf=\"!config.permissionConfig.disableUsers\" [routerLink]=\"['../users']\" class=\"ml-1\"\n mat-raised-button>\n <i class=\"icon fas fa-users\"></i> Users\n </button>\n <button *ngIf=\"!config.permissionConfig.disableRoles\" [routerLink]=\"['../roles']\" class=\"ml-1\"\n mat-raised-button>\n <i class=\"fas fa-user-md\"></i> Manage Roles\n </button>\n </div>\n <form [formGroup]=\"filterForm\" class=\"d-flex justify-content-end align-items-center gap-2\">\n <mat-form-field appearance=\"outline\">\n <mat-label>Search</mat-label>\n <input autocomplete=\"off\" formControlName=\"search\" matInput placeholder=\"Search Permissions\" type=\"text\" />\n <button (click)=\"filterForm.get('search').setValue('')\" *ngIf=\"filterForm.get('search').value\" mat-icon-button\n matSuffix type=\"button\">\n <mat-icon>clear</mat-icon>\n </button>\n </mat-form-field>\n\n <mat-form-field *ngIf=\"roles\" appearance=\"outline\" class=\"ml-2\">\n <mat-label>Show Roles</mat-label>\n <mat-select formControlName='role_ids' multiple>\n <mat-option *ngFor=\"let role of roles\" [value]=\"role?.id\">\n {{ role.label }}\n </mat-option>\n </mat-select>\n </mat-form-field>\n </form>\n </mat-card-content>\n </mat-card>\n\n <mat-card class=\"mt-2 p-0\">\n <form>\n <table aria-describedby=\"Role Permissions\" class=\"table table-sm table-bordered table-condensed table-striped\">\n <thead>\n <tr>\n <th>Permissions</th>\n <ng-container *ngFor=\"let role of roles\">\n <th *ngIf=\"filterForm.get('role_ids').value.includes(role.id)\" class=\"text-center\">\n {{ role.label }}\n </th>\n </ng-container>\n </tr>\n </thead>\n <tbody>\n <tr *ngFor=\"let permission of filteredPermissions\">\n <td>\n {{ permission.label }}\n </td>\n <ng-container *ngFor=\"let role of roles\">\n <td *ngIf=\"filterForm.get('role_ids').value.includes(role.id)\" class=\"text-center align-middle\">\n <div class=\"d-flex justify-content-center align-items-center h-100\">\n <input (change)=\"updateRolePermission(role, permission)\"\n [checked]=\"role.hasPermission(permission.slug)\" name=\"{{role.id}}[{{permission?.label}}]\"\n type=\"checkbox\" [disabled]=\"role?.client_id == null\" />\n </div>\n </td>\n </ng-container>\n </tr>\n </tbody>\n </table>\n </form>\n </mat-card>\n</div>", styles: ["input[type=checkbox]{color-scheme:light}\n"], dependencies: [{ kind: "directive", type: i3.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1$2.RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "routerLink"] }, { kind: "component", type: i6.MatButton, selector: " button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ", exportAs: ["matButton"] }, { kind: "component", type: i6.MatIconButton, selector: "button[mat-icon-button]", exportAs: ["matButton"] }, { kind: "component", type: i8$4.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i8$4.MatLabel, selector: "mat-label" }, { kind: "directive", type: i8$4.MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { kind: "component", type: i8.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "directive", type: i9.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly"], exportAs: ["matInput"] }, { kind: "component", type: i5.MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "component", type: i9$1.MatSelect, selector: "mat-select", inputs: ["aria-describedby", "panelClass", "disabled", "disableRipple", "tabIndex", "hideSingleSelectionIndicator", "placeholder", "required", "multiple", "disableOptionCentering", "compareWith", "value", "aria-label", "aria-labelledby", "errorStateMatcher", "typeaheadDebounceInterval", "sortComparator", "id", "panelWidth"], outputs: ["openedChange", "opened", "closed", "selectionChange", "valueChange"], exportAs: ["matSelect"] }, { kind: "component", type: i4.MatCard, selector: "mat-card", inputs: ["appearance"], exportAs: ["matCard"] }, { kind: "directive", type: i4.MatCardContent, selector: "mat-card-content" }, { kind: "directive", type: i1$5.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1$5.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$5.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$5.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1$5.NgForm, selector: "form:not([ngNoForm]):not([formGroup]),ng-form,[ngForm]", inputs: ["ngFormOptions"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$5.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$5.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }] }); }
11239
11257
  }
11240
11258
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: PermissionsManagementComponent, decorators: [{
11241
11259
  type: Component,
11242
- args: [{ selector: 'role-permissions-management', template: "<div class=\"d-flex flex-column justify-content-start m-2\">\n <mat-card>\n <mat-card-content class=\"d-flex justify-content-between align-items-center gap-2\">\n <div class=\"d-flex justify-content-start align-items-center gap-2\">\n <h5 class=\"m-0 fw-bold\">\n Manage Role Permissions\n </h5>\n <button *ngIf=\"!config.permissionConfig.disableUsers\" [routerLink]=\"['../users']\" class=\"ml-1\"\n mat-raised-button>\n <i class=\"icon fas fa-users\"></i> Users\n </button>\n <button *ngIf=\"!config.permissionConfig.disableRoles\" [routerLink]=\"['../roles']\" class=\"ml-1\"\n mat-raised-button>\n <i class=\"fas fa-user-md\"></i> Manage Roles\n </button>\n </div>\n <form [formGroup]=\"filterForm\" class=\"d-flex justify-content-end align-items-center gap-2\">\n <mat-form-field appearance=\"outline\">\n <mat-label>Search</mat-label>\n <input autocomplete=\"off\" formControlName=\"search\" matInput placeholder=\"Search Permissions\" type=\"text\" />\n <button (click)=\"filterForm.get('search').setValue('')\" *ngIf=\"filterForm.get('search').value\" mat-icon-button\n matSuffix type=\"button\">\n <mat-icon>clear</mat-icon>\n </button>\n </mat-form-field>\n\n <mat-form-field *ngIf=\"roles\" appearance=\"outline\" class=\"ml-2\">\n <mat-label>Show Roles</mat-label>\n <mat-select formControlName='role_ids' multiple>\n <mat-option *ngFor=\"let role of roles\" [value]=\"role?.id\">\n {{ role.label }}\n </mat-option>\n </mat-select>\n </mat-form-field>\n </form>\n </mat-card-content>\n </mat-card>\n\n <mat-card class=\"mt-2 p-0\">\n <form>\n <table aria-describedby=\"Role Permissions\" class=\"table table-sm table-bordered table-condensed table-striped\">\n <thead>\n <tr>\n <th>Permissions</th>\n <ng-container *ngFor=\"let role of roles\">\n <th *ngIf=\"filterForm.get('role_ids').value.includes(role.id)\" class=\"text-center\">\n {{ role.label }}\n </th>\n </ng-container>\n </tr>\n </thead>\n <tbody>\n <tr *ngFor=\"let permission of filteredPermissions\">\n <td>\n {{ permission.label }}\n </td>\n <ng-container *ngFor=\"let role of roles\">\n <td *ngIf=\"filterForm.get('role_ids').value.includes(role.id)\" class=\"text-center align-middle\">\n <div class=\"d-flex justify-content-center align-items-center h-100\">\n <input (change)=\"updateRolePermission(role, permission)\"\n [checked]=\"role.hasPermission(permission.slug)\" name=\"{{role.id}}[{{permission?.label}}]\"\n type=\"checkbox\" />\n </div>\n </td>\n </ng-container>\n </tr>\n </tbody>\n </table>\n </form>\n </mat-card>\n</div>" }]
11260
+ args: [{ selector: 'role-permissions-management', template: "<div class=\"d-flex flex-column justify-content-start m-2\">\n <mat-card>\n <mat-card-content class=\"d-flex justify-content-between align-items-center gap-2\">\n <div class=\"d-flex justify-content-start align-items-center gap-2\">\n <h5 class=\"m-0 fw-bold\">\n Manage Role Permissions\n </h5>\n <button *ngIf=\"!config.permissionConfig.disableUsers\" [routerLink]=\"['../users']\" class=\"ml-1\"\n mat-raised-button>\n <i class=\"icon fas fa-users\"></i> Users\n </button>\n <button *ngIf=\"!config.permissionConfig.disableRoles\" [routerLink]=\"['../roles']\" class=\"ml-1\"\n mat-raised-button>\n <i class=\"fas fa-user-md\"></i> Manage Roles\n </button>\n </div>\n <form [formGroup]=\"filterForm\" class=\"d-flex justify-content-end align-items-center gap-2\">\n <mat-form-field appearance=\"outline\">\n <mat-label>Search</mat-label>\n <input autocomplete=\"off\" formControlName=\"search\" matInput placeholder=\"Search Permissions\" type=\"text\" />\n <button (click)=\"filterForm.get('search').setValue('')\" *ngIf=\"filterForm.get('search').value\" mat-icon-button\n matSuffix type=\"button\">\n <mat-icon>clear</mat-icon>\n </button>\n </mat-form-field>\n\n <mat-form-field *ngIf=\"roles\" appearance=\"outline\" class=\"ml-2\">\n <mat-label>Show Roles</mat-label>\n <mat-select formControlName='role_ids' multiple>\n <mat-option *ngFor=\"let role of roles\" [value]=\"role?.id\">\n {{ role.label }}\n </mat-option>\n </mat-select>\n </mat-form-field>\n </form>\n </mat-card-content>\n </mat-card>\n\n <mat-card class=\"mt-2 p-0\">\n <form>\n <table aria-describedby=\"Role Permissions\" class=\"table table-sm table-bordered table-condensed table-striped\">\n <thead>\n <tr>\n <th>Permissions</th>\n <ng-container *ngFor=\"let role of roles\">\n <th *ngIf=\"filterForm.get('role_ids').value.includes(role.id)\" class=\"text-center\">\n {{ role.label }}\n </th>\n </ng-container>\n </tr>\n </thead>\n <tbody>\n <tr *ngFor=\"let permission of filteredPermissions\">\n <td>\n {{ permission.label }}\n </td>\n <ng-container *ngFor=\"let role of roles\">\n <td *ngIf=\"filterForm.get('role_ids').value.includes(role.id)\" class=\"text-center align-middle\">\n <div class=\"d-flex justify-content-center align-items-center h-100\">\n <input (change)=\"updateRolePermission(role, permission)\"\n [checked]=\"role.hasPermission(permission.slug)\" name=\"{{role.id}}[{{permission?.label}}]\"\n type=\"checkbox\" [disabled]=\"role?.client_id == null\" />\n </div>\n </td>\n </ng-container>\n </tr>\n </tbody>\n </table>\n </form>\n </mat-card>\n</div>", styles: ["input[type=checkbox]{color-scheme:light}\n"] }]
11243
11261
  }], ctorParameters: () => [{ type: HttpService }, { type: AlertService }, { type: i1$2.ActivatedRoute }, { type: CredentialsService }, { type: ErrorHandlerService }, { type: UserConfigService }, { type: i1$5.FormBuilder }], propDecorators: { clientId: [{
11244
11262
  type: Input
11245
11263
  }] } });
@@ -11431,7 +11449,7 @@ class UserSelectorComponent {
11431
11449
  useExisting: forwardRef(() => UserSelectorComponent),
11432
11450
  multi: true
11433
11451
  }
11434
- ], ngImport: i0, template: "<mat-form-field class=\"col-12 pl-0 pr-0\">\n <mat-label>User</mat-label>\n <mat-select [(ngModel)]=\"value\" (selectionChange)=\"itemSelected()\" [required]=\"isRequired\">\n <mat-option *ngFor=\"let user of items\" [value]=\"user.id\">{{user.name}}</mat-option>\n </mat-select>\n <mat-error>User is required</mat-error>\n</mat-form-field>", dependencies: [{ kind: "directive", type: i3.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1$5.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$5.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i1$5.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: i8$4.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i8$4.MatLabel, selector: "mat-label" }, { kind: "directive", type: i8$4.MatError, selector: "mat-error, [matError]", inputs: ["id"] }, { kind: "component", type: i5.MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "component", type: i9$2.MatSelect, selector: "mat-select", inputs: ["aria-describedby", "panelClass", "disabled", "disableRipple", "tabIndex", "hideSingleSelectionIndicator", "placeholder", "required", "multiple", "disableOptionCentering", "compareWith", "value", "aria-label", "aria-labelledby", "errorStateMatcher", "typeaheadDebounceInterval", "sortComparator", "id", "panelWidth"], outputs: ["openedChange", "opened", "closed", "selectionChange", "valueChange"], exportAs: ["matSelect"] }] }); }
11452
+ ], ngImport: i0, template: "<mat-form-field class=\"col-12 pl-0 pr-0\">\n <mat-label>User</mat-label>\n <mat-select [(ngModel)]=\"value\" (selectionChange)=\"itemSelected()\" [required]=\"isRequired\">\n <mat-option *ngFor=\"let user of items\" [value]=\"user.id\">{{user.name}}</mat-option>\n </mat-select>\n <mat-error>User is required</mat-error>\n</mat-form-field>", dependencies: [{ kind: "directive", type: i3.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1$5.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$5.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i1$5.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: i8$4.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i8$4.MatLabel, selector: "mat-label" }, { kind: "directive", type: i8$4.MatError, selector: "mat-error, [matError]", inputs: ["id"] }, { kind: "component", type: i5.MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "component", type: i9$1.MatSelect, selector: "mat-select", inputs: ["aria-describedby", "panelClass", "disabled", "disableRipple", "tabIndex", "hideSingleSelectionIndicator", "placeholder", "required", "multiple", "disableOptionCentering", "compareWith", "value", "aria-label", "aria-labelledby", "errorStateMatcher", "typeaheadDebounceInterval", "sortComparator", "id", "panelWidth"], outputs: ["openedChange", "opened", "closed", "selectionChange", "valueChange"], exportAs: ["matSelect"] }] }); }
11435
11453
  }
11436
11454
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: UserSelectorComponent, decorators: [{
11437
11455
  type: Component,
@@ -13144,7 +13162,7 @@ class IpRangeSelectorComponent {
13144
13162
  multi: true,
13145
13163
  useExisting: IpRangeSelectorComponent
13146
13164
  }
13147
- ], ngImport: i0, template: "<div fxLayout fxLayoutGap=\"10px\" class=\"w-100\">\n <mat-form-field fxFlex=\"calc(85% - 10px)\">\n <mat-label>{{ label }}</mat-label>\n <input type=\"text\" matInput placeholder=\"IP Range\" [formControl]=\"ipAddressControl\">\n <mat-hint>\n What is the ip address or range that we should block? Format can be either a single IP like\n <code>192.175.32.133</code> OR a range specifying the subnet like <code>192.175.32.0/24</code>\n </mat-hint>\n </mat-form-field>\n <mat-form-field fxFlex=\"calc(15% - 10px)\">\n <mat-select [formControl]=\"subnetControl\">\n <mat-option *ngFor=\"let subnet of subnetOptions\" [value]=\"subnet.value\">\n /{{ subnet.value }}\n </mat-option>\n </mat-select>\n </mat-form-field>\n</div>\n", styles: [".custom-suffix{background:gray;margin-top:-20px;position:absolute;right:0;top:20px;height:50px;border-radius:4px;padding-top:20px}\n"], dependencies: [{ kind: "directive", type: i3.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i6$1.DefaultLayoutDirective, selector: " [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]", inputs: ["fxLayout", "fxLayout.xs", "fxLayout.sm", "fxLayout.md", "fxLayout.lg", "fxLayout.xl", "fxLayout.lt-sm", "fxLayout.lt-md", "fxLayout.lt-lg", "fxLayout.lt-xl", "fxLayout.gt-xs", "fxLayout.gt-sm", "fxLayout.gt-md", "fxLayout.gt-lg"] }, { kind: "directive", type: i6$1.DefaultLayoutGapDirective, selector: " [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]", inputs: ["fxLayoutGap", "fxLayoutGap.xs", "fxLayoutGap.sm", "fxLayoutGap.md", "fxLayoutGap.lg", "fxLayoutGap.xl", "fxLayoutGap.lt-sm", "fxLayoutGap.lt-md", "fxLayoutGap.lt-lg", "fxLayoutGap.lt-xl", "fxLayoutGap.gt-xs", "fxLayoutGap.gt-sm", "fxLayoutGap.gt-md", "fxLayoutGap.gt-lg"] }, { kind: "directive", type: i6$1.DefaultFlexDirective, selector: " [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]", inputs: ["fxFlex", "fxFlex.xs", "fxFlex.sm", "fxFlex.md", "fxFlex.lg", "fxFlex.xl", "fxFlex.lt-sm", "fxFlex.lt-md", "fxFlex.lt-lg", "fxFlex.lt-xl", "fxFlex.gt-xs", "fxFlex.gt-sm", "fxFlex.gt-md", "fxFlex.gt-lg"] }, { kind: "component", type: i8$4.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i8$4.MatLabel, selector: "mat-label" }, { kind: "directive", type: i8$4.MatHint, selector: "mat-hint", inputs: ["align", "id"] }, { kind: "directive", type: i9.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly"], exportAs: ["matInput"] }, { kind: "component", type: i5.MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "component", type: i9$2.MatSelect, selector: "mat-select", inputs: ["aria-describedby", "panelClass", "disabled", "disableRipple", "tabIndex", "hideSingleSelectionIndicator", "placeholder", "required", "multiple", "disableOptionCentering", "compareWith", "value", "aria-label", "aria-labelledby", "errorStateMatcher", "typeaheadDebounceInterval", "sortComparator", "id", "panelWidth"], outputs: ["openedChange", "opened", "closed", "selectionChange", "valueChange"], exportAs: ["matSelect"] }, { kind: "directive", type: i1$5.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$5.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$5.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }] }); }
13165
+ ], ngImport: i0, template: "<div fxLayout fxLayoutGap=\"10px\" class=\"w-100\">\n <mat-form-field fxFlex=\"calc(85% - 10px)\">\n <mat-label>{{ label }}</mat-label>\n <input type=\"text\" matInput placeholder=\"IP Range\" [formControl]=\"ipAddressControl\">\n <mat-hint>\n What is the ip address or range that we should block? Format can be either a single IP like\n <code>192.175.32.133</code> OR a range specifying the subnet like <code>192.175.32.0/24</code>\n </mat-hint>\n </mat-form-field>\n <mat-form-field fxFlex=\"calc(15% - 10px)\">\n <mat-select [formControl]=\"subnetControl\">\n <mat-option *ngFor=\"let subnet of subnetOptions\" [value]=\"subnet.value\">\n /{{ subnet.value }}\n </mat-option>\n </mat-select>\n </mat-form-field>\n</div>\n", styles: [".custom-suffix{background:gray;margin-top:-20px;position:absolute;right:0;top:20px;height:50px;border-radius:4px;padding-top:20px}\n"], dependencies: [{ kind: "directive", type: i3.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i6$1.DefaultLayoutDirective, selector: " [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]", inputs: ["fxLayout", "fxLayout.xs", "fxLayout.sm", "fxLayout.md", "fxLayout.lg", "fxLayout.xl", "fxLayout.lt-sm", "fxLayout.lt-md", "fxLayout.lt-lg", "fxLayout.lt-xl", "fxLayout.gt-xs", "fxLayout.gt-sm", "fxLayout.gt-md", "fxLayout.gt-lg"] }, { kind: "directive", type: i6$1.DefaultLayoutGapDirective, selector: " [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]", inputs: ["fxLayoutGap", "fxLayoutGap.xs", "fxLayoutGap.sm", "fxLayoutGap.md", "fxLayoutGap.lg", "fxLayoutGap.xl", "fxLayoutGap.lt-sm", "fxLayoutGap.lt-md", "fxLayoutGap.lt-lg", "fxLayoutGap.lt-xl", "fxLayoutGap.gt-xs", "fxLayoutGap.gt-sm", "fxLayoutGap.gt-md", "fxLayoutGap.gt-lg"] }, { kind: "directive", type: i6$1.DefaultFlexDirective, selector: " [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]", inputs: ["fxFlex", "fxFlex.xs", "fxFlex.sm", "fxFlex.md", "fxFlex.lg", "fxFlex.xl", "fxFlex.lt-sm", "fxFlex.lt-md", "fxFlex.lt-lg", "fxFlex.lt-xl", "fxFlex.gt-xs", "fxFlex.gt-sm", "fxFlex.gt-md", "fxFlex.gt-lg"] }, { kind: "component", type: i8$4.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i8$4.MatLabel, selector: "mat-label" }, { kind: "directive", type: i8$4.MatHint, selector: "mat-hint", inputs: ["align", "id"] }, { kind: "directive", type: i9.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly"], exportAs: ["matInput"] }, { kind: "component", type: i5.MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "component", type: i9$1.MatSelect, selector: "mat-select", inputs: ["aria-describedby", "panelClass", "disabled", "disableRipple", "tabIndex", "hideSingleSelectionIndicator", "placeholder", "required", "multiple", "disableOptionCentering", "compareWith", "value", "aria-label", "aria-labelledby", "errorStateMatcher", "typeaheadDebounceInterval", "sortComparator", "id", "panelWidth"], outputs: ["openedChange", "opened", "closed", "selectionChange", "valueChange"], exportAs: ["matSelect"] }, { kind: "directive", type: i1$5.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$5.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$5.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }] }); }
13148
13166
  }
13149
13167
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: IpRangeSelectorComponent, decorators: [{
13150
13168
  type: Component,
@@ -13233,7 +13251,7 @@ class RestrictorsFormComponent {
13233
13251
  this.location.back();
13234
13252
  }
13235
13253
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: RestrictorsFormComponent, deps: [{ token: i1$5.FormBuilder }, { token: i3.Location }, { token: RequestHelperService }, { token: AlertService }, { token: RestrictorService }, { token: i3.DatePipe }], target: i0.ɵɵFactoryTarget.Component }); }
13236
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.14", type: RestrictorsFormComponent, selector: "techlify-restrictors-form", inputs: { restrictor: "restrictor" }, ngImport: i0, template: "<div fxLayout fxLayoutAlign=\"center\" class=\"mb-0\">\n <h3>Restrictor Form</h3>\n</div>\n\n<form [formGroup]=\"form\"\n fxLayout=\"row wrap\" fxLayoutAlign=\"start\" fxLayoutGap=\"10px\"\n (submit)=\"save()\">\n\n <techlify-restrictor-type-selector formControlName=\"type_id\"\n fxFlex=\"calc(100% - 10px)\"></techlify-restrictor-type-selector>\n\n <div fxLayout fxLayoutGap=\"10px\" fxFlex=\"calc(100% - 10px)\"\n class=\"mt-2\"\n *ngIf=\"form.value?.type_id === 1\">\n <mat-form-field fxFlex=\"calc(50% - 10px)\">\n <mat-label>Start Date</mat-label>\n <input formControlName=\"start_date\" matInput [matDatepicker]=\"startDatePicker\" (focus)=\"startDatePicker.open()\">\n <mat-datepicker #startDatePicker></mat-datepicker>\n <mat-hint>From what time should we allow user access.</mat-hint>\n </mat-form-field>\n\n <mat-form-field fxFlex=\"calc(50% - 10px)\">\n <mat-label>Start Time</mat-label>\n <input formControlName=\"start_time\" matInput type=\"time\">\n </mat-form-field>\n </div>\n\n <div fxLayout fxLayoutGap=\"10px\" fxFlex=\"calc(100% - 10px)\"\n class=\"mt-2\"\n *ngIf=\"form.value?.type_id === 1\">\n <mat-form-field fxFlex=\"calc(50% - 10px)\">\n <mat-label>End Date</mat-label>\n <input formControlName=\"end_date\" matInput [matDatepicker]=\"endDatePicker\" (focus)=\"endDatePicker.open()\">\n <mat-datepicker #endDatePicker></mat-datepicker>\n <mat-hint>Up to what time should we allow user access.</mat-hint>\n </mat-form-field>\n\n <mat-form-field fxFlex=\"calc(50% - 10px)\">\n <mat-label>End Time</mat-label>\n <input formControlName=\"end_time\" matInput type=\"time\">\n </mat-form-field>\n </div>\n\n <techlify-ip-range-selector fxFlex=\"calc(100% - 10px)\"\n label=\"IP Address Range (IP & Subnet Field)\"\n formControlName=\"ip_range\"\n *ngIf=\"form.value?.type_id === 2\"\n class=\"mt-2 mb-3\"></techlify-ip-range-selector>\n\n <div fxLayout fxLayoutGap=\"10px\" fxFlex=\"calc(100% - 10px)\"\n class=\"mt-2\">\n <techlify-restrictor-level-selector fxFlex=\"calc(50% - 10px)\"\n formControlName=\"level_id\"></techlify-restrictor-level-selector>\n\n <mat-form-field fxFlex=\"calc(50% - 10px)\" *ngIf=\"form.value?.level_id\">\n <mat-label>Object</mat-label>\n <mat-select *ngIf=\"form.value?.level_id === 1\" formControlName=\"restricted_object_id\">\n <mat-option [value]=\"2\">Client Admin</mat-option>\n <mat-option [value]=\"3\">Client User</mat-option>\n </mat-select>\n <app-searchable-selector *ngIf=\"form.value?.level_id === 2\"\n apiUrl=\"api/roles\"\n titleField=\"label\"\n formControlName=\"restricted_object_id\"></app-searchable-selector>\n <app-searchable-selector *ngIf=\"form.value?.level_id === 3\"\n apiUrl=\"api/users\"\n titleField=\"name\"\n formControlName=\"restricted_object_id\"></app-searchable-selector>\n </mat-form-field>\n </div>\n\n <mat-form-field fxFlex=\"calc(100% - 10px)\" class=\"mt-2\">\n <mat-label>Notes</mat-label>\n <textarea matInput formControlName=\"notes\"></textarea>\n </mat-form-field>\n\n <div fxFlex=\"100%\" fxLayout fxLayoutAlign=\"end\">\n <button [disabled]=\"isSaving\" type=\"submit\" mat-raised-button color=\"primary\">Save</button>\n <button [disabled]=\"isSaving\" (click)=\"redirectBack()\" type=\"button\" mat-flat-button>Cancel</button>\n </div>\n\n</form>\n", styles: [""], dependencies: [{ kind: "directive", type: i3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: i6.MatButton, selector: " button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ", exportAs: ["matButton"] }, { kind: "directive", type: i6$1.DefaultLayoutDirective, selector: " [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]", inputs: ["fxLayout", "fxLayout.xs", "fxLayout.sm", "fxLayout.md", "fxLayout.lg", "fxLayout.xl", "fxLayout.lt-sm", "fxLayout.lt-md", "fxLayout.lt-lg", "fxLayout.lt-xl", "fxLayout.gt-xs", "fxLayout.gt-sm", "fxLayout.gt-md", "fxLayout.gt-lg"] }, { kind: "directive", type: i6$1.DefaultLayoutGapDirective, selector: " [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]", inputs: ["fxLayoutGap", "fxLayoutGap.xs", "fxLayoutGap.sm", "fxLayoutGap.md", "fxLayoutGap.lg", "fxLayoutGap.xl", "fxLayoutGap.lt-sm", "fxLayoutGap.lt-md", "fxLayoutGap.lt-lg", "fxLayoutGap.lt-xl", "fxLayoutGap.gt-xs", "fxLayoutGap.gt-sm", "fxLayoutGap.gt-md", "fxLayoutGap.gt-lg"] }, { kind: "directive", type: i6$1.DefaultLayoutAlignDirective, selector: " [fxLayoutAlign], [fxLayoutAlign.xs], [fxLayoutAlign.sm], [fxLayoutAlign.md], [fxLayoutAlign.lg], [fxLayoutAlign.xl], [fxLayoutAlign.lt-sm], [fxLayoutAlign.lt-md], [fxLayoutAlign.lt-lg], [fxLayoutAlign.lt-xl], [fxLayoutAlign.gt-xs], [fxLayoutAlign.gt-sm], [fxLayoutAlign.gt-md], [fxLayoutAlign.gt-lg]", inputs: ["fxLayoutAlign", "fxLayoutAlign.xs", "fxLayoutAlign.sm", "fxLayoutAlign.md", "fxLayoutAlign.lg", "fxLayoutAlign.xl", "fxLayoutAlign.lt-sm", "fxLayoutAlign.lt-md", "fxLayoutAlign.lt-lg", "fxLayoutAlign.lt-xl", "fxLayoutAlign.gt-xs", "fxLayoutAlign.gt-sm", "fxLayoutAlign.gt-md", "fxLayoutAlign.gt-lg"] }, { kind: "directive", type: i6$1.DefaultFlexDirective, selector: " [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]", inputs: ["fxFlex", "fxFlex.xs", "fxFlex.sm", "fxFlex.md", "fxFlex.lg", "fxFlex.xl", "fxFlex.lt-sm", "fxFlex.lt-md", "fxFlex.lt-lg", "fxFlex.lt-xl", "fxFlex.gt-xs", "fxFlex.gt-sm", "fxFlex.gt-md", "fxFlex.gt-lg"] }, { kind: "component", type: RestrictorTypeSelectorComponent, selector: "techlify-restrictor-type-selector", inputs: ["label", "multiple", "showLabel"] }, { kind: "directive", type: i9.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly"], exportAs: ["matInput"] }, { kind: "component", type: i8$4.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i8$4.MatLabel, selector: "mat-label" }, { kind: "directive", type: i8$4.MatHint, selector: "mat-hint", inputs: ["align", "id"] }, { kind: "component", type: i11$1.MatDatepicker, selector: "mat-datepicker", exportAs: ["matDatepicker"] }, { kind: "directive", type: i11$1.MatDatepickerInput, selector: "input[matDatepicker]", inputs: ["matDatepicker", "min", "max", "matDatepickerFilter"], exportAs: ["matDatepickerInput"] }, { kind: "directive", type: i1$5.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1$5.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$5.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$5.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1$5.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$5.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "component", type: i9$2.MatSelect, selector: "mat-select", inputs: ["aria-describedby", "panelClass", "disabled", "disableRipple", "tabIndex", "hideSingleSelectionIndicator", "placeholder", "required", "multiple", "disableOptionCentering", "compareWith", "value", "aria-label", "aria-labelledby", "errorStateMatcher", "typeaheadDebounceInterval", "sortComparator", "id", "panelWidth"], outputs: ["openedChange", "opened", "closed", "selectionChange", "valueChange"], exportAs: ["matSelect"] }, { kind: "component", type: i5.MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "component", type: IpRangeSelectorComponent, selector: "techlify-ip-range-selector", inputs: ["label"] }, { kind: "component", type: RestrictorLevelSelectorComponent, selector: "techlify-restrictor-level-selector", inputs: ["label", "multiple", "showLabel"] }, { kind: "component", type: SearchableSelectorComponent, selector: "app-searchable-selector", inputs: ["valueField", "titleField", "subtitleField", "apiUrl", "multiple", "selectedValue", "enableSearch", "add", "addConfig", "edit", "editConfig", "sort", "sortBy", "searchField", "itemComponent", "items", "apiDataProperty", "cache", "perPage", "inDataSearch", "panelWidth", "focusSearchOnOpen", "isEmitInitialEvent", "required", "disabled", "value"], outputs: ["selectedValueChange", "selectionChange", "itemsChange", "isItemsEmpty"] }] }); }
13254
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.14", type: RestrictorsFormComponent, selector: "techlify-restrictors-form", inputs: { restrictor: "restrictor" }, ngImport: i0, template: "<div fxLayout fxLayoutAlign=\"center\" class=\"mb-0\">\n <h3>Restrictor Form</h3>\n</div>\n\n<form [formGroup]=\"form\"\n fxLayout=\"row wrap\" fxLayoutAlign=\"start\" fxLayoutGap=\"10px\"\n (submit)=\"save()\">\n\n <techlify-restrictor-type-selector formControlName=\"type_id\"\n fxFlex=\"calc(100% - 10px)\"></techlify-restrictor-type-selector>\n\n <div fxLayout fxLayoutGap=\"10px\" fxFlex=\"calc(100% - 10px)\"\n class=\"mt-2\"\n *ngIf=\"form.value?.type_id === 1\">\n <mat-form-field fxFlex=\"calc(50% - 10px)\">\n <mat-label>Start Date</mat-label>\n <input formControlName=\"start_date\" matInput [matDatepicker]=\"startDatePicker\" (focus)=\"startDatePicker.open()\">\n <mat-datepicker #startDatePicker></mat-datepicker>\n <mat-hint>From what time should we allow user access.</mat-hint>\n </mat-form-field>\n\n <mat-form-field fxFlex=\"calc(50% - 10px)\">\n <mat-label>Start Time</mat-label>\n <input formControlName=\"start_time\" matInput type=\"time\">\n </mat-form-field>\n </div>\n\n <div fxLayout fxLayoutGap=\"10px\" fxFlex=\"calc(100% - 10px)\"\n class=\"mt-2\"\n *ngIf=\"form.value?.type_id === 1\">\n <mat-form-field fxFlex=\"calc(50% - 10px)\">\n <mat-label>End Date</mat-label>\n <input formControlName=\"end_date\" matInput [matDatepicker]=\"endDatePicker\" (focus)=\"endDatePicker.open()\">\n <mat-datepicker #endDatePicker></mat-datepicker>\n <mat-hint>Up to what time should we allow user access.</mat-hint>\n </mat-form-field>\n\n <mat-form-field fxFlex=\"calc(50% - 10px)\">\n <mat-label>End Time</mat-label>\n <input formControlName=\"end_time\" matInput type=\"time\">\n </mat-form-field>\n </div>\n\n <techlify-ip-range-selector fxFlex=\"calc(100% - 10px)\"\n label=\"IP Address Range (IP & Subnet Field)\"\n formControlName=\"ip_range\"\n *ngIf=\"form.value?.type_id === 2\"\n class=\"mt-2 mb-3\"></techlify-ip-range-selector>\n\n <div fxLayout fxLayoutGap=\"10px\" fxFlex=\"calc(100% - 10px)\"\n class=\"mt-2\">\n <techlify-restrictor-level-selector fxFlex=\"calc(50% - 10px)\"\n formControlName=\"level_id\"></techlify-restrictor-level-selector>\n\n <mat-form-field fxFlex=\"calc(50% - 10px)\" *ngIf=\"form.value?.level_id\">\n <mat-label>Object</mat-label>\n <mat-select *ngIf=\"form.value?.level_id === 1\" formControlName=\"restricted_object_id\">\n <mat-option [value]=\"2\">Client Admin</mat-option>\n <mat-option [value]=\"3\">Client User</mat-option>\n </mat-select>\n <app-searchable-selector *ngIf=\"form.value?.level_id === 2\"\n apiUrl=\"api/roles\"\n titleField=\"label\"\n formControlName=\"restricted_object_id\"></app-searchable-selector>\n <app-searchable-selector *ngIf=\"form.value?.level_id === 3\"\n apiUrl=\"api/users\"\n titleField=\"name\"\n formControlName=\"restricted_object_id\"></app-searchable-selector>\n </mat-form-field>\n </div>\n\n <mat-form-field fxFlex=\"calc(100% - 10px)\" class=\"mt-2\">\n <mat-label>Notes</mat-label>\n <textarea matInput formControlName=\"notes\"></textarea>\n </mat-form-field>\n\n <div fxFlex=\"100%\" fxLayout fxLayoutAlign=\"end\">\n <button [disabled]=\"isSaving\" type=\"submit\" mat-raised-button color=\"primary\">Save</button>\n <button [disabled]=\"isSaving\" (click)=\"redirectBack()\" type=\"button\" mat-flat-button>Cancel</button>\n </div>\n\n</form>\n", styles: [""], dependencies: [{ kind: "directive", type: i3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: i6.MatButton, selector: " button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ", exportAs: ["matButton"] }, { kind: "directive", type: i6$1.DefaultLayoutDirective, selector: " [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]", inputs: ["fxLayout", "fxLayout.xs", "fxLayout.sm", "fxLayout.md", "fxLayout.lg", "fxLayout.xl", "fxLayout.lt-sm", "fxLayout.lt-md", "fxLayout.lt-lg", "fxLayout.lt-xl", "fxLayout.gt-xs", "fxLayout.gt-sm", "fxLayout.gt-md", "fxLayout.gt-lg"] }, { kind: "directive", type: i6$1.DefaultLayoutGapDirective, selector: " [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]", inputs: ["fxLayoutGap", "fxLayoutGap.xs", "fxLayoutGap.sm", "fxLayoutGap.md", "fxLayoutGap.lg", "fxLayoutGap.xl", "fxLayoutGap.lt-sm", "fxLayoutGap.lt-md", "fxLayoutGap.lt-lg", "fxLayoutGap.lt-xl", "fxLayoutGap.gt-xs", "fxLayoutGap.gt-sm", "fxLayoutGap.gt-md", "fxLayoutGap.gt-lg"] }, { kind: "directive", type: i6$1.DefaultLayoutAlignDirective, selector: " [fxLayoutAlign], [fxLayoutAlign.xs], [fxLayoutAlign.sm], [fxLayoutAlign.md], [fxLayoutAlign.lg], [fxLayoutAlign.xl], [fxLayoutAlign.lt-sm], [fxLayoutAlign.lt-md], [fxLayoutAlign.lt-lg], [fxLayoutAlign.lt-xl], [fxLayoutAlign.gt-xs], [fxLayoutAlign.gt-sm], [fxLayoutAlign.gt-md], [fxLayoutAlign.gt-lg]", inputs: ["fxLayoutAlign", "fxLayoutAlign.xs", "fxLayoutAlign.sm", "fxLayoutAlign.md", "fxLayoutAlign.lg", "fxLayoutAlign.xl", "fxLayoutAlign.lt-sm", "fxLayoutAlign.lt-md", "fxLayoutAlign.lt-lg", "fxLayoutAlign.lt-xl", "fxLayoutAlign.gt-xs", "fxLayoutAlign.gt-sm", "fxLayoutAlign.gt-md", "fxLayoutAlign.gt-lg"] }, { kind: "directive", type: i6$1.DefaultFlexDirective, selector: " [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]", inputs: ["fxFlex", "fxFlex.xs", "fxFlex.sm", "fxFlex.md", "fxFlex.lg", "fxFlex.xl", "fxFlex.lt-sm", "fxFlex.lt-md", "fxFlex.lt-lg", "fxFlex.lt-xl", "fxFlex.gt-xs", "fxFlex.gt-sm", "fxFlex.gt-md", "fxFlex.gt-lg"] }, { kind: "component", type: RestrictorTypeSelectorComponent, selector: "techlify-restrictor-type-selector", inputs: ["label", "multiple", "showLabel"] }, { kind: "directive", type: i9.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly"], exportAs: ["matInput"] }, { kind: "component", type: i8$4.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i8$4.MatLabel, selector: "mat-label" }, { kind: "directive", type: i8$4.MatHint, selector: "mat-hint", inputs: ["align", "id"] }, { kind: "component", type: i11$1.MatDatepicker, selector: "mat-datepicker", exportAs: ["matDatepicker"] }, { kind: "directive", type: i11$1.MatDatepickerInput, selector: "input[matDatepicker]", inputs: ["matDatepicker", "min", "max", "matDatepickerFilter"], exportAs: ["matDatepickerInput"] }, { kind: "directive", type: i1$5.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1$5.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$5.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$5.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1$5.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$5.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "component", type: i9$1.MatSelect, selector: "mat-select", inputs: ["aria-describedby", "panelClass", "disabled", "disableRipple", "tabIndex", "hideSingleSelectionIndicator", "placeholder", "required", "multiple", "disableOptionCentering", "compareWith", "value", "aria-label", "aria-labelledby", "errorStateMatcher", "typeaheadDebounceInterval", "sortComparator", "id", "panelWidth"], outputs: ["openedChange", "opened", "closed", "selectionChange", "valueChange"], exportAs: ["matSelect"] }, { kind: "component", type: i5.MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "component", type: IpRangeSelectorComponent, selector: "techlify-ip-range-selector", inputs: ["label"] }, { kind: "component", type: RestrictorLevelSelectorComponent, selector: "techlify-restrictor-level-selector", inputs: ["label", "multiple", "showLabel"] }, { kind: "component", type: SearchableSelectorComponent, selector: "app-searchable-selector", inputs: ["valueField", "titleField", "subtitleField", "apiUrl", "multiple", "selectedValue", "enableSearch", "add", "addConfig", "edit", "editConfig", "sort", "sortBy", "searchField", "itemComponent", "items", "apiDataProperty", "cache", "perPage", "inDataSearch", "panelWidth", "focusSearchOnOpen", "isEmitInitialEvent", "required", "disabled", "value"], outputs: ["selectedValueChange", "selectionChange", "itemsChange", "isItemsEmpty"] }] }); }
13237
13255
  }
13238
13256
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: RestrictorsFormComponent, decorators: [{
13239
13257
  type: Component,
@@ -13913,7 +13931,7 @@ class ColumnSelectorComponent {
13913
13931
  this.displayedColumnsChange.emit(finalColumns.map(c => c.def));
13914
13932
  }
13915
13933
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ColumnSelectorComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
13916
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.14", type: ColumnSelectorComponent, selector: "app-column-selector", inputs: { label: "label", mode: "mode", columnConfigs: "columnConfigs", selectedColumns: "selectedColumns", isExportWorking: "isExportWorking" }, outputs: { selectedColumnsChange: "selectedColumnsChange", displayedColumnsChange: "displayedColumnsChange" }, ngImport: i0, template: "<mat-form-field *ngIf=\"mode === 'selector'\">\n <mat-label>{{ label }}</mat-label>\n <mat-select [multiple]=\"true\" [formControl]=\"columnSelector\">\n <mat-option class=\"text-capitalize\" *ngFor=\"let col of sortedColumns\" [value]=\"col.def\"\n [disabled]=\"!(col?.isEditable ?? true)\">\n {{ col.label }}\n </mat-option>\n </mat-select>\n</mat-form-field>\n\n<div *ngIf=\"mode === 'icon'\" fxLayoutAlign=\"start center\">\n <mat-icon class=\"clickable\" (click)=\"select.open()\">view_column</mat-icon>\n <mat-select class=\"column-selector fl-sm\" #select [formControl]=\"columnSelector\" multiple panelWidth=\"\">\n <mat-form-field class=\"p-1 w-100\">\n <input matInput [formControl]=\"search\" placeholder=\"Search\" (keydown)=\"$event.stopPropagation();\"\n autocomplete=\"off\">\n <button mat-icon-button matSuffix type=\"button\" *ngIf=\"search.value\" (click)=\"search.setValue('')\">\n <mat-icon>clear</mat-icon>\n </button>\n </mat-form-field>\n <mat-option *ngFor=\"let column of sortedColumns\" [value]=\"column.def\" class=\"text-capitalize\"\n [disabled]=\"!(column?.isEditable ?? true)\">{{column?.label}}</mat-option>\n </mat-select>\n</div>", styles: [".column-selector{opacity:0;position:relative;right:24px;height:0!important;width:0!important}\n"], dependencies: [{ kind: "directive", type: i3.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: i8$4.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i8$4.MatLabel, selector: "mat-label" }, { kind: "directive", type: i8$4.MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { kind: "component", type: i5.MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "component", type: i9$2.MatSelect, selector: "mat-select", inputs: ["aria-describedby", "panelClass", "disabled", "disableRipple", "tabIndex", "hideSingleSelectionIndicator", "placeholder", "required", "multiple", "disableOptionCentering", "compareWith", "value", "aria-label", "aria-labelledby", "errorStateMatcher", "typeaheadDebounceInterval", "sortComparator", "id", "panelWidth"], outputs: ["openedChange", "opened", "closed", "selectionChange", "valueChange"], exportAs: ["matSelect"] }, { kind: "directive", type: i1$5.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$5.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$5.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "component", type: i8.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "directive", type: i9.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly"], exportAs: ["matInput"] }, { kind: "component", type: i6.MatIconButton, selector: "button[mat-icon-button]", exportAs: ["matButton"] }, { kind: "directive", type: i6$1.DefaultLayoutAlignDirective, selector: " [fxLayoutAlign], [fxLayoutAlign.xs], [fxLayoutAlign.sm], [fxLayoutAlign.md], [fxLayoutAlign.lg], [fxLayoutAlign.xl], [fxLayoutAlign.lt-sm], [fxLayoutAlign.lt-md], [fxLayoutAlign.lt-lg], [fxLayoutAlign.lt-xl], [fxLayoutAlign.gt-xs], [fxLayoutAlign.gt-sm], [fxLayoutAlign.gt-md], [fxLayoutAlign.gt-lg]", inputs: ["fxLayoutAlign", "fxLayoutAlign.xs", "fxLayoutAlign.sm", "fxLayoutAlign.md", "fxLayoutAlign.lg", "fxLayoutAlign.xl", "fxLayoutAlign.lt-sm", "fxLayoutAlign.lt-md", "fxLayoutAlign.lt-lg", "fxLayoutAlign.lt-xl", "fxLayoutAlign.gt-xs", "fxLayoutAlign.gt-sm", "fxLayoutAlign.gt-md", "fxLayoutAlign.gt-lg"] }] }); }
13934
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.14", type: ColumnSelectorComponent, selector: "app-column-selector", inputs: { label: "label", mode: "mode", columnConfigs: "columnConfigs", selectedColumns: "selectedColumns", isExportWorking: "isExportWorking" }, outputs: { selectedColumnsChange: "selectedColumnsChange", displayedColumnsChange: "displayedColumnsChange" }, ngImport: i0, template: "<mat-form-field *ngIf=\"mode === 'selector'\">\n <mat-label>{{ label }}</mat-label>\n <mat-select [multiple]=\"true\" [formControl]=\"columnSelector\">\n <mat-option class=\"text-capitalize\" *ngFor=\"let col of sortedColumns\" [value]=\"col.def\"\n [disabled]=\"!(col?.isEditable ?? true)\">\n {{ col.label }}\n </mat-option>\n </mat-select>\n</mat-form-field>\n\n<div *ngIf=\"mode === 'icon'\" fxLayoutAlign=\"start center\">\n <mat-icon class=\"clickable\" (click)=\"select.open()\">view_column</mat-icon>\n <mat-select class=\"column-selector fl-sm\" #select [formControl]=\"columnSelector\" multiple panelWidth=\"\">\n <mat-form-field class=\"p-1 w-100\">\n <input matInput [formControl]=\"search\" placeholder=\"Search\" (keydown)=\"$event.stopPropagation();\"\n autocomplete=\"off\">\n <button mat-icon-button matSuffix type=\"button\" *ngIf=\"search.value\" (click)=\"search.setValue('')\">\n <mat-icon>clear</mat-icon>\n </button>\n </mat-form-field>\n <mat-option *ngFor=\"let column of sortedColumns\" [value]=\"column.def\" class=\"text-capitalize\"\n [disabled]=\"!(column?.isEditable ?? true)\">{{column?.label}}</mat-option>\n </mat-select>\n</div>", styles: [".column-selector{opacity:0;position:relative;right:24px;height:0!important;width:0!important}\n"], dependencies: [{ kind: "directive", type: i3.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: i8$4.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i8$4.MatLabel, selector: "mat-label" }, { kind: "directive", type: i8$4.MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { kind: "component", type: i5.MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "component", type: i9$1.MatSelect, selector: "mat-select", inputs: ["aria-describedby", "panelClass", "disabled", "disableRipple", "tabIndex", "hideSingleSelectionIndicator", "placeholder", "required", "multiple", "disableOptionCentering", "compareWith", "value", "aria-label", "aria-labelledby", "errorStateMatcher", "typeaheadDebounceInterval", "sortComparator", "id", "panelWidth"], outputs: ["openedChange", "opened", "closed", "selectionChange", "valueChange"], exportAs: ["matSelect"] }, { kind: "directive", type: i1$5.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$5.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$5.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "component", type: i8.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "directive", type: i9.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly"], exportAs: ["matInput"] }, { kind: "component", type: i6.MatIconButton, selector: "button[mat-icon-button]", exportAs: ["matButton"] }, { kind: "directive", type: i6$1.DefaultLayoutAlignDirective, selector: " [fxLayoutAlign], [fxLayoutAlign.xs], [fxLayoutAlign.sm], [fxLayoutAlign.md], [fxLayoutAlign.lg], [fxLayoutAlign.xl], [fxLayoutAlign.lt-sm], [fxLayoutAlign.lt-md], [fxLayoutAlign.lt-lg], [fxLayoutAlign.lt-xl], [fxLayoutAlign.gt-xs], [fxLayoutAlign.gt-sm], [fxLayoutAlign.gt-md], [fxLayoutAlign.gt-lg]", inputs: ["fxLayoutAlign", "fxLayoutAlign.xs", "fxLayoutAlign.sm", "fxLayoutAlign.md", "fxLayoutAlign.lg", "fxLayoutAlign.xl", "fxLayoutAlign.lt-sm", "fxLayoutAlign.lt-md", "fxLayoutAlign.lt-lg", "fxLayoutAlign.lt-xl", "fxLayoutAlign.gt-xs", "fxLayoutAlign.gt-sm", "fxLayoutAlign.gt-md", "fxLayoutAlign.gt-lg"] }] }); }
13917
13935
  }
13918
13936
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ColumnSelectorComponent, decorators: [{
13919
13937
  type: Component,
@@ -15084,7 +15102,7 @@ let SubscriptionListingComponent = class SubscriptionListingComponent extends Te
15084
15102
  });
15085
15103
  }
15086
15104
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: SubscriptionListingComponent, deps: [{ token: SubscriptionService }, { token: i1$5.UntypedFormBuilder }, { token: i1.MatDialog }, { token: i3.DatePipe }], target: i0.ɵɵFactoryTarget.Component }); }
15087
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.14", type: SubscriptionListingComponent, selector: "app-subscription-listing", inputs: { subscriptionPackage: "subscriptionPackage" }, usesInheritance: true, ngImport: i0, template: "<div fxLayout=\"column\" class=\"m-2\">\n <mat-card appearance=\"outlined\" fxLayout fxLayoutGap=\"0.5rem\" fxLayoutAlign=\"start center\">\n <div fxLayout fxLayoutAlign=\"start center\">\n <h5 class=\"m-0\">{{subscriptionPackage?'Package':'Tenant'}} Subscriptions</h5>\n <app-subscription-form (success)=\"reload()\"\n [subscriptionPackage]=\"subscriptionPackage\"></app-subscription-form>\n </div>\n <div fxFlex>\n </div>\n <form [formGroup]=\"filterForm\" fxLayout=\"row\" fxLayoutGap=\"0.3rem\" class=\"d-print-none\"\n fxLayoutAlign=\"start start\">\n <mat-form-field appearance=\"outline\" class=\" fl-md\">\n <mat-label>Search</mat-label>\n <input type=\"text\" matInput formControlName=\"search\" placeholder=\"Search Tenant, Details\"\n autocomplete=\"off\" />\n <button *ngIf=\"filterForm.get('search').value\" matSuffix mat-icon-button\n (click)=\"resetFilter('search')\">\n <mat-icon>close</mat-icon>\n </button>\n </mat-form-field>\n\n\n <mat-form-field class=\" fl-sm\" appearance=\"outline\" *ngIf=\"!subscriptionPackage\">\n <mat-label>Package</mat-label>\n <app-searchable-selector formControlName=\"package_ids\" apiUrl=\"api/subscription-packages\"\n [multiple]=\"true\">\n </app-searchable-selector>\n <button mat-icon-button matSuffix type=\"button\" *ngIf=\"filterForm.get('package_ids').value\"\n (click)=\"resetFilter('package_ids')\">\n <mat-icon>clear</mat-icon>\n </button>\n </mat-form-field>\n\n <app-timeline-filter [showClearButton]=\"true\" [form]=\"filterForm\" appearance=\"outline\"\n formControlName=\"date_period_id\" labelText=\"Start\">\n </app-timeline-filter>\n\n <mat-form-field class=\"fl-sm\" appearance=\"outline\">\n <mat-label>Status</mat-label>\n <mat-select formControlName=\"status_ids\" multiple>\n <mat-option [value]=\"1\">Active</mat-option>\n <mat-option [value]=\"2\">Inactive</mat-option>\n </mat-select>\n <button mat-icon-button matSuffix type=\"button\" *ngIf=\"filterForm.get('status_ids').value\"\n (click)=\"resetFilter('status_ids')\">\n <mat-icon>clear</mat-icon>\n </button>\n </mat-form-field>\n\n </form>\n </mat-card>\n <mat-card appearance=\"outlined\" class=\"p-0 mt-2\">\n <table mat-table matSort [dataSource]=\"models\" class=\"w-100\" infiniteScroll [infiniteScrollDistance]=\"2\"\n [infiniteScrollThrottle]=\"50\" (scrolled)=\"onScroll()\" (matSortChange)=\"sortColumn($event)\">\n\n <ng-container matColumnDef=\"index\">\n <th mat-header-cell *matHeaderCellDef> # </th>\n <td mat-cell *matCellDef=\"let tenantSubscription; let i = index\"> {{ i+1 }} </td>\n </ng-container>\n\n <ng-container matColumnDef=\"tenant\">\n <th mat-header-cell *matHeaderCellDef mat-sort-header disableClear> Tenant </th>\n <td mat-cell *matCellDef=\"let tenantSubscription\">\n <div>\n <div>{{tenantSubscription?.tenant?.name }}</div>\n <div><span>{{tenantSubscription?.tenant?.phone }}</span> <span> |\n {{tenantSubscription?.tenant?.email }}</span></div>\n </div>\n </td>\n </ng-container>\n\n <ng-container matColumnDef=\"period\">\n <th mat-header-cell *matHeaderCellDef mat-sort-header disableClear> Period </th>\n <td mat-cell *matCellDef=\"let tenantSubscription\">\n <span *ngIf=\"tenantSubscription?.started_at\">{{tenantSubscription?.started_at | date:'mediumDate' }}\n -> {{(tenantSubscription?.ended_at | date:'mediumDate') ?? 'NA' }}</span>\n </td>\n </ng-container>\n\n <ng-container matColumnDef=\"package\">\n <th mat-header-cell *matHeaderCellDef> Package </th>\n <td mat-cell *matCellDef=\"let tenantSubscription\">\n <div>{{tenantSubscription?.package?.title }}</div>\n </td>\n </ng-container>\n\n <ng-container matColumnDef=\"status\">\n <th mat-header-cell *matHeaderCellDef> Status </th>\n <td mat-cell *matCellDef=\"let tenantSubscription\">\n <div>{{tenantSubscription?.status?.title }}</div>\n </td>\n </ng-container>\n\n <ng-container matColumnDef=\"cost_per_unit\">\n <th mat-header-cell *matHeaderCellDef> Cost/Units </th>\n <td mat-cell *matCellDef=\"let tenantSubscription\">\n <div>{{tenantSubscription?.cost_per_unit | currency:'USD':'symbol':'1.0-2' }}</div>\n </td>\n </ng-container>\n\n <ng-container matColumnDef=\"units\">\n <th mat-header-cell *matHeaderCellDef> Units </th>\n <td mat-cell *matCellDef=\"let tenantSubscription\">\n <div>{{tenantSubscription?.units | number}}</div>\n </td>\n </ng-container>\n\n <ng-container matColumnDef=\"is_unit_limitation_enforced\">\n <th mat-header-cell *matHeaderCellDef> Is Units Limited </th>\n <td mat-cell *matCellDef=\"let tenantSubscription\">\n <div>{{tenantSubscription?.is_unit_limitation_enforced ? 'Yes' : 'No' }}</div>\n </td>\n </ng-container>\n\n <ng-container matColumnDef=\"total\">\n <th mat-header-cell *matHeaderCellDef> Total Cost </th>\n <td mat-cell *matCellDef=\"let tenantSubscription\">\n <div>{{tenantSubscription?.total | currency:'USD':'symbol':'1.0-2' }}</div>\n </td>\n </ng-container>\n\n <ng-container matColumnDef=\"is_trail\">\n <th mat-header-cell *matHeaderCellDef> Is Trail</th>\n <td mat-cell *matCellDef=\"let tenantSubscription\">\n <div>\n <div>{{tenantSubscription?.is_trail ? 'Yes' : 'No' }}</div>\n <div *ngIf=\"tenantSubscription?.is_trail\"><span>{{tenantSubscription?.trail_started_at |\n date:'mediumDate' }} -> {{tenantSubscription?.trail_ended_at | date:'mediumDate'\n }}</span></div>\n </div>\n </td>\n </ng-container>\n\n\n <ng-container matColumnDef=\"actions\">\n <th mat-header-cell *matHeaderCellDef> Actions </th>\n <td mat-cell *matCellDef=\"let tenantSubscription\">\n <div class=\"text-secondary\" fxLayout>\n <div *ngIf=\"tenantSubscription?.creator_id\">\n <app-subscription-form *ngIf=\"tenantSubscription.status_id == subscriptionStatus.ACTIVE\"\n (success)=\"reload()\" [tenantSubscriptionInfo]=\"tenantSubscription\"\n [subscriptionPackage]=\"subscriptionPackage\"></app-subscription-form>\n <button *ngIf=\"tenantSubscription.status_id == subscriptionStatus.ACTIVE\"\n matTooltip=\"Cancel Subscription\" type=\"button\" mat-icon-button\n (click)=\"cancel(tenantSubscription)\">\n <mat-icon>cancel</mat-icon>\n </button>\n </div>\n </div>\n </td>\n </ng-container>\n\n <tr mat-header-row *matHeaderRowDef=\"displayedColumns\"></tr>\n <tr mat-row *matRowDef=\"let row; columns: displayedColumns;\"></tr>\n </table>\n <mat-progress-bar mode=\"indeterminate\" *ngIf=\"isWorking\"></mat-progress-bar>\n </mat-card>\n</div>", styles: [".add-icon{position:relative;top:5px}.add-icon:hover{cursor:pointer}\n"], dependencies: [{ kind: "directive", type: i3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: i6.MatIconButton, selector: "button[mat-icon-button]", exportAs: ["matButton"] }, { kind: "component", type: i8$4.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i8$4.MatLabel, selector: "mat-label" }, { kind: "directive", type: i8$4.MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { kind: "component", type: i8.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "directive", type: i9.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly"], exportAs: ["matInput"] }, { kind: "component", type: i5.MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "component", type: i9$2.MatSelect, selector: "mat-select", inputs: ["aria-describedby", "panelClass", "disabled", "disableRipple", "tabIndex", "hideSingleSelectionIndicator", "placeholder", "required", "multiple", "disableOptionCentering", "compareWith", "value", "aria-label", "aria-labelledby", "errorStateMatcher", "typeaheadDebounceInterval", "sortComparator", "id", "panelWidth"], outputs: ["openedChange", "opened", "closed", "selectionChange", "valueChange"], exportAs: ["matSelect"] }, { kind: "directive", type: i11.MatSort, selector: "[matSort]", inputs: ["matSortActive", "matSortStart", "matSortDirection", "matSortDisableClear", "matSortDisabled"], outputs: ["matSortChange"], exportAs: ["matSort"] }, { kind: "component", type: i11.MatSortHeader, selector: "[mat-sort-header]", inputs: ["mat-sort-header", "arrowPosition", "start", "disabled", "sortActionDescription", "disableClear"], exportAs: ["matSortHeader"] }, { kind: "component", type: i12.MatTable, selector: "mat-table, table[mat-table]", exportAs: ["matTable"] }, { kind: "directive", type: i12.MatHeaderCellDef, selector: "[matHeaderCellDef]" }, { kind: "directive", type: i12.MatHeaderRowDef, selector: "[matHeaderRowDef]", inputs: ["matHeaderRowDef", "matHeaderRowDefSticky"] }, { kind: "directive", type: i12.MatColumnDef, selector: "[matColumnDef]", inputs: ["matColumnDef"] }, { kind: "directive", type: i12.MatCellDef, selector: "[matCellDef]" }, { kind: "directive", type: i12.MatRowDef, selector: "[matRowDef]", inputs: ["matRowDefColumns", "matRowDefWhen"] }, { kind: "directive", type: i12.MatHeaderCell, selector: "mat-header-cell, th[mat-header-cell]" }, { kind: "directive", type: i12.MatCell, selector: "mat-cell, td[mat-cell]" }, { kind: "component", type: i12.MatHeaderRow, selector: "mat-header-row, tr[mat-header-row]", exportAs: ["matHeaderRow"] }, { kind: "component", type: i12.MatRow, selector: "mat-row, tr[mat-row]", exportAs: ["matRow"] }, { kind: "component", type: i4.MatCard, selector: "mat-card", inputs: ["appearance"], exportAs: ["matCard"] }, { kind: "directive", type: i10.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "component", type: i11$2.MatProgressBar, selector: "mat-progress-bar", inputs: ["color", "value", "bufferValue", "mode"], outputs: ["animationEnd"], exportAs: ["matProgressBar"] }, { kind: "component", type: SearchableSelectorComponent, selector: "app-searchable-selector", inputs: ["valueField", "titleField", "subtitleField", "apiUrl", "multiple", "selectedValue", "enableSearch", "add", "addConfig", "edit", "editConfig", "sort", "sortBy", "searchField", "itemComponent", "items", "apiDataProperty", "cache", "perPage", "inDataSearch", "panelWidth", "focusSearchOnOpen", "isEmitInitialEvent", "required", "disabled", "value"], outputs: ["selectedValueChange", "selectionChange", "itemsChange", "isItemsEmpty"] }, { kind: "directive", type: i1$5.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1$5.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$5.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$5.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1$5.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$5.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "component", type: SubscriptionFormComponent, selector: "app-subscription-form", inputs: ["isUpdate", "subscriptionPackage", "tenantSubscriptionInfo"], outputs: ["success"] }, { kind: "directive", type: i6$1.DefaultLayoutDirective, selector: " [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]", inputs: ["fxLayout", "fxLayout.xs", "fxLayout.sm", "fxLayout.md", "fxLayout.lg", "fxLayout.xl", "fxLayout.lt-sm", "fxLayout.lt-md", "fxLayout.lt-lg", "fxLayout.lt-xl", "fxLayout.gt-xs", "fxLayout.gt-sm", "fxLayout.gt-md", "fxLayout.gt-lg"] }, { kind: "directive", type: i6$1.DefaultLayoutGapDirective, selector: " [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]", inputs: ["fxLayoutGap", "fxLayoutGap.xs", "fxLayoutGap.sm", "fxLayoutGap.md", "fxLayoutGap.lg", "fxLayoutGap.xl", "fxLayoutGap.lt-sm", "fxLayoutGap.lt-md", "fxLayoutGap.lt-lg", "fxLayoutGap.lt-xl", "fxLayoutGap.gt-xs", "fxLayoutGap.gt-sm", "fxLayoutGap.gt-md", "fxLayoutGap.gt-lg"] }, { kind: "directive", type: i6$1.DefaultLayoutAlignDirective, selector: " [fxLayoutAlign], [fxLayoutAlign.xs], [fxLayoutAlign.sm], [fxLayoutAlign.md], [fxLayoutAlign.lg], [fxLayoutAlign.xl], [fxLayoutAlign.lt-sm], [fxLayoutAlign.lt-md], [fxLayoutAlign.lt-lg], [fxLayoutAlign.lt-xl], [fxLayoutAlign.gt-xs], [fxLayoutAlign.gt-sm], [fxLayoutAlign.gt-md], [fxLayoutAlign.gt-lg]", inputs: ["fxLayoutAlign", "fxLayoutAlign.xs", "fxLayoutAlign.sm", "fxLayoutAlign.md", "fxLayoutAlign.lg", "fxLayoutAlign.xl", "fxLayoutAlign.lt-sm", "fxLayoutAlign.lt-md", "fxLayoutAlign.lt-lg", "fxLayoutAlign.lt-xl", "fxLayoutAlign.gt-xs", "fxLayoutAlign.gt-sm", "fxLayoutAlign.gt-md", "fxLayoutAlign.gt-lg"] }, { kind: "directive", type: i6$1.DefaultFlexDirective, selector: " [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]", inputs: ["fxFlex", "fxFlex.xs", "fxFlex.sm", "fxFlex.md", "fxFlex.lg", "fxFlex.xl", "fxFlex.lt-sm", "fxFlex.lt-md", "fxFlex.lt-lg", "fxFlex.lt-xl", "fxFlex.gt-xs", "fxFlex.gt-sm", "fxFlex.gt-md", "fxFlex.gt-lg"] }, { kind: "directive", type: i6$2.InfiniteScrollDirective, selector: "[infiniteScroll], [infinite-scroll], [data-infinite-scroll]", inputs: ["infiniteScrollDistance", "infiniteScrollUpDistance", "infiniteScrollThrottle", "infiniteScrollDisabled", "infiniteScrollContainer", "scrollWindow", "immediateCheck", "horizontal", "alwaysCallback", "fromRoot"], outputs: ["scrolled", "scrolledUp"] }, { kind: "component", type: TimelineFilterComponent, selector: "app-timeline-filter", inputs: ["defaultValue", "required", "disabled", "value", "timelines", "dateFrom", "dateTo", "appearance", "showClearButton", "form", "labelText"], outputs: ["selectionChange"] }, { kind: "pipe", type: i3.DecimalPipe, name: "number" }, { kind: "pipe", type: i3.CurrencyPipe, name: "currency" }, { kind: "pipe", type: i3.DatePipe, name: "date" }] }); }
15105
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.14", type: SubscriptionListingComponent, selector: "app-subscription-listing", inputs: { subscriptionPackage: "subscriptionPackage" }, usesInheritance: true, ngImport: i0, template: "<div fxLayout=\"column\" class=\"m-2\">\n <mat-card appearance=\"outlined\" fxLayout fxLayoutGap=\"0.5rem\" fxLayoutAlign=\"start center\">\n <div fxLayout fxLayoutAlign=\"start center\">\n <h5 class=\"m-0\">{{subscriptionPackage?'Package':'Tenant'}} Subscriptions</h5>\n <app-subscription-form (success)=\"reload()\"\n [subscriptionPackage]=\"subscriptionPackage\"></app-subscription-form>\n </div>\n <div fxFlex>\n </div>\n <form [formGroup]=\"filterForm\" fxLayout=\"row\" fxLayoutGap=\"0.3rem\" class=\"d-print-none\"\n fxLayoutAlign=\"start start\">\n <mat-form-field appearance=\"outline\" class=\" fl-md\">\n <mat-label>Search</mat-label>\n <input type=\"text\" matInput formControlName=\"search\" placeholder=\"Search Tenant, Details\"\n autocomplete=\"off\" />\n <button *ngIf=\"filterForm.get('search').value\" matSuffix mat-icon-button\n (click)=\"resetFilter('search')\">\n <mat-icon>close</mat-icon>\n </button>\n </mat-form-field>\n\n\n <mat-form-field class=\" fl-sm\" appearance=\"outline\" *ngIf=\"!subscriptionPackage\">\n <mat-label>Package</mat-label>\n <app-searchable-selector formControlName=\"package_ids\" apiUrl=\"api/subscription-packages\"\n [multiple]=\"true\">\n </app-searchable-selector>\n <button mat-icon-button matSuffix type=\"button\" *ngIf=\"filterForm.get('package_ids').value\"\n (click)=\"resetFilter('package_ids')\">\n <mat-icon>clear</mat-icon>\n </button>\n </mat-form-field>\n\n <app-timeline-filter [showClearButton]=\"true\" [form]=\"filterForm\" appearance=\"outline\"\n formControlName=\"date_period_id\" labelText=\"Start\">\n </app-timeline-filter>\n\n <mat-form-field class=\"fl-sm\" appearance=\"outline\">\n <mat-label>Status</mat-label>\n <mat-select formControlName=\"status_ids\" multiple>\n <mat-option [value]=\"1\">Active</mat-option>\n <mat-option [value]=\"2\">Inactive</mat-option>\n </mat-select>\n <button mat-icon-button matSuffix type=\"button\" *ngIf=\"filterForm.get('status_ids').value\"\n (click)=\"resetFilter('status_ids')\">\n <mat-icon>clear</mat-icon>\n </button>\n </mat-form-field>\n\n </form>\n </mat-card>\n <mat-card appearance=\"outlined\" class=\"p-0 mt-2\">\n <table mat-table matSort [dataSource]=\"models\" class=\"w-100\" infiniteScroll [infiniteScrollDistance]=\"2\"\n [infiniteScrollThrottle]=\"50\" (scrolled)=\"onScroll()\" (matSortChange)=\"sortColumn($event)\">\n\n <ng-container matColumnDef=\"index\">\n <th mat-header-cell *matHeaderCellDef> # </th>\n <td mat-cell *matCellDef=\"let tenantSubscription; let i = index\"> {{ i+1 }} </td>\n </ng-container>\n\n <ng-container matColumnDef=\"tenant\">\n <th mat-header-cell *matHeaderCellDef mat-sort-header disableClear> Tenant </th>\n <td mat-cell *matCellDef=\"let tenantSubscription\">\n <div>\n <div>{{tenantSubscription?.tenant?.name }}</div>\n <div><span>{{tenantSubscription?.tenant?.phone }}</span> <span> |\n {{tenantSubscription?.tenant?.email }}</span></div>\n </div>\n </td>\n </ng-container>\n\n <ng-container matColumnDef=\"period\">\n <th mat-header-cell *matHeaderCellDef mat-sort-header disableClear> Period </th>\n <td mat-cell *matCellDef=\"let tenantSubscription\">\n <span *ngIf=\"tenantSubscription?.started_at\">{{tenantSubscription?.started_at | date:'mediumDate' }}\n -> {{(tenantSubscription?.ended_at | date:'mediumDate') ?? 'NA' }}</span>\n </td>\n </ng-container>\n\n <ng-container matColumnDef=\"package\">\n <th mat-header-cell *matHeaderCellDef> Package </th>\n <td mat-cell *matCellDef=\"let tenantSubscription\">\n <div>{{tenantSubscription?.package?.title }}</div>\n </td>\n </ng-container>\n\n <ng-container matColumnDef=\"status\">\n <th mat-header-cell *matHeaderCellDef> Status </th>\n <td mat-cell *matCellDef=\"let tenantSubscription\">\n <div>{{tenantSubscription?.status?.title }}</div>\n </td>\n </ng-container>\n\n <ng-container matColumnDef=\"cost_per_unit\">\n <th mat-header-cell *matHeaderCellDef> Cost/Units </th>\n <td mat-cell *matCellDef=\"let tenantSubscription\">\n <div>{{tenantSubscription?.cost_per_unit | currency:'USD':'symbol':'1.0-2' }}</div>\n </td>\n </ng-container>\n\n <ng-container matColumnDef=\"units\">\n <th mat-header-cell *matHeaderCellDef> Units </th>\n <td mat-cell *matCellDef=\"let tenantSubscription\">\n <div>{{tenantSubscription?.units | number}}</div>\n </td>\n </ng-container>\n\n <ng-container matColumnDef=\"is_unit_limitation_enforced\">\n <th mat-header-cell *matHeaderCellDef> Is Units Limited </th>\n <td mat-cell *matCellDef=\"let tenantSubscription\">\n <div>{{tenantSubscription?.is_unit_limitation_enforced ? 'Yes' : 'No' }}</div>\n </td>\n </ng-container>\n\n <ng-container matColumnDef=\"total\">\n <th mat-header-cell *matHeaderCellDef> Total Cost </th>\n <td mat-cell *matCellDef=\"let tenantSubscription\">\n <div>{{tenantSubscription?.total | currency:'USD':'symbol':'1.0-2' }}</div>\n </td>\n </ng-container>\n\n <ng-container matColumnDef=\"is_trail\">\n <th mat-header-cell *matHeaderCellDef> Is Trail</th>\n <td mat-cell *matCellDef=\"let tenantSubscription\">\n <div>\n <div>{{tenantSubscription?.is_trail ? 'Yes' : 'No' }}</div>\n <div *ngIf=\"tenantSubscription?.is_trail\"><span>{{tenantSubscription?.trail_started_at |\n date:'mediumDate' }} -> {{tenantSubscription?.trail_ended_at | date:'mediumDate'\n }}</span></div>\n </div>\n </td>\n </ng-container>\n\n\n <ng-container matColumnDef=\"actions\">\n <th mat-header-cell *matHeaderCellDef> Actions </th>\n <td mat-cell *matCellDef=\"let tenantSubscription\">\n <div class=\"text-secondary\" fxLayout>\n <div *ngIf=\"tenantSubscription?.creator_id\">\n <app-subscription-form *ngIf=\"tenantSubscription.status_id == subscriptionStatus.ACTIVE\"\n (success)=\"reload()\" [tenantSubscriptionInfo]=\"tenantSubscription\"\n [subscriptionPackage]=\"subscriptionPackage\"></app-subscription-form>\n <button *ngIf=\"tenantSubscription.status_id == subscriptionStatus.ACTIVE\"\n matTooltip=\"Cancel Subscription\" type=\"button\" mat-icon-button\n (click)=\"cancel(tenantSubscription)\">\n <mat-icon>cancel</mat-icon>\n </button>\n </div>\n </div>\n </td>\n </ng-container>\n\n <tr mat-header-row *matHeaderRowDef=\"displayedColumns\"></tr>\n <tr mat-row *matRowDef=\"let row; columns: displayedColumns;\"></tr>\n </table>\n <mat-progress-bar mode=\"indeterminate\" *ngIf=\"isWorking\"></mat-progress-bar>\n </mat-card>\n</div>", styles: [".add-icon{position:relative;top:5px}.add-icon:hover{cursor:pointer}\n"], dependencies: [{ kind: "directive", type: i3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: i6.MatIconButton, selector: "button[mat-icon-button]", exportAs: ["matButton"] }, { kind: "component", type: i8$4.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i8$4.MatLabel, selector: "mat-label" }, { kind: "directive", type: i8$4.MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { kind: "component", type: i8.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "directive", type: i9.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly"], exportAs: ["matInput"] }, { kind: "component", type: i5.MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "component", type: i9$1.MatSelect, selector: "mat-select", inputs: ["aria-describedby", "panelClass", "disabled", "disableRipple", "tabIndex", "hideSingleSelectionIndicator", "placeholder", "required", "multiple", "disableOptionCentering", "compareWith", "value", "aria-label", "aria-labelledby", "errorStateMatcher", "typeaheadDebounceInterval", "sortComparator", "id", "panelWidth"], outputs: ["openedChange", "opened", "closed", "selectionChange", "valueChange"], exportAs: ["matSelect"] }, { kind: "directive", type: i11.MatSort, selector: "[matSort]", inputs: ["matSortActive", "matSortStart", "matSortDirection", "matSortDisableClear", "matSortDisabled"], outputs: ["matSortChange"], exportAs: ["matSort"] }, { kind: "component", type: i11.MatSortHeader, selector: "[mat-sort-header]", inputs: ["mat-sort-header", "arrowPosition", "start", "disabled", "sortActionDescription", "disableClear"], exportAs: ["matSortHeader"] }, { kind: "component", type: i12.MatTable, selector: "mat-table, table[mat-table]", exportAs: ["matTable"] }, { kind: "directive", type: i12.MatHeaderCellDef, selector: "[matHeaderCellDef]" }, { kind: "directive", type: i12.MatHeaderRowDef, selector: "[matHeaderRowDef]", inputs: ["matHeaderRowDef", "matHeaderRowDefSticky"] }, { kind: "directive", type: i12.MatColumnDef, selector: "[matColumnDef]", inputs: ["matColumnDef"] }, { kind: "directive", type: i12.MatCellDef, selector: "[matCellDef]" }, { kind: "directive", type: i12.MatRowDef, selector: "[matRowDef]", inputs: ["matRowDefColumns", "matRowDefWhen"] }, { kind: "directive", type: i12.MatHeaderCell, selector: "mat-header-cell, th[mat-header-cell]" }, { kind: "directive", type: i12.MatCell, selector: "mat-cell, td[mat-cell]" }, { kind: "component", type: i12.MatHeaderRow, selector: "mat-header-row, tr[mat-header-row]", exportAs: ["matHeaderRow"] }, { kind: "component", type: i12.MatRow, selector: "mat-row, tr[mat-row]", exportAs: ["matRow"] }, { kind: "component", type: i4.MatCard, selector: "mat-card", inputs: ["appearance"], exportAs: ["matCard"] }, { kind: "directive", type: i10.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "component", type: i11$2.MatProgressBar, selector: "mat-progress-bar", inputs: ["color", "value", "bufferValue", "mode"], outputs: ["animationEnd"], exportAs: ["matProgressBar"] }, { kind: "component", type: SearchableSelectorComponent, selector: "app-searchable-selector", inputs: ["valueField", "titleField", "subtitleField", "apiUrl", "multiple", "selectedValue", "enableSearch", "add", "addConfig", "edit", "editConfig", "sort", "sortBy", "searchField", "itemComponent", "items", "apiDataProperty", "cache", "perPage", "inDataSearch", "panelWidth", "focusSearchOnOpen", "isEmitInitialEvent", "required", "disabled", "value"], outputs: ["selectedValueChange", "selectionChange", "itemsChange", "isItemsEmpty"] }, { kind: "directive", type: i1$5.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1$5.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$5.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$5.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1$5.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$5.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "component", type: SubscriptionFormComponent, selector: "app-subscription-form", inputs: ["isUpdate", "subscriptionPackage", "tenantSubscriptionInfo"], outputs: ["success"] }, { kind: "directive", type: i6$1.DefaultLayoutDirective, selector: " [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]", inputs: ["fxLayout", "fxLayout.xs", "fxLayout.sm", "fxLayout.md", "fxLayout.lg", "fxLayout.xl", "fxLayout.lt-sm", "fxLayout.lt-md", "fxLayout.lt-lg", "fxLayout.lt-xl", "fxLayout.gt-xs", "fxLayout.gt-sm", "fxLayout.gt-md", "fxLayout.gt-lg"] }, { kind: "directive", type: i6$1.DefaultLayoutGapDirective, selector: " [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]", inputs: ["fxLayoutGap", "fxLayoutGap.xs", "fxLayoutGap.sm", "fxLayoutGap.md", "fxLayoutGap.lg", "fxLayoutGap.xl", "fxLayoutGap.lt-sm", "fxLayoutGap.lt-md", "fxLayoutGap.lt-lg", "fxLayoutGap.lt-xl", "fxLayoutGap.gt-xs", "fxLayoutGap.gt-sm", "fxLayoutGap.gt-md", "fxLayoutGap.gt-lg"] }, { kind: "directive", type: i6$1.DefaultLayoutAlignDirective, selector: " [fxLayoutAlign], [fxLayoutAlign.xs], [fxLayoutAlign.sm], [fxLayoutAlign.md], [fxLayoutAlign.lg], [fxLayoutAlign.xl], [fxLayoutAlign.lt-sm], [fxLayoutAlign.lt-md], [fxLayoutAlign.lt-lg], [fxLayoutAlign.lt-xl], [fxLayoutAlign.gt-xs], [fxLayoutAlign.gt-sm], [fxLayoutAlign.gt-md], [fxLayoutAlign.gt-lg]", inputs: ["fxLayoutAlign", "fxLayoutAlign.xs", "fxLayoutAlign.sm", "fxLayoutAlign.md", "fxLayoutAlign.lg", "fxLayoutAlign.xl", "fxLayoutAlign.lt-sm", "fxLayoutAlign.lt-md", "fxLayoutAlign.lt-lg", "fxLayoutAlign.lt-xl", "fxLayoutAlign.gt-xs", "fxLayoutAlign.gt-sm", "fxLayoutAlign.gt-md", "fxLayoutAlign.gt-lg"] }, { kind: "directive", type: i6$1.DefaultFlexDirective, selector: " [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]", inputs: ["fxFlex", "fxFlex.xs", "fxFlex.sm", "fxFlex.md", "fxFlex.lg", "fxFlex.xl", "fxFlex.lt-sm", "fxFlex.lt-md", "fxFlex.lt-lg", "fxFlex.lt-xl", "fxFlex.gt-xs", "fxFlex.gt-sm", "fxFlex.gt-md", "fxFlex.gt-lg"] }, { kind: "directive", type: i6$2.InfiniteScrollDirective, selector: "[infiniteScroll], [infinite-scroll], [data-infinite-scroll]", inputs: ["infiniteScrollDistance", "infiniteScrollUpDistance", "infiniteScrollThrottle", "infiniteScrollDisabled", "infiniteScrollContainer", "scrollWindow", "immediateCheck", "horizontal", "alwaysCallback", "fromRoot"], outputs: ["scrolled", "scrolledUp"] }, { kind: "component", type: TimelineFilterComponent, selector: "app-timeline-filter", inputs: ["defaultValue", "required", "disabled", "value", "timelines", "dateFrom", "dateTo", "appearance", "showClearButton", "form", "labelText"], outputs: ["selectionChange"] }, { kind: "pipe", type: i3.DecimalPipe, name: "number" }, { kind: "pipe", type: i3.CurrencyPipe, name: "currency" }, { kind: "pipe", type: i3.DatePipe, name: "date" }] }); }
15088
15106
  };
15089
15107
  SubscriptionListingComponent = __decorate([
15090
15108
  UntilDestroy()
@@ -16572,40 +16590,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
16572
16590
  }]
16573
16591
  }] });
16574
16592
 
16575
- class UserTenantAcceptInvitationService extends TechlifyService {
16576
- constructor(http) {
16577
- super(http, 'user-tenant-accept-invitation');
16578
- }
16579
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: UserTenantAcceptInvitationService, deps: [{ token: HttpService }], target: i0.ɵɵFactoryTarget.Injectable }); }
16580
- static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: UserTenantAcceptInvitationService, providedIn: 'root' }); }
16581
- }
16582
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: UserTenantAcceptInvitationService, decorators: [{
16583
- type: Injectable,
16584
- args: [{
16585
- providedIn: 'root'
16586
- }]
16587
- }], ctorParameters: () => [{ type: HttpService }] });
16588
-
16589
- class UserTenantAcceptInvitationComponent {
16590
- constructor(activatedRoute, userTenantAcceptInvitationService) {
16591
- this.activatedRoute = activatedRoute;
16592
- this.userTenantAcceptInvitationService = userTenantAcceptInvitationService;
16593
- }
16594
- ngOnInit() {
16595
- this.activatedRoute.paramMap.pipe(switchMap$1((paramMap) => {
16596
- this.invitationCode = paramMap.get('invitationCode');
16597
- return this.userTenantAcceptInvitationService.show(this.invitationCode);
16598
- }))
16599
- .subscribe((res) => this.userTenant = res?.item);
16600
- }
16601
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: UserTenantAcceptInvitationComponent, deps: [{ token: i1$2.ActivatedRoute }, { token: UserTenantAcceptInvitationService }], target: i0.ɵɵFactoryTarget.Component }); }
16602
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.14", type: UserTenantAcceptInvitationComponent, isStandalone: true, selector: "app-user-tenant-accept-invitation", ngImport: i0, template: "<div *ngIf=\"!userTenant\" class=\"jumbotron-primary container mt-4\">\n <p class=\"mb-0\">\n We are working on adding you to the company.\n </p>\n</div>\n\n<div class=\"jumbotron-success container mt-4\" *ngIf=\"userTenant\">\n <p class=\"mb-0\">\n You have accepted the invitation and are now able to access {{userTenant?.tenant?.name}} via your user menu.\n </p>\n</div>", styles: [".jumbotron-primary{padding:2rem;margin-bottom:1.5rem;border-radius:.5rem;background:#e7f1ff;border:1px solid #b6d4fe;color:#084298}.jumbotron-success{padding:2rem;margin-bottom:1.5rem;border-radius:.5rem;background:#d1e7dd;border:1px solid #a3cfbb;color:#0f5132}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }] }); }
16603
- }
16604
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: UserTenantAcceptInvitationComponent, decorators: [{
16605
- type: Component,
16606
- args: [{ selector: 'app-user-tenant-accept-invitation', standalone: true, imports: [CommonModule], template: "<div *ngIf=\"!userTenant\" class=\"jumbotron-primary container mt-4\">\n <p class=\"mb-0\">\n We are working on adding you to the company.\n </p>\n</div>\n\n<div class=\"jumbotron-success container mt-4\" *ngIf=\"userTenant\">\n <p class=\"mb-0\">\n You have accepted the invitation and are now able to access {{userTenant?.tenant?.name}} via your user menu.\n </p>\n</div>", styles: [".jumbotron-primary{padding:2rem;margin-bottom:1.5rem;border-radius:.5rem;background:#e7f1ff;border:1px solid #b6d4fe;color:#084298}.jumbotron-success{padding:2rem;margin-bottom:1.5rem;border-radius:.5rem;background:#d1e7dd;border:1px solid #a3cfbb;color:#0f5132}\n"] }]
16607
- }], ctorParameters: () => [{ type: i1$2.ActivatedRoute }, { type: UserTenantAcceptInvitationService }] });
16608
-
16609
16593
  /*
16610
16594
  * Public API Surface of ngx-techlify-core
16611
16595
  */
@@ -16614,5 +16598,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
16614
16598
  * Generated bundle index. Do not edit.
16615
16599
  */
16616
16600
 
16617
- export { AccessControlConfigModule, ActionPopup, ActionPopupComponent, ActionPopupModule, AdminRoleListComponent, AdminRoleListModule, AdminRolePermissionFormComponent, AdminRolePermissionFormModule, AdminRoleService, AlertService, ApiPrefixInterceptor, AppAdminHomeComponent, AppAdminModule, AppAdminUserViewComponent, AppAdminUserViewModule, AuditLogForModelComponent, AuditLogForModelModule, AuditLogForModelRoutingModule, AuditLogListComponent, AuditLogListFilterComponent, AuditLogListFilterModule, AuditLogListFilterRoutingModule, AuditLogListModule, AuditLogListRoutingModule, AuditLogModule, AuditLogRoutingModule, AuditLogViewComponent, AuditLogViewModelComponent, AuditLogViewModelModule, AuditLogViewModelRoutingModule, AuditLogViewModule, AuditLogViewRoutingModule, AuditLogsViewModelComponent, AuditLogsViewModelModule, AuditLogsViewModelRoutingModule, AuthenticationGuard, AuthenticationService, CacheInterceptor, ChangePasswordModule, ClientService, ColumnConfig, ColumnSelectorComponent, ColumnSelectorModule, CommentFormComponent, CompanyInfoDisplayComponent, CompanyInformationComponent, ConfigService, CoreModule, CredentialsService, CurrentUserService, CustomIconComponent, CustomIconModule, DEFAULT_SELECTED_VALUE, DataManager, DataTable, DataTableComponent, DataTableModule, DateUtils, DocumentViewerComponent, DocumentViewerModule, EmailSubscriptionForUserComponent, EmailSubscriptionForUserModule, EmailSubscriptionForUserRoutingModule, EmailSubscriptionModule, EmailSubscriptionRoutingModule, EmailSubscriptionTypeFormComponent, EmailSubscriptionTypeFormModule, EmailSubscriptionTypeFormRoutingModule, EmailSubscriptionTypeListComponent, EmailSubscriptionTypeListModule, EmailSubscriptionTypeListRoutingModule, EmailSubscriptionTypeModule, EmailSubscriptionTypeRoutingModule, EmailSubscriptionUserFormComponent, EmailSubscriptionUserFormModule, EmailSubscriptionUserFormRoutingModule, EmailSubscriptionUserListComponent, EmailSubscriptionUserListFilterComponent, EmailSubscriptionUserListFilterModule, EmailSubscriptionUserListFilterRoutingModule, EmailSubscriptionUserListModule, EmailSubscriptionUserListRoutingModule, EmailSubscriptionUserModule, EmailSubscriptionUserRoutingModule, EntityFileFormComponent, EntityFileListComponent, EntityFileListModule, EntityFileService, EntityFileListModule as EntityFilesViewAllModule, EnvironmentService, ErrorHandlerInterceptor, ErrorHandlerService, ErrorSnackComponent, ExportExcelButtonComponent, ExportExcelModule, FileDragdropUploaderComponent, FileDragdropUploaderModule, FileDropperComponent, FileDropperConfig, FileDropperModule, FilterService, ForgotPasswordComponent, ForgotPasswordModule, ForgotPasswordRoutingModule, FormConfigurationFieldFormComponent, FormConfigurationFieldFormModule, FormConfigurationFieldFormRoutingModule, FormConfigurationForFormComponent, FormConfigurationForFormModule, FormConfigurationFormFieldService, FormConfigurationFormService, FormConfigurationUtilityService, FormValidatorService, HTTP_DYNAMIC_INTERCEPTORS, HttpCacheService, HttpService, ImportCsvComponent, ImportCsvModule, LoaderComponent, LoaderModule, LockedDate, LockedDateFormComponent, LockedDateListComponent, LockedDateLockUnlockButtonComponent, LockedDateModule, LockedDateService, LogLevel, Logger, LoginComponent, LoginFormFieldsComponent, LoginHistoryForUserComponent, LoginHistoryForUserModule, LoginHistoryForUserRoutingModule, LoginModule, LoginRoutingModule, MaterialModule, MultiUserConfig, MyTechlifyViewListingComponent, MyTechlifyViewListingModule, MyTechlifyViewService, NgxTechlifyUsersModule, NoteFormComponent, NoteListComponent, NoteModule, NumItemsSelector, NumberInputButtonComponent, NumberInputButtonModule, NumberSelector, PageEvent, PdfButtonComponent, PdfButtonModule, Permission, PermissionModule, PermissionRoutingProvider, PermissionsManagementComponent, ProfileEditComponent, ProfileModule, ProfileRoutingModule, ReadMoreComponent, ReadMoreModule, RequestHelperService, ResetPasswordComponent, ResetPasswordModule, ResetPasswordRoutingModule, ResetPasswordService, RestrictorTypeSelectorComponent, RestrictorTypeSelectorModule, RestrictorsModule, Role, RoleFormButtonComponent, RoleFormComponent, RoleListComponent, RoleModule, RoleRoutingProvider, RoleService, RoleViewComponent, RoleViewModule, RouteReusableStrategy, SearchableSelectorComponent, SearchableSelectorModule, SignUpComponent, SignupModule, SignupRoutingModule, SnackModule, StorageService, SubscriptionFormComponent, SubscriptionFormModule, SubscriptionListingComponent, SubscriptionListingModule, SubscriptionPackageListingComponent, SubscriptionPackageListingModule, SubscriptionPackageViewComponent, SubscriptionPackageViewModule, SubscriptionService, SuccessSnackComponent, TagService, TechlifyAppSelectorComponent, TechlifyAppSelectorModule, TechlifyAutoCompleteSelectComponent, TechlifyCompanySwitcherComponent, TechlifyCompanySwitcherModule, TechlifyConfig, TechlifyCurrencyPipe, TechlifyDeleteButtonComponent, TechlifyFeatureDirectiveModule, TechlifyFeatureEnabledDirective, TechlifyFeatureListingComponent, TechlifyFeatureModule, TechlifyFeatureRoutes, TechlifyFeatureService, TechlifyFormButtonComponent, TechlifyFormComponent, TechlifyIconComponent, TechlifyIconModule, TechlifyListComponent, TechlifyNotificationForUserComponent, TechlifyNotificationForUserModule, TechlifyNotificationForUserRoutingModule, TechlifyNotificationModule, TechlifyNotificationRoutingModule, TechlifyService, TechlifySubscriptionDirective, TechlifySubscriptionDirectiveModule, TechlifyTaggerTagFormComponent, TechlifyTaggerTagFormConfigModel, TechlifyTaggerTagFormFieldComponent, TechlifyTaggerTagFormFieldModule, TechlifyTaggerTagListComponent, TechlifyTaggerTagSelectorComponent, TechlifyTaggerTagSelectorModule, TechlifyUpdateHistoryModule, TechlifyUpdateModule, TechlifyUpdateService, TechlifyUpdatesTeaserComponent, TechlifyUpdatesTeaserModule, TechlifyViewFormComponent, TechlifyViewFormModule, TechlifyViewService, TenantFormButtonComponent, TenantListWidgetComponent, Timeline, TimelineActivityButtonComponent, TimelineActivityButtonModule, TimelineActivityListComponent, TimelineActivityListModule, TimelineFilterComponent, TimelineFilterModule, TokenInterceptor, UpdateNotifierComponent, UpdateNotifierModule, User, UserClientEnableDisableButtonComponent, UserClientEnableDisableButtonModule, UserClientsListComponent, UserClientsListModule, UserConfig, UserConfigService, UserDataService, UserEnableButtonComponent, UserEnableButtonModule, UserExploreComponent, UserFormComponent, UserListPageConfig, UserMenuComponent, UserMenuModule, UserModule, UserRoutingProvider, UserSelectorComponent, UserSelectorModule, UserService, UserSessionsComponent, UserSessionsModule, UserTenantAcceptInvitationComponent, UserTenantAcceptInvitationService, UserViewComponent, UsersViewAllComponent, UtilityModule, ViewerConfig, WrapPipe, calculateTimeline, dateValidator, esfur, estlr, esulr, parseLocalDate, techlifyFormContract, techlifyListContract };
16601
+ export { AccessControlConfigModule, ActionPopup, ActionPopupComponent, ActionPopupModule, AdminRoleListComponent, AdminRoleListModule, AdminRolePermissionFormComponent, AdminRolePermissionFormModule, AdminRoleService, AlertService, ApiPrefixInterceptor, AppAdminHomeComponent, AppAdminModule, AppAdminUserViewComponent, AppAdminUserViewModule, AuditLogForModelComponent, AuditLogForModelModule, AuditLogForModelRoutingModule, AuditLogListComponent, AuditLogListFilterComponent, AuditLogListFilterModule, AuditLogListFilterRoutingModule, AuditLogListModule, AuditLogListRoutingModule, AuditLogModule, AuditLogRoutingModule, AuditLogViewComponent, AuditLogViewModelComponent, AuditLogViewModelModule, AuditLogViewModelRoutingModule, AuditLogViewModule, AuditLogViewRoutingModule, AuditLogsViewModelComponent, AuditLogsViewModelModule, AuditLogsViewModelRoutingModule, AuthenticationGuard, AuthenticationService, CacheInterceptor, ChangePasswordModule, ClientService, ColumnConfig, ColumnSelectorComponent, ColumnSelectorModule, CommentFormComponent, CompanyInfoDisplayComponent, CompanyInformationComponent, ConfigService, CoreModule, CredentialsService, CurrentUserService, CustomIconComponent, CustomIconModule, DEFAULT_SELECTED_VALUE, DataManager, DataTable, DataTableComponent, DataTableModule, DateUtils, DocumentViewerComponent, DocumentViewerModule, EmailSubscriptionForUserComponent, EmailSubscriptionForUserModule, EmailSubscriptionForUserRoutingModule, EmailSubscriptionModule, EmailSubscriptionRoutingModule, EmailSubscriptionTypeFormComponent, EmailSubscriptionTypeFormModule, EmailSubscriptionTypeFormRoutingModule, EmailSubscriptionTypeListComponent, EmailSubscriptionTypeListModule, EmailSubscriptionTypeListRoutingModule, EmailSubscriptionTypeModule, EmailSubscriptionTypeRoutingModule, EmailSubscriptionUserFormComponent, EmailSubscriptionUserFormModule, EmailSubscriptionUserFormRoutingModule, EmailSubscriptionUserListComponent, EmailSubscriptionUserListFilterComponent, EmailSubscriptionUserListFilterModule, EmailSubscriptionUserListFilterRoutingModule, EmailSubscriptionUserListModule, EmailSubscriptionUserListRoutingModule, EmailSubscriptionUserModule, EmailSubscriptionUserRoutingModule, EntityFileFormComponent, EntityFileListComponent, EntityFileListModule, EntityFileService, EntityFileListModule as EntityFilesViewAllModule, EnvironmentService, ErrorHandlerInterceptor, ErrorHandlerService, ErrorSnackComponent, ExportExcelButtonComponent, ExportExcelModule, FileDragdropUploaderComponent, FileDragdropUploaderModule, FileDropperComponent, FileDropperConfig, FileDropperModule, FilterService, ForgotPasswordComponent, ForgotPasswordModule, ForgotPasswordRoutingModule, FormConfigurationFieldFormComponent, FormConfigurationFieldFormModule, FormConfigurationFieldFormRoutingModule, FormConfigurationForFormComponent, FormConfigurationForFormModule, FormConfigurationFormFieldService, FormConfigurationFormService, FormConfigurationUtilityService, FormValidatorService, HTTP_DYNAMIC_INTERCEPTORS, HttpCacheService, HttpService, ImportCsvComponent, ImportCsvModule, LoaderComponent, LoaderModule, LockedDate, LockedDateFormComponent, LockedDateListComponent, LockedDateLockUnlockButtonComponent, LockedDateModule, LockedDateService, LogLevel, Logger, LoginComponent, LoginFormFieldsComponent, LoginHistoryForUserComponent, LoginHistoryForUserModule, LoginHistoryForUserRoutingModule, LoginModule, LoginRoutingModule, MaterialModule, MultiUserConfig, MyTechlifyViewListingComponent, MyTechlifyViewListingModule, MyTechlifyViewService, NgxTechlifyUsersModule, NoteFormComponent, NoteListComponent, NoteModule, NumItemsSelector, NumberInputButtonComponent, NumberInputButtonModule, NumberSelector, PageEvent, PdfButtonComponent, PdfButtonModule, Permission, PermissionModule, PermissionRoutingProvider, PermissionsManagementComponent, ProfileEditComponent, ProfileModule, ProfileRoutingModule, ReadMoreComponent, ReadMoreModule, RequestHelperService, ResetPasswordComponent, ResetPasswordModule, ResetPasswordRoutingModule, ResetPasswordService, RestrictorTypeSelectorComponent, RestrictorTypeSelectorModule, RestrictorsModule, Role, RoleFormButtonComponent, RoleFormComponent, RoleListComponent, RoleModule, RoleRoutingProvider, RoleService, RoleViewComponent, RoleViewModule, RouteReusableStrategy, SearchableSelectorComponent, SearchableSelectorModule, SignUpComponent, SignupModule, SignupRoutingModule, SnackModule, StorageService, SubscriptionFormComponent, SubscriptionFormModule, SubscriptionListingComponent, SubscriptionListingModule, SubscriptionPackageListingComponent, SubscriptionPackageListingModule, SubscriptionPackageViewComponent, SubscriptionPackageViewModule, SubscriptionService, SuccessSnackComponent, TagService, TechlifyAppSelectorComponent, TechlifyAppSelectorModule, TechlifyAutoCompleteSelectComponent, TechlifyCompanySwitcherComponent, TechlifyCompanySwitcherModule, TechlifyConfig, TechlifyCurrencyPipe, TechlifyDeleteButtonComponent, TechlifyFeatureDirectiveModule, TechlifyFeatureEnabledDirective, TechlifyFeatureListingComponent, TechlifyFeatureModule, TechlifyFeatureRoutes, TechlifyFeatureService, TechlifyFormButtonComponent, TechlifyFormComponent, TechlifyIconComponent, TechlifyIconModule, TechlifyListComponent, TechlifyNotificationForUserComponent, TechlifyNotificationForUserModule, TechlifyNotificationForUserRoutingModule, TechlifyNotificationModule, TechlifyNotificationRoutingModule, TechlifyService, TechlifySubscriptionDirective, TechlifySubscriptionDirectiveModule, TechlifyTaggerTagFormComponent, TechlifyTaggerTagFormConfigModel, TechlifyTaggerTagFormFieldComponent, TechlifyTaggerTagFormFieldModule, TechlifyTaggerTagListComponent, TechlifyTaggerTagSelectorComponent, TechlifyTaggerTagSelectorModule, TechlifyUpdateHistoryModule, TechlifyUpdateModule, TechlifyUpdateService, TechlifyUpdatesTeaserComponent, TechlifyUpdatesTeaserModule, TechlifyViewFormComponent, TechlifyViewFormModule, TechlifyViewService, TenantFormButtonComponent, TenantListWidgetComponent, Timeline, TimelineActivityButtonComponent, TimelineActivityButtonModule, TimelineActivityListComponent, TimelineActivityListModule, TimelineFilterComponent, TimelineFilterModule, TokenInterceptor, UpdateNotifierComponent, UpdateNotifierModule, User, UserClientEnableDisableButtonComponent, UserClientEnableDisableButtonModule, UserClientsListComponent, UserClientsListModule, UserConfig, UserConfigService, UserDataService, UserEnableButtonComponent, UserEnableButtonModule, UserExploreComponent, UserFormComponent, UserListPageConfig, UserMenuComponent, UserMenuModule, UserModule, UserRoutingProvider, UserSelectorComponent, UserSelectorModule, UserService, UserSessionsComponent, UserSessionsModule, UserViewComponent, UsersViewAllComponent, UtilityModule, ViewerConfig, WrapPipe, calculateTimeline, dateValidator, esfur, estlr, esulr, parseLocalDate, techlifyFormContract, techlifyListContract };
16618
16602
  //# sourceMappingURL=ngx-techlify-core.mjs.map