af526dea18
Major dashboard restructure plus the new task landing pages and self-serve schedules add-on integration. ## Side menu - Full restructure: standalone Tasks / Runs / Sessions block at the top; new collapsible sections for AI, Observability, Deployments, Manage - Persisted collapse state per section in `dashboardPreferences` - New / updated icons across the menu - Dashboards section: built-in Run metrics + AI metrics + custom dashboards, with drag-to-reorder via ReactGridLayout (`DashboardList.tsx`) - DevPresence connection indicator in the env selector (DEV + V2) ## Tasks (`_index` — unified Tasks page) - Replaces the separated Agents / Standard / Schedules listing pages with one table - New `UnifiedTaskListPresenter` composes `TaskListPresenter` + `AgentListPresenter` (shared `currentWorker` lookup) - Columns: Type (with kind badge), ID, File, Running (numeric for tasks; running + suspended pills for agents), Activity (24h stacked-by-status), sticky menu - Search + "Task type" multi-select filter (URL-synced) - Client-side pagination at 25/page - Right-hand "useful links" panel (cookie-persisted state) - Live-reload SSE: page revalidates on `WORKER_CREATED` so onboarding `trigger dev` flips the blank state automatically ## Agent landing page (`/agents/$agentParam`) - New per-agent detail page - Top tabs (Sessions / Runs) toggle both the chart panel and the table - Three dashboard-style chart cards: Sessions/Runs activity, LLM spend, Tokens - `AgentDetailPresenter` queries ClickHouse for run activity, session activity (with FINAL on `sessions_v1`), and LLM cost/token activity from `llm_metrics_v1` - TimeFilter at the top drives all three charts - Sticky table header, resizable horizontal handle, sidebar with Test agent button + properties - Docs link → `ai-chat/overview` ## Standard Task landing page (`/tasks/standard/$taskParam`) - New per-task detail page mirroring the Agent layout - `TaskDetailPresenter` for activity + properties - Chart panel wrapped in a Card with "Runs by status" header - Top bar with title, TimeFilter, pagination - Right sidebar: Test task + identifier, queue, machine, retry, TTL, payload schema, etc. ## Scheduled Task landing page (`/tasks/scheduled/$taskParam`) - New per-task detail page mirroring the Agent / Standard layout - Top-bar actions (right → left): pagination, Bulk replay…, View all runs, TimeFilter, Create schedule - Connected schedules mini-table in the sidebar - **Self-serve schedules add-on integration** (reincarnated from the now-removed `/schedules` listing page during the `origin/main` merge): - Bottom usage bar pinned via `grid-rows-[auto_1fr_auto]` — progress ring + "X/Y of your schedules" + Purchase / Upgrade / Request CTA - At-limit "Create schedule" intercept dialog - `PurchaseSchedulesModal` extracted as a shared component (`apps/webapp/app/components/schedules/PurchaseSchedulesModal.tsx`) handling increase / decrease / above-quota / need-to-delete states - New resource action route at `/resources/orgs/$organizationSlug/schedules-addon` ## Sessions - Index page: list, filters, blank state, help tooltip rework - Detail page: combined input/output chronological view (replaces split tabs) - Improved raw-message view layout (full-height) - AI payload UI: `data-*` parts grouped under "AI SDK data parts:" label - `toSafeUrl` helper guards rendered URLs from streamed content - Fix: duplicate assistant content on inspector tab switch ## Playground (Test agent) - Restructured top menu; back button + agent-selector popover - Improved blank state - Recent agent chat history moved into the tabbed menu - Better message-scroll container (full height) ## Dashboards - New Dashboards landing page (`/dashboards`) — Run metrics, AI metrics, Create your own CTAs - `BuiltInDashboards` updated; new `TasksDashboardPresenter` for the tasks overview - Custom dashboards section gains drag-to-reorder; cosmetic fix for active-row drag-handle blending ## PageHeader / shared primitives - `PageTitle` gains an `accessory` prop supporting string (auto-wrapped in tooltip) and ReactNode - Help tooltips on Tasks, Runs, Sessions PageTitles explaining the concept and sub-categories - `Card` primitive used for dashboard-style chart panels throughout ## Code review fixes (last batch on this branch) - ClickHouse activity queries hardened: `FINAL` + `_is_deleted = 0` on `task_runs_v2` (ReplacingMergeTree); `organization_id` + `project_id` filters for sort-key prefix; `inserted_at` partition filter on `llm_metrics_v1` - `UnifiedTaskListPresenter`: shared `currentWorker` lookup; slug-collision guard in `mergeRunningStates`; off-by-one fixed in 24h bucket alignment - `ScheduleListPresenter`: halved platform RPCs by deriving limit from `currentPlan` instead of calling `getLimit` - Sessions detail: stopped IntersectionObserver / scroll listener re-attach on every chunk; `requestAnimationFrame` deferral on auto-scroll to avoid virtualizer race - URL hardening: `?types=` validated against known kinds; new `parseFiniteInt` helper applied to `from`/`to`/`page` params - AgentView: HITL resolution buffer now cleared once parts reach a terminal state (was an unbounded Map on long sessions); subscription effect deps documented with eslint suppression - `PurchaseSchedulesModal`: bundle state resets on each open instead of persisting stale drafts ## Manual testing Manual smoke-test plan is tracked under [TRI-10883](https://linear.app/triggerdotdev/issue/TRI-10883), broken into 20 sub-issues covering onboarding, self-serve schedules, side menu, the four landing pages, sessions, runs, dashboards, regressions and performance. 🤖 Generated with [Claude Code](https://claude.com/claude-code) --------- Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
257 lines
6.3 KiB
CSS
257 lines
6.3 KiB
CSS
@import url("non.geist");
|
|
@import url("non.geist/mono");
|
|
|
|
@import "react-grid-layout/css/styles.css";
|
|
@import "react-resizable/css/styles.css";
|
|
|
|
/* Override react-grid-layout placeholder color (default is red) */
|
|
.react-grid-item.react-grid-placeholder {
|
|
background: rgb(99 102 241) !important; /* indigo-500 */
|
|
border-radius: 0.375rem !important; /* rounded-md */
|
|
}
|
|
|
|
/* Sidebar reorder grid: subtle placeholder */
|
|
.sidebar-reorder-grid .react-grid-item.react-grid-placeholder {
|
|
background: rgb(39 42 46) !important; /* charcoal-700 */
|
|
border-radius: 0.25rem;
|
|
opacity: 1 !important;
|
|
}
|
|
|
|
/* Sidebar reorder grid: only animate transform (vertical position), not width/height */
|
|
.sidebar-reorder-grid .react-grid-item {
|
|
transition: transform 200ms ease !important;
|
|
}
|
|
|
|
/* Override resize handle icon to white */
|
|
.react-resizable-handle {
|
|
background-image: url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA2IDYiIHN0eWxlPSJiYWNrZ3JvdW5kLWNvbG9yOiNmZmZmZmYwMCIgeD0iMHB4IiB5PSIwcHgiIHdpZHRoPSI2cHgiIGhlaWdodD0iNnB4Ij48ZyBvcGFjaXR5PSIwLjMwMiI+PHBhdGggZD0iTSA2IDYgTCAwIDYgTCAwIDQuMiBMIDQgNC4yIEwgNC4yIDQuMiBMIDQuMiAwIEwgNiAwIEwgNiA2IEwgNiA2IFoiIGZpbGw9IiNmZmZmZmYiLz48L2c+PC9zdmc+') !important;
|
|
}
|
|
.react-resizable-handle::after {
|
|
border-bottom-color: rgba(255, 255, 255, 0.4) !important;
|
|
border-right-color: rgba(255, 255, 255, 0.4) !important;
|
|
border-top-color: rgba(255, 255, 255, 0.4) !important;
|
|
border-left-color: rgba(255, 255, 255, 0.4) !important;
|
|
}
|
|
|
|
@tailwind base;
|
|
@tailwind components;
|
|
@tailwind utilities;
|
|
|
|
@property --gradient-angle {
|
|
syntax: "<angle>";
|
|
initial-value: 0deg;
|
|
inherits: false;
|
|
}
|
|
|
|
@supports (-webkit-hyphens: none) {
|
|
.safari-only {
|
|
@apply border-b border-grid-dimmed;
|
|
}
|
|
}
|
|
|
|
@layer base {
|
|
* {
|
|
@apply border-grid-bright;
|
|
}
|
|
body {
|
|
@apply bg-background-dimmed text-text-dimmed;
|
|
font-feature-settings: "rlig" 1, "calt" 1;
|
|
}
|
|
|
|
/* Text selection styles */
|
|
::selection {
|
|
@apply bg-text-bright/30 text-text-bright;
|
|
}
|
|
::-moz-selection {
|
|
@apply bg-text-bright/30 text-text-bright;
|
|
}
|
|
|
|
/* shadcn charts: https://ui.shadcn.com/docs/components/chart#add-a-grid */
|
|
:root {
|
|
--chart-1: 12 76% 61%;
|
|
--chart-2: 173 58% 39%;
|
|
--chart-3: 197 37% 24%;
|
|
--chart-4: 43 74% 66%;
|
|
--chart-5: 27 87% 67%;
|
|
}
|
|
|
|
.dark {
|
|
--chart-1: 220 70% 50%;
|
|
--chart-2: 160 60% 45%;
|
|
--chart-3: 30 80% 55%;
|
|
--chart-4: 280 65% 60%;
|
|
--chart-5: 340 75% 55%;
|
|
}
|
|
}
|
|
|
|
@layer utilities {
|
|
.scrollbar-gutter-stable {
|
|
scrollbar-gutter: stable;
|
|
}
|
|
|
|
.animated-gradient-glow {
|
|
position: relative;
|
|
overflow: visible;
|
|
}
|
|
|
|
.animated-gradient-glow::before {
|
|
content: "";
|
|
position: absolute;
|
|
inset: -8px;
|
|
z-index: -1;
|
|
background: conic-gradient(
|
|
from var(--gradient-angle),
|
|
rgb(99 102 241),
|
|
rgb(245 158 11),
|
|
rgb(236 72 153),
|
|
rgb(245 158 11),
|
|
rgb(99 102 241)
|
|
);
|
|
border-radius: inherit;
|
|
animation: gradient-rotation 3s linear infinite;
|
|
pointer-events: none;
|
|
filter: blur(0.5rem);
|
|
opacity: 0.1;
|
|
}
|
|
|
|
.animated-gradient-glow-small {
|
|
position: relative;
|
|
overflow: visible;
|
|
}
|
|
|
|
.animated-gradient-glow-small::before {
|
|
content: "";
|
|
position: absolute;
|
|
inset: -1px;
|
|
z-index: -1;
|
|
background: conic-gradient(
|
|
from var(--gradient-angle),
|
|
rgb(99 102 241),
|
|
rgb(245 158 11),
|
|
rgb(236 72 153),
|
|
rgb(245 158 11),
|
|
rgb(99 102 241)
|
|
);
|
|
border-radius: inherit;
|
|
animation: gradient-rotation 3s linear infinite;
|
|
pointer-events: none;
|
|
filter: blur(0.2rem);
|
|
opacity: 0.3;
|
|
}
|
|
}
|
|
|
|
@keyframes gradient-rotation {
|
|
0% {
|
|
--gradient-angle: 0deg;
|
|
}
|
|
100% {
|
|
--gradient-angle: 360deg;
|
|
}
|
|
}
|
|
|
|
/* Streamdown markdown styling */
|
|
.streamdown-container {
|
|
/* Streamdown uses shadcn/ui CSS variables - define them for our theme.
|
|
These map Tailwind utility classes like bg-background, bg-primary, etc.
|
|
that streamdown uses internally for its link safety modal, code blocks,
|
|
and other interactive elements. */
|
|
--background: 230 16% 9%; /* charcoal-900 #121317 */
|
|
--foreground: 215 19% 87%; /* charcoal-200 #D7D9DD */
|
|
--muted: 220 8% 17%; /* charcoal-775 #1C1E21 */
|
|
--muted-foreground: 220 8% 57%; /* charcoal-400 #878C99 */
|
|
--border: 216 7% 27%; /* charcoal-650 #2C3034 */
|
|
--primary: 95 100% 66%; /* apple-500 #A8FF53 */
|
|
--primary-foreground: 230 16% 9%; /* charcoal-900 */
|
|
--sidebar: 228 10% 11%; /* charcoal-850 #15171A */;
|
|
|
|
/* Code block styling */
|
|
& [data-code-block-container] {
|
|
@apply rounded border-charcoal-650 my-0;
|
|
}
|
|
& [data-code-block] {
|
|
border-top: none;
|
|
}
|
|
|
|
& p {
|
|
@apply my-1;
|
|
}
|
|
& h1, & h2, & h3, & h4, & h5, & h6 {
|
|
@apply font-semibold text-text-bright mt-2 mb-1;
|
|
}
|
|
& h1 {
|
|
@apply text-base;
|
|
}
|
|
& h2 {
|
|
@apply text-sm;
|
|
}
|
|
& h3, & h4, & h5, & h6 {
|
|
@apply text-xs;
|
|
}
|
|
& ul, & ol {
|
|
@apply ml-4 my-1;
|
|
}
|
|
& ul {
|
|
@apply list-disc;
|
|
}
|
|
& ol {
|
|
@apply list-decimal;
|
|
}
|
|
& li {
|
|
@apply my-0.5;
|
|
}
|
|
/* Inline code (not in pre blocks) */
|
|
& code:not(pre code) {
|
|
@apply bg-charcoal-700 px-1 py-0.5 rounded text-text-bright font-mono;
|
|
}
|
|
& blockquote {
|
|
@apply border-l-2 border-charcoal-600 pl-3 my-2 italic;
|
|
}
|
|
& a {
|
|
@apply text-text-link hover:underline;
|
|
}
|
|
& strong {
|
|
@apply font-semibold text-text-bright;
|
|
}
|
|
& em {
|
|
@apply italic;
|
|
}
|
|
& hr {
|
|
@apply my-2 border-charcoal-600;
|
|
}
|
|
& table {
|
|
@apply w-full my-2 border-collapse;
|
|
}
|
|
& th, & td {
|
|
@apply border border-charcoal-600 px-2 py-1 text-left;
|
|
}
|
|
& th {
|
|
@apply bg-charcoal-700 font-semibold;
|
|
}
|
|
|
|
/* Streamdown code block container */
|
|
& [data-code-block-container] {
|
|
@apply my-2 border-charcoal-700;
|
|
}
|
|
& [data-code-block-header] {
|
|
@apply bg-charcoal-800 text-text-dimmed border-b border-charcoal-700;
|
|
}
|
|
/* Hide light mode code block, show dark mode */
|
|
& [data-code-block].dark\:hidden {
|
|
display: none !important;
|
|
}
|
|
& [data-code-block].hidden.dark\:block {
|
|
display: block !important;
|
|
}
|
|
/* Override the bg-muted/40 class to let inline styles work */
|
|
& [data-code-block] pre {
|
|
background-color: inherit !important;
|
|
@apply scrollbar-thin scrollbar-track-transparent scrollbar-thumb-charcoal-600;
|
|
}
|
|
& [data-code-block] pre code {
|
|
@apply bg-transparent;
|
|
}
|
|
& [data-code-block] .line {
|
|
@apply leading-relaxed;
|
|
}
|
|
}
|