ngx-dynamic-entity 2.4.0 → 2.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -258,6 +258,7 @@ rendering decision, not an access-control boundary.
258
258
  | `rules` | Pass the same rules the form uses, or a rule-hidden required field rejects rows the form would save. |
259
259
  | `lookups` | Option lists already resolved, merged over what `LOOKUP_REGISTRY` provides. |
260
260
  | `language` | Default `'en'`. |
261
+ | `dateOrder` | `'DMY'` or `'MDY'`: the order of a date written in digits, such as `05/09/2026`. Without it, a date that reads two ways is an error, never a guess. With a server transport the server's order is the one applied: state it on the router, and the wizard reads its review with what the server reports. If you state one here too and it differs, the wizard refuses to commit. |
261
262
  | `templateFormat` | `'csv'` (default) or `'xlsx'`. `xlsx` needs a server transport. |
262
263
 
263
264
  | Output | Payload |
@@ -930,6 +930,8 @@ const DEFAULT_UI_TEXT = {
930
930
  importDelimiterComma: 'Columns are separated by commas.',
931
931
  importDelimiterSemicolon: 'Columns are separated by semicolons, and numbers use a decimal comma.',
932
932
  importDelimiterTab: 'Columns are separated by tabs.',
933
+ importDateOrderMismatch: 'This page reads dates as {stated} but the import reads them as {reported}. Nothing can be imported until both use the same date order.',
934
+ importDateOrderUnconfirmed: 'The import did not confirm the date order {stated}, so it is not applied. A date such as 05/09/2026 is refused, or read month first by a server older than 2.5.0.',
933
935
  importRowRejected: 'This row will not be imported: {reason}',
934
936
  importRunImport: 'Import {count} row(s)',
935
937
  importImporting: 'Importing…',
@@ -10086,6 +10088,20 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.25", ngImpo
10086
10088
  * on a server because their files have fifty thousand rows. Collapsing them into one option
10087
10089
  * would make each answer imply the other.
10088
10090
  */
10091
+ /**
10092
+ * How the order the host states compares with the one the transport reports it reads with.
10093
+ *
10094
+ * - `mismatch`: both state one and they differ. Committing would store dates read one way
10095
+ * after a review that showed them the other, so nothing may be committed.
10096
+ * - `unconfirmed`: the host states one and the transport reports none. The transport reads the
10097
+ * file, so the host's order is not applied: worth a warning, not a refusal.
10098
+ * - `agreed`: anything else. Only the transport stating one is fine: it is the one that reads.
10099
+ */
10100
+ function compareDateOrders(stated, reported) {
10101
+ if (!stated || stated === reported)
10102
+ return 'agreed';
10103
+ return reported ? 'mismatch' : 'unconfirmed';
10104
+ }
10089
10105
 
10090
10106
  /**
10091
10107
  * sheet-parser.ts — the built-in CSV reader, and the reason it is the only one.
@@ -10176,6 +10192,8 @@ class LocalImportTransport {
10176
10192
  suggestion: suggestMapping(sheet.headers, columns, context.config?.entity ?? ''),
10177
10193
  arrayBound,
10178
10194
  ...(sheet.delimiter ? { delimiter: sheet.delimiter } : {}),
10195
+ // What `commit` below will read with, so the review step reads its sample the same way.
10196
+ ...(context.dateOrder ? { dateOrder: context.dateOrder } : {}),
10179
10197
  };
10180
10198
  }
10181
10199
  async commit(file, plan, context) {
@@ -10186,6 +10204,8 @@ class LocalImportTransport {
10186
10204
  lookups: context.lookups,
10187
10205
  // A `;` file means `1,5` is one and a half — the same call the server makes.
10188
10206
  decimal: decimalMarkFor(sheet.delimiter),
10207
+ // Stated by the host, never inferred: a date that reads two ways fails without it.
10208
+ dateOrder: context.dateOrder,
10189
10209
  });
10190
10210
  }
10191
10211
  async template(spec, format) {
@@ -10294,11 +10314,44 @@ function selectionOf(spec, context, fields) {
10294
10314
  * to resolve — and a consumer who wants two of them, pointed at two backends, gets that for
10295
10315
  * free.
10296
10316
  */
10317
+ /** The first release whose server says which date order it reads with, and refuses to guess one. */
10318
+ const DATE_ORDER_SINCE = [2, 5];
10319
+ /** Whether an engine version is from before the server stopped reading dates month first. */
10320
+ function readsMonthFirst(version) {
10321
+ if (!version)
10322
+ return true;
10323
+ const [major, minor] = version.split('.').map(Number);
10324
+ return major < DATE_ORDER_SINCE[0] || (major === DATE_ORDER_SINCE[0] && minor < DATE_ORDER_SINCE[1]);
10325
+ }
10297
10326
  class HttpImportTransport {
10298
10327
  options;
10328
+ /**
10329
+ * The date order each previewed file's server reported, for `commit` to compare against.
10330
+ * Keyed on the `File`, so it lives exactly as long as the file does.
10331
+ */
10332
+ reported = new WeakMap();
10299
10333
  constructor(options) {
10300
10334
  this.options = options;
10301
10335
  }
10336
+ warn(message) {
10337
+ (this.options.warn ?? ((text) => console.warn(text)))(message);
10338
+ }
10339
+ /**
10340
+ * The server reads the file, so its date order is the one that is applied. When the host
10341
+ * stated one and the server confirms none, the host's order does nothing there: say so, and
10342
+ * say what the server will do instead, which depends on how old it is.
10343
+ */
10344
+ checkDateOrder(stated, reported, version) {
10345
+ if (compareDateOrders(stated, reported) !== 'unconfirmed')
10346
+ return;
10347
+ this.warn(`[ngx-dynamic-entity] This app states the date order ${stated}, but the import server did not confirm one, ` +
10348
+ (readsMonthFirst(version)
10349
+ ? `and runs @dynamic-entity/core ${version ?? '(unreported)'}, from before 2.5.0. A server that old reads a ` +
10350
+ 'date such as 05/09/2026 month first, whatever this app states. Upgrade the server and state ' +
10351
+ 'the same dateOrder on its router.'
10352
+ : 'so it will refuse a date such as 05/09/2026 that could be day first or month first. ' +
10353
+ 'State the same dateOrder on its router.'));
10354
+ }
10302
10355
  get base() {
10303
10356
  return trimSlash(this.options.baseUrl);
10304
10357
  }
@@ -10325,8 +10378,7 @@ class HttpImportTransport {
10325
10378
  // scroll past the warning that does matter.
10326
10379
  if (!version || sameLine(version, CORE_VERSION))
10327
10380
  return;
10328
- const warn = this.options.warn ?? ((message) => console.warn(message));
10329
- warn(`[ngx-dynamic-entity] The import server runs @dynamic-entity/core ${version}; this app ` +
10381
+ this.warn(`[ngx-dynamic-entity] The import server runs @dynamic-entity/core ${version}; this app ` +
10330
10382
  `was built against ${CORE_VERSION}. The two halves of an import are supposed to be the ` +
10331
10383
  'same engine — bring them into step before trusting a difference in what they produce.');
10332
10384
  }
@@ -10342,6 +10394,8 @@ class HttpImportTransport {
10342
10394
  throw await failureOf(response);
10343
10395
  const preview = (await response.json());
10344
10396
  this.checkEngine(preview.engineVersion);
10397
+ this.reported.set(file, preview.dateOrder);
10398
+ this.checkDateOrder(context?.dateOrder, preview.dateOrder, preview.engineVersion);
10345
10399
  return {
10346
10400
  headers: preview.headers ?? [],
10347
10401
  sample: preview.sample ?? [],
@@ -10350,9 +10404,17 @@ class HttpImportTransport {
10350
10404
  // A server older than 2.3 does not say, and always sized for the default.
10351
10405
  arrayBound: preview.arrayBound ?? DEFAULT_ARRAY_ROWS,
10352
10406
  ...(preview.delimiter ? { delimiter: preview.delimiter } : {}),
10407
+ ...(preview.dateOrder ? { dateOrder: preview.dateOrder } : {}),
10353
10408
  };
10354
10409
  }
10355
10410
  async commit(file, plan, context) {
10411
+ // Before a byte is sent. The review this user approved read dates one way and the server
10412
+ // would store them another, and a streaming import cannot be taken back.
10413
+ const reported = this.reported.get(file);
10414
+ if (compareDateOrders(context?.dateOrder, reported) === 'mismatch') {
10415
+ throw new Error(`This app reads dates as ${context.dateOrder} but the import server reads them as ${reported}. ` +
10416
+ 'Nothing was imported. Set the same dateOrder on the wizard and on the server\'s router.');
10417
+ }
10356
10418
  const body = new FormData();
10357
10419
  // **The plan first, and the file second.** The server starts importing while the file is
10358
10420
  // still arriving — that is the whole reason it exists — so the plan has to have arrived
@@ -10938,6 +11000,8 @@ class ImportPreviewComponent {
10938
11000
  language = 'en';
10939
11001
  /** The decimal mark number cells use — the one the commit will read them with. */
10940
11002
  decimal = '.';
11003
+ /** The order of a date written in digits — the one the commit will read them in. */
11004
+ dateOrder;
10941
11005
  ui = inject(UiTextService);
10942
11006
  /** The columns this plan fills, in the plan's own order. */
10943
11007
  columns = signal([], ...(ngDevMode ? [{ debugName: "columns" }] : /* istanbul ignore next */ []));
@@ -10961,6 +11025,7 @@ class ImportPreviewComponent {
10961
11025
  lookups: this.lookups,
10962
11026
  rules: this.rules,
10963
11027
  decimal: this.decimal,
11028
+ dateOrder: this.dateOrder,
10964
11029
  stamp: false,
10965
11030
  firstRowNumber: 0,
10966
11031
  });
@@ -10977,6 +11042,7 @@ class ImportPreviewComponent {
10977
11042
  lang: this.language,
10978
11043
  lookups: this.lookups,
10979
11044
  decimal: this.decimal,
11045
+ dateOrder: this.dateOrder,
10980
11046
  });
10981
11047
  if ('error' in outcome)
10982
11048
  return { text: outcome.error, failed: true };
@@ -10988,7 +11054,7 @@ class ImportPreviewComponent {
10988
11054
  })));
10989
11055
  }
