Refactor BottomToolBar UI and remove debug log #12
|
|
@ -696,8 +696,6 @@ export default class LineConnection {
|
|||
timestamp: now,
|
||||
})
|
||||
|
||||
console.log(newItem)
|
||||
|
||||
// Lấy phần tử cuối
|
||||
const lastItems = await redis.zrevrange(key, 0, 0)
|
||||
if (lastItems.length > 0) {
|
||||
|
|
|
|||
|
|
@ -22,7 +22,12 @@ import { DrawerAPCControl, DrawerSwitchControl } from "./DrawerControl";
|
|||
import DrawerScenario from "./DrawerScenario";
|
||||
import { isJsonString } from "../untils/helper";
|
||||
import { motion } from "motion/react";
|
||||
import { IconCaretDown, IconCaretUp, IconPlayerPlay, IconPlus } from "@tabler/icons-react";
|
||||
import {
|
||||
IconCaretDown,
|
||||
IconCaretUp,
|
||||
IconPlayerPlay,
|
||||
IconPlus,
|
||||
} from "@tabler/icons-react";
|
||||
|
||||
interface TabsProps {
|
||||
selectedLines: TLine[];
|
||||
|
|
@ -296,217 +301,143 @@ const BottomToolBar = ({
|
|||
zIndex: 1,
|
||||
}}
|
||||
>
|
||||
<Box style={{ position: "relative" }}>
|
||||
<ActionIcon
|
||||
style={{
|
||||
position: "absolute",
|
||||
top: isExpand ? -4 : -24,
|
||||
left: "50%",
|
||||
translate: "-19px 0",
|
||||
backgroundColor: "#e3e0e0",
|
||||
width: "55px",
|
||||
}}
|
||||
variant="light"
|
||||
onClick={() => {
|
||||
setExpanded((prev) => !prev);
|
||||
}}
|
||||
>
|
||||
{isExpand ? (
|
||||
<IconCaretDown color="green" />
|
||||
) : (
|
||||
<IconCaretUp color="green" />
|
||||
)}
|
||||
</ActionIcon>
|
||||
<Grid>
|
||||
<Grid.Col span={1}></Grid.Col>
|
||||
<Grid.Col span={10}>
|
||||
<Tabs
|
||||
defaultValue="command"
|
||||
orientation="vertical"
|
||||
value={activeTabBottom}
|
||||
onChange={(val) => {
|
||||
setActiveTabBottom(val || "command");
|
||||
}}
|
||||
className={classes.containerBottom}
|
||||
style={{ height: "20vh" }}
|
||||
>
|
||||
<Tabs.List>
|
||||
<Tabs.Tab
|
||||
style={{
|
||||
backgroundColor:
|
||||
activeTabBottom === "command" ? "#c8d9fd" : "",
|
||||
fontSize: "13px",
|
||||
paddingTop: "8px",
|
||||
paddingBottom: "8px",
|
||||
}}
|
||||
value="command"
|
||||
>
|
||||
Command Line
|
||||
</Tabs.Tab>
|
||||
<Tabs.Tab
|
||||
style={{
|
||||
backgroundColor: activeTabBottom === "apc" ? "#c8d9fd" : "",
|
||||
fontSize: "13px",
|
||||
paddingTop: "8px",
|
||||
paddingBottom: "8px",
|
||||
}}
|
||||
value="apc"
|
||||
>
|
||||
APC
|
||||
</Tabs.Tab>
|
||||
<Tabs.Tab
|
||||
style={{
|
||||
backgroundColor:
|
||||
activeTabBottom === "switch" ? "#c8d9fd" : "",
|
||||
fontSize: "13px",
|
||||
paddingTop: "8px",
|
||||
paddingBottom: "8px",
|
||||
}}
|
||||
value="switch"
|
||||
>
|
||||
Switch
|
||||
</Tabs.Tab>
|
||||
</Tabs.List>
|
||||
<Box style={{ position: "relative" }}>
|
||||
<ActionIcon
|
||||
style={{
|
||||
position: "absolute",
|
||||
top: isExpand ? -4 : -24,
|
||||
left: "50%",
|
||||
translate: "-19px 0",
|
||||
backgroundColor: "#e3e0e0",
|
||||
width: "55px",
|
||||
}}
|
||||
variant="light"
|
||||
onClick={() => {
|
||||
setExpanded((prev) => !prev);
|
||||
}}
|
||||
>
|
||||
{isExpand ? (
|
||||
<IconCaretDown color="green" />
|
||||
) : (
|
||||
<IconCaretUp color="green" />
|
||||
)}
|
||||
</ActionIcon>
|
||||
<Grid>
|
||||
<Grid.Col span={1}></Grid.Col>
|
||||
<Grid.Col span={10}>
|
||||
<Tabs
|
||||
defaultValue="command"
|
||||
orientation="vertical"
|
||||
value={activeTabBottom}
|
||||
onChange={(val) => {
|
||||
setActiveTabBottom(val || "command");
|
||||
}}
|
||||
className={classes.containerBottom}
|
||||
style={{ height: "20vh" }}
|
||||
>
|
||||
<Tabs.List>
|
||||
<Tabs.Tab
|
||||
style={{
|
||||
backgroundColor:
|
||||
activeTabBottom === "command" ? "#c8d9fd" : "",
|
||||
fontSize: "13px",
|
||||
paddingTop: "8px",
|
||||
paddingBottom: "8px",
|
||||
}}
|
||||
value="command"
|
||||
>
|
||||
Command Line
|
||||
</Tabs.Tab>
|
||||
<Tabs.Tab
|
||||
style={{
|
||||
backgroundColor:
|
||||
activeTabBottom === "apc" ? "#c8d9fd" : "",
|
||||
fontSize: "13px",
|
||||
paddingTop: "8px",
|
||||
paddingBottom: "8px",
|
||||
}}
|
||||
value="apc"
|
||||
>
|
||||
APC
|
||||
</Tabs.Tab>
|
||||
<Tabs.Tab
|
||||
style={{
|
||||
backgroundColor:
|
||||
activeTabBottom === "switch" ? "#c8d9fd" : "",
|
||||
fontSize: "13px",
|
||||
paddingTop: "8px",
|
||||
paddingBottom: "8px",
|
||||
}}
|
||||
value="switch"
|
||||
>
|
||||
Switch
|
||||
</Tabs.Tab>
|
||||
</Tabs.List>
|
||||
|
||||
<Tabs.Panel value="command" p={"xs"}>
|
||||
<Flex justify={"space-between"}>
|
||||
<ScrollArea h={"15vh"}>
|
||||
<Flex wrap={"wrap"} gap={"xs"} w={"400px"}>
|
||||
{selectedLines.map((el) => (
|
||||
<Box
|
||||
key={el.id}
|
||||
style={{
|
||||
paddingLeft: "4px",
|
||||
height: "30px",
|
||||
width: "80px",
|
||||
backgroundColor: "#d4e3ff",
|
||||
borderRadius: "8px",
|
||||
}}
|
||||
>
|
||||
<Flex align={"center"} justify={"center"} gap={"4px"}>
|
||||
<Text fz={"12px"}>Line {el.lineNumber}</Text>
|
||||
<CloseButton
|
||||
style={{ minWidth: "24px" }}
|
||||
aria-label="Clear input"
|
||||
onClick={() => {
|
||||
setSelectedLines(
|
||||
selectedLines.filter(
|
||||
(line) => line.id !== el.id
|
||||
)
|
||||
);
|
||||
socket?.emit("close_cli", {
|
||||
lineId: el?.id,
|
||||
stationId: el.stationId || el.station_id,
|
||||
});
|
||||
}}
|
||||
/>
|
||||
</Flex>
|
||||
</Box>
|
||||
))}
|
||||
</Flex>
|
||||
</ScrollArea>
|
||||
<Box pl={"md"} pr={"md"}>
|
||||
<Flex justify={"space-between"} mb={"xs"}>
|
||||
<Flex></Flex>
|
||||
<Button
|
||||
fw={400}
|
||||
disabled={isDisable || selectedLines.length === 0}
|
||||
variant="filled"
|
||||
color="orange"
|
||||
size="xs"
|
||||
radius="md"
|
||||
onClick={() => {
|
||||
const listLine = selectedLines.length
|
||||
? selectedLines
|
||||
: station?.lines;
|
||||
if (listLine.length) {
|
||||
socket?.emit("write_command_line_from_web", {
|
||||
lineIds: listLine.map((line) => line.id),
|
||||
stationId: station.id,
|
||||
command: "spam_break",
|
||||
});
|
||||
setIsDisable(true);
|
||||
setTimeout(() => {
|
||||
setIsDisable(false);
|
||||
}, 5000);
|
||||
}
|
||||
}}
|
||||
>
|
||||
Send Break
|
||||
</Button>
|
||||
</Flex>
|
||||
<Tabs.Panel value="command" p={"xs"}>
|
||||
<Flex justify={"space-between"}>
|
||||
<Box>
|
||||
<Input
|
||||
ref={inputRef}
|
||||
style={{
|
||||
width: "30vw",
|
||||
boxShadow: "0px 0px 10px rgba(0, 0, 0, 0.1)",
|
||||
}}
|
||||
placeholder={"Send command to port(s)"}
|
||||
value={valueInput}
|
||||
onChange={(event) => {
|
||||
const newValue = event.currentTarget.value;
|
||||
setValueInput(newValue);
|
||||
}}
|
||||
onKeyDown={(event) => {
|
||||
if (event.key === "Enter") {
|
||||
const listLine = selectedLines.length
|
||||
? selectedLines
|
||||
: station?.lines;
|
||||
if (listLine?.length) {
|
||||
socket?.emit("write_command_line_from_web", {
|
||||
lineIds: listLine.map((line) => line.id),
|
||||
stationId: station.id,
|
||||
command: valueInput + "\r\n",
|
||||
});
|
||||
// setTimeout(() => {
|
||||
// socket?.emit("write_command_line_from_web", {
|
||||
// lineIds: listLine.map((line) => line.id),
|
||||
// stationId: station.id,
|
||||
// command: " \n",
|
||||
// });
|
||||
// }, 1000);
|
||||
}
|
||||
setValueInput("");
|
||||
}
|
||||
}}
|
||||
rightSectionPointerEvents="all"
|
||||
rightSection={
|
||||
<CloseButton
|
||||
aria-label="Clear input"
|
||||
onClick={() => setValueInput("")}
|
||||
style={{
|
||||
display: valueInput ? undefined : "none",
|
||||
}}
|
||||
/>
|
||||
}
|
||||
/>
|
||||
</Box>
|
||||
</Box>
|
||||
<Box style={{ width: "220px" }}>
|
||||
<Flex align={"center"} wrap={"wrap"} gap={"xs"}>
|
||||
<ButtonSelect
|
||||
selectedLines={selectedLines}
|
||||
setSelectedLines={setSelectedLines}
|
||||
station={station}
|
||||
userName={user?.userName}
|
||||
onClick={() => {
|
||||
const lines = station.lines.filter(
|
||||
(line) =>
|
||||
!line?.userOpenCLI ||
|
||||
line?.userOpenCLI === user?.userName
|
||||
);
|
||||
if (selectedLines.length !== lines.length) {
|
||||
setSelectedLines(lines);
|
||||
lines.forEach((line) => {
|
||||
socket?.emit("open_cli", {
|
||||
lineId: line.id,
|
||||
stationId: line.stationId || line.station_id,
|
||||
userEmail: user?.email,
|
||||
userName: user?.userName,
|
||||
});
|
||||
});
|
||||
} else {
|
||||
<ScrollArea h={"12vh"}>
|
||||
<Flex wrap={"wrap"} gap={"8px"} w={"420px"}>
|
||||
{selectedLines.map((el) => (
|
||||
<Box
|
||||
key={el.id}
|
||||
style={{
|
||||
position: "relative",
|
||||
padding: "4px 6px",
|
||||
height: "26px",
|
||||
width: "60px",
|
||||
backgroundColor: "#d4e3ff",
|
||||
borderRadius: "8px",
|
||||
}}
|
||||
>
|
||||
{/* Close button góc trên phải */}
|
||||
<CloseButton
|
||||
size="xs"
|
||||
style={{
|
||||
position: "absolute",
|
||||
top: "-4px",
|
||||
right: "-6px",
|
||||
minWidth: "18px",
|
||||
width: "18px",
|
||||
height: "18px",
|
||||
zIndex: 10,
|
||||
}}
|
||||
onClick={() => {
|
||||
setSelectedLines(
|
||||
selectedLines.filter(
|
||||
(line) => line.id !== el.id
|
||||
)
|
||||
);
|
||||
socket?.emit("close_cli", {
|
||||
lineId: el?.id,
|
||||
stationId: el.stationId || el.station_id,
|
||||
});
|
||||
}}
|
||||
/>
|
||||
|
||||
<Flex
|
||||
align={"center"}
|
||||
justify={"center"}
|
||||
h="100%"
|
||||
>
|
||||
<Text fz={"11px"}>Line {el.lineNumber}</Text>
|
||||
</Flex>
|
||||
</Box>
|
||||
))}
|
||||
</Flex>
|
||||
</ScrollArea>
|
||||
{selectedLines?.length > 0 ? (
|
||||
<Button
|
||||
fw={400}
|
||||
className={classes.buttonControl}
|
||||
variant="outline"
|
||||
onClick={() => {
|
||||
const lines = station.lines.filter(
|
||||
(line) =>
|
||||
!line?.userOpenCLI ||
|
||||
line?.userOpenCLI === user?.userName
|
||||
);
|
||||
lines.forEach((line) => {
|
||||
socket?.emit("close_cli", {
|
||||
lineId: line?.id,
|
||||
|
|
@ -514,53 +445,171 @@ const BottomToolBar = ({
|
|||
});
|
||||
});
|
||||
setSelectedLines([]);
|
||||
}}
|
||||
>
|
||||
Clear
|
||||
</Button>
|
||||
) : (
|
||||
""
|
||||
)}
|
||||
</Box>
|
||||
|
||||
<Box pl={"md"} pr={"md"}>
|
||||
<Flex justify={"space-between"} mb={"xs"}>
|
||||
<Flex></Flex>
|
||||
<Button
|
||||
fw={400}
|
||||
disabled={isDisable || selectedLines.length === 0}
|
||||
variant="filled"
|
||||
color="orange"
|
||||
size="xs"
|
||||
radius="md"
|
||||
onClick={() => {
|
||||
const listLine = selectedLines.length
|
||||
? selectedLines
|
||||
: station?.lines;
|
||||
if (listLine.length) {
|
||||
socket?.emit("write_command_line_from_web", {
|
||||
lineIds: listLine.map((line) => line.id),
|
||||
stationId: station.id,
|
||||
command: "spam_break",
|
||||
});
|
||||
setIsDisable(true);
|
||||
setTimeout(() => {
|
||||
setIsDisable(false);
|
||||
}, 5000);
|
||||
}
|
||||
}}
|
||||
>
|
||||
Send Break
|
||||
</Button>
|
||||
</Flex>
|
||||
<Box>
|
||||
<Input
|
||||
ref={inputRef}
|
||||
style={{
|
||||
width: "30vw",
|
||||
boxShadow: "0px 0px 10px rgba(0, 0, 0, 0.1)",
|
||||
}}
|
||||
placeholder={"Send command to port(s)"}
|
||||
value={valueInput}
|
||||
onChange={(event) => {
|
||||
const newValue = event.currentTarget.value;
|
||||
setValueInput(newValue);
|
||||
}}
|
||||
onKeyDown={(event) => {
|
||||
if (event.key === "Enter") {
|
||||
const listLine = selectedLines.length
|
||||
? selectedLines
|
||||
: station?.lines;
|
||||
if (listLine?.length) {
|
||||
socket?.emit("write_command_line_from_web", {
|
||||
lineIds: listLine.map((line) => line.id),
|
||||
stationId: station.id,
|
||||
command: valueInput + "\r\n",
|
||||
});
|
||||
// setTimeout(() => {
|
||||
// socket?.emit("write_command_line_from_web", {
|
||||
// lineIds: listLine.map((line) => line.id),
|
||||
// stationId: station.id,
|
||||
// command: " \n",
|
||||
// });
|
||||
// }, 1000);
|
||||
}
|
||||
setValueInput("");
|
||||
}
|
||||
}}
|
||||
rightSectionPointerEvents="all"
|
||||
rightSection={
|
||||
<CloseButton
|
||||
aria-label="Clear input"
|
||||
onClick={() => setValueInput("")}
|
||||
style={{
|
||||
display: valueInput ? undefined : "none",
|
||||
}}
|
||||
/>
|
||||
}
|
||||
}}
|
||||
/>
|
||||
<ButtonDPELP
|
||||
socket={socket}
|
||||
selectedLines={selectedLines}
|
||||
isDisable={isDisable || selectedLines.length === 0}
|
||||
onClick={() => {
|
||||
// setSelectedLines([]);
|
||||
setIsDisable(true);
|
||||
setTimeout(() => {
|
||||
setIsDisable(false);
|
||||
}, 5000);
|
||||
}}
|
||||
/>
|
||||
<Button
|
||||
fw={400}
|
||||
disabled={isDisable || selectedLines.length === 0}
|
||||
variant="filled"
|
||||
color="yellow"
|
||||
style={{ height: "30px", width: "100px" }}
|
||||
onClick={() => setOpenScenarioModal(true)}
|
||||
>
|
||||
Scenario
|
||||
</Button>
|
||||
<DrawerLogs
|
||||
socket={socket}
|
||||
isLogModalOpen={isLogModalOpen}
|
||||
setIsLogModalOpen={setIsLogModalOpen}
|
||||
testLogContent={testLogContent}
|
||||
setTestLogContent={setTestLogContent}
|
||||
/>
|
||||
</Flex>
|
||||
</Box>
|
||||
</Flex>
|
||||
</Tabs.Panel>
|
||||
<Tabs.Panel value="apc" ps={"xs"}>
|
||||
<DrawerAPCControl socket={socket} stationAPI={station} />
|
||||
</Tabs.Panel>
|
||||
<Tabs.Panel value="switch" ps={"xs"}>
|
||||
<DrawerSwitchControl socket={socket} stationAPI={station} />
|
||||
</Tabs.Panel>
|
||||
</Tabs>
|
||||
</Grid.Col>
|
||||
<Grid.Col span={1}></Grid.Col>
|
||||
</Grid>
|
||||
</Box>
|
||||
/>
|
||||
</Box>
|
||||
</Box>
|
||||
<Box style={{ width: "220px" }}>
|
||||
<Flex align={"center"} wrap={"wrap"} gap={"xs"}>
|
||||
<ButtonSelect
|
||||
selectedLines={selectedLines}
|
||||
setSelectedLines={setSelectedLines}
|
||||
station={station}
|
||||
userName={user?.userName}
|
||||
onClick={() => {
|
||||
const lines = station.lines.filter(
|
||||
(line) =>
|
||||
!line?.userOpenCLI ||
|
||||
line?.userOpenCLI === user?.userName
|
||||
);
|
||||
if (selectedLines.length !== lines.length) {
|
||||
setSelectedLines(lines);
|
||||
lines.forEach((line) => {
|
||||
socket?.emit("open_cli", {
|
||||
lineId: line.id,
|
||||
stationId: line.stationId || line.station_id,
|
||||
userEmail: user?.email,
|
||||
userName: user?.userName,
|
||||
});
|
||||
});
|
||||
} else {
|
||||
lines.forEach((line) => {
|
||||
socket?.emit("close_cli", {
|
||||
lineId: line?.id,
|
||||
stationId: line.stationId || line.station_id,
|
||||
});
|
||||
});
|
||||
setSelectedLines([]);
|
||||
}
|
||||
}}
|
||||
/>
|
||||
<ButtonDPELP
|
||||
socket={socket}
|
||||
selectedLines={selectedLines}
|
||||
isDisable={isDisable || selectedLines.length === 0}
|
||||
onClick={() => {
|
||||
// setSelectedLines([]);
|
||||
setIsDisable(true);
|
||||
setTimeout(() => {
|
||||
setIsDisable(false);
|
||||
}, 5000);
|
||||
}}
|
||||
/>
|
||||
<Button
|
||||
fw={400}
|
||||
disabled={isDisable || selectedLines.length === 0}
|
||||
variant="filled"
|
||||
color="yellow"
|
||||
style={{ height: "30px", width: "100px" }}
|
||||
onClick={() => setOpenScenarioModal(true)}
|
||||
>
|
||||
Scenario
|
||||
</Button>
|
||||
<DrawerLogs
|
||||
socket={socket}
|
||||
isLogModalOpen={isLogModalOpen}
|
||||
setIsLogModalOpen={setIsLogModalOpen}
|
||||
testLogContent={testLogContent}
|
||||
setTestLogContent={setTestLogContent}
|
||||
/>
|
||||
</Flex>
|
||||
</Box>
|
||||
</Flex>
|
||||
</Tabs.Panel>
|
||||
<Tabs.Panel value="apc" ps={"xs"}>
|
||||
<DrawerAPCControl socket={socket} stationAPI={station} />
|
||||
</Tabs.Panel>
|
||||
<Tabs.Panel value="switch" ps={"xs"}>
|
||||
<DrawerSwitchControl socket={socket} stationAPI={station} />
|
||||
</Tabs.Panel>
|
||||
</Tabs>
|
||||
</Grid.Col>
|
||||
<Grid.Col span={1}></Grid.Col>
|
||||
</Grid>
|
||||
</Box>
|
||||
</motion.div>
|
||||
|
||||
{/* Drawer Scenario để Add/Edit */}
|
||||
|
|
|
|||
Loading…
Reference in New Issue