mirror of
https://gitlab.com/mbugroup/lti-web-client.git
synced 2026-05-20 13:32:00 +00:00
Merge branch 'development' into 'schema/bulk-approve-marketings-expenses'
# Conflicts: # src/services/api/expense.ts
This commit is contained in:
@@ -192,6 +192,29 @@ export class DailyChecklistApiService extends BaseApiService<
|
||||
}
|
||||
}
|
||||
|
||||
async bulkApprove(ids: string[]) {
|
||||
try {
|
||||
const formData = new FormData();
|
||||
|
||||
formData.append('ids', ids.join(','));
|
||||
formData.append('status', 'APPROVED');
|
||||
formData.append('reject_reason', '');
|
||||
|
||||
const approvePath = `${this.basePath}/bulk-update`;
|
||||
const approveRes = await httpClient<BaseApiResponse>(approvePath, {
|
||||
method: 'PATCH',
|
||||
body: formData,
|
||||
});
|
||||
|
||||
return approveRes;
|
||||
} catch (error) {
|
||||
if (axios.isAxiosError<BaseApiResponse>(error)) {
|
||||
return error.response?.data;
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
|
||||
async reject(id: string, rejectReason: string) {
|
||||
try {
|
||||
const formData = new FormData();
|
||||
@@ -215,6 +238,29 @@ export class DailyChecklistApiService extends BaseApiService<
|
||||
}
|
||||
}
|
||||
|
||||
async bulkReject(ids: string[], rejectReason: string) {
|
||||
try {
|
||||
const formData = new FormData();
|
||||
|
||||
formData.append('ids', ids.join(','));
|
||||
formData.append('status', 'REJECTED');
|
||||
formData.append('reject_reason', rejectReason);
|
||||
|
||||
const rejectPath = `${this.basePath}/bulk-update`;
|
||||
const rejectRes = await httpClient<BaseApiResponse>(rejectPath, {
|
||||
method: 'PATCH',
|
||||
body: formData,
|
||||
});
|
||||
|
||||
return rejectRes;
|
||||
} catch (error) {
|
||||
if (axios.isAxiosError<BaseApiResponse>(error)) {
|
||||
return error.response?.data;
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
|
||||
async uploadImage(
|
||||
id: number,
|
||||
status: string,
|
||||
|
||||
@@ -126,6 +126,29 @@ class MarketingExportService extends BaseApiService<
|
||||
super(basePath);
|
||||
}
|
||||
|
||||
async bulkApprovals(
|
||||
ids: number[],
|
||||
status: 'SALES_ORDER' | 'DELIVERY_ORDER',
|
||||
date: string, // YYYY-MM-DD
|
||||
notes: string
|
||||
): Promise<BaseApiResponse<Marketing[] | Marketing> | undefined> {
|
||||
try {
|
||||
const path = `${this.basePath}/approvals/bulk`;
|
||||
|
||||
return await httpClient<BaseApiResponse<Marketing[] | Marketing>>(path, {
|
||||
method: 'POST',
|
||||
body: {
|
||||
approvable_ids: ids,
|
||||
status: status,
|
||||
date: date,
|
||||
notes: notes,
|
||||
},
|
||||
});
|
||||
} catch (error) {
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Export to Excel
|
||||
*/
|
||||
|
||||
@@ -95,6 +95,8 @@ export class RecordingService extends BaseApiService<
|
||||
const params = new URLSearchParams(initialQueryString);
|
||||
|
||||
params.set('export', 'excel');
|
||||
params.set('page', '1');
|
||||
params.set('limit', '99999999999');
|
||||
|
||||
const queryString = `?${params.toString()}`;
|
||||
|
||||
|
||||
@@ -1,7 +1,10 @@
|
||||
import { BaseApiService } from '@/services/api/base';
|
||||
import { httpClientFetcher } from '@/services/http/client';
|
||||
import { BaseApiResponse } from '@/types/api/api-general';
|
||||
import { ReportExpense } from '@/types/api/report/report-expense';
|
||||
import {
|
||||
ReportDepreciation,
|
||||
ReportExpense,
|
||||
} from '@/types/api/report/report-expense';
|
||||
|
||||
export class ReportExpenseApiService extends BaseApiService<
|
||||
ReportExpense,
|
||||
@@ -20,3 +23,9 @@ export class ReportExpenseApiService extends BaseApiService<
|
||||
}
|
||||
|
||||
export const ReportExpenseApi = new ReportExpenseApiService('/reports/expense');
|
||||
|
||||
export const DepreciationReportApi = new BaseApiService<
|
||||
ReportDepreciation,
|
||||
unknown,
|
||||
unknown
|
||||
>('/reports/expense/depreciation');
|
||||
@@ -56,7 +56,6 @@ export class UniformityApiService extends BaseApiService<
|
||||
): Promise<BaseApiResponse<UniformityDetail> | undefined> {
|
||||
const formData = new FormData();
|
||||
formData.append('date', payload.date);
|
||||
formData.append('week', payload.week.toString());
|
||||
formData.append(
|
||||
'project_flock_kandang_id',
|
||||
payload.project_flock_kandang_id.toString()
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { useCallback, useMemo, useReducer } from 'react';
|
||||
import { useCallback, useEffect, useMemo, useReducer } from 'react';
|
||||
import { useTableFilterStore } from '@/stores/table/table-filter.store';
|
||||
|
||||
/** Core filter shape (page + pageSize) extended by your custom fields */
|
||||
export type TableFilterState<TExtra extends Record<string, unknown>> = {
|
||||
@@ -30,6 +31,9 @@ export type UseTableFilterOptions<TExtra extends Record<string, unknown>> = {
|
||||
paramMap?: Partial<Record<keyof TableFilterState<TExtra>, string>>;
|
||||
/** If true, `toSearchParams`/`toQueryString` will omit values equal to defaults */
|
||||
omitDefaultsInUrl?: boolean;
|
||||
|
||||
persist?: boolean;
|
||||
storeName?: string;
|
||||
};
|
||||
|
||||
function clampToInt(n: number, min = 1) {
|
||||
@@ -90,9 +94,37 @@ function shallowEqual<T extends Record<string, unknown>>(
|
||||
export function useTableFilter<TExtra extends Record<string, unknown>>(
|
||||
options?: UseTableFilterOptions<TExtra>
|
||||
) {
|
||||
const defaults = useMemo(
|
||||
() => createInitialState<TExtra>(options),
|
||||
[options]
|
||||
if (options?.persist && !options?.storeName) {
|
||||
throw new Error(
|
||||
'storeName is required if persist is true in useTableFilter!'
|
||||
);
|
||||
}
|
||||
|
||||
const storeName = options?.storeName ?? '';
|
||||
const persistedState = useTableFilterStore(
|
||||
useCallback(
|
||||
(storeState) =>
|
||||
storeName
|
||||
? (storeState.data[storeName] as Partial<TableFilterState<TExtra>>)
|
||||
: undefined,
|
||||
[storeName]
|
||||
)
|
||||
);
|
||||
const setTableData = useTableFilterStore(
|
||||
(storeState) => storeState.setTableData
|
||||
);
|
||||
|
||||
const defaults = useMemo(() => {
|
||||
return createInitialState<TExtra>(options);
|
||||
}, [options]);
|
||||
|
||||
const initialState = useMemo(
|
||||
() =>
|
||||
({
|
||||
...defaults,
|
||||
...(persistedState as object),
|
||||
}) as TableFilterState<TExtra>,
|
||||
[defaults, persistedState]
|
||||
);
|
||||
|
||||
const [state, dispatch] = useReducer(
|
||||
@@ -106,15 +138,22 @@ export function useTableFilter<TExtra extends Record<string, unknown>>(
|
||||
case 'SET_PAGE_SIZE': {
|
||||
const pageSize = clampToInt(a.pageSize);
|
||||
const page = a.resetPage ? 1 : s.page;
|
||||
|
||||
return { ...s, pageSize, page };
|
||||
}
|
||||
case 'SET_FILTERS': {
|
||||
const page = a.resetPage ? 1 : s.page;
|
||||
|
||||
return { ...s, ...a.filters, page };
|
||||
}
|
||||
case 'UPDATE_FILTER': {
|
||||
const page = a.resetPage ? 1 : s.page;
|
||||
return { ...s, [a.key]: a.value, page } as TableFilterState<TExtra>;
|
||||
|
||||
return {
|
||||
...s,
|
||||
[a.key]: a.value,
|
||||
page,
|
||||
} as TableFilterState<TExtra>;
|
||||
}
|
||||
case 'REPLACE_ALL':
|
||||
return {
|
||||
@@ -128,12 +167,19 @@ export function useTableFilter<TExtra extends Record<string, unknown>>(
|
||||
return s;
|
||||
}
|
||||
},
|
||||
defaults
|
||||
initialState
|
||||
);
|
||||
|
||||
// Notify consumer on change (stable ref)
|
||||
useEffect(() => {
|
||||
if (!options?.persist || !storeName) {
|
||||
return;
|
||||
}
|
||||
|
||||
setTableData(storeName, state);
|
||||
}, [options?.persist, setTableData, state, storeName]);
|
||||
|
||||
const onChange = options?.onChange;
|
||||
useMemo(() => {
|
||||
useEffect(() => {
|
||||
if (onChange) onChange(state);
|
||||
}, [state, onChange]);
|
||||
|
||||
@@ -154,7 +200,7 @@ export function useTableFilter<TExtra extends Record<string, unknown>>(
|
||||
);
|
||||
|
||||
const updateFilter = useCallback(
|
||||
<K extends keyof TExtra>(key: K, value: TExtra[K], resetPage = true) => {
|
||||
<K extends keyof TExtra>(key: K, value: TExtra[K], resetPage = false) => {
|
||||
dispatch({ type: 'UPDATE_FILTER', key, value, resetPage });
|
||||
},
|
||||
[dispatch]
|
||||
|
||||
Reference in New Issue
Block a user