diff --git a/src/Bones.UI/core/composableFactory.ts b/src/Bones.UI/core/composableFactory.ts index d748127..284c8ce 100644 --- a/src/Bones.UI/core/composableFactory.ts +++ b/src/Bones.UI/core/composableFactory.ts @@ -6,170 +6,23 @@ import { onCollectionChanged, onEntityChanged } from "../tools"; export class ComposableFactory { public static get(service: { get(id: string): Promise } & INotifyService, applyFactory?: () => (entity: Ref) => void) { - return () => { - const apply = applyFactory ? applyFactory() : () => { }; - let subscribersIds: number[] = []; - - onUnmounted(() => { - subscribersIds.forEach(id => service.unsubscribe(id)); - subscribersIds = []; - }); - - const getting = ref(false); - const entity = ref(null) as Ref; - - const get = async (id: string) => { - getting.value = true; - try { - entity.value = await service.get(id); - if (apply) apply(entity as Ref); - } - finally { - getting.value = false; - } - - subscribersIds.push(service.subscribe("all", onEntityChanged(entity, apply))); - - return entity; - } - - return { - getting: getting, - get, - entity: entity - } - } + return ComposableFactory.customGet(service, service.get, applyFactory); } public static getMany(service: { getMany(filter?: TFilter): Promise } & INotifyService, applyFactory?: () => (entities: Ref) => void) { - return () => { - const apply = applyFactory ? applyFactory() : () => { }; - let subscribersIds: number[] = []; - - onUnmounted(() => { - subscribersIds.forEach(id => service.unsubscribe(id)); - subscribersIds = []; - }); - - const fetching = ref(false); - const entities = ref([]) as Ref; - - const getMany = async (filter?: TFilter, customFilter?: (el: TDetails) => boolean) => { - fetching.value = true; - try { - entities.value = await service.getMany(filter); - if (apply) apply(entities) - } - finally { - fetching.value = false; - } - - const filterMethod = customFilter || (filter ? FilterFactory.create(filter) : (el: TInfos) => true); - - subscribersIds.push(service.subscribe("all", onCollectionChanged(entities, filterMethod))); - - return entities; - } - - return { - fetching: fetching, - getMany, - entities: entities - } - } + return ComposableFactory.customGetMany(service, service.getMany, applyFactory); } public static create(service: { create(payload: TCreateDTO): Promise } & INotifyService, applyFactory?: () => (entity: Ref) => void) { - return () => { - const apply = applyFactory ? applyFactory() : () => { }; - let subscribersIds: number[] = []; - - onUnmounted(() => { - subscribersIds.forEach(id => service.unsubscribe(id)); - subscribersIds = []; - }); - - const creating = ref(false); - const created = ref(null) as Ref; - - const create = async (payload: TCreateDTO) => { - creating.value = true; - try { - created.value = await service.create(payload); - if (apply) apply(created as Ref); - } - finally { - creating.value = false; - } - - subscribersIds.push(service.subscribe("all", onEntityChanged(created))); - - return created as Ref; - } - - return { - creating: creating, - create, - created: created - } - } + return ComposableFactory.customCreate(service, service.create, applyFactory); } public static update(service: { update(id: string, payload: TUpdateDTO): Promise } & INotifyService, applyFactory?: () => (entity: Ref) => void) { - return () => { - const apply = applyFactory ? applyFactory() : () => { }; - let subscribersIds: number[] = []; - - onUnmounted(() => { - subscribersIds.forEach(id => service.unsubscribe(id)); - subscribersIds = []; - }); - - const updating = ref(false); - const updated = ref(null) as Ref; - - const update = async (id: string, payload: TUpdateDTO) => { - updating.value = true; - try { - updated.value = await service.update(id, payload); - if (apply) apply(updated as Ref); - } - finally { - updating.value = false; - } - - subscribersIds.push(service.subscribe("all", onEntityChanged(updated))); - - return updated.value as Ref; - } - - return { - updating: updating, - update, - updated: updated - } - } + return ComposableFactory.customUpdate(service, service.update, applyFactory); } public static remove(service: { remove(id: string): Promise }) { - return () => { - const removing = ref(false); - - const remove = async (id: string) => { - removing.value = true; - try { - await service.remove(id); - } - finally { - removing.value = false; - } - } - - return { - removing: removing, - remove - } - } + return ComposableFactory.customRemove(service.remove); } public static custom(method: (...args: TArgs) => Promise, applyFactory?: () => (entity: Ref) => void) { @@ -237,7 +90,11 @@ export class ComposableFactory { } } - public static customGetMany(service: INotifyService, method: (...args: TArgs) => Promise, applyFactory?: () => (entities: Ref) => void) { + /** + * Warning : read the code before using this method, the first argument in the method is used to create a filter + * The last argument passed to the getMany composable can be a custom filter function that will override the default filter + * */ + public static customGetMany(service: INotifyService, method: (...args: TArgs) => Promise, applyFactory?: () => (entities: Ref) => void) { return () => { const apply = applyFactory ? applyFactory() : () => { }; let subscribersIds: number[] = []; @@ -250,17 +107,26 @@ export class ComposableFactory { const fetching = ref(false); const entities = ref([]) as Ref; - const getMany = async ( customFilter?: (el: TDetails) => boolean, ...args: TArgs) => { + const getMany = async (...args: [...TArgs, ((el: TDetails) => boolean)?]) => { fetching.value = true; + + let customFilter: ((el: TDetails) => boolean) | undefined = undefined + + if(args.length > 1 && typeof args[args.length - 1] === 'function') { + customFilter = args.pop(); + } + + let actualArgs = args as unknown as TArgs; + try { - entities.value = await method(...args); + entities.value = await method(...actualArgs); if (apply) apply(entities) } finally { fetching.value = false; } - const filterMethod = customFilter || ((el: TInfos) => true); + const filterMethod = customFilter || (actualArgs.length > 0 ? FilterFactory.create(actualArgs[0]) : () => true); subscribersIds.push(service.subscribe("all", onCollectionChanged(entities, filterMethod))); @@ -461,5 +327,4 @@ export class ComposableFactory { } } } - } \ No newline at end of file diff --git a/tests/Bones.UI.Tests/services/testUserService.ts b/tests/Bones.UI.Tests/services/testUserService.ts index e35acdc..8a5aced 100644 --- a/tests/Bones.UI.Tests/services/testUserService.ts +++ b/tests/Bones.UI.Tests/services/testUserService.ts @@ -15,6 +15,7 @@ const AccountLoginFactory = new ServiceFactory axios.get(TEST_USERS_URL), (dto: TestUserDetailsDTO) => new TestUserDetails(dto)), ServiceFactory.addCustom("current", axios => axios.get(TEST_USERS_URL), (dto: TestUserDetailsDTO) => new TestUserDetails(dto)), ServiceFactory.addCustom("complexCurrent", (axios, p1: string, p2: number) => axios.get(TEST_USERS_URL), (dto: TestUserDetailsDTO) => new TestUserDetails(dto)), + ServiceFactory.addCustom("complexGetMany", (axios, p1: string, p2: number) => axios.get(TEST_USERS_URL), (dto: TestUserDetailsDTO) => new Array(5).map(a => new TestUserDetails(dto))), )); export const useTestUsersSync = ComposableFactory.sync(testUserServiceFactory); @@ -42,11 +43,12 @@ export const useTestUser = ComposableFactory.get(testUserServiceFactory, () => { } }); -AccountLoginFactory.complexCurrent("p1", 1); -AccountLoginFactory.current(); +// AccountLoginFactory.complexCurrent("p1", 1); +// AccountLoginFactory.current(); export const useCurrentUser = ComposableFactory.customGet(AccountLoginFactory, AccountLoginFactory.current); export const useComplexCurrentUser = ComposableFactory.customGet(AccountLoginFactory, AccountLoginFactory.complexCurrent); +export const useComplexGetMany = ComposableFactory.customGetMany(AccountLoginFactory, AccountLoginFactory.complexGetMany); export const useTestUsers = ComposableFactory.getMany(testUserServiceFactory); export const useCreateTestUser = ComposableFactory.create(testUserServiceFactory);