Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@

import type { RouterOutputs } from "@ctrlplane/api";
import { useState } from "react";
import { useRouter } from "next/navigation";
import Link from "next/link";
import { useParams, useRouter } from "next/navigation";
import { IconDots, IconPencil, IconTrash } from "@tabler/icons-react";

import { Badge } from "@ctrlplane/ui/badge";
Expand All @@ -25,6 +26,7 @@ import {
import { toast } from "@ctrlplane/ui/toast";

import type { RuleType } from "./rule-themes";
import { urls } from "~/app/urls";
import { api } from "~/trpc/react";
import {
getRuleTypeIcon,
Expand Down Expand Up @@ -56,13 +58,20 @@ interface PolicyTableRowProps {
}

const PolicyTableRow: React.FC<PolicyTableRowProps> = ({ policy }) => {
const { workspaceSlug } = useParams<{ workspaceSlug: string }>();
const updatePolicy = api.policy.update.useMutation();
const router = useRouter();
const [isEnabled, setIsEnabled] = useState(policy.enabled);
const rules = getRules(policy);
const environmentCount = 0;
const deploymentCount = 0;

const editUrl = urls
.workspace(workspaceSlug)
.policies()
.edit(policy.id)
.baseUrl();

return (
<TableRow className="group cursor-pointer hover:bg-muted/50">
{/* Name column */}
Expand Down Expand Up @@ -143,10 +152,12 @@ const PolicyTableRow: React.FC<PolicyTableRowProps> = ({ policy }) => {
</Button>
</DropdownMenuTrigger>
<DropdownMenuContent align="end">
<DropdownMenuItem className="cursor-pointer">
<IconPencil className="mr-2 h-4 w-4" />
Edit
</DropdownMenuItem>
<Link href={editUrl}>
<DropdownMenuItem className="cursor-pointer">
<IconPencil className="mr-2 h-4 w-4" />
Edit
</DropdownMenuItem>
</Link>
<DropdownMenuItem className="cursor-pointer text-destructive focus:text-destructive">
<IconTrash className="mr-2 h-4 w-4" />
Delete
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,11 @@ const PolicyActionMenu: React.FC<PolicyActionMenuProps> = ({
<DropdownMenuContent align="end">
<DropdownMenuItem asChild>
<Link
href={urls.workspace(workspaceSlug).policies().edit(policy.id)}
href={urls
.workspace(workspaceSlug)
.policies()
.edit(policy.id)
.baseUrl()}
className="flex cursor-pointer items-center gap-2"
>
<IconEdit className="h-4 w-4" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,8 @@ export const VersionConditionsPoliciesTable: React.FC<
href={urls
.workspace(workspaceSlug)
.policies()
.edit(policy.id)}
.edit(policy.id)
.baseUrl()}
>
<IconExternalLink className="h-4 w-4" />
<span className="sr-only">Edit Policy</span>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
"use client";

import Link from "next/link";
import { useParams, usePathname } from "next/navigation";
import { IconCircleFilled } from "@tabler/icons-react";

import { cn } from "@ctrlplane/ui";

import type { PolicyTab } from "../../../create/_components/PolicyContext";
import { urls } from "~/app/urls";

type TabConfig = {
id: PolicyTab;
label: string;
description: string;
href: string;
};

export const PolicyEditTabs: React.FC = () => {
const { workspaceSlug, policyId } = useParams<{
workspaceSlug: string;
policyId: string;
}>();

const pathname = usePathname();

const policyEditUrls = urls
.workspace(workspaceSlug)
.policies()
.edit(policyId);

const tabs: TabConfig[] = [
{
id: "config",
label: "Policy Configuration",
description: "Basic policy configuration",
href: policyEditUrls.configuration(),
},
{
id: "time-windows",
label: "Time Windows",
description: "Schedule-based deployment rules",
href: policyEditUrls.timeWindows(),
},
{
id: "deployment-flow",
label: "Deployment Flow",
description: "Control deployment progression",
href: policyEditUrls.deploymentFlow(),
},
{
id: "quality-security",
label: "Quality & Security",
description: "Deployment safety measures",
href: policyEditUrls.qualitySecurity(),
},
];

return (
<div className="flex h-full">
<div className="sticky top-0 h-full w-64 flex-shrink-0 border-r">
<div className="flex flex-col py-2">
{tabs.map((tab) => (
<Link
href={tab.href}
key={tab.id}
className={cn(
"flex w-full cursor-pointer justify-start gap-3 p-3 text-muted-foreground",

pathname === tab.href
? "bg-purple-500/10 text-purple-300"
: "hover:bg-purple-500/5 hover:text-purple-300",
)}
>
<IconCircleFilled className="ml-4 mt-2 size-2" />
<div className="space-y-1">
<div>{tab.label}</div>
<div
className={cn(
"text-xs",
pathname === tab.href
? "text-purple-300"
: "text-muted-foreground",
)}
>
{tab.description}
</div>
</div>
</Link>
))}
</div>
</div>
</div>
);
};
Loading
Loading