mirror of
https://gitlab.com/mbugroup/lti-web-client.git
synced 2026-05-26 00:05:45 +00:00
feat: add export to excel feature
This commit is contained in:
@@ -29,7 +29,7 @@ import {
|
|||||||
FINANCE_TRANSACTION_TYPE_OPTIONS,
|
FINANCE_TRANSACTION_TYPE_OPTIONS,
|
||||||
} from '@/config/constant';
|
} from '@/config/constant';
|
||||||
import { FinanceApi } from '@/services/api/finance';
|
import { FinanceApi } from '@/services/api/finance';
|
||||||
import { isResponseSuccess } from '@/lib/api-helper';
|
import { getErrorMessage, isResponseSuccess } from '@/lib/api-helper';
|
||||||
import { BankApi, CustomerApi, SupplierApi } from '@/services/api/master-data';
|
import { BankApi, CustomerApi, SupplierApi } from '@/services/api/master-data';
|
||||||
import { Bank } from '@/types/api/master-data/bank';
|
import { Bank } from '@/types/api/master-data/bank';
|
||||||
import Modal, { useModal } from '@/components/Modal';
|
import Modal, { useModal } from '@/components/Modal';
|
||||||
@@ -39,6 +39,7 @@ import ConfirmationModal from '@/components/modal/ConfirmationModal';
|
|||||||
import toast from 'react-hot-toast';
|
import toast from 'react-hot-toast';
|
||||||
import RequirePermission from '@/components/helper/RequirePermission';
|
import RequirePermission from '@/components/helper/RequirePermission';
|
||||||
import ButtonFilter from '@/components/helper/ButtonFilter';
|
import ButtonFilter from '@/components/helper/ButtonFilter';
|
||||||
|
import Dropdown from '@/components/dropdown/Dropdown';
|
||||||
import {
|
import {
|
||||||
FinanceTableFilterSchema,
|
FinanceTableFilterSchema,
|
||||||
FinanceTableFilterValues,
|
FinanceTableFilterValues,
|
||||||
@@ -233,6 +234,7 @@ const FinanceTable = () => {
|
|||||||
const [selectedSortBy, setSelectedSortBy] = useState<OptionType | null>(null);
|
const [selectedSortBy, setSelectedSortBy] = useState<OptionType | null>(null);
|
||||||
const [selectedFinance, setSelectedFinance] = useState<Finance | null>(null);
|
const [selectedFinance, setSelectedFinance] = useState<Finance | null>(null);
|
||||||
const [isDeleteLoading, setIsDeleteLoading] = useState(false);
|
const [isDeleteLoading, setIsDeleteLoading] = useState(false);
|
||||||
|
const [isExportLoading, setIsExportLoading] = useState(false);
|
||||||
const [dateErrorShown, setDateErrorShown] = useState(false);
|
const [dateErrorShown, setDateErrorShown] = useState(false);
|
||||||
const [hasDateError, setHasDateError] = useState(false);
|
const [hasDateError, setHasDateError] = useState(false);
|
||||||
|
|
||||||
@@ -552,6 +554,20 @@ const FinanceTable = () => {
|
|||||||
filterModal.openModal();
|
filterModal.openModal();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const exportToExcel = async () => {
|
||||||
|
setIsExportLoading(true);
|
||||||
|
try {
|
||||||
|
await FinanceApi.exportToExcel(getTableFilterQueryString());
|
||||||
|
toast.success('Excel berhasil dibuat dan diunduh.');
|
||||||
|
} catch (error) {
|
||||||
|
toast.error(
|
||||||
|
await getErrorMessage(error, 'Gagal mengekspor data finance.')
|
||||||
|
);
|
||||||
|
} finally {
|
||||||
|
setIsExportLoading(false);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
const confirmationModalDeleteClickHandler = async () => {
|
const confirmationModalDeleteClickHandler = async () => {
|
||||||
setIsDeleteLoading(true);
|
setIsDeleteLoading(true);
|
||||||
|
|
||||||
@@ -759,6 +775,51 @@ const FinanceTable = () => {
|
|||||||
onClick={handleFilterModalOpen}
|
onClick={handleFilterModalOpen}
|
||||||
className='px-3 py-2.5'
|
className='px-3 py-2.5'
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
<Dropdown
|
||||||
|
align='end'
|
||||||
|
direction='bottom'
|
||||||
|
className={{
|
||||||
|
content:
|
||||||
|
'mt-1 rounded-xl border border-base-content/5 shadow-sm overflow-hidden',
|
||||||
|
}}
|
||||||
|
trigger={
|
||||||
|
<Button
|
||||||
|
variant='outline'
|
||||||
|
color='none'
|
||||||
|
className='px-3 py-2.5 text-sm text-base-content/50 border border-base-content/10 rounded-xl shadow-button-soft'
|
||||||
|
>
|
||||||
|
<div className='flex flex-row items-center gap-1.5'>
|
||||||
|
<Icon
|
||||||
|
icon='heroicons:cloud-arrow-down'
|
||||||
|
width={20}
|
||||||
|
height={20}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<span>Ekspor</span>
|
||||||
|
|
||||||
|
<div className='w-px self-stretch bg-base-content/10' />
|
||||||
|
|
||||||
|
<Icon
|
||||||
|
icon='heroicons:chevron-down'
|
||||||
|
width={14}
|
||||||
|
height={14}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</Button>
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<Button
|
||||||
|
variant='ghost'
|
||||||
|
color='none'
|
||||||
|
onClick={exportToExcel}
|
||||||
|
isLoading={isExportLoading}
|
||||||
|
className='w-full p-3 justify-start text-sm text-base-content/50 font-semibold text-nowrap'
|
||||||
|
>
|
||||||
|
<Icon icon='heroicons:table-cells' width={20} height={20} />
|
||||||
|
Ekspor ke Excel
|
||||||
|
</Button>
|
||||||
|
</Dropdown>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ import axios from 'axios';
|
|||||||
import { BaseApiService } from '@/services/api/base';
|
import { BaseApiService } from '@/services/api/base';
|
||||||
import { BaseApiResponse } from '@/types/api/api-general';
|
import { BaseApiResponse } from '@/types/api/api-general';
|
||||||
import { httpClient, httpClientFetcher } from '@/services/http/client';
|
import { httpClient, httpClientFetcher } from '@/services/http/client';
|
||||||
|
import { formatDate } from '@/lib/helper';
|
||||||
import {
|
import {
|
||||||
CreateFinancePayment,
|
CreateFinancePayment,
|
||||||
CreateInitialBalance,
|
CreateInitialBalance,
|
||||||
@@ -174,6 +175,30 @@ export class FinanceApiService extends BaseApiService<
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async exportToExcel(initialQueryString: string) {
|
||||||
|
const params = new URLSearchParams(initialQueryString);
|
||||||
|
|
||||||
|
params.set('export', 'excel');
|
||||||
|
params.set('page', '1');
|
||||||
|
params.set('limit', '99999999999');
|
||||||
|
|
||||||
|
const res = await httpClient<Blob>(
|
||||||
|
`${this.basePath}/transactions?${params.toString()}`,
|
||||||
|
{ method: 'GET', responseType: 'blob' }
|
||||||
|
);
|
||||||
|
|
||||||
|
const url = window.URL.createObjectURL(new Blob([res]));
|
||||||
|
const link = document.createElement('a');
|
||||||
|
link.href = url;
|
||||||
|
link.setAttribute(
|
||||||
|
'download',
|
||||||
|
`finance-${formatDate(Date.now(), 'DD-MM-YYYY')}.xlsx`
|
||||||
|
);
|
||||||
|
document.body.appendChild(link);
|
||||||
|
link.click();
|
||||||
|
link.remove();
|
||||||
|
}
|
||||||
|
|
||||||
async delete(id: number) {
|
async delete(id: number) {
|
||||||
try {
|
try {
|
||||||
const deletePath = `${this.basePath}/transactions/${id}`;
|
const deletePath = `${this.basePath}/transactions/${id}`;
|
||||||
|
|||||||
Reference in New Issue
Block a user