Addign links to entry pages.

This commit is contained in:
Yaro Kasear 2025-10-14 11:33:21 -05:00
parent 775600e140
commit 668924ba10
5 changed files with 121 additions and 10 deletions

View file

@ -639,9 +639,14 @@ def _normalize_field_spec(spec, mapper, session, label_specs_model_default):
"template": spec.get("template"), "template": spec.get("template"),
"template_name": spec.get("template_name"), "template_name": spec.get("template_name"),
"template_ctx": spec.get("template_ctx"), "template_ctx": spec.get("template_ctx"),
"label_spec": spec.get("label_spec") "label_spec": spec.get("label_spec"),
} }
if "link" in spec:
field["link"] = spec["link"]
if "label_deps" in spec:
field["label_deps"] = spec["label_deps"]
if rel_prop: if rel_prop:
if field["type"] is None: if field["type"] is None:
field["type"] = "select" field["type"] = "select"
@ -970,6 +975,7 @@ def _format_label_from_values(spec: Any, values: dict) -> Optional[str]:
return "" if v is None else str(v) return "" if v is None else str(v)
def _build_href(spec: Dict[str, Any], row: Dict[str, Any], obj) -> Optional[str]: def _build_href(spec: Dict[str, Any], row: Dict[str, Any], obj) -> Optional[str]:
print(spec)
if not spec: if not spec:
return None return None
params = {} params = {}
@ -982,6 +988,7 @@ def _build_href(spec: Dict[str, Any], row: Dict[str, Any], obj) -> Optional[str]
params[k] = val params[k] = val
else: else:
params[k] = v params[k] = v
print(params)
if any(v is None for v in params.values()): if any(v is None for v in params.values()):
return None return None
try: try:
@ -1061,6 +1068,7 @@ def render_field(field, value):
label_attrs=_sanitize_attrs(field.get('label_attrs') or {}), label_attrs=_sanitize_attrs(field.get('label_attrs') or {}),
help=field.get('help'), help=field.get('help'),
value_label=field.get('value_label'), value_label=field.get('value_label'),
link_href=field.get("link_href"),
) )
@ -1231,6 +1239,15 @@ def render_form(
if vl2 is not None: if vl2 is not None:
f["value_label"] = vl2 f["value_label"] = vl2
link_spec = f.get("link")
if link_spec:
try:
href = _build_href(link_spec, values_map, instance)
except Exception:
href = None
if href:
f["link_href"] = href
# Build rows (supports nested layout with parents) # Build rows (supports nested layout with parents)
rows_map = _normalize_rows_layout(layout) rows_map = _normalize_rows_layout(layout)
rows_tree = _assign_fields_to_rows(fields, rows_map) rows_tree = _assign_fields_to_rows(fields, rows_map)

View file

@ -4,7 +4,13 @@
{% if label_attrs %}{% for k,v in label_attrs.items() %} {% if label_attrs %}{% for k,v in label_attrs.items() %}
{{k}}{% if v is not sameas true %}="{{ v }}"{% endif %} {{k}}{% if v is not sameas true %}="{{ v }}"{% endif %}
{% endfor %}{% endif %}> {% endfor %}{% endif %}>
{{ field_label }} {% if link_href %}
<a href="{{ link_href }}">
{% endif %}
{{ field_label }}
{% if link_href %}
</a>
{% endif %}
</label> </label>
{% endif %} {% endif %}

View file

@ -23,6 +23,7 @@ def _fields_for_model(model: str):
"model", "model",
"condition", "condition",
"notes", "notes",
"owner.id",
] ]
fields_spec = [ fields_spec = [
{"name": "label", "type": "display", "label": "", "row": "label", {"name": "label", "type": "display", "label": "", "row": "label",
@ -43,7 +44,7 @@ def _fields_for_model(model: str):
"attrs": {"class": "form-control"}, "label": "Device Type", "label_attrs": {"class": "form-label"}}, "attrs": {"class": "form-control"}, "label": "Device Type", "label_attrs": {"class": "form-label"}},
{"name": "owner", "row": "status", "label": "Contact", "wrap": {"class": "col"}, {"name": "owner", "row": "status", "label": "Contact", "wrap": {"class": "col"},
"attrs": {"class": "form-control"}, "label_attrs": {"class": "form-label"}, "attrs": {"class": "form-control"}, "label_attrs": {"class": "form-label"},
"label_spec": "{label}"}, "label_spec": "{label}", "link": {"endpoint": "entry.entry", "params": {"model": "user", "id": "{owner.id}"}}},
{"name": "location", "row": "status", "label": "Location", "wrap": {"class": "col"}, {"name": "location", "row": "status", "label": "Location", "wrap": {"class": "col"},
"attrs": {"class": "form-control"}, "label_attrs": {"class": "form-label"}, "attrs": {"class": "form-control"}, "label_attrs": {"class": "form-label"},
"label_spec": "{name} - {room_function.description}"}, "label_spec": "{name} - {room_function.description}"},
@ -84,7 +85,8 @@ def _fields_for_model(model: str):
"last_name", "last_name",
"title", "title",
"active", "active",
"staff" "staff",
"supervisor.id"
] ]
fields_spec = [ fields_spec = [
{"name": "label", "row": "label", "label": "", "type": "display", {"name": "label", "row": "label", "label": "", "type": "display",
@ -100,7 +102,7 @@ def _fields_for_model(model: str):
"row": "name", "wrap": {"class": "col-3"}}, "row": "name", "wrap": {"class": "col-3"}},
{"name": "supervisor", "label": "Supervisor", "label_attrs": {"class": "form-label"}, {"name": "supervisor", "label": "Supervisor", "label_attrs": {"class": "form-label"},
"label_spec": "{label}", "row": "details", "wrap": {"class": "col-3"}, "label_spec": "{label}", "row": "details", "wrap": {"class": "col-3"},
"attrs": {"class": "form-control"}}, "attrs": {"class": "form-control"}, "link": {"endpoint": "entry.entry", "params": {"id": "{supervisor.id}", "model": "user"}}},
{"name": "location", "label": "Room", "label_attrs": {"class": "form-label"}, {"name": "location", "label": "Room", "label_attrs": {"class": "form-label"},
"label_spec": "{name} - {room_function.description}", "label_spec": "{name} - {room_function.description}",
"row": "details", "wrap": {"class": "col-3"}, "attrs": {"class": "form-control"}}, "row": "details", "wrap": {"class": "col-3"}, "attrs": {"class": "form-control"}},
@ -137,9 +139,11 @@ def _fields_for_model(model: str):
{"name": "buttons", "label": "", "row": "label", "type": "template", "template": "entry_buttons.html", {"name": "buttons", "label": "", "row": "label", "type": "template", "template": "entry_buttons.html",
"wrap": {"class": "col-auto text-end me-2"}, "attrs": {"data-model": model}}, "wrap": {"class": "col-auto text-end me-2"}, "attrs": {"data-model": model}},
{"name": "contact", "row": "ownership", "wrap": {"class": "col"}, "label": "Contact", {"name": "contact", "row": "ownership", "wrap": {"class": "col"}, "label": "Contact",
"label_spec": "{label}", "attrs": {"class": "form-control"}, "label_attrs": {"class": "form-label"}}, "label_spec": "{label}", "attrs": {"class": "form-control"}, "label_attrs": {"class": "form-label"},
"link": {"endpoint": "entry.entry", "params": {"id": "{contact.id}", "model": "user"}}},
{"name": "work_item", "row": "ownership", "wrap": {"class": "col"}, "label": "Work Item", {"name": "work_item", "row": "ownership", "wrap": {"class": "col"}, "label": "Work Item",
"label_spec": "{label}", "attrs": {"class": "form-control"}, "label_attrs": {"class": "form-label"}}, "label_spec": "{label}", "attrs": {"class": "form-control"}, "label_attrs": {"class": "form-label"},
"link": {"endpoint": "entry.entry", "params": {"id": "{work_item.id}", "model": "inventory"}}},
{"name": "start_time", "type": "datetime", "attrs": {"class": "form-control"}, "row": "timestamps", {"name": "start_time", "type": "datetime", "attrs": {"class": "form-control"}, "row": "timestamps",
"wrap": {"class": "col"}, "label_attrs": {"class": "form-label"}, "label": "Start"}, "wrap": {"class": "col"}, "label_attrs": {"class": "form-label"}, "label": "Start"},
{"name": "end_time", "type": "datetime", "attrs": {"class": "form-control"}, "row": "timestamps", {"name": "end_time", "type": "datetime", "attrs": {"class": "form-control"}, "row": "timestamps",

View file

@ -0,0 +1,84 @@
{# show label unless hidden/custom #}
<!-- Overridden by inventory application -->
{% if field_type != 'hidden' and field_label %}
<label for="{{ field_name }}"
{% if label_attrs %}{% for k,v in label_attrs.items() %}
{{k}}{% if v is not sameas true %}="{{ v }}"{% endif %}
{% endfor %}{% endif %}>
{% if link_href %}
<a href="{{ link_href }}" class="link-success link-underline link-underline-opacity-0 fw-semibold">
{% endif %}
{{ field_label }}
{% if link_href %}
</a>
{% endif %}
</label>
{% endif %}
{% if field_type == 'select' %}
<select name="{{ field_name }}" id="{{ field_name }}"
{% if attrs %}{% for k,v in attrs.items() %}
{{k}}{% if v is not sameas true %}="{{ v }}"{% endif %}
{% endfor %}{% endif %}
{%- if not options %} disabled{% endif %}>
{% if options %}
<option value="">-- Select --</option>
{% for opt in options %}
<option value="{{ opt.value }}" {% if opt.value|string == value|string %}selected{% endif %}>
{{ opt.label }}
</option>
{% endfor %}
{% else %}
<option value="">-- No selection available --</option>
{% endif %}
</select>
{% elif field_type == 'textarea' %}
<textarea name="{{ field_name }}" id="{{ field_name }}"
{% if attrs %}{% for k,v in attrs.items() %}
{{k}}{% if v is not sameas true %}="{{ v }}"{% endif %}
{% endfor %}{% endif %}>{{ value if value else "" }}</textarea>
{% elif field_type == 'checkbox' %}
<input type="checkbox" name="{{ field_name }}" id="{{ field_name }}" value="1"
{% if value %}checked{% endif %}
{% if attrs %}{% for k,v in attrs.items() %}
{{k}}{% if v is not sameas true %}="{{ v }}"{% endif %}
{% endfor %}{% endif %}>
{% elif field_type == 'hidden' %}
<input type="hidden" name="{{ field_name }}" id="{{ field_name }}" value="{{ value if value else "" }}">
{% elif field_type == 'display' %}
<div {% if attrs %}{% for k,v in attrs.items() %}
{{k}}{% if v is not sameas true %}="{{ v }}"{% endif %}
{% endfor %}{% endif %}>{{ value_label if value_label else (value if value else "") }}</div>
{% elif field_type == "date" %}
<input type="date" name="{{ field_name }}" id="{{ field_name }}" value="{{ value if value else "" }}"
{% if attrs %}{% for k,v in attrs.items() %}
{{k}}{% if v is not sameas true %}="{{ v }}"{% endif %}
{% endfor %}{% endif %}>
{% elif field_type == "time" %}
<input type="time" name="{{ field_name }}" id="{{ field_name }}" value="{{ value if value else "" }}"
{% if attrs %}{% for k,v in attrs.items() %}
{{k}}{% if v is not sameas true %}="{{ v }}"{% endif %}
{% endfor %}{% endif %}>
{% elif field_type == "datetime" %}
<input type="datetime-local" name="{{ field_name }}" id="{{ field_name }}" value="{{ value if value else "" }}"
{% if attrs %}{% for k,v in attrs.items() %}
{{k}}{% if v is not sameas true %}="{{ v }}"{% endif %}
{% endfor %}{% endif %}>
{% else %}
<input type="text" name="{{ field_name }}" id="{{ field_name }}" value="{{ value if value else "" }}"
{% if attrs %}{% for k,v in attrs.items() %}
{{k}}{% if v is not sameas true %}="{{ v }}"{% endif %}
{% endfor %}{% endif %}>
{% endif %}
{% if help %}
<div class="form-text">{{ help }}</div>
{% endif %}

View file

@ -172,7 +172,7 @@
const current = getMarkdown(id); const current = getMarkdown(id);
container.innerHTML = ` container.innerHTML = `
<textarea class="form-control w-100 auto-md" id="editor${id}">${escapeForTextarea(current)}</textarea> <textarea class="form-control w-100 overflow-auto auto-md" id="editor${id}">${escapeForTextarea(current)}</textarea>
<div class="mt-2 d-flex gap-2"> <div class="mt-2 d-flex gap-2">
<button type="button" class="btn btn-primary btn-sm" onclick="saveEdit(${id})">Save</button> <button type="button" class="btn btn-primary btn-sm" onclick="saveEdit(${id})">Save</button>
<button type="button" class="btn btn-secondary btn-sm" onclick="cancelEdit(${id})">Cancel</button> <button type="button" class="btn btn-secondary btn-sm" onclick="cancelEdit(${id})">Cancel</button>
@ -211,7 +211,7 @@
function autoGrow(ta) { function autoGrow(ta) {
if (!ta) return; if (!ta) return;
ta.style.height = 'auto'; ta.style.height = 'auto';
ta.style.height = ta.scrollHeight + 'px'; ta.style.height = (ta.scrollHeight + 5) + 'px';
} }
function escapeForTextarea(s) { function escapeForTextarea(s) {