feat(FR-3223): allow editing the system announcement from the WebUI#8067
feat(FR-3223): allow editing the system announcement from the WebUI#8067agatha197 wants to merge 18 commits into
Conversation
How to use the Graphite Merge QueueAdd either label to this PR to merge it via the merge queue:
You must have a Graphite account in order to use the merge queue. Sign up using this link. An organization admin has required the Graphite Merge Queue in this repository. Please do not merge from GitHub as this will restart CI on PRs being processed by the merge queue. This stack of pull requests is managed by Graphite. Learn more about stacking. |
There was a problem hiding this comment.
Pull request overview
Adds a superadmin-only UI flow to edit the system announcement directly from the start-page announcement alert, including a markdown-capable code editor and live preview, and persists changes via the existing manager API.
Changes:
- Added
AnnouncementEditModalwith an enabled toggle, markdown editor, preview, and save/invalidate flow. - Updated
AnnouncementAlertto show an Edit action for superadmins and open the edit modal. - Extended
BAICodeEditorto support Monaco’smarkdownlanguage and added i18n strings (en/ko).
Reviewed changes
Copilot reviewed 5 out of 5 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
| resources/i18n/ko.json | Adds Korean strings for the announcement edit UI. |
| resources/i18n/en.json | Adds English strings for the announcement edit UI. |
| react/src/components/BAICodeEditor.tsx | Adds markdown to supported editor languages and Monaco language mapping. |
| react/src/components/AnnouncementEditModal.tsx | New modal for editing announcement content with markdown preview and saving via update_announcement. |
| react/src/components/AnnouncementAlert.tsx | Adds superadmin-gated Edit button and wires modal opening from the alert. |
Coverage Report for react-coverage (./react)
File Coverage
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||
7432b9d to
6c600dd
Compare
5d71df8 to
fff7f6f
Compare
|
Also addressed the suggestion from the Teams thread: |
fff7f6f to
68b42c8
Compare
84fda1a to
dfd8144
Compare
ironAiken2
left a comment
There was a problem hiding this comment.
Markdown formatting for 'quotes, code and lists' is not applied.
dfd8144 to
9d1c3fc
Compare
I applied it. |
Add a superadmin-only edit flow for the system announcement, surfaced directly on the announcement alert where it is displayed. - BAICodeEditor: add 'markdown' language so the message can be authored with Monaco's markdown support. - AnnouncementEditModal: new modal with an enabled toggle, a markdown code editor, and a live preview rendered with the same markdown-to-jsx setup as the alert. Saves via baiClient.service.update_announcement and invalidates the announcement query so the alert refreshes immediately. - AnnouncementAlert: show an Edit button on the alert for superadmins only (the manager update endpoint is superadmin-only) that opens the modal. - i18n: add the announcement-edit strings (en, ko). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Address PR review feedback: - Pass initialEnabled from the announcement query and initialize the modal's enabled toggle from it, so the switch reflects the server's current state instead of always defaulting to true. - Wrap the modal in BAIUnmountAfterClose so it remounts on each open; this drops the manual useEffect re-sync and removes the stale-state class of bugs (the useState initializers are now the single source). - Add the new summary.* announcement keys to all remaining locales.
…eview
- Block saving (with an inline error) when the announcement is enabled
but the message is empty, mirroring the backend constraint ("Empty
message not allowed to enable announcement"); mark the message field
required while enabled.
- Lay the markdown editor and live preview side by side (editor left,
preview right) and widen the modal, matching the conventional markdown
editor UX.
- i18n: add summary.AnnouncementMessageRequired across all locales.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- Mark the Enabled and Preview fields as required so the form's "(optional)" suffix no longer renders on them. - Make the preview box padding visually even on all sides by collapsing the first/last block margins via a scoped style, instead of the negative bottom-margin trick. - Remove the "Markdown syntax is supported." help text and its now-unused summary.AnnouncementMarkdownHelp key across all locales. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…n renderer - Add useSuspenseGetAnnouncement hook + ANNOUNCEMENT_QUERY_KEY constant so the get_announcement query and its key live in one place (also used for cache invalidation in the edit modal), removing the duplicated query. - Add AnnouncementMarkdown component and use it in both the alert and the modal preview, replacing two divergent markdown-rendering blocks with a single shared, margin-collapsed renderer. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Replace the manual message/enabled useState + onOk guard with a Form.useForm() instance: - name-bound fields (Switch via valuePropName, BAICodeEditor as a controlled field) so the form store is the single source of truth. - declarative validation: the "message required when enabled" rule lives on the field (dependencies on enabled) and shows an inline error instead of a toast. - the live preview and the required marker read from Form.useWatch. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
… state Replace the useState open/close flag in AnnouncementAlert with ahooks useToggle, matching the project idiom (e.g. ConfigurationsSettingList): the toggle handler drives both the Edit button and onRequestClose. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The preview was a content-box div, so its padding/border made it taller than the markdown editor. Set box-sizing: border-box and size it to the editor's outer height (shared EDITOR_HEIGHT constant + the wrapper border) so both boxes line up. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Widen the modal to 90% / max 1900px (matching FolderExplorerModalV2) and grow the editor/preview to a viewport-relative height so there is ample room to author and preview markdown side by side. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Address review feedback (seungwon): - AnnouncementEditModal now reads the announcement via useSuspenseGetAnnouncement directly (under a Suspense boundary) instead of receiving initialMessage/initialEnabled props from the parent. - Rename the hook file to useSuspenseGetAnnouncement.tsx to match its primary export. - Drop the shared AnnouncementMarkdown component; render the markdown inline in the alert and the modal preview. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Per review (seungwon): factor the announcement queryKey + queryFn into a TanStack queryOptions factory (announcementQueryOptions) and keep useSuspenseGetAnnouncement as the primary hook built on top of it. Cache invalidation reads the key from the same factory instead of a separate constant. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…bar and velog-style preview - Move the announcement Enabled switch out of the body into the modal header (top-right, next to the close button) as a controlled Switch synced to the form field via a hidden registered Form.Item. - Add a velog-style formatting toolbar (heading, bold, italic, strikethrough, quote, code, link, image, lists) above the Monaco markdown editor, operating on the editor selection via the Monaco API. - Replace the markdown-to-jsx preview with react-markdown + remark-gfm / remark-math / rehype-katex and the shared shiki SyntaxHighlighter, with velog-like reading typography. - Bold the Message / Preview field labels. - Add en/ko i18n keys for the toolbar tooltips.
…h button Replace the header Enabled switch with a footer checkbox (left) plus Cancel / Publish buttons (right), matching the DeploymentAddRevisionModal footer pattern. Removes the modal-title full-width workaround. Adds button.Publish (en: Publish, ko: 발행하기).
… all locales Fill in the 11 new keys (button.Publish + summary.Markdown* toolbar labels) for the 19 remaining languages (de, el, es, fi, fr, id, it, ja, mn, ms, pl, pt-BR, pt, ru, th, tr, vi, zh-CN, zh-TW). en/ko already had them.
The Enabled toggle lives in the modal footer (outside any <Form>), which previously forced bridging it through the form store via a hidden Switch field + setFieldValue + Form.useWatch, and split the fields into a separate suspense child so the footer/title could stay visible during load. Collapse to a single component: fetch the announcement with a non-suspense useTanQuery (chrome renders immediately, body shows a Skeleton while loading) and manage enabled/message as plain useState drafts that fall back to the server value until edited. Validation (message required when enabled) becomes a plain derived flag that disables Publish and shows an inline error. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
9d1c3fc to
e9c1de2
Compare
The manager stores the announcement purely by presence, so the `enabled` flag cannot be persisted and its footer toggle could not work. Comment out the toggle (kept for a future backend that can persist it) and give the footer two explicit actions, following the Edit Bootstrap Script modal: - Reset: clears the editor content locally (Popconfirm-guarded) so the admin can start over without touching the server. - Delete: removes the published announcement via update_announcement(false, ''), routed through a confirm modal (not an inline Popconfirm); disabled when nothing is stored. Publishing always enables (enabled=true) and requires a non-empty message. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
f623bb2 to
39f74fd
Compare

Resolves #8066 (FR-3223)
Summary
BAICodeEditor: add amarkdownlanguage (Monaco) so the message can be authored with markdown highlighting.AnnouncementEditModal(new): markdown code editor + a live preview rendered with the samemarkdown-to-jsxsetup as the alert. Publishes viabaiClient.service.update_announcementand invalidates theget_announcementquery so the alert refreshes immediately.ShellScriptEditModallayout but inlined withBAIFlex. Delete clears the announcement and is guarded by aPopconfirm; it is disabled when nothing is stored.AnnouncementAlert: show an Edit button on the alert for superadmins only, opening the modal.AnnouncementDeleted).Notes
update_announcement(enabled=true, message)puts the message in etcd, andupdate_announcement(enabled=false, …)deletes it. There is no way to persist a disabled-but-present announcement, so the Enabled checkbox could not work. The toggle implementation is kept inAnnouncementEditModal(commented out) so it can be restored once the backend can persist the flag.update_announcement(false, ''), which is exactly the operation the disable path performed.POST /manager/announcementendpoint issuperadmin_required— a regular admin would receive 403.Test plan
Verification
bash scripts/verify.sh→ Relay / Lint / Format PASS. (TypeScript reports a pre-existing, unrelatedFluentEmojiIcon.tsxerror caused by a worktree patched-dep symlink; not part of this change.)Screenshot
Enlarged announcement edit modal (markdown editor + live preview, side by side):