UNPKG

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

Version:
284 lines 14.1 kB
/** * 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 { action, computed, flow, makeObservable, observable } from 'mobx'; import { CORE_PURE_PATH, FunctionType, GenericType, GenericTypeExplicitReference, getMilestoneTemporalStereotype, LambdaFunction, LambdaFunctionInstanceValue, MILESTONING_STEREOTYPE, Multiplicity, observe_ValueSpecification, PackageableElementExplicitReference, ParameterValue, PRIMITIVE_TYPE, buildRawLambdaFromLambdaFunction, VariableExpression, PROCESSING_DATE_MILESTONING_PROPERTY_NAME, BUSINESS_DATE_MILESTONING_PROPERTY_NAME, V1_RawValueSpecificationType, } from '@finos/legend-graph'; import { ElementEditorState, } from '@finos/legend-application-studio'; import { DataQualityGraphFetchTreeState } from './DataQualityGraphFetchTreeState.js'; import { DataQualityPropertyGraphFetchTree, } from '../../graph/metamodel/pure/packageableElements/data-quality/DataQualityGraphFetchTree.js'; import { buildDefaultDataQualityRootGraphFetchTree, buildGraphFetchTreeData, } from '../utils/DataQualityGraphFetchTreeUtil.js'; import { ActionState, guaranteeNonNullable, guaranteeType, hashArray, isNonNullable, assertType, at, } from '@finos/legend-shared'; import {} from '@finos/legend-application'; import { DataQualityResultState } from './DataQualityResultState.js'; import { DATA_QUALITY_HASH_STRUCTURE } from '../../graph/metamodel/DSL_DataQuality_HashUtils.js'; import { buildFilterConditionExpression, generateDefaultValueForPrimitiveType, processFilterLambda, QueryBuilderAdvancedWorkflowState, } from '@finos/legend-query-builder'; import { DataQualityQueryBuilderState } from './DataQualityQueryBuilderState.js'; import { getDataQualityPureGraphManagerExtension } from '../../graph-manager/protocol/pure/DSL_DataQuality_PureGraphManagerExtension.js'; import { dataQualityClassValidation_setDataQualityGraphFetchTree, dataQualityClassValidation_setFilter, } from '../../graph-manager/DSL_DataQuality_GraphModifierHelper.js'; import {} from '../DSL_DataQuality_LegendStudioPlugin_Extension.js'; export var DATA_QUALITY_TAB; (function (DATA_QUALITY_TAB) { DATA_QUALITY_TAB["FILTER"] = "Filter "; DATA_QUALITY_TAB["CONSTRAINTS_SELECTION"] = "Constraints Selection"; DATA_QUALITY_TAB["TRIAL_RUNS"] = "Trial Runs"; })(DATA_QUALITY_TAB || (DATA_QUALITY_TAB = {})); export function buildExtensionState(editorStore, dataQualityState) { const extensionStateBuilders = editorStore.pluginManager .getApplicationPlugins() .flatMap((plugin) => plugin.getExtensionStates?.() ?? []); for (const stateBuilder of extensionStateBuilders) { const state = stateBuilder(editorStore, dataQualityState); if (state) { return state; } } return undefined; } export class DataQualityState extends ElementEditorState { applicationStore; graphManagerState; loadDataSpacesState = ActionState.create(); onExecutionContextChange; onRuntimeChange; extensionState; selectedTab; executionContext; dataQualityGraphFetchTreeState; structuralValidationsGraphFetchTreeState; showRuntimeSelector = false; dataQualityQueryBuilderState; resultState; showStructuralValidations = false; showDateSelection = false; processingDate = generateDefaultValueForPrimitiveType(PRIMITIVE_TYPE.STRICTDATE); businessDate = generateDefaultValueForPrimitiveType(PRIMITIVE_TYPE.STRICTDATE); constructor(editorStore, element) { super(editorStore, element); makeObservable(this, { selectedTab: observable, showRuntimeSelector: observable, dataQualityGraphFetchTreeState: observable, structuralValidationsGraphFetchTreeState: observable, dataQualityQueryBuilderState: observable, showStructuralValidations: observable, showDateSelection: observable, processingDate: observable, businessDate: observable, constraintsConfigurationElement: computed, setSelectedTab: action, setExecutionContext: action, setShowRuntimeSelector: action, initializeGraphFetchTreeState: action, initializeStructuralValidationsGraphFetchTreeState: action, setShowStructuralValidations: action, setShowDateSelection: action, updateElementOnClassChange: action, checkConstraintsSelectedAtNode: action, changeSourceElement: action, setProcessingDate: action, setBusinessDate: action, fetchStructuralValidations: flow, tabsToShow: computed, areNestedConstraintsSelected: computed, hashCode: computed, }); this.applicationStore = this.editorStore.applicationStore; this.graphManagerState = this.editorStore.graphManagerState; this.dataQualityQueryBuilderState = new DataQualityQueryBuilderState(this.editorStore.applicationStore, this.editorStore.graphManagerState, QueryBuilderAdvancedWorkflowState.INSTANCE, this.editorStore.applicationStore.config.options.queryBuilderConfig, undefined); this.selectedTab = DATA_QUALITY_TAB.CONSTRAINTS_SELECTION; this.dataQualityGraphFetchTreeState = new DataQualityGraphFetchTreeState(this); this.structuralValidationsGraphFetchTreeState = new DataQualityGraphFetchTreeState(this); this.resultState = new DataQualityResultState(this); this.extensionState = buildExtensionState(this.editorStore, this); } setShowStructuralValidations(val) { this.showStructuralValidations = val; } setShowDateSelection(val) { this.showDateSelection = val; } setProcessingDate(val) { this.processingDate = val; } setBusinessDate(val) { this.businessDate = val; } get tabsToShow() { const tabs = Object.values(DATA_QUALITY_TAB); const extensionTabGetters = this.editorStore.pluginManager .getApplicationPlugins() .flatMap((plugin) => plugin.getAllTabs?.() ?? []); for (const tabGetter of extensionTabGetters) { tabs.push(...tabGetter()); } return tabs; } get currentClassMilestoningStrategy() { const currentclass = this.dataQualityQueryBuilderState.sourceClass; if (currentclass !== undefined) { return getMilestoneTemporalStereotype(currentclass, this.graphManagerState.graph); } return undefined; } get isCurrentClassMilestoned() { return this.currentClassMilestoningStrategy !== undefined; } get lambdaParameterValues() { const parameters = []; const currentClassMilestoningStrategy = this.currentClassMilestoningStrategy; if (currentClassMilestoningStrategy === MILESTONING_STEREOTYPE.PROCESSING_TEMPORAL || currentClassMilestoningStrategy === MILESTONING_STEREOTYPE.BITEMPORAL) { const parameterValue = new ParameterValue(); parameterValue.name = PROCESSING_DATE_MILESTONING_PROPERTY_NAME; parameterValue.value = { _type: V1_RawValueSpecificationType.CSTRICTDATE, value: this.processingDate, }; parameters.push(parameterValue); } if (currentClassMilestoningStrategy === MILESTONING_STEREOTYPE.BUSINESS_TEMPORAL || currentClassMilestoningStrategy === MILESTONING_STEREOTYPE.BITEMPORAL) { const parameterValue = new ParameterValue(); parameterValue.name = BUSINESS_DATE_MILESTONING_PROPERTY_NAME; parameterValue.value = { _type: V1_RawValueSpecificationType.CSTRICTDATE, value: this.businessDate, }; parameters.push(parameterValue); } return parameters; } *fetchStructuralValidations() { const packagePath = this.constraintsConfigurationElement.path; const model = this.graphManagerState.graph; const rootGraphFetchTree = (yield getDataQualityPureGraphManagerExtension(this.graphManagerState.graphManager).fetchStructuralValidations(model, packagePath, {})); this.initializeStructuralValidationsGraphFetchTreeState(rootGraphFetchTree); } initializeFilterState(filterLambda) { if (!filterLambda) { return; } const filterSpec = observe_ValueSpecification(this.graphManagerState.graphManager.buildValueSpecification(this.graphManagerState.graphManager.serializeRawValueSpecification(filterLambda), this.graphManagerState.graph), this.dataQualityQueryBuilderState.observerContext); const compiledValueSpecification = guaranteeType(filterSpec, LambdaFunctionInstanceValue, `Can't build filter state: data quality filter only support lambda`); processFilterLambda(at(compiledValueSpecification.values, 0), this.dataQualityQueryBuilderState); } initializeGraphFetchTreeState(tree) { if (!tree) { return; } this.dataQualityGraphFetchTreeState.treeData = buildGraphFetchTreeData(this.editorStore, tree, true, true, false); } get areNestedConstraintsSelected() { const treeData = this.dataQualityGraphFetchTreeState.treeData; if (!treeData) { return false; } let constraintSelectedAtChildLevel = false; treeData.tree.subTrees.forEach((subtree) => { constraintSelectedAtChildLevel = constraintSelectedAtChildLevel || this.checkConstraintsSelectedAtNode(subtree); }); return constraintSelectedAtChildLevel; } checkConstraintsSelectedAtNode(tree) { assertType(tree, DataQualityPropertyGraphFetchTree); if (tree.constraints.length > 0) { return true; } let constraintSelectedAtChildLevel = false; tree.subTrees.forEach((subtree) => { constraintSelectedAtChildLevel = constraintSelectedAtChildLevel || this.checkConstraintsSelectedAtNode(subtree); }); return constraintSelectedAtChildLevel; } updateFilterElement = () => { const { filterState } = this.dataQualityQueryBuilderState; const filterConditionExpressions = filterState.rootIds .map((e) => guaranteeNonNullable(filterState.nodes.get(e))) .map((e) => buildFilterConditionExpression(filterState, e)) .filter(isNonNullable); if (!filterConditionExpressions.length) { dataQualityClassValidation_setFilter(this .constraintsConfigurationElement, undefined); return; } const genericType = new GenericType(guaranteeNonNullable(this.dataQualityQueryBuilderState.sourceClass)); const genericTypeReference = GenericTypeExplicitReference.create(genericType); const functionType = new FunctionType(PackageableElementExplicitReference.create(this.dataQualityQueryBuilderState.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(this .constraintsConfigurationElement, buildRawLambdaFromLambdaFunction(lambdaFunction, this.dataQualityQueryBuilderState.graphManagerState)); }; initializeStructuralValidationsGraphFetchTreeState(tree) { if (!tree) { return; } this.structuralValidationsGraphFetchTreeState.treeData = buildGraphFetchTreeData(this.editorStore, tree, true, true, true); } get sideBarClassName() { return this.showRuntimeSelector ? 'data-quality-validation__setup__data-space--with-runtime' : 'data-quality-validation__setup__data-space'; } changeSourceElement(val) { this.dataQualityQueryBuilderState.changeSourceElement(val); this.structuralValidationsGraphFetchTreeState = new DataQualityGraphFetchTreeState(this); this.resultState = new DataQualityResultState(this); this.initializeGraphFetchTreeState(buildDefaultDataQualityRootGraphFetchTree(guaranteeNonNullable(this.dataQualityQueryBuilderState.sourceClass))); this.updateElementOnClassChange(); } updateElementOnClassChange() { dataQualityClassValidation_setDataQualityGraphFetchTree(this .constraintsConfigurationElement, guaranteeNonNullable(this.dataQualityGraphFetchTreeState.treeData).tree); dataQualityClassValidation_setFilter(this .constraintsConfigurationElement, undefined); } setExecutionContext(val) { this.executionContext = val; } get isMappingReadOnly() { return false; } get isRuntimeReadOnly() { return false; } get isQuerySupported() { return true; } setSelectedTab(tab) { this.selectedTab = tab; } setShowRuntimeSelector(val) { this.showRuntimeSelector = val; } get hashCode() { return hashArray([ DATA_QUALITY_HASH_STRUCTURE.DATA_QUALITY_STATE, this.dataQualityGraphFetchTreeState, this.dataQualityQueryBuilderState.filterState, ]); } } //# sourceMappingURL=DataQualityState.js.map