@wix/bex-core 2.332.0 → 2.333.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 +3 -0
- package/dist/cjs/assets/locale/messages_bg.json +3 -0
- package/dist/cjs/assets/locale/messages_ca.json +3 -0
- package/dist/cjs/assets/locale/messages_cs.json +3 -0
- package/dist/cjs/assets/locale/messages_da.json +3 -0
- package/dist/cjs/assets/locale/messages_de.json +3 -0
- package/dist/cjs/assets/locale/messages_el.json +3 -0
- package/dist/cjs/assets/locale/messages_en.json +3 -0
- package/dist/cjs/assets/locale/messages_es.json +3 -0
- package/dist/cjs/assets/locale/messages_fi.json +3 -0
- package/dist/cjs/assets/locale/messages_fr.json +3 -0
- package/dist/cjs/assets/locale/messages_he.json +3 -0
- package/dist/cjs/assets/locale/messages_hi.json +3 -0
- package/dist/cjs/assets/locale/messages_hu.json +3 -0
- package/dist/cjs/assets/locale/messages_id.json +3 -0
- package/dist/cjs/assets/locale/messages_it.json +3 -0
- package/dist/cjs/assets/locale/messages_ja.json +3 -0
- package/dist/cjs/assets/locale/messages_ko.json +3 -0
- package/dist/cjs/assets/locale/messages_lt.json +3 -0
- package/dist/cjs/assets/locale/messages_ms.json +3 -0
- package/dist/cjs/assets/locale/messages_nl.json +3 -0
- package/dist/cjs/assets/locale/messages_no.json +3 -0
- package/dist/cjs/assets/locale/messages_pl.json +3 -0
- package/dist/cjs/assets/locale/messages_pt.json +3 -0
- package/dist/cjs/assets/locale/messages_ro.json +3 -0
- package/dist/cjs/assets/locale/messages_ru.json +3 -0
- package/dist/cjs/assets/locale/messages_sk.json +3 -0
- package/dist/cjs/assets/locale/messages_sl.json +3 -0
- package/dist/cjs/assets/locale/messages_sv.json +3 -0
- package/dist/cjs/assets/locale/messages_th.json +3 -0
- package/dist/cjs/assets/locale/messages_tl.json +3 -0
- package/dist/cjs/assets/locale/messages_tr.json +3 -0
- package/dist/cjs/assets/locale/messages_uk.json +3 -0
- package/dist/cjs/assets/locale/messages_vi.json +3 -0
- package/dist/cjs/assets/locale/messages_zh.json +3 -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 +0 -6
- package/dist/cjs/hooks/index.js.map +1 -1
- package/dist/cjs/index.js +0 -7
- 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 +324 -133
- package/dist/cjs/state/ImportState/ImportState.js.map +1 -1
- package/dist/cjs/state/ImportState/__tests__/ImportState.engine.spec.js +413 -79
- package/dist/cjs/state/ImportState/__tests__/ImportState.engine.spec.js.map +1 -1
- package/dist/cjs/state/ImportState/detectFieldType.js +23 -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/testkit/createInMemorySchemaSource.js +186 -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/SchemaSource.js +2 -1
- package/dist/cjs/types/SchemaSource.js.map +1 -1
- package/dist/esm/assets/locale/messages_ar.json +3 -0
- package/dist/esm/assets/locale/messages_bg.json +3 -0
- package/dist/esm/assets/locale/messages_ca.json +3 -0
- package/dist/esm/assets/locale/messages_cs.json +3 -0
- package/dist/esm/assets/locale/messages_da.json +3 -0
- package/dist/esm/assets/locale/messages_de.json +3 -0
- package/dist/esm/assets/locale/messages_el.json +3 -0
- package/dist/esm/assets/locale/messages_en.json +3 -0
- package/dist/esm/assets/locale/messages_es.json +3 -0
- package/dist/esm/assets/locale/messages_fi.json +3 -0
- package/dist/esm/assets/locale/messages_fr.json +3 -0
- package/dist/esm/assets/locale/messages_he.json +3 -0
- package/dist/esm/assets/locale/messages_hi.json +3 -0
- package/dist/esm/assets/locale/messages_hu.json +3 -0
- package/dist/esm/assets/locale/messages_id.json +3 -0
- package/dist/esm/assets/locale/messages_it.json +3 -0
- package/dist/esm/assets/locale/messages_ja.json +3 -0
- package/dist/esm/assets/locale/messages_ko.json +3 -0
- package/dist/esm/assets/locale/messages_lt.json +3 -0
- package/dist/esm/assets/locale/messages_ms.json +3 -0
- package/dist/esm/assets/locale/messages_nl.json +3 -0
- package/dist/esm/assets/locale/messages_no.json +3 -0
- package/dist/esm/assets/locale/messages_pl.json +3 -0
- package/dist/esm/assets/locale/messages_pt.json +3 -0
- package/dist/esm/assets/locale/messages_ro.json +3 -0
- package/dist/esm/assets/locale/messages_ru.json +3 -0
- package/dist/esm/assets/locale/messages_sk.json +3 -0
- package/dist/esm/assets/locale/messages_sl.json +3 -0
- package/dist/esm/assets/locale/messages_sv.json +3 -0
- package/dist/esm/assets/locale/messages_th.json +3 -0
- package/dist/esm/assets/locale/messages_tl.json +3 -0
- package/dist/esm/assets/locale/messages_tr.json +3 -0
- package/dist/esm/assets/locale/messages_uk.json +3 -0
- package/dist/esm/assets/locale/messages_vi.json +3 -0
- package/dist/esm/assets/locale/messages_zh.json +3 -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 +0 -1
- package/dist/esm/hooks/index.js.map +1 -1
- package/dist/esm/index.js +0 -1
- 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 +246 -111
- package/dist/esm/state/ImportState/ImportState.js.map +1 -1
- package/dist/esm/state/ImportState/__tests__/ImportState.engine.spec.js +293 -67
- package/dist/esm/state/ImportState/__tests__/ImportState.engine.spec.js.map +1 -1
- package/dist/esm/state/ImportState/detectFieldType.js +19 -0
- 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/testkit/createInMemorySchemaSource.js +140 -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.map +1 -1
- package/dist/types/hooks/index.d.ts +0 -1
- package/dist/types/hooks/index.d.ts.map +1 -1
- package/dist/types/index.d.ts +0 -1
- 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 +165 -61
- package/dist/types/state/ImportState/ImportState.d.ts.map +1 -1
- package/dist/types/state/ImportState/detectFieldType.d.ts +2 -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/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 +41 -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/SchemaSource.d.ts +6 -4
- 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,186 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
exports.__esModule = true;
|
|
4
|
+
exports.createInMemorySchemaSource = createInMemorySchemaSource;
|
|
5
|
+
var _SchemaSource = require("../types/SchemaSource");
|
|
6
|
+
var _InMemoryBackend = require("../InMemoryBackend");
|
|
7
|
+
const ALL_PERMISSIONS = {
|
|
8
|
+
createField: true,
|
|
9
|
+
updateField: true,
|
|
10
|
+
deleteField: true
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
// The types the add/edit modal offers by default (the ones @wix/data can create).
|
|
14
|
+
const DEFAULT_CREATABLE_FIELD_TYPES = [{
|
|
15
|
+
patternsType: 'SHORT_TEXT'
|
|
16
|
+
}, {
|
|
17
|
+
patternsType: 'NUMBER'
|
|
18
|
+
}, {
|
|
19
|
+
patternsType: 'BOOLEAN'
|
|
20
|
+
}, {
|
|
21
|
+
patternsType: 'DATE'
|
|
22
|
+
}];
|
|
23
|
+
/**
|
|
24
|
+
* Builds a real `SchemaSource<T>` backed by in-memory state — no data source (no
|
|
25
|
+
* `@wix/data`, no network). Its `collectionConfig.fetchData` serves the seeded
|
|
26
|
+
* `items`, and its `fieldActions` mutate the in-memory schema and return the
|
|
27
|
+
* updated fields map, so the create-new-field import flow works end to end (the
|
|
28
|
+
* created column surfaces via the schema-source merge).
|
|
29
|
+
*
|
|
30
|
+
* Returns `{ source, backend }`. Pass `source` anywhere a `SchemaSource` is
|
|
31
|
+
* accepted — `<Table fieldsSource={...} />`, `useSchemaImport(...)`, or
|
|
32
|
+
* `...collectionConfig` into the collection hook. Use `backend` to read or
|
|
33
|
+
* assert on the in-memory rows directly.
|
|
34
|
+
*/
|
|
35
|
+
function createInMemorySchemaSource(config) {
|
|
36
|
+
var _config$fields$;
|
|
37
|
+
const {
|
|
38
|
+
collectionId,
|
|
39
|
+
idField = '_id',
|
|
40
|
+
displayField = ((_config$fields$ = config.fields[0]) == null ? void 0 : _config$fields$.id) ?? idField,
|
|
41
|
+
schemaPermissions = ALL_PERMISSIONS,
|
|
42
|
+
itemPermissions,
|
|
43
|
+
creatableFieldTypes = DEFAULT_CREATABLE_FIELD_TYPES,
|
|
44
|
+
supportsPii = false
|
|
45
|
+
} = config;
|
|
46
|
+
|
|
47
|
+
// Mutable in-memory state shared by the backend, schema, and field actions.
|
|
48
|
+
const fields = {};
|
|
49
|
+
config.fields.forEach(field => {
|
|
50
|
+
fields[field.id] = field;
|
|
51
|
+
});
|
|
52
|
+
const schema = {
|
|
53
|
+
id: collectionId,
|
|
54
|
+
fields,
|
|
55
|
+
displayField,
|
|
56
|
+
idField,
|
|
57
|
+
schemaPermissions,
|
|
58
|
+
...(itemPermissions && {
|
|
59
|
+
itemPermissions
|
|
60
|
+
})
|
|
61
|
+
};
|
|
62
|
+
const keyOf = item => String(item[idField] ?? '');
|
|
63
|
+
// A fresh copy each mutation, so the schema-source merge sees a new map.
|
|
64
|
+
const fieldsSnapshot = () => ({
|
|
65
|
+
...fields
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
// The shared `InMemoryBackend` holds the rows and runs the query logic
|
|
69
|
+
// (ordering, filtering, pagination). The `collectionBackend` below adapts it
|
|
70
|
+
// to the source-neutral contract. Mutations write straight to `backend.map`
|
|
71
|
+
// and reads use the synchronous surface, so operations resolve without the
|
|
72
|
+
// util's simulated async delay (which relies on timers the test suite freezes).
|
|
73
|
+
const seed = config.items ?? [];
|
|
74
|
+
const backend = new _InMemoryBackend.InMemoryBackend({
|
|
75
|
+
paginationMode: 'offset',
|
|
76
|
+
total: seed.length,
|
|
77
|
+
createOne: index => seed[index],
|
|
78
|
+
itemKey: keyOf
|
|
79
|
+
});
|
|
80
|
+
const collectionBackend = {
|
|
81
|
+
paginationMode: 'offset',
|
|
82
|
+
find: async query => {
|
|
83
|
+
const offset = query.offset ?? 0;
|
|
84
|
+
const {
|
|
85
|
+
items,
|
|
86
|
+
total = 0
|
|
87
|
+
} = backend.fetchDataSync(query);
|
|
88
|
+
return {
|
|
89
|
+
items,
|
|
90
|
+
total,
|
|
91
|
+
hasNext: offset + items.length < total
|
|
92
|
+
};
|
|
93
|
+
},
|
|
94
|
+
get: async entityId => {
|
|
95
|
+
const item = backend.get(entityId);
|
|
96
|
+
if (!item) {
|
|
97
|
+
throw new Error(`Item "${entityId}" not found`);
|
|
98
|
+
}
|
|
99
|
+
return item;
|
|
100
|
+
},
|
|
101
|
+
create: async entity => {
|
|
102
|
+
const created = {
|
|
103
|
+
...entity
|
|
104
|
+
};
|
|
105
|
+
backend.map.set(keyOf(created), created);
|
|
106
|
+
return created;
|
|
107
|
+
},
|
|
108
|
+
update: async entity => {
|
|
109
|
+
backend.map.set(keyOf(entity), entity);
|
|
110
|
+
return entity;
|
|
111
|
+
},
|
|
112
|
+
delete: async entityId => {
|
|
113
|
+
backend.map.delete(entityId);
|
|
114
|
+
},
|
|
115
|
+
bulkDelete: async entityIds => {
|
|
116
|
+
entityIds.forEach(entityId => backend.map.delete(entityId));
|
|
117
|
+
},
|
|
118
|
+
bulkInsert: async entities => {
|
|
119
|
+
entities.forEach(entity => {
|
|
120
|
+
const created = {
|
|
121
|
+
...entity
|
|
122
|
+
};
|
|
123
|
+
backend.map.set(keyOf(created), created);
|
|
124
|
+
});
|
|
125
|
+
return {
|
|
126
|
+
succeeded: entities.length,
|
|
127
|
+
failed: 0
|
|
128
|
+
};
|
|
129
|
+
}
|
|
130
|
+
};
|
|
131
|
+
const fieldActions = {
|
|
132
|
+
addField: async field => {
|
|
133
|
+
fields[field.id] = field;
|
|
134
|
+
return fieldsSnapshot();
|
|
135
|
+
},
|
|
136
|
+
addFields: async newFields => {
|
|
137
|
+
newFields.forEach(field => {
|
|
138
|
+
fields[field.id] = field;
|
|
139
|
+
});
|
|
140
|
+
return fieldsSnapshot();
|
|
141
|
+
},
|
|
142
|
+
editField: async (fieldId, updates) => {
|
|
143
|
+
const current = fields[fieldId];
|
|
144
|
+
if (current) {
|
|
145
|
+
fields[fieldId] = {
|
|
146
|
+
...current,
|
|
147
|
+
...updates
|
|
148
|
+
};
|
|
149
|
+
}
|
|
150
|
+
return fieldsSnapshot();
|
|
151
|
+
},
|
|
152
|
+
deleteField: async fieldId => {
|
|
153
|
+
Reflect.deleteProperty(fields, fieldId);
|
|
154
|
+
return fieldsSnapshot();
|
|
155
|
+
},
|
|
156
|
+
renameField: async (fieldId, newName) => {
|
|
157
|
+
const current = fields[fieldId];
|
|
158
|
+
if (current) {
|
|
159
|
+
fields[fieldId] = {
|
|
160
|
+
...current,
|
|
161
|
+
displayName: newName
|
|
162
|
+
};
|
|
163
|
+
}
|
|
164
|
+
},
|
|
165
|
+
makePrimary: async fieldId => {
|
|
166
|
+
schema.displayField = fieldId;
|
|
167
|
+
return fieldsSnapshot();
|
|
168
|
+
}
|
|
169
|
+
};
|
|
170
|
+
const loadSchema = async () => ({
|
|
171
|
+
schema,
|
|
172
|
+
backend: collectionBackend,
|
|
173
|
+
fieldActions
|
|
174
|
+
});
|
|
175
|
+
const source = (0, _SchemaSource.defineSchemaSource)({
|
|
176
|
+
collectionId,
|
|
177
|
+
loadSchema,
|
|
178
|
+
creatableFieldTypes,
|
|
179
|
+
supportsPii
|
|
180
|
+
});
|
|
181
|
+
return {
|
|
182
|
+
source,
|
|
183
|
+
backend
|
|
184
|
+
};
|
|
185
|
+
}
|
|
186
|
+
//# sourceMappingURL=createInMemorySchemaSource.js.map
|
|
@@ -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","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 `SchemaSource<T>` 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}\n\n/**\n * Builds a real `SchemaSource<T>` backed by in-memory state — no data source (no\n * `@wix/data`, no network). Its `collectionConfig.fetchData` serves the seeded\n * `items`, and its `fieldActions` mutate the in-memory schema and return the\n * updated fields map, so the create-new-field import flow works end to end (the\n * created column surfaces via the schema-source merge).\n *\n * Returns `{ source, backend }`. Pass `source` anywhere a `SchemaSource` is\n * accepted — `<Table fieldsSource={...} />`, `useSchemaImport(...)`, or\n * `...collectionConfig` into the collection hook. 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 } = 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 });\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":[]}
|
|
@@ -2,7 +2,8 @@
|
|
|
2
2
|
|
|
3
3
|
exports.__esModule = true;
|
|
4
4
|
exports.defineSchemaSource = defineSchemaSource;
|
|
5
|
-
/** A field type a source allows creating.
|
|
5
|
+
/** A field type a source allows creating. Declare one entry per
|
|
6
|
+
* `patternsType` — the type is the entry's identity. */
|
|
6
7
|
|
|
7
8
|
/** Collection-query config derived from a source, ready to spread into a collection hook. */
|
|
8
9
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["defineSchemaSource","input","collectionId","paginationMode","creatableFieldTypes","fieldPermissions","supportsPii","loaded","schema","loadSchema","then","result","catch","error","undefined","searchableFieldIds","s","displayField","itemKey","item","_schema","String","idField","itemName","_schema2","canAddFields","_s$schemaPermissions","schemaPermissions","createField","canEditField","field","_s$schemaPermissions2","updateField","isSystem","canDeleteField","_s$schemaPermissions3","deleteField","fetchData","query","backend","loadedSchema","find","collectionConfig","queryName"],"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';\
|
|
1
|
+
{"version":3,"names":["defineSchemaSource","input","collectionId","paginationMode","creatableFieldTypes","fieldPermissions","supportsPii","loaded","schema","loadSchema","then","result","catch","error","undefined","searchableFieldIds","s","displayField","itemKey","item","_schema","String","idField","itemName","_schema2","canAddFields","_s$schemaPermissions","schemaPermissions","createField","canEditField","field","_s$schemaPermissions2","updateField","isSystem","canDeleteField","_s$schemaPermissions3","deleteField","fetchData","query","backend","loadedSchema","find","collectionConfig","queryName"],"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/** Collection-query config derived from a source, ready to spread into a collection hook. */\nexport interface SchemaCollectionConfig<T> {\n queryName: string;\n paginationMode: 'offset';\n fetchData: (query: OffsetQuery) => Promise<OffsetQueryResult<T>>;\n itemKey: (item: T) => string;\n itemName: (item: T) => 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 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}\n\n/** The resolved source: defaults filled, `loadSchema` memoized. */\nexport interface SchemaSource<T> {\n readonly collectionId: string;\n loadSchema: () => Promise<LoadedSchema<T>>;\n readonly collectionConfig: SchemaCollectionConfig<T>;\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}\n\ntype OffsetFind<T> = (\n query: OffsetQuery,\n options?: FindOptions,\n) => Promise<OffsetQueryResult<T>>;\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 } = 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\n const fetchData = async (\n query: OffsetQuery,\n ): Promise<OffsetQueryResult<T>> => {\n const { backend, schema: loadedSchema } = await loadSchema();\n return (backend.find as OffsetFind<T>)(query, {\n searchableFieldIds: searchableFieldIds(loadedSchema),\n });\n };\n\n return {\n collectionId,\n loadSchema,\n collectionConfig: {\n queryName: collectionId,\n paginationMode,\n fetchData,\n itemKey,\n itemName,\n },\n creatableFieldTypes,\n searchableFieldIds,\n canAddFields,\n canEditField,\n canDeleteField,\n fieldPermissions,\n supportsPii,\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",
|
|
@@ -501,6 +502,7 @@
|
|
|
501
502
|
"cairo.tags.bulkItemUpdate.updatingModal.CTA.asLabels": "Close",
|
|
502
503
|
"cairo.tags.tagsWidget.options.manage.CTA": "Manage Tags",
|
|
503
504
|
"cairo.table.filter.button": "Filter",
|
|
505
|
+
"cairo.import.missingRequiredField": "Missing {count, plural, one {# required field} other {# required fields}}",
|
|
504
506
|
"cairo.table.custom-columns.indication.app": "App",
|
|
505
507
|
"cairo.import.discardChanges.title": "Discard changes?",
|
|
506
508
|
"cairo.tags.collectionPage.popover.emptyState.search.placeholder": "Enter new tag name",
|
|
@@ -604,6 +606,7 @@
|
|
|
604
606
|
"cairo.tags.manageTags.modal.emptyState.body.asLabels": "Labels help you filter and organize your items.",
|
|
605
607
|
"cairo.table.custom-columns.hidden.disabled.tooltip": "This column can’t be hidden.",
|
|
606
608
|
"cairo.import.close": "Close",
|
|
609
|
+
"cairo.import.createNewField": "Create new field",
|
|
607
610
|
"cairo.filtersPanel.header.closeButton.ariaLabel": "Close",
|
|
608
611
|
"cairo.customFields.updateDataExtension.invalid-namespace.error": "Unable to update custom field due to a technical issue on our end.",
|
|
609
612
|
"cairo.filterOperator.startsWith": "Starts With",
|
|
@@ -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",
|
|
@@ -501,6 +502,7 @@
|
|
|
501
502
|
"cairo.tags.bulkItemUpdate.updatingModal.CTA.asLabels": "Close",
|
|
502
503
|
"cairo.tags.tagsWidget.options.manage.CTA": "Manage Tags",
|
|
503
504
|
"cairo.table.filter.button": "Filter",
|
|
505
|
+
"cairo.import.missingRequiredField": "Missing {count, plural, one {# required field} other {# required fields}}",
|
|
504
506
|
"cairo.table.custom-columns.indication.app": "App",
|
|
505
507
|
"cairo.import.discardChanges.title": "Discard changes?",
|
|
506
508
|
"cairo.tags.collectionPage.popover.emptyState.search.placeholder": "Enter new tag name",
|
|
@@ -604,6 +606,7 @@
|
|
|
604
606
|
"cairo.tags.manageTags.modal.emptyState.body.asLabels": "Labels help you filter and organize your items.",
|
|
605
607
|
"cairo.table.custom-columns.hidden.disabled.tooltip": "This column can’t be hidden.",
|
|
606
608
|
"cairo.import.close": "Close",
|
|
609
|
+
"cairo.import.createNewField": "Create new field",
|
|
607
610
|
"cairo.filtersPanel.header.closeButton.ariaLabel": "Close",
|
|
608
611
|
"cairo.customFields.updateDataExtension.invalid-namespace.error": "Unable to update custom field due to a technical issue on our end.",
|
|
609
612
|
"cairo.filterOperator.startsWith": "Starts With",
|
|
@@ -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",
|
|
@@ -501,6 +502,7 @@
|
|
|
501
502
|
"cairo.tags.bulkItemUpdate.updatingModal.CTA.asLabels": "Close",
|
|
502
503
|
"cairo.tags.tagsWidget.options.manage.CTA": "Manage Tags",
|
|
503
504
|
"cairo.table.filter.button": "Filter",
|
|
505
|
+
"cairo.import.missingRequiredField": "Missing {count, plural, one {# required field} other {# required fields}}",
|
|
504
506
|
"cairo.table.custom-columns.indication.app": "App",
|
|
505
507
|
"cairo.import.discardChanges.title": "Discard changes?",
|
|
506
508
|
"cairo.tags.collectionPage.popover.emptyState.search.placeholder": "Enter new tag name",
|
|
@@ -604,6 +606,7 @@
|
|
|
604
606
|
"cairo.tags.manageTags.modal.emptyState.body.asLabels": "Labels help you filter and organize your items.",
|
|
605
607
|
"cairo.table.custom-columns.hidden.disabled.tooltip": "This column can’t be hidden.",
|
|
606
608
|
"cairo.import.close": "Close",
|
|
609
|
+
"cairo.import.createNewField": "Create new field",
|
|
607
610
|
"cairo.filtersPanel.header.closeButton.ariaLabel": "Close",
|
|
608
611
|
"cairo.customFields.updateDataExtension.invalid-namespace.error": "Unable to update custom field due to a technical issue on our end.",
|
|
609
612
|
"cairo.filterOperator.startsWith": "Starts With",
|
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
"cairo.table.deleteViewModal.title": "Odstranit toto zobrazení?",
|
|
8
8
|
"cairo.table.advanced-sorting.ascending.order": "Vzestupně",
|
|
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": "Uložit zobrazení",
|
|
11
12
|
"cairo.tags.manageTags.modal.list.input.validation.exists.asLabels": "Tento štítek již existuje.",
|
|
12
13
|
"fields.audio.button.download": "Download track",
|
|
@@ -501,6 +502,7 @@
|
|
|
501
502
|
"cairo.tags.bulkItemUpdate.updatingModal.CTA.asLabels": "Zavřít",
|
|
502
503
|
"cairo.tags.tagsWidget.options.manage.CTA": "Správa tagů",
|
|
503
504
|
"cairo.table.filter.button": "Filtr",
|
|
505
|
+
"cairo.import.missingRequiredField": "Missing {count, plural, one {# required field} other {# required fields}}",
|
|
504
506
|
"cairo.table.custom-columns.indication.app": "App",
|
|
505
507
|
"cairo.import.discardChanges.title": "Discard changes?",
|
|
506
508
|
"cairo.tags.collectionPage.popover.emptyState.search.placeholder": "Zadejte název nového tagu",
|
|
@@ -604,6 +606,7 @@
|
|
|
604
606
|
"cairo.tags.manageTags.modal.emptyState.body.asLabels": "Štítky vám pomáhají filtrovat a organizovat položky.",
|
|
605
607
|
"cairo.table.custom-columns.hidden.disabled.tooltip": "Tento sloupec nelze skrýt.",
|
|
606
608
|
"cairo.import.close": "Close",
|
|
609
|
+
"cairo.import.createNewField": "Create new field",
|
|
607
610
|
"cairo.filtersPanel.header.closeButton.ariaLabel": "Zavřít",
|
|
608
611
|
"cairo.customFields.updateDataExtension.invalid-namespace.error": "Kvůli technickým potížím na naší straně nebylo možné aktualizovat vlastní pole.",
|
|
609
612
|
"cairo.filterOperator.startsWith": "Začíná na",
|
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
"cairo.table.deleteViewModal.title": "Vil du slette denne visning?",
|
|
8
8
|
"cairo.table.advanced-sorting.ascending.order": "Stigende",
|
|
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": "Gem visning",
|
|
11
12
|
"cairo.tags.manageTags.modal.list.input.validation.exists.asLabels": "Denne etiket eksisterer allerede.",
|
|
12
13
|
"fields.audio.button.download": "Download track",
|
|
@@ -501,6 +502,7 @@
|
|
|
501
502
|
"cairo.tags.bulkItemUpdate.updatingModal.CTA.asLabels": "Luk",
|
|
502
503
|
"cairo.tags.tagsWidget.options.manage.CTA": "Administrer tags",
|
|
503
504
|
"cairo.table.filter.button": "Filtrer",
|
|
505
|
+
"cairo.import.missingRequiredField": "Missing {count, plural, one {# required field} other {# required fields}}",
|
|
504
506
|
"cairo.table.custom-columns.indication.app": "App",
|
|
505
507
|
"cairo.import.discardChanges.title": "Discard changes?",
|
|
506
508
|
"cairo.tags.collectionPage.popover.emptyState.search.placeholder": "Indtast nyt tag-navn",
|
|
@@ -604,6 +606,7 @@
|
|
|
604
606
|
"cairo.tags.manageTags.modal.emptyState.body.asLabels": "Etiketter hjælper dig med at filtrere og organisere dine elementer.",
|
|
605
607
|
"cairo.table.custom-columns.hidden.disabled.tooltip": "Denne kolonne kan ikke skjules.",
|
|
606
608
|
"cairo.import.close": "Close",
|
|
609
|
+
"cairo.import.createNewField": "Create new field",
|
|
607
610
|
"cairo.filtersPanel.header.closeButton.ariaLabel": "Luk",
|
|
608
611
|
"cairo.customFields.updateDataExtension.invalid-namespace.error": "Vi kan ikke opdatere et tilpasset felt på grund af et teknisk problem hos os.",
|
|
609
612
|
"cairo.filterOperator.startsWith": "begynder med",
|
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
"cairo.table.deleteViewModal.title": "Diese Ansicht löschen?",
|
|
8
8
|
"cairo.table.advanced-sorting.ascending.order": "Aufsteigend",
|
|
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": "Ansicht speichern",
|
|
11
12
|
"cairo.tags.manageTags.modal.list.input.validation.exists.asLabels": "Dieses Label gibt es bereits.",
|
|
12
13
|
"fields.audio.button.download": "Download track",
|
|
@@ -501,6 +502,7 @@
|
|
|
501
502
|
"cairo.tags.bulkItemUpdate.updatingModal.CTA.asLabels": "Schließen",
|
|
502
503
|
"cairo.tags.tagsWidget.options.manage.CTA": "Tags verwalten",
|
|
503
504
|
"cairo.table.filter.button": "Filtern",
|
|
505
|
+
"cairo.import.missingRequiredField": "Missing {count, plural, one {# required field} other {# required fields}}",
|
|
504
506
|
"cairo.table.custom-columns.indication.app": "App",
|
|
505
507
|
"cairo.import.discardChanges.title": "Discard changes?",
|
|
506
508
|
"cairo.tags.collectionPage.popover.emptyState.search.placeholder": "Neuen Tag-Namen eingeben",
|
|
@@ -604,6 +606,7 @@
|
|
|
604
606
|
"cairo.tags.manageTags.modal.emptyState.body.asLabels": "Labels helfen dir beim Filtern und Ordnen deiner Elemente.",
|
|
605
607
|
"cairo.table.custom-columns.hidden.disabled.tooltip": "Diese Spalte kann nicht ausgeblendet werden.",
|
|
606
608
|
"cairo.import.close": "Close",
|
|
609
|
+
"cairo.import.createNewField": "Create new field",
|
|
607
610
|
"cairo.filtersPanel.header.closeButton.ariaLabel": "Schließen",
|
|
608
611
|
"cairo.customFields.updateDataExtension.invalid-namespace.error": "Wegen eines technischen Problems kann das benutzerdefiniertes Feld nicht aktualisiert werden.",
|
|
609
612
|
"cairo.filterOperator.startsWith": "Beginnt mit",
|
|
@@ -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",
|
|
@@ -501,6 +502,7 @@
|
|
|
501
502
|
"cairo.tags.bulkItemUpdate.updatingModal.CTA.asLabels": "Close",
|
|
502
503
|
"cairo.tags.tagsWidget.options.manage.CTA": "Manage Tags",
|
|
503
504
|
"cairo.table.filter.button": "Filter",
|
|
505
|
+
"cairo.import.missingRequiredField": "Missing {count, plural, one {# required field} other {# required fields}}",
|
|
504
506
|
"cairo.table.custom-columns.indication.app": "App",
|
|
505
507
|
"cairo.import.discardChanges.title": "Discard changes?",
|
|
506
508
|
"cairo.tags.collectionPage.popover.emptyState.search.placeholder": "Enter new tag name",
|
|
@@ -604,6 +606,7 @@
|
|
|
604
606
|
"cairo.tags.manageTags.modal.emptyState.body.asLabels": "Labels help you filter and organize your items.",
|
|
605
607
|
"cairo.table.custom-columns.hidden.disabled.tooltip": "This column can’t be hidden.",
|
|
606
608
|
"cairo.import.close": "Close",
|
|
609
|
+
"cairo.import.createNewField": "Create new field",
|
|
607
610
|
"cairo.filtersPanel.header.closeButton.ariaLabel": "Close",
|
|
608
611
|
"cairo.customFields.updateDataExtension.invalid-namespace.error": "Unable to update custom field due to a technical issue on our end.",
|
|
609
612
|
"cairo.filterOperator.startsWith": "Starts With",
|
|
@@ -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",
|
|
@@ -501,6 +502,7 @@
|
|
|
501
502
|
"cairo.tags.bulkItemUpdate.updatingModal.CTA.asLabels": "Close",
|
|
502
503
|
"cairo.tags.tagsWidget.options.manage.CTA": "Manage Tags",
|
|
503
504
|
"cairo.table.filter.button": "Filter",
|
|
505
|
+
"cairo.import.missingRequiredField": "Missing {count, plural, one {# required field} other {# required fields}}",
|
|
504
506
|
"cairo.table.custom-columns.indication.app": "App",
|
|
505
507
|
"cairo.import.discardChanges.title": "Discard changes?",
|
|
506
508
|
"cairo.tags.collectionPage.popover.emptyState.search.placeholder": "Enter new tag name",
|
|
@@ -604,6 +606,7 @@
|
|
|
604
606
|
"cairo.tags.manageTags.modal.emptyState.body.asLabels": "Labels help you filter and organize your items.",
|
|
605
607
|
"cairo.table.custom-columns.hidden.disabled.tooltip": "This column can’t be hidden.",
|
|
606
608
|
"cairo.import.close": "Close",
|
|
609
|
+
"cairo.import.createNewField": "Create new field",
|
|
607
610
|
"cairo.filtersPanel.header.closeButton.ariaLabel": "Close",
|
|
608
611
|
"cairo.customFields.updateDataExtension.invalid-namespace.error": "Unable to update custom field due to a technical issue on our end.",
|
|
609
612
|
"cairo.filterOperator.startsWith": "Starts With",
|