fix: projects should not be edited or deleted on the project list page
This commit is contained in:
@@ -6,8 +6,7 @@ import { TokenContext } from '@/utils/TokenProvider';
|
||||
import { ProjectType, ProjectsMessages } from '@/types/project';
|
||||
import ProjectsTable from './ProjectsTable';
|
||||
import ProjectDialog from '@/components/ProjectDialog';
|
||||
import { fetchProjects, createProject, updateProject, deleteProject } from '@/utils/projectsControl';
|
||||
import DeleteConfirmDialog from '@/components/DeleteConfirmDialog';
|
||||
import { fetchProjects, createProject } from '@/utils/projectsControl';
|
||||
|
||||
export type Props = {
|
||||
messages: ProjectsMessages;
|
||||
@@ -16,7 +15,7 @@ export type Props = {
|
||||
|
||||
export default function ProjectsPage({ messages, locale }: Props) {
|
||||
const context = useContext(TokenContext);
|
||||
const [projects, setProjects] = useState([]);
|
||||
const [projects, setProjects] = useState<ProjectType[]>([]);
|
||||
|
||||
useEffect(() => {
|
||||
async function fetchDataEffect() {
|
||||
@@ -47,47 +46,15 @@ export default function ProjectsPage({ messages, locale }: Props) {
|
||||
setEditingProject(null);
|
||||
};
|
||||
|
||||
// delete confirm dialog
|
||||
const [isDeleteConfirmDialogOpen, setIsDeleteConfirmDialogOpen] = useState(false);
|
||||
const [deleteProjectId, setDeleteProjectId] = useState<number | null>(null);
|
||||
const closeDeleteConfirmDialog = () => {
|
||||
setIsDeleteConfirmDialogOpen(false);
|
||||
setDeleteProjectId(null);
|
||||
};
|
||||
|
||||
const onSubmit = async (name: string, detail: string, isPublic: boolean) => {
|
||||
if (editingProject) {
|
||||
const updatedProject = await updateProject(context.token.access_token, editingProject.id, name, detail, isPublic);
|
||||
const updatedProjects = projects.map((project) => (project.id === updatedProject.id ? updatedProject : project));
|
||||
setProjects(updatedProjects);
|
||||
} else {
|
||||
const newProject = await createProject(context.token.access_token, name, detail, isPublic);
|
||||
setProjects([...projects, newProject]);
|
||||
const newProject = await createProject(context.token.access_token, name, detail, isPublic);
|
||||
setProjects([...projects, newProject]);
|
||||
|
||||
// refresh project roles
|
||||
context.refreshProjectRoles();
|
||||
}
|
||||
// refresh project roles
|
||||
context.refreshProjectRoles();
|
||||
closeDialog();
|
||||
};
|
||||
|
||||
const onEditClick = (project: ProjectType) => {
|
||||
setEditingProject(project);
|
||||
setIsProjectDialogOpen(true);
|
||||
};
|
||||
|
||||
const onDeleteClick = (projectId: number) => {
|
||||
setDeleteProjectId(projectId);
|
||||
setIsDeleteConfirmDialogOpen(true);
|
||||
};
|
||||
|
||||
const onConfirm = async () => {
|
||||
if (deleteProjectId) {
|
||||
await deleteProject(context.token.access_token, deleteProjectId);
|
||||
setProjects(projects.filter((project) => project.id !== deleteProjectId));
|
||||
closeDeleteConfirmDialog();
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="container mx-auto max-w-3xl pt-16 px-6 flex-grow">
|
||||
<div className="w-full p-3 flex items-center justify-between">
|
||||
@@ -99,13 +66,7 @@ export default function ProjectsPage({ messages, locale }: Props) {
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<ProjectsTable
|
||||
projects={projects}
|
||||
onEditProject={onEditClick}
|
||||
onDeleteProject={onDeleteClick}
|
||||
messages={messages}
|
||||
locale={locale}
|
||||
/>
|
||||
<ProjectsTable projects={projects} messages={messages} locale={locale} />
|
||||
|
||||
<ProjectDialog
|
||||
isOpen={isProjectDialogOpen}
|
||||
@@ -114,15 +75,6 @@ export default function ProjectsPage({ messages, locale }: Props) {
|
||||
onSubmit={onSubmit}
|
||||
messages={messages}
|
||||
/>
|
||||
|
||||
<DeleteConfirmDialog
|
||||
isOpen={isDeleteConfirmDialogOpen}
|
||||
onCancel={closeDeleteConfirmDialog}
|
||||
onConfirm={onConfirm}
|
||||
closeText={messages.close}
|
||||
confirmText={messages.areYouSure}
|
||||
deleteText={messages.delete}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,39 +1,22 @@
|
||||
import { useState, useMemo, useCallback } from 'react';
|
||||
import {
|
||||
Table,
|
||||
TableHeader,
|
||||
TableColumn,
|
||||
TableBody,
|
||||
TableRow,
|
||||
TableCell,
|
||||
Button,
|
||||
DropdownTrigger,
|
||||
Dropdown,
|
||||
DropdownMenu,
|
||||
DropdownItem,
|
||||
SortDescriptor,
|
||||
} from '@nextui-org/react';
|
||||
import { Table, TableHeader, TableColumn, TableBody, TableRow, TableCell, SortDescriptor } from '@nextui-org/react';
|
||||
import { Link, NextUiLinkClasses } from '@/src/navigation';
|
||||
import { MoreVertical } from 'lucide-react';
|
||||
import { ProjectType, ProjectsMessages } from '@/types/project';
|
||||
import dayjs from 'dayjs';
|
||||
import PublicityChip from '@/components/PublicityChip';
|
||||
|
||||
type Props = {
|
||||
projects: ProjectType[];
|
||||
onEditProject: (project: ProjectType) => void;
|
||||
onDeleteProject: (projectId: number) => void;
|
||||
messages: ProjectsMessages;
|
||||
locale: string;
|
||||
};
|
||||
|
||||
export default function ProjectsTable({ projects, onEditProject, onDeleteProject, messages, locale }: Props) {
|
||||
export default function ProjectsTable({ projects, messages, locale }: Props) {
|
||||
const headerColumns = [
|
||||
{ name: messages.id, uid: 'id', sortable: true },
|
||||
{ name: messages.publicity, uid: 'isPublic', sortable: true },
|
||||
{ name: messages.name, uid: 'name', sortable: true },
|
||||
{ name: messages.lastUpdate, uid: 'updatedAt', sortable: true },
|
||||
{ name: messages.actions, uid: 'actions' },
|
||||
];
|
||||
|
||||
const [sortDescriptor, setSortDescriptor] = useState<SortDescriptor>({
|
||||
@@ -78,22 +61,6 @@ export default function ProjectsTable({ projects, onEditProject, onDeleteProject
|
||||
);
|
||||
case 'updatedAt':
|
||||
return <span>{dayjs(cellValue).format('YYYY/MM/DD HH:mm')}</span>;
|
||||
case 'actions':
|
||||
return (
|
||||
<Dropdown>
|
||||
<DropdownTrigger>
|
||||
<Button isIconOnly radius="full" size="sm" variant="light">
|
||||
<MoreVertical size={16} />
|
||||
</Button>
|
||||
</DropdownTrigger>
|
||||
<DropdownMenu aria-label="project actions">
|
||||
<DropdownItem onClick={() => onEditProject(project)}>{messages.editProject}</DropdownItem>
|
||||
<DropdownItem className="text-danger" onClick={() => onDeleteProject(project.id)}>
|
||||
{messages.deleteProject}
|
||||
</DropdownItem>
|
||||
</DropdownMenu>
|
||||
</Dropdown>
|
||||
);
|
||||
default:
|
||||
return cellValue;
|
||||
}
|
||||
|
||||
@@ -7,14 +7,11 @@ export default function Page(params: { locale: string }) {
|
||||
projectList: t('projectList'),
|
||||
project: t('project'),
|
||||
newProject: t('new_project'),
|
||||
editProject: t('edit_project'),
|
||||
deleteProject: t('delete_project'),
|
||||
id: t('id'),
|
||||
publicity: t('publicity'),
|
||||
name: t('name'),
|
||||
detail: t('detail'),
|
||||
lastUpdate: t('last_update'),
|
||||
actions: t('actions'),
|
||||
projectName: t('project_name'),
|
||||
projectDetail: t('project_detail'),
|
||||
public: t('public'),
|
||||
@@ -22,11 +19,8 @@ export default function Page(params: { locale: string }) {
|
||||
ifYouMakePublic: t('if_you_make_public'),
|
||||
close: t('close'),
|
||||
create: t('create'),
|
||||
update: t('update'),
|
||||
pleaseEnter: t('please_enter'),
|
||||
noProjectsFound: t('no_projects_found'),
|
||||
areYouSure: t('are_you_sure'),
|
||||
delete: t('delete'),
|
||||
};
|
||||
return (
|
||||
<>
|
||||
|
||||
Reference in New Issue
Block a user