feat: add internal notes for collection attributes (#11945)#2984
feat: add internal notes for collection attributes (#11945)#2984AviArora02-commits wants to merge 8 commits intoappwrite:mainfrom
Conversation
Greptile SummaryAdds a new
Confidence Score: 4/5Not safe to merge until the storage key inconsistency and missing cleanup on column deletion are resolved. Two P1 findings: the $id || key storage key can silently mismatch across renders, and notes are never cleaned up when columns are deleted. Both have straightforward fixes. +page.svelte (storage key), deleteColumn.svelte (missing deleteNote call) Important Files Changed
|
| getNote(databaseId: string, collectionId: string, attributeKey: string): string { | ||
| const notes = loadFromStorage(); | ||
| return notes[buildNoteKey(databaseId, collectionId, attributeKey)] ?? ''; | ||
| }, |
There was a problem hiding this comment.
getNote reads localStorage directly, bypassing in-memory store state
getNote calls loadFromStorage() rather than reading from the writable store's current value. This means it always does a fresh synchronous localStorage parse on every call and is architecturally inconsistent — the store maintains an in-memory copy precisely to avoid this. The component also calls this once at mount time (line 30 of AttributeNote.svelte) and never re-reads it, creating a stale-read risk for any caller that doesn't already subscribe. Reading from the in-memory store value (via svelte/store's get) would be consistent with how the rest of the codebase handles writable stores.
There was a problem hiding this comment.
Pull request overview
Adds a console-only “internal notes” capability for database collection attributes by introducing a localStorage-backed store and a reusable UI component to view/edit notes.
Changes:
- Added
attributeNotesstore to persist attribute notes inlocalStorage - Added
AttributeNote.svelteinline editor/display component for notes
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 6 comments.
| File | Description |
|---|---|
| src/lib/stores/attributeNotes.ts | New localStorage-backed Svelte store for attribute notes (get/set/delete/reload). |
| src/lib/components/AttributeNote.svelte | New UI component to view/add/edit/remove an attribute note. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| function loadFromStorage(): NotesMap { | ||
| try { | ||
| const raw = localStorage.getItem(STORAGE_KEY); | ||
| if (!raw) return {}; | ||
| return JSON.parse(raw) as NotesMap; | ||
| } catch { | ||
| return {}; | ||
| } |
| function loadFromStorage(): NotesMap { | ||
| try { | ||
| const raw = localStorage.getItem(STORAGE_KEY); | ||
| if (!raw) return {}; | ||
| return JSON.parse(raw) as NotesMap; | ||
| } catch { | ||
| return {}; | ||
| } | ||
| } | ||
|
|
||
| /** | ||
| * Persist notes map to localStorage. | ||
| */ | ||
| function saveToStorage(notes: NotesMap): void { | ||
| try { | ||
| localStorage.setItem(STORAGE_KEY, JSON.stringify(notes)); | ||
| } catch { | ||
| // Silently ignore storage errors (e.g. private browsing quota) | ||
| } | ||
| } |
| if (note.trim()) { | ||
| updated[key] = note; |
| import { attributeNotes } from '$lib/stores/attributeNotes'; | ||
|
|
||
| interface Props { | ||
| databaseId: string; | ||
| collectionId: string; | ||
| attributeKey: string; | ||
| } | ||
|
|
||
| let { databaseId, collectionId, attributeKey }: Props = $props(); | ||
|
|
||
| // Current persisted note value | ||
| let note = $state(attributeNotes.getNote(databaseId, collectionId, attributeKey)); |
| let { databaseId, collectionId, attributeKey }: Props = $props(); | ||
|
|
||
| // Current persisted note value | ||
| let note = $state(attributeNotes.getNote(databaseId, collectionId, attributeKey)); | ||
|
|
||
| // Whether the inline editor is open | ||
| let editing = $state(false); | ||
|
|
||
| // Draft copy while the user types | ||
| let draft = $state(note); | ||
|
|
| maxlength="500" | ||
| onkeydown={handleKeydown}></textarea> | ||
| <div class="attribute-note__editor-actions"> | ||
| <span class="attribute-note__hint">Ctrl+Enter to save · Esc to cancel</span> |
There was a problem hiding this comment.
Pull request overview
Adds a console-only “internal notes” feature for database collection attributes/columns, backed by a localStorage store and surfaced inline in the columns UI.
Changes:
- Added
AttributeNote.svelteinline editor/display component for per-attribute notes - Created
attributeNotes.tsstore to persist notes in localStorage - Integrated the note component into the table columns page
Reviewed changes
Copilot reviewed 3 out of 4 changed files in this pull request and generated 3 comments.
| File | Description |
|---|---|
| src/routes/(console)/project-[region]-[project]/databases/database-[database]/table-[table]/columns/+page.svelte | Renders the new AttributeNote UI for each column in the columns list |
| src/lib/stores/attributeNotes.ts | Introduces a localStorage-backed store for reading/writing notes keyed by database/collection/attribute |
| src/lib/components/AttributeNote.svelte | New reusable inline note editor/display component |
| bun.lock | Lockfile updates (adds integrity hashes for existing dependencies) |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| getNote(databaseId: string, collectionId: string, attributeKey: string): string { | ||
| const notes = loadFromStorage(); | ||
| return notes[buildNoteKey(databaseId, collectionId, attributeKey)] ?? ''; | ||
| }, |
| * Load notes map from localStorage, returning an empty object on any error. | ||
| */ | ||
| function isNotesMap(value: unknown): value is NotesMap { | ||
| return typeof value === 'object' && value !== null && !Array.isArray(value); |
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Summary
Adds support for internal notes on collection attributes, allowing better documentation and context management within the console.
Changes
AttributeNote.sveltecomponent for displaying and managing notesattributeNotes.tsstore for handling state and logicTesting
Related Issue
Closes #11945
Notes