From 36d5f3838cba600318ec44b313e4a39070cd64cc Mon Sep 17 00:00:00 2001 From: "Rodrigo Rodriguez (Pragmatismo)" Date: Sun, 30 Nov 2025 19:50:47 -0300 Subject: [PATCH] Add Suite user manual and HTMX architecture documentation - Add comprehensive user manual covering all Suite applications - Document HTMX architecture patterns used throughout the UI - Complete designer.html JavaScript implementation - Complete sources/index.html with remaining UI and event handlers - Update SUMMARY.md with new documentation entries --- docs/src/SUMMARY.md | 2 + docs/src/chapter-04-gbui/htmx-architecture.md | 534 ++++++++ docs/src/chapter-04-gbui/suite-manual.md | 1138 +++++++++++++++++ ui/suite/designer.html | 668 +++++++++- ui/suite/sources/index.html | 212 ++- 5 files changed, 2552 insertions(+), 2 deletions(-) create mode 100644 docs/src/chapter-04-gbui/suite-manual.md diff --git a/docs/src/SUMMARY.md b/docs/src/SUMMARY.md index 9015755e6..3423ac5e5 100644 --- a/docs/src/SUMMARY.md +++ b/docs/src/SUMMARY.md @@ -37,12 +37,14 @@ # Part IV - User Interface - [Chapter 04: .gbui Interface Reference](./chapter-04-gbui/README.md) + - [Suite User Manual](./chapter-04-gbui/suite-manual.md) - [UI Structure](./chapter-04-gbui/ui-structure.md) - [default.gbui - Full Desktop](./chapter-04-gbui/default-gbui.md) - [single.gbui - Simple Chat](./chapter-04-gbui/single-gbui.md) - [Console Mode](./chapter-04-gbui/console-mode.md) - [Player - Media Viewer](./chapter-04-gbui/player.md) - [Monitoring Dashboard](./chapter-04-gbui/monitoring.md) + - [HTMX Architecture](./chapter-04-gbui/htmx-architecture.md) # Part V - Themes and Styling diff --git a/docs/src/chapter-04-gbui/htmx-architecture.md b/docs/src/chapter-04-gbui/htmx-architecture.md index 8c4526e72..00ffc3d84 100644 --- a/docs/src/chapter-04-gbui/htmx-architecture.md +++ b/docs/src/chapter-04-gbui/htmx-architecture.md @@ -1 +1,535 @@ # HTMX Architecture + +## Overview + +General Bots Suite uses **HTMX** for its user interface - a modern approach that delivers the interactivity of a single-page application without the complexity of JavaScript frameworks like React, Vue, or Angular. + +> **Why HTMX?** +> - Simpler code, easier maintenance +> - Server-rendered HTML (fast, SEO-friendly) +> - Progressive enhancement +> - No build step required +> - Smaller payload than SPA frameworks + +--- + +## How HTMX Works + +### Traditional Web vs HTMX + +**Traditional (Full Page Reload):** +``` +User clicks → Browser requests full page → Server returns entire HTML → Browser replaces everything +``` + +**HTMX (Partial Update):** +``` +User clicks → HTMX requests fragment → Server returns HTML snippet → HTMX updates only that part +``` + +### Core Concept + +HTMX extends HTML with attributes that define: +1. **What triggers the request** (`hx-trigger`) +2. **Where to send it** (`hx-get`, `hx-post`) +3. **What to update** (`hx-target`) +4. **How to update it** (`hx-swap`) + +--- + +## HTMX Attributes Reference + +### Request Attributes + +| Attribute | Purpose | Example | +|-----------|---------|---------| +| `hx-get` | GET request to URL | `hx-get="/api/tasks"` | +| `hx-post` | POST request | `hx-post="/api/tasks"` | +| `hx-put` | PUT request | `hx-put="/api/tasks/1"` | +| `hx-patch` | PATCH request | `hx-patch="/api/tasks/1"` | +| `hx-delete` | DELETE request | `hx-delete="/api/tasks/1"` | + +### Trigger Attributes + +| Attribute | Purpose | Example | +|-----------|---------|---------| +| `hx-trigger` | Event that triggers request | `hx-trigger="click"` | +| | Load on page | `hx-trigger="load"` | +| | Periodic polling | `hx-trigger="every 5s"` | +| | Keyboard event | `hx-trigger="keyup changed delay:300ms"` | + +### Target & Swap Attributes + +| Attribute | Purpose | Example | +|-----------|---------|---------| +| `hx-target` | Element to update | `hx-target="#results"` | +| `hx-swap` | How to insert content | `hx-swap="innerHTML"` | +| | | `hx-swap="outerHTML"` | +| | | `hx-swap="beforeend"` | +| | | `hx-swap="afterbegin"` | + +--- + +## Suite Architecture + +### File Structure + +``` +ui/suite/ +├── index.html # Main entry point with navigation +├── default.gbui # Full desktop layout +├── single.gbui # Simple chat layout +├── designer.html # Visual dialog designer +├── editor.html # Code editor +├── settings.html # User settings +├── css/ +│ └── app.css # Global styles +├── js/ +│ ├── layout.js # Layout management +│ └── theme-manager.js # Theme switching +├── chat/ +│ ├── chat.html # Chat component +│ └── chat.css # Chat styles +├── drive/ +│ └── index.html # File manager +├── tasks/ +│ ├── tasks.html # Task manager +│ └── tasks.css # Task styles +├── mail/ +│ ├── mail.html # Email client +│ └── mail.css # Email styles +├── calendar/ +│ └── calendar.html # Calendar view +├── meet/ +│ ├── meet.html # Video meetings +│ └── meet.css # Meeting styles +├── paper/ +│ └── paper.html # Document editor +├── research/ +│ └── research.html # AI search +├── analytics/ +│ └── analytics.html # Dashboards +├── sources/ +│ └── index.html # Prompts & templates +├── tools/ +│ └── compliance.html # Security scanner +└── monitoring/ + └── ... # System monitoring +``` + +### Loading Pattern + +The Suite uses **lazy loading** - components load only when needed: + +```html + + + Chat + +``` + +When user clicks "Chat": +1. HTMX requests `/ui/suite/chat/chat.html` +2. Server returns the Chat HTML fragment +3. HTMX inserts it into `#main-content` +4. Only Chat code loads, not entire app + +--- + +## Component Patterns + +### 1. Load on Page View + +```html + +
+
Loading tasks...
+
+``` + +### 2. Form Submission + +```html + +
+ + +
+``` + +**Flow:** +1. User types task, clicks Add +2. HTMX POSTs form data to `/api/tasks` +3. Server creates task, returns HTML for new task item +4. HTMX inserts at beginning of `#task-list` +5. Form resets automatically + +### 3. Click Actions + +```html + +
+ + Review quarterly report + +
+``` + +### 4. Search with Debounce + +```html + + + +🔄 +
+``` + +**Flow:** +1. User types in search box +2. After 300ms of no typing, HTMX sends request +3. Spinner shows during request +4. Results replace `#search-results` content + +### 5. Real-time Updates (WebSocket) + +```html + +
+
+
+ +
+ + +
+
+``` + +**Flow:** +1. WebSocket connects on load +2. History loads via HTMX GET +3. New messages sent via WebSocket (`ws-send`) +4. Server pushes updates to all connected clients + +### 6. Polling for Updates + +```html + +
+ +
+``` + +### 7. Infinite Scroll + +```html + +
+ + +
+ Loading more... +
+
+``` + +--- + +## API Response Patterns + +### Server Returns HTML Fragments + +The server doesn't return JSON - it returns ready-to-display HTML: + +**Request:** +``` +GET /api/tasks +``` + +**Response:** +```html +
+ + Review quarterly report +
+
+ + Update documentation +
+``` + +### Swap Strategies + +| Strategy | Effect | +|----------|--------| +| `innerHTML` | Replace contents of target | +| `outerHTML` | Replace entire target element | +| `beforeend` | Append inside target (at end) | +| `afterbegin` | Prepend inside target (at start) | +| `beforebegin` | Insert before target | +| `afterend` | Insert after target | +| `delete` | Delete target element | +| `none` | Don't swap (for side effects) | + +--- + +## CSS Integration + +### Loading Indicators + +```css +/* Hidden by default */ +.htmx-indicator { + display: none; +} + +/* Shown during request */ +.htmx-request .htmx-indicator { + display: inline-block; +} + +/* Or when indicator IS the requesting element */ +.htmx-request.htmx-indicator { + display: inline-block; +} +``` + +### Transition Effects + +```css +/* Fade in new content */ +.htmx-settling { + opacity: 0; +} + +.htmx-swapping { + opacity: 0; + transition: opacity 0.2s ease-out; +} +``` + +--- + +## JavaScript Integration + +### HTMX Events + +```javascript +// After any HTMX swap +document.body.addEventListener('htmx:afterSwap', (e) => { + console.log('Content updated:', e.detail.target); +}); + +// Before request +document.body.addEventListener('htmx:beforeRequest', (e) => { + console.log('Sending request to:', e.detail.pathInfo.path); +}); + +// After request completes +document.body.addEventListener('htmx:afterRequest', (e) => { + if (e.detail.successful) { + console.log('Request succeeded'); + } else { + console.error('Request failed'); + } +}); + +// On WebSocket message +document.body.addEventListener('htmx:wsAfterMessage', (e) => { + console.log('Received:', e.detail.message); +}); +``` + +### Triggering HTMX from JavaScript + +```javascript +// Trigger an HTMX request programmatically +htmx.trigger('#task-list', 'load'); + +// Make an AJAX request +htmx.ajax('GET', '/api/tasks', { + target: '#task-list', + swap: 'innerHTML' +}); + +// Process new HTMX content +htmx.process(document.getElementById('new-content')); +``` + +--- + +## Designer Page Architecture + +The visual dialog designer uses a hybrid approach: + +### Canvas Management (JavaScript) +```javascript +// State managed in JavaScript +const state = { + nodes: new Map(), // Node data + connections: [], // Connections between nodes + zoom: 1, // Canvas zoom level + pan: { x: 0, y: 0 } // Canvas position +}; +``` + +### File Operations (HTMX) +```html + + + + + +``` + +### Drag-and-Drop (JavaScript) +```javascript +// Toolbox items are draggable +toolboxItems.forEach(item => { + item.addEventListener('dragstart', (e) => { + e.dataTransfer.setData('nodeType', item.dataset.nodeType); + }); +}); + +// Canvas handles drop +canvas.addEventListener('drop', (e) => { + const nodeType = e.dataTransfer.getData('nodeType'); + createNode(nodeType, e.clientX, e.clientY); +}); +``` + +--- + +## Performance Considerations + +### 1. Minimize Request Size + +Return only what's needed: +```html + +... + + +...
+``` + +### 2. Use Appropriate Triggers + +```html + +hx-trigger="every 30s" +hx-trigger="every 1s" + + +hx-trigger="keyup changed delay:300ms" +hx-trigger="keyup" +``` + +### 3. Lazy Load Heavy Content + +```html + +
+
+``` + +### 4. Use `hx-boost` for Navigation + +```html + + +``` + +--- + +## Security + +### CSRF Protection + +HTMX automatically includes CSRF tokens: + +```html + +``` + +```javascript +// Configure HTMX to send CSRF token +document.body.addEventListener('htmx:configRequest', (e) => { + e.detail.headers['X-CSRF-Token'] = document.querySelector('meta[name="csrf-token"]').content; +}); +``` + +### Content Security + +- Server validates all inputs +- HTML is sanitized before rendering +- Authentication checked on every request + +--- + +## Comparison: HTMX vs React + +| Aspect | HTMX | React | +|--------|------|-------| +| **Learning Curve** | Low (HTML attributes) | High (JSX, hooks, state) | +| **Bundle Size** | ~14KB | ~40KB + app code | +| **Build Step** | None | Required | +| **Server Load** | More (renders HTML) | Less (returns JSON) | +| **Client Load** | Less | More | +| **SEO** | Excellent | Requires SSR | +| **Complexity** | Simple | Complex | +| **Best For** | Content sites, dashboards | Complex SPAs, offline apps | + +--- + +## Further Reading + +- [HTMX Official Documentation](https://htmx.org/docs/) +- [HTMX Examples](https://htmx.org/examples/) +- [Hypermedia Systems (Book)](https://hypermedia.systems/) +- [Chapter 04: UI Reference](./README.md) \ No newline at end of file diff --git a/docs/src/chapter-04-gbui/suite-manual.md b/docs/src/chapter-04-gbui/suite-manual.md new file mode 100644 index 000000000..e04d0c883 --- /dev/null +++ b/docs/src/chapter-04-gbui/suite-manual.md @@ -0,0 +1,1138 @@ +# General Bots Suite - User Manual + +> **The Complete Productivity Workspace** +> +> *Like Microsoft Office, but with AI built-in* + +--- + +## Welcome to General Bots Suite + +General Bots Suite is your all-in-one workspace that combines communication, productivity, and AI assistance. Think of it like having Word, Outlook, Teams, and an AI assistant all in one place - but simpler and more powerful. + +**What makes it special:** +- Everything works together seamlessly +- AI helps you with every task +- No complex setup required +- Works in your browser + +--- + +## Part I: Getting Started + +### Opening the Suite + +1. **Open your web browser** (Chrome, Firefox, Safari, or Edge) +2. **Go to your General Bots address** (example: `http://your-company.bot:8080`) +3. **The Suite loads automatically** - you'll see the workspace in seconds + +### Your First Look + +When the Suite opens, you see: + +``` +┌─────────────────────────────────────────────────────────────────┐ +│ 🤖 General Bots [Apps Menu ⋮⋮⋮] [Theme 🌙] [U] │ +├─────────────────────────────────────────────────────────────────┤ +│ │ +│ │ +│ 💬 Chat (Main Area) │ +│ │ +│ Type your message here... │ +│ │ +└─────────────────────────────────────────────────────────────────┘ +``` + +### The Apps Menu + +Click the **nine-dot grid** (⋮⋮⋮) in the top right to see all applications: + +| Icon | App | What It Does | +|------|-----|--------------| +| 💬 | **Chat** | Talk with your AI assistant | +| 📁 | **Drive** | Store and manage your files | +| ✓ | **Tasks** | Manage your to-do lists | +| ✉ | **Mail** | Send and receive emails | +| 📅 | **Calendar** | Schedule meetings and events | +| 🎥 | **Meet** | Video calls and meetings | +| 📝 | **Paper** | Write documents with AI help | +| 🔍 | **Research** | AI-powered search | +| 📊 | **Analytics** | View reports and statistics | + +--- + +## Part II: Chat - Your AI Assistant + +### What Chat Does + +Chat is your personal AI assistant. Ask questions, get help with tasks, or have a conversation - just like talking to a helpful colleague. + +### How to Use Chat + +**Sending a Message:** +1. Click in the message box at the bottom +2. Type your question or request +3. Press **Enter** or click the **↑** button + +**Example Conversations:** + +``` +You: What meetings do I have today? +Bot: You have 2 meetings scheduled: + • 10:00 AM - Team Standup + • 2:00 PM - Project Review + +You: Remind me to call John tomorrow at 3pm +Bot: Done! I've created a reminder for tomorrow at 3:00 PM + to call John. + +You: Write a professional email to decline a meeting +Bot: Here's a draft: + + Subject: Unable to Attend Meeting + + Dear [Name], + + Thank you for the invitation. Unfortunately, I have + a scheduling conflict and won't be able to attend. + + Would it be possible to reschedule or receive a + summary of the discussion? + + Best regards +``` + +### Voice Input + +1. Click the **🎤 microphone** button +2. Speak your message +3. Click again to stop +4. Your words appear as text automatically + +### Quick Suggestions + +Below the message box, you'll see **suggestion chips** - common actions you can click: + +``` +[📊 Show my tasks] [📧 Check email] [📅 Today's schedule] [❓ Help] +``` + +### Keyboard Shortcuts for Chat + +| Shortcut | Action | +|----------|--------| +| `Enter` | Send message | +| `Shift+Enter` | New line (without sending) | +| `↑` Arrow | Edit last message | +| `/` | Show command menu | + +--- + +## Part III: Drive - File Management + +### What Drive Does + +Drive is your file storage - like Google Drive or OneDrive. Store documents, images, spreadsheets, and any file you need. + +### The Drive Interface + +``` +┌─────────────────────────────────────────────────────────────────┐ +│ [+ New ▼] 🔍 Search files... [⊞] [≡] │ +├──────────────┬──────────────────────────────────────────────────┤ +│ │ 📁 My Drive > Projects > 2024 │ +│ My Drive │ ─────────────────────────────────────────────────│ +│ ⭐ Starred │ [☐] Name Size Modified │ +│ 🕐 Recent │ ─────────────────────────────────────────────── │ +│ 🗑 Trash │ 📁 Reports - Today │ +│ │ 📁 Presentations - Yesterday │ +│ ───────────│ 📄 Budget.xlsx 245 KB Mar 15 │ +│ Labels │ 📄 Notes.docx 12 KB Mar 14 │ +│ 🔵 Work │ 🖼 Logo.png 89 KB Mar 10 │ +│ 🟢 Personal│ │ +└──────────────┴──────────────────────────────────────────────────┘ +``` + +### Creating and Uploading + +**Upload Files:** +1. Click **+ New** button +2. Select **Upload Files** +3. Choose files from your computer +4. *Or:* Drag files directly into Drive + +**Create New Folder:** +1. Click **+ New** +2. Select **New Folder** +3. Type the folder name +4. Press Enter + +### Working with Files + +**Open a file:** Double-click it + +**Select files:** Click the checkbox beside the file name + +**Multiple selection:** Hold `Ctrl` (or `Cmd` on Mac) and click files + +**Right-click menu options:** +- 📂 Open +- ⬇️ Download +- ✏️ Rename +- 📋 Copy +- 📁 Move to... +- ⭐ Add to Starred +- 🔗 Share +- 🗑 Delete + +### View Options + +| Button | View | Best For | +|--------|------|----------| +| ⊞ | Grid view | Images and visual files | +| ≡ | List view | Documents and details | + +### Keyboard Shortcuts for Drive + +| Shortcut | Action | +|----------|--------| +| `Ctrl+U` | Upload files | +| `Ctrl+N` | New folder | +| `Delete` | Move to trash | +| `Ctrl+C` | Copy | +| `Ctrl+V` | Paste | +| `Enter` | Open selected | + +--- + +## Part IV: Tasks - To-Do Management + +### What Tasks Does + +Tasks helps you track what needs to be done. Create to-do lists, set due dates, and mark items complete. + +### The Tasks Interface + +``` +┌─────────────────────────────────────────────────────────────────┐ +│ ✓ Tasks Total: 12 Active: 5 Done: 7│ +├─────────────────────────────────────────────────────────────────┤ +│ ┌─────────────────────────────────────────────────────────┐ │ +│ │ What needs to be done? [Category ▼] [+ Add]│ │ +│ └─────────────────────────────────────────────────────────┘ │ +├─────────────────────────────────────────────────────────────────┤ +│ [📋 All (12)] [⏳ Active (5)] [✓ Completed (7)] [⚡ Priority] │ +├─────────────────────────────────────────────────────────────────┤ +│ ☐ Review quarterly report 📅 Today 🔴 │ +│ ☐ Call client about proposal 📅 Today 🟡 │ +│ ☐ Update project documentation 📅 Tomorrow 🟢 │ +│ ☑ Send meeting notes ✓ Done │ +│ ☑ Complete expense report ✓ Done │ +└─────────────────────────────────────────────────────────────────┘ +``` + +### Adding a Task + +1. Type your task in the input box +2. *(Optional)* Select a category: Work, Personal, Shopping, Health +3. *(Optional)* Set a due date +4. Click **+ Add** or press Enter + +**Pro tip:** Be specific! Instead of "Work on project", write "Draft introduction section for project proposal" + +### Task Priorities + +| Color | Priority | When to Use | +|-------|----------|-------------| +| 🔴 Red | High | Must do today | +| 🟡 Yellow | Medium | Important but not urgent | +| 🟢 Green | Low | Can wait | + +### Completing Tasks + +- **Click the checkbox** to mark a task done +- Completed tasks move to the "Completed" tab +- Feel the satisfaction! ✓ + +### Filter Tabs + +| Tab | Shows | +|-----|-------| +| **All** | Everything | +| **Active** | Tasks not yet done | +| **Completed** | Finished tasks | +| **Priority** | High-priority tasks only | + +### Creating Tasks from Chat + +In Chat, just say: +``` +You: Create a task to review the budget by Friday +Bot: Task created: "Review the budget" - Due: Friday +``` + +--- + +## Part V: Mail - Email Management + +### What Mail Does + +Mail connects to your email accounts so you can read, write, and organize emails without leaving the Suite. + +### The Mail Interface + +``` +┌────────────────┬───────────────────┬────────────────────────────┐ +│ │ │ │ +│ [✏ Compose] │ Inbox │ From: john@company.com │ +│ │ │ Subject: Project Update │ +│ 📥 Inbox (3) │ ● Project Update │ ──────────────────────── │ +│ 📤 Sent │ from John │ │ +│ 📝 Drafts │ 10:30 AM │ Hi, │ +│ 🗑 Trash │ │ │ +│ │ ○ Meeting Notes │ Here's the latest update │ +│ │ from Sarah │ on our project... │ +│ │ Yesterday │ │ +│ │ │ Best, │ +│ │ ○ Invoice #1234 │ John │ +│ │ from Vendor │ │ +│ │ Mar 15 │ [Reply] [Forward] [Delete]│ +└────────────────┴───────────────────┴────────────────────────────┘ +``` + +### Reading Email + +1. Click on **Mail** in the Apps menu +2. Click any email in the list to read it +3. The full email appears on the right + +### Composing Email + +1. Click **✏ Compose** +2. Fill in the fields: + - **To:** recipient's email + - **Subject:** what it's about + - **Body:** your message +3. Click **Send** + +**AI-Assisted Writing:** +``` +You: Help me write an email to reschedule tomorrow's meeting +Bot: Here's a draft: + + To: [recipient] + Subject: Request to Reschedule Meeting + + Hi [Name], + + I hope this message finds you well. Would it be + possible to reschedule our meeting tomorrow? + I have an unexpected conflict. + + Please let me know what times work for you + later this week. + + Thank you for understanding. +``` + +### Email Folders + +| Folder | Purpose | +|--------|---------| +| **Inbox** | New and unread messages | +| **Sent** | Emails you've sent | +| **Drafts** | Unfinished emails | +| **Trash** | Deleted emails (emptied after 30 days) | + +### Email Actions + +| Button | Action | +|--------|--------| +| **Reply** | Respond to sender | +| **Reply All** | Respond to everyone | +| **Forward** | Send to someone else | +| **Delete** | Move to Trash | +| **Archive** | Remove from Inbox but keep | + +--- + +## Part VI: Calendar - Scheduling + +### What Calendar Does + +Calendar shows your schedule, meetings, and events. Plan your day, week, or month at a glance. + +### The Calendar Interface + +``` +┌─────────────────────────────────────────────────────────────────┐ +│ ◄ March 2024 ► [Day] [Week] [Month] │ +├─────────────────────────────────────────────────────────────────┤ +│ Mon Tue Wed Thu Fri Sat Sun │ +│ ────────────────────────────────────────────────────────────── │ +│ 1 2 3 │ +│ │ +│ 4 5 6 7 8 9 10 │ +│ ████ │ +│ Team │ +│ Meeting │ +│ │ +│ 11 12 13 14 15 16 17 │ +│ ████ ████ │ +│ Project Review │ +│ Demo 1:1 │ +└─────────────────────────────────────────────────────────────────┘ +``` + +### Creating an Event + +**Method 1: Click and Create** +1. Click on a day/time slot +2. Enter event details +3. Click Save + +**Method 2: Ask the AI** +``` +You: Schedule a team meeting for next Tuesday at 2pm +Bot: Event created: + 📅 Team Meeting + 🕐 Tuesday, March 19 at 2:00 PM + ⏱ Duration: 1 hour +``` + +### Event Details + +When creating an event, you can set: +- **Title** - What the event is +- **Date & Time** - When it happens +- **Duration** - How long it lasts +- **Location** - Where (room or video link) +- **Attendees** - Who to invite +- **Reminder** - When to notify you +- **Repeat** - Daily, weekly, monthly + +### Calendar Views + +| View | Shows | Best For | +|------|-------|----------| +| **Day** | Hour by hour | Detailed daily planning | +| **Week** | 7 days | Seeing your week ahead | +| **Month** | Full month | Long-term planning | + +### Keyboard Navigation + +| Key | Action | +|-----|--------| +| `←` `→` | Previous/Next period | +| `T` | Jump to Today | +| `D` | Day view | +| `W` | Week view | +| `M` | Month view | + +--- + +## Part VII: Meet - Video Calls + +### What Meet Does + +Meet lets you have video calls with one person or many. Share your screen, record meetings, and get AI transcriptions. + +### Starting a Meeting + +**Start Instant Meeting:** +1. Click **Meet** in Apps menu +2. Click **Start Meeting** +3. Share the link with others + +**Schedule for Later:** +``` +You: Schedule a video call with the team for tomorrow at 10am +Bot: Meeting scheduled: + 🎥 Team Video Call + 📅 Tomorrow at 10:00 AM + 🔗 Link: meet.bot/abc-defg-hij + + Shall I send invites to the team? +``` + +### The Meeting Interface + +``` +┌─────────────────────────────────────────────────────────────────┐ +│ Meeting Room 00:15:32 [👥 3] [💬] │ +├─────────────────────────────────────────────────────────────────┤ +│ ┌─────────────────────┐ ┌─────────────────────┐ │ +│ │ │ │ │ │ +│ │ 👤 You │ │ 👤 John │ │ +│ │ │ │ │ │ +│ │ (Camera) │ │ (Camera) │ │ +│ └─────────────────────┘ └─────────────────────┘ │ +│ │ +│ ┌─────────────────────┐ │ +│ │ 👤 Sarah │ │ +│ └─────────────────────┘ │ +├─────────────────────────────────────────────────────────────────┤ +│ [🎤 Mute] [📹 Video] [🖥 Share] [🔴 Record] [📞 End] │ +└─────────────────────────────────────────────────────────────────┘ +``` + +### Meeting Controls + +| Button | Function | +|--------|----------| +| 🎤 **Mute** | Turn microphone on/off | +| 📹 **Video** | Turn camera on/off | +| 🖥 **Share** | Share your screen | +| 🔴 **Record** | Record the meeting | +| 📝 **Transcribe** | Get live captions | +| 💬 **Chat** | Open meeting chat | +| 👥 **Participants** | See who's in the call | +| 📞 **End** | Leave the meeting | + +### Screen Sharing + +1. Click **🖥 Share** +2. Choose what to share: + - **Entire Screen** - Everything you see + - **Window** - One application + - **Tab** - One browser tab +3. Click **Share** +4. Click **Stop Sharing** when done + +### AI Features in Meetings + +**Live Transcription:** +- Enable with the **📝 Transcribe** button +- Words appear as people speak +- Great for accessibility and note-taking + +**Meeting Summary:** +After the meeting, ask: +``` +You: Summarize today's project meeting +Bot: Meeting Summary: + + Duration: 45 minutes + Participants: You, John, Sarah + + Key Points: + • Project deadline moved to April 15 + • John will handle client communication + • Sarah completing design by Friday + + Action Items: + • [You] Review budget proposal + • [John] Send client update + • [Sarah] Share design mockups +``` + +--- + +## Part VIII: Paper - AI Writing + +### What Paper Does + +Paper is your writing space with AI assistance. Write documents, notes, reports - and let AI help you write better. + +### The Paper Interface + +``` +┌────────────────┬────────────────────────────────────────────────┐ +│ │ [B] [I] [U] H1 H2 • ― 🔗 📷 [AI ✨] │ +│ 📄 Notes ├────────────────────────────────────────────────┤ +│ ──────────── │ │ +│ Meeting Notes │ Project Proposal │ +│ Project Plan │ ════════════════ │ +│ Ideas │ │ +│ │ Introduction │ +│ ──────────── │ ──────────── │ +│ Quick Start │ │ +│ [📄 Blank] │ This document outlines our proposal for │ +│ [📋 Meeting] │ the upcoming project. We aim to... │ +│ [✓ To-Do] │ │ +│ [🔬 Research] │ | │ +│ │ │ +└────────────────┴────────────────────────────────────────────────┘ +``` + +### Creating a Document + +1. Click **+ New** in the sidebar +2. Choose a template: + - **Blank** - Start fresh + - **Meeting Notes** - Pre-formatted for meetings + - **To-Do List** - Checkbox format + - **Research** - Sections for sources + +### Formatting Toolbar + +| Button | Function | Shortcut | +|--------|----------|----------| +| **B** | Bold | `Ctrl+B` | +| **I** | Italic | `Ctrl+I` | +| **U** | Underline | `Ctrl+U` | +| **H1** | Heading 1 | `Ctrl+1` | +| **H2** | Heading 2 | `Ctrl+2` | +| **•** | Bullet list | `Ctrl+Shift+8` | +| **―** | Numbered list | `Ctrl+Shift+7` | +| **🔗** | Insert link | `Ctrl+K` | +| **📷** | Insert image | - | + +### AI Writing Assistant ✨ + +Click the **AI ✨** button or type `/ai` for AI help: + +**Commands:** +``` +/ai improve → Make the text better +/ai shorter → Make it more concise +/ai longer → Expand with more detail +/ai formal → Make it professional +/ai friendly → Make it casual +/ai translate → Translate to another language +/ai summarize → Create a summary +``` + +**Example:** +``` +You wrote: "The thing we need to do is make the stuff better" + +/ai formal + +AI suggests: "Our objective is to enhance the quality of + our deliverables to meet higher standards." +``` + +### Auto-Save + +Paper saves automatically as you type. Look for: +- **"Saving..."** - Currently saving +- **"Saved"** - All changes saved +- **"Offline"** - Will save when connected + +--- + +## Part IX: Research - AI Search + +### What Research Does + +Research is like having a research assistant. Search the web, your documents, and knowledge bases - then get AI-synthesized answers. + +### The Research Interface + +``` +┌────────────────┬────────────────────────────────────────────────┐ +│ │ │ +│ 🔍 Research │ ┌────────────────────────────────────────┐ │ +│ │ │ What are the best practices for... │ │ +│ ──────────── │ └────────────────────────────────────────┘ │ +│ Focus: │ │ +│ [🌐 All] │ AI Answer: │ +│ [📚 Academic] │ ══════════ │ +│ [💻 Code] │ Based on multiple sources, here are the │ +│ [🏠 Internal] │ key best practices: │ +│ │ │ +│ Collections: │ 1. Start with clear requirements │ +│ 📁 Project A │ 2. Use iterative development │ +│ 📁 References │ 3. Test early and often │ +│ │ │ +│ Recent: │ Sources: │ +│ • market size │ [1] industry-guide.com │ +│ • competitors │ [2] techblog.dev │ +│ │ [3] your-docs/guidelines.pdf │ +└────────────────┴────────────────────────────────────────────────┘ +``` + +### Search Modes + +| Mode | Icon | Searches | +|------|------|----------| +| **All** | 🌐 | Everything | +| **Academic** | 📚 | Research papers, journals | +| **Code** | 💻 | Documentation, code examples | +| **Internal** | 🏠 | Your company's knowledge base | + +### Using Research + +1. Type your question in the search box +2. Select a focus mode (optional) +3. Press Enter +4. Read the AI-synthesized answer +5. Click sources to see original content + +### Collections + +Save important searches and sources: + +1. Click **+ New Collection** +2. Name it (e.g., "Q1 Project Research") +3. Add sources by clicking **Save to Collection** +4. Access anytime from the sidebar + +### Pro Tips + +**Be specific:** +- ❌ "marketing" +- ✅ "B2B SaaS marketing strategies for startups under 50 employees" + +**Use follow-up questions:** +``` +Search: What is machine learning? +Follow-up: How is it different from deep learning? +Follow-up: What are practical business applications? +``` + +--- + +## Part X: Analytics - Reports & Insights + +### What Analytics Does + +Analytics shows you reports about usage, conversations, and performance. Understand how the bot is being used and what's working. + +### The Analytics Interface + +``` +┌─────────────────────────────────────────────────────────────────┐ +│ 📊 Analytics Dashboard [Last 24h ▼] [⟳ Refresh] │ +├─────────────────────────────────────────────────────────────────┤ +│ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ │ +│ │ 1,234 │ │ 89% │ │ 2.3s │ │ 45 │ │ +│ │ Messages │ │ Success │ │ Avg Time │ │ Users │ │ +│ │ +12% │ │ Rate │ │ Response │ │ Today │ │ +│ └──────────┘ └──────────┘ └──────────┘ └──────────┘ │ +├─────────────────────────────────────────────────────────────────┤ +│ │ +│ Messages Over Time Top Questions │ +│ ┌─────────────────────────┐ ┌─────────────────────────┐ │ +│ │ ╭─╮ │ │ 1. How do I reset... │ │ +│ │ ╭╯ ╰╮ ╭─╮ │ │ 2. What is the status...│ │ +│ │ ╭╯ ╰────╯ ╰╮ │ │ 3. Where can I find... │ │ +│ │ ─╯ ╰── │ │ 4. Help with login │ │ +│ └─────────────────────────┘ └─────────────────────────┘ │ +└─────────────────────────────────────────────────────────────────┘ +``` + +### Key Metrics + +| Metric | What It Means | +|--------|---------------| +| **Messages** | Total conversations | +| **Success Rate** | % of questions answered well | +| **Avg Response Time** | How fast the bot replies | +| **Users** | Number of people using the bot | +| **Popular Topics** | What people ask about most | + +### Time Ranges + +Select different periods to analyze: +- Last Hour +- Last 6 Hours +- Last 24 Hours +- Last 7 Days +- Last 30 Days +- Custom Range + +### Exporting Data + +Click **Export** to download reports as: +- **CSV** - For spreadsheets +- **PDF** - For sharing +- **JSON** - For developers + +--- + +## Part XI: Designer - Visual Dialog Builder + +### What Designer Does + +Designer lets you create bot conversations visually - like VB6 form designer, but for conversations. Drag and drop blocks to build dialogs without coding. + +### The Designer Interface + +``` +┌──────────────┬──────────────────────────────────────┬──────────┐ +│ Toolbox │ Canvas │Properties│ +├──────────────┼──────────────────────────────────────┼──────────┤ +│ │ │ │ +│ 💬 TALK │ ┌─────────┐ │ Node: │ +│ 👂 HEAR │ │💬 TALK │ │ TALK │ +│ 📝 SET │ │"Hello!" │───┐ │ │ +│ │ └─────────┘ │ │ Message: │ +│ ───────── │ ▼ │ [Hello!] │ +│ │ ┌─────────┐ ┌─────────┐ │ │ +│ 🔀 IF │ │👂 HEAR │──▶│🔀 IF │ │ │ +│ 🔄 FOR │ │ name │ │name="Jo"│ │ │ +│ 🔃 SWITCH │ └─────────┘ └────┬────┘ │ │ +│ │ ┌───┴───┐ │ │ +│ ───────── │ Yes No │ │ +│ │ │ │ │ │ +│ 📞 CALL │ ┌────┴──┐ ┌──┴────┐ │ │ +│ 📧 SEND │ │💬TALK │ │💬TALK │ │ │ +│ 💾 SAVE │ │"Hi Jo"│ │"Hello"│ │ │ +│ │ └───────┘ └───────┘ │ │ +└──────────────┴──────────────────────────────────────┴──────────┘ +``` + +### Building a Dialog + +**Step 1: Drag Blocks** +- Drag from Toolbox to Canvas +- Blocks snap to grid + +**Step 2: Connect Blocks** +- Drag from output port (●) to input port +- Lines show conversation flow + +**Step 3: Configure Properties** +- Click a block +- Edit settings in Properties panel + +**Step 4: Export** +- Click **Export to .bas** +- Save your dialog file + +### Block Types + +| Block | Icon | Purpose | Example | +|-------|------|---------|---------| +| **TALK** | 💬 | Bot speaks | "Welcome! How can I help?" | +| **HEAR** | 👂 | Wait for user input | Store response in `name` | +| **SET** | 📝 | Set a variable | `total = price * quantity` | +| **IF** | 🔀 | Make decisions | If age > 18 then... | +| **FOR** | 🔄 | Repeat for items | For each item in cart... | +| **SWITCH** | 🔃 | Multiple choices | Switch on category... | +| **CALL** | 📞 | Call another dialog | Call "checkout" | +| **SEND MAIL** | 📧 | Send email | Send confirmation | +| **SAVE** | 💾 | Save data | Save to database | +| **WAIT** | ⏱ | Pause | Wait 5 seconds | + +### Example: Simple Greeting Dialog + +``` + ┌─────────────────┐ + │ 💬 TALK │ + │ "What's your │ + │ name?" │ + └────────┬────────┘ + │ + ▼ + ┌─────────────────┐ + │ 👂 HEAR │ + │ as: name │ + │ type: STRING │ + └────────┬────────┘ + │ + ▼ + ┌─────────────────┐ + │ 💬 TALK │ + │ "Nice to meet │ + │ you, {name}!" │ + └─────────────────┘ +``` + +**Generated Code:** +```basic +TALK "What's your name?" +HEAR name AS STRING +TALK "Nice to meet you, " + name + "!" +``` + +### Keyboard Shortcuts in Designer + +| Shortcut | Action | +|----------|--------| +| `Ctrl+S` | Save | +| `Ctrl+O` | Open file | +| `Ctrl+Z` | Undo | +| `Ctrl+Y` | Redo | +| `Ctrl+C` | Copy block | +| `Ctrl+V` | Paste block | +| `Delete` | Delete selected | +| `Escape` | Deselect | + +--- + +## Part XII: Sources - Prompts & Templates + +### What Sources Does + +Sources is your library of prompts, templates, tools, and AI models. Find and use pre-built components to extend your bot. + +### The Sources Interface + +``` +┌─────────────────────────────────────────────────────────────────┐ +│ Sources 🔍 Search... │ +├─────────────────────────────────────────────────────────────────┤ +│ [Prompts] [Templates] [MCP Servers] [LLM Tools] [Models] │ +├──────────────┬──────────────────────────────────────────────────┤ +│ │ │ +│ Categories │ ⭐ Featured │ +│ ─────────── │ ┌────────────┐ ┌────────────┐ │ +│ 📝 Writing │ │ Customer │ │ Sales │ │ +│ 📊 Analysis │ │ Service │ │ Assistant │ │ +│ 💼 Business │ │ ──────────│ │ ──────────│ │ +│ 💻 Code │ │ Handle │ │ Qualify │ │ +│ 🎨 Creative │ │ support │ │ leads and │ │ +│ │ │ inquiries │ │ schedule │ │ +│ │ │ [Use] │ │ [Use] │ │ +│ │ └────────────┘ └────────────┘ │ +└──────────────┴──────────────────────────────────────────────────┘ +``` + +### Tabs Explained + +| Tab | Contains | Use For | +|-----|----------|---------| +| **Prompts** | Pre-written AI instructions | Starting conversations | +| **Templates** | Complete bot packages | Full solutions | +| **MCP Servers** | External tool connections | Integrations | +| **LLM Tools** | AI functions | Extending capabilities | +| **Models** | AI model options | Choosing AI provider | + +### Using a Prompt + +1. Browse or search prompts +2. Click on a prompt card +3. Click **Use** to apply it +4. Customize if needed + +### Installing a Template + +1. Go to **Templates** tab +2. Find a template (e.g., "CRM Contacts") +3. Click **Install** +4. Configure settings +5. Template is now active + +### Available Models + +| Model | Provider | Best For | +|-------|----------|----------| +| GPT-4o | OpenAI | General tasks, vision | +| Claude 3.5 | Anthropic | Analysis, coding | +| Gemini 1.5 | Google | Long documents | +| Llama 3.1 | Meta | Open source, privacy | + +--- + +## Part XIII: Tools - System Utilities + +### Compliance Scanner + +Check your bot dialogs for security issues: + +``` +┌─────────────────────────────────────────────────────────────────┐ +│ 🛡 Compliance Scanner [Scan] [Export] │ +├─────────────────────────────────────────────────────────────────┤ +│ ┌──────┐ ┌──────┐ ┌──────┐ ┌──────┐ ┌──────┐ │ +│ │ 2 │ │ 5 │ │ 3 │ │ 1 │ │ 0 │ │ +│ │🔴Crit│ │🟠High│ │🟡Med │ │🟢Low │ │ℹInfo│ │ +│ └──────┘ └──────┘ └──────┘ └──────┘ └──────┘ │ +├─────────────────────────────────────────────────────────────────┤ +│ Severity │ Issue │ File │ Action │ +│ ───────────────────────────────────────────────────────────── │ +│ 🔴 Critical│ Hardcoded password │ start.bas:15 │ [Fix] │ +│ 🔴 Critical│ API key exposed │ api.bas:42 │ [Fix] │ +│ 🟠 High │ SQL injection risk │ data.bas:28 │ [Review] │ +└─────────────────────────────────────────────────────────────────┘ +``` + +**What It Checks:** +- Hardcoded passwords +- Exposed API keys +- SQL injection risks +- Deprecated keywords +- Security best practices + +--- + +## Part XIV: Settings + +### Accessing Settings + +1. Click your **avatar** (top right) +2. Select **Settings** + +### Setting Categories + +**Profile:** +- Display name +- Avatar image +- Email address +- Language preference + +**Notifications:** +- Email notifications +- Desktop alerts +- Sound preferences + +**Appearance:** +- Theme (Light/Dark/Auto) +- Accent color +- Font size + +**Privacy:** +- Data retention +- Conversation history +- Usage analytics + +**Connections:** +- Email accounts +- Calendar sync +- Cloud storage + +--- + +## Part XV: Keyboard Shortcuts Reference + +### Global Shortcuts + +| Shortcut | Action | +|----------|--------| +| `Alt+1` | Open Chat | +| `Alt+2` | Open Drive | +| `Alt+3` | Open Tasks | +| `Alt+4` | Open Mail | +| `Alt+5` | Open Calendar | +| `Escape` | Close dialog/menu | +| `/` | Focus search | +| `Ctrl+K` | Command palette | + +### Common Shortcuts + +| Shortcut | Action | +|----------|--------| +| `Ctrl+S` | Save | +| `Ctrl+Z` | Undo | +| `Ctrl+Y` | Redo | +| `Ctrl+C` | Copy | +| `Ctrl+V` | Paste | +| `Ctrl+A` | Select all | +| `Ctrl+F` | Find | + +--- + +## Part XVI: Tips & Best Practices + +### Daily Workflow + +**Morning:** +1. Open Suite +2. Check Chat for overnight messages +3. Review Tasks for the day +4. Check Calendar for meetings + +**During Work:** +- Use Chat for quick questions +- Upload files to Drive +- Update Tasks as you complete them +- Take notes in Paper + +**End of Day:** +- Mark completed tasks done +- Archive old emails +- Review tomorrow's calendar + +### Productivity Tips + +**In Chat:** +- Be specific in your questions +- Use follow-up questions +- Say "summarize" for long responses + +**In Drive:** +- Use folders to organize +- Star important files +- Use search instead of browsing + +**In Tasks:** +- Break big tasks into smaller ones +- Set realistic due dates +- Use categories to organize + +**In Mail:** +- Process emails once +- Archive instead of delete +- Use AI for drafting + +### Getting Help + +**Ask the Bot:** +``` +You: How do I upload a file? +You: What keyboard shortcuts are there? +You: Help me with tasks +``` + +**Resources:** +- This manual +- In-app help (click ?) +- Support team + +--- + +## Appendix A: Troubleshooting + +### Common Issues + +**Suite won't load:** +- Refresh the page (`F5` or `Ctrl+R`) +- Clear browser cache +- Try a different browser + +**Files won't upload:** +- Check file size (max 100MB) +- Check internet connection +- Try a smaller file first + +**Bot not responding:** +- Wait a few seconds +- Refresh the page +- Check internet connection + +**Video/audio not working:** +- Allow camera/microphone in browser +- Check device permissions +- Try different browser + +### Error Messages + +| Message | Solution | +|---------|----------| +| "Connection lost" | Check internet, refresh page | +| "File too large" | Reduce file size | +| "Permission denied" | Contact administrator | +| "Session expired" | Log in again | + +--- + +## Appendix B: Glossary + +| Term | Definition | +|------|------------| +| **Bot** | AI assistant that responds to your messages | +| **Dialog** | A conversation flow or script | +| **HTMX** | Technology that makes pages interactive | +| **KB** | Knowledge Base - stored information | +| **MCP** | Model Context Protocol - tool connections | +| **Suite** | The complete workspace application | +| **Template** | Pre-built bot configuration | + +--- + +## Appendix C: Version History + +| Version | Date | Changes | +|---------|------|---------| +| 1.0 | March 2024 | Initial release with Chat, Drive, Tasks, Mail | +| 1.1 | April 2024 | Added Meet, Paper, Research | +| 1.2 | May 2024 | Added Designer, Sources, Compliance | + +--- + +*© General Bots - Built with ❤️ and AI* + +*For the latest documentation, visit the [online manual](../chapter-04-gbui/README.md)* \ No newline at end of file diff --git a/ui/suite/designer.html b/ui/suite/designer.html index fccb7a9c5..90ec4212c 100644 --- a/ui/suite/designer.html +++ b/ui/suite/designer.html @@ -1462,4 +1462,670 @@ // Zoom with scroll container.addEventListener('wheel', (e) => { e.preventDefault(); - const delta = e.deltaY > + const delta = e.deltaY > 0 ? -0.1 : 0.1; + const newZoom = Math.min(Math.max(state.zoom + delta, 0.25), 2); + state.zoom = newZoom; + updateCanvasTransform(); + updateZoomDisplay(); + }); + } + + function updateCanvasTransform() { + const inner = document.getElementById('canvas-inner'); + inner.style.transform = `translate(${state.pan.x}px, ${state.pan.y}px) scale(${state.zoom})`; + } + + function updateZoomDisplay() { + document.getElementById('zoom-value').textContent = Math.round(state.zoom * 100) + '%'; + } + + // Grid snapping + function snapToGrid(value, gridSize = 20) { + return Math.round(value / gridSize) * gridSize; + } + + // Create Node + function createNode(type, x, y) { + const template = nodeTemplates[type]; + if (!template) return; + + const id = 'node-' + state.nextNodeId++; + const node = { + id, + type, + x, + y, + fields: {} + }; + + // Initialize field values + template.fields.forEach(field => { + node.fields[field.name] = field.default; + }); + + state.nodes.set(id, node); + renderNode(node); + saveToHistory(); + updateStatusBar(); + } + + // Render Node + function renderNode(node) { + const template = nodeTemplates[node.type]; + const typeClass = node.type.toLowerCase().replace(/\s+/g, '-'); + + let fieldsHtml = ''; + template.fields.forEach(field => { + const value = node.fields[field.name] || ''; + if (field.type === 'textarea') { + fieldsHtml += ` +
+ + +
+ `; + } else if (field.type === 'select') { + const options = field.options.map(opt => + `` + ).join(''); + fieldsHtml += ` +
+ + +
+ `; + } else { + fieldsHtml += ` +
+ + +
+ `; + } + }); + + let portsHtml = ''; + if (template.hasInput) { + portsHtml += `
`; + } + if (template.hasOutput) { + portsHtml += `
`; + } + if (template.hasOutputTrue) { + portsHtml += `
`; + } + if (template.hasOutputFalse) { + portsHtml += `
`; + } + + const nodeEl = document.createElement('div'); + nodeEl.className = 'node'; + nodeEl.id = node.id; + nodeEl.style.left = node.x + 'px'; + nodeEl.style.top = node.y + 'px'; + nodeEl.innerHTML = ` +
+ + ${getNodeIcon(node.type)} + + ${node.type} +
+
+ ${fieldsHtml} +
+ ${portsHtml} + `; + + // Make draggable + nodeEl.addEventListener('mousedown', (e) => { + if (e.target.classList.contains('node-port')) return; + selectNode(node.id); + startNodeDrag(e, node); + }); + + // Field change handlers + nodeEl.querySelectorAll('.node-field-input, .node-field-select').forEach(input => { + input.addEventListener('change', (e) => { + node.fields[e.target.dataset.field] = e.target.value; + saveToHistory(); + }); + }); + + // Port handlers for connections + nodeEl.querySelectorAll('.node-port').forEach(port => { + port.addEventListener('mousedown', (e) => { + e.stopPropagation(); + startConnection(node.id, port.dataset.port); + }); + port.addEventListener('mouseup', (e) => { + e.stopPropagation(); + endConnection(node.id, port.dataset.port); + }); + }); + + document.getElementById('canvas-inner').appendChild(nodeEl); + } + + function getNodeIcon(type) { + const icons = { + 'TALK': '', + 'HEAR': '', + 'SET': '', + 'IF': '', + 'FOR': '', + 'SWITCH': '', + 'CALL': '', + 'SEND MAIL': '', + 'GET': '', + 'POST': '', + 'SAVE': '', + 'WAIT': '', + 'SET BOT MEMORY': '', + 'GET BOT MEMORY': '', + 'SET USER MEMORY': '', + 'GET USER MEMORY': '' + }; + return icons[type] || ''; + } + + // Node dragging + function startNodeDrag(e, node) { + state.isDragging = true; + const nodeEl = document.getElementById(node.id); + const startX = e.clientX; + const startY = e.clientY; + const origX = node.x; + const origY = node.y; + + function onMove(e) { + const dx = (e.clientX - startX) / state.zoom; + const dy = (e.clientY - startY) / state.zoom; + node.x = snapToGrid(origX + dx); + node.y = snapToGrid(origY + dy); + nodeEl.style.left = node.x + 'px'; + nodeEl.style.top = node.y + 'px'; + updateConnections(); + } + + function onUp() { + state.isDragging = false; + document.removeEventListener('mousemove', onMove); + document.removeEventListener('mouseup', onUp); + saveToHistory(); + } + + document.addEventListener('mousemove', onMove); + document.addEventListener('mouseup', onUp); + } + + // Node selection + function selectNode(id) { + if (state.selectedNode) { + const prevEl = document.getElementById(state.selectedNode); + if (prevEl) prevEl.classList.remove('selected'); + } + state.selectedNode = id; + const nodeEl = document.getElementById(id); + if (nodeEl) nodeEl.classList.add('selected'); + updatePropertiesPanel(); + } + + function deselectAll() { + if (state.selectedNode) { + const el = document.getElementById(state.selectedNode); + if (el) el.classList.remove('selected'); + } + state.selectedNode = null; + state.selectedConnection = null; + updatePropertiesPanel(); + } + + // Connections + function startConnection(nodeId, portType) { + state.isConnecting = true; + state.connectionStart = { nodeId, portType }; + } + + function endConnection(nodeId, portType) { + if (!state.isConnecting || !state.connectionStart) return; + if (state.connectionStart.nodeId === nodeId) { + state.isConnecting = false; + state.connectionStart = null; + return; + } + + // Only allow output to input connections + if (state.connectionStart.portType === 'input' || portType !== 'input') { + state.isConnecting = false; + state.connectionStart = null; + return; + } + + const connection = { + from: state.connectionStart.nodeId, + fromPort: state.connectionStart.portType, + to: nodeId, + toPort: portType + }; + + state.connections.push(connection); + state.isConnecting = false; + state.connectionStart = null; + updateConnections(); + saveToHistory(); + } + + function updateConnections() { + const svg = document.getElementById('connections-svg'); + let paths = ''; + + state.connections.forEach((conn, index) => { + const fromEl = document.getElementById(conn.from); + const toEl = document.getElementById(conn.to); + if (!fromEl || !toEl) return; + + const fromPort = fromEl.querySelector(`[data-port="${conn.fromPort}"]`); + const toPort = toEl.querySelector(`[data-port="${conn.toPort}"]`); + if (!fromPort || !toPort) return; + + const fromRect = fromPort.getBoundingClientRect(); + const toRect = toPort.getBoundingClientRect(); + const canvasRect = document.getElementById('canvas-inner').getBoundingClientRect(); + + const x1 = (fromRect.left + fromRect.width / 2 - canvasRect.left) / state.zoom; + const y1 = (fromRect.top + fromRect.height / 2 - canvasRect.top) / state.zoom; + const x2 = (toRect.left + toRect.width / 2 - canvasRect.left) / state.zoom; + const y2 = (toRect.top + toRect.height / 2 - canvasRect.top) / state.zoom; + + const midX = (x1 + x2) / 2; + const d = `M ${x1} ${y1} C ${midX} ${y1}, ${midX} ${y2}, ${x2} ${y2}`; + + paths += ``; + }); + + svg.innerHTML = ` + + + + + + ${paths} + `; + } + + // Properties Panel + function updatePropertiesPanel() { + const content = document.getElementById('properties-content'); + const empty = document.getElementById('properties-empty'); + + if (!state.selectedNode) { + content.style.display = 'none'; + empty.style.display = 'block'; + return; + } + + const node = state.nodes.get(state.selectedNode); + if (!node) return; + + const template = nodeTemplates[node.type]; + empty.style.display = 'none'; + content.style.display = 'block'; + + let html = ` +
+
Node Info
+
+ + +
+
+ + +
+
+
+
Properties
+ `; + + template.fields.forEach(field => { + const value = node.fields[field.name] || ''; + if (field.type === 'textarea') { + html += ` +
+ + +
+ `; + } else { + html += ` +
+ + +
+ `; + } + }); + + html += '
'; + content.innerHTML = html; + + // Add change handlers + content.querySelectorAll('.property-input:not([readonly]), .property-textarea').forEach(input => { + input.addEventListener('change', (e) => { + const n = state.nodes.get(e.target.dataset.node); + if (n) { + n.fields[e.target.dataset.field] = e.target.value; + // Update node view + const nodeInput = document.querySelector(`#${n.id} [data-field="${e.target.dataset.field}"]`); + if (nodeInput) nodeInput.value = e.target.value; + saveToHistory(); + } + }); + }); + } + + // History (Undo/Redo) + function saveToHistory() { + const snapshot = { + nodes: Array.from(state.nodes.entries()).map(([id, node]) => ({...node})), + connections: [...state.connections] + }; + state.history = state.history.slice(0, state.historyIndex + 1); + state.history.push(snapshot); + state.historyIndex = state.history.length - 1; + } + + function undo() { + if (state.historyIndex > 0) { + state.historyIndex--; + restoreSnapshot(state.history[state.historyIndex]); + } + } + + function redo() { + if (state.historyIndex < state.history.length - 1) { + state.historyIndex++; + restoreSnapshot(state.history[state.historyIndex]); + } + } + + function restoreSnapshot(snapshot) { + // Clear canvas + document.getElementById('canvas-inner').innerHTML = ''; + state.nodes.clear(); + state.connections = []; + + // Restore nodes + snapshot.nodes.forEach(node => { + state.nodes.set(node.id, {...node}); + renderNode(node); + }); + + // Restore connections + state.connections = [...snapshot.connections]; + updateConnections(); + updateStatusBar(); + } + + // Keyboard Shortcuts + function initKeyboardShortcuts() { + document.addEventListener('keydown', (e) => { + if (e.ctrlKey || e.metaKey) { + switch (e.key) { + case 's': + e.preventDefault(); + saveDesign(); + break; + case 'o': + e.preventDefault(); + showModal('open-modal'); + break; + case 'z': + e.preventDefault(); + if (e.shiftKey) redo(); + else undo(); + break; + case 'y': + e.preventDefault(); + redo(); + break; + case 'c': + if (state.selectedNode) { + e.preventDefault(); + state.clipboard = {...state.nodes.get(state.selectedNode)}; + } + break; + case 'v': + if (state.clipboard) { + e.preventDefault(); + const newNode = {...state.clipboard}; + newNode.id = 'node-' + state.nextNodeId++; + newNode.x += 40; + newNode.y += 40; + state.nodes.set(newNode.id, newNode); + renderNode(newNode); + selectNode(newNode.id); + saveToHistory(); + } + break; + } + } + + if (e.key === 'Delete' && state.selectedNode) { + deleteSelectedNode(); + } + + if (e.key === 'Escape') { + deselectAll(); + hideContextMenu(); + } + }); + } + + function deleteSelectedNode() { + if (!state.selectedNode) return; + const nodeEl = document.getElementById(state.selectedNode); + if (nodeEl) nodeEl.remove(); + + // Remove connections + state.connections = state.connections.filter( + conn => conn.from !== state.selectedNode && conn.to !== state.selectedNode + ); + + state.nodes.delete(state.selectedNode); + state.selectedNode = null; + updateConnections(); + updatePropertiesPanel(); + updateStatusBar(); + saveToHistory(); + } + + // Context Menu + function initContextMenu() { + const canvas = document.getElementById('canvas'); + const contextMenu = document.getElementById('context-menu'); + + canvas.addEventListener('contextmenu', (e) => { + e.preventDefault(); + const nodeEl = e.target.closest('.node'); + if (nodeEl) { + selectNode(nodeEl.id); + } + contextMenu.style.left = e.clientX + 'px'; + contextMenu.style.top = e.clientY + 'px'; + contextMenu.classList.add('visible'); + }); + + document.addEventListener('click', () => { + hideContextMenu(); + }); + } + + function hideContextMenu() { + document.getElementById('context-menu').classList.remove('visible'); + } + + // Context Menu Actions + function duplicateNode() { + if (!state.selectedNode) return; + const node = state.nodes.get(state.selectedNode); + if (!node) return; + + const newNode = {...node, fields: {...node.fields}}; + newNode.id = 'node-' + state.nextNodeId++; + newNode.x += 40; + newNode.y += 40; + state.nodes.set(newNode.id, newNode); + renderNode(newNode); + selectNode(newNode.id); + saveToHistory(); + hideContextMenu(); + } + + // Status Bar + function updateStatusBar() { + document.getElementById('node-count').textContent = state.nodes.size + ' nodes'; + document.getElementById('connection-count').textContent = state.connections.length + ' connections'; + } + + // Zoom Controls + function zoomIn() { + state.zoom = Math.min(state.zoom + 0.1, 2); + updateCanvasTransform(); + updateZoomDisplay(); + } + + function zoomOut() { + state.zoom = Math.max(state.zoom - 0.1, 0.25); + updateCanvasTransform(); + updateZoomDisplay(); + } + + // Modal Management + function showModal(id) { + document.getElementById(id).classList.add('visible'); + if (id === 'open-modal') { + htmx.trigger('#file-list-content', 'load'); + } + } + + function hideModal(id) { + document.getElementById(id).classList.remove('visible'); + } + + // Save Design + function saveDesign() { + const nodesData = Array.from(state.nodes.values()); + document.getElementById('nodes-data').value = JSON.stringify(nodesData); + document.getElementById('connections-data').value = JSON.stringify(state.connections); + + // Trigger HTMX save + htmx.ajax('POST', '/api/v1/designer/save', { + source: document.getElementById('designer-data'), + target: '#status-message' + }); + } + + // Export to .bas + function exportToBas() { + let basCode = "' Generated by General Bots Designer\n"; + basCode += "' " + new Date().toISOString() + "\n\n"; + + // Sort nodes by position (top to bottom, left to right) + const sortedNodes = Array.from(state.nodes.values()).sort((a, b) => { + if (Math.abs(a.y - b.y) < 30) return a.x - b.x; + return a.y - b.y; + }); + + sortedNodes.forEach(node => { + const template = nodeTemplates[node.type]; + switch (node.type) { + case 'TALK': + basCode += `TALK "${node.fields.message}"\n`; + break; + case 'HEAR': + basCode += `HEAR ${node.fields.variable} AS ${node.fields.type}\n`; + break; + case 'SET': + basCode += `SET ${node.fields.variable} = ${node.fields.expression}\n`; + break; + case 'IF': + basCode += `IF ${node.fields.condition} THEN\n`; + break; + case 'FOR': + basCode += `FOR EACH ${node.fields.variable} IN ${node.fields.collection}\n`; + break; + case 'CALL': + basCode += `CALL ${node.fields.procedure}(${node.fields.arguments})\n`; + break; + case 'SEND MAIL': + basCode += `SEND MAIL TO "${node.fields.to}" SUBJECT "${node.fields.subject}" BODY "${node.fields.body}"\n`; + break; + case 'GET': + basCode += `GET ${node.fields.url} TO ${node.fields.variable}\n`; + break; + case 'POST': + basCode += `POST ${node.fields.url} WITH ${node.fields.body} TO ${node.fields.variable}\n`; + break; + case 'SAVE': + basCode += `SAVE ${node.fields.data} TO "${node.fields.filename}"\n`; + break; + case 'WAIT': + basCode += `WAIT ${node.fields.duration}\n`; + break; + case 'SET BOT MEMORY': + basCode += `SET BOT MEMORY "${node.fields.key}", ${node.fields.value}\n`; + break; + case 'GET BOT MEMORY': + basCode += `GET BOT MEMORY "${node.fields.key}" AS ${node.fields.variable}\n`; + break; + case 'SET USER MEMORY': + basCode += `SET USER MEMORY "${node.fields.key}", ${node.fields.value}\n`; + break; + case 'GET USER MEMORY': + basCode += `GET USER MEMORY "${node.fields.key}" AS ${node.fields.variable}\n`; + break; + } + }); + + // Download as file + const blob = new Blob([basCode], { type: 'text/plain' }); + const url = URL.createObjectURL(blob); + const a = document.createElement('a'); + a.href = url; + a.download = (document.getElementById('current-filename').value || 'dialog') + '.bas'; + a.click(); + URL.revokeObjectURL(url); + } + + // New Design + function newDesign() { + if (state.nodes.size > 0) { + if (!confirm('Clear current design? Unsaved changes will be lost.')) return; + } + document.getElementById('canvas-inner').innerHTML = ''; + state.nodes.clear(); + state.connections = []; + state.selectedNode = null; + state.history = []; + state.historyIndex = -1; + state.nextNodeId = 1; + document.getElementById('current-filename').value = ''; + document.getElementById('file-name').textContent = 'Untitled'; + updateConnections(); + updatePropertiesPanel(); + updateStatusBar(); + } + + // File selection in open modal + document.addEventListener('click', (e) => { + const fileItem = e.target.closest('.file-item'); + if (fileItem) { + document.querySelectorAll('.file-item').forEach(f => f.classList.remove('selected')); + fileItem.classList.add('selected'); + document.getElementById('selected-file').value = fileItem.dataset.path; + } + }); + + + diff --git a/ui/suite/sources/index.html b/ui/suite/sources/index.html index 797da4bd6..17f4bd2b3 100644 --- a/ui/suite/sources/index.html +++ b/ui/suite/sources/index.html @@ -1650,4 +1650,214 @@
- + + + +
+
+
Gemini 1.5 Pro
+
Google
+
+
+

Google's most capable model with 1M context window.

+ +
+ +
+
+
+ + + + + +
+
+
Llama 3.1 405B
+
Meta
+
+
+

Open source model with strong performance across tasks.

+ +
+ + + + + + + + + +