@ngrdt/forms 0.0.18
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 +7 -0
- package/fesm2022/ngrdt-forms.mjs +1116 -0
- package/fesm2022/ngrdt-forms.mjs.map +1 -0
- package/index.d.ts +460 -0
- package/package.json +28 -0
|
@@ -0,0 +1,1116 @@
|
|
|
1
|
+
import * as i0 from '@angular/core';
|
|
2
|
+
import { inject, Injector, signal, input, model, linkedSignal, booleanAttribute, computed, effect, untracked, Directive, numberAttribute, InjectionToken, ElementRef } from '@angular/core';
|
|
3
|
+
import { takeUntilDestroyed, toSignal, toObservable } from '@angular/core/rxjs-interop';
|
|
4
|
+
import { NgControl, Validators, FormControl } from '@angular/forms';
|
|
5
|
+
import { RdtInteractiveElementComponent } from '@ngrdt/core';
|
|
6
|
+
import { RdtFileUtils } from '@ngrdt/utils';
|
|
7
|
+
import { take, map, forkJoin, of, from, switchMap, debounceTime, distinctUntilChanged } from 'rxjs';
|
|
8
|
+
import { signalStore, withState, withHooks, withComputed, withMethods, patchState } from '@ngrx/signals';
|
|
9
|
+
|
|
10
|
+
const noop = () => { };
|
|
11
|
+
class RdtBaseFormInputComponent extends RdtInteractiveElementComponent {
|
|
12
|
+
injector = inject(Injector);
|
|
13
|
+
_control = signal(null, ...(ngDevMode ? [{ debugName: "_control" }] : []));
|
|
14
|
+
control = this._control.asReadonly();
|
|
15
|
+
label = input('', ...(ngDevMode ? [{ debugName: "label" }] : []));
|
|
16
|
+
placeholder = input('', ...(ngDevMode ? [{ debugName: "placeholder" }] : []));
|
|
17
|
+
externalValue = model(null, ...(ngDevMode ? [{ debugName: "externalValue", alias: 'value' }] : [{ alias: 'value' }]));
|
|
18
|
+
internalValue = linkedSignal(() => this.toInternalValue(this.externalValue()));
|
|
19
|
+
dataTestIdInput = input(undefined, ...(ngDevMode ? [{ debugName: "dataTestIdInput", alias: 'dataTestId' }] : [{ alias: 'dataTestId' }]));
|
|
20
|
+
dataTestId = linkedSignal(() => this.dataTestIdInput() ?? this.label() ?? '');
|
|
21
|
+
readonlyInput = input(null, ...(ngDevMode ? [{ debugName: "readonlyInput", alias: 'readonly',
|
|
22
|
+
transform: booleanAttribute }] : [{
|
|
23
|
+
alias: 'readonly',
|
|
24
|
+
transform: booleanAttribute,
|
|
25
|
+
}]));
|
|
26
|
+
requiredInput = input(null, ...(ngDevMode ? [{ debugName: "requiredInput", alias: 'required',
|
|
27
|
+
transform: booleanAttribute }] : [{
|
|
28
|
+
alias: 'required',
|
|
29
|
+
transform: booleanAttribute,
|
|
30
|
+
}]));
|
|
31
|
+
requiredFromControl = signal(false, ...(ngDevMode ? [{ debugName: "requiredFromControl" }] : []));
|
|
32
|
+
required = linkedSignal(() => {
|
|
33
|
+
return this.requiredInput() ?? this.requiredFromControl() ?? false;
|
|
34
|
+
});
|
|
35
|
+
touchedInternal = signal(false, ...(ngDevMode ? [{ debugName: "touchedInternal" }] : []));
|
|
36
|
+
touched = computed(() => {
|
|
37
|
+
const control = this.control();
|
|
38
|
+
if (control) {
|
|
39
|
+
return control.touchedReactive();
|
|
40
|
+
}
|
|
41
|
+
else {
|
|
42
|
+
return this.touchedInternal();
|
|
43
|
+
}
|
|
44
|
+
}, ...(ngDevMode ? [{ debugName: "touched" }] : []));
|
|
45
|
+
invalid = computed(() => {
|
|
46
|
+
if (this.requiredInput() && this.isEmpty(this.externalValue())) {
|
|
47
|
+
return true;
|
|
48
|
+
}
|
|
49
|
+
const control = this.control();
|
|
50
|
+
if (control) {
|
|
51
|
+
return control.statusReactive() === 'INVALID';
|
|
52
|
+
}
|
|
53
|
+
else {
|
|
54
|
+
return false;
|
|
55
|
+
}
|
|
56
|
+
}, ...(ngDevMode ? [{ debugName: "invalid" }] : []));
|
|
57
|
+
requiredEffect = effect(() => {
|
|
58
|
+
this.requiredInput();
|
|
59
|
+
this.onValidatorChange();
|
|
60
|
+
}, ...(ngDevMode ? [{ debugName: "requiredEffect" }] : []));
|
|
61
|
+
requiredError = computed(() => this.getRequiredError(this.externalValue()), ...(ngDevMode ? [{ debugName: "requiredError" }] : []));
|
|
62
|
+
controlErrors = computed(() => {
|
|
63
|
+
const control = this.control();
|
|
64
|
+
if (control) {
|
|
65
|
+
control.statusReactive();
|
|
66
|
+
return control.errors;
|
|
67
|
+
}
|
|
68
|
+
else {
|
|
69
|
+
return null;
|
|
70
|
+
}
|
|
71
|
+
}, ...(ngDevMode ? [{ debugName: "controlErrors" }] : []));
|
|
72
|
+
errors = computed(() => this.controlErrors() ?? this.requiredError(), ...(ngDevMode ? [{ debugName: "errors" }] : []));
|
|
73
|
+
visibleErrors = computed(() => this.invalid() && this.touched() ? this.errors() : null, ...(ngDevMode ? [{ debugName: "visibleErrors" }] : []));
|
|
74
|
+
get ngControl() {
|
|
75
|
+
return this._ngControl;
|
|
76
|
+
}
|
|
77
|
+
_ngControl = null;
|
|
78
|
+
_onChange = noop;
|
|
79
|
+
_onTouch = noop;
|
|
80
|
+
_onValidatorChange = noop;
|
|
81
|
+
get onChange() {
|
|
82
|
+
return this._onChange;
|
|
83
|
+
}
|
|
84
|
+
get onTouch() {
|
|
85
|
+
return this._onTouch;
|
|
86
|
+
}
|
|
87
|
+
get onValidatorChange() {
|
|
88
|
+
return this._onValidatorChange;
|
|
89
|
+
}
|
|
90
|
+
ngOnInit() {
|
|
91
|
+
this._ngControl = this.injector.get(NgControl, null, {
|
|
92
|
+
self: true,
|
|
93
|
+
optional: true,
|
|
94
|
+
});
|
|
95
|
+
const control = this.ngControl?.control;
|
|
96
|
+
this._control.set(control ?? null);
|
|
97
|
+
if (control) {
|
|
98
|
+
control.events.pipe(takeUntilDestroyed(this.destroyRef)).subscribe(() => {
|
|
99
|
+
this.requiredFromControl.set(control.hasValidator(Validators.required));
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
ngOnDestroy() {
|
|
104
|
+
const control = this.control();
|
|
105
|
+
if (this.requiredInput() && control) {
|
|
106
|
+
control.removeValidators(Validators.required);
|
|
107
|
+
control.setErrors(null);
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
registerOnChange(fn) {
|
|
111
|
+
this._onChange = fn;
|
|
112
|
+
}
|
|
113
|
+
registerOnTouched(fn) {
|
|
114
|
+
this._onTouch = () => {
|
|
115
|
+
this.touchedInternal.set(true);
|
|
116
|
+
fn();
|
|
117
|
+
};
|
|
118
|
+
}
|
|
119
|
+
// eslint-disable-next-line @typescript-eslint/no-empty-function
|
|
120
|
+
writeValue(value) {
|
|
121
|
+
this.externalValue.set(value);
|
|
122
|
+
}
|
|
123
|
+
// Implemented as a part of Validator.
|
|
124
|
+
validate(control) {
|
|
125
|
+
return this.requiredError();
|
|
126
|
+
}
|
|
127
|
+
registerOnValidatorChange(fn) {
|
|
128
|
+
this._onValidatorChange = fn;
|
|
129
|
+
}
|
|
130
|
+
onInternalValueChange(value) {
|
|
131
|
+
if (value === '') {
|
|
132
|
+
value = null; // Convert empty string to null
|
|
133
|
+
}
|
|
134
|
+
if (value !== untracked(this.internalValue)) {
|
|
135
|
+
const externalValue = this.toExternalValue(value);
|
|
136
|
+
this.externalValue.set(externalValue);
|
|
137
|
+
this.onChange(externalValue);
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
toExternalValue(internalValue) {
|
|
141
|
+
return internalValue;
|
|
142
|
+
}
|
|
143
|
+
toInternalValue(externalValue) {
|
|
144
|
+
return externalValue;
|
|
145
|
+
}
|
|
146
|
+
onBlur() {
|
|
147
|
+
super.onBlur();
|
|
148
|
+
Promise.resolve().then(() => {
|
|
149
|
+
this.onTouch();
|
|
150
|
+
this.cd.markForCheck();
|
|
151
|
+
});
|
|
152
|
+
}
|
|
153
|
+
getRequiredError(value) {
|
|
154
|
+
return this.required() && this.isEmpty(value)
|
|
155
|
+
? RdtBaseFormInputComponent.REQUIRED_ERROR
|
|
156
|
+
: null;
|
|
157
|
+
}
|
|
158
|
+
static REQUIRED_ERROR = { required: true };
|
|
159
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.7", ngImport: i0, type: RdtBaseFormInputComponent, deps: null, target: i0.ɵɵFactoryTarget.Directive });
|
|
160
|
+
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "20.1.7", type: RdtBaseFormInputComponent, isStandalone: true, inputs: { label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, externalValue: { classPropertyName: "externalValue", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, dataTestIdInput: { classPropertyName: "dataTestIdInput", publicName: "dataTestId", isSignal: true, isRequired: false, transformFunction: null }, readonlyInput: { classPropertyName: "readonlyInput", publicName: "readonly", isSignal: true, isRequired: false, transformFunction: null }, requiredInput: { classPropertyName: "requiredInput", publicName: "required", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { externalValue: "valueChange" }, usesInheritance: true, ngImport: i0 });
|
|
161
|
+
}
|
|
162
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.7", ngImport: i0, type: RdtBaseFormInputComponent, decorators: [{
|
|
163
|
+
type: Directive,
|
|
164
|
+
args: [{
|
|
165
|
+
standalone: true,
|
|
166
|
+
}]
|
|
167
|
+
}] });
|
|
168
|
+
|
|
169
|
+
class RdtCheckboxComponent extends RdtBaseFormInputComponent {
|
|
170
|
+
trueValueInput = input(true, ...(ngDevMode ? [{ debugName: "trueValueInput", alias: 'trueValue' }] : [{
|
|
171
|
+
alias: 'trueValue',
|
|
172
|
+
}]));
|
|
173
|
+
trueValue = linkedSignal(() => this.trueValueInput());
|
|
174
|
+
falseValueInput = input(false, ...(ngDevMode ? [{ debugName: "falseValueInput", alias: 'falseValue' }] : [{
|
|
175
|
+
alias: 'falseValue',
|
|
176
|
+
}]));
|
|
177
|
+
falseValue = linkedSignal(() => this.falseValueInput());
|
|
178
|
+
indeterminate = input(false, ...(ngDevMode ? [{ debugName: "indeterminate", transform: booleanAttribute }] : [{ transform: booleanAttribute }]));
|
|
179
|
+
toExternalValue(internalValue) {
|
|
180
|
+
switch (internalValue) {
|
|
181
|
+
case true:
|
|
182
|
+
return this.trueValue();
|
|
183
|
+
case false:
|
|
184
|
+
return this.falseValue();
|
|
185
|
+
default:
|
|
186
|
+
return null;
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
toInternalValue(externalValue) {
|
|
190
|
+
switch (externalValue) {
|
|
191
|
+
case this.trueValue():
|
|
192
|
+
return true;
|
|
193
|
+
case this.falseValue():
|
|
194
|
+
return false;
|
|
195
|
+
default:
|
|
196
|
+
return null;
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
isEmpty(value) {
|
|
200
|
+
return value === null;
|
|
201
|
+
}
|
|
202
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.7", ngImport: i0, type: RdtCheckboxComponent, deps: null, target: i0.ɵɵFactoryTarget.Directive });
|
|
203
|
+
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "20.1.7", type: RdtCheckboxComponent, isStandalone: true, inputs: { trueValueInput: { classPropertyName: "trueValueInput", publicName: "trueValue", isSignal: true, isRequired: false, transformFunction: null }, falseValueInput: { classPropertyName: "falseValueInput", publicName: "falseValue", isSignal: true, isRequired: false, transformFunction: null }, indeterminate: { classPropertyName: "indeterminate", publicName: "indeterminate", isSignal: true, isRequired: false, transformFunction: null } }, usesInheritance: true, ngImport: i0 });
|
|
204
|
+
}
|
|
205
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.7", ngImport: i0, type: RdtCheckboxComponent, decorators: [{
|
|
206
|
+
type: Directive
|
|
207
|
+
}] });
|
|
208
|
+
|
|
209
|
+
function nullToUndefined(value) {
|
|
210
|
+
return value === null ? undefined : value;
|
|
211
|
+
}
|
|
212
|
+
function nullToUndefinedNumeric(value) {
|
|
213
|
+
return numberAttribute(value, undefined);
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
class RdtDateComponent extends RdtBaseFormInputComponent {
|
|
217
|
+
type = input('date', ...(ngDevMode ? [{ debugName: "type" }] : []));
|
|
218
|
+
minInput = input(undefined, ...(ngDevMode ? [{ debugName: "minInput", transform: nullToUndefined }] : [{
|
|
219
|
+
transform: nullToUndefined,
|
|
220
|
+
}]));
|
|
221
|
+
min = linkedSignal(() => {
|
|
222
|
+
const minInput = this.minInput();
|
|
223
|
+
return minInput ? this.toInternalValue(minInput) : null;
|
|
224
|
+
});
|
|
225
|
+
maxInput = input(undefined, ...(ngDevMode ? [{ debugName: "maxInput", transform: nullToUndefined }] : [{
|
|
226
|
+
transform: nullToUndefined,
|
|
227
|
+
}]));
|
|
228
|
+
max = linkedSignal(() => {
|
|
229
|
+
const maxInput = this.maxInput();
|
|
230
|
+
return maxInput ? this.toInternalValue(maxInput) : null;
|
|
231
|
+
});
|
|
232
|
+
isEmpty(value) {
|
|
233
|
+
return value === null;
|
|
234
|
+
}
|
|
235
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.7", ngImport: i0, type: RdtDateComponent, deps: null, target: i0.ɵɵFactoryTarget.Directive });
|
|
236
|
+
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "20.1.7", type: RdtDateComponent, isStandalone: true, inputs: { type: { classPropertyName: "type", publicName: "type", isSignal: true, isRequired: false, transformFunction: null }, minInput: { classPropertyName: "minInput", publicName: "minInput", isSignal: true, isRequired: false, transformFunction: null }, maxInput: { classPropertyName: "maxInput", publicName: "maxInput", isSignal: true, isRequired: false, transformFunction: null } }, usesInheritance: true, ngImport: i0 });
|
|
237
|
+
}
|
|
238
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.7", ngImport: i0, type: RdtDateComponent, decorators: [{
|
|
239
|
+
type: Directive
|
|
240
|
+
}] });
|
|
241
|
+
|
|
242
|
+
class RdtFileReader {
|
|
243
|
+
read(file) {
|
|
244
|
+
return this.extractData(file).pipe(take(1), map((content) => ({
|
|
245
|
+
fileName: file.name,
|
|
246
|
+
content,
|
|
247
|
+
size: file.size,
|
|
248
|
+
mimeType: file.type ?? undefined,
|
|
249
|
+
modified: isNaN(file.lastModified)
|
|
250
|
+
? undefined
|
|
251
|
+
: new Date(file.lastModified),
|
|
252
|
+
originalFile: file,
|
|
253
|
+
})));
|
|
254
|
+
}
|
|
255
|
+
readAll(files) {
|
|
256
|
+
return forkJoin(files.map((file) => this.read(file)));
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
class NoOpFileReader extends RdtFileReader {
|
|
261
|
+
extractData() {
|
|
262
|
+
return of(undefined);
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
const NO_OP_FILE_READER = new NoOpFileReader();
|
|
266
|
+
|
|
267
|
+
class RdtFileReaderBase64 extends RdtFileReader {
|
|
268
|
+
removeDataPrefix;
|
|
269
|
+
constructor(removeDataPrefix = false) {
|
|
270
|
+
super();
|
|
271
|
+
this.removeDataPrefix = removeDataPrefix;
|
|
272
|
+
}
|
|
273
|
+
extractData(file) {
|
|
274
|
+
let promise = RdtFileUtils.blobToDataUrl(file);
|
|
275
|
+
if (this.removeDataPrefix) {
|
|
276
|
+
promise = promise.then((dataUrl) => dataUrl.substring(dataUrl.indexOf(',') + 1));
|
|
277
|
+
}
|
|
278
|
+
return from(promise);
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
const RDT_DEFAULT_FILE_READER = new InjectionToken('RDT_DEFAULT_FILE_READER', {
|
|
283
|
+
factory: () => new RdtFileReaderBase64(),
|
|
284
|
+
providedIn: 'root',
|
|
285
|
+
});
|
|
286
|
+
|
|
287
|
+
function czechFileLabelFn(files) {
|
|
288
|
+
switch (files.length) {
|
|
289
|
+
case 0:
|
|
290
|
+
return 'Vyberte soubor';
|
|
291
|
+
case 1:
|
|
292
|
+
return files[0].fileName;
|
|
293
|
+
case 2:
|
|
294
|
+
case 3:
|
|
295
|
+
case 4:
|
|
296
|
+
return `Vybrány ${files.length} soubory`;
|
|
297
|
+
default:
|
|
298
|
+
return `Vybráno ${files.length} souborů`;
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
const RDT_DEFAULT_FILE_LABEL_FN = new InjectionToken('RDT_DEFAULT_FILE_LABEL_FN', {
|
|
302
|
+
providedIn: 'root',
|
|
303
|
+
factory: () => czechFileLabelFn,
|
|
304
|
+
});
|
|
305
|
+
|
|
306
|
+
const RDT_DEFAULT_MAX_FILE_SIZE = new InjectionToken('RDT_DEFAULT_MAX_FILE_SIZE', {
|
|
307
|
+
factory: () => '100 MB',
|
|
308
|
+
providedIn: 'root',
|
|
309
|
+
});
|
|
310
|
+
|
|
311
|
+
class RdtFileInputComponent extends RdtBaseFormInputComponent {
|
|
312
|
+
defaultFileReader = inject(RDT_DEFAULT_FILE_READER);
|
|
313
|
+
defaultMaxFileSize = inject(RDT_DEFAULT_MAX_FILE_SIZE);
|
|
314
|
+
defaultLabelFn = inject(RDT_DEFAULT_FILE_LABEL_FN);
|
|
315
|
+
readerInput = input(this.defaultFileReader, ...(ngDevMode ? [{ debugName: "readerInput", alias: 'reader' }] : [{
|
|
316
|
+
alias: 'reader',
|
|
317
|
+
}]));
|
|
318
|
+
reader = linkedSignal(() => this.readerInput());
|
|
319
|
+
acceptInput = input(undefined, ...(ngDevMode ? [{ debugName: "acceptInput", alias: 'accept', transform: nullToUndefined }] : [{ alias: 'accept', transform: nullToUndefined }]));
|
|
320
|
+
accept = linkedSignal(() => {
|
|
321
|
+
const acceptInput = this.acceptInput();
|
|
322
|
+
return !acceptInput || Array.isArray(acceptInput)
|
|
323
|
+
? acceptInput
|
|
324
|
+
: [acceptInput];
|
|
325
|
+
});
|
|
326
|
+
jointAccept = computed(() => this.accept()?.join(','), ...(ngDevMode ? [{ debugName: "jointAccept" }] : []));
|
|
327
|
+
maxFileSizeInput = input(this.defaultMaxFileSize, ...(ngDevMode ? [{ debugName: "maxFileSizeInput", alias: 'maxFileSize',
|
|
328
|
+
transform: nullToUndefined }] : [{
|
|
329
|
+
alias: 'maxFileSize',
|
|
330
|
+
transform: nullToUndefined,
|
|
331
|
+
}]));
|
|
332
|
+
maxFileSize = linkedSignal(() => this.maxFileSizeInput());
|
|
333
|
+
maxFileSizeInBytes = computed(() => {
|
|
334
|
+
const maxFileSize = this.maxFileSize();
|
|
335
|
+
return maxFileSize ? RdtFileUtils.fileSizeToBytes(maxFileSize) : null;
|
|
336
|
+
}, ...(ngDevMode ? [{ debugName: "maxFileSizeInBytes" }] : []));
|
|
337
|
+
labelFn = input(this.defaultLabelFn, ...(ngDevMode ? [{ debugName: "labelFn" }] : []));
|
|
338
|
+
multiple = input(false, ...(ngDevMode ? [{ debugName: "multiple", transform: booleanAttribute }] : [{ transform: booleanAttribute }]));
|
|
339
|
+
labelCtrl = new FormControl(null);
|
|
340
|
+
labelDataTestId = computed(() => this.dataTestId() + '-label', ...(ngDevMode ? [{ debugName: "labelDataTestId" }] : []));
|
|
341
|
+
touchedEffect = effect(() => {
|
|
342
|
+
const touched = this.touched();
|
|
343
|
+
if (touched) {
|
|
344
|
+
this.labelCtrl.markAsTouched();
|
|
345
|
+
}
|
|
346
|
+
else {
|
|
347
|
+
this.labelCtrl.markAsUntouched();
|
|
348
|
+
}
|
|
349
|
+
}, ...(ngDevMode ? [{ debugName: "touchedEffect" }] : []));
|
|
350
|
+
errorEffect = effect(() => {
|
|
351
|
+
this.labelCtrl?.setErrors(this.visibleErrors());
|
|
352
|
+
}, ...(ngDevMode ? [{ debugName: "errorEffect" }] : []));
|
|
353
|
+
ngOnInit() {
|
|
354
|
+
super.ngOnInit();
|
|
355
|
+
this.control()?.addValidators(this._maxFileSizeValidator);
|
|
356
|
+
}
|
|
357
|
+
ngOnDestroy() {
|
|
358
|
+
super.ngOnDestroy();
|
|
359
|
+
this.control()?.removeValidators(this._maxFileSizeValidator);
|
|
360
|
+
}
|
|
361
|
+
onFileSelected(event) {
|
|
362
|
+
const target = event.target;
|
|
363
|
+
if (!target.files) {
|
|
364
|
+
return;
|
|
365
|
+
}
|
|
366
|
+
let shouldRead = true;
|
|
367
|
+
const maxBytes = this.maxFileSizeInBytes();
|
|
368
|
+
if (maxBytes !== null) {
|
|
369
|
+
const files = Array.from(target.files);
|
|
370
|
+
for (const file of files) {
|
|
371
|
+
if (file.size > maxBytes) {
|
|
372
|
+
shouldRead = false;
|
|
373
|
+
break;
|
|
374
|
+
}
|
|
375
|
+
}
|
|
376
|
+
}
|
|
377
|
+
const reader = shouldRead
|
|
378
|
+
? this.reader()
|
|
379
|
+
: NO_OP_FILE_READER;
|
|
380
|
+
reader
|
|
381
|
+
.readAll(Array.from(target.files))
|
|
382
|
+
.pipe(takeUntilDestroyed(this.destroyRef))
|
|
383
|
+
.subscribe((files) => {
|
|
384
|
+
console.log(files);
|
|
385
|
+
this.onChange(files);
|
|
386
|
+
this.writeValue(files);
|
|
387
|
+
});
|
|
388
|
+
}
|
|
389
|
+
writeValue(value) {
|
|
390
|
+
super.writeValue(value);
|
|
391
|
+
this.setInnerValue(value);
|
|
392
|
+
}
|
|
393
|
+
setInnerValue(files) {
|
|
394
|
+
if (this.labelCtrl) {
|
|
395
|
+
const label = this.labelFn()(files ?? []);
|
|
396
|
+
this.labelCtrl.setValue(label);
|
|
397
|
+
}
|
|
398
|
+
}
|
|
399
|
+
clear() {
|
|
400
|
+
this.onInternalValueChange(null);
|
|
401
|
+
}
|
|
402
|
+
_maxFileSizeValidator = (ctrl) => {
|
|
403
|
+
const maxSize = this.maxFileSizeInBytes();
|
|
404
|
+
if (maxSize === null ||
|
|
405
|
+
!Array.isArray(ctrl.value) ||
|
|
406
|
+
ctrl.value.length === 0) {
|
|
407
|
+
return null;
|
|
408
|
+
}
|
|
409
|
+
const files = ctrl.value;
|
|
410
|
+
for (const file of files) {
|
|
411
|
+
if (file['size'] !== undefined && file.size > maxSize) {
|
|
412
|
+
return {
|
|
413
|
+
maxFileSize: {
|
|
414
|
+
max: maxSize,
|
|
415
|
+
actual: file.size,
|
|
416
|
+
},
|
|
417
|
+
};
|
|
418
|
+
}
|
|
419
|
+
}
|
|
420
|
+
return null;
|
|
421
|
+
};
|
|
422
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.7", ngImport: i0, type: RdtFileInputComponent, deps: null, target: i0.ɵɵFactoryTarget.Directive });
|
|
423
|
+
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "20.1.7", type: RdtFileInputComponent, isStandalone: true, inputs: { readerInput: { classPropertyName: "readerInput", publicName: "reader", isSignal: true, isRequired: false, transformFunction: null }, acceptInput: { classPropertyName: "acceptInput", publicName: "accept", isSignal: true, isRequired: false, transformFunction: null }, maxFileSizeInput: { classPropertyName: "maxFileSizeInput", publicName: "maxFileSize", isSignal: true, isRequired: false, transformFunction: null }, labelFn: { classPropertyName: "labelFn", publicName: "labelFn", isSignal: true, isRequired: false, transformFunction: null }, multiple: { classPropertyName: "multiple", publicName: "multiple", isSignal: true, isRequired: false, transformFunction: null } }, usesInheritance: true, ngImport: i0 });
|
|
424
|
+
}
|
|
425
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.7", ngImport: i0, type: RdtFileInputComponent, decorators: [{
|
|
426
|
+
type: Directive
|
|
427
|
+
}] });
|
|
428
|
+
|
|
429
|
+
class RdtFileReaderArrayBuffer extends RdtFileReader {
|
|
430
|
+
extractData(file) {
|
|
431
|
+
return from(RdtFileUtils.fileAsArrayBuffer(file));
|
|
432
|
+
}
|
|
433
|
+
}
|
|
434
|
+
|
|
435
|
+
class VnshFileReaderText extends RdtFileReader {
|
|
436
|
+
encoding;
|
|
437
|
+
constructor(encoding) {
|
|
438
|
+
super();
|
|
439
|
+
this.encoding = encoding;
|
|
440
|
+
}
|
|
441
|
+
extractData(file) {
|
|
442
|
+
return from(RdtFileUtils.fileAsText(file, this.encoding));
|
|
443
|
+
}
|
|
444
|
+
}
|
|
445
|
+
|
|
446
|
+
class RdtNumericInputComponent extends RdtBaseFormInputComponent {
|
|
447
|
+
min = input(undefined, ...(ngDevMode ? [{ debugName: "min", transform: nullToUndefinedNumeric }] : [{
|
|
448
|
+
transform: nullToUndefinedNumeric,
|
|
449
|
+
}]));
|
|
450
|
+
max = input(undefined, ...(ngDevMode ? [{ debugName: "max", transform: nullToUndefinedNumeric }] : [{
|
|
451
|
+
transform: nullToUndefinedNumeric,
|
|
452
|
+
}]));
|
|
453
|
+
step = input(undefined, ...(ngDevMode ? [{ debugName: "step", transform: nullToUndefinedNumeric }] : [{
|
|
454
|
+
transform: nullToUndefinedNumeric,
|
|
455
|
+
}]));
|
|
456
|
+
autocomplete = input(undefined, ...(ngDevMode ? [{ debugName: "autocomplete", transform: nullToUndefined }] : [{
|
|
457
|
+
transform: nullToUndefined,
|
|
458
|
+
}]));
|
|
459
|
+
isEmpty(value) {
|
|
460
|
+
return value === null;
|
|
461
|
+
}
|
|
462
|
+
toExternalValue(internalValue) {
|
|
463
|
+
if (typeof internalValue === 'number') {
|
|
464
|
+
return internalValue;
|
|
465
|
+
}
|
|
466
|
+
else if (internalValue && typeof internalValue === 'string') {
|
|
467
|
+
return parseFloat(internalValue);
|
|
468
|
+
}
|
|
469
|
+
return null;
|
|
470
|
+
}
|
|
471
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.7", ngImport: i0, type: RdtNumericInputComponent, deps: null, target: i0.ɵɵFactoryTarget.Directive });
|
|
472
|
+
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "20.1.7", type: RdtNumericInputComponent, isStandalone: true, inputs: { min: { classPropertyName: "min", publicName: "min", isSignal: true, isRequired: false, transformFunction: null }, max: { classPropertyName: "max", publicName: "max", isSignal: true, isRequired: false, transformFunction: null }, step: { classPropertyName: "step", publicName: "step", isSignal: true, isRequired: false, transformFunction: null }, autocomplete: { classPropertyName: "autocomplete", publicName: "autocomplete", isSignal: true, isRequired: false, transformFunction: null } }, usesInheritance: true, ngImport: i0 });
|
|
473
|
+
}
|
|
474
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.7", ngImport: i0, type: RdtNumericInputComponent, decorators: [{
|
|
475
|
+
type: Directive
|
|
476
|
+
}] });
|
|
477
|
+
|
|
478
|
+
class RdtSelectDatasource {
|
|
479
|
+
}
|
|
480
|
+
|
|
481
|
+
class RdtOfflineSelectDatasource extends RdtSelectDatasource {
|
|
482
|
+
data;
|
|
483
|
+
totalCountKnown = true;
|
|
484
|
+
queryRequired = true;
|
|
485
|
+
preprocessedData;
|
|
486
|
+
constructor(data) {
|
|
487
|
+
super();
|
|
488
|
+
this.data = data;
|
|
489
|
+
this.preprocessedData = this.preprocessData(data);
|
|
490
|
+
}
|
|
491
|
+
getData(params) {
|
|
492
|
+
const page = this.getPage(this.filterData(params.query), params.pageIndex, params.pageSize);
|
|
493
|
+
return of(page);
|
|
494
|
+
}
|
|
495
|
+
getLabel(item) {
|
|
496
|
+
return item.label;
|
|
497
|
+
}
|
|
498
|
+
getId(item) {
|
|
499
|
+
return item.value;
|
|
500
|
+
}
|
|
501
|
+
getItemsByIds(ids) {
|
|
502
|
+
const result = new Map();
|
|
503
|
+
for (const id of ids) {
|
|
504
|
+
const item = this.preprocessedData.find((item) => item.value === id);
|
|
505
|
+
if (item) {
|
|
506
|
+
result.set(id, item);
|
|
507
|
+
}
|
|
508
|
+
}
|
|
509
|
+
return of(result);
|
|
510
|
+
}
|
|
511
|
+
preprocessLabel(label) {
|
|
512
|
+
return label.trim().toLowerCase();
|
|
513
|
+
}
|
|
514
|
+
preprocessData(data) {
|
|
515
|
+
return data.map((item) => ({
|
|
516
|
+
value: item.value,
|
|
517
|
+
label: this.preprocessLabel(item.label),
|
|
518
|
+
}));
|
|
519
|
+
}
|
|
520
|
+
filterData(query) {
|
|
521
|
+
if (!query) {
|
|
522
|
+
return this.preprocessedData;
|
|
523
|
+
}
|
|
524
|
+
const prepQuery = this.preprocessLabel(query);
|
|
525
|
+
if (!prepQuery) {
|
|
526
|
+
return this.preprocessedData;
|
|
527
|
+
}
|
|
528
|
+
return this.preprocessedData.filter((item) => item.label.includes(prepQuery));
|
|
529
|
+
}
|
|
530
|
+
getPage(data, pageIndex, pageSize) {
|
|
531
|
+
if (pageSize < 1) {
|
|
532
|
+
throw new Error('Invalid page size');
|
|
533
|
+
}
|
|
534
|
+
if (pageIndex < 0) {
|
|
535
|
+
throw new Error('Invalid page index');
|
|
536
|
+
}
|
|
537
|
+
if (pageIndex * pageSize > data.length) {
|
|
538
|
+
return {
|
|
539
|
+
data: [],
|
|
540
|
+
totalCount: data.length,
|
|
541
|
+
pageIndex: pageIndex,
|
|
542
|
+
};
|
|
543
|
+
}
|
|
544
|
+
const start = pageIndex * pageSize;
|
|
545
|
+
const end = start + pageSize;
|
|
546
|
+
const items = data.slice(start, end);
|
|
547
|
+
return {
|
|
548
|
+
data: items,
|
|
549
|
+
totalCount: data.length,
|
|
550
|
+
pageIndex: pageIndex,
|
|
551
|
+
};
|
|
552
|
+
}
|
|
553
|
+
}
|
|
554
|
+
|
|
555
|
+
const rdtSelectInitialState = {
|
|
556
|
+
query: null,
|
|
557
|
+
nextPageIndex: 0,
|
|
558
|
+
pageSize: 20,
|
|
559
|
+
totalCount: 0,
|
|
560
|
+
totalCountKnown: false,
|
|
561
|
+
options: [],
|
|
562
|
+
datasource: null,
|
|
563
|
+
selectedMap: new Map(),
|
|
564
|
+
fetchError: null,
|
|
565
|
+
missingValuePlaceholder: 'Načítání...',
|
|
566
|
+
_fetchRequest: null,
|
|
567
|
+
_fetchMissingRequest: null,
|
|
568
|
+
_missingSelected: [],
|
|
569
|
+
};
|
|
570
|
+
|
|
571
|
+
function compareSelectRequestParams(a, b) {
|
|
572
|
+
return (a.query === b.query &&
|
|
573
|
+
a.pageIndex === b.pageIndex &&
|
|
574
|
+
a.pageSize === b.pageSize);
|
|
575
|
+
}
|
|
576
|
+
|
|
577
|
+
function getRdtSelectStore(initialState = rdtSelectInitialState) {
|
|
578
|
+
return signalStore(withState(initialState), withHooks({
|
|
579
|
+
onDestroy(store) {
|
|
580
|
+
store._fetchMissingRequest()?.subscription.unsubscribe();
|
|
581
|
+
store._fetchRequest()?.subscription.unsubscribe();
|
|
582
|
+
},
|
|
583
|
+
}), withComputed((state) => ({
|
|
584
|
+
hasMore: computed(() => state.nextPageIndex !== null),
|
|
585
|
+
selectedItems: computed(() => {
|
|
586
|
+
return Array.from(state.selectedMap().values());
|
|
587
|
+
}),
|
|
588
|
+
loadingOptions: computed(() => state._fetchRequest() !== null),
|
|
589
|
+
loadingMissing: computed(() => state._fetchMissingRequest() !== null),
|
|
590
|
+
loading: computed(() => state._fetchRequest() !== null ||
|
|
591
|
+
state._fetchMissingRequest() !== null),
|
|
592
|
+
// Shows selected + others while query is empty
|
|
593
|
+
// Shows only query results while query has value
|
|
594
|
+
visibleOptions: computed(() => {
|
|
595
|
+
const items = state.options();
|
|
596
|
+
const query = state.query();
|
|
597
|
+
const selectedMap = state.selectedMap();
|
|
598
|
+
const missing = state._missingSelected();
|
|
599
|
+
if (query || (selectedMap.size === 0 && missing.length === 0)) {
|
|
600
|
+
return items.map((it) => ({
|
|
601
|
+
...it,
|
|
602
|
+
selected: false,
|
|
603
|
+
}));
|
|
604
|
+
}
|
|
605
|
+
const selected = Array.from(selectedMap.values()).map((it) => ({ ...it, selected: true }));
|
|
606
|
+
const missingPlaceholder = state.missingValuePlaceholder();
|
|
607
|
+
const placeholders = missing.map((id) => ({
|
|
608
|
+
id,
|
|
609
|
+
label: missingPlaceholder.replace('{id}', String(id)),
|
|
610
|
+
value: null,
|
|
611
|
+
selected: true,
|
|
612
|
+
}));
|
|
613
|
+
placeholders.forEach((pl) => selected.push(pl));
|
|
614
|
+
items.forEach((item) => {
|
|
615
|
+
if (!selectedMap.has(item.id)) {
|
|
616
|
+
selected.push({ ...item, selected: false });
|
|
617
|
+
}
|
|
618
|
+
});
|
|
619
|
+
return selected;
|
|
620
|
+
}),
|
|
621
|
+
})), withMethods((store) => ({
|
|
622
|
+
fetch() {
|
|
623
|
+
const datasource = untracked(store.datasource);
|
|
624
|
+
const index = untracked(store.nextPageIndex);
|
|
625
|
+
const query = untracked(store.query);
|
|
626
|
+
const pageSize = untracked(store.pageSize);
|
|
627
|
+
if (!datasource || index === null) {
|
|
628
|
+
return;
|
|
629
|
+
}
|
|
630
|
+
const params = {
|
|
631
|
+
query: query,
|
|
632
|
+
pageIndex: index,
|
|
633
|
+
pageSize: pageSize,
|
|
634
|
+
};
|
|
635
|
+
const currentRequest = untracked(store._fetchRequest);
|
|
636
|
+
if (currentRequest) {
|
|
637
|
+
if (compareSelectRequestParams(currentRequest.params, params)) {
|
|
638
|
+
return;
|
|
639
|
+
}
|
|
640
|
+
else {
|
|
641
|
+
currentRequest.subscription.unsubscribe();
|
|
642
|
+
}
|
|
643
|
+
}
|
|
644
|
+
const observer = this._getFetchObserver(params);
|
|
645
|
+
const subscription = datasource.getData(params).subscribe(observer);
|
|
646
|
+
// Offline datasource using `of()` emits value synchronously
|
|
647
|
+
if (!subscription.closed) {
|
|
648
|
+
patchState(store, {
|
|
649
|
+
_fetchRequest: { subscription, params: params },
|
|
650
|
+
});
|
|
651
|
+
}
|
|
652
|
+
},
|
|
653
|
+
_getFetchObserver(requestParams) {
|
|
654
|
+
return {
|
|
655
|
+
next: (page) => this._onFetchSuccess(page, requestParams),
|
|
656
|
+
error: (error) => this._onFetchError(error),
|
|
657
|
+
complete: () => this._onFetchComplete(),
|
|
658
|
+
};
|
|
659
|
+
},
|
|
660
|
+
_onFetchSuccess(page, requestParams) {
|
|
661
|
+
let nextPageIndex = page.pageIndex + 1;
|
|
662
|
+
if (page.totalCount === null) {
|
|
663
|
+
if (page.data.length < requestParams.pageSize) {
|
|
664
|
+
nextPageIndex = null;
|
|
665
|
+
}
|
|
666
|
+
}
|
|
667
|
+
else if (requestParams.pageIndex * requestParams.pageSize + page.data.length >=
|
|
668
|
+
page.totalCount) {
|
|
669
|
+
nextPageIndex = null;
|
|
670
|
+
}
|
|
671
|
+
const options = [
|
|
672
|
+
...untracked(store.options),
|
|
673
|
+
...this._getLabelValueIds(page.data),
|
|
674
|
+
];
|
|
675
|
+
patchState(store, {
|
|
676
|
+
totalCount: page.totalCount ??
|
|
677
|
+
Math.max(untracked(store.totalCount), page.pageIndex * requestParams.pageSize + page.data.length),
|
|
678
|
+
nextPageIndex,
|
|
679
|
+
totalCountKnown: page.totalCount !== null ||
|
|
680
|
+
page.data.length < requestParams.pageSize,
|
|
681
|
+
options,
|
|
682
|
+
_fetchRequest: null,
|
|
683
|
+
});
|
|
684
|
+
this._loadMissingSelected();
|
|
685
|
+
},
|
|
686
|
+
_onFetchError(error) {
|
|
687
|
+
patchState(store, {
|
|
688
|
+
fetchError: getRdtSelectError(error),
|
|
689
|
+
_fetchRequest: null,
|
|
690
|
+
});
|
|
691
|
+
},
|
|
692
|
+
_onFetchComplete() {
|
|
693
|
+
patchState(store, {
|
|
694
|
+
_fetchRequest: null,
|
|
695
|
+
});
|
|
696
|
+
},
|
|
697
|
+
setDatasource(datasource) {
|
|
698
|
+
untracked(store._fetchRequest)?.subscription.unsubscribe();
|
|
699
|
+
patchState(store, {
|
|
700
|
+
datasource,
|
|
701
|
+
_fetchRequest: null,
|
|
702
|
+
fetchError: null,
|
|
703
|
+
totalCountKnown: datasource.totalCountKnown,
|
|
704
|
+
nextPageIndex: 0,
|
|
705
|
+
totalCount: 0,
|
|
706
|
+
options: [],
|
|
707
|
+
});
|
|
708
|
+
if (!datasource.queryRequired) {
|
|
709
|
+
this.fetch();
|
|
710
|
+
}
|
|
711
|
+
else {
|
|
712
|
+
this._loadMissingSelected();
|
|
713
|
+
}
|
|
714
|
+
},
|
|
715
|
+
setQuery(query) {
|
|
716
|
+
const datasource = untracked(store.datasource);
|
|
717
|
+
if (query !== untracked(store.query)) {
|
|
718
|
+
this.reset();
|
|
719
|
+
patchState(store, { query });
|
|
720
|
+
if (query || !datasource?.queryRequired) {
|
|
721
|
+
this.fetch();
|
|
722
|
+
}
|
|
723
|
+
}
|
|
724
|
+
},
|
|
725
|
+
reset() {
|
|
726
|
+
patchState(store, {
|
|
727
|
+
query: null,
|
|
728
|
+
nextPageIndex: 0,
|
|
729
|
+
options: [],
|
|
730
|
+
totalCount: 0,
|
|
731
|
+
totalCountKnown: untracked(store.datasource)?.totalCountKnown ?? true,
|
|
732
|
+
});
|
|
733
|
+
},
|
|
734
|
+
resetTotalCountKnown() {
|
|
735
|
+
patchState(store, {
|
|
736
|
+
totalCountKnown: untracked(store.datasource)?.totalCountKnown ?? true,
|
|
737
|
+
});
|
|
738
|
+
},
|
|
739
|
+
setSelected(ids) {
|
|
740
|
+
patchState(store, {
|
|
741
|
+
_missingSelected: ids,
|
|
742
|
+
selectedMap: new Map(),
|
|
743
|
+
});
|
|
744
|
+
this._loadMissingSelected();
|
|
745
|
+
},
|
|
746
|
+
select(ids) {
|
|
747
|
+
const oldMissing = untracked(store._missingSelected);
|
|
748
|
+
const notInMissing = ids.filter((id) => !oldMissing.includes(id));
|
|
749
|
+
if (notInMissing.length > 0) {
|
|
750
|
+
patchState(store, {
|
|
751
|
+
_missingSelected: oldMissing.concat(notInMissing),
|
|
752
|
+
});
|
|
753
|
+
this._loadMissingSelected();
|
|
754
|
+
}
|
|
755
|
+
},
|
|
756
|
+
unselectAll() {
|
|
757
|
+
const fetchMissingReq = untracked(store._fetchMissingRequest);
|
|
758
|
+
if (fetchMissingReq) {
|
|
759
|
+
fetchMissingReq.subscription.unsubscribe();
|
|
760
|
+
}
|
|
761
|
+
patchState(store, {
|
|
762
|
+
_missingSelected: [],
|
|
763
|
+
selectedMap: new Map(),
|
|
764
|
+
_fetchMissingRequest: null,
|
|
765
|
+
});
|
|
766
|
+
},
|
|
767
|
+
_setAndGetMissing() {
|
|
768
|
+
const allMissing = untracked(store._missingSelected);
|
|
769
|
+
const items = untracked(store.options);
|
|
770
|
+
const selectedMap = new Map(untracked(store.selectedMap));
|
|
771
|
+
const newMissing = [];
|
|
772
|
+
let selectedChanged = false;
|
|
773
|
+
for (const id of allMissing) {
|
|
774
|
+
const item = items.find((it) => it.id === id);
|
|
775
|
+
if (item) {
|
|
776
|
+
selectedMap.set(id, item);
|
|
777
|
+
selectedChanged = true;
|
|
778
|
+
}
|
|
779
|
+
else {
|
|
780
|
+
newMissing.push(id);
|
|
781
|
+
}
|
|
782
|
+
}
|
|
783
|
+
if (selectedChanged) {
|
|
784
|
+
patchState(store, { selectedMap });
|
|
785
|
+
}
|
|
786
|
+
if (newMissing.length === 0) {
|
|
787
|
+
this._cancelFetchMissingIfNeeded();
|
|
788
|
+
}
|
|
789
|
+
patchState(store, { _missingSelected: newMissing });
|
|
790
|
+
return newMissing;
|
|
791
|
+
},
|
|
792
|
+
_loadMissingSelected() {
|
|
793
|
+
const reallyMissing = this._setAndGetMissing();
|
|
794
|
+
if (!untracked(store.loading) && reallyMissing.length > 0) {
|
|
795
|
+
this._fetchMissing(reallyMissing);
|
|
796
|
+
}
|
|
797
|
+
},
|
|
798
|
+
_cancelFetchMissingIfNeeded() {
|
|
799
|
+
const fetchMissingReq = untracked(store._fetchMissingRequest);
|
|
800
|
+
const items = untracked(store.options);
|
|
801
|
+
if (fetchMissingReq?.ids.every((id) => items.some((it) => it.id === id))) {
|
|
802
|
+
fetchMissingReq.subscription.unsubscribe();
|
|
803
|
+
patchState(store, {
|
|
804
|
+
_fetchMissingRequest: null,
|
|
805
|
+
_missingSelected: [],
|
|
806
|
+
});
|
|
807
|
+
}
|
|
808
|
+
},
|
|
809
|
+
_fetchMissing(ids) {
|
|
810
|
+
const datasource = untracked(store.datasource);
|
|
811
|
+
if (!datasource || ids.length === 0) {
|
|
812
|
+
return;
|
|
813
|
+
}
|
|
814
|
+
const sub = datasource.getItemsByIds(ids).subscribe((map) => {
|
|
815
|
+
const newMissing = [];
|
|
816
|
+
const newSelected = new Map(untracked(store.selectedMap));
|
|
817
|
+
for (const id of untracked(store._missingSelected)) {
|
|
818
|
+
if (map.has(id)) {
|
|
819
|
+
const value = map.get(id);
|
|
820
|
+
const label = datasource.getLabel(value);
|
|
821
|
+
newSelected.set(id, { label, value, id });
|
|
822
|
+
}
|
|
823
|
+
else {
|
|
824
|
+
newMissing.push(id);
|
|
825
|
+
}
|
|
826
|
+
}
|
|
827
|
+
patchState(store, {
|
|
828
|
+
_fetchMissingRequest: null,
|
|
829
|
+
_missingSelected: newMissing,
|
|
830
|
+
selectedMap: newSelected,
|
|
831
|
+
});
|
|
832
|
+
this._loadMissingSelected();
|
|
833
|
+
});
|
|
834
|
+
if (!sub.closed) {
|
|
835
|
+
patchState(store, {
|
|
836
|
+
_fetchMissingRequest: { ids, subscription: sub },
|
|
837
|
+
});
|
|
838
|
+
}
|
|
839
|
+
},
|
|
840
|
+
selectSingle(id) {
|
|
841
|
+
this.setSelected([id]);
|
|
842
|
+
},
|
|
843
|
+
toggle(id) {
|
|
844
|
+
const oldMap = untracked(store.selectedMap);
|
|
845
|
+
const datasource = untracked(store.datasource);
|
|
846
|
+
if (!datasource) {
|
|
847
|
+
throw new Error('Datasource is undefined');
|
|
848
|
+
}
|
|
849
|
+
if (oldMap.has(id)) {
|
|
850
|
+
const newMap = new Map(oldMap);
|
|
851
|
+
newMap.delete(id);
|
|
852
|
+
patchState(store, { selectedMap: newMap });
|
|
853
|
+
}
|
|
854
|
+
else {
|
|
855
|
+
const item = untracked(store.options).find((it) => it.id === id);
|
|
856
|
+
if (!item) {
|
|
857
|
+
this.select([id]);
|
|
858
|
+
}
|
|
859
|
+
else {
|
|
860
|
+
const newMap = new Map(oldMap);
|
|
861
|
+
newMap.set(id, item);
|
|
862
|
+
patchState(store, { selectedMap: newMap });
|
|
863
|
+
}
|
|
864
|
+
}
|
|
865
|
+
},
|
|
866
|
+
cancelFetch() {
|
|
867
|
+
untracked(store._fetchRequest)?.subscription.unsubscribe();
|
|
868
|
+
patchState(store, {
|
|
869
|
+
_fetchRequest: null,
|
|
870
|
+
fetchError: null,
|
|
871
|
+
});
|
|
872
|
+
},
|
|
873
|
+
isSelected(item) {
|
|
874
|
+
const datasource = untracked(store.datasource);
|
|
875
|
+
if (!datasource) {
|
|
876
|
+
return false;
|
|
877
|
+
}
|
|
878
|
+
const id = datasource.getId(item);
|
|
879
|
+
return untracked(store.selectedMap).has(id);
|
|
880
|
+
},
|
|
881
|
+
setPageSize(size) {
|
|
882
|
+
patchState(store, { pageSize: size });
|
|
883
|
+
},
|
|
884
|
+
_getLabelValueIds(items) {
|
|
885
|
+
const datasource = untracked(store.datasource);
|
|
886
|
+
if (!datasource) {
|
|
887
|
+
throw new Error('Datasource not set!');
|
|
888
|
+
}
|
|
889
|
+
return items.map((item) => ({
|
|
890
|
+
label: datasource.getLabel(item),
|
|
891
|
+
value: item,
|
|
892
|
+
id: datasource.getId(item),
|
|
893
|
+
}));
|
|
894
|
+
},
|
|
895
|
+
})));
|
|
896
|
+
}
|
|
897
|
+
const RdtSelectStore = getRdtSelectStore();
|
|
898
|
+
function getRdtSelectError(error) {
|
|
899
|
+
if (typeof error === 'string') {
|
|
900
|
+
return error;
|
|
901
|
+
}
|
|
902
|
+
else if (error instanceof Error) {
|
|
903
|
+
return error.message;
|
|
904
|
+
}
|
|
905
|
+
else if (error && typeof error === 'object' && 'message' in error) {
|
|
906
|
+
return error.message;
|
|
907
|
+
}
|
|
908
|
+
return 'Nastala chyba.';
|
|
909
|
+
}
|
|
910
|
+
|
|
911
|
+
class RdtSelectOfflineDatasourceProviderDirective {
|
|
912
|
+
store = inject(RdtSelectStore);
|
|
913
|
+
optionsInput = input.required(...(ngDevMode ? [{ debugName: "optionsInput", alias: 'options' }] : [{
|
|
914
|
+
alias: 'options',
|
|
915
|
+
}]));
|
|
916
|
+
options = computed(() => this.parseOptions(this.optionsInput()), ...(ngDevMode ? [{ debugName: "options" }] : []));
|
|
917
|
+
parseOptions(options) {
|
|
918
|
+
if (!options || options.length === 0) {
|
|
919
|
+
return [];
|
|
920
|
+
}
|
|
921
|
+
if (typeof options[0] === 'object' && options[0]) {
|
|
922
|
+
return options;
|
|
923
|
+
}
|
|
924
|
+
else {
|
|
925
|
+
return options.map((value) => ({
|
|
926
|
+
label: String(value),
|
|
927
|
+
value: value,
|
|
928
|
+
}));
|
|
929
|
+
}
|
|
930
|
+
}
|
|
931
|
+
optionsEffect = effect(() => this.setDatasource(), ...(ngDevMode ? [{ debugName: "optionsEffect" }] : []));
|
|
932
|
+
setDatasource() {
|
|
933
|
+
const options = this.options();
|
|
934
|
+
this.store.setDatasource(new RdtOfflineSelectDatasource(options));
|
|
935
|
+
}
|
|
936
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.7", ngImport: i0, type: RdtSelectOfflineDatasourceProviderDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
|
|
937
|
+
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "20.1.7", type: RdtSelectOfflineDatasourceProviderDirective, isStandalone: true, inputs: { optionsInput: { classPropertyName: "optionsInput", publicName: "options", isSignal: true, isRequired: true, transformFunction: null } }, ngImport: i0 });
|
|
938
|
+
}
|
|
939
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.7", ngImport: i0, type: RdtSelectOfflineDatasourceProviderDirective, decorators: [{
|
|
940
|
+
type: Directive
|
|
941
|
+
}] });
|
|
942
|
+
|
|
943
|
+
class RdtSelectOptionDirective {
|
|
944
|
+
elementRef = inject(ElementRef);
|
|
945
|
+
value = input.required(...(ngDevMode ? [{ debugName: "value", alias: 'rdtSelectOption' }] : [{ alias: 'rdtSelectOption' }]));
|
|
946
|
+
_selected = signal(false, ...(ngDevMode ? [{ debugName: "_selected" }] : []));
|
|
947
|
+
set selected(value) {
|
|
948
|
+
this._selected.set(value);
|
|
949
|
+
}
|
|
950
|
+
get selected() {
|
|
951
|
+
return this._selected();
|
|
952
|
+
}
|
|
953
|
+
_disabled = signal(false, ...(ngDevMode ? [{ debugName: "_disabled" }] : []));
|
|
954
|
+
set disabled(value) {
|
|
955
|
+
this._disabled.set(value);
|
|
956
|
+
}
|
|
957
|
+
get disabled() {
|
|
958
|
+
return this._disabled();
|
|
959
|
+
}
|
|
960
|
+
setActiveStyles() {
|
|
961
|
+
this.selected = true;
|
|
962
|
+
}
|
|
963
|
+
setInactiveStyles() {
|
|
964
|
+
this.selected = false;
|
|
965
|
+
}
|
|
966
|
+
scrollIntoElement() {
|
|
967
|
+
this.elementRef.nativeElement.scrollIntoView({
|
|
968
|
+
block: 'nearest',
|
|
969
|
+
behavior: 'smooth',
|
|
970
|
+
});
|
|
971
|
+
}
|
|
972
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.7", ngImport: i0, type: RdtSelectOptionDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
|
|
973
|
+
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "20.1.7", type: RdtSelectOptionDirective, isStandalone: true, selector: "[rdtSelectOption]", inputs: { value: { classPropertyName: "value", publicName: "rdtSelectOption", isSignal: true, isRequired: true, transformFunction: null } }, host: { properties: { "class.rdt-option-selected": "_selected()", "class.rdt-option-disabled": "_disabled()" }, classAttribute: "rdt-option" }, ngImport: i0 });
|
|
974
|
+
}
|
|
975
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.7", ngImport: i0, type: RdtSelectOptionDirective, decorators: [{
|
|
976
|
+
type: Directive,
|
|
977
|
+
args: [{
|
|
978
|
+
selector: '[rdtSelectOption]',
|
|
979
|
+
host: {
|
|
980
|
+
class: 'rdt-option',
|
|
981
|
+
'[class.rdt-option-selected]': '_selected()',
|
|
982
|
+
'[class.rdt-option-disabled]': '_disabled()',
|
|
983
|
+
},
|
|
984
|
+
}]
|
|
985
|
+
}] });
|
|
986
|
+
|
|
987
|
+
class RdtBaseSelectCommonComponent extends RdtBaseFormInputComponent {
|
|
988
|
+
datasourceInput = input(null, ...(ngDevMode ? [{ debugName: "datasourceInput" }] : []));
|
|
989
|
+
store = inject(RdtSelectStore);
|
|
990
|
+
visibleOptions = this.store.visibleOptions;
|
|
991
|
+
queryValidatorFnInput = input(null, ...(ngDevMode ? [{ debugName: "queryValidatorFnInput", alias: 'inputValidator' }] : [{
|
|
992
|
+
alias: 'inputValidator',
|
|
993
|
+
}]));
|
|
994
|
+
queryValidatorFn = linkedSignal(() => this.queryValidatorFnInput());
|
|
995
|
+
queryValidatorEffect = effect(() => {
|
|
996
|
+
const validator = this.queryValidatorFn();
|
|
997
|
+
if (validator) {
|
|
998
|
+
this.inputCtrl.setValidators(validator);
|
|
999
|
+
}
|
|
1000
|
+
else {
|
|
1001
|
+
this.inputCtrl.clearValidators();
|
|
1002
|
+
}
|
|
1003
|
+
}, ...(ngDevMode ? [{ debugName: "queryValidatorEffect" }] : []));
|
|
1004
|
+
inputCtrl = new FormControl(null);
|
|
1005
|
+
inputCtrlEvents = toSignal(this.inputCtrl.events);
|
|
1006
|
+
inputErrors = computed(() => {
|
|
1007
|
+
this.inputCtrlEvents();
|
|
1008
|
+
if (this.inputCtrl.touched && this.inputCtrl.invalid) {
|
|
1009
|
+
return this.inputCtrl.errors;
|
|
1010
|
+
}
|
|
1011
|
+
else {
|
|
1012
|
+
return null;
|
|
1013
|
+
}
|
|
1014
|
+
}, ...(ngDevMode ? [{ debugName: "inputErrors" }] : []));
|
|
1015
|
+
debounceTimeInput = input(300, ...(ngDevMode ? [{ debugName: "debounceTimeInput", alias: 'debounce' }] : [{
|
|
1016
|
+
alias: 'debounce',
|
|
1017
|
+
}]));
|
|
1018
|
+
debounceTime = linkedSignal(() => this.debounceTimeInput());
|
|
1019
|
+
debouncedInput$ = toObservable(this.debounceTime).pipe(switchMap((time) => this.inputCtrl.valueChanges.pipe(debounceTime(time))), distinctUntilChanged());
|
|
1020
|
+
debouncedInput = toSignal(this.debouncedInput$, {
|
|
1021
|
+
initialValue: null,
|
|
1022
|
+
});
|
|
1023
|
+
pageSizeInput = input(20, ...(ngDevMode ? [{ debugName: "pageSizeInput", alias: 'pageSize' }] : [{
|
|
1024
|
+
alias: 'pageSize',
|
|
1025
|
+
}]));
|
|
1026
|
+
pageSizeEffect = effect(() => this.store.setPageSize(this.pageSizeInput()), ...(ngDevMode ? [{ debugName: "pageSizeEffect" }] : []));
|
|
1027
|
+
loading = computed(() => {
|
|
1028
|
+
return (this.store.loading() ||
|
|
1029
|
+
this.loadingInput() ||
|
|
1030
|
+
Object.values(this.loadingMap()).some(Boolean));
|
|
1031
|
+
}, ...(ngDevMode ? [{ debugName: "loading" }] : []));
|
|
1032
|
+
ngOnInit() {
|
|
1033
|
+
super.ngOnInit();
|
|
1034
|
+
this.debouncedInput$
|
|
1035
|
+
.pipe(takeUntilDestroyed(this.destroyRef))
|
|
1036
|
+
.subscribe((value) => this.handleInput(value));
|
|
1037
|
+
}
|
|
1038
|
+
handleInput(value) {
|
|
1039
|
+
this.store.setQuery(value);
|
|
1040
|
+
}
|
|
1041
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.7", ngImport: i0, type: RdtBaseSelectCommonComponent, deps: null, target: i0.ɵɵFactoryTarget.Directive });
|
|
1042
|
+
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "20.1.7", type: RdtBaseSelectCommonComponent, isStandalone: true, inputs: { datasourceInput: { classPropertyName: "datasourceInput", publicName: "datasourceInput", isSignal: true, isRequired: false, transformFunction: null }, queryValidatorFnInput: { classPropertyName: "queryValidatorFnInput", publicName: "inputValidator", isSignal: true, isRequired: false, transformFunction: null }, debounceTimeInput: { classPropertyName: "debounceTimeInput", publicName: "debounce", isSignal: true, isRequired: false, transformFunction: null }, pageSizeInput: { classPropertyName: "pageSizeInput", publicName: "pageSize", isSignal: true, isRequired: false, transformFunction: null } }, usesInheritance: true, ngImport: i0 });
|
|
1043
|
+
}
|
|
1044
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.7", ngImport: i0, type: RdtBaseSelectCommonComponent, decorators: [{
|
|
1045
|
+
type: Directive
|
|
1046
|
+
}] });
|
|
1047
|
+
|
|
1048
|
+
class RdtMultiSelectComponent extends RdtBaseSelectCommonComponent {
|
|
1049
|
+
selected = computed(() => {
|
|
1050
|
+
const selected = this.store.selectedItems();
|
|
1051
|
+
return selected.length > 0 ? selected : null;
|
|
1052
|
+
}, ...(ngDevMode ? [{ debugName: "selected" }] : []));
|
|
1053
|
+
isEmpty(value) {
|
|
1054
|
+
return value === null || value.length === 0;
|
|
1055
|
+
}
|
|
1056
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.7", ngImport: i0, type: RdtMultiSelectComponent, deps: null, target: i0.ɵɵFactoryTarget.Directive });
|
|
1057
|
+
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "20.1.7", type: RdtMultiSelectComponent, isStandalone: true, usesInheritance: true, ngImport: i0 });
|
|
1058
|
+
}
|
|
1059
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.7", ngImport: i0, type: RdtMultiSelectComponent, decorators: [{
|
|
1060
|
+
type: Directive
|
|
1061
|
+
}] });
|
|
1062
|
+
|
|
1063
|
+
class RdtSingleSelectComponent extends RdtBaseSelectCommonComponent {
|
|
1064
|
+
selected = computed(() => {
|
|
1065
|
+
const items = this.store.selectedItems();
|
|
1066
|
+
return items.length > 0 ? items[0] : null;
|
|
1067
|
+
}, ...(ngDevMode ? [{ debugName: "selected" }] : []));
|
|
1068
|
+
isEmpty(value) {
|
|
1069
|
+
return value === null;
|
|
1070
|
+
}
|
|
1071
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.7", ngImport: i0, type: RdtSingleSelectComponent, deps: null, target: i0.ɵɵFactoryTarget.Directive });
|
|
1072
|
+
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "20.1.7", type: RdtSingleSelectComponent, isStandalone: true, providers: [
|
|
1073
|
+
{
|
|
1074
|
+
provide: RdtBaseFormInputComponent,
|
|
1075
|
+
useValue: RdtSingleSelectComponent,
|
|
1076
|
+
},
|
|
1077
|
+
], usesInheritance: true, ngImport: i0 });
|
|
1078
|
+
}
|
|
1079
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.7", ngImport: i0, type: RdtSingleSelectComponent, decorators: [{
|
|
1080
|
+
type: Directive,
|
|
1081
|
+
args: [{
|
|
1082
|
+
providers: [
|
|
1083
|
+
{
|
|
1084
|
+
provide: RdtBaseFormInputComponent,
|
|
1085
|
+
useValue: RdtSingleSelectComponent,
|
|
1086
|
+
},
|
|
1087
|
+
],
|
|
1088
|
+
}]
|
|
1089
|
+
}] });
|
|
1090
|
+
|
|
1091
|
+
class RdtTextInputComponent extends RdtBaseFormInputComponent {
|
|
1092
|
+
type = input('text', ...(ngDevMode ? [{ debugName: "type" }] : []));
|
|
1093
|
+
autocomplete = input(undefined, ...(ngDevMode ? [{ debugName: "autocomplete", transform: nullToUndefined }] : [{
|
|
1094
|
+
transform: nullToUndefined,
|
|
1095
|
+
}]));
|
|
1096
|
+
maxlength = input(undefined, ...(ngDevMode ? [{ debugName: "maxlength", transform: nullToUndefinedNumeric }] : [{ transform: nullToUndefinedNumeric }]));
|
|
1097
|
+
minlength = input(undefined, ...(ngDevMode ? [{ debugName: "minlength", transform: nullToUndefinedNumeric }] : [{ transform: nullToUndefinedNumeric }]));
|
|
1098
|
+
pattern = input(undefined, ...(ngDevMode ? [{ debugName: "pattern", transform: nullToUndefined }] : [{
|
|
1099
|
+
transform: nullToUndefined,
|
|
1100
|
+
}]));
|
|
1101
|
+
isEmpty(value) {
|
|
1102
|
+
return value === '' || value === null;
|
|
1103
|
+
}
|
|
1104
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.7", ngImport: i0, type: RdtTextInputComponent, deps: null, target: i0.ɵɵFactoryTarget.Directive });
|
|
1105
|
+
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "20.1.7", type: RdtTextInputComponent, isStandalone: true, inputs: { type: { classPropertyName: "type", publicName: "type", isSignal: true, isRequired: false, transformFunction: null }, autocomplete: { classPropertyName: "autocomplete", publicName: "autocomplete", isSignal: true, isRequired: false, transformFunction: null }, maxlength: { classPropertyName: "maxlength", publicName: "maxlength", isSignal: true, isRequired: false, transformFunction: null }, minlength: { classPropertyName: "minlength", publicName: "minlength", isSignal: true, isRequired: false, transformFunction: null }, pattern: { classPropertyName: "pattern", publicName: "pattern", isSignal: true, isRequired: false, transformFunction: null } }, usesInheritance: true, ngImport: i0 });
|
|
1106
|
+
}
|
|
1107
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.7", ngImport: i0, type: RdtTextInputComponent, decorators: [{
|
|
1108
|
+
type: Directive
|
|
1109
|
+
}] });
|
|
1110
|
+
|
|
1111
|
+
/**
|
|
1112
|
+
* Generated bundle index. Do not edit.
|
|
1113
|
+
*/
|
|
1114
|
+
|
|
1115
|
+
export { NO_OP_FILE_READER, NoOpFileReader, RDT_DEFAULT_FILE_LABEL_FN, RDT_DEFAULT_FILE_READER, RDT_DEFAULT_MAX_FILE_SIZE, RdtCheckboxComponent, RdtDateComponent, RdtFileInputComponent, RdtFileReader, RdtFileReaderArrayBuffer, RdtFileReaderBase64, RdtMultiSelectComponent, RdtNumericInputComponent, RdtOfflineSelectDatasource, RdtSelectDatasource, RdtSelectOfflineDatasourceProviderDirective, RdtSelectOptionDirective, RdtSelectStore, RdtSingleSelectComponent, RdtTextInputComponent, VnshFileReaderText, czechFileLabelFn, rdtSelectInitialState };
|
|
1116
|
+
//# sourceMappingURL=ngrdt-forms.mjs.map
|