From 7064ec8587fc6c88551bbdd1e5ab74924e0ac94c Mon Sep 17 00:00:00 2001 From: bragaz_rexita Date: Mon, 10 Nov 2025 14:56:08 +0700 Subject: [PATCH 1/3] Repair and add overview air dryer compressor --- src/assets/svg/overview-airdryer.svg | 443 ++++++++++++++++++ src/assets/svg/overview-compressor.svg | 251 ++++++++++ ...vgOverview.jsx => SvgOverviewAirDryer.jsx} | 6 +- src/pages/home/SvgOverviewCompressor.jsx | 21 + 4 files changed, 718 insertions(+), 3 deletions(-) create mode 100644 src/assets/svg/overview-airdryer.svg create mode 100644 src/assets/svg/overview-compressor.svg rename src/pages/home/{SvgOverview.jsx => SvgOverviewAirDryer.jsx} (79%) create mode 100644 src/pages/home/SvgOverviewCompressor.jsx diff --git a/src/assets/svg/overview-airdryer.svg b/src/assets/svg/overview-airdryer.svg new file mode 100644 index 0000000..698f30b --- /dev/null +++ b/src/assets/svg/overview-airdryer.svg @@ -0,0 +1,443 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + AirDryer A + + On/Off + H + #### + + + + AirDryer B + + On/Off + H + #### + + + + AirDryer C + + On/Off + H + #### + + + + + + + + + + + + + + + + + + + + + + + + + + + PLC AirDryer + IP : 192.168.0.3 + + + PC Station + IP : 192.168.0.2 + + + + + + + + + + + + + + + + + + + + + + PC Server + IP : xxx.xxx.xx.xx + OVERVIEW AIR DRYER + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/assets/svg/overview-compressor.svg b/src/assets/svg/overview-compressor.svg new file mode 100644 index 0000000..7741e04 --- /dev/null +++ b/src/assets/svg/overview-compressor.svg @@ -0,0 +1,251 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + COMPRESSOR A + + On/Off + H + #### + + + + COMPRESSOR B + + On/Off + H + #### + + + + COMPRESSOR C + + On/Off + H + #### + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + PLC Compressor + IP : 192.168.0.1 + + + PC Station + IP : 192.168.0.2 + + + + + + + + + + + + + + + + + + + + + + PC Server + IP : xxx.xxx.xx.xx + OVERVIEW COMPRESSOR + + \ No newline at end of file diff --git a/src/pages/home/SvgOverview.jsx b/src/pages/home/SvgOverviewAirDryer.jsx similarity index 79% rename from src/pages/home/SvgOverview.jsx rename to src/pages/home/SvgOverviewAirDryer.jsx index 5c7bf83..c3c7181 100644 --- a/src/pages/home/SvgOverview.jsx +++ b/src/pages/home/SvgOverviewAirDryer.jsx @@ -3,14 +3,14 @@ import { Card, Typography, Flex } from 'antd'; import { setValSvg } from '../../components/Global/MqttConnection'; import SvgTemplate from './SvgTemplate'; import SvgViewer from './SvgViewer'; -import filePathSvg from '../../assets/svg/test-new.svg'; +import filePathSvg from '../../assets/svg/overview-airdryer.svg'; const { Text } = Typography; // const filePathSvg = '/src/assets/svg/test-new.svg'; const topicMqtt = 'PIU_GGCP/Devices/PB'; -const SvgOverview = () => { +const SvgOverviewAirDryer = () => { return ( @@ -18,4 +18,4 @@ const SvgOverview = () => { ); }; -export default SvgOverview; +export default SvgOverviewAirDryer; diff --git a/src/pages/home/SvgOverviewCompressor.jsx b/src/pages/home/SvgOverviewCompressor.jsx new file mode 100644 index 0000000..ad505e0 --- /dev/null +++ b/src/pages/home/SvgOverviewCompressor.jsx @@ -0,0 +1,21 @@ +import { useEffect, useState } from 'react'; +import { Card, Typography, Flex } from 'antd'; +import { setValSvg } from '../../components/Global/MqttConnection'; +import SvgTemplate from './SvgTemplate'; +import SvgViewer from './SvgViewer'; +import filePathSvg from '../../assets/svg/overview-compressor.svg'; + +const { Text } = Typography; + +// const filePathSvg = '/src/assets/svg/test-new.svg'; +const topicMqtt = 'PIU_GGCP/Devices/PB'; + +const SvgOverviewCompressor = () => { + return ( + + + + ); +}; + +export default SvgOverviewCompressor; -- 2.49.1 From 5952858dca2b132f7e0423751e3db1a4ce4151de Mon Sep 17 00:00:00 2001 From: bragaz_rexita Date: Mon, 10 Nov 2025 14:56:31 +0700 Subject: [PATCH 2/3] Repair sub menu air dryer and compressor --- src/layout/LayoutMenu.jsx | 174 ++++++++++++++++++++++++++------------ 1 file changed, 119 insertions(+), 55 deletions(-) diff --git a/src/layout/LayoutMenu.jsx b/src/layout/LayoutMenu.jsx index d0d5cfc..c0f12f0 100644 --- a/src/layout/LayoutMenu.jsx +++ b/src/layout/LayoutMenu.jsx @@ -51,39 +51,58 @@ const allItems = [ label: 'Dashboard', children: [ { - key: 'dashboard-svg-overview', + key: 'dashboard-svg-compressor', icon: , - label: Overview, + label: 'Compressor', + children: [ + { + key: 'dashboard-svg-compressor-overview', + icon: , + label: Overview, + }, + { + key: 'dashboard-svg-compressor-compressor-a', + icon: , + label: Compressor A, + }, + { + key: 'dashboard-svg-compressor-compressor-b', + icon: , + label: Compressor B, + }, + { + key: 'dashboard-svg-compressor-compressor-c', + icon: , + label: Compressor C, + }, + ] }, { - key: 'dashboard-svg-compressor-a', + key: 'dashboard-svg-airdryer', icon: , - label: Compressor A, - }, - { - key: 'dashboard-svg-compressor-b', - icon: , - label: Compressor B, - }, - { - key: 'dashboard-svg-compressor-c', - icon: , - label: Compressor C, - }, - { - key: 'dashboard-svg-airdryer-a', - icon: , - label: Air Dryer A, - }, - { - key: 'dashboard-svg-airdryer-b', - icon: , - label: Air Dryer B, - }, - { - key: 'dashboard-svg-airdryer-c', - icon: , - label: Air Dryer C, + label: 'Air Dryer', + children: [ + { + key: 'dashboard-svg-airdryer-overview', + icon: , + label: Overview, + }, + { + key: 'dashboard-svg-airdryer-airdryer-a', + icon: , + label: Air Dryer A, + }, + { + key: 'dashboard-svg-airdryer-airdryer-b', + icon: , + label: Air Dryer B, + }, + { + key: 'dashboard-svg-airdryer-airdryer-c', + icon: , + label: Air Dryer C, + }, + ] }, ], }, @@ -221,37 +240,77 @@ const LayoutMenu = () => { // Handle master routes if (pathname.startsWith('/master/')) { const subPath = pathParts[1]; - return `master-${subPath}`; + // Convert kebab-case to the actual menu keys + const masterKeyMap = { + 'plant-sub-section': 'master-plant-sub-section', + 'brand-device': 'master-brand-device', + 'device': 'master-device', + 'unit': 'master-unit', + 'tag': 'master-tag', + 'status': 'master-status', + 'shift': 'master-shift' + }; + return masterKeyMap[subPath] || `master-${subPath}`; } // Handle dashboard svg routes if (pathname.startsWith('/dashboard-svg/')) { const subPath = pathParts[1]; + // Map specific routes to their menu keys + if (subPath === 'overview-compressor') return 'dashboard-svg-compressor-overview'; + if (subPath === 'compressor-a') return 'dashboard-svg-compressor-compressor-a'; + if (subPath === 'compressor-b') return 'dashboard-svg-compressor-compressor-b'; + if (subPath === 'compressor-c') return 'dashboard-svg-compressor-compressor-c'; + if (subPath === 'overview-airdryer') return 'dashboard-svg-airdryer-overview'; + if (subPath === 'airdryer-a') return 'dashboard-svg-airdryer-airdryer-a'; + if (subPath === 'airdryer-b') return 'dashboard-svg-airdryer-airdryer-b'; + if (subPath === 'airdryer-c') return 'dashboard-svg-airdryer-airdryer-c'; + return `dashboard-svg-${subPath}`; } // Handle report routes if (pathname.startsWith('/report/')) { const subPath = pathParts[1]; - return `report-${subPath}`; + const reportKeyMap = { + 'trending': 'report-trending', + 'report': 'report-report' + }; + return reportKeyMap[subPath] || `report-${subPath}`; } // Handle history routes if (pathname.startsWith('/history/')) { const subPath = pathParts[1]; - return `history-${subPath}`; + const historyKeyMap = { + 'alarm': 'history-alarm', + 'event': 'history-event' + }; + return historyKeyMap[subPath] || `history-${subPath}`; } return 'home'; // default }; - // Function to get parent key from menu key - const getParentKey = (key) => { - if (key.startsWith('master-')) return 'master'; - if (key.startsWith('dashboard-svg-')) return 'dashboard-svg'; - if (key.startsWith('report-')) return 'report'; - if (key.startsWith('history-')) return 'history'; - return null; + // Function to get parent keys from menu key + const getParentKeys = (key) => { + const parentKeys = []; + + if (key.startsWith('dashboard-svg-compressor-')) { + parentKeys.push('dashboard-svg', 'dashboard-svg-compressor'); + } else if (key.startsWith('dashboard-svg-airdryer-')) { + parentKeys.push('dashboard-svg', 'dashboard-svg-airdryer'); + } else if (key.startsWith('dashboard-svg-')) { + parentKeys.push('dashboard-svg'); + } else if (key.startsWith('master-')) { + parentKeys.push('master'); + } else if (key.startsWith('report-')) { + parentKeys.push('report'); + } else if (key.startsWith('history-')) { + parentKeys.push('history'); + } + + return parentKeys; }; // Update selected and open keys when route changes @@ -259,11 +318,11 @@ const LayoutMenu = () => { const currentKey = getMenuKeyFromPath(location.pathname); setSelectedKeys([currentKey]); - const parentKey = getParentKey(currentKey); - - // If current menu has parent, open it. Otherwise, close all dropdowns - if (parentKey) { - setStateOpenKeys([parentKey]); + const parentKeys = getParentKeys(currentKey); + + // Always keep the parent menus open when a child is selected + if (parentKeys.length > 0) { + setStateOpenKeys(parentKeys); } else { setStateOpenKeys([]); } @@ -289,17 +348,30 @@ const LayoutMenu = () => { const onOpenChange = (openKeys) => { const currentOpenKey = openKeys.find((key) => stateOpenKeys.indexOf(key) === -1); + + // If clicking on a menu that was previously closed if (currentOpenKey !== undefined) { const repeatIndex = openKeys .filter((key) => key !== currentOpenKey) .findIndex((key) => levelKeys[key] === levelKeys[currentOpenKey]); + setStateOpenKeys( openKeys .filter((_, index) => index !== repeatIndex) .filter((key) => levelKeys[key] <= levelKeys[currentOpenKey]) ); } else { - setStateOpenKeys(openKeys); + // If clicking on a menu that was previously open, close only that menu + // but keep other parent menus open if they have active children + const currentKey = getMenuKeyFromPath(location.pathname); + const necessaryParentKeys = getParentKeys(currentKey); + + // Filter out only the menus that are necessary to keep open + const filteredOpenKeys = openKeys.filter(key => + necessaryParentKeys.includes(key) + ); + + setStateOpenKeys(filteredOpenKeys); } }; @@ -310,25 +382,17 @@ const LayoutMenu = () => { return allItems .filter( (item) => item.key !== 'setting' - // tambahkan menu jika terdapat menu yang di sembunyikan dari user karyawan - // && item.key !== 'master' - // && item.key !== 'master' ) .map((item) => { if (item.key === 'master') { return { ...item, - // buka command dibawah jika terdapat sub menu yang di sembunyikan - // children: item.children.filter( - // child => child.key !== 'master-product' - // tambahkan menu jika terdapat menu yang di sembunyikan dari user karyawan - // && child.key !== 'master-service' - // ) }; } return item; }); }; + const items = isAdmin === 1 ? allItems : karyawan(); return ( @@ -348,4 +412,4 @@ const LayoutMenu = () => { /> ); }; -export default LayoutMenu; +export default LayoutMenu; \ No newline at end of file -- 2.49.1 From 0916ea7103e7f70e3c6e11a44d7f78ac3d399571 Mon Sep 17 00:00:00 2001 From: bragaz_rexita Date: Mon, 10 Nov 2025 14:56:52 +0700 Subject: [PATCH 3/3] Repair file route air dryer and cmpressor --- src/App.jsx | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/App.jsx b/src/App.jsx index 1ad3150..ddaac6d 100644 --- a/src/App.jsx +++ b/src/App.jsx @@ -35,10 +35,11 @@ import IndexRole from './pages/role/IndexRole'; import IndexUser from './pages/user/IndexUser'; import SvgTest from './pages/home/SvgTest'; -import SvgOverview from './pages/home/SvgOverview'; +import SvgOverviewCompressor from './pages/home/SvgOverviewCompressor'; import SvgCompressorA from './pages/home/SvgCompressorA'; import SvgCompressorB from './pages/home/SvgCompressorB'; import SvgCompressorC from './pages/home/SvgCompressorC'; +import SvgOverviewAirDryer from './pages/home/SvgOverviewAirDryer'; import SvgAirDryerA from './pages/home/SvgAirDryerA'; import SvgAirDryerB from './pages/home/SvgAirDryerB'; import SvgAirDryerC from './pages/home/SvgAirDryerC'; @@ -63,10 +64,11 @@ const App = () => { }> - } /> + } /> } /> } /> } /> + } /> } /> } /> } /> -- 2.49.1