forked from github/plane
style: new buttons added (#470)
This commit is contained in:
parent
4de0abfc22
commit
e7ef6275cd
@ -2,7 +2,7 @@ import React, { useEffect, useState } from "react";
|
||||
import { useForm } from "react-hook-form";
|
||||
// ui
|
||||
import { CheckCircleIcon } from "@heroicons/react/20/solid";
|
||||
import { Button, Input } from "components/ui";
|
||||
import { Input, SecondaryButton } from "components/ui";
|
||||
// services
|
||||
import authenticationService from "services/authentication.service";
|
||||
import useToast from "hooks/use-toast";
|
||||
@ -140,8 +140,8 @@ export const EmailCodeForm = ({ onSuccess }: any) => {
|
||||
/>
|
||||
<button
|
||||
type="button"
|
||||
className={`text-xs mt-5 w-full flex justify-end outline-none ${
|
||||
isResendDisabled ? "text-gray-400 cursor-default" : "cursor-pointer text-theme"
|
||||
className={`mt-5 flex w-full justify-end text-xs outline-none ${
|
||||
isResendDisabled ? "cursor-default text-gray-400" : "cursor-pointer text-theme"
|
||||
} `}
|
||||
onClick={() => {
|
||||
setIsCodeResending(true);
|
||||
@ -169,16 +169,16 @@ export const EmailCodeForm = ({ onSuccess }: any) => {
|
||||
)}
|
||||
<div>
|
||||
{codeSent ? (
|
||||
<Button
|
||||
<SecondaryButton
|
||||
type="submit"
|
||||
className="w-full text-center"
|
||||
onClick={handleSubmit(handleSignin)}
|
||||
disabled={isSubmitting || (!isValid && isDirty)}
|
||||
loading={isSubmitting || (!isValid && isDirty)}
|
||||
>
|
||||
{isSubmitting ? "Signing in..." : "Sign in"}
|
||||
</Button>
|
||||
</SecondaryButton>
|
||||
) : (
|
||||
<Button
|
||||
<SecondaryButton
|
||||
type="submit"
|
||||
className="w-full text-center"
|
||||
onClick={() => {
|
||||
@ -186,10 +186,10 @@ export const EmailCodeForm = ({ onSuccess }: any) => {
|
||||
setResendCodeTimer(30);
|
||||
});
|
||||
}}
|
||||
disabled={isSubmitting || (!isValid && isDirty)}
|
||||
loading={isSubmitting || (!isValid && isDirty)}
|
||||
>
|
||||
{isSubmitting ? "Sending code..." : "Send code"}
|
||||
</Button>
|
||||
</SecondaryButton>
|
||||
)}
|
||||
</div>
|
||||
</form>
|
||||
|
@ -1,13 +1,15 @@
|
||||
import React from "react";
|
||||
// next
|
||||
|
||||
import Link from "next/link";
|
||||
|
||||
// react hook form
|
||||
import { useForm } from "react-hook-form";
|
||||
// ui
|
||||
import { Button, Input } from "components/ui";
|
||||
// services
|
||||
import authenticationService from "services/authentication.service";
|
||||
// hooks
|
||||
import useToast from "hooks/use-toast";
|
||||
|
||||
// ui
|
||||
import { Input, SecondaryButton } from "components/ui";
|
||||
// types
|
||||
type EmailPasswordFormValues = {
|
||||
email: string;
|
||||
@ -97,13 +99,13 @@ export const EmailPasswordForm = ({ onSuccess }: any) => {
|
||||
</div>
|
||||
</div>
|
||||
<div className="mt-5">
|
||||
<Button
|
||||
disabled={isSubmitting || (!isValid && isDirty)}
|
||||
className="w-full text-center"
|
||||
<SecondaryButton
|
||||
type="submit"
|
||||
className="w-full text-center"
|
||||
loading={isSubmitting || (!isValid && isDirty)}
|
||||
>
|
||||
{isSubmitting ? "Signing in..." : "Sign In"}
|
||||
</Button>
|
||||
</SecondaryButton>
|
||||
</div>
|
||||
</form>
|
||||
</>
|
||||
|
@ -20,7 +20,7 @@ import { CreateUpdateIssueModal } from "components/issues";
|
||||
import { CreateUpdateCycleModal } from "components/cycles";
|
||||
import { CreateUpdateModuleModal } from "components/modules";
|
||||
// ui
|
||||
import { Button } from "components/ui";
|
||||
import { SecondaryButton } from "components/ui";
|
||||
// icons
|
||||
import {
|
||||
FolderIcon,
|
||||
@ -350,11 +350,7 @@ export const CommandPalette: React.FC = () => {
|
||||
</Combobox>
|
||||
|
||||
<div className="flex items-center justify-end gap-2 p-3">
|
||||
<div>
|
||||
<Button type="button" size="sm" onClick={handleCommandPaletteClose}>
|
||||
Close
|
||||
</Button>
|
||||
</div>
|
||||
<SecondaryButton onClick={handleCommandPaletteClose}>Close</SecondaryButton>
|
||||
</div>
|
||||
</Dialog.Panel>
|
||||
</Transition.Child>
|
||||
|
@ -13,7 +13,7 @@ import issuesServices from "services/issues.service";
|
||||
// hooks
|
||||
import useToast from "hooks/use-toast";
|
||||
// ui
|
||||
import { Button } from "components/ui";
|
||||
import { DangerButton, SecondaryButton } from "components/ui";
|
||||
// icons
|
||||
import { MagnifyingGlassIcon } from "@heroicons/react/24/outline";
|
||||
import { LayerDiagonalIcon } from "components/icons";
|
||||
@ -211,17 +211,10 @@ export const BulkDeleteIssuesModal: React.FC<Props> = ({ isOpen, setIsOpen }) =>
|
||||
|
||||
{filteredIssues.length > 0 && (
|
||||
<div className="flex items-center justify-end gap-2 p-3">
|
||||
<Button type="button" theme="secondary" size="sm" onClick={handleClose}>
|
||||
Close
|
||||
</Button>
|
||||
<Button
|
||||
onClick={handleSubmit(handleDelete)}
|
||||
theme="danger"
|
||||
size="sm"
|
||||
disabled={isSubmitting}
|
||||
>
|
||||
<SecondaryButton onClick={handleClose}>Cancel</SecondaryButton>
|
||||
<DangerButton onClick={handleSubmit(handleDelete)} loading={isSubmitting}>
|
||||
{isSubmitting ? "Deleting..." : "Delete selected issues"}
|
||||
</Button>
|
||||
</DangerButton>
|
||||
</div>
|
||||
)}
|
||||
</form>
|
||||
|
@ -1,14 +1,15 @@
|
||||
import React, { useState } from "react";
|
||||
|
||||
// headless ui
|
||||
import { Combobox, Dialog, Transition } from "@headlessui/react";
|
||||
// react-hook-form
|
||||
import { Controller, SubmitHandler, useForm } from "react-hook-form";
|
||||
// hooks
|
||||
import { Combobox, Dialog, Transition } from "@headlessui/react";
|
||||
import { MagnifyingGlassIcon, RectangleStackIcon } from "@heroicons/react/24/outline";
|
||||
import useToast from "hooks/use-toast";
|
||||
// headless ui
|
||||
// ui
|
||||
import { Button } from "components/ui";
|
||||
import { PrimaryButton, SecondaryButton } from "components/ui";
|
||||
// icons
|
||||
import { MagnifyingGlassIcon } from "@heroicons/react/24/outline";
|
||||
import { LayerDiagonalIcon } from "components/icons";
|
||||
// types
|
||||
import { IIssue } from "types";
|
||||
@ -180,17 +181,10 @@ export const ExistingIssuesListModal: React.FC<Props> = ({
|
||||
/>
|
||||
{filteredIssues.length > 0 && (
|
||||
<div className="flex items-center justify-end gap-2 p-3">
|
||||
<Button type="button" theme="secondary" size="sm" onClick={handleClose}>
|
||||
Cancel
|
||||
</Button>
|
||||
<Button
|
||||
type="button"
|
||||
size="sm"
|
||||
onClick={handleSubmit(onSubmit)}
|
||||
disabled={isSubmitting}
|
||||
>
|
||||
<SecondaryButton onClick={handleClose}>Cancel</SecondaryButton>
|
||||
<PrimaryButton onClick={handleSubmit(onSubmit)} loading={isSubmitting}>
|
||||
{isSubmitting ? "Adding..." : "Add selected issues"}
|
||||
</Button>
|
||||
</PrimaryButton>
|
||||
</div>
|
||||
)}
|
||||
</form>
|
||||
|
@ -13,8 +13,7 @@ import { Tab, Transition, Popover } from "@headlessui/react";
|
||||
import fileService from "services/file.service";
|
||||
|
||||
// components
|
||||
import { Input, Spinner } from "components/ui";
|
||||
import { PrimaryButton } from "components/ui/button/primary-button";
|
||||
import { Input, Spinner, PrimaryButton } from "components/ui";
|
||||
// hooks
|
||||
import useOutsideClickDetector from "hooks/use-outside-click-detector";
|
||||
|
||||
|
@ -3,16 +3,16 @@ import React, { useCallback, useState } from "react";
|
||||
import NextImage from "next/image";
|
||||
import { useRouter } from "next/router";
|
||||
|
||||
// react-dropzone
|
||||
import { useDropzone } from "react-dropzone";
|
||||
|
||||
// headless ui
|
||||
import { Transition, Dialog } from "@headlessui/react";
|
||||
|
||||
// services
|
||||
import fileServices from "services/file.service";
|
||||
// icon
|
||||
import { UserCircleIcon } from "components/icons";
|
||||
// ui
|
||||
import { Button } from "components/ui";
|
||||
import { PrimaryButton, SecondaryButton } from "components/ui";
|
||||
// icons
|
||||
import { UserCircleIcon } from "components/icons";
|
||||
|
||||
type TImageUploadModalProps = {
|
||||
value?: string | null;
|
||||
@ -39,12 +39,7 @@ export const ImageUploadModal: React.FC<TImageUploadModalProps> = ({
|
||||
setImage(acceptedFiles[0]);
|
||||
}, []);
|
||||
|
||||
const {
|
||||
getRootProps,
|
||||
getInputProps,
|
||||
isDragActive,
|
||||
open: openFileDialog,
|
||||
} = useDropzone({
|
||||
const { getRootProps, getInputProps, isDragActive } = useDropzone({
|
||||
onDrop,
|
||||
});
|
||||
|
||||
@ -158,16 +153,10 @@ export const ImageUploadModal: React.FC<TImageUploadModalProps> = ({
|
||||
</div>
|
||||
</div>
|
||||
<div className="mt-5 sm:mt-6 sm:grid sm:grid-flow-row-dense sm:grid-cols-2 sm:gap-3">
|
||||
<Button theme="secondary" onClick={handleClose}>
|
||||
Cancel
|
||||
</Button>
|
||||
<Button
|
||||
type="submit"
|
||||
onClick={handleSubmit}
|
||||
disabled={isImageUploading || image === null}
|
||||
>
|
||||
<SecondaryButton onClick={handleClose}>Cancel</SecondaryButton>
|
||||
<PrimaryButton onClick={handleSubmit} loading={isImageUploading || !image}>
|
||||
{isImageUploading ? "Uploading..." : "Upload & Save"}
|
||||
</Button>
|
||||
</PrimaryButton>
|
||||
</div>
|
||||
</Dialog.Panel>
|
||||
</Transition.Child>
|
||||
|
@ -18,6 +18,8 @@ import { AllLists, AllBoards } from "components/core";
|
||||
import { CreateUpdateIssueModal, DeleteIssueModal } from "components/issues";
|
||||
import StrictModeDroppable from "components/dnd/StrictModeDroppable";
|
||||
import { CreateUpdateViewModal } from "components/views";
|
||||
// ui
|
||||
import { EmptySpace, EmptySpaceItem, PrimaryButton } from "components/ui";
|
||||
// icons
|
||||
import { PlusIcon, RectangleStackIcon, TrashIcon, XMarkIcon } from "@heroicons/react/24/outline";
|
||||
// helpers
|
||||
@ -27,7 +29,6 @@ import {
|
||||
CycleIssueResponse,
|
||||
IIssue,
|
||||
IIssueFilterOptions,
|
||||
IView,
|
||||
ModuleIssueResponse,
|
||||
UserAuth,
|
||||
} from "types";
|
||||
@ -41,8 +42,6 @@ import {
|
||||
PROJECT_MEMBERS,
|
||||
STATE_LIST,
|
||||
} from "constants/fetch-keys";
|
||||
import { EmptySpace, EmptySpaceItem } from "components/ui";
|
||||
import { PrimaryButton } from "components/ui/button/primary-button";
|
||||
|
||||
type Props = {
|
||||
type?: "issue" | "cycle" | "module";
|
||||
@ -501,14 +500,12 @@ export const IssuesView: React.FC<Props> = ({ type = "issue", openIssuesListModa
|
||||
|
||||
{Object.keys(filters).length > 0 && (
|
||||
<PrimaryButton
|
||||
type="button"
|
||||
onClick={() =>
|
||||
setCreateViewModal({
|
||||
query: filters,
|
||||
})
|
||||
}
|
||||
className="flex items-center gap-4 text-sm"
|
||||
size="sm"
|
||||
className="flex items-center gap-2 text-sm"
|
||||
>
|
||||
<PlusIcon className="h-4 w-4" />
|
||||
Save view
|
||||
|
@ -1,15 +1,11 @@
|
||||
import React from "react";
|
||||
|
||||
import { useRouter } from "next/router";
|
||||
|
||||
import { mutate } from "swr";
|
||||
|
||||
// react-hook-form
|
||||
import { useForm } from "react-hook-form";
|
||||
// headless ui
|
||||
import { Dialog, Transition } from "@headlessui/react";
|
||||
// ui
|
||||
import { Button, Input } from "components/ui";
|
||||
import { Input, PrimaryButton, SecondaryButton } from "components/ui";
|
||||
// types
|
||||
import type { IIssueLink, ModuleLink } from "types";
|
||||
|
||||
@ -116,12 +112,10 @@ export const LinkModal: React.FC<Props> = ({ isOpen, handleClose, onFormSubmit }
|
||||
</div>
|
||||
</div>
|
||||
<div className="mt-5 flex justify-end gap-2">
|
||||
<Button theme="secondary" onClick={onClose}>
|
||||
Cancel
|
||||
</Button>
|
||||
<Button type="submit" disabled={isSubmitting}>
|
||||
<SecondaryButton onClick={onClose}>Cancel</SecondaryButton>
|
||||
<PrimaryButton onClick={handleSubmit(onSubmit)} loading={isSubmitting}>
|
||||
{isSubmitting ? "Adding Link..." : "Add Link"}
|
||||
</Button>
|
||||
</PrimaryButton>
|
||||
</div>
|
||||
</form>
|
||||
</Dialog.Panel>
|
||||
|
@ -1,4 +1,4 @@
|
||||
import React, { useEffect, useRef, useState } from "react";
|
||||
import React, { useState } from "react";
|
||||
// next
|
||||
import { useRouter } from "next/router";
|
||||
// swr
|
||||
@ -10,7 +10,7 @@ import cycleService from "services/cycles.service";
|
||||
// hooks
|
||||
import useToast from "hooks/use-toast";
|
||||
// ui
|
||||
import { Button } from "components/ui";
|
||||
import { DangerButton, SecondaryButton } from "components/ui";
|
||||
// icons
|
||||
import { ExclamationTriangleIcon } from "@heroicons/react/24/outline";
|
||||
// types
|
||||
@ -28,7 +28,6 @@ export const DeleteCycleModal: React.FC<TConfirmCycleDeletionProps> = ({
|
||||
setIsOpen,
|
||||
data,
|
||||
}) => {
|
||||
const cancelButtonRef = useRef(null);
|
||||
const [isDeleteLoading, setIsDeleteLoading] = useState(false);
|
||||
|
||||
const router = useRouter();
|
||||
@ -68,12 +67,7 @@ export const DeleteCycleModal: React.FC<TConfirmCycleDeletionProps> = ({
|
||||
|
||||
return (
|
||||
<Transition.Root show={isOpen} as={React.Fragment}>
|
||||
<Dialog
|
||||
as="div"
|
||||
className="relative z-20"
|
||||
initialFocus={cancelButtonRef}
|
||||
onClose={handleClose}
|
||||
>
|
||||
<Dialog as="div" className="relative z-20" onClose={handleClose}>
|
||||
<Transition.Child
|
||||
as={React.Fragment}
|
||||
enter="ease-out duration-300"
|
||||
@ -121,25 +115,11 @@ export const DeleteCycleModal: React.FC<TConfirmCycleDeletionProps> = ({
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="bg-gray-50 px-4 py-3 sm:flex sm:flex-row-reverse sm:px-6">
|
||||
<Button
|
||||
type="button"
|
||||
onClick={handleDeletion}
|
||||
theme="danger"
|
||||
disabled={isDeleteLoading}
|
||||
className="inline-flex sm:ml-3"
|
||||
>
|
||||
<div className="flex justify-end gap-2 bg-gray-50 p-4 sm:px-6">
|
||||
<SecondaryButton onClick={handleClose}>Cancel</SecondaryButton>
|
||||
<DangerButton onClick={handleDeletion} loading={isDeleteLoading}>
|
||||
{isDeleteLoading ? "Deleting..." : "Delete"}
|
||||
</Button>
|
||||
<Button
|
||||
type="button"
|
||||
theme="secondary"
|
||||
className="inline-flex sm:ml-3"
|
||||
onClick={handleClose}
|
||||
ref={cancelButtonRef}
|
||||
>
|
||||
Cancel
|
||||
</Button>
|
||||
</DangerButton>
|
||||
</div>
|
||||
</Dialog.Panel>
|
||||
</Transition.Child>
|
||||
|
@ -1,18 +1,19 @@
|
||||
import { useEffect, useState } from "react";
|
||||
|
||||
import { useRouter } from "next/router";
|
||||
|
||||
// toast
|
||||
import useToast from "hooks/use-toast";
|
||||
// react-hook-form
|
||||
import { Controller, useForm } from "react-hook-form";
|
||||
// ui
|
||||
import { Button, CustomDatePicker, CustomSelect, Input, TextArea } from "components/ui";
|
||||
// types
|
||||
import { ICycle } from "types";
|
||||
// services
|
||||
import cyclesService from "services/cycles.service";
|
||||
// helper
|
||||
// hooks
|
||||
import useToast from "hooks/use-toast";
|
||||
// ui
|
||||
import { CustomDatePicker, Input, PrimaryButton, SecondaryButton, TextArea } from "components/ui";
|
||||
// helpers
|
||||
import { getDateRangeStatus } from "helpers/date-time.helper";
|
||||
// types
|
||||
import { ICycle } from "types";
|
||||
|
||||
type Props = {
|
||||
handleFormSubmit: (values: Partial<ICycle>) => Promise<void>;
|
||||
@ -188,11 +189,8 @@ export const CycleForm: React.FC<Props> = ({ handleFormSubmit, handleClose, stat
|
||||
</div>
|
||||
</div>
|
||||
<div className="mt-5 flex justify-end gap-2">
|
||||
<Button theme="secondary" onClick={handleClose}>
|
||||
Cancel
|
||||
</Button>
|
||||
|
||||
<Button
|
||||
<SecondaryButton onClick={handleClose}>Cancel</SecondaryButton>
|
||||
<PrimaryButton
|
||||
type="submit"
|
||||
className={
|
||||
checkEmptyDate
|
||||
@ -201,7 +199,7 @@ export const CycleForm: React.FC<Props> = ({ handleFormSubmit, handleClose, stat
|
||||
? "cursor-pointer"
|
||||
: "cursor-not-allowed"
|
||||
}
|
||||
disabled={isSubmitting || checkEmptyDate ? false : isDateValid ? false : true}
|
||||
loading={isSubmitting || checkEmptyDate ? false : isDateValid ? false : true}
|
||||
>
|
||||
{status
|
||||
? isSubmitting
|
||||
@ -210,7 +208,7 @@ export const CycleForm: React.FC<Props> = ({ handleFormSubmit, handleClose, stat
|
||||
: isSubmitting
|
||||
? "Creating Cycle..."
|
||||
: "Create Cycle"}
|
||||
</Button>
|
||||
</PrimaryButton>
|
||||
</div>
|
||||
</form>
|
||||
);
|
||||
|
@ -13,7 +13,7 @@ import useToast from "hooks/use-toast";
|
||||
// icons
|
||||
import { ExclamationTriangleIcon } from "@heroicons/react/24/outline";
|
||||
// ui
|
||||
import { Button } from "components/ui";
|
||||
import { SecondaryButton, DangerButton } from "components/ui";
|
||||
// types
|
||||
import type { CycleIssueResponse, IIssue, ModuleIssueResponse } from "types";
|
||||
// fetch-keys
|
||||
@ -26,7 +26,6 @@ type Props = {
|
||||
};
|
||||
|
||||
export const DeleteIssueModal: React.FC<Props> = ({ isOpen, handleClose, data }) => {
|
||||
const cancelButtonRef = useRef(null);
|
||||
const [isDeleteLoading, setIsDeleteLoading] = useState(false);
|
||||
|
||||
const router = useRouter();
|
||||
@ -98,7 +97,7 @@ export const DeleteIssueModal: React.FC<Props> = ({ isOpen, handleClose, data })
|
||||
|
||||
return (
|
||||
<Transition.Root show={isOpen} as={React.Fragment}>
|
||||
<Dialog as="div" className="relative z-20" initialFocus={cancelButtonRef} onClose={onClose}>
|
||||
<Dialog as="div" className="relative z-20" onClose={onClose}>
|
||||
<Transition.Child
|
||||
as={React.Fragment}
|
||||
enter="ease-out duration-300"
|
||||
@ -136,34 +135,20 @@ export const DeleteIssueModal: React.FC<Props> = ({ isOpen, handleClose, data })
|
||||
</span>
|
||||
</div>
|
||||
<span>
|
||||
<p className="text-sm leading-7 text-gray-500 break-all">
|
||||
<p className="break-all text-sm leading-7 text-gray-500">
|
||||
Are you sure you want to delete issue{" "}
|
||||
<span className="font-semibold break-all">
|
||||
<span className="break-all font-semibold">
|
||||
{data?.project_detail.identifier}-{data?.sequence_id}
|
||||
</span>{" "}
|
||||
? All of the data related to the issue will be permanently removed. This
|
||||
action cannot be undone.
|
||||
</p>
|
||||
</span>
|
||||
<div className="flex flex-row-reverse items-center gap-3">
|
||||
<Button
|
||||
type="button"
|
||||
onClick={handleDeletion}
|
||||
theme="danger"
|
||||
disabled={isDeleteLoading}
|
||||
className="rounded-lg border-none px-5 py-2 "
|
||||
>
|
||||
<div className="flex justify-end gap-2">
|
||||
<SecondaryButton onClick={onClose}>Cancel</SecondaryButton>
|
||||
<DangerButton onClick={handleDeletion} loading={isDeleteLoading}>
|
||||
{isDeleteLoading ? "Deleting..." : "Delete Issue"}
|
||||
</Button>
|
||||
<Button
|
||||
type="button"
|
||||
theme="secondary"
|
||||
className="rounded-lg border-none px-5 py-2 "
|
||||
onClick={onClose}
|
||||
ref={cancelButtonRef}
|
||||
>
|
||||
Cancel
|
||||
</Button>
|
||||
</DangerButton>
|
||||
</div>
|
||||
</div>
|
||||
</Dialog.Panel>
|
||||
|
@ -20,8 +20,7 @@ import { CreateStateModal } from "components/states";
|
||||
import { CreateUpdateCycleModal } from "components/cycles";
|
||||
import { CreateLabelModal } from "components/labels";
|
||||
// ui
|
||||
import { Button, CustomMenu, Input, Loader } from "components/ui";
|
||||
import { PrimaryButton } from "components/ui/button/primary-button";
|
||||
import { CustomMenu, Input, Loader, PrimaryButton, SecondaryButton } from "components/ui";
|
||||
// icons
|
||||
import { XMarkIcon } from "@heroicons/react/24/outline";
|
||||
// helpers
|
||||
@ -355,10 +354,8 @@ export const IssueForm: FC<IssueFormProps> = ({
|
||||
</button>
|
||||
</div>
|
||||
<div className="flex items-center gap-2">
|
||||
<Button type="button" theme="secondary" onClick={handleClose}>
|
||||
Discard
|
||||
</Button>
|
||||
<PrimaryButton type="submit" size="sm" loading={isSubmitting}>
|
||||
<SecondaryButton onClick={handleClose}>Discard</SecondaryButton>
|
||||
<PrimaryButton type="submit" loading={isSubmitting}>
|
||||
{status
|
||||
? isSubmitting
|
||||
? "Updating Issue..."
|
||||
|
@ -5,7 +5,7 @@ import { Combobox, Dialog, Transition } from "@headlessui/react";
|
||||
// icons
|
||||
import { MagnifyingGlassIcon, RectangleStackIcon } from "@heroicons/react/24/outline";
|
||||
// ui
|
||||
import { Button } from "components/ui";
|
||||
import { PrimaryButton, SecondaryButton } from "components/ui";
|
||||
// types
|
||||
import { IIssue } from "types";
|
||||
import { LayerDiagonalIcon } from "components/icons";
|
||||
@ -145,12 +145,8 @@ export const ParentIssuesListModal: React.FC<Props> = ({
|
||||
)}
|
||||
</Combobox>
|
||||
<div className="flex items-center justify-end gap-2 p-3">
|
||||
<Button type="button" theme="danger" size="sm" onClick={handleClose}>
|
||||
Cancel
|
||||
</Button>
|
||||
<Button type="button" size="sm" onClick={() => onChange(values)}>
|
||||
Add issues
|
||||
</Button>
|
||||
<SecondaryButton onClick={handleClose}>Cancel</SecondaryButton>
|
||||
<PrimaryButton onClick={() => onChange(values)}>Add issues</PrimaryButton>
|
||||
</div>
|
||||
</>
|
||||
) : (
|
||||
|
@ -14,7 +14,7 @@ import useToast from "hooks/use-toast";
|
||||
// services
|
||||
import issuesService from "services/issues.service";
|
||||
// ui
|
||||
import { Button } from "components/ui";
|
||||
import { PrimaryButton, SecondaryButton } from "components/ui";
|
||||
// icons
|
||||
import { MagnifyingGlassIcon, XMarkIcon } from "@heroicons/react/24/outline";
|
||||
import { BlockedIcon, LayerDiagonalIcon } from "components/icons";
|
||||
@ -270,14 +270,10 @@ export const SidebarBlockedSelect: React.FC<Props> = ({
|
||||
|
||||
{filteredIssues.length > 0 && (
|
||||
<div className="flex items-center justify-end gap-2 p-3">
|
||||
<div>
|
||||
<Button type="button" theme="secondary" size="sm" onClick={handleClose}>
|
||||
Close
|
||||
</Button>
|
||||
</div>
|
||||
<Button onClick={handleSubmit(onSubmit)} size="sm">
|
||||
<SecondaryButton onClick={handleClose}>Cancel</SecondaryButton>
|
||||
<PrimaryButton onClick={handleSubmit(onSubmit)}>
|
||||
Add selected issues
|
||||
</Button>
|
||||
</PrimaryButton>
|
||||
</div>
|
||||
)}
|
||||
</form>
|
||||
|
@ -14,7 +14,7 @@ import useToast from "hooks/use-toast";
|
||||
// services
|
||||
import issuesServices from "services/issues.service";
|
||||
// ui
|
||||
import { Button } from "components/ui";
|
||||
import { PrimaryButton, SecondaryButton } from "components/ui";
|
||||
// icons
|
||||
import { MagnifyingGlassIcon, XMarkIcon } from "@heroicons/react/24/outline";
|
||||
import { BlockerIcon, LayerDiagonalIcon } from "components/icons";
|
||||
@ -270,14 +270,10 @@ export const SidebarBlockerSelect: React.FC<Props> = ({
|
||||
|
||||
{filteredIssues.length > 0 && (
|
||||
<div className="flex items-center justify-end gap-2 p-3">
|
||||
<div>
|
||||
<Button type="button" theme="secondary" size="sm" onClick={handleClose}>
|
||||
Close
|
||||
</Button>
|
||||
</div>
|
||||
<Button onClick={handleSubmit(onSubmit)} size="sm">
|
||||
<SecondaryButton onClick={handleClose}>Cancel</SecondaryButton>
|
||||
<PrimaryButton onClick={handleSubmit(onSubmit)}>
|
||||
Add selected issues
|
||||
</Button>
|
||||
</PrimaryButton>
|
||||
</div>
|
||||
)}
|
||||
</Dialog.Panel>
|
||||
|
@ -29,7 +29,7 @@ import {
|
||||
SidebarStateSelect,
|
||||
} from "components/issues";
|
||||
// ui
|
||||
import { Input, Button, Spinner, CustomDatePicker } from "components/ui";
|
||||
import { Input, Spinner, CustomDatePicker } from "components/ui";
|
||||
// icons
|
||||
import {
|
||||
TagIcon,
|
||||
@ -581,12 +581,20 @@ export const IssueDetailsSidebar: React.FC<Props> = ({
|
||||
}}
|
||||
autoComplete="off"
|
||||
/>
|
||||
<Button type="submit" theme="danger" onClick={() => setCreateLabelForm(false)}>
|
||||
<button
|
||||
type="submit"
|
||||
className="grid place-items-center rounded bg-red-500 p-2.5"
|
||||
onClick={() => setCreateLabelForm(false)}
|
||||
>
|
||||
<XMarkIcon className="h-4 w-4 text-white" />
|
||||
</Button>
|
||||
<Button type="submit" theme="success" disabled={isSubmitting}>
|
||||
</button>
|
||||
<button
|
||||
type="submit"
|
||||
className="grid place-items-center rounded bg-green-500 p-2.5"
|
||||
disabled={isSubmitting}
|
||||
>
|
||||
<PlusIcon className="h-4 w-4 text-white" />
|
||||
</Button>
|
||||
</button>
|
||||
</form>
|
||||
)}
|
||||
</div>
|
||||
|
@ -210,7 +210,7 @@ export const SubIssuesList: FC<Props> = ({ parentIssue, userAuth }) => {
|
||||
<a className="group flex items-center justify-between gap-2 rounded p-2 hover:bg-gray-100">
|
||||
<div className="flex items-center gap-2 rounded text-xs">
|
||||
<span
|
||||
className="block flex-shrink-0 h-1.5 w-1.5 rounded-full"
|
||||
className="block h-1.5 w-1.5 flex-shrink-0 rounded-full"
|
||||
style={{
|
||||
backgroundColor: issue.state_detail.color,
|
||||
}}
|
||||
@ -224,7 +224,7 @@ export const SubIssuesList: FC<Props> = ({ parentIssue, userAuth }) => {
|
||||
{!isNotAllowed && (
|
||||
<button
|
||||
type="button"
|
||||
className="opacity-0 group-hover:opacity-100 cursor-pointer"
|
||||
className="cursor-pointer opacity-0 group-hover:opacity-100"
|
||||
onClick={(e) => {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
@ -253,6 +253,7 @@ export const SubIssuesList: FC<Props> = ({ parentIssue, userAuth }) => {
|
||||
}
|
||||
optionsPosition="left"
|
||||
noBorder
|
||||
noChevron
|
||||
>
|
||||
<CustomMenu.MenuItem onClick={handleCreateIssueModal}>Create new</CustomMenu.MenuItem>
|
||||
<CustomMenu.MenuItem onClick={() => setSubIssuesListModal(true)}>
|
||||
|
@ -13,7 +13,7 @@ import { Dialog, Popover, Transition } from "@headlessui/react";
|
||||
// services
|
||||
import issuesService from "services/issues.service";
|
||||
// ui
|
||||
import { Button, Input } from "components/ui";
|
||||
import { Input, PrimaryButton, SecondaryButton } from "components/ui";
|
||||
// icons
|
||||
import { ChevronDownIcon } from "@heroicons/react/24/outline";
|
||||
// types
|
||||
@ -171,12 +171,10 @@ export const CreateLabelModal: React.FC<Props> = ({ isOpen, projectId, handleClo
|
||||
</div>
|
||||
</div>
|
||||
<div className="mt-5 flex justify-end gap-2">
|
||||
<Button theme="secondary" onClick={onClose}>
|
||||
Cancel
|
||||
</Button>
|
||||
<Button type="submit" disabled={isSubmitting}>
|
||||
<SecondaryButton onClick={onClose}>Cancel</SecondaryButton>
|
||||
<PrimaryButton type="submit" loading={isSubmitting}>
|
||||
{isSubmitting ? "Creating Label..." : "Create Label"}
|
||||
</Button>
|
||||
</PrimaryButton>
|
||||
</div>
|
||||
</form>
|
||||
</Dialog.Panel>
|
||||
|
@ -13,7 +13,7 @@ import { Popover, Transition } from "@headlessui/react";
|
||||
// services
|
||||
import issuesService from "services/issues.service";
|
||||
// ui
|
||||
import { Button, Input } from "components/ui";
|
||||
import { Input, PrimaryButton, SecondaryButton } from "components/ui";
|
||||
// types
|
||||
import { IIssueLabels } from "types";
|
||||
// fetch-keys
|
||||
@ -168,24 +168,22 @@ export const CreateUpdateLabelInline: React.FC<Props> = ({
|
||||
error={errors.name}
|
||||
/>
|
||||
</div>
|
||||
<Button
|
||||
type="button"
|
||||
theme="secondary"
|
||||
<SecondaryButton
|
||||
onClick={() => {
|
||||
reset();
|
||||
setLabelForm(false);
|
||||
}}
|
||||
>
|
||||
Cancel
|
||||
</Button>
|
||||
</SecondaryButton>
|
||||
{isUpdating ? (
|
||||
<Button type="button" onClick={handleSubmit(handleLabelUpdate)} disabled={isSubmitting}>
|
||||
<PrimaryButton onClick={handleSubmit(handleLabelUpdate)} loading={isSubmitting}>
|
||||
{isSubmitting ? "Updating" : "Update"}
|
||||
</Button>
|
||||
</PrimaryButton>
|
||||
) : (
|
||||
<Button type="button" onClick={handleSubmit(handleLabelCreate)} disabled={isSubmitting}>
|
||||
<PrimaryButton onClick={handleSubmit(handleLabelCreate)} loading={isSubmitting}>
|
||||
{isSubmitting ? "Adding" : "Add"}
|
||||
</Button>
|
||||
</PrimaryButton>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
|
@ -11,7 +11,7 @@ import modulesService from "services/modules.service";
|
||||
// hooks
|
||||
import useToast from "hooks/use-toast";
|
||||
// ui
|
||||
import { Button } from "components/ui";
|
||||
import { SecondaryButton, DangerButton } from "components/ui";
|
||||
// icons
|
||||
import { ExclamationTriangleIcon } from "@heroicons/react/24/outline";
|
||||
// types
|
||||
@ -29,14 +29,10 @@ export const DeleteModuleModal: React.FC<Props> = ({ isOpen, setIsOpen, data })
|
||||
const [isDeleteLoading, setIsDeleteLoading] = useState(false);
|
||||
|
||||
const router = useRouter();
|
||||
const {
|
||||
query: { workspaceSlug },
|
||||
} = router;
|
||||
const { workspaceSlug } = router.query;
|
||||
|
||||
const { setToastAlert } = useToast();
|
||||
|
||||
const cancelButtonRef = useRef(null);
|
||||
|
||||
const handleClose = () => {
|
||||
setIsOpen(false);
|
||||
setIsDeleteLoading(false);
|
||||
@ -67,12 +63,7 @@ export const DeleteModuleModal: React.FC<Props> = ({ isOpen, setIsOpen, data })
|
||||
|
||||
return (
|
||||
<Transition.Root show={isOpen} as={React.Fragment}>
|
||||
<Dialog
|
||||
as="div"
|
||||
className="relative z-20"
|
||||
initialFocus={cancelButtonRef}
|
||||
onClose={handleClose}
|
||||
>
|
||||
<Dialog as="div" className="relative z-20" onClose={handleClose}>
|
||||
<Transition.Child
|
||||
as={React.Fragment}
|
||||
enter="ease-out duration-300"
|
||||
@ -120,25 +111,11 @@ export const DeleteModuleModal: React.FC<Props> = ({ isOpen, setIsOpen, data })
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="bg-gray-50 px-4 py-3 sm:flex sm:flex-row-reverse sm:px-6">
|
||||
<Button
|
||||
type="button"
|
||||
onClick={handleDeletion}
|
||||
theme="danger"
|
||||
disabled={isDeleteLoading}
|
||||
className="inline-flex sm:ml-3"
|
||||
>
|
||||
<div className="flex justify-end gap-2 bg-gray-50 p-4 sm:px-6">
|
||||
<SecondaryButton onClick={handleClose}>Cancel</SecondaryButton>
|
||||
<DangerButton onClick={handleDeletion} loading={isDeleteLoading}>
|
||||
{isDeleteLoading ? "Deleting..." : "Delete"}
|
||||
</Button>
|
||||
<Button
|
||||
type="button"
|
||||
theme="secondary"
|
||||
className="inline-flex sm:ml-3"
|
||||
onClick={handleClose}
|
||||
ref={cancelButtonRef}
|
||||
>
|
||||
Cancel
|
||||
</Button>
|
||||
</DangerButton>
|
||||
</div>
|
||||
</Dialog.Panel>
|
||||
</Transition.Child>
|
||||
|
@ -5,7 +5,7 @@ import { Controller, useForm } from "react-hook-form";
|
||||
// components
|
||||
import { ModuleLeadSelect, ModuleMembersSelect, ModuleStatusSelect } from "components/modules";
|
||||
// ui
|
||||
import { Button, CustomDatePicker, Input, TextArea } from "components/ui";
|
||||
import { CustomDatePicker, Input, PrimaryButton, SecondaryButton, TextArea } from "components/ui";
|
||||
// types
|
||||
import { IModule } from "types";
|
||||
|
||||
@ -132,10 +132,8 @@ export const ModuleForm: React.FC<Props> = ({ handleFormSubmit, handleClose, sta
|
||||
</div>
|
||||
</div>
|
||||
<div className="mt-5 flex justify-end gap-2">
|
||||
<Button theme="secondary" onClick={handleClose}>
|
||||
Cancel
|
||||
</Button>
|
||||
<Button type="submit" disabled={isSubmitting}>
|
||||
<SecondaryButton onClick={handleClose}>Cancel</SecondaryButton>
|
||||
<PrimaryButton type="submit" loading={isSubmitting}>
|
||||
{status
|
||||
? isSubmitting
|
||||
? "Updating Module..."
|
||||
@ -143,7 +141,7 @@ export const ModuleForm: React.FC<Props> = ({ handleFormSubmit, handleClose, sta
|
||||
: isSubmitting
|
||||
? "Creating Module..."
|
||||
: "Create Module"}
|
||||
</Button>
|
||||
</PrimaryButton>
|
||||
</div>
|
||||
</form>
|
||||
);
|
||||
|
@ -10,7 +10,7 @@ import workspaceService from "services/workspace.service";
|
||||
// hooks
|
||||
import useToast from "hooks/use-toast";
|
||||
// ui
|
||||
import { Button, Loader } from "components/ui";
|
||||
import { DangerButton, Loader, SecondaryButton } from "components/ui";
|
||||
// icons
|
||||
import GithubLogo from "public/logos/github-square.png";
|
||||
// types
|
||||
@ -133,19 +133,13 @@ const OAuthPopUp = ({ integration }: any) => {
|
||||
|
||||
{workspaceIntegrations ? (
|
||||
isInstalled ? (
|
||||
<Button
|
||||
theme="danger"
|
||||
size="rg"
|
||||
className="text-xs"
|
||||
onClick={handleRemoveIntegration}
|
||||
disabled={deletingIntegration}
|
||||
>
|
||||
<DangerButton onClick={handleRemoveIntegration} loading={deletingIntegration}>
|
||||
{deletingIntegration ? "Removing..." : "Remove installation"}
|
||||
</Button>
|
||||
</DangerButton>
|
||||
) : (
|
||||
<Button theme="secondary" size="rg" className="text-xs" onClick={startAuth}>
|
||||
<SecondaryButton onClick={startAuth} outline>
|
||||
Add installation
|
||||
</Button>
|
||||
</SecondaryButton>
|
||||
)
|
||||
) : (
|
||||
<Loader>
|
||||
|
@ -4,7 +4,7 @@ import { Dialog, Transition } from "@headlessui/react";
|
||||
// icons
|
||||
import { ExclamationTriangleIcon } from "@heroicons/react/24/outline";
|
||||
// ui
|
||||
import { Button } from "components/ui";
|
||||
import { SecondaryButton, DangerButton } from "components/ui";
|
||||
|
||||
type Props = {
|
||||
isOpen: boolean;
|
||||
@ -16,8 +16,6 @@ type Props = {
|
||||
const ConfirmProjectMemberRemove: React.FC<Props> = ({ isOpen, onClose, data, handleDelete }) => {
|
||||
const [isDeleteLoading, setIsDeleteLoading] = useState(false);
|
||||
|
||||
const cancelButtonRef = useRef(null);
|
||||
|
||||
const handleClose = () => {
|
||||
onClose();
|
||||
setIsDeleteLoading(false);
|
||||
@ -31,12 +29,7 @@ const ConfirmProjectMemberRemove: React.FC<Props> = ({ isOpen, onClose, data, ha
|
||||
|
||||
return (
|
||||
<Transition.Root show={isOpen} as={React.Fragment}>
|
||||
<Dialog
|
||||
as="div"
|
||||
className="relative z-20"
|
||||
initialFocus={cancelButtonRef}
|
||||
onClose={handleClose}
|
||||
>
|
||||
<Dialog as="div" className="relative z-20" onClose={handleClose}>
|
||||
<Transition.Child
|
||||
as={React.Fragment}
|
||||
enter="ease-out duration-300"
|
||||
@ -84,25 +77,11 @@ const ConfirmProjectMemberRemove: React.FC<Props> = ({ isOpen, onClose, data, ha
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="bg-gray-50 px-4 py-3 sm:flex sm:flex-row-reverse sm:px-6">
|
||||
<Button
|
||||
type="button"
|
||||
onClick={handleDeletion}
|
||||
theme="danger"
|
||||
disabled={isDeleteLoading}
|
||||
className="inline-flex sm:ml-3"
|
||||
>
|
||||
<div className="flex justify-end gap-2 bg-gray-50 p-4 sm:px-6">
|
||||
<SecondaryButton onClick={handleClose}>Cancel</SecondaryButton>
|
||||
<DangerButton onClick={handleDeletion} loading={isDeleteLoading}>
|
||||
{isDeleteLoading ? "Removing..." : "Remove"}
|
||||
</Button>
|
||||
<Button
|
||||
type="button"
|
||||
theme="secondary"
|
||||
className="inline-flex sm:ml-3"
|
||||
onClick={handleClose}
|
||||
ref={cancelButtonRef}
|
||||
>
|
||||
Cancel
|
||||
</Button>
|
||||
</DangerButton>
|
||||
</div>
|
||||
</Dialog.Panel>
|
||||
</Transition.Child>
|
||||
|
@ -15,8 +15,7 @@ import workspaceService from "services/workspace.service";
|
||||
// hooks
|
||||
import useToast from "hooks/use-toast";
|
||||
// ui
|
||||
import { PrimaryButton } from "components/ui/button/primary-button";
|
||||
import { Button, Input, TextArea, CustomSelect } from "components/ui";
|
||||
import { Input, TextArea, CustomSelect, PrimaryButton, SecondaryButton } from "components/ui";
|
||||
// icons
|
||||
import { XMarkIcon } from "@heroicons/react/24/outline";
|
||||
// components
|
||||
@ -311,9 +310,7 @@ export const CreateProjectModal: React.FC<Props> = (props) => {
|
||||
</div>
|
||||
|
||||
<div className="mt-5 flex justify-end gap-2 border-t-2 px-4 py-3">
|
||||
<Button theme="secondary" onClick={handleClose}>
|
||||
Cancel
|
||||
</Button>
|
||||
<SecondaryButton onClick={handleClose}>Cancel</SecondaryButton>
|
||||
<PrimaryButton type="submit" size="sm" loading={isSubmitting}>
|
||||
{isSubmitting ? "Adding project..." : "Add Project"}
|
||||
</PrimaryButton>
|
||||
|
@ -11,7 +11,7 @@ import useToast from "hooks/use-toast";
|
||||
// icons
|
||||
import { ExclamationTriangleIcon } from "@heroicons/react/24/outline";
|
||||
// ui
|
||||
import { Button, Input } from "components/ui";
|
||||
import { DangerButton, Input, SecondaryButton } from "components/ui";
|
||||
// types
|
||||
import type { IProject, IWorkspace } from "types";
|
||||
// fetch-keys
|
||||
@ -24,10 +24,12 @@ type TConfirmProjectDeletionProps = {
|
||||
data: IProject | null;
|
||||
};
|
||||
|
||||
export const DeleteProjectModal: React.FC<TConfirmProjectDeletionProps> = (props) => {
|
||||
const { isOpen, data, onClose, onSuccess } = props;
|
||||
|
||||
const cancelButtonRef = useRef(null);
|
||||
export const DeleteProjectModal: React.FC<TConfirmProjectDeletionProps> = ({
|
||||
isOpen,
|
||||
data,
|
||||
onClose,
|
||||
onSuccess,
|
||||
}) => {
|
||||
const [isDeleteLoading, setIsDeleteLoading] = useState(false);
|
||||
const [confirmProjectName, setConfirmProjectName] = useState("");
|
||||
const [confirmDeleteMyProject, setConfirmDeleteMyProject] = useState(false);
|
||||
@ -84,12 +86,7 @@ export const DeleteProjectModal: React.FC<TConfirmProjectDeletionProps> = (props
|
||||
|
||||
return (
|
||||
<Transition.Root show={isOpen} as={React.Fragment}>
|
||||
<Dialog
|
||||
as="div"
|
||||
className="relative z-20"
|
||||
initialFocus={cancelButtonRef}
|
||||
onClose={handleClose}
|
||||
>
|
||||
<Dialog as="div" className="relative z-20" onClose={handleClose}>
|
||||
<Transition.Child
|
||||
as={React.Fragment}
|
||||
enter="ease-out duration-300"
|
||||
@ -168,25 +165,11 @@ export const DeleteProjectModal: React.FC<TConfirmProjectDeletionProps> = (props
|
||||
name="typeDelete"
|
||||
/>
|
||||
</div>
|
||||
<div className="flex flex-row-reverse items-center gap-3">
|
||||
<Button
|
||||
type="button"
|
||||
onClick={handleDeletion}
|
||||
theme="danger"
|
||||
disabled={isDeleteLoading || !canDelete}
|
||||
className="rounded-lg border-none px-5 py-2"
|
||||
>
|
||||
<div className="flex justify-end gap-2">
|
||||
<SecondaryButton onClick={handleClose}>Cancel</SecondaryButton>
|
||||
<DangerButton onClick={handleDeletion} loading={isDeleteLoading || !canDelete}>
|
||||
{isDeleteLoading ? "Deleting..." : "Delete Project"}
|
||||
</Button>
|
||||
<Button
|
||||
type="button"
|
||||
theme="secondary"
|
||||
className="rounded-lg border-none px-5 py-2"
|
||||
onClick={handleClose}
|
||||
ref={cancelButtonRef}
|
||||
>
|
||||
Cancel
|
||||
</Button>
|
||||
</DangerButton>
|
||||
</div>
|
||||
</div>
|
||||
</Dialog.Panel>
|
||||
|
@ -1,10 +1,11 @@
|
||||
import React, { useState } from "react";
|
||||
|
||||
// headless ui
|
||||
import { Transition, Dialog } from "@headlessui/react";
|
||||
|
||||
// ui
|
||||
import { PrimaryButton, SecondaryButton } from "components/ui";
|
||||
// types
|
||||
import type { IProject } from "types";
|
||||
import { Button } from "components/ui";
|
||||
|
||||
// type
|
||||
type TJoinProjectModalProps = {
|
||||
@ -70,12 +71,10 @@ export const JoinProjectModal: React.FC<TJoinProjectModalProps> = ({ onClose, on
|
||||
<div className="space-y-3" />
|
||||
</div>
|
||||
<div className="mt-5 flex justify-end gap-2">
|
||||
<Button type="button" theme="secondary" onClick={handleClose}>
|
||||
Cancel
|
||||
</Button>
|
||||
<Button type="submit" onClick={handleJoin} disabled={isJoiningLoading}>
|
||||
<SecondaryButton onClick={handleClose}>Cancel</SecondaryButton>
|
||||
<PrimaryButton type="submit" onClick={handleJoin} loading={isJoiningLoading}>
|
||||
{isJoiningLoading ? "Joining..." : "Join Project"}
|
||||
</Button>
|
||||
</PrimaryButton>
|
||||
</div>
|
||||
</Dialog.Panel>
|
||||
</Transition.Child>
|
||||
|
@ -1,6 +1,7 @@
|
||||
import { FC } from "react";
|
||||
|
||||
// ui
|
||||
import { Button } from "components/ui";
|
||||
import { SecondaryButton } from "components/ui";
|
||||
|
||||
export interface JoinProjectProps {
|
||||
isJoiningProject: boolean;
|
||||
@ -16,9 +17,9 @@ export const JoinProject: FC<JoinProjectProps> = ({ isJoiningProject, handleJoin
|
||||
below.
|
||||
</p>
|
||||
<div>
|
||||
<Button type="button" disabled={isJoiningProject} onClick={handleJoin}>
|
||||
<SecondaryButton loading={isJoiningProject} onClick={handleJoin}>
|
||||
{isJoiningProject ? "Joining..." : "Click to join"}
|
||||
</Button>
|
||||
</SecondaryButton>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -8,7 +8,7 @@ import { useForm, Controller } from "react-hook-form";
|
||||
|
||||
import { Dialog, Transition } from "@headlessui/react";
|
||||
// ui
|
||||
import { Button, CustomSelect, TextArea } from "components/ui";
|
||||
import { CustomSelect, PrimaryButton, SecondaryButton, TextArea } from "components/ui";
|
||||
// hooks
|
||||
import useToast from "hooks/use-toast";
|
||||
// services
|
||||
@ -218,12 +218,10 @@ const SendProjectInvitationModal: React.FC<Props> = ({ isOpen, setIsOpen, member
|
||||
</div>
|
||||
</div>
|
||||
<div className="mt-5 flex justify-end gap-2">
|
||||
<Button theme="secondary" onClick={handleClose}>
|
||||
Cancel
|
||||
</Button>
|
||||
<Button type="submit" disabled={isSubmitting}>
|
||||
<SecondaryButton onClick={handleClose}>Cancel</SecondaryButton>
|
||||
<PrimaryButton type="submit" loading={isSubmitting}>
|
||||
{isSubmitting ? "Sending Invitation..." : "Send Invitation"}
|
||||
</Button>
|
||||
</PrimaryButton>
|
||||
</div>
|
||||
</form>
|
||||
</Dialog.Panel>
|
||||
|
@ -1,14 +1,15 @@
|
||||
// react
|
||||
import React, { useState } from "react";
|
||||
|
||||
// react-hook-form
|
||||
import { Controller, useForm } from "react-hook-form";
|
||||
// react-color
|
||||
import { TwitterPicker } from "react-color";
|
||||
// headless ui
|
||||
import { Popover, Transition } from "@headlessui/react";
|
||||
// ui
|
||||
import { PencilIcon, RectangleGroupIcon } from "@heroicons/react/24/outline";
|
||||
import { TwitterPicker } from "react-color";
|
||||
import { Button, CustomMenu, Input } from "components/ui";
|
||||
import { CustomMenu, Input, PrimaryButton, SecondaryButton } from "components/ui";
|
||||
// icons
|
||||
import { PencilIcon, RectangleGroupIcon } from "@heroicons/react/24/outline";
|
||||
// types
|
||||
import { IIssueLabels } from "types";
|
||||
|
||||
@ -110,19 +111,15 @@ const SingleLabel: React.FC<Props> = ({ label, issueLabels, editLabel, handleLab
|
||||
id="labelName"
|
||||
name="name"
|
||||
register={register}
|
||||
placeholder="Lable title"
|
||||
placeholder="Label title"
|
||||
validations={{
|
||||
required: "Label title is required",
|
||||
}}
|
||||
error={errors.name}
|
||||
/>
|
||||
</div>
|
||||
<Button type="button" theme="secondary" onClick={() => setNewLabelForm(false)}>
|
||||
Cancel
|
||||
</Button>
|
||||
<Button type="button" disabled={isSubmitting}>
|
||||
{isSubmitting ? "Adding" : "Add"}
|
||||
</Button>
|
||||
<SecondaryButton onClick={() => setNewLabelForm(false)}>Cancel</SecondaryButton>
|
||||
<PrimaryButton loading={isSubmitting}>{isSubmitting ? "Adding" : "Add"}</PrimaryButton>
|
||||
</div>
|
||||
</div>
|
||||
) : (
|
||||
|
@ -13,7 +13,7 @@ import { Dialog, Popover, Transition } from "@headlessui/react";
|
||||
// services
|
||||
import stateService from "services/state.service";
|
||||
// ui
|
||||
import { Button, CustomSelect, Input, TextArea } from "components/ui";
|
||||
import { CustomSelect, Input, PrimaryButton, SecondaryButton, TextArea } from "components/ui";
|
||||
// icons
|
||||
import { ChevronDownIcon } from "@heroicons/react/24/outline";
|
||||
// types
|
||||
@ -215,12 +215,10 @@ export const CreateStateModal: React.FC<Props> = ({ isOpen, projectId, handleClo
|
||||
</div>
|
||||
</div>
|
||||
<div className="mt-5 flex justify-end gap-2">
|
||||
<Button theme="secondary" onClick={onClose}>
|
||||
Cancel
|
||||
</Button>
|
||||
<Button type="submit" disabled={isSubmitting}>
|
||||
<SecondaryButton onClick={onClose}>Cancel</SecondaryButton>
|
||||
<PrimaryButton type="submit" loading={isSubmitting}>
|
||||
{isSubmitting ? "Creating State..." : "Create State"}
|
||||
</Button>
|
||||
</PrimaryButton>
|
||||
</div>
|
||||
</form>
|
||||
</Dialog.Panel>
|
||||
|
@ -15,7 +15,7 @@ import stateService from "services/state.service";
|
||||
// hooks
|
||||
import useToast from "hooks/use-toast";
|
||||
// ui
|
||||
import { Button, CustomSelect, Input } from "components/ui";
|
||||
import { CustomSelect, Input, PrimaryButton, SecondaryButton } from "components/ui";
|
||||
// types
|
||||
import type { IState } from "types";
|
||||
// fetch-keys
|
||||
@ -217,12 +217,10 @@ export const CreateUpdateStateInline: React.FC<Props> = ({ data, onClose, select
|
||||
error={errors.description}
|
||||
autoComplete="off"
|
||||
/>
|
||||
<Button theme="secondary" onClick={handleClose}>
|
||||
Cancel
|
||||
</Button>
|
||||
<Button theme="primary" disabled={isSubmitting} type="submit">
|
||||
<SecondaryButton onClick={handleClose}>Cancel</SecondaryButton>
|
||||
<PrimaryButton type="submit" loading={isSubmitting}>
|
||||
{isSubmitting ? (data ? "Updating..." : "Creating...") : data ? "Update" : "Create"}
|
||||
</Button>
|
||||
</PrimaryButton>
|
||||
</form>
|
||||
);
|
||||
};
|
||||
|
@ -1,4 +1,4 @@
|
||||
import React, { useEffect, useRef, useState } from "react";
|
||||
import React, { useEffect, useState } from "react";
|
||||
|
||||
import { useRouter } from "next/router";
|
||||
|
||||
@ -14,7 +14,7 @@ import issuesServices from "services/issues.service";
|
||||
// hooks
|
||||
import useToast from "hooks/use-toast";
|
||||
// ui
|
||||
import { Button } from "components/ui";
|
||||
import { DangerButton, SecondaryButton } from "components/ui";
|
||||
// helpers
|
||||
import { groupBy } from "helpers/array.helper";
|
||||
// types
|
||||
@ -46,8 +46,6 @@ export const DeleteStateModal: React.FC<Props> = ({ isOpen, onClose, data }) =>
|
||||
: null
|
||||
);
|
||||
|
||||
const cancelButtonRef = useRef(null);
|
||||
|
||||
const handleClose = () => {
|
||||
onClose();
|
||||
setIsDeleteLoading(false);
|
||||
@ -82,12 +80,7 @@ export const DeleteStateModal: React.FC<Props> = ({ isOpen, onClose, data }) =>
|
||||
|
||||
return (
|
||||
<Transition.Root show={isOpen} as={React.Fragment}>
|
||||
<Dialog
|
||||
as="div"
|
||||
className="relative z-20"
|
||||
initialFocus={cancelButtonRef}
|
||||
onClose={handleClose}
|
||||
>
|
||||
<Dialog as="div" className="relative z-20" onClose={handleClose}>
|
||||
<Transition.Child
|
||||
as={React.Fragment}
|
||||
enter="ease-out duration-300"
|
||||
@ -143,25 +136,14 @@ export const DeleteStateModal: React.FC<Props> = ({ isOpen, onClose, data }) =>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="bg-gray-50 px-4 py-3 sm:flex sm:flex-row-reverse sm:px-6">
|
||||
<Button
|
||||
type="button"
|
||||
<div className="flex justify-end gap-2 bg-gray-50 p-4 sm:px-6">
|
||||
<SecondaryButton onClick={handleClose}>Cancel</SecondaryButton>
|
||||
<DangerButton
|
||||
onClick={handleDeletion}
|
||||
theme="danger"
|
||||
disabled={isDeleteLoading || issuesWithThisStateExist}
|
||||
className="inline-flex sm:ml-3"
|
||||
loading={isDeleteLoading || issuesWithThisStateExist}
|
||||
>
|
||||
{isDeleteLoading ? "Deleting..." : "Delete"}
|
||||
</Button>
|
||||
<Button
|
||||
type="button"
|
||||
theme="secondary"
|
||||
className="inline-flex sm:ml-3"
|
||||
onClick={handleClose}
|
||||
ref={cancelButtonRef}
|
||||
>
|
||||
Cancel
|
||||
</Button>
|
||||
</DangerButton>
|
||||
</div>
|
||||
</Dialog.Panel>
|
||||
</Transition.Child>
|
||||
|
@ -1,62 +0,0 @@
|
||||
import * as React from "react";
|
||||
|
||||
type ButtonProps = {
|
||||
onClick?: () => void;
|
||||
children: React.ReactNode;
|
||||
type?: "button" | "submit" | "reset";
|
||||
className?: string;
|
||||
theme?: "primary" | "secondary" | "success" | "danger";
|
||||
size?: "sm" | "rg" | "md" | "lg";
|
||||
disabled?: boolean;
|
||||
largePadding?: boolean;
|
||||
};
|
||||
|
||||
export const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(
|
||||
(
|
||||
{
|
||||
children,
|
||||
onClick,
|
||||
type = "button",
|
||||
size = "sm",
|
||||
className = "",
|
||||
theme = "primary",
|
||||
disabled = false,
|
||||
largePadding,
|
||||
},
|
||||
ref
|
||||
) => (
|
||||
<button
|
||||
ref={ref}
|
||||
onClick={onClick}
|
||||
type={type}
|
||||
disabled={disabled}
|
||||
className={`inline-flex items-center justify-center rounded font-medium duration-300 ${
|
||||
theme === "primary"
|
||||
? `${
|
||||
disabled ? "opacity-70" : ""
|
||||
} border border-transparent bg-gray-200 shadow-sm hover:bg-gray-300 focus:outline-none`
|
||||
: theme === "secondary"
|
||||
? "border border-gray-300 bg-transparent hover:bg-gray-200"
|
||||
: theme === "success"
|
||||
? `${
|
||||
disabled ? "opacity-70" : ""
|
||||
} border border-transparent bg-green-500 text-white shadow-sm hover:bg-green-600 focus:outline-none focus:ring-2 focus:ring-green-500`
|
||||
: `${
|
||||
disabled ? "opacity-70" : ""
|
||||
} border border-transparent bg-red-500 text-white shadow-sm hover:bg-red-600 focus:outline-none focus:ring-2 focus:ring-red-500`
|
||||
} ${
|
||||
size === "sm"
|
||||
? "p-2 text-xs"
|
||||
: size === "md"
|
||||
? "text-md px-3 py-2"
|
||||
: size === "lg"
|
||||
? "text-md px-4 py-2"
|
||||
: "px-2.5 py-2 text-sm"
|
||||
} ${largePadding ? "px-8" : ""} ${className}`}
|
||||
>
|
||||
{children}
|
||||
</button>
|
||||
)
|
||||
);
|
||||
|
||||
Button.displayName = "Button";
|
@ -1 +0,0 @@
|
||||
export * from "./primary-button";
|
@ -1,32 +0,0 @@
|
||||
type TButtonProps = {
|
||||
children: React.ReactNode;
|
||||
className?: string;
|
||||
onClick?: () => void;
|
||||
type?: "button" | "submit" | "reset";
|
||||
disabled?: boolean;
|
||||
loading?: boolean;
|
||||
size?: "sm" | "md" | "lg";
|
||||
};
|
||||
|
||||
export const PrimaryButton: React.FC<TButtonProps> = (props) => {
|
||||
const { children, className, onClick, type, disabled, loading, size = "md" } = props;
|
||||
|
||||
return (
|
||||
<button
|
||||
type={type}
|
||||
className={`hover:bg-opacity-90 transition-colors text-white rounded-lg ${
|
||||
size === "sm"
|
||||
? "px-2.5 py-1.5 text-sm"
|
||||
: size === "md"
|
||||
? "px-3 py-2 text-base"
|
||||
: "px-4 py-3 text-lg"
|
||||
} ${disabled ? "bg-gray-400 cursor-not-allowed" : "bg-theme"} ${className || ""} ${
|
||||
loading ? "cursor-wait" : ""
|
||||
}`}
|
||||
onClick={onClick}
|
||||
disabled={disabled || loading}
|
||||
>
|
||||
<div className="flex items-center">{children}</div>
|
||||
</button>
|
||||
);
|
||||
};
|
36
apps/app/components/ui/buttons/danger-button.tsx
Normal file
36
apps/app/components/ui/buttons/danger-button.tsx
Normal file
@ -0,0 +1,36 @@
|
||||
// types
|
||||
import { ButtonProps } from "./type";
|
||||
|
||||
export const DangerButton: React.FC<ButtonProps> = ({
|
||||
children,
|
||||
className = "",
|
||||
onClick,
|
||||
type = "button",
|
||||
disabled = false,
|
||||
loading = false,
|
||||
size = "sm",
|
||||
outline = false,
|
||||
}) => (
|
||||
<button
|
||||
type={type}
|
||||
className={`${className} border border-red-500 font-medium duration-300 ${
|
||||
size === "sm"
|
||||
? "rounded px-3 py-2 text-xs"
|
||||
: size === "md"
|
||||
? "rounded-md px-3.5 py-2 text-sm"
|
||||
: "rounded-lg px-4 py-2 text-base"
|
||||
} ${
|
||||
disabled
|
||||
? "cursor-not-allowed border-gray-300 bg-gray-300 text-black hover:border-gray-300 hover:border-opacity-100 hover:bg-gray-300 hover:bg-opacity-100 hover:text-black"
|
||||
: ""
|
||||
} ${
|
||||
outline
|
||||
? "bg-transparent hover:bg-red-500 hover:text-white"
|
||||
: "bg-red-500 text-white hover:border-opacity-90 hover:bg-opacity-90"
|
||||
} ${loading ? "cursor-wait" : ""}`}
|
||||
onClick={onClick}
|
||||
disabled={disabled || loading}
|
||||
>
|
||||
{children}
|
||||
</button>
|
||||
);
|
3
apps/app/components/ui/buttons/index.ts
Normal file
3
apps/app/components/ui/buttons/index.ts
Normal file
@ -0,0 +1,3 @@
|
||||
export * from "./danger-button";
|
||||
export * from "./primary-button";
|
||||
export * from "./secondary-button";
|
36
apps/app/components/ui/buttons/primary-button.tsx
Normal file
36
apps/app/components/ui/buttons/primary-button.tsx
Normal file
@ -0,0 +1,36 @@
|
||||
// types
|
||||
import { ButtonProps } from "./type";
|
||||
|
||||
export const PrimaryButton: React.FC<ButtonProps> = ({
|
||||
children,
|
||||
className = "",
|
||||
onClick,
|
||||
type = "button",
|
||||
disabled = false,
|
||||
loading = false,
|
||||
size = "sm",
|
||||
outline = false,
|
||||
}) => (
|
||||
<button
|
||||
type={type}
|
||||
className={`${className} border border-theme font-medium duration-300 ${
|
||||
size === "sm"
|
||||
? "rounded px-3 py-2 text-xs"
|
||||
: size === "md"
|
||||
? "rounded-md px-3.5 py-2 text-sm"
|
||||
: "rounded-lg px-4 py-2 text-base"
|
||||
} ${
|
||||
disabled
|
||||
? "cursor-not-allowed border-gray-300 bg-gray-300 text-black hover:border-gray-300 hover:border-opacity-100 hover:bg-gray-300 hover:bg-opacity-100 hover:text-black"
|
||||
: ""
|
||||
} ${
|
||||
outline
|
||||
? "bg-transparent hover:bg-theme hover:text-white"
|
||||
: "bg-theme text-white hover:border-opacity-90 hover:bg-opacity-90"
|
||||
} ${loading ? "cursor-wait" : ""}`}
|
||||
onClick={onClick}
|
||||
disabled={disabled || loading}
|
||||
>
|
||||
{children}
|
||||
</button>
|
||||
);
|
36
apps/app/components/ui/buttons/secondary-button.tsx
Normal file
36
apps/app/components/ui/buttons/secondary-button.tsx
Normal file
@ -0,0 +1,36 @@
|
||||
// types
|
||||
import { ButtonProps } from "./type";
|
||||
|
||||
export const SecondaryButton: React.FC<ButtonProps> = ({
|
||||
children,
|
||||
className = "",
|
||||
onClick,
|
||||
type = "button",
|
||||
disabled = false,
|
||||
loading = false,
|
||||
size = "sm",
|
||||
outline = false,
|
||||
}) => (
|
||||
<button
|
||||
type={type}
|
||||
className={`${className} border border-gray-300 font-medium duration-300 ${
|
||||
size === "sm"
|
||||
? "rounded px-3 py-2 text-xs"
|
||||
: size === "md"
|
||||
? "rounded-md px-3.5 py-2 text-sm"
|
||||
: "rounded-lg px-4 py-2 text-base"
|
||||
} ${
|
||||
disabled
|
||||
? "cursor-not-allowed border-gray-300 bg-gray-300 hover:border-gray-300 hover:border-opacity-100 hover:bg-gray-300 hover:bg-opacity-100"
|
||||
: ""
|
||||
} ${
|
||||
outline
|
||||
? "bg-transparent hover:bg-gray-300"
|
||||
: "bg-gray-300 hover:border-opacity-90 hover:bg-opacity-90"
|
||||
} ${loading ? "cursor-wait" : ""}`}
|
||||
onClick={onClick}
|
||||
disabled={disabled || loading}
|
||||
>
|
||||
{children}
|
||||
</button>
|
||||
);
|
10
apps/app/components/ui/buttons/type.d.ts
vendored
Normal file
10
apps/app/components/ui/buttons/type.d.ts
vendored
Normal file
@ -0,0 +1,10 @@
|
||||
export type ButtonProps = {
|
||||
children: React.ReactNode;
|
||||
className?: string;
|
||||
onClick?: () => void;
|
||||
type?: "button" | "submit" | "reset";
|
||||
disabled?: boolean;
|
||||
loading?: boolean;
|
||||
size?: "sm" | "md" | "lg";
|
||||
outline?: boolean;
|
||||
};
|
@ -1,7 +1,7 @@
|
||||
export * from "./buttons";
|
||||
export * from "./input";
|
||||
export * from "./text-area";
|
||||
export * from "./avatar";
|
||||
export * from "./button";
|
||||
export * from "./context-menu";
|
||||
export * from "./custom-menu";
|
||||
export * from "./custom-search-select";
|
||||
|
@ -11,7 +11,7 @@ import viewsService from "services/views.service";
|
||||
// hooks
|
||||
import useToast from "hooks/use-toast";
|
||||
// ui
|
||||
import { Button } from "components/ui";
|
||||
import { DangerButton, SecondaryButton } from "components/ui";
|
||||
// icons
|
||||
import { ExclamationTriangleIcon } from "@heroicons/react/24/outline";
|
||||
// types
|
||||
@ -34,8 +34,6 @@ export const DeleteViewModal: React.FC<Props> = ({ isOpen, data, onClose, onSucc
|
||||
|
||||
const { setToastAlert } = useToast();
|
||||
|
||||
const cancelButtonRef = useRef(null);
|
||||
|
||||
const handleClose = () => {
|
||||
setIsDeleteLoading(false);
|
||||
onClose();
|
||||
@ -74,12 +72,7 @@ export const DeleteViewModal: React.FC<Props> = ({ isOpen, data, onClose, onSucc
|
||||
|
||||
return (
|
||||
<Transition.Root show={isOpen} as={React.Fragment}>
|
||||
<Dialog
|
||||
as="div"
|
||||
className="relative z-20"
|
||||
initialFocus={cancelButtonRef}
|
||||
onClose={handleClose}
|
||||
>
|
||||
<Dialog as="div" className="relative z-20" onClose={handleClose}>
|
||||
<Transition.Child
|
||||
as={React.Fragment}
|
||||
enter="ease-out duration-300"
|
||||
@ -127,25 +120,11 @@ export const DeleteViewModal: React.FC<Props> = ({ isOpen, data, onClose, onSucc
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="bg-gray-50 px-4 py-3 sm:flex sm:flex-row-reverse sm:px-6">
|
||||
<Button
|
||||
type="button"
|
||||
onClick={handleDeletion}
|
||||
theme="danger"
|
||||
disabled={isDeleteLoading}
|
||||
className="inline-flex sm:ml-3"
|
||||
>
|
||||
<div className="flex justify-end gap-2 bg-gray-50 p-4 sm:px-6">
|
||||
<SecondaryButton onClick={handleClose}>Cancel</SecondaryButton>
|
||||
<DangerButton onClick={handleDeletion} loading={isDeleteLoading}>
|
||||
{isDeleteLoading ? "Deleting..." : "Delete"}
|
||||
</Button>
|
||||
<Button
|
||||
type="button"
|
||||
theme="secondary"
|
||||
className="inline-flex sm:ml-3"
|
||||
onClick={handleClose}
|
||||
ref={cancelButtonRef}
|
||||
>
|
||||
Cancel
|
||||
</Button>
|
||||
</DangerButton>
|
||||
</div>
|
||||
</Dialog.Panel>
|
||||
</Transition.Child>
|
||||
|
@ -3,7 +3,7 @@ import { useEffect } from "react";
|
||||
// react-hook-form
|
||||
import { useForm } from "react-hook-form";
|
||||
// ui
|
||||
import { Button, Input, TextArea } from "components/ui";
|
||||
import { Input, PrimaryButton, SecondaryButton, TextArea } from "components/ui";
|
||||
// types
|
||||
import { IView } from "types";
|
||||
|
||||
@ -97,10 +97,8 @@ export const ViewForm: React.FC<Props> = ({
|
||||
</div>
|
||||
</div>
|
||||
<div className="mt-5 flex justify-end gap-2">
|
||||
<Button theme="secondary" onClick={handleClose}>
|
||||
Cancel
|
||||
</Button>
|
||||
<Button type="submit" disabled={isSubmitting}>
|
||||
<SecondaryButton onClick={handleClose}>Cancel</SecondaryButton>
|
||||
<PrimaryButton type="submit" loading={isSubmitting}>
|
||||
{status
|
||||
? isSubmitting
|
||||
? "Updating View..."
|
||||
@ -108,7 +106,7 @@ export const ViewForm: React.FC<Props> = ({
|
||||
: isSubmitting
|
||||
? "Creating View..."
|
||||
: "Create View"}
|
||||
</Button>
|
||||
</PrimaryButton>
|
||||
</div>
|
||||
</form>
|
||||
);
|
||||
|
@ -1,10 +1,10 @@
|
||||
import React, { useRef, useState } from "react";
|
||||
import React, { useState } from "react";
|
||||
// headless ui
|
||||
import { Dialog, Transition } from "@headlessui/react";
|
||||
// icons
|
||||
import { ExclamationTriangleIcon } from "@heroicons/react/24/outline";
|
||||
// ui
|
||||
import { Button } from "components/ui";
|
||||
import { DangerButton, SecondaryButton } from "components/ui";
|
||||
|
||||
type Props = {
|
||||
isOpen: boolean;
|
||||
@ -16,8 +16,6 @@ type Props = {
|
||||
const ConfirmWorkspaceMemberRemove: React.FC<Props> = ({ isOpen, onClose, data, handleDelete }) => {
|
||||
const [isDeleteLoading, setIsDeleteLoading] = useState(false);
|
||||
|
||||
const cancelButtonRef = useRef(null);
|
||||
|
||||
const handleClose = () => {
|
||||
onClose();
|
||||
setIsDeleteLoading(false);
|
||||
@ -31,12 +29,7 @@ const ConfirmWorkspaceMemberRemove: React.FC<Props> = ({ isOpen, onClose, data,
|
||||
|
||||
return (
|
||||
<Transition.Root show={isOpen} as={React.Fragment}>
|
||||
<Dialog
|
||||
as="div"
|
||||
className="relative z-20"
|
||||
initialFocus={cancelButtonRef}
|
||||
onClose={handleClose}
|
||||
>
|
||||
<Dialog as="div" className="relative z-20" onClose={handleClose}>
|
||||
<Transition.Child
|
||||
as={React.Fragment}
|
||||
enter="ease-out duration-300"
|
||||
@ -84,25 +77,11 @@ const ConfirmWorkspaceMemberRemove: React.FC<Props> = ({ isOpen, onClose, data,
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="bg-gray-50 px-4 py-3 sm:flex sm:flex-row-reverse sm:px-6">
|
||||
<Button
|
||||
type="button"
|
||||
onClick={handleDeletion}
|
||||
theme="danger"
|
||||
disabled={isDeleteLoading}
|
||||
className="inline-flex sm:ml-3"
|
||||
>
|
||||
<div className="flex justify-end gap-2 bg-gray-50 p-4 sm:px-6">
|
||||
<SecondaryButton onClick={handleClose}>Cancel</SecondaryButton>
|
||||
<DangerButton onClick={handleDeletion} loading={isDeleteLoading}>
|
||||
{isDeleteLoading ? "Removing..." : "Remove"}
|
||||
</Button>
|
||||
<Button
|
||||
type="button"
|
||||
theme="secondary"
|
||||
className="inline-flex sm:ml-3"
|
||||
onClick={handleClose}
|
||||
ref={cancelButtonRef}
|
||||
>
|
||||
Cancel
|
||||
</Button>
|
||||
</DangerButton>
|
||||
</div>
|
||||
</Dialog.Panel>
|
||||
</Transition.Child>
|
||||
|
@ -1,4 +1,4 @@
|
||||
import React, { useEffect, useRef, useState } from "react";
|
||||
import React, { useEffect, useState } from "react";
|
||||
|
||||
import { useRouter } from "next/router";
|
||||
|
||||
@ -13,7 +13,7 @@ import useToast from "hooks/use-toast";
|
||||
// icons
|
||||
import { ExclamationTriangleIcon } from "@heroicons/react/24/outline";
|
||||
// ui
|
||||
import { Button, Input } from "components/ui";
|
||||
import { DangerButton, Input, SecondaryButton } from "components/ui";
|
||||
// types
|
||||
import type { IWorkspace } from "types";
|
||||
// fetch-keys
|
||||
@ -26,7 +26,6 @@ type Props = {
|
||||
};
|
||||
|
||||
export const DeleteWorkspaceModal: React.FC<Props> = ({ isOpen, data, onClose }) => {
|
||||
const cancelButtonRef = useRef(null);
|
||||
const [isDeleteLoading, setIsDeleteLoading] = useState(false);
|
||||
const [confirmProjectName, setConfirmProjectName] = useState("");
|
||||
const [confirmDeleteMyProject, setConfirmDeleteMyProject] = useState(false);
|
||||
@ -77,12 +76,7 @@ export const DeleteWorkspaceModal: React.FC<Props> = ({ isOpen, data, onClose })
|
||||
|
||||
return (
|
||||
<Transition.Root show={isOpen} as={React.Fragment}>
|
||||
<Dialog
|
||||
as="div"
|
||||
className="relative z-20"
|
||||
initialFocus={cancelButtonRef}
|
||||
onClose={handleClose}
|
||||
>
|
||||
<Dialog as="div" className="relative z-20" onClose={handleClose}>
|
||||
<Transition.Child
|
||||
as={React.Fragment}
|
||||
enter="ease-out duration-300"
|
||||
@ -166,25 +160,11 @@ export const DeleteWorkspaceModal: React.FC<Props> = ({ isOpen, data, onClose })
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="bg-gray-50 px-4 py-3 sm:flex sm:flex-row-reverse sm:px-6">
|
||||
<Button
|
||||
type="button"
|
||||
onClick={handleDeletion}
|
||||
theme="danger"
|
||||
disabled={isDeleteLoading || !canDelete}
|
||||
className="inline-flex sm:ml-3"
|
||||
>
|
||||
<div className="flex justify-end gap-2 bg-gray-50 p-4 sm:px-6">
|
||||
<SecondaryButton onClick={handleClose}>Cancel</SecondaryButton>
|
||||
<DangerButton onClick={handleDeletion} loading={isDeleteLoading || !canDelete}>
|
||||
{isDeleteLoading ? "Deleting..." : "Delete"}
|
||||
</Button>
|
||||
<Button
|
||||
type="button"
|
||||
theme="secondary"
|
||||
className="inline-flex sm:ml-3"
|
||||
onClick={handleClose}
|
||||
ref={cancelButtonRef}
|
||||
>
|
||||
Cancel
|
||||
</Button>
|
||||
</DangerButton>
|
||||
</div>
|
||||
</Dialog.Panel>
|
||||
</Transition.Child>
|
||||
|
@ -6,7 +6,7 @@ import { Dialog, Transition } from "@headlessui/react";
|
||||
// services
|
||||
import workspaceService from "services/workspace.service";
|
||||
// ui
|
||||
import { Button, CustomSelect, Input } from "components/ui";
|
||||
import { CustomSelect, Input, PrimaryButton, SecondaryButton } from "components/ui";
|
||||
// hooks
|
||||
import useToast from "hooks/use-toast";
|
||||
// types
|
||||
@ -153,12 +153,10 @@ const SendWorkspaceInvitationModal: React.FC<Props> = ({
|
||||
</div>
|
||||
</div>
|
||||
<div className="mt-5 flex justify-end gap-2">
|
||||
<Button theme="secondary" onClick={handleClose}>
|
||||
Cancel
|
||||
</Button>
|
||||
<Button type="submit" disabled={isSubmitting}>
|
||||
<SecondaryButton onClick={handleClose}>Cancel</SecondaryButton>
|
||||
<PrimaryButton type="submit" loading={isSubmitting}>
|
||||
{isSubmitting ? "Sending Invitation..." : "Send Invitation"}
|
||||
</Button>
|
||||
</PrimaryButton>
|
||||
</div>
|
||||
</form>
|
||||
</Dialog.Panel>
|
||||
|
@ -1,5 +1,3 @@
|
||||
// ui
|
||||
import { Button } from "components/ui";
|
||||
// icons
|
||||
import { Bars3Icon } from "@heroicons/react/24/outline";
|
||||
|
||||
@ -14,14 +12,13 @@ const Header: React.FC<Props> = ({ breadcrumbs, left, right, setToggleSidebar })
|
||||
<div className="flex w-full flex-row items-center justify-between gap-y-4 border-b bg-white px-5 py-4 ">
|
||||
<div className="flex items-center gap-2">
|
||||
<div className="block md:hidden">
|
||||
<Button
|
||||
<button
|
||||
type="button"
|
||||
theme="secondary"
|
||||
className="h-8 w-8"
|
||||
className="grid h-8 w-8 place-items-center rounded border border-gray-300"
|
||||
onClick={() => setToggleSidebar((prevData) => !prevData)}
|
||||
>
|
||||
<Bars3Icon className="h-5 w-5" />
|
||||
</Button>
|
||||
</button>
|
||||
</div>
|
||||
{breadcrumbs}
|
||||
{left}
|
||||
|
@ -10,7 +10,7 @@ import projectService from "services/project.service";
|
||||
// hooks
|
||||
import useUser from "hooks/use-user";
|
||||
// ui
|
||||
import { Button, Spinner } from "components/ui";
|
||||
import { SecondaryButton, Spinner } from "components/ui";
|
||||
// components
|
||||
import { NotAuthorizedView } from "components/core";
|
||||
import { CommandPalette } from "components/command-palette";
|
||||
@ -103,17 +103,13 @@ const AppLayout: FC<AppLayoutProps> = ({
|
||||
actionButton={
|
||||
(memberType?.isViewer || memberType?.isGuest) && projectId ? (
|
||||
<Link href={`/${workspaceSlug}/projects/${projectId}/issues`}>
|
||||
<Button size="sm" theme="secondary">
|
||||
Go to Issues
|
||||
</Button>
|
||||
<SecondaryButton>Go to Issues</SecondaryButton>
|
||||
</Link>
|
||||
) : (
|
||||
(memberType?.isViewer || memberType?.isGuest) &&
|
||||
workspaceSlug && (
|
||||
<Link href={`/${workspaceSlug}`}>
|
||||
<Button size="sm" theme="secondary">
|
||||
Go to workspace
|
||||
</Button>
|
||||
<SecondaryButton>Go to workspace</SecondaryButton>
|
||||
</Link>
|
||||
)
|
||||
)
|
||||
|
@ -6,7 +6,7 @@ import Image from "next/image";
|
||||
// layouts
|
||||
import DefaultLayout from "layouts/default-layout";
|
||||
// ui
|
||||
import { Button } from "components/ui";
|
||||
import { SecondaryButton } from "components/ui";
|
||||
// images
|
||||
import Image404 from "public/404.svg";
|
||||
// types
|
||||
@ -33,9 +33,7 @@ const PageNotFound: NextPage = () => (
|
||||
</div>
|
||||
<Link href="/">
|
||||
<a className="block">
|
||||
<Button type="button" largePadding>
|
||||
Go to Home
|
||||
</Button>
|
||||
<SecondaryButton size="md">Go to Home</SecondaryButton>
|
||||
</a>
|
||||
</Link>
|
||||
</div>
|
||||
|
@ -18,7 +18,7 @@ import AppLayout from "layouts/app-layout";
|
||||
// components
|
||||
import { ImageUploadModal } from "components/core";
|
||||
// ui
|
||||
import { Button, Input, Spinner } from "components/ui";
|
||||
import { DangerButton, Input, SecondaryButton, Spinner } from "components/ui";
|
||||
import { BreadcrumbItem, Breadcrumbs } from "components/breadcrumbs";
|
||||
// icons
|
||||
import {
|
||||
@ -205,24 +205,17 @@ const Profile: NextPage = () => {
|
||||
<br />
|
||||
Supported file types are .jpg and .png.
|
||||
</p>
|
||||
<div className="flex items-center gap-2">
|
||||
<Button
|
||||
type="button"
|
||||
className="mt-4"
|
||||
onClick={() => setIsImageUploadModalOpen(true)}
|
||||
>
|
||||
<div className="mt-4 flex items-center gap-2">
|
||||
<SecondaryButton onClick={() => setIsImageUploadModalOpen(true)}>
|
||||
Upload new
|
||||
</Button>
|
||||
</SecondaryButton>
|
||||
{myProfile.avatar && myProfile.avatar !== "" && (
|
||||
<Button
|
||||
type="button"
|
||||
className="mt-4"
|
||||
theme="danger"
|
||||
<DangerButton
|
||||
onClick={() => handleDelete(myProfile.avatar, true)}
|
||||
disabled={isRemoving}
|
||||
loading={isRemoving}
|
||||
>
|
||||
{isRemoving ? "Removing..." : "Remove"}
|
||||
</Button>
|
||||
</DangerButton>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
@ -269,9 +262,9 @@ const Profile: NextPage = () => {
|
||||
</div>
|
||||
{isEditing && (
|
||||
<div>
|
||||
<Button type="submit" disabled={isSubmitting}>
|
||||
<SecondaryButton type="submit" loading={isSubmitting}>
|
||||
{isSubmitting ? "Updating Profile..." : "Update Profile"}
|
||||
</Button>
|
||||
</SecondaryButton>
|
||||
</div>
|
||||
)}
|
||||
</form>
|
||||
|
@ -16,7 +16,7 @@ import workspaceService from "services/workspace.service";
|
||||
// hooks
|
||||
import useToast from "hooks/use-toast";
|
||||
// ui
|
||||
import { Button, CustomSelect, Loader } from "components/ui";
|
||||
import { CustomSelect, Loader, SecondaryButton } from "components/ui";
|
||||
import { BreadcrumbItem, Breadcrumbs } from "components/breadcrumbs";
|
||||
// types
|
||||
import { IProject, IWorkspace } from "types";
|
||||
@ -239,9 +239,9 @@ const ControlSettings: NextPage<TControlSettingsProps> = (props) => {
|
||||
</div>
|
||||
</div>
|
||||
<div className="sm:text-right">
|
||||
<Button type="submit" disabled={isSubmitting}>
|
||||
<SecondaryButton type="submit" loading={isSubmitting}>
|
||||
{isSubmitting ? "Updating Project..." : "Update Project"}
|
||||
</Button>
|
||||
</SecondaryButton>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
|
@ -13,14 +13,15 @@ import AppLayout from "layouts/app-layout";
|
||||
// hooks
|
||||
import useToast from "hooks/use-toast";
|
||||
// ui
|
||||
import { Button } from "components/ui";
|
||||
import { SecondaryButton } from "components/ui";
|
||||
import { BreadcrumbItem, Breadcrumbs } from "components/breadcrumbs";
|
||||
// icons
|
||||
import { ContrastIcon, PeopleGroupIcon, ViewListIcon } from "components/icons";
|
||||
// types
|
||||
import { IProject, UserAuth } from "types";
|
||||
import type { NextPage, GetServerSidePropsContext } from "next";
|
||||
// fetch-keys
|
||||
import { PROJECTS_LIST, PROJECT_DETAILS } from "constants/fetch-keys";
|
||||
import { ContrastIcon, PeopleGroupIcon, ViewListIcon } from "components/icons";
|
||||
|
||||
const FeaturesSettings: NextPage<UserAuth> = (props) => {
|
||||
const router = useRouter();
|
||||
@ -183,14 +184,10 @@ const FeaturesSettings: NextPage<UserAuth> = (props) => {
|
||||
</div>
|
||||
<div className="flex items-center gap-2">
|
||||
<a href="https://plane.so/" target="_blank" rel="noreferrer">
|
||||
<Button theme="secondary" size="rg" className="text-xs">
|
||||
Plane is open-source, view Roadmap
|
||||
</Button>
|
||||
<SecondaryButton outline>Plane is open-source, view Roadmap</SecondaryButton>
|
||||
</a>
|
||||
<a href="https://github.com/makeplane/plane" target="_blank" rel="noreferrer">
|
||||
<Button theme="secondary" size="rg" className="text-xs">
|
||||
Star us on GitHub
|
||||
</Button>
|
||||
<SecondaryButton outline>Star us on GitHub</SecondaryButton>
|
||||
</a>
|
||||
</div>
|
||||
</section>
|
||||
|
@ -20,7 +20,14 @@ import EmojiIconPicker from "components/emoji-icon-picker";
|
||||
// hooks
|
||||
import useToast from "hooks/use-toast";
|
||||
// ui
|
||||
import { Button, Input, TextArea, Loader, CustomSelect, OutlineButton } from "components/ui";
|
||||
import {
|
||||
Input,
|
||||
TextArea,
|
||||
Loader,
|
||||
CustomSelect,
|
||||
OutlineButton,
|
||||
SecondaryButton,
|
||||
} from "components/ui";
|
||||
import { BreadcrumbItem, Breadcrumbs } from "components/breadcrumbs";
|
||||
// helpers
|
||||
import { debounce } from "helpers/common.helper";
|
||||
@ -30,7 +37,6 @@ import type { NextPage, GetServerSidePropsContext } from "next";
|
||||
import { PROJECTS_LIST, PROJECT_DETAILS, WORKSPACE_DETAILS } from "constants/fetch-keys";
|
||||
// constants
|
||||
import { NETWORK_CHOICES } from "constants/project";
|
||||
import SettingsNavbar from "layouts/settings-navbar";
|
||||
|
||||
const defaultValues: Partial<IProject> = {
|
||||
name: "",
|
||||
@ -288,9 +294,9 @@ const GeneralSettings: NextPage<UserAuth> = (props) => {
|
||||
</div>
|
||||
<div className="sm:text-right">
|
||||
{projectDetails ? (
|
||||
<Button type="submit" disabled={isSubmitting}>
|
||||
<SecondaryButton type="submit" loading={isSubmitting}>
|
||||
{isSubmitting ? "Updating Project..." : "Update Project"}
|
||||
</Button>
|
||||
</SecondaryButton>
|
||||
) : (
|
||||
<Loader className="mt-2 w-full">
|
||||
<Loader.Item height="34px" width="100px" light />
|
||||
|
@ -19,7 +19,7 @@ import {
|
||||
SingleLabelGroup,
|
||||
} from "components/labels";
|
||||
// ui
|
||||
import { Loader } from "components/ui";
|
||||
import { Loader, PrimaryButton } from "components/ui";
|
||||
import { BreadcrumbItem, Breadcrumbs } from "components/breadcrumbs";
|
||||
// icons
|
||||
import { PlusIcon } from "@heroicons/react/24/outline";
|
||||
@ -28,7 +28,6 @@ import { IIssueLabels, UserAuth } from "types";
|
||||
import type { GetServerSidePropsContext, NextPage } from "next";
|
||||
// fetch-keys
|
||||
import { PROJECT_DETAILS, PROJECT_ISSUE_LABELS } from "constants/fetch-keys";
|
||||
import { PrimaryButton } from "components/ui/button/primary-button";
|
||||
|
||||
const LabelsSettings: NextPage<UserAuth> = (props) => {
|
||||
const { isMember, isOwner, isViewer, isGuest } = props;
|
||||
|
@ -11,7 +11,7 @@ import workspaceService from "services/workspace.service";
|
||||
// layouts
|
||||
import AppLayout from "layouts/app-layout";
|
||||
// ui
|
||||
import { Button } from "components/ui";
|
||||
import { SecondaryButton } from "components/ui";
|
||||
import { BreadcrumbItem, Breadcrumbs } from "components/breadcrumbs";
|
||||
// types
|
||||
import type { NextPage, GetServerSideProps } from "next";
|
||||
@ -66,9 +66,7 @@ const BillingSettings: NextPage<TBillingSettingsProps> = (props) => {
|
||||
<h4 className="text-md mb-1 leading-6 text-gray-900">Current plan</h4>
|
||||
<p className="mb-3 text-sm text-gray-500">You are currently using the free plan</p>
|
||||
<a href="https://plane.so/pricing" target="_blank" rel="noreferrer">
|
||||
<Button theme="secondary" size="rg" className="text-xs">
|
||||
View Plans and Upgrade
|
||||
</Button>
|
||||
<SecondaryButton outline>View Plans and Upgrade</SecondaryButton>
|
||||
</a>
|
||||
</div>
|
||||
<div>
|
||||
|
@ -23,7 +23,7 @@ import AppLayout from "layouts/app-layout";
|
||||
import { ImageUploadModal } from "components/core";
|
||||
import { DeleteWorkspaceModal } from "components/workspace";
|
||||
// ui
|
||||
import { Spinner, Button, Input, CustomSelect, OutlineButton } from "components/ui";
|
||||
import { Spinner, Input, CustomSelect, OutlineButton, SecondaryButton } from "components/ui";
|
||||
import { BreadcrumbItem, Breadcrumbs } from "components/breadcrumbs";
|
||||
// helpers
|
||||
import { copyTextToClipboard } from "helpers/string.helper";
|
||||
@ -168,13 +168,13 @@ const WorkspaceSettings: NextPage<UserAuth> = (props) => {
|
||||
)}
|
||||
</button>
|
||||
<div>
|
||||
<Button
|
||||
<SecondaryButton
|
||||
onClick={() => {
|
||||
setIsImageUploadModalOpen(true);
|
||||
}}
|
||||
>
|
||||
{isImageUploading ? "Uploading..." : "Upload"}
|
||||
</Button>
|
||||
</SecondaryButton>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -195,9 +195,7 @@ const WorkspaceSettings: NextPage<UserAuth> = (props) => {
|
||||
value={`app.plane.so/${activeWorkspace.slug}`}
|
||||
disabled
|
||||
/>
|
||||
<Button
|
||||
type="button"
|
||||
theme="secondary"
|
||||
<SecondaryButton
|
||||
className="h-min"
|
||||
onClick={() =>
|
||||
copyTextToClipboard(`https://app.plane.so/${activeWorkspace.slug}`).then(() => {
|
||||
@ -208,9 +206,10 @@ const WorkspaceSettings: NextPage<UserAuth> = (props) => {
|
||||
});
|
||||
})
|
||||
}
|
||||
outline
|
||||
>
|
||||
<LinkIcon className="h-[18px] w-[18px]" />
|
||||
</Button>
|
||||
</SecondaryButton>
|
||||
</div>
|
||||
</div>
|
||||
<div className="grid grid-cols-12 gap-4 sm:gap-16">
|
||||
@ -259,9 +258,9 @@ const WorkspaceSettings: NextPage<UserAuth> = (props) => {
|
||||
</div>
|
||||
</div>
|
||||
<div className="sm:text-right">
|
||||
<Button onClick={handleSubmit(onSubmit)} disabled={isSubmitting}>
|
||||
<SecondaryButton onClick={handleSubmit(onSubmit)} loading={isSubmitting}>
|
||||
{isSubmitting ? "Updating..." : "Update Workspace"}
|
||||
</Button>
|
||||
</SecondaryButton>
|
||||
</div>
|
||||
<div className="grid grid-cols-12 gap-4 sm:gap-16">
|
||||
<div className="col-span-12 sm:col-span-6">
|
||||
|
@ -15,7 +15,7 @@ import DefaultLayout from "layouts/default-layout";
|
||||
// components
|
||||
import SingleInvitation from "components/workspace/single-invitation";
|
||||
// ui
|
||||
import { Button, Spinner, EmptySpace, EmptySpaceItem } from "components/ui";
|
||||
import { Spinner, EmptySpace, EmptySpaceItem, SecondaryButton, PrimaryButton } from "components/ui";
|
||||
// icons
|
||||
import { CubeIcon, PlusIcon } from "@heroicons/react/24/outline";
|
||||
// types
|
||||
@ -112,14 +112,12 @@ const OnBoard: NextPage = () => {
|
||||
<div className="mt-6 flex items-center gap-2">
|
||||
<Link href="/">
|
||||
<a className="w-full">
|
||||
<Button className="w-full" theme="secondary">
|
||||
Go to Home
|
||||
</Button>
|
||||
<SecondaryButton className="w-full">Go to Home</SecondaryButton>
|
||||
</a>
|
||||
</Link>
|
||||
<Button className="w-full" onClick={submitInvitations}>
|
||||
<PrimaryButton className="w-full" onClick={submitInvitations}>
|
||||
Accept and Continue
|
||||
</Button>
|
||||
</PrimaryButton>
|
||||
</div>
|
||||
</div>
|
||||
) : workspaces && workspaces.length > 0 ? (
|
||||
|
Loading…
Reference in New Issue
Block a user