10990
11056
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.25", ngImport: i0, type: ImportPreviewComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
10991
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.25", type: ImportPreviewComponent, isStandalone: true, selector: "ngx-import-preview", inputs: { config: "config", plan: "plan", rows: "rows", lookups: "lookups", rules: "rules", language: "language", decimal: "decimal" }, usesOnChanges: true, ngImport: i0, template: `
11057
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.25", type: ImportPreviewComponent, isStandalone: true, selector: "ngx-import-preview", inputs: { config: "config", plan: "plan", rows: "rows", lookups: "lookups", rules: "rules", language: "language", decimal: "decimal", dateOrder: "dateOrder" }, usesOnChanges: true, ngImport: i0, template: `
10992
11058
  <section class="ngx-import-preview" data-testid="import-preview">
10993
11059
  <h4 class="ngx-import-preview__heading">
10994
11060
  {{ ui.text('importPreviewHeading', language, { count: rows.length }) }}
@@ -11081,6 +11147,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.25", ngImpo
11081
11147
  type: Input
11082
11148
  }], decimal: [{
11083
11149
  type: Input
11150
+ }], dateOrder: [{
11151
+ type: Input
11084
11152
  }] } });
11085
11153
 
11086
11154
  /**
@@ -11283,6 +11351,16 @@ class EntityImportComponent {
11283
11351
  */
