@osfarm/itineraire-technique 1.1.12 → 1.1.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/editor.html +64 -1
- package/js/editor-export.js +1 -1
- package/js/editor-wiki-editor.js +138 -7
- package/package.json +1 -1
package/editor.html
CHANGED
|
@@ -51,6 +51,7 @@
|
|
|
51
51
|
<span class="visually-hidden">Autres options de chargement</span>
|
|
52
52
|
</button>
|
|
53
53
|
<ul class="dropdown-menu">
|
|
54
|
+
<li><a class="dropdown-item" href="#" onclick="showSaveAsModal()"><i class="fa fa-save" aria-hidden="true"></i> Enregistrer sous</a></li>
|
|
54
55
|
<li><a class="dropdown-item" href="#" onclick="exportToJsonFile()"><i class="fa fa-download" aria-hidden="true"></i> Exporter</a></li>
|
|
55
56
|
</ul>
|
|
56
57
|
</div>
|
|
@@ -271,6 +272,47 @@
|
|
|
271
272
|
</div>
|
|
272
273
|
</div>
|
|
273
274
|
|
|
275
|
+
<!-- Save As Modal -->
|
|
276
|
+
<div class="modal fade" id="saveAsModal" tabindex="-1" aria-labelledby="saveAsModalLabel" aria-hidden="true">
|
|
277
|
+
<div class="modal-dialog">
|
|
278
|
+
<div class="modal-content">
|
|
279
|
+
<div class="modal-header">
|
|
280
|
+
<h5 class="modal-title" id="saveAsModalLabel">Enregistrer sous</h5>
|
|
281
|
+
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
|
282
|
+
</div>
|
|
283
|
+
<div class="modal-body">
|
|
284
|
+
<form>
|
|
285
|
+
<div class="mb-3 form-check">
|
|
286
|
+
<input type="checkbox" class="form-check-input" id="saveAsUseExistingPage">
|
|
287
|
+
<label class="form-check-label" for="saveAsUseExistingPage">
|
|
288
|
+
Enregistrer sous une page existante
|
|
289
|
+
</label>
|
|
290
|
+
</div>
|
|
291
|
+
<div class="mb-3" id="saveAsPageSelectContainer">
|
|
292
|
+
<label for="saveAsPageSelect" class="form-label">Page parent</label>
|
|
293
|
+
<select class="form-select" id="saveAsPageSelect" disabled>
|
|
294
|
+
<option value="">Sélectionner une page...</option>
|
|
295
|
+
</select>
|
|
296
|
+
<div class="form-text">Si non coché, le fichier sera enregistré sous "Non classified"</div>
|
|
297
|
+
</div>
|
|
298
|
+
<div class="mb-3">
|
|
299
|
+
<label for="saveAsFilename" class="form-label">Nom du fichier</label>
|
|
300
|
+
|
|
301
|
+
<div class="input-group mb-3">
|
|
302
|
+
<input type="text" class="form-control" id="saveAsFilename" placeholder="Nom du fichier (sans extension)">
|
|
303
|
+
<span class="input-group-text" id="basic-addon2">.json</span>
|
|
304
|
+
</div>
|
|
305
|
+
</div>
|
|
306
|
+
</form>
|
|
307
|
+
</div>
|
|
308
|
+
<div class="modal-footer">
|
|
309
|
+
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Annuler</button>
|
|
310
|
+
<button type="button" class="btn btn-primary" id="saveAsConfirmBtn">Enregistrer</button>
|
|
311
|
+
</div>
|
|
312
|
+
</div>
|
|
313
|
+
</div>
|
|
314
|
+
</div>
|
|
315
|
+
|
|
274
316
|
<!-- Modal -->
|
|
275
317
|
<div class="modal fade" id="modalParams" tabindex="-1" aria-labelledby="exampleModalLabel" aria-hidden="true">
|
|
276
318
|
<div class="modal-dialog">
|
|
@@ -645,6 +687,17 @@
|
|
|
645
687
|
|
|
646
688
|
we = new WikiEditor();
|
|
647
689
|
we.loadPageFromURL();
|
|
690
|
+
|
|
691
|
+
// Set up Save As modal event listeners
|
|
692
|
+
$('#saveAsUseExistingPage').on('change', function() {
|
|
693
|
+
$('#saveAsPageSelect').prop('disabled', !this.checked);
|
|
694
|
+
});
|
|
695
|
+
|
|
696
|
+
$('#saveAsConfirmBtn').on('click', function() {
|
|
697
|
+
if (we) {
|
|
698
|
+
we.saveAs();
|
|
699
|
+
}
|
|
700
|
+
});
|
|
648
701
|
} else {
|
|
649
702
|
document.getElementById("WikiButtons").classList.add("d-none");
|
|
650
703
|
document.getElementById("NonWikiButtons").classList.remove("d-none");
|
|
@@ -670,12 +723,20 @@
|
|
|
670
723
|
}
|
|
671
724
|
}
|
|
672
725
|
|
|
726
|
+
function showSaveAsModal() {
|
|
727
|
+
if (typeof we !== 'undefined') {
|
|
728
|
+
we.showSaveAsModal();
|
|
729
|
+
} else {
|
|
730
|
+
console.error('WikiEditor instance not available');
|
|
731
|
+
}
|
|
732
|
+
}
|
|
733
|
+
|
|
673
734
|
class StepModel {
|
|
674
735
|
constructor(step) {
|
|
675
736
|
this.step = step; // keep a reference to the original object
|
|
676
737
|
|
|
677
738
|
this.step.id = step.id ?? crypto.randomUUID();
|
|
678
|
-
this.step.name = step.name ?? "
|
|
739
|
+
this.step.name = step.name ?? "";
|
|
679
740
|
this.step.color = step.color ?? "#0db3bf";
|
|
680
741
|
this.step.startDate = step.startDate ? new Date(step.startDate) : new Date();
|
|
681
742
|
this.step.endDate = step.endDate ? new Date(step.endDate) : new Date();
|
|
@@ -1013,7 +1074,9 @@
|
|
|
1013
1074
|
if (this.textContent.trim() === "") {
|
|
1014
1075
|
this.textContent = DEFAULT_TITLE;
|
|
1015
1076
|
}
|
|
1077
|
+
|
|
1016
1078
|
crops.title = this.textContent;
|
|
1079
|
+
crops.defaultTitle = false;
|
|
1017
1080
|
});
|
|
1018
1081
|
}
|
|
1019
1082
|
|
package/js/editor-export.js
CHANGED
|
@@ -100,7 +100,7 @@ function showJsonErrorModal(errorMessage) {
|
|
|
100
100
|
function showConfirmationModal(onConfirm) {
|
|
101
101
|
|
|
102
102
|
if (crops?.steps.length === 0)
|
|
103
|
-
return
|
|
103
|
+
return onConfirm();
|
|
104
104
|
|
|
105
105
|
const confirmationModal = new bootstrap.Modal(document.getElementById('confirmationModal'));
|
|
106
106
|
const confirmButton = document.getElementById('confirmImport');
|
package/js/editor-wiki-editor.js
CHANGED
|
@@ -53,7 +53,6 @@ class WikiEditor {
|
|
|
53
53
|
const jsonErrorModal = new bootstrap.Modal(document.getElementById('jsonErrorModal'));
|
|
54
54
|
jsonErrorModal.show();
|
|
55
55
|
}
|
|
56
|
-
|
|
57
56
|
}
|
|
58
57
|
});
|
|
59
58
|
|
|
@@ -66,17 +65,13 @@ class WikiEditor {
|
|
|
66
65
|
const self = this;
|
|
67
66
|
|
|
68
67
|
if (!self.pageTitle) {
|
|
69
|
-
|
|
68
|
+
self.showSaveAsModal();
|
|
70
69
|
return;
|
|
71
70
|
}
|
|
72
71
|
|
|
73
72
|
// If a page title is provided, save to that page
|
|
74
73
|
self.savePageToWiki(self.pageTitle, JSON.stringify(crops, null, 2))
|
|
75
|
-
.then(() => {
|
|
76
|
-
|
|
77
|
-
// TODO : Also set a few semantic properties on the page, including the chart type, the geolocation, etc.
|
|
78
|
-
|
|
79
|
-
|
|
74
|
+
.then(async () => {
|
|
80
75
|
alert("Itinéraire technique enregistré avec succès !");
|
|
81
76
|
})
|
|
82
77
|
.catch(err => {
|
|
@@ -151,6 +146,25 @@ class WikiEditor {
|
|
|
151
146
|
}
|
|
152
147
|
}
|
|
153
148
|
|
|
149
|
+
|
|
150
|
+
async getWikiUserPages(username) {
|
|
151
|
+
try {
|
|
152
|
+
// Encode the username for the URL
|
|
153
|
+
const encodedUsername = 'User:' + username;
|
|
154
|
+
const query = encodeURIComponent(`[[Page author::${encodedUsername}]][[A un type de page::+]]`);
|
|
155
|
+
const url = `/api.php?action=ask&query=${query}|sort=Modification date|order=desc&format=json`;
|
|
156
|
+
|
|
157
|
+
const response = await fetch(url, {
|
|
158
|
+
credentials: 'include'
|
|
159
|
+
});
|
|
160
|
+
const data = await response.json();
|
|
161
|
+
return data;
|
|
162
|
+
} catch (error) {
|
|
163
|
+
console.error("Error fetching wiki files:", error);
|
|
164
|
+
throw error;
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
|
|
154
168
|
async loadFromWiki() {
|
|
155
169
|
// Show the modal
|
|
156
170
|
const modal = new bootstrap.Modal(document.getElementById('wikiFilesModal'));
|
|
@@ -220,4 +234,121 @@ class WikiEditor {
|
|
|
220
234
|
}
|
|
221
235
|
}
|
|
222
236
|
|
|
237
|
+
/**
|
|
238
|
+
* Show the Save As modal and handle the save as functionality
|
|
239
|
+
*/
|
|
240
|
+
async showSaveAsModal() {
|
|
241
|
+
const self = this;
|
|
242
|
+
|
|
243
|
+
try {
|
|
244
|
+
// Get user info to check if logged in
|
|
245
|
+
const userInfo = await this.getWikiUserInfo();
|
|
246
|
+
|
|
247
|
+
if (!userInfo.id || userInfo.id === 0) {
|
|
248
|
+
alert('Vous devez être connecté au wiki pour utiliser cette fonctionnalité.');
|
|
249
|
+
return;
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
// Get user's existing pages
|
|
253
|
+
const pagesData = await this.getWikiUserPages(userInfo.name);
|
|
254
|
+
|
|
255
|
+
// Show the modal
|
|
256
|
+
const modal = new bootstrap.Modal(document.getElementById('saveAsModal'));
|
|
257
|
+
modal.show();
|
|
258
|
+
|
|
259
|
+
// Populate the select with user's pages
|
|
260
|
+
const pageSelect = $('#saveAsPageSelect');
|
|
261
|
+
pageSelect.empty();
|
|
262
|
+
pageSelect.append('<option value="">Sélectionner une page...</option>');
|
|
263
|
+
|
|
264
|
+
if (pagesData.query?.results) {
|
|
265
|
+
for (const [pageTitle, pageData] of Object.entries(pagesData.query.results)) {
|
|
266
|
+
const displayTitle = pageData.displaytitle || pageTitle;
|
|
267
|
+
pageSelect.append(`<option value="${pageTitle}">${displayTitle}</option>`);
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
// Set default filename from title if it's been changed
|
|
272
|
+
const filenameInput = $('#saveAsFilename');
|
|
273
|
+
const currentTitle = crops.title || '';
|
|
274
|
+
if (crops.defaultTitle === false) {
|
|
275
|
+
filenameInput.val(currentTitle);
|
|
276
|
+
} else {
|
|
277
|
+
filenameInput.val('');
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
} catch (error) {
|
|
281
|
+
console.error("Error showing save as modal:", error);
|
|
282
|
+
alert('Erreur lors du chargement des données utilisateur.');
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
/**
|
|
287
|
+
* Build the URL for saving based on the save as modal selections
|
|
288
|
+
*/
|
|
289
|
+
buildSaveAsUrl() {
|
|
290
|
+
const useExistingPage = $('#saveAsUseExistingPage').prop('checked');
|
|
291
|
+
const selectedPage = $('#saveAsPageSelect').val();
|
|
292
|
+
const filename = $('#saveAsFilename').val().trim();
|
|
293
|
+
|
|
294
|
+
if (!filename) {
|
|
295
|
+
alert('Veuillez saisir un nom de fichier.');
|
|
296
|
+
return null;
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
let subpageName;
|
|
300
|
+
|
|
301
|
+
if (useExistingPage && selectedPage) {
|
|
302
|
+
subpageName = selectedPage;
|
|
303
|
+
} else {
|
|
304
|
+
subpageName = 'Non classified';
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
// Build the final URL: subpagename/filename.json
|
|
308
|
+
const finalUrl = `${subpageName}/${filename}.json`;
|
|
309
|
+
|
|
310
|
+
if (crops.defaultTitle !== false) {
|
|
311
|
+
crops.title = filename;
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
return finalUrl;
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
/**
|
|
318
|
+
* Handle the save as operation
|
|
319
|
+
*/
|
|
320
|
+
async saveAs() {
|
|
321
|
+
const url = this.buildSaveAsUrl();
|
|
322
|
+
|
|
323
|
+
if (!url) {
|
|
324
|
+
return; // Error already handled in buildSaveAsUrl
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
const self = this;
|
|
328
|
+
const oldPageTitle = self.pageTitle;
|
|
329
|
+
|
|
330
|
+
try {
|
|
331
|
+
// Set the new page title
|
|
332
|
+
self.pageTitle = url;
|
|
333
|
+
|
|
334
|
+
// Save to the wiki first
|
|
335
|
+
await self.savePageToWiki(self.pageTitle, JSON.stringify(crops, null, 2));
|
|
336
|
+
|
|
337
|
+
// Close the modal
|
|
338
|
+
const modal = bootstrap.Modal.getInstance(document.getElementById('saveAsModal'));
|
|
339
|
+
modal.hide();
|
|
340
|
+
|
|
341
|
+
alert(`Itinéraire technique enregistré avec succès sous "${url}"`);
|
|
342
|
+
|
|
343
|
+
// Only navigate after successful save
|
|
344
|
+
const newEditorUrl = `editor.html?wiki=${encodeURIComponent(self.pageTitle)}`;
|
|
345
|
+
window.location.href = newEditorUrl;
|
|
346
|
+
|
|
347
|
+
} catch (error) {
|
|
348
|
+
// Restore the old page title if save failed
|
|
349
|
+
self.pageTitle = oldPageTitle;
|
|
350
|
+
console.error("Error saving as new file:", error);
|
|
351
|
+
alert('Erreur lors de l\'enregistrement du fichier.');
|
|
352
|
+
}
|
|
353
|
+
}
|
|
223
354
|
}
|