Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
70 changes: 70 additions & 0 deletions assets/controllers/elements/assembly_select_controller.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
import {Controller} from "@hotwired/stimulus";

import "tom-select/dist/css/tom-select.bootstrap5.css";
import '../../css/components/tom-select_extensions.css';
import TomSelect from "tom-select";
import {marked} from "marked";

export default class extends Controller {
_tomSelect;

connect() {

let settings = {
allowEmptyOption: true,
plugins: ['dropdown_input', 'clear_button'],
searchField: ["name", "description", "category", "footprint"],
valueField: "id",
labelField: "name",
preload: "focus",
render: {
item: (data, escape) => {
return '<span>' + (data.image ? "<img style='height: 1.5rem; margin-right: 5px;' ' src='" + data.image + "'/>" : "") + escape(data.name) + '</span>';
},
option: (data, escape) => {
if(data.text) {
return '<span>' + escape(data.text) + '</span>';
}

let tmp = '<div class="row m-0">' +
"<div class='col-2 p-0 d-flex align-items-center' style='max-width: 80px;'>" +
(data.image ? "<img class='typeahead-image' src='" + data.image + "'/>" : "") +
"</div>" +
"<div class='col-10'>" +
'<h6 class="m-0">' + escape(data.name) + '</h6>' +
(data.description ? '<p class="m-0">' + marked.parseInline(data.description) + '</p>' : "") +
(data.category ? '<p class="m-0"><span class="fa-solid fa-tags fa-fw"></span> ' + escape(data.category) : "");

return tmp + '</p>' +
'</div></div>';
}
}
};


if (this.element.dataset.autocomplete) {
const base_url = this.element.dataset.autocomplete;
settings.valueField = "id";
settings.load = (query, callback) => {
const url = base_url.replace('__QUERY__', encodeURIComponent(query));

fetch(url)
.then(response => response.json())
.then(json => {callback(json);})
.catch(() => {
callback()
});
};


this._tomSelect = new TomSelect(this.element, settings);
//this._tomSelect.clearOptions();
}
}

disconnect() {
super.disconnect();
//Destroy the TomSelect instance
this._tomSelect.destroy();
}
}
2 changes: 1 addition & 1 deletion assets/controllers/elements/part_select_controller.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ export default class extends Controller {

let settings = {
allowEmptyOption: true,
plugins: ['dropdown_input'],
plugins: ['dropdown_input', 'clear_button'],
searchField: ["name", "description", "category", "footprint"],
valueField: "id",
labelField: "name",
Expand Down
62 changes: 62 additions & 0 deletions assets/controllers/elements/toggle_visibility_controller.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
import { Controller } from "@hotwired/stimulus";

export default class extends Controller {

static values = {
classes: Array
};

connect() {
this.displayCheckbox = this.element.querySelector("#display");
this.displaySelect = this.element.querySelector("select#display");

if (this.displayCheckbox) {
this.toggleContainers(this.displayCheckbox.checked);

this.displayCheckbox.addEventListener("change", (event) => {
this.toggleContainers(event.target.checked);
});
}

if (this.displaySelect) {
this.toggleContainers(this.hasDisplaySelectValue());

this.displaySelect.addEventListener("change", () => {
this.toggleContainers(this.hasDisplaySelectValue());
});
}

}

/**
* Check whether a value was selected in the selectbox
* @returns {boolean} True when a value has not been selected that is not empty
*/
hasDisplaySelectValue() {
return this.displaySelect && this.displaySelect.value !== "";
}

/**
* Hides specified containers if the state is active (checkbox checked or select with value).
*
* @param {boolean} isActive - True when the checkbox is activated or the selectbox has a value.
*/
toggleContainers(isActive) {
if (!Array.isArray(this.classesValue) || this.classesValue.length === 0) {
return;
}

this.classesValue.forEach((cssClass) => {
const elements = document.querySelectorAll(`.${cssClass}`);

if (!elements.length) {
return;
}

elements.forEach((element) => {
element.style.display = isActive ? "none" : "";
});
});
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ export default class extends Controller {

connect() {
//Add event listener to the checkbox
this.getCheckbox().addEventListener('change', this.toggleInputLimits.bind(this));
this.getCheckbox()?.addEventListener('change', this.toggleInputLimits.bind(this));
}

toggleInputLimits() {
Expand Down
5 changes: 5 additions & 0 deletions assets/css/app/images.css
Original file line number Diff line number Diff line change
Expand Up @@ -61,3 +61,8 @@
.object-fit-cover {
object-fit: cover;
}

.assembly-table-image {
max-height: 40px;
object-fit: contain;
}
7 changes: 6 additions & 1 deletion assets/js/lib/datatables.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,12 @@
//CHANGED jbtronics: Preserve the get parameters (needed so we can pass additional params to query)
$.fn.initDataTables.defaults.url = window.location.origin + window.location.pathname + window.location.search;

$.fn.dataTable.ext.errMode = function(settings, helpPage, message) {
if (message.includes('ColReorder')) {
console.warn('ColReorder does not fit the number of columns', message);
}
};

var root = this,
config = $.extend({}, $.fn.initDataTables.defaults, config),
state = ''
Expand Down Expand Up @@ -105,7 +111,6 @@
}
}


root.html(data.template);
dt = $('table', root).DataTable(dtOpts);
if (config.state !== 'none') {
Expand Down
4 changes: 4 additions & 0 deletions config/permissions.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,10 @@ perms: # Here comes a list with all Permission names (they have a perm_[name] co
<<: *PART_CONTAINING
label: "perm.projects"

assemblies:
<<: *PART_CONTAINING
label: "perm.assemblies"

attachment_types:
<<: *PART_CONTAINING
label: "perm.part.attachment_types"
Expand Down
3 changes: 3 additions & 0 deletions config/services.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,9 @@ services:
arguments:
$saml_enabled: '%partdb.saml.enabled%'

App\Validator\Constraints\AssemblySystem\AssemblyCycleValidator:
tags: [ 'validator.constraint_validator' ]

####################################################################################################################
# Table settings
####################################################################################################################
Expand Down
7 changes: 7 additions & 0 deletions docs/configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,13 @@ bundled with Part-DB. Set `DATABASE_MYSQL_SSL_VERIFY_CERT` if you want to accept
time).
Also specify the default order of the columns. This is a comma separated list of column names. Available columns
are: `name`, `id`, `ipn`, `description`, `category`, `footprint`, `manufacturer`, `storage_location`, `amount`, `minamount`, `partUnit`, `addedDate`, `lastModified`, `needs_review`, `favorite`, `manufacturing_status`, `manufacturer_product_number`, `mass`, `tags`, `attachments`, `edit`.
* `TABLE_ASSEMBLIES_DEFAULT_COLUMNS`: The columns in assemblies tables, which are visible by default (when loading table for first time).
Also specify the default order of the columns. This is a comma separated list of column names. Available columns
are: `name`, `id`, `ipn`, `description`, `referencedAssemblies`, `edit`, `addedDate`, `lastModified`.
* `TABLE_ASSEMBLIES_BOM_DEFAULT_COLUMNS`: The columns in assemblies bom tables, which are visible by default (when loading table for first time).
Also specify the default order of the columns. This is a comma separated list of column names. Available columns
are: `quantity`, `name`, `id`, `ipn`, `description`, `category`, `footprint`, `manufacturer`, `designator`, `mountnames`, `storage_location`, `amount`, `addedDate`, `lastModified`.
* `CREATE_ASSEMBLY_USE_IPN_PLACEHOLDER_IN_NAME`: Use an %%ipn%% placeholder in the name of a assembly. Placeholder is replaced with the ipn input while saving.

### History/Eventlog-related settings

Expand Down
Loading