11284
11352
  lookups;
11285
11353
  language = 'en';
11354
+ /**
11355
+ * The order of a date written in digits in the sheets this wizard imports: `DMY` for day
11356
+ * first, `MDY` for month first. Without it, a date that reads two ways (`05/09/2026`) is
11357
+ * shown, and imported, as an error rather than guessed.
11358
+ *
11359
+ * The transport reads the file, so the order it reports at preview is the one applied, and
11360
+ * the one the review step shows. If that differs from this, the wizard refuses to commit;
11361
+ * if the transport reports none, the wizard warns that this order is not being applied.
11362
+ */
11363
+ dateOrder;
11286
11364
  /** Format asked of the transport when a template is downloaded. */
11287
11365
  templateFormat = 'csv';
11288
11366
  /** The finished import, once it has run. */
@@ -11299,6 +11377,8 @@ class EntityImportComponent {
11299
11377
  rowCount = signal(0, ...(ngDevMode ? [{ debugName: "rowCount" }] : /* istanbul ignore next */ []));
11300
11378
  /** The separator a delimited file turned out to use, so the user can see how it was read. */
11301
11379
  delimiter = signal(undefined, ...(ngDevMode ? [{ debugName: "delimiter" }] : /* istanbul ignore next */ []));
11380
+ /** The date order the transport said it will read with at commit, from its preview. */
11381
+ reportedDateOrder = signal(undefined, ...(ngDevMode ? [{ debugName: "reportedDateOrder" }] : /* istanbul ignore next */ []));
11302
11382
  fileName = signal('', ...(ngDevMode ? [{ debugName: "fileName" }] : /* istanbul ignore next */ []));
11303
11383
  plan = signal(null, ...(ngDevMode ? [{ debugName: "plan" }] : /* istanbul ignore next */ []));
11304
11384
  result = signal(null, ...(ngDevMode ? [{ debugName: "result" }] : /* istanbul ignore next */ []));
@@ -11317,6 +11397,7 @@ class EntityImportComponent {
11317
11397
  rules: this.rules,
11318
11398
  lookups: this.resolvedLookups(),
11319
11399
  lang: this.language,
11400
+ dateOrder: this.dateOrder,
11320
11401
  };
11321
11402
  }
