group type selection

main
alex 2023-04-22 01:14:47 +02:00
parent 1a29502b69
commit 346839917b
6 changed files with 246 additions and 199 deletions

View File

@ -5,17 +5,10 @@ import PageContent from "./Components/PageContent";
import SideMenu from "./Components/SideMenu"; import SideMenu from "./Components/SideMenu";
import Login from "./Pages/Login"; import Login from "./Pages/Login";
import { Layout } from "antd"; import { Layout } from "antd";
import { import { UseUserSession, WebSocketProvider } from "./utils";
Constants,
ClientUserDataContextPreview,
ClientUserDataContext,
UseUserSession,
WebSocketProvider,
} from "./utils";
export default function App() { export default function App() {
const { userSession, setUserSession } = UseUserSession(); const { userSession, setUserSession } = UseUserSession();
const [userData, setUserData] = useState(ClientUserDataContextPreview);
if (!userSession) { if (!userSession) {
return <Login setUserSession={setUserSession} />; return <Login setUserSession={setUserSession} />;
@ -23,16 +16,13 @@ export default function App() {
return ( return (
<Layout style={{ minHeight: "100vh" }}> <Layout style={{ minHeight: "100vh" }}>
<ClientUserDataContext.Provider value={userData}> <WebSocketProvider
<WebSocketProvider userSession={userSession}
userSession={userSession} setUserSession={setUserSession}
setUserSession={setUserSession} >
setUserData={setUserData} <SideMenu setUserSession={setUserSession}></SideMenu>
> <PageContent></PageContent>
<SideMenu setUserSession={setUserSession}></SideMenu> </WebSocketProvider>
<PageContent></PageContent>
</WebSocketProvider>
</ClientUserDataContext.Provider>
</Layout> </Layout>
); );
} }

View File

@ -9,19 +9,13 @@ import Sider from "antd/es/layout/Sider";
import { useContext, useEffect, useState } from "react"; import { useContext, useEffect, useState } from "react";
import { useLocation, useNavigate } from "react-router-dom"; import { useLocation, useNavigate } from "react-router-dom";
import PropTypes from "prop-types"; import PropTypes from "prop-types";
import { import { Constants, UseUserSession, WebSocketContext } from "../../utils";
ClientUserDataContext,
Constants,
UseUserSession,
WebSocketTestContext,
} from "../../utils";
export default function SideMenu({ setUserSession }) { export default function SideMenu({ setUserSession }) {
const { userSession } = UseUserSession(); const { userSession } = UseUserSession();
const location = useLocation(); const location = useLocation();
const [selectedKeys, setSelectedKeys] = useState("/"); const [selectedKeys, setSelectedKeys] = useState("/");
const clientUserDataContext = useContext(ClientUserDataContext); const webSocketContext = useContext(WebSocketContext);
const webSocketTestContext = useContext(WebSocketTestContext);
useEffect(() => { useEffect(() => {
const pathName = location.pathname; const pathName = location.pathname;
@ -75,11 +69,9 @@ export default function SideMenu({ setUserSession }) {
{ {
icon: ( icon: (
<Badge <Badge
status={webSocketTestContext.connectionBadgeStatus} status={webSocketContext.ConnectionBadgeStatus}
text={`${ text={`${webSocketContext.ConnectedWebSocketUsersCount} ${
webSocketTestContext.connectedWebSocketUsersCount webSocketContext.ConnectedWebSocketUsersCount === 1
} ${
webSocketTestContext.connectedWebSocketUsersCount === 1
? "user" ? "user"
: "users" : "users"
} connected`} } connected`}
@ -87,7 +79,7 @@ export default function SideMenu({ setUserSession }) {
), ),
}, },
{ {
label: clientUserDataContext.Username, label: webSocketContext.User.Username,
icon: <UserOutlined />, icon: <UserOutlined />,
}, },
{ {

View File

@ -0,0 +1,150 @@
import {
Button,
Divider,
Form,
Input,
InputNumber,
Modal,
Select,
Space,
notification,
} from "antd";
export default function GroupTypeSelectionModal({
isOpen,
setIsOpen,
setIsGroupTaskModalOpen,
categoryGroup,
currentSelectedModalGroupType,
setCurrentSelectedModalGroupType,
}) {
const handleCancel = () => setIsOpen(false);
const [api, contextHolder] = notification.useNotification();
const GroupGlobalInputs = ({ groupType }) => {
if (groupType !== null) {
var elements = [];
categoryGroup.groups.forEach((group) => {
if (group.name === groupType && group.globalInputs?.length > 0) {
group.globalInputs.forEach((globalInput) => {
switch (globalInput.type) {
case "text":
elements.push(
<Form.Item
key={globalInput.parameterName}
label={globalInput.displayName}
required
>
<Input />
</Form.Item>
);
break;
case "number":
elements.push(
<Form.Item
key={globalInput.parameterName}
label={globalInput.displayName}
required
>
<InputNumber style={{ width: "100%" }} />
</Form.Item>
);
break;
default:
api["error"]({
message: `Type ${globalInput.type} not implemented`,
description: `Was specified in: ${globalInput.displayName}`,
});
break;
}
});
}
});
return (
<>
{elements.length > 0 ? (
<>
<Divider />
<h3 style={{ fontWeight: "bold" }}>Fill in the global values</h3>
<Form layout="vertical">{elements}</Form>
</>
) : null}
</>
);
}
};
const startTaskPossible = () => {
if (
currentSelectedModalGroupType === null ||
currentSelectedModalGroupType === undefined
) {
return true;
}
let possible = false;
categoryGroup.groups.forEach((group) => {
if (group.name === currentSelectedModalGroupType) {
if (group.tasks === null) {
possible = true;
return;
}
}
});
return possible;
};
return (
<Modal
title="Select a group type"
open={isOpen}
onCancel={handleCancel}
centered
maskClosable={false}
footer={[
<Space key={0}>
<Button key="back" onClick={handleCancel}>
Cancel
</Button>
<Button
key="submit"
type="primary"
disabled={startTaskPossible()}
onClick={() => {
setIsOpen(false);
setIsGroupTaskModalOpen(true);
}}
>
Start task
</Button>
</Space>,
]}
>
{contextHolder}
<Select
placeholder="Choose a group type"
style={{ width: "100%" }}
value={currentSelectedModalGroupType}
onChange={(value) => setCurrentSelectedModalGroupType(value)}
>
{categoryGroup.category !== undefined
? categoryGroup.groups.map((group, index) => {
console.log(group);
return (
<Select.Option key={index} value={group.name}>
{group.name}
</Select.Option>
);
})
: null}
</Select>
<GroupGlobalInputs groupType={currentSelectedModalGroupType} />
</Modal>
);
}

View File

@ -1,103 +0,0 @@
import {
Button,
Divider,
Form,
Input,
InputNumber,
Modal,
Select,
Space,
} from "antd";
import { useState } from "react";
export default function TaskTypeSelectionModal({
isOpen,
setIsOpen,
setIsGroupTaskModalOpen,
}) {
const [currentSelectedModalTaskType, setCurrentSelectedModalTaskType] =
useState(null);
const handleCancel = () => setIsOpen(false);
const GroupTaskGlobalInputs = ({ taskType }) => {
if (taskType === "produktionstask1") {
return (
<>
<Divider />
<h3 style={{ fontWeight: "bold" }}>
Fill in the global values for the task
</h3>
<Form layout="vertical">
<Form.Item label="Irgendwas tolles" required>
<Input />
</Form.Item>
<Form.Item label="Nummer der Kiste" required>
<InputNumber defaultValue={0} style={{ width: "100%" }} />
</Form.Item>
</Form>
</>
);
} else if (taskType === "printer") {
return (
<>
<Divider />
<h3 style={{ fontWeight: "bold" }}>
Fill in the global values for the task
</h3>
<Form layout="vertical">
<Form.Item label="Produktname" required>
<Input />
</Form.Item>
</Form>
</>
);
}
return <h1>{taskType}</h1>;
};
return (
<Modal
title="Select a task type"
open={isOpen}
onCancel={handleCancel}
centered
footer={[
<Space key={0}>
<Button key="back" onClick={handleCancel}>
Cancel
</Button>
<Button
key="submit"
type="primary"
disabled={currentSelectedModalTaskType === null}
onClick={() => {
setIsOpen(false);
setIsGroupTaskModalOpen(true);
}}
>
Start task
</Button>
</Space>,
]}
>
<Select
placeholder="Choose a task"
style={{ width: "100%" }}
onChange={(value) => setCurrentSelectedModalTaskType(value)}
>
<Select.Option value="acrylglas">
Acryl Glas gravierung starten
</Select.Option>
<Select.Option value="printer">Label drucken</Select.Option>
<Select.Option value="produktionstask1">
Produktionstask 1
</Select.Option>
</Select>
<GroupTaskGlobalInputs taskType={currentSelectedModalTaskType} />
</Modal>
);
}

View File

@ -1,9 +1,10 @@
import { PlusOutlined, ReloadOutlined } from "@ant-design/icons"; import { PlusOutlined, ReloadOutlined } from "@ant-design/icons";
import { Badge, Button, Divider, Popconfirm, Space, Table } from "antd"; import { Button, Divider, Popconfirm, Result, Space, Table } from "antd";
import { useState } from "react"; import { useContext, useState } from "react";
import { Link } from "react-router-dom"; import { Link } from "react-router-dom";
import GroupTaskModal from "./GroupTaskModal"; import GroupTaskModal from "./GroupTaskModal";
import TaskTypeSelectionModal from "./TaskTypeSelectionModal"; import GroupTypeSelectionModal from "./GroupTypeSelectionModal";
import { WebSocketContext } from "../../utils";
const columns = [ const columns = [
{ {
@ -12,9 +13,9 @@ const columns = [
key: "id", key: "id",
}, },
{ {
title: "Task Name", title: "Group Name",
dataIndex: "taskname", dataIndex: "groupname",
key: "taskname", key: "groupname",
}, },
{ {
title: "Step", title: "Step",
@ -42,12 +43,12 @@ const columns = [
), ),
}, },
]; ];
/*
const data = [ const data = [
{ {
key: "1", key: "1",
id: "12312", id: "12312",
taskname: "Janex Device Acryl Led Lamp", groupname: "Janex Device Acryl Led Lamp",
step: "6 / 6", step: "6 / 6",
status: <Badge status="success" text="Finished" />, status: <Badge status="success" text="Finished" />,
datetime: "2020-01-01 12:00:00", datetime: "2020-01-01 12:00:00",
@ -55,42 +56,52 @@ const data = [
{ {
key: "2", key: "2",
id: "9999", id: "9999",
taskname: "Acryl Glas schneiden", groupname: "Acryl Glas schneiden",
step: "3 / 6", step: "3 / 6",
status: <Badge status="error" text="Failed" />, status: <Badge status="error" text="Failed" />,
datetime: "2020-01-01 12:00:00", datetime: "2020-01-01 12:00:00",
}, },
]; ]; */
export default function GroupTasks() { export default function GroupTasks() {
const [isTaskTypeModalOpen, setIsTaskTypeModalOpen] = useState(false); const [isGroupTypeModalOpen, setIsGroupTypeModalOpen] = useState(false);
const [isGroupTaskModalOpen, setIsGroupTaskModalOpen] = useState(false); const [isGroupTaskModalOpen, setIsGroupTaskModalOpen] = useState(false);
const [currentCategoryGroup, setCurrentCategoryGroup] = useState([]);
const [currentSelectedModalGroupType, setCurrentSelectedModalGroupType] =
useState();
const webSocketContext = useContext(WebSocketContext);
const showModal = (test) => { const showGroupTypeSelectionModal = (categoryGroup) => {
console.log(test); setCurrentCategoryGroup(categoryGroup);
setIsTaskTypeModalOpen(true); setIsGroupTypeModalOpen(true);
setCurrentSelectedModalGroupType(null);
}; };
return ( return (
<> <>
<h1 style={{ fontWeight: "bold" }}>GROUP TASKS</h1> <h1 style={{ fontWeight: "bold" }}>GROUP TASKS</h1>
<GroupTaskList {webSocketContext.CategoryGroups.length === 0 ? (
category="Janex Device Acryl Led Lamp" <Result status="404" title="No group tasks found" />
showModal={showModal} ) : (
/> webSocketContext.CategoryGroups.map((categoryGroup) => {
<GroupTaskList return (
category="Janex Werkzeug" <GroupTaskList
dataSource={false} key={categoryGroup.category}
showModal={showModal} categoryGroup={categoryGroup}
/> showGroupTypeSelectionModal={showGroupTypeSelectionModal}
<GroupTaskList category="Roese" showModal={showModal} /> />
<GroupTaskList category="Umbach" showModal={showModal} /> );
})
)}
<TaskTypeSelectionModal <GroupTypeSelectionModal
isOpen={isTaskTypeModalOpen} isOpen={isGroupTypeModalOpen}
setIsOpen={setIsTaskTypeModalOpen} setIsOpen={setIsGroupTypeModalOpen}
setIsGroupTaskModalOpen={setIsGroupTaskModalOpen} setIsGroupTaskModalOpen={setIsGroupTaskModalOpen}
categoryGroup={currentCategoryGroup}
currentSelectedModalGroupType={currentSelectedModalGroupType}
setCurrentSelectedModalGroupType={setCurrentSelectedModalGroupType}
/> />
<GroupTaskModal <GroupTaskModal
@ -101,10 +112,23 @@ export default function GroupTasks() {
); );
} }
function GroupTaskList({ category, dataSource, showModal }) { function GroupTaskList({ categoryGroup, showGroupTypeSelectionModal }) {
/*const tasksAvailable = () => {
let available = true;
categoryGroup.groups.forEach((group) => {
if (group.tasks !== null) {
available = false;
return;
}
});
return available;
}; */
return ( return (
<> <>
<Divider orientation="left">{category}</Divider> <Divider orientation="left">{categoryGroup.category}</Divider>
<Space <Space
style={{ style={{
marginBottom: 16, marginBottom: 16,
@ -115,7 +139,7 @@ function GroupTaskList({ category, dataSource, showModal }) {
<Button <Button
type="primary" type="primary"
icon={<PlusOutlined />} icon={<PlusOutlined />}
onClick={() => showModal(true)} onClick={() => showGroupTypeSelectionModal(categoryGroup)}
> >
New task New task
</Button> </Button>
@ -127,10 +151,7 @@ function GroupTaskList({ category, dataSource, showModal }) {
<Button icon={<ReloadOutlined />}>Reload</Button> <Button icon={<ReloadOutlined />}>Reload</Button>
</Popconfirm> </Popconfirm>
</Space> </Space>
<Table <Table columns={columns} />
columns={columns}
dataSource={dataSource === false ? null : data}
/>
</> </>
); );
} }

View File

@ -8,20 +8,6 @@ export const Constants = {
WS_ADDRESS: "ws://localhost:8080/ws", WS_ADDRESS: "ws://localhost:8080/ws",
}; };
/**
* client user data
*/
let l = "loading...";
// for the data preview when the request is not finished
export const ClientUserDataContextPreview = {
Username: l,
Email: l,
};
export let ClientUserDataContext = createContext(null);
/** /**
* user session * user session
*/ */
@ -51,12 +37,19 @@ export function UseUserSession() {
/** /**
* websocket * websocket
*/ */
let l = "loading...";
let webSocketContextPreview = { let webSocketContextPreview = {
connectionBadgeStatus: "error", User: {
connectedWebSocketUsersCount: 0, Username: l,
Email: l,
},
ConnectionBadgeStatus: "error",
ConnectedWebSocketUsersCount: 0,
CategoryGroups: [],
}; };
export const WebSocketTestContext = createContext(webSocketContextPreview); export const WebSocketContext = createContext(webSocketContextPreview);
// commands received from the backend server // commands received from the backend server
const ReceivedMessagesCommands = { const ReceivedMessagesCommands = {
@ -64,16 +57,17 @@ const ReceivedMessagesCommands = {
UpdateConnectedUsers: 2, UpdateConnectedUsers: 2,
}; };
export function WebSocketProvider({ export function WebSocketProvider({ children, userSession, setUserSession }) {
children,
userSession,
setUserSession,
setUserData,
}) {
const [isReady, setIsReady] = useState(false); const [isReady, setIsReady] = useState(false);
const [connectionBadgeStatus, setConnectionBadgeStatus] = useState("error"); const [connectionBadgeStatus, setConnectionBadgeStatus] = useState(
webSocketContextPreview.ConnectionBadgeStatus
);
const [connectedWebSocketUsersCount, setConnectedWebSocketUsersCount] = const [connectedWebSocketUsersCount, setConnectedWebSocketUsersCount] =
useState(0); useState(0);
const [user, setUser] = useState(webSocketContextPreview.User);
const [categoryGroups, setCategoryGroups] = useState(
webSocketContextPreview.CategoryGroups
);
let socket = null; let socket = null;
@ -95,7 +89,8 @@ export function WebSocketProvider({
switch (cmd) { switch (cmd) {
case ReceivedMessagesCommands.InitUserSocketConnection: case ReceivedMessagesCommands.InitUserSocketConnection:
setUserData(body); setUser(body.User);
setCategoryGroups(body.CategoryGroups);
break; break;
case ReceivedMessagesCommands.UpdateConnectedUsers: case ReceivedMessagesCommands.UpdateConnectedUsers:
setConnectedWebSocketUsersCount(body); setConnectedWebSocketUsersCount(body);
@ -130,13 +125,15 @@ export function WebSocketProvider({
}, []); }, []);
return ( return (
<WebSocketTestContext.Provider <WebSocketContext.Provider
value={{ value={{
connectionBadgeStatus: connectionBadgeStatus, ConnectionBadgeStatus: connectionBadgeStatus,
connectedWebSocketUsersCount: connectedWebSocketUsersCount, ConnectedWebSocketUsersCount: connectedWebSocketUsersCount,
CategoryGroups: categoryGroups,
User: user,
}} }}
> >
{children} {children}
</WebSocketTestContext.Provider> </WebSocketContext.Provider>
); );
} }