mirror of
https://github.com/rowboatlabs/rowboat.git
synced 2026-05-31 19:15:17 +02:00
Add navigation CTAs in testing section
This commit is contained in:
parent
ff15e55c6d
commit
51166c19b4
10 changed files with 46 additions and 56 deletions
|
|
@ -13,7 +13,7 @@ import { Button, Spinner, Tooltip } from "@heroui/react";
|
|||
import { apiV1 } from "rowboat-shared";
|
||||
import { CopyAsJsonButton } from "./copy-as-json-button";
|
||||
import { TestProfile } from "@/app/lib/types/testing_types";
|
||||
import { ProfileSelector } from "@/app/lib/components/selectors/profile-selector";
|
||||
import { ProfileSelector } from "@/app/projects/[projectId]/test/[[...slug]]/components/selectors/profile-selector";
|
||||
import { WithStringId } from "@/app/lib/types/types";
|
||||
import { XCircleIcon, XIcon } from "lucide-react";
|
||||
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ import { useCallback, useEffect, useState } from "react";
|
|||
import { listProfiles } from "@/app/actions/testing_actions";
|
||||
import { Button, Pagination, Spinner, Modal, ModalContent, ModalHeader, ModalBody, ModalFooter } from "@heroui/react";
|
||||
import { z } from "zod";
|
||||
import { useRouter } from "next/navigation";
|
||||
|
||||
interface ProfileSelectorProps {
|
||||
projectId: string;
|
||||
|
|
@ -19,6 +20,7 @@ export function ProfileSelector({ projectId, isOpen, onOpenChange, onSelect }: P
|
|||
const [profiles, setProfiles] = useState<WithStringId<z.infer<typeof TestProfile>>[]>([]);
|
||||
const [totalPages, setTotalPages] = useState(0);
|
||||
const pageSize = 10;
|
||||
const router = useRouter();
|
||||
|
||||
const fetchProfiles = useCallback(async (page: number) => {
|
||||
setLoading(true);
|
||||
|
|
@ -58,10 +60,10 @@ export function ProfileSelector({ projectId, isOpen, onOpenChange, onSelect }: P
|
|||
{!loading && !error && <>
|
||||
{profiles.length === 0 && <div className="text-gray-600 text-center">No profiles found</div>}
|
||||
{profiles.length > 0 && <div className="flex flex-col w-full">
|
||||
<div className="grid grid-cols-6 py-2 bg-gray-100 font-semibold text-sm">
|
||||
<div className="col-span-2 px-4">Name</div>
|
||||
<div className="col-span-3 px-4">Context</div>
|
||||
<div className="col-span-1 px-4">Mock Tools</div>
|
||||
<div className="grid grid-cols-6 py-2 bg-gray-100 dark:bg-gray-800 font-semibold text-sm">
|
||||
<div className="col-span-2 px-4 text-gray-900 dark:text-gray-100">Name</div>
|
||||
<div className="col-span-3 px-4 text-gray-900 dark:text-gray-100">Context</div>
|
||||
<div className="col-span-1 px-4 text-gray-900 dark:text-gray-100">Mock Tools</div>
|
||||
</div>
|
||||
|
||||
{profiles.map((p) => (
|
||||
|
|
@ -88,9 +90,18 @@ export function ProfileSelector({ projectId, isOpen, onOpenChange, onSelect }: P
|
|||
</>}
|
||||
</ModalBody>
|
||||
<ModalFooter>
|
||||
<div className="flex gap-2">
|
||||
<Button
|
||||
size="sm"
|
||||
color="primary"
|
||||
onPress={() => router.push(`/projects/${projectId}/test/profiles`)}
|
||||
>
|
||||
Manage Profiles
|
||||
</Button>
|
||||
<Button size="sm" variant="flat" onPress={onClose}>
|
||||
Cancel
|
||||
</Button>
|
||||
</div>
|
||||
</ModalFooter>
|
||||
</>
|
||||
)}
|
||||
|
|
@ -4,6 +4,7 @@ import { useCallback, useEffect, useState } from "react";
|
|||
import { listScenarios } from "@/app/actions/testing_actions";
|
||||
import { Button, Pagination, Spinner, Modal, ModalContent, ModalHeader, ModalBody, ModalFooter } from "@heroui/react";
|
||||
import { z } from "zod";
|
||||
import { useRouter } from "next/navigation";
|
||||
|
||||
interface ScenarioSelectorProps {
|
||||
projectId: string;
|
||||
|
|
@ -13,6 +14,7 @@ interface ScenarioSelectorProps {
|
|||
}
|
||||
|
||||
export function ScenarioSelector({ projectId, isOpen, onOpenChange, onSelect }: ScenarioSelectorProps) {
|
||||
const router = useRouter();
|
||||
const [page, setPage] = useState(1);
|
||||
const [loading, setLoading] = useState(false);
|
||||
const [error, setError] = useState<string | null>(null);
|
||||
|
|
@ -58,9 +60,9 @@ export function ScenarioSelector({ projectId, isOpen, onOpenChange, onSelect }:
|
|||
{!loading && !error && <>
|
||||
{scenarios.length === 0 && <div className="text-gray-600 text-center">No scenarios found</div>}
|
||||
{scenarios.length > 0 && <div className="flex flex-col w-full">
|
||||
<div className="grid grid-cols-5 py-2 bg-gray-100 font-semibold text-sm">
|
||||
<div className="col-span-2 px-4">Name</div>
|
||||
<div className="col-span-3 px-4">Description</div>
|
||||
<div className="grid grid-cols-5 py-2 bg-gray-100 dark:bg-gray-800 font-semibold text-sm">
|
||||
<div className="col-span-2 px-4 text-gray-900 dark:text-gray-100">Name</div>
|
||||
<div className="col-span-3 px-4 text-gray-900 dark:text-gray-100">Description</div>
|
||||
</div>
|
||||
|
||||
{scenarios.map((s) => (
|
||||
|
|
@ -86,9 +88,18 @@ export function ScenarioSelector({ projectId, isOpen, onOpenChange, onSelect }:
|
|||
</>}
|
||||
</ModalBody>
|
||||
<ModalFooter>
|
||||
<div className="flex gap-2">
|
||||
<Button
|
||||
size="sm"
|
||||
color="primary"
|
||||
onPress={() => router.push(`/projects/${projectId}/test/scenarios`)}
|
||||
>
|
||||
Manage Scenarios
|
||||
</Button>
|
||||
<Button size="sm" variant="flat" onPress={onClose}>
|
||||
Cancel
|
||||
</Button>
|
||||
</div>
|
||||
</ModalFooter>
|
||||
</>
|
||||
)}
|
||||
|
|
@ -5,7 +5,7 @@ import { listWorkflows } from "@/app/actions/workflow_actions";
|
|||
import { Button, Pagination, Spinner, Modal, ModalContent, ModalHeader, ModalBody, ModalFooter } from "@heroui/react";
|
||||
import { z } from "zod";
|
||||
import { RelativeTime } from "@primer/react";
|
||||
import { WorkflowIcon } from "../icons";
|
||||
import { WorkflowIcon } from "../../../../../../lib/components/icons";
|
||||
import { PublishedBadge } from "@/app/projects/[projectId]/workflow/published_badge";
|
||||
|
||||
interface WorkflowSelectorProps {
|
||||
|
|
@ -2,8 +2,8 @@ import { FormStatusButton } from "@/app/lib/components/form-status-button";
|
|||
import { Button, Input, Textarea } from "@heroui/react";
|
||||
import { TestProfile, TestScenario } from "@/app/lib/types/testing_types";
|
||||
import { WithStringId } from "@/app/lib/types/types";
|
||||
import { ScenarioSelector } from "@/app/lib/components/selectors/scenario-selector";
|
||||
import { ProfileSelector } from "@/app/lib/components/selectors/profile-selector";
|
||||
import { ScenarioSelector } from "@/app/projects/[projectId]/test/[[...slug]]/components/selectors/scenario-selector";
|
||||
import { ProfileSelector } from "@/app/projects/[projectId]/test/[[...slug]]/components/selectors/profile-selector";
|
||||
import { z } from "zod";
|
||||
|
||||
interface SimulationFormProps {
|
||||
|
|
|
|||
|
|
@ -288,15 +288,7 @@ function ProfileList({
|
|||
</div>
|
||||
) : profiles.length === 0 ? (
|
||||
<div className="text-center p-8 bg-gray-50 dark:bg-neutral-900 rounded-lg border border-dashed border-gray-200 dark:border-neutral-800">
|
||||
<p className="text-gray-600 dark:text-neutral-400 mb-4">No profiles created yet</p>
|
||||
<Button
|
||||
size="sm"
|
||||
color="primary"
|
||||
startContent={<PlusIcon size={16} />}
|
||||
onPress={() => router.push(`/projects/${projectId}/test/profiles/new`)}
|
||||
>
|
||||
Create Your First Profile
|
||||
</Button>
|
||||
<p className="text-gray-600 dark:text-neutral-400">No profiles created yet</p>
|
||||
</div>
|
||||
) : (
|
||||
<DataTable
|
||||
|
|
|
|||
|
|
@ -393,15 +393,7 @@ function RunsList({ projectId }: { projectId: string }) {
|
|||
</div>
|
||||
) : runs.length === 0 ? (
|
||||
<div className="text-center p-8 bg-gray-50 dark:bg-neutral-900 rounded-lg border border-dashed border-gray-200 dark:border-neutral-800">
|
||||
<p className="text-gray-600 dark:text-neutral-400 mb-4">No test runs created yet</p>
|
||||
<Button
|
||||
size="sm"
|
||||
color="primary"
|
||||
startContent={<PlusIcon size={16} />}
|
||||
onPress={() => router.push(`/projects/${projectId}/test/simulations`)}
|
||||
>
|
||||
Create Your First Test Run
|
||||
</Button>
|
||||
<p className="text-gray-600 dark:text-neutral-400">No test runs created yet</p>
|
||||
</div>
|
||||
) : (
|
||||
<DataTable
|
||||
|
|
|
|||
|
|
@ -393,15 +393,7 @@ function ScenarioList({
|
|||
</div>
|
||||
) : scenarios.length === 0 ? (
|
||||
<div className="text-center p-8 bg-gray-50 dark:bg-neutral-900 rounded-lg border border-dashed border-gray-200 dark:border-neutral-800">
|
||||
<p className="text-gray-600 dark:text-neutral-400 mb-4">No scenarios created yet</p>
|
||||
<Button
|
||||
size="sm"
|
||||
color="primary"
|
||||
startContent={<PlusIcon size={16} />}
|
||||
onPress={() => router.push(`/projects/${projectId}/test/scenarios/new`)}
|
||||
>
|
||||
Create Your First Scenario
|
||||
</Button>
|
||||
<p className="text-gray-600 dark:text-neutral-400">No scenarios created yet</p>
|
||||
</div>
|
||||
) : (
|
||||
<DataTable
|
||||
|
|
|
|||
|
|
@ -11,10 +11,10 @@ import { useRouter, useSearchParams } from "next/navigation";
|
|||
import { z } from "zod";
|
||||
import { PlusIcon, ArrowLeftIcon, AlertTriangleIcon } from "lucide-react";
|
||||
import { RelativeTime } from "@primer/react"
|
||||
import { ScenarioSelector } from "@/app/lib/components/selectors/scenario-selector";
|
||||
import { ProfileSelector } from "@/app/lib/components/selectors/profile-selector";
|
||||
import { ScenarioSelector } from "@/app/projects/[projectId]/test/[[...slug]]/components/selectors/scenario-selector";
|
||||
import { ProfileSelector } from "@/app/projects/[projectId]/test/[[...slug]]/components/selectors/profile-selector";
|
||||
import { StructuredPanel, ActionButton } from "@/app/lib/components/structured-panel";
|
||||
import { WorkflowSelector } from "@/app/lib/components/selectors/workflow-selector";
|
||||
import { WorkflowSelector } from "@/app/projects/[projectId]/test/[[...slug]]/components/selectors/workflow-selector";
|
||||
import { DataTable } from "./components/table"
|
||||
import { isValidDate } from './utils/date';
|
||||
import { SimulationForm } from "./components/simulation-form";
|
||||
|
|
@ -542,15 +542,7 @@ function SimulationList({ projectId }: { projectId: string }) {
|
|||
</div>
|
||||
) : simulations.length === 0 ? (
|
||||
<div className="text-center p-8 bg-gray-50 dark:bg-neutral-900 rounded-lg border border-dashed border-gray-200 dark:border-neutral-800">
|
||||
<p className="text-gray-600 dark:text-neutral-400 mb-4">No simulations created yet</p>
|
||||
<Button
|
||||
size="sm"
|
||||
color="primary"
|
||||
startContent={<PlusIcon size={16} />}
|
||||
onPress={() => router.push(`/projects/${projectId}/test/simulations/new`)}
|
||||
>
|
||||
Create Your First Simulation
|
||||
</Button>
|
||||
<p className="text-gray-600 dark:text-neutral-400">No simulations created yet</p>
|
||||
</div>
|
||||
) : (
|
||||
<DataTable
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue