- refactor: replace Output component with OutputForms and update related hooks and types
This commit is contained in:
@@ -19,7 +19,7 @@ const SystemHealth = ({ startTime, uptime, statuses, isLoading, isError, dateUpd
|
|||||||
if (isLoading) {
|
if (isLoading) {
|
||||||
return <span className="text-slate-500">Loading system health…</span>;
|
return <span className="text-slate-500">Loading system health…</span>;
|
||||||
}
|
}
|
||||||
|
console.log(statuses);
|
||||||
return (
|
return (
|
||||||
<div className="h-100 md:h-75 overflow-y-auto flex flex-col gap-4">
|
<div className="h-100 md:h-75 overflow-y-auto flex flex-col gap-4">
|
||||||
<div className="p-2 border-b border-gray-600 grid grid-cols-2 justify-between">
|
<div className="p-2 border-b border-gray-600 grid grid-cols-2 justify-between">
|
||||||
|
|||||||
@@ -14,7 +14,6 @@ const SystemOverview = () => {
|
|||||||
const isError = query?.isError;
|
const isError = query?.isError;
|
||||||
const dateUpdatedAt = query?.dataUpdatedAt;
|
const dateUpdatedAt = query?.dataUpdatedAt;
|
||||||
|
|
||||||
console.log(query?.dataUpdatedAt);
|
|
||||||
return (
|
return (
|
||||||
<Card className="p-4">
|
<Card className="p-4">
|
||||||
<CardHeader title="System Health" refetch={query?.refetch} icon={faArrowsRotate} />
|
<CardHeader title="System Health" refetch={query?.refetch} icon={faArrowsRotate} />
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
import { Field } from "formik";
|
import { Field, useFormikContext } from "formik";
|
||||||
|
import type { FormTypes } from "../../../types/types";
|
||||||
|
|
||||||
const BearerTypeFields = () => {
|
const BearerTypeFields = () => {
|
||||||
|
useFormikContext<FormTypes>();
|
||||||
return (
|
return (
|
||||||
<div className="flex flex-row justify-between">
|
<div className="flex flex-row justify-between">
|
||||||
<label htmlFor="format" className="text-xl">
|
<label htmlFor="format" className="text-xl">
|
||||||
|
|||||||
@@ -3,12 +3,12 @@ import Card from "../../../ui/Card";
|
|||||||
import CardHeader from "../../../ui/CardHeader";
|
import CardHeader from "../../../ui/CardHeader";
|
||||||
import ChannelFields from "./ChannelFields";
|
import ChannelFields from "./ChannelFields";
|
||||||
import type { FormTypes } from "../../../types/types";
|
import type { FormTypes } from "../../../types/types";
|
||||||
import { useGetOutputs } from "../hooks/useGetOutputs";
|
import { useGetBearerConfig } from "../hooks/useBearer";
|
||||||
|
|
||||||
const ChannelCard = () => {
|
const ChannelCard = () => {
|
||||||
const { values, errors, touched, setFieldValue } = useFormikContext<FormTypes>();
|
const { values, errors, touched, setFieldValue } = useFormikContext<FormTypes>();
|
||||||
const { query } = useGetOutputs(values?.format?.toLowerCase() || "json");
|
const { bearerQuery } = useGetBearerConfig(values?.format?.toLowerCase() || "json");
|
||||||
const outputData = query?.data;
|
const outputData = bearerQuery?.data;
|
||||||
return (
|
return (
|
||||||
<Card className="p-4 h-150 md:h-full">
|
<Card className="p-4 h-150 md:h-full">
|
||||||
<CardHeader title={`Channel (${values?.format})`} />
|
<CardHeader title={`Channel (${values?.format})`} />
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
import { Field } from "formik";
|
import { Field } from "formik";
|
||||||
import type { FormTypes, InitialValuesFormErrors } from "../../../types/types";
|
import type { FormTypes, InitialValuesFormErrors, OutputDataResponse } from "../../../types/types";
|
||||||
import type { UseQueryResult } from "@tanstack/react-query";
|
|
||||||
import { useEffect, useMemo } from "react";
|
import { useEffect, useMemo } from "react";
|
||||||
|
|
||||||
type ChannelFieldsProps = {
|
type ChannelFieldsProps = {
|
||||||
@@ -10,15 +9,15 @@ type ChannelFieldsProps = {
|
|||||||
connectTimeoutSeconds?: boolean | undefined;
|
connectTimeoutSeconds?: boolean | undefined;
|
||||||
readTimeoutSeconds?: boolean | undefined;
|
readTimeoutSeconds?: boolean | undefined;
|
||||||
};
|
};
|
||||||
outputData?: UseQueryResult<FormTypes, Error>;
|
outputData?: OutputDataResponse;
|
||||||
onSetFieldValue: (field: string, value: string, shouldValidate?: boolean | undefined) => void;
|
onSetFieldValue: (field: string, value: string, shouldValidate?: boolean | undefined) => void;
|
||||||
};
|
};
|
||||||
|
|
||||||
const ChannelFields = ({ errors, touched, values, outputData, onSetFieldValue }: ChannelFieldsProps) => {
|
const ChannelFields = ({ errors, touched, values, outputData, onSetFieldValue }: ChannelFieldsProps) => {
|
||||||
const channelFieldsObject = useMemo(() => {
|
const channelFieldsObject = useMemo(() => {
|
||||||
return {
|
return {
|
||||||
connectTimeoutSeconds: outputData?.propConnectTimeoutSeconds?.value || 5,
|
connectTimeoutSeconds: outputData?.propConnectTimeoutSeconds?.value || "5",
|
||||||
readTimeoutSeconds: outputData?.propReadTimeoutSeconds?.value || 15,
|
readTimeoutSeconds: outputData?.propReadTimeoutSeconds?.value || "15",
|
||||||
backOfficeURL: outputData?.propBackofficeURL?.value || "",
|
backOfficeURL: outputData?.propBackofficeURL?.value || "",
|
||||||
username: outputData?.propUsername?.value || "",
|
username: outputData?.propUsername?.value || "",
|
||||||
password: outputData?.propPassword?.value || "",
|
password: outputData?.propPassword?.value || "",
|
||||||
|
|||||||
@@ -1,50 +0,0 @@
|
|||||||
import { Formik, Form } from "formik";
|
|
||||||
import BearerTypeCard from "./BearerTypeCard";
|
|
||||||
import ChannelCard from "./ChannelCard";
|
|
||||||
import type { FormTypes } from "../../../types/types";
|
|
||||||
import { usePostOutputs } from "../hooks/usePostOutputs";
|
|
||||||
|
|
||||||
const Output = () => {
|
|
||||||
const { mutation } = usePostOutputs();
|
|
||||||
const handleSubmit = (values: FormTypes) => {
|
|
||||||
const channelFields = {
|
|
||||||
backOfficeURL: values.backOfficeURL,
|
|
||||||
username: values.username,
|
|
||||||
password: values.password,
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
const inititalValues: FormTypes = {
|
|
||||||
format: "JSON",
|
|
||||||
enabled: true,
|
|
||||||
backOfficeURL: "",
|
|
||||||
username: "",
|
|
||||||
password: "",
|
|
||||||
connectTimeoutSeconds: Number(5),
|
|
||||||
readTimeoutSeconds: Number(15),
|
|
||||||
overviewQuality: "HIGH",
|
|
||||||
cropSizeFactor: "3/4",
|
|
||||||
|
|
||||||
// Bof2 -optional constants
|
|
||||||
FFID: "",
|
|
||||||
SCID: "",
|
|
||||||
timestampSource: "UTC",
|
|
||||||
GPSFormat: "Minutes",
|
|
||||||
|
|
||||||
//BOF2 - optional Lane IDs
|
|
||||||
laneId: "",
|
|
||||||
LID1: "",
|
|
||||||
LID2: "",
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
|
||||||
<Formik initialValues={inititalValues} onSubmit={handleSubmit} enableReinitialize>
|
|
||||||
<Form className="grid grid-cols-1 md:grid-cols-2">
|
|
||||||
<BearerTypeCard />
|
|
||||||
<ChannelCard />
|
|
||||||
</Form>
|
|
||||||
</Formik>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default Output;
|
|
||||||
81
src/features/output/components/OutputForms.tsx
Normal file
81
src/features/output/components/OutputForms.tsx
Normal file
@@ -0,0 +1,81 @@
|
|||||||
|
import { Formik, Form } from "formik";
|
||||||
|
import BearerTypeCard from "./BearerTypeCard";
|
||||||
|
import ChannelCard from "./ChannelCard";
|
||||||
|
import type { BearerTypeFields, FormTypes, OptionalBOF2Constants } from "../../../types/types";
|
||||||
|
import { usePostBearerConfig } from "../hooks/useBearer";
|
||||||
|
import { useDispatcherConfig } from "../hooks/useDispatcherConfig";
|
||||||
|
|
||||||
|
const OutputForms = () => {
|
||||||
|
const { bearerMutation } = usePostBearerConfig();
|
||||||
|
const { dispatcherQuery, dispatcherMutation } = useDispatcherConfig();
|
||||||
|
|
||||||
|
const format = dispatcherQuery?.data?.propFormat?.value;
|
||||||
|
|
||||||
|
const inititalValues: FormTypes = {
|
||||||
|
format: format ?? "JSON",
|
||||||
|
enabled: true,
|
||||||
|
backOfficeURL: "",
|
||||||
|
username: "",
|
||||||
|
password: "",
|
||||||
|
connectTimeoutSeconds: Number(5),
|
||||||
|
readTimeoutSeconds: Number(15),
|
||||||
|
overviewQuality: "HIGH",
|
||||||
|
cropSizeFactor: "3/4",
|
||||||
|
|
||||||
|
// Bof2 -optional constants
|
||||||
|
FFID: "",
|
||||||
|
SCID: "",
|
||||||
|
timestampSource: "UTC",
|
||||||
|
GPSFormat: "Minutes",
|
||||||
|
|
||||||
|
//BOF2 - optional Lane IDs
|
||||||
|
laneId: "",
|
||||||
|
LID1: "",
|
||||||
|
LID2: "",
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleSubmit = async (values: FormTypes) => {
|
||||||
|
const bearerTypeFields = {
|
||||||
|
format: values.format,
|
||||||
|
enabled: values.enabled,
|
||||||
|
};
|
||||||
|
|
||||||
|
const bearerFields: BearerTypeFields = {
|
||||||
|
format: values.format,
|
||||||
|
enabled: values.enabled,
|
||||||
|
backOfficeURL: values.backOfficeURL,
|
||||||
|
username: values.username,
|
||||||
|
password: values.password,
|
||||||
|
connectTimeoutSeconds: values.connectTimeoutSeconds,
|
||||||
|
readTimeoutSeconds: values.readTimeoutSeconds,
|
||||||
|
overviewQuality: values.overviewQuality,
|
||||||
|
cropSizeFactor: values.cropSizeFactor,
|
||||||
|
};
|
||||||
|
|
||||||
|
const result = await dispatcherMutation.mutateAsync(bearerTypeFields);
|
||||||
|
|
||||||
|
if (result?.id) {
|
||||||
|
await bearerMutation.mutateAsync(bearerFields);
|
||||||
|
if (values.format === "BOF2") {
|
||||||
|
const optionalBOF2Fields: OptionalBOF2Constants = {
|
||||||
|
FFID: values.FFID,
|
||||||
|
SCID: values.SCID,
|
||||||
|
timestampSource: values.timestampSource,
|
||||||
|
GPSFormat: values.GPSFormat,
|
||||||
|
};
|
||||||
|
console.log("Submit BOF2 optional fields:", optionalBOF2Fields);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Formik initialValues={inititalValues} onSubmit={handleSubmit} enableReinitialize>
|
||||||
|
<Form className="grid grid-cols-1 md:grid-cols-2">
|
||||||
|
<BearerTypeCard />
|
||||||
|
<ChannelCard />
|
||||||
|
</Form>
|
||||||
|
</Formik>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default OutputForms;
|
||||||
65
src/features/output/hooks/useBearer.ts
Normal file
65
src/features/output/hooks/useBearer.ts
Normal file
@@ -0,0 +1,65 @@
|
|||||||
|
import { useMutation, useQuery } from "@tanstack/react-query";
|
||||||
|
import type { BearerTypeFields } from "../../../types/types";
|
||||||
|
|
||||||
|
const fetchBearerConfig = async (bearerConfig: string) => {
|
||||||
|
const response = await fetch(`http://100.115.148.59/api/fetch-config?id=Dispatcher0-${bearerConfig}`, {
|
||||||
|
method: "GET",
|
||||||
|
});
|
||||||
|
if (!response.ok) {
|
||||||
|
throw new Error("Network response was not ok");
|
||||||
|
}
|
||||||
|
return response.json();
|
||||||
|
};
|
||||||
|
|
||||||
|
const postBearerConfig = async (config: BearerTypeFields) => {
|
||||||
|
const channelConfigPayload = {
|
||||||
|
id: `Dispatcher0-${config.format.toLowerCase()}`,
|
||||||
|
fields: [
|
||||||
|
{
|
||||||
|
property: "propBackofficeURL",
|
||||||
|
value: config.backOfficeURL,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
property: "propConnectTimeoutSeconds",
|
||||||
|
value: config.connectTimeoutSeconds,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
property: "propPassword",
|
||||||
|
value: config.password,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
property: "propReadTimeoutSeconds",
|
||||||
|
value: config.readTimeoutSeconds,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
property: "propUsername",
|
||||||
|
value: config.username,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
};
|
||||||
|
const response = await fetch("http://192.168.202.121/api/update-config", {
|
||||||
|
method: "POST",
|
||||||
|
body: JSON.stringify(channelConfigPayload),
|
||||||
|
});
|
||||||
|
if (!response.ok) {
|
||||||
|
throw new Error("Network response was not ok");
|
||||||
|
}
|
||||||
|
return response.json();
|
||||||
|
};
|
||||||
|
|
||||||
|
export const usePostBearerConfig = () => {
|
||||||
|
const bearerMutation = useMutation({
|
||||||
|
mutationFn: (query: BearerTypeFields) => postBearerConfig(query),
|
||||||
|
mutationKey: ["outputs"],
|
||||||
|
});
|
||||||
|
return { bearerMutation };
|
||||||
|
};
|
||||||
|
|
||||||
|
export const useGetBearerConfig = (bearerConfig: string) => {
|
||||||
|
const bearerQuery = useQuery({
|
||||||
|
queryKey: ["outputs", bearerConfig],
|
||||||
|
queryFn: () => fetchBearerConfig(bearerConfig),
|
||||||
|
});
|
||||||
|
|
||||||
|
return { bearerQuery };
|
||||||
|
};
|
||||||
47
src/features/output/hooks/useDispatcherConfig.ts
Normal file
47
src/features/output/hooks/useDispatcherConfig.ts
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
import { useQuery, useMutation } from "@tanstack/react-query";
|
||||||
|
import type { DispatcherConfig } from "../../../types/types";
|
||||||
|
|
||||||
|
const getDispatcherConfig = async () => {
|
||||||
|
const response = await fetch(`http://192.168.202.121/api/fetch-config?id=Dispatcher0`);
|
||||||
|
if (!response.ok) {
|
||||||
|
throw new Error("Network response was not ok");
|
||||||
|
}
|
||||||
|
return response.json();
|
||||||
|
};
|
||||||
|
|
||||||
|
const postDispatcherConfig = async (config: DispatcherConfig) => {
|
||||||
|
const updateConfigPayload = {
|
||||||
|
id: "Dispatcher0",
|
||||||
|
fields: [
|
||||||
|
{
|
||||||
|
property: "propEnabled",
|
||||||
|
value: config.enabled,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
property: "propFormat",
|
||||||
|
value: config.format,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
};
|
||||||
|
const response = await fetch(`http://192.168.202.121/api/update-config`, {
|
||||||
|
method: "POST",
|
||||||
|
body: JSON.stringify(updateConfigPayload),
|
||||||
|
});
|
||||||
|
if (!response.ok) {
|
||||||
|
throw new Error("Network response was not ok");
|
||||||
|
}
|
||||||
|
return response.json();
|
||||||
|
};
|
||||||
|
|
||||||
|
export const useDispatcherConfig = () => {
|
||||||
|
const dispatcherQuery = useQuery({
|
||||||
|
queryKey: ["dispatcherConfig"],
|
||||||
|
queryFn: () => getDispatcherConfig(),
|
||||||
|
});
|
||||||
|
|
||||||
|
const dispatcherMutation = useMutation({
|
||||||
|
mutationKey: ["postDispatcherConfig"],
|
||||||
|
mutationFn: (config: DispatcherConfig) => postDispatcherConfig(config),
|
||||||
|
});
|
||||||
|
return { dispatcherQuery, dispatcherMutation };
|
||||||
|
};
|
||||||
@@ -1,20 +0,0 @@
|
|||||||
import { useQuery } from "@tanstack/react-query";
|
|
||||||
|
|
||||||
const fetchOutputs = async (format: string) => {
|
|
||||||
const response = await fetch(`http://100.115.148.59/api/fetch-config?id=Dispatcher0-${format}`, {
|
|
||||||
method: "GET",
|
|
||||||
});
|
|
||||||
if (!response.ok) {
|
|
||||||
throw new Error("Network response was not ok");
|
|
||||||
}
|
|
||||||
return response.json();
|
|
||||||
};
|
|
||||||
|
|
||||||
export const useGetOutputs = (format: string) => {
|
|
||||||
const query = useQuery({
|
|
||||||
queryKey: ["outputs", format],
|
|
||||||
queryFn: () => fetchOutputs(format),
|
|
||||||
});
|
|
||||||
|
|
||||||
return { query };
|
|
||||||
};
|
|
||||||
0
src/features/output/hooks/useOptionalConstants.tsx
Normal file
0
src/features/output/hooks/useOptionalConstants.tsx
Normal file
@@ -1,21 +0,0 @@
|
|||||||
import { useMutation } from "@tanstack/react-query";
|
|
||||||
import type { BearerTypeFields } from "../../../types/types";
|
|
||||||
|
|
||||||
const postQuery = async (query: BearerTypeFields) => {
|
|
||||||
const response = await fetch("/api/outputs", {
|
|
||||||
method: "POST",
|
|
||||||
body: JSON.stringify({ query }),
|
|
||||||
});
|
|
||||||
if (!response.ok) {
|
|
||||||
throw new Error("Network response was not ok");
|
|
||||||
}
|
|
||||||
return response.json();
|
|
||||||
};
|
|
||||||
|
|
||||||
export const usePostOutputs = () => {
|
|
||||||
const mutation = useMutation({
|
|
||||||
mutationFn: (query: BearerTypeFields) => postQuery(query),
|
|
||||||
mutationKey: ["outputs"],
|
|
||||||
});
|
|
||||||
return { mutation };
|
|
||||||
};
|
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
import { createFileRoute } from "@tanstack/react-router";
|
import { createFileRoute } from "@tanstack/react-router";
|
||||||
import Output from "../features/output/components/Output";
|
import OutputForms from "../features/output/components/OutputForms";
|
||||||
|
|
||||||
export const Route = createFileRoute("/output")({
|
export const Route = createFileRoute("/output")({
|
||||||
component: RouteComponent,
|
component: RouteComponent,
|
||||||
@@ -8,7 +8,7 @@ export const Route = createFileRoute("/output")({
|
|||||||
function RouteComponent() {
|
function RouteComponent() {
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<Output />
|
<OutputForms />
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -57,7 +57,33 @@ export type InitialValuesFormErrors = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export type FormTypes = BearerTypeFields & OptionalConstants & OptionalLaneIDs;
|
export type FormTypes = BearerTypeFields & OptionalConstants & OptionalLaneIDs;
|
||||||
|
type FieldProperty = {
|
||||||
|
datatype: string;
|
||||||
|
value: string;
|
||||||
|
};
|
||||||
|
export type OutputDataResponse = {
|
||||||
|
id: string;
|
||||||
|
configHash: string;
|
||||||
|
} & Record<string, FieldProperty>;
|
||||||
|
|
||||||
export type PaintedCell = {
|
export type PaintedCell = {
|
||||||
colour: string;
|
colour: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export type DispatcherConfig = {
|
||||||
|
format: string;
|
||||||
|
enabled: boolean;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type OptionalBOF2Constants = {
|
||||||
|
FFID?: string;
|
||||||
|
SCID?: string;
|
||||||
|
timestampSource?: string;
|
||||||
|
GPSFormat?: string;
|
||||||
|
};
|
||||||
|
export type OptionalBOF2LaneIDs = {
|
||||||
|
laneId?: string;
|
||||||
|
LID1?: string;
|
||||||
|
LID2?: string;
|
||||||
|
LID3?: string;
|
||||||
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user