@case-framework/survey-core 0.1.0 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +181 -0
- package/build/editor.d.mts +169 -5
- package/build/editor.d.mts.map +1 -1
- package/build/editor.mjs +429 -8
- package/build/editor.mjs.map +1 -1
- package/build/index.d.mts +189 -6
- package/build/index.d.mts.map +1 -1
- package/build/index.mjs +361 -2
- package/build/index.mjs.map +1 -1
- package/build/{package.json/package.json → package.json} +1 -1
- package/build/{survey-TUPUXiXl.d.mts → survey-D3sMutUV.d.mts} +63 -3
- package/build/{survey-TUPUXiXl.d.mts.map → survey-D3sMutUV.d.mts.map} +1 -1
- package/build/{survey-C3ZHI-5z.mjs → survey-DQmpzihl.mjs} +249 -183
- package/build/survey-DQmpzihl.mjs.map +1 -0
- package/package.json +1 -1
- package/build/survey-C3ZHI-5z.mjs.map +0 -1
package/build/editor.mjs
CHANGED
|
@@ -1,5 +1,307 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { F as structuredCloneMethod, N as generateId, l as GroupItemCore, m as ReservedSurveyItemTypes, n as SurveyItemTranslations, t as Survey } from "./survey-DQmpzihl.mjs";
|
|
2
2
|
|
|
3
|
+
//#region src/editor/ai-context.ts
|
|
4
|
+
const DEFAULT_SCOPE_LIMITS = {
|
|
5
|
+
tiny: 40,
|
|
6
|
+
focused: 150,
|
|
7
|
+
full: 500
|
|
8
|
+
};
|
|
9
|
+
const DEFAULT_FOCUS_TREE_LIMIT = 120;
|
|
10
|
+
const DEFAULT_TRANSLATION_SNIPPETS_PER_ITEM = 8;
|
|
11
|
+
const DEFAULT_TRANSLATION_SNIPPET_TEXT_LIMIT = 120;
|
|
12
|
+
const PURPOSE_DEFAULTS = {
|
|
13
|
+
generic: {
|
|
14
|
+
scope: "tiny",
|
|
15
|
+
includeRawSurvey: false,
|
|
16
|
+
includeIndexes: false,
|
|
17
|
+
includeFocusItemTree: false
|
|
18
|
+
},
|
|
19
|
+
"key-suggestion": {
|
|
20
|
+
scope: "tiny",
|
|
21
|
+
includeRawSurvey: false,
|
|
22
|
+
includeIndexes: false,
|
|
23
|
+
includeFocusItemTree: true
|
|
24
|
+
},
|
|
25
|
+
"label-suggestion": {
|
|
26
|
+
scope: "tiny",
|
|
27
|
+
includeRawSurvey: false,
|
|
28
|
+
includeIndexes: false,
|
|
29
|
+
includeFocusItemTree: true
|
|
30
|
+
},
|
|
31
|
+
"item-generation": {
|
|
32
|
+
scope: "focused",
|
|
33
|
+
includeRawSurvey: false,
|
|
34
|
+
includeIndexes: true,
|
|
35
|
+
includeFocusItemTree: true
|
|
36
|
+
},
|
|
37
|
+
translation: {
|
|
38
|
+
scope: "focused",
|
|
39
|
+
includeRawSurvey: false,
|
|
40
|
+
includeIndexes: true,
|
|
41
|
+
includeFocusItemTree: true
|
|
42
|
+
},
|
|
43
|
+
"condition-management": {
|
|
44
|
+
scope: "full",
|
|
45
|
+
includeRawSurvey: true,
|
|
46
|
+
includeIndexes: true,
|
|
47
|
+
includeFocusItemTree: true
|
|
48
|
+
}
|
|
49
|
+
};
|
|
50
|
+
const sortByItemId = (items) => [...items].sort((a, b) => a.itemId.localeCompare(b.itemId));
|
|
51
|
+
function getChildIds(survey, itemId) {
|
|
52
|
+
const item = survey.surveyItems.get(itemId);
|
|
53
|
+
if (!(item instanceof GroupItemCore)) return [];
|
|
54
|
+
return [...item.items ?? []];
|
|
55
|
+
}
|
|
56
|
+
function buildParentLookup(survey) {
|
|
57
|
+
const lookup = /* @__PURE__ */ new Map();
|
|
58
|
+
for (const item of survey.surveyItems.values()) {
|
|
59
|
+
if (!(item instanceof GroupItemCore)) continue;
|
|
60
|
+
for (const childId of item.items ?? []) lookup.set(childId, item.id);
|
|
61
|
+
}
|
|
62
|
+
return lookup;
|
|
63
|
+
}
|
|
64
|
+
function createFullKeyGetter(survey, parentLookup) {
|
|
65
|
+
const fullKeyCache = /* @__PURE__ */ new Map();
|
|
66
|
+
const getFullKey = (itemId, stack = /* @__PURE__ */ new Set()) => {
|
|
67
|
+
const cached = fullKeyCache.get(itemId);
|
|
68
|
+
if (cached) return cached;
|
|
69
|
+
const item = survey.surveyItems.get(itemId);
|
|
70
|
+
if (!item) return itemId;
|
|
71
|
+
if (stack.has(itemId)) return item.key;
|
|
72
|
+
const parentId = parentLookup.get(itemId);
|
|
73
|
+
if (!parentId) {
|
|
74
|
+
fullKeyCache.set(itemId, item.key);
|
|
75
|
+
return item.key;
|
|
76
|
+
}
|
|
77
|
+
stack.add(itemId);
|
|
78
|
+
const parentFullKey = getFullKey(parentId, stack);
|
|
79
|
+
stack.delete(itemId);
|
|
80
|
+
const fullKey = `${parentFullKey}.${item.key}`;
|
|
81
|
+
fullKeyCache.set(itemId, fullKey);
|
|
82
|
+
return fullKey;
|
|
83
|
+
};
|
|
84
|
+
return getFullKey;
|
|
85
|
+
}
|
|
86
|
+
function buildFullOutline(survey, parentLookup, getFullKey) {
|
|
87
|
+
const outline = [];
|
|
88
|
+
const visited = /* @__PURE__ */ new Set();
|
|
89
|
+
const toNode = (itemId, depth) => {
|
|
90
|
+
const item = survey.surveyItems.get(itemId);
|
|
91
|
+
if (!item) return;
|
|
92
|
+
const childCount = item instanceof GroupItemCore ? item.items.length : 0;
|
|
93
|
+
return {
|
|
94
|
+
itemId,
|
|
95
|
+
parentId: parentLookup.get(itemId),
|
|
96
|
+
depth,
|
|
97
|
+
itemType: item.type,
|
|
98
|
+
key: item.key,
|
|
99
|
+
fullKey: getFullKey(itemId),
|
|
100
|
+
itemLabel: item.metadata?.itemLabel,
|
|
101
|
+
childCount
|
|
102
|
+
};
|
|
103
|
+
};
|
|
104
|
+
const visit = (itemId, depth) => {
|
|
105
|
+
if (visited.has(itemId)) return;
|
|
106
|
+
visited.add(itemId);
|
|
107
|
+
const node = toNode(itemId, depth);
|
|
108
|
+
if (node) outline.push(node);
|
|
109
|
+
for (const childId of getChildIds(survey, itemId)) visit(childId, depth + 1);
|
|
110
|
+
};
|
|
111
|
+
const root = survey.rootItem;
|
|
112
|
+
if (root) visit(root.id, 0);
|
|
113
|
+
const remaining = sortByItemId(Array.from(survey.surveyItems.values()).filter((item) => !visited.has(item.id)).map((item) => ({ itemId: item.id })));
|
|
114
|
+
for (const item of remaining) visit(item.itemId, 0);
|
|
115
|
+
return outline;
|
|
116
|
+
}
|
|
117
|
+
function collectTinyScopeIds(survey, focusItemId) {
|
|
118
|
+
const ids = /* @__PURE__ */ new Set();
|
|
119
|
+
const rootItem = survey.rootItem;
|
|
120
|
+
if (rootItem) ids.add(rootItem.id);
|
|
121
|
+
ids.add(focusItemId);
|
|
122
|
+
for (const id of survey.getItemPath(focusItemId)) ids.add(id);
|
|
123
|
+
for (const sibling of survey.getSiblings(focusItemId)) ids.add(sibling.id);
|
|
124
|
+
for (const childId of getChildIds(survey, focusItemId)) ids.add(childId);
|
|
125
|
+
return ids;
|
|
126
|
+
}
|
|
127
|
+
function addDescendants(survey, itemId, set, maxDepth) {
|
|
128
|
+
const queue = [{
|
|
129
|
+
id: itemId,
|
|
130
|
+
depth: 0
|
|
131
|
+
}];
|
|
132
|
+
while (queue.length > 0) {
|
|
133
|
+
const current = queue.shift();
|
|
134
|
+
if (!current) continue;
|
|
135
|
+
if (current.depth >= maxDepth) continue;
|
|
136
|
+
for (const childId of getChildIds(survey, current.id)) {
|
|
137
|
+
set.add(childId);
|
|
138
|
+
queue.push({
|
|
139
|
+
id: childId,
|
|
140
|
+
depth: current.depth + 1
|
|
141
|
+
});
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
function collectFocusedScopeIds(survey, focusItemId) {
|
|
146
|
+
const ids = collectTinyScopeIds(survey, focusItemId);
|
|
147
|
+
const ancestors = survey.getItemPath(focusItemId);
|
|
148
|
+
addDescendants(survey, focusItemId, ids, 2);
|
|
149
|
+
for (const sibling of survey.getSiblings(focusItemId)) {
|
|
150
|
+
if (sibling.id === focusItemId) continue;
|
|
151
|
+
ids.add(sibling.id);
|
|
152
|
+
addDescendants(survey, sibling.id, ids, 1);
|
|
153
|
+
}
|
|
154
|
+
for (const ancestorId of ancestors) {
|
|
155
|
+
const siblingIds = (survey.getParentItem(ancestorId)?.items ?? []).filter((id) => id !== ancestorId);
|
|
156
|
+
for (const siblingId of siblingIds) {
|
|
157
|
+
ids.add(siblingId);
|
|
158
|
+
addDescendants(survey, siblingId, ids, 1);
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
return ids;
|
|
162
|
+
}
|
|
163
|
+
function buildFocusInfo(survey, focusItemId) {
|
|
164
|
+
if (!survey.surveyItems.has(focusItemId)) return;
|
|
165
|
+
const pathItemIds = [...survey.getItemPath(focusItemId), focusItemId];
|
|
166
|
+
return {
|
|
167
|
+
focusItemId,
|
|
168
|
+
parentItemId: survey.getParentItem(focusItemId)?.id,
|
|
169
|
+
pathItemIds,
|
|
170
|
+
siblingItemIds: survey.getSiblings(focusItemId).filter((item) => item.id !== focusItemId).map((item) => item.id),
|
|
171
|
+
childItemIds: getChildIds(survey, focusItemId)
|
|
172
|
+
};
|
|
173
|
+
}
|
|
174
|
+
const normalizeSnippetText = (text, maxChars) => {
|
|
175
|
+
return text.trim().replace(/\s+/g, " ").slice(0, maxChars);
|
|
176
|
+
};
|
|
177
|
+
const getContentText = (content, maxChars) => {
|
|
178
|
+
if (!content) return null;
|
|
179
|
+
const maybeText = content.content;
|
|
180
|
+
if (typeof maybeText !== "string") return null;
|
|
181
|
+
const normalized = normalizeSnippetText(maybeText, maxChars);
|
|
182
|
+
return normalized.length > 0 ? normalized : null;
|
|
183
|
+
};
|
|
184
|
+
function getItemTranslationSnippets(survey, itemId, maxSnippets, textLimit) {
|
|
185
|
+
const snippets = [];
|
|
186
|
+
const translations = survey.getItemTranslations(itemId);
|
|
187
|
+
if (!translations) return snippets;
|
|
188
|
+
for (const locale of translations.locales) {
|
|
189
|
+
const localeContent = translations.getAllForLocale(locale);
|
|
190
|
+
if (!localeContent) continue;
|
|
191
|
+
for (const [contentKey, content] of Object.entries(localeContent)) {
|
|
192
|
+
const text = getContentText(content, textLimit);
|
|
193
|
+
if (!text) continue;
|
|
194
|
+
snippets.push({
|
|
195
|
+
locale,
|
|
196
|
+
contentKey,
|
|
197
|
+
text
|
|
198
|
+
});
|
|
199
|
+
if (snippets.length >= maxSnippets) return snippets;
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
return snippets;
|
|
203
|
+
}
|
|
204
|
+
function buildFocusItemTree(survey, focusItemId, getFullKey, options) {
|
|
205
|
+
if (!survey.surveyItems.has(focusItemId)) return { truncated: false };
|
|
206
|
+
let remainingBudget = options.treeLimit;
|
|
207
|
+
let truncated = false;
|
|
208
|
+
const visit = (itemId) => {
|
|
209
|
+
if (remainingBudget <= 0) {
|
|
210
|
+
truncated = true;
|
|
211
|
+
return;
|
|
212
|
+
}
|
|
213
|
+
const item = survey.surveyItems.get(itemId);
|
|
214
|
+
if (!item) return;
|
|
215
|
+
remainingBudget -= 1;
|
|
216
|
+
const siblingKeys = survey.getSiblings(itemId).filter((sibling) => sibling.id !== itemId).map((sibling) => sibling.key);
|
|
217
|
+
const descendants = [];
|
|
218
|
+
if (item instanceof GroupItemCore) for (const childId of item.items) {
|
|
219
|
+
const childNode = visit(childId);
|
|
220
|
+
if (childNode) descendants.push(childNode);
|
|
221
|
+
}
|
|
222
|
+
return {
|
|
223
|
+
itemId: item.id,
|
|
224
|
+
itemType: item.type,
|
|
225
|
+
itemKey: item.key,
|
|
226
|
+
fullKey: getFullKey(item.id),
|
|
227
|
+
itemLabel: item.metadata?.itemLabel,
|
|
228
|
+
siblingKeys,
|
|
229
|
+
translations: getItemTranslationSnippets(survey, item.id, options.snippetsPerItem, options.snippetTextLimit),
|
|
230
|
+
descendants
|
|
231
|
+
};
|
|
232
|
+
};
|
|
233
|
+
return {
|
|
234
|
+
focusItem: visit(focusItemId),
|
|
235
|
+
truncated
|
|
236
|
+
};
|
|
237
|
+
}
|
|
238
|
+
function buildContextIndexes(survey, fullOutline, purpose) {
|
|
239
|
+
const indexes = { keyIndex: fullOutline.map((node) => ({
|
|
240
|
+
itemId: node.itemId,
|
|
241
|
+
itemType: node.itemType,
|
|
242
|
+
key: node.key,
|
|
243
|
+
fullKey: node.fullKey,
|
|
244
|
+
itemLabel: node.itemLabel,
|
|
245
|
+
path: node.fullKey.split(".").slice(0, -1)
|
|
246
|
+
})) };
|
|
247
|
+
if (purpose === "condition-management") indexes.responseSlots = Object.keys(survey.getAvailableResponseValueSlots());
|
|
248
|
+
return indexes;
|
|
249
|
+
}
|
|
250
|
+
function buildSurveyAIContextPack(survey, options = {}) {
|
|
251
|
+
const purpose = options.purpose ?? "generic";
|
|
252
|
+
const purposeDefaults = PURPOSE_DEFAULTS[purpose];
|
|
253
|
+
const scope = options.scope ?? purposeDefaults.scope;
|
|
254
|
+
const defaultLimit = DEFAULT_SCOPE_LIMITS[scope];
|
|
255
|
+
const outlineLimit = Math.max(1, options.outlineLimit ?? defaultLimit);
|
|
256
|
+
const includeRawSurvey = options.includeRawSurvey ?? purposeDefaults.includeRawSurvey;
|
|
257
|
+
const includeIndexes = options.includeIndexes ?? purposeDefaults.includeIndexes;
|
|
258
|
+
const includeFocusItemTree = options.includeFocusItemTree ?? purposeDefaults.includeFocusItemTree;
|
|
259
|
+
const focusItemId = options.focusItemId;
|
|
260
|
+
const focusExists = Boolean(focusItemId && survey.surveyItems.has(focusItemId));
|
|
261
|
+
const parentLookup = buildParentLookup(survey);
|
|
262
|
+
const getFullKey = createFullKeyGetter(survey, parentLookup);
|
|
263
|
+
const fullOutline = buildFullOutline(survey, parentLookup, getFullKey);
|
|
264
|
+
let scopedOutline = fullOutline;
|
|
265
|
+
if (scope === "tiny" && focusItemId && focusExists) {
|
|
266
|
+
const includedIds = collectTinyScopeIds(survey, focusItemId);
|
|
267
|
+
scopedOutline = fullOutline.filter((node) => includedIds.has(node.itemId));
|
|
268
|
+
} else if (scope === "focused" && focusItemId && focusExists) {
|
|
269
|
+
const includedIds = collectFocusedScopeIds(survey, focusItemId);
|
|
270
|
+
scopedOutline = fullOutline.filter((node) => includedIds.has(node.itemId));
|
|
271
|
+
}
|
|
272
|
+
const outlineTruncated = scopedOutline.length > outlineLimit;
|
|
273
|
+
const outline = outlineTruncated ? scopedOutline.slice(0, outlineLimit) : scopedOutline;
|
|
274
|
+
let focusItemTreeTruncated = false;
|
|
275
|
+
let focusItem;
|
|
276
|
+
if (includeFocusItemTree && focusItemId && focusExists) {
|
|
277
|
+
const focusTreeResult = buildFocusItemTree(survey, focusItemId, getFullKey, {
|
|
278
|
+
treeLimit: Math.max(1, options.focusItemTreeLimit ?? DEFAULT_FOCUS_TREE_LIMIT),
|
|
279
|
+
snippetsPerItem: Math.max(1, options.translationSnippetsPerItemLimit ?? DEFAULT_TRANSLATION_SNIPPETS_PER_ITEM),
|
|
280
|
+
snippetTextLimit: Math.max(1, options.translationSnippetTextLimit ?? DEFAULT_TRANSLATION_SNIPPET_TEXT_LIMIT)
|
|
281
|
+
});
|
|
282
|
+
focusItemTreeTruncated = focusTreeResult.truncated;
|
|
283
|
+
focusItem = focusTreeResult.focusItem;
|
|
284
|
+
}
|
|
285
|
+
return {
|
|
286
|
+
purpose,
|
|
287
|
+
scope,
|
|
288
|
+
surveyKey: survey.surveyKey,
|
|
289
|
+
locales: [...survey.locales],
|
|
290
|
+
itemCount: survey.surveyItems.size,
|
|
291
|
+
outline,
|
|
292
|
+
focus: focusItemId ? buildFocusInfo(survey, focusItemId) : void 0,
|
|
293
|
+
focusItem,
|
|
294
|
+
indexes: includeIndexes ? buildContextIndexes(survey, fullOutline, purpose) : void 0,
|
|
295
|
+
flags: {
|
|
296
|
+
outlineTruncated,
|
|
297
|
+
rawSurveyIncluded: includeRawSurvey,
|
|
298
|
+
focusItemTreeTruncated
|
|
299
|
+
},
|
|
300
|
+
rawSurvey: includeRawSurvey ? survey.serialize() : void 0
|
|
301
|
+
};
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
//#endregion
|
|
3
305
|
//#region src/editor/item-copy-paste.ts
|
|
4
306
|
var ItemCopyPaste = class ItemCopyPaste {
|
|
5
307
|
survey;
|
|
@@ -399,8 +701,11 @@ var SurveyEditor = class SurveyEditor {
|
|
|
399
701
|
this._pluginRegistry = pluginRegistry;
|
|
400
702
|
this._undoRedo = new SurveyEditorUndoRedo(survey.serialize(), undoRedoConfig, meta);
|
|
401
703
|
}
|
|
704
|
+
/** Returns an immutable copy of the current survey state. */
|
|
402
705
|
get survey() {
|
|
403
|
-
|
|
706
|
+
const serialized = this._survey.serialize();
|
|
707
|
+
const registry = this._pluginRegistry ?? this._survey.getPluginRegistry();
|
|
708
|
+
return Survey.fromJson(serialized, registry);
|
|
404
709
|
}
|
|
405
710
|
get hasUncommittedChanges() {
|
|
406
711
|
return this._hasUncommittedChanges;
|
|
@@ -535,7 +840,7 @@ var SurveyEditor = class SurveyEditor {
|
|
|
535
840
|
if (target?.index !== void 0) insertIndex = Math.min(target.index, parentGroup.items.length);
|
|
536
841
|
else insertIndex = parentGroup.items.length;
|
|
537
842
|
this._survey.surveyItems.set(item.id, item);
|
|
538
|
-
parentGroup.
|
|
843
|
+
parentGroup.addChild(item.id, insertIndex);
|
|
539
844
|
if (content) this._survey.translations.setItemTranslations(item.id, content);
|
|
540
845
|
}
|
|
541
846
|
removeItem(itemId, nested = false) {
|
|
@@ -572,6 +877,51 @@ var SurveyEditor = class SurveyEditor {
|
|
|
572
877
|
targetGroup.items.splice(insertIndex, 0, itemId);
|
|
573
878
|
return true;
|
|
574
879
|
}
|
|
880
|
+
/**
|
|
881
|
+
* Get a deep copy of an item's raw data.
|
|
882
|
+
* The returned object is independent of the survey—mutating it will not affect the survey.
|
|
883
|
+
* Use this when you need to edit an item in a form or pass it to updateItem after modifications.
|
|
884
|
+
*
|
|
885
|
+
* @param itemId - The ID of the item to copy
|
|
886
|
+
* @returns A deep copy of the item's RawSurveyItem data
|
|
887
|
+
* @throws Error if the item is not found
|
|
888
|
+
*/
|
|
889
|
+
getItemDataCopy(itemId) {
|
|
890
|
+
const item = this._survey.surveyItems.get(itemId);
|
|
891
|
+
if (!item) throw new Error(`Item with id '${itemId}' not found`);
|
|
892
|
+
return JSON.parse(JSON.stringify(item.rawItem));
|
|
893
|
+
}
|
|
894
|
+
/**
|
|
895
|
+
* Update an item's data in the survey.
|
|
896
|
+
* Can update common attributes (displayConditions, disabledConditions, validations, etc.)
|
|
897
|
+
* as well as type-specific config.
|
|
898
|
+
*
|
|
899
|
+
* Use getItemDataCopy to obtain an editable copy, modify it, then pass it here.
|
|
900
|
+
* Alternatively, pass a Partial to merge specific fields (top-level keys only;
|
|
901
|
+
* e.g. config replaces the entire config object).
|
|
902
|
+
*
|
|
903
|
+
* @param itemId - The ID of the item to update (must match data.id if provided)
|
|
904
|
+
* @param rawItemData - Full RawSurveyItem or Partial to merge. The id cannot be changed.
|
|
905
|
+
*/
|
|
906
|
+
updateItem(itemId, rawItemData) {
|
|
907
|
+
const existingItem = this._survey.surveyItems.get(itemId);
|
|
908
|
+
if (!existingItem) throw new Error(`Item with id '${itemId}' not found`);
|
|
909
|
+
if ("id" in rawItemData && rawItemData.id !== void 0 && rawItemData.id !== itemId) throw new Error(`Cannot change item id from '${itemId}' to '${rawItemData.id}'`);
|
|
910
|
+
const merged = {
|
|
911
|
+
...existingItem.rawItem,
|
|
912
|
+
...rawItemData,
|
|
913
|
+
id: itemId
|
|
914
|
+
};
|
|
915
|
+
const newKey = merged.key ?? existingItem.key;
|
|
916
|
+
const parentGroup = this._survey.getParentItem(itemId);
|
|
917
|
+
if (parentGroup) {
|
|
918
|
+
const siblingWithSameKey = (parentGroup.items ?? []).filter((id) => id !== itemId).map((id) => this._survey.surveyItems.get(id)).find((s) => s !== void 0 && s.key === newKey);
|
|
919
|
+
if (siblingWithSameKey) throw new Error(`Key '${newKey}' is already in use by sibling item '${siblingWithSameKey.id}'`);
|
|
920
|
+
}
|
|
921
|
+
const newItem = this._survey.createItemFromRaw(merged);
|
|
922
|
+
this._survey.surveyItems.set(itemId, newItem);
|
|
923
|
+
this.markAsModified();
|
|
924
|
+
}
|
|
575
925
|
updateItemTranslations(itemId, updatedContent) {
|
|
576
926
|
this.markAsModified();
|
|
577
927
|
if (!this._survey.surveyItems.get(itemId)) throw new Error(`Item with id '${itemId}' not found`);
|
|
@@ -579,18 +929,89 @@ var SurveyEditor = class SurveyEditor {
|
|
|
579
929
|
return true;
|
|
580
930
|
}
|
|
581
931
|
/**
|
|
932
|
+
* Update survey-level translations that are not tied to specific items.
|
|
933
|
+
* Use these for survey card, navigation, validation messages, etc.
|
|
934
|
+
*/
|
|
935
|
+
updateSurveyTranslations(updates) {
|
|
936
|
+
this.markAsModified();
|
|
937
|
+
if (updates.surveyCard) this._survey.translations.setSurveyCardContent(updates.surveyCard.locale, updates.surveyCard.content);
|
|
938
|
+
if (updates.navigation) this._survey.translations.setNavigationContent(updates.navigation.locale, updates.navigation.content);
|
|
939
|
+
if (updates.validationMessages) this._survey.translations.setValidationMessages(updates.validationMessages.locale, updates.validationMessages.content);
|
|
940
|
+
}
|
|
941
|
+
/**
|
|
942
|
+
* Get maxItemsPerPage immutably (returns a copy).
|
|
943
|
+
*/
|
|
944
|
+
getMaxItemsPerPage() {
|
|
945
|
+
const val = this._survey.maxItemsPerPage;
|
|
946
|
+
return val ? { ...val } : void 0;
|
|
947
|
+
}
|
|
948
|
+
/**
|
|
949
|
+
* Update maxItemsPerPage.
|
|
950
|
+
*/
|
|
951
|
+
updateMaxItemsPerPage(value) {
|
|
952
|
+
this.markAsModified();
|
|
953
|
+
this._survey.maxItemsPerPage = value ? { ...value } : void 0;
|
|
954
|
+
}
|
|
955
|
+
/**
|
|
956
|
+
* Get metadata immutably (returns a copy).
|
|
957
|
+
*/
|
|
958
|
+
getMetadata() {
|
|
959
|
+
const val = this._survey.metadata;
|
|
960
|
+
return val ? { ...val } : void 0;
|
|
961
|
+
}
|
|
962
|
+
/**
|
|
963
|
+
* Update metadata.
|
|
964
|
+
*/
|
|
965
|
+
updateMetadata(metadata) {
|
|
966
|
+
this.markAsModified();
|
|
967
|
+
this._survey.metadata = metadata ? { ...metadata } : void 0;
|
|
968
|
+
}
|
|
969
|
+
/**
|
|
970
|
+
* Get a template value immutably (returns a deep copy).
|
|
971
|
+
*/
|
|
972
|
+
getTemplateValue(key) {
|
|
973
|
+
const val = this._survey.getTemplateValue(key);
|
|
974
|
+
return val ? structuredCloneMethod(val) : void 0;
|
|
975
|
+
}
|
|
976
|
+
/**
|
|
977
|
+
* Get all template values immutably (returns a new Map with deep-copied values).
|
|
978
|
+
*/
|
|
979
|
+
getTemplateValues() {
|
|
980
|
+
const keys = this._survey.getTemplateValueKeys();
|
|
981
|
+
const result = /* @__PURE__ */ new Map();
|
|
982
|
+
for (const key of keys) {
|
|
983
|
+
const val = this._survey.getTemplateValue(key);
|
|
984
|
+
if (val) result.set(key, structuredCloneMethod(val));
|
|
985
|
+
}
|
|
986
|
+
return result;
|
|
987
|
+
}
|
|
988
|
+
/**
|
|
989
|
+
* Add or replace a template value.
|
|
990
|
+
*/
|
|
991
|
+
setTemplateValue(key, templateValue) {
|
|
992
|
+
this.markAsModified();
|
|
993
|
+
this._survey.setTemplateValue(key, structuredCloneMethod(templateValue));
|
|
994
|
+
}
|
|
995
|
+
/**
|
|
996
|
+
* Remove a template value.
|
|
997
|
+
*/
|
|
998
|
+
removeTemplateValue(key) {
|
|
999
|
+
this.markAsModified();
|
|
1000
|
+
this._survey.deleteTemplateValue(key);
|
|
1001
|
+
}
|
|
1002
|
+
/**
|
|
582
1003
|
* Copy a survey item and all its data to clipboard format
|
|
583
|
-
* @param
|
|
1004
|
+
* @param itemId - The ID of the item to copy
|
|
584
1005
|
* @returns Clipboard data that can be serialized to JSON for clipboard
|
|
585
1006
|
*/
|
|
586
|
-
copyItem(
|
|
587
|
-
return new ItemCopyPaste(this._survey).copyItem(
|
|
1007
|
+
copyItem(itemId) {
|
|
1008
|
+
return new ItemCopyPaste(this._survey).copyItem(itemId);
|
|
588
1009
|
}
|
|
589
1010
|
/**
|
|
590
1011
|
* Paste a survey item from clipboard data to a target location
|
|
591
1012
|
* @param clipboardData - The clipboard data containing the item to paste
|
|
592
1013
|
* @param target - Target location where to paste the item
|
|
593
|
-
* @returns The
|
|
1014
|
+
* @returns The ID of the pasted item
|
|
594
1015
|
*/
|
|
595
1016
|
pasteItem(clipboardData, target) {
|
|
596
1017
|
this.markAsModified();
|
|
@@ -599,5 +1020,5 @@ var SurveyEditor = class SurveyEditor {
|
|
|
599
1020
|
};
|
|
600
1021
|
|
|
601
1022
|
//#endregion
|
|
602
|
-
export { CommitSource, ItemCopyPaste, SurveyEditor, SurveyEditorUndoRedo };
|
|
1023
|
+
export { CommitSource, ItemCopyPaste, SurveyEditor, SurveyEditorUndoRedo, buildSurveyAIContextPack };
|
|
603
1024
|
//# sourceMappingURL=editor.mjs.map
|