Feat/unified data explorer - #268
Merged
Merged
Conversation
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
… toast Review findings on Task 5: the tab-persistence comment claimed adapter `state` was excluded from localStorage when it never was (state IS persisted on purpose — it restores page/query/sort across sessions, since fetched rows live in the adapter's actions hook, not on the tab). Replaced the comment to describe the actual contract instead of stripping the field. Also routed the "Could not load connections" toast fallback through DataExplorer.toast.loadFailed instead of a hardcoded string. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…ned tabs - useCallback the four sidebar handlers in the shell so React.memo on ConnectionRow survives page-level renders (openTab et al). - aria-label on the row action menu trigger, aria-expanded on the group header and the connection toggle, focus-within reveal for keyboard users. - Drop tabs whose connection was deleted, gated on an explicit connectionsLoaded flag plus isInitialized so a cold start never wipes tabs restored from localStorage and a failed fetch never prunes. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…gh i18n validate() now returns DataExplorer-relative i18n keys instead of hardcoded English; the connection dialog resolves them via t(). testConnection's "Connection failed" fallback is gone — it throws empty when there's no sanitised server message, and the dialog supplies connectionDialog.testFailed. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
… cross-server sync Adds copy-db-name, collection multi-select + bulk delete, in-tree search filtering, and cross-server sync targets. SidebarTreeProps gains searchQuery and siblings (source-agnostic: the shell buckets by sourceId equality). Also: per-mode name-validation messages, sorted collections, no No-databases flash, sanitizeError on every error path. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The MongoDB pane wired onDelete straight to actions.remove, so a row's trash icon deleted a document irreversibly with no prompt — the legacy page's handleDelete only opens an AlertDialog and confirmDelete does the work, and DocumentView confirms bulk delete but not single delete. Restore the dialog in the pane, since document-view.tsx cannot be modified. The shell rendered <Pane> with no key. Panes are stable component references, so a same-source tab switch reconciled the same instance and carried the previous collection's documents, view mode, selection and index data across. Key it per tab, which also resets the actions hook's document state and covers every other adapter. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
sanitizeRedisError returned the raw message when new URL(redisUrl) threw, even though validate() only checks the scheme and lets malformed URLs through (e.g. a non-numeric port). Rebuild it on the existing nosql-error-sanitizer.ts pattern: scrub any redis(s):// URL wholesale by regex, run the result through the shared sanitizeError for generic user:password@ and email patterns, then apply the URL-parse-based credential strip only as a best-effort extra layer that strips both the raw and percent-encoded form of the username/password. A parse failure in that last layer no longer changes whether the message was sanitized. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The pane's db selector wrote state.db while the tab's shell-owned id and title stayed frozen at open time, so a switched tab mislabelled its database and a second tab could open on the same one. Database switching is now a sidebar-tree-only action, which always opens or focuses the correctly identified tab. The connection form no longer offers a read-only switch: ValueEditor and CommandPanel take no readOnly prop, so the flag could only ever hide Flush and BulkActions, not "block every write operation" as the hint promises. The field stays in the data model and keeps gating those two controls. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…tate Review findings: dedupe key was (sourceId, name) only, silently dropping distinct connections sharing a name (legacy Mongo defaults unnamed rows to "My Connection"); fold in a config discriminator (connectionString/redisUrl) so same-named-different-config rows both import while true duplicates still dedupe to zero, including across a name-only case/whitespace difference. Gate the import on the shell's connectionsLoaded flag so a failed or in-flight unified-list fetch can't make every legacy connection look new. Drop the raw error message from the fetch-failure toast (untranslated, unnecessary risk in a credential-handling flow) and report total failure (imported === 0, failed > 0) as toast.error instead of toast.success. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Translates the 127-key DataExplorer namespace, Navigation.dataExplorer and Dashboard.tools.dataExplorer into the 26 non-English locales. Plural categories follow CLDR per locale: full zero/one/two/few/many/other for ar, one/few/many/other for pl/ru/uk/cs, other-only for ja/ko/ms/vi/zh. Also hardens legacy-import's normalizeName against a stored row with a missing name, which previously threw out of dedupeAgainstExisting and blocked the entire legacy import. Verified: 27/27 locales valid JSON with exactly one DataExplorer block, complete key parity and placeholder parity against en.json; 4536 ICU renders compiled and formatted across all locales with zero failures; tsc clean; jest 118/119 suites, 1040 tests (sole failure is the pre-existing react-window suite); cargo test 38 passed. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
… readOnly, safe restore - page: render an IconMenu2 sidebar trigger whenever the viewport is narrow. `setMobileSidebarOpen(true)` had no caller, so under 768px the sidebar lived in a Sheet nothing could open and the tool was an unrecoverable dead end. - connection-dialog: `testConnection` is now an explicit optional button, not a precondition for saving. Only `adapter.validate` gates the save, matching the legacy Mongo form, so a rename/recolour saves off-VPN and a connection to a server that is not up yet can be pre-created. Success and failure both render inline. Source-agnostic: the flow changes for every adapter. - types/tab-bar: drop `UnifiedTab.readOnly`. It was captured at open time and persisted, so it went stale the moment the connection was edited. The tab bar now resolves the lock glyph from the live connection. - redis adapter: seed the builder fields from the stored URL via a new defensive `parseRedisUrl` (returns null instead of throwing). Editing a saved connection and touching Builder used to submit redis://localhost:6379 and destroy the stored credentials. The password is never rendered — it is re-attached on submit unless the user types a replacement. - tab restore: validate shape before use (new lib/data-explorer/tab-storage.ts). A parsed-but-wrong value crashed the tool on mount and was never cleared, because the parse had succeeded. New i18n key `DataExplorer.openSidebar` in all 27 locales; `connectionDialog.test` and `testOk` were already translated everywhere and are now wired. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Replaces the two-step grid-of-buttons picker with an always-visible Select at the top of the connection dialog. Creating defaults to the first registered source so the dialog opens ready to type; editing pins the source, since changing what kind of database an existing connection points at was never coherent. Switching source clears any error and test result from the previous one, and the adapter form is keyed by adapter id so no field carries over. Reuses the existing connectionDialog.pickSource label, so no new keys and no change to the 27-locale parity. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The source dropdown already says "MongoDB", so the form's second mongodb/documentdb/cosmosdb/ferretdb picker read as a duplicate question. Removed it and derived dbType from the connection string. dbType stays load-bearing: normalizeConnectionString appends retryWrites=false for DocumentDB and Cosmos, which reject the driver's default and would otherwise fail writes silently. Both are identifiable by their managed hostnames, which is what detectDbType matches (already covered by lib/__tests__/nosql-dialects.test.ts). When detection cannot tell, the connection's saved dbType is kept, so an explicit FerretDB choice from an older build survives an edit. The connection-string placeholder still follows the inferred dialect. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Contributor
|
Unable to deploy a commit from a private repository on your GitHub organization to the itsmeakhil's projects team on Vercel, which is currently on the Hobby plan. In order to deploy, you can:
To read more about collaboration on Vercel, click here. |
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
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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.
No description provided.