mirror of
https://github.com/Memo-2023/mana-monorepo.git
synced 2026-05-25 12:34:37 +02:00
feat(local-first): migrate tags + task stores to reactive liveQuery across all apps
- Todo: Replace manual fetch/state stores with useLiveQuery() for tasks,
projects, and tags. Components use Svelte context instead of store imports.
Stores reduced to mutation-only services. Removes ~200 lines of manual
state management. Enables multi-tab sync and auto-refresh on data changes.
- Tags (all 16 apps): Migrate from API-based createTagStore() to shared
local-first IndexedDB ('manacore-tags'). Tags now work offline and in
guest mode with default seed data. All apps share the same tag DB via
tagLocalStore + useAllTags() + setContext pattern.
- Cleanup: Delete unused Todo API files (projects.ts, labels.ts,
reminders.ts), remove dead labels store, clean up barrel exports.
Apps migrated: Todo, Zitare, Questions, Planta, Clock, Presi, Mukke,
Context, CityCorners, ManaDeck, Chat, Contacts, Calendar, Picture,
Storage, Photos
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
32939fbfb5
commit
5c33962439
83 changed files with 1896 additions and 3937 deletions
|
|
@ -1,20 +1,13 @@
|
|||
/**
|
||||
* Tag Store - Uses shared createTagStore backed by central mana-core-auth
|
||||
* Tag Store — Local-First via Shared Tag Store
|
||||
* Tags are stored in shared IndexedDB ('manacore-tags'), accessible across all apps.
|
||||
* Use context ('tags') for reads, tagMutations for writes.
|
||||
*/
|
||||
import { browser } from '$app/environment';
|
||||
import { createTagStore } from '@manacore/shared-stores';
|
||||
import { authStore } from '$lib/stores/auth.svelte';
|
||||
|
||||
function getAuthUrl(): string {
|
||||
if (browser && typeof window !== 'undefined') {
|
||||
const injectedUrl = (window as unknown as { __PUBLIC_MANA_CORE_AUTH_URL__?: string })
|
||||
.__PUBLIC_MANA_CORE_AUTH_URL__;
|
||||
return injectedUrl || 'http://localhost:3001';
|
||||
}
|
||||
return 'http://localhost:3001';
|
||||
}
|
||||
|
||||
export const tagStore = createTagStore({
|
||||
authUrl: getAuthUrl(),
|
||||
getToken: () => authStore.getValidToken(),
|
||||
});
|
||||
export {
|
||||
tagMutations,
|
||||
useAllTags,
|
||||
getTagById,
|
||||
getTagsByIds,
|
||||
getTagColor,
|
||||
getTagsByGroup,
|
||||
} from '@manacore/shared-stores';
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
<script lang="ts">
|
||||
import { goto } from '$app/navigation';
|
||||
import { page } from '$app/stores';
|
||||
import { onMount } from 'svelte';
|
||||
import { onMount, setContext } from 'svelte';
|
||||
import { locale } from 'svelte-i18n';
|
||||
import { PillNavigation, CommandBar, TagStrip } from '@manacore/shared-ui';
|
||||
import type {
|
||||
|
|
@ -31,10 +31,17 @@
|
|||
import { AuthGate, GuestWelcomeModal } from '@manacore/shared-auth-ui';
|
||||
import { shouldShowGuestWelcome } from '@manacore/shared-auth-ui';
|
||||
import { contextStore } from '$lib/data/local-store';
|
||||
import { tagStore } from '$lib/stores/tags.svelte';
|
||||
import {
|
||||
tagLocalStore,
|
||||
tagMutations,
|
||||
useAllTags as useAllSharedTags,
|
||||
} from '@manacore/shared-stores';
|
||||
|
||||
const appItems = getPillAppItems('context');
|
||||
|
||||
const allTags = useAllSharedTags();
|
||||
setContext('tags', allTags);
|
||||
|
||||
let { children } = $props();
|
||||
|
||||
let commandBarOpen = $state(false);
|
||||
|
|
@ -218,9 +225,11 @@
|
|||
let showGuestWelcome = $state(false);
|
||||
|
||||
async function handleAuthReady() {
|
||||
await contextStore.initialize();
|
||||
await Promise.all([contextStore.initialize(), tagLocalStore.initialize()]);
|
||||
if (authStore.isAuthenticated) {
|
||||
contextStore.startSync(() => authStore.getValidToken());
|
||||
const getToken = () => authStore.getValidToken();
|
||||
contextStore.startSync(getToken);
|
||||
tagMutations.startSync(getToken);
|
||||
}
|
||||
if (!authStore.isAuthenticated && shouldShowGuestWelcome('context')) {
|
||||
showGuestWelcome = true;
|
||||
|
|
@ -234,7 +243,6 @@
|
|||
|
||||
if (authStore.isAuthenticated) {
|
||||
await userSettings.load();
|
||||
await tagStore.fetchTags();
|
||||
await Promise.all([spacesStore.load(), documentsStore.load()]);
|
||||
}
|
||||
}
|
||||
|
|
@ -280,7 +288,7 @@
|
|||
<!-- TagStrip (above PillNav, toggled via Tags pill) -->
|
||||
{#if isTagStripVisible}
|
||||
<TagStrip
|
||||
tags={tagStore.tags.map((t) => ({
|
||||
tags={allTags.value.map((t) => ({
|
||||
id: t.id,
|
||||
name: t.name,
|
||||
color: t.color || '#3b82f6',
|
||||
|
|
@ -289,7 +297,6 @@
|
|||
onToggle={() => {}}
|
||||
onClear={() => {}}
|
||||
managementHref="/tags"
|
||||
loading={tagStore.loading}
|
||||
/>
|
||||
{/if}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,12 +1,9 @@
|
|||
<script lang="ts">
|
||||
import { tagStore } from '$lib/stores/tags.svelte';
|
||||
import { onMount } from 'svelte';
|
||||
import { getContext } from 'svelte';
|
||||
import { tagMutations } from '@manacore/shared-stores';
|
||||
import type { Tag } from '@manacore/shared-tags';
|
||||
|
||||
onMount(() => {
|
||||
if (tagStore.tags.length === 0) {
|
||||
tagStore.fetchTags();
|
||||
}
|
||||
});
|
||||
const tagsCtx: { readonly value: Tag[] } = getContext('tags');
|
||||
</script>
|
||||
|
||||
<svelte:head>
|
||||
|
|
@ -19,13 +16,11 @@
|
|||
Tags sind app-übergreifend — Änderungen gelten in allen ManaCore-Apps.
|
||||
</p>
|
||||
|
||||
{#if tagStore.loading}
|
||||
<p>Lädt...</p>
|
||||
{:else if tagStore.tags.length === 0}
|
||||
{#if tagsCtx.value.length === 0}
|
||||
<p>Keine Tags vorhanden.</p>
|
||||
{:else}
|
||||
<div class="grid gap-2">
|
||||
{#each tagStore.tags as tag}
|
||||
{#each tagsCtx.value as tag}
|
||||
<div class="flex items-center gap-2 p-2 rounded-lg bg-card">
|
||||
<span class="w-3 h-3 rounded-full" style="background-color: {tag.color}"></span>
|
||||
<span>{tag.name}</span>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue