.
This commit is contained in:
@@ -59,13 +59,35 @@
|
|||||||
<div class="mb-4">
|
<div class="mb-4">
|
||||||
<h2 class="subtitle">Rota Settings</h2>
|
<h2 class="subtitle">Rota Settings</h2>
|
||||||
<div class="box">
|
<div class="box">
|
||||||
<p class="help">View and edit the rota's `options` used by the builder. Click Edit to open a modal editor.</p>
|
<p class="help">Configure rota constraint options (typed via <code>RotaConstraintOptions</code>) and a few builder args. Change values and click Save to persist.</p>
|
||||||
<div style="margin-bottom:0.5em;">
|
|
||||||
<button class="button is-link" hx-get="{% url 'rota:rota_options' rota.id %}" hx-target="#modal" hx-swap="innerHTML">Edit options</button>
|
{% if options_form %}
|
||||||
</div>
|
<form method="post" hx-post="{% url 'rota:rota_options' rota.id %}" hx-swap="none">
|
||||||
<div>
|
{% csrf_token %}
|
||||||
{% include 'rota/partials/rota_options_display.html' %}
|
<div class="columns is-multiline">
|
||||||
</div>
|
{% for field in options_form.visible_fields %}
|
||||||
|
{% if field.name|slice:":5" == "opt__" %}
|
||||||
|
<div class="column is-half">
|
||||||
|
<div class="field">
|
||||||
|
<label class="label">{{ field.label }}</label>
|
||||||
|
<div class="control">{{ field }}</div>
|
||||||
|
{% if field.help_text %}<p class="help">{{ field.help_text }}</p>{% endif %}
|
||||||
|
{% for err in field.errors %}<p class="help is-danger">{{ err }}</p>{% endfor %}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
{% endfor %}
|
||||||
|
</div>
|
||||||
|
<div class="field">
|
||||||
|
<div class="control">
|
||||||
|
<button class="button is-primary" type="submit">Save constraint options</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
{% else %}
|
||||||
|
<p class="help">Constraint form unavailable.</p>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
<hr />
|
<hr />
|
||||||
<h3 class="subtitle is-6">Available constraint keys</h3>
|
<h3 class="subtitle is-6">Available constraint keys</h3>
|
||||||
<div style="max-height:400px; overflow:auto;">
|
<div style="max-height:400px; overflow:auto;">
|
||||||
@@ -86,7 +108,6 @@
|
|||||||
<td><pre style="white-space:pre-wrap;">{{ info.current|default:"" }}</pre></td>
|
<td><pre style="white-space:pre-wrap;">{{ info.current|default:"" }}</pre></td>
|
||||||
<td>
|
<td>
|
||||||
{{ info.description|default:"" }}
|
{{ info.description|default:"" }}
|
||||||
{% comment %} Quick action: add default value if none set {% endcomment %}
|
|
||||||
{% if info.current is None or info.current == "" %}
|
{% if info.current is None or info.current == "" %}
|
||||||
<div style="margin-top:0.4em;">
|
<div style="margin-top:0.4em;">
|
||||||
<button class="button is-small is-light" hx-get="{% url 'rota:rota_option_add' rota.id %}?key={{ key }}" hx-target="#modal" hx-swap="innerHTML">Add default</button>
|
<button class="button is-small is-light" hx-get="{% url 'rota:rota_option_add' rota.id %}?key={{ key }}" hx-target="#modal" hx-swap="innerHTML">Add default</button>
|
||||||
|
|||||||
+13
-11
@@ -5,7 +5,6 @@ from .models import RotaSchedule, Worker
|
|||||||
from .forms import WorkerForm, LeaveForm, RotaScheduleForm
|
from .forms import WorkerForm, LeaveForm, RotaScheduleForm
|
||||||
from .services import run_rota_async
|
from .services import run_rota_async
|
||||||
from .forms import ShiftForm
|
from .forms import ShiftForm
|
||||||
from .forms import RotaOptionsForm
|
|
||||||
import json
|
import json
|
||||||
from django.views.decorators.http import require_http_methods
|
from django.views.decorators.http import require_http_methods
|
||||||
from django.template.loader import render_to_string
|
from django.template.loader import render_to_string
|
||||||
@@ -22,8 +21,7 @@ def index(request):
|
|||||||
|
|
||||||
def rota_detail(request, rota_id):
|
def rota_detail(request, rota_id):
|
||||||
rota = get_object_or_404(RotaSchedule, pk=rota_id)
|
rota = get_object_or_404(RotaSchedule, pk=rota_id)
|
||||||
# Prepare options form and available builder constraint defaults
|
# Prepare available builder constraint defaults
|
||||||
options_form = RotaOptionsForm()
|
|
||||||
available_constraints = {}
|
available_constraints = {}
|
||||||
try:
|
try:
|
||||||
# Try to import RotaBuilder to surface its default constraint options
|
# Try to import RotaBuilder to surface its default constraint options
|
||||||
@@ -46,12 +44,6 @@ def rota_detail(request, rota_id):
|
|||||||
run = run_rota_async(rota.id, generate_builder=generate_builder, builder_solve=builder_solve)
|
run = run_rota_async(rota.id, generate_builder=generate_builder, builder_solve=builder_solve)
|
||||||
return redirect(reverse("rota:rota_run_detail", args=(run.id,)))
|
return redirect(reverse("rota:rota_run_detail", args=(run.id,)))
|
||||||
|
|
||||||
# Prefill options form with existing rota.options JSON
|
|
||||||
try:
|
|
||||||
opt_json = json.dumps(rota.options or {}, indent=4)
|
|
||||||
except Exception:
|
|
||||||
opt_json = "{}"
|
|
||||||
|
|
||||||
# Build a richer representation of available constraints (default, type, description)
|
# Build a richer representation of available constraints (default, type, description)
|
||||||
available_constraints_rich = {}
|
available_constraints_rich = {}
|
||||||
try:
|
try:
|
||||||
@@ -87,11 +79,21 @@ def rota_detail(request, rota_id):
|
|||||||
except Exception:
|
except Exception:
|
||||||
available_constraints_rich = {k: {"default": v} for k, v in available_constraints.items()}
|
available_constraints_rich = {k: {"default": v} for k, v in available_constraints.items()}
|
||||||
|
|
||||||
options_form = RotaOptionsForm(initial={"options_json": opt_json})
|
# legacy RotaOptionsForm not used here; we provide a typed RotaScheduleForm below
|
||||||
|
|
||||||
|
# Provide a typed RotaScheduleForm instance so the template can render
|
||||||
|
# the constraint fields (prefixed with `opt__`) inline and submit them
|
||||||
|
# to the existing `rota_options` view which understands typed forms.
|
||||||
|
from .forms import RotaScheduleForm
|
||||||
|
try:
|
||||||
|
typed_form = RotaScheduleForm(instance=rota)
|
||||||
|
except Exception:
|
||||||
|
typed_form = None
|
||||||
|
|
||||||
return render(
|
return render(
|
||||||
request,
|
request,
|
||||||
"rota/rota_detail.html",
|
"rota/rota_detail.html",
|
||||||
{"rota": rota, "options_form": options_form, "available_constraints": available_constraints_rich},
|
{"rota": rota, "options_form": typed_form, "available_constraints": available_constraints_rich},
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user