Improve and condense related controls

This commit is contained in:
2026-02-15 22:11:17 +00:00
parent 02bcb559bc
commit 3d5fb29068
18 changed files with 1340 additions and 209 deletions

View File

@@ -8,49 +8,64 @@
{% endif %}
</div>
<div class="is-flex is-flex-direction-column mitigation-header-meta" style="gap: 0.35rem;">
<span class="tag is-light">{{ plan.creation_mode|title }} / {{ plan.status|title }}</span>
<span class="tag is-light">Created {{ plan.created_at }}</span>
<span class="tag is-light">Updated {{ plan.updated_at }}</span>
{% if plan.source_ai_result_id %}
<span class="tag is-light">Source Result {{ plan.source_ai_result_id }}</span>
{% endif %}
<form
class="box mitigation-artifact-card mitigation-editable-shell"
style="padding: 0.45rem; margin: 0; border: 1px solid rgba(0, 0, 0, 0.12); box-shadow: none;"
hx-headers='{"X-CSRFToken": "{{ csrf_token }}"}'
hx-post="{% url 'ai_workspace_mitigation_meta_save' type='widget' person_id=person.id plan_id=plan.id %}"
hx-target="#mitigation-shell-{{ person.id }}"
hx-swap="outerHTML">
<input type="hidden" name="active_tab" value="{{ active_tab|default:'plan_board' }}">
<div class="field" style="margin-bottom: 0.3rem;">
<div class="control">
<input class="input is-small" type="text" name="title" value="{{ plan.title }}" placeholder="Plan title">
<div class="mitigation-artifact-headline">
<p class="mitigation-artifact-title">Plan Details</p>
<div class="mitigation-artifact-actions">
<button
type="button"
class="button is-small is-link is-light is-rounded mitigation-edit-btn"
data-edit-state="view"
title="Edit plan details"
onclick="giaMitigationToggleEdit(this); return false;">
<span class="icon is-small"><i class="fa-solid fa-pen"></i></span>
</button>
</div>
</div>
<div class="field" style="margin-bottom: 0.3rem;">
<div class="control">
<textarea class="textarea is-small" rows="2" name="objective" placeholder="Plan objective">{{ plan.objective }}</textarea>
</div>
</div>
<div class="field is-grouped is-grouped-right" style="margin: 0; gap: 0.3rem;">
<div class="control">
<div class="select is-small">
<select name="creation_mode">
{% for value, label in plan_creation_mode_choices %}
<option value="{{ value }}" {% if plan.creation_mode == value %}selected{% endif %}>{{ label }}</option>
{% endfor %}
</select>
<p class="mitigation-artifact-meta">Created {{ plan.created_at }} · Updated {{ plan.updated_at }}</p>
<p class="mitigation-artifact-preview">
{{ plan.creation_mode|title }} / {{ plan.status|title }}
{% if plan.source_ai_result_id %}
· Source Result {{ plan.source_ai_result_id }}
{% endif %}
</p>
<div class="mitigation-edit-fields">
<div class="field" style="margin-bottom: 0.3rem;">
<div class="control">
<input class="input is-small" type="text" name="title" value="{{ plan.title }}" placeholder="Plan title" data-editable="1" readonly>
</div>
</div>
<div class="control">
<div class="select is-small">
<select name="status">
{% for value, label in plan_status_choices %}
<option value="{{ value }}" {% if plan.status == value %}selected{% endif %}>{{ label }}</option>
{% endfor %}
</select>
<div class="field" style="margin-bottom: 0.3rem;">
<div class="control">
<textarea class="textarea is-small" rows="2" name="objective" placeholder="Plan objective" data-editable="1" readonly>{{ plan.objective }}</textarea>
</div>
</div>
<div class="control">
<button type="submit" class="button is-small is-light">Save</button>
<div class="field is-grouped is-grouped-right" style="margin: 0; gap: 0.3rem;">
<div class="control">
<div class="select is-small">
<select name="creation_mode" data-editable-toggle="1" disabled>
{% for value, label in plan_creation_mode_choices %}
<option value="{{ value }}" {% if plan.creation_mode == value %}selected{% endif %}>{{ label }}</option>
{% endfor %}
</select>
</div>
</div>
<div class="control">
<div class="select is-small">
<select name="status" data-editable-toggle="1" disabled>
{% for value, label in plan_status_choices %}
<option value="{{ value }}" {% if plan.status == value %}selected{% endif %}>{{ label }}</option>
{% endfor %}
</select>
</div>
</div>
</div>
</div>
</form>
@@ -263,73 +278,88 @@
{% if corrections %}
{% for correction in corrections %}
<article class="box" style="padding: 0.55rem; margin-bottom: 0.5rem; border: 1px solid rgba(0, 0, 0, 0.12); box-shadow: none;">
<span class="tag is-light is-small" style="margin-bottom: 0.3rem;">Correction</span>
<span class="tag is-light is-small" style="margin-bottom: 0.3rem;">Created {{ correction.created_at }}</span>
<article class="box mitigation-artifact-card mitigation-editable-shell" style="padding: 0.45rem; margin-bottom: 0.35rem; border: 1px solid rgba(0, 0, 0, 0.12); box-shadow: none;">
<form
hx-headers='{"X-CSRFToken": "{{ csrf_token }}"}'
hx-post="{% url 'ai_workspace_mitigation_artifact_save' type='widget' person_id=person.id plan_id=plan.id kind='correction' artifact_id=correction.id %}"
hx-target="#mitigation-shell-{{ person.id }}"
hx-swap="outerHTML">
<div class="columns is-multiline" style="margin: 0 -0.3rem;">
<div class="column is-12" style="padding: 0.3rem;">
<input class="input is-small" type="text" name="title" value="{{ correction.title }}">
</div>
<div class="column is-12" style="padding: 0.3rem;">
<label class="label is-small" style="margin-bottom: 0.2rem;">Message Context</label>
<textarea class="textarea is-small" rows="2" name="source_phrase">{{ correction.source_phrase }}</textarea>
</div>
<div class="column is-12" style="padding: 0.3rem;">
<label class="label is-small" style="margin-bottom: 0.2rem;">Insight</label>
<textarea class="textarea is-small" rows="2" name="body">{{ correction.clarification }}</textarea>
</div>
<div class="column is-12-mobile is-4-tablet" style="padding: 0.3rem;">
<label class="label is-small" style="margin-bottom: 0.2rem;">Perspective</label>
<div class="select is-small is-fullwidth">
<select name="perspective">
{% for value, label in correction.PERSPECTIVE_CHOICES %}
<option value="{{ value }}" {% if correction.perspective == value %}selected{% endif %}>{{ label }}</option>
{% endfor %}
</select>
</div>
</div>
<div class="column is-12-mobile is-4-tablet" style="padding: 0.3rem;">
<label class="label is-small" style="margin-bottom: 0.2rem;">Share Target</label>
<div class="select is-small is-fullwidth">
<select name="share_target">
{% for value, label in correction.SHARE_TARGET_CHOICES %}
<option value="{{ value }}" {% if correction.share_target == value %}selected{% endif %}>{{ label }}</option>
{% endfor %}
</select>
</div>
</div>
<div class="column is-12-mobile is-4-tablet" style="padding: 0.3rem;">
<label class="label is-small" style="margin-bottom: 0.2rem;">Language Style</label>
<div class="select is-small is-fullwidth">
<select name="language_style">
{% for value, label in correction.LANGUAGE_STYLE_CHOICES %}
<option value="{{ value }}" {% if correction.language_style == value %}selected{% endif %}>{{ label }}</option>
{% endfor %}
</select>
</div>
<input type="hidden" name="active_tab" value="{{ active_tab|default:'corrections' }}">
<div class="mitigation-artifact-headline">
<p class="mitigation-artifact-title">{{ correction.title }}</p>
<div class="mitigation-artifact-actions">
<label class="checkbox is-size-7 mitigation-artifact-enabled">
<input type="checkbox" name="enabled" value="1" data-editable-toggle="1" disabled {% if correction.enabled %}checked{% endif %}>
On
</label>
<button
type="button"
class="button is-small is-link is-light is-rounded mitigation-edit-btn"
data-edit-state="view"
title="Edit correction"
onclick="giaMitigationToggleEdit(this); return false;">
<span class="icon is-small"><i class="fa-solid fa-pen"></i></span>
</button>
<button
type="button"
class="button is-small is-danger is-light is-rounded"
title="Delete correction"
hx-headers='{"X-CSRFToken": "{{ csrf_token }}"}'
hx-post="{% url 'ai_workspace_mitigation_artifact_delete' type='widget' person_id=person.id plan_id=plan.id kind='correction' artifact_id=correction.id %}"
hx-vals='{"active_tab":"corrections"}'
hx-confirm="Delete this correction?"
hx-target="#mitigation-shell-{{ person.id }}"
hx-swap="outerHTML">
<span class="icon is-small"><i class="fa-solid fa-trash"></i></span>
</button>
</div>
</div>
<label class="checkbox is-size-7" style="margin-bottom: 0.35rem;">
<input type="checkbox" name="enabled" value="1" {% if correction.enabled %}checked{% endif %}>
Enabled
</label>
<input type="hidden" name="active_tab" value="{{ active_tab|default:'corrections' }}">
<div class="buttons are-small" style="margin: 0;">
<button class="button is-small is-link is-light">Save Correction</button>
<button
type="button"
class="button is-small is-danger is-light"
hx-headers='{"X-CSRFToken": "{{ csrf_token }}"}'
hx-post="{% url 'ai_workspace_mitigation_artifact_delete' type='widget' person_id=person.id plan_id=plan.id kind='correction' artifact_id=correction.id %}"
hx-vals='{"active_tab":"corrections"}'
hx-confirm="Delete this correction?"
hx-target="#mitigation-shell-{{ person.id }}"
hx-swap="outerHTML">Delete</button>
<p class="mitigation-artifact-meta">Created {{ correction.created_at }}</p>
<p class="mitigation-artifact-preview">{{ correction.clarification }}</p>
<div class="mitigation-edit-fields">
<div class="field" style="margin-bottom: 0.3rem;">
<input class="input is-small" type="text" name="title" value="{{ correction.title }}" data-editable="1" readonly>
</div>
<div class="field" style="margin-bottom: 0.3rem;">
<label class="label is-small" style="margin-bottom: 0.2rem;">Message Context</label>
<textarea class="textarea is-small" rows="2" name="source_phrase" data-editable="1" readonly>{{ correction.source_phrase }}</textarea>
</div>
<div class="field" style="margin-bottom: 0.3rem;">
<label class="label is-small" style="margin-bottom: 0.2rem;">Insight</label>
<textarea class="textarea is-small" rows="2" name="body" data-editable="1" readonly>{{ correction.clarification }}</textarea>
</div>
<div class="columns is-multiline" style="margin: 0 -0.3rem;">
<div class="column is-12-mobile is-4-tablet" style="padding: 0.3rem;">
<label class="label is-small" style="margin-bottom: 0.2rem;">Perspective</label>
<div class="select is-small is-fullwidth">
<select name="perspective" data-editable-toggle="1" disabled>
{% for value, label in correction.PERSPECTIVE_CHOICES %}
<option value="{{ value }}" {% if correction.perspective == value %}selected{% endif %}>{{ label }}</option>
{% endfor %}
</select>
</div>
</div>
<div class="column is-12-mobile is-4-tablet" style="padding: 0.3rem;">
<label class="label is-small" style="margin-bottom: 0.2rem;">Share Target</label>
<div class="select is-small is-fullwidth">
<select name="share_target" data-editable-toggle="1" disabled>
{% for value, label in correction.SHARE_TARGET_CHOICES %}
<option value="{{ value }}" {% if correction.share_target == value %}selected{% endif %}>{{ label }}</option>
{% endfor %}
</select>
</div>
</div>
<div class="column is-12-mobile is-4-tablet" style="padding: 0.3rem;">
<label class="label is-small" style="margin-bottom: 0.2rem;">Language Style</label>
<div class="select is-small is-fullwidth">
<select name="language_style" data-editable-toggle="1" disabled>
{% for value, label in correction.LANGUAGE_STYLE_CHOICES %}
<option value="{{ value }}" {% if correction.language_style == value %}selected{% endif %}>{{ label }}</option>
{% endfor %}
</select>
</div>
</div>
</div>
</div>
</form>
</article>
@@ -511,18 +541,33 @@
<div class="columns is-multiline" style="margin: 0 -0.3rem;">
<div class="column is-12-mobile is-6-tablet" style="padding: 0.3rem;">
<label class="checkbox is-size-7"><input type="checkbox" name="enabled" value="1" {% if auto_settings.enabled %}checked{% endif %}> Enable auto checks for this Conversation</label>
<p class="is-size-7 has-text-grey" style="margin-top: 0.2rem; margin-bottom: 0;">
Master gate. When off, automatic checks return early and no auto plan, correction, or notification actions run for this conversation.
</p>
</div>
<div class="column is-12-mobile is-6-tablet" style="padding: 0.3rem;">
<label class="checkbox is-size-7"><input type="checkbox" name="auto_pattern_recognition" value="1" {% if auto_settings.auto_pattern_recognition %}checked{% endif %}> Detect pattern signals from Message rows</label>
<p class="is-size-7 has-text-grey" style="margin-top: 0.2rem; margin-bottom: 0;">
Controls background trigger behavior only. If disabled, auto-triggered scans are skipped; manual "Run Check Now" can still run.
</p>
</div>
<div class="column is-12-mobile is-6-tablet" style="padding: 0.3rem;">
<label class="checkbox is-size-7"><input type="checkbox" name="auto_create_mitigation" value="1" {% if auto_settings.auto_create_mitigation %}checked{% endif %}> Create a Plan when the Conversation has none</label>
<p class="is-size-7 has-text-grey" style="margin-top: 0.2rem; margin-bottom: 0;">
On AI pane load, if no plan exists and automation is enabled, a baseline plan is auto-created from recent messages.
</p>
</div>
<div class="column is-12-mobile is-6-tablet" style="padding: 0.3rem;">
<label class="checkbox is-size-7"><input type="checkbox" name="auto_create_corrections" value="1" {% if auto_settings.auto_create_corrections %}checked{% endif %}> Create Correction rows linked to the Plan</label>
<p class="is-size-7 has-text-grey" style="margin-top: 0.2rem; margin-bottom: 0;">
Writes up to 8 detected correction candidates per run, deduplicated by title + clarification, and links them to this plan.
</p>
</div>
<div class="column is-12-mobile is-6-tablet" style="padding: 0.3rem;">
<label class="checkbox is-size-7"><input type="checkbox" name="auto_notify_enabled" value="1" {% if auto_settings.auto_notify_enabled %}checked{% endif %}> Notify when auto writes new Correction rows</label>
<p class="is-size-7 has-text-grey" style="margin-top: 0.2rem; margin-bottom: 0;">
Sends a notification when violations are found (with count + top preview), using NTFY overrides if provided, otherwise default notifications.
</p>
</div>
<div class="column is-12-mobile is-6-tablet" style="padding: 0.3rem;">
<label class="label is-small" style="margin-bottom: 0.25rem;">Message rows per check</label>