11322
11403
  /**
@@ -11384,6 +11465,7 @@ class EntityImportComponent {
11384
11465
  this.sample.set(preview.sample);
11385
11466
  this.rowCount.set(preview.rowCount);
11386
11467
  this.delimiter.set(preview.delimiter);
11468
+ this.reportedDateOrder.set(preview.dateOrder);
11387
11469
  this.plan.set(preview.suggestion);
11388
11470
  this.step.set('map');
11389
11471
  }
@@ -11402,6 +11484,12 @@ class EntityImportComponent {
11402
11484
  this.problem.set(this.ui.text('importNeedFile', this.language));
11403
11485
  return;
11404
11486
  }
11487
+ // Never on a mismatch: the review showed dates read one way and the commit would store
11488
+ // them read another. The button is disabled too; this is for whatever calls it anyway.
11489
+ if (this.dateOrderCheck() === 'mismatch') {
11490
+ this.problem.set(this.ui.text('importDateOrderMismatch', this.language, this.dateOrders()));
11491
+ return;
11492
+ }
11405
11493
  this.busy.set(true);
11406
11494
  this.problem.set(null);
11407
11495
  try {
@@ -11467,6 +11555,14 @@ class EntityImportComponent {
11467
11555
  failedRowCount(result) {
11468
11556
  return result.failed ?? new Set(result.errors.map(error => error.row)).size;
11469
11557
  }
11558
+ /** How the order the host states compares with the one the transport reads with. */
11559
+ dateOrderCheck() {
11560
+ return compareDateOrders(this.dateOrder, this.reportedDateOrder());
11561
+ }
11562
+ /** The two orders, for a message that names them. Only asked for when they do not agree. */
11563
+ dateOrders() {
11564
+ return { stated: String(this.dateOrder), reported: String(this.reportedDateOrder()) };
11565
+ }
11470
11566
  /** The decimal mark the commit will read numbers with, so the preview reads them the same. */
