Loading frontend/src/views/InstructorView/index.tsx +1 −1 Original line number Diff line number Diff line Loading @@ -165,7 +165,7 @@ const InstructorView: FC<InstructorViewProps> = ({ { // TODO: I've detected performance issues there, but it could be just me. Otherwise I would just move this to it's former place.. } <Manager selectedThreadId={selectedThreadId} /> <Manager teamId={teamId} selectedThreadId={selectedThreadId} /> <div className={viewClass}> <Sidebar Loading graphql/components/Manager/actionLogComponents/SubscriptionService.tsx +7 −1 Original line number Diff line number Diff line Loading @@ -6,14 +6,20 @@ import { hidden } from './classes' interface SubscriptionServiceProps { teamId: string showNotifications?: boolean getPopup?: (actionLog: ActionLog) => ReactNode } const SubscriptionService: FC<SubscriptionServiceProps> = ({ teamId, showNotifications, getPopup, }) => { const { networkStatus } = useActionLogSubscription({ teamId, getPopup }) const { networkStatus } = useActionLogSubscription({ teamId, showNotifications, getPopup, }) return ( <div className={hidden}> {networkStatus} Loading graphql/components/Manager/index.tsx +8 −3 Original line number Diff line number Diff line Loading @@ -14,6 +14,7 @@ const portalElement = css` interface ManagerProps { getPopup?: (actionLog: ActionLog) => ReactNode teamId?: string selectedThreadId?: string } Loading @@ -23,18 +24,22 @@ interface ManagerProps { * Renders the subscription service components in a hidden portal: * necessary for the subscriptions to work in the trainee/instructor views. */ const Manager: FC<ManagerProps> = ({ getPopup, selectedThreadId }) => { const Manager: FC<ManagerProps> = ({ getPopup, teamId, selectedThreadId }) => { const { teamIds, instructorContext } = useSubscriptionContext() const subscribed = useMemo( () => teamIds.map(id => ( <div key={id}> <SubscriptionService teamId={id} getPopup={getPopup} /> <SubscriptionService teamId={id} showNotifications={instructorContext && teamId !== id} getPopup={getPopup} /> <EmailService teamId={id} selectedThreadId={selectedThreadId} /> {instructorContext && <TeamMilestonesService teamId={id} />} </div> )), [teamIds, getPopup, selectedThreadId, instructorContext] [teamIds, instructorContext, teamId, getPopup, selectedThreadId] ) return ( Loading graphql/utils/useActionLogSubscription.tsx +39 −24 Original line number Diff line number Diff line Loading @@ -3,7 +3,7 @@ import useInInstructor from '@inject/shared/hooks/useInInstructor' import { useNotifyContext } from '@inject/shared/notification/contexts/NotifyContext' import { usePopupContext } from '@inject/shared/popup/PopupContext' import type { ReactNode } from 'react' import { useCallback, useEffect } from 'react' import { useEffect } from 'react' import type { ActionLog } from '../fragments/ActionLog.generated' import type { CustomInjectDetails } from '../fragments/CustomInjectDetails.generated' import type { EmailDetails } from '../fragments/EmailDetails.generated' Loading @@ -15,16 +15,9 @@ import type { GetTeamChannelLogs } from '../queries/GetTeamChannelLogs.generated import { GetTeamChannelLogsDocument } from '../queries/GetTeamChannelLogs.generated' import type { TeamAction } from '../subscriptions/TeamActionLogs.generated' import { TeamActionDocument } from '../subscriptions/TeamActionLogs.generated' import type { LogType } from '../types' // TODO: refactor the component to use `useSubscription` instead const useActionLogSubscription = ({ teamId, getPopup, }: { teamId: string getPopup?: (actionLog: ActionLog) => ReactNode }) => { const isInCurrentContext = useCallback((actionLog: ActionLog): boolean => { const isInCurrentContext = (actionLog: ActionLog): boolean => { switch (actionLog.type) { case 'EMAIL': return window.location.pathname.includes('/email') Loading @@ -38,8 +31,34 @@ const useActionLogSubscription = ({ default: return false } }, []) } const getNotificationMessage = (type: LogType): string => { switch (type) { case 'EMAIL': return 'New email' case 'FORM': return 'New questionnaire' case 'INJECT': // fallthrough case 'CUSTOM_INJECT': return 'New inject' case 'TOOL': return 'New tool response' default: throw new Error(`Unknown log type: ${type}`) } } // TODO: refactor the component to use `useSubscription` instead const useActionLogSubscription = ({ teamId, showNotifications, getPopup, }: { teamId: string showNotifications?: boolean getPopup?: (actionLog: ActionLog) => ReactNode }) => { const [setIsUnread] = useSetIsUnreadChannel() const isInstructor = useInInstructor() const apollo = useApolloClient() Loading Loading @@ -177,13 +196,9 @@ const useActionLogSubscription = ({ }) } // TODO: don't notify if the EMAIL, CUSTOM_INJECT, or TOOL actionLog was created by the user const newMessageText = `New message in ${newActionLog.channel.name}` if (newActionLog.team.id === teamId) { if (showNotifications) { notify( isInstructor ? `${newActionLog.team.name}: ${newMessageText}` : newMessageText, `${newActionLog.team.name}: ${getNotificationMessage(newActionLog.type)}`, {}, new Date(newActionLog.timestamp || 0) ) Loading @@ -203,8 +218,8 @@ const useActionLogSubscription = ({ isInstructor, showPopup, getPopup, isInCurrentContext, setIsUnread, showNotifications, ] ) Loading Loading
frontend/src/views/InstructorView/index.tsx +1 −1 Original line number Diff line number Diff line Loading @@ -165,7 +165,7 @@ const InstructorView: FC<InstructorViewProps> = ({ { // TODO: I've detected performance issues there, but it could be just me. Otherwise I would just move this to it's former place.. } <Manager selectedThreadId={selectedThreadId} /> <Manager teamId={teamId} selectedThreadId={selectedThreadId} /> <div className={viewClass}> <Sidebar Loading
graphql/components/Manager/actionLogComponents/SubscriptionService.tsx +7 −1 Original line number Diff line number Diff line Loading @@ -6,14 +6,20 @@ import { hidden } from './classes' interface SubscriptionServiceProps { teamId: string showNotifications?: boolean getPopup?: (actionLog: ActionLog) => ReactNode } const SubscriptionService: FC<SubscriptionServiceProps> = ({ teamId, showNotifications, getPopup, }) => { const { networkStatus } = useActionLogSubscription({ teamId, getPopup }) const { networkStatus } = useActionLogSubscription({ teamId, showNotifications, getPopup, }) return ( <div className={hidden}> {networkStatus} Loading
graphql/components/Manager/index.tsx +8 −3 Original line number Diff line number Diff line Loading @@ -14,6 +14,7 @@ const portalElement = css` interface ManagerProps { getPopup?: (actionLog: ActionLog) => ReactNode teamId?: string selectedThreadId?: string } Loading @@ -23,18 +24,22 @@ interface ManagerProps { * Renders the subscription service components in a hidden portal: * necessary for the subscriptions to work in the trainee/instructor views. */ const Manager: FC<ManagerProps> = ({ getPopup, selectedThreadId }) => { const Manager: FC<ManagerProps> = ({ getPopup, teamId, selectedThreadId }) => { const { teamIds, instructorContext } = useSubscriptionContext() const subscribed = useMemo( () => teamIds.map(id => ( <div key={id}> <SubscriptionService teamId={id} getPopup={getPopup} /> <SubscriptionService teamId={id} showNotifications={instructorContext && teamId !== id} getPopup={getPopup} /> <EmailService teamId={id} selectedThreadId={selectedThreadId} /> {instructorContext && <TeamMilestonesService teamId={id} />} </div> )), [teamIds, getPopup, selectedThreadId, instructorContext] [teamIds, instructorContext, teamId, getPopup, selectedThreadId] ) return ( Loading
graphql/utils/useActionLogSubscription.tsx +39 −24 Original line number Diff line number Diff line Loading @@ -3,7 +3,7 @@ import useInInstructor from '@inject/shared/hooks/useInInstructor' import { useNotifyContext } from '@inject/shared/notification/contexts/NotifyContext' import { usePopupContext } from '@inject/shared/popup/PopupContext' import type { ReactNode } from 'react' import { useCallback, useEffect } from 'react' import { useEffect } from 'react' import type { ActionLog } from '../fragments/ActionLog.generated' import type { CustomInjectDetails } from '../fragments/CustomInjectDetails.generated' import type { EmailDetails } from '../fragments/EmailDetails.generated' Loading @@ -15,16 +15,9 @@ import type { GetTeamChannelLogs } from '../queries/GetTeamChannelLogs.generated import { GetTeamChannelLogsDocument } from '../queries/GetTeamChannelLogs.generated' import type { TeamAction } from '../subscriptions/TeamActionLogs.generated' import { TeamActionDocument } from '../subscriptions/TeamActionLogs.generated' import type { LogType } from '../types' // TODO: refactor the component to use `useSubscription` instead const useActionLogSubscription = ({ teamId, getPopup, }: { teamId: string getPopup?: (actionLog: ActionLog) => ReactNode }) => { const isInCurrentContext = useCallback((actionLog: ActionLog): boolean => { const isInCurrentContext = (actionLog: ActionLog): boolean => { switch (actionLog.type) { case 'EMAIL': return window.location.pathname.includes('/email') Loading @@ -38,8 +31,34 @@ const useActionLogSubscription = ({ default: return false } }, []) } const getNotificationMessage = (type: LogType): string => { switch (type) { case 'EMAIL': return 'New email' case 'FORM': return 'New questionnaire' case 'INJECT': // fallthrough case 'CUSTOM_INJECT': return 'New inject' case 'TOOL': return 'New tool response' default: throw new Error(`Unknown log type: ${type}`) } } // TODO: refactor the component to use `useSubscription` instead const useActionLogSubscription = ({ teamId, showNotifications, getPopup, }: { teamId: string showNotifications?: boolean getPopup?: (actionLog: ActionLog) => ReactNode }) => { const [setIsUnread] = useSetIsUnreadChannel() const isInstructor = useInInstructor() const apollo = useApolloClient() Loading Loading @@ -177,13 +196,9 @@ const useActionLogSubscription = ({ }) } // TODO: don't notify if the EMAIL, CUSTOM_INJECT, or TOOL actionLog was created by the user const newMessageText = `New message in ${newActionLog.channel.name}` if (newActionLog.team.id === teamId) { if (showNotifications) { notify( isInstructor ? `${newActionLog.team.name}: ${newMessageText}` : newMessageText, `${newActionLog.team.name}: ${getNotificationMessage(newActionLog.type)}`, {}, new Date(newActionLog.timestamp || 0) ) Loading @@ -203,8 +218,8 @@ const useActionLogSubscription = ({ isInstructor, showPopup, getPopup, isInCurrentContext, setIsUnread, showNotifications, ] ) Loading