@finos/legend-application-studio
Version:
Legend Studio application core
331 lines • 32.3 kB
JavaScript
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
/**
* Copyright (c) 2020-present, Goldman Sachs
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { useState, useMemo, useCallback } from 'react';
import { observer } from 'mobx-react-lite';
import { flowResult, runInAction } from 'mobx';
import { getElementIcon } from '../../../ElementIconUtils.js';
import { useDrop } from 'react-dnd';
import { FileGenerationEditorState } from '../../../../stores/editor/editor-state/element-editor-state/FileGenerationEditorState.js';
import { UnsupportedOperationError, debounce, guaranteeNonNullable, prettyCONSTName, } from '@finos/legend-shared';
import { ResizablePanelGroup, ResizablePanel, ResizablePanelSplitter, ResizablePanelSplitterLine, CustomSelectorInput, PencilIcon, RefreshIcon, TimesIcon, LockIcon, SaveIcon, PanelDropZone, Panel, PanelContent, PanelFormSection, PanelHeader, PanelFormTextField, PanelFormBooleanField, Button, } from '@finos/legend-art';
import { CORE_DND_TYPE, } from '../../../../stores/editor/utils/DnDUtils.js';
import { LEGEND_STUDIO_TEST_ID } from '../../../../__lib__/LegendStudioTesting.js';
import { useEditorStore } from '../../EditorStoreProvider.js';
import { GenerationPropertyItemType, PackageableElementReference, PackageableElementExplicitReference, isValidFullPath, resolvePackagePathAndElementName, getNullableFileGenerationConfig, } from '@finos/legend-graph';
import { useApplicationStore } from '@finos/legend-application';
import { fileGeneration_addScopeElement, fileGeneration_changeScopeElement, fileGeneration_deleteScopeElement, fileGeneration_setGenerationOutputPath, } from '../../../../stores/graph-modifier/DSL_Generation_GraphModifierHelper.js';
import { FileSystemViewer } from './FileSystemViewer.js';
const FileGenerationScopeEditor = observer((props) => {
const { isReadOnly, fileGenerationState, regenerate } = props;
const editorStore = useEditorStore();
const applicationStore = useApplicationStore();
const fileGeneration = fileGenerationState.fileGeneration;
const scopeElements = fileGeneration.scopeElements;
const scopeElementPath = (element) => element instanceof PackageableElementReference
? element.value.path
: element;
// NOTE: `showEditInput` is either boolean (to hide/show the add value button) or a number (index of the item being edited)
const [showEditInput, setShowEditInput] = useState(false);
const [itemValue, setItemValue] = useState(undefined);
const hideAddOrEditItemInput = () => {
setShowEditInput(false);
setItemValue('');
};
const showEditItemInput = (value, idx) => () => {
setItemValue(scopeElementPath(value));
setShowEditInput(idx);
};
const showAddItemInput = () => {
setShowEditInput(true);
setItemValue('');
};
const deleteScopeElement = (scopeElement) => {
fileGeneration_deleteScopeElement(fileGeneration, scopeElement);
regenerate()?.catch(applicationStore.alertUnhandledError);
};
const changeItemInputValue = (event) => setItemValue(event.target.value);
const isDisabled = Boolean(isReadOnly ||
!itemValue ||
scopeElements
.map((element) => scopeElementPath(element))
.includes(itemValue));
const addValue = () => {
if (itemValue && !isReadOnly) {
regenerate.cancel();
const element = editorStore.graphManagerState.graph.getNullableElement(itemValue, true);
fileGenerationState.addScopeElement(element ?? itemValue);
regenerate()?.catch(applicationStore.alertUnhandledError);
hideAddOrEditItemInput();
}
};
const updateValue = (value) => () => {
if (itemValue &&
!isReadOnly &&
!scopeElements
.map((element) => scopeElementPath(element))
.includes(itemValue)) {
const element = editorStore.graphManagerState.graph.getNullableElement(itemValue, true);
if (element) {
regenerate.cancel();
fileGeneration_changeScopeElement(fileGeneration, value, PackageableElementExplicitReference.create(element));
regenerate()?.catch(applicationStore.alertUnhandledError);
}
}
hideAddOrEditItemInput();
};
return (_jsxs("div", { className: "panel__content__form__section", children: [_jsx("div", { className: "panel__content__form__section__header__label", children: "Scope" }), _jsx("div", { className: "panel__content__form__section__header__prompt", children: "Specifies the list of packages and elements that will determine elements to get generated" }), _jsxs("div", { className: "panel__content__form__section__list", children: [_jsxs("div", { className: "panel__content__form__section__list__items", "data-testid": LEGEND_STUDIO_TEST_ID.PANEL_CONTENT_FORM_SECTION_LIST_ITEMS, children: [scopeElements.map((value, idx) => (
// NOTE: since the value must be unique, we will use it as the key
_jsx("div", { className: showEditInput === idx
? 'panel__content__form__section__list__new-item'
: 'panel__content__form__section__list__item', children: showEditInput === idx ? (_jsxs(_Fragment, { children: [_jsx("input", { className: "panel__content__form__section__input panel__content__form__section__list__new-item__input", spellCheck: false, disabled: isReadOnly, value: itemValue, onChange: changeItemInputValue }), _jsxs("div", { className: "panel__content__form__section__list__new-item__actions", children: [_jsx(Button, { className: "panel__content__form__section__list__new-item__add-btn", disabled: isDisabled, onClick: updateValue(value), text: "save" }), _jsx(Button, { className: "panel__content__form__section__list__new-item__cancel-btn", disabled: isReadOnly, onClick: hideAddOrEditItemInput, text: "cancel" })] })] })) : (_jsxs(_Fragment, { children: [_jsxs("div", { className: "panel__content__form__section__list__item__value file-generation-editor__configuration__content__scope", children: [_jsx("div", { className: "file-generation-editor__configuration__content__scope__icon", children: getElementIcon(value instanceof PackageableElementReference
? value.value
: undefined, editorStore) }), _jsx("div", { className: "file-generation-editor__configuration__content__scope__path", children: scopeElementPath(value) })] }), _jsxs("div", { className: "panel__content__form__section__list__item__actions", children: [_jsx("button", { className: "panel__content__form__section__list__item__edit-btn", disabled: isReadOnly, onClick: showEditItemInput(value, idx), tabIndex: -1, children: _jsx(PencilIcon, {}) }), _jsx("button", { className: "panel__content__form__section__list__item__remove-btn", disabled: isReadOnly, onClick: () => deleteScopeElement(value), tabIndex: -1, children: _jsx(TimesIcon, {}) })] })] })) }, scopeElementPath(value)))), showEditInput === true && (_jsxs("div", { className: "panel__content__form__section__list__new-item", children: [_jsx("input", { className: "panel__content__form__section__input panel__content__form__section__list__new-item__input", spellCheck: false, disabled: isReadOnly, value: itemValue, onChange: changeItemInputValue }), _jsxs("div", { className: "panel__content__form__section__list__new-item__actions", children: [_jsx("button", { className: "panel__content__form__section__list__new-item__add-btn btn btn--dark", disabled: isDisabled, onClick: addValue, tabIndex: -1, children: "Save" }), _jsx("button", { className: "panel__content__form__section__list__new-item__cancel-btn btn btn--dark", disabled: isReadOnly, onClick: hideAddOrEditItemInput, tabIndex: -1, children: "Cancel" })] })] }))] }), !scopeElements.length && (_jsx("div", { className: "panel__content__form__section__list__empty", children: "No path specified" })), showEditInput !== true && (_jsx("div", { className: "panel__content__form__section__list__new-item__add", children: _jsx("button", { className: "panel__content__form__section__list__new-item__add-btn btn btn--dark", disabled: isReadOnly, onClick: showAddItemInput, tabIndex: -1, children: "Add Value" }) }))] })] }));
});
const GenerationStringPropertyEditor = observer((props) => {
const { property, getConfigValue, isReadOnly, update } = props;
// If there is no default value the string will be 'null'. We will treat it as an empty string
const defaultValue = property.defaultValue === 'null' ? '' : property.defaultValue;
const value = getConfigValue(property.name) ?? defaultValue;
const changeValue = (event) => update(property, event.target.value);
return (_jsxs("div", { className: "panel__content__form__section", children: [_jsx("div", { className: "panel__content__form__section__header__label", children: prettyCONSTName(property.name) }), _jsx("div", { className: "panel__content__form__section__header__prompt", children: property.description }), _jsx("input", { className: "panel__content__form__section__input", spellCheck: false, disabled: isReadOnly, value: value, onChange: changeValue })] }));
});
const GenerationIntegerPropertyEditor = observer((props) => {
const { property, getConfigValue, isReadOnly, update } = props;
const defaultValue = JSON.parse(property.defaultValue);
const value = getConfigValue(property.name) ?? defaultValue;
const changeValue = (event) => update(property, event.target.value);
return (_jsxs("div", { className: "panel__content__form__section", children: [_jsx("div", { className: "panel__content__form__section__header__label", children: property.name }), _jsx("div", { className: "panel__content__form__section__header__prompt", children: property.description }), _jsx("input", { className: "panel__content__form__section__input panel__content__form__section__number-input", spellCheck: false, type: "number", disabled: isReadOnly, value: value, onChange: changeValue })] }));
});
const GenerationBooleanPropertyEditor = observer((props) => {
const { property, getConfigValue, isReadOnly, update } = props;
const defaultValue = JSON.parse(property.defaultValue);
const value = getConfigValue(property.name) ?? defaultValue;
return (_jsx(PanelFormBooleanField, { isReadOnly: isReadOnly, value: value, name: prettyCONSTName(property.name), prompt: property.description, update: (newValue) => {
update(property, newValue);
} }));
});
const GenerationEnumPropertyEditor = observer((props) => {
const { property, getConfigValue, isReadOnly, update } = props;
const applicationStore = useApplicationStore();
const getEnumLabel = (_enum) => isValidFullPath(_enum)
? resolvePackagePathAndElementName(_enum)[1]
: _enum;
const options = guaranteeNonNullable(property.items, 'Generation configuration description items for enum property item type is missing').enums.map((_enum) => ({ label: getEnumLabel(_enum), value: _enum }));
const value = getConfigValue(property.name) ??
property.defaultValue;
const onChange = (val) => {
if (val !== null && val.value !== value) {
update(property, val.value);
}
};
return (_jsxs("div", { className: "panel__content__form__section", children: [_jsx("div", { className: "panel__content__form__section__header__label", children: property.name }), _jsx("div", { className: "panel__content__form__section__header__prompt", children: property.description }), _jsx(CustomSelectorInput, { className: "panel__content__form__section__dropdown", options: options, onChange: onChange, value: { label: getEnumLabel(value), value }, isClearable: true, escapeClearsValue: true, darkMode: !applicationStore.layoutService.TEMPORARY__isLightColorThemeEnabled, disabled: isReadOnly })] }));
});
const GenerationArrayPropertyEditor = observer((props) => {
const { property, getConfigValue, isReadOnly, update } = props;
let defaultValue = [];
// NOTE: hacking this because the backend send corrupted array string
if (property.defaultValue !== '' && property.defaultValue !== '[]') {
defaultValue = property.defaultValue
.substring(1, property.defaultValue.length - 1)
.split(',');
}
const arrayValues = getConfigValue(property.name) ?? defaultValue;
// NOTE: `showEditInput` is either boolean (to hide/show the add value button) or a number (index of the item being edited)
const [showEditInput, setShowEditInput] = useState(false);
const [itemValue, setItemValue] = useState('');
const showAddItemInput = () => setShowEditInput(true);
const showEditItemInput = (value, idx) => () => {
setItemValue(value);
setShowEditInput(idx);
};
const hideAddOrEditItemInput = () => {
setShowEditInput(false);
setItemValue('');
};
const changeItemInputValue = (event) => setItemValue(event.target.value);
const addValue = () => {
if (itemValue && !isReadOnly && !arrayValues.includes(itemValue)) {
update(property, arrayValues.concat([itemValue]));
}
hideAddOrEditItemInput();
};
const updateValue = (idx) => () => {
if (itemValue && !isReadOnly && !arrayValues.includes(itemValue)) {
runInAction(() => {
arrayValues[idx] = itemValue;
});
update(property, arrayValues);
}
hideAddOrEditItemInput();
};
const deleteValue = (idx) => () => {
if (!isReadOnly) {
runInAction(() => arrayValues.splice(idx, 1));
update(property, [...arrayValues]);
// Since we keep track of the value currently being edited using the index, we have to account for it as we delete entry
if (typeof showEditInput === 'number' && showEditInput > idx) {
setShowEditInput(showEditInput - 1);
}
}
};
return (_jsxs(PanelFormSection, { children: [_jsx("div", { className: "panel__content__form__section__header__label", children: property.name }), _jsx("div", { className: "panel__content__form__section__header__prompt", children: property.description }), _jsxs("div", { className: "panel__content__form__section__list", children: [_jsxs("div", { className: "panel__content__form__section__list__items", "data-testid": LEGEND_STUDIO_TEST_ID.PANEL_CONTENT_FORM_SECTION_LIST_ITEMS, children: [arrayValues.map((value, idx) => (
// NOTE: since the value must be unique, we will use it as the key
_jsx("div", { className: showEditInput === idx
? 'panel__content__form__section__list__new-item'
: 'panel__content__form__section__list__item', children: showEditInput === idx ? (_jsxs(_Fragment, { children: [_jsx("input", { className: "panel__content__form__section__input panel__content__form__section__list__new-item__input", spellCheck: false, disabled: isReadOnly, value: itemValue, onChange: changeItemInputValue }), _jsxs("div", { className: "panel__content__form__section__list__new-item__actions", children: [_jsx("button", { className: "panel__content__form__section__list__new-item__add-btn btn btn--dark", disabled: isReadOnly || arrayValues.includes(itemValue), onClick: updateValue(idx), tabIndex: -1, children: "Save" }), _jsx("button", { className: "panel__content__form__section__list__new-item__cancel-btn btn btn--dark", disabled: isReadOnly, onClick: hideAddOrEditItemInput, tabIndex: -1, children: "Cancel" })] })] })) : (_jsxs(_Fragment, { children: [_jsx("div", { className: "panel__content__form__section__list__item__value", children: value }), _jsxs("div", { className: "panel__content__form__section__list__item__actions", children: [_jsx("button", { className: "panel__content__form__section__list__item__edit-btn", disabled: isReadOnly, onClick: showEditItemInput(value, idx), tabIndex: -1, children: _jsx(PencilIcon, {}) }), _jsx("button", { className: "panel__content__form__section__list__item__remove-btn", disabled: isReadOnly, onClick: deleteValue(idx), tabIndex: -1, children: _jsx(TimesIcon, {}) })] })] })) }, value))), showEditInput === true && (_jsxs("div", { className: "panel__content__form__section__list__new-item", children: [_jsx("input", { className: "panel__content__form__section__input panel__content__form__section__list__new-item__input", spellCheck: false, disabled: isReadOnly, value: itemValue, onChange: changeItemInputValue }), _jsxs("div", { className: "panel__content__form__section__list__new-item__actions", children: [_jsx("button", { className: "panel__content__form__section__list__new-item__add-btn btn btn--dark", disabled: isReadOnly || arrayValues.includes(itemValue), onClick: addValue, tabIndex: -1, children: "Save" }), _jsx("button", { className: "panel__content__form__section__list__new-item__cancel-btn btn btn--dark", disabled: isReadOnly, onClick: hideAddOrEditItemInput, tabIndex: -1, children: "Cancel" })] })] }))] }), showEditInput !== true && (_jsx("div", { className: "panel__content__form__section__list__new-item__add", children: _jsx(Button, { className: "panel__content__form__section__list__new-item__add-btn", disabled: isReadOnly, onClick: showAddItemInput, text: "Add Value" }) }))] })] }));
});
const GenerationMapPropertyEditor = observer((props) => {
const { property, getConfigValue, isReadOnly, update } = props;
// Right now, always assume this is a map between STRING and STRING (might need to support STRING - INTEGER and STRING - BOOLEAN)
const nonNullableDefaultValue = property.defaultValue === 'null' ? '{}' : property.defaultValue;
const mapValues = (getConfigValue(property.name) ?? JSON.parse(nonNullableDefaultValue));
// NOTE: `showEditInput` is either boolean (to hide/show the add value button) or a number (index of the item being edited)
const [showEditInput, setShowEditInput] = useState(false);
const [itemKey, setItemKey] = useState('');
const [itemValue, setItemValue] = useState('');
const showAddItemInput = () => setShowEditInput(true);
const showEditItemInput = (key, value, idx) => () => {
setItemKey(key);
setItemValue(value);
setShowEditInput(idx);
};
const hideAddOrEditItemInput = () => {
setShowEditInput(false);
setItemKey('');
setItemValue('');
};
const changeItemInputKey = (event) => setItemKey(event.target.value);
const changeItemInputValue = (event) => setItemValue(event.target.value);
const addValue = () => {
if (itemValue &&
itemKey &&
!isReadOnly &&
!Array.from(Object.keys(mapValues)).includes(itemKey)) {
runInAction(() => {
mapValues[itemKey] = itemValue;
});
update(property, mapValues);
}
hideAddOrEditItemInput();
};
const updateValue = (key) => () => {
if (itemValue && !isReadOnly) {
runInAction(() => {
delete mapValues[key];
mapValues[itemKey] = itemValue;
});
update(property, mapValues);
}
hideAddOrEditItemInput();
};
const deleteValue = (key, idx) => () => {
if (!isReadOnly) {
runInAction(() => delete mapValues[key]);
update(property, mapValues);
// Since we keep track of the value currently being edited using the index, we have to account for it as we delete entry
if (typeof showEditInput === 'number' && showEditInput > idx) {
setShowEditInput(showEditInput - 1);
}
}
};
return (_jsxs(PanelFormSection, { children: [_jsx("div", { className: "panel__content__form__section__header__label", children: property.name }), _jsx("div", { className: "panel__content__form__section__header__prompt", children: property.description }), _jsxs("div", { className: "panel__content__form__section__list", children: [_jsxs("div", { className: "panel__content__form__section__list__items", "data-testid": LEGEND_STUDIO_TEST_ID.PANEL_CONTENT_FORM_SECTION_LIST_ITEMS, children: [Array.from(Object.entries(mapValues)).map(([key, value], idx) => (
// NOTE: since the key must be unique, we will use it to generate the key
_jsx("div", { className: showEditInput === idx
? 'panel__content__form__section__list__new-item'
: 'panel__content__form__section__list__item', children: showEditInput === idx ? (_jsxs(_Fragment, { children: [_jsx("input", { className: "panel__content__form__section__input panel__content__form__section__list__new-item__input", spellCheck: false, disabled: isReadOnly, value: itemKey, onChange: changeItemInputKey }), _jsx("input", { className: "panel__content__form__section__input panel__content__form__section__list__new-item__input", spellCheck: false, disabled: isReadOnly, value: itemValue, onChange: changeItemInputValue }), _jsxs("div", { className: "panel__content__form__section__list__new-item__actions", children: [_jsx("button", { className: "panel__content__form__section__list__new-item__add-btn btn btn--dark", disabled: isReadOnly, onClick: updateValue(key), tabIndex: -1, children: "Save" }), _jsx("button", { className: "panel__content__form__section__list__new-item__cancel-btn btn btn--dark", disabled: isReadOnly, onClick: hideAddOrEditItemInput, tabIndex: -1, children: "Cancel" })] })] })) : (_jsxs(_Fragment, { children: [_jsxs("div", { className: "panel__content__form__section__list__item__value panel__content__form__section__list__item__value__map-item", children: [_jsx("span", { className: "panel__content__form__section__list__item__value__map-item__key", children: key }), _jsx("span", { className: "panel__content__form__section__list__item__value__map-item__separator", children: ":" }), _jsx("span", { className: "panel__content__form__section__list__item__value__map-item__value", children: value })] }), _jsxs("div", { className: "panel__content__form__section__list__item__actions", children: [_jsx("button", { className: "panel__content__form__section__list__item__edit-btn", disabled: isReadOnly, onClick: showEditItemInput(key, value, idx), tabIndex: -1, children: _jsx(PencilIcon, {}) }), _jsx("button", { className: "panel__content__form__section__list__item__remove-btn", disabled: isReadOnly, onClick: deleteValue(key, idx), tabIndex: -1, children: _jsx(TimesIcon, {}) })] })] })) }, key))), showEditInput === true && (_jsxs("div", { className: "panel__content__form__section__list__new-item", children: [_jsx("input", { className: "panel__content__form__section__input panel__content__form__section__list__new-item__input", spellCheck: false, disabled: isReadOnly, value: itemKey, onChange: changeItemInputKey }), _jsx("input", { className: "panel__content__form__section__input panel__content__form__section__list__new-item__input", spellCheck: false, disabled: isReadOnly, value: itemValue, onChange: changeItemInputValue }), _jsxs("div", { className: "panel__content__form__section__list__new-item__actions", children: [_jsx("button", { className: "panel__content__form__section__list__new-item__add-btn btn btn--dark", disabled: isReadOnly ||
Array.from(Object.keys(mapValues)).includes(itemKey), onClick: addValue, tabIndex: -1, children: "Save" }), _jsx("button", { className: "panel__content__form__section__list__new-item__cancel-btn btn btn--dark", disabled: isReadOnly, onClick: hideAddOrEditItemInput, tabIndex: -1, children: "Cancel" })] })] }))] }), showEditInput !== true && (_jsx("div", { className: "panel__content__form__section__list__new-item__add", children: _jsx("button", { className: "panel__content__form__section__list__new-item__add-btn btn btn--dark", disabled: isReadOnly, onClick: showAddItemInput, tabIndex: -1, children: "Add Value" }) }))] })] }));
});
export const GenerationPropertyEditor = observer((props) => {
const { property, getConfigValue, isReadOnly, update } = props;
switch (property.type) {
case GenerationPropertyItemType.STRING:
return (_jsx(GenerationStringPropertyEditor, { getConfigValue: getConfigValue, isReadOnly: isReadOnly, update: update, property: property }));
case GenerationPropertyItemType.INTEGER:
return (_jsx(GenerationIntegerPropertyEditor, { getConfigValue: getConfigValue, isReadOnly: isReadOnly, update: update, property: property }));
case GenerationPropertyItemType.BOOLEAN:
return (_jsx(GenerationBooleanPropertyEditor, { getConfigValue: getConfigValue, isReadOnly: isReadOnly, update: update, property: property }));
case GenerationPropertyItemType.ENUM:
return (_jsx(GenerationEnumPropertyEditor, { getConfigValue: getConfigValue, isReadOnly: isReadOnly, update: update, property: property }));
case GenerationPropertyItemType.ARRAY:
return (_jsx(GenerationArrayPropertyEditor, { getConfigValue: getConfigValue, isReadOnly: isReadOnly, update: update, property: property }));
case GenerationPropertyItemType.MAP:
return (_jsx(GenerationMapPropertyEditor, { getConfigValue: getConfigValue, isReadOnly: isReadOnly, update: update, property: property }));
default:
throw new UnsupportedOperationError(`Can't generate editor for artifact generation property of type '${property.type}'`);
}
});
export const FileGenerationConfigurationEditor = observer((props) => {
const { isReadOnly, fileGenerationState, elementGenerationState } = props;
const editorStore = useEditorStore();
const applicationStore = useApplicationStore();
const fileGeneration = fileGenerationState.fileGeneration;
const fileGenerationConfiguration = editorStore.graphState.graphGenerationState.globalFileGenerationState.getFileGenerationConfiguration(fileGeneration.type).properties;
const debouncedRegenerate = useMemo(() => debounce(() => flowResult(fileGenerationState.generate()), 500), [fileGenerationState]);
const update = (generationProperty, newValue) => {
debouncedRegenerate.cancel();
fileGenerationState.updateFileGenerationParameters(fileGeneration, generationProperty, newValue);
debouncedRegenerate()?.catch(applicationStore.alertUnhandledError);
};
const showFileGenerationModal = () => {
elementGenerationState?.setShowNewFileGenerationModal(true);
};
const resetDefaultConfiguration = () => {
debouncedRegenerate.cancel();
fileGenerationState.resetGenerator();
debouncedRegenerate()?.catch(applicationStore.alertUnhandledError);
};
// Drag and Drop
const handleDrop = useCallback((item) => {
const element = item.data.packageableElement;
if (!isReadOnly &&
!elementGenerationState &&
!fileGenerationState.getScopeElement(element)) {
debouncedRegenerate.cancel();
fileGeneration_addScopeElement(fileGeneration, PackageableElementExplicitReference.create(element));
debouncedRegenerate()?.catch(applicationStore.alertUnhandledError);
}
}, [
applicationStore.alertUnhandledError,
debouncedRegenerate,
elementGenerationState,
fileGeneration,
fileGenerationState,
isReadOnly,
]);
const [{ isScopeElementDragOver }, dropConnector] = useDrop(() => ({
accept: [
CORE_DND_TYPE.PROJECT_EXPLORER_PACKAGE,
CORE_DND_TYPE.PROJECT_EXPLORER_CLASS,
CORE_DND_TYPE.PROJECT_EXPLORER_ENUMERATION,
],
drop: (item) => handleDrop(item),
collect: (monitor) => ({
isScopeElementDragOver: monitor.isOver({ shallow: true }),
}),
}), [handleDrop]);
const getConfigValue = (name) => getNullableFileGenerationConfig(fileGeneration, name)?.value;
return (_jsxs(Panel, { className: "file-generation-editor__configuration", children: [_jsxs(PanelHeader, { children: [_jsx("div", { className: "panel__header__title", children: _jsx("div", { className: "panel__header__title__label", children: `${fileGeneration.type} configuration` }) }), _jsxs("div", { className: "panel__header__actions", children: [_jsx("button", { className: "panel__header__action file-generation-editor__configuration__reset-btn", tabIndex: -1, disabled: isReadOnly || !fileGeneration.configurationProperties.length, onClick: resetDefaultConfiguration, title: "Reset to default configuration", children: _jsx(RefreshIcon, {}) }), Boolean(elementGenerationState) && (_jsx("button", { className: "panel__header__action", tabIndex: -1, disabled: isReadOnly, onClick: showFileGenerationModal, title: "Promote to file generation specification...", children: _jsx(SaveIcon, {}) }))] })] }), _jsx(PanelContent, { children: _jsx(PanelDropZone, { dropTargetConnector: dropConnector, isDragOver: isScopeElementDragOver && !elementGenerationState && !isReadOnly, children: _jsxs("div", { className: "file-generation-editor__configuration__content", children: [_jsx(FileGenerationScopeEditor, { fileGenerationState: fileGenerationState, regenerate: debouncedRegenerate, isReadOnly: isReadOnly || Boolean(elementGenerationState) }), _jsx(PanelFormTextField, { isReadOnly: isReadOnly, value: fileGeneration.generationOutputPath ?? '', name: "Generation Output Path", prompt: "Specifies the root path where files will be generated.\n Defaults to the file specification path", update: (value) => fileGeneration_setGenerationOutputPath(fileGeneration, value ?? '') }), fileGenerationConfiguration.map((abstractGenerationProperty) => (_jsx(GenerationPropertyEditor, { update: update, isReadOnly: isReadOnly, getConfigValue: getConfigValue, property: abstractGenerationProperty }, abstractGenerationProperty.name +
abstractGenerationProperty.type)))] }) }) })] }));
});
export const FileGenerationEditor = observer(() => {
const editorStore = useEditorStore();
const fileGenerationEditorState = editorStore.tabManagerState.getCurrentEditorState(FileGenerationEditorState);
const fileGeneration = fileGenerationEditorState.fileGeneration;
const isReadOnly = fileGenerationEditorState.isReadOnly;
return (_jsx("div", { className: "file-generation-editor", children: _jsxs(Panel, { children: [_jsx(PanelHeader, { children: _jsxs("div", { className: "panel__header__title", children: [isReadOnly && (_jsx("div", { className: "uml-element-editor__header__lock", children: _jsx(LockIcon, {}) })), _jsx("div", { className: "panel__header__title__label", children: "file generation" }), _jsx("div", { className: "panel__header__title__content", children: fileGeneration.name })] }) }), _jsx(PanelContent, { className: "file-generation-editor__content", children: _jsxs(ResizablePanelGroup, { orientation: "vertical", children: [_jsx(ResizablePanel, { size: 400, minSize: 300, children: _jsx(FileGenerationConfigurationEditor, { isReadOnly: isReadOnly, fileGenerationState: fileGenerationEditorState.fileGenerationState }) }), _jsx(ResizablePanelSplitter, { children: _jsx(ResizablePanelSplitterLine, { color: "var(--color-dark-grey-200)" }) }), _jsx(ResizablePanel, { children: _jsx(FileSystemViewer, { generatedFileState: fileGenerationEditorState.fileGenerationState }) })] }) })] }) }));
});
//# sourceMappingURL=FileGenerationEditor.js.map