Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

kie-issues#970: Test Scenario Editor: Integrate the @kie-tools/scesim-editor component with the DMN Marshaller #2887

Merged
merged 77 commits into from
Feb 21, 2025
Merged
Show file tree
Hide file tree
Changes from 71 commits
Commits
Show all changes
77 commits
Select commit Hold shift + click to select a range
feb751e
WIP
yesamer Jan 22, 2025
6560d45
WIP
yesamer Jan 22, 2025
3771e8b
WIP
yesamer Jan 22, 2025
c6a8c29
Merge branch 'refs/heads/main' into kie-issues#970-3
yesamer Jan 23, 2025
2b6b358
WIP
yesamer Jan 23, 2025
d28cf52
Fix pattern GLOB
yesamer Jan 23, 2025
71c42a4
WIP
yesamer Jan 24, 2025
9eb83ae
Merge remote-tracking branch 'origin/main' into kie-issues#970-3
yesamer Jan 27, 2025
8112b77
MINOR
yesamer Jan 27, 2025
7ea29ee
WIP
yesamer Jan 28, 2025
2cbe85c
WIP
yesamer Jan 28, 2025
71f854b
WIP
yesamer Jan 28, 2025
1f90c5c
Merge remote-tracking branch 'origin/main' into kie-issues#970-3
yesamer Jan 29, 2025
57d4dbf
WIP
yesamer Jan 29, 2025
1362430
WIP
yesamer Jan 29, 2025
75e1f4b
WIP
yesamer Jan 29, 2025
516baac
Merge remote-tracking branch 'origin/main' into kie-issues#970-3
yesamer Jan 30, 2025
5f95d96
WIP
yesamer Jan 30, 2025
a22aac4
WIP
yesamer Jan 30, 2025
b2bf698
WIP
yesamer Jan 30, 2025
bcb5210
WIP
yesamer Jan 30, 2025
ff07116
WIP
yesamer Jan 30, 2025
d99db0a
Merge remote-tracking branch 'origin/main' into kie-issues#970-3
yesamer Jan 30, 2025
b65eb08
Merge remote-tracking branch 'origin/main' into kie-issues#970-3
yesamer Feb 3, 2025
bfa70fe
WIP
yesamer Feb 3, 2025
925506f
WIP
yesamer Feb 3, 2025
2cb9302
Tests
yesamer Feb 3, 2025
6f94e8b
WIP
yesamer Feb 3, 2025
2e2800f
WIP
yesamer Feb 3, 2025
3c3f36b
WIP
yesamer Feb 3, 2025
32cb2d9
WIP
yesamer Feb 3, 2025
86b67f6
WIP
yesamer Feb 3, 2025
3c7454b
WIP
yesamer Feb 3, 2025
abcdac3
WIP
yesamer Feb 3, 2025
7c70f0c
Merge remote-tracking branch 'origin/main' into kie-issues#970-3
yesamer Feb 4, 2025
1691f0c
WIP
yesamer Feb 4, 2025
93ab389
WIP
yesamer Feb 4, 2025
985f7c7
WIP
yesamer Feb 5, 2025
0d913cd
WIP
yesamer Feb 5, 2025
92cde17
WIP
yesamer Feb 5, 2025
96c3b39
Merge remote-tracking branch 'origin/main' into kie-issues#970-3
yesamer Feb 6, 2025
11e6a53
Add Simple story (#9)
ljmotta Feb 7, 2025
8cc7d6f
WIP
yesamer Feb 7, 2025
0b7035a
WIP
yesamer Feb 7, 2025
30fd0ad
WIP
yesamer Feb 7, 2025
b5c8f6a
1807
yesamer Feb 7, 2025
661cfdd
1807
yesamer Feb 7, 2025
142f44b
WIP
yesamer Feb 7, 2025
fa97f93
Merge remote-tracking branch 'origin/main' into kie-issues#970-3
yesamer Feb 10, 2025
5d6fb73
WIP
yesamer Feb 10, 2025
24d73b7
WIP
yesamer Feb 10, 2025
8d16192
WIP
yesamer Feb 10, 2025
653c059
WIP
yesamer Feb 10, 2025
8697f1b
Tests
yesamer Feb 10, 2025
2a258c3
WIP
yesamer Feb 10, 2025
eb22475
Tests
yesamer Feb 10, 2025
263de2f
WIP
yesamer Feb 10, 2025
6006626
WIP
yesamer Feb 10, 2025
b5b0c47
WIP
yesamer Feb 11, 2025
68a9b05
WIP
yesamer Feb 11, 2025
ec1ef16
WIP
yesamer Feb 11, 2025
f45ec5f
WIP
yesamer Feb 11, 2025
a6fd9d4
Merge remote-tracking branch 'origin/main' into kie-issues#970-3
yesamer Feb 11, 2025
603f819
screenshots (#10)
jomarko Feb 12, 2025
7e82065
WIP
yesamer Feb 12, 2025
4d5fd2a
Minor
yesamer Feb 12, 2025
23517bb
Merge remote-tracking branch 'yeser/kie-issues#970-3' into kie-issues…
yesamer Feb 12, 2025
6e7f14b
WIP
yesamer Feb 12, 2025
4db5b8c
Revert
yesamer Feb 12, 2025
7bf5810
Revert
yesamer Feb 12, 2025
d243595
Merge remote-tracking branch 'origin/main' into kie-issues#970-3
yesamer Feb 13, 2025
0cabd76
CR
yesamer Feb 18, 2025
1c18f08
Merge remote-tracking branch 'origin/main' into kie-issues#970-3
yesamer Feb 18, 2025
af44039
CR
yesamer Feb 18, 2025
abb08e3
Fix
yesamer Feb 18, 2025
06132ea
CR
yesamer Feb 20, 2025
d3c3fa9
Merge remote-tracking branch 'origin/main' into kie-issues#970-3
yesamer Feb 21, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
62 changes: 31 additions & 31 deletions packages/scesim-editor-envelope/src/TestScenarioEditorRoot.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ import * as TestScenarioEditor from "@kie-tools/scesim-editor/dist/TestScenarioE
import { getMarshaller, SceSimMarshaller, SceSimModel } from "@kie-tools/scesim-marshaller";
import { EMPTY_ONE_EIGHT } from "@kie-tools/scesim-editor/dist/resources/EmptyScesimFile";

export const DMN_MODELS_SEARCH_GLOB_PATTERN = "**/*.{dmn}";
export const DMN_MODELS_SEARCH_GLOB_PATTERN = "**/*.dmn";

export type TestScenarioEditorRootProps = {
exposing: (s: TestScenarioEditorRoot) => void;
Expand All @@ -58,7 +58,7 @@ export type TestScenarioEditorRootState = {
keyboardShortcutsRegistred: boolean;
keyboardShortcutsRegisterIds: number[];
marshaller: SceSimMarshaller | undefined;
openFilenormalizedPosixPathRelativeToTheWorkspaceRoot: string | undefined;
openFileNormalizedPosixPathRelativeToTheWorkspaceRoot: string | undefined;
pointer: number;
stack: SceSimModel[];
};
Expand All @@ -74,13 +74,13 @@ export class TestScenarioEditorRoot extends React.Component<TestScenarioEditorRo
this.testScenarioEditorRef = React.createRef();
this.state = {
error: undefined,
externalModelsByNamespace: {},
externalModelsByNamespace: new Map(),
externalModelsManagerDoneBootstraping: false,
isReadOnly: props.isReadOnly,
keyboardShortcutsRegisterIds: [],
keyboardShortcutsRegistred: false,
marshaller: undefined,
openFilenormalizedPosixPathRelativeToTheWorkspaceRoot: undefined,
openFileNormalizedPosixPathRelativeToTheWorkspaceRoot: undefined,
pointer: -1,
stack: [],
};
Expand Down Expand Up @@ -111,7 +111,7 @@ export class TestScenarioEditorRoot extends React.Component<TestScenarioEditorRo
}

public async setContent(
openFilenormalizedPosixPathRelativeToTheWorkspaceRoot: string,
openFileNormalizedPosixPathRelativeToTheWorkspaceRoot: string,
content: string
): Promise<void> {
const marshaller = this.getMarshaller(content);
Expand All @@ -124,7 +124,7 @@ export class TestScenarioEditorRoot extends React.Component<TestScenarioEditorRo
savedStackPointer = [...prev.stack];
return {
stack: [marshaller.parser.parse()],
openFilenormalizedPosixPathRelativeToTheWorkspaceRoot,
openFileNormalizedPosixPathRelativeToTheWorkspaceRoot,
pointer: 0,
};
});
Expand All @@ -136,14 +136,14 @@ export class TestScenarioEditorRoot extends React.Component<TestScenarioEditorRo
this.setState((prev) => {
// External change to the same file.
if (
prev.openFilenormalizedPosixPathRelativeToTheWorkspaceRoot ===
openFilenormalizedPosixPathRelativeToTheWorkspaceRoot
prev.openFileNormalizedPosixPathRelativeToTheWorkspaceRoot ===
openFileNormalizedPosixPathRelativeToTheWorkspaceRoot
) {
const newStack = savedStackPointer.slice(0, prev.pointer + 1);
return {
externalModelsManagerDoneBootstraping: true,
isReadOnly: prev.isReadOnly,
openFilenormalizedPosixPathRelativeToTheWorkspaceRoot,
openFileNormalizedPosixPathRelativeToTheWorkspaceRoot,
marshaller,
pointer: newStack.length,
stack: [...newStack, marshaller.parser.parse()],
Expand All @@ -156,7 +156,7 @@ export class TestScenarioEditorRoot extends React.Component<TestScenarioEditorRo
externalModelsManagerDoneBootstraping: true,
isReadOnly: prev.isReadOnly,
marshaller,
openFilenormalizedPosixPathRelativeToTheWorkspaceRoot,
openFileNormalizedPosixPathRelativeToTheWorkspaceRoot,
pointer: 0,
stack: [marshaller.parser.parse()],
};
Expand Down Expand Up @@ -198,14 +198,14 @@ export class TestScenarioEditorRoot extends React.Component<TestScenarioEditorRo
},
() =>
this.props.onNewEdit({
id: `${this.state.openFilenormalizedPosixPathRelativeToTheWorkspaceRoot}__${generateUuid()}`,
id: `${this.state.openFileNormalizedPosixPathRelativeToTheWorkspaceRoot}__${generateUuid()}`,
})
);
};

private onRequestExternalModelsAvailableToInclude: TestScenarioEditor.OnRequestExternalModelsAvailableToInclude =
async () => {
if (!this.state.openFilenormalizedPosixPathRelativeToTheWorkspaceRoot) {
if (!this.state.openFileNormalizedPosixPathRelativeToTheWorkspaceRoot) {
return [];
}

Expand All @@ -215,7 +215,7 @@ export class TestScenarioEditorRoot extends React.Component<TestScenarioEditorRo
});

return list.normalizedPosixPathsRelativeToTheWorkspaceRoot.flatMap((p) =>
__path.relative(__path.dirname(this.state.openFilenormalizedPosixPathRelativeToTheWorkspaceRoot!), p)
__path.relative(__path.dirname(this.state.openFileNormalizedPosixPathRelativeToTheWorkspaceRoot!), p)
);
};

