Refactor BottomToolBar and update user types
Improved BottomToolBar command line UI with better line selection and clearing logic. Updated TUser type to include 'id' and 'email' fields, and fixed DragTabs to support both 'userId' and 'id' for user key mapping.
This commit is contained in:
parent
b5bb90ca4e
commit
1b9b18ce3b
|
|
@ -14,7 +14,7 @@ import {
|
|||
} from "@mantine/core";
|
||||
import { useEffect, useMemo, useRef, useState } from "react";
|
||||
import classes from "./Component.module.css";
|
||||
import type { IScenario, TLine, TStation } from "../untils/types";
|
||||
import type { IScenario, TLine, TStation, TUser } from "../untils/types";
|
||||
import type { Socket } from "socket.io-client";
|
||||
import { ButtonDPELP, ButtonSelect } from "./ButtonAction";
|
||||
import DrawerLogs from "./DrawerLogs";
|
||||
|
|
@ -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[];
|
||||
|
|
@ -58,7 +63,7 @@ const ScenarioCard = ({
|
|||
index: number;
|
||||
isDisable: boolean;
|
||||
selectedLines: TLine[];
|
||||
user: any;
|
||||
user: TUser;
|
||||
socket: Socket | null;
|
||||
setOpenScenarioModal: (value: boolean) => void;
|
||||
setIsDisable: (value: boolean) => void;
|
||||
|
|
@ -138,10 +143,7 @@ const ScenarioCard = ({
|
|||
|
||||
return (
|
||||
<Grid.Col key={scenario.id} span={3}>
|
||||
<div
|
||||
ref={cardRef}
|
||||
style={{ position: "relative" }}
|
||||
>
|
||||
<div ref={cardRef} style={{ position: "relative" }}>
|
||||
<Card
|
||||
shadow="sm"
|
||||
padding="md"
|
||||
|
|
@ -178,7 +180,8 @@ const ScenarioCard = ({
|
|||
isDisable ||
|
||||
selectedLines.filter(
|
||||
(el) =>
|
||||
!el?.userEmailOpenCLI || el?.userEmailOpenCLI === user?.email
|
||||
!el?.userEmailOpenCLI ||
|
||||
el?.userEmailOpenCLI === user?.email
|
||||
).length === 0
|
||||
}
|
||||
onClick={() => {
|
||||
|
|
@ -270,9 +273,7 @@ const ScenarioCard = ({
|
|||
overflow: "auto",
|
||||
}}
|
||||
>
|
||||
{steps
|
||||
.slice(0, 5)
|
||||
.map((step: { send: string }, i: number) => (
|
||||
{steps.slice(0, 5).map((step: { send: string }, i: number) => (
|
||||
<Text
|
||||
key={i}
|
||||
size="xs"
|
||||
|
|
@ -420,7 +421,11 @@ const BottomToolBar = ({
|
|||
{scenarios.length > 0 ? (
|
||||
<Grid
|
||||
gutter="md"
|
||||
style={{ margin: 0, overflow: "visible", position: "relative" }}
|
||||
style={{
|
||||
margin: 0,
|
||||
overflow: "visible",
|
||||
position: "relative",
|
||||
}}
|
||||
>
|
||||
{scenarios.map((scenario, index) => (
|
||||
<ScenarioCard
|
||||
|
|
@ -524,7 +529,8 @@ const BottomToolBar = ({
|
|||
</Tabs.Tab>
|
||||
<Tabs.Tab
|
||||
style={{
|
||||
backgroundColor: activeTabBottom === "apc" ? "#c8d9fd" : "",
|
||||
backgroundColor:
|
||||
activeTabBottom === "apc" ? "#c8d9fd" : "",
|
||||
fontSize: "13px",
|
||||
paddingTop: "8px",
|
||||
paddingBottom: "8px",
|
||||
|
|
@ -549,24 +555,33 @@ const BottomToolBar = ({
|
|||
|
||||
<Tabs.Panel value="command" p={"xs"}>
|
||||
<Flex justify={"space-between"}>
|
||||
<ScrollArea h={"15vh"}>
|
||||
<Flex wrap={"wrap"} gap={"xs"} w={"400px"}>
|
||||
<Box>
|
||||
<ScrollArea h={"12vh"}>
|
||||
<Flex wrap={"wrap"} gap={"8px"} w={"420px"}>
|
||||
{selectedLines.map((el) => (
|
||||
<Box
|
||||
key={el.id}
|
||||
style={{
|
||||
paddingLeft: "4px",
|
||||
height: "30px",
|
||||
width: "80px",
|
||||
position: "relative",
|
||||
padding: "4px 6px",
|
||||
height: "26px",
|
||||
width: "60px",
|
||||
backgroundColor: "#d4e3ff",
|
||||
borderRadius: "8px",
|
||||
}}
|
||||
>
|
||||
<Flex align={"center"} justify={"center"} gap={"4px"}>
|
||||
<Text fz={"12px"}>Line {el.lineNumber}</Text>
|
||||
{/* Close button góc trên phải */}
|
||||
<CloseButton
|
||||
style={{ minWidth: "24px" }}
|
||||
aria-label="Clear input"
|
||||
size="xs"
|
||||
style={{
|
||||
position: "absolute",
|
||||
top: "-4px",
|
||||
right: "-6px",
|
||||
minWidth: "18px",
|
||||
width: "18px",
|
||||
height: "18px",
|
||||
zIndex: 10,
|
||||
}}
|
||||
onClick={() => {
|
||||
setSelectedLines(
|
||||
selectedLines.filter(
|
||||
|
|
@ -579,11 +594,44 @@ const BottomToolBar = ({
|
|||
});
|
||||
}}
|
||||
/>
|
||||
|
||||
<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,
|
||||
stationId: line.stationId || line.station_id,
|
||||
});
|
||||
});
|
||||
setSelectedLines([]);
|
||||
}}
|
||||
>
|
||||
Clear
|
||||
</Button>
|
||||
) : (
|
||||
""
|
||||
)}
|
||||
</Box>
|
||||
<Box pl={"md"} pr={"md"}>
|
||||
<Flex justify={"space-between"} mb={"xs"}>
|
||||
<Flex></Flex>
|
||||
|
|
|
|||
|
|
@ -2,7 +2,6 @@ import {
|
|||
ActionIcon,
|
||||
Avatar,
|
||||
Box,
|
||||
Button,
|
||||
Flex,
|
||||
Group,
|
||||
Menu,
|
||||
|
|
@ -296,7 +295,7 @@ export default function DraggableTabs({
|
|||
<Tooltip
|
||||
withArrow
|
||||
label={usersConnecting.map((el) => (
|
||||
<Text key={el.userId}>{el.userName}</Text>
|
||||
<Text key={el.userId || el.id}>{el.userName}</Text>
|
||||
))}
|
||||
>
|
||||
<Avatar radius="xl" me={"sm"}>
|
||||
|
|
|
|||
|
|
@ -105,6 +105,8 @@ export type TLine = {
|
|||
export type TUser = {
|
||||
userId: number;
|
||||
userName: string;
|
||||
id: number;
|
||||
email: string;
|
||||
};
|
||||
|
||||
export type APCProps = {
|
||||
|
|
|
|||
Loading…
Reference in New Issue