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