Skip to content

Upgrade dependencies (Node, Typescript, React, Electron, Fluent Controls) and address some long standing issues with Copilot Assistance#730

Merged
vincenzocaruso merged 38 commits into
Azure:mainfrom
rafarhat:main
Jun 8, 2026
Merged

Upgrade dependencies (Node, Typescript, React, Electron, Fluent Controls) and address some long standing issues with Copilot Assistance#730
vincenzocaruso merged 38 commits into
Azure:mainfrom
rafarhat:main

Conversation

@rafarhat

Copy link
Copy Markdown
Member

🔧 Major Framework Upgrades

  • Electron 22 → 41
  • TypeScript → 6.0.3 (target ES2025, modern module resolution)
  • React 16 → 18 → 19, react-router-dom v5 → v6
  • FluentUI upgraded to V9 with Azure SDK and remaining library updates
  • Build toolchain: migrated TSLint → ESLint (flat config), SCSS @import → @use/@forward

🧪 Test Infrastructure Overhaul

  • Migrated entire test suite from Enzyme → React Testing Library

🐛 Bug Fixes

  • Support national cloud endpoints in hostname validation

✨ New Features

  • Multi-tenant Azure AD support with tenant picker
  • Default to OS theme preference on first launch
  • Enqueue time filtering for event hub monitoring with freeform time input
  • Linux packaging: use space-free executable name

🧹 Code Quality

  • Resolved all SCSS/ESLint errors and warnings

rafarhat and others added 30 commits April 30, 2026 12:31
…move legacy deps

- Upgrade TypeScript from 4.6 to 5.8.3
- Update compilation targets from ES5 to ES2020 across all tsconfig files
- Add skipLibCheck and esModuleInterop for library compatibility
- Migrate from TSLint to ESLint with equivalent rule configuration
- Replace tslint-loader with eslint-webpack-plugin in webpack config
- Remove deprecated TSLint packages (tslint, tslint-loader, tslint-react, tslint-origin-ordered-imports-rule)
- Remove legacy msal v1 package (unused, replaced by @azure/msal-node)
- Remove deprecated react-jsonschema-form v1 (replaced by @rjsf/* v5)
- Bump all dependencies within semver ranges via npm update
- Apply npm audit fix for security patches
- Fix implicit any return type errors in 3 source files

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Upgrade electron from ^22.3.25 to ^41.3.0
- Upgrade @electron/fuses from ^1.8.0 to ^2.1.1
- Remove unused electron-reload package
- Remove globalThis.crypto polyfill (no longer needed with Node 22+ in Electron 41)
- All existing APIs (contextBridge, ipcMain.handle, will-redirect, safeStorage, etc.) remain compatible

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Upgrade react, react-dom, @types/react, @types/react-dom to v18
- Replace ReactDOM.render with createRoot API
- Switch Enzyme adapter to @cfaester/enzyme-adapter-react-18
- Fix React.FC children prop (PropsWithChildren) across components
- Replace React.SFC with React.FC

- Upgrade react-router-dom from v5 to v6 (remove @types/react-router-dom)
- Migrate Switch to Routes, Route component to Route element
- Migrate Redirect to Navigate, useHistory to useNavigate
- Migrate useRouteMatch to useLocation with pathname computation
- Replace Prompt with beforeunload event listener
- Simplify BreadcrumbRoute from Route wrapper to breadcrumb wrapper
- Update all spec files with v6 router mocks

- Install missing peer deps: @rjsf/utils, @rjsf/core, monaco-editor,
  @material-ui/core, @material-ui/icons
- Add skipLibCheck to public/tsconfig.json
- Add allowedHosts to webpack dev server config
- Add @rjsf/@x0k to Jest transformIgnorePatterns

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Upgrade @fluentui/react 8.101 to 8.125 (latest v8 patch)
- Upgrade @azure/msal-node 1.x to 2.x
- Upgrade @azure/core-amqp 3.x to 4.x
- Upgrade @microsoft/applicationinsights-web 2.x to 3.x
- Upgrade i18next 20 to 23, react-i18next 11 to 15
- Upgrade date-fns 2 to 4, semver 6 to 7, uuid 3 to 9
- Upgrade react-toastify 4 to 9 (ToastType to toast.TYPE)
- Upgrade immutable 4-rc to 5, react-collapsible 2.3 to 2.10
- Upgrade react-monaco-editor 0.54 to 0.59, ws 8.17 to 8.20
- Upgrade sass 1.35 to 1.89, sass-loader 13 to 16, concurrently 5 to 9
- Remove dead dependencies: express, body-parser, cors,
  crypto-browserify, and associated type packages

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…s (v9 pattern)

Replace iconProps: { iconName: CONSTANT } with icon: <IconComponent /> across
all command bar usages. Replace renderV9Icon() calls with direct icon component
imports in homeViewNavigation and deviceContentNav. Remove unused iconNames
imports where applicable.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…ping

- Add aria-labels to info buttons, password reveal, and skeleton loaders
- Add role=alert to form validation errors for screen reader announcements
- Make DataGrid row checkboxes use row-specific aria-labels
- Add LiveRegion announcements to 5 action handlers (commands, settings, c2d, module)
- Fix send command button icon visibility (primary button white-on-blue)
- Replace icon string mapping table with direct v9 icon component imports (26 files)
- Delete fluentV9Icons.tsx (147-entry lookup table no longer needed)
- Simplify CommandBarV9 interfaces (remove deprecated iconProps)
- Scope global CSS hacks: button svg color to .fui-Toolbar only, DataGrid cell to .rdl-cell class
- Document remaining .fui-Field label weight rule

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Convert all 31 SCSS files from @import to @use ... as * syntax
- Replace deprecated map-get()/map-merge() with sass:map module functions
- Add @forward 'palette' in _themes.scss so consumers retain access to palette vars
- Declare \-map at module level to fix !global variable creation deprecation
- Suppress harmless protobufjs dynamic require warning in webpack config

Prepares codebase for Dart Sass 3.0.0 which will remove @import support.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…ase 1)

Replace Enzyme with React Testing Library (RTL) across all 111 test files.
This establishes the RTL foundation with all 196 test suites passing.

Changes:
- Remove enzyme, enzyme-adapter-react-16, enzyme-to-json dependencies
- Add @testing-library/react, @testing-library/jest-dom, @testing-library/user-event
- Update jestSetup.ts: remove Enzyme config, add Trans mock for react-i18next
- Add shared testUtils.tsx with renderWithRouter helper and RTL re-exports
- Convert all .spec.tsx files from Enzyme shallow/mount to RTL render
- Add proper MemoryRouter wrapping for components using react-router
- Add context mocks (PnP, auth, connection string, device events)
- Delete 98 obsolete __snapshots__/ directories
- Phase 2 will restore meaningful assertions to ~52 smoke-test-only files

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Replace trivial smoke tests (expect(container).toBeDefined()) with meaningful
RTL assertions that verify rendered content, user interactions, and component
behavior across the entire test suite.

Changes by area:
- Connection Strings (7 files): verify form fields, links, delete confirmations
- Device Events (4 files): verify event rendering, systemProperties filtering
- Forms & Actions (6 files): verify form inputs, submit handlers, validation
- Device Identity & List (7 files): verify command bars, paging with page index
- PnP Components (12 files): verify commands, properties, settings, interfaces
- Auth, Model Repo, Nav (13 files): verify auth selection, breadcrumbs, settings
- Shared (2 files): verify header links, Monaco editor rendering

Review fixes applied:
- Use role-based queries instead of CSS selectors (shimmer, settings)
- Scope assertions to component containers (breadcrumb)
- Verify call arguments not just invocation (listPaging)
- Fix always-passing assertions (modelRepositoryLocationList)
- Add systemProperties filtering coverage (eventsContent)

Test results: 196 suites, 775 tests, all passing.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
   - TypeScript 6.0.3 with npm overrides for ts-jest peer dep
   - moduleResolution: bundler (frontend/jest), node16 (electron)
   - target/lib: es2025 for all configs
   - Removed deprecated baseUrl, ignoreDeprecations no longer needed
   - Fixed TS6 build errors: type guards, discriminated unions, default imports
   - Fixed frozen namespace imports in tests (jest.mock pattern)
   - Fixed runtime ssrfFilter import (esModuleInterop default import)
   - Added .scss/.css module declarations
   - Fixed pre-existing webpack JSON import warning

   Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Upgrade react and react-dom from ^18.3.1 to ^19.0.0
- Upgrade @types/react and @types/react-dom to ^19.0.0
- Upgrade react-toastify from ^9.1.3 to ^11.0.0
- Remove unused dependencies: @material-ui/core, @material-ui/icons, react-collapsible
- Replace React.createRef with useRef in maskedCopyableTextField
- Replace JSX.Element with React.JSX.Element (7 files)
- Fix useReducer type signature for React 19 in useAsyncSagaReducer
- Update react-toastify v11 API (bodyClassName, POSITION, TYPE)
- Fix tests for React 19 concurrent rendering compatibility

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Remove MiniCssExtractPlugin.loader from webpack.dev.ts which was
conflicting with style-loader. These two loaders are mutually exclusive -
style-loader injects CSS via JS (ideal for dev/HMR) while
MiniCssExtractPlugin.loader extracts to files (used in production).
Having both caused 'module has no exports' warnings for every SCSS file.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Add ProvidePlugin for process/browser in webpack.dev.ts to ensure
the process global is available before HMR and style-loader code
executes. The node-polyfill-webpack-plugin provides process as a
polyfill but it loads too late for some modules in dev mode.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Downgrade eslint from ^10.3.0 to ^9.39.4 (eslint-plugin-react compatibility)
- Add @fluentui/react-migration-v0-v9 back (required by @rjsf/fluentui-rc)
- Add npm override for react-monaco-editor monaco-editor peer dep
- Add --legacy-peer-deps to package:win/linux/mac scripts

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Add support for Azure China (21Vianet) and Azure US Government
sovereign cloud domains in IoT Hub and Event Hub hostname validation:

- IoT Hub: *.azure-devices.cn, *.azure-devices.us
- Event Hub: *.servicebus.chinacloudapi.cn, *.servicebus.usgovcloudapi.net
- Privatelink variants for all clouds
- Updated CSP connect-src with national cloud domains
- Updated error messages to list supported domains
- Added 14 new test cases for sovereign cloud hostnames

Fixes Azure#728

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Add folder-picker-dialog className to Fluent UI v9 DialogSurface
and update SCSS to replace obsolete v8 selectors (.ms-Dialog-*).
Use flex column layout for folder list with proper row height.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Re-implements the start time filtering feature that was incorrectly removed
in PR Azure#659. Users can now specify a custom start time to filter telemetry
messages by enqueue time using Fluent UI DatePicker and TimePicker controls.

- Default behavior changed from earliestEventPosition to latestEventPosition
- When user specifies start time, uses enqueuedOn for SDK v5 compatibility
- Added StartTime component with Fluent UI v9 DatePicker + TimePicker
- Added accessibility: label associations, aria-labels, error announcements
- Added backend validation for startTime date string
- Added 13 unit tests for StartTime component using RTL best practices
- Restored localization strings for start time UI

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Add executableName to linux build config so the install path is
/opt/azure-iot-explorer/ instead of /opt/Azure IoT Explorer Preview/.
Spaces in the path caused 'execvp' failures on Ubuntu.

Note: Users upgrading from older versions may need to manually remove
the old directory: sudo rm -rf '/opt/Azure IoT Explorer Preview'

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The Save button on AddDevice form was not working because CommandBarV9
ignored the type prop. ToolbarButton defaulted to type='button' instead
of type='submit', so clicking it never triggered the form's onSubmit.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The theme Switch in settings was missing its label prop after the
Fluent UI v9 migration. Now displays 'Light' or 'Dark' based on
the current theme selection.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
When the hamburger menu collapses the left nav, the grid column now
uses auto sizing instead of a fixed fraction, so the nav fits its
icon content naturally. Added overflow hidden on collapsed state and
margin-left on the hamburger button to align with tab icons.
Also removed unused nav width variables from _deviceContent.scss.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
When no saved theme preference exists in localStorage, detect the OS
dark mode setting via window.matchMedia instead of defaulting to light.
Once the user explicitly toggles the theme, their choice is persisted
and takes precedence over the OS setting.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Add tenant picker UI between login and subscription selection
- Acquire tenant-scoped tokens via getTokenForTenant()
- New: AzureTenant model, tenant service, tenant list saga, tenant picker component
- Fix logout to clear SSO cookies for proper account switching
- Add CSP entries for https://aadcdn.msftauth.net
- Use separate auth popup window to prevent 'wrong page' error
- Handle auth cancellation gracefully (no object destroyed errors)
- Add GUID validation for tenantId before URL interpolation
- Add error handling for auth redirect failures

Fixes: Azure#554

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Remove state-driven redirect pattern in interfaceNotFoundMessageBar.tsx;
  call navigate() directly in click handler (React 18+ concurrent mode fix)
- Add aka.ms, learn.microsoft.com, shell.azure.com, and GitHub model repos
  to Electron ALLOWED_EXTERNAL_URLS so documentation links open in browser

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
… test files

- Add @testing-library/jest-dom via setupFilesAfterEnv in jest config
- Replace toBeDefined() with toBeInTheDocument() for screen.getBy*/getAllBy*
  assertions (these were no-ops since getBy* throws if element not found)
- Keep toBeDefined() for non-element assertions (render result, container)

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…9 test files

Components using useEffect with dispatch on mount trigger React 18/19
act() warnings. Wrapped render() calls in await act(async () => {...})
for both direct renderers (deviceList, deviceContent, moduleIdentityList,
pnp) and parent renderers (homeView, iotHubResource, iotHubHost,
iotHubDevices, deviceModules).

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…d code

Renamed iconNames.ts to commandBarItemKeys.ts to reflect that these
constants are now used as command bar item keys, not icon names (v9 uses
direct icon component imports). Removed 5 unused enums, 20+ unused
constants, and 2 dead imports across 18 files.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Replace legacy .eslintrc.json with eslint.config.mjs (flat config)
- Add typescript-eslint unified package for v8 rule mappings
- Update deprecated rules: ban-types, no-empty-interface, no-var-requires
- Remove @stylistic/eslint-plugin (stylistic rules were not in original config)
- Auto-fix 10 curly brace violations across 10 files

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…ontrolled input warnings

Initialize useState hooks with empty strings instead of undefined to avoid
React warning about changing uncontrolled inputs to controlled. Use optional
chaining with nullish coalescing for derived values passed to input components.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
… rules-of-hooks)

- Add radix parameter to parseInt() calls in cloudToDeviceMessage.tsx
- Merge duplicate @fluentui/react-components imports in dataForm.tsx
- Add eslint-disable comments for intentional console usage in sagaReducerLogger.ts,
  credentialStorage.ts, and appInsightsClient.ts
- Rename getHubInformationFromLocalStorage to useHubInformationFromLocalStorage
- Rename sagaReducerLogger to useSagaReducerLogger and call unconditionally
- Convert renderSchemaErrors to SchemaErrors component in simpleReportedSection.tsx

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
rafarhat and others added 5 commits May 5, 2026 19:14
…ve-deps)

- Disable react/jsx-no-bind rule (90 instances, intentional pattern)
- Fix no-shadow: rename inner variable in deviceEvents/utils.ts
- Fix no-unused-vars: remove unused imports/variables, prefix unused params with _
- Fix react-hooks/exhaustive-deps: add stable deps (dispatch, navigate, componentName),
  add eslint-disable for mount-only effects with explanatory comments

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Add margin-left: 4px to .collapsibleButton inside .mainleftnav .nav-links,
matching the alignment fix previously applied to the home page nav.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Replace read-only TimePicker with freeform input
- Add parseTimeText helper for 12h/24h time formats
- Show validation error for invalid time input using Field component
- Align start time layout with custom event hub row pattern
- Clear time when date is reselected (including freeform text)
- Add horizontal-item spacing class to deviceEvents.scss

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Update GitHub Actions to Node 24.x with checkout@v4 and setup-node@v4
- Update Azure Pipelines to Node 24.x
- Add --legacy-peer-deps to all npm ci commands to resolve peer conflicts

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The flag causes a segfault on Node 24 during Jest teardown when
combined with --coverage. It is a debug-only flag not needed for CI.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Comment thread src/localization/locales/en.json
Comment thread pipelines/build-windows.yml
Comment thread public/utils/connStringHelper.ts Outdated
Comment thread public/tsconfig.json
Comment thread src/app/devices/addDevice/components/addDevice.tsx Outdated
Comment thread src/app/devices/deviceEvents/components/loader.tsx Outdated
Comment thread src/app/devices/pnp/components/deviceProperties/devicePropertiesPerInterface.tsx Outdated
Comment thread src/app/shared/appTelemetry/appInsightsClient.ts
Comment thread webpack.dev.ts Outdated
rafarhat and others added 3 commits June 3, 2026 08:12
- Extract inline styles to SCSS classes in addDevice, loader, and
  devicePropertiesPerInterface components
- Restrict webpack dev server allowedHosts to localhost
- Remove dead code: public/utils/connStringHelper.ts (unused since Azure#580)
- Support new TLS 1.3 IoT Hub hostnames (device/service endpoints)
  including privatelink variants across all clouds

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@vincenzocaruso vincenzocaruso merged commit 66c0f61 into Azure:main Jun 8, 2026
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants