Rebuild workspace widgets and behavioral graph views
This commit is contained in:
@@ -3,18 +3,18 @@
|
||||
class="tag {% if active_tab == 'graphs' %}is-dark{% else %}is-link is-light{% endif %}"
|
||||
href="{{ graphs_url }}">
|
||||
<span class="icon is-small"><i class="fa-solid fa-chart-line"></i></span>
|
||||
<span>Insight Graphs</span>
|
||||
<span>Behavioral Graphs</span>
|
||||
</a>
|
||||
<a
|
||||
class="tag {% if active_tab == 'information' %}is-dark{% else %}is-link is-light{% endif %}"
|
||||
href="{{ information_url }}">
|
||||
<span class="icon is-small"><i class="fa-solid fa-circle-info"></i></span>
|
||||
<span>Information View</span>
|
||||
<span>MS / PS Information</span>
|
||||
</a>
|
||||
<a
|
||||
class="tag {% if active_tab == 'help' %}is-dark{% else %}is-link is-light{% endif %}"
|
||||
href="{{ help_url }}">
|
||||
<span class="icon is-small"><i class="fa-solid fa-circle-question"></i></span>
|
||||
<span>Scoring Guide</span>
|
||||
<span>MS / PS Help</span>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
<div class="gia-behavior-shell">
|
||||
<div class="is-flex is-justify-content-space-between is-align-items-center is-flex-wrap-wrap mb-3">
|
||||
<div>
|
||||
<p class="is-size-7 has-text-weight-semibold has-text-grey mb-1">{{ metric.state_label }} · {{ metric.group|upper }}</p>
|
||||
<h3 class="title is-5 mb-1">{{ metric.title }}</h3>
|
||||
<p class="is-size-7">{{ metric.calculation }}</p>
|
||||
</div>
|
||||
{% include "partials/behavioral-range-tabs.html" %}
|
||||
</div>
|
||||
|
||||
<div class="columns is-multiline">
|
||||
<div class="column is-12">
|
||||
{% include "partials/behavioral-graph-card.html" with graph=metric person=person graphs_widget_url=graphs_widget_url %}
|
||||
</div>
|
||||
<div class="column is-12-tablet is-6-desktop">
|
||||
<article class="message is-light">
|
||||
<div class="message-body">
|
||||
<p class="is-size-7 has-text-weight-semibold has-text-grey mb-1">Psychological Reading</p>
|
||||
<p>{{ metric.psychology }}</p>
|
||||
</div>
|
||||
</article>
|
||||
</div>
|
||||
<div class="column is-12-tablet is-6-desktop">
|
||||
<article class="message is-light">
|
||||
<div class="message-body">
|
||||
<p class="is-size-7 has-text-weight-semibold has-text-grey mb-1">Coverage</p>
|
||||
<p class="mb-2">{{ coverage.message_count }} messages · {{ coverage.event_count }} events</p>
|
||||
<p class="is-size-7">Latest value: {{ metric.current_value_label }}</p>
|
||||
{% if metric.delta_label %}
|
||||
<p class="is-size-7">Latest shift: {{ metric.delta_label }}</p>
|
||||
{% endif %}
|
||||
</div>
|
||||
</article>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
36
core/templates/partials/ai-workspace-behavioral-graphs.html
Normal file
36
core/templates/partials/ai-workspace-behavioral-graphs.html
Normal file
@@ -0,0 +1,36 @@
|
||||
<div class="gia-behavior-shell">
|
||||
<div class="is-flex is-justify-content-space-between is-align-items-center is-flex-wrap-wrap mb-3">
|
||||
<div>
|
||||
<p class="is-size-7 has-text-weight-semibold has-text-grey mb-1">Behavioral Graphs</p>
|
||||
<p class="mb-0">{{ coverage.message_count }} messages · {{ coverage.event_count }} events · {{ coverage.session_count }} sessions</p>
|
||||
</div>
|
||||
{% include "partials/behavioral-range-tabs.html" %}
|
||||
</div>
|
||||
|
||||
<div class="columns is-multiline">
|
||||
{% for card in summary_cards %}
|
||||
<div class="column is-12-mobile is-6-tablet is-4-desktop">
|
||||
{% include "partials/behavioral-summary-card.html" with card=card %}
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
|
||||
{% for group_key, group in behavioral_groups.items %}
|
||||
<section class="mb-4">
|
||||
<div class="mb-3">
|
||||
<p class="is-size-7 has-text-weight-semibold has-text-grey mb-1">{{ group.eyebrow }}</p>
|
||||
<h3 class="title is-5 mb-1">{{ group.title }}</h3>
|
||||
<p class="is-size-7">{{ group.summary }}</p>
|
||||
</div>
|
||||
<div class="columns is-multiline">
|
||||
{% for graph in graph_cards %}
|
||||
{% if graph.group == group_key %}
|
||||
<div class="column is-12-mobile is-6-desktop">
|
||||
{% include "partials/behavioral-graph-card.html" with graph=graph person=person graphs_widget_url=graphs_widget_url %}
|
||||
</div>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
</div>
|
||||
</section>
|
||||
{% endfor %}
|
||||
</div>
|
||||
33
core/templates/partials/ai-workspace-behavioral-help.html
Normal file
33
core/templates/partials/ai-workspace-behavioral-help.html
Normal file
@@ -0,0 +1,33 @@
|
||||
<div class="gia-behavior-shell">
|
||||
<div class="is-flex is-justify-content-space-between is-align-items-center is-flex-wrap-wrap mb-3">
|
||||
<div>
|
||||
<p class="is-size-7 has-text-weight-semibold has-text-grey mb-1">MS / PS Help</p>
|
||||
<p class="mb-0">Signal definitions and psychological interpretation for the timing system.</p>
|
||||
</div>
|
||||
{% include "partials/behavioral-range-tabs.html" %}
|
||||
</div>
|
||||
|
||||
{% for group_key, group in groups.items %}
|
||||
<section class="box mb-4">
|
||||
<p class="is-size-7 has-text-weight-semibold has-text-grey mb-1">{{ group.eyebrow }}</p>
|
||||
<h3 class="title is-5 mb-2">{{ group.title }}</h3>
|
||||
<p class="mb-3">{{ group.summary }}</p>
|
||||
{% for metric in metrics %}
|
||||
{% if metric.group == group_key %}
|
||||
<article class="message is-light mb-3">
|
||||
<div class="message-body">
|
||||
<p class="is-size-7 has-text-weight-semibold has-text-grey mb-1">{{ metric.state_label }}</p>
|
||||
<p class="title is-6 mb-2">
|
||||
<span class="icon is-small mr-1"><i class="{{ metric.icon }}"></i></span>
|
||||
<span>{{ metric.title }}</span>
|
||||
</p>
|
||||
<p class="mb-2"><strong>Current:</strong> {{ metric.current_value_label }}</p>
|
||||
<p class="mb-2"><strong>How it is calculated:</strong> {{ metric.calculation }}</p>
|
||||
<p><strong>What it can mean:</strong> {{ metric.psychology }}</p>
|
||||
</div>
|
||||
</article>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
</section>
|
||||
{% endfor %}
|
||||
</div>
|
||||
@@ -0,0 +1,51 @@
|
||||
<div class="gia-behavior-shell">
|
||||
<div class="is-flex is-justify-content-space-between is-align-items-center is-flex-wrap-wrap mb-3">
|
||||
<div>
|
||||
<p class="is-size-7 has-text-weight-semibold has-text-grey mb-1">MS / PS Information</p>
|
||||
<p class="mb-0">Current timing signals for {{ person.name }} across message state and presence state.</p>
|
||||
</div>
|
||||
{% include "partials/behavioral-range-tabs.html" %}
|
||||
</div>
|
||||
|
||||
<div class="columns is-multiline">
|
||||
{% for card in summary_cards %}
|
||||
<div class="column is-12-mobile is-6-tablet is-4-desktop">
|
||||
{% include "partials/behavioral-summary-card.html" with card=card %}
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
|
||||
{% for group_key, group in behavioral_groups.items %}
|
||||
<section class="box mb-4">
|
||||
<p class="is-size-7 has-text-weight-semibold has-text-grey mb-1">{{ group.eyebrow }}</p>
|
||||
<h3 class="title is-5 mb-2">{{ group.title }}</h3>
|
||||
<p class="mb-3">{{ group.summary }}</p>
|
||||
<div class="table-container">
|
||||
<table class="table is-fullwidth is-hoverable">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Metric</th>
|
||||
<th>Current</th>
|
||||
<th>Meaning</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for graph in graph_cards %}
|
||||
{% if graph.group == group_key %}
|
||||
<tr>
|
||||
<td>
|
||||
<a href="{% url 'ai_workspace_insight_detail' type='page' person_id=person.id metric=graph.slug %}?range={{ range_key }}">
|
||||
{{ graph.title }}
|
||||
</a>
|
||||
</td>
|
||||
<td>{{ graph.current_value_label }}</td>
|
||||
<td>{{ graph.psychology }}</td>
|
||||
</tr>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</section>
|
||||
{% endfor %}
|
||||
</div>
|
||||
@@ -9,35 +9,18 @@
|
||||
<div style="margin-bottom: 0.75rem; padding: 0.5rem 0.25rem; border-bottom: 1px solid rgba(0, 0, 0, 0.12);">
|
||||
<p class="is-size-7 has-text-weight-semibold">Selected Person</p>
|
||||
<h3 class="title is-5" style="margin-bottom: 0.25rem;">{{ person.name }}</h3>
|
||||
<div class="tags" style="margin-top: 0.35rem;">
|
||||
<a class="tag is-light" href="{% url 'ai_workspace_insight_detail' type='page' person_id=person.id metric='platform' %}">Platform {{ workspace_conversation.platform_type|title }}</a>
|
||||
<a class="tag is-light" href="{% url 'ai_workspace_insight_detail' type='page' person_id=person.id metric='thread' %}">Thread {{ workspace_conversation.platform_thread_id|default:"-" }}</a>
|
||||
<a class="tag is-light" href="{% url 'ai_workspace_insight_detail' type='page' person_id=person.id metric='workspace_created' %}">Workspace Created {{ workspace_conversation.created_at|default:"-" }}</a>
|
||||
<a class="tag is-light" href="{% url 'ai_workspace_insight_detail' type='page' person_id=person.id metric='stability_state' %}">Stability {{ workspace_conversation.stability_state|title }}</a>
|
||||
<a class="tag is-light" href="{% url 'ai_workspace_insight_detail' type='page' person_id=person.id metric='stability_score' %}">Stability Score {{ workspace_conversation.stability_score|default:"-" }}</a>
|
||||
<a class="tag is-light" href="{% url 'ai_workspace_insight_detail' type='page' person_id=person.id metric='stability_confidence' %}">Confidence {{ workspace_conversation.stability_confidence }}</a>
|
||||
<a class="tag is-light" href="{% url 'ai_workspace_insight_detail' type='page' person_id=person.id metric='sample_messages' %}">Sample Msg {{ workspace_conversation.stability_sample_messages }}</a>
|
||||
<a class="tag is-light" href="{% url 'ai_workspace_insight_detail' type='page' person_id=person.id metric='sample_days' %}">Sample Days {{ workspace_conversation.stability_sample_days }}</a>
|
||||
<a class="tag is-light" href="{% url 'ai_workspace_insight_detail' type='page' person_id=person.id metric='stability_computed' %}">Stability Computed {{ workspace_conversation.stability_last_computed_at|default:"-" }}</a>
|
||||
<a class="tag is-light" href="{% url 'ai_workspace_insight_detail' type='page' person_id=person.id metric='commitment_inbound' %}">Commit In {{ workspace_conversation.commitment_inbound_score|default:"-" }}</a>
|
||||
<a class="tag is-light" href="{% url 'ai_workspace_insight_detail' type='page' person_id=person.id metric='commitment_outbound' %}">Commit Out {{ workspace_conversation.commitment_outbound_score|default:"-" }}</a>
|
||||
<a class="tag is-light" href="{% url 'ai_workspace_insight_detail' type='page' person_id=person.id metric='commitment_confidence' %}">Commit Confidence {{ workspace_conversation.commitment_confidence }}</a>
|
||||
<a class="tag is-light" href="{% url 'ai_workspace_insight_detail' type='page' person_id=person.id metric='commitment_computed' %}">Commitment Computed {{ workspace_conversation.commitment_last_computed_at|default:"-" }}</a>
|
||||
<a class="tag is-light" href="{% url 'ai_workspace_insight_detail' type='page' person_id=person.id metric='last_event' %}">Last Event {{ workspace_conversation.last_event_ts|default:"-" }}</a>
|
||||
<a class="tag is-light" href="{% url 'ai_workspace_insight_detail' type='page' person_id=person.id metric='last_ai_run' %}">Last AI Run {{ workspace_conversation.last_ai_run_at|default:"-" }}</a>
|
||||
</div>
|
||||
<p class="is-size-7 has-text-grey" style="margin-top: 0.35rem; margin-bottom: 0;">
|
||||
Open MS / PS graphs, information, and help from the controls below.
|
||||
</p>
|
||||
<div class="buttons are-small" style="margin-top: 0.35rem; margin-bottom: 0;">
|
||||
<a class="button is-light" href="{% url 'ai_workspace_insight_graphs' type='page' person_id=person.id %}">
|
||||
<span class="icon is-small"><i class="fa-solid fa-chart-line"></i></span>
|
||||
<span>Insight Graphs</span>
|
||||
</a>
|
||||
{% include "partials/behavioral-graph-launcher.html" with button_label="Graphs" show_widget_actions=behavioral_show_widget_actions default_widget_url=behavioral_graphs_widget_url default_page_url=behavioral_graphs_page_url graph_groups=behavioral_graph_groups %}
|
||||
<a class="button is-light" href="{% url 'ai_workspace_information' type='page' person_id=person.id %}">
|
||||
<span class="icon is-small"><i class="fa-solid fa-circle-info"></i></span>
|
||||
<span>Information</span>
|
||||
<span>MS / PS</span>
|
||||
</a>
|
||||
<a class="button is-light" href="{% url 'ai_workspace_insight_help' type='page' person_id=person.id %}">
|
||||
<span class="icon is-small"><i class="fa-solid fa-circle-question"></i></span>
|
||||
<span>Scoring Help</span>
|
||||
<span>Help</span>
|
||||
</a>
|
||||
</div>
|
||||
{% with participants=workspace_conversation.participants.all %}
|
||||
@@ -81,6 +64,7 @@
|
||||
id="ai-manual-widget-btn-{{ person.id }}"
|
||||
type="button"
|
||||
class="button is-light is-small js-widget-spawn-trigger is-hidden"
|
||||
data-gia-widget-id="{{ compose_widget_id }}"
|
||||
data-widget-url="{{ compose_widget_url }}"
|
||||
hx-headers='{"X-CSRFToken": "{{ csrf_token }}"}'
|
||||
hx-get="{{ compose_widget_url }}"
|
||||
|
||||
71
core/templates/partials/behavioral-graph-card.html
Normal file
71
core/templates/partials/behavioral-graph-card.html
Normal file
@@ -0,0 +1,71 @@
|
||||
<article class="card gia-behavior-graph-card">
|
||||
<header class="card-header">
|
||||
<div class="card-header-title is-flex is-justify-content-space-between is-align-items-flex-start">
|
||||
<div>
|
||||
<p class="is-size-7 has-text-weight-semibold has-text-grey mb-1">
|
||||
{{ graph.state_label }} · {{ graph.group|upper }}
|
||||
</p>
|
||||
<p class="mb-0">
|
||||
<span class="icon is-small mr-1"><i class="{{ graph.icon }}"></i></span>
|
||||
<span>{{ graph.title }}</span>
|
||||
</p>
|
||||
</div>
|
||||
<span class="tag is-light gia-badge">{{ graph.current_value_label }}</span>
|
||||
</div>
|
||||
</header>
|
||||
<div class="card-content">
|
||||
<p class="is-size-7 has-text-grey mb-2">
|
||||
{{ graph.raw_count }} sample{{ graph.raw_count|pluralize }} in this range{% if graph.delta_label %} · {{ graph.delta_label }}{% endif %}
|
||||
</p>
|
||||
{% if graph.has_data %}
|
||||
<div class="gia-behavior-chart-shell">
|
||||
<svg
|
||||
class="gia-behavior-chart"
|
||||
viewBox="0 0 100 48"
|
||||
preserveAspectRatio="none"
|
||||
role="img"
|
||||
aria-label="{{ graph.title }} graph">
|
||||
{% if graph.area_path %}
|
||||
<path class="gia-behavior-chart-area" d="{{ graph.area_path }}"></path>
|
||||
{% endif %}
|
||||
{% if graph.polyline %}
|
||||
<polyline class="gia-behavior-chart-line" points="{{ graph.polyline }}"></polyline>
|
||||
{% endif %}
|
||||
{% for marker in graph.markers|slice:"-1:" %}
|
||||
<circle class="gia-behavior-chart-point" cx="{{ marker.x }}" cy="{{ marker.y }}" r="1.8"></circle>
|
||||
{% endfor %}
|
||||
</svg>
|
||||
<div class="is-flex is-justify-content-space-between is-size-7 has-text-grey mt-1">
|
||||
<span>{{ graph.y_min_label }}</span>
|
||||
<span>{{ graph.latest_bucket_label }}</span>
|
||||
<span>{{ graph.y_max_label }}</span>
|
||||
</div>
|
||||
</div>
|
||||
{% else %}
|
||||
<article class="message is-light">
|
||||
<div class="message-body is-size-7">
|
||||
No samples for this metric in the selected range.
|
||||
</div>
|
||||
</article>
|
||||
{% endif %}
|
||||
<p class="is-size-7 mt-3">{{ graph.psychology }}</p>
|
||||
<div class="buttons are-small mt-3 mb-0">
|
||||
<a
|
||||
class="button is-light"
|
||||
href="{% url 'ai_workspace_insight_detail' type='page' person_id=person.id metric=graph.slug %}?range={{ range_key }}">
|
||||
Page
|
||||
</a>
|
||||
{% if behavioral_show_widget_actions %}
|
||||
<button
|
||||
type="button"
|
||||
class="button is-light js-widget-spawn-trigger"
|
||||
data-widget-url="{% url 'ai_workspace_insight_detail' type='widget' person_id=person.id metric=graph.slug %}?range={{ range_key }}"
|
||||
hx-get="{% url 'ai_workspace_insight_detail' type='widget' person_id=person.id metric=graph.slug %}?range={{ range_key }}"
|
||||
hx-target="#widgets-here"
|
||||
hx-swap="beforeend">
|
||||
Widget
|
||||
</button>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
</article>
|
||||
71
core/templates/partials/behavioral-graph-launcher.html
Normal file
71
core/templates/partials/behavioral-graph-launcher.html
Normal file
@@ -0,0 +1,71 @@
|
||||
<div class="dropdown is-right gia-split-dropdown" data-gia-dropdown>
|
||||
<div class="dropdown-trigger">
|
||||
<div class="buttons has-addons are-small mb-0">
|
||||
{% if show_widget_actions %}
|
||||
<button
|
||||
type="button"
|
||||
class="button is-light js-widget-spawn-trigger"
|
||||
data-widget-url="{{ default_widget_url }}"
|
||||
hx-get="{{ default_widget_url }}"
|
||||
hx-target="#widgets-here"
|
||||
hx-swap="beforeend">
|
||||
<span class="icon is-small"><i class="fa-solid fa-chart-line"></i></span>
|
||||
<span>{{ button_label|default:"Graphs" }}</span>
|
||||
</button>
|
||||
{% else %}
|
||||
<a class="button is-light" href="{{ default_page_url }}">
|
||||
<span class="icon is-small"><i class="fa-solid fa-chart-line"></i></span>
|
||||
<span>{{ button_label|default:"Graphs" }}</span>
|
||||
</a>
|
||||
{% endif %}
|
||||
<button
|
||||
type="button"
|
||||
class="button is-light js-gia-dropdown-toggle"
|
||||
aria-haspopup="true"
|
||||
aria-expanded="false">
|
||||
<span class="icon is-small"><i class="fa-solid fa-angle-down"></i></span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="dropdown-menu" role="menu">
|
||||
<div class="dropdown-content">
|
||||
<a class="dropdown-item" href="{{ default_page_url }}">
|
||||
<span class="icon is-small"><i class="fa-solid fa-up-right-from-square"></i></span>
|
||||
<span>Page</span>
|
||||
</a>
|
||||
<hr class="dropdown-divider">
|
||||
<details class="gia-dropdown-nest">
|
||||
<summary class="dropdown-item">
|
||||
<span class="icon is-small"><i class="fa-solid fa-sliders"></i></span>
|
||||
<span>Custom Graph</span>
|
||||
</summary>
|
||||
<div class="gia-dropdown-nest-body">
|
||||
{% for group in graph_groups %}
|
||||
<p class="dropdown-item has-text-weight-semibold is-size-7 has-text-grey">
|
||||
{{ group.title }}
|
||||
</p>
|
||||
{% for item in group.items %}
|
||||
{% if show_widget_actions %}
|
||||
<button
|
||||
type="button"
|
||||
class="dropdown-item js-widget-spawn-trigger"
|
||||
data-widget-url="{{ item.widget_url }}"
|
||||
hx-get="{{ item.widget_url }}"
|
||||
hx-target="#widgets-here"
|
||||
hx-swap="beforeend">
|
||||
<span class="icon is-small"><i class="{{ item.icon }}"></i></span>
|
||||
<span>{{ item.title }}</span>
|
||||
</button>
|
||||
{% else %}
|
||||
<a class="dropdown-item" href="{{ item.page_url }}">
|
||||
<span class="icon is-small"><i class="{{ item.icon }}"></i></span>
|
||||
<span>{{ item.title }}</span>
|
||||
</a>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
{% endfor %}
|
||||
</div>
|
||||
</details>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
56
core/templates/partials/behavioral-range-tabs.html
Normal file
56
core/templates/partials/behavioral-range-tabs.html
Normal file
@@ -0,0 +1,56 @@
|
||||
<div class="tabs is-toggle is-small gia-inline-tabs">
|
||||
<ul>
|
||||
<li{% if range_key == "30d" %} class="is-active"{% endif %}>
|
||||
{% if behavioral_show_widget_actions %}
|
||||
<a
|
||||
class="button is-white is-small js-widget-spawn-trigger"
|
||||
href="{{ behavioral_range_urls.30d }}"
|
||||
data-widget-url="{{ behavioral_range_urls.30d }}"
|
||||
hx-get="{{ behavioral_range_urls.30d }}"
|
||||
hx-target="#widgets-here"
|
||||
hx-swap="beforeend">30d</a>
|
||||
{% else %}
|
||||
<a href="{{ behavioral_range_urls.30d }}">30d</a>
|
||||
{% endif %}
|
||||
</li>
|
||||
<li{% if range_key == "90d" %} class="is-active"{% endif %}>
|
||||
{% if behavioral_show_widget_actions %}
|
||||
<a
|
||||
class="button is-white is-small js-widget-spawn-trigger"
|
||||
href="{{ behavioral_range_urls.90d }}"
|
||||
data-widget-url="{{ behavioral_range_urls.90d }}"
|
||||
hx-get="{{ behavioral_range_urls.90d }}"
|
||||
hx-target="#widgets-here"
|
||||
hx-swap="beforeend">90d</a>
|
||||
{% else %}
|
||||
<a href="{{ behavioral_range_urls.90d }}">90d</a>
|
||||
{% endif %}
|
||||
</li>
|
||||
<li{% if range_key == "365d" %} class="is-active"{% endif %}>
|
||||
{% if behavioral_show_widget_actions %}
|
||||
<a
|
||||
class="button is-white is-small js-widget-spawn-trigger"
|
||||
href="{{ behavioral_range_urls.365d }}"
|
||||
data-widget-url="{{ behavioral_range_urls.365d }}"
|
||||
hx-get="{{ behavioral_range_urls.365d }}"
|
||||
hx-target="#widgets-here"
|
||||
hx-swap="beforeend">1y</a>
|
||||
{% else %}
|
||||
<a href="{{ behavioral_range_urls.365d }}">1y</a>
|
||||
{% endif %}
|
||||
</li>
|
||||
<li{% if range_key == "all" %} class="is-active"{% endif %}>
|
||||
{% if behavioral_show_widget_actions %}
|
||||
<a
|
||||
class="button is-white is-small js-widget-spawn-trigger"
|
||||
href="{{ behavioral_range_urls.all }}"
|
||||
data-widget-url="{{ behavioral_range_urls.all }}"
|
||||
hx-get="{{ behavioral_range_urls.all }}"
|
||||
hx-target="#widgets-here"
|
||||
hx-swap="beforeend">All</a>
|
||||
{% else %}
|
||||
<a href="{{ behavioral_range_urls.all }}">All</a>
|
||||
{% endif %}
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
18
core/templates/partials/behavioral-summary-card.html
Normal file
18
core/templates/partials/behavioral-summary-card.html
Normal file
@@ -0,0 +1,18 @@
|
||||
<article class="message is-light gia-behavior-summary-card">
|
||||
<div class="message-body">
|
||||
<p class="is-size-7 has-text-weight-semibold has-text-grey mb-1">
|
||||
{{ card.state_label }} · {{ card.group|upper }}
|
||||
</p>
|
||||
<div class="is-flex is-align-items-center is-justify-content-space-between mb-2">
|
||||
<p class="title is-6 mb-0">
|
||||
<span class="icon is-small mr-1"><i class="{{ card.icon }}"></i></span>
|
||||
<span>{{ card.title }}</span>
|
||||
</p>
|
||||
<span class="tag is-light gia-badge">{{ card.current_value_label }}</span>
|
||||
</div>
|
||||
<p class="is-size-7 mb-1">{{ card.calculation }}</p>
|
||||
{% if card.delta_label %}
|
||||
<p class="is-size-7 has-text-grey">Latest shift: {{ card.delta_label }}</p>
|
||||
{% endif %}
|
||||
</div>
|
||||
</article>
|
||||
@@ -1,5 +1,5 @@
|
||||
<div class="box is-shadowless gia-send-composer p-2 m-0{% if composer_class %} {{ composer_class }}{% endif %}">
|
||||
<div class="field has-addons gia-send-composer-row">
|
||||
<div class="gia-send-composer m-0{% if composer_class %} {{ composer_class }}{% endif %}">
|
||||
<div class="field has-addons gia-send-composer-row mb-0">
|
||||
<div class="control is-expanded gia-send-composer-input-wrap">
|
||||
<textarea
|
||||
id="{{ textarea_id }}"
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
<div class="compose-row {% if msg.outgoing %}is-out{% else %}is-in{% endif %}{% if msg.is_deleted %} is-deleted{% endif %}" data-ts="{{ msg.ts }}" data-message-id="{{ msg.id }}"{% if msg.reply_to_id %} data-reply-to-id="{{ msg.reply_to_id }}"{% endif %} data-reply-snippet="{{ msg.display_text|default:msg.text|default:''|truncatechars:120|escape }}">
|
||||
<article class="compose-bubble {% if msg.outgoing %}is-out{% else %}is-in{% endif %}">
|
||||
<article
|
||||
class="compose-bubble {% if msg.outgoing %}is-out{% else %}is-in{% endif %}"
|
||||
title="Source: {{ msg.source_label }}{% if msg.author %} · {{ msg.author }}{% endif %}">
|
||||
{% if msg.reply_to_id %}
|
||||
<div class="compose-reply-ref" data-reply-target-id="{{ msg.reply_to_id }}">
|
||||
<button type="button" class="compose-reply-link" title="Jump to referenced message">
|
||||
@@ -7,9 +9,6 @@
|
||||
</button>
|
||||
</div>
|
||||
{% endif %}
|
||||
<div class="compose-source-badge-wrap">
|
||||
<span class="tag is-light gia-badge compose-source-badge source-{{ msg.source_service|default:'web'|lower }}">{{ msg.source_label }}</span>
|
||||
</div>
|
||||
{% if msg.image_urls %}
|
||||
{% for image_url in msg.image_urls %}
|
||||
<figure class="compose-media">
|
||||
@@ -34,9 +33,9 @@
|
||||
</figure>
|
||||
{% endif %}
|
||||
{% if not msg.hide_text %}
|
||||
<p class="compose-body">{{ msg.display_text|default:"(no text)" }}</p>
|
||||
<p class="compose-body is-size-7">{{ msg.display_text|default:"(no text)" }}</p>
|
||||
{% else %}
|
||||
<p class="compose-body compose-image-fallback is-hidden">(no text)</p>
|
||||
<p class="compose-body compose-image-fallback is-hidden is-size-7">(no text)</p>
|
||||
{% endif %}
|
||||
{% if msg.edit_count %}
|
||||
<details class="compose-edit-history">
|
||||
@@ -71,7 +70,7 @@
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% endif %}
|
||||
<p class="compose-msg-meta">
|
||||
<p class="compose-msg-meta is-size-7" title="Source: {{ msg.source_label }}">
|
||||
{{ msg.display_ts }}{% if msg.author %} · {{ msg.author }}{% endif %}
|
||||
{% if msg.is_edited %}
|
||||
<span class="tag is-light gia-badge compose-msg-flag is-edited" title="Message edited{% if msg.last_edit_display %} at {{ msg.last_edit_display }}{% endif %}">edited</span>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{% load static %}
|
||||
<link rel="stylesheet" href="{% static 'css/compose-panel.css' %}">
|
||||
<script defer src="{% static 'js/compose-panel-core.js' %}"></script>
|
||||
<script defer src="{% static 'js/compose-panel-thread.js' %}"></script>
|
||||
<script defer src="{% static 'js/compose-panel-send.js' %}"></script>
|
||||
<script defer src="{% static 'js/compose-panel.js' %}"></script>
|
||||
<link rel="stylesheet" href="{% static 'css/compose-panel.css' %}?v={{ compose_asset_version|default:'20260313b' }}">
|
||||
<script defer src="{% static 'js/compose-panel-core.js' %}?v={{ compose_asset_version|default:'20260313b' }}"></script>
|
||||
<script defer src="{% static 'js/compose-panel-thread.js' %}?v={{ compose_asset_version|default:'20260313b' }}"></script>
|
||||
<script defer src="{% static 'js/compose-panel-send.js' %}?v={{ compose_asset_version|default:'20260313b' }}"></script>
|
||||
<script defer src="{% static 'js/compose-panel.js' %}?v={{ compose_asset_version|default:'20260313b' }}"></script>
|
||||
|
||||
@@ -66,6 +66,9 @@
|
||||
{{ service|title }} · {{ identifier }}
|
||||
</p>
|
||||
</div>
|
||||
{% if behavioral_graphs_page_url %}
|
||||
{% include "partials/behavioral-graph-launcher.html" with button_label="Graphs" show_widget_actions=behavioral_show_widget_actions default_widget_url=behavioral_graphs_widget_url default_page_url=behavioral_graphs_page_url graph_groups=behavioral_graph_groups %}
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
{% if signal_ingest_warning %}
|
||||
@@ -90,6 +93,9 @@
|
||||
data-limit="{{ limit }}"
|
||||
data-last-ts="{{ last_ts }}"
|
||||
data-ws-url="{{ compose_ws_url }}">
|
||||
<p id="{{ panel_id }}-history-loader" class="compose-history-loader is-size-7 has-text-grey mb-2">
|
||||
Scroll up to load older messages.
|
||||
</p>
|
||||
{% include "partials/compose-message-rows.html" with message_rows=serialized_messages show_empty_state=True empty_message="No stored messages for this contact yet." %}
|
||||
</div>
|
||||
<p id="{{ panel_id }}-typing" class="compose-typing is-hidden">
|
||||
@@ -128,7 +134,7 @@
|
||||
<p class="help is-size-7 has-text-grey">Send disabled: {{ capability_send_reason }}</p>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% include "partials/bulma-send-composer.html" with composer_class="compose-composer-capsule" textarea_id=panel_id|add:"-textarea" textarea_class="compose-textarea" textarea_name="text" textarea_rows="1" textarea_placeholder="Type a message. Enter to send, Shift+Enter for newline." button_class="is-link is-light compose-send-btn" button_type="submit" button_disabled=True button_title=capability_send_reason|default_if_none:"" button_label="Send" button_icon_class=manual_icon_class %}
|
||||
{% include "partials/bulma-send-composer.html" with composer_class="compose-composer-capsule" textarea_id=panel_id|add:"-textarea" textarea_class="is-small compose-textarea" textarea_name="text" textarea_rows="1" textarea_placeholder="Type a message. Enter to send, Shift+Enter for newline." button_class="is-link is-light is-small compose-send-btn" button_type="submit" button_disabled=True button_title=capability_send_reason|default_if_none:"" button_label="Send" button_icon_class=manual_icon_class %}
|
||||
</div>
|
||||
<div id="{{ panel_id }}-reply-banner" class="compose-reply-banner is-hidden">
|
||||
<span class="compose-reply-banner-label">Replying to:</span>
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
{% for row in contact_rows %}
|
||||
<a
|
||||
class="panel-block"
|
||||
data-gia-widget-id="{{ row.compose_widget_id }}"
|
||||
hx-get="{{ row.compose_widget_url }}"
|
||||
hx-target="#widgets-here"
|
||||
hx-swap="beforeend">
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
<div class="buttons are-small m-0">
|
||||
<button
|
||||
class="button is-small is-link is-light"
|
||||
data-gia-widget-id="{{ row.compose_widget_id }}"
|
||||
hx-get="{{ row.compose_widget_url }}"
|
||||
hx-include="#{{ browser_form_id }}"
|
||||
hx-target="#widgets-here"
|
||||
|
||||
@@ -197,7 +197,7 @@
|
||||
hx-headers='{"X-CSRFToken": "{{ csrf_token }}"}'
|
||||
hx-get="{{ action.url }}"
|
||||
hx-target="{{ action.target }}"
|
||||
hx-swap="innerHTML"
|
||||
hx-swap="{{ action.swap|default:'innerHTML' }}"
|
||||
{% if action.target == "#windows-here" %}onclick="if (window.giaPrepareWindowAnchor) { window.giaPrepareWindowAnchor(this); }"{% endif %}
|
||||
title="{{ action.title }}">
|
||||
<span class="icon"><i class="{{ action.icon }}"></i></span>
|
||||
|
||||
@@ -109,6 +109,7 @@
|
||||
{% if item.can_compose %}
|
||||
<button
|
||||
hx-headers='{"X-CSRFToken": "{{ csrf_token }}"}'
|
||||
data-gia-widget-id="{{ item.compose_widget_id }}"
|
||||
hx-get="{{ item.compose_widget_url }}"
|
||||
hx-trigger="click"
|
||||
hx-target="#widgets-here"
|
||||
|
||||
@@ -43,6 +43,7 @@
|
||||
<button
|
||||
type="button"
|
||||
hx-headers='{"X-CSRFToken": "{{ csrf_token }}"}'
|
||||
data-gia-widget-id="{{ item.compose_widget_id }}"
|
||||
hx-get="{{ item.compose_widget_url }}"
|
||||
hx-trigger="click"
|
||||
hx-target="#widgets-here"
|
||||
|
||||
@@ -97,6 +97,7 @@
|
||||
<button
|
||||
type="button"
|
||||
hx-headers='{"X-CSRFToken": "{{ csrf_token }}"}'
|
||||
data-gia-widget-id="{{ item.compose_widget_id }}"
|
||||
hx-get="{{ item.compose_widget_url }}"
|
||||
hx-trigger="click"
|
||||
hx-target="#widgets-here"
|
||||
|
||||
Reference in New Issue
Block a user