@finos/legend-studio
Version:
111 lines • 10.4 kB
JavaScript
import { jsx as _jsx, jsxs as _jsxs } 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 { Fragment, useEffect, useMemo, useRef, useState } from 'react';
import { observer } from 'mobx-react-lite';
import { Dialog, BlankPanelContent, ArrowCircleDownIcon, clsx, CustomSelectorInput, PanelLoadingIndicator, PlayIcon, DropdownMenu, MenuContent, CaretDownIcon, MenuContentItem, } from '@finos/legend-art';
import { debounce } from '@finos/legend-shared';
import { flowResult } from 'mobx';
import { useEditorStore } from '../../EditorStoreProvider.js';
import { EDITOR_LANGUAGE, ExecutionPlanViewer, LambdaParameterValuesEditor, useApplicationStore, } from '@finos/legend-application';
import { StudioTextInputEditor } from '../../../shared/StudioTextInputEditor.js';
const ServiceExecutionResultViewer = observer((props) => {
const { executionState } = props;
// execution
const executionResultText = executionState.executionResultText;
const closeExecutionResultViewer = () => executionState.setExecutionResultText(undefined);
return (_jsx(Dialog, { open: Boolean(executionResultText), onClose: closeExecutionResultViewer, classes: {
root: 'editor-modal__root-container',
container: 'editor-modal__container',
paper: 'editor-modal__content',
}, children: _jsxs("div", { className: "modal modal--dark editor-modal", children: [_jsx("div", { className: "modal__header", children: _jsx("div", { className: "modal__title", children: "Execution Result" }) }), _jsx("div", { className: "modal__body", children: _jsx(StudioTextInputEditor, { inputValue: executionResultText ?? '', isReadOnly: true, language: EDITOR_LANGUAGE.JSON, showMiniMap: true }) }), _jsx("div", { className: "modal__footer", children: _jsx("button", { className: "btn modal__footer__close-btn", onClick: closeExecutionResultViewer, children: "Close" }) })] }) }));
});
const buildQueryOption = (query) => ({
label: query.name,
value: query,
});
const ServiceExecutionQueryImporter = observer((props) => {
const { queryState } = props;
const applicationStore = useApplicationStore();
const queryFinderRef = useRef(null);
const closeQueryImporter = () => queryState.setOpenQueryImporter(false);
const handleEnterQueryImporter = () => queryFinderRef.current?.focus();
// query finder
const [searchText, setSearchText] = useState('');
const queryOptions = queryState.queries.map(buildQueryOption);
const selectedQueryOption = queryState.selectedQueryInfo
? {
label: queryState.selectedQueryInfo.query.name,
value: queryState.selectedQueryInfo.query,
}
: null;
const onQueryOptionChange = (option) => {
if (option?.value !== queryState.selectedQueryInfo?.query.id) {
flowResult(queryState.setSelectedQueryInfo(option?.value)).catch(applicationStore.alertUnhandledError);
}
};
const formatQueryOptionLabel = (option) => (_jsxs("div", { className: "service-query-importer__query-option", children: [_jsx("div", { className: "service-query-importer__query-option__label", children: option.label }), Boolean(option.value.owner) && (_jsx("div", { className: clsx('service-query-importer__query-option__user', {
'service-query-importer__query-option__user--mine': option.value.isCurrentUserQuery,
}), children: option.value.isCurrentUserQuery ? 'mine' : option.value.owner }))] }));
const debouncedLoadQueries = useMemo(() => debounce((input) => {
flowResult(queryState.loadQueries(input)).catch(applicationStore.alertUnhandledError);
}, 500), [applicationStore, queryState]);
const onSearchTextChange = (value) => {
if (value !== searchText) {
setSearchText(value);
debouncedLoadQueries.cancel();
debouncedLoadQueries(value);
}
};
const importQuery = () => {
flowResult(queryState.importQuery()).catch(applicationStore.alertUnhandledError);
};
useEffect(() => {
flowResult(queryState.loadQueries('')).catch(applicationStore.alertUnhandledError);
}, [queryState, applicationStore]);
return (_jsx(Dialog, { open: queryState.openQueryImporter, onClose: closeQueryImporter, TransitionProps: {
onEnter: handleEnterQueryImporter,
}, classes: { container: 'search-modal__container' }, PaperProps: { classes: { root: 'search-modal__inner-container' } }, children: _jsxs("div", { className: "modal modal--dark search-modal", children: [_jsx("div", { className: "modal__title", children: "Import Query" }), _jsx(CustomSelectorInput, { ref: queryFinderRef, options: queryOptions, isLoading: queryState.loadQueriesState.isInProgress, onInputChange: onSearchTextChange, inputValue: searchText, onChange: onQueryOptionChange, value: selectedQueryOption, placeholder: "Search for a query by name...", darkMode: true, isClearable: true, formatOptionLabel: formatQueryOptionLabel }), _jsxs("div", { className: "service-query-importer__query-preview", children: [_jsx(PanelLoadingIndicator, { isLoading: queryState.loadQueryInfoState.isInProgress }), queryState.selectedQueryInfo && (_jsx(StudioTextInputEditor, { inputValue: queryState.selectedQueryInfo.content, isReadOnly: true, language: EDITOR_LANGUAGE.PURE, showMiniMap: false, hideGutter: true })), !queryState.selectedQueryInfo && (_jsx(BlankPanelContent, { children: "No query to preview" }))] }), _jsx("div", { className: "search-modal__actions", children: _jsx("button", { className: "btn btn--dark", disabled: !queryState.selectedQueryInfo, onClick: importQuery, children: "Import" }) })] }) }));
});
export const ServiceExecutionQueryEditor = observer((props) => {
const { executionState, isReadOnly } = props;
const queryState = executionState.queryState;
const editorStore = useEditorStore();
const applicationStore = useApplicationStore();
const extraServiceQueryEditorActions = editorStore.pluginManager
.getApplicationPlugins()
.flatMap((plugin) => plugin.getExtraServiceQueryEditorActionConfigurations?.() ?? [])
.map((config) => (_jsx(Fragment, { children: config.renderer(executionState, isReadOnly) }, config.key)));
const importQuery = () => {
queryState.setOpenQueryImporter(true);
};
// execute
const handleExecute = applicationStore.guardUnhandledError(() => flowResult(executionState.handleExecute()));
const generatePlan = applicationStore.guardUnhandledError(() => flowResult(executionState.generatePlan(false)));
const debugPlanGeneration = applicationStore.guardUnhandledError(() => flowResult(executionState.generatePlan(true)));
// convert to string
useEffect(() => {
flowResult(queryState.convertLambdaObjectToGrammarString(true)).catch(applicationStore.alertUnhandledError);
}, [applicationStore, queryState]);
return (_jsxs("div", { className: "panel service-execution-query-editor", children: [_jsxs("div", { className: "panel__header", children: [_jsx("div", { className: "panel__header__title", children: _jsx("div", { className: "panel__header__title__label service-editor__execution__label--query", children: "query" }) }), _jsxs("div", { className: "panel__header__actions", children: [extraServiceQueryEditorActions, _jsx("button", { className: "panel__header__action", onClick: importQuery, disabled: isReadOnly, tabIndex: -1, title: "Import query", children: _jsx(ArrowCircleDownIcon, {}) }), _jsxs("button", { className: "service-editor__execution__execute-btn", onClick: handleExecute, title: `Execute`, disabled: executionState.isExecuting, tabIndex: -1, children: [_jsxs("div", { className: "service-editor__execution__execute-btn__label", children: [_jsx(PlayIcon, { className: "service-editor__execution__execute-btn__label__icon" }), _jsx("div", { className: "service-editor__execution__execute-btn__label__title", children: "Execute" })] }), _jsx(DropdownMenu, { className: "service-editor__execution__execute-btn__dropdown-btn", disabled: executionState.isExecuting || executionState.isGeneratingPlan, content: _jsxs(MenuContent, { children: [_jsx(MenuContentItem, { className: "service-editor__execution__execute-btn__option", onClick: generatePlan, children: "Generate Plan" }), _jsx(MenuContentItem, { className: "service-editor__execution__execute-btn__option", onClick: debugPlanGeneration, children: "Debug" })] }), menuProps: {
anchorOrigin: { vertical: 'bottom', horizontal: 'right' },
transformOrigin: { vertical: 'top', horizontal: 'right' },
}, children: _jsx(CaretDownIcon, {}) })] })] })] }), _jsxs("div", { className: "panel__content property-mapping-editor__entry__container", children: [_jsx(PanelLoadingIndicator, { isLoading: executionState.isOpeningQueryEditor ||
executionState.isExecuting ||
executionState.isGeneratingPlan }), _jsx("div", { className: "service-execution-query-editor__content", children: _jsx(StudioTextInputEditor, { inputValue: queryState.lambdaString, isReadOnly: true, language: EDITOR_LANGUAGE.PURE, showMiniMap: true }) }), _jsx(ExecutionPlanViewer, { executionPlanState: executionState.executionPlanState }), _jsx(ServiceExecutionResultViewer, { executionState: executionState }), queryState.openQueryImporter && (_jsx(ServiceExecutionQueryImporter, { queryState: queryState })), executionState.parameterState.parameterValuesEditorState
.showModal && (_jsx(LambdaParameterValuesEditor, { graph: executionState.editorStore.graphManagerState.graph, lambdaParametersState: executionState.parameterState }))] })] }));
});
//# sourceMappingURL=ServiceExecutionQueryEditor.js.map