Make form layout better at wide screens & Make horizontal form column layout configurable via global Twig variables (#1293)

* Initial plan

* Make form column layout configurable with global Twig variables

Co-authored-by: jbtronics <5410681+jbtronics@users.noreply.github.com>

* Rename form column Twig globals to shorter names: label_col, input_col, offset_col

Co-authored-by: jbtronics <5410681+jbtronics@users.noreply.github.com>

* Fixed remaining places where offsets where used

* Fixed margin of delete button on admin forms

* Rename Twig globals: col_label, col_input, offset_label

Co-authored-by: jbtronics <5410681+jbtronics@users.noreply.github.com>

* Added documentation to our twig class variables

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: jbtronics <5410681+jbtronics@users.noreply.github.com>
Co-authored-by: Jan Böhmer <mail@jan-boehmer.de>
This commit is contained in:
Copilot 2026-03-07 16:14:58 +01:00 committed by GitHub
parent e8d90487d2
commit e84bae2807
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
34 changed files with 86 additions and 81 deletions

View file

@ -18,6 +18,11 @@ twig:
saml_enabled: '%partdb.saml.enabled%'
part_preview_generator: '@App\Services\Attachments\PartPreviewGenerator'
# Bootstrap grid classes used for horizontal form layouts
col_label: 'col-sm-3 col-lg-2' # The column classes for form labels
col_input: 'col-sm-9 col-lg-10' # The column classes for form input fields
offset_label: 'offset-sm-3 offset-lg-2' # Offset classes for elements that should be aligned with the input fields (e.g., submit buttons)
when@test:
twig:
strict_variables: true

View file

@ -5,7 +5,7 @@
<input type="hidden" name="_token" value="{{ csrf_token('delete' ~ entity.id) }}">
<div class="form-group">
<div class=""></div>
<div class="col-sm offset-sm-3 ps-2">
<div class="{{ col_input }} {{ offset_label }} ps-1">
{% set delete_disabled = (not is_granted("delete", entity)) or (entity.group is defined and entity.id == 1) or entity == app.user %}
<div class="btn-group">
<button class="btn btn-danger" {% if delete_disabled %}disabled{% endif %}>{% trans %}entity.delete{% endtrans %}</button>
@ -20,7 +20,7 @@
</div>
</div>
{% if entity.parent is defined %}
<div class="ms-2 custom-control custom-checkbox custom-control-inline">
<div class="ms-1 custom-control custom-checkbox custom-control-inline">
<input type="checkbox" class="form-check-input" id="recursive" name="delete_recursive">
<label class="form-check-label" for="recursive">{% trans %}entity.delete.recursive{% endtrans %}</label>
</div>

View file

@ -1,5 +1,5 @@
<div class="row mb-2">
<div class="offset-3 col">
<div class="{{ offset_label }} {{ col_input }}">
<a class="btn btn-info {% if not is_granted('create', entity) %}disabled{% endif %}" href="{{ entity_url(entity, 'clone') }}">{% trans %}entity.duplicate{% endtrans %}</a>
</div>
</div>
</div>

View file

@ -35,8 +35,8 @@
</div>
<div class="row mt-2">
<div class="offset-sm-3 col-sm">
<div class="{{ offset_label }} col-sm">
<button type="submit" class="btn btn-primary">{% trans %}export.btn{% endtrans %}</button>
</div>
</div>
</form>
</form>

View file

@ -129,7 +129,7 @@
</div>
<div class="form-group row">
<div class="col-sm-9 offset-sm-3">
<div class="{{ col_input }} {{ offset_label }}">
<div class="btn-group">
{{ form_widget(form.save) }}
<button type="button" class="btn {% if entity.id is not null %}btn-primary{% else %}btn-success{% endif %} dropdown-toggle dropdown-toggle-split" data-bs-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
@ -186,7 +186,7 @@
<div id="mass_creation" class="tab-pane fade">
<div class="row">
<p class="text-muted offset-sm-3 col-sm-9">{% trans %}mass_creation.help{% endtrans %}</p>
<p class="text-muted {{ offset_label }} {{ col_input }}">{% trans %}mass_creation.help{% endtrans %}</p>
</div>
{{ form(mass_creation_form) }}
</div>

View file

@ -41,13 +41,13 @@
{{ form_row(form.eda_info.reference_prefix) }}
<div class="row">
<div class="col-sm-9 offset-sm-3">
<div class="{{ col_input }} {{ offset_label }}">
{{ form_row(form.eda_info.visibility) }}
</div>
</div>
<div class="row mb-2">
<div class="col-sm-9 offset-sm-3">
<div class="{{ col_input }} {{ offset_label }}">
{{ form_widget(form.eda_info.exclude_from_bom) }}
{{ form_widget(form.eda_info.exclude_from_board) }}
{{ form_widget(form.eda_info.exclude_from_sim) }}
@ -55,7 +55,7 @@
</div>
<div class="row">
<div class="col-sm-9 offset-sm-3">
<div class="{{ col_input }} {{ offset_label }}">
<h6>{% trans %}eda_info.kicad_section.title{% endtrans %}:</h6>
</div>
</div>

View file

@ -10,10 +10,10 @@
{{ form_row(form.iso_code) }}
{% if entity.isoCode %}
<div class="mt-0 mb-3">
<span class="form-text text-muted offset-3 col-9">
<span class="form-text text-muted {{ offset_label }} {{ col_input }}">
<b>{% trans %}currency.iso_code.caption{% endtrans %}:</b> {{ entity.isoCode }}
</span>
<span class="form-text text-muted offset-3 col-9">
<span class="form-text text-muted {{ offset_label }} {{ col_input }}">
<b>{% trans %}currency.symbol.caption{% endtrans %}:</b> {{ entity.isoCode | currency_symbol }}
</span>
</div>
@ -21,7 +21,7 @@
{{ form_row(form.exchange_rate) }}
{% if entity.inverseExchangeRate %}
<p class="form-text text-muted offset-3 col-9">
<p class="form-text text-muted {{ offset_label }} {{ col_input }}">
{{ '1'|format_currency(vars.base_currency()) }} = {{ entity.inverseExchangeRate.tofloat | format_currency(entity.isoCode, {fraction_digit: 5}) }}<br>
{{ '1'|format_currency(entity.isoCode) }} = {{ entity.exchangeRate.tofloat | format_currency(vars.base_currency(), {fraction_digit: 5}) }}
</p>

View file

@ -28,7 +28,7 @@
{% block additional_panes %}
<div class="tab-pane" id="eda">
<div class="row">
<div class="col-sm-9 offset-sm-3">
<div class="{{ col_input }} {{ offset_label }}">
<h6>{% trans %}eda_info.kicad_section.title{% endtrans %}:</h6>
</div>
</div>

View file

@ -27,7 +27,7 @@
{{ form_row(form.options.supported_element) }}
<div class="mb-2 row">
{{ form_label(form.options.width) }}
<div class="col-sm-9">
<div class="{{ col_input }}">
<div class="input-group">
{{ form_widget(form.options.width) }}

View file

@ -31,8 +31,8 @@
{{ form_row(form.status) }}
{% if entity.id %}
<div class="mb-2 row">
<label class="col-form-label col-sm-3">{% trans %}project.edit.associated_build_part{% endtrans %}</label>
<div class="col-sm-9">
<label class="col-form-label {{ col_label }}">{% trans %}project.edit.associated_build_part{% endtrans %}</label>
<div class="{{ col_input }}">
{% if entity.buildPart %}
<span class="form-control-static"><a href="{{ entity_url(entity.buildPart) }}">{{ entity.buildPart.name }}</a></span>
{% else %}

View file

@ -8,7 +8,7 @@
{% block additional_controls %}
{% if entity.id %}
<div class="row form-group">
<div class="offset-sm-3 col-sm-9">
<div class="{{ offset_label }} {{ col_input }}">
{{ dropdown.profile_dropdown('storelocation', entity.id) }}
</div>
</div>

View file

@ -50,7 +50,7 @@
<div class="tab-pane" id="password">
{% if entity.samlUser %}
<div class="offset-3 mb-3 col-9">
<div class="mb-3 {{ offset_label }} {{ col_input }}">
<span class="badge badge-warning bg-warning"><i class="fa-solid fa-house-user"></i> {% trans %}user.saml_user{% endtrans %}</span>
</div>
{% endif %}
@ -60,7 +60,7 @@
{{ form_row(form.disabled) }}
{% if entity.id is not null %}
<div class="offset-3 mb-3">
<div class="{{ offset_label }} {{ col_input }} mb-3">
<hr>
<h6>{% trans %}user.edit.tfa.caption{% endtrans %}</h6>

View file

@ -44,7 +44,7 @@
{{ form_row(filterForm.discard) }}
<div class="row mb-3">
<div class="col-sm-9 offset-sm-3">
<div class="{{ col_input }} {{ offset_label }}">
<button type="button" class="btn btn-danger" {{ stimulus_action('helpers/form_cleanup', 'clearAll') }}>{% trans %}filter.clear_filters{% endtrans %}</button>
</div>
</div>

View file

@ -63,8 +63,8 @@
<div class="">
{{ form_row(form.mountnames) }}
<div class="row mb-2">
<label class="col-form-label col-sm-3">{% trans %}project.bom.price{% endtrans %}</label>
<div class="col-sm-9">
<label class="col-form-label {{ col_label }}">{% trans %}project.bom.price{% endtrans %}</label>
<div class="{{ col_input }}">
<div class="input-group">
{{ form_widget(form.price) }}
{{ form_widget(form.priceCurrency) }}

View file

@ -17,11 +17,11 @@
{% block form_label_class -%}
col-sm-3
{{ col_label }}
{%- endblock form_label_class %}
{% block form_group_class -%}
col-sm-9
{{ col_input }}
{%- endblock form_group_class %}
{% block si_unit_widget %}

View file

@ -12,7 +12,7 @@
{% endblock %}
{% block card_content %}
<p class="text-muted offset-3">{% trans %}info_providers.from_url.help{% endtrans %}</p>
<p class="text-muted {{ offset_label }}">{% trans %}info_providers.from_url.help{% endtrans %}</p>
{{ form_start(form) }}
{{ form_row(form.url) }}

View file

@ -28,7 +28,7 @@
{{ form_row(form.providers) }}
<div class="row mb-2">
<div class="col-sm-9 offset-sm-3">
<div class="{{ col_input }} {{ offset_label }}">
<a href="{{ path('info_providers_list') }}">{% trans %}info_providers.search.info_providers_list{% endtrans %}</a>
</div>
</div>

View file

@ -8,7 +8,7 @@
{% block card_title %}<i class="fa-solid fa-gear fa-fw"></i> {% trans %}info_providers.settings.title{% endtrans %}: <b>{{ info_provider_info.name }}</b>{% endblock %}
{% block card_content %}
<div class="offset-sm-3">
<div class="{{ offset_label }}">
<h3>
{% if info_provider_info.url is defined %}
<a href="{{ info_provider_info.url }}" class="link-external" target="_blank" rel="nofollow">{{ info_provider_info.name }}</a>
@ -23,7 +23,7 @@
{{ form_start(form) }}
<div class="row">
<div class="offset-sm-3 col mb-3 ps-2">
<div class="{{ offset_label }} col mb-3 ps-2">
<b>{{ form_help(form) }}</b>
</div>
</div>

View file

@ -36,7 +36,7 @@
{{ form_row(form.options.supported_element) }}
<div class="mb-2 row">
{{ form_label(form.options.width) }}
<div class="col-sm-9">
<div class="{{ col_input }}">
<div class="input-group">
{{ form_widget(form.options.width) }}
@ -59,8 +59,8 @@
<div class="tab-pane" id="profiles" role="tabpanel" aria-labelledby="profiles-tab">
<div class="form-group row">
<label class="col-sm-3 col-form-label">{% trans %}label_generator.selected_profile{% endtrans %}</label>
<div class="col-sm-9">
<label class="{{ col_label }} col-form-label">{% trans %}label_generator.selected_profile{% endtrans %}</label>
<div class="{{ col_input }}">
<span class="form-control-plaintext">{{ profile.name ?? '-' }}
{% if profile and is_granted("edit", profile) %}
<a href="{{ entity_url(profile, 'edit') }}" title="{% trans %}label_generator.edit_profile{% endtrans %}"
@ -71,7 +71,7 @@
</div>
<div class="form-group row">
<div class="offset-sm-3 col-sm-9">
<div class="{{ offset_label }} {{ col_input }}">
<div class="dropdown">
<button class="btn btn-info dropdown-toggle" type="button" id="loadProfilesButton"
{% if not is_granted("@labels.create_labels") %}disabled{% endif %}
@ -97,7 +97,7 @@
{% if is_granted("@labels.read_profiles") %}
<div class="form-group row">
<div class="offset-sm-3 col-sm-9">
<div class="{{ offset_label }} {{ col_input }}">
<a class="btn btn-link" href="{{ path('label_profile_new') }}">{% trans %}label_generator.edit_profiles{% endtrans %}</a>
</div>
</div>
@ -108,7 +108,7 @@
{% endif %}
<div class="form-group row">
<div class="offset-sm-3 col-sm-9">
<div class="{{ offset_label }} {{ col_input }}">
<div class="input-group">
{{ form_widget(form.save_profile_name) }}
{{ form_widget(form.save_profile) }}
@ -124,7 +124,7 @@
{{ form_end(form) }}
{% if pdf_data %}
<div class="row">
<div class="col-sm-9 offset-sm-3">
<div class="{{ col_input }} {{ offset_label }}">
<a data-turbo="false" class="btn btn-secondary" href="#" {{ stimulus_controller('pages/label_download_btn')}} {{ stimulus_action('pages/label_download_btn', 'download')}} download="{{ filename ?? '' }}">
{% trans %}label_generator.download{% endtrans %}
</a>

View file

@ -9,7 +9,7 @@
<div class="">
<div class="form-group row">
<div class="offset-sm-3 col-sm-9">
<div class="{{ offset_label }} {{ col_input }}">
<div class="img-thumbnail" style="max-width: 600px;">
<div id="reader-box" {{ stimulus_controller('pages/barcode_scan') }}></div>
</div>

View file

@ -40,7 +40,7 @@
{{ form_row(filterForm.discard) }}
<div class="row mb-3">
<div class="col-sm-9 offset-sm-3">
<div class="{{ col_input }} {{ offset_label }}">
<button type="button" class="btn btn-danger" {{ stimulus_action('helpers/form_cleanup', 'clearAll') }}>{% trans %}filter.clear_filters{% endtrans %}</button>
</div>
</div>

View file

@ -4,7 +4,7 @@
{{ form_row(form.eda_info.visibility) }}
<div class="row mb-2">
<div class="col-sm-9 offset-sm-3">
<div class="{{ col_input }} {{ offset_label }}">
{{ form_widget(form.eda_info.exclude_from_bom) }}
{{ form_widget(form.eda_info.exclude_from_board) }}
{{ form_widget(form.eda_info.exclude_from_sim) }}
@ -12,7 +12,7 @@
</div>
<div class="row">
<div class="col-sm-9 offset-sm-3">
<div class="{{ col_input }} {{ offset_label }}">
<h6>{% trans %}eda_info.kicad_section.title{% endtrans %}:</h6>
</div>
</div>

View file

@ -1,7 +1,7 @@
{{ form_row(form.name) }}
{% if part.category is not null and part.category.partnameHint is not empty %}
<div class="row">
<div class="col-sm-9 offset-sm-3">
<div class="{{ col_input }} {{ offset_label }}">
<p class="form-text help-text"><b>{% trans %}part.edit.name.category_hint{% endtrans %}:</b> {{ part.category.partnameHint }}</p>
</div>
</div>

View file

@ -107,7 +107,7 @@
{% set id = 'collapse_' ~ random() %}
<a class="btn btn-link offset-sm-3 btn-sm" data-bs-toggle="collapse" href="#{{ id }}" role="button" aria-expanded="false" aria-controls="{{ id }}">
<a class="btn btn-link {{ offset_label }} btn-sm" data-bs-toggle="collapse" href="#{{ id }}" role="button" aria-expanded="false" aria-controls="{{ id }}">
{% trans %}part_lot.edit.advanced{% endtrans %}
</a>
<div class="collapse" id="{{ id }}">
@ -142,7 +142,7 @@
<div class="mb-2 row">
{{ form_label(form.file) }}
<div class="col-sm-9">
<div class="{{ col_input }}">
{{ form_widget(form.file) }}
{{ form_errors(form.file) }}
<small class="text-muted">{% trans %}attachment.max_file_size{% endtrans %}: {{ max_upload_size | format_bytes }}</small>

View file

@ -140,7 +140,7 @@
</div>
<div class="form-group row">
<div class="col-sm-9 offset-sm-3">
<div class="{{ col_input }} {{ offset_label }}">
<div class="btn-group">
{{ form_widget(form.save) }}
<button type="button" class="btn btn-primary dropdown-toggle dropdown-toggle-split" data-bs-toggle="dropdown" aria-haspopup="true" aria-expanded="false">

View file

@ -25,7 +25,7 @@
{% endblock %}
{% block card_content %}
<p class="text-muted offset-sm-3">
<p class="text-muted {{ offset_label }}">
{% trans %}parts.import.help{% endtrans %}<br>
{% trans with {'%link%': 'https://docs.part-db.de/usage/import_export.html'} %}parts.import.help_documentation{% endtrans %}
</p>

View file

@ -13,39 +13,39 @@
<input type="hidden" name="_redirect" value="{{ uri_without_host(app.request) }}">
<div class="row mb-2">
<label class="col-form-label col-sm-3">
<label class="col-form-label {{ col_label }}">
{% trans %}part.info.stocktake_modal.expected_amount{% endtrans %}
</label>
<div class="col-sm-9">
<div class="{{ col_input }}">
<span id="stocktake-modal-expected-amount" class="form-control-plaintext">0</span>
</div>
</div>
<div class="row mb-2">
<label class="col-form-label col-sm-3">
<label class="col-form-label {{ col_label }}">
{% trans %}part.info.stocktake_modal.actual_amount{% endtrans %}
</label>
<div class="col-sm-9">
<div class="{{ col_input }}">
<input type="number" required class="form-control" min="0" step="{{ (part.partUnit and not part.partUnit.integer) ? 'any' : '1' }}" name="actual_amount" value="">
</div>
</div>
<div class="row mb-2">
<label class="col-form-label col-sm-3">
<label class="col-form-label {{ col_label }}">
{% trans %}part.info.withdraw_modal.comment{% endtrans %}
</label>
<div class="col-sm-9">
<div class="{{ col_input }}">
<input type="text" class="form-control" name="comment" value="">
<div class="form-text">{% trans %}part.info.withdraw_modal.comment.hint{% endtrans %}</div>
</div>
</div>
<div class="row mb-2">
<label class="col-form-label col-sm-3">
<label class="col-form-label {{ col_label }}">
{% trans %}part.info.withdraw_modal.timestamp{% endtrans %}
</label>
<div class="col-sm-9">
<div class="{{ col_input }}">
{# The timestamp must be between a year ago and 1 hour in the future #}
<input type="datetime-local" class="form-control" name="timestamp" value=""
max="{{ "+10mins"|date('Y-m-d\\TH:i') }}" min="{{ "-1year"|date('Y-m-d\\TH:i') }}">

View file

@ -18,17 +18,17 @@
<input type="hidden" name="_redirect" value="{{ uri_without_host(app.request) }}">
<div class="row mb-2">
<label class="col-form-label col-sm-3">
<label class="col-form-label {{ col_label }}">
{% trans %}part.info.withdraw_modal.amount{% endtrans %}
</label>
<div class="col-sm-9">
<div class="{{ col_input }}">
<input type="number" required class="form-control" min="0" step="{{ (part.partUnit and not part.partUnit.integer) ? 'any' : '1' }}" name="amount" value="">
</div>
</div>
<div class="row mb-2 d-none" id="withdraw-modal-move-to">
<label class="col-form-label col-sm-3">{% trans %}part.info.withdraw_modal.move_to{% endtrans %}</label>
<div class="col-sm-9">
<label class="col-form-label {{ col_label }}">{% trans %}part.info.withdraw_modal.move_to{% endtrans %}</label>
<div class="{{ col_input }}">
{% for lots in part.partLots|filter(l => l.instockUnknown == false) %}
<div class="form-check">
@ -42,20 +42,20 @@
</div>
<div class="row mb-2">
<label class="col-form-label col-sm-3">
<label class="col-form-label {{ col_label }}">
{% trans %}part.info.withdraw_modal.comment{% endtrans %}
</label>
<div class="col-sm-9">
<div class="{{ col_input }}">
<input type="text" class="form-control" name="comment" value="" {% if event_comment_needed('part_stock_operation') %}required{% endif %}>
<div id="emailHelp" class="form-text">{% trans %}part.info.withdraw_modal.comment.hint{% endtrans %}</div>
</div>
</div>
<div class="row mb-2">
<label class="col-form-label col-sm-3">
<label class="col-form-label {{ col_label }}">
{% trans %}part.info.withdraw_modal.timestamp{% endtrans %}
</label>
<div class="col-sm-9">
<div class="{{ col_input }}">
{# The timestamp must be between a year ago and 1 hour in the future #}
<input type="datetime-local" class="form-control" name="timestamp" value=""
max="{{ "+10mins"|date('Y-m-d\\TH:i') }}" min="{{ "-1year"|date('Y-m-d\\TH:i') }}">
@ -64,7 +64,7 @@
</div>
<div class="row mb-2">
<div class="col-sm-9 offset-sm-3">
<div class="{{ col_input }} {{ offset_label }}">
{# The timestamp must be between a year ago and 1 hour in the future #}
<div class="form-check">
<input class="form-check-input" type="checkbox" name="delete_lot_if_empty" value="true" id="withdraw_modal_delete_if_empty">

View file

@ -148,7 +148,7 @@
{{ form_row(filterForm.discard) }}
<div class="row mb-3">
<div class="col-sm-9 offset-sm-3">
<div class="{{ col_input }} {{ offset_label }}">
<button type="button" class="btn btn-danger" {{ stimulus_action('helpers/form_cleanup', 'clearAll') }}>{% trans %}filter.clear_filters{% endtrans %}</button>
</div>
</div>

View file

@ -33,7 +33,7 @@
{% if displayTrustedOption %}
<div class="form-group row mt-3">
<div class="offset-3">
<div class="{{ offset_label }} {{ col_input }}">
<div class="custom-checkbox custom-control ms-2">
<input id="_trusted" class="form-check-input" type="checkbox" name="{{ trustedParameterName }}" />
<label class="form-check-label" for="_trusted">{% trans %}tfa.code.trusted_pc{% endtrans %}</label>
@ -48,11 +48,11 @@
{% block submit_btn %}
<div class="form-group-row">
<div class="offset-3">
<div class="{{ offset_label }} {{ col_input }}">
<button type="submit" class="btn btn-primary" value="{{ "login"|trans({}, 'SchebTwoFactorBundle') }}">{% trans %}login.btn{% endtrans %}</button>
<a class="ms-2" href="{{ logoutPath }}">{% trans %}user.logout{% endtrans %}</a>
</div>
</div>
{% endblock %}
</form>
{% endblock %}
{% endblock %}

View file

@ -22,7 +22,7 @@
{% block card_content %}
{% if saml_enabled %}
<div class="col-md-9 offset-md-3 col-lg-10 offset-lg-2">
<div class="{{ offset_label }} {{ col_input }}">
<a class="btn btn-secondary" href="{{ path('saml_login') }}"><i class="fa-solid fa-house-user"></i> {% trans %}login.sso_saml_login{% endtrans %}</a>
<p class="text-muted">{% trans %}login.local_login_hint{% endtrans %}</p>
@ -39,6 +39,6 @@
{{ form_end(form) }}
{% if allow_email_pw_reset %}
<a class="offset-sm-2" href="{{ path('pw_reset_request') }}">{% trans %}pw_reset.password_forget{% endtrans %}</a>
<a class="{{ offset_label }}" href="{{ path('pw_reset_request') }}">{% trans %}pw_reset.password_forget{% endtrans %}</a>
{% endif %}
{% endblock %}

View file

@ -38,12 +38,12 @@
{% if section_widget.vars.embedded_settings_metadata is defined %} {# Check if we have nested embedded settings or not #}
<fieldset>
<legend class="offset-3">
<legend class="{{ offset_label }}">
<i class="fa-solid {{ settings_icon(settings_object)|default('fa-sliders') }} fa-fw"></i>
{{ (section_widget.vars.label ?? section_widget.vars.name|humanize)|trans }}
</legend>
<div class="row">
<div class="offset-sm-3 col mb-3 ps-2">
<div class="{{ offset_label }} col mb-3 ps-2">
<b>{{ form_help(section_widget) }}</b>
{{ form_errors(section_widget) }}
</div>

View file

@ -37,11 +37,11 @@
{{ form_start(google_form, { 'attr': google_form_attr}) }}
{% if not tfa_google.enabled %}
<div class="offset-sm-3">
<div class="{{ offset_label }}">
<h6>{% trans %}tfa_google.disabled_message{% endtrans %}</h6>
</div>
<div class="offset-sm-3 row">
<div class="{{ offset_label }} row">
<div class="col-sm-3">
<img width="100%" class="img-fluid bg-white p-2" alt="{{ tfa_google.qrContent }}" src="{{ barcode_svg(tfa_google.qrContent) | data_uri("image/svg+xml") }}">
</div>
@ -55,7 +55,7 @@
</div>
</div>
<div class="offset-sm-3">
<div class="{{ offset_label }}">
<button class="btn btn-link" type="button" data-bs-toggle="collapse" data-bs-target="#manualSetupCollapse" aria-expanded="false" aria-controls="manualSetupCollapse">
{% trans %}tfa_google.manual_setup{% endtrans %}
</button>
@ -72,7 +72,7 @@
{{ form_row(google_form.google_confirmation) }}
{% else %}
<div class="offset-sm-3">
<div class="{{ offset_label }}">
<h6>{% trans %}tfa_google.enabled_message{% endtrans %}</h6>
</div>
{% endif %}
@ -81,7 +81,7 @@
</div>
<div class="tab-pane fade" id="tfa-backup" role="tabpanel" aria-labelledby="backup-tab">
{% if user.backupCodes is empty %}
<div class="offset-sm-3">
<div class="{{ offset_label }}">
<h6>{% trans %}tfa_backup.disabled{% endtrans %}</h6>
<span>{% trans %}tfa_backup.explanation{% endtrans %}</span>
</div>
@ -89,19 +89,19 @@
{% set backup_form_attr = { 'data-delete-form': true, 'data-controller': 'elements--delete-btn', 'data-action': 'submit->elements--delete-btn#submit',
'data-delete-title': 'tfa_backup.reset_codes.confirm_title' | trans, 'data-delete-message': 'tfa_backup.reset_codes.confirm_message' | trans} %}
{{ form_start(backup_form, { 'attr': backup_form_attr}) }}
<div class="offset-sm-3">
<div class="{{ offset_label }}">
<h6>{% trans %}tfa_backup.enabled{% endtrans %}</h6>
<span>{% trans %}tfa_backup.explanation{% endtrans %}</span>
</div>
<div class="offset-sm-3 mt-2">
<div class="{{ offset_label }} mt-2">
<p class="mb-0"><b>{% trans %}tfa_backup.remaining_tokens{% endtrans %}:</b> {{ user.backupCodes | length }}</p>
<p><b>{% trans %}tfa_backup.generation_date{% endtrans %}:</b> {{ user.backupCodesGenerationDate | format_datetime }}</p>
</div>
<div class="offset-sm-3">
<div class="{{ offset_label }}">
<a href="{{ path('show_backup_codes') }}" target="_blank" data-turbo="false" class="btn btn-primary">{% trans %}tfa_backup.show_codes{% endtrans %}</a>
</div>
<div class="offset-sm-3 mt-2">
<div class="{{ offset_label }} mt-2">
{{ form_widget(backup_form.reset_codes) }}
</div>
{{ form_end(backup_form) }}

View file

@ -28,7 +28,7 @@
{{ form_row(settings_form.showEmailOnProfile) }}
{{ form_row(settings_form.avatar_file) }}
<div class="mb-3 row {% if user.masterPictureAttachment is null %}d-none{% endif %}">
<div class="offset-sm-3 col-sm-9">
<div class="{{ offset_label }} {{ col_input }}">
{% if user.masterPictureAttachment %}
<img src="{{ attachment_thumbnail(user.masterPictureAttachment, 'thumbnail_md') }}" alt="avatar" class="rounded" style="height: 75px;">
{% endif %}