feat: dossier perso (#194) — vaults home-* en tête de l'arborescence, icône maison, compose de test
- frontend/js/sidebar.js : tri stable _homeFirst appliqué à la source des deux listes de vaults (loadVaults + soft refresh) → les vaults home-<user> passent en premier, arborescence et sélecteurs cohérents. - frontend/js/viewer.js : getVaultIcon renvoie l'icône lucide "home" pour home-* (même safeCreateIcons / stroke currentColor que les autres). - docker-compose.test-win.yml : montage test_home:/vaults/Home + OBSIGATE_HOME_ROOT=/vaults/Home pour tester la feature en local ; test_home/ ajouté au .gitignore. - Tests : sidebar-filters.test.mjs +2 (icône maison, gemme violette inchangée), vérifié live sur l'instance 2020 (ordre + svg.lucide-home).
This commit is contained in:
@@ -44,6 +44,7 @@ test_dir/video/
|
||||
test_vault/images/
|
||||
test_vault/markdown/
|
||||
test_vault/budget.xlsx
|
||||
test_home/
|
||||
|
||||
# Tauri updater signing keys (private key — never commit)
|
||||
desktop/*.key
|
||||
|
||||
+20
-1
@@ -6,7 +6,7 @@ Format basé sur [Keep a Changelog](https://keepachangelog.com/fr/1.1.0/),
|
||||
et [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
||||
|
||||
> **En cours de développement** : les changements à venir sont listés dans la section
|
||||
> [Unreleased](#unreleased). La dernière version livrée est **2.64.0**.
|
||||
> [Unreleased](#unreleased). La dernière version livrée est **2.65.0**.
|
||||
|
||||
---
|
||||
|
||||
@@ -14,6 +14,25 @@ et [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
||||
|
||||
---
|
||||
|
||||
## [2.65.0] — 2026-10-10
|
||||
|
||||
### Ajouté
|
||||
|
||||
- **#194 (UI) — Dossier personnel visible dans l'arborescence**
|
||||
- Les vaults `home-<user>` s'affichent **en premier** dans l'arborescence de
|
||||
la barre latérale (tri stable appliqué à la source, `frontend/js/sidebar.js`,
|
||||
donc aussi les sélecteurs de vault).
|
||||
- Icône **maison** lucide (`data-lucide="home"`, même style/`stroke:
|
||||
currentColor` que les autres icônes) via `getVaultIcon()` —
|
||||
`frontend/js/viewer.js`.
|
||||
- `docker-compose.test-win.yml` : montage `test_home:/vaults/Home` +
|
||||
`OBSIGATE_HOME_ROOT=/vaults/Home` pour tester la feature en local
|
||||
(dossier `test_home/` ignoré par git).
|
||||
- Tests : `sidebar-filters.test.mjs` +2 (icône maison pour `home-*`,
|
||||
gemme violette inchangée ailleurs).
|
||||
|
||||
---
|
||||
|
||||
## [2.64.0] — 2026-10-10
|
||||
|
||||
### Ajouté
|
||||
|
||||
+3
-3
@@ -4,7 +4,7 @@
|
||||
|
||||
**Porte d'entrée web ultra-léger pour vos vaults Obsidian** — Accédez, naviguez et recherchez dans toutes vos notes Obsidian depuis n'importe quel appareil via une interface web moderne et responsive.
|
||||
|
||||
[]()
|
||||
[]()
|
||||
[](https://opensource.org/licenses/MIT)
|
||||
[](https://www.docker.com/)
|
||||
[](https://www.python.org/)
|
||||
@@ -977,8 +977,8 @@ Ce projet est sous licence **MIT** — voir le fichier [LICENSE](LICENSE) pour l
|
||||
|
||||
## 📝 Changelog
|
||||
|
||||
Consultez le [CHANGELOG.md](./CHANGELOG.md) pour l'historique complet de toutes les versions (v1.0.0 → v2.64.0).
|
||||
Consultez le [CHANGELOG.md](./CHANGELOG.md) pour l'historique complet de toutes les versions (v1.0.0 → v2.65.0).
|
||||
|
||||
---
|
||||
|
||||
*Projet : ObsiGate | Version : 2.64.0 | Dernière mise à jour : Septembre 2026*
|
||||
*Projet : ObsiGate | Version : 2.65.0 | Dernière mise à jour : Septembre 2026*
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
**Ultra-light web gateway for your Obsidian vaults** — Access, browse, and search all your Obsidian notes from any device via a modern, responsive web interface.
|
||||
|
||||
[]()
|
||||
[]()
|
||||
[](https://opensource.org/licenses/MIT)
|
||||
[](https://www.docker.com/)
|
||||
[](https://www.python.org/)
|
||||
@@ -1152,8 +1152,8 @@ This project is licensed under the **MIT License** - see the [LICENSE](LICENSE)
|
||||
|
||||
## 📝 Changelog
|
||||
|
||||
See [CHANGELOG.md](./CHANGELOG.md) for the complete version history (v1.0.0 → v2.64.0).
|
||||
See [CHANGELOG.md](./CHANGELOG.md) for the complete version history (v1.0.0 → v2.65.0).
|
||||
|
||||
---
|
||||
|
||||
*Project: ObsiGate | Version: 2.64.0 | Last updated: September 2026*
|
||||
*Project: ObsiGate | Version: 2.65.0 | Last updated: September 2026*
|
||||
|
||||
Generated
+1
-1
@@ -2626,7 +2626,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "obsigate-desktop"
|
||||
version = "2.64.0"
|
||||
version = "2.65.0"
|
||||
dependencies = [
|
||||
"chrono",
|
||||
"env_logger",
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "obsigate-desktop"
|
||||
version = "2.64.0"
|
||||
version = "2.65.0"
|
||||
description = "ObsiGate Desktop — Porte d'entrée native pour vos vaults Obsidian"
|
||||
authors = ["Bruno Charest"]
|
||||
edition = "2021"
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"$schema": "https://raw.githubusercontent.com/nicedoc/obsigate/main/desktop/tauri.conf.schema.json",
|
||||
"productName": "ObsiGate",
|
||||
"version": "2.64.0",
|
||||
"version": "2.65.0",
|
||||
"identifier": "com.obsigate.desktop",
|
||||
"build": {
|
||||
"frontendDist": "../frontend",
|
||||
|
||||
@@ -21,12 +21,17 @@ services:
|
||||
volumes:
|
||||
- /c/dev/git/python/ObsiGate/test_vault:/vaults/TestVault
|
||||
- /c/dev/git/python/ObsiGate/test_dir:/vaults/TestDir
|
||||
# #194 : racine des dossiers persos — UN seul montage pour tous les
|
||||
# utilisateurs (dossier hôte : mkdir test_home à côté du dépôt).
|
||||
- /c/dev/git/python/ObsiGate/test_home:/vaults/Home
|
||||
- obsigate_data:/app/data
|
||||
environment:
|
||||
- VAULT_1_NAME=TestVault
|
||||
- VAULT_1_PATH=/vaults/TestVault
|
||||
- DIR_1_NAME=TestDir
|
||||
- DIR_1_PATH=/vaults/TestDir
|
||||
# #194 : dossier personnel par utilisateur = <racine>/home-<user>
|
||||
- OBSIGATE_HOME_ROOT=/vaults/Home
|
||||
- OBSIGATE_AUTH_ENABLED=true
|
||||
- OBSIGATE_ADMIN_USER=admin
|
||||
- OBSIGATE_ADMIN_PASSWORD=test123
|
||||
|
||||
@@ -341,6 +341,8 @@ Avant de corriger quoi que ce soit, un agent IA doit :
|
||||
|
||||
| 2026-10-09 | #194 | Fonctionnalité | `backend/user_home.py` (nouveau), `backend/indexer.py`, `backend/auth/router.py`, `backend/routers/vaults.py`, `backend/main.py`, `docker-compose.yml`, `tests/test_user_home.py` (nouveau), `tests/test_auth_api.py`, `docs/features/user-home-194.md` (nouveau), `docs/ROADMAP.md`, `CHANGELOG.md`, `README.md`, `README.fr.md` | **#194 — dossier personnel par utilisateur** : chaque compte reçoit `<OBSIGATE_HOME_ROOT>/<user>` monté comme vault propre `home-<user>` (option A validée) — l'isolation s'appuie sur l'ACL par vault **existante** (`check_vault_access`), aucune ACL par chemin inventée. `backend/user_home.py` : `ensure_user_home()` idempotent (mkdir → `add_vault_to_index` → `persist_vault` → watcher → SSE → octroi dans `user.vaults`) appelé à `POST /api/auth/admin/users` **et** au démarrage (`ensure_all_user_homes()` : migration des users existants, réparation des dossiers/registres manquants, sweep des vaults `home-*` orphelins dont l'utilisateur a disparu hors route — garde `Path.parent == racine` pour ne jamais toucher à un vault admin homonyme) ; `release_user_home()` à la suppression (index/watcher/registre refermés, **dossier conservé**). **Blocage levé** : registre persistant `data/vaults.json` fusionné par `load_vault_config()` — avant, tout vault ajouté à la volée (`/api/vaults/add`) disparaissait au premier reindex complet et au redémarrage. Correctif au passage : `reload_single_vault()` remet `vault_config[name]` après `remove_vault_from_index()`. Réponse du POST = vaults réactualisés (l'instantané de `create_user` était antérieur à l'octroi). Déploiement : montage unique `/NFS/OBSIDIAN_DOC/Home:/vaults/Home` + `OBSIGATE_HOME_ROOT` (absente = feature inactive, dev/tests/desktop inchangés). Vérifié : `test_user_home.py` 12/12 (création, idempotence, username invalide, persistance après `load_vault_config`, retrait, isolation `check_vault_access`, orphelins), `test_auth_api.py::TestUserHome` 2/2, suite **1703 passed / 2 skipped**, ruff backend 0, mypy 114 fichiers 0, `validate-imports` 42 modules / 372 exports, `unit.test.mjs` 13/13 | ✅ livré (en attente vérif utilisateur) |
|
||||
|
||||
| 2026-10-09 | #194 | Fonctionnalité (UI) | `frontend/js/sidebar.js`, `frontend/js/viewer.js`, `docker-compose.test-win.yml`, `.gitignore`, `tests/frontend/sidebar-filters.test.mjs`, `docs/ROADMAP.md`, `docs/features/user-home-194.md`, `CHANGELOG.md` | **#194 (incrément UI)** : les vaults `home-<user>` s'affichent **en premier** dans l'arborescence de la sidebar — tri stable appliqué à la source (`_homeFirst` dans `loadVaults()` et dans le soft-refresh, donc `state.allVaults`, l'arborescence et les sélecteurs restent cohérents) — et portent l'icône **maison** lucide (`data-lucide="home"` via `getVaultIcon`, même `safeCreateIcons`/`stroke: currentColor` que les autres icônes, thème-aware). Compose de test : `test_home:/vaults/Home` + `OBSIGATE_HOME_ROOT=/vaults/Home` (dossier `test_home/` ignoré par git). Vérifié : `sidebar-filters.test.mjs` 8→**10/10**, `validate-imports` 42 modules / 372 exports, `unit.test.mjs` 13/13, suites voisines (ai-sidebar, toolbar-order, search-facets, pane-manager, editor-inline) vertes, **live Playwright sur l'instance 2020** : ordre `home-admin, home-bruno, TestDir, TestVault` + `svg.lucide-home` rendu (placeholder `<i>` remplacé) | ✅ livré (en attente vérif utilisateur) |
|
||||
|
||||
---
|
||||
|
||||
## 📜 Historique des bugs résolus
|
||||
|
||||
+5
-2
@@ -1,6 +1,6 @@
|
||||
# ObsiGate — Roadmap
|
||||
|
||||
> **Version :** 2.64.0 | **Dernière mise à jour :** 2026-10-10
|
||||
> **Version :** 2.65.0 | **Dernière mise à jour :** 2026-10-10
|
||||
> **Ce fichier ne contient que le travail à venir** (🔵 En cours + ⚪ Backlog) et un index compact
|
||||
> vers les fonctionnalités livrées.
|
||||
> - **Méthode de livraison à appliquer pour toute tâche : [DELIVERY_WORKFLOW.md](./DELIVERY_WORKFLOW.md)**
|
||||
@@ -46,7 +46,10 @@
|
||||
- [x] Service `ensure_user_home()` idempotent : mkdir + vault + octroi, appelé à la création
|
||||
d'un user et au démarrage (réparation/migration)
|
||||
- [x] Retrait au suppression de compte (index/watcher/registre) sans supprimer le dossier
|
||||
- [x] Montage Docker + `OBSIGATE_HOME_ROOT` dans `docker-compose.yml`
|
||||
- [x] Montage Docker + `OBSIGATE_HOME_ROOT` (prod **et** compose de test
|
||||
`docker-compose.test-win.yml` → `test_home:/vaults/Home`)
|
||||
- [x] UI : vaults `home-*` en **premier** dans l'arborescence + icône maison
|
||||
lucide (`getVaultIcon`), vérifié live sur l'instance 2020
|
||||
- [x] Tests (création, persistance après rebuild, isolation 403 entre users) + docs
|
||||
|
||||
---
|
||||
|
||||
@@ -70,6 +70,21 @@ suppression du compte, racine `/NFS/OBSIDIAN_DOC/Home` montée `/vaults/Home`.
|
||||
→ vault refermé / dossier conservé) + absence de dossier sans
|
||||
`OBSIGATE_HOME_ROOT`.
|
||||
|
||||
## UI — arborescence (incrément)
|
||||
|
||||
- **Ordre** : tri stable `home-*` en premier, appliqué à la source
|
||||
(`frontend/js/sidebar.js::_homeFirst`, sur les deux sites qui alimentent
|
||||
`state.allVaults`) → arborescence, sélecteurs et refreshs homogènes.
|
||||
- **Icône** : `getVaultIcon()` (`frontend/js/viewer.js`) renvoie
|
||||
`icon("home", size)` pour `home-*` → même pipeline lucide que le reste de
|
||||
l'app (`safeCreateIcons`, `stroke: currentColor`, suit le thème).
|
||||
- **Test local** : `docker-compose.test-win.yml` monte
|
||||
`test_home:/vaults/Home` + `OBSIGATE_HOME_ROOT=/vaults/Home`
|
||||
(`test_home/` est dans `.gitignore`).
|
||||
- **Vérifié live** (instance 2020, Playwright) : ordre
|
||||
`home-admin, home-bruno, TestDir, TestVault`, `svg.lucide-home` rendu,
|
||||
placeholder `<i>` remplacé.
|
||||
|
||||
## Impact utilisateur
|
||||
|
||||
Aucune nouvelle chaîne i18n : les noms de vault sont des données, la liste
|
||||
|
||||
@@ -220,8 +220,15 @@ async function loadVaultSettings() {
|
||||
// ---------------------------------------------------------------------------
|
||||
// Sidebar — Vault tree
|
||||
// ---------------------------------------------------------------------------
|
||||
// #194 : le dossier personnel (vault « home-<user> ») s'affiche en premier
|
||||
// dans l'arborescence. Tri stable fait sur place, à la source de toutes les
|
||||
// listes (arborescence, sélecteurs, state.allVaults).
|
||||
const _homeFirst = (a, b) =>
|
||||
(String(b?.name).startsWith("home-") ? 1 : 0) - (String(a?.name).startsWith("home-") ? 1 : 0);
|
||||
|
||||
async function loadVaults() {
|
||||
const vaults = await api("/api/vaults");
|
||||
vaults.sort(_homeFirst);
|
||||
state.allVaults = vaults;
|
||||
const container = document.getElementById("vault-tree");
|
||||
container.innerHTML = "";
|
||||
@@ -426,6 +433,7 @@ export async function refreshSidebarTreePreservingState() {
|
||||
// 2. Soft update: vault names/counts without wiping the tree
|
||||
try {
|
||||
const vaults = await api("/api/vaults");
|
||||
vaults.sort(_homeFirst);
|
||||
state.allVaults = vaults;
|
||||
vaults.forEach((v) => {
|
||||
const vItem = document.querySelector(`.vault-item[data-vault="${CSS.escape(v.name)}"]`);
|
||||
|
||||
@@ -7579,6 +7579,10 @@ export function attachTreeItemLongPress(itemEl, getMenuData) {
|
||||
}
|
||||
|
||||
export function getVaultIcon(vaultName, size = 16) {
|
||||
// Dossier personnel (#194) : icône maison, même style lucide que le reste.
|
||||
if (typeof vaultName === "string" && vaultName.startsWith("home-")) {
|
||||
return icon("home", size);
|
||||
}
|
||||
const v = state.allVaults.find((val) => val.name === vaultName);
|
||||
const type = v ? v.type : "VAULT";
|
||||
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "obsigate",
|
||||
"version": "2.64.0",
|
||||
"version": "2.65.0",
|
||||
"description": "**Porte d'entrée web ultra-léger pour vos vaults Obsidian** — Accédez, naviguez et recherchez dans toutes vos notes Obsidian depuis n'importe quel appareil via une interface web moderne et responsive.",
|
||||
"main": "patch.js",
|
||||
"directories": {
|
||||
|
||||
@@ -176,6 +176,19 @@ await test("filterSavedSearches combines with the type pills", async () => {
|
||||
assert.equal(visibleSaved(), 3, "clearing both filters restores everything");
|
||||
});
|
||||
|
||||
// ── #194 : icône du dossier personnel ──
|
||||
await test("getVaultIcon returns the lucide house icon for home-* vaults", async () => {
|
||||
const homeIcon = viewerMod.getVaultIcon("home-bruno", 16);
|
||||
assert.equal(homeIcon.tagName.toLowerCase(), "i", "placeholder lucide (comme les autres icônes)");
|
||||
assert.equal(homeIcon.getAttribute("data-lucide"), "home", "icône maison lucide");
|
||||
assert.equal(homeIcon.style.width, "16px", "taille demandée respectée");
|
||||
});
|
||||
|
||||
await test("getVaultIcon is unchanged for regular vaults", async () => {
|
||||
const vaultIcon = viewerMod.getVaultIcon("Recettes", 16);
|
||||
assert.equal(vaultIcon.tagName.toLowerCase(), "svg", "gemme violette SVG d'origine");
|
||||
});
|
||||
|
||||
// ── Summary ──
|
||||
console.log(`\n${passCount}/${testCount} tests passed`);
|
||||
if (passCount !== testCount) {
|
||||
|
||||
Reference in New Issue
Block a user