Skip to content

โ† All Skills Knowledge History

List-level export-all + batch-import, alongside per-memo modal import/export

completed๐Ÿ“ฆ my-memo๐Ÿ‘ค YCEJ9999๐Ÿ—“ 2026-06-21 10:30:00

memoimport-exportbatch-importuseFileSystemAccesstwo-input-fallback

Request

  • Export ALL memos from the list to one .txt.
  • Import a .txt and automatically add a batch of memos (like the original feature).
  • Update Mono Skills.

Summary

List-level export-all + batch-import (alongside per-memo modal import/export)

The memo app now has both granularities of .txt I/O:

  • Per-memo (in the add/edit modal): import a .txt to prefill the form; export the single open memo. (From 2026-06-21_memo-per-memo-import-export.)
  • List-level (toolbar): Ekspor Semua downloads every memo to one backup .txt; Impor Batch reads a .txt and adds all the memos it contains to the list at once.

This restores the original all-memos backup/restore and keeps the per-memo flow โ€” they share the same serialize/parse helpers and useFileSystemAccess instance.

Key implementation point: two hidden fallback inputs

The page now triggers FSA open() for two different outcomes โ€” prefill the form (per-memo) vs append a batch (list). On non-Chromium browsers the fallback is a hidden <input type=file>, and each path needs its own input + change handler, or a single shared input's change would route to the wrong action:

  • fileInput + onFallbackFile โ†’ applyImported() (writes store.input).
  • batchInput + onBatchFile โ†’ store.importMemos(parseMemos(text)) (appends to the list). The Chromium FSA path can reuse the one fsa instance because each call awaits and reads fsa.data.value immediately, so there's no cross-talk.

Helpers (restored / reused)

  • use-memo-utils.ts: re-added serializeMemos(memos) (file header + one ===== MEMO ===== block per memo) and backupFileName(); serializeMemo/memoFileName (per-memo) and parseMemos stay. parseMemos already handles one-or-many blocks and a plain .txt, so a batch file, a single-memo file, or an arbitrary text file all import.
  • use-memo.ts: re-added importMemos(incoming): number โ€” append (merge) + persist + notif count; every imported memo got a fresh crypto.randomUUID() from parseMemos.
  • index.vue: exportAll() / importBatch() / onBatchFile() + the two toolbar buttons (i-mdi-database-export-outline, i-mdi-database-import-outline) and the second hidden input.

Files

  • src/composables/use-memo-utils.ts, src/stores/use-memo.ts, src/pages/memo/index.vue.

Outcome

successvite module transform + UnoCSS icon check /memo, page, store, and use-memo-utils.ts transform 200 Page exposes exportAll/importBatch/onBatchFile/batchInput; store re-exports importMemos; utils re-export serializeMemos/backupFileName UnoCSS generates i-mdi-database-import-outline and i-mdi-database-export-outline Multi-block serialize/parse round-trip was validated in an earlier session (2 memos, multiline)

Decisions

Keep both granularities (per-memo modal + list-level batch)

List toolbar gets Ekspor Semua / Impor Batch; the add/edit modal keeps per-memo Impor/Ekspor.

Why: User asked for the original all-memos export + batch import back, in addition to the per-memo modal flow. They share helpers, so both coexist cheaply.

Separate hidden file input per import action

fileInput+onFallbackFile (prefill form) and batchInput+onBatchFile (append batch) are distinct.

Why: On non-Chromium browsers the fallback is a hidden <input>; one shared input's change event can't distinguish 'fill the form' from 'add a batch', so each needs its own input + handler.

Batch import = merge with fresh uuids

importMemos appends; parseMemos assigns new crypto.randomUUID() to each.

Why: Merge avoids data loss; fresh ids prevent collisions when re-importing a backup exported from this same app.

Files changed

FileOperationNote
src/composables/use-memo-utils.tsmodifiedRe-added serializeMemos(memos) (multi-block backup) + backupFileName(); kept serializeMemo/memoFileName/parseMemos
src/stores/use-memo.tsmodifiedRe-added importMemos(incoming): number โ€” batch append (merge) + persist + notif count; exported it
src/pages/memo/index.vuemodifiedAdded exportAll()/importBatch()/onBatchFile() + a SECOND hidden input (batchInput) so the batch fallback doesn't collide with the per-memo one; Ekspor Semua / Impor Batch toolbar buttons

Commands

pnpm dev
curl /memo + page + store + use-memo-utils.ts (all 200)
MONO_SKILLS=true MONO_SKILLS_GITHUB_TOKEN=[REDACTED] pnpm exec mono skills save --app my-memo --dir .mono/skills/pending/<id>

Validation

Tests: not run Build: passed


โ† All Skills Knowledge History