@vgip/meta-ui 2.1.3 → 2.1.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (111) hide show
  1. package/fesm2022/vgip-meta-ui.mjs +6092 -0
  2. package/fesm2022/vgip-meta-ui.mjs.map +1 -0
  3. package/index.d.ts +709 -0
  4. package/package.json +15 -3
  5. package/.eslintrc.json +0 -57
  6. package/karma.conf.js +0 -35
  7. package/ng-package.json +0 -10
  8. package/src/lib/common/fieldNormalizer/boolean.ts +0 -11
  9. package/src/lib/common/fieldNormalizer/datetime.ts +0 -8
  10. package/src/lib/common/fieldNormalizer/index.ts +0 -171
  11. package/src/lib/common/fieldNormalizer/number.ts +0 -13
  12. package/src/lib/common/fieldNormalizer/options.ts +0 -48
  13. package/src/lib/common/fieldNormalizer/radio.ts +0 -29
  14. package/src/lib/common/fieldNormalizer/reference.ts +0 -32
  15. package/src/lib/common/fieldNormalizer/richtext.ts +0 -15
  16. package/src/lib/common/fieldNormalizer/string.ts +0 -23
  17. package/src/lib/common/fieldNormalizer/text.ts +0 -17
  18. package/src/lib/common/fieldNormalizer/uniqueNameFilter.ts +0 -21
  19. package/src/lib/common/metaAutofocus.directive.ts +0 -31
  20. package/src/lib/common/metaContext.resolver.ts +0 -25
  21. package/src/lib/common/metaIcons.pipe.spec.ts +0 -15
  22. package/src/lib/common/metaIcons.pipe.ts +0 -29
  23. package/src/lib/common/metaModel.pipe.ts +0 -19
  24. package/src/lib/common/metaNormalizer.ts +0 -366
  25. package/src/lib/common/metaStripHtml.pipe.ts +0 -18
  26. package/src/lib/common/utils/colorThemes.ts +0 -86
  27. package/src/lib/common/utils/indexedDbStore/index.ts +0 -244
  28. package/src/lib/common/utils/indexedDbStore/indexedDbStore.spec.ts +0 -149
  29. package/src/lib/common/utils/relativeTimeBuilder.ts +0 -49
  30. package/src/lib/common/utils/resourceCardLabel.ts +0 -25
  31. package/src/lib/common/utils/smartProp.spec.ts +0 -24
  32. package/src/lib/common/utils/smartProp.ts +0 -28
  33. package/src/lib/common/utils/templateBuilder.ts +0 -99
  34. package/src/lib/field.scss +0 -207
  35. package/src/lib/fieldAbstract.ts +0 -327
  36. package/src/lib/fieldBoolean/index.ts +0 -55
  37. package/src/lib/fieldBoolean/style.scss +0 -22
  38. package/src/lib/fieldBoolean/test.spec.ts +0 -43
  39. package/src/lib/fieldBoolean/view.html +0 -30
  40. package/src/lib/fieldComposite/index.ts +0 -86
  41. package/src/lib/fieldComposite/style.scss +0 -6
  42. package/src/lib/fieldComposite/test.spec.ts +0 -43
  43. package/src/lib/fieldComposite/view.html +0 -9
  44. package/src/lib/fieldDatetime/index.ts +0 -359
  45. package/src/lib/fieldDatetime/style.scss +0 -81
  46. package/src/lib/fieldDatetime/test.spec.ts +0 -43
  47. package/src/lib/fieldDatetime/view.html +0 -26
  48. package/src/lib/fieldHidden/index.ts +0 -15
  49. package/src/lib/fieldHidden/view.html +0 -0
  50. package/src/lib/fieldInput/index.ts +0 -477
  51. package/src/lib/fieldInput/style.scss +0 -128
  52. package/src/lib/fieldInput/test.spec.ts +0 -43
  53. package/src/lib/fieldInput/view.html +0 -81
  54. package/src/lib/fieldList/index.ts +0 -73
  55. package/src/lib/fieldList/style.scss +0 -26
  56. package/src/lib/fieldList/test.spec.ts +0 -43
  57. package/src/lib/fieldList/view.html +0 -25
  58. package/src/lib/fieldRadio/index.ts +0 -93
  59. package/src/lib/fieldRadio/style.scss +0 -32
  60. package/src/lib/fieldRadio/test.spec.ts +0 -43
  61. package/src/lib/fieldRadio/view.html +0 -24
  62. package/src/lib/fieldReference/index.ts +0 -871
  63. package/src/lib/fieldReference/style.scss +0 -273
  64. package/src/lib/fieldReference/test.spec.ts +0 -44
  65. package/src/lib/fieldReference/view.html +0 -163
  66. package/src/lib/fieldRichtext/index.ts +0 -98
  67. package/src/lib/fieldRichtext/quill.scss +0 -6
  68. package/src/lib/fieldRichtext/style.scss +0 -87
  69. package/src/lib/fieldRichtext/test.spec.ts +0 -43
  70. package/src/lib/fieldRichtext/view.html +0 -17
  71. package/src/lib/fieldSelect/index.ts +0 -597
  72. package/src/lib/fieldSelect/style.scss +0 -165
  73. package/src/lib/fieldSelect/test.spec.ts +0 -44
  74. package/src/lib/fieldSelect/view.html +0 -128
  75. package/src/lib/fieldText/index.ts +0 -86
  76. package/src/lib/fieldText/style.scss +0 -24
  77. package/src/lib/fieldText/test.spec.ts +0 -43
  78. package/src/lib/fieldText/view.html +0 -23
  79. package/src/lib/fieldUnknown/index.ts +0 -15
  80. package/src/lib/fieldUnknown/test.spec.ts +0 -34
  81. package/src/lib/fieldUnknown/view.html +0 -9
  82. package/src/lib/index.ts +0 -127
  83. package/src/lib/layout/index.ts +0 -255
  84. package/src/lib/layout/style.scss +0 -67
  85. package/src/lib/layout/view.html +0 -45
  86. package/src/lib/metaField/index.ts +0 -133
  87. package/src/lib/metaField/test.spec.ts +0 -32
  88. package/src/lib/refDialog/index.ts +0 -157
  89. package/src/lib/refDialog/style.scss +0 -154
  90. package/src/lib/refDialog/view.html +0 -24
  91. package/src/lib/resource/index.ts +0 -559
  92. package/src/lib/resource/style.scss +0 -132
  93. package/src/lib/resource/view.html +0 -70
  94. package/src/lib/resourceCard/index.ts +0 -44
  95. package/src/lib/resourceCard/style.scss +0 -7
  96. package/src/lib/resourceCard/view.html +0 -14
  97. package/src/lib/services/metaContext/index.ts +0 -61
  98. package/src/lib/services/metaMsg/index.ts +0 -84
  99. package/src/lib/services/metaReference/index.ts +0 -98
  100. package/src/lib/services/metaResource/index.ts +0 -163
  101. package/src/lib/services/metaResource/metaHttpClient.ts +0 -76
  102. package/src/lib/services/metaResource/metaResource.spec.ts +0 -24
  103. package/src/lib/services/metaTracker/index.ts +0 -38
  104. package/src/lib/services/resourceDrafts/index.ts +0 -81
  105. package/src/lib/services/resourceDrafts/resourceDrafts.spec.ts +0 -24
  106. package/src/lib/styles.scss +0 -13
  107. package/src/public-api.ts +0 -5
  108. package/src/test.ts +0 -17
  109. package/tsconfig.lib.json +0 -25
  110. package/tsconfig.lib.prod.json +0 -9
  111. package/tsconfig.spec.json +0 -17
