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