OUT-3510 | Add side-menu setting to hide home page greeting - #203
Conversation
Renames the Banner sidebar section to "Header" and adds a "Show greeting" toggle that controls visibility of the heading/subheading block above the banner across editor, preview, and the client-facing view. Persisted via a new show_greeting column on settings. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
Greptile SummaryAdds a per-segment "Show greeting" toggle to the sidebar (renamed from "Banner" to "Header") that conditionally renders the heading/subheading block in the editor, preview, and client-facing views. The change is backed by a new
Confidence Score: 4/5Safe to merge after addressing the missing The greeting-visibility logic is straightforward and the DB migration is safe. The three consumer components read
Important Files Changed
Reviews (1): Last reviewed commit: "feat(OUT-3510): add side-menu setting to..." | Re-trigger Greptile |
| setShowGreeting: (showGreeting: boolean) => void | ||
| } |
There was a problem hiding this comment.
The
setShowGreeting action is added to both the SettingsAction interface and the store implementation, but it is never called anywhere in the codebase. All showGreeting updates flow through the generic setSettings path in useBannerSettingsMutation. This dedicated setter is dead code that adds surface area with no benefit — either wire it up where appropriate or remove it to keep the store consistent with what other dedicated setters (like setContent, setSubheading) are actually used for.
| setShowGreeting: (showGreeting: boolean) => void | |
| } | |
| } |
Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!
| const bannerUrl = bannerImages?.find((item) => item.id === bannerId) | ||
| const bannerPositionX = useSettingsStore((store) => store.bannerPositionX) ?? 50 | ||
| const bannerPositionY = useSettingsStore((store) => store.bannerPositionY) ?? 50 | ||
| const showGreeting = useSettingsStore((store) => store.showGreeting) |
There was a problem hiding this comment.
The existing
bannerPositionX and bannerPositionY reads both carry ?? 50 fallbacks to guard against an undefined store value. showGreeting lacks a matching ?? true fallback. If the store ever holds undefined for this field — during an intermediate hydration state or when hitting an un-migrated API pod — the greeting block is silently hidden instead of shown, which is the wrong safe default.
| const showGreeting = useSettingsStore((store) => store.showGreeting) | |
| const showGreeting = useSettingsStore((store) => store.showGreeting) ?? true |
| const bannerUrl = bannerImages?.find((item) => item.id === bannerId) | ||
| const bannerPositionX = useSettingsStore((store) => store.bannerPositionX) ?? 50 | ||
| const bannerPositionY = useSettingsStore((store) => store.bannerPositionY) ?? 50 | ||
| const showGreeting = useSettingsStore((store) => store.showGreeting) |
There was a problem hiding this comment.
Same
?? true fallback missing as in EditorWrapper. Without it, an undefined showGreeting value silently hides the greeting on the client-facing route.
| const showGreeting = useSettingsStore((store) => store.showGreeting) | |
| const showGreeting = useSettingsStore((store) => store.showGreeting) ?? true |
| export function Preview({ content, backgroundColor, bannerUrl, bannerPositionX, bannerPositionY }: PreviewProps) { | ||
| const displayMode = useViewStore((store) => store.displayMode) | ||
| const workspace = useViewStore((store) => store.workspace) | ||
| const showGreeting = useSettingsStore((store) => store.showGreeting) |
There was a problem hiding this comment.
Same
?? true fallback missing as in EditorWrapper and ClientEditorWrapper. Without it, an undefined showGreeting value silently hides the greeting in Preview mode.
| const showGreeting = useSettingsStore((store) => store.showGreeting) | |
| const showGreeting = useSettingsStore((store) => store.showGreeting) ?? true |
- Replace bulky cards with compact pill rows matching the new design
- Verb-sentence labels (Pay/Sign/Submit/Complete) with inline count; short {{N}} chip in editor
- Container-query grid: 4 and 3 actions fill the row; 1 and 2 stay third-width and left-align
- Hide actions with 0 pending events and the whole section when nothing is pending (OUT-3717)
- Preserve click-through navigation to the underlying apps
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
1 and 2 action cards now cap at a fixed 240px width and left-align in both the editor (IU) and client views, so space stays on the right regardless of which view renders them. Also lower the fill breakpoint to 700px so 3 and 4 actions fill the row in the editor's content column (which sits just under 768px due to the customization sidebar). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Convert the container-query breakpoints and the capped card width to rem (400px->25rem, 700px->43.75rem, 240px->15rem). No behavior change. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Replace the static time-of-day greeting with an editable, autofill-capable
header. The heading defaults to "Welcome, {{client.firstName}}" and both the
heading and subheading are now minimal single-line rich-text fields that
support plain text + autofill fields only (no marks, lists, tables, etc).
- Add MinimalEditor + getMinimalExtensions (Document content:'block' for
single-line, Paragraph, Text, UndoRedo, reused AutofillField, Placeholder)
- Add settings.heading column (HTML, default "Welcome, {{client.firstName}}");
subheading now stores HTML and is backward compatible with existing plain text
- Wire heading through the store, change-detection and save payload
- Scope .minimal-editor CSS so global .tiptap block styles don't leak in
- Remove the now-unused getTimeOfDay greeting helper
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The change-detection baseline kept the subheading in its legacy plain-text form (e.g. "Here's …") while the editor always emits "<p>…</p>", so reverting a subheading edit never string-matched the baseline and the Save Changes button stayed visible. The heading was unaffected because its default is already canonical "<p>…</p>". Normalize heading/subheading to the editor's canonical serialization when a non-canonical value loads, updating the live value and the change-detection baseline atomically via a new syncCanonicalContent store action. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Autofill fields are an inline atom TipTap node rendered via a React
NodeView. In client/preview view the resolved value was neither
selectable/copiable nor clickable when it was a link.
- Add `renderText` to the autofill node so TipTap's clipboard text
serializer emits the resolved value (template `{{...}}` falls back when
no preview client is available, e.g. in the editor). Resolution happens
outside React via a store/query-cache helper.
- Render resolved URLs and emails as anchors styled with the editor's
`cop-text-link cursor-pointer` classes; `stopPropagation` on mousedown
lets native navigation work in the readonly view.
Both fixes live on the shared extension/NodeView, so the minimal editor
(home header/subheading) inherits them automatically.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
OUT-3841 | Home App - Autofill Fields Are Not Copiable or Clickable
feat(OUT-3510): make home page header editable with autofill
…-visual-appearance-of-the-your-actions-field OUT-3729, OUT-3717 | Improve visual appearance of the Your Actions field
Changes
show_greetingcolumn onsettings(defaulttrue).EditorWrapper,Preview,ClientEditorWrapper).useBannerSettingsMutationwith a stale-response guard so rapid toggling doesn't flicker the UI when responses arrive out of order (same pattern asuseSettingsMutation).Testing Criteria
/c/...).Notes
src/db/migrations/20260601130809_add-show-greeting-to-settings.sql— addsshow_greeting boolean NOT NULL DEFAULT true. Forward-only, safe on existing rows.Impact & Surface Area of Change
settingstable schema + Drizzle snapshot — apply migration before deploying.useBannerSettingsMutationnow also handlesshowGreetingand dedupes stale responses; existing banner image/reposition flows go through the same hook, double-check they still save as expected.🤖 Generated with Claude Code