Skip to content

Commit

Permalink
render function explorer tree from function analysis info and dataspa…
Browse files Browse the repository at this point in the history
…ce executable from dataspace analytics result (#3583)
  • Loading branch information
YannanGao-gs authored Oct 16, 2024
1 parent cba0336 commit ec95430
Show file tree
Hide file tree
Showing 19 changed files with 979 additions and 252 deletions.
6 changes: 6 additions & 0 deletions .changeset/cold-jokes-mix.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
'@finos/legend-extension-dsl-data-space': patch
'@finos/legend-query-builder': patch
'@finos/legend-server-depot': patch
'@finos/legend-graph': patch
---
5 changes: 5 additions & 0 deletions .changeset/witty-mangos-care.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@finos/legend-query-builder': patch
---

Render function explorer tree from function analysis info and dataspace executable from dataspace analytics result
Original file line number Diff line number Diff line change
Expand Up @@ -22,69 +22,67 @@ import {
TagIcon,
} from '@finos/legend-art';
import { observer } from 'mobx-react-lite';
import { useRef } from 'react';
import { useEffect, useRef } from 'react';
import {
ActionAlertActionType,
ActionAlertType,
useApplicationStore,
} from '@finos/legend-application';
import { DocumentationLink } from '@finos/legend-lego/application';
import type { DataSpaceExecutable } from '../../graph/metamodel/pure/model/packageableElements/dataSpace/DSL_DataSpace_DataSpace.js';
import type { DataSpaceQueryBuilderState } from '../../stores/query-builder/DataSpaceQueryBuilderState.js';
import { DSL_DATA_SPACE_LEGEND_QUERY_DOCUMENTATION_KEY } from '../../__lib__/query/DSL_DataSpace_LegendQueryDocumentation.js';
import {
getExecutionContextFromDataspaceExecutable,
getQueryFromDataspaceExecutable,
} from '../../graph-manager/DSL_DataSpace_GraphManagerHelper.js';
import { flowResult } from 'mobx';
import type { DataSpaceExecutableAnalysisResult } from '../../graph-manager/action/analytics/DataSpaceAnalysis.js';

const DataSpaceTemplateQueryDialog = observer(
(props: {
triggerElement: HTMLElement | null;
queryBuilderState: DataSpaceQueryBuilderState;
templateQueries: DataSpaceExecutable[];
templateQueries: DataSpaceExecutableAnalysisResult[];
}) => {
const { triggerElement, queryBuilderState, templateQueries } = props;
const applicationStore = useApplicationStore();
const handleClose = (): void => {
queryBuilderState.setTemplateQueryDialogOpen(false);
};

const loadTemplateQuery = (template: DataSpaceExecutable): void => {
const executionContext = getExecutionContextFromDataspaceExecutable(
queryBuilderState.dataSpace,
template,
);
if (!executionContext) {
applicationStore.notificationService.notifyError(
'Unable find an executionContext of this template query within current dataspace',
);
const loadTemplateQuery = async (
template: DataSpaceExecutableAnalysisResult,
): Promise<void> => {
let query;
if (template.info) {
query =
await queryBuilderState.graphManagerState.graphManager.pureCodeToLambda(
template.info.query,
);
}
const query = getQueryFromDataspaceExecutable(
template,
queryBuilderState.graphManagerState,
);
if (!query) {
applicationStore.notificationService.notifyError(
'Unable get a query from this template query',
);
}
if (
query &&
executionContext &&
executionContext.hashCode !==
queryBuilderState.executionContext.hashCode
) {
queryBuilderState.setExecutionContext(executionContext);
queryBuilderState.propagateExecutionContextChange(executionContext);
queryBuilderState.initializeWithQuery(query);
queryBuilderState.onExecutionContextChange?.(executionContext);
} else if (query) {
queryBuilderState.initializeWithQuery(query);
} else {
const executionContext =
queryBuilderState.dataSpace.executionContexts.filter(
(ex) => ex.name === template.info?.executionContextKey,
)[0];
if (
executionContext &&
executionContext.name !== queryBuilderState.executionContext.name
) {
queryBuilderState.setExecutionContext(executionContext);
queryBuilderState.propagateExecutionContextChange(executionContext);
queryBuilderState.initializeWithQuery(query);
queryBuilderState.onExecutionContextChange?.(executionContext);
} else {
queryBuilderState.initializeWithQuery(query);
}
}
handleClose();
};

const loadQuery = (template: DataSpaceExecutable): void => {
const loadQuery = async (
template: DataSpaceExecutableAnalysisResult,
): Promise<void> => {
if (queryBuilderState.changeDetectionState.hasChanged) {
applicationStore.alertService.setActionAlertInfo({
message:
Expand All @@ -94,7 +92,9 @@ const DataSpaceTemplateQueryDialog = observer(
{
label: 'Proceed',
type: ActionAlertActionType.PROCEED_WITH_CAUTION,
handler: (): void => loadTemplateQuery(template),
handler: (): void => {
flowResult(loadTemplateQuery(template));
},
},
{
label: 'Abort',
Expand All @@ -104,11 +104,13 @@ const DataSpaceTemplateQueryDialog = observer(
],
});
} else {
loadTemplateQuery(template);
flowResult(loadTemplateQuery(template));
}
};

const visitTemplateQuery = (template: DataSpaceExecutable): void => {
const visitTemplateQuery = (
template: DataSpaceExecutableAnalysisResult,
): void => {
if (queryBuilderState.dataSpaceRepo.canVisitTemplateQuery) {
queryBuilderState.dataSpaceRepo.visitTemplateQuery(
queryBuilderState.dataSpace,
Expand Down Expand Up @@ -157,7 +159,9 @@ const DataSpaceTemplateQueryDialog = observer(
<button
className="query-builder__data-space__template-query-panel__query__entry"
title="click to load template query"
onClick={() => loadQuery(query)}
onClick={() => {
flowResult(loadQuery(query));
}}
>
<div className="query-builder__data-space__template-query-panel__query__entry__content">
<div className="query-builder__data-space__template-query-panel__query__entry__content__title">
Expand Down Expand Up @@ -196,12 +200,17 @@ const DataSpaceTemplateQueryDialog = observer(
const DataSpaceQueryBuilderTemplateQueryPanel = observer(
(props: { queryBuilderState: DataSpaceQueryBuilderState }) => {
const { queryBuilderState } = props;
const applicationStore = useApplicationStore();
const templateQueryButtonRef = useRef<HTMLButtonElement>(null);
const templateQueries = queryBuilderState.dataSpace.executables;

const showTemplateQueries = (): void => {
queryBuilderState.setTemplateQueryDialogOpen(true);
};
const templateQueries = queryBuilderState.displayedTemplateQueries;
useEffect(() => {
flowResult(queryBuilderState.intialize()).catch(
applicationStore.alertUnhandledError,
);
}, [queryBuilderState, applicationStore.alertUnhandledError]);

return (
<>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import type {
PureModel,
DatasetSpecification,
MappingModelCoverageAnalysisResult,
FunctionAnalysisInfo,
} from '@finos/legend-graph';
import { prettyCONSTName, uuid } from '@finos/legend-shared';
import type { DataSpaceSupportInfo } from '../../../graph/metamodel/pure/model/packageableElements/dataSpace/DSL_DataSpace_DataSpace.js';
Expand Down Expand Up @@ -221,6 +222,9 @@ export class DataSpaceAnalysisResult {
MappingModelCoverageAnalysisResult
>;

functionInfos?: Map<string, FunctionAnalysisInfo>;
dependencyFunctionInfos?: Map<string, FunctionAnalysisInfo>;

get displayName(): string {
return this.title ?? prettyCONSTName(this.name);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,31 @@
* limitations under the License.
*/

import { getExpectedArtifactGenerationExtensionOutputPath } from '@finos/legend-graph';
import {
type GraphManagerState,
ConcreteFunctionDefinition,
getExpectedArtifactGenerationExtensionOutputPath,
Service,
} from '@finos/legend-graph';
import type {
DepotServerClient,
StoreProjectData,
} from '@finos/legend-server-depot';
import type { PlainObject } from '@finos/legend-shared';
import type { DataSpaceAnalysisResult } from './DataSpaceAnalysis.js';
import { isNonNullable, type PlainObject } from '@finos/legend-shared';
import {
type DataSpaceAnalysisResult,
DataSpaceExecutableAnalysisResult,
DataSpaceFunctionPointerExecutableInfo,
DataSpaceServiceExecutableInfo,
DataSpaceTemplateExecutableInfo,
} from './DataSpaceAnalysis.js';
import {
type DataSpaceExecutable,
type DataSpace,
DataSpaceExecutableTemplate,
DataSpacePackageableElementExecutable,
} from '../../../graph/metamodel/pure/model/packageableElements/dataSpace/DSL_DataSpace_DataSpace.js';
import { getQueryFromDataspaceExecutable } from '../../DSL_DataSpace_GraphManagerHelper.js';

const DATASPACE_ANALYTICS_FILE_NAME = 'AnalyticsResult.json';
const V1_DATASPACE_ANALYTICS_ARTIFACT_EXTENSION_KEY = 'dataSpace-analytics';
Expand All @@ -42,3 +60,52 @@ export const retrieveAnalyticsResultCache = async (
),
),
);

export const buildDataSpaceExecutableAnalysisResultFromExecutable = async (
dataspace: DataSpace,
executables: DataSpaceExecutable[],
graphManagerState: GraphManagerState,
): Promise<DataSpaceExecutableAnalysisResult[]> =>
(
await Promise.all(
executables.map(async (executable) => {
const result = new DataSpaceExecutableAnalysisResult();
result.title = executable.title;
result.description = executable.description;
let info;
const query = getQueryFromDataspaceExecutable(
executable,
graphManagerState,
);
if (executable instanceof DataSpaceExecutableTemplate) {
info = new DataSpaceTemplateExecutableInfo();
if (executable.id) {
info.id = executable.id;
}
} else if (
executable instanceof DataSpacePackageableElementExecutable
) {
if (executable.executable.value instanceof Service) {
info = new DataSpaceServiceExecutableInfo();
info.id = executable.id ?? executable.executable.value.path;
} else if (
executable.executable.value instanceof ConcreteFunctionDefinition
) {
info = new DataSpaceFunctionPointerExecutableInfo();
info.id = executable.id ?? executable.executable.value.path;
}
}
if (info) {
info.executionContextKey =
executable.executionContextKey ??
dataspace.defaultExecutionContext.name;
if (query) {
info.query =
await graphManagerState.graphManager.lambdaToPureCode(query);
}
}
result.info = info;
return result;
}),
)
).filter(isNonNullable);
Loading

0 comments on commit ec95430

Please sign in to comment.