mirror of
https://github.com/awatertrevi/infisical.git
synced 2026-10-20 12:38:19 +00:00
Merge branch 'main' of https://github.com/Infisical/infisical into feat/laravel-forge-app-conn-and-secret-sync
This commit is contained in:
@@ -17,6 +17,7 @@ import {
|
||||
} from "@app/components/v2";
|
||||
import { useProject } from "@app/context";
|
||||
import { useCreateWsTag } from "@app/hooks/api";
|
||||
import { SecretV3RawSanitized, WsTag } from "@app/hooks/api/types";
|
||||
import { slugSchema } from "@app/lib/schemas";
|
||||
|
||||
export const secretTagsColors = [
|
||||
@@ -85,6 +86,8 @@ const isValidHexColor = (hexColor: string) => {
|
||||
type Props = {
|
||||
isOpen?: boolean;
|
||||
onToggle: (isOpen: boolean) => void;
|
||||
append: (data: WsTag) => void;
|
||||
currentSecret?: SecretV3RawSanitized;
|
||||
};
|
||||
|
||||
const createTagSchema = z.object({
|
||||
@@ -100,7 +103,7 @@ type TagColor = {
|
||||
name: string;
|
||||
};
|
||||
|
||||
export const CreateTagModal = ({ isOpen, onToggle }: Props): JSX.Element => {
|
||||
export const CreateTagModal = ({ isOpen, onToggle, append, currentSecret }: Props): JSX.Element => {
|
||||
const {
|
||||
control,
|
||||
reset,
|
||||
@@ -128,11 +131,12 @@ export const CreateTagModal = ({ isOpen, onToggle }: Props): JSX.Element => {
|
||||
|
||||
const onFormSubmit = async ({ slug, color }: FormData) => {
|
||||
try {
|
||||
await createWsTag({
|
||||
const data = await createWsTag({
|
||||
projectId,
|
||||
tagColor: color,
|
||||
tagSlug: slug
|
||||
});
|
||||
append(data);
|
||||
onToggle(false);
|
||||
reset();
|
||||
createNotification({
|
||||
@@ -151,8 +155,12 @@ export const CreateTagModal = ({ isOpen, onToggle }: Props): JSX.Element => {
|
||||
return (
|
||||
<Modal isOpen={isOpen} onOpenChange={onToggle}>
|
||||
<ModalContent
|
||||
title="Create tag"
|
||||
subTitle="Specify your tag name, and the slug will be created automatically."
|
||||
title={currentSecret ? `Create tag for ${currentSecret.key}` : "Create tag"}
|
||||
subTitle={
|
||||
currentSecret
|
||||
? `Create a new tag, and it will be automatically linked to secret: ${currentSecret.key}.`
|
||||
: "Specify your tag name, and the slug will be created automatically."
|
||||
}
|
||||
>
|
||||
<form onSubmit={handleSubmit(onFormSubmit)}>
|
||||
<Controller
|
||||
@@ -253,7 +261,7 @@ export const CreateTagModal = ({ isOpen, onToggle }: Props): JSX.Element => {
|
||||
isDisabled={isSubmitting}
|
||||
isLoading={isSubmitting}
|
||||
>
|
||||
Create
|
||||
{currentSecret ? "Create and Add" : "Create"}
|
||||
</Button>
|
||||
<ModalClose asChild>
|
||||
<Button variant="plain" colorSchema="secondary">
|
||||
|
||||
@@ -17,7 +17,14 @@ const badgeVariants = cva(
|
||||
variant: {
|
||||
primary: "bg-yellow/20 text-yellow",
|
||||
danger: "bg-red/20 text-red",
|
||||
success: "bg-green/20 text-green"
|
||||
success: "bg-green/20 text-green",
|
||||
org: "bg-org-v1/20 text-org-v1 [&_svg]:text-org-v1 flex items-center opacity-100 hover:bg-org-v1/10 [&_svg]:size-3 gap-x-1 w-min whitespace-nowrap",
|
||||
namespace:
|
||||
"bg-namespace-v1/20 text-namespace-v1 [&_svg]:text-namespace-v1 flex opacity-100 hover:bg-namespace-v1/10 items-center [&_svg]:size-3.5 gap-x-1 w-min whitespace-nowrap",
|
||||
project:
|
||||
"bg-primary/10 text-primary [&_svg]:text-primary opacity-100 hover:bg-primary/10 flex items-center [&_svg]:size-3 gap-x-1 w-min whitespace-nowrap",
|
||||
instance:
|
||||
"bg-mineshaft-200/20 text-mineshaft-200 [&_svg]:text-mineshaft-200 opacity-100 hover:bg-mineshaft-200/20 flex items-center [&_svg]:size-3 gap-x-1 w-min whitespace-nowrap"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -33,16 +33,21 @@ export const MenuItem = <T extends ElementType = "button">({
|
||||
description,
|
||||
// wrapping in forward ref with generic component causes the loss of ts definitions on props
|
||||
inputRef,
|
||||
variant,
|
||||
...props
|
||||
}: MenuItemProps<T> & ComponentPropsWithRef<T>): JSX.Element => {
|
||||
}: MenuItemProps<T> &
|
||||
ComponentPropsWithRef<T> & { variant?: "project" | "namespace" | "org" }): JSX.Element => {
|
||||
return (
|
||||
<Item
|
||||
type="button"
|
||||
role="menuitem"
|
||||
className={twMerge(
|
||||
"group relative mt-0.5 flex w-full cursor-pointer items-center rounded-sm px-2 py-2 font-inter text-sm text-bunker-100 transition-all duration-50 hover:bg-mineshaft-700",
|
||||
"group relative mt-0.5 box-border flex w-full cursor-pointer items-center rounded-[2px] border-l-2 border-transparent px-2 py-2 font-inter text-sm text-bunker-100 transition-all duration-50 hover:bg-mineshaft-700",
|
||||
isSelected && "bg-mineshaft-600 hover:bg-mineshaft-600",
|
||||
isDisabled && "cursor-not-allowed hover:bg-transparent",
|
||||
isSelected && variant === "org" && "border-org-v1",
|
||||
isSelected && variant === "namespace" && "border-namespace-v1",
|
||||
isSelected && variant === "project" && "border-primary",
|
||||
className
|
||||
)}
|
||||
ref={inputRef}
|
||||
|
||||
@@ -1,18 +1,37 @@
|
||||
import { IconDefinition } from "@fortawesome/free-brands-svg-icons";
|
||||
import { faCube, faCubes, faGlobe, faServer } from "@fortawesome/free-solid-svg-icons";
|
||||
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
||||
import { ReactNode } from "@tanstack/react-router";
|
||||
import { twMerge } from "tailwind-merge";
|
||||
|
||||
import { Badge } from "@app/components/v2";
|
||||
|
||||
type Props = {
|
||||
title: ReactNode;
|
||||
description?: ReactNode;
|
||||
children?: ReactNode;
|
||||
className?: string;
|
||||
scope: "org" | "project" | "namespace" | "instance";
|
||||
};
|
||||
|
||||
export const PageHeader = ({ title, description, children, className }: Props) => (
|
||||
const SCOPE_NAME: Record<NonNullable<Props["scope"]>, { label: string; icon: IconDefinition }> = {
|
||||
org: { label: "Organization", icon: faGlobe },
|
||||
project: { label: "Project", icon: faCube },
|
||||
namespace: { label: "Namespace", icon: faCubes },
|
||||
instance: { label: "Server", icon: faServer }
|
||||
};
|
||||
|
||||
export const PageHeader = ({ title, description, children, className, scope }: Props) => (
|
||||
<div className={twMerge("mb-4 w-full", className)}>
|
||||
<div className="flex w-full justify-between">
|
||||
<div className="w-full">
|
||||
<h1 className="mr-4 text-3xl font-medium text-white capitalize">{title}</h1>
|
||||
<div className="mr-4 flex w-full items-center">
|
||||
<h1 className="text-3xl font-medium text-white capitalize">{title}</h1>
|
||||
{scope && (
|
||||
<Badge variant={scope} className="mt-1 ml-2.5">
|
||||
<FontAwesomeIcon icon={SCOPE_NAME[scope].icon} />
|
||||
{SCOPE_NAME[scope].label}
|
||||
</Badge>
|
||||
)}
|
||||
</div>
|
||||
<div className="flex items-center gap-2">{children}</div>
|
||||
</div>
|
||||
|
||||
@@ -22,10 +22,18 @@ export const TabList = ({ className, children, ...props }: TabListProps) => (
|
||||
|
||||
export type TabProps = TabsPrimitive.TabsTriggerProps;
|
||||
|
||||
export const Tab = ({ className, children, ...props }: TabProps) => (
|
||||
export const Tab = ({
|
||||
className,
|
||||
children,
|
||||
variant = "project",
|
||||
...props
|
||||
}: TabProps & { variant?: "project" | "namespace" | "org" }) => (
|
||||
<TabsPrimitive.Trigger
|
||||
className={twMerge(
|
||||
"flex h-10 items-center justify-center px-3 text-sm font-medium text-mineshaft-400 transition-all select-none first:rounded-tl-md last:rounded-tr-md hover:text-mineshaft-200 data-[state=active]:border-b data-[state=active]:border-primary data-[state=active]:text-white",
|
||||
"flex h-10 items-center justify-center px-3 text-sm font-medium text-mineshaft-400 transition-all select-none first:rounded-tl-md last:rounded-tr-md hover:text-mineshaft-200 data-[state=active]:border-b data-[state=active]:text-white",
|
||||
variant === "project" && "data-[state=active]:border-primary",
|
||||
variant === "namespace" && "data-[state=active]:border-namespace-v1",
|
||||
variant === "org" && "data-[state=active]:border-org-v1",
|
||||
className
|
||||
)}
|
||||
{...props}
|
||||
|
||||
Reference in New Issue
Block a user