refractor: moved all local state, and component to that component,
used dynamic imports where-ever possible
This commit is contained in:
parent
f67bbbf9ff
commit
eadebd8d93
7 changed files with 167 additions and 150 deletions
|
|
@ -1,5 +1,16 @@
|
|||
import React from "react";
|
||||
// next
|
||||
import { useRouter } from "next/router";
|
||||
import Image from "next/image";
|
||||
// swr
|
||||
import useSWR from "swr";
|
||||
// constants
|
||||
import { PROJECT_ISSUES_ACTIVITY } from "constants/fetch-keys";
|
||||
import { addSpaceIfCamelCase, timeAgo } from "constants/common";
|
||||
// services
|
||||
import issuesServices from "lib/services/issues.service";
|
||||
// hooks
|
||||
import useUser from "lib/hooks/useUser";
|
||||
// ui
|
||||
import { Spinner } from "ui";
|
||||
// icons
|
||||
|
|
@ -12,14 +23,6 @@ import {
|
|||
} from "@heroicons/react/24/outline";
|
||||
// types
|
||||
import { IssueResponse, IState } from "types";
|
||||
// constants
|
||||
import { addSpaceIfCamelCase, timeAgo } from "constants/common";
|
||||
|
||||
type Props = {
|
||||
issueActivities: any[] | undefined;
|
||||
states: IState[] | undefined;
|
||||
issues: IssueResponse | undefined;
|
||||
};
|
||||
|
||||
const activityIcons: {
|
||||
[key: string]: JSX.Element;
|
||||
|
|
@ -32,7 +35,25 @@ const activityIcons: {
|
|||
parent: <UserIcon className="h-3.5 w-3.5" />,
|
||||
};
|
||||
|
||||
const IssueActivitySection: React.FC<Props> = ({ issueActivities, states, issues }) => {
|
||||
const IssueActivitySection: React.FC = () => {
|
||||
const router = useRouter();
|
||||
|
||||
const { issueId, projectId } = router.query;
|
||||
|
||||
const { activeWorkspace, states, issues } = useUser();
|
||||
|
||||
const { data: issueActivities } = useSWR<any[]>(
|
||||
activeWorkspace && projectId && issueId ? PROJECT_ISSUES_ACTIVITY : null,
|
||||
activeWorkspace && projectId && issueId
|
||||
? () =>
|
||||
issuesServices.getIssueActivities(
|
||||
activeWorkspace.slug,
|
||||
projectId as string,
|
||||
issueId as string
|
||||
)
|
||||
: null
|
||||
);
|
||||
|
||||
return (
|
||||
<>
|
||||
{issueActivities ? (
|
||||
|
|
|
|||
|
|
@ -1,12 +1,16 @@
|
|||
import React from "react";
|
||||
// router
|
||||
import { useRouter } from "next/router";
|
||||
// swr
|
||||
import { mutate } from "swr";
|
||||
import useSWR from "swr";
|
||||
// react hook form
|
||||
import { useForm } from "react-hook-form";
|
||||
// services
|
||||
import issuesServices from "lib/services/issues.service";
|
||||
// fetch keys
|
||||
import { PROJECT_ISSUES_COMMENTS } from "constants/fetch-keys";
|
||||
// hooks
|
||||
import useUser from "lib/hooks/useUser";
|
||||
// components
|
||||
import CommentCard from "components/project/issues/issue-detail/comment/IssueCommentCard";
|
||||
// ui
|
||||
|
|
@ -14,18 +18,11 @@ import { TextArea, Button, Spinner } from "ui";
|
|||
// types
|
||||
import type { IIssueComment } from "types";
|
||||
|
||||
type Props = {
|
||||
comments?: IIssueComment[];
|
||||
workspaceSlug: string;
|
||||
projectId: string;
|
||||
issueId: string;
|
||||
};
|
||||
|
||||
const defaultValues: Partial<IIssueComment> = {
|
||||
comment: "",
|
||||
};
|
||||
|
||||
const IssueCommentSection: React.FC<Props> = ({ comments, issueId, projectId, workspaceSlug }) => {
|
||||
const IssueCommentSection: React.FC = () => {
|
||||
const {
|
||||
register,
|
||||
handleSubmit,
|
||||
|
|
@ -34,15 +31,31 @@ const IssueCommentSection: React.FC<Props> = ({ comments, issueId, projectId, wo
|
|||
reset,
|
||||
} = useForm<IIssueComment>({ defaultValues });
|
||||
|
||||
const router = useRouter();
|
||||
|
||||
let { issueId, projectId } = router.query;
|
||||
|
||||
const { activeWorkspace } = useUser();
|
||||
|
||||
const { data: comments, mutate } = useSWR<IIssueComment[]>(
|
||||
activeWorkspace && projectId && issueId ? PROJECT_ISSUES_COMMENTS(issueId as string) : null,
|
||||
activeWorkspace && projectId && issueId
|
||||
? () =>
|
||||
issuesServices.getIssueComments(
|
||||
activeWorkspace.slug,
|
||||
projectId as string,
|
||||
issueId as string
|
||||
)
|
||||
: null
|
||||
);
|
||||
|
||||
const onSubmit = async (formData: IIssueComment) => {
|
||||
if (!activeWorkspace || !projectId || !issueId || isSubmitting) return;
|
||||
await issuesServices
|
||||
.createIssueComment(workspaceSlug, projectId, issueId, formData)
|
||||
.createIssueComment(activeWorkspace.slug, projectId as string, issueId as string, formData)
|
||||
.then((response) => {
|
||||
console.log(response);
|
||||
mutate<IIssueComment[]>(PROJECT_ISSUES_COMMENTS(issueId), (prevData) => [
|
||||
response,
|
||||
...(prevData ?? []),
|
||||
]);
|
||||
mutate((prevData) => [response, ...(prevData ?? [])]);
|
||||
reset(defaultValues);
|
||||
})
|
||||
.catch((error) => {
|
||||
|
|
@ -51,26 +64,34 @@ const IssueCommentSection: React.FC<Props> = ({ comments, issueId, projectId, wo
|
|||
};
|
||||
|
||||
const onCommentUpdate = async (comment: IIssueComment) => {
|
||||
if (!activeWorkspace || !projectId || !issueId || isSubmitting) return;
|
||||
await issuesServices
|
||||
.patchIssueComment(workspaceSlug, projectId, issueId, comment.id, comment)
|
||||
.patchIssueComment(
|
||||
activeWorkspace.slug,
|
||||
projectId as string,
|
||||
issueId as string,
|
||||
comment.id,
|
||||
comment
|
||||
)
|
||||
.then((response) => {
|
||||
console.log(response);
|
||||
mutate<IIssueComment[]>(PROJECT_ISSUES_COMMENTS(issueId), (prevData) => {
|
||||
const newData = prevData ?? [];
|
||||
const index = newData.findIndex((comment) => comment.id === response.id);
|
||||
newData[index] = response;
|
||||
return [...newData];
|
||||
mutate((prevData) => {
|
||||
const updatedComments = prevData?.map((c) => {
|
||||
if (c.id === comment.id) {
|
||||
return comment;
|
||||
}
|
||||
return c;
|
||||
});
|
||||
return updatedComments;
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
const onCommentDelete = async (commentId: string) => {
|
||||
if (!activeWorkspace || !projectId || !issueId || isSubmitting) return;
|
||||
await issuesServices
|
||||
.deleteIssueComment(workspaceSlug, projectId, issueId, commentId)
|
||||
.deleteIssueComment(activeWorkspace.slug, projectId as string, issueId as string, commentId)
|
||||
.then((response) => {
|
||||
mutate<IIssueComment[]>(PROJECT_ISSUES_COMMENTS(issueId), (prevData) =>
|
||||
(prevData ?? []).filter((c) => c.id !== commentId)
|
||||
);
|
||||
mutate((prevData) => (prevData ?? []).filter((c) => c.id !== commentId));
|
||||
console.log(response);
|
||||
});
|
||||
};
|
||||
|
|
@ -124,7 +145,6 @@ const IssueCommentSection: React.FC<Props> = ({ comments, issueId, projectId, wo
|
|||
/>
|
||||
<Button type="submit" className="whitespace-nowrap" disabled={isSubmitting}>
|
||||
{isSubmitting ? "Adding comment..." : "Add comment"}
|
||||
{/* <UploadingIcon /> */}
|
||||
</Button>
|
||||
</div>
|
||||
</form>
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
import React, { useState } from "react";
|
||||
// swr
|
||||
import useSWR from "swr";
|
||||
import dynamic from "next/dynamic";
|
||||
// headless ui
|
||||
import { Listbox, Transition } from "@headlessui/react";
|
||||
// react hook form
|
||||
|
|
@ -14,6 +15,8 @@ import useToast from "lib/hooks/useToast";
|
|||
import { PROJECT_ISSUE_LABELS } from "constants/fetch-keys";
|
||||
// commons
|
||||
import { copyTextToClipboard } from "constants/common";
|
||||
// components
|
||||
import ConfirmIssueDeletion from "components/project/issues/confirm-issue-deletion";
|
||||
// ui
|
||||
import { Input, Button, Spinner } from "ui";
|
||||
import { Popover } from "@headlessui/react";
|
||||
|
|
@ -30,7 +33,7 @@ import {
|
|||
} from "@heroicons/react/24/outline";
|
||||
// types
|
||||
import type { Control } from "react-hook-form";
|
||||
import type { IIssue, IIssueLabels, NestedKeyOf } from "types";
|
||||
import type { ICycle, IIssue, IIssueLabels, NestedKeyOf } from "types";
|
||||
import { TwitterPicker } from "react-color";
|
||||
import { positionEditorElement } from "components/lexical/helpers/editor";
|
||||
import SelectState from "./select-state";
|
||||
|
|
@ -46,7 +49,6 @@ type Props = {
|
|||
submitChanges: (formData: Partial<IIssue>) => void;
|
||||
issueDetail: IIssue | undefined;
|
||||
watch: UseFormWatch<IIssue>;
|
||||
setDeleteIssueModal: React.Dispatch<React.SetStateAction<boolean>>;
|
||||
};
|
||||
|
||||
const defaultValues: Partial<IIssueLabels> = {
|
||||
|
|
@ -59,7 +61,6 @@ const IssueDetailSidebar: React.FC<Props> = ({
|
|||
submitChanges,
|
||||
issueDetail,
|
||||
watch: watchIssue,
|
||||
setDeleteIssueModal,
|
||||
}) => {
|
||||
const [createLabelForm, setCreateLabelForm] = useState(false);
|
||||
|
||||
|
|
@ -74,6 +75,8 @@ const IssueDetailSidebar: React.FC<Props> = ({
|
|||
: null
|
||||
);
|
||||
|
||||
const [deleteIssueModal, setDeleteIssueModal] = useState(false);
|
||||
|
||||
const {
|
||||
register,
|
||||
handleSubmit,
|
||||
|
|
@ -97,15 +100,17 @@ const IssueDetailSidebar: React.FC<Props> = ({
|
|||
});
|
||||
};
|
||||
|
||||
const handleCycleChange = (cycleId: string) => {
|
||||
if (activeWorkspace && activeProject && issueDetail)
|
||||
const handleCycleChange = (cycleDetail: ICycle) => {
|
||||
if (activeWorkspace && activeProject && issueDetail) {
|
||||
submitChanges({ cycle: cycleDetail.id, cycle_detail: cycleDetail });
|
||||
issuesServices
|
||||
.addIssueToCycle(activeWorkspace.slug, activeProject.id, cycleId, {
|
||||
.addIssueToCycle(activeWorkspace.slug, activeProject.id, cycleDetail.id, {
|
||||
issues: [issueDetail.id],
|
||||
})
|
||||
.then(() => {
|
||||
submitChanges({});
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
|
|
@ -420,6 +425,11 @@ const IssueDetailSidebar: React.FC<Props> = ({
|
|||
)}
|
||||
</div>
|
||||
</div>
|
||||
<ConfirmIssueDeletion
|
||||
handleClose={() => setDeleteIssueModal(false)}
|
||||
isOpen={deleteIssueModal}
|
||||
data={issueDetail}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -9,13 +9,13 @@ import { Spinner, CustomSelect } from "ui";
|
|||
// icons
|
||||
import { ArrowPathIcon } from "@heroicons/react/24/outline";
|
||||
// types
|
||||
import { IIssue } from "types";
|
||||
import { ICycle, IIssue } from "types";
|
||||
// common
|
||||
import { classNames } from "constants/common";
|
||||
|
||||
type Props = {
|
||||
control: Control<IIssue, any>;
|
||||
handleCycleChange: (cycleId: string) => void;
|
||||
handleCycleChange: (cycle: ICycle) => void;
|
||||
};
|
||||
|
||||
const SelectCycle: React.FC<Props> = ({ control, handleCycleChange }) => {
|
||||
|
|
@ -46,7 +46,7 @@ const SelectCycle: React.FC<Props> = ({ control, handleCycleChange }) => {
|
|||
}
|
||||
value={value}
|
||||
onChange={(value: any) => {
|
||||
handleCycleChange(value);
|
||||
handleCycleChange(cycles?.find((c) => c.id === value) as any);
|
||||
}}
|
||||
>
|
||||
{cycles ? (
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue