feat(settings): final migration of settings and edits added
This commit is contained in:
20
LogisticsSupportTool_API_DOCS/app/system/Update Setting.bru
Normal file
20
LogisticsSupportTool_API_DOCS/app/system/Update Setting.bru
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
meta {
|
||||||
|
name: Update Setting
|
||||||
|
type: http
|
||||||
|
seq: 4
|
||||||
|
}
|
||||||
|
|
||||||
|
post {
|
||||||
|
url: {{url}}/lst/api/system/settings/:token
|
||||||
|
body: none
|
||||||
|
auth: inherit
|
||||||
|
}
|
||||||
|
|
||||||
|
params:path {
|
||||||
|
token:
|
||||||
|
}
|
||||||
|
|
||||||
|
settings {
|
||||||
|
encodeUrl: true
|
||||||
|
timeout: 0
|
||||||
|
}
|
||||||
@@ -219,9 +219,9 @@ const main = async () => {
|
|||||||
addListeners();
|
addListeners();
|
||||||
//userMigrate();
|
//userMigrate();
|
||||||
// some temp fixes
|
// some temp fixes
|
||||||
// above 230 remove these
|
// above 235 remove these
|
||||||
manualFixes();
|
manualFixes();
|
||||||
settingsMigrate();
|
//settingsMigrate();
|
||||||
}, 5 * 1000);
|
}, 5 * 1000);
|
||||||
|
|
||||||
// setTimeout(() => {
|
// setTimeout(() => {
|
||||||
|
|||||||
@@ -5,66 +5,31 @@ import { Router } from "express";
|
|||||||
import https from "https";
|
import https from "https";
|
||||||
import { db } from "../../../../pkg/db/db.js";
|
import { db } from "../../../../pkg/db/db.js";
|
||||||
import { serverData } from "../../../../pkg/db/schema/servers.js";
|
import { serverData } from "../../../../pkg/db/schema/servers.js";
|
||||||
|
import { settings } from "../../../../pkg/db/schema/settings.js";
|
||||||
import { createLogger } from "../../../../pkg/logger/logger.js";
|
import { createLogger } from "../../../../pkg/logger/logger.js";
|
||||||
import { tryCatch } from "../../../../pkg/utils/tryCatch.js";
|
import { tryCatch } from "../../../../pkg/utils/tryCatch.js";
|
||||||
|
|
||||||
const router = Router();
|
const router = Router();
|
||||||
|
|
||||||
router.patch("/:token", async (req: Request, res: Response) => {
|
router.patch("/:id", async (req: Request, res: Response) => {
|
||||||
const log = createLogger({ module: "admin", subModule: "update server" });
|
const log = createLogger({ module: "admin", subModule: "update setting" });
|
||||||
|
|
||||||
// when a server is updated and is posted from localhost or 127.0.0.1 we also want to post it to the test server so we can see it from there, we want to insert with update on conflict.
|
// when a server is updated and is posted from localhost or 127.0.0.1 we also want to post it to the test server so we can see it from there, we want to insert with update on conflict.
|
||||||
const token = req.params.token;
|
const id = req.params.id;
|
||||||
const updates: Record<string, any> = {};
|
const updates: Record<string, any> = {};
|
||||||
|
|
||||||
if (req.body?.name !== undefined) {
|
if (req.body?.name !== undefined) {
|
||||||
updates.name = req.body.name;
|
updates.name = req.body.name;
|
||||||
}
|
}
|
||||||
if (req.body?.serverDNS !== undefined) {
|
if (req.body?.value !== undefined) {
|
||||||
updates.serverDNS = req.body.serverDNS;
|
updates.value = req.body.value;
|
||||||
}
|
}
|
||||||
if (req.body?.ipAddress !== undefined) {
|
if (req.body?.description !== undefined) {
|
||||||
updates.ipAddress = req.body.ipAddress;
|
updates.description = req.body.description;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (req.body?.greatPlainsPlantCode !== undefined) {
|
if (req.body?.moduleName !== undefined) {
|
||||||
updates.greatPlainsPlantCode = req.body.greatPlainsPlantCode;
|
updates.moduleName = req.body.moduleName;
|
||||||
}
|
|
||||||
|
|
||||||
if (req.body?.lstServerPort !== undefined) {
|
|
||||||
updates.lstServerPort = req.body.lstServerPort;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (req.body?.serverLoc !== undefined) {
|
|
||||||
updates.serverLoc = req.body.serverLoc;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (req.body?.streetAddress !== undefined) {
|
|
||||||
updates.streetAddress = req.body.streetAddress;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (req.body?.cityState !== undefined) {
|
|
||||||
updates.cityState = req.body.cityState;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (req.body?.zipcode !== undefined) {
|
|
||||||
updates.zipcode = req.body.zipcode;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (req.body?.contactEmail !== undefined) {
|
|
||||||
updates.contactEmail = req.body.contactEmail;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (req.body?.contactPhone !== undefined) {
|
|
||||||
updates.contactPhone = req.body.contactPhone;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (req.body?.customerTiAcc !== undefined) {
|
|
||||||
updates.customerTiAcc = req.body.customerTiAcc;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (req.body?.active !== undefined) {
|
|
||||||
updates.active = req.body.active;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
updates.upd_user = req.user!.username || "lst_user";
|
updates.upd_user = req.user!.username || "lst_user";
|
||||||
@@ -73,65 +38,12 @@ router.patch("/:token", async (req: Request, res: Response) => {
|
|||||||
try {
|
try {
|
||||||
if (Object.keys(updates).length > 0) {
|
if (Object.keys(updates).length > 0) {
|
||||||
await db
|
await db
|
||||||
.update(serverData)
|
.update(settings)
|
||||||
.set(updates)
|
.set(updates)
|
||||||
.where(eq(serverData.plantToken, token));
|
.where(eq(settings.settings_id, id));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (req.hostname === "localhost" && process.env.MAIN_SERVER) {
|
res.status(200).json({ message: `Setting was just updated` });
|
||||||
log.info({}, "Running in dev server about to add in a new server");
|
|
||||||
const axiosInstance = axios.create({
|
|
||||||
httpsAgent: new https.Agent({ rejectUnauthorized: false }),
|
|
||||||
baseURL: process.env.MAIN_SERVER,
|
|
||||||
withCredentials: true,
|
|
||||||
});
|
|
||||||
|
|
||||||
const loginRes = (await axiosInstance.post(
|
|
||||||
`${process.env.MAIN_SERVER}/lst/api/auth/sign-in/username`,
|
|
||||||
{
|
|
||||||
username: process.env.MAIN_SERVER_USERNAME,
|
|
||||||
password: process.env.MAIN_SERVER_PASSWORD,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
headers: { "Content-Type": "application/json" },
|
|
||||||
},
|
|
||||||
)) as any;
|
|
||||||
|
|
||||||
const setCookie = loginRes?.headers["set-cookie"][0];
|
|
||||||
|
|
||||||
//console.log(setCookie.split(";")[0].replace("__Secure-", ""));
|
|
||||||
|
|
||||||
if (!setCookie) {
|
|
||||||
throw new Error("Did not receive a Set-Cookie header from login");
|
|
||||||
}
|
|
||||||
|
|
||||||
const { data, error } = await tryCatch(
|
|
||||||
axios.patch(
|
|
||||||
`${process.env.MAIN_SERVER}/lst/api/admin/server/${token}`,
|
|
||||||
updates,
|
|
||||||
{
|
|
||||||
headers: {
|
|
||||||
"Content-Type": "application/json",
|
|
||||||
Cookie: setCookie.split(";")[0],
|
|
||||||
},
|
|
||||||
withCredentials: true,
|
|
||||||
},
|
|
||||||
),
|
|
||||||
);
|
|
||||||
|
|
||||||
if (error) {
|
|
||||||
console.log(error);
|
|
||||||
log.error(
|
|
||||||
{ stack: error },
|
|
||||||
"There was an error adding the server to Main Server",
|
|
||||||
);
|
|
||||||
}
|
|
||||||
log.info(
|
|
||||||
{ stack: data?.data },
|
|
||||||
"A new Server was just added to the server.",
|
|
||||||
);
|
|
||||||
}
|
|
||||||
res.status(200).json({ message: `${token} Server was just updated` });
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.log(error);
|
console.log(error);
|
||||||
res.status(400).json({ message: "Error Server updated", error });
|
res.status(400).json({ message: "Error Server updated", error });
|
||||||
|
|||||||
@@ -65,8 +65,6 @@ export const addListeners = async () => {
|
|||||||
|
|
||||||
// all the migration stuff that will need to be moved later build 230 and above will need to remove
|
// all the migration stuff that will need to be moved later build 230 and above will need to remove
|
||||||
export const manualFixes = async () => {
|
export const manualFixes = async () => {
|
||||||
const fixQuery = `ALTER TABLE "serverData" ADD CONSTRAINT "serverData_name_unique" UNIQUE("name");`;
|
|
||||||
|
|
||||||
const log = createLogger({ module: "utils", subModule: "manual fixes" });
|
const log = createLogger({ module: "utils", subModule: "manual fixes" });
|
||||||
const client = new Client({
|
const client = new Client({
|
||||||
connectionString: `postgresql://${process.env.DATABASE_USER}:${process.env.DATABASE_PASSWORD}@${process.env.DATABASE_HOST}:${process.env.DATABASE_PORT}/${process.env.DATABASE_DB}`,
|
connectionString: `postgresql://${process.env.DATABASE_USER}:${process.env.DATABASE_PASSWORD}@${process.env.DATABASE_HOST}:${process.env.DATABASE_PORT}/${process.env.DATABASE_DB}`,
|
||||||
@@ -74,12 +72,16 @@ export const manualFixes = async () => {
|
|||||||
|
|
||||||
await client.connect();
|
await client.connect();
|
||||||
|
|
||||||
try {
|
/**
|
||||||
log.info({}, "Running the manual fix");
|
* The fix to correct the constraint on the server data
|
||||||
await client.query(fixQuery);
|
*/
|
||||||
} catch (e) {
|
// const fixQuery = `ALTER TABLE "serverData" ADD CONSTRAINT "serverData_name_unique" UNIQUE("name");`;
|
||||||
log.info({ error: e }, "Fix was not completed");
|
// try {
|
||||||
}
|
// log.info({}, "Running the manual fix");
|
||||||
|
// await client.query(fixQuery);
|
||||||
|
// } catch (e) {
|
||||||
|
// log.info({ error: e }, "Fix was not completed");
|
||||||
|
// }
|
||||||
};
|
};
|
||||||
|
|
||||||
export const settingsMigrate = async () => {
|
export const settingsMigrate = async () => {
|
||||||
|
|||||||
18
frontend/src/lib/querys/admin/getSettings.ts
Normal file
18
frontend/src/lib/querys/admin/getSettings.ts
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
import { keepPreviousData, queryOptions } from "@tanstack/react-query";
|
||||||
|
import axios from "axios";
|
||||||
|
|
||||||
|
export function getSettings() {
|
||||||
|
return queryOptions({
|
||||||
|
queryKey: ["getSettings"],
|
||||||
|
queryFn: () => fetchSession(),
|
||||||
|
staleTime: 5000,
|
||||||
|
refetchOnWindowFocus: true,
|
||||||
|
placeholderData: keepPreviousData,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
const fetchSession = async () => {
|
||||||
|
const { data } = await axios.get("/lst/api/system/settings");
|
||||||
|
|
||||||
|
return data.data;
|
||||||
|
};
|
||||||
26
frontend/src/lib/tableStuff/GenericColumn.tsx
Normal file
26
frontend/src/lib/tableStuff/GenericColumn.tsx
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
import { createColumnHelper } from "@tanstack/react-table";
|
||||||
|
import { ArrowDown, ArrowUp } from "lucide-react";
|
||||||
|
import { Button } from "@/components/ui/button";
|
||||||
|
|
||||||
|
export const GenericColumn = ({ columnName }: { columnName: string }) => {
|
||||||
|
const columnHelper = createColumnHelper();
|
||||||
|
|
||||||
|
return columnHelper.accessor(`${columnName}`, {
|
||||||
|
header: ({ column }) => {
|
||||||
|
return (
|
||||||
|
<Button
|
||||||
|
variant="ghost"
|
||||||
|
onClick={() => column.toggleSorting(column.getIsSorted() === "asc")}
|
||||||
|
>
|
||||||
|
<span className="flex flex-row gap-2">{`${columnName.toUpperCase()}`}</span>
|
||||||
|
{column.getIsSorted() === "asc" ? (
|
||||||
|
<ArrowUp className="ml-2 h-4 w-4" />
|
||||||
|
) : (
|
||||||
|
<ArrowDown className="ml-2 h-4 w-4" />
|
||||||
|
)}
|
||||||
|
</Button>
|
||||||
|
);
|
||||||
|
},
|
||||||
|
cell: (i) => i.getValue(),
|
||||||
|
});
|
||||||
|
};
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
import {
|
import {
|
||||||
flexRender,
|
flexRender,
|
||||||
getCoreRowModel,
|
getCoreRowModel,
|
||||||
|
getFilteredRowModel,
|
||||||
getPaginationRowModel,
|
getPaginationRowModel,
|
||||||
getSortedRowModel,
|
getSortedRowModel,
|
||||||
type SortingState,
|
type SortingState,
|
||||||
@@ -26,6 +27,9 @@ export default function TableNoExpand({
|
|||||||
columns: any;
|
columns: any;
|
||||||
}) {
|
}) {
|
||||||
const [sorting, setSorting] = useState<SortingState>([]);
|
const [sorting, setSorting] = useState<SortingState>([]);
|
||||||
|
// const [columnFilters, setColumnFilters] = React.useState<ColumnFiltersState>(
|
||||||
|
// []
|
||||||
|
// )
|
||||||
const table = useReactTable({
|
const table = useReactTable({
|
||||||
data,
|
data,
|
||||||
columns,
|
columns,
|
||||||
@@ -33,11 +37,14 @@ export default function TableNoExpand({
|
|||||||
getPaginationRowModel: getPaginationRowModel(),
|
getPaginationRowModel: getPaginationRowModel(),
|
||||||
onSortingChange: setSorting,
|
onSortingChange: setSorting,
|
||||||
getSortedRowModel: getSortedRowModel(),
|
getSortedRowModel: getSortedRowModel(),
|
||||||
|
getFilteredRowModel: getFilteredRowModel(),
|
||||||
|
|
||||||
//renderSubComponent: ({ row }: { row: any }) => <ExpandedRow row={row} />,
|
//renderSubComponent: ({ row }: { row: any }) => <ExpandedRow row={row} />,
|
||||||
//getRowCanExpand: () => true,
|
//getRowCanExpand: () => true,
|
||||||
|
filterFns: {},
|
||||||
state: {
|
state: {
|
||||||
sorting,
|
sorting,
|
||||||
|
//columnFilters
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
return (
|
return (
|
||||||
|
|||||||
@@ -1,7 +1,31 @@
|
|||||||
import { createFileRoute, Link, Outlet } from "@tanstack/react-router";
|
import {
|
||||||
|
createFileRoute,
|
||||||
|
Link,
|
||||||
|
Outlet,
|
||||||
|
redirect,
|
||||||
|
} from "@tanstack/react-router";
|
||||||
|
import { checkUserAccess } from "@/lib/authClient";
|
||||||
|
|
||||||
export const Route = createFileRoute("/_app/_adminLayout/admin/_system")({
|
export const Route = createFileRoute("/_app/_adminLayout/admin/_system")({
|
||||||
component: RouteComponent,
|
component: RouteComponent,
|
||||||
|
beforeLoad: async () => {
|
||||||
|
const auth = await checkUserAccess({
|
||||||
|
allowedRoles: ["systemAdmin", "admin"],
|
||||||
|
moduleName: "system", // optional
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!auth) {
|
||||||
|
throw redirect({
|
||||||
|
to: "/login",
|
||||||
|
search: {
|
||||||
|
// Use the current location to power a redirect after login
|
||||||
|
// (Do not use `router.state.resolvedLocation` as it can
|
||||||
|
// potentially lag behind the actual current location)
|
||||||
|
redirect: location.pathname + location.search,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
function RouteComponent() {
|
function RouteComponent() {
|
||||||
|
|||||||
@@ -1,11 +1,230 @@
|
|||||||
import { createFileRoute } from '@tanstack/react-router'
|
import { useMutation, useQuery } from "@tanstack/react-query";
|
||||||
|
import { createFileRoute } from "@tanstack/react-router";
|
||||||
|
import { createColumnHelper } from "@tanstack/react-table";
|
||||||
|
import axios from "axios";
|
||||||
|
import { ArrowDown, ArrowUp } from "lucide-react";
|
||||||
|
import { useEffect, useRef, useState } from "react";
|
||||||
|
import { toast } from "sonner";
|
||||||
|
import { Button } from "@/components/ui/button";
|
||||||
|
import { Input } from "@/components/ui/input";
|
||||||
|
import { getSettings } from "@/lib/querys/admin/getSettings";
|
||||||
|
import TableNoExpand from "@/lib/tableStuff/TableNoExpand";
|
||||||
|
|
||||||
|
type Settings = {
|
||||||
|
settings_id: string;
|
||||||
|
name: string;
|
||||||
|
active: boolean;
|
||||||
|
value: string;
|
||||||
|
description: string;
|
||||||
|
moduleName: string;
|
||||||
|
roles: string[];
|
||||||
|
};
|
||||||
|
|
||||||
|
const updateSettings = async (
|
||||||
|
id: string,
|
||||||
|
data: Record<string, string | number | boolean | null>,
|
||||||
|
) => {
|
||||||
|
console.log(id, data);
|
||||||
|
try {
|
||||||
|
const res = await axios.patch(`/lst/api/system/settings/${id}`, data, {
|
||||||
|
withCredentials: true,
|
||||||
|
});
|
||||||
|
toast.success(`Setting just updated`);
|
||||||
|
return res;
|
||||||
|
} catch (err) {
|
||||||
|
toast.error("Error in updating the settings");
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
export const Route = createFileRoute(
|
export const Route = createFileRoute(
|
||||||
'/_app/_adminLayout/admin/_system/settings',
|
"/_app/_adminLayout/admin/_system/settings",
|
||||||
)({
|
)({
|
||||||
component: RouteComponent,
|
component: RouteComponent,
|
||||||
})
|
});
|
||||||
|
|
||||||
function RouteComponent() {
|
function RouteComponent() {
|
||||||
return <div>Hello "/_app/_adminLayout/admin/_system/settings"!</div>
|
const { data, isLoading, refetch } = useQuery(getSettings());
|
||||||
|
const columnHelper = createColumnHelper<Settings>();
|
||||||
|
const submitting = useRef(false);
|
||||||
|
|
||||||
|
const updateSetting = useMutation({
|
||||||
|
mutationFn: ({
|
||||||
|
id,
|
||||||
|
field,
|
||||||
|
value,
|
||||||
|
}: {
|
||||||
|
id: string;
|
||||||
|
field: string;
|
||||||
|
value: string | number | boolean | null;
|
||||||
|
}) => updateSettings(id, { [field]: value }),
|
||||||
|
|
||||||
|
onSuccess: () => {
|
||||||
|
// refetch or update cache
|
||||||
|
refetch();
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const columns = [
|
||||||
|
columnHelper.accessor("name", {
|
||||||
|
header: ({ column }) => {
|
||||||
|
return (
|
||||||
|
<Button
|
||||||
|
variant="ghost"
|
||||||
|
onClick={() => column.toggleSorting(column.getIsSorted() === "asc")}
|
||||||
|
>
|
||||||
|
<span className="flex flex-row gap-2">Name</span>
|
||||||
|
{column.getIsSorted() === "asc" ? (
|
||||||
|
<ArrowUp className="ml-2 h-4 w-4" />
|
||||||
|
) : (
|
||||||
|
<ArrowDown className="ml-2 h-4 w-4" />
|
||||||
|
)}
|
||||||
|
</Button>
|
||||||
|
);
|
||||||
|
},
|
||||||
|
cell: (i) => i.getValue(),
|
||||||
|
}),
|
||||||
|
columnHelper.accessor("description", {
|
||||||
|
header: ({ column }) => {
|
||||||
|
return (
|
||||||
|
<Button
|
||||||
|
variant="ghost"
|
||||||
|
onClick={() => column.toggleSorting(column.getIsSorted() === "asc")}
|
||||||
|
>
|
||||||
|
<span className="flex flex-row gap-2">Description</span>
|
||||||
|
{column.getIsSorted() === "asc" ? (
|
||||||
|
<ArrowUp className="ml-2 h-4 w-4" />
|
||||||
|
) : (
|
||||||
|
<ArrowDown className="ml-2 h-4 w-4" />
|
||||||
|
)}
|
||||||
|
</Button>
|
||||||
|
);
|
||||||
|
},
|
||||||
|
cell: (i) => i.getValue(),
|
||||||
|
}),
|
||||||
|
columnHelper.accessor("value", {
|
||||||
|
header: ({ column }) => {
|
||||||
|
return (
|
||||||
|
<Button
|
||||||
|
variant="ghost"
|
||||||
|
onClick={() => column.toggleSorting(column.getIsSorted() === "asc")}
|
||||||
|
>
|
||||||
|
<span className="flex flex-row gap-2">Value</span>
|
||||||
|
{column.getIsSorted() === "asc" ? (
|
||||||
|
<ArrowUp className="ml-2 h-4 w-4" />
|
||||||
|
) : (
|
||||||
|
<ArrowDown className="ml-2 h-4 w-4" />
|
||||||
|
)}
|
||||||
|
</Button>
|
||||||
|
);
|
||||||
|
},
|
||||||
|
cell: ({ row, getValue }) => {
|
||||||
|
const initialValue = String(getValue() ?? "");
|
||||||
|
const [localValue, setLocalValue] = useState(initialValue);
|
||||||
|
|
||||||
|
const id = row.original.settings_id;
|
||||||
|
const field = "value";
|
||||||
|
|
||||||
|
useEffect(() => setLocalValue(initialValue), [initialValue]);
|
||||||
|
|
||||||
|
const handleSubmit = (newValue: string) => {
|
||||||
|
if (newValue !== initialValue) {
|
||||||
|
setLocalValue(newValue);
|
||||||
|
updateSetting.mutate({ id, field, value: newValue });
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Input
|
||||||
|
value={localValue}
|
||||||
|
onChange={(e) => setLocalValue(e.currentTarget.value)}
|
||||||
|
onBlur={(e) => {
|
||||||
|
if (!submitting.current) {
|
||||||
|
submitting.current = true;
|
||||||
|
handleSubmit(e.currentTarget.value.trim());
|
||||||
|
setTimeout(() => (submitting.current = false), 100); // reset after slight delay
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
onKeyDown={(e) => {
|
||||||
|
if (e.key === "Enter") {
|
||||||
|
e.preventDefault();
|
||||||
|
submitting.current = true;
|
||||||
|
handleSubmit(e.currentTarget.value.trim());
|
||||||
|
e.currentTarget.blur(); // will trigger blur, but we ignore it
|
||||||
|
setTimeout(() => (submitting.current = false), 100);
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
columnHelper.accessor("moduleName", {
|
||||||
|
header: ({ column }) => {
|
||||||
|
return (
|
||||||
|
<Button
|
||||||
|
variant="ghost"
|
||||||
|
onClick={() => column.toggleSorting(column.getIsSorted() === "asc")}
|
||||||
|
>
|
||||||
|
<span className="flex flex-row gap-2">Module Name</span>
|
||||||
|
{column.getIsSorted() === "asc" ? (
|
||||||
|
<ArrowUp className="ml-2 h-4 w-4" />
|
||||||
|
) : (
|
||||||
|
<ArrowDown className="ml-2 h-4 w-4" />
|
||||||
|
)}
|
||||||
|
</Button>
|
||||||
|
);
|
||||||
|
},
|
||||||
|
cell: ({ row, getValue }) => {
|
||||||
|
const initialValue = String(getValue() ?? "");
|
||||||
|
const [localValue, setLocalValue] = useState(initialValue);
|
||||||
|
|
||||||
|
const id = row.original.settings_id;
|
||||||
|
const field = "moduleName";
|
||||||
|
|
||||||
|
useEffect(() => setLocalValue(initialValue), [initialValue]);
|
||||||
|
|
||||||
|
const handleSubmit = (newValue: string) => {
|
||||||
|
if (newValue !== initialValue) {
|
||||||
|
setLocalValue(newValue);
|
||||||
|
updateSetting.mutate({ id, field, value: newValue });
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Input
|
||||||
|
value={localValue}
|
||||||
|
onChange={(e) => setLocalValue(e.currentTarget.value)}
|
||||||
|
onBlur={(e) => {
|
||||||
|
if (!submitting.current) {
|
||||||
|
submitting.current = true;
|
||||||
|
handleSubmit(e.currentTarget.value.trim());
|
||||||
|
setTimeout(() => (submitting.current = false), 100); // reset after slight delay
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
onKeyDown={(e) => {
|
||||||
|
if (e.key === "Enter") {
|
||||||
|
e.preventDefault();
|
||||||
|
submitting.current = true;
|
||||||
|
handleSubmit(e.currentTarget.value.trim());
|
||||||
|
e.currentTarget.blur(); // will trigger blur, but we ignore it
|
||||||
|
setTimeout(() => (submitting.current = false), 100);
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
];
|
||||||
|
|
||||||
|
if (isLoading)
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<span>Loading settings data</span>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
return (
|
||||||
|
<div className="m-2">
|
||||||
|
<TableNoExpand data={data} columns={columns} />
|
||||||
|
</div>
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,11 +6,13 @@ process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0";
|
|||||||
|
|
||||||
import axios from "axios";
|
import axios from "axios";
|
||||||
import { Client } from "pg";
|
import { Client } from "pg";
|
||||||
|
import { db } from "../../../../../database/dbclient.js";
|
||||||
|
import { settings } from "../../../../../database/schema/settings.js";
|
||||||
import { tryCatch } from "../../../../globalUtils/tryCatch.js";
|
import { tryCatch } from "../../../../globalUtils/tryCatch.js";
|
||||||
import type { Settings } from "../../../../types/settings.js";
|
import type { Settings } from "../../../../types/settings.js";
|
||||||
import { createLog } from "../../../logger/logger.js";
|
import { createLog } from "../../../logger/logger.js";
|
||||||
|
|
||||||
export let serverSettings: Settings[];
|
export let serverSettings: Settings[] = [];
|
||||||
export const getSettings = async () => {
|
export const getSettings = async () => {
|
||||||
const settingsType = process.env.LST_USE_GO;
|
const settingsType = process.env.LST_USE_GO;
|
||||||
createLog(
|
createLog(
|
||||||
@@ -22,7 +24,7 @@ export const getSettings = async () => {
|
|||||||
|
|
||||||
//if (settingsType !== "true") {
|
//if (settingsType !== "true") {
|
||||||
try {
|
try {
|
||||||
// serverSettings = (await db.select().from(settings)) as any;
|
//serverSettings = (await db.select().from(settings)) as any;
|
||||||
const dbUrl = String(process.env.DATABASE_URL).replace("lst_db", "lst");
|
const dbUrl = String(process.env.DATABASE_URL).replace("lst_db", "lst");
|
||||||
const client = new Client({
|
const client = new Client({
|
||||||
connectionString: dbUrl,
|
connectionString: dbUrl,
|
||||||
@@ -30,6 +32,7 @@ export const getSettings = async () => {
|
|||||||
|
|
||||||
await client.connect();
|
await client.connect();
|
||||||
|
|
||||||
|
if (serverSettings.length === 0) {
|
||||||
try {
|
try {
|
||||||
const s = await client.query("SELECT * FROM settings");
|
const s = await client.query("SELECT * FROM settings");
|
||||||
|
|
||||||
@@ -37,7 +40,6 @@ export const getSettings = async () => {
|
|||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.log(e);
|
console.log(e);
|
||||||
}
|
}
|
||||||
//.where(sql`${userRole} = ANY(roles)`);
|
|
||||||
|
|
||||||
// const { data, error } = (await tryCatch(
|
// const { data, error } = (await tryCatch(
|
||||||
// axios.get(
|
// axios.get(
|
||||||
@@ -56,7 +58,11 @@ export const getSettings = async () => {
|
|||||||
// }
|
// }
|
||||||
|
|
||||||
//serverSettings = data.data.data;
|
//serverSettings = data.data.data;
|
||||||
|
} else {
|
||||||
|
return serverSettings;
|
||||||
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
console.log(error);
|
||||||
createLog(
|
createLog(
|
||||||
"error",
|
"error",
|
||||||
"lst",
|
"lst",
|
||||||
|
|||||||
@@ -84,7 +84,15 @@
|
|||||||
"tiPostTime": "[{\"from\": \"24\", \"to\": \"24\"}]",
|
"tiPostTime": "[{\"from\": \"24\", \"to\": \"24\"}]",
|
||||||
"otherSettings": [
|
"otherSettings": [
|
||||||
{
|
{
|
||||||
"specialInstructions": "Please be sure to schedule a pick up appointment and bring 2 load bars to secure the load."
|
"specialInstructions": "Please contact ShippingReceivingBowlingGreen1@groups.alpla.com to schedule a pick up appointment and bring 2 load bars to secure the load."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"destinationInstructions": [
|
||||||
|
{
|
||||||
|
"customerID": 96,
|
||||||
|
"instructions": "Delivery appointments must be scheduled at least 48 hours in advance—no same day appointments. Delivery appointments can be scheduled via RMlmwdockscheduling@LyonsMagnus.com Phone #- 559-268-5966 ext 1158."
|
||||||
|
}
|
||||||
|
]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
@@ -351,9 +359,7 @@
|
|||||||
"oldVersion": "E:\\LST\\lst_backend",
|
"oldVersion": "E:\\LST\\lst_backend",
|
||||||
"shippingHours": "[{\"early\": \"00:01\", \"late\": \"23:59\"}]",
|
"shippingHours": "[{\"early\": \"00:01\", \"late\": \"23:59\"}]",
|
||||||
"tiPostTime": "[{\"from\": \"24\", \"to\": \"24\"}]",
|
"tiPostTime": "[{\"from\": \"24\", \"to\": \"24\"}]",
|
||||||
"otherSettings": [
|
"otherSettings": [{ "specialInstructions": "Loadbars/Straps required." }]
|
||||||
{ "specialInstructions": "Loadbars/Straps required." }
|
|
||||||
]
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"sName": "Marked Tree",
|
"sName": "Marked Tree",
|
||||||
@@ -373,9 +379,7 @@
|
|||||||
"oldVersion": "E:\\LST\\lst_backend",
|
"oldVersion": "E:\\LST\\lst_backend",
|
||||||
"shippingHours": "[{\"early\": \"06:30\", \"late\": \"23:00\"}]",
|
"shippingHours": "[{\"early\": \"06:30\", \"late\": \"23:00\"}]",
|
||||||
"tiPostTime": "[{\"from\": \"24\", \"to\": \"24\"}]",
|
"tiPostTime": "[{\"from\": \"24\", \"to\": \"24\"}]",
|
||||||
"otherSettings": [
|
"otherSettings": [{ "specialInstructions": "Loadbars/Straps required." }]
|
||||||
{ "specialInstructions": "Loadbars/Straps required." }
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user