Files
SMATEC-FRONTEND/src/components/shared/DeviceAlarmList.tsx

158 lines
4.7 KiB
TypeScript

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"
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;