From 211573bd741d1197ee0165c8215620af299c2f09 Mon Sep 17 00:00:00 2001 From: vamsikrishnamathala Date: Mon, 22 Dec 2025 19:47:59 +0530 Subject: [PATCH 1/2] chore: migrated modal to @plane/ui --- .../account/deactivate-account-modal.tsx | 86 ++-- .../automation/select-month-modal.tsx | 204 ++++----- .../core/filters/date-filter-modal.tsx | 201 ++++----- .../core/modals/bulk-delete-issues-modal.tsx | 133 +++--- .../core/modals/change-email-modal.tsx | 192 ++++----- .../modals/existing-issues-list-modal.tsx | 400 ++++++++---------- .../core/modals/user-image-upload-modal.tsx | 160 +++---- .../modals/workspace-image-upload-modal.tsx | 164 +++---- .../cycles/archived-cycles/modal.tsx | 65 +-- .../cycles/transfer-issues-modal.tsx | 168 +++----- .../core/components/exporter/export-modal.tsx | 152 +++---- .../inbox/modals/select-duplicate.tsx | 94 ++-- .../inbox/modals/snooze-issue-modal.tsx | 90 ++-- .../integration/delete-import-modal.tsx | 142 +++---- .../components/issues/archive-issue-modal.tsx | 65 +-- .../issues/confirm-issue-discard.tsx | 92 ++-- .../issues/parent-issues-list-modal.tsx | 245 +++++------ .../modules/archived-modules/modal.tsx | 71 +--- .../project/confirm-project-member-remove.tsx | 119 ++---- .../project/delete-project-modal.tsx | 178 ++++---- .../components/project/join-project-modal.tsx | 89 ++-- .../project/leave-project-modal.tsx | 181 ++++---- .../project/send-project-invitation-modal.tsx | 295 ++++++------- .../archive-project/archive-restore-modal.tsx | 86 ++-- .../options/snooze/modal.tsx | 251 +++++------ 25 files changed, 1520 insertions(+), 2403 deletions(-) diff --git a/apps/web/core/components/account/deactivate-account-modal.tsx b/apps/web/core/components/account/deactivate-account-modal.tsx index 08f8890a690..30fbca1ef11 100644 --- a/apps/web/core/components/account/deactivate-account-modal.tsx +++ b/apps/web/core/components/account/deactivate-account-modal.tsx @@ -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,65 +63,30 @@ export function DeactivateAccountModal(props: Props) { }; return ( - - - -
- - -
-
- - -
-
-
-
-
-
- - {t("deactivate_your_account")} - -

- {t("deactivate_your_account_description")} -

-
-
-
-
-
- - -
-
-
+ +
+
+
+
+
+
+

{t("deactivate_your_account")}

+

+ {t("deactivate_your_account_description")} +

+
-
-
+ +
+ + +
+ ); } diff --git a/apps/web/core/components/automation/select-month-modal.tsx b/apps/web/core/components/automation/select-month-modal.tsx index e4b79d31093..c6c0ce453ee 100644 --- a/apps/web/core/components/automation/select-month-modal.tsx +++ b/apps/web/core/components/automation/select-month-modal.tsx @@ -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,124 +39,92 @@ export function SelectMonthModal({ type, initialValues, isOpen, handleClose, han }; return ( - - - -
- - -
-
- - -
-
- - Customize time range - -
-
- {type === "auto-close" ? ( - <> - ( -
- - Months -
- )} - /> + + +
+

Customize time range

+
+
+ {type === "auto-close" ? ( + <> + ( +
+ + Months +
+ )} + /> - {errors.close_in && ( - Select a month between 1 and 12. - )} - - ) : ( - <> - ( -
- - Months -
- )} - /> - {errors.archive_in && ( - Select a month between 1 and 12. - )} - - )} + {errors.close_in && ( + Select a month between 1 and 12. + )} + + ) : ( + <> + ( +
+ + Months
-
-
-
- - -
- - - + )} + /> + {errors.archive_in && ( + Select a month between 1 and 12. + )} + + )} +
-
-
+
+ + +
+ + ); } diff --git a/apps/web/core/components/core/filters/date-filter-modal.tsx b/apps/web/core/components/core/filters/date-filter-modal.tsx index 0ec69916a80..545dd3b77e1 100644 --- a/apps/web/core/components/core/filters/date-filter-modal.tsx +++ b/apps/web/core/components/core/filters/date-filter-modal.tsx @@ -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,118 +45,89 @@ export function DateFilterModal({ title, handleClose, isOpen, onSelect }: Props) const isInvalid = watch("filterType") === "range" && date1 && date2 ? date1 > date2 : false; return ( - - - -
- -
-
- - -
-
- ( - - )} - /> - -
-
- { - const dateValue = getDate(value); - const date2Value = getDate(watch("date2")); - return ( - { - if (!date) return; - onChange(date); - }} - mode="single" - disabled={date2Value ? [{ after: date2Value }] : undefined} - /> - ); - }} - /> - {watch("filterType") === "range" && ( - { - const dateValue = getDate(value); - const date1Value = getDate(watch("date1")); - return ( - { - if (!date) return; - onChange(date); - }} - mode="single" - disabled={date1Value ? [{ before: date1Value }] : undefined} - /> - ); - }} - /> - )} -
- {watch("filterType") === "range" && ( -
- After: - {renderFormattedDate(watch("date1"))} - Before: - {!isInvalid && {renderFormattedDate(watch("date2"))}} -
- )} -
- - -
-
-
-
-
+ +
+
+ ( + + )} + /> + +
+
+ { + const dateValue = getDate(value); + const date2Value = getDate(watch("date2")); + return ( + { + if (!date) return; + onChange(date); + }} + mode="single" + disabled={date2Value ? [{ after: date2Value }] : undefined} + /> + ); + }} + /> + {watch("filterType") === "range" && ( + { + const dateValue = getDate(value); + const date1Value = getDate(watch("date1")); + return ( + { + if (!date) return; + onChange(date); + }} + mode="single" + disabled={date1Value ? [{ before: date1Value }] : undefined} + /> + ); + }} + /> + )} +
+ {watch("filterType") === "range" && ( +
+ After: + {renderFormattedDate(watch("date1"))} + Before: + {!isInvalid && {renderFormattedDate(watch("date2"))}} +
+ )} +
+ +
-
-
+ + ); } diff --git a/apps/web/core/components/core/modals/bulk-delete-issues-modal.tsx b/apps/web/core/components/core/modals/bulk-delete-issues-modal.tsx index 7db4c14a487..96d5b075f78 100644 --- a/apps/web/core/components/core/modals/bulk-delete-issues-modal.tsx +++ b/apps/web/core/components/core/modals/bulk-delete-issues-modal.tsx @@ -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,80 +150,57 @@ export const BulkDeleteIssuesModal = observer(function BulkDeleteIssuesModal(pro ); return ( - setQuery("")} appear> - -
- - -
-
- { - const selectedIssues = watch("delete_issue_ids"); - if (selectedIssues.includes(val)) - setValue( - "delete_issue_ids", - selectedIssues.filter((i) => i !== val) - ); - else setValue("delete_issue_ids", [...selectedIssues, val]); - }} - > -
-
- - - {isSearching ? ( - - - - - - - ) : ( - <>{issueList} - )} - -
- - {issues.length > 0 && ( -
- - -
- )} -
-
-
-
-
-
-
+ +
+ { + const selectedIssues = watch("delete_issue_ids"); + if (selectedIssues.includes(val)) + setValue( + "delete_issue_ids", + selectedIssues.filter((i) => i !== val) + ); + else setValue("delete_issue_ids", [...selectedIssues, val]); + }} + > +
+
+ + + {isSearching ? ( + + + + + + + ) : ( + <>{issueList} + )} + +
+ + {issues.length > 0 && ( +
+ + +
+ )} +
+
); }); diff --git a/apps/web/core/components/core/modals/change-email-modal.tsx b/apps/web/core/components/core/modals/change-email-modal.tsx index 7605e4f0643..46d79e3a550 100644 --- a/apps/web/core/components/core/modals/change-email-modal.tsx +++ b/apps/web/core/components/core/modals/change-email-modal.tsx @@ -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,119 +126,82 @@ export const ChangeEmailModal = observer(function ChangeEmailModal(props: Props) }; return ( - - - -
- - -
-
- - -
- - {changeEmailT("title")} - -

{changeEmailT("description")}

-
-
-
- {secondStep && ( -

{changeEmailT("form.email.label")}

- )} - ( - - )} - /> - {errors?.email && {errors?.email?.message}} -
- - {secondStep && ( -
-

{changeEmailT("form.code.label")}

- ( - - )} - /> - {errors?.code ? ( - {errors?.code?.message} - ) : ( - {changeEmailT("form.code.helper_text")} - )} -
- )} -
- - -
-
-
-
+ +
+

