template card or table in component table list
This commit is contained in:
102
src/components/Global/CardList.jsx
Normal file
102
src/components/Global/CardList.jsx
Normal file
@@ -0,0 +1,102 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import { Card, Button, Row, Col, Typography, Space, Tag } from 'antd';
|
||||||
|
import { EditOutlined, DeleteOutlined, EyeOutlined } from '@ant-design/icons';
|
||||||
|
|
||||||
|
const { Text } = Typography;
|
||||||
|
|
||||||
|
const CardList = ({
|
||||||
|
data,
|
||||||
|
column,
|
||||||
|
header,
|
||||||
|
showPreviewModal,
|
||||||
|
showEditModal,
|
||||||
|
showDeleteDialog,
|
||||||
|
cardColor,
|
||||||
|
}) => {
|
||||||
|
const getCardStyle = () => {
|
||||||
|
const color = cardColor ?? '#F3EDEA'; // Orange color
|
||||||
|
return {
|
||||||
|
border: `2px solid ${color}`,
|
||||||
|
borderRadius: '8px',
|
||||||
|
textAlign: 'center', // Center text
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
const getTitleStyle = (color) => {
|
||||||
|
const backgroundColor = color ?? '#FCF2ED';
|
||||||
|
return {
|
||||||
|
backgroundColor,
|
||||||
|
color: '#fff',
|
||||||
|
padding: '2px 8px',
|
||||||
|
borderRadius: '4px',
|
||||||
|
display: 'inline-block', // ganti inline-block → block
|
||||||
|
width: 'fit-content', // biar lebarnya tetap menyesuaikan teks
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Row gutter={[16, 16]} style={{ marginTop: '16px', justifyContent: 'left' }}>
|
||||||
|
{data.map((item) => (
|
||||||
|
<Col xs={24} sm={24} md={12} lg={8} key={item.device_id}>
|
||||||
|
<Card
|
||||||
|
title={
|
||||||
|
<div
|
||||||
|
style={{
|
||||||
|
display: 'flex',
|
||||||
|
justifyContent: 'space-between', // kiri & kanan
|
||||||
|
alignItems: 'center',
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<span style={getTitleStyle(item.color ?? cardColor)}>
|
||||||
|
{item[header]}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
style={getCardStyle()}
|
||||||
|
actions={[
|
||||||
|
<Space
|
||||||
|
size="middle"
|
||||||
|
style={{ display: 'flex', justifyContent: 'center' }}
|
||||||
|
>
|
||||||
|
<Button
|
||||||
|
type="text"
|
||||||
|
style={{ color: '#1890ff' }}
|
||||||
|
icon={<EyeOutlined />}
|
||||||
|
onClick={() => showPreviewModal(item)}
|
||||||
|
/>
|
||||||
|
<Button
|
||||||
|
type="text"
|
||||||
|
style={{ color: '#faad14' }}
|
||||||
|
icon={<EditOutlined />}
|
||||||
|
onClick={() => showEditModal(item)}
|
||||||
|
/>
|
||||||
|
<Button
|
||||||
|
type="text"
|
||||||
|
danger
|
||||||
|
icon={<DeleteOutlined />}
|
||||||
|
onClick={() => showDeleteDialog(item)}
|
||||||
|
/>
|
||||||
|
</Space>,
|
||||||
|
]}
|
||||||
|
>
|
||||||
|
<div style={{ textAlign: 'left' }}>
|
||||||
|
{column.map((itemCard) => (
|
||||||
|
<>
|
||||||
|
{!itemCard.hidden && !itemCard.render && (
|
||||||
|
<p>
|
||||||
|
<Text strong>{itemCard.title}:</Text>{' '}
|
||||||
|
{item[itemCard.key]}
|
||||||
|
</p>
|
||||||
|
)}
|
||||||
|
{itemCard.render && itemCard.render}
|
||||||
|
</>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</Card>
|
||||||
|
</Col>
|
||||||
|
))}
|
||||||
|
</Row>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default CardList;
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
import React, { memo, useState, useEffect, useRef } from 'react';
|
import React, { memo, useState, useEffect, useRef } from 'react';
|
||||||
import { Table, Pagination, Row, Col, Card, Grid, Button, Typography, Tag } from 'antd';
|
import { Table, Pagination, Row, Col, Card, Grid, Button, Typography, Tag, Segmented } from 'antd';
|
||||||
import {
|
import {
|
||||||
PlusOutlined,
|
PlusOutlined,
|
||||||
FilterOutlined,
|
FilterOutlined,
|
||||||
@@ -8,57 +8,15 @@ import {
|
|||||||
EyeOutlined,
|
EyeOutlined,
|
||||||
SearchOutlined,
|
SearchOutlined,
|
||||||
FilePdfOutlined,
|
FilePdfOutlined,
|
||||||
|
AppstoreOutlined,
|
||||||
|
TableOutlined,
|
||||||
} from '@ant-design/icons';
|
} from '@ant-design/icons';
|
||||||
import { setFilterData } from './DataFilter';
|
import { setFilterData } from './DataFilter';
|
||||||
|
import CardDevice from '../../pages/master/device/component/CardDevice';
|
||||||
|
import CardList from './CardList';
|
||||||
|
|
||||||
const { Text } = Typography;
|
const { Text } = Typography;
|
||||||
|
|
||||||
const defCard = {
|
|
||||||
r1: {
|
|
||||||
style: { fontWeight: 'bold', fontSize: 13 },
|
|
||||||
type: 'primary',
|
|
||||||
color: '',
|
|
||||||
text: 'Cold Work Permit',
|
|
||||||
name: '',
|
|
||||||
},
|
|
||||||
r2: {
|
|
||||||
style: { marginLeft: 8, fontSize: 13 },
|
|
||||||
type: 'primary',
|
|
||||||
color: 'success',
|
|
||||||
text: 'Pengajuan',
|
|
||||||
name: '',
|
|
||||||
},
|
|
||||||
r3: {
|
|
||||||
style: { fontSize: 12 },
|
|
||||||
type: 'secondary',
|
|
||||||
color: '',
|
|
||||||
text: 'No. IVR/20250203/XXV/III',
|
|
||||||
name: '',
|
|
||||||
},
|
|
||||||
r4: {
|
|
||||||
style: { fontSize: 12 },
|
|
||||||
type: 'primary',
|
|
||||||
color: '',
|
|
||||||
text: '3 Feb 2025',
|
|
||||||
name: '',
|
|
||||||
},
|
|
||||||
r5: {
|
|
||||||
style: { fontSize: 12 },
|
|
||||||
type: 'primary',
|
|
||||||
color: '',
|
|
||||||
text: 'Lokasi Gudang Robang',
|
|
||||||
name: '',
|
|
||||||
},
|
|
||||||
r6: {
|
|
||||||
style: { fontSize: 12 },
|
|
||||||
type: 'primary',
|
|
||||||
color: '',
|
|
||||||
text: 'maka tambahkan user tersebut dalam user_partner dengan partner baru yang ditambahkan diatas',
|
|
||||||
name: '',
|
|
||||||
},
|
|
||||||
action: (e) => {},
|
|
||||||
};
|
|
||||||
|
|
||||||
const TableList = memo(function TableList({
|
const TableList = memo(function TableList({
|
||||||
getData,
|
getData,
|
||||||
queryParams,
|
queryParams,
|
||||||
@@ -66,6 +24,11 @@ const TableList = memo(function TableList({
|
|||||||
triger,
|
triger,
|
||||||
mobile,
|
mobile,
|
||||||
rowSelection = null,
|
rowSelection = null,
|
||||||
|
header = 'name',
|
||||||
|
showPreviewModal,
|
||||||
|
showEditModal,
|
||||||
|
showDeleteDialog,
|
||||||
|
cardColor,
|
||||||
}) {
|
}) {
|
||||||
const [gridLoading, setGridLoading] = useState(false);
|
const [gridLoading, setGridLoading] = useState(false);
|
||||||
|
|
||||||
@@ -82,6 +45,8 @@ const TableList = memo(function TableList({
|
|||||||
total: 0,
|
total: 0,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const [viewMode, setViewMode] = useState('card');
|
||||||
|
|
||||||
const { useBreakpoint } = Grid;
|
const { useBreakpoint } = Grid;
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@@ -110,16 +75,16 @@ const TableList = memo(function TableList({
|
|||||||
|
|
||||||
if (resData.status == 200) {
|
if (resData.status == 200) {
|
||||||
setPagingResponse({
|
setPagingResponse({
|
||||||
totalData: resData.data.total,
|
totalData: resData.paging.total_limit,
|
||||||
perPage: resData.data.paging.page_total,
|
perPage: resData.paging.page_total,
|
||||||
totalPage: resData.data.paging.limit,
|
totalPage: resData.paging.total_page,
|
||||||
});
|
});
|
||||||
|
|
||||||
setPagination((prev) => ({
|
setPagination((prev) => ({
|
||||||
...prev,
|
...prev,
|
||||||
current: resData.data.paging.page,
|
current: resData.paging.current_page,
|
||||||
limit: resData.data.paging.limit,
|
limit: resData.paging.current_limit,
|
||||||
total: resData.data.paging.total,
|
total: resData.paging.total_limit,
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -139,140 +104,55 @@ const TableList = memo(function TableList({
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
{isMobile && mobile ? (
|
<Segmented
|
||||||
<Row gutter={24}>
|
options={[
|
||||||
<div style={{ display: 'flex', flexDirection: 'column', gap: '16px' }}>
|
{ value: 'card', icon: <AppstoreOutlined /> },
|
||||||
{data.map((item) => (
|
{ value: 'table', icon: <TableOutlined /> },
|
||||||
<Card
|
]}
|
||||||
key={item.id}
|
value={viewMode}
|
||||||
title={
|
onChange={setViewMode}
|
||||||
(mobile.r1 || mobile.r2) && (
|
/>
|
||||||
<div
|
{(isMobile && mobile) || viewMode === 'card' ? (
|
||||||
style={{
|
<CardList
|
||||||
display: 'flex',
|
cardColor={cardColor}
|
||||||
justifyContent: 'space-between',
|
data={data}
|
||||||
alignItems: 'center',
|
column={columns}
|
||||||
}}
|
header={header}
|
||||||
>
|
showPreviewModal={showPreviewModal}
|
||||||
{mobile.r1 && (
|
showEditModal={showEditModal}
|
||||||
<span style={mobile.r1.style ?? {}}>
|
showDeleteDialog={showDeleteDialog}
|
||||||
{item[mobile.r1.name] ?? mobile.r1.text ?? ''}
|
/>
|
||||||
</span>
|
|
||||||
)}
|
|
||||||
{mobile.r2 && (
|
|
||||||
<Tag
|
|
||||||
color={mobile.r2.color ?? ''}
|
|
||||||
style={mobile.r2.style ?? {}}
|
|
||||||
>
|
|
||||||
{item[mobile.r2.name] ?? mobile.r2.text ?? ''}
|
|
||||||
</Tag>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
style={{ width: '100%' }}
|
|
||||||
>
|
|
||||||
<div style={{ display: 'flex', flexDirection: 'column', gap: 8 }}>
|
|
||||||
{mobile.r3 && mobile.r4 && (
|
|
||||||
<div
|
|
||||||
style={{
|
|
||||||
display: 'flex',
|
|
||||||
alignItems: 'center',
|
|
||||||
gap: 8,
|
|
||||||
justifyContent: 'space-between',
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<Text
|
|
||||||
type={mobile.r3 ? mobile.r3.type ?? 'primary' : ''}
|
|
||||||
style={mobile.r3 ? mobile.r3.style ?? {} : {}}
|
|
||||||
>
|
|
||||||
{item[mobile.r3 ? mobile.r3.name : ''] ?? ''}
|
|
||||||
</Text>
|
|
||||||
<Text style={mobile.r4 ? mobile.r4.style ?? {} : {}}>
|
|
||||||
{item[mobile.r4 ? mobile.r4.name : ''] ?? ''}
|
|
||||||
</Text>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
{mobile.r5 && (
|
|
||||||
<Text
|
|
||||||
type={mobile.r5 ? mobile.r5.type ?? 'secondary' : ''}
|
|
||||||
style={mobile.r5 ? mobile.r5.style ?? {} : {}}
|
|
||||||
>
|
|
||||||
{item[mobile.r5 ? mobile.r5.name : ''] ?? ''}
|
|
||||||
</Text>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
{mobile.r6 && (
|
|
||||||
<div>
|
|
||||||
<Text
|
|
||||||
type={mobile.r6 ? mobile.r6.type ?? 'primary' : ''}
|
|
||||||
style={mobile.r6 ? mobile.r6.style ?? {} : {}}
|
|
||||||
>
|
|
||||||
{item[mobile.r6 ? mobile.r6.name : ''] ?? ''}
|
|
||||||
</Text>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
<div
|
|
||||||
style={{
|
|
||||||
marginTop: 16,
|
|
||||||
borderTop: '1px solid #f0f0f0',
|
|
||||||
paddingTop: 8,
|
|
||||||
textAlign: 'right',
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<Button
|
|
||||||
type="primary"
|
|
||||||
size="small"
|
|
||||||
shape="round"
|
|
||||||
icon={<EyeOutlined />}
|
|
||||||
onClick={(e) => {
|
|
||||||
mobile.action(item);
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
Detail
|
|
||||||
</Button>
|
|
||||||
</div>
|
|
||||||
</Card>
|
|
||||||
))}
|
|
||||||
</div>
|
|
||||||
</Row>
|
|
||||||
) : (
|
) : (
|
||||||
<Row gutter={24}>
|
<Row gutter={24}>
|
||||||
{/* TABLE */}
|
|
||||||
<Table
|
<Table
|
||||||
rowSelection={rowSelection || null}
|
rowSelection={rowSelection || null}
|
||||||
columns={columns}
|
columns={columns}
|
||||||
dataSource={data.map((item, index) => ({ ...item, key: index }))}
|
dataSource={data.map((item, index) => ({ ...item, key: index }))}
|
||||||
pagination={false}
|
pagination={false}
|
||||||
loading={gridLoading}
|
loading={gridLoading}
|
||||||
scroll={{
|
scroll={{ y: 520 }}
|
||||||
y: 520,
|
|
||||||
}}
|
|
||||||
/>
|
/>
|
||||||
|
|
||||||
{/* PAGINATION */}
|
|
||||||
<Col xs={24} style={{ marginTop: '16px' }}>
|
|
||||||
<Row justify="space-between" align="middle">
|
|
||||||
<Col>
|
|
||||||
<div>
|
|
||||||
Menampilkan {pagingResponse.totalPage} Data dari{' '}
|
|
||||||
{pagingResponse.perPage} Halaman
|
|
||||||
</div>
|
|
||||||
</Col>
|
|
||||||
<Col>
|
|
||||||
<Pagination
|
|
||||||
showSizeChanger
|
|
||||||
onChange={handlePaginationChange}
|
|
||||||
onShowSizeChange={handlePaginationChange}
|
|
||||||
current={pagination.current}
|
|
||||||
pageSize={pagination.pageSize}
|
|
||||||
total={pagination.total}
|
|
||||||
/>
|
|
||||||
</Col>
|
|
||||||
</Row>
|
|
||||||
</Col>
|
|
||||||
</Row>
|
</Row>
|
||||||
)}
|
)}
|
||||||
|
{/* PAGINATION */}
|
||||||
|
<Row justify="space-between" align="middle">
|
||||||
|
<Col>
|
||||||
|
<div>
|
||||||
|
Menampilkan {pagingResponse.totalPage} Data dari {pagingResponse.perPage}{' '}
|
||||||
|
Halaman
|
||||||
|
</div>
|
||||||
|
</Col>
|
||||||
|
<Col>
|
||||||
|
<Pagination
|
||||||
|
showSizeChanger
|
||||||
|
onChange={handlePaginationChange}
|
||||||
|
onShowSizeChange={handlePaginationChange}
|
||||||
|
current={pagination.current}
|
||||||
|
pageSize={pagination.pageSize}
|
||||||
|
total={pagination.total}
|
||||||
|
/>
|
||||||
|
</Col>
|
||||||
|
</Row>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -137,7 +137,6 @@ const columns = (showPreviewModal, showEditModal, showDeleteDialog) => [
|
|||||||
];
|
];
|
||||||
|
|
||||||
const ListBrandDevice = memo(function ListBrandDevice(props) {
|
const ListBrandDevice = memo(function ListBrandDevice(props) {
|
||||||
const [showFilter, setShowFilter] = useState(false);
|
|
||||||
const [trigerFilter, setTrigerFilter] = useState(false);
|
const [trigerFilter, setTrigerFilter] = useState(false);
|
||||||
const [brandDeviceData, setBrandDeviceData] = useState(initialBrandDeviceData);
|
const [brandDeviceData, setBrandDeviceData] = useState(initialBrandDeviceData);
|
||||||
|
|
||||||
@@ -208,11 +207,6 @@ const ListBrandDevice = memo(function ListBrandDevice(props) {
|
|||||||
}
|
}
|
||||||
}, [props.actionMode, brandDeviceData]);
|
}, [props.actionMode, brandDeviceData]);
|
||||||
|
|
||||||
const toggleFilter = () => {
|
|
||||||
setFormDataFilter(defaultFilter);
|
|
||||||
setShowFilter((prev) => !prev);
|
|
||||||
};
|
|
||||||
|
|
||||||
const doFilter = () => {
|
const doFilter = () => {
|
||||||
setTrigerFilter((prev) => !prev);
|
setTrigerFilter((prev) => !prev);
|
||||||
};
|
};
|
||||||
@@ -370,6 +364,12 @@ const ListBrandDevice = memo(function ListBrandDevice(props) {
|
|||||||
</Col>
|
</Col>
|
||||||
<Col xs={24} sm={24} md={24} lg={24} xl={24} style={{ marginTop: '16px' }}>
|
<Col xs={24} sm={24} md={24} lg={24} xl={24} style={{ marginTop: '16px' }}>
|
||||||
<TableList
|
<TableList
|
||||||
|
mobile
|
||||||
|
cardColor={'#42AAFF'}
|
||||||
|
header={'tag_name'}
|
||||||
|
showPreviewModal={showPreviewModal}
|
||||||
|
showEditModal={showEditModal}
|
||||||
|
showDeleteDialog={showDeleteDialog}
|
||||||
getData={getAllBrandDevice}
|
getData={getAllBrandDevice}
|
||||||
queryParams={formDataFilter}
|
queryParams={formDataFilter}
|
||||||
columns={columns(showPreviewModal, showEditModal, showDeleteDialog)}
|
columns={columns(showPreviewModal, showEditModal, showDeleteDialog)}
|
||||||
|
|||||||
@@ -1,15 +1,5 @@
|
|||||||
import React, { memo, useState, useEffect } from 'react';
|
import React, { memo, useState, useEffect } from 'react';
|
||||||
import {
|
import { Space, Tag, ConfigProvider, Button, Row, Col, Card, Input, Segmented } from 'antd';
|
||||||
Space,
|
|
||||||
Tag,
|
|
||||||
ConfigProvider,
|
|
||||||
Button,
|
|
||||||
Row,
|
|
||||||
Col,
|
|
||||||
Card,
|
|
||||||
Input,
|
|
||||||
Segmented,
|
|
||||||
} from 'antd';
|
|
||||||
import {
|
import {
|
||||||
PlusOutlined,
|
PlusOutlined,
|
||||||
EditOutlined,
|
EditOutlined,
|
||||||
@@ -23,11 +13,6 @@ import { NotifAlert, NotifOk, NotifConfirmDialog } from '../../../../components/
|
|||||||
import { useNavigate } from 'react-router-dom';
|
import { useNavigate } from 'react-router-dom';
|
||||||
import { deleteDevice, getAllDevice } from '../../../../api/master-device';
|
import { deleteDevice, getAllDevice } from '../../../../api/master-device';
|
||||||
import TableList from '../../../../components/Global/TableList';
|
import TableList from '../../../../components/Global/TableList';
|
||||||
import CardDevice from './CardDevice';
|
|
||||||
import { getFilterData } from '../../../../components/Global/DataFilter';
|
|
||||||
import ExcelJS from 'exceljs';
|
|
||||||
import { saveAs } from 'file-saver';
|
|
||||||
import logoPiEnergi from '../../../../assets/images/logo/pi-energi.png';
|
|
||||||
|
|
||||||
const columns = (showPreviewModal, showEditModal, showDeleteDialog) => [
|
const columns = (showPreviewModal, showEditModal, showDeleteDialog) => [
|
||||||
{
|
{
|
||||||
@@ -113,10 +98,7 @@ const columns = (showPreviewModal, showEditModal, showDeleteDialog) => [
|
|||||||
];
|
];
|
||||||
|
|
||||||
const ListDevice = memo(function ListDevice(props) {
|
const ListDevice = memo(function ListDevice(props) {
|
||||||
const [showFilter, setShowFilter] = useState(false);
|
|
||||||
const [trigerFilter, setTrigerFilter] = useState(false);
|
const [trigerFilter, setTrigerFilter] = useState(false);
|
||||||
const [viewMode, setViewMode] = useState('card');
|
|
||||||
const [deviceData, setDeviceData] = useState([]);
|
|
||||||
|
|
||||||
const defaultFilter = { criteria: '' };
|
const defaultFilter = { criteria: '' };
|
||||||
const [formDataFilter, setFormDataFilter] = useState(defaultFilter);
|
const [formDataFilter, setFormDataFilter] = useState(defaultFilter);
|
||||||
@@ -124,15 +106,6 @@ const ListDevice = memo(function ListDevice(props) {
|
|||||||
|
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
|
|
||||||
const fetchData = async () => {
|
|
||||||
try {
|
|
||||||
const response = await getAllDevice(formDataFilter);
|
|
||||||
setDeviceData(response.data.data);
|
|
||||||
} catch (error) {
|
|
||||||
console.error("Failed to fetch device data:", error);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const token = localStorage.getItem('token');
|
const token = localStorage.getItem('token');
|
||||||
if (token) {
|
if (token) {
|
||||||
@@ -145,15 +118,6 @@ const ListDevice = memo(function ListDevice(props) {
|
|||||||
}
|
}
|
||||||
}, [props.actionMode]);
|
}, [props.actionMode]);
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
fetchData();
|
|
||||||
}, [trigerFilter]);
|
|
||||||
|
|
||||||
const toggleFilter = () => {
|
|
||||||
setFormDataFilter(defaultFilter);
|
|
||||||
setShowFilter((prev) => !prev);
|
|
||||||
};
|
|
||||||
|
|
||||||
const doFilter = () => {
|
const doFilter = () => {
|
||||||
setTrigerFilter((prev) => !prev);
|
setTrigerFilter((prev) => !prev);
|
||||||
};
|
};
|
||||||
@@ -213,85 +177,6 @@ const ListDevice = memo(function ListDevice(props) {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const generatePdf = () => {
|
|
||||||
props.setActionMode('generatepdf');
|
|
||||||
};
|
|
||||||
|
|
||||||
const exportExcel = async () => {
|
|
||||||
const data = getFilterData();
|
|
||||||
|
|
||||||
const workbook = new ExcelJS.Workbook();
|
|
||||||
const sheet = workbook.addWorksheet('Data APD');
|
|
||||||
let rowCursor = 1;
|
|
||||||
if (logoPiEnergi) {
|
|
||||||
const response = await fetch(logoPiEnergi);
|
|
||||||
const blob = await response.blob();
|
|
||||||
const buffer = await blob.arrayBuffer();
|
|
||||||
|
|
||||||
const imageId = workbook.addImage({
|
|
||||||
buffer,
|
|
||||||
extension: 'png',
|
|
||||||
});
|
|
||||||
|
|
||||||
sheet.addImage(imageId, {
|
|
||||||
tl: { col: 0.2, row: 0.8 },
|
|
||||||
ext: { width: 163, height: 80 },
|
|
||||||
});
|
|
||||||
|
|
||||||
sheet.getRow(5).height = 15;
|
|
||||||
rowCursor = 3;
|
|
||||||
}
|
|
||||||
|
|
||||||
const titleCell = sheet.getCell(`C${rowCursor}`);
|
|
||||||
titleCell.value = 'Data APD';
|
|
||||||
titleCell.font = { size: 20, bold: true, color: { argb: 'FF00AEEF' } };
|
|
||||||
titleCell.alignment = { vertical: 'middle', horizontal: 'center' };
|
|
||||||
sheet.mergeCells(`C${rowCursor}:F${rowCursor}`);
|
|
||||||
|
|
||||||
const headers = [
|
|
||||||
'ID APD',
|
|
||||||
'Nama APD',
|
|
||||||
'Deskripsi',
|
|
||||||
'Jenis Permit Default',
|
|
||||||
'Aktif',
|
|
||||||
'Dibuat',
|
|
||||||
'Diubah',
|
|
||||||
];
|
|
||||||
sheet.addRow(headers);
|
|
||||||
const headerRow = sheet.getRow(6);
|
|
||||||
headerRow.font = { bold: true, size: 12 };
|
|
||||||
headerRow.eachCell((cell) => {
|
|
||||||
cell.alignment = {
|
|
||||||
horizontal: 'center',
|
|
||||||
vertical: 'middle',
|
|
||||||
};
|
|
||||||
});
|
|
||||||
|
|
||||||
data.forEach((item) => {
|
|
||||||
sheet.addRow([
|
|
||||||
item.id_apd,
|
|
||||||
item.nama_apd,
|
|
||||||
item.deskripsi_apd ?? '',
|
|
||||||
item.jenis_permit_default ?? '',
|
|
||||||
item.is_active ? 'Ya' : 'Tidak',
|
|
||||||
new Date(item.created_at).toLocaleString(),
|
|
||||||
new Date(item.updated_at).toLocaleString(),
|
|
||||||
]);
|
|
||||||
});
|
|
||||||
|
|
||||||
sheet.columns.forEach((col) => {
|
|
||||||
let maxLength = 10;
|
|
||||||
col.eachCell({ includeEmpty: true }, (cell) => {
|
|
||||||
const len = cell.value?.toString().length || 0;
|
|
||||||
if (len > maxLength) maxLength = len;
|
|
||||||
});
|
|
||||||
col.width = maxLength + 2;
|
|
||||||
});
|
|
||||||
|
|
||||||
const buffer = await workbook.xlsx.writeBuffer();
|
|
||||||
saveAs(new Blob([buffer]), 'Data_APD.xlsx');
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<React.Fragment>
|
<React.Fragment>
|
||||||
<Card>
|
<Card>
|
||||||
@@ -331,14 +216,6 @@ const ListDevice = memo(function ListDevice(props) {
|
|||||||
</Col>
|
</Col>
|
||||||
<Col>
|
<Col>
|
||||||
<Space wrap size="small">
|
<Space wrap size="small">
|
||||||
<Segmented
|
|
||||||
options={[
|
|
||||||
{ value: 'card', icon: <AppstoreOutlined /> },
|
|
||||||
{ value: 'table', icon: <TableOutlined /> },
|
|
||||||
]}
|
|
||||||
value={viewMode}
|
|
||||||
onChange={setViewMode}
|
|
||||||
/>
|
|
||||||
<ConfigProvider
|
<ConfigProvider
|
||||||
theme={{
|
theme={{
|
||||||
token: { colorBgContainer: '#E9F6EF' },
|
token: { colorBgContainer: '#E9F6EF' },
|
||||||
@@ -366,21 +243,18 @@ const ListDevice = memo(function ListDevice(props) {
|
|||||||
</Row>
|
</Row>
|
||||||
</Col>
|
</Col>
|
||||||
<Col xs={24} sm={24} md={24} lg={24} xl={24} style={{ marginTop: '16px' }}>
|
<Col xs={24} sm={24} md={24} lg={24} xl={24} style={{ marginTop: '16px' }}>
|
||||||
{viewMode === 'card' ? (
|
<TableList
|
||||||
<CardDevice
|
mobile
|
||||||
data={deviceData}
|
cardColor={'#42AAFF'}
|
||||||
showPreviewModal={showPreviewModal}
|
header={'device_name'}
|
||||||
showEditModal={showEditModal}
|
showPreviewModal={showPreviewModal}
|
||||||
showDeleteDialog={showDeleteDialog}
|
showEditModal={showEditModal}
|
||||||
/>
|
showDeleteDialog={showDeleteDialog}
|
||||||
) : (
|
getData={getAllDevice}
|
||||||
<TableList
|
queryParams={formDataFilter}
|
||||||
getData={getAllDevice}
|
columns={columns(showPreviewModal, showEditModal, showDeleteDialog)}
|
||||||
queryParams={formDataFilter}
|
triger={trigerFilter}
|
||||||
columns={columns(showPreviewModal, showEditModal, showDeleteDialog)}
|
/>
|
||||||
triger={trigerFilter}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
</Col>
|
</Col>
|
||||||
</Row>
|
</Row>
|
||||||
</Card>
|
</Card>
|
||||||
|
|||||||
@@ -274,6 +274,12 @@ const ListTag = memo(function ListTag(props) {
|
|||||||
</Col>
|
</Col>
|
||||||
<Col xs={24} sm={24} md={24} lg={24} xl={24} style={{ marginTop: '16px' }}>
|
<Col xs={24} sm={24} md={24} lg={24} xl={24} style={{ marginTop: '16px' }}>
|
||||||
<TableList
|
<TableList
|
||||||
|
mobile
|
||||||
|
cardColor={'#42AAFF'}
|
||||||
|
header={'tag_name'}
|
||||||
|
showPreviewModal={showPreviewModal}
|
||||||
|
showEditModal={showEditModal}
|
||||||
|
showDeleteDialog={showDeleteDialog}
|
||||||
getData={getAllTag}
|
getData={getAllTag}
|
||||||
queryParams={formDataFilter}
|
queryParams={formDataFilter}
|
||||||
columns={columns(showPreviewModal, showEditModal, showDeleteDialog)}
|
columns={columns(showPreviewModal, showEditModal, showDeleteDialog)}
|
||||||
|
|||||||
Reference in New Issue
Block a user