[Feat] Add TeamsHub browse UI with tab switching and registry management#290
[Feat] Add TeamsHub browse UI with tab switching and registry management#290
Conversation
…anagement Signed-off-by: samzong <samzong.lu@gmail.com>
|
Hi @samzong, DetailsInstructions for interacting with me using comments are available here. |
Summary of ChangesHello, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed! This pull request introduces the 'TeamsHub' browse UI, marking the second phase of the TeamsHub implementation plan. It enables users to discover and browse community teams from Git-native registries directly within the TeamsPanel. The changes include a new tabbed interface, a card-based browsing experience with search and category filtering, and a management dialog for registry sources, all while maintaining existing architectural patterns and IPC communication. Highlights
Using Gemini Code AssistThe full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips. Invoking Gemini You can request assistance from Gemini at any point by creating a comment using either
Customization To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a Limitations & Feedback Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for GitHub and other Google products, sign up here. Footnotes
|
Deploying cpwa with
|
| Latest commit: |
6de2d6d
|
| Status: | ✅ Deploy successful! |
| Preview URL: | https://c377cecc.cpwa.pages.dev |
| Branch Preview URL: | https://feat-teamshub-browse-ui.cpwa.pages.dev |
There was a problem hiding this comment.
Code Review
This pull request introduces the TeamsHub feature, which allows users to browse and manage community team registries through a new tabbed interface in the TeamsPanel. The implementation includes a registry management dialog, team cards, and comprehensive i18n support across multiple locales. The review feedback focuses on enhancing the robustness of the UI when interacting with external registry data. Specifically, it is recommended to add error handling for the initial registry list fetch and to use optional chaining when accessing registry properties like teams, descriptions, and tags to prevent potential runtime crashes from malformed or incomplete data.
| const res = await window.clawwork.hubListRegistries(); | ||
| if (res.ok && res.result) setRegistries(res.result); |
There was a problem hiding this comment.
If the IPC call to hubListRegistries fails (e.g., res.ok is false), the component silently stops loading and shows an empty state. It would be better to provide feedback to the user via a toast message if the initial registry list fails to load.
| const res = await window.clawwork.hubListRegistries(); | |
| if (res.ok && res.result) setRegistries(res.result); | |
| const res = await window.clawwork.hubListRegistries(); | |
| if (res.ok && res.result) { | |
| setRegistries(res.result); | |
| } else if (!res.ok) { | |
| toast.error(res.error ?? t('errors.unknown')); | |
| } |
| const allEntries = useMemo(() => { | ||
| const entries: (TeamHubEntry & { _registryId: string })[] = []; | ||
| for (const reg of registries) { | ||
| for (const team of reg.teams) { |
There was a problem hiding this comment.
The code assumes reg.teams is always defined. If a registry configuration exists but hasn't been successfully fetched or the cache is malformed, reg.teams might be undefined, leading to a crash. It's safer to use optional chaining or a default empty array.
| for (const team of reg.teams) { | |
| for (const team of reg.teams ?? []) { |
| e.name.toLowerCase().includes(q) || | ||
| e.description.toLowerCase().includes(q) || | ||
| e.tags.some((tag) => tag.toLowerCase().includes(q)), |
There was a problem hiding this comment.
The search logic performs toLowerCase() on description and some() on tags without checking if they exist. While the TypeScript interface marks them as required, data fetched from external JSON registries (via the main process) might have missing fields, causing the renderer to crash during filtering.
| e.name.toLowerCase().includes(q) || | |
| e.description.toLowerCase().includes(q) || | |
| e.tags.some((tag) => tag.toLowerCase().includes(q)), | |
| e.name.toLowerCase().includes(q) || | |
| (e.description?.toLowerCase() ?? '').includes(q) || | |
| e.tags?.some((tag) => tag.toLowerCase().includes(q)), |
| {reg.name || reg.url} | ||
| </span> | ||
| <span className="type-support flex-shrink-0 text-[var(--text-muted)]"> | ||
| {reg.fetchedAt ? t('teamshub.teamCount', { count: reg.teams.length }) : t('teamshub.notFetched')} |
There was a problem hiding this comment.
Accessing reg.teams.length directly can cause a crash if reg.teams is undefined (e.g., if the registry hasn't been fetched or the data is malformed). Using optional chaining is safer here.
| {reg.fetchedAt ? t('teamshub.teamCount', { count: reg.teams.length }) : t('teamshub.notFetched')} | |
| {reg.fetchedAt ? t('teamshub.teamCount', { count: reg.teams?.length ?? 0 }) : t('teamshub.notFetched')} |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 644fe14767
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| e.description.toLowerCase().includes(q) || | ||
| e.tags.some((tag) => tag.toLowerCase().includes(q)), |
There was a problem hiding this comment.
Harden TeamsHub search against malformed registry entries
When users search, this filter unconditionally calls e.description.toLowerCase() and e.tags.some(...). Registry data comes from external teamshub.json files and is not runtime-normalized before being rendered, so a registry entry with missing/null description or tags will throw here and break the TeamsHub tab as soon as text is entered in search. Please add safe fallbacks (for example, default description to '' and tags to []) before lowercasing/filtering.
Useful? React with 👍 / 👎.
| if (!v) { | ||
| setUrl(''); | ||
| setAddError(''); |
There was a problem hiding this comment.
Guard registry dialog close when form state is dirty
This dialog holds user-entered state (url) but closes immediately and clears that state whenever onOpenChange(false) fires, so an accidental outside click or ESC silently discards in-progress input. Per the stateful dialog rule in .claude/rules/frontend.md, this should use useDialogGuard/discard confirmation behavior; otherwise users can lose typed registry URLs without warning.
Useful? React with 👍 / 👎.
- Add error toast when initial hubListRegistries fails - Use optional chaining for registry teams/description/tags - Use Promise.allSettled for parallel refresh - Fix double-toast on remove by consolidating in parent - Reset dialog error state on close - Add teamshub.all i18n key (decouple from cron.filterAll) Signed-off-by: samzong <samzong.lu@gmail.com>
Summary
Add TeamsHub browse UI as a second tab in TeamsPanel, enabling users to browse community team registries and manage registry sources. This is PR-2 of the TeamsHub implementation plan.
Type of change
[Feat]new feature[UI]UI or UX changeWhy is this needed?
Users need a way to discover and browse community teams from Git-native registries. This PR adds the browse experience; install flow follows in PR-3.
What changed?
TeamsHubTabcomponent with search, category filter chips, refresh, and card gridTeamHubCardcomponent aligned with existing TeamCard styling (install button placeholder for PR-3)RegistryManageDialogfor adding/removing/refreshing registries with inline error displayteamshub.*i18n keys across all 8 locale filesArchitecture impact
hubListRegistries,hubFetchRegistry,hubAddRegistry,hubRemoveRegistry)docs/architecture-invariants.md: noneLinked issues
Part of TeamsHub implementation plan (PR-2 of 4).
Validation
pnpm lintpnpm check:ui-contractpnpm check:i18npnpm check:dead-codepnpm format:checkpnpm typecheckpnpm test(4 pre-existing failures infile-reader.test.ts, unrelated)Screenshots or recordings
Tab bar integrated into WindowTitlebar. TeamsHub tab shows browse grid with search + category chips. Registry dialog with inline URL validation hint and error display.
All colors use CSS variables. Typography uses semantic
type-*classes. No raw Tailwind palette colors or text sizes.Release note
Checklist
git commit -s)[Feat],[Fix],[UI],[Docs],[Refactor],[Build], or[Chore]