Loading analyst/src/components/NavigationBar/index.tsx +27 −15 Original line number Diff line number Diff line Loading @@ -29,11 +29,12 @@ import { useCallback, useContext, useMemo } from 'react' import { ExercisePageRoute } from '../../routes/_layout/$exerciseId' import { ActionLogsRoute } from '../../routes/_layout/$exerciseId/action-logs' import { CauseAndEffectRoute } from '../../routes/_layout/$exerciseId/cuase-and-effect' import { CauseAndEffectRoute } from '../../routes/_layout/$exerciseId/cause-and-effect' import { EmailPageRoute } from '../../routes/_layout/$exerciseId/emails' import { LearningObjectivesPageRoute } from '../../routes/_layout/$exerciseId/learning-objectives' import { MilestonesPageRoute } from '../../routes/_layout/$exerciseId/milestones' import { QuestionnairesPageRoute } from '../../routes/_layout/$exerciseId/questionnaires' import { RoomViewRoute } from '../../routes/_layout/$exerciseId/room' import { SelectTeamsPageRoute } from '../../routes/_layout/$exerciseId/select-teams' import { ToolsPageRoute } from '../../routes/_layout/$exerciseId/tools' import { ExerciseContext } from '../ExerciseContext' Loading Loading @@ -98,9 +99,29 @@ export const NavigationBar: FC<NavigationBarProps> = ({ }, }, icon: 'control', text: 'Overview', text: 'Performance Overview', end: true, }) paths.push({ link: { to: RoomViewRoute.to, params: { exerciseId, }, }, icon: 'grid-view', text: 'Room View', }) paths.push({ link: { to: CauseAndEffectRoute.to, params: { exerciseId, }, }, icon: 'one-to-many', text: 'Cause and Effect', }) paths.push({ link: { to: ActionLogsRoute.to, Loading Loading @@ -153,7 +174,7 @@ export const NavigationBar: FC<NavigationBarProps> = ({ }, }, icon: 'console', text: 'Tools', text: 'Tool Usage', }) } if (questionnairesEnabled) { Loading @@ -168,16 +189,6 @@ export const NavigationBar: FC<NavigationBarProps> = ({ text: 'Questionnaires', }) } paths.push({ link: { to: CauseAndEffectRoute.to, params: { exerciseId, }, }, icon: 'one-to-many', text: 'Cause and Effect', }) return paths }, [emailsEnabled, exerciseId, questionnairesEnabled, toolsEnabled]) Loading Loading @@ -259,8 +270,8 @@ export const NavigationBar: FC<NavigationBarProps> = ({ ...(exerciseId && teams.length ? [ { id: 'pages', name: 'Pages', id: 'views', name: 'Views', node: ( <> {paths.map(path => ( Loading Loading @@ -306,6 +317,7 @@ export const NavigationBar: FC<NavigationBarProps> = ({ sections={sections} hideNames={hide} showLogo title={exercise.name} /> <div Loading analyst/src/components/RoomViewConfig/index.tsx 0 → 100644 +180 −0 Original line number Diff line number Diff line import { Button, ButtonGroup, Divider, FormGroup, NumericInput, } from '@blueprintjs/core' import { css } from '@emotion/css' import type { Team } from '@inject/graphql' import type { DraggableGridConfig } from '@inject/shared' import type { SetState } from 'ahooks/lib/createUseStorageState' import type { FC } from 'react' const mainContainer = css` display: flex; gap: 1rem; ` const sizeSection = css` display: flex; gap: 1rem; max-width: 20rem; ` const form = css` margin-bottom: 0; ` const layoutSection = css` flex: 1; display: flex; justify-content: flex-end; ` const buttonGroup = css` align-self: flex-start; ` // TODO: make the config collapsible // TODO: add export and import layout export type RoomViewConfig = { hideTeamLabels: boolean } interface RoomViewConfigComponentProps { teams: Team[] gridConfig: DraggableGridConfig<Team> setGridConfig: ( value?: SetState<DraggableGridConfig<Team>> | undefined ) => void gridConfigDefault: DraggableGridConfig<Team> viewConfig: RoomViewConfig setViewConfig: (value?: SetState<RoomViewConfig> | undefined) => void viewConfigDefault: RoomViewConfig } export const RoomViewConfigComponent: FC<RoomViewConfigComponentProps> = ({ teams, gridConfig, setGridConfig, gridConfigDefault, viewConfig, setViewConfig, viewConfigDefault, }) => ( <main className={mainContainer}> <section className={sizeSection}> <FormGroup className={form} fill labelFor='columns' label='Columns'> <NumericInput id='columns' fill disabled={gridConfig.editing} value={gridConfig.columns} onValueChange={value => setGridConfig(prev => ({ ...(prev ?? gridConfigDefault), columns: value, })) } min={Math.max(1, Math.ceil(teams.length / gridConfig.rows))} /> </FormGroup> <FormGroup className={form} fill labelFor='rows' label='Rows'> <NumericInput id='rows' fill disabled={gridConfig.editing} value={gridConfig.rows} onValueChange={value => setGridConfig(prev => ({ ...(prev ?? gridConfigDefault), rows: value, })) } min={Math.max(1, Math.ceil(teams.length / gridConfig.columns))} /> </FormGroup> </section> <section className={layoutSection}> <ButtonGroup className={buttonGroup}> <Button icon='label' onClick={() => setViewConfig(prev => ({ ...(prev ?? viewConfigDefault), hideTeamLabels: !(prev ?? viewConfigDefault).hideTeamLabels, })) } text={ <span style={{ whiteSpace: 'nowrap', }} > {viewConfig.hideTeamLabels ? 'Show team labels' : 'Hide team labels'} </span> } /> <Divider /> {gridConfig.editing ? ( <> <Button icon='floppy-disk' onClick={() => setGridConfig(prev => ({ ...(prev ?? gridConfigDefault), editing: false, cells: prev?.editedCells ?? gridConfigDefault.cells, editedCells: [], })) } intent='primary' text='Save layout' /> <Button icon='cross' onClick={() => setGridConfig(prev => ({ ...(prev ?? gridConfigDefault), editing: false, editedCells: [], })) } text='Cancel' /> </> ) : ( <> <Button icon='edit' onClick={() => setGridConfig(prev => ({ ...(prev ?? gridConfigDefault), editing: true, editedCells: prev?.cells ?? gridConfigDefault.cells, })) } text='Edit layout' /> <Button icon='reset' onClick={() => setGridConfig(prev => ({ ...(prev ?? gridConfigDefault), cells: gridConfigDefault.cells, })) } text='Reset layout' /> </> )} </ButtonGroup> </section> </main> ) analyst/src/routeTree.gen.ts +48 −21 Original line number Diff line number Diff line Loading @@ -17,10 +17,11 @@ import { Route as LayoutExerciseIdRouteImport } from './routes/_layout/$exercise import { Route as LayoutExerciseIdIndexImport } from './routes/_layout/$exerciseId/index' import { Route as LayoutExerciseIdToolsImport } from './routes/_layout/$exerciseId/tools' import { Route as LayoutExerciseIdSelectTeamsImport } from './routes/_layout/$exerciseId/select-teams' import { Route as LayoutExerciseIdRoomImport } from './routes/_layout/$exerciseId/room' import { Route as LayoutExerciseIdQuestionnairesImport } from './routes/_layout/$exerciseId/questionnaires' import { Route as LayoutExerciseIdMilestonesImport } from './routes/_layout/$exerciseId/milestones' import { Route as LayoutExerciseIdLearningObjectivesImport } from './routes/_layout/$exerciseId/learning-objectives' import { Route as LayoutExerciseIdCuaseAndEffectImport } from './routes/_layout/$exerciseId/cuase-and-effect' import { Route as LayoutExerciseIdCauseAndEffectImport } from './routes/_layout/$exerciseId/cause-and-effect' import { Route as LayoutExerciseIdActionLogsImport } from './routes/_layout/$exerciseId/action-logs' import { Route as LayoutExerciseIdEmailsRouteImport } from './routes/_layout/$exerciseId/emails/route' import { Route as LayoutExerciseIdEmailsIndexImport } from './routes/_layout/$exerciseId/emails/index' Loading Loading @@ -65,6 +66,12 @@ const LayoutExerciseIdSelectTeamsRoute = getParentRoute: () => LayoutExerciseIdRouteRoute, } as any) const LayoutExerciseIdRoomRoute = LayoutExerciseIdRoomImport.update({ id: '/room', path: '/room', getParentRoute: () => LayoutExerciseIdRouteRoute, } as any) const LayoutExerciseIdQuestionnairesRoute = LayoutExerciseIdQuestionnairesImport.update({ id: '/questionnaires', Loading @@ -87,10 +94,10 @@ const LayoutExerciseIdLearningObjectivesRoute = getParentRoute: () => LayoutExerciseIdRouteRoute, } as any) const LayoutExerciseIdCuaseAndEffectRoute = LayoutExerciseIdCuaseAndEffectImport.update({ id: '/cuase-and-effect', path: '/cuase-and-effect', const LayoutExerciseIdCauseAndEffectRoute = LayoutExerciseIdCauseAndEffectImport.update({ id: '/cause-and-effect', path: '/cause-and-effect', getParentRoute: () => LayoutExerciseIdRouteRoute, } as any) Loading Loading @@ -170,11 +177,11 @@ declare module '@tanstack/react-router' { preLoaderRoute: typeof LayoutExerciseIdActionLogsImport parentRoute: typeof LayoutExerciseIdRouteImport } '/_layout/$exerciseId/cuase-and-effect': { id: '/_layout/$exerciseId/cuase-and-effect' path: '/cuase-and-effect' fullPath: '/$exerciseId/cuase-and-effect' preLoaderRoute: typeof LayoutExerciseIdCuaseAndEffectImport '/_layout/$exerciseId/cause-and-effect': { id: '/_layout/$exerciseId/cause-and-effect' path: '/cause-and-effect' fullPath: '/$exerciseId/cause-and-effect' preLoaderRoute: typeof LayoutExerciseIdCauseAndEffectImport parentRoute: typeof LayoutExerciseIdRouteImport } '/_layout/$exerciseId/learning-objectives': { Loading @@ -198,6 +205,13 @@ declare module '@tanstack/react-router' { preLoaderRoute: typeof LayoutExerciseIdQuestionnairesImport parentRoute: typeof LayoutExerciseIdRouteImport } '/_layout/$exerciseId/room': { id: '/_layout/$exerciseId/room' path: '/room' fullPath: '/$exerciseId/room' preLoaderRoute: typeof LayoutExerciseIdRoomImport parentRoute: typeof LayoutExerciseIdRouteImport } '/_layout/$exerciseId/select-teams': { id: '/_layout/$exerciseId/select-teams' path: '/select-teams' Loading Loading @@ -264,10 +278,11 @@ const LayoutExerciseIdEmailsRouteRouteWithChildren = interface LayoutExerciseIdRouteRouteChildren { LayoutExerciseIdEmailsRouteRoute: typeof LayoutExerciseIdEmailsRouteRouteWithChildren LayoutExerciseIdActionLogsRoute: typeof LayoutExerciseIdActionLogsRoute LayoutExerciseIdCuaseAndEffectRoute: typeof LayoutExerciseIdCuaseAndEffectRoute LayoutExerciseIdCauseAndEffectRoute: typeof LayoutExerciseIdCauseAndEffectRoute LayoutExerciseIdLearningObjectivesRoute: typeof LayoutExerciseIdLearningObjectivesRoute LayoutExerciseIdMilestonesRoute: typeof LayoutExerciseIdMilestonesRoute LayoutExerciseIdQuestionnairesRoute: typeof LayoutExerciseIdQuestionnairesRoute LayoutExerciseIdRoomRoute: typeof LayoutExerciseIdRoomRoute LayoutExerciseIdSelectTeamsRoute: typeof LayoutExerciseIdSelectTeamsRoute LayoutExerciseIdToolsRoute: typeof LayoutExerciseIdToolsRoute LayoutExerciseIdIndexRoute: typeof LayoutExerciseIdIndexRoute Loading @@ -278,11 +293,12 @@ const LayoutExerciseIdRouteRouteChildren: LayoutExerciseIdRouteRouteChildren = { LayoutExerciseIdEmailsRouteRoute: LayoutExerciseIdEmailsRouteRouteWithChildren, LayoutExerciseIdActionLogsRoute: LayoutExerciseIdActionLogsRoute, LayoutExerciseIdCuaseAndEffectRoute: LayoutExerciseIdCuaseAndEffectRoute, LayoutExerciseIdCauseAndEffectRoute: LayoutExerciseIdCauseAndEffectRoute, LayoutExerciseIdLearningObjectivesRoute: LayoutExerciseIdLearningObjectivesRoute, LayoutExerciseIdMilestonesRoute: LayoutExerciseIdMilestonesRoute, LayoutExerciseIdQuestionnairesRoute: LayoutExerciseIdQuestionnairesRoute, LayoutExerciseIdRoomRoute: LayoutExerciseIdRoomRoute, LayoutExerciseIdSelectTeamsRoute: LayoutExerciseIdSelectTeamsRoute, LayoutExerciseIdToolsRoute: LayoutExerciseIdToolsRoute, LayoutExerciseIdIndexRoute: LayoutExerciseIdIndexRoute, Loading Loading @@ -314,10 +330,11 @@ export interface FileRoutesByFullPath { '/': typeof LayoutIndexRoute '/$exerciseId/emails': typeof LayoutExerciseIdEmailsRouteRouteWithChildren '/$exerciseId/action-logs': typeof LayoutExerciseIdActionLogsRoute '/$exerciseId/cuase-and-effect': typeof LayoutExerciseIdCuaseAndEffectRoute '/$exerciseId/cause-and-effect': typeof LayoutExerciseIdCauseAndEffectRoute '/$exerciseId/learning-objectives': typeof LayoutExerciseIdLearningObjectivesRoute '/$exerciseId/milestones': typeof LayoutExerciseIdMilestonesRoute '/$exerciseId/questionnaires': typeof LayoutExerciseIdQuestionnairesRoute '/$exerciseId/room': typeof LayoutExerciseIdRoomRoute '/$exerciseId/select-teams': typeof LayoutExerciseIdSelectTeamsRoute '/$exerciseId/tools': typeof LayoutExerciseIdToolsRoute '/$exerciseId/': typeof LayoutExerciseIdIndexRoute Loading @@ -329,10 +346,11 @@ export interface FileRoutesByFullPath { export interface FileRoutesByTo { '/': typeof LayoutIndexRoute '/$exerciseId/action-logs': typeof LayoutExerciseIdActionLogsRoute '/$exerciseId/cuase-and-effect': typeof LayoutExerciseIdCuaseAndEffectRoute '/$exerciseId/cause-and-effect': typeof LayoutExerciseIdCauseAndEffectRoute '/$exerciseId/learning-objectives': typeof LayoutExerciseIdLearningObjectivesRoute '/$exerciseId/milestones': typeof LayoutExerciseIdMilestonesRoute '/$exerciseId/questionnaires': typeof LayoutExerciseIdQuestionnairesRoute '/$exerciseId/room': typeof LayoutExerciseIdRoomRoute '/$exerciseId/select-teams': typeof LayoutExerciseIdSelectTeamsRoute '/$exerciseId/tools': typeof LayoutExerciseIdToolsRoute '/$exerciseId': typeof LayoutExerciseIdIndexRoute Loading @@ -348,10 +366,11 @@ export interface FileRoutesById { '/_layout/': typeof LayoutIndexRoute '/_layout/$exerciseId/emails': typeof LayoutExerciseIdEmailsRouteRouteWithChildren '/_layout/$exerciseId/action-logs': typeof LayoutExerciseIdActionLogsRoute '/_layout/$exerciseId/cuase-and-effect': typeof LayoutExerciseIdCuaseAndEffectRoute '/_layout/$exerciseId/cause-and-effect': typeof LayoutExerciseIdCauseAndEffectRoute '/_layout/$exerciseId/learning-objectives': typeof LayoutExerciseIdLearningObjectivesRoute '/_layout/$exerciseId/milestones': typeof LayoutExerciseIdMilestonesRoute '/_layout/$exerciseId/questionnaires': typeof LayoutExerciseIdQuestionnairesRoute '/_layout/$exerciseId/room': typeof LayoutExerciseIdRoomRoute '/_layout/$exerciseId/select-teams': typeof LayoutExerciseIdSelectTeamsRoute '/_layout/$exerciseId/tools': typeof LayoutExerciseIdToolsRoute '/_layout/$exerciseId/': typeof LayoutExerciseIdIndexRoute Loading @@ -368,10 +387,11 @@ export interface FileRouteTypes { | '/' | '/$exerciseId/emails' | '/$exerciseId/action-logs' | '/$exerciseId/cuase-and-effect' | '/$exerciseId/cause-and-effect' | '/$exerciseId/learning-objectives' | '/$exerciseId/milestones' | '/$exerciseId/questionnaires' | '/$exerciseId/room' | '/$exerciseId/select-teams' | '/$exerciseId/tools' | '/$exerciseId/' Loading @@ -382,10 +402,11 @@ export interface FileRouteTypes { to: | '/' | '/$exerciseId/action-logs' | '/$exerciseId/cuase-and-effect' | '/$exerciseId/cause-and-effect' | '/$exerciseId/learning-objectives' | '/$exerciseId/milestones' | '/$exerciseId/questionnaires' | '/$exerciseId/room' | '/$exerciseId/select-teams' | '/$exerciseId/tools' | '/$exerciseId' Loading @@ -399,10 +420,11 @@ export interface FileRouteTypes { | '/_layout/' | '/_layout/$exerciseId/emails' | '/_layout/$exerciseId/action-logs' | '/_layout/$exerciseId/cuase-and-effect' | '/_layout/$exerciseId/cause-and-effect' | '/_layout/$exerciseId/learning-objectives' | '/_layout/$exerciseId/milestones' | '/_layout/$exerciseId/questionnaires' | '/_layout/$exerciseId/room' | '/_layout/$exerciseId/select-teams' | '/_layout/$exerciseId/tools' | '/_layout/$exerciseId/' Loading Loading @@ -446,10 +468,11 @@ export const routeTree = rootRoute "children": [ "/_layout/$exerciseId/emails", "/_layout/$exerciseId/action-logs", "/_layout/$exerciseId/cuase-and-effect", "/_layout/$exerciseId/cause-and-effect", "/_layout/$exerciseId/learning-objectives", "/_layout/$exerciseId/milestones", "/_layout/$exerciseId/questionnaires", "/_layout/$exerciseId/room", "/_layout/$exerciseId/select-teams", "/_layout/$exerciseId/tools", "/_layout/$exerciseId/", Loading @@ -472,8 +495,8 @@ export const routeTree = rootRoute "filePath": "_layout/$exerciseId/action-logs.tsx", "parent": "/_layout/$exerciseId" }, "/_layout/$exerciseId/cuase-and-effect": { "filePath": "_layout/$exerciseId/cuase-and-effect.tsx", "/_layout/$exerciseId/cause-and-effect": { "filePath": "_layout/$exerciseId/cause-and-effect.tsx", "parent": "/_layout/$exerciseId" }, "/_layout/$exerciseId/learning-objectives": { Loading @@ -488,6 +511,10 @@ export const routeTree = rootRoute "filePath": "_layout/$exerciseId/questionnaires.tsx", "parent": "/_layout/$exerciseId" }, "/_layout/$exerciseId/room": { "filePath": "_layout/$exerciseId/room.tsx", "parent": "/_layout/$exerciseId" }, "/_layout/$exerciseId/select-teams": { "filePath": "_layout/$exerciseId/select-teams.tsx", "parent": "/_layout/$exerciseId" Loading analyst/src/routes/_layout/$exerciseId/cuase-and-effect.tsx→analyst/src/routes/_layout/$exerciseId/cause-and-effect.tsx +4 −5 Original line number Diff line number Diff line Loading @@ -2,15 +2,14 @@ import { css } from '@emotion/css' import { useSubscribedTeams } from '@inject/frontend' import type { Team } from '@inject/graphql' import { createFileRoute } from '@tanstack/react-router' import { useContext } from 'react' import { ExerciseContext, TeamSelectPage } from '../../../components' import { TeamSelectPage } from '../../../components' import { CauseAndEffectTree } from '../../../components/CauseAndEffectTree' const RouteComponent = () => { const { exercise } = useContext(ExerciseContext) const { exerciseId } = CauseAndEffectRoute.useParams() const teams = useSubscribedTeams({ exerciseId: exercise.id, exerciseId, context: 'analyst', }) Loading @@ -33,7 +32,7 @@ const RouteComponent = () => { ) } export const Route = createFileRoute('/_layout/$exerciseId/cuase-and-effect')({ export const Route = createFileRoute('/_layout/$exerciseId/cause-and-effect')({ component: RouteComponent, }) Loading analyst/src/routes/_layout/$exerciseId/index.tsx +2 −14 Original line number Diff line number Diff line Loading @@ -7,7 +7,7 @@ import { TeamsDisplay, useSubscribedTeams, } from '@inject/frontend' import { useResize } from '@inject/shared' import { Keys, useResize } from '@inject/shared' import { createFileRoute } from '@tanstack/react-router' import { useContext } from 'react' Loading Loading @@ -35,8 +35,6 @@ const RouteComponent = () => { const { exercise } = useContext(ExerciseContext) const { name } = exercise const teams = useSubscribedTeams({ exerciseId, context: 'analyst' }) const { Loading @@ -45,7 +43,7 @@ const RouteComponent = () => { handleMouseMove, handleMouseUp, leftWidth, } = useResize() } = useResize(Keys.getAnalystOverviewLeftWidthKey(exerciseId)) return ( <main Loading @@ -65,16 +63,6 @@ const RouteComponent = () => { min-width: 35rem; `} > <h1 className={css` margin: 0; `} > {name} </h1> <Divider /> <LearningObjectives teamIds={teams.map(team => team.id)} showTeams /> <Divider /> Loading Loading
analyst/src/components/NavigationBar/index.tsx +27 −15 Original line number Diff line number Diff line Loading @@ -29,11 +29,12 @@ import { useCallback, useContext, useMemo } from 'react' import { ExercisePageRoute } from '../../routes/_layout/$exerciseId' import { ActionLogsRoute } from '../../routes/_layout/$exerciseId/action-logs' import { CauseAndEffectRoute } from '../../routes/_layout/$exerciseId/cuase-and-effect' import { CauseAndEffectRoute } from '../../routes/_layout/$exerciseId/cause-and-effect' import { EmailPageRoute } from '../../routes/_layout/$exerciseId/emails' import { LearningObjectivesPageRoute } from '../../routes/_layout/$exerciseId/learning-objectives' import { MilestonesPageRoute } from '../../routes/_layout/$exerciseId/milestones' import { QuestionnairesPageRoute } from '../../routes/_layout/$exerciseId/questionnaires' import { RoomViewRoute } from '../../routes/_layout/$exerciseId/room' import { SelectTeamsPageRoute } from '../../routes/_layout/$exerciseId/select-teams' import { ToolsPageRoute } from '../../routes/_layout/$exerciseId/tools' import { ExerciseContext } from '../ExerciseContext' Loading Loading @@ -98,9 +99,29 @@ export const NavigationBar: FC<NavigationBarProps> = ({ }, }, icon: 'control', text: 'Overview', text: 'Performance Overview', end: true, }) paths.push({ link: { to: RoomViewRoute.to, params: { exerciseId, }, }, icon: 'grid-view', text: 'Room View', }) paths.push({ link: { to: CauseAndEffectRoute.to, params: { exerciseId, }, }, icon: 'one-to-many', text: 'Cause and Effect', }) paths.push({ link: { to: ActionLogsRoute.to, Loading Loading @@ -153,7 +174,7 @@ export const NavigationBar: FC<NavigationBarProps> = ({ }, }, icon: 'console', text: 'Tools', text: 'Tool Usage', }) } if (questionnairesEnabled) { Loading @@ -168,16 +189,6 @@ export const NavigationBar: FC<NavigationBarProps> = ({ text: 'Questionnaires', }) } paths.push({ link: { to: CauseAndEffectRoute.to, params: { exerciseId, }, }, icon: 'one-to-many', text: 'Cause and Effect', }) return paths }, [emailsEnabled, exerciseId, questionnairesEnabled, toolsEnabled]) Loading Loading @@ -259,8 +270,8 @@ export const NavigationBar: FC<NavigationBarProps> = ({ ...(exerciseId && teams.length ? [ { id: 'pages', name: 'Pages', id: 'views', name: 'Views', node: ( <> {paths.map(path => ( Loading Loading @@ -306,6 +317,7 @@ export const NavigationBar: FC<NavigationBarProps> = ({ sections={sections} hideNames={hide} showLogo title={exercise.name} /> <div Loading
analyst/src/components/RoomViewConfig/index.tsx 0 → 100644 +180 −0 Original line number Diff line number Diff line import { Button, ButtonGroup, Divider, FormGroup, NumericInput, } from '@blueprintjs/core' import { css } from '@emotion/css' import type { Team } from '@inject/graphql' import type { DraggableGridConfig } from '@inject/shared' import type { SetState } from 'ahooks/lib/createUseStorageState' import type { FC } from 'react' const mainContainer = css` display: flex; gap: 1rem; ` const sizeSection = css` display: flex; gap: 1rem; max-width: 20rem; ` const form = css` margin-bottom: 0; ` const layoutSection = css` flex: 1; display: flex; justify-content: flex-end; ` const buttonGroup = css` align-self: flex-start; ` // TODO: make the config collapsible // TODO: add export and import layout export type RoomViewConfig = { hideTeamLabels: boolean } interface RoomViewConfigComponentProps { teams: Team[] gridConfig: DraggableGridConfig<Team> setGridConfig: ( value?: SetState<DraggableGridConfig<Team>> | undefined ) => void gridConfigDefault: DraggableGridConfig<Team> viewConfig: RoomViewConfig setViewConfig: (value?: SetState<RoomViewConfig> | undefined) => void viewConfigDefault: RoomViewConfig } export const RoomViewConfigComponent: FC<RoomViewConfigComponentProps> = ({ teams, gridConfig, setGridConfig, gridConfigDefault, viewConfig, setViewConfig, viewConfigDefault, }) => ( <main className={mainContainer}> <section className={sizeSection}> <FormGroup className={form} fill labelFor='columns' label='Columns'> <NumericInput id='columns' fill disabled={gridConfig.editing} value={gridConfig.columns} onValueChange={value => setGridConfig(prev => ({ ...(prev ?? gridConfigDefault), columns: value, })) } min={Math.max(1, Math.ceil(teams.length / gridConfig.rows))} /> </FormGroup> <FormGroup className={form} fill labelFor='rows' label='Rows'> <NumericInput id='rows' fill disabled={gridConfig.editing} value={gridConfig.rows} onValueChange={value => setGridConfig(prev => ({ ...(prev ?? gridConfigDefault), rows: value, })) } min={Math.max(1, Math.ceil(teams.length / gridConfig.columns))} /> </FormGroup> </section> <section className={layoutSection}> <ButtonGroup className={buttonGroup}> <Button icon='label' onClick={() => setViewConfig(prev => ({ ...(prev ?? viewConfigDefault), hideTeamLabels: !(prev ?? viewConfigDefault).hideTeamLabels, })) } text={ <span style={{ whiteSpace: 'nowrap', }} > {viewConfig.hideTeamLabels ? 'Show team labels' : 'Hide team labels'} </span> } /> <Divider /> {gridConfig.editing ? ( <> <Button icon='floppy-disk' onClick={() => setGridConfig(prev => ({ ...(prev ?? gridConfigDefault), editing: false, cells: prev?.editedCells ?? gridConfigDefault.cells, editedCells: [], })) } intent='primary' text='Save layout' /> <Button icon='cross' onClick={() => setGridConfig(prev => ({ ...(prev ?? gridConfigDefault), editing: false, editedCells: [], })) } text='Cancel' /> </> ) : ( <> <Button icon='edit' onClick={() => setGridConfig(prev => ({ ...(prev ?? gridConfigDefault), editing: true, editedCells: prev?.cells ?? gridConfigDefault.cells, })) } text='Edit layout' /> <Button icon='reset' onClick={() => setGridConfig(prev => ({ ...(prev ?? gridConfigDefault), cells: gridConfigDefault.cells, })) } text='Reset layout' /> </> )} </ButtonGroup> </section> </main> )
analyst/src/routeTree.gen.ts +48 −21 Original line number Diff line number Diff line Loading @@ -17,10 +17,11 @@ import { Route as LayoutExerciseIdRouteImport } from './routes/_layout/$exercise import { Route as LayoutExerciseIdIndexImport } from './routes/_layout/$exerciseId/index' import { Route as LayoutExerciseIdToolsImport } from './routes/_layout/$exerciseId/tools' import { Route as LayoutExerciseIdSelectTeamsImport } from './routes/_layout/$exerciseId/select-teams' import { Route as LayoutExerciseIdRoomImport } from './routes/_layout/$exerciseId/room' import { Route as LayoutExerciseIdQuestionnairesImport } from './routes/_layout/$exerciseId/questionnaires' import { Route as LayoutExerciseIdMilestonesImport } from './routes/_layout/$exerciseId/milestones' import { Route as LayoutExerciseIdLearningObjectivesImport } from './routes/_layout/$exerciseId/learning-objectives' import { Route as LayoutExerciseIdCuaseAndEffectImport } from './routes/_layout/$exerciseId/cuase-and-effect' import { Route as LayoutExerciseIdCauseAndEffectImport } from './routes/_layout/$exerciseId/cause-and-effect' import { Route as LayoutExerciseIdActionLogsImport } from './routes/_layout/$exerciseId/action-logs' import { Route as LayoutExerciseIdEmailsRouteImport } from './routes/_layout/$exerciseId/emails/route' import { Route as LayoutExerciseIdEmailsIndexImport } from './routes/_layout/$exerciseId/emails/index' Loading Loading @@ -65,6 +66,12 @@ const LayoutExerciseIdSelectTeamsRoute = getParentRoute: () => LayoutExerciseIdRouteRoute, } as any) const LayoutExerciseIdRoomRoute = LayoutExerciseIdRoomImport.update({ id: '/room', path: '/room', getParentRoute: () => LayoutExerciseIdRouteRoute, } as any) const LayoutExerciseIdQuestionnairesRoute = LayoutExerciseIdQuestionnairesImport.update({ id: '/questionnaires', Loading @@ -87,10 +94,10 @@ const LayoutExerciseIdLearningObjectivesRoute = getParentRoute: () => LayoutExerciseIdRouteRoute, } as any) const LayoutExerciseIdCuaseAndEffectRoute = LayoutExerciseIdCuaseAndEffectImport.update({ id: '/cuase-and-effect', path: '/cuase-and-effect', const LayoutExerciseIdCauseAndEffectRoute = LayoutExerciseIdCauseAndEffectImport.update({ id: '/cause-and-effect', path: '/cause-and-effect', getParentRoute: () => LayoutExerciseIdRouteRoute, } as any) Loading Loading @@ -170,11 +177,11 @@ declare module '@tanstack/react-router' { preLoaderRoute: typeof LayoutExerciseIdActionLogsImport parentRoute: typeof LayoutExerciseIdRouteImport } '/_layout/$exerciseId/cuase-and-effect': { id: '/_layout/$exerciseId/cuase-and-effect' path: '/cuase-and-effect' fullPath: '/$exerciseId/cuase-and-effect' preLoaderRoute: typeof LayoutExerciseIdCuaseAndEffectImport '/_layout/$exerciseId/cause-and-effect': { id: '/_layout/$exerciseId/cause-and-effect' path: '/cause-and-effect' fullPath: '/$exerciseId/cause-and-effect' preLoaderRoute: typeof LayoutExerciseIdCauseAndEffectImport parentRoute: typeof LayoutExerciseIdRouteImport } '/_layout/$exerciseId/learning-objectives': { Loading @@ -198,6 +205,13 @@ declare module '@tanstack/react-router' { preLoaderRoute: typeof LayoutExerciseIdQuestionnairesImport parentRoute: typeof LayoutExerciseIdRouteImport } '/_layout/$exerciseId/room': { id: '/_layout/$exerciseId/room' path: '/room' fullPath: '/$exerciseId/room' preLoaderRoute: typeof LayoutExerciseIdRoomImport parentRoute: typeof LayoutExerciseIdRouteImport } '/_layout/$exerciseId/select-teams': { id: '/_layout/$exerciseId/select-teams' path: '/select-teams' Loading Loading @@ -264,10 +278,11 @@ const LayoutExerciseIdEmailsRouteRouteWithChildren = interface LayoutExerciseIdRouteRouteChildren { LayoutExerciseIdEmailsRouteRoute: typeof LayoutExerciseIdEmailsRouteRouteWithChildren LayoutExerciseIdActionLogsRoute: typeof LayoutExerciseIdActionLogsRoute LayoutExerciseIdCuaseAndEffectRoute: typeof LayoutExerciseIdCuaseAndEffectRoute LayoutExerciseIdCauseAndEffectRoute: typeof LayoutExerciseIdCauseAndEffectRoute LayoutExerciseIdLearningObjectivesRoute: typeof LayoutExerciseIdLearningObjectivesRoute LayoutExerciseIdMilestonesRoute: typeof LayoutExerciseIdMilestonesRoute LayoutExerciseIdQuestionnairesRoute: typeof LayoutExerciseIdQuestionnairesRoute LayoutExerciseIdRoomRoute: typeof LayoutExerciseIdRoomRoute LayoutExerciseIdSelectTeamsRoute: typeof LayoutExerciseIdSelectTeamsRoute LayoutExerciseIdToolsRoute: typeof LayoutExerciseIdToolsRoute LayoutExerciseIdIndexRoute: typeof LayoutExerciseIdIndexRoute Loading @@ -278,11 +293,12 @@ const LayoutExerciseIdRouteRouteChildren: LayoutExerciseIdRouteRouteChildren = { LayoutExerciseIdEmailsRouteRoute: LayoutExerciseIdEmailsRouteRouteWithChildren, LayoutExerciseIdActionLogsRoute: LayoutExerciseIdActionLogsRoute, LayoutExerciseIdCuaseAndEffectRoute: LayoutExerciseIdCuaseAndEffectRoute, LayoutExerciseIdCauseAndEffectRoute: LayoutExerciseIdCauseAndEffectRoute, LayoutExerciseIdLearningObjectivesRoute: LayoutExerciseIdLearningObjectivesRoute, LayoutExerciseIdMilestonesRoute: LayoutExerciseIdMilestonesRoute, LayoutExerciseIdQuestionnairesRoute: LayoutExerciseIdQuestionnairesRoute, LayoutExerciseIdRoomRoute: LayoutExerciseIdRoomRoute, LayoutExerciseIdSelectTeamsRoute: LayoutExerciseIdSelectTeamsRoute, LayoutExerciseIdToolsRoute: LayoutExerciseIdToolsRoute, LayoutExerciseIdIndexRoute: LayoutExerciseIdIndexRoute, Loading Loading @@ -314,10 +330,11 @@ export interface FileRoutesByFullPath { '/': typeof LayoutIndexRoute '/$exerciseId/emails': typeof LayoutExerciseIdEmailsRouteRouteWithChildren '/$exerciseId/action-logs': typeof LayoutExerciseIdActionLogsRoute '/$exerciseId/cuase-and-effect': typeof LayoutExerciseIdCuaseAndEffectRoute '/$exerciseId/cause-and-effect': typeof LayoutExerciseIdCauseAndEffectRoute '/$exerciseId/learning-objectives': typeof LayoutExerciseIdLearningObjectivesRoute '/$exerciseId/milestones': typeof LayoutExerciseIdMilestonesRoute '/$exerciseId/questionnaires': typeof LayoutExerciseIdQuestionnairesRoute '/$exerciseId/room': typeof LayoutExerciseIdRoomRoute '/$exerciseId/select-teams': typeof LayoutExerciseIdSelectTeamsRoute '/$exerciseId/tools': typeof LayoutExerciseIdToolsRoute '/$exerciseId/': typeof LayoutExerciseIdIndexRoute Loading @@ -329,10 +346,11 @@ export interface FileRoutesByFullPath { export interface FileRoutesByTo { '/': typeof LayoutIndexRoute '/$exerciseId/action-logs': typeof LayoutExerciseIdActionLogsRoute '/$exerciseId/cuase-and-effect': typeof LayoutExerciseIdCuaseAndEffectRoute '/$exerciseId/cause-and-effect': typeof LayoutExerciseIdCauseAndEffectRoute '/$exerciseId/learning-objectives': typeof LayoutExerciseIdLearningObjectivesRoute '/$exerciseId/milestones': typeof LayoutExerciseIdMilestonesRoute '/$exerciseId/questionnaires': typeof LayoutExerciseIdQuestionnairesRoute '/$exerciseId/room': typeof LayoutExerciseIdRoomRoute '/$exerciseId/select-teams': typeof LayoutExerciseIdSelectTeamsRoute '/$exerciseId/tools': typeof LayoutExerciseIdToolsRoute '/$exerciseId': typeof LayoutExerciseIdIndexRoute Loading @@ -348,10 +366,11 @@ export interface FileRoutesById { '/_layout/': typeof LayoutIndexRoute '/_layout/$exerciseId/emails': typeof LayoutExerciseIdEmailsRouteRouteWithChildren '/_layout/$exerciseId/action-logs': typeof LayoutExerciseIdActionLogsRoute '/_layout/$exerciseId/cuase-and-effect': typeof LayoutExerciseIdCuaseAndEffectRoute '/_layout/$exerciseId/cause-and-effect': typeof LayoutExerciseIdCauseAndEffectRoute '/_layout/$exerciseId/learning-objectives': typeof LayoutExerciseIdLearningObjectivesRoute '/_layout/$exerciseId/milestones': typeof LayoutExerciseIdMilestonesRoute '/_layout/$exerciseId/questionnaires': typeof LayoutExerciseIdQuestionnairesRoute '/_layout/$exerciseId/room': typeof LayoutExerciseIdRoomRoute '/_layout/$exerciseId/select-teams': typeof LayoutExerciseIdSelectTeamsRoute '/_layout/$exerciseId/tools': typeof LayoutExerciseIdToolsRoute '/_layout/$exerciseId/': typeof LayoutExerciseIdIndexRoute Loading @@ -368,10 +387,11 @@ export interface FileRouteTypes { | '/' | '/$exerciseId/emails' | '/$exerciseId/action-logs' | '/$exerciseId/cuase-and-effect' | '/$exerciseId/cause-and-effect' | '/$exerciseId/learning-objectives' | '/$exerciseId/milestones' | '/$exerciseId/questionnaires' | '/$exerciseId/room' | '/$exerciseId/select-teams' | '/$exerciseId/tools' | '/$exerciseId/' Loading @@ -382,10 +402,11 @@ export interface FileRouteTypes { to: | '/' | '/$exerciseId/action-logs' | '/$exerciseId/cuase-and-effect' | '/$exerciseId/cause-and-effect' | '/$exerciseId/learning-objectives' | '/$exerciseId/milestones' | '/$exerciseId/questionnaires' | '/$exerciseId/room' | '/$exerciseId/select-teams' | '/$exerciseId/tools' | '/$exerciseId' Loading @@ -399,10 +420,11 @@ export interface FileRouteTypes { | '/_layout/' | '/_layout/$exerciseId/emails' | '/_layout/$exerciseId/action-logs' | '/_layout/$exerciseId/cuase-and-effect' | '/_layout/$exerciseId/cause-and-effect' | '/_layout/$exerciseId/learning-objectives' | '/_layout/$exerciseId/milestones' | '/_layout/$exerciseId/questionnaires' | '/_layout/$exerciseId/room' | '/_layout/$exerciseId/select-teams' | '/_layout/$exerciseId/tools' | '/_layout/$exerciseId/' Loading Loading @@ -446,10 +468,11 @@ export const routeTree = rootRoute "children": [ "/_layout/$exerciseId/emails", "/_layout/$exerciseId/action-logs", "/_layout/$exerciseId/cuase-and-effect", "/_layout/$exerciseId/cause-and-effect", "/_layout/$exerciseId/learning-objectives", "/_layout/$exerciseId/milestones", "/_layout/$exerciseId/questionnaires", "/_layout/$exerciseId/room", "/_layout/$exerciseId/select-teams", "/_layout/$exerciseId/tools", "/_layout/$exerciseId/", Loading @@ -472,8 +495,8 @@ export const routeTree = rootRoute "filePath": "_layout/$exerciseId/action-logs.tsx", "parent": "/_layout/$exerciseId" }, "/_layout/$exerciseId/cuase-and-effect": { "filePath": "_layout/$exerciseId/cuase-and-effect.tsx", "/_layout/$exerciseId/cause-and-effect": { "filePath": "_layout/$exerciseId/cause-and-effect.tsx", "parent": "/_layout/$exerciseId" }, "/_layout/$exerciseId/learning-objectives": { Loading @@ -488,6 +511,10 @@ export const routeTree = rootRoute "filePath": "_layout/$exerciseId/questionnaires.tsx", "parent": "/_layout/$exerciseId" }, "/_layout/$exerciseId/room": { "filePath": "_layout/$exerciseId/room.tsx", "parent": "/_layout/$exerciseId" }, "/_layout/$exerciseId/select-teams": { "filePath": "_layout/$exerciseId/select-teams.tsx", "parent": "/_layout/$exerciseId" Loading
analyst/src/routes/_layout/$exerciseId/cuase-and-effect.tsx→analyst/src/routes/_layout/$exerciseId/cause-and-effect.tsx +4 −5 Original line number Diff line number Diff line Loading @@ -2,15 +2,14 @@ import { css } from '@emotion/css' import { useSubscribedTeams } from '@inject/frontend' import type { Team } from '@inject/graphql' import { createFileRoute } from '@tanstack/react-router' import { useContext } from 'react' import { ExerciseContext, TeamSelectPage } from '../../../components' import { TeamSelectPage } from '../../../components' import { CauseAndEffectTree } from '../../../components/CauseAndEffectTree' const RouteComponent = () => { const { exercise } = useContext(ExerciseContext) const { exerciseId } = CauseAndEffectRoute.useParams() const teams = useSubscribedTeams({ exerciseId: exercise.id, exerciseId, context: 'analyst', }) Loading @@ -33,7 +32,7 @@ const RouteComponent = () => { ) } export const Route = createFileRoute('/_layout/$exerciseId/cuase-and-effect')({ export const Route = createFileRoute('/_layout/$exerciseId/cause-and-effect')({ component: RouteComponent, }) Loading
analyst/src/routes/_layout/$exerciseId/index.tsx +2 −14 Original line number Diff line number Diff line Loading @@ -7,7 +7,7 @@ import { TeamsDisplay, useSubscribedTeams, } from '@inject/frontend' import { useResize } from '@inject/shared' import { Keys, useResize } from '@inject/shared' import { createFileRoute } from '@tanstack/react-router' import { useContext } from 'react' Loading Loading @@ -35,8 +35,6 @@ const RouteComponent = () => { const { exercise } = useContext(ExerciseContext) const { name } = exercise const teams = useSubscribedTeams({ exerciseId, context: 'analyst' }) const { Loading @@ -45,7 +43,7 @@ const RouteComponent = () => { handleMouseMove, handleMouseUp, leftWidth, } = useResize() } = useResize(Keys.getAnalystOverviewLeftWidthKey(exerciseId)) return ( <main Loading @@ -65,16 +63,6 @@ const RouteComponent = () => { min-width: 35rem; `} > <h1 className={css` margin: 0; `} > {name} </h1> <Divider /> <LearningObjectives teamIds={teams.map(team => team.id)} showTeams /> <Divider /> Loading