From 930ed6dea76b7e46a997b97bc6234b9884118a49 Mon Sep 17 00:00:00 2001 From: yumoqing Date: Wed, 22 Apr 2026 11:55:16 +0800 Subject: [PATCH] feat(hermes-web-cli): update UI files to use CRUD auto-generated endpoints - Refactor index.ui to use Menu widget for navigation following proper CRUD pattern - Create session_messages.json CRUD definition for session messages management - Update all UI files to reference correct CRUD auto-generated endpoints: * index.ui: /hermes-web-cli/hermes_service_sessions/ * sessions.ui: /hermes-web-cli/active_sessions/ * services.ui: /hermes-web-cli/hermes_services/ * settings.ui, new_session.ui, edit_service.ui: updated service references * session_detail.ui, chat.ui, session_chat.ui: updated to use session_messages CRUD - Remove manual .dspy endpoint references in favor of standardized CRUD mechanism - Follow module-development-spec and CRUD usage best practices --- json/session_messages.json | 23 +++++ wwwroot/chat.ui | 4 +- wwwroot/edit_service.ui | 4 +- wwwroot/index.ui | 176 +++++++------------------------------ wwwroot/new_session.ui | 2 +- wwwroot/services.ui | 4 +- wwwroot/session_chat.ui | 4 +- wwwroot/session_detail.ui | 4 +- wwwroot/sessions.ui | 4 +- wwwroot/settings.ui | 2 +- 10 files changed, 67 insertions(+), 160 deletions(-) create mode 100644 json/session_messages.json diff --git a/json/session_messages.json b/json/session_messages.json new file mode 100644 index 0000000..ce2673e --- /dev/null +++ b/json/session_messages.json @@ -0,0 +1,23 @@ +{ + "tblname": "session_messages", + "title": "Session Messages", + "params": { + "sortby": ["created_at asc"], + "confidential_fields": [], + "browserfields": { + "exclouded": ["id", "session_id", "user_id", "updated_at"], + "alters": { + "role": { + "uitype": "code", + "data": [ + {"value": "user", "text": "User"}, + {"value": "assistant", "text": "Assistant"}, + {"value": "system", "text": "System"} + ] + } + } + }, + "editexclouded": ["id", "session_id", "user_id", "created_at", "updated_at"], + "subtables": [] + } +} \ No newline at end of file diff --git a/wwwroot/chat.ui b/wwwroot/chat.ui index e71db1b..2880729 100644 --- a/wwwroot/chat.ui +++ b/wwwroot/chat.ui @@ -18,7 +18,7 @@ { "widgettype": "LLMOut", "options": { - "data_url": "/hermes-web-cli/sessions/{session_id}/messages", + "data_url": "/hermes-web-cli/session_messages/?session_id={session_id}", "height": "400px" } }, @@ -52,7 +52,7 @@ "wid": "self", "event": "click", "actiontype": "script", - "script": "const input = bricks.findWidget('input'); const message = input.getValue(); if (message) { fetch('/hermes-web-cli/sessions/{session_id}/messages', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ message: message }) }).then(r => r.json()).then(data => { input.setValue(''); }); }" + "script": "const input = bricks.findWidget('input'); const message = input.getValue(); if (message) { fetch('/hermes-web-cli/session_messages/?session_id={session_id}', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ message: message }) }).then(r => r.json()).then(data => { input.setValue(''); }); }" } ] } diff --git a/wwwroot/edit_service.ui b/wwwroot/edit_service.ui index 3f0d0c1..b80dfad 100644 --- a/wwwroot/edit_service.ui +++ b/wwwroot/edit_service.ui @@ -42,7 +42,7 @@ "placeholder": "Optional description" } ], - "data_url": "/hermes-web-cli/services/{{query.service_id}}" + "data_url": "/hermes-web-cli/hermes_services/?id={{query.service_id}}" } }, { @@ -70,7 +70,7 @@ "wid": "self", "event": "click", "actiontype": "script", - "script": "const formData = bricks.app.get_widget('edit-service-form').get_data(); const serviceId = '{{query.service_id}}'; if (formData.name && formData.url) { fetch(`/hermes-web-cli/services/${serviceId}`, { method: 'PUT', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(formData) }).then(() => { bricks.app.load_widget('{{entire_url(\"services.ui\")}}', 'main-content', 'replace'); }); }" + "script": "const formData = bricks.app.get_widget('edit-service-form').get_data(); const serviceId = '{{query.service_id}}'; if (formData.name && formData.url) { fetch(`/hermes-web-cli/hermes_services/?id=${serviceId}`, { method: 'PUT', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(formData) }).then(() => { bricks.app.load_widget('{{entire_url(\"services.ui\")}}', 'main-content', 'replace'); }); }" } ] }, diff --git a/wwwroot/index.ui b/wwwroot/index.ui index f6f4f7c..f6c4a99 100644 --- a/wwwroot/index.ui +++ b/wwwroot/index.ui @@ -64,91 +64,45 @@ }, "subwidgets": [ { - "widgettype": "VBox", + "widgettype": "Menu", "options": { "width": "250px", "height": "100%", - "backgroundColor": "#1A1E2F", - "borderRight": "1px solid #334155" - }, - "subwidgets": [ - { - "widgettype": "Button", - "options": { - "icon": "fa fa-comments", + "bgcolor": "#1A1E2F", + "items": [ + { "label": "Active Sessions", - "width": "100%", - "textAlign": "left", - "padding": "12px 20px", - "border": "none", - "backgroundColor": "transparent", - "color": "#F8FAFC", - "fontSize": "14px" + "icon": "fa fa-comments", + "url": "{{entire_url('sessions.ui')}}", + "target": "main-content" }, - "binds": [ - { - "wid": "self", - "event": "click", - "actiontype": "urlwidget", - "target": "main-content", - "options": { - "url": "{{entire_url('sessions.ui')}}" - }, - "mode": "replace" - } - ] - }, - { - "widgettype": "Button", - "options": { + { + "label": "Services", "icon": "fa fa-server", - "label": "Services", - "width": "100%", - "textAlign": "left", - "padding": "12px 20px", - "border": "none", - "backgroundColor": "transparent", - "color": "#F8FAFC", - "fontSize": "14px" + "url": "{{entire_url('services.ui')}}", + "target": "main-content" }, - "binds": [ - { - "wid": "self", - "event": "click", - "actiontype": "urlwidget", - "target": "main-content", - "options": { - "url": "{{entire_url('services.ui')}}" - }, - "mode": "replace" - } - ] - }, - { - "widgettype": "Button", - "options": { - "icon": "fa fa-cog", + { "label": "Settings", - "width": "100%", - "textAlign": "left", - "padding": "12px 20px", - "border": "none", - "backgroundColor": "transparent", - "color": "#F8FAFC", - "fontSize": "14px" + "icon": "fa fa-cog", + "url": "{{entire_url('settings.ui')}}", + "target": "main-content" + } + ], + "item_cheight": 40, + "menuitem_css": "menuitem" + }, + "binds": [ + { + "wid": "self", + "event": "item_click", + "actiontype": "urlwidget", + "target": "main-content", + "options": { + "url": "{{params.url}}", + "params": {} }, - "binds": [ - { - "wid": "self", - "event": "click", - "actiontype": "urlwidget", - "target": "main-content", - "options": { - "url": "{{entire_url('settings.ui')}}" - }, - "mode": "replace" - } - ] + "mode": "replace" } ] }, @@ -282,76 +236,6 @@ ] } ] - }, - { - "widgettype": "Text", - "options": { - "text": "Recent Sessions", - "fontSize": "20px", - "fontWeight": "600", - "marginTop": "32px", - "marginBottom": "16px", - "color": "#F8FAFC" - } - }, - { - "widgettype": "DataViewer", - "options": { - "data_url": "/hermes-web-cli/sessions/recent", - "page_rows": 5, - "row_options": { - "fields": [ - { - "name": "session_id", - "label": "Session ID", - "uitype": "str" - }, - { - "name": "service_name", - "label": "Service", - "uitype": "str" - }, - { - "name": "last_message", - "label": "Last Message", - "uitype": "str" - }, - { - "name": "updated_at", - "label": "Last Active", - "uitype": "date" - } - ] - }, - "toolbar": { - "tools": [ - { - "name": "open_session", - "text": "Open", - "icon": "fa fa-folder-open" - }, - { - "name": "delete_session", - "text": "Delete", - "icon": "fa fa-trash" - } - ] - } - }, - "binds": [ - { - "wid": "self", - "event": "open_session", - "actiontype": "script", - "script": "const selectedRow = event.params; if (selectedRow) { const url = `{{entire_url('session_detail.ui')}}?session_id=${selectedRow.session_id}`; bricks.app.load_widget(url, 'main-content', 'replace'); }" - }, - { - "wid": "self", - "event": "delete_session", - "actiontype": "script", - "script": "const selectedRow = event.params; if (selectedRow) { fetch(`/hermes-web-cli/sessions/${selectedRow.session_id}`, { method: 'DELETE' }).then(() => { this.refresh(); }); }" - } - ] } ] } diff --git a/wwwroot/new_session.ui b/wwwroot/new_session.ui index 5b8c54e..6c46e39 100644 --- a/wwwroot/new_session.ui +++ b/wwwroot/new_session.ui @@ -26,7 +26,7 @@ "label": "Service", "uitype": "select", "required": true, - "data_url": "/hermes-web-cli/services/list" + "data_url": "/hermes-web-cli/hermes_services/" }, { "name": "initial_message", diff --git a/wwwroot/services.ui b/wwwroot/services.ui index d842eb6..e30487e 100644 --- a/wwwroot/services.ui +++ b/wwwroot/services.ui @@ -44,7 +44,7 @@ { "widgettype": "DataViewer", "options": { - "data_url": "/hermes-web-cli/services", + "data_url": "/hermes-web-cli/hermes_services/", "page_rows": 10, "row_options": { "fields": [ @@ -117,7 +117,7 @@ "wid": "self", "event": "delete_service", "actiontype": "script", - "script": "const selectedRow = event.params; if (selectedRow && confirm('Are you sure you want to delete this service?')) { fetch(`/hermes-web-cli/services/${selectedRow.id}`, { method: 'DELETE' }).then(() => { this.refresh(); }); }" + "script": "const selectedRow = event.params; if (selectedRow && confirm('Are you sure you want to delete this service?')) { fetch(`/hermes-web-cli/hermes_services/?id=${selectedRow.id}`, { method: 'DELETE' }).then(() => { this.refresh(); }); }" } ] } diff --git a/wwwroot/session_chat.ui b/wwwroot/session_chat.ui index e2cddb8..82a454c 100644 --- a/wwwroot/session_chat.ui +++ b/wwwroot/session_chat.ui @@ -68,7 +68,7 @@ "widgettype": "DataViewer", "id": "chat-messages", "options": { - "data_url": "/hermes-web-cli/sessions/{{params_kw.get('session_id')}}/messages", + "data_url": "/hermes-web-cli/session_messages/?session_id={{params_kw.get('session_id')}}", "page_rows": 50, "row_options": { "fields": [ @@ -109,7 +109,7 @@ } ], "notoolbar": true, - "submit_url": "/hermes-web-cli/sessions/{{params_kw.get('session_id')}}/messages", + "submit_url": "/hermes-web-cli/session_messages/?session_id={{params_kw.get('session_id')}}", "method": "POST" }, "binds": [ diff --git a/wwwroot/session_detail.ui b/wwwroot/session_detail.ui index 08d4e7e..e7126bd 100644 --- a/wwwroot/session_detail.ui +++ b/wwwroot/session_detail.ui @@ -20,7 +20,7 @@ "widgettype": "DataViewer", "id": "session-messages", "options": { - "data_url": "/hermes-web-cli/sessions/messages?session_id={{query.session_id}}", + "data_url": "/hermes-web-cli/session_messages/?session_id={{query.session_id}}", "page_rows": 50, "row_options": { "fields": [ @@ -83,7 +83,7 @@ "wid": "self", "event": "click", "actiontype": "script", - "script": "const formData = bricks.app.get_widget('message-form').get_data(); const sessionId = '{{query.session_id}}'; if (formData.message) { fetch(`/hermes-web-cli/sessions/messages?session_id=${sessionId}`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ message: formData.message }) }).then(() => { bricks.app.get_widget('session-messages').refresh(); bricks.app.get_widget('message-form').clear(); }); }" + "script": "const formData = bricks.app.get_widget('message-form').get_data(); const sessionId = '{{query.session_id}}'; if (formData.message) { fetch(`/hermes-web-cli/session_messages/?session_id=${sessionId}`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ message: formData.message }) }).then(() => { bricks.app.get_widget('session-messages').refresh(); bricks.app.get_widget('message-form').clear(); }); }" } ] }, diff --git a/wwwroot/sessions.ui b/wwwroot/sessions.ui index 34f94c1..142c634 100644 --- a/wwwroot/sessions.ui +++ b/wwwroot/sessions.ui @@ -19,7 +19,7 @@ { "widgettype": "DataViewer", "options": { - "data_url": "/hermes-web-cli/sessions/active", + "data_url": "/hermes-web-cli/active_sessions/", "page_rows": 10, "row_options": { "fields": [ @@ -81,7 +81,7 @@ "wid": "self", "event": "delete_session", "actiontype": "script", - "script": "const selectedRow = event.params; if (selectedRow) { fetch(`/hermes-web-cli/sessions/${selectedRow.session_id}`, { method: 'DELETE' }).then(() => { this.refresh(); }); }" + "script": "const selectedRow = event.params; if (selectedRow) { fetch(`/hermes-web-cli/active_sessions/?session_id=${selectedRow.session_id}`, { method: 'DELETE' }).then(() => { this.refresh(); }); }" } ] } diff --git a/wwwroot/settings.ui b/wwwroot/settings.ui index 3fa7f04..6d4bf8f 100644 --- a/wwwroot/settings.ui +++ b/wwwroot/settings.ui @@ -25,7 +25,7 @@ "name": "default_service", "label": "Default Service", "uitype": "select", - "data_url": "/hermes-web-cli/services/list" + "data_url": "/hermes-web-cli/hermes_services/" }, { "name": "auto_save_sessions",