Skip to content

Modernize: React 18, TypeScript 5, Fluent UI v9#1

Draft
BenGWeeks wants to merge 11 commits intomasterfrom
feature/modernize-react18-ts5
Draft

Modernize: React 18, TypeScript 5, Fluent UI v9#1
BenGWeeks wants to merge 11 commits intomasterfrom
feature/modernize-react18-ts5

Conversation

@BenGWeeks
Copy link

Summary

Major modernization of the extension toolchain:

  • React: 16.14.0 → 18.3.1
  • TypeScript: 3.1.6 → 5.9.3
  • Webpack: 4.47.0 → 5.104.1
  • UI Library: office-ui-fabric-react → @fluentui/react-components v9
  • Calendar: Custom implementation → react-activity-calendar

Changes

  • Updated all widget components to use React 18 createRoot API
  • Replaced Dropdown/Toggle with Fluent UI v9 equivalents
  • Added FluentProvider with webLightTheme
  • Updated webpack config for v5 compatibility
  • Bundling React instead of using host's React 16

Known Issues (WIP)

  • Legacy code has Q.Promise type incompatibilities with native Promise
  • CollapsibleHeader component needs children prop support
  • ActivityCalendar import type needs fixing

Test plan

  • Build completes without errors
  • Widget renders in Azure DevOps dashboard
  • Configuration panel works
  • Activity calendar displays correctly

🤖 Generated with Claude Code

BenGWeeks and others added 6 commits February 2, 2026 14:23
Major dependency upgrades:
- React 16 → 18.3.1
- TypeScript 3.1.6 → 5.9.3
- Webpack 4 → 5.104.1
- ts-loader 4 → 9.5.4
- office-ui-fabric-react → @fluentui/react-components v9

New features:
- react-activity-calendar for GitHub-style contribution graph
- Modern FluentProvider theming
- React 18 createRoot API

Known issues (WIP):
- Legacy code has Q.Promise type incompatibilities
- CollapsibleHeader children prop needs updating
- ActivityCalendar import type issue

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Document three options for local testing in README
- Add `bun run dev` script for webpack dev server
- Add webpack-dev-server dependency
- Document code quality commands (lint, format)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Fixes:
- ActivityCalendar: Use named import, update props API
- CollapsibleHeader: Add children prop, migrate to Fluent UI v9
- BatchedCachedValue: Use 'in' operator for cache check
- commits.ts: Cast Q.IPromise to native Promise
- extensionCache.ts: Fix Q.Promise cast

Build now succeeds with Webpack 5 + ts-loader 9.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Replace {} empty state types with Record<string, never>
- Add missing key props to JSX elements in iterators
- Migrate ReactDOM.render to React 18 createRoot API
- Rename componentWillReceiveProps to UNSAFE_componentWillReceiveProps
- Fix hasOwnProperty to use 'in' operator
- Replace 'any' casts with 'unknown' or specific types
- Auto-fix inferrable types and prefer-const

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add proper state interface for CompletionDropdown
- Fix Date cast to use unknown intermediate type

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The package-dev script requires tfx-cli to create the .vsix package.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Modernizes the Azure DevOps extension’s frontend/toolchain by upgrading to React 18 + TypeScript 5 + Webpack 5, migrating parts of the UI to Fluent UI v9, and replacing the custom activity calendar with react-activity-calendar.

Changes:

  • Upgraded runtime/tooling (React 18, TypeScript 5, Webpack 5) and updated build/CI/dev workflow.
  • Migrated widget + configuration UI to Fluent UI v9 and React 18 createRoot.
  • Replaced the custom calendar rendering with react-activity-calendar and updated related styling.

Reviewed changes

Copilot reviewed 30 out of 31 changed files in this pull request and generated 8 comments.

