diff --git a/packages/legend-application-data-cube/src/application/LegendDataCubePluginManager.ts b/packages/legend-application-data-cube/src/application/LegendDataCubePluginManager.ts
index 6d233f628f..cd576ec5ac 100644
--- a/packages/legend-application-data-cube/src/application/LegendDataCubePluginManager.ts
+++ b/packages/legend-application-data-cube/src/application/LegendDataCubePluginManager.ts
@@ -34,6 +34,7 @@ export class LegendDataCubePluginManager
private constructor() {
super();
}
+
registerPureProtocolProcessorPlugin(
plugin: PureProtocolProcessorPlugin,
): void {
diff --git a/packages/legend-application-data-cube/src/components/LegendDataCubeLandingPage.tsx b/packages/legend-application-data-cube/src/components/LegendDataCubeLandingPage.tsx
index fc71ac6678..581bf45e56 100644
--- a/packages/legend-application-data-cube/src/components/LegendDataCubeLandingPage.tsx
+++ b/packages/legend-application-data-cube/src/components/LegendDataCubeLandingPage.tsx
@@ -16,10 +16,12 @@
import { observer, useLocalObservable } from 'mobx-react-lite';
import { useLegendDataCubeBaseStore } from './LegendDataCubeFrameworkProvider.js';
-import { createContext, useContext } from 'react';
+import { createContext, useContext, useEffect } from 'react';
import {
DataCube,
DataCubeSettingKey,
+ FormBadge_WIP,
+ DataCubeLayoutManager,
type DataCubeState,
} from '@finos/legend-data-cube';
import { formatDate, guaranteeNonNullable } from '@finos/legend-shared';
@@ -30,6 +32,7 @@ import {
DropdownMenuItem,
useDropdownMenu,
} from '@finos/legend-art';
+import { LegendDataCubeNewQueryBuilder } from './LegendDataCubeNewQueryBuilder.js';
// const CreateQueryDialog = observer(
// (props: { view: LegendCubeViewer; store: LegendDataCubeBaseStore }) => {
@@ -100,88 +103,6 @@ import {
// },
// );
-// export const LegendDataCubeLandingPage = observer(() => {
-// const store = useLegendDataCubeBaseStore();
-// const sourceSelector = store.sourceSelector;
-
-// useEffect(() => {
-// store.context.initialize();
-// }, [store]);
-// return (
-// <>
-//
-//
-// {/* {dataCubeStore.cubeViewer ? (
-// <>
-//
-//
-// dataCubeStore.setSaveModal(true)}
-// type="button"
-// className="relative rounded-full bg-sky-900 p-1 text-gray-400 hover:text-white focus:outline-none focus:ring-2 focus:ring-white focus:ring-offset-2 focus:ring-offset-gray-800"
-// >
-// Save
-//
-//
-//
-//
-//
-//
-// >
-// ) : (
-// <>
-//
sourceSelector.openModal()}
-// className="bg-white shadow"
-// >
-//
-//
-//
-//
-//
-// Add Source
-//
-//
-//
-// >
-// )} */}
-//
-// {sourceSelector.open && (
-//
-// )}
-// {store.cubeViewer && store.saveModal && (
-//
-// )}
-// >
-// );
-// });
-
const LegendDataCubeLandingPageStoreContext = createContext<
LegendDataCubeLandingPageStore | undefined
>(undefined);
@@ -216,90 +137,128 @@ const withLegendDataCubeLandingPageStore = (WrappedComponent: React.FC) =>
);
};
-const LegendDataCubeHeader = observer((props: { dataCube: DataCubeState }) => {
- return null;
+const LegendDataCubeLandingPageHeader = observer(
+ (props: { dataCube?: DataCubeState | undefined }) => {
+ const store = useLegendDataCubeLandingPageStore();
+ const { dataCube } = props;
+
+ return (
+
+
+ Load Query
+
+
+ store.newQueryState.display.open()}
+ >
+ New Query
+
+
+ Save Query
+
+
+ );
+ },
+);
+
+const LegendDataCubeLandingPageBlank = observer(() => {
+ const store = useLegendDataCubeLandingPageStore();
+ const application = store.application;
+ const [openMenuDropdown, closeMenuDropdown, menuDropdownProps] =
+ useDropdownMenu();
+
+ return (
+
+
+
+
+
{`[ Legend DataCube ]`}
+
+
+
+
+
+
+
+ {
+ const url = application.documentationService.url;
+ if (url) {
+ application.navigationService.navigator.visitAddress(url);
+ }
+ closeMenuDropdown();
+ }}
+ disabled={true} // TODO: enable when we set up the documentation website
+ >
+ See Documentation
+
+
+
+
+
+
+
Create a new query to start
+
+ New Query
+
+
+
+
+
+
+ );
});
export const LegendDataCubeLandingPage = withLegendDataCubeLandingPageStore(
observer(() => {
const store = useLegendDataCubeLandingPageStore();
const application = store.application;
- const [openMenuDropdown, closeMenuDropdown, menuDropdownProps] =
- useDropdownMenu();
if (!store.query) {
- return (
-
-
-
-
-
{`[ Legend DataCube ]`}
-
-
-
-
-
-
- {
- const url = application.documentationService.url;
- if (url) {
- application.navigationService.navigator.visitAddress(url);
- }
- closeMenuDropdown();
- }}
- disabled={true} // TODO: enable when we set up the documentation website
- >
- See Documentation
-
-
-
-
{' '}
-
-
Create a new query to start
-
- New Query
-
-
-
-
- );
+ return ;
}
-
return (
(
-
+
),
}}
/>
diff --git a/packages/legend-application-data-cube/src/components/LegendDataCubeNewQueryBuilder.tsx b/packages/legend-application-data-cube/src/components/LegendDataCubeNewQueryBuilder.tsx
new file mode 100644
index 0000000000..30dc579f9a
--- /dev/null
+++ b/packages/legend-application-data-cube/src/components/LegendDataCubeNewQueryBuilder.tsx
@@ -0,0 +1,97 @@
+/**
+ * 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 { observer } from 'mobx-react-lite';
+import { type LegendDataCubeNewQueryState } from '../stores/LegendDataCubeNewQueryState.js';
+import { LegendDataCubeSourceBuilderType } from '../stores/source/LegendDataCubeSourceBuilderState.js';
+import {
+ Dialog,
+ Modal,
+ PanelLoadingIndicator,
+ TimesIcon,
+ cn,
+} from '@finos/legend-art';
+import { SavedQuerySourceEditor } from './source/SavedQuerySourceBuilder.js';
+import { LegendQueryDataCubeSourceBuilderState } from '../stores/source/LegendQueryDataCubeSourceBuilderState.js';
+
+export const LegendDataCubeNewQueryBuilder = observer(
+ (props: { state: LegendDataCubeNewQueryState }) => {
+ const { state } = props;
+ const sourceState = state.sourceBuilder;
+ const tabs = Object.values(LegendDataCubeSourceBuilderType);
+ const selectedTab = sourceState.label;
+
+ return (
+
+
+
+
+
+
+ {tabs.map((tab) => (
+ state.changeSourceBuilder(tab)}
+ className={cn(
+ 'flex h-6 items-center justify-center whitespace-nowrap pl-2 text-sm hover:font-bold focus:z-10',
+ {
+ 'border-b-2 border-l-0 border-r-0 border-t-0 border-solid border-sky-800':
+ tab === selectedTab,
+ },
+ )}
+ >
+ {tab}
+
+ ))}
+
+
+
+ {sourceState instanceof
+ LegendQueryDataCubeSourceBuilderState && (
+
+ )}
+
+
+
+
+ {
+ // flowResult(
+ // sourceBuilder.inputSource(
+ // (source: DataCubeGenericSource, engine: DataCubeEngine) =>
+ // store.initializeView(source, engine),
+ // ),
+ // ).catch(store.context.application.alertUnhandledError);
+ // }}
+ >
+ Open
+
+
+ Close
+
+
+
+
+ );
+ },
+);
diff --git a/packages/legend-application-data-cube/src/components/source/DataCubeSourceEditor.tsx b/packages/legend-application-data-cube/src/components/source/DataCubeSourceEditor.tsx
deleted file mode 100644
index 1239762798..0000000000
--- a/packages/legend-application-data-cube/src/components/source/DataCubeSourceEditor.tsx
+++ /dev/null
@@ -1,130 +0,0 @@
-/**
- * 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 { observer } from 'mobx-react-lite';
-import { type LegendDataCubeSourceBuilder } from '../../stores/source/LegendDataCubeSourceBuilder.js';
-import { DataCubeSourceType } from '../../stores/source/CubeInputSourceLoader.js';
-import {
- Dialog,
- Modal,
- PanelLoadingIndicator,
- TimesIcon,
- cn,
-} from '@finos/legend-art';
-import { SavedQuerySourceEditor } from './SavedQuerySourceEditor.js';
-import { SavedQueryInputSourceState } from '../../stores/source/SavedQueryInputSourceState.js';
-import { useLegendDataCubeBaseStore } from '../LegendDataCubeFrameworkProvider.js';
-
-export const DataCubeSourceEditor = observer(
- (props: { sourceBuilder: LegendDataCubeSourceBuilder }) => {
- const { sourceBuilder } = props;
- const store = useLegendDataCubeBaseStore();
- const sourceState = sourceBuilder.sourceState;
- const tabs = Object.values(DataCubeSourceType);
- const selectedTab = sourceState.label;
- const closeModal = (): void => sourceBuilder.close();
-
- return (
-
-
-
-
-
-
-
- {tabs.map((tab) => (
- sourceBuilder.changeSource(tab)}
- className={cn(
- 'flex h-6 items-center justify-center whitespace-nowrap pl-2 text-sm hover:font-bold focus:z-10',
- {
- 'border-b-2 border-l-0 border-r-0 border-t-0 border-solid border-sky-800':
- tab === selectedTab,
- },
- )}
- >
- {tab}
-
- ))}
-
-
-
- {sourceState instanceof SavedQueryInputSourceState && (
-
- )}
-
-
-
-
- {/* {
- flowResult(
- sourceBuilder.inputSource(
- (source: DataCubeGenericSource, engine: DataCubeEngine) =>
- store.initializeView(source, engine),
- ),
- ).catch(store.context.application.alertUnhandledError);
- }}
- >
- Open
-
- sourceBuilder.close()}
- >
- Close
- */}
-
-
-
- );
- },
-);
diff --git a/packages/legend-application-data-cube/src/components/source/SavedQuerySourceEditor.tsx b/packages/legend-application-data-cube/src/components/source/SavedQuerySourceBuilder.tsx
similarity index 68%
rename from packages/legend-application-data-cube/src/components/source/SavedQuerySourceEditor.tsx
rename to packages/legend-application-data-cube/src/components/source/SavedQuerySourceBuilder.tsx
index 3770f7b709..5eb7a7a8e8 100644
--- a/packages/legend-application-data-cube/src/components/source/SavedQuerySourceEditor.tsx
+++ b/packages/legend-application-data-cube/src/components/source/SavedQuerySourceBuilder.tsx
@@ -16,46 +16,46 @@
import { observer } from 'mobx-react-lite';
import { QueryLoader } from '@finos/legend-query-builder';
-import type { SavedQueryInputSourceState } from '../../stores/source/SavedQueryInputSourceState.js';
+import type { LegendQueryDataCubeSourceBuilderState } from '../../stores/source/LegendQueryDataCubeSourceBuilderState.js';
import { generateGAVCoordinates } from '@finos/legend-storage';
export const SavedQuerySourceEditor = observer(
- (props: { savedQueryInputSourceState: SavedQueryInputSourceState }) => {
- const { savedQueryInputSourceState } = props;
- const savedQuery = savedQueryInputSourceState.query;
+ (props: { sourceBuilder: LegendQueryDataCubeSourceBuilderState }) => {
+ const { sourceBuilder } = props;
+ const query = sourceBuilder.query;
return (
- {savedQuery ? (
+ {query ? (
Saved Query
Name:
-
{savedQuery.name}
+
{query.name}
Project:
{generateGAVCoordinates(
- savedQuery.groupId,
- savedQuery.artifactId,
- savedQuery.versionId,
+ query.groupId,
+ query.artifactId,
+ query.versionId,
)}
Owner:
-
{savedQuery.owner}
+
{query.owner}
) : (
- <>>
- //
+ // TODO: we could customize this loader to have a different styling
+
)}
);
diff --git a/packages/legend-application-data-cube/src/stores/LegendDataCubeBaseStore.ts b/packages/legend-application-data-cube/src/stores/LegendDataCubeBaseStore.ts
index 4e0234276c..3ca07eb28a 100644
--- a/packages/legend-application-data-cube/src/stores/LegendDataCubeBaseStore.ts
+++ b/packages/legend-application-data-cube/src/stores/LegendDataCubeBaseStore.ts
@@ -33,6 +33,7 @@ import {
guaranteeNonNullable,
} from '@finos/legend-shared';
import { LegendDataCubeDataCubeEngine } from './LegendDataCubeDataCubeEngine.js';
+import { LayoutManagerState } from '@finos/legend-data-cube';
export type LegendDataCubeApplicationStore = ApplicationStore<
LegendDataCubeApplicationConfig,
@@ -46,6 +47,7 @@ export class LegendDataCubeBaseStore {
readonly pluginManager: LegendDataCubePluginManager;
readonly depotServerClient: DepotServerClient;
readonly graphManagerState: GraphManagerState;
+ readonly layout = new LayoutManagerState();
readonly startTime = Date.now();
readonly initState = ActionState.create();
@@ -75,12 +77,14 @@ export class LegendDataCubeBaseStore {
async initialize() {
this.initState.inProgress();
+
try {
this.application.identityService.setCurrentUser(
await getCurrentUserIDFromEngineServer(
this.application.config.engineServerUrl,
),
);
+ this.application.telemetryService.setup();
} catch (error) {
assertErrorThrown(error);
this.application.logService.error(
diff --git a/packages/legend-application-data-cube/src/stores/LegendDataCubeDataCubeEngine.ts b/packages/legend-application-data-cube/src/stores/LegendDataCubeDataCubeEngine.ts
index c6c52e87e7..fd093e8795 100644
--- a/packages/legend-application-data-cube/src/stores/LegendDataCubeDataCubeEngine.ts
+++ b/packages/legend-application-data-cube/src/stores/LegendDataCubeDataCubeEngine.ts
@@ -15,9 +15,6 @@
*/
import {
- SUPPORTED_FUNCTIONS,
- V1_AppliedFunction,
- V1_Lambda,
RawLambda,
RelationalExecutionActivities,
TDSExecutionResult,
@@ -25,32 +22,28 @@ import {
V1_deserializeValueSpecification,
V1_RawLambda,
V1_serializeValueSpecification,
+ type V1_Lambda,
type GraphManagerState,
type PureModel,
type V1_ValueSpecification,
- type ParameterValue,
- BasicGraphManagerState,
- AbstractPureGraphManager,
+ type AbstractPureGraphManager,
} from '@finos/legend-graph';
import {
_elementPtr,
- _functionName,
DataCubeEngine,
DataCubeSource,
- type RelationType,
- DataCubeQuery,
+ type DataCubeRelationType,
type CompletionItem,
_function,
DataCubeFunction,
} from '@finos/legend-data-cube';
import {
- DocumentationEntry,
guaranteeType,
isNonNullable,
LogEvent,
- LogService,
UnsupportedOperationError,
type PlainObject,
+ type DocumentationEntry,
} from '@finos/legend-shared';
import type { LegendDataCubeApplicationStore } from './LegendDataCubeBaseStore.js';
import {
@@ -152,6 +145,44 @@ export class LegendDataCubeDataCubeEngine extends DataCubeEngine {
// return query;
// }
+ // async buildCubeEngine(): Promise {
+ // this.buildCubeEngineState.inProgress();
+ // const queryInfo = await this.context.graphManager.graphManager.getQueryInfo(
+ // guaranteeNonNullable(this.query).id,
+ // );
+ // const execConext =
+ // (await this.context.graphManager.graphManager.resolveQueryInfoExecutionContext(
+ // queryInfo,
+ // () =>
+ // this.context.depotServerClient.getVersionEntities(
+ // queryInfo.groupId,
+ // queryInfo.artifactId,
+ // queryInfo.versionId,
+ // ),
+ // )) as { mapping: string | undefined; runtime: string };
+ // const lambda =
+ // (await this.context.graphManager.graphManager.pureCodeToLambda(
+ // queryInfo.content,
+ // )) as unknown as RawLambda;
+ // this.context.graphManager.graph.setOrigin(
+ // new LegendSDLC(
+ // queryInfo.groupId,
+ // queryInfo.artifactId,
+ // resolveVersion(queryInfo.versionId),
+ // ),
+ // );
+ // // TODO: we should be able to call engine and convert lambda to relation if not one.
+ // const engine = new LegendDataCubeDataCubeEngine(
+ // lambda,
+ // undefined,
+ // execConext.mapping,
+ // execConext.runtime,
+ // this.context.graphManager,
+ // );
+ // this.buildCubeEngineState.complete();
+ // return engine;
+ // }
+
private buildRawLambdaFromValueSpec(query: V1_Lambda): RawLambda {
const json = guaranteeType(
V1_deserializeRawValueSpecification(
@@ -162,7 +193,9 @@ export class LegendDataCubeDataCubeEngine extends DataCubeEngine {
return new RawLambda(json.parameters, json.body);
}
- private async getRelationalType(query: RawLambda): Promise {
+ private async getRelationalType(
+ query: RawLambda,
+ ): Promise {
const relationType = await this.graphManager.getLambdaRelationType(
query,
this.graph,
diff --git a/packages/legend-application-data-cube/src/stores/LegendDataCubeLandingPageStore.ts b/packages/legend-application-data-cube/src/stores/LegendDataCubeLandingPageStore.ts
index 06fd15b830..88f644d71c 100644
--- a/packages/legend-application-data-cube/src/stores/LegendDataCubeLandingPageStore.ts
+++ b/packages/legend-application-data-cube/src/stores/LegendDataCubeLandingPageStore.ts
@@ -20,11 +20,13 @@ import type {
LegendDataCubeBaseStore,
} from './LegendDataCubeBaseStore.js';
import { type DataCubeQuery } from '@finos/legend-data-cube';
+import { LegendDataCubeNewQueryState } from './LegendDataCubeNewQueryState.js';
export class LegendDataCubeLandingPageStore {
readonly application: LegendDataCubeApplicationStore;
readonly baseStore: LegendDataCubeBaseStore;
+ readonly newQueryState: LegendDataCubeNewQueryState;
query?: DataCubeQuery | undefined;
constructor(baseStore: LegendDataCubeBaseStore) {
@@ -35,6 +37,7 @@ export class LegendDataCubeLandingPageStore {
this.application = baseStore.application;
this.baseStore = baseStore;
+ this.newQueryState = new LegendDataCubeNewQueryState(baseStore);
}
setQuery(val: DataCubeQuery | undefined): void {
diff --git a/packages/legend-application-data-cube/src/stores/LegendDataCubeNewQueryState.tsx b/packages/legend-application-data-cube/src/stores/LegendDataCubeNewQueryState.tsx
new file mode 100644
index 0000000000..bda4d61938
--- /dev/null
+++ b/packages/legend-application-data-cube/src/stores/LegendDataCubeNewQueryState.tsx
@@ -0,0 +1,117 @@
+/**
+ * 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, makeObservable, observable } from 'mobx';
+import {
+ IllegalStateError,
+ UnsupportedOperationError,
+} from '@finos/legend-shared';
+import { LegendQueryDataCubeSourceBuilderState } from './source/LegendQueryDataCubeSourceBuilderState.js';
+import type {
+ LegendDataCubeApplicationStore,
+ LegendDataCubeBaseStore,
+} from './LegendDataCubeBaseStore.js';
+import type { GraphManagerState } from '@finos/legend-graph';
+import {
+ LegendDataCubeSourceBuilderType,
+ type LegendDataCubeSourceBuilderState,
+} from './source/LegendDataCubeSourceBuilderState.js';
+import { DataCubeQuery, type DisplayState } from '@finos/legend-data-cube';
+import type { LegendDataCubeDataCubeEngine } from './LegendDataCubeDataCubeEngine.js';
+import { LegendDataCubeNewQueryBuilder } from '../components/LegendDataCubeNewQueryBuilder.js';
+
+export class LegendDataCubeNewQueryState {
+ readonly application: LegendDataCubeApplicationStore;
+ readonly baseStore: LegendDataCubeBaseStore;
+ readonly graphManagerState: GraphManagerState;
+ readonly engine: LegendDataCubeDataCubeEngine;
+ readonly display: DisplayState;
+
+ sourceBuilder: LegendDataCubeSourceBuilderState;
+
+ constructor(baseStore: LegendDataCubeBaseStore) {
+ makeObservable(this, {
+ sourceBuilder: observable,
+ currentSourceBuilderOption: computed,
+ changeSourceBuilder: action,
+ });
+
+ this.application = baseStore.application;
+ this.baseStore = baseStore;
+ this.graphManagerState = baseStore.graphManagerState;
+ this.engine = baseStore.engine;
+ this.display = this.engine.layout.newDisplay('New Query', () => (
+
+ ));
+
+ this.sourceBuilder = this.createSourceBuilder(
+ LegendDataCubeSourceBuilderType.LEGEND_QUERY,
+ );
+ }
+
+ get sourceBuilderOptions(): LegendDataCubeSourceBuilderType[] {
+ return Object.values(LegendDataCubeSourceBuilderType);
+ }
+
+ get currentSourceBuilderOption(): LegendDataCubeSourceBuilderType {
+ return this.sourceBuilder.label;
+ }
+
+ changeSourceBuilder(type: LegendDataCubeSourceBuilderType): void {
+ if (this.sourceBuilder.label !== type) {
+ switch (type) {
+ case LegendDataCubeSourceBuilderType.LEGEND_QUERY: {
+ this.sourceBuilder = new LegendQueryDataCubeSourceBuilderState(
+ this.baseStore,
+ );
+ break;
+ }
+ default:
+ throw new UnsupportedOperationError(
+ `Can't change source to unsupported type '${type}'`,
+ );
+ }
+ this.sourceBuilder = this.createSourceBuilder(type);
+ }
+ }
+
+ private createSourceBuilder(
+ type: LegendDataCubeSourceBuilderType,
+ ): LegendDataCubeSourceBuilderState {
+ switch (type) {
+ case LegendDataCubeSourceBuilderType.LEGEND_QUERY:
+ return new LegendQueryDataCubeSourceBuilderState(this.baseStore);
+ default:
+ throw new UnsupportedOperationError(
+ `Can't build source state for unsupported type '${type}'`,
+ );
+ }
+ }
+
+ async generateQuery(): Promise {
+ if (!this.sourceBuilder.isValid) {
+ throw new IllegalStateError(`Can't generate query: source is not valid`);
+ }
+
+ const source = await this.sourceBuilder.build();
+ const query = new DataCubeQuery();
+ const processedSource = await this.engine.processQuerySource(source);
+ query.source = source;
+ query.query = `~[${processedSource.columns.map((column) => `'${column.name}'`)}]->select()`;
+
+ return query;
+ }
+}
diff --git a/packages/legend-application-data-cube/src/stores/model/LegendQueryDataCubeSource.ts b/packages/legend-application-data-cube/src/stores/model/LegendQueryDataCubeSource.ts
index f6ba8edc89..5c46e5db60 100644
--- a/packages/legend-application-data-cube/src/stores/model/LegendQueryDataCubeSource.ts
+++ b/packages/legend-application-data-cube/src/stores/model/LegendQueryDataCubeSource.ts
@@ -15,16 +15,22 @@
*/
import { DataCubeSource } from '@finos/legend-data-cube';
+import type { Query, RawLambda } from '@finos/legend-graph';
import {
SerializationFactory,
usingConstantValueSchema,
+ type PlainObject,
} from '@finos/legend-shared';
import { createModelSchema, primitive } from 'serializr';
export const LEGEND_QUERY_DATA_CUBE_SOURCE_TYPE = 'legendQuery';
export class LegendQueryDataCubeSource extends DataCubeSource {
- queryId!: string;
+ savedQuery!: Query;
+ lambda!: RawLambda;
+ mappingPath!: string;
+ runtimePath!: string;
+ model!: PlainObject;
}
export class RawLegendQueryDataCubeSource {
diff --git a/packages/legend-application-data-cube/src/stores/source/CubeInputSource.ts b/packages/legend-application-data-cube/src/stores/source/CubeInputSource.ts
deleted file mode 100644
index 8a0e572183..0000000000
--- a/packages/legend-application-data-cube/src/stores/source/CubeInputSource.ts
+++ /dev/null
@@ -1,36 +0,0 @@
-/**
- * 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 type { VersionedProjectData } from '@finos/legend-server-depot';
-
-export abstract class LegendDepotSavedSource {
- project!: VersionedProjectData;
-}
-
-export class LegendDepotService extends LegendDepotSavedSource {
- service!: string;
-}
-
-export class LegendDepotFunction extends LegendDepotSavedSource {
- _function!: string;
-}
-
-export class LegendDepotTable extends LegendDepotSavedSource {
- database!: string;
- schema!: string;
- table!: string;
- runtime!: string;
-}
diff --git a/packages/legend-application-data-cube/src/stores/source/CubeInputSourceLoader.ts b/packages/legend-application-data-cube/src/stores/source/CubeInputSourceLoader.ts
deleted file mode 100644
index 75ad9ae33e..0000000000
--- a/packages/legend-application-data-cube/src/stores/source/CubeInputSourceLoader.ts
+++ /dev/null
@@ -1,57 +0,0 @@
-/**
- * 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 { ActionState, UnsupportedOperationError } from '@finos/legend-shared';
-import type { DataCubeEngine } from '@finos/legend-data-cube';
-// import type { DataCubeGenericSource } from '../model/DataCubeGenericSource.js';
-
-export enum DataCubeSourceType {
- LEGEND_QUERY = 'Legend Query',
- REPL_QUERY = 'Repl Query',
-}
-
-export abstract class LegendDataCubeInputSourceState {
- buildCubeEngineState = ActionState.create();
-
- setupActionState = ActionState.create();
-
- // readonly context: LegendDataCubeStoreContext;
-
- // constructor(context: LegendDataCubeStoreContext) {
- // this.context = context;
- // }
- abstract get label(): DataCubeSourceType;
-
- async setup(): Promise {
- this.setupActionState.complete();
- }
-
- abstract buildCubeEngine(): Promise;
-
- // abstract process(): DataCubeGenericSource;
-
- abstract get isValid(): boolean;
-
- get openActionable(): boolean {
- return true;
- }
-
- // static builder(
- // context: LegendDataCubeStoreContext,
- // ): LegendDataCubeInputSourceState {
- // throw new UnsupportedOperationError('No builder');
- // }
-}
diff --git a/packages/legend-application-data-cube/src/stores/source/LegendDataCubeSourceBuilder.ts b/packages/legend-application-data-cube/src/stores/source/LegendDataCubeSourceBuilder.ts
deleted file mode 100644
index dfca2b9fb9..0000000000
--- a/packages/legend-application-data-cube/src/stores/source/LegendDataCubeSourceBuilder.ts
+++ /dev/null
@@ -1,94 +0,0 @@
-/**
- * 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 { flow, makeObservable, observable } from 'mobx';
-import {
- DataCubeSourceType,
- type LegendDataCubeInputSourceState,
-} from './CubeInputSourceLoader.js';
-import {
- UnsupportedOperationError,
- assertErrorThrown,
- assertTrue,
- guaranteeNonNullable,
- type GeneratorFn,
-} from '@finos/legend-shared';
-import type { DataCubeEngine } from '@finos/legend-data-cube';
-
-export class LegendDataCubeSourceBuilder {
- open = false;
- sourceState: LegendDataCubeInputSourceState;
-
- constructor() {
- makeObservable(this, {
- open: observable,
- sourceState: observable,
-
- // inputSource: flow,
- });
- this.sourceState = this.buildSource(guaranteeNonNullable(this.options[0]));
- }
-
- get options(): DataCubeSourceType[] {
- return Object.values(DataCubeSourceType);
- }
-
- get currentOption(): DataCubeSourceType {
- throw new UnsupportedOperationError('');
- }
-
- openModal(): void {
- this.open = true;
- }
-
- close(): void {
- this.open = false;
- }
-
- changeSource(source: DataCubeSourceType): void {
- if (this.sourceState.label !== source) {
- this.sourceState = this.buildSource(source);
- }
- }
-
- buildSource(source: DataCubeSourceType): LegendDataCubeInputSourceState {
- // if (source === DataCubeSourceType.LEGEND_QUERY) {
- // return SavedQueryInputSourceState.builder(this.context);
- // }
- throw new UnsupportedOperationError('Not supported');
- }
-
- // *inputSource(
- // callback: (source: DataCubeGenericSource, engine: DataCubeEngine) => void,
- // ): GeneratorFn {
- // try {
- // assertTrue(
- // this.sourceState.isValid,
- // 'Source State is in a valid state to input',
- // );
- // const engine =
- // (yield this.sourceState.buildCubeEngine()) as DataCubeEngine;
- // const source = this.sourceState.process();
- // callback(source, engine);
- // this.close();
- // } catch (error) {
- // assertErrorThrown(error);
- // // this.context.application.notificationService.notifyError(
- // // `Unable to import: ${this.sourceState.label}: ${error.message}`,
- // // );
- // }
- // }
-}
diff --git a/packages/legend-application-data-cube/src/stores/source/LegendDataCubeSourceBuilderState.ts b/packages/legend-application-data-cube/src/stores/source/LegendDataCubeSourceBuilderState.ts
new file mode 100644
index 0000000000..06b425df66
--- /dev/null
+++ b/packages/legend-application-data-cube/src/stores/source/LegendDataCubeSourceBuilderState.ts
@@ -0,0 +1,45 @@
+/**
+ * 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 { ActionState, type PlainObject } from '@finos/legend-shared';
+import type {
+ LegendDataCubeApplicationStore,
+ LegendDataCubeBaseStore,
+} from '../LegendDataCubeBaseStore.js';
+import type { GraphManagerState } from '@finos/legend-graph';
+
+export enum LegendDataCubeSourceBuilderType {
+ LEGEND_QUERY = 'Legend Query',
+ ADHOC_QUERY = 'Ad hoc Query',
+}
+
+export abstract class LegendDataCubeSourceBuilderState {
+ readonly application: LegendDataCubeApplicationStore;
+ readonly baseStore: LegendDataCubeBaseStore;
+ readonly graphManagerState: GraphManagerState;
+
+ readonly buildState = ActionState.create();
+
+ constructor(baseStore: LegendDataCubeBaseStore) {
+ this.application = baseStore.application;
+ this.baseStore = baseStore;
+ this.graphManagerState = baseStore.graphManagerState;
+ }
+
+ abstract get label(): LegendDataCubeSourceBuilderType;
+ abstract get isValid(): boolean;
+ abstract build(): Promise;
+}
diff --git a/packages/legend-application-data-cube/src/stores/source/LegendQueryDataCubeSourceBuilderState.ts b/packages/legend-application-data-cube/src/stores/source/LegendQueryDataCubeSourceBuilderState.ts
new file mode 100644
index 0000000000..32192fe538
--- /dev/null
+++ b/packages/legend-application-data-cube/src/stores/source/LegendQueryDataCubeSourceBuilderState.ts
@@ -0,0 +1,84 @@
+/**
+ * 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 { IllegalStateError, isNonNullable } from '@finos/legend-shared';
+import { QuerySearchSpecification, type LightQuery } from '@finos/legend-graph';
+import {
+ QUERY_LOADER_TYPEAHEAD_SEARCH_LIMIT,
+ QueryLoaderState,
+} from '@finos/legend-query-builder';
+import { action, makeObservable, observable } from 'mobx';
+import {
+ LegendDataCubeSourceBuilderState,
+ LegendDataCubeSourceBuilderType,
+} from './LegendDataCubeSourceBuilderState.js';
+import type { LegendDataCubeBaseStore } from '../LegendDataCubeBaseStore.js';
+import { RawLegendQueryDataCubeSource } from '../model/LegendQueryDataCubeSource.js';
+
+export class LegendQueryDataCubeSourceBuilderState extends LegendDataCubeSourceBuilderState {
+ readonly queryLoaderState: QueryLoaderState;
+
+ query?: LightQuery | undefined;
+
+ constructor(baseStore: LegendDataCubeBaseStore) {
+ super(baseStore);
+
+ makeObservable(this, {
+ query: observable,
+ setQuery: action,
+ });
+
+ this.queryLoaderState = new QueryLoaderState(
+ this.application,
+ this.graphManagerState,
+ {
+ loadQuery: (query: LightQuery): void => {
+ this.setQuery(query);
+ },
+ decorateSearchSpecification: (val) => val,
+ fetchDefaultQueries: async (): Promise => {
+ const searchSpecification = new QuerySearchSpecification();
+ searchSpecification.limit = QUERY_LOADER_TYPEAHEAD_SEARCH_LIMIT;
+ return this.graphManagerState.graphManager.searchQueries(
+ QuerySearchSpecification.createDefault(undefined),
+ );
+ },
+ isReadOnly: true,
+ },
+ );
+ }
+
+ setQuery(query: LightQuery): void {
+ this.query = query;
+ }
+
+ override get label(): LegendDataCubeSourceBuilderType {
+ return LegendDataCubeSourceBuilderType.LEGEND_QUERY;
+ }
+
+ override get isValid(): boolean {
+ return isNonNullable(this.query);
+ }
+
+ override async build() {
+ if (!this.query) {
+ throw new IllegalStateError('Query is missing');
+ }
+ const source = new RawLegendQueryDataCubeSource();
+ source.queryId = this.query.id;
+ return RawLegendQueryDataCubeSource.serialization.toJson(source);
+ }
+}
diff --git a/packages/legend-application-data-cube/src/stores/source/SavedQueryInputSourceState.ts b/packages/legend-application-data-cube/src/stores/source/SavedQueryInputSourceState.ts
deleted file mode 100644
index e542707974..0000000000
--- a/packages/legend-application-data-cube/src/stores/source/SavedQueryInputSourceState.ts
+++ /dev/null
@@ -1,142 +0,0 @@
-/**
- * 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 {
- assertTrue,
- guaranteeNonNullable,
- isNonNullable,
-} from '@finos/legend-shared';
-import {
- LegendDataCubeInputSourceState,
- DataCubeSourceType,
-} from './CubeInputSourceLoader.js';
-import type { DataCubeEngine } from '@finos/legend-data-cube';
-import {
- LegendSDLC,
- QuerySearchSpecification,
- type RawLambda,
- type LightQuery,
-} from '@finos/legend-graph';
-import { resolveVersion } from '@finos/legend-server-depot';
-import { LegendDataCubeDataCubeEngine } from '../LegendDataCubeDataCubeEngine.js';
-import {
- QUERY_LOADER_TYPEAHEAD_SEARCH_LIMIT,
- QueryLoaderState,
-} from '@finos/legend-query-builder';
-import { action, makeObservable, observable } from 'mobx';
-
-export class SavedQueryInputSourceState extends LegendDataCubeInputSourceState {
- query: LightQuery | undefined;
- // queryLoaderState: QueryLoaderState;
-
- constructor() {
- super();
- makeObservable(this, {
- query: observable,
- buildCubeEngineState: observable,
- setQuery: action,
- });
- // this.queryLoaderState = new QueryLoaderState(
- // this.context.application,
- // this.context.graphManager,
- // {
- // loadQuery: (query: LightQuery): void => {
- // this.setQuery(query);
- // },
- // decorateSearchSpecification: (val) => val,
- // fetchDefaultQueries: async (): Promise => {
- // const searchSpecification = new QuerySearchSpecification();
- // searchSpecification.limit = QUERY_LOADER_TYPEAHEAD_SEARCH_LIMIT;
- // return this.context.graphManager.graphManager.searchQueries(
- // QuerySearchSpecification.createDefault(undefined),
- // );
- // },
- // isReadOnly: true,
- // },
- // );
- }
-
- setQuery(query: LightQuery): void {
- this.query = query;
- }
-
- // override process(): DataCubeGenericSource {
- // assertTrue(this.isValid);
- // return new LegendQueryDataCubeSource(guaranteeNonNullable(this.query).id);
- // }
-
- override get openActionable(): boolean {
- return false;
- }
-
- // static override builder(
- // context: LegendDataCubeStoreContext,
- // ): LegendDataCubeInputSourceState {
- // return new SavedQueryInputSourceState(context);
- // }
- override get label(): DataCubeSourceType {
- return DataCubeSourceType.LEGEND_QUERY;
- }
- override setup(): Promise {
- throw new Error('Method not implemented.');
- }
-
- override buildCubeEngine(): Promise {
- throw new Error('Method not implemented.');
- }
-
- // async buildCubeEngine(): Promise {
- // this.buildCubeEngineState.inProgress();
- // const queryInfo = await this.context.graphManager.graphManager.getQueryInfo(
- // guaranteeNonNullable(this.query).id,
- // );
- // const execConext =
- // (await this.context.graphManager.graphManager.resolveQueryInfoExecutionContext(
- // queryInfo,
- // () =>
- // this.context.depotServerClient.getVersionEntities(
- // queryInfo.groupId,
- // queryInfo.artifactId,
- // queryInfo.versionId,
- // ),
- // )) as { mapping: string | undefined; runtime: string };
- // const lambda =
- // (await this.context.graphManager.graphManager.pureCodeToLambda(
- // queryInfo.content,
- // )) as unknown as RawLambda;
- // this.context.graphManager.graph.setOrigin(
- // new LegendSDLC(
- // queryInfo.groupId,
- // queryInfo.artifactId,
- // resolveVersion(queryInfo.versionId),
- // ),
- // );
- // // TODO: we should be able to call engine and convert lambda to relation if not one.
- // const engine = new LegendDataCubeDataCubeEngine(
- // lambda,
- // undefined,
- // execConext.mapping,
- // execConext.runtime,
- // this.context.graphManager,
- // );
- // this.buildCubeEngineState.complete();
- // return engine;
- // }
-
- override get isValid(): boolean {
- return isNonNullable(this.query);
- }
-}
diff --git a/packages/legend-application-data-cube/style/_query-loader.scss b/packages/legend-application-data-cube/style/_query-loader.scss
new file mode 100644
index 0000000000..34473c2f9f
--- /dev/null
+++ b/packages/legend-application-data-cube/style/_query-loader.scss
@@ -0,0 +1,351 @@
+/**
+ * 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.
+ */
+
+@use 'mixins' as *;
+
+.query-loader {
+ height: 100%;
+
+ &__header {
+ padding: 1rem;
+ height: 9.2rem;
+ border-bottom: 0.1rem solid var(--color-dark-grey-200);
+ }
+
+ &__filter {
+ height: 2.8rem;
+ margin-top: 1rem;
+
+ &__toggler {
+ @include flexVCenter;
+ }
+
+ &__extra__filters {
+ display: flex;
+ margin-left: 0.5rem;
+ }
+
+ &__toggler__btn {
+ @include flexCenter;
+
+ height: 2.8rem;
+ align-self: flex-start;
+ border-radius: 0.2rem;
+ padding: 0 0.5rem;
+ font-size: 1.2rem;
+ border: 0.1rem solid var(--color-dark-grey-200);
+ color: var(--color-light-grey-400);
+ line-height: 2rem;
+ cursor: pointer;
+
+ & + & {
+ margin-left: 0.5rem;
+ }
+
+ &:hover {
+ border-color: var(--color-dark-grey-250);
+ background: var(--color-dark-grey-100);
+ }
+
+ &--toggled:hover,
+ &--toggled {
+ border-color: var(--color-blue-200);
+ color: var(--color-light-grey-50);
+ }
+ }
+ }
+
+ &__search {
+ @include flexCenter;
+
+ position: relative;
+
+ &__input {
+ height: 3.4rem;
+ padding-right: 2.8rem;
+ padding-left: 1rem;
+ width: 100%;
+ background: var(--color-dark-grey-85);
+ border-radius: 0.2rem;
+ border: 0.1rem solid var(--color-dark-grey-200);
+
+ &__container {
+ @include flexCenter;
+
+ position: relative;
+ height: 3.4rem;
+ width: 100%;
+ }
+
+ &--searching {
+ padding-right: 5.6rem;
+ }
+
+ &__search__icon {
+ @include flexCenter;
+
+ position: absolute;
+ right: 0.2rem;
+ height: 2.8rem;
+ width: 2.8rem;
+
+ svg {
+ color: var(--color-light-shade-100);
+ }
+ }
+
+ &__clear-btn {
+ @include flexCenter;
+
+ position: absolute;
+ right: 0.2rem;
+ height: 2.8rem;
+ width: 2.8rem;
+
+ svg {
+ color: var(--color-dark-grey-400);
+ }
+
+ &:hover svg {
+ color: var(--color-dark-grey-500);
+ }
+ }
+ }
+ }
+
+ &__content {
+ height: calc(100% - 9.2rem);
+ position: relative;
+ }
+
+ &__results {
+ padding: 0.5rem;
+ height: 100%;
+ overflow-y: overlay;
+
+ &__summary {
+ @include flexVCenter;
+
+ justify-content: space-between;
+ font-size: 1.2rem;
+ height: 2.5rem;
+ margin-bottom: 0.5rem;
+ color: var(--color-dark-grey-400);
+ padding: 0 0.5rem;
+ user-select: none;
+ }
+
+ &__summary__info {
+ font-size: 1.2rem;
+ margin-left: 0.5rem;
+ }
+
+ &__sort-by {
+ @include flexVCenter;
+
+ height: 2rem;
+
+ &__name {
+ font-size: 1.2rem;
+ font-weight: 500;
+ color: var(--color-dark-grey-400);
+ }
+
+ &__selector {
+ width: 11rem;
+ margin-left: 0.5rem;
+ }
+ }
+ }
+
+ &__result {
+ display: flex;
+ width: 100%;
+ height: 5.4rem;
+ padding: 0.5rem 0;
+ border-radius: 0.2rem;
+ cursor: pointer;
+ border: 0.1rem solid var(--color-dark-grey-200);
+ background: var(--color-dark-grey-100);
+
+ &:hover {
+ background: var(--color-dark-grey-200);
+ }
+
+ & + & {
+ margin-top: 0.5rem;
+ }
+ }
+
+ &__result__content {
+ width: calc(100% - 5rem);
+ text-align: start;
+ }
+
+ &__result__title {
+ @include ellipsisTextOverflow;
+
+ height: 2.2rem;
+ line-height: 2.2rem;
+ width: 80%;
+ padding: 0 1rem;
+ color: var(--color-light-grey-300);
+ font-weight: 500;
+ }
+
+ &__result__title__editor {
+ display: flex;
+ padding: 0 1rem;
+
+ &__input {
+ width: 80%;
+ padding: 0.5rem;
+ height: 2.2rem;
+ }
+
+ &__actions {
+ display: flex;
+ margin-left: 0.5rem;
+ }
+
+ &__save-btn,
+ &__cancel-btn {
+ font-size: 1.2rem;
+ height: 2.2rem;
+
+ &[disabled] {
+ cursor: not-allowed;
+ }
+ }
+
+ &__cancel-btn {
+ background: var(--color-dark-grey-100);
+ border: 0.1rem solid var(--color-dark-grey-300);
+
+ &:hover {
+ background: var(--color-dark-grey-250);
+ }
+ }
+ }
+
+ &__result__description {
+ @include flexVCenter;
+
+ padding: 0 1rem;
+ height: 2.2rem;
+ color: var(--color-dark-grey-500);
+
+ &__date__icon svg {
+ display: flex;
+ font-size: 1.2rem;
+ }
+
+ &__date {
+ margin-right: 1rem;
+ font-size: 1.1rem;
+ min-width: 10.5rem;
+ margin-left: 0.5rem;
+ }
+
+ &__author__icon {
+ display: flex;
+
+ svg {
+ font-size: 1rem;
+ }
+ }
+
+ &__author__name {
+ margin-left: 0.5rem;
+ color: var(--color-light-grey-500);
+ font-size: 1.1rem;
+ }
+
+ &__owner {
+ @include flexCenter;
+
+ padding: 0 0.5rem;
+ height: 1.4rem;
+ font-size: 1rem;
+ font-weight: 500;
+ color: var(--color-light-grey-50);
+ border-radius: 0.2rem;
+ background: var(--color-blue-50);
+ }
+ }
+
+ &__result__actions-menu {
+ @include flexCenter;
+
+ height: 100%;
+ width: 2.5rem;
+ cursor: pointer;
+ color: var(--color-dark-grey-300);
+
+ svg {
+ font-size: 1.6rem;
+ }
+
+ &:hover svg {
+ color: var(--color-dark-grey-400);
+ }
+ }
+
+ &__result__arrow {
+ @include flexCenter;
+
+ height: 100%;
+ width: 2.5rem;
+ color: var(--color-dark-grey-280);
+ }
+
+ &__dialog {
+ margin: 2vh 0;
+
+ &__container {
+ @include flexCenter;
+
+ height: 100%;
+ width: 100%;
+ }
+
+ &__body {
+ height: 100%;
+ width: 60rem;
+ }
+
+ &__body__content {
+ height: 100%;
+ overflow: hidden;
+ }
+
+ &__header {
+ @include flexVCenter;
+
+ justify-content: space-between;
+ height: 3.4rem;
+ padding: 0 1rem;
+ }
+
+ &__header__close-btn {
+ color: var(--color-light-grey-300);
+ }
+
+ &__content {
+ height: calc(100% - 3.4rem);
+ }
+ }
+}
diff --git a/packages/legend-application-data-cube/style/index.scss b/packages/legend-application-data-cube/style/index.scss
index ba2e9f1625..6bbcb9d1f9 100644
--- a/packages/legend-application-data-cube/style/index.scss
+++ b/packages/legend-application-data-cube/style/index.scss
@@ -15,8 +15,178 @@
*/
@forward 'query-editor';
+@forward 'query-loader';
@forward 'query-editor-light';
+:root {
+ --color-white: #fff;
+ --color-light-grey-0: #fafafa;
+ --color-light-grey-50: #f3f3f3;
+ --color-light-grey-100: #efefef;
+ --color-light-grey-150: #e6e6e6;
+ --color-light-grey-180: #dcdcdc;
+ --color-light-grey-200: #ddd;
+ --color-light-grey-250: #d4d4d4; // vscode
+ --color-light-grey-300: #cecece;
+ --color-light-grey-400: #bbb;
+ --color-black: #000;
+ --color-dark-grey-50: #1e1e1e; // vscode
+ --color-dark-grey-80: #252525;
+ --color-dark-grey-85: #272727;
+ --color-dark-grey-100: #2d2d2d;
+ --color-dark-grey-200: #353535;
+ --color-dark-grey-250: #3e3e3e;
+ --color-dark-grey-280: #404040; // vscode
+ --color-dark-grey-300: #595959;
+ --color-dark-grey-350: #606060; // vscode
+ --color-dark-grey-400: #737373;
+ --color-dark-grey-500: #9a9a9a;
+ --color-navy-300: #45456b;
+ --color-navy-500: #34345f;
+ --color-navy-600: #c2c2e3;
+ --color-purple-0: #d3bee0;
+ --color-purple-50: #af90c3;
+ --color-purple-100: #8a58ab;
+ --color-purple-200: #804090;
+ --color-purple-400: #5d3b73;
+ --color-magenta-30: #c585c0; // vscode
+ --color-magenta-50: #d06c99;
+ --color-magenta-70: #f152b1;
+ --color-magenta-100: #bb619b;
+ --color-magenta-300: #8c4268;
+ --color-pink-0: #ffc0cb;
+ --color-pink-100: #ffa7c4;
+ --color-pink-200: #f05577;
+ --color-pink-300: #d14664;
+ --color-pink-380: #c5375f;
+ --color-pink-400: #b33659;
+ --color-pink-500: #af2a5b;
+ --color-red-50: #ff958c;
+ --color-red-100: #f5584b;
+ --color-red-150: #f95252;
+ --color-red-180: #ea4646; // vscode
+ --color-red-200: #bf2f22;
+ --color-red-300: #be1100;
+ --color-red-400: #800404;
+ --color-red-500: #5a1d1d;
+ --color-carmine-200: #af3e34;
+ --color-skin-100: #f1b47f;
+ --color-skin-200: #ce9178; // vscode
+ --color-orange-50: #f90;
+ --color-orange-100: #e97f49;
+ --color-orange-150: #ca663a;
+ --color-orange-200: #c95f03;
+ --color-orange-250: #bb5803;
+ --color-orange-400: #8a4628;
+ --color-orange-500: #6c3f2b;
+ --color-yellow-0: #ffffe0;
+ --color-yellow-50: #dcdcaa; // vscode
+ --color-yellow-80: #d7ba7d; // vscode
+ --color-yellow-100: #ffca34;
+ --color-yellow-200: #fbbc05;
+ --color-yellow-300: #e2a700;
+ --color-yellow-400: #dc9d2a;
+ --color-yellow-500: #c58105;
+ --color-dark-yellow-500: #342a18;
+ --color-green-80: #65d081;
+ --color-green-100: #34a853;
+ --color-green-200: #1e8a53;
+ --color-lime-50: #a5ea81;
+ --color-lime-75: #aad468;
+ --color-lime-150: #6a9955; // vscode
+ --color-green-neon-100: #2cca72;
+ --color-medium-green-0: #7bffc8;
+ --color-medium-green-100: #39cca2;
+ --color-medium-green-150: #40c8ae; // vscode
+ --color-medium-green-180: #4ec9b0; // vscode
+ --color-medium-green-450: #139077;
+ --color-medium-green-500: #11846d;
+ --color-teal-50: #16b8bf;
+ --color-light-blue-0: #deebff;
+ --color-light-blue-10: #9cddfe; // vscode
+ --color-light-blue-20: #7fdbff;
+ --color-light-blue-50: #6391d0;
+ --color-light-blue-200: #477cc5;
+ --color-light-blue-400: #2c4f80;
+ --color-light-blue-450: #264f77; // vscode
+ --color-blue-40: #40a6ff; // vscode
+ --color-blue-50: #1c89d2;
+ --color-blue-100: #007acc;
+ --color-blue-150: #0a73b9;
+ --color-blue-180: #0c6bab;
+ --color-blue-200: #08629e;
+ --color-blue-300: #014a7b;
+ --color-blue-500: #002f4f;
+ --color-light-shade-50: #ffffff12;
+ --color-light-shade-100: #ffffff2e;
+ --color-light-shade-150: #fff3;
+ --color-dark-shade-0: #00000008;
+ --color-dark-shade-50: #00000014;
+ --color-dark-shade-100: #0000002e;
+ --color-dark-shade-200: #00000030;
+ --color-dark-shade-230: #0000003d;
+ --color-dark-shade-250: #00000045;
+ --color-dark-shade-280: #0000004f;
+ --color-dark-shade-300: #00000061;
+ --color-dark-shade-800: #000000a6;
+ --color-dark-shade-900: #000000c4;
+ --color-dark-blue-shade-100: #7f7ab124;
+ --color-dark-red-shade-50: #ff00000d;
+ --color-dark-red-shade-100: #ff00001a;
+
+ // misc
+ --color-eminence: #68217a; // vscode
+ --color-mauve: #7685b9;
+ --color-mauve-50: #7695ff;
+ --color-purple-TEMP: #bfbcff;
+ --color-orange-TEMP: #ffeed3;
+ --color-navy-TEMP: #3f51b5;
+ --color-yellow-TEMP: #f4b400;
+ --color-yellow-TEMP-2: #c19033;
+ --color-medium-green-TEMP-2: #43849c;
+ --color-dnd__overlay: #63636394;
+ --color-dnd__overlay-light: #d5d5d594;
+ --color-app-header: var(--color-navy-500);
+ --color-panel-border: var(--color-light-grey-100);
+ --color-text-label: var(--color-light-grey-100);
+ --color-required-label: var(--color-yellow-200);
+ --color-input: var(--color-white);
+ --color-input-border: var(--color-light-grey-200);
+ --color-input-border--hover: var(--color-light-grey-400);
+ --color-input-border--focus: var(--color-light-blue-200);
+ --color-input-border--dark: var(--color-dark-grey-100);
+ --color-test: var(--color-pink-200);
+ --color-test--passed: var(--color-green-100);
+ --color-test--failed: var(--color-orange-100);
+ --color-test--error: var(--color-red-100);
+ --color-test--skipped: var(--color-dark-grey-400);
+ --color-conflict: var(--color-orange-150);
+ --color-merge--current: var(--color-medium-green-150);
+ --color-merge--base: var(--color-dark-grey-350);
+ --color-merge--incoming: var(--color-blue-40);
+ --color-warning: var(--color-yellow-100);
+ // font
+ --font-entity-label: 'Roboto Condensed';
+ --color-legacylight-light-grey-100: #edf0f1;
+ --color-legacylight-light-grey-200: #dce2e4;
+ --color-legacylight-light-grey-300: #b5bec4;
+ --color-legacylight-light-grey-400: #95a0a8;
+ --color-legacylight-dark-grey-200: #29323a;
+ --color-legacylight-dark-grey-400: #4e5364;
+ --color-legacylight-light-blue-50: #def3ff;
+ --color-legacylight-light-blue-100: #7399c6;
+ --color-legacylight-light-blue-200: #6a8db6;
+ --color-legacylight-light-blue-250: #687b93;
+ --color-legacylight-light-blue-270: #597089;
+ --color-legacylight-light-blue-300: #4d6f9c;
+ --color-legacylight-light-blue-350: #475b72;
+ --color-legacylight-light-blue-400: #1b4c8c;
+ --color-legacylight-light-blue-600: #2d3d51;
+ --color-legacylight-green-100: #5cb65c;
+ --color-legacylight-orange-100: #f68f1e;
+ --color-legacylight-orange-150: #ea8212;
+}
+
// ---------------------------------------- NORMALIZE ----------------------------------------
html {
diff --git a/packages/legend-application-repl/src/components/LegendREPLDataCubeHeader.tsx b/packages/legend-application-repl/src/components/LegendREPLDataCubeHeader.tsx
index 7fcad3d017..9e587c79a3 100644
--- a/packages/legend-application-repl/src/components/LegendREPLDataCubeHeader.tsx
+++ b/packages/legend-application-repl/src/components/LegendREPLDataCubeHeader.tsx
@@ -43,7 +43,7 @@ export const LegendREPLDataCubeHeader = observer(
.publishDataCube(dataCube)
.catch((error) => dataCube.engine.logUnhandledError(error));
}}
- className="w-20 border border-neutral-400 bg-neutral-300 px-2 hover:brightness-95 disabled:cursor-not-allowed disabled:border-neutral-300 disabled:text-neutral-400 disabled:hover:brightness-100"
+ className="flex h-5 w-20 items-center justify-center border border-neutral-400 bg-neutral-300 px-2 text-sm hover:brightness-95 disabled:cursor-not-allowed disabled:border-neutral-300 disabled:text-neutral-400 disabled:hover:brightness-100"
>
Publish
diff --git a/packages/legend-application-repl/src/stores/LegendREPLBaseStore.tsx b/packages/legend-application-repl/src/stores/LegendREPLBaseStore.tsx
index 7d4d330f1a..1ec7161249 100644
--- a/packages/legend-application-repl/src/stores/LegendREPLBaseStore.tsx
+++ b/packages/legend-application-repl/src/stores/LegendREPLBaseStore.tsx
@@ -58,7 +58,7 @@ export class LegendREPLBaseStore {
makeObservable(this, {
query: observable,
- initialize: action,
+ setQuery: action,
});
this.application = application;
this.client = new LegendREPLServerClient(
@@ -75,17 +75,27 @@ export class LegendREPLBaseStore {
this.engine = new LegendREPLDataCubeEngine(this);
}
+ setQuery(query: DataCubeQuery | undefined): void {
+ this.query = query;
+ }
+
async initialize() {
this.initState.inProgress();
try {
const info = await this.client.getInfrastructureInfo();
this.currentUser = info.currentUser;
+ if (info.currentUser) {
+ this.application.identityService.setCurrentUser(info.currentUser);
+ }
+ this.application.telemetryService.setup();
+
this.queryServerBaseUrl = info.queryServerBaseUrl;
this.hostedApplicationBaseUrl = info.hostedApplicationBaseUrl;
this.gridClientLicense = info.gridClientLicense;
- this.query = DataCubeQuery.serialization.fromJson(
- await this.client.getBaseQuery(),
+ this.setQuery(
+ DataCubeQuery.serialization.fromJson(await this.client.getBaseQuery()),
);
+
this.initState.pass();
} catch (error) {
assertErrorThrown(error);
diff --git a/packages/legend-application-repl/src/stores/LegendREPLDataCubeEngine.ts b/packages/legend-application-repl/src/stores/LegendREPLDataCubeEngine.ts
index 603a59e751..0983742fd8 100644
--- a/packages/legend-application-repl/src/stores/LegendREPLDataCubeEngine.ts
+++ b/packages/legend-application-repl/src/stores/LegendREPLDataCubeEngine.ts
@@ -35,6 +35,8 @@ import {
type V1_ValueSpecification,
V1_buildEngineError,
V1_EngineError,
+ V1_RelationType,
+ V1_getGenericTypeFullPath,
} from '@finos/legend-graph';
import {
assertErrorThrown,
@@ -135,9 +137,17 @@ export class LegendREPLDataCubeEngine extends DataCubeEngine {
query: V1_Lambda,
source: DataCubeSource,
) {
- return this.client.getQueryRelationReturnType({
- query: V1_serializeValueSpecification(query, []),
- });
+ const relationType = V1_RelationType.serialization.fromJson(
+ await this.client.getQueryRelationReturnType({
+ query: V1_serializeValueSpecification(query, []),
+ }),
+ );
+ return {
+ columns: relationType.columns.map((column) => ({
+ name: column.name,
+ type: V1_getGenericTypeFullPath(column.genericType),
+ })),
+ };
}
override async getQueryCodeRelationReturnType(
@@ -146,10 +156,18 @@ export class LegendREPLDataCubeEngine extends DataCubeEngine {
source: DataCubeSource,
) {
try {
- return await this.client.getQueryCodeRelationReturnType({
- code,
- baseQuery: V1_serializeValueSpecification(baseQuery, []),
- });
+ const relationType = V1_RelationType.serialization.fromJson(
+ await this.client.getQueryCodeRelationReturnType({
+ code,
+ baseQuery: V1_serializeValueSpecification(baseQuery, []),
+ }),
+ );
+ return {
+ columns: relationType.columns.map((column) => ({
+ name: column.name,
+ type: V1_getGenericTypeFullPath(column.genericType),
+ })),
+ };
} catch (error) {
assertErrorThrown(error);
if (
diff --git a/packages/legend-application-repl/src/stores/LegendREPLServerClient.ts b/packages/legend-application-repl/src/stores/LegendREPLServerClient.ts
index cb46c0835f..14b959b245 100644
--- a/packages/legend-application-repl/src/stores/LegendREPLServerClient.ts
+++ b/packages/legend-application-repl/src/stores/LegendREPLServerClient.ts
@@ -24,9 +24,9 @@ import {
import {
type DataCubeQuery,
type CompletionItem,
- type RelationType,
} from '@finos/legend-data-cube';
import {
+ type V1_RelationType,
type PersistentDataCubeQuery,
type V1_Lambda,
type V1_ValueSpecification,
@@ -128,7 +128,7 @@ export class LegendREPLServerClient {
async getQueryRelationReturnType(
input: GetQueryRelationReturnTypeInput,
- ): Promise {
+ ): Promise> {
return this.networkClient.post(
`${this.dataCube}/getRelationReturnType`,
input,
@@ -137,7 +137,7 @@ export class LegendREPLServerClient {
async getQueryCodeRelationReturnType(
input: GetQueryCodeRelationReturnTypeInput,
- ): Promise {
+ ): Promise> {
return this.networkClient.post(
`${this.dataCube}/getRelationReturnType/code`,
input,
diff --git a/packages/legend-application-studio/src/components/editor/editor-group/service-editor/ServiceEditor.tsx b/packages/legend-application-studio/src/components/editor/editor-group/service-editor/ServiceEditor.tsx
index 71b21bbb99..12b81dd9dc 100644
--- a/packages/legend-application-studio/src/components/editor/editor-group/service-editor/ServiceEditor.tsx
+++ b/packages/legend-application-studio/src/components/editor/editor-group/service-editor/ServiceEditor.tsx
@@ -526,8 +526,7 @@ const ServiceGeneralEditor = observer(() => {
>
- Service requires at least {MINIMUM_SERVICE_OWNERS}{' '}
- owners
+ {`Service requires at least ${MINIMUM_SERVICE_OWNERS} owners`}
)}
diff --git a/packages/legend-application-studio/src/stores/editor/data-cube/LegendStudioDataCubeHelper.ts b/packages/legend-application-studio/src/stores/editor/data-cube/LegendStudioDataCubeHelper.ts
index 181e59d767..e151ee53e2 100644
--- a/packages/legend-application-studio/src/stores/editor/data-cube/LegendStudioDataCubeHelper.ts
+++ b/packages/legend-application-studio/src/stores/editor/data-cube/LegendStudioDataCubeHelper.ts
@@ -107,7 +107,7 @@ export const openDataCube = async (
}
try {
- await engine.getRelationalType(engine.selectInitialQuery);
+ await engine.getRelationType(engine.selectInitialQuery);
} catch (error) {
assertErrorThrown(error);
throw new UnsupportedOperationError(
diff --git a/packages/legend-data-cube/src/components/DataCube.tsx b/packages/legend-data-cube/src/components/DataCube.tsx
index e3dcf821d5..249cbff490 100644
--- a/packages/legend-data-cube/src/components/DataCube.tsx
+++ b/packages/legend-data-cube/src/components/DataCube.tsx
@@ -31,6 +31,7 @@ import { DataCubeState } from '../stores/DataCubeState.js';
import { type DataCubeOptions } from '../stores/DataCubeOptions.js';
import { DataCubeContextProvider, useDataCube } from './DataCubeProvider.js';
import type { DataCubeQuery } from '../stores/core/models/DataCubeQuery.js';
+import { FormBadge_WIP } from './core/DataCubeFormUtils.js';
const DataCubeTitleBar = observer(() => {
const dataCube = useDataCube();
@@ -60,7 +61,7 @@ const DataCubeTitleBar = observer(() => {
transformOrigin: { vertical: 'top', horizontal: 'left' },
classes: {
paper: 'rounded-none mt-[1px]',
- list: 'w-36 p-0 rounded-none border border-neutral-400 bg-white max-h-40 overflow-y-auto py-0.5',
+ list: 'w-40 p-0 rounded-none border border-neutral-400 bg-white max-h-40 overflow-y-auto py-0.5',
},
}}
>
@@ -76,6 +77,7 @@ const DataCubeTitleBar = observer(() => {
disabled={true} // TODO: enable when we set up the documentation website
>
See Documentation
+
;
+ ): Promise;
abstract getQueryCodeRelationReturnType(
code: string,
baseQuery: V1_ValueSpecification,
source: DataCubeSource,
- ): Promise;
+ ): Promise;
abstract executeQuery(
query: V1_Lambda,
diff --git a/packages/legend-data-cube/src/stores/view/grid/DataCubeGridQueryBuilder.ts b/packages/legend-data-cube/src/stores/view/grid/DataCubeGridQueryBuilder.ts
index 1e7ff9ff4e..249455aec4 100644
--- a/packages/legend-data-cube/src/stores/view/grid/DataCubeGridQueryBuilder.ts
+++ b/packages/legend-data-cube/src/stores/view/grid/DataCubeGridQueryBuilder.ts
@@ -21,6 +21,7 @@ import {
type V1_AppliedFunction,
V1_GenericType,
V1_RelationType,
+ V1_getGenericTypeFullPath,
} from '@finos/legend-graph';
import { type DataCubeQuerySnapshot } from '../../core/DataCubeQuerySnapshot.js';
import {
@@ -109,7 +110,12 @@ function _addCountAggColumnToPivot(
).rawType,
V1_RelationType,
).columns.map((column) =>
- _colSpec(column.name, undefined, undefined, column.type),
+ _colSpec(
+ column.name,
+ undefined,
+ undefined,
+ V1_getGenericTypeFullPath(column.genericType),
+ ),
);
uniq(
castColumns
diff --git a/packages/legend-graph/src/graph-manager/protocol/pure/v1/engine/V1_RemoteEngine.ts b/packages/legend-graph/src/graph-manager/protocol/pure/v1/engine/V1_RemoteEngine.ts
index dec1fc645b..2d771b8537 100644
--- a/packages/legend-graph/src/graph-manager/protocol/pure/v1/engine/V1_RemoteEngine.ts
+++ b/packages/legend-graph/src/graph-manager/protocol/pure/v1/engine/V1_RemoteEngine.ts
@@ -163,6 +163,7 @@ import { V1_CompleteCodeInput } from './compilation/V1_CompleteCodeInput.js';
import { CodeCompletionResult } from '../../../../action/compilation/Completion.js';
import { DeploymentResult } from '../../../../action/DeploymentResult.js';
import { PersistentDataCubeQuery } from '../../../../action/query/PersistentDataCubeQuery.js';
+import { V1_getGenericTypeFullPath } from '../helpers/V1_DomainHelper.js';
class V1_RemoteEngineConfig extends TEMPORARY__AbstractEngineConfig {
private engine: V1_RemoteEngine;
@@ -727,7 +728,11 @@ export class V1_RemoteEngine implements V1_GraphManagerEngine {
);
const result = new RelationTypeMetadata();
result.columns = res.columns.map(
- (e) => new RelationTypeColumnMetadata(e.type, e.name),
+ (column) =>
+ new RelationTypeColumnMetadata(
+ V1_getGenericTypeFullPath(column.genericType),
+ column.name,
+ ),
);
return result;
}
diff --git a/packages/legend-graph/src/graph-manager/protocol/pure/v1/helpers/V1_DomainHelper.ts b/packages/legend-graph/src/graph-manager/protocol/pure/v1/helpers/V1_DomainHelper.ts
index 5caae6859c..5a61c2ea8d 100644
--- a/packages/legend-graph/src/graph-manager/protocol/pure/v1/helpers/V1_DomainHelper.ts
+++ b/packages/legend-graph/src/graph-manager/protocol/pure/v1/helpers/V1_DomainHelper.ts
@@ -36,7 +36,7 @@ export const V1_getGenericTypeFullPath = (val: V1_GenericType): string => {
return val.rawType.fullPath;
}
throw new UnsupportedOperationError(
- 'Failed to get full path from generic type',
+ `Can't extract type path from generic type`,
);
};
@@ -152,6 +152,6 @@ export function V1_createRelationTypeColumn(
): V1_RelationTypeColumn {
const column = new V1_RelationTypeColumn();
column.name = name;
- column.type = type;
+ column.genericType = V1_createGenericTypeWithElementPath(type);
return column;
}
diff --git a/packages/legend-graph/src/graph-manager/protocol/pure/v1/model/packageableElements/type/V1_RelationType.ts b/packages/legend-graph/src/graph-manager/protocol/pure/v1/model/packageableElements/type/V1_RelationType.ts
index c7e93cd5b9..c6f51a75ee 100644
--- a/packages/legend-graph/src/graph-manager/protocol/pure/v1/model/packageableElements/type/V1_RelationType.ts
+++ b/packages/legend-graph/src/graph-manager/protocol/pure/v1/model/packageableElements/type/V1_RelationType.ts
@@ -20,23 +20,54 @@ import {
usingModelSchema,
type Hashable,
} from '@finos/legend-shared';
-import { createModelSchema, list, primitive } from 'serializr';
+import {
+ createModelSchema,
+ custom,
+ list,
+ primitive,
+ serialize,
+} from 'serializr';
import type { V1_Type } from './V1_Type.js';
import { CORE_HASH_STRUCTURE } from '../../../../../../../graph/Core_HashUtils.js';
+import type { V1_GenericType } from './V1_GenericType.js';
+import {
+ V1_deserializeGenericType,
+ V1_GenericTypeModelSchema,
+} from '../../../transformation/pureProtocol/serializationHelpers/V1_TypeSerializationHelper.js';
export class V1_RelationTypeColumn implements Hashable {
name!: string;
- type!: string;
+ genericType!: V1_GenericType;
static readonly serialization = new SerializationFactory(
createModelSchema(V1_RelationTypeColumn, {
name: primitive(),
- type: primitive(),
+ genericType: custom(
+ (val) => serialize(V1_GenericTypeModelSchema, val),
+ (val) => V1_deserializeGenericType(val),
+ {
+ beforeDeserialize: function (callback, jsonValue, jsonParentValue) {
+ /** @backwardCompatibility */
+ if (
+ jsonParentValue.type !== undefined &&
+ jsonParentValue.genericType === undefined
+ ) {
+ callback(null, jsonParentValue.type);
+ } else {
+ callback(null, jsonParentValue.genericType);
+ }
+ },
+ },
+ ),
}),
);
get hashCode(): string {
- return hashArray([CORE_HASH_STRUCTURE.RELATION_TYPE, this.name, this.type]);
+ return hashArray([
+ CORE_HASH_STRUCTURE.RELATION_TYPE,
+ this.name,
+ this.genericType,
+ ]);
}
}
diff --git a/packages/legend-graph/src/graph-manager/protocol/pure/v1/transformation/pureGraph/from/V1_ValueSpecificationTransformer.ts b/packages/legend-graph/src/graph-manager/protocol/pure/v1/transformation/pureGraph/from/V1_ValueSpecificationTransformer.ts
index 9c41566555..0f4a94b735 100644
--- a/packages/legend-graph/src/graph-manager/protocol/pure/v1/transformation/pureGraph/from/V1_ValueSpecificationTransformer.ts
+++ b/packages/legend-graph/src/graph-manager/protocol/pure/v1/transformation/pureGraph/from/V1_ValueSpecificationTransformer.ts
@@ -89,7 +89,7 @@ import { V1_CByteArray } from '../../../model/valueSpecification/raw/V1_CByteArr
import type { ColSpecArrayInstance } from '../../../../../../../graph/metamodel/pure/valueSpecification/RelationValueSpecification.js';
import { V1_ColSpecArray } from '../../../model/valueSpecification/raw/classInstance/relation/V1_ColSpecArray.js';
import { V1_ColSpec } from '../../../model/valueSpecification/raw/classInstance/relation/V1_ColSpec.js';
-import { Relation_RelationalColumn } from '../../../../../../../graph/metamodel/pure/packageableElements/relation/Relation_RelationType.js';
+import { RelationColumn } from '../../../../../../../graph/metamodel/pure/packageableElements/relation/RelationType.js';
import { V1_createGenericTypeWithElementPath } from '../../../helpers/V1_DomainHelper.js';
class V1_ValueSpecificationTransformer
@@ -134,7 +134,7 @@ class V1_ValueSpecificationTransformer
valueSpecification: FunctionExpression,
): V1_ValueSpecification {
// handle relational column
- if (valueSpecification.func instanceof Relation_RelationalColumn) {
+ if (valueSpecification.func instanceof RelationColumn) {
const _property = new V1_AppliedProperty();
_property.property = valueSpecification.func.name;
_property.parameters = valueSpecification.parametersValues.map((value) =>
diff --git a/packages/legend-graph/src/graph-manager/protocol/pure/v1/transformation/pureGraph/to/helpers/V1_ValueSpecificationBuilderHelper.ts b/packages/legend-graph/src/graph-manager/protocol/pure/v1/transformation/pureGraph/to/helpers/V1_ValueSpecificationBuilderHelper.ts
index fcfe03f72a..7ae250b79b 100644
--- a/packages/legend-graph/src/graph-manager/protocol/pure/v1/transformation/pureGraph/to/helpers/V1_ValueSpecificationBuilderHelper.ts
+++ b/packages/legend-graph/src/graph-manager/protocol/pure/v1/transformation/pureGraph/to/helpers/V1_ValueSpecificationBuilderHelper.ts
@@ -109,7 +109,7 @@ import {
import { V1_SubTypeGraphFetchTree } from '../../../../model/valueSpecification/raw/classInstance/graph/V1_SubTypeGraphFetchTree.js';
import { findMappingLocalProperty } from '../../../../../../../../graph/helpers/DSL_Mapping_Helper.js';
import { getRelationTypeGenericType } from '../../../../../../../../graph/helpers/ValueSpecificationHelper.js';
-import { Relation_RelationType } from '../../../../../../../../graph/metamodel/pure/packageableElements/relation/Relation_RelationType.js';
+import { RelationType } from '../../../../../../../../graph/metamodel/pure/packageableElements/relation/RelationType.js';
import {
V1_getGenericTypeFullPath,
V1_createGenericTypeWithElementPath,
@@ -585,7 +585,7 @@ export function V1_processProperty(
EnumValueExplicitReference.create(getEnumValue(inferredType, property)),
];
return enumValueInstanceValue;
- } else if (inferredType instanceof Relation_RelationType) {
+ } else if (inferredType instanceof RelationType) {
const col = guaranteeNonNullable(
inferredType.columns.find((e) => property === e.name),
`Can't find property ${property} in relation`,
diff --git a/packages/legend-graph/src/graph/helpers/ValueSpecificationHelper.ts b/packages/legend-graph/src/graph/helpers/ValueSpecificationHelper.ts
index 29a578b7e9..e77b372ae7 100644
--- a/packages/legend-graph/src/graph/helpers/ValueSpecificationHelper.ts
+++ b/packages/legend-graph/src/graph/helpers/ValueSpecificationHelper.ts
@@ -27,9 +27,9 @@ import {
} from '../metamodel/pure/valueSpecification/InstanceValue.js';
import { GenericType } from '../metamodel/pure/packageableElements/domain/GenericType.js';
import { PrimitiveType } from '../metamodel/pure/packageableElements/domain/PrimitiveType.js';
-import { Relation_Relation } from '../metamodel/pure/packageableElements/relation/Relation_Relation.js';
+import { Relation } from '../metamodel/pure/packageableElements/relation/Relation.js';
import { guaranteeNonNullable, guaranteeType } from '@finos/legend-shared';
-import { Relation_RelationType } from '../metamodel/pure/packageableElements/relation/Relation_RelationType.js';
+import { RelationType } from '../metamodel/pure/packageableElements/relation/RelationType.js';
import {
AbstractPropertyExpression,
SimpleFunctionExpression,
@@ -45,7 +45,7 @@ const getRelationGenericType = (
val: ValueSpecification,
): GenericType | undefined => {
const genType = val.genericType?.value;
- if (genType?.rawType === Relation_Relation.INSTANCE) {
+ if (genType?.rawType === Relation.INSTANCE) {
return genType;
}
return undefined;
@@ -53,7 +53,7 @@ const getRelationGenericType = (
export const getRelationTypeGenericType = (
val: ValueSpecification,
-): Relation_RelationType | undefined => {
+): RelationType | undefined => {
const relationGenType = getRelationGenericType(val);
if (relationGenType) {
const typeArg = guaranteeNonNullable(
@@ -62,7 +62,7 @@ export const getRelationTypeGenericType = (
);
return guaranteeType(
typeArg.value.rawType,
- Relation_RelationType,
+ RelationType,
'Relation expected to have type arugments of type RelationType',
);
}
diff --git a/packages/legend-graph/src/graph/metamodel/pure/packageableElements/relation/Relation_Relation.ts b/packages/legend-graph/src/graph/metamodel/pure/packageableElements/relation/Relation.ts
similarity index 95%
rename from packages/legend-graph/src/graph/metamodel/pure/packageableElements/relation/Relation_Relation.ts
rename to packages/legend-graph/src/graph/metamodel/pure/packageableElements/relation/Relation.ts
index e204812ff9..8a077d4d86 100644
--- a/packages/legend-graph/src/graph/metamodel/pure/packageableElements/relation/Relation_Relation.ts
+++ b/packages/legend-graph/src/graph/metamodel/pure/packageableElements/relation/Relation.ts
@@ -18,6 +18,6 @@ import { Class } from '../domain/Class.js';
const RELATION_NAME = 'Relation';
-export class Relation_Relation {
+export class Relation {
static readonly INSTANCE = new Class(RELATION_NAME);
}
diff --git a/packages/legend-graph/src/graph/metamodel/pure/packageableElements/relation/Relation_RelationType.ts b/packages/legend-graph/src/graph/metamodel/pure/packageableElements/relation/RelationType.ts
similarity index 88%
rename from packages/legend-graph/src/graph/metamodel/pure/packageableElements/relation/Relation_RelationType.ts
rename to packages/legend-graph/src/graph/metamodel/pure/packageableElements/relation/RelationType.ts
index 490be8e162..bc0e80b05c 100644
--- a/packages/legend-graph/src/graph/metamodel/pure/packageableElements/relation/Relation_RelationType.ts
+++ b/packages/legend-graph/src/graph/metamodel/pure/packageableElements/relation/RelationType.ts
@@ -18,12 +18,14 @@ import { Type } from '../domain/Type.js';
import type { PackageableElementVisitor } from '../PackageableElement.js';
import { Function } from '../domain/Function.js';
-export class Relation_RelationalColumn extends Function {
+export class RelationColumn extends Function {
type: Type;
+
constructor(name: string, type: Type) {
super(name);
this.type = type;
}
+
override accept_PackageableElementVisitor(
visitor: PackageableElementVisitor,
): T {
@@ -31,9 +33,9 @@ export class Relation_RelationalColumn extends Function {
}
}
-export class Relation_RelationType extends Type {
+export class RelationType extends Type {
static ID = 'NO_ID';
- columns: Relation_RelationalColumn[] = [];
+ columns: RelationColumn[] = [];
override accept_PackageableElementVisitor(
visitor: PackageableElementVisitor,
diff --git a/packages/legend-graph/src/index.ts b/packages/legend-graph/src/index.ts
index 83352cbb13..8c95ca3443 100644
--- a/packages/legend-graph/src/index.ts
+++ b/packages/legend-graph/src/index.ts
@@ -597,11 +597,11 @@ export * from './graph-manager/extensions/DSL_Mapping_PureGraphManagerPlugin_Ext
export { INTERNAL__UnknownSetImplementation } from './graph/metamodel/pure/packageableElements/mapping/INTERNAL__UnknownSetImplementation.js';
export { INTERNAL__UnknownPropertyMapping } from './graph/metamodel/pure/packageableElements/mapping/INTERNAL__UnknownPropertyMapping.js';
export { INTERNAL__UnknownConnection } from './graph/metamodel/pure/packageableElements/connection/INTERNAL__UnknownConnection.js';
-export { Relation_Relation } from './graph/metamodel/pure/packageableElements/relation/Relation_Relation.js';
+export { Relation } from './graph/metamodel/pure/packageableElements/relation/Relation.js';
export {
- Relation_RelationType,
- Relation_RelationalColumn,
-} from './graph/metamodel/pure/packageableElements/relation/Relation_RelationType.js';
+ RelationType,
+ RelationColumn,
+} from './graph/metamodel/pure/packageableElements/relation/RelationType.js';
export { Store } from './graph/metamodel/pure/packageableElements/store/Store.js';
export { Mapping } from './graph/metamodel/pure/packageableElements/mapping/Mapping.js';
diff --git a/packages/legend-query-builder/src/graph-manager/protocol/pure/v1/V1_QueryValueSpecificationBuilderHelper.ts b/packages/legend-query-builder/src/graph-manager/protocol/pure/v1/V1_QueryValueSpecificationBuilderHelper.ts
index d739e537fd..0409e6627c 100644
--- a/packages/legend-query-builder/src/graph-manager/protocol/pure/v1/V1_QueryValueSpecificationBuilderHelper.ts
+++ b/packages/legend-query-builder/src/graph-manager/protocol/pure/v1/V1_QueryValueSpecificationBuilderHelper.ts
@@ -63,10 +63,10 @@ import {
ColSpecArrayInstance,
ColSpecArray,
ColSpec,
- Relation_RelationType,
- Relation_RelationalColumn,
+ RelationType,
+ RelationColumn,
getValueSpecificationReturnType,
- Relation_Relation,
+ Relation,
} from '@finos/legend-graph';
import {
QUERY_BUILDER_PURE_PATH,
@@ -663,7 +663,7 @@ const V1_buildTypedProjectFunctionExpression = (
const processedExpression = new ColSpecArrayInstance(Multiplicity.ONE);
const processedColSpecArray = new ColSpecArray();
processedExpression.values = [processedColSpecArray];
- const relationType = new Relation_RelationType(Relation_RelationType.ID);
+ const relationType = new RelationType(RelationType.ID);
processedColSpecArray.colSpecs = specArray.colSpecs.map((colSpec) => {
const pColSpec = new ColSpec();
let lambda: ValueSpecification;
@@ -691,9 +691,7 @@ const V1_buildTypedProjectFunctionExpression = (
pColSpec.name = colSpec.name;
const returnType = getValueSpecificationReturnType(lambda);
if (returnType) {
- relationType.columns.push(
- new Relation_RelationalColumn(colSpec.name, returnType),
- );
+ relationType.columns.push(new RelationColumn(colSpec.name, returnType));
} else {
throw new UnsupportedOperationError(
'Unable to get return type for current lambda',
@@ -707,7 +705,7 @@ const V1_buildTypedProjectFunctionExpression = (
functionName,
compileContext,
);
- const relationGenericType = new GenericType(Relation_Relation.INSTANCE);
+ const relationGenericType = new GenericType(Relation.INSTANCE);
const relationTypeGenericType = new GenericType(relationType);
relationGenericType.typeArguments = [
GenericTypeExplicitReference.create(relationTypeGenericType),
diff --git a/packages/legend-query-builder/src/stores/data-cube/QueryBuilderDataCubeEngine.ts b/packages/legend-query-builder/src/stores/data-cube/QueryBuilderDataCubeEngine.ts
index 0a95e59001..c815a4ba1b 100644
--- a/packages/legend-query-builder/src/stores/data-cube/QueryBuilderDataCubeEngine.ts
+++ b/packages/legend-query-builder/src/stores/data-cube/QueryBuilderDataCubeEngine.ts
@@ -37,7 +37,7 @@ import {
DataCubeSource,
_function,
DataCubeFunction,
- type RelationType,
+ type DataCubeRelationType,
type CompletionItem,
_functionName,
DataCubeQuery,
@@ -71,6 +71,7 @@ export class QueryBuilderDataCubeEngine extends DataCubeEngine {
graphManagerState: GraphManagerState,
) {
super();
+
this.graphState = graphManagerState;
this.selectInitialQuery = selectQuery;
this.mappingPath = mappingPath;
@@ -117,7 +118,7 @@ export class QueryBuilderDataCubeEngine extends DataCubeEngine {
if (this.runtimePath) {
fromFuncExp.parameters.push(_elementPtr(this.runtimePath));
}
- const columns = (await this.getRelationalType(this.selectInitialQuery))
+ const columns = (await this.getRelationType(this.selectInitialQuery))
.columns;
const query = new DataCubeQuery();
query.query = `~[${columns.map((e) => `'${e.name}'`)}]->select()`;
@@ -132,7 +133,7 @@ export class QueryBuilderDataCubeEngine extends DataCubeEngine {
const srcFuncExp = this.getSourceFunctionExpression();
const source = new QueryBuilderDataCubeSource();
source.columns = (
- await this.getRelationalType(this.selectInitialQuery)
+ await this.getRelationType(this.selectInitialQuery)
).columns;
source.mapping = this.mappingPath;
source.runtime = this.runtimePath;
@@ -185,7 +186,7 @@ export class QueryBuilderDataCubeEngine extends DataCubeEngine {
);
}
- async getValueSpecificationCode(
+ override async getValueSpecificationCode(
value: V1_ValueSpecification,
pretty?: boolean | undefined,
) {
@@ -195,7 +196,7 @@ export class QueryBuilderDataCubeEngine extends DataCubeEngine {
);
}
- async getRelationalType(query: RawLambda): Promise {
+ async getRelationType(query: RawLambda) {
const relationType =
await this.graphState.graphManager.getLambdaRelationType(
query,
@@ -204,9 +205,12 @@ export class QueryBuilderDataCubeEngine extends DataCubeEngine {
return relationType;
}
- async getQueryRelationType(query: V1_Lambda, source: DataCubeSource) {
+ override async getQueryRelationType(
+ query: V1_Lambda,
+ source: DataCubeSource,
+ ) {
const lambda = this.buildRawLambdaFromValueSpec(query);
- return this.getRelationalType(lambda);
+ return this.getRelationType(lambda);
}
override async getQueryCodeRelationReturnType(
@@ -219,7 +223,7 @@ export class QueryBuilderDataCubeEngine extends DataCubeEngine {
V1_serializeValueSpecification(baseQuery, []),
);
const fullQuery = queryString + code;
- return this.getRelationalType(
+ return this.getRelationType(
await this.graphState.graphManager.pureCodeToLambda(fullQuery),
);
}
diff --git a/packages/legend-query-builder/src/stores/fetch-structure/tds/projection/QueryBuilderRelationProjectValueSpecBuidler.ts b/packages/legend-query-builder/src/stores/fetch-structure/tds/projection/QueryBuilderRelationProjectValueSpecBuidler.ts
index 914b1abfa3..abe34fce45 100644
--- a/packages/legend-query-builder/src/stores/fetch-structure/tds/projection/QueryBuilderRelationProjectValueSpecBuidler.ts
+++ b/packages/legend-query-builder/src/stores/fetch-structure/tds/projection/QueryBuilderRelationProjectValueSpecBuidler.ts
@@ -28,9 +28,9 @@ import {
V1_GraphTransformerContextBuilder,
GenericType,
GenericTypeExplicitReference,
- Relation_Relation,
- Relation_RelationalColumn,
- Relation_RelationType,
+ Relation,
+ RelationColumn,
+ RelationType,
} from '@finos/legend-graph';
import { QUERY_BUILDER_SUPPORTED_FUNCTIONS } from '../../../../graph/QueryBuilderMetaModelConst.js';
import {
@@ -64,7 +64,7 @@ export const buildRelationProjection = (
const colSepcArray = new ColSpecArray();
instanceVal.values = [colSepcArray];
- const relationType = new Relation_RelationType(Relation_RelationType.ID);
+ const relationType = new RelationType(RelationType.ID);
tdsState.projectionColumns.forEach((projectionColumnState) => {
const colSpec = new ColSpec();
@@ -118,14 +118,11 @@ export const buildRelationProjection = (
`Can't create value spec for projection column ${projectionColumnState.columnName}`,
);
relationType.columns.push(
- new Relation_RelationalColumn(
- projectionColumnState.columnName,
- returnType,
- ),
+ new RelationColumn(projectionColumnState.columnName, returnType),
);
});
projectFunction.parametersValues = [precedingExpression, instanceVal];
- const relationGenericType = new GenericType(Relation_Relation.INSTANCE);
+ const relationGenericType = new GenericType(Relation.INSTANCE);
const relationTypeGenericType = new GenericType(relationType);
relationGenericType.typeArguments = [
GenericTypeExplicitReference.create(relationTypeGenericType),
diff --git a/packages/legend-vscode-extension-dependencies/src/index.ts b/packages/legend-vscode-extension-dependencies/src/index.ts
index a11c733dc3..9e7f91d5b1 100644
--- a/packages/legend-vscode-extension-dependencies/src/index.ts
+++ b/packages/legend-vscode-extension-dependencies/src/index.ts
@@ -294,7 +294,7 @@ export {
type DataCubeAPI,
type DataCubeConfiguration,
type DataCubeExecutionResult,
- type RelationType,
+ type DataCubeRelationType,
_elementPtr,
_function,
_functionName,