diff --git a/src/data-fetching/index.ts b/src/data-fetching/index.ts index dce40e959..596b1ea45 100644 --- a/src/data-fetching/index.ts +++ b/src/data-fetching/index.ts @@ -4,3 +4,4 @@ export { useDoc } from './useDoc/useDoc' export { useDoctype } from './useDoctype/useDoctype' export { useNewDoc } from './useNewDoc/useNewDoc' export { useFrappeFetch } from './useFrappeFetch' +export { useBulkUpdate } from './useBulkUpdate/useBulkUpdate' diff --git a/src/data-fetching/useBulkUpdate/useBulkUpdate.test.ts b/src/data-fetching/useBulkUpdate/useBulkUpdate.test.ts new file mode 100644 index 000000000..a12b509d1 --- /dev/null +++ b/src/data-fetching/useBulkUpdate/useBulkUpdate.test.ts @@ -0,0 +1,38 @@ +/** + * @vitest-environment node + */ + +import { ref } from 'vue' +import { baseUrl, waitUntilValueChanges } from '../../mocks/utils' +import { useBulkUpdate } from '../index' + +describe.skip('useBulkUpdate', () => { + it('it returns expected object', async () => { + let bulkUpdate = useBulkUpdate({ baseUrl }) + + // Verify initial state + expect(bulkUpdate.data).toBe(null) + expect(bulkUpdate.error).toBe(null) + expect(typeof bulkUpdate.submit).toBe('function') + + bulkUpdate.submit([ + { doctype: 'User', name: 'user3', email: 'user3@example.com' }, + { doctype: 'User', name: 'user4', email: 'user4@example.com' }, + { doctype: 'User', name: 'user5', email: 'user5@example.com' }, + ]) + + await waitUntilValueChanges(() => bulkUpdate.data) + + console.log(bulkUpdate) + + // Verify final state + expect(bulkUpdate.data).toStrictEqual([ + { doctype: 'User', name: 'user3', email: 'user3@example.com' }, + { doctype: 'User', name: 'user4', email: 'user4@example.com' }, + { doctype: 'User', name: 'user5', email: 'user5@example.com' }, + ]) + expect(bulkUpdate.error).toBe(null) + expect(bulkUpdate.isFinished).toBe(true) + expect(bulkUpdate.loading).toBe(false) + }) +}) diff --git a/src/data-fetching/useBulkUpdate/useBulkUpdate.ts b/src/data-fetching/useBulkUpdate/useBulkUpdate.ts new file mode 100644 index 000000000..4d41be4cd --- /dev/null +++ b/src/data-fetching/useBulkUpdate/useBulkUpdate.ts @@ -0,0 +1,52 @@ +import { reactive, readonly, ref, type Ref } from 'vue' +import { useCall } from '../useCall/useCall' +import { listStore } from '../useList/listStore' +import { docStore } from '../docStore' + +export interface BulkUpdateOptions { + baseUrl?: string +} + +export interface DocumentUpdate { + doctype: string + name: string + [key: string]: any +} + +export function useBulkUpdate(options: BulkUpdateOptions = {}) { + const bulkUpdateCall = useCall({ + method: 'POST', + url: '/api/v2/method/bulk_update', + immediate: false, + refetch: false, + ...options, + transform(data) { + return data.map((row) => ({ + ...row, + name: String(row.name), + })) + }, + onSuccess(data) { + listStore.updateRows(data) + docStore.setDocs(data) + }, + }) + + async function submit(docs: DocumentUpdate[]) { + return bulkUpdateCall.submit({ docs }) + } + + return reactive({ + data: bulkUpdateCall.data, + error: bulkUpdateCall.error, + loading: bulkUpdateCall.loading, + isFinished: bulkUpdateCall.isFinished, + isFetching: bulkUpdateCall.isFetching, + canAbort: bulkUpdateCall.canAbort, + abort: bulkUpdateCall.abort, + aborted: bulkUpdateCall.aborted, + reset: bulkUpdateCall.reset, + execute: submit, + submit, + }) +} diff --git a/src/mocks/handlers.ts b/src/mocks/handlers.ts index 742921bcc..0496c11c3 100644 --- a/src/mocks/handlers.ts +++ b/src/mocks/handlers.ts @@ -90,6 +90,23 @@ export const handlers = [ }) }, ), + + http.post(url('/api/v2/method/bulk_update'), async ({ request }) => { + const body = (await request.json()) as any + const docs = body.docs || [] + + // For bulk update, documents should already have names + // Just return the updated documents as-is + const updatedDocs = docs.map((doc: any) => { + return { + ...doc, + } + }) + + return HttpResponse.json({ + data: updatedDocs, + }) + }), ] function getUsers(listParams) {