Show a summary per file
File Description
webpack.config.js Stops externalizing React so React 18 is bundled with the extension.
vss-extension.json Bumps extension version to 3.1.0.
styles/contributions.scss Removes custom calendar styling; keeps footer styling for new calendar layout.
scripts/data/tfvc/changsets.ts Simplifies default parameter typing for TS5.
scripts/data/identities/getIdentities.ts Refines casting for newer SDK client type usage.
scripts/data/identities/extensionCache.ts Adjusts Q.Promise casting for TS5 compatibility in error path.
scripts/data/git/repositories.ts Updates selected filtering logic (in check).
scripts/data/git/commits.ts Casts Q promise to native Promise for TS5 compatibility.
scripts/data/CachedValue.ts Minor TS modernization (inferred boolean initialization).
scripts/data/BatchedCachedValue.ts Uses in check for cached entries.
scripts/controls/timeWindow/timeWindow.tsx Updates legacy lifecycle to UNSAFE_componentWillReceiveProps.
scripts/controls/timeWindow/contributions.tsx Tightens state typing; minor const correctness.
scripts/controls/timeWindow/contribution.tsx Adds rel="noreferrer" to new-tab links; tightens typing.
scripts/controls/showGraphs.tsx Migrates to React 18 createRoot; removes render callbacks.
scripts/controls/graph.tsx Adds missing React list keys; simplifies default param typing.
scripts/controls/filters.tsx Migrates to React 18 createRoot while keeping existing filter UI components.
scripts/controls/WidgetGraph.tsx Replaces custom calendar with react-activity-calendar and theme config.
scripts/controls/IdentityPicker.tsx Tightens component state typing.
scripts/controls/Graphs.tsx Adds missing React list key for Graph instances.
scripts/controls/Day.tsx Simplifies default param typing.
scripts/controls/CompletionDropdown.tsx Adds explicit state type and modernizes static init.
scripts/controls/CollapsibleHeader.tsx Migrates header toggle to Fluent UI v9 Button + icons; adds children support.
scripts/contributionsWidgetConfiguration.tsx Migrates configuration panel to Fluent UI v9; uses createRoot.
scripts/contributionsWidget.tsx Migrates widget rendering + dropdown to Fluent UI v9; uses createRoot.
package.json Updates dependencies (React 18, Fluent UI v9, Webpack 5) and adds dev server script.
gulpfile.js Updates webpack invocation to use --mode (Webpack 5).
README.md Adds expanded local testing + dev server instructions and code quality commands.
.vscode/tasks.json.old Adds legacy tasks config copy.
.vscode/tasks.json Updates tasks schema to 2.0.0 (still configured for grunt).
.github/workflows/ci.yml Installs tfx-cli in CI before build step.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

BenGWeeks and others added 2 commits February 2, 2026 16:06
- Remove Q.Promise type annotation and cast in extensionCache.ts
- Migrate UNSAFE_componentWillReceiveProps to componentDidUpdate
- Update VS Code tasks.json to use bun commands instead of grunt
- Remove legacy tasks.json.old backup file
- Add explicit userMode type handling in widget configuration
- Use flushSync for accurate render timing telemetry
- Remove unused state property from CompletionDropdown

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Remove unused hub page (contributionsHub.tsx, contributionsHub.html)
- Remove legacy office-ui-fabric-react dependency
- Migrate IdentityPicker to Fluent UI v9 (Combobox with TagGroup)
- Add RepositoryPicker component for repo filtering
- Add repo selection to widget configuration (all/specific repos)
- Add "Show filters on widget" setting with filter summary display
- Remove unused utility components (Day, Graphs, filters, etc.)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 35 out of 36 changed files in this pull request and generated 4 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

BenGWeeks and others added 3 commits February 2, 2026 18:35
- Add braces to single-line if statements (curly rule)
- Convert arrow function class properties to regular methods
  to avoid TSLint semicolon rule conflict with Prettier
- Version bump to 3.1.1

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add fallback for optional IdentityRef.uniqueName/imageUrl properties
- Add request ID tracking to prevent stale async search results from
  overwriting newer ones in both IdentityPicker and RepositoryPicker

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
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