group type selection
parent
1a29502b69
commit
346839917b
26
src/App.js
26
src/App.js
|
@ -5,17 +5,10 @@ import PageContent from "./Components/PageContent";
|
|||
import SideMenu from "./Components/SideMenu";
|
||||
import Login from "./Pages/Login";
|
||||
import { Layout } from "antd";
|
||||
import {
|
||||
Constants,
|
||||
ClientUserDataContextPreview,
|
||||
ClientUserDataContext,
|
||||
UseUserSession,
|
||||
WebSocketProvider,
|
||||
} from "./utils";
|
||||
import { UseUserSession, WebSocketProvider } from "./utils";
|
||||
|
||||
export default function App() {
|
||||
const { userSession, setUserSession } = UseUserSession();
|
||||
const [userData, setUserData] = useState(ClientUserDataContextPreview);
|
||||
|
||||
if (!userSession) {
|
||||
return <Login setUserSession={setUserSession} />;
|
||||
|
@ -23,16 +16,13 @@ export default function App() {
|
|||
|
||||
return (
|
||||
<Layout style={{ minHeight: "100vh" }}>
|
||||
<ClientUserDataContext.Provider value={userData}>
|
||||
<WebSocketProvider
|
||||
userSession={userSession}
|
||||
setUserSession={setUserSession}
|
||||
setUserData={setUserData}
|
||||
>
|
||||
<SideMenu setUserSession={setUserSession}></SideMenu>
|
||||
<PageContent></PageContent>
|
||||
</WebSocketProvider>
|
||||
</ClientUserDataContext.Provider>
|
||||
<WebSocketProvider
|
||||
userSession={userSession}
|
||||
setUserSession={setUserSession}
|
||||
>
|
||||
<SideMenu setUserSession={setUserSession}></SideMenu>
|
||||
<PageContent></PageContent>
|
||||
</WebSocketProvider>
|
||||
</Layout>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -9,19 +9,13 @@ import Sider from "antd/es/layout/Sider";
|
|||
import { useContext, useEffect, useState } from "react";
|
||||
import { useLocation, useNavigate } from "react-router-dom";
|
||||
import PropTypes from "prop-types";
|
||||
import {
|
||||
ClientUserDataContext,
|
||||
Constants,
|
||||
UseUserSession,
|
||||
WebSocketTestContext,
|
||||
} from "../../utils";
|
||||
import { Constants, UseUserSession, WebSocketContext } from "../../utils";
|
||||
|
||||
export default function SideMenu({ setUserSession }) {
|
||||
const { userSession } = UseUserSession();
|
||||
const location = useLocation();
|
||||
const [selectedKeys, setSelectedKeys] = useState("/");
|
||||
const clientUserDataContext = useContext(ClientUserDataContext);
|
||||
const webSocketTestContext = useContext(WebSocketTestContext);
|
||||
const webSocketContext = useContext(WebSocketContext);
|
||||
|
||||
useEffect(() => {
|
||||
const pathName = location.pathname;
|
||||
|
@ -75,11 +69,9 @@ export default function SideMenu({ setUserSession }) {
|
|||
{
|
||||
icon: (
|
||||
<Badge
|
||||
status={webSocketTestContext.connectionBadgeStatus}
|
||||
text={`${
|
||||
webSocketTestContext.connectedWebSocketUsersCount
|
||||
} ${
|
||||
webSocketTestContext.connectedWebSocketUsersCount === 1
|
||||
status={webSocketContext.ConnectionBadgeStatus}
|
||||
text={`${webSocketContext.ConnectedWebSocketUsersCount} ${
|
||||
webSocketContext.ConnectedWebSocketUsersCount === 1
|
||||
? "user"
|
||||
: "users"
|
||||
} connected`}
|
||||
|
@ -87,7 +79,7 @@ export default function SideMenu({ setUserSession }) {
|
|||
),
|
||||
},
|
||||
{
|
||||
label: clientUserDataContext.Username,
|
||||
label: webSocketContext.User.Username,
|
||||
icon: <UserOutlined />,
|
||||
},
|
||||
{
|
||||
|
|
|
@ -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>
|
||||
);
|
||||
}
|
|
@ -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>
|
||||
);
|
||||
}
|
|
@ -1,9 +1,10 @@
|
|||
import { PlusOutlined, ReloadOutlined } from "@ant-design/icons";
|
||||
import { Badge, Button, Divider, Popconfirm, Space, Table } from "antd";
|
||||
import { useState } from "react";
|
||||
import { Button, Divider, Popconfirm, Result, Space, Table } from "antd";
|
||||
import { useContext, useState } from "react";
|
||||
import { Link } from "react-router-dom";
|
||||
import GroupTaskModal from "./GroupTaskModal";
|
||||
import TaskTypeSelectionModal from "./TaskTypeSelectionModal";
|
||||
import GroupTypeSelectionModal from "./GroupTypeSelectionModal";
|
||||
import { WebSocketContext } from "../../utils";
|
||||
|
||||
const columns = [
|
||||
{
|
||||
|
@ -12,9 +13,9 @@ const columns = [
|
|||
key: "id",
|
||||
},
|
||||
{
|
||||
title: "Task Name",
|
||||
dataIndex: "taskname",
|
||||
key: "taskname",
|
||||
title: "Group Name",
|
||||
dataIndex: "groupname",
|
||||
key: "groupname",
|
||||
},
|
||||
{
|
||||
title: "Step",
|
||||
|
@ -42,12 +43,12 @@ const columns = [
|
|||
),
|
||||
},
|
||||
];
|
||||
|
||||
/*
|
||||
const data = [
|
||||
{
|
||||
key: "1",
|
||||
id: "12312",
|
||||
taskname: "Janex Device Acryl Led Lamp",
|
||||
groupname: "Janex Device Acryl Led Lamp",
|
||||
step: "6 / 6",
|
||||
status: <Badge status="success" text="Finished" />,
|
||||
datetime: "2020-01-01 12:00:00",
|
||||
|
@ -55,42 +56,52 @@ const data = [
|
|||
{
|
||||
key: "2",
|
||||
id: "9999",
|
||||
taskname: "Acryl Glas schneiden",
|
||||
groupname: "Acryl Glas schneiden",
|
||||
step: "3 / 6",
|
||||
status: <Badge status="error" text="Failed" />,
|
||||
datetime: "2020-01-01 12:00:00",
|
||||
},
|
||||
];
|
||||
]; */
|
||||
|
||||
export default function GroupTasks() {
|
||||
const [isTaskTypeModalOpen, setIsTaskTypeModalOpen] = useState(false);
|
||||
const [isGroupTypeModalOpen, setIsGroupTypeModalOpen] = useState(false);
|
||||
const [isGroupTaskModalOpen, setIsGroupTaskModalOpen] = useState(false);
|
||||
const [currentCategoryGroup, setCurrentCategoryGroup] = useState([]);
|
||||
const [currentSelectedModalGroupType, setCurrentSelectedModalGroupType] =
|
||||
useState();
|
||||
const webSocketContext = useContext(WebSocketContext);
|
||||
|
||||
const showModal = (test) => {
|
||||
console.log(test);
|
||||
setIsTaskTypeModalOpen(true);
|
||||
const showGroupTypeSelectionModal = (categoryGroup) => {
|
||||
setCurrentCategoryGroup(categoryGroup);
|
||||
setIsGroupTypeModalOpen(true);
|
||||
setCurrentSelectedModalGroupType(null);
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<h1 style={{ fontWeight: "bold" }}>GROUP TASKS</h1>
|
||||
|
||||
<GroupTaskList
|
||||
category="Janex Device Acryl Led Lamp"
|
||||
showModal={showModal}
|
||||
/>
|
||||
<GroupTaskList
|
||||
category="Janex Werkzeug"
|
||||
dataSource={false}
|
||||
showModal={showModal}
|
||||
/>
|
||||
<GroupTaskList category="Roese" showModal={showModal} />
|
||||
<GroupTaskList category="Umbach" showModal={showModal} />
|
||||
{webSocketContext.CategoryGroups.length === 0 ? (
|
||||
<Result status="404" title="No group tasks found" />
|
||||
) : (
|
||||
webSocketContext.CategoryGroups.map((categoryGroup) => {
|
||||
return (
|
||||
<GroupTaskList
|
||||
key={categoryGroup.category}
|
||||
categoryGroup={categoryGroup}
|
||||
showGroupTypeSelectionModal={showGroupTypeSelectionModal}
|
||||
/>
|
||||
);
|
||||
})
|
||||
)}
|
||||
|
||||
<TaskTypeSelectionModal
|
||||
isOpen={isTaskTypeModalOpen}
|
||||
setIsOpen={setIsTaskTypeModalOpen}
|
||||
<GroupTypeSelectionModal
|
||||
isOpen={isGroupTypeModalOpen}
|
||||
setIsOpen={setIsGroupTypeModalOpen}
|
||||
setIsGroupTaskModalOpen={setIsGroupTaskModalOpen}
|
||||
categoryGroup={currentCategoryGroup}
|
||||
currentSelectedModalGroupType={currentSelectedModalGroupType}
|
||||
setCurrentSelectedModalGroupType={setCurrentSelectedModalGroupType}
|
||||
/>
|
||||
|
||||
<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 (
|
||||
<>
|
||||
<Divider orientation="left">{category}</Divider>
|
||||
<Divider orientation="left">{categoryGroup.category}</Divider>
|
||||
<Space
|
||||
style={{
|
||||
marginBottom: 16,
|
||||
|
@ -115,7 +139,7 @@ function GroupTaskList({ category, dataSource, showModal }) {
|
|||
<Button
|
||||
type="primary"
|
||||
icon={<PlusOutlined />}
|
||||
onClick={() => showModal(true)}
|
||||
onClick={() => showGroupTypeSelectionModal(categoryGroup)}
|
||||
>
|
||||
New task
|
||||
</Button>
|
||||
|
@ -127,10 +151,7 @@ function GroupTaskList({ category, dataSource, showModal }) {
|
|||
<Button icon={<ReloadOutlined />}>Reload</Button>
|
||||
</Popconfirm>
|
||||
</Space>
|
||||
<Table
|
||||
columns={columns}
|
||||
dataSource={dataSource === false ? null : data}
|
||||
/>
|
||||
<Table columns={columns} />
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
|
55
src/utils.js
55
src/utils.js
|
@ -8,20 +8,6 @@ export const Constants = {
|
|||
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
|
||||
*/
|
||||
|
@ -51,12 +37,19 @@ export function UseUserSession() {
|
|||
/**
|
||||
* websocket
|
||||
*/
|
||||
let l = "loading...";
|
||||
|
||||
let webSocketContextPreview = {
|
||||
connectionBadgeStatus: "error",
|
||||
connectedWebSocketUsersCount: 0,
|
||||
User: {
|
||||
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
|
||||
const ReceivedMessagesCommands = {
|
||||
|
@ -64,16 +57,17 @@ const ReceivedMessagesCommands = {
|
|||
UpdateConnectedUsers: 2,
|
||||
};
|
||||
|
||||
export function WebSocketProvider({
|
||||
children,
|
||||
userSession,
|
||||
setUserSession,
|
||||
setUserData,
|
||||
}) {
|
||||
export function WebSocketProvider({ children, userSession, setUserSession }) {
|
||||
const [isReady, setIsReady] = useState(false);
|
||||
const [connectionBadgeStatus, setConnectionBadgeStatus] = useState("error");
|
||||
const [connectionBadgeStatus, setConnectionBadgeStatus] = useState(
|
||||
webSocketContextPreview.ConnectionBadgeStatus
|
||||
);
|
||||
const [connectedWebSocketUsersCount, setConnectedWebSocketUsersCount] =
|
||||
useState(0);
|
||||
const [user, setUser] = useState(webSocketContextPreview.User);
|
||||
const [categoryGroups, setCategoryGroups] = useState(
|
||||
webSocketContextPreview.CategoryGroups
|
||||
);
|
||||
|
||||
let socket = null;
|
||||
|
||||
|
@ -95,7 +89,8 @@ export function WebSocketProvider({
|
|||
|
||||
switch (cmd) {
|
||||
case ReceivedMessagesCommands.InitUserSocketConnection:
|
||||
setUserData(body);
|
||||
setUser(body.User);
|
||||
setCategoryGroups(body.CategoryGroups);
|
||||
break;
|
||||
case ReceivedMessagesCommands.UpdateConnectedUsers:
|
||||
setConnectedWebSocketUsersCount(body);
|
||||
|
@ -130,13 +125,15 @@ export function WebSocketProvider({
|
|||
}, []);
|
||||
|
||||
return (
|
||||
<WebSocketTestContext.Provider
|
||||
<WebSocketContext.Provider
|
||||
value={{
|
||||
connectionBadgeStatus: connectionBadgeStatus,
|
||||
connectedWebSocketUsersCount: connectedWebSocketUsersCount,
|
||||
ConnectionBadgeStatus: connectionBadgeStatus,
|
||||
ConnectedWebSocketUsersCount: connectedWebSocketUsersCount,
|
||||
CategoryGroups: categoryGroups,
|
||||
User: user,
|
||||
}}
|
||||
>
|
||||
{children}
|
||||
</WebSocketTestContext.Provider>
|
||||
</WebSocketContext.Provider>
|
||||
);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue