@wix/bex-core 2.332.0 → 2.336.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/dist/cjs/assets/locale/messages_ar.json +13 -2
- package/dist/cjs/assets/locale/messages_bg.json +13 -2
- package/dist/cjs/assets/locale/messages_ca.json +13 -2
- package/dist/cjs/assets/locale/messages_cs.json +11 -0
- package/dist/cjs/assets/locale/messages_da.json +11 -0
- package/dist/cjs/assets/locale/messages_de.json +11 -0
- package/dist/cjs/assets/locale/messages_el.json +13 -2
- package/dist/cjs/assets/locale/messages_en.json +13 -2
- package/dist/cjs/assets/locale/messages_es.json +11 -0
- package/dist/cjs/assets/locale/messages_fi.json +13 -2
- package/dist/cjs/assets/locale/messages_fr.json +11 -0
- package/dist/cjs/assets/locale/messages_he.json +13 -2
- package/dist/cjs/assets/locale/messages_hi.json +11 -0
- package/dist/cjs/assets/locale/messages_hu.json +13 -2
- package/dist/cjs/assets/locale/messages_id.json +11 -0
- package/dist/cjs/assets/locale/messages_it.json +11 -0
- package/dist/cjs/assets/locale/messages_ja.json +11 -0
- package/dist/cjs/assets/locale/messages_ko.json +11 -0
- package/dist/cjs/assets/locale/messages_lt.json +13 -2
- package/dist/cjs/assets/locale/messages_ms.json +13 -2
- package/dist/cjs/assets/locale/messages_nl.json +11 -0
- package/dist/cjs/assets/locale/messages_no.json +11 -0
- package/dist/cjs/assets/locale/messages_pl.json +11 -0
- package/dist/cjs/assets/locale/messages_pt.json +11 -0
- package/dist/cjs/assets/locale/messages_ro.json +13 -2
- package/dist/cjs/assets/locale/messages_ru.json +11 -0
- package/dist/cjs/assets/locale/messages_sk.json +13 -2
- package/dist/cjs/assets/locale/messages_sl.json +13 -2
- package/dist/cjs/assets/locale/messages_sv.json +11 -0
- package/dist/cjs/assets/locale/messages_th.json +11 -0
- package/dist/cjs/assets/locale/messages_tl.json +13 -2
- package/dist/cjs/assets/locale/messages_tr.json +11 -0
- package/dist/cjs/assets/locale/messages_uk.json +11 -0
- package/dist/cjs/assets/locale/messages_vi.json +11 -0
- package/dist/cjs/assets/locale/messages_zh.json +11 -0
- package/dist/cjs/assets/locale/version_file +1 -1
- package/dist/cjs/assets/visual-e2e-locale/messages_visuale2e.json +29 -2
- package/dist/cjs/hooks/index.js +6 -6
- package/dist/cjs/hooks/index.js.map +1 -1
- package/dist/cjs/hooks/useImport.js +4 -0
- package/dist/cjs/hooks/useImport.js.map +1 -1
- package/dist/cjs/hooks/useSchemaSource.js +11 -0
- package/dist/cjs/hooks/useSchemaSource.js.map +1 -0
- package/dist/cjs/index.js +4 -9
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/services/translations.js.map +1 -1
- package/dist/cjs/state/CustomFieldModalState.js +12 -0
- package/dist/cjs/state/CustomFieldModalState.js.map +1 -1
- package/dist/cjs/state/ImportState/ImportState.js +415 -136
- package/dist/cjs/state/ImportState/ImportState.js.map +1 -1
- package/dist/cjs/state/ImportState/__tests__/ImportState.engine.spec.js +417 -82
- package/dist/cjs/state/ImportState/__tests__/ImportState.engine.spec.js.map +1 -1
- package/dist/cjs/state/ImportState/__tests__/buildImportConfig.spec.js +156 -0
- package/dist/cjs/state/ImportState/__tests__/buildImportConfig.spec.js.map +1 -0
- package/dist/cjs/state/ImportState/detectFieldType.js +41 -0
- package/dist/cjs/state/ImportState/detectFieldType.js.map +1 -1
- package/dist/cjs/state/ImportState/fieldEdit.js +49 -0
- package/dist/cjs/state/ImportState/fieldEdit.js.map +1 -1
- package/dist/cjs/state/SourceState.js +150 -0
- package/dist/cjs/state/SourceState.js.map +1 -0
- package/dist/cjs/state/index.js +7 -0
- package/dist/cjs/state/index.js.map +1 -1
- package/dist/cjs/testkit/createInMemorySchemaSource.js +190 -0
- package/dist/cjs/testkit/createInMemorySchemaSource.js.map +1 -0
- package/dist/cjs/testkit/hubJobImportMocks.js +18 -2
- package/dist/cjs/testkit/hubJobImportMocks.js.map +1 -1
- package/dist/cjs/testkit/index.js +6 -0
- package/dist/cjs/testkit/index.js.map +1 -1
- package/dist/cjs/types/Field.js.map +1 -1
- package/dist/cjs/types/Schema.js.map +1 -1
- package/dist/cjs/types/SchemaSource.js +31 -21
- package/dist/cjs/types/SchemaSource.js.map +1 -1
- package/dist/esm/assets/locale/messages_ar.json +13 -2
- package/dist/esm/assets/locale/messages_bg.json +13 -2
- package/dist/esm/assets/locale/messages_ca.json +13 -2
- package/dist/esm/assets/locale/messages_cs.json +11 -0
- package/dist/esm/assets/locale/messages_da.json +11 -0
- package/dist/esm/assets/locale/messages_de.json +11 -0
- package/dist/esm/assets/locale/messages_el.json +13 -2
- package/dist/esm/assets/locale/messages_en.json +13 -2
- package/dist/esm/assets/locale/messages_es.json +11 -0
- package/dist/esm/assets/locale/messages_fi.json +13 -2
- package/dist/esm/assets/locale/messages_fr.json +11 -0
- package/dist/esm/assets/locale/messages_he.json +13 -2
- package/dist/esm/assets/locale/messages_hi.json +11 -0
- package/dist/esm/assets/locale/messages_hu.json +13 -2
- package/dist/esm/assets/locale/messages_id.json +11 -0
- package/dist/esm/assets/locale/messages_it.json +11 -0
- package/dist/esm/assets/locale/messages_ja.json +11 -0
- package/dist/esm/assets/locale/messages_ko.json +11 -0
- package/dist/esm/assets/locale/messages_lt.json +13 -2
- package/dist/esm/assets/locale/messages_ms.json +13 -2
- package/dist/esm/assets/locale/messages_nl.json +11 -0
- package/dist/esm/assets/locale/messages_no.json +11 -0
- package/dist/esm/assets/locale/messages_pl.json +11 -0
- package/dist/esm/assets/locale/messages_pt.json +11 -0
- package/dist/esm/assets/locale/messages_ro.json +13 -2
- package/dist/esm/assets/locale/messages_ru.json +11 -0
- package/dist/esm/assets/locale/messages_sk.json +13 -2
- package/dist/esm/assets/locale/messages_sl.json +13 -2
- package/dist/esm/assets/locale/messages_sv.json +11 -0
- package/dist/esm/assets/locale/messages_th.json +11 -0
- package/dist/esm/assets/locale/messages_tl.json +13 -2
- package/dist/esm/assets/locale/messages_tr.json +11 -0
- package/dist/esm/assets/locale/messages_uk.json +11 -0
- package/dist/esm/assets/locale/messages_vi.json +11 -0
- package/dist/esm/assets/locale/messages_zh.json +11 -0
- package/dist/esm/assets/locale/version_file +1 -1
- package/dist/esm/assets/visual-e2e-locale/messages_visuale2e.json +29 -2
- package/dist/esm/hooks/index.js +1 -1
- package/dist/esm/hooks/index.js.map +1 -1
- package/dist/esm/hooks/useImport.js +3 -1
- package/dist/esm/hooks/useImport.js.map +1 -1
- package/dist/esm/hooks/useSchemaSource.js +7 -0
- package/dist/esm/hooks/useSchemaSource.js.map +1 -0
- package/dist/esm/index.js +1 -2
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/state/CustomFieldModalState.js +8 -0
- package/dist/esm/state/CustomFieldModalState.js.map +1 -1
- package/dist/esm/state/ImportState/ImportState.js +306 -113
- package/dist/esm/state/ImportState/ImportState.js.map +1 -1
- package/dist/esm/state/ImportState/__tests__/ImportState.engine.spec.js +297 -70
- package/dist/esm/state/ImportState/__tests__/ImportState.engine.spec.js.map +1 -1
- package/dist/esm/state/ImportState/__tests__/buildImportConfig.spec.js +100 -0
- package/dist/esm/state/ImportState/__tests__/buildImportConfig.spec.js.map +1 -0
- package/dist/esm/state/ImportState/detectFieldType.js +34 -15
- package/dist/esm/state/ImportState/detectFieldType.js.map +1 -1
- package/dist/esm/state/ImportState/fieldEdit.js +44 -0
- package/dist/esm/state/ImportState/fieldEdit.js.map +1 -1
- package/dist/esm/state/SourceState.js +131 -0
- package/dist/esm/state/SourceState.js.map +1 -0
- package/dist/esm/state/index.js +1 -0
- package/dist/esm/state/index.js.map +1 -1
- package/dist/esm/testkit/createInMemorySchemaSource.js +141 -0
- package/dist/esm/testkit/createInMemorySchemaSource.js.map +1 -0
- package/dist/esm/testkit/hubJobImportMocks.js +17 -1
- package/dist/esm/testkit/hubJobImportMocks.js.map +1 -1
- package/dist/esm/testkit/index.js +1 -0
- package/dist/esm/testkit/index.js.map +1 -1
- package/dist/esm/types/SchemaSource.js +21 -14
- package/dist/esm/types/SchemaSource.js.map +1 -1
- package/dist/types/hooks/index.d.ts +1 -1
- package/dist/types/hooks/index.d.ts.map +1 -1
- package/dist/types/hooks/useImport.d.ts +9 -3
- package/dist/types/hooks/useImport.d.ts.map +1 -1
- package/dist/types/hooks/useSchemaSource.d.ts +4 -0
- package/dist/types/hooks/useSchemaSource.d.ts.map +1 -0
- package/dist/types/index.d.ts +2 -3
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/services/translations.d.ts +7 -1
- package/dist/types/services/translations.d.ts.map +1 -1
- package/dist/types/state/CustomFieldModalState.d.ts +9 -0
- package/dist/types/state/CustomFieldModalState.d.ts.map +1 -1
- package/dist/types/state/ImportState/ImportState.d.ts +208 -65
- package/dist/types/state/ImportState/ImportState.d.ts.map +1 -1
- package/dist/types/state/ImportState/__tests__/buildImportConfig.spec.d.ts +2 -0
- package/dist/types/state/ImportState/__tests__/buildImportConfig.spec.d.ts.map +1 -0
- package/dist/types/state/ImportState/detectFieldType.d.ts +5 -0
- package/dist/types/state/ImportState/detectFieldType.d.ts.map +1 -1
- package/dist/types/state/ImportState/fieldEdit.d.ts +6 -0
- package/dist/types/state/ImportState/fieldEdit.d.ts.map +1 -1
- package/dist/types/state/SourceState.d.ts +39 -0
- package/dist/types/state/SourceState.d.ts.map +1 -0
- package/dist/types/state/index.d.ts +1 -0
- package/dist/types/state/index.d.ts.map +1 -1
- package/dist/types/testkit/WixPatternsContainer.driver.d.ts +4 -0
- package/dist/types/testkit/WixPatternsContainer.driver.d.ts.map +1 -1
- package/dist/types/testkit/createInMemorySchemaSource.d.ts +43 -0
- package/dist/types/testkit/createInMemorySchemaSource.d.ts.map +1 -0
- package/dist/types/testkit/hubJobImportMocks.d.ts +11 -1
- package/dist/types/testkit/hubJobImportMocks.d.ts.map +1 -1
- package/dist/types/testkit/index.d.ts +1 -0
- package/dist/types/testkit/index.d.ts.map +1 -1
- package/dist/types/types/Field.d.ts +3 -0
- package/dist/types/types/Field.d.ts.map +1 -1
- package/dist/types/types/Schema.d.ts +10 -6
- package/dist/types/types/Schema.d.ts.map +1 -1
- package/dist/types/types/SchemaSource.d.ts +30 -13
- package/dist/types/types/SchemaSource.d.ts.map +1 -1
- package/package.json +4 -4
- package/dist/cjs/hooks/useImportConfig.js +0 -12
- package/dist/cjs/hooks/useImportConfig.js.map +0 -1
- package/dist/esm/hooks/useImportConfig.js +0 -6
- package/dist/esm/hooks/useImportConfig.js.map +0 -1
- package/dist/types/hooks/useImportConfig.d.ts +0 -5
- package/dist/types/hooks/useImportConfig.d.ts.map +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["_SchemaSource","require","_InMemoryBackend","ALL_PERMISSIONS","createField","updateField","deleteField","DEFAULT_CREATABLE_FIELD_TYPES","patternsType","createInMemorySchemaSource","config","_config$fields$","collectionId","idField","displayField","fields","id","schemaPermissions","itemPermissions","creatableFieldTypes","supportsPii","references","forEach","field","schema","keyOf","item","String","fieldsSnapshot","seed","items","backend","InMemoryBackend","paginationMode","total","length","createOne","index","itemKey","collectionBackend","find","query","offset","fetchDataSync","hasNext","get","entityId","Error","create","entity","created","map","set","update","delete","bulkDelete","entityIds","bulkInsert","entities","succeeded","failed","fieldActions","addField","addFields","newFields","editField","fieldId","updates","current","Reflect","deleteProperty","renameField","newName","displayName","makePrimary","loadSchema","source","defineSchemaSource"],"sources":["../../../src/testkit/createInMemorySchemaSource.ts"],"sourcesContent":["import {\n defineSchemaSource,\n type CreatableFieldType,\n type SchemaSource,\n} from '../types/SchemaSource';\nimport type {\n CollectionBackend,\n FieldActions,\n ItemPermissions,\n LoadedSchema,\n Schema,\n SchemaPermissions,\n} from '../types/Schema';\nimport type { Field } from '../types/Field';\nimport type { OffsetQuery } from '../hooks/paginationModeConfig';\nimport { InMemoryBackend } from '../InMemoryBackend';\n\nconst ALL_PERMISSIONS: SchemaPermissions = {\n createField: true,\n updateField: true,\n deleteField: true,\n};\n\n// The types the add/edit modal offers by default (the ones @wix/data can create).\nconst DEFAULT_CREATABLE_FIELD_TYPES: CreatableFieldType[] = [\n { patternsType: 'SHORT_TEXT' },\n { patternsType: 'NUMBER' },\n { patternsType: 'BOOLEAN' },\n { patternsType: 'DATE' },\n];\n\nexport interface InMemorySchemaSource<T> {\n /** The source to pass anywhere a schema source is accepted. */\n source: SchemaSource<T>;\n /** The in-memory backend holding the rows — read or mutate them directly. */\n backend: InMemoryBackend<T>;\n}\n\nexport interface InMemorySchemaSourceConfig<T> {\n collectionId: string;\n /** The collection's fields (keyed internally by `field.id`). */\n fields: Field[];\n /** Seed rows the backend serves via `find`/`get`. */\n items?: T[];\n /** Defaults to the first field's id, else `idField`. */\n displayField?: string;\n /** Defaults to `_id`. */\n idField?: string;\n /** Defaults to all-true (add/edit/delete allowed). */\n schemaPermissions?: SchemaPermissions;\n itemPermissions?: ItemPermissions;\n /** Types the add-field modal offers. Defaults to text/number/boolean/date. */\n creatableFieldTypes?: CreatableFieldType[];\n supportsPii?: boolean;\n /** Sources for referenced collections, keyed by referenced collection id. */\n references?: Record<string, SchemaSource<any>>;\n}\n\n/**\n * Builds a real `SchemaSource<T>` backed by in-memory state — no data source (no\n * `@wix/data`, no network). Its backend `find` serves the seeded `items`, and\n * its `fieldActions` mutate the in-memory schema and return the updated fields\n * map, so the create-new-field import flow works end to end (the created column\n * surfaces via the schema-source merge).\n *\n * Returns `{ source, backend }`. Pass `source` anywhere a `SchemaSource` is\n * accepted — a `@wix/patterns/schema` collection hook, or `<Table\n * fieldsSource={...} />` (which the import reads from). Use `backend` to read or\n * assert on the in-memory rows directly.\n */\nexport function createInMemorySchemaSource<\n T extends Record<string, unknown> = Record<string, unknown>,\n>(config: InMemorySchemaSourceConfig<T>): InMemorySchemaSource<T> {\n const {\n collectionId,\n idField = '_id',\n displayField = config.fields[0]?.id ?? idField,\n schemaPermissions = ALL_PERMISSIONS,\n itemPermissions,\n creatableFieldTypes = DEFAULT_CREATABLE_FIELD_TYPES,\n supportsPii = false,\n references,\n } = config;\n\n // Mutable in-memory state shared by the backend, schema, and field actions.\n const fields: Schema['fields'] = {};\n config.fields.forEach((field) => {\n fields[field.id] = field;\n });\n\n const schema: Schema = {\n id: collectionId,\n fields,\n displayField,\n idField,\n schemaPermissions,\n ...(itemPermissions && { itemPermissions }),\n };\n\n const keyOf = (item: T): string =>\n String((item as Record<string, unknown>)[idField] ?? '');\n // A fresh copy each mutation, so the schema-source merge sees a new map.\n const fieldsSnapshot = (): Schema['fields'] => ({ ...fields });\n\n // The shared `InMemoryBackend` holds the rows and runs the query logic\n // (ordering, filtering, pagination). The `collectionBackend` below adapts it\n // to the source-neutral contract. Mutations write straight to `backend.map`\n // and reads use the synchronous surface, so operations resolve without the\n // util's simulated async delay (which relies on timers the test suite freezes).\n const seed = config.items ?? [];\n const backend = new InMemoryBackend<T>({\n paginationMode: 'offset',\n total: seed.length,\n createOne: (index) => seed[index],\n itemKey: keyOf,\n });\n\n const collectionBackend: CollectionBackend<T> = {\n paginationMode: 'offset',\n find: async (query: OffsetQuery) => {\n const offset = query.offset ?? 0;\n const { items, total = 0 } = backend.fetchDataSync(query);\n return { items, total, hasNext: offset + items.length < total };\n },\n get: async (entityId) => {\n const item = backend.get(entityId);\n if (!item) {\n throw new Error(`Item \"${entityId}\" not found`);\n }\n return item;\n },\n create: async (entity) => {\n const created = { ...entity } as T;\n backend.map.set(keyOf(created), created);\n return created;\n },\n update: async (entity) => {\n backend.map.set(keyOf(entity), entity);\n return entity;\n },\n delete: async (entityId) => {\n backend.map.delete(entityId);\n },\n bulkDelete: async (entityIds) => {\n entityIds.forEach((entityId) => backend.map.delete(entityId));\n },\n bulkInsert: async (entities) => {\n entities.forEach((entity) => {\n const created = { ...entity } as T;\n backend.map.set(keyOf(created), created);\n });\n return { succeeded: entities.length, failed: 0 };\n },\n };\n\n const fieldActions: FieldActions = {\n addField: async (field) => {\n fields[field.id] = field;\n return fieldsSnapshot();\n },\n addFields: async (newFields) => {\n newFields.forEach((field) => {\n fields[field.id] = field;\n });\n return fieldsSnapshot();\n },\n editField: async (fieldId, updates) => {\n const current = fields[fieldId];\n if (current) {\n fields[fieldId] = { ...current, ...updates } as Field;\n }\n return fieldsSnapshot();\n },\n deleteField: async (fieldId) => {\n Reflect.deleteProperty(fields, fieldId);\n return fieldsSnapshot();\n },\n renameField: async (fieldId, newName) => {\n const current = fields[fieldId];\n if (current) {\n fields[fieldId] = { ...current, displayName: newName } as Field;\n }\n },\n makePrimary: async (fieldId) => {\n schema.displayField = fieldId;\n return fieldsSnapshot();\n },\n };\n\n const loadSchema = async (): Promise<LoadedSchema<T>> => ({\n schema,\n backend: collectionBackend,\n fieldActions,\n });\n\n const source = defineSchemaSource<T>({\n collectionId,\n loadSchema,\n creatableFieldTypes,\n supportsPii,\n ...(references && { references }),\n });\n\n return { source, backend };\n}\n"],"mappings":"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","ignoreList":[]}
|
|
@@ -20,6 +20,10 @@ function hubJobImportMocks(whenRequest, when) {
|
|
|
20
20
|
outcome: 'completed',
|
|
21
21
|
succeeded: 0,
|
|
22
22
|
failed: 0,
|
|
23
|
+
/** new items created (subset of `succeeded`), for the summary step */
|
|
24
|
+
created: 0,
|
|
25
|
+
/** existing items updated (subset of `succeeded`), for the summary step */
|
|
26
|
+
updated: 0,
|
|
23
27
|
/** number of IN_PROGRESS polls before the job goes terminal */
|
|
24
28
|
inProgressPolls: 0,
|
|
25
29
|
/** csvRows indices reported as failed via movement logs */
|
|
@@ -41,7 +45,11 @@ function hubJobImportMocks(whenRequest, when) {
|
|
|
41
45
|
current: total(),
|
|
42
46
|
total: total(),
|
|
43
47
|
itemsSuccessful: state.succeeded,
|
|
44
|
-
itemsRejected: state.failed
|
|
48
|
+
itemsRejected: state.failed,
|
|
49
|
+
itemsSuccessfulInfo: {
|
|
50
|
+
itemsCreated: state.created,
|
|
51
|
+
itemsUpdated: state.updated
|
|
52
|
+
}
|
|
45
53
|
},
|
|
46
54
|
...(state.outcome === 'failed' && {
|
|
47
55
|
error: {
|
|
@@ -52,11 +60,17 @@ function hubJobImportMocks(whenRequest, when) {
|
|
|
52
60
|
});
|
|
53
61
|
return {
|
|
54
62
|
state,
|
|
55
|
-
/**
|
|
63
|
+
/**
|
|
64
|
+
* Set the job's terminal outcome and its counts. `created`/`updated` are the
|
|
65
|
+
* split of `succeeded` reported to the summary step; when omitted they
|
|
66
|
+
* default so `created` covers all successes (older jobs report neither).
|
|
67
|
+
*/
|
|
56
68
|
setOutcome(outcome, counts = {}) {
|
|
57
69
|
state.outcome = outcome;
|
|
58
70
|
state.succeeded = counts.succeeded ?? 0;
|
|
59
71
|
state.failed = counts.failed ?? 0;
|
|
72
|
+
state.updated = counts.updated ?? 0;
|
|
73
|
+
state.created = counts.created ?? state.succeeded - state.updated;
|
|
60
74
|
},
|
|
61
75
|
/** Make the job report IN_PROGRESS for `n` polls before going terminal. */
|
|
62
76
|
setInProgressPolls(n) {
|
|
@@ -95,6 +109,8 @@ function hubJobImportMocks(whenRequest, when) {
|
|
|
95
109
|
state.outcome = 'completed';
|
|
96
110
|
state.succeeded = 0;
|
|
97
111
|
state.failed = 0;
|
|
112
|
+
state.created = 0;
|
|
113
|
+
state.updated = 0;
|
|
98
114
|
state.inProgressPolls = 0;
|
|
99
115
|
state.failedRowIndices = [];
|
|
100
116
|
state.uploadedBody = undefined;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["_http","require","_types","UPLOAD_BASE","UPLOAD_PATH","FILE_ID","JOB_ID","hubJobImportMocks","whenRequest","when","state","outcome","succeeded","failed","inProgressPolls","failedRowIndices","uploadedBody","undefined","submittedRequest","submittedJobId","terminatedJobIds","pollCounts","Map","terminalStatus","JobStatus","FAILED","PARTIALLY_SUCCESSFUL","COMPLETED","total","terminalJob","id","status","progress","current","itemsSuccessful","itemsRejected","error","code","description","setOutcome","counts","setInProgressPolls","n","setFailedRowIndices","indices","getUploadedCsv","body","blob","text","arrayBuffer","TextDecoder","decode","Promise","resolve","reject","reader","FileReader","onload","String","result","onerror","readAsText","reset","clear","mocks","createFileUploadUrl","reply","uploadUrl","fileId","persist","put","data","submitJob","payload","set","job","INITIALIZING","getJob","seen","get","jobId","IN_PROGRESS","terminateJob","push","listMovementLogs","logs","map","index","sourceItemId","failure","pagingMetadata","hasNext"],"sources":["../../../src/testkit/hubJobImportMocks.ts"],"sourcesContent":["import {\n createFileUploadUrl,\n submitJob,\n getJob,\n terminateJob,\n listMovementLogs,\n} from '@wix/bex-utils/@wix/ambassador-hub-v1-job/http';\nimport {\n JobStatus,\n type DataMovementJob,\n type SubmitJobRequest,\n} from '@wix/bex-utils/@wix/ambassador-hub-v1-job/types';\n\nconst UPLOAD_BASE = 'https://import-upload.test';\nconst UPLOAD_PATH = '/file';\nconst FILE_ID = 'file-1';\nconst JOB_ID = 'job-1';\n\nexport type ImportJobOutcome = 'completed' | 'partial' | 'failed';\n\n/**\n * Test mocks for the data-hub Hub Job import lifecycle, mirroring\n * `exportServiceMocks`. Auto-included in the test container's httpClient\n * scenarios so every import test drives a fake server. Behavior is controllable\n * per test via `setOutcome` / `setInProgressPolls`, and the uploaded (aligned)\n * CSV + the submitted job request are captured for assertions.\n */\nexport function hubJobImportMocks(\n whenRequest: typeof import('@wix/http-client-testkit/client').whenRequest,\n when: typeof import('@wix/http-client-testkit/client').when,\n) {\n const state = {\n outcome: 'completed' as ImportJobOutcome,\n succeeded: 0,\n failed: 0,\n /** number of IN_PROGRESS polls before the job goes terminal */\n inProgressPolls: 0,\n /** csvRows indices reported as failed via movement logs */\n failedRowIndices: [] as number[],\n /** the raw body PUT to the signed upload URL (the aligned CSV File) */\n uploadedBody: undefined as unknown,\n /** the SubmitJobRequest payload */\n submittedRequest: undefined as SubmitJobRequest | undefined,\n submittedJobId: undefined as string | undefined,\n terminatedJobIds: [] as string[],\n };\n\n const pollCounts = new Map<string, number>();\n\n const terminalStatus = (): JobStatus =>\n state.outcome === 'failed'\n ? JobStatus.FAILED\n : state.outcome === 'partial'\n ? JobStatus.PARTIALLY_SUCCESSFUL\n : JobStatus.COMPLETED;\n\n const total = () => state.succeeded + state.failed;\n\n const terminalJob = (id: string): DataMovementJob => ({\n id,\n status: terminalStatus(),\n progress: {\n current: total(),\n total: total(),\n itemsSuccessful: state.succeeded,\n itemsRejected: state.failed,\n },\n ...(state.outcome === 'failed' && {\n error: { code: 'import_failed', description: 'Import job failed' },\n }),\n });\n\n return {\n state,\n\n /** Set the job's terminal outcome and its success/failure counts. */\n setOutcome(\n outcome: ImportJobOutcome,\n counts: { succeeded?: number; failed?: number } = {},\n ) {\n state.outcome = outcome;\n state.succeeded = counts.succeeded ?? 0;\n state.failed = counts.failed ?? 0;\n },\n\n /** Make the job report IN_PROGRESS for `n` polls before going terminal. */\n setInProgressPolls(n: number) {\n state.inProgressPolls = n;\n },\n\n /** Row indices `listMovementLogs` reports as failed (sourceItemId). */\n setFailedRowIndices(indices: number[]) {\n state.failedRowIndices = indices;\n },\n\n /** The aligned CSV uploaded to the signed URL, as text. */\n async getUploadedCsv(): Promise<string> {\n const body = state.uploadedBody;\n if (body == null) {\n return '';\n }\n if (typeof body === 'string') {\n return body;\n }\n const blob = body as Blob;\n // jsdom's File implements neither text() nor arrayBuffer() here, so fall\n // back to FileReader.\n if (typeof blob.text === 'function') {\n return blob.text();\n }\n if (typeof blob.arrayBuffer === 'function') {\n return new TextDecoder().decode(await blob.arrayBuffer());\n }\n return new Promise<string>((resolve, reject) => {\n const reader = new FileReader();\n reader.onload = () => resolve(String(reader.result));\n reader.onerror = () => reject(reader.error);\n reader.readAsText(blob);\n });\n },\n\n reset() {\n state.outcome = 'completed';\n state.succeeded = 0;\n state.failed = 0;\n state.inProgressPolls = 0;\n state.failedRowIndices = [];\n state.uploadedBody = undefined;\n state.submittedRequest = undefined;\n state.submittedJobId = undefined;\n state.terminatedJobIds = [];\n pollCounts.clear();\n },\n\n mocks: [\n whenRequest(createFileUploadUrl)\n .reply(200, {\n uploadUrl: `${UPLOAD_BASE}${UPLOAD_PATH}`,\n fileId: FILE_ID,\n })\n .persist(),\n\n when(UPLOAD_BASE)\n .put(UPLOAD_PATH)\n .reply(200, (data: unknown) => {\n state.uploadedBody = data;\n return {};\n })\n .persist(),\n\n whenRequest(submitJob)\n .reply(200, (payload: SubmitJobRequest) => {\n state.submittedRequest = payload;\n state.submittedJobId = JOB_ID;\n pollCounts.set(JOB_ID, 0);\n return {\n job: {\n id: JOB_ID,\n status: JobStatus.INITIALIZING,\n progress: { current: 0, total: total() },\n },\n };\n })\n .persist(),\n\n whenRequest(getJob)\n .reply(200, (payload: { jobId: string }) => {\n const seen = pollCounts.get(payload.jobId) ?? 0;\n pollCounts.set(payload.jobId, seen + 1);\n\n if (seen < state.inProgressPolls) {\n // No `total` here so ImportState keeps its initial CSV-row total;\n // `current` is 0-based so the first poll reports nothing processed.\n return {\n job: {\n id: payload.jobId,\n status: JobStatus.IN_PROGRESS,\n progress: {\n current: seen,\n itemsSuccessful: seen,\n itemsRejected: 0,\n },\n },\n };\n }\n\n return { job: terminalJob(payload.jobId) };\n })\n .persist(),\n\n whenRequest(terminateJob)\n .reply(200, (payload: { jobId: string }) => {\n state.terminatedJobIds.push(payload.jobId);\n return {};\n })\n .persist(),\n\n whenRequest(listMovementLogs)\n .reply(200, () => ({\n // data-hub formats a CSV item's sourceItemId as \"row N\", where N is\n // the 1-based file line (header is line 1) — so csvRows[i] is \"row i+2\".\n logs: state.failedRowIndices.map((index) => ({\n sourceItemId: `row ${index + 2}`,\n failure: { code: 'row_failed', description: 'Invalid row' },\n })),\n pagingMetadata: { hasNext: false },\n }))\n .persist(),\n ] as import('@wix/http-client-testkit').AnyScenario[],\n };\n}\n"],"mappings":"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","ignoreList":[]}
|
|
1
|
+
{"version":3,"names":["_http","require","_types","UPLOAD_BASE","UPLOAD_PATH","FILE_ID","JOB_ID","hubJobImportMocks","whenRequest","when","state","outcome","succeeded","failed","created","updated","inProgressPolls","failedRowIndices","uploadedBody","undefined","submittedRequest","submittedJobId","terminatedJobIds","pollCounts","Map","terminalStatus","JobStatus","FAILED","PARTIALLY_SUCCESSFUL","COMPLETED","total","terminalJob","id","status","progress","current","itemsSuccessful","itemsRejected","itemsSuccessfulInfo","itemsCreated","itemsUpdated","error","code","description","setOutcome","counts","setInProgressPolls","n","setFailedRowIndices","indices","getUploadedCsv","body","blob","text","arrayBuffer","TextDecoder","decode","Promise","resolve","reject","reader","FileReader","onload","String","result","onerror","readAsText","reset","clear","mocks","createFileUploadUrl","reply","uploadUrl","fileId","persist","put","data","submitJob","payload","set","job","INITIALIZING","getJob","seen","get","jobId","IN_PROGRESS","terminateJob","push","listMovementLogs","logs","map","index","sourceItemId","failure","pagingMetadata","hasNext"],"sources":["../../../src/testkit/hubJobImportMocks.ts"],"sourcesContent":["import {\n createFileUploadUrl,\n submitJob,\n getJob,\n terminateJob,\n listMovementLogs,\n} from '@wix/bex-utils/@wix/ambassador-hub-v1-job/http';\nimport {\n JobStatus,\n type DataMovementJob,\n type SubmitJobRequest,\n} from '@wix/bex-utils/@wix/ambassador-hub-v1-job/types';\n\nconst UPLOAD_BASE = 'https://import-upload.test';\nconst UPLOAD_PATH = '/file';\nconst FILE_ID = 'file-1';\nconst JOB_ID = 'job-1';\n\nexport type ImportJobOutcome = 'completed' | 'partial' | 'failed';\n\n/**\n * Test mocks for the data-hub Hub Job import lifecycle, mirroring\n * `exportServiceMocks`. Auto-included in the test container's httpClient\n * scenarios so every import test drives a fake server. Behavior is controllable\n * per test via `setOutcome` / `setInProgressPolls`, and the uploaded (aligned)\n * CSV + the submitted job request are captured for assertions.\n */\nexport function hubJobImportMocks(\n whenRequest: typeof import('@wix/http-client-testkit/client').whenRequest,\n when: typeof import('@wix/http-client-testkit/client').when,\n) {\n const state = {\n outcome: 'completed' as ImportJobOutcome,\n succeeded: 0,\n failed: 0,\n /** new items created (subset of `succeeded`), for the summary step */\n created: 0,\n /** existing items updated (subset of `succeeded`), for the summary step */\n updated: 0,\n /** number of IN_PROGRESS polls before the job goes terminal */\n inProgressPolls: 0,\n /** csvRows indices reported as failed via movement logs */\n failedRowIndices: [] as number[],\n /** the raw body PUT to the signed upload URL (the aligned CSV File) */\n uploadedBody: undefined as unknown,\n /** the SubmitJobRequest payload */\n submittedRequest: undefined as SubmitJobRequest | undefined,\n submittedJobId: undefined as string | undefined,\n terminatedJobIds: [] as string[],\n };\n\n const pollCounts = new Map<string, number>();\n\n const terminalStatus = (): JobStatus =>\n state.outcome === 'failed'\n ? JobStatus.FAILED\n : state.outcome === 'partial'\n ? JobStatus.PARTIALLY_SUCCESSFUL\n : JobStatus.COMPLETED;\n\n const total = () => state.succeeded + state.failed;\n\n const terminalJob = (id: string): DataMovementJob => ({\n id,\n status: terminalStatus(),\n progress: {\n current: total(),\n total: total(),\n itemsSuccessful: state.succeeded,\n itemsRejected: state.failed,\n itemsSuccessfulInfo: {\n itemsCreated: state.created,\n itemsUpdated: state.updated,\n },\n },\n ...(state.outcome === 'failed' && {\n error: { code: 'import_failed', description: 'Import job failed' },\n }),\n });\n\n return {\n state,\n\n /**\n * Set the job's terminal outcome and its counts. `created`/`updated` are the\n * split of `succeeded` reported to the summary step; when omitted they\n * default so `created` covers all successes (older jobs report neither).\n */\n setOutcome(\n outcome: ImportJobOutcome,\n counts: {\n succeeded?: number;\n failed?: number;\n created?: number;\n updated?: number;\n } = {},\n ) {\n state.outcome = outcome;\n state.succeeded = counts.succeeded ?? 0;\n state.failed = counts.failed ?? 0;\n state.updated = counts.updated ?? 0;\n state.created = counts.created ?? state.succeeded - state.updated;\n },\n\n /** Make the job report IN_PROGRESS for `n` polls before going terminal. */\n setInProgressPolls(n: number) {\n state.inProgressPolls = n;\n },\n\n /** Row indices `listMovementLogs` reports as failed (sourceItemId). */\n setFailedRowIndices(indices: number[]) {\n state.failedRowIndices = indices;\n },\n\n /** The aligned CSV uploaded to the signed URL, as text. */\n async getUploadedCsv(): Promise<string> {\n const body = state.uploadedBody;\n if (body == null) {\n return '';\n }\n if (typeof body === 'string') {\n return body;\n }\n const blob = body as Blob;\n // jsdom's File implements neither text() nor arrayBuffer() here, so fall\n // back to FileReader.\n if (typeof blob.text === 'function') {\n return blob.text();\n }\n if (typeof blob.arrayBuffer === 'function') {\n return new TextDecoder().decode(await blob.arrayBuffer());\n }\n return new Promise<string>((resolve, reject) => {\n const reader = new FileReader();\n reader.onload = () => resolve(String(reader.result));\n reader.onerror = () => reject(reader.error);\n reader.readAsText(blob);\n });\n },\n\n reset() {\n state.outcome = 'completed';\n state.succeeded = 0;\n state.failed = 0;\n state.created = 0;\n state.updated = 0;\n state.inProgressPolls = 0;\n state.failedRowIndices = [];\n state.uploadedBody = undefined;\n state.submittedRequest = undefined;\n state.submittedJobId = undefined;\n state.terminatedJobIds = [];\n pollCounts.clear();\n },\n\n mocks: [\n whenRequest(createFileUploadUrl)\n .reply(200, {\n uploadUrl: `${UPLOAD_BASE}${UPLOAD_PATH}`,\n fileId: FILE_ID,\n })\n .persist(),\n\n when(UPLOAD_BASE)\n .put(UPLOAD_PATH)\n .reply(200, (data: unknown) => {\n state.uploadedBody = data;\n return {};\n })\n .persist(),\n\n whenRequest(submitJob)\n .reply(200, (payload: SubmitJobRequest) => {\n state.submittedRequest = payload;\n state.submittedJobId = JOB_ID;\n pollCounts.set(JOB_ID, 0);\n return {\n job: {\n id: JOB_ID,\n status: JobStatus.INITIALIZING,\n progress: { current: 0, total: total() },\n },\n };\n })\n .persist(),\n\n whenRequest(getJob)\n .reply(200, (payload: { jobId: string }) => {\n const seen = pollCounts.get(payload.jobId) ?? 0;\n pollCounts.set(payload.jobId, seen + 1);\n\n if (seen < state.inProgressPolls) {\n // No `total` here so ImportState keeps its initial CSV-row total;\n // `current` is 0-based so the first poll reports nothing processed.\n return {\n job: {\n id: payload.jobId,\n status: JobStatus.IN_PROGRESS,\n progress: {\n current: seen,\n itemsSuccessful: seen,\n itemsRejected: 0,\n },\n },\n };\n }\n\n return { job: terminalJob(payload.jobId) };\n })\n .persist(),\n\n whenRequest(terminateJob)\n .reply(200, (payload: { jobId: string }) => {\n state.terminatedJobIds.push(payload.jobId);\n return {};\n })\n .persist(),\n\n whenRequest(listMovementLogs)\n .reply(200, () => ({\n // data-hub formats a CSV item's sourceItemId as \"row N\", where N is\n // the 1-based file line (header is line 1) — so csvRows[i] is \"row i+2\".\n logs: state.failedRowIndices.map((index) => ({\n sourceItemId: `row ${index + 2}`,\n failure: { code: 'row_failed', description: 'Invalid row' },\n })),\n pagingMetadata: { hasNext: false },\n }))\n .persist(),\n ] as import('@wix/http-client-testkit').AnyScenario[],\n };\n}\n"],"mappings":"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","ignoreList":[]}
|
|
@@ -31,6 +31,12 @@ Object.keys(_hubJobImportMocks).forEach(function (key) {
|
|
|
31
31
|
if (key in exports && exports[key] === _hubJobImportMocks[key]) return;
|
|
32
32
|
exports[key] = _hubJobImportMocks[key];
|
|
33
33
|
});
|
|
34
|
+
var _createInMemorySchemaSource = require("./createInMemorySchemaSource");
|
|
35
|
+
Object.keys(_createInMemorySchemaSource).forEach(function (key) {
|
|
36
|
+
if (key === "default" || key === "__esModule") return;
|
|
37
|
+
if (key in exports && exports[key] === _createInMemorySchemaSource[key]) return;
|
|
38
|
+
exports[key] = _createInMemorySchemaSource[key];
|
|
39
|
+
});
|
|
34
40
|
var _flush = require("../test-utils/flush");
|
|
35
41
|
Object.keys(_flush).forEach(function (key) {
|
|
36
42
|
if (key === "default" || key === "__esModule") return;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["_product","require","Object","keys","forEach","key","exports","_productFilters","_createProductsBackend","_exportServiceMocks","_hubJobImportMocks","_flush","_folder","_createFoldersBackend","_country","_createCountriesBackend","_appSettingsMocks"],"sources":["../../../src/testkit/index.ts"],"sourcesContent":["export * from './product';\nexport * from './productFilters';\nexport * from './createProductsBackend';\nexport * from './exportServiceMocks';\nexport * from './hubJobImportMocks';\nexport * from '../test-utils/flush';\nexport * from './folder';\nexport * from './createFoldersBackend';\nexport * from './country';\nexport * from './createCountriesBackend';\nexport * from './appSettingsMocks';\n"],"mappings":";;;AAAA,IAAAA,QAAA,GAAAC,OAAA;AAAAC,MAAA,CAAAC,IAAA,CAAAH,QAAA,EAAAI,OAAA,WAAAC,GAAA;EAAA,IAAAA,GAAA,kBAAAA,GAAA;EAAA,IAAAA,GAAA,IAAAC,OAAA,IAAAA,OAAA,CAAAD,GAAA,MAAAL,QAAA,CAAAK,GAAA;EAAAC,OAAA,CAAAD,GAAA,IAAAL,QAAA,CAAAK,GAAA;AAAA;AACA,IAAAE,eAAA,GAAAN,OAAA;AAAAC,MAAA,CAAAC,IAAA,CAAAI,eAAA,EAAAH,OAAA,WAAAC,GAAA;EAAA,IAAAA,GAAA,kBAAAA,GAAA;EAAA,IAAAA,GAAA,IAAAC,OAAA,IAAAA,OAAA,CAAAD,GAAA,MAAAE,eAAA,CAAAF,GAAA;EAAAC,OAAA,CAAAD,GAAA,IAAAE,eAAA,CAAAF,GAAA;AAAA;AACA,IAAAG,sBAAA,GAAAP,OAAA;AAAAC,MAAA,CAAAC,IAAA,CAAAK,sBAAA,EAAAJ,OAAA,WAAAC,GAAA;EAAA,IAAAA,GAAA,kBAAAA,GAAA;EAAA,IAAAA,GAAA,IAAAC,OAAA,IAAAA,OAAA,CAAAD,GAAA,MAAAG,sBAAA,CAAAH,GAAA;EAAAC,OAAA,CAAAD,GAAA,IAAAG,sBAAA,CAAAH,GAAA;AAAA;AACA,IAAAI,mBAAA,GAAAR,OAAA;AAAAC,MAAA,CAAAC,IAAA,CAAAM,mBAAA,EAAAL,OAAA,WAAAC,GAAA;EAAA,IAAAA,GAAA,kBAAAA,GAAA;EAAA,IAAAA,GAAA,IAAAC,OAAA,IAAAA,OAAA,CAAAD,GAAA,MAAAI,mBAAA,CAAAJ,GAAA;EAAAC,OAAA,CAAAD,GAAA,IAAAI,mBAAA,CAAAJ,GAAA;AAAA;AACA,IAAAK,kBAAA,GAAAT,OAAA;AAAAC,MAAA,CAAAC,IAAA,CAAAO,kBAAA,EAAAN,OAAA,WAAAC,GAAA;EAAA,IAAAA,GAAA,kBAAAA,GAAA;EAAA,IAAAA,GAAA,IAAAC,OAAA,IAAAA,OAAA,CAAAD,GAAA,MAAAK,kBAAA,CAAAL,GAAA;EAAAC,OAAA,CAAAD,GAAA,IAAAK,kBAAA,CAAAL,GAAA;AAAA;AACA,IAAAM,
|
|
1
|
+
{"version":3,"names":["_product","require","Object","keys","forEach","key","exports","_productFilters","_createProductsBackend","_exportServiceMocks","_hubJobImportMocks","_createInMemorySchemaSource","_flush","_folder","_createFoldersBackend","_country","_createCountriesBackend","_appSettingsMocks"],"sources":["../../../src/testkit/index.ts"],"sourcesContent":["export * from './product';\nexport * from './productFilters';\nexport * from './createProductsBackend';\nexport * from './exportServiceMocks';\nexport * from './hubJobImportMocks';\nexport * from './createInMemorySchemaSource';\nexport * from '../test-utils/flush';\nexport * from './folder';\nexport * from './createFoldersBackend';\nexport * from './country';\nexport * from './createCountriesBackend';\nexport * from './appSettingsMocks';\n"],"mappings":"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","ignoreList":[]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":[],"sources":["../../../src/types/Field.ts"],"sourcesContent":["export type PatternsFieldType =\n | 'SHORT_TEXT'\n | 'LONG_TEXT'\n | 'NUMBER'\n | 'BOOLEAN'\n | 'DATE'\n | 'DATETIME'\n | 'TIME'\n | 'URL'\n | 'ARRAY'\n | 'REFERENCE'\n | 'MULTI_REFERENCE'\n | 'OBJECT'\n | 'IMAGE'\n | 'VIDEO'\n | 'MEDIA_GALLERY'\n | 'ADDRESS'\n | 'RICH_TEXT'\n | 'DOCUMENT'\n | 'RICH_CONTENT'\n | 'MULTI_DOCUMENT'\n | 'EMAIL'\n | 'AUDIO'\n | 'COLOR'\n | 'UNKNOWN';\n\nexport type QueryOperator =\n | 'CONTAINS'\n | 'ENDS_WITH'\n | 'EQ'\n | 'EXISTS'\n | 'GT'\n | 'GTE'\n | 'HAS_ALL'\n | 'HAS_SOME'\n | 'LT'\n | 'LTE'\n | 'NE'\n | 'STARTS_WITH'\n | 'URLIZED';\n\nexport interface NumberRange {\n min?: number;\n max?: number;\n}\n\nexport interface StringLengthRange {\n minLength?: number;\n maxLength?: number;\n}\n\ninterface BaseField {\n id: string;\n displayName: string;\n isPii?: boolean;\n helpText?: string;\n /** Whether this is a system-managed field (not user-created). */\n isSystem?: boolean;\n /** Whether this is the collection's primary display field. */\n isPrimary?: boolean;\n validation?: {\n numberRange?: NumberRange;\n stringLengthRange?: StringLengthRange;\n required: boolean;\n };\n capabilities?: {\n supportedQueryOperators: QueryOperator[];\n sortable: boolean;\n };\n}\n\nexport interface BaseReferenceField extends BaseField {\n referenceMetadata: {\n referencedCollectionId: string;\n };\n}\n\nexport interface ReferenceField extends BaseReferenceField {\n type: 'REFERENCE';\n}\n\nexport interface MultiReferenceField extends BaseReferenceField {\n type: 'MULTI_REFERENCE';\n}\n\nexport interface NonReferenceField extends BaseField {\n type: Exclude<PatternsFieldType, 'REFERENCE' | 'MULTI_REFERENCE'>;\n}\n\nexport type Field = ReferenceField | MultiReferenceField | NonReferenceField;\nexport type FieldSpec = Omit<Field, 'id'>;\n"],"mappings":"","ignoreList":[]}
|
|
1
|
+
{"version":3,"names":[],"sources":["../../../src/types/Field.ts"],"sourcesContent":["export type PatternsFieldType =\n | 'SHORT_TEXT'\n | 'LONG_TEXT'\n | 'NUMBER'\n | 'BOOLEAN'\n | 'DATE'\n | 'DATETIME'\n | 'TIME'\n | 'URL'\n | 'ARRAY'\n | 'REFERENCE'\n | 'MULTI_REFERENCE'\n | 'OBJECT'\n | 'IMAGE'\n | 'VIDEO'\n | 'MEDIA_GALLERY'\n | 'ADDRESS'\n | 'RICH_TEXT'\n | 'DOCUMENT'\n | 'RICH_CONTENT'\n | 'MULTI_DOCUMENT'\n | 'EMAIL'\n | 'AUDIO'\n | 'COLOR'\n | 'UNKNOWN';\n\nexport type QueryOperator =\n | 'CONTAINS'\n | 'ENDS_WITH'\n | 'EQ'\n | 'EXISTS'\n | 'GT'\n | 'GTE'\n | 'HAS_ALL'\n | 'HAS_SOME'\n | 'LT'\n | 'LTE'\n | 'NE'\n | 'STARTS_WITH'\n | 'URLIZED';\n\nexport interface NumberRange {\n min?: number;\n max?: number;\n}\n\nexport interface StringLengthRange {\n minLength?: number;\n maxLength?: number;\n}\n\ninterface BaseField {\n id: string;\n displayName: string;\n isPii?: boolean;\n helpText?: string;\n /** Whether this is a system-managed field (not user-created). */\n isSystem?: boolean;\n /** The group this field belongs to, when the source groups its fields.\n * Absent ⇒ ungrouped. */\n group?: string;\n /** Whether this is the collection's primary display field. */\n isPrimary?: boolean;\n validation?: {\n numberRange?: NumberRange;\n stringLengthRange?: StringLengthRange;\n required: boolean;\n };\n capabilities?: {\n supportedQueryOperators: QueryOperator[];\n sortable: boolean;\n };\n}\n\nexport interface BaseReferenceField extends BaseField {\n referenceMetadata: {\n referencedCollectionId: string;\n };\n}\n\nexport interface ReferenceField extends BaseReferenceField {\n type: 'REFERENCE';\n}\n\nexport interface MultiReferenceField extends BaseReferenceField {\n type: 'MULTI_REFERENCE';\n}\n\nexport interface NonReferenceField extends BaseField {\n type: Exclude<PatternsFieldType, 'REFERENCE' | 'MULTI_REFERENCE'>;\n}\n\nexport type Field = ReferenceField | MultiReferenceField | NonReferenceField;\nexport type FieldSpec = Omit<Field, 'id'>;\n"],"mappings":"","ignoreList":[]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":[],"sources":["../../../src/types/Schema.ts"],"sourcesContent":["import type { Field } from './Field';\nimport type { FiltersMap, OptionalFiltersMap } from '../model';\nimport type {\n OffsetQuery,\n OffsetQueryResult,\n CursorQuery,\n CursorQueryResult,\n FetchTotalFn,\n} from '../hooks/paginationModeConfig';\n\n/** Field-management permissions. Absent when the schema's fields cannot be edited. */\nexport interface SchemaPermissions {\n createField: boolean;\n updateField: boolean;\n deleteField: boolean;\n}\n\n/** Item-level CRUD permissions. */\nexport interface ItemPermissions {\n createItem: boolean;\n updateItem: boolean;\n deleteItem: boolean;\n}\n\n/**\n * A source-neutral description of a collection — data only, no behavior.\n * Item access is in `CollectionBackend`, field mutations in `FieldActions`.\n */\nexport interface Schema {\n id: string;\n fields: Record<string, Field | undefined>;\n /** The field that best represents the entity (titles/selections). */\n displayField: string;\n /** The identifier field. */\n idField: string;\n /** Absent when the schema's fields cannot be edited. */\n schemaPermissions?: SchemaPermissions;\n itemPermissions?: ItemPermissions;\n}\n\nexport interface BackupConfig {\n create: () => Promise<{ backupId: string }>;\n waitForCompletion: (\n backupId: string,\n options?: { signal?: AbortSignal },\n ) => Promise<void>;\n cancel?: (backupId: string) => Promise<void>;\n restore?: (backupId: string) => Promise<{ restorationId: string }>;\n waitForRestoration?: (\n restorationId: string,\n options?: { signal?: AbortSignal },\n ) => Promise<void>;\n}\n\nexport interface BulkInsertError {\n rowIndex: number;\n message?: string;\n code?: string;\n}\n\nexport interface BulkInsertResult {\n succeeded?: number;\n failed?: number;\n errors?: BulkInsertError[];\n}\n\n/** Item data access shared by both pagination modes. */\nexport interface CollectionBackendBase<T = Record<string, unknown>> {\n get
|
|
1
|
+
{"version":3,"names":[],"sources":["../../../src/types/Schema.ts"],"sourcesContent":["import type { Field } from './Field';\nimport type { FiltersMap, OptionalFiltersMap } from '../model';\nimport type {\n OffsetQuery,\n OffsetQueryResult,\n CursorQuery,\n CursorQueryResult,\n FetchTotalFn,\n} from '../hooks/paginationModeConfig';\n\n/** Field-management permissions. Absent when the schema's fields cannot be edited. */\nexport interface SchemaPermissions {\n createField: boolean;\n updateField: boolean;\n deleteField: boolean;\n}\n\n/** Item-level CRUD permissions. */\nexport interface ItemPermissions {\n createItem: boolean;\n updateItem: boolean;\n deleteItem: boolean;\n}\n\n/**\n * A source-neutral description of a collection — data only, no behavior.\n * Item access is in `CollectionBackend`, field mutations in `FieldActions`.\n */\nexport interface Schema {\n id: string;\n fields: Record<string, Field | undefined>;\n /** The field that best represents the entity (titles/selections). */\n displayField: string;\n /** The identifier field. */\n idField: string;\n /** Group display order, present when fields carry a `group`. */\n groups?: string[];\n /** Absent when the schema's fields cannot be edited. */\n schemaPermissions?: SchemaPermissions;\n itemPermissions?: ItemPermissions;\n}\n\nexport interface BackupConfig {\n create: () => Promise<{ backupId: string }>;\n waitForCompletion: (\n backupId: string,\n options?: { signal?: AbortSignal },\n ) => Promise<void>;\n cancel?: (backupId: string) => Promise<void>;\n restore?: (backupId: string) => Promise<{ restorationId: string }>;\n waitForRestoration?: (\n restorationId: string,\n options?: { signal?: AbortSignal },\n ) => Promise<void>;\n}\n\nexport interface BulkInsertError {\n rowIndex: number;\n message?: string;\n code?: string;\n}\n\nexport interface BulkInsertResult {\n succeeded?: number;\n failed?: number;\n errors?: BulkInsertError[];\n}\n\n/** Item data access shared by both pagination modes. `find` (on\n * `CollectionBackend`) is the only required call — the rest are capabilities\n * a source provides when it (or its consumer) supports them. */\nexport interface CollectionBackendBase<T = Record<string, unknown>> {\n get?: (entityId: string) => Promise<T>;\n create?: (entity: Partial<T>) => Promise<T>;\n update?: (entity: T) => Promise<T>;\n delete?: (entityId: string) => Promise<void>;\n bulkDelete?: (entityIds: string[]) => Promise<void>;\n move?: (\n id: string,\n params: { moveAfterId: string | null | undefined },\n ) => Promise<void>;\n backup?: BackupConfig;\n bulkInsert?: (entities: Partial<T>[]) => Promise<BulkInsertResult>;\n}\n\n/** Per-call search scope the query layer passes to a backend's `find`. */\nexport interface FindOptions {\n searchableFieldIds?: string[];\n}\n\n/**\n * The query-layer fetch-data fns plus the optional `find` options the runtime\n * already accepts. Kept separate so the shared `OffsetFetchDataFn`/\n * `CursorFetchDataFn` used by `fetchData` stay unchanged.\n */\ntype OffsetFindFn<T, F extends FiltersMap> = (\n query: OffsetQuery<F>,\n options?: FindOptions,\n) => Promise<OffsetQueryResult<T>>;\ntype CursorFindFn<T, F extends FiltersMap> = (\n query: CursorQuery<F>,\n options?: FindOptions,\n) => Promise<CursorQueryResult<T>>;\n\n/**\n * A source's item data access. The source declares its `paginationMode`\n * (offset by default) together with the matching `find`, same as core's\n * `PaginationModeConfig`.\n */\nexport type CollectionBackend<\n T = Record<string, unknown>,\n F extends FiltersMap = OptionalFiltersMap,\n> = CollectionBackendBase<T> &\n (\n | { paginationMode?: 'offset'; find: OffsetFindFn<T, F> }\n | {\n paginationMode: 'cursor';\n find: CursorFindFn<T, F>;\n fetchTotal?: FetchTotalFn;\n }\n );\n\n/** Field-management actions. All optional — a read-only source provides none. */\nexport interface FieldActions {\n /**\n * Field-mutating actions return the collection's updated fields map so the\n * caller can merge its local state from the response, without reloading the\n * schema. (`renameField` is the exception — nothing consumes its result yet.)\n */\n addField?: (field: Field) => Promise<Schema['fields']>;\n /**\n * Adds several fields in a single mutation, each under its `field.id` key\n * (callers decide the keys up front — e.g. CSV import uploads values under\n * them), unlike `addField`, which derives a fresh key from the display name.\n */\n addFields?: (fields: Field[]) => Promise<Schema['fields']>;\n editField?: (\n fieldId: string,\n updates: Partial<Field>,\n ) => Promise<Schema['fields']>;\n deleteField?: (fieldId: string) => Promise<Schema['fields']>;\n renameField?: (fieldId: string, newName: string) => Promise<void>;\n makePrimary?: (fieldId: string) => Promise<Schema['fields']>;\n duplicateField?: (fieldId: string) => Promise<Schema['fields']>;\n duplicateFieldWithContent?: (fieldId: string) => Promise<Schema['fields']>;\n}\n\n/** Everything a source provides for a collection. */\nexport interface LoadedSchema<T = Record<string, unknown>> {\n schema: Schema;\n backend: CollectionBackend<T>;\n fieldActions?: FieldActions;\n}\n\n/**\n * Loads a collection's `LoadedSchema`. Sources that need dependencies expose a\n * factory that returns this type.\n */\nexport type SchemaLoader<\n T extends Record<string, unknown> = Record<string, unknown>,\n> = (collectionId: string) => Promise<LoadedSchema<T>>;\n"],"mappings":"","ignoreList":[]}
|
|
@@ -2,14 +2,28 @@
|
|
|
2
2
|
|
|
3
3
|
exports.__esModule = true;
|
|
4
4
|
exports.defineSchemaSource = defineSchemaSource;
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
5
|
+
exports.sourceFetchData = sourceFetchData;
|
|
6
|
+
/** A field type a source allows creating. Declare one entry per
|
|
7
|
+
* `patternsType` — the type is the entry's identity. */
|
|
8
8
|
|
|
9
9
|
/** What a caller passes. Only `collectionId` and `loadSchema` are required. */
|
|
10
10
|
|
|
11
11
|
/** The resolved source: defaults filled, `loadSchema` memoized. */
|
|
12
12
|
|
|
13
|
+
/** The collection fetch derived from a source: loads once, then queries the
|
|
14
|
+
* backend's `find` scoped to the source's searchable fields. */
|
|
15
|
+
function sourceFetchData(source) {
|
|
16
|
+
return async query => {
|
|
17
|
+
const {
|
|
18
|
+
backend,
|
|
19
|
+
schema
|
|
20
|
+
} = await source.loadSchema();
|
|
21
|
+
return backend.find(query, {
|
|
22
|
+
searchableFieldIds: source.searchableFieldIds(schema)
|
|
23
|
+
});
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
|
|
13
27
|
/** Fills source-neutral defaults over `input` and memoizes the load so the collection
|
|
14
28
|
* query and the table columns share a single fetch. */
|
|
15
29
|
function defineSchemaSource(input) {
|
|
@@ -18,7 +32,8 @@ function defineSchemaSource(input) {
|
|
|
18
32
|
paginationMode = 'offset',
|
|
19
33
|
creatableFieldTypes = [],
|
|
20
34
|
fieldPermissions,
|
|
21
|
-
supportsPii = false
|
|
35
|
+
supportsPii = false,
|
|
36
|
+
references = {}
|
|
22
37
|
} = input;
|
|
23
38
|
let loaded;
|
|
24
39
|
let schema;
|
|
@@ -50,32 +65,27 @@ function defineSchemaSource(input) {
|
|
|
50
65
|
var _s$schemaPermissions3;
|
|
51
66
|
return (((_s$schemaPermissions3 = s.schemaPermissions) == null ? void 0 : _s$schemaPermissions3.deleteField) ?? false) && !field.isSystem;
|
|
52
67
|
});
|
|
53
|
-
const
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
return backend.find(query, {
|
|
59
|
-
searchableFieldIds: searchableFieldIds(loadedSchema)
|
|
60
|
-
});
|
|
61
|
-
};
|
|
68
|
+
const getFieldValue = input.getFieldValue ?? ((item, field) => item[field.id]);
|
|
69
|
+
const setFieldValue = input.setFieldValue ?? ((item, field, value) => ({
|
|
70
|
+
...item,
|
|
71
|
+
[field.id]: value
|
|
72
|
+
}));
|
|
62
73
|
return {
|
|
63
74
|
collectionId,
|
|
64
75
|
loadSchema,
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
itemKey,
|
|
70
|
-
itemName
|
|
71
|
-
},
|
|
76
|
+
paginationMode,
|
|
77
|
+
itemKey,
|
|
78
|
+
itemName,
|
|
79
|
+
references,
|
|
72
80
|
creatableFieldTypes,
|
|
73
81
|
searchableFieldIds,
|
|
74
82
|
canAddFields,
|
|
75
83
|
canEditField,
|
|
76
84
|
canDeleteField,
|
|
77
85
|
fieldPermissions,
|
|
78
|
-
supportsPii
|
|
86
|
+
supportsPii,
|
|
87
|
+
getFieldValue,
|
|
88
|
+
setFieldValue
|
|
79
89
|
};
|
|
80
90
|
}
|
|
81
91
|
//# sourceMappingURL=SchemaSource.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["defineSchemaSource","input","collectionId","paginationMode","creatableFieldTypes","fieldPermissions","supportsPii","
|
|
1
|
+
{"version":3,"names":["sourceFetchData","source","query","backend","schema","loadSchema","find","searchableFieldIds","defineSchemaSource","input","collectionId","paginationMode","creatableFieldTypes","fieldPermissions","supportsPii","references","loaded","then","result","catch","error","undefined","s","displayField","itemKey","item","_schema","String","idField","itemName","_schema2","canAddFields","_s$schemaPermissions","schemaPermissions","createField","canEditField","field","_s$schemaPermissions2","updateField","isSystem","canDeleteField","_s$schemaPermissions3","deleteField","getFieldValue","id","setFieldValue","value"],"sources":["../../../src/types/SchemaSource.ts"],"sourcesContent":["import type { Field, PatternsFieldType } from './Field';\nimport type { Schema, LoadedSchema, FindOptions } from './Schema';\nimport type { FieldPermissions } from './FieldsSource';\nimport type {\n OffsetQuery,\n OffsetQueryResult,\n} from '../hooks/paginationModeConfig';\n\n/** A field type a source allows creating. Declare one entry per\n * `patternsType` — the type is the entry's identity. */\nexport interface CreatableFieldType {\n patternsType: PatternsFieldType;\n /** Custom display name. Absent ⇒ the UI's standard name for this type. */\n label?: string;\n /** Custom name-input placeholder. Absent ⇒ the UI's standard placeholder. */\n namePlaceholder?: string;\n}\n\n/** What a caller passes. Only `collectionId` and `loadSchema` are required. */\nexport interface SchemaSourceInput<T> {\n collectionId: string;\n loadSchema: () => Promise<LoadedSchema<T>>;\n /** Sources for collections this one references, keyed by the referenced\n * collection id. A renderer resolves a reference field through the matching\n * entry — its `loadSchema` gives the referenced schema and `sourceFetchData`\n * queries the referenced items. Default: none. */\n references?: Record<string, SchemaSource<any>>;\n paginationMode?: 'offset';\n /** Stable row identity. Default: `row[idField]`. */\n itemKey?: (item: T) => string;\n /** Row display label. Default: `row[displayField]`. */\n itemName?: (item: T) => string;\n /** Fields free-text search runs against. Default: `[displayField]`. */\n searchableFieldIds?: (schema: Schema) => string[];\n /** Field types the add-field modal offers. Default: none. */\n creatableFieldTypes?: CreatableFieldType[];\n /** Default: `schemaPermissions.createField`. */\n canAddFields?: (schema: Schema) => boolean;\n /** Default: `schemaPermissions.updateField && !field.isSystem`. */\n canEditField?: (field: Field, schema: Schema) => boolean;\n /** Default: `schemaPermissions.deleteField && !field.isSystem`. */\n canDeleteField?: (field: Field, schema: Schema) => boolean;\n /** Permission defaults shown in the modal. Absent ⇒ no permissions section. */\n fieldPermissions?: FieldPermissions;\n /** Default: `false`. */\n supportsPii?: boolean;\n /** The value of a field on an item. Default: `item[field.id]`. */\n getFieldValue?: (item: T, field: Field) => unknown;\n /** Writes a field's value on an item, returning the updated item.\n * Default: `{ ...item, [field.id]: value }`. */\n setFieldValue?: (item: T, field: Field, value: unknown) => T;\n}\n\n/** The resolved source: defaults filled, `loadSchema` memoized. */\nexport interface SchemaSource<T> {\n readonly collectionId: string;\n loadSchema: () => Promise<LoadedSchema<T>>;\n readonly paginationMode: 'offset';\n /** Stable row identity. */\n itemKey: (item: T) => string;\n /** Row display label. */\n itemName: (item: T) => string;\n /** Sources for referenced collections, keyed by referenced collection id. */\n readonly references: Record<string, SchemaSource<any>>;\n readonly creatableFieldTypes: CreatableFieldType[];\n searchableFieldIds: (schema: Schema) => string[];\n canAddFields: (schema: Schema) => boolean;\n canEditField: (field: Field, schema: Schema) => boolean;\n canDeleteField: (field: Field, schema: Schema) => boolean;\n readonly fieldPermissions?: FieldPermissions;\n readonly supportsPii: boolean;\n /** The value of a field on an item. */\n getFieldValue: (item: T, field: Field) => unknown;\n /** Writes a field's value on an item, returning the updated item. */\n setFieldValue: (item: T, field: Field, value: unknown) => T;\n}\n\ntype OffsetFind<T> = (\n query: OffsetQuery,\n options?: FindOptions,\n) => Promise<OffsetQueryResult<T>>;\n\n/** The collection fetch derived from a source: loads once, then queries the\n * backend's `find` scoped to the source's searchable fields. */\nexport function sourceFetchData<T>(\n source: SchemaSource<T>,\n): (query: OffsetQuery) => Promise<OffsetQueryResult<T>> {\n return async (query) => {\n const { backend, schema } = await source.loadSchema();\n return (backend.find as OffsetFind<T>)(query, {\n searchableFieldIds: source.searchableFieldIds(schema),\n });\n };\n}\n\n/** Fills source-neutral defaults over `input` and memoizes the load so the collection\n * query and the table columns share a single fetch. */\nexport function defineSchemaSource<T>(\n input: SchemaSourceInput<T>,\n): SchemaSource<T> {\n const {\n collectionId,\n paginationMode = 'offset',\n creatableFieldTypes = [],\n fieldPermissions,\n supportsPii = false,\n references = {},\n } = input;\n\n let loaded: Promise<LoadedSchema<T>> | undefined;\n let schema: Schema | undefined;\n\n const loadSchema = () =>\n (loaded ??= input\n .loadSchema()\n .then((result) => {\n schema = result.schema;\n return result;\n })\n .catch((error) => {\n loaded = undefined;\n throw error;\n }));\n\n const searchableFieldIds =\n input.searchableFieldIds ?? ((s) => [s.displayField]);\n\n const itemKey =\n input.itemKey ??\n ((item) =>\n String(\n (item as Record<string, unknown>)[schema?.idField ?? '_id'] ?? '',\n ));\n const itemName =\n input.itemName ??\n ((item) =>\n String(\n (item as Record<string, unknown>)[schema?.displayField ?? '_id'] ?? '',\n ));\n const canAddFields =\n input.canAddFields ?? ((s) => s.schemaPermissions?.createField ?? false);\n const canEditField =\n input.canEditField ??\n ((field, s) =>\n (s.schemaPermissions?.updateField ?? false) && !field.isSystem);\n const canDeleteField =\n input.canDeleteField ??\n ((field, s) =>\n (s.schemaPermissions?.deleteField ?? false) && !field.isSystem);\n const getFieldValue =\n input.getFieldValue ??\n ((item, field) => (item as Record<string, unknown>)[field.id]);\n const setFieldValue =\n input.setFieldValue ??\n ((item, field, value) => ({ ...item, [field.id]: value } as T));\n\n return {\n collectionId,\n loadSchema,\n paginationMode,\n itemKey,\n itemName,\n references,\n creatableFieldTypes,\n searchableFieldIds,\n canAddFields,\n canEditField,\n canDeleteField,\n fieldPermissions,\n supportsPii,\n getFieldValue,\n setFieldValue,\n };\n}\n"],"mappings":"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","ignoreList":[]}
|
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
"cairo.table.deleteViewModal.title": "Delete this view?",
|
|
8
8
|
"cairo.table.advanced-sorting.ascending.order": "Ascending",
|
|
9
9
|
"cairo.table.custom-columns.indication.user": "User",
|
|
10
|
+
"cairo.import.missingRequiredMessage": "Match all required fields to make sure all your items import successfully. Missing: {fields}",
|
|
10
11
|
"cairo.table.saveViewModal.title": "Save view",
|
|
11
12
|
"cairo.tags.manageTags.modal.list.input.validation.exists.asLabels": "This label already exists.",
|
|
12
13
|
"fields.audio.button.download": "Download track",
|
|
@@ -16,7 +17,7 @@
|
|
|
16
17
|
"fields.audio.button.add": "Add Audio ",
|
|
17
18
|
"cairo.collectionPage.nested.expandAll.tooltip": "Expand all",
|
|
18
19
|
"cairo.customFields.addCustomField.modal.add.CTA": "Add Field",
|
|
19
|
-
"cairo.import.subtitle": "
|
|
20
|
+
"cairo.import.subtitle": "Add items in bulk by uploading a CSV file.",
|
|
20
21
|
"cairo.tags.manageTags.modal.deleteModal.body.asLabels": "<text>The label <name>\"{name}\"</name> might be in use. Deleting this label will also remove it from all of the items it's assigned to.</text>",
|
|
21
22
|
"cairo.import.progressLabel": "Imported {processed} of {total} rows",
|
|
22
23
|
"cairo.import.done": "Done",
|
|
@@ -87,11 +88,14 @@
|
|
|
87
88
|
"cairo.dragAndDrop.leaveSite.modal.cancel.CTA": "Cancel",
|
|
88
89
|
"cairo.tags.manageTags.modal.deleteModal.delete.CTA": "Delete",
|
|
89
90
|
"cairo.updatedView.collectionPage.toast.cta": "Refresh View",
|
|
91
|
+
"cairo.editableTable.dateTime.placeholder.hour": "HH",
|
|
90
92
|
"cairo.customFields.addCustomField.modal.PII-setting.toggle.createNote": "PII settings can’t be changed later.",
|
|
91
93
|
"cairo.tags.popover.assignFolder.tooltip": "Tags can't be assigned to folders.",
|
|
94
|
+
"cairo.editableTable.dateTime.placeholder.month": "MM",
|
|
92
95
|
"cairo.customFields.fieldType.date.invalid.value": "Enter a date that follows this format: {dateFormat}",
|
|
93
96
|
"cairo.archivedFields.more-actions.tooltip": "More actions",
|
|
94
97
|
"cairo.customFields.fieldType.dropdownList.placeholder": "e.g., Italy",
|
|
98
|
+
"cairo.editableTable.dateTime.placeholder": "Choose a date and time",
|
|
95
99
|
"cairo.filtersPanel.numRange.maxRange.error": "‘To’ value must be greater than the ‘From’ value.",
|
|
96
100
|
"cairo.import.fileReadFailed": "Couldn’t read this file. Check your internet connection and that the file hasn’t been moved or deleted.",
|
|
97
101
|
"cairo.setupWidget.step.inProgress": "In progress",
|
|
@@ -135,6 +139,7 @@
|
|
|
135
139
|
"cairo.tags.manageTags.modal.list.create.CTA": "Create <name>\"{tagName}\"</name>",
|
|
136
140
|
"cairo.export.GetExportAsyncJob.job-not-found.error": "Unable to export due to a technical issue on our end.",
|
|
137
141
|
"fields.audio.more_actions_tooltip": "More actions",
|
|
142
|
+
"cairo.editableTable.dateTime.placeholder.day": "DD",
|
|
138
143
|
"cairo.replace-image.tooltip": "Replace image",
|
|
139
144
|
"cairo.tags.filterPanel.dropdown.title.asLabels": "Labels",
|
|
140
145
|
"cairo.filtersPanel.search.clearButton": "Clear search",
|
|
@@ -157,6 +162,7 @@
|
|
|
157
162
|
"cairo.table.custom-columns.subtitle": "Choose which columns to show.",
|
|
158
163
|
"cairo.customFields.addCustomField.modal.advancedSettings.read": "Read",
|
|
159
164
|
"cairo.filterOperator.equals": "Equals",
|
|
165
|
+
"cairo.editableTable.dateTime.ariaLabel.time": "Time",
|
|
160
166
|
"cairo.customFields.fieldType.dateAndTime.Name.placeholder": "e.g., Timestamp",
|
|
161
167
|
"cairo.customFields.addCustomField.modal.PII": "This field can't be used to store personally identifiable information (PII).",
|
|
162
168
|
"cairo.dragAndDrop.reorderMode.toolbar.title.learnMore": "Learn more",
|
|
@@ -183,6 +189,7 @@
|
|
|
183
189
|
"cairo.filtersPanel.date.7days": "Last 7 days",
|
|
184
190
|
"cairo.customFields.fieldType.longText.placeholder": "Enter text here",
|
|
185
191
|
"cairo.customFields.addCustomField.modal.fieldName": "Name",
|
|
192
|
+
"cairo.editableTable.dateTime.placeholder.minute": "MM",
|
|
186
193
|
"cairo.filterOperator.startsWith.tag": "starts with",
|
|
187
194
|
"cairo.tags.tagsWidget.subtitle.asLabels": "Labels help you filter and stay organized.",
|
|
188
195
|
"cairo.tags.loadTags.error.title": "We couldn’t load your tags",
|
|
@@ -363,6 +370,7 @@
|
|
|
363
370
|
"airo.tags.collectionPage.popover.emptyState.body.asLabels": "Labels help you filter and organize your items.",
|
|
364
371
|
"cairo.folders.showAll.button": "Show All",
|
|
365
372
|
"cairo.dragAndDrop.reorderMode.discardChanges.description": "Are you sure you want to cancel changes? Your changes won’t be saved.",
|
|
373
|
+
"cairo.editableTable.dateTime.ariaLabel.date": "Date",
|
|
366
374
|
"cairo.filterOperator.lessThan.tag": "less than",
|
|
367
375
|
"cairo.tags.tagsWidget.emptyState.body": "Tags help you filter and organize your items.",
|
|
368
376
|
"cairo.customFields.fieldType.date.placeholder": "Select a date",
|
|
@@ -417,6 +425,7 @@
|
|
|
417
425
|
"cairo.table.custom-columns.button.cta": "Customize",
|
|
418
426
|
"cairo.customFields.addCustomField.modal.sameName.error": "A field with this name already exists. Try a different name.",
|
|
419
427
|
"cairo.deleteView.Success.toast": "\"{viewName}\" was deleted.",
|
|
428
|
+
"cairo.editableTable.dateTime.placeholder.year": "YYYY",
|
|
420
429
|
"cairo.filtersPanel.sections.default.title": "More filters",
|
|
421
430
|
"cairo.tags.tagsWidget.input.placeholder": "Enter new tag name",
|
|
422
431
|
"cairo.entity.item": "{num, plural, =0 {items} =1 {item} other {items}}",
|
|
@@ -501,6 +510,7 @@
|
|
|
501
510
|
"cairo.tags.bulkItemUpdate.updatingModal.CTA.asLabels": "Close",
|
|
502
511
|
"cairo.tags.tagsWidget.options.manage.CTA": "Manage Tags",
|
|
503
512
|
"cairo.table.filter.button": "Filter",
|
|
513
|
+
"cairo.import.missingRequiredField": "Missing {count, plural, one {# required field} other {# required fields}}",
|
|
504
514
|
"cairo.table.custom-columns.indication.app": "App",
|
|
505
515
|
"cairo.import.discardChanges.title": "Discard changes?",
|
|
506
516
|
"cairo.tags.collectionPage.popover.emptyState.search.placeholder": "Enter new tag name",
|
|
@@ -604,6 +614,7 @@
|
|
|
604
614
|
"cairo.tags.manageTags.modal.emptyState.body.asLabels": "Labels help you filter and organize your items.",
|
|
605
615
|
"cairo.table.custom-columns.hidden.disabled.tooltip": "This column can’t be hidden.",
|
|
606
616
|
"cairo.import.close": "Close",
|
|
617
|
+
"cairo.import.createNewField": "Create new field",
|
|
607
618
|
"cairo.filtersPanel.header.closeButton.ariaLabel": "Close",
|
|
608
619
|
"cairo.customFields.updateDataExtension.invalid-namespace.error": "Unable to update custom field due to a technical issue on our end.",
|
|
609
620
|
"cairo.filterOperator.startsWith": "Starts With",
|
|
@@ -733,7 +744,7 @@
|
|
|
733
744
|
"cairo.tags.fqdn-not-found.manageTagsModal.error": "Unable to complete this action.",
|
|
734
745
|
"cairo.tags.tagsWidget.options.add.CTA.asLabels": "Create \"{tagName}\"",
|
|
735
746
|
"cairo.setupWidget.step.lockedTooltip": "You don’t have access to this step. Ask the site owner for permission.",
|
|
736
|
-
"cairo.import.title": "Import
|
|
747
|
+
"cairo.import.title": "Import a CSV file",
|
|
737
748
|
"cairo.dragAndDrop.note": "Note: Any changes made to the order of your items will appear on your live site.",
|
|
738
749
|
"cairo.tags.tagsWidget.add.CTA.asLabels": "Assign Labels",
|
|
739
750
|
"cairo.filtersPanel.date.from.placeholder": "From"
|
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
"cairo.table.deleteViewModal.title": "Delete this view?",
|
|
8
8
|
"cairo.table.advanced-sorting.ascending.order": "Ascending",
|
|
9
9
|
"cairo.table.custom-columns.indication.user": "User",
|
|
10
|
+
"cairo.import.missingRequiredMessage": "Match all required fields to make sure all your items import successfully. Missing: {fields}",
|
|
10
11
|
"cairo.table.saveViewModal.title": "Save view",
|
|
11
12
|
"cairo.tags.manageTags.modal.list.input.validation.exists.asLabels": "This label already exists.",
|
|
12
13
|
"fields.audio.button.download": "Download track",
|
|
@@ -16,7 +17,7 @@
|
|
|
16
17
|
"fields.audio.button.add": "Add Audio ",
|
|
17
18
|
"cairo.collectionPage.nested.expandAll.tooltip": "Expand all",
|
|
18
19
|
"cairo.customFields.addCustomField.modal.add.CTA": "Add Field",
|
|
19
|
-
"cairo.import.subtitle": "
|
|
20
|
+
"cairo.import.subtitle": "Add items in bulk by uploading a CSV file.",
|
|
20
21
|
"cairo.tags.manageTags.modal.deleteModal.body.asLabels": "<text>The label <name>\"{name}\"</name> might be in use. Deleting this label will also remove it from all of the items it's assigned to.</text>",
|
|
21
22
|
"cairo.import.progressLabel": "Imported {processed} of {total} rows",
|
|
22
23
|
"cairo.import.done": "Done",
|
|
@@ -87,11 +88,14 @@
|
|
|
87
88
|
"cairo.dragAndDrop.leaveSite.modal.cancel.CTA": "Cancel",
|
|
88
89
|
"cairo.tags.manageTags.modal.deleteModal.delete.CTA": "Delete",
|
|
89
90
|
"cairo.updatedView.collectionPage.toast.cta": "Refresh View",
|
|
91
|
+
"cairo.editableTable.dateTime.placeholder.hour": "HH",
|
|
90
92
|
"cairo.customFields.addCustomField.modal.PII-setting.toggle.createNote": "PII settings can’t be changed later.",
|
|
91
93
|
"cairo.tags.popover.assignFolder.tooltip": "Tags can't be assigned to folders.",
|
|
94
|
+
"cairo.editableTable.dateTime.placeholder.month": "MM",
|
|
92
95
|
"cairo.customFields.fieldType.date.invalid.value": "Enter a date that follows this format: {dateFormat}",
|
|
93
96
|
"cairo.archivedFields.more-actions.tooltip": "More actions",
|
|
94
97
|
"cairo.customFields.fieldType.dropdownList.placeholder": "e.g., Italy",
|
|
98
|
+
"cairo.editableTable.dateTime.placeholder": "Choose a date and time",
|
|
95
99
|
"cairo.filtersPanel.numRange.maxRange.error": "‘To’ value must be greater than the ‘From’ value.",
|
|
96
100
|
"cairo.import.fileReadFailed": "Couldn’t read this file. Check your internet connection and that the file hasn’t been moved or deleted.",
|
|
97
101
|
"cairo.setupWidget.step.inProgress": "In progress",
|
|
@@ -135,6 +139,7 @@
|
|
|
135
139
|
"cairo.tags.manageTags.modal.list.create.CTA": "Create <name>\"{tagName}\"</name>",
|
|
136
140
|
"cairo.export.GetExportAsyncJob.job-not-found.error": "Unable to export due to a technical issue on our end.",
|
|
137
141
|
"fields.audio.more_actions_tooltip": "More actions",
|
|
142
|
+
"cairo.editableTable.dateTime.placeholder.day": "DD",
|
|
138
143
|
"cairo.replace-image.tooltip": "Replace image",
|
|
139
144
|
"cairo.tags.filterPanel.dropdown.title.asLabels": "Labels",
|
|
140
145
|
"cairo.filtersPanel.search.clearButton": "Clear search",
|
|
@@ -157,6 +162,7 @@
|
|
|
157
162
|
"cairo.table.custom-columns.subtitle": "Choose which columns to show.",
|
|
158
163
|
"cairo.customFields.addCustomField.modal.advancedSettings.read": "Read",
|
|
159
164
|
"cairo.filterOperator.equals": "Equals",
|
|
165
|
+
"cairo.editableTable.dateTime.ariaLabel.time": "Time",
|
|
160
166
|
"cairo.customFields.fieldType.dateAndTime.Name.placeholder": "e.g., Timestamp",
|
|
161
167
|
"cairo.customFields.addCustomField.modal.PII": "This field can't be used to store personally identifiable information (PII).",
|
|
162
168
|
"cairo.dragAndDrop.reorderMode.toolbar.title.learnMore": "Learn more",
|
|
@@ -183,6 +189,7 @@
|
|
|
183
189
|
"cairo.filtersPanel.date.7days": "Last 7 days",
|
|
184
190
|
"cairo.customFields.fieldType.longText.placeholder": "Enter text here",
|
|
185
191
|
"cairo.customFields.addCustomField.modal.fieldName": "Name",
|
|
192
|
+
"cairo.editableTable.dateTime.placeholder.minute": "MM",
|
|
186
193
|
"cairo.filterOperator.startsWith.tag": "starts with",
|
|
187
194
|
"cairo.tags.tagsWidget.subtitle.asLabels": "Labels help you filter and stay organized.",
|
|
188
195
|
"cairo.tags.loadTags.error.title": "We couldn’t load your tags",
|
|
@@ -363,6 +370,7 @@
|
|
|
363
370
|
"airo.tags.collectionPage.popover.emptyState.body.asLabels": "Labels help you filter and organize your items.",
|
|
364
371
|
"cairo.folders.showAll.button": "Show All",
|
|
365
372
|
"cairo.dragAndDrop.reorderMode.discardChanges.description": "Are you sure you want to cancel changes? Your changes won’t be saved.",
|
|
373
|
+
"cairo.editableTable.dateTime.ariaLabel.date": "Date",
|
|
366
374
|
"cairo.filterOperator.lessThan.tag": "less than",
|
|
367
375
|
"cairo.tags.tagsWidget.emptyState.body": "Tags help you filter and organize your items.",
|
|
368
376
|
"cairo.customFields.fieldType.date.placeholder": "Select a date",
|
|
@@ -417,6 +425,7 @@
|
|
|
417
425
|
"cairo.table.custom-columns.button.cta": "Customize",
|
|
418
426
|
"cairo.customFields.addCustomField.modal.sameName.error": "A field with this name already exists. Try a different name.",
|
|
419
427
|
"cairo.deleteView.Success.toast": "\"{viewName}\" was deleted.",
|
|
428
|
+
"cairo.editableTable.dateTime.placeholder.year": "YYYY",
|
|
420
429
|
"cairo.filtersPanel.sections.default.title": "More filters",
|
|
421
430
|
"cairo.tags.tagsWidget.input.placeholder": "Enter new tag name",
|
|
422
431
|
"cairo.entity.item": "{num, plural, =0 {items} =1 {item} other {items}}",
|
|
@@ -501,6 +510,7 @@
|
|
|
501
510
|
"cairo.tags.bulkItemUpdate.updatingModal.CTA.asLabels": "Close",
|
|
502
511
|
"cairo.tags.tagsWidget.options.manage.CTA": "Manage Tags",
|
|
503
512
|
"cairo.table.filter.button": "Filter",
|
|
513
|
+
"cairo.import.missingRequiredField": "Missing {count, plural, one {# required field} other {# required fields}}",
|
|
504
514
|
"cairo.table.custom-columns.indication.app": "App",
|
|
505
515
|
"cairo.import.discardChanges.title": "Discard changes?",
|
|
506
516
|
"cairo.tags.collectionPage.popover.emptyState.search.placeholder": "Enter new tag name",
|
|
@@ -604,6 +614,7 @@
|
|
|
604
614
|
"cairo.tags.manageTags.modal.emptyState.body.asLabels": "Labels help you filter and organize your items.",
|
|
605
615
|
"cairo.table.custom-columns.hidden.disabled.tooltip": "This column can’t be hidden.",
|
|
606
616
|
"cairo.import.close": "Close",
|
|
617
|
+
"cairo.import.createNewField": "Create new field",
|
|
607
618
|
"cairo.filtersPanel.header.closeButton.ariaLabel": "Close",
|
|
608
619
|
"cairo.customFields.updateDataExtension.invalid-namespace.error": "Unable to update custom field due to a technical issue on our end.",
|
|
609
620
|
"cairo.filterOperator.startsWith": "Starts With",
|
|
@@ -733,7 +744,7 @@
|
|
|
733
744
|
"cairo.tags.fqdn-not-found.manageTagsModal.error": "Unable to complete this action.",
|
|
734
745
|
"cairo.tags.tagsWidget.options.add.CTA.asLabels": "Create \"{tagName}\"",
|
|
735
746
|
"cairo.setupWidget.step.lockedTooltip": "You don’t have access to this step. Ask the site owner for permission.",
|
|
736
|
-
"cairo.import.title": "Import
|
|
747
|
+
"cairo.import.title": "Import a CSV file",
|
|
737
748
|
"cairo.dragAndDrop.note": "Note: Any changes made to the order of your items will appear on your live site.",
|
|
738
749
|
"cairo.tags.tagsWidget.add.CTA.asLabels": "Assign Labels",
|
|
739
750
|
"cairo.filtersPanel.date.from.placeholder": "From"
|