basis/components/web/templates/includes/form_builder.html
apeters 519dbc73c6 Cat.
Signed-off-by: apeters <apeters@korves.net>
2025-06-03 11:40:56 +00:00

315 lines
15 KiB
HTML

{#
DATA FIELDS
current_data: dict
schema: BaseModel.model_json_schema()
system_fields: Optional[list] # An optional list of fields to disable when "system"
# is not part of a user's ACL
root_key: Optional[str] # A string to encapsulate a name in,
# i.e. a root_key "profile" for a field "email" becomes "profile.email"
#}
{% for k, v in schema.properties.items() if k not in without %}
{% if v.type in ["text", "email", "number"] %}
{% set readonly = True if "readonly" in v.input_extra else False %}
<fieldset data-loading-disable {% if k in system_fields and not "system" in session["acl"] %}class="system-field" disabled{% endif %}>
<label for="{{ v.form_id }}">{{ v.title }} {{ "🚫" if readonly }}</label>
<input {{ v.input_extra|safe }} id="{{ v.form_id }}"
name="{% if root_key %}{{ root_key }}.{{ k }}{% else %}{{ k }}{% endif %}"
type="{{ v.type }}"
value="{% if current_data[k] == None %}{{ v.default }}{% else %}{{ current_data[k] }}{% endif %}">
{% if v.description %}
<small>{{ v.description|safe }}</small>
{% endif %}
</fieldset>
{% elif v.type in ["date", "datetime-local"] %}
{% set readonly = True if "readonly" in v.input_extra else False %}
<fieldset data-loading-disable {% if k in system_fields and not "system" in session["acl"] %}class="system-field" disabled{% endif %}>
<label for="{{ v.form_id }}">{{ v.title }} {{ "🚫" if readonly }}</label>
<input {{ v.input_extra|safe }} id="{{ v.form_id }}"
name="{% if root_key %}{{ root_key }}.{{ k }}{% else %}{{ k }}{% endif %}"
type="{{ v.type }}"
value="{% if current_data[k] == None %}{{ v.default }}{% else %}{{ current_data[k] }}{% endif %}">
{% if v.description %}
<small>{{ v.description|safe }}</small>
{% endif %}
</fieldset>
{% elif v.type == "select:multi" or v.type == "select" %}
<fieldset data-loading-disable {% if k in system_fields and not "system" in session["acl"] %}class="system-field" disabled{% endif %}>
<label for="{{ v.form_id }}">{{ v.title }}</label>
<select {{ v.input_extra|safe }}
{% if v.type == "select:multi" %}
multiple
size="5"
{% endif %}
name="{% if root_key %}{{ root_key }}.{{ k }}{% else %}{{ k }}{% endif %}"
id="{{ v.form_id }}">
{% for option in v.options %}
<option value="{{ option["value"] }}" {{ "selected" if option["value"] in current_data[k] or option["value"] == "" and not current_data[k] }}>{{ option["name"] }}</option>
{% endfor %}
</select>
{% if v.description %}
<small>{{ v.description|safe }}</small>
{% endif %}
</fieldset>
{% elif v.type == "tresor" %}
{% if request.path == "/profile/" %}
<details name="tresor">
<summary role="button">{{ v.title }}</summary>
<fieldset data-loading-disable {% if k in system_fields and not "system" in session["acl"] %}class="system-field" disabled{% endif %} class="tresor">
<input id="{{ v.form_id }}" type="hidden" {{ v.input_extra|safe }}
name="{% if root_key %}{{ root_key }}.{{ k }}{% else %}{{ k }}{% endif %}"
value="{% if current_data[k] %}{{ current_data[k] }}{% endif %}" />
{% if not current_data[k] %}
<legend>Setup tresor</legend>
<input form="_ignore" id="{{ v.form_id }}-password" name="{{ v.form_id }}-password" type="password" {{ v.input_extra|safe }} />
<small>Password</small>
<input form="_ignore" id="{{ v.form_id }}-password2" name="{{ v.form_id }}-password2" type="password" {{ v.input_extra|safe }} />
<small>Confirm password</small>
<a role="button" href="#" _="on click halt the event
if not value of #{{ v.form_id }}-password
trigger notification(level: 'validationError', message: 'Missing password', duration: 3000, locations: ['{{ v.form_id }}-password'])
exit
end
if value of #{{ v.form_id }}-password != value of #{{ v.form_id }}-password2
trigger notification(level: 'validationError', message: 'Passwords do not match', duration: 3000, locations: ['{{ v.form_id }}-password', '{{ v.form_id }}-password2'])
exit
end
call VaultSetupUserCryptoAndSend(value of #{{ v.form_id }}-password)
set value of #{{ v.form_id }} to (result as JSON)
call window.vault.lock()
add @disabled to <input[type=password]/> in closest .tresor
put '<mark>Pending</mark> - please save changes to apply.' after me then remove me
on exception(error) trigger notification(level: 'error', title: 'Tresor error', message: error, duration: 3000)">
Setup encryption
</a>
{% else %}
<legend>Change tresor password</legend>
<input form="_ignore" id="old-{{ v.form_id }}" name="old-{{ v.form_id }}" type="password" {{ v.input_extra|safe }} />
<small>Current password</small>
<input form="_ignore" id="new-{{ v.form_id }}" name="new-{{ v.form_id }}" type="password" {{ v.input_extra|safe }} />
<small>New password</small>
<input form="_ignore" id="new2-{{ v.form_id }}" name="new2-{{ v.form_id }}" type="password" {{ v.input_extra|safe }} />
<small>Confirm new password</small>
<a role="button" href="#" _="install confirmButton on confirmedButton halt the event
if not value of #old-{{ v.form_id }}
trigger notification(level: 'validationError', message: 'Missing current password', duration: 3000, locations: ['old-{{ v.form_id }}'])
exit
end
if not value of #new-{{ v.form_id }}
trigger notification(level: 'validationError', message: 'Missing new password', duration: 3000, locations: ['new-{{ v.form_id }}'])
exit
end
if value of #new-{{ v.form_id }} != value of #new2-{{ v.form_id }}
trigger notification(level: 'validationError', message: 'Passwords do not match', duration: 3000, locations: ['new-{{ v.form_id }}', 'new2-{{ v.form_id }}'])
exit
end
set previousLock to window.vault.isUnlocked()
call JSON.parse(value of #{{ v.form_id }}) set keyData to the result
call VaultChangePassword(value of #old-{{ v.form_id }}, value of #new-{{ v.form_id }}, keyData)
call window.vault.exportPayload()
set value of #{{ v.form_id }} to (result as JSON)
add @disabled to closest .tresor
if not previousLock call window.vault.lock() end
put '<mark>Pending</mark> - please save changes to apply.' after me then remove me
on exception(error) trigger notification(level: 'error', title: 'Tresor error', message: error, duration: 3000)">
Change password
</a>
{% endif %}
</fieldset>
</details>
{% endif %}
{% elif v.type == "datalist" %}
<fieldset data-loading-disable {% if k in system_fields and not "system" in session["acl"] %}class="system-field" disabled{% endif %}>
<label for="{{ v.form_id }}">{{ v.title }}</label>
<input list="{{ v.form_id }}-datalist"
name="{% if root_key %}{{ root_key }}.{{ k }}{% else %}{{ k }}{% endif %}"
id="{{ v.form_id }}"
value="{% if current_data[k] == None %}{{ v.default }}{% else %}{{ current_data[k] }}{% endif %}" {{ v.input_extra|safe }}>
<datalist
id="{{ v.form_id }}-datalist">
{% for option in v.options %}
<option value="{{ option }}">
{% endfor %}
</datalist>
{% if v.description %}
<small>{{ v.description|safe }}</small>
{% endif %}
</fieldset>
{% elif (v.type == "users:multi" or v.type == "users") and "system" in session["acl"] %}
{% if not request.form_options.users or request.form_options.users == [] %}
<p>No users found</p>
{% else %}
<fieldset data-loading-disable {% if k in system_fields and not "system" in session["acl"] %}class="system-field" disabled{% endif %}>
<label for="{{ v.form_id }}">{{ v.title }}</label>
<select {{ v.input_extra|safe }}
{% if v.type == "users:multi" %}
multiple
size="5"
{% endif %}
name="{% if root_key %}{{ root_key }}.{{ k }}{% else %}{{ k }}{% endif %}"
id="{{ v.form_id }}">
{% for option in request.form_options.users %}
<option value="{{ option["value"] }}" {{ "selected" if option["value"] in current_data[k] }}>{{ option["name"] }}</option>
{% endfor %}
</select>
{% if v.description %}
<small>{{ v.description|safe }}</small>
{% endif %}
</fieldset>
{% endif %}
{% elif v.type == "emailusers:multi" or v.type == "emailusers" %}
{% if request.form_options.emailusers == [] %}
<label for="{{ v.form_id }}">{{ v.title }}</label>
<p><mark>No email users available</mark></p>
{% else %}
<fieldset data-loading-disable {% if k in system_fields and not "system" in session["acl"] %}class="system-field" disabled{% endif %}>
<label for="{{ v.form_id }}">{{ v.title }}</label>
<select {{ v.input_extra|safe }}
{% if v.type == "emailusers:multi" %}
multiple
size="5"
{% endif %}
name="{% if root_key %}{{ root_key }}.{{ k }}{% else %}{{ k }}{% endif %}"
id="{{ v.form_id }}">
{% for option in request.form_options.emailusers %}
<option value="{{ option["value"] }}" {{ "selected" if option["value"] in current_data[k]|map(attribute="id")|list }}>{{ option["name"] }}</option>
{% endfor %}
</select>
{% if v.description %}
<small>{{ v.description|safe }}</small>
{% endif %}
</fieldset>
{% endif %}
{% elif v.type == "list:text" or v.type == "list:number" %}
{% set readonly = True if "readonly" in v.input_extra else False %}
<template id="list:item">
<div>
<input {{ v.input_extra|safe }}
name="{% if root_key %}{{ root_key }}.{{ k }}{% else %}{{ k }}{% endif %}"
type="{{ "text" if v.type == "list:text" else "number" }}"
placeholder="New element">
<small><a href="#" hx-on:click="event.preventDefault();this.closest('div').remove()">Remove</a></small>
</div>
</template>
<fieldset data-loading-disable id="{{ v.form_id }}" _="on click from .add-list-item in me halt the event then render #list:item then put the result at the end of me end">
<legend>{{ v.title }} <a {{ "hidden" if readonly }} href="#" class="add-list-item">Add</a> {{ "🚫" if readonly }}</legend>
{% for list_value in current_data[k] or v.default %}
<div>
<input {{ v.input_extra|safe }}
name="{% if root_key %}{{ root_key }}.{{ k }}{% else %}{{ k }}{% endif %}"
type="{{ "text" if v.type == "list:text" else "number" }}"
value="{{ list_value }}">
<small {{ "hidden" if readonly }}><a href="#" hx-on:click="event.preventDefault();this.closest('div').remove()">Remove</a></small>
</div>
{% endfor %}
</fieldset>
{% if v.description %}
<small>{{ v.description|safe }}</small>
{% endif %}
{% elif v.type == "radio" %}
<fieldset data-loading-disable {% if k in system_fields and not "system" in session["acl"] %}class="system-field" disabled{% endif %}>
<legend for="{{ v.form_id }}">{{ v.title }}</legend>
{% for radio_value in v.enum %}
<label>
<input {{ v.input_extra|safe }}
id="{{ v.form_id }}"
type="radio"
value="{{ radio_value }}"
name="{% if root_key %}{{ root_key }}.{{ k }}{% else %}{{ k }}{% endif %}"
{{ "checked" if (current_data[k] != None and current_data[k] == radio_value) or (current_data[k] == None and v.default == radio_value) }} />
{{ radio_value|capitalize }}
</label>
{% endfor %}
{% if v.description %}
<small>{{ v.description|safe }}</small>
{% endif %}
</fieldset>
{% elif v.type == "keypair" %}
{% if not request.form_options.keypairs or request.form_options.keypairs == [] %}
<p>No key pairs available</p>
{% else %}
<fieldset data-loading-disable {% if k in system_fields and not "system" in session["acl"] %}class="system-field keypair" disabled{% endif %} class="keypair">
<legend>{{ v.title }}</legend>
<select {{ v.input_extra|safe }}
name="{% if root_key %}{{ root_key }}.{{ k }}{% else %}{{ k }}{% endif %}"
id="{{ v.form_id }}"
_="
on change or load
set keypairId to (value of <option:checked/> in me) as String
put '' into #dns-data-{{ v.form_id }}
if keypairId
add @disabled to me
put '⌛' into #dns-data-{{ v.form_id }}
getJsonUrlAsObject('/objects/keypairs/' + keypairId)
put result.details.dns_formatted into #dns-data-{{ v.form_id }}
end
catch e
put '⛔' into #dns-data-{{ v.form_id }}
finally
remove @disabled from me
trigger validate on #dns-data-{{ v.form_id }}
end">
<option value="" {{ "selected" if current_data[k] == "" }}>-- None --</option>
{% for option in request.form_options.keypairs %}
<option value="{{ option["value"] }}" {{ "selected" if option["value"] == current_data[k].id }}>{{ option["name"] }}</option>
{% endfor %}
</select>
{% if v.description %}
<small>{{ v.description|safe }}</small>
<div>
<small><i>The required DNS TXT record's value for your convenience</i> (<span class="color-blue-200 pointer" _="on click trigger change on previous <option:checked/>">force reload</span>)</small>
<textarea rows="8" class="dns-data" readonly id="dns-data-{{ v.form_id }}" _="
on validate add @hidden to closest <div/> if my value is empty else remove @hidden from closest <div/> end end
on click call my.setSelectionRange(0, -1) end">
{{- "" -}}
</textarea>
</div>
{% endif %}
</fieldset>
{% endif %}
{% elif v.type == "domain" %}
{% if request.form_options.domains == [] %}
<label for="{{ v.form_id }}">{{ v.title }}</label>
<p><mark>No domain available</mark></p>
{% else %}
<fieldset data-loading-disable {% if k in system_fields and not "system" in session["acl"] %}class="system-field" disabled{% endif %}>
<label for="{{ v.form_id }}">{{ v.title }}</label>
<select {{ v.input_extra|safe }}
name="{% if root_key %}{{ root_key }}.{{ k }}{% else %}{{ k }}{% endif %}"
id="{{ v.form_id }}">
{% for option in request.form_options.domains %}
<option value="{{ option["value"] }}" {{ "selected" if option["value"] == current_data[k].id }}>{{ option["name"] }}</option>
{% endfor %}
</select>
{% if v.description %}
<small>{{ v.description|safe }}</small>
{% endif %}
</fieldset>
{% endif %}
{% endif %}
{% endfor %}