mirror of
https://github.com/Memo-2023/mana-monorepo.git
synced 2026-05-15 00:01:10 +02:00
refactor(mana): rename inventar → inventory across the codebase
The workbench-registry app id 'inventar' did not match its @mana/shared-branding MANA_APPS counterpart 'inventory', so the tier- gating join in apps/web/src/lib/app-registry/registry.ts silently failed for the inventory module — it fell into the "no MANA_APPS entry, default visible" fallback and was effectively un-gated. The codebase had also voted overwhelmingly for 'inventar' (53 files) vs 'inventory' (3 files in shared-branding), so the long-standing mismatch was just bookkeeping debt waiting to bite. Pre-release, no live data, so the cleanest fix is to align everything on the English 'inventory': - Workbench-registry id, module.config.ts appId, module folder, route folder and i18n locale folder all renamed via git mv - Standalone apps/inventar/ workspace package renamed - All imports, store identifiers (InventarEvents → InventoryEvents, INVENTAR_GUEST_SEED, inventarModuleConfig), i18n keys and href/goto paths follow the rename - The German display label "Inventar" is preserved everywhere it is a user-visible string (page titles, i18n values, toast labels) - Dexie table prefixes (invCollections, invItems, …) are unchanged - Drive-by fix: ListView.svelte was querying non-existent inventarCollections/inventarItems tables — corrected to the actual invCollections/invItems names from module.config - The "inventar ↔ inventory id mismatch" workaround comment in registry.ts is removed since the mismatch no longer exists module-registry.ts also picks up the user's parallel newsModuleConfig addition because both edits land in the same import block — keeping them split would have left the build in an inconsistent state. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
51f408755c
commit
45790ffbb8
65 changed files with 173 additions and 147 deletions
|
|
@ -1,14 +0,0 @@
|
|||
{
|
||||
"name": "inventar",
|
||||
"version": "1.0.0",
|
||||
"private": true,
|
||||
"description": "Inventar - Configurable Inventory Management",
|
||||
"scripts": {
|
||||
"dev": "pnpm --filter @inventar/web dev",
|
||||
"dev:web": "pnpm --filter @inventar/web dev"
|
||||
},
|
||||
"devDependencies": {
|
||||
"typescript": "^5.9.3"
|
||||
},
|
||||
"packageManager": "pnpm@9.15.0"
|
||||
}
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
# Inventar
|
||||
# Inventory
|
||||
|
||||
Configurable inventory management app - track anything with custom schemas.
|
||||
|
||||
|
|
@ -6,7 +6,7 @@ Configurable inventory management app - track anything with custom schemas.
|
|||
|
||||
## Project Overview
|
||||
|
||||
Inventar is a schema-less inventory management system built with SvelteKit. Users can create collections with custom field definitions, organize items by location and category, and view them in list/grid/table views.
|
||||
Inventory is a schema-less inventory management system built with SvelteKit. Users can create collections with custom field definitions, organize items by location and category, and view them in list/grid/table views.
|
||||
|
||||
### Tech Stack
|
||||
|
||||
|
|
@ -31,13 +31,13 @@ Inventar is a schema-less inventory management system built with SvelteKit. User
|
|||
|
||||
```bash
|
||||
# From monorepo root
|
||||
pnpm dev:inventar:web # Start web app on port 5190
|
||||
pnpm dev:inventory:web # Start web app on port 5190
|
||||
```
|
||||
|
||||
## Project Structure
|
||||
|
||||
```
|
||||
apps/inventar/
|
||||
apps/inventory/
|
||||
├── apps/
|
||||
│ └── web/ # SvelteKit web client
|
||||
│ ├── src/
|
||||
14
apps/inventory/package.json
Normal file
14
apps/inventory/package.json
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
{
|
||||
"name": "inventory",
|
||||
"version": "1.0.0",
|
||||
"private": true,
|
||||
"description": "Inventory - Configurable Inventory Management",
|
||||
"scripts": {
|
||||
"dev": "pnpm --filter @inventory/web dev",
|
||||
"dev:web": "pnpm --filter @inventory/web dev"
|
||||
},
|
||||
"devDependencies": {
|
||||
"typescript": "^5.9.3"
|
||||
},
|
||||
"packageManager": "pnpm@9.15.0"
|
||||
}
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"name": "@inventar/shared",
|
||||
"name": "@inventory/shared",
|
||||
"version": "1.0.0",
|
||||
"private": true,
|
||||
"type": "module",
|
||||
|
|
@ -34,7 +34,7 @@ const sections: Section[] = [
|
|||
{ name: 'ManaCalendar', icon: 'ph:calendar-bold', tagline: 'Kalender', url: 'https://calendar.mana.how' },
|
||||
{ name: 'Kontakte', icon: 'ph:address-book-bold', tagline: 'Kontakte', url: 'https://contacts.mana.how' },
|
||||
{ name: 'ManaStorage', icon: 'ph:cloud-bold', tagline: 'Cloud-Speicher', url: 'https://storage.mana.how' },
|
||||
{ name: 'Inventar', icon: 'ph:package-bold', tagline: 'Inventar', url: 'https://inventar.mana.how' },
|
||||
{ name: 'Inventar', icon: 'ph:package-bold', tagline: 'Inventar', url: 'https://inventory.mana.how' },
|
||||
],
|
||||
},
|
||||
{
|
||||
|
|
|
|||
|
|
@ -64,7 +64,7 @@ const APP_SUBDOMAINS = new Set([
|
|||
'picture',
|
||||
'calc',
|
||||
'citycorners',
|
||||
'inventar',
|
||||
'inventory',
|
||||
'times',
|
||||
'uload',
|
||||
'memoro',
|
||||
|
|
|
|||
|
|
@ -40,6 +40,7 @@ import {
|
|||
Calculator,
|
||||
Lightning,
|
||||
Sparkle,
|
||||
Newspaper,
|
||||
} from '@mana/shared-icons';
|
||||
|
||||
// ── Apps with entity capabilities ───────────────────────────
|
||||
|
|
@ -565,13 +566,13 @@ registerApp({
|
|||
});
|
||||
|
||||
registerApp({
|
||||
id: 'inventar',
|
||||
id: 'inventory',
|
||||
name: 'Inventar',
|
||||
color: '#78716C',
|
||||
icon: Package,
|
||||
views: {
|
||||
list: { load: () => import('$lib/modules/inventar/ListView.svelte') },
|
||||
detail: { load: () => import('$lib/modules/inventar/views/DetailView.svelte') },
|
||||
list: { load: () => import('$lib/modules/inventory/ListView.svelte') },
|
||||
detail: { load: () => import('$lib/modules/inventory/views/DetailView.svelte') },
|
||||
},
|
||||
});
|
||||
|
||||
|
|
@ -669,3 +670,24 @@ registerApp({
|
|||
list: { load: () => import('$lib/modules/playground/ListView.svelte') },
|
||||
},
|
||||
});
|
||||
|
||||
registerApp({
|
||||
id: 'news',
|
||||
name: 'News',
|
||||
color: '#10B981',
|
||||
icon: Newspaper,
|
||||
views: {
|
||||
list: { load: () => import('$lib/modules/news/ListView.svelte') },
|
||||
},
|
||||
contextMenuActions: [
|
||||
{
|
||||
id: 'open-feed',
|
||||
label: 'Feed öffnen',
|
||||
icon: Plus,
|
||||
action: () =>
|
||||
window.dispatchEvent(
|
||||
new CustomEvent('mana:quick-action', { detail: { app: 'news', action: 'open' } })
|
||||
),
|
||||
},
|
||||
],
|
||||
});
|
||||
|
|
|
|||
|
|
@ -91,10 +91,9 @@ export function getAllApps(): AppDescriptor[] {
|
|||
*
|
||||
* Returns null when there is no matching MANA_APPS entry. Internal-only
|
||||
* tools that exist in the workbench but not in MANA_APPS (`automations`,
|
||||
* `playground`, the `inventar` ↔ `inventory` id mismatch) fall into this
|
||||
* case — `getAccessibleApps` then treats them as visible by default
|
||||
* rather than hiding them for everyone, since the alternative is a
|
||||
* silent regression for founders/devs.
|
||||
* `playground`) fall into this case — `getAccessibleApps` then treats
|
||||
* them as visible by default rather than hiding them for everyone, since
|
||||
* the alternative is a silent regression for founders/devs.
|
||||
*/
|
||||
function getAppRequiredTier(appId: string): AccessTier | null {
|
||||
const branding = MANA_APPS.find((a) => a.id === appId);
|
||||
|
|
|
|||
|
|
@ -138,7 +138,7 @@ describe('module-registry — pre-refactor snapshot', () => {
|
|||
music: ['songs', 'mukkePlaylists', 'playlistSongs', 'mukkeProjects', 'markers', 'songTags'],
|
||||
storage: ['files', 'storageFolders', 'fileTags'],
|
||||
presi: ['presiDecks', 'slides', 'presiDeckTags'],
|
||||
inventar: ['invCollections', 'invItems', 'invLocations', 'invCategories', 'invItemTags'],
|
||||
inventory: ['invCollections', 'invItems', 'invLocations', 'invCategories', 'invItemTags'],
|
||||
photos: ['albums', 'albumItems', 'photoFavorites', 'photoMediaTags'],
|
||||
skilltree: ['skills', 'activities', 'achievements', 'skillTags'],
|
||||
citycorners: ['cities', 'ccLocations', 'ccFavorites', 'ccLocationTags'],
|
||||
|
|
|
|||
|
|
@ -61,7 +61,7 @@ import { zitareModuleConfig } from '$lib/modules/zitare/module.config';
|
|||
import { musicModuleConfig } from '$lib/modules/music/module.config';
|
||||
import { storageModuleConfig } from '$lib/modules/storage/module.config';
|
||||
import { presiModuleConfig } from '$lib/modules/presi/module.config';
|
||||
import { inventarModuleConfig } from '$lib/modules/inventar/module.config';
|
||||
import { inventoryModuleConfig } from '$lib/modules/inventory/module.config';
|
||||
import { photosModuleConfig } from '$lib/modules/photos/module.config';
|
||||
import { skilltreeModuleConfig } from '$lib/modules/skilltree/module.config';
|
||||
import { citycornersModuleConfig } from '$lib/modules/citycorners/module.config';
|
||||
|
|
@ -84,6 +84,7 @@ import { financeModuleConfig } from '$lib/modules/finance/module.config';
|
|||
import { placesModuleConfig } from '$lib/modules/places/module.config';
|
||||
import { playgroundModuleConfig } from '$lib/modules/playground/module.config';
|
||||
import { whoModuleConfig } from '$lib/modules/who/module.config';
|
||||
import { newsModuleConfig } from '$lib/modules/news/module.config';
|
||||
|
||||
export const MODULE_CONFIGS: readonly ModuleConfig[] = [
|
||||
manaCoreConfig,
|
||||
|
|
@ -100,7 +101,7 @@ export const MODULE_CONFIGS: readonly ModuleConfig[] = [
|
|||
musicModuleConfig,
|
||||
storageModuleConfig,
|
||||
presiModuleConfig,
|
||||
inventarModuleConfig,
|
||||
inventoryModuleConfig,
|
||||
photosModuleConfig,
|
||||
skilltreeModuleConfig,
|
||||
citycornersModuleConfig,
|
||||
|
|
@ -123,6 +124,7 @@ export const MODULE_CONFIGS: readonly ModuleConfig[] = [
|
|||
placesModuleConfig,
|
||||
playgroundModuleConfig,
|
||||
whoModuleConfig,
|
||||
newsModuleConfig,
|
||||
];
|
||||
|
||||
// ─── Derived Maps ──────────────────────────────────────────
|
||||
|
|
|
|||
|
|
@ -38,7 +38,7 @@ function registerLocale(lang: SupportedLocale) {
|
|||
presi,
|
||||
uload,
|
||||
times,
|
||||
inventar,
|
||||
inventory,
|
||||
photos,
|
||||
nutriphi,
|
||||
planta,
|
||||
|
|
@ -49,6 +49,7 @@ function registerLocale(lang: SupportedLocale) {
|
|||
guides,
|
||||
help,
|
||||
cycles,
|
||||
news,
|
||||
] = await Promise.all([
|
||||
import(`./locales/apps/${lang}.json`),
|
||||
import(`./locales/common/${lang}.json`),
|
||||
|
|
@ -72,7 +73,7 @@ function registerLocale(lang: SupportedLocale) {
|
|||
import(`./locales/presi/${lang}.json`),
|
||||
import(`./locales/uload/${lang}.json`),
|
||||
import(`./locales/times/${lang}.json`),
|
||||
import(`./locales/inventar/${lang}.json`),
|
||||
import(`./locales/inventory/${lang}.json`),
|
||||
import(`./locales/photos/${lang}.json`),
|
||||
import(`./locales/nutriphi/${lang}.json`),
|
||||
import(`./locales/planta/${lang}.json`),
|
||||
|
|
@ -83,6 +84,7 @@ function registerLocale(lang: SupportedLocale) {
|
|||
import(`./locales/guides/${lang}.json`),
|
||||
import(`./locales/help/${lang}.json`),
|
||||
import(`./locales/cycles/${lang}.json`),
|
||||
import(`./locales/news/${lang}.json`),
|
||||
]);
|
||||
|
||||
return {
|
||||
|
|
@ -108,7 +110,7 @@ function registerLocale(lang: SupportedLocale) {
|
|||
presi: presi.default,
|
||||
uload: uload.default,
|
||||
times: times.default,
|
||||
inventar: inventar.default,
|
||||
inventory: inventory.default,
|
||||
photos: photos.default,
|
||||
nutriphi: nutriphi.default,
|
||||
planta: planta.default,
|
||||
|
|
@ -119,6 +121,7 @@ function registerLocale(lang: SupportedLocale) {
|
|||
guides: guides.default,
|
||||
help: help.default,
|
||||
cycles: cycles.default,
|
||||
news: news.default,
|
||||
};
|
||||
});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@
|
|||
"nutriphi": "NutriPhi",
|
||||
"planta": "Planta",
|
||||
"presi": "Presi",
|
||||
"inventar": "Inventar",
|
||||
"inventory": "Inventar",
|
||||
"memoro": "Memoro",
|
||||
"questions": "Recherche",
|
||||
"skilltree": "Skills",
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@
|
|||
"nutriphi": "NutriPhi",
|
||||
"planta": "Planta",
|
||||
"presi": "Presi",
|
||||
"inventar": "Inventory",
|
||||
"inventory": "Inventory",
|
||||
"memoro": "Memoro",
|
||||
"questions": "Research",
|
||||
"skilltree": "Skills",
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@
|
|||
"nutriphi": "NutriPhi",
|
||||
"planta": "Planta",
|
||||
"presi": "Presi",
|
||||
"inventar": "Inventario",
|
||||
"inventory": "Inventario",
|
||||
"memoro": "Memoro",
|
||||
"questions": "Investigación",
|
||||
"skilltree": "Skills",
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@
|
|||
"nutriphi": "NutriPhi",
|
||||
"planta": "Planta",
|
||||
"presi": "Presi",
|
||||
"inventar": "Inventaire",
|
||||
"inventory": "Inventaire",
|
||||
"memoro": "Memoro",
|
||||
"questions": "Recherche",
|
||||
"skilltree": "Skills",
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@
|
|||
"nutriphi": "NutriPhi",
|
||||
"planta": "Planta",
|
||||
"presi": "Presi",
|
||||
"inventar": "Inventario",
|
||||
"inventory": "Inventario",
|
||||
"memoro": "Memoro",
|
||||
"questions": "Ricerca",
|
||||
"skilltree": "Skills",
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
<!--
|
||||
Inventar — Workbench ListView
|
||||
Inventory — Workbench ListView
|
||||
Collections and items overview.
|
||||
-->
|
||||
<script lang="ts">
|
||||
|
|
@ -12,12 +12,12 @@
|
|||
let { navigate }: ViewProps = $props();
|
||||
|
||||
const collectionsQuery = useLiveQueryWithDefault(async () => {
|
||||
const all = await db.table<LocalCollection>('inventarCollections').orderBy('order').toArray();
|
||||
const all = await db.table<LocalCollection>('invCollections').orderBy('order').toArray();
|
||||
return all.filter((c) => !c.deletedAt);
|
||||
}, [] as LocalCollection[]);
|
||||
|
||||
const itemsQuery = useLiveQueryWithDefault(async () => {
|
||||
const all = await db.table<LocalItem>('inventarItems').toArray();
|
||||
const all = await db.table<LocalItem>('invItems').toArray();
|
||||
return all.filter((i) => !i.deletedAt);
|
||||
}, [] as LocalItem[]);
|
||||
|
||||
|
|
@ -20,7 +20,7 @@ const DEMO_COLLECTION_ID = 'demo-electronics';
|
|||
const DEMO_LOCATION_ID = 'demo-home';
|
||||
const DEMO_CATEGORY_ID = 'demo-tech';
|
||||
|
||||
export const INVENTAR_GUEST_SEED = {
|
||||
export const INVENTORY_GUEST_SEED = {
|
||||
invCollections: [
|
||||
{
|
||||
id: DEMO_COLLECTION_ID,
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
/**
|
||||
* Inventar constants — templates and status definitions.
|
||||
*
|
||||
* Inlined from @inventar/shared since the unified app does not depend on it.
|
||||
* Inlined from @inventory/shared since the unified app does not depend on it.
|
||||
*/
|
||||
|
||||
import type { ItemStatus } from './queries';
|
||||
|
|
@ -49,6 +49,6 @@ export {
|
|||
invItemTable,
|
||||
invLocationTable,
|
||||
invCategoryTable,
|
||||
INVENTAR_GUEST_SEED,
|
||||
INVENTORY_GUEST_SEED,
|
||||
} from './collections';
|
||||
export type { LocalCollection, LocalItem, LocalLocation, LocalCategory } from './types';
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
import type { ModuleConfig } from '$lib/data/module-registry';
|
||||
|
||||
export const inventarModuleConfig: ModuleConfig = {
|
||||
appId: 'inventar',
|
||||
export const inventoryModuleConfig: ModuleConfig = {
|
||||
appId: 'inventory',
|
||||
tables: [
|
||||
{ name: 'invCollections', syncName: 'collections' },
|
||||
{ name: 'invItems', syncName: 'items' },
|
||||
|
|
@ -9,7 +9,7 @@ import { db } from '$lib/data/database';
|
|||
import { decryptRecords } from '$lib/data/crypto';
|
||||
import type { LocalCollection, LocalItem, LocalLocation, LocalCategory } from './types';
|
||||
|
||||
// ─── Shared Types (inline to avoid @inventar/shared dependency) ───
|
||||
// ─── Shared Types (inline to avoid @inventory/shared dependency) ───
|
||||
|
||||
export interface Collection {
|
||||
id: string;
|
||||
|
|
@ -8,7 +8,7 @@
|
|||
import { invCategoryTable } from '../collections';
|
||||
import { toCategory } from '../queries';
|
||||
import type { LocalCategory } from '../types';
|
||||
import { InventarEvents } from '@mana/shared-utils/analytics';
|
||||
import { InventoryEvents } from '@mana/shared-utils/analytics';
|
||||
|
||||
export const categoriesStore = {
|
||||
async create(data: { name: string; icon?: string; color?: string; parentId?: string }) {
|
||||
|
|
@ -25,7 +25,7 @@ export const categoriesStore = {
|
|||
order: siblings.length,
|
||||
};
|
||||
await invCategoryTable.add(newLocal);
|
||||
InventarEvents.categoryCreated();
|
||||
InventoryEvents.categoryCreated();
|
||||
return toCategory(newLocal);
|
||||
},
|
||||
|
||||
|
|
@ -49,6 +49,6 @@ export const categoriesStore = {
|
|||
for (const deleteId of idsToDelete) {
|
||||
await invCategoryTable.update(deleteId, { deletedAt: now, updatedAt: now });
|
||||
}
|
||||
InventarEvents.categoryDeleted();
|
||||
InventoryEvents.categoryDeleted();
|
||||
},
|
||||
};
|
||||
|
|
@ -8,7 +8,7 @@
|
|||
import { invCollectionTable } from '../collections';
|
||||
import { toCollection } from '../queries';
|
||||
import type { LocalCollection } from '../types';
|
||||
import { InventarEvents } from '@mana/shared-utils/analytics';
|
||||
import { InventoryEvents } from '@mana/shared-utils/analytics';
|
||||
|
||||
export const collectionsStore = {
|
||||
async create(data: {
|
||||
|
|
@ -33,7 +33,7 @@ export const collectionsStore = {
|
|||
itemCount: 0,
|
||||
};
|
||||
await invCollectionTable.add(newLocal);
|
||||
InventarEvents.collectionCreated();
|
||||
InventoryEvents.collectionCreated();
|
||||
return toCollection(newLocal);
|
||||
},
|
||||
|
||||
|
|
@ -52,7 +52,7 @@ export const collectionsStore = {
|
|||
deletedAt: new Date().toISOString(),
|
||||
updatedAt: new Date().toISOString(),
|
||||
});
|
||||
InventarEvents.collectionDeleted();
|
||||
InventoryEvents.collectionDeleted();
|
||||
},
|
||||
|
||||
async reorder(orderedIds: string[]) {
|
||||
|
|
@ -9,7 +9,7 @@ import { invItemTable } from '../collections';
|
|||
import { toItem } from '../queries';
|
||||
import type { LocalItem } from '../types';
|
||||
import type { ItemStatus } from '../queries';
|
||||
import { InventarEvents } from '@mana/shared-utils/analytics';
|
||||
import { InventoryEvents } from '@mana/shared-utils/analytics';
|
||||
import { encryptRecord } from '$lib/data/crypto';
|
||||
|
||||
export const itemsStore = {
|
||||
|
|
@ -49,7 +49,7 @@ export const itemsStore = {
|
|||
const plaintextSnapshot = toItem(newLocal);
|
||||
await encryptRecord('invItems', newLocal);
|
||||
await invItemTable.add(newLocal);
|
||||
InventarEvents.itemCreated();
|
||||
InventoryEvents.itemCreated();
|
||||
return plaintextSnapshot;
|
||||
},
|
||||
|
||||
|
|
@ -76,7 +76,7 @@ export const itemsStore = {
|
|||
};
|
||||
await encryptRecord('invItems', diff);
|
||||
await invItemTable.update(id, diff);
|
||||
InventarEvents.itemUpdated();
|
||||
InventoryEvents.itemUpdated();
|
||||
},
|
||||
|
||||
async delete(id: string) {
|
||||
|
|
@ -84,7 +84,7 @@ export const itemsStore = {
|
|||
deletedAt: new Date().toISOString(),
|
||||
updatedAt: new Date().toISOString(),
|
||||
});
|
||||
InventarEvents.itemDeleted();
|
||||
InventoryEvents.itemDeleted();
|
||||
},
|
||||
|
||||
async deleteByCollection(collectionId: string) {
|
||||
|
|
@ -8,7 +8,7 @@
|
|||
import { invLocationTable } from '../collections';
|
||||
import { toLocation } from '../queries';
|
||||
import type { LocalLocation } from '../types';
|
||||
import { InventarEvents } from '@mana/shared-utils/analytics';
|
||||
import { InventoryEvents } from '@mana/shared-utils/analytics';
|
||||
|
||||
function buildPath(locations: LocalLocation[], parentId?: string): string {
|
||||
if (!parentId) return '';
|
||||
|
|
@ -42,7 +42,7 @@ export const locationsStore = {
|
|||
order: siblings.length,
|
||||
};
|
||||
await invLocationTable.add(newLocal);
|
||||
InventarEvents.locationCreated();
|
||||
InventoryEvents.locationCreated();
|
||||
return toLocation(newLocal);
|
||||
},
|
||||
|
||||
|
|
@ -66,6 +66,6 @@ export const locationsStore = {
|
|||
for (const deleteId of idsToDelete) {
|
||||
await invLocationTable.update(deleteId, { deletedAt: now, updatedAt: now });
|
||||
}
|
||||
InventarEvents.locationDeleted();
|
||||
InventoryEvents.locationDeleted();
|
||||
},
|
||||
};
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
/**
|
||||
* Uinventar Tags — Uses shared global tags + module-specific junction table.
|
||||
* Inventory Tags — Uses shared global tags + module-specific junction table.
|
||||
*/
|
||||
|
||||
import { db } from '$lib/data/database';
|
||||
|
|
@ -6,7 +6,7 @@ import { createViewStore } from '@mana/shared-stores';
|
|||
import type { ViewMode, FilterCriteria } from '../queries';
|
||||
|
||||
export const viewStore = createViewStore<ViewMode, FilterCriteria>({
|
||||
storagePrefix: 'inventar',
|
||||
storagePrefix: 'inventory',
|
||||
defaultViewMode: 'list',
|
||||
defaultSort: { field: 'name', direction: 'asc' },
|
||||
hasActiveFilters: (f) =>
|
||||
|
|
@ -17,7 +17,7 @@ const SPLIT_APP_ID_LIST = [
|
|||
'music',
|
||||
'storage',
|
||||
'presi',
|
||||
'inventar',
|
||||
'inventory',
|
||||
'photos',
|
||||
'skilltree',
|
||||
'citycorners',
|
||||
|
|
|
|||
|
|
@ -6,8 +6,8 @@
|
|||
useAllItems,
|
||||
useAllLocations,
|
||||
useAllCategories,
|
||||
} from '$lib/modules/inventar/queries';
|
||||
import { viewStore } from '$lib/modules/inventar/stores/view.svelte';
|
||||
} from '$lib/modules/inventory/queries';
|
||||
import { viewStore } from '$lib/modules/inventory/stores/view.svelte';
|
||||
|
||||
let { children }: { children: Snippet } = $props();
|
||||
|
||||
|
|
@ -1,14 +1,14 @@
|
|||
<script lang="ts">
|
||||
import { goto } from '$app/navigation';
|
||||
import { getContext } from 'svelte';
|
||||
import { collectionsStore } from '$lib/modules/inventar/stores/collections.svelte';
|
||||
import { itemsStore } from '$lib/modules/inventar/stores/items.svelte';
|
||||
import { collectionsStore } from '$lib/modules/inventory/stores/collections.svelte';
|
||||
import { itemsStore } from '$lib/modules/inventory/stores/items.svelte';
|
||||
import {
|
||||
getSortedCollections,
|
||||
getItemCountByCollection,
|
||||
getTotalItemCount,
|
||||
} from '$lib/modules/inventar/queries';
|
||||
import type { Collection, Item } from '$lib/modules/inventar/queries';
|
||||
} from '$lib/modules/inventory/queries';
|
||||
import type { Collection, Item } from '$lib/modules/inventory/queries';
|
||||
import { Plus, Trash } from '@mana/shared-icons';
|
||||
|
||||
const collectionsCtx: { readonly value: Collection[] } = getContext('collections');
|
||||
|
|
@ -19,7 +19,7 @@
|
|||
}
|
||||
|
||||
function handleCollectionClick(collection: Collection) {
|
||||
goto(`/inventar/collections/${collection.id}`);
|
||||
goto(`/inventory/collections/${collection.id}`);
|
||||
}
|
||||
|
||||
function handleDelete(e: Event, id: string) {
|
||||
|
|
@ -50,7 +50,7 @@
|
|||
</p>
|
||||
</div>
|
||||
<a
|
||||
href="/inventar/collections/new"
|
||||
href="/inventory/collections/new"
|
||||
class="flex items-center gap-2 rounded-lg bg-[hsl(var(--primary))] px-4 py-2 text-sm font-medium text-[hsl(var(--primary-foreground))] transition-colors hover:opacity-90"
|
||||
>
|
||||
<Plus size={20} />
|
||||
|
|
@ -69,7 +69,7 @@
|
|||
Erstelle deine erste Sammlung, um loszulegen.
|
||||
</p>
|
||||
<a
|
||||
href="/inventar/collections/new"
|
||||
href="/inventory/collections/new"
|
||||
class="rounded-lg bg-[hsl(var(--primary))] px-6 py-2.5 text-sm font-medium text-[hsl(var(--primary-foreground))]"
|
||||
>
|
||||
Neue Sammlung
|
||||
|
|
@ -2,8 +2,8 @@
|
|||
import { _ } from 'svelte-i18n';
|
||||
import { Plus } from '@mana/shared-icons';
|
||||
import { getContext } from 'svelte';
|
||||
import { categoriesStore } from '$lib/modules/inventar/stores/categories.svelte';
|
||||
import type { Category } from '$lib/modules/inventar/queries';
|
||||
import { categoriesStore } from '$lib/modules/inventory/stores/categories.svelte';
|
||||
import type { Category } from '$lib/modules/inventory/queries';
|
||||
|
||||
const categoriesCtx: { readonly value: Category[] } = getContext('categories');
|
||||
|
||||
|
|
@ -3,18 +3,18 @@
|
|||
import { goto } from '$app/navigation';
|
||||
import { CaretLeft, PencilSimple, Plus, Trash } from '@mana/shared-icons';
|
||||
import { getContext } from 'svelte';
|
||||
import { itemsStore } from '$lib/modules/inventar/stores/items.svelte';
|
||||
import { viewStore } from '$lib/modules/inventar/stores/view.svelte';
|
||||
import { itemsStore } from '$lib/modules/inventory/stores/items.svelte';
|
||||
import { viewStore } from '$lib/modules/inventory/stores/view.svelte';
|
||||
import {
|
||||
getCollectionById,
|
||||
getItemsByCollection,
|
||||
getSortedItems,
|
||||
} from '$lib/modules/inventar/queries';
|
||||
import type { Collection, Item, ItemStatus } from '$lib/modules/inventar/queries';
|
||||
import FieldRenderer from '$lib/modules/inventar/components/fields/FieldRenderer.svelte';
|
||||
import FieldEditor from '$lib/modules/inventar/components/fields/FieldEditor.svelte';
|
||||
import StatusBadge from '$lib/modules/inventar/components/StatusBadge.svelte';
|
||||
import ViewModeToggle from '$lib/modules/inventar/components/ViewModeToggle.svelte';
|
||||
} from '$lib/modules/inventory/queries';
|
||||
import type { Collection, Item, ItemStatus } from '$lib/modules/inventory/queries';
|
||||
import FieldRenderer from '$lib/modules/inventory/components/fields/FieldRenderer.svelte';
|
||||
import FieldEditor from '$lib/modules/inventory/components/fields/FieldEditor.svelte';
|
||||
import StatusBadge from '$lib/modules/inventory/components/StatusBadge.svelte';
|
||||
import ViewModeToggle from '$lib/modules/inventory/components/ViewModeToggle.svelte';
|
||||
|
||||
const collectionsCtx: { readonly value: Collection[] } = getContext('collections');
|
||||
const itemsCtx: { readonly value: Item[] } = getContext('items');
|
||||
|
|
@ -59,7 +59,7 @@
|
|||
{#if !collection}
|
||||
<div class="text-center py-16">
|
||||
<p class="text-[hsl(var(--muted-foreground))]">Sammlung nicht gefunden</p>
|
||||
<a href="/inventar" class="mt-4 text-[hsl(var(--primary))]">Zuruck</a>
|
||||
<a href="/inventory" class="mt-4 text-[hsl(var(--primary))]">Zuruck</a>
|
||||
</div>
|
||||
{:else}
|
||||
<div class="space-y-6">
|
||||
|
|
@ -67,7 +67,7 @@
|
|||
<div class="flex items-center justify-between">
|
||||
<div class="flex items-center gap-3">
|
||||
<a
|
||||
href="/inventar"
|
||||
href="/inventory"
|
||||
class="text-[hsl(var(--muted-foreground))] hover:text-[hsl(var(--foreground))]"
|
||||
>
|
||||
<CaretLeft size={20} />
|
||||
|
|
@ -83,7 +83,7 @@
|
|||
<div class="flex items-center gap-2">
|
||||
<ViewModeToggle current={viewStore.viewMode} onchange={(m) => viewStore.setViewMode(m)} />
|
||||
<a
|
||||
href="/inventar/collections/{collection.id}/edit"
|
||||
href="/inventory/collections/{collection.id}/edit"
|
||||
class="rounded-lg border border-[hsl(var(--border))] p-2 text-[hsl(var(--muted-foreground))] hover:text-[hsl(var(--foreground))]"
|
||||
>
|
||||
<PencilSimple size={16} />
|
||||
|
|
@ -166,8 +166,8 @@
|
|||
<div class="grid gap-4 sm:grid-cols-2 lg:grid-cols-3">
|
||||
{#each sortedItems as item (item.id)}
|
||||
<div
|
||||
onclick={() => goto(`/inventar/items/${item.id}`)}
|
||||
onkeydown={(e) => e.key === 'Enter' && goto(`/inventar/items/${item.id}`)}
|
||||
onclick={() => goto(`/inventory/items/${item.id}`)}
|
||||
onkeydown={(e) => e.key === 'Enter' && goto(`/inventory/items/${item.id}`)}
|
||||
role="button"
|
||||
tabindex="0"
|
||||
class="group cursor-pointer rounded-xl border border-[hsl(var(--border))] bg-[hsl(var(--card))] p-4 text-left"
|
||||
|
|
@ -221,7 +221,7 @@
|
|||
{#each sortedItems as item (item.id)}
|
||||
<tr
|
||||
class="cursor-pointer border-b border-[hsl(var(--border))] transition-colors hover:bg-[hsl(var(--accent)/0.05)]"
|
||||
onclick={() => goto(`/inventar/items/${item.id}`)}
|
||||
onclick={() => goto(`/inventory/items/${item.id}`)}
|
||||
>
|
||||
<td class="px-4 py-2.5 font-medium text-[hsl(var(--foreground))]">{item.name}</td>
|
||||
<td class="px-4 py-2.5"><StatusBadge status={item.status} /></td>
|
||||
|
|
@ -248,8 +248,8 @@
|
|||
<div class="space-y-2">
|
||||
{#each sortedItems as item (item.id)}
|
||||
<div
|
||||
onclick={() => goto(`/inventar/items/${item.id}`)}
|
||||
onkeydown={(e) => e.key === 'Enter' && goto(`/inventar/items/${item.id}`)}
|
||||
onclick={() => goto(`/inventory/items/${item.id}`)}
|
||||
onkeydown={(e) => e.key === 'Enter' && goto(`/inventory/items/${item.id}`)}
|
||||
role="button"
|
||||
tabindex="0"
|
||||
class="group flex w-full cursor-pointer items-center gap-4 rounded-lg border border-[hsl(var(--border))] bg-[hsl(var(--card))] px-4 py-3 text-left transition-colors hover:border-[hsl(var(--primary)/0.3)]"
|
||||
|
|
@ -3,11 +3,11 @@
|
|||
import { goto } from '$app/navigation';
|
||||
import { CaretLeft } from '@mana/shared-icons';
|
||||
import { getContext } from 'svelte';
|
||||
import { collectionsStore } from '$lib/modules/inventar/stores/collections.svelte';
|
||||
import { getCollectionById } from '$lib/modules/inventar/queries';
|
||||
import type { Collection } from '$lib/modules/inventar/queries';
|
||||
import type { CollectionSchema } from '$lib/modules/inventar/constants';
|
||||
import SchemaEditor from '$lib/modules/inventar/components/fields/SchemaEditor.svelte';
|
||||
import { collectionsStore } from '$lib/modules/inventory/stores/collections.svelte';
|
||||
import { getCollectionById } from '$lib/modules/inventory/queries';
|
||||
import type { Collection } from '$lib/modules/inventory/queries';
|
||||
import type { CollectionSchema } from '$lib/modules/inventory/constants';
|
||||
import SchemaEditor from '$lib/modules/inventory/components/fields/SchemaEditor.svelte';
|
||||
|
||||
const collectionsCtx: { readonly value: Collection[] } = getContext('collections');
|
||||
|
||||
|
|
@ -38,7 +38,7 @@
|
|||
icon: icon || undefined,
|
||||
schema,
|
||||
});
|
||||
goto(`/inventar/collections/${collection.id}`);
|
||||
goto(`/inventory/collections/${collection.id}`);
|
||||
}
|
||||
|
||||
const inputClass =
|
||||
|
|
@ -55,7 +55,7 @@
|
|||
<div class="mx-auto max-w-2xl space-y-6">
|
||||
<div class="flex items-center gap-3">
|
||||
<button
|
||||
onclick={() => goto(`/inventar/collections/${collection.id}`)}
|
||||
onclick={() => goto(`/inventory/collections/${collection.id}`)}
|
||||
class="text-[hsl(var(--muted-foreground))] hover:text-[hsl(var(--foreground))]"
|
||||
>
|
||||
<CaretLeft size={20} />
|
||||
|
|
@ -94,7 +94,7 @@
|
|||
|
||||
<div class="flex justify-end gap-3 pt-4">
|
||||
<button
|
||||
onclick={() => goto(`/inventar/collections/${collection.id}`)}
|
||||
onclick={() => goto(`/inventory/collections/${collection.id}`)}
|
||||
class="rounded-lg border border-[hsl(var(--border))] px-4 py-2 text-sm text-[hsl(var(--foreground))]"
|
||||
>
|
||||
Abbrechen
|
||||
|
|
@ -1,13 +1,13 @@
|
|||
<script lang="ts">
|
||||
import { goto } from '$app/navigation';
|
||||
import { CaretLeft } from '@mana/shared-icons';
|
||||
import { collectionsStore } from '$lib/modules/inventar/stores/collections.svelte';
|
||||
import { collectionsStore } from '$lib/modules/inventory/stores/collections.svelte';
|
||||
import {
|
||||
DEFAULT_TEMPLATES,
|
||||
type Template,
|
||||
type CollectionSchema,
|
||||
} from '$lib/modules/inventar/constants';
|
||||
import SchemaEditor from '$lib/modules/inventar/components/fields/SchemaEditor.svelte';
|
||||
} from '$lib/modules/inventory/constants';
|
||||
import SchemaEditor from '$lib/modules/inventory/components/fields/SchemaEditor.svelte';
|
||||
|
||||
let step = $state<'template' | 'details'>('template');
|
||||
let selectedTemplate = $state<Template | null>(null);
|
||||
|
|
@ -35,7 +35,7 @@
|
|||
schema,
|
||||
templateId: selectedTemplate?.id,
|
||||
});
|
||||
goto('/inventar');
|
||||
goto('/inventory');
|
||||
}
|
||||
|
||||
const inputClass =
|
||||
|
|
@ -50,7 +50,7 @@
|
|||
<div class="flex items-center gap-3">
|
||||
<button
|
||||
onclick={() =>
|
||||
step === 'details' && selectedTemplate ? (step = 'template') : goto('/inventar')}
|
||||
step === 'details' && selectedTemplate ? (step = 'template') : goto('/inventory')}
|
||||
class="text-[hsl(var(--muted-foreground))] hover:text-[hsl(var(--foreground))]"
|
||||
>
|
||||
<CaretLeft size={20} />
|
||||
|
|
@ -127,7 +127,7 @@
|
|||
<!-- Actions -->
|
||||
<div class="flex justify-end gap-3 pt-4">
|
||||
<button
|
||||
onclick={() => goto('/inventar')}
|
||||
onclick={() => goto('/inventory')}
|
||||
class="rounded-lg border border-[hsl(var(--border))] px-4 py-2 text-sm text-[hsl(var(--foreground))]"
|
||||
>
|
||||
Abbrechen
|
||||
|
|
@ -4,24 +4,24 @@
|
|||
import { goto } from '$app/navigation';
|
||||
import { CaretLeft } from '@mana/shared-icons';
|
||||
import { getContext } from 'svelte';
|
||||
import { itemsStore } from '$lib/modules/inventar/stores/items.svelte';
|
||||
import { itemsStore } from '$lib/modules/inventory/stores/items.svelte';
|
||||
import {
|
||||
getItemById,
|
||||
getCollectionById,
|
||||
getLocationById,
|
||||
getLocationFullPath,
|
||||
getCategoryById,
|
||||
} from '$lib/modules/inventar/queries';
|
||||
} from '$lib/modules/inventory/queries';
|
||||
import type {
|
||||
Collection,
|
||||
Item,
|
||||
Location,
|
||||
Category,
|
||||
ItemStatus,
|
||||
} from '$lib/modules/inventar/queries';
|
||||
import FieldRenderer from '$lib/modules/inventar/components/fields/FieldRenderer.svelte';
|
||||
import FieldEditor from '$lib/modules/inventar/components/fields/FieldEditor.svelte';
|
||||
import StatusBadge from '$lib/modules/inventar/components/StatusBadge.svelte';
|
||||
} from '$lib/modules/inventory/queries';
|
||||
import FieldRenderer from '$lib/modules/inventory/components/fields/FieldRenderer.svelte';
|
||||
import FieldEditor from '$lib/modules/inventory/components/fields/FieldEditor.svelte';
|
||||
import StatusBadge from '$lib/modules/inventory/components/StatusBadge.svelte';
|
||||
|
||||
const collectionsCtx: { readonly value: Collection[] } = getContext('collections');
|
||||
const itemsCtx: { readonly value: Item[] } = getContext('items');
|
||||
|
|
@ -90,7 +90,7 @@
|
|||
async function deleteItem() {
|
||||
if (!item || !confirm('Item endgultig loschen?')) return;
|
||||
await itemsStore.delete(item.id);
|
||||
goto(collection ? `/inventar/collections/${collection.id}` : '/inventar');
|
||||
goto(collection ? `/inventory/collections/${collection.id}` : '/inventory');
|
||||
}
|
||||
|
||||
const inputClass =
|
||||
|
|
@ -104,7 +104,7 @@
|
|||
{#if !item}
|
||||
<div class="text-center py-16">
|
||||
<p class="text-[hsl(var(--muted-foreground))]">Item nicht gefunden</p>
|
||||
<a href="/inventar" class="mt-4 text-[hsl(var(--primary))]">Zuruck</a>
|
||||
<a href="/inventory" class="mt-4 text-[hsl(var(--primary))]">Zuruck</a>
|
||||
</div>
|
||||
{:else}
|
||||
<div class="mx-auto max-w-2xl space-y-6">
|
||||
|
|
@ -112,7 +112,8 @@
|
|||
<div class="flex items-center justify-between">
|
||||
<div class="flex items-center gap-3">
|
||||
<button
|
||||
onclick={() => goto(collection ? `/inventar/collections/${collection.id}` : '/inventar')}
|
||||
onclick={() =>
|
||||
goto(collection ? `/inventory/collections/${collection.id}` : '/inventory')}
|
||||
class="text-[hsl(var(--muted-foreground))] hover:text-[hsl(var(--foreground))]"
|
||||
>
|
||||
<CaretLeft size={20} />
|
||||
|
|
@ -1,8 +1,8 @@
|
|||
<script lang="ts">
|
||||
import { getContext } from 'svelte';
|
||||
import { locationsStore } from '$lib/modules/inventar/stores/locations.svelte';
|
||||
import { getLocationTree } from '$lib/modules/inventar/queries';
|
||||
import type { Location } from '$lib/modules/inventar/queries';
|
||||
import { locationsStore } from '$lib/modules/inventory/stores/locations.svelte';
|
||||
import { getLocationTree } from '$lib/modules/inventory/queries';
|
||||
import type { Location } from '$lib/modules/inventory/queries';
|
||||
import { Plus } from '@mana/shared-icons';
|
||||
|
||||
const locationsCtx: { readonly value: Location[] } = getContext('locations');
|
||||
|
|
@ -1,9 +1,9 @@
|
|||
<script lang="ts">
|
||||
import { goto } from '$app/navigation';
|
||||
import { getContext } from 'svelte';
|
||||
import { getFilteredItems, getCollectionById } from '$lib/modules/inventar/queries';
|
||||
import type { Collection, Item } from '$lib/modules/inventar/queries';
|
||||
import StatusBadge from '$lib/modules/inventar/components/StatusBadge.svelte';
|
||||
import { getFilteredItems, getCollectionById } from '$lib/modules/inventory/queries';
|
||||
import type { Collection, Item } from '$lib/modules/inventory/queries';
|
||||
import StatusBadge from '$lib/modules/inventory/components/StatusBadge.svelte';
|
||||
import { MagnifyingGlass } from '@mana/shared-icons';
|
||||
|
||||
const collectionsCtx: { readonly value: Collection[] } = getContext('collections');
|
||||
|
|
@ -41,7 +41,7 @@
|
|||
<div class="space-y-2">
|
||||
{#each results as item (item.id)}
|
||||
<button
|
||||
onclick={() => goto(`/inventar/items/${item.id}`)}
|
||||
onclick={() => goto(`/inventory/items/${item.id}`)}
|
||||
class="flex w-full items-center gap-4 rounded-lg border border-[hsl(var(--border))] bg-[hsl(var(--card))] px-4 py-3 text-left transition-colors hover:border-[hsl(var(--primary)/0.3)]"
|
||||
>
|
||||
<div class="flex-1">
|
||||
|
|
@ -810,7 +810,7 @@ services:
|
|||
# REMOVED standalone web containers — now served by unified mana-web container (mana.how):
|
||||
# chat-web, todo-web, zitare-web, calendar-web, clock-web, contacts-web,
|
||||
# storage-web, presi-web, cards-web, nutriphi-web, skilltree-web, photos-web,
|
||||
# music-web, citycorners-web, picture-web, inventar-web, calc-web, times-web,
|
||||
# music-web, citycorners-web, picture-web, inventory-web, calc-web, times-web,
|
||||
# uload-web, memoro-web
|
||||
|
||||
# picture-backend: REMOVED — replaced by Hono server (apps/picture/apps/server)
|
||||
|
|
|
|||
|
|
@ -242,7 +242,7 @@ scrape_configs:
|
|||
- https://mana.how/notes
|
||||
- https://mana.how/habits
|
||||
- https://mana.how/guides
|
||||
- https://mana.how/inventar
|
||||
- https://mana.how/inventory
|
||||
- https://mana.how/playground
|
||||
# Standalone games (separate containers)
|
||||
- https://whopxl.mana.how
|
||||
|
|
|
|||
|
|
@ -133,7 +133,7 @@ Pure CRUD apps use mana-sync directly.
|
|||
| 5022 | citycorners-web | *(local-first only)* |
|
||||
| 5023 | cards-web | 3036 cards-server |
|
||||
| 5024 | mukke-web | 3037 mukke-server |
|
||||
| 5025 | inventar-web | *(local-first only)* |
|
||||
| 5025 | inventory-web | *(local-first only)* |
|
||||
| 5026 | context-web | *(local-first only)* |
|
||||
| 5027 | questions-web | *(local-first only)* |
|
||||
| 5028 | planta-web | 3039 planta-server |
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@ const apps = [
|
|||
{ name: 'music', url: `${BASE}:5189` },
|
||||
{ name: 'citycorners', url: `${BASE}:5190` },
|
||||
{ name: 'picture', url: `${BASE}:5174` },
|
||||
{ name: 'inventar', url: `${BASE}:5191` },
|
||||
{ name: 'inventory', url: `${BASE}:5191` },
|
||||
];
|
||||
|
||||
// When testing against production, use subdomains
|
||||
|
|
|
|||
|
|
@ -108,8 +108,8 @@
|
|||
"dev:photos:app": "pnpm dev:photos:web",
|
||||
"dev:photos:full": "concurrently -n auth,sync,web -c blue,magenta,cyan \"pnpm dev:auth\" \"pnpm dev:sync\" \"pnpm dev:photos:web\"",
|
||||
"dev:tags-test": "concurrently -n auth,sync,api -c blue,magenta,yellow \"pnpm dev:auth\" \"pnpm dev:sync\" \"pnpm dev:api\"",
|
||||
"inventar:dev": "turbo run dev --filter=inventar...",
|
||||
"dev:inventar:web": "pnpm --filter @inventar/web dev",
|
||||
"inventory:dev": "turbo run dev --filter=inventory...",
|
||||
"dev:inventory:web": "pnpm --filter @inventory/web dev",
|
||||
"times:dev": "turbo run dev --filter=times...",
|
||||
"dev:times:web": "pnpm --filter @times/web dev",
|
||||
"dev:times:full": "concurrently -n auth,sync,web -c blue,magenta,cyan \"pnpm dev:auth\" \"pnpm dev:sync\" \"pnpm dev:times:web\"",
|
||||
|
|
@ -246,7 +246,7 @@
|
|||
"dev:skilltree:local": "concurrently -n sync,web -c magenta,cyan \"pnpm dev:sync\" \"pnpm dev:skilltree:web\"",
|
||||
"dev:photos:local": "concurrently -n sync,web -c magenta,cyan \"pnpm dev:sync\" \"pnpm dev:photos:web\"",
|
||||
"dev:citycorners:local": "concurrently -n sync,web -c magenta,cyan \"pnpm dev:sync\" \"pnpm dev:citycorners:web\"",
|
||||
"dev:inventar:local": "concurrently -n sync,web -c magenta,cyan \"pnpm dev:sync\" \"pnpm dev:inventar:web\"",
|
||||
"dev:inventory:local": "concurrently -n sync,web -c magenta,cyan \"pnpm dev:sync\" \"pnpm dev:inventory:web\"",
|
||||
"dev:times:local": "concurrently -n sync,web -c magenta,cyan \"pnpm dev:sync\" \"pnpm dev:times:web\"",
|
||||
"dev:calc:local": "concurrently -n sync,web -c magenta,cyan \"pnpm dev:sync\" \"pnpm dev:calc:web\"",
|
||||
"dev:manavoxel:local": "concurrently -n sync,web -c magenta,cyan \"pnpm dev:sync\" \"pnpm dev:manavoxel:web\"",
|
||||
|
|
|
|||
|
|
@ -61,7 +61,7 @@
|
|||
music: ['Musik machen, einfach so', 'Quelloffen & unabhängig', 'Privat by Design'],
|
||||
storage: ['Deine Dateien, dein Tresor', 'Quelloffen & unabhängig', 'Privat by Design'],
|
||||
times: ['Zeiterfassung ohne Overhead', 'Quelloffen & unabhängig', 'Privat by Design'],
|
||||
inventar: ['Alles im Überblick behalten', 'Quelloffen & unabhängig', 'Privat by Design'],
|
||||
inventory: ['Alles im Überblick behalten', 'Quelloffen & unabhängig', 'Privat by Design'],
|
||||
uload: ['Links kürzen & verwalten', 'Quelloffen & unabhängig', 'Privat by Design'],
|
||||
news: ['Nachrichten, kuratiert für dich', 'Quelloffen & unabhängig', 'Privat by Design'],
|
||||
arcade: ['Spiele direkt im Browser', 'Quelloffen & unabhängig', 'Privat by Design'],
|
||||
|
|
@ -94,7 +94,7 @@
|
|||
music: ['Make music, just like that', 'Open-source & independent', 'Private by design'],
|
||||
storage: ['Your files, your vault', 'Open-source & independent', 'Private by design'],
|
||||
times: ['Time tracking without overhead', 'Open-source & independent', 'Private by design'],
|
||||
inventar: ['Keep track of everything', 'Open-source & independent', 'Private by design'],
|
||||
inventory: ['Keep track of everything', 'Open-source & independent', 'Private by design'],
|
||||
uload: ['Shorten & manage links', 'Open-source & independent', 'Private by design'],
|
||||
news: ['News, curated for you', 'Open-source & independent', 'Private by design'],
|
||||
arcade: ['Games right in your browser', 'Open-source & independent', 'Private by design'],
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@
|
|||
* }
|
||||
*
|
||||
* export const viewStore = createViewStore<MyViewMode, MyFilters>({
|
||||
* storagePrefix: 'inventar',
|
||||
* storagePrefix: 'inventory',
|
||||
* defaultViewMode: 'list',
|
||||
* defaultSort: { field: 'name', direction: 'asc' },
|
||||
* hasActiveFilters: (f) => !!(f.search || f.status?.length || f.tagIds?.length),
|
||||
|
|
@ -40,7 +40,7 @@ export interface SavedFilter<F> {
|
|||
}
|
||||
|
||||
export interface ViewStoreConfig<V extends string, F extends object> {
|
||||
/** Prefix for localStorage keys (e.g. 'inventar' → 'inventar_view_mode') */
|
||||
/** Prefix for localStorage keys (e.g. 'inventory' → 'inventory_view_mode') */
|
||||
storagePrefix: string;
|
||||
/** Default view mode */
|
||||
defaultViewMode: V;
|
||||
|
|
|
|||
|
|
@ -167,7 +167,7 @@ const track = {
|
|||
memoro: createModuleTracker('memoro'),
|
||||
app: createModuleTracker('app'),
|
||||
calc: createModuleTracker('calc'),
|
||||
inventar: createModuleTracker('inventar'),
|
||||
inventory: createModuleTracker('inventory'),
|
||||
moodlit: createModuleTracker('moodlit'),
|
||||
citycorners: createModuleTracker('citycorners'),
|
||||
};
|
||||
|
|
@ -570,18 +570,18 @@ export const CalcEvents = {
|
|||
};
|
||||
|
||||
/**
|
||||
* Inventar App Events
|
||||
* Inventory App Events
|
||||
*/
|
||||
export const InventarEvents = {
|
||||
itemCreated: () => track.inventar('item_created'),
|
||||
itemUpdated: () => track.inventar('item_updated'),
|
||||
itemDeleted: () => track.inventar('item_deleted'),
|
||||
collectionCreated: () => track.inventar('collection_created'),
|
||||
collectionDeleted: () => track.inventar('collection_deleted'),
|
||||
categoryCreated: () => track.inventar('category_created'),
|
||||
categoryDeleted: () => track.inventar('category_deleted'),
|
||||
locationCreated: () => track.inventar('location_created'),
|
||||
locationDeleted: () => track.inventar('location_deleted'),
|
||||
export const InventoryEvents = {
|
||||
itemCreated: () => track.inventory('item_created'),
|
||||
itemUpdated: () => track.inventory('item_updated'),
|
||||
itemDeleted: () => track.inventory('item_deleted'),
|
||||
collectionCreated: () => track.inventory('collection_created'),
|
||||
collectionDeleted: () => track.inventory('collection_deleted'),
|
||||
categoryCreated: () => track.inventory('category_created'),
|
||||
categoryDeleted: () => track.inventory('category_deleted'),
|
||||
locationCreated: () => track.inventory('location_created'),
|
||||
locationDeleted: () => track.inventory('location_deleted'),
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -190,7 +190,7 @@ export const MANA_APP_INDEX: Record<string, number> = {
|
|||
photos: 12,
|
||||
skilltree: 13,
|
||||
citycorners: 14,
|
||||
inventar: 15,
|
||||
inventory: 15,
|
||||
times: 16,
|
||||
nutriphi: 17,
|
||||
planta: 18,
|
||||
|
|
|
|||
|
|
@ -199,7 +199,6 @@ get_tier_badge() {
|
|||
case "$appid" in
|
||||
mana.how) appid="mana" ;;
|
||||
manadeck) appid="cards" ;;
|
||||
inventar) appid="inventory" ;;
|
||||
esac
|
||||
|
||||
echo "$TIER_APPS" | while IFS='|' read -r id name tier st; do
|
||||
|
|
|
|||
|
|
@ -120,7 +120,7 @@ const PROJECT_META: Record<string, { name: string; icon: string }> = {
|
|||
picture: { name: 'ManaPicture', icon: '🎨' },
|
||||
zitare: { name: 'Zitare', icon: '✨' },
|
||||
presi: { name: 'Presi', icon: '📊' },
|
||||
inventar: { name: 'Inventar', icon: '📦' },
|
||||
inventory: { name: 'Inventar', icon: '📦' },
|
||||
nutriphi: { name: 'Nutriphi', icon: '🥗' },
|
||||
planta: { name: 'Planta', icon: '🌱' },
|
||||
storage: { name: 'Storage', icon: '☁️' },
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue