This is an automated email from the ASF dual-hosted git repository.

tiagobento pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/incubator-kie-tools.git


The following commit(s) were added to refs/heads/main by this push:
     new 2fd5a2c3e45 kie-issues#1481: Test Scenario Editor: Create 
`@kie-tools/scesim-editor-envelope` (#2687)
2fd5a2c3e45 is described below

commit 2fd5a2c3e45b59a25beabff12bcc0ac7b7f817b7
Author: Yeser Amer <[email protected]>
AuthorDate: Tue Oct 22 17:52:26 2024 +0200

    kie-issues#1481: Test Scenario Editor: Create 
`@kie-tools/scesim-editor-envelope` (#2687)
---
 packages/scesim-editor-envelope/README.md          |  46 ++
 packages/scesim-editor-envelope/env/index.js       |  27 ++
 packages/scesim-editor-envelope/package.json       |  55 +++
 .../src/TestScenarioEditorEnvelopeApiFactory.ts    |  44 ++
 .../src/TestScenarioEditorFactory.tsx              | 160 +++++++
 .../src/TestScenarioEditorRoot.tsx                 | 517 +++++++++++++++++++++
 packages/scesim-editor-envelope/tsconfig.json      |   6 +
 packages/scesim-editor/package.json                |   1 +
 packages/scesim-editor/src/TestScenarioEditor.tsx  |  87 +++-
 .../src/TestScenarioEditorContext.tsx              |  28 +-
 .../src/commands/CommandsContextProvider.tsx       |  43 ++
 .../src/drawer/TestScenarioDrawerPanel.tsx         |   4 +-
 .../src/drawer/TestScenarioDrawerSettingsPanel.tsx |  33 +-
 .../TestScenarioEditorDependenciesContext.tsx      |  64 +++
 .../stories/dev/DevWebApp.stories.tsx              |  86 ++--
 .../stories/examples/AvailableDMNModels.ts         |  34 +-
 .../stories/misc/empty/Empty.stories.tsx           |   2 +
 .../stories/scesimEditorStoriesWrapper.tsx         |  11 +-
 .../stories/useCases/IsOldEnoughRule.stories.tsx   |   4 +-
 .../useCases/TrafficViolationDmn.stories.tsx       |   2 +
 pnpm-lock.yaml                                     |  82 ++++
 repo/graph.dot                                     |   4 +
 repo/graph.json                                    |  17 +
 23 files changed, 1288 insertions(+), 69 deletions(-)

diff --git a/packages/scesim-editor-envelope/README.md 
b/packages/scesim-editor-envelope/README.md
new file mode 100644
index 00000000000..64a8f8018c0
--- /dev/null
+++ b/packages/scesim-editor-envelope/README.md
@@ -0,0 +1,46 @@
+<!--
+   Licensed to the Apache Software Foundation (ASF) under one
+   or more contributor license agreements.  See the NOTICE file
+   distributed with this work for additional information
+   regarding copyright ownership.  The ASF licenses this file
+   to you 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.
+-->
+
+## Test Scenario Editor Envelope
+
+Package responsible for creating the necessary pumbling for `scesim-editor` to 
be used inside an Envelope.
+
+---
+
+Apache KIE (incubating) is an effort undergoing incubation at The Apache 
Software
+Foundation (ASF), sponsored by the name of Apache Incubator. Incubation is
+required of all newly accepted projects until a further review indicates that
+the infrastructure, communications, and decision making process have stabilized
+in a manner consistent with other successful ASF projects. While incubation
+status is not necessarily a reflection of the completeness or stability of the
+code, it does indicate that the project has yet to be fully endorsed by the 
ASF.
+
+Some of the incubating project’s releases may not be fully compliant with ASF
+policy. For example, releases may have incomplete or un-reviewed licensing
+conditions. What follows is a list of known issues the project is currently
+aware of (note that this list, by definition, is likely to be incomplete):
+
+- Hibernate, an LGPL project, is being used. Hibernate is in the process of
+  relicensing to ASL v2
+- Some files, particularly test files, and those not supporting comments, may
+  be missing the ASF Licensing Header
+
+If you are planning to incorporate this work into your product/project, please
+be aware that you will need to conduct a thorough licensing review to determine
+the overall implications of including this work. For the current status of this
+project through the Apache Incubator visit:
+https://incubator.apache.org/projects/kie.html
diff --git a/packages/scesim-editor-envelope/env/index.js 
b/packages/scesim-editor-envelope/env/index.js
new file mode 100644
index 00000000000..61bc742bd66
--- /dev/null
+++ b/packages/scesim-editor-envelope/env/index.js
@@ -0,0 +1,27 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.
+ */
+
+const { varsWithName, composeEnv } = require("@kie-tools-scripts/build-env");
+
+module.exports = composeEnv([require("@kie-tools/root-env/env")], {
+  vars: varsWithName({}),
+  get env() {
+    return {};
+  },
+});
diff --git a/packages/scesim-editor-envelope/package.json 
b/packages/scesim-editor-envelope/package.json
new file mode 100644
index 00000000000..17edf9fec90
--- /dev/null
+++ b/packages/scesim-editor-envelope/package.json
@@ -0,0 +1,55 @@
+{
+  "name": "@kie-tools/scesim-editor-envelope",
+  "version": "0.0.0",
+  "description": "",
+  "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 && tsc -p tsconfig.json",
+    "build:prod": "rimraf dist && pnpm lint && tsc -p tsconfig.json",
+    "lint": "run-script-if --bool \"$(build-env linters.run)\" --then 
\"kie-tools--eslint ./src\""
+  },
+  "dependencies": {
+    "@kie-tools-core/editor": "workspace:*",
+    "@kie-tools-core/envelope": "workspace:*",
+    "@kie-tools-core/envelope-bus": "workspace:*",
+    "@kie-tools-core/keyboard-shortcuts": "workspace:*",
+    "@kie-tools-core/notifications": "workspace:*",
+    "@kie-tools-core/react-hooks": "workspace:*",
+    "@kie-tools-core/workspace": "workspace:*",
+    "@kie-tools/boxed-expression-component": "workspace:*",
+    "@kie-tools/dmn-marshaller": "workspace:*",
+    "@kie-tools/scesim-editor": "workspace:*",
+    "@kie-tools/scesim-marshaller": "workspace:*",
+    "@kie-tools/xml-parser-ts": "workspace:*",
+    "@patternfly/react-core": "^4.276.6"
+  },
+  "devDependencies": {
+    "@babel/core": "^7.16.0",
+    "@babel/preset-env": "^7.16.0",
+    "@babel/preset-react": "^7.16.0",
+    "@kie-tools/eslint": "workspace:*",
+    "@kie-tools/root-env": "workspace:*",
+    "@kie-tools/tsconfig": "workspace:*",
+    "@types/react": "^17.0.6",
+    "@types/react-dom": "^17.0.5",
+    "rimraf": "^3.0.2",
+    "typescript": "^5.5.3"
+  },
+  "peerDependencies": {
+    "react": ">=17.0.2 <19.0.0",
+    "react-dom": ">=17.0.2 <19.0.0"
+  }
+}
diff --git 
a/packages/scesim-editor-envelope/src/TestScenarioEditorEnvelopeApiFactory.ts 
b/packages/scesim-editor-envelope/src/TestScenarioEditorEnvelopeApiFactory.ts
new file mode 100644
index 00000000000..394581f8575
--- /dev/null
+++ 
b/packages/scesim-editor-envelope/src/TestScenarioEditorEnvelopeApiFactory.ts
@@ -0,0 +1,44 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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 { EnvelopeApiFactoryArgs } from "@kie-tools-core/envelope";
+import { EditorEnvelopeViewApi, KogitoEditorEnvelopeApiImpl } from 
"@kie-tools-core/editor/dist/envelope";
+import {
+  Editor,
+  KogitoEditorChannelApi,
+  KogitoEditorEnvelopeApi,
+  KogitoEditorEnvelopeContextType,
+} from "@kie-tools-core/editor/dist/api";
+import { TestScenarioEditorFactory } from "./TestScenarioEditorFactory";
+
+export type TestScenarioEnvelopeApiFactoryArgs = EnvelopeApiFactoryArgs<
+  KogitoEditorEnvelopeApi,
+  KogitoEditorChannelApi,
+  EditorEnvelopeViewApi<Editor>,
+  KogitoEditorEnvelopeContextType<KogitoEditorChannelApi>
+>;
+
+export class TestScenarioEditorEnvelopeApiImpl
+  extends KogitoEditorEnvelopeApiImpl<Editor, KogitoEditorEnvelopeApi, 
KogitoEditorChannelApi>
+  implements KogitoEditorEnvelopeApi
+{
+  constructor(readonly scesimArgs: TestScenarioEnvelopeApiFactoryArgs) {
+    super(scesimArgs, new TestScenarioEditorFactory());
+  }
+}
diff --git a/packages/scesim-editor-envelope/src/TestScenarioEditorFactory.tsx 
b/packages/scesim-editor-envelope/src/TestScenarioEditorFactory.tsx
new file mode 100644
index 00000000000..8957ffaf43f
--- /dev/null
+++ b/packages/scesim-editor-envelope/src/TestScenarioEditorFactory.tsx
@@ -0,0 +1,160 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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 * as React from "react";
+import { useCallback } from "react";
+import {
+  Editor,
+  EditorFactory,
+  EditorInitArgs,
+  KogitoEditorEnvelopeContextType,
+  KogitoEditorChannelApi,
+  EditorTheme,
+  DEFAULT_WORKSPACE_ROOT_ABSOLUTE_POSIX_PATH,
+} from "@kie-tools-core/editor/dist/api";
+import { Notification } from "@kie-tools-core/notifications/dist/api";
+import { ResourceContent, ResourcesList, WorkspaceEdit } from 
"@kie-tools-core/workspace/dist/api";
+import { TestScenarioEditorRoot } from "./TestScenarioEditorRoot";
+
+export class TestScenarioEditorFactory implements EditorFactory<Editor, 
KogitoEditorChannelApi> {
+  public createEditor(
+    envelopeContext: KogitoEditorEnvelopeContextType<KogitoEditorChannelApi>,
+    initArgs: EditorInitArgs
+  ): Promise<Editor> {
+    return Promise.resolve(new TestScenarioEditorInterface(envelopeContext, 
initArgs));
+  }
+}
+
+export class TestScenarioEditorInterface implements Editor {
+  private self: TestScenarioEditorRoot;
+  public af_isReact = true;
+  public af_componentId: "scesim-editor";
+  public af_componentTitle: "Test Scenario Editor";
+
+  constructor(
+    private readonly envelopeContext: 
KogitoEditorEnvelopeContextType<KogitoEditorChannelApi>,
+    private readonly initArgs: EditorInitArgs
+  ) {}
+
+  // Not in-editor
+
+  public getPreview(): Promise<string | undefined> {
+    return this.self.getDiagramSvg();
+  }
+
+  public async validate(): Promise<Notification[]> {
+    return Promise.resolve([]);
+  }
+
+  // Forwarding to the editor
+
+  public async setTheme(theme: EditorTheme): Promise<void> {
+    return Promise.resolve(); // No-op for now. The Test Scenario Editor only 
has the LIGHT theme.
+  }
+
+  public async undo(): Promise<void> {
+    return this.self.undo();
+  }
+
+  public async redo(): Promise<void> {
+    return this.self.redo();
+  }
+
+  public getContent(): Promise<string> {
+    return this.self.getContent();
+  }
+
+  public setContent(normalizedPosixPathRelativeToTheWorkspaceRoot: string, 
content: string): Promise<void> {
+    return this.self.setContent(normalizedPosixPathRelativeToTheWorkspaceRoot, 
content);
+  }
+
+  // This is the argument to ReactDOM.render. These props can be understood 
like "static globals".
+  public af_componentRoot() {
+    return (
+      <TestScenarioEditorRootWrapper
+        exposing={(testScenarioEditorRoot) => (this.self = 
testScenarioEditorRoot)}
+        envelopeContext={this.envelopeContext}
+        workspaceRootAbsolutePosixPath={
+          this.initArgs.workspaceRootAbsolutePosixPath ?? 
DEFAULT_WORKSPACE_ROOT_ABSOLUTE_POSIX_PATH
+        }
+        isReadOnly={this.initArgs.isReadOnly}
+      />
+    );
+  }
+}
+
+// This component is a wrapper. It memoizes the TestScenarioEditorRoot props 
beforing rendering it.
+function TestScenarioEditorRootWrapper({
+  envelopeContext,
+  exposing,
+  workspaceRootAbsolutePosixPath,
+  isReadOnly,
+}: {
+  envelopeContext?: KogitoEditorEnvelopeContextType<KogitoEditorChannelApi>;
+  exposing: (s: TestScenarioEditorRoot) => void;
+  workspaceRootAbsolutePosixPath: string;
+  isReadOnly: boolean;
+}) {
+  const onNewEdit = useCallback(
+    (workspaceEdit: WorkspaceEdit) => {
+      
envelopeContext?.channelApi.notifications.kogitoWorkspace_newEdit.send(workspaceEdit);
+    },
+    [envelopeContext]
+  );
+
+  const onRequestWorkspaceFilesList = useCallback(
+    async (resource: ResourcesList) => {
+      return (
+        
envelopeContext?.channelApi.requests.kogitoWorkspace_resourceListRequest(resource)
 ?? new ResourcesList("", [])
+      );
+    },
+    [envelopeContext]
+  );
+
+  const onRequestWorkspaceFileContent = useCallback(
+    async (resource: ResourceContent) => {
+      return 
envelopeContext?.channelApi.requests.kogitoWorkspace_resourceContentRequest(resource);
+    },
+    [envelopeContext]
+  );
+
+  const onOpenFileFromNormalizedPosixPathRelativeToTheWorkspaceRoot = 
useCallback(
+    (normalizedPosixPathRelativeToTheWorkspaceRoot: string) => {
+      envelopeContext?.channelApi.notifications.kogitoWorkspace_openFile.send(
+        normalizedPosixPathRelativeToTheWorkspaceRoot
+      );
+    },
+    [envelopeContext]
+  );
+
+  return (
+    <TestScenarioEditorRoot
+      exposing={exposing}
+      onNewEdit={onNewEdit}
+      onRequestWorkspaceFilesList={onRequestWorkspaceFilesList}
+      onRequestWorkspaceFileContent={onRequestWorkspaceFileContent}
+      onOpenFileFromNormalizedPosixPathRelativeToTheWorkspaceRoot={
+        onOpenFileFromNormalizedPosixPathRelativeToTheWorkspaceRoot
+      }
+      workspaceRootAbsolutePosixPath={workspaceRootAbsolutePosixPath}
+      keyboardShortcutsService={envelopeContext?.services.keyboardShortcuts}
+      isReadOnly={isReadOnly}
+    />
+  );
+}
diff --git a/packages/scesim-editor-envelope/src/TestScenarioEditorRoot.tsx 
b/packages/scesim-editor-envelope/src/TestScenarioEditorRoot.tsx
new file mode 100644
index 00000000000..d38148a2239
--- /dev/null
+++ b/packages/scesim-editor-envelope/src/TestScenarioEditorRoot.tsx
@@ -0,0 +1,517 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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 * as React from "react";
+import { useEffect, useMemo, useState } from "react";
+import * as __path from "path";
+import {
+  imperativePromiseHandle,
+  PromiseImperativeHandle,
+} from "@kie-tools-core/react-hooks/dist/useImperativePromiseHandler";
+import { generateUuid } from "@kie-tools/boxed-expression-component/dist/api";
+import { ResourceContent, SearchType, WorkspaceChannelApi, WorkspaceEdit } 
from "@kie-tools-core/workspace/dist/api";
+import { KeyboardShortcutsService } from 
"@kie-tools-core/keyboard-shortcuts/dist/envelope/KeyboardShortcutsService";
+import { Flex } from "@patternfly/react-core/dist/js/layouts/Flex";
+import { EmptyState, EmptyStateBody, EmptyStateIcon } from 
"@patternfly/react-core/dist/js/components/EmptyState";
+import { Title } from "@patternfly/react-core/dist/js/components/Title";
+import { domParser } from "@kie-tools/xml-parser-ts";
+import { normalize } from 
"@kie-tools/dmn-marshaller/dist/normalization/normalize";
+import { getMarshaller as getDmnMarshaller } from "@kie-tools/dmn-marshaller";
+import * as TestScenarioEditor from 
"@kie-tools/scesim-editor/dist/TestScenarioEditor";
+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 type TestScenarioEditorRootProps = {
+  exposing: (s: TestScenarioEditorRoot) => void;
+  isReadOnly: boolean;
+  keyboardShortcutsService: KeyboardShortcutsService | undefined;
+  onNewEdit: (edit: WorkspaceEdit) => void;
+  onRequestWorkspaceFilesList: 
WorkspaceChannelApi["kogitoWorkspace_resourceListRequest"];
+  onRequestWorkspaceFileContent: 
WorkspaceChannelApi["kogitoWorkspace_resourceContentRequest"];
+  onOpenFileFromNormalizedPosixPathRelativeToTheWorkspaceRoot: 
WorkspaceChannelApi["kogitoWorkspace_openFile"];
+  workspaceRootAbsolutePosixPath: string;
+};
+
+export type TestScenarioEditorRootState = {
+  error: Error | undefined;
+  externalModelsByNamespace: TestScenarioEditor.ExternalDmnsIndex;
+  externalModelsManagerDoneBootstraping: boolean;
+  isReadOnly: boolean;
+  keyboardShortcutsRegistred: boolean;
+  keyboardShortcutsRegisterIds: number[];
+  marshaller: SceSimMarshaller | undefined;
+  openFilenormalizedPosixPathRelativeToTheWorkspaceRoot: string | undefined;
+  pointer: number;
+  stack: SceSimModel[];
+};
+
+export class TestScenarioEditorRoot extends 
React.Component<TestScenarioEditorRootProps, TestScenarioEditorRootState> {
+  private readonly externalModelsManagerDoneBootstraping = 
imperativePromiseHandle<void>();
+
+  private readonly testScenarioEditorRef: 
React.RefObject<TestScenarioEditor.TestScenarioEditorRef>;
+
+  constructor(props: TestScenarioEditorRootProps) {
+    super(props);
+    props.exposing(this);
+    this.testScenarioEditorRef = React.createRef();
+    this.state = {
+      error: undefined,
+      externalModelsByNamespace: {},
+      externalModelsManagerDoneBootstraping: false,
+      isReadOnly: props.isReadOnly,
+      keyboardShortcutsRegisterIds: [],
+      keyboardShortcutsRegistred: false,
+      marshaller: undefined,
+      openFilenormalizedPosixPathRelativeToTheWorkspaceRoot: undefined,
+      pointer: -1,
+      stack: [],
+    };
+  }
+
+  // Exposed API
+
+  public async undo(): Promise<void> {
+    this.setState((prev) => ({ ...prev, pointer: Math.max(0, prev.pointer - 1) 
}));
+  }
+
+  public async redo(): Promise<void> {
+    this.setState((prev) => ({ ...prev, pointer: Math.min(prev.stack.length - 
1, prev.pointer + 1) }));
+  }
+
+  public async getDiagramSvg(): Promise<string | undefined> {
+    return this.testScenarioEditorRef.current?.getDiagramSvg();
+  }
+
+  public async getContent(): Promise<string> {
+    if (!this.state.marshaller || !this.model) {
+      throw new Error(
+        `Test Scenario EDITOR ROOT: Content has not been set yet. Throwing an 
error to prevent returning a "default" content.`
+      );
+    }
+
+    return this.state.marshaller.builder.build(this.model);
+  }
+
+  public async setContent(
+    openFilenormalizedPosixPathRelativeToTheWorkspaceRoot: string,
+    content: string
+  ): Promise<void> {
+    const marshaller = this.getMarshaller(content || EMPTY_ONE_EIGHT);
+
+    // Save stack
+    let savedStackPointer: SceSimModel[] = [];
+
+    // Set the model and path for external models manager.
+    this.setState((prev) => {
+      savedStackPointer = [...prev.stack];
+      return {
+        stack: [marshaller.parser.parse()],
+        openFilenormalizedPosixPathRelativeToTheWorkspaceRoot,
+        pointer: 0,
+      };
+    });
+
+    // Wait the external manager models to load.
+    await this.externalModelsManagerDoneBootstraping.promise;
+
+    // Set the valeus to render the Test Scenario Editor.
+    this.setState((prev) => {
+      // External change to the same file.
+      if (
+        prev.openFilenormalizedPosixPathRelativeToTheWorkspaceRoot ===
+        openFilenormalizedPosixPathRelativeToTheWorkspaceRoot
+      ) {
+        const newStack = savedStackPointer.slice(0, prev.pointer + 1);
+        return {
+          externalModelsManagerDoneBootstraping: true,
+          isReadOnly: prev.isReadOnly,
+          openFilenormalizedPosixPathRelativeToTheWorkspaceRoot,
+          marshaller,
+          pointer: newStack.length,
+          stack: [...newStack, marshaller.parser.parse()],
+        };
+      }
+
+      // Different file opened. Need to reset everything.
+      else {
+        return {
+          externalModelsManagerDoneBootstraping: true,
+          isReadOnly: prev.isReadOnly,
+          marshaller,
+          openFilenormalizedPosixPathRelativeToTheWorkspaceRoot,
+          pointer: 0,
+          stack: [marshaller.parser.parse()],
+        };
+      }
+    });
+  }
+
+  public get model(): SceSimModel | undefined {
+    return this.state.stack[this.state.pointer];
+  }
+
+  // Internal methods
+
+  private getMarshaller(content: string) {
+    try {
+      return getMarshaller(content || EMPTY_ONE_EIGHT);
+    } catch (e) {
+      this.setState((s) => ({
+        ...s,
+        error: e,
+      }));
+      throw e;
+    }
+  }
+
+  private setExternalModelsByNamespace = (externalModelsByNamespace: 
TestScenarioEditor.ExternalDmnsIndex) => {
+    this.setState((prev) => ({ ...prev, externalModelsByNamespace }));
+  };
+
+  private onModelChange: TestScenarioEditor.OnSceSimModelChange = (model) => {
+    this.setState(
+      (prev) => {
+        const newStack = prev.stack.slice(0, prev.pointer + 1);
+        return {
+          ...prev,
+          stack: [...newStack, model],
+          pointer: newStack.length,
+        };
+      },
+      () =>
+        this.props.onNewEdit({
+          id: 
`${this.state.openFilenormalizedPosixPathRelativeToTheWorkspaceRoot}__${generateUuid()}`,
+        })
+    );
+  };
+
+  private onRequestExternalModelsAvailableToInclude: 
TestScenarioEditor.OnRequestExternalModelsAvailableToInclude =
+    async () => {
+      if (!this.state.openFilenormalizedPosixPathRelativeToTheWorkspaceRoot) {
+        return [];
+      }
+
+      const list = await this.props.onRequestWorkspaceFilesList({
+        pattern: DMN_MODELS_SEARCH_GLOB_PATTERN,
+        opts: { type: SearchType.TRAVERSAL },
+      });
+
+      return list.normalizedPosixPathsRelativeToTheWorkspaceRoot.flatMap((p) =>
+        
__path.relative(__path.dirname(this.state.openFilenormalizedPosixPathRelativeToTheWorkspaceRoot!),
 p)
+      );
+    };
+
+  private onRequestToResolvePathRelativeToTheOpenFile: 
TestScenarioEditor.OnRequestToResolvePath = (
+    normalizedPosixPathRelativeToTheOpenFile
+  ) => {
+    const normalizedPosixPathRelativeToTheWorkspaceRoot = __path
+      .resolve(
+        
__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 (
+    normalizedPosixPathRelativeToTheOpenFile
+  ) => {
+    const normalizedPosixPathRelativeToTheWorkspaceRoot = 
this.onRequestToResolvePathRelativeToTheOpenFile(
+      normalizedPosixPathRelativeToTheOpenFile
+    );
+    const resource = await this.props.onRequestWorkspaceFileContent({
+      normalizedPosixPathRelativeToTheWorkspaceRoot,
+      opts: { type: "text" },
+    });
+
+    const ext = __path.extname(normalizedPosixPathRelativeToTheOpenFile);
+    if (ext === ".dmn") {
+      return {
+        normalizedPosixPathRelativeToTheOpenFile,
+        type: "dmn",
+        model: normalize(getDmnMarshaller(resource?.content ?? "", { 
upgradeTo: "latest" }).parser.parse()),
+        svg: "",
+      };
+    } else {
+      throw new Error(`Unknown extension '${ext}'.`);
+    }
+  };
+
+  private onOpenFileFromPathRelativeToTheOpenFile = 
(normalizedPosixPathRelativeToTheOpenFile: string) => {
+    if (!this.state.openFilenormalizedPosixPathRelativeToTheWorkspaceRoot) {
+      return;
+    }
+
+    this.props.onOpenFileFromNormalizedPosixPathRelativeToTheWorkspaceRoot(
+      
this.onRequestToResolvePathRelativeToTheOpenFile(normalizedPosixPathRelativeToTheOpenFile)
+    );
+  };
+
+  public componentDidUpdate(
+    prevProps: Readonly<TestScenarioEditorRootProps>,
+    prevState: Readonly<TestScenarioEditorRootState>,
+    snapshot?: any
+  ): void {
+    if (this.props.keyboardShortcutsService === undefined || 
this.state.keyboardShortcutsRegistred === true) {
+      return;
+    }
+
+    const commands = this.testScenarioEditorRef.current?.getCommands();
+    if (commands === undefined) {
+      return;
+    }
+    const togglePropertiesPanel = 
this.props.keyboardShortcutsService?.registerKeyPress(
+      "I",
+      "Misc | Open/Close dock panel",
+      async () => commands.toggleTestScenarioDock()
+    );
+
+    this.setState((prev) => ({
+      ...prev,
+      keyboardShortcutsRegistred: true,
+      keyboardShortcutsRegisterIds: [togglePropertiesPanel],
+    }));
+  }
+
+  public componentWillUnmount() {
+    const keyboardShortcuts = 
this.testScenarioEditorRef.current?.getCommands();
+    if (keyboardShortcuts === undefined) {
+      return;
+    }
+
+    this.state.keyboardShortcutsRegisterIds.forEach((id) => {
+      this.props.keyboardShortcutsService?.deregister(id);
+    });
+  }
+
+  public render() {
+    return (
+      <>
+        {this.state.error && <TestScenarioMarshallerFallbackError 
error={this.state.error} />}
+        {this.model && (
+          <>
+            <TestScenarioEditor.TestScenarioEditor
+              ref={this.testScenarioEditorRef}
+              issueTrackerHref={""}
+              model={this.model}
+              onModelChange={this.onModelChange}
+              
onRequestExternalModelsAvailableToInclude={this.onRequestExternalModelsAvailableToInclude}
+              
onRequestExternalModelByPath={this.onRequestExternalModelByPathsRelativeToTheOpenFile}
+              
onRequestToJumpToPath={this.onOpenFileFromPathRelativeToTheOpenFile}
+              
onRequestToResolvePath={this.onRequestToResolvePathRelativeToTheOpenFile}
+              openFileNormalizedPosixPathRelativeToTheWorkspaceRoot={
+                
this.state.openFilenormalizedPosixPathRelativeToTheWorkspaceRoot
+              }
+            />
+            {
+              <ExternalModelsManager
+                
workspaceRootAbsolutePosixPath={this.props.workspaceRootAbsolutePosixPath}
+                thisScesimNormalizedPosixPathRelativeToTheWorkspaceRoot={
+                  
this.state.openFilenormalizedPosixPathRelativeToTheWorkspaceRoot
+                }
+                model={this.model}
+                onChange={this.setExternalModelsByNamespace}
+                
onRequestWorkspaceFilesList={this.props.onRequestWorkspaceFilesList}
+                
onRequestWorkspaceFileContent={this.props.onRequestWorkspaceFileContent}
+                
externalModelsManagerDoneBootstraping={this.externalModelsManagerDoneBootstraping}
+              />
+            }
+          </>
+        )}
+      </>
+    );
+  }
+}
+
+function ExternalModelsManager({
+  workspaceRootAbsolutePosixPath,
+  thisScesimNormalizedPosixPathRelativeToTheWorkspaceRoot,
+  model,
+  onChange,
+  onRequestWorkspaceFileContent,
+  onRequestWorkspaceFilesList,
+  externalModelsManagerDoneBootstraping,
+}: {
+  workspaceRootAbsolutePosixPath: string;
+  thisScesimNormalizedPosixPathRelativeToTheWorkspaceRoot: string | undefined;
+  model: SceSimModel;
+  onChange: (externalModelsByNamespace: TestScenarioEditor.ExternalDmnsIndex) 
=> void;
+  onRequestWorkspaceFileContent: 
WorkspaceChannelApi["kogitoWorkspace_resourceContentRequest"];
+  onRequestWorkspaceFilesList: 
WorkspaceChannelApi["kogitoWorkspace_resourceListRequest"];
+  externalModelsManagerDoneBootstraping: PromiseImperativeHandle<void>;
+}) {
+  const targetNamespace = useMemo(() => {
+    if (model.ScenarioSimulationModel.settings.type?.__$$text !== "DMN") {
+      return null;
+    }
+    if (model.ScenarioSimulationModel.settings.dmnNamespace?.__$$text) {
+      return 
model.ScenarioSimulationModel.settings.dmnNamespace?.__$$text.toUpperCase();
+    }
+    return null;
+  }, [model.ScenarioSimulationModel.settings]);
+
+  const [externalUpdatesCount, setExternalUpdatesCount] = useState(0);
+
+  // This is a hack. Every time a file is updates in KIE Sandbox, the Shared 
Worker emits an event to this BroadcastChannel.
+  // By listening to it, we can reload the `externalModelsByNamespace` object. 
This makes the DMN Editor react to external changes,
+  // Which is very important for multi-file editing.
+  //
+  // Now, this mechanism is not ideal. We would ideally only be notified on 
changes to relevant files, but this sub-system does not exist yet.
+  // The consequence of this "hack" is some extra reloads.
+  useEffect(() => {
+    const bc = new BroadcastChannel("workspaces_files");
+    bc.onmessage = ({ data }) => {
+      // Changes to `thisDmn` shouldn't update its references to external 
models.
+      // Here, `data?.relativePath` is relative to the workspace root.
+      if (data?.relativePath === 
thisScesimNormalizedPosixPathRelativeToTheWorkspaceRoot) {
+        return;
+      }
+      // We want to track changes on DMN files only.
+      if (
+        !thisScesimNormalizedPosixPathRelativeToTheWorkspaceRoot &&
+        
__path.extname(thisScesimNormalizedPosixPathRelativeToTheWorkspaceRoot!).toUpperCase()
 !== "dmn"
+      ) {
+        return;
+      }
+
+      setExternalUpdatesCount((prev) => prev + 1);
+    };
+    return () => {
+      bc.close();
+    };
+  }, [thisScesimNormalizedPosixPathRelativeToTheWorkspaceRoot]);
+
+  // This effect actually populates `externalModelsByNamespace` through the 
`onChange` call.
+  useEffect(() => {
+    let canceled = false;
+
+    if (!thisScesimNormalizedPosixPathRelativeToTheWorkspaceRoot || 
!targetNamespace) {
+      return;
+    }
+
+    onRequestWorkspaceFilesList({ pattern: DMN_MODELS_SEARCH_GLOB_PATTERN, 
opts: { type: SearchType.TRAVERSAL } })
+      .then((list) => {
+        const resources: Array<Promise<ResourceContent | undefined>> = [];
+        for (let i = 0; i < 
list.normalizedPosixPathsRelativeToTheWorkspaceRoot.length; i++) {
+          const normalizedPosixPathRelativeToTheWorkspaceRoot = 
list.normalizedPosixPathsRelativeToTheWorkspaceRoot[i];
+
+          if (
+            normalizedPosixPathRelativeToTheWorkspaceRoot === 
thisScesimNormalizedPosixPathRelativeToTheWorkspaceRoot
+          ) {
+            continue;
+          }
+
+          resources.push(
+            onRequestWorkspaceFileContent({
+              normalizedPosixPathRelativeToTheWorkspaceRoot,
+              opts: { type: "text" },
+            })
+          );
+        }
+        return Promise.all(resources);
+      })
+      .then((resources) => {
+        const externalModelsIndex: TestScenarioEditor.ExternalDmnsIndex = {};
+
+        for (let i = 0; i < resources.length; i++) {
+          const resource = resources[i];
+          if (!resource) {
+            continue;
+          }
+
+          const content = resource.content ?? "";
+
+          const normalizedPosixPathRelativeToTheOpenFile = __path.relative(
+            
__path.dirname(thisScesimNormalizedPosixPathRelativeToTheWorkspaceRoot),
+            resource.normalizedPosixPathRelativeToTheWorkspaceRoot
+          );
+
+          const ext = 
__path.extname(resource.normalizedPosixPathRelativeToTheWorkspaceRoot);
+          if (ext === ".dmn") {
+            const namespace = 
domParser.getDomDocument(content).documentElement.getAttribute("namespace");
+            if (namespace === targetNamespace) {
+              // Check for multiplicity of namespaces on DMN models
+              if (externalModelsIndex[namespace]) {
+                console.warn(
+                  `TEST SCENARIO EDITOR ROOT: Multiple DMN models encountered 
with the same namespace '${namespace}': '${
+                    resource.normalizedPosixPathRelativeToTheWorkspaceRoot
+                  }' and '${
+                    
externalModelsIndex[namespace]!.normalizedPosixPathRelativeToTheOpenFile
+                  }'. The latter will be considered.`
+                );
+              }
+
+              externalModelsIndex[namespace] = {
+                normalizedPosixPathRelativeToTheOpenFile,
+                model: normalize(getDmnMarshaller(content, { upgradeTo: 
"latest" }).parser.parse()),
+                svg: "",
+              };
+            }
+          } else {
+            throw new Error(`Unknown extension '${ext}'.`);
+          }
+        }
+
+        if (!canceled) {
+          onChange(externalModelsIndex);
+        }
+        externalModelsManagerDoneBootstraping.resolve();
+      });
+
+    return () => {
+      canceled = true;
+    };
+  }, [
+    targetNamespace,
+    onChange,
+    onRequestWorkspaceFileContent,
+    onRequestWorkspaceFilesList,
+    thisScesimNormalizedPosixPathRelativeToTheWorkspaceRoot,
+    externalUpdatesCount,
+    workspaceRootAbsolutePosixPath,
+    externalModelsManagerDoneBootstraping,
+  ]);
+
+  return <></>;
+}
+
+function TestScenarioMarshallerFallbackError({ error }: { error: Error }) {
+  return (
+    <Flex justifyContent={{ default: "justifyContentCenter" }} style={{ 
marginTop: "100px" }}>
+      <EmptyState style={{ maxWidth: "1280px" }}>
+        <EmptyStateIcon icon={() => <div style={{ fontSize: "3em" }}>😕</div>} 
/>
+        <Title size={"lg"} headingLevel={"h4"}>
+          Unable to open file.
+        </Title>
+        <br />
+        <EmptyStateBody>Error details: {error.message}</EmptyStateBody>
+      </EmptyState>
+    </Flex>
+  );
+}
diff --git a/packages/scesim-editor-envelope/tsconfig.json 
b/packages/scesim-editor-envelope/tsconfig.json
new file mode 100644
index 00000000000..9154a249aa5
--- /dev/null
+++ b/packages/scesim-editor-envelope/tsconfig.json
@@ -0,0 +1,6 @@
+{
+  "extends": "@kie-tools/tsconfig/tsconfig.esm.json",
+  "compilerOptions": {
+    "jsx": "react-jsx"
+  }
+}
diff --git a/packages/scesim-editor/package.json 
b/packages/scesim-editor/package.json
index 9cd082deee5..5814b86fe1f 100644
--- a/packages/scesim-editor/package.json
+++ b/packages/scesim-editor/package.json
@@ -21,6 +21,7 @@
     "@kie-tools-core/i18n": "workspace:*",
     "@kie-tools-core/patternfly-base": "workspace:*",
     "@kie-tools/boxed-expression-component": "workspace:*",
+    "@kie-tools/dmn-marshaller": "workspace:*",
     "@kie-tools/i18n-common-dictionary": "workspace:*",
     "@kie-tools/scesim-marshaller": "workspace:*",
     "@patternfly/react-core": "^4.276.6",
diff --git a/packages/scesim-editor/src/TestScenarioEditor.tsx 
b/packages/scesim-editor/src/TestScenarioEditor.tsx
index faf089991e7..b352179c2ff 100644
--- a/packages/scesim-editor/src/TestScenarioEditor.tsx
+++ b/packages/scesim-editor/src/TestScenarioEditor.tsx
@@ -20,12 +20,15 @@
 import "@patternfly/react-core/dist/styles/base.css";
 
 import * as React from "react";
-import { useCallback, useImperativeHandle, useMemo, useRef } from "react";
+import { useCallback, useEffect, useImperativeHandle, useMemo, useRef } from 
"react";
 
 import { I18nDictionariesProvider } from 
"@kie-tools-core/i18n/dist/react-components";
 
 import { testScenarioEditorDictionaries, TestScenarioEditorI18nContext, 
testScenarioEditorI18nDefaults } from "./i18n";
 
+import { DmnLatestModel } from "@kie-tools/dmn-marshaller";
+import { Normalized } from 
"@kie-tools/dmn-marshaller/dist/normalization/normalize";
+
 import { SceSimModel } from "@kie-tools/scesim-marshaller";
 import { SceSim__FactMappingType } from 
"@kie-tools/scesim-marshaller/dist/schemas/scesim-1_8/ts-gen/types";
 
@@ -45,6 +48,7 @@ import HelpIcon from 
"@patternfly/react-icons/dist/esm/icons/help-icon";
 
 import { ErrorBoundary, ErrorBoundaryPropsWithFallback } from 
"react-error-boundary";
 
+import { Commands, CommandsContextProvider, useCommands } from 
"./commands/CommandsContextProvider";
 import TestScenarioCreationPanel from "./creation/TestScenarioCreationPanel";
 import TestScenarioDrawerPanel from "./drawer/TestScenarioDrawerPanel";
 import TestScenarioSideBarMenu from "./sidebar/TestScenarioSideBarMenu";
@@ -62,6 +66,7 @@ import {
 } from "./store/TestScenarioStoreContext";
 import { TestScenarioEditorErrorFallback } from 
"./TestScenarioEditorErrorFallback";
 import { TestScenarioEditorContextProvider, useTestScenarioEditor } from 
"./TestScenarioEditorContext";
+import { TestScenarioEditorExternalModelsContextProvider } from 
"./externalModels/TestScenarioEditorDependenciesContext";
 import { useEffectAfterFirstRender } from "./hook/useEffectAfterFirstRender";
 import { INITIAL_COMPUTED_CACHE } from "./store/computed/initial";
 
@@ -81,9 +86,28 @@ enum TestScenarioFileStatus {
 
 /* Types */
 
+export type OnRequestExternalModelsAvailableToInclude = () => 
Promise<string[]>;
+export type OnRequestToJumpToPath = (normalizedPosixPathRelativeToTheOpenFile: 
string) => void;
+export type OnRequestToResolvePath = 
(normalizedPosixPathRelativeToTheOpenFile: string) => string;
 export type OnSceSimModelChange = (model: SceSimModel) => void;
 
+export type OnRequestExternalModelByPath = (
+  normalizedPosixPathRelativeToTheOpenFile: string
+) => Promise<ExternalDmn | null>;
+export type ExternalDmnsIndex = Record<string /** 
normalizedPosixPathRelativeToTheOpenFile */, ExternalDmn | undefined>;
+
+export type ExternalDmn = {
+  model: Normalized<DmnLatestModel>;
+  normalizedPosixPathRelativeToTheOpenFile: string;
+  svg: string;
+};
+
 export type TestScenarioEditorProps = {
+  /**
+   * When the SceSim represented by `model` ("This SceSim") is DMN-type Test 
Scenario this prop needs to map their contents by namespace.
+   * The SceSim model won't be correctly rendered if an included model is not 
found on this object.
+   */
+  externalModelsByNamespace?: ExternalDmnsIndex;
   /**
    * A link that will take users to an issue tracker so they can report 
problems they find on the Test Scenario Editor.
    * This is shown on the ErrorBoundary fallback component, when an uncaught 
error happens.
@@ -101,10 +125,33 @@ export type TestScenarioEditorProps = {
    * Notifies the caller when the Test Scenario Editor performs a new edit 
after the debounce time.
    */
   onModelDebounceStateChanged?: (changed: boolean) => void;
+  /**
+   * Called when the contents of a specific available DMN model is necessary.
+   */
+  onRequestExternalModelByPath?: OnRequestExternalModelByPath;
+  /**
+   * Called when the list of paths of available DMN models
+   */
+  onRequestExternalModelsAvailableToInclude?: 
OnRequestExternalModelsAvailableToInclude;
+  /**
+   * When users want to jump to another file, this method is called, allowing 
the controller of this component decide what to do.
+   * Links are only rendered if this is provided. Otherwise, paths will be 
rendered as text.
+   */
+  onRequestToJumpToPath?: OnRequestToJumpToPath;
+  /**
+   * All paths inside the Test Scenario Editor are relative. To be able to 
resolve them and display them as absolute paths, this function is called.
+   * If undefined, the relative paths will be displayed.
+   */
+  onRequestToResolvePath?: OnRequestToResolvePath;
+  /**
+   * The file path of the current opened Test Scenario scesim file
+   */
+  openFileNormalizedPosixPathRelativeToTheWorkspaceRoot: string | undefined;
 };
 
 export type TestScenarioEditorRef = {
   reset: (mode: SceSimModel) => void;
+  getCommands: () => Commands;
   getDiagramSvg: () => Promise<string | undefined>;
 };
 
@@ -114,8 +161,9 @@ export type TestScenarioSelectedColumnMetaData = {
   isBackground: boolean;
 };
 
-function TestScenarioMainPanel({ fileName }: { fileName: string }) {
+function TestScenarioMainPanel() {
   const { i18n } = useTestScenarioEditorI18n();
+  const { commandsRef } = useCommands();
   const testScenarioEditorStoreApi = useTestScenarioEditorStoreApi();
   const navigation = useTestScenarioEditorStore((s) => s.navigation);
   const scesimModel = useTestScenarioEditorStore((s) => s.scesim.model);
@@ -143,13 +191,24 @@ function TestScenarioMainPanel({ fileName }: { fileName: 
string }) {
     [testScenarioEditorStoreApi]
   );
 
+  // Show Properties panel
+  useEffect(() => {
+    if (!commandsRef.current) {
+      return;
+    }
+    commandsRef.current.toggleTestScenarioDock = async () => {
+      console.trace("Test Scenario Editor: COMMANDS: Toggle dock panel...");
+      testScenarioEditorStoreApi.setState((state) => {
+        state.navigation.dock.isOpen = !state.navigation.dock.isOpen;
+      });
+    };
+  }, [testScenarioEditorStoreApi, commandsRef]);
+
   return (
     <>
       <div className="kie-scesim-editor--content">
         <Drawer isExpanded={navigation.dock.isOpen} isInline={true} 
position={"right"}>
-          <DrawerContent
-            panelContent={<TestScenarioDrawerPanel fileName={fileName} 
onDrawerClose={() => showDockPanel(false)} />}
-          >
+          <DrawerContent panelContent={<TestScenarioDrawerPanel 
onDrawerClose={() => showDockPanel(false)} />}>
             <DrawerContentBody>
               {isAlertEnabled && (
                 <div className="kie-scesim-editor--content-alert">
@@ -247,16 +306,17 @@ function TestScenarioParserErrorPanel({
 }
 
 export const TestScenarioEditorInternal = ({
+  forwardRef,
   model,
   onModelChange,
   onModelDebounceStateChanged,
-  forwardRef,
 }: TestScenarioEditorProps & { forwardRef?: React.Ref<TestScenarioEditorRef> 
}) => {
   console.trace("[TestScenarioEditorInternal] Component creation ...");
 
   const scesim = useTestScenarioEditorStore((s) => s.scesim);
   const testScenarioEditorStoreApi = useTestScenarioEditorStoreApi();
   const { testScenarioEditorModelBeforeEditingRef, 
testScenarioEditorRootElementRef } = useTestScenarioEditor();
+  const { commandsRef } = useCommands();
 
   /** Implementing Editor APIs */
 
@@ -269,9 +329,10 @@ export const TestScenarioEditorInternal = ({
         const state = testScenarioEditorStoreApi.getState();
         state.dispatch(state).scesim.reset();
       },
+      getCommands: () => commandsRef.current,
       getDiagramSvg: async () => undefined,
     }),
-    [testScenarioEditorStoreApi]
+    [commandsRef, testScenarioEditorStoreApi]
   );
 
   // Make sure the Test Scenario Editor reacts to props changing.
@@ -372,7 +433,7 @@ export const TestScenarioEditorInternal = ({
               />
             );
           case TestScenarioFileStatus.VALID:
-            return <TestScenarioMainPanel fileName={"Test"} />;
+            return <TestScenarioMainPanel />;
         }
       })()}
     </div>
@@ -407,9 +468,13 @@ export const TestScenarioEditor = React.forwardRef(
       >
         <TestScenarioEditorContextProvider {...props}>
           <ErrorBoundary FallbackComponent={TestScenarioEditorErrorFallback} 
onReset={resetState}>
-            <TestScenarioEditorStoreApiContext.Provider 
value={storeRef.current}>
-              <TestScenarioEditorInternal forwardRef={ref} {...props} />
-            </TestScenarioEditorStoreApiContext.Provider>
+            <TestScenarioEditorExternalModelsContextProvider {...props}>
+              <TestScenarioEditorStoreApiContext.Provider 
value={storeRef.current}>
+                <CommandsContextProvider>
+                  <TestScenarioEditorInternal forwardRef={ref} {...props} />
+                </CommandsContextProvider>
+              </TestScenarioEditorStoreApiContext.Provider>
+            </TestScenarioEditorExternalModelsContextProvider>
           </ErrorBoundary>
         </TestScenarioEditorContextProvider>
       </I18nDictionariesProvider>
diff --git a/packages/scesim-editor/src/TestScenarioEditorContext.tsx 
b/packages/scesim-editor/src/TestScenarioEditorContext.tsx
index 49ffc97ffd1..3702076ce6c 100644
--- a/packages/scesim-editor/src/TestScenarioEditorContext.tsx
+++ b/packages/scesim-editor/src/TestScenarioEditorContext.tsx
@@ -24,9 +24,22 @@ import { TestScenarioEditorProps } from 
"./TestScenarioEditor";
 
 export type SceSimModelBeforeEditing = SceSimModel;
 
-export type TestScenarioEditorContextProviderProps = 
Pick<TestScenarioEditorProps, "issueTrackerHref" | "model">;
+export type TestScenarioEditorContextProviderProps = Pick<
+  TestScenarioEditorProps,
+  | "issueTrackerHref"
+  | "model"
+  | "onRequestToJumpToPath"
+  | "onRequestToResolvePath"
+  | "openFileNormalizedPosixPathRelativeToTheWorkspaceRoot"
+>;
 
-export type TestScenarioEditorContextType = 
Pick<TestScenarioEditorContextProviderProps, "issueTrackerHref"> & {
+export type TestScenarioEditorContextType = Pick<
+  TestScenarioEditorContextProviderProps,
+  | "issueTrackerHref"
+  | "onRequestToJumpToPath"
+  | "onRequestToResolvePath"
+  | "openFileNormalizedPosixPathRelativeToTheWorkspaceRoot"
+> & {
   testScenarioEditorModelBeforeEditingRef: 
React.MutableRefObject<SceSimModelBeforeEditing>;
   testScenarioEditorRootElementRef: React.RefObject<HTMLDivElement>;
 };
@@ -48,8 +61,17 @@ export function TestScenarioEditorContextProvider(
       issueTrackerHref: props.issueTrackerHref,
       testScenarioEditorModelBeforeEditingRef,
       testScenarioEditorRootElementRef,
+      onRequestToJumpToPath: props.onRequestToJumpToPath,
+      onRequestToResolvePath: props.onRequestToResolvePath,
+      openFileNormalizedPosixPathRelativeToTheWorkspaceRoot:
+        props.openFileNormalizedPosixPathRelativeToTheWorkspaceRoot,
     }),
-    [props.issueTrackerHref]
+    [
+      props.issueTrackerHref,
+      props.onRequestToJumpToPath,
+      props.onRequestToResolvePath,
+      props.openFileNormalizedPosixPathRelativeToTheWorkspaceRoot,
+    ]
   );
   return <TestScenarioEditorContext.Provider 
value={value}>{props.children}</TestScenarioEditorContext.Provider>;
 }
diff --git a/packages/scesim-editor/src/commands/CommandsContextProvider.tsx 
b/packages/scesim-editor/src/commands/CommandsContextProvider.tsx
new file mode 100644
index 00000000000..aa6b09ac182
--- /dev/null
+++ b/packages/scesim-editor/src/commands/CommandsContextProvider.tsx
@@ -0,0 +1,43 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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 * as React from "react";
+import { useContext, useRef } from "react";
+
+export interface Commands {
+  toggleTestScenarioDock: () => void;
+}
+
+const CommandsContext = React.createContext<{
+  commandsRef: React.MutableRefObject<Commands>;
+}>({} as any);
+
+export function useCommands() {
+  return useContext(CommandsContext);
+}
+
+export function CommandsContextProvider(props: React.PropsWithChildren<{}>) {
+  const commandsRef = useRef<Commands>({
+    toggleTestScenarioDock: () => {
+      throw new Error("Test Scenario EDITOR: toggleTestScenarioDock command 
not implemented.");
+    },
+  });
+
+  return <CommandsContext.Provider value={{ commandsRef 
}}>{props.children}</CommandsContext.Provider>;
+}
diff --git a/packages/scesim-editor/src/drawer/TestScenarioDrawerPanel.tsx 
b/packages/scesim-editor/src/drawer/TestScenarioDrawerPanel.tsx
index 0045f44ec58..cf354e6cd8a 100644
--- a/packages/scesim-editor/src/drawer/TestScenarioDrawerPanel.tsx
+++ b/packages/scesim-editor/src/drawer/TestScenarioDrawerPanel.tsx
@@ -36,7 +36,7 @@ import TestScenarioDrawerDataSelectorPanel from 
"./TestScenarioDrawerDataSelecto
 import TestScenarioDrawerCheatSheetPanel from 
"./TestScenarioDrawerCheatSheetPanel";
 import TestScenarioDrawerSettingsPanel from 
"../drawer/TestScenarioDrawerSettingsPanel";
 
-function TestScenarioDrawerPanel({ fileName, onDrawerClose }: { fileName: 
string; onDrawerClose: () => void }) {
+function TestScenarioDrawerPanel({ onDrawerClose }: { onDrawerClose: () => 
void }) {
   const { i18n } = useTestScenarioEditorI18n();
   const navigation = useTestScenarioEditorStore((state) => state.navigation);
   const settingsModel = useTestScenarioEditorStore((state) => 
state.scesim.model.ScenarioSimulationModel.settings);
@@ -76,7 +76,7 @@ function TestScenarioDrawerPanel({ fileName, onDrawerClose }: 
{ fileName: string
             case TestScenarioEditorDock.DATA_OBJECT:
               return <TestScenarioDrawerDataSelectorPanel />;
             case TestScenarioEditorDock.SETTINGS:
-              return <TestScenarioDrawerSettingsPanel fileName={fileName} />;
+              return <TestScenarioDrawerSettingsPanel />;
             default:
               throw new Error("Wrong state, an invalid dock has been selected 
" + navigation.dock.selected);
           }
diff --git 
a/packages/scesim-editor/src/drawer/TestScenarioDrawerSettingsPanel.tsx 
b/packages/scesim-editor/src/drawer/TestScenarioDrawerSettingsPanel.tsx
index 9f522a2ccbf..d8dc56ea324 100644
--- a/packages/scesim-editor/src/drawer/TestScenarioDrawerSettingsPanel.tsx
+++ b/packages/scesim-editor/src/drawer/TestScenarioDrawerSettingsPanel.tsx
@@ -33,9 +33,11 @@ import { useTestScenarioEditorI18n } from "../i18n";
 import { useTestScenarioEditorStore, useTestScenarioEditorStoreApi } from 
"../store/TestScenarioStoreContext";
 
 import "./TestScenarioDrawerSettingsPanel.css";
+import { useTestScenarioEditor } from "../TestScenarioEditorContext";
 
-function TestScenarioDrawerSettingsPanel({ fileName }: { fileName: string }) {
+function TestScenarioDrawerSettingsPanel() {
   const { i18n } = useTestScenarioEditorI18n();
+  const { openFileNormalizedPosixPathRelativeToTheWorkspaceRoot } = 
useTestScenarioEditor();
   const settingsModel = useTestScenarioEditorStore((state) => 
state.scesim.model.ScenarioSimulationModel.settings);
   const testScenarioEditorStoreApi = useTestScenarioEditorStoreApi();
   const testScenarioType = settingsModel.type?.__$$text.toUpperCase();
@@ -55,15 +57,22 @@ function TestScenarioDrawerSettingsPanel({ fileName }: { 
fileName: string }) {
       <Title className={"kie-scesim-editor-drawer-settings--title"} 
headingLevel={"h6"}>
         {i18n.drawer.settings.fileName}
       </Title>
-      <TextInput className={"kie-scesim-editor-drawer-settings--text-input"} 
value={fileName} type="text" isDisabled />
+      <TextInput
+        aria-label="filename"
+        className={"kie-scesim-editor-drawer-settings--text-input"}
+        isDisabled
+        type="text"
+        value={openFileNormalizedPosixPathRelativeToTheWorkspaceRoot}
+      />
       <Title className={"kie-scesim-editor-drawer-settings--title"} 
headingLevel={"h6"}>
         {i18n.drawer.settings.assetType}
       </Title>
       <TextInput
+        aria-label="asset-type"
         className={"kie-scesim-editor-drawer-settings--text-input"}
-        value={testScenarioType}
-        type="text"
         isDisabled
+        type="text"
+        value={testScenarioType}
       />
       {testScenarioType === "DMN" ? (
         <>
@@ -72,10 +81,10 @@ function TestScenarioDrawerSettingsPanel({ fileName }: { 
fileName: string }) {
           </Title>
           {/* Temporary Mocked */}
           <FormSelect
+            aria-label="form-select-input"
             className={"kie-scesim-editor-drawer-settings--form-select"}
-            value={"1"}
-            aria-label="FormSelect Input"
             ouiaId="BasicFormSelect"
+            value={"1"}
           >
             <FormSelectOption isDisabled={true} key={0} value={"1"} 
label={"MockedDMN.dmn"} />
             <FormSelectOption isDisabled={true} key={1} value={"2"} 
label={"MockedDMN2.dmn"} />
@@ -84,19 +93,21 @@ function TestScenarioDrawerSettingsPanel({ fileName }: { 
fileName: string }) {
             {i18n.drawer.settings.dmnName}
           </Title>
           <TextInput
+            aria-label="dmn-name"
             className={"kie-scesim-editor-drawer-settings--text-input"}
-            value={settingsModel.dmnName?.__$$text}
-            type="text"
             isDisabled
+            type="text"
+            value={settingsModel.dmnName?.__$$text}
           />
           <Title className={"kie-scesim-editor-drawer-settings--title"} 
headingLevel={"h6"}>
             {i18n.drawer.settings.dmnNameSpace}
           </Title>
           <TextInput
+            aria-label="dmn-namespace"
             className={"kie-scesim-editor-drawer-settings--text-input"}
-            value={settingsModel.dmnNamespace?.__$$text}
-            type="text"
             isDisabled
+            type="text"
+            value={settingsModel.dmnNamespace?.__$$text}
           />
         </>
       ) : (
@@ -110,6 +121,7 @@ function TestScenarioDrawerSettingsPanel({ fileName }: { 
fileName: string }) {
             </Tooltip>
           </Title>
           <TextInput
+            aria-label="rule-session"
             className={"kie-scesim-editor-drawer-settings--text-input"}
             onChange={(value) => updateSettingsField("dmoSession", value)}
             placeholder={i18n.drawer.settings.kieSessionRulePlaceholder}
@@ -125,6 +137,7 @@ function TestScenarioDrawerSettingsPanel({ fileName }: { 
fileName: string }) {
             </Tooltip>
           </Title>
           <TextInput
+            aria-label="rule-flow-group"
             className={"kie-scesim-editor-drawer-settings--text-input"}
             onChange={(value) => updateSettingsField("ruleFlowGroup", value)}
             placeholder={i18n.drawer.settings.ruleFlowGroupPlaceholder}
diff --git 
a/packages/scesim-editor/src/externalModels/TestScenarioEditorDependenciesContext.tsx
 
b/packages/scesim-editor/src/externalModels/TestScenarioEditorDependenciesContext.tsx
new file mode 100644
index 00000000000..b74b9447f3d
--- /dev/null
+++ 
b/packages/scesim-editor/src/externalModels/TestScenarioEditorDependenciesContext.tsx
@@ -0,0 +1,64 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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 * as React from "react";
+import { useContext, useMemo } from "react";
+import {
+  OnRequestExternalModelsAvailableToInclude,
+  OnRequestExternalModelByPath,
+  ExternalDmnsIndex,
+} from "../TestScenarioEditor";
+
+export interface TestScenarioEditorExternalModelsContextType {
+  onRequestExternalModelByPath?: OnRequestExternalModelByPath;
+  onRequestExternalModelsAvailableToInclude?: 
OnRequestExternalModelsAvailableToInclude;
+  externalModelsByNamespace?: ExternalDmnsIndex;
+}
+
+const TestScenarioEditorExternalModelsContext = 
React.createContext<TestScenarioEditorExternalModelsContextType>(
+  {} as any
+);
+
+export function useExternalModels() {
+  return useContext(TestScenarioEditorExternalModelsContext);
+}
+
+export function TestScenarioEditorExternalModelsContextProvider(
+  _props: React.PropsWithChildren<TestScenarioEditorExternalModelsContextType>
+) {
+  const { children, ...props } = _props;
+
+  const value = useMemo<TestScenarioEditorExternalModelsContextType>(() => {
+    return {
+      externalModelsByNamespace: props.externalModelsByNamespace,
+      onRequestExternalModelByPath: props.onRequestExternalModelByPath,
+      onRequestExternalModelsAvailableToInclude: 
props.onRequestExternalModelsAvailableToInclude,
+    };
+  }, [
+    props.externalModelsByNamespace,
+    props.onRequestExternalModelByPath,
+    props.onRequestExternalModelsAvailableToInclude,
+  ]);
+
+  return (
+    <TestScenarioEditorExternalModelsContext.Provider value={value}>
+      {children}
+    </TestScenarioEditorExternalModelsContext.Provider>
+  );
+}
diff --git a/packages/scesim-editor/stories/dev/DevWebApp.stories.tsx 
b/packages/scesim-editor/stories/dev/DevWebApp.stories.tsx
index b9d91f5a091..580fe83116e 100644
--- a/packages/scesim-editor/stories/dev/DevWebApp.stories.tsx
+++ b/packages/scesim-editor/stories/dev/DevWebApp.stories.tsx
@@ -17,7 +17,7 @@
  * under the License.
  */
 
-import React, { useCallback, useRef, useState } from "react";
+import React, { useCallback, useMemo, useRef, useState } from "react";
 import type { Meta, StoryObj } from "@storybook/react";
 import "@patternfly/react-core/dist/styles/base.css";
 import { Button } from "@patternfly/react-core/dist/js/components/Button";
@@ -25,20 +25,33 @@ import { Flex, FlexItem } from 
"@patternfly/react-core/dist/js/layouts/Flex";
 import { Page, PageSection } from 
"@patternfly/react-core/dist/js/components/Page";
 import { Stack, StackItem } from "@patternfly/react-core/dist/js";
 import { SceSimMarshaller, SceSimModel, getMarshaller } from 
"@kie-tools/scesim-marshaller";
-import { OnSceSimModelChange, TestScenarioEditorProps } from 
"../../src/TestScenarioEditor";
+import {
+  ExternalDmnsIndex,
+  OnRequestExternalModelByPath,
+  OnRequestExternalModelsAvailableToInclude,
+  OnRequestToJumpToPath,
+  OnSceSimModelChange,
+  TestScenarioEditorProps,
+} from "../../src/TestScenarioEditor";
 import { SceSimEditorWrapper } from "../scesimEditorStoriesWrapper";
-import { emptySceSim } from "../misc/empty/Empty.stories";
-import { isOldEnoughDrl } from "../useCases/IsOldEnoughRule.stories";
-import { trafficViolationDmn } from "../useCases/TrafficViolationDmn.stories";
+import { emptyFileName, emptySceSim } from "../misc/empty/Empty.stories";
+import { isOldEnoughDrl, isOldEnoughDrlFileName } from 
"../useCases/IsOldEnoughRule.stories";
+import { trafficViolationDmn, trafficViolationDmnFileName } from 
"../useCases/TrafficViolationDmn.stories";
+import { availableModelsByPath } from "../examples/AvailableDMNModels";
 import "./DevWebApp.css";
 
-function DevWebApp(args: TestScenarioEditorProps) {
-  const [state, setState] = useState<{ marshaller: SceSimMarshaller; stack: 
SceSimModel[]; pointer: number }>(() => {
+function DevWebApp(props: TestScenarioEditorProps) {
+  const [fileName, setFileName] = useState<string | 
undefined>("Untitled.scesim");
+  const [state, setState] = useState<{
+    marshaller: SceSimMarshaller;
+    pointer: number;
+    stack: SceSimModel[];
+  }>(() => {
     const emptySceSimMarshaller = getMarshaller(emptySceSim);
     return {
       marshaller: emptySceSimMarshaller,
-      stack: [emptySceSimMarshaller.parser.parse()],
       pointer: 0,
+      stack: [emptySceSimMarshaller.parser.parse()],
     };
   });
 
@@ -54,11 +67,16 @@ function DevWebApp(args: TestScenarioEditorProps) {
   const downloadAsXml = useCallback(() => {
     if (downloadRef.current) {
       const fileBlob = new 
Blob([state.marshaller.builder.build(currentModel)], { type: "text/xml" });
-      downloadRef.current.download = `scesim-test-${makeid(10)}.scesim`;
+      downloadRef.current.download = fileName ?? 
`scesim-test-${makeid(10)}.scesim`;
       downloadRef.current.href = URL.createObjectURL(fileBlob);
       downloadRef.current.click();
     }
-  }, [currentModel, state.marshaller.builder]);
+  }, [currentModel, fileName, state.marshaller.builder]);
+
+  // TODO Unmarshall here the DMN
+  const externalModelsByNamespace = useMemo<ExternalDmnsIndex>(() => {
+    return 
currentModel.ScenarioSimulationModel.settings.dmnNamespace?.__$$text, {} as 
ExternalDmnsIndex;
+  }, [currentModel.ScenarioSimulationModel.settings.dmnNamespace]);
 
   const onDragOver = useCallback((e: React.DragEvent) => {
     e.preventDefault(); // Necessary to disable the browser's default 'onDrop' 
handling.
@@ -74,9 +92,14 @@ function DevWebApp(args: TestScenarioEditorProps) {
       [...e.dataTransfer.items].forEach((item, i) => {
         if (item.kind === "file") {
           const reader = new FileReader();
+          setFileName(item.getAsFile()?.name);
           reader.addEventListener("load", ({ target }) => {
             const marshaller = getMarshaller(target?.result as string);
-            setState({ marshaller, stack: [marshaller.parser.parse()], 
pointer: 0 });
+            setState({
+              marshaller,
+              pointer: 0,
+              stack: [marshaller.parser.parse()],
+            });
           });
           reader.readAsText(item.getAsFile() as any);
         }
@@ -95,9 +118,14 @@ function DevWebApp(args: TestScenarioEditorProps) {
     });
   }, []);
 
+  const onRequestToJumpToPath = useCallback<OnRequestToJumpToPath>((path) => {
+    alert("A request to open this file: " + path);
+  }, []);
+
   const onSelectModel = useCallback(
-    (newModel) => {
+    (newModel, fileName) => {
       onModelChange(getMarshaller(newModel).parser.parse());
+      setFileName(fileName);
     },
     [onModelChange]
   );
@@ -110,8 +138,8 @@ function DevWebApp(args: TestScenarioEditorProps) {
     const marshaller = getMarshaller(emptySceSim);
     setState({
       marshaller,
-      stack: [marshaller.parser.parse()],
       pointer: 0,
+      stack: [marshaller.parser.parse()],
     });
   }, []);
 
@@ -119,17 +147,13 @@ function DevWebApp(args: TestScenarioEditorProps) {
     setState((prev) => ({ ...prev, pointer: Math.max(0, prev.pointer - 1) }));
   }, []);
 
-  /* TODO: DMN DATA Retieve
-  const externalModelsByNamespace = useMemo<ExternalModelsIndex>(() => {
-    return (currentModel.definitions.import ?? []).reduce((acc, i) => {
-      acc[i["@_namespace"]] = modelsByNamespace[i["@_namespace"]];
-      return acc;
-    }, {} as ExternalModelsIndex);
-  }, [currentModel.definitions.import]);
-
   const onRequestExternalModelByPath = 
useCallback<OnRequestExternalModelByPath>(async (path) => {
     return availableModelsByPath[path] ?? null;
-  }, []);*/
+  }, []);
+
+  const onRequestExternalModelsAvailableToInclude = 
useCallback<OnRequestExternalModelsAvailableToInclude>(async () => {
+    return Object.keys(availableModelsByPath);
+  }, []);
 
   return (
     <Page onDragOver={onDragOver} onDrop={onDrop}>
@@ -148,11 +172,15 @@ function DevWebApp(args: TestScenarioEditorProps) {
           <StackItem>
             <Flex justifyContent={{ default: "justifyContentSpaceBetween" }}>
               <FlexItem shrink={{ default: "shrink" }}>
-                <Button onClick={() => 
onSelectModel(emptySceSim)}>Empty</Button>
+                <Button onClick={() => onSelectModel(emptySceSim, 
emptyFileName)}>Empty</Button>
                 &nbsp; &nbsp;
-                <Button onClick={() => onSelectModel(isOldEnoughDrl)}>Are They 
Old Enough?</Button>
+                <Button onClick={() => onSelectModel(isOldEnoughDrl, 
isOldEnoughDrlFileName)}>
+                  Are They Old Enough?
+                </Button>
                 &nbsp; &nbsp;
-                <Button onClick={() => 
onSelectModel(trafficViolationDmn)}>Traffic Violation</Button>
+                <Button onClick={() => onSelectModel(trafficViolationDmn, 
trafficViolationDmnFileName)}>
+                  Traffic Violation
+                </Button>
                 &nbsp; &nbsp; | &nbsp; &nbsp;
                 <Button
                   onClick={undo}
@@ -198,9 +226,14 @@ function DevWebApp(args: TestScenarioEditorProps) {
         variant={"light"}
       >
         {SceSimEditorWrapper({
-          issueTrackerHref: args.issueTrackerHref,
+          issueTrackerHref: props.issueTrackerHref,
+          externalModelsByNamespace: externalModelsByNamespace,
           model: currentModel,
           onModelChange: onModelChange,
+          onRequestExternalModelsAvailableToInclude: 
onRequestExternalModelsAvailableToInclude,
+          onRequestExternalModelByPath: onRequestExternalModelByPath,
+          onRequestToJumpToPath: onRequestToJumpToPath,
+          openFileNormalizedPosixPathRelativeToTheWorkspaceRoot: fileName,
         })}
       </PageSection>
     </Page>
@@ -232,5 +265,6 @@ export const WebApp: Story = {
   args: {
     issueTrackerHref: 
"https://github.com/apache/incubator-kie-issues/issues/new";,
     model: getMarshaller(emptySceSim).parser.parse(),
+    openFileNormalizedPosixPathRelativeToTheWorkspaceRoot: "Untitled.scesim",
   },
 };
diff --git a/packages/scesim-editor/stories/examples/AvailableDMNModels.ts 
b/packages/scesim-editor/stories/examples/AvailableDMNModels.ts
index 4d7722fa228..70d8fbb5f44 100644
--- a/packages/scesim-editor/stories/examples/AvailableDMNModels.ts
+++ b/packages/scesim-editor/stories/examples/AvailableDMNModels.ts
@@ -17,17 +17,19 @@
  * under the License.
  */
 
-import { DmnLatestModel, getMarshaller } from "@kie-tools/dmn-marshaller";
+import * as TestScenarioEditor from "../../src/TestScenarioEditor";
+import { getMarshaller } from "@kie-tools/dmn-marshaller";
+import { normalize } from 
"@kie-tools/dmn-marshaller/dist/normalization/normalize";
 import { LOAN_PRE_QUALIFICATION, TRAFFIC_VIOLATION } from 
"./ExternalDmnModels";
 
-export const loanPreQualification = getMarshaller(LOAN_PRE_QUALIFICATION, { 
upgradeTo: "latest" }).parser.parse();
-export const trafficViolationModel = getMarshaller(TRAFFIC_VIOLATION, { 
upgradeTo: "latest" }).parser.parse();
+export const loanPreQualification = normalize(
+  getMarshaller(LOAN_PRE_QUALIFICATION, { upgradeTo: "latest" }).parser.parse()
+);
+export const trafficViolationModel = normalize(
+  getMarshaller(TRAFFIC_VIOLATION, { upgradeTo: "latest" }).parser.parse()
+);
 
-export const avaiableModels: {
-  model: DmnLatestModel;
-  normalizedPosixPathRelativeToTheOpenFile: string;
-  svg: string;
-}[] = [
+export const avaiableModels: TestScenarioEditor.ExternalDmn[] = [
   {
     model: loanPreQualification,
     svg: "",
@@ -40,10 +42,12 @@ export const avaiableModels: {
   },
 ];
 
-// export const availableModelsByPath: Record<string, DmnEditor.ExternalModel> 
= Object.values(avaiableModels).reduce(
-//   (acc, v) => {
-//     acc[v.normalizedPosixPathRelativeToTheOpenFile] = v;
-//     return acc;
-//   },
-//   {} as Record<string, DmnEditor.ExternalModel>
-// );
+export const availableModelsByPath: Record<string, 
TestScenarioEditor.ExternalDmn> = Object.values(
+  avaiableModels
+).reduce(
+  (acc, v) => {
+    acc[v.normalizedPosixPathRelativeToTheOpenFile] = v;
+    return acc;
+  },
+  {} as Record<string, TestScenarioEditor.ExternalDmn>
+);
diff --git a/packages/scesim-editor/stories/misc/empty/Empty.stories.tsx 
b/packages/scesim-editor/stories/misc/empty/Empty.stories.tsx
index dc538bb058e..7aa0696d501 100644
--- a/packages/scesim-editor/stories/misc/empty/Empty.stories.tsx
+++ b/packages/scesim-editor/stories/misc/empty/Empty.stories.tsx
@@ -22,6 +22,7 @@ import { getMarshaller } from "@kie-tools/scesim-marshaller";
 import { TestScenarioEditor } from "../../../src/TestScenarioEditor";
 import { SceSimEditorWrapper, StorybookTestScenarioEditorProps } from 
"../../scesimEditorStoriesWrapper";
 
+export const emptyFileName = "Untitled.scesim";
 export const emptySceSim = `<?xml version="1.0" encoding="UTF-8"?>
 <ScenarioSimulationModel version="1.8" xmlns="https://kie.org/scesim/1.8";>
   <simulation>
@@ -190,6 +191,7 @@ export const Empty: Story = {
   render: (args) => SceSimEditorWrapper(args),
   args: {
     model: marshaller.parser.parse(),
+    openFileNormalizedPosixPathRelativeToTheWorkspaceRoot: emptyFileName,
     xml: marshaller.builder.build(model),
   },
 };
diff --git a/packages/scesim-editor/stories/scesimEditorStoriesWrapper.tsx 
b/packages/scesim-editor/stories/scesimEditorStoriesWrapper.tsx
index 7588aa49d41..802302e52ca 100644
--- a/packages/scesim-editor/stories/scesimEditorStoriesWrapper.tsx
+++ b/packages/scesim-editor/stories/scesimEditorStoriesWrapper.tsx
@@ -67,10 +67,19 @@ export function SceSimEditorWrapper(props: 
Partial<StorybookTestScenarioEditorPr
   return (
     <TestScenarioEditor
       ref={ref}
-      issueTrackerHref={args.issueTrackerHref}
+      issueTrackerHref={props?.issueTrackerHref ?? args.issueTrackerHref}
       model={model}
       onModelChange={onModelChange}
       onModelDebounceStateChanged={onModelDebounceStateChanged}
+      onRequestExternalModelByPath={props?.onRequestExternalModelByPath ?? 
args.onRequestExternalModelByPath}
+      onRequestExternalModelsAvailableToInclude={
+        props?.onRequestExternalModelsAvailableToInclude ?? 
args.onRequestExternalModelsAvailableToInclude
+      }
+      openFileNormalizedPosixPathRelativeToTheWorkspaceRoot={
+        props?.openFileNormalizedPosixPathRelativeToTheWorkspaceRoot ??
+        args.openFileNormalizedPosixPathRelativeToTheWorkspaceRoot
+      }
+      onRequestToJumpToPath={props?.onRequestToJumpToPath ?? 
args.onRequestToJumpToPath}
     />
   );
 }
diff --git 
a/packages/scesim-editor/stories/useCases/IsOldEnoughRule.stories.tsx 
b/packages/scesim-editor/stories/useCases/IsOldEnoughRule.stories.tsx
index 9f0e102caaf..0aa060b7715 100644
--- a/packages/scesim-editor/stories/useCases/IsOldEnoughRule.stories.tsx
+++ b/packages/scesim-editor/stories/useCases/IsOldEnoughRule.stories.tsx
@@ -23,6 +23,7 @@ import { getMarshaller } from "@kie-tools/scesim-marshaller";
 import { TestScenarioEditor } from "../../src/TestScenarioEditor";
 import { SceSimEditorWrapper, StorybookTestScenarioEditorProps } from 
"../scesimEditorStoriesWrapper";
 
+export const isOldEnoughDrlFileName = "IsOldEnough.scesim";
 export const isOldEnoughDrl = `<ScenarioSimulationModel version="1.8" 
xmlns="https://kie.org/scesim/1.8";>
 <simulation>
   <scesimModelDescriptor>
@@ -401,9 +402,10 @@ const marshaller = getMarshaller(isOldEnoughDrl);
 const model = marshaller.parser.parse();
 
 export const IsOldEnough: Story = {
-  render: (args) => SceSimEditorWrapper(args),
   args: {
     model: marshaller.parser.parse(),
     xml: marshaller.builder.build(model),
+    openFileNormalizedPosixPathRelativeToTheWorkspaceRoot: 
isOldEnoughDrlFileName,
   },
+  render: (args) => SceSimEditorWrapper(args),
 };
diff --git 
a/packages/scesim-editor/stories/useCases/TrafficViolationDmn.stories.tsx 
b/packages/scesim-editor/stories/useCases/TrafficViolationDmn.stories.tsx
index 19ba0102ca1..58856b5432a 100644
--- a/packages/scesim-editor/stories/useCases/TrafficViolationDmn.stories.tsx
+++ b/packages/scesim-editor/stories/useCases/TrafficViolationDmn.stories.tsx
@@ -23,6 +23,7 @@ import { getMarshaller } from "@kie-tools/scesim-marshaller";
 import { TestScenarioEditor } from "../../src/TestScenarioEditor";
 import { SceSimEditorWrapper, StorybookTestScenarioEditorProps } from 
"../scesimEditorStoriesWrapper";
 
+export const trafficViolationDmnFileName = "TrafficViolation.scesim";
 export const trafficViolationDmn = `<?xml version="1.0" encoding="UTF-8"?>
 <ScenarioSimulationModel version="1.8" xmlns="https://kie.org/scesim/1.8";>
   <simulation>
@@ -806,6 +807,7 @@ export const TrafficViolation: Story = {
   render: (args) => SceSimEditorWrapper(args),
   args: {
     model: marshaller.parser.parse(),
+    openFileNormalizedPosixPathRelativeToTheWorkspaceRoot: 
trafficViolationDmnFileName,
     xml: marshaller.builder.build(model),
   },
 };
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 23d9cdf6874..c799d568ed7 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -9317,6 +9317,9 @@ importers:
       '@kie-tools/boxed-expression-component':
         specifier: workspace:*
         version: link:../boxed-expression-component
+      '@kie-tools/dmn-marshaller':
+        specifier: workspace:*
+        version: link:../dmn-marshaller
       '@kie-tools/i18n-common-dictionary':
         specifier: workspace:*
         version: link:../i18n-common-dictionary
@@ -9460,6 +9463,85 @@ importers:
         specifier: ^5.9.0
         version: 5.9.0
 
+  packages/scesim-editor-envelope:
+    dependencies:
+      '@kie-tools-core/editor':
+        specifier: workspace:*
+        version: link:../editor
+      '@kie-tools-core/envelope':
+        specifier: workspace:*
+        version: link:../envelope
+      '@kie-tools-core/envelope-bus':
+        specifier: workspace:*
+        version: link:../envelope-bus
+      '@kie-tools-core/keyboard-shortcuts':
+        specifier: workspace:*
+        version: link:../keyboard-shortcuts
+      '@kie-tools-core/notifications':
+        specifier: workspace:*
+        version: link:../notifications
+      '@kie-tools-core/react-hooks':
+        specifier: workspace:*
+        version: link:../react-hooks
+      '@kie-tools-core/workspace':
+        specifier: workspace:*
+        version: link:../workspace
+      '@kie-tools/boxed-expression-component':
+        specifier: workspace:*
+        version: link:../boxed-expression-component
+      '@kie-tools/dmn-marshaller':
+        specifier: workspace:*
+        version: link:../dmn-marshaller
+      '@kie-tools/scesim-editor':
+        specifier: workspace:*
+        version: link:../scesim-editor
+      '@kie-tools/scesim-marshaller':
+        specifier: workspace:*
+        version: link:../scesim-marshaller
+      '@kie-tools/xml-parser-ts':
+        specifier: workspace:*
+        version: link:../xml-parser-ts
+      '@patternfly/react-core':
+        specifier: ^4.276.6
+        version: 4.276.6([email protected]([email protected]))([email protected])
+      react:
+        specifier: '>=17.0.2 <19.0.0'
+        version: 17.0.2
+      react-dom:
+        specifier: '>=17.0.2 <19.0.0'
+        version: 17.0.2([email protected])
+    devDependencies:
+      '@babel/core':
+        specifier: ^7.16.0
+        version: 7.24.9
+      '@babel/preset-env':
+        specifier: ^7.16.0
+        version: 7.24.7(@babel/[email protected])
+      '@babel/preset-react':
+        specifier: ^7.16.0
+        version: 7.22.15(@babel/[email protected])
+      '@kie-tools/eslint':
+        specifier: workspace:*
+        version: link:../eslint
+      '@kie-tools/root-env':
+        specifier: workspace:*
+        version: link:../root-env
+      '@kie-tools/tsconfig':
+        specifier: workspace:*
+        version: link:../tsconfig
+      '@types/react':
+        specifier: ^17.0.6
+        version: 17.0.21
+      '@types/react-dom':
+        specifier: ^17.0.5
+        version: 17.0.8
+      rimraf:
+        specifier: ^3.0.2
+        version: 3.0.2
+      typescript:
+        specifier: ^5.5.3
+        version: 5.5.3
+
   packages/scesim-marshaller:
     dependencies:
       '@kie-tools/xml-parser-ts':
diff --git a/repo/graph.dot b/repo/graph.dot
index 3ecfb0097fb..6d5c8fa636e 100644
--- a/repo/graph.dot
+++ b/repo/graph.dot
@@ -168,6 +168,7 @@ digraph G {
   "@kie-tools/runtime-tools-swf-webapp-components" [ color = "blue", fontcolor 
= "blue", style = "rounded" ];
   "@kie-tools/scesim-editor" [ color = "blue", fontcolor = "blue", style = 
"rounded" ];
   "@kie-tools/scesim-marshaller" [ color = "blue", fontcolor = "blue", style = 
"rounded" ];
+  "@kie-tools/scesim-editor-envelope" [ color = "blue", fontcolor = "blue", 
style = "rounded" ];
   "@kie-tools/serverless-logic-web-tools" [ color = "black", fontcolor = 
"black", style = "dashed, rounded" ];
   "@kie-tools/text-editor" [ color = "blue", fontcolor = "blue", style = 
"rounded" ];
   "@kie-tools/yard-editor" [ color = "blue", fontcolor = "blue", style = 
"rounded" ];
@@ -534,6 +535,9 @@ digraph G {
   "@kie-tools/runtime-tools-task-console-webapp" -> 
"@kie-tools/runtime-tools-shared-webapp-components" [ style = "solid", color = 
"blue" ];
   "@kie-tools/scesim-editor" -> "@kie-tools/boxed-expression-component" [ 
style = "solid", color = "blue" ];
   "@kie-tools/scesim-editor" -> "@kie-tools/scesim-marshaller" [ style = 
"solid", color = "blue" ];
+  "@kie-tools/scesim-editor-envelope" -> "@kie-tools-core/editor" [ style = 
"solid", color = "blue" ];
+  "@kie-tools/scesim-editor-envelope" -> "@kie-tools-core/react-hooks" [ style 
= "solid", color = "blue" ];
+  "@kie-tools/scesim-editor-envelope" -> "@kie-tools/scesim-editor" [ style = 
"solid", color = "blue" ];
   "@kie-tools/scesim-marshaller" -> "@kie-tools/xml-parser-ts-codegen" [ style 
= "dashed", color = "blue" ];
   "@kie-tools/serverless-logic-web-tools" -> 
"@kie-tools-core/kubernetes-bridge" [ style = "solid", color = "black" ];
   "@kie-tools/serverless-logic-web-tools" -> 
"@kie-tools-core/workspaces-git-fs" [ style = "solid", color = "black" ];
diff --git a/repo/graph.json b/repo/graph.json
index 2cdd586225a..d7f93f2dcd1 100644
--- a/repo/graph.json
+++ b/repo/graph.json
@@ -176,6 +176,7 @@
       { "id": "@kie-tools/runtime-tools-swf-webapp-components" },
       { "id": "@kie-tools/scesim-editor" },
       { "id": "@kie-tools/scesim-marshaller" },
+      { "id": "@kie-tools/scesim-editor-envelope" },
       { "id": "@kie-tools/serverless-logic-web-tools" },
       { "id": "@kie-tools/text-editor" },
       { "id": "@kie-tools/yard-editor" },
@@ -2180,6 +2181,21 @@
         "target": "@kie-tools/xml-parser-ts-codegen",
         "weight": 1
       },
+      {
+        "source": "@kie-tools/scesim-editor-envelope",
+        "target": "@kie-tools-core/editor",
+        "weight": 1
+      },
+      {
+        "source": "@kie-tools/scesim-editor-envelope",
+        "target": "@kie-tools-core/react-hooks",
+        "weight": 1
+      },
+      {
+        "source": "@kie-tools/scesim-editor-envelope",
+        "target": "@kie-tools/scesim-editor",
+        "weight": 1
+      },
       {
         "source": "@kie-tools/serverless-logic-web-tools",
         "target": "@kie-tools-core/kubernetes-bridge",
@@ -2722,6 +2738,7 @@
     ["@kie-tools/runtime-tools-swf-webapp-components", 
"packages/runtime-tools-swf-webapp-components"],
     ["@kie-tools/runtime-tools-task-console-webapp", 
"packages/runtime-tools-task-console-webapp"],
     ["@kie-tools/scesim-editor", "packages/scesim-editor"],
+    ["@kie-tools/scesim-editor-envelope", "packages/scesim-editor-envelope"],
     ["@kie-tools/scesim-marshaller", "packages/scesim-marshaller"],
     ["@kie-tools/serverless-logic-web-tools", 
"packages/serverless-logic-web-tools"],
     [


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to