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
|
-
|
|
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
|