bug fix: inputs resetting if a websocket messages triggers a render
parent
ddd86ed479
commit
a3a63b8d84
|
@ -1,4 +1,5 @@
|
||||||
import { createContext, useContext, useRef, useState } from "react";
|
import { createContext, useContext, useRef, useState } from "react";
|
||||||
|
import { Form } from "antd";
|
||||||
|
|
||||||
const preview = {
|
const preview = {
|
||||||
categoryGroup: {},
|
categoryGroup: {},
|
||||||
|
@ -10,6 +11,7 @@ const preview = {
|
||||||
previousParamCategory: null,
|
previousParamCategory: null,
|
||||||
paginationPageRef: null,
|
paginationPageRef: null,
|
||||||
selectInputs: {},
|
selectInputs: {},
|
||||||
|
form: null,
|
||||||
};
|
};
|
||||||
|
|
||||||
const GroupTasksContext = createContext(preview);
|
const GroupTasksContext = createContext(preview);
|
||||||
|
@ -32,6 +34,8 @@ export function GroupTasksProvider({ children }) {
|
||||||
// this is used for the <Select /> inputs as there is no way to manipulate the select value via the DOM (like we do on the text inputs) as it is needed by the websocket
|
// this is used for the <Select /> inputs as there is no way to manipulate the select value via the DOM (like we do on the text inputs) as it is needed by the websocket
|
||||||
const [selectInputs, setSelectInputs] = useState({});
|
const [selectInputs, setSelectInputs] = useState({});
|
||||||
|
|
||||||
|
const [form] = Form.useForm();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<GroupTasksContext.Provider
|
<GroupTasksContext.Provider
|
||||||
value={{
|
value={{
|
||||||
|
@ -50,6 +54,7 @@ export function GroupTasksProvider({ children }) {
|
||||||
paginationPageRef,
|
paginationPageRef,
|
||||||
selectInputs,
|
selectInputs,
|
||||||
setSelectInputs,
|
setSelectInputs,
|
||||||
|
form,
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{children}
|
{children}
|
||||||
|
|
|
@ -294,13 +294,15 @@ export function handleWebSocketMessage(
|
||||||
// update input value
|
// update input value
|
||||||
|
|
||||||
if (body.inputType === "text") {
|
if (body.inputType === "text") {
|
||||||
|
groupTasksContext.form.setFieldValue(body.element, body.value);
|
||||||
|
|
||||||
// html based DOM manipulation
|
// html based DOM manipulation
|
||||||
const foundInput = document.getElementById(body.element);
|
/*const foundInput = document.getElementById(body.element);
|
||||||
|
|
||||||
if (foundInput) {
|
if (foundInput) {
|
||||||
// this timeout is needed because the previous useState for the lockedByUserId takes some milliseconds to complete
|
// this timeout is needed because the previous useState for the lockedByUserId takes some milliseconds to complete
|
||||||
setTimeout(() => setNativeValue(foundInput, body.value), 50);
|
// setTimeout(() => setNativeValue(foundInput, body.value), 50);
|
||||||
}
|
} */
|
||||||
} else if (body.inputType === "select" || body.inputType === "checkbox") {
|
} else if (body.inputType === "select" || body.inputType === "checkbox") {
|
||||||
groupTasksContext.setSelectInputs((prev) => {
|
groupTasksContext.setSelectInputs((prev) => {
|
||||||
const newInputs = { ...prev };
|
const newInputs = { ...prev };
|
||||||
|
@ -1106,7 +1108,11 @@ function setNativeValue(element, value) {
|
||||||
// React 16
|
// React 16
|
||||||
let tracker = element._valueTracker;
|
let tracker = element._valueTracker;
|
||||||
if (tracker) {
|
if (tracker) {
|
||||||
|
console.log("tracker set value", value);
|
||||||
|
console.log(element);
|
||||||
tracker.setValue(lastValue);
|
tracker.setValue(lastValue);
|
||||||
|
} else {
|
||||||
|
console.log("tracker not set value");
|
||||||
}
|
}
|
||||||
element.dispatchEvent(event);
|
element.dispatchEvent(event);
|
||||||
}
|
}
|
||||||
|
|
|
@ -389,6 +389,8 @@ export default function GroupTasksViewModal({ isOpen }) {
|
||||||
|
|
||||||
groupTaskSteps.sort((a, b) => a.Step - b.Step);
|
groupTaskSteps.sort((a, b) => a.Step - b.Step);
|
||||||
|
|
||||||
|
if (groupTasksContext.categoryGroup.groups === undefined) return [];
|
||||||
|
|
||||||
groupTasksContext.categoryGroup.groups.forEach((group) => {
|
groupTasksContext.categoryGroup.groups.forEach((group) => {
|
||||||
if (currentGroupTask.current.GroupId === group.id) {
|
if (currentGroupTask.current.GroupId === group.id) {
|
||||||
groupTasks = group.tasks;
|
groupTasks = group.tasks;
|
||||||
|
@ -770,9 +772,9 @@ function InputRequiredHandler({
|
||||||
currentGroupTask,
|
currentGroupTask,
|
||||||
groupTaskParameters,
|
groupTaskParameters,
|
||||||
groupTaskStepInputs,
|
groupTaskStepInputs,
|
||||||
notificationApi,
|
|
||||||
step,
|
step,
|
||||||
taskLockedByUserId,
|
taskLockedByUserId,
|
||||||
|
notificationApi,
|
||||||
}) {
|
}) {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const groupTasksContext = useGroupTasksContext();
|
const groupTasksContext = useGroupTasksContext();
|
||||||
|
@ -860,7 +862,236 @@ function InputRequiredHandler({
|
||||||
typingTimer.current = setTimeout(() => typingMessage(), 1000);
|
typingTimer.current = setTimeout(() => typingMessage(), 1000);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const getInitialFormValues = () => {
|
||||||
|
let initialValues = {};
|
||||||
|
|
||||||
|
groupTaskParameters.forEach((groupTaskParameter) => {
|
||||||
|
initialValues[
|
||||||
|
`${currentGroupTask.Id}-${step}-${groupTaskParameter.parameterName}`
|
||||||
|
] = getDefaultValue(groupTaskParameter);
|
||||||
|
});
|
||||||
|
|
||||||
|
return initialValues;
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
<Form
|
||||||
|
form={groupTasksContext.form}
|
||||||
|
layout="vertical"
|
||||||
|
id="groupTasksViewModalRequiredInputsForm"
|
||||||
|
initialValues={getInitialFormValues()}
|
||||||
|
>
|
||||||
|
{groupTaskParameters.map((groupTaskParameter, index) => {
|
||||||
|
switch (groupTaskParameter.type) {
|
||||||
|
case "text":
|
||||||
|
return (
|
||||||
|
<MyFormItem
|
||||||
|
key={index}
|
||||||
|
t={t}
|
||||||
|
labelDisplayName={groupTaskParameter.displayName}
|
||||||
|
isGlobal={groupTaskParameter.global}
|
||||||
|
name={`${currentGroupTask.Id}-${step}-${groupTaskParameter.parameterName}`}
|
||||||
|
>
|
||||||
|
<Input
|
||||||
|
id={`${currentGroupTask.Id}-${step}-${groupTaskParameter.parameterName}`}
|
||||||
|
disabled={taskLockedByUserId !== ""}
|
||||||
|
onChange={(e) =>
|
||||||
|
handleInputChange(
|
||||||
|
"text",
|
||||||
|
e.target.value,
|
||||||
|
currentGroupTask.Id,
|
||||||
|
groupTaskParameter.parameterName
|
||||||
|
)
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
</MyFormItem>
|
||||||
|
);
|
||||||
|
case "number":
|
||||||
|
return (
|
||||||
|
<MyFormItem
|
||||||
|
key={index}
|
||||||
|
t={t}
|
||||||
|
labelDisplayName={groupTaskParameter.displayName}
|
||||||
|
isGlobal={groupTaskParameter.global}
|
||||||
|
name={`${currentGroupTask.Id}-${step}-${groupTaskParameter.parameterName}`}
|
||||||
|
>
|
||||||
|
<InputNumber
|
||||||
|
id={`${currentGroupTask.Id}-${step}-${groupTaskParameter.parameterName}`}
|
||||||
|
style={{ width: "100%" }}
|
||||||
|
disabled={taskLockedByUserId !== ""}
|
||||||
|
max={Number.MAX_SAFE_INTEGER}
|
||||||
|
onChange={(e) =>
|
||||||
|
handleInputChange(
|
||||||
|
"text",
|
||||||
|
e,
|
||||||
|
currentGroupTask.Id,
|
||||||
|
groupTaskParameter.parameterName
|
||||||
|
)
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
</MyFormItem>
|
||||||
|
);
|
||||||
|
case "textarea":
|
||||||
|
return (
|
||||||
|
<MyFormItem
|
||||||
|
key={index}
|
||||||
|
t={t}
|
||||||
|
labelDisplayName={groupTaskParameter.displayName}
|
||||||
|
isGlobal={groupTaskParameter.global}
|
||||||
|
name={`${currentGroupTask.Id}-${step}-${groupTaskParameter.parameterName}`}
|
||||||
|
>
|
||||||
|
<TextArea
|
||||||
|
id={`${currentGroupTask.Id}-${step}-${groupTaskParameter.parameterName}`}
|
||||||
|
disabled={taskLockedByUserId !== ""}
|
||||||
|
onChange={(e) =>
|
||||||
|
handleInputChange(
|
||||||
|
"text",
|
||||||
|
e.target.value,
|
||||||
|
currentGroupTask.Id,
|
||||||
|
groupTaskParameter.parameterName
|
||||||
|
)
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
</MyFormItem>
|
||||||
|
);
|
||||||
|
case "select":
|
||||||
|
return (
|
||||||
|
<MyFormItem
|
||||||
|
key={index}
|
||||||
|
t={t}
|
||||||
|
labelDisplayName={groupTaskParameter.displayName}
|
||||||
|
isGlobal={groupTaskParameter.global}
|
||||||
|
name={`${currentGroupTask.Id}-${step}-${groupTaskParameter.parameterName}`}
|
||||||
|
>
|
||||||
|
<SelectComponent
|
||||||
|
id={`${currentGroupTask.Id}-${step}-${groupTaskParameter.parameterName}`}
|
||||||
|
t={t}
|
||||||
|
disabled={taskLockedByUserId !== ""}
|
||||||
|
options={groupTaskParameter.options}
|
||||||
|
parameterName={groupTaskParameter.parameterName}
|
||||||
|
onSelectChange={(value) =>
|
||||||
|
handleInputChange(
|
||||||
|
"select",
|
||||||
|
value,
|
||||||
|
currentGroupTask.Id,
|
||||||
|
groupTaskParameter.parameterName
|
||||||
|
)
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
</MyFormItem>
|
||||||
|
);
|
||||||
|
case "select_machine":
|
||||||
|
return (
|
||||||
|
<MyFormItem
|
||||||
|
key={index}
|
||||||
|
t={t}
|
||||||
|
labelDisplayName={groupTaskParameter.displayName}
|
||||||
|
isGlobal={groupTaskParameter.global}
|
||||||
|
>
|
||||||
|
<SelectMachineComponent
|
||||||
|
id={`${currentGroupTask.Id}-${step}-${groupTaskParameter.parameterName}`}
|
||||||
|
disabled={taskLockedByUserId !== ""}
|
||||||
|
t={t}
|
||||||
|
notificationApi={notificationApi}
|
||||||
|
globalInput={groupTaskParameter}
|
||||||
|
onSelectChange={(value, notes) =>
|
||||||
|
handleInputChange(
|
||||||
|
"select",
|
||||||
|
value,
|
||||||
|
currentGroupTask.Id,
|
||||||
|
groupTaskParameter.parameterName,
|
||||||
|
notes
|
||||||
|
)
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
</MyFormItem>
|
||||||
|
);
|
||||||
|
case "checkbox":
|
||||||
|
return (
|
||||||
|
<MyFormItem
|
||||||
|
key={index}
|
||||||
|
t={t}
|
||||||
|
style={{
|
||||||
|
marginBottom:
|
||||||
|
groupTaskParameters.length > index &&
|
||||||
|
groupTaskParameters[index + 1].type === "checkbox"
|
||||||
|
? 0
|
||||||
|
: AppStyle.app.margin,
|
||||||
|
}}
|
||||||
|
name={`${currentGroupTask.Id}-${step}-${groupTaskParameter.parameterName}`}
|
||||||
|
>
|
||||||
|
<Checkbox
|
||||||
|
id={`${currentGroupTask.Id}-${step}-${groupTaskParameter.parameterName}`}
|
||||||
|
disabled={taskLockedByUserId !== ""}
|
||||||
|
checked={
|
||||||
|
groupTasksContext.selectInputs[
|
||||||
|
groupTaskParameter.parameterName
|
||||||
|
]?.value
|
||||||
|
}
|
||||||
|
onChange={(e) => {
|
||||||
|
groupTasksContext.setSelectInputs((prevState) => ({
|
||||||
|
...prevState,
|
||||||
|
[groupTaskParameter.parameterName]: {
|
||||||
|
value: e.target.checked,
|
||||||
|
},
|
||||||
|
}));
|
||||||
|
|
||||||
|
handleInputChange(
|
||||||
|
"checkbox",
|
||||||
|
e.target.checked,
|
||||||
|
currentGroupTask.Id,
|
||||||
|
groupTaskParameter.parameterName
|
||||||
|
);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<MyFormItemLabel
|
||||||
|
t={t}
|
||||||
|
displayName={groupTaskParameter.displayName}
|
||||||
|
isGlobal={groupTaskParameter.global}
|
||||||
|
/>
|
||||||
|
</Checkbox>
|
||||||
|
</MyFormItem>
|
||||||
|
);
|
||||||
|
case "select":
|
||||||
|
return (
|
||||||
|
<MyFormItem
|
||||||
|
key={index}
|
||||||
|
t={t}
|
||||||
|
labelDisplayName={groupTaskParameter.displayName}
|
||||||
|
isGlobal={groupTaskParameter.global}
|
||||||
|
name={`${currentGroupTask.Id}-${step}-${groupTaskParameter.parameterName}`}
|
||||||
|
>
|
||||||
|
<SelectComponent
|
||||||
|
id={`${currentGroupTask.Id}-${step}-${groupTaskParameter.parameterName}`}
|
||||||
|
t={t}
|
||||||
|
disabled={taskLockedByUserId !== ""}
|
||||||
|
options={groupTaskParameter.options}
|
||||||
|
parameterName={groupTaskParameter.parameterName}
|
||||||
|
onSelectChange={(value) =>
|
||||||
|
handleInputChange(
|
||||||
|
"select",
|
||||||
|
value,
|
||||||
|
currentGroupTask.Id,
|
||||||
|
groupTaskParameter.parameterName
|
||||||
|
)
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
</MyFormItem>
|
||||||
|
);
|
||||||
|
default:
|
||||||
|
return (
|
||||||
|
<Typography.Text type="danger" key={index}>
|
||||||
|
Type <b>{groupTaskParameter.type}</b> not implemented. Was
|
||||||
|
specified in: <b>{groupTaskParameter.displayName}</b> <br />
|
||||||
|
<br />
|
||||||
|
</Typography.Text>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
})}
|
||||||
|
</Form>
|
||||||
|
);
|
||||||
|
|
||||||
|
/*return (
|
||||||
<Form layout="vertical" id="groupTasksViewModalRequiredInputsForm">
|
<Form layout="vertical" id="groupTasksViewModalRequiredInputsForm">
|
||||||
{groupTaskParameters.map((groupTaskParameter, index) => {
|
{groupTaskParameters.map((groupTaskParameter, index) => {
|
||||||
switch (groupTaskParameter.type) {
|
switch (groupTaskParameter.type) {
|
||||||
|
@ -1043,7 +1274,7 @@ function InputRequiredHandler({
|
||||||
}
|
}
|
||||||
})}
|
})}
|
||||||
</Form>
|
</Form>
|
||||||
);
|
); */
|
||||||
}
|
}
|
||||||
|
|
||||||
function GroupTaskStepLogHandler({ currentGroupTaskId, log, files }) {
|
function GroupTaskStepLogHandler({ currentGroupTaskId, log, files }) {
|
||||||
|
|
|
@ -181,11 +181,19 @@ export default function GroupTasks({ isGroupTasksViewModalOpen }) {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function MyFormItem({ children, t, style, labelDisplayName, isGlobal }) {
|
export function MyFormItem({
|
||||||
|
children,
|
||||||
|
t,
|
||||||
|
style,
|
||||||
|
labelDisplayName,
|
||||||
|
isGlobal,
|
||||||
|
name,
|
||||||
|
}) {
|
||||||
return (
|
return (
|
||||||
<Form.Item
|
<Form.Item
|
||||||
style={style}
|
style={style}
|
||||||
required
|
required
|
||||||
|
name={name}
|
||||||
label={
|
label={
|
||||||
labelDisplayName !== undefined && (
|
labelDisplayName !== undefined && (
|
||||||
<MyFormItemLabel
|
<MyFormItemLabel
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import React from "react";
|
import React, { Suspense } from "react";
|
||||||
import ReactDOM from "react-dom/client";
|
import ReactDOM from "react-dom/client";
|
||||||
import "./index.css";
|
import "./index.css";
|
||||||
import App from "./App";
|
import App from "./App";
|
||||||
|
@ -24,12 +24,13 @@ const Loading = () => {
|
||||||
*/
|
*/
|
||||||
|
|
||||||
const root = ReactDOM.createRoot(document.getElementById("root"));
|
const root = ReactDOM.createRoot(document.getElementById("root"));
|
||||||
|
|
||||||
root.render(
|
root.render(
|
||||||
<React.Suspense fallback={<Loading />}>
|
<Suspense fallback={<Loading />}>
|
||||||
<BrowserRouter>
|
<BrowserRouter>
|
||||||
<App />
|
<App />
|
||||||
</BrowserRouter>
|
</BrowserRouter>
|
||||||
</React.Suspense>
|
</Suspense>
|
||||||
);
|
);
|
||||||
|
|
||||||
// If you want to start measuring performance in your app, pass a function
|
// If you want to start measuring performance in your app, pass a function
|
||||||
|
|
Loading…
Reference in New Issue