feat: premier lancement ObsiGate + section Configuration harmonisée (#160)
- Premier lancement : %USERPROFILE%\ObsiGate créé et monté comme vault de
démarrage « ObsiGate » (remplace voute_obsidian), vault_path dessus,
racine home nommée d'après son dernier segment (fin du « bruno » codé en
dur), champs de fenêtre préservés.
- Document « Prise en main.md » embarqué dans le binaire
(include_str!) et écrit dans ce répertoire si absent — jamais écrasé.
- Section « 🖥️ Vaults & dossiers (Desktop) » refondue : markup à classes
(zéro style inline), bloc CSS desktop-roots-* sur variables (motif
webauthn-key-item), boutons .config-btn-sm primaire/secondaire,
cibles tactiles 44px en mobile.
- Tests : test_default_first_run_config, test_welcome_doc_embedded
(cargo test 28 passed), suites frontend vertes, E2E 123/123.
This commit is contained in:
+19
-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).
|
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
|
> **En cours de développement** : les changements à venir sont listés dans la section
|
||||||
> [Unreleased](#unreleased). La dernière version livrée est **2.50.2**.
|
> [Unreleased](#unreleased). La dernière version livrée est **2.51.0**.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -14,6 +14,24 @@ et [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
## [2.51.0] — 2026-10-03
|
||||||
|
|
||||||
|
### Ajouté
|
||||||
|
|
||||||
|
- **#160 — Premier lancement professionnel + section Configuration harmonisée**
|
||||||
|
- **Premier lancement** : `%USERPROFILE%\ObsiGate` est créé et monté comme
|
||||||
|
vault de démarrage (nom « ObsiGate », remplace `voute_obsidian`), le
|
||||||
|
contexte initial s'ouvre dessus, le dossier home reste une racine nommée
|
||||||
|
d'après son chemin (fin du « bruno » codé en dur), et le document
|
||||||
|
**`Prise en main.md`** (contenu embarqué) y est écrit une seule fois —
|
||||||
|
jamais écrasé.
|
||||||
|
- **Section « 🖥️ Vaults & dossiers (Desktop) »** refondue : lignes au motif
|
||||||
|
des cartes de la configuration (icône, nom, chemin tronqué), boutons
|
||||||
|
Retirer/Ajouter en `.config-btn-sm` secondaire/ primaire, zéro style
|
||||||
|
inline, variables CSS uniquement, cibles tactiles 44px en mobile.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
## [2.50.2] — 2026-10-02
|
## [2.50.2] — 2026-10-02
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|||||||
+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.
|
**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://opensource.org/licenses/MIT)
|
||||||
[](https://www.docker.com/)
|
[](https://www.docker.com/)
|
||||||
[](https://www.python.org/)
|
[](https://www.python.org/)
|
||||||
@@ -976,8 +976,8 @@ Ce projet est sous licence **MIT** — voir le fichier [LICENSE](LICENSE) pour l
|
|||||||
|
|
||||||
## 📝 Changelog
|
## 📝 Changelog
|
||||||
|
|
||||||
Consultez le [CHANGELOG.md](./CHANGELOG.md) pour l'historique complet de toutes les versions (v1.0.0 → v2.50.2).
|
Consultez le [CHANGELOG.md](./CHANGELOG.md) pour l'historique complet de toutes les versions (v1.0.0 → v2.51.0).
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
*Projet : ObsiGate | Version : 2.50.2 | Dernière mise à jour : Septembre 2026*
|
*Projet : ObsiGate | Version : 2.51.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.
|
**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://opensource.org/licenses/MIT)
|
||||||
[](https://www.docker.com/)
|
[](https://www.docker.com/)
|
||||||
[](https://www.python.org/)
|
[](https://www.python.org/)
|
||||||
@@ -1151,8 +1151,8 @@ This project is licensed under the **MIT License** - see the [LICENSE](LICENSE)
|
|||||||
|
|
||||||
## 📝 Changelog
|
## 📝 Changelog
|
||||||
|
|
||||||
See [CHANGELOG.md](./CHANGELOG.md) for the complete version history (v1.0.0 → v2.50.2).
|
See [CHANGELOG.md](./CHANGELOG.md) for the complete version history (v1.0.0 → v2.51.0).
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
*Project: ObsiGate | Version: 2.50.2 | Last updated: September 2026*
|
*Project: ObsiGate | Version: 2.51.0 | Last updated: September 2026*
|
||||||
|
|||||||
Generated
+1
-1
@@ -2626,7 +2626,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "obsigate-desktop"
|
name = "obsigate-desktop"
|
||||||
version = "2.50.2"
|
version = "2.51.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"chrono",
|
"chrono",
|
||||||
"env_logger",
|
"env_logger",
|
||||||
|
|||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "obsigate-desktop"
|
name = "obsigate-desktop"
|
||||||
version = "2.50.2"
|
version = "2.51.0"
|
||||||
description = "ObsiGate Desktop — Porte d'entrée native pour vos vaults Obsidian"
|
description = "ObsiGate Desktop — Porte d'entrée native pour vos vaults Obsidian"
|
||||||
authors = ["Bruno Charest"]
|
authors = ["Bruno Charest"]
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
|
|||||||
+85
-18
@@ -161,6 +161,39 @@ fn save_config(config: &AppConfig) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ── Premier lancement (#160) ───────────────────────────────────────────────
|
||||||
|
|
||||||
|
/// Répertoire de démarrage monté comme vault au premier lancement.
|
||||||
|
const STARTER_VAULT_NAME: &str = "ObsiGate";
|
||||||
|
/// Document d'accueil écrit (si absent) dans le répertoire de démarrage.
|
||||||
|
const WELCOME_DOC_NAME: &str = "Prise en main.md";
|
||||||
|
const WELCOME_DOC: &str = include_str!("prise_en_main.md");
|
||||||
|
|
||||||
|
/// Config par défaut au premier lancement — pure, sans I/O (testable).
|
||||||
|
/// `<home>/ObsiGate` est monté comme vault ET comme contexte initial ; le
|
||||||
|
/// dossier home reste une racine, nommée d'après son dernier segment
|
||||||
|
/// (fin du « bruno » codé en dur, #160).
|
||||||
|
fn default_first_run_config(home: &str) -> AppConfig {
|
||||||
|
let home_path = std::path::Path::new(home);
|
||||||
|
let vault_dir = home_path.join("ObsiGate");
|
||||||
|
let vault_path = vault_dir.to_string_lossy().to_string();
|
||||||
|
AppConfig {
|
||||||
|
vault_path: Some(vault_path.clone()),
|
||||||
|
vaults: vec![VaultConfig {
|
||||||
|
name: STARTER_VAULT_NAME.to_string(),
|
||||||
|
path: vault_path,
|
||||||
|
}],
|
||||||
|
dirs: vec![DirConfig {
|
||||||
|
name: home_path
|
||||||
|
.file_name()
|
||||||
|
.map(|s| s.to_string_lossy().to_string())
|
||||||
|
.unwrap_or_else(|| home.to_string()),
|
||||||
|
path: home.to_string(),
|
||||||
|
}],
|
||||||
|
..AppConfig::default()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// ── Backend lifecycle ───────────────────────────────────────────────────────
|
// ── Backend lifecycle ───────────────────────────────────────────────────────
|
||||||
|
|
||||||
fn spawn_backend(exe_dir: &PathBuf) -> Result<Child, String> {
|
fn spawn_backend(exe_dir: &PathBuf) -> Result<Child, String> {
|
||||||
@@ -535,7 +568,7 @@ fn main() {
|
|||||||
// Load config for window state
|
// Load config for window state
|
||||||
let mut config = load_config();
|
let mut config = load_config();
|
||||||
|
|
||||||
// First run: create sensible defaults per platform
|
// First run: create sensible defaults per platform (#160)
|
||||||
if config.vaults.is_empty() {
|
if config.vaults.is_empty() {
|
||||||
info!("First run — creating default vault configuration");
|
info!("First run — creating default vault configuration");
|
||||||
#[cfg(target_os = "windows")]
|
#[cfg(target_os = "windows")]
|
||||||
@@ -543,25 +576,28 @@ fn main() {
|
|||||||
#[cfg(not(target_os = "windows"))]
|
#[cfg(not(target_os = "windows"))]
|
||||||
let home = std::env::var("HOME").unwrap_or_else(|_| "/home/bruno".to_string());
|
let home = std::env::var("HOME").unwrap_or_else(|_| "/home/bruno".to_string());
|
||||||
|
|
||||||
let vault_dir = std::path::PathBuf::from(&home).join("voute_obsidian");
|
// Montage du répertoire de démarrage (vault + contexte initial) sans
|
||||||
// Create the vault directory if it doesn't exist
|
// toucher aux autres champs (taille/position de fenêtre) de la config.
|
||||||
if !vault_dir.exists() {
|
let defaults = default_first_run_config(&home);
|
||||||
if let Err(e) = fs::create_dir_all(&vault_dir) {
|
config.dirs = defaults.dirs;
|
||||||
error!("Failed to create default vault dir {}: {}", vault_dir.display(), e);
|
config.vaults = defaults.vaults;
|
||||||
} else {
|
config.vault_path = defaults.vault_path;
|
||||||
info!("Created default vault dir: {}", vault_dir.display());
|
|
||||||
|
let vault_dir = std::path::PathBuf::from(config.vaults[0].path.clone());
|
||||||
|
if let Err(e) = fs::create_dir_all(&vault_dir) {
|
||||||
|
error!("Failed to create default vault dir {}: {}", vault_dir.display(), e);
|
||||||
|
} else {
|
||||||
|
info!("Created default vault dir: {}", vault_dir.display());
|
||||||
|
}
|
||||||
|
// Document d'accueil : écrit une seule fois, jamais écrasé (#160).
|
||||||
|
let welcome = vault_dir.join(WELCOME_DOC_NAME);
|
||||||
|
if !welcome.exists() {
|
||||||
|
match fs::write(&welcome, WELCOME_DOC) {
|
||||||
|
Ok(()) => info!("Welcome document written: {}", welcome.display()),
|
||||||
|
Err(e) => error!("Failed to write {}: {}", welcome.display(), e),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
config.dirs = vec![
|
|
||||||
DirConfig { name: "bruno".to_string(), path: home.clone() },
|
|
||||||
];
|
|
||||||
config.vaults = vec![
|
|
||||||
VaultConfig {
|
|
||||||
name: "Obsidian".to_string(),
|
|
||||||
path: vault_dir.to_string_lossy().to_string(),
|
|
||||||
},
|
|
||||||
];
|
|
||||||
config.vault_path = Some(home);
|
|
||||||
save_config(&config);
|
save_config(&config);
|
||||||
info!("Default vault config saved");
|
info!("Default vault config saved");
|
||||||
}
|
}
|
||||||
@@ -1239,4 +1275,35 @@ mod tests {
|
|||||||
"main.rs : disable_drag_drop_handler() manquant — drag & drop bloqué"
|
"main.rs : disable_drag_drop_handler() manquant — drag & drop bloqué"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// #160 — premier lancement : `<home>/ObsiGate` monté comme vault et
|
||||||
|
/// comme contexte initial, racine home nommée d'après son chemin.
|
||||||
|
#[test]
|
||||||
|
fn test_default_first_run_config() {
|
||||||
|
#[cfg(target_os = "windows")]
|
||||||
|
let home = r"C:\Users\alice";
|
||||||
|
#[cfg(not(target_os = "windows"))]
|
||||||
|
let home = "/home/alice";
|
||||||
|
|
||||||
|
let c = default_first_run_config(home);
|
||||||
|
assert_eq!(c.vaults.len(), 1);
|
||||||
|
assert_eq!(c.vaults[0].name, STARTER_VAULT_NAME);
|
||||||
|
assert!(c.vaults[0].path.ends_with("ObsiGate"), "{}", c.vaults[0].path);
|
||||||
|
assert_eq!(c.vault_path.as_deref(), Some(c.vaults[0].path.as_str()));
|
||||||
|
assert_eq!(c.dirs.len(), 1);
|
||||||
|
assert_eq!(c.dirs[0].name, "alice", "nom de racine dérivé du chemin");
|
||||||
|
assert_eq!(c.dirs[0].path, home);
|
||||||
|
assert!(!c.wizard_done);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// #160 — le document d'accueil est embarqué dans le binaire : non vide,
|
||||||
|
/// Markdown, et nom de fichier stable (écrit une seule fois sur le disque).
|
||||||
|
#[test]
|
||||||
|
fn test_welcome_doc_embedded() {
|
||||||
|
assert!(WELCOME_DOC.len() > 500, "document d'accueil trop court");
|
||||||
|
assert!(WELCOME_DOC.starts_with('#'), "attendu : titre Markdown");
|
||||||
|
assert!(WELCOME_DOC.contains("ObsiGate"));
|
||||||
|
assert!(WELCOME_DOC.contains("Ctrl+Espace"));
|
||||||
|
assert_eq!(WELCOME_DOC_NAME, "Prise en main.md");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,41 @@
|
|||||||
|
# 🟢 Bienvenue sur ObsiGate — Prise en main
|
||||||
|
|
||||||
|
Ce dossier `%USERPROFILE%\ObsiGate` est votre **espace de départ** : il est
|
||||||
|
monté automatiquement comme vault **ObsiGate** au premier lancement. Vous
|
||||||
|
pouvez y écrire librement, puis brancher vos vrais vaults Obsidian quand vous
|
||||||
|
êtes prêt.
|
||||||
|
|
||||||
|
## ObsiGate en 30 secondes
|
||||||
|
|
||||||
|
ObsiGate est une porte d'entrée locale vers vos notes : index en mémoire,
|
||||||
|
recherche instantanée, lecture Markdown avec liens `[[wikilinks]]`, images,
|
||||||
|
PDF, tableurs Excel, Excalidraw, Mermaid et assistant IA — sans base de
|
||||||
|
données, sans modification de vos fichiers, tout reste sur votre machine.
|
||||||
|
|
||||||
|
## Premiers pas (application desktop)
|
||||||
|
|
||||||
|
1. **Ce document** s'affiche dans la visionneuse : c'est votre première note,
|
||||||
|
modifiez-la ou supprimez-la quand vous n'en avez plus besoin.
|
||||||
|
2. **Ajouter vos vaults** : Configuration → « 🖥️ Vaults & dossiers (Desktop) »
|
||||||
|
→ *Ajouter un vault* (sélecteur de dossier natif). Depuis la sidebar,
|
||||||
|
clic droit sur une racine → « Retirer de l'application » la désiste
|
||||||
|
(aucun fichier n'est supprimé).
|
||||||
|
3. **Naviguer** : la sidebar liste vos racines et leur arbre ; l'onglet
|
||||||
|
Navigation parcourt un dossier sous forme de vues répertoire.
|
||||||
|
4. **Rechercher** : `Ctrl+Espace` (palette de fichiers),
|
||||||
|
`Ctrl+Alt+Espace` (palette de commandes), `Ctrl+F` dans un document.
|
||||||
|
5. **Onglets** : `Ctrl+W` ferme l'onglet, `Ctrl+Tab` bascule ; le mode split
|
||||||
|
divise l'écran en panneaux.
|
||||||
|
6. **Guide complet** : bouton d'aide de l'en-tête — sommaire, raccourcis,
|
||||||
|
architecture, et téléchargement du guide en Markdown/PDF.
|
||||||
|
|
||||||
|
## Le saviez-vous ?
|
||||||
|
|
||||||
|
- Le **glisser-déposer** de fichiers depuis l'Explorateur est pris en charge :
|
||||||
|
déposez-les sur la fenêtre pour les importer.
|
||||||
|
- Le **clic droit** est partout : menus contextuels de fichier, dossier et
|
||||||
|
vault (avec renommage, création, suppression, vue graphique).
|
||||||
|
- Le **watcher** surveille vos vaults : une note modifiée dans Obsidian
|
||||||
|
apparaît immédiatement ici.
|
||||||
|
|
||||||
|
— *Ce fichier vous appartient.*
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"$schema": "https://raw.githubusercontent.com/nicedoc/obsigate/main/desktop/tauri.conf.schema.json",
|
"$schema": "https://raw.githubusercontent.com/nicedoc/obsigate/main/desktop/tauri.conf.schema.json",
|
||||||
"productName": "ObsiGate",
|
"productName": "ObsiGate",
|
||||||
"version": "2.50.2",
|
"version": "2.51.0",
|
||||||
"identifier": "com.obsigate.desktop",
|
"identifier": "com.obsigate.desktop",
|
||||||
"build": {
|
"build": {
|
||||||
"frontendDist": "../frontend",
|
"frontendDist": "../frontend",
|
||||||
|
|||||||
@@ -37,6 +37,19 @@ Deux surfaces, réservées à l'application desktop :
|
|||||||
vaults et dossiers chargés, avec boutons « Ajouter un vault » (sélecteur de
|
vaults et dossiers chargés, avec boutons « Ajouter un vault » (sélecteur de
|
||||||
dossier natif) et « Ajouter un dossier ».
|
dossier natif) et « Ajouter un dossier ».
|
||||||
|
|
||||||
|
### Premier lancement (#160)
|
||||||
|
|
||||||
|
Au tout premier démarrage (aucun vault configuré), l'application :
|
||||||
|
|
||||||
|
1. crée et monte **`%USERPROFILE%\ObsiGate`** comme vault de démarrage
|
||||||
|
(« ObsiGate ») et ouvre l'interface dessus ;
|
||||||
|
2. y écrit le document **`Prise en main.md`** — présentation, premières
|
||||||
|
étapes, raccourcis (`Ctrl+Espace`, `Ctrl+Alt+Espace`, `Ctrl+F`,
|
||||||
|
`Ctrl+W`/`Ctrl+Tab`) et accès au guide complet (bouton d'aide de l'en-tête).
|
||||||
|
Le fichier n'est jamais réécrit : modifiez-le ou supprimez-le librement ;
|
||||||
|
3. ajoute votre dossier personnel comme seconde racine (nommée d'après son
|
||||||
|
chemin).
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 2. Téléchargement des binaires
|
## 2. Téléchargement des binaires
|
||||||
|
|||||||
+12
-1
@@ -1,6 +1,6 @@
|
|||||||
# ObsiGate — Roadmap
|
# ObsiGate — Roadmap
|
||||||
|
|
||||||
> **Version :** 2.50.2 | **Dernière mise à jour :** 2026-10-02
|
> **Version :** 2.51.0 | **Dernière mise à jour :** 2026-10-03
|
||||||
> **Ce fichier ne contient que le travail à venir** (🔵 En cours + ⚪ Backlog) et un index compact
|
> **Ce fichier ne contient que le travail à venir** (🔵 En cours + ⚪ Backlog) et un index compact
|
||||||
> vers les fonctionnalités livrées.
|
> vers les fonctionnalités livrées.
|
||||||
> - **Méthode de livraison à appliquer pour toute tâche : [DELIVERY_WORKFLOW.md](./DELIVERY_WORKFLOW.md)**
|
> - **Méthode de livraison à appliquer pour toute tâche : [DELIVERY_WORKFLOW.md](./DELIVERY_WORKFLOW.md)**
|
||||||
@@ -50,6 +50,16 @@
|
|||||||
- [x] Rafraîchissement de la jump list après chaque ajout/retrait
|
- [x] Rafraîchissement de la jump list après chaque ajout/retrait
|
||||||
- [x] i18n FR/EN, tests (garde-fou ACL + unit), E2E, fiche features, release
|
- [x] i18n FR/EN, tests (garde-fou ACL + unit), E2E, fiche features, release
|
||||||
|
|
||||||
|
### 160. Premier lancement professionnel + section Configuration harmonisée
|
||||||
|
|
||||||
|
- **Effort :** 0,5-1 jour | **Impact :** 🟢 | **Framework :** config Rust + CSS classes existantes
|
||||||
|
- **Statut :** ✅ livré le 2026-10-02 (v2.51.0) — ouvert le 2026-10-02
|
||||||
|
- **Reste à faire :**
|
||||||
|
- [x] Premier lancement : monter `%USERPROFILE%\ObsiGate` comme vault par défaut (remplace `voute_obsidian`), `vault_path` dessus, nom de dossier racine home dérivé du chemin (fin du hardcode « bruno »)
|
||||||
|
- [x] Document `Prise en main.md` (contenu embarqué `include_str!`) écrit dans ce dossier si absent — jamais d'écrasement
|
||||||
|
- [x] Refonte visuelle de la section « 🖥️ Vaults & dossiers (Desktop) » : classes CSS (motif `webauthn-key-item`), boutons `.config-btn-sm`, zéro style inline, override mobile 44px
|
||||||
|
- [x] Tests Rust (config par défaut + doc embarqué), suites frontend, E2E, docs, release
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 🔵 En cours — Visionneuse & édition Excel (P0/P1/P2)
|
## 🔵 En cours — Visionneuse & édition Excel (P0/P1/P2)
|
||||||
@@ -282,6 +292,7 @@
|
|||||||
| 155 | Tableur — Menu contextuel (clic droit / appui long) & sélection type Excel | 2.44.0 | [features/xlsx-context-menu.md](./features/xlsx-context-menu.md) |
|
| 155 | Tableur — Menu contextuel (clic droit / appui long) & sélection type Excel | 2.44.0 | [features/xlsx-context-menu.md](./features/xlsx-context-menu.md) |
|
||||||
| 156 | Tableur — Complétude éditeur : presse-papiers/clavier (A5-A7), mise en forme (A8), décision calcul (A9), undo unifié (A10), export + recherche multi-feuilles (A11), concurrence optimiste (A12), cache méta (A13), outils IA `.xlsm`/`.csv` (A14) + BUG-096 → BUG-099 | 2.45.0 | [features/xlsx-editor-completeness.md](./features/xlsx-editor-completeness.md) |
|
| 156 | Tableur — Complétude éditeur : presse-papiers/clavier (A5-A7), mise en forme (A8), décision calcul (A9), undo unifié (A10), export + recherche multi-feuilles (A11), concurrence optimiste (A12), cache méta (A13), outils IA `.xlsm`/`.csv` (A14) + BUG-096 → BUG-099 | 2.45.0 | [features/xlsx-editor-completeness.md](./features/xlsx-editor-completeness.md) |
|
||||||
| 159 | Desktop — gestion des vaults & dossiers : retrait par menu contextuel + section Configuration (ajout vault/dossier racine) | 2.50.0 | [features/desktop-tauri.md](./features/desktop-tauri.md) |
|
| 159 | Desktop — gestion des vaults & dossiers : retrait par menu contextuel + section Configuration (ajout vault/dossier racine) | 2.50.0 | [features/desktop-tauri.md](./features/desktop-tauri.md) |
|
||||||
|
| 160 | Desktop — premier lancement professionnel (répertoire `%USERPROFILE%\ObsiGate` + `Prise en main.md`) et section Configuration harmonisée | 2.51.0 | [features/desktop-tauri.md](./features/desktop-tauri.md) |
|
||||||
| BUG-047 | Versionnage — source unique `VERSION` + bump SemVer automatique au commit (hooks + tag) | 2.3.0 | [DEVELOPMENT_AND_RELEASES.md](./DEVELOPMENT_AND_RELEASES.md) |
|
| BUG-047 | Versionnage — source unique `VERSION` + bump SemVer automatique au commit (hooks + tag) | 2.3.0 | [DEVELOPMENT_AND_RELEASES.md](./DEVELOPMENT_AND_RELEASES.md) |
|
||||||
| 90 | Barre d'actions du document — regroupement fonctionnel + spacers | 2.3.0 | [archive](./archive/COMPLETED_v1-v2.md) |
|
| 90 | Barre d'actions du document — regroupement fonctionnel + spacers | 2.3.0 | [archive](./archive/COMPLETED_v1-v2.md) |
|
||||||
| 89 | Drag & drop complet de fichiers/dossiers & intégration Assistant IA | 2.3.0 | [features/drag-and-drop-ai.md](./features/drag-and-drop-ai.md) |
|
| 89 | Drag & drop complet de fichiers/dossiers & intégration Assistant IA | 2.3.0 | [features/drag-and-drop-ai.md](./features/drag-and-drop-ai.md) |
|
||||||
|
|||||||
@@ -107,3 +107,19 @@
|
|||||||
- [x] Tests : `tests/frontend/desktop-roots.test.mjs` (4 — helpers purs +
|
- [x] Tests : `tests/frontend/desktop-roots.test.mjs` (4 — helpers purs +
|
||||||
gating hors desktop), inscrit au CI ; suites frontend/JSDOM vertes,
|
gating hors desktop), inscrit au CI ; suites frontend/JSDOM vertes,
|
||||||
`cargo test` 25 passed.
|
`cargo test` 25 passed.
|
||||||
|
|
||||||
|
## H. Premier lancement & section Configuration harmonisée — #160 — ✅ livré (2026-10-02, v2.51.0)
|
||||||
|
|
||||||
|
- [x] `default_first_run_config(home)` (pure, testée) : `<home>/ObsiGate`
|
||||||
|
monté comme vault « ObsiGate » ET comme `vault_path`, racine home nommée
|
||||||
|
d'après son dernier segment — remplace `voute_obsidian` + le « bruno »
|
||||||
|
codé en dur ; les champs fenêtre de la config existante sont préservés.
|
||||||
|
- [x] `Prise en main.md` : contenu embarqué (`include_str!("prise_en_main.md")`),
|
||||||
|
écrit au premier lancement **si absent** (jamais d'écrasement).
|
||||||
|
- [x] Section `cfg-desktop-roots` refondue : markup à classes (zéro style
|
||||||
|
inline), bloc CSS `#160` sur variables (`desktop-roots-*`, motif
|
||||||
|
`webauthn-key-item`), boutons `.config-btn-sm` (primaire/secondaire),
|
||||||
|
override mobile 44px dans le bloc `#config-modal`.
|
||||||
|
- [x] Tests : `test_default_first_run_config`, `test_welcome_doc_embedded`
|
||||||
|
— `cargo test` 28 passed ; suites frontend vertes (validate-imports,
|
||||||
|
unit, config-mobile, desktop-roots, settings-order) + E2E locale.
|
||||||
|
|||||||
+9
-9
@@ -1951,7 +1951,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<!-- Desktop vaults & root directories (#159) -->
|
<!-- Desktop vaults & root directories (#159, #160) -->
|
||||||
<section
|
<section
|
||||||
id="cfg-desktop-roots"
|
id="cfg-desktop-roots"
|
||||||
class="config-section help-section"
|
class="config-section help-section"
|
||||||
@@ -1965,23 +1965,23 @@
|
|||||||
racine chargés par l'application desktop.
|
racine chargés par l'application desktop.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<div id="desktop-roots-list">
|
<div
|
||||||
<!-- Roots injected by the Tauri shell are injected here -->
|
id="desktop-roots-list"
|
||||||
|
class="desktop-roots-list"
|
||||||
|
>
|
||||||
|
<!-- Racines injectées par renderDesktopRoots() -->
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div
|
<div class="config-actions-row desktop-roots-actions">
|
||||||
class="config-actions-row"
|
|
||||||
style="margin-top: 16px"
|
|
||||||
>
|
|
||||||
<button
|
<button
|
||||||
class="config-btn-save"
|
class="config-btn-primary config-btn-sm"
|
||||||
id="cfg-desktop-add-vault"
|
id="cfg-desktop-add-vault"
|
||||||
data-i18n="desktop.add_vault"
|
data-i18n="desktop.add_vault"
|
||||||
>
|
>
|
||||||
📁 Ajouter un vault
|
📁 Ajouter un vault
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
class="config-btn-save"
|
class="config-btn-secondary config-btn-sm"
|
||||||
id="cfg-desktop-add-dir"
|
id="cfg-desktop-add-dir"
|
||||||
data-i18n="desktop.add_dir"
|
data-i18n="desktop.add_dir"
|
||||||
>
|
>
|
||||||
|
|||||||
+10
-7
@@ -797,14 +797,17 @@ async function renderDesktopRoots() {
|
|||||||
const list = document.getElementById("desktop-roots-list");
|
const list = document.getElementById("desktop-roots-list");
|
||||||
if (!list) return;
|
if (!list) return;
|
||||||
const row = (name, path, kind) =>
|
const row = (name, path, kind) =>
|
||||||
'<div class="hidden-files-vault-card" style="display:flex;align-items:center;gap:10px;margin-bottom:8px">' +
|
'<div class="desktop-roots-item">' +
|
||||||
'<i data-lucide="' + (kind === "vault" ? "vault" : "folder") + '" style="width:16px;flex-shrink:0"></i>' +
|
`<i data-lucide="${kind === "vault" ? "vault" : "folder"}" class="desktop-roots-icon"></i>` +
|
||||||
'<div style="flex:1;min-width:0"><div style="font-weight:600">' + escapeHtml(name) + "</div>" +
|
'<div class="desktop-roots-text">' +
|
||||||
'<div style="font-size:12px;color:var(--text-muted);overflow:hidden;text-overflow:ellipsis">' + escapeHtml(path) + "</div></div>" +
|
`<span class="desktop-roots-name">${escapeHtml(name)}</span>` +
|
||||||
'<button class="config-btn-save" data-root="' + escapeHtml(name) + '" style="padding:4px 10px;font-size:12px;white-space:nowrap">' +
|
`<span class="desktop-roots-path" title="${escapeHtml(path)}">${escapeHtml(path)}</span>` +
|
||||||
'<i data-lucide="folder-minus" style="width:14px;vertical-align:-2px"></i> ' + escapeHtml(t("desktop.remove_root")) + "</button></div>";
|
"</div>" +
|
||||||
|
`<button class="config-btn-secondary config-btn-sm" data-root="${escapeHtml(name)}">` +
|
||||||
|
`<i data-lucide="folder-minus" class="desktop-roots-btn-icon"></i>${escapeHtml(t("desktop.remove_root"))}</button>` +
|
||||||
|
"</div>";
|
||||||
if (!vaults.length && !dirs.length) {
|
if (!vaults.length && !dirs.length) {
|
||||||
list.innerHTML = '<div style="padding:12px;color:var(--text-muted)">' + escapeHtml(t("desktop.roots_empty")) + "</div>";
|
list.innerHTML = `<div class="desktop-roots-empty">${escapeHtml(t("desktop.roots_empty"))}</div>`;
|
||||||
} else {
|
} else {
|
||||||
list.innerHTML = vaults.map((v) => row(v.name, v.path, "vault")).join("") +
|
list.innerHTML = vaults.map((v) => row(v.name, v.path, "vault")).join("") +
|
||||||
dirs.map((d) => row(d.name, d.path, "dir")).join("");
|
dirs.map((d) => row(d.name, d.path, "dir")).join("");
|
||||||
|
|||||||
@@ -5041,6 +5041,15 @@ body.resizing-v {
|
|||||||
min-height: 44px;
|
min-height: 44px;
|
||||||
min-width: 44px;
|
min-width: 44px;
|
||||||
}
|
}
|
||||||
|
#config-modal .desktop-roots-item {
|
||||||
|
flex-wrap: wrap;
|
||||||
|
}
|
||||||
|
#config-modal .desktop-roots-item .config-btn-sm {
|
||||||
|
min-height: 44px;
|
||||||
|
}
|
||||||
|
#config-modal .desktop-roots-actions {
|
||||||
|
flex-wrap: wrap;
|
||||||
|
}
|
||||||
#config-modal .hidden-files-add-row {
|
#config-modal .hidden-files-add-row {
|
||||||
flex-wrap: wrap;
|
flex-wrap: wrap;
|
||||||
}
|
}
|
||||||
@@ -11963,6 +11972,79 @@ mark {
|
|||||||
.webauthn-key-meta { font-size: 0.75rem; color: var(--text-muted, #888); }
|
.webauthn-key-meta { font-size: 0.75rem; color: var(--text-muted, #888); }
|
||||||
.config-btn-sm { padding: 4px 10px; font-size: 0.78rem; }
|
.config-btn-sm { padding: 4px 10px; font-size: 0.78rem; }
|
||||||
|
|
||||||
|
/* ── #160 : Section Configuration — Vaults & dossiers (Desktop) ──────────── */
|
||||||
|
.desktop-roots-list {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 8px;
|
||||||
|
}
|
||||||
|
.desktop-roots-item {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 10px;
|
||||||
|
padding: 8px 10px;
|
||||||
|
background: var(--surface2, #1a1a2e);
|
||||||
|
border: 1px solid var(--border, transparent);
|
||||||
|
border-radius: 6px;
|
||||||
|
transition: border-color 150ms;
|
||||||
|
}
|
||||||
|
.desktop-roots-item:hover {
|
||||||
|
border-color: var(--accent);
|
||||||
|
}
|
||||||
|
.desktop-roots-icon {
|
||||||
|
width: 16px;
|
||||||
|
height: 16px;
|
||||||
|
flex-shrink: 0;
|
||||||
|
color: var(--accent);
|
||||||
|
}
|
||||||
|
.desktop-roots-text {
|
||||||
|
flex: 1;
|
||||||
|
min-width: 0;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 2px;
|
||||||
|
}
|
||||||
|
.desktop-roots-name {
|
||||||
|
font-size: 0.9rem;
|
||||||
|
font-weight: 600;
|
||||||
|
color: var(--text, #fff);
|
||||||
|
}
|
||||||
|
.desktop-roots-path {
|
||||||
|
font-size: 0.75rem;
|
||||||
|
color: var(--text-muted, #888);
|
||||||
|
white-space: nowrap;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
}
|
||||||
|
.desktop-roots-item .config-btn-sm {
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 6px;
|
||||||
|
flex-shrink: 0;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
.desktop-roots-btn-icon {
|
||||||
|
width: 14px;
|
||||||
|
height: 14px;
|
||||||
|
}
|
||||||
|
.desktop-roots-empty {
|
||||||
|
padding: 12px;
|
||||||
|
font-size: 0.85rem;
|
||||||
|
color: var(--text-muted, #888);
|
||||||
|
background: var(--surface2, #1a1a2e);
|
||||||
|
border-radius: 6px;
|
||||||
|
}
|
||||||
|
.desktop-roots-actions {
|
||||||
|
display: flex;
|
||||||
|
justify-content: flex-end;
|
||||||
|
gap: 8px;
|
||||||
|
}
|
||||||
|
.desktop-roots-actions .config-btn-sm {
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 6px;
|
||||||
|
}
|
||||||
|
|
||||||
/* MFA Disable card */
|
/* MFA Disable card */
|
||||||
.mfa-disable-card {
|
.mfa-disable-card {
|
||||||
padding: 16px; border-radius: 10px;
|
padding: 16px; border-radius: 10px;
|
||||||
|
|||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "obsigate",
|
"name": "obsigate",
|
||||||
"version": "2.50.2",
|
"version": "2.51.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.",
|
"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",
|
"main": "patch.js",
|
||||||
"directories": {
|
"directories": {
|
||||||
|
|||||||
Reference in New Issue
Block a user