Loading analyst/src/routes/_layout/$exerciseId/emails/route.tsx +4 −2 Original line number Original line Diff line number Diff line Loading @@ -9,8 +9,9 @@ import { import { css } from '@emotion/css' import { css } from '@emotion/css' import { ExerciseContext, useEmailThreads } from '@inject/analyst' import { ExerciseContext, useEmailThreads } from '@inject/analyst' import type { ExtendedEmailThread } from '@inject/frontend' import type { ExtendedEmailThread } from '@inject/frontend' import { noEmailReceived, ThreadLogCards } from '@inject/frontend' import { ThreadLogCards } from '@inject/frontend' import type { Email, Team } from '@inject/graphql' import type { Email, Team } from '@inject/graphql' import { useTranslationFrontend } from '@inject/locale' import { TabButton } from '@inject/shared' import { TabButton } from '@inject/shared' import { import { createFileRoute, createFileRoute, Loading Loading @@ -82,6 +83,7 @@ const RouteComponent = () => { {team.name} {team.name} </TabButton> </TabButton> ) ) const { t } = useTranslationFrontend() return ( return ( <> <> <div <div Loading Loading @@ -124,7 +126,7 @@ const RouteComponent = () => { <ThreadLogCards <ThreadLogCards teamId={selectedTeam.id} teamId={selectedTeam.id} emailThreads={emailThreads} emailThreads={emailThreads} noEmailString={noEmailReceived} noEmailString={t('emails.noArchived')} inAnalyst inAnalyst onClick={emailThread => { onClick={emailThread => { nav({ nav({ Loading frontend/src/actionlog/InjectMessage/Content/ToolContent.tsx +23 −19 Original line number Original line Diff line number Diff line import { css } from '@emotion/css' import { css } from '@emotion/css' import type { ToolDetails } from '@inject/graphql' import type { ToolDetails } from '@inject/graphql' import { useTranslationFrontend } from '@inject/locale' import { breakWord } from '@inject/shared' import { breakWord } from '@inject/shared' import type { NavigateOptions } from '@tanstack/react-router' import type { NavigateOptions } from '@tanstack/react-router' import type { FC } from 'react' import type { FC } from 'react' Loading Loading @@ -41,16 +42,18 @@ const ToolContent: FC<ToolContentProps> = ({ exerciseId, exerciseId, inInstructor, inInstructor, getFileLink, getFileLink, }) => ( }) => { const { t } = useTranslationFrontend() return ( <div className={wrapper}> <div className={wrapper}> {details.tool.requiresInput && ( {details.tool.requiresInput && ( <> <> <div className={emphasized}>argument:</div> <div className={emphasized}>{t('tools.argument')}</div> <div className={breakWord}>{details.argument}</div> <div className={breakWord}>{details.argument}</div> <div /> <div /> </> </> )} )} <div className={emphasized}>response:</div> <div className={emphasized}>{t('tools.response')}</div> <div className={response}> <div className={response}> <ContentComponent <ContentComponent getFileLink={getFileLink} getFileLink={getFileLink} Loading @@ -61,5 +64,6 @@ const ToolContent: FC<ToolContentProps> = ({ </div> </div> </div> </div> ) ) } export default ToolContent export default ToolContent frontend/src/actionlog/InjectMessage/Content/TraineeQuestionnaireContent.tsx +2 −2 Original line number Original line Diff line number Diff line Loading @@ -305,7 +305,7 @@ const TraineeQuestionnaireContent: FC<TraineeQuestionnaireContentProps> = ({ gap: 0.5rem; gap: 0.5rem; `} `} > > {onClose && <Button text='Close' onClick={onClose} />} {onClose && <Button text={t('close')} onClick={onClose} />} <Button <Button className={cx({ className={cx({ [wiggleClass]: wiggling, [wiggleClass]: wiggling, Loading @@ -316,7 +316,7 @@ const TraineeQuestionnaireContent: FC<TraineeQuestionnaireContentProps> = ({ title={title} title={title} loading={loading} loading={loading} > > Submit {t('submit')} </Button> </Button> </div> </div> } } Loading frontend/src/components/FileArea/index.tsx +5 −2 Original line number Original line Diff line number Diff line import { Colors, FileInput, FormGroup, type Intent } from '@blueprintjs/core' import { Colors, FileInput, FormGroup, type Intent } from '@blueprintjs/core' import { css, cx } from '@emotion/css' import { css, cx } from '@emotion/css' import { useUploadFile } from '@inject/graphql' import { useUploadFile } from '@inject/graphql' import { useTranslationFrontend } from '@inject/locale' import type { NavigateOptions } from '@tanstack/react-router' import type { NavigateOptions } from '@tanstack/react-router' import type { ChangeEvent, FC } from 'react' import type { ChangeEvent, FC } from 'react' import { useCallback, useState } from 'react' import { useCallback, useState } from 'react' Loading Loading @@ -30,6 +31,7 @@ const FileArea: FC<{ addFileInfo, addFileInfo, getLink, getLink, }) => { }) => { const { t } = useTranslationFrontend() const [internalError, setInternalError] = useState('') const [internalError, setInternalError] = useState('') // TODO: use contextual saving of file selection, we have an API for that :tm: // TODO: use contextual saving of file selection, we have an API for that :tm: Loading Loading @@ -70,7 +72,7 @@ const FileArea: FC<{ internalError internalError ? internalError ? internalError : !teamId : !teamId ? 'Select a team before selecting a file' ? t('files.selectTeamFirst') : undefined : undefined } } intent={ intent={ Loading @@ -90,7 +92,8 @@ const FileArea: FC<{ [fileInputDanger]: intent === 'danger' || !!internalError, [fileInputDanger]: intent === 'danger' || !!internalError, } } )} )} text='Attach a file' text={t('files.attachFile')} buttonText={t('files.browse')} onInputChange={handleFileChange} onInputChange={handleFileChange} /> /> </FormGroup> </FormGroup> Loading frontend/src/components/Questionnaire/QuestionDescription.tsx +8 −3 Original line number Original line Diff line number Diff line import { Classes, Colors } from '@blueprintjs/core' import { Classes, Colors } from '@blueprintjs/core' import { css, cx } from '@emotion/css' import { css, cx } from '@emotion/css' import { useTranslationFrontend } from '@inject/locale' import { ErrorMessage } from '@inject/shared' import { ErrorMessage } from '@inject/shared' const container = css` const container = css` Loading @@ -21,6 +22,8 @@ export const QuestionDescription = ({ max: number max: number current: number current: number }) => { }) => { const { t } = useTranslationFrontend() if (min <= 1 && max === -1) { if (min <= 1 && max === -1) { return null return null } } Loading @@ -28,12 +31,14 @@ export const QuestionDescription = ({ <div className={cx(Classes.TEXT_MUTED, container)}> <div className={cx(Classes.TEXT_MUTED, container)}> {max !== -1 && current >= max && ( {max !== -1 && current >= max && ( <div> <div> <ErrorMessage minimal>Maximum characters reached</ErrorMessage> <ErrorMessage minimal> {t('questionnaire.maxCharactersReached')} </ErrorMessage> </div> </div> )} )} {min !== 1 && ( {min !== 1 && ( <span> <span> <span>Mininimal length:</span> <span>{t('questionnaire.minimalLength')}:</span> <span className={paragraph}> {min} </span> <span className={paragraph}> {min} </span> {current !== 0 && current < min && ( {current !== 0 && current < min && ( <span <span Loading @@ -41,7 +46,7 @@ export const QuestionDescription = ({ color: ${Colors.RED4}; color: ${Colors.RED4}; `} `} > > Needed {t('questionnaire.needed')} </span> </span> )} )} </span> </span> Loading Loading
analyst/src/routes/_layout/$exerciseId/emails/route.tsx +4 −2 Original line number Original line Diff line number Diff line Loading @@ -9,8 +9,9 @@ import { import { css } from '@emotion/css' import { css } from '@emotion/css' import { ExerciseContext, useEmailThreads } from '@inject/analyst' import { ExerciseContext, useEmailThreads } from '@inject/analyst' import type { ExtendedEmailThread } from '@inject/frontend' import type { ExtendedEmailThread } from '@inject/frontend' import { noEmailReceived, ThreadLogCards } from '@inject/frontend' import { ThreadLogCards } from '@inject/frontend' import type { Email, Team } from '@inject/graphql' import type { Email, Team } from '@inject/graphql' import { useTranslationFrontend } from '@inject/locale' import { TabButton } from '@inject/shared' import { TabButton } from '@inject/shared' import { import { createFileRoute, createFileRoute, Loading Loading @@ -82,6 +83,7 @@ const RouteComponent = () => { {team.name} {team.name} </TabButton> </TabButton> ) ) const { t } = useTranslationFrontend() return ( return ( <> <> <div <div Loading Loading @@ -124,7 +126,7 @@ const RouteComponent = () => { <ThreadLogCards <ThreadLogCards teamId={selectedTeam.id} teamId={selectedTeam.id} emailThreads={emailThreads} emailThreads={emailThreads} noEmailString={noEmailReceived} noEmailString={t('emails.noArchived')} inAnalyst inAnalyst onClick={emailThread => { onClick={emailThread => { nav({ nav({ Loading
frontend/src/actionlog/InjectMessage/Content/ToolContent.tsx +23 −19 Original line number Original line Diff line number Diff line import { css } from '@emotion/css' import { css } from '@emotion/css' import type { ToolDetails } from '@inject/graphql' import type { ToolDetails } from '@inject/graphql' import { useTranslationFrontend } from '@inject/locale' import { breakWord } from '@inject/shared' import { breakWord } from '@inject/shared' import type { NavigateOptions } from '@tanstack/react-router' import type { NavigateOptions } from '@tanstack/react-router' import type { FC } from 'react' import type { FC } from 'react' Loading Loading @@ -41,16 +42,18 @@ const ToolContent: FC<ToolContentProps> = ({ exerciseId, exerciseId, inInstructor, inInstructor, getFileLink, getFileLink, }) => ( }) => { const { t } = useTranslationFrontend() return ( <div className={wrapper}> <div className={wrapper}> {details.tool.requiresInput && ( {details.tool.requiresInput && ( <> <> <div className={emphasized}>argument:</div> <div className={emphasized}>{t('tools.argument')}</div> <div className={breakWord}>{details.argument}</div> <div className={breakWord}>{details.argument}</div> <div /> <div /> </> </> )} )} <div className={emphasized}>response:</div> <div className={emphasized}>{t('tools.response')}</div> <div className={response}> <div className={response}> <ContentComponent <ContentComponent getFileLink={getFileLink} getFileLink={getFileLink} Loading @@ -61,5 +64,6 @@ const ToolContent: FC<ToolContentProps> = ({ </div> </div> </div> </div> ) ) } export default ToolContent export default ToolContent
frontend/src/actionlog/InjectMessage/Content/TraineeQuestionnaireContent.tsx +2 −2 Original line number Original line Diff line number Diff line Loading @@ -305,7 +305,7 @@ const TraineeQuestionnaireContent: FC<TraineeQuestionnaireContentProps> = ({ gap: 0.5rem; gap: 0.5rem; `} `} > > {onClose && <Button text='Close' onClick={onClose} />} {onClose && <Button text={t('close')} onClick={onClose} />} <Button <Button className={cx({ className={cx({ [wiggleClass]: wiggling, [wiggleClass]: wiggling, Loading @@ -316,7 +316,7 @@ const TraineeQuestionnaireContent: FC<TraineeQuestionnaireContentProps> = ({ title={title} title={title} loading={loading} loading={loading} > > Submit {t('submit')} </Button> </Button> </div> </div> } } Loading
frontend/src/components/FileArea/index.tsx +5 −2 Original line number Original line Diff line number Diff line import { Colors, FileInput, FormGroup, type Intent } from '@blueprintjs/core' import { Colors, FileInput, FormGroup, type Intent } from '@blueprintjs/core' import { css, cx } from '@emotion/css' import { css, cx } from '@emotion/css' import { useUploadFile } from '@inject/graphql' import { useUploadFile } from '@inject/graphql' import { useTranslationFrontend } from '@inject/locale' import type { NavigateOptions } from '@tanstack/react-router' import type { NavigateOptions } from '@tanstack/react-router' import type { ChangeEvent, FC } from 'react' import type { ChangeEvent, FC } from 'react' import { useCallback, useState } from 'react' import { useCallback, useState } from 'react' Loading Loading @@ -30,6 +31,7 @@ const FileArea: FC<{ addFileInfo, addFileInfo, getLink, getLink, }) => { }) => { const { t } = useTranslationFrontend() const [internalError, setInternalError] = useState('') const [internalError, setInternalError] = useState('') // TODO: use contextual saving of file selection, we have an API for that :tm: // TODO: use contextual saving of file selection, we have an API for that :tm: Loading Loading @@ -70,7 +72,7 @@ const FileArea: FC<{ internalError internalError ? internalError ? internalError : !teamId : !teamId ? 'Select a team before selecting a file' ? t('files.selectTeamFirst') : undefined : undefined } } intent={ intent={ Loading @@ -90,7 +92,8 @@ const FileArea: FC<{ [fileInputDanger]: intent === 'danger' || !!internalError, [fileInputDanger]: intent === 'danger' || !!internalError, } } )} )} text='Attach a file' text={t('files.attachFile')} buttonText={t('files.browse')} onInputChange={handleFileChange} onInputChange={handleFileChange} /> /> </FormGroup> </FormGroup> Loading
frontend/src/components/Questionnaire/QuestionDescription.tsx +8 −3 Original line number Original line Diff line number Diff line import { Classes, Colors } from '@blueprintjs/core' import { Classes, Colors } from '@blueprintjs/core' import { css, cx } from '@emotion/css' import { css, cx } from '@emotion/css' import { useTranslationFrontend } from '@inject/locale' import { ErrorMessage } from '@inject/shared' import { ErrorMessage } from '@inject/shared' const container = css` const container = css` Loading @@ -21,6 +22,8 @@ export const QuestionDescription = ({ max: number max: number current: number current: number }) => { }) => { const { t } = useTranslationFrontend() if (min <= 1 && max === -1) { if (min <= 1 && max === -1) { return null return null } } Loading @@ -28,12 +31,14 @@ export const QuestionDescription = ({ <div className={cx(Classes.TEXT_MUTED, container)}> <div className={cx(Classes.TEXT_MUTED, container)}> {max !== -1 && current >= max && ( {max !== -1 && current >= max && ( <div> <div> <ErrorMessage minimal>Maximum characters reached</ErrorMessage> <ErrorMessage minimal> {t('questionnaire.maxCharactersReached')} </ErrorMessage> </div> </div> )} )} {min !== 1 && ( {min !== 1 && ( <span> <span> <span>Mininimal length:</span> <span>{t('questionnaire.minimalLength')}:</span> <span className={paragraph}> {min} </span> <span className={paragraph}> {min} </span> {current !== 0 && current < min && ( {current !== 0 && current < min && ( <span <span Loading @@ -41,7 +46,7 @@ export const QuestionDescription = ({ color: ${Colors.RED4}; color: ${Colors.RED4}; `} `} > > Needed {t('questionnaire.needed')} </span> </span> )} )} </span> </span> Loading