11471
11567
  decimal() {
11472
11568
  return decimalMarkFor(this.delimiter());
@@ -11497,7 +11593,7 @@ class EntityImportComponent {
11497
11593
  this.step.set('upload');
11498
11594
  }
11499
11595
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.25", ngImport: i0, type: EntityImportComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
11500
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.25", type: EntityImportComponent, isStandalone: true, selector: "ngx-entity-import", inputs: { config: "config", rules: "rules", lookups: "lookups", language: "language", templateFormat: "templateFormat" }, outputs: { importComplete: "importComplete", templateReady: "templateReady" }, ngImport: i0, template: `
11596
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.25", type: EntityImportComponent, isStandalone: true, selector: "ngx-entity-import", inputs: { config: "config", rules: "rules", lookups: "lookups", language: "language", dateOrder: "dateOrder", templateFormat: "templateFormat" }, outputs: { importComplete: "importComplete", templateReady: "templateReady" }, ngImport: i0, template: `
11501
11597
  <div class="ngx-import" data-testid="entity-import">
11502
11598
  <ol class="ngx-import__steps" data-testid="import-steps">
11503
11599
  @for (name of steps; track name) {
@@ -11556,6 +11652,18 @@ class EntityImportComponent {
11556
11652
  @if (delimiterText(); as separator) {
11557
11653
  <p class="ngx-entity-import__delimiter" data-testid="import-delimiter">{{ separator }}</p>
11558
11654
  }
11655
+ @switch (dateOrderCheck()) {
11656
+ @case ('mismatch') {
11657
+ <p class="ngx-entity-import__problem" role="alert" data-testid="import-date-order-mismatch">
11658
+ {{ ui.text('importDateOrderMismatch', language, dateOrders()) }}
11659
+ </p>
11660
+ }
11661
+ @case ('unconfirmed') {
11662
+ <p class="ngx-entity-import__delimiter" data-testid="import-date-order-unconfirmed">
11663
+ {{ ui.text('importDateOrderUnconfirmed', language, dateOrders()) }}
11664
+ </p>
11665
+ }
11666
+ }
11559
11667
  @if (plan(); as current) {
11560
11668
  <ngx-import-preview
11561
11669
  [config]="config"
@@ -11565,12 +11673,13 @@ class EntityImportComponent {
11565
11673
  [rules]="rules"
11566
11674
  [language]="language"
11567
11675
  [decimal]="decimal()"
11676
+ [dateOrder]="reportedDateOrder()"
11568
11677
  />
11569
11678
  }
11570
11679
  <button
11571
11680
  type="button"
11572
11681
  data-testid="import-commit"
11573
- [disabled]="busy()"
11682
+ [disabled]="busy() || dateOrderCheck() === 'mismatch'"
11574
11683
  (click)="commit()"
11575
11684
  >
11576
11685
  {{
@@ -11617,7 +11726,7 @@ class EntityImportComponent {
11617
11726
  }
11618
11727
  }
11619
11728
  </div>
11620
- `, isInline: true, styles: [".ngx-import{display:flex;flex-direction:column;gap:var(--ngx-gap, 16px);color:var(--ngx-color-text, #1f2937);font-size:var(--ngx-font-size, 14px)}.ngx-import__steps{display:flex;flex-wrap:wrap;gap:8px;list-style:none;margin:0;padding:0}.ngx-import__step{padding:4px 12px;border:1px solid var(--ngx-color-border, #e5e7eb);border-radius:var(--ngx-radius-sm, 6px);color:var(--ngx-color-muted, #6b7280);background:var(--ngx-color-surface-alt, #f9fafb)}.ngx-import__step--current{color:var(--ngx-color-accent, #4f46e5);border-color:var(--ngx-color-accent, #4f46e5);background:var(--ngx-color-accent-soft, #e0e7ff);font-weight:600}.ngx-import__problem{margin:0;padding:10px 12px;border:1px solid var(--ngx-color-border, #fecaca);border-radius:var(--ngx-radius-sm, 6px);background:var(--ngx-color-error-soft, #fef2f2);color:var(--ngx-color-error, #b91c1c);overflow-wrap:anywhere}.ngx-import__file{display:flex;flex-direction:column;gap:6px;padding:14px;border:1px dashed var(--ngx-color-border, #d1d5db);border-radius:var(--ngx-radius-sm, 6px);background:var(--ngx-color-surface, #ffffff)}.ngx-import button{align-self:flex-start;padding:8px 16px;border:1px solid var(--ngx-color-border, #d1d5db);border-radius:var(--ngx-radius-sm, 6px);background:var(--ngx-color-surface, #ffffff);color:inherit;font:inherit;cursor:pointer}.ngx-import button:hover:not(:disabled){border-color:var(--ngx-color-accent, #4f46e5);background:var(--ngx-color-accent-soft, #e0e7ff)}.ngx-import button:disabled{opacity:.55;cursor:not-allowed}\n"], dependencies: [{ kind: "component", type: ImportTemplateComponent, selector: "ngx-import-template", inputs: ["config", "language"], outputs: ["download"] }, { kind: "component", type: ImportMapperComponent, selector: "ngx-import-mapper", inputs: ["config", "headers", "plan", "language"], outputs: ["planChange"] }, { kind: "component", type: ImportPreviewComponent, selector: "ngx-import-preview", inputs: ["config", "plan", "rows", "lookups", "rules", "language", "decimal"] }, { kind: "component", type: ImportErrorsComponent, selector: "ngx-import-errors", inputs: ["errors", "language"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
11729
+ `, isInline: true, styles: [".ngx-import{display:flex;flex-direction:column;gap:var(--ngx-gap, 16px);color:var(--ngx-color-text, #1f2937);font-size:var(--ngx-font-size, 14px)}.ngx-import__steps{display:flex;flex-wrap:wrap;gap:8px;list-style:none;margin:0;padding:0}.ngx-import__step{padding:4px 12px;border:1px solid var(--ngx-color-border, #e5e7eb);border-radius:var(--ngx-radius-sm, 6px);color:var(--ngx-color-muted, #6b7280);background:var(--ngx-color-surface-alt, #f9fafb)}.ngx-import__step--current{color:var(--ngx-color-accent, #4f46e5);border-color:var(--ngx-color-accent, #4f46e5);background:var(--ngx-color-accent-soft, #e0e7ff);font-weight:600}.ngx-import__problem{margin:0;padding:10px 12px;border:1px solid var(--ngx-color-border, #fecaca);border-radius:var(--ngx-radius-sm, 6px);background:var(--ngx-color-error-soft, #fef2f2);color:var(--ngx-color-error, #b91c1c);overflow-wrap:anywhere}.ngx-import__file{display:flex;flex-direction:column;gap:6px;padding:14px;border:1px dashed var(--ngx-color-border, #d1d5db);border-radius:var(--ngx-radius-sm, 6px);background:var(--ngx-color-surface, #ffffff)}.ngx-import button{align-self:flex-start;padding:8px 16px;border:1px solid var(--ngx-color-border, #d1d5db);border-radius:var(--ngx-radius-sm, 6px);background:var(--ngx-color-surface, #ffffff);color:inherit;font:inherit;cursor:pointer}.ngx-import button:hover:not(:disabled){border-color:var(--ngx-color-accent, #4f46e5);background:var(--ngx-color-accent-soft, #e0e7ff)}.ngx-import button:disabled{opacity:.55;cursor:not-allowed}\n"], dependencies: [{ kind: "component", type: ImportTemplateComponent, selector: "ngx-import-template", inputs: ["config", "language"], outputs: ["download"] }, { kind: "component", type: ImportMapperComponent, selector: "ngx-import-mapper", inputs: ["config", "headers", "plan", "language"], outputs: ["planChange"] }, { kind: "component", type: ImportPreviewComponent, selector: "ngx-import-preview", inputs: ["config", "plan", "rows", "lookups", "rules", "language", "decimal", "dateOrder"] }, { kind: "component", type: ImportErrorsComponent, selector: "ngx-import-errors", inputs: ["errors", "language"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
11621
11730
  }
11622
11731
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.25", ngImport: i0, type: EntityImportComponent, decorators: [{
11623
11732
  type: Component,
@@ -11685,6 +11794,18 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.25", ngImpo
11685
11794
  @if (delimiterText(); as separator) {
11686
11795
  <p class="ngx-entity-import__delimiter" data-testid="import-delimiter">{{ separator }}</p>
11687
11796
  }
11797
+ @switch (dateOrderCheck()) {
11798
+ @case ('mismatch') {
11799
+ <p class="ngx-entity-import__problem" role="alert" data-testid="import-date-order-mismatch">
11800
+ {{ ui.text('importDateOrderMismatch', language, dateOrders()) }}
11801
+ </p>
11802
+ }
11803
+ @case ('unconfirmed') {
11804
+ <p class="ngx-entity-import__delimiter" data-testid="import-date-order-unconfirmed">
11805
+ {{ ui.text('importDateOrderUnconfirmed', language, dateOrders()) }}
11806
+ </p>
11807
+ }
11808
+ }
11688
11809
  @if (plan(); as current) {
11689
11810
  <ngx-import-preview
11690
11811
  [config]="config"
@@ -11694,12 +11815,13 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.25", ngImpo
11694
11815
  [rules]="rules"
11695
11816
  [language]="language"
11696
11817
  [decimal]="decimal()"
11818
+ [dateOrder]="reportedDateOrder()"
11697
11819
  />
11698
11820
  }
11699
11821
  <button
11700
11822
  type="button"
11701
11823
  data-testid="import-commit"
11702
- [disabled]="busy()"
11824
+ [disabled]="busy() || dateOrderCheck() === 'mismatch'"
11703
11825
  (click)="commit()"
11704
11826
  >
11705
11827
  {{
@@ -11756,6 +11878,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.25", ngImpo
11756
11878
  type: Input
11757
11879
  }], language: [{
11758
11880
  type: Input
11881
+ }], dateOrder: [{
11882
+ type: Input
11759
11883
  }], templateFormat: [{
11760
11884
  type: Input
11761
11885
  }], importComplete: [{
@@ -11793,5 +11917,5 @@ function saveBlob(blob, filename) {
11793
11917
  * Generated bundle index. Do not edit.
11794
11918
  */
11795
11919
 
11796
- export { ASYNC_VALIDATOR_REGISTRY, ArrayFieldComponent, BooleanFieldComponent, COMMON_MODULES_REGISTRY, CONFIG_SOURCE, CascadeDataService, CheckboxFieldComponent, ColorFieldComponent, ConfigSourceService, CurrencyFieldComponent, DEFAULT_UI_TEXT, DEFAULT_VALIDATION_MESSAGES, DateFieldComponent, DateTimeFieldComponent, DropdownFieldComponent, DynamicFieldComponent, DynamicFormComponent, DynamicRecordFormComponent, ENTITY_REF_CACHE_STORE, ENTITY_REF_REGISTRY, EmailFieldComponent, EntityImportComponent, EntityRefFieldComponent, EntityRefRegistryService, EntityRefSelectionService, EntityReferenceService, FIELD_TYPE_REGISTRY, FIELD_TYPE_SETS, FieldRegistryService, FileFieldComponent, GroupFieldComponent, HOOK_REGISTRY, HookRegistryService, HttpImportTransport, IMPORT_TRANSPORT, ImageFieldComponent, ImportErrorsComponent, ImportMapperComponent, ImportPreviewComponent, ImportTemplateComponent, InMemoryEntityRefCacheStore, LOOKUP_REGISTRY, LocalImportTransport, LookupRegistryService, MARKDOWN_RENDERER, MASKED_PLACEHOLDER, MASKED_ROLES, MarkdownFieldComponent, MonthYearFieldComponent, MultiSelectFieldComponent, NumberFieldComponent, PasswordFieldComponent, PhoneFieldComponent, RECORD_MIGRATIONS, RadioFieldComponent, RatingFieldComponent, RbacService, RulesEvaluationService, SHEET_PARSER, SYSTEM_DEFAULT_CAN_EDIT, SliderFieldComponent, TagsFieldComponent, TextFieldComponent, TextareaFieldComponent, TimeFieldComponent, UI_TEXT, UPLOAD_HANDLER, UiTextService, UrlFieldComponent, VALIDATION_MESSAGES, VALIDATOR_REGISTRY, ValidationMessagesService, ValidatorRegistryService, builtInFieldTypes, defaultSheetParser, fieldDescribedBy, fieldDomId, nextFieldInstanceId, phoneValidator, provideBuiltInFieldTypes, provideFieldTypes, provideHttpImportTransport, provideNgxDynamicEntity, refreshChoiceOptions, resolveUiText, urlValidator };
11920
+ export { ASYNC_VALIDATOR_REGISTRY, ArrayFieldComponent, BooleanFieldComponent, COMMON_MODULES_REGISTRY, CONFIG_SOURCE, CascadeDataService, CheckboxFieldComponent, ColorFieldComponent, ConfigSourceService, CurrencyFieldComponent, DEFAULT_UI_TEXT, DEFAULT_VALIDATION_MESSAGES, DateFieldComponent, DateTimeFieldComponent, DropdownFieldComponent, DynamicFieldComponent, DynamicFormComponent, DynamicRecordFormComponent, ENTITY_REF_CACHE_STORE, ENTITY_REF_REGISTRY, EmailFieldComponent, EntityImportComponent, EntityRefFieldComponent, EntityRefRegistryService, EntityRefSelectionService, EntityReferenceService, FIELD_TYPE_REGISTRY, FIELD_TYPE_SETS, FieldRegistryService, FileFieldComponent, GroupFieldComponent, HOOK_REGISTRY, HookRegistryService, HttpImportTransport, IMPORT_TRANSPORT, ImageFieldComponent, ImportErrorsComponent, ImportMapperComponent, ImportPreviewComponent, ImportTemplateComponent, InMemoryEntityRefCacheStore, LOOKUP_REGISTRY, LocalImportTransport, LookupRegistryService, MARKDOWN_RENDERER, MASKED_PLACEHOLDER, MASKED_ROLES, MarkdownFieldComponent, MonthYearFieldComponent, MultiSelectFieldComponent, NumberFieldComponent, PasswordFieldComponent, PhoneFieldComponent, RECORD_MIGRATIONS, RadioFieldComponent, RatingFieldComponent, RbacService, RulesEvaluationService, SHEET_PARSER, SYSTEM_DEFAULT_CAN_EDIT, SliderFieldComponent, TagsFieldComponent, TextFieldComponent, TextareaFieldComponent, TimeFieldComponent, UI_TEXT, UPLOAD_HANDLER, UiTextService, UrlFieldComponent, VALIDATION_MESSAGES, VALIDATOR_REGISTRY, ValidationMessagesService, ValidatorRegistryService, builtInFieldTypes, compareDateOrders, defaultSheetParser, fieldDescribedBy, fieldDomId, nextFieldInstanceId, phoneValidator, provideBuiltInFieldTypes, provideFieldTypes, provideHttpImportTransport, provideNgxDynamicEntity, refreshChoiceOptions, resolveUiText, urlValidator };
11797
11921
  //# sourceMappingURL=ngx-dynamic-entity.mjs.map