{changeEmailT("title")}

+

{changeEmailT("description")}

+
+
+
+ {secondStep &&

{changeEmailT("form.email.label")}

} + ( + + )} + /> + {errors?.email && {errors?.email?.message}} +
+ + {secondStep && ( +
+

{changeEmailT("form.code.label")}

+ ( + + )} + /> + {errors?.code ? ( + {errors?.code?.message} + ) : ( + {changeEmailT("form.code.helper_text")} + )}
+ )} +
+ +
-
-
+ + ); }); diff --git a/apps/web/core/components/core/modals/existing-issues-list-modal.tsx b/apps/web/core/components/core/modals/existing-issues-list-modal.tsx index 2acace1a23c..5148c5eced1 100644 --- a/apps/web/core/components/core/modals/existing-issues-list-modal.tsx +++ b/apps/web/core/components/core/modals/existing-issues-list-modal.tsx @@ -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,62 +131,136 @@ export function ExistingIssuesListModal(props: Props) { const filteredIssues = issues.filter((issue) => !shouldHideIssue?.(issue)); return ( - <> - setSearchTerm("")} appear> - - -
- + + { + if (selectedIssues.some((i) => i.id === val.id)) + setSelectedIssues((prevData) => prevData.filter((i) => i.id !== val.id)); + else setSelectedIssues((prevData) => [...prevData, val]); + }} + > +
+
-
- - - { - if (selectedIssues.some((i) => i.id === val.id)) - setSelectedIssues((prevData) => prevData.filter((i) => i.id !== val.id)); - else setSelectedIssues((prevData) => [...prevData, val]); - }} +
+ {selectedIssues.length > 0 ? ( +
+ {selectedIssues.map((issue) => ( +
-
-
+ + +
+ ))} +
+ ) : ( +
+ {t("issue.select.empty")} +
+ )} + {workspaceLevelToggle && ( + +
+ setIsWorkspaceLevel((prevData) => !prevData)} /> + +
+
+ )} +
+ + + {/* TODO: Translate here */} + {searchTerm !== "" && ( +
+ Search results for{" "} + + {'"'} + {searchTerm} + {'"'} + {" "} + in project: +
+ )} -
- {selectedIssues.length > 0 ? ( -
- {selectedIssues.map((issue) => ( -
+ {isSearching || isLoading ? ( + + + + + + + ) : ( + <> + {filteredIssues.length === 0 ? ( + + ) : ( +
    0 ? "p-2" : ""}`}> + {filteredIssues.map((issue) => { + const selected = selectedIssues.some((i) => i.id === issue.id); + + return ( + + `group flex w-full cursor-pointer select-none items-center justify-between gap-2 rounded-md px-3 py-2 my-0.5 text-secondary ${ + active ? "bg-layer-1 text-primary" : "" + } ${selected ? "text-primary" : ""}` + } + > +
    + + + - -
    - ))} -
- ) : ( -
- {t("issue.select.empty")} -
- )} - {workspaceLevelToggle && ( - -
- setIsWorkspaceLevel((prevData) => !prevData)} - /> - + + {issue.name}
-
- )} -
- - - {/* TODO: Translate here */} - {searchTerm !== "" && ( -
- Search results for{" "} - - {'"'} - {searchTerm} - {'"'} - {" "} - in project: -
- )} - - {isSearching || isLoading ? ( - - - - - - - ) : ( - <> - {filteredIssues.length === 0 ? ( - - ) : ( -
    0 ? "p-2" : ""}`}> - {filteredIssues.map((issue) => { - const selected = selectedIssues.some((i) => i.id === issue.id); - - return ( - - `group flex w-full cursor-pointer select-none items-center justify-between gap-2 rounded-md px-3 py-2 my-0.5 text-secondary ${ - active ? "bg-layer-1 text-primary" : "" - } ${selected ? "text-primary" : ""}` - } - > -
    - - - - - - {issue.name} -
    - e.stopPropagation()} - > - - -
    - ); - })} -
- )} - - )} -
- -
- -
- - -
-
- - -
-
-
- + e.stopPropagation()} + > + + + + ); + })} + + )} + + )} + + +
+ +
+ + +
+
+ ); } diff --git a/apps/web/core/components/core/modals/user-image-upload-modal.tsx b/apps/web/core/components/core/modals/user-image-upload-modal.tsx index 96405d6479c..cba0f53bf27 100644 --- a/apps/web/core/components/core/modals/user-image-upload-modal.tsx +++ b/apps/web/core/components/core/modals/user-image-upload-modal.tsx @@ -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,106 +88,68 @@ export const UserImageUploadModal = observer(function UserImageUploadModal(props }; return ( - - - -
- - -
-
- +
+

Upload Image

+
+
+
- -
- - Upload Image - -
-
-
- {image !== null || (value && value !== "") ? ( - <> - - image - - ) : ( -
- - - {isDragActive ? "Drop image here to upload" : "Drag & drop image here"} - -
- )} - - -
-
- {fileRejections.length > 0 && ( -

- {fileRejections[0].errors[0].code === "file-too-large" - ? "The image size cannot exceed 5 MB." - : "Please upload a file in a valid format."} -

- )} -
-
-

File formats supported- .jpeg, .jpg, .png, .webp

-
- -
- - -
+ {image !== null || (value && value !== "") ? ( + <> + + image + + ) : ( +
+ + + {isDragActive ? "Drop image here to upload" : "Drag & drop image here"} +
- - + )} + + +
+ {fileRejections.length > 0 && ( +

+ {fileRejections[0].errors[0].code === "file-too-large" + ? "The image size cannot exceed 5 MB." + : "Please upload a file in a valid format."} +

+ )} +
+
+

File formats supported- .jpeg, .jpg, .png, .webp

+
+ +
+ +
-
-
+ + ); }); diff --git a/apps/web/core/components/core/modals/workspace-image-upload-modal.tsx b/apps/web/core/components/core/modals/workspace-image-upload-modal.tsx index e4c28a4de9c..20c7f1983d5 100644 --- a/apps/web/core/components/core/modals/workspace-image-upload-modal.tsx +++ b/apps/web/core/components/core/modals/workspace-image-upload-modal.tsx @@ -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,112 +101,68 @@ export const WorkspaceImageUploadModal = observer(function WorkspaceImageUploadM }; return ( - - - -
- - -
-
- +
+

Upload image

+
+
+
- -
- - Upload image - -
-
-
- {image !== null || (value && value !== "") ? ( - <> - - image - - ) : ( -
- - - {isDragActive ? "Drop image here to upload" : "Drag & drop image here"} - -
- )} - - -
-
- {fileRejections.length > 0 && ( -

- {fileRejections[0].errors[0].code === "file-too-large" - ? "The image size cannot exceed 5 MB." - : "Please upload a file in a valid format."} -

- )} -
-
-

File formats supported- .jpeg, .jpg, .png, .webp

-
- -
- - -
+ Edit + + image + + ) : ( +
+ + + {isDragActive ? "Drop image here to upload" : "Drag & drop image here"} +
- - + )} + + +
+ {fileRejections.length > 0 && ( +

+ {fileRejections[0].errors[0].code === "file-too-large" + ? "The image size cannot exceed 5 MB." + : "Please upload a file in a valid format."} +

+ )} +
+
+

