框架优化
This commit is contained in:
@@ -3,8 +3,7 @@ import { Layout, Switch, Button, Dropdown } from 'antd';
|
|||||||
import { UserOutlined, LogoutOutlined } from '@ant-design/icons';
|
import { UserOutlined, LogoutOutlined } from '@ant-design/icons';
|
||||||
import { useTheme } from '@/contexts/ThemeContext';
|
import { useTheme } from '@/contexts/ThemeContext';
|
||||||
import { useAuth } from '@/contexts/AuthContext';
|
import { useAuth } from '@/contexts/AuthContext';
|
||||||
import { MenuTrigger } from '../common/MenuTrigger';
|
import { MenuTrigger } from '../Layout/MenuTrigger';
|
||||||
|
|
||||||
const { Header: AntHeader } = Layout;
|
const { Header: AntHeader } = Layout;
|
||||||
|
|
||||||
const Header = ({ collapsed, setCollapsed }) => {
|
const Header = ({ collapsed, setCollapsed }) => {
|
||||||
|
|||||||
@@ -1,18 +1,17 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { RocketOutlined } from '@ant-design/icons';
|
import { RocketOutlined } from '@ant-design/icons';
|
||||||
|
import { Typography } from 'antd';
|
||||||
|
|
||||||
|
const { Text } = Typography;
|
||||||
|
|
||||||
export const Logo = ({ collapsed, isDarkMode }) => (
|
export const Logo = ({ collapsed, isDarkMode }) => (
|
||||||
<div className="logo">
|
<div className="logo">
|
||||||
<div className="flex items-center justify-center gap-2">
|
<div className="flex items-center justify-center gap-2">
|
||||||
<RocketOutlined className="text-2xl text-primary-500" />
|
<RocketOutlined className="text-2xl text-primary-500" />
|
||||||
{!collapsed && (
|
{!collapsed && (
|
||||||
<h1 className="text-lg font-semibold m-0" style={{
|
<Text className="text-lg font-semibold m-0" style={{ color: 'var(--primary-color)' }}>
|
||||||
background: 'var(--primary-gradient)',
|
|
||||||
WebkitBackgroundClip: 'text',
|
|
||||||
WebkitTextFillColor: 'transparent'
|
|
||||||
}}>
|
|
||||||
Uppeta
|
Uppeta
|
||||||
</h1>
|
</Text>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ import { Layout, Menu } from 'antd';
|
|||||||
import { useNavigate, useLocation } from 'react-router-dom';
|
import { useNavigate, useLocation } from 'react-router-dom';
|
||||||
import { useTheme } from '@/contexts/ThemeContext';
|
import { useTheme } from '@/contexts/ThemeContext';
|
||||||
import { getMenuItems } from '@/utils/menuUtils';
|
import { getMenuItems } from '@/utils/menuUtils';
|
||||||
import { Logo } from '@/components/common/Logo';
|
import { Logo } from '@/components/Layout/Logo';
|
||||||
|
|
||||||
const { Sider } = Layout;
|
const { Sider } = Layout;
|
||||||
|
|
||||||
|
|||||||
@@ -1,18 +0,0 @@
|
|||||||
import React from 'react';
|
|
||||||
import { Table } from 'antd';
|
|
||||||
|
|
||||||
export const BaseTable = ({
|
|
||||||
columns,
|
|
||||||
dataSource,
|
|
||||||
loading = false,
|
|
||||||
rowKey = 'id',
|
|
||||||
...props
|
|
||||||
}) => (
|
|
||||||
<Table
|
|
||||||
columns={columns}
|
|
||||||
dataSource={dataSource}
|
|
||||||
loading={loading}
|
|
||||||
rowKey={rowKey}
|
|
||||||
{...props}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
@@ -1,17 +0,0 @@
|
|||||||
import React from 'react';
|
|
||||||
|
|
||||||
export const Icon = ({ name, className = '', style = {} }) => (
|
|
||||||
<span
|
|
||||||
className={`material-symbols-rounded ${className}`}
|
|
||||||
style={{
|
|
||||||
fontSize: '20px',
|
|
||||||
background: 'var(--primary-gradient)',
|
|
||||||
WebkitBackgroundClip: 'text',
|
|
||||||
WebkitTextFillColor: 'transparent',
|
|
||||||
fontVariationSettings: "'FILL' 1, 'wght' 400, 'GRAD' 200, 'opsz' 20",
|
|
||||||
...style
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{name}
|
|
||||||
</span>
|
|
||||||
);
|
|
||||||
@@ -1,21 +0,0 @@
|
|||||||
import React from 'react';
|
|
||||||
|
|
||||||
export const Logo = ({ collapsed, isDarkMode }) => (
|
|
||||||
<div className="logo">
|
|
||||||
<div className="flex items-center justify-center gap-2">
|
|
||||||
<span className="material-symbols-rounded text-primary-500">
|
|
||||||
rocket_launch
|
|
||||||
</span>
|
|
||||||
<h1
|
|
||||||
style={{
|
|
||||||
color: isDarkMode ? '#fff' : '#000',
|
|
||||||
fontSize: collapsed ? '14px' : '18px',
|
|
||||||
margin: 0,
|
|
||||||
display: collapsed ? 'none' : 'block',
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
Uppeta
|
|
||||||
</h1>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
@@ -1,14 +0,0 @@
|
|||||||
import React from 'react';
|
|
||||||
import { Button } from 'antd';
|
|
||||||
import { PlusOutlined } from '@ant-design/icons';
|
|
||||||
|
|
||||||
export const PageHeader = ({ title, onAdd, addButtonText = '新增' }) => (
|
|
||||||
<div className="flex justify-between items-center mb-4">
|
|
||||||
<h1 className="text-2xl font-bold">{title}</h1>
|
|
||||||
{onAdd && (
|
|
||||||
<Button type="primary" icon={<PlusOutlined />} onClick={onAdd}>
|
|
||||||
{addButtonText}
|
|
||||||
</Button>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
import { supabase } from '@/config/supabase'
|
import { supabase } from '@/config/supabase'
|
||||||
|
|
||||||
class SupabaseService {
|
class SupabaseService {
|
||||||
async get(table, options = {}) {
|
async select(table, options = {}) {
|
||||||
try {
|
try {
|
||||||
let query = supabase
|
let query = supabase
|
||||||
.from(table)
|
.from(table)
|
||||||
@@ -96,6 +96,26 @@ class SupabaseService {
|
|||||||
throw error
|
throw error
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// 通用 UPSERT 请求
|
||||||
|
async upsert(table, data, onConflict) {
|
||||||
|
try {
|
||||||
|
let query = supabase
|
||||||
|
.from(table)
|
||||||
|
.upsert(data)
|
||||||
|
.select()
|
||||||
|
|
||||||
|
if (onConflict) {
|
||||||
|
query = query.onConflict(onConflict)
|
||||||
|
}
|
||||||
|
|
||||||
|
const { data: result, error } = await query
|
||||||
|
if (error) throw error
|
||||||
|
return result
|
||||||
|
} catch (error) {
|
||||||
|
console.error(`Error upserting into ${table}:`, error.message)
|
||||||
|
throw error
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export const supabaseService = new SupabaseService()
|
export const supabaseService = new SupabaseService()
|
||||||
@@ -10,7 +10,7 @@ export const useTeamMembership = (teamId) => {
|
|||||||
|
|
||||||
setLoading(true);
|
setLoading(true);
|
||||||
try {
|
try {
|
||||||
const result = await supabaseService.get('team_memberships', {
|
const result = await SupabaseService.select('team_memberships', {
|
||||||
select: '*',
|
select: '*',
|
||||||
relations: {
|
relations: {
|
||||||
user: 'id, email, name'
|
user: 'id, email, name'
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ export const useTeams = () => {
|
|||||||
// 获取团队列表
|
// 获取团队列表
|
||||||
const fetchTeams = async (params = {}) => {
|
const fetchTeams = async (params = {}) => {
|
||||||
try {
|
try {
|
||||||
const result = await supabaseService.get('teams', {
|
const result = await SupabaseService.select('teams', {
|
||||||
select: `
|
select: `
|
||||||
id,
|
id,
|
||||||
name,
|
name,
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ import { supabaseService } from "@/hooks/supabaseService";
|
|||||||
|
|
||||||
const Login = () => {
|
const Login = () => {
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
const { login, signInWithGoogle, loading } = useAuth();
|
const { login, signInWithGoogle, emailLoading, googleLoading } = useAuth();
|
||||||
const [form] = Form.useForm();
|
const [form] = Form.useForm();
|
||||||
|
|
||||||
const handleLogin = async (values) => {
|
const handleLogin = async (values) => {
|
||||||
@@ -75,6 +75,8 @@ const Login = () => {
|
|||||||
type="primary"
|
type="primary"
|
||||||
htmlType="submit"
|
htmlType="submit"
|
||||||
block
|
block
|
||||||
|
loading={emailLoading}
|
||||||
|
disabled={googleLoading}
|
||||||
className="h-12 rounded-xl text-base font-medium bg-gradient-to-r from-blue-600 to-cyan-500 border-0 hover:from-blue-700 hover:to-cyan-600"
|
className="h-12 rounded-xl text-base font-medium bg-gradient-to-r from-blue-600 to-cyan-500 border-0 hover:from-blue-700 hover:to-cyan-600"
|
||||||
>
|
>
|
||||||
登录
|
登录
|
||||||
@@ -89,7 +91,8 @@ const Login = () => {
|
|||||||
icon={<GoogleOutlined />}
|
icon={<GoogleOutlined />}
|
||||||
block
|
block
|
||||||
onClick={signInWithGoogle}
|
onClick={signInWithGoogle}
|
||||||
loading={loading}
|
loading={googleLoading}
|
||||||
|
disabled={emailLoading}
|
||||||
className="h-12 rounded-xl text-base font-medium mb-6 bg-white dark:bg-gray-700 hover:bg-gray-50 dark:hover:bg-gray-600 border border-gray-200 dark:border-gray-600"
|
className="h-12 rounded-xl text-base font-medium mb-6 bg-white dark:bg-gray-700 hover:bg-gray-50 dark:hover:bg-gray-600 border border-gray-200 dark:border-gray-600"
|
||||||
>
|
>
|
||||||
使用 Google 账号登录
|
使用 Google 账号登录
|
||||||
|
|||||||
@@ -92,7 +92,6 @@ const CustomerPage = () => {
|
|||||||
dataIndex: 'created_at',
|
dataIndex: 'created_at',
|
||||||
key: 'created_at',
|
key: 'created_at',
|
||||||
sorter: true,
|
sorter: true,
|
||||||
width: 180,
|
|
||||||
render: (text) => (
|
render: (text) => (
|
||||||
<span>{new Date(text).toLocaleString('zh-CN', {
|
<span>{new Date(text).toLocaleString('zh-CN', {
|
||||||
year: 'numeric',
|
year: 'numeric',
|
||||||
@@ -106,7 +105,7 @@ const CustomerPage = () => {
|
|||||||
{
|
{
|
||||||
title: '操作',
|
title: '操作',
|
||||||
key: 'action',
|
key: 'action',
|
||||||
width: 150,
|
fixed: 'right',
|
||||||
render: (_, record) => (
|
render: (_, record) => (
|
||||||
<Space size={0}>
|
<Space size={0}>
|
||||||
<Button
|
<Button
|
||||||
@@ -157,6 +156,7 @@ const CustomerPage = () => {
|
|||||||
columns={columns}
|
columns={columns}
|
||||||
dataSource={customers}
|
dataSource={customers}
|
||||||
rowKey="id"
|
rowKey="id"
|
||||||
|
scroll={{ x: true }}
|
||||||
loading={loading}
|
loading={loading}
|
||||||
onChange={handleTableChange}
|
onChange={handleTableChange}
|
||||||
pagination={{
|
pagination={{
|
||||||
|
|||||||
@@ -195,7 +195,7 @@ const QuotationPage = () => {
|
|||||||
{
|
{
|
||||||
title: '操作',
|
title: '操作',
|
||||||
key: 'action',
|
key: 'action',
|
||||||
width: 280,
|
fixed: 'right',
|
||||||
render: (_, record) => (
|
render: (_, record) => (
|
||||||
<Space size={0}>
|
<Space size={0}>
|
||||||
<Button
|
<Button
|
||||||
@@ -321,6 +321,7 @@ const QuotationPage = () => {
|
|||||||
columns={columns}
|
columns={columns}
|
||||||
dataSource={quotations}
|
dataSource={quotations}
|
||||||
rowKey="id"
|
rowKey="id"
|
||||||
|
scroll={{ x: true }}
|
||||||
loading={loadingQuotations}
|
loading={loadingQuotations}
|
||||||
onChange={handleTableChange}
|
onChange={handleTableChange}
|
||||||
pagination={{
|
pagination={{
|
||||||
|
|||||||
@@ -110,7 +110,6 @@ const CategoryDrawer = () => {
|
|||||||
{
|
{
|
||||||
title: '分类名称',
|
title: '分类名称',
|
||||||
dataIndex: ['attributes', 'name'],
|
dataIndex: ['attributes', 'name'],
|
||||||
width: '60%',
|
|
||||||
render: (text, record) => {
|
render: (text, record) => {
|
||||||
const isEditing = record.id === editingKey;
|
const isEditing = record.id === editingKey;
|
||||||
return isEditing ? (
|
return isEditing ? (
|
||||||
@@ -128,7 +127,6 @@ const CategoryDrawer = () => {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: '操作',
|
title: '操作',
|
||||||
width: '40%',
|
|
||||||
render: (_, record) => {
|
render: (_, record) => {
|
||||||
const isEditing = record.id === editingKey;
|
const isEditing = record.id === editingKey;
|
||||||
return isEditing ? (
|
return isEditing ? (
|
||||||
@@ -221,6 +219,7 @@ const CategoryDrawer = () => {
|
|||||||
</Button>
|
</Button>
|
||||||
<Form form={form}>
|
<Form form={form}>
|
||||||
<Table
|
<Table
|
||||||
|
scroll={{ x: true }}
|
||||||
columns={columns}
|
columns={columns}
|
||||||
dataSource={data}
|
dataSource={data}
|
||||||
rowKey="id"
|
rowKey="id"
|
||||||
|
|||||||
@@ -374,7 +374,6 @@ const ServicePage = () => {
|
|||||||
title: "项目名称",
|
title: "项目名称",
|
||||||
dataIndex: "name",
|
dataIndex: "name",
|
||||||
key: "name",
|
key: "name",
|
||||||
width: "25%",
|
|
||||||
render: (text, record) => {
|
render: (text, record) => {
|
||||||
const isEditing = record.key === editingKey;
|
const isEditing = record.key === editingKey;
|
||||||
return isEditing ? (
|
return isEditing ? (
|
||||||
@@ -408,7 +407,6 @@ const ServicePage = () => {
|
|||||||
title: "描述",
|
title: "描述",
|
||||||
dataIndex: "description",
|
dataIndex: "description",
|
||||||
key: "description",
|
key: "description",
|
||||||
width: "25%",
|
|
||||||
render: (text, record) => {
|
render: (text, record) => {
|
||||||
const isEditing = record.key === editingKey;
|
const isEditing = record.key === editingKey;
|
||||||
return isEditing ? (
|
return isEditing ? (
|
||||||
@@ -454,7 +452,6 @@ const ServicePage = () => {
|
|||||||
title: "单价",
|
title: "单价",
|
||||||
dataIndex: "price",
|
dataIndex: "price",
|
||||||
key: "price",
|
key: "price",
|
||||||
width: "15%",
|
|
||||||
render: (price, record) => {
|
render: (price, record) => {
|
||||||
const isEditing = record.key === editingKey;
|
const isEditing = record.key === editingKey;
|
||||||
return isEditing ? (
|
return isEditing ? (
|
||||||
@@ -489,7 +486,6 @@ const ServicePage = () => {
|
|||||||
title: "数量",
|
title: "数量",
|
||||||
dataIndex: "quantity",
|
dataIndex: "quantity",
|
||||||
key: "quantity",
|
key: "quantity",
|
||||||
width: "15%",
|
|
||||||
render: (quantity, record) => {
|
render: (quantity, record) => {
|
||||||
const isEditing = record.key === editingKey;
|
const isEditing = record.key === editingKey;
|
||||||
return isEditing ? (
|
return isEditing ? (
|
||||||
@@ -517,7 +513,6 @@ const ServicePage = () => {
|
|||||||
{
|
{
|
||||||
title: "小计",
|
title: "小计",
|
||||||
key: "subtotal",
|
key: "subtotal",
|
||||||
width: "20%",
|
|
||||||
render: (_, record) => (
|
render: (_, record) => (
|
||||||
<span className="text-blue-600 font-medium">
|
<span className="text-blue-600 font-medium">
|
||||||
¥
|
¥
|
||||||
@@ -534,7 +529,7 @@ const ServicePage = () => {
|
|||||||
{
|
{
|
||||||
title: "操作",
|
title: "操作",
|
||||||
key: "action",
|
key: "action",
|
||||||
width: "150px",
|
fixed: 'right',
|
||||||
render: (_, record) => {
|
render: (_, record) => {
|
||||||
const isEditing = record.key === editingKey;
|
const isEditing = record.key === editingKey;
|
||||||
return isEditing ? (
|
return isEditing ? (
|
||||||
@@ -630,6 +625,7 @@ const ServicePage = () => {
|
|||||||
>
|
>
|
||||||
<Table
|
<Table
|
||||||
columns={itemColumns}
|
columns={itemColumns}
|
||||||
|
scroll={{ x: true }}
|
||||||
dataSource={section.items.map((item, itemIndex) => ({
|
dataSource={section.items.map((item, itemIndex) => ({
|
||||||
...item,
|
...item,
|
||||||
key: `${record.id}-${sectionIndex}-${itemIndex}`,
|
key: `${record.id}-${sectionIndex}-${itemIndex}`,
|
||||||
|
|||||||
@@ -151,28 +151,23 @@ const SectionManagement = () => {
|
|||||||
{
|
{
|
||||||
title: '项目名称',
|
title: '项目名称',
|
||||||
dataIndex: 'name',
|
dataIndex: 'name',
|
||||||
width: '20%',
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: '描述',
|
title: '描述',
|
||||||
dataIndex: 'description',
|
dataIndex: 'description',
|
||||||
width: '25%',
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: '单价',
|
title: '单价',
|
||||||
dataIndex: 'price',
|
dataIndex: 'price',
|
||||||
width: '15%',
|
|
||||||
render: (price) => `¥${price}`
|
render: (price) => `¥${price}`
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: '数量',
|
title: '数量',
|
||||||
dataIndex: 'quantity',
|
dataIndex: 'quantity',
|
||||||
width: '15%',
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: '单位',
|
title: '单位',
|
||||||
dataIndex: 'unit',
|
dataIndex: 'unit',
|
||||||
width: '15%',
|
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
@@ -181,7 +176,6 @@ const SectionManagement = () => {
|
|||||||
{
|
{
|
||||||
title: '项目名称',
|
title: '项目名称',
|
||||||
dataIndex: 'name',
|
dataIndex: 'name',
|
||||||
width: '20%',
|
|
||||||
render: (_, __, index) => (
|
render: (_, __, index) => (
|
||||||
<Form.Item
|
<Form.Item
|
||||||
name={[index, 'name']}
|
name={[index, 'name']}
|
||||||
@@ -194,7 +188,6 @@ const SectionManagement = () => {
|
|||||||
{
|
{
|
||||||
title: '描述',
|
title: '描述',
|
||||||
dataIndex: 'description',
|
dataIndex: 'description',
|
||||||
width: '25%',
|
|
||||||
render: (_, __, index) => (
|
render: (_, __, index) => (
|
||||||
<Form.Item
|
<Form.Item
|
||||||
name={[index, 'description']}
|
name={[index, 'description']}
|
||||||
@@ -207,7 +200,6 @@ const SectionManagement = () => {
|
|||||||
{
|
{
|
||||||
title: '单价',
|
title: '单价',
|
||||||
dataIndex: 'price',
|
dataIndex: 'price',
|
||||||
width: '15%',
|
|
||||||
render: (_, __, index) => (
|
render: (_, __, index) => (
|
||||||
<Form.Item
|
<Form.Item
|
||||||
name={[index, 'price']}
|
name={[index, 'price']}
|
||||||
@@ -225,7 +217,6 @@ const SectionManagement = () => {
|
|||||||
{
|
{
|
||||||
title: '数量',
|
title: '数量',
|
||||||
dataIndex: 'quantity',
|
dataIndex: 'quantity',
|
||||||
width: '15%',
|
|
||||||
render: (_, __, index) => (
|
render: (_, __, index) => (
|
||||||
<Form.Item
|
<Form.Item
|
||||||
name={[index, 'quantity']}
|
name={[index, 'quantity']}
|
||||||
@@ -243,7 +234,6 @@ const SectionManagement = () => {
|
|||||||
{
|
{
|
||||||
title: '单位',
|
title: '单位',
|
||||||
dataIndex: 'unit',
|
dataIndex: 'unit',
|
||||||
width: '15%',
|
|
||||||
render: (_, __, index) => (
|
render: (_, __, index) => (
|
||||||
<Form.Item
|
<Form.Item
|
||||||
name={[index, 'unit']}
|
name={[index, 'unit']}
|
||||||
@@ -268,7 +258,6 @@ const SectionManagement = () => {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: '操作',
|
title: '操作',
|
||||||
width: '10%',
|
|
||||||
render: (_, __, index, { remove }) => (
|
render: (_, __, index, { remove }) => (
|
||||||
<Button
|
<Button
|
||||||
type="link"
|
type="link"
|
||||||
@@ -350,6 +339,7 @@ const SectionManagement = () => {
|
|||||||
</div>
|
</div>
|
||||||
<div className="p-4">
|
<div className="p-4">
|
||||||
<Table
|
<Table
|
||||||
|
scroll={{ x: true }}
|
||||||
dataSource={section.attributes.items}
|
dataSource={section.attributes.items}
|
||||||
columns={drawerColumns}
|
columns={drawerColumns}
|
||||||
pagination={false}
|
pagination={false}
|
||||||
|
|||||||
@@ -88,7 +88,7 @@ const ServiceType = () => {
|
|||||||
<PlusOutlined /> 新增服务类型
|
<PlusOutlined /> 新增服务类型
|
||||||
</Button>
|
</Button>
|
||||||
|
|
||||||
<Table columns={columns} dataSource={data} rowKey="id" />
|
<Table scroll={{ x: true }} columns={columns} dataSource={data} rowKey="id" />
|
||||||
|
|
||||||
<Modal
|
<Modal
|
||||||
title={editingId ? '编辑服务类型' : '新增服务类型'}
|
title={editingId ? '编辑服务类型' : '新增服务类型'}
|
||||||
|
|||||||
@@ -120,7 +120,6 @@ const UnitManagement = () => {
|
|||||||
{
|
{
|
||||||
title: '单位名称',
|
title: '单位名称',
|
||||||
dataIndex: ['attributes', 'name'],
|
dataIndex: ['attributes', 'name'],
|
||||||
width: '60%',
|
|
||||||
render: (text, record) => {
|
render: (text, record) => {
|
||||||
const isEditing = record.id === editingKey;
|
const isEditing = record.id === editingKey;
|
||||||
return isEditing ? (
|
return isEditing ? (
|
||||||
@@ -139,7 +138,6 @@ const UnitManagement = () => {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: '操作',
|
title: '操作',
|
||||||
width: '40%',
|
|
||||||
render: (_, record) => {
|
render: (_, record) => {
|
||||||
const isEditing = record.id === editingKey;
|
const isEditing = record.id === editingKey;
|
||||||
return isEditing ? (
|
return isEditing ? (
|
||||||
@@ -235,6 +233,7 @@ const UnitManagement = () => {
|
|||||||
|
|
||||||
<Form form={form} className="flex-1">
|
<Form form={form} className="flex-1">
|
||||||
<Table
|
<Table
|
||||||
|
scroll={{ x: true }}
|
||||||
dataSource={data}
|
dataSource={data}
|
||||||
columns={columns}
|
columns={columns}
|
||||||
rowKey="id"
|
rowKey="id"
|
||||||
|
|||||||
@@ -74,7 +74,6 @@ const SupplierPage = () => {
|
|||||||
dataIndex: 'created_at',
|
dataIndex: 'created_at',
|
||||||
key: 'created_at',
|
key: 'created_at',
|
||||||
sorter: true,
|
sorter: true,
|
||||||
width: 180,
|
|
||||||
render: (text) => (
|
render: (text) => (
|
||||||
<span>{new Date(text).toLocaleString('zh-CN', {
|
<span>{new Date(text).toLocaleString('zh-CN', {
|
||||||
year: 'numeric',
|
year: 'numeric',
|
||||||
@@ -88,7 +87,7 @@ const SupplierPage = () => {
|
|||||||
{
|
{
|
||||||
title: '操作',
|
title: '操作',
|
||||||
key: 'action',
|
key: 'action',
|
||||||
width: 150,
|
fixed: 'right',
|
||||||
render: (_, record) => (
|
render: (_, record) => (
|
||||||
<Space size={0}>
|
<Space size={0}>
|
||||||
<Button
|
<Button
|
||||||
@@ -136,6 +135,7 @@ const SupplierPage = () => {
|
|||||||
}
|
}
|
||||||
>
|
>
|
||||||
<Table
|
<Table
|
||||||
|
scroll={{ x: true }}
|
||||||
columns={columns}
|
columns={columns}
|
||||||
dataSource={suppliers}
|
dataSource={suppliers}
|
||||||
rowKey="id"
|
rowKey="id"
|
||||||
|
|||||||
@@ -47,7 +47,7 @@ const ResourceTaskForm = () => {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: "操作",
|
title: "操作",
|
||||||
width: 100,
|
|
||||||
render: (_, record, index) => (
|
render: (_, record, index) => (
|
||||||
<Button
|
<Button
|
||||||
type="link"
|
type="link"
|
||||||
@@ -261,6 +261,7 @@ const ResourceTaskForm = () => {
|
|||||||
bordered={false}
|
bordered={false}
|
||||||
>
|
>
|
||||||
<Table
|
<Table
|
||||||
|
scroll={{ x: true }}
|
||||||
dataSource={dataSource}
|
dataSource={dataSource}
|
||||||
columns={columns}
|
columns={columns}
|
||||||
pagination={false}
|
pagination={false}
|
||||||
|
|||||||
@@ -86,7 +86,7 @@ const ResourceTask = () => {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: "操作",
|
title: "操作",
|
||||||
width: 250,
|
fixed: 'right',
|
||||||
key: "action",
|
key: "action",
|
||||||
render: (_, record) => (
|
render: (_, record) => (
|
||||||
<Space size={0}>
|
<Space size={0}>
|
||||||
@@ -146,6 +146,7 @@ const ResourceTask = () => {
|
|||||||
}
|
}
|
||||||
>
|
>
|
||||||
<Table
|
<Table
|
||||||
|
scroll={{ x: true }}
|
||||||
columns={columns}
|
columns={columns}
|
||||||
dataSource={quotations}
|
dataSource={quotations}
|
||||||
rowKey="id"
|
rowKey="id"
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ export const ExpandedMemberships = ({ teamId }) => {
|
|||||||
const loadMemberships = async () => {
|
const loadMemberships = async () => {
|
||||||
try {
|
try {
|
||||||
setLoading(true);
|
setLoading(true);
|
||||||
const { data } = await supabaseService.get('team_membership', {
|
const { data } = await SupabaseService.select('team_membership', {
|
||||||
select: `
|
select: `
|
||||||
id,
|
id,
|
||||||
role,
|
role,
|
||||||
|
|||||||
@@ -149,6 +149,7 @@ export const MembershipTable = ({ memberships, onUpdate, onDelete, onAdd }) => {
|
|||||||
</Button> */}
|
</Button> */}
|
||||||
<Form form={form} component={false}>
|
<Form form={form} component={false}>
|
||||||
<Table
|
<Table
|
||||||
|
scroll={{ x: true }}
|
||||||
components={{
|
components={{
|
||||||
body: {
|
body: {
|
||||||
cell: EditableMembershipCell,
|
cell: EditableMembershipCell,
|
||||||
|
|||||||
@@ -175,7 +175,7 @@ export const TeamTable = ({ tableLoading,pagination,dataSource, onTableChange,on
|
|||||||
return (
|
return (
|
||||||
<Form form={form} component={false}>
|
<Form form={form} component={false}>
|
||||||
<Table
|
<Table
|
||||||
className='w-full'
|
scroll={{ x: true }}
|
||||||
pagination={pagination}
|
pagination={pagination}
|
||||||
loading={loading||tableLoading}
|
loading={loading||tableLoading}
|
||||||
components={{
|
components={{
|
||||||
|
|||||||
@@ -57,7 +57,7 @@ const TeamManagement = () => {
|
|||||||
// 获取团队成员
|
// 获取团队成员
|
||||||
const getTeamMembers = async (teamId) => {
|
const getTeamMembers = async (teamId) => {
|
||||||
try {
|
try {
|
||||||
const result = await supabaseService.get('team_memberships', {
|
const result = await SupabaseService.select('team_memberships', {
|
||||||
select: '*',
|
select: '*',
|
||||||
relations: {
|
relations: {
|
||||||
user: 'id, email, name'
|
user: 'id, email, name'
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { routes } from '@/routes/routes';
|
import { routes } from '@/routes/routes';
|
||||||
import * as AntIcons from '@ant-design/icons';
|
import * as AntIcons from '@ant-design/icons';
|
||||||
import { ColorIcon } from '@/components/common/ColorIcon';
|
import { ColorIcon } from '@/components/Layout/ColorIcon';
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user