Further improve detail display and work on inline latency display
This commit is contained in:
@@ -31,6 +31,10 @@
|
||||
<span class="icon is-small"><i class="fa-solid fa-chart-line"></i></span>
|
||||
<span>Insight Graphs</span>
|
||||
</a>
|
||||
<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>
|
||||
</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>
|
||||
@@ -38,19 +42,33 @@
|
||||
</div>
|
||||
{% with participants=workspace_conversation.participants.all %}
|
||||
{% if participants %}
|
||||
<p class="is-size-7" style="margin-top: 0.35rem; margin-bottom: 0;">
|
||||
Participants:
|
||||
{% for participant in participants %}
|
||||
{% if not forloop.first %}, {% endif %}
|
||||
{{ participant.name }}
|
||||
{% endfor %}
|
||||
</p>
|
||||
<div style="margin-top: 0.35rem;">
|
||||
<p class="is-size-7 has-text-weight-semibold" style="margin-bottom: 0.2rem;">Participants</p>
|
||||
<div class="tags">
|
||||
{% for participant in participants %}
|
||||
<span class="tag is-light">{{ participant.name }}</span>
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
{% endwith %}
|
||||
{% if workspace_conversation.participant_feedback %}
|
||||
<p class="is-size-7" style="margin-top: 0.35rem; margin-bottom: 0;">
|
||||
Participant Feedback: {{ workspace_conversation.participant_feedback }}
|
||||
</p>
|
||||
{% if participant_feedback_display %}
|
||||
<div style="margin-top: 0.25rem;">
|
||||
<p class="is-size-7 has-text-weight-semibold" style="margin-bottom: 0.2rem;">Participant Feedback</p>
|
||||
<div class="tags">
|
||||
<span class="tag is-light {{ participant_feedback_display.state_class }}">
|
||||
<span class="icon is-small"><i class="{{ participant_feedback_display.state_icon }}"></i></span>
|
||||
<span>{{ participant_feedback_display.state_label }}</span>
|
||||
</span>
|
||||
<span class="tag is-light">Inbound {{ participant_feedback_display.inbound_messages|default:"-" }}</span>
|
||||
<span class="tag is-light">Outbound {{ participant_feedback_display.outbound_messages|default:"-" }}</span>
|
||||
<span class="tag is-light">Sample Msg {{ participant_feedback_display.sample_messages|default:"-" }}</span>
|
||||
<span class="tag is-light">Sample Days {{ participant_feedback_display.sample_days|default:"-" }}</span>
|
||||
{% if participant_feedback_display.updated_at_label %}
|
||||
<span class="tag is-light">Updated {{ participant_feedback_display.updated_at_label }}</span>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
{% if compose_page_url %}
|
||||
<div class="buttons are-small" style="margin-top: 0.45rem; margin-bottom: 0;">
|
||||
@@ -96,17 +114,32 @@
|
||||
<div class="is-flex is-justify-content-space-between is-align-items-center" style="margin-bottom: 0.4rem;">
|
||||
<div class="tabs is-small is-toggle is-toggle-rounded" style="margin-bottom: 0;">
|
||||
<ul>
|
||||
<li id="ai-tab-{{ person.id }}-artifacts">
|
||||
<a onclick="giaWorkspaceRun('{{ person.id }}', 'artifacts', false); return false;">Plan</a>
|
||||
<li id="ai-tab-{{ person.id }}-plan_board" class="is-active">
|
||||
<a onclick="giaWorkspaceOpenTab('{{ person.id }}', 'plan_board', false); return false;">Plan</a>
|
||||
</li>
|
||||
<li id="ai-tab-{{ person.id }}-corrections">
|
||||
<a onclick="giaWorkspaceOpenTab('{{ person.id }}', 'corrections', false); return false;">Corrections</a>
|
||||
</li>
|
||||
<li id="ai-tab-{{ person.id }}-engage">
|
||||
<a onclick="giaWorkspaceOpenTab('{{ person.id }}', 'engage', false); return false;">Engage</a>
|
||||
</li>
|
||||
<li id="ai-tab-{{ person.id }}-fundamentals">
|
||||
<a onclick="giaWorkspaceOpenTab('{{ person.id }}', 'fundamentals', false); return false;">Fundamentals</a>
|
||||
</li>
|
||||
<li id="ai-tab-{{ person.id }}-auto">
|
||||
<a onclick="giaWorkspaceOpenTab('{{ person.id }}', 'auto', false); return false;">Auto</a>
|
||||
</li>
|
||||
<li id="ai-tab-{{ person.id }}-ask_ai">
|
||||
<a onclick="giaWorkspaceOpenTab('{{ person.id }}', 'ask_ai', false); return false;">Ask AI</a>
|
||||
</li>
|
||||
<li id="ai-tab-{{ person.id }}-summarise">
|
||||
<a onclick="giaWorkspaceRun('{{ person.id }}', 'summarise', false); return false;">Summary</a>
|
||||
<a onclick="giaWorkspaceOpenTab('{{ person.id }}', 'summarise', false); return false;">Summary</a>
|
||||
</li>
|
||||
<li id="ai-tab-{{ person.id }}-draft_reply" class="is-active">
|
||||
<a onclick="giaWorkspaceRun('{{ person.id }}', 'draft_reply', false); return false;">Draft</a>
|
||||
<li id="ai-tab-{{ person.id }}-draft_reply">
|
||||
<a onclick="giaWorkspaceOpenTab('{{ person.id }}', 'draft_reply', false); return false;">Draft</a>
|
||||
</li>
|
||||
<li id="ai-tab-{{ person.id }}-extract_patterns">
|
||||
<a onclick="giaWorkspaceRun('{{ person.id }}', 'extract_patterns', false); return false;">Patterns</a>
|
||||
<a onclick="giaWorkspaceOpenTab('{{ person.id }}', 'extract_patterns', false); return false;">Patterns</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
@@ -163,7 +196,8 @@
|
||||
// One-time migration flush to avoid stale cached pane HTML from earlier UI schema.
|
||||
localStorage.removeItem("gia_workspace_cache_v1");
|
||||
localStorage.removeItem("gia_workspace_cache_v2");
|
||||
return JSON.parse(localStorage.getItem("gia_workspace_cache_v3") || "{}");
|
||||
localStorage.removeItem("gia_workspace_cache_v3");
|
||||
return JSON.parse(localStorage.getItem("gia_workspace_cache_v4") || "{}");
|
||||
} catch (e) {
|
||||
return {};
|
||||
}
|
||||
@@ -171,7 +205,7 @@
|
||||
|
||||
function persistCache() {
|
||||
try {
|
||||
localStorage.setItem("gia_workspace_cache_v3", JSON.stringify(window.giaWorkspaceCache));
|
||||
localStorage.setItem("gia_workspace_cache_v4", JSON.stringify(window.giaWorkspaceCache));
|
||||
} catch (e) {
|
||||
// Ignore storage write issues.
|
||||
}
|
||||
@@ -282,6 +316,46 @@
|
||||
indicator.style.display = show ? "inline-flex" : "none";
|
||||
}
|
||||
|
||||
const OPERATION_TABS = ["summarise", "draft_reply", "extract_patterns"];
|
||||
const MITIGATION_TABS = ["plan_board", "corrections", "engage", "fundamentals", "auto", "ask_ai"];
|
||||
const ALL_TOP_TABS = MITIGATION_TABS.concat(OPERATION_TABS);
|
||||
|
||||
function isMitigationTab(tabKey) {
|
||||
return MITIGATION_TABS.indexOf(tabKey) !== -1;
|
||||
}
|
||||
|
||||
function operationForTab(tabKey) {
|
||||
return isMitigationTab(tabKey) ? "artifacts" : tabKey;
|
||||
}
|
||||
|
||||
function setTopCapsuleActive(tabKey) {
|
||||
ALL_TOP_TABS.forEach(function(name) {
|
||||
const tab = document.getElementById("ai-tab-" + personId + "-" + name);
|
||||
if (tab) {
|
||||
tab.classList.toggle("is-active", name === tabKey);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function showOperationPane(operation) {
|
||||
["artifacts", "summarise", "draft_reply", "extract_patterns"].forEach(function(op) {
|
||||
const pane = document.getElementById("ai-pane-" + personId + "-" + op);
|
||||
if (!pane) {
|
||||
return;
|
||||
}
|
||||
pane.style.display = op === operation ? "block" : "none";
|
||||
});
|
||||
}
|
||||
|
||||
function applyMitigationTabSelection() {
|
||||
const state = window.giaWorkspaceState[personId] || {};
|
||||
const targetTab = state.currentMitigationTab || "plan_board";
|
||||
setTopCapsuleActive(targetTab);
|
||||
if (typeof window.giaMitigationShowTab === "function") {
|
||||
window.giaMitigationShowTab(personId, targetTab);
|
||||
}
|
||||
}
|
||||
|
||||
function hydrateCachedIfAvailable(operation) {
|
||||
if (operation === "artifacts") {
|
||||
return false;
|
||||
@@ -303,29 +377,35 @@
|
||||
return false;
|
||||
}
|
||||
|
||||
window.giaWorkspaceShowTab = function(pid, operation) {
|
||||
window.giaWorkspaceShowTab = function(pid, operation, tabKey) {
|
||||
if (pid !== personId) {
|
||||
return;
|
||||
}
|
||||
["artifacts", "summarise", "draft_reply", "extract_patterns"].forEach(function(op) {
|
||||
const tab = document.getElementById("ai-tab-" + personId + "-" + op);
|
||||
const pane = document.getElementById("ai-pane-" + personId + "-" + op);
|
||||
if (!tab || !pane) {
|
||||
return;
|
||||
}
|
||||
if (op === operation) {
|
||||
tab.classList.add("is-active");
|
||||
pane.style.display = "block";
|
||||
} else {
|
||||
tab.classList.remove("is-active");
|
||||
pane.style.display = "none";
|
||||
}
|
||||
});
|
||||
showOperationPane(operation);
|
||||
const activeTab = tabKey || (
|
||||
operation === "artifacts"
|
||||
? ((window.giaWorkspaceState[personId] || {}).currentMitigationTab || "plan_board")
|
||||
: operation
|
||||
);
|
||||
setTopCapsuleActive(activeTab);
|
||||
const hydrated = hydrateCachedIfAvailable(operation);
|
||||
const entry = operation === "artifacts" ? null : getCacheEntry(operation);
|
||||
setCachedIndicator(hydrated || !!entry, entry ? entry.ts : null);
|
||||
window.giaWorkspaceState[personId] = window.giaWorkspaceState[personId] || {};
|
||||
window.giaWorkspaceState[personId].current = operation;
|
||||
window.giaWorkspaceState[personId].currentTab = activeTab;
|
||||
};
|
||||
|
||||
window.giaWorkspaceOpenTab = function(pid, tabKey, forceRefresh) {
|
||||
if (pid !== personId) {
|
||||
return;
|
||||
}
|
||||
window.giaWorkspaceState[personId] = window.giaWorkspaceState[personId] || {};
|
||||
if (isMitigationTab(tabKey)) {
|
||||
window.giaWorkspaceState[personId].currentMitigationTab = tabKey;
|
||||
}
|
||||
window.giaWorkspaceState[personId].pendingTabKey = tabKey;
|
||||
window.giaWorkspaceRun(personId, operationForTab(tabKey), !!forceRefresh);
|
||||
};
|
||||
|
||||
window.giaWorkspaceRun = function(pid, operation, forceRefresh) {
|
||||
@@ -339,11 +419,25 @@
|
||||
return;
|
||||
}
|
||||
const currentState = window.giaWorkspaceState[personId] || {};
|
||||
const targetTabKey = currentState.pendingTabKey || (
|
||||
operation === "artifacts"
|
||||
? (currentState.currentMitigationTab || "plan_board")
|
||||
: operation
|
||||
);
|
||||
if (!forceRefresh && currentState.current === operation && pane.dataset.loaded === "1") {
|
||||
window.giaWorkspaceShowTab(personId, operation);
|
||||
window.giaWorkspaceShowTab(personId, operation, targetTabKey);
|
||||
if (operation === "artifacts") {
|
||||
applyMitigationTabSelection();
|
||||
}
|
||||
if (window.giaWorkspaceState[personId]) {
|
||||
window.giaWorkspaceState[personId].pendingTabKey = "";
|
||||
}
|
||||
return;
|
||||
}
|
||||
window.giaWorkspaceShowTab(personId, operation);
|
||||
window.giaWorkspaceShowTab(personId, operation, targetTabKey);
|
||||
if (operation === "artifacts") {
|
||||
applyMitigationTabSelection();
|
||||
}
|
||||
|
||||
const key = cacheKey(operation);
|
||||
const entry = getCacheEntry(operation);
|
||||
@@ -360,6 +454,12 @@
|
||||
if (operation === "draft_reply" && typeof window.giaWorkspaceUseDraft === "function") {
|
||||
window.giaWorkspaceUseDraft(personId, operation, 0);
|
||||
}
|
||||
if (operation === "artifacts") {
|
||||
applyMitigationTabSelection();
|
||||
}
|
||||
if (window.giaWorkspaceState[personId]) {
|
||||
window.giaWorkspaceState[personId].pendingTabKey = "";
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -391,6 +491,12 @@
|
||||
if (operation === "draft_reply" && typeof window.giaWorkspaceUseDraft === "function") {
|
||||
window.giaWorkspaceUseDraft(personId, operation, 0);
|
||||
}
|
||||
if (operation === "artifacts") {
|
||||
applyMitigationTabSelection();
|
||||
}
|
||||
if (window.giaWorkspaceState[personId]) {
|
||||
window.giaWorkspaceState[personId].pendingTabKey = "";
|
||||
}
|
||||
})
|
||||
.catch(function() {
|
||||
pane.innerHTML = '<div class="notification is-danger is-light ai-animate-in">Failed to load AI response.</div>';
|
||||
@@ -401,8 +507,13 @@
|
||||
if (pid !== personId) {
|
||||
return;
|
||||
}
|
||||
const current = (window.giaWorkspaceState[personId] && window.giaWorkspaceState[personId].current) || "summarise";
|
||||
window.giaWorkspaceRun(personId, current, true);
|
||||
const state = window.giaWorkspaceState[personId] || {};
|
||||
const currentTab = state.currentTab || (
|
||||
state.current === "artifacts"
|
||||
? (state.currentMitigationTab || "plan_board")
|
||||
: (state.current || "plan_board")
|
||||
);
|
||||
window.giaWorkspaceOpenTab(personId, currentTab, true);
|
||||
};
|
||||
|
||||
window.giaWorkspaceUseDraft = function(pid, operation, index) {
|
||||
@@ -503,12 +614,14 @@
|
||||
names.forEach(function(name) {
|
||||
const pane = document.getElementById("mitigation-tab-" + pid + "-" + name);
|
||||
const tab = document.getElementById("mitigation-tab-btn-" + pid + "-" + name);
|
||||
if (!pane || !tab) {
|
||||
if (!pane) {
|
||||
return;
|
||||
}
|
||||
const active = (name === tabName);
|
||||
pane.style.display = active ? "block" : "none";
|
||||
tab.classList.toggle("is-active", active);
|
||||
if (tab) {
|
||||
tab.classList.toggle("is-active", active);
|
||||
}
|
||||
});
|
||||
const shell = document.getElementById("mitigation-shell-" + pid);
|
||||
if (!shell) {
|
||||
@@ -584,6 +697,6 @@
|
||||
};
|
||||
}
|
||||
|
||||
window.giaWorkspaceRun(personId, "artifacts", false);
|
||||
window.giaWorkspaceOpenTab(personId, "plan_board", false);
|
||||
})();
|
||||
</script>
|
||||
|
||||
Reference in New Issue
Block a user