@@ -1,43 +0,0 @@
1
- /*
2
- * @Author: Alexander.Vangelov@vonage.com
3
- * @Date: 2019-09-19 17:35:19
4
- * @Last Modified by: Alexander.Vangelov@vonage.com
5
- * @Last Modified time: 2020-02-27 12:17:16
6
- */
7
-
8
- import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
9
- import { NgForm } from '@angular/forms';
10
-
11
- import { MetaModule } from '..';
12
-
13
- import { FieldRichtext } from '.';
14
-
15
- describe('FieldRichtext', () => {
16
- let component: FieldRichtext;
17
- let fixture: ComponentFixture<FieldRichtext>;
18
-
19
- beforeEach(waitForAsync(() => {
20
- TestBed.configureTestingModule({
21
- declarations: [],
22
- imports: [
23
- MetaModule
24
- ],
25
- providers: [
26
- { provide: NgForm, useValue: new NgForm([], []) }
27
- ]
28
- })
29
- .compileComponents();
30
- }));
31
-
32
- beforeEach(() => {
33
- fixture = TestBed.createComponent(FieldRichtext);
34
- component = fixture.componentInstance;
35
- component.parent = {};
36
- component.meta = { name: 'f1' };
37
- fixture.detectChanges();
38
- });
39
-
40
- it('should create', () => {
41
- expect(component).toBeTruthy();
42
- });
43
- });
@@ -1,17 +0,0 @@
1
- <div class='vgip-meta-field-preview' *ngIf='preview && parent[meta.name]'>
2
- <div class='vgip-meta-field-label' [title]='meta.label || meta.name'>{{meta.label || meta.name}}</div>
3
- <div class='vgip-meta-field-value __gu'>{{parent[meta.name]}}</div>
4
- </div>
5
- <div *ngIf='!preview' class="Vlt-form__element" [ngClass]="{ 'Vlt-form__element--error': f.invalid && ((f | metaModel)._parent.submitted || (fq | metaModel).touched) }">
6
- <label class="Vlt-label">{{meta.label || meta.name}}<span *ngIf='validations.required' class='Vlt-red'>*</span></label> <!-- eslint-disable-line -->
7
- <div class="Vlt-textarea" [ngClass]='{ active: active }'>
8
- <input type='hidden' class='main model' [required]='validations.required' [minlength]='validations.minlength' [maxlength]='validations.maxlength' [(ngModel)]='parent[meta.name]' #f='ngModel' [name]='name'/>
9
- <quill-editor (onFocus)='active = true' (onBlur)='active = false' class='main model' [(ngModel)]='parent[meta.name]' #fq='ngModel' (ngModelChange)="onModelChangeLocal($event)" [ngModelOptions]='{ standalone: true }' placeholder=' ' [modules]="quillConfigModules"></quill-editor>
10
- </div>
11
- <small *ngIf='f.invalid && ((f | metaModel)._parent.submitted || (fq | metaModel).touched)' class="Vlt-form__element__error">
12
- <span *ngIf="f.errors.required">Required</span>
13
- <span *ngIf="f.errors.maxlength">Length can not exceed {{validations.maxlength}} characters</span>
14
- <span *ngIf="f.errors.custom">{{f.errors.custom}}&nbsp;</span>
15
- </small>
16
- <small *ngIf='meta.helpText' class="Vlt-form__element__hint">{{meta.helpText}}</small>
17
- </div>
@@ -1,597 +0,0 @@
1
- import { Component, OnInit, ViewContainerRef } from '@angular/core';
2
- import { FieldAbstract } from '../fieldAbstract';
3
- import { ControlContainer, NgForm } from '@angular/forms';
4
- import { MetaReferenceService } from '../services/metaReference';
5
- import { MetaResourceService, IMetaResourceConfig } from '../services/metaResource';
6
- import { MetaRefDialog } from '../refDialog';
7
-
8
- @Component({
9
- templateUrl: './view.html',
10
- styleUrls: ['./style.scss'],
11
- viewProviders: [{ provide: ControlContainer, useExisting: NgForm }],
12
- standalone: false
13
- })
14
- export class FieldSelect extends FieldAbstract implements OnInit {
15
- multiple: boolean;
16
- input: HTMLInputElement;
17
- dropdown: HTMLElement;
18
- dropdownScrollContainer: HTMLElement;
19
- showText: string;
20
- activeSuggestionIndex: number;
21
- value: any;
22
- isCreatable = false;
23
- isUpdatable = false;
24
- asyncOptions: Array<any>;
25
- searching: boolean;
26
- filteredOptions: Array<any>;
27
- searchInputText: '';
28
- searchInput: HTMLInputElement;
29
- private desiredValue: any;
30
-
31
- constructor(
32
- private referenceService: MetaReferenceService,
33
- private metaResource: MetaResourceService,
34
- private viewContainerRef: ViewContainerRef
35
- ) {
36
- super();
37
- }
38
-
39
- get options() {
40
- return this.filteredOptions || this.asyncOptions || this.meta.options || this.meta.picklist || [];
41
- }
42
-
43
- get groupedOptions() {
44
- return this.options.reduce((r, { group }) => {
45
- if (!r.some(o => o.group === group)) {
46
- r.push({ group, groupItem: this.options.filter(v => v.group === group) });
47
- }
48
- return r;
49
- }, []);
50
- }
51
-
52
- get resourceService() {
53
- if (!this.metaResourceService) {
54
- const metaResourceConfig: IMetaResourceConfig = {
55
- integrationCode: this.integrationCode,
56
- resourceType: this.resourceType,
57
- delegate: this.delegate
58
- };
59
- this.metaResourceService = this.metaResource.new(metaResourceConfig);
60
- }
61
- return this.metaResourceService;
62
- }
63
-
64
- get optionsBackup() {
65
- return this.asyncOptions || this.meta.options || this.meta.picklist || [];
66
- }
67
-
68
- // static setup(instance, parent, meta) { } // eslint-disable-line @typescript-eslint/no-unused-vars
69
-
70
- ngOnInit() {
71
- // console.log('parent', this.parent);
72
- this.validationAttributes = ['required'];
73
- this.multiple = (this.meta.type === 'multipicklist') || this.meta.multiple;
74
- const origValue = this.parent[this.meta.name];
75
- if (this.meta.reference) {
76
- this.isCreatable = true;
77
- this.isUpdatable = this.meta.reference.updatable
78
- }
79
- Object.defineProperty(this.parent, this.meta.name, {
80
- set: (value) => {
81
- this.desiredValue = value;
82
- if (this.multiple) {
83
- if (value && value instanceof Array === false) {
84
- for (const o of this.optionsBackup) {
85
- if ((value.id || value) === (o.id || o.value || o.name || 0)) {
86
- this.model = [o];
87
- this.value = [this.modelToValue(o, this.meta.valueType)];
88
- break;
89
- }
90
- }
91
- }
92
- if (!value || value.length) {
93
- const values = (value instanceof Array) ? value : (value || '').split(';'); // should not handle incorrect values
94
- this.value = [];
95
- this.model = [];
96
- for (const v of values) {
97
- if (v) {
98
- for (const o of this.optionsBackup) {
99
- if ((v.id || v) === (o.id || o.value || o.name || 0)) {
100
- this.model.push(o);
101
- this.value.push(this.modelToValue(o, this.meta.valueType));
102
- break;
103
- }
104
- }
105
- }
106
- }
107
- if (!this.model.length && !this.isPersistedParent) {
108
- delete this.model;
109
- delete this.value;
110
- delete this.showText;
111
- } else {
112
- this.showText = (this.model || []).map((o) => o.label || o).join(', ');
113
- }
114
- }
115
- } else {
116
- if (value) {
117
- for (const o of this.options) {
118
- if ((value.id || value) === (o.id || o.value || o.name || o)) {
119
- this.model = o;
120
- this.value = this.modelToValue(o, this.meta.valueType);
121
- this.showText = o.label || o;
122
- break;
123
- }
124
- }
125
- } else {
126
- delete this.model;
127
- delete this.value;
128
- delete this.showText;
129
- }
130
- }
131
- this.onSubjectChange(this.model);
132
- this.meta.$optional = this.isOptional;
133
- },
134
- get: () => this.value,
135
- enumerable: this.sendToServer,
136
- configurable: true
137
- });
138
-
139
- if (origValue) {
140
- this.parent[this.meta.name] = origValue;
141
- }
142
-
143
- if (this.default && !this.model) {
144
- setTimeout(() => {
145
- if (!this.model) {
146
- this.parent[this.meta.name] = this.default.id || this.default;
147
- }
148
- }, 0);
149
- }
150
-
151
- if (typeof (this.meta.enabled) !== 'undefined') {
152
- if (typeof (this.meta.enabled) === 'object') {
153
- for (const par of Object.keys(this.meta.enabled)) {
154
- console.log('this.meta.enabled', this.meta.enabled)
155
- const parValue = this.parent[par];
156
- if (parValue) {
157
- // logic for specific values, this works only for true
158
- } else {
159
- this.logicalDisabled = true;
160
- this.clear();
161
- }
162
- this.parentChangeSubject.subscribe((value) => {
163
- if (value && value.hasOwnProperty(par)) {
164
- setTimeout(() => {
165
- this.logicalDisabled = !value[par];
166
- if (this.logicalDisabled) {
167
- this.clear();
168
- } else {
169
- this.filterOptions();
170
- }
171
- }, 0 );
172
- }
173
- });
174
- }
175
- this.filterOptions();
176
- }
177
- }
178
-
179
- if (this.meta.search) {
180
- const searchParams = this.meta.search.params;
181
- if (searchParams) {
182
- for (const par of Object.keys(searchParams)) {
183
- const parValue = this.parent[searchParams[par]];
184
- if (parValue) {
185
- const params = {};
186
- params[par] = parValue;
187
- this.searchOptions(params);
188
- }
189
- this.parentChangeSubject.subscribe((value) => {
190
- if (value?.hasOwnProperty(searchParams[par])) {
191
- if (!this.logicalDisabled) {
192
- this.searchOptions(value);
193
- }
194
- }
195
- });
196
- }
197
- }
198
- }
199
- }
200
-
201
- onActivated(ev) {
202
- // ev.preventDefault();
203
- // ev.stopPropagation();
204
- this.input = ev.srcElement;
205
- if (!this.dropdown) {
206
- this.dropdown = ev.srcElement.parentNode.parentNode.parentNode;
207
- this.searchInput = this.dropdown.querySelector('.vgip-search_input');
208
- }
209
- this.showDropdown();
210
- }
211
-
212
- detectSearchBlock(element) {
213
- return this.elementRef.nativeElement.querySelector('.Vlt-search_wrap').contains(element);
214
- }
215
-
216
- onBlur(ev) {
217
- let internalControl = false;
218
- if (ev.relatedTarget) {
219
-
220
- if (!this.detectSearchBlock(ev.relatedTarget) && !this.elementRef.nativeElement.contains(ev.relatedTarget)) {
221
- this.dismissDropdown();
222
- } else {
223
- internalControl = true;
224
- }
225
- }
226
- if (this.keyListenerActive && !internalControl) {
227
- this.input.removeEventListener('keydown', this.keydown);
228
- if (this.searchInput) {
229
- this.searchInput.removeEventListener('keydown', this.keydown);
230
- }
231
- setTimeout(() => {
232
- if (!this.keyListenerActive) {
233
- document.removeEventListener('click', this.clickout);
234
- }
235
- }, 400);
236
- delete this.keyListenerActive;
237
- }
238
- this.onLeave.emit(ev);
239
- }
240
-
241
- onOptionSelect(ev, option) {
242
- if (ev) {
243
- ev.preventDefault();
244
- ev.stopPropagation();
245
- }
246
- this.focus();
247
- if (this.multiple) {
248
- if (!this.model) {
249
- this.model = [];
250
- }
251
- const optionIndex = this.model.indexOf(option);
252
- if (optionIndex === -1) {
253
- this.model.push(option);
254
- } else {
255
- this.model.splice(optionIndex, 1);
256
- if (!this.model.length) {
257
- delete this.model;
258
- }
259
- }
260
- this.onModelChange(this.model);
261
- if (this.model) {
262
- this.showText = (this.model || []).map((o) => o.label || o).join(', ');
263
- } else {
264
- delete this.showText;
265
- }
266
- } else {
267
- this.dismissDropdown();
268
- if (typeof option !== 'undefined') {
269
- this.model = option;
270
- this.onModelChange(option);
271
- this.showText = option.label || (option.id === '' ? '--empty--' : option);
272
- if (typeof (option) === 'object' && !option.id && option.id !== '') {
273
- delete this.showText;
274
- }
275
- }
276
- }
277
- }
278
-
279
- clear(ev?) {
280
- delete this.model;
281
- this.onModelChange(this.model);
282
- delete this.showText;
283
- if (ev) {
284
- ev.preventDefault();
285
- ev.stopPropagation();
286
- return false;
287
- }
288
- }
289
-
290
- openResource(ev) {
291
- this.dismissDropdown();
292
- if (this.model && typeof(this.meta.reference.updatable) === 'function') {
293
- return this.meta.reference.updatable(this);
294
- } else if (typeof(this.meta.reference.creatable) === 'function') {
295
- return this.meta.reference.creatable(this);
296
- }
297
- const refDialogComponent = this.viewContainerRef.createComponent(MetaRefDialog);
298
- let theme = this.elementRef.nativeElement.dataset.theme;
299
- if (!theme || theme === 'inherit') {
300
- let parentComponent = this.elementRef.nativeElement.closest('vgip-meta-layout');
301
- if (parentComponent) {
302
- theme = parentComponent.dataset.theme;
303
- }
304
- if (!theme || theme === 'inherit') {
305
- parentComponent = this.elementRef.nativeElement.closest('vgip-meta-resource');
306
- if (parentComponent) {
307
- theme = parentComponent.dataset.theme;
308
- }
309
- }
310
- }
311
- this.referenceService.openDialog(
312
- refDialogComponent, this.metaResource, this.integrationCode, this.meta.reference, null, false, null, theme, this.overlayContainer
313
- ).subscribe((result: any) => {
314
- if (result) {
315
- const existingOptions = (this.meta.options || []).find((o) => (o.id === result.id && o.type === result.type));
316
- if (existingOptions) {
317
- existingOptions.label = result.label;
318
- } else {
319
- if (!this.meta.options) {
320
- this.meta.options = [];
321
- }
322
- this.meta.options.unshift(result);
323
- }
324
- this.onOptionSelect(ev, result);
325
- }
326
- });
327
- }
328
-
329
- showDropdown(updateActiveSuggestionIndex = true) {
330
- this.dropdown.classList.add('Vlt-dropdown--expanded');
331
- if (!this.keyListenerActive) {
332
- if (this.searchInput) {
333
- this.searchInput.focus(); // Focus directly on search input first visit
334
- this.searchInput.addEventListener('keydown', this.keydown);
335
- }
336
- this.input.addEventListener('keydown', this.keydown);
337
- setTimeout(() => {
338
- document.addEventListener('click', this.clickout);
339
- }, 200);
340
- this.keyListenerActive = true;
341
- }
342
- if (updateActiveSuggestionIndex && this.options && this.model) {
343
- for (let suggestionIndex = 0; suggestionIndex < this.options.length; suggestionIndex++) {
344
- if (this.model === this.options[suggestionIndex]) {
345
- this.activeSuggestionIndex = suggestionIndex;
346
- break;
347
- }
348
- }
349
- }
350
- this.ensureDropdownIsVisible();
351
- }
352
-
353
- dismissDropdown(event?) {
354
- if (event) {
355
- this.focus();
356
- }
357
- if (this.dropdown) {
358
- this.dropdown.classList.remove('Vlt-dropdown--expanded');
359
- }
360
- if (this.searchInput) {
361
- this.clearSearchField();
362
- }
363
- delete this.activeSuggestionIndex;
364
- }
365
-
366
- onSearchChange() {
367
- const search = new RegExp(this.searchInputText, 'gi');
368
- if (this.searchInputText === '') {
369
- this.filteredOptions = [...this.optionsBackup];
370
- } else {
371
- this.filteredOptions = this.optionsBackup.filter(option => (option.label || option.id || option.name || option).match(search));
372
- }
373
- }
374
-
375
- clearSearchField(ev?) {
376
- this.searchInputText = '';
377
- this.onSearchChange();
378
- if (ev) {
379
- ev.preventDefault();
380
- ev.stopPropagation();
381
- return false;
382
- }
383
- }
384
-
385
- private ensureDropdownIsVisible() {
386
- setTimeout(() => {
387
- const holder = this.dropdown.closest('.Vlt-card__content, .Vlt-modal__content');
388
- if (holder) {
389
- const el = this.elementRef.nativeElement.querySelector('.Vlt-dropdown__panel');
390
- const elRect = el.getBoundingClientRect();
391
- const holderRect = holder.getBoundingClientRect();
392
- if (holderRect.top + holderRect.height < elRect.top + elRect.height) {
393
- el.scrollIntoView({ block: 'end' });
394
- }
395
- }
396
- }, 400);
397
- }
398
-
399
- private ensureDropdownOptionIsVisible() {
400
- if (!this.dropdownScrollContainer) {
401
- this.dropdownScrollContainer = this.dropdown.querySelector('.Vlt-dropdown__scroll');
402
- }
403
- if (this.dropdownScrollContainer && typeof (this.activeSuggestionIndex) === 'number') {
404
- const scrollTop = 44 * this.activeSuggestionIndex;
405
- const scrollBottom = 44 * (this.activeSuggestionIndex - 7);
406
- if (scrollTop < this.dropdownScrollContainer.scrollTop) {
407
- this.dropdownScrollContainer.scrollTop = scrollTop;
408
- } else if (scrollBottom > this.dropdownScrollContainer.scrollTop) {
409
- this.dropdownScrollContainer.scrollTop = scrollBottom;
410
- }
411
- }
412
- }
413
-
414
- private filterOptions() {
415
- console.log('filterOptions')
416
- this.asyncOptions = [];
417
- if (!this.logicalDisabled) {
418
- for (const o of this.meta.options) {
419
- if (o.for) {
420
- for (const par of Object.keys(o.for)) {
421
- const parValue = this.parent[par];
422
- if (o.for[par].indexOf(parValue) !== -1) {
423
- this.asyncOptions.push(o);
424
- }
425
- }
426
- } else {
427
- this.asyncOptions.push(o);
428
- }
429
- }
430
- }
431
- if (this.model) {
432
- // replace current selections with valid ones from the new options list (support duplicate id)
433
- if (this.multiple) {
434
- const validSelections = [];
435
- for (let i = this.model.length - 1; i >= 0; i--) {
436
- const applicable = this.asyncOptions.find((o) => o.id === this.model[i].id);
437
- if (applicable) {
438
- validSelections.push(applicable);
439
- }
440
- }
441
- this.model = validSelections;
442
- if (this.model) {
443
- this.showText = (this.model || []).map((o) => o.label || o).join(', ');
444
- } else {
445
- delete this.showText;
446
- }
447
- } else {
448
- this.model = this.asyncOptions.find((m) => m.id === this.model.id);
449
- }
450
- this.onModelChange(this.model);
451
- }
452
- }
453
-
454
- private clickout = (event) => {
455
- if (
456
- event.target.className === 'Vlt-dropdown__link' && this.elementRef.nativeElement.contains(event.target)
457
- ) {
458
- this.focus();
459
- } else if (
460
- event.target !== this.input &&
461
- !event.target.classList.contains('Vlt-dropdown__block') &&
462
- !this.detectSearchBlock(event.target)
463
- ) {
464
- this.dismissDropdown();
465
- } else if (this.detectSearchBlock(event.target)) {
466
- event.target.focus();
467
- } else {
468
- this.focus();
469
- }
470
- };
471
-
472
- private keydown = (event) => {
473
- switch (event.key) {
474
- case 'ArrowDown': {
475
- this.showDropdown(false);
476
- if (typeof (this.activeSuggestionIndex) === 'undefined') {
477
- this.activeSuggestionIndex = 0;
478
- } else {
479
- this.activeSuggestionIndex++;
480
- if (this.activeSuggestionIndex >= this.options.length) {
481
- this.activeSuggestionIndex = 0;
482
- }
483
- }
484
- this.ensureDropdownOptionIsVisible();
485
- event.preventDefault();
486
- event.stopPropagation();
487
- break;
488
- }
489
- case 'ArrowUp': {
490
- this.showDropdown(false);
491
- if (typeof (this.activeSuggestionIndex) === 'undefined') {
492
- this.activeSuggestionIndex = this.options.length - 1;
493
- } else {
494
- this.activeSuggestionIndex--;
495
- if (this.activeSuggestionIndex < 0) {
496
- this.activeSuggestionIndex = this.options.length - 1;
497
- }
498
- }
499
- this.ensureDropdownOptionIsVisible();
500
- event.preventDefault();
501
- event.stopPropagation();
502
- break;
503
- }
504
- case 'Enter':
505
- case 'Space':
506
- case ' ': {
507
- if (typeof (this.activeSuggestionIndex) !== 'undefined') {
508
- event.preventDefault();
509
- event.stopPropagation();
510
- this.onOptionSelect(event, this.options[this.activeSuggestionIndex]);
511
- if (!this.multiple) {
512
- delete this.activeSuggestionIndex;
513
- }
514
- }
515
- break;
516
- }
517
- case 'Escape': {
518
- event.preventDefault();
519
- event.stopPropagation();
520
- this.dismissDropdown();
521
- break;
522
- }
523
- case 'Backspace': {
524
- if (!this.dropdown.classList.contains('Vlt-dropdown--expanded')) {
525
- event.preventDefault();
526
- event.stopPropagation();
527
- this.clear();
528
- }
529
- break;
530
- }
531
- }
532
- };
533
-
534
- private searchOptions(params?) { // eslint-disable-line @typescript-eslint/no-unused-vars
535
- let searchUrl = `/fields/${this.meta.name}/search`;
536
- if (this.meta.search) {
537
- const searchParams = this.meta.search.params;
538
- if (this.meta.search.url) {
539
- searchUrl = this.meta.search.url.replace(/\${\s*([\w.]+)\s*}/g, (match, key) => {
540
- if (searchParams.hasOwnProperty(key)) {
541
- const props = searchParams[key].split('.');
542
- const field = props[0];
543
- const prop = props[1];
544
- delete searchParams[key]; // if it is URL param, remove it as query param
545
- let parValue = this.parent[field];
546
- if (parValue) {
547
- if (prop) {
548
- parValue = parValue[prop];
549
- }
550
- if (parValue) {
551
- return parValue;
552
- }
553
- }
554
- }
555
- return 'undefined';
556
- });
557
- }
558
- if (searchParams) {
559
- for (const par of Object.keys(searchParams)) {
560
- const val = this.parent[searchParams[par]];
561
- if (val) {
562
- searchUrl += `${searchUrl.indexOf('?') === -1 ? '?' : '&'}${par}=${val.id || val}`;
563
- }
564
- }
565
- }
566
- }
567
- this.searching = true;
568
- this.resourceService.getByPath(searchUrl).subscribe((options) => {
569
- this.asyncOptions = options;
570
- let validValue = false;
571
- const value = this.value || this.desiredValue;
572
- if (this.multiple) {
573
- if (value) {
574
- const values = value instanceof Array ? value : (value || "").split(";");
575
- validValue = values.some(
576
- (v) =>
577
- options.find(
578
- (o) => (v.id || v) === (o.id || o.value || o.name || 0)
579
- ) !== undefined
580
- );
581
- }
582
- } else {
583
- if (value) {
584
- validValue = options.find((o) => (o.id || o) === (value.id || value)) !== undefined;
585
- }
586
- }
587
-
588
- if (!validValue) {
589
- this.clear();
590
- } else {
591
- this.parent[this.meta.name] = value;
592
- }
593
- delete this.searching;
594
- });
595
- }
596
-
597
- }