Merge branch 'main' of github.com:xuqssq/uppmkt-admin
This commit is contained in:
@@ -42,12 +42,35 @@ export const useTeams = () => {
|
||||
}
|
||||
};
|
||||
|
||||
// 创建团队前检查类型是否已存在
|
||||
const checkTeamTypeExists = async (type) => {
|
||||
try {
|
||||
const {data} = await supabaseService.select('teams', {
|
||||
filter: {
|
||||
deleted_at: { is: null },
|
||||
'attributes->>type': { eq: type }
|
||||
}
|
||||
});
|
||||
return data.length > 0;
|
||||
} catch (error) {
|
||||
console.error('检查团队类型失败:', error);
|
||||
throw error;
|
||||
}
|
||||
};
|
||||
|
||||
// 创建团队
|
||||
const createTeam = async (values) => {
|
||||
try {
|
||||
if (values.type) {
|
||||
const result = await checkTeamTypeExists(values.type);
|
||||
if (result) {
|
||||
throw new Error(`团队类型 "${values.type}" 已存在,请使用其他类型名称`);
|
||||
}
|
||||
}
|
||||
const newTeam = await supabaseService.insert('teams', {
|
||||
name: values.name,
|
||||
description: values.description
|
||||
description: values.description,
|
||||
attributes: { type: values.type }
|
||||
});
|
||||
|
||||
// 创建团队成员关系
|
||||
|
||||
@@ -41,7 +41,12 @@ export const TeamForm = ({ form }) => {
|
||||
>
|
||||
<Input placeholder="请输入团队名称" />
|
||||
</Form.Item>
|
||||
|
||||
<Form.Item
|
||||
name="type"
|
||||
label="项目归属"
|
||||
>
|
||||
<Input placeholder="请输入项目归属" />
|
||||
</Form.Item>
|
||||
<Form.Item
|
||||
name="avatarUrl"
|
||||
label="团队头像"
|
||||
|
||||
@@ -2,7 +2,8 @@ import React, { useState, useEffect } from 'react';
|
||||
import { Modal,Button, Form, Input, Select, message } from 'antd';
|
||||
import { MembershipTable } from './MembershipTable';
|
||||
import { supabaseService } from '@/hooks/supabaseService';
|
||||
|
||||
import { supabase } from '@/config/supabase';
|
||||
import { v4 as uuidv4 } from "uuid";
|
||||
const { Option } = Select;
|
||||
|
||||
export const ExpandedMemberships = ({ teamId }) => {
|
||||
@@ -69,17 +70,26 @@ export const ExpandedMemberships = ({ teamId }) => {
|
||||
}
|
||||
};
|
||||
|
||||
const handleAdd = () => {
|
||||
const handleAdd = (value) => {
|
||||
handleModalOk(value)
|
||||
setIsModalVisible(true);
|
||||
form.resetFields();
|
||||
};
|
||||
|
||||
const handleModalOk = async () => {
|
||||
const handleModalOk = async (values) => {
|
||||
try {
|
||||
const values = await form.validateFields();
|
||||
const { data: users, error: userError } = await supabase
|
||||
.from('users')
|
||||
.select('id, email')
|
||||
.eq('email', values.email)
|
||||
.single();
|
||||
if (userError || users.length===0) {
|
||||
throw new Error('未找到该用户');
|
||||
}
|
||||
await supabaseService.insert('team_membership', {
|
||||
id:uuidv4(),
|
||||
team_id: teamId,
|
||||
user_id: values.user_id,
|
||||
user_id: users.id,
|
||||
role: values.role,
|
||||
is_creator: false
|
||||
});
|
||||
@@ -88,7 +98,7 @@ export const ExpandedMemberships = ({ teamId }) => {
|
||||
message.success('成员已添加');
|
||||
await loadMemberships();
|
||||
} catch (error) {
|
||||
message.error('添加成员失败');
|
||||
message.error(error.message || '添加成员失败');
|
||||
console.error('Add failed:', error);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1,12 +1,14 @@
|
||||
import React, { useState } from 'react';
|
||||
import { Table, Button, Space, Popconfirm, Tag, Form } from 'antd';
|
||||
import { Table, Button, Space, Popconfirm, Tag, Form, Modal, Input, Select } from 'antd';
|
||||
import { EditOutlined, DeleteOutlined, SaveOutlined, CloseOutlined, PlusOutlined } from '@ant-design/icons';
|
||||
import { EditableMembershipCell } from './EditableMembershipCell';
|
||||
import { roleColors } from '../constants/teamConstants';
|
||||
import { message } from 'antd';
|
||||
|
||||
export const MembershipTable = ({ memberships, onUpdate, onDelete, onAdd }) => {
|
||||
const [form] = Form.useForm();
|
||||
const [editingKey, setEditingKey] = useState('');
|
||||
const [addModalVisible, setAddModalVisible] = useState(false);
|
||||
|
||||
const isEditing = (record) => record.id === editingKey;
|
||||
|
||||
@@ -38,7 +40,6 @@ export const MembershipTable = ({ memberships, onUpdate, onDelete, onAdd }) => {
|
||||
render: (user) => (
|
||||
<div className="flex flex-col">
|
||||
<span className="font-medium">{user?.email}</span>
|
||||
<span className="text-gray-500 text-sm">{user?.email}</span>
|
||||
</div>
|
||||
),
|
||||
},
|
||||
@@ -137,16 +138,71 @@ export const MembershipTable = ({ memberships, onUpdate, onDelete, onAdd }) => {
|
||||
};
|
||||
});
|
||||
|
||||
const AddMemberModal = ({ visible, onCancel, onAdd }) => {
|
||||
const [loading, setLoading] = useState(false);
|
||||
|
||||
const handleSubmit = async () => {
|
||||
try {
|
||||
setLoading(true);
|
||||
const values = await form.validateFields();
|
||||
await onAdd(values);
|
||||
form.resetFields();
|
||||
onCancel();
|
||||
} catch (error) {
|
||||
message.error('添加失败: ' + error.message);
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<Modal
|
||||
title="添加成员"
|
||||
open={visible}
|
||||
onCancel={onCancel}
|
||||
onOk={handleSubmit}
|
||||
confirmLoading={loading}
|
||||
>
|
||||
<Form
|
||||
form={form}
|
||||
layout="vertical"
|
||||
>
|
||||
<Form.Item
|
||||
name="email"
|
||||
label="邮箱"
|
||||
rules={[
|
||||
{ required: true, message: '请输入邮箱' },
|
||||
{ type: 'email', message: '请输入有效的邮箱地址' }
|
||||
]}
|
||||
>
|
||||
<Input placeholder='请输入邮箱' />
|
||||
</Form.Item>
|
||||
<Form.Item
|
||||
name="role"
|
||||
label="角色"
|
||||
rules={[{ required: true, message: '请选择角色' }]}
|
||||
initialValue="MEMBER"
|
||||
>
|
||||
<Select>
|
||||
<Select.Option value="OWNER">管理员</Select.Option>
|
||||
<Select.Option value="MEMBER">成员</Select.Option>
|
||||
</Select>
|
||||
</Form.Item>
|
||||
</Form>
|
||||
</Modal>
|
||||
);
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="space-y-4">
|
||||
{/* <Button
|
||||
<Button
|
||||
type="primary"
|
||||
icon={<PlusOutlined />}
|
||||
onClick={onAdd}
|
||||
onClick={() => setAddModalVisible(true)}
|
||||
className="mb-4"
|
||||
>
|
||||
添加成员
|
||||
</Button> */}
|
||||
</Button>
|
||||
<Form form={form} component={false}>
|
||||
<Table
|
||||
scroll={{ x: true }}
|
||||
@@ -161,6 +217,12 @@ export const MembershipTable = ({ memberships, onUpdate, onDelete, onAdd }) => {
|
||||
pagination={false}
|
||||
/>
|
||||
</Form>
|
||||
|
||||
<AddMemberModal
|
||||
visible={addModalVisible}
|
||||
onCancel={() => setAddModalVisible(false)}
|
||||
onAdd={onAdd}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
@@ -77,6 +77,12 @@ export const TeamTable = ({ tableLoading,pagination,dataSource, onTableChange,on
|
||||
</div>
|
||||
),
|
||||
},
|
||||
{
|
||||
title: '归属',
|
||||
dataIndex: 'type',
|
||||
dataIndex: ["attributes", "type"],
|
||||
key: "type",
|
||||
},
|
||||
{
|
||||
title: '描述',
|
||||
dataIndex: 'description',
|
||||
|
||||
@@ -152,7 +152,7 @@ const TeamManagement = () => {
|
||||
await loadTeams({ current: 1 });
|
||||
message.success('创建团队成功');
|
||||
} catch (error) {
|
||||
message.error('创建团队失败');
|
||||
message.error(error.message);
|
||||
} finally {
|
||||
setConfirmLoading(false);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user