feat: renamed old frontend and fixed some minor bugs

This commit is contained in:
=
2025-01-06 14:56:49 +05:30
parent 8c902d7699
commit 54377a44d3
2577 changed files with 35240 additions and 35116 deletions
+1 -1
View File
@@ -4,7 +4,7 @@ import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
const Error = ({ text }: { text: string }): JSX.Element => {
return (
<div className="relative m-auto flex w-fit flex-row items-center justify-center rounded-full">
<FontAwesomeIcon icon={faExclamationTriangle} className="mx-2 mt-1.5 mb-2 text-red" />
<FontAwesomeIcon icon={faExclamationTriangle} className="mx-2 mb-2 mt-1.5 text-red" />
{text && <p className="relative top-0 mr-2 py-1 text-sm text-red">{text}</p>}
</div>
);
+3 -3
View File
@@ -48,7 +48,7 @@ const InputField = ({
placeholder={placeholder}
value={value}
required={isRequired}
className="text-md min-w-16 w-full rounded-md border border-gray-600 bg-bunker-800 p-2 text-gray-400 outline-none"
className="text-md w-full min-w-16 rounded-md border border-gray-600 bg-bunker-800 p-2 text-gray-400 outline-none"
name={name}
readOnly
autoComplete={autoComplete}
@@ -79,7 +79,7 @@ const InputField = ({
: ""
} ${
error ? "focus:ring-red/50" : "focus:ring-primary/50"
} text-md min-w-16 peer relative w-full rounded-md bg-mineshaft-900 p-2 text-gray-400 outline-none duration-200 focus:ring-4`}
} text-md peer relative w-full min-w-16 rounded-md bg-mineshaft-900 p-2 text-gray-400 outline-none duration-200 focus:ring-4`}
name={name}
spellCheck="false"
autoComplete={autoComplete}
@@ -121,7 +121,7 @@ const InputField = ({
</div>
)} */}
</div>
{error && <p className="mx-0 mt-0.5 mb-2 max-w-xs text-xs text-red">{errorText}</p>}
{error && <p className="mx-0 mb-2 mt-0.5 max-w-xs text-xs text-red">{errorText}</p>}
</div>
);
};
-112
View File
@@ -1,112 +0,0 @@
import React, { Fragment } from "react";
import { faAngleDown, faCheck, faPlus } from "@fortawesome/free-solid-svg-icons";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { Listbox, Transition } from "@headlessui/react";
interface ListBoxProps {
isSelected: string;
onChange: (arg: string) => void;
data: string[] | null;
text?: string;
buttonAction?: () => void;
isFull?: boolean;
}
/**
* This is the component that we use for drop down lists.
* @param {object} obj
* @param {string} obj.isSelected - the item that is currently selected
* @param {function} obj.onChange - what happends if you select the item inside a list
* @param {string[]} obj.data - all the options available
* @param {string} obj.text - the text that shows us in front of the select option
* @param {function} obj.buttonAction - if there is a button at the bottom of the list, this is the action that happens when you click the button
* @returns
*/
const ListBox = ({
isSelected,
onChange,
data,
text,
buttonAction,
isFull
}: ListBoxProps): JSX.Element => {
return (
<Listbox value={isSelected} onChange={onChange}>
<div className="relative">
<Listbox.Button
className={`relative text-gray-400 ${
isFull ? "w-full" : "w-52"
} focus-visible:ring-offset-orange-300 cursor-default rounded-md bg-white/[0.07] py-2.5 pl-3 pr-10 text-left shadow-md duration-200 hover:bg-white/[0.11] focus:outline-none focus-visible:border-indigo-500 focus-visible:ring-2 focus-visible:ring-white focus-visible:ring-opacity-75 focus-visible:ring-offset-2 sm:text-sm`}
>
<div className="flex flex-row">
{text}
<span className="ml-1 block cursor-pointer truncate font-semibold text-gray-300">
{" "}
{isSelected}
</span>
</div>
{data && (
<div className="pointer-events-none absolute inset-y-0 right-0 flex cursor-pointer items-center pr-2">
<FontAwesomeIcon icon={faAngleDown} className="text-md mr-1.5" />
</div>
)}
</Listbox.Button>
{data && (
<Transition
as={Fragment}
leave="transition ease-in duration-100"
leaveFrom="opacity-100"
leaveTo="opacity-0"
>
<Listbox.Options className="no-scrollbar::-webkit-scrollbar absolute z-[70] mt-1 max-h-60 w-full overflow-auto rounded-md border border-mineshaft-700 bg-bunker p-2 text-base shadow-lg ring-1 ring-black ring-opacity-5 no-scrollbar focus:outline-none sm:text-sm">
{data.map((person, personIdx) => (
<Listbox.Option
key={`${person}.${personIdx + 1}`}
className={({ active, selected }) =>
`relative my-0.5 cursor-default select-none rounded-md py-2 pl-10 pr-4 ${
selected ? "bg-white/10 font-bold text-gray-400" : ""
} ${
active && !selected
? "cursor-pointer bg-white/5 text-mineshaft-200"
: "text-gray-400"
} `
}
value={person}
>
{({ selected }) => (
<>
<span
className={`block truncate text-primary${
selected ? "font-medium" : "font-normal"
}`}
>
{person}
</span>
{selected ? (
<span className="absolute inset-y-0 left-0 flex items-center rounded-lg pl-3 text-primary">
<FontAwesomeIcon icon={faCheck} className="text-md ml-1" />
</span>
) : null}
</>
)}
</Listbox.Option>
))}
{buttonAction && (
<button type="button" onClick={buttonAction} className="w-full cursor-pointer">
<div className="relative my-0.5 mt-2 flex cursor-pointer select-none justify-start rounded-md py-2 pl-10 pr-4 text-gray-400 duration-200 hover:bg-lime-300 hover:font-semibold hover:text-black">
<span className="absolute inset-y-0 left-0 flex items-center rounded-lg pl-3 pr-4">
<FontAwesomeIcon icon={faPlus} className="text-lg" />
</span>
Add Project
</div>
</button>
)}
</Listbox.Options>
</Transition>
)}
</div>
</Listbox>
);
};
export default ListBox;
-45
View File
@@ -1,45 +0,0 @@
import { Switch } from "@headlessui/react";
interface ToggleProps {
enabled: boolean;
setEnabled: (value: boolean) => void;
addOverride: (value: string | undefined, id: string) => void;
id: string;
}
/**
* This is a typical 'iPhone' toggle (e.g., user for overriding secrets with personal values)
* @param obj
* @param {boolean} obj.enabled - whether the toggle is turned on or off
* @param {function} obj.setEnabled - change the state of the toggle
* @param {function} obj.addOverride - a function that adds an override to a certain secret
* @param {number} obj.id - id of a certain secret
* @returns
*/
const Toggle = ({ enabled, setEnabled, addOverride, id }: ToggleProps): JSX.Element => {
return (
<Switch
checked={enabled}
onChange={() => {
if (enabled === false) {
addOverride("", id);
} else {
addOverride(undefined, id);
}
setEnabled(!enabled);
}}
className={`${
enabled ? "bg-primary" : "bg-bunker-400"
} relative inline-flex h-5 w-9 items-center rounded-full`}
>
<span className="sr-only">Enable notifications</span>
<span
className={`${
enabled ? "translate-x-[1.26rem]" : "translate-x-0.5"
} inline-block h-3.5 w-3.5 transform rounded-full bg-bunker-800 transition`}
/>
</Switch>
);
};
export default Toggle;
@@ -1,148 +0,0 @@
/* eslint-disable react/button-has-type */
import React, { ButtonHTMLAttributes } from "react";
import Image from "next/image";
import { IconProp } from "@fortawesome/fontawesome-svg-core";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
const classNames = require("classnames");
type ButtonProps = {
text?: string;
onButtonPressed: () => void;
loading?: boolean;
color?: string;
size: string;
icon?: IconProp;
active?: boolean;
iconDisabled?: IconProp;
textDisabled?: string;
type?: ButtonHTMLAttributes<any>["type"];
};
/**
* This is the main butto component in the app.
* @param {object} props
* @param {string} props.text - text inside the button
* @param {function} props.onButtonPressed - the action that happens when the button is clicked
* @param {boolean} props.loading - if a button is currently in the laoding state
* @param {string} props.color - button color
* @param {string} props.size - button size
* @param {FontAwesomeIconProps} props.icon - the icon inside the button
* @param {boolean} props.active - if the button is active or disabled
* @param {FontAwesomeIconProps} props.text - the icon inside the button when it is disabled
* @param {string} props.textDisable - text inside the button when it is disabled
* @returns
*/
const Button = ({
active,
text,
textDisabled,
color,
size,
onButtonPressed,
loading,
icon,
iconDisabled,
type = "button"
}: ButtonProps): JSX.Element => {
// Check if the button show always be 'active' - then true;
// or if it should switch between 'active' and 'disabled' - then give the status
const activityStatus = active || (text !== "" && textDisabled === undefined);
const styleButton = classNames(
"group m-auto md:m-0 inline-block rounded-md duration-200",
// Setting background colors and hover modes
color === "mineshaft" &&
activityStatus &&
"bg-mineshaft-800 border border-mineshaft-600 hover:bg-primary/[0.15] hover:border-primary/60",
color === "mineshaft" && !activityStatus && "bg-mineshaft",
(color === "primary" || !color) &&
activityStatus &&
"bg-primary border border-primary-400 opacity-80 hover:opacity-100",
(color === "primary" || !color) && !activityStatus && "bg-primary",
color === "red" && "bg-red-800 border border-red",
// Changing the opacity when active vs when not
activityStatus ? "opacity-100 cursor-pointer" : "opacity-40",
// Setting the button sizes
size === "md" && "h-10 w-full px-2 md:px-4",
size === "lg" && "h-12 w-full px-2 md:px-8",
!size && "md:py-1 px-3 md:px-8",
size === "icon-md" && "h-10 w-10 flex items-center justify-center",
size === "icon-sm" && "h-9 w-9 flex items-center justify-center"
);
const styleMainDiv = classNames(
"relative font-medium flex items-center",
// Setting the text color for the text and icon
color === "mineshaft" && "text-bunker-200",
color !== "mineshaft" && color !== "red" && color !== "none" && "text-black",
color === "red" && "text-gray-200",
color === "none" && "text-gray-200 text-xl",
activityStatus && color !== "red" && color !== "mineshaft" && color !== "none"
? "group-hover:text-black"
: "",
size === "icon" && "flex items-center justify-center"
);
const textStyle = classNames(
"relative duration-200 text-center w-full",
// Show the loading sign if the loading indicator is on
loading ? "opacity-0" : "opacity-100",
size === "md" && "text-sm",
size === "lg" && "text-lg"
);
const button = (
<button
disabled={!activityStatus}
type={type}
onClick={onButtonPressed}
className={styleButton}
>
<div className={styleMainDiv}>
<div
className={`${
loading === true ? "opacity-100" : "opacity-0"
} absolute flex w-full items-center bg-primary px-3 duration-200`}
>
<Image
src="/images/loading/loadingblack.gif"
height={25}
width={42}
alt="loading animation"
className="rounded-xl"
/>
</div>
{icon && (
<FontAwesomeIcon
icon={icon}
className={`my-auto flex font-extrabold ${size === "icon-sm" ? "text-sm" : "text-sm"} ${
(text || textDisabled) && "mr-2"
}`}
/>
)}
{iconDisabled && (
<FontAwesomeIcon
icon={iconDisabled as IconProp}
className={`my-auto flex font-extrabold ${size === "icon-sm" ? "text-sm" : "text-md"} ${
(text || textDisabled) && "mr-2"
}`}
/>
)}
{(text || textDisabled) && (
<p className={textStyle}>{activityStatus ? text : textDisabled}</p>
)}
</div>
</button>
);
return button;
};
export default Button;
@@ -1,100 +0,0 @@
import { Fragment } from "react";
import { useTranslation } from "react-i18next";
import { Dialog, Transition } from "@headlessui/react";
import Button from "../buttons/Button";
interface IntegrationOption {
clientId: string;
clientSlug?: string; // vercel-integration specific
docsLink: string;
image: string;
isAvailable: boolean;
name: string;
slug: string;
type: string;
}
type Props = {
isOpen: boolean;
closeModal: () => void;
selectedIntegrationOption: IntegrationOption | null;
integrationOptionPress: (integrationOption: IntegrationOption) => void;
};
const ActivateBotDialog = ({
isOpen,
closeModal,
selectedIntegrationOption,
integrationOptionPress
}: Props) => {
const { t } = useTranslation();
const submit = async () => {
try {
// type check
if (!selectedIntegrationOption) return;
// start integration or probe for PAT
integrationOptionPress(selectedIntegrationOption);
} catch (err) {
console.log(err);
}
closeModal();
};
return (
<div>
<Transition appear show={isOpen} as={Fragment}>
<Dialog as="div" className="relative z-10" onClose={closeModal}>
<Transition.Child
as={Fragment}
enter="ease-out duration-300"
enterFrom="opacity-0"
enterTo="opacity-100"
leave="ease-in duration-200"
leaveFrom="opacity-100"
leaveTo="opacity-0"
>
<div className="fixed inset-0 bg-black bg-opacity-70" />
</Transition.Child>
<div className="fixed inset-0 overflow-y-auto">
<div className="flex min-h-full items-center justify-center p-4 text-center">
<Transition.Child
as={Fragment}
enter="ease-out duration-300"
enterFrom="opacity-0 scale-95"
enterTo="opacity-100 scale-100"
leave="ease-in duration-200"
leaveFrom="opacity-100 scale-100"
leaveTo="opacity-0 scale-95"
>
<Dialog.Panel className="w-full max-w-md transform overflow-hidden rounded-md border border-gray-700 bg-bunker-800 p-6 text-left align-middle shadow-xl transition-all">
<Dialog.Title as="h3" className="text-lg font-medium leading-6 text-gray-400">
{t("integrations.grant-access-to-secrets")}
</Dialog.Title>
<div className="mt-2 mb-2">
<p className="text-sm text-gray-500">
{t("integrations.why-infisical-needs-access")}
</p>
</div>
<div className="mt-6 max-w-max">
<Button
onButtonPressed={submit}
color="mineshaft"
text={t("integrations.grant-access-button") as string}
size="md"
/>
</div>
</Dialog.Panel>
</Transition.Child>
</div>
</div>
</Dialog>
</Transition>
</div>
);
};
export default ActivateBotDialog;
@@ -1,149 +0,0 @@
import { Fragment } from "react";
import { Trans, useTranslation } from "react-i18next";
import { useRouter } from "next/router";
import { Dialog, Transition } from "@headlessui/react";
import Button from "../buttons/Button";
import ListBox from "../Listbox";
type Props = {
isOpen: boolean;
closeModal: () => void;
submitModal: () => void;
data: any;
email: string;
setEmail: (email: string) => void;
};
const AddProjectMemberDialog = ({
isOpen,
closeModal,
submitModal,
data,
email,
setEmail
}: Props) => {
const router = useRouter();
const { t } = useTranslation();
return (
<div className="z-50">
<Transition appear show={isOpen} as={Fragment}>
<Dialog as="div" className="relative" onClose={closeModal}>
<Transition.Child
as={Fragment}
enter="ease-out duration-300"
enterFrom="opacity-0"
enterTo="opacity-100"
leave="ease-in duration-200"
leaveFrom="opacity-100"
leaveTo="opacity-0"
>
<div className="fixed inset-0 bg-black bg-opacity-70" />
</Transition.Child>
<div className="fixed inset-0 overflow-y-auto">
<div className="flex min-h-full items-center justify-center p-4 text-center">
<Transition.Child
as={Fragment}
enter="ease-out duration-300"
enterFrom="opacity-0 scale-95"
enterTo="opacity-100 scale-100"
leave="ease-in duration-200"
leaveFrom="opacity-100 scale-100"
leaveTo="opacity-0 scale-95"
>
<Dialog.Panel className="w-full max-w-md transform rounded-md border border-mineshaft-600 bg-mineshaft-800 p-6 text-left align-middle shadow-xl transition-all">
{data?.length > 0 ? (
<Dialog.Title
as="h3"
className="z-50 text-lg font-medium leading-6 text-gray-400"
>
{t("section.members.add-dialog.add-member-to-project")}
</Dialog.Title>
) : (
<Dialog.Title
as="h3"
className="z-50 mb-4 text-lg font-medium text-mineshaft-300"
>
{t("section.members.add-dialog.already-all-invited")}
</Dialog.Title>
)}
<div className="mt-2 mb-4">
{data?.length > 0 ? (
<div className="flex flex-col">
<p className="text-sm text-gray-500">
{t("section.members.add-dialog.user-will-email")}
</p>
<div className="">
<Trans
i18nKey="section.members.add-dialog.looking-add"
components={[
// eslint-disable-next-line react/jsx-key
<button
type="button"
className="inline-flex justify-center rounded-md py-1 text-sm text-gray-500 focus:outline-none focus-visible:ring-2 focus-visible:ring-blue-500 focus-visible:ring-offset-2"
onClick={() => router.push(`/org/${router.query.id}/members`)}
aria-label="add member"
/>,
// eslint-disable-next-line react/jsx-key
<button
type="button"
className="ml-1 inline-flex justify-center rounded-md py-1 text-sm text-gray-500 hover:text-primary focus:outline-none focus-visible:ring-2 focus-visible:ring-blue-500 focus-visible:ring-offset-2"
onClick={() =>
router.push(`/org/${router.query.id}/members?action=invite`)
}
aria-label="add member"
/>
]}
/>
</div>
</div>
) : (
<p className="text-sm text-gray-500">
{t("section.members.add-dialog.add-user-org-first")}
</p>
)}
</div>
<div className="max-h-28">
{data?.length > 0 && (
<ListBox
isSelected={email || data[0]}
onChange={setEmail}
data={data}
isFull
/>
)}
</div>
<div className="max-w-max">
{data?.length > 0 ? (
<div className="mt-6 flex w-max flex-col justify-start">
<Button
onButtonPressed={submitModal}
color="mineshaft"
text={t("section.members.add-member") as string}
size="md"
/>
</div>
) : (
<Button
onButtonPressed={() =>
router.push(`/org/${localStorage.getItem("orgData.id")}/members`)
}
color="mineshaft"
text={t("section.members.add-dialog.add-user-to-org") as string}
size="md"
/>
)}
</div>
</Dialog.Panel>
</Transition.Child>
</div>
</div>
</Dialog>
</Transition>
</div>
);
};
export default AddProjectMemberDialog;
@@ -1,140 +0,0 @@
import { FormEventHandler, Fragment, useEffect, useState } from "react";
import { Dialog, Transition } from "@headlessui/react";
import Button from "../buttons/Button";
import InputField from "../InputField";
type FormFields = { name: string; slug: string };
type Props = {
isOpen?: boolean;
isEditMode?: boolean;
// on edit mode load up initial values
initialValues?: FormFields;
onClose: () => void;
onCreateSubmit: (data: FormFields) => void;
onEditSubmit: (data: FormFields) => void;
};
// TODO: Migrate to better form management and validation. Preferable react-hook-form + yup
/**
* The dialog modal for when the user wants to create a new workspace
* @param {*} param0
* @returns
*/
export const AddUpdateEnvironmentDialog = ({
isOpen,
onClose,
onCreateSubmit,
onEditSubmit,
initialValues,
isEditMode
}: Props) => {
const [formInput, setFormInput] = useState<FormFields>({
name: "",
slug: ""
});
// This use effect can be removed when the unmount is happening from outside the component
// When unmount happens outside state gets unmounted also
useEffect(() => {
setFormInput(initialValues || { name: "", slug: "" });
}, [isOpen]);
// REFACTOR: Move to react-hook-form with yup for better form management
const onInputChange = (fieldName: string, fieldValue: string) => {
setFormInput((state) => ({ ...state, [fieldName]: fieldValue }));
};
const onFormSubmit: FormEventHandler = (e) => {
e.preventDefault();
const data = {
name: formInput.name,
slug: formInput.slug.toLowerCase()
};
if (isEditMode) {
onEditSubmit(data);
return;
}
onCreateSubmit(data);
};
return (
<div>
<Transition appear show={isOpen} as={Fragment}>
<Dialog as="div" className="relative z-20" onClose={onClose}>
<Transition.Child
as={Fragment}
enter="ease-out duration-300"
enterFrom="opacity-0"
enterTo="opacity-100"
leave="ease-out duration-150"
leaveFrom="opacity-100"
leaveTo="opacity-0"
>
<div className="fixed inset-0 bg-black bg-opacity-70" />
</Transition.Child>
<div className="fixed inset-0 z-50 overflow-y-auto">
<div className="flex min-h-full items-center justify-center p-4 text-center">
<Transition.Child
as={Fragment}
enter="ease-out duration-300"
enterFrom="opacity-0 scale-95"
enterTo="opacity-100 scale-100"
leave="ease-in duration-200"
leaveFrom="opacity-100 scale-100"
leaveTo="opacity-0 scale-95"
>
<Dialog.Panel className="w-full max-w-md transform overflow-hidden rounded-md border border-gray-700 bg-bunker-800 p-6 text-left align-middle shadow-xl transition-all">
<Dialog.Title as="h3" className="text-lg font-medium leading-6 text-gray-400">
{isEditMode ? "Update environment" : "Create a new environment"}
</Dialog.Title>
<form onSubmit={onFormSubmit}>
<div className="mt-4 max-h-28">
<InputField
label="Environment Name"
onChangeHandler={(val) => onInputChange("name", val)}
type="varName"
value={formInput.name}
placeholder=""
isRequired
// error={error.length > 0}
// errorText={error}
/>
</div>
<div className="mt-4 max-h-28">
<InputField
label="Environment Slug"
onChangeHandler={(val) => onInputChange("slug", val)}
type="varName"
value={formInput.slug}
placeholder=""
isRequired
// error={error.length > 0}
// errorText={error}
/>
</div>
<p className="mt-2 text-xs text-gray-500">
Slugs are shorthands used in cli to access environment
</p>
<div className="mt-4 max-w-min">
<Button
onButtonPressed={() => null}
type="submit"
color="mineshaft"
text={isEditMode ? "Update" : "Create"}
active={formInput.name !== "" && formInput.slug !== ""}
size="md"
/>
</div>
</form>
</Dialog.Panel>
</Transition.Child>
</div>
</div>
</Dialog>
</Transition>
</div>
);
};
@@ -1,104 +0,0 @@
import { Fragment, useState } from "react";
import { Dialog, Transition } from "@headlessui/react";
import Button from "../buttons/Button";
import InputField from "../InputField";
import { Checkbox } from "../table/Checkbox";
type Props = {
isOpen: boolean;
closeModal: () => void;
submitModal: (email: string, addAllUser: boolean) => void;
workspaceName: string;
setWorkspaceName: (workspaceName: string) => void;
error: boolean;
loading: boolean;
};
/**
* The dialog modal for when the user wants to create a new workspace
*/
const AddWorkspaceDialog = ({
isOpen,
closeModal,
submitModal,
workspaceName,
setWorkspaceName,
error,
loading
}: Props) => {
const [addAllUsers, setAddAllUsers] = useState(true);
const submit = () => {
submitModal(workspaceName, addAllUsers);
};
return (
<div>
<Transition appear show={isOpen} as={Fragment}>
<Dialog as="div" className="relative z-[100]" onClose={closeModal}>
<Transition.Child
as={Fragment}
enter="ease-out duration-300"
enterFrom="opacity-0"
enterTo="opacity-100"
leave="ease-in duration-200"
leaveFrom="opacity-100"
leaveTo="opacity-0"
>
<div className="fixed inset-0 bg-black bg-opacity-70" />
</Transition.Child>
<div className="fixed inset-0 overflow-y-auto">
<div className="flex min-h-full items-center justify-center p-4 text-center">
<Transition.Child
as={Fragment}
enter="ease-out duration-300"
enterFrom="opacity-0 scale-95"
enterTo="opacity-100 scale-100"
leave="ease-in duration-200"
leaveFrom="opacity-100 scale-100"
leaveTo="opacity-0 scale-95"
>
<Dialog.Panel className="w-full max-w-md transform overflow-hidden rounded-md border border-gray-700 bg-bunker-800 p-6 text-left align-middle shadow-xl transition-all">
<Dialog.Title as="h3" className="text-lg font-medium leading-6 text-gray-400">
Create a new project
</Dialog.Title>
<div className="mt-2">
<p className="text-sm text-gray-500">
This project will contain your secrets and configs.
</p>
</div>
<div className="mt-4 max-h-28">
<InputField
label="Project Name"
onChangeHandler={setWorkspaceName}
type="varName"
value={workspaceName}
placeholder=""
isRequired
error={error}
/>
</div>
<div className="mt-4 ml-1">
<Checkbox addAllUsers={addAllUsers} setAddAllUsers={setAddAllUsers} />
</div>
<div className="mt-4 max-w-min">
<Button
onButtonPressed={submit}
loading={loading}
color="mineshaft"
text="Create"
size="md"
/>
</div>
</Dialog.Panel>
</Transition.Child>
</div>
</div>
</Dialog>
</Transition>
</div>
);
};
export default AddWorkspaceDialog;
@@ -1,91 +0,0 @@
import { Fragment, useEffect, useState } from "react";
import { Dialog, Transition } from "@headlessui/react";
import InputField from "../InputField";
// REFACTOR: Move all these modals into one reusable one
type Props = {
isOpen?: boolean;
onClose: () => void;
title: string;
onSubmit: () => void;
deleteKey?: string;
};
const DeleteActionModal = ({ isOpen, onClose, title, onSubmit, deleteKey }: Props) => {
const [deleteInputField, setDeleteInputField] = useState("");
useEffect(() => {
setDeleteInputField("");
}, [isOpen]);
return (
<div>
<Transition appear show={isOpen} as={Fragment}>
<Dialog as="div" className="relative z-10" onClose={onClose}>
<Transition.Child
as={Fragment}
enter="ease-out duration-300"
enterFrom="opacity-0"
enterTo="opacity-100"
leave="ease-in duration-150"
leaveFrom="opacity-100"
leaveTo="opacity-0"
>
<div className="fixed inset-0 bg-black bg-opacity-70" />
</Transition.Child>
<div className="fixed inset-0 overflow-y-auto">
<div className="flex min-h-full items-center justify-center p-4 text-center">
<Transition.Child
as={Fragment}
enter="ease-out duration-300"
enterFrom="opacity-0 scale-95"
enterTo="opacity-100 scale-100"
leave="ease-in duration-200"
leaveFrom="opacity-100 scale-100"
leaveTo="opacity-0 scale-95"
>
<Dialog.Panel className="w-full max-w-md transform overflow-hidden rounded-md border border-gray-700 bg-grey p-6 text-left align-middle shadow-xl transition-all">
<Dialog.Title as="h3" className="text-lg font-medium leading-6 text-gray-400">
{title}
</Dialog.Title>
<div className="mt-2">
<p className="text-sm text-gray-500">This action is irrevertible.</p>
</div>
<div className="mt-2">
<InputField
isRequired
label={`Type ${deleteKey} to delete the resource`}
onChangeHandler={(val) => setDeleteInputField(val)}
value={deleteInputField}
type="text"
/>
</div>
<div className="mt-6">
<button
type="button"
className="hover:bg-alizarin hover:text-semibold inline-flex justify-center rounded-md border border-transparent bg-gray-800 px-4 py-2 text-sm font-medium text-gray-400 duration-200 hover:text-white focus:outline-none focus-visible:ring-2 focus-visible:ring-blue-500 focus-visible:ring-offset-2"
onClick={onSubmit}
disabled={Boolean(deleteKey) && deleteInputField !== deleteKey}
>
Delete
</button>
<button
type="button"
className="hover:text-semibold ml-2 inline-flex justify-center rounded-md border border-transparent bg-gray-800 px-4 py-2 text-sm font-medium text-gray-400 duration-200 hover:border-white hover:text-white focus:outline-none focus-visible:ring-2 focus-visible:ring-blue-500 focus-visible:ring-offset-2"
onClick={onClose}
>
Cancel
</button>
</div>
</Dialog.Panel>
</Transition.Child>
</div>
</div>
</Dialog>
</Transition>
</div>
);
};
export default DeleteActionModal;
@@ -1,81 +0,0 @@
import { Fragment } from "react";
import { useTranslation } from "react-i18next";
import { Dialog, Transition } from "@headlessui/react";
// #TODO: USE THIS. Currently it's not. Kinda complicated to set up because of state.
type Props = {
isOpen: boolean;
onClose: () => void;
onSubmit: () => void;
};
export const DeleteEnvVar = ({ isOpen, onClose, onSubmit }: Props) => {
const { t } = useTranslation();
return (
<div>
<Transition appear show={isOpen} as={Fragment}>
<Dialog as="div" className="relative z-[80]" onClose={() => {}}>
<div className="fixed inset-0 overflow-y-auto">
<Transition.Child
as={Fragment}
enter="ease-out duration-300"
enterFrom="opacity-0"
enterTo="opacity-100"
leave="ease-in duration-200"
leaveFrom="opacity-100"
leaveTo="opacity-0"
>
<div
className="fixed inset-0 bg-black bg-opacity-70"
onClick={onClose}
onKeyDown={onClose}
role="button"
tabIndex={0}
aria-label="Close"
/>
</Transition.Child>
<div className="flex min-h-full items-center justify-center p-4 text-center">
<Transition.Child
as={Fragment}
enter="ease-out duration-300"
enterFrom="opacity-0 scale-95"
enterTo="opacity-100 scale-100"
leave="ease-in duration-200"
leaveFrom="opacity-100 scale-100"
leaveTo="opacity-0 scale-95"
>
<Dialog.Panel className="w-full max-w-md transform overflow-hidden rounded-md border border-mineshaft-600 bg-bunker p-6 text-left align-middle shadow-xl transition-all">
<Dialog.Title as="h3" className="text-lg font-medium leading-6 text-bunker-200">
{t("dashboard:sidebar.delete-key-dialog.title")}
</Dialog.Title>
<div className="mt-2">
<p className="text-sm text-bunker-300">
{t("dashboard:sidebar.delete-key-dialog.confirm-delete-message")}
</p>
</div>
<div className="mt-6 flex justify-start">
<button
type="button"
className="text-semibold inline-flex justify-center rounded-md border border-transparent bg-red-500 px-4 py-2 text-sm font-medium text-bunker-100 opacity-80 duration-200 hover:opacity-100 focus:outline-none focus-visible:ring-2 focus-visible:ring-blue-500 focus-visible:ring-offset-2"
onClick={onSubmit}
>
Delete
</button>
<button
type="button"
className="hover:text-semibold ml-2 inline-flex justify-center rounded-md border border-transparent bg-bunker-500 px-4 py-2 text-sm font-medium text-gray-400 duration-200 hover:bg-mineshaft-500 hover:text-white focus:outline-none focus-visible:ring-2 focus-visible:ring-blue-500 focus-visible:ring-offset-2"
onClick={onClose}
>
Cancel
</button>
</div>
</Dialog.Panel>
</Transition.Child>
</div>
</div>
</Dialog>
</Transition>
</div>
);
};
@@ -1,77 +0,0 @@
import { Fragment } from "react";
import { Dialog, Transition } from "@headlessui/react";
// #TODO: USE THIS. Currently it's not. Kinda complicated to set up because of state.
type Props = {
isOpen: boolean;
closeModal: () => void;
submitModal: (userIdToBeDeleted: string) => void;
userIdToBeDeleted: string;
};
const DeleteUserDialog = ({ isOpen, closeModal, submitModal, userIdToBeDeleted }: Props) => {
const submit = () => {
submitModal(userIdToBeDeleted);
};
return (
<div>
<Transition appear show={isOpen} as={Fragment}>
<Dialog as="div" className="relative z-10" onClose={closeModal}>
<Transition.Child
as={Fragment}
enter="ease-out duration-300"
enterFrom="opacity-0"
enterTo="opacity-100"
leave="ease-in duration-200"
leaveFrom="opacity-100"
leaveTo="opacity-0"
>
<div className="fixed inset-0 bg-black bg-opacity-25" />
</Transition.Child>
<div className="fixed inset-0 overflow-y-auto">
<div className="flex min-h-full items-center justify-center p-4 text-center">
<Transition.Child
as={Fragment}
enter="ease-out duration-300"
enterFrom="opacity-0 scale-95"
enterTo="opacity-100 scale-100"
leave="ease-in duration-200"
leaveFrom="opacity-100 scale-100"
leaveTo="opacity-0 scale-95"
>
<Dialog.Panel className="w-full max-w-md transform overflow-hidden rounded-2xl border border-gray-700 bg-grey p-6 text-left align-middle shadow-xl transition-all">
<Dialog.Title as="h3" className="text-lg font-medium leading-6 text-gray-400">
Are you sure you want to remove this user from the workspace?
</Dialog.Title>
<div className="mt-2">
<p className="text-sm text-gray-500">This action is irrevertible.</p>
</div>
<div className="mt-6">
<button
type="button"
className="hover:bg-alizarin hover:text-semibold inline-flex justify-center rounded-md border border-transparent bg-gray-800 px-4 py-2 text-sm font-medium text-gray-400 duration-200 hover:text-white focus:outline-none focus-visible:ring-2 focus-visible:ring-blue-500 focus-visible:ring-offset-2"
onClick={submit}
>
Delete
</button>
<button
type="button"
className="hover:text-semibold ml-2 inline-flex justify-center rounded-md border border-transparent bg-gray-800 px-4 py-2 text-sm font-medium text-gray-400 duration-200 hover:border-white hover:text-white focus:outline-none focus-visible:ring-2 focus-visible:ring-blue-500 focus-visible:ring-offset-2"
onClick={submit}
>
Cancel
</button>
</div>
</Dialog.Panel>
</Transition.Child>
</div>
</div>
</Dialog>
</Transition>
</div>
);
};
export default DeleteUserDialog;
@@ -1,80 +0,0 @@
import { Fragment } from "react";
import { useRouter } from "next/router";
import { Dialog, Transition } from "@headlessui/react";
import { useOrganization } from "@app/context";
// REFACTOR: Move all these modals into one reusable one
type Props = {
isOpen?: boolean;
onClose: () => void;
text: string;
};
const UpgradePlanModal = ({ isOpen, onClose, text }: Props) => {
const router = useRouter();
const { currentOrg } = useOrganization();
return (
<div>
<Transition appear show={isOpen} as={Fragment}>
<Dialog as="div" className="relative z-10" onClose={onClose}>
<Transition.Child
as={Fragment}
enter="ease-out duration-300"
enterFrom="opacity-0"
enterTo="opacity-100"
leave="ease-in duration-150"
leaveFrom="opacity-100"
leaveTo="opacity-0"
>
<div className="fixed inset-0 bg-black bg-opacity-50 drop-shadow-xl" />
</Transition.Child>
<div className="fixed inset-0 overflow-y-auto">
<div className="flex min-h-full items-center justify-center p-4 text-center">
<Transition.Child
as={Fragment}
enter="ease-out duration-300"
enterFrom="opacity-0 scale-95"
enterTo="opacity-100 scale-100"
leave="ease-in duration-200"
leaveFrom="opacity-100 scale-100"
leaveTo="opacity-0 scale-95"
>
<Dialog.Panel className="w-full max-w-md transform overflow-hidden rounded-md border border-mineshaft-500 bg-bunker p-6 pt-5 text-left align-middle shadow-xl transition-all">
<Dialog.Title as="h3" className="text-xl font-medium leading-6 text-primary">
Unleash Infisical&apos;s Full Power
</Dialog.Title>
<div className="mt-2">
<p className="mb-1 text-sm text-bunker-300">{text}</p>
<p className="text-sm text-bunker-300">
Upgrade and get access to this, as well as to other powerful enhancements.
</p>
</div>
<div className="mt-4">
<button
type="button"
className="hover:text-semibold inline-flex justify-center rounded-md border border-transparent bg-primary px-4 py-2 text-sm font-medium text-black opacity-80 duration-200 hover:opacity-100 focus:outline-none focus-visible:ring-2 focus-visible:ring-blue-500 focus-visible:ring-offset-2"
onClick={() => router.push(`/org/${currentOrg?.id}/billing`)}
>
Upgrade Now
</button>
<button
type="button"
className="hover:text-semibold ml-2 inline-flex justify-center rounded-md border border-transparent bg-gray-800 px-4 py-2 text-sm font-medium text-gray-400 duration-200 hover:border-red hover:text-red focus:outline-none focus-visible:ring-2 focus-visible:ring-blue-500 focus-visible:ring-offset-2"
onClick={onClose}
>
Maybe Later
</button>
</div>
</Dialog.Panel>
</Transition.Child>
</div>
</div>
</Dialog>
</Transition>
</div>
);
};
export default UpgradePlanModal;
@@ -1,69 +0,0 @@
import { faXmark } from "@fortawesome/free-solid-svg-icons";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
interface PopupProps {
buttonText: string;
buttonLink: string;
titleText: string;
emoji: string;
textLine1: string;
textLine2: string;
setCheckDocsPopUpVisible: (value: boolean) => void;
}
/**
* This is the notification that pops up at the bottom right when a user performs a certain action
* @param {object} org
* @param {string} org.buttonText - text of the button inside the notification
* @param {string} org.buttonLink - where the button leads to
* @param {string} org.titleText - the text at the top of a notification
* @param {string} org.emoji - the emoji in the notification title
* @param {string} org.textLine1 - first line of the text in the notification
* @param {string} org.textLine2 - second line of the text in the notification
* @param {string} org.setCheckDocsPopUpVisible - the functions that closes the popup
* @returns
*/
const BottonRightPopup = ({
buttonText,
buttonLink,
titleText,
emoji,
textLine1,
textLine2,
setCheckDocsPopUpVisible
}: PopupProps): JSX.Element => {
return (
<div
className="absolute bottom-0 right-0 z-[100] mr-6 mb-6 flex max-w-xl flex-col items-start rounded-md border border-gray-600/50 bg-bunker pt-3 pb-4 text-gray-200 drop-shadow-xl"
role="alert"
>
<div className="flex w-full flex-row items-center justify-between border-b border-gray-600/70 px-6 pb-3">
<div className="mr-2 mt-0.5 flex flex-row text-xl font-bold">
<div>{titleText}</div>
<div className="ml-2.5">{emoji}</div>
</div>
<button className="mt-1" onClick={() => setCheckDocsPopUpVisible(false)} type="button">
<FontAwesomeIcon
icon={faXmark}
className="cursor-pointer text-2xl text-gray-400 duration-200 hover:text-red"
/>
</button>
</div>
<div className="mt-4 mb-0.5 block px-6 text-gray-300 sm:inline">{textLine1}</div>
<div className="mb-4 block px-6 sm:inline">{textLine2}</div>
<div className="flex w-full flex-row px-6">
{/* eslint-disable-next-line react/jsx-no-target-blank */}
<a
className="flex w-full justify-center rounded-md bg-white/10 p-2 font-bold duration-200 hover:bg-primary hover:text-black"
href={buttonLink}
target="_blank"
rel="noopener"
>
{buttonText}
</a>
</div>
</div>
);
};
export default BottonRightPopup;
@@ -1,46 +0,0 @@
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;
@@ -1,32 +0,0 @@
/* eslint-disable jsx-a11y/label-has-associated-control */
type Props = {
addAllUsers: boolean;
setAddAllUsers: (arg: boolean) => void;
};
export const Checkbox = ({ addAllUsers, setAddAllUsers }: Props) => (
<div className="flex flex-row items-center">
{addAllUsers === true ? (
<input
type="checkbox"
className="h-4 w-4 accent-primary"
checked
readOnly
onClick={() => setAddAllUsers(!addAllUsers)}
/>
) : (
<div
onKeyDown={() => setAddAllUsers(!addAllUsers)}
role="button"
tabIndex={0}
aria-label="add all users"
className="h-4 w-4 rounded-sm border border-gray-600 bg-bunker"
onClick={() => setAddAllUsers(!addAllUsers)}
/>
)}
<label className="ml-2 text-sm text-gray-500">
Add all members of my organization to this project.
</label>
</div>
);