Expand All @@ -224,19 +224,12 @@ export class TestScenarioEditorRoot extends React.Component<TestScenarioEditorRo
) => {
const normalizedPosixPathRelativeToTheWorkspaceRoot = __path
.resolve(
__path.dirname(this.state.openFilenormalizedPosixPathRelativeToTheWorkspaceRoot!),
__path.dirname(this.state.openFileNormalizedPosixPathRelativeToTheWorkspaceRoot!),
normalizedPosixPathRelativeToTheOpenFile
)
.substring(1); // Remove leading slash.

return normalizedPosixPathRelativeToTheWorkspaceRoot;

// Example:
// this.state.openFileAbsolutePath = /Users/ljmotta/packages/dmns/Dmn.dmn
// normalizedPosixPathRelativeToTheOpenFile = ../../tmp/Tmp.dmn
// workspaceRootAbsolutePosixPath = /Users/ljmotta
// resolvedAbsolutePath = /Users/ljmotta/tmp/Tmp.dmn
// return (which is the normalizedPosixPathRelativeToTheWorkspaceRoot) = tmp/Tmp.dmn
};

private onRequestExternalModelByPathsRelativeToTheOpenFile: TestScenarioEditor.OnRequestExternalModelByPath = async (
Expand Down Expand Up @@ -264,7 +257,7 @@ export class TestScenarioEditorRoot extends React.Component<TestScenarioEditorRo
};

