diff --git a/src/app/editor/components/block/block-host.component.ts b/src/app/editor/components/block/block-host.component.ts index 74b71f5..0a39d25 100644 --- a/src/app/editor/components/block/block-host.component.ts +++ b/src/app/editor/components/block/block-host.component.ts @@ -34,6 +34,7 @@ import { EmbedBlockComponent } from './blocks/embed-block.component'; import { OutlineBlockComponent } from './blocks/outline-block.component'; import { LineBlockComponent } from './blocks/line-block.component'; import { ColumnsBlockComponent } from './blocks/columns-block.component'; +import { CollapsibleBlockComponent } from './blocks/collapsible-block.component'; /** * Block host component - routes to specific block type @@ -64,6 +65,7 @@ import { ColumnsBlockComponent } from './blocks/columns-block.component'; OutlineBlockComponent, LineBlockComponent, ColumnsBlockComponent, + CollapsibleBlockComponent, OverlayModule, PortalModule ], @@ -152,7 +154,12 @@ import { ColumnsBlockComponent } from './blocks/columns-block.component'; } @case ('toggle') { - + } @case ('dropdown') { @@ -178,6 +185,9 @@ import { ColumnsBlockComponent } from './blocks/columns-block.component'; @case ('columns') { } + @case ('collapsible') { + + } } @@ -969,6 +979,17 @@ export class BlockHostComponent implements OnDestroy { }, 50); } + onCreateToggleBelow(): void { + // Create a new Toggle block right below current block + const preset = this.documentService.getDefaultProps('toggle'); + const newBlock = this.documentService.createBlock('toggle', preset); + this.documentService.insertBlock(this.block.id, newBlock); + setTimeout(() => { + const el = document.querySelector(`[data-block-id="${newBlock.id}"] [contenteditable]`) as HTMLElement | null; + el?.focus(); + }, 50); + } + onDeleteBlock(): void { // Delete current block this.documentService.deleteBlock(this.block.id); diff --git a/src/app/editor/components/block/block-initial-menu.component.ts b/src/app/editor/components/block/block-initial-menu.component.ts index ac6ff58..9210479 100644 --- a/src/app/editor/components/block/block-initial-menu.component.ts +++ b/src/app/editor/components/block/block-initial-menu.component.ts @@ -10,7 +10,7 @@ export interface BlockMenuAction { standalone: true, imports: [CommonModule], template: ` -
+
-
+ +
+ + +

+

+

+
+
+
+
+ +
+
+ + +
+ + + + + + + + + + + + + + + + + + + + +
+
+
+ Press Enter in the title to start writing… +
+
+
+
+ `, + styles: [` + [contenteditable]:empty:before { content: attr(placeholder); color: var(--text-muted); } + `] +}) +export class CollapsibleBlockComponent implements AfterViewInit { + @Input({ required: true }) block!: Block; + @Output() update = new EventEmitter(); + + @ViewChild('editable') editable?: ElementRef; + + readonly isCollapsed = signal(true); + private readonly documentService = inject(DocumentService); + + get props(): CollapsibleProps { return this.block.props; } + + ngOnInit(): void { + this.isCollapsed.set(this.props.collapsed ?? true); + } + + ngAfterViewInit(): void { + const el = this.editable?.nativeElement; + if (el) { el.textContent = this.props.title || ''; } + } + + toggle(ev?: MouseEvent): void { + ev?.stopPropagation(); + const next = !this.isCollapsed(); + this.isCollapsed.set(next); + this.update.emit({ ...this.props, collapsed: next }); + } + + onHeaderClick(ev: MouseEvent): void { + // Avoid toggling by default; only arrow toggles + ev.stopPropagation(); + } + + onTitleInput(event: Event): void { + const target = event.target as HTMLElement; + this.update.emit({ ...this.props, title: target.textContent || '' }); + } + + onTitleKeyDown(event: KeyboardEvent): void { + if (event.key === 'Enter' && !event.shiftKey) { + event.preventDefault(); + // Ensure open and create first inner paragraph, focus it + const opened = this.isCollapsed(); + if (opened) { + this.isCollapsed.set(false); + } + if (!Array.isArray(this.props.content)) { + this.props.content = []; + } + if (this.props.content.length === 0) { + const p = this.documentService.createBlock('paragraph', { text: '' }); + const updated = { ...this.props, content: [p], collapsed: false } as CollapsibleProps; + this.update.emit(updated); + setTimeout(() => { + const el = document.querySelector(`[data-block-id="${p.id}"] [contenteditable]`) as HTMLElement | null; + el?.focus(); + }, 0); + } else { + // Focus the first existing child + setTimeout(() => { + const first = this.props.content[0]; + const el = document.querySelector(`[data-block-id="${first.id}"] [contenteditable]`) as HTMLElement | null; + el?.focus(); + }, 0); + } + } + } + + trackById = (_: number, b: Block) => b.id; + + onChildUpdate(index: number, patch: any): void { + const next = this.props.content.map((b, i) => i === index ? ({ ...b, props: { ...(b as any).props, ...patch } as any }) : b); + this.update.emit({ ...this.props, content: next }); + } + + onChildMeta(index: number, meta: any): void { + const next = this.props.content.map((b, i) => i === index ? ({ ...b, meta: { ...(b.meta || {}), ...meta } }) : b); + this.update.emit({ ...this.props, content: next }); + } + + insertParagraphBelow(index: number): void { + const p = this.documentService.createBlock('paragraph', { text: '' }); + const next = [...this.props.content]; + next.splice(index + 1, 0, p); + this.update.emit({ ...this.props, content: next }); + setTimeout(() => { + const el = document.querySelector(`[data-block-id="${p.id}"] [contenteditable]`) as HTMLElement | null; + el?.focus(); + }, 0); + } + + removeChild(index: number): void { + const next = this.props.content.filter((_, i) => i !== index); + this.update.emit({ ...this.props, content: next }); + } +} diff --git a/src/app/editor/components/block/blocks/columns-block.component.ts b/src/app/editor/components/block/blocks/columns-block.component.ts index b4fe984..6deb083 100644 --- a/src/app/editor/components/block/blocks/columns-block.component.ts +++ b/src/app/editor/components/block/blocks/columns-block.component.ts @@ -13,6 +13,7 @@ import { ListItemBlockComponent } from './list-item-block.component'; import { CodeBlockComponent } from './code-block.component'; import { QuoteBlockComponent } from './quote-block.component'; import { ToggleBlockComponent } from './toggle-block.component'; +import { CollapsibleBlockComponent } from './collapsible-block.component'; import { HintBlockComponent } from './hint-block.component'; import { ButtonBlockComponent } from './button-block.component'; import { ImageBlockComponent } from './image-block.component'; @@ -41,6 +42,7 @@ import { DragDropFilesDirective } from '../../../../blocks/file/directives/drag- CodeBlockComponent, QuoteBlockComponent, ToggleBlockComponent, + CollapsibleBlockComponent, HintBlockComponent, ButtonBlockComponent, ImageBlockComponent, @@ -122,6 +124,7 @@ import { DragDropFilesDirective } from '../../../../blocks/file/directives/drag- @case ('paragraph') { } + @case ('collapsible') { + + } @case ('hint') { } diff --git a/src/app/editor/components/block/blocks/paragraph-block.component.ts b/src/app/editor/components/block/blocks/paragraph-block.component.ts index dc3876b..cf92691 100644 --- a/src/app/editor/components/block/blocks/paragraph-block.component.ts +++ b/src/app/editor/components/block/blocks/paragraph-block.component.ts @@ -6,9 +6,8 @@ import { Block, ParagraphProps } from '../../../core/models/block.model'; import { DocumentService } from '../../../services/document.service'; import { SelectionService } from '../../../services/selection.service'; import { PaletteService } from '../../../services/palette.service'; -import { PaletteCategory, PaletteItem, getPaletteItemsByCategory } from '../../../core/constants/palette-items'; -import { FilePickerService } from '../../../../blocks/file/services/file-picker.service'; -import { BlockInsertionService } from '../../../../blocks/file/services/block-insertion.service'; +import { PaletteCategory, PaletteItem, getPaletteItemsByCategory, PALETTE_ITEMS } from '../../../core/constants/palette-items'; + @Component({ selector: 'app-paragraph-block', @@ -24,30 +23,52 @@ import { BlockInsertionService } from '../../../../blocks/file/services/block-in [isFocused]="isFocused" [isEmpty]="isEmpty" [showDragHandle]="false" - [actions]="undefined" + [actions]="inColumn ? [] : undefined" (action)="onInlineAction($event)" > -
+
+
+ @if (inColumn) { + + } +
@if (moreOpen()) { -
+
@for (category of categories; track category) {
-
{{ category }}
+
{{ category }}
@for (item of getItems(category); track item.id) { -
- +
@if (!isCollapsed()) { -
-
- Nested content will be rendered here +
+ +
+
+ + +
+ + + + + + + + + + + + + + + + + +
+
+
+ Press Enter in the title to start writing…
- } -
+
+ } +
`, styles: [` [contenteditable]:empty:before { @@ -44,17 +109,19 @@ import { Block, ToggleProps } from '../../../core/models/block.model'; export class ToggleBlockComponent implements AfterViewInit { @Input({ required: true }) block!: Block; @Output() update = new EventEmitter(); + // For host to create block below (used for quick multi-toggle creation) + @Output() createBlock = new EventEmitter(); + @Output() createParagraph = new EventEmitter(); @ViewChild('editable') editable?: ElementRef; readonly isCollapsed = signal(true); + private readonly documentService = inject(DocumentService); ngOnInit(): void { this.isCollapsed.set(this.props.collapsed ?? true); } - get props(): ToggleProps { - return this.block.props; - } + get props(): ToggleProps { return this.block.props; } ngAfterViewInit(): void { if (this.editable?.nativeElement) { @@ -65,6 +132,20 @@ export class ToggleBlockComponent implements AfterViewInit { toggle(): void { const newState = !this.isCollapsed(); this.isCollapsed.set(newState); + // If opening and no content yet, create first paragraph for typing + if (!newState) { + const empty = !this.props.content || this.props.content.length === 0; + if (empty) { + const p = this.documentService.createBlock('paragraph', { text: '' }); + const next = { ...this.props, collapsed: false, content: [p] } as ToggleProps; + this.update.emit(next); + setTimeout(() => { + const el = document.querySelector(`[data-block-id="${p.id}"] [contenteditable]`) as HTMLElement | null; + el?.focus(); + }, 0); + return; + } + } this.update.emit({ ...this.props, collapsed: newState }); } @@ -72,4 +153,45 @@ export class ToggleBlockComponent implements AfterViewInit { const target = event.target as HTMLElement; this.update.emit({ ...this.props, title: target.textContent || '' }); } + + onTitleKeyDown(event: KeyboardEvent): void { + if (event.key === 'Enter' && !event.shiftKey) { + event.preventDefault(); + const text = (this.editable?.nativeElement?.textContent || '').trim(); + if (text.length === 0) { + // Exit creation: ask host to insert a paragraph below + this.createParagraph.emit(); + return; + } + // Multi-toggle creation: ask host to create another toggle below + this.createBlock.emit(); + } + } + + trackById = (_: number, b: Block) => b.id; + onChildUpdate(index: number, patch: any): void { + const next = this.props.content.map((b, i) => i === index ? ({ ...b, props: { ...(b as any).props, ...patch } as any }) : b); + this.update.emit({ ...this.props, content: next }); + } + + onChildMeta(index: number, meta: any): void { + const next = this.props.content.map((b, i) => i === index ? ({ ...b, meta: { ...(b.meta || {}), ...meta } }) : b); + this.update.emit({ ...this.props, content: next }); + } + + insertParagraphBelow(index: number): void { + const p = this.documentService.createBlock('paragraph', { text: '' }); + const next = [...this.props.content]; + next.splice(index + 1, 0, p); + this.update.emit({ ...this.props, content: next }); + setTimeout(() => { + const el = document.querySelector(`[data-block-id="${p.id}"] [contenteditable]`) as HTMLElement | null; + el?.focus(); + }, 0); + } + + removeChild(index: number): void { + const next = this.props.content.filter((_, i) => i !== index); + this.update.emit({ ...this.props, content: next }); + } } diff --git a/src/app/editor/components/editor-shell/editor-shell.component.ts b/src/app/editor/components/editor-shell/editor-shell.component.ts index ce50dd1..a2782f1 100644 --- a/src/app/editor/components/editor-shell/editor-shell.component.ts +++ b/src/app/editor/components/editor-shell/editor-shell.component.ts @@ -16,7 +16,7 @@ import { DragDropService } from '../../services/drag-drop.service'; import { DragDropFilesDirective } from '../../../blocks/file/directives/drag-drop-files.directive'; import { FilePickerService } from '../../../blocks/file/services/file-picker.service'; import { BlockInsertionService } from '../../../blocks/file/services/block-insertion.service'; -import { PaletteItem } from '../../core/constants/palette-items'; +import { PaletteItem, PALETTE_ITEMS } from '../../core/constants/palette-items'; @Component({ selector: 'app-editor-shell', @@ -33,10 +33,25 @@ import { PaletteItem } from '../../core/constants/palette-items';
-
+
+ + = { - 'checkbox-list': { type: 'list-item' as any, props: { kind: 'check', checked: false, text: '' } }, - 'numbered-list': { type: 'list-item' as any, props: { kind: 'numbered', number: 1, text: '' } }, - 'bullet-list': { type: 'list-item' as any, props: { kind: 'bullet', text: '' } }, - 'table': { type: 'table', props: this.documentService.getDefaultProps('table') }, - 'image': { type: 'image', props: this.documentService.getDefaultProps('image') }, - 'file': null, - 'heading-2': { type: 'heading', props: { level: 2, text: '' } }, - 'new-page': { type: 'paragraph', props: { text: '' } }, // Placeholder - 'use-ai': { type: 'paragraph', props: { text: '' } }, // Placeholder - }; - - const config = typeMap[action]; - if (action === 'file') { - this.filePicker.pick({ multiple: true, accept: '*/*' }).then(files => { - if (!files.length) return; - this.insertFilesAtCursor(files); - }); - return; - } - if (config) { - const block = this.documentService.createBlock(config.type, config.props); - this.documentService.appendBlock(block); - this.selectionService.setActive(block.id); - } + return; + } + // Map toolbar action to palette item id + const idMap: Record = { + 'checkbox-list': 'checkbox-list', + 'numbered-list': 'numbered-list', + 'bullet-list': 'bullet-list', + 'table': 'table', + 'image': 'image', + 'file': 'file', + 'heading-2': 'heading-2', + // 'new-page' and 'use-ai' are placeholders and not palette-backed + }; + const id = idMap[action]; + if (!id) return; + const item = PALETTE_ITEMS.find(i => i.id === id); + if (item) { + this.paletteService.applySelection(item); } } onPaletteItemSelected(item: PaletteItem): void { - // Special handling for File: open multi-picker and create N blocks - if (item.type === 'file' || item.id === 'file') { - this.filePicker.pick({ multiple: true, accept: '*/*' }).then(files => { - if (!files.length) return; - this.insertFilesAtCursor(files); - }); - return; - } + // Delegate to authoritative creation flow + this.paletteService.applySelection(item); + } - // Convert list types to list-item for independent lines - let blockType = item.type; - let props = this.documentService.getDefaultProps(blockType); - if (item.type === 'list') { - blockType = 'list-item' as any; - props = this.documentService.getDefaultProps(blockType); - if (item.id === 'checkbox-list') { props.kind = 'check'; props.checked = false; } - else if (item.id === 'numbered-list') { props.kind = 'numbered'; props.number = 1; } - else if (item.id === 'bullet-list') { props.kind = 'bullet'; } - } - - const block = this.documentService.createBlock(blockType, props); - this.documentService.appendBlock(block); - this.selectionService.setActive(block.id); + onClearDocument(): void { + // Empty page: remove all blocks and clear selection/menus + this.documentService.clearBlocks(); + this.selectionService.clear(); + this.showInitialMenu.set(false); + this.insertAfterBlockId.set(null); } /** @@ -431,91 +424,64 @@ export class EditorShellComponent implements AfterViewInit { }, 0); } - onInitialMenuAction(action: BlockMenuAction): void { + async onInitialMenuAction(action: BlockMenuAction): Promise { // Hide menu immediately this.showInitialMenu.set(false); - + const blockId = this.insertAfterBlockId(); if (!blockId) return; - - // If paragraph type selected, just hide menu and keep the paragraph + + // Ensure the placeholder paragraph is the active block so applySelection can convert/insert correctly + this.selectionService.setActive(blockId); + + // Paragraph: keep as-is and just focus if (action.type === 'paragraph') { - // Focus on the paragraph setTimeout(() => { const element = document.querySelector(`[data-block-id="${blockId}"] [contenteditable]`) as HTMLElement; - if (element) { - element.focus(); - } + element?.focus(); }, 0); return; } - - // If "more" selected, open full palette + + // More: open full palette if (action.type === 'more') { - this.paletteService.open(); + this.paletteService.open(blockId); return; } - - // Otherwise, convert the paragraph block to the selected type - let blockType: any = 'paragraph'; - let props: any = { text: '' }; - - switch (action.type) { - case 'heading': - blockType = 'heading'; - props = { level: 2, text: '' }; - break; - case 'checkbox': - blockType = 'list-item'; - props = { kind: 'check', text: '', checked: false }; - break; - case 'list': - blockType = 'list-item'; - props = { kind: 'bullet', text: '' }; - break; - case 'numbered': - blockType = 'list-item'; - props = { kind: 'numbered', text: '', number: 1 }; - break; - case 'formula': - blockType = 'code'; - props = { language: 'latex', code: '' }; - break; - case 'table': - blockType = 'table'; - props = this.documentService.getDefaultProps('table'); - break; - case 'code': - blockType = 'code'; - props = this.documentService.getDefaultProps('code'); - break; - case 'image': - blockType = 'image'; - props = this.documentService.getDefaultProps('image'); - break; - case 'file': - // Open picker and replace the placeholder paragraph with N file blocks at the same index - const currentBlocks = this.documentService.blocks(); - const idx = currentBlocks.findIndex(b => b.id === blockId); - this.filePicker.pick({ multiple: true, accept: '*/*' }).then(files => { - if (!files.length) return; - // Delete the placeholder paragraph - this.documentService.deleteBlock(blockId); - // Insert at original index - this.inserter.createFromFiles(files, idx); - }); - return; // early exit; we handle asynchronously - } - - // Convert the existing block - this.documentService.updateBlock(blockId, { type: blockType, props }); - - // Focus on the converted block - setTimeout(() => { - const newElement = document.querySelector(`[data-block-id="${blockId}"] [contenteditable]`) as HTMLElement; - if (newElement) { - newElement.focus(); + + // Map initial menu actions to palette items + const idMap: Record = { + heading: 'heading-2', + checkbox: 'checkbox-list', + list: 'bullet-list', + numbered: 'numbered-list', + table: 'table', + code: 'code', + image: 'image', + file: 'file', + }; + + // Special-case formula: insert a code block then switch language to LaTeX + if (action.type === 'formula') { + const codeItem = PALETTE_ITEMS.find(i => i.id === 'code'); + if (codeItem) { + await this.paletteService.applySelection(codeItem); + const newActiveId = this.selectionService.getActive(); + if (newActiveId) { + const blk: any = this.documentService.getBlock(newActiveId); + if (blk?.type === 'code') { + this.documentService.updateBlockProps(newActiveId, { ...(blk.props || {}), language: 'latex', code: '' }); + } + } } - }, 0); + return; + } + + const id = idMap[action.type]; + if (!id) return; + const item = PALETTE_ITEMS.find(i => i.id === id); + if (item) { + await this.paletteService.applySelection(item); + } } } diff --git a/src/app/editor/components/palette/block-menu.component.ts b/src/app/editor/components/palette/block-menu.component.ts index 585e73a..1a0676d 100644 --- a/src/app/editor/components/palette/block-menu.component.ts +++ b/src/app/editor/components/palette/block-menu.component.ts @@ -13,15 +13,15 @@ import { PaletteItem, PaletteCategory, getPaletteItemsByCategory } from '../../c
-
-

SUGGESTIONS

+

SUGGESTIONS

@if (showSuggestions()) { -
+
-
-

{{ category }}

+
+

{{ category }}

@@ -63,10 +63,10 @@ import { PaletteItem, PaletteCategory, getPaletteItemsByCategory } from '../../c @if (matchesQuery(item)) {
diff --git a/vault/.obsidian/bookmarks.json b/vault/.obsidian/bookmarks.json index fc69ce2..491add1 100644 --- a/vault/.obsidian/bookmarks.json +++ b/vault/.obsidian/bookmarks.json @@ -1,3 +1,16 @@ { - "items": [] + "items": [ + { + "type": "file", + "path": "Allo-3/bruno.md", + "title": "bruno.md", + "ctime": 1763066387749 + }, + { + "type": "file", + "path": "tata/Les Compléments Alimentaires Un Guide Général.md", + "title": "Les Compléments Alimentaires Un Guide Général.md", + "ctime": 1763156633684 + } + ] } \ No newline at end of file diff --git a/vault/Allo-3/Stargate Atlantis.md b/vault/Allo-3/Stargate Atlantis.md index 61ec8da..07a1559 100644 --- a/vault/Allo-3/Stargate Atlantis.md +++ b/vault/Allo-3/Stargate Atlantis.md @@ -12,7 +12,7 @@ task: false archive: true draft: false private: false -description: "Stargate Atlantis: une expédition militaire et scientifique découvre la cité mythique d'Atlantis dans la galaxie de Pégase et affronte les Wraiths." +description: "Une expédition militaire et scientifique découvre la cité mythique d'Atlantis dans la galaxie de Pégase et affronte les Wraiths." --- *Stargate Atlantis* est une série de science-fiction dérivée de la populaire *Stargate SG-1*. Elle suit les aventures d'une expédition internationale, composée de scientifiques et de militaires, qui voyage à travers la porte des étoiles vers la lointaine galaxie de Pégase. Leur destination est la cité mythique d'Atlantis, une métropole volante abandonnée construite par une race ancienne et technologiquement supérieure connue sous le nom d'Anciens. diff --git a/vault/Drawing-20251114-1647.excalidraw.md b/vault/Drawing-20251114-1647.excalidraw.md new file mode 100644 index 0000000..e73503d --- /dev/null +++ b/vault/Drawing-20251114-1647.excalidraw.md @@ -0,0 +1,32 @@ +--- +titre: Drawing-20251114-1647.excalidraw +auteur: Bruno Charest +creation_date: 2025-11-14T16:47:49-04:00 +modification_date: 2025-11-14T16:47:49-04:00 +catégorie: "" +tags: [] +aliases: [] +status: en-cours +publish: false +favoris: false +template: false +task: false +archive: false +draft: false +private: false +excalidraw-plugin: parsed +created: 2025-11-14T21:47:48.100Z +updated: 2025-11-14T21:47:48.100Z +title: Drawing-20251114-1647 +--- +==⚠ Switch to EXCALIDRAW VIEW in the MORE OPTIONS menu of this document. ⚠== + +# Excalidraw Data + +## Text Elements +%% +## Drawing +```compressed-json +N4IgLgngDgpiBcIYA8DGBDANgSwCYCd0B3EAGhADcZ8BnbAewDsEAmcm+gV31TkXoBGdXNnSMAtCgw4CxcVEycA5tmbkYmGAFsYjMDQQBtALrl0UKAGUw6MH2ABfcgDNsmg/EcOgA=== +``` +%% \ No newline at end of file diff --git a/vault/Drawing-20251114-1647.excalidraw.md.bak b/vault/Drawing-20251114-1647.excalidraw.md.bak new file mode 100644 index 0000000..9626294 --- /dev/null +++ b/vault/Drawing-20251114-1647.excalidraw.md.bak @@ -0,0 +1,17 @@ +--- +excalidraw-plugin: parsed +created: "2025-11-14T21:47:48.100Z" +updated: "2025-11-14T21:47:48.100Z" +title: "Drawing-20251114-1647" +--- +==⚠ Switch to EXCALIDRAW VIEW in the MORE OPTIONS menu of this document. ⚠== + +# Excalidraw Data + +## Text Elements +%% +## Drawing +```compressed-json +N4IgLgngDgpiBcIYA8DGBDANgSwCYCd0B3EAGhADcZ8BnbAewDsEAmcm+gV31TkXoBGdXNnSMAtCgw4CxcVEycA5tmbkYmGAFsYjMDQQBtALrl0UKAGUw6MH2ABfcgDNsmg/EcOgA=== +``` +%% \ No newline at end of file diff --git a/vault/attachments/nimbus/2025/1114/img-7086e8a9-2d58-4a7d-9002-dfb6512c71ec-png-20251114-152745-71san2.png b/vault/attachments/nimbus/2025/1114/img-7086e8a9-2d58-4a7d-9002-dfb6512c71ec-png-20251114-152745-71san2.png new file mode 100644 index 0000000..87c8951 Binary files /dev/null and b/vault/attachments/nimbus/2025/1114/img-7086e8a9-2d58-4a7d-9002-dfb6512c71ec-png-20251114-152745-71san2.png differ diff --git a/vault/folder-4/toto.md b/vault/folder-4/toto.md index 2a82d60..08bd419 100644 --- a/vault/folder-4/toto.md +++ b/vault/folder-4/toto.md @@ -7,11 +7,12 @@ tags: [""] aliases: [""] status: "en-cours" publish: false -favoris: false +favoris: true template: false task: false archive: false draft: false private: false -description: "Nouvelle note 7 de Bruno Charest, actuellement en cours de rédaction." +description: "Note intitulée 'Nouvelle note 7', rédigée par Bruno Charest et en cours de travail." +color: "#F59E0B" --- diff --git a/vault/tata/Les Compléments Alimentaires Un Guide Général.md b/vault/tata/Les Compléments Alimentaires Un Guide Général.md index 6c8f204..bbc9806 100644 --- a/vault/tata/Les Compléments Alimentaires Un Guide Général.md +++ b/vault/tata/Les Compléments Alimentaires Un Guide Général.md @@ -13,7 +13,7 @@ draft: true private: false titre: "" readOnly: false -description: "Les Compléments Alimentaires : Un Guide Général Dans notre quête constante de bien-être et de..." +description: "Ce guide offre une vue d'ensemble équilibrée sur les compléments alimentaires, leurs bénéfices, risques et l'importance d'une utilisation éclairée." color: "#00AEEF" --- ## Les Compléments Alimentaires : Un Guide Général