UNPKG

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

Version:
118 lines 11.9 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 { useApplicationStore } from '@finos/legend-application'; import { flowResult } from 'mobx'; import { buildFilterConditionExpression, ExecutionPlanViewer, } from '@finos/legend-query-builder'; import { MILESTONING_STEREOTYPE, buildRawLambdaFromLambdaFunction, CORE_PURE_PATH, FunctionType, GenericType, GenericTypeExplicitReference, LambdaFunction, Multiplicity, PackageableElementExplicitReference, VariableExpression, } from '@finos/legend-graph'; import { guaranteeNonNullable, isNonNullable, prettyDuration, } from '@finos/legend-shared'; import { useRef, useState } from 'react'; import { DATA_QUALITY_VALIDATION_TEST_ID } from './constants/DataQualityConstants.js'; import { BlankPanelContent, CubesLoadingIndicator, CubesLoadingIndicatorIcon, MenuContent, MenuContentItem, PanelContent, ExclamationTriangleIcon, DebugIcon, CaretDownIcon, MenuContentItemIcon, MenuContentItemLabel, PauseCircleIcon, PlayIcon, ReportIcon, ControlledDropdownMenu, } from '@finos/legend-art'; import { DataQualityResultValues } from './DataQualityResultValues.js'; import { dataQualityClassValidation_setFilter } from '../graph-manager/DSL_DataQuality_GraphModifierHelper.js'; import { DataQualityDateSelectionPanel } from './DataQualityDateSelectionPanel.js'; export const DataQualityResultPanel = observer((props) => { const { dataQualityState } = props; const applicationStore = useApplicationStore(); const resultState = dataQualityState.resultState; const executionResult = resultState.executionResult; const buildFilterExpression = (queryBuilderState) => { const { filterState } = queryBuilderState; const filterConditionExpressions = filterState.rootIds .map((e) => guaranteeNonNullable(filterState.nodes.get(e))) .map((e) => buildFilterConditionExpression(filterState, e)) .filter(isNonNullable); if (!filterConditionExpressions.length) { dataQualityClassValidation_setFilter(dataQualityState.constraintsConfigurationElement, undefined); return; } const genericType = new GenericType(guaranteeNonNullable(queryBuilderState.class)); const genericTypeReference = GenericTypeExplicitReference.create(genericType); const functionType = new FunctionType(PackageableElementExplicitReference.create(queryBuilderState.graphManagerState.graph.getType(CORE_PURE_PATH.ANY)), Multiplicity.ONE); functionType.parameters.push(new VariableExpression(filterState.lambdaParameterName, Multiplicity.ONE, genericTypeReference)); const lambdaFunction = new LambdaFunction(functionType); lambdaFunction.expressionSequence = filterConditionExpressions; dataQualityClassValidation_setFilter(dataQualityState.constraintsConfigurationElement, buildRawLambdaFromLambdaFunction(lambdaFunction, queryBuilderState.graphManagerState)); }; const runQuery = () => { resultState.pressedRunQuery.inProgress(); flowResult(resultState.runQuery()).catch(applicationStore.alertUnhandledError); resultState.pressedRunQuery.complete(); }; const cancelQuery = applicationStore.guardUnhandledError(() => flowResult(resultState.cancelQuery())); const generatePlan = applicationStore.guardUnhandledError(() => { buildFilterExpression(dataQualityState.dataQualityQueryBuilderState); return flowResult(resultState.generatePlan(false)); }); const debugPlanGeneration = applicationStore.guardUnhandledError(() => flowResult(resultState.generatePlan(true))); const allowSettingPreviewLimit = dataQualityState.isQuerySupported; const isRunQueryDisabled = resultState.isGeneratingPlan || resultState.pressedRunQuery.isInProgress || dataQualityState.dataQualityQueryBuilderState.filterState .allValidationIssues.length !== 0; const getResultSetDescription = (_executionResult) => { const queryDuration = resultState.executionDuration ? prettyDuration(resultState.executionDuration, { ms: true, }) : undefined; if (!queryDuration) { return undefined; } return `validation ran in ${queryDuration}`; }; const resultDescription = executionResult ? getResultSetDescription(executionResult) : undefined; const [previewLimitValue, setPreviewLimitValue] = useState(resultState.previewLimit); const changePreviewLimit = (event) => { setPreviewLimitValue(parseInt(event.target.value, 10)); }; const inputRef = useRef(null); const getPreviewLimit = () => { if (isNaN(previewLimitValue) || previewLimitValue === 0) { setPreviewLimitValue(1); dataQualityState.resultState.setPreviewLimit(1); } else { dataQualityState.resultState.setPreviewLimit(previewLimitValue); } }; const onKeyDown = (event) => { if (event.code === 'Enter') { getPreviewLimit(); inputRef.current?.focus(); } else if (event.code === 'Escape') { inputRef.current?.select(); } }; const isLoading = resultState.isRunningQuery || resultState.isGeneratingPlan; const currentClassMilestoningStrategy = dataQualityState.currentClassMilestoningStrategy; const showProcessingDate = currentClassMilestoningStrategy === MILESTONING_STEREOTYPE.PROCESSING_TEMPORAL || currentClassMilestoningStrategy === MILESTONING_STEREOTYPE.BITEMPORAL; const showBusinessDate = currentClassMilestoningStrategy === MILESTONING_STEREOTYPE.BUSINESS_TEMPORAL || currentClassMilestoningStrategy === MILESTONING_STEREOTYPE.BITEMPORAL; return (_jsxs("div", { "data-testid": DATA_QUALITY_VALIDATION_TEST_ID.DATA_QUALITY_VALIDATION_RESULT_PANEL, className: "panel data-quality-validation__result", children: [_jsxs("div", { className: "panel__header", children: [_jsxs("div", { className: "panel__header__title", children: [_jsx("div", { className: "panel__header__title__label", children: "results" }), resultState.pressedRunQuery.isInProgress && (_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 ?? '' }), executionResult && resultState.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" })] }))] }), _jsxs("div", { className: "panel__header__actions data-quality-validation__result__header__actions", children: [showProcessingDate && (_jsxs("div", { className: "trial-runs-result-modifier-prompt__group", children: [_jsx("div", { className: "trial-runs-result-modifier-prompt__group__label", children: "Processing Date" }), _jsx("button", { className: "trial-runs-result-modifier-prompt__header__label editable-value", onClick: () => dataQualityState.setShowDateSelection(true), children: _jsx("div", { className: "trial-runs-result-modifier-prompt__header__label__title", children: dataQualityState.processingDate }) })] })), showBusinessDate && (_jsxs("div", { className: "trial-runs-result-modifier-prompt__group", children: [_jsx("div", { className: "trial-runs-result-modifier-prompt__group__label", children: "Business Date" }), _jsx("button", { className: "trial-runs-result-modifier-prompt__header__label editable-value", onClick: () => dataQualityState.setShowDateSelection(true), children: _jsx("div", { className: "trial-runs-result-modifier-prompt__header__label__title", children: dataQualityState.businessDate }) })] })), allowSettingPreviewLimit && (_jsxs("div", { className: "data-quality-validation__result__limit", children: [_jsx("div", { className: "data-quality-validation__result__limit__label", children: "preview row limit" }), _jsx("input", { ref: inputRef, className: "input--dark data-quality-validation__result__limit__input", spellCheck: false, type: "number", value: previewLimitValue, onChange: changePreviewLimit, onBlur: getPreviewLimit, onKeyDown: onKeyDown })] })), _jsx("div", { className: "data-quality-validation__result__execute-btn btn__dropdown-combo btn__dropdown-combo--primary", children: resultState.isRunningQuery ? (_jsx("button", { className: "btn__dropdown-combo__canceler data-quality-validation__result__execute-btn__btn", onClick: cancelQuery, tabIndex: -1, children: _jsxs("div", { className: "btn--dark btn--caution btn__dropdown-combo__canceler__label data-quality-validation__result__execute-btn__btn", children: [_jsx(PauseCircleIcon, {}), "Stop"] }) })) : (_jsxs(_Fragment, { children: [_jsxs("button", { className: "btn__dropdown-combo__label data-quality-validation__result__execute-btn__validation data-quality-validation__result__execute-btn__btn data-quality-validation__result__execute-btn__btn--green", onClick: runQuery, tabIndex: -1, disabled: isRunQueryDisabled, children: [_jsx(PlayIcon, {}), "Run Validation"] }), _jsx(ControlledDropdownMenu, { className: "btn__dropdown-combo__dropdown-btn data-quality-validation__result__execute-btn__btn data-quality-validation__result__execute-btn__btn--green", disabled: isRunQueryDisabled, content: _jsxs(MenuContent, { children: [_jsxs(MenuContentItem, { className: "btn__dropdown-combo__option", onClick: generatePlan, disabled: isRunQueryDisabled, children: [_jsx(MenuContentItemIcon, { children: _jsx(ReportIcon, {}) }), _jsx(MenuContentItemLabel, { children: "Generate Plan" })] }), _jsxs(MenuContentItem, { className: "btn__dropdown-combo__option", onClick: debugPlanGeneration, disabled: isRunQueryDisabled, children: [_jsx(MenuContentItemIcon, { children: _jsx(DebugIcon, {}) }), _jsx(MenuContentItemLabel, { children: "Debug" })] })] }), menuProps: { anchorOrigin: { vertical: 'bottom', horizontal: 'right' }, transformOrigin: { vertical: 'top', horizontal: 'right' }, }, children: _jsx(CaretDownIcon, {}) })] })) })] })] }), _jsxs(PanelContent, { className: "data-quality-validation__result__content", children: [_jsx(CubesLoadingIndicator, { isLoading: isLoading, children: _jsx(CubesLoadingIndicatorIcon, {}) }), !executionResult && !isLoading && (_jsx(BlankPanelContent, { children: "Click on run validation to see the constraints validation results" })), executionResult && !isLoading && (_jsx("div", { className: "data-quality-validation__result__values", children: _jsx(DataQualityResultValues, { executionResult: executionResult }) }))] }), _jsx(ExecutionPlanViewer, { executionPlanState: resultState.executionPlanState }), _jsx(DataQualityDateSelectionPanel, { dataQualityState: dataQualityState })] })); }); //# sourceMappingURL=DataQualityResultPanel.js.map