Files
flowdeck/static/js/workspaces.js
T
bruno 8d0d69e7b8
FlowDeck CI / test (push) Failing after 3h9m51s
FlowDeck CI / lint (push) Successful in 1m54s
FlowDeck CI / docker (push) Skipped
fix: A27 lint terminé — eslint 0/0 (285 warnings nettoyés) (v7.25.0)
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
2026-10-01 21:30:37 -04:00

155 lines
5.2 KiB
JavaScript

/* exported workspacesPage -- appeles depuis les attributs HTML des templates */
function workspacesPage() {
return {
workspaces: [],
activeId: null,
showCreate: false,
showRename: false,
wsName: '',
renameTarget: null,
// Gitea
giteaStatus: 'loading', // loading|ok|not_linked|error
giteaGroups: [],
giteaTotal: 0,
activeOrg: 'all',
giteaSearch: '',
get filteredGroups() {
var self = this;
var q = (this.giteaSearch || '').toLowerCase();
var groups = this.activeOrg === 'all' ? this.giteaGroups : this.giteaGroups.filter(function(g) { return g.org === self.activeOrg; });
if (!q) return groups;
return groups.map(function(g) {
return {org: g.org, avatar: g.avatar, projects: g.projects.filter(function(p) {
return p.name.toLowerCase().includes(q) || (p.description||'').toLowerCase().includes(q);
})};
}).filter(function(g) { return g.projects.length > 0; });
},
async init() {
await this.load();
await this.loadGitea();
},
async load() {
const r = await fetch('/api/workspaces');
const d = await r.json();
this.workspaces = d.workspaces || [];
this.activeId = d.active_id;
},
async selectLocal(ws) {
await fetch(`/api/workspaces/${ws.id}/select`, {headers: {'X-CSRF-Token': (document.cookie.match(/csrf_token=([^;]+)/)||[])[1]||''}, method:'POST'});
window.location = '/local-workspace';
},
async doCreate() {
if (!this.wsName.trim()) return;
await fetch('/api/workspaces', {
method:'POST',
headers:{'X-CSRF-Token': (document.cookie.match(/csrf_token=([^;]+)/)||[])[1]||'', 'Content-Type':'application/json'},
body:JSON.stringify({name:this.wsName.trim()})
});
this.wsName = '';
this.showCreate = false;
await this.load();
},
renameWs(ws) {
this.renameTarget = ws;
this.wsName = ws.name;
this.showRename = true;
},
async doRename() {
if (!this.wsName.trim()||!this.renameTarget) return;
await fetch(`/api/workspaces/${this.renameTarget.id}`, {
method:'PUT',
headers:{'X-CSRF-Token': (document.cookie.match(/csrf_token=([^;]+)/)||[])[1]||'', 'Content-Type':'application/json'},
body:JSON.stringify({name:this.wsName.trim()})
});
this.wsName = '';
this.showRename = false;
this.renameTarget = null;
await this.load();
},
async deleteWs(ws) {
if (!confirm(`Delete workspace "${ws.name}" and all its pages?`)) return;
await fetch(`/api/workspaces/${ws.id}`, {headers: {'X-CSRF-Token': (document.cookie.match(/csrf_token=([^;]+)/)||[])[1]||''}, method:'DELETE'});
await this.load();
},
// ── Gitea ──
async loadGitea() {
this.giteaStatus = 'loading';
try {
// Get orgs
const orgsRes = await fetch('/api/gitea/orgs');
if (orgsRes.status === 401) { this.giteaStatus = 'not_linked'; return; }
if (!orgsRes.ok) { this.giteaStatus = 'error'; return; }
const orgsData = await orgsRes.json();
const orgs = orgsData.orgs || [];
// Fetch repos: user repos + org repos
const groups = [];
// Get username for the "personal" tab
let myLogin = 'Me';
try {
const meRes = await fetch('/auth/user');
if (meRes.ok) {
const meData = await meRes.json();
myLogin = meData.user?.login || 'Me';
if (myLogin.includes('_')) myLogin = myLogin.split('_').pop(); // strip gitea_ prefix if present
}
} catch { /* volontaire */ }
// User repos (no org filter)
try {
const userRes = await fetch('/api/gitea/projects');
if (userRes.ok) {
const d = await userRes.json();
const repos = d.projects || [];
if (repos.length) {
groups.push({org: myLogin, avatar: '', projects: repos.map(r => ({...r, owner: r.owner || {login: myLogin}}))});
}
}
} catch { /* volontaire */ }
// Org repos
for (const org of orgs) {
try {
const res = await fetch('/api/gitea/projects?org=' + encodeURIComponent(org.username || org.login || org.name));
if (res.ok) {
const d = await res.json();
if (d.projects && d.projects.length) {
groups.push({org: org.username || org.login || org.name, avatar: org.avatar_url || '', projects: d.projects});
}
}
} catch { /* volontaire */ }
}
this.giteaGroups = groups;
this.giteaTotal = groups.reduce((sum, g) => sum + g.projects.length, 0);
this.giteaStatus = 'ok';
} catch {
this.giteaStatus = 'error';
}
},
openGitea(proj) {
const owner = proj.owner?.login || proj.owner?.username || proj.full_name?.split('/')[0] || '';
const repo = proj.name;
if (owner && repo) {
// Set workspace cookie so sidebar shows tree
document.cookie = 'flowdeck_workspace=gitea:' + owner + ':' + repo + ';path=/;SameSite=Lax';
window.location = `/gitea-workspace?owner=${encodeURIComponent(owner)}&repo=${encodeURIComponent(repo)}`;
}
}
};
}