Refactor case inline editing and search widget for improved functionality and layout

This commit is contained in:
Ross
2026-03-02 12:31:06 +00:00
parent 4c1e0c3d2a
commit b1ec4b173e
4 changed files with 56 additions and 39 deletions
+12 -14
View File
@@ -97,10 +97,10 @@
<h2 class="d-flex align-items-center" style="gap: .5rem; white-space: nowrap;"> <h2 class="d-flex align-items-center" style="gap: .5rem; white-space: nowrap;">
<span>Case:</span> <span>Case:</span>
<div class="d-flex align-items-center quick-edit-wrap"> <div class="d-flex align-items-center quick-edit-wrap">
<span id="case-inline-title" {% url 'atlas:case_inline_field' case.pk 'title' as title_url %}
hx-get="{% url 'atlas:case_inline_field' case.pk 'title' %}?show_label=0" {% with endpoint_default=title_url|add:"?show_label=0" endpoint_edit=title_url|add:"?edit=1&show_label=0" %}
hx-trigger="load" {% include 'atlas/partials/case_inline_field.html' with show_label=0 editing=False field_label="Title" can_edit=can_edit endpoint_url_default=endpoint_default endpoint_url_edit=endpoint_edit container_id='case-inline-title' field_kind='text' value=case.title display_value=case.title field_name='title' error_message='' %}
hx-swap="innerHTML">{{ case.title }}</span> {% endwith %}
{% if can_edit %} {% if can_edit %}
<button class="btn btn-sm btn-link text-muted p-0 ms-2 quick-edit-button" <button class="btn btn-sm btn-link text-muted p-0 ms-2 quick-edit-button"
hx-get="{% url 'atlas:case_inline_field' case.pk 'title' %}?edit=1&show_label=0" hx-get="{% url 'atlas:case_inline_field' case.pk 'title' %}?edit=1&show_label=0"
@@ -236,12 +236,10 @@
hx-target="#case-inline-diagnostic_certainty" hx-target="#case-inline-diagnostic_certainty"
hx-swap="innerHTML">quick edit</button> hx-swap="innerHTML">quick edit</button>
{% endif %} {% endif %}
<div id="case-inline-diagnostic_certainty" class="ms-2" {% url 'atlas:case_inline_field' case.pk 'diagnostic_certainty' as diag_url %}
hx-get="{% url 'atlas:case_inline_field' case.pk 'diagnostic_certainty' %}?show_label=0" {% with endpoint_default=diag_url|add:"?show_label=0" endpoint_edit=diag_url|add:"?edit=1&show_label=0" %}
hx-trigger="load" {% include 'atlas/partials/case_inline_field.html' with show_label=0 editing=False field_label="Diagnostic certainty" can_edit=can_edit endpoint_url_default=endpoint_default endpoint_url_edit=endpoint_edit container_id='case-inline-diagnostic_certainty' field_kind='select' value=case.get_diagnostic_certainty_display display_value=case.get_diagnostic_certainty_display field_name='diagnostic_certainty' error_message='' %}
hx-swap="innerHTML"> {% endwith %}
<span class="badge bg-info text-dark">{{ case.get_diagnostic_certainty_display }}</span>
</div>
</div> </div>
{# Normal toggle HTMX block #} {# Normal toggle HTMX block #}
<div class="mt-1"> <div class="mt-1">
@@ -263,10 +261,10 @@
<div class="d-flex align-items-start justify-content-between quick-edit-wrap"> <div class="d-flex align-items-start justify-content-between quick-edit-wrap">
<div class="d-flex align-items-start flex-grow-1"> <div class="d-flex align-items-start flex-grow-1">
<strong>Description:</strong> <strong>Description:</strong>
<div id="case-inline-description" class="ms-2 flex-grow-1" {% url 'atlas:case_inline_field' case.pk 'description' as desc_url %}
hx-get="{% url 'atlas:case_inline_field' case.pk 'description' %}?show_label=0" {% with endpoint_default=desc_url|add:"?show_label=0" endpoint_edit=desc_url|add:"?edit=1&show_label=0" %}
hx-trigger="load" {% include 'atlas/partials/case_inline_field.html' with show_label=0 editing=False field_label="Description" can_edit=can_edit endpoint_url_default=endpoint_default endpoint_url_edit=endpoint_edit container_id='case-inline-description' field_kind='textarea' value=case.description display_value=case.description field_name='description' error_message='' %}
hx-swap="innerHTML">{{ case.description }}</div> {% endwith %}
</div> </div>
{% if can_edit %} {% if can_edit %}
<button class="btn btn-sm btn-link text-muted p-0 ms-2 quick-edit-button" <button class="btn btn-sm btn-link text-muted p-0 ms-2 quick-edit-button"
@@ -36,13 +36,14 @@
<p class="mb-1 text-truncate">{{ case.description }}</p> <p class="mb-1 text-truncate">{{ case.description }}</p>
</div> </div>
<div class="ms-2"> <div class="ms-2 d-flex align-items-center">
{% if collection %} {% if collection %}
<form class="m-0" hx-post="{% url 'atlas:add_case_to_collection' collection.pk %}" hx-target="#full-question-list" hx-swap="beforeend"> <form class="m-0" hx-post="{% url 'atlas:add_case_to_collection' collection.pk %}" hx-target="#full-question-list" hx-swap="beforeend">
{% csrf_token %} {% csrf_token %}
<input type="hidden" name="case" value="{{ case.pk }}"> <input type="hidden" name="case" value="{{ case.pk }}">
<button type="submit" class="btn btn-sm btn-outline-primary">Add</button> <button type="submit" class="btn btn-sm btn-outline-primary">Add</button>
</form> </form>
<a class="btn btn-sm btn-outline-secondary ms-2" href="{% url 'atlas:case_detail' case.pk %}" target="_blank" rel="noopener">View</a>
{% else %} {% else %}
<a class="btn btn-sm btn-outline-secondary" href="{% url 'atlas:case_displaysets' case.pk %}">View</a> <a class="btn btn-sm btn-outline-secondary" href="{% url 'atlas:case_displaysets' case.pk %}">View</a>
{% endif %} {% endif %}
@@ -48,18 +48,36 @@
{% for case in recent_cases %} {% for case in recent_cases %}
<div class="list-group-item d-flex justify-content-between align-items-center" data-case-pk="{{ case.pk }}"> <div class="list-group-item d-flex justify-content-between align-items-center" data-case-pk="{{ case.pk }}">
<div class="flex-fill me-3"> <div class="flex-fill me-3">
<div class="fw-semibold">{{ case.title }}</div> <div class="d-flex w-100 justify-content-between">
<div class="small text-muted">{% if case.description %}{{ case.description|truncatechars:100 }}{% endif %}</div> <h6 class="mb-1">{{ case.title }}</h6>
<small class="text-muted">{{ case.created_date|date:"Y-m-d" }}</small>
</div>
<div class="mb-1">
<small class="text-muted me-2">{% if case.author.all %}By {{ case.author.all|join:", " }}{% endif %}</small>
{% for cond in case.condition.all %}
{% if cond.name %}<span class="badge bg-secondary me-1" title="Condition: {{ cond.name }}">{{ cond.name }}</span>{% endif %}
{% endfor %}
{% for pres in case.presentation.all %}
{% if pres.name %}<span class="badge bg-secondary me-1" title="Presentation: {{ pres.name }}">{{ pres.name }}</span>{% endif %}
{% endfor %}
{% for ss in case.subspecialty.all %}
{% if ss.name %}<span class="badge bg-secondary" title="Subspecialty: {{ ss.name }}">{{ ss.name }}</span>{% endif %}
{% endfor %}
</div>
<p class="mb-1 text-truncate">{% if case.description %}{{ case.description|truncatechars:100 }}{% endif %}</p>
</div>
<div class="ms-2 d-flex align-items-center">
{% if collection %}
<form class="m-0" hx-post="{% url 'atlas:add_case_to_collection' collection.pk %}" hx-target="#full-question-list" hx-swap="beforeend">
{% csrf_token %}
<input type="hidden" name="case" value="{{ case.pk }}">
<button type="submit" class="btn btn-sm btn-outline-primary">Add</button>
</form>
<a class="btn btn-sm btn-outline-secondary ms-2" href="{% url 'atlas:case_detail' case.pk %}" target="_blank" rel="noopener">View</a>
{% else %}
<a class="btn btn-sm btn-outline-secondary" href="{% url 'atlas:case_displaysets' case.pk %}">View</a>
{% endif %}
</div> </div>
{% if collection %}
<form class="m-0" hx-post="{% url 'atlas:add_case_to_collection' collection.pk %}" hx-target="#full-question-list" hx-swap="beforeend">
{% csrf_token %}
<input type="hidden" name="case" value="{{ case.pk }}">
<button type="submit" class="btn btn-sm btn-outline-primary">Add</button>
</form>
{% else %}
<a class="btn btn-sm btn-outline-secondary" href="{% url 'atlas:case_displaysets' case.pk %}">View</a>
{% endif %}
</div> </div>
{% endfor %} {% endfor %}
</div> </div>
@@ -1,19 +1,19 @@
<div class="case-search-widget"> <div class="case-search-widget">
{% with input_id=input_id|default:'case-search-input' target_id=target_id|default:'case-search-results' %} {% with input_id=input_id|default:'case-search-input' target_id=target_id|default:'case-search-results' %}
<label for="{{ input_id }}" class="form-label">Search cases</label> <label for="{{ input_id }}" class="form-label">Search cases</label>
<input id="{{ input_id }}" name="q" class="form-control" type="search" <input id="{{ input_id }}" name="q" class="form-control" type="search"
placeholder="Type to search cases..." placeholder="Type to search cases..."
hx-get="{% url 'atlas:case_search' %}" hx-get="{% url 'atlas:case_search' %}"
hx-include="#{{ input_id }}" hx-include="#{{ input_id }}"
{% if collection %}hx-vals='{"collection": "{{ collection.pk }}"}'{% endif %} {% if collection %}hx-vals='{"collection": "{{ collection.pk }}"}'{% endif %}
hx-target="#{{ target_id }}" hx-target="#{{ target_id }}"
hx-trigger="keyup changed delay:400ms" hx-trigger="keyup changed delay:400ms"
autocomplete="off"> autocomplete="off">
<div id="{{ target_id }}" class="mt-2"> <div id="{{ target_id }}" class="mt-2">
{# Render initial results (search + recent) on initial GET; HTMX searches will replace this div with partial results #} {# Render initial results (search + recent) on initial GET; HTMX searches will replace this div with partial results #}
{% include 'atlas/partials/case_search_results.html' with cases=cases recent_cases=recent_cases collection=collection %} {% include 'atlas/partials/case_search_results.html' with cases=cases recent_cases=recent_cases collection=collection %}
</div> </div>
{% endwith %} {% endwith %}
</div> </div>
@@ -26,7 +26,7 @@
input.addEventListener('input', function(){ input.addEventListener('input', function(){
if (timer) clearTimeout(timer); if (timer) clearTimeout(timer);
timer = setTimeout(function(){ timer = setTimeout(function(){
try { try {
var q = encodeURIComponent(input.value || ''); var q = encodeURIComponent(input.value || '');
var url = "{% url 'atlas:case_search' %}?q=" + q + ({% if collection %} "&collection={{ collection.pk }}" {% else %} '' {% endif %}); var url = "{% url 'atlas:case_search' %}?q=" + q + ({% if collection %} "&collection={{ collection.pk }}" {% else %} '' {% endif %});
var target = '#{{ target_id|default:"case-search-results" }}'; var target = '#{{ target_id|default:"case-search-results" }}';