feat(platform): wire prompt library dialogs into UI#1386
Conversation
📝 WalkthroughWalkthroughThis pull request implements the Prompt Library feature across the platform by introducing lazy-loaded prompt library and save-as-prompt dialogs in the chat input component and agent instructions page. The changes export prompt dialog type definitions for broader reuse, add comprehensive test coverage for the new dialog components, and expand internationalization support across multiple languages (German variants and English) with new UI strings for prompt management, including library tabs, form labels, actions, and deletion confirmations. Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Possibly related PRs
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Your free trial has ended. If you'd like to continue receiving code reviews, you can add a payment method here.
|
@coderabbitai review |
✅ Actions performedReview triggered.
|
b881873 to
9ef3513
Compare
- Add BookOpen button to chat input toolbar to open PromptLibraryDialog - Add Save-as-prompt button (visible when input has content) to open SaveAsPromptDialog - Add Browse prompts button to agent instructions page that appends selected prompt content to system instructions - Restructure prompts i18n namespace to match component key references - Add German translations for prompts namespace (de, de-AT, de-CH) - Export dialog props interfaces for lazy component type inference - Remove unused @ts-expect-error and TabValue type from prompt-library-dialog - Add a11y and render tests for all three prompt dialogs Closes #1331
9ef3513 to
608330b
Compare
There was a problem hiding this comment.
Actionable comments posted: 7
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
services/platform/messages/de.json (1)
2803-2817:⚠️ Potential issue | 🔴 CriticalResolve the leftover merge conflict before shipping.
<<<<<<< HEADmakes this file invalid JSON, so the German locale will fail to parse/load. It also leaves the final nesting ofcanvas,promptLibrary, andsaveAsPromptambiguous.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@services/platform/messages/de.json` around lines 2803 - 2817, The file contains an unresolved Git merge marker ("<<<<<<< HEAD") that breaks JSON parsing and makes the final nesting of the "canvas" object and the keys "promptLibrary" and "saveAsPrompt" ambiguous; remove all conflict markers ("<<<<<<< HEAD", "=======", ">>>>>>> ..."), choose the correct version of the "canvas" block (or merge fields manually) and ensure the JSON object correctly includes "canvas", "promptLibrary", and "saveAsPrompt" with proper braces and commas so the locale parses as valid JSON.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@services/platform/app/features/chat/components/chat-input.tsx`:
- Around line 496-500: The PromptLibraryDialog currently replaces the entire
composer by calling onSelectPrompt={(content) => onChange?.(content)}; instead,
preserve the user's draft by inserting/appending the selected prompt into the
existing composer state—use the current composer value and concatenate or splice
at the cursor and then call onChange with the new combined string (e.g.,
onSelectPrompt={(content) => onChange?.((currentComposerValue ?? '') + content)}
or perform an insertion at the caret if you have cursor position info). Update
PromptLibraryDialog's onSelectPrompt wiring to reference the existing composer
value/state rather than overwriting it.
In
`@services/platform/app/features/prompts/components/__tests__/prompt-form-dialog.test.tsx`:
- Around line 49-62: Replace the unsafe "as never" assertion in the test fixture
for initialData with a properly typed fixture or a satisfies-based pattern so
TypeScript validates the shape; specifically update the initialData object in
prompt-form-dialog.test.tsx (and the similar fixture around lines 88-98) to
either use a helper like createPromptFixture(...) that returns the correct
Prompt type or append "satisfies Prompt" to the literal so the compiler enforces
property shapes (target the initialData symbol and the test file's fixture
declarations when making the change).
In
`@services/platform/app/features/prompts/components/__tests__/prompt-library-dialog.test.tsx`:
- Around line 79-88: Add a test that exercises the full "use prompt" flow:
render PromptLibraryDialog with open={true}, pass spies for onSelectPrompt and
onOpenChange, simulate the user clicking the prompt's "Use" (or equivalent)
button via userEvent.click on the card, then assert that onSelectPrompt was
called with the expected prompt object/ID and that onOpenChange was called to
close the dialog (e.g., calledWith(false) or dialog not in document). Also
assert any usage-increment side-effect observable in the component (e.g., a call
to the increment handler or an updated usage count) by spying/mocking the
relevant handler or verifying updated UI, using the component name
PromptLibraryDialog and prop names onSelectPrompt and onOpenChange to locate
targets.
In
`@services/platform/app/features/prompts/components/__tests__/save-as-prompt-dialog.test.tsx`:
- Around line 46-55: The test claims to verify initialContent but only checks
the title; update the test for SaveAsPromptDialog to assert the textarea is
prefilled by querying the input (e.g., screen.getByDisplayValue("Hello, this is
a test prompt.") or screen.getByRole('textbox') and expect its value to equal
the initialContent), and also supply and mock the component's submit handler
prop (onSubmit/onSave — use the actual prop name the component exposes) then
trigger the submit (click the confirm button) and assert the handler was called
with the expected payload containing the initialContent.
In `@services/platform/messages/de-AT.json`:
- Around line 1-65: de-AT.json is a full duplicate of the base German locale
(all keys under "prompts" and "settings" match de.json); remove or minimize it
so the app falls back to de.json: either delete
services/platform/messages/de-AT.json entirely or replace its contents with an
empty object or only the specific override keys that differ (e.g., any unique
entries under "prompts" or "settings" if needed) so that only Austrian-specific
overrides remain and all identical keys are omitted.
In `@services/platform/messages/de-CH.json`:
- Around line 42-45: The current translation places "form": {"browsePrompts":
"..."} under settings.agents, but the UI expects
settings.agents.knowledge.form.browsePrompts; update the JSON structure so the
"browsePrompts" key is nested under the "knowledge" object (i.e., move or create
"knowledge" and put "form": {"browsePrompts": "Prompts durchsuchen"} inside it)
so the translation is available at settings.agents.knowledge.form.browsePrompts.
In `@services/platform/messages/en.json`:
- Line 1454: The "providers.description" message value is too generic for the
providers table empty state; update the en.json value so it clearly explains the
empty state and next steps (e.g., mention there are no providers yet and how to
add them) so users know what the section is for; locate the key
"providers.description" referenced from providers-table.tsx (line ~143) and
replace "Description" with a concise, actionable sentence like "No providers yet
— add a provider to integrate external services" (or similar copy that fits
tone).
---
Outside diff comments:
In `@services/platform/messages/de.json`:
- Around line 2803-2817: The file contains an unresolved Git merge marker
("<<<<<<< HEAD") that breaks JSON parsing and makes the final nesting of the
"canvas" object and the keys "promptLibrary" and "saveAsPrompt" ambiguous;
remove all conflict markers ("<<<<<<< HEAD", "=======", ">>>>>>> ..."), choose
the correct version of the "canvas" block (or merge fields manually) and ensure
the JSON object correctly includes "canvas", "promptLibrary", and "saveAsPrompt"
with proper braces and commas so the locale parses as valid JSON.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: ASSERTIVE
Plan: Pro
Run ID: ce89b83f-a060-4257-b95f-e2470bebfdbc
📒 Files selected for processing (11)
services/platform/app/features/chat/components/chat-input.tsxservices/platform/app/features/prompts/components/__tests__/prompt-form-dialog.test.tsxservices/platform/app/features/prompts/components/__tests__/prompt-library-dialog.test.tsxservices/platform/app/features/prompts/components/__tests__/save-as-prompt-dialog.test.tsxservices/platform/app/features/prompts/components/prompt-library-dialog.tsxservices/platform/app/features/prompts/components/save-as-prompt-dialog.tsxservices/platform/app/routes/dashboard/$id/agents/$agentId/instructions.tsxservices/platform/messages/de-AT.jsonservices/platform/messages/de-CH.jsonservices/platform/messages/de.jsonservices/platform/messages/en.json
| <PromptLibraryDialog | ||
| open={promptLibraryOpen} | ||
| onOpenChange={setPromptLibraryOpen} | ||
| onSelectPrompt={(content) => onChange?.(content)} | ||
| /> |
There was a problem hiding this comment.
Don't overwrite the user's draft when inserting a prompt.
This replaces the entire composer value with the selected prompt, so any in-progress message is lost. The feature is described as inserting prompts; this wiring should append or insert into the current text instead of clobbering it.
💡 Minimal fix
<PromptLibraryDialog
open={promptLibraryOpen}
onOpenChange={setPromptLibraryOpen}
- onSelectPrompt={(content) => onChange?.(content)}
+ onSelectPrompt={(content) => {
+ const separator = value.trim() ? '\n\n' : '';
+ onChange?.(value + separator + content);
+ }}
/>📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| <PromptLibraryDialog | |
| open={promptLibraryOpen} | |
| onOpenChange={setPromptLibraryOpen} | |
| onSelectPrompt={(content) => onChange?.(content)} | |
| /> | |
| <PromptLibraryDialog | |
| open={promptLibraryOpen} | |
| onOpenChange={setPromptLibraryOpen} | |
| onSelectPrompt={(content) => { | |
| const separator = value.trim() ? '\n\n' : ''; | |
| onChange?.(value + separator + content); | |
| }} | |
| /> |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@services/platform/app/features/chat/components/chat-input.tsx` around lines
496 - 500, The PromptLibraryDialog currently replaces the entire composer by
calling onSelectPrompt={(content) => onChange?.(content)}; instead, preserve the
user's draft by inserting/appending the selected prompt into the existing
composer state—use the current composer value and concatenate or splice at the
cursor and then call onChange with the new combined string (e.g.,
onSelectPrompt={(content) => onChange?.((currentComposerValue ?? '') + content)}
or perform an insertion at the caret if you have cursor position info). Update
PromptLibraryDialog's onSelectPrompt wiring to reference the existing composer
value/state rather than overwriting it.
| initialData={{ | ||
| _id: 'prompt-1' as never, | ||
| _creationTime: 1700000000000, | ||
| organizationId: 'test-org-id', | ||
| createdBy: 'user-1', | ||
| title: 'Existing Prompt', | ||
| content: 'Some content', | ||
| description: 'A description', | ||
| scope: 'personal', | ||
| category: 'general', | ||
| tags: ['tag1'], | ||
| usageCount: 3, | ||
| isPublished: true, | ||
| }} |
There was a problem hiding this comment.
🧹 Nitpick | 🔵 Trivial
Avoid as never in these test fixtures.
This bypasses the type checker exactly where the fixture should catch shape drift in initialData. Please switch to a typed fixture helper or a satisfies-based pattern instead of nullifying the type system.
Based on learnings, "prefer the 'satisfies' operator over 'as' type assertions for config objects and test data."
Also applies to: 88-98
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In
`@services/platform/app/features/prompts/components/__tests__/prompt-form-dialog.test.tsx`
around lines 49 - 62, Replace the unsafe "as never" assertion in the test
fixture for initialData with a properly typed fixture or a satisfies-based
pattern so TypeScript validates the shape; specifically update the initialData
object in prompt-form-dialog.test.tsx (and the similar fixture around lines
88-98) to either use a helper like createPromptFixture(...) that returns the
correct Prompt type or append "satisfies Prompt" to the literal so the compiler
enforces property shapes (target the initialData symbol and the test file's
fixture declarations when making the change).
| it('renders prompt cards when open', () => { | ||
| render( | ||
| <PromptLibraryDialog | ||
| open={true} | ||
| onOpenChange={vi.fn()} | ||
| onSelectPrompt={vi.fn()} | ||
| />, | ||
| ); | ||
| expect(screen.getByText('Test Prompt')).toBeInTheDocument(); | ||
| }); |
There was a problem hiding this comment.
🛠️ Refactor suggestion | 🟠 Major
The main “use prompt” flow is still untested.
This only proves the card renders. It would not catch a broken onSelectPrompt, missed usage increment, or dialog-close-on-use regression, which are the load-bearing behaviors for this feature.
As per coding guidelines, "Tests should cover happy paths, edge cases, and error conditions."
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In
`@services/platform/app/features/prompts/components/__tests__/prompt-library-dialog.test.tsx`
around lines 79 - 88, Add a test that exercises the full "use prompt" flow:
render PromptLibraryDialog with open={true}, pass spies for onSelectPrompt and
onOpenChange, simulate the user clicking the prompt's "Use" (or equivalent)
button via userEvent.click on the card, then assert that onSelectPrompt was
called with the expected prompt object/ID and that onOpenChange was called to
close the dialog (e.g., calledWith(false) or dialog not in document). Also
assert any usage-increment side-effect observable in the component (e.g., a call
to the increment handler or an updated usage count) by spying/mocking the
relevant handler or verifying updated UI, using the component name
PromptLibraryDialog and prop names onSelectPrompt and onOpenChange to locate
targets.
| it('renders with initial content when open', () => { | ||
| render( | ||
| <SaveAsPromptDialog | ||
| open={true} | ||
| onOpenChange={vi.fn()} | ||
| initialContent="Hello, this is a test prompt." | ||
| />, | ||
| ); | ||
| expect(screen.getByText('prompts.saveAs.title')).toBeInTheDocument(); | ||
| }); |
There was a problem hiding this comment.
🛠️ Refactor suggestion | 🟠 Major
This test never verifies the initialContent behavior it names.
It only checks the dialog title, so a regression where the textarea is no longer prefilled would still pass. Please assert the field value, and ideally the submit payload as well.
As per coding guidelines, "Tests should cover happy paths, edge cases, and error conditions."
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In
`@services/platform/app/features/prompts/components/__tests__/save-as-prompt-dialog.test.tsx`
around lines 46 - 55, The test claims to verify initialContent but only checks
the title; update the test for SaveAsPromptDialog to assert the textarea is
prefilled by querying the input (e.g., screen.getByDisplayValue("Hello, this is
a test prompt.") or screen.getByRole('textbox') and expect its value to equal
the initialContent), and also supply and mock the component's submit handler
prop (onSubmit/onSave — use the actual prop name the component exposes) then
trigger the submit (click the confirm button) and assert the handler was called
with the expected payload containing the initialContent.
| { | ||
| "prompts": { | ||
| "tabs": { | ||
| "all": "Alle", | ||
| "team": "Team", | ||
| "personal": "Persönlich" | ||
| }, | ||
| "library": { | ||
| "title": "Prompt-Bibliothek", | ||
| "description": "Prompt-Vorlagen durchsuchen, speichern und teilen.", | ||
| "searchPlaceholder": "Prompts suchen...", | ||
| "loading": "Prompts werden geladen...", | ||
| "empty": "Noch keine Prompts. Erstelle deine erste Prompt-Vorlage." | ||
| }, | ||
| "actions": { | ||
| "create": "Prompt erstellen", | ||
| "createFirst": "Ersten Prompt erstellen", | ||
| "edit": "Bearbeiten", | ||
| "delete": "Löschen", | ||
| "use": "Verwenden", | ||
| "usePrompt": "Diesen Prompt verwenden", | ||
| "more": "Weitere Aktionen" | ||
| }, | ||
| "deleteConfirm": { | ||
| "title": "Prompt löschen", | ||
| "description": "Bist du sicher, dass du \"{title}\" löschen möchtest? Diese Aktion kann nicht rückgängig gemacht werden." | ||
| }, | ||
| "scope": { | ||
| "global": "Global (alle)", | ||
| "team": "Team", | ||
| "personal": "Persönlich" | ||
| }, | ||
| "form": { | ||
| "createTitle": "Prompt erstellen", | ||
| "createDescription": "Eine neue Prompt-Vorlage erstellen.", | ||
| "editTitle": "Prompt bearbeiten", | ||
| "editDescription": "Die Prompt-Vorlage aktualisieren.", | ||
| "titleLabel": "Titel", | ||
| "titlePlaceholder": "Prompt-Titel eingeben...", | ||
| "contentLabel": "Inhalt", | ||
| "contentPlaceholder": "Prompt-Inhalt eingeben...", | ||
| "descriptionLabel": "Beschreibung", | ||
| "descriptionPlaceholder": "Kurze Beschreibung des Prompts...", | ||
| "scopeLabel": "Sichtbarkeit", | ||
| "categoryLabel": "Kategorie", | ||
| "categoryPlaceholder": "z.B. Schreiben, Analyse, Programmierung", | ||
| "tagsLabel": "Tags", | ||
| "tagsPlaceholder": "Kommagetrennte Tags...", | ||
| "save": "Speichern", | ||
| "create": "Erstellen" | ||
| }, | ||
| "saveAs": { | ||
| "title": "Als Prompt speichern", | ||
| "description": "Den aktuellen Text als wiederverwendbare Prompt-Vorlage speichern." | ||
| }, | ||
| "usageCount": "{count, plural, one {# Verwendung} other {# Verwendungen}}" | ||
| }, | ||
| "settings": { | ||
| "agents": { | ||
| "form": { | ||
| "browsePrompts": "Prompts durchsuchen" | ||
| } | ||
| } | ||
| } | ||
| } |
There was a problem hiding this comment.
🛠️ Refactor suggestion | 🟠 Major
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
python - <<'PY'
import json
from pathlib import Path
base_path = Path("services/platform/messages/de.json")
variant_path = Path("services/platform/messages/de-AT.json")
base = json.loads(base_path.read_text(encoding="utf-8"))
variant = json.loads(variant_path.read_text(encoding="utf-8"))
def flatten(obj, prefix=""):
out = {}
if isinstance(obj, dict):
for k, v in obj.items():
p = f"{prefix}.{k}" if prefix else k
out.update(flatten(v, p))
else:
out[prefix] = obj
return out
b = flatten(base)
v = flatten(variant)
same = [k for k, val in v.items() if k in b and b[k] == val]
diff = [k for k, val in v.items() if k in b and b[k] != val]
only_variant = [k for k in v if k not in b]
print(f"Variant leaf keys: {len(v)}")
print(f"Same as base de.json: {len(same)}")
print(f"Different from base de.json: {len(diff)}")
print(f"Only in de-AT.json: {len(only_variant)}")
if same:
print("\nSample redundant keys:")
for k in same[:30]:
print(" -", k)
PYRepository: tale-project/tale
Length of output: 1034
Remove or minimize de-AT.json — currently a full duplicate of de.json.
All 41 keys in this file are identical to the base de.json. Per the established pattern, locale variants must contain only keys whose values differ from the base locale. Since there are no Austrian-specific overrides, this file should either be deleted or kept empty to allow fallback to the base German locale.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@services/platform/messages/de-AT.json` around lines 1 - 65, de-AT.json is a
full duplicate of the base German locale (all keys under "prompts" and
"settings" match de.json); remove or minimize it so the app falls back to
de.json: either delete services/platform/messages/de-AT.json entirely or replace
its contents with an empty object or only the specific override keys that differ
(e.g., any unique entries under "prompts" or "settings" if needed) so that only
Austrian-specific overrides remain and all identical keys are omitted.
| }, | ||
| "form": { | ||
| "browsePrompts": "Prompts durchsuchen" | ||
| } |
There was a problem hiding this comment.
Fix i18n key nesting for browsePrompts path.
Line 43 currently places form under settings.agents, but the UI expects settings.agents.knowledge.form.browsePrompts. This will miss the translation at runtime.
Proposed fix
- "knowledge": {
- "fileTooLarge": "Datei zu gross"
- },
- "form": {
- "browsePrompts": "Prompts durchsuchen"
- }
+ "knowledge": {
+ "fileTooLarge": "Datei zu gross",
+ "form": {
+ "browsePrompts": "Prompts durchsuchen"
+ }
+ }🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@services/platform/messages/de-CH.json` around lines 42 - 45, The current
translation places "form": {"browsePrompts": "..."} under settings.agents, but
the UI expects settings.agents.knowledge.form.browsePrompts; update the JSON
structure so the "browsePrompts" key is nested under the "knowledge" object
(i.e., move or create "knowledge" and put "form": {"browsePrompts": "Prompts
durchsuchen"} inside it) so the translation is available at
settings.agents.knowledge.form.browsePrompts.
| "providers": { | ||
| "title": "Providers", | ||
| "description": "Manage LLM providers and their models", | ||
| "description": "Description", |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
# Find all call sites to confirm whether this key is rendered as a page/section description.
rg -n -C2 --type=ts --type=tsx "settings\.providers\.description|t\(['\"]settings\.providers\.description['\"]\)"Repository: tale-project/tale
Length of output: 88
🏁 Script executed:
#!/bin/bash
set -euo pipefail
# Search for usage of this translation key more broadly
rg -n "settings\.providers\.description|providers\.description" --type=json --type=ts
# Also search for pattern t("settings.providers.description") without type restrictions
rg -n "settings\.providers\.description"Repository: tale-project/tale
Length of output: 932
🏁 Script executed:
#!/bin/bash
# Read the JSON file around line 1454 to see context
wc -l services/platform/messages/en.jsonRepository: tale-project/tale
Length of output: 100
🏁 Script executed:
#!/bin/bash
# Check the context around line 1454
sed -n '1440,1470p' services/platform/messages/en.jsonRepository: tale-project/tale
Length of output: 1321
🏁 Script executed:
#!/bin/bash
# Check git log to see what changed in the JSON file around line 1454
git log --oneline -n 20 -- services/platform/messages/en.jsonRepository: tale-project/tale
Length of output: 121
🏁 Script executed:
#!/bin/bash
# Check the diff for recent changes to this file
git diff HEAD~5 HEAD -- services/platform/messages/en.json | head -200Repository: tale-project/tale
Length of output: 89
🏁 Script executed:
#!/bin/bash
# Read the providers-table.tsx context around line 143
sed -n '130,160p' services/platform/app/features/settings/providers/components/providers-table.tsxRepository: tale-project/tale
Length of output: 923
providers.description is too generic for an empty state message.
The key is used as the description in the empty state of the providers table (providers-table.tsx:143). Currently set to "Description", which is too generic and provides no context to users about what the section does.
Suggested fix
- "description": "Description",
+ "description": "Manage AI providers and their models.",📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| "description": "Description", | |
| "description": "Manage AI providers and their models.", |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@services/platform/messages/en.json` at line 1454, The "providers.description"
message value is too generic for the providers table empty state; update the
en.json value so it clearly explains the empty state and next steps (e.g.,
mention there are no providers yet and how to add them) so users know what the
section is for; locate the key "providers.description" referenced from
providers-table.tsx (line ~143) and replace "Description" with a concise,
actionable sentence like "No providers yet — add a provider to integrate
external services" (or similar copy that fits tone).
…mpt form The promptTemplates table was missing from the RLS rules and permission matrix, causing "insert access not allowed" errors. Additionally, the prompt form's Team scope option had no team picker, so teamId was always undefined.
Remove trivially inferred type parameter and mock useTeams in tests.
Summary
PromptLibraryDialog,SaveAsPromptDialog, andPromptFormDialogcomponents into the UI -- they were fully implemented but unreachable dead codepromptsi18n namespace inen.jsonto match component key references (nestedtabs.*,library.*,actions.*,form.*,scope.*,deleteConfirm.*,saveAs.*)promptsnamespace tode.json,de-AT.json, andde-CH.json@ts-expect-errorinprompt-library-dialog.tsxby removing the unnecessary type annotation and passingsetActiveTabdirectly toonValueChangePromptLibraryDialogPropsandSaveAsPromptDialogPropsinterfaces for lazy component type inferenceCloses #1331
Test plan
bun run --filter @tale/platform lint-- passesbun run --filter @tale/platform typecheck-- passesbunx vitest --run --project client-- all tests pass including new prompt dialog testsbunx vitest --run --project server-- all tests passSummary by CodeRabbit
New Features
Documentation
Tests