diff --git a/apps/home/workspace.html b/apps/home/workspace.html index 5737b4673..303ce8859 100644 --- a/apps/home/workspace.html +++ b/apps/home/workspace.html @@ -278,6 +278,27 @@ } .pulse-network-link a:hover { text-decoration: underline; } + +/* Click-to-converse interactive elements */ +[data-conversation] { + cursor: pointer; + transition: background 0.15s ease; + border-radius: 4px; +} +[data-conversation]:hover { + background: #f1f5f9; +} +.pulse-tell-more { + display: inline-block; + margin-top: 0.75rem; + font-size: 0.8rem; + color: #6366f1; + text-decoration: none; +} +.pulse-tell-more:hover { + text-decoration: underline; + background: transparent; +}
@@ -317,6 +338,7 @@
{{ narrative_header }}
+ Tell me more → {% if narrative_updated_at %}
Updated at {{ narrative_updated_at }}
{% endif %} @@ -336,7 +358,7 @@
{% for event in events %} {% set is_past = event.get('occurred', false) or (event.get('end', '') and event['end'] < now.strftime('%H:%M:%S')) %} -
+
{{ event.get('start', '')[:5] }} {{ event.get('title', 'Untitled') }}
@@ -347,7 +369,7 @@
Recent Activity
{% for act in activities[:6] %} -
+
{{ act.get('display_time', '') }} {{ act.get('description', act.get('activity', '')) }}
@@ -370,13 +392,13 @@
Needs You
{% if attention %} -
{{ attention.placeholder_text }}
+
{{ attention.placeholder_text }}
{% endif %} {% for item in pulse_needs %} -
{{ item }}
+
{{ item }}
{% endfor %} {% for todo in todos[:7] %} -
{{ todo.get('text', '') }}{% if todo.get('facet') %} ({{ todo['facet'] }}){% endif %}
+
{{ todo.get('text', '') }}{% if todo.get('facet') %} ({{ todo['facet'] }}){% endif %}
{% endfor %}
{% if todos|length > 7 %} @@ -391,7 +413,7 @@
Network Pulse
{% for ent in entities %} -
+
{{ ent.get('entity_type', '?')[:3] }} {{ ent.get('name', '') }}
@@ -413,6 +435,18 @@ if (el) el.innerHTML = marked.parse(narrativeRaw, {breaks: true, gfm: true}); } + // Click-to-converse: delegated handler for all [data-conversation] elements + var dashboard = document.querySelector('.pulse-dashboard'); + if (dashboard) { + dashboard.addEventListener('click', function(e) { + var el = e.target.closest('[data-conversation]'); + if (el && window.openConversation) { + e.preventDefault(); + window.openConversation({ prompt: el.dataset.conversation }); + } + }); + } + // WebSocket live updates if (window.appEvents) { // Vital signs: supervisor.status, observe.observed, observe.status diff --git a/convey/templates/app.html b/convey/templates/app.html index 0e40dd651..c6c993aa5 100644 --- a/convey/templates/app.html +++ b/convey/templates/app.html @@ -190,6 +190,25 @@ // Expose for websocket navigate handler window._closeConversationPanel = closePanel; + // --- Public conversation API --- + // Generic API for any app to open the conversation panel with a pre-filled prompt. + window.openConversation = function(options) { + options = options || {}; + if (options.prompt) { + input.value = options.prompt; + input.dispatchEvent(new Event('input')); + } + if (options.autoSend) { + form.requestSubmit(); + } else { + input.focus(); + input.setSelectionRange(input.value.length, input.value.length); + if (options.prompt && options.prompt.length > 40) { + openPanel(); + } + } + }; + // Save state before navigation window.addEventListener('pagehide', save);