Skip to content

Commit

Permalink
MR | DQ Validation element fix and enhancement (#3478)
Browse files Browse the repository at this point in the history
  • Loading branch information
viju4076 authored Aug 28, 2024
1 parent fbeeb38 commit fdfb9f4
Show file tree
Hide file tree
Showing 9 changed files with 173 additions and 58 deletions.
5 changes: 5 additions & 0 deletions .changeset/purple-weeks-cheer.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@finos/legend-extension-dsl-data-quality': patch
---

dq validation element fix to create element with default values and enhancement to select or deselect all constraints of a class at once
Original file line number Diff line number Diff line change
Expand Up @@ -28,18 +28,25 @@ import {
filterByType,
getNullableFirstEntry,
guaranteeNonNullable,
UnsupportedOperationError,
} from '@finos/legend-shared';
import {
type Mapping,
type PackageableRuntime,
type Class,
getMappingCompatibleRuntimes,
PackageableElementExplicitReference,
getMappingCompatibleClasses,
} from '@finos/legend-graph';
import {
type PackageableElementOption,
buildElementOption,
} from '@finos/legend-lego/graph-editor';
import { DataSpace } from '@finos/legend-extension-dsl-data-space/graph';
import {
DataSpace,
resolveUsableDataSpaceClasses,
} from '@finos/legend-extension-dsl-data-space/graph';
import { buildDefaultDataQualityRootGraphFetchTree } from './utils/DataQualityGraphFetchTreeUtil.js';

export type RuntimeOption = {
label: string;
Expand Down Expand Up @@ -136,6 +143,7 @@ export class DataQuality_ClassElementDriver extends NewElementDriver<DataQuality
}

createElement(name: string): DataQualityClassValidationsConfiguration {
let usableClasses: Class[] = [];
const dataQualityConstraintsConfiguration =
new DataQualityClassValidationsConfiguration(name);
if (
Expand All @@ -152,6 +160,11 @@ export class DataQuality_ClassElementDriver extends NewElementDriver<DataQuality
dataQualityConstraintsConfiguration.context = dataSpaceExecutionContext;
dataQualityConstraintsConfiguration.dataQualityRootGraphFetchTree =
undefined;
usableClasses = resolveUsableDataSpaceClasses(
dataSpaceToSet.value,
dataSpaceToSet.value.defaultExecutionContext.mapping.value,
this.editorStore.graphManagerState,
);
} else {
if (this.mappingSelected && this.runtimeSelected) {
const mappingOption = guaranteeNonNullable(this.mappingSelected);
Expand All @@ -166,10 +179,19 @@ export class DataQuality_ClassElementDriver extends NewElementDriver<DataQuality
mappingAndRuntimeExecutionContext.runtime = runtimeValue;
dataQualityConstraintsConfiguration.context =
mappingAndRuntimeExecutionContext;
usableClasses = getMappingCompatibleClasses(
mapping.value,
this.editorStore.graphManagerState.usableClasses,
);
}
dataQualityConstraintsConfiguration.dataQualityRootGraphFetchTree =
undefined;
}
if (usableClasses.length === 0) {
throw new UnsupportedOperationError(
'Must have at least one usable class with given mapping',
);
}
dataQualityConstraintsConfiguration.dataQualityRootGraphFetchTree =
buildDefaultDataQualityRootGraphFetchTree(usableClasses[0]!);
return dataQualityConstraintsConfiguration;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -39,11 +39,13 @@ import {
TimesIcon,
TreeView,
ExclamationTriangleIcon,
MinusSquareIcon,
} from '@finos/legend-art';
import { dataQualityClassValidation_setDataQualityGraphFetchTree } from '../graph-manager/DSL_DataQuality_GraphModifierHelper.js';
import type { DataQualityClassValidationsConfiguration } from '../graph/metamodel/pure/packageableElements/data-quality/DataQualityValidationConfiguration.js';
import {
type Type,
type Constraint,
Class,
Enumeration,
PropertyGraphFetchTree,
Expand Down Expand Up @@ -98,25 +100,68 @@ export const DataQualityConstraintsTreeNodeContainer = observer(
) : (
<ChevronRightIcon />
)
) : (
<div />
);
) : null;
const nodeTypeIcon = type ? (
getClassPropertyIcon(type)
) : (
<PURE_UnknownElementTypeIcon />
);
const showClassConstraintsSelectionCheckBox =
!node.isReadOnly &&
node.type instanceof Class &&
node.constraints.length !== 0;
const noClassConstraintsSelected =
node.type instanceof Class &&
node.constraints.length > 0 &&
node.constraints.every((constraint) => !constraint.isSelected);
const allClassConstraintsSelected =
node.type instanceof Class &&
node.constraints.length > 0 &&
node.constraints.every((constraint) => constraint.isSelected);

const toggleExpandNode = (): void => onNodeSelect?.(node);
const deleteNode = (): void => removeNode?.(node);
const toggleChecked = (constraint: ConstraintState): void => {
dataQualityGraphFetchTreeState.updateNode(
node,
constraint.constraint,
[constraint.constraint],
!constraint.isSelected,
);
constraint.setIsSelected(!constraint.isSelected);
};

const checkBoxIcon = () => {
if (noClassConstraintsSelected) {
return <SquareIcon />;
}
if (allClassConstraintsSelected) {
return <CheckSquareIcon />;
}
return <MinusSquareIcon />;
};

const toggleClassConstraintsSelection = (): void => {
const desiredConstraints: Constraint[] = [];
let addConstraint = true;
if (!allClassConstraintsSelected) {
node.constraints.forEach((constraint) => {
desiredConstraints.push(constraint.constraint);
constraint.setIsSelected(true);
});
} else {
addConstraint = false;
node.constraints.forEach((constraint) => {
desiredConstraints.push(constraint.constraint);
constraint.setIsSelected(false);
});
}
dataQualityGraphFetchTreeState.updateNode(
node,
desiredConstraints,
addConstraint,
);
};

return (
<div className="constraints-selection-node">
<div
Expand All @@ -127,13 +172,31 @@ export const DataQualityConstraintsTreeNodeContainer = observer(
}}
>
<div className="data-quality-validation-graph-fetch-tree__node__content">
<div className="tree-view__node__icon data-quality-validation-graph-fetch-tree__node__icon">
<div
className="data-quality-validation-graph-fetch-tree__expand-icon"
onClick={toggleExpandNode}
>
{nodeExpandIcon}
</div>
<div className="data-quality-validation-graph-fetch-tree__node__icon">
{showClassConstraintsSelectionCheckBox && (
<div onClick={toggleClassConstraintsSelection}>
<button
className={clsx(
'panel__content__form__section__toggler__btn',
'data-quality-validation-graph-fetch-tree__constraint__checkbox',
{
'panel__content__form__section__toggler__btn--toggled':
!noClassConstraintsSelected,
},
)}
>
{checkBoxIcon()}
</button>
</div>
)}
{nodeExpandIcon && (
<div
className="data-quality-validation-graph-fetch-tree__expand-icon"
onClick={toggleExpandNode}
>
{nodeExpandIcon}
</div>
)}
<div
className="data-quality-validation-graph-fetch-tree__type-icon"
onClick={toggleExpandNode}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,7 @@ export const DataQualityResultPanel = observer(
if (!queryDuration) {
return undefined;
}
return `query ran in ${queryDuration}`;
return `validation ran in ${queryDuration}`;
};
const resultDescription = executionResult
? getResultSetDescription(executionResult)
Expand Down Expand Up @@ -203,7 +203,7 @@ export const DataQualityResultPanel = observer(
<div className="panel__header__title__label">results</div>
{resultState.pressedRunQuery.isInProgress && (
<div className="panel__header__title__label__status">
Running Query...
Running Validation...
</div>
)}
<div
Expand Down Expand Up @@ -259,13 +259,13 @@ export const DataQualityResultPanel = observer(
) : (
<>
<button
className="btn__dropdown-combo__label data-quality-validation__result__execute-btn__btn data-quality-validation__result__execute-btn__btn--green"
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}
>
<PlayIcon />
Run Query
Run Validation
</button>
<ControlledDropdownMenu
className="btn__dropdown-combo__dropdown-btn data-quality-validation__result__execute-btn__btn data-quality-validation__result__execute-btn__btn--green"
Expand Down Expand Up @@ -314,7 +314,7 @@ export const DataQualityResultPanel = observer(
</CubesLoadingIndicator>
{!executionResult && !isLoading && (
<BlankPanelContent>
Build or load a valid query first
Click on run validation to see the constraints validation results
</BlankPanelContent>
)}
{executionResult && !isLoading && (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,13 +71,9 @@ export class DataQualityGraphFetchTreeState implements Hashable {
);
}

onClassChange(_class: Class | undefined): void {
this.updateTreeData(_class);
}

updateNode(
node: DataQualityGraphFetchTreeNodeData,
constraint: Constraint,
constraints: Constraint[],
addConstraint: boolean,
): void {
if (!this.treeData) {
Expand All @@ -86,7 +82,7 @@ export class DataQualityGraphFetchTreeState implements Hashable {
);
return;
}
updateNodeConstraints(this.treeData, node, constraint, addConstraint);
updateNodeConstraints(this.treeData, node, constraints, addConstraint);
this.setGraphFetchTree({ ...this.treeData });
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,10 +43,13 @@ import {
import type { DataSpaceExecutionContext } from '@finos/legend-extension-dsl-data-space/graph';
import { DataQualityGraphFetchTreeState } from './DataQualityGraphFetchTreeState.js';
import {
type DataQualityRootGraphFetchTree,
DataQualityPropertyGraphFetchTree,
DataQualityRootGraphFetchTree,
} from '../../graph/metamodel/pure/packageableElements/data-quality/DataQualityGraphFetchTree.js';
import { buildGraphFetchTreeData } from '../utils/DataQualityGraphFetchTreeUtil.js';
import {
buildDefaultDataQualityRootGraphFetchTree,
buildGraphFetchTreeData,
} from '../utils/DataQualityGraphFetchTreeUtil.js';
import {
type GeneratorFn,
ActionState,
Expand Down Expand Up @@ -131,11 +134,11 @@ export abstract class DataQualityState extends ElementEditorState {
setExecutionContext: action,
setShowRuntimeSelector: action,
initializeGraphFetchTreeState: action,
initialGraphFetchTreeFromClass: action,
initializeStructuralValidationsGraphFetchTreeState: action,
setShowStructuralValidations: action,
updateElementOnClassChange: action,
checkConstraintsSelectedAtNode: action,
changeClass: action,
fetchStructuralValidations: flow,
tabsToShow: computed,
areNestedConstraintsSelected: computed,
Expand Down Expand Up @@ -193,14 +196,6 @@ export abstract class DataQualityState extends ElementEditorState {
);
}

initialGraphFetchTreeFromClass(
rootClass: Class,
): DataQualityRootGraphFetchTree {
return new DataQualityRootGraphFetchTree(
PackageableElementExplicitReference.create(rootClass),
);
}

initializeFilterState(filterLambda: RawLambda | undefined) {
if (!filterLambda) {
return;
Expand Down Expand Up @@ -334,20 +329,22 @@ export abstract class DataQualityState extends ElementEditorState {

changeClass(val: Class): void {
this.dataQualityQueryBuilderState.changeClass(val);
this.dataQualityGraphFetchTreeState.onClassChange(val);
this.structuralValidationsGraphFetchTreeState =
new DataQualityGraphFetchTreeState(this);
this.resultState = new DataQualityResultState(this);
this.initializeGraphFetchTreeState(
buildDefaultDataQualityRootGraphFetchTree(
this.dataQualityQueryBuilderState.class!,
),
);
this.updateElementOnClassChange();
}

updateElementOnClassChange() {
dataQualityClassValidation_setDataQualityGraphFetchTree(
this
.constraintsConfigurationElement as DataQualityClassValidationsConfiguration,
this.initialGraphFetchTreeFromClass(
this.dataQualityQueryBuilderState.class!,
),
this.dataQualityGraphFetchTreeState.treeData!.tree,
);
dataQualityClassValidation_setFilter(
this
Expand Down
Loading

0 comments on commit fdfb9f4

Please sign in to comment.