Addign links to entry pages.
This commit is contained in:
parent
775600e140
commit
668924ba10
5 changed files with 121 additions and 10 deletions
|
|
@ -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)
|
||||||
|
|
|
||||||
|
|
@ -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 %}>
|
||||||
|
{% if link_href %}
|
||||||
|
<a href="{{ link_href }}">
|
||||||
|
{% endif %}
|
||||||
{{ field_label }}
|
{{ field_label }}
|
||||||
|
{% if link_href %}
|
||||||
|
</a>
|
||||||
|
{% endif %}
|
||||||
</label>
|
</label>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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",
|
||||||
|
|
|
||||||
84
inventory/templates/crudkit/field.html
Normal file
84
inventory/templates/crudkit/field.html
Normal 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 %}
|
||||||
|
|
@ -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) {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue