Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[M2-4923] Feature: In Progress Activities and Flows Auto-Completion #363

Closed
wants to merge 12 commits into from
8 changes: 8 additions & 0 deletions src/abstract/lib/GroupBuilder/buildIdToEntityMap.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { Activity, ActivityFlow, Entity } from "."

export const buildIdToEntityMap = (activities: Activity[], activityFlows?: ActivityFlow[]): Record<string, Entity> => {
return [...activities, ...(activityFlows ?? [])].reduce<Record<string, Entity>>((acc, current) => {
acc[current.id] = current
return acc
}, {})
}
1 change: 1 addition & 0 deletions src/abstract/lib/GroupBuilder/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
export { createActivityGroupsBuilder } from "./ActivityGroupsBuilder"
export * from "./types"
export * from "./activityGroups.types"
export * from "./buildIdToEntityMap"
1 change: 1 addition & 0 deletions src/features/EntityProgressAutoCompletion/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from "./lib/useEntityProgressAutoCompletion"
Original file line number Diff line number Diff line change
@@ -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<Array<ScheduleEventDto>>((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<EventEntity> = []
// const eventsEntities: Array<EventEntity> = events
// .map<EventEntity>(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])
}
3 changes: 3 additions & 0 deletions src/pages/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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 <AuthorizedRoutes refreshToken={tokens.refreshToken} />
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ import {
Activity,
ActivityFlow,
ActivityListGroup,
Entity,
EventEntity,
buildIdToEntityMap,
createActivityGroupsBuilder,
} from "~/abstract/lib/GroupBuilder"
import { EventModel, ScheduleEvent } from "~/entities/event"
Expand All @@ -24,13 +24,6 @@ type ProcessParams = {
}

const createActivityGroupsBuildManager = () => {
const buildIdToEntityMap = (activities: Activity[], activityFlows: ActivityFlow[]): Record<string, Entity> => {
return [...activities, ...activityFlows].reduce<Record<string, Entity>>((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)
Expand Down