Added an modal form on the part info page, to merge a part into another one

This commit is contained in:
Jan Böhmer 2023-11-22 22:50:25 +01:00
parent b0f5d9b55f
commit 73f6d79925
4 changed files with 167 additions and 1 deletions

View file

@ -0,0 +1,68 @@
/*
* This file is part of Part-DB (https://github.com/Part-DB/Part-DB-symfony).
*
* Copyright (C) 2019 - 2023 Jan Böhmer (https://github.com/jbtronics)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published
* by the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
import {Controller} from "@hotwired/stimulus";
export default class extends Controller
{
static targets = ['link', 'mode', 'otherSelect'];
static values = {
targetId: Number,
};
connect() {
}
update() {
const link = this.linkTarget;
const other_select = this.otherSelectTarget;
//Extract the mode using the mode radio buttons (we filter the array to get the checked one)
const mode = (this.modeTargets.filter((e)=>e.checked))[0].value;
if (other_select.value === '') {
link.classList.add('disabled');
return;
}
//Extract href template from data attribute on link target
let href = link.getAttribute('data-href-template');
let target, other;
if (mode === '1') {
target = this.targetIdValue;
other = other_select.value;
} else if (mode === '2') {
target = other_select.value;
other = this.targetIdValue;
} else {
throw 'Invalid mode';
}
//Replace placeholder with actual target id
href = href.replace('__target__', target);
//Replace placeholder with selected value of the select (the event sender)
href = href.replace('__other__', other);
//Assign new href to link
link.setAttribute('href', href);
//Make link clickable
link.classList.remove('disabled');
}
}

View file

@ -0,0 +1,65 @@
{# Merge modal #}
{% if is_granted('edit', part) %}
<br>
<button type="button" class="btn btn-info mt-2" data-bs-toggle="modal" data-bs-target="#merge-modal">
<i class="fas fa-code-merge" aria-hidden="true"></i> {% trans %}part.info.merge_btn{% endtrans %}
</button>
{% endif %}
<div class="modal fade" id="merge-modal" tabindex="-1" aria-labelledby="merge-modal-title" tabindex="-1" aria-hidden="true" {{ stimulus_controller('pages/part_withdraw_modal') }}>
<div class="modal-dialog">
<div class="modal-content" {{ stimulus_controller('pages/part_merge_modal', {'targetId': part.iD }) }}>
<div class="modal-header">
<h1 class="modal-title fs-5" id="merge-modal-title">{% trans %}part.info.merge_modal.title{% endtrans %}</h1>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
{# non visible form elements #}
<input type="hidden" name="lot_id" value="">
<input type="hidden" name="_redirect" value="{{ app.request.baseUrl ~ app.request.requestUri }}">
<div class="row mb-2">
<label class="form-label">
{% trans %}part.info.merge_modal.other_part{% endtrans %}:
</label>
<select class="form-select" {{ stimulus_controller('elements/part_select') }}
data-autocomplete="{{ path('typeahead_parts', {'query': '__QUERY__'}) }}"
{{ stimulus_target('pages/part_merge_modal', 'otherSelect') }}
{{ stimulus_action('pages/part_merge_modal', 'update', 'change') }}
>
{# Filled by stimulus controller #}
</select>
</div>
<div class="mb2">
<div class="form-check">
<input class="form-check-input" type="radio" name="mergeModalMode" id="mergeModalMode_1"
{{ stimulus_target('pages/part_merge_modal', 'mode') }}
{{ stimulus_action('pages/part_merge_modal', 'update', 'change') }}
value="1">
<label class="form-check-label" for="mergeModalMode_1">
{% trans %}part.info.merge_modal.other_into_this{% endtrans %}
</label>
</div>
<div class="form-check">
<input class="form-check-input" type="radio" name="mergeModalMode" id="mergeModalMode_2"
{{ stimulus_target('pages/part_merge_modal', 'mode') }}
{{ stimulus_action('pages/part_merge_modal', 'update', 'change') }}
value="2" checked>
<label class="form-check-label" for="mergeModalMode_2">
{% trans %}part.info.merge_modal.this_into_other{% endtrans %}
</label>
</div>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">{% trans %}modal.close{% endtrans %}</button>
<a class="btn btn-primary disabled" {{ stimulus_target('pages/part_merge_modal', 'link') }}
data-href-template="{{ path('part_merge', {'target': '__target__', 'other': '__other__'}) }}"
>{% trans %}modal.submit{% endtrans %}</a>
</div>
</div>
</div>
</div>

View file

@ -7,7 +7,7 @@
</a>
{% endif %}
{# Create new button #}
{% if is_granted('create', part) %}
<br>
<div class="btn-group mt-2">
@ -27,6 +27,9 @@
</div>
{% endif %}
{# Merge modal #}
{% include "parts/info/_merge_modal.html.twig" %}
<form method="post" class="mt-2" action="{{ entity_url(part, 'delete') }}"
{{ stimulus_controller('elements/delete_btn') }} {{ stimulus_action('elements/delete_btn', "submit", "submit") }}
data-delete-title="{% trans with {'%name%': part.name|escape }%}part.delete.confirm_title{% endtrans %}"

View file

@ -11993,5 +11993,35 @@ Please note, that you can not impersonate a disabled user. If you try you will g
<target><![CDATA[<b>%other%</b> will be deleted, and the part will be saved with the shown information.]]></target>
</segment>
</unit>
<unit id="BY9.T4F" name="part.info.merge_modal.title">
<segment>
<source>part.info.merge_modal.title</source>
<target>Merge parts</target>
</segment>
</unit>
<unit id="CasQeyD" name="part.info.merge_modal.other_part">
<segment>
<source>part.info.merge_modal.other_part</source>
<target>Other part</target>
</segment>
</unit>
<unit id="96Qzc6H" name="part.info.merge_modal.other_into_this">
<segment>
<source>part.info.merge_modal.other_into_this</source>
<target>Merge other part into this one (delete other part, keep this one)</target>
</segment>
</unit>
<unit id="Oe4cpRH" name="part.info.merge_modal.this_into_other">
<segment>
<source>part.info.merge_modal.this_into_other</source>
<target>Merge this part into other one (delete this part, keep other one)</target>
</segment>
</unit>
<unit id="pO3q5CN" name="part.info.merge_btn">
<segment>
<source>part.info.merge_btn</source>
<target>Merge part</target>
</segment>
</unit>
</file>
</xliff>