1068a4a5f7
- Tracked items get the same isSpillover flag as categories: a per-item "More" checkbox collapses it into the "More »" nav tab instead of its own top-level tab, mirroring Category.isSpillover end to end (schema, CRUD, public API, nav partitioning, /more page). - Renamed user-facing "Tracked events" text to "Tracked items" (admin tab, toolbar, buttons, placeholders, /event/:id subtitle) — the underlying TrackedEvent/events data model and routes are unchanged. - Locked the per-item recap cadence dropdown (previously a live Continuous/Daily/Hourly picker) and moved it to its own labeled section with an explanatory hint: reading eventsRecap.ts confirmed Continuous and Hourly currently behave identically, so the live choice was more confusing than useful. New items are fixed to Continuous; existing items show their real cadence read-only.
90 lines
2.5 KiB
Svelte
90 lines
2.5 KiB
Svelte
<script lang="ts">
|
|
import type { PageData } from './$types';
|
|
import MergeTab from '$lib/components/admin/MergeTab.svelte';
|
|
import ModelsTab from '$lib/components/admin/ModelsTab.svelte';
|
|
import RetentionTab from '$lib/components/admin/RetentionTab.svelte';
|
|
import EventsTab from '$lib/components/admin/EventsTab.svelte';
|
|
import WidgetsTab from '$lib/components/admin/WidgetsTab.svelte';
|
|
import ConnectionsTab from '$lib/components/admin/ConnectionsTab.svelte';
|
|
import LogsTab from '$lib/components/admin/LogsTab.svelte';
|
|
|
|
let { data }: { data: PageData } = $props();
|
|
|
|
const tabs = [
|
|
{ id: 'merge', label: 'Sources & Merge' },
|
|
{ id: 'models', label: 'Models' },
|
|
{ id: 'retention', label: 'Retention' },
|
|
{ id: 'events', label: 'Tracked items' },
|
|
{ id: 'widgets', label: 'Widgets' },
|
|
{ id: 'connections', label: 'Connections' },
|
|
{ id: 'logs', label: 'Logs' }
|
|
];
|
|
|
|
let active = $state('merge');
|
|
</script>
|
|
|
|
<div class="head">
|
|
<span class="title">Admin</span>
|
|
<nav class="tabs">
|
|
{#each tabs as tab}
|
|
<button class="tab" class:active={active === tab.id} onclick={() => (active = tab.id)}>
|
|
{tab.label}
|
|
</button>
|
|
{/each}
|
|
</nav>
|
|
</div>
|
|
|
|
<div class="content">
|
|
{#if active === 'merge'}
|
|
<MergeTab settings={data.settings} sources={data.sources} />
|
|
{:else if active === 'models'}
|
|
<ModelsTab settings={data.settings} models={data.models} aiStatus={data.aiStatus} />
|
|
{:else if active === 'retention'}
|
|
<RetentionTab settings={data.settings} />
|
|
{:else if active === 'events'}
|
|
<EventsTab events={data.events} sources={data.sources} />
|
|
{:else if active === 'widgets'}
|
|
<WidgetsTab settings={data.settings} stockTickers={data.stockTickers} bookmarks={data.bookmarks} poe2Watchlist={data.poe2Watchlist} />
|
|
{:else if active === 'connections'}
|
|
<ConnectionsTab settings={data.settings} aiStatus={data.aiStatus} telegramStatus={data.telegramStatus} />
|
|
{:else if active === 'logs'}
|
|
<LogsTab logs={data.logs} />
|
|
{/if}
|
|
</div>
|
|
|
|
<style>
|
|
.head {
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: space-between;
|
|
flex-wrap: wrap;
|
|
gap: 12px;
|
|
margin-bottom: 20px;
|
|
}
|
|
.title {
|
|
font-family: var(--font-voice);
|
|
font-size: 24px;
|
|
font-weight: 500;
|
|
}
|
|
.tabs {
|
|
display: flex;
|
|
gap: 6px;
|
|
flex-wrap: wrap;
|
|
}
|
|
.tab {
|
|
font-size: 12px;
|
|
padding: 5px 12px;
|
|
border: none;
|
|
background: transparent;
|
|
color: var(--text-secondary);
|
|
border-radius: var(--radius);
|
|
}
|
|
.tab.active {
|
|
background: var(--pill-bg);
|
|
color: var(--pill-text);
|
|
}
|
|
.content {
|
|
max-width: 720px;
|
|
}
|
|
</style>
|