Skip to content

Conversation

@dirkwa
Copy link
Contributor

@dirkwa dirkwa commented Jan 18, 2026

Description:

Detect and display npm-deprecated plugins/webapps in the admin UI to help users identify packages that should be removed.

Changes:

  • Add checkDeprecations() function to query npm registry for deprecation status with 1-hour cache
  • Detect locally installed plugins not in npm search results (orphan plugins like @signalk/zones)
  • Show combined badge in sidebar (e.g. "3↑ 1✗" for updates and deprecated)
  • Add "Deprecated" tab in Appstore with only "Remove" option for affected plugins
  • Display "Deprecated" badge on Plugin Configuration and Webapps pages

How it works:

The deprecation check runs when Appstore data is fetched. Since deprecated packages are often removed from npm's search index, the code also detects "orphan" plugins - those installed locally but not found in npm search results - ensuring they still get flagged.

Depends on:

#2267 (React 19 migration) - must be merged first

Screenshots:

image image image image

dirkwa added 14 commits January 16, 2026 05:53
Migrate server-admin-ui from React 16 to React 19, including:
- React Router v4 to v6 (Switch→Routes, component→element)
- Redux 3 to Redux 5 with react-redux 9 hooks
- Bootstrap 4 to Bootstrap 5 class names (ml-*→ms-*, badge-*→text-bg-*)
- ReactDOM.render to createRoot API
- String refs to React.createRef()

Module Federation configured with singleton:true for React to ensure
hooks and context work correctly across host and plugin boundaries.
Plugins built against React 16 will need to be rebuilt.

Add improved error handling in dynamicutilities.js to detect React
version incompatibility and display user-friendly messages.

Add test plugin (examples/test-custom-renderer-plugin) demonstrating
React 19 compatible embedded webapp and custom Data Browser renderer.

BREAKING CHANGE: Embedded webapps and custom renderers built with
React 16 must be updated and rebuilt to work with React 19.
Migrate Admin UI components from legacy Redux connect() HOC pattern to
modern useSelector/useDispatch hooks. Convert affected files from
JavaScript to TypeScript for improved type safety.

Changes:
- Convert 12 component files from .js to .tsx with full TypeScript types
- Replace connect() mapStateToProps with useSelector hooks
- Replace connect() mapDispatchToProps with useDispatch hooks
- Add proper TypeScript interfaces for component props and state
- Remove unused eslint-disable comments for unconfigured rules
- Fix lint warnings for unused imports

Components converted to TypeScript with hooks:
- DataBrowser, Meta, Playground
- ProvidersConfiguration, ServerUpdate, Settings
- VesselConfiguration, Logging, BackupRestore, SourcePriorities
- Apps, OIDCSettings

Also includes fixes to existing hook-based components:
- Login.js, ServerLog.js: Remove obsolete eslint-disable comments
- Various security components: Modernize Redux usage
The component was importing appStore via connect() but never using it.
Remove old JavaScript files that were superseded by TypeScript conversions.
Delete unused routerCompat.tsx shim that was never imported.
Remove echo comments that simply describe what code does.

Update documentation to follow maintainer guidelines:
- Remove implementation details that may drift from code
- Replace inline code snippets with links to source files
- Update file references from .js to .tsx
- Remove @signalk/vesselpositions from optionalDependencies and categories.ts
- Remove vesselpositions.png image and references from webapps.md
- Fix sidebar submenu alignment for dropdown items without icons
- Remove echo comments and stale code cruft:
  - SidebarFooter/Form/Header: remove commented boilerplate
  - Sidebar.tsx: remove redundant function name comments
  - bootstrap.tsx: remove section header comments
  - appSlice.ts: remove echo comments
  - Dashboard.tsx: remove implementation history comment
  - _custom.scss: simplify comments, remove variable name echoes
- Fix SCSS deprecation warnings (PR 2237):
  - darken()/lighten() → color.adjust()
  - / division → math.div()
  - nth()/map-get()/map-keys() → list.nth()/map.get()/map.keys()
  - lightness() → color.channel()
  - Silence only @import deprecations (Bootstrap 5 still uses @import)
Generated build artifact was accidentally committed, adding 44K lines.
Added to .gitignore to prevent future commits.
Enable strict type checking in server-admin-ui tsconfig.json and fix
all resulting type errors. Add graceful error handling for plugins
incompatible with React 19.

Key changes:
- Enable strict mode in tsconfig.json, update lib to ES2021
- Add missing properties and index signatures to store types
- Fix null/undefined handling with nullish coalescing operators
- Add type assertions for RJSF template compatibility
- Create type declaration for jsonlint-mod module
- Add PluginErrorBoundary to EmbeddedPluginConfigurationForm
- Enhance error detection in dynamicutilities.ts for React 19
  incompatibility patterns

Incompatible plugins now show a friendly warning instead of crashing
the entire configuration page.
Enable stricter TypeScript linting rules to catch unused code at
compile time and fix all resulting errors.

Changes:
- Enable noUnusedLocals and noUnusedParameters in tsconfig.json
- Remove unused React import from bootstrap.tsx
- Remove unused dispatch parameter from enableSecurity function
- Remove unused onClose prop from PluginConfigCard component
- Remove unused FormText import from Meta.tsx
- Remove unused Col and Row imports from ProvidersConfiguration.tsx
- Remove dead changelog fetching code from ServerUpdate.tsx
Fix missing status feedback when installing or removing apps in the
app store. The progress animation and status text (Installing, Removing,
Removed, etc.) were not displayed because the installing app properties
were not being merged into the derived app list.

Changes:
- Add missing properties to InstallingApp type (isRemoving, isRemove,
  installFailed)
- Spread all installing app properties in Apps.tsx deriveAppList
  function so ActionCellRenderer receives the status flags
Add WebappErrorBoundary to Embedded.tsx to gracefully handle React 19
incompatibility errors when loading webapps built for older React versions.

Previously, clicking on an incompatible webapp (e.g., @canboat/visual-analyzer)
crashed the entire admin UI with "Minified React error SignalK#306". Now users see
a friendly warning message with a "Try again" button, and can navigate away
without reloading the page.

The error boundary:
- Catches render-phase errors from dynamically loaded webapps
- Shows React 19 compatibility hint for known error patterns
- Provides retry functionality for transient errors
- Resets automatically when switching between webapps (via key prop)
Add container="body" to DropdownMenu in ActionCellRenderer to render
the dropdown in a portal, preventing it from being clipped by the
InfiniteScroll container's overflow.
Detect and display npm-deprecated plugins/webapps in the admin UI to help
users identify packages that should be removed.

Changes:
- Add checkDeprecations() function to query npm registry for deprecation status
- Detect locally installed plugins not in npm search results (orphan plugins)
- Show combined badge in sidebar (e.g. "3↑ 1✗" for updates and deprecated)
- Add "Deprecated" tab in Appstore with only "Remove" option for affected plugins
- Display "Deprecated" badge on Plugin Configuration and Webapps pages
- Include 1-hour cache for deprecation status to avoid excessive npm API calls

The deprecation check runs when the Appstore data is fetched. Orphan plugin
detection ensures deprecated packages removed from npm search index are still
found and flagged.
@dirkwa
Copy link
Contributor Author

dirkwa commented Jan 18, 2026

I will rebase it once R19
is in the master.

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.

1 participant