mirror of
https://github.com/makeplane/plane
synced 2024-06-14 14:31:34 +00:00
fix: modules mutation, updated dummy content (#165)
* fix: modules mutation, updated dummy content * fix: 404 page * feat: added plausible script * feat: added plausible to doc
This commit is contained in:
parent
1b7fb358fc
commit
9737b80dcb
@ -4,13 +4,13 @@ import { useState } from "react";
|
|||||||
import SingleStat from "components/project/cycles/stats-view/single-stat";
|
import SingleStat from "components/project/cycles/stats-view/single-stat";
|
||||||
import ConfirmCycleDeletion from "components/project/cycles/confirm-cycle-deletion";
|
import ConfirmCycleDeletion from "components/project/cycles/confirm-cycle-deletion";
|
||||||
// types
|
// types
|
||||||
import { ICycle, SelectSprintType } from "types";
|
import { ICycle, SelectCycleType } from "types";
|
||||||
import { CompletedCycleIcon, CurrentCycleIcon, UpcomingCycleIcon } from "ui/icons";
|
import { CompletedCycleIcon, CurrentCycleIcon, UpcomingCycleIcon } from "ui/icons";
|
||||||
|
|
||||||
type TCycleStatsViewProps = {
|
type TCycleStatsViewProps = {
|
||||||
cycles: ICycle[];
|
cycles: ICycle[];
|
||||||
setCreateUpdateCycleModal: React.Dispatch<React.SetStateAction<boolean>>;
|
setCreateUpdateCycleModal: React.Dispatch<React.SetStateAction<boolean>>;
|
||||||
setSelectedCycle: React.Dispatch<React.SetStateAction<SelectSprintType>>;
|
setSelectedCycle: React.Dispatch<React.SetStateAction<SelectCycleType>>;
|
||||||
type: "current" | "upcoming" | "completed";
|
type: "current" | "upcoming" | "completed";
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -21,7 +21,7 @@ const CycleStatsView: React.FC<TCycleStatsViewProps> = ({
|
|||||||
type,
|
type,
|
||||||
}) => {
|
}) => {
|
||||||
const [cycleDeleteModal, setCycleDeleteModal] = useState(false);
|
const [cycleDeleteModal, setCycleDeleteModal] = useState(false);
|
||||||
const [selectedCycleForDelete, setSelectedCycleForDelete] = useState<SelectSprintType>();
|
const [selectedCycleForDelete, setSelectedCycleForDelete] = useState<SelectCycleType>();
|
||||||
|
|
||||||
const handleDeleteCycle = (cycle: ICycle) => {
|
const handleDeleteCycle = (cycle: ICycle) => {
|
||||||
setSelectedCycleForDelete({ ...cycle, actionType: "delete" });
|
setSelectedCycleForDelete({ ...cycle, actionType: "delete" });
|
||||||
|
@ -63,7 +63,7 @@ const ConfirmModuleDeletion: React.FC<Props> = ({ isOpen, setIsOpen, data }) =>
|
|||||||
<Transition.Root show={isOpen} as={React.Fragment}>
|
<Transition.Root show={isOpen} as={React.Fragment}>
|
||||||
<Dialog
|
<Dialog
|
||||||
as="div"
|
as="div"
|
||||||
className="relative z-10"
|
className="relative z-20"
|
||||||
initialFocus={cancelButtonRef}
|
initialFocus={cancelButtonRef}
|
||||||
onClose={handleClose}
|
onClose={handleClose}
|
||||||
>
|
>
|
||||||
@ -79,7 +79,7 @@ const ConfirmModuleDeletion: React.FC<Props> = ({ isOpen, setIsOpen, data }) =>
|
|||||||
<div className="fixed inset-0 bg-gray-500 bg-opacity-75 transition-opacity" />
|
<div className="fixed inset-0 bg-gray-500 bg-opacity-75 transition-opacity" />
|
||||||
</Transition.Child>
|
</Transition.Child>
|
||||||
|
|
||||||
<div className="fixed inset-0 z-10 overflow-y-auto">
|
<div className="fixed inset-0 z-20 overflow-y-auto">
|
||||||
<div className="flex min-h-full items-end justify-center p-4 text-center sm:items-center sm:p-0">
|
<div className="flex min-h-full items-end justify-center p-4 text-center sm:items-center sm:p-0">
|
||||||
<Transition.Child
|
<Transition.Child
|
||||||
as={React.Fragment}
|
as={React.Fragment}
|
@ -7,6 +7,10 @@ import { mutate } from "swr";
|
|||||||
import { useForm } from "react-hook-form";
|
import { useForm } from "react-hook-form";
|
||||||
|
|
||||||
import { Dialog, Transition } from "@headlessui/react";
|
import { Dialog, Transition } from "@headlessui/react";
|
||||||
|
// components
|
||||||
|
import SelectLead from "components/project/modules/create-update-module-modal/select-lead";
|
||||||
|
import SelectMembers from "components/project/modules/create-update-module-modal/select-members";
|
||||||
|
import SelectStatus from "components/project/modules/create-update-module-modal/select-status";
|
||||||
// ui
|
// ui
|
||||||
import { Button, Input, TextArea } from "ui";
|
import { Button, Input, TextArea } from "ui";
|
||||||
// services
|
// services
|
||||||
@ -17,9 +21,6 @@ import type { IModule } from "types";
|
|||||||
import { renderDateFormat } from "constants/common";
|
import { renderDateFormat } from "constants/common";
|
||||||
// fetch keys
|
// fetch keys
|
||||||
import { MODULE_LIST } from "constants/fetch-keys";
|
import { MODULE_LIST } from "constants/fetch-keys";
|
||||||
import SelectLead from "./select-lead";
|
|
||||||
import SelectMembers from "./select-members";
|
|
||||||
import SelectStatus from "./select-status";
|
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
isOpen: boolean;
|
isOpen: boolean;
|
||||||
@ -51,15 +52,6 @@ const CreateUpdateModuleModal: React.FC<Props> = ({ isOpen, setIsOpen, data, pro
|
|||||||
defaultValues,
|
defaultValues,
|
||||||
});
|
});
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
if (data) {
|
|
||||||
setIsOpen(true);
|
|
||||||
reset(data);
|
|
||||||
} else {
|
|
||||||
reset(defaultValues);
|
|
||||||
}
|
|
||||||
}, [data, setIsOpen, reset]);
|
|
||||||
|
|
||||||
const onSubmit = async (formData: IModule) => {
|
const onSubmit = async (formData: IModule) => {
|
||||||
if (!workspaceSlug) return;
|
if (!workspaceSlug) return;
|
||||||
const payload = {
|
const payload = {
|
||||||
@ -71,11 +63,7 @@ const CreateUpdateModuleModal: React.FC<Props> = ({ isOpen, setIsOpen, data, pro
|
|||||||
await modulesService
|
await modulesService
|
||||||
.createModule(workspaceSlug as string, projectId, payload)
|
.createModule(workspaceSlug as string, projectId, payload)
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
mutate<IModule[]>(
|
mutate(MODULE_LIST(projectId));
|
||||||
MODULE_LIST(projectId),
|
|
||||||
(prevData) => [res, ...(prevData ?? [])],
|
|
||||||
false
|
|
||||||
);
|
|
||||||
handleClose();
|
handleClose();
|
||||||
})
|
})
|
||||||
.catch((err) => {
|
.catch((err) => {
|
||||||
@ -119,6 +107,15 @@ const CreateUpdateModuleModal: React.FC<Props> = ({ isOpen, setIsOpen, data, pro
|
|||||||
reset(defaultValues);
|
reset(defaultValues);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (data) {
|
||||||
|
setIsOpen(true);
|
||||||
|
reset(data);
|
||||||
|
} else {
|
||||||
|
reset(defaultValues);
|
||||||
|
}
|
||||||
|
}, [data, setIsOpen, reset]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Transition.Root show={isOpen} as={React.Fragment}>
|
<Transition.Root show={isOpen} as={React.Fragment}>
|
||||||
<Dialog as="div" className="relative z-20" onClose={handleClose}>
|
<Dialog as="div" className="relative z-20" onClose={handleClose}>
|
||||||
|
@ -27,13 +27,17 @@ const PageNotFound: NextPage = () => {
|
|||||||
<div className="space-y-2">
|
<div className="space-y-2">
|
||||||
<h3 className="text-lg font-semibold">Oops! Something went wrong.</h3>
|
<h3 className="text-lg font-semibold">Oops! Something went wrong.</h3>
|
||||||
<p className="text-sm text-gray-500">
|
<p className="text-sm text-gray-500">
|
||||||
Lorem ipsum dolor sit amet consectetur. Fermentum augue ipsum ipsum adipiscing tempus
|
Sorry, the page you are looking for cannot be found. It may have been removed, had its
|
||||||
diam.
|
name changed, or is temporarily unavailable.
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
<Link href="/">
|
||||||
|
<a className="block">
|
||||||
<Button type="button" largePadding>
|
<Button type="button" largePadding>
|
||||||
Go to Home
|
Go to Home
|
||||||
</Button>
|
</Button>
|
||||||
|
</a>
|
||||||
|
</Link>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</DefaultLayout>
|
</DefaultLayout>
|
||||||
|
@ -5,7 +5,7 @@ import type { NextPage, NextPageContext } from "next";
|
|||||||
|
|
||||||
import useSWR from "swr";
|
import useSWR from "swr";
|
||||||
// services
|
// services
|
||||||
import sprintService from "lib/services/cycles.service";
|
import cycleService from "lib/services/cycles.service";
|
||||||
import projectService from "lib/services/project.service";
|
import projectService from "lib/services/project.service";
|
||||||
import workspaceService from "lib/services/workspace.service";
|
import workspaceService from "lib/services/workspace.service";
|
||||||
// layouts
|
// layouts
|
||||||
@ -16,9 +16,9 @@ import CycleStatsView from "components/project/cycles/stats-view";
|
|||||||
// ui
|
// ui
|
||||||
import { BreadcrumbItem, Breadcrumbs, HeaderButton, EmptySpace, EmptySpaceItem, Loader } from "ui";
|
import { BreadcrumbItem, Breadcrumbs, HeaderButton, EmptySpace, EmptySpaceItem, Loader } from "ui";
|
||||||
// icons
|
// icons
|
||||||
import { ArrowPathIcon, PlusIcon } from "@heroicons/react/24/outline";
|
import { PlusIcon } from "@heroicons/react/24/outline";
|
||||||
// types
|
// types
|
||||||
import { ICycle, SelectSprintType } from "types";
|
import { ICycle, SelectCycleType } from "types";
|
||||||
// fetching keys
|
// fetching keys
|
||||||
import { CYCLE_LIST, PROJECT_DETAILS, WORKSPACE_DETAILS } from "constants/fetch-keys";
|
import { CYCLE_LIST, PROJECT_DETAILS, WORKSPACE_DETAILS } from "constants/fetch-keys";
|
||||||
// lib
|
// lib
|
||||||
@ -26,8 +26,8 @@ import { requiredAuth } from "lib/auth";
|
|||||||
import { Tab } from "@headlessui/react";
|
import { Tab } from "@headlessui/react";
|
||||||
import { CyclesIcon } from "ui/icons";
|
import { CyclesIcon } from "ui/icons";
|
||||||
|
|
||||||
const ProjectSprints: NextPage = () => {
|
const ProjectCycles: NextPage = () => {
|
||||||
const [selectedCycle, setSelectedCycle] = useState<SelectSprintType>();
|
const [selectedCycle, setSelectedCycle] = useState<SelectCycleType>();
|
||||||
const [createUpdateCycleModal, setCreateUpdateCycleModal] = useState(false);
|
const [createUpdateCycleModal, setCreateUpdateCycleModal] = useState(false);
|
||||||
|
|
||||||
const {
|
const {
|
||||||
@ -49,7 +49,7 @@ const ProjectSprints: NextPage = () => {
|
|||||||
const { data: cycles } = useSWR<ICycle[]>(
|
const { data: cycles } = useSWR<ICycle[]>(
|
||||||
activeWorkspace && projectId ? CYCLE_LIST(projectId as string) : null,
|
activeWorkspace && projectId ? CYCLE_LIST(projectId as string) : null,
|
||||||
activeWorkspace && projectId
|
activeWorkspace && projectId
|
||||||
? () => sprintService.getCycles(activeWorkspace.slug, projectId as string)
|
? () => cycleService.getCycles(activeWorkspace.slug, projectId as string)
|
||||||
: null
|
: null
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -224,4 +224,4 @@ export const getServerSideProps = async (ctx: NextPageContext) => {
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
export default ProjectSprints;
|
export default ProjectCycles;
|
||||||
|
@ -18,7 +18,7 @@ import ModulesBoardView from "components/project/modules/board-view";
|
|||||||
import ModulesListView from "components/project/modules/list-view";
|
import ModulesListView from "components/project/modules/list-view";
|
||||||
import ConfirmIssueDeletion from "components/project/issues/confirm-issue-deletion";
|
import ConfirmIssueDeletion from "components/project/issues/confirm-issue-deletion";
|
||||||
import ModuleDetailSidebar from "components/project/modules/module-detail-sidebar";
|
import ModuleDetailSidebar from "components/project/modules/module-detail-sidebar";
|
||||||
import ConfirmModuleDeletion from "components/project/modules/confirm-module-deleteion";
|
import ConfirmModuleDeletion from "components/project/modules/confirm-module-deletion";
|
||||||
import CreateUpdateIssuesModal from "components/project/issues/create-update-issue-modal";
|
import CreateUpdateIssuesModal from "components/project/issues/create-update-issue-modal";
|
||||||
import View from "components/core/view";
|
import View from "components/core/view";
|
||||||
// ui
|
// ui
|
||||||
@ -345,7 +345,7 @@ const SingleModule = () => {
|
|||||||
>
|
>
|
||||||
<EmptySpace
|
<EmptySpace
|
||||||
title="You don't have any issue yet."
|
title="You don't have any issue yet."
|
||||||
description="A cycle is a fixed time period where a team commits to a set number of issues from their backlog. Cycles are usually one, two, or four weeks long."
|
description="Modules are smaller, focused projects that help you group and organize issues within a specific time frame."
|
||||||
Icon={RectangleStackIcon}
|
Icon={RectangleStackIcon}
|
||||||
>
|
>
|
||||||
<EmptySpaceItem
|
<EmptySpaceItem
|
||||||
|
@ -78,7 +78,7 @@ const ProjectModules: NextPage = () => {
|
|||||||
<div className="flex h-full w-full flex-col items-center justify-center px-4">
|
<div className="flex h-full w-full flex-col items-center justify-center px-4">
|
||||||
<EmptySpace
|
<EmptySpace
|
||||||
title="You don't have any module yet."
|
title="You don't have any module yet."
|
||||||
description="A cycle is a fixed time period where a team commits to a set number of issues from their backlog. Cycles are usually one, two, or four weeks long."
|
description="Modules are smaller, focused projects that help you group and organize issues within a specific time frame."
|
||||||
Icon={RectangleGroupIcon}
|
Icon={RectangleGroupIcon}
|
||||||
>
|
>
|
||||||
<EmptySpaceItem
|
<EmptySpaceItem
|
||||||
|
@ -9,6 +9,7 @@ import { ThemeContextProvider } from "contexts/theme.context";
|
|||||||
|
|
||||||
function MyApp({ Component, pageProps }: AppProps) {
|
function MyApp({ Component, pageProps }: AppProps) {
|
||||||
return (
|
return (
|
||||||
|
<>
|
||||||
<UserProvider>
|
<UserProvider>
|
||||||
<ToastContextProvider>
|
<ToastContextProvider>
|
||||||
<ThemeContextProvider>
|
<ThemeContextProvider>
|
||||||
@ -16,6 +17,8 @@ function MyApp({ Component, pageProps }: AppProps) {
|
|||||||
</ThemeContextProvider>
|
</ThemeContextProvider>
|
||||||
</ToastContextProvider>
|
</ToastContextProvider>
|
||||||
</UserProvider>
|
</UserProvider>
|
||||||
|
<script defer data-domain="app.plane.so" src="https://plausible.io/js/script.js"></script>
|
||||||
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
2
apps/app/types/cycles.d.ts
vendored
2
apps/app/types/cycles.d.ts
vendored
@ -30,7 +30,7 @@ export interface CycleIssueResponse {
|
|||||||
cycle: string;
|
cycle: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export type SelectSprintType =
|
export type SelectCycleType =
|
||||||
| (ICycle & { actionType: "edit" | "delete" | "create-issue" })
|
| (ICycle & { actionType: "edit" | "delete" | "create-issue" })
|
||||||
| undefined;
|
| undefined;
|
||||||
|
|
||||||
|
@ -31,12 +31,24 @@ const CustomListbox: React.FC<Props> = ({
|
|||||||
${className || "px-2 py-1"}`}
|
${className || "px-2 py-1"}`}
|
||||||
>
|
>
|
||||||
{icon ?? null}
|
{icon ?? null}
|
||||||
<span className="block truncate">
|
<div className="flex items-center gap-2 truncate">
|
||||||
{Array.isArray(value)
|
{Array.isArray(value) ? (
|
||||||
? value.map((v) => options?.find((o) => o.value === v)?.display).join(", ") ||
|
value.map((v) => options?.find((o) => o.value === v)?.display).join(", ") ||
|
||||||
`${title}`
|
`${title}`
|
||||||
: options?.find((o) => o.value === value)?.display || `${title}`}
|
) : (
|
||||||
</span>
|
<>
|
||||||
|
{options?.find((o) => o.value === value)?.color && (
|
||||||
|
<span
|
||||||
|
className="h-1.5 w-1.5 flex-shrink-0 rounded-full"
|
||||||
|
style={{
|
||||||
|
backgroundColor: options?.find((o) => o.value === value)?.color,
|
||||||
|
}}
|
||||||
|
></span>
|
||||||
|
)}{" "}
|
||||||
|
{options?.find((o) => o.value === value)?.display || `${title}`}
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
</Listbox.Button>
|
</Listbox.Button>
|
||||||
|
|
||||||
<Transition
|
<Transition
|
||||||
|
@ -35,6 +35,11 @@ export default function App({ Component, pageProps }) {
|
|||||||
<Component {...pageProps} />
|
<Component {...pageProps} />
|
||||||
</Layout>
|
</Layout>
|
||||||
</MDXProvider>
|
</MDXProvider>
|
||||||
|
<script
|
||||||
|
defer
|
||||||
|
data-domain="docs.plane.so"
|
||||||
|
src="https://plausible.io/js/script.js"
|
||||||
|
></script>
|
||||||
</>
|
</>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user