mirror of
https://github.com/Memo-2023/mana-monorepo.git
synced 2026-05-14 22:41:09 +02:00
feat(scene-scope): wire filterBySceneScope into notes/todo/contacts/calendar queries
The four modules with tag junctions now filter their main useAll* queries through filterBySceneScope: when a scene has scopeTagIds set, only records tagged with at least one matching tag (+ untagged records) appear in the UI. Modules without tag junctions (drink, food, habits, journal, dreams, places) are unaffected — their records are always globally visible. - useAllNotes → noteTagOps.getTagIds - useAllTasks → taskTagTable junction lookup - useAllContacts → contactTagOps.getTagIds - useAllCalendarItems → eventTagOps.getTagIds (calendar-sourced blocks only; task/habit blocks pass through unfiltered) When no scene scope is active (scopeTagIds undefined), filterBySceneScope is a no-op identity pass — zero overhead for unscoped scenes. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
62fc566693
commit
26e1c4774f
4 changed files with 23 additions and 4 deletions
|
|
@ -13,6 +13,8 @@
|
|||
import { useLiveQueryWithDefault } from '@mana/local-store/svelte';
|
||||
import { db } from '$lib/data/database';
|
||||
import { decryptRecords } from '$lib/data/crypto';
|
||||
import { filterBySceneScope } from '$lib/stores/scene-scope.svelte';
|
||||
import { eventTagOps } from './stores/tags.svelte';
|
||||
import type { LocalCalendar, LocalEvent, Calendar, CalendarEvent } from './types';
|
||||
import { timeBlockToCalendarEvent } from './types';
|
||||
import type { LocalTimeBlock } from '$lib/data/time-blocks/types';
|
||||
|
|
@ -65,8 +67,13 @@ export function useAllCalendarItems() {
|
|||
eventsById.set(e.id, e);
|
||||
}
|
||||
|
||||
// Scene scope filter: only calendar-sourced blocks are tag-filterable.
|
||||
const scopedBlocks = await filterBySceneScope(decryptedBlocks, async (b) =>
|
||||
b.sourceModule === 'calendar' && b.sourceId ? eventTagOps.getTagIds(b.sourceId) : []
|
||||
);
|
||||
|
||||
// Convert to CalendarEvent, joining event data for calendar blocks
|
||||
return decryptedBlocks.map((block) => {
|
||||
return scopedBlocks.map((block) => {
|
||||
const tb = toTimeBlock(block);
|
||||
const eventData =
|
||||
block.sourceModule === 'calendar' ? (eventsById.get(block.sourceId) ?? null) : null;
|
||||
|
|
|
|||
|
|
@ -5,6 +5,8 @@
|
|||
import { useLiveQueryWithDefault } from '@mana/local-store/svelte';
|
||||
import { db } from '$lib/data/database';
|
||||
import { decryptRecords } from '$lib/data/crypto';
|
||||
import { filterBySceneScope } from '$lib/stores/scene-scope.svelte';
|
||||
import { contactTagOps } from './stores/tags.svelte';
|
||||
import type { LocalContact, Contact, SortField, ContactFilter } from './types';
|
||||
|
||||
// ─── Type Converter ───────────────────────────────────────
|
||||
|
|
@ -55,7 +57,8 @@ export function useAllContacts() {
|
|||
(c) => !c.deletedAt
|
||||
);
|
||||
const decrypted = await decryptRecords('contacts', visible);
|
||||
return decrypted.map(toContact);
|
||||
const scoped = await filterBySceneScope(decrypted, (c) => contactTagOps.getTagIds(c.id));
|
||||
return scoped.map(toContact);
|
||||
}, []);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -17,6 +17,8 @@
|
|||
import { useLiveQueryWithDefault } from '@mana/local-store/svelte';
|
||||
import { db } from '$lib/data/database';
|
||||
import { decryptRecords } from '$lib/data/crypto';
|
||||
import { filterBySceneScope } from '$lib/stores/scene-scope.svelte';
|
||||
import { noteTagOps } from './stores/tags.svelte';
|
||||
import type { LocalNote, Note } from './types';
|
||||
|
||||
// ─── Type Converters ───────────────────────────────────────
|
||||
|
|
@ -49,7 +51,8 @@ export function useAllNotes() {
|
|||
// Locked vault returns the blobs untouched so the UI can render
|
||||
// a "🔒" placeholder where title/content would be.
|
||||
const decrypted = await decryptRecords('notes', visible);
|
||||
return decrypted.map(toNote).sort((a, b) => {
|
||||
const scoped = await filterBySceneScope(decrypted, (n) => noteTagOps.getTagIds(n.id));
|
||||
return scoped.map(toNote).sort((a, b) => {
|
||||
if (a.isPinned !== b.isPinned) return a.isPinned ? -1 : 1;
|
||||
return b.updatedAt.localeCompare(a.updatedAt);
|
||||
});
|
||||
|
|
|
|||
|
|
@ -5,6 +5,8 @@
|
|||
import { useLiveQueryWithDefault } from '@mana/local-store/svelte';
|
||||
import { db } from '$lib/data/database';
|
||||
import { decryptRecords } from '$lib/data/crypto';
|
||||
import { filterBySceneScope } from '$lib/stores/scene-scope.svelte';
|
||||
import { taskTagTable } from './collections';
|
||||
import type {
|
||||
LocalTask,
|
||||
LocalBoardView,
|
||||
|
|
@ -46,7 +48,11 @@ export function useAllTasks() {
|
|||
const locals = await db.table<LocalTask>('tasks').orderBy('order').toArray();
|
||||
const visible = locals.filter((t) => !t.deletedAt);
|
||||
const decrypted = await decryptRecords('tasks', visible);
|
||||
return decrypted.map(toTask);
|
||||
const scoped = await filterBySceneScope(decrypted, async (t) => {
|
||||
const links = await taskTagTable.where('taskId').equals(t.id).toArray();
|
||||
return links.filter((l) => !l.deletedAt).map((l) => l.tagId);
|
||||
});
|
||||
return scoped.map(toTask);
|
||||
}, [] as Task[]);
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue