L'Air du Bois est une plateforme Open Source de partage collaboratif ouverte à tous les amoureux du travail du bois. (En savoir plus)

Rejoindre l'Air du Bois Se connecter

2 réponses
Flomac
( Modifié )

Bonjour,

Je me suis posé la même question et voyant qu'il n'y avait pas de solution, en voici une de contournement. J'espère que cela ne contrevient pas au règle d'utilisation du site de l'ADB.

J'ai écris un petit script qui fait croire au serveur de l'ADB qu'on lui soumet des pièce une à une.
Il y a une protection sur le serveur qui empêche de soumettre une foule de requêtes dans un temps trop court, ce qui est normale. J'ai donc du ajouter un temps d'attente entre 2 soumissions de pièces ce qui fait qu'il ne faut pas soumettre trop de pièces d'un seul coup au risque que le navigateur considère le script comme trop lent et cherche donc à l'arrêter ou freeze.

Le CSV (exporté depuis OpenCutList) que le script attend est de ce type :

N°;Désignation;Quantité
A;Socle;1
B;Traverse;2
etc...

Le principe du script : ajouter un bouton "input" afin de charger un fichier .csv et ensuite de soumettre automatiquement chaque ligne du CSV au serveur.
Pour utiliser ce script il faut ouvrir la console javascript du navigateur, le coller puis appuyer sur |entrer| pour l'exécuter. Ensuite il suffit de surveiller la console javascript pour voir l'avancement de l'importation.
[EDIT : cela ne fonctionne que si on quitte le processus après la création et qu'on l'édite ensuite ; je n'ai pas cherché à comprendre pourquoi]

En espérant que cela sera utile et utilisable à d'autres personnes que moi !

Voici la version compressée du script :

const processusId=document.location.href.split("/")[4].split("-")[0];let pieces;function handleFileSelect(e){for(var i,n=e.target.files,t=0;i=n[t];t++)if("text/csv"==i.type){var o=new FileReader;o.onload=function(e){pieces=csvToArray(o.result),$.post("/processus/"+processusId+"/part/new").done(function(e){formAddPiece=$(e),addPiece(formAddPiece.find("form"))})},o.readAsText(i);break}}function csvToArray(e,i=";"){const n=e.slice(0,e.indexOf("\n")).split(i),t=e.slice(e.indexOf("\n")+1).split("\n");return t.map(function(e){var t=e.split(i);return n.reduce(function(e,i,n){return e[i=i.normalize("NFD").replace(/[\u0300-\u036f]/g,"").replace("°","").toLowerCase()]=t[n],e},{})})}$(".ladb-header-tools").prepend("<input type=\"file\" id=\"files\" name=\"files[]\" accept=\".csv\" multiple />"),document.getElementById("files").addEventListener("change",handleFileSelect,!1);let i=0;function resolveAfter3Seconds(i){return new Promise(e=>{setTimeout(()=>{e(i)},3e3)})}async function waitBeforeAddNewPiece(e){await resolveAfter3Seconds(10);addPiece(e)}function addPiece(n){var e=pieces[i];formAddPiece.find("#ladb_workflow_part_number").val(e.n),formAddPiece.find("#ladb_workflow_part_name").val(e.designation),formAddPiece.find("#ladb_workflow_part_count").val(e.quantite);var t=n.serialize(),e=n.attr("action");$.post(e,t).done(function(e){console.log(i+1+"/"+pieces.length),i++,i<pieces.length&&waitBeforeAddNewPiece(n)})}

Et la version détaillée pour ceux que cela intéresse :

const processusId = document.location.href.split('/')[4].split('-')[0];
let pieces;
$('.ladb-header-tools').prepend('<input type="file" id="files" name="files[]" accept=".csv" multiple />')
document.getElementById('files').addEventListener('change', handleFileSelect, false);
function handleFileSelect(evt) {
var files = evt.target.files; // FileList object
// Loop through the FileList and render image files as thumbnails.
for (var i = 0, f; f = files[i]; i++) {
if (f.type != 'text/csv') {
continue;
}
var reader = new FileReader();
// Closure to capture the file information.
reader.onload = (function(theFile) {
return function(e) {
pieces = csvToArray(reader.result)
$.post( "/processus/"+processusId+"/part/new")
.done(function( data ) {
formAddPiece = $(data);
// for (let index = 0; index < pieces.length; index++) {
addPiece(formAddPiece.find('form'));
// }
});
};
})(f);
reader.readAsText(f)
break;
}
}

function csvToArray(str, delimiter = ";") {
// slice from start of text to the first \n index
// use split to create an array from string by delimiter
const headers = str.slice(0, str.indexOf("\n")).split(delimiter);

// slice from \n index + 1 to the end of the text
// use split to create an array of each csv value row
const rows = str.slice(str.indexOf("\n") + 1).split("\n");

// Map the rows
// split values from each row into an array
// use headers.reduce to create an object
// object properties derived from headers:values
// the object passed as an element of the array
const arr = rows.map(function (row) {
const values = row.split(delimiter);
const el = headers.reduce(function (object, header, index) {
header = header.normalize("NFD").replace(/[\u0300-\u036f]/g, "").replace('°','').toLowerCase();
object[header] = values[index];
return object;
}, {});
return el;
});

// return the array
return arr;
}

let i = 0;
function resolveAfter3Seconds(x) {
return new Promise(resolve => {
setTimeout(() => {
resolve(x);
}, 3000);
});
};
async function waitBeforeAddNewPiece(form) {
var x = await resolveAfter3Seconds(10);
addPiece(form);
}
function addPiece(form) {
const element = pieces[i];
formAddPiece.find('#ladb_workflow_part_number').val(element.n);
formAddPiece.find('#ladb_workflow_part_name').val(element.designation);
formAddPiece.find('#ladb_workflow_part_count').val(element.quantite);
let formData = form.serialize()
let url = form.attr('action')
$.post( url, formData )
.done(function( data ) {
console.log((i+1)+'/'+pieces.length)
i++
if(i < pieces.length) {
waitBeforeAddNewPiece(form)
}
});
}

Mis à jour
Flomac
( Modifié )

Bonjour,

Une autre solution pour quelqu'un qui est déjà familiarisé avec le langage javascript/jquery et la console javascript que tout les navigateurs propose (plus ou moins facile d'accès selon les navigateurs ). Dans cette console, il est possible de saisir/coller du code afin de modifier l'affichage du site (il suffit de recharger la page pour retrouver l'affichage normale).

Pour afficher seulement le graphique (il faut quand même restreindre le placement des boites dans la largeur ensuite il suffit d'augmenter la valeur '5000px' pour imprimer plus long) :

$('#ladb_topbar, #ladb_leftbar, .ladb-workflow-workspace header, .ladb-right-panel, #ladb_bottombar').css('display', 'none');
$('.ladb-workflow-task-diagram').css('width', '100%');
$('.ladb-workflow-board').css({'height': '5000px','top': '0'});
$('.ladb-workflow-workspace').css('top','0');

Pour afficher seulement la liste des taches (là aussi il suffit d'augmenter la valeur '5000px' pour imprimer plus long) :

$('#ladb_topbar, #ladb_leftbar, .ladb-workflow-workspace header, .ladb-workflow-task-diagram, #ladb_bottombar').css('display', 'none');
$('.ladb-right-panel').removeClass('ladb-no-print').css('left', '0');
$('.ladb-workflow-board').css({'height': '5000px','top': '0'});
$('.ladb-workflow-workspace').css('top','0');

Mis à jour