File formats supported- .jpeg, .jpg, .png, .webp

+
+ +
+ +
-
-
+ + ); }); diff --git a/apps/web/core/components/cycles/archived-cycles/modal.tsx b/apps/web/core/components/cycles/archived-cycles/modal.tsx index 7f7dd33f9b3..5d7b35560a7 100644 --- a/apps/web/core/components/cycles/archived-cycles/modal.tsx +++ b/apps/web/core/components/cycles/archived-cycles/modal.tsx @@ -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,51 +70,21 @@ export function ArchiveCycleModal(props: Props) { }; return ( - - - -
- - -
-
- - -
-

Archive cycle {cycleName}

-

- Are you sure you want to archive the cycle? All your archives can be restored later. -

-
- - -
-
-
-
-
+ +
+

Archive cycle {cycleName}

+

+ Are you sure you want to archive the cycle? All your archives can be restored later. +

+
+ +
-
-
+ + ); } diff --git a/apps/web/core/components/cycles/transfer-issues-modal.tsx b/apps/web/core/components/cycles/transfer-issues-modal.tsx index 5da2a4331f5..32a5c2c5e8e 100644 --- a/apps/web/core/components/cycles/transfer-issues-modal.tsx +++ b/apps/web/core/components/cycles/transfer-issues-modal.tsx @@ -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,109 +70,71 @@ 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 ( - - - -
- - -
-
- - -
-
-
- -

Transfer work items

-
- -
-
- - setQuery(e.target.value)} - value={query} - /> -
-
- {filteredOptions ? ( - filteredOptions.length > 0 ? ( - filteredOptions.map((optionId) => { - const cycleDetails = getCycleById(optionId); + +
+
+
+ +

Transfer work items

+
+ +
+
+ + setQuery(e.target.value)} + value={query} + /> +
+
+ {filteredOptions ? ( + filteredOptions.length > 0 ? ( + filteredOptions.map((optionId) => { + const cycleDetails = getCycleById(optionId); - if (!cycleDetails) return; + if (!cycleDetails) return; - return ( - - ); - }) - ) : ( -
- - - You don’t have any current cycle. Please create one to transfer the work items. - -
- ) - ) : ( -

Loading...

- )} -
-
- - -
+ return ( + + ); + }) + ) : ( +
+ + + You don’t have any current cycle. Please create one to transfer the work items. + +
+ ) + ) : ( +

Loading...

+ )}
-
-
+ + ); }); diff --git a/apps/web/core/components/exporter/export-modal.tsx b/apps/web/core/components/exporter/export-modal.tsx index 38c5e9b3dc8..6f955e70948 100644 --- a/apps/web/core/components/exporter/export-modal.tsx +++ b/apps/web/core/components/exporter/export-modal.tsx @@ -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,101 +98,64 @@ export const Exporter = observer(function Exporter(props: Props) { } return ( - - { - if (!isSelectOpen) handleClose(); - }} - > - -
- - -
-
- - -
-
- -

- {t("workspace_settings.settings.exports.modal.title")}{" "} - {provider === "csv" ? "CSV" : provider === "xlsx" ? "Excel" : provider === "json" ? "JSON" : ""} -

-
-
-
- onChange(val)} - options={options} - input - label={ - value && value.length > 0 - ? value - .map((projectId) => { - const projectDetails = getProjectById(projectId); + { + if (!isSelectOpen) handleClose(); + }} + position={EModalPosition.CENTER} + width={EModalWidth.XL} + > +
+
+ +

+ {t("workspace_settings.settings.exports.modal.title")}{" "} + {provider === "csv" ? "CSV" : provider === "xlsx" ? "Excel" : provider === "json" ? "JSON" : ""} +

+
+
+
+ onChange(val)} + options={options} + input + label={ + value && value.length > 0 + ? value + .map((projectId) => { + const projectDetails = getProjectById(projectId); - return projectDetails?.identifier; - }) - .join(", ") - : "All projects" - } - onOpen={() => setIsSelectOpen(true)} - onClose={() => setIsSelectOpen(false)} - optionsClassName="max-w-48 sm:max-w-[532px]" - placement="bottom-end" - multiple - /> -
-
setMultiple(!multiple)} - className="flex max-w-min cursor-pointer items-center gap-2" - > - setMultiple(!multiple)} /> -
- {t("workspace_settings.settings.exports.export_separate_files")} -
-
-
- - -
-
- - + return projectDetails?.identifier; + }) + .join(", ") + : "All projects" + } + onOpen={() => setIsSelectOpen(true)} + onClose={() => setIsSelectOpen(false)} + optionsClassName="max-w-48 sm:max-w-[532px]" + placement="bottom-end" + multiple + /> +
+
setMultiple(!multiple)} className="flex max-w-min cursor-pointer items-center gap-2"> + setMultiple(!multiple)} /> +
+ {t("workspace_settings.settings.exports.export_separate_files")}
-
-
+
+ + +
+ + ); }); diff --git a/apps/web/core/components/inbox/modals/select-duplicate.tsx b/apps/web/core/components/inbox/modals/select-duplicate.tsx index af9373b13f8..0104672b58a 100644 --- a/apps/web/core/components/inbox/modals/select-duplicate.tsx +++ b/apps/web/core/components/inbox/modals/select-duplicate.tsx @@ -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"; @@ -124,66 +124,34 @@ export function SelectDuplicateInboxIssueModal(props: Props) { ); return ( - setQuery("")} appear> -
-
- - -
- - -
- - - -
-
- - - {isSearching ? ( - - - - - - - ) : ( - <>{issueList} - )} - -
-
-
-
-
+ + +
+
-
- + + + {isSearching ? ( + + + + + + + ) : ( + <>{issueList} + )} + + + ); } diff --git a/apps/web/core/components/inbox/modals/snooze-issue-modal.tsx b/apps/web/core/components/inbox/modals/snooze-issue-modal.tsx index 8d56f68bca7..6f391dbda07 100644 --- a/apps/web/core/components/inbox/modals/snooze-issue-modal.tsx +++ b/apps/web/core/components/inbox/modals/snooze-issue-modal.tsx @@ -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,63 +20,34 @@ export function InboxIssueSnoozeModal(props: InboxIssueSnoozeModalProps) { const { t } = useTranslation(); return ( - - - +
+ { + if (!date) return; + setDate(date); + }} + mode="single" + disabled={[ + { + before: new Date(), + }, + ]} + /> + -
- -
-
- - -
+ {t("inbox_issue.actions.snooze")} + + + ); } diff --git a/apps/web/core/components/integration/delete-import-modal.tsx b/apps/web/core/components/integration/delete-import-modal.tsx index 3b37f255c55..3f90d6073e7 100644 --- a/apps/web/core/components/integration/delete-import-modal.tsx +++ b/apps/web/core/components/integration/delete-import-modal.tsx @@ -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,85 +56,55 @@ export function DeleteImportModal({ isOpen, handleClose, data }: Props) { if (!data) return <>; return ( - - - -
- - -
-
- - -
-
- - - -

Delete project

-
-
- -

- Are you sure you want to delete import from{" "} - {data?.service}? All of - the data related to the import will be permanently removed. This action cannot be undone. -

-
-
-

- To confirm, type delete import below: -

- { - if (e.target.value === "delete import") setConfirmDeleteImport(true); - else setConfirmDeleteImport(false); - }} - placeholder="Enter 'delete import'" - className="mt-2 w-full" - /> -
-
- - -
-
-
-
-
+ +
+
+ + + +

Delete project

+
+
+ +

+ Are you sure you want to delete import from{" "} + {data?.service}? All of the data + related to the import will be permanently removed. This action cannot be undone. +

+
+
+

+ To confirm, type delete import below: +

+ { + if (e.target.value === "delete import") setConfirmDeleteImport(true); + else setConfirmDeleteImport(false); + }} + placeholder="Enter 'delete import'" + className="mt-2 w-full" + /> +
+
+ +
-
-
+ + ); } diff --git a/apps/web/core/components/issues/archive-issue-modal.tsx b/apps/web/core/components/issues/archive-issue-modal.tsx index 199ab5d6d1c..f54518406e7 100644 --- a/apps/web/core/components/issues/archive-issue-modal.tsx +++ b/apps/web/core/components/issues/archive-issue-modal.tsx @@ -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,51 +62,21 @@ export function ArchiveIssueModal(props: Props) { }; return ( - - - -
- - -
-
- - -
-

- {t("issue.archive.label")} {projectDetails?.identifier} {issue.sequence_id} -

-

{t("issue.archive.confirm_message")}

-
- - -
-
-
-
-
+ +
+

+ {t("issue.archive.label")} {projectDetails?.identifier} {issue.sequence_id} +

+

{t("issue.archive.confirm_message")}

+
+ +
-
-
+ + ); } diff --git a/apps/web/core/components/issues/confirm-issue-discard.tsx b/apps/web/core/components/issues/confirm-issue-discard.tsx index 123b6210e0d..16ca19a2d9d 100644 --- a/apps/web/core/components/issues/confirm-issue-discard.tsx +++ b/apps/web/core/components/issues/confirm-issue-discard.tsx @@ -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,66 +27,34 @@ export function ConfirmIssueDiscard(props: Props) { }; return ( - - - -
- - -
-
- - -
-
-
- - Save this draft? - -
-

- You can save this work item to Drafts so you can come back to it later.{" "} -

-
-
-
-
-
-
- -
-
- - -
-
-
-
+ +
+
+
+

Save this draft?

+
+

+ You can save this work item to Drafts so you can come back to it later.{" "} +

+
-
-
+ +
+
+ +
+
+ + +
+
+ ); } diff --git a/apps/web/core/components/issues/parent-issues-list-modal.tsx b/apps/web/core/components/issues/parent-issues-list-modal.tsx index 40648cdd404..5ed488e3b11 100644 --- a/apps/web/core/components/issues/parent-issues-list-modal.tsx +++ b/apps/web/core/components/issues/parent-issues-list-modal.tsx @@ -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,144 +85,111 @@ export function ParentIssuesListModal({ }, [debouncedSearchTerm, isOpen, issueId, projectId, workspaceSlug]); return ( - <> - setSearchTerm("")} appear> - - -
- + + { + onChange(val); + handleClose(); + }} + > +
+
+ + {searchTerm !== "" && ( +
+ Search results for{" "} + + {'"'} + {searchTerm} + {'"'} + {" "} + in project: +
+ )} -
- - - { - onChange(val); - handleClose(); - }} - > -
-
- - {searchTerm !== "" && ( -
- Search results for{" "} - - {'"'} - {searchTerm} - {'"'} - {" "} - in project: -
- )} - - {isSearching || isLoading ? ( - - - - - - - ) : ( - <> - {issues.length === 0 ? ( - + + + + + + ) : ( + <> + {issues.length === 0 ? ( + + ) : ( +
    0 ? "p-2" : ""}`}> + {issues.map((issue) => ( + + `group flex w-full cursor-pointer select-none items-center justify-between gap-2 rounded-md px-3 py-2 my-0.5 text-secondary ${ + active ? "bg-layer-1 text-primary" : "" + } ${selected ? "text-primary" : ""}` + } + > +
    + + + - ) : ( -
      0 ? "p-2" : ""}`}> - {issues.map((issue) => ( - - `group flex w-full cursor-pointer select-none items-center justify-between gap-2 rounded-md px-3 py-2 my-0.5 text-secondary ${ - active ? "bg-layer-1 text-primary" : "" - } ${selected ? "text-primary" : ""}` - } - > -
      - - - - {" "} - {issue.name} -
      - e.stopPropagation()} - > - - -
      - ))} -
    - )} - - )} - - - - -
    -
