Add navigation CTAs in testing section

This commit is contained in:
akhisud3195 2025-03-14 18:08:12 +05:30 committed by ramnique
parent ff15e55c6d
commit 51166c19b4
10 changed files with 46 additions and 56 deletions

View file

@ -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";

View file

@ -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>
<Button size="sm" variant="flat" onPress={onClose}>
Cancel
</Button>
<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>
</>
)}

View file

@ -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>
<Button size="sm" variant="flat" onPress={onClose}>
Cancel
</Button>
<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>
</>
)}

View file

@ -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 {

View file

@ -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 {

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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