@finos/legend-cube-builder 0.0.0-stage → 0.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +201 -0
- package/README.md +64 -2
- package/docs/adding-an-operation.md +92 -0
- package/docs/hosting.md +79 -0
- package/docs/testing.md +83 -0
- package/lib/__lib__/LegendCubeCommand.d.ts +26 -0
- package/lib/__lib__/LegendCubeCommand.d.ts.map +1 -0
- package/lib/__lib__/LegendCubeCommand.js +40 -0
- package/lib/__lib__/LegendCubeCommand.js.map +1 -0
- package/lib/__lib__/LegendCubeHelpText.d.ts +19 -0
- package/lib/__lib__/LegendCubeHelpText.d.ts.map +1 -0
- package/lib/__lib__/LegendCubeHelpText.js +35 -0
- package/lib/__lib__/LegendCubeHelpText.js.map +1 -0
- package/lib/__lib__/LegendCubeLabels.d.ts +87 -0
- package/lib/__lib__/LegendCubeLabels.d.ts.map +1 -0
- package/lib/__lib__/LegendCubeLabels.js +128 -0
- package/lib/__lib__/LegendCubeLabels.js.map +1 -0
- package/lib/__lib__/LegendCubeTesting.d.ts +33 -0
- package/lib/__lib__/LegendCubeTesting.d.ts.map +1 -0
- package/lib/__lib__/LegendCubeTesting.js +34 -0
- package/lib/__lib__/LegendCubeTesting.js.map +1 -0
- package/lib/__test-utils__/CubeCanvasTestUtils.d.ts +24 -0
- package/lib/__test-utils__/CubeCanvasTestUtils.d.ts.map +1 -0
- package/lib/__test-utils__/CubeCanvasTestUtils.js +37 -0
- package/lib/__test-utils__/CubeCanvasTestUtils.js.map +1 -0
- package/lib/__test-utils__/CubeEngineTestSupport.d.ts +47 -0
- package/lib/__test-utils__/CubeEngineTestSupport.d.ts.map +1 -0
- package/lib/__test-utils__/CubeEngineTestSupport.js +106 -0
- package/lib/__test-utils__/CubeEngineTestSupport.js.map +1 -0
- package/lib/__test-utils__/CubeNorthwindTestQueries.d.ts +31 -0
- package/lib/__test-utils__/CubeNorthwindTestQueries.d.ts.map +1 -0
- package/lib/__test-utils__/CubeNorthwindTestQueries.js +102 -0
- package/lib/__test-utils__/CubeNorthwindTestQueries.js.map +1 -0
- package/lib/__test-utils__/CubeOperationsTestUtils.d.ts +42 -0
- package/lib/__test-utils__/CubeOperationsTestUtils.d.ts.map +1 -0
- package/lib/__test-utils__/CubeOperationsTestUtils.js +92 -0
- package/lib/__test-utils__/CubeOperationsTestUtils.js.map +1 -0
- package/lib/__test-utils__/CubePageTestUtils.d.ts +33 -0
- package/lib/__test-utils__/CubePageTestUtils.d.ts.map +1 -0
- package/lib/__test-utils__/CubePageTestUtils.js +68 -0
- package/lib/__test-utils__/CubePageTestUtils.js.map +1 -0
- package/lib/__test-utils__/CubeTestApplication.d.ts +30 -0
- package/lib/__test-utils__/CubeTestApplication.d.ts.map +1 -0
- package/lib/__test-utils__/CubeTestApplication.js +57 -0
- package/lib/__test-utils__/CubeTestApplication.js.map +1 -0
- package/lib/__test-utils__/FakeCubeEngine.d.ts +41 -0
- package/lib/__test-utils__/FakeCubeEngine.d.ts.map +1 -0
- package/lib/__test-utils__/FakeCubeEngine.js +91 -0
- package/lib/__test-utils__/FakeCubeEngine.js.map +1 -0
- package/lib/components/CubeButton.d.ts +20 -0
- package/lib/components/CubeButton.d.ts.map +1 -0
- package/lib/components/CubeButton.js +24 -0
- package/lib/components/CubeButton.js.map +1 -0
- package/lib/components/CubeEditor.d.ts +31 -0
- package/lib/components/CubeEditor.d.ts.map +1 -0
- package/lib/components/CubeEditor.js +90 -0
- package/lib/components/CubeEditor.js.map +1 -0
- package/lib/components/CubeNodeIcon.d.ts +23 -0
- package/lib/components/CubeNodeIcon.d.ts.map +1 -0
- package/lib/components/CubeNodeIcon.js +42 -0
- package/lib/components/CubeNodeIcon.js.map +1 -0
- package/lib/components/canvas/CubeCanvas.d.ts +37 -0
- package/lib/components/canvas/CubeCanvas.d.ts.map +1 -0
- package/lib/components/canvas/CubeCanvas.js +137 -0
- package/lib/components/canvas/CubeCanvas.js.map +1 -0
- package/lib/components/canvas/CubeCanvasContext.d.ts +19 -0
- package/lib/components/canvas/CubeCanvasContext.d.ts.map +1 -0
- package/lib/components/canvas/CubeCanvasContext.js +22 -0
- package/lib/components/canvas/CubeCanvasContext.js.map +1 -0
- package/lib/components/canvas/CubeCanvasContextMenu.d.ts +28 -0
- package/lib/components/canvas/CubeCanvasContextMenu.d.ts.map +1 -0
- package/lib/components/canvas/CubeCanvasContextMenu.js +35 -0
- package/lib/components/canvas/CubeCanvasContextMenu.js.map +1 -0
- package/lib/components/canvas/CubeCanvasDnd.d.ts +43 -0
- package/lib/components/canvas/CubeCanvasDnd.d.ts.map +1 -0
- package/lib/components/canvas/CubeCanvasDnd.js +51 -0
- package/lib/components/canvas/CubeCanvasDnd.js.map +1 -0
- package/lib/components/canvas/CubeCanvasEdge.d.ts +24 -0
- package/lib/components/canvas/CubeCanvasEdge.d.ts.map +1 -0
- package/lib/components/canvas/CubeCanvasEdge.js +33 -0
- package/lib/components/canvas/CubeCanvasEdge.js.map +1 -0
- package/lib/components/canvas/CubeCanvasElements.d.ts +66 -0
- package/lib/components/canvas/CubeCanvasElements.d.ts.map +1 -0
- package/lib/components/canvas/CubeCanvasElements.js +97 -0
- package/lib/components/canvas/CubeCanvasElements.js.map +1 -0
- package/lib/components/canvas/CubeCanvasLayout.d.ts +32 -0
- package/lib/components/canvas/CubeCanvasLayout.d.ts.map +1 -0
- package/lib/components/canvas/CubeCanvasLayout.js +63 -0
- package/lib/components/canvas/CubeCanvasLayout.js.map +1 -0
- package/lib/components/canvas/CubeCanvasNode.d.ts +29 -0
- package/lib/components/canvas/CubeCanvasNode.d.ts.map +1 -0
- package/lib/components/canvas/CubeCanvasNode.js +75 -0
- package/lib/components/canvas/CubeCanvasNode.js.map +1 -0
- package/lib/components/editors/CubeColumnPicker.d.ts +47 -0
- package/lib/components/editors/CubeColumnPicker.d.ts.map +1 -0
- package/lib/components/editors/CubeColumnPicker.js +56 -0
- package/lib/components/editors/CubeColumnPicker.js.map +1 -0
- package/lib/components/editors/CubeDistinctEditor.d.ts +23 -0
- package/lib/components/editors/CubeDistinctEditor.d.ts.map +1 -0
- package/lib/components/editors/CubeDistinctEditor.js +24 -0
- package/lib/components/editors/CubeDistinctEditor.js.map +1 -0
- package/lib/components/editors/CubeFilterEditor.d.ts +26 -0
- package/lib/components/editors/CubeFilterEditor.d.ts.map +1 -0
- package/lib/components/editors/CubeFilterEditor.js +90 -0
- package/lib/components/editors/CubeFilterEditor.js.map +1 -0
- package/lib/components/editors/CubeIntegerField.d.ts +29 -0
- package/lib/components/editors/CubeIntegerField.d.ts.map +1 -0
- package/lib/components/editors/CubeIntegerField.js +30 -0
- package/lib/components/editors/CubeIntegerField.js.map +1 -0
- package/lib/components/editors/CubeJoinEditor.d.ts +26 -0
- package/lib/components/editors/CubeJoinEditor.d.ts.map +1 -0
- package/lib/components/editors/CubeJoinEditor.js +84 -0
- package/lib/components/editors/CubeJoinEditor.js.map +1 -0
- package/lib/components/editors/CubeNodeEditorPanel.d.ts +29 -0
- package/lib/components/editors/CubeNodeEditorPanel.d.ts.map +1 -0
- package/lib/components/editors/CubeNodeEditorPanel.js +72 -0
- package/lib/components/editors/CubeNodeEditorPanel.js.map +1 -0
- package/lib/components/editors/CubeNodeEditorRegistry.d.ts +44 -0
- package/lib/components/editors/CubeNodeEditorRegistry.d.ts.map +1 -0
- package/lib/components/editors/CubeNodeEditorRegistry.js +43 -0
- package/lib/components/editors/CubeNodeEditorRegistry.js.map +1 -0
- package/lib/components/editors/CubeRenameEditor.d.ts +26 -0
- package/lib/components/editors/CubeRenameEditor.d.ts.map +1 -0
- package/lib/components/editors/CubeRenameEditor.js +58 -0
- package/lib/components/editors/CubeRenameEditor.js.map +1 -0
- package/lib/components/editors/CubeRestrictEditor.d.ts +26 -0
- package/lib/components/editors/CubeRestrictEditor.d.ts.map +1 -0
- package/lib/components/editors/CubeRestrictEditor.js +23 -0
- package/lib/components/editors/CubeRestrictEditor.js.map +1 -0
- package/lib/components/editors/CubeRowCountEditor.d.ts +25 -0
- package/lib/components/editors/CubeRowCountEditor.d.ts.map +1 -0
- package/lib/components/editors/CubeRowCountEditor.js +38 -0
- package/lib/components/editors/CubeRowCountEditor.js.map +1 -0
- package/lib/components/editors/CubeSliceEditor.d.ts +25 -0
- package/lib/components/editors/CubeSliceEditor.d.ts.map +1 -0
- package/lib/components/editors/CubeSliceEditor.js +40 -0
- package/lib/components/editors/CubeSliceEditor.js.map +1 -0
- package/lib/components/editors/CubeSortEditor.d.ts +27 -0
- package/lib/components/editors/CubeSortEditor.d.ts.map +1 -0
- package/lib/components/editors/CubeSortEditor.js +72 -0
- package/lib/components/editors/CubeSortEditor.js.map +1 -0
- package/lib/components/editors/CubeSourceEditor.d.ts +25 -0
- package/lib/components/editors/CubeSourceEditor.d.ts.map +1 -0
- package/lib/components/editors/CubeSourceEditor.js +41 -0
- package/lib/components/editors/CubeSourceEditor.js.map +1 -0
- package/lib/components/editors/CubeValueEditor.d.ts +40 -0
- package/lib/components/editors/CubeValueEditor.d.ts.map +1 -0
- package/lib/components/editors/CubeValueEditor.js +178 -0
- package/lib/components/editors/CubeValueEditor.js.map +1 -0
- package/lib/components/grid/CubeGridRegion.d.ts +23 -0
- package/lib/components/grid/CubeGridRegion.d.ts.map +1 -0
- package/lib/components/grid/CubeGridRegion.js +94 -0
- package/lib/components/grid/CubeGridRegion.js.map +1 -0
- package/lib/components/grid/CubeGridValues.d.ts +25 -0
- package/lib/components/grid/CubeGridValues.d.ts.map +1 -0
- package/lib/components/grid/CubeGridValues.js +95 -0
- package/lib/components/grid/CubeGridValues.js.map +1 -0
- package/lib/components/grid/CubeResultGrid.d.ts +39 -0
- package/lib/components/grid/CubeResultGrid.d.ts.map +1 -0
- package/lib/components/grid/CubeResultGrid.js +86 -0
- package/lib/components/grid/CubeResultGrid.js.map +1 -0
- package/lib/components/palette/CubePalette.d.ts +29 -0
- package/lib/components/palette/CubePalette.d.ts.map +1 -0
- package/lib/components/palette/CubePalette.js +73 -0
- package/lib/components/palette/CubePalette.js.map +1 -0
- package/lib/components/show-pure/CubeShowPureDialog.d.ts +23 -0
- package/lib/components/show-pure/CubeShowPureDialog.d.ts.map +1 -0
- package/lib/components/show-pure/CubeShowPureDialog.js +37 -0
- package/lib/components/show-pure/CubeShowPureDialog.js.map +1 -0
- package/lib/components/source-picker/CubeSourcePicker.d.ts +22 -0
- package/lib/components/source-picker/CubeSourcePicker.d.ts.map +1 -0
- package/lib/components/source-picker/CubeSourcePicker.js +89 -0
- package/lib/components/source-picker/CubeSourcePicker.js.map +1 -0
- package/lib/components/spec-transfer/CubeSpecTransferDialog.d.ts +26 -0
- package/lib/components/spec-transfer/CubeSpecTransferDialog.d.ts.map +1 -0
- package/lib/components/spec-transfer/CubeSpecTransferDialog.js +45 -0
- package/lib/components/spec-transfer/CubeSpecTransferDialog.js.map +1 -0
- package/lib/graph-manager/CubeEngine.d.ts +128 -0
- package/lib/graph-manager/CubeEngine.d.ts.map +1 -0
- package/lib/graph-manager/CubeEngine.js +61 -0
- package/lib/graph-manager/CubeEngine.js.map +1 -0
- package/lib/graph-manager/CubeModelOutlineHelper.d.ts +33 -0
- package/lib/graph-manager/CubeModelOutlineHelper.d.ts.map +1 -0
- package/lib/graph-manager/CubeModelOutlineHelper.js +45 -0
- package/lib/graph-manager/CubeModelOutlineHelper.js.map +1 -0
- package/lib/graph-manager/protocol/pure/CubeEngineBuilder.d.ts +26 -0
- package/lib/graph-manager/protocol/pure/CubeEngineBuilder.d.ts.map +1 -0
- package/lib/graph-manager/protocol/pure/CubeEngineBuilder.js +22 -0
- package/lib/graph-manager/protocol/pure/CubeEngineBuilder.js.map +1 -0
- package/lib/graph-manager/protocol/pure/v1/V1_CubeEngineErrors.d.ts +27 -0
- package/lib/graph-manager/protocol/pure/v1/V1_CubeEngineErrors.d.ts.map +1 -0
- package/lib/graph-manager/protocol/pure/v1/V1_CubeEngineErrors.js +76 -0
- package/lib/graph-manager/protocol/pure/v1/V1_CubeEngineErrors.js.map +1 -0
- package/lib/graph-manager/protocol/pure/v1/V1_CubeExecutionResultReader.d.ts +27 -0
- package/lib/graph-manager/protocol/pure/v1/V1_CubeExecutionResultReader.d.ts.map +1 -0
- package/lib/graph-manager/protocol/pure/v1/V1_CubeExecutionResultReader.js +82 -0
- package/lib/graph-manager/protocol/pure/v1/V1_CubeExecutionResultReader.js.map +1 -0
- package/lib/graph-manager/protocol/pure/v1/V1_CubeLambdaSerializer.d.ts +32 -0
- package/lib/graph-manager/protocol/pure/v1/V1_CubeLambdaSerializer.d.ts.map +1 -0
- package/lib/graph-manager/protocol/pure/v1/V1_CubeLambdaSerializer.js +195 -0
- package/lib/graph-manager/protocol/pure/v1/V1_CubeLambdaSerializer.js.map +1 -0
- package/lib/graph-manager/protocol/pure/v1/V1_CubeModelOutlineBuilder.d.ts +20 -0
- package/lib/graph-manager/protocol/pure/v1/V1_CubeModelOutlineBuilder.d.ts.map +1 -0
- package/lib/graph-manager/protocol/pure/v1/V1_CubeModelOutlineBuilder.js +174 -0
- package/lib/graph-manager/protocol/pure/v1/V1_CubeModelOutlineBuilder.js.map +1 -0
- package/lib/graph-manager/protocol/pure/v1/V1_CubeRelationTypeAdapter.d.ts +24 -0
- package/lib/graph-manager/protocol/pure/v1/V1_CubeRelationTypeAdapter.d.ts.map +1 -0
- package/lib/graph-manager/protocol/pure/v1/V1_CubeRelationTypeAdapter.js +43 -0
- package/lib/graph-manager/protocol/pure/v1/V1_CubeRelationTypeAdapter.js.map +1 -0
- package/lib/graph-manager/protocol/pure/v1/V1_LegendCubeEngine.d.ts +45 -0
- package/lib/graph-manager/protocol/pure/v1/V1_LegendCubeEngine.d.ts.map +1 -0
- package/lib/graph-manager/protocol/pure/v1/V1_LegendCubeEngine.js +171 -0
- package/lib/graph-manager/protocol/pure/v1/V1_LegendCubeEngine.js.map +1 -0
- package/lib/graph-manager/protocol/pure/v1/__test-utils__/V1_CubeEngineTestUtils.d.ts +22 -0
- package/lib/graph-manager/protocol/pure/v1/__test-utils__/V1_CubeEngineTestUtils.d.ts.map +1 -0
- package/lib/graph-manager/protocol/pure/v1/__test-utils__/V1_CubeEngineTestUtils.js +79 -0
- package/lib/graph-manager/protocol/pure/v1/__test-utils__/V1_CubeEngineTestUtils.js.map +1 -0
- package/lib/index.css +17 -0
- package/lib/index.css.map +1 -0
- package/lib/index.d.ts +25 -0
- package/lib/index.d.ts.map +1 -0
- package/lib/index.js +24 -0
- package/lib/index.js.map +1 -0
- package/lib/stores/CubeEditorState.d.ts +236 -0
- package/lib/stores/CubeEditorState.d.ts.map +1 -0
- package/lib/stores/CubeEditorState.js +632 -0
- package/lib/stores/CubeEditorState.js.map +1 -0
- package/lib/stores/CubeExecutionState.d.ts +67 -0
- package/lib/stores/CubeExecutionState.d.ts.map +1 -0
- package/lib/stores/CubeExecutionState.js +212 -0
- package/lib/stores/CubeExecutionState.js.map +1 -0
- package/lib/stores/CubeGridQuickActions.d.ts +40 -0
- package/lib/stores/CubeGridQuickActions.d.ts.map +1 -0
- package/lib/stores/CubeGridQuickActions.js +86 -0
- package/lib/stores/CubeGridQuickActions.js.map +1 -0
- package/lib/stores/CubeHost.d.ts +31 -0
- package/lib/stores/CubeHost.d.ts.map +1 -0
- package/lib/stores/CubeHost.js +17 -0
- package/lib/stores/CubeHost.js.map +1 -0
- package/lib/stores/CubeNodeEditorState.d.ts +103 -0
- package/lib/stores/CubeNodeEditorState.d.ts.map +1 -0
- package/lib/stores/CubeNodeEditorState.js +262 -0
- package/lib/stores/CubeNodeEditorState.js.map +1 -0
- package/lib/stores/CubeShowPureState.d.ts +41 -0
- package/lib/stores/CubeShowPureState.d.ts.map +1 -0
- package/lib/stores/CubeShowPureState.js +100 -0
- package/lib/stores/CubeShowPureState.js.map +1 -0
- package/lib/stores/CubeSourcePickerState.d.ts +98 -0
- package/lib/stores/CubeSourcePickerState.d.ts.map +1 -0
- package/lib/stores/CubeSourcePickerState.js +334 -0
- package/lib/stores/CubeSourcePickerState.js.map +1 -0
- package/lib/stores/CubeSpecTransferState.d.ts +60 -0
- package/lib/stores/CubeSpecTransferState.d.ts.map +1 -0
- package/lib/stores/CubeSpecTransferState.js +167 -0
- package/lib/stores/CubeSpecTransferState.js.map +1 -0
- package/lib/stores/LocalModelCatalog.d.ts +37 -0
- package/lib/stores/LocalModelCatalog.d.ts.map +1 -0
- package/lib/stores/LocalModelCatalog.js +49 -0
- package/lib/stores/LocalModelCatalog.js.map +1 -0
- package/lib/stores/editors/CubeFilterDraft.d.ts +61 -0
- package/lib/stores/editors/CubeFilterDraft.d.ts.map +1 -0
- package/lib/stores/editors/CubeFilterDraft.js +186 -0
- package/lib/stores/editors/CubeFilterDraft.js.map +1 -0
- package/lib/stores/editors/CubeIntegerText.d.ts +24 -0
- package/lib/stores/editors/CubeIntegerText.d.ts.map +1 -0
- package/lib/stores/editors/CubeIntegerText.js +33 -0
- package/lib/stores/editors/CubeIntegerText.js.map +1 -0
- package/lib/stores/editors/CubeJoinDraft.d.ts +71 -0
- package/lib/stores/editors/CubeJoinDraft.d.ts.map +1 -0
- package/lib/stores/editors/CubeJoinDraft.js +145 -0
- package/lib/stores/editors/CubeJoinDraft.js.map +1 -0
- package/lib/stores/editors/CubeNodeDraft.d.ts +38 -0
- package/lib/stores/editors/CubeNodeDraft.d.ts.map +1 -0
- package/lib/stores/editors/CubeNodeDraft.js +35 -0
- package/lib/stores/editors/CubeNodeDraft.js.map +1 -0
- package/lib/stores/editors/CubeNodeDraftRegistry.d.ts +35 -0
- package/lib/stores/editors/CubeNodeDraftRegistry.d.ts.map +1 -0
- package/lib/stores/editors/CubeNodeDraftRegistry.js +55 -0
- package/lib/stores/editors/CubeNodeDraftRegistry.js.map +1 -0
- package/lib/stores/editors/CubeRenameDraft.d.ts +44 -0
- package/lib/stores/editors/CubeRenameDraft.d.ts.map +1 -0
- package/lib/stores/editors/CubeRenameDraft.js +79 -0
- package/lib/stores/editors/CubeRenameDraft.js.map +1 -0
- package/lib/stores/editors/CubeRestrictDraft.d.ts +37 -0
- package/lib/stores/editors/CubeRestrictDraft.d.ts.map +1 -0
- package/lib/stores/editors/CubeRestrictDraft.js +73 -0
- package/lib/stores/editors/CubeRestrictDraft.js.map +1 -0
- package/lib/stores/editors/CubeRowCountDraft.d.ts +42 -0
- package/lib/stores/editors/CubeRowCountDraft.d.ts.map +1 -0
- package/lib/stores/editors/CubeRowCountDraft.js +55 -0
- package/lib/stores/editors/CubeRowCountDraft.js.map +1 -0
- package/lib/stores/editors/CubeSliceDraft.d.ts +42 -0
- package/lib/stores/editors/CubeSliceDraft.d.ts.map +1 -0
- package/lib/stores/editors/CubeSliceDraft.js +72 -0
- package/lib/stores/editors/CubeSliceDraft.js.map +1 -0
- package/lib/stores/editors/CubeSortDraft.d.ts +49 -0
- package/lib/stores/editors/CubeSortDraft.d.ts.map +1 -0
- package/lib/stores/editors/CubeSortDraft.js +99 -0
- package/lib/stores/editors/CubeSortDraft.js.map +1 -0
- package/lib/stores/fixtures/CubeNorthwindModel.d.ts +23 -0
- package/lib/stores/fixtures/CubeNorthwindModel.d.ts.map +1 -0
- package/lib/stores/fixtures/CubeNorthwindModel.js +338 -0
- package/lib/stores/fixtures/CubeNorthwindModel.js.map +1 -0
- package/package.json +81 -3
- package/src/__lib__/LegendCubeCommand.ts +44 -0
- package/src/__lib__/LegendCubeHelpText.ts +58 -0
- package/src/__lib__/LegendCubeLabels.ts +171 -0
- package/src/__lib__/LegendCubeTesting.ts +33 -0
- package/src/__test-utils__/CubeCanvasTestUtils.ts +53 -0
- package/src/__test-utils__/CubeEngineTestSupport.ts +172 -0
- package/src/__test-utils__/CubeNorthwindTestQueries.ts +165 -0
- package/src/__test-utils__/CubeOperationsTestUtils.ts +177 -0
- package/src/__test-utils__/CubePageTestUtils.tsx +96 -0
- package/src/__test-utils__/CubeTestApplication.ts +82 -0
- package/src/__test-utils__/FakeCubeEngine.ts +145 -0
- package/src/components/CubeButton.tsx +35 -0
- package/src/components/CubeEditor.tsx +239 -0
- package/src/components/CubeNodeIcon.tsx +64 -0
- package/src/components/canvas/CubeCanvas.tsx +262 -0
- package/src/components/canvas/CubeCanvasContext.ts +31 -0
- package/src/components/canvas/CubeCanvasContextMenu.tsx +89 -0
- package/src/components/canvas/CubeCanvasDnd.ts +82 -0
- package/src/components/canvas/CubeCanvasEdge.tsx +57 -0
- package/src/components/canvas/CubeCanvasElements.ts +153 -0
- package/src/components/canvas/CubeCanvasLayout.ts +88 -0
- package/src/components/canvas/CubeCanvasNode.tsx +149 -0
- package/src/components/editors/CubeColumnPicker.tsx +138 -0
- package/src/components/editors/CubeDistinctEditor.tsx +28 -0
- package/src/components/editors/CubeFilterEditor.tsx +309 -0
- package/src/components/editors/CubeIntegerField.tsx +51 -0
- package/src/components/editors/CubeJoinEditor.tsx +247 -0
- package/src/components/editors/CubeNodeEditorPanel.tsx +215 -0
- package/src/components/editors/CubeNodeEditorRegistry.ts +81 -0
- package/src/components/editors/CubeRenameEditor.tsx +143 -0
- package/src/components/editors/CubeRestrictEditor.tsx +103 -0
- package/src/components/editors/CubeRowCountEditor.tsx +53 -0
- package/src/components/editors/CubeSliceEditor.tsx +69 -0
- package/src/components/editors/CubeSortEditor.tsx +206 -0
- package/src/components/editors/CubeSourceEditor.tsx +106 -0
- package/src/components/editors/CubeValueEditor.tsx +333 -0
- package/src/components/grid/CubeGridRegion.tsx +275 -0
- package/src/components/grid/CubeGridValues.ts +125 -0
- package/src/components/grid/CubeResultGrid.tsx +138 -0
- package/src/components/palette/CubePalette.tsx +177 -0
- package/src/components/show-pure/CubeShowPureDialog.tsx +101 -0
- package/src/components/source-picker/CubeSourcePicker.tsx +304 -0
- package/src/components/spec-transfer/CubeSpecTransferDialog.tsx +157 -0
- package/src/graph-manager/CubeEngine.ts +169 -0
- package/src/graph-manager/CubeModelOutlineHelper.ts +58 -0
- package/src/graph-manager/protocol/pure/CubeEngineBuilder.ts +34 -0
- package/src/graph-manager/protocol/pure/v1/V1_CubeEngineErrors.ts +109 -0
- package/src/graph-manager/protocol/pure/v1/V1_CubeExecutionResultReader.ts +115 -0
- package/src/graph-manager/protocol/pure/v1/V1_CubeLambdaSerializer.ts +257 -0
- package/src/graph-manager/protocol/pure/v1/V1_CubeModelOutlineBuilder.ts +243 -0
- package/src/graph-manager/protocol/pure/v1/V1_CubeRelationTypeAdapter.ts +58 -0
- package/src/graph-manager/protocol/pure/v1/V1_LegendCubeEngine.ts +278 -0
- package/src/graph-manager/protocol/pure/v1/__test-utils__/V1_CubeEngineTestUtils.ts +127 -0
- package/src/index.ts +41 -0
- package/src/stores/CubeEditorState.ts +807 -0
- package/src/stores/CubeExecutionState.ts +288 -0
- package/src/stores/CubeGridQuickActions.ts +129 -0
- package/src/stores/CubeHost.ts +32 -0
- package/src/stores/CubeNodeEditorState.ts +324 -0
- package/src/stores/CubeShowPureState.ts +118 -0
- package/src/stores/CubeSourcePickerState.ts +426 -0
- package/src/stores/CubeSpecTransferState.ts +198 -0
- package/src/stores/LocalModelCatalog.ts +70 -0
- package/src/stores/editors/CubeFilterDraft.ts +241 -0
- package/src/stores/editors/CubeIntegerText.ts +34 -0
- package/src/stores/editors/CubeJoinDraft.ts +224 -0
- package/src/stores/editors/CubeNodeDraft.ts +46 -0
- package/src/stores/editors/CubeNodeDraftRegistry.ts +83 -0
- package/src/stores/editors/CubeRenameDraft.ts +110 -0
- package/src/stores/editors/CubeRestrictDraft.ts +83 -0
- package/src/stores/editors/CubeRowCountDraft.ts +69 -0
- package/src/stores/editors/CubeSliceDraft.ts +87 -0
- package/src/stores/editors/CubeSortDraft.ts +135 -0
- package/src/stores/fixtures/CubeNorthwindModel.ts +355 -0
- package/tsconfig.json +133 -0
|
@@ -0,0 +1,275 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2026-present, Goldman Sachs
|
|
3
|
+
*
|
|
4
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
* you may not use this file except in compliance with the License.
|
|
6
|
+
* You may obtain a copy of the License at
|
|
7
|
+
*
|
|
8
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
*
|
|
10
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
* See the License for the specific language governing permissions and
|
|
14
|
+
* limitations under the License.
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
import { PanelLoadingIndicator } from '@finos/legend-art';
|
|
18
|
+
import { flowResult } from 'mobx';
|
|
19
|
+
import { observer } from 'mobx-react-lite';
|
|
20
|
+
import { useState } from 'react';
|
|
21
|
+
import { EXECUTE_SHORTCUT_LABEL } from '../../__lib__/LegendCubeCommand.js';
|
|
22
|
+
import {
|
|
23
|
+
CUBE_PENDING_LABEL,
|
|
24
|
+
formatDisabledReasons,
|
|
25
|
+
getRowLimitError,
|
|
26
|
+
getTruncationMessage,
|
|
27
|
+
ROW_LIMIT_WARNING_THRESHOLD,
|
|
28
|
+
} from '../../__lib__/LegendCubeLabels.js';
|
|
29
|
+
import { LEGEND_CUBE_TEST_ID } from '../../__lib__/LegendCubeTesting.js';
|
|
30
|
+
import type { CubeEditorState } from '../../stores/CubeEditorState.js';
|
|
31
|
+
import { CubeButton } from '../CubeButton.js';
|
|
32
|
+
import { CubeResultGrid } from './CubeResultGrid.js';
|
|
33
|
+
import { formatDuration } from './CubeGridValues.js';
|
|
34
|
+
|
|
35
|
+
/** The first line of an error is shown, at most this long; the rest is under Details */
|
|
36
|
+
const MAX_ERROR_LINE_LENGTH = 500;
|
|
37
|
+
|
|
38
|
+
const CubeRowLimitInput = observer(
|
|
39
|
+
(props: { editorState: CubeEditorState }) => {
|
|
40
|
+
const { editorState } = props;
|
|
41
|
+
const [draft, setDraft] = useState(String(editorState.rowLimit));
|
|
42
|
+
const [error, setError] = useState<string | undefined>();
|
|
43
|
+
const commit = (): void => {
|
|
44
|
+
const problem = getRowLimitError(draft);
|
|
45
|
+
setError(problem);
|
|
46
|
+
if (!problem) {
|
|
47
|
+
editorState.setRowLimit(Number(draft.trim()));
|
|
48
|
+
}
|
|
49
|
+
};
|
|
50
|
+
return (
|
|
51
|
+
<div className="flex items-center gap-1">
|
|
52
|
+
<label className="flex items-center gap-1 text-base">
|
|
53
|
+
Rows
|
|
54
|
+
<input
|
|
55
|
+
className="h-6 w-20 rounded-sm border border-[var(--color-border-default)] bg-[var(--color-bg-input)] px-1 text-right text-base text-[var(--color-text-primary)]"
|
|
56
|
+
aria-label="Row limit"
|
|
57
|
+
aria-invalid={error !== undefined}
|
|
58
|
+
value={draft}
|
|
59
|
+
onChange={(event) => setDraft(event.target.value)}
|
|
60
|
+
onBlur={commit}
|
|
61
|
+
onKeyDown={(event) => {
|
|
62
|
+
if (event.key === 'Enter') {
|
|
63
|
+
commit();
|
|
64
|
+
}
|
|
65
|
+
}}
|
|
66
|
+
/>
|
|
67
|
+
</label>
|
|
68
|
+
{error !== undefined && (
|
|
69
|
+
<span
|
|
70
|
+
className="text-sm text-[var(--color-status-error)]"
|
|
71
|
+
role="alert"
|
|
72
|
+
>
|
|
73
|
+
{error}
|
|
74
|
+
</span>
|
|
75
|
+
)}
|
|
76
|
+
{error === undefined &&
|
|
77
|
+
editorState.rowLimit > ROW_LIMIT_WARNING_THRESHOLD && (
|
|
78
|
+
<span className="text-sm text-[var(--color-status-warn)]">
|
|
79
|
+
A large row limit can slow the page down.
|
|
80
|
+
</span>
|
|
81
|
+
)}
|
|
82
|
+
</div>
|
|
83
|
+
);
|
|
84
|
+
},
|
|
85
|
+
);
|
|
86
|
+
|
|
87
|
+
const CubeGridToolbar = observer(
|
|
88
|
+
(props: {
|
|
89
|
+
editorState: CubeEditorState;
|
|
90
|
+
showSql: boolean;
|
|
91
|
+
onToggleSql: () => void;
|
|
92
|
+
}) => {
|
|
93
|
+
const { editorState, showSql, onToggleSql } = props;
|
|
94
|
+
const { execution, host } = editorState;
|
|
95
|
+
const { applicationStore } = host;
|
|
96
|
+
const { result } = execution;
|
|
97
|
+
const disabledReasons = execution.disabledReasons;
|
|
98
|
+
const execute = (): void => {
|
|
99
|
+
flowResult(execution.execute()).catch(
|
|
100
|
+
applicationStore.alertUnhandledError,
|
|
101
|
+
);
|
|
102
|
+
};
|
|
103
|
+
return (
|
|
104
|
+
<div
|
|
105
|
+
className="flex h-8 shrink-0 items-center gap-3 border-b border-[var(--color-border-default)] bg-[var(--color-bg-panel-header)] px-2"
|
|
106
|
+
data-testid={LEGEND_CUBE_TEST_ID.GRID_TOOLBAR}
|
|
107
|
+
>
|
|
108
|
+
{execution.isRunning ? (
|
|
109
|
+
<CubeButton title="Stop the run" onClick={() => execution.stop()}>
|
|
110
|
+
Stop
|
|
111
|
+
</CubeButton>
|
|
112
|
+
) : (
|
|
113
|
+
<CubeButton
|
|
114
|
+
primary={true}
|
|
115
|
+
disabled={!execution.canExecute}
|
|
116
|
+
title={
|
|
117
|
+
disabledReasons.length
|
|
118
|
+
? `${formatDisabledReasons(disabledReasons)}\n(${EXECUTE_SHORTCUT_LABEL})`
|
|
119
|
+
: `Run the query up to the selected node (${EXECUTE_SHORTCUT_LABEL})`
|
|
120
|
+
}
|
|
121
|
+
onClick={execute}
|
|
122
|
+
>
|
|
123
|
+
Execute
|
|
124
|
+
</CubeButton>
|
|
125
|
+
)}
|
|
126
|
+
<CubeRowLimitInput editorState={editorState} />
|
|
127
|
+
{execution.isRunning && (
|
|
128
|
+
<span className="text-base text-[var(--color-text-secondary)]">
|
|
129
|
+
{CUBE_PENDING_LABEL.EXECUTING_QUERY}
|
|
130
|
+
</span>
|
|
131
|
+
)}
|
|
132
|
+
{execution.isStale && (
|
|
133
|
+
<span
|
|
134
|
+
className="rounded-sm bg-[var(--color-status-warn-bg)] px-1 text-base text-[var(--color-status-warn)]"
|
|
135
|
+
title="The query or the row limit changed since this run"
|
|
136
|
+
>
|
|
137
|
+
Stale: execute again to refresh
|
|
138
|
+
</span>
|
|
139
|
+
)}
|
|
140
|
+
{result && !execution.isRunning && (
|
|
141
|
+
<>
|
|
142
|
+
<span className="text-base text-[var(--color-text-secondary)]">
|
|
143
|
+
{`${result.rows.length.toLocaleString('en-US')} row${result.rows.length === 1 ? '' : 's'} in ${formatDuration(result.durationMs)}`}
|
|
144
|
+
</span>
|
|
145
|
+
{result.limited && (
|
|
146
|
+
<span className="text-base text-[var(--color-status-warn)]">
|
|
147
|
+
{getTruncationMessage(result.rowLimit)}
|
|
148
|
+
</span>
|
|
149
|
+
)}
|
|
150
|
+
{result.sql.length > 0 && (
|
|
151
|
+
<CubeButton aria-expanded={showSql} onClick={onToggleSql}>
|
|
152
|
+
{showSql ? 'Hide SQL' : 'Show SQL'}
|
|
153
|
+
</CubeButton>
|
|
154
|
+
)}
|
|
155
|
+
</>
|
|
156
|
+
)}
|
|
157
|
+
</div>
|
|
158
|
+
);
|
|
159
|
+
},
|
|
160
|
+
);
|
|
161
|
+
|
|
162
|
+
/** The SQL the run's database ran, with Copy */
|
|
163
|
+
const CubeSqlPanel = observer((props: { editorState: CubeEditorState }) => {
|
|
164
|
+
const { editorState } = props;
|
|
165
|
+
const { applicationStore } = editorState.host;
|
|
166
|
+
const sql = editorState.execution.result?.sql ?? [];
|
|
167
|
+
if (!sql.length) {
|
|
168
|
+
return null;
|
|
169
|
+
}
|
|
170
|
+
const copySql = (): void => {
|
|
171
|
+
applicationStore.clipboardService
|
|
172
|
+
.copyTextToClipboard(sql.join('\n\n'))
|
|
173
|
+
.catch(applicationStore.alertUnhandledError);
|
|
174
|
+
};
|
|
175
|
+
return (
|
|
176
|
+
<div
|
|
177
|
+
className="flex max-h-40 shrink-0 gap-2 overflow-auto border-b border-[var(--color-border-default)] p-2"
|
|
178
|
+
data-testid={LEGEND_CUBE_TEST_ID.SQL_PANEL}
|
|
179
|
+
>
|
|
180
|
+
<div className="min-w-0 flex-1">
|
|
181
|
+
{sql.map((statement, index) => (
|
|
182
|
+
<pre
|
|
183
|
+
// statements hold no state, and the same one may run twice
|
|
184
|
+
// eslint-disable-next-line react/no-array-index-key
|
|
185
|
+
key={index}
|
|
186
|
+
className="whitespace-pre-wrap font-mono text-sm"
|
|
187
|
+
>
|
|
188
|
+
{statement}
|
|
189
|
+
</pre>
|
|
190
|
+
))}
|
|
191
|
+
</div>
|
|
192
|
+
<CubeButton onClick={copySql}>Copy SQL</CubeButton>
|
|
193
|
+
</div>
|
|
194
|
+
);
|
|
195
|
+
});
|
|
196
|
+
|
|
197
|
+
const CubeExecutionError = observer(
|
|
198
|
+
(props: { editorState: CubeEditorState }) => {
|
|
199
|
+
const error = props.editorState.execution.error;
|
|
200
|
+
if (!error) {
|
|
201
|
+
return null;
|
|
202
|
+
}
|
|
203
|
+
const isCut = error.firstLine.length > MAX_ERROR_LINE_LENGTH;
|
|
204
|
+
const firstLine = isCut
|
|
205
|
+
? `${error.firstLine.slice(0, MAX_ERROR_LINE_LENGTH)}…`
|
|
206
|
+
: error.firstLine;
|
|
207
|
+
return (
|
|
208
|
+
<div
|
|
209
|
+
className="m-2 rounded-sm border border-[var(--color-status-error)] bg-[var(--color-status-error-bg)] p-2 text-base"
|
|
210
|
+
data-testid={LEGEND_CUBE_TEST_ID.EXECUTION_ERROR}
|
|
211
|
+
role="alert"
|
|
212
|
+
>
|
|
213
|
+
<div
|
|
214
|
+
className="font-medium text-[var(--color-status-error)]"
|
|
215
|
+
title={isCut ? error.firstLine : undefined}
|
|
216
|
+
>
|
|
217
|
+
{firstLine}
|
|
218
|
+
</div>
|
|
219
|
+
{(isCut || error.detail !== error.firstLine) && (
|
|
220
|
+
<details className="mt-1">
|
|
221
|
+
<summary className="cursor-pointer text-[var(--color-text-secondary)]">
|
|
222
|
+
Details
|
|
223
|
+
</summary>
|
|
224
|
+
<pre className="mt-1 max-h-60 overflow-auto whitespace-pre-wrap text-sm">
|
|
225
|
+
{error.detail}
|
|
226
|
+
</pre>
|
|
227
|
+
</details>
|
|
228
|
+
)}
|
|
229
|
+
</div>
|
|
230
|
+
);
|
|
231
|
+
},
|
|
232
|
+
);
|
|
233
|
+
|
|
234
|
+
/** The results: Execute, the row limit and the run's stats above the grid (PLAN §9) */
|
|
235
|
+
export const CubeGridRegion = observer(
|
|
236
|
+
(props: { editorState: CubeEditorState }) => {
|
|
237
|
+
const { editorState } = props;
|
|
238
|
+
const { execution, host } = editorState;
|
|
239
|
+
const [showSql, setShowSql] = useState(false);
|
|
240
|
+
const darkMode =
|
|
241
|
+
!host.applicationStore.layoutService.TEMPORARY__isLightColorThemeEnabled;
|
|
242
|
+
return (
|
|
243
|
+
<div
|
|
244
|
+
className="flex h-full flex-col bg-[var(--color-bg-panel)]"
|
|
245
|
+
data-testid={LEGEND_CUBE_TEST_ID.GRID_REGION}
|
|
246
|
+
>
|
|
247
|
+
<PanelLoadingIndicator isLoading={execution.isRunning} />
|
|
248
|
+
<CubeGridToolbar
|
|
249
|
+
editorState={editorState}
|
|
250
|
+
showSql={showSql}
|
|
251
|
+
onToggleSql={() => setShowSql(!showSql)}
|
|
252
|
+
/>
|
|
253
|
+
{showSql && !execution.isRunning && (
|
|
254
|
+
<CubeSqlPanel editorState={editorState} />
|
|
255
|
+
)}
|
|
256
|
+
<div className="min-h-0 flex-1">
|
|
257
|
+
{execution.error ? (
|
|
258
|
+
<CubeExecutionError editorState={editorState} />
|
|
259
|
+
) : execution.result ? (
|
|
260
|
+
<CubeResultGrid
|
|
261
|
+
key={execution.result.id}
|
|
262
|
+
editorState={editorState}
|
|
263
|
+
result={execution.result}
|
|
264
|
+
darkMode={darkMode}
|
|
265
|
+
/>
|
|
266
|
+
) : (
|
|
267
|
+
<div className="flex h-full items-center justify-center text-base text-[var(--color-text-secondary)]">
|
|
268
|
+
Execute the query to see its rows.
|
|
269
|
+
</div>
|
|
270
|
+
)}
|
|
271
|
+
</div>
|
|
272
|
+
</div>
|
|
273
|
+
);
|
|
274
|
+
},
|
|
275
|
+
);
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2026-present, Goldman Sachs
|
|
3
|
+
*
|
|
4
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
* you may not use this file except in compliance with the License.
|
|
6
|
+
* You may obtain a copy of the License at
|
|
7
|
+
*
|
|
8
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
*
|
|
10
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
* See the License for the specific language governing permissions and
|
|
14
|
+
* limitations under the License.
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
import { TypeFamily } from '@finos/legend-cube';
|
|
18
|
+
import type { CubeResultValue } from '../../graph-manager/CubeEngine.js';
|
|
19
|
+
|
|
20
|
+
// How the grid shows and sorts values (PLAN §9, Settled before M1.8).
|
|
21
|
+
// Integer and Decimal values arrive as their exact text and are never turned
|
|
22
|
+
// into JS numbers, which would lose digits.
|
|
23
|
+
|
|
24
|
+
const NUMERIC_FAMILIES: ReadonlySet<TypeFamily> = new Set([
|
|
25
|
+
TypeFamily.INTEGER,
|
|
26
|
+
TypeFamily.FLOAT,
|
|
27
|
+
TypeFamily.DECIMAL,
|
|
28
|
+
TypeFamily.NUMBER,
|
|
29
|
+
]);
|
|
30
|
+
|
|
31
|
+
export const isNumericFamily = (family: TypeFamily): boolean =>
|
|
32
|
+
NUMERIC_FAMILIES.has(family);
|
|
33
|
+
|
|
34
|
+
const NUMBER_TEXT =
|
|
35
|
+
/^(?<sign>[+-]?)(?<whole>\d*)(?:\.(?<fraction>\d*))?(?:[eE](?<exponent>[+-]?\d+))?$/u;
|
|
36
|
+
|
|
37
|
+
/** A number's text as sign, digits without leading or trailing zeros, and the position of the decimal point */
|
|
38
|
+
const parseNumberText = (
|
|
39
|
+
text: string,
|
|
40
|
+
): { negative: boolean; digits: string; point: number } | undefined => {
|
|
41
|
+
const groups = NUMBER_TEXT.exec(text.trim())?.groups;
|
|
42
|
+
if (!groups || (!groups.whole && !groups.fraction)) {
|
|
43
|
+
return undefined;
|
|
44
|
+
}
|
|
45
|
+
const {
|
|
46
|
+
sign,
|
|
47
|
+
whole = '',
|
|
48
|
+
fraction = '',
|
|
49
|
+
exponent = '0',
|
|
50
|
+
} = groups as Partial<Record<string, string>>;
|
|
51
|
+
const allDigits = whole + fraction;
|
|
52
|
+
const leadingZeros = allDigits.length - allDigits.replace(/^0+/u, '').length;
|
|
53
|
+
const digits = allDigits.slice(leadingZeros).replace(/0+$/u, '');
|
|
54
|
+
return {
|
|
55
|
+
negative: sign === '-' && digits !== '',
|
|
56
|
+
digits,
|
|
57
|
+
point: whole.length - leadingZeros + Number(exponent),
|
|
58
|
+
};
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
const compareMagnitudes = (
|
|
62
|
+
left: { digits: string; point: number },
|
|
63
|
+
right: { digits: string; point: number },
|
|
64
|
+
): number => {
|
|
65
|
+
if (!left.digits || !right.digits) {
|
|
66
|
+
return (left.digits ? 1 : 0) - (right.digits ? 1 : 0);
|
|
67
|
+
}
|
|
68
|
+
if (left.point !== right.point) {
|
|
69
|
+
return left.point < right.point ? -1 : 1;
|
|
70
|
+
}
|
|
71
|
+
const length = Math.max(left.digits.length, right.digits.length);
|
|
72
|
+
const a = left.digits.padEnd(length, '0');
|
|
73
|
+
const b = right.digits.padEnd(length, '0');
|
|
74
|
+
return a === b ? 0 : a < b ? -1 : 1;
|
|
75
|
+
};
|
|
76
|
+
|
|
77
|
+
/** Compares two numbers written as text, digit for digit: `'9' < '10'`, `'9007199254740993' > '9007199254740992'` */
|
|
78
|
+
export const compareNumberText = (left: string, right: string): number => {
|
|
79
|
+
const a = parseNumberText(left);
|
|
80
|
+
const b = parseNumberText(right);
|
|
81
|
+
if (!a || !b) {
|
|
82
|
+
// not a number: keep a stable order by text
|
|
83
|
+
return left < right ? -1 : left > right ? 1 : 0;
|
|
84
|
+
}
|
|
85
|
+
if (a.negative !== b.negative) {
|
|
86
|
+
return a.negative ? -1 : 1;
|
|
87
|
+
}
|
|
88
|
+
const magnitude = compareMagnitudes(a, b);
|
|
89
|
+
return a.negative ? -magnitude : magnitude;
|
|
90
|
+
};
|
|
91
|
+
|
|
92
|
+
/** Orders a column's values: nulls first, then numbers by value whether they are JS numbers or exact text */
|
|
93
|
+
export const compareCellValues = (
|
|
94
|
+
left: CubeResultValue | undefined,
|
|
95
|
+
right: CubeResultValue | undefined,
|
|
96
|
+
): number => {
|
|
97
|
+
if (
|
|
98
|
+
left === null ||
|
|
99
|
+
left === undefined ||
|
|
100
|
+
right === null ||
|
|
101
|
+
right === undefined
|
|
102
|
+
) {
|
|
103
|
+
return (left ?? null) === null ? ((right ?? null) === null ? 0 : -1) : 1;
|
|
104
|
+
}
|
|
105
|
+
if (typeof left === 'number' && typeof right === 'number') {
|
|
106
|
+
return left - right;
|
|
107
|
+
}
|
|
108
|
+
if (
|
|
109
|
+
(typeof left === 'string' || typeof left === 'number') &&
|
|
110
|
+
(typeof right === 'string' || typeof right === 'number')
|
|
111
|
+
) {
|
|
112
|
+
return compareNumberText(String(left), String(right));
|
|
113
|
+
}
|
|
114
|
+
return String(left) < String(right)
|
|
115
|
+
? -1
|
|
116
|
+
: String(left) > String(right)
|
|
117
|
+
? 1
|
|
118
|
+
: 0;
|
|
119
|
+
};
|
|
120
|
+
|
|
121
|
+
/** A run's duration for the toolbar: milliseconds under a second, else seconds */
|
|
122
|
+
export const formatDuration = (durationMs: number): string =>
|
|
123
|
+
durationMs < 1000
|
|
124
|
+
? `${Math.round(durationMs)} ms`
|
|
125
|
+
: `${(durationMs / 1000).toFixed(1)} s`;
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2026-present, Goldman Sachs
|
|
3
|
+
*
|
|
4
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
* you may not use this file except in compliance with the License.
|
|
6
|
+
* You may obtain a copy of the License at
|
|
7
|
+
*
|
|
8
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
*
|
|
10
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
* See the License for the specific language governing permissions and
|
|
14
|
+
* limitations under the License.
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
import { clsx } from '@finos/legend-art';
|
|
18
|
+
import {
|
|
19
|
+
DataGrid,
|
|
20
|
+
type DataGridCellRendererParams,
|
|
21
|
+
type DataGridColumnDefinition,
|
|
22
|
+
type DataGridDefaultMenuItem,
|
|
23
|
+
type DataGridGetContextMenuItemsParams,
|
|
24
|
+
type DataGridMenuItemDef,
|
|
25
|
+
} from '@finos/legend-lego/data-grid';
|
|
26
|
+
import { memo, useCallback, useMemo } from 'react';
|
|
27
|
+
import { NULL_CELL_TEXT } from '../../__lib__/LegendCubeLabels.js';
|
|
28
|
+
import { LEGEND_CUBE_TEST_ID } from '../../__lib__/LegendCubeTesting.js';
|
|
29
|
+
import type { CubeResultValue } from '../../graph-manager/CubeEngine.js';
|
|
30
|
+
import type { CubeEditorState } from '../../stores/CubeEditorState.js';
|
|
31
|
+
import type { CubeExecutionResult } from '../../stores/CubeExecutionState.js';
|
|
32
|
+
import { getCubeGridQuickActions } from '../../stores/CubeGridQuickActions.js';
|
|
33
|
+
import { compareCellValues, isNumericFamily } from './CubeGridValues.js';
|
|
34
|
+
|
|
35
|
+
type CubeRow = readonly CubeResultValue[];
|
|
36
|
+
|
|
37
|
+
/** A column's id in the grid: its position, as `c<position>` */
|
|
38
|
+
const COLUMN_ID_PREFIX = 'c';
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* The grid's context menu (spec §12.4): on a cell, its quick actions, then
|
|
42
|
+
* ag-grid's own items, which M7 curates; elsewhere ag-grid's only. Read when
|
|
43
|
+
* the menu opens, so it reflects the cube and the run as they are then.
|
|
44
|
+
*/
|
|
45
|
+
export const getCubeGridContextMenuItems = (
|
|
46
|
+
editorState: CubeEditorState,
|
|
47
|
+
params: DataGridGetContextMenuItemsParams<CubeRow>,
|
|
48
|
+
): (DataGridDefaultMenuItem | DataGridMenuItemDef<CubeRow>)[] => {
|
|
49
|
+
const defaultItems = params.defaultItems ?? [];
|
|
50
|
+
const colId = params.column?.getColId();
|
|
51
|
+
if (!colId?.startsWith(COLUMN_ID_PREFIX)) {
|
|
52
|
+
return defaultItems;
|
|
53
|
+
}
|
|
54
|
+
const position = Number(colId.slice(COLUMN_ID_PREFIX.length));
|
|
55
|
+
const cell = params.node?.data?.[position] ?? null;
|
|
56
|
+
const actions = getCubeGridQuickActions(editorState, position, cell);
|
|
57
|
+
if (!actions.length) {
|
|
58
|
+
return defaultItems;
|
|
59
|
+
}
|
|
60
|
+
return [
|
|
61
|
+
...actions.map((quickAction): DataGridMenuItemDef<CubeRow> => {
|
|
62
|
+
const tooltip = quickAction.disabledReason ?? quickAction.hint;
|
|
63
|
+
return {
|
|
64
|
+
name: quickAction.label,
|
|
65
|
+
disabled: quickAction.disabledReason !== undefined,
|
|
66
|
+
...(tooltip === undefined ? {} : { tooltip }),
|
|
67
|
+
action: () => quickAction.apply(),
|
|
68
|
+
};
|
|
69
|
+
}),
|
|
70
|
+
'separator',
|
|
71
|
+
...defaultItems,
|
|
72
|
+
];
|
|
73
|
+
};
|
|
74
|
+
|
|
75
|
+
const CubeCell: React.FC<
|
|
76
|
+
DataGridCellRendererParams<CubeRow, CubeResultValue>
|
|
77
|
+
> = (props) =>
|
|
78
|
+
props.value === null || props.value === undefined ? (
|
|
79
|
+
<span className="text-[var(--color-text-muted)]">{NULL_CELL_TEXT}</span>
|
|
80
|
+
) : (
|
|
81
|
+
<>{String(props.value)}</>
|
|
82
|
+
);
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* The rows of a run (PLAN §9): columns from Cube's own schema of the capture
|
|
86
|
+
* node, by position, so any column name works. Numbers are right-aligned and
|
|
87
|
+
* shown and sorted exactly as the engine wrote them. A cell's context menu
|
|
88
|
+
* offers the quick actions (`getCubeGridContextMenuItems`).
|
|
89
|
+
*/
|
|
90
|
+
export const CubeResultGrid = memo(
|
|
91
|
+
(props: {
|
|
92
|
+
editorState: CubeEditorState;
|
|
93
|
+
result: CubeExecutionResult;
|
|
94
|
+
darkMode: boolean;
|
|
95
|
+
}) => {
|
|
96
|
+
const { editorState, result, darkMode } = props;
|
|
97
|
+
const getContextMenuItems = useCallback(
|
|
98
|
+
(params: DataGridGetContextMenuItemsParams<CubeRow>) =>
|
|
99
|
+
getCubeGridContextMenuItems(editorState, params),
|
|
100
|
+
[editorState],
|
|
101
|
+
);
|
|
102
|
+
const columnDefs = useMemo(
|
|
103
|
+
(): DataGridColumnDefinition<CubeRow, CubeResultValue>[] =>
|
|
104
|
+
result.schema.columns.map((column, position) => {
|
|
105
|
+
const numeric = isNumericFamily(column.type.family);
|
|
106
|
+
return {
|
|
107
|
+
colId: `${COLUMN_ID_PREFIX}${position}`,
|
|
108
|
+
headerName: column.name,
|
|
109
|
+
headerTooltip: `${column.type.displayName}${column.nullable ? '?' : ''} (${column.type.fullName})`,
|
|
110
|
+
valueGetter: (params) => params.data?.[position] ?? null,
|
|
111
|
+
cellRenderer: CubeCell,
|
|
112
|
+
...(numeric
|
|
113
|
+
? { type: 'rightAligned', comparator: compareCellValues }
|
|
114
|
+
: {}),
|
|
115
|
+
};
|
|
116
|
+
}),
|
|
117
|
+
[result],
|
|
118
|
+
);
|
|
119
|
+
return (
|
|
120
|
+
<div
|
|
121
|
+
className={clsx('h-full w-full', {
|
|
122
|
+
'ag-theme-balham': !darkMode,
|
|
123
|
+
'ag-theme-balham-dark': darkMode,
|
|
124
|
+
})}
|
|
125
|
+
data-testid={LEGEND_CUBE_TEST_ID.RESULT_GRID}
|
|
126
|
+
>
|
|
127
|
+
<DataGrid<CubeRow>
|
|
128
|
+
rowData={result.rows as CubeRow[]}
|
|
129
|
+
columnDefs={columnDefs}
|
|
130
|
+
suppressFieldDotNotation={true}
|
|
131
|
+
tooltipShowDelay={500}
|
|
132
|
+
getContextMenuItems={getContextMenuItems}
|
|
133
|
+
/>
|
|
134
|
+
</div>
|
|
135
|
+
);
|
|
136
|
+
},
|
|
137
|
+
);
|
|
138
|
+
CubeResultGrid.displayName = 'CubeResultGrid';
|