@rosoftlab/core 0.0.100
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.
- package/README.md +6 -0
- package/esm2020/lib/base-components/base-form-edit.component.mjs +242 -0
- package/esm2020/lib/base-components/field-error-display/field-error-display.component.mjs +15 -0
- package/esm2020/lib/base-components/generic-table/generic-table.component.mjs +431 -0
- package/esm2020/lib/base-components/index.mjs +5 -0
- package/esm2020/lib/base-components/page-not-found/page-not-found.component.mjs +15 -0
- package/esm2020/lib/base-components/searchable-dropdown/searchable-dropdown.component.mjs +231 -0
- package/esm2020/lib/base-components/under-construction/under-construction.component.mjs +12 -0
- package/esm2020/lib/constants/symbols.mjs +3 -0
- package/esm2020/lib/converters/date/date.converter.mjs +12 -0
- package/esm2020/lib/decorators/attribute.decorator.mjs +85 -0
- package/esm2020/lib/decorators/base-datastore-config.decorator.mjs +7 -0
- package/esm2020/lib/decorators/base-model-config.decorator.mjs +10 -0
- package/esm2020/lib/decorators/custom.type.decorator.mjs +11 -0
- package/esm2020/lib/decorators/grid-layout.decorator.mjs +23 -0
- package/esm2020/lib/directives/translated-content.directive.mjs +96 -0
- package/esm2020/lib/directives/translated-element.directive.mjs +20 -0
- package/esm2020/lib/index.mjs +29 -0
- package/esm2020/lib/interfaces/attribute-decorator-options.interface.mjs +2 -0
- package/esm2020/lib/interfaces/datastore-config.interface.mjs +2 -0
- package/esm2020/lib/interfaces/model-config.interface.mjs +2 -0
- package/esm2020/lib/interfaces/overrides.interface.mjs +2 -0
- package/esm2020/lib/interfaces/property-converter.interface.mjs +2 -0
- package/esm2020/lib/material.mjs +94 -0
- package/esm2020/lib/models/base-meta.model.mjs +7 -0
- package/esm2020/lib/models/base-query-data.mjs +13 -0
- package/esm2020/lib/models/base.model.mjs +171 -0
- package/esm2020/lib/models/error-response.model.mjs +9 -0
- package/esm2020/lib/models/grid-layout-format.enum.mjs +15 -0
- package/esm2020/lib/models/grid-layout.mjs +18 -0
- package/esm2020/lib/models/rule.mjs +6 -0
- package/esm2020/lib/module.mjs +55 -0
- package/esm2020/lib/pipes/Nl2brPipe.pipe.mjs +21 -0
- package/esm2020/lib/pipes/input-error.pipe.mjs +37 -0
- package/esm2020/lib/providers.mjs +10 -0
- package/esm2020/lib/services/base-datastore.service.mjs +333 -0
- package/esm2020/lib/services/base.service.mjs +95 -0
- package/esm2020/lib/services/dialog.service.mjs +150 -0
- package/esm2020/lib/services/grid-layout.service.mjs +21 -0
- package/esm2020/lib/services/index.mjs +5 -0
- package/esm2020/lib/validators/pattern-validator.mjs +15 -0
- package/esm2020/public-api.mjs +12 -0
- package/esm2020/rosoftlab-core.mjs +5 -0
- package/fesm2015/rosoftlab-core.mjs +2217 -0
- package/fesm2015/rosoftlab-core.mjs.map +1 -0
- package/fesm2020/rosoftlab-core.mjs +2210 -0
- package/fesm2020/rosoftlab-core.mjs.map +1 -0
- package/lib/base-components/base-form-edit.component.d.ts +58 -0
- package/lib/base-components/field-error-display/field-error-display.component.d.ts +7 -0
- package/lib/base-components/generic-table/generic-table.component.d.ts +93 -0
- package/lib/base-components/index.d.ts +4 -0
- package/lib/base-components/page-not-found/page-not-found.component.d.ts +8 -0
- package/lib/base-components/searchable-dropdown/searchable-dropdown.component.d.ts +62 -0
- package/lib/base-components/under-construction/under-construction.component.d.ts +6 -0
- package/lib/constants/symbols.d.ts +1 -0
- package/lib/converters/date/date.converter.d.ts +5 -0
- package/lib/decorators/attribute.decorator.d.ts +2 -0
- package/lib/decorators/base-datastore-config.decorator.d.ts +1 -0
- package/lib/decorators/base-model-config.decorator.d.ts +1 -0
- package/lib/decorators/custom.type.decorator.d.ts +1 -0
- package/lib/decorators/grid-layout.decorator.d.ts +2 -0
- package/lib/directives/translated-content.directive.d.ts +21 -0
- package/lib/directives/translated-element.directive.d.ts +10 -0
- package/lib/index.d.ts +27 -0
- package/lib/interfaces/attribute-decorator-options.interface.d.ts +8 -0
- package/lib/interfaces/datastore-config.interface.d.ts +8 -0
- package/lib/interfaces/model-config.interface.d.ts +8 -0
- package/lib/interfaces/overrides.interface.d.ts +5 -0
- package/lib/interfaces/property-converter.interface.d.ts +4 -0
- package/lib/material.d.ts +42 -0
- package/lib/models/base-meta.model.d.ts +5 -0
- package/lib/models/base-query-data.d.ts +7 -0
- package/lib/models/base.model.d.ts +33 -0
- package/lib/models/error-response.model.d.ts +17 -0
- package/lib/models/grid-layout-format.enum.d.ts +12 -0
- package/lib/models/grid-layout.d.ts +13 -0
- package/lib/models/rule.d.ts +5 -0
- package/lib/module.d.ts +14 -0
- package/lib/pipes/Nl2brPipe.pipe.d.ts +7 -0
- package/lib/pipes/input-error.pipe.d.ts +10 -0
- package/lib/providers.d.ts +2 -0
- package/lib/services/base-datastore.service.d.ts +45 -0
- package/lib/services/base.service.d.ts +26 -0
- package/lib/services/dialog.service.d.ts +21 -0
- package/lib/services/grid-layout.service.d.ts +9 -0
- package/lib/services/index.d.ts +4 -0
- package/lib/validators/pattern-validator.d.ts +4 -0
- package/package.json +53 -0
- package/public-api.d.ts +7 -0
- package/rosoftlab-core.d.ts +5 -0
|
@@ -0,0 +1,2210 @@
|
|
|
1
|
+
import * as i0 from '@angular/core';
|
|
2
|
+
import { Component, Input, EventEmitter, Optional, Self, Output, Injectable, ElementRef, ViewEncapsulation, ViewChild, Directive, ContentChildren, NgModule, Pipe } from '@angular/core';
|
|
3
|
+
import { coerceBooleanProperty } from '@angular/cdk/coercion';
|
|
4
|
+
import * as i2 from '@angular/forms';
|
|
5
|
+
import { FormControl, FormGroup, Validators, ReactiveFormsModule } from '@angular/forms';
|
|
6
|
+
import { Subject, Observable, throwError, from, merge, of, fromEvent, BehaviorSubject, combineLatest } from 'rxjs';
|
|
7
|
+
import { filter, debounceTime, tap, switchMap, finalize, takeUntil, map, catchError, distinctUntilChanged, startWith } from 'rxjs/operators';
|
|
8
|
+
import * as i1 from '@angular/cdk/a11y';
|
|
9
|
+
import * as i3 from '@angular/material/form-field';
|
|
10
|
+
import * as i4 from '@angular/material/button';
|
|
11
|
+
import { MatButtonModule } from '@angular/material/button';
|
|
12
|
+
import * as i5 from '@angular/material/icon';
|
|
13
|
+
import { MatIconModule } from '@angular/material/icon';
|
|
14
|
+
import * as i6 from '@angular/material/autocomplete';
|
|
15
|
+
import { MatAutocompleteModule } from '@angular/material/autocomplete';
|
|
16
|
+
import * as i7 from '@angular/material/core';
|
|
17
|
+
import { MatNativeDateModule, MatRippleModule, MatOptionModule } from '@angular/material/core';
|
|
18
|
+
import * as i8 from '@angular/material/input';
|
|
19
|
+
import { MatInputModule } from '@angular/material/input';
|
|
20
|
+
import * as i3$1 from '@angular/common';
|
|
21
|
+
import { DatePipe, DecimalPipe, PercentPipe, CommonModule } from '@angular/common';
|
|
22
|
+
import * as i1$1 from '@ngx-translate/core';
|
|
23
|
+
import { TranslateModule } from '@ngx-translate/core';
|
|
24
|
+
import { __decorate } from 'tslib';
|
|
25
|
+
import * as i2$2 from 'ng-block-ui';
|
|
26
|
+
import { BlockUI, BlockUIModule } from 'ng-block-ui';
|
|
27
|
+
import * as i2$1 from '@angular/router';
|
|
28
|
+
import * as i1$2 from '@angular/common/http';
|
|
29
|
+
import { HttpHeaders, HttpParams, HttpErrorResponse, HttpClientModule } from '@angular/common/http';
|
|
30
|
+
import { compare } from 'fast-json-patch';
|
|
31
|
+
import * as qs from 'qs';
|
|
32
|
+
import Swal from 'sweetalert2';
|
|
33
|
+
import * as i12 from '@angular/cdk/drag-drop';
|
|
34
|
+
import { moveItemInArray, DragDropModule } from '@angular/cdk/drag-drop';
|
|
35
|
+
import * as i9 from '@angular/material/paginator';
|
|
36
|
+
import { MatPaginator, MatPaginatorModule } from '@angular/material/paginator';
|
|
37
|
+
import * as i8$1 from '@angular/material/sort';
|
|
38
|
+
import { MatSort, MatSortModule } from '@angular/material/sort';
|
|
39
|
+
import * as i6$1 from '@angular/material/table';
|
|
40
|
+
import { MatTableDataSource, MatTableModule } from '@angular/material/table';
|
|
41
|
+
import * as jsonLogic from 'json-logic-js/logic.js';
|
|
42
|
+
import * as i5$1 from '@angular/material/progress-spinner';
|
|
43
|
+
import { MatProgressSpinnerModule } from '@angular/material/progress-spinner';
|
|
44
|
+
import * as i13 from '@angular/material/tooltip';
|
|
45
|
+
import { MatTooltipModule } from '@angular/material/tooltip';
|
|
46
|
+
import { parseISO } from 'date-fns';
|
|
47
|
+
import { MatButtonToggleModule } from '@angular/material/button-toggle';
|
|
48
|
+
import { MatCheckboxModule } from '@angular/material/checkbox';
|
|
49
|
+
import { MatChipsModule } from '@angular/material/chips';
|
|
50
|
+
import { MatGridListModule } from '@angular/material/grid-list';
|
|
51
|
+
import { MatMenuModule } from '@angular/material/menu';
|
|
52
|
+
import { MatProgressBarModule } from '@angular/material/progress-bar';
|
|
53
|
+
import { MatSelectModule } from '@angular/material/select';
|
|
54
|
+
import { MatSidenavModule } from '@angular/material/sidenav';
|
|
55
|
+
import { MatSlideToggleModule } from '@angular/material/slide-toggle';
|
|
56
|
+
import { MatSliderModule } from '@angular/material/slider';
|
|
57
|
+
import { MatSnackBarModule } from '@angular/material/snack-bar';
|
|
58
|
+
import { MatToolbarModule } from '@angular/material/toolbar';
|
|
59
|
+
import { MatCardModule } from '@angular/material/card';
|
|
60
|
+
import { MatTabsModule } from '@angular/material/tabs';
|
|
61
|
+
import { MatExpansionModule } from '@angular/material/expansion';
|
|
62
|
+
import { MatRadioModule } from '@angular/material/radio';
|
|
63
|
+
import { MatDatepickerModule } from '@angular/material/datepicker';
|
|
64
|
+
import { MatDividerModule } from '@angular/material/divider';
|
|
65
|
+
import { MatListModule } from '@angular/material/list';
|
|
66
|
+
import { MatDialogModule } from '@angular/material/dialog';
|
|
67
|
+
import { PortalModule } from '@angular/cdk/portal';
|
|
68
|
+
import { MatTreeModule } from '@angular/material/tree';
|
|
69
|
+
import { MatBadgeModule } from '@angular/material/badge';
|
|
70
|
+
import { MatStepperModule } from '@angular/material/stepper';
|
|
71
|
+
import { CdkStepperModule } from '@angular/cdk/stepper';
|
|
72
|
+
|
|
73
|
+
class FieldErrorDisplayComponent {
|
|
74
|
+
}
|
|
75
|
+
FieldErrorDisplayComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.0", ngImport: i0, type: FieldErrorDisplayComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
76
|
+
FieldErrorDisplayComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.3.0", type: FieldErrorDisplayComponent, selector: "rsl-field-error-display", inputs: { errorMsg: "errorMsg", displayError: "displayError" }, ngImport: i0, template: "<div *ngIf=\"displayError\" >\n <!-- <span class=\"glyphicon glyphicon-remove form-control-feedback fix-error-icon\"></span> -->\n <span class=\"sr-only\">(error)</span>\n <div class=\"error-msg\">\n {{ errorMsg }}\n </div>\n</div>\n", styles: [".error-msg{color:red}.fix-error-icon{top:27px}\n"] });
|
|
77
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.0", ngImport: i0, type: FieldErrorDisplayComponent, decorators: [{
|
|
78
|
+
type: Component,
|
|
79
|
+
args: [{ selector: 'rsl-field-error-display', template: "<div *ngIf=\"displayError\" >\n <!-- <span class=\"glyphicon glyphicon-remove form-control-feedback fix-error-icon\"></span> -->\n <span class=\"sr-only\">(error)</span>\n <div class=\"error-msg\">\n {{ errorMsg }}\n </div>\n</div>\n", styles: [".error-msg{color:red}.fix-error-icon{top:27px}\n"] }]
|
|
80
|
+
}], propDecorators: { errorMsg: [{
|
|
81
|
+
type: Input
|
|
82
|
+
}], displayError: [{
|
|
83
|
+
type: Input
|
|
84
|
+
}] } });
|
|
85
|
+
|
|
86
|
+
class PageNotFoundComponent {
|
|
87
|
+
constructor() {
|
|
88
|
+
}
|
|
89
|
+
ngOnInit() {
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
PageNotFoundComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.0", ngImport: i0, type: PageNotFoundComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
93
|
+
PageNotFoundComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.3.0", type: PageNotFoundComponent, selector: "rsl-page-not-found", ngImport: i0, template: "<div class=\"forms-view-container\">\n <div class=\"under-construction-view-container\">\n Page not found\n </div>\n</div>", styles: [".under-construction-view-container{height:calc(100vh - 250px);margin:60px 0 0;padding:0;display:flex;justify-content:center;align-items:center;box-sizing:border-box;font-size:1.8em;line-height:1.3em;font-weight:300;color:#58585b;text-align:center}\n"] });
|
|
94
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.0", ngImport: i0, type: PageNotFoundComponent, decorators: [{
|
|
95
|
+
type: Component,
|
|
96
|
+
args: [{ selector: 'rsl-page-not-found', template: "<div class=\"forms-view-container\">\n <div class=\"under-construction-view-container\">\n Page not found\n </div>\n</div>", styles: [".under-construction-view-container{height:calc(100vh - 250px);margin:60px 0 0;padding:0;display:flex;justify-content:center;align-items:center;box-sizing:border-box;font-size:1.8em;line-height:1.3em;font-weight:300;color:#58585b;text-align:center}\n"] }]
|
|
97
|
+
}], ctorParameters: function () { return []; } });
|
|
98
|
+
|
|
99
|
+
class SearchableDropdownComponent {
|
|
100
|
+
constructor(_focusMonitor, _elementRef, ngControl) {
|
|
101
|
+
this._focusMonitor = _focusMonitor;
|
|
102
|
+
this._elementRef = _elementRef;
|
|
103
|
+
this.ngControl = ngControl;
|
|
104
|
+
this.onChange = (_) => { };
|
|
105
|
+
this.onTouched = () => { };
|
|
106
|
+
this.stateChanges = new Subject();
|
|
107
|
+
this.focused = false;
|
|
108
|
+
this.errorState = false;
|
|
109
|
+
this.id = `rsl-searchable-dropdown-${SearchableDropdownComponent.nextId++}`;
|
|
110
|
+
// label for the search dropdown
|
|
111
|
+
this.label = '';
|
|
112
|
+
//Fields for sorting the API data
|
|
113
|
+
this.sortFields = '';
|
|
114
|
+
// The value used to populate the control value
|
|
115
|
+
this.valueField = 'id';
|
|
116
|
+
// The minumum char for search
|
|
117
|
+
this.minLengthTerm = 3;
|
|
118
|
+
this.modelSelected = new EventEmitter();
|
|
119
|
+
this._required = false;
|
|
120
|
+
this._disabled = false;
|
|
121
|
+
this.showSerach = true;
|
|
122
|
+
this.isLoading = false;
|
|
123
|
+
this.options = [];
|
|
124
|
+
this.filteredOptions = [];
|
|
125
|
+
/** Subject that emits when the component has been destroyed. */
|
|
126
|
+
this._onDestroy = new Subject();
|
|
127
|
+
this.searchControl = new FormControl('');
|
|
128
|
+
_focusMonitor.monitor(_elementRef, true).subscribe(origin => {
|
|
129
|
+
if (this.focused && !origin) {
|
|
130
|
+
this.onTouched();
|
|
131
|
+
}
|
|
132
|
+
this.focused = !!origin;
|
|
133
|
+
this.stateChanges.next();
|
|
134
|
+
});
|
|
135
|
+
if (this.ngControl) {
|
|
136
|
+
this.ngControl.valueAccessor = this;
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
get empty() {
|
|
140
|
+
return !this.value;
|
|
141
|
+
}
|
|
142
|
+
get required() { return this._required; }
|
|
143
|
+
set required(value) {
|
|
144
|
+
this._required = coerceBooleanProperty(value);
|
|
145
|
+
this.stateChanges.next();
|
|
146
|
+
}
|
|
147
|
+
get disabled() { return this._disabled; }
|
|
148
|
+
set disabled(value) {
|
|
149
|
+
this._disabled = coerceBooleanProperty(value);
|
|
150
|
+
this.stateChanges.next();
|
|
151
|
+
}
|
|
152
|
+
get value() {
|
|
153
|
+
return this._value;
|
|
154
|
+
}
|
|
155
|
+
set value(value) {
|
|
156
|
+
if (value)
|
|
157
|
+
if (this._value !== value) {
|
|
158
|
+
this.loadModel(value);
|
|
159
|
+
}
|
|
160
|
+
this._value = value;
|
|
161
|
+
this.stateChanges.next();
|
|
162
|
+
}
|
|
163
|
+
ngOnInit() {
|
|
164
|
+
if (!this.displayFields)
|
|
165
|
+
this.displayFields = this.searchFields;
|
|
166
|
+
this.loadModel(this.ngControl.value);
|
|
167
|
+
if (this.preloadElementsCount) {
|
|
168
|
+
this.serviceRef.getAll(1, this.preloadElementsCount).subscribe({
|
|
169
|
+
next: (data) => {
|
|
170
|
+
this.showSerach = false;
|
|
171
|
+
this.options = data.getModels();
|
|
172
|
+
this.filteredOptions = this.options;
|
|
173
|
+
}
|
|
174
|
+
});
|
|
175
|
+
}
|
|
176
|
+
this.searchControl.valueChanges
|
|
177
|
+
.pipe(filter((res) => {
|
|
178
|
+
const result = res !== null && res.length >= this.minLengthTerm;
|
|
179
|
+
if (!result) {
|
|
180
|
+
this.options = [];
|
|
181
|
+
this.filteredOptions = [];
|
|
182
|
+
}
|
|
183
|
+
this.showSerach = !result;
|
|
184
|
+
return result;
|
|
185
|
+
}), debounceTime(300), tap(() => {
|
|
186
|
+
this.filteredOptions = [];
|
|
187
|
+
this.isLoading = true;
|
|
188
|
+
}), switchMap((value) => this.serviceRef
|
|
189
|
+
.getAll(1, 10, this.sortFields, `${this.searchFields.replace(',', '|')}@=*${value}`)
|
|
190
|
+
.pipe(finalize(() => {
|
|
191
|
+
this.isLoading = false;
|
|
192
|
+
}))), takeUntil(this._onDestroy))
|
|
193
|
+
.subscribe((options) => {
|
|
194
|
+
this.filteredOptions = options.getModels();
|
|
195
|
+
});
|
|
196
|
+
}
|
|
197
|
+
onSelected($event) {
|
|
198
|
+
const value = $event.option.value;
|
|
199
|
+
this.searchControl.setValue(value);
|
|
200
|
+
this.modelSelected.emit(value);
|
|
201
|
+
if (this.valueField in value) {
|
|
202
|
+
this.setControlValue(value[this.valueField]);
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
setControlValue(value) {
|
|
206
|
+
this.value = value;
|
|
207
|
+
this.ngControl.control.setValue(value);
|
|
208
|
+
}
|
|
209
|
+
displayWith(value) {
|
|
210
|
+
return this.getConcatedFields(value);
|
|
211
|
+
}
|
|
212
|
+
clearSelection() {
|
|
213
|
+
this.modelSelected.emit(null);
|
|
214
|
+
this.setControlValue(null);
|
|
215
|
+
this.searchControl.setValue(null);
|
|
216
|
+
this.filteredOptions = this.options;
|
|
217
|
+
}
|
|
218
|
+
getConcatedFields(option) {
|
|
219
|
+
if (!option)
|
|
220
|
+
return null;
|
|
221
|
+
const filtersArr = this.displayFields.split(',');
|
|
222
|
+
return filtersArr.reduce((acc, cv) => {
|
|
223
|
+
return acc.concat(option[cv] + ' ');
|
|
224
|
+
}, '');
|
|
225
|
+
}
|
|
226
|
+
ngOnDestroy() {
|
|
227
|
+
this.searchControl = null;
|
|
228
|
+
this.stateChanges.complete();
|
|
229
|
+
this._focusMonitor.stopMonitoring(this._elementRef);
|
|
230
|
+
this._onDestroy.next();
|
|
231
|
+
this._onDestroy.complete();
|
|
232
|
+
}
|
|
233
|
+
getSearchText() {
|
|
234
|
+
return `Enter ${this.minLengthTerm} characters to start search`;
|
|
235
|
+
}
|
|
236
|
+
writeValue(model) {
|
|
237
|
+
console.log(model);
|
|
238
|
+
this.value = model;
|
|
239
|
+
}
|
|
240
|
+
registerOnChange(fn) {
|
|
241
|
+
this.onChange = fn;
|
|
242
|
+
}
|
|
243
|
+
registerOnTouched(fn) {
|
|
244
|
+
this.onTouched = fn;
|
|
245
|
+
}
|
|
246
|
+
setDisabledState(isDisabled) {
|
|
247
|
+
this.disabled = isDisabled;
|
|
248
|
+
}
|
|
249
|
+
loadModel(id) {
|
|
250
|
+
//Load the model from API to display the value
|
|
251
|
+
let needLoad = false;
|
|
252
|
+
if (id) {
|
|
253
|
+
if (!this.searchControl.value)
|
|
254
|
+
needLoad = true;
|
|
255
|
+
else {
|
|
256
|
+
if (this.searchControl.value[this.valueField] !== id) {
|
|
257
|
+
needLoad = true;
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
if (needLoad) {
|
|
262
|
+
this.serviceRef.get(id).subscribe({
|
|
263
|
+
next: (model) => {
|
|
264
|
+
this.options.push(model);
|
|
265
|
+
this.filteredOptions = this.options;
|
|
266
|
+
this.searchControl.setValue(model);
|
|
267
|
+
}
|
|
268
|
+
});
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
SearchableDropdownComponent.nextId = 0;
|
|
273
|
+
SearchableDropdownComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.0", ngImport: i0, type: SearchableDropdownComponent, deps: [{ token: i1.FocusMonitor }, { token: i0.ElementRef }, { token: i2.NgControl, optional: true, self: true }], target: i0.ɵɵFactoryTarget.Component });
|
|
274
|
+
SearchableDropdownComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.3.0", type: SearchableDropdownComponent, selector: "rsl-searchable-dropdown", inputs: { label: "label", fControlName: "fControlName", serviceRef: "serviceRef", searchFields: "searchFields", displayFields: "displayFields", sortFields: "sortFields", valueField: "valueField", minLengthTerm: "minLengthTerm", preloadElementsCount: "preloadElementsCount", required: "required", disabled: "disabled", value: "value" }, outputs: { modelSelected: "modelSelected" }, host: { properties: { "class.example-floating": "shouldLabelFloat", "id": "id", "attr.aria-describedby": "describedBy" } }, ngImport: i0, template: "<div class=\"form-group\">\r\n <label>{{label | translate}}</label>\r\n <mat-form-field appearance=\"outline\" fxFlex>\r\n <input matInput [matAutocomplete]=\"auto\" [formControl]=\"searchControl\">\r\n <button *ngIf=\"searchControl.value\" matSuffix mat-icon-button aria-label=\"Clear\" (click)=\"clearSelection()\">\r\n <mat-icon>close</mat-icon>\r\n </button>\r\n <mat-autocomplete #auto=\"matAutocomplete\" (optionSelected)=\"onSelected($event)\"\r\n [displayWith]=\"displayWith.bind(this)\">\r\n <mat-option *ngIf=\"isLoading\">Loading...</mat-option>\r\n <mat-option *ngIf=\"!isLoading && filteredOptions.length == 0 && !showSerach\" disabled>Not found</mat-option>\r\n <mat-option *ngIf=\"showSerach\" disabled>{{getSearchText()}}</mat-option>\r\n <ng-container *ngIf=\"!isLoading && filteredOptions.length > 0\">\r\n <mat-option *ngFor=\"let option of filteredOptions\" [value]=\"option\">\r\n <span><b>{{getConcatedFields(option)}}</b></span>\r\n </mat-option>\r\n </ng-container>\r\n\r\n </mat-autocomplete>\r\n </mat-form-field>\r\n</div>", components: [{ type: i3.MatFormField, selector: "mat-form-field", inputs: ["color", "appearance", "hideRequiredMarker", "hintLabel", "floatLabel"], exportAs: ["matFormField"] }, { type: i4.MatButton, selector: "button[mat-button], button[mat-raised-button], button[mat-icon-button], button[mat-fab], button[mat-mini-fab], button[mat-stroked-button], button[mat-flat-button]", inputs: ["disabled", "disableRipple", "color"], exportAs: ["matButton"] }, { type: i5.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { type: i6.MatAutocomplete, selector: "mat-autocomplete", inputs: ["disableRipple"], exportAs: ["matAutocomplete"] }, { type: i7.MatOption, selector: "mat-option", exportAs: ["matOption"] }], directives: [{ type: i8.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"] }, { type: i6.MatAutocompleteTrigger, selector: "input[matAutocomplete], textarea[matAutocomplete]", exportAs: ["matAutocompleteTrigger"] }, { type: i2.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { type: i2.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { type: i3$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i3.MatSuffix, selector: "[matSuffix]" }, { type: i3$1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }], pipes: { "translate": i1$1.TranslatePipe } });
|
|
275
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.0", ngImport: i0, type: SearchableDropdownComponent, decorators: [{
|
|
276
|
+
type: Component,
|
|
277
|
+
args: [{ selector: 'rsl-searchable-dropdown', host: {
|
|
278
|
+
'[class.example-floating]': 'shouldLabelFloat',
|
|
279
|
+
'[id]': 'id',
|
|
280
|
+
'[attr.aria-describedby]': 'describedBy',
|
|
281
|
+
}, template: "<div class=\"form-group\">\r\n <label>{{label | translate}}</label>\r\n <mat-form-field appearance=\"outline\" fxFlex>\r\n <input matInput [matAutocomplete]=\"auto\" [formControl]=\"searchControl\">\r\n <button *ngIf=\"searchControl.value\" matSuffix mat-icon-button aria-label=\"Clear\" (click)=\"clearSelection()\">\r\n <mat-icon>close</mat-icon>\r\n </button>\r\n <mat-autocomplete #auto=\"matAutocomplete\" (optionSelected)=\"onSelected($event)\"\r\n [displayWith]=\"displayWith.bind(this)\">\r\n <mat-option *ngIf=\"isLoading\">Loading...</mat-option>\r\n <mat-option *ngIf=\"!isLoading && filteredOptions.length == 0 && !showSerach\" disabled>Not found</mat-option>\r\n <mat-option *ngIf=\"showSerach\" disabled>{{getSearchText()}}</mat-option>\r\n <ng-container *ngIf=\"!isLoading && filteredOptions.length > 0\">\r\n <mat-option *ngFor=\"let option of filteredOptions\" [value]=\"option\">\r\n <span><b>{{getConcatedFields(option)}}</b></span>\r\n </mat-option>\r\n </ng-container>\r\n\r\n </mat-autocomplete>\r\n </mat-form-field>\r\n</div>" }]
|
|
282
|
+
}], ctorParameters: function () { return [{ type: i1.FocusMonitor }, { type: i0.ElementRef }, { type: i2.NgControl, decorators: [{
|
|
283
|
+
type: Optional
|
|
284
|
+
}, {
|
|
285
|
+
type: Self
|
|
286
|
+
}] }]; }, propDecorators: { label: [{
|
|
287
|
+
type: Input
|
|
288
|
+
}], fControlName: [{
|
|
289
|
+
type: Input
|
|
290
|
+
}], serviceRef: [{
|
|
291
|
+
type: Input
|
|
292
|
+
}], searchFields: [{
|
|
293
|
+
type: Input
|
|
294
|
+
}], displayFields: [{
|
|
295
|
+
type: Input
|
|
296
|
+
}], sortFields: [{
|
|
297
|
+
type: Input
|
|
298
|
+
}], valueField: [{
|
|
299
|
+
type: Input
|
|
300
|
+
}], minLengthTerm: [{
|
|
301
|
+
type: Input
|
|
302
|
+
}], preloadElementsCount: [{
|
|
303
|
+
type: Input
|
|
304
|
+
}], modelSelected: [{
|
|
305
|
+
type: Output
|
|
306
|
+
}], required: [{
|
|
307
|
+
type: Input
|
|
308
|
+
}], disabled: [{
|
|
309
|
+
type: Input
|
|
310
|
+
}], value: [{
|
|
311
|
+
type: Input
|
|
312
|
+
}] } });
|
|
313
|
+
|
|
314
|
+
class UnderConstructionComponent {
|
|
315
|
+
constructor() { }
|
|
316
|
+
}
|
|
317
|
+
UnderConstructionComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.0", ngImport: i0, type: UnderConstructionComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
318
|
+
UnderConstructionComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.3.0", type: UnderConstructionComponent, selector: "rsl-under-construction", ngImport: i0, template: "<div class=\"forms-view-container\">\n <div class=\"under-construction-view-container\">\n Page under construction\n </div>\n</div>", styles: [".under-construction-view-container{height:calc(100vh - 250px);margin:60px 0 0;padding:0;display:flex;justify-content:center;align-items:center;box-sizing:border-box;font-size:1.8em;line-height:1.3em;font-weight:300;color:#58585b;text-align:center}\n"] });
|
|
319
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.0", ngImport: i0, type: UnderConstructionComponent, decorators: [{
|
|
320
|
+
type: Component,
|
|
321
|
+
args: [{ selector: 'rsl-under-construction', template: "<div class=\"forms-view-container\">\n <div class=\"under-construction-view-container\">\n Page under construction\n </div>\n</div>", styles: [".under-construction-view-container{height:calc(100vh - 250px);margin:60px 0 0;padding:0;display:flex;justify-content:center;align-items:center;box-sizing:border-box;font-size:1.8em;line-height:1.3em;font-weight:300;color:#58585b;text-align:center}\n"] }]
|
|
322
|
+
}], ctorParameters: function () { return []; } });
|
|
323
|
+
|
|
324
|
+
class BaseQueryData {
|
|
325
|
+
constructor(jsonApiModels, metaData) {
|
|
326
|
+
this.jsonApiModels = jsonApiModels;
|
|
327
|
+
this.metaData = metaData;
|
|
328
|
+
}
|
|
329
|
+
getModels() {
|
|
330
|
+
return this.jsonApiModels;
|
|
331
|
+
}
|
|
332
|
+
getMeta() {
|
|
333
|
+
return this.metaData;
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
class BaseDatastore {
|
|
338
|
+
constructor(httpClient) {
|
|
339
|
+
this.httpClient = httpClient;
|
|
340
|
+
// tslint:disable-next-line:variable-name
|
|
341
|
+
this._store = {};
|
|
342
|
+
// tslint:enable:max-line-length
|
|
343
|
+
// tslint:disable-next-line:ban-types
|
|
344
|
+
this.toQueryString = this.datastoreConfig.overrides
|
|
345
|
+
&& this.datastoreConfig.overrides.toQueryString ?
|
|
346
|
+
this.datastoreConfig.overrides.toQueryString : this._toQueryString;
|
|
347
|
+
}
|
|
348
|
+
// tslint:enable:max-line-length
|
|
349
|
+
get getDirtyAttributes() {
|
|
350
|
+
if (this.datastoreConfig.overrides
|
|
351
|
+
&& this.datastoreConfig.overrides.getDirtyAttributes) {
|
|
352
|
+
return this.datastoreConfig.overrides.getDirtyAttributes;
|
|
353
|
+
}
|
|
354
|
+
else {
|
|
355
|
+
return BaseDatastore.getDirtyAttributes;
|
|
356
|
+
}
|
|
357
|
+
}
|
|
358
|
+
get getAllAttributes() {
|
|
359
|
+
if (this.datastoreConfig.overrides
|
|
360
|
+
&& this.datastoreConfig.overrides.getAllAttributes) {
|
|
361
|
+
return this.datastoreConfig.overrides.getAllAttributes;
|
|
362
|
+
}
|
|
363
|
+
else {
|
|
364
|
+
return BaseDatastore.getAllAttributes;
|
|
365
|
+
}
|
|
366
|
+
}
|
|
367
|
+
// protected config: DatastoreConfig;
|
|
368
|
+
static getDirtyAttributes(attributesMetadata) {
|
|
369
|
+
const dirtyData = {};
|
|
370
|
+
for (const propertyName in attributesMetadata) {
|
|
371
|
+
if (attributesMetadata.hasOwnProperty(propertyName)) {
|
|
372
|
+
const metadata = attributesMetadata[propertyName];
|
|
373
|
+
if (metadata.hasDirtyAttributes) {
|
|
374
|
+
const attributeName = metadata.serializedName != null ? metadata.serializedName : propertyName;
|
|
375
|
+
dirtyData[attributeName] = metadata.serialisationValue ? metadata.serialisationValue : metadata.newValue;
|
|
376
|
+
}
|
|
377
|
+
}
|
|
378
|
+
}
|
|
379
|
+
return dirtyData;
|
|
380
|
+
}
|
|
381
|
+
static getAllAttributes(attributesMetadata) {
|
|
382
|
+
const dirtyData = {};
|
|
383
|
+
for (const propertyName in attributesMetadata) {
|
|
384
|
+
if (attributesMetadata.hasOwnProperty(propertyName)) {
|
|
385
|
+
const metadata = attributesMetadata[propertyName];
|
|
386
|
+
const attributeName = metadata.serializedName != null ? metadata.serializedName : propertyName;
|
|
387
|
+
dirtyData[attributeName] = metadata.serialisationValue ? metadata.serialisationValue : metadata.newValue;
|
|
388
|
+
}
|
|
389
|
+
}
|
|
390
|
+
return dirtyData;
|
|
391
|
+
}
|
|
392
|
+
findAll(modelType, params, headers, customUrl) {
|
|
393
|
+
const customHeadhers = this.buildHeaders(headers);
|
|
394
|
+
const htmlParams = this.buildParams(params);
|
|
395
|
+
const url = this.buildUrl(modelType, customUrl);
|
|
396
|
+
const response = this.httpClient.get(url, { headers: customHeadhers, params: htmlParams, withCredentials: true })
|
|
397
|
+
.pipe(map(res => this.extractQueryData(res, modelType)), catchError(this.handleError));
|
|
398
|
+
return response;
|
|
399
|
+
}
|
|
400
|
+
findRecord(modelType, id, params, headers, customUrl) {
|
|
401
|
+
const customHeadhers = this.buildHeaders(headers);
|
|
402
|
+
let url = this.buildUrl(modelType, customUrl);
|
|
403
|
+
if (id) {
|
|
404
|
+
url += '/' + id;
|
|
405
|
+
}
|
|
406
|
+
const htmlParams = this.buildParams(params, undefined);
|
|
407
|
+
return this.httpClient.get(url, { headers: customHeadhers, params: htmlParams, withCredentials: true })
|
|
408
|
+
.pipe(map(res => this.entityToModel(res, modelType, undefined)), catchError(this.handleError));
|
|
409
|
+
}
|
|
410
|
+
getCustom(modelType, params, headers, customUrl, customResponseType) {
|
|
411
|
+
const customHeadhers = this.buildHeaders(headers);
|
|
412
|
+
const url = this.buildUrl(modelType, customUrl);
|
|
413
|
+
const htmlParams = this.buildParams(params, undefined);
|
|
414
|
+
if (!customResponseType)
|
|
415
|
+
customResponseType = 'json';
|
|
416
|
+
return this.httpClient.get(url, { headers: customHeadhers, params: htmlParams, withCredentials: true, responseType: customResponseType });
|
|
417
|
+
}
|
|
418
|
+
postCustom(modelType, body, params, headers, customUrl) {
|
|
419
|
+
const customHeadhers = this.buildHeaders(headers);
|
|
420
|
+
const url = this.buildUrl(modelType, customUrl);
|
|
421
|
+
const htmlParams = this.buildParams(params, undefined);
|
|
422
|
+
return this.httpClient.post(url, body, { headers: customHeadhers, params: htmlParams, reportProgress: true, withCredentials: true });
|
|
423
|
+
}
|
|
424
|
+
patchCustom(modelType, body, params, headers, customUrl) {
|
|
425
|
+
const customHeadhers = this.buildHeaders(headers);
|
|
426
|
+
const url = this.buildUrl(modelType, customUrl);
|
|
427
|
+
const htmlParams = this.buildParams(params, undefined);
|
|
428
|
+
return this.httpClient.patch(url, body, { headers: customHeadhers, params: htmlParams, withCredentials: true });
|
|
429
|
+
}
|
|
430
|
+
createRecord(modelType, data) {
|
|
431
|
+
return new modelType(this, data);
|
|
432
|
+
}
|
|
433
|
+
saveRecord(attributesMetadata, model, params, headers, customUrl, customBody) {
|
|
434
|
+
const modelType = model.constructor;
|
|
435
|
+
const modelConfig = model.modelConfig;
|
|
436
|
+
const customHeadhers = this.buildHeaders(headers);
|
|
437
|
+
const url = this.buildUrl(modelType, customUrl);
|
|
438
|
+
const htmlParams = this.buildParams(params);
|
|
439
|
+
let httpCall;
|
|
440
|
+
const body = customBody || this.modelToEntity(model, attributesMetadata);
|
|
441
|
+
if (model.id) {
|
|
442
|
+
// tslint:disable-next-line:max-line-length
|
|
443
|
+
httpCall = this.httpClient.patch(url + '/' + model.id, body, { headers: customHeadhers, params: htmlParams, withCredentials: true });
|
|
444
|
+
}
|
|
445
|
+
else {
|
|
446
|
+
httpCall = this.httpClient.post(url, body, { headers: customHeadhers, params: htmlParams, withCredentials: true });
|
|
447
|
+
}
|
|
448
|
+
return httpCall
|
|
449
|
+
.pipe(map(res => {
|
|
450
|
+
const data = this.resetMetadataAttributes(res, attributesMetadata, modelType);
|
|
451
|
+
return this.entityToModel(data, modelType);
|
|
452
|
+
}), catchError(this.handleError));
|
|
453
|
+
}
|
|
454
|
+
patchRecord(attributesMetadata, model, origModel, params, headers, customUrl) {
|
|
455
|
+
const modelType = model.constructor;
|
|
456
|
+
const modelConfig = model.modelConfig;
|
|
457
|
+
const customHeadhers = this.buildHeaders(headers);
|
|
458
|
+
const url = this.buildUrl(modelType, customUrl);
|
|
459
|
+
const htmlParams = this.buildParams(params);
|
|
460
|
+
let httpCall;
|
|
461
|
+
let origData = { id: '' };
|
|
462
|
+
if (origModel)
|
|
463
|
+
origData = this.modelToEntity(origModel, origModel.attributeMetadata, true);
|
|
464
|
+
const newData = this.modelToEntity(model, attributesMetadata, true);
|
|
465
|
+
newData.id = origData.id;
|
|
466
|
+
const patch = compare(origData, newData);
|
|
467
|
+
if (patch.length > 0) {
|
|
468
|
+
httpCall = this.httpClient.patch(url + '/' + model.id, patch, { headers: customHeadhers, params: htmlParams, withCredentials: true });
|
|
469
|
+
return httpCall
|
|
470
|
+
.pipe(map(res => {
|
|
471
|
+
const data = this.resetMetadataAttributes(res, attributesMetadata, modelType);
|
|
472
|
+
return this.entityToModel(data, modelType);
|
|
473
|
+
}), catchError(this.handleError));
|
|
474
|
+
}
|
|
475
|
+
else {
|
|
476
|
+
return new Observable((observer) => {
|
|
477
|
+
observer.next(model);
|
|
478
|
+
observer.complete();
|
|
479
|
+
});
|
|
480
|
+
}
|
|
481
|
+
}
|
|
482
|
+
// getPatch<T extends BaseModel>(
|
|
483
|
+
// model: T,
|
|
484
|
+
// origModel: T): any {
|
|
485
|
+
// }
|
|
486
|
+
replaceRecord(attributesMetadata, model, params, headers, customUrl, customBody) {
|
|
487
|
+
const modelType = model.constructor;
|
|
488
|
+
const modelConfig = model.modelConfig;
|
|
489
|
+
const customHeadhers = this.buildHeaders(headers);
|
|
490
|
+
const url = this.buildUrl(modelType, customUrl);
|
|
491
|
+
const htmlParams = this.buildParams(params);
|
|
492
|
+
let httpCall;
|
|
493
|
+
const body = customBody || this.modelToEntity(model, attributesMetadata, true);
|
|
494
|
+
if (model.id) {
|
|
495
|
+
httpCall = this.httpClient.put(url + '/' + model.id, body, { headers: customHeadhers, params: htmlParams, withCredentials: true });
|
|
496
|
+
}
|
|
497
|
+
else {
|
|
498
|
+
httpCall = this.httpClient.post(url, body, { headers: customHeadhers, params: htmlParams, withCredentials: true });
|
|
499
|
+
}
|
|
500
|
+
return httpCall
|
|
501
|
+
.pipe(map(res => {
|
|
502
|
+
const data = this.resetMetadataAttributes(res, attributesMetadata, modelType);
|
|
503
|
+
return this.entityToModel(data, modelType);
|
|
504
|
+
}), catchError(this.handleError));
|
|
505
|
+
}
|
|
506
|
+
deleteRecord(modelType, id, headers, customUrl) {
|
|
507
|
+
const customHeadhers = this.buildHeaders(headers);
|
|
508
|
+
let url = this.buildUrl(modelType, customUrl);
|
|
509
|
+
if (!url.includes('share')) {
|
|
510
|
+
url = url + '/' + id;
|
|
511
|
+
}
|
|
512
|
+
// const idParam = new HttpParams().set('id', id);
|
|
513
|
+
return this.httpClient.delete(url, { headers: customHeadhers, withCredentials: true })
|
|
514
|
+
.pipe(catchError(this.handleError));
|
|
515
|
+
}
|
|
516
|
+
buildUrl(modelType, customUrl) {
|
|
517
|
+
if (customUrl) {
|
|
518
|
+
return customUrl;
|
|
519
|
+
}
|
|
520
|
+
const modelConfig = Reflect.getMetadata('BaseModelConfig', modelType);
|
|
521
|
+
const baseUrl = modelConfig.baseUrl || this.datastoreConfig.baseUrl;
|
|
522
|
+
const apiVersion = modelConfig.apiVersion || this.datastoreConfig.apiVersion;
|
|
523
|
+
const modelEndpointUrl = modelConfig.modelEndpointUrl || modelConfig.type;
|
|
524
|
+
const url = [baseUrl, apiVersion, modelEndpointUrl].filter((x) => x).join('/');
|
|
525
|
+
return url;
|
|
526
|
+
}
|
|
527
|
+
extractQueryData(res, modelType) {
|
|
528
|
+
let result;
|
|
529
|
+
const body = res;
|
|
530
|
+
const models = [];
|
|
531
|
+
for (const data of body.data) {
|
|
532
|
+
const model = this.entityToModel(data, modelType, undefined);
|
|
533
|
+
models.push(model);
|
|
534
|
+
}
|
|
535
|
+
result = new BaseQueryData(models, this.parseMeta(body, modelType));
|
|
536
|
+
return result;
|
|
537
|
+
}
|
|
538
|
+
deserializeModel(modelType, data) {
|
|
539
|
+
data = this.transformSerializedNamesToPropertyNames(modelType, data);
|
|
540
|
+
return new modelType(this, data);
|
|
541
|
+
}
|
|
542
|
+
handleError(error) {
|
|
543
|
+
if (error.error instanceof ErrorEvent) {
|
|
544
|
+
// A client-side or network error occurred. Handle it accordingly.
|
|
545
|
+
// console.error('An error occurred:', error.error.message);
|
|
546
|
+
}
|
|
547
|
+
else {
|
|
548
|
+
// The backend returned an unsuccessful response code.
|
|
549
|
+
// The response body may contain clues as to what went wrong,
|
|
550
|
+
// console.error(
|
|
551
|
+
// 'Backend returned code ${error.status}, ' +
|
|
552
|
+
// 'body was: ${error.error}');
|
|
553
|
+
}
|
|
554
|
+
// return an observable with a user-facing error message
|
|
555
|
+
return throwError(error);
|
|
556
|
+
}
|
|
557
|
+
parseMeta(body, modelType) {
|
|
558
|
+
const metaModel = Reflect.getMetadata('BaseModelConfig', modelType).meta;
|
|
559
|
+
return new metaModel(body);
|
|
560
|
+
}
|
|
561
|
+
resetMetadataAttributes(res, attributesMetadata, modelType) {
|
|
562
|
+
// TODO check why is attributesMetadata from the arguments never used
|
|
563
|
+
for (const propertyName in attributesMetadata) {
|
|
564
|
+
if (attributesMetadata.hasOwnProperty(propertyName)) {
|
|
565
|
+
const metadata = attributesMetadata[propertyName];
|
|
566
|
+
if (metadata.hasDirtyAttributes) {
|
|
567
|
+
metadata.hasDirtyAttributes = false;
|
|
568
|
+
}
|
|
569
|
+
}
|
|
570
|
+
}
|
|
571
|
+
if (res) {
|
|
572
|
+
res.attributeMetadata = attributesMetadata;
|
|
573
|
+
}
|
|
574
|
+
return res;
|
|
575
|
+
}
|
|
576
|
+
get datastoreConfig() {
|
|
577
|
+
const configFromDecorator = Reflect.getMetadata('BaseDatastoreConfig', this.constructor);
|
|
578
|
+
return Object.assign(configFromDecorator, this.config);
|
|
579
|
+
}
|
|
580
|
+
transformSerializedNamesToPropertyNames(modelType, attributes) {
|
|
581
|
+
const serializedNameToPropertyName = this.getModelPropertyNames(modelType.prototype);
|
|
582
|
+
const properties = {};
|
|
583
|
+
Object.keys(serializedNameToPropertyName).forEach((serializedName) => {
|
|
584
|
+
if (attributes[serializedName] !== null && attributes[serializedName] !== undefined) {
|
|
585
|
+
properties[serializedNameToPropertyName[serializedName]] = attributes[serializedName];
|
|
586
|
+
}
|
|
587
|
+
});
|
|
588
|
+
return properties;
|
|
589
|
+
}
|
|
590
|
+
getModelPropertyNames(model) {
|
|
591
|
+
return Reflect.getMetadata('AttributeMapping', model);
|
|
592
|
+
}
|
|
593
|
+
buildHeaders(customHeaders) {
|
|
594
|
+
const headers = {
|
|
595
|
+
Accept: 'application/json-patch+json',
|
|
596
|
+
// 'Content-Type': 'application/vnd.api+json',
|
|
597
|
+
'Content-Type': 'application/json-patch+json'
|
|
598
|
+
};
|
|
599
|
+
if (customHeaders && customHeaders.keys().length) {
|
|
600
|
+
// tslint:disable-next-line:variable-name
|
|
601
|
+
Object.assign({}, headers, customHeaders.keys().map(header_name => {
|
|
602
|
+
headers['' + header_name] = customHeaders.get(header_name);
|
|
603
|
+
}));
|
|
604
|
+
}
|
|
605
|
+
return new HttpHeaders(headers);
|
|
606
|
+
}
|
|
607
|
+
buildParams(params, id) {
|
|
608
|
+
let httpParams = new HttpParams();
|
|
609
|
+
if (id) {
|
|
610
|
+
httpParams = httpParams.set('id', id);
|
|
611
|
+
}
|
|
612
|
+
if (params) {
|
|
613
|
+
Object.keys(params)
|
|
614
|
+
.filter(key => {
|
|
615
|
+
const v = params[key];
|
|
616
|
+
return (Array.isArray(v) || typeof v === 'string') ?
|
|
617
|
+
(v.length > 0) :
|
|
618
|
+
(v !== null && v !== undefined);
|
|
619
|
+
})
|
|
620
|
+
.forEach(key => {
|
|
621
|
+
httpParams = httpParams.set(key, params[key]);
|
|
622
|
+
});
|
|
623
|
+
}
|
|
624
|
+
return httpParams;
|
|
625
|
+
}
|
|
626
|
+
entityToModel(res, modelType, model) {
|
|
627
|
+
return this.extractRecordDataJson(res, modelType, model);
|
|
628
|
+
}
|
|
629
|
+
extractRecordDataJson(res, modelType, model) {
|
|
630
|
+
const body = res;
|
|
631
|
+
if (!body) {
|
|
632
|
+
throw new Error('no body in response');
|
|
633
|
+
}
|
|
634
|
+
if (model) {
|
|
635
|
+
Object.assign(model, body);
|
|
636
|
+
}
|
|
637
|
+
const deserializedModel = model || this.deserializeModel(modelType, body.data || body);
|
|
638
|
+
return deserializedModel;
|
|
639
|
+
}
|
|
640
|
+
modelToEntity(model, attributesMetadata, allAttributes = false) {
|
|
641
|
+
let attributes;
|
|
642
|
+
if (allAttributes) {
|
|
643
|
+
attributes = this.getAllAttributes(attributesMetadata, model);
|
|
644
|
+
}
|
|
645
|
+
else {
|
|
646
|
+
attributes = this.getDirtyAttributes(attributesMetadata, model);
|
|
647
|
+
}
|
|
648
|
+
// this.getRelationships(model, attributes);
|
|
649
|
+
return attributes;
|
|
650
|
+
}
|
|
651
|
+
_toQueryString(params) {
|
|
652
|
+
return qs.stringify(params, { arrayFormat: 'brackets' });
|
|
653
|
+
}
|
|
654
|
+
}
|
|
655
|
+
BaseDatastore.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.0", ngImport: i0, type: BaseDatastore, deps: [{ token: i1$2.HttpClient }], target: i0.ɵɵFactoryTarget.Injectable });
|
|
656
|
+
BaseDatastore.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "13.3.0", ngImport: i0, type: BaseDatastore });
|
|
657
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.0", ngImport: i0, type: BaseDatastore, decorators: [{
|
|
658
|
+
type: Injectable
|
|
659
|
+
}], ctorParameters: function () { return [{ type: i1$2.HttpClient }]; } });
|
|
660
|
+
|
|
661
|
+
class BaseService {
|
|
662
|
+
constructor(datastore) {
|
|
663
|
+
this.datastore = datastore;
|
|
664
|
+
}
|
|
665
|
+
setModelType(modelType) {
|
|
666
|
+
this.modelType = modelType;
|
|
667
|
+
}
|
|
668
|
+
get(id, customInclude = '') {
|
|
669
|
+
const response = this.datastore.findRecord(this.modelType, id, { customInclude });
|
|
670
|
+
return response;
|
|
671
|
+
}
|
|
672
|
+
getAll(page, pageSize, sort = '', filters = '', customInclude = '') {
|
|
673
|
+
const response = this.datastore.findAll(this.modelType, {
|
|
674
|
+
Page: page,
|
|
675
|
+
PageSize: pageSize,
|
|
676
|
+
Sorts: sort,
|
|
677
|
+
Filters: filters,
|
|
678
|
+
customInclude
|
|
679
|
+
});
|
|
680
|
+
return response;
|
|
681
|
+
}
|
|
682
|
+
delete(id) {
|
|
683
|
+
const response = this.datastore.deleteRecord(this.modelType, id);
|
|
684
|
+
return response;
|
|
685
|
+
}
|
|
686
|
+
getCustom(params, headers, customUrl, customResponseType) {
|
|
687
|
+
return this.datastore.getCustom(this.modelType, params, headers, customUrl, customResponseType);
|
|
688
|
+
}
|
|
689
|
+
postCustom(body, params, headers, customUrl) {
|
|
690
|
+
return this.datastore.postCustom(this.modelType, body, params, headers, customUrl);
|
|
691
|
+
}
|
|
692
|
+
patchCustom(body, params, headers, customUrl) {
|
|
693
|
+
return this.datastore.patchCustom(this.modelType, body, params, headers, customUrl);
|
|
694
|
+
}
|
|
695
|
+
// checkIfPropertyUnique(property: string, value: any): Observable<boolean> {
|
|
696
|
+
// }
|
|
697
|
+
save(docTypeOrFormGroup, id, origModel) {
|
|
698
|
+
if (id == null) {
|
|
699
|
+
let fromModel;
|
|
700
|
+
if (docTypeOrFormGroup instanceof FormGroup) {
|
|
701
|
+
fromModel = this.fromFormGroup(docTypeOrFormGroup, id);
|
|
702
|
+
}
|
|
703
|
+
else {
|
|
704
|
+
fromModel = docTypeOrFormGroup;
|
|
705
|
+
}
|
|
706
|
+
const data = this.datastore.createRecord(this.modelType, fromModel);
|
|
707
|
+
return data.save();
|
|
708
|
+
}
|
|
709
|
+
else {
|
|
710
|
+
return this.patch(docTypeOrFormGroup, origModel, id);
|
|
711
|
+
}
|
|
712
|
+
}
|
|
713
|
+
patch(docTypeOrFormGroup, origModel, id) {
|
|
714
|
+
let fromModel;
|
|
715
|
+
if (docTypeOrFormGroup instanceof FormGroup) {
|
|
716
|
+
fromModel = this.fromFormGroup(docTypeOrFormGroup, id);
|
|
717
|
+
}
|
|
718
|
+
else {
|
|
719
|
+
fromModel = docTypeOrFormGroup;
|
|
720
|
+
}
|
|
721
|
+
const data = this.datastore.createRecord(this.modelType, fromModel);
|
|
722
|
+
return data.patch(origModel);
|
|
723
|
+
}
|
|
724
|
+
newModel(data) {
|
|
725
|
+
return new this.modelType(this.datastore, data);
|
|
726
|
+
}
|
|
727
|
+
toFormGroup(fb, fromModel) {
|
|
728
|
+
if (fromModel === undefined) {
|
|
729
|
+
fromModel = this.newModel();
|
|
730
|
+
}
|
|
731
|
+
return fromModel.getFromGroup(fb);
|
|
732
|
+
}
|
|
733
|
+
fromFormGroup(formGroup, id) {
|
|
734
|
+
// const saveModel = this.newModel(formGroup.getRawValue());
|
|
735
|
+
// saveModel.id = id ? id : null;
|
|
736
|
+
// return saveModel;
|
|
737
|
+
const saveModel = this.newModel();
|
|
738
|
+
saveModel.getModelFromFormGroup(formGroup);
|
|
739
|
+
saveModel.id = id ? id : null;
|
|
740
|
+
return saveModel;
|
|
741
|
+
}
|
|
742
|
+
}
|
|
743
|
+
BaseService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.0", ngImport: i0, type: BaseService, deps: [{ token: BaseDatastore }], target: i0.ɵɵFactoryTarget.Injectable });
|
|
744
|
+
BaseService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "13.3.0", ngImport: i0, type: BaseService, providedIn: 'root' });
|
|
745
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.0", ngImport: i0, type: BaseService, decorators: [{
|
|
746
|
+
type: Injectable,
|
|
747
|
+
args: [{
|
|
748
|
+
providedIn: 'root'
|
|
749
|
+
}]
|
|
750
|
+
}], ctorParameters: function () { return [{ type: BaseDatastore }]; } });
|
|
751
|
+
|
|
752
|
+
/**
|
|
753
|
+
* Async modal dialog service
|
|
754
|
+
* DialogService makes this app easier to test by faking this service.
|
|
755
|
+
* TODO: better modal implementation that doesn't use window.confirm
|
|
756
|
+
*/
|
|
757
|
+
class DialogService {
|
|
758
|
+
/**
|
|
759
|
+
* Ask user to confirm an action. `message` explains the action and choices.
|
|
760
|
+
* Returns observable resolving to `true`=confirm or `false`=cancel
|
|
761
|
+
*/
|
|
762
|
+
constructor() { }
|
|
763
|
+
confirm(message, text, confirmButtonText = 'Delete', cancelButtonText = 'Cancel') {
|
|
764
|
+
const confirmation = Swal.fire({
|
|
765
|
+
title: message || 'Are you sure?',
|
|
766
|
+
icon: 'warning',
|
|
767
|
+
text: text || '',
|
|
768
|
+
showCancelButton: true,
|
|
769
|
+
confirmButtonText: confirmButtonText,
|
|
770
|
+
cancelButtonText: cancelButtonText,
|
|
771
|
+
customClass: {
|
|
772
|
+
confirmButton: 'btn btn-red btn-fill btn-wd',
|
|
773
|
+
cancelButton: 'btn btn-grey btn-fill btn-wd',
|
|
774
|
+
},
|
|
775
|
+
buttonsStyling: false,
|
|
776
|
+
reverseButtons: true
|
|
777
|
+
})
|
|
778
|
+
.then((result) => {
|
|
779
|
+
if (result.value) {
|
|
780
|
+
return true;
|
|
781
|
+
}
|
|
782
|
+
else {
|
|
783
|
+
return false;
|
|
784
|
+
}
|
|
785
|
+
}).catch();
|
|
786
|
+
return from(confirmation);
|
|
787
|
+
}
|
|
788
|
+
showSaveMessage(message, title) {
|
|
789
|
+
const confirmation = Swal.fire({
|
|
790
|
+
icon: 'success',
|
|
791
|
+
title: message,
|
|
792
|
+
timer: 2000,
|
|
793
|
+
showConfirmButton: false,
|
|
794
|
+
// customClass: 'overflow-hidden',
|
|
795
|
+
buttonsStyling: false
|
|
796
|
+
}).then(() => {
|
|
797
|
+
return true;
|
|
798
|
+
}, () => {
|
|
799
|
+
return false;
|
|
800
|
+
}).catch();
|
|
801
|
+
return from(confirmation);
|
|
802
|
+
}
|
|
803
|
+
showRegisteredMessage(message, title) {
|
|
804
|
+
const confirmation = Swal.fire({
|
|
805
|
+
icon: 'success',
|
|
806
|
+
title: message,
|
|
807
|
+
showConfirmButton: true,
|
|
808
|
+
customClass: {
|
|
809
|
+
confirmButton: 'btn btn-success',
|
|
810
|
+
},
|
|
811
|
+
buttonsStyling: false
|
|
812
|
+
}).then(() => {
|
|
813
|
+
return true;
|
|
814
|
+
}, () => {
|
|
815
|
+
return false;
|
|
816
|
+
}).catch();
|
|
817
|
+
return from(confirmation);
|
|
818
|
+
}
|
|
819
|
+
// notification(message?: string, type?: NotificationType, fromPosition?: NotificationFrom, align?: NotificationAlign, timer?: number) {
|
|
820
|
+
// if (!type) {
|
|
821
|
+
// type = NotificationType.success;
|
|
822
|
+
// }
|
|
823
|
+
// if (!fromPosition) {
|
|
824
|
+
// fromPosition = NotificationFrom.bottom;
|
|
825
|
+
// }
|
|
826
|
+
// if (!align) {
|
|
827
|
+
// align = NotificationAlign.center;
|
|
828
|
+
// }
|
|
829
|
+
// if (!timer) {
|
|
830
|
+
// timer = 3000;
|
|
831
|
+
// }
|
|
832
|
+
// $.notify({
|
|
833
|
+
// icon: 'notifications',
|
|
834
|
+
// message: message
|
|
835
|
+
// }, {
|
|
836
|
+
// type: type,
|
|
837
|
+
// timer: 3000,
|
|
838
|
+
// placement: {
|
|
839
|
+
// from: from,
|
|
840
|
+
// align: align
|
|
841
|
+
// }
|
|
842
|
+
// });
|
|
843
|
+
// }
|
|
844
|
+
showErrorMessage(e, message) {
|
|
845
|
+
if (!message) {
|
|
846
|
+
message = 'Validation errors';
|
|
847
|
+
}
|
|
848
|
+
if (e instanceof HttpErrorResponse) {
|
|
849
|
+
// Validation errors
|
|
850
|
+
if (e.status === 400) {
|
|
851
|
+
const errors = e.error.errors;
|
|
852
|
+
if (errors) {
|
|
853
|
+
errors.forEach(error => {
|
|
854
|
+
message += error.field + ' ' + error.detail + '\n';
|
|
855
|
+
});
|
|
856
|
+
// message = errors.detail;
|
|
857
|
+
// if (detail.relationships) {
|
|
858
|
+
// detail.relationships.forEach(relation => {
|
|
859
|
+
// console.log(relation);
|
|
860
|
+
// });
|
|
861
|
+
// }
|
|
862
|
+
}
|
|
863
|
+
}
|
|
864
|
+
}
|
|
865
|
+
const confirmation = Swal.fire({
|
|
866
|
+
icon: 'error',
|
|
867
|
+
title: message,
|
|
868
|
+
// timer: 2000,
|
|
869
|
+
showConfirmButton: true,
|
|
870
|
+
customClass: {
|
|
871
|
+
confirmButton: 'btn btn-success',
|
|
872
|
+
},
|
|
873
|
+
buttonsStyling: false
|
|
874
|
+
}).then(() => {
|
|
875
|
+
return true;
|
|
876
|
+
}, () => {
|
|
877
|
+
return false;
|
|
878
|
+
}).catch();
|
|
879
|
+
return from(confirmation);
|
|
880
|
+
}
|
|
881
|
+
getTextTranslation(translationKey) {
|
|
882
|
+
// // const result = await promise;
|
|
883
|
+
// // return result;
|
|
884
|
+
// const result = this.translate.instant(translationKey);
|
|
885
|
+
// if (result === translationKey) {
|
|
886
|
+
return translationKey;
|
|
887
|
+
// }
|
|
888
|
+
// return result;
|
|
889
|
+
}
|
|
890
|
+
}
|
|
891
|
+
DialogService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.0", ngImport: i0, type: DialogService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
892
|
+
DialogService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "13.3.0", ngImport: i0, type: DialogService });
|
|
893
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.0", ngImport: i0, type: DialogService, decorators: [{
|
|
894
|
+
type: Injectable
|
|
895
|
+
}], ctorParameters: function () { return []; } });
|
|
896
|
+
|
|
897
|
+
class BaseFormEditComponent {
|
|
898
|
+
constructor(fb, router, route, modelService, dialogService, translate, location) {
|
|
899
|
+
this.fb = fb;
|
|
900
|
+
this.router = router;
|
|
901
|
+
this.route = route;
|
|
902
|
+
this.modelService = modelService;
|
|
903
|
+
this.dialogService = dialogService;
|
|
904
|
+
this.translate = translate;
|
|
905
|
+
this.location = location;
|
|
906
|
+
this.isLoading = true;
|
|
907
|
+
this.changeUrlRoute = true;
|
|
908
|
+
this.generateForm(this.modelService.newModel());
|
|
909
|
+
}
|
|
910
|
+
afterSave(model) {
|
|
911
|
+
return new Observable((observer) => {
|
|
912
|
+
observer.next(model);
|
|
913
|
+
observer.complete();
|
|
914
|
+
});
|
|
915
|
+
}
|
|
916
|
+
beforeSave(model) {
|
|
917
|
+
return new Observable((observer) => {
|
|
918
|
+
observer.next(model);
|
|
919
|
+
observer.complete();
|
|
920
|
+
});
|
|
921
|
+
}
|
|
922
|
+
ngOnInit() {
|
|
923
|
+
this.initForm();
|
|
924
|
+
}
|
|
925
|
+
initForm(customInclude = '', newModelId = null, model = null) {
|
|
926
|
+
if (model === null) {
|
|
927
|
+
this.modelId = this.route.snapshot.paramMap.get('id') ?? newModelId;
|
|
928
|
+
this.isEdit = false;
|
|
929
|
+
if (this.modelId) {
|
|
930
|
+
this.modelService.get(this.modelId, customInclude).subscribe((value) => {
|
|
931
|
+
this.isEdit = true;
|
|
932
|
+
this.generateForm(value);
|
|
933
|
+
});
|
|
934
|
+
}
|
|
935
|
+
else {
|
|
936
|
+
if (this.changeUrlRoute) {
|
|
937
|
+
const addUrl = this.router.createUrlTree([]).toString();
|
|
938
|
+
this.editRoute = this.router.createUrlTree([addUrl.replace('add', 'edit')]).toString();
|
|
939
|
+
}
|
|
940
|
+
// }
|
|
941
|
+
this.generateForm(this.modelService.newModel());
|
|
942
|
+
}
|
|
943
|
+
}
|
|
944
|
+
else {
|
|
945
|
+
this.modelId = model.id;
|
|
946
|
+
this.isEdit = true;
|
|
947
|
+
this.generateForm(model);
|
|
948
|
+
}
|
|
949
|
+
}
|
|
950
|
+
generateForm(model) {
|
|
951
|
+
this.isLoading = false;
|
|
952
|
+
this.modelId = model.id;
|
|
953
|
+
this.model = model;
|
|
954
|
+
this.baseForm = this.modelService.toFormGroup(this.fb, model);
|
|
955
|
+
this.afterFormGenerated();
|
|
956
|
+
}
|
|
957
|
+
afterFormGenerated() {
|
|
958
|
+
}
|
|
959
|
+
getFromGroup(formGroup = null) {
|
|
960
|
+
if (!formGroup)
|
|
961
|
+
return this.baseForm;
|
|
962
|
+
if (formGroup instanceof FormGroup)
|
|
963
|
+
return formGroup;
|
|
964
|
+
return this.baseForm.controls[formGroup];
|
|
965
|
+
}
|
|
966
|
+
validateAllFormFields(formGroup = null) {
|
|
967
|
+
const fg = this.getFromGroup(formGroup);
|
|
968
|
+
Object.keys(fg.controls).forEach(field => {
|
|
969
|
+
// console.log(field);
|
|
970
|
+
const control = fg.get(field);
|
|
971
|
+
if (control instanceof FormControl) {
|
|
972
|
+
control.markAsTouched({ onlySelf: true });
|
|
973
|
+
}
|
|
974
|
+
else if (control instanceof FormGroup) {
|
|
975
|
+
this.validateAllFormFields(control);
|
|
976
|
+
}
|
|
977
|
+
});
|
|
978
|
+
}
|
|
979
|
+
isFieldValid(field, formGroup = null) {
|
|
980
|
+
const fg = this.getFromGroup(formGroup);
|
|
981
|
+
const filedControl = fg.get(field);
|
|
982
|
+
return !filedControl.valid && filedControl.touched;
|
|
983
|
+
}
|
|
984
|
+
isFieldValidFromArray(arrayIndex, field, arrayName = 'formArray') {
|
|
985
|
+
const fieldControl = this.baseForm.get(arrayName).get([arrayIndex]).get(field);
|
|
986
|
+
return !fieldControl.valid && fieldControl.touched;
|
|
987
|
+
}
|
|
988
|
+
displayFieldCss(field) {
|
|
989
|
+
return {
|
|
990
|
+
'has-error': this.isFieldValid(field),
|
|
991
|
+
'has-feedback': this.isFieldValid(field)
|
|
992
|
+
};
|
|
993
|
+
}
|
|
994
|
+
onCancel() {
|
|
995
|
+
this.router.navigate([this.cancelRoute]);
|
|
996
|
+
}
|
|
997
|
+
onSave() {
|
|
998
|
+
this.saveModel(this.baseForm);
|
|
999
|
+
}
|
|
1000
|
+
saveModel(formGroup = null) {
|
|
1001
|
+
const fg = this.getFromGroup(formGroup);
|
|
1002
|
+
const that = this;
|
|
1003
|
+
if (fg) {
|
|
1004
|
+
if (fg.valid) {
|
|
1005
|
+
that.blockUI.start('Saving ...');
|
|
1006
|
+
this.beforeSave(this.model).subscribe(_ => {
|
|
1007
|
+
this.modelService.save(this.baseForm, this.modelId, this.model).subscribe((newModel) => {
|
|
1008
|
+
this.model = newModel;
|
|
1009
|
+
this.modelId = newModel.id;
|
|
1010
|
+
if (this.editRoute) {
|
|
1011
|
+
this.isEdit = true;
|
|
1012
|
+
if (this.changeUrlRoute) {
|
|
1013
|
+
const url = this.router.createUrlTree([this.editRoute, this.modelId]).toString();
|
|
1014
|
+
this.location.replaceState(url);
|
|
1015
|
+
}
|
|
1016
|
+
}
|
|
1017
|
+
this.afterSave(newModel).subscribe((val) => {
|
|
1018
|
+
this.blockUI.stop();
|
|
1019
|
+
this.dialogService.showSaveMessage('Your changes were saved successfully.').subscribe(d => {
|
|
1020
|
+
fg.markAsPristine();
|
|
1021
|
+
});
|
|
1022
|
+
});
|
|
1023
|
+
}, err => {
|
|
1024
|
+
this.serverErrors(err);
|
|
1025
|
+
this.blockUI.stop();
|
|
1026
|
+
});
|
|
1027
|
+
});
|
|
1028
|
+
}
|
|
1029
|
+
else {
|
|
1030
|
+
this.validateAllFormFields(formGroup);
|
|
1031
|
+
}
|
|
1032
|
+
}
|
|
1033
|
+
}
|
|
1034
|
+
serverErrors(err) {
|
|
1035
|
+
if (err.error) {
|
|
1036
|
+
if (err.error.errors) {
|
|
1037
|
+
const validationErrors = err.error.errors;
|
|
1038
|
+
if (Array.isArray(validationErrors)) {
|
|
1039
|
+
validationErrors.forEach(prop => {
|
|
1040
|
+
const formControl = this.baseForm.get(prop);
|
|
1041
|
+
if (formControl) {
|
|
1042
|
+
// activate the error message
|
|
1043
|
+
formControl.setErrors({
|
|
1044
|
+
serverError: validationErrors[prop].join('\n')
|
|
1045
|
+
});
|
|
1046
|
+
}
|
|
1047
|
+
});
|
|
1048
|
+
}
|
|
1049
|
+
else {
|
|
1050
|
+
const keys = Object.keys(validationErrors);
|
|
1051
|
+
keys.forEach(prop => {
|
|
1052
|
+
const formControl = this.baseForm.get(prop);
|
|
1053
|
+
if (formControl) {
|
|
1054
|
+
// activate the error message
|
|
1055
|
+
formControl.setErrors({
|
|
1056
|
+
serverError: validationErrors[prop].join('\n')
|
|
1057
|
+
});
|
|
1058
|
+
}
|
|
1059
|
+
});
|
|
1060
|
+
}
|
|
1061
|
+
}
|
|
1062
|
+
}
|
|
1063
|
+
}
|
|
1064
|
+
canDeactivate() {
|
|
1065
|
+
// Allow synchronous navigation (`true`) if no crisis or the crisis is unchanged
|
|
1066
|
+
if (!this.baseForm.dirty) {
|
|
1067
|
+
return true;
|
|
1068
|
+
}
|
|
1069
|
+
// Otherwise ask the user with the dialog service and return its
|
|
1070
|
+
// observable which resolves to true or false when the user decides
|
|
1071
|
+
return this.dialogService.confirm('Discard changes ?', null, 'Discard');
|
|
1072
|
+
}
|
|
1073
|
+
getFiledName(filedTranslationKey) {
|
|
1074
|
+
return { field: this.translate.instant(filedTranslationKey) };
|
|
1075
|
+
}
|
|
1076
|
+
getCustomErrorMessage(error, fieldLabel) {
|
|
1077
|
+
return '';
|
|
1078
|
+
}
|
|
1079
|
+
getErrorMessageFromArray(arrayIndex, field, filedTranslationKey, arrayName = 'formArray') {
|
|
1080
|
+
const fieldControl = this.baseForm.get(arrayName).get([arrayIndex]).get(field);
|
|
1081
|
+
return this.getErrorMessageForField(fieldControl, filedTranslationKey);
|
|
1082
|
+
}
|
|
1083
|
+
getErrorMessage(field, filedTranslationKey, formGroup = null) {
|
|
1084
|
+
const fg = this.getFromGroup(formGroup);
|
|
1085
|
+
return this.getErrorMessageForField(fg.get(field), filedTranslationKey);
|
|
1086
|
+
}
|
|
1087
|
+
getErrorMessageForField(fieldControl, filedTranslationKey) {
|
|
1088
|
+
const error = fieldControl.errors;
|
|
1089
|
+
const fieldLabel = this.translate.instant(filedTranslationKey);
|
|
1090
|
+
let rvalue = '';
|
|
1091
|
+
if (error !== null) {
|
|
1092
|
+
if (error['required'] === true) {
|
|
1093
|
+
rvalue = this.translate.instant('General.Field.Required', { field: fieldLabel });
|
|
1094
|
+
}
|
|
1095
|
+
if (error['minlength']) {
|
|
1096
|
+
rvalue = this.translate.instant('General.Field.MinLength', { field: fieldLabel, requiredLength: error.minlength.requiredLength });
|
|
1097
|
+
}
|
|
1098
|
+
if (error['email'] === true) {
|
|
1099
|
+
rvalue = this.translate.instant('General.Field.InvalidEmail');
|
|
1100
|
+
}
|
|
1101
|
+
if (error['url'] === true) {
|
|
1102
|
+
rvalue = this.translate.instant('General.Field.InvalidUrl');
|
|
1103
|
+
}
|
|
1104
|
+
if (error['serverError']) {
|
|
1105
|
+
rvalue = error['serverError'];
|
|
1106
|
+
}
|
|
1107
|
+
if (rvalue === '') {
|
|
1108
|
+
rvalue = this.getCustomErrorMessage(error, fieldLabel);
|
|
1109
|
+
}
|
|
1110
|
+
}
|
|
1111
|
+
return rvalue;
|
|
1112
|
+
}
|
|
1113
|
+
}
|
|
1114
|
+
BaseFormEditComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.0", ngImport: i0, type: BaseFormEditComponent, deps: [{ token: i2.FormBuilder }, { token: i2$1.Router }, { token: i2$1.ActivatedRoute }, { token: BaseService }, { token: DialogService }, { token: i1$1.TranslateService }, { token: i3$1.Location }], target: i0.ɵɵFactoryTarget.Component });
|
|
1115
|
+
BaseFormEditComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.3.0", type: BaseFormEditComponent, selector: "app-base.form.edit", ngImport: i0, template: '', isInline: true });
|
|
1116
|
+
__decorate([
|
|
1117
|
+
BlockUI()
|
|
1118
|
+
], BaseFormEditComponent.prototype, "blockUI", void 0);
|
|
1119
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.0", ngImport: i0, type: BaseFormEditComponent, decorators: [{
|
|
1120
|
+
type: Component,
|
|
1121
|
+
args: [{
|
|
1122
|
+
selector: 'app-base.form.edit',
|
|
1123
|
+
template: ''
|
|
1124
|
+
}]
|
|
1125
|
+
}], ctorParameters: function () { return [{ type: i2.FormBuilder }, { type: i2$1.Router }, { type: i2$1.ActivatedRoute }, { type: BaseService }, { type: DialogService }, { type: i1$1.TranslateService }, { type: i3$1.Location }]; }, propDecorators: { blockUI: [] } });
|
|
1126
|
+
|
|
1127
|
+
var GridLayoutFormat;
|
|
1128
|
+
(function (GridLayoutFormat) {
|
|
1129
|
+
GridLayoutFormat[GridLayoutFormat["none"] = 0] = "none";
|
|
1130
|
+
GridLayoutFormat[GridLayoutFormat["date"] = 1] = "date";
|
|
1131
|
+
GridLayoutFormat[GridLayoutFormat["number"] = 2] = "number";
|
|
1132
|
+
GridLayoutFormat[GridLayoutFormat["percent"] = 3] = "percent";
|
|
1133
|
+
GridLayoutFormat[GridLayoutFormat["picture"] = 4] = "picture";
|
|
1134
|
+
})(GridLayoutFormat || (GridLayoutFormat = {}));
|
|
1135
|
+
var CellTextAlign;
|
|
1136
|
+
(function (CellTextAlign) {
|
|
1137
|
+
CellTextAlign["left"] = "left";
|
|
1138
|
+
CellTextAlign["center"] = "center";
|
|
1139
|
+
CellTextAlign["right"] = "right";
|
|
1140
|
+
})(CellTextAlign || (CellTextAlign = {}));
|
|
1141
|
+
|
|
1142
|
+
class GenericTableComponent {
|
|
1143
|
+
// ruleEngineService: RuleEngineService<T>;
|
|
1144
|
+
constructor(dialogService, router, datePipe, numberPipe, percentPipe, renderer) {
|
|
1145
|
+
this.dialogService = dialogService;
|
|
1146
|
+
this.router = router;
|
|
1147
|
+
this.datePipe = datePipe;
|
|
1148
|
+
this.numberPipe = numberPipe;
|
|
1149
|
+
this.percentPipe = percentPipe;
|
|
1150
|
+
this.renderer = renderer;
|
|
1151
|
+
this.defaultSort = null;
|
|
1152
|
+
this.defaultSortDirection = null;
|
|
1153
|
+
this.deletePropertyName = 'name';
|
|
1154
|
+
this.stickyColumns = null;
|
|
1155
|
+
this.editOnClick = false;
|
|
1156
|
+
this.editOnDblClick = false;
|
|
1157
|
+
this.allowEdit = true;
|
|
1158
|
+
this.popupEdit = false;
|
|
1159
|
+
this.customInclude = null;
|
|
1160
|
+
this.infiniteScroll = false;
|
|
1161
|
+
this.dataSource = new MatTableDataSource();
|
|
1162
|
+
this.resultsLength = 0;
|
|
1163
|
+
this.isLoadingResults = true;
|
|
1164
|
+
this.isRateLimitReached = false;
|
|
1165
|
+
this.filterChanged = new Subject();
|
|
1166
|
+
this.selectedObject = new EventEmitter();
|
|
1167
|
+
this.click = new EventEmitter();
|
|
1168
|
+
this.editModel = new EventEmitter();
|
|
1169
|
+
}
|
|
1170
|
+
ngOnChanges() {
|
|
1171
|
+
if (this.baseService !== undefined || this.baseService !== null) {
|
|
1172
|
+
if (this.gridLayoutService != null) {
|
|
1173
|
+
this.gridLayout = this.gridLayoutService.getGridLayout();
|
|
1174
|
+
}
|
|
1175
|
+
else {
|
|
1176
|
+
const model = this.baseService.newModel();
|
|
1177
|
+
this.gridLayout = model.getGridLayout();
|
|
1178
|
+
}
|
|
1179
|
+
this.displayedColumns = [];
|
|
1180
|
+
if (this.allowReorderItems) {
|
|
1181
|
+
this.displayedColumns.push('position');
|
|
1182
|
+
}
|
|
1183
|
+
this.displayedColumns.push.apply(this.displayedColumns, this.gridLayout.map(x => x.propertyName));
|
|
1184
|
+
if (!this.editOnClick && !this.editOnDblClick && this.allowEdit) {
|
|
1185
|
+
this.displayedColumns.push('delete');
|
|
1186
|
+
}
|
|
1187
|
+
}
|
|
1188
|
+
}
|
|
1189
|
+
ngOnInit() {
|
|
1190
|
+
this.filterChangedSubscription = this.filterChanged
|
|
1191
|
+
.pipe(debounceTime(300), distinctUntilChanged())
|
|
1192
|
+
.subscribe(newText => {
|
|
1193
|
+
if (newText.length >= 3 || newText.length == 0) {
|
|
1194
|
+
this.filterValue = newText;
|
|
1195
|
+
this.paginator.pageIndex = 0;
|
|
1196
|
+
this.refreshForm();
|
|
1197
|
+
}
|
|
1198
|
+
});
|
|
1199
|
+
// this.getGridLayout();
|
|
1200
|
+
this.sort.sortChange.subscribe(() => this.paginator.pageIndex = 0);
|
|
1201
|
+
this.paginator.pageSize = 15;
|
|
1202
|
+
if (this.defaultSort) {
|
|
1203
|
+
this.sort.active = this.defaultSort;
|
|
1204
|
+
if (this.defaultSortDirection) {
|
|
1205
|
+
this.sort.direction = this.defaultSortDirection;
|
|
1206
|
+
}
|
|
1207
|
+
else {
|
|
1208
|
+
this.sort.direction = 'asc';
|
|
1209
|
+
}
|
|
1210
|
+
}
|
|
1211
|
+
// this.dataSource.paginator = this.paginator;
|
|
1212
|
+
merge(this.sort.sortChange, this.paginator.page)
|
|
1213
|
+
.pipe(startWith({}), switchMap(() => {
|
|
1214
|
+
this.isLoadingResults = true;
|
|
1215
|
+
return this.getData();
|
|
1216
|
+
}), map(data => {
|
|
1217
|
+
// Flip flag to show that loading has finished.
|
|
1218
|
+
this.isLoadingResults = false;
|
|
1219
|
+
this.isRateLimitReached = false;
|
|
1220
|
+
if (data) {
|
|
1221
|
+
this.resultsLength = data.getMeta().meta.count;
|
|
1222
|
+
return data.getModels();
|
|
1223
|
+
}
|
|
1224
|
+
else {
|
|
1225
|
+
this.resultsLength = 0;
|
|
1226
|
+
return [];
|
|
1227
|
+
}
|
|
1228
|
+
}), catchError(() => {
|
|
1229
|
+
this.isLoadingResults = false;
|
|
1230
|
+
// Catch if the GitHub API has reached its rate limit. Return empty data.
|
|
1231
|
+
this.isRateLimitReached = true;
|
|
1232
|
+
return of([]);
|
|
1233
|
+
})).subscribe(data => {
|
|
1234
|
+
// if (this.infiniteScroll) {
|
|
1235
|
+
// let oldData = this.dataSource.data ?? null;
|
|
1236
|
+
// // if (oldData.length === 0) {
|
|
1237
|
+
// // oldData = data;
|
|
1238
|
+
// // } else {
|
|
1239
|
+
// oldData=oldData.concat(data);
|
|
1240
|
+
// // }
|
|
1241
|
+
// this.dataSource.data = oldData;
|
|
1242
|
+
// }
|
|
1243
|
+
// else {
|
|
1244
|
+
this.dataSource.data = data;
|
|
1245
|
+
// }
|
|
1246
|
+
});
|
|
1247
|
+
// this.paginator.nextPage()
|
|
1248
|
+
}
|
|
1249
|
+
getData() {
|
|
1250
|
+
this.isLoadingResults = true;
|
|
1251
|
+
const pageIndex = (this.paginator.pageIndex || 0) + 1;
|
|
1252
|
+
const pageSize = this.paginator.pageSize || 20;
|
|
1253
|
+
const filters = [];
|
|
1254
|
+
let sorts = '';
|
|
1255
|
+
if (this.sort.active) {
|
|
1256
|
+
if (this.sort.direction === 'desc') {
|
|
1257
|
+
sorts = '-' + this.sort.active;
|
|
1258
|
+
}
|
|
1259
|
+
else {
|
|
1260
|
+
sorts = this.sort.active;
|
|
1261
|
+
}
|
|
1262
|
+
}
|
|
1263
|
+
if (this.hasSearch) {
|
|
1264
|
+
if (this.filterValue) {
|
|
1265
|
+
// const filtersArr = this.searchFields.split(",");
|
|
1266
|
+
// filtersArr.forEach(element => {
|
|
1267
|
+
// filters.push(element + '@=*' + this.filterValue);
|
|
1268
|
+
// });
|
|
1269
|
+
const y = '(' + this.searchFields.replace(',', '|') + ')';
|
|
1270
|
+
filters.push(y + '@=*' + this.filterValue);
|
|
1271
|
+
}
|
|
1272
|
+
}
|
|
1273
|
+
if (this.defaultFilter) {
|
|
1274
|
+
filters.push(this.defaultFilter);
|
|
1275
|
+
}
|
|
1276
|
+
const filtersValue = filters.join(', ');
|
|
1277
|
+
return this.baseService.getAll(pageIndex, pageSize, sorts, filtersValue, this.customInclude);
|
|
1278
|
+
}
|
|
1279
|
+
refreshForm() {
|
|
1280
|
+
this.getData().subscribe(data => {
|
|
1281
|
+
if (data) {
|
|
1282
|
+
this.isLoadingResults = false;
|
|
1283
|
+
this.isRateLimitReached = false;
|
|
1284
|
+
this.resultsLength = data.getMeta().meta.count;
|
|
1285
|
+
this.dataSource.data = data.getModels();
|
|
1286
|
+
}
|
|
1287
|
+
else {
|
|
1288
|
+
this.isLoadingResults = false;
|
|
1289
|
+
this.isRateLimitReached = false;
|
|
1290
|
+
this.resultsLength = 0;
|
|
1291
|
+
this.dataSource.data = [];
|
|
1292
|
+
}
|
|
1293
|
+
});
|
|
1294
|
+
}
|
|
1295
|
+
highlight(element) {
|
|
1296
|
+
if (this.selectedItem) {
|
|
1297
|
+
this.selectedItem.highlighted = element.highlighted;
|
|
1298
|
+
}
|
|
1299
|
+
this.selectedItem = null;
|
|
1300
|
+
element.highlighted = !element.highlighted;
|
|
1301
|
+
if (element.highlighted) {
|
|
1302
|
+
this.selectedItem = element;
|
|
1303
|
+
this.selectedObject.emit(element);
|
|
1304
|
+
}
|
|
1305
|
+
else {
|
|
1306
|
+
this.selectedObject.emit(null);
|
|
1307
|
+
}
|
|
1308
|
+
}
|
|
1309
|
+
deleteObject(model) {
|
|
1310
|
+
const msg = 'Do you want to delete ' + model[this.deletePropertyName] + '?';
|
|
1311
|
+
this.dialogService.confirm(msg).subscribe((response) => {
|
|
1312
|
+
if (response) {
|
|
1313
|
+
this.baseService.delete(model.id).subscribe(() => {
|
|
1314
|
+
const tempData = [];
|
|
1315
|
+
this.selectedObject.emit(null);
|
|
1316
|
+
this.dataSource.data.map((item) => {
|
|
1317
|
+
if (item.id !== model.id) {
|
|
1318
|
+
tempData.push(item);
|
|
1319
|
+
}
|
|
1320
|
+
});
|
|
1321
|
+
this.dataSource.data = tempData;
|
|
1322
|
+
});
|
|
1323
|
+
}
|
|
1324
|
+
});
|
|
1325
|
+
}
|
|
1326
|
+
editObject(model) {
|
|
1327
|
+
if (!this.popupEdit) {
|
|
1328
|
+
const id = model.id;
|
|
1329
|
+
this.router.navigate([this.editLink, id]);
|
|
1330
|
+
}
|
|
1331
|
+
else {
|
|
1332
|
+
this.editModel.emit(model);
|
|
1333
|
+
}
|
|
1334
|
+
}
|
|
1335
|
+
getFlexStyle(column) {
|
|
1336
|
+
if (column.width) {
|
|
1337
|
+
const style = column.grow + ' ' + column.shrink + ' ' + column.width + 'px';
|
|
1338
|
+
return style;
|
|
1339
|
+
}
|
|
1340
|
+
return null;
|
|
1341
|
+
}
|
|
1342
|
+
getCellTextAlign(column) {
|
|
1343
|
+
return column.textAlign ?? CellTextAlign.left;
|
|
1344
|
+
}
|
|
1345
|
+
showPictureCell(column) {
|
|
1346
|
+
return (column?.formating ?? GridLayoutFormat.none) === GridLayoutFormat.picture;
|
|
1347
|
+
}
|
|
1348
|
+
deleteDisabled(model) {
|
|
1349
|
+
if (this.deleteDisableRule) {
|
|
1350
|
+
return this.evaluateRule(this.deleteDisableRule, model);
|
|
1351
|
+
}
|
|
1352
|
+
else {
|
|
1353
|
+
return false;
|
|
1354
|
+
}
|
|
1355
|
+
}
|
|
1356
|
+
cellClick(model, propertyName) {
|
|
1357
|
+
this.click.emit({ propertyName, model });
|
|
1358
|
+
}
|
|
1359
|
+
evaluateRule(rules, model) {
|
|
1360
|
+
let result = true;
|
|
1361
|
+
rules.forEach(rule => {
|
|
1362
|
+
let jsonRule;
|
|
1363
|
+
if (typeof rule.rule === 'string') {
|
|
1364
|
+
jsonRule = JSON.parse(rule.rule);
|
|
1365
|
+
}
|
|
1366
|
+
else {
|
|
1367
|
+
jsonRule = rule.rule;
|
|
1368
|
+
}
|
|
1369
|
+
if (rule.parameters) {
|
|
1370
|
+
const data = '{' + rule.parameters.map((item) => {
|
|
1371
|
+
return '"' + item + '":"' + model[item] + '"';
|
|
1372
|
+
}).join(',') + '}';
|
|
1373
|
+
result = jsonLogic.apply(jsonRule, JSON.parse(data));
|
|
1374
|
+
}
|
|
1375
|
+
else {
|
|
1376
|
+
result = jsonLogic.apply(jsonRule);
|
|
1377
|
+
}
|
|
1378
|
+
});
|
|
1379
|
+
return result;
|
|
1380
|
+
}
|
|
1381
|
+
getCelValue(row, propertyName) {
|
|
1382
|
+
if (!row)
|
|
1383
|
+
return "";
|
|
1384
|
+
// if (propertyName == 'kompetenzenStdev')
|
|
1385
|
+
// console.log(propertyName);
|
|
1386
|
+
if (propertyName.indexOf('.') === -1) {
|
|
1387
|
+
var gridLayout = this.gridLayout.find(f => f.propertyName.indexOf(propertyName) > -1);
|
|
1388
|
+
return this.getFormatedValue(gridLayout, row[propertyName]);
|
|
1389
|
+
}
|
|
1390
|
+
else {
|
|
1391
|
+
const prop = propertyName.split('.')[0];
|
|
1392
|
+
const subProp = propertyName.replace(prop + '.', '');
|
|
1393
|
+
return this.getCelValue(row[prop], subProp);
|
|
1394
|
+
}
|
|
1395
|
+
}
|
|
1396
|
+
getFormatedValue(gridLayout, value) {
|
|
1397
|
+
if (gridLayout) {
|
|
1398
|
+
switch (gridLayout.formating) {
|
|
1399
|
+
case GridLayoutFormat.date:
|
|
1400
|
+
return this.datePipe.transform(value, gridLayout.format);
|
|
1401
|
+
break;
|
|
1402
|
+
case GridLayoutFormat.number:
|
|
1403
|
+
return this.numberPipe.transform(value, gridLayout.format);
|
|
1404
|
+
case GridLayoutFormat.percent:
|
|
1405
|
+
const valuePrc = value / 100;
|
|
1406
|
+
return this.percentPipe.transform(valuePrc, gridLayout.format);
|
|
1407
|
+
default:
|
|
1408
|
+
return value;
|
|
1409
|
+
break;
|
|
1410
|
+
}
|
|
1411
|
+
}
|
|
1412
|
+
return value;
|
|
1413
|
+
}
|
|
1414
|
+
applyFilter(event) {
|
|
1415
|
+
}
|
|
1416
|
+
dropTable(event) {
|
|
1417
|
+
if (this.changeItemPosition) {
|
|
1418
|
+
const prevItem = this.dataSource.data[event.previousIndex];
|
|
1419
|
+
const currentItem = this.dataSource.data[event.currentIndex];
|
|
1420
|
+
if (this.changeItemPosition(prevItem, currentItem)) {
|
|
1421
|
+
const prevIndex = this.dataSource.data.findIndex((d) => d === event.item.data);
|
|
1422
|
+
moveItemInArray(this.dataSource.data, prevIndex, event.currentIndex);
|
|
1423
|
+
this.table.renderRows();
|
|
1424
|
+
}
|
|
1425
|
+
}
|
|
1426
|
+
}
|
|
1427
|
+
isColumnSticky(name) {
|
|
1428
|
+
if (this.stickyColumns) {
|
|
1429
|
+
const filtersArr = this.stickyColumns.split(",");
|
|
1430
|
+
return filtersArr.findIndex(f => f == name) !== -1;
|
|
1431
|
+
}
|
|
1432
|
+
return false;
|
|
1433
|
+
}
|
|
1434
|
+
updateElement(model) {
|
|
1435
|
+
//Find if element exist
|
|
1436
|
+
var currentElement = this.dataSource.data.find(f => f.id === model.id);
|
|
1437
|
+
if (currentElement !== null) {
|
|
1438
|
+
const index = this.dataSource.data.indexOf(currentElement);
|
|
1439
|
+
this.dataSource.data[index] = model;
|
|
1440
|
+
}
|
|
1441
|
+
else {
|
|
1442
|
+
this.dataSource.data.push(model);
|
|
1443
|
+
}
|
|
1444
|
+
const newData = [...this.dataSource.data];
|
|
1445
|
+
this.dataSource.data = newData;
|
|
1446
|
+
this.dataSource._updateChangeSubscription();
|
|
1447
|
+
}
|
|
1448
|
+
ngAfterViewInit() {
|
|
1449
|
+
fromEvent(this.matTableRef.nativeElement, 'scroll')
|
|
1450
|
+
.pipe(debounceTime(700))
|
|
1451
|
+
.subscribe((e) => this.onTableScroll(e));
|
|
1452
|
+
}
|
|
1453
|
+
onTableScroll(e) {
|
|
1454
|
+
const tableViewHeight = e.target.offsetHeight; // viewport: ~500px
|
|
1455
|
+
const tableScrollHeight = e.target.scrollHeight; // length of all table
|
|
1456
|
+
const scrollLocation = e.target.scrollTop; // how far user scrolled
|
|
1457
|
+
// If the user has scrolled within 200px of the bottom, add more data
|
|
1458
|
+
const scrollThreshold = 200;
|
|
1459
|
+
const scrollUpLimit = scrollThreshold;
|
|
1460
|
+
if (scrollLocation < scrollUpLimit && this.paginator.pageIndex > 0) {
|
|
1461
|
+
// this.firstPage--;
|
|
1462
|
+
console.log(`onTableScroll() UP: firstPage decreased to ${this.paginator.pageIndex}. Now fetching data...`);
|
|
1463
|
+
// this.fetchData();
|
|
1464
|
+
this.scrollTo(tableScrollHeight / 2 - 2 * tableViewHeight);
|
|
1465
|
+
}
|
|
1466
|
+
const scrollDownLimit = tableScrollHeight - tableViewHeight - scrollThreshold;
|
|
1467
|
+
if (scrollLocation > scrollDownLimit && this.paginator.pageIndex < this.paginator.getNumberOfPages()) {
|
|
1468
|
+
// this.firstPage++;
|
|
1469
|
+
console.log(`onTableScroll(): firstPage increased to ${this.paginator.pageIndex}. Now fetching data...`);
|
|
1470
|
+
this.paginator.nextPage();
|
|
1471
|
+
// this.scrollTo(tableScrollHeight / 2 + tableViewHeight);
|
|
1472
|
+
}
|
|
1473
|
+
}
|
|
1474
|
+
scrollTo(position) {
|
|
1475
|
+
this.renderer.setProperty(this.matTableRef.nativeElement, 'scrollTop', position);
|
|
1476
|
+
}
|
|
1477
|
+
getCellClass(model, property) {
|
|
1478
|
+
return model.getCellClass(property);
|
|
1479
|
+
}
|
|
1480
|
+
}
|
|
1481
|
+
GenericTableComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.0", ngImport: i0, type: GenericTableComponent, deps: [{ token: DialogService }, { token: i2$1.Router }, { token: i3$1.DatePipe }, { token: i3$1.DecimalPipe }, { token: i3$1.PercentPipe }, { token: i0.Renderer2 }], target: i0.ɵɵFactoryTarget.Component });
|
|
1482
|
+
GenericTableComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.3.0", type: GenericTableComponent, selector: "rsl-generic-table", inputs: { modelType: "modelType", baseService: "baseService", gridLayoutService: "gridLayoutService", editLink: "editLink", defaultSort: "defaultSort", defaultSortDirection: "defaultSortDirection", deleteDisableRule: "deleteDisableRule", deletePropertyName: "deletePropertyName", hasSearch: "hasSearch", searchFields: "searchFields", defaultFilter: "defaultFilter", allowReorderItems: "allowReorderItems", stickyColumns: "stickyColumns", editOnClick: "editOnClick", editOnDblClick: "editOnDblClick", allowEdit: "allowEdit", popupEdit: "popupEdit", customInclude: "customInclude", changeItemPosition: "changeItemPosition", infiniteScroll: "infiniteScroll" }, outputs: { selectedObject: "selectedObject", click: "click", editModel: "editModel" }, viewQueries: [{ propertyName: "paginator", first: true, predicate: MatPaginator, descendants: true, static: true }, { propertyName: "sort", first: true, predicate: MatSort, descendants: true, static: true }, { propertyName: "filter", first: true, predicate: ElementRef, descendants: true }, { propertyName: "table", first: true, predicate: ["table"], descendants: true }, { propertyName: "matTableRef", first: true, predicate: ["table"], descendants: true, read: ElementRef }], usesOnChanges: true, ngImport: i0, template: "<div class=\"containerX\" *ngIf=\"hasSearch\">\r\n <div fxLayout=\"row\" fxLayout.xs=\"column\" fxLayout.sm=\"column\" fxFlexFill>\r\n <mat-form-field fxFlex>\r\n <mat-label>Filter</mat-label>\r\n <input matInput [ngModel]='filterValue' (ngModelChange)='filterChanged.next($event)' #filter>\r\n </mat-form-field>\r\n </div>\r\n</div>\r\n\r\n<div class=\"table-container\">\r\n <div class=\"mat-elevation-z2\">\r\n <!-- #applicationsContainer -->\r\n <div class=\"example-loading-shade\" *ngIf=\"isLoadingResults || isRateLimitReached\">\r\n <mat-spinner *ngIf=\"isLoadingResults\"></mat-spinner>\r\n <div class=\"example-rate-limit-reached\" *ngIf=\"isRateLimitReached\">\r\n {{'General.LoadingData' | translate}}\r\n </div>\r\n </div>\r\n\r\n\r\n <mat-table fxFlex #table [dataSource]=\"dataSource\" id=\"tempalte-forms-table\" matSort matSortDisableClear\r\n matSortDirection=\"asc\" cdkDropList [cdkDropListData]=\"dataSource\" (cdkDropListDropped)=\"dropTable($event)\">\r\n <!-- (scroll)=\"onTableScroll($event)\" -->\r\n\r\n\r\n <ng-container matColumnDef=\"position\">\r\n <mat-header-cell *matHeaderCellDef disableClear=\"true\">\r\n <!-- {{'General.Order' | translate}} -->\r\n </mat-header-cell>\r\n <mat-cell fxFlex *matCellDef=\"let element;\">\r\n <mat-icon cdkDragHandle>reorder</mat-icon>\r\n </mat-cell>\r\n </ng-container>\r\n\r\n\r\n <ng-container *ngFor=\"let column of gridLayout\" [matColumnDef]=\"column.propertyName\"\r\n [sticky]=\"isColumnSticky(column.propertyName)\">\r\n <mat-header-cell mat-sort-header disableClear [style.flex]=\"getFlexStyle(column)\" *matHeaderCellDef>\r\n {{column.translateKey | translate}}\r\n </mat-header-cell>\r\n <mat-cell matTooltip={{getCelValue(row,column.propertyName)}} [style.flex]=\"getFlexStyle(column)\"\r\n [style.text-align]=\"getCellTextAlign(column)\" *matCellDef=\"let row\" (click)=\"cellClick(row,column.propertyName)\">\r\n <div [ngClass]=\"getCellClass(row,column.propertyName)\" *ngIf=\"!showPictureCell(column)\">\r\n {{getCelValue(row,column.propertyName)}}\r\n </div>\r\n <img [ngClass]=\"getCellClass(row,column.propertyName)\" *ngIf=\"showPictureCell(column)\">\r\n </mat-cell>\r\n </ng-container>\r\n\r\n\r\n <ng-container matColumnDef=\"delete\" stickyEnd *ngIf=\"!editOnClick && !editOnDblClick\">\r\n <mat-header-cell *matHeaderCellDef disableClear=\"true\">\r\n </mat-header-cell>\r\n <mat-cell *matCellDef=\"let row\">\r\n <button class=\"btn btn-green btn-fill btn-wd btn-just-icon\" (click)=\"editObject(row)\"\r\n matTooltip=\"{{'General.Edit' | translate}}\">\r\n <!-- <mat-icon>edit</mat-icon> -->\r\n <i class=\"material-icons\">edit</i>\r\n <div class=\"ripple-container\"></div>\r\n </button>\r\n <button class=\"btn btn-red btn-fill btn-wd btn-just-icon\" (click)=\"deleteObject(row)\"\r\n [disabled]=\"deleteDisabled(row)\" matTooltip=\"{{'General.Delete' | translate}}\">\r\n <i class=\"material-icons\">delete</i>\r\n <div class=\"ripple-container\"></div>\r\n </button>\r\n </mat-cell>\r\n </ng-container>\r\n\r\n <mat-header-row *matHeaderRowDef=\"displayedColumns;sticky: true\"></mat-header-row>\r\n\r\n <ng-container *ngIf=\"!editOnClick && !editOnDblClick\">\r\n <mat-row *matRowDef=\"let row;let index = dataIndex; columns: displayedColumns;\" cdkDrag [cdkDragData]=\"row\"\r\n [ngClass]=\"{hovered: row.hovered, highlighted: row.highlighted}\" (click)=\"highlight(row)\"\r\n (mouseover)=\"row.hovered = true\" (mouseout)=\"row.hovered = false\">\r\n </mat-row>\r\n </ng-container>\r\n\r\n <ng-container *ngIf=\"editOnClick && !editOnDblClick\">\r\n <mat-row *matRowDef=\"let row;let index = dataIndex; columns: displayedColumns;\" cdkDrag [cdkDragData]=\"row\"\r\n [ngClass]=\"{hovered: row.hovered, highlighted: row.highlighted}\" (click)=\"editObject(row)\"\r\n (mouseover)=\"row.hovered = true\" (mouseout)=\"row.hovered = false\" style=\"cursor: pointer;\"></mat-row>\r\n </ng-container>\r\n\r\n <ng-container *ngIf=\"!editOnClick && editOnDblClick\">\r\n <mat-row *matRowDef=\"let row;let index = dataIndex; columns: displayedColumns;\" cdkDrag [cdkDragData]=\"row\"\r\n [ngClass]=\"{hovered: row.hovered, highlighted: row.highlighted}\" (dblclick)=\"editObject(row)\"\r\n (click)=\"highlight(row)\" (mouseover)=\"row.hovered = true\" (mouseout)=\"row.hovered = false\"\r\n style=\"cursor: pointer;\"></mat-row>\r\n </ng-container>\r\n\r\n <!-- [ngClass]=\"{hovered: row.hovered, highlighted: row.highlighted}\"\r\n (click)=\"highlight(row)\" (mouseover)=\"row.hovered = true\" (mouseout)=\"row.hovered = false\" -->\r\n </mat-table>\r\n <mat-paginator #paginator [hidden]=\"infiniteScroll\" [length]=\"resultsLength\" [pageSize]=\"15\"\r\n [pageSizeOptions]=\"[15, 30, 100]\" [showFirstLastButtons]=\"true\">\r\n </mat-paginator>\r\n </div>\r\n</div>", styles: [".mat-column-delete{flex:0 0 90px;padding-right:30px}.mat-sort-header-button{display:block;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.mat-column-position{flex:0 0 60px!important}.mat-table{overflow-x:auto}[hidden]{display:none!important}\n"], components: [{ type: i3.MatFormField, selector: "mat-form-field", inputs: ["color", "appearance", "hideRequiredMarker", "hintLabel", "floatLabel"], exportAs: ["matFormField"] }, { type: i5$1.MatProgressSpinner, selector: "mat-progress-spinner, mat-spinner", inputs: ["color", "diameter", "strokeWidth", "mode", "value"], exportAs: ["matProgressSpinner"] }, { type: i6$1.MatTable, selector: "mat-table, table[mat-table]", exportAs: ["matTable"] }, { type: i5.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { type: i8$1.MatSortHeader, selector: "[mat-sort-header]", inputs: ["disabled", "mat-sort-header", "arrowPosition", "start", "sortActionDescription", "disableClear"], exportAs: ["matSortHeader"] }, { type: i6$1.MatHeaderRow, selector: "mat-header-row, tr[mat-header-row]", exportAs: ["matHeaderRow"] }, { type: i6$1.MatRow, selector: "mat-row, tr[mat-row]", exportAs: ["matRow"] }, { type: i9.MatPaginator, selector: "mat-paginator", inputs: ["disabled"], exportAs: ["matPaginator"] }], directives: [{ type: i3$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i3.MatLabel, selector: "mat-label" }, { type: i8.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"] }, { type: i2.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { type: i8$1.MatSort, selector: "[matSort]", inputs: ["matSortDisabled", "matSortActive", "matSortStart", "matSortDirection", "matSortDisableClear"], outputs: ["matSortChange"], exportAs: ["matSort"] }, { type: i12.CdkDropList, selector: "[cdkDropList], cdk-drop-list", inputs: ["cdkDropListConnectedTo", "cdkDropListData", "cdkDropListOrientation", "id", "cdkDropListLockAxis", "cdkDropListDisabled", "cdkDropListSortingDisabled", "cdkDropListEnterPredicate", "cdkDropListSortPredicate", "cdkDropListAutoScrollDisabled", "cdkDropListAutoScrollStep"], outputs: ["cdkDropListDropped", "cdkDropListEntered", "cdkDropListExited", "cdkDropListSorted"], exportAs: ["cdkDropList"] }, { type: i6$1.MatColumnDef, selector: "[matColumnDef]", inputs: ["sticky", "matColumnDef"] }, { type: i6$1.MatHeaderCellDef, selector: "[matHeaderCellDef]" }, { type: i6$1.MatHeaderCell, selector: "mat-header-cell, th[mat-header-cell]" }, { type: i6$1.MatCellDef, selector: "[matCellDef]" }, { type: i6$1.MatCell, selector: "mat-cell, td[mat-cell]" }, { type: i12.CdkDragHandle, selector: "[cdkDragHandle]", inputs: ["cdkDragHandleDisabled"] }, { type: i3$1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { type: i13.MatTooltip, selector: "[matTooltip]", exportAs: ["matTooltip"] }, { type: i3$1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { type: i6$1.MatHeaderRowDef, selector: "[matHeaderRowDef]", inputs: ["matHeaderRowDef", "matHeaderRowDefSticky"] }, { type: i6$1.MatRowDef, selector: "[matRowDef]", inputs: ["matRowDefColumns", "matRowDefWhen"] }, { type: i12.CdkDrag, selector: "[cdkDrag]", inputs: ["cdkDragData", "cdkDragLockAxis", "cdkDragRootElement", "cdkDragBoundary", "cdkDragStartDelay", "cdkDragFreeDragPosition", "cdkDragDisabled", "cdkDragConstrainPosition", "cdkDragPreviewClass", "cdkDragPreviewContainer"], outputs: ["cdkDragStarted", "cdkDragReleased", "cdkDragEnded", "cdkDragEntered", "cdkDragExited", "cdkDragDropped", "cdkDragMoved"], exportAs: ["cdkDrag"] }], pipes: { "translate": i1$1.TranslatePipe }, encapsulation: i0.ViewEncapsulation.None });
|
|
1483
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.0", ngImport: i0, type: GenericTableComponent, decorators: [{
|
|
1484
|
+
type: Component,
|
|
1485
|
+
args: [{ selector: 'rsl-generic-table', encapsulation: ViewEncapsulation.None, template: "<div class=\"containerX\" *ngIf=\"hasSearch\">\r\n <div fxLayout=\"row\" fxLayout.xs=\"column\" fxLayout.sm=\"column\" fxFlexFill>\r\n <mat-form-field fxFlex>\r\n <mat-label>Filter</mat-label>\r\n <input matInput [ngModel]='filterValue' (ngModelChange)='filterChanged.next($event)' #filter>\r\n </mat-form-field>\r\n </div>\r\n</div>\r\n\r\n<div class=\"table-container\">\r\n <div class=\"mat-elevation-z2\">\r\n <!-- #applicationsContainer -->\r\n <div class=\"example-loading-shade\" *ngIf=\"isLoadingResults || isRateLimitReached\">\r\n <mat-spinner *ngIf=\"isLoadingResults\"></mat-spinner>\r\n <div class=\"example-rate-limit-reached\" *ngIf=\"isRateLimitReached\">\r\n {{'General.LoadingData' | translate}}\r\n </div>\r\n </div>\r\n\r\n\r\n <mat-table fxFlex #table [dataSource]=\"dataSource\" id=\"tempalte-forms-table\" matSort matSortDisableClear\r\n matSortDirection=\"asc\" cdkDropList [cdkDropListData]=\"dataSource\" (cdkDropListDropped)=\"dropTable($event)\">\r\n <!-- (scroll)=\"onTableScroll($event)\" -->\r\n\r\n\r\n <ng-container matColumnDef=\"position\">\r\n <mat-header-cell *matHeaderCellDef disableClear=\"true\">\r\n <!-- {{'General.Order' | translate}} -->\r\n </mat-header-cell>\r\n <mat-cell fxFlex *matCellDef=\"let element;\">\r\n <mat-icon cdkDragHandle>reorder</mat-icon>\r\n </mat-cell>\r\n </ng-container>\r\n\r\n\r\n <ng-container *ngFor=\"let column of gridLayout\" [matColumnDef]=\"column.propertyName\"\r\n [sticky]=\"isColumnSticky(column.propertyName)\">\r\n <mat-header-cell mat-sort-header disableClear [style.flex]=\"getFlexStyle(column)\" *matHeaderCellDef>\r\n {{column.translateKey | translate}}\r\n </mat-header-cell>\r\n <mat-cell matTooltip={{getCelValue(row,column.propertyName)}} [style.flex]=\"getFlexStyle(column)\"\r\n [style.text-align]=\"getCellTextAlign(column)\" *matCellDef=\"let row\" (click)=\"cellClick(row,column.propertyName)\">\r\n <div [ngClass]=\"getCellClass(row,column.propertyName)\" *ngIf=\"!showPictureCell(column)\">\r\n {{getCelValue(row,column.propertyName)}}\r\n </div>\r\n <img [ngClass]=\"getCellClass(row,column.propertyName)\" *ngIf=\"showPictureCell(column)\">\r\n </mat-cell>\r\n </ng-container>\r\n\r\n\r\n <ng-container matColumnDef=\"delete\" stickyEnd *ngIf=\"!editOnClick && !editOnDblClick\">\r\n <mat-header-cell *matHeaderCellDef disableClear=\"true\">\r\n </mat-header-cell>\r\n <mat-cell *matCellDef=\"let row\">\r\n <button class=\"btn btn-green btn-fill btn-wd btn-just-icon\" (click)=\"editObject(row)\"\r\n matTooltip=\"{{'General.Edit' | translate}}\">\r\n <!-- <mat-icon>edit</mat-icon> -->\r\n <i class=\"material-icons\">edit</i>\r\n <div class=\"ripple-container\"></div>\r\n </button>\r\n <button class=\"btn btn-red btn-fill btn-wd btn-just-icon\" (click)=\"deleteObject(row)\"\r\n [disabled]=\"deleteDisabled(row)\" matTooltip=\"{{'General.Delete' | translate}}\">\r\n <i class=\"material-icons\">delete</i>\r\n <div class=\"ripple-container\"></div>\r\n </button>\r\n </mat-cell>\r\n </ng-container>\r\n\r\n <mat-header-row *matHeaderRowDef=\"displayedColumns;sticky: true\"></mat-header-row>\r\n\r\n <ng-container *ngIf=\"!editOnClick && !editOnDblClick\">\r\n <mat-row *matRowDef=\"let row;let index = dataIndex; columns: displayedColumns;\" cdkDrag [cdkDragData]=\"row\"\r\n [ngClass]=\"{hovered: row.hovered, highlighted: row.highlighted}\" (click)=\"highlight(row)\"\r\n (mouseover)=\"row.hovered = true\" (mouseout)=\"row.hovered = false\">\r\n </mat-row>\r\n </ng-container>\r\n\r\n <ng-container *ngIf=\"editOnClick && !editOnDblClick\">\r\n <mat-row *matRowDef=\"let row;let index = dataIndex; columns: displayedColumns;\" cdkDrag [cdkDragData]=\"row\"\r\n [ngClass]=\"{hovered: row.hovered, highlighted: row.highlighted}\" (click)=\"editObject(row)\"\r\n (mouseover)=\"row.hovered = true\" (mouseout)=\"row.hovered = false\" style=\"cursor: pointer;\"></mat-row>\r\n </ng-container>\r\n\r\n <ng-container *ngIf=\"!editOnClick && editOnDblClick\">\r\n <mat-row *matRowDef=\"let row;let index = dataIndex; columns: displayedColumns;\" cdkDrag [cdkDragData]=\"row\"\r\n [ngClass]=\"{hovered: row.hovered, highlighted: row.highlighted}\" (dblclick)=\"editObject(row)\"\r\n (click)=\"highlight(row)\" (mouseover)=\"row.hovered = true\" (mouseout)=\"row.hovered = false\"\r\n style=\"cursor: pointer;\"></mat-row>\r\n </ng-container>\r\n\r\n <!-- [ngClass]=\"{hovered: row.hovered, highlighted: row.highlighted}\"\r\n (click)=\"highlight(row)\" (mouseover)=\"row.hovered = true\" (mouseout)=\"row.hovered = false\" -->\r\n </mat-table>\r\n <mat-paginator #paginator [hidden]=\"infiniteScroll\" [length]=\"resultsLength\" [pageSize]=\"15\"\r\n [pageSizeOptions]=\"[15, 30, 100]\" [showFirstLastButtons]=\"true\">\r\n </mat-paginator>\r\n </div>\r\n</div>", styles: [".mat-column-delete{flex:0 0 90px;padding-right:30px}.mat-sort-header-button{display:block;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.mat-column-position{flex:0 0 60px!important}.mat-table{overflow-x:auto}[hidden]{display:none!important}\n"] }]
|
|
1486
|
+
}], ctorParameters: function () { return [{ type: DialogService }, { type: i2$1.Router }, { type: i3$1.DatePipe }, { type: i3$1.DecimalPipe }, { type: i3$1.PercentPipe }, { type: i0.Renderer2 }]; }, propDecorators: { modelType: [{
|
|
1487
|
+
type: Input
|
|
1488
|
+
}], baseService: [{
|
|
1489
|
+
type: Input
|
|
1490
|
+
}], gridLayoutService: [{
|
|
1491
|
+
type: Input
|
|
1492
|
+
}], editLink: [{
|
|
1493
|
+
type: Input
|
|
1494
|
+
}], defaultSort: [{
|
|
1495
|
+
type: Input
|
|
1496
|
+
}], defaultSortDirection: [{
|
|
1497
|
+
type: Input
|
|
1498
|
+
}], deleteDisableRule: [{
|
|
1499
|
+
type: Input
|
|
1500
|
+
}], deletePropertyName: [{
|
|
1501
|
+
type: Input
|
|
1502
|
+
}], hasSearch: [{
|
|
1503
|
+
type: Input
|
|
1504
|
+
}], searchFields: [{
|
|
1505
|
+
type: Input
|
|
1506
|
+
}], defaultFilter: [{
|
|
1507
|
+
type: Input
|
|
1508
|
+
}], allowReorderItems: [{
|
|
1509
|
+
type: Input
|
|
1510
|
+
}], stickyColumns: [{
|
|
1511
|
+
type: Input
|
|
1512
|
+
}], editOnClick: [{
|
|
1513
|
+
type: Input
|
|
1514
|
+
}], editOnDblClick: [{
|
|
1515
|
+
type: Input
|
|
1516
|
+
}], allowEdit: [{
|
|
1517
|
+
type: Input
|
|
1518
|
+
}], popupEdit: [{
|
|
1519
|
+
type: Input
|
|
1520
|
+
}], customInclude: [{
|
|
1521
|
+
type: Input
|
|
1522
|
+
}], changeItemPosition: [{
|
|
1523
|
+
type: Input
|
|
1524
|
+
}], infiniteScroll: [{
|
|
1525
|
+
type: Input
|
|
1526
|
+
}], paginator: [{
|
|
1527
|
+
type: ViewChild,
|
|
1528
|
+
args: [MatPaginator, { static: true }]
|
|
1529
|
+
}], sort: [{
|
|
1530
|
+
type: ViewChild,
|
|
1531
|
+
args: [MatSort, { static: true }]
|
|
1532
|
+
}], filter: [{
|
|
1533
|
+
type: ViewChild,
|
|
1534
|
+
args: [ElementRef, { static: false }]
|
|
1535
|
+
}], table: [{
|
|
1536
|
+
type: ViewChild,
|
|
1537
|
+
args: ['table']
|
|
1538
|
+
}], matTableRef: [{
|
|
1539
|
+
type: ViewChild,
|
|
1540
|
+
args: ['table', { read: ElementRef }]
|
|
1541
|
+
}], selectedObject: [{
|
|
1542
|
+
type: Output
|
|
1543
|
+
}], click: [{
|
|
1544
|
+
type: Output
|
|
1545
|
+
}], editModel: [{
|
|
1546
|
+
type: Output
|
|
1547
|
+
}] } });
|
|
1548
|
+
|
|
1549
|
+
// tslint:disable-next-line:variable-name
|
|
1550
|
+
const AttributeMetadata = Symbol('AttributeMetadata');
|
|
1551
|
+
|
|
1552
|
+
class DateConverter {
|
|
1553
|
+
mask(value) {
|
|
1554
|
+
const d = parseISO(value);
|
|
1555
|
+
return d;
|
|
1556
|
+
}
|
|
1557
|
+
unmask(value) {
|
|
1558
|
+
// const result = format(value, 'YYYY-MM-DDTHH:mm:ssZ');
|
|
1559
|
+
return value;
|
|
1560
|
+
}
|
|
1561
|
+
}
|
|
1562
|
+
|
|
1563
|
+
function Attribute(options = {}) {
|
|
1564
|
+
return (target, propertyName) => {
|
|
1565
|
+
const converter = (dataType, value, forSerialisation = false) => {
|
|
1566
|
+
let attrConverter;
|
|
1567
|
+
if (dataType) {
|
|
1568
|
+
if (options.converter) {
|
|
1569
|
+
attrConverter = options.converter;
|
|
1570
|
+
}
|
|
1571
|
+
else if (dataType === Date) {
|
|
1572
|
+
attrConverter = new DateConverter();
|
|
1573
|
+
}
|
|
1574
|
+
else {
|
|
1575
|
+
const datatype = new dataType();
|
|
1576
|
+
if (datatype.mask && datatype.unmask) {
|
|
1577
|
+
attrConverter = datatype;
|
|
1578
|
+
}
|
|
1579
|
+
}
|
|
1580
|
+
if (attrConverter) {
|
|
1581
|
+
if (!forSerialisation) {
|
|
1582
|
+
return attrConverter.mask(value);
|
|
1583
|
+
}
|
|
1584
|
+
return attrConverter.unmask(value);
|
|
1585
|
+
}
|
|
1586
|
+
}
|
|
1587
|
+
return value;
|
|
1588
|
+
};
|
|
1589
|
+
const saveAnnotations = () => {
|
|
1590
|
+
const metadata = Reflect.getMetadata('Attribute', target) || {};
|
|
1591
|
+
metadata[propertyName] = {
|
|
1592
|
+
marked: true
|
|
1593
|
+
};
|
|
1594
|
+
Reflect.defineMetadata('Attribute', metadata, target);
|
|
1595
|
+
const mappingMetadata = Reflect.getMetadata('AttributeMapping', target) || {};
|
|
1596
|
+
const serializedPropertyName = options.serializedName !== undefined ? options.serializedName : propertyName;
|
|
1597
|
+
mappingMetadata[serializedPropertyName] = propertyName;
|
|
1598
|
+
Reflect.defineMetadata('AttributeMapping', mappingMetadata, target);
|
|
1599
|
+
const requiredMetadata = Reflect.getMetadata('AttributeRequired', target) || {};
|
|
1600
|
+
requiredMetadata[serializedPropertyName] = options.required !== undefined ? options.required : false;
|
|
1601
|
+
Reflect.defineMetadata('AttributeRequired', requiredMetadata, target);
|
|
1602
|
+
const defaultMetadata = Reflect.getMetadata('AttributedefaultValue', target) || {};
|
|
1603
|
+
defaultMetadata[serializedPropertyName] = options.defaultValue !== undefined ? options.defaultValue : null;
|
|
1604
|
+
Reflect.defineMetadata('AttributedefaultValue', defaultMetadata, target);
|
|
1605
|
+
const formSubGroupMetadata = Reflect.getMetadata('AttributeformSubGroup', target) || {};
|
|
1606
|
+
formSubGroupMetadata[serializedPropertyName] = options.formSubGroup !== undefined ? options.formSubGroup : null;
|
|
1607
|
+
Reflect.defineMetadata('AttributeformSubGroup', formSubGroupMetadata, target);
|
|
1608
|
+
};
|
|
1609
|
+
const setMetadata = (hasDirtyAttributes, instance, oldValue, newValue, isNew) => {
|
|
1610
|
+
const targetType = Reflect.getMetadata('design:type', target, propertyName);
|
|
1611
|
+
if (!instance[AttributeMetadata]) {
|
|
1612
|
+
instance[AttributeMetadata] = {};
|
|
1613
|
+
}
|
|
1614
|
+
const propertyHasDirtyAttributes = typeof oldValue === 'undefined' && !isNew ? false : hasDirtyAttributes;
|
|
1615
|
+
instance[AttributeMetadata][propertyName] = {
|
|
1616
|
+
newValue,
|
|
1617
|
+
oldValue,
|
|
1618
|
+
serializedName: options.serializedName,
|
|
1619
|
+
hasDirtyAttributes: propertyHasDirtyAttributes,
|
|
1620
|
+
serialisationValue: converter(targetType, newValue, true)
|
|
1621
|
+
};
|
|
1622
|
+
};
|
|
1623
|
+
const getter = function () {
|
|
1624
|
+
return this['_' + propertyName];
|
|
1625
|
+
};
|
|
1626
|
+
const setter = function (newVal) {
|
|
1627
|
+
const targetType = Reflect.getMetadata('design:type', target, propertyName);
|
|
1628
|
+
const convertedValue = converter(targetType, newVal);
|
|
1629
|
+
if (convertedValue !== this['_' + propertyName]) {
|
|
1630
|
+
setMetadata(true, this, this['_' + propertyName], newVal, !this.id);
|
|
1631
|
+
this['_' + propertyName] = convertedValue;
|
|
1632
|
+
}
|
|
1633
|
+
};
|
|
1634
|
+
if (delete target[propertyName]) {
|
|
1635
|
+
saveAnnotations();
|
|
1636
|
+
Object.defineProperty(target, propertyName, {
|
|
1637
|
+
get: getter,
|
|
1638
|
+
set: setter,
|
|
1639
|
+
enumerable: true,
|
|
1640
|
+
configurable: true
|
|
1641
|
+
});
|
|
1642
|
+
}
|
|
1643
|
+
};
|
|
1644
|
+
}
|
|
1645
|
+
|
|
1646
|
+
function BaseDatastoreConfig(config = {}) {
|
|
1647
|
+
// tslint:disable-next-line:only-arrow-functions
|
|
1648
|
+
return (target) => {
|
|
1649
|
+
Reflect.defineMetadata('BaseDatastoreConfig', config, target);
|
|
1650
|
+
};
|
|
1651
|
+
}
|
|
1652
|
+
|
|
1653
|
+
class BaseMetaModel {
|
|
1654
|
+
constructor(response) {
|
|
1655
|
+
this.links = response.links || [];
|
|
1656
|
+
this.meta = response.meta;
|
|
1657
|
+
}
|
|
1658
|
+
}
|
|
1659
|
+
|
|
1660
|
+
function BaseModelConfig(config = {}) {
|
|
1661
|
+
return (target) => {
|
|
1662
|
+
if (typeof config['meta'] === 'undefined' || config['meta'] == null) {
|
|
1663
|
+
config['meta'] = BaseMetaModel;
|
|
1664
|
+
}
|
|
1665
|
+
Reflect.defineMetadata('BaseModelConfig', config, target);
|
|
1666
|
+
};
|
|
1667
|
+
}
|
|
1668
|
+
|
|
1669
|
+
function CustomType(config = {}) {
|
|
1670
|
+
return (target, propertyName) => {
|
|
1671
|
+
const annotations = Reflect.getMetadata('CustomType', target) || [];
|
|
1672
|
+
annotations.push({
|
|
1673
|
+
propertyName,
|
|
1674
|
+
relationship: config.key || propertyName
|
|
1675
|
+
});
|
|
1676
|
+
Reflect.defineMetadata('CustomType', annotations, target);
|
|
1677
|
+
};
|
|
1678
|
+
}
|
|
1679
|
+
|
|
1680
|
+
function GridLayout(translateKey, width, grow = 0, shrink = 0, subProperty, formating = GridLayoutFormat.none, format = '', order = 0, textAlign = CellTextAlign.left) {
|
|
1681
|
+
return (target, propertyName) => {
|
|
1682
|
+
const annotations = Reflect.getMetadata('GridLayout', target) || [];
|
|
1683
|
+
let propName = propertyName;
|
|
1684
|
+
if (subProperty) {
|
|
1685
|
+
propName = propertyName.toString() + '.' + subProperty;
|
|
1686
|
+
}
|
|
1687
|
+
annotations.push({
|
|
1688
|
+
propertyName: propName,
|
|
1689
|
+
translateKey,
|
|
1690
|
+
width,
|
|
1691
|
+
grow,
|
|
1692
|
+
shrink,
|
|
1693
|
+
formating,
|
|
1694
|
+
format,
|
|
1695
|
+
order,
|
|
1696
|
+
textAlign
|
|
1697
|
+
});
|
|
1698
|
+
Reflect.defineMetadata('GridLayout', annotations, target);
|
|
1699
|
+
};
|
|
1700
|
+
}
|
|
1701
|
+
|
|
1702
|
+
class TranslatedElementDirective {
|
|
1703
|
+
constructor(viewRef, templateRef) {
|
|
1704
|
+
this.viewRef = viewRef;
|
|
1705
|
+
this.templateRef = templateRef;
|
|
1706
|
+
}
|
|
1707
|
+
}
|
|
1708
|
+
TranslatedElementDirective.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.0", ngImport: i0, type: TranslatedElementDirective, deps: [{ token: i0.ViewContainerRef }, { token: i0.TemplateRef }], target: i0.ɵɵFactoryTarget.Directive });
|
|
1709
|
+
TranslatedElementDirective.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "12.0.0", version: "13.3.0", type: TranslatedElementDirective, selector: "[translatedElement]", inputs: { elementKey: ["translatedElement", "elementKey"] }, ngImport: i0 });
|
|
1710
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.0", ngImport: i0, type: TranslatedElementDirective, decorators: [{
|
|
1711
|
+
type: Directive,
|
|
1712
|
+
args: [{
|
|
1713
|
+
selector: '[translatedElement]',
|
|
1714
|
+
}]
|
|
1715
|
+
}], ctorParameters: function () { return [{ type: i0.ViewContainerRef }, { type: i0.TemplateRef }]; }, propDecorators: { elementKey: [{
|
|
1716
|
+
type: Input,
|
|
1717
|
+
args: ['translatedElement']
|
|
1718
|
+
}] } });
|
|
1719
|
+
|
|
1720
|
+
const TOKEN_START_DEMARC = '{{';
|
|
1721
|
+
const TOKEN_END_DEMARC = '}}';
|
|
1722
|
+
// adapted from @kasperlauge's solution in https://github.com/ngx-translate/core/issues/223
|
|
1723
|
+
class TranslatedContentDirective {
|
|
1724
|
+
constructor(viewRef, renderer, translateService, changeDetectorRef) {
|
|
1725
|
+
this.viewRef = viewRef;
|
|
1726
|
+
this.renderer = renderer;
|
|
1727
|
+
this.translateService = translateService;
|
|
1728
|
+
this.changeDetectorRef = changeDetectorRef;
|
|
1729
|
+
this.subs = [];
|
|
1730
|
+
}
|
|
1731
|
+
ngOnInit() {
|
|
1732
|
+
this.rawTranslation = merge(this.translateService.get(this.translationKey), this.translateService.onLangChange.asObservable().pipe(switchMap(() => this.translateService.get(this.translationKey))));
|
|
1733
|
+
}
|
|
1734
|
+
ngAfterContentInit() {
|
|
1735
|
+
// QueryList.changes doesn't re-emit after its initial value, which we have by now
|
|
1736
|
+
// BehaviorSubjects re-emit their initial value on subscription, so we get what we need by merging
|
|
1737
|
+
// the BehaviorSubject and the QueryList.changes observable
|
|
1738
|
+
const elementsSubject = new BehaviorSubject(this.elements.toArray());
|
|
1739
|
+
const elementsChanges = merge(elementsSubject, this.elements.changes);
|
|
1740
|
+
this.translationData = combineLatest(this.rawTranslation, elementsChanges)
|
|
1741
|
+
.pipe(map(([rawTranslation]) => {
|
|
1742
|
+
return {
|
|
1743
|
+
elements: this.elements.toArray(),
|
|
1744
|
+
rawTranslation,
|
|
1745
|
+
};
|
|
1746
|
+
}));
|
|
1747
|
+
this.subs.push(this.translationData.subscribe(this.render.bind(this)));
|
|
1748
|
+
}
|
|
1749
|
+
render(translationData) {
|
|
1750
|
+
if (!translationData.rawTranslation || translationData.rawTranslation === this.translationKey) {
|
|
1751
|
+
throw new Error(`No resource matching the key '${this.translationKey}'`);
|
|
1752
|
+
}
|
|
1753
|
+
while (this.viewRef.element.nativeElement.firstChild) {
|
|
1754
|
+
this.renderer.removeChild(this.viewRef.element.nativeElement, this.viewRef.element.nativeElement.firstChild);
|
|
1755
|
+
}
|
|
1756
|
+
let lastTokenEnd = 0;
|
|
1757
|
+
while (lastTokenEnd < translationData.rawTranslation.length) {
|
|
1758
|
+
const tokenStartDemarc = translationData.rawTranslation.indexOf(TOKEN_START_DEMARC, lastTokenEnd);
|
|
1759
|
+
if (tokenStartDemarc < 0) {
|
|
1760
|
+
break;
|
|
1761
|
+
}
|
|
1762
|
+
const tokenStart = tokenStartDemarc + TOKEN_START_DEMARC.length;
|
|
1763
|
+
const tokenEnd = translationData.rawTranslation.indexOf(TOKEN_END_DEMARC, tokenStart);
|
|
1764
|
+
if (tokenEnd < 0) {
|
|
1765
|
+
throw new Error(`Encountered unterminated token in translation string '${this.translationKey}'`);
|
|
1766
|
+
}
|
|
1767
|
+
const tokenEndDemarc = tokenEnd + TOKEN_END_DEMARC.length;
|
|
1768
|
+
const precedingText = translationData.rawTranslation.substring(lastTokenEnd, tokenStartDemarc);
|
|
1769
|
+
const precedingTextElement = this.renderer.createText(precedingText);
|
|
1770
|
+
this.renderer.appendChild(this.viewRef.element.nativeElement, precedingTextElement);
|
|
1771
|
+
const elementKey = translationData.rawTranslation.substring(tokenStart, tokenEnd);
|
|
1772
|
+
const embeddedElementTemplate = translationData.elements.find(element => element.elementKey === elementKey);
|
|
1773
|
+
if (embeddedElementTemplate) {
|
|
1774
|
+
const embeddedElementView = embeddedElementTemplate.viewRef.createEmbeddedView(embeddedElementTemplate.templateRef);
|
|
1775
|
+
this.renderer.appendChild(this.viewRef.element.nativeElement, embeddedElementView.rootNodes[0]);
|
|
1776
|
+
}
|
|
1777
|
+
else {
|
|
1778
|
+
const missingTokenText = translationData.rawTranslation.substring(tokenStartDemarc, tokenEndDemarc);
|
|
1779
|
+
const missingTokenElement = this.renderer.createText(missingTokenText);
|
|
1780
|
+
this.renderer.appendChild(this.viewRef.element.nativeElement, missingTokenElement);
|
|
1781
|
+
}
|
|
1782
|
+
lastTokenEnd = tokenEndDemarc;
|
|
1783
|
+
}
|
|
1784
|
+
const trailingText = translationData.rawTranslation.substring(lastTokenEnd);
|
|
1785
|
+
const trailingTextElement = this.renderer.createText(trailingText);
|
|
1786
|
+
this.renderer.appendChild(this.viewRef.element.nativeElement, trailingTextElement);
|
|
1787
|
+
// in case the rendering happens outside of a change detection event, this ensures that any translations in the
|
|
1788
|
+
// embedded elements are rendered
|
|
1789
|
+
this.changeDetectorRef.detectChanges();
|
|
1790
|
+
}
|
|
1791
|
+
ngOnDestroy() {
|
|
1792
|
+
this.subs.forEach(sub => sub.unsubscribe());
|
|
1793
|
+
}
|
|
1794
|
+
}
|
|
1795
|
+
TranslatedContentDirective.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.0", ngImport: i0, type: TranslatedContentDirective, deps: [{ token: i0.ViewContainerRef }, { token: i0.Renderer2 }, { token: i1$1.TranslateService }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Directive });
|
|
1796
|
+
TranslatedContentDirective.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "12.0.0", version: "13.3.0", type: TranslatedContentDirective, selector: "[appTranslatedContent]", inputs: { translationKey: ["appTranslatedContent", "translationKey"] }, queries: [{ propertyName: "elements", predicate: TranslatedElementDirective }], ngImport: i0 });
|
|
1797
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.0", ngImport: i0, type: TranslatedContentDirective, decorators: [{
|
|
1798
|
+
type: Directive,
|
|
1799
|
+
args: [{
|
|
1800
|
+
selector: '[appTranslatedContent]',
|
|
1801
|
+
}]
|
|
1802
|
+
}], ctorParameters: function () { return [{ type: i0.ViewContainerRef }, { type: i0.Renderer2 }, { type: i1$1.TranslateService }, { type: i0.ChangeDetectorRef }]; }, propDecorators: { translationKey: [{
|
|
1803
|
+
type: Input,
|
|
1804
|
+
args: ['appTranslatedContent']
|
|
1805
|
+
}], elements: [{
|
|
1806
|
+
type: ContentChildren,
|
|
1807
|
+
args: [TranslatedElementDirective]
|
|
1808
|
+
}] } });
|
|
1809
|
+
|
|
1810
|
+
class GridLayoutModel {
|
|
1811
|
+
constructor(propertyName, translateKey = null, width = null, grow = 0, shrink = 0, formating = GridLayoutFormat.none, format = '', order = 0, textAlign = CellTextAlign.left) {
|
|
1812
|
+
this.formating = GridLayoutFormat.none;
|
|
1813
|
+
this.order = 0;
|
|
1814
|
+
this.textAlign = CellTextAlign.left;
|
|
1815
|
+
this.propertyName = propertyName;
|
|
1816
|
+
this.translateKey = translateKey;
|
|
1817
|
+
this.width = width;
|
|
1818
|
+
this.grow = grow;
|
|
1819
|
+
this.shrink = shrink;
|
|
1820
|
+
this.formating = formating;
|
|
1821
|
+
this.format = format;
|
|
1822
|
+
this.order = order;
|
|
1823
|
+
this.textAlign = textAlign;
|
|
1824
|
+
}
|
|
1825
|
+
}
|
|
1826
|
+
|
|
1827
|
+
class BaseModel {
|
|
1828
|
+
// tslint:disable-next-line:variable-name
|
|
1829
|
+
constructor(_datastore, data) {
|
|
1830
|
+
this._datastore = _datastore;
|
|
1831
|
+
if (data) {
|
|
1832
|
+
if (data.id) {
|
|
1833
|
+
this.id = data.id;
|
|
1834
|
+
}
|
|
1835
|
+
Object.assign(this, data);
|
|
1836
|
+
}
|
|
1837
|
+
}
|
|
1838
|
+
save(params, headers, customUrl, customBody) {
|
|
1839
|
+
const attributesMetadata = this[AttributeMetadata];
|
|
1840
|
+
return this._datastore.saveRecord(attributesMetadata, this, params, headers, customUrl, customBody);
|
|
1841
|
+
}
|
|
1842
|
+
patch(origModel, params, headers, customUrl) {
|
|
1843
|
+
const attributesMetadata = this[AttributeMetadata];
|
|
1844
|
+
return this._datastore.patchRecord(attributesMetadata, this, origModel, params, headers, customUrl);
|
|
1845
|
+
}
|
|
1846
|
+
replace(params, headers, customUrl, customBody) {
|
|
1847
|
+
const attributesMetadata = this[AttributeMetadata];
|
|
1848
|
+
return this._datastore.replaceRecord(attributesMetadata, this, params, headers, customUrl, customBody);
|
|
1849
|
+
}
|
|
1850
|
+
get attributeMetadata() {
|
|
1851
|
+
const attributesMetadata = this[AttributeMetadata];
|
|
1852
|
+
return attributesMetadata;
|
|
1853
|
+
}
|
|
1854
|
+
set attributeMetadata(val) {
|
|
1855
|
+
this[AttributeMetadata] = val;
|
|
1856
|
+
}
|
|
1857
|
+
get hasDirtyAttributes() {
|
|
1858
|
+
const attributesMetadata = this[AttributeMetadata];
|
|
1859
|
+
let hasDirtyAttributes = false;
|
|
1860
|
+
for (const propertyName in attributesMetadata) {
|
|
1861
|
+
if (attributesMetadata.hasOwnProperty(propertyName)) {
|
|
1862
|
+
const metadata = attributesMetadata[propertyName];
|
|
1863
|
+
if (metadata.hasDirtyAttributes) {
|
|
1864
|
+
hasDirtyAttributes = true;
|
|
1865
|
+
break;
|
|
1866
|
+
}
|
|
1867
|
+
}
|
|
1868
|
+
}
|
|
1869
|
+
return hasDirtyAttributes;
|
|
1870
|
+
}
|
|
1871
|
+
rollbackAttributes() {
|
|
1872
|
+
const attributesMetadata = this[AttributeMetadata];
|
|
1873
|
+
let metadata;
|
|
1874
|
+
for (const propertyName in attributesMetadata) {
|
|
1875
|
+
if (attributesMetadata.hasOwnProperty(propertyName)) {
|
|
1876
|
+
if (attributesMetadata[propertyName].hasDirtyAttributes) {
|
|
1877
|
+
this[propertyName] = attributesMetadata[propertyName].oldValue;
|
|
1878
|
+
metadata = {
|
|
1879
|
+
hasDirtyAttributes: false,
|
|
1880
|
+
newValue: attributesMetadata[propertyName].oldValue,
|
|
1881
|
+
oldValue: undefined
|
|
1882
|
+
};
|
|
1883
|
+
attributesMetadata[propertyName] = metadata;
|
|
1884
|
+
}
|
|
1885
|
+
}
|
|
1886
|
+
}
|
|
1887
|
+
this[AttributeMetadata] = attributesMetadata;
|
|
1888
|
+
}
|
|
1889
|
+
get modelConfig() {
|
|
1890
|
+
return Reflect.getMetadata('BaseModelConfig', this.constructor);
|
|
1891
|
+
}
|
|
1892
|
+
deserializeModel(modelType, data) {
|
|
1893
|
+
data = this.transformSerializedNamesToPropertyNames(modelType, data);
|
|
1894
|
+
return new modelType(this._datastore, data);
|
|
1895
|
+
}
|
|
1896
|
+
transformSerializedNamesToPropertyNames(modelType, attributes) {
|
|
1897
|
+
const serializedNameToPropertyName = this.getModelPropertyNames(modelType.prototype);
|
|
1898
|
+
const properties = {};
|
|
1899
|
+
Object.keys(serializedNameToPropertyName).forEach((serializedName) => {
|
|
1900
|
+
if (attributes[serializedName] !== null && attributes[serializedName] !== undefined) {
|
|
1901
|
+
properties[serializedNameToPropertyName[serializedName]] = attributes[serializedName];
|
|
1902
|
+
}
|
|
1903
|
+
});
|
|
1904
|
+
return properties;
|
|
1905
|
+
}
|
|
1906
|
+
getModelPropertyNames(model) {
|
|
1907
|
+
return Reflect.getMetadata('AttributeMapping', model);
|
|
1908
|
+
}
|
|
1909
|
+
getModelRequiredPropertyNames(model) {
|
|
1910
|
+
return Reflect.getMetadata('AttributeRequired', model);
|
|
1911
|
+
}
|
|
1912
|
+
getModelDefaultPropertyValues(model) {
|
|
1913
|
+
return Reflect.getMetadata('AttributedefaultValue', model);
|
|
1914
|
+
}
|
|
1915
|
+
getModelSubGroupPropertyNames(model) {
|
|
1916
|
+
return Reflect.getMetadata('AttributeformSubGroup', model);
|
|
1917
|
+
}
|
|
1918
|
+
getFromGroup(fb) {
|
|
1919
|
+
const props = Object.keys(this.getModelPropertyNames(this));
|
|
1920
|
+
const requiredProps = this.getModelRequiredPropertyNames(this);
|
|
1921
|
+
const defaultValues = this.getModelDefaultPropertyValues(this);
|
|
1922
|
+
const formSubGroupsValues = this.getModelSubGroupPropertyNames(this);
|
|
1923
|
+
const controlsConfig = {};
|
|
1924
|
+
const that = this;
|
|
1925
|
+
if (props) {
|
|
1926
|
+
props.forEach(property => {
|
|
1927
|
+
const value = that[property] !== undefined ? that[property] : defaultValues[property];
|
|
1928
|
+
const formSubGroup = formSubGroupsValues[property] ?? null;
|
|
1929
|
+
if (requiredProps[property]) {
|
|
1930
|
+
if (formSubGroup)
|
|
1931
|
+
this.getSubFromGroup(fb, controlsConfig, formSubGroup).addControl(property, fb.control(value, Validators.required));
|
|
1932
|
+
else
|
|
1933
|
+
controlsConfig[property] = [value, Validators.required];
|
|
1934
|
+
}
|
|
1935
|
+
else {
|
|
1936
|
+
if (formSubGroup)
|
|
1937
|
+
this.getSubFromGroup(fb, controlsConfig, formSubGroup).addControl(property, fb.control(value));
|
|
1938
|
+
else
|
|
1939
|
+
controlsConfig[property] = value;
|
|
1940
|
+
}
|
|
1941
|
+
});
|
|
1942
|
+
}
|
|
1943
|
+
return fb.group(controlsConfig);
|
|
1944
|
+
}
|
|
1945
|
+
getSubFromGroup(fb, controlsConfig, subGroup) {
|
|
1946
|
+
if (!controlsConfig[subGroup])
|
|
1947
|
+
controlsConfig[subGroup] = fb.group({});
|
|
1948
|
+
return controlsConfig[subGroup];
|
|
1949
|
+
}
|
|
1950
|
+
getModelFromFormGroup(formGroup, id) {
|
|
1951
|
+
const props = Object.keys(this.getModelPropertyNames(this));
|
|
1952
|
+
const formSubGroupsValues = this.getModelSubGroupPropertyNames(this);
|
|
1953
|
+
const data = {};
|
|
1954
|
+
if (id) {
|
|
1955
|
+
data.id = id;
|
|
1956
|
+
}
|
|
1957
|
+
const that = this;
|
|
1958
|
+
if (props) {
|
|
1959
|
+
props.forEach(property => {
|
|
1960
|
+
const formSubGroup = formSubGroupsValues[property] ?? null;
|
|
1961
|
+
if (!formSubGroup)
|
|
1962
|
+
data[property] = formGroup.controls[property].value ?? null;
|
|
1963
|
+
else
|
|
1964
|
+
data[property] = formGroup.controls[formSubGroup].controls[property].value ?? null;
|
|
1965
|
+
});
|
|
1966
|
+
}
|
|
1967
|
+
if (data) {
|
|
1968
|
+
if (id) {
|
|
1969
|
+
this.id = id;
|
|
1970
|
+
}
|
|
1971
|
+
Object.assign(this, data);
|
|
1972
|
+
}
|
|
1973
|
+
}
|
|
1974
|
+
getGridLayout() {
|
|
1975
|
+
const result = Array();
|
|
1976
|
+
const gridLayout = Reflect.getMetadata('GridLayout', this);
|
|
1977
|
+
if (gridLayout) {
|
|
1978
|
+
for (const layout of gridLayout) {
|
|
1979
|
+
const data = new GridLayoutModel(layout.propertyName, layout.translateKey, layout.width, layout.shrink, layout.grow, layout.formating, layout.format, layout.order, layout.textAlign);
|
|
1980
|
+
result.push(data);
|
|
1981
|
+
}
|
|
1982
|
+
}
|
|
1983
|
+
return result.sort(function (a, b) { return a.order - b.order; });
|
|
1984
|
+
//result;
|
|
1985
|
+
}
|
|
1986
|
+
getSerializedModel() {
|
|
1987
|
+
const attributesMetadata = this[AttributeMetadata];
|
|
1988
|
+
return this._datastore.modelToEntity(this, attributesMetadata, true);
|
|
1989
|
+
}
|
|
1990
|
+
getCellClass(property) {
|
|
1991
|
+
return '';
|
|
1992
|
+
}
|
|
1993
|
+
}
|
|
1994
|
+
|
|
1995
|
+
class ErrorResponse {
|
|
1996
|
+
constructor(errors) {
|
|
1997
|
+
this.errors = [];
|
|
1998
|
+
if (errors) {
|
|
1999
|
+
this.errors = errors;
|
|
2000
|
+
}
|
|
2001
|
+
}
|
|
2002
|
+
}
|
|
2003
|
+
|
|
2004
|
+
class Rule {
|
|
2005
|
+
constructor() {
|
|
2006
|
+
this.parameters = [];
|
|
2007
|
+
}
|
|
2008
|
+
}
|
|
2009
|
+
|
|
2010
|
+
class MaterialModule {
|
|
2011
|
+
}
|
|
2012
|
+
MaterialModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.0", ngImport: i0, type: MaterialModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
|
|
2013
|
+
MaterialModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "12.0.0", version: "13.3.0", ngImport: i0, type: MaterialModule, imports: [MatAutocompleteModule, MatButtonModule, MatButtonToggleModule, MatCardModule, MatCheckboxModule, MatChipsModule, MatDatepickerModule,
|
|
2014
|
+
MatDialogModule, MatExpansionModule, MatGridListModule, MatIconModule,
|
|
2015
|
+
MatInputModule, MatListModule, MatMenuModule, MatNativeDateModule,
|
|
2016
|
+
MatPaginatorModule, MatProgressBarModule, MatProgressSpinnerModule, MatRadioModule, MatRippleModule, MatSelectModule, MatSidenavModule,
|
|
2017
|
+
MatSliderModule, MatSlideToggleModule, MatSnackBarModule, MatSortModule, MatTableModule, MatTabsModule, MatToolbarModule,
|
|
2018
|
+
MatTooltipModule, MatOptionModule, DragDropModule, MatDividerModule, PortalModule, MatTreeModule, MatBadgeModule, MatStepperModule,
|
|
2019
|
+
CdkStepperModule], exports: [MatAutocompleteModule, MatButtonModule, MatButtonToggleModule, MatCardModule, MatCheckboxModule, MatChipsModule, MatDatepickerModule,
|
|
2020
|
+
MatDialogModule, MatExpansionModule, MatGridListModule, MatIconModule,
|
|
2021
|
+
MatInputModule, MatListModule, MatMenuModule, MatNativeDateModule,
|
|
2022
|
+
MatPaginatorModule, MatProgressBarModule, MatProgressSpinnerModule, MatRadioModule, MatRippleModule, MatSelectModule, MatSidenavModule,
|
|
2023
|
+
MatSliderModule, MatSlideToggleModule, MatSnackBarModule, MatSortModule, MatTableModule, MatTabsModule, MatToolbarModule,
|
|
2024
|
+
MatTooltipModule, MatOptionModule, DragDropModule, MatDividerModule, PortalModule, MatTreeModule, MatBadgeModule, MatStepperModule,
|
|
2025
|
+
CdkStepperModule] });
|
|
2026
|
+
MaterialModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "13.3.0", ngImport: i0, type: MaterialModule, imports: [[
|
|
2027
|
+
MatAutocompleteModule, MatButtonModule, MatButtonToggleModule, MatCardModule, MatCheckboxModule, MatChipsModule, MatDatepickerModule,
|
|
2028
|
+
MatDialogModule, MatExpansionModule, MatGridListModule, MatIconModule,
|
|
2029
|
+
MatInputModule, MatListModule, MatMenuModule, MatNativeDateModule,
|
|
2030
|
+
MatPaginatorModule, MatProgressBarModule, MatProgressSpinnerModule, MatRadioModule, MatRippleModule, MatSelectModule, MatSidenavModule,
|
|
2031
|
+
MatSliderModule, MatSlideToggleModule, MatSnackBarModule, MatSortModule, MatTableModule, MatTabsModule, MatToolbarModule,
|
|
2032
|
+
MatTooltipModule, MatOptionModule, DragDropModule, MatDividerModule, PortalModule, MatTreeModule, MatBadgeModule, MatStepperModule,
|
|
2033
|
+
CdkStepperModule
|
|
2034
|
+
], MatAutocompleteModule, MatButtonModule, MatButtonToggleModule, MatCardModule, MatCheckboxModule, MatChipsModule, MatDatepickerModule,
|
|
2035
|
+
MatDialogModule, MatExpansionModule, MatGridListModule, MatIconModule,
|
|
2036
|
+
MatInputModule, MatListModule, MatMenuModule, MatNativeDateModule,
|
|
2037
|
+
MatPaginatorModule, MatProgressBarModule, MatProgressSpinnerModule, MatRadioModule, MatRippleModule, MatSelectModule, MatSidenavModule,
|
|
2038
|
+
MatSliderModule, MatSlideToggleModule, MatSnackBarModule, MatSortModule, MatTableModule, MatTabsModule, MatToolbarModule,
|
|
2039
|
+
MatTooltipModule, MatOptionModule, DragDropModule, MatDividerModule, PortalModule, MatTreeModule, MatBadgeModule, MatStepperModule,
|
|
2040
|
+
CdkStepperModule] });
|
|
2041
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.0", ngImport: i0, type: MaterialModule, decorators: [{
|
|
2042
|
+
type: NgModule,
|
|
2043
|
+
args: [{
|
|
2044
|
+
imports: [
|
|
2045
|
+
MatAutocompleteModule, MatButtonModule, MatButtonToggleModule, MatCardModule, MatCheckboxModule, MatChipsModule, MatDatepickerModule,
|
|
2046
|
+
MatDialogModule, MatExpansionModule, MatGridListModule, MatIconModule,
|
|
2047
|
+
MatInputModule, MatListModule, MatMenuModule, MatNativeDateModule,
|
|
2048
|
+
MatPaginatorModule, MatProgressBarModule, MatProgressSpinnerModule, MatRadioModule, MatRippleModule, MatSelectModule, MatSidenavModule,
|
|
2049
|
+
MatSliderModule, MatSlideToggleModule, MatSnackBarModule, MatSortModule, MatTableModule, MatTabsModule, MatToolbarModule,
|
|
2050
|
+
MatTooltipModule, MatOptionModule, DragDropModule, MatDividerModule, PortalModule, MatTreeModule, MatBadgeModule, MatStepperModule,
|
|
2051
|
+
CdkStepperModule
|
|
2052
|
+
],
|
|
2053
|
+
exports: [
|
|
2054
|
+
MatAutocompleteModule, MatButtonModule, MatButtonToggleModule, MatCardModule, MatCheckboxModule, MatChipsModule, MatDatepickerModule,
|
|
2055
|
+
MatDialogModule, MatExpansionModule, MatGridListModule, MatIconModule,
|
|
2056
|
+
MatInputModule, MatListModule, MatMenuModule, MatNativeDateModule,
|
|
2057
|
+
MatPaginatorModule, MatProgressBarModule, MatProgressSpinnerModule, MatRadioModule, MatRippleModule, MatSelectModule, MatSidenavModule,
|
|
2058
|
+
MatSliderModule, MatSlideToggleModule, MatSnackBarModule, MatSortModule, MatTableModule, MatTabsModule, MatToolbarModule,
|
|
2059
|
+
MatTooltipModule, MatOptionModule, DragDropModule, MatDividerModule, PortalModule, MatTreeModule, MatBadgeModule, MatStepperModule,
|
|
2060
|
+
CdkStepperModule
|
|
2061
|
+
],
|
|
2062
|
+
}]
|
|
2063
|
+
}] });
|
|
2064
|
+
|
|
2065
|
+
class GridLayoutService {
|
|
2066
|
+
constructor(baseService) {
|
|
2067
|
+
this.baseService = baseService;
|
|
2068
|
+
}
|
|
2069
|
+
getGridLayout() {
|
|
2070
|
+
var model = this.baseService.newModel();
|
|
2071
|
+
return model.getGridLayout();
|
|
2072
|
+
}
|
|
2073
|
+
}
|
|
2074
|
+
GridLayoutService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.0", ngImport: i0, type: GridLayoutService, deps: [{ token: BaseService }], target: i0.ɵɵFactoryTarget.Injectable });
|
|
2075
|
+
GridLayoutService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "13.3.0", ngImport: i0, type: GridLayoutService, providedIn: 'root' });
|
|
2076
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.0", ngImport: i0, type: GridLayoutService, decorators: [{
|
|
2077
|
+
type: Injectable,
|
|
2078
|
+
args: [{
|
|
2079
|
+
providedIn: 'root'
|
|
2080
|
+
}]
|
|
2081
|
+
}], ctorParameters: function () { return [{ type: BaseService }]; } });
|
|
2082
|
+
|
|
2083
|
+
const PROVIDERS = [
|
|
2084
|
+
BaseDatastore,
|
|
2085
|
+
DatePipe,
|
|
2086
|
+
DecimalPipe,
|
|
2087
|
+
PercentPipe,
|
|
2088
|
+
];
|
|
2089
|
+
|
|
2090
|
+
class RslBaseModule {
|
|
2091
|
+
}
|
|
2092
|
+
RslBaseModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.0", ngImport: i0, type: RslBaseModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
|
|
2093
|
+
RslBaseModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "12.0.0", version: "13.3.0", ngImport: i0, type: RslBaseModule, declarations: [GenericTableComponent,
|
|
2094
|
+
SearchableDropdownComponent], imports: [CommonModule, i1$1.TranslateModule, MaterialModule,
|
|
2095
|
+
ReactiveFormsModule, i2$2.BlockUIModule], exports: [HttpClientModule,
|
|
2096
|
+
GenericTableComponent,
|
|
2097
|
+
SearchableDropdownComponent] });
|
|
2098
|
+
RslBaseModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "13.3.0", ngImport: i0, type: RslBaseModule, providers: [
|
|
2099
|
+
PROVIDERS
|
|
2100
|
+
], imports: [[
|
|
2101
|
+
CommonModule,
|
|
2102
|
+
TranslateModule.forChild({}),
|
|
2103
|
+
MaterialModule,
|
|
2104
|
+
ReactiveFormsModule,
|
|
2105
|
+
BlockUIModule.forRoot(),
|
|
2106
|
+
], HttpClientModule] });
|
|
2107
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.0", ngImport: i0, type: RslBaseModule, decorators: [{
|
|
2108
|
+
type: NgModule,
|
|
2109
|
+
args: [{
|
|
2110
|
+
declarations: [
|
|
2111
|
+
GenericTableComponent,
|
|
2112
|
+
SearchableDropdownComponent
|
|
2113
|
+
],
|
|
2114
|
+
imports: [
|
|
2115
|
+
CommonModule,
|
|
2116
|
+
TranslateModule.forChild({}),
|
|
2117
|
+
MaterialModule,
|
|
2118
|
+
ReactiveFormsModule,
|
|
2119
|
+
BlockUIModule.forRoot(),
|
|
2120
|
+
],
|
|
2121
|
+
providers: [
|
|
2122
|
+
PROVIDERS
|
|
2123
|
+
],
|
|
2124
|
+
exports: [
|
|
2125
|
+
HttpClientModule,
|
|
2126
|
+
GenericTableComponent,
|
|
2127
|
+
SearchableDropdownComponent
|
|
2128
|
+
]
|
|
2129
|
+
}]
|
|
2130
|
+
}] });
|
|
2131
|
+
|
|
2132
|
+
class InputErrorPipe {
|
|
2133
|
+
constructor(translate) {
|
|
2134
|
+
this.translate = translate;
|
|
2135
|
+
}
|
|
2136
|
+
transform(value, filedTranslationKey) {
|
|
2137
|
+
let rvalue = '';
|
|
2138
|
+
if (value !== null) {
|
|
2139
|
+
if (value['invalid'] === true) {
|
|
2140
|
+
rvalue = 'ERROR.INVALID';
|
|
2141
|
+
}
|
|
2142
|
+
if (value['mustMatch'] === true) {
|
|
2143
|
+
rvalue = 'Account.Password.MustMach';
|
|
2144
|
+
}
|
|
2145
|
+
if (value['required'] === true) {
|
|
2146
|
+
const field = this.translate.instant(filedTranslationKey.field);
|
|
2147
|
+
rvalue = this.translate.instant('General.Field.Required', { field });
|
|
2148
|
+
}
|
|
2149
|
+
if (value['minlength']) {
|
|
2150
|
+
const field = this.translate.instant(filedTranslationKey.field);
|
|
2151
|
+
rvalue = this.translate.instant('General.Field.MinLength', { field, requiredLength: value.minlength.requiredLength });
|
|
2152
|
+
}
|
|
2153
|
+
}
|
|
2154
|
+
return rvalue;
|
|
2155
|
+
}
|
|
2156
|
+
}
|
|
2157
|
+
InputErrorPipe.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.0", ngImport: i0, type: InputErrorPipe, deps: [{ token: i1$1.TranslateService }], target: i0.ɵɵFactoryTarget.Pipe });
|
|
2158
|
+
InputErrorPipe.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "12.0.0", version: "13.3.0", ngImport: i0, type: InputErrorPipe, name: "inputError" });
|
|
2159
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.0", ngImport: i0, type: InputErrorPipe, decorators: [{
|
|
2160
|
+
type: Pipe,
|
|
2161
|
+
args: [{
|
|
2162
|
+
name: 'inputError'
|
|
2163
|
+
}]
|
|
2164
|
+
}], ctorParameters: function () { return [{ type: i1$1.TranslateService }]; } });
|
|
2165
|
+
|
|
2166
|
+
class Nl2brPipe {
|
|
2167
|
+
transform(value, args) {
|
|
2168
|
+
// return value.replace(/\n/g, '<br />');
|
|
2169
|
+
if (value) {
|
|
2170
|
+
value = value.replace(/(?:\r\n\r\n|\r\r|\n\n)/g, '</p><p>');
|
|
2171
|
+
return '<p>' + value.replace(/(?:\r\n|\r|\n)/g, '<br>') + '</p>';
|
|
2172
|
+
}
|
|
2173
|
+
return value;
|
|
2174
|
+
}
|
|
2175
|
+
}
|
|
2176
|
+
Nl2brPipe.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.0", ngImport: i0, type: Nl2brPipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe });
|
|
2177
|
+
Nl2brPipe.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "12.0.0", version: "13.3.0", ngImport: i0, type: Nl2brPipe, name: "nl2br" });
|
|
2178
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.0", ngImport: i0, type: Nl2brPipe, decorators: [{
|
|
2179
|
+
type: Pipe,
|
|
2180
|
+
args: [{
|
|
2181
|
+
name: 'nl2br'
|
|
2182
|
+
}]
|
|
2183
|
+
}] });
|
|
2184
|
+
|
|
2185
|
+
class CustomValidators {
|
|
2186
|
+
static patternValidator(regex, error) {
|
|
2187
|
+
return (control) => {
|
|
2188
|
+
if (!control.value) {
|
|
2189
|
+
// if control is empty return no error
|
|
2190
|
+
return null;
|
|
2191
|
+
}
|
|
2192
|
+
// test the value of the control against the regexp supplied
|
|
2193
|
+
const valid = regex.test(control.value);
|
|
2194
|
+
// if true, return no error (no error), else return error passed in the second parameter
|
|
2195
|
+
return valid ? null : error;
|
|
2196
|
+
};
|
|
2197
|
+
}
|
|
2198
|
+
}
|
|
2199
|
+
|
|
2200
|
+
/*
|
|
2201
|
+
* Public API Surface of core
|
|
2202
|
+
*/
|
|
2203
|
+
// export * from './lib/services/base-datastore.service';
|
|
2204
|
+
|
|
2205
|
+
/**
|
|
2206
|
+
* Generated bundle index. Do not edit.
|
|
2207
|
+
*/
|
|
2208
|
+
|
|
2209
|
+
export { Attribute, BaseDatastore, BaseDatastoreConfig, BaseFormEditComponent, BaseMetaModel, BaseModel, BaseModelConfig, BaseQueryData, BaseService, CellTextAlign, CustomType, CustomValidators, DialogService, ErrorResponse, FieldErrorDisplayComponent, GenericTableComponent, GridLayout, GridLayoutFormat, GridLayoutModel, GridLayoutService, InputErrorPipe, MaterialModule, Nl2brPipe, PROVIDERS, PageNotFoundComponent, RslBaseModule, Rule, SearchableDropdownComponent, TranslatedContentDirective, TranslatedElementDirective, UnderConstructionComponent };
|
|
2210
|
+
//# sourceMappingURL=rosoftlab-core.mjs.map
|