Skip to content

Commit fa7fc21

Browse files
makingclaude
andcommitted
Add auto-generate summary button to entry form
Add a button next to the Summary field in EntryForm that calls the /summarize API to automatically generate a summary from the entry content. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
1 parent a6f96a0 commit fa7fc21

File tree

3 files changed

+61
-8
lines changed

3 files changed

+61
-8
lines changed

ui/src/pages/entries/EntryForm.tsx

Lines changed: 41 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ export function EntryForm({ mode }: EntryFormProps) {
3636
const [originalMarkdown, setOriginalMarkdown] = useState('');
3737
const [isRestoredFromPreview, setIsRestoredFromPreview] = useState(false);
3838
const [isLoadingExisting, setIsLoadingExisting] = useState(false);
39+
const [isSummarizing, setIsSummarizing] = useState(false);
3940

4041
// Load existing entry for edit mode
4142
const {
@@ -178,6 +179,25 @@ export function EntryForm({ mode }: EntryFormProps) {
178179
}
179180
};
180181

182+
const handleAutoSummarize = async () => {
183+
if (!formData.content.trim()) {
184+
setSubmitError('Content is required to generate summary');
185+
return;
186+
}
187+
188+
setIsSummarizing(true);
189+
setSubmitError(null);
190+
191+
try {
192+
const summary = await api.summarize(formData.content);
193+
handleFieldChange('summary', summary);
194+
} catch (error) {
195+
setSubmitError(error instanceof Error ? error.message : 'Failed to generate summary');
196+
} finally {
197+
setIsSummarizing(false);
198+
}
199+
};
200+
181201
const handleSubmit = (e: React.FormEvent) => {
182202
e.preventDefault();
183203
setSubmitError(null);
@@ -364,13 +384,27 @@ export function EntryForm({ mode }: EntryFormProps) {
364384
placeholder="Enter entry title"
365385
required
366386
/>
367-
<Textarea
368-
label="Summary"
369-
value={formData.summary}
370-
onChange={(e) => handleFieldChange('summary', e.target.value)}
371-
placeholder="Brief description of the entry"
372-
rows={2}
373-
/>
387+
<div>
388+
<div className="flex items-center justify-between mb-1">
389+
<label className="block text-sm font-medium text-black">Summary</label>
390+
<Button
391+
type="button"
392+
variant="secondary"
393+
size="sm"
394+
onClick={() => void handleAutoSummarize()}
395+
disabled={isSummarizing || !formData.content.trim()}
396+
loading={isSummarizing}
397+
>
398+
Auto Generate
399+
</Button>
400+
</div>
401+
<Textarea
402+
value={formData.summary}
403+
onChange={(e) => handleFieldChange('summary', e.target.value)}
404+
placeholder="Brief description of the entry"
405+
rows={2}
406+
/>
407+
</div>
374408
{mode === 'create' && (
375409
<div className="flex items-end space-x-2">
376410
<div className="w-80">

ui/src/services/api.ts

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { Entry, PaginationResult, SearchCriteria, CreateEntryRequest, UpdateEntryRequest, TagAndCount, Category, ProblemDetail } from '../types';
1+
import { Category, CreateEntryRequest, Entry, PaginationResult, ProblemDetail, SearchCriteria, TagAndCount, UpdateEntryRequest } from '../types';
22
import { createMarkdownWithFrontMatter } from '../utils';
33

44
const DEFAULT_TENANT = '_';
@@ -194,6 +194,20 @@ export const api = {
194194
});
195195
return handleResponse<TagAndCount[]>(response);
196196
},
197+
198+
// Summary operations
199+
async summarize(content: string): Promise<string> {
200+
const response = await fetch('/summarize', {
201+
method: 'POST',
202+
headers: {
203+
'Content-Type': 'application/json',
204+
...buildHeaders(),
205+
},
206+
body: JSON.stringify({ content }),
207+
});
208+
const result = await handleResponse<{ summary: string }>(response);
209+
return result.summary;
210+
},
197211
};
198212

199213
export { ApiError };

ui/vite.config.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,11 @@ export default defineConfig({
1111
changeOrigin: true,
1212
secure: false,
1313
},
14+
'/summarize': {
15+
target: 'http://localhost:8080',
16+
changeOrigin: true,
17+
secure: false,
18+
},
1419
},
1520
},
1621
build: {

0 commit comments

Comments
 (0)