ngx-techlify-core 18.57.0 → 18.58.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.
Files changed (107) hide show
  1. package/esm2022/lib/access-control-config/access-control-config.service.mjs +3 -3
  2. package/esm2022/lib/app-admin/admin-role/admin-role-list/admin-role-list.component.mjs +3 -3
  3. package/esm2022/lib/app-admin/admin-role/admin-role-permission-form/admin-role-permission-form.component.mjs +3 -3
  4. package/esm2022/lib/app-admin/admin-role/admin-role.service.mjs +3 -3
  5. package/esm2022/lib/app-admin/tenant/tenant-list-widget/tenant-list-widget.component.mjs +3 -3
  6. package/esm2022/lib/audit-log/audit-log-list/audit-log-list.component.mjs +35 -94
  7. package/esm2022/lib/audit-log/audit-log-list-filter/audit-log-list-filter.component.mjs +3 -12
  8. package/esm2022/lib/audit-log/audit-log.service.mjs +3 -3
  9. package/esm2022/lib/base-model/index.mjs +4 -4
  10. package/esm2022/lib/base-model/techlify-form-component.mjs +128 -0
  11. package/esm2022/lib/base-model/techlify-list-component.mjs +289 -0
  12. package/esm2022/lib/base-model/techlify-service.mjs +68 -0
  13. package/esm2022/lib/company-information/client.service.mjs +3 -3
  14. package/esm2022/lib/company-information/company-information/company-information.component.mjs +3 -3
  15. package/esm2022/lib/delete-button/techlify-delete-button.component.mjs +1 -1
  16. package/esm2022/lib/entity-files/entity-file.service.mjs +3 -3
  17. package/esm2022/lib/form-configuration/form-configuration-form-field.service.mjs +3 -3
  18. package/esm2022/lib/form-configuration/form-configuration-form.service.mjs +3 -3
  19. package/esm2022/lib/login/login-form-fields/login-form-fields.component.mjs +3 -3
  20. package/esm2022/lib/note/note-list/note-list.component.mjs +3 -3
  21. package/esm2022/lib/pdf-button/pdf-button.component.mjs +11 -7
  22. package/esm2022/lib/reset-password/reset-password.component.mjs +3 -3
  23. package/esm2022/lib/reset-password/reset-password.service.mjs +3 -3
  24. package/esm2022/lib/restrictors/restrictor-level-selector/restrictor-level.service.mjs +3 -3
  25. package/esm2022/lib/restrictors/restrictor-status-selector/restrictor-status.service.mjs +3 -3
  26. package/esm2022/lib/restrictors/restrictor-type-selector/restrictor-type.service.mjs +3 -3
  27. package/esm2022/lib/restrictors/restrictor.service.mjs +3 -3
  28. package/esm2022/lib/searchable-selector/searchable-selector.component.mjs +7 -7
  29. package/esm2022/lib/subscription/subscription-form/subscription-form.component.mjs +3 -3
  30. package/esm2022/lib/subscription/subscription-listing/subscription-listing.component.mjs +3 -3
  31. package/esm2022/lib/subscription/subscription-package-listing/subscription-package-listing.component.mjs +3 -3
  32. package/esm2022/lib/subscription/subscription-package.service.mjs +3 -3
  33. package/esm2022/lib/subscription/subscription.service.mjs +3 -3
  34. package/esm2022/lib/techlify-feature/techlify-feature.service.mjs +3 -3
  35. package/esm2022/lib/techlify-icon/techlify-icon.component.mjs +7 -2
  36. package/esm2022/lib/techlify-notifications/techlify-notification-for-user/techlify-notification-for-user.component.mjs +3 -3
  37. package/esm2022/lib/techlify-notifications/techlify-notification-for-user/techlify-notification-subscription.service.mjs +3 -3
  38. package/esm2022/lib/techlify-notifications/techlify-notification-for-user/techlify-notification-type.service.mjs +3 -3
  39. package/esm2022/lib/techlify-view/my-techlify-view-listing/my-techlify-view-listing.component.mjs +3 -3
  40. package/esm2022/lib/techlify-view/my-techlify-view-listing/my-techlify-view.service.mjs +3 -3
  41. package/esm2022/lib/techlify-view/techlify-view-form/techlify-view-form.component.mjs +3 -3
  42. package/esm2022/lib/techlify-view/techlify-view.service.mjs +3 -3
  43. package/esm2022/lib/timeline-activity/timeline-activity-list/timeline-activity-list.component.mjs +3 -3
  44. package/esm2022/lib/timeline-activity/timeline-activity.service.mjs +3 -3
  45. package/esm2022/lib/user/user-enable-button-component/user-enable-button.component.mjs +5 -5
  46. package/esm2022/lib/user/user-enable-button-component/user-enable-button.module.mjs +7 -3
  47. package/esm2022/lib/user/user-sessions/user-session.service.mjs +3 -3
  48. package/esm2022/lib/user/user-sessions/user-sessions/user-sessions.component.mjs +3 -3
  49. package/esm2022/lib/user/user.service.mjs +3 -3
  50. package/esm2022/lib/user/users-view-all.component.mjs +3 -3
  51. package/esm2022/lib/user-clients-list/user-client.service.mjs +3 -3
  52. package/esm2022/lib/user-clients-list/user-clients-list.component.mjs +3 -3
  53. package/fesm2022/ngx-techlify-core.mjs +199 -243
  54. package/fesm2022/ngx-techlify-core.mjs.map +1 -1
  55. package/lib/access-control-config/access-control-config.service.d.ts +2 -2
  56. package/lib/app-admin/admin-role/admin-role-list/admin-role-list.component.d.ts +2 -2
  57. package/lib/app-admin/admin-role/admin-role-permission-form/admin-role-permission-form.component.d.ts +2 -2
  58. package/lib/app-admin/admin-role/admin-role.service.d.ts +2 -2
  59. package/lib/app-admin/tenant/tenant-list-widget/tenant-list-widget.component.d.ts +2 -2
  60. package/lib/audit-log/audit-log-list/audit-log-list.component.d.ts +7 -11
  61. package/lib/audit-log/audit-log-list-filter/audit-log-list-filter.component.d.ts +0 -2
  62. package/lib/audit-log/audit-log.service.d.ts +2 -2
  63. package/lib/base-model/index.d.ts +3 -3
  64. package/lib/base-model/{techlify-form-component.class.d.ts → techlify-form-component.d.ts} +7 -6
  65. package/lib/base-model/{techlify-listing-component.class.d.ts → techlify-list-component.d.ts} +6 -6
  66. package/lib/base-model/{techlify-service.class.d.ts → techlify-service.d.ts} +1 -1
  67. package/lib/company-information/client.service.d.ts +2 -2
  68. package/lib/company-information/company-information/company-information.component.d.ts +2 -2
  69. package/lib/delete-button/techlify-delete-button.component.d.ts +2 -2
  70. package/lib/entity-files/entity-file.service.d.ts +2 -2
  71. package/lib/form-configuration/form-configuration-form-field.service.d.ts +2 -2
  72. package/lib/form-configuration/form-configuration-form.service.d.ts +2 -2
  73. package/lib/login/login-form-fields/login-form-fields.component.d.ts +2 -2
  74. package/lib/note/note-list/note-list.component.d.ts +2 -2
  75. package/lib/pdf-button/pdf-button.component.d.ts +2 -1
  76. package/lib/reset-password/reset-password.component.d.ts +2 -2
  77. package/lib/reset-password/reset-password.service.d.ts +2 -2
  78. package/lib/restrictors/restrictor-level-selector/restrictor-level.service.d.ts +2 -2
  79. package/lib/restrictors/restrictor-status-selector/restrictor-status.service.d.ts +2 -2
  80. package/lib/restrictors/restrictor-type-selector/restrictor-type.service.d.ts +2 -2
  81. package/lib/restrictors/restrictor.service.d.ts +2 -2
  82. package/lib/subscription/subscription-form/subscription-form.component.d.ts +2 -2
  83. package/lib/subscription/subscription-listing/subscription-listing.component.d.ts +2 -2
  84. package/lib/subscription/subscription-package-listing/subscription-package-listing.component.d.ts +2 -2
  85. package/lib/subscription/subscription-package.service.d.ts +2 -2
  86. package/lib/subscription/subscription.service.d.ts +2 -2
  87. package/lib/techlify-feature/techlify-feature.service.d.ts +2 -2
  88. package/lib/techlify-notifications/techlify-notification-for-user/techlify-notification-for-user.component.d.ts +2 -2
  89. package/lib/techlify-notifications/techlify-notification-for-user/techlify-notification-subscription.service.d.ts +2 -2
  90. package/lib/techlify-notifications/techlify-notification-for-user/techlify-notification-type.service.d.ts +2 -2
  91. package/lib/techlify-view/my-techlify-view-listing/my-techlify-view-listing.component.d.ts +2 -2
  92. package/lib/techlify-view/my-techlify-view-listing/my-techlify-view.service.d.ts +2 -2
  93. package/lib/techlify-view/techlify-view-form/techlify-view-form.component.d.ts +2 -2
  94. package/lib/techlify-view/techlify-view.service.d.ts +2 -2
  95. package/lib/timeline-activity/timeline-activity-list/timeline-activity-list.component.d.ts +2 -2
  96. package/lib/timeline-activity/timeline-activity.service.d.ts +2 -2
  97. package/lib/user/user-enable-button-component/user-enable-button.module.d.ts +2 -1
  98. package/lib/user/user-sessions/user-session.service.d.ts +2 -2
  99. package/lib/user/user-sessions/user-sessions/user-sessions.component.d.ts +2 -2
  100. package/lib/user/user.service.d.ts +2 -2
  101. package/lib/user/users-view-all.component.d.ts +2 -2
  102. package/lib/user-clients-list/user-client.service.d.ts +2 -2
  103. package/lib/user-clients-list/user-clients-list.component.d.ts +2 -2
  104. package/package.json +1 -1
  105. package/esm2022/lib/base-model/techlify-form-component.class.mjs +0 -119
  106. package/esm2022/lib/base-model/techlify-listing-component.class.mjs +0 -289
  107. package/esm2022/lib/base-model/techlify-service.class.mjs +0 -68
