/** * Copyright (c) 2026-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 { flowResult } from 'mobx'; import { BlankPanelPlaceholder, clsx, ContextMenu, CustomSelectorInput, Dialog, MenuContent, MenuContentItem, Modal, ModalBody, ModalFooter, ModalFooterButton, ModalHeader, ModalTitle, Panel, PanelFormTextField, PanelHeader, PanelHeaderActionItem, PanelHeaderActions, PlusIcon, } from '@finos/legend-art'; import type { IngestTestableState, IngestTestSuiteState, } from '../../../../../stores/editor/editor-state/element-editor-state/ingest/IngestTestableState.js'; import { forwardRef, useRef, useState } from 'react'; import { useEditorStore } from '../../../EditorStoreProvider.js'; import { validateTestableId } from '../../../../../stores/editor/utils/TestableUtils.js'; import { RenameModal } from '../../testable/TestableSharedComponents.js'; import type { IngestTestSuite } from '@finos/legend-graph'; import { guaranteeNonNullable } from '@finos/legend-shared'; import { testSuite_setId } from '../../../../../stores/graph-modifier/Testable_GraphModifierHelper.js'; import { LakehouseTestSuiteEditor } from '../../testable/LakehouseTestableEditor.js'; // ─── Create Suite Modal ─────────────────────────────────────────────────────── interface ItemOption { value: string; label: string; } const CreateSuiteModal = observer( (props: { testableState: IngestTestableState; onClose: () => void }) => { const { testableState, onClose } = props; const editorStore = useEditorStore(); const applicationStore = editorStore.applicationStore; const inputRef = useRef(null); const [testName, setTestName] = useState(undefined); const [datasetName, setDatasetName] = useState( testableState.datasetNames[0], ); const existingIds = testableState.ingest.tests.map((suite) => suite.id); const generateSuiteName = (): string => { let idx = 1; while (existingIds.includes(`suite_${idx}`)) { idx++; } return `suite_${idx}`; }; const testError = validateTestableId(testName, undefined); const datasetOptions: ItemOption[] = testableState.datasetNames.map( (name) => ({ value: name, label: name, }), ); const selectedDatasetOption = datasetOptions.find((option) => option.value === datasetName) ?? null; const isValid = testName && !testError && datasetName; const create = (): void => { if (!testName || !datasetName) { return; } flowResult( testableState.createSuite(generateSuiteName(), testName, datasetName), ) .then((error) => { if (error) { applicationStore.notificationService.notifyError(error); } else { onClose(); } }) .catch(applicationStore.alertUnhandledError); }; return ( inputRef.current?.focus() }, paper: { classes: { root: 'search-modal__inner-container' } }, }} > setTestName(value ?? '')} errorMessage={testError} />
MatView Dataset
Select the MatView dataset tested by this first test
setDatasetName(option?.value) } value={selectedDatasetOption} placeholder="Select dataset..." isClearable={false} darkMode={true} disabled={datasetOptions.length === 0} />
); }, ); // ─── Create Test Modal ──────────────────────────────────────────────────────── const CreateTestModal = observer( (props: { suiteState: IngestTestSuiteState; onClose: () => void }) => { const { suiteState, onClose } = props; const editorStore = suiteState.editorStore; const applicationStore = editorStore.applicationStore; const inputRef = useRef(null); const existingIds = suiteState.suite.tests.map((test) => test.id); const [testName, setTestName] = useState(undefined); const [datasetName, setDatasetName] = useState( suiteState.testableState.datasetNames[0], ); const testNameError = validateTestableId(testName, existingIds); const datasetOptions: ItemOption[] = suiteState.testableState.datasetNames.map((name) => ({ value: name, label: name, })); const selectedDatasetOption = datasetOptions.find((option) => option.value === datasetName) ?? null; const isValid = testName && !testNameError && datasetName; const create = (): void => { if (!testName || !datasetName) { return; } flowResult(suiteState.addNewTest(testName, datasetName)) .then((error) => { if (error) { applicationStore.notificationService.notifyError(error); } else { onClose(); } }) .catch(applicationStore.alertUnhandledError); }; return ( inputRef.current?.focus() }, paper: { classes: { root: 'search-modal__inner-container' } }, }} > setTestName(value ?? '')} errorMessage={testNameError} />
MatView Dataset
Select which MatView dataset this test will verify
setDatasetName(option?.value) } value={selectedDatasetOption} placeholder="Select dataset..." isClearable={false} darkMode={true} disabled={datasetOptions.length === 0} />
); }, ); // ─── Suite Tab Context Menu ─────────────────────────────────────────────────── const SuiteHeaderTabContextMenu = observer( forwardRef< HTMLDivElement, { testSuite: IngestTestSuite; testableState: IngestTestableState; } >(function SuiteHeaderTabContextMenu(props, ref) { const { testSuite, testableState } = props; const deleteSuite = (): void => { const suiteState = testableState.suiteStates.find( (state) => state.suite === testSuite, ); if (suiteState) { testableState.deleteSuite(suiteState); } }; const rename = (): void => testableState.setSuiteToRename(testSuite); return ( Rename Delete ); }), ); // ─── Main Testing Tab ───────────────────────────────────────────────────────── export const IngestTestableEditor = observer( (props: { testableState: IngestTestableState }) => { const { testableState } = props; const selectedSuiteState = testableState.selectedSuiteState; const isReadOnly = testableState.ingestDefinitionEditorState.isReadOnly; const ingest = testableState.ingest; const addSuite = (): void => { testableState.setShowCreateSuiteModal(true); }; const changeSuite = (suite: IngestTestSuite): void => { testableState.changeSuite(suite); }; const renameSuite = (value: string): void => testSuite_setId(guaranteeNonNullable(testableState.suiteToRename), value); return ( {testableState.showCreateSuiteModal && ( testableState.setShowCreateSuiteModal(false)} /> )} {testableState.showCreateTestModal && selectedSuiteState && ( testableState.setShowCreateTestModal(false)} /> )} {ingest.tests.length ? (
{ingest.tests.map((suite) => (
changeSuite(suite)} className={clsx('service-test-suite-editor__tab', { 'service-test-suite-editor__tab--active': selectedSuiteState?.suite === suite, })} > } > {suite.id}
))}
) : (
)}
{selectedSuiteState && ( )} {!ingest.tests.length && ( )} {testableState.suiteToRename && ( testableState.setSuiteToRename(undefined)} setValue={renameSuite} /> )}
); }, );