mirror of
https://github.com/Memo-2023/mana-monorepo.git
synced 2026-05-14 18:41:08 +02:00
feat: add Cmd+K spotlight actions to all 23 apps
Each app's PillNavigation now has spotlightActions with app-specific quick actions (create, navigate, settings). Users can press Cmd+K / Ctrl+K from any app to search apps, navigate, and trigger actions. Apps: todo, calendar, contacts, chat, picture, clock, zitare, cards, storage, manacore, mukke, presi, context, questions, photos, planta, citycorners, guides, calc, moodlit, matrix, uload, arcade Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
075e204b14
commit
4d0e9a6a3f
23 changed files with 602 additions and 27 deletions
|
|
@ -10,6 +10,7 @@
|
|||
PillDropdownItem,
|
||||
CommandBarItem,
|
||||
QuickAction,
|
||||
SpotlightAction,
|
||||
} from '@manacore/shared-ui';
|
||||
import { theme } from '$lib/stores/theme.svelte';
|
||||
import { authStore } from '$lib/stores/auth.svelte';
|
||||
|
|
@ -246,6 +247,27 @@
|
|||
goto('/login');
|
||||
}
|
||||
|
||||
const spotlightActions: SpotlightAction[] = [
|
||||
{
|
||||
id: 'calculator',
|
||||
label: 'Rechner',
|
||||
category: 'Navigation',
|
||||
onExecute: () => goto('/standard'),
|
||||
},
|
||||
{
|
||||
id: 'converter',
|
||||
label: 'Umrechner',
|
||||
category: 'Navigation',
|
||||
onExecute: () => goto('/converter'),
|
||||
},
|
||||
{
|
||||
id: 'settings',
|
||||
label: 'Einstellungen',
|
||||
category: 'Navigation',
|
||||
onExecute: () => goto('/settings'),
|
||||
},
|
||||
];
|
||||
|
||||
async function handleAuthReady() {
|
||||
await Promise.all([calcStore.initialize(), tagLocalStore.initialize()]);
|
||||
|
||||
|
|
@ -316,6 +338,7 @@
|
|||
themesHref="/themes"
|
||||
helpHref="/help"
|
||||
allAppsHref="/apps"
|
||||
{spotlightActions}
|
||||
/>
|
||||
|
||||
{#if isTagStripVisible}
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@
|
|||
QuickInputItem,
|
||||
PillTagSelectorConfig,
|
||||
PillNavElement,
|
||||
SpotlightAction,
|
||||
} from '@manacore/shared-ui';
|
||||
import { theme } from '$lib/stores/theme';
|
||||
import { authStore } from '$lib/stores/auth.svelte';
|
||||
|
|
@ -403,6 +404,31 @@
|
|||
);
|
||||
}
|
||||
|
||||
const spotlightActions: SpotlightAction[] = [
|
||||
{
|
||||
id: 'new-event',
|
||||
label: 'Neues Event',
|
||||
icon: 'plus',
|
||||
shortcut: 'N',
|
||||
category: 'Erstellen',
|
||||
onExecute: () => goto('/new'),
|
||||
},
|
||||
{ id: 'today', label: 'Heute', category: 'Navigation', onExecute: () => goto('/') },
|
||||
{ id: 'week', label: 'Wochenansicht', category: 'Navigation', onExecute: () => goto('/week') },
|
||||
{
|
||||
id: 'month',
|
||||
label: 'Monatsansicht',
|
||||
category: 'Navigation',
|
||||
onExecute: () => goto('/month'),
|
||||
},
|
||||
{
|
||||
id: 'settings',
|
||||
label: 'Einstellungen',
|
||||
category: 'Navigation',
|
||||
onExecute: () => goto('/settings'),
|
||||
},
|
||||
];
|
||||
|
||||
async function handleAuthReady() {
|
||||
// Initialize local-first databases (opens IndexedDB, seeds guest data)
|
||||
await Promise.all([
|
||||
|
|
@ -498,6 +524,7 @@
|
|||
allAppsHref="/apps"
|
||||
onOpenInPanel={handleOpenInPanel}
|
||||
ariaLabel="Hauptnavigation"
|
||||
{spotlightActions}
|
||||
/>
|
||||
{/if}
|
||||
|
||||
|
|
|
|||
|
|
@ -9,7 +9,12 @@
|
|||
import { isNavCollapsed as collapsedStore } from '$lib/stores/navigation';
|
||||
import { PillNavigation, QuickInputBar, TagStrip } from '@manacore/shared-ui';
|
||||
import { SyncIndicator } from '@manacore/shared-ui';
|
||||
import type { PillNavItem, PillDropdownItem, QuickInputItem } from '@manacore/shared-ui';
|
||||
import type {
|
||||
PillNavItem,
|
||||
PillDropdownItem,
|
||||
QuickInputItem,
|
||||
SpotlightAction,
|
||||
} from '@manacore/shared-ui';
|
||||
import {
|
||||
tagLocalStore,
|
||||
tagMutations,
|
||||
|
|
@ -190,6 +195,25 @@
|
|||
goto(`/decks/${item.id}`);
|
||||
}
|
||||
|
||||
const spotlightActions: SpotlightAction[] = [
|
||||
{
|
||||
id: 'new-deck',
|
||||
label: 'Neues Deck',
|
||||
icon: 'plus',
|
||||
shortcut: 'N',
|
||||
category: 'Erstellen',
|
||||
onExecute: () => goto('/new'),
|
||||
},
|
||||
{ id: 'all-decks', label: 'Alle Decks', category: 'Navigation', onExecute: () => goto('/') },
|
||||
{ id: 'study', label: 'Lernen', category: 'Navigation', onExecute: () => goto('/study') },
|
||||
{
|
||||
id: 'settings',
|
||||
label: 'Einstellungen',
|
||||
category: 'Navigation',
|
||||
onExecute: () => goto('/settings'),
|
||||
},
|
||||
];
|
||||
|
||||
async function handleAuthReady() {
|
||||
// Initialize local-first database and shared tag store
|
||||
await Promise.all([cardsStore.initialize(), tagLocalStore.initialize()]);
|
||||
|
|
@ -246,6 +270,7 @@
|
|||
onLogout={handleSignOut}
|
||||
onToggleTheme={handleToggleTheme}
|
||||
{isDark}
|
||||
{spotlightActions}
|
||||
{isCollapsed}
|
||||
onCollapsedChange={handleCollapsedChange}
|
||||
showThemeToggle={true}
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@
|
|||
import { setContext } from 'svelte';
|
||||
import { PillNavigation, TagStrip } from '@manacore/shared-ui';
|
||||
import { SyncIndicator } from '@manacore/shared-ui';
|
||||
import type { PillNavItem, PillDropdownItem } from '@manacore/shared-ui';
|
||||
import type { PillNavItem, PillDropdownItem, SpotlightAction } from '@manacore/shared-ui';
|
||||
import {
|
||||
tagLocalStore,
|
||||
tagMutations,
|
||||
|
|
@ -124,6 +124,30 @@
|
|||
filterHiddenNavItems('chat', baseNavItems, userSettings.nav?.hiddenNavItems || {})
|
||||
);
|
||||
|
||||
// Spotlight actions for PillNavigation
|
||||
const spotlightActions: SpotlightAction[] = [
|
||||
{
|
||||
id: 'new-chat',
|
||||
label: 'Neuer Chat',
|
||||
icon: 'plus',
|
||||
shortcut: 'N',
|
||||
category: 'Erstellen',
|
||||
onExecute: () => goto('/chat'),
|
||||
},
|
||||
{
|
||||
id: 'templates',
|
||||
label: 'Vorlagen',
|
||||
category: 'Navigation',
|
||||
onExecute: () => goto('/templates'),
|
||||
},
|
||||
{
|
||||
id: 'settings',
|
||||
label: 'Einstellungen',
|
||||
category: 'Navigation',
|
||||
onExecute: () => goto('/settings'),
|
||||
},
|
||||
];
|
||||
|
||||
// User email for user dropdown
|
||||
let userEmail = $derived(authStore.user?.email);
|
||||
|
||||
|
|
@ -254,6 +278,7 @@
|
|||
themesHref="/themes"
|
||||
helpHref="/help"
|
||||
allAppsHref="/apps"
|
||||
{spotlightActions}
|
||||
/>
|
||||
|
||||
<!-- TagStrip (above PillNav, toggled via Tags pill) -->
|
||||
|
|
|
|||
|
|
@ -5,7 +5,12 @@
|
|||
import { _, locale } from 'svelte-i18n';
|
||||
import { PillNavigation, QuickInputBar, TagStrip } from '@manacore/shared-ui';
|
||||
import { SyncIndicator } from '@manacore/shared-ui';
|
||||
import type { PillNavItem, PillDropdownItem, QuickInputItem } from '@manacore/shared-ui';
|
||||
import type {
|
||||
PillNavItem,
|
||||
PillDropdownItem,
|
||||
QuickInputItem,
|
||||
SpotlightAction,
|
||||
} from '@manacore/shared-ui';
|
||||
import {
|
||||
tagLocalStore,
|
||||
tagMutations,
|
||||
|
|
@ -207,6 +212,22 @@
|
|||
|
||||
let showGuestWelcome = $state(false);
|
||||
|
||||
const spotlightActions: SpotlightAction[] = [
|
||||
{ id: 'explore', label: 'Entdecken', category: 'Navigation', onExecute: () => goto('/') },
|
||||
{
|
||||
id: 'favorites',
|
||||
label: 'Favoriten',
|
||||
category: 'Navigation',
|
||||
onExecute: () => goto('/favorites'),
|
||||
},
|
||||
{
|
||||
id: 'settings',
|
||||
label: 'Einstellungen',
|
||||
category: 'Navigation',
|
||||
onExecute: () => goto('/settings'),
|
||||
},
|
||||
];
|
||||
|
||||
async function handleAuthReady() {
|
||||
await Promise.all([citycornersStore.initialize(), tagLocalStore.initialize()]);
|
||||
if (authStore.isAuthenticated) {
|
||||
|
|
@ -259,6 +280,7 @@
|
|||
themesHref="/themes"
|
||||
helpHref="/help"
|
||||
profileHref="/profile"
|
||||
{spotlightActions}
|
||||
/>
|
||||
{/if}
|
||||
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@
|
|||
PillDropdownItem,
|
||||
CommandBarItem,
|
||||
QuickAction,
|
||||
SpotlightAction,
|
||||
} from '@manacore/shared-ui';
|
||||
import { theme } from '$lib/stores/theme.svelte';
|
||||
import { authStore } from '$lib/stores/auth.svelte';
|
||||
|
|
@ -184,6 +185,36 @@
|
|||
// User email for user dropdown — empty string for guests so PillNav shows login button
|
||||
let userEmail = $derived(authStore.isAuthenticated ? authStore.user?.email || 'Menü' : '');
|
||||
|
||||
// Spotlight actions for PillNavigation
|
||||
const spotlightActions: SpotlightAction[] = [
|
||||
{
|
||||
id: 'new-alarm',
|
||||
label: 'Neuer Alarm',
|
||||
icon: 'plus',
|
||||
category: 'Erstellen',
|
||||
onExecute: () => goto('/alarms'),
|
||||
},
|
||||
{
|
||||
id: 'new-timer',
|
||||
label: 'Neuer Timer',
|
||||
icon: 'plus',
|
||||
category: 'Erstellen',
|
||||
onExecute: () => goto('/timers'),
|
||||
},
|
||||
{
|
||||
id: 'world-clock',
|
||||
label: 'Weltuhren',
|
||||
category: 'Navigation',
|
||||
onExecute: () => goto('/world-clock'),
|
||||
},
|
||||
{
|
||||
id: 'settings',
|
||||
label: 'Einstellungen',
|
||||
category: 'Navigation',
|
||||
onExecute: () => goto('/settings'),
|
||||
},
|
||||
];
|
||||
|
||||
// TagStrip visibility
|
||||
let isTagStripVisible = $state(false);
|
||||
function handleTagStripToggle() {
|
||||
|
|
@ -340,6 +371,7 @@
|
|||
themesHref="/themes"
|
||||
helpHref="/help"
|
||||
allAppsHref="/apps"
|
||||
{spotlightActions}
|
||||
/>
|
||||
|
||||
<!-- TagStrip (above PillNav, toggled via Tags pill) -->
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@
|
|||
PillDropdownItem,
|
||||
QuickInputItem,
|
||||
CreatePreview,
|
||||
SpotlightAction,
|
||||
} from '@manacore/shared-ui';
|
||||
import { theme } from '$lib/stores/theme';
|
||||
import { authStore } from '$lib/stores/auth.svelte';
|
||||
|
|
@ -305,6 +306,30 @@
|
|||
previousOnboardingShow = showing;
|
||||
});
|
||||
|
||||
const spotlightActions: SpotlightAction[] = [
|
||||
{
|
||||
id: 'new-contact',
|
||||
label: 'Neuer Kontakt',
|
||||
icon: 'plus',
|
||||
shortcut: 'N',
|
||||
category: 'Erstellen',
|
||||
onExecute: () => goto('/new'),
|
||||
},
|
||||
{ id: 'all', label: 'Alle Kontakte', category: 'Navigation', onExecute: () => goto('/') },
|
||||
{
|
||||
id: 'favorites',
|
||||
label: 'Favoriten',
|
||||
category: 'Navigation',
|
||||
onExecute: () => goto('/favorites'),
|
||||
},
|
||||
{
|
||||
id: 'settings',
|
||||
label: 'Einstellungen',
|
||||
category: 'Navigation',
|
||||
onExecute: () => goto('/settings'),
|
||||
},
|
||||
];
|
||||
|
||||
async function handleAuthReady() {
|
||||
// Initialize local-first databases (opens IndexedDB, seeds guest data)
|
||||
await Promise.all([
|
||||
|
|
@ -394,6 +419,7 @@
|
|||
allAppsHref="/apps"
|
||||
onOpenInPanel={handleOpenInPanel}
|
||||
ariaLabel="Hauptnavigation"
|
||||
{spotlightActions}
|
||||
/>
|
||||
|
||||
<!-- TagStrip (above PillNav, toggled via Tags pill) -->
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@
|
|||
PillDropdownItem,
|
||||
CommandBarItem,
|
||||
QuickAction,
|
||||
SpotlightAction,
|
||||
} from '@manacore/shared-ui';
|
||||
import { theme } from '$lib/stores/theme.svelte';
|
||||
import { authStore } from '$lib/stores/auth.svelte';
|
||||
|
|
@ -180,6 +181,24 @@
|
|||
filterHiddenNavItems('context', baseNavItems, userSettings.nav?.hiddenNavItems || {})
|
||||
);
|
||||
|
||||
const spotlightActions: SpotlightAction[] = [
|
||||
{
|
||||
id: 'new-space',
|
||||
label: 'Neuer Space',
|
||||
icon: 'plus',
|
||||
shortcut: 'N',
|
||||
category: 'Erstellen',
|
||||
onExecute: () => goto('/new'),
|
||||
},
|
||||
{ id: 'all-spaces', label: 'Alle Spaces', category: 'Navigation', onExecute: () => goto('/') },
|
||||
{
|
||||
id: 'settings',
|
||||
label: 'Einstellungen',
|
||||
category: 'Navigation',
|
||||
onExecute: () => goto('/settings'),
|
||||
},
|
||||
];
|
||||
|
||||
const navRoutes = baseNavItems.map((item) => item.href);
|
||||
|
||||
function handleKeydown(event: KeyboardEvent) {
|
||||
|
|
@ -295,6 +314,7 @@
|
|||
themesHref="/themes"
|
||||
helpHref="/help"
|
||||
allAppsHref="/apps"
|
||||
{spotlightActions}
|
||||
/>
|
||||
|
||||
<!-- TagStrip (above PillNav, toggled via Tags pill) -->
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@
|
|||
import { onMount, setContext } from 'svelte';
|
||||
import { PillNavigation } from '@manacore/shared-ui';
|
||||
import { SyncIndicator } from '@manacore/shared-ui';
|
||||
import type { PillNavItem, PillDropdownItem } from '@manacore/shared-ui';
|
||||
import type { PillNavItem, PillDropdownItem, SpotlightAction } from '@manacore/shared-ui';
|
||||
import { theme } from '$lib/stores/theme';
|
||||
import { authStore } from '$lib/stores/auth.svelte';
|
||||
import { guidesStore } from '$lib/stores/guides.svelte';
|
||||
|
|
@ -28,8 +28,12 @@
|
|||
// Context for child pages
|
||||
let showCreateModal = $state(false);
|
||||
let showImportModal = $state(false);
|
||||
setContext('openCreateGuide', () => { showCreateModal = true; });
|
||||
setContext('openImportGuide', () => { showImportModal = true; });
|
||||
setContext('openCreateGuide', () => {
|
||||
showCreateModal = true;
|
||||
});
|
||||
setContext('openImportGuide', () => {
|
||||
showImportModal = true;
|
||||
});
|
||||
|
||||
// App switcher
|
||||
let appItems = $derived(getPillAppItems('guides', undefined, undefined, authStore.user?.tier));
|
||||
|
|
@ -96,13 +100,43 @@
|
|||
function handleCollapsedChange(collapsed: boolean) {
|
||||
isCollapsed = collapsed;
|
||||
}
|
||||
function handleToggleTheme() { theme.toggleMode(); }
|
||||
function handleThemeModeChange(mode: 'light' | 'dark' | 'system') { theme.setMode(mode); }
|
||||
function handleToggleTheme() {
|
||||
theme.toggleMode();
|
||||
}
|
||||
function handleThemeModeChange(mode: 'light' | 'dark' | 'system') {
|
||||
theme.setMode(mode);
|
||||
}
|
||||
async function handleLogout() {
|
||||
await authStore.signOut();
|
||||
goto('/login');
|
||||
}
|
||||
|
||||
const spotlightActions: SpotlightAction[] = [
|
||||
{
|
||||
id: 'new-guide',
|
||||
label: 'Neuer Guide',
|
||||
icon: 'plus',
|
||||
shortcut: 'N',
|
||||
category: 'Erstellen',
|
||||
onExecute: () => {
|
||||
showCreateModal = true;
|
||||
},
|
||||
},
|
||||
{ id: 'all-guides', label: 'Alle Guides', category: 'Navigation', onExecute: () => goto('/') },
|
||||
{
|
||||
id: 'collections',
|
||||
label: 'Sammlungen',
|
||||
category: 'Navigation',
|
||||
onExecute: () => goto('/collections'),
|
||||
},
|
||||
{
|
||||
id: 'settings',
|
||||
label: 'Einstellungen',
|
||||
category: 'Navigation',
|
||||
onExecute: () => goto('/settings'),
|
||||
},
|
||||
];
|
||||
|
||||
async function handleAuthReady() {
|
||||
await dbStore.initialize();
|
||||
if (authStore.isAuthenticated) {
|
||||
|
|
@ -114,15 +148,17 @@
|
|||
}
|
||||
</script>
|
||||
|
||||
<svelte:window onkeydown={(e) => {
|
||||
if ((e.ctrlKey || e.metaKey) && !e.shiftKey && !e.altKey) {
|
||||
const num = parseInt(e.key);
|
||||
if (num >= 1 && num <= baseNavItems.length) {
|
||||
e.preventDefault();
|
||||
goto(baseNavItems[num - 1].href);
|
||||
<svelte:window
|
||||
onkeydown={(e) => {
|
||||
if ((e.ctrlKey || e.metaKey) && !e.shiftKey && !e.altKey) {
|
||||
const num = parseInt(e.key);
|
||||
if (num >= 1 && num <= baseNavItems.length) {
|
||||
e.preventDefault();
|
||||
goto(baseNavItems[num - 1].href);
|
||||
}
|
||||
}
|
||||
}
|
||||
}} />
|
||||
}}
|
||||
/>
|
||||
|
||||
<AuthGate
|
||||
{authStore}
|
||||
|
|
@ -158,6 +194,7 @@
|
|||
showAppSwitcher={true}
|
||||
{appItems}
|
||||
{userEmail}
|
||||
{spotlightActions}
|
||||
/>
|
||||
|
||||
<main class="relative z-0 pb-24" style="padding-top: 0">
|
||||
|
|
@ -173,7 +210,11 @@
|
|||
class="fixed bottom-20 right-4 z-50 flex h-14 w-14 items-center justify-center rounded-full bg-primary text-white shadow-lg transition-transform hover:scale-105 active:scale-95"
|
||||
aria-label="Neue Anleitung erstellen"
|
||||
>
|
||||
<svg width="24" height="24" viewBox="0 0 256 256" fill="currentColor"><path d="M228 128a12 12 0 0 1-12 12h-76v76a12 12 0 0 1-24 0v-76H40a12 12 0 0 1 0-24h76V40a12 12 0 0 1 24 0v76h76a12 12 0 0 1 12 12Z"/></svg>
|
||||
<svg width="24" height="24" viewBox="0 0 256 256" fill="currentColor"
|
||||
><path
|
||||
d="M228 128a12 12 0 0 1-12 12h-76v76a12 12 0 0 1-24 0v-76H40a12 12 0 0 1 0-24h76V40a12 12 0 0 1 24 0v76h76a12 12 0 0 1 12 12Z"
|
||||
/></svg
|
||||
>
|
||||
</button>
|
||||
|
||||
<!-- Guest Welcome -->
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@
|
|||
import SessionWarning from '$lib/components/SessionWarning.svelte';
|
||||
import { locale } from 'svelte-i18n';
|
||||
import { PillNavigation, TagStrip } from '@manacore/shared-ui';
|
||||
import type { PillNavItem, PillDropdownItem } from '@manacore/shared-ui';
|
||||
import type { PillNavItem, PillDropdownItem, SpotlightAction } from '@manacore/shared-ui';
|
||||
import { tagLocalStore, tagMutations, useAllTags } from '$lib/stores/tags.svelte';
|
||||
import { linkLocalStore, linkMutations } from '@manacore/shared-links';
|
||||
import { manacoreStore } from '$lib/data/local-store';
|
||||
|
|
@ -266,6 +266,24 @@
|
|||
|
||||
loading = false;
|
||||
});
|
||||
|
||||
const spotlightActions: SpotlightAction[] = [
|
||||
{ id: 'home', label: 'Home', category: 'Navigation', onExecute: () => goto('/home') },
|
||||
{
|
||||
id: 'dashboard',
|
||||
label: 'Dashboard',
|
||||
category: 'Navigation',
|
||||
onExecute: () => goto('/dashboard'),
|
||||
},
|
||||
{ id: 'credits', label: 'Credits', category: 'Navigation', onExecute: () => goto('/credits') },
|
||||
{ id: 'apps', label: 'Alle Apps', category: 'Navigation', onExecute: () => goto('/apps') },
|
||||
{
|
||||
id: 'settings',
|
||||
label: 'Einstellungen',
|
||||
category: 'Navigation',
|
||||
onExecute: () => goto('/settings'),
|
||||
},
|
||||
];
|
||||
</script>
|
||||
|
||||
<svelte:window onkeydown={handleKeydown} />
|
||||
|
|
@ -321,6 +339,7 @@
|
|||
themesHref="/themes"
|
||||
helpHref="/help"
|
||||
allAppsHref="/apps"
|
||||
{spotlightActions}
|
||||
/>
|
||||
|
||||
<!-- TagStrip (above PillNav, toggled via Tags pill) -->
|
||||
|
|
|
|||
|
|
@ -21,7 +21,12 @@
|
|||
import type { ThemeVariant } from '@manacore/shared-theme';
|
||||
import { isNavCollapsed as collapsedStore } from '$lib/stores/navigation.svelte';
|
||||
import { PillNavigation, TagStrip } from '@manacore/shared-ui';
|
||||
import type { PillNavItem, PillDropdownItem, QuickInputItem } from '@manacore/shared-ui';
|
||||
import type {
|
||||
PillNavItem,
|
||||
PillDropdownItem,
|
||||
QuickInputItem,
|
||||
SpotlightAction,
|
||||
} from '@manacore/shared-ui';
|
||||
import { tagStore } from '$lib/stores/tags.svelte';
|
||||
import { MagnifyingGlass, X } from '@manacore/shared-icons';
|
||||
import { getPillAppItems } from '@manacore/shared-branding';
|
||||
|
|
@ -131,6 +136,16 @@
|
|||
isTagStripVisible = !isTagStripVisible;
|
||||
}
|
||||
|
||||
const spotlightActions: SpotlightAction[] = [
|
||||
{ id: 'rooms', label: 'Räume', category: 'Navigation', onExecute: () => goto('/') },
|
||||
{
|
||||
id: 'settings',
|
||||
label: 'Einstellungen',
|
||||
category: 'Navigation',
|
||||
onExecute: () => goto('/settings'),
|
||||
},
|
||||
];
|
||||
|
||||
// Navigation items for Matrix
|
||||
const navItems: PillNavItem[] = [
|
||||
{ href: '/chat', label: 'Chat', icon: 'home' },
|
||||
|
|
@ -436,6 +451,7 @@
|
|||
settingsHref="/settings"
|
||||
helpHref="/help"
|
||||
allAppsHref="https://mana.how"
|
||||
{spotlightActions}
|
||||
/>
|
||||
{/if}
|
||||
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
import { goto } from '$app/navigation';
|
||||
import { page } from '$app/stores';
|
||||
import { PillNavigation } from '@manacore/shared-ui';
|
||||
import type { PillNavItem } from '@manacore/shared-ui';
|
||||
import type { PillNavItem, SpotlightAction } from '@manacore/shared-ui';
|
||||
import { getPillAppItems, getManaApp } from '@manacore/shared-branding';
|
||||
import { AuthGate, GuestWelcomeModal, SessionExpiredBanner } from '@manacore/shared-auth-ui';
|
||||
import { shouldShowGuestWelcome } from '@manacore/shared-auth-ui';
|
||||
|
|
@ -37,6 +37,22 @@
|
|||
goto('/auth/login');
|
||||
}
|
||||
|
||||
const spotlightActions: SpotlightAction[] = [
|
||||
{ id: 'scenes', label: 'Szenen', category: 'Navigation', onExecute: () => goto('/moods') },
|
||||
{
|
||||
id: 'sequences',
|
||||
label: 'Sequences',
|
||||
category: 'Navigation',
|
||||
onExecute: () => goto('/sequences'),
|
||||
},
|
||||
{
|
||||
id: 'settings',
|
||||
label: 'Einstellungen',
|
||||
category: 'Navigation',
|
||||
onExecute: () => goto('/settings'),
|
||||
},
|
||||
];
|
||||
|
||||
function handleAuthReady() {
|
||||
if (authStore.isAuthenticated) moodlitStore.startSync(() => authStore.getValidToken());
|
||||
if (!authStore.isAuthenticated && shouldShowGuestWelcome('moodlit')) showGuestWelcome = true;
|
||||
|
|
@ -69,6 +85,7 @@
|
|||
showAppSwitcher={true}
|
||||
{appItems}
|
||||
{userEmail}
|
||||
{spotlightActions}
|
||||
>
|
||||
{#snippet logo()}
|
||||
<span class="text-xl">🌈</span>
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@
|
|||
PillDropdownItem,
|
||||
QuickInputItem,
|
||||
CreatePreview,
|
||||
SpotlightAction,
|
||||
} from '@manacore/shared-ui';
|
||||
import {
|
||||
SplitPaneContainer,
|
||||
|
|
@ -194,6 +195,36 @@
|
|||
goto('/projects');
|
||||
}
|
||||
|
||||
const spotlightActions: SpotlightAction[] = [
|
||||
{
|
||||
id: 'new-project',
|
||||
label: 'Neues Projekt',
|
||||
icon: 'plus',
|
||||
shortcut: 'N',
|
||||
category: 'Erstellen',
|
||||
onExecute: () => goto('/projects/new'),
|
||||
},
|
||||
{ id: 'songs', label: 'Songs', category: 'Navigation', onExecute: () => goto('/') },
|
||||
{
|
||||
id: 'playlists',
|
||||
label: 'Playlists',
|
||||
category: 'Navigation',
|
||||
onExecute: () => goto('/playlists'),
|
||||
},
|
||||
{
|
||||
id: 'projects',
|
||||
label: 'Projekte',
|
||||
category: 'Navigation',
|
||||
onExecute: () => goto('/projects'),
|
||||
},
|
||||
{
|
||||
id: 'settings',
|
||||
label: 'Einstellungen',
|
||||
category: 'Navigation',
|
||||
onExecute: () => goto('/settings'),
|
||||
},
|
||||
];
|
||||
|
||||
let showGuestWelcome = $state(false);
|
||||
|
||||
async function handleAuthReady() {
|
||||
|
|
@ -248,6 +279,7 @@
|
|||
profileHref="/profile"
|
||||
onOpenInPanel={handleOpenInPanel}
|
||||
ariaLabel="Main navigation"
|
||||
{spotlightActions}
|
||||
/>
|
||||
|
||||
<!-- TagStrip (above PillNav, toggled via Tags pill) -->
|
||||
|
|
|
|||
|
|
@ -4,7 +4,12 @@
|
|||
import { _, locale } from 'svelte-i18n';
|
||||
import { PillNavigation, QuickInputBar, TagStrip } from '@manacore/shared-ui';
|
||||
import { SyncIndicator } from '@manacore/shared-ui';
|
||||
import type { PillNavItem, PillDropdownItem, QuickInputItem } from '@manacore/shared-ui';
|
||||
import type {
|
||||
PillNavItem,
|
||||
PillDropdownItem,
|
||||
QuickInputItem,
|
||||
SpotlightAction,
|
||||
} from '@manacore/shared-ui';
|
||||
import { theme } from '$lib/stores/theme';
|
||||
import { authStore } from '$lib/stores/auth.svelte';
|
||||
import { photoStore } from '$lib/stores/photos.svelte';
|
||||
|
|
@ -58,6 +63,23 @@
|
|||
selectedTagIds = [];
|
||||
}
|
||||
|
||||
const spotlightActions: SpotlightAction[] = [
|
||||
{ id: 'all-photos', label: 'Alle Fotos', category: 'Navigation', onExecute: () => goto('/') },
|
||||
{ id: 'albums', label: 'Alben', category: 'Navigation', onExecute: () => goto('/albums') },
|
||||
{
|
||||
id: 'favorites',
|
||||
label: 'Favoriten',
|
||||
category: 'Navigation',
|
||||
onExecute: () => goto('/favorites'),
|
||||
},
|
||||
{
|
||||
id: 'settings',
|
||||
label: 'Einstellungen',
|
||||
category: 'Navigation',
|
||||
onExecute: () => goto('/settings'),
|
||||
},
|
||||
];
|
||||
|
||||
// Navigation items
|
||||
const navItems: PillNavItem[] = [
|
||||
{ href: '/', label: $_('nav.gallery'), icon: 'image' },
|
||||
|
|
@ -164,6 +186,7 @@
|
|||
themesHref="/themes"
|
||||
helpHref="/help"
|
||||
profileHref="/profile"
|
||||
{spotlightActions}
|
||||
/>
|
||||
|
||||
<!-- TagStrip (toggled via Tags pill) -->
|
||||
|
|
|
|||
|
|
@ -5,7 +5,12 @@
|
|||
import { page } from '$app/stores';
|
||||
import { locale } from 'svelte-i18n';
|
||||
import { PillNavigation, TagStrip } from '@manacore/shared-ui';
|
||||
import type { PillNavItem, PillNavElement, PillDropdownItem } from '@manacore/shared-ui';
|
||||
import type {
|
||||
PillNavItem,
|
||||
PillNavElement,
|
||||
PillDropdownItem,
|
||||
SpotlightAction,
|
||||
} from '@manacore/shared-ui';
|
||||
import {
|
||||
THEME_DEFINITIONS,
|
||||
DEFAULT_THEME_VARIANTS,
|
||||
|
|
@ -218,6 +223,31 @@
|
|||
);
|
||||
let currentLanguageLabel = $derived(getCurrentLanguageLabel(currentLocale));
|
||||
|
||||
// Spotlight actions for PillNavigation
|
||||
const spotlightActions: SpotlightAction[] = [
|
||||
{
|
||||
id: 'new-image',
|
||||
label: 'Neues Bild generieren',
|
||||
icon: 'plus',
|
||||
shortcut: 'N',
|
||||
category: 'Erstellen',
|
||||
onExecute: () => goto('/app/generate'),
|
||||
},
|
||||
{
|
||||
id: 'gallery',
|
||||
label: 'Galerie',
|
||||
category: 'Navigation',
|
||||
onExecute: () => goto('/app/gallery'),
|
||||
},
|
||||
{ id: 'boards', label: 'Boards', category: 'Navigation', onExecute: () => goto('/app/board') },
|
||||
{
|
||||
id: 'settings',
|
||||
label: 'Einstellungen',
|
||||
category: 'Navigation',
|
||||
onExecute: () => goto('/app/settings'),
|
||||
},
|
||||
];
|
||||
|
||||
// User email for user dropdown — empty string for guests so PillNav shows login button
|
||||
let userEmail = $derived(authStore.isAuthenticated ? authStore.user?.email || 'Menü' : '');
|
||||
|
||||
|
|
@ -346,6 +376,7 @@
|
|||
helpHref="/app/help"
|
||||
feedbackHref="/app/feedback"
|
||||
allAppsHref="/app/apps"
|
||||
{spotlightActions}
|
||||
/>
|
||||
<!-- TagStrip (toggled via Tags pill) -->
|
||||
{#if isTagStripVisible}
|
||||
|
|
|
|||
|
|
@ -3,7 +3,12 @@
|
|||
import { page } from '$app/stores';
|
||||
import { PillNavigation, QuickInputBar, TagStrip } from '@manacore/shared-ui';
|
||||
import { SyncIndicator } from '@manacore/shared-ui';
|
||||
import type { PillNavItem, QuickInputItem, CreatePreview } from '@manacore/shared-ui';
|
||||
import type {
|
||||
PillNavItem,
|
||||
QuickInputItem,
|
||||
CreatePreview,
|
||||
SpotlightAction,
|
||||
} from '@manacore/shared-ui';
|
||||
import {
|
||||
tagLocalStore,
|
||||
tagMutations,
|
||||
|
|
@ -126,6 +131,29 @@
|
|||
}
|
||||
}
|
||||
|
||||
const spotlightActions: SpotlightAction[] = [
|
||||
{
|
||||
id: 'new-plant',
|
||||
label: 'Neue Pflanze',
|
||||
icon: 'plus',
|
||||
shortcut: 'N',
|
||||
category: 'Erstellen',
|
||||
onExecute: () => goto('/add'),
|
||||
},
|
||||
{
|
||||
id: 'all-plants',
|
||||
label: 'Alle Pflanzen',
|
||||
category: 'Navigation',
|
||||
onExecute: () => goto('/dashboard'),
|
||||
},
|
||||
{
|
||||
id: 'settings',
|
||||
label: 'Einstellungen',
|
||||
category: 'Navigation',
|
||||
onExecute: () => goto('/settings'),
|
||||
},
|
||||
];
|
||||
|
||||
async function handleAuthReady() {
|
||||
await Promise.all([plantaStore.initialize(), tagLocalStore.initialize()]);
|
||||
if (authStore.isAuthenticated) {
|
||||
|
|
@ -156,6 +184,7 @@
|
|||
themesHref="/themes"
|
||||
helpHref="/help"
|
||||
profileHref="/profile"
|
||||
{spotlightActions}
|
||||
/>
|
||||
|
||||
<!-- TagStrip (above PillNav, toggled via Tags pill) -->
|
||||
|
|
|
|||
|
|
@ -5,7 +5,12 @@
|
|||
import { locale } from 'svelte-i18n';
|
||||
import { PillNavigation, QuickInputBar, TagStrip } from '@manacore/shared-ui';
|
||||
import { SyncIndicator } from '@manacore/shared-ui';
|
||||
import type { PillNavItem, PillDropdownItem, QuickInputItem } from '@manacore/shared-ui';
|
||||
import type {
|
||||
PillNavItem,
|
||||
PillDropdownItem,
|
||||
QuickInputItem,
|
||||
SpotlightAction,
|
||||
} from '@manacore/shared-ui';
|
||||
import {
|
||||
tagLocalStore,
|
||||
tagMutations,
|
||||
|
|
@ -156,6 +161,29 @@
|
|||
goto(`/deck/${item.id}`);
|
||||
}
|
||||
|
||||
const spotlightActions: SpotlightAction[] = [
|
||||
{
|
||||
id: 'new-deck',
|
||||
label: 'Neue Präsentation',
|
||||
icon: 'plus',
|
||||
shortcut: 'N',
|
||||
category: 'Erstellen',
|
||||
onExecute: () => goto('/new'),
|
||||
},
|
||||
{
|
||||
id: 'all-decks',
|
||||
label: 'Alle Präsentationen',
|
||||
category: 'Navigation',
|
||||
onExecute: () => goto('/'),
|
||||
},
|
||||
{
|
||||
id: 'settings',
|
||||
label: 'Einstellungen',
|
||||
category: 'Navigation',
|
||||
onExecute: () => goto('/settings'),
|
||||
},
|
||||
];
|
||||
|
||||
async function handleAuthReady() {
|
||||
// Initialize local-first databases (opens IndexedDB, seeds guest data)
|
||||
await Promise.all([presiStore.initialize(), tagLocalStore.initialize()]);
|
||||
|
|
@ -242,6 +270,7 @@
|
|||
themesHref="/themes"
|
||||
helpHref="/help"
|
||||
allAppsHref="/apps"
|
||||
{spotlightActions}
|
||||
/>
|
||||
|
||||
<!-- TagStrip (above PillNav, toggled via Tags pill) -->
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@
|
|||
PillDropdownItem,
|
||||
QuickInputItem,
|
||||
CreatePreview,
|
||||
SpotlightAction,
|
||||
} from '@manacore/shared-ui';
|
||||
import { getPillAppItems, getManaApp } from '@manacore/shared-branding';
|
||||
import {
|
||||
|
|
@ -172,6 +173,29 @@
|
|||
isTagStripVisible = !isTagStripVisible;
|
||||
}
|
||||
|
||||
const spotlightActions: SpotlightAction[] = [
|
||||
{
|
||||
id: 'new-question',
|
||||
label: 'Neue Frage',
|
||||
icon: 'plus',
|
||||
shortcut: 'N',
|
||||
category: 'Erstellen',
|
||||
onExecute: () => goto('/'),
|
||||
},
|
||||
{
|
||||
id: 'collections',
|
||||
label: 'Sammlungen',
|
||||
category: 'Navigation',
|
||||
onExecute: () => goto('/collections'),
|
||||
},
|
||||
{
|
||||
id: 'settings',
|
||||
label: 'Einstellungen',
|
||||
category: 'Navigation',
|
||||
onExecute: () => goto('/settings'),
|
||||
},
|
||||
];
|
||||
|
||||
// Navigation items
|
||||
let navItems = $derived<PillNavItem[]>([
|
||||
{ href: '/', label: 'Questions', icon: 'help-circle' },
|
||||
|
|
@ -235,6 +259,7 @@
|
|||
themesHref="/themes"
|
||||
helpHref="/help"
|
||||
profileHref="/profile"
|
||||
{spotlightActions}
|
||||
/>
|
||||
|
||||
<!-- Quick Input Bar -->
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@
|
|||
import { locale } from 'svelte-i18n';
|
||||
import { PillNavigation, setupGlobalErrorHandler, TagStrip } from '@manacore/shared-ui';
|
||||
import { SyncIndicator } from '@manacore/shared-ui';
|
||||
import type { PillNavItem, PillDropdownItem } from '@manacore/shared-ui';
|
||||
import type { PillNavItem, PillDropdownItem, SpotlightAction } from '@manacore/shared-ui';
|
||||
import { theme } from '$lib/stores/theme.svelte';
|
||||
import { authStore } from '$lib/stores/auth.svelte';
|
||||
import { userSettings } from '$lib/stores/user-settings.svelte';
|
||||
|
|
@ -174,6 +174,24 @@
|
|||
goto('/login');
|
||||
}
|
||||
|
||||
const spotlightActions: SpotlightAction[] = [
|
||||
{
|
||||
id: 'upload',
|
||||
label: 'Datei hochladen',
|
||||
icon: 'plus',
|
||||
shortcut: 'U',
|
||||
category: 'Aktionen',
|
||||
onExecute: () => goto('/'),
|
||||
},
|
||||
{ id: 'all-files', label: 'Alle Dateien', category: 'Navigation', onExecute: () => goto('/') },
|
||||
{
|
||||
id: 'settings',
|
||||
label: 'Einstellungen',
|
||||
category: 'Navigation',
|
||||
onExecute: () => goto('/settings'),
|
||||
},
|
||||
];
|
||||
|
||||
async function handleAuthReady() {
|
||||
// Initialize local-first databases
|
||||
await Promise.all([storageStore.initialize(), tagLocalStore.initialize()]);
|
||||
|
|
@ -237,6 +255,7 @@
|
|||
homeRoute="/files"
|
||||
onToggleTheme={handleToggleTheme}
|
||||
{isDark}
|
||||
{spotlightActions}
|
||||
{isCollapsed}
|
||||
onCollapsedChange={handleCollapsedChange}
|
||||
showThemeToggle={true}
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@
|
|||
PillNavElement,
|
||||
QuickInputItem,
|
||||
CreatePreview,
|
||||
SpotlightAction,
|
||||
} from '@manacore/shared-ui';
|
||||
import { authStore } from '$lib/stores/auth.svelte';
|
||||
import { userSettings } from '$lib/stores/user-settings.svelte';
|
||||
|
|
@ -314,6 +315,36 @@
|
|||
goto('/login');
|
||||
}
|
||||
|
||||
const spotlightActions: SpotlightAction[] = [
|
||||
{
|
||||
id: 'new-task',
|
||||
label: 'Neue Aufgabe',
|
||||
icon: 'plus',
|
||||
shortcut: 'N',
|
||||
category: 'Erstellen',
|
||||
onExecute: () => goto('/'),
|
||||
},
|
||||
{ id: 'today', label: 'Heute', category: 'Navigation', onExecute: () => goto('/today') },
|
||||
{
|
||||
id: 'upcoming',
|
||||
label: 'Demnächst',
|
||||
category: 'Navigation',
|
||||
onExecute: () => goto('/upcoming'),
|
||||
},
|
||||
{
|
||||
id: 'kanban',
|
||||
label: 'Kanban Board',
|
||||
category: 'Navigation',
|
||||
onExecute: () => goto('/kanban'),
|
||||
},
|
||||
{
|
||||
id: 'settings',
|
||||
label: 'Einstellungen',
|
||||
category: 'Navigation',
|
||||
onExecute: () => goto('/settings'),
|
||||
},
|
||||
];
|
||||
|
||||
async function handleAuthReady() {
|
||||
// Initialize local-first databases (opens IndexedDB, seeds guest data)
|
||||
await Promise.all([
|
||||
|
|
@ -418,6 +449,7 @@
|
|||
helpHref="/help"
|
||||
onOpenInPanel={handleOpenInPanel}
|
||||
ariaLabel="Hauptnavigation"
|
||||
{spotlightActions}
|
||||
/>
|
||||
|
||||
<!-- Unified filter strip (tags + priorities + sort, toggled via Filter pill) -->
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
import { page } from '$app/stores';
|
||||
import { onMount } from 'svelte';
|
||||
import { PillNavigation } from '@manacore/shared-ui';
|
||||
import type { PillNavItem } from '@manacore/shared-ui';
|
||||
import type { PillNavItem, SpotlightAction } from '@manacore/shared-ui';
|
||||
import { getPillAppItems, getManaApp } from '@manacore/shared-branding';
|
||||
import { AuthGate, GuestWelcomeModal, SessionExpiredBanner } from '@manacore/shared-auth-ui';
|
||||
import { shouldShowGuestWelcome } from '@manacore/shared-auth-ui';
|
||||
|
|
@ -23,6 +23,24 @@
|
|||
{ href: '/settings', label: 'Settings', icon: 'settings' },
|
||||
];
|
||||
|
||||
const spotlightActions: SpotlightAction[] = [
|
||||
{
|
||||
id: 'new-link',
|
||||
label: 'Neuer Link',
|
||||
icon: 'plus',
|
||||
shortcut: 'N',
|
||||
category: 'Erstellen',
|
||||
onExecute: () => goto('/'),
|
||||
},
|
||||
{ id: 'all-links', label: 'Alle Links', category: 'Navigation', onExecute: () => goto('/') },
|
||||
{
|
||||
id: 'settings',
|
||||
label: 'Einstellungen',
|
||||
category: 'Navigation',
|
||||
onExecute: () => goto('/settings'),
|
||||
},
|
||||
];
|
||||
|
||||
let isSidebarMode = $state(false);
|
||||
let isCollapsed = $state(false);
|
||||
let isDark = $state(false);
|
||||
|
|
@ -118,6 +136,7 @@
|
|||
{appItems}
|
||||
{userEmail}
|
||||
settingsHref="/settings"
|
||||
{spotlightActions}
|
||||
>
|
||||
{#snippet logo()}
|
||||
<span class="text-xl">🔗</span>
|
||||
|
|
|
|||
|
|
@ -8,7 +8,12 @@
|
|||
ImmersiveModeToggle,
|
||||
TagStrip,
|
||||
} from '@manacore/shared-ui';
|
||||
import type { PillNavItem, PillDropdownItem, QuickInputItem } from '@manacore/shared-ui';
|
||||
import type {
|
||||
PillNavItem,
|
||||
PillDropdownItem,
|
||||
QuickInputItem,
|
||||
SpotlightAction,
|
||||
} from '@manacore/shared-ui';
|
||||
import { SyncIndicator } from '@manacore/shared-ui';
|
||||
import {
|
||||
tagLocalStore,
|
||||
|
|
@ -247,6 +252,23 @@
|
|||
zitareSettings.togglePillNav();
|
||||
}
|
||||
|
||||
const spotlightActions: SpotlightAction[] = [
|
||||
{ id: 'random', label: 'Zufälliges Zitat', category: 'Aktionen', onExecute: () => goto('/') },
|
||||
{
|
||||
id: 'favorites',
|
||||
label: 'Favoriten',
|
||||
category: 'Navigation',
|
||||
onExecute: () => goto('/favorites'),
|
||||
},
|
||||
{ id: 'lists', label: 'Listen', category: 'Navigation', onExecute: () => goto('/lists') },
|
||||
{
|
||||
id: 'settings',
|
||||
label: 'Einstellungen',
|
||||
category: 'Navigation',
|
||||
onExecute: () => goto('/settings'),
|
||||
},
|
||||
];
|
||||
|
||||
async function handleAuthReady() {
|
||||
// Initialize local-first databases (app + shared tags)
|
||||
await Promise.all([zitareStore.initialize(), tagLocalStore.initialize()]);
|
||||
|
|
@ -286,6 +308,7 @@
|
|||
homeRoute="/"
|
||||
onToggleTheme={handleToggleTheme}
|
||||
{isDark}
|
||||
{spotlightActions}
|
||||
showThemeToggle={true}
|
||||
showThemeVariants={true}
|
||||
{themeVariantItems}
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@
|
|||
PillDropdownItem,
|
||||
CommandBarItem,
|
||||
QuickAction,
|
||||
SpotlightAction,
|
||||
} from '@manacore/shared-ui';
|
||||
import { theme } from '$lib/stores/theme.svelte';
|
||||
import { authStore } from '$lib/stores/auth.svelte';
|
||||
|
|
@ -49,6 +50,24 @@
|
|||
|
||||
let { children } = $props();
|
||||
|
||||
const spotlightActions: SpotlightAction[] = [
|
||||
{
|
||||
id: 'new-game',
|
||||
label: 'Neues Spiel erstellen',
|
||||
icon: 'plus',
|
||||
shortcut: 'N',
|
||||
category: 'Erstellen',
|
||||
onExecute: () => goto('/create'),
|
||||
},
|
||||
{ id: 'games', label: 'Alle Spiele', category: 'Navigation', onExecute: () => goto('/') },
|
||||
{
|
||||
id: 'settings',
|
||||
label: 'Einstellungen',
|
||||
category: 'Navigation',
|
||||
onExecute: () => goto('/settings'),
|
||||
},
|
||||
];
|
||||
|
||||
let commandBarOpen = $state(false);
|
||||
|
||||
const commandBarQuickActions: QuickAction[] = [
|
||||
|
|
@ -223,6 +242,7 @@
|
|||
themesHref="/themes"
|
||||
helpHref="/help"
|
||||
allAppsHref="/apps"
|
||||
{spotlightActions}
|
||||
/>
|
||||
|
||||
<main class="main-content bg-background">
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue