From 2ac48138cba961fc09853ab16b4bb2f1dc2972f0 Mon Sep 17 00:00:00 2001 From: Blake Matthes Date: Mon, 23 Jun 2025 12:00:28 -0500 Subject: [PATCH] feat(silo attached detach): added in silo attach detach setup in the silo card --- .../logistics/siloAdjustments/AttachSilo.tsx | 164 ++++ .../logistics/siloAdjustments/DetachSilo.tsx | 145 +++ .../logistics/siloAdjustments/SiloCard.tsx | 21 +- frontend/src/routeTree.gen.ts | 917 +++++++----------- .../materialHelper/consumption/index.tsx | 2 +- frontend/src/utils/formStuff/index.tsx | 14 + .../utils/formStuff/options/FieldErrors.tsx | 16 + .../utils/formStuff/options/InputField.tsx | 58 +- .../utils/formStuff/options/selectorField.tsx | 57 ++ .../utils/formStuff/options/submitButton.tsx | 24 + .../querys/logistics/machineConnected.tsx | 23 + .../utils/querys/logistics/notConnected.tsx | 23 + server/globalUtils/runProdApi.ts | 92 ++ .../siloAdjustments/postAdjustment.ts | 10 +- .../controller/siloAttachments/attachSilo.ts | 43 + .../controller/siloAttachments/detachSilo.ts | 42 + .../siloAttachments/siloConnectionData.ts | 63 ++ server/services/logistics/logisticsService.ts | 6 + server/services/logistics/route/attachSilo.ts | 65 ++ server/services/logistics/route/detachSilo.ts | 67 ++ .../logistics/route/getSiloConnectionData.ts | 66 ++ .../sqlServer/querys/silo/connectionCheck.ts | 42 + 22 files changed, 1362 insertions(+), 598 deletions(-) create mode 100644 frontend/src/components/logistics/siloAdjustments/AttachSilo.tsx create mode 100644 frontend/src/components/logistics/siloAdjustments/DetachSilo.tsx create mode 100644 frontend/src/utils/formStuff/index.tsx create mode 100644 frontend/src/utils/formStuff/options/FieldErrors.tsx create mode 100644 frontend/src/utils/formStuff/options/selectorField.tsx create mode 100644 frontend/src/utils/formStuff/options/submitButton.tsx create mode 100644 frontend/src/utils/querys/logistics/machineConnected.tsx create mode 100644 frontend/src/utils/querys/logistics/notConnected.tsx create mode 100644 server/globalUtils/runProdApi.ts create mode 100644 server/services/logistics/controller/siloAttachments/attachSilo.ts create mode 100644 server/services/logistics/controller/siloAttachments/detachSilo.ts create mode 100644 server/services/logistics/controller/siloAttachments/siloConnectionData.ts create mode 100644 server/services/logistics/route/attachSilo.ts create mode 100644 server/services/logistics/route/detachSilo.ts create mode 100644 server/services/logistics/route/getSiloConnectionData.ts create mode 100644 server/services/sqlServer/querys/silo/connectionCheck.ts diff --git a/frontend/src/components/logistics/siloAdjustments/AttachSilo.tsx b/frontend/src/components/logistics/siloAdjustments/AttachSilo.tsx new file mode 100644 index 0000000..564a7e3 --- /dev/null +++ b/frontend/src/components/logistics/siloAdjustments/AttachSilo.tsx @@ -0,0 +1,164 @@ +import { Button } from "@/components/ui/button"; +import { + Dialog, + DialogClose, + DialogContent, + DialogDescription, + DialogFooter, + DialogHeader, + DialogTitle, + DialogTrigger, +} from "@/components/ui/dialog"; + +import { useAppForm } from "@/utils/formStuff"; +import { getMachineConnected } from "@/utils/querys/logistics/machineConnected"; +import { getMachineNotConnected } from "@/utils/querys/logistics/notConnected"; +import { useQuery } from "@tanstack/react-query"; +import axios from "axios"; +import { useState } from "react"; +import { toast } from "sonner"; + +export function AttachSilo(props: any) { + const [open, setOpen] = useState(false); + const { data, isError, isLoading, refetch } = useQuery( + getMachineNotConnected({ + siloID: props.silo.LocationID, + connectionType: "detached", + }) + ); + const { refetch: attached } = useQuery( + getMachineConnected({ + siloID: props.silo.LocationID, + connectionType: "connected", + }) + ); + + const form = useAppForm({ + defaultValues: { + laneId: props.silo.LocationID, + productionLotId: "", + machineId: "", + }, + onSubmit: async ({ value }) => { + console.log(value); + try { + const res = await axios.post( + "/api/logistics/attachsilo", + value + ); + + if (res.data.success) { + toast.success(res.data.message); + refetch(); + attached(); + form.reset(); + setOpen(!open); + } else { + console.log(res.data); + toast.error(res.data.message); + refetch(); + form.reset(); + setOpen(!open); + } + } catch (error) { + console.log(error); + toast.error( + "There was an error attaching the silo please try again, if persist please enter a helpdesk ticket." + ); + } + }, + }); + + if (isError) + return ( +
+

There was an error loading data

+
+ ); + + if (isLoading) + return ( +
+

Loading....

+
+ ); + + // convert the array that comes over to label and value + const tranMachine = data.map((i: any) => ({ + value: i.machineId.toString(), + label: i.name, + })); + + return ( + + + + + + +
{ + e.preventDefault(); + form.handleSubmit(); + }} + > + + + Attach silo for: {props.silo.Description} + + + Enter the new lotnumber, select the machine you + would like to attach. + + +
+

+ NOTE: If the machine you are trying to attach is not + showing in the drop down this means it is already + attached to this silo. +

