@finos/legend-extension-dsl-data-space
Version:
Legend extension for Data Space DSL
173 lines • 14.3 kB
JavaScript
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 { CustomSelectorInput, createFilter, ControlledDropdownMenu, MenuContentItem, MenuContent, MenuContentItemIcon, CheckIcon, MenuContentItemLabel, SearchIcon, PanelHeaderActions, PanelHeader, MoreVerticalIcon, compareLabelFn, PanelHeaderActionItem, AnchorLinkIcon, } from '@finos/legend-art';
import { observer } from 'mobx-react-lite';
import { useApplicationStore } from '@finos/legend-application';
import { resolveUsableDataSpaceClasses, DataSpacesDepotRepository, } from '../../stores/query-builder/DataSpaceQueryBuilderState.js';
import { buildRuntimeValueOption, getRuntimeOptionFormatter, QueryBuilderClassSelector, } from '@finos/legend-query-builder';
import { getMappingCompatibleRuntimes, PackageableElementExplicitReference, RuntimePointer, } from '@finos/legend-graph';
import { generateGAVCoordinates } from '@finos/legend-storage';
import { useEffect } from 'react';
import { guaranteeNonNullable, guaranteeType } from '@finos/legend-shared';
import { flowResult } from 'mobx';
import {} from '../../graph/metamodel/pure/model/packageableElements/dataSpace/DSL_DataSpace_DataSpace.js';
import { DataSpaceAdvancedSearchModal } from './DataSpaceAdvancedSearchModal.js';
import { generateDataSpaceQueryCreatorRoute } from '../../__lib__/to-delete/DSL_DataSpace_LegendQueryNavigation_to_delete.js';
export const buildDataSpaceOption = (value) => ({
label: value.title ?? value.name,
value,
});
export const formatDataSpaceOptionLabel = (option) => (_jsx("div", { className: "query-builder__setup__data-space__option", title: `${option.label} - ${option.value.path} - ${option.value.groupId && option.value.artifactId && option.value.versionId
? generateGAVCoordinates(option.value.groupId, option.value.artifactId, option.value.versionId)
: ''}`, children: _jsx("div", { className: "query-builder__setup__data-space__option__label", children: option.label }) }));
const resolveExecutionContextRuntimes = (queryBuilderState) => {
if (queryBuilderState.dataSpaceAnalysisResult) {
const executionContext = Array.from(queryBuilderState.dataSpaceAnalysisResult.executionContextsIndex.values()).find((e) => e.mapping.path ===
queryBuilderState.executionContext.mapping.value.path);
return guaranteeNonNullable(executionContext).compatibleRuntimes;
}
return getMappingCompatibleRuntimes(queryBuilderState.executionContext.mapping.value, queryBuilderState.graphManagerState.usableRuntimes);
};
export const buildExecutionContextOption = (value) => ({
label: value.name,
value,
});
/**
* This setup panel supports cascading in order: Data-space -> Execution context (-> Runtime) -> Class
*
* In other words, we will only show:
* - For runtime selector: the list of compatible runtimes with the selected
execution context mapping
* - For class selector: the list of compatible class with the selected execution context mapping
*
* See details on propagation/cascading in {@link DataSpaceQueryBuilderState}
*/
const DataSpaceQueryBuilderSetupPanelContent = observer((props) => {
const { queryBuilderState } = props;
const applicationStore = useApplicationStore();
const repo = queryBuilderState.dataSpaceRepo;
const depotRepo = repo instanceof DataSpacesDepotRepository ? repo : undefined;
const project = depotRepo?.project;
// data product
const prioritizeDataSpaceFunc = queryBuilderState.dataSpaceRepo.prioritizeDataSpaceFunc;
const sortedAllOptions = (queryBuilderState.dataSpaceRepo.dataSpaces ?? [])
.map(buildDataSpaceOption)
.sort(compareLabelFn);
const dataSpaceOptions = prioritizeDataSpaceFunc
? [
...sortedAllOptions.filter((val) => prioritizeDataSpaceFunc(val.value)),
...sortedAllOptions.filter((val) => !prioritizeDataSpaceFunc(val.value)),
]
: sortedAllOptions;
const selectedDataSpaceOption = {
label: queryBuilderState.dataSpace.title ?? queryBuilderState.dataSpace.name,
value: {
groupId: project?.groupId,
artifactId: project?.artifactId,
versionId: project?.versionId,
title: queryBuilderState.dataSpace.title,
name: queryBuilderState.dataSpace.name,
path: queryBuilderState.dataSpace.path,
defaultExecutionContext: queryBuilderState.dataSpace.defaultExecutionContext.name,
},
};
const onDataSpaceOptionChange = (option) => {
queryBuilderState.queryChatState?.abort();
queryBuilderState
.onDataSpaceChange(option.value)
.catch(queryBuilderState.applicationStore.alertUnhandledError);
};
const openDataSpaceAdvancedSearch = () => {
if (repo.isAdvancedDataSpaceSearchEnabled && depotRepo) {
depotRepo.showAdvancedSearchPanel(queryBuilderState.dataSpace);
}
};
// execution context
const executionContextOptions = queryBuilderState.dataSpace.executionContexts
.map(buildExecutionContextOption)
.sort(compareLabelFn);
const showExecutionContextOptions = executionContextOptions.length > 1;
const selectedExecutionContextOption = buildExecutionContextOption(queryBuilderState.executionContext);
const onExecutionContextOptionChange = async (option) => {
if (option.value === queryBuilderState.executionContext) {
return;
}
const currentMapping = queryBuilderState.executionContext.mapping.value.path;
queryBuilderState.setExecutionContext(option.value);
await queryBuilderState.propagateExecutionContextChange(currentMapping === option.value.mapping.value.path);
queryBuilderState.onExecutionContextChange?.(option.value);
};
const handleExecutionContextOptionChange = (option) => {
flowResult(onExecutionContextOptionChange(option));
};
// runtime
const runtimeOptions = resolveExecutionContextRuntimes(queryBuilderState)
.map((rt) => new RuntimePointer(PackageableElementExplicitReference.create(rt)))
.map(buildRuntimeValueOption)
.sort(compareLabelFn);
const selectedRuntimeOption = queryBuilderState.executionContextState
.runtimeValue
? buildRuntimeValueOption(queryBuilderState.executionContextState.runtimeValue)
: null;
const changeRuntime = (option) => {
if (option.value === queryBuilderState.executionContextState.runtimeValue) {
return;
}
queryBuilderState.changeRuntime(option.value);
queryBuilderState.onRuntimeChange?.(option.value);
};
const runtimeFilterOption = createFilter({
ignoreCase: true,
ignoreAccents: false,
stringify: (option) => guaranteeType(option.data.value, RuntimePointer).packageableRuntime
.value.path,
});
// class
const classes = resolveUsableDataSpaceClasses(queryBuilderState.dataSpace, queryBuilderState.executionContext.mapping.value, queryBuilderState.graphManagerState, queryBuilderState);
useEffect(() => {
flowResult(queryBuilderState.dataSpaceRepo.loadDataSpaces()).catch(applicationStore.alertUnhandledError);
}, [queryBuilderState, applicationStore]);
const copyDataSpaceLinkToClipboard = () => {
const nonNullableProject = guaranteeNonNullable(project, 'Unable to copy data product query set up link to clipboard because project is null');
const dataSpace = queryBuilderState.dataSpace;
const executionContext = queryBuilderState.executionContext;
const runtimePath = queryBuilderState.executionContextState.runtimeValue instanceof
RuntimePointer
? queryBuilderState.executionContextState.runtimeValue
.packageableRuntime.value.path
: undefined;
const route = applicationStore.navigationService.navigator.generateAddress(generateDataSpaceQueryCreatorRoute(nonNullableProject.groupId, nonNullableProject.artifactId, nonNullableProject.versionId, dataSpace.path, executionContext.name, runtimePath, queryBuilderState.class?.path));
navigator.clipboard
.writeText(route)
.catch(() => applicationStore.notificationService.notifyError('Error copying data product query set up link to clipboard'));
applicationStore.notificationService.notifySuccess('Copied data product query set up link to clipboard');
};
return (_jsxs("div", { className: "query-builder__setup__config-group", children: [_jsx(PanelHeader, { title: "properties", children: _jsxs(PanelHeaderActions, { children: [_jsx(PanelHeaderActionItem, { title: "copy data product query set up link to clipboard", onClick: copyDataSpaceLinkToClipboard, children: _jsx(AnchorLinkIcon, {}) }), _jsx(ControlledDropdownMenu, { className: "panel__header__action query-builder__setup__config-group__header__dropdown-trigger", title: "Show Settings...", content: _jsx(MenuContent, { children: _jsxs(MenuContentItem, { onClick: () => queryBuilderState.setShowRuntimeSelector(!queryBuilderState.showRuntimeSelector), children: [_jsx(MenuContentItemIcon, { children: queryBuilderState.showRuntimeSelector ? (_jsx(CheckIcon, {})) : null }), _jsx(MenuContentItemLabel, { children: "Show Runtime Selector" })] }) }), menuProps: {
anchorOrigin: { vertical: 'bottom', horizontal: 'right' },
transformOrigin: { vertical: 'top', horizontal: 'right' },
}, children: _jsx(MoreVerticalIcon, { className: "query-builder__icon__more-options" }) })] }) }), _jsxs("div", { className: "query-builder__setup__config-group__content", children: [_jsxs("div", { className: "query-builder__setup__config-group__item", children: [_jsx("label", { className: "btn--sm query-builder__setup__config-group__data-product", title: "data product", htmlFor: "query-builder__setup__data-space-selector", children: "Data Product" }), _jsx(CustomSelectorInput, { inputId: "query-builder__setup__data-space-selector", className: "panel__content__form__section__dropdown query-builder__setup__config-group__item__selector", options: dataSpaceOptions, isLoading: queryBuilderState.dataSpaceRepo.loadDataSpacesState.isInProgress, onChange: onDataSpaceOptionChange, value: selectedDataSpaceOption, placeholder: "Search for data product...", escapeClearsValue: true, darkMode: !applicationStore.layoutService
.TEMPORARY__isLightColorThemeEnabled, formatOptionLabel: formatDataSpaceOptionLabel }), depotRepo && (_jsxs(_Fragment, { children: [_jsx("button", { tabIndex: -1, className: "query-builder__setup__data-space-searcher__btn btn--dark", onClick: openDataSpaceAdvancedSearch, title: "Open advanced search for data product...", children: _jsx(SearchIcon, {}) }), depotRepo.advancedSearchState && (_jsx(DataSpaceAdvancedSearchModal, { searchState: depotRepo.advancedSearchState, onClose: () => depotRepo.hideAdvancedSearchPanel() }))] }))] }), Boolean(showExecutionContextOptions) && (_jsxs("div", { className: "query-builder__setup__config-group__item", children: [_jsx("label", { className: "btn--sm query-builder__setup__config-group__item__label", title: "execution context", htmlFor: "query-builder__setup__context-selector", children: "Context" }), _jsx(CustomSelectorInput, { inputId: "query-builder__setup__context-selector", className: "panel__content__form__section__dropdown query-builder__setup__config-group__item__selector", placeholder: "Choose an execution context...", options: executionContextOptions, disabled: executionContextOptions.length < 1 ||
(executionContextOptions.length === 1 &&
Boolean(selectedExecutionContextOption)), onChange: handleExecutionContextOptionChange, value: selectedExecutionContextOption, darkMode: !applicationStore.layoutService
.TEMPORARY__isLightColorThemeEnabled })] })), queryBuilderState.showRuntimeSelector && (_jsxs("div", { className: "query-builder__setup__config-group__item", children: [_jsx("label", { className: "btn--sm query-builder__setup__config-group__item__label", title: "runtime", htmlFor: "query-builder__setup__runtime-selector", children: "Runtime" }), _jsx(CustomSelectorInput, { inputId: "query-builder__setup__runtime-selector", className: "panel__content__form__section__dropdown query-builder__setup__config-group__item__selector", placeholder: "Choose a runtime...", noMatchMessage: "No compatible runtime found for specified execution context", options: runtimeOptions, onChange: changeRuntime, value: selectedRuntimeOption, darkMode: !applicationStore.layoutService
.TEMPORARY__isLightColorThemeEnabled, filterOption: runtimeFilterOption, formatOptionLabel: getRuntimeOptionFormatter({
darkMode: !applicationStore.layoutService
.TEMPORARY__isLightColorThemeEnabled,
}) })] })), _jsx("div", { className: "query-builder__setup__config-group__item", children: _jsx(QueryBuilderClassSelector, { queryBuilderState: queryBuilderState, classes: classes, onClassChange: queryBuilderState.onClassChange, noMatchMessage: "No compatible entity found for specified execution context" }) })] })] }));
});
export const renderDataSpaceQueryBuilderSetupPanelContent = (queryBuilderState) => (_jsx(DataSpaceQueryBuilderSetupPanelContent, { queryBuilderState: queryBuilderState }));
//# sourceMappingURL=DataSpaceQueryBuilder.js.map