UNPKG

@finos/legend-extension-dsl-data-quality

Version:
174 lines 19.2 kB
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 { observer } from 'mobx-react-lite'; import { CORE_DND_TYPE, useEditorStore, } from '@finos/legend-application-studio'; import { DATA_QUALITY_RELATION_VALIDATION_EDITOR_TAB, DataQualityRelationValidationConfigurationState, } from './states/DataQualityRelationValidationConfigurationState.js'; import React, { useCallback, useEffect, useRef } from 'react'; import { BlankPanelContent, CaretDownIcon, clsx, ControlledDropdownMenu, CsvIcon, DragPreviewLayer, ExclamationTriangleIcon, MenuContent, MenuContentItem, MenuContentItemIcon, MenuContentItemLabel, Panel, PanelContent, PanelLoadingIndicator, PauseCircleIcon, PlayIcon, PlusIcon, } from '@finos/legend-art'; import { prettyCONSTName, prettyDuration, returnUndefOnError, } from '@finos/legend-shared'; import { ExecutionPlanViewer, LambdaEditor, LambdaParameterValuesEditor, } from '@finos/legend-query-builder'; import { PrimitiveType, stub_RawVariableExpression, Type, RawExecutionResult, extractExecutionResultValues, TDSExecutionResult, } from '@finos/legend-graph'; import { ActionAlertActionType, ActionAlertType, DEFAULT_TAB_SIZE, useApplicationNavigationContext, useApplicationStore, } from '@finos/legend-application'; import { dataQualityRelationValidation_addParameter, dataQualityRelationValidation_deleteParameter, } from '../graph-manager/DSL_DataQuality_GraphModifierHelper.js'; import { flowResult } from 'mobx'; import { DataQualityRelationTrialRuns } from './DataQualityRelationTrialRuns.js'; import { DataQualityValidationParametersEditor, FUNCTION_PARAMETER_DND_TYPE, } from './DataQualityValidationParametersEditor.js'; import { useDrop } from 'react-dnd'; import { DataQualityRelationValidationsEditor } from './DataQualityRelationValidationsEditor.js'; import { CodeEditor } from '@finos/legend-lego/code-editor'; import { CODE_EDITOR_LANGUAGE } from '@finos/legend-code-editor'; import { DataQualityRelationGridResult } from './DataQualityRelationGridResult.js'; import { DATA_QUALITY_VALIDATION_TEST_ID, USER_ATTESTATION_MESSAGE, } from './constants/DataQualityConstants.js'; const RelationDefinitionEditor = observer((props) => { const { dataQualityRelationValidationConfigurationState } = props; const { relationFunctionDefinitionEditorState, resultState } = dataQualityRelationValidationConfigurationState; const { editorStore: { applicationStore }, } = dataQualityRelationValidationConfigurationState; const validationElement = dataQualityRelationValidationConfigurationState.validationElement; const lambdaExecutionResult = dataQualityRelationValidationConfigurationState.executionResult; const isReadOnly = dataQualityRelationValidationConfigurationState.isReadOnly; const isExportDisabled = dataQualityRelationValidationConfigurationState.isRunningValidation || dataQualityRelationValidationConfigurationState.isGeneratingPlan; const exportValidationResults = async (format) => { dataQualityRelationValidationConfigurationState.handleExport(format); }; const getResultSetDescription = (_executionResult) => { const queryDuration = dataQualityRelationValidationConfigurationState.executionDuration ? prettyDuration(dataQualityRelationValidationConfigurationState.executionDuration, { ms: true, }) : undefined; if (!queryDuration) { return undefined; } return `lambda ran in ${queryDuration}`; }; const resultDescription = !dataQualityRelationValidationConfigurationState.isRunningValidation && lambdaExecutionResult ? getResultSetDescription(lambdaExecutionResult) : undefined; const confirmExport = (format) => { applicationStore.alertService.setActionAlertInfo({ message: USER_ATTESTATION_MESSAGE, type: ActionAlertType.CAUTION, actions: [ { label: 'Accept', type: ActionAlertActionType.PROCEED_WITH_CAUTION, handler: applicationStore.guardUnhandledError(() => exportValidationResults(format)), }, { label: 'Decline', type: ActionAlertActionType.PROCEED, default: true, }, ], }); }; const addParameter = () => { dataQualityRelationValidation_addParameter(validationElement.query.parameters, stub_RawVariableExpression(PrimitiveType.STRING)); }; const deleteParameter = (val) => () => { dataQualityRelationValidation_deleteParameter(validationElement.query.parameters, val); }; const handleDropParameter = useCallback((item) => { if (!isReadOnly && item.data.packageableElement instanceof Type) { dataQualityRelationValidation_addParameter(validationElement.query.parameters, stub_RawVariableExpression(item.data.packageableElement)); } }, [validationElement, isReadOnly]); const [{ isParameterDragOver }, dropConnector] = useDrop(() => ({ accept: [ CORE_DND_TYPE.PROJECT_EXPLORER_CLASS, CORE_DND_TYPE.PROJECT_EXPLORER_ENUMERATION, ], drop: (item) => handleDropParameter(item), collect: (monitor) => ({ isParameterDragOver: monitor.isOver({ shallow: true }), }), }), [handleDropParameter]); const ref = useRef(null); dropConnector(ref); const renderFuncResult = () => { if (lambdaExecutionResult instanceof TDSExecutionResult) { return (_jsx(DataQualityRelationGridResult, { executionResult: lambdaExecutionResult, relationValidationConfigurationState: dataQualityRelationValidationConfigurationState })); } if (lambdaExecutionResult instanceof RawExecutionResult) { const val = lambdaExecutionResult.value === null ? 'null' : lambdaExecutionResult.value.toString(); return (_jsx(CodeEditor, { language: CODE_EDITOR_LANGUAGE.TEXT, inputValue: val, isReadOnly: true })); } else if (lambdaExecutionResult !== undefined) { const json = returnUndefOnError(() => JSON.stringify(extractExecutionResultValues(lambdaExecutionResult), null, DEFAULT_TAB_SIZE)) ?? JSON.stringify(lambdaExecutionResult); return (_jsx(CodeEditor, { language: CODE_EDITOR_LANGUAGE.JSON, inputValue: json, isReadOnly: true })); } return _jsx(BlankPanelContent, { children: "Lambda Did Not Run" }); }; return (_jsxs(_Fragment, { children: [_jsx(PanelLoadingIndicator, { isLoading: resultState.isGeneratingPlan || dataQualityRelationValidationConfigurationState.isRunningValidation }), _jsxs("div", { className: "relation-validation-config-editor__definition", children: [_jsxs("div", { className: "relation-validation-config-editor__definition__item", children: [_jsxs("div", { className: "relation-validation-config-editor__definition__item__header", children: [_jsx("div", { className: "relation-validation-config-editor__definition__item__header__title", children: "PARAMETERS" }), _jsx("button", { className: "relation-validation-config-editor__definition__item__header__add-btn btn--dark", disabled: isReadOnly, onClick: addParameter, tabIndex: -1, title: "Add Parameter", children: _jsx(PlusIcon, {}) })] }), _jsx(DragPreviewLayer, { labelGetter: (item) => item.parameter.name === '' ? '(unknown)' : item.parameter.name, types: [FUNCTION_PARAMETER_DND_TYPE] }), _jsxs("div", { ref: ref, className: clsx('relation-validation-config-editor__definition__item__content', { 'panel__content__lists--dnd-over': isParameterDragOver && !isReadOnly, }), children: [validationElement.query.parameters.map((param) => (_jsx(DataQualityValidationParametersEditor, { parameter: param, _validationConfig: validationElement, deleteParameter: deleteParameter(param), isReadOnly: isReadOnly }, param._UUID))), validationElement.query.parameters.length === 0 && (_jsx("div", { className: "relation-validation-config-editor__definition__item__content--empty", children: "No parameters" }))] })] }), _jsxs("div", { className: "relation-validation-config-editor__definition__item", children: [_jsx("div", { className: "relation-validation-config-editor__definition__item__header", children: _jsx("div", { className: "relation-validation-config-editor__definition__item__header__title", children: "LAMBDA" }) }), _jsx("div", { className: clsx('relation-validation-config-editor__definition__item__content', { backdrop__element: Boolean(relationFunctionDefinitionEditorState.parserError), }), children: _jsx(LambdaEditor, { className: "relation-validation-config-editor__definition__lambda-editor lambda-editor--dark", disabled: relationFunctionDefinitionEditorState.isConvertingFunctionBodyToString || false, lambdaEditorState: relationFunctionDefinitionEditorState, forceBackdrop: false, autoFocus: true }) })] }), _jsxs("div", { className: "relation-validation-config-editor__item", children: [_jsxs("div", { className: "relation-validation-config-editor__definition__item__header", children: [_jsxs("div", { className: "relation-validation-config-editor__definition__item__header-group", children: [_jsx("div", { className: "relation-validation-config-editor__definition__item__header__title", children: "RESULT" }), dataQualityRelationValidationConfigurationState.isRunningValidation && (_jsx("div", { className: "panel__header__title__label__status", children: "Running Validation..." })), _jsx("div", { "data-testid": DATA_QUALITY_VALIDATION_TEST_ID.DATA_QUALITY_VALIDATION_RESULT_ANALYTICS, className: "data-quality-validation__result__analytics", children: resultDescription ?? '' }), lambdaExecutionResult && dataQualityRelationValidationConfigurationState.checkForStaleResults && (_jsxs("div", { className: "data-quality-validation__result__stale-status", children: [_jsx("div", { className: "data-quality-validation__result__stale-status__icon", children: _jsx(ExclamationTriangleIcon, {}) }), _jsx("div", { className: "data-quality-validation__result__stale-status__label", children: "Preview data might be stale" })] }))] }), _jsx(ControlledDropdownMenu, { className: "data-quality-validation__result__export__dropdown", title: "Export", disabled: isExportDisabled, content: _jsx(MenuContent, { children: Object.values(resultState.exportDataFormatOptions).map((format) => (_jsxs(MenuContentItem, { onClick: () => confirmExport(format), children: [_jsx(MenuContentItemIcon, { children: _jsx(CsvIcon, {}) }), _jsx(MenuContentItemLabel, { children: format })] }, format))) }), menuProps: { anchorOrigin: { vertical: 'bottom', horizontal: 'right' }, transformOrigin: { vertical: 'top', horizontal: 'right' }, elevation: 7, }, children: _jsxs("div", { className: "relation-validation-config-editor__definition__item__header__action", children: [_jsx("div", { className: "data-quality-validation__result__export__dropdown__label", children: "Export" }), _jsx("div", { className: "data-quality-validation__result__export__dropdown__trigger", children: _jsx(CaretDownIcon, {}) })] }) })] }), _jsx("div", { className: "relation-validation-config-editor__definition__item__content", children: _jsx("div", { className: "relation-validation-config-editor__definition__result-viewer", children: renderFuncResult() }) })] })] })] })); }); export const DataQualityRelationValidationConfigurationEditor = observer(() => { const editorStore = useEditorStore(); const applicationStore = useApplicationStore(); const dataQualityRelationValidationConfigurationState = editorStore.tabManagerState.getCurrentEditorState(DataQualityRelationValidationConfigurationState); const dataQualityRelationValidationElement = dataQualityRelationValidationConfigurationState.validationElement; const selectedTab = dataQualityRelationValidationConfigurationState.selectedTab; const changeTab = (tab) => () => dataQualityRelationValidationConfigurationState.setSelectedTab(tab); const executionIsRunning = dataQualityRelationValidationConfigurationState.isRunningValidation || dataQualityRelationValidationConfigurationState.isGeneratingPlan; const cancelValidation = applicationStore.guardUnhandledError(() => flowResult(dataQualityRelationValidationConfigurationState.cancelValidationRun())); const runValidation = applicationStore.guardUnhandledError(() => flowResult(dataQualityRelationValidationConfigurationState.handleRunValidation())); const generatePlan = applicationStore.guardUnhandledError(() => flowResult(dataQualityRelationValidationConfigurationState.generatePlan(false))); const debugPlanGeneration = applicationStore.guardUnhandledError(() => flowResult(dataQualityRelationValidationConfigurationState.generatePlan(true))); useEffect(() => { flowResult(dataQualityRelationValidationConfigurationState.relationFunctionDefinitionEditorState.convertLambdaObjectToGrammarString({ pretty: true, firstLoad: true, })).catch(applicationStore.alertUnhandledError); flowResult(dataQualityRelationValidationConfigurationState.convertValidationLambdaObjects()).catch(applicationStore.alertUnhandledError); }, [applicationStore, dataQualityRelationValidationConfigurationState]); useApplicationNavigationContext('studio.editor.dq-relation-editor'); return (_jsxs("div", { className: "relation-validation-config-editor uml-editor uml-editor--dark", children: [_jsxs(Panel, { children: [_jsx("div", { className: "panel__header", children: _jsxs("div", { className: "panel__header__title", children: [_jsx("div", { className: "panel__header__title__label", children: "dataQualityRelationValidation" }), _jsx("div", { className: "panel__header__title__content", children: dataQualityRelationValidationElement.name })] }) }), _jsxs("div", { className: "panel__header relation-validation-config-editor__tabs__header", children: [_jsx("div", { className: "relation-validation-config-editor__tabs", children: Object.values(DATA_QUALITY_RELATION_VALIDATION_EDITOR_TAB).map((tab) => (_jsx("div", { onClick: changeTab(tab), className: clsx('relation-validation-config-editor__tab', { 'relation-validation-config-editor__tab--active': tab === selectedTab, }), children: prettyCONSTName(tab) }, tab))) }), _jsx("div", { className: "panel__header__actions", children: selectedTab === DATA_QUALITY_RELATION_VALIDATION_EDITOR_TAB.DEFINITION && (_jsx(_Fragment, { children: _jsx("div", { className: "btn__dropdown-combo btn__dropdown-combo--primary", children: dataQualityRelationValidationConfigurationState.isRunningValidation ? (_jsx("button", { className: "btn__dropdown-combo__canceler", onClick: cancelValidation, tabIndex: -1, children: _jsxs("div", { className: "btn--dark btn--caution btn__dropdown-combo__canceler__label", children: [_jsx(PauseCircleIcon, { className: "btn__dropdown-combo__canceler__label__icon" }), _jsx("div", { className: "btn__dropdown-combo__canceler__label__title", children: "Stop" })] }) })) : (_jsxs(_Fragment, { children: [_jsxs("button", { className: "btn__dropdown-combo__label", onClick: runValidation, title: "Run Function", disabled: executionIsRunning, tabIndex: -1, children: [_jsx(PlayIcon, { className: "btn__dropdown-combo__label__icon" }), _jsx("div", { className: "btn__dropdown-combo__label__title", children: "Run" })] }), _jsx(ControlledDropdownMenu, { className: "btn__dropdown-combo__dropdown-btn", disabled: executionIsRunning, content: _jsxs(MenuContent, { children: [_jsx(MenuContentItem, { className: "btn__dropdown-combo__option", onClick: generatePlan, children: "Generate Plan" }), _jsx(MenuContentItem, { className: "btn__dropdown-combo__option", onClick: debugPlanGeneration, children: "Debug" })] }), menuProps: { anchorOrigin: { vertical: 'bottom', horizontal: 'right', }, transformOrigin: { vertical: 'top', horizontal: 'right', }, }, children: _jsx(CaretDownIcon, {}) })] })) }) })) })] }), _jsxs(PanelContent, { children: [selectedTab === DATA_QUALITY_RELATION_VALIDATION_EDITOR_TAB.DEFINITION && (_jsx(RelationDefinitionEditor, { dataQualityRelationValidationConfigurationState: dataQualityRelationValidationConfigurationState })), selectedTab === DATA_QUALITY_RELATION_VALIDATION_EDITOR_TAB.TRIAL_RUN && (_jsx(DataQualityRelationTrialRuns, { dataQualityRelationValidationConfigurationState: dataQualityRelationValidationConfigurationState })), selectedTab === DATA_QUALITY_RELATION_VALIDATION_EDITOR_TAB.VALIDATIONS && (_jsx(DataQualityRelationValidationsEditor, { dataQualityRelationValidationConfigurationState: dataQualityRelationValidationConfigurationState }))] })] }), _jsx(ExecutionPlanViewer, { executionPlanState: dataQualityRelationValidationConfigurationState.executionPlanState }), dataQualityRelationValidationConfigurationState.parametersState .parameterValuesEditorState.showModal && (_jsx(LambdaParameterValuesEditor, { graph: dataQualityRelationValidationConfigurationState.editorStore .graphManagerState.graph, observerContext: dataQualityRelationValidationConfigurationState.editorStore .changeDetectionState.observerContext, lambdaParametersState: dataQualityRelationValidationConfigurationState.parametersState }))] })); }); //# sourceMappingURL=DataQualityRelationValidationConfigurationEditor.js.map