bigbuffet-rw/app/soapbox/entity-store/hooks/useEntityActions.ts

75 lines
1.9 KiB
TypeScript
Raw Normal View History

2023-03-14 12:24:11 -07:00
import { z } from 'zod';
import { useApi, useAppDispatch } from 'soapbox/hooks';
2023-03-14 12:24:11 -07:00
import { importEntities } from '../actions';
import { useDeleteEntity } from './useDeleteEntity';
2023-03-14 12:24:11 -07:00
import type { Entity } from '../types';
import type { EntitySchema } from './types';
import type { AxiosResponse } from 'axios';
type EntityPath = [entityType: string, listKey?: string]
interface UseEntityActionsOpts<TEntity extends Entity = Entity> {
schema?: EntitySchema<TEntity>
}
interface CreateEntityResult<TEntity extends Entity = Entity> {
response: AxiosResponse
entity: TEntity
}
interface EntityActionEndpoints {
post?: string
delete?: string
}
interface EntityCallbacks<TEntity extends Entity = Entity> {
onSuccess?(entity: TEntity): void
}
2023-03-14 12:24:11 -07:00
function useEntityActions<TEntity extends Entity = Entity, P = any>(
path: EntityPath,
endpoints: EntityActionEndpoints,
opts: UseEntityActionsOpts<TEntity> = {},
) {
const [entityType, listKey] = path;
2023-03-14 12:24:11 -07:00
const api = useApi();
const dispatch = useAppDispatch();
const deleteEntity = useDeleteEntity(entityType, (entityId) => {
if (!endpoints.delete) return Promise.reject(endpoints);
return api.delete(endpoints.delete.replace(':id', entityId));
});
2023-03-14 12:24:11 -07:00
function createEntity(params: P, callbacks: EntityCallbacks = {}): Promise<CreateEntityResult<TEntity>> {
2023-03-14 12:24:11 -07:00
if (!endpoints.post) return Promise.reject(endpoints);
return api.post(endpoints.post, params).then((response) => {
const schema = opts.schema || z.custom<TEntity>();
const entity = schema.parse(response.data);
// TODO: optimistic updating
dispatch(importEntities([entity], entityType, listKey));
if (callbacks.onSuccess) {
callbacks.onSuccess(entity);
}
2023-03-14 12:24:11 -07:00
return {
response,
entity,
};
});
}
return {
2023-03-15 11:51:25 -07:00
createEntity: createEntity,
2023-03-14 12:24:11 -07:00
deleteEntity: endpoints.delete ? deleteEntity : undefined,
};
}
export { useEntityActions };