From 11cea42b275e761a7b1292abe5663bfec263afda Mon Sep 17 00:00:00 2001 From: Marek Vesely <xvesely4@fi.muni.cz> Date: Tue, 21 May 2024 13:48:55 +0200 Subject: [PATCH] fix: role exercise team count --- codegen/gql/fragments/Definition.graphql | 3 ++ codegen/gql/fragments/Role.graphql | 4 ++ .../src/pages/instructor/+exerciseCreator.tsx | 43 ++++++++++++++++--- graphql/fragments/Definition.generated.ts | 4 +- graphql/fragments/Role.generated.ts | 8 ++++ graphql/queries/GetDefinition.generated.ts | 4 +- graphql/queries/GetDefinitions.generated.ts | 4 +- 7 files changed, 57 insertions(+), 13 deletions(-) create mode 100644 codegen/gql/fragments/Role.graphql create mode 100644 graphql/fragments/Role.generated.ts diff --git a/codegen/gql/fragments/Definition.graphql b/codegen/gql/fragments/Definition.graphql index 6d935972c..fa99b9a8f 100644 --- a/codegen/gql/fragments/Definition.graphql +++ b/codegen/gql/fragments/Definition.graphql @@ -5,4 +5,7 @@ fragment Definition on DefinitionType { channels { ...Channel } + roles { + ...Role + } } diff --git a/codegen/gql/fragments/Role.graphql b/codegen/gql/fragments/Role.graphql new file mode 100644 index 000000000..a7e5e8c7b --- /dev/null +++ b/codegen/gql/fragments/Role.graphql @@ -0,0 +1,4 @@ +fragment Role on DefinitionRoleType { + id + name +} diff --git a/frontend/src/pages/instructor/+exerciseCreator.tsx b/frontend/src/pages/instructor/+exerciseCreator.tsx index be896a714..0f6d6380f 100644 --- a/frontend/src/pages/instructor/+exerciseCreator.tsx +++ b/frontend/src/pages/instructor/+exerciseCreator.tsx @@ -11,14 +11,14 @@ import { Label, NumericInput, } from '@blueprintjs/core' +import type { Definition } from '@inject/graphql/fragments/Definition.generated' import { useCreateExercises } from '@inject/graphql/mutations/CreateExercise.generated' import { useGetDefinitions } from '@inject/graphql/queries/GetDefinitions.generated' import { GetExercisesDocument } from '@inject/graphql/queries/GetExercises.generated' import Box from '@inject/shared/components/Box' import { useNotifyContext } from '@inject/shared/notification/contexts/NotifyContext' -import { useCallback, useMemo, useState } from 'react' +import { useCallback, useEffect, useMemo, useState } from 'react' -const TEAMS_MIN = 1 const TEAMS_MAX = 20 const ExerciseCreator = () => { @@ -32,7 +32,18 @@ const ExerciseCreator = () => { }) const { notify } = useNotifyContext() const [definitionId, setDefinitionId] = useState<string>() - const [count, setCount] = useState<undefined | number>(undefined) + const [definition, setDefinition] = useState<Definition>() + const [count, setCount] = useState<undefined | number>() + + useEffect(() => { + const definition = definitionData?.definitions?.find( + definition => definition?.id === definitionId + ) + setCount(definition?.roles.length || 1) + if (definition) { + setDefinition(definition) + } + }, [definitionData?.definitions, definitionId]) const handleSubmit = useCallback(() => { addExercise({ @@ -104,17 +115,35 @@ const ExerciseCreator = () => { </Label> <Label style={{ width: '100%' }}> - Team count + Number of teams + {definition?.roles.length ? ( + <> + {' '} + <span + className={Classes.TEXT_MUTED} + >{`(multiple of the number of roles - ${definition.roles.length})`}</span> + </> + ) : ( + '' + )} <NumericInput fill value={count} + disabled={!definition} + stepSize={definition?.roles.length || 1} + minorStepSize={null} + majorStepSize={null} onValueChange={value => { - if (value >= TEAMS_MIN && value <= TEAMS_MAX) { + if ( + value >= (definition?.roles.length || 1) && + value <= Math.max(TEAMS_MAX, definition?.roles.length || 1) && + value % (definition?.roles.length || 1) === 0 + ) { setCount(value) } }} - min={TEAMS_MIN} - max={TEAMS_MAX} + min={definition?.roles.length || 1} + max={Math.max(TEAMS_MAX, definition?.roles.length || 1)} title='Number of teams' placeholder='Number of teams' style={{ margin: 0 }} diff --git a/graphql/fragments/Definition.generated.ts b/graphql/fragments/Definition.generated.ts index 1d4614871..102d2fac2 100644 --- a/graphql/fragments/Definition.generated.ts +++ b/graphql/fragments/Definition.generated.ts @@ -3,6 +3,6 @@ import type * as _Types from '../types'; import type { DocumentNode } from 'graphql'; -export type Definition = { id: string, name: string, version: string, channels: Array<{ id: string, name: string, type: _Types.ChannelType, readReceipt: Array<{ readReceipt: string | null, teamId: string }> }> }; +export type Definition = { id: string, name: string, version: string, channels: Array<{ id: string, name: string, type: _Types.ChannelType, readReceipt: Array<{ readReceipt: string | null, teamId: string }> }>, roles: Array<{ id: string, name: string }> }; -export const Definition = /*#__PURE__*/ {"kind":"Document","definitions":[{"kind":"FragmentDefinition","name":{"kind":"Name","value":"Definition"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"DefinitionType"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"version"}},{"kind":"Field","name":{"kind":"Name","value":"channels"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"Channel"}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"Channel"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"DefinitionChannelType"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"type"}},{"kind":"Field","name":{"kind":"Name","value":"readReceipt"},"directives":[{"kind":"Directive","name":{"kind":"Name","value":"client"}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"readReceipt"}},{"kind":"Field","name":{"kind":"Name","value":"teamId"}}]}}]}}]} as unknown as DocumentNode; \ No newline at end of file +export const Definition = /*#__PURE__*/ {"kind":"Document","definitions":[{"kind":"FragmentDefinition","name":{"kind":"Name","value":"Definition"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"DefinitionType"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"version"}},{"kind":"Field","name":{"kind":"Name","value":"channels"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"Channel"}}]}},{"kind":"Field","name":{"kind":"Name","value":"roles"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"Role"}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"Channel"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"DefinitionChannelType"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"type"}},{"kind":"Field","name":{"kind":"Name","value":"readReceipt"},"directives":[{"kind":"Directive","name":{"kind":"Name","value":"client"}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"readReceipt"}},{"kind":"Field","name":{"kind":"Name","value":"teamId"}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"Role"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"DefinitionRoleType"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}}]}}]} as unknown as DocumentNode; \ No newline at end of file diff --git a/graphql/fragments/Role.generated.ts b/graphql/fragments/Role.generated.ts new file mode 100644 index 000000000..3d937e977 --- /dev/null +++ b/graphql/fragments/Role.generated.ts @@ -0,0 +1,8 @@ +/* eslint-disable */ +//@ts-nocheck +import type * as _Types from '../types'; + +import type { DocumentNode } from 'graphql'; +export type Role = { id: string, name: string }; + +export const Role = /*#__PURE__*/ {"kind":"Document","definitions":[{"kind":"FragmentDefinition","name":{"kind":"Name","value":"Role"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"DefinitionRoleType"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}}]}}]} as unknown as DocumentNode; \ No newline at end of file diff --git a/graphql/queries/GetDefinition.generated.ts b/graphql/queries/GetDefinition.generated.ts index 5c08ebdd7..9e6034bc2 100644 --- a/graphql/queries/GetDefinition.generated.ts +++ b/graphql/queries/GetDefinition.generated.ts @@ -10,10 +10,10 @@ export type GetDefinitionVariables = _Types.Exact<{ }>; -export type GetDefinition = { definition: { id: string, name: string, version: string, channels: Array<{ id: string, name: string, type: _Types.ChannelType, readReceipt: Array<{ readReceipt: string | null, teamId: string }> }> } | null }; +export type GetDefinition = { definition: { id: string, name: string, version: string, channels: Array<{ id: string, name: string, type: _Types.ChannelType, readReceipt: Array<{ readReceipt: string | null, teamId: string }> }>, roles: Array<{ id: string, name: string }> } | null }; -export const GetDefinitionDocument = /*#__PURE__*/ {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"GetDefinition"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"definitionId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"ID"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"definition"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"definitionId"},"value":{"kind":"Variable","name":{"kind":"Name","value":"definitionId"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"Definition"}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"Definition"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"DefinitionType"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"version"}},{"kind":"Field","name":{"kind":"Name","value":"channels"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"Channel"}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"Channel"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"DefinitionChannelType"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"type"}},{"kind":"Field","name":{"kind":"Name","value":"readReceipt"},"directives":[{"kind":"Directive","name":{"kind":"Name","value":"client"}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"readReceipt"}},{"kind":"Field","name":{"kind":"Name","value":"teamId"}}]}}]}}]} as unknown as DocumentNode; +export const GetDefinitionDocument = /*#__PURE__*/ {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"GetDefinition"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"definitionId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"ID"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"definition"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"definitionId"},"value":{"kind":"Variable","name":{"kind":"Name","value":"definitionId"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"Definition"}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"Definition"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"DefinitionType"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"version"}},{"kind":"Field","name":{"kind":"Name","value":"channels"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"Channel"}}]}},{"kind":"Field","name":{"kind":"Name","value":"roles"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"Role"}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"Channel"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"DefinitionChannelType"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"type"}},{"kind":"Field","name":{"kind":"Name","value":"readReceipt"},"directives":[{"kind":"Directive","name":{"kind":"Name","value":"client"}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"readReceipt"}},{"kind":"Field","name":{"kind":"Name","value":"teamId"}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"Role"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"DefinitionRoleType"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}}]}}]} as unknown as DocumentNode; /** * __useGetDefinition__ diff --git a/graphql/queries/GetDefinitions.generated.ts b/graphql/queries/GetDefinitions.generated.ts index 2a6921a60..6a82dd44f 100644 --- a/graphql/queries/GetDefinitions.generated.ts +++ b/graphql/queries/GetDefinitions.generated.ts @@ -8,10 +8,10 @@ const defaultOptions = {} as const; export type GetDefinitionsVariables = _Types.Exact<{ [key: string]: never; }>; -export type GetDefinitions = { definitions: Array<{ id: string, name: string, version: string, channels: Array<{ id: string, name: string, type: _Types.ChannelType, readReceipt: Array<{ readReceipt: string | null, teamId: string }> }> } | null> | null }; +export type GetDefinitions = { definitions: Array<{ id: string, name: string, version: string, channels: Array<{ id: string, name: string, type: _Types.ChannelType, readReceipt: Array<{ readReceipt: string | null, teamId: string }> }>, roles: Array<{ id: string, name: string }> } | null> | null }; -export const GetDefinitionsDocument = /*#__PURE__*/ {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"GetDefinitions"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"definitions"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"Definition"}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"Definition"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"DefinitionType"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"version"}},{"kind":"Field","name":{"kind":"Name","value":"channels"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"Channel"}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"Channel"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"DefinitionChannelType"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"type"}},{"kind":"Field","name":{"kind":"Name","value":"readReceipt"},"directives":[{"kind":"Directive","name":{"kind":"Name","value":"client"}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"readReceipt"}},{"kind":"Field","name":{"kind":"Name","value":"teamId"}}]}}]}}]} as unknown as DocumentNode; +export const GetDefinitionsDocument = /*#__PURE__*/ {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"GetDefinitions"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"definitions"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"Definition"}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"Definition"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"DefinitionType"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"version"}},{"kind":"Field","name":{"kind":"Name","value":"channels"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"Channel"}}]}},{"kind":"Field","name":{"kind":"Name","value":"roles"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"Role"}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"Channel"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"DefinitionChannelType"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"type"}},{"kind":"Field","name":{"kind":"Name","value":"readReceipt"},"directives":[{"kind":"Directive","name":{"kind":"Name","value":"client"}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"readReceipt"}},{"kind":"Field","name":{"kind":"Name","value":"teamId"}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"Role"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"DefinitionRoleType"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}}]}}]} as unknown as DocumentNode; /** * __useGetDefinitions__ -- GitLab