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 { Form } from "antd";
|
||||
|
||||
const preview = {
|
||||
categoryGroup: {},
|
||||
|
@ -10,6 +11,7 @@ const preview = {
|
|||
previousParamCategory: null,
|
||||
paginationPageRef: null,
|
||||
selectInputs: {},
|
||||
form: null,
|
||||
};
|
||||
|
||||
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
|
||||
const [selectInputs, setSelectInputs] = useState({});
|
||||
|
||||
const [form] = Form.useForm();
|
||||
|
||||
return (
|
||||
<GroupTasksContext.Provider
|
||||
value={{
|
||||
|
@ -50,6 +54,7 @@ export function GroupTasksProvider({ children }) {
|
|||
paginationPageRef,
|
||||
selectInputs,
|
||||
setSelectInputs,
|
||||
form,
|
||||
}}
|
||||
>
|
||||
{children}
|
||||
|
|
|
@ -294,13 +294,15 @@ export function handleWebSocketMessage(
|
|||
// update input value
|
||||
|
||||
if (body.inputType === "text") {
|
||||
groupTasksContext.form.setFieldValue(body.element, body.value);
|
||||
|
||||
// html based DOM manipulation
|
||||
const foundInput = document.getElementById(body.element);
|
||||
/*const foundInput = document.getElementById(body.element);
|
||||
|
||||
if (foundInput) {
|
||||
// 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") {
|
||||
groupTasksContext.setSelectInputs((prev) => {
|
||||
const newInputs = { ...prev };
|
||||
|
@ -1106,7 +1108,11 @@ function setNativeValue(element, value) {
|
|||
// React 16
|
||||
let tracker = element._valueTracker;
|
||||
if (tracker) {
|
||||
console.log("tracker set value", value);
|
||||
console.log(element);
|
||||
tracker.setValue(lastValue);
|
||||
} else {
|
||||
console.log("tracker not set value");
|
||||
}
|
||||
element.dispatchEvent(event);
|
||||
}
|
||||
|
|
|
@ -389,6 +389,8 @@ export default function GroupTasksViewModal({ isOpen }) {
|
|||
|
||||
groupTaskSteps.sort((a, b) => a.Step - b.Step);
|
||||
|
||||
if (groupTasksContext.categoryGroup.groups === undefined) return [];
|
||||
|
||||
groupTasksContext.categoryGroup.groups.forEach((group) => {
|
||||
if (currentGroupTask.current.GroupId === group.id) {
|
||||
groupTasks = group.tasks;
|
||||
|
@ -770,9 +772,9 @@ function InputRequiredHandler({
|
|||
currentGroupTask,
|
||||
groupTaskParameters,
|
||||
groupTaskStepInputs,
|
||||
notificationApi,
|
||||
step,
|
||||
taskLockedByUserId,
|
||||
notificationApi,
|
||||
}) {
|
||||
const { t } = useTranslation();
|
||||
const groupTasksContext = useGroupTasksContext();
|
||||
|
@ -860,7 +862,236 @@ function InputRequiredHandler({
|
|||
typingTimer.current = setTimeout(() => typingMessage(), 1000);
|
||||
};
|
||||
|
||||
const getInitialFormValues = () => {
|
||||
let initialValues = {};
|
||||
|
||||
groupTaskParameters.forEach((groupTaskParameter) => {
|
||||
initialValues[
|
||||
`${currentGroupTask.Id}-${step}-${groupTaskParameter.parameterName}`
|
||||
] = getDefaultValue(groupTaskParameter);
|
||||
});
|
||||
|
||||
return initialValues;
|
||||
};
|
||||
|
||||
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">
|
||||
{groupTaskParameters.map((groupTaskParameter, index) => {
|
||||
switch (groupTaskParameter.type) {
|
||||
|
@ -1043,7 +1274,7 @@ function InputRequiredHandler({
|
|||
}
|
||||
})}
|
||||
</Form>
|
||||
);
|
||||
); */
|
||||
}
|
||||
|
||||
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 (
|
||||
<Form.Item
|
||||
style={style}
|
||||
required
|
||||
name={name}
|
||||
label={
|
||||
labelDisplayName !== undefined && (
|
||||
<MyFormItemLabel
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import React from "react";
|
||||
import React, { Suspense } from "react";
|
||||
import ReactDOM from "react-dom/client";
|
||||
import "./index.css";
|
||||
import App from "./App";
|
||||
|
@ -24,12 +24,13 @@ const Loading = () => {
|
|||
*/
|
||||
|
||||
const root = ReactDOM.createRoot(document.getElementById("root"));
|
||||
|
||||
root.render(
|
||||
<React.Suspense fallback={<Loading />}>
|
||||
<Suspense fallback={<Loading />}>
|
||||
<BrowserRouter>
|
||||
<App />
|
||||
</BrowserRouter>
|
||||
</React.Suspense>
|
||||
</Suspense>
|
||||
);
|
||||
|
||||
// If you want to start measuring performance in your app, pass a function
|
||||
|
|
Loading…
Reference in New Issue