feat: now user can edit view (#793)

* feat: now user can edit view

* fix: build error
This commit is contained in:
Saheb Giri 2023-04-12 15:33:21 +05:30 committed by GitHub
parent 0f9812cf2c
commit 032ef831b2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 69 additions and 70 deletions

View File

@ -401,7 +401,7 @@ export const IssuesView: React.FC<Props> = ({
<CreateUpdateViewModal
isOpen={createViewModal !== null}
handleClose={() => setCreateViewModal(null)}
preLoadedData={createViewModal}
data={createViewModal}
/>
<CreateUpdateIssueModal
isOpen={createIssueModal && preloadedData?.actionType === "createIssue"}

View File

@ -1,4 +1,4 @@
import React, { useRef, useState } from "react";
import React, { useState } from "react";
import { useRouter } from "next/router";
@ -21,12 +21,11 @@ import { VIEWS_LIST } from "constants/fetch-keys";
type Props = {
isOpen: boolean;
setIsOpen: React.Dispatch<React.SetStateAction<boolean>>;
data: IView | null;
onClose: () => void;
onSuccess?: () => void;
};
export const DeleteViewModal: React.FC<Props> = ({ isOpen, data, onClose, onSuccess }) => {
export const DeleteViewModal: React.FC<Props> = ({ isOpen, data, setIsOpen }) => {
const [isDeleteLoading, setIsDeleteLoading] = useState(false);
const router = useRouter();
@ -35,14 +34,14 @@ export const DeleteViewModal: React.FC<Props> = ({ isOpen, data, onClose, onSucc
const { setToastAlert } = useToast();
const handleClose = () => {
setIsOpen(false);
setIsDeleteLoading(false);
onClose();
};
const handleDeletion = async () => {
setIsDeleteLoading(true);
if (!workspaceSlug || !data || !projectId) return;
await viewsService
.deleteView(workspaceSlug as string, projectId as string, data.id)
.then(() => {
@ -50,8 +49,6 @@ export const DeleteViewModal: React.FC<Props> = ({ isOpen, data, onClose, onSucc
views?.filter((view) => view.id !== data.id)
);
if (onSuccess) onSuccess();
handleClose();
setToastAlert({
@ -66,6 +63,8 @@ export const DeleteViewModal: React.FC<Props> = ({ isOpen, data, onClose, onSucc
title: "Error!",
message: "View could not be deleted. Please try again.",
});
})
.finally(() => {
setIsDeleteLoading(false);
});
};
@ -111,10 +110,9 @@ export const DeleteViewModal: React.FC<Props> = ({ isOpen, data, onClose, onSucc
</Dialog.Title>
<div className="mt-2">
<p className="text-sm text-gray-500">
Are you sure you want to delete view- {" "}
<span className="font-bold">{data?.name}</span>
? All of the data related to the view will be permanently removed.
This action cannot be undone.
Are you sure you want to delete view-{" "}
<span className="font-bold">{data?.name}</span>? All of the data related
to the view will be permanently removed. This action cannot be undone.
</p>
</div>
</div>

View File

@ -1,8 +1,5 @@
import { useEffect } from "react";
import { useRouter } from "next/router";
import useSWR from "swr";
import { useForm } from "react-hook-form";
// ui
@ -11,11 +8,6 @@ import { Input, PrimaryButton, SecondaryButton, TextArea } from "components/ui";
import { FilterList } from "components/core";
// types
import { IView } from "types";
// constant
import { STATE_LIST } from "constants/fetch-keys";
// services
import stateService from "services/state.service";
// components
import { SelectFilters } from "components/views";
@ -23,8 +15,7 @@ type Props = {
handleFormSubmit: (values: IView) => Promise<void>;
handleClose: () => void;
status: boolean;
data?: IView;
preLoadedData?: Partial<IView> | null;
data?: IView | null;
};
const defaultValues: Partial<IView> = {
@ -32,13 +23,7 @@ const defaultValues: Partial<IView> = {
description: "",
};
export const ViewForm: React.FC<Props> = ({
handleFormSubmit,
handleClose,
status,
data,
preLoadedData,
}) => {
export const ViewForm: React.FC<Props> = ({ handleFormSubmit, handleClose, status, data }) => {
const {
register,
formState: { errors, isSubmitting },
@ -49,6 +34,7 @@ export const ViewForm: React.FC<Props> = ({
} = useForm<IView>({
defaultValues,
});
const filters = watch("query");
const handleCreateUpdateView = async (formData: IView) => {
await handleFormSubmit(formData);
@ -66,13 +52,10 @@ export const ViewForm: React.FC<Props> = ({
}, [data, reset]);
useEffect(() => {
reset({
...defaultValues,
...preLoadedData,
});
}, [preLoadedData, reset]);
const filters = watch("query");
if (status && data) {
setValue("query", data.query_data);
}
}, [data, status, setValue]);
return (
<form onSubmit={handleSubmit(handleCreateUpdateView)}>
@ -84,18 +67,19 @@ export const ViewForm: React.FC<Props> = ({
<div>
<Input
id="name"
label="Name"
name="name"
type="name"
placeholder="Enter name"
placeholder="Title"
autoComplete="off"
mode="transparent"
className="resize-none text-xl"
error={errors.name}
register={register}
validations={{
required: "Name is required",
required: "Title is required",
maxLength: {
value: 255,
message: "Name should be less than 255 characters",
message: "Title should be less than 255 characters",
},
}}
/>
@ -104,8 +88,9 @@ export const ViewForm: React.FC<Props> = ({
<TextArea
id="description"
name="description"
label="Description"
placeholder="Enter description"
placeholder="Description"
className="h-32 resize-none text-sm"
mode="transparent"
error={errors.description}
register={register}
/>

View File

@ -20,16 +20,10 @@ import { VIEWS_LIST } from "constants/fetch-keys";
type Props = {
isOpen: boolean;
handleClose: () => void;
data?: IView;
preLoadedData?: Partial<IView> | null;
data?: IView | null;
};
export const CreateUpdateViewModal: React.FC<Props> = ({
isOpen,
handleClose,
data,
preLoadedData,
}) => {
export const CreateUpdateViewModal: React.FC<Props> = ({ isOpen, handleClose, data }) => {
const router = useRouter();
const { workspaceSlug, projectId } = router.query;
@ -66,14 +60,18 @@ export const CreateUpdateViewModal: React.FC<Props> = ({
};
const updateView = async (payload: IView) => {
const payloadData = {
...payload,
query_data: payload.query,
};
await viewsService
.updateView(workspaceSlug as string, projectId as string, data?.id ?? "", payload)
.updateView(workspaceSlug as string, projectId as string, data?.id ?? "", payloadData)
.then((res) => {
mutate<IView[]>(
VIEWS_LIST(projectId as string),
(prevData) =>
prevData?.map((p) => {
if (p.id === res.id) return { ...p, ...payload };
if (p.id === res.id) return { ...p, ...payloadData };
return p;
}),
@ -135,7 +133,6 @@ export const CreateUpdateViewModal: React.FC<Props> = ({
handleClose={handleClose}
status={data ? true : false}
data={data}
preLoadedData={preLoadedData}
/>
</Dialog.Panel>
</Transition.Child>

View File

@ -1,4 +1,4 @@
import React, { useState } from "react";
import React from "react";
import { mutate } from "swr";
import Link from "next/link";
import { useRouter } from "next/router";
@ -22,10 +22,11 @@ import { renderShortDate, renderShortTime } from "helpers/date-time.helper";
type Props = {
view: IView;
setSelectedView: React.Dispatch<React.SetStateAction<IView | null>>;
handleEditView: () => void;
handleDeleteView: () => void;
};
export const SingleViewItem: React.FC<Props> = ({ view, setSelectedView }) => {
export const SingleViewItem: React.FC<Props> = ({ view, handleEditView, handleDeleteView }) => {
const router = useRouter();
const { workspaceSlug, projectId } = router.query;
@ -134,23 +135,23 @@ export const SingleViewItem: React.FC<Props> = ({ view, setSelectedView }) => {
</button>
)}
<CustomMenu width="auto" verticalEllipsis>
{/* <CustomMenu.MenuItem
<CustomMenu.MenuItem
onClick={(e: any) => {
e.preventDefault();
e.stopPropagation();
// handleEditView();
handleEditView();
}}
>
<span className="flex items-center justify-start gap-2">
<PencilIcon className="h-3.5 w-3.5" />
<span>Edit View</span>
</span>
</CustomMenu.MenuItem> */}
</CustomMenu.MenuItem>
<CustomMenu.MenuItem
onClick={(e: any) => {
e.preventDefault();
e.stopPropagation();
setSelectedView(view);
handleDeleteView();
}}
>
<span className="flex items-center justify-start gap-2">

View File

@ -25,8 +25,11 @@ import { IView } from "types";
import type { NextPage } from "next";
const ProjectViews: NextPage = () => {
const [isCreateViewModalOpen, setIsCreateViewModalOpen] = useState(false);
const [selectedView, setSelectedView] = useState<IView | null>(null);
const [createUpdateViewModal, setCreateUpdateViewModal] = useState(false);
const [selectedViewToUpdate, setSelectedViewToUpdate] = useState<IView | null>(null);
const [deleteViewModal, setDeleteViewModal] = useState(false);
const [selectedViewToDelete, setSelectedViewToDelete] = useState<IView | null>(null);
const router = useRouter();
const { workspaceSlug, projectId } = router.query;
@ -45,6 +48,16 @@ const ProjectViews: NextPage = () => {
: null
);
const handleEditView = (view: IView) => {
setSelectedViewToUpdate(view);
setCreateUpdateViewModal(true);
};
const handleDeleteView = (view: IView) => {
setSelectedViewToDelete(view);
setDeleteViewModal(true);
};
return (
<ProjectAuthorizationWrapper
meta={{
@ -73,14 +86,14 @@ const ProjectViews: NextPage = () => {
}
>
<CreateUpdateViewModal
isOpen={isCreateViewModalOpen}
handleClose={() => setIsCreateViewModalOpen(false)}
isOpen={createUpdateViewModal}
handleClose={() => setCreateUpdateViewModal(false)}
data={selectedViewToUpdate}
/>
<DeleteViewModal
isOpen={!!selectedView}
data={selectedView}
onClose={() => setSelectedView(null)}
onSuccess={() => setSelectedView(null)}
isOpen={deleteViewModal}
data={selectedViewToDelete}
setIsOpen={setDeleteViewModal}
/>
{views ? (
views.length > 0 ? (
@ -88,7 +101,12 @@ const ProjectViews: NextPage = () => {
<h3 className="text-3xl font-semibold text-black">Views</h3>
<ul role="list" className="divide-y">
{views.map((view) => (
<SingleViewItem key={view.id} view={view} setSelectedView={setSelectedView} />
<SingleViewItem
key={view.id}
view={view}
handleEditView={() => handleEditView(view)}
handleDeleteView={() => handleDeleteView(view)}
/>
))}
</ul>
</div>