Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
70 changes: 42 additions & 28 deletions src/components/PlannerCanvas.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -358,6 +358,7 @@ export default function PlannerCanvas() {
const [workflowTitle, setWorkflowTitle] = useState(persisted.title || '');
const [isEditingTitle, setIsEditingTitle] = useState(false);
const [isGeneratingTitle, setIsGeneratingTitle] = useState(false);
const [titleError, setTitleError] = useState(null);
const [configModalNode, setConfigModalNode] = useState(null);
const [isConfigModalOpen, setIsConfigModalOpen] = useState(false);
const setActiveApp = useStore.use.actions().setActiveApp;
Expand Down Expand Up @@ -753,6 +754,7 @@ export default function PlannerCanvas() {

const handleTitleChange = useCallback((e) => {
setWorkflowTitle(e.target.value);
setTitleError(null);
}, []);

const handleTitleBlur = useCallback(() => {
Expand All @@ -769,9 +771,12 @@ export default function PlannerCanvas() {
const generateAITitle = useCallback(async () => {
if (isGeneratingTitle) return; // Prevent double-clicks

const previousTitle = workflowTitle;

try {
console.log('Generating AI title...');
setIsGeneratingTitle(true);
setTitleError(null);

const flowData = { nodes, edges };

Expand Down Expand Up @@ -804,23 +809,27 @@ export default function PlannerCanvas() {
suggestedTitle = suggestedTitle.replace(/['"]/g, '').trim();
console.log('Suggested title:', suggestedTitle);
setWorkflowTitle(suggestedTitle);
setTitleError(null);
} else {
console.warn('No title in response:', data);
setWorkflowTitle('AI Generated Flow');
setTitleError(null);
}
} else {
console.error('API error:', response.status, response.statusText);
const errorData = await response.json().catch(() => ({}));
console.error('Error details:', errorData);
setWorkflowTitle(''); // Reset to empty
setWorkflowTitle(previousTitle);
setTitleError('Unable to generate a new title. Please try again.');
}
} catch (error) {
console.error('Failed to generate AI title:', error);
setWorkflowTitle(''); // Reset to empty
setWorkflowTitle(previousTitle);
setTitleError('Unable to generate a new title. Please try again.');
} finally {
setIsGeneratingTitle(false);
}
}, [nodes, edges, isGeneratingTitle, workflowAutoTitleModel]);
}, [nodes, edges, isGeneratingTitle, workflowAutoTitleModel, workflowTitle]);

// Persist planner graph on each change
useEffect(() => {
Expand All @@ -834,33 +843,38 @@ export default function PlannerCanvas() {
<div className="planner-canvas-container">
{/* Workflow Title in upper left corner */}
<div className="workflow-title-container">
{isEditingTitle ? (
<input
type="text"
value={workflowTitle}
onChange={handleTitleChange}
onBlur={handleTitleBlur}
onKeyPress={handleTitleKeyPress}
placeholder="Title your Flow"
className="workflow-title-input"
autoFocus
/>
) : (
<div
className="workflow-title-display"
onDoubleClick={handleTitleDoubleClick}
<div className="workflow-title-row">
{isEditingTitle ? (
<input
type="text"
value={workflowTitle}
onChange={handleTitleChange}
onBlur={handleTitleBlur}
onKeyPress={handleTitleKeyPress}
placeholder="Title your Flow"
className="workflow-title-input"
autoFocus
/>
) : (
<div
className="workflow-title-display"
onDoubleClick={handleTitleDoubleClick}
>
{workflowTitle || 'Title your Flow'}
</div>
)}
<button
className="btn btn-ai-title"
onClick={generateAITitle}
disabled={isGeneratingTitle}
title={isGeneratingTitle ? "Generating title..." : "Generate title with AI"}
>
{workflowTitle || 'Title your Flow'}
</div>
<span className="icon">{isGeneratingTitle ? 'hourglass_empty' : 'auto_awesome'}</span>
</button>
</div>
{titleError && (
<div className="workflow-title-error">{titleError}</div>
)}
<button
className="btn btn-ai-title"
onClick={generateAITitle}
disabled={isGeneratingTitle}
title={isGeneratingTitle ? "Generating title..." : "Generate title with AI"}
>
<span className="icon">{isGeneratingTitle ? 'hourglass_empty' : 'auto_awesome'}</span>
</button>
</div>

<div className="planner-toolbar">
Expand Down
15 changes: 15 additions & 0 deletions src/styles/components/planner.css
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,13 @@
top: var(--spacing-10);
left: var(--spacing-10);
z-index: var(--z-index-dropdown);
display: flex;
flex-direction: column;
align-items: flex-start;
gap: var(--spacing-2);
}

.workflow-title-row {
display: flex;
align-items: center;
gap: var(--spacing-4);
Expand Down Expand Up @@ -152,6 +159,14 @@
transform: scale(1.05);
}

.workflow-title-error {
color: var(--surface-error);
font-size: var(--typography-font-size-sm);
background: rgba(255, 77, 77, 0.15);
padding: var(--spacing-2) var(--spacing-4);
border-radius: var(--radius-sm);
}

.planner-toolbar {
position: absolute;
top: var(--spacing-10);
Expand Down
Loading