хз уже че тут придумывать
This commit is contained in:
parent
b917ad6432
commit
3b63d2c533
1 changed files with 64 additions and 16 deletions
|
|
@ -53,7 +53,7 @@ import {
|
||||||
type DeviceImportPreview,
|
type DeviceImportPreview,
|
||||||
type DeviceItem,
|
type DeviceItem,
|
||||||
} from '../api/objects'
|
} from '../api/objects'
|
||||||
import { useRacks, useCreateRack, useDeleteRack, type RackItem } from '../api/racks'
|
import { useRacks, useCreateRack, useUpdateRack, useDeleteRack, type RackItem } from '../api/racks'
|
||||||
import { useZones, useCreateZone, useDeleteZone, type ZoneItem } from '../api/zones'
|
import { useZones, useCreateZone, useDeleteZone, type ZoneItem } from '../api/zones'
|
||||||
import { CategoryTag, DeviceStatusBadge } from '../components/StatusBadge'
|
import { CategoryTag, DeviceStatusBadge } from '../components/StatusBadge'
|
||||||
import { DiscoveryDrawer } from '../components/DiscoveryDrawer'
|
import { DiscoveryDrawer } from '../components/DiscoveryDrawer'
|
||||||
|
|
@ -113,6 +113,7 @@ export function InventoryObjectDetailPage() {
|
||||||
const previewCSV = usePreviewCSV(objId)
|
const previewCSV = usePreviewCSV(objId)
|
||||||
const importCSV = useImportCSV(objId)
|
const importCSV = useImportCSV(objId)
|
||||||
const createRack = useCreateRack(objId)
|
const createRack = useCreateRack(objId)
|
||||||
|
const updateRack = useUpdateRack(objId)
|
||||||
const deleteRack = useDeleteRack(objId)
|
const deleteRack = useDeleteRack(objId)
|
||||||
const createZone = useCreateZone(objId)
|
const createZone = useCreateZone(objId)
|
||||||
const deleteZone = useDeleteZone(objId)
|
const deleteZone = useDeleteZone(objId)
|
||||||
|
|
@ -126,6 +127,7 @@ export function InventoryObjectDetailPage() {
|
||||||
const [sheetsModal, setSheetsModal] = useState(false)
|
const [sheetsModal, setSheetsModal] = useState(false)
|
||||||
const [discoveryTaskId, setDiscoveryTaskId] = useState<string | null>(null)
|
const [discoveryTaskId, setDiscoveryTaskId] = useState<string | null>(null)
|
||||||
const [discoveryOpen, setDiscoveryOpen] = useState(false)
|
const [discoveryOpen, setDiscoveryOpen] = useState(false)
|
||||||
|
const [editRack, setEditRack] = useState<RackItem | null>(null)
|
||||||
const [csvFile, setCsvFile] = useState<File | null>(null)
|
const [csvFile, setCsvFile] = useState<File | null>(null)
|
||||||
const [csvPreview, setCsvPreview] = useState<DeviceImportPreview | null>(null)
|
const [csvPreview, setCsvPreview] = useState<DeviceImportPreview | null>(null)
|
||||||
const [searchText, setSearchText] = useState('')
|
const [searchText, setSearchText] = useState('')
|
||||||
|
|
@ -134,6 +136,7 @@ export function InventoryObjectDetailPage() {
|
||||||
const [rackForm] = Form.useForm()
|
const [rackForm] = Form.useForm()
|
||||||
const [zoneForm] = Form.useForm()
|
const [zoneForm] = Form.useForm()
|
||||||
const [sheetsForm] = Form.useForm()
|
const [sheetsForm] = Form.useForm()
|
||||||
|
const [editRackForm] = Form.useForm()
|
||||||
|
|
||||||
const rackOptions = useMemo(
|
const rackOptions = useMemo(
|
||||||
() => (racks ?? []).map((r) => ({ value: r.id, label: r.name })),
|
() => (racks ?? []).map((r) => ({ value: r.id, label: r.name })),
|
||||||
|
|
@ -315,6 +318,26 @@ export function InventoryObjectDetailPage() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const openEditRack = (row: RackItem) => {
|
||||||
|
editRackForm.setFieldsValue({
|
||||||
|
rack_type: row.rack_type ?? '',
|
||||||
|
location: row.location ?? '',
|
||||||
|
})
|
||||||
|
setEditRack(row)
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleSaveRack = async () => {
|
||||||
|
if (!editRack) return
|
||||||
|
const values = editRackForm.getFieldsValue()
|
||||||
|
try {
|
||||||
|
await updateRack.mutateAsync({ id: editRack.id, body: stripEmpty(values) as any })
|
||||||
|
message.success('Стойка обновлена')
|
||||||
|
setEditRack(null)
|
||||||
|
} catch {
|
||||||
|
message.error('Ошибка при обновлении стойки')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const filteredDevices = useMemo(() => {
|
const filteredDevices = useMemo(() => {
|
||||||
if (!searchText) return devices ?? []
|
if (!searchText) return devices ?? []
|
||||||
const q = searchText.toLowerCase()
|
const q = searchText.toLowerCase()
|
||||||
|
|
@ -504,27 +527,52 @@ export function InventoryObjectDetailPage() {
|
||||||
{
|
{
|
||||||
title: 'Название',
|
title: 'Название',
|
||||||
key: 'name',
|
key: 'name',
|
||||||
render: (_: unknown, row: RackItem) => (
|
render: (_: unknown, row: RackItem) => {
|
||||||
<span>{row.name}{row.rack_type ? <Tag style={{ marginLeft: 6 }}>{row.rack_type}</Tag> : null}</span>
|
if (editRack?.id === row.id) {
|
||||||
),
|
return (
|
||||||
|
<Space>
|
||||||
|
<span>{row.name}</span>
|
||||||
|
<Form form={editRackForm} layout="inline" size="small">
|
||||||
|
<Form.Item name="rack_type" style={{ marginBottom: 0 }}>
|
||||||
|
<Input placeholder="Тип (entry, exit...)" style={{ width: 130 }} />
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item name="location" style={{ marginBottom: 0 }}>
|
||||||
|
<Input placeholder="Расположение" style={{ width: 120 }} />
|
||||||
|
</Form.Item>
|
||||||
|
</Form>
|
||||||
|
<Button size="small" type="primary" onClick={handleSaveRack} loading={updateRack.isPending}>Сохранить</Button>
|
||||||
|
<Button size="small" onClick={() => setEditRack(null)}>Отмена</Button>
|
||||||
|
</Space>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
return (
|
||||||
|
<span>
|
||||||
|
{row.name}
|
||||||
|
{row.rack_type ? <Tag style={{ marginLeft: 6 }}>{row.rack_type}</Tag> : null}
|
||||||
|
</span>
|
||||||
|
)
|
||||||
|
},
|
||||||
},
|
},
|
||||||
{ title: 'Зона', dataIndex: 'zone_name', key: 'zone_name', render: (v: string | null) => v ? <Tag>{v}</Tag> : '—' },
|
{ title: 'Зона', dataIndex: 'zone_name', key: 'zone_name', render: (v: string | null) => v ? <Tag>{v}</Tag> : '—' },
|
||||||
{ title: 'Расположение', dataIndex: 'location', key: 'location', render: (v: string | null) => v ?? '—' },
|
{ title: 'Расположение', dataIndex: 'location', key: 'location', render: (v: string | null) => v ?? '—' },
|
||||||
{
|
{
|
||||||
title: '',
|
title: '',
|
||||||
key: 'actions',
|
key: 'actions',
|
||||||
width: 60,
|
width: 90,
|
||||||
render: (_: unknown, row: RackItem) => (
|
render: (_: unknown, row: RackItem) => (
|
||||||
<Popconfirm
|
<Space>
|
||||||
title="Удалить стойку?"
|
<Button size="small" icon={<EditOutlined />} onClick={() => openEditRack(row)} />
|
||||||
description="Устройства останутся, привязка к стойке будет снята."
|
<Popconfirm
|
||||||
okText="Удалить"
|
title="Удалить стойку?"
|
||||||
cancelText="Отмена"
|
description="Устройства останутся, привязка к стойке будет снята."
|
||||||
okButtonProps={{ danger: true }}
|
okText="Удалить"
|
||||||
onConfirm={() => deleteRack.mutateAsync(row.id).catch(() => message.error('Ошибка удаления стойки'))}
|
cancelText="Отмена"
|
||||||
>
|
okButtonProps={{ danger: true }}
|
||||||
<Button size="small" danger icon={<DeleteOutlined />} />
|
onConfirm={() => deleteRack.mutateAsync(row.id).catch(() => message.error('Ошибка удаления стойки'))}
|
||||||
</Popconfirm>
|
>
|
||||||
|
<Button size="small" danger icon={<DeleteOutlined />} />
|
||||||
|
</Popconfirm>
|
||||||
|
</Space>
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
|
|
@ -640,7 +688,7 @@ export function InventoryObjectDetailPage() {
|
||||||
<Modal
|
<Modal
|
||||||
title="Стойки и зоны"
|
title="Стойки и зоны"
|
||||||
open={rackModal}
|
open={rackModal}
|
||||||
onCancel={() => { setRackModal(false); rackForm.resetFields(); zoneForm.resetFields() }}
|
onCancel={() => { setRackModal(false); rackForm.resetFields(); zoneForm.resetFields(); setEditRack(null) }}
|
||||||
footer={null}
|
footer={null}
|
||||||
width={820}
|
width={820}
|
||||||
>
|
>
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue