feat(master/device-detail && alarm): Enhance device detail page with alarm list and binary sensors integration, update iconfont URLs, and improve alarm confirmation handling
This commit is contained in:
158
src/components/shared/DeviceAlarmList.tsx
Normal file
158
src/components/shared/DeviceAlarmList.tsx
Normal file
@@ -0,0 +1,158 @@
|
||||
import { DATE_TIME_FORMAT, DEFAULT_PAGE_SIZE, DURATION_POLLING } from '@/const';
|
||||
import AlarmDescription from '@/pages/Alarm/components/AlarmDescription';
|
||||
import AlarmFormConfirm from '@/pages/Alarm/components/AlarmFormConfirm';
|
||||
import { apiGetAlarms } from '@/services/master/AlarmController';
|
||||
import { CheckOutlined } from '@ant-design/icons';
|
||||
import { ActionType, ProList, ProListMetas } from '@ant-design/pro-components';
|
||||
import { useIntl } from '@umijs/max';
|
||||
import { Button, message, theme, Typography } from 'antd';
|
||||
import moment from 'moment';
|
||||
import { useRef, useState } from 'react';
|
||||
import AlarmUnConfirmButton from './Alarm/AlarmUnConfirmButton';
|
||||
import { getBadgeStatus, getTitleColorByDeviceStateLevel } from './ThingShared';
|
||||
|
||||
type DeviceAlarmListProps = {
|
||||
thingId: string;
|
||||
};
|
||||
|
||||
const DeviceAlarmList = ({ thingId }: DeviceAlarmListProps) => {
|
||||
const { token } = theme.useToken();
|
||||
const [messageApi, contextHolder] = message.useMessage();
|
||||
const intl = useIntl();
|
||||
const actionRef = useRef<ActionType>();
|
||||
const [loading, setIsLoading] = useState<boolean>(false);
|
||||
const [alarmConfirmed, setAlarmConfirmed] = useState<
|
||||
MasterModel.Alarm | undefined
|
||||
>(undefined);
|
||||
const columns: ProListMetas<MasterModel.Alarm> = {
|
||||
title: {
|
||||
dataIndex: 'name',
|
||||
render(_, item) {
|
||||
return (
|
||||
<Typography.Text
|
||||
style={{
|
||||
color: getTitleColorByDeviceStateLevel(item.level || 0, token),
|
||||
}}
|
||||
>
|
||||
{item.name}
|
||||
</Typography.Text>
|
||||
);
|
||||
},
|
||||
},
|
||||
avatar: {
|
||||
render: (_, item) => getBadgeStatus(item.level || 0),
|
||||
},
|
||||
description: {
|
||||
dataIndex: 'time',
|
||||
render: (_, item) => {
|
||||
return (
|
||||
<>
|
||||
{item.confirmed ? (
|
||||
<AlarmDescription alarm={item} size="small" />
|
||||
) : (
|
||||
<div>{moment.unix(item?.time || 0).format(DATE_TIME_FORMAT)}</div>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
},
|
||||
},
|
||||
actions: {
|
||||
render: (_, entity) => [
|
||||
entity.confirmed ? (
|
||||
<AlarmUnConfirmButton
|
||||
key="unconfirm"
|
||||
alarm={entity}
|
||||
message={messageApi}
|
||||
onFinish={(isReload) => {
|
||||
if (isReload) actionRef.current?.reload();
|
||||
}}
|
||||
/>
|
||||
) : (
|
||||
<Button
|
||||
key="confirm"
|
||||
icon={<CheckOutlined />}
|
||||
type="dashed"
|
||||
className="green-btn"
|
||||
style={{ color: 'green', borderColor: 'green' }}
|
||||
size="small"
|
||||
onClick={() => setAlarmConfirmed(entity)}
|
||||
></Button>
|
||||
),
|
||||
],
|
||||
},
|
||||
};
|
||||
return (
|
||||
<>
|
||||
{contextHolder}
|
||||
<AlarmFormConfirm
|
||||
isOpen={!!alarmConfirmed}
|
||||
setIsOpen={(v) => {
|
||||
if (!v) setAlarmConfirmed(undefined);
|
||||
}}
|
||||
alarm={alarmConfirmed || ({} as MasterModel.Alarm)}
|
||||
trigger={<></>}
|
||||
message={messageApi}
|
||||
onFinish={(isReload) => {
|
||||
if (isReload) actionRef.current?.reload();
|
||||
}}
|
||||
/>
|
||||
<ProList<MasterModel.Alarm>
|
||||
rowKey={(record) => `${record.thing_id}_${record.id}`}
|
||||
bordered
|
||||
actionRef={actionRef}
|
||||
metas={columns}
|
||||
polling={DURATION_POLLING}
|
||||
loading={loading}
|
||||
search={false}
|
||||
dateFormatter="string"
|
||||
cardProps={{
|
||||
bodyStyle: { paddingInline: 16, paddingBlock: 8 },
|
||||
}}
|
||||
pagination={{
|
||||
defaultPageSize: DEFAULT_PAGE_SIZE * 2,
|
||||
showSizeChanger: false,
|
||||
pageSizeOptions: ['5', '10', '15', '20'],
|
||||
showTotal: (total, range) =>
|
||||
`${range[0]}-${range[1]}
|
||||
${intl.formatMessage({
|
||||
id: 'common.paginations.of',
|
||||
defaultMessage: 'of',
|
||||
})}
|
||||
${total} ${intl.formatMessage({
|
||||
id: 'master.alarms.table.pagination',
|
||||
defaultMessage: 'alarms',
|
||||
})}`,
|
||||
}}
|
||||
request={async (params) => {
|
||||
setIsLoading(true);
|
||||
try {
|
||||
const { current, pageSize } = params;
|
||||
const offset = current === 1 ? 0 : (current! - 1) * pageSize!;
|
||||
const body: MasterModel.SearchAlarmPaginationBody = {
|
||||
limit: pageSize,
|
||||
offset: offset,
|
||||
thing_id: thingId,
|
||||
dir: 'desc',
|
||||
};
|
||||
const res = await apiGetAlarms(body);
|
||||
return {
|
||||
data: res.alarms,
|
||||
total: res.total,
|
||||
success: true,
|
||||
};
|
||||
} catch (error) {
|
||||
return {
|
||||
data: [],
|
||||
total: 0,
|
||||
success: false,
|
||||
};
|
||||
} finally {
|
||||
setIsLoading(false);
|
||||
}
|
||||
}}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export default DeviceAlarmList;
|
||||
Reference in New Issue
Block a user