mirror of
https://github.com/Memo-2023/mana-monorepo.git
synced 2026-05-14 20:01:09 +02:00
feat(apps): register agents + timeline as MANA_APPS + broadcast URL fix + members page chrome
Three modules move from "dedicated route only" to "first-class
apps in the launcher". After this they show up in the AppDrawer
pill, can be pinned to workbench scenes, and get a direct URL from
the app switcher.
MANA_APPS entries added:
- agents (/agents) — AI agent management. Icon: smiling robot head
with antenna dot. violet→fuchsia gradient, status
beta, requiredTier beta.
- timeline (/timeline) — Chronological view across modules. Icon: vertical
event dots with connecting axis. amber→orange,
status beta, requiredTier beta.
Plus: broadcast's MANA_APPS entry already existed but had no URL
override, so the auto-derived /broadcast didn't match the real route
at /broadcasts. Added an APP_URL_OVERRIDES entry mapping
id='broadcast' → '/broadcasts' so the app switcher lands the user on
the right page. Icon + module.config stay singular.
Route wiring:
- /agents previously only had /agents/templates/ as a subroute. Added
/agents/+page.svelte that renders the existing ai-agents ListView
(at $lib/modules/ai-agents/), so the top-level URL works from the
AppDrawer.
- /timeline already had a root +page.svelte — no work there.
- /broadcasts already had a root +page.svelte — no work there.
/spaces/members page chrome:
- Swapped the hand-rolled header for @mana/shared-ui PageHeader with
backHref="/", breadcrumb "Workbench › Mitglieder verwalten", and the
space name + type as the description. Feels like a native Mana page
now instead of an orphaned admin route.
- Dropped the ~60 lines of unused .type-chip CSS (moved the chip info
into the PageHeader description string).
- Container bumped to 720px max-width to match other admin pages.
0 errors across 7236 files.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
1861e89d45
commit
9d6a5a53a8
4 changed files with 81 additions and 88 deletions
14
apps/mana/apps/web/src/routes/(app)/agents/+page.svelte
Normal file
14
apps/mana/apps/web/src/routes/(app)/agents/+page.svelte
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
<script lang="ts">
|
||||
/**
|
||||
* /agents — AI Agents top-level route.
|
||||
*
|
||||
* Renders the existing workbench-card ListView from
|
||||
* `$lib/modules/ai-agents/`. The module folder is named `ai-agents`
|
||||
* for internal clarity, but the user-facing MANA_APPS id + route is
|
||||
* plain `agents` so the URL stays short.
|
||||
*/
|
||||
|
||||
import ListView from '$lib/modules/ai-agents/ListView.svelte';
|
||||
</script>
|
||||
|
||||
<ListView />
|
||||
|
|
@ -12,6 +12,7 @@
|
|||
*/
|
||||
|
||||
import { onMount } from 'svelte';
|
||||
import { PageHeader } from '@mana/shared-ui';
|
||||
import { getActiveSpace, authFetch } from '$lib/data/scope';
|
||||
import { SPACE_TYPE_LABELS } from '@mana/shared-branding';
|
||||
|
||||
|
|
@ -143,17 +144,18 @@
|
|||
</script>
|
||||
|
||||
<div class="container">
|
||||
<header class="page-head">
|
||||
<h1>Mitglieder</h1>
|
||||
{#if activeSpace}
|
||||
<p class="subtitle">
|
||||
<strong>{activeSpace.name}</strong>
|
||||
<span class="type-chip" data-type={activeSpace.type}
|
||||
>{SPACE_TYPE_LABELS.de[activeSpace.type]}</span
|
||||
>
|
||||
</p>
|
||||
{/if}
|
||||
</header>
|
||||
<PageHeader
|
||||
title="Mitglieder"
|
||||
description={activeSpace
|
||||
? `${activeSpace.name} · ${SPACE_TYPE_LABELS.de[activeSpace.type]}`
|
||||
: undefined}
|
||||
backHref="/"
|
||||
size="lg"
|
||||
>
|
||||
{#snippet breadcrumb()}
|
||||
<a href="/">Workbench</a> <span class="crumb-sep">›</span> Mitglieder verwalten
|
||||
{/snippet}
|
||||
</PageHeader>
|
||||
|
||||
{#if !activeSpace}
|
||||
<p class="empty">Lade aktiven Space …</p>
|
||||
|
|
@ -263,87 +265,15 @@
|
|||
instead of falling back to hardcoded white. */
|
||||
|
||||
.container {
|
||||
max-width: 640px;
|
||||
max-width: 720px;
|
||||
margin: 0 auto;
|
||||
padding: 1.5rem 1rem 4rem;
|
||||
padding: 0 1rem 4rem;
|
||||
color: hsl(var(--color-foreground));
|
||||
}
|
||||
|
||||
.page-head {
|
||||
margin-bottom: 1.5rem;
|
||||
}
|
||||
|
||||
.page-head h1 {
|
||||
font-size: 1.5rem;
|
||||
font-weight: 600;
|
||||
margin: 0 0 0.25rem;
|
||||
color: hsl(var(--color-foreground));
|
||||
}
|
||||
|
||||
.subtitle {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.5rem;
|
||||
margin: 0;
|
||||
color: hsl(var(--color-muted-foreground, 0 0% 55%));
|
||||
font-size: 0.875rem;
|
||||
}
|
||||
|
||||
.type-chip {
|
||||
font-size: 0.6875rem;
|
||||
padding: 0.125rem 0.5rem;
|
||||
border-radius: 9999px;
|
||||
background: hsl(var(--color-muted, 0 0% 94%));
|
||||
color: hsl(var(--color-muted-foreground, 0 0% 45%));
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.02em;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.type-chip[data-type='brand'] {
|
||||
background: hsl(260 60% 95%);
|
||||
color: hsl(260 55% 35%);
|
||||
}
|
||||
.type-chip[data-type='club'] {
|
||||
background: hsl(160 45% 93%);
|
||||
color: hsl(160 55% 28%);
|
||||
}
|
||||
.type-chip[data-type='family'] {
|
||||
background: hsl(30 70% 93%);
|
||||
color: hsl(30 55% 35%);
|
||||
}
|
||||
.type-chip[data-type='team'] {
|
||||
background: hsl(210 55% 93%);
|
||||
color: hsl(210 55% 32%);
|
||||
}
|
||||
.type-chip[data-type='practice'] {
|
||||
background: hsl(340 50% 94%);
|
||||
color: hsl(340 50% 38%);
|
||||
}
|
||||
|
||||
:global(.dark) .type-chip {
|
||||
background: hsl(var(--color-muted, 0 0% 20%));
|
||||
color: hsl(var(--color-muted-foreground, 0 0% 75%));
|
||||
}
|
||||
:global(.dark) .type-chip[data-type='brand'] {
|
||||
background: hsl(260 40% 25%);
|
||||
color: hsl(260 80% 85%);
|
||||
}
|
||||
:global(.dark) .type-chip[data-type='club'] {
|
||||
background: hsl(160 35% 20%);
|
||||
color: hsl(160 70% 80%);
|
||||
}
|
||||
:global(.dark) .type-chip[data-type='family'] {
|
||||
background: hsl(30 40% 22%);
|
||||
color: hsl(30 80% 82%);
|
||||
}
|
||||
:global(.dark) .type-chip[data-type='team'] {
|
||||
background: hsl(210 40% 22%);
|
||||
color: hsl(210 70% 82%);
|
||||
}
|
||||
:global(.dark) .type-chip[data-type='practice'] {
|
||||
background: hsl(340 35% 23%);
|
||||
color: hsl(340 65% 82%);
|
||||
.crumb-sep {
|
||||
margin: 0 0.25rem;
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
.hint-card {
|
||||
|
|
|
|||
|
|
@ -248,6 +248,18 @@ export const APP_ICONS = {
|
|||
// (emerald) while staying in the "communication" colour family.
|
||||
`<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100"><defs><linearGradient id="bc" x1="0%" y1="0%" x2="100%" y2="100%"><stop offset="0%" style="stop-color:#6366f1"/><stop offset="100%" style="stop-color:#06b6d4"/></linearGradient></defs><rect width="100" height="100" rx="22" fill="url(#bc)"/><path d="M32 42v16l14 4v-24l-14 4z" fill="white" fill-opacity="0.95"/><path d="M46 38l26-10v44l-26-10z" fill="white"/><path d="M42 62v14a3 3 0 0 0 3 3h4a3 3 0 0 0 3-3V64" fill="white" fill-opacity="0.85"/><path d="M78 40c4 2 6 5 6 10s-2 8-6 10" fill="none" stroke="white" stroke-width="2.5" stroke-linecap="round" opacity="0.8"/><path d="M84 32c6 3 10 9 10 18s-4 15-10 18" fill="none" stroke="white" stroke-width="2.5" stroke-linecap="round" opacity="0.5"/></svg>`
|
||||
),
|
||||
agents: svgToDataUrl(
|
||||
// Smiling robot head with antenna dot — represents the AI agents that
|
||||
// carry out autonomous missions. Violet→fuchsia gradient sits next to
|
||||
// companion in the AI Workbench family.
|
||||
`<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100"><defs><linearGradient id="ag" x1="0%" y1="0%" x2="100%" y2="100%"><stop offset="0%" style="stop-color:#8b5cf6"/><stop offset="100%" style="stop-color:#d946ef"/></linearGradient></defs><rect width="100" height="100" rx="22" fill="url(#ag)"/><line x1="50" y1="20" x2="50" y2="28" stroke="white" stroke-width="3" stroke-linecap="round"/><circle cx="50" cy="18" r="3" fill="white"/><rect x="24" y="30" width="52" height="40" rx="10" fill="white"/><circle cx="38" cy="48" r="5" fill="#8b5cf6"/><circle cx="62" cy="48" r="5" fill="#8b5cf6"/><circle cx="39" cy="47" r="1.5" fill="white"/><circle cx="63" cy="47" r="1.5" fill="white"/><path d="M38 60c3 3 7 4 12 4s9-1 12-4" stroke="#8b5cf6" stroke-width="3" stroke-linecap="round" fill="none"/><rect x="34" y="72" width="10" height="8" rx="2" fill="white" fill-opacity="0.9"/><rect x="56" y="72" width="10" height="8" rx="2" fill="white" fill-opacity="0.9"/><line x1="22" y1="46" x2="28" y2="46" stroke="white" stroke-width="3" stroke-linecap="round" opacity="0.7"/><line x1="72" y1="46" x2="78" y2="46" stroke="white" stroke-width="3" stroke-linecap="round" opacity="0.7"/></svg>`
|
||||
),
|
||||
timeline: svgToDataUrl(
|
||||
// Vertical event-dots with connecting line — timeline/history axis.
|
||||
// Amber→orange gradient so it stands apart from the blue Activity icon
|
||||
// while still reading as "chronological" in the AI Workbench family.
|
||||
`<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100"><defs><linearGradient id="tl" x1="0%" y1="0%" x2="100%" y2="100%"><stop offset="0%" style="stop-color:#f59e0b"/><stop offset="100%" style="stop-color:#ea580c"/></linearGradient></defs><rect width="100" height="100" rx="22" fill="url(#tl)"/><line x1="34" y1="22" x2="34" y2="78" stroke="white" stroke-width="3" stroke-linecap="round" opacity="0.55"/><circle cx="34" cy="30" r="5" fill="white"/><circle cx="34" cy="50" r="5" fill="white"/><circle cx="34" cy="70" r="5" fill="white"/><rect x="44" y="26" width="32" height="8" rx="2" fill="white" fill-opacity="0.95"/><rect x="44" y="46" width="26" height="8" rx="2" fill="white" fill-opacity="0.8"/><rect x="44" y="66" width="30" height="8" rx="2" fill="white" fill-opacity="0.9"/></svg>`
|
||||
),
|
||||
} as const;
|
||||
|
||||
export type AppIconId = keyof typeof APP_ICONS;
|
||||
|
|
|
|||
|
|
@ -1071,6 +1071,40 @@ export const MANA_APPS: ManaApp[] = [
|
|||
status: 'development',
|
||||
requiredTier: 'alpha',
|
||||
},
|
||||
{
|
||||
id: 'agents',
|
||||
name: 'Agents',
|
||||
description: {
|
||||
de: 'KI-Agenten verwalten',
|
||||
en: 'Manage AI agents',
|
||||
},
|
||||
longDescription: {
|
||||
de: 'Lege mehrere KI-Agenten an — jeder mit eigenem Namen, Avatar, System-Prompt, Memory und Tool-Policy. Agents führen autonome Missions aus und schreiben unter ihrer eigenen Identität.',
|
||||
en: 'Create multiple AI agents — each with its own name, avatar, system prompt, memory and tool policy. Agents run autonomous missions and write under their own identity.',
|
||||
},
|
||||
icon: APP_ICONS.agents,
|
||||
color: '#8b5cf6',
|
||||
comingSoon: false,
|
||||
status: 'beta',
|
||||
requiredTier: 'beta',
|
||||
},
|
||||
{
|
||||
id: 'timeline',
|
||||
name: 'Timeline',
|
||||
description: {
|
||||
de: 'Was wurde wann getan',
|
||||
en: 'What happened when',
|
||||
},
|
||||
longDescription: {
|
||||
de: 'Chronologische Übersicht aller Einträge über alle Module — Tasks, Events, Kalender, KI-Missionen. Mit Akteur-Filter (User vs. KI vs. System) und Analytics-Ansicht.',
|
||||
en: 'A chronological view of every record across every module — tasks, events, calendar, AI missions. With actor filter (user / AI / system) and analytics drill-down.',
|
||||
},
|
||||
icon: APP_ICONS.timeline,
|
||||
color: '#f59e0b',
|
||||
comingSoon: false,
|
||||
status: 'beta',
|
||||
requiredTier: 'beta',
|
||||
},
|
||||
];
|
||||
|
||||
/**
|
||||
|
|
@ -1162,6 +1196,9 @@ const APP_URL_OVERRIDES: Partial<Record<AppIconId, { dev: string; prod: string }
|
|||
mana: { dev: 'http://localhost:5173', prod: 'https://mana.how' },
|
||||
// Standalone apps on their own subdomain / port.
|
||||
arcade: { dev: 'http://localhost:5201', prod: 'https://arcade.mana.how' },
|
||||
// The broadcast module's route is `/broadcasts` (plural) but the icon
|
||||
// + id stay singular to match the `lib/modules/broadcast/` folder.
|
||||
broadcast: { dev: 'http://localhost:5173/broadcasts', prod: 'https://mana.how/broadcasts' },
|
||||
};
|
||||
|
||||
export const APP_URLS: Record<AppIconId, { dev: string; prod: string }> = Object.fromEntries(
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue