mirror of
https://github.com/Memo-2023/mana-monorepo.git
synced 2026-05-14 20:21:09 +02:00
♻️ refactor: create createSimpleNavigationStores and migrate 10 apps
- Add factory for writable navigation stores with optional persistence - Support toolbar collapsed state with withToolbar option - Migrate all 10 navigation stores to use shared factory - Clock saves 32 LOC with built-in localStorage persistence Savings: ~50 LOC (68 LOC removed, factory adds reusable 94 LOC)
This commit is contained in:
parent
c14cd6cac5
commit
bf719f188f
13 changed files with 150 additions and 82 deletions
|
|
@ -1,5 +1,6 @@
|
||||||
import { writable } from 'svelte/store';
|
import { createSimpleNavigationStores } from '@manacore/shared-stores';
|
||||||
|
|
||||||
export const isSidebarMode = writable(false);
|
export const { isSidebarMode, isNavCollapsed, isToolbarCollapsed } = createSimpleNavigationStores({
|
||||||
export const isNavCollapsed = writable(false);
|
withToolbar: true,
|
||||||
export const isToolbarCollapsed = writable(false);
|
toolbarCollapsedDefault: false,
|
||||||
|
});
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,3 @@
|
||||||
import { writable } from 'svelte/store';
|
import { createSimpleNavigationStores } from '@manacore/shared-stores';
|
||||||
|
|
||||||
export const isSidebarMode = writable(false);
|
export const { isSidebarMode, isNavCollapsed } = createSimpleNavigationStores();
|
||||||
export const isNavCollapsed = writable(false);
|
|
||||||
|
|
|
||||||
|
|
@ -1,35 +1,5 @@
|
||||||
/**
|
import { createSimpleNavigationStores } from '@manacore/shared-stores';
|
||||||
* Navigation Store - Manages navigation state
|
|
||||||
*/
|
|
||||||
|
|
||||||
import { writable } from 'svelte/store';
|
export const { isSidebarMode, isNavCollapsed } = createSimpleNavigationStores({
|
||||||
import { browser } from '$app/environment';
|
storageKey: 'clock',
|
||||||
|
});
|
||||||
const SIDEBAR_MODE_KEY = 'clock_sidebar_mode';
|
|
||||||
const NAV_COLLAPSED_KEY = 'clock_nav_collapsed';
|
|
||||||
|
|
||||||
// Check localStorage for initial values
|
|
||||||
function getInitialSidebarMode(): boolean {
|
|
||||||
if (!browser) return false;
|
|
||||||
return localStorage.getItem(SIDEBAR_MODE_KEY) === 'true';
|
|
||||||
}
|
|
||||||
|
|
||||||
function getInitialCollapsed(): boolean {
|
|
||||||
if (!browser) return false;
|
|
||||||
return localStorage.getItem(NAV_COLLAPSED_KEY) === 'true';
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create stores
|
|
||||||
export const isSidebarMode = writable(getInitialSidebarMode());
|
|
||||||
export const isNavCollapsed = writable(getInitialCollapsed());
|
|
||||||
|
|
||||||
// Subscribe to persist changes
|
|
||||||
if (browser) {
|
|
||||||
isSidebarMode.subscribe((value) => {
|
|
||||||
localStorage.setItem(SIDEBAR_MODE_KEY, String(value));
|
|
||||||
});
|
|
||||||
|
|
||||||
isNavCollapsed.subscribe((value) => {
|
|
||||||
localStorage.setItem(NAV_COLLAPSED_KEY, String(value));
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,3 @@
|
||||||
import { writable } from 'svelte/store';
|
import { createSimpleNavigationStores } from '@manacore/shared-stores';
|
||||||
|
|
||||||
export const isSidebarMode = writable(false);
|
export const { isSidebarMode, isNavCollapsed } = createSimpleNavigationStores();
|
||||||
export const isNavCollapsed = writable(false);
|
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,3 @@
|
||||||
import { writable } from 'svelte/store';
|
import { createSimpleNavigationStores } from '@manacore/shared-stores';
|
||||||
|
|
||||||
export const isSidebarMode = writable(false);
|
export const { isSidebarMode, isNavCollapsed } = createSimpleNavigationStores();
|
||||||
export const isNavCollapsed = writable(false);
|
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,3 @@
|
||||||
import { writable } from 'svelte/store';
|
import { createSimpleNavigationStores } from '@manacore/shared-stores';
|
||||||
|
|
||||||
export const isSidebarMode = writable(false);
|
export const { isSidebarMode, isNavCollapsed } = createSimpleNavigationStores();
|
||||||
export const isNavCollapsed = writable(false);
|
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,3 @@
|
||||||
import { writable } from 'svelte/store';
|
import { createSimpleNavigationStores } from '@manacore/shared-stores';
|
||||||
|
|
||||||
export const isSidebarMode = writable(false);
|
export const { isSidebarMode, isNavCollapsed } = createSimpleNavigationStores();
|
||||||
export const isNavCollapsed = writable(false);
|
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,3 @@
|
||||||
import { writable } from 'svelte/store';
|
import { createSimpleNavigationStores } from '@manacore/shared-stores';
|
||||||
|
|
||||||
export const isSidebarMode = writable(false);
|
export const { isSidebarMode, isNavCollapsed } = createSimpleNavigationStores();
|
||||||
export const isNavCollapsed = writable(false);
|
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,3 @@
|
||||||
/**
|
import { createSimpleNavigationStores } from '@manacore/shared-stores';
|
||||||
* Navigation Store - Manages sidebar and navigation state
|
|
||||||
*/
|
|
||||||
|
|
||||||
import { writable } from 'svelte/store';
|
export const { isSidebarMode, isNavCollapsed } = createSimpleNavigationStores();
|
||||||
|
|
||||||
export const isSidebarMode = writable(false);
|
|
||||||
export const isNavCollapsed = writable(false);
|
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
import { writable } from 'svelte/store';
|
import { createSimpleNavigationStores } from '@manacore/shared-stores';
|
||||||
|
|
||||||
export const isSidebarMode = writable(false);
|
export const { isSidebarMode, isNavCollapsed, isToolbarCollapsed } = createSimpleNavigationStores({
|
||||||
export const isNavCollapsed = writable(false);
|
withToolbar: true,
|
||||||
export const isToolbarCollapsed = writable(true);
|
toolbarCollapsedDefault: true,
|
||||||
|
});
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,7 @@
|
||||||
| ~~**MITTEL**~~ | ~~TypeScript Configs~~ | ~~400 LOC~~ ✅ **~280 LOC entfernt** | ~~Niedrig~~ |
|
| ~~**MITTEL**~~ | ~~TypeScript Configs~~ | ~~400 LOC~~ ✅ **~280 LOC entfernt** | ~~Niedrig~~ |
|
||||||
| **MITTEL** | UI Component Cleanup | 400 LOC | Niedrig |
|
| **MITTEL** | UI Component Cleanup | 400 LOC | Niedrig |
|
||||||
| ~~**MITTEL**~~ | ~~Vite Configs~~ | ~~300 LOC~~ ✅ **~350 LOC entfernt** | ~~Niedrig~~ |
|
| ~~**MITTEL**~~ | ~~Vite Configs~~ | ~~300 LOC~~ ✅ **~350 LOC entfernt** | ~~Niedrig~~ |
|
||||||
| **MITTEL** | Navigation Stores | 50 LOC | Niedrig |
|
| ~~**MITTEL**~~ | ~~Navigation Stores~~ | ~~50 LOC~~ ✅ **~50 LOC entfernt** | ~~Niedrig~~ |
|
||||||
| ~~**NIEDRIG**~~ | ~~Drizzle Configs~~ | ~~200 LOC~~ ✅ **~160 LOC entfernt** | ~~Niedrig~~ |
|
| ~~**NIEDRIG**~~ | ~~Drizzle Configs~~ | ~~200 LOC~~ ✅ **~160 LOC entfernt** | ~~Niedrig~~ |
|
||||||
| **NIEDRIG** | Logger Utilities | 130 LOC | Niedrig |
|
| **NIEDRIG** | Logger Utilities | 130 LOC | Niedrig |
|
||||||
|
|
||||||
|
|
@ -174,30 +174,38 @@ export const todoSettings = {
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
### 2.2 MITTEL: Navigation Stores (50 LOC)
|
### ~~2.2 MITTEL: Navigation Stores~~ ✅ ERLEDIGT (~50 LOC gespart)
|
||||||
|
|
||||||
**Problem:** 9 Apps haben fast identische Navigation-Stores.
|
**Status:** `createSimpleNavigationStores()` Factory erstellt und 10 Apps migriert (29.01.2026)
|
||||||
|
|
||||||
**Pattern (5-6 LOC pro App):**
|
**Erstellte Factory:** `packages/shared-stores/src/navigation-simple.ts`
|
||||||
|
- Erstellt `isSidebarMode`, `isNavCollapsed` writable Stores
|
||||||
|
- Optional: `isToolbarCollapsed` mit `withToolbar: true`
|
||||||
|
- Optional: localStorage Persistenz mit `storageKey`
|
||||||
|
|
||||||
|
**Migrierte Apps (10 von 10):**
|
||||||
|
- ✅ Einfach: chat, contacts, manacore, manadeck, matrix, presi, storage
|
||||||
|
- ✅ Mit Toolbar: calendar, todo
|
||||||
|
- ✅ Mit Persistenz: clock
|
||||||
|
|
||||||
|
**Vorher (5-36 LOC):**
|
||||||
```typescript
|
```typescript
|
||||||
import { writable } from 'svelte/store';
|
import { writable } from 'svelte/store';
|
||||||
export const isSidebarMode = writable(false);
|
export const isSidebarMode = writable(false);
|
||||||
export const isNavCollapsed = writable(false);
|
export const isNavCollapsed = writable(false);
|
||||||
|
// + optional localStorage handling (30+ LOC)
|
||||||
```
|
```
|
||||||
|
|
||||||
**Ausnahme:** Clock (36 LOC) mit localStorage Persistenz + Media Query Listeners
|
**Nachher (3-5 LOC):**
|
||||||
|
|
||||||
**Empfehlung:** Factory in `@manacore/shared-stores`
|
|
||||||
|
|
||||||
```typescript
|
```typescript
|
||||||
export function createNavigationStore(options?: {
|
import { createSimpleNavigationStores } from '@manacore/shared-stores';
|
||||||
persist?: boolean;
|
export const { isSidebarMode, isNavCollapsed } = createSimpleNavigationStores({
|
||||||
mediaQueryCollapse?: string;
|
storageKey: 'clock', // optional
|
||||||
}) {
|
});
|
||||||
// ...
|
|
||||||
}
|
|
||||||
```
|
```
|
||||||
|
|
||||||
|
**Einsparung:** ~50 LOC (besonders Clock: 36 → 4 LOC)
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
### 2.3 NIEDRIG: Theme Stores Migration
|
### 2.3 NIEDRIG: Theme Stores Migration
|
||||||
|
|
@ -427,7 +435,7 @@ export default createDrizzleConfig({ dbName: 'chat' });
|
||||||
| ~~`createAppSettingsStore()` Factory erstellen~~ | ~~600~~ → **323** | ~~Mittel~~ | ✅ Erledigt |
|
| ~~`createAppSettingsStore()` Factory erstellen~~ | ~~600~~ → **323** | ~~Mittel~~ | ✅ Erledigt |
|
||||||
| ~~`@manacore/shared-tsconfig` Package erstellen~~ | ~~400~~ → **280** | ~~Niedrig~~ | ✅ Erledigt |
|
| ~~`@manacore/shared-tsconfig` Package erstellen~~ | ~~400~~ → **280** | ~~Niedrig~~ | ✅ Erledigt |
|
||||||
| ~~`@manacore/shared-vite-config` erweitern (15 Apps)~~ | ~~300~~ → **350** | ~~Niedrig~~ | ✅ Erledigt |
|
| ~~`@manacore/shared-vite-config` erweitern (15 Apps)~~ | ~~300~~ → **350** | ~~Niedrig~~ | ✅ Erledigt |
|
||||||
| Navigation Store Factory erstellen | 50 | Niedrig | Offen |
|
| ~~Navigation Store Factory erstellen~~ | ~~50~~ → **50** | ~~Niedrig~~ | ✅ Erledigt |
|
||||||
|
|
||||||
### Phase 3: Backend Setup (5-7 Tage, ~2.000 LOC)
|
### Phase 3: Backend Setup (5-7 Tage, ~2.000 LOC)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -15,3 +15,8 @@ export {
|
||||||
type AppSettingsStore,
|
type AppSettingsStore,
|
||||||
type AppSettingsStoreOptions,
|
type AppSettingsStoreOptions,
|
||||||
} from './settings.svelte';
|
} from './settings.svelte';
|
||||||
|
export {
|
||||||
|
createSimpleNavigationStores,
|
||||||
|
type SimpleNavigationStores,
|
||||||
|
type SimpleNavigationOptions,
|
||||||
|
} from './navigation-simple';
|
||||||
|
|
|
||||||
94
packages/shared-stores/src/navigation-simple.ts
Normal file
94
packages/shared-stores/src/navigation-simple.ts
Normal file
|
|
@ -0,0 +1,94 @@
|
||||||
|
/**
|
||||||
|
* Simple Navigation Stores Factory
|
||||||
|
* Creates writable stores for navigation state with optional persistence.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { writable, type Writable } from 'svelte/store';
|
||||||
|
|
||||||
|
export interface SimpleNavigationStores {
|
||||||
|
/** Whether the app is in sidebar mode (desktop) */
|
||||||
|
isSidebarMode: Writable<boolean>;
|
||||||
|
/** Whether the nav is collapsed */
|
||||||
|
isNavCollapsed: Writable<boolean>;
|
||||||
|
/** Whether the toolbar is collapsed (optional) */
|
||||||
|
isToolbarCollapsed?: Writable<boolean>;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface SimpleNavigationOptions {
|
||||||
|
/** App name for localStorage keys (e.g., 'clock' -> 'clock_sidebar_mode') */
|
||||||
|
storageKey?: string;
|
||||||
|
/** Include isToolbarCollapsed store */
|
||||||
|
withToolbar?: boolean;
|
||||||
|
/** Default value for toolbar collapsed */
|
||||||
|
toolbarCollapsedDefault?: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates simple navigation stores compatible with Svelte's writable API.
|
||||||
|
*
|
||||||
|
* @example
|
||||||
|
* // Basic usage (no persistence)
|
||||||
|
* export const { isSidebarMode, isNavCollapsed } = createSimpleNavigationStores();
|
||||||
|
*
|
||||||
|
* @example
|
||||||
|
* // With persistence
|
||||||
|
* export const { isSidebarMode, isNavCollapsed } = createSimpleNavigationStores({
|
||||||
|
* storageKey: 'clock',
|
||||||
|
* });
|
||||||
|
*
|
||||||
|
* @example
|
||||||
|
* // With toolbar
|
||||||
|
* export const { isSidebarMode, isNavCollapsed, isToolbarCollapsed } = createSimpleNavigationStores({
|
||||||
|
* withToolbar: true,
|
||||||
|
* toolbarCollapsedDefault: true,
|
||||||
|
* });
|
||||||
|
*/
|
||||||
|
export function createSimpleNavigationStores(
|
||||||
|
options: SimpleNavigationOptions = {}
|
||||||
|
): SimpleNavigationStores {
|
||||||
|
const { storageKey, withToolbar = false, toolbarCollapsedDefault = false } = options;
|
||||||
|
|
||||||
|
const isBrowser = typeof localStorage !== 'undefined';
|
||||||
|
|
||||||
|
// Helper to get initial value from localStorage
|
||||||
|
function getInitialValue(key: string, defaultValue: boolean): boolean {
|
||||||
|
if (!isBrowser || !storageKey) return defaultValue;
|
||||||
|
const stored = localStorage.getItem(`${storageKey}_${key}`);
|
||||||
|
return stored !== null ? stored === 'true' : defaultValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Helper to create a persisted writable
|
||||||
|
function createPersistedWritable(key: string, defaultValue: boolean): Writable<boolean> {
|
||||||
|
const store = writable(getInitialValue(key, defaultValue));
|
||||||
|
|
||||||
|
if (isBrowser && storageKey) {
|
||||||
|
store.subscribe((value) => {
|
||||||
|
localStorage.setItem(`${storageKey}_${key}`, String(value));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return store;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create stores (persisted if storageKey provided, otherwise simple)
|
||||||
|
const isSidebarMode = storageKey
|
||||||
|
? createPersistedWritable('sidebar_mode', false)
|
||||||
|
: writable(false);
|
||||||
|
|
||||||
|
const isNavCollapsed = storageKey
|
||||||
|
? createPersistedWritable('nav_collapsed', false)
|
||||||
|
: writable(false);
|
||||||
|
|
||||||
|
const result: SimpleNavigationStores = {
|
||||||
|
isSidebarMode,
|
||||||
|
isNavCollapsed,
|
||||||
|
};
|
||||||
|
|
||||||
|
if (withToolbar) {
|
||||||
|
result.isToolbarCollapsed = storageKey
|
||||||
|
? createPersistedWritable('toolbar_collapsed', toolbarCollapsedDefault)
|
||||||
|
: writable(toolbarCollapsedDefault);
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue