feat(ocp): add lots with scroll view was added
This commit is contained in:
32
frontend/package-lock.json
generated
32
frontend/package-lock.json
generated
@@ -16,6 +16,7 @@
|
|||||||
"@radix-ui/react-dropdown-menu": "^2.1.6",
|
"@radix-ui/react-dropdown-menu": "^2.1.6",
|
||||||
"@radix-ui/react-label": "^2.1.2",
|
"@radix-ui/react-label": "^2.1.2",
|
||||||
"@radix-ui/react-popover": "^1.1.6",
|
"@radix-ui/react-popover": "^1.1.6",
|
||||||
|
"@radix-ui/react-scroll-area": "^1.2.3",
|
||||||
"@radix-ui/react-select": "^2.1.6",
|
"@radix-ui/react-select": "^2.1.6",
|
||||||
"@radix-ui/react-separator": "^1.1.2",
|
"@radix-ui/react-separator": "^1.1.2",
|
||||||
"@radix-ui/react-slot": "^1.1.2",
|
"@radix-ui/react-slot": "^1.1.2",
|
||||||
@@ -1740,6 +1741,37 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@radix-ui/react-scroll-area": {
|
||||||
|
"version": "1.2.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/@radix-ui/react-scroll-area/-/react-scroll-area-1.2.3.tgz",
|
||||||
|
"integrity": "sha512-l7+NNBfBYYJa9tNqVcP2AGvxdE3lmE6kFTBXdvHgUaZuy+4wGCL1Cl2AfaR7RKyimj7lZURGLwFO59k4eBnDJQ==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@radix-ui/number": "1.1.0",
|
||||||
|
"@radix-ui/primitive": "1.1.1",
|
||||||
|
"@radix-ui/react-compose-refs": "1.1.1",
|
||||||
|
"@radix-ui/react-context": "1.1.1",
|
||||||
|
"@radix-ui/react-direction": "1.1.0",
|
||||||
|
"@radix-ui/react-presence": "1.1.2",
|
||||||
|
"@radix-ui/react-primitive": "2.0.2",
|
||||||
|
"@radix-ui/react-use-callback-ref": "1.1.0",
|
||||||
|
"@radix-ui/react-use-layout-effect": "1.1.0"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"@types/react": "*",
|
||||||
|
"@types/react-dom": "*",
|
||||||
|
"react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
|
||||||
|
"react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
|
||||||
|
},
|
||||||
|
"peerDependenciesMeta": {
|
||||||
|
"@types/react": {
|
||||||
|
"optional": true
|
||||||
|
},
|
||||||
|
"@types/react-dom": {
|
||||||
|
"optional": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@radix-ui/react-select": {
|
"node_modules/@radix-ui/react-select": {
|
||||||
"version": "2.1.6",
|
"version": "2.1.6",
|
||||||
"resolved": "https://registry.npmjs.org/@radix-ui/react-select/-/react-select-2.1.6.tgz",
|
"resolved": "https://registry.npmjs.org/@radix-ui/react-select/-/react-select-2.1.6.tgz",
|
||||||
|
|||||||
@@ -20,6 +20,7 @@
|
|||||||
"@radix-ui/react-dropdown-menu": "^2.1.6",
|
"@radix-ui/react-dropdown-menu": "^2.1.6",
|
||||||
"@radix-ui/react-label": "^2.1.2",
|
"@radix-ui/react-label": "^2.1.2",
|
||||||
"@radix-ui/react-popover": "^1.1.6",
|
"@radix-ui/react-popover": "^1.1.6",
|
||||||
|
"@radix-ui/react-scroll-area": "^1.2.3",
|
||||||
"@radix-ui/react-select": "^2.1.6",
|
"@radix-ui/react-select": "^2.1.6",
|
||||||
"@radix-ui/react-separator": "^1.1.2",
|
"@radix-ui/react-separator": "^1.1.2",
|
||||||
"@radix-ui/react-slot": "^1.1.2",
|
"@radix-ui/react-slot": "^1.1.2",
|
||||||
|
|||||||
@@ -1,14 +1,22 @@
|
|||||||
import {LstCard} from "@/components/extendedUI/LstCard";
|
import { LstCard } from "@/components/extendedUI/LstCard";
|
||||||
|
|
||||||
import {Skeleton} from "@/components/ui/skeleton";
|
import { Skeleton } from "@/components/ui/skeleton";
|
||||||
import {Table, TableBody, TableCell, TableHead, TableHeader, TableRow} from "@/components/ui/table";
|
import {
|
||||||
import {useSessionStore} from "@/lib/store/sessionStore";
|
Table,
|
||||||
import {useSettingStore} from "@/lib/store/useSettings";
|
TableBody,
|
||||||
import {LotType} from "@/types/lots";
|
TableCell,
|
||||||
import {getlots} from "@/utils/querys/production/lots";
|
TableHead,
|
||||||
import {useQuery} from "@tanstack/react-query";
|
TableHeader,
|
||||||
|
TableRow,
|
||||||
|
} from "@/components/ui/table";
|
||||||
|
import { useSessionStore } from "@/lib/store/sessionStore";
|
||||||
|
import { useSettingStore } from "@/lib/store/useSettings";
|
||||||
|
import { LotType } from "@/types/lots";
|
||||||
|
import { getlots } from "@/utils/querys/production/lots";
|
||||||
|
import { useQuery } from "@tanstack/react-query";
|
||||||
import ManualPrint from "./ManualPrinting/ManualPrint";
|
import ManualPrint from "./ManualPrinting/ManualPrint";
|
||||||
import ManualPrintForm from "./ManualPrinting/ManualPrintForm";
|
import ManualPrintForm from "./ManualPrinting/ManualPrintForm";
|
||||||
|
import { ScrollArea } from "@/components/ui/scroll-area";
|
||||||
|
|
||||||
let lotColumns = [
|
let lotColumns = [
|
||||||
{
|
{
|
||||||
@@ -57,12 +65,12 @@ let lotColumns = [
|
|||||||
// },
|
// },
|
||||||
];
|
];
|
||||||
export default function Lots() {
|
export default function Lots() {
|
||||||
const {data, isError, isLoading} = useQuery(getlots());
|
const { data, isError, isLoading } = useQuery(getlots());
|
||||||
const {user} = useSessionStore();
|
const { user } = useSessionStore();
|
||||||
const {settings} = useSettingStore();
|
const { settings } = useSettingStore();
|
||||||
const server = settings.filter((n) => n.name === "server")[0]?.value || "";
|
const server = settings.filter((n) => n.name === "server")[0]?.value || "";
|
||||||
|
|
||||||
console.log(server);
|
console.log(data);
|
||||||
|
|
||||||
const roles = ["admin", "manager", "operator"];
|
const roles = ["admin", "manager", "operator"];
|
||||||
|
|
||||||
@@ -83,13 +91,16 @@ export default function Lots() {
|
|||||||
if (isError) {
|
if (isError) {
|
||||||
return (
|
return (
|
||||||
<div className="m-2 p-2 min-h-2/5">
|
<div className="m-2 p-2 min-h-2/5">
|
||||||
|
<ScrollArea className="max-h-1/2 rounded-md border p-4">
|
||||||
<LstCard>
|
<LstCard>
|
||||||
<p className="text-center">Current Assigned lots</p>
|
<p className="text-center">Current Assigned lots</p>
|
||||||
<Table>
|
<Table>
|
||||||
<TableHeader>
|
<TableHeader>
|
||||||
<TableRow>
|
<TableRow>
|
||||||
{lotColumns.map((l) => (
|
{lotColumns.map((l) => (
|
||||||
<TableHead key={l.key}>{l.label}</TableHead>
|
<TableHead key={l.key}>
|
||||||
|
{l.label}
|
||||||
|
</TableHead>
|
||||||
))}
|
))}
|
||||||
</TableRow>
|
</TableRow>
|
||||||
</TableHeader>
|
</TableHeader>
|
||||||
@@ -131,12 +142,14 @@ export default function Lots() {
|
|||||||
</TableBody>
|
</TableBody>
|
||||||
</Table>
|
</Table>
|
||||||
</LstCard>
|
</LstCard>
|
||||||
|
</ScrollArea>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<LstCard className="m-2 p-2 min-h-2/5">
|
<LstCard className="m-2 p-2 min-h-2/5">
|
||||||
|
<ScrollArea className="h-[400px]">
|
||||||
<p className="text-center">Current Assigned lots</p>
|
<p className="text-center">Current Assigned lots</p>
|
||||||
<Table>
|
<Table>
|
||||||
<TableHeader>
|
<TableHeader>
|
||||||
@@ -188,21 +201,42 @@ export default function Lots() {
|
|||||||
<TableBody>
|
<TableBody>
|
||||||
{data?.map((lot: LotType) => (
|
{data?.map((lot: LotType) => (
|
||||||
<TableRow key={lot.LabelOnlineID}>
|
<TableRow key={lot.LabelOnlineID}>
|
||||||
<TableCell className="font-medium">{lot.MachineLocation}</TableCell>
|
<TableCell className="font-medium">
|
||||||
<TableCell className="font-medium">{lot.AV}</TableCell>
|
{lot.MachineLocation}
|
||||||
<TableCell className="font-medium">{lot.Alias}</TableCell>
|
</TableCell>
|
||||||
<TableCell className="font-medium">{lot.LOT}</TableCell>
|
<TableCell className="font-medium">
|
||||||
<TableCell className="font-medium">{lot.ProlinkLot}</TableCell>
|
{lot.AV}
|
||||||
<TableCell className="font-medium">{lot.PlannedQTY}</TableCell>
|
</TableCell>
|
||||||
<TableCell className="font-medium">{lot.Produced}</TableCell>
|
<TableCell className="font-medium">
|
||||||
<TableCell className="font-medium">{lot.Remaining}</TableCell>
|
{lot.Alias}
|
||||||
<TableCell className="font-medium">{lot.overPrinting}</TableCell>
|
</TableCell>
|
||||||
|
<TableCell className="font-medium">
|
||||||
|
{lot.LOT}
|
||||||
|
</TableCell>
|
||||||
|
<TableCell className="font-medium">
|
||||||
|
{lot.ProlinkLot}
|
||||||
|
</TableCell>
|
||||||
|
<TableCell className="font-medium">
|
||||||
|
{lot.PlannedQTY}
|
||||||
|
</TableCell>
|
||||||
|
<TableCell className="font-medium">
|
||||||
|
{lot.Produced}
|
||||||
|
</TableCell>
|
||||||
|
<TableCell className="font-medium">
|
||||||
|
{lot.Remaining}
|
||||||
|
</TableCell>
|
||||||
|
<TableCell className="font-medium">
|
||||||
|
{lot.overPrinting}
|
||||||
|
</TableCell>
|
||||||
{user && roles.includes(user.role) && (
|
{user && roles.includes(user.role) && (
|
||||||
<>
|
<>
|
||||||
{server === "usday1vms006" || server === "localhost" ? (
|
{server === "usday1vms006" ||
|
||||||
|
server === "localhost" ? (
|
||||||
<>
|
<>
|
||||||
<TableCell className="flex justify-center">
|
<TableCell className="flex justify-center">
|
||||||
<ManualPrintForm lot={lot} />
|
<ManualPrintForm
|
||||||
|
lot={lot}
|
||||||
|
/>
|
||||||
</TableCell>
|
</TableCell>
|
||||||
</>
|
</>
|
||||||
) : (
|
) : (
|
||||||
@@ -217,6 +251,7 @@ export default function Lots() {
|
|||||||
</TableBody>
|
</TableBody>
|
||||||
)}
|
)}
|
||||||
</Table>
|
</Table>
|
||||||
|
</ScrollArea>
|
||||||
</LstCard>
|
</LstCard>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
56
frontend/src/components/ui/scroll-area.tsx
Normal file
56
frontend/src/components/ui/scroll-area.tsx
Normal file
@@ -0,0 +1,56 @@
|
|||||||
|
import * as React from "react"
|
||||||
|
import * as ScrollAreaPrimitive from "@radix-ui/react-scroll-area"
|
||||||
|
|
||||||
|
import { cn } from "@/lib/utils"
|
||||||
|
|
||||||
|
function ScrollArea({
|
||||||
|
className,
|
||||||
|
children,
|
||||||
|
...props
|
||||||
|
}: React.ComponentProps<typeof ScrollAreaPrimitive.Root>) {
|
||||||
|
return (
|
||||||
|
<ScrollAreaPrimitive.Root
|
||||||
|
data-slot="scroll-area"
|
||||||
|
className={cn("relative", className)}
|
||||||
|
{...props}
|
||||||
|
>
|
||||||
|
<ScrollAreaPrimitive.Viewport
|
||||||
|
data-slot="scroll-area-viewport"
|
||||||
|
className="ring-ring/10 dark:ring-ring/20 dark:outline-ring/40 outline-ring/50 size-full rounded-[inherit] transition-[color,box-shadow] focus-visible:ring-4 focus-visible:outline-1"
|
||||||
|
>
|
||||||
|
{children}
|
||||||
|
</ScrollAreaPrimitive.Viewport>
|
||||||
|
<ScrollBar />
|
||||||
|
<ScrollAreaPrimitive.Corner />
|
||||||
|
</ScrollAreaPrimitive.Root>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
function ScrollBar({
|
||||||
|
className,
|
||||||
|
orientation = "vertical",
|
||||||
|
...props
|
||||||
|
}: React.ComponentProps<typeof ScrollAreaPrimitive.ScrollAreaScrollbar>) {
|
||||||
|
return (
|
||||||
|
<ScrollAreaPrimitive.ScrollAreaScrollbar
|
||||||
|
data-slot="scroll-area-scrollbar"
|
||||||
|
orientation={orientation}
|
||||||
|
className={cn(
|
||||||
|
"flex touch-none p-px transition-colors select-none",
|
||||||
|
orientation === "vertical" &&
|
||||||
|
"h-full w-2.5 border-l border-l-transparent",
|
||||||
|
orientation === "horizontal" &&
|
||||||
|
"h-2.5 flex-col border-t border-t-transparent",
|
||||||
|
className
|
||||||
|
)}
|
||||||
|
{...props}
|
||||||
|
>
|
||||||
|
<ScrollAreaPrimitive.ScrollAreaThumb
|
||||||
|
data-slot="scroll-area-thumb"
|
||||||
|
className="bg-border relative flex-1 rounded-full"
|
||||||
|
/>
|
||||||
|
</ScrollAreaPrimitive.ScrollAreaScrollbar>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export { ScrollArea, ScrollBar }
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
import {queryOptions} from "@tanstack/react-query";
|
import { queryOptions } from "@tanstack/react-query";
|
||||||
import axios from "axios";
|
import axios from "axios";
|
||||||
|
|
||||||
export function getlots() {
|
export function getlots() {
|
||||||
@@ -13,7 +13,7 @@ export function getlots() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const fetchSettings = async () => {
|
const fetchSettings = async () => {
|
||||||
const {data} = await axios.get("/api/v1/ocp/lots");
|
const { data } = await axios.get("/api/ocp/getlots");
|
||||||
// if we are not localhost ignore the devDir setting.
|
// if we are not localhost ignore the devDir setting.
|
||||||
//const url: string = window.location.host.split(":")[0];
|
//const url: string = window.location.host.split(":")[0];
|
||||||
let lotData = data.data;
|
let lotData = data.data;
|
||||||
|
|||||||
23
server/services/ocp/controller/lots/lots.ts
Normal file
23
server/services/ocp/controller/lots/lots.ts
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
import { tryCatch } from "../../../../globalUtils/tryCatch.js";
|
||||||
|
import { query } from "../../../sqlServer/prodSqlServer.js";
|
||||||
|
import { lotQuery } from "../../../sqlServer/querys/ocp/lots.js";
|
||||||
|
|
||||||
|
export const getLots = async () => {
|
||||||
|
const { data: lotInfo, error: lotError } = await tryCatch(
|
||||||
|
query(lotQuery, "Alplalabel online lots")
|
||||||
|
);
|
||||||
|
|
||||||
|
if (lotError) {
|
||||||
|
return {
|
||||||
|
success: false,
|
||||||
|
message: "There was an error getting the lots",
|
||||||
|
data: lotError,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
success: true,
|
||||||
|
message: "Current active lots that are technically released.",
|
||||||
|
data: lotInfo,
|
||||||
|
};
|
||||||
|
};
|
||||||
@@ -6,7 +6,8 @@ import getPrinters from "./routes/printers/getPritners.js";
|
|||||||
import { db } from "../../../database/dbclient.js";
|
import { db } from "../../../database/dbclient.js";
|
||||||
import { settings } from "../../../database/schema/settings.js";
|
import { settings } from "../../../database/schema/settings.js";
|
||||||
import updateprinters from "./routes/printers/updatePrinters.js";
|
import updateprinters from "./routes/printers/updatePrinters.js";
|
||||||
import { updatePrinters } from "./controller/updatePrinters.js";
|
import { updatePrinters } from "./controller/printers/updatePrinters.js";
|
||||||
|
import getLots from "./routes/lots/getLots.js";
|
||||||
|
|
||||||
const app = new OpenAPIHono();
|
const app = new OpenAPIHono();
|
||||||
|
|
||||||
@@ -15,6 +16,8 @@ const routes = [
|
|||||||
//printer
|
//printer
|
||||||
getPrinters,
|
getPrinters,
|
||||||
updateprinters,
|
updateprinters,
|
||||||
|
// lots
|
||||||
|
getLots,
|
||||||
] as const;
|
] as const;
|
||||||
const setting = await db.select().from(settings);
|
const setting = await db.select().from(settings);
|
||||||
|
|
||||||
|
|||||||
35
server/services/ocp/routes/lots/getLots.ts
Normal file
35
server/services/ocp/routes/lots/getLots.ts
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
// an external way to creating logs
|
||||||
|
import { createRoute, OpenAPIHono, z } from "@hono/zod-openapi";
|
||||||
|
import { responses } from "../../../../globalUtils/routeDefs/responses.js";
|
||||||
|
import { tryCatch } from "../../../../globalUtils/tryCatch.js";
|
||||||
|
import { getPrinters } from "../../controller/printers/getPrinters.js";
|
||||||
|
import { getLots } from "../../controller/lots/lots.js";
|
||||||
|
|
||||||
|
const app = new OpenAPIHono({ strict: false });
|
||||||
|
|
||||||
|
app.openapi(
|
||||||
|
createRoute({
|
||||||
|
tags: ["ocp"],
|
||||||
|
summary: "Returns current active lots that are tech released",
|
||||||
|
method: "get",
|
||||||
|
path: "/getlots",
|
||||||
|
responses: responses(),
|
||||||
|
}),
|
||||||
|
async (c) => {
|
||||||
|
const { data: lotData, error: lotError } = await tryCatch(getLots());
|
||||||
|
|
||||||
|
if (lotError) {
|
||||||
|
return c.json({
|
||||||
|
success: false,
|
||||||
|
message: "There was an error getting the printers",
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return c.json({
|
||||||
|
success: lotData.success,
|
||||||
|
message: lotData.message,
|
||||||
|
data: lotData.data,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
);
|
||||||
|
export default app;
|
||||||
55
server/services/sqlServer/querys/ocp/lots.ts
Normal file
55
server/services/sqlServer/querys/ocp/lots.ts
Normal file
@@ -0,0 +1,55 @@
|
|||||||
|
export const lotQuery = `
|
||||||
|
select IdMaschinen_ProdPlanung as LabelOnlineID,
|
||||||
|
IdMaschine as machineID,
|
||||||
|
MaschinenStandort as MachineLocation,
|
||||||
|
MaschinenBez as MachineDescription,
|
||||||
|
IdProdPlanung as LOT,
|
||||||
|
prolink.lot as ProlinkLot,
|
||||||
|
IdArtikelvarianten as AV,
|
||||||
|
ArtikelVariantenBez as Alias,
|
||||||
|
convert(varchar, add_date, 20) as Add_Date,
|
||||||
|
Add_user,
|
||||||
|
idEtikettenDrucker as printerID,
|
||||||
|
b.name as PrinterName,
|
||||||
|
CAST(TotalPlannedLoadingUnits as float) as PlannedQTY,
|
||||||
|
CAST(TotalProducedLoadingUnits as float) as Produced,
|
||||||
|
ROUND(CAST(TotalPlannedLoadingUnits as float) - CAST(TotalProducedLoadingUnits as float),2) as Remaining,
|
||||||
|
case
|
||||||
|
-- checks if someone changed the criteria to something else to trigger the over run
|
||||||
|
when x.ProzentReserveAnzahlPaletten > 0 then 'yes'
|
||||||
|
|
||||||
|
-- if the lot has a decimal in it to allow over running with no intervention
|
||||||
|
when CAST(TotalPlannedLoadingUnits as float) - floor(CAST(TotalPlannedLoadingUnits as float)) > 0 then 'yes'
|
||||||
|
else 'no' end as overPrinting,
|
||||||
|
CustomerHumanReadableId as CustomerId,
|
||||||
|
CustomerName as CustomerName,
|
||||||
|
idMaschine as MachineID,
|
||||||
|
prolink.lastProlinkUpdate as lastProlinkUpdate,
|
||||||
|
IdEtikettenLayoutPalette as palletLabel,
|
||||||
|
AnzahlKopienPalette as pallerCopies,
|
||||||
|
IdEtikettenLayoutKarton as cartonLabel,
|
||||||
|
AnzahlKopienKarton as cartonCopies,
|
||||||
|
IsTechnicallyReleased
|
||||||
|
--*
|
||||||
|
from AlplaPROD_test1.dbo.V_Maschinen_ProdPlanungen x (nolock)
|
||||||
|
join
|
||||||
|
[test1_AlplaPROD2.0_Read].[productionControlling].[ProducedLot] on
|
||||||
|
x.IdProdPlanung =
|
||||||
|
[test1_AlplaPROD2.0_Read].[productionControlling].[ProducedLot].ProductionLotHumanReadableId
|
||||||
|
left join
|
||||||
|
[test1_AlplaPROD2.0_Read].masterData.Printer as b on
|
||||||
|
x.IdEtikettenDrucker = b.HumanReadableId
|
||||||
|
-- adding in prolink lot
|
||||||
|
left join
|
||||||
|
(SELECT * from (SELECT IdMaschine as prolinkMachineId,
|
||||||
|
Produktionslos as lot,
|
||||||
|
Upd_Date as lastProlinkUpdate,
|
||||||
|
ROW_NUMBER() OVER (PARTITION BY IdMaschine ORDER BY Upd_Date DESC) RN_Prolink
|
||||||
|
FROM AlplaPROD_test1.dbo.T_HistoryProduktionsdaten (nolock)
|
||||||
|
WHERE Upd_Date BETWEEN DATEADD(DD, - 300, getdate()) AND DATEADD(DD, 1, getdate())) p
|
||||||
|
WHERE RN_Prolink = 1
|
||||||
|
) as prolink on
|
||||||
|
x.idMaschine = prolink.prolinkMachineId
|
||||||
|
|
||||||
|
where IsTechnicallyReleased = 1
|
||||||
|
`;
|
||||||
Reference in New Issue
Block a user