Skip to content

Commit 7de2b52

Browse files
authored
Feat: Examplse tab for user guide & delete trees (#73)
1 parent 6839d86 commit 7de2b52

12 files changed

Lines changed: 636 additions & 91 deletions

File tree

docs/ARCHITECTURE.md

Lines changed: 62 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,11 @@ The main process runs Node.js and manages the application lifecycle. It's organi
5252
- `browser:runStep`, `browser:runConditional` → AutomationExecutor
5353
- `pick-selector` → SelectorPicker
5454
- `browser:closed` event → Main window notification
55+
- `loopi:listTrees` → TreeStore: List all saved automations
56+
- `loopi:loadTrees` → TreeStore: Load specific automation
57+
- `loopi:saveTree` → TreeStore: Save/update automation
58+
- `loopi:loadExample` → TreeStore: Load example from `docs/examples/`
59+
- `loopi:deleteTree` → TreeStore: Delete automation file from disk
5560

5661
### Renderer Process (`src/`)
5762

@@ -61,9 +66,14 @@ React-based UI running in Chromium with restricted privileges.
6166

6267
```
6368
App (root)
64-
├── Dashboard
65-
│ └── Automation list & management
66-
└── AutomationBuilder
69+
├── Dashboard (src/components/Dashboard.tsx)
70+
│ ├── Tabs: "Your Automations" | "Examples"
71+
│ ├── YourAutomations (src/components/dashboard/YourAutomations.tsx)
72+
│ │ └── Edit/Delete/Export actions
73+
│ └── Examples (src/components/dashboard/Examples.tsx)
74+
│ └── Load example automations
75+
76+
└── AutomationBuilder (src/components/AutomationBuilder.tsx)
6777
├── BuilderHeader
6878
│ ├── Settings dialog (name, description, schedule)
6979
│ └── Execution controls (run, pause, stop)
@@ -168,6 +178,55 @@ ReactFlow re-renders updated node
168178
6. Complete: reset state, show success message
169179
```
170180

181+
### Delete Automation Flow
182+
183+
```
184+
1. User clicks Delete button in YourAutomations
185+
186+
2. Confirmation dialog: "Are you sure?"
187+
188+
3. If confirmed:
189+
window.electronAPI.tree.delete(automationId) [IPC invoke]
190+
191+
4. Main: ipcHandlers.handle("loopi:deleteTree")
192+
193+
5. TreeStore.deleteAutomation(id, folder)
194+
- Build file path: ~/.config/[AppName]/.trees/tree_[id].json
195+
- fs.unlinkSync(filePath) // Permanent deletion
196+
- Return true/false
197+
198+
6. If success:
199+
- Renderer updates local state
200+
- Remove automation from automations array
201+
- UI re-renders without deleted item
202+
203+
7. If error:
204+
- User sees alert: "Failed to delete automation"
205+
- Automation remains in list (no data loss)
206+
```
207+
208+
### Load Example Flow
209+
210+
```
211+
1. User clicks "Load Example" button on example card
212+
213+
2. handleLoadExample(example)
214+
215+
3. window.electronAPI.tree.loadExample(fileName) [IPC invoke]
216+
217+
4. Main: ipcHandlers.handle("loopi:loadExample")
218+
219+
5. Read file: docs/examples/[fileName].json
220+
221+
6. Return parsed automation JSON
222+
223+
7. Renderer:
224+
- Generate new ID: Date.now().toString()
225+
- window.electronAPI.tree.save(automation) [IPC invoke]
226+
- Add to automations array
227+
- Switch to "Your Automations" tab
228+
```
229+
171230
## Type System Design
172231

173232
### Variables System

docs/COMPONENT_GUIDE.md

Lines changed: 162 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,15 @@ App (src/app.tsx)
99
├── Router → Dashboard | AutomationBuilder | Credentials
1010
1111
├── Dashboard (src/components/Dashboard.tsx)
12-
│ └── Lists all automations
13-
│ └── Edit/Delete/Export actions
12+
│ ├── Tabs: "Your Automations" | "Examples"
13+
│ │
14+
│ ├── YourAutomations (src/components/dashboard/YourAutomations.tsx)
15+
│ │ └── Lists user's automations
16+
│ │ └── Edit/Delete/Export actions
17+
│ │
18+
│ └── Examples (src/components/dashboard/Examples.tsx)
19+
│ └── Lists 7 example automations
20+
│ └── "Load Example" button for each
1421
1522
└── AutomationBuilder (src/components/AutomationBuilder.tsx)
1623
├── BuilderHeader
@@ -63,23 +70,76 @@ const [currentAutomation, setCurrentAutomation] = useState<Automation>();
6370

6471
#### Dashboard.tsx (src/components/Dashboard.tsx)
6572

66-
List and manage automations.
73+
Container component managing automation list and examples with tab navigation.
6774

6875
**Props:**
6976
```typescript
7077
interface DashboardProps {
71-
automations: Automation[];
72-
onEdit: (automation: Automation) => void;
73-
onDelete: (id: string) => void;
74-
onNew: () => void;
78+
automations: StoredAutomation[];
79+
onCreateAutomation: () => void;
80+
onEditAutomation: (automation: StoredAutomation) => void;
81+
onUpdateAutomations: (automations: StoredAutomation[]) => void;
7582
}
7683
```
7784

7885
**Features:**
79-
- List all automations
86+
- Two-tab interface: "Your Automations" and "Examples"
87+
- Import automation from JSON file
88+
- Load example automations from `docs/examples/` folder (via IPC)
89+
- Delete automation with file system cleanup (via IPC)
90+
- Switches to "Your Automations" tab after import/load
91+
92+
**Key Methods:**
93+
- `handleImportAutomation()` - Import automation JSON file
94+
- `handleLoadExample(example)` - Load example via `tree.loadExample()` IPC
95+
- `handleDeleteAutomation(automationId)` - Delete via `tree.delete()` IPC, removes file from disk
96+
97+
#### YourAutomations.tsx (src/components/dashboard/YourAutomations.tsx)
98+
99+
Tab component displaying user's saved automations.
100+
101+
**Props:**
102+
```typescript
103+
interface YourAutomationsProps {
104+
automations: StoredAutomation[];
105+
totalAutomations: number;
106+
onEditAutomation: (automation: StoredAutomation) => void;
107+
onDeleteAutomation: (automationId: string) => Promise<void>;
108+
}
109+
```
110+
111+
**Features:**
112+
- Card-based grid layout
113+
- Shows automation name, description, last update time
80114
- Edit button → open in builder
81-
- Delete button → confirm and remove
82-
- New Automation button → create new
115+
- Delete button (Trash2 icon) → confirmation dialog → IPC delete
116+
- Empty state when no automations exist
117+
118+
**Key Methods:**
119+
- `handleDelete(automationId)` - Shows confirmation dialog, calls async delete callback
120+
121+
#### Examples.tsx (src/components/dashboard/Examples.tsx)
122+
123+
Tab component displaying example automations for user learning.
124+
125+
**Props:**
126+
```typescript
127+
interface ExamplesProps {
128+
automations: StoredAutomation[];
129+
onLoadExample: (example) => Promise<void>;
130+
}
131+
```
132+
133+
**Features:**
134+
- Grid layout with 7 curated example automations
135+
- Examples: Google Search, Contact Form, E-commerce Price Monitor, GitHub API, Hacker News, Multi-Page Scraper, Pagination Loop
136+
- "Load Example" button for each example
137+
- Creates new automation from example data
138+
- Hover shadow effect for interactivity
139+
140+
**Example Data Source:**
141+
- Loaded from `docs/examples/*.json` via IPC handler `loopi:loadExample`
142+
- Files read by main process for security (no direct renderer file access)
83143

84144
#### AutomationBuilder.tsx (src/components/AutomationBuilder.tsx)
85145

@@ -289,6 +349,98 @@ const executeGraph = async (nodeId) => {
289349
};
290350
```
291351

352+
## Storage & Backend
353+
354+
### TreeStore (src/main/treeStore.ts)
355+
356+
File system layer for automation persistence.
357+
358+
**Key Functions:**
359+
```typescript
360+
// List all saved automations
361+
listAutomations(folder: string): StoredAutomation[]
362+
363+
// Load specific automation by ID
364+
loadAutomation(id: string, folder: string): StoredAutomation | null
365+
366+
// Save/update automation to disk
367+
saveAutomation(automation: StoredAutomation, folder: string): string
368+
369+
// Delete automation file permanently
370+
deleteAutomation(id: string, folder: string): boolean
371+
372+
// Load example from docs/examples folder
373+
loadExample(fileName: string): StoredAutomation
374+
```
375+
376+
**Storage Location:**
377+
- User automations: `~/.config/[AppName]/.trees/tree_[automationId].json`
378+
- Examples (read-only): `docs/examples/*.json`
379+
- File format: JSON with StoredAutomation schema
380+
381+
**Example:**
382+
```typescript
383+
{
384+
"id": "1734000000000",
385+
"name": "Google Search Automation",
386+
"description": "Search Google and take screenshot",
387+
"createdAt": "2024-12-12 10:00:00",
388+
"updatedAt": "2024-12-12 10:30:00",
389+
"flow": { nodes: [...], edges: [...] }
390+
}
391+
```
392+
393+
### IPC Bridge (src/preload.ts)
394+
395+
Exposes secure API to renderer process.
396+
397+
**Available Methods:**
398+
```typescript
399+
window.electronAPI.tree = {
400+
list(): Promise<StoredAutomation[]>
401+
load(): Promise<StoredAutomation | null>
402+
save(automation: StoredAutomation): Promise<string>
403+
loadExample(fileName: string): Promise<StoredAutomation>
404+
delete(automationId: string): Promise<boolean>
405+
}
406+
```
407+
408+
**Security Model:**
409+
- Renderer cannot access filesystem directly
410+
- All file I/O routed through main process
411+
- Context isolation prevents direct Node.js access
412+
- Preload script acts as secure gateway
413+
414+
### IPC Handlers (src/main/ipcHandlers.ts)
415+
416+
Routes IPC messages to appropriate services.
417+
418+
**Automation Handlers:**
419+
- `loopi:listTrees` → TreeStore.listAutomations()
420+
- `loopi:loadTrees` → TreeStore.loadAutomation()
421+
- `loopi:saveTree` → TreeStore.saveAutomation()
422+
- `loopi:loadExample` → TreeStore.loadExample()
423+
- `loopi:deleteTree` → TreeStore.deleteAutomation()
424+
425+
**Type Definitions (src/types/globals.d.ts):**
426+
```typescript
427+
interface ElectronAPI {
428+
tree: {
429+
list: () => Promise<StoredAutomation[]>;
430+
load: () => Promise<StoredAutomation | null>;
431+
save: (automation: StoredAutomation) => Promise<string>;
432+
loadExample: (fileName: string) => Promise<StoredAutomation>;
433+
delete: (automationId: string) => Promise<boolean>;
434+
};
435+
}
436+
437+
declare global {
438+
interface Window {
439+
electronAPI: ElectronAPI;
440+
}
441+
}
442+
```
443+
292444
### UI Component Patterns
293445

294446
#### Form Fields

package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "loopi",
3-
"version": "1.0.0",
4-
"description": "A visual automation builder that lets you create, schedule, and run automations with secure credential management",
3+
"version": "1.2.2",
4+
"description": "Loopi — Visual Browser Automation for humans and teams",
55
"author": "Dyan-Dev",
66
"main": ".webpack/main",
77
"scripts": {

0 commit comments

Comments
 (0)