-
Notifications
You must be signed in to change notification settings - Fork 418
Post Meeting Template Editor & Selector #1050
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
📝 WalkthroughWalkthroughThis update introduces a customizable meeting note enhancement system using user-defined templates. It adds a new "templates" settings tab and interface for creating, editing, cloning, and deleting templates, including emoji selection. The enhancement logic now supports template-based custom grammar, and configuration/state management is extended to track the selected template. Changes
Sequence Diagram(s)sequenceDiagram
participant User
participant SettingsUI
participant DB
participant Editor
participant LLM
User->>SettingsUI: Open Templates Tab
SettingsUI->>DB: Fetch templates
DB-->>SettingsUI: Return templates
User->>SettingsUI: Create/Edit/Clone/Delete template
SettingsUI->>DB: Update templates
DB-->>SettingsUI: Confirm update
User->>SettingsUI: Select template
SettingsUI->>DB: Save selected_template_id
User->>Editor: Trigger Enhance
Editor->>DB: Fetch config (including selected_template_id)
Editor->>DB: Fetch selected template (if any)
Editor->>Editor: Generate custom grammar (if template)
Editor->>LLM: Send enhance request (with grammar & template info)
LLM-->>Editor: Return enhanced notes
Editor-->>User: Display enhanced notes
Possibly related PRs
✨ Finishing Touches
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. 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
SupportNeed help? Create a ticket on our support page for assistance with any issues or questions. Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
Documentation and Community
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 5
🔭 Outside diff range comments (1)
apps/desktop/src/components/settings/components/template-sections.tsx (1)
30-33: Fix state update bug in handleChange.The
handleChangemethod uses the staleitemsstate when callingonChange, which could lead to data loss when multiple rapid updates occur.const handleChange = (item: ReorderItem & { id: string }) => { - setItems(items.map((i) => (i.id === item.id ? item : i))); - onChange(items); + const updatedItems = items.map((i) => (i.id === item.id ? item : i)); + setItems(updatedItems); + onChange(updatedItems); };
🧹 Nitpick comments (2)
plugins/local-llm/src/server.rs (1)
235-241: Consider simplifying the metadata access pattern.The nested unwrap_or calls work but could be simplified for better readability.
Consider extracting the metadata access into a variable to avoid duplication:
- Some("custom") => request - .metadata - .as_ref() - .unwrap_or(&serde_json::Value::Object(Default::default())) - .get("customGrammar") - .and_then(|v| v.as_str()) - .map(|s| s.to_string()), + Some("custom") => { + let metadata = request.metadata.as_ref() + .unwrap_or(&serde_json::Value::Object(Default::default())); + metadata.get("customGrammar") + .and_then(|v| v.as_str()) + .map(|s| s.to_string()) + }apps/desktop/src/components/editor-area/index.tsx (1)
199-199: Useletinstead ofvar.For consistency with modern JavaScript standards and the rest of the codebase.
- var finalInput = ""; + let finalInput = "";
📜 Review details
Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (13)
apps/desktop/src/components/editor-area/index.tsx(3 hunks)apps/desktop/src/components/settings/components/tab-icon.tsx(2 hunks)apps/desktop/src/components/settings/components/template-sections.tsx(6 hunks)apps/desktop/src/components/settings/components/types.ts(1 hunks)apps/desktop/src/components/settings/views/general.tsx(1 hunks)apps/desktop/src/components/settings/views/index.ts(1 hunks)apps/desktop/src/components/settings/views/template.tsx(4 hunks)apps/desktop/src/components/settings/views/templates.tsx(1 hunks)apps/desktop/src/routes/app.settings.tsx(3 hunks)crates/db-user/src/config_types.rs(2 hunks)crates/template/assets/enhance.system.jinja(1 hunks)plugins/db/js/bindings.gen.ts(1 hunks)plugins/local-llm/src/server.rs(1 hunks)
🧰 Additional context used
📓 Path-based instructions (1)
`**/*.{js,ts,tsx,rs}`: 1. No error handling. 2. No unused imports, variables, or functions. 3. For comments, keep it minimal. It should be about "Why", not "What".
**/*.{js,ts,tsx,rs}: 1. No error handling.
2. No unused imports, variables, or functions.
3. For comments, keep it minimal. It should be about "Why", not "What".
⚙️ Source: CodeRabbit Configuration File
List of files the instruction was applied to:
apps/desktop/src/components/settings/views/index.tsapps/desktop/src/components/settings/views/general.tsxplugins/db/js/bindings.gen.tscrates/db-user/src/config_types.rsapps/desktop/src/routes/app.settings.tsxapps/desktop/src/components/settings/components/types.tsapps/desktop/src/components/settings/components/tab-icon.tsxapps/desktop/src/components/settings/views/template.tsxplugins/local-llm/src/server.rsapps/desktop/src/components/editor-area/index.tsxapps/desktop/src/components/settings/views/templates.tsxapps/desktop/src/components/settings/components/template-sections.tsx
🪛 Biome (1.9.4)
apps/desktop/src/components/editor-area/index.tsx
[error] 468-468: Unexpected control character in a regular expression.
Control characters are unusual and potentially incorrect inputs, so they are disallowed.
(lint/suspicious/noControlCharactersInRegex)
[error] 468-468: Unexpected control character in a regular expression.
Control characters are unusual and potentially incorrect inputs, so they are disallowed.
(lint/suspicious/noControlCharactersInRegex)
⏰ Context from checks skipped due to timeout of 90000ms (3)
- GitHub Check: ci (windows, windows-latest)
- GitHub Check: ci (macos, macos-latest)
- GitHub Check: ci
🔇 Additional comments (15)
crates/db-user/src/config_types.rs (1)
47-47: LGTM! Clean addition of the selected template field.The new
selected_template_idfield is properly typed asOption<String>and correctly initialized asNonein the default implementation. This follows Rust conventions and integrates seamlessly with the existing configuration structure.Also applies to: 59-59
apps/desktop/src/components/settings/views/index.ts (1)
12-12: LGTM! Export follows the established pattern.The new
TemplatesViewexport is consistent with the existing module structure and naming conventions.apps/desktop/src/components/settings/views/general.tsx (1)
129-129: LGTM! Correctly preserves the selected template ID during updates.The addition ensures that the
selected_template_idis preserved when updating other general configuration fields, following the established pattern for maintaining existing config values.apps/desktop/src/routes/app.settings.tsx (3)
8-8: LGTM! Import follows the established pattern.The
TemplatesViewimport is correctly added and follows the existing import structure.
94-95: LGTM! Tab label integration is consistent.The templates tab label addition maintains the existing conditional rendering chain structure and follows the established pattern for tab labels.
127-127: LGTM! Tab content rendering follows the established pattern.The conditional rendering for the templates tab is consistent with how other tabs are handled in the component.
plugins/db/js/bindings.gen.ts (1)
154-154: LGTM! Generated type definition correctly reflects backend changes.The
selected_template_id: string | nullfield correctly maps the RustOption<String>type to TypeScript, maintaining type safety across the stack.apps/desktop/src/components/settings/components/tab-icon.tsx (1)
5-5: LGTM! Clean implementation of the templates tab icon.The changes properly integrate the new templates tab icon while maintaining consistency with other tab icons by using the same styling approach.
Also applies to: 23-23, 25-25, 30-31
apps/desktop/src/components/settings/components/types.ts (1)
2-2: LGTM! Proper integration of the templates tab type.The changes correctly extend the Tab type and TABS array to support the new templates feature while maintaining consistency with the existing structure.
Also applies to: 4-4, 12-12
crates/template/assets/enhance.system.jinja (1)
3-13: LGTM! Well-structured template customization instructions.The conditional block properly instructs the assistant to follow custom template structures when provided, maintaining strict adherence to the user-defined format.
apps/desktop/src/components/settings/views/template.tsx (1)
26-174: LGTM! Well-implemented emoji selector feature.The emoji selection functionality is cleanly implemented with proper Unicode emoji handling, state management, and UI integration. The popover-based selector provides a good user experience.
apps/desktop/src/components/editor-area/index.tsx (2)
447-500: Well-implemented template grammar generation!The
generateCustomGBNFfunction properly handles edge cases, validates input, escapes special characters, and generates valid GBNF grammar. The control character removal at line 468 is a good security practice.
244-268: Add error handling for template operations.The template loading and processing logic should handle potential failures gracefully to prevent the enhancement process from breaking.
if (selectedTemplateId) { - const templates = await dbCommands.listTemplates(); - const selectedTemplate = templates.find(t => t.id === selectedTemplateId); + try { + const templates = await dbCommands.listTemplates(); + const selectedTemplate = templates.find(t => t.id === selectedTemplateId); - if (selectedTemplate) { - // Generate custom GBNF grammar - if (selectedTemplate.sections && selectedTemplate.sections.length > 0) { - customGrammar = generateCustomGBNF(selectedTemplate.sections); - } + if (selectedTemplate) { + // Generate custom GBNF grammar + if (selectedTemplate.sections && selectedTemplate.sections.length > 0) { + customGrammar = generateCustomGBNF(selectedTemplate.sections); + } - // Format template as a readable string for system prompt - templateInfo = ` + // Format template as a readable string for system prompt + templateInfo = ` SELECTED TEMPLATE: Template Title: ${selectedTemplate.title || "Untitled"} Template Description: ${selectedTemplate.description || "No description"} Sections:`; - selectedTemplate.sections?.forEach((section, index) => { - templateInfo += ` + selectedTemplate.sections?.forEach((section, index) => { + templateInfo += ` ${index + 1}. ${section.title || "Untitled Section"} └─ ${section.description || "No description"}`; - }); + }); + } + } catch (error) { + console.error("Failed to load template:", error); + // Continue with enhancement without custom template } }Likely an incorrect or invalid review comment.
apps/desktop/src/components/settings/views/templates.tsx (1)
300-413: Excellent TemplateCard implementation!The component properly handles:
- Emoji extraction and fallback logic
- Text truncation for long titles/descriptions
- Clean event handling with stopPropagation for edit button
- Visual feedback for selected state
apps/desktop/src/components/settings/components/template-sections.tsx (1)
35-39: Well-implemented section deletion functionality!The delete functionality is properly integrated with:
- Clean removal from state
- Proper onChange callback invocation
- Intuitive UI with hover effects
- Correct event handling
Also applies to: 116-136
| type ViewState = "list" | "editor" | "new"; | ||
|
|
||
| export default function TemplatesView() { | ||
| console.log("templatesview mounted@!"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Remove debug console.log statement.
Debug logging should not be committed to production code.
- console.log("templatesview mounted@!");📝 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.
| console.log("templatesview mounted@!"); |
🤖 Prompt for AI Agents
In apps/desktop/src/components/settings/views/templates.tsx at line 16, remove
the debug console.log statement "templatesview mounted@!" to prevent debug
logging from being included in production code.
| console.log("loaded templates: ", templates); | ||
| console.log(templates); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Remove debug console.log statements.
Debug logging should not be committed to production code.
- console.log("loaded templates: ", templates);
- console.log(templates);📝 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.
| console.log("loaded templates: ", templates); | |
| console.log(templates); |
🤖 Prompt for AI Agents
In apps/desktop/src/components/settings/views/templates.tsx at lines 67 to 68,
remove the debug console.log statements that output the loaded templates. These
debug logs should not be present in production code to keep the console clean
and avoid leaking potentially sensitive information.
| const handleCloneTemplate = async (template: Template) => { | ||
| try { | ||
| const clonedTemplate: Template = { | ||
| ...template, | ||
| id: crypto.randomUUID(), | ||
| title: `${template.title} Copy`, | ||
| user_id: userId, | ||
| }; | ||
| await dbCommands.upsertTemplate(clonedTemplate); | ||
| await loadTemplates(); | ||
| } catch (error) { | ||
| console.error("Failed to clone template:", error); | ||
| } | ||
| }; | ||
|
|
||
| const handleDeleteTemplate = async (template: Template) => { | ||
| try { | ||
| await dbCommands.deleteTemplate(template.id); | ||
| await loadTemplates(); | ||
| } catch (error) { | ||
| console.error("Failed to delete template:", error); | ||
| } | ||
| }; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Add user-facing error notifications.
Template operations should provide feedback to users when they fail, not just log to console.
Consider using a toast notification system to inform users of operation failures:
const handleCloneTemplate = async (template: Template) => {
try {
const clonedTemplate: Template = {
...template,
id: crypto.randomUUID(),
title: `${template.title} Copy`,
user_id: userId,
};
await dbCommands.upsertTemplate(clonedTemplate);
await loadTemplates();
} catch (error) {
console.error("Failed to clone template:", error);
+ toast({
+ title: "Failed to clone template",
+ description: "Please try again later",
+ variant: "destructive",
+ });
}
};
const handleDeleteTemplate = async (template: Template) => {
try {
await dbCommands.deleteTemplate(template.id);
await loadTemplates();
} catch (error) {
console.error("Failed to delete template:", error);
+ toast({
+ title: "Failed to delete template",
+ description: "Please try again later",
+ variant: "destructive",
+ });
}
};📝 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.
| const handleCloneTemplate = async (template: Template) => { | |
| try { | |
| const clonedTemplate: Template = { | |
| ...template, | |
| id: crypto.randomUUID(), | |
| title: `${template.title} Copy`, | |
| user_id: userId, | |
| }; | |
| await dbCommands.upsertTemplate(clonedTemplate); | |
| await loadTemplates(); | |
| } catch (error) { | |
| console.error("Failed to clone template:", error); | |
| } | |
| }; | |
| const handleDeleteTemplate = async (template: Template) => { | |
| try { | |
| await dbCommands.deleteTemplate(template.id); | |
| await loadTemplates(); | |
| } catch (error) { | |
| console.error("Failed to delete template:", error); | |
| } | |
| }; | |
| const handleCloneTemplate = async (template: Template) => { | |
| try { | |
| const clonedTemplate: Template = { | |
| ...template, | |
| id: crypto.randomUUID(), | |
| title: `${template.title} Copy`, | |
| user_id: userId, | |
| }; | |
| await dbCommands.upsertTemplate(clonedTemplate); | |
| await loadTemplates(); | |
| } catch (error) { | |
| console.error("Failed to clone template:", error); | |
| toast({ | |
| title: "Failed to clone template", | |
| description: "Please try again later", | |
| variant: "destructive", | |
| }); | |
| } | |
| }; | |
| const handleDeleteTemplate = async (template: Template) => { | |
| try { | |
| await dbCommands.deleteTemplate(template.id); | |
| await loadTemplates(); | |
| } catch (error) { | |
| console.error("Failed to delete template:", error); | |
| toast({ | |
| title: "Failed to delete template", | |
| description: "Please try again later", | |
| variant: "destructive", | |
| }); | |
| } | |
| }; |
🤖 Prompt for AI Agents
In apps/desktop/src/components/settings/views/templates.tsx between lines 141
and 163, the error handling for cloning and deleting templates only logs errors
to the console without notifying users. Enhance user experience by integrating a
toast notification system to display error messages when these operations fail.
Modify the catch blocks to trigger user-facing error notifications alongside the
existing console.error calls.
| item: ReorderItem & { id: string }; | ||
| onChange: (item: ReorderItem & { id: string }) => void; | ||
| onDelete: (itemId: string) => void; | ||
| dragControls: any; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Add proper typing for dragControls prop.
Using any type defeats TypeScript's type safety benefits.
- dragControls: any;
+ dragControls: ReturnType<typeof useDragControls>;You'll need to import the type:
import { type DragControls, useDragControls } from "motion/react";🤖 Prompt for AI Agents
In apps/desktop/src/components/settings/components/template-sections.tsx at line
96, replace the type of dragControls from 'any' to the proper DragControls type
imported from "motion/react". Import 'DragControls' using `import { type
DragControls } from "motion/react";` and update the dragControls declaration to
use this type to ensure type safety.
No description provided.