private onOpenFileFromPathRelativeToTheOpenFile = (normalizedPosixPathRelativeToTheOpenFile: string) => {
if (!this.state.openFilenormalizedPosixPathRelativeToTheWorkspaceRoot) {
if (!this.state.openFileNormalizedPosixPathRelativeToTheWorkspaceRoot) {
return;
}

Expand Down Expand Up @@ -318,6 +311,7 @@ export class TestScenarioEditorRoot extends React.Component<TestScenarioEditorRo
<>
<TestScenarioEditor.TestScenarioEditor
ref={this.testScenarioEditorRef}
externalModelsByNamespace={this.state.externalModelsByNamespace}
issueTrackerHref={""}
model={this.model}
onModelChange={this.onModelChange}
Expand All @@ -326,14 +320,14 @@ export class TestScenarioEditorRoot extends React.Component<TestScenarioEditorRo
onRequestToJumpToPath={this.onOpenFileFromPathRelativeToTheOpenFile}
onRequestToResolvePath={this.onRequestToResolvePathRelativeToTheOpenFile}
openFileNormalizedPosixPathRelativeToTheWorkspaceRoot={
this.state.openFilenormalizedPosixPathRelativeToTheWorkspaceRoot
this.state.openFileNormalizedPosixPathRelativeToTheWorkspaceRoot
}
/>
{
<ExternalModelsManager
workspaceRootAbsolutePosixPath={this.props.workspaceRootAbsolutePosixPath}
thisScesimNormalizedPosixPathRelativeToTheWorkspaceRoot={
this.state.openFilenormalizedPosixPathRelativeToTheWorkspaceRoot
this.state.openFileNormalizedPosixPathRelativeToTheWorkspaceRoot
}
model={this.model}
onChange={this.setExternalModelsByNamespace}
Expand Down Expand Up @@ -371,7 +365,7 @@ function ExternalModelsManager({
return null;
}
if (model.ScenarioSimulationModel.settings.dmnNamespace?.__$$text) {
return model.ScenarioSimulationModel.settings.dmnNamespace?.__$$text.toUpperCase();
return model.ScenarioSimulationModel.settings.dmnNamespace?.__$$text;
}
return null;
}, [model.ScenarioSimulationModel.settings]);
Expand Down Expand Up @@ -437,7 +431,7 @@ function ExternalModelsManager({
return Promise.all(resources);
})
.then((resources) => {
const externalModelsIndex: TestScenarioEditor.ExternalDmnsIndex = {};
const externalModelsByNamespace: TestScenarioEditor.ExternalDmnsIndex = new Map();

for (let i = 0; i < resources.length; i++) {
const resource = resources[i];
Expand All @@ -457,29 +451,35 @@ function ExternalModelsManager({
const namespace = domParser.getDomDocument(content).documentElement.getAttribute("namespace");
if (targetNamespace && namespace === targetNamespace) {
// Check for multiplicity of namespaces on DMN models
if (externalModelsIndex[namespace]) {
if (externalModelsByNamespace.has(namespace)) {
console.warn(
`TEST SCENARIO EDITOR ROOT: Multiple DMN models encountered with the same namespace '${namespace}': '${
resource.normalizedPosixPathRelativeToTheWorkspaceRoot
}' and '${
externalModelsIndex[namespace]!.normalizedPosixPathRelativeToTheOpenFile
externalModelsByNamespace.get(namespace)!.normalizedPosixPathRelativeToTheOpenFile
}'. The latter will be considered.`
);
}

externalModelsIndex[namespace] = {
externalModelsByNamespace.set(namespace, {
normalizedPosixPathRelativeToTheOpenFile,
model: normalize(getDmnMarshaller(content, { upgradeTo: "latest" }).parser.parse()),
svg: "",
};
});
}
} else {
throw new Error(`Unknown extension '${ext}'.`);
}
}

/* If the DMN file with the targetNamespace is not found, it populates the returning externalModelsByNamespace Map
/* adding the targetNamespace key with an undefined model, to be propagated to the internal Test Scenario component */
if (targetNamespace && !externalModelsByNamespace.has(targetNamespace)) {
externalModelsByNamespace.set(targetNamespace, undefined);
}

if (!canceled) {
onChange(externalModelsIndex);
onChange(externalModelsByNamespace);
}
externalModelsManagerDoneBootstraping.resolve();
});
Expand Down
13 changes: 13 additions & 0 deletions packages/scesim-editor/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,18 @@
"description": "The Test Scenario editor, a powerful tool to create, edit and manage *.scesim files, to test DMN assets",
"license": "Apache-2.0",
"keywords": [],
"homepage": "https://github.com/apache/incubator-kie-tools",
"repository": {
"type": "git",
"url": "https://github.com/apache/incubator-kie-tools.git"
},
"bugs": {
"url": "https://github.com/apache/incubator-kie-tools/issues"
},
"files": [
"dist",
"src"
],
"scripts": {
"build:dev": "rimraf dist && pnpm copy:css && tsc -p tsconfig.json",
"build:prod": "rimraf dist && pnpm copy:css && pnpm lint && tsc -p tsconfig.json && pnpm test-e2e",
Expand All @@ -28,6 +40,7 @@
"dependencies": {
"@kie-tools-core/i18n": "workspace:*",
"@kie-tools-core/patternfly-base": "workspace:*",
"@kie-tools-core/react-hooks": "workspace:*",
"@kie-tools/boxed-expression-component": "workspace:*",
"@kie-tools/dmn-marshaller": "workspace:*",
"@kie-tools/i18n-common-dictionary": "workspace:*",
Expand Down
37 changes: 28 additions & 9 deletions packages/scesim-editor/src/TestScenarioEditor.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,10 @@ import {
} from "./store/TestScenarioStoreContext";
import { TestScenarioEditorErrorFallback } from "./TestScenarioEditorErrorFallback";
import { TestScenarioEditorContextProvider, useTestScenarioEditor } from "./TestScenarioEditorContext";
import { TestScenarioEditorExternalModelsContextProvider } from "./externalModels/TestScenarioEditorDependenciesContext";
import {
TestScenarioEditorExternalModelsContextProvider,
useExternalModels,
} from "./externalModels/TestScenarioEditorDependenciesContext";
import { useEffectAfterFirstRender } from "./hook/useEffectAfterFirstRender";
import { INITIAL_COMPUTED_CACHE } from "./store/computed/initial";

Expand Down Expand Up @@ -95,7 +98,7 @@ export type OnSceSimModelChange = (model: SceSimModel) => void;
export type OnRequestExternalModelByPath = (
normalizedPosixPathRelativeToTheOpenFile: string
) => Promise<ExternalDmn | null>;
export type ExternalDmnsIndex = Record<string /** normalizedPosixPathRelativeToTheOpenFile */, ExternalDmn | undefined>;
export type ExternalDmnsIndex = Map<string, ExternalDmn | undefined>;

export type ExternalDmn = {
model: Normalized<DmnLatestModel>;
Expand Down Expand Up @@ -165,15 +168,32 @@ export type TestScenarioSelectedColumnMetaData = {
function TestScenarioMainPanel() {
const { i18n } = useTestScenarioEditorI18n();
const { commandsRef } = useCommands();
const { externalModelsByNamespace } = useExternalModels();
const testScenarioEditorStoreApi = useTestScenarioEditorStoreApi();
const navigation = useTestScenarioEditorStore((s) => s.navigation);
const scesimModel = useTestScenarioEditorStore((s) => s.scesim.model);
const isAlertEnabled = true; // Will be managed in kie-issue#970
const navigation = useTestScenarioEditorStore((state) => state.navigation);
const scesimModel = useTestScenarioEditorStore((state) => state.scesim.model);
const testScenarioDmnNamespace = scesimModel.ScenarioSimulationModel.settings.dmnNamespace?.__$$text;
const testScenarioDmnFilePath = scesimModel.ScenarioSimulationModel.settings.dmnFilePath?.__$$text;
const testScenarioType = scesimModel.ScenarioSimulationModel.settings.type?.__$$text.toUpperCase();

const scenarioTableScrollableElementRef = useRef<HTMLDivElement | null>(null);
const backgroundTableScrollableElementRef = useRef<HTMLDivElement | null>(null);

/* RULE-based Test Scenario are still not supported. The Notification will always be active in such a case
In DMN-based Test Scenario, the notification will be active if:
- The DMN model with the target reference is missing at all
- The DMN model with the target reference is found, but in a different location */
const isMissingDataObjectsNotificationEnabled = useMemo(() => {
const isReferencedDMNFileMissing =
externalModelsByNamespace &&
externalModelsByNamespace.has(testScenarioDmnNamespace!) &&
(!externalModelsByNamespace.get(testScenarioDmnNamespace!) ||
externalModelsByNamespace.get(testScenarioDmnNamespace!)?.normalizedPosixPathRelativeToTheOpenFile !==
testScenarioDmnFilePath);

return testScenarioType === "RULE" || isReferencedDMNFileMissing;
}, [externalModelsByNamespace, testScenarioDmnFilePath, testScenarioDmnNamespace, testScenarioType]);

const onTabChanged = useCallback(
(_event, tab) => {
testScenarioEditorStoreApi.setState((state) => {
Expand Down Expand Up @@ -211,10 +231,10 @@ function TestScenarioMainPanel() {
<Drawer isExpanded={navigation.dock.isOpen} isInline={true} position={"right"}>
<DrawerContent panelContent={<TestScenarioDrawerPanel onDrawerClose={() => showDockPanel(false)} />}>
<DrawerContentBody>
{isAlertEnabled && (
{isMissingDataObjectsNotificationEnabled && (
<div className="kie-scesim-editor--content-alert">
<Alert
variant={testScenarioType === "DMN" ? "warning" : "danger"}
variant={"danger"}
title={
testScenarioType === "DMN"
? i18n.alerts.dmnDataRetrievedFromScesim
Expand Down Expand Up @@ -328,7 +348,7 @@ export const TestScenarioEditorInternal = ({
reset: () => {
console.trace("[TestScenarioEditorInternal: Reset called!");
const state = testScenarioEditorStoreApi.getState();
state.dispatch(state).scesim.reset();
state.dispatch(state).navigation.reset();
},
getCommands: () => commandsRef.current,
getDiagramSvg: async () => undefined,
Expand All @@ -349,7 +369,6 @@ export const TestScenarioEditorInternal = ({

state.scesim.model = model;
testScenarioEditorModelBeforeEditingRef.current = model;
//state.dispatch(state).scesim.reset();
});
}, [testScenarioEditorStoreApi, model]);

Expand Down
Loading
Loading