-
- + {" "} + {issue.name} + + e.stopPropagation()} + > + + + + ))} + + )} + + )} + + + ); } diff --git a/apps/web/core/components/modules/archived-modules/modal.tsx b/apps/web/core/components/modules/archived-modules/modal.tsx index 79d2b269232..65aa7933b47 100644 --- a/apps/web/core/components/modules/archived-modules/modal.tsx +++ b/apps/web/core/components/modules/archived-modules/modal.tsx @@ -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,57 +56,21 @@ export function ArchiveModuleModal(props: Props) { }; return ( - - - -
- - -
-
- - -
-

Archive module {moduleName}

-

- Are you sure you want to archive the module? All your archives can be restored later. -

-
- - -
-
-
-
-
+ +
+

Archive module {moduleName}

+

+ Are you sure you want to archive the module? All your archives can be restored later. +

+
+ +
-
-
+ + ); } diff --git a/apps/web/core/components/project/confirm-project-member-remove.tsx b/apps/web/core/components/project/confirm-project-member-remove.tsx index 60806b43837..e38787d2d1a 100644 --- a/apps/web/core/components/project/confirm-project-member-remove.tsx +++ b/apps/web/core/components/project/confirm-project-member-remove.tsx @@ -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,86 +47,42 @@ export const ConfirmProjectMemberRemove = observer(function ConfirmProjectMember const currentProjectDetails = getProjectById(projectId.toString()); return ( - - - -
- - -
-
- - -
-
-
-
-
- - {isCurrentUser ? "Leave project?" : `Remove ${data?.display_name}?`} - -
-

- {isCurrentUser ? ( - <> - Are you sure you want to leave the{" "} - {currentProjectDetails?.name} 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-{" "} - {data?.display_name}? They will no longer have access - to this project. This action cannot be undone. - - )} -

-
-
-
-
-
- - -
-
-
+ +
+
+
+
+
+

+ {isCurrentUser ? "Leave project?" : `Remove ${data?.display_name}?`} +

+
+

+ {isCurrentUser ? ( + <> + Are you sure you want to leave the {currentProjectDetails?.name}{" "} + 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- {data?.display_name}? + They will no longer have access to this project. This action cannot be undone. + + )} +

+
-
-
+ +
+ + +
+ ); }); diff --git a/apps/web/core/components/project/delete-project-modal.tsx b/apps/web/core/components/project/delete-project-modal.tsx index 2f482323da2..23dce2bee99 100644 --- a/apps/web/core/components/project/delete-project-modal.tsx +++ b/apps/web/core/components/project/delete-project-modal.tsx @@ -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,109 +88,77 @@ export function DeleteProjectModal(props: DeleteProjectModal) { }; return ( - - - -
- - -
-
- - -
-
- - - -

Delete project

-
-
- -

- Are you sure you want to delete project{" "} - {project?.name}? All of the data related to the - project will be permanently removed. This action cannot be undone -

-
-
-

- Enter the project name {project?.name} to - continue: -

- ( - - )} - /> -
-
-

- To confirm, type delete my project below: -

- ( - - )} - /> -
-
- - -
-
-
-
-
+ +
+
+ + + +

Delete project

+
+
+ +

+ Are you sure you want to delete project {project?.name}? + All of the data related to the project will be permanently removed. This action cannot be undone +

+
+
+

+ Enter the project name {project?.name} to continue: +

+ ( + + )} + /> +
+
+

+ To confirm, type delete my project below: +

+ ( + + )} + /> +
+
+ +
-
-
+ + ); } diff --git a/apps/web/core/components/project/join-project-modal.tsx b/apps/web/core/components/project/join-project-modal.tsx index a8c978cf2d5..4e7cf2659cc 100644 --- a/apps/web/core/components/project/join-project-modal.tsx +++ b/apps/web/core/components/project/join-project-modal.tsx @@ -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 ( - - - -
- - -
-
- - -
- - Join Project? - -

- Are you sure you want to join the project{" "} - {project?.name}? Please click the 'Join - Project' button below to continue. -

-
-
-
- - -
- - -
-
-
-
+ +
+

Join Project?

+

+ Are you sure you want to join the project {project?.name}? + Please click the 'Join Project' button below to continue. +

+
+
+
+ + +
+ ); } diff --git a/apps/web/core/components/project/leave-project-modal.tsx b/apps/web/core/components/project/leave-project-modal.tsx index 57c0d4920a9..d3de91c7f30 100644 --- a/apps/web/core/components/project/leave-project-modal.tsx +++ b/apps/web/core/components/project/leave-project-modal.tsx @@ -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,113 +107,82 @@ export const LeaveProjectModal = observer(function LeaveProjectModal(props: ILea }; return ( - - - -
- - -
-
- - -
-
- - - -

Leave Project

-
-
+ + +
+ + + +

Leave Project

+
+
- -

- Are you sure you want to leave the project - - {` "${project?.name}" `}? All of the work items - associated with you will become inaccessible. -

-
+ +

+ Are you sure you want to leave the project - + {` "${project?.name}" `}? All of the work items associated + with you will become inaccessible. +

+
-
-

- Enter the project name {project?.name} to - continue: -

- ( - - )} - /> -
+
+

+ Enter the project name {project?.name} to continue: +

+ ( + + )} + /> +
-
-

