Compare commits
No commits in common. '4e299630b684db777a703424050209873c37f0dc' and 'b890b8300fa7a06bdd253612264bfb36277701dd' have entirely different histories.
4e299630b6
...
b890b8300f
@ -1,18 +1,12 @@
|
|||||||
//region CSS
|
//region CSS
|
||||||
import './styles/app.scss';
|
import './styles/app.scss';
|
||||||
//endregion
|
//endregion
|
||||||
//region jQuery
|
|
||||||
import 'jqueryLocal'; // Declare $ as a global variable, accessible in all files
|
|
||||||
//endregion
|
|
||||||
//region Bootstrap
|
//region Bootstrap
|
||||||
import '@popperjs/core';
|
import 'bootstrap';
|
||||||
import {Tooltip} from 'bootstrap';
|
|
||||||
//region Tooltips
|
|
||||||
const tooltipTriggerList = document.querySelectorAll('[data-bs-toggle="tooltip"]');
|
|
||||||
[...tooltipTriggerList].map(tooltipTriggerEl => new Tooltip(tooltipTriggerEl));
|
|
||||||
//endregion
|
//endregion
|
||||||
|
//region jQuery
|
||||||
|
import 'jqueryLocal'; // Declare $ as a global variable, accessible in all files
|
||||||
//endregion
|
//endregion
|
||||||
//region FontAwesome
|
//region FontAwesome
|
||||||
import 'fontawesome';
|
import 'fontawesome';
|
||||||
//endregion
|
//endregion
|
||||||
import 'modalDynamic';
|
|
@ -1,15 +1,4 @@
|
|||||||
{
|
{
|
||||||
"controllers": {
|
"controllers": {},
|
||||||
"@symfony/ux-turbo": {
|
|
||||||
"turbo-core": {
|
|
||||||
"enabled": true,
|
|
||||||
"fetch": "eager"
|
|
||||||
},
|
|
||||||
"mercure-turbo-stream": {
|
|
||||||
"enabled": false,
|
|
||||||
"fetch": "eager"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"entrypoints": []
|
"entrypoints": []
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,148 @@
|
|||||||
|
//region Datatables.net
|
||||||
|
import 'datatables.net';
|
||||||
|
import 'datatables.net-dt/css/dataTables.dataTables.min.css';
|
||||||
|
//endregion
|
||||||
|
//region Bootstrap 5 styling for Datatables.net
|
||||||
|
import 'datatables.net-bs5';
|
||||||
|
import 'datatables.net-bs5/css/dataTables.bootstrap5.min.css';
|
||||||
|
//endregion
|
||||||
|
//region Custom style for Datatables.net
|
||||||
|
import './styles/datatables.scss';
|
||||||
|
//endregion
|
||||||
|
import 'jqueryLocal';
|
||||||
|
|
||||||
|
$(function () {
|
||||||
|
$('table.table-datatable').each(function () {
|
||||||
|
const self = $(this);
|
||||||
|
|
||||||
|
//region Options du datatable
|
||||||
|
let options = {
|
||||||
|
paging: self.data('sortPaging', false),
|
||||||
|
pageLength: self.data('sortPerPage', 50),
|
||||||
|
processing: true,
|
||||||
|
layout: self.data(
|
||||||
|
'sortLayout',
|
||||||
|
{
|
||||||
|
topStart: null,
|
||||||
|
topEnd: null,
|
||||||
|
bottomStart: null,
|
||||||
|
bottomEnd: 'paging',
|
||||||
|
},
|
||||||
|
),
|
||||||
|
};
|
||||||
|
//endregion
|
||||||
|
//region Gestion tri initial
|
||||||
|
let initialSort = [];
|
||||||
|
$('> thead > tr > th[data-sort-onLoad]', this).each(function () {
|
||||||
|
let self = $(this);
|
||||||
|
initialSort.push(
|
||||||
|
{
|
||||||
|
index: self.index(),
|
||||||
|
priority: self.data('sortOnload'),
|
||||||
|
direction: self.data('sortOrder', 'asc').toLowerCase(),
|
||||||
|
},
|
||||||
|
);
|
||||||
|
});
|
||||||
|
initialSort.sort(function (sort1, sort2) {
|
||||||
|
if (sort1.priority === sort2.priority) {
|
||||||
|
return sort1.index - sort2.index;
|
||||||
|
}
|
||||||
|
|
||||||
|
return sort1.priority - sort2.priority;
|
||||||
|
});
|
||||||
|
|
||||||
|
if (initialSort.length > 0) {
|
||||||
|
options.order = [];
|
||||||
|
initialSort.forEach(function (sortOrder) {
|
||||||
|
options.order.push([sortOrder.index, sortOrder.direction]);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
//endregion
|
||||||
|
//region Gestion sens de tri (1er clic ou initial si concerné)
|
||||||
|
let descSort = [];
|
||||||
|
$('> thead > tr > th[data-sort-order]', this).each(function () {
|
||||||
|
const self = $(this);
|
||||||
|
if (self.data('sortOrder', 'asc').toLowerCase() === 'desc') {
|
||||||
|
descSort.push(self.index());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
if (descSort.length > 0) {
|
||||||
|
if (!options.hasOwnProperty('columnDefs')) {
|
||||||
|
options.columnDefs = [];
|
||||||
|
}
|
||||||
|
options.columnDefs.push(
|
||||||
|
{
|
||||||
|
targets: descSort,
|
||||||
|
orderSequence: ['desc', 'asc'],
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
//endregion
|
||||||
|
//region Gestion désactivation tri
|
||||||
|
let disabledSort = [];
|
||||||
|
$('> thead > tr > th[data-sort]', this).each(function () {
|
||||||
|
const self = $(this);
|
||||||
|
if (!self.data('sort', true)) {
|
||||||
|
disabledSort.push(self.index());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
if (disabledSort.length > 0) {
|
||||||
|
if (!options.hasOwnProperty('columnDefs')) {
|
||||||
|
options.columnDefs = [];
|
||||||
|
}
|
||||||
|
options.columnDefs.push(
|
||||||
|
{
|
||||||
|
targets: disabledSort,
|
||||||
|
orderable: false,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
//endregion
|
||||||
|
//region Gestion nom des colonnes
|
||||||
|
const columnsName = $('> thead > tr > th[data-sort-name]', this);
|
||||||
|
if (columnsName.length > 0) {
|
||||||
|
if (!options.hasOwnProperty('columnDefs')) {
|
||||||
|
options.columnDefs = [];
|
||||||
|
}
|
||||||
|
|
||||||
|
columnsName.each(function () {
|
||||||
|
const self = $(this);
|
||||||
|
const name = self.data('sortName', '');
|
||||||
|
if (name !== '') {
|
||||||
|
options.columnDefs.push(
|
||||||
|
{
|
||||||
|
targets: self.index(),
|
||||||
|
name: name,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
//endregion
|
||||||
|
//region Gestion de AJAX
|
||||||
|
const ajaxUrl = self.data('sortAjax', false);
|
||||||
|
if (ajaxUrl !== false) {
|
||||||
|
options.serverSide = true;
|
||||||
|
options.ajax = {
|
||||||
|
url: ajaxUrl,
|
||||||
|
type: 'POST',
|
||||||
|
//createCDATASection: '',
|
||||||
|
cache: self.data('sortAjaxCache', false),
|
||||||
|
};
|
||||||
|
|
||||||
|
options.columns = [];
|
||||||
|
columnsName.each(function () {
|
||||||
|
const self = $(this);
|
||||||
|
const name = self.data('sortName', '');
|
||||||
|
if (name !== '') {
|
||||||
|
options.columns[self.index()] = {
|
||||||
|
data: name,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
//endregion
|
||||||
|
|
||||||
|
self.DataTable(options);
|
||||||
|
});
|
||||||
|
});
|
@ -1,329 +0,0 @@
|
|||||||
//region Datatables.net
|
|
||||||
import 'datatables.net';
|
|
||||||
import 'datatables.net-dt/css/dataTables.dataTables.min.css';
|
|
||||||
//endregion
|
|
||||||
//region Bootstrap 5 styling for Datatables.net
|
|
||||||
import 'datatables.net-bs5';
|
|
||||||
import 'datatables.net-bs5/css/dataTables.bootstrap5.min.css';
|
|
||||||
//endregion
|
|
||||||
//region Custom style for Datatables.net
|
|
||||||
import './styles/datatables2.scss';
|
|
||||||
//endregion
|
|
||||||
import 'jqueryLocal';
|
|
||||||
import Utils from 'utils';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Chargement automatique des éléments : tableaux, {@link https://datatables.net/ DataTables (v2)}
|
|
||||||
*
|
|
||||||
* Valide seulement si le JS "DataTable" est bien présent\
|
|
||||||
* S'instancie automatiquement sur les <table class="table-datatable2">
|
|
||||||
*
|
|
||||||
* Options :
|
|
||||||
* * table :
|
|
||||||
* * data-sort-paging : boolean\
|
|
||||||
* Pagination gérée ?\
|
|
||||||
* Défaut : faux
|
|
||||||
* * data-sort-per-page : integer\
|
|
||||||
* Nombre d'éléments par défaut par page\
|
|
||||||
* Défaut : 50
|
|
||||||
* * data-sort-layout : string (JSON)\
|
|
||||||
* Le JSON du modèle du tableau (https://datatables.net/reference/option/layout)\
|
|
||||||
* Défaut : pagination (si active) en bas à droite
|
|
||||||
* * data-sort-ajax : string|false\
|
|
||||||
* Faux si pas de requête AJAX géré\
|
|
||||||
* Sinon l'URL AJAX appelée\
|
|
||||||
* Bien penser à définir les "data-sort-name" sur les <th>\
|
|
||||||
* Défaut : false
|
|
||||||
* * data-sort-ajax-type : string\
|
|
||||||
* Le type de la requête AJAX (GET, POST, etc.)\
|
|
||||||
* Défaut : POST
|
|
||||||
* * data-sort-ajax-cache : boolean\
|
|
||||||
* Mise en cache du résultat des requêtes AJAX ?\
|
|
||||||
* Défaut : faux
|
|
||||||
* * data-sort-lang : string (JSON)\
|
|
||||||
* Le JSON des traductions
|
|
||||||
* * data-sort-lang-url : string (url)\
|
|
||||||
* L'URL renvoyant le JSON des traductions\
|
|
||||||
* Ignore si "data-sort-lang" renseigné
|
|
||||||
* * data-sort-lang-code : string\
|
|
||||||
* Code langue (plugin, voir https://datatables.net/plug-ins/i18n/French.html#Browser-loading-/-CDN)\
|
|
||||||
* Exemple avec "fr-FR" : chargera "//cdn.datatables.net/plug-ins/2.2.2/i18n/fr-FR.json"\
|
|
||||||
* Ignoré si "data-sort-lang" ou "data-sort-lang-url" est renseigné
|
|
||||||
* * data-sort-child : string (HTML)|false\
|
|
||||||
* Faux si pas de lignes enfants gérées\
|
|
||||||
* Sinon le contenu HTML de la ligne enfant\
|
|
||||||
* Ignoré si supplanté par la version sur les <tr>\
|
|
||||||
* Défaut : false
|
|
||||||
* * data-sort-child-ajax : string (url)|false\
|
|
||||||
* Faux si pas de lignes enfants gérées\
|
|
||||||
* L'URL des requêtes AJAX pour les lignes enfants\
|
|
||||||
* Ignoré si "data-sort-child" est renseigné ou supplanté par la version sur les <tr>\
|
|
||||||
* Défaut : false
|
|
||||||
* * data-sort-child-ajax-type : string\
|
|
||||||
* Le type de la requête AJAX pour les lignes enfants (GET, POST, etc.)\
|
|
||||||
* Ignoré si supplanté par la version sur les <tr>\
|
|
||||||
* Défaut : POST
|
|
||||||
* * data-sort-child-ajax-cache : boolean\
|
|
||||||
* Mise en cache du résultat des requêtes AJAX pour les lignes enfants ?\
|
|
||||||
* Ignoré si supplanté par la version sur les <tr>\
|
|
||||||
* Défaut : faux
|
|
||||||
* * thead th :
|
|
||||||
* * data-sort-onLoad : integer\
|
|
||||||
* Ordre de tri de la colonne pour le tri initial/au chargement
|
|
||||||
* * data-sort-order : string ("asc", "desc")\
|
|
||||||
* Sens du tri de la colonne lors du 1er clic (et lors du tri initial/au chargement si "data-sort-onLoad" également renseigné)
|
|
||||||
* * data-sort : boolean\
|
|
||||||
* Activer le tri sur la colonne ?\
|
|
||||||
* Défaut : vrai
|
|
||||||
* * data-sort-name : string\
|
|
||||||
* Le nom de la colonne dans la source de données (AJAX : cf. data-sort-ajax)
|
|
||||||
* * data-sort-name-value : boolean\
|
|
||||||
* La colonne à une valeur de tri différente de son affichage ?\
|
|
||||||
* Si vrai attends une paire display/sort dans le JSON (exemple : https://datatables.net/examples/ajax/orthogonal-data.html)\
|
|
||||||
* Cf. SolulogSAS\BaseSite\Web\DataTables2_ColumnWithSortValue\
|
|
||||||
* Défaut : faux
|
|
||||||
* * data-sort-child : string (HTML)|false\
|
|
||||||
* Faux si pas de lignes enfants gérées\
|
|
||||||
* Sinon le contenu HTML de la ligne enfant\
|
|
||||||
* Défaut : false
|
|
||||||
* * data-sort-child-ajax : string (url)|false\
|
|
||||||
* Faux si pas de lignes enfants gérées\
|
|
||||||
* L'URL des requêtes AJAX pour les lignes enfants\
|
|
||||||
* Ignoré si "data-sort-child" est renseigné\
|
|
||||||
* Défaut : false
|
|
||||||
* * data-sort-child-ajax-id : any\
|
|
||||||
* L'ID ajax de la ligne enfant (transmis dans "ajaxId")\
|
|
||||||
* Défaut : {néant}
|
|
||||||
* * data-sort-child-ajax-type : string\
|
|
||||||
* Le type de la requête AJAX pour les lignes enfants (GET, POST, etc.)\
|
|
||||||
* Défaut : POST
|
|
||||||
* * data-sort-child-ajax-cache : boolean\
|
|
||||||
* Mise en cache du résultat des requêtes AJAX pour les lignes enfants ?\
|
|
||||||
* Défaut : faux
|
|
||||||
* * tbody td :
|
|
||||||
* * data-order : any\
|
|
||||||
* La valeur utilisée pour le tri
|
|
||||||
* * data-filter : any\
|
|
||||||
* La valeur utilisée pour le filtrage
|
|
||||||
*
|
|
||||||
* @param {Document|jQuery} page
|
|
||||||
*/
|
|
||||||
function datatables2 (page) {
|
|
||||||
$('table.table-datatable2', page).each(function () {
|
|
||||||
const self = $(this);
|
|
||||||
|
|
||||||
//region Options du datatable
|
|
||||||
let options = {
|
|
||||||
paging: self.dataDefault('sortPaging', false),
|
|
||||||
pageLength: self.dataDefault('sortPerPage', 50),
|
|
||||||
processing: true,
|
|
||||||
layout:
|
|
||||||
self.dataDefault('sortLayout',
|
|
||||||
{
|
|
||||||
topStart: null,
|
|
||||||
topEnd: null,
|
|
||||||
bottomStart: null,
|
|
||||||
bottomEnd: 'paging',
|
|
||||||
},
|
|
||||||
),
|
|
||||||
};
|
|
||||||
//endregion
|
|
||||||
//region Gestion traduction
|
|
||||||
let lang = self.dataDefault('sortLang', undefined);
|
|
||||||
if (Utils.isUndefined(lang)) {
|
|
||||||
let langUrl = self.dataDefault('sortLangUrl', undefined);
|
|
||||||
if (Utils.isUndefined(langUrl)) {
|
|
||||||
const langCode = self.dataDefault('sortLangCode', undefined);
|
|
||||||
if (!Utils.isUndefined(langCode)) {
|
|
||||||
langUrl = '//cdn.datatables.net/plug-ins/2.2.2/i18n/' + langCode + '.json';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!Utils.isUndefined(langUrl)) {
|
|
||||||
lang = {url: langUrl};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!Utils.isUndefined(lang)) {
|
|
||||||
options.language = lang;
|
|
||||||
}
|
|
||||||
//endregion
|
|
||||||
//region Gestion tri initial
|
|
||||||
let initialSort = [];
|
|
||||||
$('> thead > tr > th[data-sort-onLoad]', self).each(function () {
|
|
||||||
let self = $(this);
|
|
||||||
initialSort.push(
|
|
||||||
{
|
|
||||||
index: self.index(),
|
|
||||||
priority: self.dataDefault('sortOnload', 0),
|
|
||||||
direction: self.dataDefault('sortOrder', 'asc').toLowerCase(),
|
|
||||||
},
|
|
||||||
);
|
|
||||||
});
|
|
||||||
initialSort.sort(function (sort1, sort2) {
|
|
||||||
if (sort1.priority === sort2.priority) {
|
|
||||||
return sort1.index - sort2.index;
|
|
||||||
}
|
|
||||||
|
|
||||||
return sort1.priority - sort2.priority;
|
|
||||||
});
|
|
||||||
|
|
||||||
if (initialSort.length > 0) {
|
|
||||||
options.order = [];
|
|
||||||
initialSort.forEach(function (sortOrder) {
|
|
||||||
options.order.push([sortOrder.index, sortOrder.direction]);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
//endregion
|
|
||||||
//region Gestion sens de tri (1er clic ou initial si concerné)
|
|
||||||
let descSort = [];
|
|
||||||
$('> thead > tr > th[data-sort-order]', self).each(function () {
|
|
||||||
const self = $(this);
|
|
||||||
if (self.dataDefault('sortOrder', 'asc').toLowerCase() === 'desc') {
|
|
||||||
descSort.push(self.index());
|
|
||||||
}
|
|
||||||
});
|
|
||||||
if (descSort.length > 0) {
|
|
||||||
if (!options.hasOwnProperty('columnDefs')) {
|
|
||||||
options.columnDefs = [];
|
|
||||||
}
|
|
||||||
options.columnDefs.push(
|
|
||||||
{
|
|
||||||
targets: descSort,
|
|
||||||
orderSequence: ['desc', 'asc'],
|
|
||||||
},
|
|
||||||
);
|
|
||||||
}
|
|
||||||
//endregion
|
|
||||||
//region Gestion désactivation tri
|
|
||||||
let disabledSort = [];
|
|
||||||
$('> thead > tr > th[data-sort]', self).each(function () {
|
|
||||||
const self = $(this);
|
|
||||||
if (!self.dataDefault('sort', true)) {
|
|
||||||
disabledSort.push(self.index());
|
|
||||||
}
|
|
||||||
});
|
|
||||||
if (disabledSort.length > 0) {
|
|
||||||
if (!options.hasOwnProperty('columnDefs')) {
|
|
||||||
options.columnDefs = [];
|
|
||||||
}
|
|
||||||
options.columnDefs.push(
|
|
||||||
{
|
|
||||||
targets: disabledSort,
|
|
||||||
orderable: false,
|
|
||||||
},
|
|
||||||
);
|
|
||||||
}
|
|
||||||
//endregion
|
|
||||||
//region Gestion nom des colonnes
|
|
||||||
const columnsName = $('> thead > tr > th[data-sort-name]', self);
|
|
||||||
if (columnsName.length > 0) {
|
|
||||||
if (!options.hasOwnProperty('columnDefs')) {
|
|
||||||
options.columnDefs = [];
|
|
||||||
}
|
|
||||||
|
|
||||||
columnsName.each(function () {
|
|
||||||
const self = $(this);
|
|
||||||
const name = self.dataDefault('sortName', '');
|
|
||||||
if (name !== '') {
|
|
||||||
options.columnDefs.push(
|
|
||||||
{
|
|
||||||
targets: self.index(),
|
|
||||||
name: name,
|
|
||||||
},
|
|
||||||
);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
//endregion
|
|
||||||
//region Gestion de AJAX
|
|
||||||
const ajaxUrl = self.dataDefault('sortAjax', false);
|
|
||||||
if (ajaxUrl !== false) {
|
|
||||||
options.serverSide = true;
|
|
||||||
options.ajax = {
|
|
||||||
url: ajaxUrl,
|
|
||||||
type: self.dataDefault('sortAjaxType', 'POST'),
|
|
||||||
cache: self.dataDefault('sortAjaxCache', false),
|
|
||||||
};
|
|
||||||
|
|
||||||
options.columns = [];
|
|
||||||
columnsName.each(function () {
|
|
||||||
const self = $(this);
|
|
||||||
const name = self.dataDefault('sortName', '');
|
|
||||||
const nameValue = self.dataDefault('sortNameValue', false);
|
|
||||||
if (name !== '') {
|
|
||||||
options.columns[self.index()] = {
|
|
||||||
data: nameValue
|
|
||||||
? {_: name + '.display', sort: name + '.sort'}
|
|
||||||
: name,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
//endregion
|
|
||||||
|
|
||||||
const datatable = self.DataTable(options);
|
|
||||||
|
|
||||||
//region Gestion lignes enfants
|
|
||||||
const child = self.dataDefault('sortChild', false);
|
|
||||||
const childAjaxUrl = self.dataDefault('sortChildAjax', false);
|
|
||||||
const childAjaxType = self.dataDefault('sortChildAjaxType', 'POST');
|
|
||||||
const childAjaxCache = self.dataDefault('sortChildAjaxCache', false);
|
|
||||||
|
|
||||||
if (child === true || childAjaxUrl !== false) {
|
|
||||||
const showData = function (dtRow, childData) {
|
|
||||||
const parentHtml = '<div></div>';
|
|
||||||
const childJquery = $(parentHtml).append(childData);
|
|
||||||
datatables2(childJquery);
|
|
||||||
|
|
||||||
//noinspection JSUnresolvedReference
|
|
||||||
dtRow.child(childJquery).show();
|
|
||||||
};
|
|
||||||
self.on('click', '> tbody > tr:not([data-dt-row!=""][data-dt-row]) > td', function () {
|
|
||||||
//region Obtention ligne
|
|
||||||
const row = $(this).parents('tr').first();
|
|
||||||
const dtRow = datatable.row(row);
|
|
||||||
//endregion
|
|
||||||
//region Lignes enfants déjà affichées ? Les masques
|
|
||||||
//noinspection JSUnresolvedReference
|
|
||||||
if (dtRow.child.isShown()) {
|
|
||||||
//noinspection JSUnresolvedReference
|
|
||||||
dtRow.child.hide();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
//endregion
|
|
||||||
|
|
||||||
//region Données enfants directement spécifiées
|
|
||||||
const childData = row.dataDefault('sortChild', false);
|
|
||||||
if (childData !== false) {
|
|
||||||
showData(dtRow, childData);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
//endregion
|
|
||||||
//region Données enfants via AJAX
|
|
||||||
const rowChildAjaxUrl = row.dataDefault('sortChildAjax', childAjaxUrl);
|
|
||||||
if (Utils.isUndefined(rowChildAjaxUrl) || rowChildAjaxUrl === false) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
$.ajax(
|
|
||||||
{
|
|
||||||
type: row.dataDefault('sortChildAjaxType', childAjaxType),
|
|
||||||
url: rowChildAjaxUrl,
|
|
||||||
data: {
|
|
||||||
ajaxId: row.dataDefault('sortChildAjaxId', undefined),
|
|
||||||
},
|
|
||||||
cache: row.dataDefault('sortChildAjaxCache', childAjaxCache),
|
|
||||||
},
|
|
||||||
)
|
|
||||||
.done(childData => {
|
|
||||||
showData(dtRow, childData);
|
|
||||||
});
|
|
||||||
//endregion
|
|
||||||
});
|
|
||||||
}
|
|
||||||
//endregion
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
$(function () {
|
|
||||||
datatables2(document);
|
|
||||||
});
|
|
@ -1,26 +0,0 @@
|
|||||||
import 'bootstrap';
|
|
||||||
import 'jqueryLocal';
|
|
||||||
import Utils from 'utils';
|
|
||||||
|
|
||||||
$(function () {
|
|
||||||
$('.modal-dynamic').on('show.bs.modal', function (event) {
|
|
||||||
const dialog = $(this);
|
|
||||||
const sender = $(event.relatedTarget);
|
|
||||||
|
|
||||||
const title = sender.dataDefault('modalDynamicTitle');
|
|
||||||
const body = sender.dataDefault('modalDynamicBody');
|
|
||||||
const linkUrl = sender.dataDefault('modalDynamicLinkUrl', sender.matchTag('a') ? sender.attr('href') : undefined);
|
|
||||||
|
|
||||||
if (!Utils.isUndefined(title)) {
|
|
||||||
$('.modal-title', dialog).html(title);
|
|
||||||
}
|
|
||||||
if (!Utils.isUndefined(body)) {
|
|
||||||
$('.modal-body', dialog).html(body);
|
|
||||||
}
|
|
||||||
if (!Utils.isUndefined(linkUrl)) {
|
|
||||||
$('a.modal-confirm-link', dialog).attr('href', linkUrl);
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
});
|
|
||||||
});
|
|
@ -0,0 +1,36 @@
|
|||||||
|
table.dataTable thead > tr > th.dt-orderable-asc span.dt-column-order::after,
|
||||||
|
table.dataTable thead > tr > th.dt-orderable-desc span.dt-column-order::after,
|
||||||
|
table.dataTable thead > tr > th.dt-ordering-asc span.dt-column-order::after,
|
||||||
|
table.dataTable thead > tr > th.dt-ordering-desc span.dt-column-order::after,
|
||||||
|
table.dataTable thead > tr > td.dt-orderable-asc span.dt-column-order::after,
|
||||||
|
table.dataTable thead > tr > td.dt-orderable-desc span.dt-column-order::after,
|
||||||
|
table.dataTable thead > tr > td.dt-ordering-asc span.dt-column-order::after,
|
||||||
|
table.dataTable thead > tr > td.dt-ordering-desc span.dt-column-order::after {
|
||||||
|
margin-top : 3px;
|
||||||
|
}
|
||||||
|
|
||||||
|
table.dataTable thead > tr > th.dt-orderable-asc span.dt-column-order,
|
||||||
|
table.dataTable thead > tr > th.dt-orderable-desc span.dt-column-order,
|
||||||
|
table.dataTable thead > tr > th.dt-ordering-asc span.dt-column-order,
|
||||||
|
table.dataTable thead > tr > th.dt-ordering-desc span.dt-column-order,
|
||||||
|
table.dataTable thead > tr > td.dt-orderable-asc span.dt-column-order,
|
||||||
|
table.dataTable thead > tr > td.dt-orderable-desc span.dt-column-order,
|
||||||
|
table.dataTable thead > tr > td.dt-ordering-asc span.dt-column-order,
|
||||||
|
table.dataTable thead > tr > td.dt-ordering-desc span.dt-column-order {
|
||||||
|
position : relative;
|
||||||
|
left : 10px;
|
||||||
|
top : none;
|
||||||
|
bottom : none;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.dt-container .dt-paging .dt-paging-button {
|
||||||
|
padding : 0;
|
||||||
|
margin : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
table.dataTable th.dt-type-numeric,
|
||||||
|
table.dataTable th.dt-type-date,
|
||||||
|
table.dataTable td.dt-type-numeric,
|
||||||
|
table.dataTable td.dt-type-date {
|
||||||
|
text-align : left;
|
||||||
|
}
|
@ -1,35 +0,0 @@
|
|||||||
table.table-datatable2 {
|
|
||||||
& > thead > tr {
|
|
||||||
& > th.dt-orderable-asc span.dt-column-title {
|
|
||||||
margin-right : 5px;
|
|
||||||
}
|
|
||||||
|
|
||||||
& > th.dt-orderable-asc span.dt-column-order,
|
|
||||||
& > th.dt-orderable-desc span.dt-column-order {
|
|
||||||
position : relative;
|
|
||||||
left : 0;
|
|
||||||
top : 0;
|
|
||||||
bottom : 0;
|
|
||||||
|
|
||||||
&::after {
|
|
||||||
margin-top : 3px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
& > tbody > tr[data-dt-row]:not([data-dt-row='']) > td {
|
|
||||||
padding : 0.75rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
div.dt-container .dt-paging .dt-paging-button {
|
|
||||||
padding : 0;
|
|
||||||
margin : 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
th.dt-type-numeric,
|
|
||||||
th.dt-type-date,
|
|
||||||
td.dt-type-numeric,
|
|
||||||
td.dt-type-date {
|
|
||||||
text-align : left;
|
|
||||||
}
|
|
||||||
}
|
|
File diff suppressed because it is too large
Load Diff
@ -1,3 +0,0 @@
|
|||||||
framework:
|
|
||||||
property_info:
|
|
||||||
with_constructor_extractor: true
|
|
@ -1,5 +0,0 @@
|
|||||||
symfonycasts_sass:
|
|
||||||
# Path to your Sass root file
|
|
||||||
root_sass:
|
|
||||||
- '%kernel.project_dir%/assets/styles/app.scss'
|
|
||||||
- '%kernel.project_dir%/assets/styles/datatables2.scss'
|
|
@ -1,89 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Controller\Config;
|
|
||||||
|
|
||||||
use App\Entity\MaterialType;
|
|
||||||
use App\Form\Config\MaterialTypeEditForm;
|
|
||||||
use App\Misc\FlashType;
|
|
||||||
use App\Repository\MaterialTypeRepository;
|
|
||||||
use Doctrine\ORM\EntityManagerInterface;
|
|
||||||
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
|
||||||
use Symfony\Component\HttpFoundation\Request;
|
|
||||||
use Symfony\Component\HttpFoundation\Response;
|
|
||||||
use Symfony\Component\Routing\Attribute\Route;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Controllers for the configuration pages
|
|
||||||
*/
|
|
||||||
#[Route('/Config/MaterialType')]
|
|
||||||
class MaterialTypeController extends AbstractController {
|
|
||||||
private readonly EntityManagerInterface $entityManager;
|
|
||||||
/**
|
|
||||||
* @var MaterialTypeRepository The material type repository
|
|
||||||
*/
|
|
||||||
private readonly MaterialTypeRepository $materialTypeRepository;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Initialisation
|
|
||||||
*
|
|
||||||
* @param MaterialTypeRepository $materialTypeRepository The material type repository
|
|
||||||
*/
|
|
||||||
public function __construct (EntityManagerInterface $entityManager, MaterialTypeRepository $materialTypeRepository) {
|
|
||||||
$this->entityManager = $entityManager;
|
|
||||||
$this->materialTypeRepository = $materialTypeRepository;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* List of material types
|
|
||||||
*
|
|
||||||
* @return Response The response
|
|
||||||
*/
|
|
||||||
#[Route('/', name: 'config_materialType_list', alias: 'config_materialType')]
|
|
||||||
public function list (): Response {
|
|
||||||
return $this->render(
|
|
||||||
'Config/MaterialType/List.html.twig',
|
|
||||||
[
|
|
||||||
'materialTypes' => $this->materialTypeRepository->findAll(),
|
|
||||||
]
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Edit/Create a material type
|
|
||||||
*
|
|
||||||
* @return Response The response
|
|
||||||
*/
|
|
||||||
#[Route('/Create', name: 'config_materialType_create')]
|
|
||||||
#[Route('/Edit-{id}', name: 'config_materialType_edit')]
|
|
||||||
public function edit (Request $request, ?MaterialType $materialType = null): Response {
|
|
||||||
$materialType ??= new MaterialType();
|
|
||||||
|
|
||||||
$form = $this->createForm(MaterialTypeEditForm::class, $materialType);
|
|
||||||
$form->handleRequest($request);
|
|
||||||
if ($form->isSubmitted() && $form->isValid()) {
|
|
||||||
$this->entityManager->persist($materialType);
|
|
||||||
$this->entityManager->flush();
|
|
||||||
|
|
||||||
$this->addFlash(FlashType::SUCCESS, 'Le type de matériau a bien été enregistré.');
|
|
||||||
return $this->redirectToRoute('config_materialType_list');
|
|
||||||
}
|
|
||||||
|
|
||||||
return $this->render('Config/MaterialType/Edit.html.twig', [
|
|
||||||
'form' => $form->createView(),
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Delete a material type
|
|
||||||
*
|
|
||||||
* @return Response The response
|
|
||||||
*/
|
|
||||||
#[Route('/Delete-{id}', name: 'config_materialType_delete')]
|
|
||||||
public function delete (MaterialType $materialType): Response {
|
|
||||||
$this->entityManager->remove($materialType);
|
|
||||||
$this->entityManager->flush();
|
|
||||||
|
|
||||||
$this->addFlash(FlashType::SUCCESS, 'Le type de matériau a bien été supprimé.');
|
|
||||||
return $this->redirectToRoute('config_materialType_list');
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,45 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Form\Config;
|
|
||||||
|
|
||||||
use App\Entity\MaterialType;
|
|
||||||
use Symfony\Component\Form\AbstractType;
|
|
||||||
use Symfony\Component\Form\Extension\Core\Type\SubmitType;
|
|
||||||
use Symfony\Component\Form\FormBuilderInterface;
|
|
||||||
use Symfony\Component\OptionsResolver\OptionsResolver;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The form for editing a material type
|
|
||||||
*/
|
|
||||||
class MaterialTypeEditForm extends AbstractType {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @inheritDoc
|
|
||||||
*/
|
|
||||||
public function configureOptions (OptionsResolver $resolver): void {
|
|
||||||
$resolver->setDefaults(
|
|
||||||
[
|
|
||||||
'data_class' => MaterialType::class,
|
|
||||||
]
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @inheritDoc
|
|
||||||
*/
|
|
||||||
public function buildForm (FormBuilderInterface $builder, array $options): void {
|
|
||||||
$builder
|
|
||||||
->add('name', null, [
|
|
||||||
'label' => 'Nom',
|
|
||||||
])
|
|
||||||
->add('stackName', null, [
|
|
||||||
'label' => 'Nom de la pile',
|
|
||||||
])
|
|
||||||
->add('stackSize', null, [
|
|
||||||
'label' => 'Taille de la pile',
|
|
||||||
])
|
|
||||||
->add('submit', SubmitType::class, [
|
|
||||||
'label' => 'Enregistrer',
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,8 +0,0 @@
|
|||||||
{% extends 'base.html.twig' %}
|
|
||||||
|
|
||||||
{% block title %}Modification type de matériau - {{ parent() }}{% endblock %}
|
|
||||||
|
|
||||||
{% block mainContent %}
|
|
||||||
<h1>Modification type de matériau</h1>
|
|
||||||
{{ form(form) }}
|
|
||||||
{% endblock %}
|
|
@ -1,62 +0,0 @@
|
|||||||
{% extends '/base.html.twig' %}
|
|
||||||
|
|
||||||
{% block title %}Liste des types de matériaux - {{ parent() }}{% endblock %}
|
|
||||||
{% block importmap %}{{ importmap(['app', 'datatables2']) }}{% endblock %}
|
|
||||||
|
|
||||||
{% block mainContent %}
|
|
||||||
<h1>Liste des types de matériaux</h1>
|
|
||||||
<div class="d-flex">
|
|
||||||
<div class="table-responsive mnw-25">
|
|
||||||
<table class="table table-sm table-striped table-hover table-bordered table-datatable2">
|
|
||||||
<thead>
|
|
||||||
<tr>
|
|
||||||
<th scope="col" data-sort-onLoad="1" class="align-middle">Nom</th>
|
|
||||||
<th scope="col" data-sort="false" class="fit-content align-middle">
|
|
||||||
<a href="{{ path('config_materialType_create') }}" class="btn btn-primary" data-bs-toggle="tooltip" data-bs-title="Ajouter">
|
|
||||||
<i class="fa-solid fa-square-plus"></i>
|
|
||||||
</a>
|
|
||||||
</th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody>
|
|
||||||
{% for materialType in materialTypes %}
|
|
||||||
<tr>
|
|
||||||
<td>{{ materialType.name }}</td>
|
|
||||||
<td class="fit-content">
|
|
||||||
<a href="{{ path('config_materialType_edit', {id: materialType.id}) }}"
|
|
||||||
class="text-primary me-2"
|
|
||||||
data-bs-toggle="tooltip"
|
|
||||||
data-bs-title="Éditer"
|
|
||||||
><i class="fa-solid fa-pen"></i></a>
|
|
||||||
<a href="#" class="text-danger" id="btDelete" data-bs-toggle="tooltip" data-bs-title="Supprimer">
|
|
||||||
<span data-bs-toggle="modal"
|
|
||||||
data-bs-target="#deleteConfirmation"
|
|
||||||
data-modal-dynamic-link-url="{{ path('config_materialType_delete', {id: materialType.id}) }}"
|
|
||||||
><i class="fa-solid fa-xmark"></i></span>
|
|
||||||
</a>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
{% endfor %}
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="modal modal-dynamic fade" id="deleteConfirmation" tabindex="-1" aria-label="btDelete" aria-hidden="true">
|
|
||||||
<div class="modal-dialog">
|
|
||||||
<div class="modal-content">
|
|
||||||
<div class="modal-header">
|
|
||||||
<h1 class="modal-title fs-5">Suppression</h1>
|
|
||||||
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
|
||||||
</div>
|
|
||||||
<div class="modal-body">
|
|
||||||
Êtes-vous sûr de vouloir supprimer ce type de matériau ?
|
|
||||||
</div>
|
|
||||||
<div class="modal-footer">
|
|
||||||
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Non</button>
|
|
||||||
<a href="#" class="modal-confirm-link btn btn-danger">Oui</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{% endblock %}
|
|
Loading…
Reference in New Issue