@finos/legend-extension-dsl-data-quality
Version:
Legend extension for Data Quality
155 lines • 7.55 kB
JavaScript
/**
* Copyright (c) 2026-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 { PanelDisplayState } from '@finos/legend-art';
import { DataQualityRelationValidationState } from './DataQualityRelationValidationState.js';
import { ActionState, assertErrorThrown, hashValue, } from '@finos/legend-shared';
import { action, computed, flow, makeObservable, observable } from 'mobx';
import { getDataQualityPureGraphManagerExtension } from '../../graph-manager/protocol/pure/DSL_DataQuality_PureGraphManagerExtension.js';
import { buildExecutionParameterValues } from '@finos/legend-query-builder';
import { DataQualityRelationValidation } from '../../graph-manager/index.js';
export var SuggestedValidationsFilter;
(function (SuggestedValidationsFilter) {
SuggestedValidationsFilter[SuggestedValidationsFilter["ALL"] = 0] = "ALL";
SuggestedValidationsFilter[SuggestedValidationsFilter["NEW"] = 1] = "NEW";
SuggestedValidationsFilter[SuggestedValidationsFilter["MODIFICATIONS"] = 2] = "MODIFICATIONS";
})(SuggestedValidationsFilter || (SuggestedValidationsFilter = {}));
export var SuggestionType;
(function (SuggestionType) {
SuggestionType["NEW"] = "NEW";
SuggestionType["EDIT"] = "EDIT";
SuggestionType["APPLIED"] = "APPLIED";
})(SuggestionType || (SuggestionType = {}));
export class SuggestedValidationsState {
parentState;
suggestionPanelState;
fetchState = ActionState.create();
suggestedValidations = [];
filter = SuggestedValidationsFilter.ALL;
constructor(parentState) {
makeObservable(this, {
suggestedValidations: observable,
filter: observable,
onClickSuggestValidations: action,
onFilterChange: action,
fetchValidationSuggestions: flow,
existingValidationsByName: computed,
selectedSuggestions: computed,
filteredSuggestions: computed,
});
this.parentState = parentState;
this.suggestionPanelState = new PanelDisplayState({
initial: 0,
default: 300,
snap: 100,
});
}
get existingValidationsByName() {
return new Map(this.parentState.validationStates.map((s) => [
s.relationValidation.name,
hashValue(s.lambdaString),
]));
}
get filteredSuggestions() {
return this.suggestedValidations.filter((s) => {
const type = this.getSuggestionType(s);
switch (this.filter) {
case SuggestedValidationsFilter.NEW:
return type === SuggestionType.NEW;
case SuggestedValidationsFilter.MODIFICATIONS:
return type === SuggestionType.EDIT;
default:
return type === SuggestionType.NEW || type === SuggestionType.EDIT;
}
});
}
get selectedSuggestions() {
return this.filteredSuggestions.filter((e) => e.isSelected);
}
getSuggestionType(suggestion) {
const name = suggestion.relationValidation.name;
const existingHash = this.existingValidationsByName.get(name);
// TODO: name does not exist already treated as new rule probably needs to change if exact assertion exist, because then the suggestion is unecessary?
if (existingHash === undefined) {
return SuggestionType.NEW;
}
return existingHash !== hashValue(suggestion.lambdaString)
? SuggestionType.EDIT
: SuggestionType.APPLIED;
}
onClickSuggestValidations = () => {
if (!this.suggestionPanelState.isOpen) {
this.suggestionPanelState.toggle();
}
if (!this.fetchState.isInProgress) {
this.fetchValidationSuggestions();
}
};
onFilterChange = (newFilter) => {
this.filter = newFilter;
};
*fetchValidationSuggestions() {
this.fetchState.inProgress();
try {
// Parse the response into proper RawLambda objects
const packagePath = this.parentState.validationElement.path;
const model = this.parentState.editorStore.graphManagerState.graph;
const extension = getDataQualityPureGraphManagerExtension(this.parentState.editorStore.graphManagerState.graphManager);
const options = {
lambdaParameterValues: buildExecutionParameterValues(this.parentState.parametersState.parameterStates, this.parentState.editorStore.graphManagerState),
};
const result = (yield extension.fetchValidationSuggestions(model, packagePath, options));
const suggestions = result.map((suggestion) => {
const lambda = this.parentState.editorStore.graphManagerState.graphManager.buildRawValueSpecification(suggestion.assertion, this.parentState.editorStore.graphManagerState.graph);
const validation = new DataQualityRelationValidation(suggestion.name, lambda);
if (suggestion.type) {
validation.type = suggestion.type;
}
return validation;
});
// Create validation states
const suggestedValidations = suggestions.map((validation) => new DataQualityRelationValidationState(validation, this.parentState.editorStore));
// Convert to grammar strings for display
const lambdas = new Map();
suggestedValidations.forEach((validationState) => {
lambdas.set(validationState.lambdaId, validationState.relationValidation.assertion);
});
suggestedValidations.forEach((validationState) => {
validationState.initializeWithColumns(this.parentState.relationTypeMetadata.columns);
});
const isolatedLambdas = (yield this.parentState.editorStore.graphManagerState.graphManager.lambdasToPureCode(lambdas));
isolatedLambdas.forEach((grammarText, key) => {
const validationState = suggestedValidations.find((state) => state.lambdaId === key);
if (validationState) {
validationState.setLambdaString(validationState.extractLambdaString(grammarText));
}
});
suggestedValidations.forEach((validationState) => {
if (validationState.dataQualityValidationLambdaFormState) {
const description = validationState.dataQualityValidationLambdaFormState.getDescription();
validationState.relationValidation.description = description;
}
});
this.suggestedValidations = suggestedValidations;
this.fetchState.pass();
}
catch (error) {
assertErrorThrown(error);
this.fetchState.fail();
this.parentState.editorStore.applicationStore.notificationService.notifyError(error);
}
}
}
//# sourceMappingURL=DataQualityRelationValidationSuggestedValidationState.js.map