diff --git a/packages/boxed-expression-component/README.md b/packages/boxed-expression-component/README.md index a9dc432b9c5..ee3b6bb598c 100644 --- a/packages/boxed-expression-component/README.md +++ b/packages/boxed-expression-component/README.md @@ -28,16 +28,6 @@ This editor provides the possibility to edit the expression related to a Decisio The main component is `src/components/BoxedExpressionEditor/BoxedExpressionEditor.tsx`. It represents the entry point for using the editor. -In the `showcase` folder, there is a tiny React application, which represent the Proof Of Value about how it is possible to integrate the `BoxedExpressionEditor` component inside another existing application. - -Once the showcase application gets launched, you can see on the right side of the page the JSON that is actually produced for the corresponding selected logic type. -Such JSON represents the model data that must be adopted to initialize the `BoxedExpressionEditor` component, by populating its props. - -The retrieval of the updated expression is performed by making usage of global functions, belonging to `beeApiWrapper` object, that must be available in the `Window` namespace and used by the `BoxedExpressionEditor` component. -All exposed function expected to exist, are defined in `src/api/BoxedExpressionEditor.ts`. - -Consider that the showcase app is able to display the most updated JSON representing an expression, because uses such APIs (please refer to `showcase/src/index.tsx`). - ## Scripts In the main project (where the components actually live), it is possible to execute, from the root folder, the following scripts (`pnpm` is recommended): diff --git a/packages/boxed-expression-component/src/@types/react-table.ts b/packages/boxed-expression-component/src/@types/react-table.ts index 0b73090593c..a80df179ba2 100644 --- a/packages/boxed-expression-component/src/@types/react-table.ts +++ b/packages/boxed-expression-component/src/@types/react-table.ts @@ -40,6 +40,9 @@ declare module "react-table" { export interface ColumnInterface { /** Used by react-table to hold the original id chosen for the column, independently of applied operations */ originalId?: string; + decisionId?: string; + decisionName?: string; + headerCellClickCallback?: () => void; /** Column identifier */ accessor: string; /** Column group type */ diff --git a/packages/boxed-expression-component/src/table/BeeTable/BeeTableHeader.tsx b/packages/boxed-expression-component/src/table/BeeTable/BeeTableHeader.tsx index 6b8da177426..db104fe4d53 100644 --- a/packages/boxed-expression-component/src/table/BeeTable/BeeTableHeader.tsx +++ b/packages/boxed-expression-component/src/table/BeeTable/BeeTableHeader.tsx @@ -30,6 +30,9 @@ import { BeeTableThController } from "./BeeTableThController"; import { assertUnreachable } from "../../expressions/ExpressionDefinitionRoot/ExpressionDefinitionLogicTypeSelector"; import { InlineEditableTextInput } from "./InlineEditableTextInput"; import { DEFAULT_EXPRESSION_VARIABLE_NAME } from "../../expressionVariable/ExpressionVariableMenu"; +import { Button } from "@patternfly/react-core/dist/js/components/Button"; +import { ArrowUpIcon } from "@patternfly/react-icons/dist/js/icons/arrow-up-icon"; +import { Flex } from "@patternfly/react-core/dist/js/layouts/Flex"; export interface BeeTableColumnUpdate { typeRef: string | undefined; @@ -229,43 +232,54 @@ export function BeeTableHeader({ } }} headerCellInfo={ -
- {column.headerCellElement ? ( - column.headerCellElement - ) : column.isInlineEditable && !isReadOnly ? ( - { - onExpressionHeaderUpdated( - column, - columnIndex - )({ "@_label": value, "@_typeRef": column.dataType }); - }} - isReadOnly={isReadOnly} + +
+ {column.headerCellElement ? ( + column.headerCellElement + ) : column.isInlineEditable && !isReadOnly ? ( + { + onExpressionHeaderUpdated( + column, + columnIndex + )({ "@_label": value, "@_typeRef": column.dataType }); + }} + isReadOnly={isReadOnly} + /> + ) : ( +

+ {column.label} +

+ )} + {column.dataType ? ( +

+ ({column.dataType}) +

+ ) : null} +
+ {column.decisionId !== undefined && column.headerCellClickCallback !== undefined && ( +
+ } /> )} diff --git a/packages/dmn-editor-envelope/src/DmnEditorFactory.tsx b/packages/dmn-editor-envelope/src/DmnEditorFactory.tsx index 0af0ec31460..ca44d6f5bcb 100644 --- a/packages/dmn-editor-envelope/src/DmnEditorFactory.tsx +++ b/packages/dmn-editor-envelope/src/DmnEditorFactory.tsx @@ -42,7 +42,7 @@ export class DmnEditorFactory implements EditorFactory { this.setState((prev) => ({ ...prev, pointer: Math.max(0, prev.pointer - 1) })); } diff --git a/packages/dmn-editor-envelope/src/NewDmnEditorChannelApi.ts b/packages/dmn-editor-envelope/src/NewDmnEditorChannelApi.ts new file mode 100644 index 00000000000..a29086a40ed --- /dev/null +++ b/packages/dmn-editor-envelope/src/NewDmnEditorChannelApi.ts @@ -0,0 +1,22 @@ +/* + * 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 { KogitoEditorChannelApi } from "@kie-tools-core/editor/dist/api"; + +export interface NewDmnEditorChannelApi extends KogitoEditorChannelApi {} diff --git a/packages/dmn-editor-envelope/src/NewDmnEditorEnvelopeApi.ts b/packages/dmn-editor-envelope/src/NewDmnEditorEnvelopeApi.ts new file mode 100644 index 00000000000..692f3ca8622 --- /dev/null +++ b/packages/dmn-editor-envelope/src/NewDmnEditorEnvelopeApi.ts @@ -0,0 +1,28 @@ +/* + * 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 { KogitoEditorEnvelopeApi } from "@kie-tools-core/editor/dist/api"; + +export interface NewDmnEditorEnvelopeApi extends KogitoEditorEnvelopeApi { + /** + * Open boxed expression editor for given node + * @param nodeId id of the node to open + */ + dmnEditor_openBoxedExpressionEditor(nodeId: string): void; +} diff --git a/packages/dmn-editor-envelope/src/NewDmnEditorEnvelopeApiFactory.ts b/packages/dmn-editor-envelope/src/NewDmnEditorEnvelopeApiFactory.ts new file mode 100644 index 00000000000..8c58c9dbdcf --- /dev/null +++ b/packages/dmn-editor-envelope/src/NewDmnEditorEnvelopeApiFactory.ts @@ -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. + */ + +import { EnvelopeApiFactoryArgs } from "@kie-tools-core/envelope"; +import { EditorEnvelopeViewApi, KogitoEditorEnvelopeApiImpl } from "@kie-tools-core/editor/dist/envelope"; +import { KogitoEditorEnvelopeContextType } from "@kie-tools-core/editor/dist/api"; +import { NewDmnEditorInterface } from "./NewDmnEditorFactory"; +import { NewDmnEditorEnvelopeApi } from "./NewDmnEditorEnvelopeApi"; +import { NewDmnEditorChannelApi } from "./NewDmnEditorChannelApi"; +import { NewDmnEditorFactory } from "./NewDmnEditorFactory"; + +export type NewDmnEnvelopeApiFactoryArgs = EnvelopeApiFactoryArgs< + NewDmnEditorEnvelopeApi, + NewDmnEditorChannelApi, + EditorEnvelopeViewApi, + KogitoEditorEnvelopeContextType +>; + +export class NewDmnEditorEnvelopeApiImpl + extends KogitoEditorEnvelopeApiImpl + implements NewDmnEditorEnvelopeApi +{ + constructor(readonly dmnArgs: NewDmnEnvelopeApiFactoryArgs) { + super(dmnArgs, new NewDmnEditorFactory()); + } + + public dmnEditor_openBoxedExpressionEditor(nodeId: string): void { + this.getEditorOrThrowError().openBoxedExpressionEditor(nodeId); + } +} diff --git a/packages/dmn-editor-envelope/src/NewDmnEditorFactory.tsx b/packages/dmn-editor-envelope/src/NewDmnEditorFactory.tsx new file mode 100644 index 00000000000..ca94144d6c6 --- /dev/null +++ b/packages/dmn-editor-envelope/src/NewDmnEditorFactory.tsx @@ -0,0 +1,42 @@ +/* + * 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 { EditorFactory, EditorInitArgs, KogitoEditorEnvelopeContextType } from "@kie-tools-core/editor/dist/api"; +import { NewDmnEditorChannelApi } from "./NewDmnEditorChannelApi"; +import { DmnEditorInterface } from "./DmnEditorFactory"; + +export class NewDmnEditorFactory implements EditorFactory { + public createEditor( + envelopeContext: KogitoEditorEnvelopeContextType, + initArgs: EditorInitArgs + ): Promise { + return Promise.resolve(new NewDmnEditorInterface(envelopeContext, initArgs)); + } +} + +export class NewDmnEditorInterface extends DmnEditorInterface { + /** + * Open boxed expression editor for given node + * @param nodeId id of the node to open + */ + public openBoxedExpressionEditor(nodeId: string): void { + this.self.openBoxedExpressionEditor(nodeId); + } +} diff --git a/packages/dmn-editor/src/DmnEditor.tsx b/packages/dmn-editor/src/DmnEditor.tsx index 3a1b18aa288..e1115f7f97f 100644 --- a/packages/dmn-editor/src/DmnEditor.tsx +++ b/packages/dmn-editor/src/DmnEditor.tsx @@ -67,6 +67,7 @@ const SVG_PADDING = 20; export type DmnEditorRef = { reset: (mode: DmnLatestModel) => void; getDiagramSvg: () => Promise; + openBoxedExpressionEditor: (nodeId: string) => void; getCommands: () => Commands; }; @@ -203,6 +204,11 @@ export const DmnEditorInternal = ({ const state = dmnEditorStoreApi.getState(); return state.dispatch(state).dmn.reset(normalize(model)); }, + openBoxedExpressionEditor: (nodeId: string) => { + dmnEditorStoreApi.setState((state) => { + state.dispatch(state).boxedExpressionEditor.open(nodeId); + }); + }, getDiagramSvg: async () => { const nodes = diagramRef.current?.getReactFlowInstance()?.getNodes(); const edges = diagramRef.current?.getReactFlowInstance()?.getEdges(); diff --git a/packages/form-dmn/src/FormDmnOutputs.tsx b/packages/form-dmn/src/FormDmnOutputs.tsx index 9cd9ac6ce94..fe143392822 100644 --- a/packages/form-dmn/src/FormDmnOutputs.tsx +++ b/packages/form-dmn/src/FormDmnOutputs.tsx @@ -19,6 +19,7 @@ import * as React from "react"; import { useCallback, useEffect, useMemo, useRef, useState } from "react"; +import { ArrowUpIcon } from "@patternfly/react-icons/dist/js/icons/arrow-up-icon"; import { CheckCircleIcon } from "@patternfly/react-icons/dist/js/icons/check-circle-icon"; import { InfoCircleIcon } from "@patternfly/react-icons/dist/js/icons/info-circle-icon"; import { ExclamationCircleIcon } from "@patternfly/react-icons/dist/js/icons/exclamation-circle-icon"; @@ -40,6 +41,8 @@ import "./styles.scss"; import { ErrorBoundary } from "@kie-tools/dmn-runner/dist/ErrorBoundary"; import { ExclamationTriangleIcon } from "@patternfly/react-icons/dist/js/icons/exclamation-triangle-icon"; import { DecisionResult, DmnEvaluationStatus, DmnEvaluationResult } from "@kie-tools/extended-services-api"; +import { Flex } from "@patternfly/react-core/dist/js/layouts/Flex"; +import { Button } from "@patternfly/react-core/dist/js/components/Button"; const ISSUES_URL = "https://github.com/apache/incubator-kie-issues/issues"; @@ -61,6 +64,7 @@ export interface FormDmnOutputsProps { locale?: string; notificationsPanel: boolean; openExecutionTab?: () => void; + openBoxedExpressionEditor?: (nodeId: string) => void; } export function FormDmnOutputs({ openExecutionTab, ...props }: FormDmnOutputsProps) { @@ -258,7 +262,18 @@ export function FormDmnOutputs({ openExecutionTab, ...props }: FormDmnOutputsPro onAnimationEnd={(e) => onAnimationEnd(e, index)} > - {dmnFormResult.decisionName} + + {dmnFormResult.decisionName} + {props.openBoxedExpressionEditor !== undefined && ( +