main
alex 2023-10-29 23:20:48 +01:00
parent 5d1b9bec2c
commit ec337b4c5b
4 changed files with 216 additions and 103 deletions

View File

@ -298,6 +298,8 @@ export function handleWebSocketMessage(
// update input value // update input value
console.log("body", body.inputType, body.value, body.element);
if (body.inputType === "text") { if (body.inputType === "text") {
// html based DOM manipulation // html based DOM manipulation
const foundInput = document.getElementById(body.element); const foundInput = document.getElementById(body.element);
@ -306,7 +308,7 @@ export function handleWebSocketMessage(
// 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") { } else if (body.inputType === "select" || body.inputType === "checkbox") {
groupTasksContext.setSelectInputs((prev) => { groupTasksContext.setSelectInputs((prev) => {
const newInputs = { ...prev }; const newInputs = { ...prev };

View File

@ -1,18 +1,20 @@
import { import {
Alert, Alert,
Button, Button,
Checkbox,
Form, Form,
Input, Input,
InputNumber, InputNumber,
Popover, Popover,
Space, Space,
Steps, Steps,
Tag, Typography,
notification, notification,
} from "antd"; } from "antd";
import { useEffect, useRef } from "react"; import { useEffect, useRef } from "react";
import { useNavigate, useParams } from "react-router-dom"; import { useNavigate, useParams } from "react-router-dom";
import { import {
AppStyle,
BrowserTabSession, BrowserTabSession,
Constants, Constants,
FormatDatetime, FormatDatetime,
@ -36,7 +38,11 @@ import { useWebSocketContext } from "../../../Contexts/WebSocketContext";
import { useGroupTasksContext } from "../../../Contexts/GroupTasksContext"; import { useGroupTasksContext } from "../../../Contexts/GroupTasksContext";
import { useAppContext } from "../../../Contexts/AppContext"; import { useAppContext } from "../../../Contexts/AppContext";
import { SentMessagesCommands } from "../../../Handlers/WebSocketMessageHandler"; import { SentMessagesCommands } from "../../../Handlers/WebSocketMessageHandler";
import { SelectMachineComponent } from "./GroupTypeSelectionModal"; import {
SelectComponent,
SelectMachineComponent,
} from "./GroupTypeSelectionModal";
import { MyFormItem, MyFormItemLabel } from ".";
export default function GroupTasksViewModal({ isOpen }) { export default function GroupTasksViewModal({ isOpen }) {
const webSocketContext = useWebSocketContext(); const webSocketContext = useWebSocketContext();
@ -727,6 +733,7 @@ function InputRequiredHandler({
taskLockedByUserId, taskLockedByUserId,
}) { }) {
const { t } = useTranslation(); const { t } = useTranslation();
const groupTasksContext = useGroupTasksContext();
const globalInputs = JSON.parse(currentGroupTask.GlobalInputs); const globalInputs = JSON.parse(currentGroupTask.GlobalInputs);
const stepInputs = JSON.parse(groupTaskStepInputs); const stepInputs = JSON.parse(groupTaskStepInputs);
@ -753,19 +760,6 @@ function InputRequiredHandler({
return globalInputValue !== undefined ? globalInputValue.value : ""; return globalInputValue !== undefined ? globalInputValue.value : "";
}; };
const getLabel = (displayName, groupTaskParameter) => {
return groupTaskParameter.global ? (
<>
{displayName}
<Tag style={{ marginLeft: 6 }} color="purple">
{t("groupTasks.tag.global")}
</Tag>
</>
) : (
displayName
);
};
let lastChange = useRef(); let lastChange = useRef();
let typingTimer = useRef(); let typingTimer = useRef();
@ -788,7 +782,7 @@ function InputRequiredHandler({
}; };
if (inputType === "text") { if (inputType === "text") {
// element is only needed for text inputs for the DOM manipulation // element is only needed for text and checkbox inputs for the DOM manipulation
data.element = `${currentGroupTaskId}-${step}-${groupTaskParameterName}`; data.element = `${currentGroupTaskId}-${step}-${groupTaskParameterName}`;
} else { } else {
data.data = notes; data.data = notes;
@ -833,13 +827,11 @@ function InputRequiredHandler({
switch (groupTaskParameter.type) { switch (groupTaskParameter.type) {
case "text": case "text":
return ( return (
<Form.Item <MyFormItem
key={index} key={index}
label={getLabel( t={t}
groupTaskParameter.displayName, labelDisplayName={groupTaskParameter.displayName}
groupTaskParameter isGlobal={groupTaskParameter.global}
)}
required
> >
<Input <Input
id={`${currentGroupTask.Id}-${step}-${groupTaskParameter.parameterName}`} id={`${currentGroupTask.Id}-${step}-${groupTaskParameter.parameterName}`}
@ -854,17 +846,15 @@ function InputRequiredHandler({
) )
} }
/> />
</Form.Item> </MyFormItem>
); );
case "number": case "number":
return ( return (
<Form.Item <MyFormItem
key={index} key={index}
label={getLabel( t={t}
groupTaskParameter.displayName, labelDisplayName={groupTaskParameter.displayName}
groupTaskParameter isGlobal={groupTaskParameter.global}
)}
required
> >
<InputNumber <InputNumber
id={`${currentGroupTask.Id}-${step}-${groupTaskParameter.parameterName}`} id={`${currentGroupTask.Id}-${step}-${groupTaskParameter.parameterName}`}
@ -881,17 +871,15 @@ function InputRequiredHandler({
) )
} }
/> />
</Form.Item> </MyFormItem>
); );
case "textarea": case "textarea":
return ( return (
<Form.Item <MyFormItem
key={index} key={index}
label={getLabel( t={t}
groupTaskParameter.displayName, labelDisplayName={groupTaskParameter.displayName}
groupTaskParameter isGlobal={groupTaskParameter.global}
)}
required
> >
<TextArea <TextArea
id={`${currentGroupTask.Id}-${step}-${groupTaskParameter.parameterName}`} id={`${currentGroupTask.Id}-${step}-${groupTaskParameter.parameterName}`}
@ -906,17 +894,15 @@ function InputRequiredHandler({
) )
} }
/> />
</Form.Item> </MyFormItem>
); );
case "select_machine": case "select_machine":
return ( return (
<Form.Item <MyFormItem
key={index} key={index}
label={getLabel( t={t}
groupTaskParameter.displayName, labelDisplayName={groupTaskParameter.displayName}
groupTaskParameter isGlobal={groupTaskParameter.global}
)}
required
> >
<SelectMachineComponent <SelectMachineComponent
disabled={taskLockedByUserId !== ""} disabled={taskLockedByUserId !== ""}
@ -933,15 +919,84 @@ function InputRequiredHandler({
) )
} }
/> />
</Form.Item> </MyFormItem>
);
case "checkbox":
return (
<MyFormItem
key={index}
t={t}
style={{
marginBottom:
groupTaskParameters.length > index &&
groupTaskParameters[index + 1].type === "checkbox"
? 0
: AppStyle.app.margin,
}}
>
<Checkbox
defaultChecked={getDefaultValue(groupTaskParameter)}
disabled={taskLockedByUserId !== ""}
checked={
groupTaskStepInputs[groupTaskParameter.parameterName]?.value
}
onChange={(e) => {
groupTasksContext.setSelectInputs((prevState) => ({
...prevState,
[groupTaskParameter.parameterName]: {
value: e.target.checked,
},
}));
handleInputChange(
"checkbox",
e.target.checked,
currentGroupTask.Id,
groupTaskParameter.parameterName
);
}}
>
{console.log("checked", groupTaskStepInputs)}
<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}
>
<SelectComponent
t={t}
disabled={taskLockedByUserId !== ""}
options={groupTaskParameter.options}
parameterName={groupTaskParameter.parameterName}
onSelectChange={(value) =>
handleInputChange(
"select",
value,
currentGroupTask.Id,
groupTaskParameter.parameterName
)
}
/>
</MyFormItem>
); );
default: default:
return ( return (
<p key={index}> <Typography.Text type="danger" key={index}>
Type <b>{groupTaskParameter.type}</b> not implemented. Was Type <b>{groupTaskParameter.type}</b> not implemented. Was
specified in: <b>{groupTaskParameter.displayName}</b> specified in: <b>{groupTaskParameter.displayName}</b> <br />
</p> <br />
</Typography.Text>
); );
} }
})} })}

View File

@ -12,7 +12,7 @@ import {
Typography, Typography,
notification, notification,
} from "antd"; } from "antd";
import { AppStyle, Constants, GetUuid, myFetch } from "../../../utils"; import { AppStyle, GetUuid, myFetch } from "../../../utils";
import { InfoCircleOutlined } from "@ant-design/icons"; import { InfoCircleOutlined } from "@ant-design/icons";
import TextArea from "antd/es/input/TextArea"; import TextArea from "antd/es/input/TextArea";
import { useTranslation } from "react-i18next"; import { useTranslation } from "react-i18next";
@ -20,7 +20,7 @@ import { useWebSocketContext } from "../../../Contexts/WebSocketContext";
import { useGroupTasksContext } from "../../../Contexts/GroupTasksContext"; import { useGroupTasksContext } from "../../../Contexts/GroupTasksContext";
import { SentMessagesCommands } from "../../../Handlers/WebSocketMessageHandler"; import { SentMessagesCommands } from "../../../Handlers/WebSocketMessageHandler";
import { useEffect, useRef, useState } from "react"; import { useEffect, useRef, useState } from "react";
import Paragraph from "antd/es/skeleton/Paragraph"; import { MyFormItem, MyFormItemLabel } from ".";
export default function GroupTypeSelectionModal({ export default function GroupTypeSelectionModal({
isOpen, isOpen,
@ -260,10 +260,16 @@ export default function GroupTypeSelectionModal({
); );
} }
export function SelectComponent({ t, globalInput }) { export function SelectComponent({
t,
options,
parameterName,
onSelectChange,
disabled,
}) {
const groupTasksContext = useGroupTasksContext(); const groupTasksContext = useGroupTasksContext();
if (globalInput.options === null) { if (options === undefined) {
return ( return (
<Typography.Text type="danger"> <Typography.Text type="danger">
Options for this input not specified in the index.json Options for this input not specified in the index.json
@ -273,23 +279,29 @@ export function SelectComponent({ t, globalInput }) {
return ( return (
<Select <Select
disabled={disabled}
placeholder={t( placeholder={t(
"groupTasks.groupTypeSelectionModal.select.valuePlaceholder" "groupTasks.groupTypeSelectionModal.select.valuePlaceholder"
)} )}
style={{ width: "100%" }} style={{ width: "100%" }}
options={globalInput.options.map((option) => { options={options.map((option) => {
return { return {
label: option, label: option,
value: option, value: option,
}; };
})} })}
onChange={(value) => { value={groupTasksContext.selectInputs[parameterName]?.value}
onSelect={(value) => {
groupTasksContext.setSelectInputs((prevState) => ({ groupTasksContext.setSelectInputs((prevState) => ({
...prevState, ...prevState,
[globalInput.parameterName]: { [parameterName]: {
value: value, value: value,
}, },
})); }));
if (onSelectChange !== undefined) {
onSelectChange(value);
}
}} }}
/> />
); );
@ -376,9 +388,6 @@ export function SelectMachineComponent({
}); });
}, []); }, []);
const selectedInput =
groupTasksContext.selectInputs[globalInput.parameterName]?.value;
return ( return (
<Select <Select
disabled={disabled} disabled={disabled}
@ -388,7 +397,7 @@ export function SelectMachineComponent({
)} )}
style={{ width: "100%" }} style={{ width: "100%" }}
options={options} options={options}
value={selectedInput} value={groupTasksContext.selectInputs[globalInput.parameterName]?.value}
onSelect={(value) => { onSelect={(value) => {
const parsedNotes = JSON.parse(responseData.current[value].Notes); const parsedNotes = JSON.parse(responseData.current[value].Notes);
@ -415,23 +424,6 @@ function GroupGlobalInputs({
}) { }) {
const { t } = useTranslation(); const { t } = useTranslation();
const getLabel = (displayName) => {
return (
<>
{displayName === undefined || displayName === "" ? (
<Typography.Text type="danger">
DisplayName is missing
</Typography.Text>
) : (
displayName
)}
<Tag style={{ marginLeft: 6 }} color="purple">
{t("groupTasks.tag.global")}
</Tag>
</>
);
};
var elements = []; var elements = [];
if (currentSelectedModalGroupType !== undefined) { if (currentSelectedModalGroupType !== undefined) {
@ -444,67 +436,72 @@ function GroupGlobalInputs({
switch (globalInput.type) { switch (globalInput.type) {
case "text": case "text":
elements.push( elements.push(
<Form.Item <MyFormItem
key={index} key={index}
label={getLabel(globalInput.displayName)} t={t}
required labelDisplayName={globalInput.displayName}
isGlobal={true}
> >
<Input id={globalInput.parameterName} /> <Input id={globalInput.parameterName} />
</Form.Item> </MyFormItem>
); );
break; break;
case "number": case "number":
elements.push( elements.push(
<Form.Item <MyFormItem
key={index} key={index}
label={getLabel(globalInput.displayName)} t={t}
required labelDisplayName={globalInput.displayName}
isGlobal={true}
> >
<InputNumber <InputNumber
style={{ width: "100%" }} style={{ width: "100%" }}
max={Number.MAX_SAFE_INTEGER} max={Number.MAX_SAFE_INTEGER}
id={globalInput.parameterName} id={globalInput.parameterName}
/> />
</Form.Item> </MyFormItem>
); );
break; break;
case "textarea": case "textarea":
elements.push( elements.push(
<Form.Item <MyFormItem
key={index} key={index}
label={getLabel(globalInput.displayName)} t={t}
required labelDisplayName={globalInput.displayName}
isGlobal={true}
> >
<TextArea id={globalInput.parameterName} /> <TextArea id={globalInput.parameterName} />
</Form.Item> </MyFormItem>
); );
break; break;
case "select_machine": case "select_machine":
elements.push( elements.push(
<Form.Item <MyFormItem
key={index} key={index}
label={getLabel(globalInput.displayName)} t={t}
required labelDisplayName={globalInput.displayName}
isGlobal={true}
> >
<SelectMachineComponent <SelectMachineComponent
t={t} t={t}
notificationApi={notificationApi} notificationApi={notificationApi}
globalInput={globalInput} globalInput={globalInput}
/> />
</Form.Item> </MyFormItem>
); );
break; break;
case "checkbox": case "checkbox":
elements.push( elements.push(
<Form.Item <MyFormItem
key={index} key={index}
required t={t}
isGlobal={true}
style={{ style={{
marginBottom: marginBottom:
group.globalInputs.length > index && group.globalInputs.length > index &&
group.globalInputs[index + 1].type === "checkbox" group.globalInputs[index + 1].type === "checkbox"
? 0 ? 0
: 12, : AppStyle.app.margin,
}} }}
> >
<Checkbox <Checkbox
@ -516,20 +513,32 @@ function GroupGlobalInputs({
: false : false
} }
> >
{getLabel(globalInput.displayName)} {
<MyFormItemLabel
t={t}
displayName={globalInput.displayName}
isGlobal={true}
/>
}
</Checkbox> </Checkbox>
</Form.Item> </MyFormItem>
); );
break; break;
case "select": case "select":
elements.push( elements.push(
<Form.Item <MyFormItem
key={index} key={index}
label={getLabel(globalInput.displayName)} t={t}
required labelDisplayName={globalInput.displayName}
isGlobal={true}
> >
<SelectComponent t={t} globalInput={globalInput} /> <SelectComponent
</Form.Item> t={t}
globalInput={globalInput}
options={globalInput.options}
parameterName={globalInput.parameterName}
/>
</MyFormItem>
); );
break; break;

View File

@ -1,4 +1,13 @@
import { Button, Col, Popconfirm, Result, Row } from "antd"; import {
Button,
Col,
Form,
Popconfirm,
Result,
Row,
Tag,
Typography,
} from "antd";
import { useEffect, useState } from "react"; import { useEffect, useState } from "react";
import GroupTasksViewModal from "./GroupTasksViewModal"; import GroupTasksViewModal from "./GroupTasksViewModal";
import GroupTypeSelectionModal from "./GroupTypeSelectionModal"; import GroupTypeSelectionModal from "./GroupTypeSelectionModal";
@ -162,3 +171,41 @@ export default function GroupTasks({ isGroupTasksViewModalOpen }) {
</> </>
); );
} }
export function MyFormItem({ children, t, style, labelDisplayName, isGlobal }) {
return (
<Form.Item
style={style}
required
label={
labelDisplayName !== undefined && (
<MyFormItemLabel
t={t}
displayName={labelDisplayName}
isGlobal={isGlobal}
/>
)
}
>
{children}
</Form.Item>
);
}
export function MyFormItemLabel({ t, displayName, isGlobal }) {
return (
<>
{displayName === undefined || displayName === "" ? (
<Typography.Text type="danger">DisplayName is missing</Typography.Text>
) : (
displayName
)}
{isGlobal && (
<Tag style={{ marginLeft: 6 }} color="purple">
{t("groupTasks.tag.global")}
</Tag>
)}
</>
);
}