fix: rebuild ui.js, search.js, viewer.js from app.js with shell script (no truncation)
CI / lint (push) Successful in 12s
CI / security (push) Successful in 8s
CI / test (push) Successful in 16s
CI / build (push) Successful in 3s

This commit is contained in:
2026-05-28 16:54:15 -04:00
parent 97d14d867a
commit 7c927ca54e
3 changed files with 269 additions and 86 deletions
+181 -14
View File
@@ -1,5 +1,7 @@
/* ObsiGate — Auto-extracted module */
import { state } from './state.js';;
/* ObsiGate — UI module */
import { state } from './state.js';
import { openFile } from './viewer.js';
import { safeCreateIcons } from './utils.js';
// ---------------------------------------------------------------------------
// Right Sidebar Manager
// ---------------------------------------------------------------------------
@@ -34,9 +36,9 @@ export const RightSidebarManager = {
if (!sidebar) return;
if (state.rightSidebarVisible) {
if (rightSidebarVisible) {
sidebar.classList.remove("hidden");
sidebar.style.width = `${state.rightSidebarWidth}px`;
sidebar.style.width = `${rightSidebarWidth}px`;
if (handle) handle.classList.remove("hidden");
if (tocBtn) {
tocBtn.classList.add("active");
@@ -65,7 +67,7 @@ export const RightSidebarManager = {
toggle() {
state.rightSidebarVisible = !state.rightSidebarVisible;
localStorage.setItem("obsigate-right-sidebar-visible", state.rightSidebarVisible);
localStorage.setItem("obsigate-right-sidebar-visible", rightSidebarVisible);
this.applyState();
},
@@ -116,7 +118,7 @@ export const RightSidebarManager = {
document.body.style.cursor = "";
document.body.style.userSelect = "";
localStorage.setItem("obsigate-right-sidebar-width", state.rightSidebarWidth);
localStorage.setItem("obsigate-right-sidebar-width", rightSidebarWidth);
};
handle.addEventListener("mousedown", onMouseDown);
@@ -125,6 +127,7 @@ export const RightSidebarManager = {
},
};
// ---------------------------------------------------------------------------
// Theme
// ---------------------------------------------------------------------------
@@ -197,6 +200,7 @@ function closeHeaderMenu() {
menuDropdown.classList.remove("active");
}
// ---------------------------------------------------------------------------
// Custom Dropdowns
// ---------------------------------------------------------------------------
@@ -327,6 +331,7 @@ function populateCustomDropdown(dropdownId, optionsList, defaultValue) {
});
}
// ---------------------------------------------------------------------------
// Toast notifications
// ---------------------------------------------------------------------------
@@ -359,6 +364,7 @@ function showToast(message, type) {
}, 3500);
}
// ---------------------------------------------------------------------------
// Sidebar toggle (desktop)
// ---------------------------------------------------------------------------
@@ -385,6 +391,7 @@ function initSidebarToggle() {
});
}
// ---------------------------------------------------------------------------
// Mobile sidebar
// ---------------------------------------------------------------------------
@@ -411,6 +418,7 @@ function closeMobileSidebar() {
if (overlay) overlay.classList.remove("active");
}
// ---------------------------------------------------------------------------
// Resizable sidebar (horizontal)
// ---------------------------------------------------------------------------
@@ -452,6 +460,7 @@ function initSidebarResize() {
});
}
// ---------------------------------------------------------------------------
// Resizable tag section (vertical)
// ---------------------------------------------------------------------------
@@ -494,6 +503,7 @@ function initTagResize() {
});
}
// ---------------------------------------------------------------------------
// Frontmatter Accent Card Builder
// ---------------------------------------------------------------------------
@@ -557,11 +567,163 @@ function buildFrontmatterCard(frontmatter) {
// ZONE 2: Body 2 columns
const leftCol = el("div", { class: "ac-col" }, [
el("div", { class: "ac-row" }, [el("span", { class: "ac-k" }, [document.createTextNode("auteur")]), el("span", { class: "ac-v" }, [document.createTextNode(frontmatter.auteur || "—")])]),
el("div", { class: "ac-row" }, [el("span", { class: "ac-k" }, [document.createTextNode("catégorie")]), el("span", { class: "ac-v" }, [document.createTextNode(frontmatter.catégorie || frontmatter.categorie ||
el("div", { class: "ac-row" }, [el("span", { class: "ac-k" }, [document.createTextNode("catégorie")]), el("span", { class: "ac-v" }, [document.createTextNode(frontmatter.catégorie || frontmatter.categorie || "—")])]),
el("div", { class: "ac-row" }, [el("span", { class: "ac-k" }, [document.createTextNode("statut")]), el("span", { class: "ac-v" }, [document.createTextNode(frontmatter.statut || "—")])]),
el("div", { class: "ac-row" }, [el("span", { class: "ac-k" }, [document.createTextNode("aliases")]), el("span", { class: "ac-v muted" }, [document.createTextNode(frontmatter.aliases && frontmatter.aliases.length > 0 ? frontmatter.aliases.join(", ") : "[]")])]),
]);
... [OUTPUT TRUNCATED - 6724 chars omitted out of 56724 total] ...
const rightCol = el("div", { class: "ac-col" }, [
el("div", { class: "ac-row" }, [el("span", { class: "ac-k" }, [document.createTextNode("creation_date")]), el("span", { class: "ac-v mono" }, [document.createTextNode(formatDate(frontmatter.creation_date))])]),
el("div", { class: "ac-row" }, [el("span", { class: "ac-k" }, [document.createTextNode("modification_date")]), el("span", { class: "ac-v mono" }, [document.createTextNode(formatDate(frontmatter.modification_date))])]),
el("div", { class: "ac-row" }, [el("span", { class: "ac-k" }, [document.createTextNode("publish")]), el("span", { class: "ac-v" }, [document.createTextNode(String(frontmatter.publish || false))])]),
el("div", { class: "ac-row" }, [el("span", { class: "ac-k" }, [document.createTextNode("favoris")]), el("span", { class: "ac-v" }, [document.createTextNode(String(frontmatter.favoris || false))])]),
]);
'div');
const acBody = el("div", { class: "ac-body" }, [leftCol, rightCol]);
// ZONE 3: Tags row
const tagPills = [];
if (frontmatter.tags && frontmatter.tags.length > 0) {
frontmatter.tags.forEach((tag) => {
tagPills.push(el("span", { class: "ac-tag" }, [document.createTextNode(tag)]));
});
}
const acTagsRow = el("div", { class: "ac-tags-row" }, [el("span", { class: "ac-tags-k" }, [document.createTextNode("tags")]), el("div", { class: "ac-tags-wrap" }, tagPills)]);
// ZONE 4: Flags row
const flagChips = [];
booleanFlags.forEach((flag) => {
const chipClass = flag.value ? "flag-chip on" : "flag-chip off";
flagChips.push(el("span", { class: chipClass }, [el("span", { class: "flag-dot" }), document.createTextNode(flag.key)]));
});
const acFlagsRow = el("div", { class: "ac-flags-row" }, [el("span", { class: "ac-flags-k" }, [document.createTextNode("flags")]), ...flagChips]);
// Assemble the card
const acCard = el("div", { class: "ac-card" }, [acTop, acBody, acTagsRow, acFlagsRow]);
// Toggle functionality
fmHeader.addEventListener("click", () => {
isOpen = !isOpen;
if (isOpen) {
acCard.style.display = "block";
chevron.classList.remove("closed");
chevron.classList.add("open");
} else {
acCard.style.display = "none";
chevron.classList.remove("open");
chevron.classList.add("closed");
}
safeCreateIcons();
});
// Wrap in section
const fmSection = el("div", { class: "fm-section" }, [fmHeader, acCard]);
return fmSection;
}
// ---------------------------------------------------------------------------
// File Operations Manager
// ---------------------------------------------------------------------------
const FileOperations = {
showCreateDirectoryModal(vault, parentPath) {
const overlay = this._createModalOverlay();
const modal = document.createElement('div');
modal.className = 'obsigate-modal';
modal.innerHTML = `
<div class="obsigate-modal-header">
<h3 class="obsigate-modal-title">Créer un dossier</h3>
</div>
<div class="obsigate-modal-body">
<div class="modal-form-group">
<label class="modal-label">Nom du dossier</label>
<input type="text" class="modal-input" id="dir-name-input" placeholder="nouveau-dossier" />
<div class="modal-hint">Dans: ${parentPath || '/'}</div>
<div class="modal-error" id="dir-error" style="display:none;"></div>
</div>
</div>
<div class="obsigate-modal-footer">
<button class="modal-btn" id="dir-cancel-btn">Annuler</button>
<button class="modal-btn primary" id="dir-create-btn">Créer</button>
</div>
`;
overlay.appendChild(modal);
document.body.appendChild(overlay);
setTimeout(() => overlay.classList.add('active'), 10);
const input = modal.querySelector('#dir-name-input');
const errorDiv = modal.querySelector('#dir-error');
const createBtn = modal.querySelector('#dir-create-btn');
const cancelBtn = modal.querySelector('#dir-cancel-btn');
input.focus();
const validateName = (name) => {
if (!name.trim()) return 'Le nom ne peut pas être vide';
if (/[/\\:*?"<>|]/.test(name)) return 'Caractères interdits: / \\ : * ? " < > |';
return null;
};
input.addEventListener('input', () => {
const error = validateName(input.value);
if (error) {
errorDiv.textContent = error;
errorDiv.style.display = 'block';
input.classList.add('error');
} else {
errorDiv.style.display = 'none';
input.classList.remove('error');
}
});
const create = async () => {
const name = input.value.trim();
const error = validateName(name);
if (error) {
errorDiv.textContent = error;
errorDiv.style.display = 'block';
return;
}
const path = parentPath ? `${parentPath}/${name}` : name;
createBtn.disabled = true;
createBtn.textContent = 'Création...';
try {
await api(`/api/directory/${encodeURIComponent(vault)}`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ path }),
});
showToast(`Dossier "${name}" créé`, 'success');
this._closeModal(overlay);
await refreshSidebarTreePreservingState();
} catch (err) {
showToast(err.message || 'Erreur lors de la création', 'error');
createBtn.disabled = false;
createBtn.textContent = 'Créer';
}
};
createBtn.addEventListener('click', create);
cancelBtn.addEventListener('click', () => this._closeModal(overlay));
input.addEventListener('keydown', (e) => {
if (e.key === 'Enter') create();
if (e.key === 'Escape') this._closeModal(overlay);
});
},
showCreateFileModal(vault, parentPath) {
const overlay = this._createModalOverlay();
const modal = document.createElement('div');
modal.className = 'obsigate-modal';
modal.innerHTML = `
<div class="obsigate-modal-header">
@@ -743,10 +905,10 @@ function buildFrontmatterCard(frontmatter) {
if (type === 'file' && state.currentVault === vault && state.currentPath === path) {
await openFile(vault, nextPath);
} else if (type === 'directory' && state.currentVault === vault && currentPath && (state.currentPath === path || state.currentPath.startsWith(`${path}/`))) {
const suffix = state.currentPath === path ? '' : state.currentPath.slice(path.length);
} else if (type === 'directory' && state.currentVault === vault && currentPath && (state.currentPath === path || currentPath.startsWith(`${path}/`))) {
const suffix = state.currentPath === path ? '' : currentPath.slice(path.length);
state.currentPath = `${nextPath}${suffix}`;
await focusPathInSidebar(vault, state.currentPath, { alignToTop: false });
await focusPathInSidebar(vault, currentPath, { alignToTop: false });
}
showToast(type === 'directory' ? 'Dossier renommé' : 'Fichier renommé', 'success');
@@ -830,7 +992,7 @@ function buildFrontmatterCard(frontmatter) {
this._closeModal(overlay);
await refreshSidebarTreePreservingState();
if (state.currentVault === vault && currentPath && state.currentPath.startsWith(path)) {
if (state.currentVault === vault && currentPath && currentPath.startsWith(path)) {
showWelcome();
}
} catch (err) {
@@ -923,6 +1085,7 @@ function buildFrontmatterCard(frontmatter) {
}
};
// ---------------------------------------------------------------------------
// Find in Page Manager
// ---------------------------------------------------------------------------
@@ -1344,6 +1507,7 @@ const FindInPageManager = {
},
};
// ---------------------------------------------------------------------------
// Init
// ---------------------------------------------------------------------------
@@ -1414,6 +1578,7 @@ async function init() {
safeCreateIcons();
}
// ---- Modify openFile to use TabManager ----
const _originalOpenFile = openFile;
openFile = function(vault, path) {
@@ -1453,4 +1618,6 @@ const _origInit2 = init;
init = function() {
_origInit2();
TabManager.init();
};
};