- To confirm, type Leave Project below: -

- ( - - )} - /> -
-
- - -
- -
-
-
+
+

+ To confirm, type Leave Project below: +

+ ( + + )} + /> +
+
+ +
-
-
+ + ); }); diff --git a/apps/web/core/components/project/send-project-invitation-modal.tsx b/apps/web/core/components/project/send-project-invitation-modal.tsx index 900e974188d..8ab0dc010c9 100644 --- a/apps/web/core/components/project/send-project-invitation-modal.tsx +++ b/apps/web/core/components/project/send-project-invitation-modal.tsx @@ -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,182 +182,140 @@ export const SendProjectInvitationModal = observer(function SendProjectInvitatio }; return ( - - - -
- - -
-
- - -
-
- - {t("project_settings.members.invite_members.title")} - -
-

- {t("project_settings.members.invite_members.sub_heading")} -

-
+ + +
+

+ {t("project_settings.members.invite_members.title")} +

+
+

{t("project_settings.members.invite_members.sub_heading")}

+
-
- {fields.map((field, index) => ( -
-
- { - const selectedMember = getWorkspaceMemberDetails(value); - return ( - - {value && value !== "" ? ( -
- - {selectedMember?.member.display_name} -
- ) : ( -
Select co-worker
- )} -
-
- -
- - + {fields.length > 1 && ( +
+
-
- - - + )} +
+
+ ))} +
+
+
+ +
+ +
-
-
+ + ); }); diff --git a/apps/web/core/components/project/settings/archive-project/archive-restore-modal.tsx b/apps/web/core/components/project/settings/archive-project/archive-restore-modal.tsx index f0a02f22d77..8a7699fe8d0 100644 --- a/apps/web/core/components/project/settings/archive-project/archive-restore-modal.tsx +++ b/apps/web/core/components/project/settings/archive-project/archive-restore-modal.tsx @@ -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,61 +80,31 @@ export function ArchiveRestoreProjectModal(props: Props) { }; return ( - - - -
- - -
-
- - -
-

- {archive ? "Archive" : "Restore"} {projectDetails.name} -

-

- {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." - : "Restoring a project will activate it and make it visible to all members of the project. Are you sure you want to continue?"} -

-
- - -
-
-
-
-
+ +
+

+ {archive ? "Archive" : "Restore"} {projectDetails.name} +

+

+ {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." + : "Restoring a project will activate it and make it visible to all members of the project. Are you sure you want to continue?"} +

+
+ +
-
-
+
+
); } diff --git a/apps/web/core/components/workspace-notifications/sidebar/notification-card/options/snooze/modal.tsx b/apps/web/core/components/workspace-notifications/sidebar/notification-card/options/snooze/modal.tsx index b481fba2a60..e50e552f175 100644 --- a/apps/web/core/components/workspace-notifications/sidebar/notification-card/options/snooze/modal.tsx +++ b/apps/web/core/components/workspace-notifications/sidebar/notification-card/options/snooze/modal.tsx @@ -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,155 +107,117 @@ export function NotificationSnoozeModal(props: TNotificationSnoozeModal) { }; return ( - - - -
- - -
-
- - -
-
- - Customize Snooze Time - + + +
+

Customize Snooze Time

+ +
+ +
+
-
- +
+
+
Pick a date
+ ( + { + setValue("time", undefined); + onChange(val); + }} + minDate={new Date()} + buttonVariant="border-with-text" + buttonContainerClassName="w-full text-left" + buttonClassName="border-strong px-3 py-2.5" + hideIcon + /> + )} + /> +
+
+
Pick a time
+ ( + + {value ? ( + + {value} {watch("period").toLowerCase()} + + ) : ( + Select a time + )}
-
- -
-
-
Pick a date
- ( - { - setValue("time", undefined); - onChange(val); - }} - minDate={new Date()} - buttonVariant="border-with-text" - buttonContainerClassName="w-full text-left" - buttonClassName="border-strong px-3 py-2.5" - hideIcon - /> - )} - /> + } + input + > +
+
{ + setValue("period", "AM"); + }} + 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
-
-
Pick a time
- ( - - {value ? ( - - {value} {watch("period").toLowerCase()} - - ) : ( - Select a time - )} -
- } - input - > -
-
{ - setValue("period", "AM"); - }} - 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 -
-
{ - setValue("period", "PM"); - }} - 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 -
-
- {getTimeStamp().length > 0 ? ( - getTimeStamp().map((time, index) => ( - -
- {time.label} -
-
- )) - ) : ( -

No available time for this date.

- )} - - )} - /> +
{ + setValue("period", "PM"); + }} + 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
+ {getTimeStamp().length > 0 ? ( + getTimeStamp().map((time, index) => ( + +
+ {time.label} +
+
+ )) + ) : ( +

No available time for this date.

+ )} + + )} + /> +
+
-
-
- - -
-
- - - +
+
+ +
-
-
+ + ); } From cc7c1413028c408bf4715b4dd438e4645234bbb6 Mon Sep 17 00:00:00 2001 From: vamsikrishnamathala Date: Mon, 22 Dec 2025 20:17:02 +0530 Subject: [PATCH 2/2] chore: fixed spacings --- .../account/deactivate-account-modal.tsx | 2 +- .../automation/select-month-modal.tsx | 2 +- .../core/modals/user-image-upload-modal.tsx | 24 +++++++++---------- .../modals/workspace-image-upload-modal.tsx | 24 +++++++++---------- .../core/components/exporter/export-modal.tsx | 2 +- .../inbox/modals/select-duplicate.tsx | 1 + .../inbox/modals/snooze-issue-modal.tsx | 2 +- 7 files changed, 29 insertions(+), 28 deletions(-) diff --git a/apps/web/core/components/account/deactivate-account-modal.tsx b/apps/web/core/components/account/deactivate-account-modal.tsx index 30fbca1ef11..ae10f1c94e0 100644 --- a/apps/web/core/components/account/deactivate-account-modal.tsx +++ b/apps/web/core/components/account/deactivate-account-modal.tsx @@ -80,7 +80,7 @@ export function DeactivateAccountModal(props: Props) {
-
-

File formats supported- .jpeg, .jpg, .png, .webp

-
- -
- - +
+ + +
diff --git a/apps/web/core/components/core/modals/workspace-image-upload-modal.tsx b/apps/web/core/components/core/modals/workspace-image-upload-modal.tsx index 20c7f1983d5..0818406935c 100644 --- a/apps/web/core/components/core/modals/workspace-image-upload-modal.tsx +++ b/apps/web/core/components/core/modals/workspace-image-upload-modal.tsx @@ -148,19 +148,19 @@ export const WorkspaceImageUploadModal = observer(function WorkspaceImageUploadM

)} - -

File formats supported- .jpeg, .jpg, .png, .webp

-
- -
- - +
+ + +
diff --git a/apps/web/core/components/exporter/export-modal.tsx b/apps/web/core/components/exporter/export-modal.tsx index 6f955e70948..309e842ccb9 100644 --- a/apps/web/core/components/exporter/export-modal.tsx +++ b/apps/web/core/components/exporter/export-modal.tsx @@ -139,7 +139,7 @@ export const Exporter = observer(function Exporter(props: Props) { multiple /> -
setMultiple(!multiple)} className="flex max-w-min cursor-pointer items-center gap-2"> +
setMultiple(!multiple)} />
{t("workspace_settings.settings.exports.export_separate_files")} diff --git a/apps/web/core/components/inbox/modals/select-duplicate.tsx b/apps/web/core/components/inbox/modals/select-duplicate.tsx index 0104672b58a..ee1c65074d8 100644 --- a/apps/web/core/components/inbox/modals/select-duplicate.tsx +++ b/apps/web/core/components/inbox/modals/select-duplicate.tsx @@ -65,6 +65,7 @@ export function SelectDuplicateInboxIssueModal(props: Props) { const handleClose = () => { onClose(); + setQuery(""); }; const handleSubmit = (selectedItem: string) => { diff --git a/apps/web/core/components/inbox/modals/snooze-issue-modal.tsx b/apps/web/core/components/inbox/modals/snooze-issue-modal.tsx index 6f391dbda07..4f05552df9f 100644 --- a/apps/web/core/components/inbox/modals/snooze-issue-modal.tsx +++ b/apps/web/core/components/inbox/modals/snooze-issue-modal.tsx @@ -41,7 +41,7 @@ export function InboxIssueSnoozeModal(props: InboxIssueSnoozeModalProps) {