fix: A27 lint terminé — eslint 0/0 (285 warnings nettoyés) (v7.25.0)
FlowDeck CI / test (push) Failing after 3h9m51s
FlowDeck CI / lint (push) Successful in 1m54s
FlowDeck CI / docker (push) Skipped

3 familles, 13 fichiers (+153/−167) :

1. no-empty ×70 = TOUS des `catch (x) {}` vides → `catch { /* volontaire */ }`
   (binding optionnel ES2019 + commentaire : passe no-empty ET
   no-unused-vars, zéro changement de comportement).

2. no-unused-vars ×171 :
   - bindings de catch inutilisés retirés (e/err/ex/e2/e3)
   - 24 lignes mortes déterministes, chaque suppression validée par assert
     sur le texte exact (`var self = this` ×8, `var lang`, `var acc`,
     `var today`, `var path/restored/files/resolved/items/clickEl`,
     `uid()`/`propName()` sans un seul appel, `.then` + `resolved++`
     compteurs jamais lus)
   - `/* exported */` sur les 10 fonctions appelées depuis les attributs
     HTML des templates (vérifiées par grep : 1 template chacune) :
     setActiveTab/kanbanBoard/filterSystem/sortSystem/newIssueForm/
     showNewIssue, importWizard, libraryPage, workspacesPage, settingsInit

3. no-undef ×44 = vrais globaux déclarés dans eslint.config.mjs
   (getSvgIcon = script inline de base.html, TextDecoder = API navigateur,
   Prism = CDN) + 2 vrais correctifs :
   - settings.js : `typeof toast === 'function'` = guard TOUJOURS faux
     (pas de toast global) → les toasts timezone/SAML ne s'affichaient
     jamais → `window.showToast` (2 sites)
   - local_workspace.js : `_wsInitData = window._wsInitData`
     (auto-affectation sans effet, global implicite) supprimé

