mirror of
https://github.com/makeplane/plane
synced 2024-06-14 14:31:34 +00:00
fix: cycles list rendering fixes
This commit is contained in:
parent
9c2ea8a7ae
commit
b1448c947e
@ -1,4 +1,4 @@
|
|||||||
import { FC } from "react";
|
import { FC, MouseEvent } from "react";
|
||||||
import Link from "next/link";
|
import Link from "next/link";
|
||||||
import { useRouter } from "next/router";
|
import { useRouter } from "next/router";
|
||||||
// hooks
|
// hooks
|
||||||
@ -22,6 +22,7 @@ import { getDateRangeStatus, renderShortDateWithYearFormat, findHowManyDaysLeft
|
|||||||
import { copyTextToClipboard, truncateText } from "helpers/string.helper";
|
import { copyTextToClipboard, truncateText } from "helpers/string.helper";
|
||||||
// types
|
// types
|
||||||
import { ICycle } from "types";
|
import { ICycle } from "types";
|
||||||
|
import { useMobxStore } from "lib/mobx/store-provider";
|
||||||
|
|
||||||
type TCyclesListItem = {
|
type TCyclesListItem = {
|
||||||
cycle: ICycle;
|
cycle: ICycle;
|
||||||
@ -61,6 +62,8 @@ const stateGroups = [
|
|||||||
|
|
||||||
export const CyclesListItem: FC<TCyclesListItem> = (props) => {
|
export const CyclesListItem: FC<TCyclesListItem> = (props) => {
|
||||||
const { cycle } = props;
|
const { cycle } = props;
|
||||||
|
// store
|
||||||
|
const { cycle: cycleStore } = useMobxStore();
|
||||||
// router
|
// router
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const { workspaceSlug, projectId } = router.query;
|
const { workspaceSlug, projectId } = router.query;
|
||||||
@ -91,10 +94,39 @@ export const CyclesListItem: FC<TCyclesListItem> = (props) => {
|
|||||||
color: group.color,
|
color: group.color,
|
||||||
}));
|
}));
|
||||||
|
|
||||||
const handleAddToFavorites = () => {};
|
const handleAddToFavorites = (e: MouseEvent<HTMLButtonElement>) => {
|
||||||
const handleRemoveFromFavorites = () => {};
|
e.preventDefault();
|
||||||
const handleEditCycle = () => {};
|
if (!workspaceSlug || !projectId) return;
|
||||||
const handleDeleteCycle = () => {};
|
|
||||||
|
cycleStore.addCycleToFavorites(workspaceSlug?.toString(), projectId.toString(), cycle.id).catch(() => {
|
||||||
|
setToastAlert({
|
||||||
|
type: "error",
|
||||||
|
title: "Error!",
|
||||||
|
message: "Couldn't add the cycle to favorites. Please try again.",
|
||||||
|
});
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleRemoveFromFavorites = (e: MouseEvent<HTMLButtonElement>) => {
|
||||||
|
e.preventDefault();
|
||||||
|
if (!workspaceSlug || !projectId) return;
|
||||||
|
|
||||||
|
cycleStore.removeCycleFromFavorites(workspaceSlug?.toString(), projectId.toString(), cycle.id).catch(() => {
|
||||||
|
setToastAlert({
|
||||||
|
type: "error",
|
||||||
|
title: "Error!",
|
||||||
|
message: "Couldn't add the cycle to favorites. Please try again.",
|
||||||
|
});
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleEditCycle = (e: MouseEvent<HTMLButtonElement>) => {
|
||||||
|
e.preventDefault();
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleDeleteCycle = (e: MouseEvent<HTMLButtonElement>) => {
|
||||||
|
e.preventDefault();
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
|
@ -19,20 +19,19 @@ export const CyclesView: FC<ICyclesView> = observer((props) => {
|
|||||||
// store
|
// store
|
||||||
const { cycle: cycleStore } = useMobxStore();
|
const { cycle: cycleStore } = useMobxStore();
|
||||||
// api call to fetch cycles list
|
// api call to fetch cycles list
|
||||||
useSWR(
|
const { isLoading } = useSWR(
|
||||||
workspaceSlug && projectId ? `CYCLES_LIST_${projectId}` : null,
|
workspaceSlug && projectId ? `CYCLES_LIST_${projectId}_${filter}` : null,
|
||||||
workspaceSlug && projectId ? () => cycleStore.fetchCycles(workspaceSlug, projectId, filter) : null
|
workspaceSlug && projectId ? () => cycleStore.fetchCycles(workspaceSlug, projectId, filter) : null
|
||||||
);
|
);
|
||||||
|
|
||||||
const cyclesList = cycleStore.cycles?.[projectId]?.[filter];
|
const cyclesList = cycleStore.cycles?.[projectId];
|
||||||
console.log("cyclesList", cyclesList);
|
|
||||||
console.log("cyclesList", cyclesList);
|
console.log("cyclesList", cyclesList);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
{view === "list" && (
|
{view === "list" && (
|
||||||
<>
|
<>
|
||||||
{cyclesList ? (
|
{!isLoading ? (
|
||||||
<CyclesList cycles={cyclesList} filter={filter} />
|
<CyclesList cycles={cyclesList} filter={filter} />
|
||||||
) : (
|
) : (
|
||||||
<Loader className="space-y-4">
|
<Loader className="space-y-4">
|
||||||
@ -45,7 +44,7 @@ export const CyclesView: FC<ICyclesView> = observer((props) => {
|
|||||||
)}
|
)}
|
||||||
{view === "board" && (
|
{view === "board" && (
|
||||||
<>
|
<>
|
||||||
{cyclesList ? (
|
{!isLoading ? (
|
||||||
<CyclesBoard cycles={cyclesList} filter={filter} />
|
<CyclesBoard cycles={cyclesList} filter={filter} />
|
||||||
) : (
|
) : (
|
||||||
<Loader className="grid grid-cols-1 gap-9 md:grid-cols-2 lg:grid-cols-3">
|
<Loader className="grid grid-cols-1 gap-9 md:grid-cols-2 lg:grid-cols-3">
|
||||||
|
@ -170,7 +170,7 @@ const ProjectCyclesPage: NextPage = observer(() => {
|
|||||||
<Tab.Panel as="div" className="p-4 sm:p-5 h-full overflow-y-auto">
|
<Tab.Panel as="div" className="p-4 sm:p-5 h-full overflow-y-auto">
|
||||||
{cycleTab && cyclesView && workspaceSlug && projectId && (
|
{cycleTab && cyclesView && workspaceSlug && projectId && (
|
||||||
<CyclesView
|
<CyclesView
|
||||||
filter={cycleTab as ICycleAPIFilter}
|
filter="all"
|
||||||
view={cyclesView as ICycleView}
|
view={cyclesView as ICycleView}
|
||||||
workspaceSlug={workspaceSlug?.toString()}
|
workspaceSlug={workspaceSlug?.toString()}
|
||||||
projectId={projectId?.toString()}
|
projectId={projectId?.toString()}
|
||||||
@ -183,7 +183,7 @@ const ProjectCyclesPage: NextPage = observer(() => {
|
|||||||
<Tab.Panel as="div" className="p-4 sm:p-5 h-full overflow-y-auto">
|
<Tab.Panel as="div" className="p-4 sm:p-5 h-full overflow-y-auto">
|
||||||
{cycleTab && cyclesView && workspaceSlug && projectId && (
|
{cycleTab && cyclesView && workspaceSlug && projectId && (
|
||||||
<CyclesView
|
<CyclesView
|
||||||
filter={cycleTab as ICycleAPIFilter}
|
filter="upcoming"
|
||||||
view={cyclesView as ICycleView}
|
view={cyclesView as ICycleView}
|
||||||
workspaceSlug={workspaceSlug?.toString()}
|
workspaceSlug={workspaceSlug?.toString()}
|
||||||
projectId={projectId?.toString()}
|
projectId={projectId?.toString()}
|
||||||
@ -193,7 +193,7 @@ const ProjectCyclesPage: NextPage = observer(() => {
|
|||||||
<Tab.Panel as="div" className="p-4 sm:p-5 h-full overflow-y-auto">
|
<Tab.Panel as="div" className="p-4 sm:p-5 h-full overflow-y-auto">
|
||||||
{cycleTab && cyclesView && workspaceSlug && projectId && (
|
{cycleTab && cyclesView && workspaceSlug && projectId && (
|
||||||
<CyclesView
|
<CyclesView
|
||||||
filter={cycleTab as ICycleAPIFilter}
|
filter="completed"
|
||||||
view={cyclesView as ICycleView}
|
view={cyclesView as ICycleView}
|
||||||
workspaceSlug={workspaceSlug?.toString()}
|
workspaceSlug={workspaceSlug?.toString()}
|
||||||
projectId={projectId?.toString()}
|
projectId={projectId?.toString()}
|
||||||
@ -203,7 +203,7 @@ const ProjectCyclesPage: NextPage = observer(() => {
|
|||||||
<Tab.Panel as="div" className="p-4 sm:p-5 h-full overflow-y-auto">
|
<Tab.Panel as="div" className="p-4 sm:p-5 h-full overflow-y-auto">
|
||||||
{cycleTab && cyclesView && workspaceSlug && projectId && (
|
{cycleTab && cyclesView && workspaceSlug && projectId && (
|
||||||
<CyclesView
|
<CyclesView
|
||||||
filter={cycleTab as ICycleAPIFilter}
|
filter="draft"
|
||||||
view={cyclesView as ICycleView}
|
view={cyclesView as ICycleView}
|
||||||
workspaceSlug={workspaceSlug?.toString()}
|
workspaceSlug={workspaceSlug?.toString()}
|
||||||
projectId={projectId?.toString()}
|
projectId={projectId?.toString()}
|
||||||
|
@ -12,9 +12,7 @@ export interface ICycleStore {
|
|||||||
error: any | null;
|
error: any | null;
|
||||||
|
|
||||||
cycles: {
|
cycles: {
|
||||||
[project_id: string]: {
|
[project_id: string]: ICycle[];
|
||||||
[filter_name: string]: ICycle[];
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
cycle_details: {
|
cycle_details: {
|
||||||
@ -26,8 +24,10 @@ export interface ICycleStore {
|
|||||||
projectId: string,
|
projectId: string,
|
||||||
params: "all" | "current" | "upcoming" | "draft" | "completed" | "incomplete"
|
params: "all" | "current" | "upcoming" | "draft" | "completed" | "incomplete"
|
||||||
) => Promise<void>;
|
) => Promise<void>;
|
||||||
|
createCycle: (workspaceSlug: string, projectId: string, data: any) => Promise<ICycle>;
|
||||||
|
|
||||||
createCycle: (workspaceSlug: string, projectId: string, data: any, filter: string) => Promise<ICycle>;
|
addCycleToFavorites: (workspaceSlug: string, projectId: string, cycleId: string) => Promise<any>;
|
||||||
|
removeCycleFromFavorites: (workspaceSlug: string, projectId: string, cycleId: string) => Promise<void>;
|
||||||
}
|
}
|
||||||
|
|
||||||
class CycleStore implements ICycleStore {
|
class CycleStore implements ICycleStore {
|
||||||
@ -35,9 +35,7 @@ class CycleStore implements ICycleStore {
|
|||||||
error: any | null = null;
|
error: any | null = null;
|
||||||
|
|
||||||
cycles: {
|
cycles: {
|
||||||
[project_id: string]: {
|
[project_id: string]: ICycle[];
|
||||||
[filter_name: string]: ICycle[];
|
|
||||||
};
|
|
||||||
} = {};
|
} = {};
|
||||||
|
|
||||||
cycle_details: {
|
cycle_details: {
|
||||||
@ -63,6 +61,9 @@ class CycleStore implements ICycleStore {
|
|||||||
// actions
|
// actions
|
||||||
fetchCycles: action,
|
fetchCycles: action,
|
||||||
createCycle: action,
|
createCycle: action,
|
||||||
|
|
||||||
|
addCycleToFavorites: action,
|
||||||
|
removeCycleFromFavorites: action,
|
||||||
});
|
});
|
||||||
|
|
||||||
this.rootStore = _rootStore;
|
this.rootStore = _rootStore;
|
||||||
@ -92,9 +93,7 @@ class CycleStore implements ICycleStore {
|
|||||||
runInAction(() => {
|
runInAction(() => {
|
||||||
this.cycles = {
|
this.cycles = {
|
||||||
...this.cycles,
|
...this.cycles,
|
||||||
[projectId]: {
|
[projectId]: cyclesResponse,
|
||||||
[params]: cyclesResponse,
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
this.loader = false;
|
this.loader = false;
|
||||||
this.error = null;
|
this.error = null;
|
||||||
@ -106,7 +105,7 @@ class CycleStore implements ICycleStore {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
createCycle = async (workspaceSlug: string, projectId: string, data: any, filter: string) => {
|
createCycle = async (workspaceSlug: string, projectId: string, data: any) => {
|
||||||
try {
|
try {
|
||||||
const response = await this.cycleService.createCycle(
|
const response = await this.cycleService.createCycle(
|
||||||
workspaceSlug,
|
workspaceSlug,
|
||||||
@ -118,10 +117,7 @@ class CycleStore implements ICycleStore {
|
|||||||
runInAction(() => {
|
runInAction(() => {
|
||||||
this.cycles = {
|
this.cycles = {
|
||||||
...this.cycles,
|
...this.cycles,
|
||||||
[projectId]: {
|
[projectId]: [...this.cycles[projectId], response],
|
||||||
...this.cycles[projectId],
|
|
||||||
[filter]: [...this.cycles[projectId][filter], response],
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -131,6 +127,67 @@ class CycleStore implements ICycleStore {
|
|||||||
throw error;
|
throw error;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
addCycleToFavorites = async (workspaceSlug: string, projectId: string, cycleId: string) => {
|
||||||
|
try {
|
||||||
|
runInAction(() => {
|
||||||
|
this.cycles = {
|
||||||
|
...this.cycles,
|
||||||
|
[projectId]: this.cycles[projectId].map((cycle) => {
|
||||||
|
if (cycle.id === cycleId) return { ...cycle, is_favorite: true };
|
||||||
|
return cycle;
|
||||||
|
}),
|
||||||
|
};
|
||||||
|
});
|
||||||
|
// updating through api.
|
||||||
|
const response = await this.cycleService.addCycleToFavorites(workspaceSlug, projectId, { cycle: cycleId });
|
||||||
|
return response;
|
||||||
|
} catch (error) {
|
||||||
|
console.log("Failed to add cycle to favorites in the cycles store", error);
|
||||||
|
// resetting the local state
|
||||||
|
runInAction(() => {
|
||||||
|
this.cycles = {
|
||||||
|
...this.cycles,
|
||||||
|
[projectId]: this.cycles[projectId].map((cycle) => {
|
||||||
|
if (cycle.id === cycleId) return { ...cycle, is_favorite: false };
|
||||||
|
return cycle;
|
||||||
|
}),
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
removeCycleFromFavorites = async (workspaceSlug: string, projectId: string, cycleId: string) => {
|
||||||
|
try {
|
||||||
|
runInAction(() => {
|
||||||
|
this.cycles = {
|
||||||
|
...this.cycles,
|
||||||
|
[projectId]: this.cycles[projectId].map((cycle) => {
|
||||||
|
if (cycle.id === cycleId) return { ...cycle, is_favorite: false };
|
||||||
|
return cycle;
|
||||||
|
}),
|
||||||
|
};
|
||||||
|
});
|
||||||
|
// updating through api
|
||||||
|
const response = await this.cycleService.removeCycleFromFavorites(workspaceSlug, projectId, cycleId);
|
||||||
|
return response;
|
||||||
|
} catch (error) {
|
||||||
|
console.log("Failed to remove cycle from favorites - Cycle Store", error);
|
||||||
|
// resetting the local state
|
||||||
|
runInAction(() => {
|
||||||
|
this.cycles = {
|
||||||
|
...this.cycles,
|
||||||
|
[projectId]: this.cycles[projectId].map((cycle) => {
|
||||||
|
if (cycle.id === cycleId) return { ...cycle, is_favorite: true };
|
||||||
|
return cycle;
|
||||||
|
}),
|
||||||
|
};
|
||||||
|
});
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export default CycleStore;
|
export default CycleStore;
|
||||||
|
Loading…
Reference in New Issue
Block a user