Merge remote-tracking branch 'origin' into service-token-v3

This commit is contained in:
Tuan Dang
2023-09-20 17:47:55 +01:00
33 changed files with 576 additions and 1626 deletions
@@ -0,0 +1,46 @@
import { useState } from "react";
import { faInfo } from "@fortawesome/free-solid-svg-icons";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { Tooltip } from "@app/components/v2/Tooltip";
const GlobPatternExamples = () => {
const [showTip, setShowTip] = useState<boolean>(false);
return (
<Tooltip
isOpen={showTip}
onOpenChange={setShowTip}
content={
<div>
<h4 className="mb-2">Here are some examples of glob patterns:</h4>
<div className="ol-listStyleType">
<li>
<code className="text-primary">/</code> - Matches all files and directories in the
current directory
</li>
<li>
<code className="text-primary">**/*</code> - Matches all files and directories in the
current directory and its subdirectories
</li>
<li>
<code className="text-primary">{"/{dir1,dir2}"}</code> - Matches all files and
directories in dir1 and dir2
</li>
</div>
</div>
}
position="right"
className="text-xs"
>
<div
className="flex h-3.5 w-3.5 items-center justify-center rounded-full border border-[1px] border-mineshaft-300"
onMouseEnter={() => setShowTip(true)}
>
<FontAwesomeIcon icon={faInfo} className="h-2 w-2" />
</div>
</Tooltip>
);
};
export default GlobPatternExamples;
@@ -0,0 +1,30 @@
import type { Meta, StoryObj } from "@storybook/react";
import { Accordion, AccordionContent, AccordionItem, AccordionTrigger } from "./Accordion";
const meta: Meta<typeof Accordion> = {
title: "Components/Accordion",
component: Accordion,
tags: ["v2"],
argTypes: {}
};
export default meta;
type Story = StoryObj<typeof Accordion>;
export const Basic: Story = {
render: (args) => (
<div className="flex justify-center w-full">
<Accordion {...args}>
<AccordionItem value="section-1">
<AccordionTrigger>Section 1</AccordionTrigger>
<AccordionContent>Description of Section 1</AccordionContent>
</AccordionItem>
<AccordionItem value="section-2">
<AccordionTrigger>Section 2</AccordionTrigger>
<AccordionContent>Description of Section 2</AccordionContent>
</AccordionItem>
</Accordion>
</div>
)
};
@@ -8,7 +8,7 @@ export const AccordionItem = forwardRef<HTMLDivElement, AccordionPrimitive.Accor
({ children, className, ...props }, forwardedRef) => (
<AccordionPrimitive.Item
className={twMerge(
"focus-within:shadow-mauve12 mt-px overflow-hidden first:mt-0 first:rounded-t last:rounded-b focus-within:relative focus-within:z-10 focus-within:shadow-[0_0_0_2px]",
"mt-px overflow-hidden first:mt-0 data-[state=open]:border-l data-[state=open]:border-primary transition-all border-transparent",
className
)}
{...props}
@@ -27,7 +27,7 @@ export const AccordionTrigger = forwardRef<
<AccordionPrimitive.Header className="flex">
<AccordionPrimitive.Trigger
className={twMerge(
"text-violet11 shadow-mauve6 hover:bg-mauve2 group flex h-[45px] flex-1 cursor-default items-center justify-between bg-white px-5 text-[15px] leading-none shadow-[0_1px_0] outline-none",
"py-2 px-4 group data-[state=open]:text-primary h-11 hover:text-primary flex flex-1 outline-none items-center justify-between ",
className
)}
{...props}
@@ -36,7 +36,7 @@ export const AccordionTrigger = forwardRef<
{children}
<FontAwesomeIcon
icon={faChevronDown}
className="text-violet10 ease-[cubic-bezier(0.87,_0,_0.13,_1)] transition-transform duration-300 group-data-[state=open]:rotate-180"
className="ease-[cubic-bezier(0.87,_0,_0.13,_1)] transition-transform duration-300 group-data-[state=open]:rotate-180 text-sm"
aria-hidden
/>
</AccordionPrimitive.Trigger>
@@ -51,13 +51,13 @@ export const AccordionContent = forwardRef<
>(({ children, className, ...props }, forwardedRef) => (
<AccordionPrimitive.Content
className={twMerge(
"text-mauve11 bg-mauve2 data-[state=open]:animate-slideDown data-[state=closed]:animate-slideUp overflow-hidden text-[15px]",
"data-[state=open]:animate-slideDown data-[state=closed]:animate-slideUp overflow-hidden",
className
)}
{...props}
ref={forwardedRef}
>
<div className="py-[15px] px-5">{children}</div>
<div className="text-sm py-2 px-4">{children}</div>
</AccordionPrimitive.Content>
));
@@ -68,10 +68,7 @@ export const Accordion = ({
children,
...props
}: AccordionPrimitive.AccordionSingleProps | AccordionPrimitive.AccordionMultipleProps) => (
<AccordionPrimitive.Root
className="bg-mauve6 w-[300px] rounded-md shadow-[0_2px_10px] shadow-black/5"
{...props}
>
<AccordionPrimitive.Root {...props} className={twMerge("w-80 text-bunker-300", props.className)}>
{children}
</AccordionPrimitive.Root>
);
+1 -1
View File
@@ -79,7 +79,7 @@ export const Tr = ({
}: TrProps): JSX.Element => (
<tr
className={twMerge(
"cursor-default border-b last:border-b-0 border-solid border-mineshaft-600",
"cursor-default border-b border-solid border-mineshaft-600 last:border-b-0",
isHoverable && "hover:bg-mineshaft-600",
isSelectable && "cursor-pointer",
className
@@ -45,8 +45,7 @@ export const withPermission = <T extends {}, J extends TOrgPermission>(
<div>
<div className="text-4xl font-medium mb-2">Access Restricted</div>
<div className="text-sm">
Your role has limited permissions, please <br /> You do not have permission to this
page.
Your role has limited permissions, please <br /> contact your admin to gain access
</div>
</div>
</div>
@@ -15,6 +15,7 @@ import { yupResolver } from "@hookform/resolvers/yup";
import { twMerge } from "tailwind-merge";
import * as yup from "yup";
import GlobPatternExamples from "@app/components/basic/popups/GlobPatternExamples";
import { useNotificationContext } from "@app/components/context/Notifications/NotificationProvider";
import { ProjectPermissionCan } from "@app/components/permissions";
// TODO:(akhilmhdh) convert all the util functions like this into a lib folder grouped by functionality
@@ -222,7 +223,7 @@ export const SecretDropzone = ({
onDragOver={handleDrag}
onDrop={handleDrop}
className={twMerge(
"relative mx-0.5 mb-4 mt-4 flex cursor-pointer items-center justify-center rounded-md bg-mineshaft-900 py-4 text-sm px-2 text-mineshaft-200 opacity-60 outline-dashed outline-2 outline-chicago-600 duration-200 hover:opacity-100",
"relative mx-0.5 mb-4 mt-4 flex cursor-pointer items-center justify-center rounded-md bg-mineshaft-900 py-4 px-2 text-sm text-mineshaft-200 opacity-60 outline-dashed outline-2 outline-chicago-600 duration-200 hover:opacity-100",
isDragActive && "opacity-100",
!isSmaller && "w-full max-w-3xl flex-col space-y-4 py-20",
isLoading && "bg-bunker-800"
@@ -234,7 +235,7 @@ export const SecretDropzone = ({
</div>
) : (
<form onSubmit={handleSubmit(handleFormSubmit)}>
<div className="flex items-center justify-cente flex-col space-y-2">
<div className="justify-cente flex flex-col items-center space-y-2">
<div>
<FontAwesomeIcon icon={faUpload} size={isSmaller ? "2x" : "5x"} />
</div>
@@ -324,7 +325,12 @@ export const SecretDropzone = ({
</FormControl>
)}
/>
<FormControl label="Secret Path" className="flex-grow" isRequired>
<FormControl
label="Secret Path"
className="flex-grow"
isRequired
icon={<GlobPatternExamples />}
>
<Input
{...register("secretPath")}
placeholder="Provide a path, default is /"
@@ -334,7 +340,7 @@ export const SecretDropzone = ({
<div className="border-t border-mineshaft-600 pt-4">
<div className="mb-4 flex items-center justify-between">
<div>Secrets</div>
<div className="w-1/2 flex items-center space-x-2">
<div className="flex w-1/2 items-center space-x-2">
<Input
placeholder="Search for secret"
value={searchFilter}
@@ -367,7 +373,7 @@ export const SecretDropzone = ({
{!isSecretsLoading && !secrets?.secrets?.length && (
<EmptyState title="No secrets found" icon={faKey} />
)}
<div className="grid grid-cols-2 gap-4 max-h-64 overflow-auto thin-scrollbar ">
<div className="thin-scrollbar grid max-h-64 grid-cols-2 gap-4 overflow-auto ">
{isSecretsLoading &&
Array.apply(0, Array(2)).map((_x, i) => (
<Skeleton
@@ -5,6 +5,7 @@ import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { motion } from "framer-motion";
import { twMerge } from "tailwind-merge";
import GlobPatternExamples from "@app/components/basic/popups/GlobPatternExamples";
import {
Checkbox,
FormControl,
@@ -98,7 +99,7 @@ export const MultiEnvProjectPermission = ({
return (
<div
className={twMerge(
"px-10 py-6 bg-mineshaft-800 rounded-md",
"rounded-md bg-mineshaft-800 px-10 py-6",
(selectedPermissionCategory !== Permission.NoAccess || isCustom) &&
"border-l-2 border-primary-600"
)}
@@ -107,8 +108,8 @@ export const MultiEnvProjectPermission = ({
<div>
<FontAwesomeIcon icon={icon} className="text-4xl" />
</div>
<div className="flex-grow flex flex-col">
<div className="font-medium mb-1 text-lg">{title}</div>
<div className="flex flex-grow flex-col">
<div className="mb-1 text-lg font-medium">{title}</div>
<div className="text-xs font-light">{subtitle}</div>
</div>
<div>
@@ -130,12 +131,19 @@ export const MultiEnvProjectPermission = ({
animate={{ height: isCustom ? "auto" : 0 }}
className="overflow-hidden"
>
<TableContainer className="border-mineshaft-500 mt-6">
<TableContainer className="mt-6 border-mineshaft-500">
<Table>
<THead>
<Tr>
<Th />
<Th className="min-w-[8rem]">Secret Path</Th>
<Th className="min-w-[8rem]">
<div className="flex items-center gap-2">
Secret Path
<span className="text-xs normal-case">
<GlobPatternExamples />
</span>
</div>
</Th>
<Th className="text-center">View</Th>
<Th className="text-center">Create</Th>
<Th className="text-center">Modify</Th>
@@ -169,7 +169,7 @@ export const ProjectRoleModifySection = ({ role, onGoBack }: Props) => {
return (
<div>
<form onSubmit={handleSubmit(handleFormSubmit)}>
<div className="flex justify-between mb-2 items-center">
<div className="mb-2 flex items-center justify-between">
<h1 className="text-xl font-semibold text-mineshaft-100">
{isNewRole ? "New" : "Edit"} Role
</h1>
@@ -211,7 +211,7 @@ export const ProjectRoleModifySection = ({ role, onGoBack }: Props) => {
>
<Input {...register("description")} isReadOnly={isNonEditable} />
</FormControl>
<div className="flex justify-between items-center pt-6 border-t border-t-mineshaft-800">
<div className="flex items-center justify-between border-t border-t-mineshaft-800 pt-6">
<div>
<h2 className="text-xl font-medium">Add Permission</h2>
</div>
@@ -255,7 +255,7 @@ export const ProjectRoleModifySection = ({ role, onGoBack }: Props) => {
/>
</div>
</div>
<div className="flex items-center space-x-4 mt-12">
<div className="mt-12 flex items-center space-x-4">
<Button
type="submit"
isDisabled={isSubmitting || isNonEditable || !isDirty}
@@ -23,8 +23,8 @@ enum Permission {
}
const PERMISSIONS = [
{ action: "edit", label: "Update workspace details" },
{ action: "delete", label: "Delete workspace" }
{ action: "edit", label: "Update project details" },
{ action: "delete", label: "Delete projects" }
] as const;
export const WsProjectPermission = ({ isNonEditable, setValue, control }: Props) => {
@@ -1,10 +1,9 @@
import { useEffect, useState } from "react";
import { useEffect } from "react";
import { Controller, useForm } from "react-hook-form";
import { faInfo } from "@fortawesome/free-solid-svg-icons";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { yupResolver } from "@hookform/resolvers/yup";
import * as yup from "yup";
import GlobPatternExamples from "@app/components/basic/popups/GlobPatternExamples";
import {
Button,
FormControl,
@@ -13,8 +12,7 @@ import {
ModalClose,
ModalContent,
Select,
SelectItem,
Tooltip
SelectItem
} from "@app/components/v2";
const formSchema = yup.object({
@@ -48,7 +46,6 @@ export const AddWebhookForm = ({
} = useForm<TFormSchema>({
resolver: yupResolver(formSchema)
});
const [showTip, setShowTip] = useState<boolean>(false);
useEffect(() => {
if (!isOpen) {
@@ -89,40 +86,7 @@ export const AddWebhookForm = ({
/>
<FormControl
label="Secret Path"
icon={
<Tooltip
isOpen={showTip}
onOpenChange={setShowTip}
content={
<div>
<h4 className="mb-2">Here are some examples of glob patterns:</h4>
<div className="ol-listStyleType">
<li>
<code className="text-primary">/</code> - Matches all files and
directories in the current directory
</li>
<li>
<code className="text-primary">**/*</code> - Matches all files and
directories in the current directory and its subdirectories
</li>
<li>
<code className="text-primary">{"/{dir1,dir2}"}</code> - Matches all files
and directories in dir1 and dir2
</li>
</div>
</div>
}
position="right"
className="text-xs"
>
<div
className="flex h-3.5 w-3.5 items-center justify-center rounded-full border border-[1px] border-mineshaft-300"
onMouseEnter={() => setShowTip(true)}
>
<FontAwesomeIcon icon={faInfo} className="h-2 w-2" />
</div>
</Tooltip>
}
icon={<GlobPatternExamples />}
isRequired
isError={Boolean(errors?.secretPath)}
errorText={errors?.secretPath?.message}