Update modal Scenario
This commit is contained in:
parent
5a8cf4b999
commit
2729feed4e
|
|
@ -4,7 +4,8 @@ import type { HttpContext } from '@adonisjs/core/http'
|
|||
export default class BrandsController {
|
||||
// GET /models
|
||||
async index({}: HttpContext) {
|
||||
return await Brand.all()
|
||||
const brands = await Brand.all()
|
||||
return brands.sort((a, b) => a.id - b.id)
|
||||
}
|
||||
|
||||
// POST /models
|
||||
|
|
|
|||
|
|
@ -4,7 +4,8 @@ import type { HttpContext } from '@adonisjs/core/http'
|
|||
export default class CategoriesController {
|
||||
// GET /models
|
||||
async index({}: HttpContext) {
|
||||
return await Category.all()
|
||||
const categories = await Category.all()
|
||||
return categories.sort((a, b) => a.id - b.id)
|
||||
}
|
||||
|
||||
// POST /models
|
||||
|
|
|
|||
|
|
@ -5,9 +5,34 @@ import "./App.css";
|
|||
import classes from "./App.module.css";
|
||||
import componentClasses from "./components/Component.module.css";
|
||||
|
||||
import { Suspense, useCallback, useEffect, useMemo, useRef, useState } from "react";
|
||||
import { Tabs, Text, Container, Flex, MantineProvider, Grid, ScrollArea, LoadingOverlay } from "@mantine/core";
|
||||
import type { IScenario, ReceivedFile, ResponseData, TLine, TStation, TUser } from "./untils/types";
|
||||
import {
|
||||
Suspense,
|
||||
useCallback,
|
||||
useEffect,
|
||||
useMemo,
|
||||
useRef,
|
||||
useState,
|
||||
} from "react";
|
||||
import {
|
||||
Tabs,
|
||||
Text,
|
||||
Container,
|
||||
Flex,
|
||||
MantineProvider,
|
||||
Grid,
|
||||
ScrollArea,
|
||||
LoadingOverlay,
|
||||
} from "@mantine/core";
|
||||
import type {
|
||||
IScenario,
|
||||
ReceivedFile,
|
||||
ResponseData,
|
||||
TBrands,
|
||||
TCategories,
|
||||
TLine,
|
||||
TStation,
|
||||
TUser,
|
||||
} from "./untils/types";
|
||||
import axios from "axios";
|
||||
import CardLine from "./components/CardLine";
|
||||
import { SocketProvider, useSocket } from "./context/SocketContext";
|
||||
|
|
@ -44,7 +69,10 @@ const chunkArray = <T,>(array: T[], size: number): T[][] => {
|
|||
*/
|
||||
function App() {
|
||||
const user = useMemo(() => {
|
||||
return localStorage.getItem("user") && isJsonString(localStorage.getItem("user")) ? JSON.parse(localStorage.getItem("user") || "") : null;
|
||||
return localStorage.getItem("user") &&
|
||||
isJsonString(localStorage.getItem("user"))
|
||||
? JSON.parse(localStorage.getItem("user") || "")
|
||||
: null;
|
||||
}, []);
|
||||
|
||||
if (!user) {
|
||||
|
|
@ -72,6 +100,8 @@ function App() {
|
|||
const [activeTabBottom, setActiveTabBottom] = useState<string>("command");
|
||||
const lineBuffersRef = useRef(new Map<number, string>());
|
||||
const flushScheduledRef = useRef(false);
|
||||
const [listBrands, setListBrands] = useState<TBrands[]>([]);
|
||||
const [listCategories, setListCategories] = useState<TCategories[]>([]);
|
||||
|
||||
const connectApcSwitch = (station: TStation) => {
|
||||
if (station?.apc_1_ip && station?.apc_1_port) {
|
||||
|
|
@ -105,7 +135,9 @@ function App() {
|
|||
setStations(
|
||||
response.data.map((station) => {
|
||||
connectApcSwitch(station);
|
||||
const lines = (station?.lines || []).sort((a: TLine, b: TLine) => a?.lineNumber - b?.lineNumber);
|
||||
const lines = (station?.lines || []).sort(
|
||||
(a: TLine, b: TLine) => a?.lineNumber - b?.lineNumber
|
||||
);
|
||||
return { ...station, lines };
|
||||
})
|
||||
);
|
||||
|
|
@ -130,18 +162,58 @@ function App() {
|
|||
}
|
||||
};
|
||||
|
||||
// function get list brand
|
||||
const getBrands = async () => {
|
||||
try {
|
||||
const response = await axios.get(apiUrl + "api/brands");
|
||||
if (response.data) {
|
||||
if (response.data && Array.isArray(response.data)) {
|
||||
setListBrands(response.data);
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
console.log("Error get brand", error);
|
||||
}
|
||||
};
|
||||
|
||||
// function get list brand
|
||||
const getCategories = async () => {
|
||||
try {
|
||||
const response = await axios.get(apiUrl + "api/categories");
|
||||
if (response.data && Array.isArray(response.data)) {
|
||||
setListCategories(response.data);
|
||||
}
|
||||
} catch (error) {
|
||||
console.log("Error get brand", error);
|
||||
}
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
if (!socket) return;
|
||||
getStation();
|
||||
getScenarios();
|
||||
getBrands();
|
||||
getCategories();
|
||||
}, [socket]);
|
||||
|
||||
useEffect(() => {
|
||||
if (!socket || !stations?.length) return;
|
||||
|
||||
socket.on("line_connected", (data) => updateValueLineStation(data?.lineId, { status: data.status, connecting: false }, data?.stationId));
|
||||
socket.on("line_connected", (data) =>
|
||||
updateValueLineStation(
|
||||
data?.lineId,
|
||||
{ status: data.status, connecting: false },
|
||||
data?.stationId
|
||||
)
|
||||
);
|
||||
|
||||
socket.on("line_disconnected", (data) => updateValueLineStation(data?.lineId, { status: data.status, connecting: false }, data?.stationId));
|
||||
socket.on("line_disconnected", (data) =>
|
||||
updateValueLineStation(
|
||||
data?.lineId,
|
||||
{ status: data.status, connecting: false },
|
||||
data?.stationId
|
||||
)
|
||||
);
|
||||
|
||||
socket?.on("line_output", (data) => {
|
||||
const { lineId, data: text } = data;
|
||||
|
|
@ -161,7 +233,11 @@ function App() {
|
|||
});
|
||||
|
||||
socket?.on("line_error", (data) => {
|
||||
updateValueLineStation(data?.lineId, { netOutput: data.error, connecting: false }, data?.stationId);
|
||||
updateValueLineStation(
|
||||
data?.lineId,
|
||||
{ netOutput: data.error, connecting: false },
|
||||
data?.stationId
|
||||
);
|
||||
});
|
||||
|
||||
socket?.on("init", (data) => {
|
||||
|
|
@ -169,7 +245,11 @@ function App() {
|
|||
// console.log(data);
|
||||
setLoadingTerminal(true);
|
||||
data.forEach((value) => {
|
||||
updateValueLineStation(value?.id, { ...value, netOutput: value.output }, value?.stationId);
|
||||
updateValueLineStation(
|
||||
value?.id,
|
||||
{ ...value, netOutput: value.output },
|
||||
value?.stationId
|
||||
);
|
||||
});
|
||||
}
|
||||
});
|
||||
|
|
@ -290,13 +370,21 @@ function App() {
|
|||
|
||||
socket?.on("line_connecting", (data) => {
|
||||
setTimeout(() => {
|
||||
updateValueLineStation(data?.lineId, { connecting: true }, data?.stationId);
|
||||
updateValueLineStation(
|
||||
data?.lineId,
|
||||
{ connecting: true },
|
||||
data?.stationId
|
||||
);
|
||||
}, 100);
|
||||
});
|
||||
|
||||
socket?.on("running_scenario", (data) => {
|
||||
setTimeout(() => {
|
||||
updateValueLineStation(data?.lineId, { runningScenario: data?.title || "" }, data?.stationId);
|
||||
updateValueLineStation(
|
||||
data?.lineId,
|
||||
{ runningScenario: data?.title || "" },
|
||||
data?.stationId
|
||||
);
|
||||
}, 100);
|
||||
});
|
||||
|
||||
|
|
@ -341,7 +429,8 @@ function App() {
|
|||
flushScheduledRef.current = false;
|
||||
}, []);
|
||||
|
||||
const updateValueLineStation = useCallback((lineId: number, updates: Partial<TLine>, stationId?: number) => {
|
||||
const updateValueLineStation = useCallback(
|
||||
(lineId: number, updates: Partial<TLine>, stationId?: number) => {
|
||||
setStations((prevStations) =>
|
||||
prevStations?.map((station: TStation) =>
|
||||
station.id === stationId
|
||||
|
|
@ -358,7 +447,8 @@ function App() {
|
|||
lineNumber: lineItem.lineNumber,
|
||||
line_number: lineItem.line_number,
|
||||
...(isNetOutput && {
|
||||
netOutput: (lineItem.netOutput || "") + (updates.netOutput || ""),
|
||||
netOutput:
|
||||
(lineItem.netOutput || "") + (updates.netOutput || ""),
|
||||
output: updates.netOutput, // Nếu netOutput thì update luôn output
|
||||
loadingOutput: lineItem.loadingOutput ? false : true,
|
||||
}),
|
||||
|
|
@ -379,15 +469,19 @@ function App() {
|
|||
...prevSelected,
|
||||
...updates,
|
||||
...(isNetOutput && {
|
||||
netOutput: (prevSelected.netOutput || "") + (updates.netOutput || ""),
|
||||
netOutput:
|
||||
(prevSelected.netOutput || "") + (updates.netOutput || ""),
|
||||
output: updates.netOutput,
|
||||
loadingOutput: prevSelected.loadingOutput ? false : true,
|
||||
}),
|
||||
};
|
||||
});
|
||||
}, []);
|
||||
},
|
||||
[]
|
||||
);
|
||||
|
||||
const updateValueSelectedLine = useCallback((lineId: number, updates: Partial<TLine>) => {
|
||||
const updateValueSelectedLine = useCallback(
|
||||
(lineId: number, updates: Partial<TLine>) => {
|
||||
// Update selectedLine nếu nó đang được chọn
|
||||
setSelectedLine((prevSelected) => {
|
||||
if (!prevSelected || prevSelected.id !== lineId) return prevSelected;
|
||||
|
|
@ -398,13 +492,16 @@ function App() {
|
|||
...prevSelected,
|
||||
...updates,
|
||||
...(isNetOutput && {
|
||||
netOutput: (prevSelected.netOutput || "") + (updates.netOutput || ""),
|
||||
netOutput:
|
||||
(prevSelected.netOutput || "") + (updates.netOutput || ""),
|
||||
output: updates.netOutput,
|
||||
loadingOutput: prevSelected.loadingOutput ? false : true,
|
||||
}),
|
||||
};
|
||||
});
|
||||
}, []);
|
||||
},
|
||||
[]
|
||||
);
|
||||
|
||||
// const getLine = (lineId: number, stationId: number) => {
|
||||
// const station = stations?.find((sta) => sta.id === stationId);
|
||||
|
|
@ -449,21 +546,28 @@ function App() {
|
|||
scenarios={scenarios}
|
||||
setScenarios={setScenarios}
|
||||
panels={stations.map((station) => (
|
||||
<Tabs.Panel className={classes.content} key={station.id} value={station.id.toString()} pt="md">
|
||||
<Tabs.Panel
|
||||
className={classes.content}
|
||||
key={station.id}
|
||||
value={station.id.toString()}
|
||||
pt="md"
|
||||
>
|
||||
<Flex className={classes.containerMain}>
|
||||
<Grid>
|
||||
<Grid.Col
|
||||
span={12}
|
||||
style={{
|
||||
borderRadius: 8,
|
||||
}}>
|
||||
}}
|
||||
>
|
||||
<ScrollArea
|
||||
// h={expandedBottomBar ? "80vh" : "85vh"}
|
||||
h={expandedBottomBar ? "73vh" : "83vh"}
|
||||
type="scroll"
|
||||
scrollbars="y"
|
||||
style={{ overflowX: "hidden" }}
|
||||
className={componentClasses.hideScrollBar}>
|
||||
className={componentClasses.hideScrollBar}
|
||||
>
|
||||
{station.lines.length > 0 ? (
|
||||
station.lines.length < 9 ? (
|
||||
<Grid
|
||||
|
|
@ -471,7 +575,8 @@ function App() {
|
|||
style={{
|
||||
margin: 0,
|
||||
width: "100%",
|
||||
}}>
|
||||
}}
|
||||
>
|
||||
{station.lines.map((line, i) => (
|
||||
<Grid.Col
|
||||
key={line.id ?? i}
|
||||
|
|
@ -481,7 +586,8 @@ function App() {
|
|||
height: "100%",
|
||||
maxWidth: "100%",
|
||||
overflow: "hidden",
|
||||
}}>
|
||||
}}
|
||||
>
|
||||
<CardLine
|
||||
socket={socket}
|
||||
stationItem={station}
|
||||
|
|
@ -489,7 +595,10 @@ function App() {
|
|||
selectedLines={selectedLines}
|
||||
setSelectedLines={setSelectedLines}
|
||||
openTerminal={openTerminal}
|
||||
loadTerminal={loadingTerminal && Number(station.id) === Number(activeTab)}
|
||||
loadTerminal={
|
||||
loadingTerminal &&
|
||||
Number(station.id) === Number(activeTab)
|
||||
}
|
||||
scenarios={scenarios}
|
||||
/>
|
||||
</Grid.Col>
|
||||
|
|
@ -506,11 +615,15 @@ function App() {
|
|||
|
||||
const leftChunks = chunkArray(leftLines, 2);
|
||||
const rightChunks = chunkArray(rightLines, 2);
|
||||
const numRows = Math.max(leftChunks.length, rightChunks.length);
|
||||
const numRows = Math.max(
|
||||
leftChunks.length,
|
||||
rightChunks.length
|
||||
);
|
||||
|
||||
return (
|
||||
<>
|
||||
{Array.from({ length: numRows }).map((_, rowIndex) => {
|
||||
{Array.from({ length: numRows }).map(
|
||||
(_, rowIndex) => {
|
||||
const leftRow = leftChunks[rowIndex] || [];
|
||||
const rightRow = rightChunks[rowIndex] || [];
|
||||
|
||||
|
|
@ -521,28 +634,38 @@ function App() {
|
|||
style={{
|
||||
margin: 0,
|
||||
width: "100%",
|
||||
}}>
|
||||
}}
|
||||
>
|
||||
{/* Cột A */}
|
||||
<Grid.Col span={6}>
|
||||
<Grid gutter="md">
|
||||
{leftRow.map((line, i) => (
|
||||
<Grid.Col
|
||||
key={line.id ?? `L-${rowIndex}-${i}`}
|
||||
key={
|
||||
line.id ?? `L-${rowIndex}-${i}`
|
||||
}
|
||||
span={6}
|
||||
style={{
|
||||
display: "flex",
|
||||
height: "100%",
|
||||
maxWidth: "100%",
|
||||
overflow: "hidden",
|
||||
}}>
|
||||
}}
|
||||
>
|
||||
<CardLine
|
||||
socket={socket}
|
||||
stationItem={station}
|
||||
line={line}
|
||||
selectedLines={selectedLines}
|
||||
setSelectedLines={setSelectedLines}
|
||||
setSelectedLines={
|
||||
setSelectedLines
|
||||
}
|
||||
openTerminal={openTerminal}
|
||||
loadTerminal={loadingTerminal && Number(station.id) === Number(activeTab)}
|
||||
loadTerminal={
|
||||
loadingTerminal &&
|
||||
Number(station.id) ===
|
||||
Number(activeTab)
|
||||
}
|
||||
scenarios={scenarios}
|
||||
/>
|
||||
</Grid.Col>
|
||||
|
|
@ -555,22 +678,31 @@ function App() {
|
|||
<Grid gutter="md">
|
||||
{rightRow.map((line, i) => (
|
||||
<Grid.Col
|
||||
key={line.id ?? `R-${rowIndex}-${i}`}
|
||||
key={
|
||||
line.id ?? `R-${rowIndex}-${i}`
|
||||
}
|
||||
span={6}
|
||||
style={{
|
||||
display: "flex",
|
||||
height: "100%",
|
||||
maxWidth: "100%",
|
||||
overflow: "hidden",
|
||||
}}>
|
||||
}}
|
||||
>
|
||||
<CardLine
|
||||
socket={socket}
|
||||
stationItem={station}
|
||||
line={line}
|
||||
selectedLines={selectedLines}
|
||||
setSelectedLines={setSelectedLines}
|
||||
setSelectedLines={
|
||||
setSelectedLines
|
||||
}
|
||||
openTerminal={openTerminal}
|
||||
loadTerminal={loadingTerminal && Number(station.id) === Number(activeTab)}
|
||||
loadTerminal={
|
||||
loadingTerminal &&
|
||||
Number(station.id) ===
|
||||
Number(activeTab)
|
||||
}
|
||||
scenarios={scenarios}
|
||||
/>
|
||||
</Grid.Col>
|
||||
|
|
@ -579,7 +711,8 @@ function App() {
|
|||
</Grid.Col>
|
||||
</Grid>
|
||||
);
|
||||
})}
|
||||
}
|
||||
)}
|
||||
</>
|
||||
);
|
||||
})()
|
||||
|
|
@ -610,6 +743,8 @@ function App() {
|
|||
activeTabBottom={activeTabBottom}
|
||||
setActiveTabBottom={setActiveTabBottom}
|
||||
isExpand={expandedBottomBar}
|
||||
listBrands={listBrands}
|
||||
listCategories={listCategories}
|
||||
/>
|
||||
</Flex>
|
||||
</Tabs.Panel>
|
||||
|
|
@ -635,7 +770,9 @@ function App() {
|
|||
setActive={setActiveTab}
|
||||
active={activeTab}
|
||||
onSendCommand={(value) => {
|
||||
const listLine = selectedLines.length ? selectedLines : stations.find((el) => el.id === Number(activeTab))?.lines;
|
||||
const listLine = selectedLines.length
|
||||
? selectedLines
|
||||
: stations.find((el) => el.id === Number(activeTab))?.lines;
|
||||
if (listLine?.length) {
|
||||
socket?.emit("write_command_line_from_web", {
|
||||
lineIds: listLine.map((line) => line.id),
|
||||
|
|
@ -651,6 +788,8 @@ function App() {
|
|||
}, 1000);
|
||||
}
|
||||
}}
|
||||
listBrands={listBrands}
|
||||
listCategories={listCategories}
|
||||
/>
|
||||
|
||||
<StationSetting
|
||||
|
|
@ -692,13 +831,24 @@ function App() {
|
|||
|
||||
export default function Main() {
|
||||
const user = useMemo(() => {
|
||||
return localStorage.getItem("user") && isJsonString(localStorage.getItem("user")) ? JSON.parse(localStorage.getItem("user") || "") : null;
|
||||
return localStorage.getItem("user") &&
|
||||
isJsonString(localStorage.getItem("user"))
|
||||
? JSON.parse(localStorage.getItem("user") || "")
|
||||
: null;
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<MantineProvider>
|
||||
<SocketProvider>
|
||||
<Suspense fallback={<LoadingOverlay visible={true} zIndex={1000} overlayProps={{ radius: "sm", blur: 1 }} />}>
|
||||
<Suspense
|
||||
fallback={
|
||||
<LoadingOverlay
|
||||
visible={true}
|
||||
zIndex={1000}
|
||||
overlayProps={{ radius: "sm", blur: 1 }}
|
||||
/>
|
||||
}
|
||||
>
|
||||
<Notifications position="top-right" autoClose={5000} />
|
||||
{user ? (
|
||||
<App />
|
||||
|
|
|
|||
|
|
@ -13,7 +13,14 @@ import {
|
|||
} from "@mantine/core";
|
||||
import { useEffect, useMemo, useRef, useState } from "react";
|
||||
import classes from "./Component.module.css";
|
||||
import type { IScenario, TLine, TStation, TUser } from "../untils/types";
|
||||
import type {
|
||||
IScenario,
|
||||
TBrands,
|
||||
TCategories,
|
||||
TLine,
|
||||
TStation,
|
||||
TUser,
|
||||
} from "../untils/types";
|
||||
import type { Socket } from "socket.io-client";
|
||||
import { ButtonDPELP, ButtonSelect } from "./ButtonAction";
|
||||
import DrawerLogs from "./Drawer/DrawerLogs";
|
||||
|
|
@ -47,6 +54,8 @@ interface TabsProps {
|
|||
activeTabBottom: string;
|
||||
setActiveTabBottom: (value: React.SetStateAction<string>) => void;
|
||||
isExpand: boolean;
|
||||
listBrands: TBrands[];
|
||||
listCategories: TCategories[];
|
||||
}
|
||||
|
||||
// Component cho từng Scenario Card
|
||||
|
|
@ -379,6 +388,8 @@ const BottomToolBar = ({
|
|||
activeTabBottom,
|
||||
isExpand,
|
||||
stationId,
|
||||
listBrands,
|
||||
listCategories,
|
||||
}: TabsProps) => {
|
||||
const user = useMemo(() => {
|
||||
return localStorage.getItem("user") &&
|
||||
|
|
@ -1067,6 +1078,8 @@ const BottomToolBar = ({
|
|||
setScenarios={setScenarios}
|
||||
externalOpened={openDrawerScenario}
|
||||
onExternalClose={() => setOpenDrawerScenario(false)}
|
||||
listBrands={listBrands}
|
||||
listCategories={listCategories}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
|
|
|
|||
|
|
@ -37,7 +37,13 @@ import {
|
|||
IconUsersGroup,
|
||||
} from "@tabler/icons-react";
|
||||
import classes from "./Component.module.css";
|
||||
import type { IScenario, TStation, TUser } from "../untils/types";
|
||||
import type {
|
||||
IScenario,
|
||||
TBrands,
|
||||
TCategories,
|
||||
TStation,
|
||||
TUser,
|
||||
} from "../untils/types";
|
||||
import type { Socket } from "socket.io-client";
|
||||
import ModalHistory from "./Modal/ModalHistory";
|
||||
import ModalConfig from "./Modal/ModalConfig";
|
||||
|
|
@ -60,6 +66,8 @@ interface DraggableTabsProps {
|
|||
onSendCommand: (value: string) => void;
|
||||
scenarios: IScenario[];
|
||||
setScenarios: (value: React.SetStateAction<IScenario[]>) => void;
|
||||
listBrands: TBrands[];
|
||||
listCategories: TCategories[];
|
||||
}
|
||||
|
||||
function SortableTab({
|
||||
|
|
@ -123,6 +131,8 @@ export default function DraggableTabs({
|
|||
setActive,
|
||||
scenarios,
|
||||
setScenarios,
|
||||
listBrands,
|
||||
listCategories,
|
||||
}: DraggableTabsProps) {
|
||||
const user = useMemo(() => {
|
||||
return localStorage.getItem("user") &&
|
||||
|
|
@ -396,6 +406,8 @@ export default function DraggableTabs({
|
|||
setScenarios={setScenarios}
|
||||
externalOpened={openDrawerScenario}
|
||||
onExternalClose={() => setOpenDrawerScenario(false)}
|
||||
listBrands={listBrands}
|
||||
listCategories={listCategories}
|
||||
/>
|
||||
</DndContext>
|
||||
);
|
||||
|
|
|
|||
|
|
@ -10,15 +10,23 @@ import {
|
|||
Flex,
|
||||
CloseButton,
|
||||
Checkbox,
|
||||
Select,
|
||||
TagsInput,
|
||||
} from "@mantine/core";
|
||||
import classes from "../Component.module.css";
|
||||
import TableRows from "./Scenario/TableRows";
|
||||
import { useEffect, useState } from "react";
|
||||
import { useForm } from "@mantine/form";
|
||||
import DialogConfirm from "../DialogConfirm";
|
||||
import type { IBodyScenario, IScenario } from "../../untils/types";
|
||||
import type {
|
||||
IBodyScenario,
|
||||
IScenario,
|
||||
TBrands,
|
||||
TCategories,
|
||||
} from "../../untils/types";
|
||||
import axios from "axios";
|
||||
import { notifications } from "@mantine/notifications";
|
||||
import { isJsonString } from "../../untils/helper";
|
||||
const apiUrl = import.meta.env.VITE_BACKEND_URL;
|
||||
|
||||
function ModalScenario({
|
||||
|
|
@ -26,11 +34,15 @@ function ModalScenario({
|
|||
setScenarios,
|
||||
externalOpened,
|
||||
onExternalClose,
|
||||
listBrands,
|
||||
listCategories,
|
||||
}: {
|
||||
scenarios: IScenario[];
|
||||
setScenarios: (value: React.SetStateAction<IScenario[]>) => void;
|
||||
externalOpened?: boolean;
|
||||
onExternalClose?: () => void;
|
||||
listBrands: TBrands[];
|
||||
listCategories: TCategories[];
|
||||
}) {
|
||||
const [opened, { close }] = useDisclosure(false);
|
||||
|
||||
|
|
@ -60,9 +72,13 @@ function ModalScenario({
|
|||
repeat: "1",
|
||||
},
|
||||
] as IBodyScenario[],
|
||||
timeout: "30000",
|
||||
timeout: "30",
|
||||
isReboot: false,
|
||||
send_result: false,
|
||||
note: "",
|
||||
series: [] as string[],
|
||||
brandId: "",
|
||||
categoryId: "",
|
||||
},
|
||||
validate: {
|
||||
title: (value) => {
|
||||
|
|
@ -129,6 +145,10 @@ function ModalScenario({
|
|||
send_result: form.values.send_result,
|
||||
body: body,
|
||||
timeout: Number(form.values.timeout),
|
||||
categoryId: Number(form.values.categoryId),
|
||||
brandId: Number(form.values.brandId),
|
||||
note: form.values.note,
|
||||
series: form.values.series,
|
||||
};
|
||||
const url = isEdit ? "api/scenarios/update" : "api/scenarios/create";
|
||||
const res = await axios.post(
|
||||
|
|
@ -219,7 +239,7 @@ function ModalScenario({
|
|||
right: 0,
|
||||
bottom: 0,
|
||||
backgroundColor: "rgba(0,0,0,0.6)",
|
||||
zIndex: 100000,
|
||||
zIndex: 100,
|
||||
display: "flex",
|
||||
alignItems: "center",
|
||||
justifyContent: "center",
|
||||
|
|
@ -248,13 +268,13 @@ function ModalScenario({
|
|||
<Flex
|
||||
justify="space-between"
|
||||
align="center"
|
||||
p="lg"
|
||||
p="sm"
|
||||
style={{
|
||||
borderBottom: "1px solid #e9ecef",
|
||||
flexShrink: 0,
|
||||
}}
|
||||
>
|
||||
<Text fw={700} size="xl">
|
||||
<Text fw={700} size="md">
|
||||
{isEdit ? "✏️ Edit Scenarios" : "➕ Add Scenarios"}
|
||||
</Text>
|
||||
<CloseButton size="lg" onClick={handleClose} />
|
||||
|
|
@ -319,6 +339,25 @@ function ModalScenario({
|
|||
"send_result",
|
||||
scenario.send_result
|
||||
);
|
||||
form.setFieldValue("note", scenario.note);
|
||||
form.setFieldValue(
|
||||
"brandId",
|
||||
scenario.brand_id
|
||||
? scenario.brand_id.toString()
|
||||
: scenario?.brandId?.toString()
|
||||
);
|
||||
form.setFieldValue(
|
||||
"categoryId",
|
||||
scenario.category_id
|
||||
? scenario.category_id.toString()
|
||||
: scenario.categoryId.toString()
|
||||
);
|
||||
form.setFieldValue(
|
||||
"series",
|
||||
isJsonString(scenario?.series)
|
||||
? JSON.parse(scenario.series)
|
||||
: []
|
||||
);
|
||||
}
|
||||
}}
|
||||
>
|
||||
|
|
@ -425,6 +464,60 @@ function ModalScenario({
|
|||
</Grid.Col>
|
||||
</Grid>
|
||||
</Box>
|
||||
<Box>
|
||||
<Grid>
|
||||
<Grid.Col span={2}>
|
||||
<Select
|
||||
label="Brand"
|
||||
placeholder="Select Brand"
|
||||
data={listBrands?.map((el) => ({
|
||||
value: el.id.toString(),
|
||||
label: el.name,
|
||||
}))}
|
||||
value={form.values.brandId || null}
|
||||
onChange={(value) =>
|
||||
form.setFieldValue("brandId", value || "")
|
||||
}
|
||||
/>
|
||||
</Grid.Col>
|
||||
<Grid.Col span={2}>
|
||||
<Select
|
||||
label="Category"
|
||||
placeholder="Select Category"
|
||||
data={listCategories?.map((el) => ({
|
||||
value: el.id.toString(),
|
||||
label: el.name,
|
||||
}))}
|
||||
value={form.values.categoryId || null}
|
||||
onChange={(value) =>
|
||||
form.setFieldValue("categoryId", value || "")
|
||||
}
|
||||
/>
|
||||
</Grid.Col>
|
||||
<Grid.Col span={2}>
|
||||
<TextInput
|
||||
label="Note"
|
||||
placeholder="Input note"
|
||||
value={form.values.note}
|
||||
onChange={(e) =>
|
||||
form.setFieldValue("note", e.target.value)
|
||||
}
|
||||
required
|
||||
/>
|
||||
</Grid.Col>
|
||||
<Grid.Col span={6}>
|
||||
<TagsInput
|
||||
label="Series"
|
||||
placeholder="Enter Series"
|
||||
data={[]}
|
||||
value={form.values.series || []}
|
||||
onChange={(value: string[]) =>
|
||||
form.setFieldValue("series", value)
|
||||
}
|
||||
/>
|
||||
</Grid.Col>
|
||||
</Grid>
|
||||
</Box>
|
||||
<hr style={{ width: "100%" }} />
|
||||
<Box>
|
||||
<ScrollArea
|
||||
|
|
|
|||
|
|
@ -165,6 +165,12 @@ export type IScenario = {
|
|||
isReboot: boolean;
|
||||
is_reboot: boolean;
|
||||
send_result: boolean;
|
||||
brandId: number;
|
||||
brand_id?: number;
|
||||
categoryId: number;
|
||||
category_id?: number;
|
||||
note: string;
|
||||
series: string;
|
||||
updated_at: string;
|
||||
};
|
||||
|
||||
|
|
@ -241,3 +247,12 @@ export type TextTSMLicense = {
|
|||
LICENSE_COUNT: string;
|
||||
LICENSE_PRIORITY: string;
|
||||
};
|
||||
|
||||
export type TBrands = {
|
||||
id: number;
|
||||
name: string;
|
||||
};
|
||||
export type TCategories = {
|
||||
id: number;
|
||||
name: string;
|
||||
};
|
||||
|
|
|
|||
Loading…
Reference in New Issue