UNPKG

survey-creator-core

Version:

A framework-independent core package of the SurveyJS Survey Creator component. With Survey Creator, you can visually design complex, interactive JSON forms and surveys in a drag-and-drop interface.

1,101 lines (1,094 loc) 181 kB
/*! * SurveyJS Creator v2.5.4 * (c) 2015-2025 Devsoft Baltic OÜ - http://surveyjs.io/ * Github: https://github.com/surveyjs/survey-creator * License: https://surveyjs.io/Licenses#SurveyCreator */ import { Helpers, SvgRegistry, ComputedUpdater, Action, SurveyModel, settings, createDropdownActionModel, FunctionFactory, Serializer, ItemValue, matrixDropdownColumnTypes, surveyLocalization, ElementFactory, ActionContainer, Base, LocalizableString, EventBase, hasLicense, glc, QuestionCommentModel, TextAreaModel, CustomError, JsonObject, checkLibraryVersion } from 'survey-core'; import { getLocString, editorLocalization, listComponentCss as listComponentCss$1, SurveyHelper, defaultPropertyGridDefinition, settings as settings$1, PropertyGridModel, SurveyQuestionProperties, getLocaleStrings, UIPreset, SurveyCreatorModel, saveToFileHandler, PredefinedCreatorPresets, CreatorPresets, SurveyJSON5 } from 'survey-creator-core'; class CreatorPresetEditableBase { get navigationPanelName() { return this.path + "_navigation"; } constructor(preset) { this.preset = preset; this.children = []; this.notifyCallback = (message) => { }; } get path() { return this.preset.getPath(); } getJsonPath(model) { return this.path; } get fullPath() { let prefix = this.parent ? this.parent.fullPath : ""; if (this.path && prefix) { prefix += "_"; } return prefix + this.path; } get pageName() { return "page_" + this.fullPath; } getPageTitle(model) { return model.getPageByName(this.pageName).title; } getPageShortTitle(model) { return model.getPageByName(this.pageName).navigationTitle; } get mainPanelName() { return this.path + "_mainPanel"; } getMainElementNames() { return [this.mainPanelName]; } getMainPanelName() { return this.mainPanelName; } getCustomQuestionCssSuffix(question) { return ""; } createPages() { const res = []; const mainPage = this.createMainPage(); if (mainPage) { res.push(mainPage); } this.children.forEach(item => { const pages = item.createPages(); if (Array.isArray(pages)) { pages.forEach(page => res.push(page)); } }); return res; } get questionNames() { return []; } validate(model) { if (!this.validateCore(model)) return false; for (let i = 0; i < this.children.length; i++) { if (!this.children[i].validate(model)) return false; } return true; } validateCore(model) { return true; } createMainPage() { const res = this.createMainPageCore(); if (res) { res.name = this.pageName; } return res; } getBoolVisibleIf(name, isTrue = true) { return "{" + name + "}=" + (isTrue ? "true" : "false"); } getTextVisibleIf(name, val) { return "{" + name + "}='" + val + "'"; } getNotEmptyVisibleIf(name) { return "{" + name + "} notempty"; } createMainPageCore() { return undefined; } getNavigationElementName() { return this.navigationPanelName; } getJsonValue(model, creator, defaultJson) { const page = model.getPageByName(this.pageName); const core = page && page.isVisible ? this.getJsonValueCore(model, creator, defaultJson) : undefined; let hasValue = !!core; const res = hasValue ? core : {}; this.children.forEach(item => { const val = item.getJsonValue(model, creator); if (!!val) { hasValue = true; res[item.getJsonPath(model)] = val; } }); return hasValue ? res : undefined; } getDefaultJsonValue(creator) { const json = this.getDefaultJsonValueCore(creator); this.children.forEach(item => json[item.path] = item.getDefaultJsonValueCore(creator)); return json; } setJsonLocalizationStrings(model, locStrs) { this.setJsonLocalizationStringsCore(model, locStrs); this.children.forEach(item => item.setJsonLocalizationStrings(model, locStrs)); } updateJsonLocalizationStrings(locStrs) { this.updateJsonLocalizationStringsCore(locStrs); this.children.forEach(item => item.updateJsonLocalizationStrings(locStrs)); } dispose() { this.disposeCore(); this.children.forEach(item => item.dispose()); } setupQuestions(model, creatorSetup) { this.setupQuestionsCore(model, creatorSetup); this.children.forEach(item => { item.setupQuestions(model, creatorSetup); }); } resetToDefaults(model, notify = true) { this.restoreValuesFromDefault(model); this.notifyCallback(this.getPageTitle(model) + " " + getLocString("presets.editor.resoredToDefault")); this.children.forEach(item => { item.resetToDefaults(model, notify); }); } setupOnCurrentPage(model, creator, active) { this.setupOnCurrentPageCore(model, creator, active); this.children.forEach(item => { item.setupOnCurrentPage(model, creator, active); }); } updateOnValueChanged(model, name) { this.updateOnValueChangedCore(model, name); this.children.forEach(item => { item.updateOnValueChanged(model, name); }); } updateOnMatrixDetailPanelVisibleChanged(model, creator, options) { this.updateOnMatrixDetailPanelVisibleChangedCore(model, creator, options); this.children.forEach(item => { item.updateOnMatrixDetailPanelVisibleChanged(model, creator, options); }); } onGetMatrixRowActions(model, creator, options) { this.onGetMatrixRowActionsCore(model, creator, options); this.children.forEach(item => { item.onGetMatrixRowActions(model, creator, options); }); } onGetQuestionTitleActions(model, creator, options) { } onGetPanelTitleActions(model, creator, options) { } onMatrixRowDragOver(model, creator, options) { } onMatrixRowRemoving(model, creator, options) { } onMatrixRowAdded(model, creator, options) { } onMatrixCellValueChanged(model, creator, options) { } setupQuestionsValue(model, json, creator) { this.setupQuestionsValueCore(model, json, creator); this.saveValuesAsDefault(model); this.children.forEach(item => { item.setupQuestionsValue(model, !!json ? json[item.path] : undefined, creator); }); } onLocaleChanged(model, json, creator) { this.onLocaleChangedCore(model, json, creator); this.children.forEach(item => { item.setupQuestionsValue(model, !!json ? json[item.path] : undefined, creator); }); } saveValuesAsDefault(model) { this.questionNames.forEach(name => model.getQuestionByName(name).defaultValue = model.getValue(name) && JSON.parse(JSON.stringify(model.getValue(name)))); } restoreValuesFromDefault(model) { this.questionNames.forEach(name => model.getQuestionByName(name).value = model.getQuestionByName(name).defaultValue && JSON.parse(JSON.stringify(model.getQuestionByName(name).defaultValue))); } setupQuestionsCore(model, creatorSetup) { } resetToDefaultsCore(model) { } setupQuestionsValueCore(model, json, creator) { } onLocaleChangedCore(model, json, creator) { } getJsonValueCore(model, creator, defaultJson) { return undefined; } getDefaultJsonValueCore(creator) { return {}; } setJsonLocalizationStringsCore(model, locStrs) { } updateJsonLocalizationStringsCore(locStrs) { } disposeCore() { } setupOnCurrentPageCore(model, creator, active) { } updateOnValueChangedCore(model, name) { } updateOnMatrixDetailPanelVisibleChangedCore(model, creator, options) { } onGetMatrixRowActionsCore(model, creator, options) { } copyJson(json) { return Helpers.getUnbindValue(json); } static updateModifiedText(locStrs, text, localizationName) { if (!localizationName) return undefined; if (!text) return; const presetStrs = editorLocalization.presetStrings; editorLocalization.presetStrings = undefined; if (text !== editorLocalization.getString(localizationName)) { CreatorPresetEditableBase.saveTextInLocStrs(locStrs, text, localizationName); } editorLocalization.presetStrings = presetStrs; } static saveTextInLocStrs(locStrs, text, localizationName) { const paths = localizationName.split("."); for (let i = 0; i < paths.length - 1; i++) { const path = paths[i]; if (!locStrs[path]) { locStrs[path] = {}; } locStrs = locStrs[path]; } locStrs[paths[paths.length - 1]] = text; } } var presetsCss = { root: "sps-root-modern", container: "sps-container-modern", header: "sps-title sps-container-modern__title", body: "sps-body", bodyEmpty: "sps-body sps-body--empty", footer: "sps-footer sps-body__footer sps-clearfix", title: "", description: "", logo: "sps-logo", logoImage: "sps-logo__image", headerText: "sps-header__text", navigationButton: "", bodyNavigationButton: "", completedPage: "sps-completedpage", navigation: { complete: "sps-btn sps-btn--primary-brand sps-footer__complete-btn", prev: "sps-btn sps-btn--secondary-brand sps-footer__prev-btn", next: "sps-btn sps-btn--primary-brand sps-footer__next-btn", start: "sps-btn sps-footer__start-btn", preview: "sps-btn sps-footer__preview-btn", edit: "sps-btn sps-footer__edit-btn" }, list: JSON.parse(JSON.stringify(listComponentCss$1)), panel: { withFrame: "sps-panel--with-frame", nested: "sps-panel--nested", expandableAnimating: "", header: "sps-panel__header", title: "sps-title sps-panel__title", titleBar: "sd-action-title-bar sps-action-title-bar", contentEnter: "sps-panel__content--enter", contentLeave: "sps-panel__content--leave", titleExpandable: "sps-panel__title--expandable", titleExpanded: "sps-panel__title--expanded", titleCollapsed: "sps-panel__title--collapsed", titleOnError: "sps-panel__title--error", description: "sps-description sps-panel__description", container: "sps-panel sps-row__panel", content: "sps-panel__content", icon: "sps-panel__icon", iconExpanded: "sps-panel__icon--expanded", footer: "sps-panel__footer", requiredMark: "sps-panel__required-text", collapsed: "sps-panel--collapsed", expanded: "sps-panel--expanded", }, paneldynamic: { nested: "", mainRoot: "sps-question sps-row__question", root: "sps-paneldynamic", navigation: "sps-paneldynamic__navigation", title: "sps-title sps-question__title", button: "sps-action-button sps-action-button--text", buttonRemove: "sps-action-button--danger", buttonAdd: "sps-paneldynamic__add-btn", panelsContainer: "", panelWrapper: "sps-paneldynamic__panel-wrapper", panelWrapperList: "", progressTop: "sps-paneldynamic__progress sps-paneldynamic__progress--top", progressBottom: "sps-paneldynamic__progress sps-paneldynamic__progress--bottom", buttonPrev: "sps-paneldynamic__prev-btn", buttonNext: "sps-paneldynamic__next-btn", progressContainer: "sps-paneldynamic__progress-container", progress: "sps-progress", progressBar: "sps-progress__bar", progressText: "sps-paneldynamic__progress-text", panelFooter: "sps-panel__footer", separator: "sps-paneldynamic__separator", footer: "sps-paneldynamic__footer", footerButtonsContainer: "sps-paneldynamic__buttons-container", }, progress: "sps-progress sps-body__progress", progressBar: "sps-progress__bar", progressText: "sps-progress__text", progressTextInBar: "sps-hidden", page: { root: "sps-page sps-body__page", title: "sps-title sps-page__title", description: "sps-description sps-page__description" }, pageTitle: "sps-title sps-page__title", pageDescription: "sps-description sps-page__description", row: "sps-row sps-clearfix", rowEnter: "sps-row--enter", rowLeave: "sps-row--leave", rowDelayedEnter: "sps-row--delayed-fade-in", rowMultiple: "sps-row--multiple", question: { withFrame: "sps-question--with-frame", nested: "sps-question--nested", mainRoot: "sps-question sps-row__question", flowRoot: "sps-question sps-row__question sps-row__question--flow", asCell: "sps-table__cell", header: "sps-question__header", headerLeft: "sps-question__header--location--left", headerTop: "sps-question__header--location--top", headerBottom: "sps-question__header--location--bottom", content: "sps-question__content", contentLeft: "sps-question__content--left", titleLeftRoot: "sps-question--location--left", titleOnAnswer: "sps-question__title--answer", titleOnError: "sps-question__title--error", title: "sps-title sps-question__title", titleBar: "sd-action-title-bar sps-action-title-bar", requiredMark: "sps-question__required-text", number: "sps-question__num", description: "sps-description sps-question__description", descriptionUnderInput: "sps-question__description--under", comment: "sps-comment", required: "sps-question--required", titleRequired: "sps-question__title--required", indent: 0, footer: "sps-question__footer", formGroup: "sps-question__form-group", hasError: "", readOnly: "sd-question--readonly sps-question--disabled", confirmDialog: "sps-popup--confirm sv-popup--confirm svc-creator-popup", errorsContainerBottom: "sps-question__erbox--below-question", }, checkbox: { root: "sps-selectbase", item: "sps-item sps-checkbox sps-selectbase__item", itemSelectAll: "sps-checkbox--selectall", itemNone: "sps-checkbox--none", itemReadOnly: "sps-item--disabled sps-checkbox--disabled", itemChecked: "sps-checkbox--checked", itemHover: "sps-checkbox--allowhover", itemInline: "sps-selectbase__item--inline", label: "sps-selectbase__label", // label: "sps-checkbox", itemSvgIconId: "#icon-check-16x16", labelChecked: "", //itemControl: "sps-visuallyhidden sps-item__control", itemControl: "sps-checkbox__control", itemDecorator: "sps-checkbox__svg", //itemDecorator: "sps-checkbox__hidden", //controlLabel: "sps-item__control-label", controlLabel: "sps-checkbox__caption", materialDecorator: "sps-checkbox__rectangle", //materialDecorator: "sps-item__decorator sps-checkbox__decorator", other: "sps-comment sps-question__other", column: "sps-selectbase__column" }, radiogroup: { root: "sps-selectbase", item: "sps-item sps-radio sps-selectbase__item", itemInline: "sps-selectbase__item--inline", label: "sps-selectbase__label", labelChecked: "", itemReadOnly: "sps-item--disabled sps-radio--disabled", itemChecked: "sps-radio--checked", itemHover: "sps-radio--allowhover", itemControl: "sps-visuallyhidden sps-item__control", itemDecorator: "sps-item__svg sps-radio__svg", controlLabel: "sps-item__control-label", materialDecorator: "sps-item__decorator sps-radio__decorator", other: "sps-comment sps-question__other", clearButton: "sps-btn sps-selectbase__clear-btn", column: "sps-selectbase__column" }, boolean: { mainRoot: "sps-question sps-row__question sps-question--boolean", rootCheckbox: "sps-selectbase", checkboxItem: "sps-checkbox", checkboxItemChecked: "sps-checkbox--checked", checkboxitemIndeterminate: "sps-checkbox--indeterminate", checkboxItemReadOnly: "sps-checkbox--disabled", svgIconId: "#icon-v2check", checkboxLabel: "sps-selectbase__label", controlCheckbox: "sps-checkbox__control", checkboxControlLabel: "sps-checkbox__caption", checkboxItemDecorator: "sps-checkbox__svg", checkboxMaterialDecorator: "sps-checkbox__rectangle" }, text: { root: "sps-input sps-text", controlReadOnly: "sps-input--readonly", small: "sps-row__question--small", content: "sps-question__content sps-text__content", remainingCharacterCounter: "sps-remaining-character-counter", onError: "sps-input--error" }, comment: { root: "sps-input sps-comment", content: "sps-question__content sps-comment__content", remainingCharacterCounter: "sps-remaining-character-counter", small: "sps-row__question--small", onError: "sps-input--error" }, dropdown: { root: "sps-selectbase", popup: "sps-dropdown-popup svc-creator-popup", small: "sps-row__question--small sd-row__question--small", control: "sps-input sps-dropdown", controlEmpty: "sps-dropdown--empty sd-dropdown--empty", controlValue: "sps-dropdown__value", filterStringInput: "sd-dropdown__filter-string-input sps-dropdown__filter-string-input", other: "sps-comment sps-question__other", onError: "sps-input--error", selectWrapper: "sv-dropdown_select-wrapper sps-dropdown_select-wrapper", chevronButtonIconId: "icon-chevron", cleanButton: "sps-dropdown__clean-button sps-input__edit-button", controlReadOnly: "sps-input--readonly sd-input--disabled sd-input--readonly", hintPrefix: "sps-dropdown__hint-prefix sd-dropdown__hint-prefix", hintSuffix: "sps-dropdown__hint-suffix sd-dropdown__hint-suffix" }, tagbox: { cleanItemButton: "sd-tagbox-item_clean-button sps-tagbox-item_clean-button", cleanItemButtonSvg: "sd-tagbox-item_clean-button-svg sps-tagbox-item_clean-button-svg", control: "sd-input sd-tagbox sd-dropdown sps-tagbox sps-dropdown", controlValue: "sd-tagbox__value sd-dropdown__value sps-tagbox__value", filterStringInput: "sd-dropdown__filter-string-input sps-dropdown__filter-string-input", }, matrix: { tableWrapper: "sps-matrix sps-table-wrapper", root: "sps-table", rowError: "sps-matrix__row--error", cell: "sps-table__cell sps-matrix__cell", headerCell: "sps-table__cell sps-table__cell--header", label: "sps-item sps-radio sps-matrix__label", itemValue: "sps-visuallyhidden sps-item__control sps-radio__control", itemChecked: "sps-radio--checked", itemReadOnly: "sps-item--disabled sps-radio--disabled", itemHover: "sps-radio--allowhover", materialDecorator: "sps-item__decorator sps-radio__decorator", itemDecorator: "sps-item__svg sps-radio__svg", cellText: "sps-matrix__text", cellTextSelected: "sps-matrix__text--checked", cellTextReadOnly: "sps-matrix__text--disabled", }, matrixdropdown: { tableWrapper: "sps-table-wrapper", root: "sps-table", cell: "sps-table__cell", headerCell: "sps-table__cell sps-table__cell--header", emptyCell: "sps-table__cell--empty", rowEnter: "sps-table__row--enter", rowLeave: "sps-table__row--leave", }, matrixdynamic: { mainRoot: "sps-question sps-question--matrixdynamic sd-element sd-question sd-row__question sd-element--complex sd-question--complex sd-question--table", tableWrapper: "sps-table-wrapper", root: "sps-table sps-matrixdynamic", content: "sps-matrixdynamic__content sps-text__content", cell: "sps-table__cell", row: "sps-table__row", rowDisabled: "sps-table__row-disabled", rowReadOnly: "sps-table__row-readonly", headerCell: "sps-table__cell sps-table__cell--header", button: "sps-btn", detailRow: "sps-table__row sps-table__row--detail", detailButton: "sps-table__cell--detail-button sps-action-button", detailButtonExpanded: "sps-table__cell--detail-button--expanded", detailIcon: "sps-detail-panel__icon sps-action-button__icon", detailIconExpanded: "sps-detail-panel__icon--expanded", detailIconExpandedId: "icon-collapse-24x24", detailIconId: "icon-expand-24x24", detailPanelCell: "sps-table__cell sps-table__cell--detail-panel", actionsCell: "sps-table__cell sps-table__cell--actions", buttonAdd: "sps-matrixdynamic__add-btn sps-action-button sps-action-button--large", buttonRemove: "sps-matrixdynamic__remove-btn", iconAdd: "", iconRemove: "xxx", dragElementDecorator: "sps-drag-element__svg", iconDragElement: "#icon-drag-24x24", iconDrag: "sps-matrixdynamic__drag-element", footer: "sps-matrixdynamic__footer", dragDropGhostPositionTop: "sps-matrixdynamic__drag-drop-ghost-position-top", dragDropGhostPositionBottom: "sps-matrixdynamic__drag-drop-ghost-position-bottom", noRowsSection: "sps-matrixdynamic__placeholder", noRowsText: "sps-matrixdynamic__placeholder-text", cellQuestionWrapper: "sps-table__question-wrapper", draggedRow: "sps-matrixdynamic__dragged-row", emptyCell: "sps-table__cell--empty", rowEmpty: "sps-table__row--empty", rowEnter: "sps-table__row--enter", rowLeave: "sps-table__row--leave", }, actionBar: { root: "sps-action-bar", item: "sps-action-button", itemPressed: "sps-action-button--pressed", itemAsIcon: "sps-action-button--icon", itemIcon: "sps-action-button__icon", itemTitle: "sps-action-button__title", } }; class CreatorPresetEditableList extends CreatorPresetEditableBase { constructor() { super(...arguments); //private replaceNonLettersWithDash(inputString) { // return inputString?.replace(/[^a-zA-Z0-9]/g, "-"); //} this.defaultIcon = "square-dashed-24x24"; } get nameItems() { return this.path + "_items"; } get nameMatrix() { return this.fullPath + "_matrix"; } hasIcon(_) { return false; } getMainElementNames() { return [this.nameItems]; } get iconList() { return Object.keys(SvgRegistry.icons).map(name => "icon-" + name); } getMatrixKeyColumnName(question) { return "name"; } getDefaultItems(question) { return this.defaultItems; } getDefaultItem(question, key) { const keyColumn = this.getMatrixKeyColumnName(question); return this.getDefaultItems(question).filter(i => i[keyColumn] == key)[0]; } //private fillAutoName(question: QuestionMatrixDynamicModel, propName: string) { // question.value?.filter(v =>v.isDefault === false && !v[propName]).forEach(v => v[propName] = this.replaceNonLettersWithDash(v.title)); //} updateOnValueChangedCore(model, name) { if (this.needToSetActions(name)) { const matrix = model.getQuestionByName(name); this.updateMatrixRowActions(model, matrix); } } updateMatrixRowActions(model, matrix) { matrix.renderedTable.rows.forEach(r => { var _a, _b, _c; if (!r.row) return; const iconActions = (_b = (_a = r.cells[1]) === null || _a === void 0 ? void 0 : _a.item) === null || _b === void 0 ? void 0 : _b.value.actions; this.updateRowActions(matrix, r.row, iconActions); const actions = (_c = r.cells[r.cells.length - 1].item) === null || _c === void 0 ? void 0 : _c.value.actions; this.updateRowActions(matrix, r.row, actions); }); } updateRowActions(question, row, actions) { if (!actions) return; const keyColumn = this.getMatrixKeyColumnName(question); if (!question.value) return; const rowData = question.value.filter(r => { var _a; return ((_a = row.value) === null || _a === void 0 ? void 0 : _a[keyColumn]) == (r === null || r === void 0 ? void 0 : r[keyColumn]); })[0]; if (!rowData) return; actions.forEach(a => this.updateRowAction(question, row, rowData, keyColumn, a)); } updateRowAction(question, row, rowData, keyColumn, action) { if (action.id == "icon-action") { action.iconName = rowData.iconName || this.defaultIcon; } if (action.id == "reset-to-default") { const defaultItem = this.getDefaultItem(question, rowData[keyColumn]); if (!defaultItem) return; const defaultData = {}; Object.keys(rowData).forEach(key => defaultData[key] = defaultItem[key]); action.enabled = !Helpers.isTwoValueEquals(rowData, defaultData); } } createResetAction(model, row, action) { return { id: "reset-to-default", iconName: "icon-reset", tooltip: getLocString("presets.items.restoreToDefault"), location: "end", visibleIndex: 15, action: action }; } createEditAction(model, creator, question, row) { return { id: "edit-item", iconName: "icon-edit", tooltip: getLocString("presets.items.edit"), location: "end", visibleIndex: 13, action: () => { this.editItem(model, creator, question, row); } }; } createIconAction(iconName, cssClass = "sps-matrixdynamic__row-icon") { return { id: "icon-action", iconName: iconName, innerCss: cssClass, location: "start", enabled: false }; } setupStandardActions(actions, question, row, allowExpand, isItemsMatrix) { actions.forEach(a => { if (a.id == "show-detail") { a.location = "end"; a.iconName = "icon-expand-24x24"; a.title = new ComputedUpdater(() => row.isDetailPanelShowing ? getLocString("presets.items.collapse") : getLocString("presets.items.expand")); a.tooltip = getLocString("presets.items.expand"); a.visibleIndex = 10; a.visible = allowExpand; } if (a.id == "remove-row") { a.visibleIndex = 20; a.component = "sv-action-bar-item"; a.action = () => question.removeRowUI(row); a.iconName = isItemsMatrix ? "icon-add_24x24" : "icon-remove_24x24"; a.tooltip = isItemsMatrix ? getLocString("presets.items.add") : getLocString("presets.items.delete"); } }); } editItem(model, creator, question, row, options) { let survey; let resetAction; const itemKey = this.getMatrixKeyColumnName(question); const resetActionParams = { id: "reset-to-default", title: getLocString("presets.editor.resetToDefault"), css: "sps-action--grow", innerCss: "sps-btn sps-btn--secondary-alert", visibleIndex: 15, action: (a) => { const defaultItem = this.getDefaultItem(question, survey.getValue(itemKey)); survey.data = defaultItem; resetAction.enabled = false; this.notifyCallback(getLocString("presets.editor.itemRestoredToDefault")); } }; resetAction = new Action(resetActionParams); survey = this.showDetailPanelInPopup(question, row, model.rootElement, { actions: [resetAction], title: options === null || options === void 0 ? void 0 : options.description, removeOnCancel: options === null || options === void 0 ? void 0 : options.isNew }); resetAction.enabled = !Helpers.isTwoValueEquals(survey.data, this.getDefaultItem(question, survey.getValue(itemKey))); survey.onValueChanged.add(() => resetAction.enabled = true); const keyQuestion = survey.getQuestionByName(itemKey); if (this.getDefaultItem(question, keyQuestion.value)) { keyQuestion.readOnly = true; } } resetItem(model, question, row) { const name = row.getValue("name"); const defaultItems = this.getDefaultItem(question, name); if (defaultItems) { const value = question.value; const itemRow = value.filter(v => v.name == name)[0]; Object.keys(itemRow).forEach((key) => { itemRow[key] = defaultItems[key]; }); question.value = value; } this.notifyCallback(getLocString("presets.editor.itemRestoredToDefault")); } restoreItems(questionItems, questionHiddenItems, rowIndex) { const rowData = questionHiddenItems.value[rowIndex]; const value = questionItems.value ? [...questionItems.value] : []; value.push(rowData); questionItems.value = value; } getMatrix(model) { return model.getQuestionByName(this.nameMatrix); } isItemsMatrix(name) { return name === this.nameMatrix; } needToSetActions(name) { return this.isItemsMatrix(name); } onGetMatrixRowActionsCore(model, creator, options) { var _a, _b; if (this.needToSetActions(options.question.name)) { const question = options.question; const allowExpand = question.detailElements.filter(e => e.visible).length > 0; if (this.hasIcon(options.question.name)) { const keyColumn = this.getMatrixKeyColumnName(options.question); const iconName = ((_b = (_a = question.value) === null || _a === void 0 ? void 0 : _a.filter(v => v[keyColumn] == options.row.getValue(keyColumn))[0]) === null || _b === void 0 ? void 0 : _b.iconName) || this.defaultIcon; options.actions.push(this.createIconAction(iconName)); } const resetAction = this.createResetAction(model, options.row, (action) => { this.resetItem(model, question, options.row); action.enabled = false; }); options.actions.push(resetAction); options.actions.push(this.createEditAction(model, creator, question, options.row)); this.setupStandardActions(options.actions, question, options.row, allowExpand, question.name == this.nameMatrix); this.updateRowActions(question, options.row, options.actions); } } onMatrixRowDragOver(model, creator, options) { if (this.isItemsMatrix(options.fromMatrix.name) && this.isItemsMatrix(options.toMatrix.name)) { options.allow = true; } } onMatrixRowRemoving(model, creator, options) { if (this.isItemsMatrix(options.question.name) && options.question.name != this.nameMatrix) { const rowData = options.question.value[options.rowIndex]; const hiddenItems = this.getMatrix(model); const value = hiddenItems.value ? [...hiddenItems.value] : []; value.push(rowData); hiddenItems.value = value; } } getExistingKeys(model, key) { const items = model.getQuestionByName(this.nameItems).value || []; const unsorted = model.getQuestionByName(this.nameMatrix).value || []; return [...items, ...unsorted]; } getDefaultValueForRow(model, question, key) { return SurveyHelper.getNewName(this.getExistingKeys(model, key).map(i => i[key]).filter(v => !!v).map(r => ({ name: r })), key); } setDefaultValueForRow(model, question, row) { const key = this.getMatrixKeyColumnName(question); const value = this.getDefaultValueForRow(model, question, key); row.getQuestionByName(key).value = value; row.getQuestionByName("title").value = value; } onMatrixRowAdded(model, creator, options) { var _a, _b; if (this.isItemsMatrix(options.question.name)) { this.setDefaultValueForRow(model, options.question, options.row); this.editItem(model, creator, options.question, options.row, { description: getLocString("presets.items.newItem") + " " + (((_b = (_a = options.question.data) === null || _a === void 0 ? void 0 : _a.value) === null || _b === void 0 ? void 0 : _b.title) || this.getPageShortTitle(model)), isNew: true }); } } onMatrixCellValueChanged(model, creator, options) { if (this.needToSetActions(options.question.name)) { const renderedRow = options.question.renderedTable.rows.find(r => r.row == options.row); if (!renderedRow) return; const actions = renderedRow.cells[renderedRow.cells.length - 1].item.value.actions; if (!actions) return; this.updateRowActions(options.question, options.row, actions); } } showDetailPanelInPopup(matrix, row, rootElement, options) { var _a; const index = matrix.visibleRows.findIndex(r => r === row); const data = matrix.value[index]; const survey = new SurveyModel({ elements: matrix.toJSON().detailElements }); survey.fitToContainer = false; survey.showNavigationButtons = false; survey.data = data; survey.css = presetsCss; survey.enterKeyAction = "loseFocus"; survey.questionErrorLocation = "bottom"; if (settings.showDialog) { const popupModel = (_a = settings.showDialog) === null || _a === void 0 ? void 0 : _a.call(settings, { componentName: "survey", data: { survey: survey, model: survey }, onApply: () => { if (survey.validate()) { const newValue = [...matrix.value]; const newData = {}; survey.getAllQuestions().forEach(q => { if (q.visible) { newData[q.name] = survey.data[q.name]; } }); const newRowValue = Object.assign(Object.assign({}, matrix.value[index]), newData); newValue[index] = newRowValue; matrix.value = newValue; this.updateMatrixRowActions(matrix.survey, matrix); return true; } else { return false; } }, onCancel: () => { if (options.removeOnCancel) { matrix.removeRowUI(row); } return true; }, cssClass: "sps-popup svc-property-editor svc-creator-popup", title: options.title || getLocString("presets.editor.edit"), displayMode: "popup" }, rootElement); if (survey.getAllQuestions().filter(q => !q.startWithNewLine).length > 0) { popupModel.width = "100%"; } if (popupModel.footerToolbar) { const defaultActionBarCss = popupModel.footerToolbar.cssClasses; defaultActionBarCss.item = "sps-btn"; popupModel.footerToolbar.cssClasses = defaultActionBarCss; popupModel.footerToolbar.getActionById("apply").innerCss = "sps-btn--primary-brand"; popupModel.footerToolbar.getActionById("cancel").innerCss = "sps-btn--secondary-brand"; if (options.actions) { popupModel.footerToolbar.actions.unshift(...options.actions); } } survey.getAllPanels().forEach(q => q.visible = !q.visible); survey.getAllQuestions().forEach(q => { q.visible = !q.visible; if (q.isRequired) { q.requiredErrorText = getLocString("presets.editor.required"); } }); } return survey; } } var listComponentCss = { root: "sps-list__container", itemsContainer: "sps-list", itemsContainerFiltering: "sps-list--filtering", emptyContainer: "sps-list__empty-container", emptyText: "sps-list__empty-text", filter: "sps-list__filter", filterIcon: "sps-list__filter-icon", filterInput: "sps-list__input", searchClearButtonIcon: "sps-list__filter-clear-button", loadingIndicator: "sps-list__loading-indicator", item: "sps-list__item", itemSelected: "sps-list__item--selected", itemGroup: "sps-list__item--group", itemGroupSelected: "sps-list__item--group-selected", itemWithIcon: "sps-list__item--with-icon", itemDisabled: "sps-list__item--disabled", itemFocused: "sps-list__item--focused", itemHovered: "sps-list__item--hovered", itemTextWrap: "sps-list__item-text--wrap", itemIcon: "sps-list__item-icon", itemMarkerIcon: "sps-list-item__marker-icon", itemSeparator: "sps-list__item-separator", itemBody: "sps-list__item-body", }; class CreatorPresetEditableCaregorizedListConfigurator extends CreatorPresetEditableList { get defaultCategoriesMap() { return this.defaultCategories.reduce((acc, i) => { acc[i.category] = i; return acc; }, {}); } getDefaultItems(question) { return (question === null || question === void 0 ? void 0 : question.name) === this.nameCategories ? this.defaultCategories : this.defaultItems; } get nameInnerMatrix() { return "items"; } get nameCategories() { return this.fullPath + "_categories"; } getMainElementNames() { return [this.nameCategories]; } getMatrixKeyColumnName(question) { return question.name === this.nameCategories ? "category" : "name"; } get questionNames() { return [this.nameCategories]; } setupCategoryActions(model, creator, question, row, actions) { actions.forEach(a => { if (a.id == "remove-row") { a.iconName = "icon-delete_24x24"; a.tooltip = getLocString("presets.items.delete"); a.innerCss = "sps-action-button sps-action-button--icon sps-action-button--danger"; } if (a.id == "reset-to-default") { a.action = () => { this.resetCategory(model, row); }; } }); } ejectRowData(question, row, remove) { const value = question.value; const rowDataIndex = question.visibleRows.indexOf(row); const rowData = value[rowDataIndex]; if (remove) { value.splice(rowDataIndex, 1); question.value = value; } return rowData; } moveToCategory(model, question, row, categoryName, remove = false) { const rowData = this.ejectRowData(question, row, remove); const categories = this.getQuestionCategories(model); const catValue = categories.value; const general = this.findOrCreateCategory(catValue, categoryName); general[this.nameInnerMatrix].push(rowData); categories.value = catValue; return categories.visibleRows.find(r => r.getValue("category") == categoryName); } itemMenuCategoriesEnabled(model) { return true; } setSubitemsToAction(action, items) { action.setSubItems({ items: items, cssClasses: listComponentCss }); action.markerIconName = "icon-chevronright-24x24"; } getItemMenuActionsCore(model, question, row) { const categoriesQuestion = this.getQuestionCategories(model); const categories = categoriesQuestion.value; const actions = []; const isUnsorted = question.name == this.nameMatrix; const hasCategories = this.itemMenuCategoriesEnabled(model); if (!isUnsorted) { actions.push(new Action({ id: "remove-from", title: getLocString("presets.items.removeFrom").replace("{0}", question.title), action: () => { const rowDataIndex = question.visibleRows.indexOf(row); question.removeRow(rowDataIndex); } })); } else { if (hasCategories) { actions.push(new Action({ id: "move-to", title: getLocString("presets.items.moveTo"), css: "sps-list__item--label", enabled: false })); } else { actions.push(new Action({ id: "restore-item", title: getLocString("presets.toolbox.addToToolbox"), action: () => { const rowDataIndex = question.visibleRows.indexOf(row); question.removeRow(rowDataIndex); } })); } } if (!hasCategories) return actions; const currentCategory = categories.filter(c => (c[this.nameInnerMatrix] || []).filter(i => { var _a; return i.name == ((_a = row.value) === null || _a === void 0 ? void 0 : _a.name); }).length > 0)[0]; const moveToCategories = categories.filter((i) => i.category != (currentCategory === null || currentCategory === void 0 ? void 0 : currentCategory.category)).map((i) => new Action({ id: "to-" + i.category, title: i.title, action: () => { this.moveToCategory(model, question, row, i.category, true); } })); if (!isUnsorted) { actions.push(new Action({ id: "categories", title: getLocString("presets.items.categoriesLabel"), css: "sps-list__item--label", enabled: false, needSeparator: true })); const catGroup = new Action({ id: "move-to-categories", title: getLocString("presets.items.moveToCategory") }); this.setSubitemsToAction(catGroup, moveToCategories); actions.push(catGroup); } else { actions.push(...moveToCategories); } actions.push(new Action({ id: "move-to-new-category", title: getLocString("presets.items.moveToNewCategory"), needSeparator: isUnsorted, action: () => { const newCatRow = this.moveToCategory(model, question, row, this.getDefaultValueForRow(model, question, "category"), true); this.editItem(model, null, categoriesQuestion, newCatRow, { description: getLocString("presets.items.newCategory") + " " + this.getPageShortTitle(model), isNew: true }); } })); return actions; } getItemMenuActions(model, question, row) { const actions = this.getItemMenuActionsCore(model, question, row); if (!this.getDefaultItem(question, row.value.name)) { actions.push(new Action({ id: "remove-custom-item", title: getLocString("presets.toolbox.deleteCustomItem"), css: "sps-list__item--alert", needSeparator: true, action: () => { this.ejectRowData(question, row, true); } })); } return actions; } replaceRemoveAction(model, question, row, actions) { const originalAction = actions.filter(a => a.id == "remove-row")[0]; if (originalAction) { originalAction.visible = false; const addAction = createDropdownActionModel({ id: "context-menu", iconName: "more-circle-24x24", tooltip: getLocString("presets.items.more"), location: "end", visibleIndex: 20 }, { items: [], showPointer: false, verticalPosition: "bottom", horizontalPosition: "center", cssClass: "sps-popup-menu sps-popup-menu--context", cssClasses: listComponentCss, searchEnabled: false }); addAction.popupModel.onVisibilityChanged.add((_, opt) => { if (opt.isVisible) { const listModel = opt.model.contentComponentData.model; listModel.actions = this.getItemMenuActions(model, question, row); listModel.flushUpdates(); } }); actions.push(addAction); } } getQuestionCategories(model) { return model.getQuestionByName(this.nameCategories); } isItemsMatrix(name) { return super.isItemsMatrix(name) || name === this.nameInnerMatrix; } resetCategory(model, row) { var _a; const category = row.getValue("category"); const defaultItems = (_a = this.defaultCategories.filter(i => i.category == category)[0]) === null || _a === void 0 ? void 0 : _a[this.nameInnerMatrix]; if (!defaultItems) return; const categoriesQuestion = this.getQuestionCategories(model); const hiddenItemsQuestion = this.getMatrix(model); const hiddenValue = hiddenItemsQuestion.value || []; const value = categoriesQuestion.value; const categoryRow = value.filter(v => v.category == category)[0]; categoryRow[this.nameInnerMatrix].forEach(i => { if (!defaultItems.some(di => di.name == i.name)) { hiddenValue.push(i); } }); categoryRow[this.nameInnerMatrix] = defaultItems; function clearItemFromDefault(items) { if (!items) return; defaultItems.forEach(di => { const index = items.findIndex(i => i.name == di.name); if (index >= 0) items.splice(index, 1); }); } value.filter(v => v.category != category).forEach(v => { defaultItems.forEach(di => { clearItemFromDefault(v[this.nameInnerMatrix]); }); }); clearItemFromDefault(hiddenValue); hiddenItemsQuestion.value = hiddenValue; categoriesQuestion.value = value; this.notifyCallback(getLocString("presets.editor.categoryRestoredToDefault")); } findOrCreateCategory(categories, category) { let generalCategory = categories.filter(c => c.category == category)[0]; if (!generalCategory) { generalCategory = { category: category || "general", title: category || "General", [this.nameInnerMatrix]: [] }; categories.push(generalCategory); } return generalCategory; } needToSetActions(name) { return this.isItemsMatrix(name) || name === this.nameCategories; } onGetMatrixRowActionsCore(model, creator, options) { super.onGetMatrixRowActionsCore(model, creator, options); if (options.question.name === this.nameCategories) { this.setupCategoryActions(model, creator, options.question, options.row, options.actions); } if (this.isItemsMatrix(options.question.name)) { this.replaceRemoveAction(model, options.question, options.row, options.actions); } } getExistingKeys(model, key) { const cats = model.getQuestionByName(this.nameCategories).value || []; const unsorted = model.getQuestionByName(this.nameMatrix).value || []; return [...cats, ...cats.map(c => c.items).flat().filter(key => !!key), ...unsorted]; } onMatrixRowRemoving(model, creator, options) { super.onMatrixRowRemoving(model, creator, options); if (options.question.name == this.nameCategories) { const items = options.question.value[options.rowIndex][this.nameInnerMatrix]; if (items) { const hiddenItems = this.getMatrix(model); const value = hiddenItems.value ? hiddenItems.value.concat(items) : items; hiddenItems.value = value; } } if (options.question.name == this.nameMatrix) { const rowData = options.question.value[options.rowIndex]; const defaultCategory = this.defaultCategories.filter(c => c[this.nameInnerMatrix].filter(i => i.name == rowData.name).length > 0)[0]; this.moveToCategory(model, options.question, options.row, defaultCategory === null || defaultCategory === void 0 ? void 0 : defaultCategory.category); } } onMatrixRowAdded(model, creator, options) { super.onMatrixRowAdded(model, creator, options); if (options.question.name == this.nameCategories) { this.setDefaultValueForRow(model, options.question, options.row); this.editItem(model, creator, options.question, options.row, { description: getLocString("presets.items.newCategory") + " " + this.getPageShortTitle(model), isNew: true }); } } } const LocCategoriesName = "toolboxCategories"; function validateToolboxJson(params) { const value = params[0]; if (!value || !value.type) return true; const obj = Serializer.createClas