+
+
+ ( + + )} + /> +
+
+ ( + + )} + /> +
+ + + + + + + Attach + + +
+
+
+ ); +} diff --git a/frontend/src/components/logistics/siloAdjustments/DetachSilo.tsx b/frontend/src/components/logistics/siloAdjustments/DetachSilo.tsx new file mode 100644 index 0000000..9bf8d09 --- /dev/null +++ b/frontend/src/components/logistics/siloAdjustments/DetachSilo.tsx @@ -0,0 +1,145 @@ +import { Button } from "@/components/ui/button"; +import { + Dialog, + DialogClose, + DialogContent, + DialogDescription, + DialogFooter, + DialogHeader, + DialogTitle, + DialogTrigger, +} from "@/components/ui/dialog"; + +import { useAppForm } from "@/utils/formStuff"; +import { getMachineConnected } from "@/utils/querys/logistics/machineConnected"; +import { getMachineNotConnected } from "@/utils/querys/logistics/notConnected"; + +import { useQuery } from "@tanstack/react-query"; +import axios from "axios"; +import { useState } from "react"; +import { toast } from "sonner"; + +export function DetachSilo(props: any) { + const [open, setOpen] = useState(false); + const { data, isError, isLoading, refetch } = useQuery( + getMachineConnected({ + siloID: props.silo.LocationID, + connectionType: "connected", + }) + ); + + const { refetch: notConnected } = useQuery( + getMachineNotConnected({ + siloID: props.silo.LocationID, + connectionType: "detached", + }) + ); + + const form = useAppForm({ + defaultValues: { + laneId: props.silo.LocationID, + machineId: 0, + }, + onSubmit: async ({ value }) => { + try { + const res = await axios.post( + "/api/logistics/detachsilo", + value + ); + + if (res.status === 200) { + toast.success(res.data.message); + + refetch(); + notConnected(); + form.reset(); + setOpen(!open); + } else { + console.log(res.data); + toast.error(res.data.message); + refetch(); + form.reset(); + setOpen(!open); + } + } catch (error) { + console.log(error); + toast.error( + "There was an error detaching the silo please try again, if persist please enter a helpdesk ticket." + ); + } + }, + }); + + if (isError) + return ( +
+

There was an error loading data

+
+ ); + + if (isLoading) + return ( +
+

Loading....

+
+ ); + + // convert the array that comes over to label and value + const tranMachine = data.map((i: any) => ({ + value: i.machineId.toString(), + label: i.name, + })); + return ( + + + + + +
{ + e.preventDefault(); + form.handleSubmit(); + }} + > + + + Attach silo for: {props.silo.Description} + + + Select the machine you would like to detach. + + +
+
+
+ ( + + )} + /> +
+
+
+ + + + + + Detach + + +
+
+
+ ); +} diff --git a/frontend/src/components/logistics/siloAdjustments/SiloCard.tsx b/frontend/src/components/logistics/siloAdjustments/SiloCard.tsx index 8a191b9..67b4b63 100644 --- a/frontend/src/components/logistics/siloAdjustments/SiloCard.tsx +++ b/frontend/src/components/logistics/siloAdjustments/SiloCard.tsx @@ -19,6 +19,8 @@ import { CircleAlert } from "lucide-react"; import { useState } from "react"; import { toast } from "sonner"; import ChartData from "./ChartData"; +import { AttachSilo } from "./AttachSilo"; +import { DetachSilo } from "./DetachSilo"; export default function SiloCard(data: any) { const token = localStorage.getItem("auth_token"); @@ -151,6 +153,7 @@ export default function SiloCard(data: any) { /> diff --git a/frontend/src/routeTree.gen.ts b/frontend/src/routeTree.gen.ts index a8cc97b..1d1665d 100644 --- a/frontend/src/routeTree.gen.ts +++ b/frontend/src/routeTree.gen.ts @@ -8,506 +8,203 @@ // You should NOT make any changes in this file as it will be overwritten. // Additionally, you should also exclude this file from your linter and/or formatter to prevent it from being checked or modified. -// Import Routes +import { Route as rootRouteImport } from './routes/__root' +import { Route as RegisterRouteImport } from './routes/register' +import { Route as LoginRouteImport } from './routes/login' +import { Route as ChangelogRouteImport } from './routes/changelog' +import { Route as AboutRouteImport } from './routes/about' +import { Route as EomRouteImport } from './routes/_eom' +import { Route as AuthRouteImport } from './routes/_auth' +import { Route as AdminRouteImport } from './routes/_admin' +import { Route as IndexRouteImport } from './routes/index' +import { Route as OcpIndexRouteImport } from './routes/ocp/index' +import { Route as EomEomRouteImport } from './routes/_eom/eom' +import { Route as AuthProfileRouteImport } from './routes/_auth/profile' +import { Route as AdminUsersRouteImport } from './routes/_admin/users' +import { Route as AdminSubModulesRouteImport } from './routes/_admin/subModules' +import { Route as AdminSettingsRouteImport } from './routes/_admin/settings' +import { Route as AdminServersRouteImport } from './routes/_admin/servers' +import { Route as AdminProdUsersRouteImport } from './routes/_admin/prodUsers' +import { Route as AdminNotificationMGTRouteImport } from './routes/_admin/notificationMGT' +import { Route as AdminModulesRouteImport } from './routes/_admin/modules' +import { Route as userPasswordChangeRouteImport } from './routes/(user)/passwordChange' +import { Route as ocmeCyclecountIndexRouteImport } from './routes/(ocme)/cyclecount/index' +import { Route as logisticsSiloAdjustmentsIndexRouteImport } from './routes/(logistics)/siloAdjustments/index' +import { Route as logisticsOpenOrdersIndexRouteImport } from './routes/(logistics)/openOrders/index' +import { Route as logisticsMaterialHelperIndexRouteImport } from './routes/(logistics)/materialHelper/index' +import { Route as logisticsHelperCommandsIndexRouteImport } from './routes/(logistics)/helperCommands/index' +import { Route as logisticsDmIndexRouteImport } from './routes/(logistics)/dm/index' +import { Route as logisticsBarcodegenIndexRouteImport } from './routes/(logistics)/barcodegen/index' +import { Route as EomArticleAvRouteImport } from './routes/_eom/article/$av' +import { Route as logisticsSiloAdjustmentsHistRouteImport } from './routes/(logistics)/siloAdjustments/$hist' +import { Route as logisticsMaterialHelperSiloLinkIndexRouteImport } from './routes/(logistics)/materialHelper/siloLink/index' +import { Route as logisticsMaterialHelperConsumptionIndexRouteImport } from './routes/(logistics)/materialHelper/consumption/index' +import { Route as logisticsSiloAdjustmentsCommentCommentRouteImport } from './routes/(logistics)/siloAdjustments/comment/$comment' -import { Route as rootRoute } from './routes/__root' -import { Route as RegisterImport } from './routes/register' -import { Route as LoginImport } from './routes/login' -import { Route as ChangelogImport } from './routes/changelog' -import { Route as AboutImport } from './routes/about' -import { Route as EomImport } from './routes/_eom' -import { Route as AuthImport } from './routes/_auth' -import { Route as AdminImport } from './routes/_admin' -import { Route as IndexImport } from './routes/index' -import { Route as OcpIndexImport } from './routes/ocp/index' -import { Route as EomEomImport } from './routes/_eom/eom' -import { Route as AuthProfileImport } from './routes/_auth/profile' -import { Route as AdminUsersImport } from './routes/_admin/users' -import { Route as AdminSubModulesImport } from './routes/_admin/subModules' -import { Route as AdminSettingsImport } from './routes/_admin/settings' -import { Route as AdminServersImport } from './routes/_admin/servers' -import { Route as AdminProdUsersImport } from './routes/_admin/prodUsers' -import { Route as AdminNotificationMGTImport } from './routes/_admin/notificationMGT' -import { Route as AdminModulesImport } from './routes/_admin/modules' -import { Route as userPasswordChangeImport } from './routes/(user)/passwordChange' -import { Route as ocmeCyclecountIndexImport } from './routes/(ocme)/cyclecount/index' -import { Route as logisticsSiloAdjustmentsIndexImport } from './routes/(logistics)/siloAdjustments/index' -import { Route as logisticsOpenOrdersIndexImport } from './routes/(logistics)/openOrders/index' -import { Route as logisticsMaterialHelperIndexImport } from './routes/(logistics)/materialHelper/index' -import { Route as logisticsHelperCommandsIndexImport } from './routes/(logistics)/helperCommands/index' -import { Route as logisticsDmIndexImport } from './routes/(logistics)/dm/index' -import { Route as logisticsBarcodegenIndexImport } from './routes/(logistics)/barcodegen/index' -import { Route as EomArticleAvImport } from './routes/_eom/article/$av' -import { Route as logisticsSiloAdjustmentsHistImport } from './routes/(logistics)/siloAdjustments/$hist' -import { Route as logisticsMaterialHelperSiloLinkIndexImport } from './routes/(logistics)/materialHelper/siloLink/index' -import { Route as logisticsMaterialHelperConsumptionIndexImport } from './routes/(logistics)/materialHelper/consumption/index' -import { Route as logisticsSiloAdjustmentsCommentCommentImport } from './routes/(logistics)/siloAdjustments/comment/$comment' - -// Create/Update Routes - -const RegisterRoute = RegisterImport.update({ +const RegisterRoute = RegisterRouteImport.update({ id: '/register', path: '/register', - getParentRoute: () => rootRoute, + getParentRoute: () => rootRouteImport, } as any) - -const LoginRoute = LoginImport.update({ +const LoginRoute = LoginRouteImport.update({ id: '/login', path: '/login', - getParentRoute: () => rootRoute, + getParentRoute: () => rootRouteImport, } as any) - -const ChangelogRoute = ChangelogImport.update({ +const ChangelogRoute = ChangelogRouteImport.update({ id: '/changelog', path: '/changelog', - getParentRoute: () => rootRoute, + getParentRoute: () => rootRouteImport, } as any) - -const AboutRoute = AboutImport.update({ +const AboutRoute = AboutRouteImport.update({ id: '/about', path: '/about', - getParentRoute: () => rootRoute, + getParentRoute: () => rootRouteImport, } as any) - -const EomRoute = EomImport.update({ +const EomRoute = EomRouteImport.update({ id: '/_eom', - getParentRoute: () => rootRoute, + getParentRoute: () => rootRouteImport, } as any) - -const AuthRoute = AuthImport.update({ +const AuthRoute = AuthRouteImport.update({ id: '/_auth', - getParentRoute: () => rootRoute, + getParentRoute: () => rootRouteImport, } as any) - -const AdminRoute = AdminImport.update({ +const AdminRoute = AdminRouteImport.update({ id: '/_admin', - getParentRoute: () => rootRoute, + getParentRoute: () => rootRouteImport, } as any) - -const IndexRoute = IndexImport.update({ +const IndexRoute = IndexRouteImport.update({ id: '/', path: '/', - getParentRoute: () => rootRoute, + getParentRoute: () => rootRouteImport, } as any) - -const OcpIndexRoute = OcpIndexImport.update({ +const OcpIndexRoute = OcpIndexRouteImport.update({ id: '/ocp/', path: '/ocp/', - getParentRoute: () => rootRoute, + getParentRoute: () => rootRouteImport, } as any) - -const EomEomRoute = EomEomImport.update({ +const EomEomRoute = EomEomRouteImport.update({ id: '/eom', path: '/eom', getParentRoute: () => EomRoute, } as any) - -const AuthProfileRoute = AuthProfileImport.update({ +const AuthProfileRoute = AuthProfileRouteImport.update({ id: '/profile', path: '/profile', getParentRoute: () => AuthRoute, } as any) - -const AdminUsersRoute = AdminUsersImport.update({ +const AdminUsersRoute = AdminUsersRouteImport.update({ id: '/users', path: '/users', getParentRoute: () => AdminRoute, } as any) - -const AdminSubModulesRoute = AdminSubModulesImport.update({ +const AdminSubModulesRoute = AdminSubModulesRouteImport.update({ id: '/subModules', path: '/subModules', getParentRoute: () => AdminRoute, } as any) - -const AdminSettingsRoute = AdminSettingsImport.update({ +const AdminSettingsRoute = AdminSettingsRouteImport.update({ id: '/settings', path: '/settings', getParentRoute: () => AdminRoute, } as any) - -const AdminServersRoute = AdminServersImport.update({ +const AdminServersRoute = AdminServersRouteImport.update({ id: '/servers', path: '/servers', getParentRoute: () => AdminRoute, } as any) - -const AdminProdUsersRoute = AdminProdUsersImport.update({ +const AdminProdUsersRoute = AdminProdUsersRouteImport.update({ id: '/prodUsers', path: '/prodUsers', getParentRoute: () => AdminRoute, } as any) - -const AdminNotificationMGTRoute = AdminNotificationMGTImport.update({ +const AdminNotificationMGTRoute = AdminNotificationMGTRouteImport.update({ id: '/notificationMGT', path: '/notificationMGT', getParentRoute: () => AdminRoute, } as any) - -const AdminModulesRoute = AdminModulesImport.update({ +const AdminModulesRoute = AdminModulesRouteImport.update({ id: '/modules', path: '/modules', getParentRoute: () => AdminRoute, } as any) - -const userPasswordChangeRoute = userPasswordChangeImport.update({ +const userPasswordChangeRoute = userPasswordChangeRouteImport.update({ id: '/(user)/passwordChange', path: '/passwordChange', - getParentRoute: () => rootRoute, + getParentRoute: () => rootRouteImport, } as any) - -const ocmeCyclecountIndexRoute = ocmeCyclecountIndexImport.update({ +const ocmeCyclecountIndexRoute = ocmeCyclecountIndexRouteImport.update({ id: '/(ocme)/cyclecount/', path: '/cyclecount/', - getParentRoute: () => rootRoute, + getParentRoute: () => rootRouteImport, } as any) - const logisticsSiloAdjustmentsIndexRoute = - logisticsSiloAdjustmentsIndexImport.update({ + logisticsSiloAdjustmentsIndexRouteImport.update({ id: '/(logistics)/siloAdjustments/', path: '/siloAdjustments/', - getParentRoute: () => rootRoute, + getParentRoute: () => rootRouteImport, + } as any) +const logisticsOpenOrdersIndexRoute = + logisticsOpenOrdersIndexRouteImport.update({ + id: '/(logistics)/openOrders/', + path: '/openOrders/', + getParentRoute: () => rootRouteImport, } as any) - -const logisticsOpenOrdersIndexRoute = logisticsOpenOrdersIndexImport.update({ - id: '/(logistics)/openOrders/', - path: '/openOrders/', - getParentRoute: () => rootRoute, -} as any) - const logisticsMaterialHelperIndexRoute = - logisticsMaterialHelperIndexImport.update({ + logisticsMaterialHelperIndexRouteImport.update({ id: '/(logistics)/materialHelper/', path: '/materialHelper/', - getParentRoute: () => rootRoute, + getParentRoute: () => rootRouteImport, } as any) - const logisticsHelperCommandsIndexRoute = - logisticsHelperCommandsIndexImport.update({ + logisticsHelperCommandsIndexRouteImport.update({ id: '/(logistics)/helperCommands/', path: '/helperCommands/', - getParentRoute: () => rootRoute, + getParentRoute: () => rootRouteImport, } as any) - -const logisticsDmIndexRoute = logisticsDmIndexImport.update({ +const logisticsDmIndexRoute = logisticsDmIndexRouteImport.update({ id: '/(logistics)/dm/', path: '/dm/', - getParentRoute: () => rootRoute, + getParentRoute: () => rootRouteImport, } as any) - -const logisticsBarcodegenIndexRoute = logisticsBarcodegenIndexImport.update({ - id: '/(logistics)/barcodegen/', - path: '/barcodegen/', - getParentRoute: () => rootRoute, -} as any) - -const EomArticleAvRoute = EomArticleAvImport.update({ +const logisticsBarcodegenIndexRoute = + logisticsBarcodegenIndexRouteImport.update({ + id: '/(logistics)/barcodegen/', + path: '/barcodegen/', + getParentRoute: () => rootRouteImport, + } as any) +const EomArticleAvRoute = EomArticleAvRouteImport.update({ id: '/article/$av', path: '/article/$av', getParentRoute: () => EomRoute, } as any) - const logisticsSiloAdjustmentsHistRoute = - logisticsSiloAdjustmentsHistImport.update({ + logisticsSiloAdjustmentsHistRouteImport.update({ id: '/(logistics)/siloAdjustments/$hist', path: '/siloAdjustments/$hist', - getParentRoute: () => rootRoute, + getParentRoute: () => rootRouteImport, } as any) - const logisticsMaterialHelperSiloLinkIndexRoute = - logisticsMaterialHelperSiloLinkIndexImport.update({ + logisticsMaterialHelperSiloLinkIndexRouteImport.update({ id: '/(logistics)/materialHelper/siloLink/', path: '/materialHelper/siloLink/', - getParentRoute: () => rootRoute, + getParentRoute: () => rootRouteImport, } as any) - const logisticsMaterialHelperConsumptionIndexRoute = - logisticsMaterialHelperConsumptionIndexImport.update({ + logisticsMaterialHelperConsumptionIndexRouteImport.update({ id: '/(logistics)/materialHelper/consumption/', path: '/materialHelper/consumption/', - getParentRoute: () => rootRoute, + getParentRoute: () => rootRouteImport, } as any) - const logisticsSiloAdjustmentsCommentCommentRoute = - logisticsSiloAdjustmentsCommentCommentImport.update({ + logisticsSiloAdjustmentsCommentCommentRouteImport.update({ id: '/(logistics)/siloAdjustments/comment/$comment', path: '/siloAdjustments/comment/$comment', - getParentRoute: () => rootRoute, + getParentRoute: () => rootRouteImport, } as any) -// Populate the FileRoutesByPath interface - -declare module '@tanstack/react-router' { - interface FileRoutesByPath { - '/': { - id: '/' - path: '/' - fullPath: '/' - preLoaderRoute: typeof IndexImport - parentRoute: typeof rootRoute - } - '/_admin': { - id: '/_admin' - path: '' - fullPath: '' - preLoaderRoute: typeof AdminImport - parentRoute: typeof rootRoute - } - '/_auth': { - id: '/_auth' - path: '' - fullPath: '' - preLoaderRoute: typeof AuthImport - parentRoute: typeof rootRoute - } - '/_eom': { - id: '/_eom' - path: '' - fullPath: '' - preLoaderRoute: typeof EomImport - parentRoute: typeof rootRoute - } - '/about': { - id: '/about' - path: '/about' - fullPath: '/about' - preLoaderRoute: typeof AboutImport - parentRoute: typeof rootRoute - } - '/changelog': { - id: '/changelog' - path: '/changelog' - fullPath: '/changelog' - preLoaderRoute: typeof ChangelogImport - parentRoute: typeof rootRoute - } - '/login': { - id: '/login' - path: '/login' - fullPath: '/login' - preLoaderRoute: typeof LoginImport - parentRoute: typeof rootRoute - } - '/register': { - id: '/register' - path: '/register' - fullPath: '/register' - preLoaderRoute: typeof RegisterImport - parentRoute: typeof rootRoute - } - '/(user)/passwordChange': { - id: '/(user)/passwordChange' - path: '/passwordChange' - fullPath: '/passwordChange' - preLoaderRoute: typeof userPasswordChangeImport - parentRoute: typeof rootRoute - } - '/_admin/modules': { - id: '/_admin/modules' - path: '/modules' - fullPath: '/modules' - preLoaderRoute: typeof AdminModulesImport - parentRoute: typeof AdminImport - } - '/_admin/notificationMGT': { - id: '/_admin/notificationMGT' - path: '/notificationMGT' - fullPath: '/notificationMGT' - preLoaderRoute: typeof AdminNotificationMGTImport - parentRoute: typeof AdminImport - } - '/_admin/prodUsers': { - id: '/_admin/prodUsers' - path: '/prodUsers' - fullPath: '/prodUsers' - preLoaderRoute: typeof AdminProdUsersImport - parentRoute: typeof AdminImport - } - '/_admin/servers': { - id: '/_admin/servers' - path: '/servers' - fullPath: '/servers' - preLoaderRoute: typeof AdminServersImport - parentRoute: typeof AdminImport - } - '/_admin/settings': { - id: '/_admin/settings' - path: '/settings' - fullPath: '/settings' - preLoaderRoute: typeof AdminSettingsImport - parentRoute: typeof AdminImport - } - '/_admin/subModules': { - id: '/_admin/subModules' - path: '/subModules' - fullPath: '/subModules' - preLoaderRoute: typeof AdminSubModulesImport - parentRoute: typeof AdminImport - } - '/_admin/users': { - id: '/_admin/users' - path: '/users' - fullPath: '/users' - preLoaderRoute: typeof AdminUsersImport - parentRoute: typeof AdminImport - } - '/_auth/profile': { - id: '/_auth/profile' - path: '/profile' - fullPath: '/profile' - preLoaderRoute: typeof AuthProfileImport - parentRoute: typeof AuthImport - } - '/_eom/eom': { - id: '/_eom/eom' - path: '/eom' - fullPath: '/eom' - preLoaderRoute: typeof EomEomImport - parentRoute: typeof EomImport - } - '/ocp/': { - id: '/ocp/' - path: '/ocp' - fullPath: '/ocp' - preLoaderRoute: typeof OcpIndexImport - parentRoute: typeof rootRoute - } - '/(logistics)/siloAdjustments/$hist': { - id: '/(logistics)/siloAdjustments/$hist' - path: '/siloAdjustments/$hist' - fullPath: '/siloAdjustments/$hist' - preLoaderRoute: typeof logisticsSiloAdjustmentsHistImport - parentRoute: typeof rootRoute - } - '/_eom/article/$av': { - id: '/_eom/article/$av' - path: '/article/$av' - fullPath: '/article/$av' - preLoaderRoute: typeof EomArticleAvImport - parentRoute: typeof EomImport - } - '/(logistics)/barcodegen/': { - id: '/(logistics)/barcodegen/' - path: '/barcodegen' - fullPath: '/barcodegen' - preLoaderRoute: typeof logisticsBarcodegenIndexImport - parentRoute: typeof rootRoute - } - '/(logistics)/dm/': { - id: '/(logistics)/dm/' - path: '/dm' - fullPath: '/dm' - preLoaderRoute: typeof logisticsDmIndexImport - parentRoute: typeof rootRoute - } - '/(logistics)/helperCommands/': { - id: '/(logistics)/helperCommands/' - path: '/helperCommands' - fullPath: '/helperCommands' - preLoaderRoute: typeof logisticsHelperCommandsIndexImport - parentRoute: typeof rootRoute - } - '/(logistics)/materialHelper/': { - id: '/(logistics)/materialHelper/' - path: '/materialHelper' - fullPath: '/materialHelper' - preLoaderRoute: typeof logisticsMaterialHelperIndexImport - parentRoute: typeof rootRoute - } - '/(logistics)/openOrders/': { - id: '/(logistics)/openOrders/' - path: '/openOrders' - fullPath: '/openOrders' - preLoaderRoute: typeof logisticsOpenOrdersIndexImport - parentRoute: typeof rootRoute - } - '/(logistics)/siloAdjustments/': { - id: '/(logistics)/siloAdjustments/' - path: '/siloAdjustments' - fullPath: '/siloAdjustments' - preLoaderRoute: typeof logisticsSiloAdjustmentsIndexImport - parentRoute: typeof rootRoute - } - '/(ocme)/cyclecount/': { - id: '/(ocme)/cyclecount/' - path: '/cyclecount' - fullPath: '/cyclecount' - preLoaderRoute: typeof ocmeCyclecountIndexImport - parentRoute: typeof rootRoute - } - '/(logistics)/siloAdjustments/comment/$comment': { - id: '/(logistics)/siloAdjustments/comment/$comment' - path: '/siloAdjustments/comment/$comment' - fullPath: '/siloAdjustments/comment/$comment' - preLoaderRoute: typeof logisticsSiloAdjustmentsCommentCommentImport - parentRoute: typeof rootRoute - } - '/(logistics)/materialHelper/consumption/': { - id: '/(logistics)/materialHelper/consumption/' - path: '/materialHelper/consumption' - fullPath: '/materialHelper/consumption' - preLoaderRoute: typeof logisticsMaterialHelperConsumptionIndexImport - parentRoute: typeof rootRoute - } - '/(logistics)/materialHelper/siloLink/': { - id: '/(logistics)/materialHelper/siloLink/' - path: '/materialHelper/siloLink' - fullPath: '/materialHelper/siloLink' - preLoaderRoute: typeof logisticsMaterialHelperSiloLinkIndexImport - parentRoute: typeof rootRoute - } - } -} - -// Create and export the route tree - -interface AdminRouteChildren { - AdminModulesRoute: typeof AdminModulesRoute - AdminNotificationMGTRoute: typeof AdminNotificationMGTRoute - AdminProdUsersRoute: typeof AdminProdUsersRoute - AdminServersRoute: typeof AdminServersRoute - AdminSettingsRoute: typeof AdminSettingsRoute - AdminSubModulesRoute: typeof AdminSubModulesRoute - AdminUsersRoute: typeof AdminUsersRoute -} - -const AdminRouteChildren: AdminRouteChildren = { - AdminModulesRoute: AdminModulesRoute, - AdminNotificationMGTRoute: AdminNotificationMGTRoute, - AdminProdUsersRoute: AdminProdUsersRoute, - AdminServersRoute: AdminServersRoute, - AdminSettingsRoute: AdminSettingsRoute, - AdminSubModulesRoute: AdminSubModulesRoute, - AdminUsersRoute: AdminUsersRoute, -} - -const AdminRouteWithChildren = AdminRoute._addFileChildren(AdminRouteChildren) - -interface AuthRouteChildren { - AuthProfileRoute: typeof AuthProfileRoute -} - -const AuthRouteChildren: AuthRouteChildren = { - AuthProfileRoute: AuthProfileRoute, -} - -const AuthRouteWithChildren = AuthRoute._addFileChildren(AuthRouteChildren) - -interface EomRouteChildren { - EomEomRoute: typeof EomEomRoute - EomArticleAvRoute: typeof EomArticleAvRoute -} - -const EomRouteChildren: EomRouteChildren = { - EomEomRoute: EomEomRoute, - EomArticleAvRoute: EomArticleAvRoute, -} - -const EomRouteWithChildren = EomRoute._addFileChildren(EomRouteChildren) - export interface FileRoutesByFullPath { '/': typeof IndexRoute - '': typeof EomRouteWithChildren '/about': typeof AboutRoute '/changelog': typeof ChangelogRoute '/login': typeof LoginRoute @@ -536,10 +233,8 @@ export interface FileRoutesByFullPath { '/materialHelper/consumption': typeof logisticsMaterialHelperConsumptionIndexRoute '/materialHelper/siloLink': typeof logisticsMaterialHelperSiloLinkIndexRoute } - export interface FileRoutesByTo { '/': typeof IndexRoute - '': typeof EomRouteWithChildren '/about': typeof AboutRoute '/changelog': typeof ChangelogRoute '/login': typeof LoginRoute @@ -568,9 +263,8 @@ export interface FileRoutesByTo { '/materialHelper/consumption': typeof logisticsMaterialHelperConsumptionIndexRoute '/materialHelper/siloLink': typeof logisticsMaterialHelperSiloLinkIndexRoute } - export interface FileRoutesById { - __root__: typeof rootRoute + __root__: typeof rootRouteImport '/': typeof IndexRoute '/_admin': typeof AdminRouteWithChildren '/_auth': typeof AuthRouteWithChildren @@ -603,12 +297,10 @@ export interface FileRoutesById { '/(logistics)/materialHelper/consumption/': typeof logisticsMaterialHelperConsumptionIndexRoute '/(logistics)/materialHelper/siloLink/': typeof logisticsMaterialHelperSiloLinkIndexRoute } - export interface FileRouteTypes { fileRoutesByFullPath: FileRoutesByFullPath fullPaths: | '/' - | '' | '/about' | '/changelog' | '/login' @@ -639,7 +331,6 @@ export interface FileRouteTypes { fileRoutesByTo: FileRoutesByTo to: | '/' - | '' | '/about' | '/changelog' | '/login' @@ -702,7 +393,6 @@ export interface FileRouteTypes { | '/(logistics)/materialHelper/siloLink/' fileRoutesById: FileRoutesById } - export interface RootRouteChildren { IndexRoute: typeof IndexRoute AdminRoute: typeof AdminRouteWithChildren @@ -727,6 +417,272 @@ export interface RootRouteChildren { logisticsMaterialHelperSiloLinkIndexRoute: typeof logisticsMaterialHelperSiloLinkIndexRoute } +declare module '@tanstack/react-router' { + interface FileRoutesByPath { + '/register': { + id: '/register' + path: '/register' + fullPath: '/register' + preLoaderRoute: typeof RegisterRouteImport + parentRoute: typeof rootRouteImport + } + '/login': { + id: '/login' + path: '/login' + fullPath: '/login' + preLoaderRoute: typeof LoginRouteImport + parentRoute: typeof rootRouteImport + } + '/changelog': { + id: '/changelog' + path: '/changelog' + fullPath: '/changelog' + preLoaderRoute: typeof ChangelogRouteImport + parentRoute: typeof rootRouteImport + } + '/about': { + id: '/about' + path: '/about' + fullPath: '/about' + preLoaderRoute: typeof AboutRouteImport + parentRoute: typeof rootRouteImport + } + '/_eom': { + id: '/_eom' + path: '' + fullPath: '' + preLoaderRoute: typeof EomRouteImport + parentRoute: typeof rootRouteImport + } + '/_auth': { + id: '/_auth' + path: '' + fullPath: '' + preLoaderRoute: typeof AuthRouteImport + parentRoute: typeof rootRouteImport + } + '/_admin': { + id: '/_admin' + path: '' + fullPath: '' + preLoaderRoute: typeof AdminRouteImport + parentRoute: typeof rootRouteImport + } + '/': { + id: '/' + path: '/' + fullPath: '/' + preLoaderRoute: typeof IndexRouteImport + parentRoute: typeof rootRouteImport + } + '/ocp/': { + id: '/ocp/' + path: '/ocp' + fullPath: '/ocp' + preLoaderRoute: typeof OcpIndexRouteImport + parentRoute: typeof rootRouteImport + } + '/_eom/eom': { + id: '/_eom/eom' + path: '/eom' + fullPath: '/eom' + preLoaderRoute: typeof EomEomRouteImport + parentRoute: typeof EomRoute + } + '/_auth/profile': { + id: '/_auth/profile' + path: '/profile' + fullPath: '/profile' + preLoaderRoute: typeof AuthProfileRouteImport + parentRoute: typeof AuthRoute + } + '/_admin/users': { + id: '/_admin/users' + path: '/users' + fullPath: '/users' + preLoaderRoute: typeof AdminUsersRouteImport + parentRoute: typeof AdminRoute + } + '/_admin/subModules': { + id: '/_admin/subModules' + path: '/subModules' + fullPath: '/subModules' + preLoaderRoute: typeof AdminSubModulesRouteImport + parentRoute: typeof AdminRoute + } + '/_admin/settings': { + id: '/_admin/settings' + path: '/settings' + fullPath: '/settings' + preLoaderRoute: typeof AdminSettingsRouteImport + parentRoute: typeof AdminRoute + } + '/_admin/servers': { + id: '/_admin/servers' + path: '/servers' + fullPath: '/servers' + preLoaderRoute: typeof AdminServersRouteImport + parentRoute: typeof AdminRoute + } + '/_admin/prodUsers': { + id: '/_admin/prodUsers' + path: '/prodUsers' + fullPath: '/prodUsers' + preLoaderRoute: typeof AdminProdUsersRouteImport + parentRoute: typeof AdminRoute + } + '/_admin/notificationMGT': { + id: '/_admin/notificationMGT' + path: '/notificationMGT' + fullPath: '/notificationMGT' + preLoaderRoute: typeof AdminNotificationMGTRouteImport + parentRoute: typeof AdminRoute + } + '/_admin/modules': { + id: '/_admin/modules' + path: '/modules' + fullPath: '/modules' + preLoaderRoute: typeof AdminModulesRouteImport + parentRoute: typeof AdminRoute + } + '/(user)/passwordChange': { + id: '/(user)/passwordChange' + path: '/passwordChange' + fullPath: '/passwordChange' + preLoaderRoute: typeof userPasswordChangeRouteImport + parentRoute: typeof rootRouteImport + } + '/(ocme)/cyclecount/': { + id: '/(ocme)/cyclecount/' + path: '/cyclecount' + fullPath: '/cyclecount' + preLoaderRoute: typeof ocmeCyclecountIndexRouteImport + parentRoute: typeof rootRouteImport + } + '/(logistics)/siloAdjustments/': { + id: '/(logistics)/siloAdjustments/' + path: '/siloAdjustments' + fullPath: '/siloAdjustments' + preLoaderRoute: typeof logisticsSiloAdjustmentsIndexRouteImport + parentRoute: typeof rootRouteImport + } + '/(logistics)/openOrders/': { + id: '/(logistics)/openOrders/' + path: '/openOrders' + fullPath: '/openOrders' + preLoaderRoute: typeof logisticsOpenOrdersIndexRouteImport + parentRoute: typeof rootRouteImport + } + '/(logistics)/materialHelper/': { + id: '/(logistics)/materialHelper/' + path: '/materialHelper' + fullPath: '/materialHelper' + preLoaderRoute: typeof logisticsMaterialHelperIndexRouteImport + parentRoute: typeof rootRouteImport + } + '/(logistics)/helperCommands/': { + id: '/(logistics)/helperCommands/' + path: '/helperCommands' + fullPath: '/helperCommands' + preLoaderRoute: typeof logisticsHelperCommandsIndexRouteImport + parentRoute: typeof rootRouteImport + } + '/(logistics)/dm/': { + id: '/(logistics)/dm/' + path: '/dm' + fullPath: '/dm' + preLoaderRoute: typeof logisticsDmIndexRouteImport + parentRoute: typeof rootRouteImport + } + '/(logistics)/barcodegen/': { + id: '/(logistics)/barcodegen/' + path: '/barcodegen' + fullPath: '/barcodegen' + preLoaderRoute: typeof logisticsBarcodegenIndexRouteImport + parentRoute: typeof rootRouteImport + } + '/_eom/article/$av': { + id: '/_eom/article/$av' + path: '/article/$av' + fullPath: '/article/$av' + preLoaderRoute: typeof EomArticleAvRouteImport + parentRoute: typeof EomRoute + } + '/(logistics)/siloAdjustments/$hist': { + id: '/(logistics)/siloAdjustments/$hist' + path: '/siloAdjustments/$hist' + fullPath: '/siloAdjustments/$hist' + preLoaderRoute: typeof logisticsSiloAdjustmentsHistRouteImport + parentRoute: typeof rootRouteImport + } + '/(logistics)/materialHelper/siloLink/': { + id: '/(logistics)/materialHelper/siloLink/' + path: '/materialHelper/siloLink' + fullPath: '/materialHelper/siloLink' + preLoaderRoute: typeof logisticsMaterialHelperSiloLinkIndexRouteImport + parentRoute: typeof rootRouteImport + } + '/(logistics)/materialHelper/consumption/': { + id: '/(logistics)/materialHelper/consumption/' + path: '/materialHelper/consumption' + fullPath: '/materialHelper/consumption' + preLoaderRoute: typeof logisticsMaterialHelperConsumptionIndexRouteImport + parentRoute: typeof rootRouteImport + } + '/(logistics)/siloAdjustments/comment/$comment': { + id: '/(logistics)/siloAdjustments/comment/$comment' + path: '/siloAdjustments/comment/$comment' + fullPath: '/siloAdjustments/comment/$comment' + preLoaderRoute: typeof logisticsSiloAdjustmentsCommentCommentRouteImport + parentRoute: typeof rootRouteImport + } + } +} + +interface AdminRouteChildren { + AdminModulesRoute: typeof AdminModulesRoute + AdminNotificationMGTRoute: typeof AdminNotificationMGTRoute + AdminProdUsersRoute: typeof AdminProdUsersRoute + AdminServersRoute: typeof AdminServersRoute + AdminSettingsRoute: typeof AdminSettingsRoute + AdminSubModulesRoute: typeof AdminSubModulesRoute + AdminUsersRoute: typeof AdminUsersRoute +} + +const AdminRouteChildren: AdminRouteChildren = { + AdminModulesRoute: AdminModulesRoute, + AdminNotificationMGTRoute: AdminNotificationMGTRoute, + AdminProdUsersRoute: AdminProdUsersRoute, + AdminServersRoute: AdminServersRoute, + AdminSettingsRoute: AdminSettingsRoute, + AdminSubModulesRoute: AdminSubModulesRoute, + AdminUsersRoute: AdminUsersRoute, +} + +const AdminRouteWithChildren = AdminRoute._addFileChildren(AdminRouteChildren) + +interface AuthRouteChildren { + AuthProfileRoute: typeof AuthProfileRoute +} + +const AuthRouteChildren: AuthRouteChildren = { + AuthProfileRoute: AuthProfileRoute, +} + +const AuthRouteWithChildren = AuthRoute._addFileChildren(AuthRouteChildren) + +interface EomRouteChildren { + EomEomRoute: typeof EomEomRoute + EomArticleAvRoute: typeof EomArticleAvRoute +} + +const EomRouteChildren: EomRouteChildren = { + EomEomRoute: EomEomRoute, + EomArticleAvRoute: EomArticleAvRoute, +} + +const EomRouteWithChildren = EomRoute._addFileChildren(EomRouteChildren) + const rootRouteChildren: RootRouteChildren = { IndexRoute: IndexRoute, AdminRoute: AdminRouteWithChildren, @@ -753,159 +709,6 @@ const rootRouteChildren: RootRouteChildren = { logisticsMaterialHelperSiloLinkIndexRoute: logisticsMaterialHelperSiloLinkIndexRoute, } - -export const routeTree = rootRoute +export const routeTree = rootRouteImport ._addFileChildren(rootRouteChildren) ._addFileTypes() - -/* ROUTE_MANIFEST_START -{ - "routes": { - "__root__": { - "filePath": "__root.tsx", - "children": [ - "/", - "/_admin", - "/_auth", - "/_eom", - "/about", - "/changelog", - "/login", - "/register", - "/(user)/passwordChange", - "/ocp/", - "/(logistics)/siloAdjustments/$hist", - "/(logistics)/barcodegen/", - "/(logistics)/dm/", - "/(logistics)/helperCommands/", - "/(logistics)/materialHelper/", - "/(logistics)/openOrders/", - "/(logistics)/siloAdjustments/", - "/(ocme)/cyclecount/", - "/(logistics)/siloAdjustments/comment/$comment", - "/(logistics)/materialHelper/consumption/", - "/(logistics)/materialHelper/siloLink/" - ] - }, - "/": { - "filePath": "index.tsx" - }, - "/_admin": { - "filePath": "_admin.tsx", - "children": [ - "/_admin/modules", - "/_admin/notificationMGT", - "/_admin/prodUsers", - "/_admin/servers", - "/_admin/settings", - "/_admin/subModules", - "/_admin/users" - ] - }, - "/_auth": { - "filePath": "_auth.tsx", - "children": [ - "/_auth/profile" - ] - }, - "/_eom": { - "filePath": "_eom.tsx", - "children": [ - "/_eom/eom", - "/_eom/article/$av" - ] - }, - "/about": { - "filePath": "about.tsx" - }, - "/changelog": { - "filePath": "changelog.tsx" - }, - "/login": { - "filePath": "login.tsx" - }, - "/register": { - "filePath": "register.tsx" - }, - "/(user)/passwordChange": { - "filePath": "(user)/passwordChange.tsx" - }, - "/_admin/modules": { - "filePath": "_admin/modules.tsx", - "parent": "/_admin" - }, - "/_admin/notificationMGT": { - "filePath": "_admin/notificationMGT.tsx", - "parent": "/_admin" - }, - "/_admin/prodUsers": { - "filePath": "_admin/prodUsers.tsx", - "parent": "/_admin" - }, - "/_admin/servers": { - "filePath": "_admin/servers.tsx", - "parent": "/_admin" - }, - "/_admin/settings": { - "filePath": "_admin/settings.tsx", - "parent": "/_admin" - }, - "/_admin/subModules": { - "filePath": "_admin/subModules.tsx", - "parent": "/_admin" - }, - "/_admin/users": { - "filePath": "_admin/users.tsx", - "parent": "/_admin" - }, - "/_auth/profile": { - "filePath": "_auth/profile.tsx", - "parent": "/_auth" - }, - "/_eom/eom": { - "filePath": "_eom/eom.tsx", - "parent": "/_eom" - }, - "/ocp/": { - "filePath": "ocp/index.tsx" - }, - "/(logistics)/siloAdjustments/$hist": { - "filePath": "(logistics)/siloAdjustments/$hist.tsx" - }, - "/_eom/article/$av": { - "filePath": "_eom/article/$av.tsx", - "parent": "/_eom" - }, - "/(logistics)/barcodegen/": { - "filePath": "(logistics)/barcodegen/index.tsx" - }, - "/(logistics)/dm/": { - "filePath": "(logistics)/dm/index.tsx" - }, - "/(logistics)/helperCommands/": { - "filePath": "(logistics)/helperCommands/index.tsx" - }, - "/(logistics)/materialHelper/": { - "filePath": "(logistics)/materialHelper/index.tsx" - }, - "/(logistics)/openOrders/": { - "filePath": "(logistics)/openOrders/index.tsx" - }, - "/(logistics)/siloAdjustments/": { - "filePath": "(logistics)/siloAdjustments/index.tsx" - }, - "/(ocme)/cyclecount/": { - "filePath": "(ocme)/cyclecount/index.tsx" - }, - "/(logistics)/siloAdjustments/comment/$comment": { - "filePath": "(logistics)/siloAdjustments/comment/$comment.tsx" - }, - "/(logistics)/materialHelper/consumption/": { - "filePath": "(logistics)/materialHelper/consumption/index.tsx" - }, - "/(logistics)/materialHelper/siloLink/": { - "filePath": "(logistics)/materialHelper/siloLink/index.tsx" - } - } -} -ROUTE_MANIFEST_END */ diff --git a/frontend/src/routes/(logistics)/materialHelper/consumption/index.tsx b/frontend/src/routes/(logistics)/materialHelper/consumption/index.tsx index 93251cc..57c3d5e 100644 --- a/frontend/src/routes/(logistics)/materialHelper/consumption/index.tsx +++ b/frontend/src/routes/(logistics)/materialHelper/consumption/index.tsx @@ -1,5 +1,5 @@ import ConsumeMaterial from "@/components/logistics/materialHelper/consumption/ConsumeMaterial"; -import PreformReturn from "@/components/logistics/materialHelper/consumption/PreformReturn"; +import PreformReturn from "@/components/logistics/materialHelper/consumption/MaterialReturn"; import { createFileRoute } from "@tanstack/react-router"; export const Route = createFileRoute( diff --git a/frontend/src/utils/formStuff/index.tsx b/frontend/src/utils/formStuff/index.tsx new file mode 100644 index 0000000..07e0a70 --- /dev/null +++ b/frontend/src/utils/formStuff/index.tsx @@ -0,0 +1,14 @@ +import { createFormHook, createFormHookContexts } from "@tanstack/react-form"; +import { InputField } from "./options/InputField"; +import { SubmitButton } from "./options/submitButton"; +import { SelectField } from "./options/selectorField"; + +export const { fieldContext, useFieldContext, formContext, useFormContext } = + createFormHookContexts(); + +export const { useAppForm } = createFormHook({ + fieldComponents: { InputField, SelectField }, + formComponents: { SubmitButton }, + fieldContext, + formContext, +}); diff --git a/frontend/src/utils/formStuff/options/FieldErrors.tsx b/frontend/src/utils/formStuff/options/FieldErrors.tsx new file mode 100644 index 0000000..98376fa --- /dev/null +++ b/frontend/src/utils/formStuff/options/FieldErrors.tsx @@ -0,0 +1,16 @@ +import { AnyFieldMeta } from "@tanstack/react-form"; +import { ZodError } from "zod"; + +type FieldErrorsProps = { + meta: AnyFieldMeta; +}; + +export const FieldErrors = ({ meta }: FieldErrorsProps) => { + if (!meta.isTouched) return null; + + return meta.errors.map(({ message }: ZodError, index) => ( +

+ {message} +

+ )); +}; diff --git a/frontend/src/utils/formStuff/options/InputField.tsx b/frontend/src/utils/formStuff/options/InputField.tsx index b400914..1311765 100644 --- a/frontend/src/utils/formStuff/options/InputField.tsx +++ b/frontend/src/utils/formStuff/options/InputField.tsx @@ -1,32 +1,28 @@ -//import { Input } from "@/components/ui/input"; -//import { Label } from "@radix-ui/react-dropdown-menu"; +import { Label } from "@/components/ui/label"; +import { useFieldContext } from ".."; +import { Input } from "@/components/ui/input"; +import { FieldErrors } from "./FieldErrors"; -// export const FormInput = (form: any, label: string) => { -// // -// // value.length > 3 -// // ? undefined -// // : "Username must be longer than 3 letters", -// // }} -// // children={(field) => { -// // return ( -// //
-// // -// // field.handleChange(e.target.value)} -// // /> -// // {field.state.meta.errors.length ? ( -// // {field.state.meta.errors.join(",")} -// // ) : null} -// //
-// // ); -// // }} -// // />; -// }; +type InputFieldProps = { + label: string; + inputType: string; + required: boolean; +}; +export const InputField = ({ label, inputType, required }: InputFieldProps) => { + const field = useFieldContext(); + + return ( +
+ + field.handleChange(e.target.value)} + onBlur={field.handleBlur} + type={inputType} + required={required} + /> + +
+ ); +}; diff --git a/frontend/src/utils/formStuff/options/selectorField.tsx b/frontend/src/utils/formStuff/options/selectorField.tsx new file mode 100644 index 0000000..1d23084 --- /dev/null +++ b/frontend/src/utils/formStuff/options/selectorField.tsx @@ -0,0 +1,57 @@ +import { Label } from "@/components/ui/label"; +import { useFieldContext } from ".."; +import { + Select, + SelectContent, + SelectItem, + SelectTrigger, + SelectValue, +} from "@/components/ui/select"; +import { FieldErrors } from "./FieldErrors"; + +type SelectOption = { + value: string; + label: string; +}; + +type SelectFieldProps = { + label: string; + options: SelectOption[]; + placeholder?: string; +}; + +export const SelectField = ({ + label, + options, + placeholder, +}: SelectFieldProps) => { + const field = useFieldContext(); + + return ( +
+
+ + +
+ +
+ ); +}; diff --git a/frontend/src/utils/formStuff/options/submitButton.tsx b/frontend/src/utils/formStuff/options/submitButton.tsx new file mode 100644 index 0000000..f0ab6fb --- /dev/null +++ b/frontend/src/utils/formStuff/options/submitButton.tsx @@ -0,0 +1,24 @@ +import { useStore } from "@tanstack/react-form"; +import { useFormContext } from ".."; +import { Button } from "@/components/ui/button"; + +type SubmitButtonProps = { + children: React.ReactNode; +}; + +export const SubmitButton = ({ children }: SubmitButtonProps) => { + const form = useFormContext(); + + const [isSubmitting] = useStore(form.store, (state) => [ + state.isSubmitting, + state.canSubmit, + ]); + + return ( +
+ +
+ ); +}; diff --git a/frontend/src/utils/querys/logistics/machineConnected.tsx b/frontend/src/utils/querys/logistics/machineConnected.tsx new file mode 100644 index 0000000..0736efd --- /dev/null +++ b/frontend/src/utils/querys/logistics/machineConnected.tsx @@ -0,0 +1,23 @@ +import { queryOptions } from "@tanstack/react-query"; +import axios from "axios"; + +export function getMachineConnected(siloCon: any) { + return queryOptions({ + queryKey: [`siloConnectionAttached-${siloCon.siloID}`], + queryFn: () => fetchStockSilo(siloCon), + //enabled: + //staleTime: 1000, + //refetchInterval: 60 * 1000, + refetchOnWindowFocus: true, + }); +} + +const fetchStockSilo = async (siloCon: any) => { + const { data } = await axios.post(`/api/logistics/siloconnection`, { + siloID: siloCon.siloID, + connectionType: siloCon.connectionType, + }); + // if we are not localhost ignore the devDir setting. + //const url: string = window.location.host.split(":")[0]; + return data.data ?? []; +}; diff --git a/frontend/src/utils/querys/logistics/notConnected.tsx b/frontend/src/utils/querys/logistics/notConnected.tsx new file mode 100644 index 0000000..6346dea --- /dev/null +++ b/frontend/src/utils/querys/logistics/notConnected.tsx @@ -0,0 +1,23 @@ +import { queryOptions } from "@tanstack/react-query"; +import axios from "axios"; + +export function getMachineNotConnected(siloCon: any) { + return queryOptions({ + queryKey: [`siloConnectionNotConnected-${siloCon.siloID}`], + queryFn: () => fetchStockSilo(siloCon), + //enabled: + //staleTime: 1000, + //refetchInterval: 60 * 1000, + refetchOnWindowFocus: true, + }); +} + +const fetchStockSilo = async (siloCon: any) => { + const { data } = await axios.post(`/api/logistics/siloconnection`, { + siloID: siloCon.siloID, + connectionType: siloCon.connectionType, + }); + // if we are not localhost ignore the devDir setting. + //const url: string = window.location.host.split(":")[0]; + return data.data ?? []; +}; diff --git a/server/globalUtils/runProdApi.ts b/server/globalUtils/runProdApi.ts new file mode 100644 index 0000000..f196c11 --- /dev/null +++ b/server/globalUtils/runProdApi.ts @@ -0,0 +1,92 @@ +import axios from "axios"; +import { prodEndpointCreation } from "./createUrl.js"; +import { tryCatch } from "./tryCatch.js"; +import { createLog } from "../services/logger/logger.js"; + +type bodyData = any; + +type Data = { + endpoint: string; + data: bodyData[]; +}; +export const runProdApi = async (data: Data) => { + /** + * Detachs a silo + */ + + let url = await prodEndpointCreation(data.endpoint); + + const { data: d, error } = await tryCatch( + axios.post(url, data.data[0], { + headers: { + "X-API-Key": process.env.TEC_API_KEY || "", + "Content-Type": "application/json", + }, + }) + ); + + let e = error as any; + if (e) { + //console.log(e.response); + if (e.status === 401) { + createLog( + "error", + "lst", + "logistics", + `Not autorized: ${JSON.stringify(e.response?.data)}` + ); + const data = { + success: false, + message: `Not autorized: ${JSON.stringify(e.response?.data)}`, + data: { + status: e.response?.status, + statusText: e.response?.statusText, + data: e.response?.data, + }, + }; + return data; + } else { + createLog( + "error", + "lst", + "logistics", + `There was an error processing the endpoint: ${JSON.stringify( + e.response?.data + )}` + ); + return { + success: false, + message: `There was an error processing the endpoint: ${JSON.stringify( + e.response?.data + )}`, + data: { + status: e.response?.status, + statusText: e.response?.statusText, + data: e.response?.data, + }, + }; + } + } + + if (d?.status !== 200) { + return { + success: false, + message: "Error processing endpoint", + data: { + status: d?.status, + statusText: d?.statusText, + data: d?.data, + }, + }; + } else { + return { + success: true, + message: "Endpoint was processed", + data: { + status: d.status, + statusText: d.statusText, + data: d.data, + }, + }; + } +}; diff --git a/server/services/logistics/controller/siloAdjustments/postAdjustment.ts b/server/services/logistics/controller/siloAdjustments/postAdjustment.ts index 9c520e5..81e0a13 100644 --- a/server/services/logistics/controller/siloAdjustments/postAdjustment.ts +++ b/server/services/logistics/controller/siloAdjustments/postAdjustment.ts @@ -41,15 +41,21 @@ export const postAdjustment = async (data: any, prod: any) => { const { data: silo, error } = await tryCatch( axios.post(url, siloAdjustment, { - headers: { Authorization: `Basic ${prod}` }, + headers: { + "X-API-Key": process.env.TEC_API_KEY || "", + "Content-Type": "application/json", + }, }) ); let e = error as any; if (e) { + console.log(e.response); if (e.status === 401) { const data = { success: false, - message: "Incorrect alpla prod password.", + message: `There was error posting the data: ${JSON.stringify( + e.response?.data + )}`, data: { status: e.response?.status, statusText: e.response?.statusText, diff --git a/server/services/logistics/controller/siloAttachments/attachSilo.ts b/server/services/logistics/controller/siloAttachments/attachSilo.ts new file mode 100644 index 0000000..6abbc37 --- /dev/null +++ b/server/services/logistics/controller/siloAttachments/attachSilo.ts @@ -0,0 +1,43 @@ +import { runProdApi } from "../../../../globalUtils/runProdApi.js"; +import { tryCatch } from "../../../../globalUtils/tryCatch.js"; + +export const attachSilo = async (data: any) => { + /** + * Detachs a silo + */ + + const detachData = { + endpoint: "/public/v1.0/IssueMaterial/AssignSiloToMachine", + data: [ + { + laneId: data.laneId, + machineId: data.machineId, + productionLotId: data.productionLotId, + }, + ], + }; + + const { data: d, error } = await tryCatch(runProdApi(detachData)); + + if (error) { + return { + success: false, + message: "Error processing attachingSilo data", + data: error, + }; + } + + if (!d.success) { + return { + success: false, + message: "Error processing silo attach data", + data: d.message, + }; + } + + return { + success: true, + message: "silo attach was completed", + data: d.data, + }; +}; diff --git a/server/services/logistics/controller/siloAttachments/detachSilo.ts b/server/services/logistics/controller/siloAttachments/detachSilo.ts new file mode 100644 index 0000000..f3b354b --- /dev/null +++ b/server/services/logistics/controller/siloAttachments/detachSilo.ts @@ -0,0 +1,42 @@ +import { runProdApi } from "../../../../globalUtils/runProdApi.js"; +import { tryCatch } from "../../../../globalUtils/tryCatch.js"; + +export const detachSilo = async (data: any) => { + /** + * Detachs a silo + */ + + const detachData = { + endpoint: "/public/v1.0/IssueMaterial/DetachSiloFromMachine", + data: [ + { + laneId: data.laneId, + machineId: data.machineId, + }, + ], + }; + + const { data: d, error } = await tryCatch(runProdApi(detachData)); + + if (error) { + return { + success: false, + message: "Error processing detach data", + data: error, + }; + } + + if (!d.success) { + return { + success: false, + message: "Error processing detach data", + data: d.message, + }; + } + + return { + success: true, + message: "Detach was completed", + data: d.data, + }; +}; diff --git a/server/services/logistics/controller/siloAttachments/siloConnectionData.ts b/server/services/logistics/controller/siloAttachments/siloConnectionData.ts new file mode 100644 index 0000000..d662a51 --- /dev/null +++ b/server/services/logistics/controller/siloAttachments/siloConnectionData.ts @@ -0,0 +1,63 @@ +import { tryCatch } from "../../../../globalUtils/tryCatch.js"; +import { createLog } from "../../../logger/logger.js"; +import { query } from "../../../sqlServer/prodSqlServer.js"; +import { + connectedToMachine, + notconnectedToMachine, +} from "../../../sqlServer/querys/silo/connectionCheck.js"; + +type Data = { + siloID: string; + connectionType: string; +}; +export const siloConnectionType = async (data: Data) => { + /** + * Will return the machines that are attached or detached based on the silo and connection type + */ + + if (!data) { + return { + success: false, + message: "Missing mandatory data", + data: [{ error: "Missing siloId or ConnectionType" }], + }; + } + + // change the silo id to the correct one + let newQuery = ""; + + if (data.connectionType === "connected") { + newQuery = connectedToMachine.replace("[siloID]", data.siloID); + } else { + newQuery = notconnectedToMachine.replace("[siloID]", data.siloID); + } + + /** + * get the silo data + */ + const { data: s, error } = (await tryCatch( + query(newQuery, "Silo connection check") + )) as any; + + if (error) { + createLog( + "error", + "lst", + "logistics", + `There was an error getting the silo connection data: ${JSON.stringify( + error + )}` + ); + return { + success: false, + message: "There was an error getting the silo connection data.", + data: error, + }; + } + + return { + success: true, + message: `silo ${data.connectionType} data`, + data: s.data, + }; +}; diff --git a/server/services/logistics/logisticsService.ts b/server/services/logistics/logisticsService.ts index f0cfb7b..0393d2f 100644 --- a/server/services/logistics/logisticsService.ts +++ b/server/services/logistics/logisticsService.ts @@ -21,6 +21,9 @@ import intervalChecks from "./route/getActiveLogistics.js"; import getActiveLanes from "./route/getActiveLanes.js"; import removeAsNonReable from "./route/removeAsNonReusable.js"; import getSSCC from "./route/getSSCCNumber.js"; +import getConnectionType from "./route/getSiloConnectionData.js"; +import detachSilo from "./route/detachSilo.js"; +import attachSilo from "./route/attachSilo.js"; const app = new OpenAPIHono(); @@ -33,6 +36,9 @@ const routes = [ postComment, getStockSilo, getSiloAdjustments, + getConnectionType, + detachSilo, + attachSilo, //lanes getCycleCountCheck, //warehouse diff --git a/server/services/logistics/route/attachSilo.ts b/server/services/logistics/route/attachSilo.ts new file mode 100644 index 0000000..070c14b --- /dev/null +++ b/server/services/logistics/route/attachSilo.ts @@ -0,0 +1,65 @@ +import { createRoute, OpenAPIHono, z } from "@hono/zod-openapi"; +import { responses } from "../../../globalUtils/routeDefs/responses.js"; +import { tryCatch } from "../../../globalUtils/tryCatch.js"; +import { apiHit } from "../../../globalUtils/apiHits.js"; +import { attachSilo } from "../controller/siloAttachments/attachSilo.js"; + +const app = new OpenAPIHono(); + +// const Body = z +// .object({ +// age: z.number().optional().openapi({ example: 90 }), +// //email: z.string().optional().openapi({example: "s.smith@example.com"}), +// type: z.string().optional().openapi({ example: "fg" }), +// }) +// .openapi("User"); +app.openapi( + createRoute({ + tags: ["logistics"], + summary: "Returns all the silo connection based on connection type", + method: "post", + path: "/attachsilo", + // request: { + // body: { + // content: { + // "application/json": { schema: Body }, + // }, + // }, + // }, + // description: + // "Provided a running number and lot number you can consume material.", + responses: responses(), + }), + async (c: any) => { + apiHit(c, { endpoint: "/attachSilo" }); + + const { data: body, error: bodyError } = await tryCatch(c.req.json()); + + if (bodyError) { + return { + success: false, + message: "Missing mandatory data", + data: [{ error: "Missing Data" }], + }; + } + + let b = body as any; + + const { data: silo, error } = await tryCatch(attachSilo(b)); + + if (error) { + return c.json({ + success: false, + message: "Error detaching silo.", + data: error, + }); + } + + return c.json({ + success: silo.success, + message: silo.message, + data: silo.data, + }); + } +); +export default app; diff --git a/server/services/logistics/route/detachSilo.ts b/server/services/logistics/route/detachSilo.ts new file mode 100644 index 0000000..dedb4d2 --- /dev/null +++ b/server/services/logistics/route/detachSilo.ts @@ -0,0 +1,67 @@ +import { createRoute, OpenAPIHono, z } from "@hono/zod-openapi"; +import { responses } from "../../../globalUtils/routeDefs/responses.js"; +import { tryCatch } from "../../../globalUtils/tryCatch.js"; +import { apiHit } from "../../../globalUtils/apiHits.js"; + +import { siloConnectionType } from "../controller/siloAttachments/siloConnectionData.js"; +import { detachSilo } from "../controller/siloAttachments/detachSilo.js"; + +const app = new OpenAPIHono(); + +// const Body = z +// .object({ +// age: z.number().optional().openapi({ example: 90 }), +// //email: z.string().optional().openapi({example: "s.smith@example.com"}), +// type: z.string().optional().openapi({ example: "fg" }), +// }) +// .openapi("User"); +app.openapi( + createRoute({ + tags: ["logistics"], + summary: "Returns all the silo connection based on connection type", + method: "post", + path: "/detachsilo", + // request: { + // body: { + // content: { + // "application/json": { schema: Body }, + // }, + // }, + // }, + // description: + // "Provided a running number and lot number you can consume material.", + responses: responses(), + }), + async (c: any) => { + apiHit(c, { endpoint: "/attachSilo" }); + + const { data: body, error: bodyError } = await tryCatch(c.req.json()); + + if (bodyError) { + return { + success: false, + message: "Missing mandatory data", + data: [{ error: "Missing Data" }], + }; + } + + let b = body as any; + + const { data: silo, error } = await tryCatch(detachSilo(b)); + + if (error) { + return c.json({ + success: false, + message: "Error detaching silo.", + data: error, + }); + } + + return c.json({ + success: silo.success, + message: silo.message, + data: silo.data, + }); + } +); +export default app; diff --git a/server/services/logistics/route/getSiloConnectionData.ts b/server/services/logistics/route/getSiloConnectionData.ts new file mode 100644 index 0000000..da3ef9c --- /dev/null +++ b/server/services/logistics/route/getSiloConnectionData.ts @@ -0,0 +1,66 @@ +import { createRoute, OpenAPIHono, z } from "@hono/zod-openapi"; +import { responses } from "../../../globalUtils/routeDefs/responses.js"; +import { tryCatch } from "../../../globalUtils/tryCatch.js"; +import { apiHit } from "../../../globalUtils/apiHits.js"; + +import { siloConnectionType } from "../controller/siloAttachments/siloConnectionData.js"; + +const app = new OpenAPIHono(); + +// const Body = z +// .object({ +// age: z.number().optional().openapi({ example: 90 }), +// //email: z.string().optional().openapi({example: "s.smith@example.com"}), +// type: z.string().optional().openapi({ example: "fg" }), +// }) +// .openapi("User"); +app.openapi( + createRoute({ + tags: ["logistics"], + summary: "Returns all the silo connection based on connection type", + method: "post", + path: "/siloconnection", + // request: { + // body: { + // content: { + // "application/json": { schema: Body }, + // }, + // }, + // }, + // description: + // "Provided a running number and lot number you can consume material.", + responses: responses(), + }), + async (c: any) => { + apiHit(c, { endpoint: "/siloconnection" }); + + const { data: body, error: bodyError } = await tryCatch(c.req.json()); + + if (bodyError) { + return { + success: false, + message: "Missing mandatory data", + data: [{ error: "Missing Data" }], + }; + } + + let b = body as any; + + const { data: silo, error } = await tryCatch(siloConnectionType(b)); + + if (error) { + return c.json({ + success: false, + message: "Error getting silo connection data.", + data: error, + }); + } + + return c.json({ + success: silo.success, + message: silo.message, + data: silo.data, + }); + } +); +export default app; diff --git a/server/services/sqlServer/querys/silo/connectionCheck.ts b/server/services/sqlServer/querys/silo/connectionCheck.ts new file mode 100644 index 0000000..635719b --- /dev/null +++ b/server/services/sqlServer/querys/silo/connectionCheck.ts @@ -0,0 +1,42 @@ +export const notconnectedToMachine = ` + select distinct HumanReadableId as machineId + ,Location as location + ,name + --,[SiloHumanReadableId] + from [test1_AlplaPROD2.0_Read].[masterData].[Machine] (nolock) m + + left join + [test1_AlplaPROD2.0_Read].[issueMaterial].[SiloAssignment] (nolock) s + on s.MachineId = m.id + + + where m.id not in ( + SELECT + [MachineId] + + FROM [test1_AlplaPROD2.0_Read].[issueMaterial].[SiloAssignment] + + where [SiloHumanReadableId] = [siloID] + ) + + and name not like '%REWORK%' +`; + +export const connectedToMachine = ` +SELECT + [SiloHumanReadableId] + ,[SiloDescription] + ,[MaterialHumanReadableId] + ,[MaterialDescription] + ,[ConnectionDate] + ,m.HumanReadableId as machineId + ,m.Location as location + ,m.Name as name + FROM [test1_AlplaPROD2.0_Read].[issueMaterial].[SiloAssignment] s + +left join +[test1_AlplaPROD2.0_Read].[masterData].[Machine] m +on m.id = s.MachineId + +where [SiloHumanReadableId] = [siloID] +`;