@ngrdt/forms 0.0.78 → 0.0.81

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.
@@ -2,7 +2,7 @@ import * as i0 from '@angular/core';
2
2
  import { inject, Injector, signal, model, linkedSignal, input, booleanAttribute, computed, effect, untracked, Directive, InjectionToken, output, forwardRef, numberAttribute, ElementRef, Pipe } from '@angular/core';
3
3
  import { takeUntilDestroyed, toSignal, toObservable } from '@angular/core/rxjs-interop';
4
4
  import { FormControlName, FormControlDirective, NgModel, NgControl, Validators, NG_VALUE_ACCESSOR, FormControl, FormGroup } from '@angular/forms';
5
- import { RdtInteractiveElementComponent, RdtComponentOutletDirective } from '@ngrdt/core';
5
+ import { RdtInteractiveElementComponent, RdtComponentOutletDirective, RdtTranslateService } from '@ngrdt/core';
6
6
  import { startWith, take, map, forkJoin, of, from, switchMap, debounceTime, distinctUntilChanged, merge, takeUntil } from 'rxjs';
7
7
  import { RdtFileUtils, RdtObjectUtils, RdtDateUtils } from '@ngrdt/utils';
8
8
  import { signalStore, withState, withHooks, withComputed, withMethods, patchState } from '@ngrx/signals';
@@ -407,23 +407,27 @@ const RDT_DEFAULT_FILE_READER = new InjectionToken('RDT_DEFAULT_FILE_READER', {
407
407
  providedIn: 'root',
408
408
  });
409
409
 
410
- function czechFileLabelFn(files) {
411
- switch (files.length) {
412
- case 0:
413
- return 'Vyberte soubor';
414
- case 1:
415
- return files[0].fileName;
416
- case 2:
417
- case 3:
418
- case 4:
419
- return `Vybrány ${files.length} soubory`;
420
- default:
421
- return `Vybráno ${files.length} souborů`;
410
+ function fileLabelTranslate(translate, files) {
411
+ const count = files.length;
412
+ if (count === 0) {
413
+ return translate.instant('RDT_FILE_LABEL_EMPTY');
414
+ }
415
+ if (count === 1) {
416
+ return translate.instant('RDT_FILE_LABEL_SINGLE', {
417
+ fileName: files[0].fileName,
418
+ });
419
+ }
420
+ if (count >= 2 && count <= 4) {
421
+ return translate.instant('RDT_FILE_LABEL_FEW', { count });
422
422
  }
423
+ return translate.instant('RDT_FILE_LABEL_MANY', { count });
423
424
  }
424
425
  const RDT_DEFAULT_FILE_LABEL_FN = new InjectionToken('RDT_DEFAULT_FILE_LABEL_FN', {
425
426
  providedIn: 'root',
426
- factory: () => czechFileLabelFn,
427
+ factory: () => {
428
+ const translate = inject(RdtTranslateService);
429
+ return (files) => fileLabelTranslate(translate, files);
430
+ },
427
431
  });
428
432
 
429
433
  const RDT_DEFAULT_MAX_FILE_SIZE = new InjectionToken('RDT_DEFAULT_MAX_FILE_SIZE', {
@@ -685,10 +689,14 @@ const rdtSelectInitialState = {
685
689
  datasource: null,
686
690
  selectedMap: new Map(),
687
691
  fetchError: null,
688
- missingValuePlaceholder: 'Načítání (ID = {id})...',
692
+ /* loadingValuePlaceholder: 'Načítání (ID = {id})...',
693
+ missingValuePlaceholder: 'Neznámá hodnota (ID = {id})', */
694
+ loadingValuePlaceholder: 'RDT_SELECT_LOADING_ID',
695
+ missingValuePlaceholder: 'RDT_SELECT_UNKNOWN_ID',
689
696
  _fetchRequest: null,
690
697
  _fetchMissingRequest: null,
691
698
  _missingSelected: [],
699
+ _unfetchableIds: [],
692
700
  };
693
701
 
694
702
  function compareSelectRequestParams(a, b) {
@@ -719,6 +727,7 @@ function getRdtSelectStore(initialState = rdtSelectInitialState) {
719
727
  const query = state.query();
720
728
  const selectedMap = state.selectedMap();
721
729
  const missing = state._missingSelected();
730
+ const unfetchable = state._unfetchableIds();
722
731
  if (query) {
723
732
  return items.map((it) => ({
724
733
  ...it,
@@ -727,13 +736,21 @@ function getRdtSelectStore(initialState = rdtSelectInitialState) {
727
736
  }
728
737
  const selected = [];
729
738
  const missingPlaceholder = state.missingValuePlaceholder();
730
- const placeholders = missing.map((id) => ({
739
+ const loadingPlaceholder = state.loadingValuePlaceholder();
740
+ const loadingPlaceholders = missing.map((id) => ({
741
+ id,
742
+ label: loadingPlaceholder + '::id=' + String(id),
743
+ value: null,
744
+ selected: true,
745
+ }));
746
+ const missingPlaceholders = unfetchable.map((id) => ({
731
747
  id,
732
- label: missingPlaceholder.replace('{id}', String(id)),
748
+ label: missingPlaceholder + '::id=' + String(id),
733
749
  value: null,
734
750
  selected: true,
735
751
  }));
736
- placeholders.forEach((pl) => selected.push(pl));
752
+ selected.push(...loadingPlaceholders);
753
+ selected.push(...missingPlaceholders);
737
754
  items.forEach((item) => {
738
755
  selected.push({ ...item, selected: selectedMap.has(item.id) });
739
756
  });
@@ -867,6 +884,7 @@ function getRdtSelectStore(initialState = rdtSelectInitialState) {
867
884
  },
868
885
  setSelected(ids) {
869
886
  patchState(store, {
887
+ _unfetchableIds: [],
870
888
  _missingSelected: ids,
871
889
  selectedMap: new Map(),
872
890
  });
@@ -894,6 +912,7 @@ function getRdtSelectStore(initialState = rdtSelectInitialState) {
894
912
  });
895
913
  },
896
914
  _setAndGetMissing() {
915
+ const unfetchable = untracked(store._unfetchableIds);
897
916
  const allMissing = untracked(store._missingSelected);
898
917
  const items = untracked(store.options);
899
918
  const selectedMap = new Map(untracked(store.selectedMap));
@@ -905,7 +924,7 @@ function getRdtSelectStore(initialState = rdtSelectInitialState) {
905
924
  selectedMap.set(id, item);
906
925
  selectedChanged = true;
907
926
  }
908
- else {
927
+ else if (!unfetchable.includes(id)) {
909
928
  newMissing.push(id);
910
929
  }
911
930
  }
@@ -933,12 +952,16 @@ function getRdtSelectStore(initialState = rdtSelectInitialState) {
933
952
  _cancelFetchMissingIfNeeded() {
934
953
  const fetchMissingReq = untracked(store._fetchMissingRequest);
935
954
  const items = untracked(store.options);
936
- if (fetchMissingReq?.ids.every((id) => items.some((it) => it.id === id))) {
937
- fetchMissingReq.subscription.unsubscribe();
938
- patchState(store, {
939
- _fetchMissingRequest: null,
940
- _missingSelected: [],
941
- });
955
+ const missingEmpty = untracked(store._missingSelected).length === 0;
956
+ if (fetchMissingReq) {
957
+ if (fetchMissingReq.ids.every((id) => items.some((it) => it.id === id)) ||
958
+ missingEmpty) {
959
+ fetchMissingReq.subscription.unsubscribe();
960
+ patchState(store, {
961
+ _fetchMissingRequest: null,
962
+ _missingSelected: [],
963
+ });
964
+ }
942
965
  }
943
966
  },
944
967
  _fetchMissing(ids, datasource) {
@@ -948,12 +971,17 @@ function getRdtSelectStore(initialState = rdtSelectInitialState) {
948
971
  const sub = datasource.getItemsByIds(ids).subscribe((map) => {
949
972
  const newMissing = [];
950
973
  const newSelected = new Map(untracked(store.selectedMap));
974
+ const unfetchable = [...untracked(store._unfetchableIds)];
951
975
  for (const id of untracked(store._missingSelected)) {
952
976
  if (map.has(id)) {
953
977
  const value = map.get(id);
954
978
  const label = datasource.getLabel(value);
955
979
  newSelected.set(id, { label, value, id });
956
980
  }
981
+ else if (ids.includes(id)) {
982
+ console.error(`Item with id ${JSON.stringify(id)} not found by getItemsByIds().`, datasource);
983
+ unfetchable.push(id);
984
+ }
957
985
  else {
958
986
  newMissing.push(id);
959
987
  }
@@ -962,6 +990,7 @@ function getRdtSelectStore(initialState = rdtSelectInitialState) {
962
990
  _fetchMissingRequest: null,
963
991
  _missingSelected: newMissing,
964
992
  selectedMap: newSelected,
993
+ _unfetchableIds: [...unfetchable],
965
994
  initialized: true,
966
995
  });
967
996
  this._loadMissingSelected();
@@ -981,7 +1010,20 @@ function getRdtSelectStore(initialState = rdtSelectInitialState) {
981
1010
  if (!datasource) {
982
1011
  throw new Error('Datasource is undefined');
983
1012
  }
984
- if (oldMap.has(id)) {
1013
+ const unfetchableIds = untracked(store._unfetchableIds);
1014
+ const missingSelectedIds = untracked(store._missingSelected);
1015
+ if (unfetchableIds.includes(id) || missingSelectedIds.includes(id)) {
1016
+ const newUnfetchableIds = unfetchableIds.filter((unfetchableId) => unfetchableId !== id);
1017
+ const newMissingSelected = missingSelectedIds.filter((missingId) => missingId !== id);
1018
+ patchState(store, {
1019
+ _unfetchableIds: newUnfetchableIds,
1020
+ _missingSelected: newMissingSelected,
1021
+ });
1022
+ if (newMissingSelected.length === 0) {
1023
+ this._cancelFetchMissingIfNeeded();
1024
+ }
1025
+ }
1026
+ else if (oldMap.has(id)) {
985
1027
  const newMap = new Map(oldMap);
986
1028
  newMap.delete(id);
987
1029
  patchState(store, { selectedMap: newMap });
@@ -1040,7 +1082,7 @@ function getRdtSelectError(error) {
1040
1082
  else if (error && typeof error === 'object' && 'message' in error) {
1041
1083
  return error.message;
1042
1084
  }
1043
- return 'Nastala chyba.';
1085
+ return 'RDT_SELECT_ERROR';
1044
1086
  }
1045
1087
 
1046
1088
  class RdtSelectOfflineDatasourceProviderDirective {
@@ -1128,7 +1170,9 @@ class RdtBaseSelectCommonComponent extends RdtBaseFormInputComponent {
1128
1170
  alias: 'manualInit',
1129
1171
  });
1130
1172
  manualInit = linkedSignal(() => this.manualInitInput());
1131
- datasourceInput = input(null);
1173
+ datasourceInput = input(null, {
1174
+ alias: 'datasource',
1175
+ });
1132
1176
  store = inject(RdtSelectStore);
1133
1177
  visibleOptions = this.store.visibleOptions;
1134
1178
  queryValidatorFnInput = input(null, {
@@ -1172,6 +1216,12 @@ class RdtBaseSelectCommonComponent extends RdtBaseFormInputComponent {
1172
1216
  this.loadingInput() ||
1173
1217
  RdtObjectUtils.someValuesTrue(this.loadingMap()));
1174
1218
  });
1219
+ datasourceEffect = effect(() => {
1220
+ const datasource = this.datasourceInput();
1221
+ if (datasource) {
1222
+ this.store.setDatasource(datasource);
1223
+ }
1224
+ });
1175
1225
  ngOnInit() {
1176
1226
  super.ngOnInit();
1177
1227
  const control = this.control();
@@ -1230,7 +1280,7 @@ class RdtBaseSelectCommonComponent extends RdtBaseFormInputComponent {
1230
1280
  }
1231
1281
  });
1232
1282
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.0", ngImport: i0, type: RdtBaseSelectCommonComponent, deps: null, target: i0.ɵɵFactoryTarget.Directive });
1233
- static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "20.0.0", type: RdtBaseSelectCommonComponent, isStandalone: true, inputs: { manualInitInput: { classPropertyName: "manualInitInput", publicName: "manualInit", isSignal: true, isRequired: false, transformFunction: null }, 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 });
1283
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "20.0.0", type: RdtBaseSelectCommonComponent, isStandalone: true, inputs: { manualInitInput: { classPropertyName: "manualInitInput", publicName: "manualInit", isSignal: true, isRequired: false, transformFunction: null }, datasourceInput: { classPropertyName: "datasourceInput", publicName: "datasource", 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 });
1234
1284
  }
1235
1285
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.0", ngImport: i0, type: RdtBaseSelectCommonComponent, decorators: [{
1236
1286
  type: Directive
@@ -1327,14 +1377,15 @@ function getFirstError(errors) {
1327
1377
  return null;
1328
1378
  }
1329
1379
  const defaultRdtFormErrorCodes = {
1330
- required: () => `Povinné pole.`,
1331
- email: () => 'Neplatný email.',
1332
- minlength: (value) => `Minimální délka je ${value.requiredLength} znaků.`,
1333
- maxlength: (value) => `Maximální délka je ${value.requiredLength} znaků.`,
1334
- notFound: () => 'Pro zadaný kód nebyla nalezena žádná položka.',
1335
- multipleFound: () => 'Pro zadaný kód bylo nalezeno více položek.',
1380
+ required: () => `RDT_ERROR_REQUIRED`,
1381
+ email: () => 'RDT_ERROR_EMAIL_INVALID',
1382
+ minlength: (value) => ['RDT_ERROR_MIN_LENGTH', value.requiredLength],
1383
+ maxlength: (value) => ['RDT_ERROR_MAX_LENGTH', value.requiredLength],
1384
+ notFound: () => 'RDT_ERROR_NOT_FOUND',
1385
+ multipleFound: () => 'RDT_ERROR_MULTIPLE_FOUND',
1336
1386
  };
1337
1387
  class RdtFormErrorPipe {
1388
+ translateService = inject(RdtTranslateService);
1338
1389
  errorCodes = (() => {
1339
1390
  const injected = inject(RDT_FORM_ERROR_CODES_PROVIDER, {
1340
1391
  optional: true,
@@ -1352,13 +1403,18 @@ class RdtFormErrorPipe {
1352
1403
  if (error) {
1353
1404
  const fn = this.errorCodes[error.key];
1354
1405
  if (fn) {
1355
- return fn(error.value);
1406
+ if (Array.isArray(fn())) {
1407
+ return this.translateService.instant(fn()[0], [
1408
+ fn().slice(1),
1409
+ ]);
1410
+ }
1411
+ return this.translateService.instant(fn());
1356
1412
  }
1357
1413
  else if (typeof error.value === 'string') {
1358
- return error.value;
1414
+ return this.translateService.instant(error.value);
1359
1415
  }
1360
1416
  else {
1361
- return 'Neznámá chyba';
1417
+ return this.translateService.instant('RDT_ERROR_UNKNOWN');
1362
1418
  }
1363
1419
  }
1364
1420
  return '';
@@ -1409,7 +1465,7 @@ class RdtDateValidators {
1409
1465
  lastDayOfMonth: true,
1410
1466
  };
1411
1467
  };
1412
- static greaterOrEqualToField(startDateField, error = 'Platnost do musí být později než platnost od.', unsubscribeSubj) {
1468
+ static greaterOrEqualToField(startDateField, error = 'RDT_DATE_TOO_SOON', unsubscribeSubj) {
1413
1469
  let subbed = false;
1414
1470
  return (endControl) => {
1415
1471
  const startControl = startDateField instanceof FormControl
@@ -1441,7 +1497,7 @@ class RdtDateValidators {
1441
1497
  return null;
1442
1498
  };
1443
1499
  }
1444
- static lessOrEqualToField(endDateField, error = 'Platnost od musí být dříve než platnost do.', unsubscribeSubj) {
1500
+ static lessOrEqualToField(endDateField, error = 'RDT_DATE_TOO_LATE', unsubscribeSubj) {
1445
1501
  let subbed = false;
1446
1502
  return (startControl) => {
1447
1503
  const endControl = endDateField instanceof FormControl
@@ -1622,5 +1678,5 @@ class RdtCommonValidators {
1622
1678
  * Generated bundle index. Do not edit.
1623
1679
  */
1624
1680
 
1625
- export { NO_OP_FILE_READER, NoOpFileReader, RDT_CHECKBOX_BASE_PROVIDER, RDT_DEFAULT_FILE_LABEL_FN, RDT_DEFAULT_FILE_READER, RDT_DEFAULT_MAX_FILE_SIZE, RDT_FORM_ERROR_CODES_PROVIDER, RdtBaseFormInputComponent, RdtBaseSelectCommonComponent, RdtCheckboxComponent, RdtCheckboxOutletDirective, RdtCommonValidators, RdtDateComponent, RdtDateValidators, RdtFileInputComponent, RdtFileReader, RdtFileReaderArrayBuffer, RdtFileReaderBase64, RdtFormErrorPipe, RdtFormInputOutletDirective, RdtMultiSelectComponent, RdtNumericInputComponent, RdtOfflineSelectDatasource, RdtSelectDatasource, RdtSelectOfflineDatasourceProviderDirective, RdtSelectOptionDirective, RdtSelectStore, RdtSingleSelectComponent, RdtTextAreaComponent, RdtTextInputComponent, VnshFileReaderText, czechFileLabelFn, defaultRdtFormErrorCodes, getFirstError, getRdtSelectPage, rdtSelectInitialState };
1681
+ export { NO_OP_FILE_READER, NoOpFileReader, RDT_CHECKBOX_BASE_PROVIDER, RDT_DEFAULT_FILE_LABEL_FN, RDT_DEFAULT_FILE_READER, RDT_DEFAULT_MAX_FILE_SIZE, RDT_FORM_ERROR_CODES_PROVIDER, RdtBaseFormInputComponent, RdtBaseSelectCommonComponent, RdtCheckboxComponent, RdtCheckboxOutletDirective, RdtCommonValidators, RdtDateComponent, RdtDateValidators, RdtFileInputComponent, RdtFileReader, RdtFileReaderArrayBuffer, RdtFileReaderBase64, RdtFormErrorPipe, RdtFormInputOutletDirective, RdtMultiSelectComponent, RdtNumericInputComponent, RdtOfflineSelectDatasource, RdtSelectDatasource, RdtSelectOfflineDatasourceProviderDirective, RdtSelectOptionDirective, RdtSelectStore, RdtSingleSelectComponent, RdtTextAreaComponent, RdtTextInputComponent, VnshFileReaderText, defaultRdtFormErrorCodes, fileLabelTranslate, getFirstError, getRdtSelectPage, rdtSelectInitialState };
1626
1682
  //# sourceMappingURL=ngrdt-forms.mjs.map