@@ -0,0 +1,128 @@
1
+ import { Directive, EventEmitter, inject, Input, Optional, Output } from '@angular/core';
2
+ import { finalize } from 'rxjs';
3
+ import { AlertService } from '../core/alert.service';
4
+ import * as i0 from "@angular/core";
5
+ import * as i1 from "../core/form-validator.service";
6
+ import * as i2 from "./techlify-service";
7
+ /**
8
+ * Interface used to ensure we have a consistent structure across our form components
9
+ *
10
+ * It also provides some abstraction of repeated code to reduce our codebase size
11
+ *
12
+ * @todo This should be moved to ngx-techlify-core
13
+ *
14
+ * Advantages of this abstract class
15
+ * - Less code, less maintenance, less bugs
16
+ * - more consistent code
17
+ * - comments on more code
18
+ * - save time, save energy
19
+ */
20
+ export class TechlifyFormComponent {
21
+ constructor(formValidatorService, service) {
22
+ this.formValidatorService = formValidatorService;
23
+ this.service = service;
24
+ //Boolean to denote the form is in API progress
25
+ this.isWorking = false;
26
+ //Array of created multiple entries
27
+ this.createdEntries = [];
28
+ //Boolean to denote if form is in update mode
29
+ this.isUpdate = false;
30
+ //Boolean to denote if form has ability to create multiple entries
31
+ this.isAllowCreateAnother = true;
32
+ //Emits an event once form submit is success
33
+ this.success = new EventEmitter();
34
+ //Injected alert service
35
+ this.alertService = inject(AlertService, { optional: true });
36
+ }
37
+ /**
38
+ * Submits the form
39
+ * @param model form model optional, if needed to be overriden
40
+ * @returns
41
+ */
42
+ submit(model) {
43
+ this.form.markAllAsTouched();
44
+ if (!this.service) {
45
+ throw new Error(`${this.constructor.name}: Service is required to submit the form`);
46
+ }
47
+ if (!this.form.valid) {
48
+ return;
49
+ }
50
+ if (!model) {
51
+ model = this.form.value;
52
+ }
53
+ this.isWorking = true;
54
+ (this.isUpdate ?
55
+ this.service.update(model) :
56
+ this.service.store(model))
57
+ .pipe(finalize(() => this.isWorking = false))
58
+ .subscribe((res) => {
59
+ this.createdEntries.unshift(res?.item);
60
+ if (model?.is_create_another) {
61
+ this.alertService.addAlert('Successfully Created', 'success');
62
+ return;
63
+ }
64
+ if (this.isUpdate) {
65
+ this.success.emit(res?.item);
66
+ }
67
+ else {
68
+ this.success.emit((this.createdEntries.length == 1) ? this.createdEntries[0] : this.createdEntries);
69
+ }
70
+ if (this.dialogRef) {
71
+ this.dialogRef.close(res.item);
72
+ }
73
+ });
74
+ }
75
+ /**
76
+ * Close the active dialog
77
+ */
78
+ closeDialog() {
79
+ if (this.createdEntries?.length > 0) {
80
+ this.success.emit(this.createdEntries);
81
+ }
82
+ this.dialogRef.close();
83
+ }
84
+ /**
85
+ * Resets the value of a field in the HTML form
86
+ *
87
+ * @param event
88
+ * @param field
89
+ */
90
+ resetFieldValue(event, field) {
91
+ this.form?.get(field)?.setValue('');
92
+ }
93
+ /**
94
+ * Retrieves the value of a field from the HTML form
95
+ *
96
+ * @param field
97
+ * @returns
98
+ */
99
+ getFieldValue(field) {
100
+ return this.form?.get(field)?.value;
101
+ }
102
+ /**
103
+ * Method to evaluate form fields
104
+ * */
105
+ isFieldValid(field) {
106
+ return this.formValidatorService.isFieldValid(field, this.form);
107
+ }
108
+ /**
109
+ * Method to find error in form fields
110
+ * */
111
+ getErrorMessage(field) {
112
+ return this.formValidatorService.getErrorMessage(field, this.form, this.errorMessages);
113
+ }
114
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: TechlifyFormComponent, deps: [{ token: i1.FormValidatorService }, { token: i2.TechlifyService, optional: true }], target: i0.ɵɵFactoryTarget.Directive }); }
115
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "18.2.14", type: TechlifyFormComponent, inputs: { isUpdate: "isUpdate", isAllowCreateAnother: "isAllowCreateAnother" }, outputs: { success: "success" }, ngImport: i0 }); }
116
+ }
117
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: TechlifyFormComponent, decorators: [{
118
+ type: Directive
119
+ }], ctorParameters: () => [{ type: i1.FormValidatorService }, { type: i2.TechlifyService, decorators: [{
120
+ type: Optional
121
+ }] }], propDecorators: { isUpdate: [{
122
+ type: Input
123
+ }], isAllowCreateAnother: [{
124
+ type: Input
125
+ }], success: [{
126
+ type: Output
127
+ }] } });
128
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGVjaGxpZnktZm9ybS1jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9uZ3gtdGVjaGxpZnktY29yZS9zcmMvbGliL2Jhc2UtbW9kZWwvdGVjaGxpZnktZm9ybS1jb21wb25lbnQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBRUEsT0FBTyxFQUFFLFNBQVMsRUFBRSxZQUFZLEVBQUUsTUFBTSxFQUFFLEtBQUssRUFBRSxRQUFRLEVBQUUsTUFBTSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBRXpGLE9BQU8sRUFBRSxRQUFRLEVBQUUsTUFBTSxNQUFNLENBQUM7QUFFaEMsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLHVCQUF1QixDQUFDOzs7O0FBRXJEOzs7Ozs7Ozs7Ozs7R0FZRztBQUVILE1BQU0sT0FBZ0IscUJBQXFCO0lBNkJ6QyxZQUNZLG9CQUEwQyxFQUM5QixPQUF5QjtRQURyQyx5QkFBb0IsR0FBcEIsb0JBQW9CLENBQXNCO1FBQzlCLFlBQU8sR0FBUCxPQUFPLENBQWtCO1FBdkJqRCwrQ0FBK0M7UUFDL0MsY0FBUyxHQUFZLEtBQUssQ0FBQztRQUszQixtQ0FBbUM7UUFDbkMsbUJBQWMsR0FBUSxFQUFFLENBQUM7UUFFekIsNkNBQTZDO1FBQ3BDLGFBQVEsR0FBWSxLQUFLLENBQUM7UUFFbkMsa0VBQWtFO1FBQ3pELHlCQUFvQixHQUFZLElBQUksQ0FBQztRQUU5Qyw0Q0FBNEM7UUFDbEMsWUFBTyxHQUFHLElBQUksWUFBWSxFQUFPLENBQUM7UUFFNUMsd0JBQXdCO1FBQ2QsaUJBQVksR0FBRyxNQUFNLENBQUMsWUFBWSxFQUFFLEVBQUUsUUFBUSxFQUFFLElBQUksRUFBRSxDQUFDLENBQUM7SUFNbEUsQ0FBQztJQUNEOzs7O09BSUc7SUFDSCxNQUFNLENBQUMsS0FBVztRQUNoQixJQUFJLENBQUMsSUFBSSxDQUFDLGdCQUFnQixFQUFFLENBQUM7UUFDN0IsSUFBSSxDQUFDLElB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ZSxDQUFDLEtBQUssRUFBRSxJQUFJLENBQUMsSUFBSSxFQUFFLElBQUksQ0FBQyxhQUFhLENBQUMsQ0FBQztJQUN6RixDQUFDOytHQXhIbUIscUJBQXFCO21HQUFyQixxQkFBcUI7OzRGQUFyQixxQkFBcUI7a0JBRDFDLFNBQVM7OzBCQWdDTCxRQUFRO3lDQWJGLFFBQVE7c0JBQWhCLEtBQUs7Z0JBR0csb0JBQW9CO3NCQUE1QixLQUFLO2dCQUdJLE9BQU87c0JBQWhCLE1BQU0iLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBVbnR5cGVkRm9ybUdyb3VwIH0gZnJvbSAnQGFuZ3VsYXIvZm9ybXMnO1xuaW1wb3J0IHsgRm9ybVZhbGlkYXRvclNlcnZpY2UgfSBmcm9tICcuLi9jb3JlL2Zvcm0tdmFsaWRhdG9yLnNlcnZpY2UnO1xuaW1wb3J0IHsgRGlyZWN0aXZlLCBFdmVudEVtaXR0ZXIsIGluamVjdCwgSW5wdXQsIE9wdGlvbmFsLCBPdXRwdXQgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IFRlY2hsaWZ5U2VydmljZSB9IGZyb20gJy4vdGVjaGxpZnktc2VydmljZSc7XG5pbXBvcnQgeyBmaW5hbGl6ZSB9IGZyb20gJ3J4anMnO1xuaW1wb3J0IHsgTWF0RGlhbG9nUmVmIH0gZnJvbSAnQGFuZ3VsYXIvbWF0ZXJpYWwvZGlhbG9nJztcbmltcG9ydCB7IEFsZXJ0U2VydmljZSB9IGZyb20gJy4uL2NvcmUvYWxlcnQuc2VydmljZSc7XG5cbi8qKlxuICogSW50ZXJmYWNlIHVzZWQgdG8gZW5zdXJlIHdlIGhhdmUgYSBjb25zaXN0ZW50IHN0cnVjdHVyZSBhY3Jvc3Mgb3VyIGZvcm0gY29tcG9uZW50c1xuICpcbiAqIEl0IGFsc28gcHJvdmlkZXMgc29tZSBhYnN0cmFjdGlvbiBvZiByZXBlYXRlZCBjb2RlIHRvIHJlZHVjZSBvdXIgY29kZWJhc2Ugc2l6ZVxuICpcbiAqIEB0b2RvIFRoaXMgc2hvdWxkIGJlIG1vdmVkIHRvIG5neC10ZWNobGlmeS1jb3JlXG4gKlxuICogQWR2YW50YWdlcyBvZiB0aGlzIGFic3RyYWN0IGNsYXNzXG4gKiAtIExlc3MgY29kZSwgbGVzcyBtYWludGVuYW5jZSwgbGVzcyBidWdzXG4gKiAtIG1vcmUgY29uc2lzdGVudCBjb2RlXG4gKiAtIGNvbW1lbnRzIG9uIG1vcmUgY29kZVxuICogLSBzYXZlIHRpbWUsIHNhdmUgZW5lcmd5XG4gKi9cbkBEaXJlY3RpdmUoKVxuZXhwb3J0IGFic3RyYWN0IGNsYXNzIFRlY2hsaWZ5Rm9ybUNvbXBvbmVudCB7XG5cbiAgLy9Gb3JtIGJ1aWxkZXIgaW5zdGFuY2VcbiAgZm9ybTogVW50eXBlZEZvcm1Hcm91cDtcblxuICAvL0Vycm9yIG1lc3NhZ2VzIGNvbmZpZyBmb3IgdGhlIGZvcm1cbiAgZXJyb3JNZXNzYWdlczogYW55O1xuXG4gIC8vQm9vbGVhbiB0byBkZW5vdGUgdGhlIGZvcm0gaXMgaW4gQVBJIHByb2dyZXNzXG4gIGlzV29ya2luZzogYm9vbGVhbiA9IGZhbHNlO1xuXG4gIC8vRm9ybSBkaWFsb2dyZWYgcmVmZXJlbmNlXG4gIGRpYWxvZ1JlZjogTWF0RGlhbG9nUmVmPGFueSwgYW55PjtcblxuICAvL0FycmF5IG9mIGNyZWF0ZWQgbXVsdGlwbGUgZW50cmllc1xuICBjcmVhdGVkRW50cmllczogYW55ID0gW107XG5cbiAgLy9Cb29sZWFuIHRvIGRlbm90ZSBpZiBmb3JtIGlzIGluIHVwZGF0ZSBtb2RlXG4gIEBJbnB1dCgpIGlzVXBkYXRlOiBib29sZWFuID0gZmFsc2U7XG5cbiAgLy9Cb29sZWFuIHRvIGRlbm90ZSBpZiBmb3JtIGhhcyBhYmlsaXR5IHRvIGNyZWF0ZSBtdWx0aXBsZSBlbnRyaWVzXG4gIEBJbnB1dCgpIGlzQWxsb3dDcmVhdGVBbm90aGVyOiBib29sZWFuID0gdHJ1ZTtcblxuICAvL0VtaXRzIGFuIGV2ZW50IG9uY2UgZm9ybSBzdWJtaXQgaXMgc3VjY2Vzc1xuICBAT3V0cHV0KCkgc3VjY2VzcyA9IG5ldyBFdmVudEVtaXR0ZXI8YW55PigpO1xuXG4gIC8vSW5qZWN0ZWQgYWxlcnQgc2VydmljZVxuICBwcm90ZWN0ZWQgYWxlcnRTZXJ2aWNlID0gaW5qZWN0KEFsZXJ0U2VydmljZSwgeyBvcHRpb25hbDogdHJ1ZSB9KTtcblxuICBjb25zdHJ1Y3RvcihcbiAgICBwcm90ZWN0ZWQgZm9ybVZhbGlkYXRvclNlcnZpY2U6IEZvcm1WYWxpZGF0b3JTZXJ2aWNlLFxuICAgIEBPcHRpb25hbCgpIHByb3RlY3RlZCBzZXJ2aWNlPzogVGVjaGxpZnlTZXJ2aWNlKSB7XG5cbiAgfVxuICAvKipcbiAgICogU3VibWl0cyB0aGUgZm9ybVxuICAgKiBAcGFyYW0gbW9kZWwgZm9ybSBtb2RlbCBvcHRpb25hbCwgaWYgbmVlZGVkIHRvIGJlIG92ZXJyaWRlblxuICAgKiBAcmV0dXJucyBcbiAgICovXG4gIHN1Ym1pdChtb2RlbD86IGFueSkge1xuICAgIHRoaXMuZm9ybS5tYXJrQWxsQXNUb3VjaGVkKCk7XG4gICAgaWYgKCF0aGlzLnNlcnZpY2UpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgYCR7dGhpcy5jb25zdHJ1Y3Rvci5uYW1lfTogU2VydmljZSBpcyByZXF1aXJlZCB0byBzdWJtaXQgdGhlIGZvcm1gXG4gICAgICApO1xuICAgIH1cbiAgICBpZiAoIXRoaXMuZm9ybS52YWxpZCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBpZiAoIW1vZGVsKSB7XG4gICAgICBtb2RlbCA9IHRoaXMuZm9ybS52YWx1ZTtcbiAgICB9XG4gICAgdGhpcy5pc1dvcmtpbmcgPSB0cnVlO1xuICAgIChcbiAgICAgIHRoaXMuaXNVcGRhdGUgP1xuICAgICAgICB0aGlzLnNlcnZpY2UudXBkYXRlKG1vZGVsKSA6XG4gICAgICAgIHRoaXMuc2VydmljZS5zdG9yZShtb2RlbClcbiAgICApXG4gICAgICAucGlwZShcbiAgICAgICAgZmluYWxpemUoKCkgPT4gdGhpcy5pc1dvcmtpbmcgPSBmYWxzZSksXG4gICAgICApXG4gICAgICAuc3Vic2NyaWJlKChyZXM6IGFueSkgPT4ge1xuICAgICAgICB0aGlzLmNyZWF0ZWRFbnRyaWVzLnVuc2hpZnQocmVzPy5pdGVtKTtcbiAgICAgICAgaWYgKG1vZGVsPy5pc19jcmVhdGVfYW5vdGhlcikge1xuICAgICAgICAgIHRoaXMuYWxlcnRTZXJ2aWNlLmFkZEFsZXJ0KCdTdWNjZXNzZnVsbHkgQ3JlYXRlZCcsICdzdWNjZXNzJyk7XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIGlmICh0aGlzLmlzVXBkYXRlKSB7XG4gICAgICAgICAgdGhpcy5zdWNjZXNzLmVtaXQocmVzPy5pdGVtKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICB0aGlzLnN1Y2Nlc3MuZW1pdCgodGhpcy5jcmVhdGVkRW50cmllcy5sZW5ndGggPT0gMSkgPyB0aGlzLmNyZWF0ZWRFbnRyaWVzWzBdIDogdGhpcy5jcmVhdGVkRW50cmllcyk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHRoaXMuZGlhbG9nUmVmKSB7XG4gICAgICAgICAgdGhpcy5kaWFsb2dSZWYuY2xvc2UocmVzLml0ZW0pO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDbG9zZSB0aGUgYWN0aXZlIGRpYWxvZ1xuICAgKi9cbiAgY2xvc2VEaWFsb2coKSB7XG4gICAgaWYgKHRoaXMuY3JlYXRlZEVudHJpZXM/Lmxlbmd0aCA+IDApIHtcbiAgICAgIHRoaXMuc3VjY2Vzcy5lbWl0KHRoaXMuY3JlYXRlZEVudHJpZXMpO1xuICAgIH1cbiAgICB0aGlzLmRpYWxvZ1JlZi5jbG9zZSgpO1xuICB9XG5cbiAgLyoqXG4gICAqIFJlc2V0cyB0aGUgdmFsdWUgb2YgYSBmaWVsZCBpbiB0aGUgSFRNTCBmb3JtXG4gICAqXG4gICAqIEBwYXJhbSBldmVudFxuICAgKiBAcGFyYW0gZmllbGRcbiAgICovXG4gIHJlc2V0RmllbGRWYWx1ZShldmVudDogYW55LCBmaWVsZDogc3RyaW5nKSB7XG4gICAgdGhpcy5mb3JtPy5nZXQoZmllbGQpPy5zZXRWYWx1ZSgnJyk7XG4gIH1cblxuICAvKipcbiAgICogUmV0cmlldmVzIHRoZSB2YWx1ZSBvZiBhIGZpZWxkIGZyb20gdGhlIEhUTUwgZm9ybVxuICAgKlxuICAgKiBAcGFyYW0gZmllbGRcbiAgICogQHJldHVybnNcbiAgICovXG4gIGdldEZpZWxkVmFsdWUoZmllbGQ6IHN0cmluZykge1xuICAgIHJldHVybiB0aGlzLmZvcm0/LmdldChmaWVsZCk/LnZhbHVlO1xuICB9XG5cbiAgLyoqXG4gICAqIE1ldGhvZCB0byBldmFsdWF0ZSBmb3JtIGZpZWxkc1xuICAgKiAqL1xuICBpc0ZpZWxkVmFsaWQoZmllbGQ6IHN0cmluZykge1xuICAgIHJldHVybiB0aGlzLmZvcm1WYWxpZGF0b3JTZXJ2aWNlLmlzRmllbGRWYWxpZChmaWVsZCwgdGhpcy5mb3JtKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBNZXRob2QgdG8gZmluZCBlcnJvciBpbiBmb3JtIGZpZWxkc1xuICAgKiAqL1xuICBnZXRFcnJvck1lc3NhZ2UoZmllbGQ6IHN0cmluZykge1xuICAgIHJldHVybiB0aGlzLmZvcm1WYWxpZGF0b3JTZXJ2aWNlLmdldEVycm9yTWVzc2FnZShmaWVsZCwgdGhpcy5mb3JtLCB0aGlzLmVycm9yTWVzc2FnZXMpO1xuICB9XG5cbn1cbiJdfQ==
@@ -0,0 +1,289 @@
1
+ import { __decorate } from "tslib";
2
+ import { debounceTime, finalize } from 'rxjs/operators';
3
+ import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy';
4
+ import { Title } from '@angular/platform-browser';
5
+ import { Directive, inject, Optional } from '@angular/core';
6
+ import { EnvironmentService } from '../core/environment.service';
7
+ import { RequestHelperService } from '../request-helper/request-helper.service';
8
+ import * as i0 from "@angular/core";
9
+ import * as i1 from "./techlify-service";
10
+ /**
11
+ * Interface used to ensure we have a consistent structure across our listing pages
12
+ *
13
+ * @todo This should be moved to ngx-techlify-core
14
+ *
15
+ * Advantages of this abstract class
16
+ * - Less code, less maintenance, less bugs
17
+ * - more consistent code
18
+ * - comments on more code
19
+ * - save time, save energy
20
+ */
21
+ let TechlifyListComponent = class TechlifyListComponent {
22
+ get isFilterPatchFromRoute() {
23
+ return this._isFilterPatchFromRoute;
24
+ }
25
+ set isFilterPatchFromRoute(value) {
26
+ this._isFilterPatchFromRoute = value;
27
+ }
28
+ /**
29
+ * Child classes can override this.
30
+ * If left undefined/empty, falls back to environment.appTitle
31
+ */
32
+ get pageTitle() {
33
+ return undefined; // default
34
+ }
35
+ constructor(service) {
36
+ this.service = service;
37
+ this.models = [];
38
+ this.selectedModelIds = [];
39
+ this.isAllSelected = false;
40
+ this.page = 1;
41
+ this.perPage = 25;
42
+ this.lastPage = 0;
43
+ this.isWorking = false;
44
+ this.isViewLoaded = false;
45
+ this.columnConfigs = [];
46
+ /**
47
+ * Boolean to turn off, if we don't want to patch filters from route.
48
+ * This can be overriden in child classes if need
49
+ */
50
+ this._isFilterPatchFromRoute = true;
51
+ this.titleService = inject(Title, { optional: true });
52
+ this.environmentService = inject(EnvironmentService, { optional: true });
53
+ //Request helper service to inherited and overriden if needed
54
+ this.requestHelperService = inject(RequestHelperService);
55
+ const resolvedTitle = this.pageTitle && this.pageTitle.trim().length > 0
56
+ ? this.pageTitle
57
+ : this.environmentService.get().appTitle;
58
+ this.titleService.setTitle(resolvedTitle);
59
+ }
60
+ /**
61
+ * Function that listens for any changes in the filter form group
62
+ * It updates the route automatically
63
+ * Also reload the page on change
64
+ */
65
+ listenFilterChanges() {
66
+ this.filterForm.valueChanges.pipe(debounceTime(500), untilDestroyed(this))
67
+ .subscribe(_ => {
68
+ if (this.isFilterPatchFromRoute) {
69
+ const unformatedFilters = JSON.parse(JSON.stringify(this.filterForm.value));
70
+ this.filters = this.requestHelperService.convertToFormData(unformatedFilters);
71
+ this.requestHelperService.updateQueryParams(this.filters);
72
+ }
73
+ this.reload();
74
+ });
75
+ }
76
+ /**
77
+ * Function decodes the route params and patches the filter
78
+ * Setup the filterFormConfigurtion to override for multiple and date attributes.
79
+ */
80
+ patchFiltersFromRoute() {
81
+ this.requestHelperService.updateFormWithQueryParams(this.filterForm, this.filterFormConfiguration);
82
+ }
83
+ /**
84
+ * Function that loads the main models of the application
85
+ */
86
+ loadData(filters) {
87
+ if (!this.service) {
88
+ throw new Error(`${this.constructor.name}: Service is required to load the data`);
89
+ }
90
+ this.isWorking = true;
91
+ if (!filters) {
92
+ filters = JSON.parse(JSON.stringify(this.filterForm.value));
93
+ filters.perPage = this.perPage;
94
+ filters.page = this.page;
95
+ }
96
+ this.service.index(filters)
97
+ .pipe(finalize(() => this.isWorking = false))
98
+ .subscribe((result) => {
99
+ this.lastPage = result?.last_page || this.page;
100
+ if (result?.data?.length > 0) {
101
+ this.models = this.models.concat(result.data);
102
+ }
103
+ });
104
+ }
105
+ ;
106
+ /**
107
+ * Reload all data from page 1
108
+ */
109
+ reload() {
110
+ this.models = [];
111
+ this.selectedModelIds = [];
112
+ this.page = 1;
113
+ if (!this.isWorking) {
114
+ this.loadData();
115
+ }
116
+ }
117
+ /**
118
+ * Can be called when the user is scrolling,
119
+ * to trigger loading a new page of data
120
+ */
121
+ onScroll() {
122
+ if (!this.isWorking && this.page < this.lastPage) {
123
+ this.page += 1;
124
+ this.loadData();
125
+ }
126
+ }
127
+ /**
128
+ * Reset the Filter.
129
+ *
130
+ * @param field Field name.
131
+ */
132
+ resetFilter(field) {
133
+ this.filterForm.get(field).reset('');
134
+ }
135
+ /**
136
+ * @deprecated will be removed in release/18.55.0
137
+ * Use `modelsUpdatedById` instead, which finds the model by id and does not require tracking the index.
138
+ *
139
+ * Updates a specific row in the table by index.
140
+ * @param model The model to be updated.
141
+ * @param index The index of the model in the list.
142
+ */
143
+ modelUpdated(model, index) {
144
+ this.models[index] = model;
145
+ this.models = [...this.models];
146
+ }
147
+ /**
148
+ * Updates one or more models in the list by matching on their `id`.
149
+ * Accepts a single model or an array of models.
150
+ * @param models The updated model or array of models.
151
+ */
152
+ modelsUpdatedById(models) {
153
+ if (!Array.isArray(models)) {
154
+ models = [models];
155
+ }
156
+ models.forEach((updatedModel) => {
157
+ const index = this.models.findIndex((m) => m.id === updatedModel.id);
158
+ if (index !== -1) {
159
+ this.models[index] = updatedModel;
160
+ }
161
+ });
162
+ this.models = [...this.models];
163
+ this.selectedModelIds = [];
164
+ }
165
+ /**
166
+ * Deletes one or more models in the list by matching on their `id`.
167
+ * Accepts a single model or an array of models.
168
+ * @param models The updated model or array of models.
169
+ */
170
+ modelsDeletedById(models) {
171
+ if (!Array.isArray(models)) {
172
+ models = [models];
173
+ }
174
+ this.models = this.models.filter((m) => !(models.some((item) => item.id === m.id)));
175
+ this.selectedModelIds = [];
176
+ }
177
+ /**
178
+ * Adds a new model at the first position in the table.
179
+ * @param model The new model to be added.
180
+ */
181
+ modelCreated(model) {
182
+ if (Array.isArray(model)) {
183
+ //When create another feature is used, we get array of models
184
+ this.models.unshift(...model);
185
+ }
186
+ else {
187
+ this.models.unshift(model);
188
+ }
189
+ this.models = [...this.models];
190
+ }
191
+ /**
192
+ * @deprecated will be removed in release/18.57.0
193
+ *
194
+ * Remove a model from the list.
195
+ * @param index Index of the model in the list.
196
+ */
197
+ modelDeleted(index) {
198
+ this.models.splice(index, 1);
199
+ this.models = [...this.models];
200
+ }
201
+ /**
202
+ * Used for multi select
203
+ * Trigerred when select all is toggled
204
+ */
205
+ selectAll() {
206
+ this.selectedModelIds = [];
207
+ this.models.map((model) => {
208
+ model.is_selected = this.isAllSelected;
209
+ if (this.isAllSelected) {
210
+ this.selectedModelIds.push(model.id);
211
+ }
212
+ });
213
+ this.models = [...this.models];
214
+ }
215
+ /**
216
+ * Used for multi select
217
+ * Trigerred if any entry section is modified
218
+ */
219
+ isSelectionModified(event, model) {
220
+ this.isAllSelected = false;
221
+ if (event.checked) {
222
+ this.selectedModelIds.push(model?.id);
223
+ }
224
+ else {
225
+ this.selectedModelIds = this.selectedModelIds.filter((modelId) => modelId != model?.id);
226
+ }
227
+ }
228
+ /**
229
+ * Defualt method to listen to sort column updates
230
+ * @param event
231
+ */
232
+ sortColumn(event) {
233
+ const direction = event.direction.toString().toUpperCase();
234
+ this.models = [];
235
+ this.filterForm.get('sort_by').setValue(`${event?.active}|${direction}`);
236
+ }
237
+ /**
238
+ * It should be overrided in child class to reset a filter form instance.
239
+ * Used by setView method.
240
+ */
241
+ resetFilterForm() {
242
+ //If filterForm exists, then reset
243
+ if (this.filterForm) {
244
+ this.filterForm.reset();
245
+ }
246
+ }
247
+ /**
248
+ * It should be overrided in child class to reset column configs.
249
+ * Used by setView method.
250
+ */
251
+ resetColumnConfigs() {
252
+ this.columnConfigs = [];
253
+ }
254
+ /**
255
+ * Hook method used to set the selected view
256
+ * @param view optional used by my-view-list
257
+ */
258
+ setView(view) {
259
+ //Reset the query params
260
+ this.requestHelperService.updateQueryParams({});
261
+ this.isViewLoaded = false;
262
+ this.resetColumnConfigs();
263
+ this.resetFilterForm();
264
+ setTimeout(() => {
265
+ if (view) {
266
+ //If there is a view, then set it.
267
+ //Setup view filters
268
+ this.filterForm.setValue(this.requestHelperService.convertToFormData(view?.filters));
269
+ //Setup view columns
270
+ this.columnConfigs.forEach(column => {
271
+ column.isSelected = (view?.columns).some(col => col === column.def);
272
+ });
273
+ }
274
+ this.isViewLoaded = true;
275
+ }, 500);
276
+ }
277
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: TechlifyListComponent, deps: [{ token: i1.TechlifyService, optional: true }], target: i0.ɵɵFactoryTarget.Directive }); }
278
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "18.2.14", type: TechlifyListComponent, ngImport: i0 }); }
279
+ };
280
+ TechlifyListComponent = __decorate([
281
+ UntilDestroy()
282
+ ], TechlifyListComponent);
283
+ export { TechlifyListComponent };
284
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: TechlifyListComponent, decorators: [{
285
+ type: Directive
286
+ }], ctorParameters: () => [{ type: i1.TechlifyService, decorators: [{
287
+ type: Optional
288
+ }] }] });
289
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGVjaGxpZnktbGlzdC1jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9uZ3gtdGVjaGxpZnktY29yZS9zcmMvbGliL2Jhc2UtbW9kZWwvdGVjaGxpZnktbGlzdC1jb21wb25lbnQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUFBLE9BQU8sRUFBRSxZQUFZLEVBQUUsUUFBUSxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFDeEQsT0FBTyxFQUFFLFlBQVksRUFBRSxjQUFjLEVBQUUsTUFBTSx1QkFBdUIsQ0FBQztBQUNyRSxPQUFPLEVBQUUsS0FBSyxFQUFFLE1BQU0sMkJBQTJCLENBQUM7QUFDbEQsT0FBTyxFQUFFLFNBQVMsRUFBRSxNQUFNLEVBQUUsUUFBUSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQzVELE9BQU8sRUFBRSxrQkFBa0IsRUFBRSxNQUFNLDZCQUE2QixDQUFDO0FBQ2pFLE9BQU8sRUFBRSxvQkFBb0IsRUFBRSxNQUFNLDBDQUEwQyxDQUFDOzs7QUFJaEY7Ozs7Ozs7Ozs7R0FVRztBQUdJLElBQWUscUJBQXFCLEdBQXBDLE1BQWUscUJBQXFCO0lBcUJ6QyxJQUFJLHNCQUFzQjtRQUN4QixPQUFPLElBQUksQ0FBQyx1QkFBdUIsQ0FBQztJQUN0QyxDQUFDO0lBQ0QsSUFBSSxzQkFBc0IsQ0FBQyxLQUFjO1FBQ3ZDLElBQUksQ0FBQyx1QkFBdUIsR0FBRyxLQUFLLENBQUM7SUFDdkMsQ0FBQztJQXFCRDs7O1FBR0k7SUFDSixJQUFjLFNBQVM7UUFDckIsT0FBTyxTQUFTLENBQUMsQ0FBQyxVQUFVO0lBQzlCLENBQUM7SUFTRCxZQUFrQyxPQUF5QjtRQUF6QixZQUFPLEdBQVAsT0FBTyxDQUFrQjtRQTVEM0QsV0FBTSxHQUFVLEVBQUUsQ0FBQztRQUNuQixxQkFBZ0IsR0FBVSxFQUFFLENBQUM7UUFDN0Isa0JBQWEsR0FBRyxLQUFLLENBQUM7UUFDdEIsU0FBSSxHQUFHLENB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QUksQ0FBQyxvQkFBb0IsQ0FBQyxpQkFBaUIsQ0FBQyxFQUFFLENBQUMsQ0FBQztRQUNoRCxJQUFJLENBQUMsWUFBWSxHQUFHLEtBQUssQ0FBQztRQUMxQixJQUFJLENBQUMsa0JBQWtCLEVBQUUsQ0FBQztRQUMxQixJQUFJLENBQUMsZUFBZSxFQUFFLENBQUM7UUFDdkIsVUFBVSxDQUFDLEdBQUcsRUFBRTtZQUNkLElBQUksSUFBSSxFQUFFLENBQUM7Z0JBQ1Qsa0NBQWtDO2dCQUNsQyxvQkFBb0I7Z0JBQ3BCLElBQUksQ0FBQyxVQUFVLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxvQkFBb0IsQ0FBQyxpQkFBaUIsQ0FBQyxJQUFJLEVBQUUsT0FBTyxDQUFDLENBQUMsQ0FBQztnQkFDckYsb0JBQW9CO2dCQUNwQixJQUFJLENBQUMsYUFBYSxDQUFDLE9BQU8sQ0FBQyxNQUFNLENBQUMsRUFBRTtvQkFDbEMsTUFBTSxDQUFDLFVBQVUsR0FBRyxDQUFDLElBQUksRUFBRSxPQUFvQixDQUFBLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxLQUFLLE1BQU0sQ0FBQyxHQUFHLENBQUMsQ0FBQztnQkFDbEYsQ0FBQyxDQUFDLENBQUM7WUFDTCxDQUFDO1lBQ0QsSUFBSSxDQUFDLFlBQVksR0FBRyxJQUFJLENBQUM7UUFDM0IsQ0FBQyxFQUFFLEdBQUcsQ0FBQyxDQUFDO0lBQ1YsQ0FBQzsrR0E5U21CLHFCQUFxQjttR0FBckIscUJBQXFCOztBQUFyQixxQkFBcUI7SUFGMUMsWUFBWSxFQUFFO0dBRU8scUJBQXFCLENBK1MxQzs7NEZBL1NxQixxQkFBcUI7a0JBRDFDLFNBQVM7OzBCQStESyxRQUFRIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgZGVib3VuY2VUaW1lLCBmaW5hbGl6ZSB9IGZyb20gJ3J4anMvb3BlcmF0b3JzJztcbmltcG9ydCB7IFVudGlsRGVzdHJveSwgdW50aWxEZXN0cm95ZWQgfSBmcm9tICdAbmduZWF0L3VudGlsLWRlc3Ryb3knO1xuaW1wb3J0IHsgVGl0bGUgfSBmcm9tICdAYW5ndWxhci9wbGF0Zm9ybS1icm93c2VyJztcbmltcG9ydCB7IERpcmVjdGl2ZSwgaW5qZWN0LCBPcHRpb25hbCB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgRW52aXJvbm1lbnRTZXJ2aWNlIH0gZnJvbSAnLi4vY29yZS9lbnZpcm9ubWVudC5zZXJ2aWNlJztcbmltcG9ydCB7IFJlcXVlc3RIZWxwZXJTZXJ2aWNlIH0gZnJvbSAnLi4vcmVxdWVzdC1oZWxwZXIvcmVxdWVzdC1oZWxwZXIuc2VydmljZSc7XG5pbXBvcnQgeyBUZWNobGlmeVNlcnZpY2UgfSBmcm9tICcuL3RlY2hsaWZ5LXNlcnZpY2UnO1xuaW1wb3J0IHsgQ29sdW1uQ29uZmlnIH0gZnJvbSAnLi4vY29sdW1uLXNlbGVjdG9yJztcblxuLyoqXG4gKiBJbnRlcmZhY2UgdXNlZCB0byBlbnN1cmUgd2UgaGF2ZSBhIGNvbnNpc3RlbnQgc3RydWN0dXJlIGFjcm9zcyBvdXIgbGlzdGluZyBwYWdlc1xuICpcbiAqIEB0b2RvIFRoaXMgc2hvdWxkIGJlIG1vdmVkIHRvIG5neC10ZWNobGlmeS1jb3JlXG4gKlxuICogQWR2YW50YWdlcyBvZiB0aGlzIGFic3RyYWN0IGNsYXNzXG4gKiAtIExlc3MgY29kZSwgbGVzcyBtYWludGVuYW5jZSwgbGVzcyBidWdzXG4gKiAtIG1vcmUgY29uc2lzdGVudCBjb2RlXG4gKiAtIGNvbW1lbnRzIG9uIG1vcmUgY29kZVxuICogLSBzYXZlIHRpbWUsIHNhdmUgZW5lcmd5XG4gKi9cbkBVbnRpbERlc3Ryb3koKVxuQERpcmVjdGl2ZSgpXG5leHBvcnQgYWJzdHJhY3QgY2xhc3MgVGVjaGxpZnlMaXN0Q29tcG9uZW50IHtcblxuICBtb2RlbHM6IGFueVtdID0gW107XG4gIHNlbGVjdGVkTW9kZWxJZHM6IGFueVtdID0gW107XG4gIGlzQWxsU2VsZWN0ZWQgPSBmYWxzZTtcbiAgcGFnZSA9IDE7XG4gIHBlclBhZ2UgPSAyNTtcbiAgbGFzdFBhZ2UgPSAwO1xuICBpc1dvcmtpbmcgPSBmYWxzZTtcbiAgZmlsdGVyRm9ybTogYW55O1xuICBpc1ZpZXdMb2FkZWQgPSBmYWxzZTtcbiAgY29sdW1uQ29uZmlnczogQ29sdW1uQ29uZmlnW10gPSBbXTtcblxuICAvL0ZpbHRlcnMgdG8gYmUgZXhwb3J0ZWQgZm9yIHZpZXcgaW50ZWdyYXRpb25cbiAgZmlsdGVyczogYW55O1xuXG4gIC8qKlxuICAgKiBCb29sZWFuIHRvIHR1cm4gb2ZmLCBpZiB3ZSBkb24ndCB3YW50IHRvIHBhdGNoIGZpbHRlcnMgZnJvbSByb3V0ZS5cbiAgICogVGhpcyBjYW4gYmUgb3ZlcnJpZGVuIGluIGNoaWxkIGNsYXNzZXMgaWYgbmVlZCBcbiAgICovXG4gIHByb3RlY3RlZCBfaXNGaWx0ZXJQYXRjaEZyb21Sb3V0ZSA9IHRydWU7XG4gIGdldCBpc0ZpbHRlclBhdGNoRnJvbVJvdXRlKCkge1xuICAgIHJldHVybiB0aGlzLl9pc0ZpbHRlclBhdGNoRnJvbVJvdXRlO1xuICB9XG4gIHNldCBpc0ZpbHRlclBhdGNoRnJvbVJvdXRlKHZhbHVlOiBib29sZWFuKSB7XG4gICAgdGhpcy5faXNGaWx0ZXJQYXRjaEZyb21Sb3V0ZSA9IHZhbHVlO1xuICB9XG5cbiAgLyoqXG4gICAqIEZpbHRlciBmb3JtIGNvbmZpZ3VyYXRpb24gdXNlZCB0byBkZWNvZGUgdGhlIHJvdXRlIHBhcmFtcy5cbiAgICogRWc6IE92ZXJyaWRlIGluIGNoaWxkIGNsYXNzXG4gICAqICBgYGAgXG4gICAqIGZpbHRlckZvcm1Db25maWd1cmF0aW9uOiBhbnkgPSB7XG4gICAgc3RhdHVzX2lkOiB7IG11bHRpcGxlOiB0cnVlIH0sXG4gICAgYnJhbmNoX2lkczogeyBtdWx0aXBsZTogdHJ1ZSB9LFxuICAgIGRlcGFydG1lbnRfaWRzOiB7IG11bHRpcGxlOiB0cnVlIH0sXG4gICAgZW1wbG95ZWVfaWRzOiB7IG11bHRpcGxlOiB0cnVlIH0sXG4gICAgY291cnNlX2lkczogeyBtdWx0aXBsZTogdHJ1ZSB9LFxuICAgIGRhdGVfZnJvbTogeyBkYXRlOiB0cnVlIH0sXG4gICAgZGF0ZV90bzogeyBkYXRlOiB0cnVlIH0sXG4gICAgZHVlX2RhdGVfZnJvbTogeyBkYXRlOiB0cnVlIH0sXG4gICAgZHVlX2RhdGVfdG86IHsgZGF0ZTogdHJ1ZSB9LFxuICAgfSBcbiAgICpgYGBcbiAgICovXG4gIGZpbHRlckZvcm1Db25maWd1cmF0aW9uOiBhbnk7XG5cbiAgLyoqXG4gICAgKiBDaGlsZCBjbGFzc2VzIGNhbiBvdmVycmlkZSB0aGlzLlxuICAgICogSWYgbGVmdCB1bmRlZmluZWQvZW1wdHksIGZhbGxzIGJhY2sgdG8gZW52aXJvbm1lbnQuYXBwVGl0bGVcbiAgICAqL1xuICBwcm90ZWN0ZWQgZ2V0IHBhZ2VUaXRsZSgpOiBzdHJpbmcgfCB1bmRlZmluZWQge1xuICAgIHJldHVybiB1bmRlZmluZWQ7IC8vIGRlZmF1bHRcbiAgfVxuXG5cbiAgcHJpdmF0ZSB0aXRsZVNlcnZpY2UgPSBpbmplY3QoVGl0bGUsIHsgb3B0aW9uYWw6IHRydWUgfSk7XG4gIHByaXZhdGUgZW52aXJvbm1lbnRTZXJ2aWNlID0gaW5qZWN0KEVudmlyb25tZW50U2VydmljZSwgeyBvcHRpb25hbDogdHJ1ZSB9KTtcblxuICAvL1JlcXVlc3QgaGVscGVyIHNlcnZpY2UgdG8gaW5oZXJpdGVkIGFuZCBvdmVycmlkZW4gaWYgbmVlZGVkXG4gIHByb3RlY3RlZCByZXF1ZXN0SGVscGVyU2VydmljZSA9IGluamVjdChSZXF1ZXN0SGVscGVyU2VydmljZSk7XG5cbiAgY29uc3RydWN0b3IoQE9wdGlvbmFsKCkgcHJvdGVjdGVkIHNlcnZpY2U/OiBUZWNobGlmeVNlcnZpY2UpIHtcbiAgICBjb25zdCByZXNvbHZlZFRpdGxlID1cbiAgICAgIHRoaXMucGFnZVRpdGxlICYmIHRoaXMucGFnZVRpdGxlLnRyaW0oKS5sZW5ndGggPiAwXG4gICAgICAgID8gdGhpcy5wYWdlVGl0bGVcbiAgICAgICAgOiB0aGlzLmVudmlyb25tZW50U2VydmljZS5nZXQoKS5hcHBUaXRsZTtcbiAgICB0aGlzLnRpdGxlU2VydmljZS5zZXRUaXRsZShyZXNvbHZlZFRpdGxlKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBGdW5jdGlvbiB0aGF0IGxpc3RlbnMgZm9yIGFueSBjaGFuZ2VzIGluIHRoZSBmaWx0ZXIgZm9ybSBncm91cFxuICAgKiBJdCB1cGRhdGVzIHRoZSByb3V0ZSBhdXRvbWF0aWNhbGx5XG4gICAqIEFsc28gcmVsb2FkIHRoZSBwYWdlIG9uIGNoYW5nZVxuICAgKi9cbiAgbGlzdGVuRmlsdGVyQ2hhbmdlcygpOiB2b2lkIHtcbiAgICB0aGlzLmZpbHRlckZvcm0udmFsdWVDaGFuZ2VzLnBpcGUoZGVib3VuY2VUaW1lKDUwMCksIHVudGlsRGVzdHJveWVkKHRoaXMpKVxuICAgICAgLnN1YnNjcmliZShfID0+IHtcbiAgICAgICAgaWYgKHRoaXMuaXNGaWx0ZXJQYXRjaEZyb21Sb3V0ZSkge1xuICAgICAgICAgIGNvbnN0IHVuZm9ybWF0ZWRGaWx0ZXJzID0gSlNPTi5wYXJzZShKU09OLnN0cmluZ2lmeSh0aGlzLmZpbHRlckZvcm0udmFsdWUpKTtcbiAgICAgICAgICB0aGlzLmZpbHRlcnMgPSB0aGlzLnJlcXVlc3RIZWxwZXJTZXJ2aWNlLmNvbnZlcnRUb0Zvcm1EYXRhKHVuZm9ybWF0ZWRGaWx0ZXJzKTtcbiAgICAgICAgICB0aGlzLnJlcXVlc3RIZWxwZXJTZXJ2aWNlLnVwZGF0ZVF1ZXJ5UGFyYW1zKHRoaXMuZmlsdGVycyk7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5yZWxvYWQoKTtcbiAgICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIEZ1bmN0aW9uIGRlY29kZXMgdGhlIHJvdXRlIHBhcmFtcyBhbmQgcGF0Y2hlcyB0aGUgZmlsdGVyXG4gICAqIFNldHVwIHRoZSBmaWx0ZXJGb3JtQ29uZmlndXJ0aW9uIHRvIG92ZXJyaWRlIGZvciBtdWx0aXBsZSBhbmQgZGF0ZSBhdHRyaWJ1dGVzLlxuICAgKi9cbiAgcGF0Y2hGaWx0ZXJzRnJvbVJvdXRlKCkge1xuICAgIHRoaXMucmVxdWVzdEhlbHBlclNlcnZpY2UudXBkYXRlRm9ybVdpdGhRdWVyeVBhcmFtcyh0aGlzLmZpbHRlckZvcm0sIHRoaXMuZmlsdGVyRm9ybUNvbmZpZ3VyYXRpb24pO1xuICB9XG5cbiAgLyoqXG4gICAqIEZ1bmN0aW9uIHRoYXQgbG9hZHMgdGhlIG1haW4gbW9kZWxzIG9mIHRoZSBhcHBsaWNhdGlvblxuICAgKi9cbiAgbG9hZERhdGEoZmlsdGVycz86IGFueSk6IHZvaWQge1xuICAgIGlmICghdGhpcy5zZXJ2aWNlKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgIGAke3RoaXMuY29uc3RydWN0b3IubmFtZX06IFNlcnZpY2UgaXMgcmVxdWlyZWQgdG8gbG9hZCB0aGUgZGF0YWBcbiAgICAgICk7XG4gICAgfVxuICAgIHRoaXMuaXNXb3JraW5nID0gdHJ1ZTtcbiAgICBpZiAoIWZpbHRlcnMpIHtcbiAgICAgIGZpbHRlcnMgPSBKU09OLnBhcnNlKEpTT04uc3RyaW5naWZ5KHRoaXMuZmlsdGVyRm9ybS52YWx1ZSkpO1xuICAgICAgZmlsdGVycy5wZXJQYWdlID0gdGhpcy5wZXJQYWdlO1xuICAgICAgZmlsdGVycy5wYWdlID0gdGhpcy5wYWdlO1xuICAgIH1cbiAgICB0aGlzLnNlcnZpY2UuaW5kZXgoZmlsdGVycylcbiAgICAgIC5waXBlKGZpbmFsaXplKCgpID0+IHRoaXMuaXNXb3JraW5nID0gZmFsc2UpKVxuICAgICAgLnN1YnNjcmliZSgocmVzdWx0OiBhbnkpID0+IHtcbiAgICAgICAgdGhpcy5sYXN0UGFnZSA9IHJlc3VsdD8ubGFzdF9wYWdlIHx8IHRoaXMucGFnZTtcbiAgICAgICAgaWYgKHJlc3VsdD8uZGF0YT8ubGVuZ3RoID4gMCkge1xuICAgICAgICAgIHRoaXMubW9kZWxzID0gdGhpcy5tb2RlbHMuY29uY2F0KHJlc3VsdC5kYXRhKTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gIH07XG5cbiAgLyoqXG4gICAqIFJlbG9hZCBhbGwgZGF0YSBmcm9tIHBhZ2UgMVxuICAgKi9cbiAgcmVsb2FkKCk6IHZvaWQge1xuICAgIHRoaXMubW9kZWxzID0gW107XG4gICAgdGhpcy5zZWxlY3RlZE1vZGVsSWRzID0gW107XG4gICAgdGhpcy5wYWdlID0gMTtcbiAgICBpZiAoIXRoaXMuaXNXb3JraW5nKSB7XG4gICAgICB0aGlzLmxvYWREYXRhKCk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIENhbiBiZSBjYWxsZWQgd2hlbiB0aGUgdXNlciBpcyBzY3JvbGxpbmcsXG4gICAqIHRvIHRyaWdnZXIgbG9hZGluZyBhIG5ldyBwYWdlIG9mIGRhdGFcbiAgICovXG4gIG9uU2Nyb2xsKCk6IHZvaWQge1xuICAgIGlmICghdGhpcy5pc1dvcmtpbmcgJiYgdGhpcy5wYWdlIDwgdGhpcy5sYXN0UGFnZSkge1xuICAgICAgdGhpcy5wYWdlICs9IDE7XG4gICAgICB0aGlzLmxvYWREYXRhKCk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFJlc2V0IHRoZSBGaWx0ZXIuXG4gICAqXG4gICAqIEBwYXJhbSBmaWVsZCBGaWVsZCBuYW1lLlxuICAgKi9cbiAgcmVzZXRGaWx0ZXIoZmllbGQ6IHN0cmluZyk6IHZvaWQge1xuICAgIHRoaXMuZmlsdGVyRm9ybS5nZXQoZmllbGQpLnJlc2V0KCcnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVwcmVjYXRlZCB3aWxsIGJlIHJlbW92ZWQgaW4gcmVsZWFzZS8xOC41NS4wXG4gICAqIFVzZSBgbW9kZWxzVXBkYXRlZEJ5SWRgIGluc3RlYWQsIHdoaWNoIGZpbmRzIHRoZSBtb2RlbCBieSBpZCBhbmQgZG9lcyBub3QgcmVxdWlyZSB0cmFja2luZyB0aGUgaW5kZXguXG4gICAqIFxuICAgKiBVcGRhdGVzIGEgc3BlY2lmaWMgcm93IGluIHRoZSB0YWJsZSBieSBpbmRleC5cbiAgICogQHBhcmFtIG1vZGVsIFRoZSBtb2RlbCB0byBiZSB1cGRhdGVkLlxuICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBtb2RlbCBpbiB0aGUgbGlzdC5cbiAgICovXG4gIG1vZGVsVXBkYXRlZChtb2RlbDogYW55LCBpbmRleDogbnVtYmVyKTogdm9pZCB7XG4gICAgdGhpcy5tb2RlbHNbaW5kZXhdID0gbW9kZWw7XG4gICAgdGhpcy5tb2RlbHMgPSBbLi4udGhpcy5tb2RlbHNdO1xuICB9XG5cbiAgLyoqXG4gICAqIFVwZGF0ZXMgb25lIG9yIG1vcmUgbW9kZWxzIGluIHRoZSBsaXN0IGJ5IG1hdGNoaW5nIG9uIHRoZWlyIGBpZGAuXG4gICAqIEFjY2VwdHMgYSBzaW5nbGUgbW9kZWwgb3IgYW4gYXJyYXkgb2YgbW9kZWxzLlxuICAgKiBAcGFyYW0gbW9kZWxzIFRoZSB1cGRhdGVkIG1vZGVsIG9yIGFycmF5IG9mIG1vZGVscy5cbiAgICovXG4gIG1vZGVsc1VwZGF0ZWRCeUlkKG1vZGVsczogYW55IHwgYW55W10pOiB2b2lkIHtcbiAgICBpZiAoIUFycmF5LmlzQXJyYXkobW9kZWxzKSkge1xuICAgICAgbW9kZWxzID0gW21vZGVsc107XG4gICAgfVxuICAgIG1vZGVscy5mb3JFYWNoKCh1cGRhdGVkTW9kZWw6IGFueSkgPT4ge1xuICAgICAgY29uc3QgaW5kZXggPSB0aGlzLm1vZGVscy5maW5kSW5kZXgoKG06IGFueSkgPT4gbS5pZCA9PT0gdXBkYXRlZE1vZGVsLmlkKTtcbiAgICAgIGlmIChpbmRleCAhPT0gLTEpIHtcbiAgICAgICAgdGhpcy5tb2RlbHNbaW5kZXhdID0gdXBkYXRlZE1vZGVsO1xuICAgICAgfVxuICAgIH0pO1xuICAgIHRoaXMubW9kZWxzID0gWy4uLnRoaXMubW9kZWxzXTtcbiAgICB0aGlzLnNlbGVjdGVkTW9kZWxJZHMgPSBbXTtcbiAgfVxuXG4gIC8qKlxuICAgKiBEZWxldGVzIG9uZSBvciBtb3JlIG1vZGVscyBpbiB0aGUgbGlzdCBieSBtYXRjaGluZyBvbiB0aGVpciBgaWRgLlxuICAgKiBBY2NlcHRzIGEgc2luZ2xlIG1vZGVsIG9yIGFuIGFycmF5IG9mIG1vZGVscy5cbiAgICogQHBhcmFtIG1vZGVscyBUaGUgdXBkYXRlZCBtb2RlbCBvciBhcnJheSBvZiBtb2RlbHMuXG4gICAqL1xuICBtb2RlbHNEZWxldGVkQnlJZChtb2RlbHM6IGFueSB8IGFueVtdKTogdm9pZCB7XG4gICAgaWYgKCFBcnJheS5pc0FycmF5KG1vZGVscykpIHtcbiAgICAgIG1vZGVscyA9IFttb2RlbHNdO1xuICAgIH1cbiAgICB0aGlzLm1vZGVscyA9IHRoaXMubW9kZWxzLmZpbHRlcigobTogYW55KSA9PiAhKG1vZGVscy5zb21lKChpdGVtOiBhbnkpID0+IGl0ZW0uaWQgPT09IG0uaWQpKSk7XG4gICAgdGhpcy5zZWxlY3RlZE1vZGVsSWRzID0gW107XG4gIH1cblxuICAvKipcbiAgICogQWRkcyBhIG5ldyBtb2RlbCBhdCB0aGUgZmlyc3QgcG9zaXRpb24gaW4gdGhlIHRhYmxlLlxuICAgKiBAcGFyYW0gbW9kZWwgVGhlIG5ldyBtb2RlbCB0byBiZSBhZGRlZC5cbiAgICovXG4gIG1vZGVsQ3JlYXRlZChtb2RlbDogYW55KTogdm9pZCB7XG4gICAgaWYgKEFycmF5LmlzQXJyYXkobW9kZWwpKSB7XG4gICAgICAvL1doZW4gY3JlYXRlIGFub3RoZXIgZmVhdHVyZSBpcyB1c2VkLCB3ZSBnZXQgYXJyYXkgb2YgbW9kZWxzXG4gICAgICB0aGlzLm1vZGVscy51bnNoaWZ0KC4uLm1vZGVsKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5tb2RlbHMudW5zaGlmdChtb2RlbCk7XG4gICAgfVxuICAgIHRoaXMubW9kZWxzID0gWy4uLnRoaXMubW9kZWxzXTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVwcmVjYXRlZCB3aWxsIGJlIHJlbW92ZWQgaW4gcmVsZWFzZS8xOC41Ny4wXG4gICAqIFxuICAgKiBSZW1vdmUgYSBtb2RlbCBmcm9tIHRoZSBsaXN0LlxuICAgKiBAcGFyYW0gaW5kZXggSW5kZXggb2YgdGhlIG1vZGVsIGluIHRoZSBsaXN0LlxuICAgKi9cbiAgbW9kZWxEZWxldGVkKGluZGV4OiBudW1iZXIpOiB2b2lkIHtcbiAgICB0aGlzLm1vZGVscy5zcGxpY2UoaW5kZXgsIDEpO1xuICAgIHRoaXMubW9kZWxzID0gWy4uLnRoaXMubW9kZWxzXTtcbiAgfVxuXG4gIC8qKlxuICAgKiBVc2VkIGZvciBtdWx0aSBzZWxlY3RcbiAgICogVHJpZ2VycmVkIHdoZW4gc2VsZWN0IGFsbCBpcyB0b2dnbGVkXG4gICAqL1xuICBzZWxlY3RBbGwoKTogdm9pZCB7XG4gICAgdGhpcy5zZWxlY3RlZE1vZGVsSWRzID0gW107XG4gICAgdGhpcy5tb2RlbHMubWFwKChtb2RlbDogYW55KSA9PiB7XG4gICAgICBtb2RlbC5pc19zZWxlY3RlZCA9IHRoaXMuaXNBbGxTZWxlY3RlZDtcbiAgICAgIGlmICh0aGlzLmlzQWxsU2VsZWN0ZWQpIHtcbiAgICAgICAgdGhpcy5zZWxlY3RlZE1vZGVsSWRzLnB1c2gobW9kZWwuaWQpO1xuICAgICAgfVxuICAgIH0pO1xuICAgIHRoaXMubW9kZWxzID0gWy4uLnRoaXMubW9kZWxzXTtcbiAgfVxuXG4gIC8qKlxuICAgKiBVc2VkIGZvciBtdWx0aSBzZWxlY3RcbiAgICogVHJpZ2VycmVkIGlmIGFueSBlbnRyeSBzZWN0aW9uIGlzIG1vZGlmaWVkXG4gICAqL1xuICBpc1NlbGVjdGlvbk1vZGlmaWVkKGV2ZW50OiBhbnksIG1vZGVsOiBhbnkpOiB2b2lkIHtcbiAgICB0aGlzLmlzQWxsU2VsZWN0ZWQgPSBmYWxzZTtcbiAgICBpZiAoZXZlbnQuY2hlY2tlZCkge1xuICAgICAgdGhpcy5zZWxlY3RlZE1vZGVsSWRzLnB1c2gobW9kZWw/LmlkKTtcbiAgICB9XG4gICAgZWxzZSB7XG4gICAgICB0aGlzLnNlbGVjdGVkTW9kZWxJZHMgPSB0aGlzLnNlbGVjdGVkTW9kZWxJZHMuZmlsdGVyKChtb2RlbElkOiBhbnkpID0+IG1vZGVsSWQgIT0gbW9kZWw/LmlkKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogRGVmdWFsdCBtZXRob2QgdG8gbGlzdGVuIHRvIHNvcnQgY29sdW1uIHVwZGF0ZXNcbiAgICogQHBhcmFtIGV2ZW50IFxuICAgKi9cbiAgc29ydENvbHVtbihldmVudDogYW55KSB7XG4gICAgY29uc3QgZGlyZWN0aW9uID0gZXZlbnQuZGlyZWN0aW9uLnRvU3RyaW5nKCkudG9VcHBlckNhc2UoKTtcbiAgICB0aGlzLm1vZGVscyA9IFtdO1xuICAgIHRoaXMuZmlsdGVyRm9ybS5nZXQoJ3NvcnRfYnknKS5zZXRWYWx1ZShgJHtldmVudD8uYWN0aXZlfXwke2RpcmVjdGlvbn1gKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBJdCBzaG91bGQgYmUgb3ZlcnJpZGVkIGluIGNoaWxkIGNsYXNzIHRvIHJlc2V0IGEgZmlsdGVyIGZvcm0gaW5zdGFuY2UuXG4gICAqIFVzZWQgYnkgc2V0VmlldyBtZXRob2QuXG4gICAqL1xuICBwcm90ZWN0ZWQgcmVzZXRGaWx0ZXJGb3JtKCk6IHZvaWQge1xuICAgIC8vSWYgZmlsdGVyRm9ybSBleGlzdHMsIHRoZW4gcmVzZXRcbiAgICBpZiAodGhpcy5maWx0ZXJGb3JtKSB7XG4gICAgICB0aGlzLmZpbHRlckZvcm0ucmVzZXQoKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogSXQgc2hvdWxkIGJlIG92ZXJyaWRlZCBpbiBjaGlsZCBjbGFzcyB0byByZXNldCBjb2x1bW4gY29uZmlncy5cbiAgICogVXNlZCBieSBzZXRWaWV3IG1ldGhvZC5cbiAgICovXG4gIHByb3RlY3RlZCByZXNldENvbHVtbkNvbmZpZ3MoKTogdm9pZCB7XG4gICAgdGhpcy5jb2x1bW5Db25maWdzID0gW107XG4gIH1cblxuICAvKipcbiAgICogSG9vayBtZXRob2QgdXNlZCB0byBzZXQgdGhlIHNlbGVjdGVkIHZpZXdcbiAgICogQHBhcmFtIHZpZXcgb3B0aW9uYWwgdXNlZCBieSBteS12aWV3LWxpc3RcbiAgICovXG4gIHNldFZpZXcodmlldz86IGFueSkge1xuICAgIC8vUmVzZXQgdGhlIHF1ZXJ5IHBhcmFtc1xuICAgIHRoaXMucmVxdWVzdEhlbHBlclNlcnZpY2UudXBkYXRlUXVlcnlQYXJhbXMoe30pO1xuICAgIHRoaXMuaXNWaWV3TG9hZGVkID0gZmFsc2U7XG4gICAgdGhpcy5yZXNldENvbHVtbkNvbmZpZ3MoKTtcbiAgICB0aGlzLnJlc2V0RmlsdGVyRm9ybSgpO1xuICAgIHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgaWYgKHZpZXcpIHtcbiAgICAgICAgLy9JZiB0aGVyZSBpcyBhIHZpZXcsIHRoZW4gc2V0IGl0LlxuICAgICAgICAvL1NldHVwIHZpZXcgZmlsdGVyc1xuICAgICAgICB0aGlzLmZpbHRlckZvcm0uc2V0VmFsdWUodGhpcy5yZXF1ZXN0SGVscGVyU2VydmljZS5jb252ZXJ0VG9Gb3JtRGF0YSh2aWV3Py5maWx0ZXJzKSk7XG4gICAgICAgIC8vU2V0dXAgdmlldyBjb2x1bW5zXG4gICAgICAgIHRoaXMuY29sdW1uQ29uZmlncy5mb3JFYWNoKGNvbHVtbiA9PiB7XG4gICAgICAgICAgY29sdW1uLmlzU2VsZWN0ZWQgPSAodmlldz8uY29sdW1ucyBhcyBzdHJpbmdbXSkuc29tZShjb2wgPT4gY29sID09PSBjb2x1bW4uZGVmKTtcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgICB0aGlzLmlzVmlld0xvYWRlZCA9IHRydWU7XG4gICAgfSwgNTAwKTtcbiAgfVxufVxuIl19
@@ -0,0 +1,68 @@
1
+ /**
2
+ * Interface used to ensure we have a consistent structure across our listing pages
3
+ *
4
+ * Advantages of this abstract class
5
+ * - Less code, less maintenance, less bugs
6
+ * - more consistent code
7
+ * - comments on more code
8
+ * - save time, save energy
9
+ */
10
+ export class TechlifyService {
11
+ constructor(http, baseUrl) {
12
+ this.http = http;
13
+ this.baseUrl = 'you-forgot-to-set-a-base-url';
14
+ this.baseUrl = baseUrl;
15
+ }
16
+ /**
17
+ * Loads a set of the model this service is for
18
+ *
19
+ * @param params Query parameters
20
+ * @return Observable<any>
21
+ */
22
+ index(params, isCache) {
23
+ if (isCache) {
24
+ return this.http.cache().get(`api/${this.baseUrl}`, { params });
25
+ }
26
+ return this.http.get(`api/${this.baseUrl}`, { params });
27
+ }
28
+ /**
29
+ * Add a new record to the database
30
+ *
31
+ * @param model The data of the model to add
32
+ * @param params Query parameters
33
+ * @return Observable<any>
34
+ */
35
+ store(model, params) {
36
+ return this.http.post(`api/${this.baseUrl}`, model, { params });
37
+ }
38
+ /**
39
+ * Load a single model record, often with all relations and related data
40
+ *
41
+ * @param modelId ID of the model to load
42
+ * @param params Query parameters
43
+ * @return Observable<any>
44
+ */
45
+ show(modelId, params) {
46
+ return this.http.get(`api/${this.baseUrl}/${modelId}`, { params });
47
+ }
48
+ /**
49
+ * Update fields of a single existing model
50
+ *
51
+ * @param model Model to update
52
+ * @param params Query parameters
53
+ * @return Observable<any>
54
+ */
55
+ update(model, params) {
56
+ return this.http.put(`api/${this.baseUrl}/${model.id}`, model, { params });
57
+ }
58
+ /**
59
+ * Delete a single model
60
+ *
61
+ * @param model Model to delete
62
+ * @return Observable<any>
63
+ */
64
+ delete(model) {
65
+ return this.http.delete(`api/${this.baseUrl}/${model.id}`);
66
+ }
67
+ }
68
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGVjaGxpZnktc2VydmljZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL25neC10ZWNobGlmeS1jb3JlL3NyYy9saWIvYmFzZS1tb2RlbC90ZWNobGlmeS1zZXJ2aWNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUdBOzs7Ozs7OztHQVFHO0FBQ0gsTUFBTSxPQUFPLGVBQWU7SUFJMUIsWUFBc0IsSUFBaUIsRUFBRSxPQUFlO1FBQWxDLFNBQUksR0FBSixJQUFJLENBQWE7UUFGN0IsWUFBTyxHQUFHLDhCQUE4QixDQUFDO1FBR2pELElBQUksQ0FBQyxPQUFPLEdBQUcsT0FBTyxDQUFDO0lBQ3pCLENBQUM7SUFFRDs7Ozs7T0FLRztJQUNILEtBQUssQ0FBQyxNQUFZLEVBQUUsT0FBaUI7UUFDbkMsSUFBSSxPQUFPLEVBQUUsQ0FBQztZQUNaLE9BQU8sSUFBSSxDQUFDLElBQUksQ0FBQyxLQUFLLEVBQUUsQ0FBQyxHQUFHLENBQUMsT0FBTyxJQUFJLENBQUMsT0FBTyxFQUFFLEVBQUUsRUFBRSxNQUFNLEVBQUUsQ0FBQyxDQUFDO1FBQ2xFLENBQUM7UUFFRCxPQUFPLElBQUksQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLE9BQU8sSUFBSSxDQUFDLE9BQU8sRUFBRSxFQUFFLEVBQUUsTUFBTSxFQUFFLENBQUMsQ0FBQztJQUMxRCxDQUFDO0lBRUQ7Ozs7OztPQU1HO0lBQ0gsS0FBSyxDQUFDLEtBQVUsRUFBRSxNQUFZO1FBQzVCLE9BQU8sSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsT0FBTyxJQUFJLENBQUMsT0FBTyxFQUFFLEVBQUUsS0FBSyxFQUFFLEVBQUUsTUFBTSxFQUFFLENBQUMsQ0FBQztJQUNsRSxDQUFDO0lBRUQ7Ozs7OztPQU1HO0lBQ0gsSUFBSSxDQUFDLE9BQVksRUFBRSxNQUFZO1FBQzdCLE9BQU8sSUFBSSxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsT0FBTyxJQUFJLENBQUMsT0FBTyxJQUFJLE9BQU8sRUFBRSxFQUFFLEVBQUUsTUFBTSxFQUFFLENBQUMsQ0FBQztJQUNyRSxDQUFDO0lBRUQ7Ozs7OztPQU1HO0lBQ0gsTUFBTSxDQUFDLEtBQVUsRUFBRSxNQUFZO1FBQzdCLE9BQU8sSUFBSSxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsT0FBTyxJQUFJLENBQUMsT0FBTyxJQUFJLEtBQUssQ0FBQyxFQUFFLEVBQUUsRUFBRSxLQUFLLEVBQUUsRUFBRSxNQUFNLEVBQUUsQ0FBQyxDQUFDO0lBQzdFLENBQUM7SUFFRDs7Ozs7T0FLRztJQUNILE1BQU0sQ0FBQyxLQUFVO1FBQ2YsT0FBTyxJQUFJLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxPQUFPLElBQUksQ0FBQyxPQUFPLElBQUksS0FBSyxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUM7SUFDN0QsQ0FBQztDQUdGIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgSHR0cFNlcnZpY2UgfSBmcm9tICcuLi9jb3JlJztcbmltcG9ydCB7IE9ic2VydmFibGUgfSBmcm9tICdyeGpzJztcblxuLyoqXG4gKiBJbnRlcmZhY2UgdXNlZCB0byBlbnN1cmUgd2UgaGF2ZSBhIGNvbnNpc3RlbnQgc3RydWN0dXJlIGFjcm9zcyBvdXIgbGlzdGluZyBwYWdlc1xuICpcbiAqIEFkdmFudGFnZXMgb2YgdGhpcyBhYnN0cmFjdCBjbGFzc1xuICogLSBMZXNzIGNvZGUsIGxlc3MgbWFpbnRlbmFuY2UsIGxlc3MgYnVnc1xuICogLSBtb3JlIGNvbnNpc3RlbnQgY29kZVxuICogLSBjb21tZW50cyBvbiBtb3JlIGNvZGVcbiAqIC0gc2F2ZSB0aW1lLCBzYXZlIGVuZXJneVxuICovXG5leHBvcnQgY2xhc3MgVGVjaGxpZnlTZXJ2aWNlIHtcblxuICBwcm90ZWN0ZWQgYmFzZVVybCA9ICd5b3UtZm9yZ290LXRvLXNldC1hLWJhc2UtdXJsJztcblxuICBjb25zdHJ1Y3Rvcihwcm90ZWN0ZWQgaHR0cDogSHR0cFNlcnZpY2UsIGJhc2VVcmw6IHN0cmluZykge1xuICAgIHRoaXMuYmFzZVVybCA9IGJhc2VVcmw7XG4gIH1cblxuICAvKipcbiAgICogTG9hZHMgYSBzZXQgb2YgdGhlIG1vZGVsIHRoaXMgc2VydmljZSBpcyBmb3JcbiAgICpcbiAgICogQHBhcmFtIHBhcmFtcyBRdWVyeSBwYXJhbWV0ZXJzXG4gICAqIEByZXR1cm4gT2JzZXJ2YWJsZTxhbnk+XG4gICAqL1xuICBpbmRleChwYXJhbXM/OiBhbnksIGlzQ2FjaGU/OiBib29sZWFuKTogT2JzZXJ2YWJsZTxhbnk+IHtcbiAgICBpZiAoaXNDYWNoZSkge1xuICAgICAgcmV0dXJuIHRoaXMuaHR0cC5jYWNoZSgpLmdldChgYXBpLyR7dGhpcy5iYXNlVXJsfWAsIHsgcGFyYW1zIH0pO1xuICAgIH1cblxuICAgIHJldHVybiB0aGlzLmh0dHAuZ2V0KGBhcGkvJHt0aGlzLmJhc2VVcmx9YCwgeyBwYXJhbXMgfSk7XG4gIH1cblxuICAvKipcbiAgICogQWRkIGEgbmV3IHJlY29yZCB0byB0aGUgZGF0YWJhc2VcbiAgICpcbiAgICogQHBhcmFtIG1vZGVsIFRoZSBkYXRhIG9mIHRoZSBtb2RlbCB0byBhZGRcbiAgICogQHBhcmFtIHBhcmFtcyBRdWVyeSBwYXJhbWV0ZXJzXG4gICAqIEByZXR1cm4gT2JzZXJ2YWJsZTxhbnk+XG4gICAqL1xuICBzdG9yZShtb2RlbDogYW55LCBwYXJhbXM/OiBhbnkpOiBPYnNlcnZhYmxlPGFueT4ge1xuICAgIHJldHVybiB0aGlzLmh0dHAucG9zdChgYXBpLyR7dGhpcy5iYXNlVXJsfWAsIG1vZGVsLCB7IHBhcmFtcyB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBMb2FkIGEgc2luZ2xlIG1vZGVsIHJlY29yZCwgb2Z0ZW4gd2l0aCBhbGwgcmVsYXRpb25zIGFuZCByZWxhdGVkIGRhdGFcbiAgICpcbiAgICogQHBhcmFtIG1vZGVsSWQgSUQgb2YgdGhlIG1vZGVsIHRvIGxvYWRcbiAgICogQHBhcmFtIHBhcmFtcyBRdWVyeSBwYXJhbWV0ZXJzXG4gICAqIEByZXR1cm4gT2JzZXJ2YWJsZTxhbnk+XG4gICAqL1xuICBzaG93KG1vZGVsSWQ6IGFueSwgcGFyYW1zPzogYW55KTogT2JzZXJ2YWJsZTxhbnk+IHtcbiAgICByZXR1cm4gdGhpcy5odHRwLmdldChgYXBpLyR7dGhpcy5iYXNlVXJsfS8ke21vZGVsSWR9YCwgeyBwYXJhbXMgfSk7XG4gIH1cblxuICAvKipcbiAgICogVXBkYXRlIGZpZWxkcyBvZiBhIHNpbmdsZSBleGlzdGluZyBtb2RlbFxuICAgKlxuICAgKiBAcGFyYW0gbW9kZWwgTW9kZWwgdG8gdXBkYXRlXG4gICAqIEBwYXJhbSBwYXJhbXMgUXVlcnkgcGFyYW1ldGVyc1xuICAgKiBAcmV0dXJuIE9ic2VydmFibGU8YW55PlxuICAgKi9cbiAgdXBkYXRlKG1vZGVsOiBhbnksIHBhcmFtcz86IGFueSk6IE9ic2VydmFibGU8YW55PiB7XG4gICAgcmV0dXJuIHRoaXMuaHR0cC5wdXQoYGFwaS8ke3RoaXMuYmFzZVVybH0vJHttb2RlbC5pZH1gLCBtb2RlbCwgeyBwYXJhbXMgfSk7XG4gIH1cblxuICAvKipcbiAgICogRGVsZXRlIGEgc2luZ2xlIG1vZGVsXG4gICAqXG4gICAqIEBwYXJhbSBtb2RlbCBNb2RlbCB0byBkZWxldGVcbiAgICogQHJldHVybiBPYnNlcnZhYmxlPGFueT5cbiAgICovXG4gIGRlbGV0ZShtb2RlbDogYW55KTogT2JzZXJ2YWJsZTxhbnk+IHtcbiAgICByZXR1cm4gdGhpcy5odHRwLmRlbGV0ZShgYXBpLyR7dGhpcy5iYXNlVXJsfS8ke21vZGVsLmlkfWApO1xuICB9XG5cblxufVxuIl19
@@ -1,8 +1,8 @@
1
1
  import { Injectable } from '@angular/core';
