diff --git a/src/abstract/lib/GroupBuilder/buildIdToEntityMap.ts b/src/abstract/lib/GroupBuilder/buildIdToEntityMap.ts new file mode 100644 index 000000000..52a85deb6 --- /dev/null +++ b/src/abstract/lib/GroupBuilder/buildIdToEntityMap.ts @@ -0,0 +1,8 @@ +import { Activity, ActivityFlow, Entity } from "." + +export const buildIdToEntityMap = (activities: Activity[], activityFlows?: ActivityFlow[]): Record => { + return [...activities, ...(activityFlows ?? [])].reduce>((acc, current) => { + acc[current.id] = current + return acc + }, {}) +} diff --git a/src/abstract/lib/GroupBuilder/index.ts b/src/abstract/lib/GroupBuilder/index.ts index 9676f6721..8141f540c 100644 --- a/src/abstract/lib/GroupBuilder/index.ts +++ b/src/abstract/lib/GroupBuilder/index.ts @@ -1,3 +1,4 @@ export { createActivityGroupsBuilder } from "./ActivityGroupsBuilder" export * from "./types" export * from "./activityGroups.types" +export * from "./buildIdToEntityMap" diff --git a/src/features/EntityProgressAutoCompletion/index.ts b/src/features/EntityProgressAutoCompletion/index.ts new file mode 100644 index 000000000..158607070 --- /dev/null +++ b/src/features/EntityProgressAutoCompletion/index.ts @@ -0,0 +1 @@ +export * from "./lib/useEntityProgressAutoCompletion" diff --git a/src/features/EntityProgressAutoCompletion/lib/useEntityProgressAutoCompletion.ts b/src/features/EntityProgressAutoCompletion/lib/useEntityProgressAutoCompletion.ts new file mode 100644 index 000000000..982e45d4c --- /dev/null +++ b/src/features/EntityProgressAutoCompletion/lib/useEntityProgressAutoCompletion.ts @@ -0,0 +1,93 @@ +import { useCallback, useEffect, useMemo } from "react" + +import { useLocation } from "react-router-dom" + +import { getDataFromProgressId } from "~/abstract/lib" +import { EventEntity, buildIdToEntityMap } from "~/abstract/lib/GroupBuilder" +import { AvailableGroupEvaluator } from "~/abstract/lib/GroupBuilder/AvailableGroupEvaluator" +import { GroupsBuildContext } from "~/abstract/lib/GroupBuilder/GroupUtility" +import { appletModel } from "~/entities/applet" +import { useUserEventsMutation } from "~/entities/event" +import { ROUTES } from "~/shared/constants" +import { matchPaths } from "~/shared/utils" +import { useAppSelector } from "~/shared/utils" +import { mapActivitiesFromDto } from "~/widgets/ActivityGroups/model/mappers" + +const AVAILABLE_PATHS = [ROUTES.profile.path, ROUTES.settings.path, ROUTES.appletList.path] + +export const useEntityProgressAutoCompletion = () => { + const location = useLocation() + + const { mutateAsync: getUserEvents } = useUserEventsMutation() + + const applets = useAppSelector(appletModel.selectors.appletsSelector) + + const progressKeys = useMemo(() => Object.keys(applets.groupProgress), [applets.groupProgress]) + + const isProgressEmpty = progressKeys.length === 0 + + const isValidPath = matchPaths(AVAILABLE_PATHS, location.pathname).some(Boolean) + + const performAutoCompletion = useCallback(() => { + // Here logic for auto completion + + // Step 1: Get all events from request + // const userEventsData = await getUserEvents(undefined) // I don't know about this request, I think it is not a good idea [Just example] + // const userEvents = userEventsData.data?.result + + // Step 2: Get all progress entities ids from redux + const progressEntityEvents = progressKeys.map((progressId: string) => { + return getDataFromProgressId(progressId) + }) + + console.info(progressEntityEvents) + + // Step 3: Get all activities by progress entities ids from requrest + + // Step 4: Map all activitiesDTOS into activities + const activities = mapActivitiesFromDto([]) // Provide ActivityDTO here + + const idToEntity = buildIdToEntityMap(activities) + console.info(idToEntity) + + // Step 5: Prepare input params for AvailableGroupEvaluator + const inputParams: GroupsBuildContext = { + progress: applets.groupProgress, + allAppletActivities: activities, + } + + // Step 6: Create AvailableGroupEvaluator instance + const availableEvaluator = new AvailableGroupEvaluator(inputParams) + + // Step 7: Prepate eventsEntities from userEvents and progressEntityEvents + // const events = userEvents?.reduce>((acc, ue) => acc.concat(ue.events), []) + // console.info(events) + + // This example of how to map events to EventEntity taken from src/widgets/ActivityGroups/model/services/ActivityGroupsBuildManager.ts + const eventsEntities: Array = [] + // const eventsEntities: Array = events + // .map(event => ({ + // entity: idToEntity[event.entityId], + // event, + // })) + // // @todo - remove after fix on BE + // .filter(entityEvent => !!entityEvent.entity) + + // Step 8: Evaluate available events + const filtered = availableEvaluator.evaluate(eventsEntities) + console.info(filtered) + + // Step 9: Take events which are already unavailable + + // Step 10: Get actual activity progress from the redux "progress" + + // Step 11: Process answers + // Step 12: Submit answers + }, [applets.groupProgress, getUserEvents, progressKeys]) + + useEffect(() => { + if (isValidPath && !isProgressEmpty) { + performAutoCompletion() + } + }, [isProgressEmpty, isValidPath, performAutoCompletion]) +} diff --git a/src/pages/index.tsx b/src/pages/index.tsx index 48bfb5b0d..108bd4f47 100644 --- a/src/pages/index.tsx +++ b/src/pages/index.tsx @@ -4,10 +4,13 @@ const UnauthorizedRoutes = lazy(() => import("./UnauthorizedRoutes")) const AuthorizedRoutes = lazy(() => import("./AuthorizedRoutes")) import { userModel } from "~/entities/user" +import { useEntityProgressAutoCompletion } from "~/features/EntityProgressAutoCompletion" function ApplicationRouter(): JSX.Element | null { const { isAuthorized, tokens } = userModel.hooks.useAuthorization() + useEntityProgressAutoCompletion() + if (isAuthorized) { return } diff --git a/src/widgets/ActivityGroups/model/services/ActivityGroupsBuildManager.ts b/src/widgets/ActivityGroups/model/services/ActivityGroupsBuildManager.ts index c2efaf5be..779217997 100644 --- a/src/widgets/ActivityGroups/model/services/ActivityGroupsBuildManager.ts +++ b/src/widgets/ActivityGroups/model/services/ActivityGroupsBuildManager.ts @@ -5,8 +5,8 @@ import { Activity, ActivityFlow, ActivityListGroup, - Entity, EventEntity, + buildIdToEntityMap, createActivityGroupsBuilder, } from "~/abstract/lib/GroupBuilder" import { EventModel, ScheduleEvent } from "~/entities/event" @@ -24,13 +24,6 @@ type ProcessParams = { } const createActivityGroupsBuildManager = () => { - const buildIdToEntityMap = (activities: Activity[], activityFlows: ActivityFlow[]): Record => { - return [...activities, ...activityFlows].reduce>((acc, current) => { - acc[current.id] = current - return acc - }, {}) - } - const sort = (eventEntities: EventEntity[]) => { let flows = eventEntities.filter(x => x.entity.pipelineType === ActivityPipelineType.Flow) let activities = eventEntities.filter(x => x.entity.pipelineType === ActivityPipelineType.Regular)