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 aab8cc10780 kie-issues#1852: Load custom forms in jBPM Quarkus Dev UI
extension’s Tasks page (#2948)
aab8cc10780 is described below
commit aab8cc107809a519cf1650daf2c255cfd40a443a
Author: Luiz João Motta <[email protected]>
AuthorDate: Fri Feb 28 22:02:29 2025 -0300
kie-issues#1852: Load custom forms in jBPM Quarkus Dev UI extension’s Tasks
page (#2948)
---
.rat-excludes | 8 ++
.../main/resources/custom-forms-dev/hiring.config | 7 ++
.../src/main/resources/custom-forms-dev/hiring.tsx | 101 +++++++++++++++++++++
.../custom-forms-dev/hiring_ITInterview.config | 12 +++
.../custom-forms-dev/hiring_ITInterview.html | 71 +++++++++++++++
.../devui/runtime/forms/impl/FormsStorageImpl.java | 9 --
packages/jbpm-quarkus-devui/package.json | 4 +-
.../CustomTaskFormDisplayer.tsx | 43 +++++----
.../src/TaskForms/TaskFormGatewayApi.ts | 29 +++++-
.../envelope/components/FormEditor/FormEditor.tsx | 2 +-
.../src/formDisplayer/api/types.ts | 9 --
.../embedded/EmbeddedFormDisplayer.tsx | 2 +-
.../components/FormDisplayer/FormDisplayer.tsx | 33 ++++---
.../HtmlFormRenderer/HtmlFormRenderer.tsx | 2 +-
.../ReactFormRenderer/ReactFormRenderer.tsx | 2 +-
.../ResourcesContainer/ResourcesContainer.tsx | 2 +-
16 files changed, 271 insertions(+), 65 deletions(-)
diff --git a/.rat-excludes b/.rat-excludes
index 4e47f2f52e3..50cc8b07991 100644
--- a/.rat-excludes
+++ b/.rat-excludes
@@ -510,6 +510,14 @@ README.md
ImportJavaClasses.test.tsx.snap
# packages/jbpm-quarkus-devui/jbpm-quarkus-devui-parent.iml
jbpm-quarkus-devui-parent.iml
+#
packages/jbpm-quarkus-devui/dev/src/main/resources/custom-forms-dev/hiring_ITInterview.html
+hiring_ITInterview.html
+#
packages/jbpm-quarkus-devui/dev/src/main/resources/custom-forms-dev/hiring_ITInterview.config
+hiring_ITInterview.config
+#
packages/jbpm-quarkus-devui/dev/src/main/resources/custom-forms-dev/hiring.tsx
+hiring.tsx
+#
packages/jbpm-quarkus-devui/dev/src/main/resources/custom-forms-dev/hiring.config
+hiring.config
#
packages/jbpm-quarkus-devui/jbpm-quarkus-devui-runtime/src/test/resources/forms/hiring_HRInterview.config
hiring_HRInterview.config
#
packages/jbpm-quarkus-devui/jbpm-quarkus-devui-runtime/src/test/resources/forms/hiring_ITInterview.config
diff --git
a/packages/jbpm-quarkus-devui/dev/src/main/resources/custom-forms-dev/hiring.config
b/packages/jbpm-quarkus-devui/dev/src/main/resources/custom-forms-dev/hiring.config
new file mode 100644
index 00000000000..90c1c53baa0
--- /dev/null
+++
b/packages/jbpm-quarkus-devui/dev/src/main/resources/custom-forms-dev/hiring.config
@@ -0,0 +1,7 @@
+{
+ "schema" :
"{\"$schema\":\"https://json-schema.org/draft/2019-09/schema\",\"type\":\"object\",\"properties\":{\"candidate\":{\"type\":\"string\"},\"experience\":{\"type\":\"integer\"},\"skills\":{\"type\":\"string\"}}}",
+ "resources" : {
+ "scripts" : { },
+ "styles" : { }
+ }
+}
\ No newline at end of file
diff --git
a/packages/jbpm-quarkus-devui/dev/src/main/resources/custom-forms-dev/hiring.tsx
b/packages/jbpm-quarkus-devui/dev/src/main/resources/custom-forms-dev/hiring.tsx
new file mode 100644
index 00000000000..88b3c92bc55
--- /dev/null
+++
b/packages/jbpm-quarkus-devui/dev/src/main/resources/custom-forms-dev/hiring.tsx
@@ -0,0 +1,101 @@
+import React, { useCallback, useEffect, useState } from "react";
+import { TextInput, FormGroup } from "@patternfly/react-core";
+const Form__hiring: React.FC<any> = (props: any) => {
+ const [formApi, setFormApi] = useState<any>();
+ const [candidate, set__candidate] = useState<string>("");
+ const [experience, set__experience] = useState<number>();
+ const [skills, set__skills] = useState<string>("");
+ /* Utility function that fills the form with the data received from the
kogito runtime */
+ const setFormData = (data) => {
+ if (!data) {
+ return;
+ }
+ set__candidate(data?.candidate ?? "");
+ set__experience(data?.experience);
+ set__skills(data?.skills ?? "");
+ };
+ /* Utility function to generate the expected form output as a json object */
+ const getFormData = useCallback(() => {
+ const formData: any = {};
+ formData.candidate = candidate;
+ formData.experience = experience;
+ formData.skills = skills;
+ return formData;
+ }, [candidate, experience, skills]);
+ /* Utility function to validate the form on the 'beforeSubmit' Lifecycle
Hook */
+ const validateForm = useCallback(() => {}, []);
+ /* Utility function to perform actions on the on the 'afterSubmit' Lifecycle
Hook */
+ const afterSubmit = useCallback((result) => {}, []);
+ useEffect(() => {
+ if (formApi) {
+ /*
+ Form Lifecycle Hook that will be executed before the form is submitted.
+ Throwing an error will stop the form submit. Usually should be used to
validate the form.
+ */
+ formApi.beforeSubmit = () => validateForm();
+ /*
+ Form Lifecycle Hook that will be executed after the form is submitted.
+ It will receive a response object containing the `type` flag
indicating if the submit has been successful and `info` with extra information
about the submit result.
+ */
+ formApi.afterSubmit = (result) => afterSubmit(result);
+ /* Generates the expected form output object to be posted */
+ formApi.getFormData = () => getFormData();
+ }
+ }, [getFormData, validateForm, afterSubmit]);
+ useEffect(() => {
+ /*
+ Call to the Kogito console form engine. It will establish the connection
with the console embeding the form
+ and return an instance of FormAPI that will allow hook custom code into
the form lifecycle.
+ The `window.Form.openForm` call expects an object with the following
entries:
+ - onOpen: Callback that will be called after the connection with the
console is established. The callback
+ will receive the following arguments:
+ - data: the data to be bound into the form
+ - ctx: info about the context where the form is being displayed.
This will contain information such as the form JSON Schema, process/task,
user...
+ */
+ const api = window.Form.openForm({
+ onOpen: (data, context) => {
+ setFormData(data);
+ },
+ });
+ setFormApi(api);
+ }, []);
+ return (
+ <div className={"pf-c-form"}>
+ <FormGroup fieldId={"uniforms-0006-0000"} label={"Candidate"}
isRequired={false}>
+ <TextInput
+ name={"candidate"}
+ id={"uniforms-0006-0000"}
+ isDisabled={false}
+ placeholder={""}
+ type={"text"}
+ value={candidate}
+ onChange={set__candidate}
+ />
+ </FormGroup>
+ <FormGroup fieldId={"uniforms-0006-0002"} label={"Experience Level"}
isRequired={false}>
+ <TextInput
+ type={"number"}
+ name={"experience"}
+ isDisabled={false}
+ id={"uniforms-0006-0002"}
+ placeholder={""}
+ step={1}
+ value={experience}
+ onChange={(newValue) => set__experience(Number(newValue))}
+ />
+ </FormGroup>
+ <FormGroup fieldId={"uniforms-0006-0003"} label={"Skills"}
isRequired={false}>
+ <TextInput
+ name={"skills"}
+ id={"uniforms-0006-0003"}
+ isDisabled={false}
+ placeholder={""}
+ type={"text"}
+ value={skills}
+ onChange={set__skills}
+ />
+ </FormGroup>
+ </div>
+ );
+};
+export default Form__hiring;
diff --git
a/packages/jbpm-quarkus-devui/dev/src/main/resources/custom-forms-dev/hiring_ITInterview.config
b/packages/jbpm-quarkus-devui/dev/src/main/resources/custom-forms-dev/hiring_ITInterview.config
new file mode 100644
index 00000000000..ddbc10aaf7c
--- /dev/null
+++
b/packages/jbpm-quarkus-devui/dev/src/main/resources/custom-forms-dev/hiring_ITInterview.config
@@ -0,0 +1,12 @@
+{
+ "schema":
"{\"$schema\":\"https://json-schema.org/draft/2019-09/schema\",\"type\":\"object\",\"properties\":{\"approve\":{\"type\":\"boolean\",\"input\":true,\"output\":true},\"baseSalary\":{\"type\":\"integer\",\"input\":true},\"bonus\":{\"type\":\"integer\",\"input\":true},\"candidate\":{\"type\":\"string\",\"input\":true},\"category\":{\"type\":\"string\",\"input\":true}}}",
+ "resources": {
+ "styles": {
+ "bootstrap.min.css":
"https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css"
+ },
+ "scripts": {
+ "jquery.js":
"https://cdn.jsdelivr.net/npm/[email protected]/dist/jquery.slim.min.js",
+ "bootstrap.bundle.min.js":
"https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.min.js"
+ }
+ }
+}
\ No newline at end of file
diff --git
a/packages/jbpm-quarkus-devui/dev/src/main/resources/custom-forms-dev/hiring_ITInterview.html
b/packages/jbpm-quarkus-devui/dev/src/main/resources/custom-forms-dev/hiring_ITInterview.html
new file mode 100644
index 00000000000..246f41c2ff3
--- /dev/null
+++
b/packages/jbpm-quarkus-devui/dev/src/main/resources/custom-forms-dev/hiring_ITInterview.html
@@ -0,0 +1,71 @@
+<div>
+ <div class="form-check">
+ <input type="checkbox" id="approve" name="approve"
class="form-check-input" />
+ <label class="form-check-label" for="approve">I approve this
candidate!</label>
+ </div>
+ <div class="form-group">
+ <label for="baseSalary">Base salary</label>
+ <input type="number" class="form-control" id="baseSalary"
name="baseSalary" disabled step="1" value="" />
+ </div>
+ <div class="form-group">
+ <label for="bonus">Bonus</label>
+ <input type="number" class="form-control" id="bonus" name="bonus" disabled
step="1" value="" />
+ </div>
+ <div class="form-group">
+ <label for="candidate">Candidate</label>
+ <input type="text" id="candidate" name="candidate" class="form-control"
disabled value="" />
+ </div>
+ <div class="form-group">
+ <label for="category">Area</label>
+ <input type="text" id="category" name="category" class="form-control"
disabled value="" />
+ </div>
+ <script>
+ /* Utility function that fills the form with the data received from the
kogito runtime */
+ function setFormData(data) {
+ if (!data) {
+ return;
+ }
+ document.getElementById("approve").checked = data?.approve;
+ document.getElementById("baseSalary").value = data?.baseSalary ?? "";
+ document.getElementById("bonus").value = data?.bonus ?? "";
+ document.getElementById("candidate").value = data?.candidate ?? "";
+ document.getElementById("category").value = data?.category ?? "";
+ }
+ /* Utility function to generate the expected form output as a json object
*/
+ function getFormData() {
+ const formData = {};
+ formData.approve = document.getElementById("approve").checked;
+ return formData;
+ }
+ /* Utility function to validate the form on the 'beforeSubmit' Lifecycle
Hook */
+ function validateForm() {}
+ /*
+ Call to the Kogito console form engine. It will establish the
connection with the console embeding the form
+ and return an instance of FormAPI that will allow hook custom code
into the form lifecycle.
+ The `window.Form.openForm` call expects an object with the
following entries:
+ - onOpen: Callback that will be called after the connection
with the console is established. The callback
+ will receive the following arguments:
+ - data: the data to be bound into the form
+ - ctx: info about the context where the form is being
displayed. This will contain information such as the form JSON Schema,
process/task, user...
+ */
+ const formApi = window.Form.openForm({
+ onOpen: (data, context) => {
+ setFormData(data);
+ },
+ });
+ /*
+ Form Lifecycle Hook that will be executed before the form is
submitted.
+ Throwing an error will stop the form submit. Usually should be
used to validate the form.
+ */
+ formApi.beforeSubmit = () => {
+ validateForm();
+ };
+ /*
+ Form Lifecycle Hook that will be executed after the form is
submitted.
+ It will receive a response object containing the `type` flag
indicating if the submit has been successful and `info` with extra information
about the submit result.
+ */
+ formApi.afterSubmit = (response) => {};
+ /* Generates the expected form output object to be posted */
+ formApi.getFormData = () => getFormData();
+ </script>
+</div>
diff --git
a/packages/jbpm-quarkus-devui/jbpm-quarkus-devui-runtime/src/main/java/org/jbpm/quarkus/devui/runtime/forms/impl/FormsStorageImpl.java
b/packages/jbpm-quarkus-devui/jbpm-quarkus-devui-runtime/src/main/java/org/jbpm/quarkus/devui/runtime/forms/impl/FormsStorageImpl.java
index 6bea503cffd..95a57bf79b6 100644
---
a/packages/jbpm-quarkus-devui/jbpm-quarkus-devui-runtime/src/main/java/org/jbpm/quarkus/devui/runtime/forms/impl/FormsStorageImpl.java
+++
b/packages/jbpm-quarkus-devui/jbpm-quarkus-devui-runtime/src/main/java/org/jbpm/quarkus/devui/runtime/forms/impl/FormsStorageImpl.java
@@ -57,14 +57,10 @@ import jakarta.enterprise.context.ApplicationScoped;
public class FormsStorageImpl implements FormsStorage {
public static final String PROJECT_FORM_STORAGE_PROP =
"quarkus.kogito-runtime-tools.forms.folder";
-
private static final String CONFIG_EXT = ".config";
-
private static final String FORMS_STORAGE_PATH = "/custom-forms-dev";
-
private static final String JAR_FORMS_STORAGE_PATH = "/target/classes" +
FORMS_STORAGE_PATH;
private static final String FS_FORMS_STORAGE_PATH = "/src/main/resources"
+ FORMS_STORAGE_PATH;
-
private static final Logger LOGGER =
LoggerFactory.getLogger(FormsStorageImpl.class);
private final Map<String, FormInfo> formInfoMap = new HashMap<>();
@@ -179,13 +175,10 @@ public class FormsStorageImpl implements FormsStorage {
}
JsonObject configJSON = new JsonObject(configStr);
-
FormResources resources = new FormResources();
-
JsonObject resourcesJSON = configJSON.getJsonObject("resources");
resourcesJSON.getJsonObject("scripts").stream().forEach(entry ->
resources.getScripts().put(entry.getKey(), entry.getValue().toString()));
-
resourcesJSON.getJsonObject("styles").stream().forEach(entry ->
resources.getStyles().put(entry.getKey(), entry.getValue().toString()));
return new FormConfiguration(configJSON.getString("schema"),
resources);
@@ -225,14 +218,12 @@ public class FormsStorageImpl implements FormsStorage {
}
FileUtils.write(formFile, formContent.getSource(),
StandardCharsets.UTF_8);
-
FileUtils.write(configFile,
JsonObject.mapFrom(formContent.getConfiguration()).encodePrettily(),
StandardCharsets.UTF_8);
LocalDateTime lastModified =
LocalDateTime.ofInstant(Instant.ofEpochMilli(System.currentTimeMillis()),
TimeZone.getDefault().toZoneId());
FormInfo newInfo = new FormInfo(formName, formInfo.getType(),
lastModified);
formInfoMap.put(formName, newInfo);
-
modifiedForms.put(formName, new Form(newInfo, formContent.getSource(),
formContent.getConfiguration()));
}
diff --git a/packages/jbpm-quarkus-devui/package.json
b/packages/jbpm-quarkus-devui/package.json
index 353cf95be0c..973a09bd8d4 100644
--- a/packages/jbpm-quarkus-devui/package.json
+++ b/packages/jbpm-quarkus-devui/package.json
@@ -26,8 +26,8 @@
"quarkus:dev:darwin:linux": "mvn clean package quarkus:dev -DskipTests",
"quarkus:dev:win32": "mvn clean package quarkus:dev `-DskipTests",
"start": "run-script-os",
- "start:darwin:linux": "pnpm build:dev && mvn -f ./dev/pom.xml quarkus:dev",
- "start:win32": "pnpm build:dev && mvn -f ./dev/pom.xml quarkus:dev
-Dquarkus.http.host=127.0.0.1 -Dkogito.service.url=http://127.0.0.1:8080/kie
-Dkogito.jobs-service.url=http://127.0.0.1:8080/kie
-Dkogito.data-index.urll=http://127.0.0.1:8080/kie"
+ "start:darwin:linux": "pnpm build:dev && mvn -f ./dev/pom.xml clean
quarkus:dev",
+ "start:win32": "pnpm build:dev && mvn -f ./dev/pom.xml clean quarkus:dev
-Dquarkus.http.host=127.0.0.1 -Dkogito.service.url=http://127.0.0.1:8080/kie
-Dkogito.jobs-service.url=http://127.0.0.1:8080/kie
-Dkogito.data-index.urll=http://127.0.0.1:8080/kie"
},
"dependencies": {
"@kie-tools/maven-base": "workspace:*"
diff --git
a/packages/runtime-tools-process-enveloped-components/src/taskForm/envelope/components/CustomTaskFormDisplayer/CustomTaskFormDisplayer.tsx
b/packages/runtime-tools-process-enveloped-components/src/taskForm/envelope/components/CustomTaskFormDisplayer/CustomTaskFormDisplayer.tsx
index d3719005377..4261e55d695 100644
---
a/packages/runtime-tools-process-enveloped-components/src/taskForm/envelope/components/CustomTaskFormDisplayer/CustomTaskFormDisplayer.tsx
+++
b/packages/runtime-tools-process-enveloped-components/src/taskForm/envelope/components/CustomTaskFormDisplayer/CustomTaskFormDisplayer.tsx
@@ -16,7 +16,7 @@
* specific language governing permissions and limitations
* under the License.
*/
-import React, { useEffect, useRef, useState } from "react";
+import React, { useEffect, useRef, useState, useCallback } from "react";
import { v4 as uuidv4 } from "uuid";
import { UserTaskInstance } from
"@kie-tools/runtime-tools-process-gateway-api/dist/types";
import { generateFormData } from "../utils/TaskFormDataUtils";
@@ -65,24 +65,27 @@ const CustomTaskFormDisplayer:
React.FC<CustomTaskFormDisplayerProps & OUIAProps
const [formOpened, setFormOpened] = useState<FormOpened>();
const [submitted, setSubmitted] = useState<boolean>(false);
- const doSubmit = async (phase: string, payload: any) => {
- const formDisplayerApi = formDisplayerApiRef.current;
+ const doSubmit = useCallback(
+ async (phase: string, payload: any) => {
+ const formDisplayerApi = formDisplayerApiRef.current;
- try {
- const response = await driver.doSubmit(phase, payload);
- formDisplayerApi!.notifySubmitResult({
- type: FormSubmitResponseType.SUCCESS,
- info: response,
- });
- } catch (error) {
- formDisplayerApi!.notifySubmitResult({
- type: FormSubmitResponseType.FAILURE,
- info: error,
- });
- } finally {
- setSubmitted(true);
- }
- };
+ try {
+ const response = await driver.doSubmit(phase, payload);
+ formDisplayerApi!.notifySubmitResult({
+ type: FormSubmitResponseType.SUCCESS,
+ info: response,
+ });
+ } catch (error) {
+ formDisplayerApi!.notifySubmitResult({
+ type: FormSubmitResponseType.FAILURE,
+ info: error,
+ });
+ } finally {
+ setSubmitted(true);
+ }
+ },
+ [driver]
+ );
useEffect(() => {
if (phases) {
@@ -104,13 +107,13 @@ const CustomTaskFormDisplayer:
React.FC<CustomTaskFormDisplayerProps & OUIAProps
});
setFormActions(actions);
}
- }, []);
+ }, [doSubmit, phases]);
useEffect(() => {
if (formOpened) {
document.getElementById(`${formUUID}-form`)!.style.visibility =
"visible";
}
- }, [formOpened]);
+ }, [formOpened, formUUID]);
return (
<div {...componentOuiaProps(ouiaId, "custom-form-displayer", ouiaSafe)}
style={{ height: "100%" }}>
diff --git
a/packages/runtime-tools-process-webapp-components/src/TaskForms/TaskFormGatewayApi.ts
b/packages/runtime-tools-process-webapp-components/src/TaskForms/TaskFormGatewayApi.ts
index 282bfdb48e0..71408a62191 100644
---
a/packages/runtime-tools-process-webapp-components/src/TaskForms/TaskFormGatewayApi.ts
+++
b/packages/runtime-tools-process-webapp-components/src/TaskForms/TaskFormGatewayApi.ts
@@ -28,7 +28,7 @@ import { Form } from
"@kie-tools/runtime-tools-shared-gateway-api/dist/types";
export interface TaskFormGatewayApi {
getTaskFormSchema(userTask: UserTaskInstance, headers?: any):
Promise<Record<string, any>>;
- getCustomForm(userTask: UserTaskInstance): Promise<Form>;
+ getCustomForm(userTask: UserTaskInstance, headers?: any): Promise<Form>;
doSubmit(userTask: UserTaskInstance, phase: string, payload: any, headers?:
any): Promise<any>;
@@ -92,6 +92,27 @@ export class TaskFormGatewayApiImpl implements
TaskFormGatewayApi {
});
}
+ fetchCustomForm(endpoint: string, headers?: any) {
+ return new Promise<Form>((resolve, reject) => {
+ axios
+ .get(this.replaceEndpointBaseUrl(endpoint), {
+ headers: {
+ "Content-Type": "application/json",
+ Accept: "application/json",
+ ...headers,
+ },
+ })
+ .then((response) => {
+ if (response.status == 200) {
+ resolve(response.data);
+ } else {
+ reject(response);
+ }
+ })
+ .catch((error) => reject(error));
+ });
+ }
+
fetchTaskTransitionPhases(endpoint: string, headers?: any) {
return new Promise<string[]>((resolve, reject) => {
axios
@@ -128,8 +149,10 @@ export class TaskFormGatewayApiImpl implements
TaskFormGatewayApi {
return this.fetchTaskFormSchema(endpoint, headers);
}
- getCustomForm(userTask: UserTaskInstance): Promise<Form> {
- return Promise.reject();
+ getCustomForm(userTask: UserTaskInstance, headers?: any): Promise<Form> {
+ const baseUrl = cleanUserTaskEndpoint(userTask);
+ const endpoint = `${baseUrl}/forms/${userTask.processId}_${userTask.name}`;
+ return this.fetchCustomForm(endpoint, headers);
}
getTaskPhases(userTask: UserTaskInstance, headers?: any): Promise<string[]> {
diff --git
a/packages/runtime-tools-shared-enveloped-components/src/formDetails/envelope/components/FormEditor/FormEditor.tsx
b/packages/runtime-tools-shared-enveloped-components/src/formDetails/envelope/components/FormEditor/FormEditor.tsx
index e2518edd6e4..97b53f049b7 100644
---
a/packages/runtime-tools-shared-enveloped-components/src/formDetails/envelope/components/FormEditor/FormEditor.tsx
+++
b/packages/runtime-tools-shared-enveloped-components/src/formDetails/envelope/components/FormEditor/FormEditor.tsx
@@ -61,7 +61,7 @@ export const FormEditor = React.forwardRef<ResizableContent,
FormEditorProps>(
{ code, formType, formContent, setFormContent, saveFormContent, isSource =
false, isConfig = false },
forwardedRef
) => {
- const [formSourceCode, setFormSourceCode] = useState("");
+ const [formSourceCode, setFormSourceCode] = useState(formContent.source);
const appContext = useFormDetailsContext();
const container = useRef<HTMLDivElement>(null);
diff --git
a/packages/runtime-tools-shared-enveloped-components/src/formDisplayer/api/types.ts
b/packages/runtime-tools-shared-enveloped-components/src/formDisplayer/api/types.ts
index 60449ccdc71..1b02e7c3fee 100644
---
a/packages/runtime-tools-shared-enveloped-components/src/formDisplayer/api/types.ts
+++
b/packages/runtime-tools-shared-enveloped-components/src/formDisplayer/api/types.ts
@@ -58,12 +58,3 @@ export interface Association {
origin: string;
envelopeServerId: string;
}
-
-export interface FormResources {
- scripts: {
- [key: string]: string;
- };
- styles: {
- [key: string]: string;
- };
-}
diff --git
a/packages/runtime-tools-shared-enveloped-components/src/formDisplayer/embedded/EmbeddedFormDisplayer.tsx
b/packages/runtime-tools-shared-enveloped-components/src/formDisplayer/embedded/EmbeddedFormDisplayer.tsx
index e5dc93d6a59..2846cc106a7 100644
---
a/packages/runtime-tools-shared-enveloped-components/src/formDisplayer/embedded/EmbeddedFormDisplayer.tsx
+++
b/packages/runtime-tools-shared-enveloped-components/src/formDisplayer/embedded/EmbeddedFormDisplayer.tsx
@@ -72,7 +72,7 @@ export const EmbeddedFormDisplayer = React.forwardRef((props:
Props, forwardedRe
}
);
},
- []
+ [props.context, props.data, props.formContent]
);
return (
diff --git
a/packages/runtime-tools-shared-enveloped-components/src/formDisplayer/envelope/components/FormDisplayer/FormDisplayer.tsx
b/packages/runtime-tools-shared-enveloped-components/src/formDisplayer/envelope/components/FormDisplayer/FormDisplayer.tsx
index e2284fa5975..249e7fdd1a4 100644
---
a/packages/runtime-tools-shared-enveloped-components/src/formDisplayer/envelope/components/FormDisplayer/FormDisplayer.tsx
+++
b/packages/runtime-tools-shared-enveloped-components/src/formDisplayer/envelope/components/FormDisplayer/FormDisplayer.tsx
@@ -17,10 +17,10 @@
* under the License.
*/
-import React, { useCallback, useEffect, useImperativeHandle, useState } from
"react";
+import React, { useMemo, useCallback, useEffect, useImperativeHandle, useState
} from "react";
import { Bullseye } from "@patternfly/react-core/dist/js/layouts/Bullseye";
import { BallBeat } from "react-pure-loaders";
-import { Form } from "@kie-tools/runtime-tools-shared-gateway-api/src/types";
+import { Form, FormResources } from
"@kie-tools/runtime-tools-shared-gateway-api/src/types";
import { FormOpened, FormOpenedState } from "../../../api";
import ReactFormRenderer from "../ReactFormRenderer/ReactFormRenderer";
import HtmlFormRenderer from "../HtmlFormRenderer/HtmlFormRenderer";
@@ -39,29 +39,27 @@ interface FormDisplayerProps {
export const FormDisplayer = React.forwardRef<EmbeddedFormApi,
FormDisplayerProps & OUIAProps>(
({ isEnvelopeConnectedToChannel, content, data, context, onOpenForm, ouiaId,
ouiaSafe }, forwardedRef) => {
const [source, setSource] = useState<string>();
- const [resources, setResources] = useState<any>();
+ const [resources, setResources] = useState<FormResources>();
const [formData, setFormData] = useState<string>();
const [formApi, setFormApi] = useState<InternalFormDisplayerApi>({} as
InternalFormDisplayerApi);
const [isExecuting, setIsExecuting] = useState<boolean>(false);
- const doOpenForm = (config: FormConfig): EmbeddedFormApi => {
- const api: EmbeddedFormApi = {};
- setFormApi(new InternalFormDisplayerApiImpl(api, config.onOpen!));
- return api;
- };
-
- const canDisplayForm = useCallback(() => {
- return isEnvelopeConnectedToChannel && !isExecuting && source;
- }, [isEnvelopeConnectedToChannel, isExecuting, source]);
+ const canDisplayForm = useMemo(
+ () => isEnvelopeConnectedToChannel && !isExecuting && source &&
resources,
+ [isEnvelopeConnectedToChannel, isExecuting, source, resources]
+ );
useEffect(() => {
window.Form = {
- openForm: doOpenForm,
+ openForm: (config: FormConfig): EmbeddedFormApi => {
+ const api: EmbeddedFormApi = {};
+ setFormApi(new InternalFormDisplayerApiImpl(api, config.onOpen!));
+ return api;
+ },
};
}, []);
useEffect(() => {
- /* istanbul ignore else */
if (isEnvelopeConnectedToChannel) {
setSource(content.source);
setResources(content.configuration.resources);
@@ -85,18 +83,19 @@ export const FormDisplayer =
React.forwardRef<EmbeddedFormApi, FormDisplayerProp
});
}, 500);
}
+ // eslint-disable-next-line
}, [formApi]);
useImperativeHandle(forwardedRef, () => formApi, [formApi]);
return (
<div {...componentOuiaProps(ouiaId, "form-displayer", ouiaSafe)}>
- {canDisplayForm() ? (
+ {canDisplayForm ? (
<div id={"inner-form-container"}>
{content.formInfo && content.formInfo.type === "TSX" ? (
- <ReactFormRenderer source={source!} resources={resources}
setIsExecuting={setIsExecuting} />
+ <ReactFormRenderer source={source!} resources={resources!}
setIsExecuting={setIsExecuting} />
) : (
- <HtmlFormRenderer source={source!} resources={resources} />
+ <HtmlFormRenderer source={source!} resources={resources!} />
)}
</div>
) : (
diff --git
a/packages/runtime-tools-shared-enveloped-components/src/formDisplayer/envelope/components/HtmlFormRenderer/HtmlFormRenderer.tsx
b/packages/runtime-tools-shared-enveloped-components/src/formDisplayer/envelope/components/HtmlFormRenderer/HtmlFormRenderer.tsx
index b91f3ef2735..81267be202b 100644
---
a/packages/runtime-tools-shared-enveloped-components/src/formDisplayer/envelope/components/HtmlFormRenderer/HtmlFormRenderer.tsx
+++
b/packages/runtime-tools-shared-enveloped-components/src/formDisplayer/envelope/components/HtmlFormRenderer/HtmlFormRenderer.tsx
@@ -19,7 +19,7 @@
import React from "react";
import InnerHTML from "dangerously-set-html-content";
-import { FormResources } from "../../../api";
+import { FormResources } from
"@kie-tools/runtime-tools-shared-gateway-api/src/types";
import ResourcesContainer from "../ResourcesContainer/ResourcesContainer";
interface HtmlFormRendererProps {
diff --git
a/packages/runtime-tools-shared-enveloped-components/src/formDisplayer/envelope/components/ReactFormRenderer/ReactFormRenderer.tsx
b/packages/runtime-tools-shared-enveloped-components/src/formDisplayer/envelope/components/ReactFormRenderer/ReactFormRenderer.tsx
index 8eee4681aa9..61363f8e2d8 100644
---
a/packages/runtime-tools-shared-enveloped-components/src/formDisplayer/envelope/components/ReactFormRenderer/ReactFormRenderer.tsx
+++
b/packages/runtime-tools-shared-enveloped-components/src/formDisplayer/envelope/components/ReactFormRenderer/ReactFormRenderer.tsx
@@ -23,7 +23,7 @@ import { transform } from "@babel/standalone";
import ReactDOM from "react-dom";
import * as PatternflyReact from "@patternfly/react-core/dist/js";
import * as PatternflyReactIcons from "@patternfly/react-icons/dist/js";
-import { FormResources } from "../../../api";
+import { FormResources } from
"@kie-tools/runtime-tools-shared-gateway-api/src/types";
import { sourceHandler } from "../../../utils";
import ResourcesContainer from "../ResourcesContainer/ResourcesContainer";
diff --git
a/packages/runtime-tools-shared-enveloped-components/src/formDisplayer/envelope/components/ResourcesContainer/ResourcesContainer.tsx
b/packages/runtime-tools-shared-enveloped-components/src/formDisplayer/envelope/components/ResourcesContainer/ResourcesContainer.tsx
index cdbeaa0421a..1fcea6c5183 100644
---
a/packages/runtime-tools-shared-enveloped-components/src/formDisplayer/envelope/components/ResourcesContainer/ResourcesContainer.tsx
+++
b/packages/runtime-tools-shared-enveloped-components/src/formDisplayer/envelope/components/ResourcesContainer/ResourcesContainer.tsx
@@ -19,7 +19,7 @@
import React, { ReactElement } from "react";
import { Helmet } from "react-helmet";
-import { FormResources } from "../../../api";
+import { FormResources } from
"@kie-tools/runtime-tools-shared-gateway-api/src/types";
interface ResourcesContainerProps {
resources: FormResources;
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]