Update disable Station

This commit is contained in:
nguyentrungthat 2026-01-15 15:39:43 +07:00
parent f6620edc35
commit c4a5b1c499
8 changed files with 198 additions and 99 deletions

View File

@ -6,6 +6,7 @@ import zulip from 'zulip-js'
import { ErrorRow, LogRule, ParsedLog, TestError, TestResult } from './types.js' import { ErrorRow, LogRule, ParsedLog, TestError, TestResult } from './types.js'
import axios from 'axios' import axios from 'axios'
import moment from 'moment' import moment from 'moment'
import Station from '#models/station'
const mailTo = 'andrew.ng@apactech.io' const mailTo = 'andrew.ng@apactech.io'
const mailCC = ['ips@ipsupply.com.au', 'kay@ipsupply.com.au', 'joseph@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], failed: [...failed],
} }
} }
export async function checkStationActive(stationId: string): Promise<boolean> {
const station = await Station.find(stationId)
return station?.is_active || false
}

View File

@ -13,6 +13,7 @@ import Station from '#models/station'
import APCController from '#services/apc_connection' import APCController from '#services/apc_connection'
import { import {
appendLog, appendLog,
checkStationActive,
cleanData, cleanData,
sendMessageToMail, sendMessageToMail,
sendMessageToZulip, sendMessageToZulip,
@ -171,12 +172,21 @@ export class WebSocketIo {
// FE gửi yêu cầu connect lines // FE gửi yêu cầu connect lines
socket.on('connect_lines', async (data) => { socket.on('connect_lines', async (data) => {
const { stationData, linesData } = data const { stationData, linesData } = data
// Check station is active
const activeStation = await checkStationActive(stationData.id)
if (!activeStation) return
await this.connectLine(io, linesData, stationData) await this.connectLine(io, linesData, stationData)
}) })
socket.on('write_command_line_from_web', async (data) => { socket.on('write_command_line_from_web', async (data) => {
const { lineIds, stationId, command } = data const { lineIds, stationId, command } = data
// Check station is active
// const activeStation = await checkStationActive(stationId)
// if (!activeStation) return
await this.handleLineOperation( await this.handleLineOperation(
io, io,
stationId, stationId,
@ -190,6 +200,10 @@ export class WebSocketIo {
socket.on('run_scenario', async (data) => { socket.on('run_scenario', async (data) => {
const lineId = data.id const lineId = data.id
const scenario = data.scenario const scenario = data.scenario
// Check station is active
const activeStation = await checkStationActive(data.stationId)
if (!activeStation) return
await this.handleLineOperation( await this.handleLineOperation(
io, io,
data.stationId, data.stationId,
@ -206,6 +220,10 @@ export class WebSocketIo {
const lineId = data.lineId const lineId = data.lineId
const baud = data.baud const baud = data.baud
const line = await Line.find(lineId) const line = await Line.find(lineId)
// Check station is active
const activeStation = await checkStationActive(data.stationId)
if (!activeStation) return
if (!line) { if (!line) {
console.log(`Line [${lineId}] not found!!!`) console.log(`Line [${lineId}] not found!!!`)
return return
@ -341,6 +359,10 @@ export class WebSocketIo {
socket.on('control_apc', async (data) => { socket.on('control_apc', async (data) => {
try { try {
const { outletNumbers, action, station, apcName } = data const { outletNumbers, action, station, apcName } = data
// Check station is active
const activeStation = await checkStationActive(station.id)
if (!activeStation) return
if (action === 'reconnect') { if (action === 'reconnect') {
if (!station) return if (!station) return
const apcIp = (station as any)[`${apcName}_ip`] as string const apcIp = (station as any)[`${apcName}_ip`] as string
@ -401,6 +423,10 @@ export class WebSocketIo {
socket.on('connect_apc', async (data) => { socket.on('connect_apc', async (data) => {
try { try {
const { apcIp, station, apcName } = data const { apcIp, station, apcName } = data
// Check station is active
const activeStation = await checkStationActive(station.id)
if (!activeStation) return
const apc = this.apcsControl.get(apcIp) const apc = this.apcsControl.get(apcIp)
if (apc && apc.status === 'CONNECTED') { if (apc && apc.status === 'CONNECTED') {
socket.emit('apc_output', { socket.emit('apc_output', {
@ -423,6 +449,10 @@ export class WebSocketIo {
socket.on('connect_switch', async (data) => { socket.on('connect_switch', async (data) => {
try { try {
const { ip, station } = data const { ip, station } = data
// Check station is active
const activeStation = await checkStationActive(station.id)
if (!activeStation) return
const element = this.switchControl.get(ip) const element = this.switchControl.get(ip)
// Connect station if not connected // Connect station if not connected
@ -452,6 +482,10 @@ export class WebSocketIo {
socket.on('control_switch', async (data) => { socket.on('control_switch', async (data) => {
const { ports, command, ip, station } = 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) const element1 = this.switchControl.get(ip)
if (!element1) { if (!element1) {
await this.connectSwitch(io, station) await this.connectSwitch(io, station)
@ -573,6 +607,9 @@ export class WebSocketIo {
const stationId = data.stationId || '' const stationId = data.stationId || ''
const scenarioName = data.scenarioName || '' const scenarioName = data.scenarioName || ''
const station = await Station.find(stationId) const station = await Station.find(stationId)
// Check station is active
const activeStation = await checkStationActive(stationId)
if (!activeStation) return
// Check station sendWiki flag // Check station sendWiki flag
console.log('[DPELP] Received run all dpelp', lineIds) console.log('[DPELP] Received run all dpelp', lineIds)
if (!station || !station?.send_wiki) return if (!station || !station?.send_wiki) return
@ -608,6 +645,10 @@ export class WebSocketIo {
socket.on('clear_terminal', async (data) => { socket.on('clear_terminal', async (data) => {
const { stationId, lineId } = data const { stationId, lineId } = data
// Check station is active
const activeStation = await checkStationActive(stationId)
if (!activeStation) return
await this.handleLineOperation( await this.handleLineOperation(
io, io,
stationId, stationId,
@ -619,6 +660,10 @@ export class WebSocketIo {
socket.on('run_physical_test', async (data) => { socket.on('run_physical_test', async (data) => {
const { stationId, lineId } = data const { stationId, lineId } = data
// Check station is active
const activeStation = await checkStationActive(stationId)
if (!activeStation) return
await this.handleLineOperation( await this.handleLineOperation(
io, io,
stationId, stationId,
@ -630,6 +675,10 @@ export class WebSocketIo {
socket.on('end_run_physical_test', async (data) => { socket.on('end_run_physical_test', async (data) => {
const { stationId, lineId } = data const { stationId, lineId } = data
// Check station is active
const activeStation = await checkStationActive(stationId)
if (!activeStation) return
await this.handleLineOperation( await this.handleLineOperation(
io, io,
stationId, stationId,
@ -644,6 +693,10 @@ export class WebSocketIo {
socket.on('reset_physical_test', async (data) => { socket.on('reset_physical_test', async (data) => {
const { stationId, lineId } = data const { stationId, lineId } = data
// Check station is active
const activeStation = await checkStationActive(stationId)
if (!activeStation) return
await this.handleLineOperation( await this.handleLineOperation(
io, io,
stationId, stationId,
@ -664,6 +717,10 @@ export class WebSocketIo {
socket.on('load_ios_router', async (data) => { socket.on('load_ios_router', async (data) => {
const { stationId, lineId, iosName, outletNumber, station, apcName, isReboot } = 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( await this.handleLineOperation(
io, io,
stationId, stationId,
@ -695,6 +752,10 @@ export class WebSocketIo {
socket.on('load_ios_switch', async (data) => { socket.on('load_ios_switch', async (data) => {
const { stationId, lineId, iosName } = data const { stationId, lineId, iosName } = data
// Check station is active
const activeStation = await checkStationActive(stationId)
if (!activeStation) return
await this.handleLineOperation( await this.handleLineOperation(
io, io,
stationId, stationId,
@ -708,6 +769,10 @@ export class WebSocketIo {
socket.on('load_license_router', async (data) => { socket.on('load_license_router', async (data) => {
const { stationId, lineId, licenseName, portName } = data const { stationId, lineId, licenseName, portName } = data
// Check station is active
const activeStation = await checkStationActive(stationId)
if (!activeStation) return
await this.handleLineOperation( await this.handleLineOperation(
io, io,
stationId, stationId,
@ -721,6 +786,10 @@ export class WebSocketIo {
socket.on('load_license_switch', async (data) => { socket.on('load_license_switch', async (data) => {
const { stationId, lineId, licenseName, portName } = data const { stationId, lineId, licenseName, portName } = data
// Check station is active
const activeStation = await checkStationActive(stationId)
if (!activeStation) return
await this.handleLineOperation( await this.handleLineOperation(
io, io,
stationId, stationId,

View File

@ -108,6 +108,7 @@ function App() {
const [listLicense, setListLicense] = useState<FileInfo[]>([]); const [listLicense, setListLicense] = useState<FileInfo[]>([]);
const connectApcSwitch = (station: TStation) => { const connectApcSwitch = (station: TStation) => {
if (!station?.is_active) return;
if (station?.apc_1_ip && station?.apc_1_port) { if (station?.apc_1_ip && station?.apc_1_port) {
socket?.emit("connect_apc", { socket?.emit("connect_apc", {
station: station, station: station,

View File

@ -187,6 +187,7 @@ const BottomToolBar = ({
</Tabs.List> </Tabs.List>
<Tabs.Panel <Tabs.Panel
className={!station?.is_active ? classes.isDisabled : ""}
value="command" value="command"
p={4} p={4}
style={{ height: "200px", overflow: "auto" }} style={{ height: "200px", overflow: "auto" }}
@ -423,6 +424,7 @@ const BottomToolBar = ({
</Flex> </Flex>
</Tabs.Panel> </Tabs.Panel>
<Tabs.Panel <Tabs.Panel
className={!station?.is_active ? classes.isDisabled : ""}
value="apc" value="apc"
p={0} p={0}
ps={"xs"} ps={"xs"}
@ -448,6 +450,7 @@ const BottomToolBar = ({
</Box> </Box>
</Tabs.Panel> </Tabs.Panel>
<Tabs.Panel <Tabs.Panel
className={!station?.is_active ? classes.isDisabled : ""}
value="switch" value="switch"
ps={"xs"} ps={"xs"}
style={{ style={{
@ -467,7 +470,10 @@ const BottomToolBar = ({
</Tabs.Panel> </Tabs.Panel>
</Tabs> </Tabs>
) : ( ) : (
<Box p={3}> <Box
p={3}
className={!station?.is_active ? classes.isDisabled : ""}
>
<Flex <Flex
direction="row" direction="row"
align="center" align="center"

View File

@ -128,7 +128,9 @@ const CardLine = ({
shadow="sm" shadow="sm"
radius="md" radius="md"
withBorder withBorder
className={classes.card_line} className={`${classes.card_line} ${
!stationItem?.is_active ? classes.isDisabled : ""
}`}
style={{ style={{
...(selectedLines.find((val) => val.id === line.id) ...(selectedLines.find((val) => val.id === line.id)
? { backgroundColor: "#8bf55940" } ? { backgroundColor: "#8bf55940" }

View File

@ -107,7 +107,12 @@ function SortableTab({
c="#747474" c="#747474"
> >
<Box className={classes.stationName}> <Box className={classes.stationName}>
<Text fw={600} fz="md" className={classes.stationText}> <Text
fw={600}
fz="md"
className={classes.stationText}
c={!tab?.is_active ? `red` : ""}
>
{tab.name} {tab.name}
</Text> </Text>
</Box> </Box>

View File

@ -441,54 +441,59 @@ export const DrawerAPCControl: React.FC<DrawerProps> = ({
gap: "10px", gap: "10px",
paddingTop: "8px", paddingTop: "8px",
paddingBottom: "8px", paddingBottom: "8px",
minHeight: "60px",
}} }}
> >
{listOutlet {dataStation?.apc_1_ip
.filter((el) => el.apc === 1) ? listOutlet
.map((outlet, i) => ( .filter((el) => el.apc === 1)
<Card .map((outlet, i) => (
key={i} <Card
shadow="sm" key={i}
padding="xs" shadow="sm"
radius="md" padding="xs"
withBorder radius="md"
className={`${ withBorder
isSubmit || !dataStation?.apc_1_ip className={`${
? classes.isDisabled isSubmit || !dataStation?.apc_1_ip
: "" ? classes.isDisabled
}`} : ""
style={{ }`}
paddingLeft: 0, style={{
paddingRight: 0, paddingLeft: 0,
width: "55px", paddingRight: 0,
position: "relative", width: "55px",
cursor: "pointer", position: "relative",
textAlign: "center", cursor: "pointer",
border: listOutletSelected.find( textAlign: "center",
(el) => el.name === outlet.name && el.apc === outlet.apc border: listOutletSelected.find(
)?.name (el) =>
? "1px solid #0018ff" el.name === outlet.name && el.apc === outlet.apc
: "", )?.name
}} ? "1px solid #0018ff"
onClick={() => { : "",
toggleSelect(outlet, i + 1); }}
}} onClick={() => {
> toggleSelect(outlet, i + 1);
<Text }}
fw={500} >
fz={"12px"} <Text
style={{ fw={500}
color: outlet.status === "ON" ? "#40c057" : "#f03e3e", fz={"12px"}
}} style={{
> color:
{findLineByOutlet(outlet) outlet.status === "ON" ? "#40c057" : "#f03e3e",
? "Line " + }}
(findLineByOutlet(outlet)?.lineNumber || >
findLineByOutlet(outlet)?.line_number) {findLineByOutlet(outlet)
: outlet.name} ? "Line " +
</Text> (findLineByOutlet(outlet)?.lineNumber ||
</Card> findLineByOutlet(outlet)?.line_number)
))} : outlet.name}
</Text>
</Card>
))
: ""}
</Box> </Box>
</Box> </Box>
</fieldset> </fieldset>
@ -674,54 +679,59 @@ export const DrawerAPCControl: React.FC<DrawerProps> = ({
gap: "10px", gap: "10px",
paddingTop: "8px", paddingTop: "8px",
paddingBottom: "8px", paddingBottom: "8px",
minHeight: "60px",
}} }}
> >
{listOutlet {dataStation?.apc_2_ip
.filter((el) => el.apc === 2) ? listOutlet
.map((outlet, i) => ( .filter((el) => el.apc === 2)
<Card .map((outlet, i) => (
key={i} <Card
shadow="sm" key={i}
padding="xs" shadow="sm"
radius="md" padding="xs"
withBorder radius="md"
className={`${ withBorder
isSubmit || !dataStation?.apc_2_ip className={`${
? classes.isDisabled isSubmit || !dataStation?.apc_2_ip
: "" ? classes.isDisabled
}`} : ""
style={{ }`}
paddingLeft: 0, style={{
paddingRight: 0, paddingLeft: 0,
width: "55px", paddingRight: 0,
position: "relative", width: "55px",
cursor: "pointer", position: "relative",
textAlign: "center", cursor: "pointer",
border: listOutletSelected.find( textAlign: "center",
(el) => el.name === outlet.name && el.apc === outlet.apc border: listOutletSelected.find(
)?.name (el) =>
? "1px solid #0018ff" el.name === outlet.name && el.apc === outlet.apc
: "", )?.name
}} ? "1px solid #0018ff"
onClick={() => { : "",
toggleSelect(outlet, i + 1); }}
}} onClick={() => {
> toggleSelect(outlet, i + 1);
<Text }}
fw={500} >
fz={"12px"} <Text
style={{ fw={500}
color: outlet.status === "ON" ? "#40c057" : "#f03e3e", fz={"12px"}
}} style={{
> color:
{findLineByOutlet(outlet) outlet.status === "ON" ? "#40c057" : "#f03e3e",
? "Line " + }}
(findLineByOutlet(outlet)?.lineNumber || >
findLineByOutlet(outlet)?.line_number) {findLineByOutlet(outlet)
: outlet.name} ? "Line " +
</Text> (findLineByOutlet(outlet)?.lineNumber ||
</Card> findLineByOutlet(outlet)?.line_number)
))} : outlet.name}
</Text>
</Card>
))
: ""}
</Box> </Box>
</Box> </Box>
</fieldset> </fieldset>
@ -1169,7 +1179,7 @@ export const DrawerSwitchControl: React.FC<DrawerProps> = ({
</div> </div>
<Grid.Col span={12} pt={"0px"}> <Grid.Col span={12} pt={"0px"}>
{listPorts?.length > 0 && ( {dataStation?.switch_control_ip && listPorts?.length > 0 && (
<Box> <Box>
<Flex gap={"8px"} wrap={"wrap"}> <Flex gap={"8px"} wrap={"wrap"}>
{listPorts?.map((group, key) => { {listPorts?.map((group, key) => {

View File

@ -82,7 +82,7 @@ const StationSetting = ({
form.setFieldValue("apc_2_password", dataStation.apc_2_password); form.setFieldValue("apc_2_password", dataStation.apc_2_password);
form.setFieldValue("switch_control_ip", dataStation.switch_control_ip); form.setFieldValue("switch_control_ip", dataStation.switch_control_ip);
form.setFieldValue("send_wiki", dataStation?.send_wiki); form.setFieldValue("send_wiki", dataStation?.send_wiki);
// form.setFieldValue("is_active", dataStation?.is_active); form.setFieldValue("is_active", dataStation?.is_active);
form.setFieldValue( form.setFieldValue(
"switch_control_port", "switch_control_port",
dataStation.switch_control_port dataStation.switch_control_port
@ -403,7 +403,7 @@ const StationSetting = ({
form.setFieldValue("send_wiki", event.currentTarget.checked) form.setFieldValue("send_wiki", event.currentTarget.checked)
} }
/> />
{/* <Checkbox <Checkbox
c={"yellow"} c={"yellow"}
color="yellow" color="yellow"
ml={"12px"} ml={"12px"}
@ -412,7 +412,7 @@ const StationSetting = ({
onChange={(event) => onChange={(event) =>
form.setFieldValue("is_active", event.currentTarget.checked) form.setFieldValue("is_active", event.currentTarget.checked)
} }
/> */} />
</div> </div>
} }
size={"90%"} size={"90%"}