-
Notifications
You must be signed in to change notification settings - Fork 21
Release 0.7.1
#517
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Release 0.7.1
#517
Changes from 95 commits
Commits
Show all changes
102 commits
Select commit
Hold shift + click to select a range
63ee520
sync next and main (#501)
tnaum-ms c609539
feat: add maxWorkers configuration to optimize memory usage in Jest
tnaum-ms 56ca5c3
feat: implement tests for vscodeLink operations including queries, mu…
tnaum-ms c7f7fa6
feat: update @trpc/client and @trpc/server to version 11.10.0
tnaum-ms afcea58
Initial plan
Copilot 5ceda4f
Add experimental AI query generation setting and activation telemetry
Copilot d06bbb8
Revert unrelated package-lock.json changes
Copilot 9c01543
feat: implement support for tRPC query and mutation cancellation usin…
tnaum-ms 5381ca8
feat: enhance BaseRouterContext with detailed AbortSignal documentati…
tnaum-ms 69ae902
feat: add SKILL.md for webview tRPC messaging with detailed guidance …
tnaum-ms 522eb28
feat: refactor WebviewController to support AbortSignal for query and…
tnaum-ms 4b74c1a
feat: refactor WebviewController and appRouter for improved AbortSign…
tnaum-ms a76a9ac
feat: enhance type safety for webview names and update SKILL.md with …
tnaum-ms a40fc5e
Initial plan
Copilot c330a3c
Add PromptReconnectStep and ReconnectStep to updateCredentials wizard
Copilot 3883a91
Revert package-lock.json changes from npm install
Copilot 73f41d9
feat: add AbortSignal support for query cancellation across various s…
tnaum-ms 957e1fb
feat: propagate UserCancelledError for AbortSignal in query optimizat…
tnaum-ms d267243
feat: enhance query optimization with AbortSignal cancellation handli…
tnaum-ms d0b9627
feat: add cancellation messages for query insights and log Copilot ca…
tnaum-ms 2fb430f
feat: add explanation for AbortSignal handling in sendSafe function t…
tnaum-ms 458e1f3
feat: implement AbortSignal handling in dispose method to abort activ…
tnaum-ms 392f135
Fix lint errors in PromptReconnectStep.test.ts
Copilot c8d6275
docs: update SKILL.md to use ${workspaceFolder} for file paths and ad…
tnaum-ms fcac390
Fix unbound-method lint errors in PromptReconnectStep.test.ts
Copilot b8ffaf2
Add PR Completion Checklist to copilot-instructions.md
Copilot 8d39b6d
test: update expectation in vscodeLink tests to account for signal st…
tnaum-ms cbdf501
test: update expectation in vscodeLink tests to verify operation stru…
tnaum-ms 53cdc3e
Apply prettier formatting fixes
Copilot 3a740d2
Address review feedback on PromptReconnectStep
Copilot 821b8b5
Show reconnect prompt when updating credentials from error node
Copilot fea7cb8
Rename isInErrorState to offerReconnect and apply reconnect to update…
Copilot ae97c48
Add React Webview Architecture and Guidelines documentation
tnaum-ms a12913c
Refactor reconnect logic in UpdateCS and UpdateCredentials wizards
tnaum-ms fbe02bb
Make experimentalFeaturesStatus telemetry fire-and-forget
Copilot 7d2d536
Revert unrelated package-lock.json changes
Copilot 9b01edc
Refactor reconnect handling in UpdateCredentials wizard and remove un…
tnaum-ms 5db9cd7
docs: clarify webviewName naming distinction in tRPC messaging skill
tnaum-ms 84482df
docs: document panel ownership architecture in WebviewController.disp…
tnaum-ms 97d6fa5
fix: add double-dispose guard to WebviewController.dispose()
tnaum-ms 5c12c2a
fix: clear Stage 3 AbortController ref on completion/failure
tnaum-ms 65545d1
refactor: rename webview identifiers for consistency in WebviewRegistry
tnaum-ms abb5225
docs: add description for webviewName in BaseRouterContext
tnaum-ms 7a4125d
Add experimental setting for AI query generation and activation telem…
tnaum-ms ba7df90
Merge branch 'next' into copilot/add-wizard-step-for-reconnecting
tnaum-ms 77f95e0
refactor: use instance extensionContext instead of global ext.context…
tnaum-ms f8c668a
fix: prevent overwriting telemetry result='Canceled' with 'Failed' on…
tnaum-ms ec5510c
fix: prettier-fix
tnaum-ms c936c5d
Add reconnect prompt to credential update wizard for error recovery n…
tnaum-ms 4d357fb
Merge branch 'next' into dev/tnaum/320-feat-support-trpc-query-cancel…
tnaum-ms 0153bd6
feat: TRCP upgrade + abort signal support (#502)
tnaum-ms 8a1ac34
chore(deps): bump qs and body-parser
dependabot[bot] 66b2b9e
chore(deps): bump qs and body-parser (#505)
tnaum-ms 64f03fb
docs: add feedback collection section to README
tnaum-ms 663013c
docs: update feedback collection instructions in README
tnaum-ms 390eeac
docs: add feedback collection section to README (#509)
tnaum-ms 33d143b
docs: add connection string deduplication details to v0.7.0 release n…
tnaum-ms b12cf2e
docs: reorder dark theme rendering fix in changelog
tnaum-ms 4b3653b
Defensive trimming and validation simplification for connection strin…
tnaum-ms 4a94afa
Initial plan
Copilot 6130185
Remove redundant trimming in connection string handling
Copilot 387f51e
Move trimming to explicit separate line as requested
Copilot a2f0bd8
Move trimming to explicit separate line in connection string wizard s…
tnaum-ms 5fe6a0e
chore: release notes 0.7 + change log update (#510)
tnaum-ms 2c5d7d1
Merge branch 'next' into dev/tnaum/connection-string-handling
tnaum-ms e19ed25
Enhance storage connection string handling: add validation and cleanu…
tnaum-ms 1102940
test: add whitespace trimming tests for sanitizeConnectionString
tnaum-ms 446b21b
refactor: remove redundant .toString() in ExecuteStep
tnaum-ms bf94c78
test: add validatePassword unit tests
tnaum-ms c9750b6
Redact credentials from log messages that interpolate parser errors
tnaum-ms 062d828
Document design intent for automatic cleanup of invalid connections
tnaum-ms e01fc14
Fix misleading success toast after failed connection-string save
tnaum-ms 9e9f14e
chore(deps-dev): bump minimatch from 3.1.2 to 3.1.4
dependabot[bot] ca2e48e
feat: refactor data migration command and add announced migration pro…
tnaum-ms 1bacb29
refactor: remove unused url property from announced provider QuickPic…
tnaum-ms fff1593
fix: validate announced providers array and shape from package.json
tnaum-ms 97483ba
refactor: remove unused url field from AnnouncedMigrationProvider
tnaum-ms 0392dfa
test: validate x-announcedMigrationProviders shape in package.json
tnaum-ms ca773cb
fix: prettier-fix
tnaum-ms bf3d738
chore(deps-dev): bump minimatch from 3.1.2 to 3.1.4 (#514)
tnaum-ms 52b2b1a
version bump to `0.7.1`
tnaum-ms 459b5a2
chore: update release notes for v0.7.1 patch release
tnaum-ms 96eaf62
chore: update release notes to include v0.7.1 patch release
tnaum-ms 65dc442
chore: add instructions for updating release notes index
tnaum-ms 78de61c
Merge branch 'next' into dev/tnaum/connection-string-handling
tnaum-ms 97a442d
Defensive trimming and validation simplification for connection strin…
tnaum-ms a1e7c98
Merge branch 'next' into dev/tnaum/announce-migration-providers
tnaum-ms 30caad8
feat: Data Migration discoverability — announced providers & always-v…
tnaum-ms 6929920
Update src/services/migrationServices.ts
tnaum-ms fe52895
Merge branch 'next' into dev/tnaum/prepare-0.7.1-release
tnaum-ms 6fbdc7c
Prepare `0.7.1` release (#516)
tnaum-ms e9e2182
docs: clarify RFC 3986 assumption in redactCredentialsFromConnectionS…
tnaum-ms 960118e
fix: clear Stage 3 tips/error timer on cancel and re-trigger
tnaum-ms 3af9111
Add unmount cleanup for query insights timer
tnaum-ms e0664a6
[WIP] Pre-release updates `0.7.1` (#519)
tnaum-ms 6f5099f
fix: dispose EventEmitter in WebviewController.dispose()
tnaum-ms 45cddc7
fix: abort in-flight AI request on QueryInsightsTab unmount
tnaum-ms 69f3942
fix: abort previous Stage 3 request before starting a new one
tnaum-ms c4b1c98
fix: correct GitHub branding in comment
tnaum-ms 9c0fe64
docs: update SKILL.md to use current WebviewRegistry keys
tnaum-ms a05760e
docs: fix accessibility skill name reference
tnaum-ms 106c48b
chore: run npm install
tnaum-ms File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,248 @@ | ||
| --- | ||
| name: react-webview-architecture | ||
| description: Architecture patterns for React-based webviews in the vscode-documentdb extension. Use when creating new webview components, modifying existing views (CollectionView, DocumentView), working with state management (Context API), integrating Fluent UI components, handling Monaco Editor or SlickGrid, solving stale closure bugs with refs, or debugging webview rendering issues. Does NOT cover tRPC messaging (see webview-trpc-messaging skill) or accessibility/ARIA (see detecting-accessibility-issues skill). | ||
| --- | ||
|
|
||
| # React Webview Architecture | ||
|
|
||
| Patterns and conventions for React webviews in vscode-documentdb. | ||
|
|
||
| **Related skills** (do not duplicate): | ||
|
|
||
| - **webview-trpc-messaging** — tRPC routers, procedures, telemetry, AbortSignal, subscriptions, WebviewController | ||
| - **detecting-accessibility-issues** — ARIA labels, Announcer, focus management, screen reader patterns | ||
|
|
||
| **Full reference**: See [references/REACT_ARCHITECTURE_GUIDELINES.md](./references/REACT_ARCHITECTURE_GUIDELINES.md) | ||
|
|
||
| ## When to Use | ||
|
|
||
| - Creating or modifying a webview (DocumentView, CollectionView) | ||
| - Adding new components inside `src/webviews/` | ||
| - Working with CollectionView context or state management | ||
| - Integrating Monaco Editor or SlickGrid | ||
| - Debugging stale closure issues in event handlers | ||
|
|
||
| ## Rendering Pipeline | ||
|
|
||
| Every webview boots through `src/webviews/index.tsx`: | ||
|
|
||
| ```tsx | ||
| root.render( | ||
| <DynamicThemeProvider useAdaptive={true}> | ||
| <WithWebviewContext vscodeApi={vscodeApi}> | ||
| <Component /> | ||
| </WithWebviewContext> | ||
| </DynamicThemeProvider>, | ||
| ); | ||
| ``` | ||
|
|
||
| - **`DynamicThemeProvider`** — adapts Fluent UI theming to VS Code's active color theme | ||
| - **`WithWebviewContext`** — provides `vscodeApi` (postMessage) via React Context | ||
| - **`WebviewRegistry`** — maps webview names → React components (in `api/configuration/WebviewRegistry`) | ||
|
|
||
| Configuration from the extension host is read via `useConfiguration<T>()`. | ||
|
|
||
| ## File Organization | ||
|
|
||
| ``` | ||
| viewName/ | ||
| ├── ViewName.tsx # Main component | ||
| ├── viewName.scss # Styles | ||
| ├── viewNameContext.ts # Context + state types (if complex) | ||
| ├── viewNameController.ts # WebviewController subclass (extension-side) | ||
| ├── viewNameRouter.ts # tRPC router (extension-side, see webview-trpc-messaging skill) | ||
| ├── constants.ts | ||
| ├── components/ # Sub-components | ||
| ├── hooks/ # Custom React hooks | ||
| ├── types/ # TypeScript types | ||
| └── utils/ # Helpers | ||
| ``` | ||
|
|
||
| ## Component Hierarchy | ||
|
|
||
| **DocumentView** (simpler, good reference pattern): | ||
|
|
||
| ``` | ||
| DocumentView | ||
| ├── ProgressBar (conditional: isLoading) | ||
| ├── ToolbarDocuments | ||
| └── MonacoEditor | ||
| ``` | ||
|
|
||
| **CollectionView** (complex, multi-tab): | ||
|
|
||
| ``` | ||
| CollectionView | ||
| ├── ProgressBar (conditional) | ||
| ├── ToolbarMainView | ||
| ├── QueryEditor | ||
| │ └── MonacoAutoHeight (multiple: filter, project, sort) | ||
| ├── TabList (Results | Query Insights [PREVIEW]) | ||
| ├── Results Tab: | ||
| │ ├── ToolbarViewNavigation + ToolbarDocumentManipulation + ViewSwitcher | ||
| │ ├── DataViewPanelTable / DataViewPanelTree / DataViewPanelJSON | ||
| │ └── ToolbarTableNavigation (Table View only) | ||
| └── Query Insights Tab: | ||
| └── QueryInsightsMain (3-stage progressive loading) | ||
| ``` | ||
|
|
||
| ## State Management | ||
|
|
||
| ### Simple views (DocumentView): local `useState` + props | ||
|
|
||
| ### Complex views (CollectionView): React Context with `[state, setState]` tuple | ||
|
|
||
| ```tsx | ||
| export const CollectionViewContext = createContext< | ||
| [CollectionViewContextType, React.Dispatch<React.SetStateAction<CollectionViewContextType>>] | ||
| >([DefaultCollectionViewContext, () => {}]); | ||
|
|
||
| // Provider in parent | ||
| const [currentContext, setCurrentContext] = useState(DefaultCollectionViewContext); | ||
| <CollectionViewContext.Provider value={[currentContext, setCurrentContext]}> | ||
|
|
||
| // Consumer in child | ||
| const [currentContext, setCurrentContext] = useContext(CollectionViewContext); | ||
| ``` | ||
|
|
||
| **Always use functional updates** when state depends on previous value: | ||
|
|
||
| ```tsx | ||
| setCurrentContext((prev) => ({ | ||
| ...prev, | ||
| isLoading: true, | ||
| activeQuery: { ...prev.activeQuery, pageNumber: 1 }, | ||
| })); | ||
| ``` | ||
|
|
||
| ## Stale Closure Pattern (CRITICAL) | ||
|
|
||
| Third-party components (SlickGrid) bind event handlers at initialization — they don't update when state changes. **Always use refs** to access current data in those handlers: | ||
|
|
||
| ```tsx | ||
| const dataRef = useRef(data); | ||
| useEffect(() => { | ||
| dataRef.current = data; | ||
| }, [data]); | ||
|
|
||
| const onCellDblClick = useCallback((event) => { | ||
| const item = dataRef.current[event.detail.args.row]; // ✅ always current | ||
| // NOT: data[event.detail.args.row]; ❌ stale closure | ||
| }, []); // stable deps only | ||
| ``` | ||
|
|
||
| **Why**: SlickGrid binds handlers once at init time. Without refs, handlers see the data from initialization, not the latest state. This caused multiple hard-to-debug issues. | ||
|
|
||
| ## Monaco Editor | ||
|
|
||
| ### Required patterns: | ||
|
|
||
| 1. **Manual layout** — Monaco doesn't auto-resize: | ||
|
|
||
| ```tsx | ||
| useEffect(() => { | ||
| const handler = debounce(() => editorRef.current?.layout(), 200); | ||
| window.addEventListener('resize', handler); | ||
| handleResize(); // initial layout | ||
| return () => window.removeEventListener('resize', handler); | ||
| }, []); | ||
| ``` | ||
|
|
||
| 2. **Dispose on unmount**: | ||
|
|
||
| ```tsx | ||
| return () => { | ||
| editorRef.current?.dispose(); | ||
| }; | ||
| ``` | ||
|
|
||
| 3. **MonacoAutoHeight** — self-sizing editor for query fields: | ||
|
|
||
| ```tsx | ||
| <MonacoAutoHeight | ||
| adaptiveHeight={{ enabled: true, maxLines: 10, minLines: 1, lineHeight: 19 }} | ||
| onExecuteRequest={() => onExecuteRequest()} | ||
| onMount={(editor, monaco) => handleEditorDidMount(editor, monaco)} | ||
| /> | ||
| ``` | ||
|
|
||
| 4. **JSON Schema delay** — Monaco's JSON worker may not be ready immediately after mount. An AbortController-guarded delay is used (see QueryEditor for the pattern). | ||
|
|
||
| ## Fluent UI Integration | ||
|
|
||
| Use `@fluentui/react-components` (v9), themed via `DynamicThemeProvider`: | ||
|
|
||
| | Component | Usage | | ||
| | -------------------------- | ------------------------- | | ||
| | `ProgressBar` | Loading states | | ||
| | `Button`, `ToggleButton` | Toolbar actions | | ||
| | `Tab`, `TabList` | View switching | | ||
| | `Dropdown`, `Option` | Selection (ViewSwitcher) | | ||
| | `Badge` | Status/preview indicators | | ||
| | `MessageBar` | Info/warning messages | | ||
| | `Skeleton`, `SkeletonItem` | Loading placeholders | | ||
|
|
||
| Animations: `Collapse` from `@fluentui/react-motion-components-preview` | ||
|
|
||
| ## Styling | ||
|
|
||
| - Each component gets its own `.scss` file, imported directly | ||
| - Shared styles in `sharedStyles.scss`, applied via `@extend` | ||
| - **Consistent spacing unit: `10px`** with flexbox `row-gap`/`column-gap` | ||
| - **No inline styles** — move to SCSS files | ||
| - Avoid negative margins — fix layout with proper flexbox | ||
|
|
||
| ```scss | ||
| .documentView { | ||
| display: flex; | ||
| flex-direction: column; | ||
| height: 100vh; | ||
| row-gap: 10px; | ||
| } | ||
| ``` | ||
|
|
||
| ## Custom Hooks | ||
|
|
||
| | Hook | Purpose | | ||
| | ------------------------------------- | -------------------------------------------------------------------------------------------- | | ||
| | `useSelectiveContextMenuPrevention()` | Prevents browser context menu everywhere except Monaco editors. Call once in top-level view. | | ||
| | `useHideScrollbarsDuringResize()` | Returns a function that temporarily hides scrollbars during layout transitions (500ms). | | ||
|
|
||
| ## Conditional Rendering Patterns | ||
|
|
||
| **Object-based switch:** | ||
|
|
||
| ```tsx | ||
| {{ | ||
| 'Table View': <DataViewPanelTable {...props} />, | ||
| 'Tree View': <DataViewPanelTree {...props} />, | ||
| 'JSON View': <DataViewPanelJSON {...props} />, | ||
| }[currentContext.currentView]} | ||
| ``` | ||
|
|
||
| ## Loading State | ||
|
|
||
| ```tsx | ||
| const [isLoading, setIsLoading] = useState(false); | ||
| setIsLoading(true); | ||
| try { | ||
| await op(); | ||
| } finally { | ||
| setIsLoading(false); | ||
| } | ||
|
|
||
| // In render: | ||
| { | ||
| isLoading && <ProgressBar thickness="large" shape="square" className="progressBar" />; | ||
| } | ||
| ``` | ||
|
|
||
| ## Common Pitfalls | ||
|
|
||
| 1. **Forgetting refs with third-party components** → stale data in event handlers | ||
| 2. **Not cleaning up** event listeners, Monaco instances, AbortControllers in `useEffect` return | ||
| 3. **Not calling `editor.layout()`** after resize → blank Monaco panels | ||
| 4. **Using `any`** → use proper types or `unknown` with type guards | ||
| 5. **Missing `l10n.t()`** on user-facing strings | ||
| 6. **Inline styles** instead of SCSS files | ||
| 7. **Negative margins** to fix spacing — restructure layout with flexbox gap instead | ||
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.