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 ConfirmCycleDeletion from "components/project/cycles/confirm-cycle-deletion";
|
||||
// types
|
||||
import { ICycle, SelectSprintType } from "types";
|
||||
import { ICycle, SelectCycleType } from "types";
|
||||
import { CompletedCycleIcon, CurrentCycleIcon, UpcomingCycleIcon } from "ui/icons";
|
||||
|
||||
type TCycleStatsViewProps = {
|
||||
cycles: ICycle[];
|
||||
setCreateUpdateCycleModal: React.Dispatch<React.SetStateAction<boolean>>;
|
||||
setSelectedCycle: React.Dispatch<React.SetStateAction<SelectSprintType>>;
|
||||
setSelectedCycle: React.Dispatch<React.SetStateAction<SelectCycleType>>;
|
||||
type: "current" | "upcoming" | "completed";
|
||||
};
|
||||
|
||||
@ -21,7 +21,7 @@ const CycleStatsView: React.FC<TCycleStatsViewProps> = ({
|
||||
type,
|
||||
}) => {
|
||||
const [cycleDeleteModal, setCycleDeleteModal] = useState(false);
|
||||
const [selectedCycleForDelete, setSelectedCycleForDelete] = useState<SelectSprintType>();
|
||||
const [selectedCycleForDelete, setSelectedCycleForDelete] = useState<SelectCycleType>();
|
||||
|
||||
const handleDeleteCycle = (cycle: ICycle) => {
|
||||
setSelectedCycleForDelete({ ...cycle, actionType: "delete" });
|
||||
|
@ -63,7 +63,7 @@ const ConfirmModuleDeletion: React.FC<Props> = ({ isOpen, setIsOpen, data }) =>
|
||||
<Transition.Root show={isOpen} as={React.Fragment}>
|
||||
<Dialog
|
||||
as="div"
|
||||
className="relative z-10"
|
||||
className="relative z-20"
|
||||
initialFocus={cancelButtonRef}
|
||||
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" />
|
||||
</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">
|
||||
<Transition.Child
|
||||
as={React.Fragment}
|
@ -7,6 +7,10 @@ import { mutate } from "swr";
|
||||
import { useForm } from "react-hook-form";
|
||||
|
||||
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
|
||||
import { Button, Input, TextArea } from "ui";
|
||||
// services
|
||||
@ -17,9 +21,6 @@ import type { IModule } from "types";
|
||||
import { renderDateFormat } from "constants/common";
|
||||
// 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 = {
|
||||
isOpen: boolean;
|
||||
@ -51,15 +52,6 @@ const CreateUpdateModuleModal: React.FC<Props> = ({ isOpen, setIsOpen, data, pro
|
||||
defaultValues,
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
if (data) {
|
||||
setIsOpen(true);
|
||||
reset(data);
|
||||
} else {
|
||||
reset(defaultValues);
|
||||
}
|
||||
}, [data, setIsOpen, reset]);
|
||||
|
||||
const onSubmit = async (formData: IModule) => {
|
||||
if (!workspaceSlug) return;
|
||||
const payload = {
|
||||
@ -71,11 +63,7 @@ const CreateUpdateModuleModal: React.FC<Props> = ({ isOpen, setIsOpen, data, pro
|
||||
await modulesService
|
||||
.createModule(workspaceSlug as string, projectId, payload)
|
||||
.then((res) => {
|
||||
mutate<IModule[]>(
|
||||
MODULE_LIST(projectId),
|
||||
(prevData) => [res, ...(prevData ?? [])],
|
||||
false
|
||||
);
|
||||
mutate(MODULE_LIST(projectId));
|
||||
handleClose();
|
||||
})
|
||||
.catch((err) => {
|
||||
@ -119,6 +107,15 @@ const CreateUpdateModuleModal: React.FC<Props> = ({ isOpen, setIsOpen, data, pro
|
||||
reset(defaultValues);
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
if (data) {
|
||||
setIsOpen(true);
|
||||
reset(data);
|
||||
} else {
|
||||
reset(defaultValues);
|
||||
}
|
||||
}, [data, setIsOpen, reset]);
|
||||
|
||||
return (
|
||||
<Transition.Root show={isOpen} as={React.Fragment}>
|
||||
<Dialog as="div" className="relative z-20" onClose={handleClose}>
|
||||
|
@ -27,13 +27,17 @@ const PageNotFound: NextPage = () => {
|
||||
<div className="space-y-2">
|
||||
<h3 className="text-lg font-semibold">Oops! Something went wrong.</h3>
|
||||
<p className="text-sm text-gray-500">
|
||||
Lorem ipsum dolor sit amet consectetur. Fermentum augue ipsum ipsum adipiscing tempus
|
||||
diam.
|
||||
Sorry, the page you are looking for cannot be found. It may have been removed, had its
|
||||
name changed, or is temporarily unavailable.
|
||||
</p>
|
||||
</div>
|
||||
<Button type="button" largePadding>
|
||||
Go to Home
|
||||
</Button>
|
||||
<Link href="/">
|
||||
<a className="block">
|
||||
<Button type="button" largePadding>
|
||||
Go to Home
|
||||
</Button>
|
||||
</a>
|
||||
</Link>
|
||||
</div>
|
||||
</div>
|
||||
</DefaultLayout>
|
||||
|
@ -5,7 +5,7 @@ import type { NextPage, NextPageContext } from "next";
|
||||
|
||||
import useSWR from "swr";
|
||||
// services
|
||||
import sprintService from "lib/services/cycles.service";
|
||||
import cycleService from "lib/services/cycles.service";
|
||||
import projectService from "lib/services/project.service";
|
||||
import workspaceService from "lib/services/workspace.service";
|
||||
// layouts
|
||||
@ -16,9 +16,9 @@ import CycleStatsView from "components/project/cycles/stats-view";
|
||||
// ui
|
||||
import { BreadcrumbItem, Breadcrumbs, HeaderButton, EmptySpace, EmptySpaceItem, Loader } from "ui";
|
||||
// icons
|
||||
import { ArrowPathIcon, PlusIcon } from "@heroicons/react/24/outline";
|
||||
import { PlusIcon } from "@heroicons/react/24/outline";
|
||||
// types
|
||||
import { ICycle, SelectSprintType } from "types";
|
||||
import { ICycle, SelectCycleType } from "types";
|
||||
// fetching keys
|
||||
import { CYCLE_LIST, PROJECT_DETAILS, WORKSPACE_DETAILS } from "constants/fetch-keys";
|
||||
// lib
|
||||
@ -26,8 +26,8 @@ import { requiredAuth } from "lib/auth";
|
||||
import { Tab } from "@headlessui/react";
|
||||
import { CyclesIcon } from "ui/icons";
|
||||
|
||||
const ProjectSprints: NextPage = () => {
|
||||
const [selectedCycle, setSelectedCycle] = useState<SelectSprintType>();
|
||||
const ProjectCycles: NextPage = () => {
|
||||
const [selectedCycle, setSelectedCycle] = useState<SelectCycleType>();
|
||||
const [createUpdateCycleModal, setCreateUpdateCycleModal] = useState(false);
|
||||
|
||||
const {
|
||||
@ -49,7 +49,7 @@ const ProjectSprints: NextPage = () => {
|
||||
const { data: cycles } = useSWR<ICycle[]>(
|
||||
activeWorkspace && projectId ? CYCLE_LIST(projectId as string) : null,
|
||||
activeWorkspace && projectId
|
||||
? () => sprintService.getCycles(activeWorkspace.slug, projectId as string)
|
||||
? () => cycleService.getCycles(activeWorkspace.slug, projectId as string)
|
||||
: 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 ConfirmIssueDeletion from "components/project/issues/confirm-issue-deletion";
|
||||
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 View from "components/core/view";
|
||||
// ui
|
||||
@ -345,7 +345,7 @@ const SingleModule = () => {
|
||||
>
|
||||
<EmptySpace
|
||||
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}
|
||||
>
|
||||
<EmptySpaceItem
|
||||
|
@ -78,7 +78,7 @@ const ProjectModules: NextPage = () => {
|
||||
<div className="flex h-full w-full flex-col items-center justify-center px-4">
|
||||
<EmptySpace
|
||||
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}
|
||||
>
|
||||
<EmptySpaceItem
|
||||
|
@ -9,13 +9,16 @@ import { ThemeContextProvider } from "contexts/theme.context";
|
||||
|
||||
function MyApp({ Component, pageProps }: AppProps) {
|
||||
return (
|
||||
<UserProvider>
|
||||
<ToastContextProvider>
|
||||
<ThemeContextProvider>
|
||||
<Component {...pageProps} />
|
||||
</ThemeContextProvider>
|
||||
</ToastContextProvider>
|
||||
</UserProvider>
|
||||
<>
|
||||
<UserProvider>
|
||||
<ToastContextProvider>
|
||||
<ThemeContextProvider>
|
||||
<Component {...pageProps} />
|
||||
</ThemeContextProvider>
|
||||
</ToastContextProvider>
|
||||
</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;
|
||||
}
|
||||
|
||||
export type SelectSprintType =
|
||||
export type SelectCycleType =
|
||||
| (ICycle & { actionType: "edit" | "delete" | "create-issue" })
|
||||
| undefined;
|
||||
|
||||
|
@ -31,12 +31,24 @@ const CustomListbox: React.FC<Props> = ({
|
||||
${className || "px-2 py-1"}`}
|
||||
>
|
||||
{icon ?? null}
|
||||
<span className="block truncate">
|
||||
{Array.isArray(value)
|
||||
? value.map((v) => options?.find((o) => o.value === v)?.display).join(", ") ||
|
||||
`${title}`
|
||||
: options?.find((o) => o.value === value)?.display || `${title}`}
|
||||
</span>
|
||||
<div className="flex items-center gap-2 truncate">
|
||||
{Array.isArray(value) ? (
|
||||
value.map((v) => options?.find((o) => o.value === v)?.display).join(", ") ||
|
||||
`${title}`
|
||||
) : (
|
||||
<>
|
||||
{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>
|
||||
|
||||
<Transition
|
||||
|
@ -35,6 +35,11 @@ export default function App({ Component, pageProps }) {
|
||||
<Component {...pageProps} />
|
||||
</Layout>
|
||||
</MDXProvider>
|
||||
<script
|
||||
defer
|
||||
data-domain="docs.plane.so"
|
||||
src="https://plausible.io/js/script.js"
|
||||
></script>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user