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 { Button, Row, Col, Card, Input } 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);
};
import { memo } from 'react';
import { Modal, Divider, Descriptions } from 'antd';
const DetailEventAlarm = memo(function DetailEventAlarm({ visible, onCancel, selectedData }) {
return (
<React.Fragment>
<Card>
<Row>
<Col xs={24}>
<Row justify="space-between" align="middle" gutter={[8, 8]}>
<Col xs={24} sm={24} md={12} lg={12}>
<Input.Search
placeholder="Search alarm by tanggal, plant, device, tag, engineer..."
value={searchValue}
onChange={(e) => {
const value = e.target.value;
setSearchValue(value);
// Auto search when clearing by backspace/delete
if (value === '') {
setFormDataFilter({ search: '' });
setTrigerFilter((prev) => !prev);
}
}}
onSearch={handleSearch}
allowClear={{
clearIcon: <span onClick={handleSearchClear}></span>,
}}
enterButton={
<Button
type="primary"
icon={<SearchOutlined />}
style={{
backgroundColor: '#23A55A',
borderColor: '#23A55A',
}}
>
Search
</Button>
}
size="large"
/>
</Col>
</Row>
</Col>
<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>
<Modal
title="Detail Event Alarm"
open={visible}
onCancel={onCancel}
onOk={onCancel}
okText="Tutup"
cancelButtonProps={{ style: { display: 'none' } }}
width={700}
>
{selectedData && (
<div>
<Descriptions bordered column={2}>
<Descriptions.Item label="Tanggal" span={2}>
{selectedData.tanggal}
</Descriptions.Item>
<Descriptions.Item label="Plant Sub Section" span={2}>
{selectedData.plant_sub_section}
</Descriptions.Item>
<Descriptions.Item label="Device">
{selectedData.device}
</Descriptions.Item>
<Descriptions.Item label="Tag">
{selectedData.tag}
</Descriptions.Item>
<Descriptions.Item label="Engineer" span={2}>
{selectedData.engineer}
</Descriptions.Item>
</Descriptions>
<Divider style={{ margin: '16px 0' }} />
{/* Additional Info */}
<div
style={{
marginTop: '16px',
padding: '12px',
backgroundColor: '#f6f9ff',
borderRadius: '6px',
border: '1px solid #d6e4ff',
}}
>
<div style={{ fontSize: '12px', color: '#595959' }}>
<strong>Catatan:</strong> Event alarm ini telah tercatat dalam sistem untuk
monitoring dan analisis lebih lanjut.
</div>
</div>
</div>
)}
</Modal>
);
});
export default ListEventAlarm;
export default DetailEventAlarm;

View File

@@ -64,47 +64,62 @@ const initialAlarmsData = [
},
];
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 handleViewDetail = (record) => {
props.setSelectedData(record);
props.setActionMode('preview');
};
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: '10%',
},
{
title: 'Action',
key: 'action',
width: '10%',
align: 'center',
render: (_, record) => (
<Button type="link" onClick={() => handleViewDetail(record)}>
Detail
</Button>
),
},
];
const [trigerFilter, setTrigerFilter] = useState(false);
const [alarmsData] = useState(initialAlarmsData);