2
- import { TechlifyServiceBaseClass } from '../base-model';
2
+ import { TechlifyService } from '../base-model';
3
3
  import * as i0 from "@angular/core";
4
4
  import * as i1 from "../core";
5
- export class ClientService extends TechlifyServiceBaseClass {
5
+ export class ClientService extends TechlifyService {
6
6
  constructor(httpService) {
7
7
  super(httpService, 'clients');
8
8
  this.httpService = httpService;
@@ -16,4 +16,4 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
16
16
  providedIn: 'root'
17
17
  }]
18
18
  }], ctorParameters: () => [{ type: i1.HttpService }] });
19
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2xpZW50LnNlcnZpY2UuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9uZ3gtdGVjaGxpZnktY29yZS9zcmMvbGliL2NvbXBhbnktaW5mb3JtYXRpb24vY2xpZW50LnNlcnZpY2UudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUMzQyxPQUFPLEVBQUUsd0JBQXdCLEVBQUUsTUFBTSxlQUFlLENBQUM7OztBQU16RCxNQUFNLE9BQU8sYUFBYyxTQUFRLHdCQUF3QjtJQUV6RCxZQUNZLFdBQXdCO1FBRWxDLEtBQUssQ0FBQyxXQUFXLEVBQUUsU0FBUyxDQUFDLENBQUM7UUFGcEIsZ0JBQVcsR0FBWCxXQUFXLENBQWE7SUFHcEMsQ0FBQzsrR0FOVSxhQUFhO21IQUFiLGFBQWEsY0FGWixNQUFNOzs0RkFFUCxhQUFhO2tCQUh6QixVQUFVO21CQUFDO29CQUNWLFVBQVUsRUFBRSxNQUFNO2lCQUNuQiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IEluamVjdGFibGUgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IFRlY2hsaWZ5U2VydmljZUJhc2VDbGFzcyB9IGZyb20gJy4uL2Jhc2UtbW9kZWwnO1xuaW1wb3J0IHsgSHR0cFNlcnZpY2UgfSBmcm9tICcuLi9jb3JlJztcblxuQEluamVjdGFibGUoe1xuICBwcm92aWRlZEluOiAncm9vdCdcbn0pXG5leHBvcnQgY2xhc3MgQ2xpZW50U2VydmljZSBleHRlbmRzIFRlY2hsaWZ5U2VydmljZUJhc2VDbGFzcyB7XG5cbiAgY29uc3RydWN0b3IoXG4gICAgcHJvdGVjdGVkIGh0dHBTZXJ2aWNlOiBIdHRwU2VydmljZVxuICApIHtcbiAgICBzdXBlcihodHRwU2VydmljZSwgJ2NsaWVudHMnKTtcbiAgfVxufVxuIl19
19
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2xpZW50LnNlcnZpY2UuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9uZ3gtdGVjaGxpZnktY29yZS9zcmMvbGliL2NvbXBhbnktaW5mb3JtYXRpb24vY2xpZW50LnNlcnZpY2UudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUMzQyxPQUFPLEVBQUUsZUFBZSxFQUFFLE1BQU0sZUFBZSxDQUFDOzs7QUFNaEQsTUFBTSxPQUFPLGFBQWMsU0FBUSxlQUFlO0lBRWhELFlBQ1ksV0FBd0I7UUFFbEMsS0FBSyxDQUFDLFdBQVcsRUFBRSxTQUFTLENBQUMsQ0FBQztRQUZwQixnQkFBVyxHQUFYLFdBQVcsQ0FBYTtJQUdwQyxDQUFDOytHQU5VLGFBQWE7bUhBQWIsYUFBYSxjQUZaLE1BQU07OzRGQUVQLGFBQWE7a0JBSHpCLFVBQVU7bUJBQUM7b0JBQ1YsVUFBVSxFQUFFLE1BQU07aUJBQ25CIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgSW5qZWN0YWJsZSB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgVGVjaGxpZnlTZXJ2aWNlIH0gZnJvbSAnLi4vYmFzZS1tb2RlbCc7XG5pbXBvcnQgeyBIdHRwU2VydmljZSB9IGZyb20gJy4uL2NvcmUnO1xuXG5ASW5qZWN0YWJsZSh7XG4gIHByb3ZpZGVkSW46ICdyb290J1xufSlcbmV4cG9ydCBjbGFzcyBDbGllbnRTZXJ2aWNlIGV4dGVuZHMgVGVjaGxpZnlTZXJ2aWNlIHtcblxuICBjb25zdHJ1Y3RvcihcbiAgICBwcm90ZWN0ZWQgaHR0cFNlcnZpY2U6IEh0dHBTZXJ2aWNlXG4gICkge1xuICAgIHN1cGVyKGh0dHBTZXJ2aWNlLCAnY2xpZW50cycpO1xuICB9XG59XG4iXX0=