FLOW NAME PERSISTENCE FIX
Documentation for Plans
๐ง Flow Name Persistence - COMPLETE FIX
Date: October 12, 2025
Status: โ
FIXED
Severity: HIGH (User Experience)
๐ฏ The Complete Problem
The flow name editing had TWO issues:
Issue 1: Signal Two-Way Binding โ FIXED
- Problem: Template used
[(ngModel)]with a signal (doesn't work) - Fix: Changed to one-way binding with manual signal update
- Status: โ Fixed earlier
Issue 2: No Persistence After Refresh โ THIS WAS THE REAL ISSUE
- Problem: Flow saves correctly, but on refresh shows "Untitled Flow"
- Root Cause:
currentFlowIdandcurrentFlowNamewere NOT persisted - Fix: Converted to use
autoFlashStatefor automatic persistence - Status: โ FIXED NOW!
๐ What Was Really Happening
Before Fix
// Regular signals - NOT persisted
readonly currentFlowId = signal<string | null>(null);
readonly currentFlowName = signal<string>('Untitled Flow');
User Experience:
- User edits name to "paks Flow" โ
- User saves flow โ Flow saved to storage with correct name โ
- User refreshes page โ
currentFlowId= null,currentFlowName= "Untitled Flow" โ - Canvas is blank, showing "Untitled Flow" โ
- But saved flow "paks Flow" exists in history (can click to load it) โ
The flow WAS saving correctly, but on refresh, the app started with a blank canvas instead of loading the last flow!
โ The Complete Fix
1. Convert to Flash Persistence
// โ
AFTER: Auto-persisted with Flash Persistence
readonly currentFlowId = autoFlashState<string | null>('singularity:currentFlowId', null);
readonly currentFlowName = autoFlashState<string>('singularity:currentFlowName', 'Untitled Flow');
2. Auto-Load Last Flow on Init
async ngOnInit(): Promise<void> {
// ... initialization ...
// Load available flows
await this.loadAvailableFlows();
// โ
AUTO-LOAD: Restore last opened flow
const lastFlowId = this.currentFlowId();
if (lastFlowId) {
console.log(`๐ Auto-loading last flow: ${lastFlowId}`);
await this.loadFlow(lastFlowId).catch(err => {
console.error('Failed to auto-load last flow:', err);
// If loading fails, start with blank canvas
this.createNewFlow();
});
} else {
console.log('๐ Starting with new flow');
}
// ... rest of initialization ...
}
3. Import autoFlashState
import { GgStorage, autoFlashState } from '@storage-system';
๐ What Works Now
User Experience (After Fix)
- Edit Flow Name: Click "Untitled Flow", type "My Amazing Flow" โ
- Save Flow: Click Save button โ Flow saved with new name โ
- Refresh Page: Automatically loads "My Amazing Flow" โ
- Name Persists: Shows "My Amazing Flow" in header โ
- Blocks Persist: Canvas shows all blocks โ
- Connections Persist: All connections restored โ
๐งช How to Test
Test 1: Name Editing
- Open Logic Builder
- Click on flow name
- Type "My Test Flow"
- Press Enter
- โ Name updates immediately
Test 2: Save and Persistence
- Continue from Test 1
- Add some blocks to canvas
- Click Save button
- See "โ Flow saved: My Test Flow"
- โ Flow saved with correct name
Test 3: Refresh Persistence (THE BIG FIX!)
- Continue from Test 2
- Refresh the page (F5 or Cmd+R)
- โ Canvas loads automatically
- โ Shows "My Test Flow" in header
- โ All blocks are restored
- โ All connections are restored
Test 4: Multiple Flows
- Create and save "Flow 1"
- Click "New Flow" button
- Create and save "Flow 2"
- Refresh page
- โ Loads "Flow 2" (last active)
- Click history, select "Flow 1"
- โ Loads "Flow 1" with correct name
๐ Impact
| Action | Before | After |
|---|---|---|
| Edit name | โ Broken (signal binding) | โ Works |
| Save flow | โ Saves with name | โ Saves with name |
| Refresh page | โ Shows "Untitled Flow" | โ Shows saved name |
| Auto-load flow | โ Blank canvas | โ Loads last flow |
| Name in history | โ Correct | โ Correct |
๐ Files Changed
logic-builder.component.ts
- Changed
currentFlowIdandcurrentFlowNameto useautoFlashState - Made
ngOnInitasync - Added auto-load logic for last opened flow
- Added
autoFlashStateimport
- Changed
logic-builder.component.html
- Fixed signal two-way binding (earlier fix)
๐ Key Learnings
1. Flash Persistence for UI State
When user state should persist across sessions:
// โ
DO: Use autoFlashState
readonly myState = autoFlashState('key', defaultValue);
// โ DON'T: Use regular signals for persistent state
readonly myState = signal(defaultValue);
2. Auto-Load Last Context
For better UX, restore user's last context:
async ngOnInit() {
const lastId = this.currentId();
if (lastId) {
await this.loadItem(lastId); // โ
Restore context
}
}
3. Two-Way Binding with Signals
Always use manual update pattern:
<input
[ngModel]="mySignal()"
(ngModelChange)="mySignal.set($event)"
/>
๐ Related Fixes
This completes the trilogy of fixes today:
- โ Storage System Mismatch - Flow Composer now loads flows
- โ Signal Two-Way Binding - Flow name editing works
- โ Flow Persistence - Flow name and canvas persist after refresh
Status: โ COMPLETELY FIXED
Flow name editing now works perfectly with full persistence across page refreshes! ๐