perf(format): code format
This commit is contained in:
@@ -6,14 +6,7 @@ import {
|
||||
getDownloadLog,
|
||||
} from "@/components/label/api/workload"
|
||||
import useAuth from "@/components/label/hooks/useAuth"
|
||||
import {
|
||||
ActionIcon,
|
||||
Button,
|
||||
Group,
|
||||
Paper,
|
||||
Stack,
|
||||
Text,
|
||||
} from "@mantine/core"
|
||||
import { ActionIcon, Button, Group, Paper, Stack, Text } from "@mantine/core"
|
||||
import { notifications } from "@mantine/notifications"
|
||||
import { IconDownload, IconFileExport, IconRefresh } from "@tabler/icons-react"
|
||||
import dayjs from "dayjs"
|
||||
@@ -99,7 +92,9 @@ export default function TeamCostPage() {
|
||||
title: "导出时间",
|
||||
width: 200,
|
||||
render: (record) =>
|
||||
record.create_at ? dayjs(record.create_at).format("YYYY-MM-DD HH:mm:ss") : "-",
|
||||
record.create_at
|
||||
? dayjs(record.create_at).format("YYYY-MM-DD HH:mm:ss")
|
||||
: "-",
|
||||
},
|
||||
{ accessor: "file_name", title: "导出文件名", width: 280 },
|
||||
{ accessor: "create_user", title: "操作人", width: 160 },
|
||||
|
||||
@@ -77,7 +77,10 @@ export default function TeamDailypaperPage() {
|
||||
const { isShow } = useAuth()
|
||||
const treeData = useAllUserStore((s) => s.treeData)
|
||||
|
||||
const leaderOptions = useMemo(() => flattenLeaderTree(treeData ?? []), [treeData])
|
||||
const leaderOptions = useMemo(
|
||||
() => flattenLeaderTree(treeData ?? []),
|
||||
[treeData]
|
||||
)
|
||||
|
||||
const defaultFilters = useMemo(() => {
|
||||
return {
|
||||
@@ -116,7 +119,8 @@ export default function TeamDailypaperPage() {
|
||||
})
|
||||
|
||||
const [modalOpened, setModalOpened] = useState(false)
|
||||
const [editingRecord, setEditingRecord] = useState<Daily.DailyWorkList | null>(null)
|
||||
const [editingRecord, setEditingRecord] =
|
||||
useState<Daily.DailyWorkList | null>(null)
|
||||
const [searchExpanded, setSearchExpanded] = useState(false)
|
||||
|
||||
const queryParams = useMemo(() => {
|
||||
@@ -147,7 +151,13 @@ export default function TeamDailypaperPage() {
|
||||
}
|
||||
})
|
||||
return params
|
||||
}, [appliedFilters, page, pageSize, sortStatus.columnAccessor, sortStatus.direction])
|
||||
}, [
|
||||
appliedFilters,
|
||||
page,
|
||||
pageSize,
|
||||
sortStatus.columnAccessor,
|
||||
sortStatus.direction,
|
||||
])
|
||||
|
||||
const load = useCallback(async () => {
|
||||
if (!queryTrigger) return
|
||||
@@ -182,7 +192,9 @@ export default function TeamDailypaperPage() {
|
||||
useEffect(() => {
|
||||
const run = async () => {
|
||||
const res = await getSelfProjectList()
|
||||
setProjectOptions((res ?? []).map((p) => ({ label: p.label, value: String(p.value) })))
|
||||
setProjectOptions(
|
||||
(res ?? []).map((p) => ({ label: p.label, value: String(p.value) }))
|
||||
)
|
||||
}
|
||||
queueMicrotask(run)
|
||||
}, [])
|
||||
@@ -237,7 +249,11 @@ export default function TeamDailypaperPage() {
|
||||
item.obj_type === 0 || item.obj_type === 1
|
||||
? (objTypeTextMap.get(item.obj_type) ?? "-")
|
||||
: "-",
|
||||
item.residual_pm === true ? "正" : item.residual_pm === false ? "负" : "-",
|
||||
item.residual_pm === true
|
||||
? "正"
|
||||
: item.residual_pm === false
|
||||
? "负"
|
||||
: "-",
|
||||
item.start_time ?? "-",
|
||||
item.end_time ?? "-",
|
||||
item.work_time ?? 0,
|
||||
@@ -274,7 +290,8 @@ export default function TeamDailypaperPage() {
|
||||
accessor: "week",
|
||||
title: "星期",
|
||||
width: 90,
|
||||
render: (record) => (record.date ? weekDayText(dayjs(record.date).day()) : "-"),
|
||||
render: (record) =>
|
||||
record.date ? weekDayText(dayjs(record.date).day()) : "-",
|
||||
},
|
||||
{
|
||||
accessor: "set_type",
|
||||
@@ -299,7 +316,8 @@ export default function TeamDailypaperPage() {
|
||||
accessor: "accounting_type",
|
||||
title: "核算方式",
|
||||
width: 140,
|
||||
render: (record) => accountTypeMap.get(record.accounting_type ?? "") ?? "-",
|
||||
render: (record) =>
|
||||
accountTypeMap.get(record.accounting_type ?? "") ?? "-",
|
||||
},
|
||||
{
|
||||
accessor: "project_name",
|
||||
@@ -348,14 +366,23 @@ export default function TeamDailypaperPage() {
|
||||
title: "余量正负",
|
||||
width: 100,
|
||||
render: (record) =>
|
||||
record.residual_pm === true ? "正" : record.residual_pm === false ? "负" : "-",
|
||||
record.residual_pm === true
|
||||
? "正"
|
||||
: record.residual_pm === false
|
||||
? "负"
|
||||
: "-",
|
||||
},
|
||||
{ accessor: "start_time", title: "开始时间", width: 120 },
|
||||
{ accessor: "end_time", title: "结束时间", width: 120 },
|
||||
{ accessor: "work_time", title: "工时", width: 90, sortable: true },
|
||||
{ accessor: "rate", title: "额定倍率", width: 90 },
|
||||
{ accessor: "standard_size", title: "标准量", width: 90, sortable: true },
|
||||
{ accessor: "completed_size", title: "完成量", width: 90, sortable: true },
|
||||
{
|
||||
accessor: "completed_size",
|
||||
title: "完成量",
|
||||
width: 90,
|
||||
sortable: true,
|
||||
},
|
||||
{ accessor: "residual_size", title: "余量", width: 90, sortable: true },
|
||||
{
|
||||
accessor: "residual_work_time",
|
||||
@@ -430,7 +457,9 @@ export default function TeamDailypaperPage() {
|
||||
title: "删除日报",
|
||||
centered: true,
|
||||
children: (
|
||||
<Text size="sm">删除后不可恢复,你确定删除该日报吗?</Text>
|
||||
<Text size="sm">
|
||||
删除后不可恢复,你确定删除该日报吗?
|
||||
</Text>
|
||||
),
|
||||
labels: { confirm: "删除", cancel: "取消" },
|
||||
confirmProps: { color: "red" },
|
||||
@@ -530,7 +559,9 @@ export default function TeamDailypaperPage() {
|
||||
radius="xs"
|
||||
type="date"
|
||||
value={filters.date_start}
|
||||
onChange={(e) => setFilters((s) => ({ ...s, date_start: e.target.value }))}
|
||||
onChange={(e) =>
|
||||
setFilters((s) => ({ ...s, date_start: e.target.value }))
|
||||
}
|
||||
/>
|
||||
<TextInput
|
||||
label="结束日期"
|
||||
@@ -538,7 +569,9 @@ export default function TeamDailypaperPage() {
|
||||
radius="xs"
|
||||
type="date"
|
||||
value={filters.date_end}
|
||||
onChange={(e) => setFilters((s) => ({ ...s, date_end: e.target.value }))}
|
||||
onChange={(e) =>
|
||||
setFilters((s) => ({ ...s, date_end: e.target.value }))
|
||||
}
|
||||
/>
|
||||
<MultiSelect
|
||||
label="员工姓名"
|
||||
@@ -578,7 +611,9 @@ export default function TeamDailypaperPage() {
|
||||
searchable
|
||||
clearable
|
||||
value={filters.set_type ? [filters.set_type] : []}
|
||||
onChange={(v) => setFilters((s) => ({ ...s, set_type: v[0] ?? "" }))}
|
||||
onChange={(v) =>
|
||||
setFilters((s) => ({ ...s, set_type: v[0] ?? "" }))
|
||||
}
|
||||
/>
|
||||
<MultiSelect
|
||||
label="出勤类型"
|
||||
@@ -588,7 +623,9 @@ export default function TeamDailypaperPage() {
|
||||
searchable
|
||||
clearable
|
||||
value={filters.actual_type ? [filters.actual_type] : []}
|
||||
onChange={(v) => setFilters((s) => ({ ...s, actual_type: v[0] ?? "" }))}
|
||||
onChange={(v) =>
|
||||
setFilters((s) => ({ ...s, actual_type: v[0] ?? "" }))
|
||||
}
|
||||
/>
|
||||
<MultiSelect
|
||||
label="工作类别"
|
||||
@@ -598,7 +635,9 @@ export default function TeamDailypaperPage() {
|
||||
searchable
|
||||
clearable
|
||||
value={filters.work_type ? [filters.work_type] : []}
|
||||
onChange={(v) => setFilters((s) => ({ ...s, work_type: v[0] ?? "" }))}
|
||||
onChange={(v) =>
|
||||
setFilters((s) => ({ ...s, work_type: v[0] ?? "" }))
|
||||
}
|
||||
/>
|
||||
<MultiSelect
|
||||
label="核算方式"
|
||||
@@ -620,10 +659,15 @@ export default function TeamDailypaperPage() {
|
||||
searchable
|
||||
clearable
|
||||
value={
|
||||
filters.performance_accounting ? [filters.performance_accounting] : []
|
||||
filters.performance_accounting
|
||||
? [filters.performance_accounting]
|
||||
: []
|
||||
}
|
||||
onChange={(v) =>
|
||||
setFilters((s) => ({ ...s, performance_accounting: v[0] ?? "" }))
|
||||
setFilters((s) => ({
|
||||
...s,
|
||||
performance_accounting: v[0] ?? "",
|
||||
}))
|
||||
}
|
||||
/>
|
||||
<MultiSelect
|
||||
@@ -634,7 +678,9 @@ export default function TeamDailypaperPage() {
|
||||
searchable
|
||||
clearable
|
||||
value={filters.obj_type ? [filters.obj_type] : []}
|
||||
onChange={(v) => setFilters((s) => ({ ...s, obj_type: v[0] ?? "" }))}
|
||||
onChange={(v) =>
|
||||
setFilters((s) => ({ ...s, obj_type: v[0] ?? "" }))
|
||||
}
|
||||
/>
|
||||
</SimpleGrid>
|
||||
</Collapse>
|
||||
@@ -656,10 +702,7 @@ export default function TeamDailypaperPage() {
|
||||
}}>
|
||||
<Stack gap={12} align="stretch" style={{ flex: 1, minHeight: 0 }}>
|
||||
<Flex justify="space-between" align="center" w="100%">
|
||||
<Button
|
||||
size="xs"
|
||||
radius="xs"
|
||||
onClick={handleExportData}>
|
||||
<Button size="xs" radius="xs" onClick={handleExportData}>
|
||||
导出日报
|
||||
</Button>
|
||||
<ActionIcon onClick={load} variant="transparent">
|
||||
@@ -704,7 +747,9 @@ export default function TeamDailypaperPage() {
|
||||
<Group gap="md">
|
||||
<Text size="sm">工时:{summaryText.total_work_time}</Text>
|
||||
<Text size="sm">标准量:{summaryText.total_standard_size}</Text>
|
||||
<Text size="sm">完成量:{summaryText.total_completed_size}</Text>
|
||||
<Text size="sm">
|
||||
完成量:{summaryText.total_completed_size}
|
||||
</Text>
|
||||
<Text size="sm">余量:{summaryText.total_residual_size}</Text>
|
||||
<Text size="sm">
|
||||
余量工时:{summaryText.total_residual_work_time}
|
||||
|
||||
@@ -1,14 +1,7 @@
|
||||
"use client"
|
||||
|
||||
import { getUserGroupAll, userAdd } from "@/components/label/api/user"
|
||||
import {
|
||||
Button,
|
||||
Group,
|
||||
Modal,
|
||||
Select,
|
||||
Stack,
|
||||
TextInput,
|
||||
} from "@mantine/core"
|
||||
import { Button, Group, Modal, Select, Stack, TextInput } from "@mantine/core"
|
||||
import { useForm } from "@mantine/form"
|
||||
import { notifications } from "@mantine/notifications"
|
||||
import { useEffect, useState } from "react"
|
||||
@@ -22,9 +15,9 @@ export default function CreateUserModal({
|
||||
opened,
|
||||
onCloseAction,
|
||||
}: ComponentProps) {
|
||||
const [groupOpts, setGroupOpts] = useState<Array<{ label: string; value: string }>>(
|
||||
[]
|
||||
)
|
||||
const [groupOpts, setGroupOpts] = useState<
|
||||
Array<{ label: string; value: string }>
|
||||
>([])
|
||||
const [submitting, setSubmitting] = useState(false)
|
||||
|
||||
const form = useForm({
|
||||
@@ -116,11 +109,7 @@ export default function CreateUserModal({
|
||||
onClick={() => onCloseAction()}>
|
||||
取消
|
||||
</Button>
|
||||
<Button
|
||||
type="submit"
|
||||
size="xs"
|
||||
radius="xs"
|
||||
loading={submitting}>
|
||||
<Button type="submit" size="xs" radius="xs" loading={submitting}>
|
||||
确定
|
||||
</Button>
|
||||
</Group>
|
||||
|
||||
@@ -2,14 +2,7 @@
|
||||
|
||||
import { getUserGroupAll, userEditById } from "@/components/label/api/user"
|
||||
import { User } from "@/components/label/api/user/typing"
|
||||
import {
|
||||
Button,
|
||||
Group,
|
||||
Modal,
|
||||
Select,
|
||||
Stack,
|
||||
TextInput,
|
||||
} from "@mantine/core"
|
||||
import { Button, Group, Modal, Select, Stack, TextInput } from "@mantine/core"
|
||||
import { useForm } from "@mantine/form"
|
||||
import { notifications } from "@mantine/notifications"
|
||||
import { useEffect, useMemo, useState } from "react"
|
||||
@@ -25,9 +18,9 @@ export default function EditUserModal({
|
||||
data,
|
||||
onCloseAction,
|
||||
}: ComponentProps) {
|
||||
const [groupOpts, setGroupOpts] = useState<Array<{ label: string; value: string }>>(
|
||||
[]
|
||||
)
|
||||
const [groupOpts, setGroupOpts] = useState<
|
||||
Array<{ label: string; value: string }>
|
||||
>([])
|
||||
const [submitting, setSubmitting] = useState(false)
|
||||
|
||||
const groupValueByName = useMemo(() => {
|
||||
@@ -153,11 +146,7 @@ export default function EditUserModal({
|
||||
onClick={() => onCloseAction()}>
|
||||
取消
|
||||
</Button>
|
||||
<Button
|
||||
type="submit"
|
||||
size="xs"
|
||||
radius="xs"
|
||||
loading={submitting}>
|
||||
<Button type="submit" size="xs" radius="xs" loading={submitting}>
|
||||
确定
|
||||
</Button>
|
||||
</Group>
|
||||
|
||||
@@ -121,7 +121,9 @@ export default function ImportModal({ opened, onCloseAction }: ComponentProps) {
|
||||
XLSX.utils.book_append_sheet(wb, ws, "用户信息")
|
||||
wb.Sheets["用户信息"]["!rows"] = [{ hpx: 20 }, { hpx: 20 }, { hpx: 20 }]
|
||||
wb.Sheets["用户信息"]["!cols"] = [{ wch: 20 }, { wch: 20 }, { wch: 20 }]
|
||||
wb.Sheets["用户信息"]["!merges"] = [{ s: { c: 0, r: 0 }, e: { c: 2, r: 2 } }]
|
||||
wb.Sheets["用户信息"]["!merges"] = [
|
||||
{ s: { c: 0, r: 0 }, e: { c: 2, r: 2 } },
|
||||
]
|
||||
if (wb.Sheets["用户信息"]["A1"]) {
|
||||
wb.Sheets["用户信息"]["A1"].s = { alignment: { wrapText: true } }
|
||||
}
|
||||
@@ -251,11 +253,7 @@ export default function ImportModal({ opened, onCloseAction }: ComponentProps) {
|
||||
}}>
|
||||
取消
|
||||
</Button>
|
||||
<Button
|
||||
size="xs"
|
||||
radius="xs"
|
||||
onClick={submit}
|
||||
loading={submitting}>
|
||||
<Button size="xs" radius="xs" onClick={submit} loading={submitting}>
|
||||
开始导入
|
||||
</Button>
|
||||
</Group>
|
||||
|
||||
@@ -16,7 +16,7 @@ import {
|
||||
} from "@mantine/core"
|
||||
import { modals } from "@mantine/modals"
|
||||
import { notifications } from "@mantine/notifications"
|
||||
import { IconEdit, IconPlus, IconRefresh, IconSearch, IconUpload } from "@tabler/icons-react"
|
||||
import { IconEdit, IconRefresh, IconSearch } from "@tabler/icons-react"
|
||||
import { DataTable, DataTableColumn } from "mantine-datatable"
|
||||
import { useCallback, useEffect, useMemo, useState } from "react"
|
||||
import CreateUserModal from "./components/CreateUserModal"
|
||||
@@ -193,7 +193,7 @@ export default function TeamEmployeePage() {
|
||||
重置
|
||||
</Button>
|
||||
</Group>
|
||||
<Group>
|
||||
{/* <Group>
|
||||
{isShow("add") ? (
|
||||
<Button
|
||||
size="xs"
|
||||
@@ -213,7 +213,7 @@ export default function TeamEmployeePage() {
|
||||
批量导入
|
||||
</Button>
|
||||
) : null}
|
||||
</Group>
|
||||
</Group> */}
|
||||
</Group>
|
||||
</Paper>
|
||||
|
||||
|
||||
@@ -19,12 +19,12 @@ interface ComponentProps {
|
||||
export default function CreateModal({ opened, onCloseAction }: ComponentProps) {
|
||||
const storeUserOpts = useAllUserStore((s) => s.userOpts)
|
||||
|
||||
const [groupOpts, setGroupOpts] = useState<Array<{ label: string; value: string }>>(
|
||||
[]
|
||||
)
|
||||
const [userOpts, setUserOpts] = useState<Array<{ label: string; value: string }>>(
|
||||
[]
|
||||
)
|
||||
const [groupOpts, setGroupOpts] = useState<
|
||||
Array<{ label: string; value: string }>
|
||||
>([])
|
||||
const [userOpts, setUserOpts] = useState<
|
||||
Array<{ label: string; value: string }>
|
||||
>([])
|
||||
const [submitting, setSubmitting] = useState(false)
|
||||
|
||||
const finalUserOpts = useMemo(() => {
|
||||
@@ -51,7 +51,9 @@ export default function CreateModal({ opened, onCloseAction }: ComponentProps) {
|
||||
getUserAll(),
|
||||
])
|
||||
setGroupOpts(groupRes ?? [])
|
||||
setUserOpts((userRes ?? []).map((u) => ({ label: u.label, value: String(u.value) })))
|
||||
setUserOpts(
|
||||
(userRes ?? []).map((u) => ({ label: u.label, value: String(u.value) }))
|
||||
)
|
||||
}
|
||||
queueMicrotask(run)
|
||||
}, [opened])
|
||||
@@ -125,11 +127,7 @@ export default function CreateModal({ opened, onCloseAction }: ComponentProps) {
|
||||
onClick={() => onCloseAction()}>
|
||||
取消
|
||||
</Button>
|
||||
<Button
|
||||
type="submit"
|
||||
size="xs"
|
||||
radius="xs"
|
||||
loading={submitting}>
|
||||
<Button type="submit" size="xs" radius="xs" loading={submitting}>
|
||||
确定
|
||||
</Button>
|
||||
</Group>
|
||||
|
||||
@@ -15,7 +15,12 @@ import {
|
||||
TextInput,
|
||||
} from "@mantine/core"
|
||||
import { notifications } from "@mantine/notifications"
|
||||
import { IconPlus, IconRefresh, IconSearch, IconUserCircle } from "@tabler/icons-react"
|
||||
import {
|
||||
IconPlus,
|
||||
IconRefresh,
|
||||
IconSearch,
|
||||
IconUserCircle,
|
||||
} from "@tabler/icons-react"
|
||||
import { useCallback, useEffect, useMemo, useState } from "react"
|
||||
import CreateModal from "./components/CreateModal"
|
||||
|
||||
|
||||
@@ -37,7 +37,8 @@ export default function TeamSyncServerPage() {
|
||||
const [appliedOnline, setAppliedOnline] = useState<string | null>(null)
|
||||
|
||||
const [open, setOpen] = useState(false)
|
||||
const [editingRecord, setEditingRecord] = useState<Response.SyncServer | null>(null)
|
||||
const [editingRecord, setEditingRecord] =
|
||||
useState<Response.SyncServer | null>(null)
|
||||
const [editingLocation, setEditingLocation] = useState("")
|
||||
const [submitting, setSubmitting] = useState(false)
|
||||
|
||||
|
||||
@@ -21,7 +21,15 @@ import {
|
||||
} from "@mantine/core"
|
||||
import { modals } from "@mantine/modals"
|
||||
import { notifications } from "@mantine/notifications"
|
||||
import { IconPlayerPause, IconPlayerPlay, IconPlus, IconRefresh, IconSearch, IconTrash, IconX } from "@tabler/icons-react"
|
||||
import {
|
||||
IconPlayerPause,
|
||||
IconPlayerPlay,
|
||||
IconPlus,
|
||||
IconRefresh,
|
||||
IconSearch,
|
||||
IconTrash,
|
||||
IconX,
|
||||
} from "@tabler/icons-react"
|
||||
import { DataTable, DataTableColumn } from "mantine-datatable"
|
||||
import { useCallback, useEffect, useMemo, useState } from "react"
|
||||
|
||||
@@ -56,11 +64,15 @@ export default function TeamSyncTaskPage() {
|
||||
const [appliedProjectId, setAppliedProjectId] = useState<string | null>(null)
|
||||
const [appliedServerId, setAppliedServerId] = useState<string | null>(null)
|
||||
|
||||
const [projectOpt, setProjectOpt] = useState<Array<{ label: string; value: string }>>([])
|
||||
const [serverAllOpt, setServerAllOpt] = useState<Array<{ label: string; value: string }>>([])
|
||||
const [serverOnlineOpt, setServerOnlineOpt] = useState<Array<{ label: string; value: string }>>(
|
||||
[]
|
||||
)
|
||||
const [projectOpt, setProjectOpt] = useState<
|
||||
Array<{ label: string; value: string }>
|
||||
>([])
|
||||
const [serverAllOpt, setServerAllOpt] = useState<
|
||||
Array<{ label: string; value: string }>
|
||||
>([])
|
||||
const [serverOnlineOpt, setServerOnlineOpt] = useState<
|
||||
Array<{ label: string; value: string }>
|
||||
>([])
|
||||
const [serverMap, setServerMap] = useState<Map<number, string>>(new Map())
|
||||
|
||||
const [open, setOpen] = useState(false)
|
||||
@@ -78,7 +90,9 @@ export default function TeamSyncTaskPage() {
|
||||
setProjectOpt(projects.map((p) => ({ label: p.name, value: String(p.id) })))
|
||||
|
||||
const allServers = serverRes ?? []
|
||||
setServerAllOpt(allServers.map((s) => ({ label: s.ip, value: String(s.id) })))
|
||||
setServerAllOpt(
|
||||
allServers.map((s) => ({ label: s.ip, value: String(s.id) }))
|
||||
)
|
||||
setServerOnlineOpt(
|
||||
allServers
|
||||
.filter((s) => s.is_online)
|
||||
@@ -122,7 +136,11 @@ export default function TeamSyncTaskPage() {
|
||||
load()
|
||||
}, [load])
|
||||
|
||||
const performStatusAction = async (id: number, statusTo: number, successText: string) => {
|
||||
const performStatusAction = async (
|
||||
id: number,
|
||||
statusTo: number,
|
||||
successText: string
|
||||
) => {
|
||||
try {
|
||||
await updateSyncTaskStatus(id, statusTo)
|
||||
notifications.show({
|
||||
@@ -156,7 +174,9 @@ export default function TeamSyncTaskPage() {
|
||||
title: "同步服务IP",
|
||||
width: 160,
|
||||
render: (record) =>
|
||||
record.sync_server_id ? serverMap.get(record.sync_server_id) ?? "-" : "-",
|
||||
record.sync_server_id
|
||||
? (serverMap.get(record.sync_server_id) ?? "-")
|
||||
: "-",
|
||||
},
|
||||
{ accessor: "location", title: "IP所在地", width: 140 },
|
||||
{ accessor: "create_at", title: "创建时间", width: 180 },
|
||||
@@ -167,10 +187,13 @@ export default function TeamSyncTaskPage() {
|
||||
width: 200,
|
||||
textAlign: "center",
|
||||
render: (record) => {
|
||||
const couldRun = isShow("task_edit") && [10].includes(record.status ?? -1)
|
||||
const couldStop = isShow("task_edit") && [1, 2].includes(record.status ?? -1)
|
||||
const couldRun =
|
||||
isShow("task_edit") && [10].includes(record.status ?? -1)
|
||||
const couldStop =
|
||||
isShow("task_edit") && [1, 2].includes(record.status ?? -1)
|
||||
const couldDelete =
|
||||
isShow("task_edit") && [1, 2, 3, 4, 9, 10].includes(record.status ?? -1)
|
||||
isShow("task_edit") &&
|
||||
[1, 2, 3, 4, 9, 10].includes(record.status ?? -1)
|
||||
const couldClose =
|
||||
isShow("task_edit") && ![11, 12].includes(record.status ?? -1)
|
||||
|
||||
@@ -199,7 +222,11 @@ export default function TeamSyncTaskPage() {
|
||||
),
|
||||
labels: { confirm: "确定", cancel: "取消" },
|
||||
onConfirm: () =>
|
||||
performStatusAction(record.id as number, 9, "已暂停任务"),
|
||||
performStatusAction(
|
||||
record.id as number,
|
||||
9,
|
||||
"已暂停任务"
|
||||
),
|
||||
})
|
||||
}}>
|
||||
<IconPlayerPause size={16} />
|
||||
@@ -219,7 +246,11 @@ export default function TeamSyncTaskPage() {
|
||||
labels: { confirm: "确定", cancel: "取消" },
|
||||
confirmProps: { color: "red" },
|
||||
onConfirm: () =>
|
||||
performStatusAction(record.id as number, 5, "已提交删除"),
|
||||
performStatusAction(
|
||||
record.id as number,
|
||||
5,
|
||||
"已提交删除"
|
||||
),
|
||||
})
|
||||
}}>
|
||||
<IconTrash size={16} />
|
||||
@@ -238,7 +269,11 @@ export default function TeamSyncTaskPage() {
|
||||
),
|
||||
labels: { confirm: "确定", cancel: "取消" },
|
||||
onConfirm: () =>
|
||||
performStatusAction(record.id as number, 11, "已关闭任务"),
|
||||
performStatusAction(
|
||||
record.id as number,
|
||||
11,
|
||||
"已关闭任务"
|
||||
),
|
||||
})
|
||||
}}>
|
||||
<IconX size={16} />
|
||||
@@ -437,7 +472,11 @@ export default function TeamSyncTaskPage() {
|
||||
onChange={setNewServerId}
|
||||
/>
|
||||
<Group justify="flex-end">
|
||||
<Button variant="default" size="xs" radius="xs" onClick={() => setOpen(false)}>
|
||||
<Button
|
||||
variant="default"
|
||||
size="xs"
|
||||
radius="xs"
|
||||
onClick={() => setOpen(false)}>
|
||||
取消
|
||||
</Button>
|
||||
<Button
|
||||
|
||||
@@ -35,9 +35,7 @@ export function flattenLeaderTree(
|
||||
|
||||
export function toNumberArray(values?: string[]) {
|
||||
if (!values || values.length === 0) return undefined
|
||||
const numbers = values
|
||||
.map((v) => Number(v))
|
||||
.filter((v) => Number.isFinite(v))
|
||||
const numbers = values.map((v) => Number(v)).filter((v) => Number.isFinite(v))
|
||||
return numbers.length > 0 ? numbers : undefined
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
"use client"
|
||||
|
||||
import { getProjectList, getProjectTypeList } from "@/components/label/api/project"
|
||||
import {
|
||||
getProjectList,
|
||||
getProjectTypeList,
|
||||
} from "@/components/label/api/project"
|
||||
import { getTaskList } from "@/components/label/api/task"
|
||||
import { Task } from "@/components/label/api/task/typing"
|
||||
import TaskStatusTag from "@/components/label/components/TaskStatusTag"
|
||||
@@ -18,7 +21,13 @@ import {
|
||||
Text,
|
||||
} from "@mantine/core"
|
||||
import { notifications } from "@mantine/notifications"
|
||||
import { IconChevronDown, IconChevronUp, IconDownload, IconRefresh, IconSearch } from "@tabler/icons-react"
|
||||
import {
|
||||
IconChevronDown,
|
||||
IconChevronUp,
|
||||
IconDownload,
|
||||
IconRefresh,
|
||||
IconSearch,
|
||||
} from "@tabler/icons-react"
|
||||
import { DataTable, DataTableColumn } from "mantine-datatable"
|
||||
import { useEffect, useMemo, useState } from "react"
|
||||
import * as XLSX from "xlsx-js-style"
|
||||
@@ -37,24 +46,25 @@ const emptyFilters = {
|
||||
|
||||
function toNumberArray(values?: string[]) {
|
||||
if (!values || values.length === 0) return undefined
|
||||
const arr = values
|
||||
.map((v) => Number(v))
|
||||
.filter((v) => Number.isFinite(v))
|
||||
const arr = values.map((v) => Number(v)).filter((v) => Number.isFinite(v))
|
||||
return arr.length > 0 ? arr : undefined
|
||||
}
|
||||
|
||||
export default function TaskListTable() {
|
||||
const treeData = useAllUserStore((s) => s.treeData)
|
||||
const userOptions = useMemo(() => flattenLeaderTree(treeData ?? []), [treeData])
|
||||
const userOptions = useMemo(
|
||||
() => flattenLeaderTree(treeData ?? []),
|
||||
[treeData]
|
||||
)
|
||||
|
||||
const [collapsed, setCollapsed] = useState(true)
|
||||
const [loading, setLoading] = useState(false)
|
||||
const [projectTypeOpts, setProjectTypeOpts] = useState<Array<{ label: string; value: string }>>(
|
||||
[]
|
||||
)
|
||||
const [projectNameOpts, setProjectNameOpts] = useState<Array<{ label: string; value: string }>>(
|
||||
[]
|
||||
)
|
||||
const [projectTypeOpts, setProjectTypeOpts] = useState<
|
||||
Array<{ label: string; value: string }>
|
||||
>([])
|
||||
const [projectNameOpts, setProjectNameOpts] = useState<
|
||||
Array<{ label: string; value: string }>
|
||||
>([])
|
||||
const [filters, setFilters] = useState(emptyFilters)
|
||||
|
||||
const [records, setRecords] = useState<Task.DataProps[]>([])
|
||||
@@ -69,14 +79,18 @@ export default function TaskListTable() {
|
||||
])
|
||||
|
||||
if (typesRes.status === "fulfilled") {
|
||||
setProjectTypeOpts((typesRes.value ?? []).map((t) => ({ label: t, value: t })))
|
||||
setProjectTypeOpts(
|
||||
(typesRes.value ?? []).map((t) => ({ label: t, value: t }))
|
||||
)
|
||||
} else {
|
||||
setProjectTypeOpts([])
|
||||
}
|
||||
|
||||
if (projectsRes.status === "fulfilled") {
|
||||
const list = projectsRes.value?.project_list ?? []
|
||||
setProjectNameOpts(list.map((p) => ({ label: p.name, value: String(p.id) })))
|
||||
setProjectNameOpts(
|
||||
list.map((p) => ({ label: p.name, value: String(p.id) }))
|
||||
)
|
||||
} else {
|
||||
setProjectNameOpts([])
|
||||
}
|
||||
@@ -101,7 +115,8 @@ export default function TaskListTable() {
|
||||
page_size: nextFilters.page_size,
|
||||
get_data: false,
|
||||
}
|
||||
if (nextFilters.project_type.length > 0) payload.project_type = nextFilters.project_type
|
||||
if (nextFilters.project_type.length > 0)
|
||||
payload.project_type = nextFilters.project_type
|
||||
if (nextFilters.project_id.length > 0) {
|
||||
payload.project_id = toNumberArray(nextFilters.project_id)
|
||||
}
|
||||
@@ -153,7 +168,10 @@ export default function TaskListTable() {
|
||||
title: "状态",
|
||||
width: 160,
|
||||
render: (record) => (
|
||||
<TaskStatusTag status={record.label_status} rejected={record.rejected} />
|
||||
<TaskStatusTag
|
||||
status={record.label_status}
|
||||
rejected={record.rejected}
|
||||
/>
|
||||
),
|
||||
},
|
||||
{ accessor: "current_username", title: "当前负责人", width: 120 },
|
||||
@@ -214,8 +232,16 @@ export default function TaskListTable() {
|
||||
width: 120,
|
||||
render: (record) => record.label_object_size?.second_comment_size ?? 0,
|
||||
},
|
||||
{ accessor: "first_commit_label_time", title: "标注首次提交时间", width: 180 },
|
||||
{ accessor: "first_commit_review1_time", title: "审核首次提交时间", width: 180 },
|
||||
{
|
||||
accessor: "first_commit_label_time",
|
||||
title: "标注首次提交时间",
|
||||
width: 180,
|
||||
},
|
||||
{
|
||||
accessor: "first_commit_review1_time",
|
||||
title: "审核首次提交时间",
|
||||
width: 180,
|
||||
},
|
||||
{ accessor: "reject_times", title: "驳回次数", width: 100 },
|
||||
{
|
||||
accessor: "label_work_time",
|
||||
@@ -329,7 +355,13 @@ export default function TaskListTable() {
|
||||
variant="subtle"
|
||||
size="xs"
|
||||
radius="xs"
|
||||
rightSection={collapsed ? <IconChevronDown size={14} /> : <IconChevronUp size={14} />}
|
||||
rightSection={
|
||||
collapsed ? (
|
||||
<IconChevronDown size={14} />
|
||||
) : (
|
||||
<IconChevronUp size={14} />
|
||||
)
|
||||
}
|
||||
onClick={() => setCollapsed((v) => !v)}>
|
||||
{collapsed ? "展开筛选" : "收起筛选"}
|
||||
</Button>
|
||||
@@ -387,10 +419,12 @@ export default function TaskListTable() {
|
||||
label="任务状态"
|
||||
size="xs"
|
||||
radius="xs"
|
||||
data={Array.from(TaskStatusEnum.entries()).map(([value, label]) => ({
|
||||
label,
|
||||
value: String(value),
|
||||
}))}
|
||||
data={Array.from(TaskStatusEnum.entries()).map(
|
||||
([value, label]) => ({
|
||||
label,
|
||||
value: String(value),
|
||||
})
|
||||
)}
|
||||
searchable
|
||||
clearable
|
||||
value={filters.label_status}
|
||||
@@ -445,7 +479,11 @@ export default function TaskListTable() {
|
||||
</Stack>
|
||||
</Paper>
|
||||
|
||||
<Paper withBorder p="sm" radius="sm" style={{ flex: 1, minHeight: 0, display: "flex" }}>
|
||||
<Paper
|
||||
withBorder
|
||||
p="sm"
|
||||
radius="sm"
|
||||
style={{ flex: 1, minHeight: 0, display: "flex" }}>
|
||||
<DataTable<Task.DataProps>
|
||||
withTableBorder
|
||||
withRowBorders
|
||||
@@ -453,7 +491,7 @@ export default function TaskListTable() {
|
||||
records={records}
|
||||
columns={columns}
|
||||
noRecordsText="暂无数据"
|
||||
rowKey="id"
|
||||
idAccessor="id"
|
||||
scrollAreaProps={{ type: "auto" }}
|
||||
style={{ width: "100%" }}
|
||||
/>
|
||||
@@ -472,7 +510,9 @@ export default function TaskListTable() {
|
||||
<Text size="sm">问题数:{totalSize?.question_size ?? 0}</Text>
|
||||
<Text size="sm">审核对象数:{totalSize?.review_size ?? 0}</Text>
|
||||
<Text size="sm">批注数(1):{totalSize?.first_comment_size ?? 0}</Text>
|
||||
<Text size="sm">批注数(2):{totalSize?.second_comment_size ?? 0}</Text>
|
||||
<Text size="sm">
|
||||
批注数(2):{totalSize?.second_comment_size ?? 0}
|
||||
</Text>
|
||||
</Group>
|
||||
</Paper>
|
||||
</Stack>
|
||||
|
||||
@@ -21,7 +21,12 @@ import {
|
||||
} from "mantine-datatable"
|
||||
import { useEffect, useMemo, useState } from "react"
|
||||
import * as XLSX from "xlsx-js-style"
|
||||
import { DimensionType, GroupedData, MetricColumn, dimensionOpts } from "./config"
|
||||
import {
|
||||
DimensionType,
|
||||
GroupedData,
|
||||
MetricColumn,
|
||||
dimensionOpts,
|
||||
} from "./config"
|
||||
|
||||
function emptyGroupedData(): GroupedData {
|
||||
return {
|
||||
@@ -42,8 +47,12 @@ export default function WorkloadMetricsTable(props: {
|
||||
}) {
|
||||
const { title, sheetName, fileName, metrics, fetchData } = props
|
||||
|
||||
const [startDate, setStartDate] = useState(dayjs().subtract(1, "day").format("YYYY-MM-DD"))
|
||||
const [endDate, setEndDate] = useState(dayjs().subtract(1, "day").format("YYYY-MM-DD"))
|
||||
const [startDate, setStartDate] = useState(
|
||||
dayjs().subtract(1, "day").format("YYYY-MM-DD")
|
||||
)
|
||||
const [endDate, setEndDate] = useState(
|
||||
dayjs().subtract(1, "day").format("YYYY-MM-DD")
|
||||
)
|
||||
const [dimension, setDimension] = useState<DimensionType>("all")
|
||||
const [data, setData] = useState<GroupedData>(emptyGroupedData())
|
||||
const [loading, setLoading] = useState(false)
|
||||
@@ -152,14 +161,18 @@ export default function WorkloadMetricsTable(props: {
|
||||
{ accessor: "user_name", title: "用户名", width: 120 },
|
||||
{ accessor: "group_name", title: "用户组", width: 160 },
|
||||
],
|
||||
order_by_group_name: [{ accessor: "group_name", title: "用户组", width: 180 }],
|
||||
order_by_group_name: [
|
||||
{ accessor: "group_name", title: "用户组", width: 180 },
|
||||
],
|
||||
order_by_project_name: [
|
||||
{ accessor: "project_name", title: "项目名称", width: 220 },
|
||||
],
|
||||
order_by_project_type: [
|
||||
{ accessor: "project_type", title: "项目类型", width: 220 },
|
||||
],
|
||||
order_by_user_name: [{ accessor: "user_name", title: "用户名", width: 180 }],
|
||||
order_by_user_name: [
|
||||
{ accessor: "user_name", title: "用户名", width: 180 },
|
||||
],
|
||||
}
|
||||
return allCols[dimension]
|
||||
}, [dimension])
|
||||
@@ -319,7 +332,11 @@ export default function WorkloadMetricsTable(props: {
|
||||
</SimpleGrid>
|
||||
</Paper>
|
||||
|
||||
<Paper withBorder p="sm" radius="sm" style={{ flex: 1, minHeight: 0, display: "flex" }}>
|
||||
<Paper
|
||||
withBorder
|
||||
p="sm"
|
||||
radius="sm"
|
||||
style={{ flex: 1, minHeight: 0, display: "flex" }}>
|
||||
<DataTable<any>
|
||||
withTableBorder
|
||||
withRowBorders
|
||||
@@ -327,7 +344,7 @@ export default function WorkloadMetricsTable(props: {
|
||||
records={sortedRecords}
|
||||
columns={columns}
|
||||
noRecordsText="暂无数据"
|
||||
rowKey={rowKey as any}
|
||||
idAccessor={rowKey as any}
|
||||
scrollAreaProps={{ type: "auto" }}
|
||||
style={{ width: "100%" }}
|
||||
sortStatus={sortStatus}
|
||||
|
||||
Reference in New Issue
Block a user