Skip to content

Commit

Permalink
feat: #1230533 fallback on replace or massReplace if PATCH method is …
Browse files Browse the repository at this point in the history
…not available for an entity
  • Loading branch information
botisSmile committed Nov 22, 2023
1 parent 8017fc2 commit 02dd1c9
Show file tree
Hide file tree
Showing 5 changed files with 67 additions and 5 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ function ResourceTable(props: IResourceTable): JSX.Element {
const rowsPerPageOptions = defaultRowsPerPageOptions
const [rowsPerPage, setRowsPerPage] = useState<number>(defaultPageSize)

const [resourceData, { massUpdate, replace, update }] =
const [resourceData, { massUpdate, massReplace, replace, update }] =
useApiEditableList<ISourceField>(
resource,
page,
Expand Down Expand Up @@ -199,6 +199,8 @@ function ResourceTable(props: IResourceTable): JSX.Element {
): void {
if (update) {
update(id, { [name]: value })
} else if (replace) {
replace({ id, [name]: value } as unknown as ISourceField)
}
}

Expand Down Expand Up @@ -278,6 +280,7 @@ function ResourceTable(props: IResourceTable): JSX.Element {
filterOrSearchAreUp
}
onMassupdate={massUpdate}
onMassreplace={massReplace}
onPageChange={handlePageChange}
onRowUpdate={handleRowChange}
onRowsPerPageChange={onRowsPerPageChange}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import {
IFieldGuesserProps,
IHydraMember,
IResource,
IResourceEditableMassReplace,
IResourceEditableMassUpdate,
ITableConfig,
ITableRow,
Expand All @@ -31,6 +32,7 @@ interface IProps<T extends IHydraMember> {
currentPage?: number
diffRows?: ITableRow[]
onMassupdate: IResourceEditableMassUpdate<T>
onMassreplace: IResourceEditableMassReplace<T>
onPageChange: (page: number) => void
onRowUpdate?: (
id: string | number,
Expand Down Expand Up @@ -58,6 +60,7 @@ function TableGuesser<T extends IHydraMember>(props: IProps<T>): JSX.Element {
currentPage,
diffRows,
onMassupdate,
onMassreplace,
onPageChange,
onRowUpdate,
resource,
Expand Down Expand Up @@ -112,10 +115,16 @@ function TableGuesser<T extends IHydraMember>(props: IProps<T>): JSX.Element {
}

function handleApply(): void {
if (onMassupdate && selectedField !== '') {
onMassupdate(selectedRows, {
[selectedField.title]: selectedValue,
} as unknown as Partial<T>)
if (selectedField !== '') {
if (onMassupdate) {
onMassupdate(selectedRows, {
[selectedField.title]: selectedValue,
} as unknown as Partial<T>)
} else if (onMassreplace) {
onMassreplace(selectedRows, {
[selectedField.title]: selectedValue,
} as unknown as Omit<T, '@id' | '@type'>)
}
}
}

Expand Down
20 changes: 20 additions & 0 deletions packages/components/src/hooks/useApi.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -389,5 +389,25 @@ describe('useApi', () => {
true
)
})

it('should call the API (massReplace)', async () => {
const { result } = renderHookWithProviders(() =>
useApiEditableList<ITest>(resource)
)
await waitFor(() =>
expect(result.current[0].data['hydra:member'].length).toEqual(2)
)
;(fetchApi as jest.Mock).mockClear()
await act(() =>
result.current[1].massReplace([1], { id: 1, hello: 'world' })
)
expect(fetchApi).toHaveBeenCalledWith(
'en',
'https://localhost/metadata/1',
undefined,
{ body: '{"id":1,"hello":"world"}', method: 'PUT' },
true
)
})
})
})
25 changes: 25 additions & 0 deletions packages/components/src/hooks/useApi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,29 @@ export function useApiEditableList<T extends IHydraMember>(
[load, searchParameters, searchValue, update, updateList]
)

const massEditableReplace = useCallback(
async (
ids: (string | number)[],
updatedItem: Omit<T, '@id' | '@type'>
): Promise<void> => {
updateList((items) =>
items.map((item) =>
ids.includes(item.id) ? { ...item, ...updatedItem } : item
)
)
const promises = ids.map((id) =>
replace({ id, ...updatedItem } as unknown as T)
)
const responses = await Promise.all(promises)
const hasError = responses.some((response) => isError(response))
if (hasError || searchParameters || searchValue) {
// reload if error or if any filter is applied
load()
}
},
[load, searchParameters, searchValue, replace, updateList]
)

const editableCreate = useCallback(
async (item: Omit<T, 'id' | '@id' | '@type'>): Promise<void> => {
const createResponse = await create(item)
Expand Down Expand Up @@ -272,6 +295,7 @@ export function useApiEditableList<T extends IHydraMember>(
}
if (replace) {
operations.replace = editableReplace
operations.massReplace = massEditableReplace
}
if (remove) {
operations.remove = editableRemove
Expand All @@ -284,6 +308,7 @@ export function useApiEditableList<T extends IHydraMember>(
editableReplace,
editableUpdate,
massEditableUpdate,
massEditableReplace,
remove,
replace,
update,
Expand Down
5 changes: 5 additions & 0 deletions packages/shared/src/types/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,10 @@ export type IResourceEditableMassUpdate<T> = (
ids: (string | number)[],
item: Partial<T>
) => Promise<void>
export type IResourceEditableMassReplace<T> = (
ids: (string | number)[],
item: Omit<T, '@id' | '@type'>
) => Promise<void>
export type IResourceEditableRemove = (id: string | number) => Promise<void>
export type IResourceEditableReplace<T> = (
item: Omit<T, '@id' | '@type'>
Expand All @@ -75,6 +79,7 @@ export type IResourceEditableUpdate<T> = (
export interface IResourceEditableOperations<T> {
create?: IResourceEditableCreate<T>
massUpdate?: IResourceEditableMassUpdate<T>
massReplace?: IResourceEditableMassReplace<T>
remove?: IResourceEditableRemove
replace?: IResourceEditableReplace<T>
update?: IResourceEditableUpdate<T>
Expand Down

0 comments on commit 02dd1c9

Please sign in to comment.