eslint static/js : **0 erreur / 0 warning** (285 → 0) · node --check vert
sur tous les fichiers · suite **1089/1089** · ruff OK · docs à jour
This commit is contained in:
2026-10-01 21:30:37 -04:00
parent 103bc57418
commit 8d0d69e7b8
19 changed files with 189 additions and 173 deletions
+30
View File
@@ -1,5 +1,35 @@
# Changelog - FlowDeck # Changelog - FlowDeck
## v7.25.0 (2026-10-01) — Audit : A27 CLOSED (eslint 0/0)
### Fixed
- **Toasts settings jamais affichés** : `settings.js` appelait
`typeof toast === 'function'` — guard **toujours faux** (le `toast` global
n'existait pas) → les retours « Timezone saved » / « SP metadata URL
copiée » ne s'affichaient jamais. → `window.showToast` (global `base.html`)
- `_wsInitData = window._wsInitData` (auto-affectation d'un nom non déclaré,
sans effet observable car `window._wsInitData` existe depuis L4) supprimé
### Changed
- **A27 lint terminé : `eslint static/js` = 0 erreur / 0 warning** (285 → 0,
22 fichiers) :
· no-empty ×70 = `catch (x) {}` vides → `catch { /* volontaire */ }`
(binding optionnel ES2019 ; zéro changement de comportement)
· no-unused-vars ×171 = bindings de catch retirés + 24 lignes mortes
déterministes (assert sur texte exact avant suppression) +
`/* exported */` sur les 10 fonctions appelées depuis les attributs
HTML des templates (vérifiées par grep)
· no-undef ×44 = vrais globaux déclarés dans `eslint.config.mjs`
(getSvgIcon = inline base.html, TextDecoder = API, Prism = CDN)
### Notes
- `node --check` vert sur tous les fichiers ; suite complète **1089/1089**
- A27 reste ouvert uniquement pour : `base` 1 523 L structurel (inline par
nature, décision assumée) + ~500 L de petits blocs hors cibles
## v7.24.0 (2026-10-01) — Audit : A27 extraction TERMINÉE (bilan -85 %) ## v7.24.0 (2026-10-01) — Audit : A27 extraction TERMINÉE (bilan -85 %)
### Changed ### Changed
+2 -2
View File
File diff suppressed because one or more lines are too long
+1 -1
View File
@@ -1 +1 @@
7.24.0 7.25.0
+1 -1
View File
@@ -1,6 +1,6 @@
# WORKLOAD — FlowDeck Notion Clone # WORKLOAD — FlowDeck Notion Clone
> **Début**: 2026-07-08 | **Version**: v7.24.0 (audit — A27 extraction TERMINÉE : 11 874 L, -85 % inline) | **Statut**: EN COURS 🔄 > **Début**: 2026-07-08 | **Version**: v7.25.0 (audit — A27 CLOSED : eslint 0/0, 285 warnings nettoyés) | **Statut**: EN COURS 🔄
> **Cible**: parité Notion + intégration forge · **Follow-ups v7.3 livrés**: sidebar teamspaces, notif `page.updated`, charts `number` + dashboards multi-DB, unfurl forge, UI Settings → Audit — voir `ROADMAP.md § v7.3.0` > **Cible**: parité Notion + intégration forge · **Follow-ups v7.3 livrés**: sidebar teamspaces, notif `page.updated`, charts `number` + dashboards multi-DB, unfurl forge, UI Settings → Audit — voir `ROADMAP.md § v7.3.0`
## Avancement Global ## Avancement Global
+1 -1
View File
@@ -185,7 +185,7 @@ async def lifespan(_app: FastAPI):
app = FastAPI( app = FastAPI(
title="FlowDeck", title="FlowDeck",
version="7.24.0", version="7.25.0",
docs_url="/docs", docs_url="/docs",
redoc_url="/redoc", redoc_url="/redoc",
lifespan=lifespan, lifespan=lifespan,
+1 -1
View File
@@ -2,7 +2,7 @@
"openapi": "3.1.0", "openapi": "3.1.0",
"info": { "info": {
"title": "FlowDeck", "title": "FlowDeck",
"version": "7.24.0" "version": "7.25.0"
}, },
"paths": { "paths": {
"/auth/register": { "/auth/register": {
+3
View File
@@ -40,6 +40,9 @@ const browserGlobals = {
Alpine: "readonly", htmx: "readonly", Sortable: "readonly", Alpine: "readonly", htmx: "readonly", Sortable: "readonly",
// Globals exposed on window by app.js // Globals exposed on window by app.js
openModal: "readonly", closeModal: "readonly", openModal: "readonly", closeModal: "readonly",
// getSvgIcon : script inline de base.html (nonce) ; Prism : CDN des vues ;
// TextDecoder : API navigateur (ES2015)
getSvgIcon: "readonly", Prism: "readonly", TextDecoder: "readonly",
}; };
export default [ export default [
+2 -2
View File
@@ -61,7 +61,7 @@
self._place(); self._place();
var el = document.querySelector('.fd-ctx-menu'); var el = document.querySelector('.fd-ctx-menu');
if (el && window.ResizeObserver) { if (el && window.ResizeObserver) {
if (self._ro) { try { self._ro.disconnect(); } catch (e) {} } if (self._ro) { try { self._ro.disconnect(); } catch { /* volontaire */ } }
self._ro = new ResizeObserver(function () { self._place(); }); self._ro = new ResizeObserver(function () { self._place(); });
self._ro.observe(el); self._ro.observe(el);
} }
@@ -95,7 +95,7 @@
this.maxH = Math.max(120, vh - ny - 8); this.maxH = Math.max(120, vh - ny - 8);
}, },
close() { close() {
if (this._ro) { try { this._ro.disconnect(); } catch (e) {} this._ro = null; } if (this._ro) { try { this._ro.disconnect(); } catch { /* volontaire */ } this._ro = null; }
this.open = false; this.open = false;
this.node = null; this.node = null;
this.handlers = {}; this.handlers = {};
+6 -6
View File
@@ -126,7 +126,7 @@
remove() { remove() {
var fn = this.onRemove || this.onPick; var fn = this.onRemove || this.onPick;
if (fn) { try { fn(''); } catch (e) {} } if (fn) { try { fn(''); } catch { /* volontaire */ } }
this.close(); this.close();
}, },
@@ -143,7 +143,7 @@
loadRecent() { loadRecent() {
try { this.recent = JSON.parse(localStorage.getItem('fd_icon_recent') || '[]'); } try { this.recent = JSON.parse(localStorage.getItem('fd_icon_recent') || '[]'); }
catch (e) { this.recent = []; } catch { this.recent = []; }
}, },
pushRecent(e) { pushRecent(e) {
try { try {
@@ -151,7 +151,7 @@
r.unshift(e); r.unshift(e);
this.recent = r.slice(0, 32); this.recent = r.slice(0, 32);
localStorage.setItem('fd_icon_recent', JSON.stringify(this.recent)); localStorage.setItem('fd_icon_recent', JSON.stringify(this.recent));
} catch (err) {} } catch { /* volontaire */ }
}, },
async loadCustom() { async loadCustom() {
@@ -160,7 +160,7 @@
var d = await r.json(); var d = await r.json();
this.custom = (d && d.emojis) || []; this.custom = (d && d.emojis) || [];
this.customLoaded = true; this.customLoaded = true;
} catch (e) { this.custom = []; } } catch { this.custom = []; }
}, },
openCustomModal() { openCustomModal() {
@@ -196,7 +196,7 @@
this.customModal = false; this.customModal = false;
this.pick(d.emoji.url); this.pick(d.emoji.url);
} }
} catch (e) { } catch {
if (window.showToast) window.showToast('Emoji upload failed', 'error'); if (window.showToast) window.showToast('Emoji upload failed', 'error');
} }
this.customBusy = false; this.customBusy = false;
@@ -206,7 +206,7 @@
var csrf = (document.cookie.match(/csrf_token=([^;]+)/) || [])[1] || ''; var csrf = (document.cookie.match(/csrf_token=([^;]+)/) || [])[1] || '';
await fetch('/api/custom-emojis/' + id, { method: 'DELETE', headers: { 'X-CSRF-Token': csrf }, credentials: 'same-origin' }); await fetch('/api/custom-emojis/' + id, { method: 'DELETE', headers: { 'X-CSRF-Token': csrf }, credentials: 'same-origin' });
this.custom = this.custom.filter(function (e) { return e.id !== id; }); this.custom = this.custom.filter(function (e) { return e.id !== id; });
} catch (e) {} } catch { /* volontaire */ }
} }
}); });
}); });
+20 -24
View File
@@ -430,7 +430,7 @@
if(!lastAsst) return; if(!lastAsst) return;
var steps = acts.map(function(a){ var steps = acts.map(function(a){
var res = null; var res = null;
try{ res = a.result_json ? JSON.parse(a.result_json) : {}; }catch(e){ res = {}; } try{ res = a.result_json ? JSON.parse(a.result_json) : {}; }catch{ res = {}; }
var msg = (res && res.message) ? res.message : ''; var msg = (res && res.message) ? res.message : '';
return agentPanel._actionStep({ return agentPanel._actionStep({
tool: a.tool_name, status: a.status, target_id: a.target_id, tool: a.tool_name, status: a.status, target_id: a.target_id,
@@ -672,7 +672,7 @@
r.insertNode(br); r.insertNode(br);
r.setStartAfter(br); r.collapse(true); r.setStartAfter(br); r.collapse(true);
this.input = this.composerText(); this.input = this.composerText();
}catch(e){} }catch { /* volontaire */ }
this.resizeInput(); this.resizeInput();
}, },
_caretQuery(){ _caretQuery(){
@@ -687,7 +687,7 @@
if(i > 0 && s[i-1] === '@' && (i === 1 || /\s/.test(s[i-2]))){ if(i > 0 && s[i-1] === '@' && (i === 1 || /\s/.test(s[i-2]))){
return {node: node, at: i-1, raw: s.slice(i, off)}; return {node: node, at: i-1, raw: s.slice(i, off)};
} }
}catch(e){} }catch { /* volontaire */ }
return null; return null;
}, },
_expandToAt(range){ _expandToAt(range){
@@ -727,14 +727,14 @@
useRange.setStartAfter(span); useRange.collapse(true); useRange.setStartAfter(span); useRange.collapse(true);
useRange.insertNode(sp); useRange.insertNode(sp);
useRange.setStart(sp, 1); useRange.setEnd(sp, 1); useRange.setStart(sp, 1); useRange.setEnd(sp, 1);
try{ var s2 = window.getSelection(); if(s2){ s2.removeAllRanges(); s2.addRange(useRange); } }catch(e2){} try{ var s2 = window.getSelection(); if(s2){ s2.removeAllRanges(); s2.addRange(useRange); } }catch { /* volontaire */ }
} else { } else {
if(el.textContent) el.appendChild(document.createTextNode(' ')); if(el.textContent) el.appendChild(document.createTextNode(' '));
el.appendChild(span); el.appendChild(span);
el.appendChild(document.createTextNode(' ')); el.appendChild(document.createTextNode(' '));
try{ var r2 = document.createRange(); r2.selectNodeContents(el); r2.collapse(false); var s3 = window.getSelection(); if(s3){ s3.removeAllRanges(); s3.addRange(r2); } }catch(e3){} try{ var r2 = document.createRange(); r2.selectNodeContents(el); r2.collapse(false); var s3 = window.getSelection(); if(s3){ s3.removeAllRanges(); s3.addRange(r2); } }catch { /* volontaire */ }
} }
}catch(e){} }catch { /* volontaire */ }
this.input = this.composerText(); this.input = this.composerText();
this.resizeInput(); this.resizeInput();
this._emptyCheck(); this._emptyCheck();
@@ -753,7 +753,7 @@
this._insertToken(item, r); this._insertToken(item, r);
return; return;
} }
}catch(e){} }catch { /* volontaire */ }
} }
this._insertToken(item); this._insertToken(item);
}, },
@@ -803,12 +803,12 @@
onPaste(e){ onPaste(e){
e.preventDefault(); e.preventDefault();
var text = ''; var text = '';
try{ if(e.clipboardData) text = e.clipboardData.getData('text/plain') || ''; }catch(err){ } try{ if(e.clipboardData) text = e.clipboardData.getData('text/plain') || ''; }catch { /* volontaire */ }
if(!text) return; if(!text) return;
try{ try{
var sel = window.getSelection(); var sel = window.getSelection();
if(sel && sel.rangeCount){ sel.getRangeAt(0).deleteContents(); document.execCommand('insertText', false, text); } if(sel && sel.rangeCount){ sel.getRangeAt(0).deleteContents(); document.execCommand('insertText', false, text); }
}catch(err){} }catch { /* volontaire */ }
this.input = this.composerText(); this.input = this.composerText();
this.resizeInput(); this.resizeInput();
}, },
@@ -889,7 +889,6 @@
return null; return null;
}, },
useSuggestion(c){ useSuggestion(c){
var self = this;
if(!c || c._sep) return; if(!c || c._sep) return;
if(c._admin){ if(c._admin){
this.setComposerText(c.cmd.replace(/\s*<[^>]*>\s*$/, ' ')); this.setComposerText(c.cmd.replace(/\s*<[^>]*>\s*$/, ' '));
@@ -926,7 +925,6 @@
this.scrollBottom(); this.scrollBottom();
}, },
handleCommand(text){ handleCommand(text){
var self = this;
var parts = text.replace(/^\/+/, '').trim().split(/\s+/); var parts = text.replace(/^\/+/, '').trim().split(/\s+/);
var cmd = (parts.shift() || '').toLowerCase(); var cmd = (parts.shift() || '').toLowerCase();
var arg = parts.join(' ').trim(); var arg = parts.join(' ').trim();
@@ -1164,7 +1162,7 @@
if(tok){ e.preventDefault(); this._removeTokenDom(tok); return; } if(tok){ e.preventDefault(); this._removeTokenDom(tok); return; }
} }
} }
}catch(err){} }catch { /* volontaire */ }
} }
if(key === 'Escape'){ if(key === 'Escape'){
if(this.mentionOpen){ e.preventDefault(); e.stopPropagation(); this.mentionOpen = false; this._mentionFrom = null; this._atNode = null; return; } if(this.mentionOpen){ e.preventDefault(); e.stopPropagation(); this.mentionOpen = false; this._mentionFrom = null; this._atNode = null; return; }
@@ -1219,7 +1217,6 @@
// Render agent markdown responses (headings, tables, code, lists, …) to // Render agent markdown responses (headings, tables, code, lists, …) to
// HTML so the panel displays content like Notion (no raw `##` / `**`). // HTML so the panel displays content like Notion (no raw `##` / `**`).
renderMarkdown(md){ renderMarkdown(md){
var self = this;
function escHtml(s){ return String(s==null?'':s).replace(/&/g,'&amp;').replace(/</g,'&lt;').replace(/>/g,'&gt;'); } function escHtml(s){ return String(s==null?'':s).replace(/&/g,'&amp;').replace(/</g,'&lt;').replace(/>/g,'&gt;'); }
function inline(t){ function inline(t){
t = escHtml(t); t = escHtml(t);
@@ -1261,7 +1258,6 @@
var t = raw.trim(); var t = raw.trim();
// Fenced code block // Fenced code block
if(t.startsWith('```')){ if(t.startsWith('```')){
var lang = t.substring(3).trim();
var code = []; var code = [];
i++; i++;
while(i < lines.length && !lines[i].trim().startsWith('```')){ while(i < lines.length && !lines[i].trim().startsWith('```')){
@@ -1351,7 +1347,7 @@
var ok = document.execCommand('copy'); var ok = document.execCommand('copy');
document.body.removeChild(ta); document.body.removeChild(ta);
self.toast(ok ? 'Réponse copiée.' : 'Copie impossible.', !ok); self.toast(ok ? 'Réponse copiée.' : 'Copie impossible.', !ok);
}catch(err){ self.toast('Copie impossible.', true); } }catch{ self.toast('Copie impossible.', true); }
} }
if(navigator.clipboard && navigator.clipboard.writeText){ if(navigator.clipboard && navigator.clipboard.writeText){
navigator.clipboard.writeText(text).then(function(){ self.toast('Réponse copiée.'); }).catch(function(){ fallback(); }); navigator.clipboard.writeText(text).then(function(){ self.toast('Réponse copiée.'); }).catch(function(){ fallback(); });
@@ -1418,7 +1414,7 @@
if(ment.length){ text = 'Analyse le contexte référencé.'; } if(ment.length){ text = 'Analyse le contexte référencé.'; }
else if(!hasSkills){ return; } else if(!hasSkills){ return; }
} }
try { await self.ensureConversation(); } catch(e){ return; } try { await self.ensureConversation(); } catch{ return; }
var rawText = text; var rawText = text;
// La requête est composée EN ARRIÈRE-PLAN (hors de la boîte d'édition) : // La requête est composée EN ARRIÈRE-PLAN (hors de la boîte d'édition) :
// contexte1 + contexte2 + skill-1 + skill-2 + texte. // contexte1 + contexte2 + skill-1 + skill-2 + texte.
@@ -1505,7 +1501,7 @@
fph.steps = runSteps.slice(); fph.steps = runSteps.slice();
fph.stepsOpen = false; fph.stepsOpen = false;
fph.model = self.autoLabel || ''; fph.model = self.autoLabel || '';
if(window.__fdInsertAI){ try{ var h=window.__fdInsertAI; window.__fdInsertAI=null; h(ev.content||''); }catch(e){} } if(window.__fdInsertAI){ try{ var h=window.__fdInsertAI; window.__fdInsertAI=null; h(ev.content||''); }catch { /* volontaire */ } }
} }
else if(ev.type==='notice'){ self.notice = ev.message; } else if(ev.type==='notice'){ self.notice = ev.message; }
else if(ev.type==='error'){ else if(ev.type==='error'){
@@ -1515,7 +1511,7 @@
eph.steps = runSteps.slice(); eph.steps = runSteps.slice();
self.errorMsg = ev.message; self.errorMsg = ev.message;
} }
}catch(e){} }catch { /* volontaire */ }
}); });
self.scrollBottom(); self.scrollBottom();
return read(); return read();
@@ -1631,7 +1627,7 @@
var out = title ? ('Titre du document : ' + title) : 'Document ouvert'; var out = title ? ('Titre du document : ' + title) : 'Document ouvert';
if(text) out += '\n\n' + text; if(text) out += '\n\n' + text;
return out.slice(0, 9000); return out.slice(0, 9000);
}catch(e){ return ''; } }catch{ return ''; }
}; };
if(!window.fdGetPageContext) window.fdGetPageContext = window.fdReadPageContext; if(!window.fdGetPageContext) window.fdGetPageContext = window.fdReadPageContext;
@@ -1644,7 +1640,7 @@
try{ try{
var m = (window.location.pathname || '').match(new RegExp('^\\/?' + prefix + '\\/(\\d+)')); var m = (window.location.pathname || '').match(new RegExp('^\\/?' + prefix + '\\/(\\d+)'));
return m ? m[1] : null; return m ? m[1] : null;
}catch(e){ return null; } }catch{ return null; }
} }
function labelFromTitle(){ function labelFromTitle(){
try{ try{
@@ -1652,7 +1648,7 @@
t = t.replace(/^\s*FlowDeck\s*-\s*/i, ''); t = t.replace(/^\s*FlowDeck\s*-\s*/i, '');
t = t.replace(/\s*[-|]\s*FlowDeck\s*$/i, ''); t = t.replace(/\s*[-|]\s*FlowDeck\s*$/i, '');
if(t && t.toLowerCase() !== 'home' && t.toLowerCase() !== 'flowdeck') return t; if(t && t.toLowerCase() !== 'home' && t.toLowerCase() !== 'flowdeck') return t;
}catch(e){} }catch { /* volontaire */ }
return ''; return '';
} }
function docContext(){ function docContext(){
@@ -1671,7 +1667,7 @@
refType: pid ? 'document' : null refType: pid ? 'document' : null
}; };
} }
}catch(e){} }catch { /* volontaire */ }
return null; return null;
} }
function marker(){ function marker(){
@@ -1686,7 +1682,7 @@
var lbl = b.getAttribute('data-fd-context'); var lbl = b.getAttribute('data-fd-context');
return {kind:'section', icon:'📍', label:lbl, text:'', key:'marker'}; return {kind:'section', icon:'📍', label:lbl, text:'', key:'marker'};
} }
}catch(e){} }catch { /* volontaire */ }
return null; return null;
} }
function byPath(){ function byPath(){
@@ -1777,7 +1773,7 @@
if(E.autoSave) E.autoSave(); if(E.autoSave) E.autoSave();
if(E.render) E.render(); if(E.render) E.render();
return true; return true;
}catch(e){ return false; } }catch{ return false; }
}; };
// Backward-compatible detection hooks (banner + Ask AI) // Backward-compatible detection hooks (banner + Ask AI)
+2 -1
View File
@@ -1,4 +1,5 @@
const BD=(()=>{try{const el=document.getElementById('bd-config');return el?JSON.parse(el.textContent):{}}catch(e){return {}}})(); /* exported setActiveTab, kanbanBoard, filterSystem, sortSystem, newIssueForm, showNewIssue -- appeles depuis les attributs HTML des templates */
const BD=(()=>{try{const el=document.getElementById('bd-config');return el?JSON.parse(el.textContent):{}}catch{return {}}})();
var owner = BD.owner; var owner = BD.owner;
var repo = BD.repo; var repo = BD.repo;
+3 -6
View File
@@ -1,4 +1,4 @@
const DB_CONFIG=(()=>{try{const el=document.getElementById('db-config');const v=el?JSON.parse(el.textContent):null;return v===undefined?null:v}catch(e){return null}})(); const DB_CONFIG=(()=>{try{const el=document.getElementById('db-config');const v=el?JSON.parse(el.textContent):null;return v===undefined?null:v}catch{return null}})();
(function() { (function() {
'use strict'; 'use strict';
@@ -47,7 +47,7 @@ const DB_CONFIG=(()=>{try{const el=document.getElementById('db-config');const v=
var PALETTE = {gray:'#8b8b8b',brown:'#9f6b53',orange:'#d9730d',yellow:'#cb912f',green:'#448361',blue:'#337ea9',purple:'#9065b0',pink:'#c14c8a',red:'#d44c47'}; var PALETTE = {gray:'#8b8b8b',brown:'#9f6b53',orange:'#d9730d',yellow:'#cb912f',green:'#448361',blue:'#337ea9',purple:'#9065b0',pink:'#c14c8a',red:'#d44c47'};
function escHtml(s) { return String(s==null?'':s).replace(/&/g,'&amp;').replace(/</g,'&lt;').replace(/>/g,'&gt;').replace(/"/g,'&quot;'); } function escHtml(s) { return String(s==null?'':s).replace(/&/g,'&amp;').replace(/</g,'&lt;').replace(/>/g,'&gt;').replace(/"/g,'&quot;'); }
function parseJSON(s, d) { try { return typeof s === 'string' ? JSON.parse(s) : (s || d); } catch(e) { return d; } } function parseJSON(s, d) { try { return typeof s === 'string' ? JSON.parse(s) : (s || d); } catch { return d; } }
function parseOpts(prop) { function parseOpts(prop) {
var o = parseJSON(prop.options_json, []); var o = parseJSON(prop.options_json, []);
if (!Array.isArray(o)) o = []; if (!Array.isArray(o)) o = [];
@@ -57,7 +57,6 @@ const DB_CONFIG=(()=>{try{const el=document.getElementById('db-config');const v=
var found = parseOpts(prop).filter(function(o){ return o.name === name; })[0]; var found = parseOpts(prop).filter(function(o){ return o.name === name; })[0];
return (found && PALETTE[found.color]) || '#8b8b8b'; return (found && PALETTE[found.color]) || '#8b8b8b';
} }
function uid() { return 'dbx' + Math.random().toString(36).slice(2,9); }
function getCsrf() { var m = document.cookie.match(/csrf_token=([^;]+)/); return m ? m[1] : ''; } function getCsrf() { var m = document.cookie.match(/csrf_token=([^;]+)/); return m ? m[1] : ''; }
function toast(msg, kind) { function toast(msg, kind) {
if (typeof window.showToast === 'function') window.showToast(msg, kind); if (typeof window.showToast === 'function') window.showToast(msg, kind);
@@ -167,7 +166,6 @@ const DB_CONFIG=(()=>{try{const el=document.getElementById('db-config');const v=
if (ref === undefined || ref === null || ref === '') return null; if (ref === undefined || ref === null || ref === '') return null;
return state.properties.filter(function(p){ return String(p.id) === String(ref) || p.name === ref; })[0] || null; return state.properties.filter(function(p){ return String(p.id) === String(ref) || p.name === ref; })[0] || null;
} }
function propName(ref) { var p = findProp(ref); return p ? p.name : ''; }
function firstPropOfTypes(types) { function firstPropOfTypes(types) {
return state.properties.filter(function(p){ return types.indexOf(p.prop_type) >= 0; })[0] || null; return state.properties.filter(function(p){ return types.indexOf(p.prop_type) >= 0; })[0] || null;
} }
@@ -321,7 +319,7 @@ const DB_CONFIG=(()=>{try{const el=document.getElementById('db-config');const v=
h += '<th class="db-th db-th-handle" style="width:32px;min-width:32px"></th>'; h += '<th class="db-th db-th-handle" style="width:32px;min-width:32px"></th>';
props.forEach(function(prop){ props.forEach(function(prop){
var w = state.colWidths[prop.id] || 200; var w = state.colWidths[prop.id] || 200;
var groupIdx = 0; var acc = 0; var groupIdx = 0;
groups.forEach(function(g, gi){ if (g.props.indexOf(prop) >= 0) groupIdx = gi; }); groups.forEach(function(g, gi){ if (g.props.indexOf(prop) >= 0) groupIdx = gi; });
var collapsed = hasGroups && state.collapsedGroups[groupIdx]; var collapsed = hasGroups && state.collapsedGroups[groupIdx];
h += '<th class="db-th db-th-property" data-colgroup="'+groupIdx+'" style="'+(collapsed?'display:none;':'')+'min-width:'+w+'px;width:'+w+'px" data-prop-id="'+prop.id+'">'; h += '<th class="db-th db-th-property" data-colgroup="'+groupIdx+'" style="'+(collapsed?'display:none;':'')+'min-width:'+w+'px;width:'+w+'px" data-prop-id="'+prop.id+'">';
@@ -523,7 +521,6 @@ const DB_CONFIG=(()=>{try{const el=document.getElementById('db-config');const v=
if (!dp) return '<div style="padding:24px;color:var(--text-dim)">Add a Date property to use the calendar view.</div>'; if (!dp) return '<div style="padding:24px;color:var(--text-dim)">Add a Date property to use the calendar view.</div>';
var mode = calMode(); var mode = calMode();
var cur = state.calCursor; var cur = state.calCursor;
var today = new Date();
var h = '<div class="db-cal-head">'; var h = '<div class="db-cal-head">';
h += '<div class="db-cal-nav"><button data-cal-prev="1">\u2039</button><button data-cal-next="1">\u203a</button></div>'; h += '<div class="db-cal-nav"><button data-cal-prev="1">\u2039</button><button data-cal-next="1">\u203a</button></div>';
var title; var title;
+9 -9
View File
@@ -63,7 +63,7 @@ document.addEventListener('alpine:init', () => {
var d = await r.json(); var d = await r.json();
this.treeItems = d.tree || []; this.treeItems = d.tree || [];
this._sortTree(); this._sortTree();
} catch(e) { this.treeItems = []; this.sortedTreeItems = []; } } catch { this.treeItems = []; this.sortedTreeItems = []; }
finally { this.treeLoading = false; } finally { this.treeLoading = false; }
}, },
@@ -267,7 +267,7 @@ document.addEventListener('alpine:init', () => {
ul.appendChild(li); ul.appendChild(li);
}); });
el.appendChild(ul); el.appendChild(ul);
} catch(e) {} } catch { /* volontaire */ }
}, },
async openFile(path, sha) { async openFile(path, sha) {
@@ -286,7 +286,7 @@ document.addEventListener('alpine:init', () => {
} else { } else {
this.fileContent = '[Error loading file]'; this.fileContent = '[Error loading file]';
} }
} catch(e) { } catch {
this.fileContent = '[Error loading file]'; this.fileContent = '[Error loading file]';
} }
this.fileLoading = false; this.fileLoading = false;
@@ -343,7 +343,7 @@ document.addEventListener('alpine:init', () => {
var d = await r.json(); var d = await r.json();
window.showToast('Failed to save: ' + (d.error || 'Unknown error'), 'error'); window.showToast('Failed to save: ' + (d.error || 'Unknown error'), 'error');
} }
} catch(e) { window.showToast('Network error', 'error'); } } catch { window.showToast('Network error', 'error'); }
}, },
async deleteCurrentFile() { async deleteCurrentFile() {
@@ -358,7 +358,7 @@ document.addEventListener('alpine:init', () => {
this.filePath = ''; this.filePath = '';
await this.refreshTree(); await this.refreshTree();
} }
} catch(e) {} } catch { /* volontaire */ }
}, },
async refreshTree() { async refreshTree() {
@@ -380,7 +380,7 @@ document.addEventListener('alpine:init', () => {
try { try {
var r = await fetch('/api/gitea/projects/' + this.owner + '/' + this.repo + '/private-pages'); var r = await fetch('/api/gitea/projects/' + this.owner + '/' + this.repo + '/private-pages');
if (r.ok) { var d = await r.json(); this.privatePages = d.pages || []; } if (r.ok) { var d = await r.json(); this.privatePages = d.pages || []; }
} catch(e) {} } catch { /* volontaire */ }
}, },
newPrivate() { newPrivate() {
@@ -398,7 +398,7 @@ document.addEventListener('alpine:init', () => {
this.editingPrivateTitle = d.page.title; this.editingPrivateTitle = d.page.title;
this.editingPrivateContent = d.page.content; this.editingPrivateContent = d.page.content;
} }
} catch(e) {} } catch { /* volontaire */ }
}, },
async savePrivate() { async savePrivate() {
@@ -419,7 +419,7 @@ document.addEventListener('alpine:init', () => {
this.editingPrivateContent = ''; this.editingPrivateContent = '';
await this.loadPrivatePages(); await this.loadPrivatePages();
} }
} catch(e) {} } catch { /* volontaire */ }
}, },
// Create new file // Create new file
@@ -477,7 +477,7 @@ document.addEventListener('alpine:init', () => {
method: 'DELETE', headers: {'X-CSRF-Token': this.getCsrfToken ? this.getCsrfToken() : ''} method: 'DELETE', headers: {'X-CSRF-Token': this.getCsrfToken ? this.getCsrfToken() : ''}
}); });
if (r.ok) await this.loadPrivatePages(); if (r.ok) await this.loadPrivatePages();
} catch(e) {} } catch { /* volontaire */ }
}, },
getCsrfToken() { getCsrfToken() {
+7 -6
View File
@@ -1,3 +1,4 @@
/* exported importWizard -- appeles depuis les attributs HTML des templates */
function importWizard() { function importWizard() {
return { return {
@@ -25,11 +26,11 @@ function importWizard() {
try { try {
const r = await fetch('/api/import/sources'); const r = await fetch('/api/import/sources');
this.sources = (await r.json()).sources || []; this.sources = (await r.json()).sources || [];
} catch(e) {} } catch { /* volontaire */ }
try { try {
const c = await fetch('/api/csrf-token'); const c = await fetch('/api/csrf-token');
this.csrf = (await c.json()).csrf_token; this.csrf = (await c.json()).csrf_token;
} catch(e) {} } catch { /* volontaire */ }
}, },
humanSize(n) { return n > 1048576 ? (n/1048576).toFixed(1)+' Mo' : Math.max(1, Math.round(n/1024))+' Ko'; }, humanSize(n) { return n > 1048576 ? (n/1048576).toFixed(1)+' Mo' : Math.max(1, Math.round(n/1024))+' Ko'; },
addFiles(list) { addFiles(list) {
@@ -61,7 +62,7 @@ function importWizard() {
this.preview = merged; this.preview = merged;
this.mapping = {}; this.mapping = {};
(merged ? merged.pages : []).forEach(p => (p.schema||[]).forEach(c => { this.mapping[c.name]=c.type; })); (merged ? merged.pages : []).forEach(p => (p.schema||[]).forEach(c => { this.mapping[c.name]=c.type; }));
} catch(e) { this.error = 'Erreur réseau'; } } catch { this.error = 'Erreur réseau'; }
finally { this.busy = false; setTimeout(()=>{this.progress=0;},800); } finally { this.busy = false; setTimeout(()=>{this.progress=0;},800); }
}, },
async importOne(f) { async importOne(f) {
@@ -82,7 +83,7 @@ function importWizard() {
if (!r.ok) { f.status='error'; f.error=d.detail||'Erreur'; return null; } if (!r.ok) { f.status='error'; f.error=d.detail||'Erreur'; return null; }
f.status = (d.status==='partial' ? 'partial' : 'done'); f.status = (d.status==='partial' ? 'partial' : 'done');
return d; return d;
} catch(e) { f.status='error'; f.error='Erreur réseau'; return null; } } catch { f.status='error'; f.error='Erreur réseau'; return null; }
}, },
async doImport() { async doImport() {
this.busy = true; this.error=''; this.report=null; this.progress=0; this.busy = true; this.error=''; this.report=null; this.progress=0;
@@ -115,7 +116,7 @@ function importWizard() {
const d = await r.json(); const d = await r.json();
if (!r.ok) { this.urlError = d.detail || 'Erreur'; return; } if (!r.ok) { this.urlError = d.detail || 'Erreur'; return; }
this.report = d; this.progress = 100; this.report = d; this.progress = 100;
} catch(e) { this.urlError = 'Erreur réseau'; } } catch { this.urlError = 'Erreur réseau'; }
finally { this.busy = false; } finally { this.busy = false; }
}, },
async doForge(kind) { async doForge(kind) {
@@ -132,7 +133,7 @@ function importWizard() {
const d = await r.json(); const d = await r.json();
if (!r.ok) { this.forgeError = d.detail || 'Erreur'; return; } if (!r.ok) { this.forgeError = d.detail || 'Erreur'; return; }
this.report = d; this.progress = 100; this.report = d; this.progress = 100;
} catch(e) { this.forgeError = 'Erreur réseau'; } } catch { this.forgeError = 'Erreur réseau'; }
finally { this.busy = false; } finally { this.busy = false; }
}, },
async pollJob(jobId, f) { async pollJob(jobId, f) {
+15 -15
View File
@@ -1,3 +1,4 @@
/* exported libraryPage -- appeles depuis les attributs HTML des templates */
function libraryPage() { function libraryPage() {
return { return {
@@ -298,7 +299,7 @@ function libraryPage() {
} else { } else {
if (window.showToast) window.showToast('Not a text file', 'error'); if (window.showToast) window.showToast('Not a text file', 'error');
} }
} catch (e) { } catch {
if (window.showToast) window.showToast('Copy failed', 'error'); if (window.showToast) window.showToast('Copy failed', 'error');
} }
}, },
@@ -389,7 +390,7 @@ function libraryPage() {
headers: {'Content-Type':'application/json', 'X-CSRF-Token': csrf}, headers: {'Content-Type':'application/json', 'X-CSRF-Token': csrf},
body: JSON.stringify({ parent_id: parentId || 0 }) body: JSON.stringify({ parent_id: parentId || 0 })
}); });
} catch(e) {} } catch { /* volontaire */ }
} }
this.clearSelection(); this.clearSelection();
this.loadTab(); this.loadTab();
@@ -537,7 +538,6 @@ function libraryPage() {
doSort() { doSort() {
var s = this.sortBy; var s = this.sortBy;
if (!s) return; if (!s) return;
var self = this;
function sortNodes(nodes) { function sortNodes(nodes) {
if (!nodes) return; if (!nodes) return;
nodes.sort(function(a,b){ nodes.sort(function(a,b){
@@ -574,7 +574,7 @@ function libraryPage() {
item.children = d.items || []; item.children = d.items || [];
// Mark the tree for depth calculation // Mark the tree for depth calculation
this._markChildren(item.children, (item.depth || 0) + 1); this._markChildren(item.children, (item.depth || 0) + 1);
} catch(e) { } catch {
item.children = []; item.children = [];
} }
} }
@@ -701,7 +701,7 @@ function libraryPage() {
item.page_icon = icon; item.page_icon = icon;
this._renderTable(); this._renderTable();
if (window.showToast) window.showToast('Icon updated', 'success'); if (window.showToast) window.showToast('Icon updated', 'success');
} catch(e) { } catch {
if (window.showToast) window.showToast('Failed to update icon', 'error'); if (window.showToast) window.showToast('Failed to update icon', 'error');
} }
}, },
@@ -712,7 +712,7 @@ function libraryPage() {
var r = await fetch('/api/settings/tags/all'); var r = await fetch('/api/settings/tags/all');
var d = await r.json(); var d = await r.json();
this.workspaceTags = d.tags || []; this.workspaceTags = d.tags || [];
} catch(e) { this.workspaceTags = []; } } catch { this.workspaceTags = []; }
}, },
toggleTagFilter(tagName) { toggleTagFilter(tagName) {
@@ -771,7 +771,7 @@ function libraryPage() {
this._ctxRefreshAvail(); this._ctxRefreshAvail();
this._recomputeFlatItems(); this._recomputeFlatItems();
} }
} catch(e) {} } catch { /* volontaire */ }
}, },
async toggleFavoriteItem(item) { async toggleFavoriteItem(item) {
@@ -809,7 +809,7 @@ function libraryPage() {
this.loadTab(); this.loadTab();
this._syncSidebar(); this._syncSidebar();
if (window.showToast) window.showToast('Page duplicated', 'success'); if (window.showToast) window.showToast('Page duplicated', 'success');
} catch(e) { } catch {
if (window.showToast) window.showToast('Failed to duplicate page', 'error'); if (window.showToast) window.showToast('Failed to duplicate page', 'error');
} }
}, },
@@ -828,7 +828,7 @@ function libraryPage() {
var all = (d.items || []).filter(function(it) { return ids.indexOf(it.id) === -1; }); var all = (d.items || []).filter(function(it) { return ids.indexOf(it.id) === -1; });
this._moveAllCandidates = all; this._moveAllCandidates = all;
this.moveCandidates = all.slice(0, 30); this.moveCandidates = all.slice(0, 30);
} catch(e) { } catch {
this._moveAllCandidates = []; this._moveAllCandidates = [];
this.moveCandidates = []; this.moveCandidates = [];
} }
@@ -881,7 +881,7 @@ function libraryPage() {
if (r.ok) { if (r.ok) {
item.title = newName; item.title = newName;
} }
} catch(e) {} } catch { /* volontaire */ }
this._renderTable(); this._renderTable();
this._syncSidebar(); this._syncSidebar();
}, },
@@ -908,7 +908,7 @@ function libraryPage() {
var cr = await fetch('/api/library/children/' + parentId); var cr = await fetch('/api/library/children/' + parentId);
var cd = await cr.json(); var cd = await cr.json();
parent.children = cd.items || []; parent.children = cd.items || [];
} catch(e) {} } catch { /* volontaire */ }
this._recomputeFlatItems(); this._recomputeFlatItems();
this._renderTable(); this._renderTable();
return; return;
@@ -917,7 +917,7 @@ function libraryPage() {
if (window.fdNavigate) window.fdNavigate('/pages/' + d.id); if (window.fdNavigate) window.fdNavigate('/pages/' + d.id);
else window.location.href = '/pages/' + d.id; else window.location.href = '/pages/' + d.id;
} }
} catch(e) { } catch {
if (window.showToast) window.showToast('Failed to create page', 'error'); if (window.showToast) window.showToast('Failed to create page', 'error');
} }
}, },
@@ -996,7 +996,7 @@ function libraryPage() {
if (days < 7) return days + 'd ago'; if (days < 7) return days + 'd ago';
if (days < 30) return Math.floor(days/7) + 'w ago'; if (days < 30) return Math.floor(days/7) + 'w ago';
return dt.toLocaleDateString('en-US',{month:'short',day:'numeric',year:'numeric'}); return dt.toLocaleDateString('en-US',{month:'short',day:'numeric',year:'numeric'});
} catch(e) { return d; } } catch { return d; }
} }
}; };
} }
@@ -1029,11 +1029,11 @@ function libraryPage() {
if (el && el.__x) { el.__x.$data.peekItem = null; } if (el && el.__x) { el.__x.$data.peekItem = null; }
} }
dragging = false; dragging = false;
try { localStorage.setItem('fd_peek_width', panel.style.width); } catch(ex) {} try { localStorage.setItem('fd_peek_width', panel.style.width); } catch { /* volontaire */ }
handle.releasePointerCapture(e.pointerId); handle.releasePointerCapture(e.pointerId);
}); });
try { try {
var saved = localStorage.getItem('fd_peek_width'); var saved = localStorage.getItem('fd_peek_width');
if (saved) panel.style.width = saved; if (saved) panel.style.width = saved;
} catch(ex) {} } catch { /* volontaire */ }
})(); })();
+22 -35
View File
@@ -1,4 +1,4 @@
const LW=(()=>{try{const el=document.getElementById('lw-config');return el?JSON.parse(el.textContent):{}}catch(e){return {}}})(); const LW=(()=>{try{const el=document.getElementById('lw-config');return el?JSON.parse(el.textContent):{}}catch{return {}}})();
console.log('FLOWDECK v2.4.6 — IIFE running, about to set _wsInitData'); console.log('FLOWDECK v2.4.6 — IIFE running, about to set _wsInitData');
window._wsInitData = (function() { window._wsInitData = (function() {
@@ -17,7 +17,7 @@ window._wsInitData = (function() {
target:null, target:null,
expanded: (function() { expanded: (function() {
try { return JSON.parse(localStorage.getItem('fd_ws_expanded') || '{}'); } try { return JSON.parse(localStorage.getItem('fd_ws_expanded') || '{}'); }
catch(e) { return {}; } catch { return {}; }
})(), })(),
currentFolder: LW.current_folder_id, currentFolder: LW.current_folder_id,
searchQuery: '', searchQuery: '',
@@ -118,7 +118,7 @@ window._wsInitData = (function() {
pendingSyncCount: 0, pendingSyncCount: 0,
pinnedIds: (function() { pinnedIds: (function() {
try { return JSON.parse(localStorage.getItem('fd_ws_pinned') || '[]'); } try { return JSON.parse(localStorage.getItem('fd_ws_pinned') || '[]'); }
catch(e) { return []; } catch { return []; }
})(), })(),
// Navigation history // Navigation history
@@ -223,13 +223,13 @@ window._wsInitData = (function() {
window._wsData.closePreviewPanel(); window._wsData.closePreviewPanel();
} }
dragging = false; dragging = false;
try { localStorage.setItem('fd_peek_width', panel.style.width); } catch(ex) {} try { localStorage.setItem('fd_peek_width', panel.style.width); } catch { /* volontaire */ }
handle.releasePointerCapture(e.pointerId); handle.releasePointerCapture(e.pointerId);
}); });
try { try {
var saved = localStorage.getItem('fd_peek_width'); var saved = localStorage.getItem('fd_peek_width');
if (saved) panel.style.width = saved; if (saved) panel.style.width = saved;
} catch(ex) {} } catch { /* volontaire */ }
}, },
_recompute() { _recompute() {
@@ -252,7 +252,7 @@ window._wsInitData = (function() {
if (idx === -1) this.pinnedIds.push(id); if (idx === -1) this.pinnedIds.push(id);
else this.pinnedIds.splice(idx, 1); else this.pinnedIds.splice(idx, 1);
try { localStorage.setItem('fd_ws_pinned', JSON.stringify(this.pinnedIds)); } try { localStorage.setItem('fd_ws_pinned', JSON.stringify(this.pinnedIds)); }
catch(e) {} catch { /* volontaire */ }
this._haptic(); this._haptic();
}, },
isPinned(id) { isPinned(id) {
@@ -380,7 +380,6 @@ window._wsInitData = (function() {
_getItemPath(id) { _getItemPath(id) {
// Build folder path by walking up parent chain via tree // Build folder path by walking up parent chain via tree
var path = [];
var found = this._findInTree(this.tree, id); var found = this._findInTree(this.tree, id);
if (!found) return '—'; if (!found) return '—';
return '/' + found.path.reverse().join('/'); return '/' + found.path.reverse().join('/');
@@ -515,7 +514,7 @@ window._wsInitData = (function() {
} else { } else {
preview = '<div style="text-align:center;padding:30px;color:var(--text-tertiary)">Empty document</div>'; preview = '<div style="text-align:center;padding:30px;color:var(--text-tertiary)">Empty document</div>';
} }
} catch(e) { } catch {
preview = '<pre style="background:var(--bg-tertiary);padding:14px;border-radius:6px;overflow:auto;font-size:12px;font-family:monospace;white-space:pre-wrap;">' + this._escHtml(String(content).substring(0, 3000)) + '</pre>'; preview = '<pre style="background:var(--bg-tertiary);padding:14px;border-radius:6px;overflow:auto;font-size:12px;font-family:monospace;white-space:pre-wrap;">' + this._escHtml(String(content).substring(0, 3000)) + '</pre>';
} }
@@ -533,7 +532,7 @@ window._wsInitData = (function() {
} }
} }
body.innerHTML = preview || '<div style="color:var(--text-tertiary);text-align:center;padding:20px">(empty)</div>'; body.innerHTML = preview || '<div style="color:var(--text-tertiary);text-align:center;padding:20px">(empty)</div>';
} catch(e) { } catch {
body.innerHTML = '<div style="text-align:center;padding:20px;color:var(--text-tertiary)">Preview not available</div>'; body.innerHTML = '<div style="text-align:center;padding:20px;color:var(--text-tertiary)">Preview not available</div>';
} }
}, },
@@ -602,7 +601,7 @@ window._wsInitData = (function() {
} else { } else {
if (window.showToast) window.showToast('Not a text file', 'error'); if (window.showToast) window.showToast('Not a text file', 'error');
} }
} catch (e) { } catch {
if (window.showToast) window.showToast('Copy failed', 'error'); if (window.showToast) window.showToast('Copy failed', 'error');
} }
}, },
@@ -634,7 +633,7 @@ window._wsInitData = (function() {
if (window.appState && window.appState.refreshFavorites) window.appState.refreshFavorites(); if (window.appState && window.appState.refreshFavorites) window.appState.refreshFavorites();
if (window.showToast) window.showToast(node.favorited ? 'Added to Favorites' : 'Removed from Favorites', 'success'); if (window.showToast) window.showToast(node.favorited ? 'Added to Favorites' : 'Removed from Favorites', 'success');
} }
} catch(e) {} } catch { /* volontaire */ }
}, },
async setItemIcon(node, icon) { async setItemIcon(node, icon) {
@@ -652,7 +651,7 @@ window._wsInitData = (function() {
this.displayTree = [...this.tree]; this.displayTree = [...this.tree];
this._reloadAfterAction(); this._reloadAfterAction();
if (window.showToast) window.showToast('Icon updated', 'success'); if (window.showToast) window.showToast('Icon updated', 'success');
} catch(e) { } catch {
if (window.showToast) window.showToast('Failed to update icon', 'error'); if (window.showToast) window.showToast('Failed to update icon', 'error');
} }
}, },
@@ -741,7 +740,7 @@ window._wsInitData = (function() {
this._computeFilteredTableItems(); this._computeFilteredTableItems();
this._ctxRefreshAvail(); this._ctxRefreshAvail();
} }
} catch(e) {} } catch { /* volontaire */ }
}, },
_markTree(nodes, depth) { _markTree(nodes, depth) {
@@ -873,7 +872,7 @@ window._wsInitData = (function() {
if (node) { node.name = newName; } if (node) { node.name = newName; }
this._reloadAfterAction(); this._reloadAfterAction();
} }
} catch(e) {} } catch { /* volontaire */ }
}, },
esc(s) { esc(s) {
@@ -1012,7 +1011,7 @@ window._wsInitData = (function() {
_saveExpandedState() { _saveExpandedState() {
try { localStorage.setItem('fd_ws_expanded', JSON.stringify(this.expanded)); } try { localStorage.setItem('fd_ws_expanded', JSON.stringify(this.expanded)); }
catch(e) {} catch { /* volontaire */ }
}, },
_reloadAfterAction() { _reloadAfterAction() {
this._saveExpandedState(); this._saveExpandedState();
@@ -1051,7 +1050,6 @@ window._wsInitData = (function() {
this._saveExpandedState(); this._saveExpandedState();
if (window.appState && window.appState.refreshSidebarTree) window.appState.refreshSidebarTree(); if (window.appState && window.appState.refreshSidebarTree) window.appState.refreshSidebarTree();
if (window.FlowDeck && window.FlowDeck.syncPageTitle) window.FlowDeck.syncPageTitle(node.id, n); if (window.FlowDeck && window.FlowDeck.syncPageTitle) window.FlowDeck.syncPageTitle(node.id, n);
var self = this;
if (this.folderStack && this.folderStack.length) { if (this.folderStack && this.folderStack.length) {
this.folderStack.forEach(function(f) { if (String(f.id) === String(node.id)) f.name = n; }); this.folderStack.forEach(function(f) { if (String(f.id) === String(node.id)) f.name = n; });
} }
@@ -1155,7 +1153,6 @@ window._wsInitData = (function() {
if (!ids.length || !ids[0]) return; if (!ids.length || !ids[0]) return;
// Restore via API (soft-delete undo) — single or bulk // Restore via API (soft-delete undo) — single or bulk
var self = this; var self = this;
var restored = 0;
var total = ids.length; var total = ids.length;
function restoreOne(i) { function restoreOne(i) {
if (i >= total) { if (i >= total) {
@@ -1163,7 +1160,6 @@ window._wsInitData = (function() {
return; return;
} }
fetch('/api/local-workspace/items/' + ids[i] + '/restore', {headers: {'X-CSRF-Token': (document.cookie.match(/csrf_token=([^;]+)/)||[])[1]||''}, method: 'POST' }) fetch('/api/local-workspace/items/' + ids[i] + '/restore', {headers: {'X-CSRF-Token': (document.cookie.match(/csrf_token=([^;]+)/)||[])[1]||''}, method: 'POST' })
.then(function(r) { if (r.ok) restored++; })
.finally(function() { restoreOne(i + 1); }); .finally(function() { restoreOne(i + 1); });
} }
restoreOne(0); restoreOne(0);
@@ -1274,7 +1270,6 @@ window._wsInitData = (function() {
_fetchRetry(url, json) { _fetchRetry(url, json) {
var maxRetries = 2; var maxRetries = 2;
var delay = 300; var delay = 300;
var self = this;
return new Promise(function(resolve, reject) { return new Promise(function(resolve, reject) {
function attempt(n) { function attempt(n) {
fetch(url).then(function(r) { fetch(url).then(function(r) {
@@ -1432,7 +1427,7 @@ window._wsInitData = (function() {
} }
return lines.join('\n').substring(0, 500) || '(empty)'; return lines.join('\n').substring(0, 500) || '(empty)';
} }
} catch(e) {} } catch { /* volontaire */ }
} }
// Fallback: raw text // Fallback: raw text
return String(content).substring(0, 500); return String(content).substring(0, 500);
@@ -1575,7 +1570,6 @@ window._wsInitData = (function() {
// Find parent node id from the onclick attribute or data // Find parent node id from the onclick attribute or data
var li = parentFolder.closest('.ws-tree-item'); var li = parentFolder.closest('.ws-tree-item');
if (li) { if (li) {
var clickEl = li.querySelector('.name.folder');
// Try to extract ID from onclick or the onclick handler // Try to extract ID from onclick or the onclick handler
// Use data attributes if available, otherwise fall back // Use data attributes if available, otherwise fall back
} }
@@ -1646,7 +1640,6 @@ window._wsInitData = (function() {
var items = ev.dataTransfer.items; var items = ev.dataTransfer.items;
if (!items) return; if (!items) return;
var self = this;
var dtFiles = ev.dataTransfer.files; var dtFiles = ev.dataTransfer.files;
// Check if any item is a directory (WebKit only) // Check if any item is a directory (WebKit only)
@@ -1700,7 +1693,6 @@ window._wsInitData = (function() {
function doUpload() { function doUpload() {
// Build structure // Build structure
var structure = []; var structure = [];
var files = [];
for (var i = 0; i < allItems.length; i++) { for (var i = 0; i < allItems.length; i++) {
structure.push({path: allItems[i].path, type: allItems[i].type}); structure.push({path: allItems[i].path, type: allItems[i].type});
} }
@@ -1711,7 +1703,6 @@ window._wsInitData = (function() {
if (allItems[i].type === 'file') fileEntries.push(allItems[i]); if (allItems[i].type === 'file') fileEntries.push(allItems[i]);
} }
var resolved = 0;
var formData = new FormData(); var formData = new FormData();
formData.append('structure', JSON.stringify(structure)); formData.append('structure', JSON.stringify(structure));
if (parentId) formData.append('parent_id', parentId); if (parentId) formData.append('parent_id', parentId);
@@ -1725,10 +1716,8 @@ window._wsInitData = (function() {
var fe = fileEntries[idx]; var fe = fileEntries[idx];
fe.entry.file(function(file) { fe.entry.file(function(file) {
formData.append('files', file, fe.path); formData.append('files', file, fe.path);
resolved++;
addFile(idx + 1); addFile(idx + 1);
}, function() { }, function() {
resolved++;
addFile(idx + 1); addFile(idx + 1);
}); });
} }
@@ -1779,7 +1768,6 @@ window._wsInitData = (function() {
if (r.ok) { if (r.ok) {
this.uploadStatus = '✓ ' + d.items.length + ' item(s) uploaded'; this.uploadStatus = '✓ ' + d.items.length + ' item(s) uploaded';
this.uploadProgress = 100; this.uploadProgress = 100;
var items = d.items || [];
setTimeout(function() { setTimeout(function() {
self.uploading = false; self.uploading = false;
self._reloadAfterAction(); self._reloadAfterAction();
@@ -1789,7 +1777,7 @@ window._wsInitData = (function() {
this.uploadProgress = 0; this.uploadProgress = 0;
setTimeout(function() { self.uploading = false; }, 2000); setTimeout(function() { self.uploading = false; }, 2000);
} }
} catch(e) { } catch {
this.uploadStatus = '✗ Network error'; this.uploadStatus = '✗ Network error';
this.uploadProgress = 0; this.uploadProgress = 0;
setTimeout(function() { self.uploading = false; }, 2000); setTimeout(function() { self.uploading = false; }, 2000);
@@ -1802,7 +1790,7 @@ window._wsInitData = (function() {
var r = await fetch('/api/local-workspace/tags', { cache: 'no-store' }); var r = await fetch('/api/local-workspace/tags', { cache: 'no-store' });
var d = await r.json(); var d = await r.json();
this.workspaceTags = d.tags || []; this.workspaceTags = d.tags || [];
} catch(e) { this.workspaceTags = []; } } catch { this.workspaceTags = []; }
}, },
// Mise à jour OPTIMISTE du compteur d'un tag dans la barre de tags : // Mise à jour OPTIMISTE du compteur d'un tag dans la barre de tags :
@@ -1859,7 +1847,7 @@ window._wsInitData = (function() {
await this.loadWorkspaceTags(); await this.loadWorkspaceTags();
this._computeFilteredTableItems(); this._computeFilteredTableItems();
} }
} catch(e) {} } catch { /* volontaire */ }
this.tagInputId = null; this.tagInputId = null;
}, },
@@ -1876,7 +1864,7 @@ window._wsInitData = (function() {
await this.loadWorkspaceTags(); await this.loadWorkspaceTags();
this._computeFilteredTableItems(); this._computeFilteredTableItems();
} }
} catch(e) {} } catch { /* volontaire */ }
}, },
_updateNodeTags(nodes, itemId, tag, action, removeTagId) { _updateNodeTags(nodes, itemId, tag, action, removeTagId) {
@@ -1983,7 +1971,7 @@ window._wsInitData = (function() {
this._collectFolders(d.tree || [], folders, 0); this._collectFolders(d.tree || [], folders, 0);
this._moveAllCandidates = folders; this._moveAllCandidates = folders;
this.moveCandidates = folders.slice(0, 50); this.moveCandidates = folders.slice(0, 50);
} catch(e) { } catch {
this._moveAllCandidates = []; this._moveAllCandidates = [];
this.moveCandidates = []; this.moveCandidates = [];
} }
@@ -2014,7 +2002,7 @@ window._wsInitData = (function() {
headers: {'X-CSRF-Token': (document.cookie.match(/csrf_token=([^;]+)/)||[])[1]||'', 'Content-Type':'application/json'}, headers: {'X-CSRF-Token': (document.cookie.match(/csrf_token=([^;]+)/)||[])[1]||'', 'Content-Type':'application/json'},
body: JSON.stringify({ parent_id: parentId || null }) body: JSON.stringify({ parent_id: parentId || null })
}); });
} catch(e) {} } catch { /* volontaire */ }
} }
this.clearSelection(); this.clearSelection();
this._reloadAfterAction(); this._reloadAfterAction();
@@ -2026,7 +2014,6 @@ window._wsInitData = (function() {
// Injecter toutes les props comme globales pour Alpine (résout les 36 erreurs de scope) // Injecter toutes les props comme globales pour Alpine (résout les 36 erreurs de scope)
var _wsKeys = Object.keys(window._wsInitData); var _wsKeys = Object.keys(window._wsInitData);
for (var _i = 0; _i < _wsKeys.length; _i++) { for (var _i = 0; _i < _wsKeys.length; _i++) {
try { window[_wsKeys[_i]] = window._wsInitData[_wsKeys[_i]]; } catch(e) {} try { window[_wsKeys[_i]] = window._wsInitData[_wsKeys[_i]]; } catch { /* volontaire */ }
} }
_wsInitData = window._wsInitData;
console.log('FLOWDECK v2.4.6 — IIFE done, _wsInitData keys:', Object.keys(window._wsInitData).length); console.log('FLOWDECK v2.4.6 — IIFE done, _wsInitData keys:', Object.keys(window._wsInitData).length);
+1 -1
View File
@@ -1,4 +1,4 @@
const RT=(()=>{try{const el=document.getElementById('rt-config');return el?JSON.parse(el.textContent):{}}catch(e){return {}}})(); const RT=(()=>{try{const el=document.getElementById('rt-config');return el?JSON.parse(el.textContent):{}}catch{return {}}})();
/* eslint-disable */ /* eslint-disable */
/* ═══════════ v5.13.0 Realtime — WS gateway, présence, curseurs, merge LWW ═══════════ */ /* ═══════════ v5.13.0 Realtime — WS gateway, présence, curseurs, merge LWW ═══════════ */
+58 -58
View File
@@ -1,4 +1,5 @@
const ST=(()=>{try{const el=document.getElementById('st-config');return el?JSON.parse(el.textContent):{}}catch(e){return {}}})(); /* exported settingsInit -- appeles depuis les attributs HTML des templates */
const ST=(()=>{try{const el=document.getElementById('st-config');return el?JSON.parse(el.textContent):{}}catch{return {}}})();
function settingsInit() { function settingsInit() {
return { return {
@@ -107,13 +108,13 @@ function settingsInit() {
var r = await fetch('/api/notifications/prefs', {credentials:'same-origin'}); var r = await fetch('/api/notifications/prefs', {credentials:'same-origin'});
var d = await r.json(); var d = await r.json();
this.notifPrefs = Object.assign({comments:true, mentions:true, reminders:true, assignments:true}, d.prefs || {}); this.notifPrefs = Object.assign({comments:true, mentions:true, reminders:true, assignments:true}, d.prefs || {});
} catch(e) {} } catch { /* volontaire */ }
try { try {
var tz = await fetch('/api/notifications/timezone', {credentials:'same-origin'}); var tz = await fetch('/api/notifications/timezone', {credentials:'same-origin'});
var td = await tz.json(); var td = await tz.json();
this.userTimezone = td.timezone || ''; this.userTimezone = td.timezone || '';
this.userZones = td.zones || []; this.userZones = td.zones || [];
} catch(e) {} } catch { /* volontaire */ }
}, },
async saveNotifPrefs() { async saveNotifPrefs() {
try { try {
@@ -121,7 +122,7 @@ function settingsInit() {
method: 'POST', headers: {'Content-Type':'application/json','X-CSRF-Token': this.getCsrfToken()}, method: 'POST', headers: {'Content-Type':'application/json','X-CSRF-Token': this.getCsrfToken()},
body: JSON.stringify(this.notifPrefs) body: JSON.stringify(this.notifPrefs)
}); });
} catch(e) {} } catch { /* volontaire */ }
}, },
async saveTimezone() { async saveTimezone() {
try { try {
@@ -129,8 +130,8 @@ function settingsInit() {
method: 'POST', headers: {'Content-Type':'application/json','X-CSRF-Token': this.getCsrfToken()}, method: 'POST', headers: {'Content-Type':'application/json','X-CSRF-Token': this.getCsrfToken()},
body: JSON.stringify({timezone: this.userTimezone}) body: JSON.stringify({timezone: this.userTimezone})
}); });
if (r.ok && typeof toast === 'function') toast('Timezone saved'); if (r.ok && typeof window.showToast === 'function') window.showToast('Timezone saved');
} catch(e) {} } catch { /* volontaire */ }
}, },
async loadTags() { async loadTags() {
@@ -138,7 +139,7 @@ function settingsInit() {
var r = await fetch('/api/settings/tags/all'); var r = await fetch('/api/settings/tags/all');
var d = await r.json(); var d = await r.json();
this.allTags = d.tags || []; this.allTags = d.tags || [];
} catch(e) { this.allTags = []; } } catch { this.allTags = []; }
}, },
async createTag() { async createTag() {
@@ -169,7 +170,6 @@ function settingsInit() {
this.renamingTag = tag; this.renamingTag = tag;
this.renameValue = tag.name; this.renameValue = tag.name;
// Focus the input after Alpine renders the modal // Focus the input after Alpine renders the modal
var self = this;
this.$nextTick(function() { this.$nextTick(function() {
var input = document.querySelector('.modal-box input[type=text]'); var input = document.querySelector('.modal-box input[type=text]');
if (input) { input.focus(); input.select(); } if (input) { input.focus(); input.select(); }
@@ -213,7 +213,7 @@ function settingsInit() {
var r = await this.adminFetch('/api/admin/users'); var r = await this.adminFetch('/api/admin/users');
var d = await r.json(); var d = await r.json();
this.adminUsers = d.users || []; this.adminUsers = d.users || [];
} catch(e) { this.adminUsers = []; } } catch { this.adminUsers = []; }
await this.loadAdminStats(); await this.loadAdminStats();
}, },
@@ -221,7 +221,7 @@ function settingsInit() {
try { try {
var r = await this.adminFetch('/api/admin/stats'); var r = await this.adminFetch('/api/admin/stats');
this.adminStats = await r.json(); this.adminStats = await r.json();
} catch(e) { this.adminStats = {}; } } catch { this.adminStats = {}; }
}, },
async loadAdminAudit() { async loadAdminAudit() {
@@ -249,7 +249,7 @@ function settingsInit() {
const logs = d.logs || []; const logs = d.logs || [];
this.auditLogs = (reset !== false) ? logs : this.auditLogs.concat(logs); this.auditLogs = (reset !== false) ? logs : this.auditLogs.concat(logs);
this.auditHasMore = logs.length >= this.auditPageSize; this.auditHasMore = logs.length >= this.auditPageSize;
} catch(e) { } catch {
if (reset !== false) this.auditLogs = []; if (reset !== false) this.auditLogs = [];
this.auditHasMore = false; this.auditHasMore = false;
} }
@@ -278,7 +278,7 @@ function settingsInit() {
var d = await r.json(); var d = await r.json();
window.showToast(d.error || 'Failed to create user', 'error'); window.showToast(d.error || 'Failed to create user', 'error');
} }
} catch(e) { window.showToast('Network error', 'error'); } } catch { window.showToast('Network error', 'error'); }
}, },
async adminUpdateUser() { async adminUpdateUser() {
@@ -295,7 +295,7 @@ function settingsInit() {
this.editingUser = null; this.editingUser = null;
await this.loadAdminUsers(); await this.loadAdminUsers();
} }
} catch(e) {} } catch { /* volontaire */ }
}, },
async adminDeleteUser(id) { async adminDeleteUser(id) {
@@ -303,7 +303,7 @@ function settingsInit() {
try { try {
await this.adminFetch('/api/admin/users/' + id, { method: 'DELETE' }); await this.adminFetch('/api/admin/users/' + id, { method: 'DELETE' });
await this.loadAdminUsers(); await this.loadAdminUsers();
} catch(e) {} } catch { /* volontaire */ }
}, },
// ── LLM / Agent ── // ── LLM / Agent ──
@@ -447,7 +447,7 @@ function settingsInit() {
} }
if (this.selectedProviderId) this.keyForm(this.selectedProviderId); if (this.selectedProviderId) this.keyForm(this.selectedProviderId);
this.syncLlmStatus(); this.syncLlmStatus();
} catch(e) {} } catch { /* volontaire */ }
}, },
async loadProviderModels(id) { async loadProviderModels(id) {
var f = this.keyForm(id); var f = this.keyForm(id);
@@ -474,7 +474,7 @@ function settingsInit() {
} else { } else {
f.msg = 'Erreur: ' + (d.error || 'échec de connexion'); f.msg = 'Erreur: ' + (d.error || 'échec de connexion');
} }
} catch(e) { f.msg = 'Erreur réseau'; } } catch { f.msg = 'Erreur réseau'; }
finally { f.modelLoading = false; } finally { f.modelLoading = false; }
}, },
async saveUserKey(id) { async saveUserKey(id) {
@@ -505,7 +505,7 @@ function settingsInit() {
} else { } else {
f.msg = d.detail || 'Erreur lors de l\'enregistrement'; f.msg = d.detail || 'Erreur lors de l\'enregistrement';
} }
} catch(e) { f.msg = 'Erreur réseau'; } } catch { f.msg = 'Erreur réseau'; }
finally { f.saving = false; } finally { f.saving = false; }
}, },
globalNeedsKeyFor(id) { globalNeedsKeyFor(id) {
@@ -534,7 +534,7 @@ function settingsInit() {
this._setProviderState(id, false, d.error || 'échec de connexion'); this._setProviderState(id, false, d.error || 'échec de connexion');
f.msg = '✗ Test échoué : ' + (d.error || 'échec de connexion'); f.msg = '✗ Test échoué : ' + (d.error || 'échec de connexion');
} }
} catch(e) { } catch {
this._setProviderState(id, false, 'Erreur réseau'); this._setProviderState(id, false, 'Erreur réseau');
f.msg = 'Erreur réseau'; f.msg = 'Erreur réseau';
} }
@@ -559,7 +559,7 @@ function settingsInit() {
} else { } else {
f.msg = d.detail || 'Erreur lors de la suppression'; f.msg = d.detail || 'Erreur lors de la suppression';
} }
} catch(e) { f.msg = 'Erreur réseau'; } } catch { f.msg = 'Erreur réseau'; }
finally { f.deleting = false; } finally { f.deleting = false; }
}, },
async loadLlmConfig() { async loadLlmConfig() {
@@ -576,7 +576,7 @@ function settingsInit() {
api_base: d.api_base || (defp && defp.base_url) || ''}; api_base: d.api_base || (defp && defp.base_url) || ''};
this.applyLlmModels(); this.applyLlmModels();
this.syncLlmStatus(); this.syncLlmStatus();
} catch(e) {} } catch { /* volontaire */ }
}, },
applyLlmModels() { applyLlmModels() {
var p = this.providerById(this.llmForm.provider); var p = this.providerById(this.llmForm.provider);
@@ -619,7 +619,7 @@ function settingsInit() {
} else { } else {
this.llmMsg = d.detail || 'Erreur lors de l\'enregistrement'; this.llmMsg = d.detail || 'Erreur lors de l\'enregistrement';
} }
} catch(e) { this.llmMsg = 'Erreur réseau'; } } catch { this.llmMsg = 'Erreur réseau'; }
finally { this.llmSaving = false; } finally { this.llmSaving = false; }
}, },
async resetGlobalLlm() { async resetGlobalLlm() {
@@ -644,7 +644,7 @@ function settingsInit() {
} else { } else {
this.llmMsg = d.detail || 'Erreur lors de la réinitialisation'; this.llmMsg = d.detail || 'Erreur lors de la réinitialisation';
} }
} catch(e) { this.llmMsg = 'Erreur réseau'; } } catch { this.llmMsg = 'Erreur réseau'; }
finally { this.llmSaving = false; } finally { this.llmSaving = false; }
}, },
async testLlm() { async testLlm() {
@@ -669,7 +669,7 @@ function settingsInit() {
this._setProviderState(this.llmForm.provider, d.ok, d.error || ''); this._setProviderState(this.llmForm.provider, d.ok, d.error || '');
if (d.ok) cur.verified_model = d.model || ''; if (d.ok) cur.verified_model = d.model || '';
} }
} catch(e) { this.llmTestOk = false; this.llmTestMsg = 'Erreur réseau'; } } catch { this.llmTestOk = false; this.llmTestMsg = 'Erreur réseau'; }
finally { this.llmTesting = false; } finally { this.llmTesting = false; }
}, },
getCompletedLlmTest() { return this.llmTestMsg; }, getCompletedLlmTest() { return this.llmTestMsg; },
@@ -698,7 +698,7 @@ function settingsInit() {
} else { } else {
this.accountMsg = '✗ ' + (d.error || 'Error'); this.accountMsg = '✗ ' + (d.error || 'Error');
} }
} catch(e) { this.accountMsg = '✗ Network error'; } } catch { this.accountMsg = '✗ Network error'; }
this.accountSaving = false; this.accountSaving = false;
}, },
@@ -737,7 +737,7 @@ function settingsInit() {
var r = await fetch('/api/gitea/status'); var r = await fetch('/api/gitea/status');
var d = await r.json(); var d = await r.json();
this.giteaLinked = d.linked || false; this.giteaLinked = d.linked || false;
} catch(e) { this.giteaLinked = false; } } catch { this.giteaLinked = false; }
}, },
async disconnectGitea() { async disconnectGitea() {
@@ -745,41 +745,41 @@ function settingsInit() {
try { try {
var r = await fetch('/api/gitea/disconnect', { method: 'DELETE', headers: {'X-CSRF-Token': this.getCsrfToken()} }); var r = await fetch('/api/gitea/disconnect', { method: 'DELETE', headers: {'X-CSRF-Token': this.getCsrfToken()} });
if (r.ok) { this.giteaLinked = false; } if (r.ok) { this.giteaLinked = false; }
} catch(e) {} } catch { /* volontaire */ }
}, },
async loadGithubStatus() { async loadGithubStatus() {
try { try {
var r = await fetch('/api/github/status'); var r = await fetch('/api/github/status');
var d = await r.json(); var d = await r.json();
this.githubLinked = d.linked || false; this.githubLinked = d.linked || false;
} catch(e) { this.githubLinked = false; } } catch { this.githubLinked = false; }
}, },
async disconnectGithub() { async disconnectGithub() {
if (!confirm('Disconnect GitHub? You can reconnect anytime.')) return; if (!confirm('Disconnect GitHub? You can reconnect anytime.')) return;
try { try {
var r = await fetch('/api/github/disconnect', { method: 'DELETE', headers: {'X-CSRF-Token': this.getCsrfToken()} }); var r = await fetch('/api/github/disconnect', { method: 'DELETE', headers: {'X-CSRF-Token': this.getCsrfToken()} });
if (r.ok) { this.githubLinked = false; } if (r.ok) { this.githubLinked = false; }
} catch(e) {} } catch { /* volontaire */ }
}, },
async loadAutomations() { async loadAutomations() {
try { await this.loadCollectionsForForm(); } catch(e) {} try { await this.loadCollectionsForForm(); } catch { /* volontaire */ }
try { try {
var r = await fetch('/workspace/automations', {credentials:'same-origin'}); var r = await fetch('/workspace/automations', {credentials:'same-origin'});
var d = await r.json(); var d = await r.json();
this.automations = d.automations || []; this.automations = d.automations || [];
} catch(e) { this.automations = []; } } catch { this.automations = []; }
}, },
async loadCollectionsForForm() { async loadCollectionsForForm() {
try { try {
var r = await fetch('/db/api', {credentials:'same-origin'}); var r = await fetch('/db/api', {credentials:'same-origin'});
var d = await r.json(); var d = await r.json();
this.globalCollections = d.collections || []; this.globalCollections = d.collections || [];
} catch(e) { this.globalCollections = []; } } catch { this.globalCollections = []; }
}, },
async saveAutomation() { async saveAutomation() {
if (!this.af.name.trim()) { window.showToast && window.showToast('Nom requis', 'error'); return; } if (!this.af.name.trim()) { window.showToast && window.showToast('Nom requis', 'error'); return; }
try { JSON.parse(this.af.condition_json || '[]'); } catch(e) { window.showToast && window.showToast('Conditions JSON invalide', 'error'); return; } try { JSON.parse(this.af.condition_json || '[]'); } catch { window.showToast && window.showToast('Conditions JSON invalide', 'error'); return; }
try { JSON.parse(this.af.actions_json || '[]'); } catch(e) { window.showToast && window.showToast('Actions JSON invalide', 'error'); return; } try { JSON.parse(this.af.actions_json || '[]'); } catch { window.showToast && window.showToast('Actions JSON invalide', 'error'); return; }
var payload = { var payload = {
name: this.af.name, name: this.af.name,
trigger_type: this.af.trigger_type, trigger_type: this.af.trigger_type,
@@ -801,7 +801,7 @@ function settingsInit() {
window.showToast && window.showToast(this.editAutomationId ? 'Automation mise à jour' : 'Automation créée'); window.showToast && window.showToast(this.editAutomationId ? 'Automation mise à jour' : 'Automation créée');
this.cancelEditAutomation(); this.cancelEditAutomation();
await this.loadAutomations(); await this.loadAutomations();
} catch(e) { window.showToast && window.showToast('Erreur réseau', 'error'); } } catch { window.showToast && window.showToast('Erreur réseau', 'error'); }
}, },
editAutomation(a) { editAutomation(a) {
this.editAutomationId = a.id; this.editAutomationId = a.id;
@@ -837,7 +837,7 @@ function settingsInit() {
headers: {'Content-Type':'application/json','X-CSRF-Token': this.getCsrfToken()}, headers: {'Content-Type':'application/json','X-CSRF-Token': this.getCsrfToken()},
body: JSON.stringify(payload) }); body: JSON.stringify(payload) });
if (r.ok) await this.loadAutomations(); if (r.ok) await this.loadAutomations();
} catch(e) {} } catch { /* volontaire */ }
}, },
async runAutomation(id) { async runAutomation(id) {
try { try {
@@ -850,7 +850,7 @@ function settingsInit() {
this.autoRuns.push({ created_at: new Date().toLocaleString(), trigger_source: 'manual', status: d.status || 'fired', detail: d.detail || '' }); this.autoRuns.push({ created_at: new Date().toLocaleString(), trigger_source: 'manual', status: d.status || 'fired', detail: d.detail || '' });
window.showToast && window.showToast('Résultat : ' + (d.status || '') + ' — ' + (d.detail || '')); window.showToast && window.showToast('Résultat : ' + (d.status || '') + ' — ' + (d.detail || ''));
await this.loadAutomations(); await this.loadAutomations();
} catch(e) {} } catch { /* volontaire */ }
}, },
async deleteAutomation(id) { async deleteAutomation(id) {
if (!confirm('Supprimer cette automation ?')) return; if (!confirm('Supprimer cette automation ?')) return;
@@ -858,7 +858,7 @@ function settingsInit() {
var r = await fetch('/workspace/automations/' + id, { method:'DELETE', credentials:'same-origin', var r = await fetch('/workspace/automations/' + id, { method:'DELETE', credentials:'same-origin',
headers: {'X-CSRF-Token': this.getCsrfToken()} }); headers: {'X-CSRF-Token': this.getCsrfToken()} });
if (r.ok) await this.loadAutomations(); if (r.ok) await this.loadAutomations();
} catch(e) {} } catch { /* volontaire */ }
}, },
// ── v5.2.0 API tokens ── // ── v5.2.0 API tokens ──
async loadApiTokens() { async loadApiTokens() {
@@ -866,7 +866,7 @@ function settingsInit() {
var r = await fetch('/api/settings/tokens', {headers: {'X-CSRF-Token': (document.cookie.match(/csrf_token=([^;]+)/)||[])[1]||''}, credentials:'same-origin'}); var r = await fetch('/api/settings/tokens', {headers: {'X-CSRF-Token': (document.cookie.match(/csrf_token=([^;]+)/)||[])[1]||''}, credentials:'same-origin'});
var d = await r.json(); var d = await r.json();
this.apiTokens = d.tokens || []; this.apiTokens = d.tokens || [];
} catch(e) { this.apiTokens = []; } } catch { this.apiTokens = []; }
}, },
async createApiToken() { async createApiToken() {
var name = this.tokenName.trim(); var name = this.tokenName.trim();
@@ -879,12 +879,12 @@ function settingsInit() {
this.newToken = d; this.newToken = d;
this.tokenName = ''; this.tokenName = '';
await this.loadApiTokens(); await this.loadApiTokens();
} catch(e) { window.showToast && window.showToast('Erreur réseau', 'error'); } } catch { window.showToast && window.showToast('Erreur réseau', 'error'); }
}, },
async copyNewToken() { async copyNewToken() {
if (!this.newToken) return; if (!this.newToken) return;
try { await navigator.clipboard.writeText(this.newToken.token); window.showToast && window.showToast('Token copié'); } try { await navigator.clipboard.writeText(this.newToken.token); window.showToast && window.showToast('Token copié'); }
catch(e) { window.showToast && window.showToast(this.newToken.token, 'error'); } catch { window.showToast && window.showToast(this.newToken.token, 'error'); }
}, },
async revokeApiToken(t) { async revokeApiToken(t) {
if (!confirm('Révoquer le token « ' + t.name + ' » ? Il ne fonctionnera plus immédiatement.')) return; if (!confirm('Révoquer le token « ' + t.name + ' » ? Il ne fonctionnera plus immédiatement.')) return;
@@ -892,7 +892,7 @@ function settingsInit() {
var r = await fetch('/api/settings/tokens/' + t.id, {method:'DELETE', credentials:'same-origin', var r = await fetch('/api/settings/tokens/' + t.id, {method:'DELETE', credentials:'same-origin',
headers: {'X-CSRF-Token': this.getCsrfToken()} }); headers: {'X-CSRF-Token': this.getCsrfToken()} });
if (r.ok) await this.loadApiTokens(); if (r.ok) await this.loadApiTokens();
} catch(e) {} } catch { /* volontaire */ }
}, },
// ── v5.2.0 Sessions ── // ── v5.2.0 Sessions ──
async loadSessions() { async loadSessions() {
@@ -900,7 +900,7 @@ function settingsInit() {
var r = await fetch('/api/settings/sessions', {credentials:'same-origin'}); var r = await fetch('/api/settings/sessions', {credentials:'same-origin'});
var d = await r.json(); var d = await r.json();
this.sessions = d.sessions || []; this.sessions = d.sessions || [];
} catch(e) { this.sessions = []; } } catch { this.sessions = []; }
}, },
async revokeSession(s) { async revokeSession(s) {
var msg = s.is_current ? 'Déconnecter cet appareil ?' : 'Révoquer cette session ?'; var msg = s.is_current ? 'Déconnecter cet appareil ?' : 'Révoquer cette session ?';
@@ -912,7 +912,7 @@ function settingsInit() {
if (s.is_current) window.location = '/auth/login?provider=local'; if (s.is_current) window.location = '/auth/login?provider=local';
await this.loadSessions(); await this.loadSessions();
} }
} catch(e) {} } catch { /* volontaire */ }
}, },
// ── v6.2.0 Web Clipper ── // ── v6.2.0 Web Clipper ──
async loadClipperDevices() { async loadClipperDevices() {
@@ -920,14 +920,14 @@ function settingsInit() {
var r = await fetch('/api/v2/web-clipper/devices', {credentials:'same-origin'}); var r = await fetch('/api/v2/web-clipper/devices', {credentials:'same-origin'});
var d = await r.json(); var d = await r.json();
this.clipperDevices = d.devices || []; this.clipperDevices = d.devices || [];
} catch(e) { this.clipperDevices = []; } } catch { this.clipperDevices = []; }
}, },
async revokeClipperDevice(d) { async revokeClipperDevice(d) {
if (!confirm('Révoquer l\'extension « ' + (d.device_name || d.device_id) + ' » ?')) return; if (!confirm('Révoquer l\'extension « ' + (d.device_name || d.device_id) + ' » ?')) return;
try { try {
var r = await fetch('/api/v2/web-clipper/devices/' + d.id, {method:'DELETE', credentials:'same-origin', headers: {'X-CSRF-Token': this.getCsrfToken()}}); var r = await fetch('/api/v2/web-clipper/devices/' + d.id, {method:'DELETE', credentials:'same-origin', headers: {'X-CSRF-Token': this.getCsrfToken()}});
if (r.ok) await this.loadClipperDevices(); if (r.ok) await this.loadClipperDevices();
} catch(e) {} } catch { /* volontaire */ }
}, },
async testClip() { async testClip() {
this.clipTesting = true; this.clipTestMsg = ''; this.clipTestOk = false; this.clipTesting = true; this.clipTestMsg = ''; this.clipTestOk = false;
@@ -940,7 +940,7 @@ function settingsInit() {
var d = await r.json(); var d = await r.json();
if (r.ok) { this.clipTestOk = true; this.clipTestMsg = '✓ Page créée : #' + d.page_id + ' — ' + d.title; await this.loadClipperDevices(); } if (r.ok) { this.clipTestOk = true; this.clipTestMsg = '✓ Page créée : #' + d.page_id + ' — ' + d.title; await this.loadClipperDevices(); }
else this.clipTestMsg = d.detail || 'Erreur'; else this.clipTestMsg = d.detail || 'Erreur';
} catch(e) { this.clipTestMsg = 'Erreur réseau'; } } catch { this.clipTestMsg = 'Erreur réseau'; }
finally { this.clipTesting = false; } finally { this.clipTesting = false; }
}, },
// ── v6.7.0 SSO / Enterprise (admin) ── // ── v6.7.0 SSO / Enterprise (admin) ──
@@ -957,8 +957,8 @@ function settingsInit() {
async copySsoMetadata() { async copySsoMetadata() {
try { try {
await navigator.clipboard.writeText(this.ssoMetadataUrl()); await navigator.clipboard.writeText(this.ssoMetadataUrl());
if (typeof toast === 'function') toast('SP metadata URL copiée'); if (typeof window.showToast === 'function') window.showToast('SP metadata URL copiée');
} catch(e) {} } catch { /* volontaire */ }
}, },
async loadSsoConfig() { async loadSsoConfig() {
this.ssoMsg = ''; this.ssoMsg = '';
@@ -994,7 +994,7 @@ function settingsInit() {
this.ssoGroups = (d.groups_mapping || []).map(function(g){ return {sso_group: g.sso_group || '', workspace_role: g.workspace_role || 'editor', workspace_id: g.workspace_id || ''}; }); this.ssoGroups = (d.groups_mapping || []).map(function(g){ return {sso_group: g.sso_group || '', workspace_role: g.workspace_role || 'editor', workspace_id: g.workspace_id || ''}; });
} }
} }
} catch(e) {} } catch { /* volontaire */ }
try { try {
var w = await fetch('/api/v2/sso/workspaces', {credentials:'same-origin'}); var w = await fetch('/api/v2/sso/workspaces', {credentials:'same-origin'});
if (w.ok) { if (w.ok) {
@@ -1002,13 +1002,13 @@ function settingsInit() {
this.ssoWorkspaces = wd.workspaces || []; this.ssoWorkspaces = wd.workspaces || [];
this.ssoProvisioned = wd.provisioned_users || this.ssoProvisioned; this.ssoProvisioned = wd.provisioned_users || this.ssoProvisioned;
} }
} catch(e) {} } catch { /* volontaire */ }
}, },
async saveSsoConfig() { async saveSsoConfig() {
this.ssoMsg = ''; this.ssoMsg = '';
var amap = {}; var amap = {};
try { amap = JSON.parse(this.ssoAttrJson || '{}'); } try { amap = JSON.parse(this.ssoAttrJson || '{}'); }
catch(e) { this.ssoMsg = 'Attribute mapping : JSON invalide'; this.ssoOk = false; return; } catch { this.ssoMsg = 'Attribute mapping : JSON invalide'; this.ssoOk = false; return; }
if (amap === null || typeof amap !== 'object' || Array.isArray(amap)) { if (amap === null || typeof amap !== 'object' || Array.isArray(amap)) {
this.ssoMsg = 'Attribute mapping : doit être un objet JSON'; this.ssoOk = false; return; this.ssoMsg = 'Attribute mapping : doit être un objet JSON'; this.ssoOk = false; return;
} }
@@ -1024,10 +1024,10 @@ function settingsInit() {
delete payload.id; delete payload.id;
try { try {
var r = await this.adminFetch('/api/v2/sso/config', {method:'POST', headers:{'Content-Type':'application/json'}, body: JSON.stringify(payload)}); var r = await this.adminFetch('/api/v2/sso/config', {method:'POST', headers:{'Content-Type':'application/json'}, body: JSON.stringify(payload)});
var d = null; try { d = await r.json(); } catch(e) {} var d = null; try { d = await r.json(); } catch { /* volontaire */ }
if (!r.ok) { this.ssoMsg = (d && (d.detail || d.error)) || ('Erreur ' + r.status); this.ssoOk = false; } if (!r.ok) { this.ssoMsg = (d && (d.detail || d.error)) || ('Erreur ' + r.status); this.ssoOk = false; }
else { this.ssoMsg = 'Configuration enregistrée'; this.ssoOk = true; await this.loadSsoConfig(); } else { this.ssoMsg = 'Configuration enregistrée'; this.ssoOk = true; await this.loadSsoConfig(); }
} catch(e) { this.ssoMsg = 'Erreur réseau'; this.ssoOk = false; } } catch { this.ssoMsg = 'Erreur réseau'; this.ssoOk = false; }
finally { this.ssoSaving = false; } finally { this.ssoSaving = false; }
}, },
async disableSso() { async disableSso() {
@@ -1037,16 +1037,16 @@ function settingsInit() {
var r = await this.adminFetch('/api/v2/sso/config', {method:'DELETE'}); var r = await this.adminFetch('/api/v2/sso/config', {method:'DELETE'});
if (r.ok) { this.ssoMsg = 'SSO désactivé'; this.ssoOk = true; await this.loadSsoConfig(); } if (r.ok) { this.ssoMsg = 'SSO désactivé'; this.ssoOk = true; await this.loadSsoConfig(); }
else { this.ssoMsg = 'Erreur ' + r.status; this.ssoOk = false; } else { this.ssoMsg = 'Erreur ' + r.status; this.ssoOk = false; }
} catch(e) { this.ssoMsg = 'Erreur réseau'; this.ssoOk = false; } } catch { this.ssoMsg = 'Erreur réseau'; this.ssoOk = false; }
}, },
async syncSsoGroups() { async syncSsoGroups() {
this.ssoMsg = ''; this.ssoMsg = '';
try { try {
var r = await this.adminFetch('/api/v2/sso/sync', {method:'POST', headers:{'Content-Type':'application/json'}, body:'{}'}); var r = await this.adminFetch('/api/v2/sso/sync', {method:'POST', headers:{'Content-Type':'application/json'}, body:'{}'});
var d = null; try { d = await r.json(); } catch(e) {} var d = null; try { d = await r.json(); } catch { /* volontaire */ }
if (r.ok) { this.ssoMsg = 'Groupes re-synchronisés — ' + (d && d.updated || 0) + '/' + (d && d.users || 0) + ' utilisateur(s)'; this.ssoOk = true; await this.loadSsoConfig(); } if (r.ok) { this.ssoMsg = 'Groupes re-synchronisés — ' + (d && d.updated || 0) + '/' + (d && d.users || 0) + ' utilisateur(s)'; this.ssoOk = true; await this.loadSsoConfig(); }
else { this.ssoMsg = (d && d.detail) || ('Erreur ' + r.status); this.ssoOk = false; } else { this.ssoMsg = (d && d.detail) || ('Erreur ' + r.status); this.ssoOk = false; }
} catch(e) { this.ssoMsg = 'Erreur réseau'; this.ssoOk = false; } } catch { this.ssoMsg = 'Erreur réseau'; this.ssoOk = false; }
}, },
addSsoGroup() { this.ssoGroups.push({sso_group:'', workspace_role:'editor', workspace_id: this.ssoCfg.default_workspace_id || ''}); }, addSsoGroup() { this.ssoGroups.push({sso_group:'', workspace_role:'editor', workspace_id: this.ssoCfg.default_workspace_id || ''}); },
removeSsoGroup(i) { this.ssoGroups.splice(i, 1); }, removeSsoGroup(i) { this.ssoGroups.splice(i, 1); },
@@ -1056,7 +1056,7 @@ function settingsInit() {
var r = await this.adminFetch('/api/settings/backups'); var r = await this.adminFetch('/api/settings/backups');
var d = await r.json(); var d = await r.json();
this.backups = d.backups || []; this.backups = d.backups || [];
} catch(e) { this.backups = []; } } catch { this.backups = []; }
}, },
async runBackup() { async runBackup() {
this.backupRunning = true; this.backupMsg = ''; this.backupOk = false; this.backupRunning = true; this.backupMsg = ''; this.backupOk = false;
@@ -1065,7 +1065,7 @@ function settingsInit() {
var d = await r.json(); var d = await r.json();
if (r.ok) { this.backupOk = true; this.backupMsg = '✓ Sauvegarde créée : ' + d.filename; await this.loadBackups(); } if (r.ok) { this.backupOk = true; this.backupMsg = '✓ Sauvegarde créée : ' + d.filename; await this.loadBackups(); }
else { this.backupMsg = d.detail || 'Erreur'; } else { this.backupMsg = d.detail || 'Erreur'; }
} catch(e) { this.backupMsg = 'Erreur réseau'; } } catch { this.backupMsg = 'Erreur réseau'; }
finally { this.backupRunning = false; } finally { this.backupRunning = false; }
}, },
closeSettings() { closeSettings() {
+5 -4
View File
@@ -1,3 +1,4 @@
/* exported workspacesPage -- appeles depuis les attributs HTML des templates */
function workspacesPage() { function workspacesPage() {
return { return {
@@ -105,7 +106,7 @@ function workspacesPage() {
myLogin = meData.user?.login || 'Me'; myLogin = meData.user?.login || 'Me';
if (myLogin.includes('_')) myLogin = myLogin.split('_').pop(); // strip gitea_ prefix if present if (myLogin.includes('_')) myLogin = myLogin.split('_').pop(); // strip gitea_ prefix if present
} }
} catch(e) {} } catch { /* volontaire */ }
// User repos (no org filter) // User repos (no org filter)
try { try {
@@ -117,7 +118,7 @@ function workspacesPage() {
groups.push({org: myLogin, avatar: '', projects: repos.map(r => ({...r, owner: r.owner || {login: myLogin}}))}); groups.push({org: myLogin, avatar: '', projects: repos.map(r => ({...r, owner: r.owner || {login: myLogin}}))});
} }
} }
} catch(e) {} } catch { /* volontaire */ }
// Org repos // Org repos
for (const org of orgs) { for (const org of orgs) {
@@ -129,13 +130,13 @@ function workspacesPage() {
groups.push({org: org.username || org.login || org.name, avatar: org.avatar_url || '', projects: d.projects}); groups.push({org: org.username || org.login || org.name, avatar: org.avatar_url || '', projects: d.projects});
} }
} }
} catch(e) {} } catch { /* volontaire */ }
} }
this.giteaGroups = groups; this.giteaGroups = groups;
this.giteaTotal = groups.reduce((sum, g) => sum + g.projects.length, 0); this.giteaTotal = groups.reduce((sum, g) => sum + g.projects.length, 0);
this.giteaStatus = 'ok'; this.giteaStatus = 'ok';
} catch(e) { } catch {
this.giteaStatus = 'error'; this.giteaStatus = 'error';
} }
}, },