refactor event alarm components to improve detail view and add action buttons

This commit is contained in:
2025-10-09 14:48:36 +07:00
parent 6807be41b6
commit 406b306275
2 changed files with 108 additions and 282 deletions

View File

@@ -1,247 +1,58 @@
import React, { memo, useState, useEffect } from 'react'; import { memo } from 'react';
import { Button, Row, Col, Card, Input } from 'antd'; import { Modal, Divider, Descriptions } from 'antd';
import { SearchOutlined } from '@ant-design/icons';
import { useNavigate } from 'react-router-dom';
import TableList from '../../../components/Global/TableList';
// Dummy data untuk riwayat alarm
const initialAlarmsData = [
{
alarm_id: 1,
tanggal: '2025-01-15 08:30:00',
plant_sub_section: 'Plant A - Section 1',
device: 'Device 001',
tag: 'TEMP-001',
engineer: 'Pras',
},
{
alarm_id: 2,
tanggal: '2025-01-15 09:15:00',
plant_sub_section: 'Plant B - Section 2',
device: 'Device 002',
tag: 'PRESS-002',
engineer: 'Bagus',
},
{
alarm_id: 3,
tanggal: '2025-01-15 10:00:00',
plant_sub_section: 'Plant A - Section 3',
device: 'Device 003',
tag: 'FLOW-003',
engineer: 'iqbal',
},
{
alarm_id: 4,
tanggal: '2025-01-15 11:45:00',
plant_sub_section: 'Plant C - Section 1',
device: 'Device 004',
tag: 'LEVEL-004',
engineer: 'riski',
},
{
alarm_id: 5,
tanggal: '2025-01-15 13:20:00',
plant_sub_section: 'Plant B - Section 3',
device: 'Device 005',
tag: 'TEMP-005',
engineer: 'anton',
},
{
alarm_id: 6,
tanggal: '2025-01-15 14:00:00',
plant_sub_section: 'Plant A - Section 2',
device: 'Device 006',
tag: 'PRESS-006',
engineer: 'kurniawan',
},
{
alarm_id: 7,
tanggal: '2025-01-15 15:30:00',
plant_sub_section: 'Plant C - Section 2',
device: 'Device 007',
tag: 'FLOW-007',
engineer: 'wawan',
},
];
const columns = [
{
title: 'No',
key: 'no',
width: '5%',
align: 'center',
render: (_, __, index) => index + 1,
},
{
title: 'Tanggal',
dataIndex: 'tanggal',
key: 'tanggal',
width: '15%',
},
{
title: 'Plant Sub Section',
dataIndex: 'plant_sub_section',
key: 'plant_sub_section',
width: '20%',
},
{
title: 'Device',
dataIndex: 'device',
key: 'device',
width: '15%',
},
{
title: 'Tag',
dataIndex: 'tag',
key: 'tag',
width: '15%',
},
{
title: 'Engineer',
dataIndex: 'engineer',
key: 'engineer',
width: '15%',
},
];
const ListEventAlarm = memo(function ListEventAlarm(props) {
const [trigerFilter, setTrigerFilter] = useState(false);
const [alarmsData] = useState(initialAlarmsData);
const defaultFilter = { search: '' };
const [formDataFilter, setFormDataFilter] = useState(defaultFilter);
const [searchValue, setSearchValue] = useState('');
const navigate = useNavigate();
// Dummy data function to simulate API call
const getAllEventAlarm = async (params) => {
// Simulate API delay
await new Promise((resolve) => setTimeout(resolve, 300));
// Extract URLSearchParams
const searchParam = params.get('search') || '';
const page = parseInt(params.get('page')) || 1;
const limit = parseInt(params.get('limit')) || 10;
console.log('getAllEventAlarm called with:', { searchParam, page, limit });
// Filter by search
let filteredAlarms = alarmsData;
if (searchParam) {
const searchLower = searchParam.toLowerCase();
filteredAlarms = alarmsData.filter(
(alarm) =>
alarm.tanggal.toLowerCase().includes(searchLower) ||
alarm.plant_sub_section.toLowerCase().includes(searchLower) ||
alarm.device.toLowerCase().includes(searchLower) ||
alarm.tag.toLowerCase().includes(searchLower) ||
alarm.engineer.toLowerCase().includes(searchLower)
);
}
// Pagination logic
const totalData = filteredAlarms.length;
const totalPages = Math.ceil(totalData / limit);
const startIndex = (page - 1) * limit;
const endIndex = startIndex + limit;
const paginatedData = filteredAlarms.slice(startIndex, endIndex);
return {
status: 200,
statusCode: 200,
data: {
data: paginatedData,
total: totalData,
paging: {
page: page,
limit: limit,
total: totalData,
page_total: totalPages,
},
},
};
};
useEffect(() => {
const token = localStorage.getItem('token');
if (token) {
if (props.actionMode == 'list') {
setFormDataFilter(defaultFilter);
doFilter();
}
} else {
navigate('/signin');
}
}, [props.actionMode, alarmsData]);
const doFilter = () => {
setTrigerFilter((prev) => !prev);
};
const handleSearch = () => {
setFormDataFilter({ search: searchValue });
setTrigerFilter((prev) => !prev);
};
const handleSearchClear = () => {
setSearchValue('');
setFormDataFilter({ search: '' });
setTrigerFilter((prev) => !prev);
};
const DetailEventAlarm = memo(function DetailEventAlarm({ visible, onCancel, selectedData }) {
return ( return (
<React.Fragment> <Modal
<Card> title="Detail Event Alarm"
<Row> open={visible}
<Col xs={24}> onCancel={onCancel}
<Row justify="space-between" align="middle" gutter={[8, 8]}> onOk={onCancel}
<Col xs={24} sm={24} md={12} lg={12}> okText="Tutup"
<Input.Search cancelButtonProps={{ style: { display: 'none' } }}
placeholder="Search alarm by tanggal, plant, device, tag, engineer..." width={700}
value={searchValue} >
onChange={(e) => { {selectedData && (
const value = e.target.value; <div>
setSearchValue(value); <Descriptions bordered column={2}>
// Auto search when clearing by backspace/delete <Descriptions.Item label="Tanggal" span={2}>
if (value === '') { {selectedData.tanggal}
setFormDataFilter({ search: '' }); </Descriptions.Item>
setTrigerFilter((prev) => !prev); <Descriptions.Item label="Plant Sub Section" span={2}>
} {selectedData.plant_sub_section}
}} </Descriptions.Item>
onSearch={handleSearch} <Descriptions.Item label="Device">
allowClear={{ {selectedData.device}
clearIcon: <span onClick={handleSearchClear}></span>, </Descriptions.Item>
}} <Descriptions.Item label="Tag">
enterButton={ {selectedData.tag}
<Button </Descriptions.Item>
type="primary" <Descriptions.Item label="Engineer" span={2}>
icon={<SearchOutlined />} {selectedData.engineer}
</Descriptions.Item>
</Descriptions>
<Divider style={{ margin: '16px 0' }} />
{/* Additional Info */}
<div
style={{ style={{
backgroundColor: '#23A55A', marginTop: '16px',
borderColor: '#23A55A', padding: '12px',
backgroundColor: '#f6f9ff',
borderRadius: '6px',
border: '1px solid #d6e4ff',
}} }}
> >
Search <div style={{ fontSize: '12px', color: '#595959' }}>
</Button> <strong>Catatan:</strong> Event alarm ini telah tercatat dalam sistem untuk
} monitoring dan analisis lebih lanjut.
size="large" </div>
/> </div>
</Col> </div>
</Row> )}
</Col> </Modal>
<Col xs={24} sm={24} md={24} lg={24} xl={24} style={{ marginTop: '16px' }}>
<TableList
getData={getAllEventAlarm}
queryParams={formDataFilter}
columns={columns}
triger={trigerFilter}
/>
</Col>
</Row>
</Card>
</React.Fragment>
); );
}); });
export default ListEventAlarm; export default DetailEventAlarm;

View File

@@ -64,7 +64,13 @@ const initialAlarmsData = [
}, },
]; ];
const columns = [ const ListEventAlarm = memo(function ListEventAlarm(props) {
const handleViewDetail = (record) => {
props.setSelectedData(record);
props.setActionMode('preview');
};
const columns = [
{ {
title: 'No', title: 'No',
key: 'no', key: 'no',
@@ -100,11 +106,20 @@ const columns = [
title: 'Engineer', title: 'Engineer',
dataIndex: 'engineer', dataIndex: 'engineer',
key: 'engineer', key: 'engineer',
width: '15%', width: '10%',
}, },
]; {
title: 'Action',
const ListEventAlarm = memo(function ListEventAlarm(props) { key: 'action',
width: '10%',
align: 'center',
render: (_, record) => (
<Button type="link" onClick={() => handleViewDetail(record)}>
Detail
</Button>
),
},
];
const [trigerFilter, setTrigerFilter] = useState(false); const [trigerFilter, setTrigerFilter] = useState(false);
const [alarmsData] = useState(initialAlarmsData); const [alarmsData] = useState(initialAlarmsData);