@dexteel/mesf-core 7.15.3 → 7.16.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -7,28 +7,39 @@ on:
7
7
  - next
8
8
  - next-ng
9
9
  - v7
10
+ workflow_dispatch: # Allow manual trigger from any branch
11
+
12
+ permissions:
13
+ contents: read
14
+ id-token: write # Required for npm Trusted Publishing (OIDC)
15
+
10
16
  jobs:
11
17
  publish:
12
- if: github.event.pull_request.merged == true && startsWith(github.event.pull_request.head.ref, 'release-please')
18
+ if: >-
19
+ github.event_name == 'workflow_dispatch' ||
20
+ (github.event.pull_request.merged == true && startsWith(github.event.pull_request.head.ref, 'release-please'))
13
21
  runs-on: ubuntu-latest
14
22
  steps:
15
23
  - uses: actions/checkout@v4
16
24
  - name: Setup Node.js
17
25
  uses: actions/setup-node@v4
18
26
  with:
19
- node-version: 'lts/hydrogen' # Adjust this to your Node.js version
20
- registry-url: 'https://registry.npmjs.org'
27
+ node-version: 'lts/jod' # Node 22 LTS
28
+ - name: Upgrade npm for Trusted Publishing
29
+ run: |
30
+ npm install -g npm@latest
31
+ npm --version
32
+ npm config set registry https://registry.npmjs.org/
21
33
  - name: Install dependencies
22
34
  run: npm install
23
35
  - name: Build
24
36
  run: npm run build
25
37
  - name: Publish to npm
26
38
  run: npm publish
27
- env:
28
- NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
39
+ # No NODE_AUTH_TOKEN needed — uses OIDC Trusted Publishing
29
40
  - name: Read package.json version
30
41
  id: package-version
31
- run: echo "::set-output name=version::$(node -p "require('./package.json').version")"
42
+ run: echo "version=$(node -p "require('./package.json').version")" >> "$GITHUB_OUTPUT"
32
43
  - name: Push Notification to Google Workspace
33
44
  run: |
34
45
  curl -X POST "https://chat.googleapis.com/v1/spaces/AAAA4hvxkZc/messages?key=AIzaSyDdI0hCZtE6vySjMm-WEfRq3CPzqKqqsHI&token=_DSEU_3n-CC5ZDK2nKNfabm2X_M_IcIAqQxenkYgDZk" \
@@ -1,3 +1,3 @@
1
1
  {
2
- ".": "7.15.3"
2
+ ".": "7.16.1"
3
3
  }
package/CHANGELOG.md CHANGED
@@ -1,5 +1,26 @@
1
1
  # Changelog
2
2
 
3
+ ## [7.16.1](https://github.com/dexteel/mesf-core-frontend/compare/@dexteel/mesf-core-v7.16.0...@dexteel/mesf-core-v7.16.1) (2026-03-24)
4
+
5
+
6
+ ### Bug Fixes
7
+
8
+ * migrate npm publish to OIDC Trusted Publishing and update docs ([e759e41](https://github.com/dexteel/mesf-core-frontend/commit/e759e41ed5ccaa535fc79a92f162e934b46a60ad))
9
+
10
+ ## [7.16.0](https://github.com/dexteel/mesf-core-frontend/compare/@dexteel/mesf-core-v7.15.4...@dexteel/mesf-core-v7.16.0) (2026-03-24)
11
+
12
+
13
+ ### Features
14
+
15
+ * enhance navbar experience ([06626e9](https://github.com/dexteel/mesf-core-frontend/commit/06626e9b2fe1b93127771af2eb1dc74b1c2c6cf3))
16
+
17
+ ## [7.15.4](https://github.com/dexteel/mesf-core-frontend/compare/@dexteel/mesf-core-v7.15.3...@dexteel/mesf-core-v7.15.4) (2026-03-24)
18
+
19
+
20
+ ### Bug Fixes
21
+
22
+ * share reusable navbar menubar behavior ([#628](https://github.com/dexteel/mesf-core-frontend/issues/628)) ([3156cf2](https://github.com/dexteel/mesf-core-frontend/commit/3156cf28acfa9d2dc0cffde9ab779b14c59d6c4f))
23
+
3
24
  ## [7.15.3](https://github.com/dexteel/mesf-core-frontend/compare/@dexteel/mesf-core-v7.15.2...@dexteel/mesf-core-v7.15.3) (2026-03-10)
4
25
 
5
26
 
package/CLAUDE.md CHANGED
@@ -11,7 +11,8 @@ This file provides guidance to Claude Code (claude.ai/code) when working with co
11
11
 
12
12
  ### Code Quality
13
13
  - `npx @biomejs/biome check --write ./src` - Format and organize imports with Biome
14
- - Pre-commit hook automatically runs Biome formatting on staged files
14
+ - `npm run type-check` - Run TypeScript type checking without emitting
15
+ - Pre-commit hook (via Husky) automatically runs Biome formatting on staged files
15
16
 
16
17
  ## Architecture Overview
17
18
 
@@ -40,7 +41,7 @@ This is `@dexteel/mesf-core`, a React component library built as an NPM package
40
41
 
41
42
  - **src/components/** - Reusable UI components organized by domain
42
43
  - `navigation/` - Header, menu components
43
- - `modals/` - Dialog components
44
+ - `modals/` - Dialog components
44
45
  - `shared/` - Common utility components
45
46
 
46
47
  - **src/configuration/** - Admin and configuration modules
@@ -57,30 +58,41 @@ This is `@dexteel/mesf-core`, a React component library built as an NPM package
57
58
  - **src/services/** - API communication layer
58
59
  - **src/utils/** - Utility functions and helpers
59
60
  - **src/controls/** - Form controls and input components
61
+ - **src/models/** - TypeScript type definitions and interfaces
62
+ - **src/pages/** - Page-level components
63
+ - **src/routes/** - Route configuration
64
+ - **src/reducers/** - Redux reducers
65
+ - **src/account/** - Account-related components
66
+ - **src/helmet/** - React Helmet (meta tag) management
67
+ - **src/css/** - Stylesheets and theme configuration
60
68
 
61
69
  ### Technology Stack
62
70
 
63
- **Core Framework**: React 17 with TypeScript
64
- **Build Tool**: Rollup with TypeScript plugin
65
- **Styling**: Material-UI v4 with custom theme support
71
+ **Core Framework**: React 18 with TypeScript 5
72
+ **Build Tool**: Rollup 2 with rollup-plugin-typescript2
73
+ **Styling**: MUI v6 (`@mui/material`, `@mui/lab`, `@mui/styles`) with Emotion
66
74
  **State**: Redux Toolkit for complex state, React Context for simpler state
67
- **Authentication**: Azure MSAL for Microsoft authentication
68
- **Data Visualization**: Nivo charts, Chart.js with react-chartjs-2
69
- **Grid Component**: AG Grid (Enterprise features available)
70
- **Date Handling**: Moment.js with timezone support
75
+ **Authentication**: Azure MSAL (`@azure/msal-browser`, `@azure/msal-react`)
76
+ **Data Visualization**: Chart.js 4 with react-chartjs-2, ECharts 6
77
+ **Grid Component**: AG Grid 33 (Community + Enterprise), MUI X Data Grid v7
78
+ **Date Handling**: Moment.js with moment-timezone, date-fns-tz
79
+ **Routing**: React Router DOM v6
80
+ **Real-time**: SignalR 8 (`@microsoft/signalr`)
71
81
 
72
82
  ### Key Dependencies
73
83
 
74
84
  The library has extensive peer dependencies that consuming applications must provide:
75
- - Material-UI components and theming
76
- - AG Grid for data tables
77
- - Chart libraries (Nivo, Chart.js)
78
- - React Router DOM for navigation
79
- - Redux Toolkit for state management
85
+ - MUI v6 components, icons, lab, styles, and Emotion styling
86
+ - MUI X v7 (Data Grid, Date Pickers, Tree View)
87
+ - AG Grid 33 (Community + Enterprise + React bindings)
88
+ - React 18 and React DOM 18
89
+ - React Router DOM v6
90
+ - Redux Toolkit
91
+ - date-fns (v3 or v4)
80
92
 
81
93
  ### Development Notes
82
94
 
83
- **Styling**: Uses Material-UI v4 theming system. Custom theme exports available via `src/css/themeMESF`.
95
+ **Styling**: Uses MUI v6 theming system with Emotion. Custom theme exports available via `src/css/themeMESF`.
84
96
 
85
97
  **Internationalization**: Components support timezone handling via `moment-timezone` and `date-fns-tz`.
86
98
 
package/README.md CHANGED
@@ -1,19 +1,76 @@
1
- # For Changing passwords, mesf-core is needed:
2
- https://github.com/dexteel/mesf-core/commit/02877a88ab283f2a64cd1a0bc85bdb7c099935f2
1
+ # @dexteel/mesf-core
3
2
 
4
- # How to install project in subfolders
3
+ A React component library for Dexteel Manufacturing Execution Systems (MES). Provides shared UI components, context providers, services, hooks, and utilities used across Dexteel frontend applications.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ npm install @dexteel/mesf-core
9
+ ```
10
+
11
+ ### Peer Dependencies
12
+
13
+ This library requires the consuming application to provide the following:
14
+
15
+ ```json
16
+ {
17
+ "@emotion/react": "^11.14.0",
18
+ "@emotion/styled": "^11.14.1",
19
+ "@mui/icons-material": "latest-v6",
20
+ "@mui/lab": "latest-v6",
21
+ "@mui/material": "latest-v6",
22
+ "@mui/styles": "latest-v6",
23
+ "@mui/x-data-grid": "latest-v7",
24
+ "@mui/x-date-pickers": "latest-v7",
25
+ "@mui/x-tree-view": "latest-v7",
26
+ "@react-spring/web": "^9.7.5",
27
+ "@reduxjs/toolkit": "^1.6.2",
28
+ "ag-grid-community": "^33.3.1",
29
+ "ag-grid-enterprise": "^33.3.1",
30
+ "ag-grid-react": "^33.3.1",
31
+ "date-fns": "^3.0.0 || ^4.0.0",
32
+ "moment": "^2.29.1",
33
+ "react": "^18.3.1",
34
+ "react-dom": "^18.3.1",
35
+ "react-router-dom": "^6.30.1"
36
+ }
37
+ ```
38
+
39
+ ## Development
40
+
41
+ ```bash
42
+ # Install dependencies
43
+ npm install
44
+
45
+ # Build for production
46
+ npm run build
47
+
48
+ # Build in watch mode
49
+ npm run watch
50
+ # or
51
+ npm start
52
+
53
+ # Type checking
54
+ npm run type-check
55
+
56
+ # Format and organize imports
57
+ npx @biomejs/biome check --write ./src
58
+ ```
59
+
60
+ ## Deploying in Subfolders
61
+
62
+ When deploying a consuming application into a subfolder, edit the following file in the deployed build:
5
63
 
6
- In deployed version, edit the following file:
7
64
  ```
8
65
  DEPLOY_FOLDER/ClientApp/dist/index.html
9
66
  ```
10
- Change the ``<base />`` tag to the desired base url
11
67
 
12
- ![img.png](img.png)
13
- ## DON'T FORGET THE TRAILING SLASH
14
- ## EXAMPLES:
15
- - ``<base href="/" />`` (default)
16
- - ``<base href="/old/" />``
17
- - ``<base href="/testing/" />``
18
- - ``<base href="/old/testing/" />``
68
+ Change the `<base />` tag to the desired base URL.
69
+
70
+ **Important:** Always include a trailing slash.
19
71
 
72
+ Examples:
73
+ - `<base href="/" />` (default)
74
+ - `<base href="/old/" />`
75
+ - `<base href="/testing/" />`
76
+ - `<base href="/old/testing/" />`
@@ -1,10 +1,11 @@
1
1
  import React, { type ReactNode } from "react";
2
+ import type { NavbarRendererProps } from "./components/navigation/NavbarMenuBar";
2
3
  import { ConfigurationsType } from "./configurationMenu";
3
4
  import type { LogbookSettingsState } from "./reducers/LogbookSettingsReducer";
4
5
  interface Props {
5
6
  authentication: any;
6
7
  routes: () => ReactNode;
7
- navbar: () => ReactNode;
8
+ navbar: React.ComponentType<NavbarRendererProps>;
8
9
  navbarTitle?: string;
9
10
  configurations: ConfigurationsType;
10
11
  showAreaSelector?: boolean;
@@ -0,0 +1,25 @@
1
+ import React from "react";
2
+ import { type LinkProps } from "react-router-dom";
3
+ type To = LinkProps["to"];
4
+ export interface NavbarMenuItemConfig {
5
+ label: string;
6
+ to: To;
7
+ permission?: string;
8
+ }
9
+ export interface NavbarMenuConfig {
10
+ id: string;
11
+ label: string;
12
+ to?: To;
13
+ items: NavbarMenuItemConfig[];
14
+ permission?: string;
15
+ }
16
+ export interface NavbarRendererProps {
17
+ isMobile?: boolean;
18
+ closeDrawer?: () => void;
19
+ }
20
+ interface NavbarMenuBarProps extends NavbarRendererProps {
21
+ menus: NavbarMenuConfig[];
22
+ hoverSwitchDelayMs?: number;
23
+ }
24
+ export declare function NavbarMenuBar({ menus, isMobile, closeDrawer, hoverSwitchDelayMs, }: NavbarMenuBarProps): React.JSX.Element;
25
+ export {};
@@ -1,6 +1,7 @@
1
1
  import React, { type ReactNode } from "react";
2
+ import type { NavbarRendererProps } from "./components/navigation/NavbarMenuBar";
2
3
  import { ConfigurationsType } from "./configurationMenu";
3
4
  declare const RouterContext: React.Context<() => ReactNode>;
4
5
  declare const ConfigurationContext: React.Context<ConfigurationsType>;
5
- declare const NavbarContext: React.Context<() => ReactNode>;
6
+ declare const NavbarContext: React.Context<React.ComponentType<NavbarRendererProps>>;
6
7
  export { RouterContext, ConfigurationContext, NavbarContext };
package/dist/index.d.ts CHANGED
@@ -3,6 +3,7 @@ export { LicenseManager } from "ag-grid-enterprise";
3
3
  export * from "./account";
4
4
  export * from "./components/modals/error-modal";
5
5
  export * from "./components/modals/modal.mesf";
6
+ export * from "./components/navigation/NavbarMenuBar";
6
7
  export * from "./components/navigation/TimeAndUserMenu";
7
8
  export * from "./components/shared/buttons/button-with-loading";
8
9
  export { ExcelIcon } from "./components/shared/icons/ExcelIcon";
package/dist/index.esm.js CHANGED
@@ -1,7 +1,7 @@
1
1
  import { HubConnectionBuilder, LogLevel } from '@microsoft/signalr';
2
2
  export * from '@microsoft/signalr';
3
3
  export { LicenseManager } from 'ag-grid-enterprise';
4
- import { styled, DialogTitle as DialogTitle$1, DialogContent as DialogContent$1, DialogActions as DialogActions$1, Grid2, Button, Box, MenuItem, ListItemIcon, createTheme, TextField, Alert as Alert$2, useTheme, InputAdornment, Popover, MenuList, ListItemText, alpha, Dialog as Dialog$1, Paper, List, ListItem, Chip, SvgIcon, Typography as Typography$1, Checkbox, IconButton as IconButton$1, CircularProgress, FormControl, FormHelperText, FormControlLabel, Snackbar, DialogContentText, Badge, InputLabel, Select, Input, Divider, Card, CardContent, CardActions, Collapse, Tooltip, CssBaseline, AppBar, Toolbar, Container, Menu, Switch, Autocomplete, Hidden, Drawer, Grid, Accordion, AccordionSummary, AccordionDetails, Tabs, Tab, useMediaQuery, ListSubheader, ListItemButton, StyledEngineProvider, ThemeProvider, ListItemSecondaryAction } from '@mui/material';
4
+ import { styled, DialogTitle as DialogTitle$1, DialogContent as DialogContent$1, DialogActions as DialogActions$1, Grid2, Button, Box, MenuItem, ListItemIcon, createTheme, TextField, Alert as Alert$2, useTheme, InputAdornment, Popover, MenuList, ListItemText, alpha, Dialog as Dialog$1, Paper, List, ListItem, Chip, SvgIcon, Typography as Typography$1, Checkbox, IconButton as IconButton$1, CircularProgress, FormControl, FormHelperText, FormControlLabel, Snackbar, DialogContentText, Badge, InputLabel, Select, Input, Divider, Card, CardContent, CardActions, Collapse, Tooltip, CssBaseline, AppBar, Toolbar, Container, Menu, Switch, Autocomplete, useMediaQuery, Drawer, Grid, Accordion, AccordionSummary, AccordionDetails, Tabs, Tab, ListSubheader, ListItemButton, StyledEngineProvider, ThemeProvider, ListItemSecondaryAction } from '@mui/material';
5
5
  import { useMutation, useQuery, useQueryClient, QueryClient, QueryClientProvider } from '@tanstack/react-query';
6
6
  import * as React from 'react';
7
7
  import React__default, { createContext, useContext, useRef, useState, useEffect, useCallback, useMemo, Component, lazy, Suspense } from 'react';
@@ -25,7 +25,7 @@ import DeleteIcon from '@mui/icons-material/Delete';
25
25
  import EditIcon from '@mui/icons-material/Edit';
26
26
  import FindInPageIcon from '@mui/icons-material/FindInPage';
27
27
  import PlaylistAddIcon from '@mui/icons-material/PlaylistAdd';
28
- import { ArrowRight, ArrowBackRounded, ArrowForwardRounded, SkipNext, ChevronLeft, ChevronRight, Cloud, Square as Square$1, Timeline, Send, Menu as Menu$1, People, Storage, Group, Assignment, Chat, ViewList, Build, Settings as Settings$2, Code as Code$1, FastRewind, FastForward, ZoomIn, Restore, Lock, Create, Delete, Folder, InsertChart, Search, PlaylistAdd, DragIndicator, Save, AttachFile, CloudUpload, GetApp } from '@mui/icons-material';
28
+ import { ArrowRight, ArrowBackRounded, ArrowForwardRounded, SkipNext, ChevronLeft, ChevronRight, Cloud, ExpandLess, ExpandMore, Square as Square$1, Timeline, Send, Menu as Menu$1, People, Storage, Group, Assignment, Chat, ViewList, Build, Settings as Settings$2, Code as Code$1, FastRewind, FastForward, ZoomIn, Restore, Lock, Create, Delete, Folder, InsertChart, Search, PlaylistAdd, DragIndicator, Save, AttachFile, CloudUpload, GetApp } from '@mui/icons-material';
29
29
  import ContentCopyIcon from '@mui/icons-material/ContentCopy';
30
30
  import FormatListBulletedSharpIcon from '@mui/icons-material/FormatListBulletedSharp';
31
31
  import LockOutlinedIcon from '@mui/icons-material/LockOutlined';
@@ -6687,6 +6687,175 @@ function Logout() {
6687
6687
  React__default.createElement(Typography$1, { variant: "h6" }, "Logging out..."))));
6688
6688
  }
6689
6689
 
6690
+ function NavbarMenuBar({ menus, isMobile = false, closeDrawer, hoverSwitchDelayMs = 100, }) {
6691
+ const hasPermissionTo = useHasPermission();
6692
+ const [openMenuId, setOpenMenuId] = useState(null);
6693
+ const [menuAnchorEl, setMenuAnchorEl] = useState(null);
6694
+ const triggerRefs = useRef({});
6695
+ const hoverTimeoutRef = useRef(null);
6696
+ const visibleMenus = useMemo(() => {
6697
+ return menus
6698
+ .filter((menu) => !menu.permission || hasPermissionTo(menu.permission))
6699
+ .map((menu) => (Object.assign(Object.assign({}, menu), { items: menu.items.filter((item) => !item.permission || hasPermissionTo(item.permission)) })))
6700
+ .filter((menu) => menu.items.length > 0 || Boolean(menu.to));
6701
+ }, [hasPermissionTo, menus]);
6702
+ const clearHoverTimeout = () => {
6703
+ if (hoverTimeoutRef.current !== null) {
6704
+ window.clearTimeout(hoverTimeoutRef.current);
6705
+ hoverTimeoutRef.current = null;
6706
+ }
6707
+ };
6708
+ const focusTrigger = (menuId) => {
6709
+ var _a;
6710
+ (_a = triggerRefs.current[menuId]) === null || _a === void 0 ? void 0 : _a.focus();
6711
+ };
6712
+ const getAdjacentMenu = (menuId, direction) => {
6713
+ var _a;
6714
+ const currentIndex = visibleMenus.findIndex((menu) => menu.id === menuId);
6715
+ if (currentIndex === -1) {
6716
+ return null;
6717
+ }
6718
+ const nextIndex = (currentIndex + direction + visibleMenus.length) % visibleMenus.length;
6719
+ return (_a = visibleMenus[nextIndex]) !== null && _a !== void 0 ? _a : null;
6720
+ };
6721
+ const openMenu = (menuId, anchorEl) => {
6722
+ var _a;
6723
+ clearHoverTimeout();
6724
+ setOpenMenuId(menuId);
6725
+ setMenuAnchorEl((_a = anchorEl !== null && anchorEl !== void 0 ? anchorEl : triggerRefs.current[menuId]) !== null && _a !== void 0 ? _a : null);
6726
+ };
6727
+ const closeMenu = () => {
6728
+ clearHoverTimeout();
6729
+ setOpenMenuId(null);
6730
+ setMenuAnchorEl(null);
6731
+ };
6732
+ useEffect(() => () => clearHoverTimeout(), []);
6733
+ useEffect(() => {
6734
+ if (!openMenuId) {
6735
+ return;
6736
+ }
6737
+ const handlePointerDown = (event) => {
6738
+ const target = event.target;
6739
+ const trigger = triggerRefs.current[openMenuId];
6740
+ const menuPaper = document.querySelector(`#${openMenuId}-menu .MuiPaper-root`);
6741
+ if (target &&
6742
+ ((trigger && trigger.contains(target)) ||
6743
+ (menuPaper && menuPaper.contains(target)))) {
6744
+ return;
6745
+ }
6746
+ closeMenu();
6747
+ };
6748
+ document.addEventListener("mousedown", handlePointerDown, true);
6749
+ document.addEventListener("touchstart", handlePointerDown, true);
6750
+ return () => {
6751
+ document.removeEventListener("mousedown", handlePointerDown, true);
6752
+ document.removeEventListener("touchstart", handlePointerDown, true);
6753
+ };
6754
+ }, [openMenuId]);
6755
+ const handleMenuOpen = (event, menuId) => {
6756
+ if (openMenuId === menuId) {
6757
+ closeMenu();
6758
+ return;
6759
+ }
6760
+ openMenu(menuId, event.currentTarget);
6761
+ };
6762
+ const handleMenuHover = (event, menuId) => {
6763
+ if (isMobile || !openMenuId || openMenuId === menuId) {
6764
+ return;
6765
+ }
6766
+ clearHoverTimeout();
6767
+ hoverTimeoutRef.current = window.setTimeout(() => {
6768
+ openMenu(menuId, event.currentTarget);
6769
+ }, hoverSwitchDelayMs);
6770
+ };
6771
+ const handleMenuKeyDown = (event, menu) => {
6772
+ switch (event.key) {
6773
+ case "Enter":
6774
+ case " ":
6775
+ case "ArrowDown": {
6776
+ if (!menu.items.length) {
6777
+ return;
6778
+ }
6779
+ event.preventDefault();
6780
+ openMenu(menu.id, event.currentTarget);
6781
+ break;
6782
+ }
6783
+ case "ArrowRight":
6784
+ case "ArrowLeft": {
6785
+ event.preventDefault();
6786
+ const adjacentMenu = getAdjacentMenu(menu.id, event.key === "ArrowRight" ? 1 : -1);
6787
+ if (!adjacentMenu) {
6788
+ return;
6789
+ }
6790
+ focusTrigger(adjacentMenu.id);
6791
+ if (openMenuId && adjacentMenu.items.length) {
6792
+ openMenu(adjacentMenu.id);
6793
+ }
6794
+ break;
6795
+ }
6796
+ case "Escape": {
6797
+ if (!openMenuId) {
6798
+ return;
6799
+ }
6800
+ event.preventDefault();
6801
+ closeMenu();
6802
+ focusTrigger(menu.id);
6803
+ break;
6804
+ }
6805
+ }
6806
+ };
6807
+ return (React__default.createElement(React__default.Fragment, null, visibleMenus.map((menu) => {
6808
+ var _a;
6809
+ const isMenuOpen = openMenuId === menu.id;
6810
+ const buttonId = `${menu.id}-trigger`;
6811
+ return menu.items.length > 0 ? (React__default.createElement(React__default.Fragment, { key: menu.id },
6812
+ React__default.createElement(Button, { ref: (node) => {
6813
+ triggerRefs.current[menu.id] = node;
6814
+ }, id: buttonId, "aria-controls": `${menu.id}-menu`, "aria-haspopup": "true", "aria-expanded": isMenuOpen ? "true" : undefined, onClick: (event) => handleMenuOpen(event, menu.id), onMouseEnter: (event) => handleMenuHover(event, menu.id), onMouseLeave: clearHoverTimeout, onKeyDown: (event) => handleMenuKeyDown(event, menu), sx: {
6815
+ marginRight: (theme) => theme.spacing(2),
6816
+ color: "white",
6817
+ display: "flex",
6818
+ alignItems: "center",
6819
+ whiteSpace: "nowrap",
6820
+ } },
6821
+ menu.label,
6822
+ isMenuOpen ? (React__default.createElement(ExpandLess, { sx: { marginLeft: (theme) => theme.spacing(0.5) } })) : (React__default.createElement(ExpandMore, { sx: { marginLeft: (theme) => theme.spacing(0.5) } }))),
6823
+ React__default.createElement(Menu, { id: `${menu.id}-menu`, anchorEl: isMenuOpen ? menuAnchorEl : null, hideBackdrop: true, disableScrollLock: true, keepMounted: true, open: isMenuOpen, onClose: closeMenu, sx: {
6824
+ pointerEvents: "none",
6825
+ "& .MuiPaper-root": {
6826
+ pointerEvents: "auto",
6827
+ },
6828
+ }, MenuListProps: {
6829
+ "aria-labelledby": buttonId,
6830
+ autoFocusItem: isMenuOpen,
6831
+ }, anchorOrigin: {
6832
+ vertical: "bottom",
6833
+ horizontal: "center",
6834
+ }, transformOrigin: {
6835
+ vertical: "top",
6836
+ horizontal: "center",
6837
+ } }, menu.items.map((item, index) => (React__default.createElement(MenuItem, { key: `${menu.id}-item-${item.label}-${index}`, component: Link, to: item.to, onClick: () => {
6838
+ closeMenu();
6839
+ closeDrawer === null || closeDrawer === void 0 ? void 0 : closeDrawer();
6840
+ }, sx: {
6841
+ textDecoration: "none",
6842
+ color: "inherit",
6843
+ } },
6844
+ React__default.createElement(Typography$1, null, item.label))))))) : (React__default.createElement(Button, { key: menu.id, ref: (node) => {
6845
+ triggerRefs.current[menu.id] = node;
6846
+ }, id: buttonId, component: Link, to: (_a = menu.to) !== null && _a !== void 0 ? _a : "#", onClick: () => {
6847
+ closeMenu();
6848
+ closeDrawer === null || closeDrawer === void 0 ? void 0 : closeDrawer();
6849
+ }, onKeyDown: (event) => handleMenuKeyDown(event, menu), sx: {
6850
+ marginRight: (theme) => theme.spacing(2),
6851
+ color: "white",
6852
+ display: "flex",
6853
+ alignItems: "center",
6854
+ whiteSpace: "nowrap",
6855
+ } }, menu.label));
6856
+ })));
6857
+ }
6858
+
6690
6859
  const TimeAndUserMenu = () => {
6691
6860
  const { getUserName } = useToken();
6692
6861
  const [userName, setUserName] = useState(getUserName());
@@ -9667,7 +9836,7 @@ const ConfigurationContext = createContext([
9667
9836
  [],
9668
9837
  () => React__default.createElement(React__default.Fragment, null),
9669
9838
  ]);
9670
- const NavbarContext = createContext(() => React__default.createElement(React__default.Fragment, null));
9839
+ const NavbarContext = createContext(() => (React__default.createElement(React__default.Fragment, null)));
9671
9840
 
9672
9841
  const AreaSelector$1 = lazy(() => Promise.resolve().then(function () { return areaSelector; }).then((mod) => ({
9673
9842
  default: mod.AreaSelector,
@@ -9677,7 +9846,8 @@ function Header({ showAreaSelector = false, showTrendingsV2Icon = true, navbarTi
9677
9846
  const CustomNavbar = useContext(NavbarContext);
9678
9847
  const [drawerOpen, setDrawerOpen] = useState(false);
9679
9848
  const hasPermissionTo = useHasPermission();
9680
- useUserContext();
9849
+ const theme = useTheme();
9850
+ const isCompactNavigation = useMediaQuery(theme.breakpoints.down("lg"));
9681
9851
  const handleDrawerToggle = () => {
9682
9852
  setDrawerOpen(!drawerOpen);
9683
9853
  };
@@ -9701,19 +9871,23 @@ function Header({ showAreaSelector = false, showTrendingsV2Icon = true, navbarTi
9701
9871
  return (React__default.createElement(React__default.Fragment, null,
9702
9872
  React__default.createElement(AppBar, { position: "static", sx: {
9703
9873
  backgroundColor: (theme) => theme.palette.primary.main,
9874
+ zIndex: (theme) => theme.zIndex.modal + 1,
9704
9875
  } },
9705
- React__default.createElement(Toolbar, { sx: { backgroundColor: (theme) => theme.palette.primary.main } },
9706
- React__default.createElement(Hidden, { mdUp: true },
9707
- React__default.createElement(IconButton$1, { edge: "start", sx: {
9708
- flexGrow: 0,
9709
- marginRight: (theme) => theme.spacing(2),
9710
- textDecoration: "none",
9711
- color: "white",
9712
- textWrap: "nowrap",
9713
- }, color: "inherit", "aria-label": "menu", onClick: handleDrawerToggle },
9714
- React__default.createElement(MenuIcon, null))),
9876
+ React__default.createElement(Toolbar, { sx: {
9877
+ backgroundColor: (theme) => theme.palette.primary.main,
9878
+ minWidth: 0,
9879
+ overflowX: "hidden",
9880
+ } },
9881
+ isCompactNavigation && (React__default.createElement(IconButton$1, { edge: "start", sx: {
9882
+ flexShrink: 0,
9883
+ marginRight: (theme) => theme.spacing(2),
9884
+ textDecoration: "none",
9885
+ color: "white",
9886
+ textWrap: "nowrap",
9887
+ }, color: "inherit", "aria-label": "menu", onClick: handleDrawerToggle },
9888
+ React__default.createElement(MenuIcon, null))),
9715
9889
  React__default.createElement(Typography$1, { variant: "h6", component: Link, to: "/home", sx: {
9716
- flexGrow: 0,
9890
+ flexShrink: 0,
9717
9891
  marginRight: (theme) => theme.spacing(2),
9718
9892
  textDecoration: "none",
9719
9893
  color: "white",
@@ -9722,16 +9896,21 @@ function Header({ showAreaSelector = false, showTrendingsV2Icon = true, navbarTi
9722
9896
  React__default.createElement(Box, { sx: {
9723
9897
  display: "flex",
9724
9898
  flexGrow: 1,
9899
+ minWidth: 0,
9900
+ overflow: "hidden",
9725
9901
  "& a": {
9726
9902
  color: "white",
9727
9903
  },
9728
- } },
9729
- React__default.createElement(Hidden, { smDown: true },
9730
- React__default.createElement(CustomNavbar, { closeDrawer: handleDrawerToggle }))),
9904
+ "& > *": {
9905
+ minWidth: 0,
9906
+ maxWidth: "100%",
9907
+ },
9908
+ } }, !isCompactNavigation && (React__default.createElement(CustomNavbar, { closeDrawer: handleDrawerToggle }))),
9731
9909
  React__default.createElement(Box, { sx: {
9732
9910
  display: "flex",
9733
9911
  alignItems: "center",
9734
9912
  color: "white",
9913
+ flexShrink: 0,
9735
9914
  } },
9736
9915
  showTrendingsV2Icon && (React__default.createElement(Tooltip, { title: "Trendings V2 (ECharts)", placement: "bottom", arrow: true, enterDelay: 1500 },
9737
9916
  React__default.createElement(IconButton$1, { color: "inherit", component: Link, to: "/trendings-v2" },
@@ -9746,8 +9925,11 @@ function Header({ showAreaSelector = false, showTrendingsV2Icon = true, navbarTi
9746
9925
  width: 250,
9747
9926
  "& .MuiDrawer-paper": {
9748
9927
  width: 250,
9749
- marginTop: 56, // Height of AppBar on mobile
9750
- height: `calc(100% - 56px)`,
9928
+ top: { xs: 56, sm: 64 },
9929
+ height: {
9930
+ xs: "calc(100% - 56px)",
9931
+ sm: "calc(100% - 64px)",
9932
+ },
9751
9933
  backgroundColor: (theme) => theme.palette.grey[100], // Light grey background
9752
9934
  // Alternatively, you can use a specific color:
9753
9935
  // backgroundColor: '#f5f5f5',
@@ -20267,5 +20449,5 @@ var areaSelector = /*#__PURE__*/Object.freeze({
20267
20449
  AreaSelector: AreaSelector
20268
20450
  });
20269
20451
 
20270
- export { Account, AssetProvider, AssetTreePicker, AuthContext, AuthProvider, ButtonWithLoading, ChangePassword, CheckBoxControl, Configuration$1 as Configuration, ContextMenu$1 as ContextMenu, ContextMenuMESFProvider, CreateNewAssetDialog, CurrencyFormatter, DataGridControl, DateFormatter, DateTimeFormatter, ENTRY_INITIAL_VALUES$1 as ENTRY_INITIAL_VALUES, EditAssetDialog, ErrorModal, ExcelIcon, FetchError, FilterPanel, GenericPanel, GenericTable, GetCrewColor, GetShiftColor, HelmetDexteel, IntegerFormatter, LogbookSettingsInitialState, LogbookSettingsProvider, Login, Logout, LongFilterPanel, MESApiService, MESFLogbookEntry$1 as MESFLogbookEntry, MESFLogbookReport$1 as MESFLogbookReport, MESFMain, MESSAGE_API, MESSAGE_ERRORS, MasterDetailPanel, MesfModal, ModalTreeFilterControl, MultipleSelectorControl, NumberFormatter, RemoveAssetDialog, SPExecutorPage, ShiftDayNavigatorControl, ShiftNavigatorProvider, ShiftPeriodNavigatorControl, SimplePasswordControl, SimpleSelectorControl, TimeAndUserMenu, TimeFormatter, TimeService, TreePickerControl, TreePickerControlV2, USER_LABELS, UTLSettingsProvider, UserProvider, axiosInstance, deleteUser, dxtServerTimeZone, dxtToLocalServerTime, dxtToUTC, formatNumber, getAuthTypes, getCrewStyle, getDataUser, getEntries$1 as getEntries, getError, getMomentTz, getShiftByParameters, getShiftStyle, getShiftsRangeByParameters, getTokenFromLS, getUserPermissionsFromAPI, getUsers, logbookNavbar, logbookRoutesMESF, renewToken, routeLogbookEntry$1 as routeLogbookEntry, routeLogbookReport, useSearchAssets as searchAssets, sectionLogbookNavbar, sectionLogbookRoutesMESF, setPassword, setProfilesToUser, themeDXT, themeMESF, upsertUser, useAssetContext, useContextMenuMESF, useEntries$1 as useEntries, useFrontendVersionCheck, useHasPermission, useHasProfile, useLogbookSettings, useMesfRealtime, useShiftNavigator, useShiftNavigatorManager, useToken, useUTLSettingsContext, useUserContext };
20452
+ export { Account, AssetProvider, AssetTreePicker, AuthContext, AuthProvider, ButtonWithLoading, ChangePassword, CheckBoxControl, Configuration$1 as Configuration, ContextMenu$1 as ContextMenu, ContextMenuMESFProvider, CreateNewAssetDialog, CurrencyFormatter, DataGridControl, DateFormatter, DateTimeFormatter, ENTRY_INITIAL_VALUES$1 as ENTRY_INITIAL_VALUES, EditAssetDialog, ErrorModal, ExcelIcon, FetchError, FilterPanel, GenericPanel, GenericTable, GetCrewColor, GetShiftColor, HelmetDexteel, IntegerFormatter, LogbookSettingsInitialState, LogbookSettingsProvider, Login, Logout, LongFilterPanel, MESApiService, MESFLogbookEntry$1 as MESFLogbookEntry, MESFLogbookReport$1 as MESFLogbookReport, MESFMain, MESSAGE_API, MESSAGE_ERRORS, MasterDetailPanel, MesfModal, ModalTreeFilterControl, MultipleSelectorControl, NavbarMenuBar, NumberFormatter, RemoveAssetDialog, SPExecutorPage, ShiftDayNavigatorControl, ShiftNavigatorProvider, ShiftPeriodNavigatorControl, SimplePasswordControl, SimpleSelectorControl, TimeAndUserMenu, TimeFormatter, TimeService, TreePickerControl, TreePickerControlV2, USER_LABELS, UTLSettingsProvider, UserProvider, axiosInstance, deleteUser, dxtServerTimeZone, dxtToLocalServerTime, dxtToUTC, formatNumber, getAuthTypes, getCrewStyle, getDataUser, getEntries$1 as getEntries, getError, getMomentTz, getShiftByParameters, getShiftStyle, getShiftsRangeByParameters, getTokenFromLS, getUserPermissionsFromAPI, getUsers, logbookNavbar, logbookRoutesMESF, renewToken, routeLogbookEntry$1 as routeLogbookEntry, routeLogbookReport, useSearchAssets as searchAssets, sectionLogbookNavbar, sectionLogbookRoutesMESF, setPassword, setProfilesToUser, themeDXT, themeMESF, upsertUser, useAssetContext, useContextMenuMESF, useEntries$1 as useEntries, useFrontendVersionCheck, useHasPermission, useHasProfile, useLogbookSettings, useMesfRealtime, useShiftNavigator, useShiftNavigatorManager, useToken, useUTLSettingsContext, useUserContext };
20271
20453
  //# sourceMappingURL=index.esm.js.map