refactor(ocp): finished the dashboard and move logs and labels to a tab style
This commit is contained in:
@@ -125,7 +125,10 @@ export default function LabelLog() {
|
||||
{label.runningNr}
|
||||
</TableCell>
|
||||
<TableCell className="font-medium">
|
||||
{format(label.upd_date, "M/d/yyyy hh:mm")}
|
||||
{format(
|
||||
label?.upd_date.replace("Z", ""),
|
||||
"M/d/yyyy hh:mm"
|
||||
)}
|
||||
</TableCell>
|
||||
<TableCell className="font-medium">
|
||||
{label.status}
|
||||
|
||||
@@ -70,8 +70,6 @@ export default function Lots() {
|
||||
const { settings } = useSettingStore();
|
||||
const server = settings.filter((n) => n.name === "server")[0]?.value || "";
|
||||
|
||||
console.log(data);
|
||||
|
||||
const roles = ["admin", "manager", "operator"];
|
||||
|
||||
if (user && roles.includes(user.role)) {
|
||||
@@ -234,9 +232,7 @@ export default function Lots() {
|
||||
server === "localhost" ? (
|
||||
<>
|
||||
<TableCell className="flex justify-center">
|
||||
<ManualPrintForm
|
||||
lot={lot}
|
||||
/>
|
||||
<ManualPrintForm />
|
||||
</TableCell>
|
||||
</>
|
||||
) : (
|
||||
|
||||
@@ -20,31 +20,31 @@ import {
|
||||
SelectValue,
|
||||
} from "@/components/ui/select";
|
||||
import { Textarea } from "@/components/ui/textarea";
|
||||
import {useSessionStore} from "@/lib/store/sessionStore";
|
||||
import { useSettingStore } from "@/lib/store/useSettings";
|
||||
import {LotType} from "@/types/lots";
|
||||
import axios from "axios";
|
||||
import { Tag } from "lucide-react";
|
||||
import { useState } from "react";
|
||||
import { Controller, useForm } from "react-hook-form";
|
||||
import { toast } from "sonner";
|
||||
import {manualPrintLabels} from "./ManualPrintLabel";
|
||||
|
||||
const printReason = [
|
||||
{ key: "printerIssue", label: "Printer Related" },
|
||||
{ key: "missingRfidTag", label: "Missing or incorrect tag" },
|
||||
{ key: "strapper", label: "Strapper Error" },
|
||||
{ key: "manualCheck", label: "20th pallet check" },
|
||||
{ key: "outOfSync", label: "Labeler Out of Sync" },
|
||||
];
|
||||
|
||||
export default function ManualPrintForm({lot}: {lot: LotType}) {
|
||||
const {user} = useSessionStore();
|
||||
export default function ManualPrintForm() {
|
||||
const token = localStorage.getItem("auth_token");
|
||||
const { settings } = useSettingStore();
|
||||
const [open, setOpen] = useState(false);
|
||||
const server = settings.filter((n) => n.name === "server")[0]?.value;
|
||||
// const serverPort = settings.filter((n) => n.name === "serverPort")[0]?.value;
|
||||
// const serverUrl = `http://${server}:${serverPort}`;
|
||||
|
||||
// what is the dyco set to? rfid or dyco
|
||||
const dyco = settings.filter((n) => n.name === "dycoPrint");
|
||||
const {
|
||||
register,
|
||||
handleSubmit,
|
||||
@@ -54,27 +54,22 @@ export default function ManualPrintForm({lot}: {lot: LotType}) {
|
||||
control,
|
||||
} = useForm();
|
||||
|
||||
const handlePrintLabel = async (lot: LotType) => {
|
||||
//console.log(lot);
|
||||
const labels: any = await manualPrintLabels(lot, user);
|
||||
|
||||
if (labels.success) {
|
||||
toast.success(labels.message);
|
||||
} else {
|
||||
toast.error(labels.message);
|
||||
}
|
||||
};
|
||||
|
||||
const handleManualPrintLog = async (logData: any, lot: LotType) => {
|
||||
const handleManualPrintLog = async (logData: any) => {
|
||||
// toast.success(`A new label was sent to printer: ${lot.PrinterName} for line ${lot.MachineDescription} `);
|
||||
const logdataUrl = `/api/ocp/manualLabelLog`;
|
||||
const logdataUrl = `/api/ocp/manuallabellog`;
|
||||
axios
|
||||
.post(logdataUrl, logData, {headers: {Authorization: `Bearer ${token}`}})
|
||||
.post(logdataUrl, logData, {
|
||||
headers: { Authorization: `Bearer ${token}` },
|
||||
})
|
||||
.then((d) => {
|
||||
//console.log(d);
|
||||
console.log(d);
|
||||
if (d.data.success) {
|
||||
toast.success(d.data.message);
|
||||
handlePrintLabel(lot);
|
||||
} else {
|
||||
toast.error(d.data.message);
|
||||
}
|
||||
reset();
|
||||
setOpen(false);
|
||||
})
|
||||
.catch((e) => {
|
||||
if (e.response.status === 500) {
|
||||
@@ -91,9 +86,14 @@ export default function ManualPrintForm({lot}: {lot: LotType}) {
|
||||
};
|
||||
|
||||
const onSubmit = (data: any) => {
|
||||
console.log(data);
|
||||
//console.log(data);
|
||||
|
||||
handleManualPrintLog(data, lot);
|
||||
handleManualPrintLog(data);
|
||||
};
|
||||
|
||||
const closeForm = () => {
|
||||
reset();
|
||||
setOpen(false);
|
||||
};
|
||||
return (
|
||||
<Dialog
|
||||
@@ -117,12 +117,14 @@ export default function ManualPrintForm({lot}: {lot: LotType}) {
|
||||
<DialogHeader>
|
||||
<DialogTitle>Edit profile</DialogTitle>
|
||||
<DialogDescription>
|
||||
Make changes to your profile here. Click save when you're done.
|
||||
Make changes to your profile here. Click save when
|
||||
you're done.
|
||||
</DialogDescription>
|
||||
</DialogHeader>
|
||||
<form onSubmit={handleSubmit(onSubmit)}>
|
||||
<p>
|
||||
To manually print a label you must complete all the required fields below.
|
||||
To manually print a label you must complete all the
|
||||
required fields below.
|
||||
<br />
|
||||
If you clicked this in error just click close
|
||||
</p>
|
||||
@@ -143,35 +145,46 @@ export default function ManualPrintForm({lot}: {lot: LotType}) {
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
<SelectGroup>
|
||||
<SelectLabel>Print Reasons</SelectLabel>
|
||||
{printReason.map((printReason: any) => (
|
||||
<SelectItem value={printReason.key}>{printReason.label}</SelectItem>
|
||||
))}
|
||||
<SelectLabel>
|
||||
Print Reasons
|
||||
</SelectLabel>
|
||||
{printReason.map(
|
||||
(printReason: any) => (
|
||||
<SelectItem
|
||||
value={printReason.key}
|
||||
>
|
||||
{printReason.label}
|
||||
</SelectItem>
|
||||
)
|
||||
)}
|
||||
</SelectGroup>
|
||||
</SelectContent>
|
||||
</Select>
|
||||
)}
|
||||
/>
|
||||
) : (
|
||||
<div>
|
||||
<div className="m-2">
|
||||
<Label htmlFor="printRason" className="m-1">
|
||||
Why are you manually printing?
|
||||
</Label>
|
||||
<Input
|
||||
type="text"
|
||||
className={errors.printReason ? "border-red-500" : ""}
|
||||
className={
|
||||
errors.printReason ? "border-red-500" : ""
|
||||
}
|
||||
aria-invalid={!!errors.printReason}
|
||||
{...register("printReason", {
|
||||
required: true,
|
||||
minLength: {
|
||||
value: 5,
|
||||
message: "To short of a reason please try again!",
|
||||
message:
|
||||
"To short of a reason please try again!",
|
||||
},
|
||||
})}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
<div>
|
||||
<div className="m-2">
|
||||
<Label htmlFor="line" className="m-1">
|
||||
"What is the line number you are printing?"
|
||||
</Label>
|
||||
@@ -184,7 +197,7 @@ export default function ManualPrintForm({lot}: {lot: LotType}) {
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<div className="m-2">
|
||||
<Label htmlFor="initials" className="m-1">
|
||||
Enter intials
|
||||
</Label>
|
||||
@@ -195,20 +208,52 @@ export default function ManualPrintForm({lot}: {lot: LotType}) {
|
||||
{...register("initials", { required: true })}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<hr />
|
||||
{dyco[0].value === "0" && (
|
||||
<div>
|
||||
<p>Enter the missing tag number.</p>
|
||||
<hr />
|
||||
<Label htmlFor="rfidTag" className="m-1">
|
||||
Enter the tag number only Example
|
||||
ALPLA000002541. only enter 2541
|
||||
</Label>
|
||||
<Input
|
||||
type="text"
|
||||
className={
|
||||
errors.printReason ? "border-red-500" : ""
|
||||
}
|
||||
aria-invalid={!!errors.printReason}
|
||||
{...register("rfidTag", {
|
||||
required: true,
|
||||
minLength: {
|
||||
value: 1,
|
||||
message: "Tag number is to short!",
|
||||
},
|
||||
})}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
<div className="m-2">
|
||||
<Textarea
|
||||
//label="Comments"
|
||||
placeholder="add more info as needed."
|
||||
{...register("additionalComments")}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<DialogFooter>
|
||||
<Button color="danger" variant="default" onClick={() => setOpen(!open)}>
|
||||
<div className="mt-3">
|
||||
<Button
|
||||
color="danger"
|
||||
variant="default"
|
||||
onClick={closeForm}
|
||||
>
|
||||
Close
|
||||
</Button>
|
||||
<Button color="primary" type="submit">
|
||||
Print
|
||||
</Button>
|
||||
</div>
|
||||
</DialogFooter>
|
||||
</form>
|
||||
</DialogContent>
|
||||
|
||||
@@ -3,7 +3,7 @@ import axios from "axios";
|
||||
|
||||
export const manualPrintLabels = async (lot: LotType, user: any) => {
|
||||
//console.log(lot);
|
||||
const labelUrl = `/ocp/manualPrintAndFollow`;
|
||||
const labelUrl = `/api/ocp/manualprintandfollow`;
|
||||
|
||||
try {
|
||||
const res = await axios.post(
|
||||
@@ -19,7 +19,7 @@ export const manualPrintLabels = async (lot: LotType, user: any) => {
|
||||
};
|
||||
} else {
|
||||
return {
|
||||
success: true,
|
||||
success: false,
|
||||
message: `Line ${lot.MachineDescription} encountered an error printing labels: ${res.data.message}`,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1,5 +1,154 @@
|
||||
import { LstCard } from "@/components/extendedUI/LstCard";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { Skeleton } from "@/components/ui/skeleton";
|
||||
import {
|
||||
Table,
|
||||
TableBody,
|
||||
TableCell,
|
||||
TableHead,
|
||||
TableHeader,
|
||||
TableRow,
|
||||
} from "@/components/ui/table";
|
||||
import { getOcpLogs } from "@/utils/querys/production/ocpLogs";
|
||||
import { useQuery } from "@tanstack/react-query";
|
||||
import axios from "axios";
|
||||
import { format } from "date-fns";
|
||||
import { Trash } from "lucide-react";
|
||||
import { toast } from "sonner";
|
||||
|
||||
const labelLogs = [
|
||||
{ key: "message", label: "Error Message" },
|
||||
{ key: "created_at", label: "ErrorDat" },
|
||||
{ key: "clear", label: "Clear" },
|
||||
//{key: "reprint", label: "Reprint"}, // removing the reprint button for now until repritning is working as intended
|
||||
];
|
||||
|
||||
export default function OcpLogs() {
|
||||
return <LstCard className="m-2 p-2">Ocp Logs</LstCard>;
|
||||
const { data, isError, isLoading } = useQuery(getOcpLogs("4"));
|
||||
|
||||
const clearLog = async (log: any) => {
|
||||
try {
|
||||
const res = await axios.patch(`/api/logger/logs/${log.log_id}`);
|
||||
|
||||
if (res.data.success) {
|
||||
toast.success(`Log message: ${log.message}, was just cleared`);
|
||||
} else {
|
||||
console.log(res);
|
||||
toast.error(`There was an error clearing the message.`);
|
||||
}
|
||||
} catch (error) {
|
||||
toast.error(`There was an error trying to clearing the message.`);
|
||||
}
|
||||
};
|
||||
const logData = data ? data : [];
|
||||
if (isError) {
|
||||
return (
|
||||
<div className="m-2 p-2 min-h-2/5">
|
||||
<LstCard>
|
||||
<p className="text-center">Labels for the last 2 hours</p>
|
||||
<Table>
|
||||
<TableHeader>
|
||||
<TableRow>
|
||||
{labelLogs.map((l) => (
|
||||
<TableHead key={l.key}>{l.label}</TableHead>
|
||||
))}
|
||||
</TableRow>
|
||||
</TableHeader>
|
||||
|
||||
<TableBody>
|
||||
{Array(7)
|
||||
.fill(0)
|
||||
.map((_, i) => (
|
||||
<TableRow key={i}>
|
||||
<TableCell className="font-medium">
|
||||
<Skeleton className="h-4" />
|
||||
</TableCell>
|
||||
<TableCell>
|
||||
<Skeleton className="h-4" />
|
||||
</TableCell>
|
||||
<TableCell>
|
||||
<Skeleton className="h-4" />
|
||||
</TableCell>
|
||||
<TableCell>
|
||||
<Skeleton className="h-4" />
|
||||
</TableCell>
|
||||
<TableCell>
|
||||
<Skeleton className="h-4" />
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
))}
|
||||
</TableBody>
|
||||
</Table>
|
||||
</LstCard>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<LstCard className="m-2 p-2 min-h-2/5">
|
||||
<p className="text-center">Labels for the last 2 hours</p>
|
||||
<Table>
|
||||
<TableHeader>
|
||||
<TableRow>
|
||||
{labelLogs.map((l) => (
|
||||
<TableHead key={l.key}>{l.label}</TableHead>
|
||||
))}
|
||||
</TableRow>
|
||||
</TableHeader>
|
||||
{isLoading ? (
|
||||
<>
|
||||
<TableBody>
|
||||
{Array(7)
|
||||
.fill(0)
|
||||
.map((_, i) => (
|
||||
<TableRow key={i}>
|
||||
<TableCell className="font-medium">
|
||||
<Skeleton className="h-4" />
|
||||
</TableCell>
|
||||
<TableCell>
|
||||
<Skeleton className="h-4" />
|
||||
</TableCell>
|
||||
<TableCell>
|
||||
<Skeleton className="h-4" />
|
||||
</TableCell>
|
||||
<TableCell>
|
||||
<Skeleton className="h-4" />
|
||||
</TableCell>
|
||||
<TableCell>
|
||||
<Skeleton className="h-4" />
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
))}
|
||||
</TableBody>
|
||||
</>
|
||||
) : (
|
||||
<TableBody>
|
||||
{logData.map((label: any) => (
|
||||
<TableRow key={label.log_id}>
|
||||
<TableCell className="font-medium max-w-5/6">
|
||||
<p className="text-balance">
|
||||
{label.message}
|
||||
</p>
|
||||
</TableCell>
|
||||
<TableCell className="font-medium">
|
||||
{format(
|
||||
label?.created_at.replace("Z", ""),
|
||||
"M/d/yyyy hh:mm"
|
||||
)}
|
||||
</TableCell>
|
||||
<TableCell className="font-medium">
|
||||
<Button
|
||||
size="icon"
|
||||
onClick={() => clearLog(label)}
|
||||
>
|
||||
<Trash />
|
||||
</Button>
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
))}
|
||||
</TableBody>
|
||||
)}
|
||||
</Table>
|
||||
</LstCard>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@ import Lots from "./Lots";
|
||||
import OcpLogs from "./OcpLogs";
|
||||
import PrinterStatus from "./PrinterStatus";
|
||||
import { useSettingStore } from "@/lib/store/useSettings";
|
||||
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs";
|
||||
|
||||
export default function OCPPage() {
|
||||
const { settings } = useSettingStore();
|
||||
@@ -17,13 +18,25 @@ export default function OCPPage() {
|
||||
<Lots />
|
||||
</div>
|
||||
|
||||
<div className="flex flex-row">
|
||||
<div className="w-1/2">
|
||||
<LabelLog />
|
||||
</div>
|
||||
<div className="w-1/2">
|
||||
<div className="w-5/6">
|
||||
<Tabs defaultValue="ocplogs" className="w-full">
|
||||
<TabsList className="grid w-full grid-cols-2">
|
||||
<TabsTrigger value="ocplogs">
|
||||
OcpLogs
|
||||
</TabsTrigger>
|
||||
<TabsTrigger value="labels">Labels</TabsTrigger>
|
||||
</TabsList>
|
||||
<TabsContent value="ocplogs">
|
||||
<div className="w-full">
|
||||
<OcpLogs />
|
||||
</div>
|
||||
</TabsContent>
|
||||
<TabsContent value="labels">
|
||||
<div className="w-full">
|
||||
<LabelLog />
|
||||
</div>
|
||||
</TabsContent>
|
||||
</Tabs>
|
||||
</div>
|
||||
</div>
|
||||
<div className="w-1/6 flex flex-col">
|
||||
|
||||
@@ -7,7 +7,7 @@ export function getlabels(hours: string) {
|
||||
queryFn: () => fetchSettings(hours),
|
||||
|
||||
staleTime: 1000,
|
||||
//refetchInterval: 2500,
|
||||
refetchInterval: 2 * 2000,
|
||||
refetchOnWindowFocus: true,
|
||||
});
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@ export function getlots() {
|
||||
queryFn: () => fetchSettings(),
|
||||
|
||||
staleTime: 10 * 1000,
|
||||
//refetchInterval: 10 * 1000,
|
||||
refetchInterval: 10 * 1000,
|
||||
refetchOnWindowFocus: true,
|
||||
});
|
||||
}
|
||||
|
||||
22
frontend/src/utils/querys/production/ocpLogs.tsx
Normal file
22
frontend/src/utils/querys/production/ocpLogs.tsx
Normal file
@@ -0,0 +1,22 @@
|
||||
import { queryOptions } from "@tanstack/react-query";
|
||||
import axios from "axios";
|
||||
|
||||
export function getOcpLogs(hours: string) {
|
||||
return queryOptions({
|
||||
queryKey: ["ocpLogs"],
|
||||
queryFn: () => fetchSettings(hours),
|
||||
|
||||
staleTime: 1000,
|
||||
refetchInterval: 2 * 1000,
|
||||
refetchOnWindowFocus: true,
|
||||
});
|
||||
}
|
||||
|
||||
const fetchSettings = async (hours: string) => {
|
||||
const { data } = await axios.get(
|
||||
`/api/logger/logs?service=ocp&service=rfid&level=error&level=warn&hours=${hours}`
|
||||
);
|
||||
// if we are not localhost ignore the devDir setting.
|
||||
//const url: string = window.location.host.split(":")[0];
|
||||
return data.data ?? [];
|
||||
};
|
||||
Reference in New Issue
Block a user