feat: add delete button
This commit is contained in:
parent
bc06258a1d
commit
066c9e8895
@ -53,6 +53,15 @@ export async function updateWorkspaceWebsiteInfo(
|
||||
queryClient.resetQueries(['websites', workspaceId]);
|
||||
}
|
||||
|
||||
export async function deleteWorkspaceWebsite(
|
||||
workspaceId: string,
|
||||
websiteId: string
|
||||
) {
|
||||
await request.delete(`/api/workspace/${workspaceId}/website/${websiteId}`);
|
||||
|
||||
queryClient.resetQueries(['websites', workspaceId]);
|
||||
}
|
||||
|
||||
export function useWorspaceWebsites(workspaceId: string) {
|
||||
const { data: websites = [], isLoading } = useQuery(
|
||||
['websites', workspaceId],
|
||||
|
@ -9,10 +9,7 @@ function createRequest() {
|
||||
const ins = axios.create();
|
||||
|
||||
ins.interceptors.request.use(async (val) => {
|
||||
if (
|
||||
['post', 'get'].includes(String(val.method).toLowerCase()) &&
|
||||
!val.headers.Authorization
|
||||
) {
|
||||
if (!val.headers.Authorization) {
|
||||
val.headers.Authorization = `Bearer ${getJWT()}`;
|
||||
}
|
||||
|
||||
|
@ -1,7 +1,8 @@
|
||||
import { Button, Form, Input, message } from 'antd';
|
||||
import { Button, Form, Input, message, Popconfirm, Tabs } from 'antd';
|
||||
import React from 'react';
|
||||
import { useParams } from 'react-router';
|
||||
import { useNavigate, useParams } from 'react-router';
|
||||
import {
|
||||
deleteWorkspaceWebsite,
|
||||
updateWorkspaceWebsiteInfo,
|
||||
useWorkspaceWebsiteInfo,
|
||||
} from '../api/model/website';
|
||||
@ -20,6 +21,7 @@ export const WebsiteInfo: React.FC = React.memo(() => {
|
||||
currentWorkspaceId!,
|
||||
websiteId!
|
||||
);
|
||||
const navigate = useNavigate();
|
||||
|
||||
const [, handleSave] = useRequest(
|
||||
async (values: { name: string; domain: string }) => {
|
||||
@ -32,6 +34,14 @@ export const WebsiteInfo: React.FC = React.memo(() => {
|
||||
}
|
||||
);
|
||||
|
||||
const [, handleDeleteWebsite] = useRequest(async () => {
|
||||
await deleteWorkspaceWebsite(currentWorkspaceId!, websiteId!);
|
||||
|
||||
message.success('Delete Success');
|
||||
|
||||
navigate('/settings/websites');
|
||||
});
|
||||
|
||||
if (!currentWorkspaceId) {
|
||||
return <NoWorkspaceTip />;
|
||||
}
|
||||
@ -55,6 +65,8 @@ export const WebsiteInfo: React.FC = React.memo(() => {
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<Tabs>
|
||||
<Tabs.TabPane key={'detail'} tab={'Detail'}>
|
||||
<Form
|
||||
layout="vertical"
|
||||
initialValues={{
|
||||
@ -70,7 +82,11 @@ export const WebsiteInfo: React.FC = React.memo(() => {
|
||||
<Form.Item label="Name" name="name" rules={[{ required: true }]}>
|
||||
<Input size="large" />
|
||||
</Form.Item>
|
||||
<Form.Item label="Domain" name="domain" rules={[{ required: true }]}>
|
||||
<Form.Item
|
||||
label="Domain"
|
||||
name="domain"
|
||||
rules={[{ required: true }]}
|
||||
>
|
||||
<Input size="large" />
|
||||
</Form.Item>
|
||||
|
||||
@ -80,6 +96,19 @@ export const WebsiteInfo: React.FC = React.memo(() => {
|
||||
</Button>
|
||||
</Form.Item>
|
||||
</Form>
|
||||
</Tabs.TabPane>
|
||||
|
||||
<Tabs.TabPane key={'data'} tab={'Data'}>
|
||||
<Popconfirm
|
||||
title="Delete Website"
|
||||
onConfirm={() => handleDeleteWebsite()}
|
||||
>
|
||||
<Button type="primary" danger={true}>
|
||||
Delete Website
|
||||
</Button>
|
||||
</Popconfirm>
|
||||
</Tabs.TabPane>
|
||||
</Tabs>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
@ -34,7 +34,6 @@ export const Settings: React.FC = React.memo(() => {
|
||||
mode="vertical"
|
||||
items={items}
|
||||
/>
|
||||
{pathname}
|
||||
</div>
|
||||
<div className="w-full md:w-5/6 py-2 px-4">
|
||||
<Routes>
|
||||
|
@ -1,7 +1,7 @@
|
||||
import { Handler } from 'express';
|
||||
import { checkIsWorkspaceUser } from '../model/workspace';
|
||||
import { getWorkspaceUser } from '../model/workspace';
|
||||
|
||||
export function workspacePermission(): Handler {
|
||||
export function workspacePermission(roles: string[] = []): Handler {
|
||||
return async (req, res, next) => {
|
||||
const workspaceId =
|
||||
req.body.workspaceId ?? req.query.workspaceId ?? req.params.workspaceId;
|
||||
@ -16,12 +16,20 @@ export function workspacePermission(): Handler {
|
||||
throw new Error('This middleware should be use after auth()');
|
||||
}
|
||||
|
||||
const isWorkspaceUser = await checkIsWorkspaceUser(workspaceId, userId);
|
||||
const info = await getWorkspaceUser(workspaceId, userId);
|
||||
|
||||
if (!isWorkspaceUser) {
|
||||
if (!info) {
|
||||
throw new Error('Is not workspace user');
|
||||
}
|
||||
|
||||
if (Array.isArray(roles) && roles.length > 0) {
|
||||
if (!roles.includes(info.role)) {
|
||||
throw new Error(
|
||||
`Workspace roles not has this permission, need ${roles}`
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
next();
|
||||
};
|
||||
}
|
||||
|
@ -1,21 +1,23 @@
|
||||
import { prisma } from './_client';
|
||||
|
||||
export async function getWorkspaceUser(workspaceId: string, userId: string) {
|
||||
const info = await prisma.workspacesOnUsers.findFirst({
|
||||
where: {
|
||||
workspaceId,
|
||||
userId,
|
||||
},
|
||||
});
|
||||
|
||||
return info;
|
||||
}
|
||||
|
||||
export async function checkIsWorkspaceUser(
|
||||
workspaceId: string,
|
||||
userId: string
|
||||
) {
|
||||
const workspace = await prisma.workspace.findUnique({
|
||||
where: {
|
||||
id: workspaceId,
|
||||
users: {
|
||||
some: {
|
||||
userId,
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
const info = await getWorkspaceUser(workspaceId, userId);
|
||||
|
||||
if (workspace) {
|
||||
if (info) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
@ -84,3 +86,17 @@ export async function addWorkspaceWebsite(
|
||||
|
||||
return website;
|
||||
}
|
||||
|
||||
export async function deleteWorkspaceWebsite(
|
||||
workspaceId: string,
|
||||
websiteId: string
|
||||
) {
|
||||
const website = await prisma.website.delete({
|
||||
where: {
|
||||
id: websiteId,
|
||||
workspaceId,
|
||||
},
|
||||
});
|
||||
|
||||
return website;
|
||||
}
|
||||
|
@ -4,10 +4,12 @@ import { body, param, query, validate } from '../middleware/validate';
|
||||
import { workspacePermission } from '../middleware/workspace';
|
||||
import {
|
||||
addWorkspaceWebsite,
|
||||
deleteWorkspaceWebsite,
|
||||
getWorkspaceWebsiteInfo,
|
||||
getWorkspaceWebsites,
|
||||
updateWorkspaceWebsiteInfo,
|
||||
} from '../model/workspace';
|
||||
import { ROLES } from '../utils/const';
|
||||
|
||||
export const workspaceRouter = Router();
|
||||
|
||||
@ -128,3 +130,29 @@ workspaceRouter.post(
|
||||
res.json({ website });
|
||||
}
|
||||
);
|
||||
|
||||
workspaceRouter.delete(
|
||||
'/:workspaceId/website/:websiteId',
|
||||
validate(
|
||||
param('workspaceId')
|
||||
.isString()
|
||||
.withMessage('workspaceId should be string')
|
||||
.isUUID()
|
||||
.withMessage('workspaceId should be UUID'),
|
||||
param('websiteId')
|
||||
.isString()
|
||||
.withMessage('workspaceId should be string')
|
||||
.isUUID()
|
||||
.withMessage('workspaceId should be UUID')
|
||||
),
|
||||
auth(),
|
||||
workspacePermission([ROLES.owner]),
|
||||
async (req, res) => {
|
||||
const workspaceId = req.params.workspaceId;
|
||||
const websiteId = req.params.websiteId;
|
||||
|
||||
const website = await deleteWorkspaceWebsite(workspaceId, websiteId);
|
||||
|
||||
res.json({ website });
|
||||
}
|
||||
);
|
||||
|
Loading…
Reference in New Issue
Block a user