[WEB-5782]chore: migrated modals to @plane/ui (#8420)
* chore: migrated modal to @plane/ui * chore: fixed spacings
This commit is contained in:
parent
39728d4cc4
commit
5b28327551
25 changed files with 1530 additions and 2412 deletions
|
|
@ -1,11 +1,11 @@
|
|||
import React, { useState } from "react";
|
||||
import { useState } from "react";
|
||||
import { Trash2 } from "lucide-react";
|
||||
import { Dialog, Transition } from "@headlessui/react";
|
||||
import { PROFILE_SETTINGS_TRACKER_EVENTS } from "@plane/constants";
|
||||
import { useTranslation } from "@plane/i18n";
|
||||
// ui
|
||||
import { Button } from "@plane/propel/button";
|
||||
import { TOAST_TYPE, setToast } from "@plane/propel/toast";
|
||||
import { EModalPosition, EModalWidth, ModalCore } from "@plane/ui";
|
||||
// hooks
|
||||
import { captureError, captureSuccess } from "@/helpers/event-tracker.helper";
|
||||
import { useUser } from "@/hooks/store/user";
|
||||
|
|
@ -47,6 +47,7 @@ export function DeactivateAccountModal(props: Props) {
|
|||
signOut();
|
||||
router.push("/");
|
||||
handleClose();
|
||||
return;
|
||||
})
|
||||
.catch((err: any) => {
|
||||
captureError({
|
||||
|
|
@ -62,45 +63,15 @@ export function DeactivateAccountModal(props: Props) {
|
|||
};
|
||||
|
||||
return (
|
||||
<Transition.Root show={isOpen} as={React.Fragment}>
|
||||
<Dialog as="div" className="relative z-20" onClose={handleClose}>
|
||||
<Transition.Child
|
||||
as={React.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-backdrop transition-opacity" />
|
||||
</Transition.Child>
|
||||
|
||||
<div className="fixed inset-0 z-20 overflow-y-auto">
|
||||
<div className="flex min-h-full items-end justify-center p-4 text-center sm:items-center sm:p-0">
|
||||
<Transition.Child
|
||||
as={React.Fragment}
|
||||
enter="ease-out duration-300"
|
||||
enterFrom="opacity-0 translate-y-4 sm:translate-y-0 sm:scale-95"
|
||||
enterTo="opacity-100 translate-y-0 sm:scale-100"
|
||||
leave="ease-in duration-200"
|
||||
leaveFrom="opacity-100 translate-y-0 sm:scale-100"
|
||||
leaveTo="opacity-0 translate-y-4 sm:translate-y-0 sm:scale-95"
|
||||
>
|
||||
<Dialog.Panel className="relative transform overflow-hidden rounded-lg bg-surface-1 text-left shadow-raised-200 transition-all sm:my-8 sm:w-[40rem]">
|
||||
<ModalCore isOpen={isOpen} handleClose={handleClose} position={EModalPosition.CENTER} width={EModalWidth.XXL}>
|
||||
<div className="px-4 pb-4 pt-5 sm:p-6 sm:pb-4">
|
||||
<div className="">
|
||||
<div className="flex items-start gap-x-4">
|
||||
<div className="mt-3 grid place-items-center rounded-full bg-red-500/20 p-2 sm:mt-3 sm:p-2 md:mt-0 md:p-4 lg:mt-0 lg:p-4 ">
|
||||
<Trash2
|
||||
className="h-4 w-4 text-red-600 sm:h-4 sm:w-4 md:h-6 md:w-6 lg:h-6 lg:w-6"
|
||||
aria-hidden="true"
|
||||
/>
|
||||
<Trash2 className="h-4 w-4 text-red-600 sm:h-4 sm:w-4 md:h-6 md:w-6 lg:h-6 lg:w-6" aria-hidden="true" />
|
||||
</div>
|
||||
<div>
|
||||
<Dialog.Title as="h3" className="my-4 text-20 font-medium leading-6 text-primary">
|
||||
{t("deactivate_your_account")}
|
||||
</Dialog.Title>
|
||||
<h3 className="my-4 text-20 font-medium leading-6 text-primary">{t("deactivate_your_account")}</h3>
|
||||
<p className="mt-6 list-disc pr-4 text-14 font-regular text-secondary">
|
||||
{t("deactivate_your_account_description")}
|
||||
</p>
|
||||
|
|
@ -109,18 +80,13 @@ export function DeactivateAccountModal(props: Props) {
|
|||
</div>
|
||||
</div>
|
||||
<div className="mb-2 flex items-center justify-end gap-2 p-4 sm:px-6">
|
||||
<Button variant="secondary" size="lg" onClick={onClose}>
|
||||
<Button variant="secondary" size="lg" onClick={handleClose}>
|
||||
{t("cancel")}
|
||||
</Button>
|
||||
<Button variant="error-fill" size="lg" onClick={handleDeleteAccount}>
|
||||
{isDeactivating ? t("deactivating") : t("confirm")}
|
||||
</Button>
|
||||
</div>
|
||||
</Dialog.Panel>
|
||||
</Transition.Child>
|
||||
</div>
|
||||
</div>
|
||||
</Dialog>
|
||||
</Transition.Root>
|
||||
</ModalCore>
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,14 +1,10 @@
|
|||
import React from "react";
|
||||
import { useParams } from "next/navigation";
|
||||
// react-hook-form
|
||||
import { Controller, useForm } from "react-hook-form";
|
||||
// headless ui
|
||||
import { Dialog, Transition } from "@headlessui/react";
|
||||
import { Button } from "@plane/propel/button";
|
||||
import type { IProject } from "@plane/types";
|
||||
// ui
|
||||
import { Input } from "@plane/ui";
|
||||
// types
|
||||
import { Input, EModalPosition, EModalWidth, ModalCore } from "@plane/ui";
|
||||
|
||||
// types
|
||||
type Props = {
|
||||
|
|
@ -43,37 +39,10 @@ export function SelectMonthModal({ type, initialValues, isOpen, handleClose, han
|
|||
};
|
||||
|
||||
return (
|
||||
<Transition.Root show={isOpen} as={React.Fragment}>
|
||||
<Dialog as="div" className="relative z-30" onClose={onClose}>
|
||||
<Transition.Child
|
||||
as={React.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-backdrop transition-opacity" />
|
||||
</Transition.Child>
|
||||
|
||||
<div className="fixed inset-0 z-10 overflow-y-auto">
|
||||
<div className="flex min-h-full items-center justify-center p-4 text-center sm:p-0">
|
||||
<Transition.Child
|
||||
as={React.Fragment}
|
||||
enter="ease-out duration-300"
|
||||
enterFrom="opacity-0 translate-y-4 sm:translate-y-0 sm:scale-95"
|
||||
enterTo="opacity-100 translate-y-0 sm:scale-100"
|
||||
leave="ease-in duration-200"
|
||||
leaveFrom="opacity-100 translate-y-0 sm:scale-100"
|
||||
leaveTo="opacity-0 translate-y-4 sm:translate-y-0 sm:scale-95"
|
||||
>
|
||||
<Dialog.Panel className="relative transform rounded-lg bg-surface-1 px-4 pb-4 pt-5 text-left shadow-raised-200 transition-all sm:my-8 sm:w-full sm:max-w-2xl sm:p-6">
|
||||
<ModalCore isOpen={isOpen} handleClose={onClose} position={EModalPosition.CENTER} width={EModalWidth.XXL}>
|
||||
<form onSubmit={handleSubmit(onSubmit)}>
|
||||
<div>
|
||||
<Dialog.Title as="h3" className="text-16 font-medium leading-6 text-primary">
|
||||
Customize time range
|
||||
</Dialog.Title>
|
||||
<h3 className="text-16 font-medium leading-6 text-primary">Customize time range</h3>
|
||||
<div className="mt-8 flex items-center gap-2">
|
||||
<div className="flex w-full flex-col justify-center gap-1">
|
||||
{type === "auto-close" ? (
|
||||
|
|
@ -156,11 +125,6 @@ export function SelectMonthModal({ type, initialValues, isOpen, handleClose, han
|
|||
</Button>
|
||||
</div>
|
||||
</form>
|
||||
</Dialog.Panel>
|
||||
</Transition.Child>
|
||||
</div>
|
||||
</div>
|
||||
</Dialog>
|
||||
</Transition.Root>
|
||||
</ModalCore>
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,12 +1,8 @@
|
|||
import { Fragment } from "react";
|
||||
import { Controller, useForm } from "react-hook-form";
|
||||
|
||||
import { Dialog, Transition } from "@headlessui/react";
|
||||
|
||||
import { Button } from "@plane/propel/button";
|
||||
import { Calendar } from "@plane/propel/calendar";
|
||||
|
||||
import { CloseIcon } from "@plane/propel/icons";
|
||||
import { EModalPosition, EModalWidth, ModalCore } from "@plane/ui";
|
||||
import { renderFormattedPayloadDate, renderFormattedDate, getDate } from "@plane/utils";
|
||||
import { DateFilterSelect } from "./date-filter-select";
|
||||
type Props = {
|
||||
|
|
@ -49,32 +45,8 @@ export function DateFilterModal({ title, handleClose, isOpen, onSelect }: Props)
|
|||
const isInvalid = watch("filterType") === "range" && date1 && date2 ? date1 > date2 : false;
|
||||
|
||||
return (
|
||||
<Transition.Root show={isOpen} as={Fragment}>
|
||||
<Dialog as="div" className="relative z-30" onClose={handleClose}>
|
||||
<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-backdrop transition-opacity" />
|
||||
</Transition.Child>
|
||||
<div className="fixed inset-0 z-20 flex w-full justify-center overflow-y-auto">
|
||||
<div className="flex min-h-full items-center justify-center p-4 text-center sm:p-0">
|
||||
<Transition.Child
|
||||
as={Fragment}
|
||||
enter="ease-out duration-300"
|
||||
enterFrom="opacity-0 translate-y-4 sm:translate-y-0 sm:scale-95"
|
||||
enterTo="opacity-100 translate-y-0 sm:scale-100"
|
||||
leave="ease-in duration-200"
|
||||
leaveFrom="opacity-100 translate-y-0 sm:scale-100"
|
||||
leaveTo="opacity-0 translate-y-4 sm:translate-y-0 sm:scale-95"
|
||||
>
|
||||
<Dialog.Panel className="relative flex transform rounded-lg bg-surface-1 px-5 py-8 text-left shadow-raised-200 transition-all sm:my-8 sm:w-full sm:max-w-2xl sm:p-6">
|
||||
<form className="space-y-4">
|
||||
<ModalCore isOpen={isOpen} handleClose={handleClose} position={EModalPosition.CENTER} width={EModalWidth.XXL}>
|
||||
<form className="space-y-4 px-5 py-8 sm:p-6">
|
||||
<div className="flex w-full justify-between">
|
||||
<Controller
|
||||
control={control}
|
||||
|
|
@ -156,11 +128,6 @@ export function DateFilterModal({ title, handleClose, isOpen, onSelect }: Props)
|
|||
</Button>
|
||||
</div>
|
||||
</form>
|
||||
</Dialog.Panel>
|
||||
</Transition.Child>
|
||||
</div>
|
||||
</div>
|
||||
</Dialog>
|
||||
</Transition.Root>
|
||||
</ModalCore>
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,18 +1,18 @@
|
|||
import React, { useEffect, useState } from "react";
|
||||
import { useEffect, useState } from "react";
|
||||
import { observer } from "mobx-react";
|
||||
import { useParams } from "next/navigation";
|
||||
import { useTheme } from "next-themes";
|
||||
import type { SubmitHandler } from "react-hook-form";
|
||||
import { useForm } from "react-hook-form";
|
||||
import { Search } from "lucide-react";
|
||||
import { Combobox, Dialog, Transition } from "@headlessui/react";
|
||||
import { Combobox } from "@headlessui/react";
|
||||
// plane imports
|
||||
import { useTranslation } from "@plane/i18n";
|
||||
import { Button } from "@plane/propel/button";
|
||||
import { TOAST_TYPE, setToast } from "@plane/propel/toast";
|
||||
import type { ISearchIssueResponse, IUser } from "@plane/types";
|
||||
import { EIssuesStoreType } from "@plane/types";
|
||||
import { Loader } from "@plane/ui";
|
||||
import { Loader, EModalPosition, EModalWidth, ModalCore } from "@plane/ui";
|
||||
// assets
|
||||
import darkIssuesAsset from "@/app/assets/empty-state/search/issues-dark.webp?url";
|
||||
import lightIssuesAsset from "@/app/assets/empty-state/search/issues-light.webp?url";
|
||||
|
|
@ -150,20 +150,7 @@ export const BulkDeleteIssuesModal = observer(function BulkDeleteIssuesModal(pro
|
|||
);
|
||||
|
||||
return (
|
||||
<Transition.Root show={isOpen} as={React.Fragment} afterLeave={() => setQuery("")} appear>
|
||||
<Dialog as="div" className="relative z-20" onClose={handleClose}>
|
||||
<div className="fixed inset-0 z-20 overflow-y-auto bg-backdrop p-4 transition-opacity sm:p-6 md:p-20">
|
||||
<Transition.Child
|
||||
as={React.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="relative flex w-full items-center justify-center ">
|
||||
<div className="w-full max-w-2xl transform divide-y divide-subtle-1 divide-opacity-10 rounded-lg bg-surface-1 shadow-raised-200 transition-all">
|
||||
<ModalCore isOpen={isOpen} handleClose={handleClose} position={EModalPosition.CENTER} width={EModalWidth.XXL}>
|
||||
<form>
|
||||
<Combobox
|
||||
onChange={(val: string) => {
|
||||
|
|
@ -208,22 +195,12 @@ export const BulkDeleteIssuesModal = observer(function BulkDeleteIssuesModal(pro
|
|||
<Button variant="secondary" size="lg" onClick={handleClose}>
|
||||
Cancel
|
||||
</Button>
|
||||
<Button
|
||||
variant="error-fill"
|
||||
size="lg"
|
||||
onClick={handleSubmit(handleDelete)}
|
||||
loading={isSubmitting}
|
||||
>
|
||||
<Button variant="error-fill" size="lg" onClick={handleSubmit(handleDelete)} loading={isSubmitting}>
|
||||
{isSubmitting ? "Deleting..." : "Delete selected work items"}
|
||||
</Button>
|
||||
</div>
|
||||
)}
|
||||
</form>
|
||||
</div>
|
||||
</Dialog.Panel>
|
||||
</Transition.Child>
|
||||
</div>
|
||||
</Dialog>
|
||||
</Transition.Root>
|
||||
</ModalCore>
|
||||
);
|
||||
});
|
||||
|
|
|
|||
|
|
@ -1,12 +1,11 @@
|
|||
import React, { useState } from "react";
|
||||
import { useState } from "react";
|
||||
import { observer } from "mobx-react";
|
||||
import { Controller, useForm } from "react-hook-form";
|
||||
import { Transition, Dialog } from "@headlessui/react";
|
||||
// plane imports
|
||||
import { useTranslation } from "@plane/i18n";
|
||||
import { Button } from "@plane/propel/button";
|
||||
import { TOAST_TYPE, setToast } from "@plane/propel/toast";
|
||||
import { Input } from "@plane/ui";
|
||||
import { Input, EModalPosition, EModalWidth, ModalCore } from "@plane/ui";
|
||||
import { cn } from "@plane/utils";
|
||||
// helpers
|
||||
import { authErrorHandler } from "@/helpers/authentication.helper";
|
||||
|
|
@ -127,43 +126,14 @@ export const ChangeEmailModal = observer(function ChangeEmailModal(props: Props)
|
|||
};
|
||||
|
||||
return (
|
||||
<Transition.Root show={isOpen} as={React.Fragment}>
|
||||
<Dialog as="div" className="relative z-30" onClose={handleClose}>
|
||||
<Transition.Child
|
||||
as={React.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 transition-opacity bg-backdrop" />
|
||||
</Transition.Child>
|
||||
|
||||
<div className="overflow-y-auto fixed inset-0 z-30">
|
||||
<div className="flex justify-center items-center p-4 min-h-full text-center sm:p-0">
|
||||
<Transition.Child
|
||||
as={React.Fragment}
|
||||
enter="ease-out duration-300"
|
||||
enterFrom="opacity-0 translate-y-4 sm:translate-y-0 sm:scale-95"
|
||||
enterTo="opacity-100 translate-y-0 sm:scale-100"
|
||||
leave="ease-in duration-200"
|
||||
leaveFrom="opacity-100 translate-y-0 sm:scale-100"
|
||||
leaveTo="opacity-0 translate-y-4 sm:translate-y-0 sm:scale-95"
|
||||
>
|
||||
<Dialog.Panel className="relative transform overflow-hidden rounded-lg bg-surface-1 px-4 text-left shadow-raised-200 transition-all sm:my-8 sm:w-[30rem]">
|
||||
<div className="py-4 space-y-0">
|
||||
<Dialog.Title as="h3" className="text-16 font-medium leading-6 text-primary">
|
||||
{changeEmailT("title")}
|
||||
</Dialog.Title>
|
||||
<ModalCore isOpen={isOpen} handleClose={handleClose} position={EModalPosition.CENTER} width={EModalWidth.XXL}>
|
||||
<div className="py-4 space-y-0 px-4">
|
||||
<h3 className="text-16 font-medium leading-6 text-primary">{changeEmailT("title")}</h3>
|
||||
<p className="my-4 text-13 text-secondary">{changeEmailT("description")}</p>
|
||||
</div>
|
||||
<form onSubmit={handleSubmit(onSubmit)} className="space-y-4" noValidate>
|
||||
<form onSubmit={handleSubmit(onSubmit)} className="space-y-4 px-4" noValidate>
|
||||
<div className="flex flex-col gap-1">
|
||||
{secondStep && (
|
||||
<h4 className="text-13 font-medium text-secondary">{changeEmailT("form.email.label")}</h4>
|
||||
)}
|
||||
{secondStep && <h4 className="text-13 font-medium text-secondary">{changeEmailT("form.email.label")}</h4>}
|
||||
<Controller
|
||||
control={control}
|
||||
name="email"
|
||||
|
|
@ -184,10 +154,7 @@ export const ChangeEmailModal = observer(function ChangeEmailModal(props: Props)
|
|||
ref={ref}
|
||||
hasError={Boolean(errors.email)}
|
||||
placeholder={changeEmailT("form.email.placeholder")}
|
||||
className={cn(
|
||||
{ "border-red-500": errors.email },
|
||||
{ "cursor-not-allowed !bg-surface-2": secondStep }
|
||||
)}
|
||||
className={cn({ "border-red-500": errors.email }, { "cursor-not-allowed !bg-surface-2": secondStep })}
|
||||
disabled={secondStep}
|
||||
/>
|
||||
)}
|
||||
|
|
@ -235,11 +202,6 @@ export const ChangeEmailModal = observer(function ChangeEmailModal(props: Props)
|
|||
</Button>
|
||||
</div>
|
||||
</form>
|
||||
</Dialog.Panel>
|
||||
</Transition.Child>
|
||||
</div>
|
||||
</div>
|
||||
</Dialog>
|
||||
</Transition.Root>
|
||||
</ModalCore>
|
||||
);
|
||||
});
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import React, { useEffect, useState, useRef } from "react";
|
||||
import { useEffect, useState, useRef } from "react";
|
||||
import { Rocket, Search } from "lucide-react";
|
||||
import { Combobox, Dialog, Transition } from "@headlessui/react";
|
||||
import { Combobox } from "@headlessui/react";
|
||||
// i18n
|
||||
import { useTranslation } from "@plane/i18n";
|
||||
// types
|
||||
|
|
@ -10,7 +10,7 @@ import { TOAST_TYPE, setToast } from "@plane/propel/toast";
|
|||
import { Tooltip } from "@plane/propel/tooltip";
|
||||
import type { ISearchIssueResponse, TProjectIssuesSearchParams } from "@plane/types";
|
||||
// ui
|
||||
import { Loader, ToggleSwitch } from "@plane/ui";
|
||||
import { Loader, ToggleSwitch, EModalPosition, EModalWidth, ModalCore } from "@plane/ui";
|
||||
import { generateWorkItemLink, getTabIndex } from "@plane/utils";
|
||||
// helpers
|
||||
// hooks
|
||||
|
|
@ -131,32 +131,7 @@ export function ExistingIssuesListModal(props: Props) {
|
|||
const filteredIssues = issues.filter((issue) => !shouldHideIssue?.(issue));
|
||||
|
||||
return (
|
||||
<>
|
||||
<Transition.Root show={isOpen} as={React.Fragment} afterLeave={() => setSearchTerm("")} appear>
|
||||
<Dialog as="div" className="relative z-30" onClose={handleClose}>
|
||||
<Transition.Child
|
||||
as={React.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-backdrop transition-opacity" />
|
||||
</Transition.Child>
|
||||
|
||||
<div className="fixed inset-0 z-30 overflow-y-auto p-4 sm:p-6 md:p-20">
|
||||
<Transition.Child
|
||||
as={React.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="relative mx-auto max-w-2xl transform rounded-lg bg-surface-1 shadow-raised-200 transition-all">
|
||||
<ModalCore isOpen={isOpen} handleClose={handleClose} position={EModalPosition.CENTER} width={EModalWidth.XXL}>
|
||||
<Combobox
|
||||
as="div"
|
||||
onChange={(val: ISearchIssueResponse) => {
|
||||
|
|
@ -217,10 +192,7 @@ export function ExistingIssuesListModal(props: Props) {
|
|||
isWorkspaceLevel ? "text-primary" : "text-secondary"
|
||||
}`}
|
||||
>
|
||||
<ToggleSwitch
|
||||
value={isWorkspaceLevel}
|
||||
onChange={() => setIsWorkspaceLevel((prevData) => !prevData)}
|
||||
/>
|
||||
<ToggleSwitch value={isWorkspaceLevel} onChange={() => setIsWorkspaceLevel((prevData) => !prevData)} />
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => setIsWorkspaceLevel((prevData) => !prevData)}
|
||||
|
|
@ -233,10 +205,7 @@ export function ExistingIssuesListModal(props: Props) {
|
|||
)}
|
||||
</div>
|
||||
|
||||
<Combobox.Options
|
||||
static
|
||||
className="vertical-scrollbar scrollbar-md max-h-80 scroll-py-2 overflow-y-auto"
|
||||
>
|
||||
<Combobox.Options static className="vertical-scrollbar scrollbar-md max-h-80 scroll-py-2 overflow-y-auto">
|
||||
{/* TODO: Translate here */}
|
||||
{searchTerm !== "" && (
|
||||
<h5 className="mx-2 text-13 text-secondary">
|
||||
|
|
@ -334,9 +303,7 @@ export function ExistingIssuesListModal(props: Props) {
|
|||
disabled={filteredIssues.length === 0}
|
||||
className={filteredIssues.length === 0 ? "p-0" : ""}
|
||||
>
|
||||
{selectedIssues.length === issues.length
|
||||
? t("issue.select.deselect_all")
|
||||
: t("issue.select.select_all")}
|
||||
{selectedIssues.length === issues.length ? t("issue.select.deselect_all") : t("issue.select.select_all")}
|
||||
</Button>
|
||||
<div className="flex items-center justify-end gap-2">
|
||||
<Button variant="secondary" size="lg" onClick={handleClose}>
|
||||
|
|
@ -353,11 +320,6 @@ export function ExistingIssuesListModal(props: Props) {
|
|||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
</Dialog.Panel>
|
||||
</Transition.Child>
|
||||
</div>
|
||||
</Dialog>
|
||||
</Transition.Root>
|
||||
</>
|
||||
</ModalCore>
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,13 +1,13 @@
|
|||
import React, { useState } from "react";
|
||||
import { useState } from "react";
|
||||
import { observer } from "mobx-react";
|
||||
import { useDropzone } from "react-dropzone";
|
||||
import { Transition, Dialog } from "@headlessui/react";
|
||||
// plane imports
|
||||
import { ACCEPTED_AVATAR_IMAGE_MIME_TYPES_FOR_REACT_DROPZONE, MAX_FILE_SIZE } from "@plane/constants";
|
||||
import { Button } from "@plane/propel/button";
|
||||
import { UserCirclePropertyIcon } from "@plane/propel/icons";
|
||||
import { TOAST_TYPE, setToast } from "@plane/propel/toast";
|
||||
import { EFileAssetType } from "@plane/types";
|
||||
import { EModalPosition, EModalWidth, ModalCore } from "@plane/ui";
|
||||
import { getAssetIdFromUrl, getFileURL, checkURLValidity } from "@plane/utils";
|
||||
// services
|
||||
import { FileService } from "@/services/file.service";
|
||||
|
|
@ -88,36 +88,9 @@ export const UserImageUploadModal = observer(function UserImageUploadModal(props
|
|||
};
|
||||
|
||||
return (
|
||||
<Transition.Root show={isOpen} as={React.Fragment}>
|
||||
<Dialog as="div" className="relative z-30" onClose={handleClose}>
|
||||
<Transition.Child
|
||||
as={React.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-backdrop transition-opacity" />
|
||||
</Transition.Child>
|
||||
|
||||
<div className="fixed inset-0 z-30 overflow-y-auto">
|
||||
<div className="flex min-h-full items-center justify-center p-4 text-center sm:p-0">
|
||||
<Transition.Child
|
||||
as={React.Fragment}
|
||||
enter="ease-out duration-300"
|
||||
enterFrom="opacity-0 translate-y-4 sm:translate-y-0 sm:scale-95"
|
||||
enterTo="opacity-100 translate-y-0 sm:scale-100"
|
||||
leave="ease-in duration-200"
|
||||
leaveFrom="opacity-100 translate-y-0 sm:scale-100"
|
||||
leaveTo="opacity-0 translate-y-4 sm:translate-y-0 sm:scale-95"
|
||||
>
|
||||
<Dialog.Panel className="relative transform overflow-hidden rounded-lg bg-surface-1 px-5 py-8 text-left shadow-raised-200 transition-all sm:w-full sm:max-w-xl sm:p-6">
|
||||
<div className="space-y-5">
|
||||
<Dialog.Title as="h3" className="text-16 font-medium leading-6 text-primary">
|
||||
Upload Image
|
||||
</Dialog.Title>
|
||||
<ModalCore isOpen={isOpen} handleClose={handleClose} position={EModalPosition.CENTER} width={EModalWidth.XL}>
|
||||
<div className="space-y-5 px-5 py-8 sm:p-6">
|
||||
<h3 className="text-16 font-medium leading-6 text-primary">Upload Image</h3>
|
||||
<div className="space-y-3">
|
||||
<div className="flex items-center justify-center gap-3">
|
||||
<div
|
||||
|
|
@ -162,7 +135,6 @@ export const UserImageUploadModal = observer(function UserImageUploadModal(props
|
|||
</p>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
<p className="my-4 text-13 text-secondary">File formats supported- .jpeg, .jpg, .png, .webp</p>
|
||||
<div className="flex items-center justify-between">
|
||||
<Button variant="error-fill" size="lg" onClick={handleImageRemove} disabled={!value}>
|
||||
|
|
@ -172,22 +144,12 @@ export const UserImageUploadModal = observer(function UserImageUploadModal(props
|
|||
<Button variant="secondary" size="lg" onClick={handleClose}>
|
||||
Cancel
|
||||
</Button>
|
||||
<Button
|
||||
variant="primary"
|
||||
size="lg"
|
||||
onClick={handleSubmit}
|
||||
disabled={!image}
|
||||
loading={isImageUploading}
|
||||
>
|
||||
<Button variant="primary" size="lg" onClick={handleSubmit} disabled={!image} loading={isImageUploading}>
|
||||
{isImageUploading ? "Uploading" : "Upload & Save"}
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
</Dialog.Panel>
|
||||
</Transition.Child>
|
||||
</div>
|
||||
</div>
|
||||
</Dialog>
|
||||
</Transition.Root>
|
||||
</ModalCore>
|
||||
);
|
||||
});
|
||||
|
|
|
|||
|
|
@ -1,14 +1,14 @@
|
|||
import React, { useState } from "react";
|
||||
import { useState } from "react";
|
||||
import { observer } from "mobx-react";
|
||||
import { useParams } from "next/navigation";
|
||||
import { useDropzone } from "react-dropzone";
|
||||
import { Transition, Dialog } from "@headlessui/react";
|
||||
// plane imports
|
||||
import { ACCEPTED_AVATAR_IMAGE_MIME_TYPES_FOR_REACT_DROPZONE, MAX_FILE_SIZE } from "@plane/constants";
|
||||
import { Button } from "@plane/propel/button";
|
||||
import { UserCirclePropertyIcon } from "@plane/propel/icons";
|
||||
import { TOAST_TYPE, setToast } from "@plane/propel/toast";
|
||||
import { EFileAssetType } from "@plane/types";
|
||||
import { EModalPosition, EModalWidth, ModalCore } from "@plane/ui";
|
||||
import { getAssetIdFromUrl, getFileURL, checkURLValidity } from "@plane/utils";
|
||||
// hooks
|
||||
import { useWorkspace } from "@/hooks/store/use-workspace";
|
||||
|
|
@ -101,36 +101,9 @@ export const WorkspaceImageUploadModal = observer(function WorkspaceImageUploadM
|
|||
};
|
||||
|
||||
return (
|
||||
<Transition.Root show={isOpen} as={React.Fragment}>
|
||||
<Dialog as="div" className="relative z-30" onClose={handleClose}>
|
||||
<Transition.Child
|
||||
as={React.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-backdrop transition-opacity" />
|
||||
</Transition.Child>
|
||||
|
||||
<div className="fixed inset-0 z-30 overflow-y-auto">
|
||||
<div className="flex min-h-full items-center justify-center p-4 text-center sm:p-0">
|
||||
<Transition.Child
|
||||
as={React.Fragment}
|
||||
enter="ease-out duration-300"
|
||||
enterFrom="opacity-0 translate-y-4 sm:translate-y-0 sm:scale-95"
|
||||
enterTo="opacity-100 translate-y-0 sm:scale-100"
|
||||
leave="ease-in duration-200"
|
||||
leaveFrom="opacity-100 translate-y-0 sm:scale-100"
|
||||
leaveTo="opacity-0 translate-y-4 sm:translate-y-0 sm:scale-95"
|
||||
>
|
||||
<Dialog.Panel className="relative transform overflow-hidden rounded-lg bg-surface-1 px-5 py-8 text-left shadow-raised-200 transition-all sm:w-full sm:max-w-xl sm:p-6">
|
||||
<div className="space-y-5">
|
||||
<Dialog.Title as="h3" className="text-16 font-medium leading-6 text-primary">
|
||||
Upload image
|
||||
</Dialog.Title>
|
||||
<ModalCore isOpen={isOpen} handleClose={handleClose} position={EModalPosition.CENTER} width={EModalWidth.XL}>
|
||||
<div className="space-y-5 px-5 py-8 sm:p-6">
|
||||
<h3 className="text-16 font-medium leading-6 text-primary">Upload image</h3>
|
||||
<div className="space-y-3">
|
||||
<div className="flex items-center justify-center gap-3">
|
||||
<div
|
||||
|
|
@ -175,38 +148,21 @@ export const WorkspaceImageUploadModal = observer(function WorkspaceImageUploadM
|
|||
</p>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
<p className="my-4 text-13 text-secondary">File formats supported- .jpeg, .jpg, .png, .webp</p>
|
||||
<div className="flex items-center justify-between">
|
||||
<Button
|
||||
variant="error-fill"
|
||||
size="lg"
|
||||
onClick={handleImageRemove}
|
||||
disabled={!value}
|
||||
loading={isRemoving}
|
||||
>
|
||||
<Button variant="error-fill" size="lg" onClick={handleImageRemove} disabled={!value} loading={isRemoving}>
|
||||
{isRemoving ? "Removing" : "Remove"}
|
||||
</Button>
|
||||
<div className="flex items-center gap-2">
|
||||
<Button variant="secondary" size="lg" onClick={handleClose}>
|
||||
Cancel
|
||||
</Button>
|
||||
<Button
|
||||
variant="primary"
|
||||
size="lg"
|
||||
onClick={handleSubmit}
|
||||
disabled={!image}
|
||||
loading={isImageUploading}
|
||||
>
|
||||
<Button variant="primary" size="lg" onClick={handleSubmit} disabled={!image} loading={isImageUploading}>
|
||||
{isImageUploading ? "Uploading" : "Upload & Save"}
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
</Dialog.Panel>
|
||||
</Transition.Child>
|
||||
</div>
|
||||
</div>
|
||||
</Dialog>
|
||||
</Transition.Root>
|
||||
</ModalCore>
|
||||
);
|
||||
});
|
||||
|
|
|
|||
|
|
@ -1,9 +1,9 @@
|
|||
import { useState, Fragment } from "react";
|
||||
import { Dialog, Transition } from "@headlessui/react";
|
||||
import { useState } from "react";
|
||||
// ui
|
||||
import { CYCLE_TRACKER_EVENTS } from "@plane/constants";
|
||||
import { Button } from "@plane/propel/button";
|
||||
import { TOAST_TYPE, setToast } from "@plane/propel/toast";
|
||||
import { EModalPosition, EModalWidth, ModalCore } from "@plane/ui";
|
||||
// hooks
|
||||
import { captureError, captureSuccess } from "@/helpers/event-tracker.helper";
|
||||
import { useCycle } from "@/hooks/store/use-cycle";
|
||||
|
|
@ -51,6 +51,7 @@ export function ArchiveCycleModal(props: Props) {
|
|||
});
|
||||
onClose();
|
||||
router.push(`/${workspaceSlug}/projects/${projectId}/cycles`);
|
||||
return;
|
||||
})
|
||||
.catch(() => {
|
||||
setToast({
|
||||
|
|
@ -69,32 +70,7 @@ export function ArchiveCycleModal(props: Props) {
|
|||
};
|
||||
|
||||
return (
|
||||
<Transition.Root 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-in duration-200"
|
||||
leaveFrom="opacity-100"
|
||||
leaveTo="opacity-0"
|
||||
>
|
||||
<div className="fixed inset-0 bg-backdrop transition-opacity" />
|
||||
</Transition.Child>
|
||||
|
||||
<div className="fixed inset-0 z-10 overflow-y-auto">
|
||||
<div className="flex min-h-full items-end justify-center p-4 text-center sm:items-center sm:p-0">
|
||||
<Transition.Child
|
||||
as={Fragment}
|
||||
enter="ease-out duration-300"
|
||||
enterFrom="opacity-0 translate-y-4 sm:translate-y-0 sm:scale-95"
|
||||
enterTo="opacity-100 translate-y-0 sm:scale-100"
|
||||
leave="ease-in duration-200"
|
||||
leaveFrom="opacity-100 translate-y-0 sm:scale-100"
|
||||
leaveTo="opacity-0 translate-y-4 sm:translate-y-0 sm:scale-95"
|
||||
>
|
||||
<Dialog.Panel className="relative transform overflow-hidden rounded-lg bg-surface-1 text-left shadow-raised-200 transition-all sm:my-8 sm:w-full sm:max-w-lg">
|
||||
<ModalCore isOpen={isOpen} handleClose={onClose} position={EModalPosition.CENTER} width={EModalWidth.LG}>
|
||||
<div className="px-5 py-4">
|
||||
<h3 className="text-18 font-medium 2xl:text-20">Archive cycle {cycleName}</h3>
|
||||
<p className="mt-3 text-13 text-secondary">
|
||||
|
|
@ -109,11 +85,6 @@ export function ArchiveCycleModal(props: Props) {
|
|||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
</Dialog.Panel>
|
||||
</Transition.Child>
|
||||
</div>
|
||||
</div>
|
||||
</Dialog>
|
||||
</Transition.Root>
|
||||
</ModalCore>
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,15 +1,13 @@
|
|||
import React, { useState } from "react";
|
||||
import { useState } from "react";
|
||||
import { observer } from "mobx-react";
|
||||
import { useParams } from "next/navigation";
|
||||
import { AlertCircle, Search } from "lucide-react";
|
||||
import { Dialog, Transition } from "@headlessui/react";
|
||||
import { CycleIcon, TransferIcon, CloseIcon } from "@plane/propel/icons";
|
||||
import { TOAST_TYPE, setToast } from "@plane/propel/toast";
|
||||
import { EIssuesStoreType } from "@plane/types";
|
||||
import { EModalPosition, EModalWidth, ModalCore } from "@plane/ui";
|
||||
import { useCycle } from "@/hooks/store/use-cycle";
|
||||
import { useIssues } from "@/hooks/store/use-issues";
|
||||
//icons
|
||||
// constants
|
||||
|
||||
type Props = {
|
||||
isOpen: boolean;
|
||||
|
|
@ -72,42 +70,9 @@ export const TransferIssuesModal = observer(function TransferIssuesModal(props:
|
|||
return cycleDetails?.name?.toLowerCase().includes(query?.toLowerCase());
|
||||
});
|
||||
|
||||
// useEffect(() => {
|
||||
// const handleKeyDown = (e: KeyboardEvent) => {
|
||||
// if (e.key === "Escape") {
|
||||
// handleClose();
|
||||
// }
|
||||
// };
|
||||
// }, [handleClose]);
|
||||
|
||||
return (
|
||||
<Transition.Root show={isOpen} as={React.Fragment}>
|
||||
<Dialog as="div" className="relative z-20" onClose={handleClose}>
|
||||
<Transition.Child
|
||||
as={React.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-backdrop transition-opacity" />
|
||||
</Transition.Child>
|
||||
|
||||
<div className="fixed inset-0 z-10">
|
||||
<div className="mt-10 flex min-h-full items-start justify-center p-4 text-center sm:p-0 md:mt-20">
|
||||
<Transition.Child
|
||||
as={React.Fragment}
|
||||
enter="ease-out duration-300"
|
||||
enterFrom="opacity-0 translate-y-4 sm:translate-y-0 sm:scale-95"
|
||||
enterTo="opacity-100 translate-y-0 sm:scale-100"
|
||||
leave="ease-in duration-200"
|
||||
leaveFrom="opacity-100 translate-y-0 sm:scale-100"
|
||||
leaveTo="opacity-0 translate-y-4 sm:translate-y-0 sm:scale-95"
|
||||
>
|
||||
<Dialog.Panel className="relative transform rounded-lg bg-surface-1 py-5 text-left shadow-raised-200 transition-all sm:w-full sm:max-w-2xl">
|
||||
<div className="flex flex-col gap-4">
|
||||
<ModalCore isOpen={isOpen} handleClose={handleClose} position={EModalPosition.TOP} width={EModalWidth.XXL}>
|
||||
<div className="flex flex-col gap-4 py-5">
|
||||
<div className="flex items-center justify-between px-5">
|
||||
<div className="flex items-center gap-1">
|
||||
<TransferIcon className="w-5 fill-primary" />
|
||||
|
|
@ -170,11 +135,6 @@ export const TransferIssuesModal = observer(function TransferIssuesModal(props:
|
|||
)}
|
||||
</div>
|
||||
</div>
|
||||
</Dialog.Panel>
|
||||
</Transition.Child>
|
||||
</div>
|
||||
</div>
|
||||
</Dialog>
|
||||
</Transition.Root>
|
||||
</ModalCore>
|
||||
);
|
||||
});
|
||||
|
|
|
|||
|
|
@ -2,14 +2,13 @@ import React, { useState } from "react";
|
|||
import { intersection } from "lodash-es";
|
||||
import { observer } from "mobx-react";
|
||||
import { useParams } from "next/navigation";
|
||||
import { Dialog, Transition } from "@headlessui/react";
|
||||
// types
|
||||
import { useTranslation } from "@plane/i18n";
|
||||
import { Button } from "@plane/propel/button";
|
||||
import { TOAST_TYPE, setToast } from "@plane/propel/toast";
|
||||
import type { IUser, IImporterService } from "@plane/types";
|
||||
// ui
|
||||
import { Checkbox, CustomSearchSelect } from "@plane/ui";
|
||||
import { Checkbox, CustomSearchSelect, EModalPosition, EModalWidth, ModalCore } from "@plane/ui";
|
||||
// hooks
|
||||
import { useProject } from "@/hooks/store/use-project";
|
||||
import { useUser } from "@/hooks/store/user";
|
||||
|
|
@ -99,38 +98,14 @@ export const Exporter = observer(function Exporter(props: Props) {
|
|||
}
|
||||
|
||||
return (
|
||||
<Transition.Root show={isOpen} as={React.Fragment}>
|
||||
<Dialog
|
||||
as="div"
|
||||
className="relative z-20"
|
||||
onClose={() => {
|
||||
<ModalCore
|
||||
isOpen={isOpen}
|
||||
handleClose={() => {
|
||||
if (!isSelectOpen) handleClose();
|
||||
}}
|
||||
position={EModalPosition.CENTER}
|
||||
width={EModalWidth.XL}
|
||||
>
|
||||
<Transition.Child
|
||||
as={React.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-backdrop transition-opacity" />
|
||||
</Transition.Child>
|
||||
|
||||
<div className="fixed inset-0 z-20 overflow-y-auto">
|
||||
<div className="flex min-h-full items-center justify-center p-4 text-center sm:p-0">
|
||||
<Transition.Child
|
||||
as={React.Fragment}
|
||||
enter="ease-out duration-300"
|
||||
enterFrom="opacity-0 translate-y-4 sm:translate-y-0 sm:scale-95"
|
||||
enterTo="opacity-100 translate-y-0 sm:scale-100"
|
||||
leave="ease-in duration-200"
|
||||
leaveFrom="opacity-100 translate-y-0 sm:scale-100"
|
||||
leaveTo="opacity-0 translate-y-4 sm:translate-y-0 sm:scale-95"
|
||||
>
|
||||
<Dialog.Panel className="relative transform rounded-lg bg-surface-1 text-left shadow-raised-200 transition-all sm:my-8 sm:w-full sm:max-w-xl">
|
||||
<div className="flex flex-col gap-6 gap-y-4 p-6">
|
||||
<div className="flex w-full items-center justify-start gap-6">
|
||||
<span className="flex items-center justify-start">
|
||||
|
|
@ -164,10 +139,7 @@ export const Exporter = observer(function Exporter(props: Props) {
|
|||
multiple
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
onClick={() => setMultiple(!multiple)}
|
||||
className="flex max-w-min cursor-pointer items-center gap-2"
|
||||
>
|
||||
<div className="flex max-w-min cursor-pointer items-center gap-2">
|
||||
<Checkbox checked={multiple} onChange={() => setMultiple(!multiple)} />
|
||||
<div className="whitespace-nowrap text-13">
|
||||
{t("workspace_settings.settings.exports.export_separate_files")}
|
||||
|
|
@ -177,23 +149,13 @@ export const Exporter = observer(function Exporter(props: Props) {
|
|||
<Button variant="secondary" onClick={handleClose}>
|
||||
{t("cancel")}
|
||||
</Button>
|
||||
<Button
|
||||
variant="primary"
|
||||
onClick={ExportCSVToMail}
|
||||
disabled={exportLoading}
|
||||
loading={exportLoading}
|
||||
>
|
||||
<Button variant="primary" onClick={ExportCSVToMail} disabled={exportLoading} loading={exportLoading}>
|
||||
{exportLoading
|
||||
? `${t("workspace_settings.settings.exports.exporting")}...`
|
||||
: t("workspace_settings.settings.exports.title")}
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
</Dialog.Panel>
|
||||
</Transition.Child>
|
||||
</div>
|
||||
</div>
|
||||
</Dialog>
|
||||
</Transition.Root>
|
||||
</ModalCore>
|
||||
);
|
||||
});
|
||||
|
|
|
|||
|
|
@ -1,13 +1,13 @@
|
|||
import React, { useEffect, useState } from "react";
|
||||
import { useEffect, useState } from "react";
|
||||
import { useParams } from "next/navigation";
|
||||
import { useTheme } from "next-themes";
|
||||
import { Search } from "lucide-react";
|
||||
import { Combobox, Dialog, Transition } from "@headlessui/react";
|
||||
import { Combobox } from "@headlessui/react";
|
||||
// plane imports
|
||||
import { useTranslation } from "@plane/i18n";
|
||||
import { TOAST_TYPE, setToast } from "@plane/propel/toast";
|
||||
import type { ISearchIssueResponse } from "@plane/types";
|
||||
import { Loader } from "@plane/ui";
|
||||
import { Loader, EModalPosition, EModalWidth, ModalCore } from "@plane/ui";
|
||||
// assets
|
||||
import darkIssuesAsset from "@/app/assets/empty-state/search/issues-dark.webp?url";
|
||||
import lightIssuesAsset from "@/app/assets/empty-state/search/issues-light.webp?url";
|
||||
|
|
@ -65,6 +65,7 @@ export function SelectDuplicateInboxIssueModal(props: Props) {
|
|||
|
||||
const handleClose = () => {
|
||||
onClose();
|
||||
setQuery("");
|
||||
};
|
||||
|
||||
const handleSubmit = (selectedItem: string) => {
|
||||
|
|
@ -124,33 +125,7 @@ export function SelectDuplicateInboxIssueModal(props: Props) {
|
|||
);
|
||||
|
||||
return (
|
||||
<Transition.Root show={isOpen} as={React.Fragment} afterLeave={() => setQuery("")} appear>
|
||||
<div className="flex flex-wrap items-start">
|
||||
<div className="space-y-1 sm:basis-1/2">
|
||||
<Dialog as="div" className="relative z-30" onClose={handleClose}>
|
||||
<Transition.Child
|
||||
as={React.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-backdrop transition-opacity" />
|
||||
</Transition.Child>
|
||||
|
||||
<div className="fixed inset-0 z-30 overflow-y-auto p-4 sm:p-6 md:p-20">
|
||||
<Transition.Child
|
||||
as={React.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="relative mx-auto max-w-2xl transform rounded-lg bg-surface-1 shadow-raised-200 transition-all">
|
||||
<ModalCore isOpen={isOpen} handleClose={handleClose} position={EModalPosition.CENTER} width={EModalWidth.XXL}>
|
||||
<Combobox value={value} onChange={handleSubmit}>
|
||||
<div className="relative m-1">
|
||||
<Search
|
||||
|
|
@ -178,12 +153,6 @@ export function SelectDuplicateInboxIssueModal(props: Props) {
|
|||
)}
|
||||
</Combobox.Options>
|
||||
</Combobox>
|
||||
</Dialog.Panel>
|
||||
</Transition.Child>
|
||||
</div>
|
||||
</Dialog>
|
||||
</div>
|
||||
</div>
|
||||
</Transition.Root>
|
||||
</ModalCore>
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,10 +1,9 @@
|
|||
import type { FC } from "react";
|
||||
import { Fragment, useState } from "react";
|
||||
import { Dialog, Transition } from "@headlessui/react";
|
||||
import { useState } from "react";
|
||||
// ui
|
||||
import { useTranslation } from "@plane/i18n";
|
||||
import { Button } from "@plane/propel/button";
|
||||
import { Calendar } from "@plane/propel/calendar";
|
||||
import { EModalPosition, EModalWidth, ModalCore } from "@plane/ui";
|
||||
|
||||
export type InboxIssueSnoozeModalProps = {
|
||||
isOpen: boolean;
|
||||
|
|
@ -21,32 +20,8 @@ export function InboxIssueSnoozeModal(props: InboxIssueSnoozeModalProps) {
|
|||
const { t } = useTranslation();
|
||||
|
||||
return (
|
||||
<Transition.Root show={isOpen} as={Fragment}>
|
||||
<Dialog as="div" className="relative z-20" onClose={handleClose}>
|
||||
<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-backdrop transition-opacity" />
|
||||
</Transition.Child>
|
||||
<div className="fixed inset-0 z-20 flex w-full justify-center overflow-y-auto">
|
||||
<div className="flex min-h-full items-center justify-center p-4 text-center sm:p-0">
|
||||
<Transition.Child
|
||||
as={Fragment}
|
||||
enter="ease-out duration-300"
|
||||
enterFrom="opacity-0 translate-y-4 sm:translate-y-0 sm:scale-95"
|
||||
enterTo="opacity-100 translate-y-0 sm:scale-100"
|
||||
leave="ease-in duration-200"
|
||||
leaveFrom="opacity-100 translate-y-0 sm:scale-100"
|
||||
leaveTo="opacity-0 translate-y-4 sm:translate-y-0 sm:scale-95"
|
||||
>
|
||||
<Dialog.Panel className="relative flex transform rounded-lg bg-surface-1 px-5 py-8 text-left shadow-raised-200 transition-all sm:my-8 sm:w-full sm:max-w-2xl sm:p-6">
|
||||
<div className="flex h-full w-full flex-col gap-y-1">
|
||||
<ModalCore isOpen={isOpen} handleClose={handleClose} position={EModalPosition.CENTER} width={EModalWidth.XXL}>
|
||||
<div className="flex h-full w-full flex-col gap-y-1 px-5 py-8 sm:p-6">
|
||||
<Calendar
|
||||
className="rounded-md border border-subtle p-3"
|
||||
captionLayout="dropdown"
|
||||
|
|
@ -66,18 +41,13 @@ export function InboxIssueSnoozeModal(props: InboxIssueSnoozeModalProps) {
|
|||
<Button
|
||||
variant="primary"
|
||||
onClick={() => {
|
||||
close();
|
||||
handleClose();
|
||||
onConfirm(date);
|
||||
}}
|
||||
>
|
||||
{t("inbox_issue.actions.snooze")}
|
||||
</Button>
|
||||
</div>
|
||||
</Dialog.Panel>
|
||||
</Transition.Child>
|
||||
</div>
|
||||
</div>
|
||||
</Dialog>
|
||||
</Transition.Root>
|
||||
</ModalCore>
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,23 +1,15 @@
|
|||
import React, { useState } from "react";
|
||||
|
||||
import { useState } from "react";
|
||||
import { useParams } from "next/navigation";
|
||||
|
||||
import { mutate } from "swr";
|
||||
|
||||
// headless ui
|
||||
// icons
|
||||
import { AlertTriangle } from "lucide-react";
|
||||
import { Dialog, Transition } from "@headlessui/react";
|
||||
// services
|
||||
import { Button } from "@plane/propel/button";
|
||||
import { TOAST_TYPE, setToast } from "@plane/propel/toast";
|
||||
import type { IUser, IImporterService } from "@plane/types";
|
||||
import { Input } from "@plane/ui";
|
||||
import { Input, EModalPosition, EModalWidth, ModalCore } from "@plane/ui";
|
||||
import { IMPORTER_SERVICES_LIST } from "@/constants/fetch-keys";
|
||||
import { IntegrationService } from "@/services/integrations/integration.service";
|
||||
// ui
|
||||
// icons
|
||||
// types
|
||||
// fetch-keys
|
||||
|
||||
type Props = {
|
||||
isOpen: boolean;
|
||||
|
|
@ -64,32 +56,7 @@ export function DeleteImportModal({ isOpen, handleClose, data }: Props) {
|
|||
if (!data) return <></>;
|
||||
|
||||
return (
|
||||
<Transition.Root show={isOpen} as={React.Fragment}>
|
||||
<Dialog as="div" className="relative z-20" onClose={handleClose}>
|
||||
<Transition.Child
|
||||
as={React.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-backdrop transition-opacity" />
|
||||
</Transition.Child>
|
||||
|
||||
<div className="fixed inset-0 z-20 overflow-y-auto">
|
||||
<div className="flex min-h-full items-end justify-center p-4 text-center sm:items-center sm:p-0">
|
||||
<Transition.Child
|
||||
as={React.Fragment}
|
||||
enter="ease-out duration-300"
|
||||
enterFrom="opacity-0 translate-y-4 sm:translate-y-0 sm:scale-95"
|
||||
enterTo="opacity-100 translate-y-0 sm:scale-100"
|
||||
leave="ease-in duration-200"
|
||||
leaveFrom="opacity-100 translate-y-0 sm:scale-100"
|
||||
leaveTo="opacity-0 translate-y-4 sm:translate-y-0 sm:scale-95"
|
||||
>
|
||||
<Dialog.Panel className="relative transform overflow-hidden rounded-lg bg-surface-1 text-left shadow-raised-200 transition-all sm:my-8 sm:w-full sm:max-w-2xl">
|
||||
<ModalCore isOpen={isOpen} handleClose={handleClose} position={EModalPosition.CENTER} width={EModalWidth.XXL}>
|
||||
<div className="flex flex-col gap-6 p-6">
|
||||
<div className="flex w-full items-center justify-start gap-6">
|
||||
<span className="place-items-center rounded-full bg-red-500/20 p-4">
|
||||
|
|
@ -102,8 +69,8 @@ export function DeleteImportModal({ isOpen, handleClose, data }: Props) {
|
|||
<span>
|
||||
<p className="text-13 leading-7 text-secondary">
|
||||
Are you sure you want to delete import from{" "}
|
||||
<span className="break-words font-semibold capitalize text-primary">{data?.service}</span>? All of
|
||||
the data related to the import will be permanently removed. This action cannot be undone.
|
||||
<span className="break-words font-semibold capitalize text-primary">{data?.service}</span>? All of the data
|
||||
related to the import will be permanently removed. This action cannot be undone.
|
||||
</p>
|
||||
</span>
|
||||
<div>
|
||||
|
|
@ -138,11 +105,6 @@ export function DeleteImportModal({ isOpen, handleClose, data }: Props) {
|
|||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
</Dialog.Panel>
|
||||
</Transition.Child>
|
||||
</div>
|
||||
</div>
|
||||
</Dialog>
|
||||
</Transition.Root>
|
||||
</ModalCore>
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,11 +1,11 @@
|
|||
import { useState, Fragment } from "react";
|
||||
import { Dialog, Transition } from "@headlessui/react";
|
||||
import { useState } from "react";
|
||||
// i18n
|
||||
import { useTranslation } from "@plane/i18n";
|
||||
// types
|
||||
import { Button } from "@plane/propel/button";
|
||||
import { TOAST_TYPE, setToast } from "@plane/propel/toast";
|
||||
import type { TDeDupeIssue, TIssue } from "@plane/types";
|
||||
import { EModalPosition, EModalWidth, ModalCore } from "@plane/ui";
|
||||
// hooks
|
||||
import { useIssues } from "@/hooks/store/use-issues";
|
||||
import { useProject } from "@/hooks/store/use-project";
|
||||
|
|
@ -49,6 +49,7 @@ export function ArchiveIssueModal(props: Props) {
|
|||
message: t("issue.archive.success.message"),
|
||||
});
|
||||
onClose();
|
||||
return;
|
||||
})
|
||||
.catch(() =>
|
||||
setToast({
|
||||
|
|
@ -61,32 +62,7 @@ export function ArchiveIssueModal(props: Props) {
|
|||
};
|
||||
|
||||
return (
|
||||
<Transition.Root show={isOpen} as={Fragment}>
|
||||
<Dialog as="div" className="relative z-30" onClose={onClose}>
|
||||
<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-backdrop transition-opacity" />
|
||||
</Transition.Child>
|
||||
|
||||
<div className="fixed inset-0 z-30 overflow-y-auto">
|
||||
<div className="flex min-h-full items-end justify-center p-4 text-center sm:items-center sm:p-0">
|
||||
<Transition.Child
|
||||
as={Fragment}
|
||||
enter="ease-out duration-300"
|
||||
enterFrom="opacity-0 translate-y-4 sm:translate-y-0 sm:scale-95"
|
||||
enterTo="opacity-100 translate-y-0 sm:scale-100"
|
||||
leave="ease-in duration-200"
|
||||
leaveFrom="opacity-100 translate-y-0 sm:scale-100"
|
||||
leaveTo="opacity-0 translate-y-4 sm:translate-y-0 sm:scale-95"
|
||||
>
|
||||
<Dialog.Panel className="relative transform overflow-hidden rounded-lg bg-surface-1 text-left shadow-raised-200 transition-all sm:my-8 sm:w-full sm:max-w-lg">
|
||||
<ModalCore isOpen={isOpen} handleClose={onClose} position={EModalPosition.CENTER} width={EModalWidth.LG}>
|
||||
<div className="px-5 py-4">
|
||||
<h3 className="text-18 font-medium 2xl:text-20">
|
||||
{t("issue.archive.label")} {projectDetails?.identifier} {issue.sequence_id}
|
||||
|
|
@ -101,11 +77,6 @@ export function ArchiveIssueModal(props: Props) {
|
|||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
</Dialog.Panel>
|
||||
</Transition.Child>
|
||||
</div>
|
||||
</div>
|
||||
</Dialog>
|
||||
</Transition.Root>
|
||||
</ModalCore>
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,9 +1,7 @@
|
|||
import React, { useState } from "react";
|
||||
|
||||
// headless ui
|
||||
import { Dialog, Transition } from "@headlessui/react";
|
||||
import { useState } from "react";
|
||||
// ui
|
||||
import { Button } from "@plane/propel/button";
|
||||
import { EModalPosition, EModalWidth, ModalCore } from "@plane/ui";
|
||||
|
||||
type Props = {
|
||||
isOpen: boolean;
|
||||
|
|
@ -29,38 +27,11 @@ export function ConfirmIssueDiscard(props: Props) {
|
|||
};
|
||||
|
||||
return (
|
||||
<Transition.Root show={isOpen} as={React.Fragment}>
|
||||
<Dialog as="div" className="relative z-30" onClose={handleClose}>
|
||||
<Transition.Child
|
||||
as={React.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-backdrop transition-opacity" />
|
||||
</Transition.Child>
|
||||
|
||||
<div className="fixed inset-0 z-30 overflow-y-auto">
|
||||
<div className="my-10 flex items-center justify-center p-4 text-center sm:p-0 md:my-32">
|
||||
<Transition.Child
|
||||
as={React.Fragment}
|
||||
enter="ease-out duration-300"
|
||||
enterFrom="opacity-0 translate-y-4 sm:translate-y-0 sm:scale-95"
|
||||
enterTo="opacity-100 translate-y-0 sm:scale-100"
|
||||
leave="ease-in duration-200"
|
||||
leaveFrom="opacity-100 translate-y-0 sm:scale-100"
|
||||
leaveTo="opacity-0 translate-y-4 sm:translate-y-0 sm:scale-95"
|
||||
>
|
||||
<Dialog.Panel className="relative transform overflow-hidden rounded-lg bg-surface-1 text-left shadow-raised-200 transition-all sm:my-8 sm:w-[40rem]">
|
||||
<ModalCore isOpen={isOpen} handleClose={handleClose} position={EModalPosition.TOP} width={EModalWidth.XXL}>
|
||||
<div className="px-4 pb-4 pt-5 sm:p-6 sm:pb-4">
|
||||
<div className="sm:flex sm:items-start">
|
||||
<div className="mt-3 text-center sm:mt-0 sm:text-left">
|
||||
<Dialog.Title as="h3" className="text-16 font-medium leading-6 text-primary">
|
||||
Save this draft?
|
||||
</Dialog.Title>
|
||||
<h3 className="text-16 font-medium leading-6 text-primary">Save this draft?</h3>
|
||||
<div className="mt-2">
|
||||
<p className="text-13 text-secondary">
|
||||
You can save this work item to Drafts so you can come back to it later.{" "}
|
||||
|
|
@ -84,11 +55,6 @@ export function ConfirmIssueDiscard(props: Props) {
|
|||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
</Dialog.Panel>
|
||||
</Transition.Child>
|
||||
</div>
|
||||
</div>
|
||||
</Dialog>
|
||||
</Transition.Root>
|
||||
</ModalCore>
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,13 +3,13 @@ import { useParams } from "next/navigation";
|
|||
// icons
|
||||
import { Rocket, Search } from "lucide-react";
|
||||
// headless ui
|
||||
import { Combobox, Dialog, Transition } from "@headlessui/react";
|
||||
import { Combobox } from "@headlessui/react";
|
||||
// i18n
|
||||
import { useTranslation } from "@plane/i18n";
|
||||
// types
|
||||
import type { ISearchIssueResponse } from "@plane/types";
|
||||
// ui
|
||||
import { Loader } from "@plane/ui";
|
||||
import { Loader, EModalPosition, EModalWidth, ModalCore } from "@plane/ui";
|
||||
import { generateWorkItemLink, getTabIndex } from "@plane/utils";
|
||||
// components
|
||||
import { IssueSearchModalEmptyState } from "@/components/core/modals/issue-search-modal-empty-state";
|
||||
|
|
@ -85,32 +85,7 @@ export function ParentIssuesListModal({
|
|||
}, [debouncedSearchTerm, isOpen, issueId, projectId, workspaceSlug]);
|
||||
|
||||
return (
|
||||
<>
|
||||
<Transition.Root show={isOpen} as={React.Fragment} afterLeave={() => setSearchTerm("")} appear>
|
||||
<Dialog as="div" className="relative z-30" onClose={handleClose}>
|
||||
<Transition.Child
|
||||
as={React.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-backdrop transition-opacity" />
|
||||
</Transition.Child>
|
||||
|
||||
<div className="fixed inset-0 z-30 overflow-y-auto p-4 sm:p-6 md:p-20">
|
||||
<Transition.Child
|
||||
as={React.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="relative mx-auto max-w-2xl transform rounded-lg bg-surface-1 shadow-raised-200 transition-all">
|
||||
<ModalCore isOpen={isOpen} handleClose={handleClose} position={EModalPosition.CENTER} width={EModalWidth.XXL}>
|
||||
<Combobox
|
||||
value={value}
|
||||
onChange={(val) => {
|
||||
|
|
@ -132,10 +107,7 @@ export function ParentIssuesListModal({
|
|||
tabIndex={baseTabIndex}
|
||||
/>
|
||||
</div>
|
||||
<Combobox.Options
|
||||
static
|
||||
className="max-h-80 scroll-py-2 overflow-y-auto vertical-scrollbar scrollbar-md"
|
||||
>
|
||||
<Combobox.Options static className="max-h-80 scroll-py-2 overflow-y-auto vertical-scrollbar scrollbar-md">
|
||||
{searchTerm !== "" && (
|
||||
<h5 className="mx-2 text-13 text-secondary">
|
||||
Search results for{" "}
|
||||
|
|
@ -218,11 +190,6 @@ export function ParentIssuesListModal({
|
|||
)}
|
||||
</Combobox.Options>
|
||||
</Combobox>
|
||||
</Dialog.Panel>
|
||||
</Transition.Child>
|
||||
</div>
|
||||
</Dialog>
|
||||
</Transition.Root>
|
||||
</>
|
||||
</ModalCore>
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
import { useState, Fragment } from "react";
|
||||
import { Dialog, Transition } from "@headlessui/react";
|
||||
import { useState } from "react";
|
||||
// ui
|
||||
import { Button } from "@plane/propel/button";
|
||||
import { TOAST_TYPE, setToast } from "@plane/propel/toast";
|
||||
import { EModalPosition, EModalWidth, ModalCore } from "@plane/ui";
|
||||
// hooks
|
||||
import { useModule } from "@/hooks/store/use-module";
|
||||
import { useAppRouter } from "@/hooks/use-app-router";
|
||||
|
|
@ -43,6 +43,7 @@ export function ArchiveModuleModal(props: Props) {
|
|||
});
|
||||
onClose();
|
||||
router.push(`/${workspaceSlug}/projects/${projectId}/modules`);
|
||||
return;
|
||||
})
|
||||
.catch(() =>
|
||||
setToast({
|
||||
|
|
@ -55,32 +56,7 @@ export function ArchiveModuleModal(props: Props) {
|
|||
};
|
||||
|
||||
return (
|
||||
<Transition.Root 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-in duration-200"
|
||||
leaveFrom="opacity-100"
|
||||
leaveTo="opacity-0"
|
||||
>
|
||||
<div className="fixed inset-0 bg-backdrop transition-opacity" />
|
||||
</Transition.Child>
|
||||
|
||||
<div className="fixed inset-0 z-10 overflow-y-auto">
|
||||
<div className="flex min-h-full items-end justify-center p-4 text-center sm:items-center sm:p-0">
|
||||
<Transition.Child
|
||||
as={Fragment}
|
||||
enter="ease-out duration-300"
|
||||
enterFrom="opacity-0 translate-y-4 sm:translate-y-0 sm:scale-95"
|
||||
enterTo="opacity-100 translate-y-0 sm:scale-100"
|
||||
leave="ease-in duration-200"
|
||||
leaveFrom="opacity-100 translate-y-0 sm:scale-100"
|
||||
leaveTo="opacity-0 translate-y-4 sm:translate-y-0 sm:scale-95"
|
||||
>
|
||||
<Dialog.Panel className="relative transform overflow-hidden rounded-lg bg-surface-1 text-left shadow-raised-200 transition-all sm:my-8 sm:w-full sm:max-w-lg">
|
||||
<ModalCore isOpen={isOpen} handleClose={onClose} position={EModalPosition.CENTER} width={EModalWidth.LG}>
|
||||
<div className="px-5 py-4">
|
||||
<h3 className="text-18 font-medium 2xl:text-20">Archive module {moduleName}</h3>
|
||||
<p className="mt-3 text-13 text-secondary">
|
||||
|
|
@ -90,22 +66,11 @@ export function ArchiveModuleModal(props: Props) {
|
|||
<Button variant="secondary" size="lg" onClick={onClose}>
|
||||
Cancel
|
||||
</Button>
|
||||
<Button
|
||||
variant="primary"
|
||||
size="lg"
|
||||
tabIndex={1}
|
||||
onClick={handleArchiveModule}
|
||||
loading={isArchiving}
|
||||
>
|
||||
<Button variant="primary" size="lg" tabIndex={1} onClick={handleArchiveModule} loading={isArchiving}>
|
||||
{isArchiving ? "Archiving" : "Archive"}
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
</Dialog.Panel>
|
||||
</Transition.Child>
|
||||
</div>
|
||||
</div>
|
||||
</Dialog>
|
||||
</Transition.Root>
|
||||
</ModalCore>
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,13 +1,12 @@
|
|||
import React, { useState } from "react";
|
||||
import { useState } from "react";
|
||||
import { observer } from "mobx-react";
|
||||
import { useParams } from "next/navigation";
|
||||
import { AlertTriangle } from "lucide-react";
|
||||
// headless ui
|
||||
import { Dialog, Transition } from "@headlessui/react";
|
||||
// types
|
||||
import { Button } from "@plane/propel/button";
|
||||
import type { IUserLite } from "@plane/types";
|
||||
// ui
|
||||
import { EModalPosition, EModalWidth, ModalCore } from "@plane/ui";
|
||||
// hooks
|
||||
import { useProject } from "@/hooks/store/use-project";
|
||||
import { useUser } from "@/hooks/store/user";
|
||||
|
|
@ -48,54 +47,27 @@ export const ConfirmProjectMemberRemove = observer(function ConfirmProjectMember
|
|||
const currentProjectDetails = getProjectById(projectId.toString());
|
||||
|
||||
return (
|
||||
<Transition.Root show={isOpen} as={React.Fragment}>
|
||||
<Dialog as="div" className="relative z-20" onClose={handleClose}>
|
||||
<Transition.Child
|
||||
as={React.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-backdrop transition-opacity" />
|
||||
</Transition.Child>
|
||||
|
||||
<div className="fixed inset-0 z-20 overflow-y-auto">
|
||||
<div className="flex min-h-full items-end justify-center p-4 text-center sm:items-center sm:p-0">
|
||||
<Transition.Child
|
||||
as={React.Fragment}
|
||||
enter="ease-out duration-300"
|
||||
enterFrom="opacity-0 translate-y-4 sm:translate-y-0 sm:scale-95"
|
||||
enterTo="opacity-100 translate-y-0 sm:scale-100"
|
||||
leave="ease-in duration-200"
|
||||
leaveFrom="opacity-100 translate-y-0 sm:scale-100"
|
||||
leaveTo="opacity-0 translate-y-4 sm:translate-y-0 sm:scale-95"
|
||||
>
|
||||
<Dialog.Panel className="relative transform overflow-hidden rounded-lg bg-surface-1 text-left shadow-raised-200 transition-all sm:my-8 sm:w-[40rem]">
|
||||
<ModalCore isOpen={isOpen} handleClose={handleClose} position={EModalPosition.CENTER} width={EModalWidth.XXL}>
|
||||
<div className="bg-surface-1 px-4 pb-4 pt-5 sm:p-6 sm:pb-4">
|
||||
<div className="sm:flex sm:items-start">
|
||||
<div className="mx-auto flex h-12 w-12 flex-shrink-0 items-center justify-center rounded-full bg-red-100 sm:mx-0 sm:h-10 sm:w-10">
|
||||
<AlertTriangle className="h-6 w-6 text-red-600" aria-hidden="true" />
|
||||
</div>
|
||||
<div className="mt-3 text-center sm:ml-4 sm:mt-0 sm:text-left">
|
||||
<Dialog.Title as="h3" className="text-16 font-medium leading-6 text-primary">
|
||||
<h3 className="text-16 font-medium leading-6 text-primary">
|
||||
{isCurrentUser ? "Leave project?" : `Remove ${data?.display_name}?`}
|
||||
</Dialog.Title>
|
||||
</h3>
|
||||
<div className="mt-2">
|
||||
<p className="text-13 text-secondary">
|
||||
{isCurrentUser ? (
|
||||
<>
|
||||
Are you sure you want to leave the{" "}
|
||||
<span className="font-bold">{currentProjectDetails?.name}</span> project? You will be able
|
||||
to join the project if invited again or if it{"'"}s public.
|
||||
Are you sure you want to leave the <span className="font-bold">{currentProjectDetails?.name}</span>{" "}
|
||||
project? You will be able to join the project if invited again or if it{"'"}s public.
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
Are you sure you want to remove member-{" "}
|
||||
<span className="font-bold">{data?.display_name}</span>? They will no longer have access
|
||||
to this project. This action cannot be undone.
|
||||
Are you sure you want to remove member- <span className="font-bold">{data?.display_name}</span>?
|
||||
They will no longer have access to this project. This action cannot be undone.
|
||||
</>
|
||||
)}
|
||||
</p>
|
||||
|
|
@ -107,27 +79,10 @@ export const ConfirmProjectMemberRemove = observer(function ConfirmProjectMember
|
|||
<Button variant="secondary" size="lg" onClick={handleClose}>
|
||||
Cancel
|
||||
</Button>
|
||||
<Button
|
||||
variant="error-fill"
|
||||
size="lg"
|
||||
tabIndex={1}
|
||||
onClick={handleDeletion}
|
||||
loading={isDeleteLoading}
|
||||
>
|
||||
{isCurrentUser
|
||||
? isDeleteLoading
|
||||
? "Leaving..."
|
||||
: "Leave"
|
||||
: isDeleteLoading
|
||||
? "Removing..."
|
||||
: "Remove"}
|
||||
<Button variant="error-fill" size="lg" tabIndex={1} onClick={handleDeletion} loading={isDeleteLoading}>
|
||||
{isCurrentUser ? (isDeleteLoading ? "Leaving..." : "Leave") : isDeleteLoading ? "Removing..." : "Remove"}
|
||||
</Button>
|
||||
</div>
|
||||
</Dialog.Panel>
|
||||
</Transition.Child>
|
||||
</div>
|
||||
</div>
|
||||
</Dialog>
|
||||
</Transition.Root>
|
||||
</ModalCore>
|
||||
);
|
||||
});
|
||||
|
|
|
|||
|
|
@ -1,15 +1,13 @@
|
|||
import React from "react";
|
||||
import { useParams } from "next/navigation";
|
||||
import { Controller, useForm } from "react-hook-form";
|
||||
import { AlertTriangle } from "lucide-react";
|
||||
import { Dialog, Transition } from "@headlessui/react";
|
||||
// types
|
||||
import { PROJECT_TRACKER_EVENTS } from "@plane/constants";
|
||||
import { Button } from "@plane/propel/button";
|
||||
import { TOAST_TYPE, setToast } from "@plane/propel/toast";
|
||||
import type { IProject } from "@plane/types";
|
||||
// ui
|
||||
import { Input } from "@plane/ui";
|
||||
import { Input, EModalPosition, EModalWidth, ModalCore } from "@plane/ui";
|
||||
// constants
|
||||
// hooks
|
||||
import { captureError, captureSuccess } from "@/helpers/event-tracker.helper";
|
||||
|
|
@ -90,32 +88,7 @@ export function DeleteProjectModal(props: DeleteProjectModal) {
|
|||
};
|
||||
|
||||
return (
|
||||
<Transition.Root show={isOpen} as={React.Fragment}>
|
||||
<Dialog as="div" className="relative z-20" onClose={handleClose}>
|
||||
<Transition.Child
|
||||
as={React.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-backdrop transition-opacity" />
|
||||
</Transition.Child>
|
||||
|
||||
<div className="fixed inset-0 z-20 overflow-y-auto">
|
||||
<div className="flex min-h-full items-end justify-center p-4 text-center sm:items-center sm:p-0">
|
||||
<Transition.Child
|
||||
as={React.Fragment}
|
||||
enter="ease-out duration-300"
|
||||
enterFrom="opacity-0 translate-y-4 sm:translate-y-0 sm:scale-95"
|
||||
enterTo="opacity-100 translate-y-0 sm:scale-100"
|
||||
leave="ease-in duration-200"
|
||||
leaveFrom="opacity-100 translate-y-0 sm:scale-100"
|
||||
leaveTo="opacity-0 translate-y-4 sm:translate-y-0 sm:scale-95"
|
||||
>
|
||||
<Dialog.Panel className="relative transform overflow-hidden rounded-lg bg-surface-1 text-left shadow-raised-200 transition-all sm:my-8 sm:w-full sm:max-w-2xl">
|
||||
<ModalCore isOpen={isOpen} handleClose={handleClose} position={EModalPosition.CENTER} width={EModalWidth.XXL}>
|
||||
<form onSubmit={handleSubmit(onSubmit)} className="flex flex-col gap-6 p-6">
|
||||
<div className="flex w-full items-center justify-start gap-6">
|
||||
<span className="place-items-center rounded-full bg-red-500/20 p-4">
|
||||
|
|
@ -127,15 +100,13 @@ export function DeleteProjectModal(props: DeleteProjectModal) {
|
|||
</div>
|
||||
<span>
|
||||
<p className="text-13 leading-7 text-secondary">
|
||||
Are you sure you want to delete project{" "}
|
||||
<span className="break-words font-semibold">{project?.name}</span>? All of the data related to the
|
||||
project will be permanently removed. This action cannot be undone
|
||||
Are you sure you want to delete project <span className="break-words font-semibold">{project?.name}</span>?
|
||||
All of the data related to the project will be permanently removed. This action cannot be undone
|
||||
</p>
|
||||
</span>
|
||||
<div className="text-secondary">
|
||||
<p className="break-words text-13 ">
|
||||
Enter the project name <span className="font-medium text-primary">{project?.name}</span> to
|
||||
continue:
|
||||
Enter the project name <span className="font-medium text-primary">{project?.name}</span> to continue:
|
||||
</p>
|
||||
<Controller
|
||||
control={control}
|
||||
|
|
@ -188,11 +159,6 @@ export function DeleteProjectModal(props: DeleteProjectModal) {
|
|||
</Button>
|
||||
</div>
|
||||
</form>
|
||||
</Dialog.Panel>
|
||||
</Transition.Child>
|
||||
</div>
|
||||
</div>
|
||||
</Dialog>
|
||||
</Transition.Root>
|
||||
</ModalCore>
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,10 +1,9 @@
|
|||
import { useState, Fragment } from "react";
|
||||
|
||||
import { Transition, Dialog } from "@headlessui/react";
|
||||
import { useState } from "react";
|
||||
// types
|
||||
import { Button } from "@plane/propel/button";
|
||||
import type { IProject } from "@plane/types";
|
||||
// ui
|
||||
import { EModalPosition, EModalWidth, ModalCore } from "@plane/ui";
|
||||
// hooks
|
||||
import { useUserPermissions } from "@/hooks/store/user";
|
||||
import { useAppRouter } from "@/hooks/use-app-router";
|
||||
|
|
@ -26,13 +25,17 @@ export function JoinProjectModal(props: TJoinProjectModalProps) {
|
|||
// router
|
||||
const router = useAppRouter();
|
||||
|
||||
const handleJoin = () => {
|
||||
const handleJoin = async () => {
|
||||
setIsJoiningLoading(true);
|
||||
|
||||
joinProject(workspaceSlug, project.id)
|
||||
await joinProject(workspaceSlug, project.id)
|
||||
.then(() => {
|
||||
router.push(`/${workspaceSlug}/projects/${project.id}/issues`);
|
||||
handleClose();
|
||||
return;
|
||||
})
|
||||
.catch(() => {
|
||||
console.error("Error joining project");
|
||||
})
|
||||
.finally(() => {
|
||||
setIsJoiningLoading(false);
|
||||
|
|
@ -40,63 +43,23 @@ export function JoinProjectModal(props: TJoinProjectModalProps) {
|
|||
};
|
||||
|
||||
return (
|
||||
<Transition.Root show={isOpen} as={Fragment}>
|
||||
<Dialog as="div" className="relative z-20" onClose={handleClose}>
|
||||
<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-backdrop transition-opacity" />
|
||||
</Transition.Child>
|
||||
|
||||
<div className="fixed inset-0 z-20 overflow-y-auto">
|
||||
<div className="flex min-h-full items-center justify-center p-4 text-center sm:p-0">
|
||||
<Transition.Child
|
||||
as={Fragment}
|
||||
enter="ease-out duration-300"
|
||||
enterFrom="opacity-0 translate-y-4 sm:translate-y-0 sm:scale-95"
|
||||
enterTo="opacity-100 translate-y-0 sm:scale-100"
|
||||
leave="ease-in duration-200"
|
||||
leaveFrom="opacity-100 translate-y-0 sm:scale-100"
|
||||
leaveTo="opacity-0 translate-y-4 sm:translate-y-0 sm:scale-95"
|
||||
>
|
||||
<Dialog.Panel className="relative transform overflow-hidden rounded-lg bg-surface-1 px-5 py-8 text-left shadow-raised-200 transition-all sm:w-full sm:max-w-xl sm:p-6">
|
||||
<div className="space-y-5">
|
||||
<Dialog.Title as="h3" className="text-16 font-medium leading-6 text-primary">
|
||||
Join Project?
|
||||
</Dialog.Title>
|
||||
<ModalCore isOpen={isOpen} handleClose={handleClose} position={EModalPosition.CENTER} width={EModalWidth.XL}>
|
||||
<div className="space-y-5 px-5 py-8 sm:p-6">
|
||||
<h3 className="text-16 font-medium leading-6 text-primary">Join Project?</h3>
|
||||
<p>
|
||||
Are you sure you want to join the project{" "}
|
||||
<span className="break-words font-semibold">{project?.name}</span>? Please click the 'Join
|
||||
Project' button below to continue.
|
||||
Are you sure you want to join the project <span className="break-words font-semibold">{project?.name}</span>?
|
||||
Please click the 'Join Project' button below to continue.
|
||||
</p>
|
||||
<div className="space-y-3" />
|
||||
</div>
|
||||
<div className="mt-5 flex justify-end gap-2">
|
||||
<div className="mt-5 flex justify-end gap-2 px-5 pb-8 sm:px-6 sm:pb-6">
|
||||
<Button variant="secondary" size="lg" onClick={handleClose}>
|
||||
Cancel
|
||||
</Button>
|
||||
<Button
|
||||
variant="primary"
|
||||
size="lg"
|
||||
tabIndex={1}
|
||||
type="submit"
|
||||
onClick={handleJoin}
|
||||
loading={isJoiningLoading}
|
||||
>
|
||||
<Button variant="primary" size="lg" tabIndex={1} type="submit" onClick={handleJoin} loading={isJoiningLoading}>
|
||||
{isJoiningLoading ? "Joining..." : "Join Project"}
|
||||
</Button>
|
||||
</div>
|
||||
</Dialog.Panel>
|
||||
</Transition.Child>
|
||||
</div>
|
||||
</div>
|
||||
</Dialog>
|
||||
</Transition.Root>
|
||||
</ModalCore>
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,17 +1,15 @@
|
|||
import { Fragment } from "react";
|
||||
import { observer } from "mobx-react";
|
||||
import { useParams } from "next/navigation";
|
||||
import { Controller, useForm } from "react-hook-form";
|
||||
// headless ui
|
||||
import { AlertTriangleIcon } from "lucide-react";
|
||||
import { Dialog, Transition } from "@headlessui/react";
|
||||
// types
|
||||
import { MEMBER_TRACKER_EVENTS } from "@plane/constants";
|
||||
import { Button } from "@plane/propel/button";
|
||||
import { TOAST_TYPE, setToast } from "@plane/propel/toast";
|
||||
import type { IProject } from "@plane/types";
|
||||
// ui
|
||||
import { Input } from "@plane/ui";
|
||||
import { Input, EModalPosition, EModalWidth, ModalCore } from "@plane/ui";
|
||||
// constants
|
||||
// hooks
|
||||
import { captureError, captureSuccess } from "@/helpers/event-tracker.helper";
|
||||
|
|
@ -109,32 +107,7 @@ export const LeaveProjectModal = observer(function LeaveProjectModal(props: ILea
|
|||
};
|
||||
|
||||
return (
|
||||
<Transition.Root show={isOpen} as={Fragment}>
|
||||
<Dialog as="div" className="relative z-20" onClose={handleClose}>
|
||||
<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-backdrop transition-opacity" />
|
||||
</Transition.Child>
|
||||
|
||||
<div className="fixed inset-0 z-20 overflow-y-auto">
|
||||
<div className="flex min-h-full items-end justify-center p-4 text-center sm:items-center sm:p-0">
|
||||
<Transition.Child
|
||||
as={Fragment}
|
||||
enter="ease-out duration-300"
|
||||
enterFrom="opacity-0 translate-y-4 sm:translate-y-0 sm:scale-95"
|
||||
enterTo="opacity-100 translate-y-0 sm:scale-100"
|
||||
leave="ease-in duration-200"
|
||||
leaveFrom="opacity-100 translate-y-0 sm:scale-100"
|
||||
leaveTo="opacity-0 translate-y-4 sm:translate-y-0 sm:scale-95"
|
||||
>
|
||||
<Dialog.Panel className="relative transform overflow-hidden rounded-lg bg-surface-1 text-left shadow-raised-200 transition-all sm:my-8 sm:w-full sm:max-w-2xl">
|
||||
<ModalCore isOpen={isOpen} handleClose={handleClose} position={EModalPosition.CENTER} width={EModalWidth.XXL}>
|
||||
<form onSubmit={handleSubmit(onSubmit)} className="flex flex-col gap-6 p-6">
|
||||
<div className="flex w-full items-center justify-start gap-6">
|
||||
<span className="place-items-center rounded-full bg-red-500/20 p-4">
|
||||
|
|
@ -148,15 +121,14 @@ export const LeaveProjectModal = observer(function LeaveProjectModal(props: ILea
|
|||
<span>
|
||||
<p className="text-13 leading-7 text-secondary">
|
||||
Are you sure you want to leave the project -
|
||||
<span className="font-medium text-primary">{` "${project?.name}" `}</span>? All of the work items
|
||||
associated with you will become inaccessible.
|
||||
<span className="font-medium text-primary">{` "${project?.name}" `}</span>? All of the work items associated
|
||||
with you will become inaccessible.
|
||||
</p>
|
||||
</span>
|
||||
|
||||
<div className="text-secondary">
|
||||
<p className="break-words text-13 ">
|
||||
Enter the project name <span className="font-medium text-primary">{project?.name}</span> to
|
||||
continue:
|
||||
Enter the project name <span className="font-medium text-primary">{project?.name}</span> to continue:
|
||||
</p>
|
||||
<Controller
|
||||
control={control}
|
||||
|
|
@ -211,11 +183,6 @@ export const LeaveProjectModal = observer(function LeaveProjectModal(props: ILea
|
|||
</Button>
|
||||
</div>
|
||||
</form>
|
||||
</Dialog.Panel>
|
||||
</Transition.Child>
|
||||
</div>
|
||||
</div>
|
||||
</Dialog>
|
||||
</Transition.Root>
|
||||
</ModalCore>
|
||||
);
|
||||
});
|
||||
|
|
|
|||
|
|
@ -2,14 +2,13 @@ import React, { useEffect } from "react";
|
|||
import { observer } from "mobx-react";
|
||||
import { useForm, Controller, useFieldArray } from "react-hook-form";
|
||||
import { Plus } from "lucide-react";
|
||||
import { Dialog, Transition } from "@headlessui/react";
|
||||
// plane imports
|
||||
import { ROLE, EUserPermissions, MEMBER_TRACKER_EVENTS } from "@plane/constants";
|
||||
import { useTranslation } from "@plane/i18n";
|
||||
import { Button } from "@plane/propel/button";
|
||||
import { CloseIcon, ChevronDownIcon } from "@plane/propel/icons";
|
||||
import { TOAST_TYPE, setToast } from "@plane/propel/toast";
|
||||
import { Avatar, CustomSelect, CustomSearchSelect } from "@plane/ui";
|
||||
import { Avatar, CustomSelect, CustomSearchSelect, EModalPosition, EModalWidth, ModalCore } from "@plane/ui";
|
||||
// helpers
|
||||
import { getFileURL } from "@plane/utils";
|
||||
// hooks
|
||||
|
|
@ -183,49 +182,19 @@ export const SendProjectInvitationModal = observer(function SendProjectInvitatio
|
|||
};
|
||||
|
||||
return (
|
||||
<Transition.Root show={isOpen} as={React.Fragment}>
|
||||
<Dialog as="div" className="relative z-20" onClose={handleClose}>
|
||||
<Transition.Child
|
||||
as={React.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-backdrop transition-opacity" />
|
||||
</Transition.Child>
|
||||
|
||||
<div className="fixed inset-0 z-20 overflow-y-auto">
|
||||
<div className="flex min-h-full items-center justify-center p-4 text-center">
|
||||
<Transition.Child
|
||||
as={React.Fragment}
|
||||
enter="ease-out duration-300"
|
||||
enterFrom="opacity-0 translate-y-4 sm:translate-y-0 sm:scale-95"
|
||||
enterTo="opacity-100 translate-y-0 sm:scale-100"
|
||||
leave="ease-in duration-200"
|
||||
leaveFrom="opacity-100 translate-y-0 sm:scale-100"
|
||||
leaveTo="opacity-0 translate-y-4 sm:translate-y-0 sm:scale-95"
|
||||
>
|
||||
<Dialog.Panel className="relative transform rounded-lg bg-surface-1 p-5 text-left shadow-raised-200 transition-all sm:w-full sm:max-w-2xl">
|
||||
<form onSubmit={handleSubmit(onSubmit)}>
|
||||
<ModalCore isOpen={isOpen} handleClose={handleClose} position={EModalPosition.CENTER} width={EModalWidth.XXL}>
|
||||
<form onSubmit={handleSubmit(onSubmit)} className="p-5">
|
||||
<div className="space-y-5">
|
||||
<Dialog.Title as="h3" className="text-16 font-medium leading-6 text-primary">
|
||||
<h3 className="text-16 font-medium leading-6 text-primary">
|
||||
{t("project_settings.members.invite_members.title")}
|
||||
</Dialog.Title>
|
||||
</h3>
|
||||
<div className="mt-2">
|
||||
<p className="text-13 text-secondary">
|
||||
{t("project_settings.members.invite_members.sub_heading")}
|
||||
</p>
|
||||
<p className="text-13 text-secondary">{t("project_settings.members.invite_members.sub_heading")}</p>
|
||||
</div>
|
||||
|
||||
<div className="mb-3 space-y-4">
|
||||
{fields.map((field, index) => (
|
||||
<div
|
||||
key={field.id}
|
||||
className="group mb-1 flex items-start justify-between gap-x-4 text-13 w-full"
|
||||
>
|
||||
<div key={field.id} className="group mb-1 flex items-start justify-between gap-x-4 text-13 w-full">
|
||||
<div className="flex flex-col gap-1 flex-grow w-full">
|
||||
<Controller
|
||||
control={control}
|
||||
|
|
@ -270,9 +239,7 @@ export const SendProjectInvitationModal = observer(function SendProjectInvitatio
|
|||
}}
|
||||
/>
|
||||
{errors.members && errors.members[index]?.member_id && (
|
||||
<span className="px-1 text-13 text-red-500">
|
||||
{errors.members[index]?.member_id?.message}
|
||||
</span>
|
||||
<span className="px-1 text-13 text-red-500">{errors.members[index]?.member_id?.message}</span>
|
||||
)}
|
||||
</div>
|
||||
|
||||
|
|
@ -287,17 +254,14 @@ export const SendProjectInvitationModal = observer(function SendProjectInvitatio
|
|||
{...field}
|
||||
customButton={
|
||||
<div className="flex w-24 items-center justify-between gap-1 rounded-md border border-subtle px-3 py-2.5 text-left text-13 text-secondary shadow-sm duration-300 hover:bg-layer-1 hover:text-primary focus:outline-none">
|
||||
<span className="capitalize">
|
||||
{field.value ? ROLE[field.value] : "Select role"}
|
||||
</span>
|
||||
<span className="capitalize">{field.value ? ROLE[field.value] : "Select role"}</span>
|
||||
<ChevronDownIcon className="h-3 w-3" aria-hidden="true" />
|
||||
</div>
|
||||
}
|
||||
input
|
||||
>
|
||||
{Object.entries(
|
||||
checkCurrentOptionWorkspaceRole(watch(`members.${index}.member_id`))
|
||||
).map(([key, label]) => {
|
||||
{Object.entries(checkCurrentOptionWorkspaceRole(watch(`members.${index}.member_id`))).map(
|
||||
([key, label]) => {
|
||||
if (parseInt(key) > (currentProjectRole ?? EUserPermissions.GUEST)) return null;
|
||||
|
||||
return (
|
||||
|
|
@ -305,14 +269,13 @@ export const SendProjectInvitationModal = observer(function SendProjectInvitatio
|
|||
{label}
|
||||
</CustomSelect.Option>
|
||||
);
|
||||
})}
|
||||
}
|
||||
)}
|
||||
</CustomSelect>
|
||||
)}
|
||||
/>
|
||||
{errors.members && errors.members[index]?.role && (
|
||||
<span className="px-1 text-13 text-red-500">
|
||||
{errors.members[index]?.role?.message}
|
||||
</span>
|
||||
<span className="px-1 text-13 text-red-500">{errors.members[index]?.role?.message}</span>
|
||||
)}
|
||||
</div>
|
||||
|
||||
|
|
@ -332,7 +295,6 @@ export const SendProjectInvitationModal = observer(function SendProjectInvitatio
|
|||
))}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="mt-5 flex items-center justify-between gap-2">
|
||||
<button
|
||||
type="button"
|
||||
|
|
@ -354,11 +316,6 @@ export const SendProjectInvitationModal = observer(function SendProjectInvitatio
|
|||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</Dialog.Panel>
|
||||
</Transition.Child>
|
||||
</div>
|
||||
</div>
|
||||
</Dialog>
|
||||
</Transition.Root>
|
||||
</ModalCore>
|
||||
);
|
||||
});
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
import { useState, Fragment } from "react";
|
||||
import { Dialog, Transition } from "@headlessui/react";
|
||||
import { useState } from "react";
|
||||
// ui
|
||||
import { Button } from "@plane/propel/button";
|
||||
import { TOAST_TYPE, setToast } from "@plane/propel/toast";
|
||||
import { EModalPosition, EModalWidth, ModalCore } from "@plane/ui";
|
||||
// hooks
|
||||
import { useProject } from "@/hooks/store/use-project";
|
||||
import { useAppRouter } from "@/hooks/use-app-router";
|
||||
|
|
@ -44,6 +44,7 @@ export function ArchiveRestoreProjectModal(props: Props) {
|
|||
});
|
||||
onClose();
|
||||
router.push(`/${workspaceSlug}/projects/`);
|
||||
return;
|
||||
})
|
||||
.catch(() =>
|
||||
setToast({
|
||||
|
|
@ -66,6 +67,7 @@ export function ArchiveRestoreProjectModal(props: Props) {
|
|||
});
|
||||
onClose();
|
||||
router.push(`/${workspaceSlug}/projects/`);
|
||||
return;
|
||||
})
|
||||
.catch(() =>
|
||||
setToast({
|
||||
|
|
@ -78,39 +80,14 @@ export function ArchiveRestoreProjectModal(props: Props) {
|
|||
};
|
||||
|
||||
return (
|
||||
<Transition.Root show={isOpen} as={Fragment}>
|
||||
<Dialog as="div" className="relative z-20" onClose={handleClose}>
|
||||
<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-backdrop transition-opacity" />
|
||||
</Transition.Child>
|
||||
|
||||
<div className="fixed inset-0 z-10 overflow-y-auto">
|
||||
<div className="flex min-h-full items-end justify-center p-4 text-center sm:items-center sm:p-0">
|
||||
<Transition.Child
|
||||
as={Fragment}
|
||||
enter="ease-out duration-300"
|
||||
enterFrom="opacity-0 translate-y-4 sm:translate-y-0 sm:scale-95"
|
||||
enterTo="opacity-100 translate-y-0 sm:scale-100"
|
||||
leave="ease-in duration-200"
|
||||
leaveFrom="opacity-100 translate-y-0 sm:scale-100"
|
||||
leaveTo="opacity-0 translate-y-4 sm:translate-y-0 sm:scale-95"
|
||||
>
|
||||
<Dialog.Panel className="relative transform overflow-hidden rounded-lg bg-surface-1 text-left shadow-raised-200 transition-all sm:my-8 sm:w-full sm:max-w-lg">
|
||||
<ModalCore isOpen={isOpen} handleClose={handleClose} position={EModalPosition.CENTER} width={EModalWidth.LG}>
|
||||
<div className="px-5 py-4">
|
||||
<h3 className="text-18 font-medium 2xl:text-20">
|
||||
{archive ? "Archive" : "Restore"} {projectDetails.name}
|
||||
</h3>
|
||||
<p className="mt-3 text-13 text-secondary">
|
||||
{archive
|
||||
? "This project and its work items, cycles, modules, and pages will be archived. Its work items won’t appear in search. Only project admins can restore the project."
|
||||
? "This project and its work items, cycles, modules, and pages will be archived. Its work items won't appear in search. Only project admins can restore the project."
|
||||
: "Restoring a project will activate it and make it visible to all members of the project. Are you sure you want to continue?"}
|
||||
</p>
|
||||
<div className="mt-3 flex justify-end gap-2">
|
||||
|
|
@ -128,11 +105,6 @@ export function ArchiveRestoreProjectModal(props: Props) {
|
|||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
</Dialog.Panel>
|
||||
</Transition.Child>
|
||||
</div>
|
||||
</div>
|
||||
</Dialog>
|
||||
</Transition.Root>
|
||||
</ModalCore>
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,16 +1,13 @@
|
|||
import { Fragment } from "react";
|
||||
import { useParams } from "next/navigation";
|
||||
import { useForm, Controller } from "react-hook-form";
|
||||
import { Transition, Dialog } from "@headlessui/react";
|
||||
// plane imports
|
||||
import { allTimeIn30MinutesInterval12HoursFormat } from "@plane/constants";
|
||||
import { Button } from "@plane/propel/button";
|
||||
import { CloseIcon } from "@plane/propel/icons";
|
||||
import { CustomSelect } from "@plane/ui";
|
||||
import { CustomSelect, EModalPosition, EModalWidth, ModalCore } from "@plane/ui";
|
||||
// components
|
||||
import { getDate, cn } from "@plane/utils";
|
||||
import { DateDropdown } from "@/components/dropdowns/date";
|
||||
// helpers
|
||||
|
||||
type TNotificationSnoozeModal = {
|
||||
isOpen: boolean;
|
||||
|
|
@ -110,37 +107,10 @@ export function NotificationSnoozeModal(props: TNotificationSnoozeModal) {
|
|||
};
|
||||
|
||||
return (
|
||||
<Transition.Root show={isOpen} as={Fragment}>
|
||||
<Dialog as="div" className="relative z-20" onClose={handleClose}>
|
||||
<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-backdrop transition-opacity" />
|
||||
</Transition.Child>
|
||||
|
||||
<div className="fixed inset-0 z-20 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 translate-y-4 sm:translate-y-0 sm:scale-95"
|
||||
enterTo="opacity-100 translate-y-0 sm:scale-100"
|
||||
leave="ease-in duration-200"
|
||||
leaveFrom="opacity-100 translate-y-0 sm:scale-100"
|
||||
leaveTo="opacity-0 translate-y-4 sm:translate-y-0 sm:scale-95"
|
||||
>
|
||||
<Dialog.Panel className="relative w-full transform rounded-lg bg-surface-1 p-5 text-left shadow-raised-200 transition-all sm:w-full sm:max-w-2xl">
|
||||
<form onSubmit={handleSubmit(onSubmit)}>
|
||||
<ModalCore isOpen={isOpen} handleClose={handleClose} position={EModalPosition.CENTER} width={EModalWidth.XXL}>
|
||||
<form onSubmit={handleSubmit(onSubmit)} className="p-5">
|
||||
<div className="flex items-center justify-between">
|
||||
<Dialog.Title as="h3" className="text-h5-medium leading-6 text-primary">
|
||||
Customize Snooze Time
|
||||
</Dialog.Title>
|
||||
<h3 className="text-h5-medium leading-6 text-primary">Customize Snooze Time</h3>
|
||||
|
||||
<div>
|
||||
<button type="button" onClick={handleClose}>
|
||||
|
|
@ -201,13 +171,10 @@ export function NotificationSnoozeModal(props: TNotificationSnoozeModal) {
|
|||
onClick={() => {
|
||||
setValue("period", "AM");
|
||||
}}
|
||||
className={cn(
|
||||
"flex h-full w-1/2 cursor-pointer items-center justify-center text-center",
|
||||
{
|
||||
className={cn("flex h-full w-1/2 cursor-pointer items-center justify-center text-center", {
|
||||
"bg-accent-primary/90 text-on-color": watch("period") === "AM",
|
||||
"bg-layer-1": watch("period") !== "AM",
|
||||
}
|
||||
)}
|
||||
})}
|
||||
>
|
||||
AM
|
||||
</div>
|
||||
|
|
@ -215,13 +182,10 @@ export function NotificationSnoozeModal(props: TNotificationSnoozeModal) {
|
|||
onClick={() => {
|
||||
setValue("period", "PM");
|
||||
}}
|
||||
className={cn(
|
||||
"flex h-full w-1/2 cursor-pointer items-center justify-center text-center",
|
||||
{
|
||||
className={cn("flex h-full w-1/2 cursor-pointer items-center justify-center text-center", {
|
||||
"bg-accent-primary/90 text-on-color": watch("period") === "PM",
|
||||
"bg-layer-1": watch("period") !== "PM",
|
||||
}
|
||||
)}
|
||||
})}
|
||||
>
|
||||
PM
|
||||
</div>
|
||||
|
|
@ -254,11 +218,6 @@ export function NotificationSnoozeModal(props: TNotificationSnoozeModal) {
|
|||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</Dialog.Panel>
|
||||
</Transition.Child>
|
||||
</div>
|
||||
</div>
|
||||
</Dialog>
|
||||
</Transition.Root>
|
||||
</ModalCore>
|
||||
);
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue