mirror of
https://github.com/Part-DB/Part-DB-server.git
synced 2025-06-21 01:25:55 +02:00
Use stimulus collection controller for parts orderdetails
This commit is contained in:
parent
66b7b2e9bf
commit
4847fe2fa3
8 changed files with 108 additions and 75 deletions
|
@ -30,6 +30,7 @@ export default class extends Controller {
|
||||||
return long.slice(0, 6); // 6 characters is enough for our unique IDs here
|
return long.slice(0, 6); // 6 characters is enough for our unique IDs here
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new entry in the target using the given prototype value
|
* Create a new entry in the target using the given prototype value
|
||||||
*/
|
*/
|
||||||
|
@ -50,6 +51,50 @@ export default class extends Controller {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Similar to createEvent Pricedetails need some special handling to fill min amount
|
||||||
|
* @param event
|
||||||
|
*/
|
||||||
|
createPricedetail(event) {
|
||||||
|
//First insert our new element
|
||||||
|
this.createElement(event);
|
||||||
|
|
||||||
|
const extractElementsFromRow = (row) => {
|
||||||
|
const priceRelated = row.querySelector("input[id$='price_related_quantity_value']");
|
||||||
|
const minDiscount = row.querySelector("input[id$='min_discount_quantity_value']");
|
||||||
|
|
||||||
|
return [priceRelated, minDiscount];
|
||||||
|
}
|
||||||
|
|
||||||
|
const targetTable = this.targetTarget;
|
||||||
|
const targetRows = targetTable.tBodies[0].rows;
|
||||||
|
const targetRowsCount = targetRows.length;
|
||||||
|
|
||||||
|
//If we just have one element we dont have to do anything as 1 is already the default
|
||||||
|
if(targetRowsCount <= 1) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Our new element is the last child of the table
|
||||||
|
const newlyCreatedRow = targetRows[targetRowsCount - 1];
|
||||||
|
const [newPriceRelated, newMinDiscount] = extractElementsFromRow(newlyCreatedRow);
|
||||||
|
|
||||||
|
const oldRow = targetRows[targetRowsCount - 2];
|
||||||
|
const [oldPriceRelated, oldMinDiscount] = extractElementsFromRow(oldRow);
|
||||||
|
|
||||||
|
//Use the old PriceRelated value to determine the next 10 decade value for the new row
|
||||||
|
const oldMinAmount = parseInt(oldMinDiscount.value)
|
||||||
|
//The next 10 power can be achieved by creating a string beginning with "1" and adding 0 times the length of the old string
|
||||||
|
const oldMinAmountLength = oldMinAmount.toString().length;
|
||||||
|
const newMinAmountStr = '1' + '0'.repeat(oldMinAmountLength);
|
||||||
|
//Parse the sting back to an integer and we have our new min amount
|
||||||
|
const newMinAmount = parseInt(newMinAmountStr);
|
||||||
|
|
||||||
|
|
||||||
|
//Assign it to our new element
|
||||||
|
newMinDiscount.value = newMinAmount;
|
||||||
|
}
|
||||||
|
|
||||||
deleteElement(event) {
|
deleteElement(event) {
|
||||||
bootbox.confirm(this.deleteMessageValue, (result) => {
|
bootbox.confirm(this.deleteMessageValue, (result) => {
|
||||||
if(result) {
|
if(result) {
|
||||||
|
|
|
@ -3,6 +3,7 @@ require('bootstrap-select/js/bootstrap-select'); // we have to manually require
|
||||||
|
|
||||||
import {Controller} from "@hotwired/stimulus";
|
import {Controller} from "@hotwired/stimulus";
|
||||||
import "bootstrap-select/dist/css/bootstrap-select.css";
|
import "bootstrap-select/dist/css/bootstrap-select.css";
|
||||||
|
import "../../css/selectpicker_extensions.css";
|
||||||
|
|
||||||
export default class extends Controller {
|
export default class extends Controller {
|
||||||
connect() {
|
connect() {
|
||||||
|
|
|
@ -857,17 +857,3 @@ div.dataTables_wrapper div.dataTables_info {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
/***********************************************
|
|
||||||
* Special level whitespace characters that only show up when inside a bootstrap-select dropdown
|
|
||||||
***********************************************/
|
|
||||||
.dropdown-item span.picker-level::after {
|
|
||||||
content: "\00a0\00a0\00a0"; /* 3 spaces */
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Bootstrap-select Hide on Selected element */
|
|
||||||
.picker-hs {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
.dropdown-item .picker-hs {
|
|
||||||
display: inherit;
|
|
||||||
}
|
|
14
assets/css/selectpicker_extensions.css
Normal file
14
assets/css/selectpicker_extensions.css
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
/***********************************************
|
||||||
|
* Special level whitespace characters that only show up when inside a bootstrap-select dropdown
|
||||||
|
***********************************************/
|
||||||
|
.dropdown-item span.picker-level::after {
|
||||||
|
content: "\00a0\00a0\00a0"; /* 3 spaces */
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Bootstrap-select Hide on Selected element */
|
||||||
|
.picker-hs {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
.dropdown-item .picker-hs {
|
||||||
|
display: inherit;
|
||||||
|
}
|
|
@ -1,7 +1,3 @@
|
||||||
{% set delete_btn %}
|
|
||||||
|
|
||||||
{% endset %}
|
|
||||||
|
|
||||||
{% form_theme form with ['Parts/edit/edit_form_styles.html.twig'] %}
|
{% form_theme form with ['Parts/edit/edit_form_styles.html.twig'] %}
|
||||||
{% import 'components/collection_type.macro.html.twig' as collection %}
|
{% import 'components/collection_type.macro.html.twig' as collection %}
|
||||||
|
|
||||||
|
|
|
@ -1,17 +1,21 @@
|
||||||
{% form_theme form with ['Parts/edit/edit_form_styles.html.twig', "bootstrap_4_layout.html.twig"] %}
|
{# Leave this template at bootstrap 4 for now, as it otherwise destroys our layout #}
|
||||||
|
{% form_theme form.orderdetails with ['Parts/edit/edit_form_styles.html.twig', "bootstrap_4_layout.html.twig"] %}
|
||||||
|
{% import 'components/collection_type.macro.html.twig' as collection %}
|
||||||
|
|
||||||
<table class="table table-striped table-sm table-responsive-md" id="orderdetails_table" data-prototype="{% if form.orderdetails.vars.prototype is defined %}{{ form_widget(form.orderdetails.vars.prototype)|e('html_attr') }}{% endif %}">
|
<div {{ collection.controller(form.orderdetails, 'orderdetails.edit.delete.confirm') }}>
|
||||||
<tbody>
|
<table class="table table-striped table-sm table-responsive-md" id="orderdetails_table" {{ collection.target() }}>
|
||||||
{% for detail in form.orderdetails %}
|
<tbody>
|
||||||
{{ form_widget(detail, {'disable_delete' : not is_granted('orderdetails.delete', part)}) }}
|
{% for detail in form.orderdetails %}
|
||||||
{% endfor %}
|
{{ form_widget(detail, {'disable_delete' : not is_granted('orderdetails.delete', part)}) }}
|
||||||
</tbody>
|
{% endfor %}
|
||||||
</table>
|
</tbody>
|
||||||
|
</table>
|
||||||
|
|
||||||
<button type="button" class="btn btn-success" onclick="create_orderdetail_entry(this)" {% if not is_granted('orderdetails.create', part) %}disabled{% endif %}>
|
<button type="button" class="btn btn-success" {{ collection.create_btn() }} {% if not is_granted('orderdetails.create', part) %}disabled{% endif %}>
|
||||||
<i class="fas fa-plus-square fa-fw"></i>
|
<i class="fas fa-plus-square fa-fw"></i>
|
||||||
{% trans %}orderdetail.create{% endtrans %}
|
{% trans %}orderdetail.create{% endtrans %}
|
||||||
</button>
|
</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
function delete_pricedetail_entry(btn) {
|
function delete_pricedetail_entry(btn) {
|
||||||
|
@ -40,7 +44,7 @@
|
||||||
var new_min_amount = $("input[id$='min_discount_quantity_value']" , $holder).last().val();
|
var new_min_amount = $("input[id$='min_discount_quantity_value']" , $holder).last().val();
|
||||||
//Assign a valid value, if no price are existing yet
|
//Assign a valid value, if no price are existing yet
|
||||||
if (typeof new_min_amount == "undefined") {
|
if (typeof new_min_amount == "undefined") {
|
||||||
new_min_amount = 0;
|
new_min_amount = 0;
|
||||||
}
|
}
|
||||||
new_min_amount = parseInt(new_min_amount) + 1;
|
new_min_amount = parseInt(new_min_amount) + 1;
|
||||||
//Determine the next exponent, 10 -> 100 -> 1000
|
//Determine the next exponent, 10 -> 100 -> 1000
|
||||||
|
@ -53,25 +57,4 @@
|
||||||
$("#" + price_related_id).val("1");
|
$("#" + price_related_id).val("1");
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function delete_orderdetail_entry(btn) {
|
|
||||||
window.bootbox.confirm('{% trans %}orderdetails.edit.delete.confirm{% endtrans %}', function (result) {
|
|
||||||
if(result) {
|
|
||||||
$(btn).parents("tr").remove();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function create_orderdetail_entry(btn) {
|
|
||||||
//Determine the table, so we can determine, how many entries there are already.
|
|
||||||
$holder = $("#orderdetails_table");
|
|
||||||
|
|
||||||
var index = $holder.children("tbody").children("tr").length;
|
|
||||||
var newForm = $holder.data("prototype");
|
|
||||||
|
|
||||||
//Increase the index
|
|
||||||
newForm = newForm.replace(/__name__/g, index);
|
|
||||||
|
|
||||||
$holder.children("tbody").append(newForm);
|
|
||||||
}
|
|
||||||
</script>
|
</script>
|
|
@ -1,5 +1,6 @@
|
||||||
{% block pricedetail_widget %}
|
{% block pricedetail_widget %}
|
||||||
{% form_theme form.currency 'Form/extendedBootstrap4_layout.html.twig' %}
|
{% form_theme form.currency 'Form/extendedBootstrap4_layout.html.twig' %}
|
||||||
|
{% import 'components/collection_type.macro.html.twig' as collection %}
|
||||||
|
|
||||||
<tr>
|
<tr>
|
||||||
<td>{{ form_widget(form.min_discount_quantity, {'attr': {'class': 'form-control-sm'}}) }} {{ form_errors(form.min_discount_quantity) }}</td>
|
<td>{{ form_widget(form.min_discount_quantity, {'attr': {'class': 'form-control-sm'}}) }} {{ form_errors(form.min_discount_quantity) }}</td>
|
||||||
|
@ -14,7 +15,7 @@
|
||||||
<td>{{ form_widget(form.price_related_quantity, {'attr': {'class': 'form-control-sm'}}) }} {{ form_errors(form.price_related_quantity) }}</td>
|
<td>{{ form_widget(form.price_related_quantity, {'attr': {'class': 'form-control-sm'}}) }} {{ form_errors(form.price_related_quantity) }}</td>
|
||||||
<td>
|
<td>
|
||||||
<button type="button" class="btn btn-danger order_btn_delete btn-sm" title="{% trans %}orderdetail.delete{% endtrans %}"
|
<button type="button" class="btn btn-danger order_btn_delete btn-sm" title="{% trans %}orderdetail.delete{% endtrans %}"
|
||||||
onclick="delete_pricedetail_entry(this);" {% if not is_granted('@parts_prices.delete') %}disabled{% endif %}>
|
{{ collection.delete_btn() }} {% if not is_granted('@parts_prices.delete') %}disabled{% endif %}>
|
||||||
<i class="fas fa-trash-alt fa-fw"></i>
|
<i class="fas fa-trash-alt fa-fw"></i>
|
||||||
</button>
|
</button>
|
||||||
{{ form_errors(form) }}
|
{{ form_errors(form) }}
|
||||||
|
@ -23,37 +24,40 @@
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block orderdetail_widget %}
|
{% block orderdetail_widget %}
|
||||||
|
{% import 'components/collection_type.macro.html.twig' as collection %}
|
||||||
<tr>
|
<tr>
|
||||||
<td>
|
<td>
|
||||||
{{ form_row(form.supplier, {'attr': {'class': 'form-control-sm'}}) }}
|
{{ form_row(form.supplier, {'attr': {'class': 'form-control-sm form-control'}}) }}
|
||||||
{{ form_row(form.supplierpartnr, {'attr': {'class': 'form-control-sm'}}) }}
|
{{ form_row(form.supplierpartnr, {'attr': {'class': 'form-control-sm'}}) }}
|
||||||
{{ form_row(form.supplier_product_url, {'attr': {'class': 'form-control-sm'}}) }}
|
{{ form_row(form.supplier_product_url, {'attr': {'class': 'form-control-sm'}}) }}
|
||||||
{{ form_widget(form.obsolete) }}
|
{{ form_widget(form.obsolete) }}
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<table class="table table-sm table-bordered" data-prototype="{% if form.pricedetails.vars.prototype is defined %}{{ form_widget(form.pricedetails.vars.prototype)|e('html_attr') }}{% endif %}">
|
<div {{ collection.controller(form.pricedetails, 'pricedetails.edit.delete.confirm') }}>
|
||||||
<thead>
|
<table class="table table-sm table-bordered" {{ collection.target() }}>
|
||||||
<tr>
|
<thead>
|
||||||
<th>{% trans %}pricedetails.edit.min_qty{% endtrans %}</th>
|
<tr>
|
||||||
<th>{% trans %}pricedetails.edit.price{% endtrans %}</th>
|
<th>{% trans %}pricedetails.edit.min_qty{% endtrans %}</th>
|
||||||
<th>{% trans %}pricedetails.edit.price_qty{% endtrans %}</th>
|
<th>{% trans %}pricedetails.edit.price{% endtrans %}</th>
|
||||||
<th></th>
|
<th>{% trans %}pricedetails.edit.price_qty{% endtrans %}</th>
|
||||||
</tr>
|
<th></th>
|
||||||
</thead>
|
</tr>
|
||||||
<tbody>
|
</thead>
|
||||||
{% for price in form.pricedetails %}
|
<tbody>
|
||||||
{{ form_widget(price) }}
|
{% for price in form.pricedetails %}
|
||||||
{% endfor %}
|
{{ form_widget(price) }}
|
||||||
</tbody>
|
{% endfor %}
|
||||||
</table>
|
</tbody>
|
||||||
|
</table>
|
||||||
|
|
||||||
<button type="button" class="btn btn-success" onclick="create_pricedetail_entry(this)" {% if not is_granted('@parts_prices.create') %}disabled{% endif %}>
|
<button type="button" class="btn btn-success" {{ collection.create_pricedetail_btn() }} {% if not is_granted('@parts_prices.create') %}disabled{% endif %}>
|
||||||
<i class="fas fa-plus-square fa-fw"></i>
|
<i class="fas fa-plus-square fa-fw"></i>
|
||||||
{% trans %}pricedetail.create{% endtrans %}
|
{% trans %}pricedetail.create{% endtrans %}
|
||||||
</button>
|
</button>
|
||||||
|
</div>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<button type="button" class="btn btn-danger order_btn_delete" onclick="delete_orderdetail_entry(this);" title="{% trans %}orderdetail.delete{% endtrans %}"
|
<button type="button" class="btn btn-danger order_btn_delete" {{ collection.delete_btn() }} title="{% trans %}orderdetail.delete{% endtrans %}"
|
||||||
{% if not is_granted('@parts_orderdetails.delete') %}disabled{% endif %}>
|
{% if not is_granted('@parts_orderdetails.delete') %}disabled{% endif %}>
|
||||||
<i class="fas fa-trash-alt fa-fw"></i>
|
<i class="fas fa-trash-alt fa-fw"></i>
|
||||||
</button>
|
</button>
|
||||||
|
@ -86,7 +90,7 @@
|
||||||
{% import 'components/collection_type.macro.html.twig' as collection %}
|
{% import 'components/collection_type.macro.html.twig' as collection %}
|
||||||
<tr>
|
<tr>
|
||||||
<td>
|
<td>
|
||||||
{{ form_widget(form) }}
|
{{ form_widget(form) }}
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
{% dump(form) %}
|
{% dump(form) %}
|
||||||
|
|
|
@ -13,6 +13,10 @@
|
||||||
{{ stimulus_action('elements/collection_type', 'createElement') }}
|
{{ stimulus_action('elements/collection_type', 'createElement') }}
|
||||||
{% endmacro %}
|
{% endmacro %}
|
||||||
|
|
||||||
|
{% macro create_pricedetail_btn() %}
|
||||||
|
{{ stimulus_action('elements/collection_type', 'createPricedetail') }}
|
||||||
|
{% endmacro %}
|
||||||
|
|
||||||
{% macro delete_btn() %}
|
{% macro delete_btn() %}
|
||||||
{{ stimulus_action('elements/collection_type', 'deleteElement') }}
|
{{ stimulus_action('elements/collection_type', 'deleteElement') }}
|
||||||
{% endmacro %}
|
{% endmacro %}
|
Loading…
Add table
Add a link
Reference in a new issue