feat(dashboard): variable autocomplete, highlighting & live preview for {variable} fields#48
Closed
Abdulkhalek-1 wants to merge 27 commits into
Closed
feat(dashboard): variable autocomplete, highlighting & live preview for {variable} fields#48Abdulkhalek-1 wants to merge 27 commits into
Abdulkhalek-1 wants to merge 27 commits into
Conversation
21 TDD tasks: pure logic foundations (tokenize, validation, caret, filter, registry, automation vars, preview resolver), React components (VariableEditor, VariableBrowser, DiscordMessagePreview, usePreviewContext), and rollout across welcome/commands/scheduled/leveling/tempvoice/automation. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Installs @testing-library/react, @testing-library/user-event, and jsdom as devDependencies, wires up the @vitejs/plugin-react plugin in vitest.config.ts so TSX files get the automatic JSX runtime, extends the include glob to cover tests/**/*.test.tsx, adds the variable-field coverage path, and adds a smoke component test (jsdom docblock, 1 test) that confirms the DOM render pipeline. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Creates registry.ts with welcomeVariables, customCommandVariables, levelingVariables, tempvoiceVariables descriptors, knownTokenSet, buildRealData (CDN URL builder with fallbacks), and buildTokenValues. Drift-guard tests assert token names match canonical @fluxcore/systems sources (WELCOME_VARIABLES, TEMPLATE_VARIABLES). Also adds ./customCommands/variables subpath export to packages/systems/package.json so the drift test import resolves (dist files already existed; the export map entry was missing). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…validation
Implements the VariableEditor React component: overlay-mirror token highlighting,
{-triggered ARIA combobox with ArrowUp/Down/Enter/Tab/Escape navigation, and
unknown-variable warning list with Levenshtein suggestions. Fixes import path
(../../lib/utils), synchronous caret-query detection on change event, and
active-index starting at -1 so ArrowDown selects index 0 first.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Implements Task 10: a Popover-based variable browser with live filtering, grouped token list, and onInsert callback; test stubs ResizeObserver for jsdom. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Implements usePreviewContext(guildId) which assembles PreviewRealData for the live variable-field preview from useAuth + useGuilds query results, memoized on [auth.data, guilds.data, guildId]. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Replace plain Input/Textarea fields in EmbedEditor with VariableEditor (token highlighting, autocomplete), add VariableBrowser near description, add DiscordMessagePreview below fields, thread PreviewRealData via usePreviewContext into all three EmbedEditor instances (welcome/farewell/DM). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Replace the plain Textarea + static hint in the level-up announcement field with VariableEditor, VariableBrowser, and DiscordMessagePreview, giving users inline token insertion and a live Discord-style preview. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Threads workflow eventType down through NodeDetailPanel → ActionFields and swaps variable-bearing text/textarea inputs for VariableEditor with per-event autocomplete. StepPanel action fields get an empty variable list (not event-scoped in the current model). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…ation Thread eventType into StepPanelProps and compute buildAutomationVariables in StepPanel so step action fields receive the real token set instead of []. Fix VariableEditor id prop (text + textarea branches) to use sanitised fieldId so <Label htmlFor> correctly associates with the input. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Adds DiscordMessagePreview below ActionFields in ActionPanel for sendMessage, sendDM (content preview) and sendEmbed (embed preview), using already-computed variables and usePreviewContext for live guild/user resolution. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…highlight The highlight backdrop and the text field each carried the full field style (border + bg-surface-lowest + rounded), stacking two bordered boxes into a doubled/corrupted border. The field also carried both text-text and text-transparent, so twMerge could not dedupe the custom color and the field's own text painted over the colored backdrop, hiding variable highlighting. Move border/background/rounding/focus-ring to the container (focus-within), and make both inner layers borderless + transparent-bg with identical padding: the field text is transparent, the backdrop shows the accent/danger-colored tokens. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Add variables.* and variables.entries.* to common.json so VariableBrowser and VariableEditor render human-readable descriptions for all registry tokens (welcome/leveling/tempvoice top-level tokens + automation/command entries). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Task 1 added @testing-library/react, @testing-library/user-event, and jsdom to apps/dashboard devDependencies, but the docker workflow (repo root not bind-mounted) meant the root lockfile was never regenerated, so `pnpm install --frozen-lockfile` (CI/clean clone) would fail. Regenerated from the current manifests. Diff is additive (peer-dep hash re-resolution only). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
… forwarding
- vitest.config.ts: widen coverage include to *.{ts,tsx} so .tsx components are not silently excluded
- commands.tsx: gate DiscordMessagePreview content/embed by formResponseType to prevent both rendering at once
- VariableEditor: add aria-required prop and forward it to textarea and input elements
- ActionFields: pass aria-required={field.required} to both VariableEditor branches (text + textarea)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This was referenced Jul 8, 2026
This was referenced Jul 8, 2026
Member
Author
3 tasks
Member
Author
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.
Summary
Adds a reusable variable-field editing experience to every dashboard text field that supports
{variable}placeholders, replacing the old static hint text with:{-triggered autocomplete — an ARIA combobox that filters the field's variables as you type and inserts at the cursorRolled out to
Welcome / Farewell / DM · Custom Commands · Scheduled Messages · Leveling announce · TempVoice name template · Automation action fields (with event-scoped variables threaded through the workflow editor —
{ban.reason}only shows for Member Banned, etc.)Architecture
New module
apps/dashboard/src/client/shared/ui/variable-field/: pure, DOM-free logic (tokenizer, caret math, filter, validation, registry, preview resolver) with node-env unit tests, plus three React components (VariableEditor,VariableBrowser,DiscordMessagePreview) and ausePreviewContexthook tested under jsdom. The editor uses an overlay-mirror technique (native field +aria-hiddenhighlight backdrop) to keep native caret/undo/IME while showing colored tokens. A registry drift guard asserts the dashboard's token names match the canonical@fluxcore/systemsruntime tokens, so the UI can't silently diverge from bot-side substitution.Design: spec · plan
Testing
tsc -p tsconfig.client.json --noEmit)@testing-library/reacttoolchain (no client test infra existed before) and regeneratedpnpm-lock.yamlto matchNotes
memberCountuses a sample (not client-available).Follow-ups (non-blocking)
🤖 Generated with Claude Code