From c4a5b1c4994bbb9e5cbabdf3ea8fe28de1cdf774 Mon Sep 17 00:00:00 2001 From: nguyentrungthat <80239428+nguentrungthat@users.noreply.github.com> Date: Thu, 15 Jan 2026 15:39:43 +0700 Subject: [PATCH] Update disable Station --- BACKEND/app/ultils/helper.ts | 6 + BACKEND/providers/socket_io_provider.ts | 69 ++++++ FRONTEND/src/App.tsx | 1 + FRONTEND/src/components/BottomToolBar.tsx | 8 +- FRONTEND/src/components/CardLine.tsx | 4 +- FRONTEND/src/components/DragTabs.tsx | 7 +- .../src/components/Drawer/DrawerControl.tsx | 196 +++++++++--------- FRONTEND/src/components/FormAddEdit.tsx | 6 +- 8 files changed, 198 insertions(+), 99 deletions(-) diff --git a/BACKEND/app/ultils/helper.ts b/BACKEND/app/ultils/helper.ts index 94a8225..53c61c0 100644 --- a/BACKEND/app/ultils/helper.ts +++ b/BACKEND/app/ultils/helper.ts @@ -6,6 +6,7 @@ import zulip from 'zulip-js' import { ErrorRow, LogRule, ParsedLog, TestError, TestResult } from './types.js' import axios from 'axios' import moment from 'moment' +import Station from '#models/station' const mailTo = 'andrew.ng@apactech.io' const mailCC = ['ips@ipsupply.com.au', 'kay@ipsupply.com.au', 'joseph@apactech.io'] @@ -1386,3 +1387,8 @@ export function parseLicenseReport(output: string) { failed: [...failed], } } + +export async function checkStationActive(stationId: string): Promise { + const station = await Station.find(stationId) + return station?.is_active || false +} diff --git a/BACKEND/providers/socket_io_provider.ts b/BACKEND/providers/socket_io_provider.ts index 0d8f71a..dc8331b 100644 --- a/BACKEND/providers/socket_io_provider.ts +++ b/BACKEND/providers/socket_io_provider.ts @@ -13,6 +13,7 @@ import Station from '#models/station' import APCController from '#services/apc_connection' import { appendLog, + checkStationActive, cleanData, sendMessageToMail, sendMessageToZulip, @@ -171,12 +172,21 @@ export class WebSocketIo { // FE gửi yêu cầu connect lines socket.on('connect_lines', async (data) => { const { stationData, linesData } = data + + // Check station is active + const activeStation = await checkStationActive(stationData.id) + if (!activeStation) return + await this.connectLine(io, linesData, stationData) }) socket.on('write_command_line_from_web', async (data) => { const { lineIds, stationId, command } = data + // Check station is active + // const activeStation = await checkStationActive(stationId) + // if (!activeStation) return + await this.handleLineOperation( io, stationId, @@ -190,6 +200,10 @@ export class WebSocketIo { socket.on('run_scenario', async (data) => { const lineId = data.id const scenario = data.scenario + // Check station is active + const activeStation = await checkStationActive(data.stationId) + if (!activeStation) return + await this.handleLineOperation( io, data.stationId, @@ -206,6 +220,10 @@ export class WebSocketIo { const lineId = data.lineId const baud = data.baud const line = await Line.find(lineId) + // Check station is active + const activeStation = await checkStationActive(data.stationId) + if (!activeStation) return + if (!line) { console.log(`Line [${lineId}] not found!!!`) return @@ -341,6 +359,10 @@ export class WebSocketIo { socket.on('control_apc', async (data) => { try { const { outletNumbers, action, station, apcName } = data + // Check station is active + const activeStation = await checkStationActive(station.id) + if (!activeStation) return + if (action === 'reconnect') { if (!station) return const apcIp = (station as any)[`${apcName}_ip`] as string @@ -401,6 +423,10 @@ export class WebSocketIo { socket.on('connect_apc', async (data) => { try { const { apcIp, station, apcName } = data + // Check station is active + const activeStation = await checkStationActive(station.id) + if (!activeStation) return + const apc = this.apcsControl.get(apcIp) if (apc && apc.status === 'CONNECTED') { socket.emit('apc_output', { @@ -423,6 +449,10 @@ export class WebSocketIo { socket.on('connect_switch', async (data) => { try { const { ip, station } = data + // Check station is active + const activeStation = await checkStationActive(station.id) + if (!activeStation) return + const element = this.switchControl.get(ip) // Connect station if not connected @@ -452,6 +482,10 @@ export class WebSocketIo { socket.on('control_switch', async (data) => { const { ports, command, ip, station } = data + // Check station is active + const activeStation = await checkStationActive(station.id) + if (!activeStation) return + const element1 = this.switchControl.get(ip) if (!element1) { await this.connectSwitch(io, station) @@ -573,6 +607,9 @@ export class WebSocketIo { const stationId = data.stationId || '' const scenarioName = data.scenarioName || '' const station = await Station.find(stationId) + // Check station is active + const activeStation = await checkStationActive(stationId) + if (!activeStation) return // Check station sendWiki flag console.log('[DPELP] Received run all dpelp', lineIds) if (!station || !station?.send_wiki) return @@ -608,6 +645,10 @@ export class WebSocketIo { socket.on('clear_terminal', async (data) => { const { stationId, lineId } = data + // Check station is active + const activeStation = await checkStationActive(stationId) + if (!activeStation) return + await this.handleLineOperation( io, stationId, @@ -619,6 +660,10 @@ export class WebSocketIo { socket.on('run_physical_test', async (data) => { const { stationId, lineId } = data + // Check station is active + const activeStation = await checkStationActive(stationId) + if (!activeStation) return + await this.handleLineOperation( io, stationId, @@ -630,6 +675,10 @@ export class WebSocketIo { socket.on('end_run_physical_test', async (data) => { const { stationId, lineId } = data + // Check station is active + const activeStation = await checkStationActive(stationId) + if (!activeStation) return + await this.handleLineOperation( io, stationId, @@ -644,6 +693,10 @@ export class WebSocketIo { socket.on('reset_physical_test', async (data) => { const { stationId, lineId } = data + // Check station is active + const activeStation = await checkStationActive(stationId) + if (!activeStation) return + await this.handleLineOperation( io, stationId, @@ -664,6 +717,10 @@ export class WebSocketIo { socket.on('load_ios_router', async (data) => { const { stationId, lineId, iosName, outletNumber, station, apcName, isReboot } = data + // Check station is active + const activeStation = await checkStationActive(stationId) + if (!activeStation) return + await this.handleLineOperation( io, stationId, @@ -695,6 +752,10 @@ export class WebSocketIo { socket.on('load_ios_switch', async (data) => { const { stationId, lineId, iosName } = data + // Check station is active + const activeStation = await checkStationActive(stationId) + if (!activeStation) return + await this.handleLineOperation( io, stationId, @@ -708,6 +769,10 @@ export class WebSocketIo { socket.on('load_license_router', async (data) => { const { stationId, lineId, licenseName, portName } = data + // Check station is active + const activeStation = await checkStationActive(stationId) + if (!activeStation) return + await this.handleLineOperation( io, stationId, @@ -721,6 +786,10 @@ export class WebSocketIo { socket.on('load_license_switch', async (data) => { const { stationId, lineId, licenseName, portName } = data + // Check station is active + const activeStation = await checkStationActive(stationId) + if (!activeStation) return + await this.handleLineOperation( io, stationId, diff --git a/FRONTEND/src/App.tsx b/FRONTEND/src/App.tsx index c621ff2..22cab6c 100644 --- a/FRONTEND/src/App.tsx +++ b/FRONTEND/src/App.tsx @@ -108,6 +108,7 @@ function App() { const [listLicense, setListLicense] = useState([]); const connectApcSwitch = (station: TStation) => { + if (!station?.is_active) return; if (station?.apc_1_ip && station?.apc_1_port) { socket?.emit("connect_apc", { station: station, diff --git a/FRONTEND/src/components/BottomToolBar.tsx b/FRONTEND/src/components/BottomToolBar.tsx index ccfc052..3008171 100644 --- a/FRONTEND/src/components/BottomToolBar.tsx +++ b/FRONTEND/src/components/BottomToolBar.tsx @@ -187,6 +187,7 @@ const BottomToolBar = ({ ) : ( - + val.id === line.id) ? { backgroundColor: "#8bf55940" } diff --git a/FRONTEND/src/components/DragTabs.tsx b/FRONTEND/src/components/DragTabs.tsx index 3930e01..10c34c1 100644 --- a/FRONTEND/src/components/DragTabs.tsx +++ b/FRONTEND/src/components/DragTabs.tsx @@ -107,7 +107,12 @@ function SortableTab({ c="#747474" > - + {tab.name} diff --git a/FRONTEND/src/components/Drawer/DrawerControl.tsx b/FRONTEND/src/components/Drawer/DrawerControl.tsx index 4507292..01f3bd3 100644 --- a/FRONTEND/src/components/Drawer/DrawerControl.tsx +++ b/FRONTEND/src/components/Drawer/DrawerControl.tsx @@ -441,54 +441,59 @@ export const DrawerAPCControl: React.FC = ({ gap: "10px", paddingTop: "8px", paddingBottom: "8px", + minHeight: "60px", }} > - {listOutlet - .filter((el) => el.apc === 1) - .map((outlet, i) => ( - el.name === outlet.name && el.apc === outlet.apc - )?.name - ? "1px solid #0018ff" - : "", - }} - onClick={() => { - toggleSelect(outlet, i + 1); - }} - > - - {findLineByOutlet(outlet) - ? "Line " + - (findLineByOutlet(outlet)?.lineNumber || - findLineByOutlet(outlet)?.line_number) - : outlet.name} - - - ))} + {dataStation?.apc_1_ip + ? listOutlet + .filter((el) => el.apc === 1) + .map((outlet, i) => ( + + el.name === outlet.name && el.apc === outlet.apc + )?.name + ? "1px solid #0018ff" + : "", + }} + onClick={() => { + toggleSelect(outlet, i + 1); + }} + > + + {findLineByOutlet(outlet) + ? "Line " + + (findLineByOutlet(outlet)?.lineNumber || + findLineByOutlet(outlet)?.line_number) + : outlet.name} + + + )) + : ""} @@ -674,54 +679,59 @@ export const DrawerAPCControl: React.FC = ({ gap: "10px", paddingTop: "8px", paddingBottom: "8px", + minHeight: "60px", }} > - {listOutlet - .filter((el) => el.apc === 2) - .map((outlet, i) => ( - el.name === outlet.name && el.apc === outlet.apc - )?.name - ? "1px solid #0018ff" - : "", - }} - onClick={() => { - toggleSelect(outlet, i + 1); - }} - > - - {findLineByOutlet(outlet) - ? "Line " + - (findLineByOutlet(outlet)?.lineNumber || - findLineByOutlet(outlet)?.line_number) - : outlet.name} - - - ))} + {dataStation?.apc_2_ip + ? listOutlet + .filter((el) => el.apc === 2) + .map((outlet, i) => ( + + el.name === outlet.name && el.apc === outlet.apc + )?.name + ? "1px solid #0018ff" + : "", + }} + onClick={() => { + toggleSelect(outlet, i + 1); + }} + > + + {findLineByOutlet(outlet) + ? "Line " + + (findLineByOutlet(outlet)?.lineNumber || + findLineByOutlet(outlet)?.line_number) + : outlet.name} + + + )) + : ""} @@ -1169,7 +1179,7 @@ export const DrawerSwitchControl: React.FC = ({ - {listPorts?.length > 0 && ( + {dataStation?.switch_control_ip && listPorts?.length > 0 && ( {listPorts?.map((group, key) => { diff --git a/FRONTEND/src/components/FormAddEdit.tsx b/FRONTEND/src/components/FormAddEdit.tsx index e6ac87f..7cd1acb 100644 --- a/FRONTEND/src/components/FormAddEdit.tsx +++ b/FRONTEND/src/components/FormAddEdit.tsx @@ -82,7 +82,7 @@ const StationSetting = ({ form.setFieldValue("apc_2_password", dataStation.apc_2_password); form.setFieldValue("switch_control_ip", dataStation.switch_control_ip); form.setFieldValue("send_wiki", dataStation?.send_wiki); - // form.setFieldValue("is_active", dataStation?.is_active); + form.setFieldValue("is_active", dataStation?.is_active); form.setFieldValue( "switch_control_port", dataStation.switch_control_port @@ -403,7 +403,7 @@ const StationSetting = ({ form.setFieldValue("send_wiki", event.currentTarget.checked) } /> - {/* form.setFieldValue("is_active", event.currentTarget.checked) } - /> */} + /> } size={"90%"}