fix(webapp): restore header docs buttons when the dashboard agent is unavailable (#4592)

Restores the page-header docs buttons removed in #4529 / #4418, shown
only when the dashboard agent is unavailable (feature flag off, or pages
outside the environment layout). The buttons are restored verbatim at
their original spots — 22 sites across 21 files — wrapped in a small
`WhenAgentUnavailable` gate that reads the agent context (SSR-safe, no
hydration flicker).

Also: in the light theme, the query editor's Format/Clear/Copy toolbar
gets a translucent white background (`light:bg-white/80`) instead of
transparent, so it no longer blends into the code behind it.
<img width="1215" height="133" alt="Screenshot 2026-08-12 at 17 26 02"
src="https://github.com/user-attachments/assets/4bdba825-9cbd-4df4-b6ca-0ea6691a534b"
/>
This commit is contained in:
Katia Bulatova
2026-08-12 18:08:44 +02:00
committed by GitHub
parent 442702e879
commit 622fa79643
26 changed files with 309 additions and 28 deletions
+1 -1
View File
@@ -7,4 +7,4 @@ Meet the dashboard agent: a chat in every environment that answers questions abo
**Watch…** on a run, queue, error or the health report tells you when things change: a run finishes, a queue clears or grows past a number you pick, an error comes back, an environment recovers. The answer arrives in the chat and, if you want, by email, Slack or webhook — and the agent can look into bad news on its own. A watch reaches you on any browser you sign in from, without opening the chat first.
A sample of conversations is scored automatically so the agent keeps getting better; only the score and a one-line summary are kept, never your messages, data or code, and we can switch it off for your organization on request. The Docs button is gone from page headers — ask the agent instead, or open Documentation from Help & Feedback. Separately, a queue's wait times, peak depth, throughput and throttling can now be read from the API.
A sample of conversations is scored automatically so the agent keeps getting better; only the score and a one-line summary are kept, never your messages, data or code, and we can switch it off for your organization on request. Ask the agent instead of the Docs buttons in page headers — they stay there when the agent isn't available to you. Separately, a queue's wait times, peak depth, throughput and throttling can now be read from the API.
@@ -0,0 +1,6 @@
---
area: webapp
type: fix
---
In the light theme, the Format, Clear and Copy buttons on the query editor no longer blend into the query text behind them.
@@ -284,7 +284,7 @@ export function TSQLEditor(opts: TSQLEditorProps) {
}}
/>
{showButtons && (
<div className="absolute right-0 top-0 z-10 flex items-center justify-end bg-background-deep/80 light:bg-transparent p-1.5">
<div className="absolute right-0 top-0 z-10 flex items-center justify-end bg-background-deep/80 light:bg-white/80 p-1.5">
{additionalActions && additionalActions}
{showFormatButton && (
<Button
@@ -0,0 +1,10 @@
import { useDashboardAgent } from "./dashboardAgentLauncher";
export function WhenAgentUnavailable({ children }: { children: React.ReactNode }) {
const agent = useDashboardAgent();
if (agent) {
return null;
}
return <>{children}</>;
}
@@ -1,4 +1,4 @@
import { ExclamationTriangleIcon } from "@heroicons/react/20/solid";
import { BookOpenIcon, ExclamationTriangleIcon } from "@heroicons/react/20/solid";
import { json } from "@remix-run/node";
import { useFetcher, useRevalidator } from "@remix-run/react";
@@ -92,6 +92,7 @@ import { requireUserId } from "~/services/session.server";
import { cn } from "~/utils/cn";
import { formatNumberCompact } from "~/utils/numberFormatter";
import {
docsPath,
EnvironmentParamSchema,
v3AgentTaskPath,
v3PlaygroundAgentPath,
@@ -102,6 +103,7 @@ import {
v3TestTaskPath,
} from "~/utils/pathBuilder";
import { sectionAgentPageContext } from "~/components/dashboard-agent/suggested-prompts";
import { WhenAgentUnavailable } from "~/components/dashboard-agent/WhenAgentUnavailable";
import type { Handle } from "~/utils/handle";
export const handle: Handle = {
@@ -286,6 +288,15 @@ export default function Page() {
<PageTitle title="Tasks" accessory={<TasksHelpTooltip />} />
<PageAccessories>
<AdminDebugTooltip />
<WhenAgentUnavailable>
<LinkButton
variant={"docs/small"}
LeadingIcon={BookOpenIcon}
to={docsPath("/tasks/overview")}
>
Task docs
</LinkButton>
</WhenAgentUnavailable>
</PageAccessories>
</NavBar>
<PageBody scrollable={false}>
@@ -1,3 +1,4 @@
import { BookOpenIcon } from "@heroicons/react/24/solid";
import { type LoaderFunctionArgs } from "@remix-run/server-runtime";
import { Suspense, useMemo, useState } from "react";
import { TypedAwait, typeddefer, useTypedLoaderData } from "remix-typedjson";
@@ -16,7 +17,7 @@ import { statusColor } from "~/components/primitives/charts/statusColors";
import { CopyableText } from "~/components/primitives/CopyableText";
import { DateTime } from "~/components/primitives/DateTime";
import { Header2 } from "~/components/primitives/Headers";
import { NavBar, PageTitle } from "~/components/primitives/PageHeader";
import { NavBar, PageAccessories, PageTitle } from "~/components/primitives/PageHeader";
import { Paragraph } from "~/components/primitives/Paragraph";
import * as Property from "~/components/primitives/PropertyTable";
import { Spinner } from "~/components/primitives/Spinner";
@@ -42,12 +43,14 @@ import { clickhouseFactory } from "~/services/clickhouse/clickhouseFactoryInstan
import { getResizableSnapshot } from "~/services/resizablePanel.server";
import { requireUser } from "~/services/session.server";
import {
docsPath,
EnvironmentParamSchema,
v3EnvironmentPath,
v3PlaygroundAgentPath,
} from "~/utils/pathBuilder";
import { parseFiniteInt } from "~/utils/searchParams";
import { agentsAgentPageContext } from "~/components/dashboard-agent/suggested-prompts";
import { WhenAgentUnavailable } from "~/components/dashboard-agent/WhenAgentUnavailable";
import type { Handle } from "~/utils/handle";
export const handle: Handle = {
@@ -227,6 +230,17 @@ export default function Page() {
</span>
}
/>
<PageAccessories>
<WhenAgentUnavailable>
<LinkButton
variant="docs/small"
LeadingIcon={BookOpenIcon}
to={docsPath("ai-chat/overview")}
>
Agents docs
</LinkButton>
</WhenAgentUnavailable>
</PageAccessories>
</NavBar>
<MetricsLayout.Root>
<MetricsLayout.Filters>
@@ -4,6 +4,7 @@ import { parseWithZod } from "@conform-to/zod";
import {
BellAlertIcon,
BellSlashIcon,
BookOpenIcon,
EnvelopeIcon,
LockClosedIcon,
PlusIcon,
@@ -24,7 +25,7 @@ import { Button, LinkButton } from "~/components/primitives/Buttons";
import { ClipboardField } from "~/components/primitives/ClipboardField";
import { DetailCell } from "~/components/primitives/DetailCell";
import { Header2, Header3 } from "~/components/primitives/Headers";
import { NavBar, PageTitle } from "~/components/primitives/PageHeader";
import { NavBar, PageAccessories, PageTitle } from "~/components/primitives/PageHeader";
import { Paragraph } from "~/components/primitives/Paragraph";
import {
Table,
@@ -59,12 +60,14 @@ import { requireUserId } from "~/services/session.server";
import { cn } from "~/utils/cn";
import {
EnvironmentParamSchema,
docsPath,
v3BillingPath,
v3NewProjectAlertPath,
v3ProjectAlertsPath,
} from "~/utils/pathBuilder";
import { alertsWorker } from "~/v3/alertsWorker.server";
import { alertsAgentPageContext } from "~/components/dashboard-agent/suggested-prompts";
import { WhenAgentUnavailable } from "~/components/dashboard-agent/WhenAgentUnavailable";
import type { Handle } from "~/utils/handle";
export const handle: Handle = {
@@ -190,6 +193,17 @@ export default function Page() {
<PageContainer>
<NavBar>
<PageTitle title="Alerts" />
<PageAccessories>
<WhenAgentUnavailable>
<LinkButton
LeadingIcon={BookOpenIcon}
to={docsPath("v3/troubleshooting-alerts")}
variant="docs/small"
>
Alerts docs
</LinkButton>
</WhenAgentUnavailable>
</PageAccessories>
</NavBar>
<PageBody scrollable={false}>
{alertChannels.length > 0 ? (
@@ -1,4 +1,5 @@
import {
BookOpenIcon,
CheckCircleIcon,
ExclamationTriangleIcon,
KeyIcon,
@@ -74,8 +75,9 @@ import {
import { rbac } from "~/services/rbac.server";
import { dashboardAction, dashboardLoader } from "~/services/routeBuilders/dashboardBuilder";
import { cn } from "~/utils/cn";
import { EnvironmentParamSchema, v3BillingPath } from "~/utils/pathBuilder";
import { docsPath, EnvironmentParamSchema, v3BillingPath } from "~/utils/pathBuilder";
import { sectionAgentPageContext } from "~/components/dashboard-agent/suggested-prompts";
import { WhenAgentUnavailable } from "~/components/dashboard-agent/WhenAgentUnavailable";
import type { Handle } from "~/utils/handle";
export const handle: Handle = {
@@ -340,6 +342,16 @@ export default function Page() {
</Property.Item>
</Property.Table>
</AdminDebugTooltip>
<WhenAgentUnavailable>
<LinkButton
variant="docs/small"
LeadingIcon={BookOpenIcon}
to={docsPath("/v3/apikeys")}
>
API keys docs
</LinkButton>
</WhenAgentUnavailable>
</PageAccessories>
</NavBar>
<PageBody scrollable={false}>
@@ -1,4 +1,5 @@
import { ExclamationCircleIcon } from "@heroicons/react/20/solid";
import { BookOpenIcon } from "@heroicons/react/24/solid";
import { Outlet, useLocation, useNavigation, useParams } from "@remix-run/react";
import { type LoaderFunctionArgs } from "@remix-run/server-runtime";
@@ -55,9 +56,15 @@ import {
runOpsSplitReadEnabled,
type PrismaClientOrTransaction,
} from "~/db.server";
import { EnvironmentParamSchema, v3BatchPath, v3BatchRunsPath } from "~/utils/pathBuilder";
import {
docsPath,
EnvironmentParamSchema,
v3BatchPath,
v3BatchRunsPath,
} from "~/utils/pathBuilder";
import { throwNotFound } from "~/utils/httpErrors";
import { batchesAgentPageContext } from "~/components/dashboard-agent/suggested-prompts";
import { WhenAgentUnavailable } from "~/components/dashboard-agent/WhenAgentUnavailable";
import type { Handle } from "~/utils/handle";
export const handle: Handle = {
@@ -122,6 +129,15 @@ export default function Page() {
<PageTitle title="Batches" />
<PageAccessories>
<AdminDebugTooltip />
<WhenAgentUnavailable>
<LinkButton
variant={"docs/small"}
LeadingIcon={BookOpenIcon}
to={docsPath("/triggering")}
>
Batches docs
</LinkButton>
</WhenAgentUnavailable>
</PageAccessories>
</NavBar>
<PageBody scrollable={false}>
@@ -1,6 +1,7 @@
import { getFormProps, getInputProps, useForm } from "@conform-to/react";
import { parseWithZod } from "@conform-to/zod";
import { ArrowUpCircleIcon, CheckIcon, EnvelopeIcon, PlusIcon } from "@heroicons/react/20/solid";
import { BookOpenIcon } from "@heroicons/react/24/solid";
import { DialogClose } from "@radix-ui/react-dialog";
import { useFetcher, useSearchParams } from "@remix-run/react";
import { type ActionFunctionArgs, json, type LoaderFunctionArgs } from "@remix-run/server-runtime";
@@ -66,6 +67,7 @@ import { requireUserId } from "~/services/session.server";
import { cn } from "~/utils/cn";
import {
branchesPath,
docsPath,
EnvironmentParamSchema,
ProjectParamSchema,
v3BillingPath,
@@ -78,6 +80,7 @@ import { NewBranchPanel } from "~/routes/resources.branches.create";
import { BranchesOptions } from "~/utils/branches";
import { IconArrowBearRight2 } from "@tabler/icons-react";
import { branchesAgentPageContext } from "~/components/dashboard-agent/suggested-prompts";
import { WhenAgentUnavailable } from "~/components/dashboard-agent/WhenAgentUnavailable";
import type { Handle } from "~/utils/handle";
import { pageMeta } from "~/utils/pageTitle";
@@ -256,6 +259,17 @@ export default function Page() {
))}
</Property.Table>
</AdminDebugTooltip>
<WhenAgentUnavailable>
<LinkButton
variant={"docs/small"}
LeadingIcon={BookOpenIcon}
to={docsPath("deployment/preview-branches")}
>
Branches docs
</LinkButton>
</WhenAgentUnavailable>
{limits.isAtLimit ? (
<UpgradePanel
limits={limits}
@@ -1,4 +1,4 @@
import { PlusIcon } from "@heroicons/react/20/solid";
import { BookOpenIcon, PlusIcon } from "@heroicons/react/20/solid";
import { NoSymbolIcon } from "@heroicons/react/24/solid";
import { Outlet, useParams } from "@remix-run/react";
import { type LoaderFunctionArgs } from "@remix-run/server-runtime";
@@ -49,11 +49,13 @@ import { checkPermissions } from "~/services/routeBuilders/permissions.server";
import { requireUserId } from "~/services/session.server";
import { cn } from "~/utils/cn";
import {
docsPath,
EnvironmentParamSchema,
v3BulkActionPath,
v3CreateBulkActionPath,
} from "~/utils/pathBuilder";
import { bulkActionsAgentPageContext } from "~/components/dashboard-agent/suggested-prompts";
import { WhenAgentUnavailable } from "~/components/dashboard-agent/WhenAgentUnavailable";
import type { Handle } from "~/utils/handle";
export const handle: Handle = {
@@ -140,6 +142,15 @@ export default function Page() {
<PageTitle title="Bulk actions" />
<PageAccessories>
<AdminDebugTooltip />
<WhenAgentUnavailable>
<LinkButton
variant={"docs/small"}
LeadingIcon={BookOpenIcon}
to={docsPath("/bulk-actions")}
>
Bulk actions docs
</LinkButton>
</WhenAgentUnavailable>
<LinkButton
variant="primary/small"
LeadingIcon={PlusIcon}
@@ -1,4 +1,9 @@
import { ArrowPathIcon, ArrowUturnLeftIcon, NoSymbolIcon } from "@heroicons/react/20/solid";
import {
ArrowPathIcon,
ArrowUturnLeftIcon,
BookOpenIcon,
NoSymbolIcon,
} from "@heroicons/react/20/solid";
import { Form, Outlet, useLocation, useNavigate, useNavigation, useParams } from "@remix-run/react";
import { type LoaderFunctionArgs } from "@remix-run/server-runtime";
@@ -26,7 +31,7 @@ import {
DialogTrigger,
DialogFooter,
} from "~/components/primitives/Dialog";
import { NavBar, PageTitle } from "~/components/primitives/PageHeader";
import { NavBar, PageAccessories, PageTitle } from "~/components/primitives/PageHeader";
import { PaginationControls } from "~/components/primitives/Pagination";
import { Paragraph } from "~/components/primitives/Paragraph";
import {
@@ -66,6 +71,7 @@ import { titleCase } from "~/utils";
import { cn } from "~/utils/cn";
import {
EnvironmentParamSchema,
docsPath,
v3DeploymentPath,
v3ProjectSettingsIntegrationsPath,
} from "~/utils/pathBuilder";
@@ -75,6 +81,7 @@ import { useAutoRevalidate } from "~/hooks/useAutoRevalidate";
import { env } from "~/env.server";
import { DialogClose } from "@radix-ui/react-dialog";
import { deploymentsAgentPageContext } from "~/components/dashboard-agent/suggested-prompts";
import { WhenAgentUnavailable } from "~/components/dashboard-agent/WhenAgentUnavailable";
import type { Handle } from "~/utils/handle";
export const handle: Handle = {
@@ -199,6 +206,17 @@ export default function Page() {
<PageContainer>
<NavBar>
<PageTitle title="Deployments" />
<PageAccessories>
<WhenAgentUnavailable>
<LinkButton
variant={"docs/small"}
LeadingIcon={BookOpenIcon}
to={docsPath("/cli-deploy")}
>
Deployments docs
</LinkButton>
</WhenAgentUnavailable>
</PageAccessories>
</NavBar>
<PageBody scrollable={false}>
<ResizablePanelGroup orientation="horizontal" className="h-full max-h-full">
@@ -1,4 +1,5 @@
import { CheckIcon, PlusIcon } from "@heroicons/react/20/solid";
import { BookOpenIcon } from "@heroicons/react/24/solid";
import { useSearchParams } from "@remix-run/react";
import { type LoaderFunctionArgs } from "@remix-run/server-runtime";
import { useCallback } from "react";
@@ -39,13 +40,14 @@ import { BranchesPresenter } from "~/presenters/v3/BranchesPresenter.server";
import { logger } from "~/services/logger.server";
import { requireUserId } from "~/services/session.server";
import { cn } from "~/utils/cn";
import { branchesDevPath, ProjectParamSchema } from "~/utils/pathBuilder";
import { branchesDevPath, docsPath, ProjectParamSchema } from "~/utils/pathBuilder";
import { ArchiveButton } from "../resources.branches.archive";
import { NewBranchPanel } from "~/routes/resources.branches.create";
import { BranchesOptions } from "~/utils/branches";
import { IconArrowBearRight2 } from "@tabler/icons-react";
import { useAutoRevalidate } from "~/hooks/useAutoRevalidate";
import { branchesAgentPageContext } from "~/components/dashboard-agent/suggested-prompts";
import { WhenAgentUnavailable } from "~/components/dashboard-agent/WhenAgentUnavailable";
import type { Handle } from "~/utils/handle";
import { pageMeta } from "~/utils/pageTitle";
@@ -110,6 +112,17 @@ export default function Page() {
))}
</Property.Table>
</AdminDebugTooltip>
<WhenAgentUnavailable>
<LinkButton
variant={"docs/small"}
LeadingIcon={BookOpenIcon}
to={docsPath("deployment/dev-branches")}
>
Dev branches docs
</LinkButton>
</WhenAgentUnavailable>
{limits.isAtLimit ? (
<BranchLimitReachedDialog limits={limits} />
) : (
@@ -1,6 +1,7 @@
import { getFormProps, getInputProps, useForm } from "@conform-to/react";
import { parseWithZod } from "@conform-to/zod";
import {
BookOpenIcon,
InformationCircleIcon,
LockClosedIcon,
NoSymbolIcon,
@@ -38,7 +39,7 @@ import { Header2 } from "~/components/primitives/Headers";
import { Input } from "~/components/primitives/Input";
import { InputGroup } from "~/components/primitives/InputGroup";
import { Label } from "~/components/primitives/Label";
import { NavBar, PageTitle } from "~/components/primitives/PageHeader";
import { NavBar, PageAccessories, PageTitle } from "~/components/primitives/PageHeader";
import { Paragraph } from "~/components/primitives/Paragraph";
import { SearchInput } from "~/components/primitives/SearchInput";
import { Switch } from "~/components/primitives/Switch";
@@ -71,6 +72,7 @@ import { VercelIntegrationService } from "~/services/vercelIntegration.server";
import { cn } from "~/utils/cn";
import {
EnvironmentParamSchema,
docsPath,
v3EnvironmentVariablesPath,
v3NewEnvironmentVariablesPath,
} from "~/utils/pathBuilder";
@@ -86,6 +88,7 @@ import {
type TriggerEnvironmentType,
} from "~/v3/vercel/vercelProjectIntegrationSchema";
import { sectionAgentPageContext } from "~/components/dashboard-agent/suggested-prompts";
import { WhenAgentUnavailable } from "~/components/dashboard-agent/WhenAgentUnavailable";
import type { Handle } from "~/utils/handle";
export const handle: Handle = {
@@ -460,6 +463,17 @@ function EnvironmentVariablesListPage({
<PageContainer>
<NavBar>
<PageTitle title="Environment variables" />
<PageAccessories>
<WhenAgentUnavailable>
<LinkButton
LeadingIcon={BookOpenIcon}
to={docsPath("v3/deploy-environment-variables")}
variant="docs/small"
>
Environment variables docs
</LinkButton>
</WhenAgentUnavailable>
</PageAccessories>
</NavBar>
<PageBody scrollable={false}>
<div className={cn("flex h-full min-h-0 flex-col")}>
@@ -1,4 +1,4 @@
import { CheckIcon } from "@heroicons/react/20/solid";
import { CheckIcon, BookOpenIcon } from "@heroicons/react/20/solid";
import { type LoaderFunctionArgs } from "@remix-run/server-runtime";
import { IconCardsFilled, IconDiamondFilled, IconTallymark4 } from "@tabler/icons-react";
@@ -44,10 +44,12 @@ import { cn } from "~/utils/cn";
import { formatNumber } from "~/utils/numberFormatter";
import {
concurrencyPath,
docsPath,
EnvironmentParamSchema,
organizationBillingPath,
} from "~/utils/pathBuilder";
import { limitsAgentPageContext } from "~/components/dashboard-agent/suggested-prompts";
import { WhenAgentUnavailable } from "~/components/dashboard-agent/WhenAgentUnavailable";
import type { Handle } from "~/utils/handle";
export const handle: Handle = {
@@ -130,6 +132,11 @@ export default function Page() {
</Property.Item>
</Property.Table>
</AdminDebugTooltip>
<WhenAgentUnavailable>
<LinkButton variant={"docs/small"} LeadingIcon={BookOpenIcon} to={docsPath("/limits")}>
Limits docs
</LinkButton>
</WhenAgentUnavailable>
</PageAccessories>
</NavBar>
<PageBody scrollable={true}>
@@ -14,7 +14,7 @@ import { MainCenteredContainer, PageBody, PageContainer } from "~/components/lay
import { TruncatedCopyableValue } from "~/components/primitives/TruncatedCopyableValue";
import { DateTime, formatDateTime } from "~/components/primitives/DateTime";
import { Header3 } from "~/components/primitives/Headers";
import { NavBar, PageTitle } from "~/components/primitives/PageHeader";
import { NavBar, PageAccessories, PageTitle } from "~/components/primitives/PageHeader";
import { Paragraph } from "~/components/primitives/Paragraph";
import TooltipPortal from "~/components/primitives/TooltipPortal";
import { cn } from "~/utils/cn";
@@ -35,7 +35,10 @@ import { findEnvironmentBySlug } from "~/models/runtimeEnvironment.server";
import { PromptPresenter } from "~/presenters/v3/PromptPresenter.server";
import { clickhouseFactory } from "~/services/clickhouse/clickhouseFactoryInstance.server";
import { requireUserId } from "~/services/session.server";
import { EnvironmentParamSchema, v3PromptsPath } from "~/utils/pathBuilder";
import { docsPath, EnvironmentParamSchema, v3PromptsPath } from "~/utils/pathBuilder";
import { LinkButton } from "~/components/primitives/Buttons";
import { BookOpenIcon } from "@heroicons/react/24/solid";
import { WhenAgentUnavailable } from "~/components/dashboard-agent/WhenAgentUnavailable";
import { promptsAgentPageContext } from "~/components/dashboard-agent/suggested-prompts";
import type { Handle } from "~/utils/handle";
@@ -101,6 +104,13 @@ export default function PromptsPage() {
<PageContainer>
<NavBar>
<PageTitle title="Prompts" />
<PageAccessories>
<WhenAgentUnavailable>
<LinkButton variant="docs/small" LeadingIcon={BookOpenIcon} to={docsPath("ai/prompts")}>
Prompts docs
</LinkButton>
</WhenAgentUnavailable>
</PageAccessories>
</NavBar>
<PageBody scrollable={false}>
<Table containerClassName="border-t-0">
@@ -94,6 +94,7 @@ import {
} from "~/utils/pathBuilder";
import type { Handle } from "~/utils/handle";
import { queuesAgentPageContext } from "~/components/dashboard-agent/suggested-prompts";
import { WhenAgentUnavailable } from "~/components/dashboard-agent/WhenAgentUnavailable";
import { PauseEnvironmentService } from "~/v3/services/pauseEnvironment.server";
import { handleQueueMutationAction } from "~/models/queueMutation.server";
import {
@@ -477,6 +478,15 @@ function QueuesWithMetricsView() {
<PageTitle title="Queues" />
<PageAccessories>
<AdminDebugTooltip />
<WhenAgentUnavailable>
<LinkButton
variant={"docs/small"}
LeadingIcon={BookOpenIcon}
to={docsPath("/queue-concurrency")}
>
Queues docs
</LinkButton>
</WhenAgentUnavailable>
</PageAccessories>
</NavBar>
<MetricsLayout.Root>
@@ -1683,6 +1693,15 @@ function ClassicQueuesView() {
<PageTitle title="Queues" />
<PageAccessories>
<AdminDebugTooltip />
<WhenAgentUnavailable>
<LinkButton
variant={"docs/small"}
LeadingIcon={BookOpenIcon}
to={docsPath("/queue-concurrency")}
>
Queues docs
</LinkButton>
</WhenAgentUnavailable>
</PageAccessories>
</NavBar>
<PageBody scrollable={false}>
@@ -1,6 +1,7 @@
import {
ArrowUturnLeftIcon,
BoltSlashIcon,
BookOpenIcon,
ChevronDownIcon,
ChevronRightIcon,
InformationCircleIcon,
@@ -106,10 +107,12 @@ import { getResizableSnapshot } from "~/services/resizablePanel.server";
import { requireUserId } from "~/services/session.server";
import { rbac } from "~/services/rbac.server";
import { runAgentPageContext } from "~/components/dashboard-agent/suggested-prompts";
import { WhenAgentUnavailable } from "~/components/dashboard-agent/WhenAgentUnavailable";
import { cn } from "~/utils/cn";
import type { Handle } from "~/utils/handle";
import { lerp } from "~/utils/lerp";
import {
docsPath,
v3BillingPath,
v3RunParamsSchema,
v3RunPath,
@@ -520,6 +523,11 @@ export default function Page() {
</Property.Item>
</Property.Table>
</AdminDebugTooltip>
<WhenAgentUnavailable>
<LinkButton variant={"docs/small"} LeadingIcon={BookOpenIcon} to={docsPath("/runs")}>
Run docs
</LinkButton>
</WhenAgentUnavailable>
<Dialog key={`replay-${run.friendlyId}`}>
<DialogTrigger asChild>
<Button
@@ -79,6 +79,7 @@ import {
shouldRevalidateRunsList,
} from "./shouldRevalidateRunsList";
import { useRunsLiveReload } from "./useRunsLiveReload";
import { WhenAgentUnavailable } from "~/components/dashboard-agent/WhenAgentUnavailable";
import { pageMeta } from "~/utils/pageTitle";
export { shouldRevalidateRunsList as shouldRevalidate };
@@ -177,6 +178,15 @@ export default function Page() {
)}
<PageAccessories>
<AdminDebugTooltip />
<WhenAgentUnavailable>
<LinkButton
variant={"docs/small"}
LeadingIcon={BookOpenIcon}
to={docsPath("/runs-and-attempts")}
>
Runs docs
</LinkButton>
</WhenAgentUnavailable>
</PageAccessories>
</NavBar>
<PageBody scrollable={false}>
@@ -1,5 +1,5 @@
import { BoltIcon, BoltSlashIcon } from "@heroicons/react/20/solid";
import { CheckIcon } from "@heroicons/react/24/solid";
import { BookOpenIcon, CheckIcon } from "@heroicons/react/24/solid";
import { type LoaderFunctionArgs } from "@remix-run/server-runtime";
import { useVirtualizer } from "@tanstack/react-virtual";
@@ -21,7 +21,7 @@ import { Button, LinkButton } from "~/components/primitives/Buttons";
import { CopyableText } from "~/components/primitives/CopyableText";
import { DateTime } from "~/components/primitives/DateTime";
import { Dialog, DialogTrigger } from "~/components/primitives/Dialog";
import { NavBar, PageTitle } from "~/components/primitives/PageHeader";
import { NavBar, PageAccessories, PageTitle } from "~/components/primitives/PageHeader";
import { Paragraph } from "~/components/primitives/Paragraph";
import * as Property from "~/components/primitives/PropertyTable";
import {
@@ -65,8 +65,15 @@ import { requireUserId } from "~/services/session.server";
import { type SessionStatus } from "~/services/sessionsRepository/sessionsRepository.server";
import { cn } from "~/utils/cn";
import { throwNotFound } from "~/utils/httpErrors";
import { EnvironmentParamSchema, v3RunPath, v3RunsPath, v3SessionsPath } from "~/utils/pathBuilder";
import {
docsPath,
EnvironmentParamSchema,
v3RunPath,
v3RunsPath,
v3SessionsPath,
} from "~/utils/pathBuilder";
import { sessionsAgentPageContext } from "~/components/dashboard-agent/suggested-prompts";
import { WhenAgentUnavailable } from "~/components/dashboard-agent/WhenAgentUnavailable";
import type { Handle } from "~/utils/handle";
import { pageMeta } from "~/utils/pageTitle";
@@ -139,6 +146,17 @@ export default function Page() {
</span>
}
/>
<PageAccessories>
<WhenAgentUnavailable>
<LinkButton
variant={"docs/small"}
LeadingIcon={BookOpenIcon}
to={docsPath("/ai-chat/sessions")}
>
Sessions docs
</LinkButton>
</WhenAgentUnavailable>
</PageAccessories>
</NavBar>
<PageBody scrollable={false}>
<ResizablePanelGroup orientation="horizontal" className="max-h-full">
@@ -1,3 +1,4 @@
import { BookOpenIcon } from "@heroicons/react/24/solid";
import { type LoaderFunctionArgs } from "@remix-run/server-runtime";
import { typedjson, useTypedLoaderData } from "remix-typedjson";
import { QuestionMarkIcon } from "~/assets/icons/QuestionMarkIcon";
@@ -5,6 +6,7 @@ import { InlineCode } from "~/components/code/InlineCode";
import { ListPagination } from "~/components/ListPagination";
import { AdminDebugTooltip } from "~/components/admin/debugTooltip";
import { MainCenteredContainer, PageBody } from "~/components/layout/AppLayout";
import { LinkButton } from "~/components/primitives/Buttons";
import { NavBar, PageAccessories, PageTitle } from "~/components/primitives/PageHeader";
import { Paragraph } from "~/components/primitives/Paragraph";
import { SimpleTooltip } from "~/components/primitives/Tooltip";
@@ -19,9 +21,10 @@ import { getSessionFiltersFromRequest } from "~/presenters/SessionFilters.server
import { SessionListPresenter } from "~/presenters/v3/SessionListPresenter.server";
import { clickhouseFactory } from "~/services/clickhouse/clickhouseFactoryInstance.server";
import { requireUserId } from "~/services/session.server";
import { EnvironmentParamSchema } from "~/utils/pathBuilder";
import { docsPath, EnvironmentParamSchema } from "~/utils/pathBuilder";
import { throwNotFound } from "~/utils/httpErrors";
import { sessionsAgentPageContext } from "~/components/dashboard-agent/suggested-prompts";
import { WhenAgentUnavailable } from "~/components/dashboard-agent/WhenAgentUnavailable";
import type { Handle } from "~/utils/handle";
export const handle: Handle = {
@@ -79,6 +82,15 @@ export default function Page() {
<PageTitle title="Sessions" accessory={<SessionsHelpTooltip />} />
<PageAccessories>
<AdminDebugTooltip />
<WhenAgentUnavailable>
<LinkButton
variant={"docs/small"}
LeadingIcon={BookOpenIcon}
to={docsPath("ai-chat/sessions")}
>
Sessions docs
</LinkButton>
</WhenAgentUnavailable>
</PageAccessories>
</NavBar>
<PageBody scrollable={false}>
@@ -1,13 +1,14 @@
import { MagnifyingGlassIcon } from "@heroicons/react/20/solid";
import { BookOpenIcon, MagnifyingGlassIcon } from "@heroicons/react/20/solid";
import { Outlet, useParams } from "@remix-run/react";
import { type LoaderFunctionArgs } from "@remix-run/server-runtime";
import { typedjson, useTypedLoaderData } from "remix-typedjson";
import { TestHasNoTasks } from "~/components/BlankStatePanels";
import { MainCenteredContainer, PageBody, PageContainer } from "~/components/layout/AppLayout";
import { LinkButton } from "~/components/primitives/Buttons";
import { Callout } from "~/components/primitives/Callout";
import { Input } from "~/components/primitives/Input";
import { NavBar, PageTitle } from "~/components/primitives/PageHeader";
import { NavBar, PageAccessories, PageTitle } from "~/components/primitives/PageHeader";
import { Paragraph } from "~/components/primitives/Paragraph";
import { RadioButtonCircle } from "~/components/primitives/RadioButton";
import {
@@ -35,8 +36,9 @@ import { findEnvironmentBySlug } from "~/models/runtimeEnvironment.server";
import { type TaskListItem, TestPresenter } from "~/presenters/v3/TestPresenter.server";
import { requireUserId } from "~/services/session.server";
import { cn } from "~/utils/cn";
import { EnvironmentParamSchema, v3TestTaskPath } from "~/utils/pathBuilder";
import { docsPath, EnvironmentParamSchema, v3TestTaskPath } from "~/utils/pathBuilder";
import { testAgentPageContext } from "~/components/dashboard-agent/suggested-prompts";
import { WhenAgentUnavailable } from "~/components/dashboard-agent/WhenAgentUnavailable";
import type { Handle } from "~/utils/handle";
export const handle: Handle = {
@@ -86,6 +88,17 @@ export default function Page() {
<PageContainer>
<NavBar>
<PageTitle title="Test" />
<PageAccessories>
<WhenAgentUnavailable>
<LinkButton
variant={"docs/small"}
LeadingIcon={BookOpenIcon}
to={docsPath("/run-tests")}
>
Test docs
</LinkButton>
</WhenAgentUnavailable>
</PageAccessories>
</NavBar>
<PageBody scrollable={false}>
{tasks.length === 0 ? (
@@ -1,3 +1,4 @@
import { BookOpenIcon } from "@heroicons/react/20/solid";
import { Outlet, useParams } from "@remix-run/react";
import { type LoaderFunctionArgs } from "@remix-run/server-runtime";
@@ -6,6 +7,7 @@ import { AdminDebugTooltip } from "~/components/admin/debugTooltip";
import { NoWaitpointTokens } from "~/components/BlankStatePanels";
import { MainCenteredContainer, PageBody, PageContainer } from "~/components/layout/AppLayout";
import { ListPagination } from "~/components/ListPagination";
import { LinkButton } from "~/components/primitives/Buttons";
import { ClipboardField } from "~/components/primitives/ClipboardField";
import { CopyableText } from "~/components/primitives/CopyableText";
import { DateTime } from "~/components/primitives/DateTime";
@@ -47,8 +49,9 @@ import {
runOpsSplitReadEnabled,
type PrismaClientOrTransaction,
} from "~/db.server";
import { EnvironmentParamSchema, v3WaitpointTokenPath } from "~/utils/pathBuilder";
import { docsPath, EnvironmentParamSchema, v3WaitpointTokenPath } from "~/utils/pathBuilder";
import { waitpointsAgentPageContext } from "~/components/dashboard-agent/suggested-prompts";
import { WhenAgentUnavailable } from "~/components/dashboard-agent/WhenAgentUnavailable";
import type { Handle } from "~/utils/handle";
export const handle: Handle = {
@@ -138,6 +141,11 @@ export default function Page() {
<PageTitle title={<V4Title>Waitpoint Tokens</V4Title>} />
<PageAccessories>
<AdminDebugTooltip />
<WhenAgentUnavailable>
<LinkButton variant={"docs/small"} LeadingIcon={BookOpenIcon} to={docsPath("/wait")}>
Waitpoints docs
</LinkButton>
</WhenAgentUnavailable>
</PageAccessories>
</NavBar>
<PageBody scrollable={false}>
@@ -20,7 +20,7 @@ import { Header2, Header3 } from "~/components/primitives/Headers";
import { Input } from "~/components/primitives/Input";
import { InputGroup } from "~/components/primitives/InputGroup";
import { Label } from "~/components/primitives/Label";
import { NavBar, PageTitle } from "~/components/primitives/PageHeader";
import { NavBar, PageAccessories, PageTitle } from "~/components/primitives/PageHeader";
import { Paragraph } from "~/components/primitives/Paragraph";
import { Select, SelectItem } from "~/components/primitives/Select";
import { prisma } from "~/db.server";
@@ -38,12 +38,14 @@ import {
} from "~/utils/pathBuilder";
import {
ArrowTopRightOnSquareIcon,
BookOpenIcon,
CommandLineIcon,
DocumentTextIcon,
PencilSquareIcon,
SparklesIcon,
TrashIcon,
} from "@heroicons/react/20/solid";
import { WhenAgentUnavailable } from "~/components/dashboard-agent/WhenAgentUnavailable";
import { pageMeta } from "~/utils/pageTitle";
export const meta = pageMeta("Add Private Connection");
@@ -552,6 +554,17 @@ export default function Page() {
text: "Private Connections",
}}
/>
<PageAccessories>
<WhenAgentUnavailable>
<LinkButton
variant="docs/small"
LeadingIcon={BookOpenIcon}
to={docsPath("private-networking/overview")}
>
Private connection docs
</LinkButton>
</WhenAgentUnavailable>
</PageAccessories>
</NavBar>
<PageBody scrollable={true}>
<MainHorizontallyCenteredContainer className="max-w-3xl">
@@ -1,6 +1,6 @@
import { getFormProps, getInputProps, useForm } from "@conform-to/react";
import { parseWithZod } from "@conform-to/zod";
import { ShieldCheckIcon, TrashIcon } from "@heroicons/react/20/solid";
import { BookOpenIcon, ShieldCheckIcon, TrashIcon } from "@heroicons/react/20/solid";
import { ShieldExclamationIcon } from "@heroicons/react/24/solid";
import { DialogClose } from "@radix-ui/react-dialog";
import { Form, useActionData, useFetcher } from "@remix-run/react";
@@ -9,7 +9,7 @@ import { useState } from "react";
import { typedjson, useTypedLoaderData } from "remix-typedjson";
import { z } from "zod";
import { PageBody, PageContainer } from "~/components/layout/AppLayout";
import { Button } from "~/components/primitives/Buttons";
import { Button, LinkButton } from "~/components/primitives/Buttons";
import { Callout } from "~/components/primitives/Callout";
import { ClipboardField } from "~/components/primitives/ClipboardField";
import { DateTime } from "~/components/primitives/DateTime";
@@ -46,8 +46,9 @@ import {
revokePersonalAccessToken,
} from "~/services/personalAccessToken.server";
import { requireUserId } from "~/services/session.server";
import { personalAccessTokensPath } from "~/utils/pathBuilder";
import { docsPath, personalAccessTokensPath } from "~/utils/pathBuilder";
import { WhenAgentUnavailable } from "~/components/dashboard-agent/WhenAgentUnavailable";
import { pageMeta } from "~/utils/pageTitle";
export const meta = pageMeta("Personal Access Tokens");
@@ -247,6 +248,15 @@ export default function Page() {
<NavBar>
<PageTitle title="Personal Access Tokens" />
<PageAccessories>
<WhenAgentUnavailable>
<LinkButton
LeadingIcon={BookOpenIcon}
to={docsPath("management/overview#personal-access-token-pat")}
variant="docs/small"
>
Personal Access Token docs
</LinkButton>
</WhenAgentUnavailable>
<Dialog>
<DialogTrigger asChild>
<Button variant="primary/small">Create new token</Button>
+1 -1
View File
@@ -838,7 +838,7 @@ export function docsRoot() {
}
export function docsPath(path: string) {
return `${docsRoot()}/${path}`;
return `${docsRoot()}/${path.replace(/^\//, "")}`;
}
export function docsTroubleshootingPath(path: string) {