Skip to content

feat(ui-react): implement announcements admin panel#6133

Open
luizhf42 wants to merge 3 commits intomasterfrom
feat/ui-react/admin-announcement-pages
Open

feat(ui-react): implement announcements admin panel#6133
luizhf42 wants to merge 3 commits intomasterfrom
feat/ui-react/admin-announcement-pages

Conversation

@luizhf42
Copy link
Copy Markdown
Member

@luizhf42 luizhf42 commented Apr 7, 2026

What

Full CRUD for system-wide announcements in the React admin panel — list with pagination, detail view, create page, edit page, and delete confirmation. Content is authored with a Tiptap v3 rich text editor and stored as markdown on the backend.

Why

Feature #10 from shellhub-io/team#93. The announcements feature existed only in the Vue admin panel and needed to be ported to the React console.

Changes

  • Routing: Four lazy-loaded routes under /admin/announcements, conditionally registered when getConfig().announcements is enabled. Routes are inside AdminRoute > LicenseGuard, so they inherit admin auth and license checks. Direct URL access returns 404 when the feature flag is off.
  • Data hooks: useAdminAnnouncements (paginated list + single entity) and useAdminAnnouncementMutations (create, update, delete with query invalidation). Follow the exact patterns from useAdminNamespaces and useAdminNamespaceMutations.
  • Rich text editor: Tiptap v3 with @tiptap/markdown for native bidirectional markdown support — eliminates the Vue codebase's Turndown + MarkdownIt conversion pipeline. Toolbar with bold, italic, strike, headings, lists, blockquote, code blocks, links, images, undo/redo. Includes roving tabindex for keyboard navigation.
  • Security: isAllowedUrl utility (extracted to utils/url.ts) validates link/image URLs against an allowlist (http:, https:, mailto:) in both the editor toolbar prompts and the Link extension's validate option (covers paste/auto-detect). The read-only renderer adds rel="noopener noreferrer" and target="_blank" to rendered links.
  • Read-only renderer: AnnouncementContent uses a non-editable Tiptap instance with the same extensions as the editor, guaranteeing visual parity. Parent passes key={uuid} to force re-mount on content changes.
  • List page: Paginated table with UUID chip, title, date, and action buttons (edit navigates, delete opens dialog). Auto-resets to last valid page after deleting the final item on a non-first page.
  • Create/Edit pages: Full-page forms wrapped in <form> for Enter-key submission. Title field with live character counter (max 90). Edit page uses null state to distinguish "not yet edited" from "cleared", avoiding overwrites on query refetch.
  • Tests: 47 unit tests covering the list page (rendering, loading/empty/error states, navigation, pagination, delete action) and the delete dialog (confirmation flow, error handling, callback order, null announcement guard).

Testing

  • Enable the announcements feature flag in the dev environment config
  • Create an announcement with rich text (headings, lists, links, images by URL), verify it stores and renders correctly
  • Edit an existing announcement, verify title and content update without losing formatting
  • Delete from both the list page and detail page
  • Test with the feature flag disabled — /admin/announcements should 404, sidebar link should be hidden
  • Verify keyboard navigation through the editor toolbar (Tab enters, arrow keys cycle, Tab exits)

@luizhf42 luizhf42 requested a review from a team as a code owner April 7, 2026 20:32
@github-actions
Copy link
Copy Markdown

github-actions bot commented Apr 7, 2026

Claude finished @luizhf42's task in 5m 22s —— View job


Code Review Complete

Reviewed 16 files across code quality, security, testing, TypeScript/React patterns, and architecture. 1 inline issue posted (medium severity — URL validation bug).

The overall implementation is solid: routing is correctly nested under AdminRoute > LicenseGuard with feature-flag gating, hooks follow established patterns (useAdminNamespaces/useAdminNamespaceMutations), the rich-text editor has good accessibility (roving tabindex, ARIA attributes), and the 47 unit tests provide thorough coverage of the list page and delete dialog. No pkg/ changes, so no cross-repo impact on cloud/enterprise.

If you've addressed the feedback and want a new review, tag @shellhub-io/admin and a team member can trigger it.


@luizhf42 luizhf42 force-pushed the feat/ui-react/admin-announcement-pages branch 2 times, most recently from ab1e6f0 to 1cd6745 Compare April 7, 2026 20:43
@luizhf42 luizhf42 self-assigned this Apr 8, 2026
@luizhf42 luizhf42 added kind/feature New feature or request area/ui status/work-in-progress product/enterprise Issue/PR related to Enterprise Edition do-not-merge labels Apr 8, 2026
@luizhf42 luizhf42 force-pushed the feat/ui-react/admin-announcement-pages branch from 1cd6745 to 5d771f4 Compare April 8, 2026 18:40
@luizhf42 luizhf42 requested a review from a team as a code owner April 8, 2026 18:40
@gustavosbarreto
Copy link
Copy Markdown
Member

/review

@github-actions
Copy link
Copy Markdown

github-actions bot commented Apr 8, 2026

Claude finished @gustavosbarreto's task in 1m 40s —— View job


Code Review Complete

Reviewed 16 files across code quality, security, testing, TypeScript/React patterns, and architecture. 1 inline issue posted (high severity — stale editor content on same-route navigation).

The overall implementation is solid: routing is correctly nested under AdminRoute > LicenseGuard with feature-flag gating, hooks follow established patterns (useAdminNamespaces/useAdminNamespaceMutations), the Tiptap editor has good accessibility (roving tabindex, ARIA attributes), URL validation correctly blocks dangerous protocols, and the 47 unit tests provide thorough coverage. No pkg/ changes, so no cross-repo impact on cloud/enterprise.


If you've addressed the feedback and want a new review, tag @shellhub-io/admin and a team member can trigger it.

luizhf42 added 3 commits April 8, 2026 15:58
Add SHELLHUB_ANNOUNCEMENTS env var to docker-compose and
gen-config.sh so the React UI can read the flag at runtime.
Without this, getConfig().announcements always returned the
default (false) and the sidebar entry was never shown.
Add full CRUD for system-wide announcements in the React
admin panel, gated behind the announcements feature flag.

- Tiptap v3 rich text editor with markdown storage
- List page with pagination, detail, create, and edit pages
- URL validation (isAllowedUrl) to prevent XSS via links
- Read-only content renderer with link security attributes
- Delete confirmation dialog with query invalidation
Cover list page and delete dialog with 47 unit tests:
rendering, loading/empty/error states, navigation,
pagination, delete confirmation flow, and error handling.
@luizhf42 luizhf42 force-pushed the feat/ui-react/admin-announcement-pages branch from 5d771f4 to e457a25 Compare April 8, 2026 18:58
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/ui do-not-merge kind/feature New feature or request product/enterprise Issue/PR related to Enterprise Edition status/work-in-progress

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants