{"version":3,"sources":["configure/apiAuthorizationConfig.ts","api/api-authorization/AuthorizeService.ts","api/api-authorization/useAuthorizeService.ts","api/api-authorization/useAuthenticatedState.ts","components/layout/UserNav.tsx","api/account/AccountService.ts","api/account/ClaimTypes.ts","api/account/useAccountService.ts","api/account/useCurrentUserId.ts","globalState/currentUserDetails/useCurrentUserRolesCache.ts","api/account/useCurrentUserRoles.ts","api/account/useExternalAuthenticationSchemes.ts","api/account/useLockoutCallback.ts","api/account/useResendConfirmationEmailCallback.ts","api/account/useStartExternalLoginCallback.ts","shared/authorizeRoute/AuthorizeContainer.tsx","services/OverallRiskService.ts","shared/authorizeRoute/AuthorizeRoute.tsx","components/shared/NavLinkTrackActive.tsx","configure/security/IdentityRoles.ts","api/main/models/codeOnly/SubscriptionType.ts","api/main/models/Subscription.ts","configure/mainApiConfig.ts","api/main/subscriptions/useSubscription.ts","globalState/currentUserDetails/useCurrentUserProfileCache.ts","api/main/models/RoleGroup.ts","api/main/models/User.ts","api/main/models/Profile.ts","api/main/profiles/useProfile.ts","api/main/profiles/useCurrentUserProfile.ts","configure/recoilPersistConfig.ts","globalState/subscriptions/useSubscriptionEmulation.ts","globalState/subscriptions/useCurrentUserOrEmulatedSubscriptionId.ts","components/home/Navigation.tsx","components/layout/appNavbarBrand/AppNavbarBrand.tsx","components/layout/Header.tsx","components/layout/FooterNavigation.tsx","components/layout/Footer.tsx","shared/sidebarNav/SidebarNav.tsx","shared/sidebarNav/SidebarNavTitle.tsx","components/shared/AppRoutes.tsx","components/shared/LoadingIndicator.tsx","components/shared/background/Background.tsx","components/api-authorization/LoginWaiting.tsx","components/api-authorization/ApiAuthorizationConstants.ts","components/api-authorization/Login.tsx","components/api-authorization/Logout.tsx","components/api-authorization/routes.tsx","shared/userFriendlyErrorMessage/registerErrorMessageConverters.ts","shared/alertOnErrors/AlertOnErrors.tsx","shared/userFriendlyErrorMessage/userFriendlyErrorMessage.ts","shared/useChanges/useChanges.ts","shared/useChanges/useChangesArray.ts","components/account/ExternalLoginButton.tsx","components/shared/FormButtons.tsx","components/shared/MainContainer.tsx","services/DriverPinService.ts","shared/passwordValidation/PasswordOptions.ts","shared/passwordValidation/PasswordValidation.ts","shared/passwordValidation/usePasswordValidation.ts","shared/passwordValidation/generatePasswordRulesDescription.ts","components/profiles/RegisterProfileDetails.tsx","api/main/profiles/useRegisterProfileCallback.ts","components/profiles/ConfirmInviteProfileDetails.tsx","api/main/profiles/useProfileForInvite.ts","components/account/routes.tsx","components/account/Login.tsx","api/account/useLoginWithPasswordCallback.ts","components/account/Register.tsx","api/account/useRegisterAccountCallback.ts","components/account/ExternalLoginCallback.tsx","api/account/useCompletedExternalLoginDetails.ts","api/account/useCreateAccountForExternalLoginCallback.ts","components/account/ForgotPassword.tsx","api/account/useSendPasswordResetEmailCallback.ts","components/account/ResetPassword.tsx","api/account/useResetPasswordCallback.ts","components/account/ConfirmEmail.tsx","api/account/useConfirmEmailCallback.ts","components/account/ConfirmEmailChange.tsx","api/account/useConfirmEmailChangeCallback.ts","components/account/ConfirmInvite.tsx","api/account/useConfirmInviteCallback.ts","components/profiles/ChangeEmail.tsx","components/shared/Banner.tsx","components/shared/pillsNavBar/PillsNavBar.tsx","components/profiles/ProfileNavigation.tsx","shared/useSaveInStore/useSaveInStore.ts","api/main/profiles/useCreateProfileCallback.ts","api/main/profiles/useUpdateProfileCallback.ts","api/main/profiles/useSaveProfileCallback.ts","components/profiles/ProfileDetails.tsx","components/profiles/routes.tsx","components/profiles/Profile.tsx","api/main/users/useUser.ts","api/account/useChangeEmailCallback.ts","components/profiles/ChangePassword.tsx","api/account/useChangePasswordCallback.ts","shared/useURLSearchParams/useURLSearchParams.ts","shared/useURLSearchParams/useReplaceSearchParamsEffect.ts","shared/useURLSearchParams/useSearchParams.ts","components/home/Home.tsx","components/home/routes.tsx","components/administration/AdministrationNavigation.tsx","components/shared/SidebarRequired.tsx","components/administration/routes.tsx","components/administration/AdministrationHome.tsx","shared/useFetchMoreCallback/useFetchMoreCallback.ts","api/main/models/QuestionTag.ts","components/shared/searchInput/SearchInput.tsx","components/shared/NoResultsFound.tsx","components/shared/StickyToolbar.tsx","components/shared/TableRowButtons.tsx","components/shared/cardsOrTable/CardsOrTable.tsx","globalState/preferredListViewMode/usePreferredListViewMode.ts","components/questionTags/QuestionTagsList.tsx","api/main/questionTags/useQuestionTag.ts","api/main/questionTags/useCreateQuestionTagCallback.ts","api/main/questionTags/useUpdateQuestionTagCallback.ts","components/questionTags/EditQuestionTag.tsx","api/main/questionTags/useSaveQuestionTagCallback.ts","components/questionTags/DeleteQuestionTag.tsx","components/questionTags/routes.tsx","api/main/questionTags/useQuestionTags.ts","api/main/questionTags/useDeleteQuestionTagCallback.ts","api/main/models/DriverMetric.ts","components/driverMetrics/DriverMetricsList.tsx","api/main/driverMetrics/useDriverMetric.ts","api/main/driverMetrics/useCreateDriverMetricCallback.ts","api/main/driverMetrics/useUpdateDriverMetricCallback.ts","components/driverMetrics/EditDriverMetric.tsx","api/main/driverMetrics/useSaveDriverMetricCallback.ts","components/driverMetrics/DeleteDriverMetric.tsx","components/driverMetrics/routes.tsx","api/main/driverMetrics/useDriverMetrics.ts","api/main/driverMetrics/useDeleteDriverMetricCallback.ts","components/subscriptions/SubscriptionsListBase.tsx","api/main/subscriptions/useSubscriptions.ts","api/main/subscriptions/useCreateSubscriptionCallback.ts","api/main/subscriptions/useUpdateSubscriptionCallback.ts","api/main/subscriptions/useSaveSubscriptionCallback.ts","api/main/models/BlobReference.ts","api/main/blobReferences/BlobUploadService.ts","api/main/blobReferences/useUploadBlobCallback.ts","components/shared/useBlobReferenceState/useBlobReferenceState.ts","components/shared/fileUploadButton/FileUploadButton.tsx","components/shared/uploadedImagePreview/UploadedImagePreview.tsx","components/subscriptions/image/ImageTab.tsx","components/subscriptions/SubscriptionAdministrationNavigation.tsx","components/shared/TwoValueSwitch.tsx","components/subscriptions/Distributors/DistributorEditNavigation.tsx","components/subscriptions/Distributors/Administration/DistributorSubscriptionEditNavigation.tsx","components/subscriptions/Studies/StudyEditNavigation.tsx","components/subscriptions/EditSubscriptionBase.tsx","api/main/subscriptions/viewModels/useEditSubscriptionViewModel.ts","api/main/subscriptions/useGenerateUniqueStudyPinCallback.ts","api/main/models/SubscriptionTeam.ts","api/main/profiles/viewModels/useUsersListViewBaseViewModel.ts","api/main/subscriptionTeams/useDeleteSubscriptionTeamCallback.ts","api/main/profiles/useDeleteProfileCallback.ts","components/subscriptions/DeleteSubscription.tsx","api/main/models/codeOnly/AssessmentType.ts","components/subscriptions/routes.tsx","components/subscriptions/Subscriptions/SubscriptionsList.tsx","components/subscriptions/Subscriptions/EditSubscription.tsx","api/main/subscriptions/useDeleteSubscriptionCallback.ts","api/main/models/codeOnly/FeedbackStyle.ts","api/main/models/Assessment.ts","api/main/assessments/useCreateAssessmentCallback.ts","api/main/assessments/useUpdateAssessmentCallback.ts","api/main/models/AssessmentFeedback.ts","api/main/assessmentFeedbacks/useCreateAssessmentFeedbackCallback.ts","api/main/assessmentFeedbacks/useUpdateAssessmentFeedbackCallback.ts","api/main/models/Question.ts","api/main/models/QuestionTagLink.ts","api/main/questionTagLinks/useDeleteQuestionTagLinkCallback.ts","api/main/models/DriverMetricAdjustment.ts","api/main/driverMetricAdjustments/useCreateDriverMetricAdjustmentCallback.ts","api/main/driverMetricAdjustments/useUpdateDriverMetricAdjustmentCallback.ts","api/main/driverMetricAdjustments/useSaveDriverMetricAdjustmentCallback.ts","api/main/driverMetricAdjustments/useDeleteDriverMetricAdjustmentCallback.ts","api/main/models/DriverMetricRecommendation.ts","api/main/driverMetricRecommendations/useCreateDriverMetricRecommendationCallback.ts","api/main/driverMetricRecommendations/useUpdateDriverMetricRecommendationCallback.ts","api/main/driverMetricRecommendations/useSaveDriverMetricRecommendationCallback.ts","api/main/driverMetricRecommendations/useDeleteDriverMetricRecommendationCallback.ts","api/main/questionTagLinks/useCreateQuestionTagLinkCallback.ts","api/main/questionTagLinks/useUpdateQuestionTagLinkCallback.ts","api/main/questionTagLinks/useSaveQuestionTagLinkCallback.ts","shared/validator-react-contrib/useValidatorArrayCallback.ts","utilities/hasAnyValidationErrors.ts","api/main/models/AssessmentItem.ts","api/main/assessmentItems/useCreateAssessmentItemCallback.ts","api/main/assessmentItems/useUpdateAssessmentItemCallback.ts","shared/htmlEditor/BlobReferenceUploadAdapter.ts","shared/htmlEditor/HtmlEditor.tsx","shared/fetch-oembed/providers/DailyMotionProvider.ts","shared/fetch-oembed/providers/FacebookProvider.ts","shared/fetch-oembed/providers/FlickrProvider.ts","shared/fetch-oembed/providers/GoogleMapsProvider.ts","shared/fetch-oembed/providers/InstagramProvider.ts","shared/fetch-oembed/providers/SpotifyProvider.ts","shared/fetch-oembed/providers/TwitterProvider.ts","shared/fetch-oembed/providers/VimeoProvider.ts","shared/fetch-oembed/providers/YouTubeProvider.ts","shared/fetch-oembed/FetchOEmbed.ts","shared/fetch-oembed/processOEmbedElements.ts","shared/htmlEditor/HtmlDisplay.tsx","components/shared/cardHeaderCollapse/CardHeaderCollapse.tsx","components/shared/uploadedVideoPreview/UploadedVideoPreview.tsx","components/assessments/edit/feedback/Feedback.tsx","components/assessments/edit/feedback/FeedbackTab.tsx","components/assessments/edit/driverMetrics/DriverMetricRecommendationComponent.tsx","components/assessments/edit/driverMetrics/DriverMetricsTab.tsx","components/questionTags/questionTagSelector/QuestionTagButton.tsx","components/questionTags/questionTagSelector/QuestionTagSelector.tsx","components/assessments/edit/questionTags/QuestionTagsTab.tsx","components/shared/useBlobReferenceState/useBlobReferenceStateArray.ts","api/main/models/AssessmentItemQuestion.ts","api/main/models/AssessmentItemDriverMetricQuantity.ts","api/main/assessmentItemQuestions/useCreateAssessmentItemQuestionCallback.ts","api/main/assessmentItemQuestions/useUpdateAssessmentItemQuestionCallback.ts","api/main/assessmentItemQuestions/useDeleteAssessmentItemQuestionCallback.ts","components/shared/useDisplayOrder/useDisplayOrder.ts","api/main/models/codeOnly/QuestionType.ts","components/shared/inputSelectOrText/InputSelectOrText.tsx","components/questionTags/questionTagSelector/QuestionTagDisplay.tsx","api/main/questions/viewModels/useQuestionsListViewModel.ts","components/shared/tagFilter/TagDisplay.tsx","components/questions/selectQuestionModal/SelectQuestionModal.tsx","components/questions/questionnaires/SelectQuestionnaireModal/SelectQuestionnaireModal.tsx","components/questions/learning/SelectLearningModal/SelectLearningModal.tsx","components/assessments/edit/assessmentItems/assessmentItemDriverMetricDisplayQuantityRuleComponent.tsx","components/assessments/edit/assessmentItems/AssessmentItemComponent.tsx","components/questions/information/SelectInformationModal/SelectInformationModal.tsx","components/assessments/edit/assessmentItems/AssessmentItemsTab.tsx","api/main/AssessmentItemDriverMetricQuantity/useCreateAssessmentItemDriverMetricQuantityCallback.ts","api/main/AssessmentItemDriverMetricQuantity/useUpdateAssessmentItemDriverMetricQuantityCallback.ts","components/assessments/edit/EditAssessmentBase.tsx","api/main/assessments/viewModels/useEditAssessmentViewModel.ts","api/main/assessments/viewModels/useEditAssessmentSupportingData.ts","api/main/assessments/useSaveAssessmentCallback.ts","api/main/assessmentFeedbacks/useSaveAssessmentFeedbackCallback.ts","api/main/assessmentFeedbacks/useDeleteAssessmentFeedbackCallback.ts","api/main/assessmentItems/useSaveAssessmentItemCallback.ts","api/main/assessmentItems/useDeleteAssessmentItemCallback.ts","api/main/AssessmentItemDriverMetricQuantity/useSaveAssessmentItemDriverMetricQuantityCallback.ts","api/main/AssessmentItemDriverMetricQuantity/useDeleteAssessmentItemDriverMetricQuantityCallback.ts","api/main/assessmentItemQuestions/useSaveAssessmentItemQuestionCallback.ts","components/assessments/DeleteAssessmentBase.tsx","api/main/assessments/useAssessment.ts","api/main/assessments/useDeleteAssessmentCallback.ts","components/assessments/AssessmentsListBase.tsx","api/main/assessments/viewModels/useAssessmentListViewModel.ts","api/main/assessments/useCloneAssessmentCallback.ts","components/assessments/assessments/routes.tsx","components/assessments/assessments/AssessmentsList.tsx","components/assessments/assessments/EditAssessment.tsx","components/assessments/assessments/DeleteAssessment.tsx","components/assessments/trainingModules/routes.tsx","components/assessments/trainingModules/TrainingModulesList.tsx","components/assessments/trainingModules/EditTrainingModule.tsx","components/assessments/trainingModules/DeleteTrainingModule.tsx","components/questions/QuestionsListBase.tsx","api/main/questions/useCreateQuestionCallback.ts","api/main/questions/useUpdateQuestionCallback.ts","api/main/questions/useDeleteQuestionCallback.ts","api/main/models/QuestionAnswer.ts","api/main/models/QuestionFeedback.ts","api/main/models/QuestionSequenceQuestion.ts","components/questions/edit/video/VideoTab.tsx","components/questions/edit/multipleChoiceVideo/QuestionAnswerMultipleChoiceVideo.tsx","components/questions/edit/multipleChoiceVideo/QuestionPromptMultipleChoiceVideoTab.tsx","api/main/questionAnswers/useCreateQuestionAnswerCallback.ts","api/main/questionAnswers/useUpdateQuestionAnswerCallback.ts","api/main/questionAnswers/useDeleteQuestionAnswerCallback.ts","components/questions/edit/feedback/Feedback.tsx","components/questions/edit/feedback/FeedbackTab.tsx","api/main/questionFeedbacks/useCreateQuestionFeedbackCallback.ts","api/main/questionFeedbacks/useUpdateQuestionFeedbackCallback.ts","api/main/questionFeedbacks/useDeleteQuestionFeedbackCallback.ts","components/questions/edit/questionTags/QuestionTagsTab.tsx","components/questions/edit/driverMetrics/DriverMetricRecommendationComponent.tsx","components/questions/edit/driverMetrics/DriverMetricsTab.tsx","components/questions/edit/slidingScaleVideo/QuestionAnswerSlidingScaleVideo.tsx","components/questions/edit/slidingScaleVideo/SlidingScaleSlider.tsx","components/questions/edit/slidingScaleVideo/QuestionPromptSlidingScaleVideoTab.tsx","utilities/timeStringFromSeconds.ts","components/questions/edit/responseTimeVideo/QuestionAnswerResponseTimeVideo.tsx","components/questions/edit/responseTimeVideo/QuestionPromptResponseTimeVideoTab.tsx","components/questions/edit/image/ImageTab.tsx","components/questions/edit/locationResponseImage/QuestionAnswerLocationResponseImage.tsx","components/shared/interactiveImage/ResizableOverlay.tsx","components/shared/interactiveImage/InteractiveImage.tsx","utilities/textFromHtml.ts","components/questions/edit/locationDiscriminationImage/reponseWindowColors.ts","components/questions/edit/locationResponseImage/QuestionPromptLocationResponseImageTab.tsx","components/questions/edit/locationDiscriminationImage/QuestionAnswerLocationDiscriminationImage.tsx","components/questions/edit/locationDiscriminationImage/QuestionPromptLocationDiscriminationImageTab.tsx","components/questions/edit/sequenceOfQuestions/QuestionSequenceQuestionComponent.tsx","components/questions/edit/sequenceOfQuestions/SequenceOfQuestionsTab.tsx","api/main/questionSequenceQuestions/useCreateQuestionSequenceQuestionCallback.ts","api/main/questionSequenceQuestions/useUpdateQuestionSequenceQuestionCallback.ts","api/main/questionSequenceQuestions/useDeleteQuestionSequenceQuestionCallback.ts","components/questions/edit/learningText/LearningTextTab.tsx","components/questions/questionnaires/QuestionnaireQuestion/QuestionnaireQuestionAnswerMultipleChoice.tsx","components/questions/questionnaires/QuestionnaireQuestion/SlidingScaleQuestionnaireQuestion.tsx","components/questions/questionnaires/QuestionnaireQuestion/CreateQuestionnaireQuestionModal/CreateQuestionnaireQuestionModal.tsx","components/questions/questionnaires/QuestionnaireQuestion/QuestionnaireQuestionSequenceQuestionComponent.tsx","components/questions/questionnaires/QuestionnaireQuestion/SequenceOfQuestionnaireQuestionsTab.tsx","components/questions/edit/informationText/InformationTextTab.tsx","components/questions/edit/multipleChoiceImage/QuestionAnswerMultipleChoiceImage.tsx","components/questions/edit/multipleChoiceImage/QuestionPromptMultipleChoiceImageTab.tsx","components/questions/edit/EditQuestionBase.tsx","api/main/questions/viewModels/useEditQuestionViewModel.ts","api/main/questions/viewModels/useEditQuestionSupportingData.ts","api/main/questions/useSaveQuestionCallback.ts","api/main/questionAnswers/useSaveQuestionAnswerCallback.ts","api/main/questionFeedbacks/useSaveQuestionFeedbackCallback.ts","api/main/questionSequenceQuestions/useSaveQuestionSequenceQuestionCallback.ts","api/main/questions/useQuestions.ts","api/main/models/QuestionResponseEvent.ts","api/main/questionResponseEvents/useDeleteQuestionResponseEventCallback.ts","components/questions/DeleteQuestionBase.tsx","api/main/questions/viewModels/useQuestionLinksViewModel.ts","components/questions/questions/routes.tsx","components/questions/questions/QuestionsList.tsx","components/questions/questions/EditQuestion.tsx","components/questions/questions/DeleteQuestion.tsx","components/questions/questionnaires/routes.tsx","components/questions/questionnaires/QuestionnairesList.tsx","components/questions/questionnaires/EditQuestionnaire.tsx","components/questions/questionnaires/DeleteQuestionnaire.tsx","components/questions/learning/routes.tsx","components/questions/learning/LearningList.tsx","components/questions/learning/EditLearning.tsx","components/questions/learning/DeleteLearning.tsx","api/main/models/SubscriptionAssessment.ts","api/main/subscriptionAssessments/useCreateSubscriptionAssessmentCallback.ts","api/main/subscriptionAssessments/useUpdateSubscriptionAssessmentCallback.ts","components/subscriptionAssessments/SubscriptionAssessmentsListBase.tsx","api/main/subscriptionAssessments/viewModels/useSubscriptionAssessmentsListBaseViewModel.ts","api/main/subscriptionAssessments/useSaveSubscriptionAssessmentCallback.ts","api/main/subscriptionAssessments/useDeleteSubscriptionAssessmentCallback.ts","components/subscriptionAssessments/assessments/routes.tsx","components/subscriptionAssessments/assessments/SubscriptionAssessmentsList.tsx","components/subscriptionAssessments/trainingModules/routes.tsx","components/subscriptionAssessments/trainingModules/SubscriptionTrainingModulesList.tsx","api/main/models/UserAssessmentAssignment.ts","api/main/models/AssessmentSession.ts","components/assessmentSessions/launch/progress/ScoreProgressBar.tsx","components/assessmentSessions/launch/utilities/questionScoreFromNumber.ts","components/me/DueDateLabel.tsx","components/me/DashboardAssessmentCard.tsx","components/me/MeDashboard.tsx","api/main/meDashboardViewModels/useMeDashboardViewModel.ts","components/me/routes.tsx","components/users/UsersListBase.tsx","api/main/profiles/useProfileSupportingData.ts","components/users/DeleteUserBase.tsx","api/main/users/useChangeUserRoleGroupCallback.ts","components/users/drivers/DriverNavigation.tsx","components/users/managers/ManagerNavigation.tsx","components/users/administrators/AdministratorNavigation.tsx","components/users/EditUserBase.tsx","api/account/useInviteCallback.ts","api/account/useResendInviteEmailCallback.ts","api/account/useChangeAccountEmailCallback.ts","api/main/profiles/useGenerateUniqueDriverPinCallback.ts","components/users/administrators/routes.tsx","components/users/administrators/AdministratorsList.tsx","components/users/administrators/EditAdministrator.tsx","components/users/administrators/DeleteAdministrator.tsx","components/manage/routes.tsx","components/manage/ManageHome.tsx","components/manage/ManageNavigation.tsx","components/subscriptionTeam/SubscriptionTeamNavigation.tsx","components/users/drivers/DriversList.tsx","components/users/drivers/DeleteDriver.tsx","components/users/drivers/EditDriver.tsx","components/users/drivers/routes.tsx","components/users/managers/ManagersList.tsx","components/users/managers/DeleteManager.tsx","components/users/managers/EditManager.tsx","components/users/managers/routes.tsx","components/subscriptionTeam/SubscriptionTeamsList.tsx","api/main/subscriptionTeams/useSubscriptionTeam.ts","api/main/subscriptionTeams/useCreateSubscriptionTeamCallback.ts","api/main/subscriptionTeams/useUpdateSubscriptionTeamCallback.ts","components/subscriptionTeam/EditSubscriptionTeam.tsx","api/main/subscriptionTeams/useSaveSubscriptionTeamCallback.ts","components/subscriptionTeam/routes.tsx","api/main/subscriptionTeams/viewModels/useListSubscriptionTeamsViewModel.ts","components/subscriptionTeam/DeleteSubscriptionTeam.tsx","api/main/models/UserDriverMetric.ts","api/main/userAssessmentAssignments/viewModels/useUserAssessmentAssignmentsListViewBaseViewModel.ts","api/main/userAssessmentAssignments/useCreateUserAssessmentAssignmentCallback.ts","api/main/userAssessmentAssignments/useUpdateUserAssessmentAssignmentCallback.ts","components/users/UserNavigation.tsx","components/shared/ISODateTimeInput.tsx","components/userAssessmentAssignment/UserAssessmentAssignmentsListBase.tsx","api/main/userAssessmentAssignments/useSaveUserAssessmentAssignmentCallback.ts","api/main/userAssessmentAssignments/useDeleteUserAssessmentAssignmentCallback.ts","api/main/assessments/useSendAssessmentReminderCallback.ts","api/main/assessments/useSendAllAssessmentReminderCallback.ts","components/userAssessmentAssignment/assessments/UserAssessmentAssignmentsList.tsx","components/userAssessmentAssignment/assessments/routes.tsx","components/userAssessmentAssignment/trainingModules/UserAssessmentTrainingModuleAssignmentsList.tsx","components/userAssessmentAssignment/trainingModules/routes.tsx","api/main/assessmentSessions/useCreateAssessmentSessionCallback.ts","api/main/assessmentSessions/useUpdateAssessmentSessionCallback.ts","api/main/questionResponseEvents/useCreateQuestionResponseEventCallback.ts","api/main/questionResponseEvents/useUpdateQuestionResponseEventCallback.ts","utilities/subsitutePlaceholders.ts","components/assessmentSessions/launch/feedback/ShowQuestionFeedback.tsx","components/assessmentSessions/launch/FinishPage.tsx","components/assessmentSessions/launch/questions/learningImage/ShowQuestionLearningImage.tsx","components/assessmentSessions/launch/questions/learningText/ShowQuestionLearningText.tsx","components/assessmentSessions/launch/questions/learningVideo/ShowQuestionLearningVideo.tsx","shared/prefetchImage/ImagePrefetcher.ts","shared/prefetchImage/usePrefetchImages.ts","components/assessmentSessions/launch/questions/useClickSound/useClickSound.ts","components/assessmentSessions/launch/questions/locationDiscriminationImage/QuestionTimer.tsx","components/assessmentSessions/launch/questions/locationDiscriminationImage/ShowQuestionLocationDiscriminationImage.tsx","components/assessmentSessions/launch/questions/locationResponseImage/ShowQuestionLocationResponseImage.tsx","components/assessmentSessions/launch/questions/multipleChoiceVideo/ShowQuestionMultipleChoiceVideo.tsx","components/assessmentSessions/launch/questions/responseTimeVideo/ShowQuestionResponseTimeVideo.tsx","components/assessmentSessions/launch/questions/slidingScaleVideo/ShowQuestionSlidingScaleVideo.tsx","components/assessmentSessions/launch/questions/QuestionnaireQuestions/ShowQuestionnaireMultipleChoice.tsx","components/assessmentSessions/launch/questions/QuestionnaireQuestions/ShowQuestionnaireSlidingScale.tsx","components/assessmentSessions/launch/questions/QuestionnaireQuestions/ShowQuestionnaireInput.tsx","components/assessmentSessions/launch/questions/QuestionnaireQuestions/QuestionnaireQuestionListComponent.tsx","components/assessmentSessions/launch/questions/informationVideo/ShowQuestionInformationVideo.tsx","components/assessmentSessions/launch/questions/informationImage/ShowQuestionInformationImage.tsx","components/assessmentSessions/launch/questions/informationText/ShowQuestionInformationText.tsx","components/assessmentSessions/launch/questions/multipleChoiceImage/ShowQuestionMultipleChoiceImage.tsx","components/assessmentSessions/launch/questions/ShowQuestion.tsx","components/assessmentSessions/launch/StartPage.tsx","components/assessmentSessions/launch/utilities/calculateQuestionScore.ts","components/assessmentSessions/launch/utilities/combineQuestionScores.ts","components/assessmentSessions/launch/utilities/calculateAssessmentScore.ts","components/assessmentSessions/launch/progress/PageProgress.tsx","components/assessmentSessions/launch/LaunchAssessmentBase.tsx","api/main/assessmentSessions/viewModels/useLaunchAssessmentSessionViewModel.ts","api/main/assessmentSessions/viewModels/useLaunchAssessmentSessionSupportingData.ts","api/main/assessmentSessions/useSaveAssessmentSessionCallback.ts","api/main/userDriverMetrics/useApplyDriverMetricsForAssessmentSessionCallback.ts","api/main/questionResponseEvents/useSaveQuestionResponseEventCallback.ts","components/assessmentSessions/StartAssessmentBase.tsx","api/main/assessmentSessions/useInitializeAssessmentSessionCallback.ts","components/assessmentSessions/assessments/StartAssessment.tsx","components/assessmentSessions/assessments/routes.tsx","components/assessmentSessions/assessments/LaunchAssessment.tsx","components/assessmentSessions/assessments/AssessmentResults.tsx","components/assessmentSessions/trainingModules/StartTraining.tsx","components/assessmentSessions/trainingModules/routes.tsx","components/assessmentSessions/trainingModules/LaunchTraining.tsx","components/assessmentSessions/trainingModules/TrainingResults.tsx","components/dashboard/utilities/getLatestSessions.ts","components/dashboard/utilities/generateDashboardSummary.ts","components/dashboard/utilities/calculateAverageScore.ts","api/main/dashboard/viewModels/useAdministrationDashboardViewModel.ts","components/dashboard/utilities/useExpandedUserAssessmentAssignments.ts","components/dashboard/chartData/useAverageScoreChartData.ts","components/dashboard/chartDataUtilities/ChartDataConverter.ts","components/dashboard/charts/dashboardChartColors.ts","components/dashboard/charts/AverageScoreRadarChart.tsx","components/dashboard/progress/IndividualScoreProgressBar.tsx","components/dashboard/utilities/useCachedDashboardSummaries.ts","components/dashboard/utilities/useDashboardBaseRoute.ts","components/dashboard/tabs/AssessmentProgressDashboardTab.tsx","components/dashboard/backButton/DashboardBackButton.tsx","components/dashboard/utilities/useDashboardRequiresBackButton.ts","components/dashboard/administrationDashboard/AdministrationAssessmentDashboard.tsx","globalState/activeDashboardRiskCategoryFilter/useActiveDashboardRiskCategoryFilter.ts","components/dashboard/chartData/useAverageDriverMetricRiskChartData.ts","components/dashboard/chartData/useCompletionChartData.ts","components/dashboard/charts/AverageDriverMetricRiskDonutChart.tsx","components/dashboard/charts/CompletionBarChart.tsx","components/dashboard/progress/AverageScoreProgressBar.tsx","components/dashboard/progress/AssessmentAverageScoreProgressBar.tsx","components/dashboard/progress/TrainingAverageScoreProgressBar.tsx","components/dashboard/listGroups/DashboardListGroupItem.tsx","components/dashboard/listGroups/OverallRiskFilterListGroupItem.tsx","components/dashboard/tabs/SubscriptionsDashboardTab.tsx","components/dashboard/tabs/UsersDashboardTab.tsx","components/dashboard/tabs/EsituStaffDashboardTab.tsx","components/dashboard/tabs/SubscriptionTeamsDashboardTab.tsx","components/dashboard/tabs/SubscriptionUsersDashboardTab.tsx","components/dashboard/tabs/AssessmentsDashboardTabBase.tsx","components/dashboard/tabs/AssessmentsDashboardTab.tsx","components/dashboard/tabs/TrainingDashboardTab.tsx","globalState/activeDashboardAssessmentType/useActiveDashboardAssessmentType.ts","globalState/activeDashboardTab/useActiveDashboardTab.ts","components/dashboard/listGroups/DistributorDashboardListGroupItem.tsx","components/dashboard/tabs/DistributorsDashboardTab.tsx","configure/chartColors.ts","components/dashboard/charts/DriverMetricsRadarChart.tsx","components/dashboard/charts/DriverScoreProgressBarAsChart.tsx","components/dashboard/tabs/UserProgressDashboardTab.tsx","components/dashboard/chartData/useDriverMetricsChartData.ts","components/dashboard/administrationDashboard/StaffUserDashboard.tsx","api/main/dashboard/viewModels/useSubscriptionDashboardViewModel.ts","components/dashboard/subscriptionDashboard/SubscriptionUserDashboard.tsx","components/dashboard/myDashboard/MyDashboard.tsx","components/dashboard/tabs/ExportAssessmentResults.tsx","components/dashboard/subscriptionDashboard/SubscriptionDashboard.tsx","components/dashboard/subscriptionDashboard/SubscriptionAssessmentDashboard.tsx","components/dashboard/subscriptionDashboard/SubscriptionTeamDashboard.tsx","components/dashboard/routes.tsx","components/dashboard/dashboard/Dashboard.tsx","components/dashboard/administrationDashboard/AdministrationDashboard.tsx","components/users/import/ImportUsersBase.tsx","api/main/users/useImportUsersCallback.ts","components/users/import/ImportDrivers.tsx","components/users/import/ImportManagers.tsx","components/users/import/ImportUserAssessmentAssignmentBase.tsx","components/users/import/routes.tsx","api/main/userAssessmentAssignments/useImportUserAssessmentAssignmentsCallback.ts","components/questions/information/routes.tsx","components/questions/information/InformationList.tsx","components/questions/information/EditInformation.tsx","components/questions/information/DeleteInformation.tsx","components/subscriptions/Distributors/Administration/DistributorAdministrationNavigation.tsx","components/dashboard/tabs/DistributorSubscriptionsDashboardTab.tsx","components/subscriptions/Distributors/routes.tsx","components/subscriptions/Distributors/DistributorsList.tsx","components/subscriptions/Distributors/EditDistributor.tsx","components/subscriptions/Distributors/DistributorAssessmentsList.tsx","components/subscriptions/Distributors/DistributorTrainingList.tsx","components/subscriptions/Distributors/Administration/DistributorAdministrationHome.tsx","components/dashboard/administrationDashboard/DistributorAdministrationDashboard.tsx","components/subscriptions/Distributors/DistributorAdminList.tsx","components/subscriptions/Distributors/Administration/CreateDistributorAdmin.tsx","components/subscriptions/Distributors/Administration/DistributorSubscriptionsList.tsx","components/subscriptions/Distributors/Administration/EditDistributorSubscription.tsx","components/subscriptions/Distributors/Administration/DistributorSubscriptionAssessmentsList.tsx","components/subscriptions/Distributors/Administration/DistributorSubscriptionTrainingList.tsx","api/main/models/SdkClient.ts","api/main/sdkClients/useSdkClient.ts","components/sdk/sdkClients/DeleteSdkClient.tsx","api/main/sdkClients/useCreateSdkClientCallback.ts","api/main/sdkClients/useUpdateSdkClientCallback.ts","shared/useJsonObject/useJsonObject.ts","components/shared/secretInput/SecretInput.tsx","services/ApiKeyGenerationService.ts","components/sdk/sdkClients/EditSdkClient.tsx","api/main/sdkClients/useSaveSdkClientCallback.ts","api/main/models/SdkWebhook.ts","components/sdk/sdkClients/SdkClientsTable.tsx","components/sdk/sdkWebhooks/SdkWebhooksTable.tsx","api/main/sdkWebhooks/useSdkWebhook.ts","api/main/sdkWebhooks/viewModels/useEditSdkWebhookSupportingData.ts","components/sdk/sdkWebhooks/DeleteSdkWebhook.tsx","api/main/models/codeOnly/HttpMethod.ts","api/main/sdkWebhooks/useCreateSdkWebhookCallback.ts","api/main/sdkWebhooks/useUpdateSdkWebhookCallback.ts","components/sdk/sdkWebhooks/webhookEventTypeSelector/WebhookEventTypeButton.tsx","components/sdk/sdkWebhooks/webhookEventTypeSelector/WebhookEventTypeSelector.tsx","api/main/models/codeOnly/SdkWebhookEventType.ts","components/sdk/sdkWebhooks/EditSdkWebhook.tsx","api/main/sdkWebhooks/useSaveSdkWebhookCallback.ts","components/sdk/routes.tsx","components/sdk/SdkOverview.tsx","api/main/sdkClients/viewModels/useSdkOverviewViewModel.ts","api/main/sdkClients/useDeleteSdkClientCallback.ts","api/main/sdkWebhooks/useDeleteSdkWebhookCallback.ts","components/cmsPages/routes.tsx","components/cmsPages/TermsAndConditionsPage.tsx","components/cmsPages/PrivacyPolicyPage.tsx","components/cmsPages/CookiePolicyPage.tsx","components/subscriptions/Studies/Administration/StudyAdministrationNavigation.tsx","components/subscriptions/Studies/routes.tsx","components/subscriptions/Studies/StudiesList.tsx","components/subscriptions/Studies/EditStudy.tsx","components/subscriptions/Studies/StudyAssesmentsList.tsx","components/subscriptions/Studies/Administration/StudyAdministrationHome.tsx","components/dashboard/administrationDashboard/StudyAdministrationDashboard.tsx","api/main/dashboard/viewModels/useStudyAdministrationDashboardViewModel.ts","components/studyAccount/StudyLogin.tsx","api/account/useStudyLoginCallback.ts","components/studyAccount/routes.tsx","components/studyAccount/StudyComplete.tsx","api/account/useStudyLogoutCallback.ts","components/studyAccount/StudyThanks.tsx","configure/routeConfig.tsx","components/shared/NotFound.tsx","components/layout/Sidebar.tsx","components/layout/Layout.tsx","configure/iconsConfig.ts","configure/configureApollo.ts","configure/languageConfig.ts","locales/localeResources.ts","components/subscriptions/SubscriptionStyleOverrides.tsx","api/main/subscriptions/viewModels/useSubscriptionStyleOverridesViewModel.ts","App.tsx","configure/configureServices.ts","configure/i18n.ts","configure/errorMessageConfig.ts","registerServiceWorker.ts","reportWebVitals.ts","index.tsx"],"names":["apiAuthorizationConfig","authService","_popUpDisabled","_callbacks","_nextSubscriptionId","_user","_isAuthenticated","_userManager","this","undefined","a","getUser","user","profile","ensureUserManagerInitialized","userManager","access_token","state","error","signinSilent","createArguments","silentUser","updateState","success","console","log","Error","signinPopup","popUpUser","message","signinRedirect","redirect","url","signinCallback","signoutPopup","signoutRedirect","signoutCallback","response","notifySubscribers","callback","push","subscription","subscriptionId","subscriptionIndex","map","element","index","found","filter","length","splice","useReplaceToNavigate","data","status","AuthenticationResultStatus","Fail","Success","Redirect","fetch","ok","window","location","hostname","toLowerCase","json","settings","automaticSilentRenew","includeIdTokenInSilentRenew","userStore","WebStorageStateStore","prefix","UserManager","events","addUserSignedOut","removeUser","useAuthorizeService","useAuthenticatedState","options","React","isAuthenticated","setIsAuthenticated","setUser","stateChanged","authenticated","userResult","includeUser","subscribe","unsubscribe","UserNav","useToggleState","dropdownOpen","toggleDropdown","t","useTranslation","Dropdown","direction","isOpen","toggle","nav","DropdownToggle","size","round","name","email","preferred_username","className","DropdownMenu","right","DropdownItem","header","tag","to","icon","divider","pathname","local","NavItem","Button","color","AccountService","api","loginWithPassword","request","returnUrl","post","encodeURIComponent","credentials","result","register","defaultRegisterReturnUrl","getExternalAuthenticationSchemes","get","startExternalLogin","provider","form","document","createElement","action","method","body","append","submit","completeExternalLogin","remoteError","createAccountForExternalLogin","model","sendPasswordResetEmail","resetPassword","confirmEmail","confirmEmailChange","currentUserRoles","changePassword","changeEmail","resendConfirmEmail","invite","resendInviteEmail","confirmInvite","changeAccountEmail","lockout","studyLogin","studyLogout","ApiFetch","origin","ClaimTypes","useAccountService","useServices","services","accountService","useCurrentUserId","sub","currentUserRolesCacheState","atom","key","default","roles","isLoading","useCurrentUserRolesCache","useRecoilState","refreshCurrentUserRoles","setRoles","isNullOrUndefined","prevState","useCurrentUserRoles","useAsyncCallback","refresh","isExecuting","errors","lazy","useExternalAuthenticationSchemes","externalAuthenticationSchemes","setExternalAuthenticationSchemes","useLockoutCallback","useResendConfirmationEmailCallback","useStartExternalLoginCallback","OverallRiskCategory","AuthorizeContainer","props","usersRoles","hasRequiredRole","setHasRequiredRole","requireRole","requireRoles","flat","hasRole","roleToCheck","find","it","children","failedCheck","showIfNotAuthorized","AuthorizeRoute","Component","component","render","rest","redirectUrl","href","NavLinkTrackActive","exact","activeClassName","IdentityRoles","SubscriptionType","defaultRiskRules","highRiskBelow","mediumRiskBelow","overallRiskService","value","notStarted","riskRules","NotAssessed","riskRulesToUse","High","Medium","Low","categoryOrValue","getRiskCategory","i18n","tickAmount","colors","i","subscriptionFieldsFragment","gql","mainApiConfig","useSubscription","id","useLazyQuery","variables","Guid","empty","fetchPolicy","pollInterval","onCompleted","load","loading","refetch","currentUserProfileCacheState","useCurrentUserProfilesCache","roleGroupFieldsFragment","userFieldsFragment","profileFieldsFragment","useProfile","isUserId","userId","useCurrentUserProfile","profileCache","setProfileCache","storeProfile","loadProfileFromStore","persistKey","persistAtom","recoilPersist","subscriptionEmulationState","effects_UNSTABLE","useSubscriptionEmulation","useCurrentUserOrEmulatedSubscriptionId","emualtedSubscriptionId","currentUserProfile","Navigation","currentProfile","emulatedSubscriptionId","useMemo","includes","subscriptionType","Study","NavLink","showIf","Subscription","Distributor","AppNavbarBrand","Header","showUserNav","fixed","Container","fluid","display","mobile","Nav","FooterNavigation","target","rel","Footer","SidebarNav","SidebarNavTitle","child","AppRoutes","routes","item","authorize","path","LoadingIndicator","fullWidth","inline","style","ret","width","textAlign","Spinner","type","Background","centerChildren","background","data-background","LoginWaiting","waiting","QueryParameterNames","LogoutActions","LoginActions","ApplicationPaths","DefaultLoginRedirectPath","ApiAuthorizationPrefix","Login","LoginFailed","LoginCallback","Register","Profile","LogOut","LoggedOut","LogOutCallback","IdentityRegisterPath","IdentityManagePath","login","getReturnUrl","processLoginCallback","URLSearchParams","search","setState","redirectToProfile","redirectToRegister","signIn","navigateToReturnUrl","completeSignIn","fromQuery","startsWith","redirectToApiAuthorizationPath","apiAuthorizationPath","replace","Logout","isReady","history","logout","processLogoutCallback","populateAuthenticationState","signOut","completeSignOut","apiAuthorizationRoutes","loginAction","logoutAction","configuredErrorMessageConverters","AlertOnErrors","simple","openErrors","setOpenErrors","toggleOpen","friendlyErrors","friendly","converter","Array","isArray","toString","userFriendlyErrorMessage","errorGroups","groups","group","Alert","Row","Col","xs","onClick","cursor","Badge","pill","details","lang","JSON","stringify","useChanges","unchanged","initialChanges","changes","setChanges","change","reset","useChangesArray","getKey","_changes","hasAnythingChanged","unchangedItem","unchangedItemKey","changeRecord","isAddition","isRemoval","hasUnsavedChanges","oldItem","oldItemKey","newArray","newState","keysInNewArray","newChanges","modelFromChanges","changesToUse","added","removed","updated","Object","keys","modelFor","changeFor","changesFor","addFor","removeFor","markAsSaved","models","hasChangedSomething","keysToCheck","ExternalLoginButton","providerDisplayName","propsClassName","text","context","FormButtons","noPadding","MainContainer","DriverPinService","pinEmailSuffix","pin","endsWith","defaultPasswordOptions","requireDigit","requiredLength","requireLowercase","requireNonAlphanumeric","requiredUniqueChars","requireUppercase","PasswordValidation","passwordOptions","password","charMap","char","charAt","indexOf","RegExp","test","errorDescription","join","valid","usePasswordValidation","passwordValidation","checkPassword","check","passwordRequirements","passwordErrors","requirements","generatePasswordRulesDescrption","useRegisterProfileDetailsProps","useMutation","mutationAction","actionErrors","useRegisterProfileCallback","_registerProfile","isRegisteringProfile","registerProfileErrors","newGuid","firstName","lastName","subscriptionTeamId","uniqueDriverPin","useValidatorCallback","validation","fieldsToCheck","rules","checkRules","validate","validationErrors","registerProfile","RegisterProfileDetails","FormGroup","Label","htmlFor","onChange","e","currentTarget","onBlur","ConfirmInviteProfileDetails","params","code","useProfileForInvite","loadingErrors","Input","readOnly","accountRoutes","loadErrors","requiresTwoFactor","requiresEmailConfirmation","useLoginWithPasswordCallback","isLoggingIn","loginErrors","isPendingEmailConfirmation","setIsPendingEmailConfirmation","useHistory","resendConfirmationEmail","isResendingConfirmationEmail","resendConfirmationEmailErrors","hasSentConfirmationEmail","setHasSentConfirmationEmail","rememberMe","isUsingDriverPin","isPinEmail","isDoingFullPageRedirect","setIsDoingFullPageRedirect","performLogin","succeeded","Card","CardHeader","CardBody","Form","onSubmit","preventDefault","executingChildren","autoComplete","CustomInput","label","checked","displayName","useRegisterAccountCallback","isRegistering","registerErrors","confirmPassword","registerProfileDetailsProps","singleCheck","performRegister","md","FormText","disabled","claims","isNewUser","loginProvider","setData","useCompletedExternalLoginDetails","useCreateAccountForExternalLoginCallback","createAccount","isCreatingAccount","createAccountErrors","emailClaim","emailSent","setEmailSent","useSendPasswordResetEmailCallback","sendResetEmail","isSendingResetEmail","sendResetEmailErrors","hasResetPassword","setHasResetPassword","useResetPasswordCallback","isResettingPassword","resetPasswordErrors","emailConfirmed","setEmailConfirmed","useConfirmEmailCallback","confirmEmailErrors","useConfirmEmailChangeCallback","useConfirmInviteCallback","isConfirmingInvite","confirmInviteErrors","Banner","PillsNavBar","justified","textColor","pills","ProfileNavigation","useSaveInStore","createDataStore","updateDataStore","create","isCreating","createErrors","update","isUpdating","updateErrors","isCreate","beforeSaving","afterSaving","save","isSaving","saveErrors","useCreateProfileCallback","useUpdateProfileCallback","useSaveProfileCallback","_create","createStatus","_update","updateStatus","profileRoutes","profileTabRoutes","hasSaved","setHasSaved","setIsCreate","storeModel","refreshProfile","saveForm","useUser","refreshUserModel","newEmail","useChangeEmailCallback","isChangingPassword","changeEmailErrors","hasSentEmail","setHasSentEmail","hasChangedPassword","setHasChangedPassword","currentPassword","newPassword","useChangePasswordCallback","changePasswordErrors","useURLSearchParams","useLocation","useReplaceSearchParamsEffect","changesValue","set","delete","hash","useSearchParams","forEach","homeRoutes","AdministrationNavigation","download","SidebarRequired","data-sidebar-required","administrationRoutes","administrationSidebarRoutes","useFetchMoreCallback","fetchMoreFromStore","currentEndOffset","merge","newResultLength","_hasMore","setHasMore","fetchMore","offset","updateQuery","previousQueryResult","fetchMoreResult","hasMore","questionTagFieldsFragment","SearchInput","placeholder","onSearchButtonClick","InputGroup","onKeyPress","charCode","InputGroupAddon","addonType","NoResultsFound","StickyToolbar","isStuck","setIsStuck","topOffset","scrollableAncestor","onEnter","onLeave","TableRowButtons","CardsOrTable","viewMode","items","columns","buttons","tableHeadings","onItemClick","sm","lg","column","columnIndex","node","CardFooter","Table","responsive","striped","heading","itemIndex","onDoubleClick","preferredListViewModeState","usePreferredListViewMode","useQuestionTag","useCreateQuestionTagCallback","useUpdateQuestionTagCallback","EditQuestionTag","useParams","_isLoading","useSaveQuestionTagCallback","goBack","saveFormErrors","outline","questionTagRoutes","searchParam","setSearch","startOffset","first","pageSize","prevResults","newResults","useQuestionTags","allItems","useToggleStateArray","isMenuOpen","toggleMenuOpen","lowerSearch","toLocaleLowerCase","setViewMode","ButtonGroup","view","CardTitle","ButtonDropdown","caret","useDeleteQuestionTagCallback","remove","removeErrors","onRemoveFormSubmit","isRemoving","removeFormErrors","plaintext","driverMetricFieldsFragment","useDriverMetric","useCreateDriverMetricCallback","useUpdateDriverMetricCallback","EditDriverMetric","startValue","useSaveDriverMetricCallback","driverMetricRoutes","useDriverMetrics","useDeleteDriverMetricCallback","SubscriptionsListBase","title","subscriptionTypes","baseRoute","navigationPills","distributorSubscriptionList","useSubscriptions","currentEmulatedSubscriptionId","emulateSubscription","subscriptionIdToUse","setSubscriptionIdToUse","onManage","onStopManaging","distributorSubscriptionId","companyName","currentUsers","useCreateSubscriptionCallback","useUpdateSubscriptionCallback","useSaveSubscriptionCallback","blobReferenceFieldsFragment","BlobUploadService","apiFetch","files","uploadMultiple","file","FormData","init","headers","newHeaders","Headers","filename","dataUrl","blob","useUploadBlobCallback","uploadService","upload","useBlobReferenceState","onUploaded","initialValue","useState","blobReference","setBlobReference","uploadBlob","isUploading","uploadErrors","clearUpload","useCallback","FileUploadButton","onUpload","UploadedImagePreview","src","alt","ImageTab","imageBlob","uploadImageBlob","isUploadingImageBlob","clearImageBlob","isImageDropdownOpen","toggleImageDropdown","SubscriptionAdministrationNavigation","onNavigate","editLink","onNavLinkClick","link","getAttribute","TwoValueSwitch","leftLabel","rightLabel","uniqueName","noGutters","DistributorEditNavigation","DistributorSubscriptionEditNavigation","StudyEditNavigation","CreateSubscriptionBase","EditSubscriptionBase","onCreateDefaultValues","isInDistributor","currentSubscriptionId","useEditSubscriptionViewModel","archived","brandColor","brandImageBlobReferenceId","maxUsers","restrictMaxUsers","allowBranding","allowExport","studyUniqueCode","studyReturnUrl","activeSubscriptionType","setImageBlob","uploadImageBlobErrors","useEffect","brandImageBlobReference","generateUniqueStudyPin","useGenerateUniqueStudyPinCallback","isGeneratingUniqueStudyPin","generateUniqueStudyPinErrors","newPin","regeneratePin","navigateTo","hasStudyAccessCode","protocol","host","getRiskName","paddingLeft","paddingRight","min","max","valueAsNumber","Collapse","parseInt","subscriptionTeamFieldsFragment","useUsersListViewBaseViewModel","subscriptionIdOrEmptyGuid","subscriptionTeamIdOrEmptyGuid","subscriptionTeam","subscriptionTeams","useDeleteSubscriptionTeamCallback","useDeleteProfileCallback","AssessmentType","subscriptionRoutes","useDeleteSubscriptionCallback","removeProfile","removeProfileErrors","removeTeam","removeTeamErrors","lockoutErrors","archive","FeedbackStyle","feedbackStyleDisplayName","NoScore","NoFeedback","SummaryFeedback","EachQuestionFeedback","assessmentFieldsFragment","useCreateAssessmentCallback","useUpdateAssessmentCallback","assessmentFeedbackFieldsFragment","useCreateAssessmentFeedbackCallback","useUpdateAssessmentFeedbackCallback","questionFieldsFragment","questionDefaultValues","questionType","questionText","imageBlobReferenceId","videoBlobReferenceId","questionTextImageBlobReferenceId","preQuestionText","maximumClicks","maxScore","timeLimitSeconds","numberOfSubQuestions","driverMetricId","questionTagLinkFieldsFragment","useDeleteQuestionTagLinkCallback","driverMetricAdjustmentFieldsFragment","useCreateDriverMetricAdjustmentCallback","useUpdateDriverMetricAdjustmentCallback","useSaveDriverMetricAdjustmentCallback","useDeleteDriverMetricAdjustmentCallback","driverMetricRecommendationFieldsFragment","driverMetricRecommendationDefaultValues","targetId","targetType","minScore","useCreateDriverMetricRecommendationCallback","useUpdateDriverMetricRecommendationCallback","useSaveDriverMetricRecommendationCallback","useDeleteDriverMetricRecommendationCallback","useCreateQuestionTagLinkCallback","useUpdateQuestionTagLinkCallback","useSaveQuestionTagLinkCallback","useValidatorArrayCallback","validating","deps","setValidationErrors","validator","Validator","fields","hasAnyValidationErrors","flatErrors","assessmentItemFieldsFragment","assessmentItemDefaultValues","assessmentId","displayOrder","moment","unix","numberOfQuestionsToPresent","counterbalanceGroup","useCreateAssessmentItemCallback","useUpdateAssessmentItemCallback","BlobReferenceUploadAdapter","loader","then","Promise","resolve","reject","uploadFile","BlobReferenceUploadAdapterPlugin","editor","plugins","createUploadAdapter","HtmlEditor","setKey","trackedValue","current","DecoupledEditor","config","extraPlugins","event","getData","onReady","ui","getEditableElement","parentElement","insertBefore","toolbar","DailyMotionProvider","format","urls","FacebookProvider","FlickrProvider","GoogleMapsProvider","InstagramProvider","SpotifyProvider","TwitterProvider","VimeoProvider","YouTubeProvider","FetchOmbed","_providers","pattern","regExp","match","getProvider","fetchJsonp","escape","elements","tagName","getElementsByTagName","service","theElement","getOEmbedData","html","innerHTML","HtmlDisplay","textOnly","elementRef","setTimeout","processOEmbedElements","ref","dangerouslySetInnerHTML","__html","CardHeaderCollapse","UploadedVideoPreview","poster","onTimeUpdate","playsInline","controls","Feedback","videoBlob","uploadChildBlob","isOpenInitially","uploadVideoBlob","isUploadingVideoBlob","clearVideoBlob","isBlobDropdownOpen","toggleBlobDropdown","maxHeight","overflowY","minTotalScore","maxTotalScore","feedbackText","isEmpty","FeedbackTab","activeAssessmentType","feedbacksManager","childBlobs","validateAssessmentFeedback","assessmentFeedbackValidationErrors","orderedFeedbacks","sort","b","addFeedback","feedbackStyle","values","TrainingModule","DriverMetricRecommendationComponent","driverMetrics","assessmentType","DriverMetricsTab","driverMetricRecommendationsManager","validateDriverMetricRecommendation","driverMetricRecommendationValidationErrors","orderedRecommendations","addRecommendation","QuestionTagButton","isSelected","toggleSelected","gray","readonly","onToggleSelected","QuestionTagSelector","tags","selectedTags","keyDown","tabIndex","onKeyDown","userSelect","QuestionTagsTab","questionTags","linksManager","questionTagId","existing","useBlobReferenceStateArray","blobReferences","setBlobReferences","assessmentItemQuestionFieldsFragment","assessmentItemQuestionDefaultValues","assessmentItemId","questionId","assessmentItemDriverMetricQuantityFieldsFragment","useCreateAssessmentItemQuestionCallback","useUpdateAssessmentItemQuestionCallback","useDeleteAssessmentItemQuestionCallback","useDisplayOrder","managedItems","filterItems","orderedItems","canMoveUp","canMoveDown","moveUp","otherModel","newDisplayOrderMe","moveDown","QuestionType","QuestionTypeCategory","questionTypeDisplayName","MultipleChoiceVideo","SlidingScaleVideo","ResponseTimeVideo","LocationResponseImage","LocationDiscriminationImage","MultipleChoiceImage","Questionnaire","QuestionnaireInput","QuestionnaireScale","QuestionnaireMultipleChoice","LearningVideo","LearningImage","LearningText","SequenceOfQuestions","InformationVideo","InformationImage","InformationText","getQuestionTypeCategory","Question","QuestionnaireQuestion","Learning","Informtion","getQuestionTypes","category","InputSelectOrText","isTextMode","toggleTextMode","setText","lastTextChangeEvent","useRef","saveText","QuestionTagDisplay","useQuestionsListViewModel","questionTypes","links","TagDisplay","SelectQuestionModal","isLoadingQuestions","onClose","questionTypeCategories","initialSelectedIds","isEdit","selectedQuestions","setSelectedQuestions","toggleSelection","closeModal","selectedIds","externalEvent","cancelled","addedIds","removedIds","setSelectedTags","toggleTagSelected","isTagSelected","setFilter","myLinks","driverMetricName","myTags","isTagFilterOpen","toggleTagFilterOpen","Modal","ModalHeader","ModalBody","itemIsSelected","colSpan","ModalFooter","count","SelectQuestionnaireModal","questionTypeCategory","SelectLearningModal","AssessmentItemDriverMetricDisplayQuantityRuleComponent","quantity","AssessmentItemComponent","assessmentItemQuestions","allQuestions","assessmentItemQuestionsManager","assessmentItemDriverMetricQuantitiesManager","validateAssessmentItemDriverMetricQuantity","assessmentItemDriverMetricQuantityErrors","counterbalanceGroups","currentItemDisplayRules","activeQuestionTypeCategory","assessmentItemQuestion","question","addAssessmentItemDriverMetricQuantity","headingText","subheadingText","totalQuantity","Number","isNaN","poolCount","questionNames","questionModalIsOpen","toggleQuestionModal","questionnaireModalIsOpen","toggleQuestionnaireModal","learningModalIsOpen","toggleLearningModal","onQuestionModalClosed","selectedId","unselectedId","onQuestionnaireModalClosed","onLearningModalClosed","RemoveBoth","marginBottom","ListGroup","ListGroupItem","questions","questionnaires","learning","SelectInformationModal","AssessmentItemsTab","assessmentItemsManager","validateAssessmentItem","assessmentItemValidationErrors","canMoveAnswerUp","moveAnswerUp","canMoveAnswerDown","moveAnswerDown","answer","openQuestionModal","openQuestionnaireModal","openLearningModal","informationModalIsOpen","toggleInformationModal","openInformationModal","newAssessmentItemId","onInformationModalClosed","isLearning","safetyMetricText","uniqueUsedSafetyMetrics","assessmentItem","currentQuestion","safetyMetric","driverMetric","easierSafetyMetricList","fontWeight","maxSuspiciousAnswers","suspiciousAnswerText","useCreateAssessmentItemDriverMetricQuantityCallback","useUpdateAssessmentItemDriverMetricQuantityCallback","CreateAssessmentBase","EditAssessmentBase","defaultAssessmentType","useEditAssessmentViewModel","storeFeedbacks","feedbacks","storeQuestionTagLinks","questionTagLinks","storeDriverMetricRecommendations","driverMetricRecommendations","storeDriverMetricAdjustments","driverMetricAdjustments","storeAssessmentItems","assessmentItems","storeAssessmentItemDriverMetricQuantities","assessmentItemDriverMetricQuantities","storeAssessmentItemQuestions","assessmentItemsQuestions","useEditAssessmentSupportingData","isLoadingSupportingData","loadSupportingDataErrors","Assessment","isSmartIndividuality","tileText","creationDate","toISOString","useSaveAssessmentCallback","useSaveAssessmentFeedbackCallback","saveAssessmentFeedback","useDeleteAssessmentFeedbackCallback","removeAssessmentFeedback","questionTagLinksManager","saveQuestionTagLink","removeQuestionTagLink","driverMetricAdjustmentsManager","saveAssessmentDriverMetricAdjustment","removeAssessmentDriverMetricAdjustment","saveAssessmentDriverMetricRecommendation","removeAssessmentDriverMetricRecommendation","useSaveAssessmentItemCallback","saveAssessmentItem","useDeleteAssessmentItemCallback","removeAssessmentItem","useSaveAssessmentItemDriverMetricQuantityCallback","saveAssessmentItemDriverMetricQuantity","useDeleteAssessmentItemDriverMetricQuantityCallback","removeAssessmentItemDriverMetricQuantity","useSaveAssessmentItemQuestionCallback","saveAssessmentItemQuestion","removeAssessmentItemQuestion","setChildBlobs","uploadChildBlobErrors","feedback","videoBlobReference","imageBlobReference","myModel","adjustmentValue","validateDriverMetricAdjustment","driverMetricAdjustmentValidationErrors","activeTab","setActiveTab","active","DeleteAssessmentBase","useAssessment","useDeleteAssessmentCallback","AssessmentsListBase","assessmentTypes","useAssessmentsListViewModel","copyFromAssessmentId","cloneAssessment","useCloneAssessmentCallback","cloneAssessmentErrors","cloned","cloneAndEdit","isCloning","cloneAndEditErrors","date","assessmentRoutes","trainingModuleAssessmentRoutes","QuestionsListBase","questionTypeColumnHidden","questionTypeColumnName","useCreateQuestionCallback","useUpdateQuestionCallback","useDeleteQuestionCallback","questionAnswerFieldsFragment","questionAnswerDefaultValues","answerText","answerTextImageBlobReferenceId","score","isCorrect","startResponseTimeSeconds","endResponseTimeSeconds","scaleImageBlobReferenceId","windowTop","windowLeft","windowBottom","windowRight","discriminationGroup","subQuestionNumber","isSuspicious","suspicionScore","questionFeedbackFieldsFragment","questionSequenceQuestionFieldsFragment","questionSequenceQuestionDefaultValues","parentQuestionId","childQuestionId","VideoTab","isVideoDropdownOpen","toggleVideoDropdown","QuestionAnswerMultipleChoiceVideo","answerTextImageBlob","uploadAnswerTextImageBlob","isUploadingAnswerTextImageBlob","clearAnswerTextImageBlob","isAnswerImageDropdownOpen","toggleAnswerImageDropdown","QuestionPromptMultipleChoiceVideoTab","questionTextImageBlob","uploadQuestionTextImageBlob","isUploadingQuestionTextImageBlob","clearQuestionTextImageBlob","answersManager","validateQuestionAnswer","questionAnswerValidationErrors","orderedAnswers","addAnswer","isQuestionTextImageDropdownOpen","toggleQuestionTextImageDropdown","useCreateQuestionAnswerCallback","useUpdateQuestionAnswerCallback","useDeleteQuestionAnswerCallback","validateQuestionFeedback","questionFeedbackValidationErrors","useCreateQuestionFeedbackCallback","useUpdateQuestionFeedbackCallback","useDeleteQuestionFeedbackCallback","QuestionAnswerSlidingScaleVideo","SlidingScaleSlider","answers","selectedAnswerId","onSelectedAnswerChanged","marks","defaultValue","Math","floor","selectedAnswerIndex","selected","onSelectedAnswerIndexChanged","selectedAnswer","QuestionPromptSlidingScaleVideoTab","timeStringFromSeconds","seconds","minutes","hours","wholeSeconds","milliseconds","padStart","substr","QuestionAnswerResponseTimeVideo","currentVideoTime","startTimeString","endTimeString","QuestionPromptResponseTimeVideoTab","currentTime","activeQuestionType","QuestionAnswerLocationResponseImage","locationString","ResizableOverlay","shapeProps","_isSelected","onSelect","allowTransform","shapeRef","trRef","nodes","getLayer","batchDraw","onDragEnd","x","y","onTransformEnd","scaleX","scaleY","height","textHiddenByAction","setTextHiddenByAction","textHiddenByMouse","setTextHiddenByMouse","textHidden","shape","onTap","draggable","onDragStart","onMouseEnter","onMouseLeave","radiusX","radiusY","align","visible","rotateEnabled","boundBoxFunc","oldBox","newBox","onTransformStart","InteractiveImage","_overlays","overlays","_onOverlayTransformed","onOverlayTransformed","_onAddOverlay","onAddOverlay","allowAdd","addOverlayShapeType","onShapeClicked","onVirtualConversionChanged","divRef","_selectShape","_virtualSize","setVirtualSize","virtualSize","needToCalculateVirtualSize","virtualToDisplay","point","clientWidth","clientHeight","displayToVirtual","selectShape","virtualShapeProps","newDisplaySize","retLocation","retSize","handleOverlayLayerClick","getStage","shapePosition","evt","offsetX","touches","clientX","offsetY","clientY","newShape","forceInitialRefresh","setForceRefreshCount","calculatedHeight","setCalcualtedHeight","handleResize","addEventListener","removeEventListener","backgroundImage","onLoad","naturalWidth","naturalHeight","onMouseDown","onTouchStart","newAttrs","textFromHtml","DOMParser","parseFromString","textContent","responseWindowColors","stroke","fill","QuestionPromptLocationResponseImageTab","isAddingAnswer","toggleAddAnswer","onAnswerAdded","newItem","onAnswerOverlayTransformed","opacity","QuestionAnswerLocationDiscriminationImage","discriminationGroups","discriminationGroupColor","QuestionPromptLocationDiscriminationImageTab","QuestionSequenceQuestionComponent","childQuestion","SequenceOfQuestionsTab","questionSequenceQuestionsManager","isLoadingAllQuestions","ensureAllQuestionsLoaded","orderedQuestions","_toggleQuestionModal","_toggleQuestionnaireModal","useCreateQuestionSequenceQuestionCallback","useUpdateQuestionSequenceQuestionCallback","useDeleteQuestionSequenceQuestionCallback","LearningTextTab","QuestionnaireQuestionAnswerMultipleChoice","SlidingScaleQuestionnaireQuestion","CreateQuestionnaireQuestionModal","questionnaire","parentId","questionnaireQuestionAnswersManager","questionnaireQuestionsManager","cancelSave","newQuestionSequenceQuestion","marginTop","QuestionnaireQuestionSequenceQuestionComponent","parent","questionToRemove","deleteQuestion","SequenceOfQuestionnaireQuestionsTab","newQuestion","emptyQuestion","InformationTextTab","QuestionAnswerMultipleChoiceImage","QuestionPromptMultipleChoiceImageTab","CreateQuestionBase","EditQuestionBase","defaultQuestionType","useEditQuestionViewModel","storeAnswers","storeQuestionnaireQuestionAnswers","questionnaireQuestionAnswers","storeQuestionSequenceQuestions","questionSequenceQuestions","refreshEdit","useEditQuestionSupportingData","useSaveQuestionCallback","setVideoBlob","uploadVideoBlobErrors","setQuestionTextImageBlob","uploadQuestionTextImageBlobErrors","questionTextImageBlobReference","answerTextImageBlobReference","scaleImageBlobReference","useSaveQuestionAnswerCallback","saveQuestionAnswer","removeQuestionAnswer","useSaveQuestionFeedbackCallback","saveQuestionFeedback","removeQuestionFeedback","saveQuestionDriverMetricAdjustment","removeQuestionDriverMetricAdjustment","saveQuestionDriverMetricRecommendation","removeQuestionDriverMetricRecommendation","useSaveQuestionSequenceQuestionCallback","saveQuestionQuestionSequenceQuestion","removeQuestionQuestionSequenceQuestion","useQuestions","_allQuestions","loadAllQuestionsErrors","loadAllQuestions","removeQuestionnaireQuestion","isVideoQuestion","isImageQuestion","canHaveFeedback","canHaveDriverMetrics","canHaveAnswers","questionResponseEventFieldsFragment","questionResponseEventDefaultValues","questionAnswerId","assessmentSessionId","cancelEventDate","clickPositionX","clickPositionY","eventDate","responseTimeSeconds","textInput","useDeleteQuestionResponseEventCallback","DeleteQuestionBase","useQuestionLinksViewModel","assessmentLinks","responseEvents","removeQuestionAnswerErrors","removeQuestionFeedbackErrors","removeQuestionTagLinkErrors","removeDriverMetricRecommendation","removeDriverMetricRecommendationErrors","removeDriverMetricAdjustment","removeDriverMetricAdjustmentErrors","removeAssessmentLink","removeAssessmentLinkErrors","removeQuestionResponseEvent","removeQuestionResponseEventErrors","removeQuestionSequenceQuestion","removeQuestionSequenceQuestionErrors","questionRoutes","questionnaireRoutes","learningRoutes","subscriptionAssessmentFieldsFragment","useCreateSubscriptionAssessmentCallback","useUpdateSubscriptionAssessmentCallback","SubscriptionAssessmentsListBase","mobileColumn1Name","isDistributorSubscription","isStudy","lowerSubscriptionId","selectedItems","assessments","useSubscriptionAssessmentsListViewBaseViewModel","storeSubscriptionAssessments","currentAssessments","setCurrentAssessments","subscriptionAsssessmentsManager","useSaveSubscriptionAssessmentCallback","saveSubscriptionAssessment","useDeleteSubscriptionAssessmentCallback","removeSubscriptionAssessment","saveAllSubscriptionAssessments","saveAllSubscriptionAssessmentsDebounced","useDebouncedCallback","toggleSubscriptionAssessment","subscriptionToUse","maxRestarts","isSubscriptionAssessmentSelected","isSubscriptionAssessmentSelectedByDistributor","currentAssessmentCount","assessmentLimit","pluraliseOrNot","subscriptionAsssessment","subscriptionAssessmentRoutes","subscriptionTrainingModuleAssessmentRoutes","userAssessmentAssignmentFieldsFragment","userAssessmentAssignmentDefaultValues","targetDate","add","assessmentSessionFieldsFragment","ScoreProgressBar","riskName","riskCategory","questionScoreFromNumber","DueDateLabel","dueDate","completedDate","now","dueSoonDateIso","dueDateIso","DashboardAssessmentCard","assessment","assignment","session","canRetake","DateLabelComponent","endDate","isFinished","totalScore","MeDashboard","profileIdParam","profileId","useMeDashboardViewModel","viewModel","userAssessmentAssignments","assessmentSessions","isStudyParticipant","assessmentsCount","trainingCount","getAssessmentSummary","mySessions","completionCount","startedCount","startDate","maxRestartCount","isEverFinished","isLatestFinished","generateCards","isUndefined","includeIfEverFinishedIs","includeIfLatestFinishedIs","latestSession","latestFinishedSession","displayInline","generateHistoryCards","latestSessions","CardGroup","meRoutes","UsersListBase","filterByRoleGroups","roleGroupColumnHidden","teamColumnHidden","allowImport","subscriptionUserCount","setSubscriptionUserCount","maxUserCount","setMaxUserCount","roleGroup","CardSubtitle","myTeam","useProfileSupportingData","DeleteUserBase","defaultRoleGroup","isDriver","useChangeUserRoleGroupCallback","resetCurrentUserRoles","useResetCurrentUserRolesCallback","DriverNavigation","ManagerNavigation","AdministratorNavigation","CreateUserBase","EditUserBase","filterRoleGroups","userModel","changeUserModel","roleGroupModel","changeRoleGroupModel","useInviteCallback","inviteErrors","useResendInviteEmailCallback","isResendingInviteEmail","resendInviteEmailErrors","hasResentInviteEmail","setHasResentInviteEmail","currentEmail","useChangeAccountEmailCallback","changeUserRoleGroupInStore","changeUserRoleGroupInStoreErrors","willExceedMaxUsers","setWillExceedMaxUsers","storeRoleGroups","roleGroups","storeSubscriptionTeams","saveSubscription","subscriptionTeamsManager","orderedSubscriptionTeams","isUsingUniqueDriverPin","generateUniqueDriverPin","useGenerateUniqueDriverPinCallback","isGeneratingUniqueDriverPin","generateUniqueDriverPinErrors","driverPinService","emailFromPin","sendEmail","roleGroupId","isManager","isDistributorAdministrator","isAdministrator","administratorsRoutes","manageRoutes","ManageNavigation","SubscriptionTeamNavigation","DriversList","DeleteDriver","CreateDriver","EditDriver","driversRoutes","ManagersList","DeleteManager","CreateManager","EditManager","managersRoutes","useSubscriptionTeam","useCreateSubscriptionTeamCallback","useUpdateSubscriptionTeamCallback","EditSubscriptionTeam","useSaveSubscriptionTeamCallback","subscriptionTeamRoutes","useSubscriptionTeamsListViewModel","userDriverMetricFieldsFragment","useUserAssessmentAssignmentsListViewBaseViewModel","userIdOrEmptyGuid","subscriptionAssessments","userDriverMetrics","useCreateUserAssessmentAssignmentCallback","useUpdateUserAssessmentAssignmentCallback","UserNavigation","ISODateTimeInput","theValue","theFormat","valueMoment","isValid","onChangeWrapper","newValueMoment","newValue","utc","newEvent","UserAssessmentAssignmentsListBase","_profile","storeUserAssessmentAssignments","baseRouteSolver","userAssessmentAssignmentsManager","useSaveUserAssessmentAssignmentCallback","saveUserAssessmentAssignment","useDeleteUserAssessmentAssignmentCallback","removeUserAssessmentAssignment","saveAllUserAssessmentAssignments","saveAllUserAssessmentAssignmentsDebounced","userAssessmentAssignment","allowed","currentAssignment","validateUserAssessmentAssignments","toggleUserAssessmentAssignment","defaultRestarts","isUserAssessmentAssignmentSelected","useSendAssessmentReminderCallback","remind","useSendAllAssessmentReminderCallback","remindAll","handleRemindButton","generateRecommendationReasons","myRules","rule","metric","userMetric","currentValue","userAssessmentAssignmentErrors","recommendationReasons","reason","UserAssessmentAssignmentsList","userAssessmentAssignmentRoutes","UserAssessmentTrainingModuleAssignmentsList","userTrainingModuleAssessmentAssignmentsRoutes","useCreateAssessmentSessionCallback","useUpdateAssessmentSessionCallback","useCreateQuestionResponseEventCallback","useUpdateQuestionResponseEventCallback","subsitutePlaceholders","subsitutions","keyValue","ShowQuestionFeedback","questionScore","onPageComplete","activeFeedback","imageUrl","videoUrl","feedbackHtml","FinishPage","calculateQuestionScore","exceedsSuspiciousLimit","questionFeedbacks","questionResponseEvents","pages","allCurrentQuestionSequence","finishPageFeedbackStyle","showingFeedbackForQuestion","setShowingFeedbackForQuestion","questionFeedbackModalIsOpen","closeQuestionFeedbackModal","openQuestionFeedbackModal","driverMetricPageGroups","page","pageType","questionnaireQuestions","entry","metricScore","driverMetricBreakdown","groupScore","flush","subQuestionProgressBars","myQuestionnaireQuestions","questionnaireQuestionNumber","questionnaireQuestion","questionBreakdown","fontSize","screenNumber","ShowQuestionLearningImage","ShowQuestionLearningText","ShowQuestionLearningVideo","videoRef","hasVideoStarted","setHasVideoStarted","hasVideoFinished","setHasVideoFinished","startVideo","play","onVideoEnded","disablePictureInPicture","onEnded","ImagePrefetcher","_blobs","cacheRecord","originalUrl","cachedBlobUrl","blobUrl","URL","createObjectURL","revokeObjectURL","usePrefetchImages","imagePrefetcher","isCached","cacheImage","urlFor","useClickSound","useSound","QuestionTimer","secondsRemaining","ShowQuestionLocationDiscriminationImage","addResponseEvent","cancelResponseEvent","questionResponseEventsManager","resetResponseTimeStart","calculateResponseTime","hasFailedMaximumClickRule","isMaximumClickRuleFailtureRecord","endImageBlob","hasActivityStarted","setHasActivityStarted","hasActivityFinished","setHasActivityFinished","endImageUrl","resolveImageUrl","startActivity","onActivityEnded","colorIndex","displayShapeSize","setVirtualConversions","conversions","shapeType","addingShapeForClick","setAddingShapeForClick","discriminationMenuPosition","setDiscriminationMenuPosition","onResponseClickEventStarted","newItemId","newShapeProps","playClickSound","onResponseClickEventFinished","setSecondsRemaining","timer","setInterval","clearInterval","ScoreCard","includeQuestionTimer","pageX","pageY","left","discriminationMenuMaxWidth","top","maxWidth","backgroundColor","borderColor","ShowQuestionLocationResponseImage","onResponseClickEvent","ShowQuestionMultipleChoiceVideo","selectSingleAnswer","onSelectSingleAnswer","answerBlob","ShowQuestionResponseTimeVideo","cancelAllButHighestResponse","isShowingClickIndicator","setIsShowingClickIndicator","ShowQuestionSlidingScaleVideo","selectedAnswerBlob","ShowQuestionnaireMultipleChoice","paddingTop","paddingBottom","ShowQuestionnaireSlidingScale","ShowQuestionnaireInput","currentUserId","setTextInput","addInput","existingAnswers","existingAnswer","ShowQuestionnaireQuestionListComponent","currentQuestionnaire","filteredQuestions","filteredAnswers","myQuestionResponseEvent","selectedQuestionAnswerId","ShowQuestionInformationVideo","ShowQuestionInformationImage","ShowQuestionInformationText","ShowQuestionMultipleChoiceImage","ShowQuestion","assessmentSession","responseTimeStart","setResponseTimeStart","answerSelected","setAnswerSelected","nowMoment","startMoment","diff","savedQuestionnaireForJson","setSavedQuestionnaireForJson","filteredSequenceQuestions","completedResponses","questionnaireJson","savedQuestionnaireResponse","CombinedQuestionScore","textQuestions","maximumClickRuleFailScore","performMaximumClickRule","currentFailRecord","cancelAllButHighestResponseComplete","setCancelAllButHighestResponseComplete","calculateHighestResponseTimeScore","currentResponses","highestScore","reduce","prev","currentResponse","StartPage","responses","combineQuestionScores","scores","calculateAssessmentScore","questionnaireSequenceQuestions","questionScores","currentSequenceQuestions","questionSequence","driverMetricScores","myScore","rawScore","questionPartCount","rawTotalScore","rawRiskCategory","metricTotalScore","isMetricBased","PageProgress","currentPageIndex","pageCount","Progress","currentPage","LaunchAssessmentBase","finishPageOnly","useLaunchAssessmentSessionViewModel","assessmentFeedbacks","questionAnswers","assessmentItemSessionOrders","useLaunchAssessmentSessionSupportingData","supportingDataErrors","useSaveAssessmentSessionCallback","saveAssessmentSession","saveAssessmentSessionErrors","useApplyDriverMetricsForAssessmentSessionCallback","applyDriverMetricsForAssessmentSession","applyDriverMetricsForAssessmentSessionErrors","useSaveQuestionResponseEventCallback","saveQuestionResponseEvent","saveQuestionResponseEventErrors","questionIds","questionItem","fullScreen","finishPage","finishPageIndex","detectBrowser","userAgent","navigator","detectOS","browserData","browser","platform","screenResolution","screen","screenOrientation","orientation","windowResolution","innerWidth","innerHeight","colorDepth","touch","maxTouchPoints","assessmentScore","newPosition","currentPosition","markedSuspicious","browserDataJson","saveEverything","saveEverythingErrors","setCurrentPageIndex","currentAssessmentItem","hasJumpedToInitialPage","setHasJumpedToInitialPage","initialPageIndex","setCanNavigateForwards","canNavigateBack","setCanNavigateBack","navigateBack","newPageIndex","expectedCanNavigateBack","canNavigateForwards","navigateForwards","navigateFinish","furthestTravelled","setFurthestTravelled","StartAssessmentBase","paramUserId","initializeAssessmentSession","useInitializeAssessmentSessionCallback","initializeAssessment","isInitializingAssessment","initializeAssessmentErrors","hasInitializationStarted","setHasInitializationStarted","currentUserAssessmentAssignment","newUserAssessmentAssignment","StartAssessment","assessmentSessionAssessmentRoutes","StartTraining","assessmentSessionTrainingRoutes","getLatestSessions","sessions","existingSession","latestSessionsIncludingIncomplete","generateDashboardSummary","profiles","expandedUserAssessmentAssignments","usedAssessments","usedProfiles","suspiciousAssessments","averageScore","scoreSum","sessionCount","calculateAverageScore","uniqueAssignedAssessmentUserCombinations","started","complete","profileTotalUserMetricScores","myDriverMetrics","myUserDriverMetricTotalScore","totalUserDriverMetricScore","averageUserDriverMetricScore","uniqueSessionsCount","totalFinishedSessionsCount","duplicateSessionsCount","assessmentsText","getNameSummary","suspiciousAssessmentText","usersText","i18next","names","maxNamesToShow","growingNames","useAdministrationDashboardViewModel","useExpandedUserAssessmentAssignments","profilesInTeam","useAverageScoreChartData","getDashboardSummary","generateSeries","seriesName","summary","chartDataConverters","series","dataSeries","labels","shortenText","maxTextLength","toDonut","xaxis","yaxis","toLine","unitOfTime","groupByDate","groupCounts","groupId","startOf","total","toDate","getTime","markers","toDateLine","uniqueTexts","generateSeriesData","categories","maxLength","shortenedIndicator","garChartColours","AverageScoreRadarChart","toRadar","seriesOptions","chart","show","plotOptions","radar","polygons","getSpidergraphBackgroundColors","tooltip","formatter","val","IndividualScoreProgressBar","footer","useCachedDashboardSummaries","calculateDashboardSummary","cachedDashboardSummaries","assessmentSummaryData","trainingSummaryData","cachedData","useDashboardBaseRoute","administrationSubscriptionPrefix","nextSlash","substring","AssessmentProgressDashboardTab","subscriptions","showSubscriptionName","filterByUser","users","getCachedDashboardSummary","averageScoreChartData","isHistoryExpandedFor","toggleHistoryExpandedFor","generateItems","myProfiles","latestCompleteSession","latestSessionIncludingIncomplete","team","isCurrentUser","launchBaseRoute","allMyHistoricCompleteSessions","ListGroupItemHeading","ListGroupItemText","DashboardBackButton","useDashboardRequiresBackButton","AdministrationAssessmentDashboard","allProfiles","allAssessments","allAssmentSessions","allUserAssessmentAssignments","allUserDriverMetrics","sessionFilter","assignmentFilter","myAssignments","myUserDriverMetrics","udm","_generateDashboardSummary","activeDashboardRiskCategoryFilterState","useActiveDashboardRiskCategoryFilter","useAverageDriverMetricRiskChartData","getUserMetricSummary","summaries","useCompletionChartData","getValue","AverageDriverMetricRiskDonutChart","dataLabels","enabled","w","seriesIndex","legend","position","pie","donut","CompletionBarChart","toColumn","stacked","AverageScoreProgressBar","AssessmentAverageScoreProgressBar","TrainingAverageScoreProgressBar","DashboardListGroupItem","hideAssessments","hideTraining","hideSuspicious","seatExportHref","progressType","assessmentsSummary","trainingSummary","marginLeft","OverallRiskFilterListGroupItem","riskCategoryFilter","setRiskCategoryFilter","SubscriptionsDashboardTab","changeTab","subscriptionsAndEsitu","filterBySubscription","averageDriverMetricRiskChartData","completionChartData","filterdSubscriptionsAndEsitu","padding","UsersDashboardTab","linkToFolder","filterdUsers","averageScoreRiskChartData","EsituStaffDashboardTab","staffProfiles","SubscriptionTeamsDashboardTab","filterByTeam","filteredSubscriptionTeams","SubscriptionUsersDashboardTab","nonStaffProfiles","AssessmentsDashboardTabBase","_activeAssessmentType","mySubscriptionId","filterByAssessment","filterdAssessments","AssessmentsDashboardTab","TrainingDashboardTab","activeDashboardAssessmentTypeState","useActiveDashboardAssessmentType","activeDashboardTabState","useActiveDashboardTab","dashboard","array","setArray","myDashboard","Function","myPrevState","DistributorDashboardListGroupItem","distributorSummary","subscriptionAssessmentAssignment","currentDistributorSubscriptions","distributorUserAssignments","distributorAssignedAssessments","assessmentAssignmentCounts","AssessmentId","totalSubscriptionsCount","distributorUserAssessmentAssignmentCount","distributorUserTrainingAssignmentCount","filteredAssessments","assessmentAssignments","DistributorSubscriptionsText","generateDistributorDashboardSummary","distributorAssessments","distributorTraining","DistributorsDashboardTab","distributors","chartColors","DriverMetricsRadarChart","DriverScoreProgressBarAsChart","userDriveMetric","UserProgressDashboardTab","driverMetricsChartData","totalValue","previousValue","useDriverMetricsChartData","myAssessments","StaffUserDashboard","userIdProp","userIdParam","setActiveAssessmentType","useSubscriptionDashboardViewModel","SubscriptionUserDashboard","subscriptionIdParam","MyDashboard","ExportAssessmentResults","assessmentsWithSessions","assessmentToUse","setAssessmentToUse","setFilterByTeam","subscriptionTeamToUse","setSubscriptionTeamToUse","isDetailed","setisDetailed","includeDeviceMetrics","setIncludeDeviceMetrics","pickAssessment","pickedAssessment","exportToUse","pickSubscriptionTeam","pickedSubscriptionTeam","SubscriptionDashboard","riskRule","hideAssessmentTypeToggle","SubscriptionAssessmentDashboard","SubscriptionTeamDashboard","allSubscriptionTeams","dashboardRoutes","justifyContent","tabName","ImportUsersBase","subscriptionTeamIdParam","roleGroupParam","setSubscriptionTeamId","_roleGroup","setRoleGroup","uploadBlobErrors","importUsers","useImportUsersCallback","importUsersErrors","importUsersResults","setImportUsersResults","blobId","results","successful","performUserImport","isImportingUsers","performUserImportErrors","rowNumber","ImportDrivers","ImportManagers","importUsersRoutes","importUserAssessmentAssignments","useImportUserAssessmentAssignmentsCallback","importUserAssessmentAssignmentsErrors","importUserAssessmentAssignmentsResults","setImportUserAssessmentAssignmentsResults","performUserAssessmentAssignmentImport","isImportingUserAssessmentAssignments","performUserAssessmentAssignmentImportErrors","informationRoutes","DistributorAdministrationNavigation","DistributorSubscriptionsDashboardTab","filteredSubscriptions","filteredSubscriptionsAndEsitu","distributorRoutes","currentDistributorsSubscriptions","currentSubscription","sdkClientFieldsFragment","useSdkClient","useCreateSdkClientCallback","useUpdateSdkClientCallback","useJsonObject","onJsonChanged","parse","setValue","valueToStore","newJson","SecretInput","valueWhenHidden","_onClick","isVisible","toggleIsVisible","uniqueId","copiedTooltipIsOpen","toggleCopiedTooltipOpen","copyToClipboard","clipboard","writeText","Tooltip","placement","ApiKeyGenerationService","_applicationPrefix","_secretLength","generateSecret","allChars","random","EditSdkClient","apiSecret","ipAllowListJson","rolesJson","useSaveSdkClientCallback","secret","generateKey","ipAddresses","setIpAddresses","_","sdkWebhookFieldsFragment","SdkClientsTable","SdkWebhooksTable","sdkClients","client","sdkClientId","eventsJson","headersJson","useSdkWebhook","useEditSdkWebhookSupportingData","HttpMethod","useCreateSdkWebhookCallback","useUpdateSdkWebhookCallback","WebhookEventTypeButton","eventType","WebhookEventTypeSelector","eventTypes","selectedEventTypes","sdkWebhookEventTypes","dataObject","EditSdkWebhook","httpMethod","useSaveSdkWebhookCallback","setHeaders","setSelectedEventTypes","myDataObject","myKeys","eventData","queryString","sampleJson","sampleQueryString","Post","Put","sdkRoutes","useSdkOverviewViewModel","sdkWebhooks","useDeleteSdkClientCallback","useDeleteSdkWebhookCallback","sdkClient","cmsPageRoutes","scrollTo","LowerAlphaList","listItems","alphaCharacters","rowSpan","StudyAdministrationNavigation","studyRoutes","studyId","useStudyAdministrationDashboardViewModel","StudyLogin","useStudyLoginCallback","studyUniqueCodeParam","userIdentifierParam","uniqueIdentifierDefault","userIdentifier","performStudyLogin","autoLoginStarted","setAutoLoginStarted","studyAccountRoutes","useStudyLogoutCallback","studyLogoutErrors","attemptedLogout","setAttemptedLogout","appRoutes","sidebarRoutes","Sidebar","Layout","fallback","configureIcons","library","faBook","faBuilding","faBus","faCarCrash","faCaretUp","faCaretDown","faCaretLeft","faCaretRight","faChalkboardTeacher","faCheck","faCheckCircle","faChevronLeft","faChevronRight","faClipboardCheck","faClone","faCloudDownloadAlt","faCode","faCogs","faCommentDots","faCopy","faCreditCard","faCross","faDesktop","faDice","faDownload","faEdit","faExclamationCircle","faExclamationTriangle","faEye","faEyeSlash","faFileAlt","faFlagCheckered","faFolderMinus","faGraduationCap","faHistory","faHome","faIdCardAlt","faInfo","faLink","faLock","faMeh","faMinus","faPen","faPersonBooth","faPhotoVideo","faPlay","faPlayCircle","faPlus","faPoundSign","faProjectDiagram","faRuler","faSave","faSchool","faSearch","faShippingFast","faSolarPanel","faSpinner","faStop","faStopwatch","faSync","faTachometerAlt","faTag","faTags","faTerminal","faThLarge","faThList","faThumbsDown","faThumbsUp","faTicketAlt","faTimes","faTimesCircle","faTrash","faTrashAlt","faTrashRestore","faUndo","faUpload","faUser","faUserCheck","faUserClock","faUsersCog","faUserGraduate","faUserTag","faUsers","faUserShield","faVideo","faVoteYea","faWindowRestore","farCalendarAlt","farCalendarTimes","farCircle","farClock","farFrown","farFrownOpen","farListAlt","farSmile","faPhone","faEnvelope","cache","InMemoryCache","apolloCachePersistor","CachePersistor","storage","localStorage","restore","HttpLink","uri","apolloClient","ApolloClient","availableLanguages","flagCountryCode","momentLocale","numeralLocale","localeResources","en","translation","SubscriptionStyleOverrides","useSubscriptionStyleOverridesViewModel","logoUrl","shadeBlend","hoverColor","p","c0","c1","n","u","f","split","R","slice","G","B","R1","G1","B1","serviceProvider","ServiceProvider","builder","singleton","removeItem","purgeRecoilPersist","purge","use","LanguageDetector","initReactI18next","fallbackLng","resources","interpolation","escapeValue","Date","isMoment","isNumber","numeral","on","languageCode","thisLanguage","indexOfDash","shortCode","findLanguage","locale","shouldHandle","graphQLErrors","externalProviderError","subStr","App","I18nextProvider","Provider","ApolloProvider","defaultTitle","titleTemplate","isLocalhost","Boolean","registerValidSW","swUrl","serviceWorker","registration","onupdatefound","installingWorker","installing","onstatechange","controller","catch","reportWebVitals","onPerfEntry","getCLS","getFID","getFCP","getLCP","getTTFB","baseUrl","rootElement","getElementById","ReactDOM","basename","process","ready","unregister","reload","checkValidServiceWorker","registerServiceWorker"],"mappings":"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","file":"static/js/main.c9f5c543.chunk.js","sourcesContent":["export const apiAuthorizationConfig = {\r\n endpoint: '/',\r\n applicationName: 'EsituDrive',\r\n};","import { UserManager, WebStorageStateStore, User, Profile } from \"oidc-client\";\r\nimport { apiAuthorizationConfig } from \"../../configure/apiAuthorizationConfig\";\r\n\r\nexport interface AuthenticationResult {\r\n status: string,\r\n message?: string,\r\n state?: any,\r\n}\r\n\r\nexport class AuthorizeService {\r\n // By default pop ups are disabled because they don't work properly on Edge.\r\n // If you want to enable pop up authentication simply set this flag to false.\r\n _popUpDisabled = true;\r\n\r\n _callbacks: Array<{ callback: () => void, subscription: number }>;\r\n _nextSubscriptionId: number;\r\n _user: User | null;\r\n _isAuthenticated = false;\r\n _userManager: UserManager | undefined;\r\n\r\n\r\n\r\n constructor() {\r\n this._callbacks = [];\r\n this._nextSubscriptionId = 0;\r\n this._user = null;\r\n this._isAuthenticated = false;\r\n this._userManager = undefined;\r\n }\r\n\r\n async isAuthenticated(): Promise {\r\n const user = await this.getUser();\r\n return !!user;\r\n }\r\n\r\n async getUser(): Promise {\r\n let user = this._user;\r\n\r\n if (user && user.profile) {\r\n return user.profile;\r\n }\r\n\r\n const userManager = await this.ensureUserManagerInitialized();\r\n if (!userManager) {\r\n return null;\r\n }\r\n\r\n user = await userManager.getUser();\r\n return user?.profile ?? null;\r\n }\r\n\r\n async getAccessToken(): Promise {\r\n const userManager = await this.ensureUserManagerInitialized();\r\n if (!userManager) {\r\n return null;\r\n }\r\n\r\n const user = await userManager.getUser();\r\n return user?.access_token ?? null;\r\n }\r\n\r\n // We try to authenticate the user in three different ways:\r\n // 1) We try to see if we can authenticate the user silently. This happens\r\n // when the user is already logged in on the IdP and is done using a hidden iframe\r\n // on the client.\r\n // 2) We try to authenticate the user using a PopUp Window. This might fail if there is a\r\n // Pop-Up blocker or the user has disabled PopUps.\r\n // 3) If the two methods above fail, we redirect the browser to the IdP to perform a traditional\r\n // redirect flow.\r\n async signIn(state: any): Promise {\r\n const userManager = await this.ensureUserManagerInitialized();\r\n if (!userManager) {\r\n return this.error(\"User manager not available.\");\r\n }\r\n\r\n try {\r\n const silentUser = await userManager.signinSilent(this.createArguments());\r\n this.updateState(silentUser);\r\n return this.success(state);\r\n } catch (silentError: any) {\r\n // User might not be authenticated, fallback to popup authentication\r\n console.log(\"Silent authentication error: \", silentError);\r\n\r\n try {\r\n if (this._popUpDisabled) {\r\n throw new Error('Popup disabled. Change \\'AuthorizeService.js:AuthorizeService._popupDisabled\\' to false to enable it.')\r\n }\r\n\r\n const popUpUser = await userManager.signinPopup(this.createArguments());\r\n this.updateState(popUpUser);\r\n return this.success(state);\r\n } catch (popUpError: any) {\r\n if (popUpError.message === \"Popup window closed\") { // eslint-disable-line @typescript-eslint/no-unsafe-member-access\r\n // The user explicitly cancelled the login action by closing an opened popup.\r\n return this.error(\"The user closed the window.\");\r\n } else if (!this._popUpDisabled) {\r\n console.log(\"Popup authentication error: \", popUpError);\r\n }\r\n\r\n // PopUps might be blocked by the user, fallback to redirect\r\n try {\r\n await userManager.signinRedirect(this.createArguments(state));\r\n return this.redirect();\r\n } catch (redirectError: any) {\r\n console.log(\"Redirect authentication error: \", redirectError);\r\n return this.error(redirectError);\r\n }\r\n }\r\n }\r\n }\r\n\r\n async completeSignIn(url: string): Promise {\r\n try {\r\n const userManager = await this.ensureUserManagerInitialized();\r\n if (!userManager) {\r\n return this.error('There was an error signing in.');\r\n }\r\n\r\n const user = await userManager.signinCallback(url);\r\n this.updateState(user);\r\n return this.success(user?.state);\r\n } catch (error: any) {\r\n console.log('There was an error signing in: ', error);\r\n return this.error('There was an error signing in.');\r\n }\r\n }\r\n\r\n // We try to sign out the user in two different ways:\r\n // 1) We try to do a sign-out using a PopUp Window. This might fail if there is a\r\n // Pop-Up blocker or the user has disabled PopUps.\r\n // 2) If the method above fails, we redirect the browser to the IdP to perform a traditional\r\n // post logout redirect flow.\r\n async signOut(state: any) {\r\n const userManager = await this.ensureUserManagerInitialized();\r\n if (!userManager) {\r\n return this.error(\"User manager not available.\");\r\n }\r\n\r\n try {\r\n if (this._popUpDisabled) {\r\n throw new Error('Popup disabled. Change \\'AuthorizeService.ts:AuthorizeService._popupDisabled\\' to false to enable it.')\r\n }\r\n\r\n await userManager.signoutPopup(this.createArguments());\r\n this.updateState(null);\r\n return this.success(state);\r\n } catch (popupSignOutError: any) {\r\n console.log(\"Popup signout error: \", popupSignOutError);\r\n try {\r\n await userManager.signoutRedirect(this.createArguments(state));\r\n return this.redirect();\r\n } catch (redirectSignOutError: any) {\r\n console.log(\"Redirect signout error: \", redirectSignOutError);\r\n return this.error(redirectSignOutError);\r\n }\r\n }\r\n }\r\n\r\n async completeSignOut(url: string) {\r\n const userManager = await this.ensureUserManagerInitialized();\r\n if (!userManager) {\r\n return this.error(\"User manager not available.\");\r\n }\r\n\r\n try {\r\n const response = await userManager.signoutCallback(url);\r\n this.updateState(null);\r\n return this.success(response?.state);\r\n } catch (error: any) {\r\n console.log(`There was an error trying to log out '${error}'.`);\r\n return this.error(error);\r\n }\r\n }\r\n\r\n updateState(user: User | null) {\r\n this._user = user;\r\n this._isAuthenticated = !!this._user;\r\n this.notifySubscribers();\r\n }\r\n\r\n subscribe(callback: () => void): number {\r\n this._callbacks.push({ callback, subscription: this._nextSubscriptionId++ });\r\n return this._nextSubscriptionId - 1;\r\n }\r\n\r\n unsubscribe(subscriptionId: number) {\r\n const subscriptionIndex = this._callbacks\r\n .map((element, index) => element.subscription === subscriptionId ? { found: true, index } : { found: false })\r\n .filter(element => element.found === true);\r\n if (subscriptionIndex.length === 1) {\r\n this._callbacks = this._callbacks.splice(subscriptionIndex[0].index!, 1);\r\n } else {\r\n //throw new Error(`Found an invalid number of subscriptions ${subscriptionIndex.length}`);\r\n }\r\n }\r\n\r\n notifySubscribers() {\r\n for (const callbackEntry of this._callbacks) {\r\n const callback = callbackEntry.callback;\r\n callback();\r\n }\r\n }\r\n\r\n createArguments(state?: any) {\r\n return { useReplaceToNavigate: true, data: state };\r\n }\r\n\r\n error(message: string): AuthenticationResult {\r\n return { status: AuthenticationResultStatus.Fail, message };\r\n }\r\n\r\n success(state: any): AuthenticationResult {\r\n return { status: AuthenticationResultStatus.Success, state };\r\n }\r\n\r\n redirect(): AuthenticationResult {\r\n return { status: AuthenticationResultStatus.Redirect };\r\n }\r\n\r\n async ensureUserManagerInitialized(): Promise {\r\n if (this._userManager !== undefined) {\r\n return this._userManager;\r\n }\r\n\r\n let response: Response;\r\n try {\r\n response = await fetch(`${apiAuthorizationConfig.endpoint}_configuration/${apiAuthorizationConfig.applicationName}`);\r\n if (!response.ok) {\r\n //throw new Error(`Could not load settings for '${window.location.hostname.toLowerCase()}'`);\r\n console.error(`Could not load settings for '${window.location.hostname.toLowerCase()}'`);\r\n return null;\r\n }\r\n } catch (error) {\r\n console.error(`Could not load settings for '${window.location.hostname.toLowerCase()}'`);\r\n return null;\r\n }\r\n\r\n\r\n const settings: { automaticSilentRenew: boolean, includeIdTokenInSilentRenew: boolean, userStore: WebStorageStateStore } = await response.json();\r\n settings.automaticSilentRenew = true;\r\n settings.includeIdTokenInSilentRenew = true;\r\n settings.userStore = new WebStorageStateStore({\r\n prefix: apiAuthorizationConfig.applicationName\r\n });\r\n\r\n this._userManager = new UserManager(settings);\r\n\r\n this._userManager.events.addUserSignedOut(async () => {\r\n await (this._userManager!).removeUser();\r\n this.updateState(null);\r\n });\r\n\r\n return this._userManager;\r\n }\r\n\r\n static get instance() { return authService }\r\n}\r\n\r\nconst authService = new AuthorizeService();\r\n\r\nexport default authService;\r\n\r\nexport const AuthenticationResultStatus = {\r\n Redirect: 'redirect',\r\n Success: 'success',\r\n Fail: 'fail'\r\n};\r\n","import authService, { AuthorizeService } from './AuthorizeService';\r\n\r\n/**\r\n * Hook to return the authentication service.\r\n */\r\nexport function useAuthorizeService(): AuthorizeService {\r\n return authService;\r\n}\r\n","import * as React from 'react';\r\nimport { useAuthorizeService } from './useAuthorizeService';\r\nimport { Profile } from 'oidc-client';\r\n\r\nexport interface UseAuthenticationStateOptions {\r\n /**\r\n * By default we don't load the user details as they are often unused and require extra loading. When this is set to true we'll load the user record and return it as well.\r\n */\r\n includeUser?: boolean,\r\n}\r\n\r\n/**\r\n * Hook to return the authenticated state of the user. The hook subscribes to authenticate changes by authService and will update the state in components whenever that changes.\r\n * @param onStateChanged\r\n */\r\nexport function useAuthenticatedState(options: UseAuthenticationStateOptions = {}): { isAuthenticated: boolean | null, user: Profile | null } {\r\n const authService = useAuthorizeService();\r\n const [isAuthenticated, setIsAuthenticated] = React.useState(null);\r\n const [user, setUser] = React.useState(null);\r\n\r\n const stateChanged = React.useCallback(async () => {\r\n const authenticated = await authService.isAuthenticated();\r\n\r\n let userResult: Profile | null = null;\r\n if (options.includeUser) {\r\n userResult = await authService.getUser();\r\n setUser(userResult);\r\n }\r\n\r\n setIsAuthenticated(authenticated);\r\n }, [authService, options.includeUser]);\r\n\r\n // Subscribe to changes to the authService state.\r\n React.useEffect(() => {\r\n const subscription = authService.subscribe(() => { stateChanged(); });\r\n stateChanged();\r\n return () => { authService.unsubscribe(subscription); };\r\n }, [authService, stateChanged]);\r\n\r\n return { isAuthenticated: isAuthenticated, user: user };\r\n}\r\n","import './userNav.scss';\r\n\r\nimport * as React from 'react';\r\nimport { DropdownToggle, DropdownMenu, DropdownItem, Dropdown, NavItem, Button } from 'reactstrap';\r\nimport Avatar from 'react-avatar';\r\nimport { FontAwesomeIcon } from '@fortawesome/react-fontawesome';\r\nimport { LinkContainer } from 'react-router-bootstrap';\r\nimport { useAuthenticatedState } from '../../api/api-authorization/useAuthenticatedState';\r\nimport { useTranslation } from 'react-i18next';\r\nimport { useToggleState } from 'use-toggle-state';\r\n\r\n/**\r\n * Navbar area that is for the current user. \r\n */\r\nexport const UserNav = () => {\r\n const { isAuthenticated, user } = useAuthenticatedState({ includeUser: true });\r\n const [dropdownOpen, toggleDropdown] = useToggleState();\r\n\r\n const { t } = useTranslation();\r\n\r\n // Render the UI\r\n //\r\n\r\n // If the user is not logged in, then give them the login and register options.\r\n if (!isAuthenticated) {\r\n return (\r\n <>\r\n {/*\r\n \r\n \r\n \r\n */}\r\n \r\n \r\n \r\n \r\n \r\n \r\n );\r\n }\r\n\r\n // User is logged in so show their options.\r\n return (\r\n toggleDropdown()} nav>\r\n \r\n \r\n \r\n {user?.name ?? ''}\r\n \r\n \r\n \r\n {t('userNav.account', 'Account')}\r\n \r\n \r\n \r\n <> {t('userNav.profile', 'Profile')}\r\n \r\n \r\n \r\n \r\n \r\n \r\n <> {t('userNav.signOut', 'Sign out')}\r\n \r\n \r\n \r\n \r\n );\r\n};\r\n","import { ApiFetch } from \"apifetch-json\";\r\n\r\n/**\r\n * Class that provides a service for managing an account on the server.\r\n * \r\n * NOTE: not to be confused with AuthoriazationService which manages the authorised state of the current user.\r\n * \r\n * The login() and logout() method here are usually invoked through components used by AuthorizationService's routing to share the authorisation state with the server.\r\n */\r\nexport class AccountService {\r\n api: ApiFetch;\r\n\r\n constructor(api?: ApiFetch) {\r\n this.api = api ?? new ApiFetch();\r\n }\r\n\r\n /**\r\n * Attempt to login to the account with an email and password.\r\n */\r\n loginWithPassword = async (request: LoginWithPasswordRequest, returnUrl: string = ''): Promise => {\r\n const result = await this.api.post(\r\n `/api/account/login?returnUrl=${encodeURIComponent(returnUrl ?? '')}`,\r\n request,\r\n {\r\n credentials: 'include',\r\n });\r\n\r\n return result;\r\n }\r\n\r\n /**\r\n * Register the user with a new password based account.\r\n */\r\n register = async (request: RegisterRequest, returnUrl: string = ''): Promise => {\r\n const result = await this.api.post(\r\n `/api/account/register?returnUrl=${encodeURIComponent(returnUrl || defaultRegisterReturnUrl)}`,\r\n request,\r\n {\r\n credentials: 'include'\r\n });\r\n\r\n return result;\r\n }\r\n\r\n /**\r\n * Get a list of all external authentication schemes registered for use with accounts on this server.\r\n */\r\n getExternalAuthenticationSchemes = async (): Promise> => {\r\n const result = await this.api.get>('/api/account/getExternalAuthenticationSchemes');\r\n return result;\r\n }\r\n\r\n /**\r\n * Start the process of logging in with an external provider.\r\n */\r\n startExternalLogin = (provider: string, returnUrl: string = '') => {\r\n // We want to post the whole page to the action as it needs to return a redirect. To acheive this we create and post a form.\r\n let form = document.createElement('form');\r\n form.action = `/api/account/startExternalLogin?provider=${encodeURIComponent(provider)}&returnUrl=${encodeURIComponent(returnUrl ?? '')}`;\r\n form.method = 'post';\r\n document.body.append(form);\r\n form.submit();\r\n }\r\n\r\n /**\r\n * Complete the external login process.\r\n */\r\n completeExternalLogin = async (returnUrl: string = '', remoteError: string = '') => {\r\n const result = await this.api.get(`/api/account/completeExternalLogin?returnUrl=${encodeURIComponent(returnUrl ?? '')}&remoteError=${encodeURIComponent(remoteError ?? '')}`);\r\n return result;\r\n }\r\n\r\n /**\r\n * Creates an account linked to the current external login with the additional details passed in.\r\n */\r\n createAccountForExternalLogin = async (model: CreateExternalLoginAccountDetails, returnUrl: string = ''): Promise => {\r\n const result = await this.api.post(\r\n `/api/account/createAccountForExternalLogin?returnUrl=${encodeURIComponent(returnUrl ?? '')}`,\r\n model,\r\n {\r\n credentials: 'include'\r\n });\r\n return result;\r\n }\r\n\r\n /**\r\n * Send a password reset email.\r\n */\r\n sendPasswordResetEmail = async (email: string) => {\r\n const result = await this.api.post(`/api/account/sendPasswordResetEmail`, { email: email });\r\n return result;\r\n }\r\n\r\n /**\r\n * Reset password (using an emailed code as varification).\r\n */\r\n resetPassword = async (model: ResetPasswordRequest) => {\r\n const result = await this.api.post(`/api/account/resetPassword`, model);\r\n return result;\r\n }\r\n\r\n /**\r\n * Confirm email (using an emailed code as varification).\r\n */\r\n confirmEmail = async (model: ConfirmEmailRequest) => {\r\n const result = await this.api.post(`/api/account/confirmEmail`, model);\r\n return result;\r\n }\r\n\r\n /**\r\n * Confirm email change (using an emailed code as varification).\r\n */\r\n confirmEmailChange = async (model: ConfirmEmailChangeRequest) => {\r\n const result = await this.api.post(\r\n `/api/account/confirmEmailChange`,\r\n model,\r\n {\r\n credentials: 'include'\r\n });\r\n return result;\r\n }\r\n\r\n /**\r\n * Returns the IdentityRoles names of the current user.\r\n */\r\n currentUserRoles = async (): Promise => {\r\n const result = await this.api.get(\r\n '/api/account/currentUserRoles',\r\n {\r\n credentials: 'include'\r\n });\r\n\r\n return result;\r\n }\r\n\r\n /**\r\n * Change password of the logged in user.\r\n */\r\n changePassword = async (model: ChangePasswordRequest) => {\r\n const result = await this.api.post(\r\n `/api/account/changePassword`,\r\n model,\r\n {\r\n credentials: 'include'\r\n });\r\n return result;\r\n }\r\n\r\n /**\r\n * Change email of the logged in user.\r\n */\r\n changeEmail = async (model: ChangeEmailRequest) => {\r\n const result = await this.api.post(\r\n `/api/account/changeEmail`,\r\n model,\r\n {\r\n credentials: 'include'\r\n });\r\n return result;\r\n }\r\n\r\n /**\r\n * Resent the email verification email.\r\n */\r\n resendConfirmEmail = async (email: string) => {\r\n const result = await this.api.post(\r\n `/api/account/resendConfirmEmail`,\r\n { email: email }\r\n );\r\n return result;\r\n }\r\n\r\n\r\n /**\r\n * Change email of the logged in user.\r\n */\r\n invite = async (model: InviteRequest) => {\r\n const result = await this.api.post(\r\n `/api/account/invite`,\r\n model,\r\n {\r\n credentials: 'include'\r\n }\r\n );\r\n return result;\r\n }\r\n\r\n /**\r\n * Resent the invite email.\r\n */\r\n resendInviteEmail = async (email: string) => {\r\n const result = await this.api.post(\r\n `/api/account/resendInviteEmail`,\r\n { email: email }\r\n );\r\n return result;\r\n }\r\n\r\n /**\r\n * Confirm an invite and set a password (will also perform a login).\r\n */\r\n confirmInvite = async (model: ConfirmInviteRequest, returnUrl: string = '') => {\r\n const result = await this.api.post(\r\n `/api/account/confirmInvite?returnUrl=${encodeURIComponent(returnUrl || defaultRegisterReturnUrl)}`,\r\n model\r\n );\r\n return result;\r\n }\r\n\r\n /**\r\n * Change email of another user (as an administrator)\r\n */\r\n changeAccountEmail = async (model: ChangeAccountEmailRequest) => {\r\n const result = await this.api.post(\r\n `/api/account/changeAccountEmail`,\r\n model,\r\n {\r\n credentials: 'include'\r\n });\r\n return result;\r\n }\r\n\r\n /**\r\n * Lockout a user.\r\n */\r\n lockout = async (model: LockoutRequest) => {\r\n const result = await this.api.post(\r\n `/api/account/lockout`,\r\n model,\r\n {\r\n credentials: 'include'\r\n }\r\n );\r\n return result;\r\n }\r\n\r\n /**\r\n * Log the user in to a study.\r\n */\r\n studyLogin = async (request: StudyLoginRequest): Promise => {\r\n const result = await this.api.post(\r\n `/api/account/studyLogin`,\r\n request,\r\n {\r\n credentials: 'include',\r\n });\r\n\r\n return result;\r\n }\r\n\r\n /**\r\n * Log the user out of a study.\r\n */\r\n studyLogout = async (request: StudyLogoutRequest): Promise => {\r\n const result = await this.api.post(\r\n `/api/account/studyLogout`,\r\n request,\r\n {\r\n credentials: 'include',\r\n });\r\n\r\n return result;\r\n }\r\n}\r\n\r\nconst defaultRegisterReturnUrl = `/authentication/login?returnUrl=${encodeURIComponent(window.origin + '/')}`;\r\n\r\nexport interface LoginWithPasswordRequest\r\n{\r\n email: string,\r\n password: string,\r\n rememberMe: boolean,\r\n}\r\n\r\nexport interface StudyLoginRequest {\r\n studyUniqueCode: string,\r\n userIdentifier: string,\r\n}\r\n\r\nexport interface StudyLogoutRequest {\r\n assessmentSessionId: string,\r\n}\r\n\r\n\r\nexport interface LoginResult {\r\n succeeded: boolean,\r\n requiresTwoFactor: boolean,\r\n requiresEmailConfirmation: boolean,\r\n returnUrl: string\r\n}\r\n\r\nexport interface RegisterResult extends LoginResult {\r\n userId: string,\r\n}\r\n\r\nexport interface ExternalAuthenticationScheme {\r\n name: string,\r\n displayName: string\r\n}\r\n\r\nexport interface Claim {\r\n type: string,\r\n properties: { [id: string]: string },\r\n originalIssuer: string,\r\n issuer: string,\r\n valueType: string,\r\n value: string,\r\n}\r\n\r\nexport interface CompleteExternalLoginResult {\r\n isNewUser: boolean,\r\n returnUrl: string,\r\n loginProvider: string,\r\n claims: Array,\r\n}\r\n\r\nexport interface CreateExternalLoginAccountDetails {\r\n email: string\r\n}\r\n\r\nexport interface RegisterRequest {\r\n email: string,\r\n password: string,\r\n}\r\n\r\nexport interface ResetPasswordRequest {\r\n userId: string,\r\n code: string,\r\n password: string,\r\n}\r\n\r\nexport interface ConfirmEmailRequest {\r\n userId: string,\r\n code: string,\r\n}\r\n\r\nexport interface CurrentUserRolesResult {\r\n userId: string,\r\n roles: Array,\r\n}\r\n\r\nexport interface ChangePasswordRequest {\r\n currentPassword: string,\r\n newPassword: string,\r\n}\r\n\r\nexport interface ChangeEmailRequest {\r\n newEmail: string,\r\n}\r\n\r\nexport interface ConfirmEmailChangeRequest {\r\n userId: string,\r\n code: string,\r\n email: string,\r\n}\r\n\r\nexport interface InviteRequest {\r\n email: string,\r\n sendEmail: boolean,\r\n}\r\n\r\nexport interface InviteResult {\r\n userId: string,\r\n}\r\n\r\n\r\nexport interface ChangeAccountEmailRequest {\r\n currentEmail: string,\r\n newEmail: string,\r\n}\r\n\r\nexport interface ConfirmInviteRequest {\r\n userId: string,\r\n code: string,\r\n password: string,\r\n}\r\n\r\nexport interface LockoutRequest {\r\n email: string,\r\n endDate?: string,\r\n archive?: boolean,\r\n}\r\n","/**\r\n * URIs of common claim types. \r\n */\r\nexport const ClaimTypes = {\r\n /**\r\n * The URI for a claim that specifies the actor.\r\n */\r\n actor: 'http://schemas.xmlsoap.org/ws/2009/09/identity/claims/actor',\r\n /**\r\n * The URI for a claim that specifies the postal code of an entity.\r\n */\r\n postalCode: 'http://schemas.xmlsoap.org/ws/2005/05/identity/claims/postalcode',\r\n /**\r\n * The URI for a claim that specifies an RSA key.\r\n */\r\n rsa: 'http://schemas.xmlsoap.org/ws/2005/05/identity/claims/rsa',\r\n /**\r\n * The URI for a claim that specifies a security identifier (SID).\r\n */\r\n sid: 'http://schemas.xmlsoap.org/ws/2005/05/identity/claims/sid',\r\n /**\r\n * The URI for a claim that specifies a service principal name (SPN) claim.\r\n */\r\n spn: 'http://schemas.xmlsoap.org/ws/2005/05/identity/claims/spn',\r\n /**\r\n * The URI for a claim that specifies the state or province in which an entity resides.\r\n */\r\n stateOrProvince: 'http://schemas.xmlsoap.org/ws/2005/05/identity/claims/stateorprovince',\r\n /**\r\n * The URI for a claim that specifies the street address of an entity.\r\n */\r\n streetAddress: 'http://schemas.xmlsoap.org/ws/2005/05/identity/claims/streetaddress',\r\n /**\r\n * The URI for a claim that specifies the surname of an entity.\r\n */\r\n surname: 'http://schemas.xmlsoap.org/ws/2005/05/identity/claims/surname',\r\n /**\r\n * The URI for a claim that identifies the system entity.\r\n */\r\n system: 'http://schemas.xmlsoap.org/ws/2005/05/identity/claims/system',\r\n /**\r\n * The URI for a claim that specifies a thumbprint. A thumbprint is a globally unique SHA-1 hash of an X.509 certificate.\r\n */\r\n thumbprint: 'http://schemas.xmlsoap.org/ws/2005/05/identity/claims/thumbprint',\r\n /**\r\n * The URI for a claim that specifies a user principal name (UPN).\r\n */\r\n upn: 'http://schemas.xmlsoap.org/ws/2005/05/identity/claims/upn',\r\n /**\r\n * The URI for a claim that specifies a URI.\r\n */\r\n uri: 'http://schemas.xmlsoap.org/ws/2005/05/identity/claims/uri',\r\n /**\r\n * The URI for a claim that specifies the webpage of an entity.\r\n */\r\n webpage: 'http://schemas.xmlsoap.org/ws/2005/05/identity/claims/webpage',\r\n /**\r\n * The URI for a claim that specifies the alternative phone number of an entity.\r\n */\r\n otherPhone: 'http://schemas.xmlsoap.org/ws/2005/05/identity/claims/otherphone',\r\n /**\r\n * The URI for a claim that specifies the name of an entity.\r\n */\r\n nameIdentifier: 'http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier',\r\n /**\r\n * The URI for a claim that specifies the name of an entity.\r\n */\r\n name: 'http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name',\r\n /**\r\n * The URI for a claim that specifies the mobile phone number of an entity.\r\n */\r\n mobilePhone: 'http://schemas.xmlsoap.org/ws/2005/05/identity/claims/mobilephone',\r\n /**\r\n * The URI for a claim that specifies the anonymous user.\r\n */\r\n anonymous: 'http://schemas.xmlsoap.org/ws/2005/05/identity/claims/anonymous',\r\n /**\r\n * The URI for a claim that specifies details about whether an identity is authenticated.\r\n */\r\n authentication: 'http://schemas.xmlsoap.org/ws/2005/05/identity/claims/authentication',\r\n /**\r\n * The URI for a claim that specifies an authorization decision on an entity.\r\n */\r\n authorizationDecision: 'http://schemas.xmlsoap.org/ws/2005/05/identity/claims/authorizationdecision',\r\n /**\r\n * The URI for a claim that specifies the country/region in which an entity resides,\r\n */\r\n country: 'http://schemas.xmlsoap.org/ws/2005/05/identity/claims/country',\r\n /**\r\n * The URI for a claim that specifies the date of birth of an entity.\r\n */\r\n dateOfBirth: 'http://schemas.xmlsoap.org/ws/2005/05/identity/claims/dateofbirth',\r\n /**\r\n * The URI for a claim that specifies a deny-only security identifier (SID) for\r\n * an entity. A deny-only SID denies the specified entity to a securable object.\r\n */\r\n denyOnlySid: 'http://schemas.xmlsoap.org/ws/2005/05/identity/claims/denyonlysid',\r\n /**\r\n * The URI for a claim that specifies the email address of an entity.\r\n */\r\n email: 'http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress',\r\n /**\r\n * The URI for a claim that specifies the gender of an entity.\r\n */\r\n gender: 'http://schemas.xmlsoap.org/ws/2005/05/identity/claims/gender', \r\n /**\r\n * The URI for a claim that specifies the given name of an entity.\r\n */\r\n givenName: 'http://schemas.xmlsoap.org/ws/2005/05/identity/claims/givenname',\r\n /**\r\n * The URI for a claim that specifies a hash value.\r\n */\r\n hash: 'http://schemas.xmlsoap.org/ws/2005/05/identity/claims/hash',\r\n /**\r\n * The URI for a claim that specifies the home phone number of an entity.\r\n */\r\n homePhone: 'http://schemas.xmlsoap.org/ws/2005/05/identity/claims/homephone',\r\n /**\r\n * The URI for a claim that specifies the locale in which an entity resides.\r\n */\r\n locality: 'http://schemas.xmlsoap.org/ws/2005/05/identity/claims/locality',\r\n /**\r\n * The URI for a claim that specifies the DNS name associated with the computer\r\n * name or with the alternative name of either the subject or issuer of an X.509\r\n * certificate.\r\n */\r\n dns: 'http://schemas.xmlsoap.org/ws/2005/05/identity/claims/dns',\r\n /**\r\n * The URI for an X.500 distinguished name claim, such as the subject of an X.509\r\n * Public Key Certificate or an entry identifier in a directory services Directory\r\n * Information Tree.\r\n */\r\n x500DistinguishedName: 'http://schemas.xmlsoap.org/ws/2005/05/identity/claims/x500distinguishedname',\r\n}\r\n\r\n/**\r\n * URIs of common Microsoft specific claim types. \r\n */\r\nexport const MicrosoftClaimTypes = {\r\n /**\r\n * The URI for a claim that specifies the primary group SID of an entity.\r\n */\r\n primaryGroupSid: 'http://schemas.microsoft.com/ws/2008/06/identity/claims/primarygroupsid',\r\n /**\r\n * The URI for a claim that specifies the primary SID of an entity.\r\n */\r\n primarySid: 'http://schemas.microsoft.com/ws/2008/06/identity/claims/primarysid',\r\n /**\r\n * The URI for a claim that specifies the role of an entity.\r\n */\r\n role: 'http://schemas.microsoft.com/ws/2008/06/identity/claims/role',\r\n /**\r\n * The URI for a claim that specifies a serial number.\r\n */\r\n serialNumber: 'http://schemas.microsoft.com/ws/2008/06/identity/claims/serialnumber',\r\n /**\r\n * The URI for a claim that specifies the user data.\r\n */\r\n userData: 'http://schemas.microsoft.com/ws/2008/06/identity/claims/userdata',\r\n /**\r\n * The URI for a claim that specifies the version.\r\n */\r\n version: 'http://schemas.microsoft.com/ws/2008/06/identity/claims/version',\r\n /**\r\n * The URI for a claim that specifies the Windows domain account name of an entity.\r\n */\r\n windowsAccountName: 'http://schemas.microsoft.com/ws/2008/06/identity/claims/windowsaccountname',\r\n /**\r\n * The URI for a claim that specifies the Windows device.\r\n */\r\n windowsDeviceClaim: 'http://schemas.microsoft.com/ws/2008/06/identity/claims/windowsdeviceclaim',\r\n /**\r\n * The URI for a claim that specifies the Windows group SID of the device.\r\n */\r\n windowsDeviceGroup: 'http://schemas.microsoft.com/ws/2008/06/identity/claims/windowsdevicegroup',\r\n /**\r\n * \r\n */\r\n windowsFqbnVersion: 'http://schemas.microsoft.com/ws/2008/06/identity/claims/windowsfqbnversion',\r\n /**\r\n * \r\n */\r\n windowsSubAuthority: 'http://schemas.microsoft.com/ws/2008/06/identity/claims/windowssubauthority',\r\n /**\r\n * The URI for a claim that specifies the instant at which an entity was authenticated,\r\n */\r\n authenticationInstant: 'http://schemas.microsoft.com/ws/2008/06/identity/claims/authenticationinstant',\r\n /**\r\n * The URI for a claim that specifies the method with which an entity was authenticated,\r\n */\r\n authenticationMethod: 'http://schemas.microsoft.com/ws/2008/06/identity/claims/authenticationmethod',\r\n /**\r\n * The URI for a claim that specifies the cookie path.\r\n */\r\n cookiePath: 'http://schemas.microsoft.com/ws/2008/06/identity/claims/cookiepath',\r\n /**\r\n * The URI for a claim that specifies the deny-only primary group SID on an entity,\r\n * A deny-only SID denies the specified entity to a securable object.\r\n */\r\n denyOnlyPrimaryGroupSid: 'http://schemas.microsoft.com/ws/2008/06/identity/claims/denyonlyprimarygroupsid',\r\n /**\r\n * The URI for a claim that specifies the deny-only primary SID on an entity.\r\n * A deny-only SID denies the specified entity to a securable object.\r\n */\r\n denyOnlyPrimarySid: 'http://schemas.microsoft.com/ws/2008/06/identity/claims/denyonlyprimarysid',\r\n /**\r\n * \r\n */\r\n windowsUserClaim: 'http://schemas.microsoft.com/ws/2008/06/identity/claims/windowsuserclaim',\r\n /**\r\n * The URI for a claim that specifies the Windows deny-only group SID of the device,\r\n */\r\n denyOnlyWindowsDeviceGroup: 'http://schemas.microsoft.com/ws/2008/06/identity/claims/denyonlywindowsdevicegroup',\r\n /**\r\n */\r\n dsa: 'http://schemas.microsoft.com/ws/2008/06/identity/claims/dsa',\r\n /**\r\n * \r\n */\r\n expiration: 'http://schemas.microsoft.com/ws/2008/06/identity/claims/expiration',\r\n /**\r\n * \r\n */\r\n expired: 'http://schemas.microsoft.com/ws/2008/06/identity/claims/expired',\r\n /**\r\n * The URI for a claim that specifies the SID for the group of an entity.\r\n */\r\n groupSid: 'http://schemas.microsoft.com/ws/2008/06/identity/claims/groupsid',\r\n /**\r\n * \r\n */\r\n isPersistent: 'http://schemas.microsoft.com/ws/2008/06/identity/claims/ispersistent',\r\n}\r\n","import { AccountService } from \"./AccountService\";\r\nimport { useServices } from \"inject-typesafe-react\";\r\nimport { AppServices } from \"../../configure/configureServices\";\r\n\r\n/**\r\n * Hook to return the AccountService from the context (via useService).\r\n */\r\nexport function useAccountService(): AccountService {\r\n return useServices((services: AppServices) => services.accountService());\r\n}\r\n","import { useAuthenticatedState } from \"../api-authorization/useAuthenticatedState\";\r\n\r\n/**\r\n * Hook to get the current user id.\r\n */\r\nexport function useCurrentUserId(): string | undefined {\r\n const { user } = useAuthenticatedState({ includeUser: true });\r\n return user?.sub;\r\n}\r\n","import * as React from 'react';\r\nimport { atom, useRecoilState } from 'recoil';\r\n\r\nexport interface CurrentUserRolesCache {\r\n isLoading: boolean,\r\n isAuthenticated: boolean,\r\n roles: Array,\r\n}\r\n\r\nexport const currentUserRolesCacheState = atom({\r\n key: 'currentUserRolesCacheState',\r\n default: { isAuthenticated: false, roles: [], isLoading: false },\r\n //effects_UNSTABLE: [persistAtom],\r\n});\r\n\r\n/**\r\n * Hook that provides access to the Global search text from the global search text state while abstracting the global stage provider from the calling code.\r\n */\r\nexport function useCurrentUserRolesCache(): [CurrentUserRolesCache, React.Dispatch>] {\r\n const [value, setValue] = useRecoilState(currentUserRolesCacheState);\r\n return [value, setValue];\r\n}","import * as React from \"react\";\r\nimport { AsyncLoadResult, AsyncLoadOptions } from \"../../shared/abstractStore\";\r\nimport { useAsyncCallback } from \"react-use-async-callback\";\r\nimport { useAccountService } from \"./useAccountService\";\r\nimport { useAuthenticatedState } from \"../../api/api-authorization/useAuthenticatedState\";\r\nimport { isNullOrUndefined } from \"util\";\r\nimport { AccountService } from \"./AccountService\";\r\nimport { CurrentUserRolesCache, useCurrentUserRolesCache } from \"../../globalState/currentUserDetails/useCurrentUserRolesCache\";\r\n\r\n\r\n/**\r\n * Refresh the current user state using the accountService.\r\n * @param isAuthenticated\r\n */\r\nconst refreshCurrentUserRoles = async (isAuthenticated: boolean | null, accountService: AccountService, setRoles: (value: React.SetStateAction) => void): Promise => {\r\n // Do nothing if we don't know our authentication state.\r\n if (isNullOrUndefined(isAuthenticated)) {\r\n return;\r\n }\r\n\r\n // If we are not authenticated then we have no roles.\r\n if (!isAuthenticated) {\r\n setRoles({ isAuthenticated: false, roles: [], isLoading: false });\r\n return;\r\n }\r\n\r\n // Otherwise we are authenticated, so load our roles.\r\n setRoles(prevState => ({ ...prevState, isLoading: true }));\r\n let result = await accountService.currentUserRoles();\r\n setRoles({ isAuthenticated: true, roles: result.roles, isLoading: false });\r\n};\r\n\r\n/**\r\n * Returns the list of roles for the current user.\r\n */\r\nexport function useCurrentUserRoles(options: AsyncLoadOptions = {}): AsyncLoadResult<{ roles: Array | null }> {\r\n const { isAuthenticated } = useAuthenticatedState();\r\n const [roles, setRoles] = useCurrentUserRolesCache();\r\n const accountService = useAccountService();\r\n\r\n const [refresh, { isExecuting: isLoading, errors }] = useAsyncCallback(async () => {\r\n // Don't trigger more than one attempt at loading the roles at once.\r\n if (roles.isLoading) {\r\n return;\r\n }\r\n\r\n await refreshCurrentUserRoles(isAuthenticated, accountService, setRoles);\r\n }, [accountService, isAuthenticated, setRoles, roles]);\r\n\r\n React.useEffect(() => {\r\n if (options.lazy) {\r\n return;\r\n }\r\n\r\n // Refresh from the store if we need to.\r\n if (isNullOrUndefined(isAuthenticated)) {\r\n return;\r\n }\r\n\r\n if (!roles || roles.isAuthenticated !== isAuthenticated) {\r\n refresh();\r\n }\r\n }, [refresh, options.lazy, isAuthenticated, roles]);\r\n\r\n // TODO handle options.pollInterval.\r\n\r\n return {\r\n data: { roles: roles?.roles ?? null },\r\n refresh: refresh,\r\n isLoading: isLoading,\r\n errors: errors\r\n };\r\n}\r\n\r\n\r\n/**\r\n * Clear the cached user roles.\r\n */\r\nexport function useResetCurrentUserRolesCallback() {\r\n const { isAuthenticated } = useAuthenticatedState();\r\n const [/*roles*/, setRoles] = useCurrentUserRolesCache();\r\n const accountService = useAccountService();\r\n\r\n const [refresh] = useAsyncCallback(async () => {\r\n await refreshCurrentUserRoles(isAuthenticated, accountService, setRoles);\r\n }, [accountService, isAuthenticated]);\r\n\r\n return React.useCallback(() => {\r\n refresh();\r\n }, [refresh]);\r\n}\r\n","import * as React from \"react\";\r\nimport { ExternalAuthenticationScheme } from \"./AccountService\";\r\nimport { AsyncLoadResult, AsyncLoadOptions } from \"../../shared/abstractStore\";\r\nimport { useAsyncCallback } from \"react-use-async-callback\";\r\nimport { useAccountService } from \"./useAccountService\";\r\n\r\n/**\r\n * Use the store to return a list of external authentication schemes for the app.\r\n */\r\nexport function useExternalAuthenticationSchemes(options: AsyncLoadOptions = {}): AsyncLoadResult<{ externalAuthenticationSchemes: Array }> {\r\n const [externalAuthenticationSchemes, setExternalAuthenticationSchemes] = React.useState>([]);\r\n\r\n const accountService = useAccountService();\r\n\r\n const [refresh, { isExecuting: isLoading, errors }] = useAsyncCallback(async () => {\r\n let result = await accountService.getExternalAuthenticationSchemes();\r\n setExternalAuthenticationSchemes(result);\r\n }, [accountService, setExternalAuthenticationSchemes]);\r\n\r\n React.useEffect(() => {\r\n if (!options.lazy) {\r\n refresh();\r\n }\r\n }, [refresh, options.lazy]);\r\n\r\n // TODO handle options.pollInterval.\r\n\r\n return {\r\n data: { externalAuthenticationSchemes: externalAuthenticationSchemes },\r\n refresh: refresh,\r\n isLoading: isLoading,\r\n errors: errors\r\n };\r\n}\r\n","import { AsyncActionStatus } from \"../../shared/abstractStore\";\r\nimport { useAsyncCallback } from \"react-use-async-callback\";\r\nimport { LockoutRequest } from \"./AccountService\";\r\nimport { useAccountService } from \"./useAccountService\";\r\n\r\n/**\r\n * Callback to lockout an account.\r\n */\r\nexport function useLockoutCallback(): [(model: LockoutRequest) => Promise, AsyncActionStatus] {\r\n const accountService = useAccountService();\r\n\r\n const [action, { isExecuting, errors }] = useAsyncCallback(async (model: LockoutRequest) => {\r\n let result = await accountService.lockout(model);\r\n return result;\r\n }, [accountService]);\r\n\r\n return [action, { isExecuting, errors }];\r\n}\r\n","import { AsyncActionStatus } from \"../../shared/abstractStore\";\r\nimport { useAsyncCallback } from \"react-use-async-callback\";\r\nimport { useAccountService } from \"./useAccountService\";\r\n\r\n/**\r\n * Callback to resend the email confirmation email.\r\n */\r\nexport function useResendConfirmationEmailCallback(): [(email: string) => Promise, AsyncActionStatus] {\r\n const accountService = useAccountService();\r\n\r\n const [action, { isExecuting, errors }] = useAsyncCallback(async (email: string) => {\r\n return await accountService.resendConfirmEmail(email);\r\n }, [accountService]);\r\n\r\n return [action, { isExecuting, errors }];\r\n}\r\n","import { AsyncActionStatus } from \"../../shared/abstractStore\";\r\nimport { useAsyncCallback } from \"react-use-async-callback\";\r\nimport { useAccountService } from \"./useAccountService\";\r\n\r\n/**\r\n * Callback to Start the external login process for a provider.\r\n */\r\nexport function useStartExternalLoginCallback(): [(provider: string, returnUrl?: string) => Promise, AsyncActionStatus] {\r\n const accountService = useAccountService();\r\n\r\n const [action, { isExecuting, errors }] = useAsyncCallback(async (provider: string, returnUrl?: string): Promise => {\r\n accountService.startExternalLogin(provider, returnUrl);\r\n }, [accountService]);\r\n\r\n return [action, { isExecuting, errors }];\r\n}\r\n","import * as React from 'react';\r\nimport { isNullOrUndefined } from 'util';\r\nimport { useAuthenticatedState } from '../../api/api-authorization/useAuthenticatedState';\r\nimport { useCurrentUserRoles } from '../../api/account';\r\n\r\nexport interface AuthorizeContainerProps {\r\n requireRole?: string | Array,\r\n /**\r\n * When set to true, the containers children will only show if authorization fails.\r\n */\r\n showIfNotAuthorized?: boolean,\r\n children?: React.ReactNode,\r\n}\r\n\r\n/**\r\n * Container component that will check for authorization before showing its children.\r\n * @param props\r\n */\r\nexport const AuthorizeContainer = (props: AuthorizeContainerProps) => {\r\n const { isAuthenticated } = useAuthenticatedState();\r\n const { data: { roles: usersRoles } } = useCurrentUserRoles();\r\n const [ hasRequiredRole, setHasRequiredRole ] = React.useState(); \r\n\r\n // Load the roles only if we need to.\r\n React.useEffect(() => {\r\n if (props.requireRole && !isNullOrUndefined(usersRoles)) {\r\n const requireRoles = [props.requireRole].flat(2);\r\n let hasRole = false;\r\n for (let roleToCheck of requireRoles) {\r\n if (usersRoles.find(it => it === roleToCheck)) {\r\n hasRole = true;\r\n break;\r\n }\r\n }\r\n setHasRequiredRole(hasRole);\r\n }\r\n }, [props.requireRole, usersRoles, setHasRequiredRole, isAuthenticated]);\r\n\r\n // Render the UI\r\n //\r\n const { children } = props;\r\n\r\n // Show nothing until we have a defined authenticated state.\r\n if (isNullOrUndefined(isAuthenticated)) {\r\n return (<>);\r\n }\r\n\r\n let failedCheck = false;\r\n\r\n // Check if we are not authenticted.\r\n if (!isAuthenticated) {\r\n failedCheck = true;\r\n }\r\n\r\n // If we need to check a role but don't have the roles to check yet, show nothing.\r\n if (isAuthenticated && props.requireRole && isNullOrUndefined(usersRoles)) {\r\n return (<>);\r\n }\r\n\r\n // If we checked a role and didn't have one we were looking for, show nothing.\r\n if (hasRequiredRole === false) {\r\n failedCheck = true;\r\n }\r\n\r\n // If we get here then we can render the children or not based on if the check failed or succeeded.\r\n if (failedCheck) {\r\n if (props.showIfNotAuthorized) {\r\n return (<>{children});\r\n }\r\n\r\n return (<>);\r\n }\r\n\r\n if (props.showIfNotAuthorized) {\r\n return (<>);\r\n }\r\n\r\n return (<>{children});\r\n};\r\n","import i18n from 'i18next';\r\n\r\n\r\nexport enum OverallRiskCategory {\r\n High = 'High',\r\n Medium = 'Medium',\r\n Low = 'Low',\r\n NotAssessed = 'Not Assessed',\r\n}\r\n\r\nexport interface RiskRules {\r\n highRiskBelow: number,\r\n mediumRiskBelow: number,\r\n // lowBelow: number, // Always 100.\r\n}\r\n\r\nexport const defaultRiskRules: RiskRules = {\r\n highRiskBelow: 30,\r\n mediumRiskBelow: 70,\r\n};\r\n\r\n\r\n/**\r\n * Service that pulls together all utilities needed to manage the overall risk calculations and display.\r\n */\r\nexport class OverallRiskService {\r\n /**\r\n * Returns the name of the risk based off number.\r\n * @param value\r\n */\r\n getRiskCategory(value: number, notStarted: boolean, riskRules?: RiskRules | undefined | null): OverallRiskCategory {\r\n\r\n if (notStarted) {\r\n return OverallRiskCategory.NotAssessed;\r\n }\r\n\r\n const riskRulesToUse = riskRules ?? defaultRiskRules;\r\n\r\n if (value < riskRulesToUse.highRiskBelow) {\r\n return OverallRiskCategory.High;\r\n } else if (value < riskRulesToUse.mediumRiskBelow) {\r\n return OverallRiskCategory.Medium;\r\n } else {\r\n return OverallRiskCategory.Low;\r\n }\r\n }\r\n\r\n /**\r\n * Returns the name of the risk based off the category (caluclating it first if needed).\r\n * @param value\r\n */\r\n getRiskName(category: OverallRiskCategory, riskRules?: RiskRules | undefined | null): string;\r\n getRiskName(value: number, riskRules?: RiskRules | undefined | null): string;\r\n getRiskName(categoryOrValue: OverallRiskCategory | number, riskRules?: RiskRules | undefined | null): string {\r\n const riskRulesToUse = riskRules ?? defaultRiskRules;\r\n\r\n // Get a risk category either by converting it from the number passed in, or by using the passed in category.\r\n let category: OverallRiskCategory;\r\n if (typeof categoryOrValue === 'number') {\r\n category = this.getRiskCategory(categoryOrValue, false, riskRulesToUse);\r\n } else {\r\n category = categoryOrValue as OverallRiskCategory;\r\n }\r\n\r\n switch (category) {\r\n case OverallRiskCategory.High:\r\n return i18n.t('getRiskName.high', 'High risk');\r\n case OverallRiskCategory.Medium:\r\n return i18n.t('getRiskName.medium', 'Medium risk');\r\n case OverallRiskCategory.Low:\r\n return i18n.t('getRiskName.low', 'Low risk');\r\n case OverallRiskCategory.NotAssessed:\r\n return i18n.t('getRiskName.notAssessed', 'Not assessed');\r\n }\r\n\r\n /* NOTREACHED */\r\n }\r\n\r\n\r\n getSpidergraphBackgroundColors(tickAmount: number, riskRules?: RiskRules | undefined | null): Array {\r\n const riskRulesToUse = riskRules ?? defaultRiskRules;\r\n\r\n // Colors need to be built in reverse order so we can run red from the centre out to green.\r\n let colors: Array = [];\r\n for (let i = 0; i < 100; i += tickAmount) {\r\n if (i < riskRulesToUse.highRiskBelow) {\r\n colors = [`rgba(248,108,107, 0.8)`, ...colors];\r\n } else if (i < riskRulesToUse.mediumRiskBelow) {\r\n colors = [`rgba(255,193,7, 0.7)`, ...colors];\r\n } else {\r\n colors = [`rgba(77,189,116, 0.6)`, ...colors];\r\n }\r\n }\r\n\r\n return colors;\r\n }\r\n}\r\n\r\nexport const overallRiskService = new OverallRiskService();\r\n","import * as React from 'react';\r\nimport { Route, Redirect, RouteProps } from 'react-router-dom';\r\nimport { isNullOrUndefined } from 'util';\r\nimport { useAuthenticatedState } from '../../api/api-authorization/useAuthenticatedState';\r\nimport { useCurrentUserRoles } from '../../api/account';\r\n\r\nexport interface AuthorizeRouteProps extends RouteProps {\r\n requireRole?: string | Array,\r\n}\r\n\r\n/**\r\n * Route component that will check for authorization before showing its component.\r\n * \r\n * NOTE this was originally based on AuthorizeRoute from Microsoft's template but converted to typescript and React hooks and to support more than just the component prop.\r\n * @param props\r\n */\r\nexport const AuthorizeRoute = (props: AuthorizeRouteProps) => {\r\n const { isAuthenticated } = useAuthenticatedState();\r\n const { data: { roles: usersRoles } } = useCurrentUserRoles();\r\n const [ hasRequiredRole, setHasRequiredRole ] = React.useState(); \r\n\r\n // Load the roles only if we need to.\r\n React.useEffect(() => {\r\n if (props.requireRole && !isNullOrUndefined(usersRoles)) {\r\n const requireRoles = [props.requireRole].flat(2);\r\n let hasRole = false;\r\n for (let roleToCheck of requireRoles) {\r\n if (usersRoles.find(it => it === roleToCheck)) {\r\n hasRole = true;\r\n break;\r\n }\r\n }\r\n setHasRequiredRole(hasRole);\r\n }\r\n }, [props.requireRole, usersRoles, setHasRequiredRole, isAuthenticated]);\r\n\r\n // Render the UI\r\n //\r\n const { component: Component, render, children, ...rest } = props;\r\n\r\n // Show nothing until we have a defined authenticated state.\r\n if (isNullOrUndefined(isAuthenticated)) {\r\n return (<>);\r\n }\r\n \r\n // If we need to check a role, but can't yet return nothing.\r\n if (props.requireRole && isNullOrUndefined(usersRoles)) {\r\n return (<>);\r\n }\r\n\r\n // If we don't have the role we require, show text saying so.\r\n if (hasRequiredRole === false) {\r\n return (<>Sorry you do not have permission to access this area.);\r\n }\r\n\r\n return (\r\n {\r\n if (isAuthenticated) {\r\n if (Component) {\r\n return ;\r\n } else if (render) {\r\n return render(props);\r\n } else {\r\n return children;\r\n }\r\n } else {\r\n const redirectUrl = `/authentication/login?returnUrl=${encodeURIComponent(window.location.href)}`\r\n return \r\n }\r\n }} />\r\n );\r\n};\r\n","import * as React from 'react';\r\nimport { NavLink, NavLinkProps } from 'react-router-dom';\r\n\r\nexport interface NavLinkTrackActiveProps extends NavLinkProps {\r\n}\r\n\r\n/**\r\n * NavLink from react-router configured to track the active component with the active class. \r\n * \r\n * This simply returns a that is preconfigured with activeClassName=\"active\".\r\n */\r\nexport const NavLinkTrackActive = (props: NavLinkTrackActiveProps) => {\r\n const { to, exact, activeClassName, ...rest } = props;\r\n\r\n return (\r\n \r\n );\r\n};\r\n","/**\r\n * Constants for the available roles.\r\n */\r\nexport const IdentityRoles = {\r\n DriverManagement: 'DriverManagement',\r\n SubscriptionAdministration: 'SubscriptionAdministration',\r\n DistributionAdministration: 'DistributorAdministration',\r\n Administration: 'Administration',\r\n};\r\n\r\n///**\r\n// * Constants (enum) for the available Roles.\r\n// */\r\n//export enum IdentityRoles {\r\n// Administration = 'Administration'\r\n//}\r\n","import { TFunction } from \"i18next\";\r\n\r\n/**\r\n * Subscription types\r\n */\r\nexport enum SubscriptionType {\r\n Subscription = \"Subscription\",\r\n Distributor = \"Distributor\",\r\n Study = \"Study\"\r\n}\r\n\r\n/**\r\n * Return translated display name if its needed.\r\n * @param t\r\n */\r\nexport function subscriptionTypeDisplayName(type: SubscriptionType, t: TFunction): string {\r\n switch (type) {\r\n case SubscriptionType.Subscription: return t('subscriptionTypeDisplayName.Subscription', 'Subscription');\r\n case SubscriptionType.Distributor: return t('subscriptionTypeDisplayName.Distributor', 'Distributor');\r\n case SubscriptionType.Study: return t('subscriptionTypeDisplayName.Study', 'Study');\r\n }\r\n}\r\n","import gql from \"graphql-tag\";\r\nimport { Guid } from \"guid-string\";\r\nimport { defaultRiskRules } from \"../../../services/OverallRiskService\";\r\nimport { subscriptionFields } from \"../generated/subscriptionFields\";\r\nimport { SubscriptionType } from \"./codeOnly/SubscriptionType\";\r\n\r\nexport const subscriptionFieldsFragment = gql`\r\n fragment subscriptionFields on Subscription {\r\n id\r\n companyName\r\n archived\r\n brandColor\r\n brandImageBlobReferenceId\r\n maxUsers\r\n currentUsers\r\n restrictMaxUsers\r\n allowBranding\r\n allowExport\r\n highRiskBelow\r\n mediumRiskBelow\r\n subscriptionType\r\n distributorSubscriptionId\r\n studyUniqueCode\r\n studyReturnUrl\r\n }\r\n`;\r\n\r\n\r\nexport type Subscription = Omit;\r\n\r\nexport const subscriptionDefaultValues = (): Partial => ({\r\n id: Guid.newGuid(),\r\n companyName: '',\r\n archived: false,\r\n brandColor: '',\r\n brandImageBlobReferenceId: null,\r\n maxUsers: 1,\r\n currentUsers: 0,\r\n restrictMaxUsers: false,\r\n allowBranding: false,\r\n allowExport: false,\r\n highRiskBelow: defaultRiskRules.highRiskBelow,\r\n mediumRiskBelow: defaultRiskRules.mediumRiskBelow,\r\n subscriptionType: SubscriptionType.Subscription,\r\n distributorSubscriptionId: null,\r\n studyUniqueCode: '',\r\n studyReturnUrl: ''\r\n});","import { WatchQueryFetchPolicy } from \"@apollo/client\";\r\n\r\nexport const mainApiConfig = {\r\n endpoint: '/graphql',\r\n blobUploadEndpoint: '/api/blobs',\r\n blobDownloadEndpoint: '/api/blobs/redirectToUrl',\r\n defaultFetchPolicy: 'cache-and-network' as WatchQueryFetchPolicy,\r\n //defaultFetchPolicy: 'cache-first' as WatchQueryFetchPolicy,\r\n};","import * as React from 'react';\r\nimport { useLazyQuery } from \"@apollo/react-hooks\";\r\nimport gql from \"graphql-tag\";\r\nimport { Guid } from \"guid-string\";\r\nimport { AsyncLoadResult, AsyncLoadOptions } from '../../../shared/abstractStore';\r\nimport { subscriptionQuery, subscriptionQueryVariables } from '../generated/subscriptionQuery';\r\nimport { subscriptionFieldsFragment } from '../models/Subscription';\r\nimport { mainApiConfig } from '../../../configure/mainApiConfig';\r\n\r\n/**\r\n * Get a Subscription from the store.\r\n * @param id\r\n * @param options\r\n */\r\nexport function useSubscription(id: string | undefined | null, options: AsyncLoadOptions = {}): AsyncLoadResult {\r\n // Query the data we need form the api.\r\n const [load, { data, loading, error, refetch }] = useLazyQuery(\r\n gql`\r\n query subscriptionQuery ($id: ID!) {\r\n model: subscription(id: $id) {\r\n ...subscriptionFields\r\n }\r\n }\r\n\r\n ${subscriptionFieldsFragment}\r\n `,\r\n {\r\n variables: {\r\n id: id ?? Guid.empty,\r\n },\r\n fetchPolicy: options.fetchPolicy ?? mainApiConfig.defaultFetchPolicy,\r\n pollInterval: options.pollInterval,\r\n onCompleted: (data) => {\r\n if (options.onCompleted) {\r\n options.onCompleted(data);\r\n }\r\n }\r\n }\r\n );\r\n\r\n // Run the query (unless we are being lazy).\r\n React.useEffect(() => {\r\n if (!options.lazy) {\r\n load();\r\n }\r\n }, [options.lazy, load])\r\n\r\n // Return the results.\r\n const refresh = React.useCallback(async () => { !refetch ? await load() : await refetch(); }, [refetch, load]);\r\n return React.useMemo(() => ({\r\n data: data ?? ({} as any),\r\n refresh: refresh,\r\n isLoading: loading,\r\n errors: error\r\n }), [data, refresh, loading, error]);\r\n}\r\n","import * as React from 'react';\r\nimport { atom, useRecoilState } from 'recoil';\r\nimport { Profile } from '../../api/main/models/Profile';\r\n\r\nexport interface CurrentUserProfileCache {\r\n isLoading: boolean,\r\n isAuthenticated: boolean,\r\n profile: Profile | null,\r\n}\r\n\r\nexport const currentUserProfileCacheState = atom({\r\n key: 'currentUserProfileCacheState',\r\n default: { isAuthenticated: false, profile: null, isLoading: false },\r\n //effects_UNSTABLE: [persistAtom],\r\n});\r\n\r\n/**\r\n * Hook that provides access to the current user's profile cached in global state.\r\n */\r\nexport function useCurrentUserProfilesCache(): [CurrentUserProfileCache, React.Dispatch>] {\r\n const [value, setValue] = useRecoilState(currentUserProfileCacheState);\r\n return [value, setValue];\r\n}","import gql from \"graphql-tag\";\r\nimport { roleGroupFields } from \"../generated/roleGroupFields\";\r\n\r\nexport const roleGroupFieldsFragment = gql`\r\n fragment roleGroupFields on RoleGroup {\r\n id\r\n name\r\n }\r\n`;\r\n\r\n\r\nexport type RoleGroup = Omit;","import gql from \"graphql-tag\";\r\nimport { userFields } from \"../generated/userFields\";\r\nimport { roleGroupFieldsFragment } from \"./RoleGroup\";\r\n\r\nexport const userFieldsFragment = gql`\r\n fragment userFields on User {\r\n id\r\n userName\r\n email\r\n emailConfirmed\r\n phoneNumberConfirmed\r\n twoFactorEnabled\r\n lockoutEnd\r\n lockoutEnabled\r\n accessFailedCount\r\n roleGroup {\r\n ...roleGroupFields\r\n }\r\n }\r\n\r\n ${roleGroupFieldsFragment}\r\n`;\r\n\r\n\r\nexport type User = Omit;\r\n","import gql from \"graphql-tag\";\r\nimport { Guid } from \"guid-string\";\r\nimport { profileFields } from \"../generated/profileFields\";\r\nimport { userFieldsFragment } from \"./User\";\r\n\r\nexport const profileFieldsFragment = gql`\r\n fragment profileFields on Profile {\r\n id\r\n userId\r\n firstName\r\n lastName\r\n archived\r\n subscriptionId\r\n uniqueDriverPin\r\n subscriptionTeamId\r\n\r\n user {\r\n ...userFields,\r\n }\r\n }\r\n\r\n ${userFieldsFragment}\r\n`;\r\n\r\n\r\nexport type Profile = Omit;\r\n\r\n/**\r\n * Default values.\r\n */\r\nexport const profileDefaultValues = (): Partial => ({\r\n id: Guid.newGuid(),\r\n firstName: '',\r\n lastName: '',\r\n subscriptionId: null,\r\n subscriptionTeamId: null,\r\n uniqueDriverPin: '',\r\n});","import * as React from 'react';\r\nimport { useLazyQuery } from \"@apollo/react-hooks\";\r\nimport gql from \"graphql-tag\";\r\nimport { Guid } from \"guid-string\";\r\nimport { AsyncLoadResult, AsyncLoadOptions } from '../../../shared/abstractStore';\r\nimport { profileQuery, profileQueryVariables } from '../generated/profileQuery';\r\nimport { profileFieldsFragment } from '../models/Profile';\r\nimport { mainApiConfig } from '../../../configure/mainApiConfig';\r\n\r\nexport interface ProfileOptions extends AsyncLoadOptions {\r\n isUserId?: boolean,\r\n}\r\n\r\n/**\r\n * Get a Profile from the store.\r\n * @param id\r\n * @param options\r\n */\r\nexport function useProfile(id: string | undefined | null, options: ProfileOptions = {}): AsyncLoadResult {\r\n // Query the data we need form the api.\r\n const [load, { data, loading, error, refetch }] = useLazyQuery(\r\n gql`\r\n query profileQuery ($id: ID, $userId: ID) {\r\n model: profile(id: $id, userId: $userId) {\r\n ...profileFields\r\n }\r\n }\r\n\r\n ${profileFieldsFragment}\r\n `,\r\n {\r\n variables: {\r\n id: !options.isUserId ? id ?? Guid.empty : null,\r\n userId: options.isUserId ? id ?? Guid.empty : null\r\n },\r\n fetchPolicy: options.fetchPolicy ?? mainApiConfig.defaultFetchPolicy,\r\n pollInterval: options.pollInterval,\r\n onCompleted: (data) => {\r\n if (options.onCompleted) {\r\n options.onCompleted(data);\r\n }\r\n }\r\n }\r\n );\r\n\r\n // Run the query (unless we are being lazy).\r\n React.useEffect(() => {\r\n if (!options.lazy) {\r\n load();\r\n }\r\n }, [options.lazy, load])\r\n\r\n // Return the results.\r\n const refresh = React.useCallback(async () => { !refetch ? await load() : await refetch(); }, [refetch, load]);\r\n return React.useMemo(() => ({\r\n data: data ?? ({} as any),\r\n refresh: refresh,\r\n isLoading: loading,\r\n errors: error\r\n }), [data, refresh, loading, error]);\r\n}\r\n","import * as React from \"react\";\r\nimport { AsyncLoadResult, AsyncLoadOptions } from \"../../../shared/abstractStore\";\r\nimport { isNullOrUndefined } from \"util\";\r\nimport { useCurrentUserProfilesCache } from \"../../../globalState/currentUserDetails/useCurrentUserProfileCache\";\r\nimport { useProfile } from \"./useProfile\";\r\nimport { useAuthenticatedState } from \"../../api-authorization/useAuthenticatedState\";\r\nimport { Guid } from \"guid-string\";\r\nimport { Profile } from \"../models/Profile\";\r\n\r\n/**\r\n * Returns the (application level) Profile for the current user.\r\n */\r\nexport function useCurrentUserProfile(options: AsyncLoadOptions = {}): AsyncLoadResult<{ model: Profile | null }> {\r\n const { isAuthenticated, user } = useAuthenticatedState({ includeUser: true });\r\n const [profileCache, setProfileCache] = useCurrentUserProfilesCache();\r\n\r\n // Need the GraphQL api hook to let us load a profile if we need it.\r\n const { data: { model: storeProfile }, refresh: loadProfileFromStore, errors } = useProfile(user?.sub ?? Guid.empty, { lazy: true, isUserId: true });\r\n\r\n // Update the profile in the cache from the store if we need to.\r\n React.useEffect(() => {\r\n // Do nothing if we don't know our authentication state.\r\n if (isNullOrUndefined(isAuthenticated)) {\r\n return;\r\n }\r\n\r\n // If we are not authenticated then we have no profile.\r\n if (!isAuthenticated) {\r\n if (profileCache.isLoading && !!profileCache.profile) {\r\n setProfileCache({ isAuthenticated: false, profile: null, isLoading: false });\r\n }\r\n return;\r\n }\r\n\r\n // If we are authenticated and we already have our profile, then we dont need to do anything more.\r\n if (profileCache.profile) {\r\n return;\r\n }\r\n\r\n // If we're already trying to load the profile but haven't completed yet , we can give up and wait\r\n // this will either retrigger because the graphql api returns the data or because it was started at the sane time by\r\n // another component and then is available for us via a global state chane of the cached value.\r\n if (profileCache.isLoading && !storeProfile) {\r\n return;\r\n }\r\n\r\n // If we've received a store profile via graphql, we can update the profile in the cache.\r\n if (storeProfile && profileCache.isLoading && profileCache.profile !== storeProfile) {\r\n setProfileCache(prevState => ({ ...prevState, profile: storeProfile, isLoading: false, }));\r\n return;\r\n }\r\n\r\n // If we reach this point we're going to need to trigger the profile load from the database. If we are being lazy this is where we stop.\r\n if (options.lazy) {\r\n return;\r\n }\r\n\r\n // OK we've tried everything else, lets trigger the profile load from the store.\r\n setProfileCache(prevState => ({ ...prevState, isLoading: true, }));\r\n loadProfileFromStore();\r\n }, [isAuthenticated, storeProfile, setProfileCache, profileCache, options.lazy, loadProfileFromStore]);\r\n \r\n\r\n return {\r\n data: { model: profileCache.profile ?? null },\r\n refresh: loadProfileFromStore,\r\n isLoading: profileCache.isLoading,\r\n errors: errors\r\n };\r\n}\r\n\r\n","import { recoilPersist } from 'recoil-persist';\r\n\r\nconst persistKey = 'recoil-persist';\r\n\r\n/**\r\n * Configure persistance of recoil, to use you need to add an effect to any atom you want to be persisted e.g.:\r\n const counterState = atom({\r\n key: 'count',\r\n default: 0,\r\n effects_UNSTABLE: [persistAtom],\r\n })\r\n */\r\nexport const { persistAtom } = recoilPersist({\r\n key: persistKey\r\n});\r\n\r\n/**\r\n * Purge the recoil persistance.\r\n */\r\nexport function purgeRecoilPersist() {\r\n window?.localStorage?.removeItem(persistKey);\r\n}\r\n","import * as React from 'react';\r\nimport { atom, useRecoilState } from 'recoil';\r\nimport { persistAtom } from '../../configure/recoilPersistConfig';\r\n\r\nexport const subscriptionEmulationState = atom({\r\n key: 'subscriptionEmulationState',\r\n default: null,\r\n effects_UNSTABLE: [persistAtom],\r\n});\r\n\r\n/**\r\n * Hook that provides access to the subscription emulation functionality.\r\n * \r\n * For code that just wants to get the current user's subscription (overriden by the emulated subscription if emulation is being used) you\r\n * should use useCurrentUserOrEmulatedSubscription().\r\n */\r\nexport function useSubscriptionEmulation(): [string | null | undefined, React.Dispatch>] {\r\n const [value, setValue] = useRecoilState(subscriptionEmulationState);\r\n return [value, setValue];\r\n}","import { useCurrentUserProfile } from '../../api/main/profiles/useCurrentUserProfile';\r\nimport { useSubscriptionEmulation } from './useSubscriptionEmulation';\r\n\r\n\r\n/**\r\n * Returns the current user's subscriptionId, or if the user is currently emulating a different subscription, the emulated subscription.\r\n */\r\nexport function useCurrentUserOrEmulatedSubscriptionId(): string | null | undefined {\r\n const [emualtedSubscriptionId] = useSubscriptionEmulation();\r\n const { data: { model: currentUserProfile } } = useCurrentUserProfile();\r\n\r\n return emualtedSubscriptionId ?? currentUserProfile?.subscriptionId;\r\n}","import { NavItem, NavLink } from 'reactstrap';\r\nimport { AuthorizeContainer } from '../../shared/authorizeRoute';\r\nimport { useTranslation } from 'react-i18next';\r\nimport { FontAwesomeIcon } from '@fortawesome/react-fontawesome';\r\nimport { NavLinkTrackActive } from '../shared/NavLinkTrackActive';\r\nimport { IdentityRoles } from '../../configure/security/IdentityRoles';\r\nimport { ConditionalFragment } from 'react-conditionalfragment';\r\nimport { useSubscription } from '../../api/main/subscriptions/useSubscription';\r\nimport { SubscriptionType } from '../../api/main/models/codeOnly/SubscriptionType';\r\nimport { useCurrentUserProfile } from '../../api/main/profiles/useCurrentUserProfile';\r\nimport { Guid } from 'guid-string';\r\nimport { useCurrentUserOrEmulatedSubscriptionId } from '../../globalState/subscriptions/useCurrentUserOrEmulatedSubscriptionId';\r\nimport { useMemo } from 'react';\r\nimport { useCurrentUserRoles } from '../../api/account';\r\n\r\n/**\r\n * Primary navigation menu for the app. \r\n */\r\nexport const Navigation = () => {\r\n const { t } = useTranslation();\r\n\r\n // If the user is part of a study, we don't provide any menu options.\r\n \r\n const { data: { model: currentProfile } } = useCurrentUserProfile();\r\n const { data: { roles } } = useCurrentUserRoles();\r\n const emulatedSubscriptionId = useCurrentUserOrEmulatedSubscriptionId();\r\n\r\n // NOTE we don't want to loose menus when we are emulating a study subscription, so for non-admins we always grab it directly from the profile not using the\r\n // useCurrentUserOrEmulatedSubscriptionId hook.\r\n const subscriptionId = useMemo(() => {\r\n // Admins can use the emulated subscription.\r\n if (roles?.includes(IdentityRoles.Administration)) {\r\n return emulatedSubscriptionId;\r\n }\r\n\r\n // Non-admins can't use the emulated subscription.\r\n return currentProfile?.subscriptionId ?? Guid.empty;\r\n }, [currentProfile, emulatedSubscriptionId, roles]);\r\n\r\n // Load the subscription\r\n const { data: { model } } = useSubscription(subscriptionId ?? Guid.empty);\r\n if (model?.subscriptionType === SubscriptionType.Study && !roles?.includes(IdentityRoles.SubscriptionAdministration)) {\r\n return (<>);\r\n }\r\n\r\n\r\n // Return the general UI.\r\n return (\r\n <>\r\n \r\n \r\n \r\n \r\n <> {t('navigation.home', 'Home')}\r\n \r\n \r\n\r\n \r\n \r\n \r\n <> {t('navigation.dashboard', 'Dashboard')}\r\n \r\n \r\n \r\n\r\n \r\n \r\n \r\n \r\n \r\n <> {t('navigation.manageSubscription', 'Manage subscription')}\r\n \r\n \r\n \r\n \r\n\r\n \r\n \r\n \r\n \r\n \r\n <> {t('navigation.manageDistributor', 'Manage distributor')}\r\n \r\n \r\n \r\n \r\n\r\n \r\n \r\n \r\n \r\n <> {t('navigation.administration', 'Administration')}\r\n \r\n \r\n \r\n \r\n );\r\n};\r\n","import './appNavbarBrand.scss';\r\n\r\nimport * as React from 'react';\r\n//import { NavbarBrand } from 'reactstrap'; // Not used as it renders a / and we want to control our / elsewhere.\r\n\r\n/**\r\n * Navbar brand image for the app. \r\n */\r\nexport const AppNavbarBrand = () => {\r\n return (\r\n
\r\n {/*
\r\n
\r\n
\r\n
*/}\r\n
\r\n );\r\n};","import './header.scss';\r\n\r\nimport { Nav, Container } from 'reactstrap';\r\nimport { AppHeader, AppSidebarToggler } from '@coreui/react';\r\nimport { UserNav } from './UserNav';\r\nimport { Link } from 'react-router-dom';\r\nimport { Navigation } from '../home/Navigation';\r\nimport { AppNavbarBrand } from './appNavbarBrand/AppNavbarBrand';\r\nimport { SubscriptionType } from '../../api/main/models/codeOnly/SubscriptionType';\r\nimport { ConditionalFragment } from 'react-conditionalfragment';\r\nimport { useMemo } from 'react';\r\nimport { useSubscription } from '../../api/main/subscriptions/useSubscription';\r\nimport { useCurrentUserProfile } from '../../api/main/profiles/useCurrentUserProfile';\r\nimport { Guid } from 'guid-string';\r\n\r\nexport const Header = () => {\r\n // If the user is part of a study, we don't provide any menu options.\r\n // NOTE we don't want to loose menus when we are emulating a study subscription, so we always grab it directly from the profile not using the\r\n // useCurrentUserOrEmulatedSubscriptionId hook.\r\n const { data: { model: currentProfile } } = useCurrentUserProfile();\r\n const { data: { model } } = useSubscription(currentProfile?.subscriptionId ?? Guid.empty);\r\n const showUserNav = useMemo(() => !model || model.subscriptionType !== SubscriptionType.Study, [model]);\r\n \r\n return (\r\n \r\n \r\n \r\n\r\n \r\n \r\n \r\n \r\n\r\n \r\n \r\n\r\n \r\n \r\n \r\n \r\n\r\n {/**/}\r\n \r\n \r\n );\r\n};\r\n","import * as React from 'react';\r\nimport { NavItem, NavLink } from 'reactstrap';\r\nimport { useTranslation } from 'react-i18next';\r\nimport { NavLinkTrackActive } from '../shared/NavLinkTrackActive';\r\n\r\n/**\r\n * Footer navigation menu for the app. \r\n */\r\nexport const FooterNavigation = () => {\r\n const { t } = useTranslation();\r\n\r\n return (\r\n <>\r\n \r\n \r\n {t('footerNavigation.esitu-solutions', 'Esitu Solutions')}\r\n \r\n \r\n \r\n \r\n {t('footerNavigation.termsAndConditions', 'Terms and conditions')}\r\n \r\n \r\n \r\n \r\n {t('footerNavigation.privacyPolicy', 'Privacy policy')}\r\n \r\n \r\n \r\n \r\n {t('footerNavigation.cookiePolicy', 'Cookie policy')}\r\n \r\n \r\n \r\n );\r\n};\r\n","import './footer.scss';\r\nimport * as React from 'react';\r\nimport { AppFooter } from '@coreui/react';\r\nimport { Nav } from 'reactstrap';\r\nimport { FooterNavigation } from './FooterNavigation';\r\n\r\nexport const Footer = () => {\r\n return (\r\n \r\n \r\n \r\n );\r\n};\r\n\r\n","import * as React from 'react';\r\nimport PerfectScrollbar from 'react-perfect-scrollbar';\r\n\r\nexport const SidebarNav = (props: any) => {\r\n return (\r\n \r\n {props.children}\r\n \r\n );\r\n};\r\n","import './sidebarNavTitle.scss';\r\n\r\nimport * as React from 'react';\r\nimport { NavItem } from 'reactstrap';\r\n\r\nexport interface SidebarNavTitleProps {\r\n className?: string,\r\n child?: boolean,\r\n children?: React.ReactNode,\r\n}\r\n\r\nexport const SidebarNavTitle = (props: SidebarNavTitleProps) => {\r\n const { className, child, children } = props;\r\n\r\n return (\r\n \r\n {children}\r\n \r\n );\r\n};\r\n","import * as React from 'react';\r\nimport { Route, Switch } from 'react-router';\r\nimport { RouteEntry } from '../../shared/routes';\r\nimport { AuthorizeRoute } from '../../shared/authorizeRoute';\r\n\r\nexport interface AppRoutesProps {\r\n routes: Array,\r\n}\r\n\r\nexport const AppRoutes = (props: AppRoutesProps) => {\r\n const { routes } = props;\r\n\r\n return (\r\n \r\n {\r\n routes.map((item, index) => {\r\n // If we need to authorize for this route then use an AuthorizeRoute.\r\n if (item.authorize || item.requireRole) {\r\n return ();\r\n }\r\n\r\n // Otherwise a simple Route will do.\r\n return ();\r\n })\r\n }\r\n \r\n );\r\n};\r\n","import * as React from 'react';\r\nimport { Spinner } from 'reactstrap';\r\n\r\nexport interface LoadingIndicatorProps {\r\n className?: string,\r\n fullWidth?: boolean,\r\n size?: 'sm' | 'md' | 'lg',\r\n inline?: boolean,\r\n}\r\n\r\n/**\r\n * Simple spinner that can be shown during loading.\r\n */\r\nexport const LoadingIndicator = (props: LoadingIndicatorProps) => {\r\n const { className, fullWidth, size, inline } = props;\r\n\r\n const style = React.useMemo(() => {\r\n let ret: React.CSSProperties = {};\r\n if (fullWidth) {\r\n ret.width = '100%';\r\n ret.textAlign = 'center';\r\n }\r\n\r\n if (inline) {\r\n ret.display = 'inline';\r\n }\r\n\r\n return ret;\r\n }, [inline, fullWidth])\r\n\r\n return (\r\n
\r\n \r\n Loading\r\n
\r\n );\r\n};\r\n\r\n","import './background.scss';\r\n\r\nimport * as React from 'react';\r\nimport { Helmet } from 'react-helmet-async';\r\n\r\nexport interface BackgroundProps {\r\n children?: React.ReactNode,\r\n className?: string,\r\n centerChildren?: 'none' | 'vertically' | 'horizontally',\r\n\r\n background?: 'default',\r\n}\r\n\r\n/**\r\n * Background for making the back of screens look nicer.\r\n * @param props\r\n */\r\nexport const Background = (props: BackgroundProps) => {\r\n const {\r\n children,\r\n className,\r\n centerChildren,\r\n background = 'default',\r\n } = props;\r\n\r\n return (\r\n
\r\n \r\n \r\n \r\n {children}\r\n
\r\n );\r\n};","import { LoadingIndicator } from '../shared/LoadingIndicator';\r\nimport { Background } from '../shared/background/Background';\r\n\r\nexport interface LoginWaitingProps {\r\n waiting: boolean,\r\n message: string\r\n}\r\n\r\n/**\r\n * Component that is shown during waiting of any login or logout options.\r\n * \r\n * If you want to change the \"waiting\" screen between redirects for all login actions, this is where to do it.\r\n */\r\nexport const LoginWaiting = (props: LoginWaitingProps) => {\r\n const { waiting, message } = props;\r\n\r\n return (\r\n \r\n {/**/}\r\n\r\n {\r\n waiting ? (\r\n <>\r\n \r\n
\r\n {message}\r\n
\r\n \r\n ) : (\r\n <>\r\n {\r\n !!message ? (
{message}
) : null\r\n }\r\n \r\n )\r\n }\r\n
\r\n );\r\n};","export const QueryParameterNames = {\r\n ReturnUrl: 'returnUrl',\r\n Message: 'message'\r\n};\r\n\r\nexport const LogoutActions = {\r\n LogoutCallback: 'logout-callback',\r\n Logout: 'logout',\r\n LoggedOut: 'logged-out'\r\n};\r\n\r\nexport const LoginActions = {\r\n Login: 'login',\r\n LoginCallback: 'login-callback',\r\n LoginFailed: 'login-failed',\r\n Profile: 'profile',\r\n Register: 'register'\r\n};\r\n\r\nconst prefix = '/authentication';\r\n\r\nexport const ApplicationPaths = {\r\n DefaultLoginRedirectPath: '/',\r\n ApiAuthorizationPrefix: prefix,\r\n Login: `${prefix}/${LoginActions.Login}`,\r\n LoginFailed: `${prefix}/${LoginActions.LoginFailed}`,\r\n LoginCallback: `${prefix}/${LoginActions.LoginCallback}`,\r\n Register: `${prefix}/${LoginActions.Register}`,\r\n Profile: `${prefix}/${LoginActions.Profile}`,\r\n LogOut: `${prefix}/${LogoutActions.Logout}`,\r\n LoggedOut: `${prefix}/${LogoutActions.LoggedOut}`,\r\n LogOutCallback: `${prefix}/${LogoutActions.LogoutCallback}`,\r\n IdentityRegisterPath: '/account/register',\r\n IdentityManagePath: '/profile'\r\n};\r\n","import * as React from 'react'\r\nimport { LoginWaiting } from './LoginWaiting';\r\nimport { LoginActions, QueryParameterNames, ApplicationPaths } from './ApiAuthorizationConstants';\r\nimport authService, { AuthenticationResultStatus } from '../../api/api-authorization/AuthorizeService';\r\n\r\nexport interface LoginProps {\r\n action: string,\r\n}\r\n\r\nexport interface LoginState {\r\n message: string | undefined | null,\r\n}\r\n\r\n// The main responsibility of this component is to handle the user's login process.\r\n// This is the starting point for the login process. Any component that needs to authenticate\r\n// a user can simply perform a redirect to this component with a returnUrl query parameter and\r\n// let the component perform the login and return back to the return url.\r\nexport class Login extends React.Component {\r\n constructor(props: LoginProps) {\r\n super(props);\r\n\r\n this.state = {\r\n message: undefined\r\n };\r\n }\r\n\r\n componentDidMount() {\r\n const action = this.props.action;\r\n switch (action) {\r\n case LoginActions.Login:\r\n this.login(this.getReturnUrl());\r\n break;\r\n case LoginActions.LoginCallback:\r\n this.processLoginCallback();\r\n break;\r\n case LoginActions.LoginFailed:\r\n const params = new URLSearchParams(window.location.search);\r\n const error = params.get(QueryParameterNames.Message);\r\n this.setState({ message: error });\r\n break;\r\n case LoginActions.Profile:\r\n this.redirectToProfile();\r\n break;\r\n case LoginActions.Register:\r\n this.redirectToRegister();\r\n break;\r\n default:\r\n throw new Error(`Invalid action '${action}'`);\r\n }\r\n }\r\n\r\n render() {\r\n const action = this.props.action;\r\n const { message } = this.state;\r\n\r\n switch (action) {\r\n case LoginActions.Login:\r\n return ();\r\n case LoginActions.LoginCallback:\r\n return ();\r\n case LoginActions.Profile:\r\n case LoginActions.Register:\r\n return ();\r\n default:\r\n throw new Error(`Invalid action '${action}'`);\r\n }\r\n }\r\n\r\n async login(returnUrl: string) {\r\n const state = { returnUrl };\r\n const result = await authService.signIn(state);\r\n switch (result.status) {\r\n case AuthenticationResultStatus.Redirect:\r\n break;\r\n case AuthenticationResultStatus.Success:\r\n await this.navigateToReturnUrl(returnUrl);\r\n break;\r\n case AuthenticationResultStatus.Fail:\r\n this.setState({ message: result.message });\r\n break;\r\n default:\r\n throw new Error(`Invalid status result ${result.status}.`);\r\n }\r\n }\r\n\r\n async processLoginCallback() {\r\n const url = window.location.href;\r\n const result = await authService.completeSignIn(url);\r\n switch (result.status) {\r\n case AuthenticationResultStatus.Redirect:\r\n // There should not be any redirects as the only time completeSignIn finishes\r\n // is when we are doing a redirect sign in flow.\r\n throw new Error('Should not redirect.');\r\n case AuthenticationResultStatus.Success:\r\n await this.navigateToReturnUrl(this.getReturnUrl(result.state));\r\n break;\r\n case AuthenticationResultStatus.Fail:\r\n this.setState({ message: result.message });\r\n break;\r\n default:\r\n throw new Error(`Invalid authentication result status '${result.status}'.`);\r\n }\r\n }\r\n\r\n getReturnUrl(state?: any) {\r\n const params = new URLSearchParams(window.location.search);\r\n const fromQuery = params.get(QueryParameterNames.ReturnUrl);\r\n if (fromQuery && !fromQuery.startsWith(`${window.location.origin}/`)) {\r\n // This is an extra check to prevent open redirects.\r\n throw new Error(\"Invalid return url. The return url needs to have the same origin as the current page.\")\r\n }\r\n return (state && state.returnUrl) || fromQuery || `${window.location.origin}/`;\r\n }\r\n\r\n redirectToRegister() {\r\n this.redirectToApiAuthorizationPath(`${ApplicationPaths.IdentityRegisterPath}?${QueryParameterNames.ReturnUrl}=${encodeURIComponent(ApplicationPaths.Login)}`);\r\n }\r\n\r\n redirectToProfile() {\r\n this.redirectToApiAuthorizationPath(ApplicationPaths.IdentityManagePath);\r\n }\r\n\r\n redirectToApiAuthorizationPath(apiAuthorizationPath: string) {\r\n const redirectUrl = `${window.location.origin}${apiAuthorizationPath}`;\r\n // It's important that we do a replace here so that when the user hits the back arrow on the\r\n // browser he gets sent back to where it was on the app instead of to an endpoint on this\r\n // component.\r\n window.location.replace(redirectUrl);\r\n }\r\n\r\n navigateToReturnUrl(returnUrl: string) {\r\n // It's important that we do a replace here so that we remove the callback uri with the\r\n // fragment containing the tokens from the browser history.\r\n window.location.replace(returnUrl);\r\n }\r\n}\r\n","import * as React from 'react';\r\nimport { LogoutActions, QueryParameterNames, ApplicationPaths } from './ApiAuthorizationConstants';\r\nimport { LoginWaiting } from './LoginWaiting';\r\nimport authService, { AuthenticationResultStatus } from '../../api/api-authorization/AuthorizeService';\r\nimport { Redirect } from 'react-router';\r\n\r\nexport interface LogoutProps {\r\n action: string,\r\n}\r\n\r\nexport interface LogoutState {\r\n message: string | undefined,\r\n isReady: boolean,\r\n authenticated: boolean,\r\n}\r\n\r\n// The main responsibility of this component is to handle the user's logout process.\r\n// This is the starting point for the logout process, which is usually initiated when a\r\n// user clicks on the logout button on the LoginMenu component.\r\nexport class Logout extends React.Component {\r\n constructor(props: LogoutProps) {\r\n super(props);\r\n\r\n this.state = {\r\n message: undefined,\r\n isReady: false,\r\n authenticated: false\r\n };\r\n }\r\n\r\n componentDidMount() {\r\n const action = this.props.action;\r\n switch (action) {\r\n case LogoutActions.Logout:\r\n if (!!window.history.state.state.local) {\r\n this.logout(this.getReturnUrl());\r\n } else {\r\n // This prevents regular links to /authentication/logout from triggering a logout\r\n this.setState({ isReady: true, message: \"The logout was not initiated from within the page.\" });\r\n }\r\n break;\r\n case LogoutActions.LogoutCallback:\r\n this.processLogoutCallback();\r\n break;\r\n case LogoutActions.LoggedOut:\r\n this.setState({ isReady: true, message: \"You successfully logged out!\" });\r\n break;\r\n default:\r\n throw new Error(`Invalid action '${action}'`);\r\n }\r\n\r\n this.populateAuthenticationState();\r\n }\r\n\r\n render() {\r\n const { isReady, message } = this.state;\r\n if (!isReady) {\r\n return ();\r\n }\r\n\r\n const action = this.props.action;\r\n switch (action) {\r\n case LogoutActions.Logout:\r\n return ();\r\n case LogoutActions.LogoutCallback:\r\n return ();\r\n case LogoutActions.LoggedOut:\r\n return ();\r\n default:\r\n throw new Error(`Invalid action '${action}'`);\r\n } }\r\n\r\n async logout(returnUrl: string) {\r\n const state = { returnUrl };\r\n const isauthenticated = await authService.isAuthenticated();\r\n if (isauthenticated) {\r\n const result = await authService.signOut(state);\r\n switch (result.status) {\r\n case AuthenticationResultStatus.Redirect:\r\n break;\r\n case AuthenticationResultStatus.Success:\r\n await this.navigateToReturnUrl(returnUrl);\r\n break;\r\n case AuthenticationResultStatus.Fail:\r\n this.setState({ message: result.message });\r\n break;\r\n default:\r\n throw new Error(\"Invalid authentication result status.\");\r\n }\r\n } else {\r\n this.setState({ message: \"You successfully logged out!\" });\r\n }\r\n }\r\n\r\n async processLogoutCallback() {\r\n const url = window.location.href;\r\n const result = await authService.completeSignOut(url);\r\n switch (result.status) {\r\n case AuthenticationResultStatus.Redirect:\r\n // There should not be any redirects as the only time completeAuthentication finishes\r\n // is when we are doing a redirect sign in flow.\r\n throw new Error('Should not redirect.');\r\n case AuthenticationResultStatus.Success:\r\n await this.navigateToReturnUrl(this.getReturnUrl(result.state));\r\n break;\r\n case AuthenticationResultStatus.Fail:\r\n this.setState({ message: result.message });\r\n break;\r\n default:\r\n throw new Error(\"Invalid authentication result status.\");\r\n }\r\n }\r\n\r\n async populateAuthenticationState() {\r\n const authenticated = await authService.isAuthenticated();\r\n this.setState({ isReady: true, authenticated });\r\n }\r\n\r\n getReturnUrl(state?: any) {\r\n const params = new URLSearchParams(window.location.search);\r\n const fromQuery = params.get(QueryParameterNames.ReturnUrl);\r\n if (fromQuery && !fromQuery.startsWith(`${window.location.origin}/`)) {\r\n // This is an extra check to prevent open redirects.\r\n throw new Error(\"Invalid return url. The return url needs to have the same origin as the current page.\")\r\n }\r\n return (state && state.returnUrl) ||\r\n fromQuery ||\r\n `${window.location.origin}${ApplicationPaths.LoggedOut}`;\r\n }\r\n\r\n navigateToReturnUrl(returnUrl: string) {\r\n return window.location.replace(returnUrl);\r\n }\r\n}\r\n","import { Login } from './Login'\r\nimport { Logout } from './Logout'\r\nimport { RouteEntry } from '../../shared/routes';\r\n\r\nexport const apiAuthorizationRoutes: Array = [\r\n { path: '/authentication/login', render: () => loginAction('login') },\r\n { path: '/authentication/login-callback', render: () => loginAction('login-callback') },\r\n { path: '/authentication/login-failed', render: () => loginAction('login-failed') },\r\n { path: '/authentication/profile', render: () => loginAction('profile') },\r\n { path: '/authentication/register', render: () => loginAction('register') },\r\n\r\n { path: '/authentication/logout', render: () => logoutAction('logout') },\r\n { path: '/authentication/logout-callback', render: () => logoutAction('logout-callback') },\r\n { path: '/authentication/logged-out', render: () => logoutAction('logged-out') },\r\n];\r\n\r\nfunction loginAction(name: string){\r\n return ();\r\n}\r\n\r\nfunction logoutAction(name: string) {\r\n return ();\r\n}\r\n","import { ErrorMessageConverter } from \"./ErrorMessageConverter\";\r\n\r\n/**\r\n * Register all converters to use for error messages when calling userFriendlyErrorMessage().\r\n * \r\n * Convters will be run in array order, with the first non-null/undefined result being returned as the error message.\r\n * \r\n * @param converters\r\n */\r\nexport function registerErrorMessageConverters(converters: Array): void {\r\n configuredErrorMessageConverters = converters;\r\n}\r\n\r\n/**\r\n * Currently registered ErrorMessageConvters set by registerErrorMessageConverters().\r\n */\r\nexport let configuredErrorMessageConverters: Array = [];","import * as React from 'react';\r\nimport { Alert, AlertProps, Row, Col, Badge } from 'reactstrap';\r\nimport { userFriendlyErrorMessage, FriendlyErrorMessage } from '../userFriendlyErrorMessage';\r\nimport { FontAwesomeIcon } from '@fortawesome/react-fontawesome';\r\nimport { ConditionalFragment } from 'react-conditionalfragment';\r\n\r\n\r\nexport interface AlertOnErrorsProps extends AlertProps {\r\n errors?: any,\r\n children?: any,\r\n simple?: boolean,\r\n}\r\n\r\n/**\r\n * Alert that shows an if error is set.\r\n * @param props\r\n */\r\nexport const AlertOnErrors = (props: AlertOnErrorsProps) => {\r\n const { errors, color, simple, ...rest } = props;\r\n\r\n const [openErrors, setOpenErrors] = React.useState>([]);\r\n const isOpen = React.useCallback((key: string) => !!openErrors.find(it => it === key), [openErrors]);\r\n const toggleOpen = React.useCallback((key: string) => {\r\n setOpenErrors(prevState => {\r\n if (prevState.find(it => it === key)) {\r\n return prevState.filter(it => it !== key);\r\n } else {\r\n return [...prevState, key];\r\n }\r\n });\r\n }, [setOpenErrors]);\r\n\r\n // Get the friendly version of each error.\r\n const friendlyErrors = React.useMemo(() => {\r\n // Flatten up to three levels of errors (wrapping in our own array first) and removing any\r\n // empty items (e.g. null, undefined, '').\r\n let flatErrors = [errors].flat(4).filter(item => item ? true : false);\r\n\r\n // Make friendly versions of all the error messages.\r\n const ret: Array = [flatErrors.map(error => userFriendlyErrorMessage(error))].flat(2);\r\n return ret;\r\n }, [errors])\r\n\r\n // Group errors with the same message together.\r\n const errorGroups = React.useMemo(() => {\r\n let groups: Array<{ message: string, errors: Array }> = [];\r\n\r\n for (const error of friendlyErrors) {\r\n let group = groups.find(item => item.message === error.message);\r\n if (!group) {\r\n group = { message: error.message, errors: [] };\r\n groups.push(group);\r\n }\r\n\r\n group.errors.push(error);\r\n }\r\n\r\n return groups;\r\n }, [friendlyErrors]);\r\n \r\n // If we have no errors, return nothing.\r\n if (!friendlyErrors.length) {\r\n return null;\r\n }\r\n\r\n // If we are in simple mode, return a list of friendly messages with no grouping or options to expand for more details.\r\n if (!!simple) {\r\n return (\r\n \r\n {props.children}\r\n\r\n {\r\n friendlyErrors.map((item, index) => (\r\n
\r\n {item.message}\r\n
\r\n ))\r\n }\r\n
\r\n );\r\n }\r\n\r\n // If we are not in simple mode (the default) then provide an interactive list of errors with grouping and the ability to expand for more\r\n // details if the user wants to.\r\n return (\r\n \r\n {props.children}\r\n {\r\n errorGroups.map(item => (\r\n
\r\n \r\n \r\n
toggleOpen(item.message)} style={{ cursor: 'pointer' }}>\r\n \r\n <> {\r\n item.errors.length > 1 ? (\r\n \r\n {item.errors.length}\r\n \r\n ) : (\r\n \r\n \r\n \r\n )\r\n }\r\n 1}>\r\n <> \r\n \r\n
\r\n \r\n \r\n
\r\n {item.message}\r\n
\r\n \r\n {\r\n item.errors.map((error, index) => (\r\n
\r\n \r\n
\r\n {error.details}\r\n
\r\n
\r\n \r\n {JSON.stringify(error?.error, null, 4)}\r\n \r\n
\r\n ))\r\n }\r\n
\r\n \r\n
\r\n
\r\n ))\r\n }\r\n
\r\n );\r\n};\r\n","import { isNullOrUndefined } from \"util\";\r\nimport { configuredErrorMessageConverters } from \"./registerErrorMessageConverters\";\r\nimport { FriendlyErrorMessage } from \"./FriendlyErrorMessage\";\r\n\r\n/**\r\n * Translate an error message into a user friendly message, also giving the option for wrapping the message for translation if required\r\n * and seperating out additional details from the core error message.\r\n * \r\n * @param error the original error.\r\n */\r\nexport function userFriendlyErrorMessage(error: any): FriendlyErrorMessage | Array {\r\n // Give each converter in order a chance to handle the error until one does.\r\n for (const converter of configuredErrorMessageConverters) {\r\n const friendly = converter(error);\r\n if (!isNullOrUndefined(friendly)) {\r\n if (Array.isArray(friendly)) {\r\n return friendly as Array;\r\n } else if ((friendly as FriendlyErrorMessage)?.error) {\r\n return friendly as FriendlyErrorMessage;\r\n } else {\r\n return { message: friendly as string, error: error };\r\n }\r\n }\r\n }\r\n\r\n // Give up and return the error with a basic wrapper.\r\n return {\r\n message: error?.message ?? error?.toString,\r\n error: error\r\n };\r\n}","import * as React from 'react';\r\nimport { ModelChanges } from './ModelChanges';\r\n\r\n/**\r\n * Hook that makes it easy to apply changes ontop of original data.\r\n */\r\nexport function useChanges(unchanged: T | undefined | null, initialChanges: Partial = {}): ModelChanges {\r\n // Store changes in the state.\r\n const [changes, setChanges] = React.useState>(initialChanges);\r\n\r\n // Provide a method to apply a change or set of changes.\r\n const change = React.useCallback((changes: Partial) => {\r\n\r\n setChanges(prevState =>({\r\n ...prevState,\r\n ...changes\r\n }));\r\n }, [setChanges]);\r\n\r\n // Provide a method to reset all changes.\r\n const reset = React.useCallback(() => {\r\n setChanges({});\r\n }, [setChanges]);\r\n\r\n // Combine the initial model with the changes to produce model with its current state.\r\n const model = React.useMemo((): T => {\r\n return {\r\n ...(unchanged ?? {} as T), ...changes\r\n };\r\n }, [unchanged, changes]);\r\n\r\n // Combine everything into a return value and return it (caching it with useMemo()).\r\n const ret = React.useMemo(() => ({\r\n change: change,\r\n changes: changes,\r\n reset: reset,\r\n model: model\r\n }), [changes, change, reset, model]);\r\n\r\n return ret;\r\n}","import * as React from 'react';\r\nimport { ModelArrayChanges } from './ModelArrayChanges';\r\nimport { isNullOrUndefined } from 'util';\r\n\r\n/**\r\n * An item in a changed array.\r\n */\r\ninterface ModelArrayItemChanges {\r\n key: Key,\r\n unchanged: T | undefined | null,\r\n changes: Partial,\r\n isAddition: boolean,\r\n isRemoval: boolean,\r\n hasUnsavedChanges: boolean,\r\n}\r\n\r\n/**\r\n * Hook that makes it easy to apply changes to multiple items in an array ontop of original data.\r\n */\r\nexport function useChangesArray(unchanged: Array | undefined | null, getKey: (item: T) => Key): ModelArrayChanges {\r\n // Store changes to be layered ontop of unchangedRecords in the state.\r\n const [_changes, setChanges] = React.useState>>([]);\r\n\r\n // When unchanged changes, make sure we merge those source changes \"under\" the changes that come from calling change/changeFor and friends.\r\n React.useEffect(() => {\r\n setChanges(prevState => {\r\n // Loop over each unchanged item and see if we need to add it to our list of changes.\r\n // NOTE because out unchanged may have come from a filter() or map() statement we look for changes\r\n // in the array contents not array reference for performance reasons rather than just assuming\r\n // a change to unchanged needs a state change. This is what hasAnythingChanged handles for us.\r\n let ret: Array> = [];\r\n let hasAnythingChanged = false;\r\n\r\n // Update each change in unchangedRecord into the tracked changes.\r\n for (let unchangedItem of unchanged ?? []) {\r\n const unchangedItemKey = getKey(unchangedItem);\r\n let changeRecord = prevState.find(item => item.key === unchangedItemKey);\r\n\r\n // Check if we have the same underlying unchanged object.\r\n if (changeRecord) {\r\n if (changeRecord.unchanged !== unchangedItem) {\r\n // Update the unchanged item.\r\n changeRecord.unchanged = unchangedItem;\r\n hasAnythingChanged = true;\r\n }\r\n\r\n // Push to ret \r\n ret.push(changeRecord);\r\n } else {\r\n // Add a new unchanged record.\r\n ret.push({\r\n key: unchangedItemKey,\r\n unchanged: unchangedItem,\r\n changes: {},\r\n isAddition: false,\r\n isRemoval: false,\r\n hasUnsavedChanges: false,\r\n });\r\n hasAnythingChanged = true;\r\n }\r\n }\r\n\r\n // Loop over all the previous items and if any of those have disapeared from the underlying source, make remove them.\r\n for (const oldItem of prevState) {\r\n // If this item never existed in the unchanged list then we need to add it to ret and continue.\r\n if (!oldItem.unchanged) {\r\n if (!ret.find(item => item === oldItem)) {\r\n ret.push(oldItem);\r\n }\r\n continue;\r\n }\r\n\r\n // Find the item in the old.\r\n const oldItemKey = getKey(oldItem.unchanged);\r\n const existsInUnchanged = !!unchanged?.find(item => getKey(item) === oldItemKey);\r\n if (!existsInUnchanged) {\r\n ret = ret?.filter(it => it !== oldItem);\r\n hasAnythingChanged = true;\r\n }\r\n }\r\n\r\n // If nothing has changed, return the unchanged state.\r\n if (!hasAnythingChanged) {\r\n return prevState;\r\n }\r\n\r\n // Return the updated state.\r\n return ret;\r\n });\r\n }, [unchanged, getKey, setChanges]);\r\n\r\n // Provide a method to apply a change or set of changes.\r\n // NOTE a side effect of this code is that the first time we make any change, we'll be creating a record for everything from unchangedRecords\r\n // into _changes for ease in the future.\r\n // we can't do that before this point as we allow unchanged to be passed in with new values after the state of _changes is originally set.\r\n const change = React.useCallback((newArray: Array) => {\r\n setChanges(prevState => {\r\n let newState = [...prevState];\r\n let keysInNewArray = [];\r\n\r\n // Loop over each item in the array and find its matching changes\r\n for (let newChanges of newArray) {\r\n let key = getKey(newChanges);\r\n keysInNewArray.push(key);\r\n let changeRecord = prevState.find(it => it.key === key);\r\n\r\n // If we don't have a change record for this item, see if we have an unchanged record\r\n if (!changeRecord) {\r\n // Add as an addition.\r\n newState.push({\r\n key: key,\r\n unchanged: null,\r\n changes: newChanges,\r\n isAddition: true,\r\n isRemoval: false,\r\n hasUnsavedChanges: true,\r\n });\r\n } else {\r\n // Update the changes in the change record.\r\n changeRecord.changes = { ...changeRecord.changes, ...newChanges };\r\n changeRecord.hasUnsavedChanges = true;\r\n }\r\n }\r\n\r\n // Loop over anything that wasn't in array and mark it is removed.\r\n for (let changeRecord of newState) {\r\n if (!keysInNewArray.find(it => it === changeRecord.key)) {\r\n changeRecord.isRemoval = true;\r\n changeRecord.hasUnsavedChanges = true;\r\n }\r\n }\r\n\r\n return newState;\r\n });\r\n }, [setChanges, getKey]);\r\n\r\n // Provide a method to reset all changes.\r\n const reset = React.useCallback(() => {\r\n setChanges([]);\r\n }, [setChanges]);\r\n\r\n // Combine the initial model with the changes to produce model with its current state.\r\n const modelFromChanges = React.useCallback((changesToUse: Array>): Array => {\r\n let ret = [];\r\n\r\n for (let item of changesToUse) {\r\n // Merge the original and the change into a model.\r\n ret.push({ ...(item.unchanged ?? {}), ...item.changes } as T);\r\n }\r\n\r\n return ret;\r\n }, []);\r\n\r\n const model = React.useMemo(() => modelFromChanges(_changes.filter(it => !it.isRemoval)), [_changes, modelFromChanges]);\r\n const added = React.useMemo(() => modelFromChanges(_changes.filter(it => it.isAddition && !it.isRemoval && it.hasUnsavedChanges)), [_changes, modelFromChanges]);\r\n const removed = React.useMemo(() => modelFromChanges(_changes.filter(it => it.isRemoval && !it.isAddition && it.hasUnsavedChanges)), [_changes, modelFromChanges]);\r\n const updated = React.useMemo(() => modelFromChanges(_changes.filter(it => !it.isAddition && !it.isRemoval && Object.keys(it.changes).length && it.hasUnsavedChanges)), [_changes, modelFromChanges]);\r\n\r\n // Combine everything into a return value and return it (caching it with useMemo()).\r\n const ret = React.useMemo(() => ({\r\n model: model,\r\n change: change,\r\n reset: reset,\r\n\r\n added: added,\r\n removed: removed,\r\n updated: updated,\r\n \r\n modelFor: (key: Key) => {\r\n const changeRecord = _changes.find(it => it.key === key);\r\n if (!changeRecord) {\r\n return null;\r\n }\r\n\r\n return { ...(changeRecord.unchanged ?? {}), ...changeRecord.changes } as T;\r\n },\r\n changeFor: (key: Key, newChanges: Partial) => {\r\n setChanges(prevState => {\r\n let newState = [...prevState];\r\n\r\n // Find the key in question\r\n let changeRecord = prevState.find(it => it.key === key);\r\n\r\n // If we don't have a change record for this item, add it as an addition.\r\n if (!changeRecord) {\r\n newState.push({\r\n key: key,\r\n unchanged: null,\r\n changes: newChanges,\r\n isAddition: true,\r\n isRemoval: false,\r\n hasUnsavedChanges: true,\r\n });\r\n } else {\r\n // Update the changes in the change record.\r\n changeRecord.changes = { ...changeRecord.changes, ...newChanges };\r\n changeRecord.hasUnsavedChanges = true;\r\n }\r\n\r\n return newState;\r\n });\r\n },\r\n changesFor: (key: Key) => {\r\n const changeRecord = _changes.find(it => it.key === key);\r\n if (!changeRecord) {\r\n return {};\r\n }\r\n\r\n return changeRecord.changes;\r\n },\r\n addFor: (item: Partial) => {\r\n var key = getKey(item as T);\r\n setChanges(prevState => {\r\n let newState = [...prevState];\r\n\r\n // Find the key in question\r\n let changeRecord = prevState.find(it => it.key === key);\r\n if (!changeRecord) {\r\n newState.push({\r\n key: key,\r\n unchanged: null,\r\n changes: item,\r\n isAddition: true,\r\n isRemoval: false,\r\n hasUnsavedChanges: true,\r\n });\r\n } else if (changeRecord.isRemoval) {\r\n // If we are added after being removed then mark ourselves as not removed and reset our changes to the passed in model.\r\n changeRecord.isRemoval = false;\r\n changeRecord.changes = item;\r\n } else {\r\n // We were asked to add something that already exists, silently ignore that.\r\n // TODO would we be better throwing an exception?\r\n }\r\n\r\n return newState;\r\n });\r\n },\r\n removeFor: (key: Key) => {\r\n setChanges(prevState => {\r\n let newState = [...prevState];\r\n\r\n // Find the key in question\r\n let changeRecord = prevState.find(it => it.key === key);\r\n if (changeRecord) {\r\n changeRecord.isRemoval = true;\r\n changeRecord.hasUnsavedChanges = true;\r\n }\r\n\r\n return newState;\r\n });\r\n },\r\n\r\n /**\r\n * Mark the current changes for this model as saved.\r\n */\r\n markAsSaved: (models?: Array) => {\r\n setChanges(prevState => {\r\n let newState: Array> = [...prevState];\r\n let hasChangedSomething = false;\r\n const keysToCheck = models ? models.map(item => getKey(item)) : null;\r\n\r\n for (const item of prevState) {\r\n // If we were passed in an array of items to mark, then make sure this is in the array before marking it as complete\r\n // (if we don't get an array passed in then everything gets marked as complete).\r\n if (!isNullOrUndefined(keysToCheck)) {\r\n if (!keysToCheck.find(it => it === item.key)) {\r\n continue;\r\n }\r\n }\r\n\r\n // Mark as all changes having been saved.\r\n item.hasUnsavedChanges = false;\r\n\r\n // Saved additions should also no longer be marked as additions (but removals are fine to be left marked as removals.)\r\n item.isAddition = false;\r\n\r\n hasChangedSomething = true;\r\n }\r\n\r\n // If we didn't end up changing anything then end without having made any changes.\r\n if (!hasChangedSomething) {\r\n return prevState;\r\n }\r\n\r\n // Otherwise set our new state.\r\n return newState;\r\n });\r\n },\r\n }), [_changes, setChanges, change, reset, model, added, removed, updated, getKey]);\r\n\r\n return ret;\r\n}\r\n","import './externalLoginButton.scss';\r\n\r\nimport * as React from 'react';\r\nimport { ButtonProps, Button } from 'reactstrap';\r\nimport { FontAwesomeIcon } from '@fortawesome/react-fontawesome';\r\nimport { IconProp } from '@fortawesome/fontawesome-svg-core';\r\nimport { useTranslation } from 'react-i18next';\r\n\r\nexport interface ExternalLoginButtonProps extends ButtonProps {\r\n provider: string,\r\n providerDisplayName?: string,\r\n}\r\n\r\ninterface ProviderDisplayOptions {\r\n text: string,\r\n icon: IconProp,\r\n className: string,\r\n}\r\n\r\n/**\r\n * Button for a an external service that can be used to log in. \r\n */\r\nexport const ExternalLoginButton = (props: ExternalLoginButtonProps) => {\r\n const { t } = useTranslation();\r\n const { provider, providerDisplayName, className: propsClassName, ...rest } = props;\r\n\r\n const { text, icon, className } = React.useMemo((): ProviderDisplayOptions => {\r\n switch (provider) {\r\n case 'Microsoft':\r\n return { text: t('externalLoginButton.microsoftAccountProviderText', 'Microsoft Account'), icon: ['fab', 'microsoft'], className: 'microsoft' };\r\n case 'Google':\r\n return { text: providerDisplayName ?? provider, icon: ['fab', 'google'], className: 'google' };\r\n case 'Facebook':\r\n return { text: providerDisplayName ?? provider, icon: ['fab', 'facebook'], className: 'facebook' };\r\n case 'Twitter':\r\n return { text: providerDisplayName ?? provider, icon: ['fab', 'twitter'], className: 'twitter' };\r\n default:\r\n return { text: providerDisplayName ?? provider, icon: 'external-link-alt', className: 'other' };\r\n }\r\n }, [provider, providerDisplayName, t]);\r\n\r\n return (\r\n \r\n );\r\n};\r\n","import './formButtons.scss';\r\n\r\nimport * as React from 'react';\r\n\r\nexport interface FormButtonsProps {\r\n className?: string,\r\n noPadding?: boolean,\r\n children: React.ReactNode\r\n}\r\n\r\n/**\r\n * Container for buttons (e.g. sumbit) at the bottom of a form. \r\n */\r\nexport const FormButtons = (props: FormButtonsProps) => {\r\n const { className, children, noPadding = false } = props;\r\n\r\n return (\r\n
\r\n {children}\r\n
\r\n );\r\n};","import './mainContainer.scss'; \r\n\r\nimport * as React from 'react';\r\nimport { Container, ContainerProps } from 'reactstrap';\r\n\r\nexport interface MainContainerProps extends ContainerProps {\r\n color?: 'main' | 'transparent',\r\n}\r\n\r\n/**\r\n * Main container that ensures \r\n */\r\nexport const MainContainer = (props: MainContainerProps) => {\r\n const {\r\n className,\r\n children,\r\n color = 'main',\r\n ...rest } = props;\r\n\r\n return (\r\n \r\n {children}\r\n \r\n );\r\n};","/**\r\n * Service that lets us manage our special PINs used for logging in by some users.\r\n * \r\n * There is a C# version of some of this classes functioality available in DriverPinService.cs.\r\n */\r\nexport class DriverPinService\r\n{\r\n private pinEmailSuffix: string = '@pins.esitudrive.com';\r\n\r\n /**\r\n * Returns the email address to set in the user from the provided PIN.\r\n * @param pin\r\n */\r\n emailFromPin(pin: string): string {\r\n if (pin.endsWith(this.pinEmailSuffix)) {\r\n return pin;\r\n }\r\n\r\n return `${pin}${this.pinEmailSuffix}`;\r\n }\r\n\r\n /**\r\n * Returns true if email is a driver pin email.\r\n * @param email\r\n */\r\n isPinEmail(email: string): boolean {\r\n return email.endsWith(this.pinEmailSuffix);\r\n }\r\n}","\r\n/**\r\n * Rules for a password.\r\n * \r\n * This is designed to mirror PasswordOptions from ASP.NET Core Identity.\r\n */\r\nexport interface PasswordOptions {\r\n requireDigit: boolean,\r\n requiredLength: number,\r\n requireLowercase: boolean,\r\n requireNonAlphanumeric: boolean,\r\n requiredUniqueChars: number,\r\n requireUppercase: boolean\r\n}\r\n\r\n/**\r\n * Default PasswordOptions used when no custom options are supplied.\r\n * \r\n * The default rules match those for ASP.NET Core Identity to make it out-of-the-box compatible with backends using\r\n * ASP.NET Core identity, however there is no dependency on it and it can be used with any backend.\r\n */\r\nexport const defaultPasswordOptions = {\r\n requireDigit: true,\r\n requiredLength: 6,\r\n requireLowercase: true,\r\n requireNonAlphanumeric: true,\r\n requiredUniqueChars: 1,\r\n requireUppercase: true\r\n} as PasswordOptions;\r\n","import i18n from 'i18next';\r\nimport { PasswordOptions, defaultPasswordOptions } from './PasswordOptions';\r\n\r\n/**\r\n * Enforce and describe PasswordOptions.\r\n */\r\nexport class PasswordValidation {\r\n private readonly passwordOptions: PasswordOptions;\r\n\r\n constructor(passwordOptions?: PasswordOptions) {\r\n this.passwordOptions = passwordOptions ?? defaultPasswordOptions;\r\n }\r\n\r\n /**\r\n * Check password against the PasswordOptions and return a success indicator and an array of any errors, and a friendly description of all errors.\r\n * @param password\r\n */\r\n check(password: string): PasswordCheckResults {\r\n let ok = true;\r\n let errors: Array = [];\r\n\r\n if (this.passwordOptions.requiredLength > password.length) {\r\n ok = false;\r\n errors.push(i18n.t('passwordValidation.requiredLengthError', 'must be at least {{requiredLength}} characters long', { requiredLength: this.passwordOptions.requiredLength }));\r\n }\r\n\r\n if (this.passwordOptions.requiredUniqueChars > 1) {\r\n let charMap = Array();\r\n for (let i = 0; i < password.length; ++i) {\r\n let char = password.charAt(i);\r\n if (charMap.indexOf(char) !== -1) {\r\n charMap.push(char);\r\n\r\n // Break if we know enough to let the password pass on this rule.\r\n if (charMap.length > this.passwordOptions.requiredUniqueChars) {\r\n break;\r\n }\r\n }\r\n }\r\n\r\n if (this.passwordOptions.requiredUniqueChars > charMap.length) {\r\n ok = false;\r\n errors.push(i18n.t('passwordValidation.requiredUniqueCharsError', 'must contain at least {{requiredUniqueChars}} unique characters', { requiredUniqueChars: this.passwordOptions.requiredUniqueChars }));\r\n }\r\n }\r\n\r\n if (this.passwordOptions.requireDigit) {\r\n let regExp = new RegExp('.*[0-9].*');\r\n if (!regExp.test(password)) {\r\n ok = false;\r\n errors.push(i18n.t('passwordValidation.requireDigitError', 'must contain a number'));\r\n }\r\n }\r\n\r\n if (this.passwordOptions.requireLowercase) {\r\n let regExp = new RegExp('.*[a-z].*');\r\n if (!regExp.test(password)) {\r\n ok = false;\r\n errors.push(i18n.t('passwordValidation.requireLowercaseError', 'must contain a lowercase letter'));\r\n }\r\n }\r\n\r\n if (this.passwordOptions.requireUppercase) {\r\n let regExp = new RegExp('.*[A-Z].*');\r\n if (!regExp.test(password)) {\r\n ok = false;\r\n errors.push(i18n.t('passwordValidation.requireUppercaseError', 'must contain an uppercase letter'));\r\n }\r\n }\r\n\r\n if (this.passwordOptions.requireNonAlphanumeric) {\r\n let regExp = new RegExp('.*[^0-9a-zA-Z].*');\r\n if (!regExp.test(password)) {\r\n ok = false;\r\n errors.push(i18n.t('passwordValidation.requireNonAlphanumericError', 'must contain a symbol (such as !$%&*@#)'));\r\n }\r\n }\r\n\r\n // Generate a textual description of all errors, or blank if there are no errors for errorDescription.\r\n let errorDescription: string = '';\r\n if (errors.length) {\r\n errorDescription = i18n.t('passwordValidation.errorDescription', 'Password {{errors}}', { errors: errors.join(', ') });\r\n }\r\n\r\n return { valid: ok, errors, errorDescription };\r\n }\r\n}\r\n\r\nexport interface PasswordCheckResults {\r\n valid: boolean,\r\n errors: Array,\r\n errorDescription: string,\r\n}\r\n\r\n","import * as React from 'react';\r\nimport { PasswordCheckResults, PasswordValidation } from './PasswordValidation';\r\nimport { generatePasswordRulesDescrption } from './generatePasswordRulesDescription';\r\n\r\nexport interface PasswordValidationResult {\r\n checkPassword: (password: string) => PasswordCheckResults,\r\n passwordRequirements: string,\r\n}\r\n\r\n/**\r\n * Hook for password validation.\r\n */\r\nexport function usePasswordValidation(): PasswordValidationResult {\r\n let passwordValidation = React.useMemo(() => new PasswordValidation(), []);\r\n let checkPassword = React.useCallback((password: string) => {\r\n return passwordValidation.check(password);\r\n }, [passwordValidation]);\r\n let passwordRequirements = React.useMemo(() => {\r\n return generatePasswordRulesDescrption(passwordValidation);\r\n }, [passwordValidation])\r\n\r\n return {\r\n checkPassword,\r\n passwordRequirements\r\n };\r\n}","import i18n from 'i18next';\r\nimport { PasswordValidation } from \"./PasswordValidation\";\r\n\r\n/**\r\n * Generates a plain text description of the password rules for passwordValidation.\r\n * @param passwordValidation\r\n */\r\nexport function generatePasswordRulesDescrption(passwordValidation: PasswordValidation): string {\r\n const { valid, errors: passwordErrors } = passwordValidation.check('');\r\n if (valid) {\r\n return '';\r\n }\r\n\r\n return i18n.t('generatePasswordRulesDescription.passwordRequirements', 'Your password {{requirements}}.', { requirements: passwordErrors.join(', ')});\r\n}\r\n","import * as React from \"react\";\r\nimport { FormGroup, Label } from \"reactstrap\";\r\nimport { useChanges } from \"../../shared/useChanges\";\r\nimport { useValidatorCallback, ValidateCallback } from \"pojo-validator-react\";\r\nimport { ValidatedInput } from \"pojo-validator-reactstrap\";\r\nimport { useTranslation } from \"react-i18next\";\r\nimport { Guid } from \"guid-string\";\r\nimport { Profile as ProfileModel } from '../../api/main/models/Profile';\r\nimport { useRegisterProfileCallback } from \"../../api/main/profiles/useRegisterProfileCallback\";\r\nimport { ProfileCreateInput } from \"../../api/main/generated/globalTypes\";\r\nimport { ValidationErrors } from \"pojo-validator\";\r\n\r\nexport interface RegisterProfileDetailsProps {\r\n // Public\r\n registerProfile: (userId: string) => Promise,\r\n isRegisteringProfile: boolean,\r\n registerProfileErrors: any,\r\n\r\n validate: ValidateCallback,\r\n validationErrors: ValidationErrors\r\n\r\n // Private\r\n model: ProfileModel,\r\n change: (changes: Partial) => void,\r\n changes: Partial\r\n}\r\n\r\n/**\r\n * Custom hook that lets users of RegisterProfileDetails own the state of the Profile without being aware of its format.\r\n * @param userId\r\n */\r\nexport function useRegisterProfileDetailsProps(): RegisterProfileDetailsProps {\r\n const { t } = useTranslation();\r\n\r\n const [_registerProfile, { isExecuting: isRegisteringProfile, errors: registerProfileErrors }] = useRegisterProfileCallback();\r\n const { model, change, changes } = useChanges(null, { id: Guid.newGuid(), firstName: '', lastName: '', subscriptionId: null, subscriptionTeamId: null, uniqueDriverPin: '' });\r\n\r\n const [validate, validationErrors] = useValidatorCallback((validation, fieldsToCheck) => {\r\n if (!model) {\r\n return;\r\n }\r\n\r\n const rules = {\r\n firstName: () => !model.firstName ? t('registerProfileDetails.firstNameRequired', 'First name is required') : '',\r\n lastName: () => !model.lastName ? t('registerProfileDetails.lastNameRequired', 'Last name is required') : '',\r\n };\r\n\r\n validation.checkRules(rules, fieldsToCheck);\r\n }, [model]);\r\n\r\n const registerProfile = React.useCallback(async (userId: string) => {\r\n await _registerProfile({ ...model, userId: userId } as ProfileCreateInput);\r\n }, [_registerProfile, model]);\r\n\r\n return {\r\n registerProfile: registerProfile,\r\n isRegisteringProfile: isRegisteringProfile,\r\n registerProfileErrors: registerProfileErrors,\r\n\r\n validate: validate,\r\n validationErrors: validationErrors,\r\n\r\n model: model,\r\n change: change,\r\n changes: changes,\r\n };\r\n};\r\n\r\n\r\n/**\r\n * Allow the user to set their personal details on their profile during registration.\r\n */\r\nexport const RegisterProfileDetails = (props: RegisterProfileDetailsProps & { children?: React.ReactNode }) => {\r\n const { model, change, validate, validationErrors, children, } = props;\r\n const { t } = useTranslation();\r\n\r\n // Render the UI.\r\n //\r\n return (\r\n <>\r\n \r\n \r\n change({ firstName: e.currentTarget.value })} onBlur={e => validate('firstName')} validationErrors={validationErrors['firstName']} />\r\n \r\n \r\n \r\n change({ lastName: e.currentTarget.value })} onBlur={e => validate('lastName')} validationErrors={validationErrors['lastName']} />\r\n \r\n\r\n {children}\r\n \r\n );\r\n};\r\n","import { AsyncActionStatus } from '../../../shared/abstractStore';\r\nimport { ProfileCreateInput } from '../generated/globalTypes';\r\nimport { registerProfileMutation, registerProfileMutationVariables } from '../generated/registerProfileMutation';\r\nimport { profileFieldsFragment } from '../models/Profile';\r\nimport { useMutation } from '@apollo/react-hooks';\r\nimport gql from 'graphql-tag';\r\nimport { useAsyncCallback } from 'react-use-async-callback';\r\n\r\n/**\r\n * Get a callback to create a Profile in the store during registration.\r\n */\r\nexport function useRegisterProfileCallback(): [(model: ProfileCreateInput) => Promise, AsyncActionStatus] {\r\n //throw new Error('Users cannot self register for this app.');\r\n\r\n const [mutationAction, { error }] = useMutation(\r\n gql`\r\n mutation registerProfileMutation ($model: ProfileCreateInput!) {\r\n registerProfile(model: $model) {\r\n ...profileFields\r\n }\r\n }\r\n\r\n ${profileFieldsFragment}\r\n `\r\n );\r\n\r\n // Wrap the mutation in a standard callback.\r\n const [action, { isExecuting, errors: actionErrors }] = useAsyncCallback(async (model: ProfileCreateInput) => {\r\n const result = await mutationAction({ variables: { model: model } });\r\n if (result.errors && result.errors.length) {\r\n throw result.errors;\r\n }\r\n }, [mutationAction]);\r\n\r\n return [action, { isExecuting: isExecuting, errors: error ? error.message : actionErrors }];\r\n}\r\n","import { FormGroup, Label, Input } from \"reactstrap\";\r\nimport { useTranslation } from \"react-i18next\";\r\nimport { AlertOnErrors } from \"../../shared/alertOnErrors\";\r\nimport { useProfileForInvite } from \"../../api/main/profiles/useProfileForInvite\";\r\n\r\n/**\r\n * Allow the user to set their personal details on their profile during registration.\r\n */\r\nexport const ConfirmInviteProfileDetails = () => {\r\n const { t } = useTranslation();\r\n\r\n const { data: { model }, errors: loadingErrors } = useProfileForInvite();\r\n\r\n // Render the UI.\r\n //\r\n return (\r\n <>\r\n \r\n\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n );\r\n};\r\n","import * as React from 'react';\r\nimport { useLazyQuery } from \"@apollo/react-hooks\";\r\nimport gql from \"graphql-tag\";\r\nimport { AsyncLoadResult, AsyncLoadOptions } from '../../../shared/abstractStore';\r\nimport { profileForInviteQuery, profileForInviteQueryVariables } from '../generated/profileForInviteQuery';\r\nimport { profileFieldsFragment } from '../models/Profile';\r\nimport { mainApiConfig } from '../../../configure/mainApiConfig';\r\n\r\n/**\r\n * Get a Profile from the store using the information available when confirming an invite.\r\n * \r\n * This exists because useProfile() is secured to only load information for authenticated users. This method exists to use the details of an invite as\r\n * permission to load the details of the related profile.\r\n * \r\n * This version gets its details from the query string invite code.\r\n * \r\n * @param id\r\n * @param options\r\n */\r\nexport function useProfileForInvite(options: AsyncLoadOptions = {}): AsyncLoadResult {\r\n // Get the details from the query string.\r\n const { userId, code } = React.useMemo(() => {\r\n const params = new URLSearchParams(window.location.search);\r\n const userId = params.get('userId') ?? params.get('UserId') ?? '';\r\n const code = params.get('code') ?? params.get('Code') ?? '';\r\n return { userId, code };\r\n }, []);\r\n\r\n // Query the data we need form the api.\r\n const [load, { data, loading, error, refetch }] = useLazyQuery(\r\n gql`\r\n query profileForInviteQuery ($userId: ID!, $code: String!) {\r\n model: profileForInvite(userId: $userId, code: $code) {\r\n ...profileFields\r\n }\r\n }\r\n\r\n ${profileFieldsFragment}\r\n `,\r\n {\r\n variables: {\r\n userId: userId,\r\n code: code\r\n },\r\n fetchPolicy: options.fetchPolicy ?? mainApiConfig.defaultFetchPolicy,\r\n pollInterval: options.pollInterval,\r\n onCompleted: (data) => {\r\n if (options.onCompleted) {\r\n options.onCompleted(data);\r\n }\r\n }\r\n }\r\n );\r\n\r\n // Run the query (unless we are being lazy).\r\n React.useEffect(() => {\r\n if (!options.lazy) {\r\n load();\r\n }\r\n }, [options.lazy, load])\r\n\r\n // Return the results.\r\n const refresh = React.useCallback(async () => { !refetch ? await load() : await refetch(); }, [refetch, load]);\r\n return React.useMemo(() => ({\r\n data: data ?? ({} as any),\r\n refresh: refresh,\r\n isLoading: loading,\r\n errors: error\r\n }), [data, refresh, loading, error]);\r\n}\r\n","import { RouteEntry } from \"../../shared/routes\";\r\nimport { Login } from \"./Login\";\r\nimport { Register } from \"./Register\";\r\nimport { ExternalLoginCallback } from \"./ExternalLoginCallback\";\r\nimport { ConfirmEmail } from \"./ConfirmEmail\";\r\nimport { ForgotPassword } from './ForgotPassword';\r\nimport { ResetPassword } from \"./ResetPassword\";\r\nimport { ConfirmEmailChange } from \"./ConfirmEmailChange\";\r\nimport { ConfirmInvite } from \"./ConfirmInvite\";\r\n\r\nexport const accountRoutes: Array = [\r\n // Account\r\n { path: '/account/login', component: Login },\r\n { path: '/account/register', component: Register },\r\n { path: '/account/externalLogin', component: ExternalLoginCallback },\r\n { path: '/account/forgotPassword', component: ForgotPassword },\r\n { path: '/account/resetPassword', component: ResetPassword },\r\n { path: '/account/confirmEmail', component: ConfirmEmail },\r\n { path: '/account/confirmEmailChange', component: ConfirmEmailChange },\r\n { path: '/account/confirmInvite', component: ConfirmInvite },\r\n];\r\n","import * as React from \"react\";\r\nimport { Form, Alert, FormGroup, Label, CustomInput, Spinner, Row, Col, Card, CardHeader, CardBody } from \"reactstrap\";\r\nimport { AlertOnErrors } from \"../../shared/alertOnErrors\";\r\nimport { Link, useHistory } from \"react-router-dom\";\r\nimport { useChanges } from \"../../shared/useChanges\";\r\nimport { useValidatorCallback } from \"pojo-validator-react\";\r\nimport { ValidatedInput } from \"pojo-validator-reactstrap\";\r\nimport { ButtonAsync } from \"reactstrap-buttonasync\"\r\nimport { LoadingIndicator } from \"../../components/shared/LoadingIndicator\";\r\nimport { useExternalAuthenticationSchemes, useLoginWithPasswordCallback, useStartExternalLoginCallback, useResendConfirmationEmailCallback } from \"../../api/account\";\r\nimport { Login as LoginModel } from '../../api/account/models/Login';\r\nimport { useTranslation } from \"react-i18next\";\r\nimport { ExternalLoginButton } from \"./ExternalLoginButton\";\r\nimport { FormButtons } from \"../shared/FormButtons\";\r\nimport { MainContainer } from \"../shared/MainContainer\";\r\nimport { Background } from \"../shared/background/Background\";\r\nimport { ConditionalFragment } from \"react-conditionalfragment\";\r\nimport { DriverPinService } from \"../../services/DriverPinService\";\r\n\r\n/**\r\n * Login screen.\r\n */\r\nexport const Login = () => {\r\n const { t } = useTranslation();\r\n const { data: { externalAuthenticationSchemes }, isLoading, errors: loadErrors } = useExternalAuthenticationSchemes();\r\n const [login, { isExecuting: isLoggingIn, errors: loginErrors }] = useLoginWithPasswordCallback();\r\n const [startExternalLogin] = useStartExternalLoginCallback();\r\n const [isPendingEmailConfirmation, setIsPendingEmailConfirmation] = React.useState(false);\r\n const history = useHistory();\r\n\r\n const [resendConfirmationEmail, { isExecuting: isResendingConfirmationEmail, errors: resendConfirmationEmailErrors }] = useResendConfirmationEmailCallback();\r\n const [hasSentConfirmationEmail, setHasSentConfirmationEmail] = React.useState(false);\r\n\r\n const { model, change } = useChanges({ email: '', password: '', rememberMe: true });\r\n\r\n // Need the URL to pass on to registration or 2faif we redirect to it.\r\n const params = new URLSearchParams(window.location.search);\r\n const returnUrl = params.get('returnUrl') ?? params.get('ReturnUrl') ?? '';\r\n\r\n // Are we using a PIN to login?\r\n const isUsingDriverPin = React.useMemo(() => {\r\n if (!model.email) {\r\n return true;\r\n }\r\n\r\n if (model.email.indexOf('@') === -1) {\r\n return true;\r\n }\r\n\r\n const pinService = new DriverPinService();\r\n if (pinService.isPinEmail(model.email)) {\r\n return true;\r\n }\r\n\r\n return false;\r\n }, [model.email]);\r\n\r\n /**\r\n * Validate the model before trying to use it.\r\n */\r\n const [validate, validationErrors] = useValidatorCallback((validation, fieldsToCheck) => {\r\n const rules = {\r\n email: () => !model.email ? t('login.emailRequired', 'Email or PIN is required') : '',\r\n password: () => !isUsingDriverPin && !model.password ? t('login.passwordRequired', 'Password is required') : '',\r\n };\r\n\r\n validation.checkRules(rules, fieldsToCheck);\r\n }, [model, isUsingDriverPin]);\r\n\r\n /**\r\n * Perform a login by and handle the result.\r\n */\r\n const [isDoingFullPageRedirect, setIsDoingFullPageRedirect] = React.useState(false);\r\n const performLogin = React.useCallback(async (): Promise => {\r\n if (!validate()) {\r\n return;\r\n }\r\n\r\n let result = await login(model);\r\n\r\n if (result) {\r\n setIsPendingEmailConfirmation(result.requiresEmailConfirmation);\r\n\r\n if (result.requiresTwoFactor) {\r\n history.push(`/account/loginWithTwoFactor?returnUrl=${encodeURIComponent(result.returnUrl)}`);\r\n }\r\n\r\n // Redirect the whole page (not just the react app) as its likely the returnUrl is handled on the server.\r\n if (result.succeeded) {\r\n // Redirect the whole page (not just react) to the returnUrl to let the server handle as well as the client.\r\n if (!result.requiresEmailConfirmation && !result.requiresTwoFactor) {\r\n setIsDoingFullPageRedirect(true);\r\n window.location.href = result.returnUrl;\r\n }\r\n }\r\n }\r\n }, [login, model, setIsPendingEmailConfirmation, history, validate, setIsDoingFullPageRedirect]);\r\n\r\n // Render the UI.\r\n return (\r\n \r\n \r\n \r\n \r\n

\r\n {t('login.signInHeading', 'Sign in')}\r\n

\r\n
\r\n \r\n
{ e.preventDefault(); await performLogin(); }}>\r\n \r\n {\r\n isPendingEmailConfirmation ?\r\n hasSentConfirmationEmail ? (\r\n \r\n <>{t('login.confirmationEmailHasBeenResent', 'Confirmation link to verify the email for this account has been resent. Please check your email to confirm.')} \r\n { e.preventDefault(); await resendConfirmationEmail(model.email); setHasSentConfirmationEmail(true); }}\r\n isExecuting={isResendingConfirmationEmail}\r\n executingChildren={<>{t('common.sending', 'Sending...')}}>\r\n {t('common.resendEmail', 'Resend email')}\r\n \r\n \r\n ) : (\r\n \r\n <>{t('login.mustConfirmEmailBeforeLogin', 'You need to confirm your account before you can sign in. Please check your email.')} \r\n { e.preventDefault(); await resendConfirmationEmail(model.email); setHasSentConfirmationEmail(true); }}\r\n isExecuting={isResendingConfirmationEmail}\r\n executingChildren={<>{t('common.sending', 'Sending...')}}>\r\n {t('common.resendEmail', 'Resend email')}\r\n \r\n \r\n ) : null\r\n }\r\n \r\n \r\n change({ email: e.currentTarget.value })} onBlur={e => validate('email')} validationErrors={validationErrors['email']} />\r\n \r\n \r\n \r\n \r\n change({ password: e.currentTarget.value })} onBlur={e => validate('password')} validationErrors={validationErrors['password']} />\r\n \r\n \r\n change({ rememberMe: e.currentTarget.checked })} />\r\n \r\n \r\n\r\n \r\n \r\n \r\n \r\n \r\n {t('login.forgotYourPassword', 'Forgotten your password?')}\r\n \r\n \r\n \r\n \r\n {t('login.loggingIn', 'Signing in...')}}>\r\n {t('login.signIn', 'Sign in')}\r\n \r\n \r\n \r\n\r\n {/*\r\n \r\n \r\n */}\r\n \r\n\r\n
\r\n {\r\n isLoading ? (\r\n \r\n ) : (\r\n <>\r\n
\r\n {\r\n !externalAuthenticationSchemes ? null\r\n : externalAuthenticationSchemes.length !== 0 ? (\r\n <>\r\n
{t('login.useExternalService', 'Or sign in using an identity provider')}
\r\n {\r\n externalAuthenticationSchemes.map((item) => (\r\n startExternalLogin(item.name, returnUrl)} />\r\n ))\r\n }\r\n \r\n )\r\n : null\r\n }\r\n
\r\n \r\n )\r\n }\r\n
\r\n \r\n
\r\n
\r\n
\r\n
\r\n );\r\n};\r\n","import * as React from \"react\";\r\nimport { LoginResult } from \"../../api/account\";\r\nimport { AsyncActionStatus } from \"../../shared/abstractStore\";\r\nimport { useAsyncCallback } from \"react-use-async-callback\";\r\nimport { LoginWithPasswordRequest } from \"./AccountService\";\r\nimport { useAccountService } from \"./useAccountService\";\r\n\r\n/**\r\n * Callback to Login using a password.\r\n */\r\nexport function useLoginWithPasswordCallback(): [(model: LoginWithPasswordRequest) => Promise, AsyncActionStatus] {\r\n const accountService = useAccountService();\r\n\r\n // Get the return url from the query string.\r\n const returnUrl = React.useMemo(() => {\r\n const params = new URLSearchParams(window.location.search);\r\n const returnUrl = params.get('returnUrl') ?? params.get('ReturnUrl') ?? '';\r\n return returnUrl;\r\n }, []);\r\n\r\n const [action, { isExecuting, errors }] = useAsyncCallback(async (model: LoginWithPasswordRequest) => {\r\n let result = await accountService.loginWithPassword(model, returnUrl);\r\n\r\n // If we have additional steps to take before we are completely signed in, handle those now.\r\n if (result.requiresTwoFactor || result.requiresEmailConfirmation) {\r\n // Don't want to redirect to returnUrl.\r\n return result;\r\n }\r\n\r\n // If we get here we have a successful login\r\n\r\n return result;\r\n }, [accountService]);\r\n\r\n return [action, { isExecuting, errors }];\r\n}\r\n","import * as React from \"react\";\r\nimport { Row, Col, Form, Alert, FormGroup, Label, Spinner, FormText, Card, CardHeader, CardBody } from \"reactstrap\";\r\nimport { AlertOnErrors } from \"../../shared/alertOnErrors\";\r\nimport { Link, useHistory } from \"react-router-dom\";\r\nimport { useChanges } from \"../../shared/useChanges\";\r\nimport { useValidatorCallback } from \"pojo-validator-react\";\r\nimport { ValidatedInput } from \"pojo-validator-reactstrap\";\r\nimport { ButtonAsync } from \"reactstrap-buttonasync\"\r\nimport { LoadingIndicator } from \"../../components/shared/LoadingIndicator\";\r\nimport { useExternalAuthenticationSchemes, useStartExternalLoginCallback, useRegisterAccountCallback, useResendConfirmationEmailCallback } from \"../../api/account\";\r\nimport { Register as RegisterModel } from '../../api/account/models/Register';\r\nimport { useTranslation } from \"react-i18next\";\r\nimport { ExternalLoginButton } from \"./ExternalLoginButton\";\r\nimport { FormButtons } from \"../shared/FormButtons\";\r\nimport { usePasswordValidation } from \"../../shared/passwordValidation\";\r\nimport { RegisterProfileDetails, useRegisterProfileDetailsProps } from \"../profiles/RegisterProfileDetails\";\r\nimport { ConditionalFragment } from \"react-conditionalfragment\";\r\nimport { MainContainer } from \"../shared/MainContainer\";\r\nimport { Background } from \"../shared/background/Background\";\r\n\r\n/**\r\n * Register screen.\r\n */\r\nexport const Register = () => {\r\n const { t } = useTranslation();\r\n const { data: { externalAuthenticationSchemes }, isLoading, errors: loadErrors } = useExternalAuthenticationSchemes();\r\n const [register, { isExecuting: isRegistering, errors: registerErrors }] = useRegisterAccountCallback();\r\n const [startExternalLogin] = useStartExternalLoginCallback();\r\n const [isPendingEmailConfirmation, setIsPendingEmailConfirmation] = React.useState(false);\r\n const [resendConfirmationEmail, { isExecuting: isResendingConfirmationEmail, errors: resendConfirmationEmailErrors }] = useResendConfirmationEmailCallback();\r\n const history = useHistory();\r\n\r\n const { checkPassword, passwordRequirements } = usePasswordValidation();\r\n\r\n const { model, change } = useChanges({ email: '', password: '', confirmPassword: '' });\r\n\r\n const registerProfileDetailsProps = useRegisterProfileDetailsProps();\r\n\r\n // Need the URL to pass on to registration or 2faif we redirect to it.\r\n const params = new URLSearchParams(window.location.search);\r\n const returnUrl = params.get('returnUrl') ?? params.get('ReturnUrl') ?? '';\r\n \r\n /**\r\n * Validate the model before trying to use it.\r\n */\r\n const [validate, validationErrors] = useValidatorCallback((validation, fieldsToCheck) => {\r\n const rules = {\r\n email: () => !model.email ? t('register.emailRequired', 'Email is required') : '',\r\n password: () => !model.password ? t('register.passwordRequired', 'Password is required')\r\n : checkPassword(model.password).errorDescription,\r\n confirmPassword: () => model.confirmPassword !== model.password ? t('register.passwordsDoNotMatch', 'The password and confirmation password do not match') : '',\r\n };\r\n\r\n validation.checkRules(rules, fieldsToCheck);\r\n\r\n // Check the profile details as well (ensuring an error reflects in our error state).\r\n validation.singleCheck('profileDetails', !registerProfileDetailsProps.validate(fieldsToCheck), 'Profile details has some validation errors');\r\n }, [model, registerProfileDetailsProps.validate]);\r\n\r\n /**\r\n * Perform a login by and handle the result.\r\n */\r\n const [isDoingFullPageRedirect, setIsDoingFullPageRedirect] = React.useState(false);\r\n const performRegister = React.useCallback(async (): Promise => {\r\n if (!validate()) {\r\n return;\r\n }\r\n\r\n const result = await register(model);\r\n\r\n if (result) {\r\n setIsPendingEmailConfirmation(result.requiresEmailConfirmation);\r\n\r\n // Save the profile.\r\n await registerProfileDetailsProps.registerProfile(result.userId);\r\n\r\n // Now send the initial email confirmation as we have the profile saved, so can address the user by name.\r\n await resendConfirmationEmail(model.email);\r\n\r\n if (result.requiresTwoFactor) {\r\n setIsDoingFullPageRedirect(true);\r\n history.push(`/account/loginWithTwoFactor?returnUrl=${encodeURIComponent(result.returnUrl)}`);\r\n }\r\n\r\n // Redirect the whole page (not just the react app) as its likely the returnUrl is handled on the server.\r\n if (result.succeeded) {\r\n // Redirect the whole page (not just react) to the returnUrl to let the server handle as well as the client.\r\n if (!result.requiresEmailConfirmation && !result.requiresTwoFactor) {\r\n setIsDoingFullPageRedirect(true);\r\n window.location.href = result.returnUrl;\r\n }\r\n }\r\n }\r\n }, [register, model, setIsPendingEmailConfirmation, history, validate, registerProfileDetailsProps, setIsDoingFullPageRedirect, resendConfirmationEmail]);\r\n \r\n // Render the UI.\r\n return (\r\n \r\n \r\n \r\n \r\n

\r\n {t('register.registerNewAccountHeading', 'Register a new account')}\r\n

\r\n
\r\n \r\n \r\n \r\n
{ e.preventDefault(); await performRegister(); }}>\r\n \r\n\r\n \r\n \r\n \r\n \r\n {t('register.confirmationEmailHasBeenResent', 'Please check your email to confirm your account. You won\\'t be able to login until you have confirmed your account.')}\r\n \r\n \r\n { e.preventDefault(); await resendConfirmationEmail(model.email); }}\r\n isExecuting={isResendingConfirmationEmail}\r\n executingChildren={<>{t('common.sending', 'Sending...')}}>\r\n {t('common.resendEmail', 'Resend email')}\r\n \r\n \r\n \r\n \r\n \r\n\r\n \r\n \r\n \r\n change({ email: e.currentTarget.value })} onBlur={e => validate('email')} validationErrors={validationErrors['email']} />\r\n \r\n \r\n \r\n change({ password: e.currentTarget.value })} onBlur={e => validate('password')} validationErrors={validationErrors['password']} />\r\n \r\n {passwordRequirements}\r\n \r\n \r\n \r\n \r\n change({ confirmPassword: e.currentTarget.value })} onBlur={e => validate('confirmPassword')} validationErrors={validationErrors['confirmPassword']} />\r\n \r\n \r\n \r\n\r\n\r\n {/* Repeated because the height of the form on screen is too long for the user to see this at the top */}\r\n \r\n \r\n \r\n \r\n {t('register.confirmationEmailHasBeenResent', 'Please check your email to confirm your account. You won\\'t be able to login until you have confirmed your account.')}\r\n \r\n \r\n { e.preventDefault(); await resendConfirmationEmail(model.email); }}\r\n isExecuting={isResendingConfirmationEmail}\r\n executingChildren={<>{t('common.sending', 'Sending...')}}>\r\n {t('common.resendEmail', 'Resend email')}\r\n \r\n \r\n \r\n \r\n \r\n\r\n \r\n \r\n \r\n \r\n {t('register.login', 'Already have an account? Sign in instead.')}\r\n \r\n \r\n \r\n {t('register.registering', 'Registering...')}}>\r\n {t('register.register', 'Register')}\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n {\r\n isLoading ? (\r\n \r\n ) : (\r\n <>\r\n
{t('register.useExternalService', 'Or register using an identity provider')}
\r\n
\r\n {\r\n !externalAuthenticationSchemes ? null\r\n : externalAuthenticationSchemes.length !== 0 ? (\r\n <>\r\n {\r\n externalAuthenticationSchemes.map((item) => (\r\n
\r\n startExternalLogin(item.name, returnUrl)} />\r\n
\r\n ))\r\n }\r\n \r\n ) : null\r\n }\r\n
\r\n \r\n )\r\n }\r\n \r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n );\r\n};\r\n","import * as React from \"react\";\r\nimport { AsyncActionStatus } from \"../../shared/abstractStore\";\r\nimport { useAsyncCallback } from \"react-use-async-callback\";\r\nimport { RegisterRequest, RegisterResult } from \"./AccountService\";\r\nimport { useAccountService } from \"./useAccountService\";\r\n\r\n/**\r\n * Callback to Register an account.\r\n */\r\nexport function useRegisterAccountCallback(): [(model: RegisterRequest) => Promise, AsyncActionStatus] {\r\n const accountService = useAccountService();\r\n\r\n // Get the return url from the query string.\r\n const returnUrl = React.useMemo(() => {\r\n const params = new URLSearchParams(window.location.search);\r\n const returnUrl = params.get('returnUrl') ?? params.get('ReturnUrl') ?? '';\r\n return returnUrl;\r\n }, []);\r\n\r\n const [action, { isExecuting, errors }] = useAsyncCallback(async (model: RegisterRequest) => {\r\n let result = await accountService.register(model, returnUrl);\r\n\r\n // If we have additional steps to take before we are completely signed in, handle those now.\r\n if (result.requiresTwoFactor || result.requiresEmailConfirmation) {\r\n // Don't want to redirect to returnUrl.\r\n return result;\r\n }\r\n\r\n // If we get here we have a successful login\r\n\r\n return result;\r\n }, [accountService]);\r\n\r\n return [action, { isExecuting, errors }];\r\n}\r\n","import * as React from \"react\";\r\nimport { useCompletedExternalLoginDetails, useCreateAccountForExternalLoginCallback } from \"../../api/account\";\r\nimport { ClaimTypes } from \"../../api/account\";\r\nimport { useChanges } from \"../../shared/useChanges\";\r\nimport { useValidatorCallback } from \"pojo-validator-react\";\r\nimport { AlertOnErrors } from \"../../shared/alertOnErrors\";\r\nimport { LoadingIndicator } from \"../../components/shared/LoadingIndicator\";\r\nimport { FormGroup, Label, Form, Spinner, Card, CardHeader, CardBody } from \"reactstrap\";\r\nimport { ValidatedInput } from \"pojo-validator-reactstrap\";\r\nimport { ButtonAsync } from \"reactstrap-buttonasync\";\r\nimport { ExternalLoginCallback as ExternalLoginCallbackModel } from \"../../api/account/models/ExternalLoginCallback\";\r\nimport { useTranslation } from \"react-i18next\";\r\nimport { RegisterProfileDetails, useRegisterProfileDetailsProps } from \"../profiles/RegisterProfileDetails\";\r\nimport { MainContainer } from \"../shared/MainContainer\";\r\nimport { Background } from \"../shared/background/Background\";\r\n\r\n/**\r\n * Complete an the external login.\r\n */\r\nexport const ExternalLoginCallback = () => {\r\n const { t } = useTranslation();\r\n const { data: { isNewUser, loginProvider, returnUrl, claims }, isLoading, errors: loadErrors } = useCompletedExternalLoginDetails();\r\n const [createAccount, { isExecuting: isCreatingAccount, errors: createAccountErrors }] = useCreateAccountForExternalLoginCallback();\r\n\r\n const registerProfileDetailsProps = useRegisterProfileDetailsProps();\r\n\r\n const { model, change } = useChanges({ email: '' });\r\n const [validate, validationErrors] = useValidatorCallback((validation, fieldsToCheck) => {\r\n if (!model) {\r\n return;\r\n }\r\n\r\n const rules = {\r\n email: () => !model.email ? t('externalLoginCallback.emailRequired', 'Email is required') : '',\r\n };\r\n validation.checkRules(rules, fieldsToCheck);\r\n\r\n // Check the profile details as well (ensuring an error reflects in our error state).\r\n validation.singleCheck('profileDetails', !registerProfileDetailsProps.validate(fieldsToCheck), 'Profile details has some validation errors');\r\n }, [model]);\r\n\r\n // When the data returned by the external login changes, we want to use it to either default some changes or redirect away from the page.\r\n React.useEffect(() => {\r\n // If this is not a new user just redirect to their target page.\r\n if (!isNewUser) {\r\n // Redirect the whole page (not just the react app) as its likely the returnUrl is handled on the server.\r\n window.location.href = returnUrl || '/';\r\n } else {\r\n // Default the email in the model for new users (if the external login provided one).\r\n let emailClaim = claims.find(item => item.type === ClaimTypes.email);\r\n if (emailClaim && emailClaim.value) {\r\n change({ email: emailClaim.value });\r\n }\r\n }\r\n }, [isNewUser, returnUrl, claims, change]);\r\n\r\n // Render the UI.\r\n //\r\n\r\n // If we're not ready, show the loading indicator.\r\n if (isLoading || !isNewUser) {\r\n return (\r\n <>\r\n \r\n \r\n \r\n );\r\n }\r\n\r\n // Render the external login registration view.\r\n return (\r\n \r\n \r\n \r\n \r\n

{t('externalLoginCallback.registerAccountHeading', 'Register with your {{loginProvider}} account', { context: loginProvider, loginProvider: loginProvider })}

\r\n
\r\n \r\n

\r\n {t('externalLOginCallback.registerHelpText', 'You\\'ve successfully authenticated with {loginProvider}. Please enter an email address for this site below and click the Register button to finish logging in.')}\r\n

\r\n \r\n
{\r\n e.preventDefault();\r\n if (!validate()) {\r\n return;\r\n }\r\n\r\n const result = await createAccount(model)\r\n if (result) {\r\n // Save the profile.\r\n await registerProfileDetailsProps.registerProfile(result.userId);\r\n }\r\n }}>\r\n \r\n\r\n\r\n \r\n\r\n \r\n \r\n change({ email: e.currentTarget.value })} onBlur={e => validate('email')} validationErrors={validationErrors['email']} />\r\n \r\n {t('externalLoginCallback.registring', 'Registering...')}}>\r\n {t('externalLoginCallback.register', 'Register')}\r\n \r\n \r\n
\r\n
\r\n
\r\n
\r\n );\r\n};\r\n\r\n","import * as React from \"react\";\r\nimport { AsyncLoadResult, AsyncLoadOptions } from \"../../shared/abstractStore\";\r\nimport { useAsyncCallback } from \"react-use-async-callback\";\r\nimport { CompleteExternalLoginResult } from \"./AccountService\";\r\nimport { useAccountService } from \"./useAccountService\";\r\n\r\n/**\r\n * Details of the external login that has just completed and invoked our callback.\r\n */\r\nexport function useCompletedExternalLoginDetails(options: AsyncLoadOptions = {}): AsyncLoadResult {\r\n const [data, setData] = React.useState({ claims: [], isNewUser: false, loginProvider: '', returnUrl: '' });\r\n\r\n const accountService = useAccountService();\r\n\r\n // Get the details from the external login off the query string.\r\n const { returnUrl, remoteError } = React.useMemo(() => {\r\n const params = new URLSearchParams(window.location.search);\r\n const returnUrl = params.get('returnUrl') ?? params.get('ReturnUrl') ?? '';\r\n const remoteError = params.get('remoteError') ?? params.get('RemoteError') ?? '';\r\n return { returnUrl, remoteError};\r\n }, []);\r\n\r\n const [refresh, { isExecuting: isLoading, errors }] = useAsyncCallback(async () => {\r\n let result = await accountService.completeExternalLogin(returnUrl, remoteError);\r\n setData(result);\r\n }, [accountService, returnUrl, remoteError, setData]);\r\n\r\n React.useEffect(() => {\r\n if (!options.lazy) {\r\n refresh();\r\n }\r\n }, [refresh, options.lazy]);\r\n\r\n // TODO handle options.pollInterval.\r\n\r\n return {\r\n data: data,\r\n refresh: refresh,\r\n isLoading: isLoading,\r\n errors: errors\r\n };\r\n}\r\n","import * as React from \"react\";\r\nimport { AsyncActionStatus } from \"../../shared/abstractStore\";\r\nimport { useAsyncCallback } from \"react-use-async-callback\";\r\nimport { CreateExternalLoginAccountDetails, RegisterResult } from \"./AccountService\";\r\nimport { useAccountService } from \"./useAccountService\";\r\n\r\n/**\r\n * Register an account for an authenticated external login.\r\n */\r\nexport function useCreateAccountForExternalLoginCallback(): [(model: CreateExternalLoginAccountDetails) => Promise, AsyncActionStatus] {\r\n const accountService = useAccountService();\r\n\r\n // Get the return url from the query string.\r\n const returnUrl = React.useMemo(() => {\r\n const params = new URLSearchParams(window.location.search);\r\n const returnUrl = params.get('returnUrl') ?? params.get('ReturnUrl') ?? '';\r\n return returnUrl;\r\n }, []);\r\n\r\n const [action, { isExecuting, errors }] = useAsyncCallback(async (model: CreateExternalLoginAccountDetails) => {\r\n let result = await accountService.createAccountForExternalLogin(model, returnUrl);\r\n\r\n // If we get here everything went well so redirect to the returnUrl.\r\n // Redirect the whole page (not just the react app) as its likely the returnUrl is handled on the server.\r\n window.location.href = result.returnUrl;\r\n\r\n return result;\r\n }, [accountService]);\r\n\r\n return [action, { isExecuting, errors }];\r\n}\r\n","import * as React from \"react\";\r\nimport { Form, Alert, FormGroup, Label, Spinner, Row, Col, CardHeader, Card, CardBody } from \"reactstrap\";\r\nimport { AlertOnErrors } from \"../../shared/alertOnErrors\";\r\nimport { useChanges } from \"../../shared/useChanges\";\r\nimport { useValidatorCallback } from \"pojo-validator-react\";\r\nimport { ValidatedInput } from \"pojo-validator-reactstrap\";\r\nimport { ButtonAsync } from \"reactstrap-buttonasync\";\r\nimport { useSendPasswordResetEmailCallback } from \"../../api/account\";\r\nimport { ForgotPassword as ForgotPasswordModel } from '../../api/account/models/ForgotPassword';\r\nimport { useTranslation } from \"react-i18next\";\r\nimport { FormButtons } from \"../shared/FormButtons\";\r\nimport { Background } from \"../shared/background/Background\";\r\nimport { MainContainer } from \"../shared/MainContainer\";\r\nimport { Link } from \"react-router-dom\";\r\n\r\n/**\r\n * Request a password reset emai because the user has forgotten their password.\r\n */\r\nexport const ForgotPassword = () => {\r\n const { t } = useTranslation();\r\n const [emailSent, setEmailSent] = React.useState(false);\r\n const [sendResetEmail, { isExecuting: isSendingResetEmail, errors: sendResetEmailErrors }] = useSendPasswordResetEmailCallback();\r\n\r\n const { model, change } = useChanges({ email: '' });\r\n\r\n const [validate, validationErrors] = useValidatorCallback((validation, fieldsToCheck) => {\r\n if (!model) {\r\n return;\r\n }\r\n\r\n const rules = {\r\n email: () => !model.email ? t('forgotPassword.emailRequired', 'Email is required') : '',\r\n };\r\n\r\n validation.checkRules(rules, fieldsToCheck);\r\n }, [model]);\r\n\r\n // Render the UI.\r\n // \r\n return (\r\n \r\n \r\n \r\n \r\n

{t('forgotPassword.forgotPasswordHeading', 'Forgot your password?')}

\r\n
\r\n \r\n

\r\n {t('forgotPassword.helpText', 'Enter your email and we\\'ll send you a link you can use to recover your account and set a new password.')}\r\n

\r\n
{\r\n e.preventDefault();\r\n const ok = await sendResetEmail(model.email);\r\n setEmailSent(ok);\r\n }}>\r\n\r\n \r\n {\r\n emailSent ? (\r\n \r\n \r\n \r\n {t('forgotPassword.emailHasBeenSent', 'Please check your email and follow the link to reset your password.')}\r\n \r\n \r\n {t('common.sending', 'Sending...')}}>\r\n {t('common.resendEmail', 'Resend email')}\r\n \r\n \r\n \r\n \r\n ) : null\r\n }\r\n \r\n \r\n change({ email: e.currentTarget.value })} onBlur={e => validate('email')} validationErrors={validationErrors['email']} />\r\n \r\n\r\n \r\n \r\n \r\n \r\n {t('forgottenPassord.forgotYourPassword', 'Remembered your password and want to login instead?')}\r\n \r\n \r\n \r\n {t('common.sending', 'Sending...')}}>\r\n {t('forgottenPassword.send', 'Send password reset email')}\r\n \r\n \r\n \r\n \r\n \r\n
\r\n
\r\n
\r\n
\r\n );\r\n};\r\n","import { AsyncActionStatus } from \"../../shared/abstractStore\";\r\nimport { useAsyncCallback } from \"react-use-async-callback\";\r\nimport { useAccountService } from \"./useAccountService\";\r\n\r\n/**\r\n * Callback to Send a password reset email.\r\n */\r\nexport function useSendPasswordResetEmailCallback(): [(email: string) => Promise, AsyncActionStatus] {\r\n const accountService = useAccountService();\r\n\r\n const [action, { isExecuting, errors }] = useAsyncCallback(async (email: string) => {\r\n return await accountService.sendPasswordResetEmail(email);\r\n }, [accountService]);\r\n\r\n return [action, { isExecuting, errors }];\r\n}\r\n","import * as React from \"react\";\r\nimport { Form, Alert, FormGroup, Label, Spinner, Button, FormText, Row, Col, Card, CardHeader, CardBody } from \"reactstrap\";\r\nimport { useChanges } from \"../../shared/useChanges\";\r\nimport { useValidatorCallback } from \"pojo-validator-react\";\r\nimport { ValidatedInput } from \"pojo-validator-reactstrap\";\r\nimport { ButtonAsync } from \"reactstrap-buttonasync\"\r\nimport { useResetPasswordCallback } from \"../../api/account\";\r\nimport { ResetPassword as ResetPasswordModel } from '../../api/account/models/ResetPassword';\r\nimport { useTranslation } from \"react-i18next\";\r\nimport { LoadingIndicator } from \"../shared/LoadingIndicator\";\r\nimport { LinkContainer } from \"react-router-bootstrap\";\r\nimport { usePasswordValidation } from \"../../shared/passwordValidation\";\r\nimport { FormButtons } from \"../shared/FormButtons\";\r\nimport { Background } from \"../shared/background/Background\";\r\nimport { MainContainer } from \"../shared/MainContainer\";\r\n\r\n/**\r\n * Reset the password (after following a unique link from an email).\r\n */\r\nexport const ResetPassword = () => {\r\n const { t } = useTranslation();\r\n const [hasResetPassword, setHasResetPassword] = React.useState(false);\r\n const [resetPassword, { isExecuting: isResettingPassword, errors: resetPasswordErrors }] = useResetPasswordCallback();\r\n const { checkPassword, passwordRequirements } = usePasswordValidation();\r\n\r\n const { model, change } = useChanges({ password: '', confirmPassword: '' });\r\n const [validate, validationErrors] = useValidatorCallback((validation, fieldsToCheck) => {\r\n if (!model) {\r\n return;\r\n }\r\n\r\n const rules = {\r\n password: () => !model.password ? t('resetPassword.passwordRequired', 'Password is required')\r\n : checkPassword(model.password).errorDescription,\r\n confirmPassword: () => model.confirmPassword !== model.password ? t('register.passwordsDoNotMatch', 'The password and confirmation password do not match') : '',\r\n };\r\n\r\n validation.checkRules(rules, fieldsToCheck);\r\n }, [model]);\r\n \r\n // Render the UI.\r\n //\r\n\r\n // If we're not ready, show the loading indicator.\r\n if (!model) {\r\n return ();\r\n }\r\n\r\n return (\r\n \r\n \r\n \r\n \r\n

{t('resetPassword.resetPasswordHeading', 'Reset Password')}

\r\n
\r\n \r\n

\r\n {t('resetPassword.thanksForConfirmingEmail', 'Thanks for confirming your email. You can now set a new password.')}\r\n

\r\n\r\n
{\r\n e.preventDefault();\r\n if (!validate()) {\r\n return;\r\n }\r\n\r\n const ok = await resetPassword(model.password);\r\n setHasResetPassword(ok);\r\n }}>\r\n {\r\n resetPasswordErrors ? (\r\n \r\n {resetPasswordErrors}\r\n \r\n ) : null\r\n }\r\n {\r\n hasResetPassword ? (\r\n \r\n \r\n \r\n {t('resetPassword.passwordHasBeenReset', 'Your password has been reset.')}\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n ) : null\r\n }\r\n\r\n \r\n \r\n change({ password: e.currentTarget.value })} onBlur={e => validate('password')} validationErrors={validationErrors['password']} />\r\n \r\n {passwordRequirements}\r\n \r\n \r\n \r\n \r\n change({ confirmPassword: e.currentTarget.value })} onBlur={e => validate('confirmPassword')} validationErrors={validationErrors['confirmPassword']} />\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n\r\n {t('resetPassword.resetting', 'Resetting password...')}}>\r\n {t('resetPassword.reset', 'Reset password')}\r\n \r\n \r\n \r\n \r\n \r\n
\r\n
\r\n
\r\n
\r\n
\r\n );\r\n};\r\n","import * as React from \"react\";\r\nimport { AsyncActionStatus } from \"../../shared/abstractStore\";\r\nimport { useAsyncCallback } from \"react-use-async-callback\";\r\nimport { useAccountService } from \"./useAccountService\";\r\n\r\n/**\r\n * Callback to reset the password of an account using a unique URL from an email as authorization.\r\n */\r\nexport function useResetPasswordCallback(): [(password: string) => Promise, AsyncActionStatus] {\r\n const accountService = useAccountService();\r\n\r\n // Get the code from the query string.\r\n const { userId, code } = React.useMemo(() => {\r\n const params = new URLSearchParams(window.location.search);\r\n const userId = params.get('userId') ?? params.get('UserId') ?? '';\r\n const code = params.get('code') ?? params.get('Code') ?? '';\r\n return { userId, code };\r\n }, []);\r\n\r\n const [action, { isExecuting, errors }] = useAsyncCallback(async (password: string) => {\r\n return await accountService.resetPassword({ userId: userId, code: code, password: password });\r\n }, [accountService]);\r\n\r\n return [action, { isExecuting, errors }];\r\n}\r\n","import * as React from \"react\";\r\nimport { Alert, Button, Card, CardBody, CardHeader, Col, Row } from \"reactstrap\";\r\nimport { useConfirmEmailCallback } from \"../../api/account\";\r\nimport { useTranslation } from \"react-i18next\";\r\nimport { LinkContainer } from \"react-router-bootstrap\";\r\nimport { LoadingIndicator } from \"../shared/LoadingIndicator\";\r\nimport { FormButtons } from \"../shared/FormButtons\";\r\nimport { ConditionalFragment } from \"react-conditionalfragment\";\r\nimport { Background } from \"../shared/background/Background\";\r\nimport { MainContainer } from \"../shared/MainContainer\";\r\n\r\n/**\r\n * Confirm an email address for an account using a unique link included in the email. \r\n */\r\nexport const ConfirmEmail = () => {\r\n const { t } = useTranslation();\r\n const [emailConfirmed, setEmailConfirmed] = React.useState(false);\r\n const [confirmEmail, { errors: confirmEmailErrors }] = useConfirmEmailCallback();\r\n\r\n // Trigger the email confirmation on page load.\r\n React.useEffect(() => {\r\n (async () => {\r\n if (!emailConfirmed) {\r\n const ok = await confirmEmail();\r\n setEmailConfirmed(ok);\r\n }\r\n })();\r\n }, [confirmEmail, setEmailConfirmed, emailConfirmed]);\r\n\r\n // Render the UI.\r\n // \r\n return (\r\n \r\n \r\n \r\n \r\n

\r\n {\r\n confirmEmailErrors ? t('confirmEmail.confirmEmailFailureHeading', 'Sorry we cannot confirm your email using this code')\r\n : emailConfirmed ? t('confirmEmail.confirmEmailSuccessHeading', 'Thanks for confirming your email')\r\n : ()\r\n }\r\n

\r\n
\r\n \r\n \r\n \r\n {confirmEmailErrors}\r\n \r\n \r\n \r\n {/**/}\r\n {/* {t('confirmEmail.thankYouForConfirming', 'Thank you for confirming your email. You account setup is now complete.')}*/}\r\n {/**/}\r\n

\r\n {t('confirmEmail.thankYouForConfirming', 'Thank you for confirming your email. You account setup is now complete.')}\r\n

\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n
\r\n
\r\n
\r\n
\r\n
\r\n );\r\n};\r\n","import * as React from \"react\";\r\nimport { AsyncActionStatus } from \"../../shared/abstractStore\";\r\nimport { useAsyncCallback } from \"react-use-async-callback\";\r\nimport { useAccountService } from \"./useAccountService\";\r\n\r\n/**\r\n * Confirm an email address.\r\n */\r\nexport function useConfirmEmailCallback(): [() => Promise, AsyncActionStatus] {\r\n const accountService = useAccountService();\r\n\r\n // Get the return url from the query string.\r\n const { userId, code } = React.useMemo(() => {\r\n const params = new URLSearchParams(window.location.search);\r\n const userId = params.get('userId') ?? params.get('UserId') ?? '';\r\n const code = params.get('code') ?? params.get('Code') ?? '';\r\n return { userId, code };\r\n }, []);\r\n\r\n const [action, { isExecuting, errors }] = useAsyncCallback(async () => {\r\n return await accountService.confirmEmail({ userId: userId, code: code });\r\n }, [accountService, userId, code]);\r\n\r\n return [action, { isExecuting, errors }];\r\n}\r\n","import * as React from \"react\";\r\nimport { Alert, Button, Card, CardBody, CardHeader, Col, Row } from \"reactstrap\";\r\nimport { useConfirmEmailChangeCallback } from \"../../api/account\";\r\nimport { LoadingIndicator } from \"../shared/LoadingIndicator\";\r\nimport { useTranslation } from \"react-i18next\";\r\nimport { LinkContainer } from \"react-router-bootstrap\";\r\nimport { ConditionalFragment } from \"react-conditionalfragment\";\r\nimport { FormButtons } from \"../shared/FormButtons\";\r\nimport { Background } from \"../shared/background/Background\";\r\nimport { MainContainer } from \"../shared/MainContainer\";\r\n\r\n/**\r\n * Confirm an email address change for an account using a unique link included in the email. \r\n */\r\nexport const ConfirmEmailChange = () => {\r\n const { t } = useTranslation();\r\n const [emailConfirmed, setEmailConfirmed] = React.useState(false);\r\n const [confirmEmail, { errors: confirmEmailErrors }] = useConfirmEmailChangeCallback();\r\n\r\n // Trigger the email confirmation on page load.\r\n React.useEffect(() => {\r\n (async () => {\r\n if (!emailConfirmed) {\r\n const ok = await confirmEmail();\r\n setEmailConfirmed(ok);\r\n }\r\n })();\r\n }, [confirmEmail, setEmailConfirmed, emailConfirmed]);\r\n\r\n // Render the UI.\r\n // \r\n return (\r\n \r\n \r\n \r\n \r\n

\r\n {\r\n confirmEmailErrors ? t('confirmEmailChange.confirmEmailChangeFailureHeading', 'Sorry we cannot confirm your change of email using this code')\r\n : emailConfirmed ? t('confirmEmailChange.confirmEmailChangeSuccessHeading', 'Thank you for confirming your change of email.')\r\n : ()\r\n }\r\n

\r\n
\r\n \r\n \r\n \r\n {confirmEmailErrors}\r\n \r\n \r\n \r\n {/**/}\r\n {/* <>{t('confirmEmailChange.thankYouForConfirming', 'Thank you for confirming your change of email. We\\'ve swapped that over for you.')} */}\r\n {/**/}\r\n

\r\n {t('confirmEmailChange.thankYouForConfirming', 'Thank you for confirming your change of email. We\\'ve swapped that over for you.')}\r\n

\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n
\r\n
\r\n
\r\n
\r\n
\r\n );\r\n};\r\n","import * as React from \"react\";\r\nimport { AsyncActionStatus } from \"../../shared/abstractStore\";\r\nimport { useAsyncCallback } from \"react-use-async-callback\";\r\nimport { useAccountService } from \"./useAccountService\";\r\n\r\n/**\r\n * Confirm an email address.\r\n */\r\nexport function useConfirmEmailChangeCallback(): [() => Promise, AsyncActionStatus] {\r\n const accountService = useAccountService();\r\n\r\n // Get the return url from the query string.\r\n const { userId, code, email } = React.useMemo(() => {\r\n const params = new URLSearchParams(window.location.search);\r\n const userId = params.get('userId') ?? params.get('UserId') ?? '';\r\n const code = params.get('code') ?? params.get('Code') ?? '';\r\n const email = params.get('email') ?? params.get('Email') ?? '';\r\n return { userId, code, email };\r\n }, []);\r\n\r\n const [action, { isExecuting, errors }] = useAsyncCallback(async () => {\r\n return await accountService.confirmEmailChange({ userId: userId, code: code, email: email });\r\n }, [accountService, userId, code, email]);\r\n\r\n return [action, { isExecuting, errors }];\r\n}\r\n","import * as React from \"react\";\r\nimport { Form, FormGroup, Label, FormText, Spinner, Row, Col, CardHeader, Card, CardBody } from \"reactstrap\";\r\nimport { useConfirmInviteCallback } from \"../../api/account\";\r\nimport { useTranslation } from \"react-i18next\";\r\nimport { AlertOnErrors } from \"../../shared/alertOnErrors\";\r\nimport { useValidatorCallback } from \"pojo-validator-react\";\r\nimport { useChanges } from \"../../shared/useChanges\";\r\nimport { ConfirmInvite as ConfirmInviteModel } from \"../../api/account/models/ConfirmInvite\";\r\nimport { usePasswordValidation } from \"../../shared/passwordValidation\";\r\nimport { ValidatedInput } from \"pojo-validator-reactstrap\";\r\nimport { FormButtons } from \"../shared/FormButtons\";\r\nimport { ButtonAsync } from \"reactstrap-buttonasync\";\r\nimport { useHistory } from \"react-router\";\r\nimport { ConfirmInviteProfileDetails } from \"../profiles/ConfirmInviteProfileDetails\";\r\nimport { MainContainer } from \"../shared/MainContainer\";\r\nimport { Background } from \"../shared/background/Background\";\r\n\r\n/**\r\n * Confirm an email address and provide registration details as part of an invite.\r\n */\r\nexport const ConfirmInvite = () => {\r\n const { t } = useTranslation();\r\n const [confirmInvite, { isExecuting: isConfirmingInvite, errors: confirmInviteErrors }] = useConfirmInviteCallback();\r\n const { model, change } = useChanges({ password: '', confirmPassword: '' });\r\n const { checkPassword, passwordRequirements } = usePasswordValidation();\r\n const history = useHistory();\r\n\r\n /**\r\n * Validate the model before trying to use it.\r\n */\r\n const [validate, validationErrors] = useValidatorCallback((validation, fieldsToCheck) => {\r\n const rules = {\r\n password: () => !model.password ? t('confirmInvite.passwordRequired', 'Password is required')\r\n : checkPassword(model.password).errorDescription,\r\n confirmPassword: () => model.confirmPassword !== model.password ? t('confirmInvite.passwordsDoNotMatch', 'The password and confirmation password do not match') : '',\r\n };\r\n\r\n validation.checkRules(rules, fieldsToCheck);\r\n }, [model]);\r\n\r\n /**\r\n * Perform a login by and handle the result.\r\n */\r\n const [isDoingFullPageRedirect, setIsDoingFullPageRedirect] = React.useState(false);\r\n const performRegister = React.useCallback(async (): Promise => {\r\n if (!validate()) {\r\n return;\r\n }\r\n\r\n const result = await confirmInvite(model);\r\n\r\n if (result) {\r\n if (result.requiresTwoFactor) {\r\n history.push(`/account/loginWithTwoFactor?returnUrl=${encodeURIComponent(result.returnUrl)}`);\r\n }\r\n\r\n // Redirect the whole page (not just the react app) as its likely the returnUrl is handled on the server.\r\n if (result.succeeded) {\r\n // Redirect the whole page (not just react) to the returnUrl to let the server handle as well as the client.\r\n if (!result.requiresEmailConfirmation && !result.requiresTwoFactor) {\r\n setIsDoingFullPageRedirect(true);\r\n window.location.href = result.returnUrl;\r\n }\r\n }\r\n }\r\n }, [confirmInvite, model, history, validate, setIsDoingFullPageRedirect]);\r\n\r\n\r\n // Render the UI.\r\n return (\r\n \r\n \r\n \r\n \r\n

\r\n {t('confirmInvite.finishRegistrationHeading', 'Register your account')}\r\n

\r\n
\r\n \r\n

\r\n {t('confirmInvite.thanksForAccepting', 'Thanks for accepting the invite. You can now set a password to finish your account creation.')}\r\n

\r\n\r\n
{ e.preventDefault(); await performRegister(); }}>\r\n \r\n\r\n \r\n\r\n \r\n \r\n change({ password: e.currentTarget.value })} onBlur={e => validate('password')} validationErrors={validationErrors['password']} />\r\n \r\n {passwordRequirements}\r\n \r\n \r\n \r\n \r\n change({ confirmPassword: e.currentTarget.value })} onBlur={e => validate('confirmPassword')} validationErrors={validationErrors['confirmPassword']} />\r\n \r\n\r\n\r\n \r\n \r\n \r\n \r\n \r\n {t('confirmInvite.registering', 'Registering...')}}>\r\n {t('confirmInvite.register', 'Register')}\r\n \r\n \r\n \r\n \r\n \r\n
\r\n
\r\n
\r\n
\r\n );\r\n};\r\n","import * as React from \"react\";\r\nimport { AsyncActionStatus } from \"../../shared/abstractStore\";\r\nimport { useAsyncCallback } from \"react-use-async-callback\";\r\nimport { useAccountService } from \"./useAccountService\";\r\nimport { RegisterResult } from \"./AccountService\";\r\n\r\n/**\r\n * Confirm an invite and set a password.\r\n */\r\nexport function useConfirmInviteCallback(): [(model: { password: string }) => Promise, AsyncActionStatus] {\r\n const accountService = useAccountService();\r\n\r\n // Get the details from the query string.\r\n const { userId, code } = React.useMemo(() => {\r\n const params = new URLSearchParams(window.location.search);\r\n const userId = params.get('userId') ?? params.get('UserId') ?? '';\r\n const code = params.get('code') ?? params.get('Code') ?? '';\r\n return { userId, code };\r\n }, []);\r\n\r\n const [action, { isExecuting, errors }] = useAsyncCallback(async (model: { password: string }) => {\r\n return await accountService.confirmInvite({ userId: userId, code: code, password: model.password });\r\n }, [accountService, userId, code]);\r\n\r\n return [action, { isExecuting, errors }];\r\n}\r\n","import * as React from \"react\";\r\nimport { Form, Alert, FormGroup, Label, Spinner } from \"reactstrap\";\r\nimport { useChanges } from \"../../shared/useChanges\";\r\nimport { useValidatorCallback } from \"pojo-validator-react\";\r\nimport { ValidatedInput } from \"pojo-validator-reactstrap\";\r\nimport { ButtonAsync } from \"reactstrap-buttonasync\";\r\nimport { ChangeEmail as ChangeEmailModel } from '../../api/account/models/ChangeEmail';\r\nimport { useTranslation } from \"react-i18next\";\r\nimport { LoadingIndicator } from \"../shared/LoadingIndicator\";\r\nimport { AlertOnErrors } from \"../../shared/alertOnErrors\";\r\nimport { useChangeEmailCallback, useResendConfirmationEmailCallback } from \"../../api/account\";\r\nimport { useUser } from \"../../api/main/users/useUser\";\r\nimport { useAuthenticatedState } from \"../../api/api-authorization/useAuthenticatedState\";\r\nimport { FormButtons } from \"../shared/FormButtons\";\r\nimport { MainContainer } from \"../shared/MainContainer\";\r\nimport { ConditionalFragment } from \"react-conditionalfragment\";\r\n\r\n/**\r\n * Change the logged in user's email.\r\n */\r\nexport const ChangeEmail = () => {\r\n const { t } = useTranslation();\r\n const { user } = useAuthenticatedState({ includeUser: true });\r\n const { data: { model: storeModel, }, isLoading, errors: loadErrors, refresh: refreshUserModel } = useUser(user?.sub ?? '', { lazy: true });\r\n\r\n const [changeEmail, { isExecuting: isChangingPassword, errors: changeEmailErrors }] = useChangeEmailCallback();\r\n const [hasSentEmail, setHasSentEmail] = React.useState(false);\r\n\r\n const [resendConfirmationEmail, { isExecuting: isResendingConfirmationEmail, errors: resendConfirmationEmailErrors }] = useResendConfirmationEmailCallback();\r\n const [hasSentConfirmationEmail, setHasSentConfirmationEmail] = React.useState(false);\r\n\r\n const { model, change } = useChanges({ newEmail: storeModel?.email ?? '' });\r\n const [validate, validationErrors] = useValidatorCallback((validation, fieldsToCheck) => {\r\n if (!model) {\r\n return;\r\n }\r\n\r\n const rules = {\r\n newEmail: () => !model.newEmail ? t('changeEmail.newEmailRequired', 'Email is required')\r\n : storeModel && storeModel.email === model.newEmail ? t('changeEmail.newEmailMatchesOldEmail', 'Your new email is the same as your old email and so does not need to go through an email update process.')\r\n : '',\r\n };\r\n\r\n validation.checkRules(rules, fieldsToCheck);\r\n }, [model]);\r\n\r\n // Only load the user model once we know the user id.\r\n React.useEffect(() => {\r\n if (!user) {\r\n return;\r\n }\r\n\r\n refreshUserModel();\r\n }, [user, refreshUserModel]);\r\n \r\n // Render the UI.\r\n //\r\n\r\n return (\r\n \r\n \r\n \r\n \r\n\r\n
{\r\n e.preventDefault();\r\n if (!validate()) {\r\n return;\r\n }\r\n\r\n const ok = await changeEmail(model.newEmail);\r\n setHasSentEmail(ok);\r\n }}>\r\n \r\n\r\n {\r\n hasSentEmail ? (\r\n \r\n <>{t('changeEmail.emailHasBeenSent', 'Confirmation link to change email sent. Please check your email to confirm.')} \r\n { e.preventDefault(); await changeEmail(model.newEmail); }}\r\n isExecuting={isResendingConfirmationEmail}\r\n executingChildren={<>{t('common.sending', 'Sending...')}}>\r\n {t('common.resendEmail', 'Resend email')}\r\n \r\n \r\n ) : null\r\n }\r\n {\r\n hasSentConfirmationEmail ? (\r\n \r\n <>{t('login.confirmationEmailHasBeenResent', 'Confirmation link to verify the email for this account has been resent. Please check your email to confirm.')} \r\n { e.preventDefault(); await resendConfirmationEmail(storeModel?.email ?? model.newEmail); }}\r\n isExecuting={isResendingConfirmationEmail}\r\n executingChildren={<>{t('common.sending', 'Sending...')}}>\r\n {t('common.resendEmail', 'Resend email')}\r\n \r\n \r\n ) : null\r\n }\r\n\r\n \r\n \r\n change({ newEmail: e.currentTarget.value })} onBlur={e => validate('newEmail')} validationErrors={validationErrors['newEmail']} />\r\n {\r\n storeModel && !storeModel.emailConfirmed && model.newEmail === storeModel.email ? (\r\n
\r\n { e.preventDefault(); await resendConfirmationEmail(model.newEmail); setHasSentConfirmationEmail(true); }}\r\n isExecuting={isResendingConfirmationEmail}\r\n executingChildren={<>{t('common.resendingEmail', 'Resending email...')}}>\r\n {t('changeEmail.resendVerificationEmail', 'Resend verification email')}\r\n \r\n
\r\n ): null\r\n }\r\n
\r\n\r\n \r\n {t('changeEmail.updatingEmail', 'Updating email...')}}>\r\n {t('changeEmail.updateEmail', 'Update email')}\r\n \r\n \r\n \r\n
\r\n );\r\n};\r\n","import './banner.scss';\r\n\r\nimport * as React from 'react';\r\nimport { Container } from 'reactstrap';\r\n\r\nexport interface BannerProps {\r\n children?: React.ReactNode,\r\n className?: string,\r\n fluid?: boolean,\r\n}\r\n\r\n/**\r\n * Banner to show title and toolbars at the top of pages.\r\n * @param props\r\n */\r\nexport const Banner = (props: BannerProps) => {\r\n const { children, className, fluid } = props;\r\n\r\n return (\r\n
\r\n \r\n {children}\r\n \r\n
\r\n );\r\n};","import './pillsNavBar.scss';\r\n\r\nimport * as React from 'react';\r\nimport { Nav } from 'reactstrap';\r\n\r\nexport interface PillsNavBarProps {\r\n className?: string,\r\n style?: React.CSSProperties,\r\n children?: React.ReactNode,\r\n justified?: boolean,\r\n textColor?: 'inherit' | 'white'\r\n}\r\n\r\n/**\r\n * Navigation of NavItems via styled pills.\r\n * @param props\r\n */\r\nexport const PillsNavBar = (props: PillsNavBarProps) => {\r\n const {\r\n className,\r\n style,\r\n children,\r\n justified,\r\n textColor = 'inherit',\r\n } = props;\r\n\r\n return (\r\n \r\n );\r\n};","import { useTranslation } from \"react-i18next\";\r\nimport { NavItem, NavLink } from \"reactstrap\";\r\nimport { NavLinkTrackActive } from \"../shared/NavLinkTrackActive\";\r\n\r\n/**\r\n * Navigation under the Profile area.\r\n */\r\nexport const ProfileNavigation = () => {\r\n const { t } = useTranslation();\r\n\r\n return (\r\n <>\r\n \r\n \r\n {t('profile.profile', 'Profile')}\r\n \r\n \r\n \r\n \r\n {t('profile.changeEmail', 'Email')}\r\n \r\n \r\n \r\n \r\n {t('profile.changePassword', 'Change Password')}\r\n \r\n \r\n \r\n );\r\n};\r\n","import * as React from 'react';\r\nimport { useAsyncCallback } from 'react-use-async-callback';\r\nimport { AsyncActionStatus } from '../abstractStore';\r\n\r\n/**\r\n * Options for saiving store data. \r\n */\r\nexport interface SaveInStoreOptions {\r\n beforeSaving?: (id: TId, changes: Partial, isCreate: boolean) => void,\r\n afterSaving?: (id: TId, changes: Partial, isCreate: boolean) => void,\r\n}\r\n\r\n/**\r\n * Hook to give us a save method that can cope with creating or updating the store as appropriate.\r\n */\r\nexport function useSaveInStore(\r\n createDataStore: [(model: T) => Promise, AsyncActionStatus],\r\n updateDataStore: [(id: TId, model: Partial) => Promise, AsyncActionStatus],\r\n options?: SaveInStoreOptions\r\n)\r\n : [(id: TId, changes: Partial, isCreate: boolean) => Promise, AsyncActionStatus]\r\n{\r\n\r\n const [create, { isExecuting: isCreating, errors: createErrors }] = createDataStore;\r\n const [update, { isExecuting: isUpdating, errors: updateErrors }] = updateDataStore;\r\n const [save, { isExecuting: isSaving, errors: saveErrors }] = useAsyncCallback(async (id: TId, changes: Partial, isCreate: boolean) => {\r\n // Run the pre-save option.\r\n if (options && options.beforeSaving) {\r\n options.beforeSaving(id, changes, isCreate);\r\n } \r\n\r\n // Create or update the item in the store.\r\n if (isCreate) {\r\n await create(changes as T);\r\n } else {\r\n await update(id, changes);\r\n }\r\n\r\n // Run the post-save option.\r\n if (options && options.afterSaving) {\r\n options.afterSaving(id, changes, isCreate);\r\n } \r\n }, [create, update, options]);\r\n\r\n // Combine errors from all sources into a single errors result.\r\n const errors = React.useMemo(() => {\r\n let ret = [];\r\n if (createErrors) {\r\n ret.push(createErrors);\r\n }\r\n if (updateErrors) {\r\n ret.push(updateErrors);\r\n }\r\n if (saveErrors) {\r\n ret.push(saveErrors);\r\n }\r\n\r\n if (ret.length === 0) {\r\n return undefined;\r\n }\r\n\r\n if (ret.length === 1) {\r\n return ret[0];\r\n }\r\n\r\n return ret;\r\n }, [createErrors, updateErrors, saveErrors]);\r\n\r\n return [save, { isExecuting: isSaving || isCreating || isUpdating, errors: errors }];\r\n}\r\n","import { useMutation } from \"@apollo/react-hooks\";\r\nimport { useAsyncCallback } from 'react-use-async-callback';\r\nimport gql from \"graphql-tag\";\r\nimport { AsyncActionStatus } from '../../../shared/abstractStore';\r\nimport { ProfileCreateInput } from '../generated/globalTypes';\r\nimport { createProfileMutation, createProfileMutationVariables } from '../generated/createProfileMutation';\r\nimport { profileFieldsFragment } from '../models/Profile';\r\n\r\n/**\r\n * Get a callback to create a Profile in the store.\r\n */\r\nexport function useCreateProfileCallback(): [(model: ProfileCreateInput) => Promise, AsyncActionStatus] {\r\n const [mutationAction, { error }] = useMutation(\r\n gql`\r\n mutation createProfileMutation ($model: ProfileCreateInput!) {\r\n createProfile(model: $model) {\r\n ...profileFields\r\n }\r\n }\r\n\r\n ${profileFieldsFragment}\r\n `\r\n );\r\n\r\n // Wrap the mutation in a standard callback.\r\n const [action, { isExecuting, errors: actionErrors }] = useAsyncCallback(async (model: ProfileCreateInput) => {\r\n const result = await mutationAction({ variables: { model: model } });\r\n if (result.errors && result.errors.length) {\r\n throw result.errors;\r\n }\r\n }, [mutationAction]);\r\n\r\n return [action, { isExecuting: isExecuting, errors: error ? error.message : actionErrors }];\r\n}\r\n","import { useMutation } from \"@apollo/react-hooks\";\r\nimport { useAsyncCallback } from 'react-use-async-callback';\r\nimport gql from \"graphql-tag\";\r\nimport { AsyncActionStatus } from '../../../shared/abstractStore';\r\nimport { ProfileUpdateInput } from '../generated/globalTypes';\r\nimport { updateProfileMutation, updateProfileMutationVariables } from '../generated/updateProfileMutation';\r\nimport { profileFieldsFragment } from '../models/Profile';\r\n\r\n/**\r\n * Get a callback to update a Profile in the store.\r\n */\r\nexport function useUpdateProfileCallback(): [(id: string, model: ProfileUpdateInput) => Promise, AsyncActionStatus] {\r\n const [mutationAction, { error }] = useMutation(\r\n gql`\r\n mutation updateProfileMutation ($model: ProfileUpdateInput!) {\r\n updateProfile(model: $model) {\r\n ...profileFields\r\n }\r\n }\r\n\r\n ${profileFieldsFragment}\r\n `\r\n );\r\n\r\n // Wrap the mutation in a standard callback.\r\n const [action, { isExecuting, errors: actionErrors }] = useAsyncCallback(async (id: string, model: ProfileUpdateInput) => {\r\n const result = await mutationAction({ variables: { model: { ...model, id: id } } });\r\n if (result.errors && result.errors.length) {\r\n throw result.errors;\r\n }\r\n }, [mutationAction]);\r\n\r\n return [action, { isExecuting: isExecuting, errors: error ? error.message : actionErrors }];\r\n}\r\n","import * as React from 'react';\r\nimport { ProfileCreateInput, ProfileUpdateInput } from '../generated/globalTypes';\r\nimport { useSaveInStore, SaveInStoreOptions } from '../../../shared/useSaveInStore';\r\nimport { useCreateProfileCallback } from './useCreateProfileCallback';\r\nimport { useUpdateProfileCallback } from './useUpdateProfileCallback';\r\nimport { Profile } from '../models/Profile';\r\n\r\n/**\r\n * Get a callback to save a Profile in the store using either a create or update.\r\n */\r\nexport function useSaveProfileCallback(options: SaveInStoreOptions = {}) {\r\n const [_create, createStatus] = useCreateProfileCallback();\r\n const create = React.useCallback((model: Partial) => _create(model as ProfileCreateInput), [_create]);\r\n\r\n const [_update, updateStatus] = useUpdateProfileCallback();\r\n const update = React.useCallback((id: string, changes: Partial) => _update(id, changes as ProfileUpdateInput), [_update]);\r\n\r\n return useSaveInStore(\r\n [create, createStatus],\r\n [update, updateStatus],\r\n options\r\n );\r\n}\r\n","import * as React from \"react\";\r\nimport { Row, Col, Form, FormGroup, Label, Spinner, Alert } from \"reactstrap\";\r\nimport { useChanges } from \"../../shared/useChanges\";\r\nimport { useValidatorCallback } from \"pojo-validator-react\";\r\nimport { ValidatedInput } from \"pojo-validator-reactstrap\";\r\nimport { ButtonAsync } from \"reactstrap-buttonasync\"\r\nimport { useAuthenticatedState } from \"../../api/api-authorization/useAuthenticatedState\";\r\nimport { LoadingIndicator } from \"../shared/LoadingIndicator\";\r\nimport { Guid } from \"guid-string\";\r\nimport { useProfile } from \"../../api/main/profiles/useProfile\";\r\nimport { useSaveProfileCallback } from \"../../api/main/profiles/useSaveProfileCallback\";\r\nimport { AlertOnErrors } from \"../../shared/alertOnErrors\";\r\nimport { useTranslation } from \"react-i18next\";\r\nimport { FormButtons } from \"../shared/FormButtons\";\r\nimport { FontAwesomeIcon } from \"@fortawesome/react-fontawesome\";\r\nimport { useAsyncCallback } from \"react-use-async-callback\";\r\nimport { MainContainer } from \"../shared/MainContainer\";\r\nimport { ConditionalFragment } from \"react-conditionalfragment\";\r\n\r\n/**\r\n * Allow the user to change their personal details on their profile.\r\n */\r\nexport const ProfileDetails = () => {\r\n const { t } = useTranslation();\r\n const [hasSaved, setHasSaved] = React.useState(false);\r\n const [isCreate, setIsCreate] = React.useState(false);\r\n const { user } = useAuthenticatedState({ includeUser: true});\r\n const { data: { model: storeModel, }, isLoading, errors: loadErrors, refresh: refreshProfile } = useProfile(user?.sub ?? '', {\r\n isUserId: true,\r\n lazy: true,\r\n onCompleted: (data) => {\r\n // If we don't find a record in the database, create one ready to save.\r\n if (!data) {\r\n setIsCreate(true);\r\n change({ id: Guid.newGuid(), userId: user?.sub ?? '' });\r\n }\r\n } });\r\n const { model, change, changes } = useChanges(storeModel);\r\n const [save, { isExecuting: isSaving, errors: saveErrors }] = useSaveProfileCallback({ afterSaving: () => setIsCreate(false) })\r\n\r\n const [validate, validationErrors] = useValidatorCallback((validation, fieldsToCheck) => {\r\n if (!model) {\r\n return;\r\n }\r\n\r\n const rules = {\r\n firstName: () => !model.firstName ? t('profileDetails.firstNameRequired', 'First name is required') : '',\r\n lastName: () => !model.lastName ? t('profileDetails.lastNameRequired', 'Last name is required') : '',\r\n };\r\n\r\n validation.checkRules(rules, fieldsToCheck);\r\n }, [model]);\r\n\r\n // Only load the profile once we know the user.\r\n React.useEffect(() => {\r\n if (!user) {\r\n return;\r\n }\r\n\r\n refreshProfile();\r\n }, [user, refreshProfile]);\r\n\r\n const [saveForm] = useAsyncCallback(async () => {\r\n if (!validate()) {\r\n return;\r\n }\r\n\r\n await save(model.id, changes, isCreate);\r\n\r\n setHasSaved(true);\r\n }, [save, model, setHasSaved, validate, isCreate, changes]);\r\n\r\n\r\n // Render the UI.\r\n //\r\n\r\n return (\r\n \r\n \r\n \r\n \r\n\r\n
{ e.preventDefault(); await saveForm(); }}>\r\n \r\n\r\n {\r\n hasSaved ? (\r\n \r\n {t('profileDetails.hasSaved', 'Your details have been updated.')}\r\n \r\n ): null\r\n }\r\n\r\n \r\n \r\n \r\n \r\n change({ firstName: e.currentTarget.value })} onBlur={e => validate('firstName')} validationErrors={validationErrors['firstName']} />\r\n \r\n \r\n \r\n \r\n \r\n change({ lastName: e.currentTarget.value })} onBlur={e => validate('lastName')} validationErrors={validationErrors['lastName']} />\r\n \r\n \r\n \r\n\r\n \r\n {t('common.saving', 'Saving...')}}>\r\n \r\n <> {t('common.save', 'Save')}\r\n \r\n \r\n \r\n
\r\n );\r\n};\r\n","import { Redirect } from \"react-router\";\r\nimport { RouteEntry } from \"../../shared/routes\";\r\nimport { ChangeEmail } from \"./ChangeEmail\";\r\nimport { ChangePassword } from \"./ChangePassword\";\r\nimport { Profile } from \"./Profile\";\r\nimport { ProfileDetails } from \"./ProfileDetails\";\r\n\r\nexport const profileRoutes: Array = [\r\n { path: '/profile', component: Profile, authorize: true },\r\n];\r\n\r\nexport const profileTabRoutes: Array = [\r\n { path: '/profile', exact: true, component: () => , authorize: true },\r\n { path: '/profile/details', exact: true, component: ProfileDetails, authorize: true },\r\n { path: '/profile/changeEmail', exact: true, component: ChangeEmail, authorize: true },\r\n { path: '/profile/changePassword', exact: true, component: ChangePassword, authorize: true },\r\n];\r\n\r\n","import { useTranslation } from \"react-i18next\";\r\nimport { Banner } from \"../shared/Banner\";\r\nimport { Background } from \"../shared/background/Background\";\r\nimport { profileTabRoutes } from \"./routes\";\r\nimport { AppRoutes } from \"../shared/AppRoutes\";\r\nimport { PillsNavBar } from \"../shared/pillsNavBar/PillsNavBar\";\r\nimport { ProfileNavigation } from \"./ProfileNavigation\";\r\nimport { Col, Row } from \"reactstrap\";\r\n\r\n/**\r\n * Allow the user to change their profile.\r\n */\r\nexport const Profile = () => {\r\n const { t } = useTranslation();\r\n\r\n return (\r\n \r\n \r\n \r\n \r\n

{t('profile.heading', 'Profile')}

\r\n \r\n \r\n \r\n \r\n \r\n \r\n
\r\n
\r\n\r\n \r\n
\r\n );\r\n};\r\n","import * as React from 'react';\r\nimport { useLazyQuery } from \"@apollo/react-hooks\";\r\nimport gql from \"graphql-tag\";\r\nimport { Guid } from \"guid-string\";\r\nimport { AsyncLoadResult, AsyncLoadOptions } from '../../../shared/abstractStore';\r\nimport { userQuery, userQueryVariables } from '../generated/userQuery';\r\nimport { userFieldsFragment } from '../models/User';\r\nimport { mainApiConfig } from '../../../configure/mainApiConfig';\r\n\r\n/**\r\n * Get a User from the store.\r\n * @param id\r\n * @param options\r\n */\r\nexport function useUser(id: string | undefined | null, options: AsyncLoadOptions = {}): AsyncLoadResult {\r\n // Query the data we need from the API.\r\n const [load, { data, loading, error, refetch }] = useLazyQuery(\r\n gql`\r\n query userQuery ($id: ID!) {\r\n model: user(id: $id) {\r\n ...userFields\r\n }\r\n }\r\n\r\n ${userFieldsFragment}\r\n `,\r\n {\r\n variables: { id: id ?? Guid.empty },\r\n pollInterval: options.pollInterval,\r\n fetchPolicy: options.fetchPolicy ?? mainApiConfig.defaultFetchPolicy,\r\n onCompleted: (data) => {\r\n if (options.onCompleted) {\r\n options.onCompleted(data);\r\n }\r\n }\r\n }\r\n );\r\n\r\n // Run the query (unless we are being lazy).\r\n React.useEffect(() => {\r\n if (!options.lazy) {\r\n load();\r\n }\r\n }, [options.lazy, load])\r\n\r\n // Return the results.\r\n const refresh = React.useCallback(async () => { !refetch ? await load() : await refetch(); }, [refetch, load]);\r\n return React.useMemo(() => ({\r\n data: data ?? ({} as any),\r\n refresh: refresh,\r\n isLoading: loading,\r\n errors: error\r\n }), [data, refresh, loading, error]);\r\n}\r\n","import { AsyncActionStatus } from \"../../shared/abstractStore\";\r\nimport { useAsyncCallback } from \"react-use-async-callback\";\r\nimport { useAccountService } from \"./useAccountService\";\r\n\r\n/**\r\n * Callback to change the email of the current user..\r\n */\r\nexport function useChangeEmailCallback(): [(newEmail: string) => Promise, AsyncActionStatus] {\r\n const accountService = useAccountService();\r\n\r\n const [action, { isExecuting, errors }] = useAsyncCallback(async (newEmail: string) => {\r\n return await accountService.changeEmail({ newEmail: newEmail });\r\n }, [accountService]);\r\n\r\n return [action, { isExecuting, errors }];\r\n}\r\n","import * as React from \"react\";\r\nimport { Form, Alert, FormGroup, Label, Spinner, FormText } from \"reactstrap\";\r\nimport { useChanges } from \"../../shared/useChanges\";\r\nimport { useValidatorCallback } from \"pojo-validator-react\";\r\nimport { ValidatedInput } from \"pojo-validator-reactstrap\";\r\nimport { ButtonAsync } from \"reactstrap-buttonasync\";\r\nimport { ChangePassword as ChangePasswordModel } from '../../api/account/models/ChangePassword';\r\nimport { useTranslation } from \"react-i18next\";\r\nimport { AlertOnErrors } from \"../../shared/alertOnErrors\";\r\nimport { useChangePasswordCallback } from \"../../api/account\";\r\nimport { usePasswordValidation } from \"../../shared/passwordValidation\";\r\nimport { FormButtons } from \"../shared/FormButtons\";\r\nimport { MainContainer } from \"../shared/MainContainer\";\r\n\r\n/**\r\n * Change the logged in user's password.\r\n */\r\nexport const ChangePassword = () => {\r\n const { t } = useTranslation();\r\n const [hasChangedPassword, setHasChangedPassword] = React.useState(false);\r\n const [changePassword, { isExecuting: isChangingPassword, errors: changePasswordErrors }] = useChangePasswordCallback();\r\n const { checkPassword, passwordRequirements } = usePasswordValidation();\r\n\r\n const { model, change } = useChanges({ currentPassword: '', newPassword: '', confirmPassword: '' });\r\n const [validate, validationErrors] = useValidatorCallback((validation, fieldsToCheck) => {\r\n if (!model) {\r\n return;\r\n }\r\n\r\n const rules = {\r\n currentPassword: () => !model.currentPassword ? t('changePassword.currentPasswordRequred', 'Current password is required'): '',\r\n newPassword: () => !model.newPassword ? t('changePassword.newPasswordRequired', 'Password is required')\r\n : checkPassword(model.newPassword).errorDescription,\r\n confirmPassword: () => model.confirmPassword !== model.newPassword ? t('changePassword.passwordsDoNotMatch', 'The password and confirmation password do not match') : '',\r\n };\r\n\r\n validation.checkRules(rules, fieldsToCheck);\r\n }, [model]);\r\n \r\n // Render the UI.\r\n //\r\n\r\n return (\r\n \r\n
{\r\n e.preventDefault();\r\n if (!validate()) {\r\n return;\r\n }\r\n\r\n const ok = await changePassword(model.currentPassword, model.newPassword);\r\n setHasChangedPassword(ok);\r\n }}>\r\n \r\n\r\n {\r\n hasChangedPassword ? (\r\n \r\n {t('changePassword.passwordHasBeenChanged', 'Your password has been changed.')}\r\n \r\n ) : null\r\n }\r\n\r\n \r\n \r\n change({ currentPassword: e.currentTarget.value })} onBlur={e => validate('currentPassword')} validationErrors={validationErrors['currentPassword']} />\r\n \r\n \r\n \r\n change({ newPassword: e.currentTarget.value })} onBlur={e => validate('newPassword')} validationErrors={validationErrors['newPassword']} />\r\n \r\n {passwordRequirements}\r\n \r\n \r\n \r\n \r\n change({ confirmPassword: e.currentTarget.value })} onBlur={e => validate('confirmPassword')} validationErrors={validationErrors['confirmPassword']} />\r\n \r\n \r\n {t('changePassword.updatingPassword', 'Updating password...')}}>\r\n {t('changePassword.updatePassword', 'Update password')}\r\n \r\n \r\n \r\n
\r\n );\r\n};\r\n","import { AsyncActionStatus } from \"../../shared/abstractStore\";\r\nimport { useAsyncCallback } from \"react-use-async-callback\";\r\nimport { useAccountService } from \"./useAccountService\";\r\n\r\n/**\r\n * Callback to change the password of the current user..\r\n */\r\nexport function useChangePasswordCallback(): [(currentPassword: string, newPassword: string) => Promise, AsyncActionStatus] {\r\n const accountService = useAccountService();\r\n\r\n const [action, { isExecuting, errors }] = useAsyncCallback(async (currentPassword: string, newPassword: string) => {\r\n return await accountService.changePassword({ currentPassword: currentPassword, newPassword: newPassword });\r\n }, [accountService]);\r\n\r\n return [action, { isExecuting, errors }];\r\n}\r\n","import * as React from 'react';\r\nimport { useLocation } from \"react-router\";\r\n\r\n/**\r\n * Hook to get the URLSearchParams from the current or passed in location.\r\n * @param search\r\n */\r\nexport function useURLSearchParams(search?: string) {\r\n const location = useLocation();\r\n return React.useMemo(() => new URLSearchParams(search ?? location?.search ?? ''), [search, location]);\r\n}","import * as React from 'react';\r\nimport { useURLSearchParams } from \"./useURLSearchParams\";\r\nimport { useHistory, useLocation } from \"react-router\";\r\n\r\n/**\r\n * Replace the Search params in the browser using history.replace().\r\n * @param name name of the Query param to return the value of.\r\n */\r\nexport function useReplaceSearchParamsEffect(changes: T): void {\r\n const location = useLocation();\r\n const params = useURLSearchParams();\r\n const history = useHistory();\r\n\r\n const url = React.useMemo(() => {\r\n for (let key in changes) {\r\n\r\n // Make sure we treat undefined, null, and empty strings the same to avoid potentially infinate rerenders\r\n // if an empty string is passed in to changes.\r\n let changesValue = changes[key] ?? '';\r\n let paramsValeue = params.get(key) ?? '';\r\n\r\n if (changesValue === paramsValeue) {\r\n continue;\r\n }\r\n\r\n if (!changesValue) {\r\n params.delete(key);\r\n } else {\r\n params.set(key, changesValue);\r\n }\r\n }\r\n\r\n return `${location.pathname}?${params}${location.hash}`;\r\n }, [changes, location, params]);\r\n\r\n // If we have changed the url because of a parameter, apply it with history.replace().\r\n React.useEffect(() => {\r\n if (!url) {\r\n return;\r\n }\r\n\r\n history.replace(url);\r\n }, [url, history]);\r\n}","import * as React from 'react';\r\nimport { useURLSearchParams } from \"./useURLSearchParams\";\r\n\r\n\r\n/**\r\n * Hook to get the value of specific search parameters using deconstruction.\r\n * @param name name of the Query param to return the value of.\r\n */\r\nexport function useSearchParams(): { [key: string]: string | null } {\r\n const params = useURLSearchParams();\r\n const deconstructionObject = React.useMemo(() => {\r\n let ret = {};\r\n params.forEach((value, key) => {\r\n ret = {\r\n ...ret,\r\n [key]: value\r\n }\r\n });\r\n return ret;\r\n }, [params]);\r\n\r\n return deconstructionObject;\r\n}","import { Redirect } from 'react-router';\r\nimport { useSearchParams } from '../../shared/useURLSearchParams';\r\n\r\n/**\r\n * Default / home page.\r\n */\r\nexport const Home = () => {\r\n // If we have a redirect URL on the query string redirect there.\r\n var { redirectUrl } = useSearchParams();\r\n\r\n return (\r\n <>\r\n \r\n \r\n );\r\n};","import { RouteEntry } from \"../../shared/routes\";\r\nimport { Home } from \"./Home\";\r\n\r\nexport const homeRoutes: Array = [\r\n { path: '/', exact: true, component: Home, authorize: true },\r\n];\r\n","import { NavItem, NavLink } from 'reactstrap';\r\nimport { AuthorizeContainer } from '../../shared/authorizeRoute';\r\nimport { useTranslation } from 'react-i18next';\r\nimport { FontAwesomeIcon } from '@fortawesome/react-fontawesome';\r\nimport { NavLinkTrackActive } from '../shared/NavLinkTrackActive';\r\nimport { IdentityRoles } from '../../configure/security/IdentityRoles';\r\nimport { SidebarNavTitle } from '../../shared/sidebarNav';\r\n\r\n/**\r\n * Administration navigation menu for the app. \r\n */\r\nexport const AdministrationNavigation = () => {\r\n const { t } = useTranslation();\r\n\r\n return (\r\n <>\r\n \r\n \r\n {t('administrationNavigation.dashboardTitle', 'Esitu Dashboard')}\r\n \r\n \r\n \r\n \r\n <> {t('administrationNavigation.dashboard', 'Esitu dashboard')}\r\n \r\n \r\n\r\n \r\n {t('administrationNavigation.subscriptionsTitle', 'Subscriptions')}\r\n \r\n \r\n \r\n \r\n <> {t('administrationNavigation.subscriptions', 'Subscriptions')}\r\n \r\n \r\n \r\n \r\n \r\n <> {t('administrationNavigation.distributors', 'Distributors')}\r\n \r\n \r\n \r\n \r\n \r\n <> {t('administrationNavigation.studies', 'Studies')}\r\n \r\n \r\n\r\n \r\n {t('administrationNavigation.assessmentsTitle', 'Assessments')}\r\n \r\n \r\n \r\n \r\n <> {t('administrationNavigation.assessments', 'Assessments')}\r\n \r\n \r\n \r\n \r\n \r\n <> {t('administrationNavigation.questions', 'Questions')}\r\n \r\n \r\n \r\n \r\n \r\n <> {t('administrationNavigation.informationPages', 'Information pages')}\r\n \r\n \r\n\r\n \r\n {t('administrationNavigation.psycoMetricsTitle', 'Psychometrics')}\r\n \r\n \r\n \r\n \r\n <> {t('administrationNavigation.questionnaires', 'Questionnaires')}\r\n \r\n \r\n\r\n \r\n {t('administrationNavigation.learningTitle', 'Training')}\r\n \r\n \r\n \r\n \r\n <> {t('administrationNavigation.trainingModules', 'Training modules')}\r\n \r\n \r\n \r\n \r\n \r\n <> {t('administrationNavigation.learningActivities', 'Learning activities')}\r\n \r\n \r\n\r\n \r\n {t('administrationNavigation.tagsTitle', 'Metrics and tag')}\r\n \r\n \r\n \r\n \r\n <> {t('administrationNavigation.driverMetrics', 'Safety metrics')}\r\n \r\n \r\n \r\n \r\n \r\n <> {t('administrationNavigation.tags', 'Tags')}\r\n \r\n \r\n\r\n \r\n {t('administrationNavigation.usersTitle', 'User management')}\r\n \r\n\r\n \r\n \r\n \r\n <> {t('administrationNavigation.administrators', 'Esitu staff')}\r\n \r\n \r\n\r\n \r\n {t('administrationNavigation.exportsTitle', 'Exports and analysis')}\r\n \r\n \r\n \r\n \r\n <> {t('administrationNavigation.events', 'Export event data')}\r\n \r\n \r\n \r\n \r\n );\r\n};\r\n","import './sidebarRequired.scss';\r\n\r\nimport * as React from 'react';\r\nimport { Helmet } from 'react-helmet-async';\r\n\r\nexport interface SidebarRequiredProps {\r\n children?: React.ReactNode,\r\n}\r\n\r\n/**\r\n * Component that shows the sidebr if it is required/recommended for the screensize.\r\n */\r\nexport const SidebarRequired = (props: SidebarRequiredProps) => {\r\n const { children } = props;\r\n\r\n return (\r\n <>\r\n \r\n \r\n \r\n {children}\r\n \r\n );\r\n};\r\n","import { RouteEntry } from \"../../shared/routes\";\r\nimport { AdministrationNavigation } from \"./AdministrationNavigation\";\r\nimport { AdministrationHome } from \"./AdministrationHome\";\r\nimport { SidebarRequired } from \"../shared/SidebarRequired\";\r\nimport { IdentityRoles } from \"../../configure/security/IdentityRoles\";\r\n\r\nexport const administrationRoutes: Array = [\r\n { path: '/administration', exact: true, component: AdministrationHome, authorize: true, requireRole: IdentityRoles.Administration },\r\n];\r\n\r\nexport const administrationSidebarRoutes: Array = [\r\n { path: '/administration', component: () => , authorize: true, requireRole: IdentityRoles.Administration },\r\n];\r\n","import { Redirect } from 'react-router';\r\n\r\n/**\r\n * Default Administration home page.\r\n */\r\nexport const AdministrationHome = () => {\r\n return (\r\n <>\r\n \r\n \r\n );\r\n};","import * as React from 'react';\r\n\r\n/**\r\n * Returns a hook based callback that can be used to fetch more data in a controlled way and will automatically stop fetching when it reaches the end,\r\n * which it identifies by a call that returns less data than we are expecting.\r\n * \r\n * You can check if there is more using the hasMore() function returned in its state.\r\n */\r\nexport function useFetchMoreCallback(\r\n fetchMoreFromStore: any,// (...args: any) => Promise<{ data: T }>,\r\n currentEndOffset: number | undefined | null,\r\n merge: (prevResult: T | undefined | null, newResult: T | undefined | null) => T | undefined | null,\r\n newResultLength: (newResult: T | undefined | null) => number | undefined | null\r\n): { fetchMore: () => void, hasMore: () => boolean }\r\n{\r\n const [_hasMore, setHasMore] = React.useState(true);\r\n\r\n // Read more data.\r\n const fetchMore = React.useCallback(() => {\r\n fetchMoreFromStore({\r\n variables: { offset: currentEndOffset ?? 0 },\r\n updateQuery: (previousQueryResult: T | undefined | null, { fetchMoreResult }: { fetchMoreResult: (T | undefined | null) }) => {\r\n if (!fetchMoreResult) {\r\n return previousQueryResult;\r\n }\r\n\r\n // If we didn't read any extra results, tell the cursor its reached the end.\r\n if (!newResultLength(fetchMoreResult)) {\r\n setHasMore(false);\r\n }\r\n\r\n // Merge everything together.\r\n return merge(previousQueryResult, fetchMoreResult);\r\n\r\n }\r\n });\r\n }, [fetchMoreFromStore, currentEndOffset, merge, newResultLength]);\r\n\r\n // Is there any more data available? True until fetchMore reads past the end of the data.\r\n const hasMore = React.useCallback(() => _hasMore, [_hasMore]);\r\n\r\n return React.useMemo(() => ({\r\n fetchMore: fetchMore,\r\n hasMore: hasMore,\r\n }), [fetchMore, hasMore]);\r\n} ","import gql from \"graphql-tag\";\r\nimport { questionTagFields } from \"../generated/questionTagFields\";\r\n\r\nexport const questionTagFieldsFragment = gql`\r\n fragment questionTagFields on QuestionTag {\r\n id\r\n name\r\n archived\r\n }\r\n`;\r\n\r\n\r\nexport type QuestionTag = Omit;\r\n","import './searchInput.scss';\r\nimport * as React from 'react';\r\nimport { Input, InputGroup, InputGroupAddon, Button, InputProps } from 'reactstrap';\r\nimport { FontAwesomeIcon } from '@fortawesome/react-fontawesome';\r\nimport { useTranslation } from 'react-i18next';\r\n\r\nexport interface SearchInputProps extends InputProps {\r\n onSearchButtonClick?: () => void,\r\n children?: React.ReactNode,\r\n}\r\n\r\n/**\r\n * Input that is hooked up for searching as the user types, by introducing an appropriate delay before raising the onSearch event.\r\n */\r\nexport const SearchInput = (props: SearchInputProps) => {\r\n const { type, placeholder, className, style, onSearchButtonClick, children, ...rest } = props;\r\n\r\n const { t } = useTranslation();\r\n\r\n return (\r\n \r\n {\r\n // When the user presses enter, trigger a click on the search button.\r\n if (e.charCode === 13) {\r\n if (onSearchButtonClick) {\r\n onSearchButtonClick();\r\n }\r\n }\r\n }}\r\n {...rest} />\r\n \r\n \r\n \r\n {children}\r\n \r\n );\r\n};","import './noResultsFound.scss';\r\n\r\nimport * as React from 'react';\r\nimport { useTranslation } from 'react-i18next';\r\nimport { FontAwesomeIcon } from '@fortawesome/react-fontawesome';\r\nimport { IconProp } from '@fortawesome/fontawesome-svg-core';\r\n\r\nexport interface NoResultsFoundProps {\r\n className?: string,\r\n search?: string,\r\n children?: React.ReactNode,\r\n icon?: IconProp,\r\n}\r\n\r\n/**\r\n * Component to show when a search or query returned no results.\r\n */\r\nexport const NoResultsFound = (props: NoResultsFoundProps) => {\r\n const {\r\n className,\r\n search,\r\n children,\r\n icon\r\n } = props;\r\n\r\n const { t } = useTranslation();\r\n\r\n // Otherwise render th default contents.\r\n return (\r\n
\r\n
\r\n \r\n
\r\n {\r\n children ? children\r\n : (\r\n

\r\n {\r\n search ?\r\n t('notResultsFound.nothingMatchedSearch', 'Sorry there were no matches for \"{{search}}.\"', { search: search })\r\n : t('notResultsFound.nothingFound', 'Sorry there is nothing to show you here yet.')\r\n }\r\n

\r\n )\r\n }\r\n
\r\n );\r\n};","import './stickyToolbar.scss';\r\n\r\nimport * as React from 'react';\r\nimport { Waypoint } from 'react-waypoint';\r\nimport { Container } from 'reactstrap';\r\nimport { ConditionalFragment } from 'react-conditionalfragment';\r\n\r\nexport interface StickyToolbarProps {\r\n className?: string,\r\n children: React.ReactNode\r\n}\r\n\r\n/**\r\n * Container for a toolbar that sticks to the top of the screen when its scrolled off the screen.\r\n * \r\n * NOTE Some code here is specific to the layout rather than the overall functionality. Namely:\r\n * 1. The use of the \"main\" class when top-toolbar-stuck which is used to make sure available margins are kept in sync with the
element\r\n * during sidebar states.\r\n * 2. The topOffset=\"\" which is used to ensure the triggering happens when we would move behind the fixed nav header.\r\n * \r\n * If you want to use this code elsewhere, you will likely need to tweak these values.\r\n */\r\nexport const StickyToolbar = (props: StickyToolbarProps) => {\r\n const [isStuck, setIsStuck] = React.useState(false);\r\n const { className, children } = props;\r\n\r\n return (\r\n <>\r\n setIsStuck(false)} onLeave={() => setIsStuck(true)} />\r\n\r\n \r\n
\r\n \r\n {children}\r\n \r\n
\r\n
\r\n\r\n {/* Render the unstuck version even when we render the stuck version as well (prevents screen jitter when the screen is only just big enough to \"stick\" but removing the Sticky elements from the flow causes there to be enough virticle space again */}\r\n
\r\n {children}\r\n
\r\n \r\n );\r\n};","import './tableRowButtons.scss';\r\n\r\nimport * as React from 'react';\r\n\r\nexport interface TableRowButtonsProps {\r\n className?: string,\r\n children: React.ReactNode\r\n}\r\n\r\n/**\r\n * Container for buttons used in a table's row.\r\n */\r\nexport const TableRowButtons = (props: TableRowButtonsProps) => {\r\n const { className, children } = props;\r\n\r\n return (\r\n
\r\n {children}\r\n
\r\n );\r\n};","import { ReactNode } from \"react\";\r\nimport { ConditionalFragment } from \"react-conditionalfragment\";\r\nimport { Card, CardBody, CardFooter, Col, Row, Table } from \"reactstrap\";\r\nimport { isNullOrUndefined } from \"util\";\r\nimport { TableRowButtons } from \"../TableRowButtons\";\r\nimport \"./cardsOrTable.scss\";\r\n\r\nexport type CardsOrTableViewMode = 'cards' | 'table';\r\n\r\nexport type CardsOrTableColumnFunction = (item: ItemType, view: CardsOrTableViewMode) => ReactNode | undefined | null;\r\n\r\nexport interface CardsOrTableProps {\r\n viewMode: CardsOrTableViewMode,\r\n items: Array,\r\n columns: Array>,\r\n buttons?: CardsOrTableColumnFunction | undefined | null,\r\n tableHeadings: Array,\r\n onItemClick?: (item: ItemType) => void,\r\n}\r\n\r\nexport const CardsOrTable = (props: CardsOrTableProps) => {\r\n const {\r\n viewMode = 'cards',\r\n items,\r\n columns,\r\n buttons,\r\n tableHeadings,\r\n onItemClick,\r\n } = props;\r\n\r\n switch (viewMode) {\r\n case 'cards':\r\n return (\r\n
\r\n \r\n {\r\n items?.map((item, index) => {\r\n return (\r\n \r\n \r\n !!onItemClick && onItemClick(item)} style={{ cursor: !!onItemClick ? 'pointer' : undefined }}>\r\n {\r\n columns.map((column, columnIndex) => {\r\n const node = column(item, viewMode);\r\n if (!node) {\r\n return node;\r\n }\r\n\r\n return (\r\n
\r\n {node}\r\n
\r\n );\r\n })\r\n }\r\n
\r\n \r\n {buttons && buttons(item, viewMode)}\r\n \r\n
\r\n \r\n );\r\n })\r\n }\r\n
\r\n
\r\n );\r\n case 'table':\r\n return (\r\n
\r\n \r\n \r\n \r\n {\r\n tableHeadings.map((heading, columnIndex) => {\r\n const node = heading;\r\n if (isNullOrUndefined(node)) {\r\n return null;\r\n }\r\n\r\n return (\r\n \r\n );\r\n })\r\n }\r\n \r\n \r\n \r\n \r\n \r\n \r\n {\r\n items?.map((item, itemIndex) => (\r\n !!onItemClick && onItemClick(item)}>\r\n {\r\n columns.map((column, columnIndex) => {\r\n const node = column(item, viewMode);\r\n if (isNullOrUndefined(node)) {\r\n return null;\r\n }\r\n\r\n return (\r\n \r\n );\r\n })\r\n }\r\n\r\n \r\n \r\n \r\n \r\n ))\r\n }\r\n \r\n
\r\n {node}\r\n  
\r\n {node}\r\n \r\n \r\n {buttons && buttons(item, viewMode)}\r\n \r\n
\r\n
\r\n );\r\n }\r\n}\r\n","import * as React from 'react';\r\nimport { atom, useRecoilState } from 'recoil';\r\nimport { CardsOrTableViewMode } from '../../components/shared/cardsOrTable/CardsOrTable';\r\nimport { persistAtom } from '../../configure/recoilPersistConfig';\r\n\r\nexport const preferredListViewModeState = atom({\r\n key: 'preferredListViewModeState',\r\n default: 'cards',\r\n effects_UNSTABLE: [persistAtom],\r\n \r\n});\r\n\r\n/**\r\n * Hook that returns the users preferred view mode for list views so that changing it once preserves it across all lists until changed back.\r\n */\r\nexport function usePreferredListViewMode(): [CardsOrTableViewMode, React.Dispatch>] {\r\n const [value, setValue] = useRecoilState(preferredListViewModeState);\r\n return [value, setValue];\r\n}","import * as React from 'react';\r\nimport { Button, Row, Col, ButtonGroup, ButtonDropdown, DropdownToggle, DropdownMenu, DropdownItem, CardTitle } from 'reactstrap';\r\nimport { LinkContainer } from 'react-router-bootstrap';\r\nimport { AlertOnErrors } from '../../shared/alertOnErrors';\r\nimport { LoadingIndicator } from '../shared/LoadingIndicator';\r\nimport { useQuestionTags } from '../../api/main/questionTags/useQuestionTags';\r\nimport { Waypoint } from 'react-waypoint';\r\nimport { useReplaceSearchParamsEffect, useSearchParams } from '../../shared/useURLSearchParams';\r\nimport { useTranslation } from 'react-i18next';\r\nimport { SearchInput } from '../shared/searchInput/SearchInput';\r\nimport { FontAwesomeIcon } from '@fortawesome/react-fontawesome';\r\nimport { MainContainer } from '../shared/MainContainer';\r\nimport { NoResultsFound } from '../shared/NoResultsFound';\r\nimport { StickyToolbar } from '../shared/StickyToolbar';\r\nimport { useHistory } from 'react-router';\r\nimport { ConditionalFragment } from 'react-conditionalfragment';\r\nimport { Banner } from '../shared/Banner';\r\nimport { useToggleStateArray } from 'use-toggle-state';\r\nimport { Background } from '../shared/background/Background';\r\nimport { CardsOrTable } from '../shared/cardsOrTable/CardsOrTable';\r\nimport { usePreferredListViewMode } from '../../globalState/preferredListViewMode/usePreferredListViewMode';\r\n\r\n\r\n/**\r\n * List of QuestionTags.\r\n */\r\nexport const QuestionTagsList = () => {\r\n const { t } = useTranslation();\r\n const { search: searchParam } = useSearchParams();\r\n const [search, setSearch] = React.useState(searchParam ?? '');\r\n const { data: { items: allItems }, isLoading, errors: loadingErrors, fetchMore, hasMore } = useQuestionTags({ pageSize: undefined });\r\n const [isMenuOpen, toggleMenuOpen] = useToggleStateArray();\r\n const history = useHistory();\r\n\r\n // Filter by the questionTag's search client side so it can work when offline as well as online.\r\n const items = React.useMemo(() => {\r\n if (!allItems || !search) {\r\n return allItems;\r\n }\r\n\r\n let lowerSearch = search.toLocaleLowerCase();\r\n\r\n // Filter the items being displayed.\r\n return allItems.filter(item =>\r\n item.name.toLocaleLowerCase().indexOf(lowerSearch) >= 0\r\n );\r\n }, [allItems, search]);\r\n\r\n useReplaceSearchParamsEffect({ search: search });\r\n\r\n const [viewMode, setViewMode] = usePreferredListViewMode();\r\n\r\n\r\n return (\r\n \r\n \r\n \r\n \r\n \r\n

{t('administratorsQuestionTagList.heading', 'Tags')}

\r\n \r\n \r\n \r\n \r\n \r\n \r\n\r\n \r\n setSearch(e.currentTarget.value)} />\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n
\r\n
\r\n
\r\n\r\n \r\n \r\n history.push(`/administration/tags/edit/${item.id}`)}\r\n tableHeadings={[\r\n t('questionTagsListBase.name', 'Name'),\r\n ]}\r\n columns={[\r\n (item, view) => view === 'cards' ? ({item.name}) : item.name,\r\n ]}\r\n buttons={(item) => (\r\n \r\n \r\n \r\n \r\n toggleMenuOpen(item.id)}>\r\n \r\n {t('common.menuDropdown', 'More')}\r\n \r\n \r\n \r\n \r\n \r\n <> {t('common.delete', 'Delete')}\r\n \r\n \r\n \r\n \r\n \r\n )}\r\n />\r\n \r\n \r\n \r\n \r\n\r\n \r\n\r\n \r\n \r\n\r\n \r\n \r\n\r\n \r\n\r\n \r\n
\r\n );\r\n};\r\n","import * as React from 'react';\r\nimport { useLazyQuery } from \"@apollo/react-hooks\";\r\nimport gql from \"graphql-tag\";\r\nimport { Guid } from \"guid-string\";\r\nimport { AsyncLoadResult, AsyncLoadOptions } from '../../../shared/abstractStore';\r\nimport { questionTagQuery, questionTagQueryVariables } from '../generated/questionTagQuery';\r\nimport { questionTagFieldsFragment } from '../models/QuestionTag';\r\nimport { mainApiConfig } from '../../../configure/mainApiConfig';\r\n\r\n/**\r\n * Get a QuestionTag from the store.\r\n * @param id\r\n * @param options\r\n */\r\nexport function useQuestionTag(id: string | undefined | null, options: AsyncLoadOptions = {}): AsyncLoadResult {\r\n // Query the data we need form the api.\r\n const [load, { data, loading, error, refetch }] = useLazyQuery(\r\n gql`\r\n query questionTagQuery ($id: ID!) {\r\n model: questionTag(id: $id) {\r\n ...questionTagFields\r\n }\r\n }\r\n\r\n ${questionTagFieldsFragment}\r\n `,\r\n {\r\n variables: {\r\n id: id ?? Guid.empty,\r\n },\r\n fetchPolicy: options.fetchPolicy ?? mainApiConfig.defaultFetchPolicy,\r\n pollInterval: options.pollInterval,\r\n onCompleted: (data) => {\r\n if (options.onCompleted) {\r\n options.onCompleted(data);\r\n }\r\n }\r\n }\r\n );\r\n\r\n // Run the query (unless we are being lazy).\r\n React.useEffect(() => {\r\n if (!options.lazy) {\r\n load();\r\n }\r\n }, [options.lazy, load])\r\n\r\n // Return the results.\r\n const refresh = React.useCallback(async () => { !refetch ? await load() : await refetch(); }, [refetch, load]);\r\n return React.useMemo(() => ({\r\n data: data ?? ({} as any),\r\n refresh: refresh,\r\n isLoading: loading,\r\n errors: error\r\n }), [data, refresh, loading, error]);\r\n}\r\n","import { useMutation } from \"@apollo/react-hooks\";\r\nimport { useAsyncCallback } from 'react-use-async-callback';\r\nimport gql from \"graphql-tag\";\r\nimport { AsyncActionStatus } from '../../../shared/abstractStore';\r\nimport { QuestionTagCreateInput } from '../generated/globalTypes';\r\nimport { createQuestionTagMutation, createQuestionTagMutationVariables } from '../generated/createQuestionTagMutation';\r\nimport { questionTagFieldsFragment } from '../models/QuestionTag';\r\n\r\n/**\r\n * Get a callback to create a QuestionTag in the store.\r\n */\r\nexport function useCreateQuestionTagCallback(): [(model: QuestionTagCreateInput) => Promise, AsyncActionStatus] {\r\n const [mutationAction, { error }] = useMutation(\r\n gql`\r\n mutation createQuestionTagMutation ($model: QuestionTagCreateInput!) {\r\n createQuestionTag(model: $model) {\r\n ...questionTagFields\r\n }\r\n }\r\n\r\n ${questionTagFieldsFragment}\r\n `\r\n );\r\n\r\n // Wrap the mutation in a standard callback.\r\n const [action, { isExecuting, errors: actionErrors }] = useAsyncCallback(async (model: QuestionTagCreateInput) => {\r\n const result = await mutationAction({ variables: { model: model } });\r\n if (result.errors && result.errors.length) {\r\n throw result.errors;\r\n }\r\n }, [mutationAction]);\r\n\r\n return [action, { isExecuting: isExecuting, errors: error ? error.message : actionErrors }];\r\n}\r\n","import { useMutation } from \"@apollo/react-hooks\";\r\nimport { useAsyncCallback } from 'react-use-async-callback';\r\nimport gql from \"graphql-tag\";\r\nimport { AsyncActionStatus } from '../../../shared/abstractStore';\r\nimport { QuestionTagUpdateInput } from '../generated/globalTypes';\r\nimport { updateQuestionTagMutation, updateQuestionTagMutationVariables } from '../generated/updateQuestionTagMutation';\r\nimport { questionTagFieldsFragment } from '../models/QuestionTag';\r\n\r\n/**\r\n * Get a callback to update a QuestionTag in the store.\r\n */\r\nexport function useUpdateQuestionTagCallback(): [(id: string, model: QuestionTagUpdateInput) => Promise, AsyncActionStatus] {\r\n const [mutationAction, { error }] = useMutation(\r\n gql`\r\n mutation updateQuestionTagMutation ($model: QuestionTagUpdateInput!) {\r\n updateQuestionTag(model: $model) {\r\n ...questionTagFields\r\n }\r\n }\r\n\r\n ${questionTagFieldsFragment}\r\n `\r\n );\r\n\r\n // Wrap the mutation in a standard callback.\r\n const [action, { isExecuting, errors: actionErrors }] = useAsyncCallback(async (id: string, model: QuestionTagUpdateInput) => {\r\n const result = await mutationAction({ variables: { model: { ...model, id: id } } });\r\n if (result.errors && result.errors.length) {\r\n throw result.errors;\r\n }\r\n }, [mutationAction]);\r\n\r\n return [action, { isExecuting: isExecuting, errors: error ? error.message : actionErrors }];\r\n}\r\n","import { Button, Row, Col, Form, Label, FormGroup, Spinner } from 'reactstrap';\r\nimport { AlertOnErrors } from '../../shared/alertOnErrors';\r\nimport { LoadingIndicator } from '../shared/LoadingIndicator';\r\nimport { useTranslation } from 'react-i18next';\r\nimport { FontAwesomeIcon } from '@fortawesome/react-fontawesome';\r\nimport { MainContainer } from '../shared/MainContainer';\r\nimport { useParams, useHistory } from 'react-router';\r\nimport { useQuestionTag } from '../../api/main/questionTags/useQuestionTag';\r\nimport { useChanges } from '../../shared/useChanges';\r\nimport { useSaveQuestionTagCallback } from '../../api/main/questionTags/useSaveQuestionTagCallback';\r\nimport { useValidatorCallback } from 'pojo-validator-react';\r\nimport { ValidatedInput } from 'pojo-validator-reactstrap';\r\nimport { FormButtons } from '../shared/FormButtons';\r\nimport { ButtonAsync } from 'reactstrap-buttonasync';\r\nimport { useAsyncCallback } from 'react-use-async-callback';\r\nimport { Guid } from 'guid-string';\r\nimport { ConditionalFragment } from 'react-conditionalfragment';\r\nimport { Banner } from '../shared/Banner';\r\nimport { Background } from '../shared/background/Background';\r\n\r\ninterface EditQuestionTagProps {\r\n isCreate?: boolean,\r\n}\r\n\r\n/**\r\n * Create and invite a new questionTag.\r\n */\r\nexport const CreateQuestionTag = () => ();\r\n\r\n/**\r\n * Edit a questionTag.\r\n */\r\nexport const EditQuestionTag = (props: EditQuestionTagProps) => {\r\n const { isCreate } = props;\r\n\r\n const { t } = useTranslation();\r\n const { id } = useParams<{ id: string | undefined }>();\r\n const { data: { model: storeModel }, isLoading: _isLoading, errors: loadErrors } = useQuestionTag(id);\r\n const isLoading = _isLoading;\r\n const { model, change, changes } = useChanges(storeModel, isCreate ? { id: Guid.newGuid(), name: '', } : undefined);\r\n const [save, { errors: saveErrors }] = useSaveQuestionTagCallback();\r\n const history = useHistory();\r\n\r\n const [validate, validationErrors] = useValidatorCallback((validation, fieldsToCheck) => {\r\n const rules = {\r\n name: () => !model?.name ? t('editQuestionTag.nameRequired', 'Name is required') : '',\r\n };\r\n\r\n validation.checkRules(rules, fieldsToCheck);\r\n }, [model]);\r\n\r\n const [saveForm, { isExecuting: isSaving, errors: saveFormErrors }] = useAsyncCallback(async () => {\r\n if (!validate()) {\r\n return;\r\n }\r\n\r\n await save(model.id, changes, !!isCreate);\r\n\r\n history.goBack();\r\n }, [validate, save, model, changes, isCreate, history]);\r\n\r\n return (\r\n \r\n \r\n \r\n \r\n

\r\n {\r\n isCreate ? (\r\n <>{t('editQuestionTag.createHeading', 'Add tag')}\r\n ) : (\r\n <>{t('editQuestionTag.editHeading', 'Edit tag')}\r\n )\r\n }\r\n

\r\n \r\n \r\n \r\n \r\n \r\n \r\n
\r\n
\r\n\r\n \r\n \r\n\r\n
{ e.preventDefault(); saveForm(); }}>\r\n \r\n \r\n change({ name: e.currentTarget.value })} onBlur={e => validate('name')} validationErrors={validationErrors['name']} />\r\n \r\n \r\n \r\n {t('common.saving', 'Saving...')}}>\r\n \r\n <> {t('common.save', 'Save')}\r\n \r\n \r\n \r\n \r\n
\r\n
\r\n
\r\n );\r\n};\r\n","import * as React from 'react';\r\nimport { QuestionTagCreateInput, QuestionTagUpdateInput } from '../generated/globalTypes';\r\nimport { useSaveInStore, SaveInStoreOptions } from '../../../shared/useSaveInStore';\r\nimport { useCreateQuestionTagCallback } from './useCreateQuestionTagCallback';\r\nimport { useUpdateQuestionTagCallback } from './useUpdateQuestionTagCallback';\r\nimport { QuestionTag } from '../models/QuestionTag';\r\n\r\n/**\r\n * Get a callback to save a QuestionTag in the store using either a create or update.\r\n */\r\nexport function useSaveQuestionTagCallback(options: SaveInStoreOptions = {}) {\r\n const [_create, createStatus] = useCreateQuestionTagCallback();\r\n const create = React.useCallback((model: Partial) => _create(model as QuestionTagCreateInput), [_create]);\r\n\r\n const [_update, updateStatus] = useUpdateQuestionTagCallback();\r\n const update = React.useCallback((id: string, changes: Partial) => _update(id, changes as QuestionTagUpdateInput), [_update]);\r\n\r\n return useSaveInStore(\r\n [create, createStatus],\r\n [update, updateStatus],\r\n options\r\n );\r\n}\r\n","import { Button, Form, Label, FormGroup, Spinner, Input, Row, Col } from 'reactstrap';\r\nimport { AlertOnErrors } from '../../shared/alertOnErrors';\r\nimport { LoadingIndicator } from '../shared/LoadingIndicator';\r\nimport { useTranslation } from 'react-i18next';\r\nimport { FontAwesomeIcon } from '@fortawesome/react-fontawesome';\r\nimport { MainContainer } from '../shared/MainContainer';\r\nimport { useParams, useHistory } from 'react-router';\r\nimport { FormButtons } from '../shared/FormButtons';\r\nimport { ButtonAsync } from 'reactstrap-buttonasync';\r\nimport { useAsyncCallback } from 'react-use-async-callback';\r\nimport { useQuestionTag } from '../../api/main/questionTags/useQuestionTag';\r\nimport { useDeleteQuestionTagCallback } from '../../api/main/questionTags/useDeleteQuestionTagCallback';\r\nimport { ConditionalFragment } from 'react-conditionalfragment';\r\nimport { Banner } from '../shared/Banner';\r\nimport { Background } from '../shared/background/Background';\r\n\r\n/**\r\n * Delete a questionTag (profile) by locking them out permanently.\r\n */\r\nexport const DeleteQuestionTag = () => {\r\n const { t } = useTranslation();\r\n const { id } = useParams<{ id: string }>();\r\n const { data: { model }, isLoading, errors: loadErrors } = useQuestionTag(id);\r\n const [remove, { errors: removeErrors }] = useDeleteQuestionTagCallback();\r\n const history = useHistory();\r\n\r\n const [onRemoveFormSubmit, { isExecuting: isRemoving, errors: removeFormErrors }] = useAsyncCallback(async () => {\r\n if (!model) {\r\n return;\r\n }\r\n\r\n await remove(model.id);\r\n\r\n history.goBack();\r\n }, [model, history]);\r\n\r\n return (\r\n \r\n \r\n \r\n \r\n

{t('deleteQuestionTag.heading', 'Are you sure you want to delete this tag?')}

\r\n \r\n \r\n \r\n \r\n \r\n \r\n
\r\n
\r\n\r\n \r\n \r\n\r\n
{ e.preventDefault(); onRemoveFormSubmit(); }}>\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n {t('common.deleting', 'Deleting...')}}>\r\n \r\n <> {t('common.delete', 'Delete')}\r\n \r\n \r\n \r\n \r\n
\r\n
\r\n
\r\n );\r\n};\r\n","import { RouteEntry } from \"../../shared/routes\";\r\nimport { QuestionTagsList } from './QuestionTagsList';\r\nimport { EditQuestionTag, CreateQuestionTag } from \"./EditQuestionTag\";\r\nimport { IdentityRoles } from \"../../configure/security/IdentityRoles\";\r\nimport { DeleteQuestionTag } from \"./DeleteQuestionTag\";\r\n\r\nexport const questionTagRoutes: Array = [\r\n { path: '/administration/tags', exact: true, component: QuestionTagsList, authorize: true, requireRole: IdentityRoles.Administration },\r\n { path: '/administration/tags/edit/:id', component: EditQuestionTag, authorize: true, requireRole: IdentityRoles.Administration },\r\n { path: '/administration/tags/add', component: CreateQuestionTag, authorize: true, requireRole: IdentityRoles.Administration },\r\n { path: '/administration/tags/delete/:id', component: DeleteQuestionTag, authorize: true, requireRole: IdentityRoles.Administration },\r\n];\r\n","import * as React from 'react';\r\nimport { useLazyQuery } from \"@apollo/react-hooks\";\r\nimport gql from \"graphql-tag\";\r\nimport { AsyncLoadPagedResult, AsyncLoadPagedOptions } from '../../../shared/abstractStore';\r\nimport { useFetchMoreCallback } from '../../../shared/useFetchMoreCallback';\r\nimport { questionTagsQuery, questionTagsQueryVariables } from '../generated/questionTagsQuery';\r\nimport { mainApiConfig } from '../../../configure/mainApiConfig';\r\nimport { questionTagFieldsFragment } from '../models/QuestionTag';\r\n\r\n/**\r\n * Get a list of questionTags from the store.\r\n * @param id\r\n * @param options\r\n */\r\nexport function useQuestionTags(options: AsyncLoadPagedOptions = {}): AsyncLoadPagedResult {\r\n // Query data we need from the api.\r\n const [load, { data, loading, error, refetch, fetchMore: fetchMoreFromStore }] = useLazyQuery(\r\n gql`\r\n query questionTagsQuery ($offset: Int, $first: Int) {\r\n items: questionTags (offset: $offset, first: $first) {\r\n ...questionTagFields\r\n }\r\n }\r\n\r\n ${questionTagFieldsFragment}\r\n `,\r\n {\r\n\r\n variables: {\r\n offset: options.startOffset,\r\n first: options.pageSize\r\n },\r\n fetchPolicy: options.fetchPolicy ?? mainApiConfig.defaultFetchPolicy,\r\n pollInterval: options.pollInterval,\r\n onCompleted: (data) => {\r\n if (options.onCompleted) {\r\n options.onCompleted(data);\r\n }\r\n }\r\n }\r\n );\r\n\r\n // Run the query (unless we are being lazy).\r\n React.useEffect(() => {\r\n if (!options.lazy) {\r\n load();\r\n }\r\n }, [options.lazy, load])\r\n\r\n // Get the functions used to manage paging.\r\n const { fetchMore, hasMore: _hasMore } = useFetchMoreCallback(\r\n fetchMoreFromStore,\r\n (options?.startOffset ?? 0) + (data?.items?.length ?? 0),\r\n (prevResults, newResults) => ({\r\n ...prevResults,\r\n ...newResults,\r\n\r\n items: [...(prevResults?.items ?? []), ...(newResults?.items ?? [])]\r\n }),\r\n (newResults) => newResults?.items?.length\r\n );\r\n const hasMore = React.useCallback(() => !options.pageSize ? false : _hasMore(), [options.pageSize, _hasMore]);\r\n \r\n // Return the results.\r\n const refresh = React.useCallback(async () => { !refetch ? await load() : await refetch(); }, [refetch, load]);\r\n return React.useMemo(() => ({\r\n data: data ?? ({} as any),\r\n refresh: refresh,\r\n isLoading: loading,\r\n errors: error,\r\n fetchMore: fetchMore,\r\n hasMore: hasMore,\r\n }), [data, refresh, loading, error, fetchMore, hasMore]);\r\n}\r\n","import { useMutation } from \"@apollo/react-hooks\";\r\nimport { useAsyncCallback } from 'react-use-async-callback';\r\nimport gql from \"graphql-tag\";\r\nimport { AsyncActionStatus } from '../../../shared/abstractStore';\r\nimport { deleteQuestionTagMutation, deleteQuestionTagMutationVariables } from '../generated/deleteQuestionTagMutation';\r\nimport { questionTagFieldsFragment } from '../models/QuestionTag';\r\n\r\n/**\r\n * Get a callback to delete a QuestionTag in the store.\r\n */\r\nexport function useDeleteQuestionTagCallback(): [(id: string) => Promise, AsyncActionStatus] {\r\n const [mutationAction, { error }] = useMutation(\r\n gql`\r\n mutation deleteQuestionTagMutation ($id: ID!) {\r\n deleteQuestionTag(id: $id) {\r\n ...questionTagFields\r\n }\r\n }\r\n\r\n ${questionTagFieldsFragment}\r\n `\r\n );\r\n\r\n // Wrap the mutation in a standard callback.\r\n const [action, { isExecuting, errors: actionErrors }] = useAsyncCallback(async (id: string) => {\r\n const result = await mutationAction({ variables: { id: id } });\r\n if (result.errors && result.errors.length) {\r\n throw result.errors;\r\n }\r\n }, [mutationAction]);\r\n\r\n return [action, { isExecuting: isExecuting, errors: error ? error.message : actionErrors }];\r\n}\r\n","import gql from \"graphql-tag\";\r\nimport { driverMetricFields } from \"../generated/driverMetricFields\";\r\n\r\nexport const driverMetricFieldsFragment = gql`\r\n fragment driverMetricFields on DriverMetric {\r\n id\r\n name\r\n archived\r\n startValue\r\n }\r\n`;\r\n\r\n\r\nexport type DriverMetric = Omit;\r\n","import * as React from 'react';\r\nimport { Button, Row, Col, ButtonGroup, ButtonDropdown, DropdownToggle, DropdownMenu, DropdownItem, CardTitle } from 'reactstrap';\r\nimport { LinkContainer } from 'react-router-bootstrap';\r\nimport { AlertOnErrors } from '../../shared/alertOnErrors';\r\nimport { LoadingIndicator } from '../shared/LoadingIndicator';\r\nimport { useDriverMetrics } from '../../api/main/driverMetrics/useDriverMetrics';\r\nimport { Waypoint } from 'react-waypoint';\r\nimport { useReplaceSearchParamsEffect, useSearchParams } from '../../shared/useURLSearchParams';\r\nimport { useTranslation } from 'react-i18next';\r\nimport { SearchInput } from '../shared/searchInput/SearchInput';\r\nimport { FontAwesomeIcon } from '@fortawesome/react-fontawesome';\r\nimport { MainContainer } from '../shared/MainContainer';\r\nimport { NoResultsFound } from '../shared/NoResultsFound';\r\nimport { StickyToolbar } from '../shared/StickyToolbar';\r\nimport { useHistory } from 'react-router';\r\nimport { ConditionalFragment } from 'react-conditionalfragment';\r\nimport { Banner } from '../shared/Banner';\r\nimport { useToggleStateArray } from 'use-toggle-state';\r\nimport { Background } from '../shared/background/Background';\r\nimport { CardsOrTable } from '../shared/cardsOrTable/CardsOrTable';\r\nimport { usePreferredListViewMode } from '../../globalState/preferredListViewMode/usePreferredListViewMode';\r\n\r\n\r\n\r\n/**\r\n * List of DriverMetrics.\r\n */\r\nexport const DriverMetricsList = () => {\r\n const { t } = useTranslation();\r\n const { search: searchParam } = useSearchParams();\r\n const [search, setSearch] = React.useState(searchParam ?? '');\r\n const { data: { items: allItems }, isLoading, errors: loadingErrors, fetchMore, hasMore } = useDriverMetrics({ pageSize: undefined });\r\n const [isMenuOpen, toggleMenuOpen] = useToggleStateArray();\r\n const history = useHistory();\r\n\r\n // Filter by the driverMetric's search client side so it can work when offline as well as online.\r\n const items = React.useMemo(() => {\r\n if (!allItems || !search) {\r\n return allItems;\r\n }\r\n\r\n let lowerSearch = search.toLocaleLowerCase();\r\n\r\n // Filter the items being displayed.\r\n return allItems.filter(item =>\r\n item.name.toLocaleLowerCase().indexOf(lowerSearch) >= 0\r\n );\r\n }, [allItems, search]);\r\n\r\n useReplaceSearchParamsEffect({ search: search });\r\n\r\n const [viewMode, setViewMode] = usePreferredListViewMode();\r\n\r\n\r\n return (\r\n \r\n \r\n \r\n \r\n \r\n

{t('administratorsDriverMetricList.heading', 'Safety metrics')}

\r\n \r\n \r\n \r\n \r\n \r\n \r\n\r\n \r\n setSearch(e.currentTarget.value)} />\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n
\r\n
\r\n
\r\n\r\n \r\n \r\n history.push(`/administration/safety-metrics/edit/${item.id}`)}\r\n tableHeadings={[\r\n t('driverMetricBase.name', 'Name'),\r\n ]}\r\n columns={[\r\n (item, view) => view === 'cards' ? ({item.name}) : item.name,\r\n ]}\r\n\r\n buttons={(item) => (\r\n\r\n \r\n \r\n \r\n \r\n toggleMenuOpen(item.id)}>\r\n \r\n {t('common.menuDropdown', 'More')}\r\n \r\n \r\n \r\n \r\n \r\n <> {t('common.delete', 'Delete')}\r\n \r\n \r\n \r\n \r\n \r\n )}\r\n />\r\n \r\n \r\n \r\n \r\n\r\n \r\n\r\n \r\n \r\n\r\n \r\n \r\n\r\n \r\n\r\n \r\n
\r\n );\r\n};\r\n","import * as React from 'react';\r\nimport { useLazyQuery } from \"@apollo/react-hooks\";\r\nimport gql from \"graphql-tag\";\r\nimport { Guid } from \"guid-string\";\r\nimport { AsyncLoadResult, AsyncLoadOptions } from '../../../shared/abstractStore';\r\nimport { driverMetricQuery, driverMetricQueryVariables } from '../generated/driverMetricQuery';\r\nimport { driverMetricFieldsFragment } from '../models/DriverMetric';\r\nimport { mainApiConfig } from '../../../configure/mainApiConfig';\r\n\r\n/**\r\n * Get a DriverMetric from the store.\r\n * @param id\r\n * @param options\r\n */\r\nexport function useDriverMetric(id: string | undefined | null, options: AsyncLoadOptions = {}): AsyncLoadResult {\r\n // Query the data we need form the api.\r\n const [load, { data, loading, error, refetch }] = useLazyQuery(\r\n gql`\r\n query driverMetricQuery ($id: ID!) {\r\n model: driverMetric(id: $id) {\r\n ...driverMetricFields\r\n }\r\n }\r\n\r\n ${driverMetricFieldsFragment}\r\n `,\r\n {\r\n variables: {\r\n id: id ?? Guid.empty,\r\n },\r\n fetchPolicy: options.fetchPolicy ?? mainApiConfig.defaultFetchPolicy,\r\n pollInterval: options.pollInterval,\r\n onCompleted: (data) => {\r\n if (options.onCompleted) {\r\n options.onCompleted(data);\r\n }\r\n }\r\n }\r\n );\r\n\r\n // Run the query (unless we are being lazy).\r\n React.useEffect(() => {\r\n if (!options.lazy) {\r\n load();\r\n }\r\n }, [options.lazy, load])\r\n\r\n // Return the results.\r\n const refresh = React.useCallback(async () => { !refetch ? await load() : await refetch(); }, [refetch, load]);\r\n return React.useMemo(() => ({\r\n data: data ?? ({} as any),\r\n refresh: refresh,\r\n isLoading: loading,\r\n errors: error\r\n }), [data, refresh, loading, error]);\r\n}\r\n","import { useMutation } from \"@apollo/react-hooks\";\r\nimport { useAsyncCallback } from 'react-use-async-callback';\r\nimport gql from \"graphql-tag\";\r\nimport { AsyncActionStatus } from '../../../shared/abstractStore';\r\nimport { DriverMetricCreateInput } from '../generated/globalTypes';\r\nimport { createDriverMetricMutation, createDriverMetricMutationVariables } from '../generated/createDriverMetricMutation';\r\nimport { driverMetricFieldsFragment } from '../models/DriverMetric';\r\n\r\n/**\r\n * Get a callback to create a DriverMetric in the store.\r\n */\r\nexport function useCreateDriverMetricCallback(): [(model: DriverMetricCreateInput) => Promise, AsyncActionStatus] {\r\n const [mutationAction, { error }] = useMutation(\r\n gql`\r\n mutation createDriverMetricMutation ($model: DriverMetricCreateInput!) {\r\n createDriverMetric(model: $model) {\r\n ...driverMetricFields\r\n }\r\n }\r\n\r\n ${driverMetricFieldsFragment}\r\n `\r\n );\r\n\r\n // Wrap the mutation in a standard callback.\r\n const [action, { isExecuting, errors: actionErrors }] = useAsyncCallback(async (model: DriverMetricCreateInput) => {\r\n const result = await mutationAction({ variables: { model: model } });\r\n if (result.errors && result.errors.length) {\r\n throw result.errors;\r\n }\r\n }, [mutationAction]);\r\n\r\n return [action, { isExecuting: isExecuting, errors: error ? error.message : actionErrors }];\r\n}\r\n","import { useMutation } from \"@apollo/react-hooks\";\r\nimport { useAsyncCallback } from 'react-use-async-callback';\r\nimport gql from \"graphql-tag\";\r\nimport { AsyncActionStatus } from '../../../shared/abstractStore';\r\nimport { DriverMetricUpdateInput } from '../generated/globalTypes';\r\nimport { updateDriverMetricMutation, updateDriverMetricMutationVariables } from '../generated/updateDriverMetricMutation';\r\nimport { driverMetricFieldsFragment } from '../models/DriverMetric';\r\n\r\n/**\r\n * Get a callback to update a DriverMetric in the store.\r\n */\r\nexport function useUpdateDriverMetricCallback(): [(id: string, model: DriverMetricUpdateInput) => Promise, AsyncActionStatus] {\r\n const [mutationAction, { error }] = useMutation(\r\n gql`\r\n mutation updateDriverMetricMutation ($model: DriverMetricUpdateInput!) {\r\n updateDriverMetric(model: $model) {\r\n ...driverMetricFields\r\n }\r\n }\r\n\r\n ${driverMetricFieldsFragment}\r\n `\r\n );\r\n\r\n // Wrap the mutation in a standard callback.\r\n const [action, { isExecuting, errors: actionErrors }] = useAsyncCallback(async (id: string, model: DriverMetricUpdateInput) => {\r\n const result = await mutationAction({ variables: { model: { ...model, id: id } } });\r\n if (result.errors && result.errors.length) {\r\n throw result.errors;\r\n }\r\n }, [mutationAction]);\r\n\r\n return [action, { isExecuting: isExecuting, errors: error ? error.message : actionErrors }];\r\n}\r\n","import { Button, Row, Col, Form, Label, FormGroup, Spinner } from 'reactstrap';\r\nimport { AlertOnErrors } from '../../shared/alertOnErrors';\r\nimport { LoadingIndicator } from '../shared/LoadingIndicator';\r\nimport { useTranslation } from 'react-i18next';\r\nimport { FontAwesomeIcon } from '@fortawesome/react-fontawesome';\r\nimport { MainContainer } from '../shared/MainContainer';\r\nimport { useParams, useHistory } from 'react-router';\r\nimport { useDriverMetric } from '../../api/main/driverMetrics/useDriverMetric';\r\nimport { useChanges } from '../../shared/useChanges';\r\nimport { useSaveDriverMetricCallback } from '../../api/main/driverMetrics/useSaveDriverMetricCallback';\r\nimport { useValidatorCallback } from 'pojo-validator-react';\r\nimport { ValidatedInput } from 'pojo-validator-reactstrap';\r\nimport { FormButtons } from '../shared/FormButtons';\r\nimport { ButtonAsync } from 'reactstrap-buttonasync';\r\nimport { useAsyncCallback } from 'react-use-async-callback';\r\nimport { Guid } from 'guid-string';\r\nimport { ConditionalFragment } from 'react-conditionalfragment';\r\nimport { Banner } from '../shared/Banner';\r\nimport { Background } from '../shared/background/Background';\r\n\r\ninterface EditDriverMetricProps {\r\n isCreate?: boolean,\r\n}\r\n\r\n/**\r\n * Create and invite a new driverMetric.\r\n */\r\nexport const CreateDriverMetric = () => ();\r\n\r\n/**\r\n * Edit a driverMetric.\r\n */\r\nexport const EditDriverMetric = (props: EditDriverMetricProps) => {\r\n const { isCreate } = props;\r\n\r\n const { t } = useTranslation();\r\n const { id } = useParams<{ id: string | undefined }>();\r\n const { data: { model: storeModel }, isLoading: _isLoading, errors: loadErrors } = useDriverMetric(id);\r\n const isLoading = _isLoading;\r\n const { model, change, changes } = useChanges(storeModel, isCreate ? { id: Guid.newGuid(), name: '', startValue: 0, } : undefined);\r\n const [save, { errors: saveErrors }] = useSaveDriverMetricCallback();\r\n const history = useHistory();\r\n\r\n const [validate, validationErrors] = useValidatorCallback((validation, fieldsToCheck) => {\r\n const rules = {\r\n name: () => !model?.name ? t('editDriverMetric.nameRequired', 'Name is required') : '',\r\n };\r\n\r\n validation.checkRules(rules, fieldsToCheck);\r\n }, [model]);\r\n\r\n const [saveForm, { isExecuting: isSaving, errors: saveFormErrors }] = useAsyncCallback(async () => {\r\n if (!validate()) {\r\n return;\r\n }\r\n\r\n await save(model.id, changes, !!isCreate);\r\n\r\n history.goBack();\r\n }, [validate, save, model, changes, isCreate, history]);\r\n\r\n return (\r\n \r\n \r\n \r\n \r\n

\r\n {\r\n isCreate ? (\r\n <>{t('editDriverMetric.createHeading', 'Add safety metric')}\r\n ) : (\r\n <>{t('editDriverMetric.editHeading', 'Edit safety metric')}\r\n )\r\n }\r\n

\r\n \r\n \r\n \r\n \r\n \r\n \r\n
\r\n
\r\n\r\n \r\n \r\n\r\n
{ e.preventDefault(); saveForm(); }}>\r\n \r\n \r\n change({ name: e.currentTarget.value })} onBlur={e => validate('name')} validationErrors={validationErrors['name']} />\r\n \r\n \r\n \r\n {t('common.saving', 'Saving...')}}>\r\n \r\n <> {t('common.save', 'Save')}\r\n \r\n \r\n \r\n \r\n
\r\n
\r\n
\r\n );\r\n};\r\n","import * as React from 'react';\r\nimport { DriverMetricCreateInput, DriverMetricUpdateInput } from '../generated/globalTypes';\r\nimport { useSaveInStore, SaveInStoreOptions } from '../../../shared/useSaveInStore';\r\nimport { useCreateDriverMetricCallback } from './useCreateDriverMetricCallback';\r\nimport { useUpdateDriverMetricCallback } from './useUpdateDriverMetricCallback';\r\nimport { DriverMetric } from '../models/DriverMetric';\r\n\r\n/**\r\n * Get a callback to save a DriverMetric in the store using either a create or update.\r\n */\r\nexport function useSaveDriverMetricCallback(options: SaveInStoreOptions = {}) {\r\n const [_create, createStatus] = useCreateDriverMetricCallback();\r\n const create = React.useCallback((model: Partial) => _create(model as DriverMetricCreateInput), [_create]);\r\n\r\n const [_update, updateStatus] = useUpdateDriverMetricCallback();\r\n const update = React.useCallback((id: string, changes: Partial) => _update(id, changes as DriverMetricUpdateInput), [_update]);\r\n\r\n return useSaveInStore(\r\n [create, createStatus],\r\n [update, updateStatus],\r\n options\r\n );\r\n}\r\n","import { Button, Form, Label, FormGroup, Spinner, Input, Row, Col } from 'reactstrap';\r\nimport { AlertOnErrors } from '../../shared/alertOnErrors';\r\nimport { LoadingIndicator } from '../shared/LoadingIndicator';\r\nimport { useTranslation } from 'react-i18next';\r\nimport { FontAwesomeIcon } from '@fortawesome/react-fontawesome';\r\nimport { MainContainer } from '../shared/MainContainer';\r\nimport { useParams, useHistory } from 'react-router';\r\nimport { FormButtons } from '../shared/FormButtons';\r\nimport { ButtonAsync } from 'reactstrap-buttonasync';\r\nimport { useAsyncCallback } from 'react-use-async-callback';\r\nimport { useDriverMetric } from '../../api/main/driverMetrics/useDriverMetric';\r\nimport { useDeleteDriverMetricCallback } from '../../api/main/driverMetrics/useDeleteDriverMetricCallback';\r\nimport { ConditionalFragment } from 'react-conditionalfragment';\r\nimport { Banner } from '../shared/Banner';\r\nimport { Background } from '../shared/background/Background';\r\n\r\n/**\r\n * Delete a driverMetric (profile) by locking them out permanently.\r\n */\r\nexport const DeleteDriverMetric = () => {\r\n const { t } = useTranslation();\r\n const { id } = useParams<{ id: string }>();\r\n const { data: { model }, isLoading, errors: loadErrors } = useDriverMetric(id);\r\n const [remove, { errors: removeErrors }] = useDeleteDriverMetricCallback();\r\n const history = useHistory();\r\n\r\n const [onRemoveFormSubmit, { isExecuting: isRemoving, errors: removeFormErrors }] = useAsyncCallback(async () => {\r\n if (!model) {\r\n return;\r\n }\r\n\r\n await remove(model.id);\r\n\r\n history.goBack();\r\n }, [model, history]);\r\n\r\n return (\r\n \r\n \r\n \r\n \r\n

{t('deleteDriverMetric.heading', 'Are you sure you want to delete this safety metric?')}

\r\n \r\n \r\n \r\n \r\n \r\n \r\n
\r\n
\r\n\r\n \r\n \r\n\r\n
{ e.preventDefault(); onRemoveFormSubmit(); }}>\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n {t('common.deleting', 'Deleting...')}}>\r\n \r\n <> {t('common.delete', 'Delete')}\r\n \r\n \r\n \r\n \r\n
\r\n
\r\n
\r\n );\r\n};\r\n","import { RouteEntry } from \"../../shared/routes\";\r\nimport { DriverMetricsList } from './DriverMetricsList';\r\nimport { EditDriverMetric, CreateDriverMetric } from \"./EditDriverMetric\";\r\nimport { IdentityRoles } from \"../../configure/security/IdentityRoles\";\r\nimport { DeleteDriverMetric } from \"./DeleteDriverMetric\";\r\n\r\nexport const driverMetricRoutes: Array = [\r\n { path: '/administration/safety-metrics', exact: true, component: DriverMetricsList, authorize: true, requireRole: IdentityRoles.Administration },\r\n { path: '/administration/safety-metrics/edit/:id', component: EditDriverMetric, authorize: true, requireRole: IdentityRoles.Administration },\r\n { path: '/administration/safety-metrics/add', component: CreateDriverMetric, authorize: true, requireRole: IdentityRoles.Administration },\r\n { path: '/administration/safety-metrics/delete/:id', component: DeleteDriverMetric, authorize: true, requireRole: IdentityRoles.Administration },\r\n];\r\n","import * as React from 'react';\r\nimport { useLazyQuery } from \"@apollo/react-hooks\";\r\nimport gql from \"graphql-tag\";\r\nimport { AsyncLoadPagedResult, AsyncLoadPagedOptions } from '../../../shared/abstractStore';\r\nimport { useFetchMoreCallback } from '../../../shared/useFetchMoreCallback';\r\nimport { driverMetricsQuery, driverMetricsQueryVariables } from '../generated/driverMetricsQuery';\r\nimport { mainApiConfig } from '../../../configure/mainApiConfig';\r\nimport { driverMetricFieldsFragment } from '../models/DriverMetric';\r\n\r\n/**\r\n * Get a list of driverMetrics from the store.\r\n * @param id\r\n * @param options\r\n */\r\nexport function useDriverMetrics(options: AsyncLoadPagedOptions = {}): AsyncLoadPagedResult {\r\n // Query data we need from the api.\r\n const [load, { data, loading, error, refetch, fetchMore: fetchMoreFromStore }] = useLazyQuery(\r\n gql`\r\n query driverMetricsQuery ($offset: Int, $first: Int) {\r\n items: driverMetrics (offset: $offset, first: $first) {\r\n ...driverMetricFields\r\n }\r\n }\r\n\r\n ${driverMetricFieldsFragment}\r\n `,\r\n {\r\n\r\n variables: {\r\n offset: options.startOffset,\r\n first: options.pageSize\r\n },\r\n fetchPolicy: options.fetchPolicy ?? mainApiConfig.defaultFetchPolicy,\r\n pollInterval: options.pollInterval,\r\n onCompleted: (data) => {\r\n if (options.onCompleted) {\r\n options.onCompleted(data);\r\n }\r\n }\r\n }\r\n );\r\n\r\n // Run the query (unless we are being lazy).\r\n React.useEffect(() => {\r\n if (!options.lazy) {\r\n load();\r\n }\r\n }, [options.lazy, load])\r\n\r\n // Get the functions used to manage paging.\r\n const { fetchMore, hasMore: _hasMore } = useFetchMoreCallback(\r\n fetchMoreFromStore,\r\n (options?.startOffset ?? 0) + (data?.items?.length ?? 0),\r\n (prevResults, newResults) => ({\r\n ...prevResults,\r\n ...newResults,\r\n\r\n items: [...(prevResults?.items ?? []), ...(newResults?.items ?? [])]\r\n }),\r\n (newResults) => newResults?.items?.length\r\n );\r\n const hasMore = React.useCallback(() => !options.pageSize ? false : _hasMore(), [options.pageSize, _hasMore]);\r\n \r\n // Return the results.\r\n const refresh = React.useCallback(async () => { !refetch ? await load() : await refetch(); }, [refetch, load]);\r\n return React.useMemo(() => ({\r\n data: data ?? ({} as any),\r\n refresh: refresh,\r\n isLoading: loading,\r\n errors: error,\r\n fetchMore: fetchMore,\r\n hasMore: hasMore,\r\n }), [data, refresh, loading, error, fetchMore, hasMore]);\r\n}\r\n","import { useMutation } from \"@apollo/react-hooks\";\r\nimport { useAsyncCallback } from 'react-use-async-callback';\r\nimport gql from \"graphql-tag\";\r\nimport { AsyncActionStatus } from '../../../shared/abstractStore';\r\nimport { deleteDriverMetricMutation, deleteDriverMetricMutationVariables } from '../generated/deleteDriverMetricMutation';\r\nimport { driverMetricFieldsFragment } from '../models/DriverMetric';\r\n\r\n/**\r\n * Get a callback to delete a DriverMetric in the store.\r\n */\r\nexport function useDeleteDriverMetricCallback(): [(id: string) => Promise, AsyncActionStatus] {\r\n const [mutationAction, { error }] = useMutation(\r\n gql`\r\n mutation deleteDriverMetricMutation ($id: ID!) {\r\n deleteDriverMetric(id: $id) {\r\n ...driverMetricFields\r\n }\r\n }\r\n\r\n ${driverMetricFieldsFragment}\r\n `\r\n );\r\n\r\n // Wrap the mutation in a standard callback.\r\n const [action, { isExecuting, errors: actionErrors }] = useAsyncCallback(async (id: string) => {\r\n const result = await mutationAction({ variables: { id: id } });\r\n if (result.errors && result.errors.length) {\r\n throw result.errors;\r\n }\r\n }, [mutationAction]);\r\n\r\n return [action, { isExecuting: isExecuting, errors: error ? error.message : actionErrors }];\r\n}\r\n","import * as React from 'react';\r\nimport { Button, Row, Col, ButtonGroup, ButtonDropdown, DropdownToggle, DropdownMenu, DropdownItem, CardTitle } from 'reactstrap';\r\nimport { LinkContainer } from 'react-router-bootstrap';\r\nimport { AlertOnErrors } from '../../shared/alertOnErrors';\r\nimport { LoadingIndicator } from '../shared/LoadingIndicator';\r\nimport { Waypoint } from 'react-waypoint';\r\nimport { useReplaceSearchParamsEffect, useSearchParams } from '../../shared/useURLSearchParams';\r\nimport { useTranslation } from 'react-i18next';\r\nimport { SearchInput } from '../shared/searchInput/SearchInput';\r\nimport { FontAwesomeIcon } from '@fortawesome/react-fontawesome';\r\nimport { MainContainer } from '../shared/MainContainer';\r\nimport { NoResultsFound } from '../shared/NoResultsFound';\r\nimport { StickyToolbar } from '../shared/StickyToolbar';\r\nimport { useHistory, useParams } from 'react-router';\r\nimport { ConditionalFragment } from 'react-conditionalfragment';\r\nimport { Banner } from '../shared/Banner';\r\nimport { useToggleStateArray } from 'use-toggle-state';\r\nimport { Background } from '../shared/background/Background';\r\nimport { useSubscriptions } from '../../api/main/subscriptions/useSubscriptions';\r\nimport { useSubscriptionEmulation } from \"../../globalState/subscriptions/useSubscriptionEmulation\";\r\nimport { CardsOrTable} from '../shared/cardsOrTable/CardsOrTable';\r\nimport { usePreferredListViewMode } from '../../globalState/preferredListViewMode/usePreferredListViewMode';\r\nimport { SubscriptionType } from '../../api/main/models/codeOnly/SubscriptionType'\r\nimport { PillsNavBar } from '../shared/pillsNavBar/PillsNavBar';\r\n\r\nexport interface SubscriptionListBaseBaseProps {\r\n title: string,\r\n subscriptionTypes: Array,\r\n baseRoute: string,\r\n distributorSubscriptionList?: boolean,\r\n navigationPills?: React.ReactNode,\r\n}\r\n\r\n/**\r\n * List of subscriptions.\r\n */\r\nexport const SubscriptionsListBase = (props: SubscriptionListBaseBaseProps) => {\r\n const {\r\n title,\r\n subscriptionTypes,\r\n baseRoute,\r\n navigationPills,\r\n distributorSubscriptionList = false,\r\n } = props\r\n\r\n const { t } = useTranslation();\r\n const { search: searchParam } = useSearchParams();\r\n const [search, setSearch] = React.useState(searchParam ?? '');\r\n const { data: { items: allItems }, isLoading, errors: loadingErrors, fetchMore, hasMore } = useSubscriptions({ pageSize: undefined, subscriptionTypes: subscriptionTypes});\r\n const [isMenuOpen, toggleMenuOpen] = useToggleStateArray();\r\n const history = useHistory();\r\n\r\n const [currentEmulatedSubscriptionId, emulateSubscription] = useSubscriptionEmulation();\r\n const { subscriptionId } = useParams<{ subscriptionId: string | undefined }>();\r\n const [subscriptionIdToUse, setSubscriptionIdToUse] = React.useState();\r\n\r\n React.useEffect(() => {\r\n\r\n if (currentEmulatedSubscriptionId === null) {\r\n setSubscriptionIdToUse(subscriptionId);\r\n }\r\n else {\r\n setSubscriptionIdToUse(currentEmulatedSubscriptionId)\r\n }\r\n\r\n\r\n }, [currentEmulatedSubscriptionId, subscriptionId, setSubscriptionIdToUse]);\r\n\r\n const onManage = React.useCallback((id) => {\r\n emulateSubscription(id);\r\n }, [emulateSubscription]);\r\n\r\n const onStopManaging = React.useCallback((id) => {\r\n emulateSubscription(null);\r\n }, [emulateSubscription]);\r\n\r\n // Filter by the user's search client side so it can work when offline as well as online.\r\n const items = React.useMemo(() => {\r\n let ret = (allItems ?? []);\r\n\r\n if (distributorSubscriptionList) {\r\n //If we are in a distributor admin area, we only want to see subscriptions relating to the current distributor\r\n ret = ret.filter(item => item.distributorSubscriptionId === subscriptionIdToUse);\r\n\r\n }\r\n\r\n if (!allItems || !search) {\r\n return ret;\r\n }\r\n\r\n let lowerSearch = search.toLocaleLowerCase();\r\n\r\n // Filter the items being displayed.\r\n return ret.filter(item =>\r\n item.companyName.toLocaleLowerCase().indexOf(lowerSearch) >= 0\r\n );\r\n }, [allItems, search, distributorSubscriptionList, subscriptionIdToUse]);\r\n\r\n useReplaceSearchParamsEffect({ search: search });\r\n\r\n const [viewMode, setViewMode] = usePreferredListViewMode();\r\n\r\n return (\r\n \r\n \r\n \r\n \r\n \r\n \r\n

\r\n {title}\r\n

\r\n \r\n \r\n \r\n {navigationPills}\r\n \r\n \r\n\r\n
\r\n
\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n setSearch(e.currentTarget.value)} />\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n
\r\n
\r\n\r\n \r\n \r\n history.push(`${baseRoute}/edit/${item.id}`)}\r\n tableHeadings={[\r\n t('subscriptionsListBase.name', 'Name'), \r\n t('subscriptionsListBase.userCount', 'User count')\r\n ]}\r\n columns={[\r\n (item, view) => view === 'cards' ? ({item.companyName}) : item.companyName,\r\n (item, view) => view === 'cards' ? (t('subscriptionsListBase.userCountCard', 'User count: ') + item.currentUsers) : item.currentUsers,\r\n ]}\r\n buttons={(item) => (\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n toggleMenuOpen(item.id)}>\r\n \r\n {t('common.menuDropdown', 'More')}\r\n \r\n \r\n \r\n \r\n \r\n <> {t('common.delete', 'Delete')}\r\n \r\n \r\n \r\n \r\n \r\n )}\r\n />\r\n \r\n \r\n \r\n\r\n \r\n \r\n \r\n\r\n \r\n \r\n \r\n \r\n\r\n \r\n
\r\n );\r\n};\r\n","import * as React from 'react';\r\nimport { useLazyQuery } from \"@apollo/react-hooks\";\r\nimport gql from \"graphql-tag\";\r\nimport { AsyncLoadPagedResult, AsyncLoadPagedOptions } from '../../../shared/abstractStore';\r\nimport { useFetchMoreCallback } from '../../../shared/useFetchMoreCallback';\r\nimport { subscriptionsQuery, subscriptionsQueryVariables } from '../generated/subscriptionsQuery';\r\nimport { mainApiConfig } from '../../../configure/mainApiConfig';\r\nimport { subscriptionFieldsFragment } from '../models/Subscription';\r\nimport { SubscriptionType } from '../models/codeOnly/SubscriptionType';\r\n\r\nexport interface SubscriptionsAsyncLoadPageOptions extends AsyncLoadPagedOptions {\r\n subscriptionTypes?: Array,\r\n}\r\n\r\n/**\r\n * Get a list of subscriptions from the store.\r\n * @param id\r\n * @param options\r\n */\r\nexport function useSubscriptions(options: SubscriptionsAsyncLoadPageOptions = {}): AsyncLoadPagedResult {\r\n // Query data we need from the api.\r\n const [load, { data, loading, error, refetch, fetchMore: fetchMoreFromStore }] = useLazyQuery(\r\n gql`\r\n query subscriptionsQuery ($offset: Int, $first: Int, $subscriptionTypes: [String!]) {\r\n items: subscriptions (offset: $offset, first: $first, subscriptionTypes: $subscriptionTypes) {\r\n ...subscriptionFields\r\n }\r\n }\r\n\r\n ${subscriptionFieldsFragment}\r\n `,\r\n {\r\n\r\n variables: {\r\n offset: options.startOffset,\r\n first: options.pageSize,\r\n subscriptionTypes: options.subscriptionTypes,\r\n },\r\n fetchPolicy: options.fetchPolicy ?? mainApiConfig.defaultFetchPolicy,\r\n pollInterval: options.pollInterval,\r\n onCompleted: (data) => {\r\n if (options.onCompleted) {\r\n options.onCompleted(data);\r\n }\r\n }\r\n }\r\n );\r\n\r\n // Run the query (unless we are being lazy).\r\n React.useEffect(() => {\r\n if (!options.lazy) {\r\n load();\r\n }\r\n }, [options.lazy, load])\r\n\r\n // Get the functions used to manage paging.\r\n const { fetchMore, hasMore: _hasMore } = useFetchMoreCallback(\r\n fetchMoreFromStore,\r\n (options?.startOffset ?? 0) + (data?.items?.length ?? 0),\r\n (prevResults, newResults) => ({\r\n ...prevResults,\r\n ...newResults,\r\n\r\n items: [...(prevResults?.items ?? []), ...(newResults?.items ?? [])]\r\n }),\r\n (newResults) => newResults?.items?.length\r\n );\r\n const hasMore = React.useCallback(() => !options.pageSize ? false : _hasMore(), [options.pageSize, _hasMore]);\r\n \r\n // Return the results.\r\n const refresh = React.useCallback(async () => { !refetch ? await load() : await refetch(); }, [refetch, load]);\r\n return React.useMemo(() => ({\r\n data: data ?? ({} as any),\r\n refresh: refresh,\r\n isLoading: loading,\r\n errors: error,\r\n fetchMore: fetchMore,\r\n hasMore: hasMore,\r\n }), [data, refresh, loading, error, fetchMore, hasMore]);\r\n}\r\n","import { useMutation } from \"@apollo/react-hooks\";\r\nimport { useAsyncCallback } from 'react-use-async-callback';\r\nimport gql from \"graphql-tag\";\r\nimport { AsyncActionStatus } from '../../../shared/abstractStore';\r\nimport { SubscriptionCreateInput } from '../generated/globalTypes';\r\nimport { createSubscriptionMutation, createSubscriptionMutationVariables } from '../generated/createSubscriptionMutation';\r\nimport { subscriptionFieldsFragment } from '../models/Subscription';\r\n\r\n/**\r\n * Get a callback to create a Subscription in the store.\r\n */\r\nexport function useCreateSubscriptionCallback(): [(model: SubscriptionCreateInput) => Promise, AsyncActionStatus] {\r\n const [mutationAction, { error }] = useMutation(\r\n gql`\r\n mutation createSubscriptionMutation ($model: SubscriptionCreateInput!) {\r\n createSubscription(model: $model) {\r\n ...subscriptionFields\r\n }\r\n }\r\n\r\n ${subscriptionFieldsFragment}\r\n `\r\n );\r\n\r\n // Wrap the mutation in a standard callback.\r\n const [action, { isExecuting, errors: actionErrors }] = useAsyncCallback(async (model: SubscriptionCreateInput) => {\r\n const result = await mutationAction({ variables: { model: model } });\r\n if (result.errors && result.errors.length) {\r\n throw result.errors;\r\n }\r\n }, [mutationAction]);\r\n\r\n return [action, { isExecuting: isExecuting, errors: error ? error.message : actionErrors }];\r\n}\r\n","import { useMutation } from \"@apollo/react-hooks\";\r\nimport { useAsyncCallback } from 'react-use-async-callback';\r\nimport gql from \"graphql-tag\";\r\nimport { AsyncActionStatus } from '../../../shared/abstractStore';\r\nimport { SubscriptionUpdateInput } from '../generated/globalTypes';\r\nimport { updateSubscriptionMutation, updateSubscriptionMutationVariables } from '../generated/updateSubscriptionMutation';\r\nimport { subscriptionFieldsFragment } from '../models/Subscription';\r\n\r\n/**\r\n * Get a callback to update a Subscription in the store.\r\n */\r\nexport function useUpdateSubscriptionCallback(): [(id: string, model: SubscriptionUpdateInput) => Promise, AsyncActionStatus] {\r\n const [mutationAction, { error }] = useMutation(\r\n gql`\r\n mutation updateSubscriptionMutation ($model: SubscriptionUpdateInput!) {\r\n updateSubscription(model: $model) {\r\n ...subscriptionFields\r\n }\r\n }\r\n\r\n ${subscriptionFieldsFragment}\r\n `\r\n );\r\n\r\n // Wrap the mutation in a standard callback.\r\n const [action, { isExecuting, errors: actionErrors }] = useAsyncCallback(async (id: string, model: SubscriptionUpdateInput) => {\r\n const result = await mutationAction({ variables: { model: { ...model, id: id } } });\r\n if (result.errors && result.errors.length) {\r\n throw result.errors;\r\n }\r\n }, [mutationAction]);\r\n\r\n return [action, { isExecuting: isExecuting, errors: error ? error.message : actionErrors }];\r\n}\r\n","import * as React from 'react';\r\nimport { SubscriptionCreateInput, SubscriptionUpdateInput } from '../generated/globalTypes';\r\nimport { useSaveInStore, SaveInStoreOptions } from '../../../shared/useSaveInStore';\r\nimport { useCreateSubscriptionCallback } from './useCreateSubscriptionCallback';\r\nimport { useUpdateSubscriptionCallback } from './useUpdateSubscriptionCallback';\r\nimport { Subscription } from '../models/Subscription';\r\n\r\n/**\r\n * Get a callback to save a Subscription in the store using either a create or update.\r\n */\r\nexport function useSaveSubscriptionCallback(options: SaveInStoreOptions = {}) {\r\n const [_create, createStatus] = useCreateSubscriptionCallback();\r\n const create = React.useCallback((model: Partial) => _create(model as SubscriptionCreateInput), [_create]);\r\n\r\n const [_update, updateStatus] = useUpdateSubscriptionCallback();\r\n const update = React.useCallback((id: string, changes: Partial) => _update(id, changes as SubscriptionUpdateInput), [_update]);\r\n\r\n return useSaveInStore(\r\n [create, createStatus],\r\n [update, updateStatus],\r\n options\r\n );\r\n}\r\n","import gql from \"graphql-tag\";\r\nimport { blobReferenceFields } from \"../generated/blobReferenceFields\";\r\n\r\nexport const blobReferenceFieldsFragment = gql`\r\n fragment blobReferenceFields on BlobReference {\r\n id\r\n filename\r\n mimeType\r\n storageReference\r\n archived\r\n url\r\n }\r\n`;\r\n\r\n\r\nexport type BlobReference = Omit;\r\n","import { ApiFetch } from 'apifetch-json';\r\nimport { BlobReference } from '../models/BlobReference';\r\n\r\n/**\r\n * Service for handling the uploading of files as blobs.\r\n */\r\nexport class BlobUploadService {\r\n private readonly url: string;\r\n private readonly api: ApiFetch;\r\n\r\n\r\n constructor(url: string, apiFetch?: ApiFetch) {\r\n this.url = url;\r\n this.api = apiFetch || new ApiFetch();\r\n }\r\n\r\n /**\r\n * Upload a single file from a FileList (as provided by input[type=\"file\"])\r\n * @param files\r\n */\r\n async upload(files: FileList): Promise {\r\n let response = await this.uploadMultiple(files);\r\n\r\n if (!response || !response.length) {\r\n return null;\r\n }\r\n\r\n return response[0];\r\n }\r\n\r\n /**\r\n * Upload a single file that is provided as a File rather than a FileList.\r\n * @param file\r\n */\r\n async uploadFile(file: File): Promise {\r\n let response = await this.uploadMultiple([file]);\r\n\r\n if (!response || !response.length) {\r\n return null;\r\n }\r\n\r\n return response[0];\r\n }\r\n\r\n /**\r\n * Upload multiple items.\r\n * @param files\r\n */\r\n async uploadMultiple(files: FileList | Array): Promise> {\r\n var data = new FormData();\r\n for (let i = 0; i < files.length; ++i) {\r\n let file = files[i];\r\n data.append('files', file, file.name);\r\n }\r\n\r\n // We use fetch() rather than post() here as we want full control over headers and body.\r\n let result = await this.api.fetch>(\r\n `${this.url}/upload`,\r\n (init) => {\r\n let { headers, ...rest } = init;\r\n\r\n // Make sure we don't pass 'Content-Type' as that will break the way browsers\r\n // pass file uploads. They require it to be blank so the browser can handle\r\n // it with an appropriate boundry set etc.\r\n let newHeaders = new Headers(headers);\r\n newHeaders.delete('Content-Type');\r\n\r\n return {\r\n ...rest,\r\n method: 'POST',\r\n headers: newHeaders,\r\n body: data\r\n };\r\n });\r\n\r\n return result;\r\n }\r\n\r\n async uploadDataUrl(filename: string, dataUrl: string): Promise {\r\n let result = await this.api.post(`${this.url}/uploadDataUrl?filename=${encodeURIComponent(filename)}`, dataUrl);\r\n return result;\r\n }\r\n\r\n async uploadBlobObject(filename: string, blob: globalThis.Blob): Promise {\r\n var data = new FormData();\r\n data.append('files', blob, filename);\r\n\r\n // We use fetch() rather than post() here as we want full control over headers and body.\r\n let result = await this.api.fetch>(\r\n `${this.url}/upload`,\r\n (init) => {\r\n let { headers, ...rest } = init;\r\n\r\n // Make sure we don't pass 'Content-Type' as that will break the way browsers\r\n // pass file uploads. They require it to be blank so the browser can handle\r\n // it with an appropriate boundry set etc.\r\n let newHeaders = new Headers(headers);\r\n newHeaders.delete('Content-Type');\r\n\r\n return {\r\n ...rest,\r\n method: 'POST',\r\n headers: newHeaders,\r\n body: data\r\n };\r\n });\r\n\r\n return result[0];\r\n }\r\n}\r\n","import { BlobReference } from '../models/BlobReference';\r\nimport { useAsyncCallback } from 'react-use-async-callback';\r\nimport { BlobUploadService } from './BlobUploadService';\r\nimport { mainApiConfig } from '../../../configure/mainApiConfig';\r\nimport { useServices } from 'inject-typesafe-react';\r\nimport { AppServices } from '../../../configure/configureServices';\r\n\r\n/**\r\n * Get a callback to upload blobs in bulk.\r\n */\r\nexport function useBulkUploadBlobsCallback() {\r\n const apiFetch = useServices((services: AppServices) => services.apiFetch());\r\n\r\n return useAsyncCallback(async (files: FileList): Promise> => {\r\n const uploadService = new BlobUploadService(mainApiConfig.blobUploadEndpoint, apiFetch);\r\n const ret = await uploadService.uploadMultiple(files);\r\n return ret ?? [];\r\n }, [apiFetch]);\r\n}\r\n\r\n/**\r\n * Get a callback to upload a blob.\r\n */\r\nexport function useUploadBlobCallback() {\r\n const apiFetch = useServices((services: AppServices) => services.apiFetch());\r\n\r\n return useAsyncCallback(async (files: FileList): Promise => {\r\n const uploadService = new BlobUploadService(mainApiConfig.blobUploadEndpoint, apiFetch);\r\n const ret = await uploadService.upload(files);\r\n return ret;\r\n }, [apiFetch]);\r\n}\r\n","import { Dispatch, SetStateAction, useCallback, useMemo, useState } from \"react\";\r\nimport { useAsyncCallback } from \"react-use-async-callback\";\r\nimport { useUploadBlobCallback } from \"../../../api/main/blobReferences/useUploadBlobCallback\";\r\nimport { BlobReference } from \"../../../api/main/models/BlobReference\";\r\n\r\nexport type BlobReferenceUpdatedCallback = (blobReference: BlobReference | null) => void;\r\nexport type BlobReferenceStateReturnType = [\r\n BlobReference | null,\r\n Dispatch>,\r\n {\r\n upload: (files: FileList | null) => Promise,\r\n isUploading: boolean,\r\n uploadErrors: any,\r\n clearUpload: () => void,\r\n }\r\n];\r\n\r\n/**\r\n * Custom hook to manage a BlobReference in state along with upload options.\r\n */\r\nexport function useBlobReferenceState(onUploaded?: BlobReferenceUpdatedCallback, initialValue?: BlobReference | null)\r\n : BlobReferenceStateReturnType\r\n{\r\n // State we store the blob in.\r\n const [blobReference, setBlobReference] = useState(initialValue ?? null);\r\n\r\n // Uploading of a blob.\r\n const [uploadBlob] = useUploadBlobCallback();\r\n const [upload, { isExecuting: isUploading, errors: uploadErrors }] = useAsyncCallback(async (files: FileList | null) => {\r\n if (!files) {\r\n return null;\r\n }\r\n\r\n // Upload the blob.\r\n const blob = await uploadBlob(files);\r\n if (!blob) {\r\n return null;\r\n }\r\n\r\n // Store the state.\r\n setBlobReference(blob);\r\n\r\n // Call the callback.\r\n if (onUploaded) {\r\n onUploaded(blob);\r\n }\r\n\r\n return blob;\r\n }, [uploadBlob, onUploaded, setBlobReference]);\r\n\r\n // Clearing a blob.\r\n const clearUpload = useCallback(() => {\r\n // Clear the state.\r\n setBlobReference(null);\r\n\r\n // Call the callback.\r\n if (onUploaded) {\r\n onUploaded(null);\r\n }\r\n }, [setBlobReference, onUploaded]);\r\n\r\n // Return everything in a format that is easy for people to grab the bits they want.\r\n const ret = useMemo((): BlobReferenceStateReturnType => ([\r\n blobReference,\r\n setBlobReference,\r\n {\r\n upload,\r\n isUploading,\r\n uploadErrors,\r\n clearUpload,\r\n }\r\n ]), [blobReference, setBlobReference, upload, isUploading, uploadErrors, clearUpload]);\r\n\r\n return ret;\r\n}","import './fileUploadButton.scss';\r\nimport * as React from 'react';\r\nimport { Label, Input } from 'reactstrap';\r\n\r\nexport interface FileUploadButtonProps {\r\n color?: string,\r\n outline?: boolean,\r\n onUpload?: (files: FileList | null) => void,\r\n\r\n isExecuting?: boolean;\r\n executingChildren?: React.ReactNode;\r\n\r\n className?: string,\r\n style?: React.CSSProperties,\r\n children?: React.ReactNode,\r\n}\r\n\r\n/**\r\n * Button for uploading files without showing the file input of the browser.\r\n */\r\nexport const FileUploadButton = (props: FileUploadButtonProps) => {\r\n const {\r\n color = 'primary',\r\n outline = true,\r\n className,\r\n style,\r\n children,\r\n onUpload,\r\n isExecuting,\r\n executingChildren,\r\n } = props;\r\n\r\n return (\r\n \r\n );\r\n};\r\n","import './uploadedImagePreview.scss';\r\n\r\nimport * as React from 'react';\r\nimport { useTranslation } from 'react-i18next';\r\nimport { ConditionalFragment } from 'react-conditionalfragment';\r\nimport { FontAwesomeIcon } from '@fortawesome/react-fontawesome';\r\n\r\nexport interface UploadedImagePreviewProps {\r\n src: string,\r\n alt?: string,\r\n\r\n size?: 'sm' | 'lg',\r\n\r\n className?: string,\r\n style?: React.CSSProperties,\r\n}\r\n\r\n/**\r\n * Preview of an image uploaded by a user, suitable for use on an Edit form for example and made to look similar to other controls that would show in that context.\r\n */\r\nexport const UploadedImagePreview = (props: UploadedImagePreviewProps) => {\r\n const {\r\n src,\r\n alt,\r\n size = 'lg',\r\n className,\r\n style,\r\n } = props;\r\n\r\n const { t } = useTranslation();\r\n\r\n return (\r\n
\r\n \r\n {alt\r\n \r\n \r\n
\r\n
\r\n \r\n
\r\n

\r\n {\r\n t('uploadedImagePreview.notImageText', 'No image has been uploaded yet')\r\n }\r\n

\r\n
\r\n
\r\n
\r\n );\r\n};\r\n","import { useTranslation } from \"react-i18next\";\r\nimport { ButtonGroup, Dropdown, DropdownItem, DropdownMenu, DropdownToggle, FormGroup, Label, Spinner } from \"reactstrap\";\r\nimport { useToggleState } from \"use-toggle-state\";\r\nimport { BlobReference } from \"../../../api/main/models/BlobReference\";\r\nimport { Subscription } from \"../../../api/main/models/Subscription\";\r\nimport { FileUploadButton } from \"../../shared/fileUploadButton/FileUploadButton\";\r\nimport { UploadedImagePreview } from \"../../shared/uploadedImagePreview/UploadedImagePreview\";\r\n\r\nexport interface ImageTabProps {\r\n model: Subscription | undefined,\r\n\r\n imageBlob: BlobReference | undefined | null,\r\n uploadImageBlob: (files: FileList | null) => void,\r\n isUploadingImageBlob: boolean,\r\n clearImageBlob: () => void,\r\n\r\n}\r\n\r\n/**\r\n * Image upload tab for EditQuestion.\r\n * @param props\r\n */\r\nexport const ImageTab = (props: ImageTabProps) => {\r\n const {\r\n //model,\r\n imageBlob, uploadImageBlob, isUploadingImageBlob, clearImageBlob,\r\n } = props;\r\n\r\n const { t } = useTranslation();\r\n\r\n const [isImageDropdownOpen, toggleImageDropdown] = useToggleState();\r\n\r\n return (\r\n <>\r\n \r\n \r\n\r\n \r\n\r\n \r\n uploadImageBlob(files)} isExecuting={isUploadingImageBlob}\r\n executingChildren={<><> {t('common.uploading', 'Uploading...')}}\r\n >\r\n {t('imageTab.uploadImageImage', 'Upload logo...')}\r\n \r\n\r\n toggleImageDropdown()}>\r\n \r\n \r\n {t('common.more', 'More')}\r\n \r\n \r\n \r\n \r\n {t('imageTab.clearImage', 'Clear logo')}\r\n \r\n \r\n \r\n \r\n \r\n \r\n );\r\n};","import { MouseEventHandler, useCallback } from \"react\";\r\nimport { useTranslation } from \"react-i18next\";\r\nimport { NavItem, NavLink } from \"reactstrap\";\r\nimport { NavLinkTrackActive } from \"../shared/NavLinkTrackActive\";\r\nimport { FontAwesomeIcon } from '@fortawesome/react-fontawesome';\r\n\r\nexport interface SubscriptionAdministrationNavigationProps {\r\n id: string,\r\n onNavigate?: (link: string) => void,\r\n editLink?: string,\r\n}\r\n\r\n/**\r\n * Navigation under editing of a Subscription in the administration area.\r\n */\r\nexport const SubscriptionAdministrationNavigation = (props: SubscriptionAdministrationNavigationProps) => {\r\n const { id, onNavigate, editLink } = props;\r\n const { t } = useTranslation();\r\n\r\n // If we have an onNavigate event, we should call that instead of leting the links handle themselves.\r\n const onNavLinkClick = useCallback((e) => {\r\n if (onNavigate) {\r\n e.preventDefault();\r\n const link = e.currentTarget.getAttribute(\"href\") ?? '';\r\n onNavigate(link);\r\n }\r\n }, [onNavigate]);\r\n\r\n return (\r\n <>\r\n \r\n \r\n \r\n {t('subscriptionAdministrationNavigation.subscription', ' Subscription')}\r\n \r\n \r\n \r\n \r\n \r\n {t('subscriptionAdministrationNavigation.assessments', ' Assessments')}\r\n \r\n \r\n \r\n \r\n \r\n {t('subscriptionAdministrationNavigation.training', ' Training modules')}\r\n \r\n \r\n \r\n );\r\n};\r\n","import * as React from 'react';\r\nimport { Row, Col, CustomInput } from 'reactstrap';\r\nimport { Guid } from 'guid-string';\r\n\r\nexport interface TwoValueSwitchProps {\r\n leftLabel: string,\r\n rightLabel: string,\r\n checked: boolean,\r\n onChange?: (checked: boolean) => void,\r\n disabled?: boolean,\r\n}\r\n\r\n/**\r\n * A switch component that lets the user select between two values leftLabel (false), rightLabel (true).\r\n */\r\nexport const TwoValueSwitch = (props: TwoValueSwitchProps) => {\r\n const { checked, onChange, leftLabel, rightLabel, disabled } = props;\r\n const [uniqueName] = React.useState(Guid.newGuid());\r\n\r\n return (\r\n \r\n \r\n {leftLabel}\r\n \r\n \r\n { if (onChange) { onChange(e.currentTarget.checked); } }} disabled={disabled} />\r\n \r\n \r\n {rightLabel}\r\n \r\n \r\n );\r\n};","import { MouseEventHandler, useCallback } from \"react\";\r\nimport { useTranslation } from \"react-i18next\";\r\nimport { NavItem, NavLink } from \"reactstrap\";\r\nimport { NavLinkTrackActive } from \"../../shared/NavLinkTrackActive\";\r\nimport { FontAwesomeIcon } from '@fortawesome/react-fontawesome';\r\n\r\nexport interface SubscriptionAdministrationNavigationProps {\r\n id: string,\r\n onNavigate?: (link: string) => void,\r\n editLink?: string,\r\n}\r\n\r\n/**\r\n * Navigation under editing of a Distributor in the administration area.\r\n */\r\nexport const DistributorEditNavigation = (props: SubscriptionAdministrationNavigationProps) => {\r\n const { id, onNavigate, editLink } = props;\r\n const { t } = useTranslation();\r\n\r\n // If we have an onNavigate event, we should call that instead of leting the links handle themselves.\r\n const onNavLinkClick = useCallback((e) => {\r\n if (onNavigate) {\r\n e.preventDefault();\r\n const link = e.currentTarget.getAttribute(\"href\") ?? '';\r\n onNavigate(link);\r\n }\r\n }, [onNavigate]);\r\n\r\n return (\r\n <>\r\n \r\n \r\n \r\n {t('distributorAdministrationNavigation.distributor', ' Distributor')}\r\n \r\n \r\n \r\n \r\n \r\n {t('distributorAdministrationNavigation.assessments', ' Assessments')}\r\n \r\n \r\n \r\n \r\n \r\n {t('distributorAdministrationNavigation.training', ' Training Modules')}\r\n \r\n \r\n \r\n );\r\n};\r\n//TODO","import { MouseEventHandler, useCallback } from \"react\";\r\nimport { useTranslation } from \"react-i18next\";\r\nimport { NavItem, NavLink } from \"reactstrap\";\r\nimport { NavLinkTrackActive } from \"../../../shared/NavLinkTrackActive\";\r\nimport { FontAwesomeIcon } from '@fortawesome/react-fontawesome';\r\n\r\nexport interface SubscriptionAdministrationNavigationProps {\r\n id: string,\r\n onNavigate?: (link: string) => void,\r\n editLink?: string,\r\n}\r\n\r\n/**\r\n * Navigation under editing of a Distributor in the administration area.\r\n */\r\nexport const DistributorSubscriptionEditNavigation = (props: SubscriptionAdministrationNavigationProps) => {\r\n const { id, onNavigate, editLink } = props;\r\n const { t } = useTranslation();\r\n\r\n // If we have an onNavigate event, we should call that instead of leting the links handle themselves.\r\n const onNavLinkClick = useCallback((e) => {\r\n if (onNavigate) {\r\n e.preventDefault();\r\n const link = e.currentTarget.getAttribute(\"href\") ?? '';\r\n onNavigate(link);\r\n }\r\n }, [onNavigate]);\r\n\r\n return (\r\n <>\r\n \r\n \r\n \r\n {t('distributorSubscriptionEditNavigation.subscription', ' Subscription')}\r\n \r\n \r\n \r\n \r\n \r\n {t('distributorSubscriptionEditNavigation.assessments', ' Assessments')}\r\n \r\n \r\n \r\n \r\n \r\n {t('distributorSubscriptionEditNavigation.training', ' Training Modules')}\r\n \r\n \r\n \r\n );\r\n};","import { FontAwesomeIcon } from \"@fortawesome/react-fontawesome\";\r\nimport { MouseEventHandler, useCallback } from \"react\";\r\nimport { useTranslation } from \"react-i18next\";\r\nimport { NavItem, NavLink } from \"reactstrap\";\r\nimport { NavLinkTrackActive } from \"../../shared/NavLinkTrackActive\";\r\n\r\nexport interface StudyAdministrationNavigationProps {\r\n id: string,\r\n onNavigate?: (link: string) => void,\r\n editLink?: string,\r\n}\r\n\r\n/**\r\n * Navigation under editing of a Study in the administration area.\r\n */\r\nexport const StudyEditNavigation = (props: StudyAdministrationNavigationProps) => {\r\n const { id, onNavigate, editLink } = props;\r\n const { t } = useTranslation();\r\n\r\n // If we have an onNavigate event, we should call that instead of leting the links handle themselves.\r\n const onNavLinkClick = useCallback((e) => {\r\n if (onNavigate) {\r\n e.preventDefault();\r\n const link = e.currentTarget.getAttribute(\"href\") ?? '';\r\n onNavigate(link);\r\n }\r\n }, [onNavigate]);\r\n\r\n // Render the UI\r\n //\r\n return (\r\n <>\r\n \r\n \r\n \r\n {t('studyAdministrationNavigation.study', ' Study')}\r\n \r\n \r\n \r\n \r\n \r\n {t('studyAdministrationNavigation.assessments', ' Assessments')}\r\n \r\n \r\n \r\n );\r\n};","import { Button, Row, Col, Form, Label, FormGroup, Spinner, Collapse, FormText, InputGroup, InputGroupAddon, Input } from 'reactstrap';\r\nimport { AlertOnErrors } from '../../shared/alertOnErrors';\r\nimport { LoadingIndicator } from '../shared/LoadingIndicator';\r\nimport { useTranslation } from 'react-i18next';\r\nimport { FontAwesomeIcon } from '@fortawesome/react-fontawesome';\r\nimport { MainContainer } from '../shared/MainContainer';\r\nimport { useParams, useHistory } from 'react-router';\r\nimport { useChanges } from '../../shared/useChanges';\r\nimport { useSaveSubscriptionCallback } from '../../api/main/subscriptions/useSaveSubscriptionCallback';\r\nimport { useValidatorCallback } from 'pojo-validator-react';\r\nimport { ValidatedInput } from 'pojo-validator-reactstrap';\r\nimport { FormButtons } from '../shared/FormButtons';\r\nimport { ButtonAsync } from 'reactstrap-buttonasync';\r\nimport { useAsyncCallback } from 'react-use-async-callback';\r\nimport { ConditionalFragment } from 'react-conditionalfragment';\r\nimport { Banner } from '../shared/Banner';\r\nimport { Background } from '../shared/background/Background';\r\nimport { useEditSubscriptionViewModel } from '../../api/main/subscriptions/viewModels/useEditSubscriptionViewModel';\r\nimport React, { useEffect, useMemo } from 'react';\r\nimport { useBlobReferenceState } from '../shared/useBlobReferenceState/useBlobReferenceState';\r\nimport { ImageTab } from './image/ImageTab';\r\nimport { Subscription, subscriptionDefaultValues } from '../../api/main/models/Subscription';\r\nimport { PillsNavBar } from '../shared/pillsNavBar/PillsNavBar';\r\nimport { SubscriptionAdministrationNavigation } from './SubscriptionAdministrationNavigation';\r\nimport { TwoValueSwitch } from '../shared/TwoValueSwitch';\r\nimport { defaultRiskRules, OverallRiskCategory, overallRiskService } from '../../services/OverallRiskService';\r\nimport { SubscriptionType } from '../../api/main/models/codeOnly/SubscriptionType';\r\nimport { DistributorEditNavigation } from './Distributors/DistributorEditNavigation';\r\nimport { DistributorSubscriptionEditNavigation } from './Distributors/Administration/DistributorSubscriptionEditNavigation';\r\nimport { useCurrentUserOrEmulatedSubscriptionId } from '../../globalState/subscriptions/useCurrentUserOrEmulatedSubscriptionId';\r\nimport { StudyEditNavigation } from './Studies/StudyEditNavigation';\r\nimport { useGenerateUniqueStudyPinCallback } from '../../api/main/subscriptions/useGenerateUniqueStudyPinCallback';\r\n\r\ninterface EditSubscriptionProps {\r\n isCreate?: boolean,\r\n onCreateDefaultValues?: () => Partial,\r\n subscriptionType: SubscriptionType,\r\n isInDistributor?: boolean,\r\n}\r\n\r\n/**\r\n * Create a new subscription.\r\n * @param props\r\n */\r\nexport const CreateSubscriptionBase = (props: EditSubscriptionProps) => ();\r\n\r\n/**\r\n * Edit a subscription.\r\n */\r\nexport const EditSubscriptionBase = (props: EditSubscriptionProps) => {\r\n const {\r\n isCreate,\r\n onCreateDefaultValues,\r\n subscriptionType,\r\n isInDistributor = false,\r\n } = props;\r\n const { t } = useTranslation();\r\n const { id } = useParams<{ id: string | undefined; }>();\r\n const currentSubscriptionId = useCurrentUserOrEmulatedSubscriptionId();\r\n\r\n const { data: {\r\n model: storeModel,\r\n }, isLoading: _isLoading, errors: loadErrors } = useEditSubscriptionViewModel(id);\r\n const isLoading = _isLoading;\r\n const { model, change, changes } = useChanges(storeModel, isCreate ? { ...subscriptionDefaultValues(), ...(onCreateDefaultValues ? onCreateDefaultValues() : {}) } : undefined);\r\n const [save, { errors: saveErrors }] = useSaveSubscriptionCallback();\r\n const history = useHistory();\r\n\r\n //Allow subscription to work with a passed in subscription type or with the type of the pre existing subscription\r\n const activeSubscriptionType: SubscriptionType = useMemo(() => model?.subscriptionType as SubscriptionType ?? subscriptionType, [model, subscriptionType]);\r\n\r\n const [imageBlob, setImageBlob, { upload: uploadImageBlob, isUploading: isUploadingImageBlob, uploadErrors: uploadImageBlobErrors, clearUpload: clearImageBlob }] = useBlobReferenceState(blob => {\r\n change({ brandImageBlobReferenceId: blob?.id ?? null });\r\n });\r\n useEffect(() => setImageBlob(storeModel?.brandImageBlobReference ?? null), [setImageBlob, storeModel]);\r\n\r\n // Unique PINS as an alternative to traditional username and password logins.\r\n const [generateUniqueStudyPin, { isExecuting: isGeneratingUniqueStudyPin, errors: generateUniqueStudyPinErrors }] = useGenerateUniqueStudyPinCallback();\r\n const [regeneratePin] = useAsyncCallback(async () => {\r\n const newPin = await generateUniqueStudyPin();\r\n change({ studyUniqueCode: newPin });\r\n }, [generateUniqueStudyPin, change]);\r\n\r\n const [validate, validationErrors] = useValidatorCallback((validation, fieldsToCheck) => {\r\n const rules = {\r\n companyName: () => !model?.companyName ? t('editSubscription.companyName.required', 'Subscription name is required') : '',\r\n //brandColor: () => !!model.brandColor && (model?.brandColor.length > 7 || model.brandColor.indexOf('#') === -1) ? t('editSubscription.brandColorFormat', 'Brand color must be in the format #123456 representing your hex brand color code') : '',\r\n };\r\n\r\n validation.checkRules(rules, fieldsToCheck);\r\n }, [model]);\r\n\r\n const [saveForm, { isExecuting: isSaving, errors: saveFormErrors }] = useAsyncCallback(async (options?: { navigateTo?: string, }) => {\r\n if (!validate()) {\r\n return;\r\n }\r\n changes.subscriptionType = activeSubscriptionType;\r\n\r\n if (isInDistributor) {\r\n changes.distributorSubscriptionId = currentSubscriptionId;\r\n }\r\n\r\n await save(model.id, changes, !!isCreate);\r\n\r\n // Navigate to the next screen.\r\n if (options?.navigateTo) {\r\n history.push(options.navigateTo);\r\n } else {\r\n history.goBack();\r\n }\r\n }, [validate, save, model, changes, isCreate, history]);\r\n\r\n // Track if the subscription has had a study access code generated yet or not.\r\n const hasStudyAccessCode = !!model?.studyUniqueCode;\r\n\r\n\r\n // Render the UI.\r\n //\r\n return (\r\n \r\n \r\n \r\n \r\n

\r\n {\r\n activeSubscriptionType === SubscriptionType.Distributor ? (\r\n isCreate ? (\r\n <>{t('editSubscription.createHeading.distributor', 'Add distributor')}\r\n ) : (\r\n <>{t('editSubscription.editHeading.distributor', 'Edit distributor')}\r\n )\r\n ) : (\r\n activeSubscriptionType === SubscriptionType.Study ? (\r\n isCreate ? (\r\n <>{t('editSubscription.createHeading.study', 'Add study')}\r\n ) : (\r\n <>{t('editSubscription.editHeading.study', 'Edit study')}\r\n )\r\n ) : isCreate ? (\r\n <>{t('editSubscription.createHeading.subscription', 'Add subscription')}\r\n ) : (\r\n <>{t('editSubscription.editHeading.subscription', 'Edit subscription')} \r\n )\r\n )\r\n }\r\n

\r\n \r\n \r\n \r\n \r\n \r\n saveForm({ navigateTo: link })}\r\n />\r\n \r\n \r\n \r\n \r\n saveForm({ navigateTo: link })}\r\n />\r\n \r\n \r\n \r\n \r\n \r\n saveForm({ navigateTo: link })}\r\n />\r\n \r\n \r\n \r\n \r\n saveForm({ navigateTo: link })}\r\n />\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n
\r\n
\r\n\r\n \r\n \r\n\r\n
{ e.preventDefault(); saveForm(); }}>\r\n \r\n \r\n change({ companyName: e.currentTarget.value })}\r\n onBlur={e => validate('companyName')}\r\n validationErrors={validationErrors['companyName']} />\r\n \r\n\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n regeneratePin()}\r\n isExecuting={isGeneratingUniqueStudyPin}\r\n executingChildren={<>{t('common.generatingCode', 'Generating unique code...')}}>\r\n \r\n <> \r\n {\r\n hasStudyAccessCode ? t('editSubscription.regenerateCode', 'Reset code')\r\n : t('editSubscription.regenerateCode', 'Generate code')\r\n }\r\n \r\n \r\n \r\n \r\n {t('editSubscription.studyUniqueCode.hint.text', 'Each study needs its own unqiue study access code.')}\r\n \r\n <> \r\n \r\n {t('editSubscription.studyUniqueCode.hint.danger', 'If you reset the study access code any existing links using the previous code will no longer work.')}\r\n \r\n \r\n \r\n \r\n\r\n \r\n \r\n \r\n \r\n {t('editSubscription.sharableUrl.label', 'This is the link you need to either provide directly to your study participants or connect to your study management software such as Prolific. When this link is visited the participant will be taken to the assessment to start the study. For the best experience using study management software, pass the participant identifier as a URL parameter or query string using ?user=[id], e.g. ?user=12345. This will have to be configured in your study management software but will help you link the completed assessments to the study managements profiling data captured about the participant.')}\r\n \r\n \r\n\r\n \r\n \r\n change({ studyReturnUrl: e.currentTarget.value })} />\r\n \r\n {t('editSubscription.studyReturnUrl.label', 'This is the link the user will be redirected to after they complete their assessment and click close. If you are using study management software such as Prolific, you should be given this URL when setting up the study. If you do not supply a link here, we will redirect the user to our own built in thank you page.')}\r\n \r\n \r\n \r\n\r\n \r\n \r\n \r\n \r\n \r\n \r\n {overallRiskService.getRiskName(OverallRiskCategory.High)}\r\n \r\n <> \r\n \r\n {t('editSubscription.lessThanSign', '<')}\r\n \r\n \r\n \r\n change({ highRiskBelow: e.currentTarget.valueAsNumber })}\r\n onBlur={e => validate('highRiskBelow')}\r\n validationErrors={validationErrors['highRiskBelow']}\r\n />\r\n \r\n \r\n \r\n {t('editSubscription.lessThanOrEqualsSign', '<=')}\r\n \r\n <> \r\n \r\n {overallRiskService.getRiskName(OverallRiskCategory.Medium)}\r\n \r\n <> \r\n \r\n {t('editSubscription.lessThanSign', '<')}\r\n \r\n \r\n \r\n change({ mediumRiskBelow: e.currentTarget.valueAsNumber })}\r\n onBlur={e => validate('mediumRiskBelow')}\r\n validationErrors={validationErrors['mediumRiskBelow']}\r\n />\r\n\r\n \r\n \r\n \r\n {t('editSubscription.lessThanOrEqualsSign', '<=')}\r\n \r\n <> \r\n {overallRiskService.getRiskName(OverallRiskCategory.Low)}\r\n \r\n \r\n \r\n \r\n {t('editSubscription.riskRules.formText', 'Default rules for new subscriptions and the Esitu Drive dashboard are: High risk < {{highRiskBelow}} <= Medium risk < {{mediumRiskBelow}} <= Low risk.', defaultRiskRules)}\r\n \r\n \r\n \r\n\r\n \r\n \r\n \r\n change({ restrictMaxUsers: checked })}\r\n />\r\n \r\n \r\n \r\n \r\n change({ maxUsers: parseInt(e.currentTarget.value) })}\r\n onBlur={e => validate('maxUsers')}\r\n validationErrors={validationErrors['maxUsers']} />\r\n \r\n {t('editSubscription.maxUsers.help', 'Setting to 0 gives the subscription unlimited users')}\r\n \r\n \r\n \r\n \r\n\r\n \r\n \r\n \r\n change({ allowBranding: checked })}\r\n />\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n change({ brandColor: e.currentTarget.value })}\r\n onBlur={e => validate('brandColor')}\r\n validationErrors={validationErrors['brandColor']} />\r\n \r\n \r\n \r\n \r\n \r\n {t('editSubscription.brandColor.formText', 'This will change the primary colour of buttons shown. Other colours used by the app will maintain Esitu colours and branding.')}\r\n \r\n \r\n \r\n \r\n \r\n \r\n\r\n \r\n \r\n change({ allowExport: checked })}\r\n />\r\n \r\n\r\n \r\n \r\n {t('common.saving', 'Saving...')}}>\r\n \r\n <> {t('common.save', 'Save')}\r\n \r\n \r\n \r\n \r\n
\r\n
\r\n
\r\n );\r\n};\r\n","import * as React from 'react';\r\nimport { useLazyQuery } from \"@apollo/react-hooks\";\r\nimport gql from \"graphql-tag\";\r\nimport { AsyncLoadResult, AsyncLoadOptions } from '../../../../shared/abstractStore';\r\nimport { editSubscriptionViewModelQuery, editSubscriptionViewModelQueryVariables } from '../../generated/editSubscriptionViewModelQuery';\r\nimport { mainApiConfig } from '../../../../configure/mainApiConfig';\r\nimport { blobReferenceFieldsFragment } from '../../models/BlobReference';\r\nimport { Guid } from 'guid-string';\r\nimport { subscriptionFieldsFragment } from '../../models/Subscription';\r\n\r\n/**\r\n * View model for EditSubscription that replaces the call to useSubscription() and loads the right related data.\r\n * @param options\r\n */\r\nexport function useEditSubscriptionViewModel(id: string | undefined | null, options: AsyncLoadOptions = {}): AsyncLoadResult {\r\n // Query the data we need form the api.\r\n const [load, { data, loading, error, refetch }] = useLazyQuery(\r\n gql`\r\n query editSubscriptionViewModelQuery ($id: ID!) {\r\n model: subscription(id: $id) {\r\n ...subscriptionFields\r\n\r\n brandImageBlobReference {\r\n ...blobReferenceFields\r\n }\r\n }\r\n }\r\n\r\n ${subscriptionFieldsFragment}\r\n ${blobReferenceFieldsFragment}\r\n\r\n `,\r\n {\r\n variables: {\r\n id: id ?? Guid.empty\r\n },\r\n fetchPolicy: options.fetchPolicy ?? mainApiConfig.defaultFetchPolicy,\r\n pollInterval: options.pollInterval,\r\n onCompleted: (data) => {\r\n if (options.onCompleted) {\r\n options.onCompleted(data);\r\n }\r\n }\r\n }\r\n );\r\n\r\n // Run the query (unless we are being lazy).\r\n React.useEffect(() => {\r\n if (!options.lazy) {\r\n load();\r\n }\r\n }, [options.lazy, load])\r\n\r\n // Return the results.\r\n const refresh = React.useCallback(async () => { !refetch ? await load() : await refetch(); }, [refetch, load]);\r\n return React.useMemo(() => ({\r\n data: data ?? ({} as any),\r\n refresh: refresh,\r\n isLoading: loading,\r\n errors: error\r\n }), [data, refresh, loading, error]);\r\n}\r\n","import { useMutation } from \"@apollo/react-hooks\";\r\nimport { useAsyncCallback } from 'react-use-async-callback';\r\nimport gql from \"graphql-tag\";\r\nimport { AsyncActionStatus } from '../../../shared/abstractStore';\r\nimport { generateUniqueStudyPinMutation } from '../generated/generateUniqueStudyPinMutation';\r\n//import { generateUniqueStudyPinMutation } from '../generated/generateUniqueStudyPinMutation';\r\n\r\n/**\r\n * Get a callback to generate a unique driver pin that can be used to log in a user.\r\n */\r\nexport function useGenerateUniqueStudyPinCallback(): [() => Promise, AsyncActionStatus] {\r\n const [mutationAction, { error }] = useMutation(\r\n gql`\r\n mutation generateUniqueStudyPinMutation {\r\n generateUniqueStudyPin\r\n }\r\n `\r\n );\r\n\r\n // Wrap the mutation in a standard callback.\r\n const [action, { isExecuting, errors: actionErrors }] = useAsyncCallback(async () => {\r\n const result = await mutationAction({});\r\n if (result.errors && result.errors.length) {\r\n throw result.errors;\r\n }\r\n return result.data?.generateUniqueStudyPin ?? '';\r\n }, [mutationAction]);\r\n\r\n return [action, { isExecuting: isExecuting, errors: error ? error.message : actionErrors }];\r\n}\r\n","import gql from \"graphql-tag\";\r\nimport { Guid } from \"guid-string\";\r\nimport { subscriptionTeamFields } from \"../generated/subscriptionTeamFields\";\r\n\r\nexport const subscriptionTeamFieldsFragment = gql`\r\n fragment subscriptionTeamFields on SubscriptionTeam {\r\n id\r\n subscriptionId\r\n name\r\n archived\r\n }\r\n`;\r\n\r\n\r\nexport type SubscriptionTeam = Omit;\r\n\r\nexport const subscriptionTeamDefaultValues = (): Partial => ({\r\n id: Guid.newGuid(),\r\n name: '',\r\n subscriptionId: undefined,\r\n archived: false,\r\n});","import * as React from 'react';\r\nimport { useLazyQuery } from \"@apollo/react-hooks\";\r\nimport gql from \"graphql-tag\";\r\nimport { AsyncLoadPagedResult, AsyncLoadPagedOptions } from '../../../../shared/abstractStore';\r\nimport { useFetchMoreCallback } from '../../../../shared/useFetchMoreCallback';\r\nimport { usersListViewBaseViewModelQuery, usersListViewBaseViewModelQueryVariables } from '../../generated/usersListViewBaseViewModelQuery';\r\nimport { mainApiConfig } from '../../../../configure/mainApiConfig';\r\nimport { profileFieldsFragment } from '../../models/Profile';\r\nimport { subscriptionFieldsFragment } from '../../models/Subscription';\r\nimport { subscriptionTeamFieldsFragment } from '../../models/SubscriptionTeam';\r\nimport { Guid } from 'guid-string';\r\n\r\nexport interface UsersListViewBaseViewModelAsyncLoadPagedOptions extends AsyncLoadPagedOptions {\r\n subscriptionId?: string | undefined | null,\r\n subscriptionTeamId?: string | undefined | null,\r\n}\r\n\r\n/**\r\n * Get a list of profiles from the store.\r\n * @param id\r\n * @param options\r\n */\r\nexport function useUsersListViewBaseViewModel(options: UsersListViewBaseViewModelAsyncLoadPagedOptions = {}): AsyncLoadPagedResult {\r\n // Query data we need from the api.\r\n const [load, { data, loading, error, refetch, fetchMore: fetchMoreFromStore }] = useLazyQuery(\r\n gql`\r\n query usersListViewBaseViewModelQuery ($offset: Int, $first: Int, $subscriptionId: ID, $subscriptionTeamId: ID, $subscriptionIdOrEmptyGuid: ID!, $subscriptionTeamIdOrEmptyGuid: ID!) {\r\n items: profiles (offset: $offset, first: $first, subscriptionId: $subscriptionId, subscriptionTeamId: $subscriptionTeamId) {\r\n ...profileFields\r\n }\r\n\r\n subscription (id: $subscriptionIdOrEmptyGuid) {\r\n ...subscriptionFields\r\n }\r\n subscriptionTeam (id: $subscriptionTeamIdOrEmptyGuid){\r\n ...subscriptionTeamFields\r\n }\r\n subscriptionTeams (subscriptionId: $subscriptionIdOrEmptyGuid){\r\n ...subscriptionTeamFields\r\n }\r\n }\r\n\r\n ${profileFieldsFragment}\r\n ${subscriptionFieldsFragment}\r\n ${subscriptionTeamFieldsFragment}\r\n `,\r\n {\r\n\r\n variables: {\r\n offset: options.startOffset,\r\n first: options.pageSize,\r\n subscriptionId: options.subscriptionId,\r\n subscriptionTeamId: options.subscriptionTeamId,\r\n subscriptionIdOrEmptyGuid: options.subscriptionId ?? Guid.empty,\r\n subscriptionTeamIdOrEmptyGuid: options.subscriptionTeamId ?? Guid.empty,\r\n },\r\n fetchPolicy: options.fetchPolicy ?? mainApiConfig.defaultFetchPolicy,\r\n pollInterval: options.pollInterval,\r\n onCompleted: (data) => {\r\n if (options.onCompleted) {\r\n options.onCompleted(data);\r\n }\r\n }\r\n }\r\n );\r\n\r\n // Run the query (unless we are being lazy).\r\n React.useEffect(() => {\r\n if (!options.lazy) {\r\n load();\r\n }\r\n }, [options.lazy, load])\r\n\r\n // Get the functions used to manage paging.\r\n const { fetchMore, hasMore: _hasMore } = useFetchMoreCallback(\r\n fetchMoreFromStore,\r\n (options?.startOffset ?? 0) + (data?.items?.length ?? 0),\r\n (prevResults, newResults) => ({\r\n ...prevResults,\r\n ...newResults,\r\n\r\n items: [...(prevResults?.items ?? []), ...(newResults?.items ?? [])],\r\n subscription: newResults?.subscription ?? null,\r\n subscriptionTeam: newResults?.subscriptionTeam ?? null,\r\n subscriptionTeams: newResults?.subscriptionTeams ?? [],\r\n }),\r\n (newResults) => newResults?.items?.length\r\n );\r\n const hasMore = React.useCallback(() => !options.pageSize ? false : _hasMore(), [options.pageSize, _hasMore]);\r\n \r\n // Return the results.\r\n const refresh = React.useCallback(async () => { !refetch ? await load() : await refetch(); }, [refetch, load]);\r\n return React.useMemo(() => ({\r\n data: data ?? ({} as any),\r\n refresh: refresh,\r\n isLoading: loading,\r\n errors: error,\r\n fetchMore: fetchMore,\r\n hasMore: hasMore,\r\n }), [data, refresh, loading, error, fetchMore, hasMore]);\r\n}\r\n","import { useMutation } from \"@apollo/react-hooks\";\r\nimport { useAsyncCallback } from 'react-use-async-callback';\r\nimport gql from \"graphql-tag\";\r\nimport { AsyncActionStatus } from '../../../shared/abstractStore';\r\nimport { deleteSubscriptionTeamMutation, deleteSubscriptionTeamMutationVariables } from '../generated/deleteSubscriptionTeamMutation';\r\nimport { subscriptionTeamFieldsFragment } from '../models/SubscriptionTeam';\r\n\r\n/**\r\n * Get a callback to delete a SubscriptionTeam in the store.\r\n */\r\nexport function useDeleteSubscriptionTeamCallback(): [(id: string) => Promise, AsyncActionStatus] {\r\n const [mutationAction, { error }] = useMutation(\r\n gql`\r\n mutation deleteSubscriptionTeamMutation ($id: ID!) {\r\n deleteSubscriptionTeam(id: $id) {\r\n ...subscriptionTeamFields\r\n }\r\n }\r\n\r\n ${subscriptionTeamFieldsFragment}\r\n `\r\n );\r\n\r\n // Wrap the mutation in a standard callback.\r\n const [action, { isExecuting, errors: actionErrors }] = useAsyncCallback(async (id: string) => {\r\n const result = await mutationAction({ variables: { id: id } });\r\n if (result.errors && result.errors.length) {\r\n throw result.errors;\r\n }\r\n }, [mutationAction]);\r\n\r\n return [action, { isExecuting: isExecuting, errors: error ? error.message : actionErrors }];\r\n}\r\n","import { useMutation } from \"@apollo/react-hooks\";\r\nimport { useAsyncCallback } from 'react-use-async-callback';\r\nimport gql from \"graphql-tag\";\r\nimport { AsyncActionStatus } from '../../../shared/abstractStore';\r\nimport { deleteProfileMutation, deleteProfileMutationVariables } from '../generated/deleteProfileMutation';\r\nimport { profileFieldsFragment } from '../models/Profile';\r\n\r\n/**\r\n * Get a callback to delete a Profile in the store.\r\n */\r\nexport function useDeleteProfileCallback(): [(id: string) => Promise, AsyncActionStatus] {\r\n const [mutationAction, { error }] = useMutation(\r\n gql`\r\n mutation deleteProfileMutation ($id: ID!) {\r\n deleteProfile(id: $id) {\r\n ...profileFields\r\n }\r\n }\r\n\r\n ${profileFieldsFragment}\r\n `\r\n );\r\n\r\n // Wrap the mutation in a standard callback.\r\n const [action, { isExecuting, errors: actionErrors }] = useAsyncCallback(async (id: string) => {\r\n const result = await mutationAction({ variables: { id: id } });\r\n if (result.errors && result.errors.length) {\r\n throw result.errors;\r\n }\r\n }, [mutationAction]);\r\n\r\n return [action, { isExecuting: isExecuting, errors: error ? error.message : actionErrors }];\r\n}\r\n","import { Button, Form, Label, FormGroup, Spinner, Input, Row, Col } from 'reactstrap';\r\nimport { AlertOnErrors } from '../../shared/alertOnErrors';\r\nimport { LoadingIndicator } from '../shared/LoadingIndicator';\r\nimport { useTranslation } from 'react-i18next';\r\nimport { FontAwesomeIcon } from '@fortawesome/react-fontawesome';\r\nimport { MainContainer } from '../shared/MainContainer';\r\nimport { useParams, useHistory } from 'react-router';\r\nimport { FormButtons } from '../shared/FormButtons';\r\nimport { ButtonAsync } from 'reactstrap-buttonasync';\r\nimport { useAsyncCallback } from 'react-use-async-callback';\r\nimport { useUsersListViewBaseViewModel } from '../../api/main/profiles/viewModels/useUsersListViewBaseViewModel';\r\nimport { useDeleteSubscriptionCallback } from '../../api/main/subscriptions/useDeleteSubscriptionCallback';\r\nimport { ConditionalFragment } from 'react-conditionalfragment';\r\nimport { Banner } from '../shared/Banner';\r\nimport { Background } from '../shared/background/Background';\r\nimport { useLockoutCallback } from '../../api/account';\r\nimport { useDeleteSubscriptionTeamCallback } from '../../api/main/subscriptionTeams/useDeleteSubscriptionTeamCallback';\r\nimport { useDeleteProfileCallback } from '../../api/main/profiles/useDeleteProfileCallback';\r\n\r\n/**\r\n * Delete a subscription.\r\n */\r\nexport const DeleteSubscription = () => {\r\n const { t } = useTranslation();\r\n const { id } = useParams<{ id: string }>();\r\n const { data: { subscription: model, items, subscriptionTeams }, isLoading, errors: loadErrors } = useUsersListViewBaseViewModel({ subscriptionId: id });\r\n const [remove, { errors: removeErrors }] = useDeleteSubscriptionCallback();\r\n const [removeProfile, { errors: removeProfileErrors }] = useDeleteProfileCallback();\r\n const [removeTeam, { errors: removeTeamErrors }] = useDeleteSubscriptionTeamCallback();\r\n const [lockout, { errors: lockoutErrors }] = useLockoutCallback();\r\n const history = useHistory();\r\n\r\n const [onRemoveFormSubmit, { isExecuting: isRemoving, errors: removeFormErrors }] = useAsyncCallback(async () => {\r\n if (!model) {\r\n return;\r\n }\r\n\r\n items.forEach(item => lockout({ email: item.user.email, archive: true }));\r\n items.forEach(item => removeProfile(item.id));\r\n subscriptionTeams.forEach(item => removeTeam(item.id));\r\n\r\n await remove(model.id);\r\n\r\n history.goBack();\r\n }, [model, history]);\r\n\r\n return (\r\n \r\n \r\n \r\n \r\n

{t('deleteSubscription.heading', 'Are you sure you want to delete this subscription?')}

\r\n \r\n \r\n \r\n \r\n \r\n \r\n
\r\n
\r\n\r\n \r\n \r\n\r\n
{ e.preventDefault(); onRemoveFormSubmit(); }}>\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n {t('common.deleting', 'Deleting...')}}>\r\n \r\n <> {t('common.delete', 'Delete')}\r\n \r\n \r\n \r\n \r\n
\r\n
\r\n
\r\n );\r\n};\r\n","import { TFunction } from \"i18next\";\r\n\r\n/**\r\n * Assessment types\r\n */\r\nexport enum AssessmentType {\r\n Assessment = \"Assessment\",\r\n TrainingModule = \"TrainingModule\",\r\n}\r\n\r\n/**\r\n * Return translated display name for a feedback style.\r\n * @param t\r\n */\r\nexport function assessmentTypeDisplayName(type: AssessmentType, t: TFunction): string {\r\n switch (type) {\r\n case AssessmentType.Assessment: return t('assessmentTypeDisplayName.Assessment', 'Assessment');\r\n case AssessmentType.TrainingModule: return t('assessmentTypeDisplayName.TrainingModule', 'Training module');\r\n }\r\n}\r\n","import { RouteEntry } from \"../../shared/routes\";\r\nimport { SubscriptionsList } from './Subscriptions/SubscriptionsList';\r\nimport { IdentityRoles } from \"../../configure/security/IdentityRoles\";\r\nimport { EditSubscription, CreateSubscription } from \"./Subscriptions/EditSubscription\";\r\nimport { DeleteSubscription } from \"./DeleteSubscription\";\r\n\r\nexport const subscriptionRoutes: Array = [\r\n { path: '/administration/subscriptions', exact: true, component: SubscriptionsList, authorize: true, requireRole: IdentityRoles.Administration },\r\n { path: '/administration/subscriptions/edit/:id', component: EditSubscription, authorize: true, requireRole: IdentityRoles.Administration },\r\n { path: '/administration/subscriptions/add', component: CreateSubscription, authorize: true, requireRole: IdentityRoles.Administration },\r\n { path: '/administration/subscriptions/delete/:id', component: DeleteSubscription, authorize: true, requireRole: IdentityRoles.Administration },\r\n];\r\n","import { SubscriptionType } from \"../../../api/main/models/codeOnly/SubscriptionType\";\r\nimport { SubscriptionsListBase } from \"../SubscriptionsListBase\";\r\nimport { useTranslation } from \"react-i18next\";\r\n\r\n/**\r\n * List of actual subscriptions.\r\n */\r\nexport const SubscriptionsList = () => {\r\n const { t } = useTranslation();\r\n\r\n return (\r\n \r\n );\r\n};","import { SubscriptionType } from \"../../../api/main/models/codeOnly/SubscriptionType\";\r\nimport { CreateSubscriptionBase, EditSubscriptionBase } from \"../EditSubscriptionBase\";\r\n\r\n/**\r\n * Create an actual Subscription.\r\n */\r\nexport const CreateSubscription = () => (\r\n ({ subscriptionType: SubscriptionType.Subscription })}\r\n />);\r\n\r\n/**\r\n * Edit an actual Subscription.\r\n */\r\nexport const EditSubscription = () => ();","import { useMutation } from \"@apollo/react-hooks\";\r\nimport { useAsyncCallback } from 'react-use-async-callback';\r\nimport gql from \"graphql-tag\";\r\nimport { AsyncActionStatus } from '../../../shared/abstractStore';\r\nimport { deleteSubscriptionMutation, deleteSubscriptionMutationVariables } from '../generated/deleteSubscriptionMutation';\r\nimport { subscriptionFieldsFragment } from '../models/Subscription';\r\n\r\n/**\r\n * Get a callback to delete a Subscription in the store.\r\n */\r\nexport function useDeleteSubscriptionCallback(): [(id: string) => Promise, AsyncActionStatus] {\r\n const [mutationAction, { error }] = useMutation(\r\n gql`\r\n mutation deleteSubscriptionMutation ($id: ID!) {\r\n deleteSubscription(id: $id) {\r\n ...subscriptionFields\r\n }\r\n }\r\n\r\n ${subscriptionFieldsFragment}\r\n `\r\n );\r\n\r\n // Wrap the mutation in a standard callback.\r\n const [action, { isExecuting, errors: actionErrors }] = useAsyncCallback(async (id: string) => {\r\n const result = await mutationAction({ variables: { id: id } });\r\n if (result.errors && result.errors.length) {\r\n throw result.errors;\r\n }\r\n }, [mutationAction]);\r\n\r\n return [action, { isExecuting: isExecuting, errors: error ? error.message : actionErrors }];\r\n}\r\n","import { TFunction } from \"i18next\";\r\n\r\n/**\r\n * Feedback styles\r\n */\r\nexport enum FeedbackStyle {\r\n NoScore = \"NoScore\",\r\n NoFeedback = \"NoFeedback\",\r\n SummaryFeedback = \"SummaryFeedback\",\r\n EachQuestionFeedback = \"EachQuestionFeedback\",\r\n}\r\n\r\n/**\r\n * Return translated display name for a feedback style.\r\n * @param t\r\n */\r\nexport function feedbackStyleDisplayName(type: FeedbackStyle, t: TFunction): string {\r\n switch (type) {\r\n case FeedbackStyle.NoScore: return t('feedbackStyleDisplayName.NoScore', 'On the Finish page the user will be shown the overall feedback text but given no score.');\r\n case FeedbackStyle.NoFeedback: return t('feedbackStyleDisplayName.NoFeedback', 'On the Finish page the user will be shown the overall feedback text and their total score, but cannot break that score down by question.');\r\n case FeedbackStyle.SummaryFeedback: return t('feedbackStyleDisplayName.SummaryFeedback', 'On the Finish page the user will be shown the overall feedback text, their total score, and have the ability to view their score for each question.');\r\n case FeedbackStyle.EachQuestionFeedback: return t('feedbackStyleDisplayName.EachQuestionFeedback', 'Feedback will be given to the user after each question. On the Finish page the user will be shown the overall feedback text, their total score, and have the ability to review their score for each question again.');\r\n }\r\n}\r\n","import gql from \"graphql-tag\";\r\nimport { Guid } from \"guid-string\";\r\nimport moment from \"moment\";\r\nimport { assessmentFields } from \"../generated/assessmentFields\";\r\nimport { AssessmentType } from \"./codeOnly/AssessmentType\";\r\nimport { FeedbackStyle } from \"./codeOnly/FeedbackStyle\";\r\n\r\nexport const assessmentFieldsFragment = gql`\r\n fragment assessmentFields on Assessment {\r\n id\r\n name\r\n assessmentType\r\n isSmartIndividuality\r\n feedbackStyle\r\n archived\r\n text\r\n imageBlobReferenceId\r\n tileText\r\n creationDate\r\n maxSuspiciousAnswers\r\n suspiciousAnswerText\r\n highRiskBelow\r\n mediumRiskBelow\r\n }\r\n`;\r\n\r\n\r\nexport type Assessment = Omit;\r\n\r\nexport const assessmentDefaultValues = (): Partial => ({\r\n id: Guid.newGuid(),\r\n name: '',\r\n assessmentType: AssessmentType.Assessment,\r\n isSmartIndividuality: false,\r\n feedbackStyle: FeedbackStyle.NoFeedback,\r\n archived: false,\r\n text: '',\r\n imageBlobReferenceId: null,\r\n tileText: '',\r\n creationDate: moment().toISOString(),\r\n maxSuspiciousAnswers: 0,\r\n suspiciousAnswerText: '',\r\n highRiskBelow: 30,\r\n mediumRiskBelow: 70,\r\n});","import { useMutation } from \"@apollo/react-hooks\";\r\nimport { useAsyncCallback } from 'react-use-async-callback';\r\nimport gql from \"graphql-tag\";\r\nimport { AsyncActionStatus } from '../../../shared/abstractStore';\r\nimport { AssessmentCreateInput } from '../generated/globalTypes';\r\nimport { createAssessmentMutation, createAssessmentMutationVariables } from '../generated/createAssessmentMutation';\r\nimport { assessmentFieldsFragment } from '../models/Assessment';\r\n\r\n/**\r\n * Get a callback to create a Assessment in the store.\r\n */\r\nexport function useCreateAssessmentCallback(): [(model: AssessmentCreateInput) => Promise, AsyncActionStatus] {\r\n const [mutationAction, { error }] = useMutation(\r\n gql`\r\n mutation createAssessmentMutation ($model: AssessmentCreateInput!) {\r\n createAssessment(model: $model) {\r\n ...assessmentFields\r\n }\r\n }\r\n\r\n ${assessmentFieldsFragment}\r\n `\r\n );\r\n\r\n // Wrap the mutation in a standard callback.\r\n const [action, { isExecuting, errors: actionErrors }] = useAsyncCallback(async (model: AssessmentCreateInput) => {\r\n const result = await mutationAction({ variables: { model: model } });\r\n if (result.errors && result.errors.length) {\r\n throw result.errors;\r\n }\r\n }, [mutationAction]);\r\n\r\n return [action, { isExecuting: isExecuting, errors: error ? error.message : actionErrors }];\r\n}\r\n","import { useMutation } from \"@apollo/react-hooks\";\r\nimport { useAsyncCallback } from 'react-use-async-callback';\r\nimport gql from \"graphql-tag\";\r\nimport { AsyncActionStatus } from '../../../shared/abstractStore';\r\nimport { AssessmentUpdateInput } from '../generated/globalTypes';\r\nimport { updateAssessmentMutation, updateAssessmentMutationVariables } from '../generated/updateAssessmentMutation';\r\nimport { assessmentFieldsFragment } from '../models/Assessment';\r\n\r\n/**\r\n * Get a callback to update a Assessment in the store.\r\n */\r\nexport function useUpdateAssessmentCallback(): [(id: string, model: AssessmentUpdateInput) => Promise, AsyncActionStatus] {\r\n const [mutationAction, { error }] = useMutation(\r\n gql`\r\n mutation updateAssessmentMutation ($model: AssessmentUpdateInput!) {\r\n updateAssessment(model: $model) {\r\n ...assessmentFields\r\n }\r\n }\r\n\r\n ${assessmentFieldsFragment}\r\n `\r\n );\r\n\r\n // Wrap the mutation in a standard callback.\r\n const [action, { isExecuting, errors: actionErrors }] = useAsyncCallback(async (id: string, model: AssessmentUpdateInput) => {\r\n const result = await mutationAction({ variables: { model: { ...model, id: id } } });\r\n if (result.errors && result.errors.length) {\r\n throw result.errors;\r\n }\r\n }, [mutationAction]);\r\n\r\n return [action, { isExecuting: isExecuting, errors: error ? error.message : actionErrors }];\r\n}\r\n","import gql from \"graphql-tag\";\r\nimport { Guid } from \"guid-string\";\r\nimport { assessmentFeedbackFields } from \"../generated/assessmentFeedbackFields\";\r\n\r\nexport const assessmentFeedbackFieldsFragment = gql`\r\n fragment assessmentFeedbackFields on AssessmentFeedback {\r\n id\r\n assessmentId\r\n minTotalScore\r\n maxTotalScore\r\n archived\r\n feedbackText\r\n imageBlobReferenceId\r\n videoBlobReferenceId\r\n }\r\n`;\r\n\r\n\r\nexport type AssessmentFeedback = Omit;\r\n\r\n// Default values.\r\nexport const assessmentFeedbackDefaultValues = (): Partial => ({\r\n id: Guid.newGuid(),\r\n assessmentId: undefined,\r\n minTotalScore: 0,\r\n maxTotalScore: 100,\r\n feedbackText: '',\r\n videoBlobReferenceId: null,\r\n imageBlobReferenceId: null,\r\n});","import { useMutation } from \"@apollo/react-hooks\";\r\nimport { useAsyncCallback } from 'react-use-async-callback';\r\nimport gql from \"graphql-tag\";\r\nimport { AsyncActionStatus } from '../../../shared/abstractStore';\r\nimport { AssessmentFeedbackCreateInput } from '../generated/globalTypes';\r\nimport { createAssessmentFeedbackMutation, createAssessmentFeedbackMutationVariables } from '../generated/createAssessmentFeedbackMutation';\r\nimport { assessmentFeedbackFieldsFragment } from '../models/AssessmentFeedback';\r\n\r\n/**\r\n * Get a callback to create a AssessmentFeedback in the store.\r\n */\r\nexport function useCreateAssessmentFeedbackCallback(): [(model: AssessmentFeedbackCreateInput) => Promise, AsyncActionStatus] {\r\n const [mutationAction, { error }] = useMutation(\r\n gql`\r\n mutation createAssessmentFeedbackMutation ($model: AssessmentFeedbackCreateInput!) {\r\n createAssessmentFeedback(model: $model) {\r\n ...assessmentFeedbackFields\r\n }\r\n }\r\n\r\n ${assessmentFeedbackFieldsFragment}\r\n `\r\n );\r\n\r\n // Wrap the mutation in a standard callback.\r\n const [action, { isExecuting, errors: actionErrors }] = useAsyncCallback(async (model: AssessmentFeedbackCreateInput) => {\r\n const result = await mutationAction({ variables: { model: model } });\r\n if (result.errors && result.errors.length) {\r\n throw result.errors;\r\n }\r\n }, [mutationAction]);\r\n\r\n return [action, { isExecuting: isExecuting, errors: error ? error.message : actionErrors }];\r\n}\r\n","import { useMutation } from \"@apollo/react-hooks\";\r\nimport { useAsyncCallback } from 'react-use-async-callback';\r\nimport gql from \"graphql-tag\";\r\nimport { AsyncActionStatus } from '../../../shared/abstractStore';\r\nimport { AssessmentFeedbackUpdateInput } from '../generated/globalTypes';\r\nimport { updateAssessmentFeedbackMutation, updateAssessmentFeedbackMutationVariables } from '../generated/updateAssessmentFeedbackMutation';\r\nimport { assessmentFeedbackFieldsFragment } from '../models/AssessmentFeedback';\r\n\r\n/**\r\n * Get a callback to update a AssessmentFeedback in the store.\r\n */\r\nexport function useUpdateAssessmentFeedbackCallback(): [(id: string, model: AssessmentFeedbackUpdateInput) => Promise, AsyncActionStatus] {\r\n const [mutationAction, { error }] = useMutation(\r\n gql`\r\n mutation updateAssessmentFeedbackMutation ($model: AssessmentFeedbackUpdateInput!) {\r\n updateAssessmentFeedback(model: $model) {\r\n ...assessmentFeedbackFields\r\n }\r\n }\r\n\r\n ${assessmentFeedbackFieldsFragment}\r\n `\r\n );\r\n\r\n // Wrap the mutation in a standard callback.\r\n const [action, { isExecuting, errors: actionErrors }] = useAsyncCallback(async (id: string, model: AssessmentFeedbackUpdateInput) => {\r\n const result = await mutationAction({ variables: { model: { ...model, id: id } } });\r\n if (result.errors && result.errors.length) {\r\n throw result.errors;\r\n }\r\n }, [mutationAction]);\r\n\r\n return [action, { isExecuting: isExecuting, errors: error ? error.message : actionErrors }];\r\n}\r\n","import gql from \"graphql-tag\";\r\nimport { Guid } from \"guid-string\";\r\nimport { questionFields } from \"../generated/questionFields\";\r\n\r\nexport const questionFieldsFragment = gql`\r\n fragment questionFields on Question {\r\n id\r\n questionType\r\n name\r\n imageBlobReferenceId\r\n videoBlobReferenceId\r\n archived\r\n questionText\r\n questionTextImageBlobReferenceId\r\n preQuestionText\r\n maximumClicks\r\n maxScore\r\n timeLimitSeconds\r\n numberOfSubQuestions\r\n driverMetricId\r\n }\r\n`;\r\n\r\n\r\nexport type Question = Omit;\r\n\r\nexport const questionDefaultValues = (): Partial => ({\r\n id: Guid.newGuid(),\r\n name: '',\r\n questionType: '',\r\n questionText: '',\r\n imageBlobReferenceId: null,\r\n videoBlobReferenceId: null,\r\n questionTextImageBlobReferenceId: null,\r\n preQuestionText: '',\r\n maximumClicks: 10,\r\n maxScore: 100,\r\n timeLimitSeconds: 30,\r\n numberOfSubQuestions: 1,\r\n driverMetricId: null,\r\n});","import gql from \"graphql-tag\";\r\nimport { questionTagLinkFields } from \"../generated/questionTagLinkFields\";\r\n\r\nexport const questionTagLinkFieldsFragment = gql`\r\n fragment questionTagLinkFields on QuestionTagLink {\r\n id\r\n targetId\r\n targetType\r\n questionTagId\r\n archived\r\n }\r\n`;\r\n\r\n\r\nexport type QuestionTagLink = Omit;\r\n","import { useMutation } from \"@apollo/react-hooks\";\r\nimport { useAsyncCallback } from 'react-use-async-callback';\r\nimport gql from \"graphql-tag\";\r\nimport { AsyncActionStatus } from '../../../shared/abstractStore';\r\nimport { deleteQuestionTagLinkMutation, deleteQuestionTagLinkMutationVariables } from '../generated/deleteQuestionTagLinkMutation';\r\nimport { questionTagLinkFieldsFragment } from '../models/QuestionTagLink';\r\n\r\n/**\r\n * Get a callback to delete a QuestionTagLink in the store.\r\n */\r\nexport function useDeleteQuestionTagLinkCallback(): [(id: string) => Promise, AsyncActionStatus] {\r\n const [mutationAction, { error }] = useMutation(\r\n gql`\r\n mutation deleteQuestionTagLinkMutation ($id: ID!) {\r\n deleteQuestionTagLink(id: $id) {\r\n ...questionTagLinkFields\r\n }\r\n }\r\n\r\n ${questionTagLinkFieldsFragment}\r\n `\r\n );\r\n\r\n // Wrap the mutation in a standard callback.\r\n const [action, { isExecuting, errors: actionErrors }] = useAsyncCallback(async (id: string) => {\r\n const result = await mutationAction({ variables: { id: id } });\r\n if (result.errors && result.errors.length) {\r\n throw result.errors;\r\n }\r\n }, [mutationAction]);\r\n\r\n return [action, { isExecuting: isExecuting, errors: error ? error.message : actionErrors }];\r\n}\r\n","import gql from \"graphql-tag\";\r\nimport { Guid } from \"guid-string\";\r\nimport { driverMetricAdjustmentFields } from \"../generated/driverMetricAdjustmentFields\";\r\n\r\nexport const driverMetricAdjustmentFieldsFragment = gql`\r\n fragment driverMetricAdjustmentFields on DriverMetricAdjustment {\r\n id\r\n targetId\r\n targetType\r\n driverMetricId\r\n minScore\r\n maxScore\r\n adjustmentValue\r\n archived\r\n }\r\n`;\r\n\r\n\r\nexport type DriverMetricAdjustment = Omit;\r\n\r\n// Default values.\r\nexport const driverMetricAdjustmentDefaultValues = (): Partial => ({\r\n id: Guid.newGuid(),\r\n targetId: undefined,\r\n targetType: '',\r\n minScore: 0,\r\n maxScore: 100,\r\n driverMetricId: undefined,\r\n adjustmentValue: 1,\r\n});","import { useMutation } from \"@apollo/react-hooks\";\r\nimport { useAsyncCallback } from 'react-use-async-callback';\r\nimport gql from \"graphql-tag\";\r\nimport { AsyncActionStatus } from '../../../shared/abstractStore';\r\nimport { DriverMetricAdjustmentCreateInput } from '../generated/globalTypes';\r\nimport { createDriverMetricAdjustmentMutation, createDriverMetricAdjustmentMutationVariables } from '../generated/createDriverMetricAdjustmentMutation';\r\nimport { driverMetricAdjustmentFieldsFragment } from '../models/DriverMetricAdjustment';\r\n\r\n/**\r\n * Get a callback to create a DriverMetricAdjustment in the store.\r\n */\r\nexport function useCreateDriverMetricAdjustmentCallback(): [(model: DriverMetricAdjustmentCreateInput) => Promise, AsyncActionStatus] {\r\n const [mutationAction, { error }] = useMutation(\r\n gql`\r\n mutation createDriverMetricAdjustmentMutation ($model: DriverMetricAdjustmentCreateInput!) {\r\n createDriverMetricAdjustment(model: $model) {\r\n ...driverMetricAdjustmentFields\r\n }\r\n }\r\n\r\n ${driverMetricAdjustmentFieldsFragment}\r\n `\r\n );\r\n\r\n // Wrap the mutation in a standard callback.\r\n const [action, { isExecuting, errors: actionErrors }] = useAsyncCallback(async (model: DriverMetricAdjustmentCreateInput) => {\r\n const result = await mutationAction({ variables: { model: model } });\r\n if (result.errors && result.errors.length) {\r\n throw result.errors;\r\n }\r\n }, [mutationAction]);\r\n\r\n return [action, { isExecuting: isExecuting, errors: error ? error.message : actionErrors }];\r\n}\r\n","import { useMutation } from \"@apollo/react-hooks\";\r\nimport { useAsyncCallback } from 'react-use-async-callback';\r\nimport gql from \"graphql-tag\";\r\nimport { AsyncActionStatus } from '../../../shared/abstractStore';\r\nimport { DriverMetricAdjustmentUpdateInput } from '../generated/globalTypes';\r\nimport { updateDriverMetricAdjustmentMutation, updateDriverMetricAdjustmentMutationVariables } from '../generated/updateDriverMetricAdjustmentMutation';\r\nimport { driverMetricAdjustmentFieldsFragment } from '../models/DriverMetricAdjustment';\r\n\r\n/**\r\n * Get a callback to update a DriverMetricAdjustment in the store.\r\n */\r\nexport function useUpdateDriverMetricAdjustmentCallback(): [(id: string, model: DriverMetricAdjustmentUpdateInput) => Promise, AsyncActionStatus] {\r\n const [mutationAction, { error }] = useMutation(\r\n gql`\r\n mutation updateDriverMetricAdjustmentMutation ($model: DriverMetricAdjustmentUpdateInput!) {\r\n updateDriverMetricAdjustment(model: $model) {\r\n ...driverMetricAdjustmentFields\r\n }\r\n }\r\n\r\n ${driverMetricAdjustmentFieldsFragment}\r\n `\r\n );\r\n\r\n // Wrap the mutation in a standard callback.\r\n const [action, { isExecuting, errors: actionErrors }] = useAsyncCallback(async (id: string, model: DriverMetricAdjustmentUpdateInput) => {\r\n const result = await mutationAction({ variables: { model: { ...model, id: id } } });\r\n if (result.errors && result.errors.length) {\r\n throw result.errors;\r\n }\r\n }, [mutationAction]);\r\n\r\n return [action, { isExecuting: isExecuting, errors: error ? error.message : actionErrors }];\r\n}\r\n","import * as React from 'react';\r\nimport { DriverMetricAdjustmentCreateInput, DriverMetricAdjustmentUpdateInput } from '../generated/globalTypes';\r\nimport { useSaveInStore, SaveInStoreOptions } from '../../../shared/useSaveInStore';\r\nimport { useCreateDriverMetricAdjustmentCallback } from './useCreateDriverMetricAdjustmentCallback';\r\nimport { useUpdateDriverMetricAdjustmentCallback } from './useUpdateDriverMetricAdjustmentCallback';\r\nimport { DriverMetricAdjustment } from '../models/DriverMetricAdjustment';\r\n\r\n/**\r\n * Get a callback to save a DriverMetricAdjustment in the store using either a create or update.\r\n */\r\nexport function useSaveDriverMetricAdjustmentCallback(options: SaveInStoreOptions = {}) {\r\n const [_create, createStatus] = useCreateDriverMetricAdjustmentCallback();\r\n const create = React.useCallback((model: Partial) => _create(model as DriverMetricAdjustmentCreateInput), [_create]);\r\n\r\n const [_update, updateStatus] = useUpdateDriverMetricAdjustmentCallback();\r\n const update = React.useCallback((id: string, changes: Partial) => _update(id, changes as DriverMetricAdjustmentUpdateInput), [_update]);\r\n\r\n return useSaveInStore(\r\n [create, createStatus],\r\n [update, updateStatus],\r\n options\r\n );\r\n}\r\n","import { useMutation } from \"@apollo/react-hooks\";\r\nimport { useAsyncCallback } from 'react-use-async-callback';\r\nimport gql from \"graphql-tag\";\r\nimport { AsyncActionStatus } from '../../../shared/abstractStore';\r\nimport { deleteDriverMetricAdjustmentMutation, deleteDriverMetricAdjustmentMutationVariables } from '../generated/deleteDriverMetricAdjustmentMutation';\r\nimport { driverMetricAdjustmentFieldsFragment } from '../models/DriverMetricAdjustment';\r\n\r\n/**\r\n * Get a callback to delete a DriverMetricAdjustment in the store.\r\n */\r\nexport function useDeleteDriverMetricAdjustmentCallback(): [(id: string) => Promise, AsyncActionStatus] {\r\n const [mutationAction, { error }] = useMutation(\r\n gql`\r\n mutation deleteDriverMetricAdjustmentMutation ($id: ID!) {\r\n deleteDriverMetricAdjustment(id: $id) {\r\n ...driverMetricAdjustmentFields\r\n }\r\n }\r\n\r\n ${driverMetricAdjustmentFieldsFragment}\r\n `\r\n );\r\n\r\n // Wrap the mutation in a standard callback.\r\n const [action, { isExecuting, errors: actionErrors }] = useAsyncCallback(async (id: string) => {\r\n const result = await mutationAction({ variables: { id: id } });\r\n if (result.errors && result.errors.length) {\r\n throw result.errors;\r\n }\r\n }, [mutationAction]);\r\n\r\n return [action, { isExecuting: isExecuting, errors: error ? error.message : actionErrors }];\r\n}\r\n","import gql from \"graphql-tag\";\r\nimport { Guid } from \"guid-string\";\r\nimport { driverMetricRecommendationFields } from \"../generated/driverMetricRecommendationFields\";\r\n\r\nexport const driverMetricRecommendationFieldsFragment = gql`\r\n fragment driverMetricRecommendationFields on DriverMetricRecommendation {\r\n id\r\n targetId\r\n targetType\r\n driverMetricId\r\n minScore\r\n maxScore\r\n archived\r\n }\r\n`;\r\n\r\n\r\nexport type DriverMetricRecommendation = Omit;\r\n\r\n// Default values.\r\nexport const driverMetricRecommendationDefaultValues = () : Partial => ({\r\n id: Guid.newGuid(),\r\n targetId: undefined,\r\n targetType: '',\r\n minScore: 0,\r\n maxScore: 100,\r\n driverMetricId: undefined,\r\n});","import { useMutation } from \"@apollo/react-hooks\";\r\nimport { useAsyncCallback } from 'react-use-async-callback';\r\nimport gql from \"graphql-tag\";\r\nimport { AsyncActionStatus } from '../../../shared/abstractStore';\r\nimport { DriverMetricRecommendationCreateInput } from '../generated/globalTypes';\r\nimport { createDriverMetricRecommendationMutation, createDriverMetricRecommendationMutationVariables } from '../generated/createDriverMetricRecommendationMutation';\r\nimport { driverMetricRecommendationFieldsFragment } from '../models/DriverMetricRecommendation';\r\n\r\n/**\r\n * Get a callback to create a DriverMetricRecommendation in the store.\r\n */\r\nexport function useCreateDriverMetricRecommendationCallback(): [(model: DriverMetricRecommendationCreateInput) => Promise, AsyncActionStatus] {\r\n const [mutationAction, { error }] = useMutation(\r\n gql`\r\n mutation createDriverMetricRecommendationMutation ($model: DriverMetricRecommendationCreateInput!) {\r\n createDriverMetricRecommendation(model: $model) {\r\n ...driverMetricRecommendationFields\r\n }\r\n }\r\n\r\n ${driverMetricRecommendationFieldsFragment}\r\n `\r\n );\r\n\r\n // Wrap the mutation in a standard callback.\r\n const [action, { isExecuting, errors: actionErrors }] = useAsyncCallback(async (model: DriverMetricRecommendationCreateInput) => {\r\n const result = await mutationAction({ variables: { model: model } });\r\n if (result.errors && result.errors.length) {\r\n throw result.errors;\r\n }\r\n }, [mutationAction]);\r\n\r\n return [action, { isExecuting: isExecuting, errors: error ? error.message : actionErrors }];\r\n}\r\n","import { useMutation } from \"@apollo/react-hooks\";\r\nimport { useAsyncCallback } from 'react-use-async-callback';\r\nimport gql from \"graphql-tag\";\r\nimport { AsyncActionStatus } from '../../../shared/abstractStore';\r\nimport { DriverMetricRecommendationUpdateInput } from '../generated/globalTypes';\r\nimport { updateDriverMetricRecommendationMutation, updateDriverMetricRecommendationMutationVariables } from '../generated/updateDriverMetricRecommendationMutation';\r\nimport { driverMetricRecommendationFieldsFragment } from '../models/DriverMetricRecommendation';\r\n\r\n/**\r\n * Get a callback to update a DriverMetricRecommendation in the store.\r\n */\r\nexport function useUpdateDriverMetricRecommendationCallback(): [(id: string, model: DriverMetricRecommendationUpdateInput) => Promise, AsyncActionStatus] {\r\n const [mutationAction, { error }] = useMutation(\r\n gql`\r\n mutation updateDriverMetricRecommendationMutation ($model: DriverMetricRecommendationUpdateInput!) {\r\n updateDriverMetricRecommendation(model: $model) {\r\n ...driverMetricRecommendationFields\r\n }\r\n }\r\n\r\n ${driverMetricRecommendationFieldsFragment}\r\n `\r\n );\r\n\r\n // Wrap the mutation in a standard callback.\r\n const [action, { isExecuting, errors: actionErrors }] = useAsyncCallback(async (id: string, model: DriverMetricRecommendationUpdateInput) => {\r\n const result = await mutationAction({ variables: { model: { ...model, id: id } } });\r\n if (result.errors && result.errors.length) {\r\n throw result.errors;\r\n }\r\n }, [mutationAction]);\r\n\r\n return [action, { isExecuting: isExecuting, errors: error ? error.message : actionErrors }];\r\n}\r\n","import * as React from 'react';\r\nimport { DriverMetricRecommendationCreateInput, DriverMetricRecommendationUpdateInput } from '../generated/globalTypes';\r\nimport { useSaveInStore, SaveInStoreOptions } from '../../../shared/useSaveInStore';\r\nimport { useCreateDriverMetricRecommendationCallback } from './useCreateDriverMetricRecommendationCallback';\r\nimport { useUpdateDriverMetricRecommendationCallback } from './useUpdateDriverMetricRecommendationCallback';\r\nimport { DriverMetricRecommendation } from '../models/DriverMetricRecommendation';\r\n\r\n/**\r\n * Get a callback to save a DriverMetricRecommendation in the store using either a create or update.\r\n */\r\nexport function useSaveDriverMetricRecommendationCallback(options: SaveInStoreOptions = {}) {\r\n const [_create, createStatus] = useCreateDriverMetricRecommendationCallback();\r\n const create = React.useCallback((model: Partial) => _create(model as DriverMetricRecommendationCreateInput), [_create]);\r\n\r\n const [_update, updateStatus] = useUpdateDriverMetricRecommendationCallback();\r\n const update = React.useCallback((id: string, changes: Partial) => _update(id, changes as DriverMetricRecommendationUpdateInput), [_update]);\r\n\r\n return useSaveInStore(\r\n [create, createStatus],\r\n [update, updateStatus],\r\n options\r\n );\r\n}\r\n","import { useMutation } from \"@apollo/react-hooks\";\r\nimport { useAsyncCallback } from 'react-use-async-callback';\r\nimport gql from \"graphql-tag\";\r\nimport { AsyncActionStatus } from '../../../shared/abstractStore';\r\nimport { deleteDriverMetricRecommendationMutation, deleteDriverMetricRecommendationMutationVariables } from '../generated/deleteDriverMetricRecommendationMutation';\r\nimport { driverMetricRecommendationFieldsFragment } from '../models/DriverMetricRecommendation';\r\n\r\n/**\r\n * Get a callback to delete a DriverMetricRecommendation in the store.\r\n */\r\nexport function useDeleteDriverMetricRecommendationCallback(): [(id: string) => Promise, AsyncActionStatus] {\r\n const [mutationAction, { error }] = useMutation(\r\n gql`\r\n mutation deleteDriverMetricRecommendationMutation ($id: ID!) {\r\n deleteDriverMetricRecommendation(id: $id) {\r\n ...driverMetricRecommendationFields\r\n }\r\n }\r\n\r\n ${driverMetricRecommendationFieldsFragment}\r\n `\r\n );\r\n\r\n // Wrap the mutation in a standard callback.\r\n const [action, { isExecuting, errors: actionErrors }] = useAsyncCallback(async (id: string) => {\r\n const result = await mutationAction({ variables: { id: id } });\r\n if (result.errors && result.errors.length) {\r\n throw result.errors;\r\n }\r\n }, [mutationAction]);\r\n\r\n return [action, { isExecuting: isExecuting, errors: error ? error.message : actionErrors }];\r\n}\r\n","import { useMutation } from \"@apollo/react-hooks\";\r\nimport { useAsyncCallback } from 'react-use-async-callback';\r\nimport gql from \"graphql-tag\";\r\nimport { AsyncActionStatus } from '../../../shared/abstractStore';\r\nimport { QuestionTagLinkCreateInput } from '../generated/globalTypes';\r\nimport { createQuestionTagLinkMutation, createQuestionTagLinkMutationVariables } from '../generated/createQuestionTagLinkMutation';\r\nimport { questionTagLinkFieldsFragment } from '../models/QuestionTagLink';\r\n\r\n/**\r\n * Get a callback to create a QuestionTagLink in the store.\r\n */\r\nexport function useCreateQuestionTagLinkCallback(): [(model: QuestionTagLinkCreateInput) => Promise, AsyncActionStatus] {\r\n const [mutationAction, { error }] = useMutation(\r\n gql`\r\n mutation createQuestionTagLinkMutation ($model: QuestionTagLinkCreateInput!) {\r\n createQuestionTagLink(model: $model) {\r\n ...questionTagLinkFields\r\n }\r\n }\r\n\r\n ${questionTagLinkFieldsFragment}\r\n `\r\n );\r\n\r\n // Wrap the mutation in a standard callback.\r\n const [action, { isExecuting, errors: actionErrors }] = useAsyncCallback(async (model: QuestionTagLinkCreateInput) => {\r\n const result = await mutationAction({ variables: { model: model } });\r\n if (result.errors && result.errors.length) {\r\n throw result.errors;\r\n }\r\n }, [mutationAction]);\r\n\r\n return [action, { isExecuting: isExecuting, errors: error ? error.message : actionErrors }];\r\n}\r\n","import { useMutation } from \"@apollo/react-hooks\";\r\nimport { useAsyncCallback } from 'react-use-async-callback';\r\nimport gql from \"graphql-tag\";\r\nimport { AsyncActionStatus } from '../../../shared/abstractStore';\r\nimport { QuestionTagLinkUpdateInput } from '../generated/globalTypes';\r\nimport { updateQuestionTagLinkMutation, updateQuestionTagLinkMutationVariables } from '../generated/updateQuestionTagLinkMutation';\r\nimport { questionTagLinkFieldsFragment } from '../models/QuestionTagLink';\r\n\r\n/**\r\n * Get a callback to update a QuestionTagLink in the store.\r\n */\r\nexport function useUpdateQuestionTagLinkCallback(): [(id: string, model: QuestionTagLinkUpdateInput) => Promise, AsyncActionStatus] {\r\n const [mutationAction, { error }] = useMutation(\r\n gql`\r\n mutation updateQuestionTagLinkMutation ($model: QuestionTagLinkUpdateInput!) {\r\n updateQuestionTagLink(model: $model) {\r\n ...questionTagLinkFields\r\n }\r\n }\r\n\r\n ${questionTagLinkFieldsFragment}\r\n `\r\n );\r\n\r\n // Wrap the mutation in a standard callback.\r\n const [action, { isExecuting, errors: actionErrors }] = useAsyncCallback(async (id: string, model: QuestionTagLinkUpdateInput) => {\r\n const result = await mutationAction({ variables: { model: { ...model, id: id } } });\r\n if (result.errors && result.errors.length) {\r\n throw result.errors;\r\n }\r\n }, [mutationAction]);\r\n\r\n return [action, { isExecuting: isExecuting, errors: error ? error.message : actionErrors }];\r\n}\r\n","import * as React from 'react';\r\nimport { QuestionTagLinkCreateInput, QuestionTagLinkUpdateInput } from '../generated/globalTypes';\r\nimport { useSaveInStore, SaveInStoreOptions } from '../../../shared/useSaveInStore';\r\nimport { useCreateQuestionTagLinkCallback } from './useCreateQuestionTagLinkCallback';\r\nimport { useUpdateQuestionTagLinkCallback } from './useUpdateQuestionTagLinkCallback';\r\nimport { QuestionTagLink } from '../models/QuestionTagLink';\r\n\r\n/**\r\n * Get a callback to save a QuestionTagLink in the store using either a create or update.\r\n */\r\nexport function useSaveQuestionTagLinkCallback(options: SaveInStoreOptions = {}) {\r\n const [_create, createStatus] = useCreateQuestionTagLinkCallback();\r\n const create = React.useCallback((model: Partial) => _create(model as QuestionTagLinkCreateInput), [_create]);\r\n\r\n const [_update, updateStatus] = useUpdateQuestionTagLinkCallback();\r\n const update = React.useCallback((id: string, changes: Partial) => _update(id, changes as QuestionTagLinkUpdateInput), [_update]);\r\n\r\n return useSaveInStore(\r\n [create, createStatus],\r\n [update, updateStatus],\r\n options\r\n );\r\n}\r\n","import * as React from \"react\";\r\nimport { ValidationErrors, Validator, ValidationState } from \"pojo-validator\";\r\n\r\nexport type ValidateModelCallback = (model: T, fieldsToCheck?: string | Array | undefined) => boolean;\r\nexport type ValidationErrorsForModel = (id: string) => ValidationErrors;\r\n\r\n/**\r\n * Hook that provides a validate method and its associated validationErrors as a state object managed by validation.\r\n * \r\n * validation is a callback that is takes a model and stores the errors for all the models that have been passed in index by their id.\r\n * \r\n * @param validating the validation method.\r\n */\r\nexport function useValidatorArrayCallback(validating: (model: T, validation: ValidationState, fieldsToCheck?: Array) => void, deps: React.DependencyList)\r\n : [ValidateModelCallback, ValidationErrorsForModel] {\r\n const [validationErrors, setValidationErrors] = React.useState<{ [key: string]: ValidationErrors }>({});\r\n\r\n // Create the method in the right format for us to return it so we can call validate() directly.\r\n const validate = React.useCallback((model: T, fieldsToCheck?: string | Array): boolean => {\r\n let validator = new Validator(validating);\r\n\r\n // Work out the fields to be checked as we support passing a single field for convenience as well as passing an array.\r\n let fields: Array | undefined = undefined;\r\n if (fieldsToCheck) {\r\n if (fieldsToCheck as string) {\r\n fields = [(fieldsToCheck as string)];\r\n } else {\r\n fields = (fieldsToCheck as any) as Array;\r\n }\r\n }\r\n\r\n const ok = validator.validate(model, fields);\r\n\r\n setValidationErrors(prevState => ({\r\n ...prevState,\r\n [(model as any).id]: validator.errors(), // NOTE this line is not typesafe as it assumes T has a propery id.\r\n }));\r\n\r\n return ok;\r\n \r\n },\r\n // eslint-disable-next-line react-hooks/exhaustive-deps\r\n [...deps, validating, setValidationErrors]);\r\n\r\n const getErrors = React.useCallback((id: string) => {\r\n const ret = validationErrors[id];\r\n return ret ?? {} as ValidationErrors;\r\n }, [validationErrors]);\r\n\r\n return [validate, getErrors];\r\n}\r\n","/**\r\n * Returns true if there are any non-empty validation errors in the validationErrors passed in.\r\n * @param validationErrors\r\n */\r\nexport function hasAnyValidationErrors(validationErrors: Array | Array> | undefined | null) {\r\n let flatErrors = [validationErrors].flat(4).filter(item => item ? true : false);\r\n\r\n for (const error of flatErrors) {\r\n if (!!error) {\r\n return true;\r\n }\r\n }\r\n\r\n return false;\r\n}","import gql from \"graphql-tag\";\r\nimport { Guid } from \"guid-string\";\r\nimport moment from \"moment\";\r\nimport { assessmentItemFields } from \"../generated/assessmentItemFields\";\r\n\r\nexport const assessmentItemFieldsFragment = gql`\r\n fragment assessmentItemFields on AssessmentItem {\r\n id\r\n assessmentId\r\n displayOrder\r\n archived\r\n numberOfQuestionsToPresent\r\n counterbalanceGroup\r\n }\r\n`;\r\n\r\n\r\nexport type AssessmentItem = Omit;\r\n\r\n// Default values.\r\nexport const assessmentItemDefaultValues = (): Partial => ({\r\n id: Guid.newGuid(),\r\n assessmentId: undefined,\r\n displayOrder: moment().unix(),\r\n archived: false,\r\n numberOfQuestionsToPresent: 1,\r\n counterbalanceGroup: '',\r\n});","import { useMutation } from \"@apollo/react-hooks\";\r\nimport { useAsyncCallback } from 'react-use-async-callback';\r\nimport gql from \"graphql-tag\";\r\nimport { AsyncActionStatus } from '../../../shared/abstractStore';\r\nimport { AssessmentItemCreateInput } from '../generated/globalTypes';\r\nimport { createAssessmentItemMutation, createAssessmentItemMutationVariables } from '../generated/createAssessmentItemMutation';\r\nimport { assessmentItemFieldsFragment } from '../models/AssessmentItem';\r\n\r\n/**\r\n * Get a callback to create a AssessmentItem in the store.\r\n */\r\nexport function useCreateAssessmentItemCallback(): [(model: AssessmentItemCreateInput) => Promise, AsyncActionStatus] {\r\n const [mutationAction, { error }] = useMutation(\r\n gql`\r\n mutation createAssessmentItemMutation ($model: AssessmentItemCreateInput!) {\r\n createAssessmentItem(model: $model) {\r\n ...assessmentItemFields\r\n }\r\n }\r\n\r\n ${assessmentItemFieldsFragment}\r\n `\r\n );\r\n\r\n // Wrap the mutation in a standard callback.\r\n const [action, { isExecuting, errors: actionErrors }] = useAsyncCallback(async (model: AssessmentItemCreateInput) => {\r\n const result = await mutationAction({ variables: { model: model } });\r\n if (result.errors && result.errors.length) {\r\n throw result.errors;\r\n }\r\n }, [mutationAction]);\r\n\r\n return [action, { isExecuting: isExecuting, errors: error ? error.message : actionErrors }];\r\n}\r\n","import { useMutation } from \"@apollo/react-hooks\";\r\nimport { useAsyncCallback } from 'react-use-async-callback';\r\nimport gql from \"graphql-tag\";\r\nimport { AsyncActionStatus } from '../../../shared/abstractStore';\r\nimport { AssessmentItemUpdateInput } from '../generated/globalTypes';\r\nimport { updateAssessmentItemMutation, updateAssessmentItemMutationVariables } from '../generated/updateAssessmentItemMutation';\r\nimport { assessmentItemFieldsFragment } from '../models/AssessmentItem';\r\n\r\n/**\r\n * Get a callback to update a AssessmentItem in the store.\r\n */\r\nexport function useUpdateAssessmentItemCallback(): [(id: string, model: AssessmentItemUpdateInput) => Promise, AsyncActionStatus] {\r\n const [mutationAction, { error }] = useMutation(\r\n gql`\r\n mutation updateAssessmentItemMutation ($model: AssessmentItemUpdateInput!) {\r\n updateAssessmentItem(model: $model) {\r\n ...assessmentItemFields\r\n }\r\n }\r\n\r\n ${assessmentItemFieldsFragment}\r\n `\r\n );\r\n\r\n // Wrap the mutation in a standard callback.\r\n const [action, { isExecuting, errors: actionErrors }] = useAsyncCallback(async (id: string, model: AssessmentItemUpdateInput) => {\r\n const result = await mutationAction({ variables: { model: { ...model, id: id } } });\r\n if (result.errors && result.errors.length) {\r\n throw result.errors;\r\n }\r\n }, [mutationAction]);\r\n\r\n return [action, { isExecuting: isExecuting, errors: error ? error.message : actionErrors }];\r\n}\r\n","import { ApiFetch } from \"apifetch-json\";\r\nimport { BlobUploadService } from \"../../api/main/blobReferences/BlobUploadService\";\r\nimport { mainApiConfig } from \"../../configure/mainApiConfig\";\r\n\r\n/**\r\n * File upload adapter for CKEdtior5 that hooks the image upload capabilities up to our BlobReferences for storing the blobs and generating the URLs.\r\n */\r\nexport class BlobReferenceUploadAdapter {\r\n loader: any;\r\n apiFetch: ApiFetch;\r\n\r\n constructor(loader: any, apiFetch?: ApiFetch) {\r\n // The file loader instance to use during the upload.\r\n this.loader = loader;\r\n\r\n this.apiFetch = apiFetch ?? new ApiFetch();\r\n }\r\n\r\n // Starts the upload process.\r\n upload() {\r\n return this.loader.file\r\n .then((file: File) => new Promise((resolve, reject) => {\r\n const blobService = new BlobUploadService(mainApiConfig.blobUploadEndpoint, this.apiFetch);\r\n\r\n // Upload as a blob reference.\r\n return blobService\r\n .uploadFile(file)\r\n .then(blob => {\r\n if (blob && blob.id) {\r\n resolve({\r\n //default: blob.url,\r\n default: `${mainApiConfig.blobDownloadEndpoint}/${blob.id}`,\r\n });\r\n } else {\r\n reject(`Could not upload ${file.name}`);\r\n }\r\n });\r\n }));\r\n }\r\n}\r\n\r\n/**\r\n * Plugin to create the adapter (using default ApiFetch).\r\n * @param editor\r\n */\r\nexport function BlobReferenceUploadAdapterPlugin(editor: any) {\r\n editor.plugins.get('FileRepository').createUploadAdapter = (loader: any) => {\r\n // Configure the URL to the upload script in your back-end here!\r\n return new BlobReferenceUploadAdapter(loader);\r\n };\r\n}\r\n","import * as React from 'react';\r\nimport { CKEditor } from '@ckeditor/ckeditor5-react';\r\nimport DecoupledEditor from '@ckeditor/ckeditor5-build-decoupled-document';\r\nimport { Guid } from 'guid-string';\r\nimport { BlobReferenceUploadAdapterPlugin } from './BlobReferenceUploadAdapter';\r\nimport './HtmlEditor.scss';\r\n\r\nexport interface HtmlEditorProps {\r\n value?: string,\r\n onChange?: (value: string) => void,\r\n onBlur?: () => void,\r\n}\r\n\r\n/**\r\n * Html editor component that abstracts the editor actually being used from the code using it where its unimportant.\r\n * \r\n * This version uses CKEditor 5 internally.\r\n * \r\n * @param props\r\n */\r\nexport const HtmlEditor = (props: HtmlEditorProps) => {\r\n const { value, onChange, onBlur } = props;\r\n\r\n // Calculate a key that only changes when the value is changed external to the editor itself as we need to update the key\r\n // of the componentto force a re-render whenever that does happen as CKEditor doesn't cope with it otherwise which means\r\n // we would otherwise not update when we've loaded data from the database and would therefore keep showing as blank.\r\n const [key, setKey] = React.useState(() => Guid.newGuid());\r\n const trackedValue = React.useRef(value ?? '');\r\n React.useEffect(() => {\r\n if (value !== trackedValue.current) {\r\n // value has been changed external to the changes made by the user in the editor.\r\n setKey(Guid.newGuid());\r\n }\r\n }, [value, trackedValue, setKey]);\r\n\r\n return (\r\n
\r\n
\r\n
\r\n
\r\n {\r\n const data = editor.getData();\r\n\r\n // Keep a track of changes that were performed by the editor itself (so we can check for external changes).\r\n trackedValue.current = data;\r\n\r\n if (onChange) {\r\n onChange(data);\r\n }\r\n }}\r\n onBlur={(event: any, editor: any) => {\r\n if (onBlur) {\r\n onBlur();\r\n }\r\n }}\r\n onReady={(editor: any) => {\r\n if (!editor) {\r\n return;\r\n }\r\n\r\n // Insert the toolbar before the editable area.\r\n editor.ui?.getEditableElement().parentElement.insertBefore(\r\n editor.ui?.view.toolbar.element,\r\n editor.ui?.getEditableElement()\r\n );\r\n\r\n }}\r\n />\r\n
\r\n
\r\n
\r\n );\r\n};","import '../OEmbedProvider';\r\nimport { OEmbedProvider } from '../OEmbedProvider';\r\n\r\n/**\r\n * DailyMotion oembed provider.\r\n */\r\nexport const DailyMotionProvider: OEmbedProvider = {\r\n name: 'dailymotion',\r\n type: 'video',\r\n format: 'jsonp',\r\n api: 'https://www.dailymotion.com/services/oembed',\r\n urls: [\r\n \"dailymotion\\\\.com/.+\",\r\n ],\r\n};\r\n","import '../OEmbedProvider';\r\nimport { OEmbedProvider } from '../OEmbedProvider';\r\n\r\n/**\r\n * YouTube oembed provider.\r\n */\r\nexport const FacebookProvider: OEmbedProvider = {\r\n name: 'facebook',\r\n type: 'rich',\r\n format: 'json',\r\n api: 'https://TODO',\r\n urls: [\r\n \"facebook.com\",\r\n ],\r\n};\r\n","import '../OEmbedProvider';\r\nimport { OEmbedProvider } from '../OEmbedProvider';\r\n\r\n/**\r\n * Flickr oembed provider.\r\n */\r\nexport const FlickrProvider: OEmbedProvider = {\r\n name: 'flickr',\r\n type: 'photo',\r\n format: 'jsonp',\r\n api: 'https://www.flickr.com/services/oembed',\r\n urls: [\r\n \"flickr\\\\.com/photos/.+\",\r\n ],\r\n};\r\n","import '../OEmbedProvider';\r\nimport { OEmbedProvider } from '../OEmbedProvider';\r\n\r\n/**\r\n * YouTube oembed provider.\r\n */\r\nexport const GoogleMapsProvider: OEmbedProvider = {\r\n name: 'googleMaps',\r\n type: 'rich',\r\n format: 'json',\r\n api: 'https://TODO',\r\n urls: [\r\n \"TODO\",\r\n ],\r\n};\r\n","import '../OEmbedProvider';\r\nimport { OEmbedProvider } from '../OEmbedProvider';\r\n\r\n/**\r\n * Instagram oembed provider.\r\n */\r\nexport const InstagramProvider: OEmbedProvider = {\r\n name: 'instagram',\r\n type: 'photo',\r\n format: 'jsonp',\r\n api: 'https://api.instagram.com/oembed',\r\n urls: [\r\n \"instagr\\\\.?am(\\\\.com)?/.+\",\r\n ],\r\n};\r\n","import '../OEmbedProvider';\r\nimport { OEmbedProvider } from '../OEmbedProvider';\r\n\r\n/**\r\n * Spotify oembed provider.\r\n */\r\nexport const SpotifyProvider: OEmbedProvider = {\r\n name: 'spotify',\r\n type: 'rich',\r\n format: 'jsonp',\r\n api: 'https://embed.spotify.com/oembed/',\r\n urls: [\r\n \"open.spotify.com/(track|album|user)/\",\r\n ],\r\n};\r\n","import '../OEmbedProvider';\r\nimport { OEmbedProvider } from '../OEmbedProvider';\r\n\r\n/**\r\n * Twitter oembed provider.\r\n */\r\nexport const TwitterProvider: OEmbedProvider = {\r\n name: 'youtube',\r\n type: 'video',\r\n format: 'json',\r\n api: 'https://TODO',\r\n urls: [\r\n \"TODO\",\r\n ],\r\n};\r\n","import '../OEmbedProvider';\r\nimport { OEmbedProvider } from '../OEmbedProvider';\r\n\r\n/**\r\n * YouTube oembed provider.\r\n */\r\nexport const VimeoProvider: OEmbedProvider = {\r\n name: 'vimeo',\r\n type: 'video',\r\n format: 'json',\r\n api: 'https://vimeo.com/api/oembed.json',\r\n urls: [\r\n \"www\\\\.vimeo\\\\.com\\\\/groups\\\\/.*\\\\/videos\\\\/.*\",\r\n \"www\\\\.vimeo\\\\.com\\\\/.*\",\r\n \"vimeo\\\\.com\\\\/groups\\\\/.*\\\\/videos\\\\/.*\",\r\n \"vimeo\\\\.com\\\\/.*\"\r\n ],\r\n};\r\n","import '../OEmbedProvider';\r\nimport { OEmbedProvider } from '../OEmbedProvider';\r\n\r\n/**\r\n * YouTube oembed provider.\r\n */\r\nexport const YouTubeProvider: OEmbedProvider = {\r\n name: 'youtube',\r\n type: 'video',\r\n format: 'json',\r\n api: 'https://www.youtube.com/oembed',\r\n urls: [\r\n \"youtube\\\\.com/watch.+v=[\\\\w-]+&?\",\r\n \"youtu\\\\.be/[\\\\w-]+\",\r\n \"youtube.com/embed\"\r\n ],\r\n};\r\n","import { OEmbedProvider } from \"./OEmbedProvider\";\r\nimport { OEmbedResult } from \"./OEmbedResult\";\r\nimport { DailyMotionProvider } from \"./providers/DailyMotionProvider\";\r\nimport { FacebookProvider } from \"./providers/FacebookProvider\";\r\nimport { FlickrProvider } from \"./providers/FlickrProvider\";\r\nimport { GoogleMapsProvider } from \"./providers/GoogleMapsProvider\";\r\nimport { InstagramProvider } from \"./providers/InstagramProvider\";\r\nimport { SpotifyProvider } from \"./providers/SpotifyProvider\";\r\nimport { TwitterProvider } from \"./providers/TwitterProvider\";\r\nimport { VimeoProvider } from \"./providers/VimeoProvider\";\r\nimport { YouTubeProvider } from \"./providers/YouTubeProvider\";\r\nimport fetchJsonp from \"fetch-jsonp\";\r\n\r\n/**\r\n * Implementation of an oembed client that only depends on fetch() and fetch-jsonp (for JSONP support).\r\n */\r\nexport class FetchOmbed {\r\n private _providers: Array;\r\n\r\n constructor() {\r\n this._providers = [\r\n DailyMotionProvider,\r\n FacebookProvider,\r\n FlickrProvider,\r\n GoogleMapsProvider,\r\n InstagramProvider,\r\n SpotifyProvider,\r\n TwitterProvider,\r\n VimeoProvider,\r\n YouTubeProvider,\r\n ];\r\n }\r\n\r\n /**\r\n * Get the best provider for handling url.\r\n * @param url\r\n */\r\n getProvider(url: string): OEmbedProvider | null {\r\n for (const provider of this._providers) {\r\n for (const pattern of provider.urls) {\r\n var regExp = new RegExp(pattern);\r\n if (url.match(regExp)) {\r\n return provider;\r\n }\r\n }\r\n }\r\n\r\n return null;\r\n }\r\n\r\n /**\r\n * Return the OEmbedResult for url.\r\n * @param url\r\n */\r\n async getOEmbedData(url: string): Promise {\r\n // Find the right provider to use.\r\n const provider = this.getProvider(url);\r\n if (!provider) {\r\n console.error(`getOEmbedData could not find a registered provider to handle url: ${url}`);\r\n return null;\r\n }\r\n\r\n try {\r\n if (provider.format === 'jsonp') {\r\n // Special handling of JSONP which uses a script tab to return the json wrapped in a javascript callback function.\r\n const response = await fetchJsonp(`${provider.api}?format=json&url=${escape(url)}`);\r\n const result = await response.json();\r\n return result as OEmbedResult;\r\n } else {\r\n const response = await fetch(`${provider.api}?format=${escape(provider.format)}&url=${escape(url)}` /*, { mode: 'no-cors' } */);\r\n const result = await response.json();\r\n return result as OEmbedResult;\r\n }\r\n } catch (error) {\r\n console.error(`getOEmbedData failed when contacting provider: ${error}`);\r\n return null;\r\n }\r\n }\r\n\r\n\r\n}","import { FetchOmbed } from \"./FetchOEmbed\";\r\n\r\n/**\r\n * Scan element and its children looking for oembed elements. If we find any, then we load the oembed data we have providers for within them.\r\n * @param element\r\n */\r\nexport async function processOEmbedElements(element: Element): Promise {\r\n // Find all the oembed elements.\r\n const elements: Array = [\r\n ...(element.tagName.toLowerCase() === 'oembed'? [element]: []),\r\n ...element.getElementsByTagName('oembed')\r\n ];\r\n\r\n // If we didn't find any elements to process, return doing nothing.\r\n if (!elements.length) {\r\n return;\r\n }\r\n\r\n // Process each oembed element we find.\r\n const service = new FetchOmbed();\r\n for (const theElement of elements) {\r\n // Need a URL to work with.\r\n const url = theElement.getAttribute('url');\r\n if (!url) {\r\n continue;\r\n }\r\n\r\n // Load the data using our trusted oembed providers.\r\n const data = await service.getOEmbedData(url);\r\n if (!data || !data.html) {\r\n continue;\r\n }\r\n\r\n // Update the innerHTML of the element based on the result.\r\n theElement.innerHTML = data.html;\r\n }\r\n}","import './htmlDisplay.scss';\r\nimport * as React from 'react';\r\nimport { processOEmbedElements } from '../fetch-oembed';\r\n\r\nexport interface HtmlDisplayProps {\r\n html: string,\r\n textOnly?: boolean,\r\n}\r\n\r\n/**\r\n * Component that shows Html created by the user in HtmlEditor.\r\n * @param props\r\n */\r\nexport const HtmlDisplay = (props: HtmlDisplayProps) => {\r\n const { html, textOnly } = props;\r\n\r\n const elementRef = React.useRef(null);\r\n\r\n // Initialize any oembed content.\r\n React.useEffect(() => {\r\n setTimeout(() => {\r\n if (!elementRef.current) {\r\n return;\r\n }\r\n\r\n processOEmbedElements(elementRef.current);\r\n }, 100);\r\n }, [html]);\r\n\r\n return (\r\n
\r\n
\r\n );\r\n};","import \"./cardHeaderCollapse.scss\";\r\nimport { CardHeader, CardHeaderProps, Col, Row } from \"reactstrap\";\r\nimport { FontAwesomeIcon } from \"@fortawesome/react-fontawesome\";\r\n\r\nexport interface CardHeaderCollapseProps extends CardHeaderProps {\r\n isOpen: boolean,\r\n toggle: () => void,\r\n}\r\n\r\n/**\r\n * CardHeader that knows the card can collapse into its header.\r\n */\r\nexport const CardHeaderCollapse = (props: CardHeaderCollapseProps) => {\r\n const {\r\n isOpen,\r\n toggle,\r\n className,\r\n children,\r\n ...rest\r\n } = props;\r\n\r\n return (\r\n toggle()}\r\n {...rest}\r\n >\r\n \r\n \r\n {children}\r\n \r\n \r\n \r\n \r\n \r\n \r\n );\r\n};","import './uploadedVideoPreview.scss';\r\n\r\nimport { useTranslation } from 'react-i18next';\r\nimport { ConditionalFragment } from 'react-conditionalfragment';\r\nimport { FontAwesomeIcon } from '@fortawesome/react-fontawesome';\r\nimport { CSSProperties, ReactEventHandler } from 'react';\r\n\r\nexport interface UploadedVideoPreviewProps {\r\n src: string,\r\n poster?: string,\r\n\r\n className?: string,\r\n style?: CSSProperties,\r\n\r\n onTimeUpdate?: ReactEventHandler,\r\n}\r\n\r\n/**\r\n * Preview of an video uploaded by a user, suitable for use on an Edit form for example and made to look similar to other controls that would show in that context.\r\n */\r\nexport const UploadedVideoPreview = (props: UploadedVideoPreviewProps) => {\r\n const {\r\n src,\r\n poster,\r\n className,\r\n style,\r\n onTimeUpdate,\r\n } = props;\r\n\r\n const { t } = useTranslation();\r\n\r\n return (\r\n
\r\n \r\n
\r\n \r\n \r\n
\r\n
\r\n \r\n
\r\n
\r\n \r\n
\r\n

\r\n {\r\n t('uploadedVideoPreview.notVideoText', 'No video has been uploaded yet')\r\n }\r\n

\r\n
\r\n
\r\n
\r\n );\r\n};\r\n","import { FontAwesomeIcon } from \"@fortawesome/react-fontawesome\";\r\nimport { Guid } from \"guid-string\";\r\nimport { ValidationErrors } from \"pojo-validator\";\r\nimport { ValidateCallback } from \"pojo-validator-react\";\r\nimport { ValidatedInput } from \"pojo-validator-reactstrap\";\r\nimport { useCallback } from \"react\";\r\nimport { ConditionalFragment } from \"react-conditionalfragment\";\r\nimport { useTranslation } from \"react-i18next\";\r\nimport { useAsyncCallback } from \"react-use-async-callback\";\r\nimport { Button, ButtonGroup, Card, CardBody, Col, Collapse, Dropdown, DropdownItem, DropdownMenu, DropdownToggle, FormGroup, FormText, Label, Row, Spinner} from \"reactstrap\";\r\nimport { useToggleState } from \"use-toggle-state\";\r\nimport { AssessmentFeedback } from \"../../../../api/main/models/AssessmentFeedback\";\r\nimport { BlobReference } from \"../../../../api/main/models/BlobReference\";\r\nimport { HtmlEditor } from \"../../../../shared/htmlEditor\";\r\nimport { CardHeaderCollapse } from \"../../../shared/cardHeaderCollapse/CardHeaderCollapse\";\r\nimport { FileUploadButton } from \"../../../shared/fileUploadButton/FileUploadButton\";\r\nimport { FormButtons } from \"../../../shared/FormButtons\";\r\nimport { UploadedImagePreview } from \"../../../shared/uploadedImagePreview/UploadedImagePreview\";\r\nimport { UploadedVideoPreview } from \"../../../shared/uploadedVideoPreview/UploadedVideoPreview\";\r\n\r\nexport interface FeedbackProps {\r\n model: AssessmentFeedback | undefined,\r\n change: (changes: Partial) => void,\r\n remove: () => void,\r\n\r\n videoBlob: BlobReference | undefined | null,\r\n imageBlob: BlobReference | undefined | null,\r\n uploadChildBlob: (files: FileList | null) => Promise,\r\n\r\n isOpenInitially?: boolean,\r\n\r\n validate: ValidateCallback,\r\n validationErrors: ValidationErrors,\r\n}\r\n\r\n/**\r\n * An item of feedback for a question.\r\n * @param props\r\n */\r\nexport const Feedback = (props: FeedbackProps) => {\r\n const {\r\n model,\r\n change,\r\n remove,\r\n\r\n videoBlob,\r\n imageBlob,\r\n uploadChildBlob,\r\n isOpenInitially = false,\r\n\r\n validate,\r\n validationErrors,\r\n } = props;\r\n\r\n const { t } = useTranslation();\r\n\r\n // Self management of if we are expanded or not.\r\n const [isOpen, toggleOpen] = useToggleState(isOpenInitially);\r\n\r\n // Uploading the video blob.\r\n const [uploadVideoBlob, { isExecuting: isUploadingVideoBlob }] = useAsyncCallback(async (files: FileList | null) => {\r\n const blob = await uploadChildBlob(files);\r\n if (!blob) {\r\n return;\r\n }\r\n\r\n change({ videoBlobReferenceId: blob.id });\r\n }, [uploadChildBlob, change]);\r\n const clearVideoBlob = useCallback(() => {\r\n change({ videoBlobReferenceId: null });\r\n }, [change]);\r\n\r\n // Uploading the image blob.\r\n const [uploadImageBlob, { isExecuting: isUploadingImageBlob }] = useAsyncCallback(async (files: FileList | null) => {\r\n const blob = await uploadChildBlob(files);\r\n if (!blob) {\r\n return;\r\n }\r\n\r\n change({ imageBlobReferenceId: blob.id });\r\n }, [uploadChildBlob, change]);\r\n const clearImageBlob = useCallback(() => {\r\n change({ imageBlobReferenceId: null });\r\n }, [change]);\r\n\r\n\r\n const [isBlobDropdownOpen, toggleBlobDropdown] = useToggleState();\r\n\r\n return (\r\n \r\n \r\n
\r\n {t('feedback.heading.assessment', 'Feedback when total score is between {{minTotalScore}}% and {{maxTotalScore}}%', { minTotalScore: model?.minTotalScore ?? 0, maxTotalScore: model?.maxTotalScore ?? 0})}\r\n
\r\n
\r\n\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n\r\n \r\n \r\n change({ feedbackText: html })} />\r\n \r\n \r\n \r\n \r\n\r\n \r\n \r\n \r\n \r\n\r\n change({ minTotalScore: e.currentTarget.valueAsNumber })} onBlur={() => validate('minScore')} validationErrors={validationErrors['minScore']} />\r\n \r\n \r\n \r\n \r\n \r\n\r\n change({ maxTotalScore: e.currentTarget.valueAsNumber })} onBlur={() => validate('maxScore')} validationErrors={validationErrors['maxScore']} />\r\n \r\n \r\n \r\n\r\n\r\n \r\n \r\n\r\n {/* If we have no video show the image upload area, but including an option to upload a video. */}\r\n \r\n \r\n\r\n \r\n uploadImageBlob(files)} isExecuting={isUploadingImageBlob}\r\n executingChildren={<><> {t('common.uploading', 'Uploading...')}}\r\n >\r\n {t('feedback.uploadImage', 'Upload image...')}\r\n \r\n uploadVideoBlob(files)} isExecuting={isUploadingVideoBlob}\r\n executingChildren={<><> {t('common.uploading', 'Uploading...')}}\r\n >\r\n {t('feedback.uploadVideo', 'Upload video...')}\r\n \r\n toggleBlobDropdown()}>\r\n \r\n \r\n {t('common.more', 'More')}\r\n \r\n \r\n \r\n clearImageBlob()}>\r\n {t('feedback.clearImage', 'Clear image')}\r\n \r\n \r\n \r\n \r\n \r\n\r\n {/* If have a video show the video upload experience. User can return to the image upload experience by clearning the video.. */}\r\n \r\n \r\n\r\n \r\n uploadVideoBlob(files)} isExecuting={isUploadingVideoBlob}\r\n executingChildren={<><> {t('common.uploading', 'Uploading...')}}\r\n >\r\n {t('feedback.uploadVideo', 'Upload video...')}\r\n \r\n uploadImageBlob(files)} isExecuting={isUploadingImageBlob}\r\n executingChildren={<><> {t('common.uploading', 'Uploading...')}}\r\n >\r\n {t('feedback.uploadThumnail', 'Upload thumbnail...')}\r\n \r\n toggleBlobDropdown()}>\r\n \r\n \r\n {t('common.more', 'More')}\r\n \r\n \r\n \r\n clearVideoBlob()}>\r\n \r\n <> \r\n {t('feedback.clearVideo', 'Clear video')}\r\n \r\n clearImageBlob()}>\r\n \r\n <> \r\n {t('feedback.clearThumbnail', 'Clear thumbnail')}\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n
\r\n );\r\n};","import { useCallback, useMemo } from \"react\";\r\nimport { useTranslation } from \"react-i18next\";\r\nimport { Button, FormGroup, FormText, Label } from \"reactstrap\";\r\nimport { BlobReference } from \"../../../../api/main/models/BlobReference\";\r\nimport { ModelArrayChanges } from \"../../../../shared/useChanges\";\r\nimport { Feedback } from \"./Feedback\";\r\nimport { ValidationErrors } from \"pojo-validator\";\r\nimport { Assessment } from \"../../../../api/main/models/Assessment\";\r\nimport { AssessmentFeedback, assessmentFeedbackDefaultValues } from \"../../../../api/main/models/AssessmentFeedback\";\r\nimport { ValidatedInput } from \"pojo-validator-reactstrap\";\r\nimport { FeedbackStyle, feedbackStyleDisplayName } from \"../../../../api/main/models/codeOnly/FeedbackStyle\";\r\nimport { AssessmentType } from \"../../../../api/main/models/codeOnly/AssessmentType\";\r\nimport { ValidateCallback } from \"pojo-validator-react\";\r\n\r\nexport interface FeedbackTabProps {\r\n model: Assessment | undefined,\r\n change: (changes: Partial) => void,\r\n activeAssessmentType: AssessmentType,\r\n\r\n validate: ValidateCallback,\r\n validationErrors: ValidationErrors,\r\n\r\n feedbacksManager: ModelArrayChanges,\r\n\r\n childBlobs: Array,\r\n uploadChildBlob: (files: FileList | null) => Promise,\r\n\r\n validateAssessmentFeedback: (model: AssessmentFeedback) => boolean,\r\n assessmentFeedbackValidationErrors: (id: string) => ValidationErrors,\r\n}\r\n\r\n/**\r\n * Tab for maintaining the feedback based on the question scores.\r\n * @param props\r\n */\r\nexport const FeedbackTab = (props: FeedbackTabProps) => {\r\n const {\r\n model,\r\n change,\r\n activeAssessmentType,\r\n\r\n validate,\r\n validationErrors,\r\n\r\n feedbacksManager,\r\n childBlobs,\r\n uploadChildBlob,\r\n\r\n validateAssessmentFeedback,\r\n assessmentFeedbackValidationErrors,\r\n } = props;\r\n\r\n const { t } = useTranslation();\r\n\r\n // Order the feedback so they are shown based on their minimum score.\r\n const orderedFeedbacks = useMemo(() => {\r\n let ret = [...feedbacksManager.model];\r\n\r\n // Sort by min score, then max score.\r\n ret.sort((a, b) => (a.minTotalScore === b.minTotalScore ? (a.maxTotalScore === b.maxTotalScore? 0: a.maxTotalScore < b.maxTotalScore? -1: 1) : a.minTotalScore < b.minTotalScore ? -1 : 1));\r\n\r\n return ret;\r\n }, [feedbacksManager.model]);\r\n \r\n\r\n // Adding of feedback.\r\n const addFeedback = useCallback(() => {\r\n feedbacksManager.addFor({\r\n ...assessmentFeedbackDefaultValues(),\r\n\r\n assessmentId: model?.id,\r\n });\r\n }, [feedbacksManager, model?.id]);\r\n\r\n return (\r\n <>\r\n \r\n \r\n change({ feedbackStyle: e.currentTarget.value })} onBlur={e => validate('feedbackStyle')} validationErrors={validationErrors['feedbackStyle']}>\r\n {\r\n Object.values(FeedbackStyle)\r\n .map(item => (\r\n \r\n ))\r\n }\r\n \r\n \r\n {\r\n activeAssessmentType === AssessmentType.TrainingModule ? t('editAssessmentBase.feedbackStyle.formText.learning', 'This controls how the user is given feedback on the Finish page and throughout the learning module.')\r\n : t('editAssessmentBase.feedbackStyle.formText.assessment', 'This controls how the user is given feedback on the Finish page and throughout the assessment.')\r\n }\r\n \r\n \r\n\r\n \r\n \r\n\r\n
\r\n {\r\n orderedFeedbacks.map(item => (\r\n feedbacksManager.changeFor(item.id, changes)}\r\n remove={() => feedbacksManager.removeFor(item.id)}\r\n\r\n isOpenInitially={!!feedbacksManager.added.find(it => it.id === item.id)}\r\n\r\n videoBlob={childBlobs.find(it => it.id === item.videoBlobReferenceId)}\r\n imageBlob={childBlobs.find(it => it.id === item.imageBlobReferenceId)}\r\n uploadChildBlob={uploadChildBlob}\r\n\r\n validate={() => validateAssessmentFeedback(item)}\r\n validationErrors={assessmentFeedbackValidationErrors(item.id)}\r\n />\r\n ))\r\n }\r\n
\r\n\r\n \r\n
\r\n \r\n );\r\n};\r\n","import { FontAwesomeIcon } from \"@fortawesome/react-fontawesome\";\r\nimport { ValidationErrors } from \"pojo-validator\";\r\nimport { ValidateCallback } from \"pojo-validator-react\";\r\nimport { ValidatedInput } from \"pojo-validator-reactstrap\";\r\nimport { useTranslation } from \"react-i18next\";\r\nimport { Button, ButtonGroup, Card, FormGroup } from \"reactstrap\";\r\nimport { AssessmentType } from \"../../../../api/main/models/codeOnly/AssessmentType\";\r\nimport { DriverMetric } from \"../../../../api/main/models/DriverMetric\";\r\nimport { DriverMetricRecommendation } from \"../../../../api/main/models/DriverMetricRecommendation\";\r\nimport { FormButtons } from \"../../../shared/FormButtons\";\r\n\r\nexport interface DriverMetricRecommendationComponentProps {\r\n model: DriverMetricRecommendation | undefined,\r\n change: (changes: Partial) => void,\r\n remove: () => void,\r\n\r\n validate: ValidateCallback,\r\n validationErrors: ValidationErrors,\r\n\r\n driverMetrics: Array,\r\n\r\n assessmentType: AssessmentType | undefined | null,\r\n}\r\n\r\n/**\r\n * Component for driver metric recommendation rules for questions.\r\n * @param props\r\n */\r\nexport const DriverMetricRecommendationComponent = (props: DriverMetricRecommendationComponentProps) => {\r\n const {\r\n model,\r\n change,\r\n remove,\r\n validate,\r\n validationErrors,\r\n driverMetrics,\r\n assessmentType,\r\n } = props;\r\n\r\n const { t } = useTranslation();\r\n\r\n return (\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n
\r\n {\r\n assessmentType === AssessmentType.TrainingModule ? t('driverMetricRecommendationComponent.beforeMetric.learning', 'Recommend this training module when')\r\n : t('driverMetricRecommendationComponent.beforeMetric.assessment', 'Recommend this assessment when')\r\n }\r\n <> \r\n change({ driverMetricId: e.currentTarget.value })} onBlur={() => validate('driverMetricId')} validationErrors={validationErrors['driverMetricId']}>\r\n \r\n {\r\n driverMetrics.map(item => (\r\n \r\n ))\r\n }\r\n \r\n <> \r\n {t('driverMetricRecommendationComponent.beforeMin', 'is between')}\r\n <> \r\n change({ minScore: e.currentTarget.valueAsNumber })} onBlur={() => validate('minScore')} validationErrors={validationErrors['minScore']} />\r\n <> \r\n {t('driverMetricRecommendationComponent.beforeMax', 'and')}\r\n <> \r\n change({ maxScore: e.currentTarget.valueAsNumber })} onBlur={() => validate('maxScore')} validationErrors={validationErrors['maxScore']} />\r\n <> \r\n {t('driverMetricRecommendationComponent.afterMax', '')}\r\n
\r\n
\r\n
\r\n );\r\n};","import { ValidationErrors } from \"pojo-validator\";\r\nimport { useCallback, useMemo } from \"react\";\r\nimport { useTranslation } from \"react-i18next\";\r\nimport { Button, FormGroup, Label } from \"reactstrap\";\r\nimport { Assessment } from \"../../../../api/main/models/Assessment\";\r\nimport { AssessmentType } from \"../../../../api/main/models/codeOnly/AssessmentType\";\r\nimport { DriverMetric } from \"../../../../api/main/models/DriverMetric\";\r\nimport { DriverMetricAdjustment } from \"../../../../api/main/models/DriverMetricAdjustment\";\r\nimport { DriverMetricRecommendation, driverMetricRecommendationDefaultValues } from \"../../../../api/main/models/DriverMetricRecommendation\";\r\nimport { ModelArrayChanges } from \"../../../../shared/useChanges\";\r\nimport { DriverMetricRecommendationComponent } from \"./DriverMetricRecommendationComponent\";\r\n\r\nexport interface DriverMetricsTabProps {\r\n model: Assessment | undefined,\r\n change: (changes: Partial) => void,\r\n activeAssessmentType: AssessmentType,\r\n\r\n driverMetricRecommendationsManager: ModelArrayChanges,\r\n driverMetricAdjustmentsManager: ModelArrayChanges,\r\n\r\n driverMetrics: Array,\r\n\r\n validateDriverMetricRecommendation: (model: DriverMetricRecommendation) => boolean,\r\n driverMetricRecommendationValidationErrors: (id: string) => ValidationErrors,\r\n\r\n validateDriverMetricAdjustment: (model: DriverMetricAdjustment) => boolean,\r\n driverMetricAdjustmentValidationErrors: (id: string) => ValidationErrors,\r\n}\r\n\r\n/**\r\n * Tab for maintaining driver metrics for a question.\r\n * @param props\r\n */\r\nexport const DriverMetricsTab = (props: DriverMetricsTabProps) => {\r\n const {\r\n model,\r\n //change,\r\n //activeAssessmentType,\r\n\r\n driverMetricRecommendationsManager,\r\n //driverMetricAdjustmentsManager,\r\n driverMetrics,\r\n\r\n validateDriverMetricRecommendation,\r\n driverMetricRecommendationValidationErrors,\r\n\r\n //validateDriverMetricAdjustment,\r\n //driverMetricAdjustmentValidationErrors,\r\n } = props;\r\n\r\n const { t } = useTranslation();\r\n\r\n // Order the recommendations so they are shown based on their minimum score.\r\n const orderedRecommendations = useMemo(() => {\r\n let ret = [...driverMetricRecommendationsManager.model];\r\n\r\n // Sort by min score, then max score.\r\n ret.sort((a, b) => (a.minScore === b.minScore ? (a.maxScore === b.maxScore ? 0 : a.maxScore < b.maxScore ? -1 : 1) : a.minScore < b.minScore ? -1 : 1));\r\n\r\n return ret;\r\n }, [driverMetricRecommendationsManager.model]);\r\n\r\n // Adding of a recommendation.\r\n const addRecommendation = useCallback(() => {\r\n driverMetricRecommendationsManager.addFor({\r\n ...driverMetricRecommendationDefaultValues(),\r\n\r\n targetId: model?.id,\r\n targetType: 'Assessment',\r\n });\r\n }, [driverMetricRecommendationsManager, model?.id]);\r\n\r\n //// Order the adjustments so they are shown based on their minimum score.\r\n //const orderedAdjustments = useMemo(() => {\r\n // let ret = [...driverMetricAdjustmentsManager.model];\r\n\r\n // // Sort by min score, then max score.\r\n // ret.sort((a, b) => (a.minScore === b.minScore ? (a.maxScore === b.maxScore? 0: a.maxScore < b.maxScore? -1: 1) : a.minScore < b.minScore ? -1 : 1));\r\n\r\n // return ret;\r\n //}, [driverMetricAdjustmentsManager.model]);\r\n\r\n //// Adding of an adjustment.\r\n //const addAdjustment = useCallback(() => {\r\n // driverMetricAdjustmentsManager.addFor({\r\n // ...driverMetricAdjustmentDefaultValues(),\r\n\r\n // targetId: model?.id,\r\n // targetType: 'Assessment',\r\n // });\r\n //}, [driverMetricAdjustmentsManager, model?.id]);\r\n\r\n \r\n return (\r\n <>\r\n {/*\r\n \r\n change({ isSmartIndividuality: checked })}\r\n />\r\n \r\n {\r\n activeAssessmentType === AssessmentType.TrainingModule ? t('editAssessmentBase.isSmartIndividuality.formText.standardised.trainingModule', 'Standardised training modules are always fair and are not customised for the user taking the training, except to exclude questions they have seen previously.')\r\n : t('editAssessmentBase.isSmartIndividuality.formText.standardised.assessment', 'Standardised assessments are always fair and are not customised for the user taking the assessment, except to exclude questions they have seen previously.')\r\n }\r\n
\r\n {\r\n activeAssessmentType === AssessmentType.TrainingModule ? t('editAssessmentBase.isSmartIndividuality.formText.smart.trainingModule', 'Smart customised training modules look at the safety metrics of the user taking the training and check them against safety metric recommendations for indivudal questions and activities to customise the presented questions and activities to the needs of the individual user.')\r\n : t('editAssessmentBase.isSmartIndividuality.formText.smart.assessment', 'Smart customised assessments look at the safety metrics of the user taking the assessment and check them against safety metric recommendations for indivudal questions and activities to customise the presented questions and activities to the needs of the individual user.')\r\n }\r\n
\r\n
*/}\r\n\r\n \r\n \r\n\r\n
\r\n {\r\n orderedRecommendations.map(item => (\r\n driverMetricRecommendationsManager.changeFor(item.id, changes)}\r\n remove={() => driverMetricRecommendationsManager.removeFor(item.id)}\r\n driverMetrics={driverMetrics}\r\n validate={() => validateDriverMetricRecommendation(item)}\r\n validationErrors={driverMetricRecommendationValidationErrors(item.id)}\r\n assessmentType={model?.assessmentType as AssessmentType}\r\n />\r\n ))\r\n }\r\n
\r\n\r\n \r\n
\r\n\r\n {/* Driver metric adjustments have been removed form the UI in favour of using much simplier logic built around the primary driver metrics instead. */}\r\n {/*}\r\n \r\n\r\n
\r\n {\r\n orderedAdjustments.map(item => (\r\n driverMetricAdjustmentsManager.changeFor(item.id, changes)}\r\n remove={() => driverMetricAdjustmentsManager.removeFor(item.id)}\r\n driverMetrics={driverMetrics}\r\n validate={() => validateDriverMetricAdjustment(item)}\r\n validationErrors={driverMetricAdjustmentValidationErrors(item.id)}\r\n assessmentType={model?.assessmentType as AssessmentType}\r\n />\r\n ))\r\n }\r\n
\r\n\r\n \r\n
*/}\r\n \r\n );\r\n};\r\n","import { FontAwesomeIcon } from \"@fortawesome/react-fontawesome\";\r\nimport { useCallback } from \"react\";\r\nimport { ConditionalFragment } from \"react-conditionalfragment\";\r\nimport { Button, ButtonGroup } from \"reactstrap\";\r\nimport { QuestionTag } from \"../../../api/main/models/QuestionTag\";\r\nimport \"./questionTagButton.scss\";\r\n\r\nexport interface QuestionTagButtonProps {\r\n tag: QuestionTag,\r\n isSelected: boolean,\r\n toggleSelected?: () => void,\r\n gray?: boolean,\r\n readonly?: boolean,\r\n}\r\n\r\n/**\r\n * Button for toggling a question tag on or off.\r\n */\r\nexport const QuestionTagButton = (props: QuestionTagButtonProps) => {\r\n const {\r\n tag,\r\n isSelected,\r\n toggleSelected,\r\n gray = false,\r\n readonly = false,\r\n } = props;\r\n\r\n const onToggleSelected = useCallback(() => {\r\n if (toggleSelected) {\r\n toggleSelected();\r\n }\r\n }, [toggleSelected]);\r\n\r\n return (\r\n \r\n \r\n \r\n \r\n \r\n \r\n );\r\n};\r\n","import { FontAwesomeIcon } from \"@fortawesome/react-fontawesome\";\r\nimport { useCallback, useMemo, KeyboardEvent } from \"react\";\r\nimport { ConditionalFragment } from \"react-conditionalfragment\";\r\nimport { useTranslation } from \"react-i18next\";\r\nimport { Col, Collapse, Row } from \"reactstrap\";\r\nimport { useToggleState } from \"use-toggle-state\";\r\nimport { QuestionTag } from \"../../../api/main/models/QuestionTag\";\r\nimport { QuestionTagButton } from \"./QuestionTagButton\";\r\nimport \"./questionTagSelector.scss\";\r\n\r\nexport interface QuestionTagSelectorProps {\r\n tags: Array,\r\n isSelected: (id: string) => boolean,\r\n toggleSelected?: (id: string) => void,\r\n}\r\n\r\n/**\r\n * Selector for toggling a question tag on or off.\r\n */\r\nexport const QuestionTagSelector = (props: QuestionTagSelectorProps) => {\r\n const {\r\n tags,\r\n isSelected,\r\n toggleSelected,\r\n } = props;\r\n\r\n const { t } = useTranslation();\r\n\r\n const [isOpen, toggleOpen] = useToggleState();\r\n\r\n const selectedTags = useMemo(() => {\r\n return tags.filter(item => isSelected(item.id));\r\n }, [tags, isSelected]);\r\n\r\n // Handle keyboard keys in a way that let us act select like.\r\n const keyDown = useCallback((event: KeyboardEvent) => {\r\n switch (event.key) {\r\n case 'Down':\r\n case 'ArrowDown':\r\n case 'ArrowUp':\r\n case 'Esc':\r\n case 'Escape':\r\n case ' ':\r\n case 'Enter':\r\n toggleOpen();\r\n break;\r\n default:\r\n break;\r\n }\r\n }, [toggleOpen]);\r\n\r\n return (\r\n
\r\n
toggleOpen()}>\r\n \r\n \r\n {\r\n selectedTags\r\n .map(item => (\r\n \r\n ))\r\n }\r\n \r\n \r\n {t('questionTagSelector.nothingSelected', 'No tags have been selected.')}\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n
\r\n \r\n
\r\n {\r\n tags.map(item => (\r\n {\r\n if (toggleSelected) {\r\n toggleSelected(item.id);\r\n }\r\n }}\r\n />\r\n ))\r\n }\r\n
\r\n
\r\n
\r\n );\r\n};\r\n","import { Guid } from \"guid-string\";\r\nimport { useCallback } from \"react\";\r\nimport { useTranslation } from \"react-i18next\";\r\nimport { FormGroup, Label } from \"reactstrap\";\r\nimport { Assessment } from \"../../../../api/main/models/Assessment\";\r\nimport { QuestionTag } from \"../../../../api/main/models/QuestionTag\";\r\nimport { QuestionTagLink } from \"../../../../api/main/models/QuestionTagLink\";\r\nimport { ModelArrayChanges } from \"../../../../shared/useChanges\";\r\nimport { QuestionTagSelector } from \"../../../questionTags/questionTagSelector/QuestionTagSelector\";\r\n\r\nexport interface QuestionTagsTabProps {\r\n model: Assessment | undefined,\r\n\r\n questionTags: Array,\r\n linksManager: ModelArrayChanges,\r\n}\r\n\r\n/**\r\n * Tab for maintaining the tags for this question.\r\n * @param props\r\n */\r\nexport const QuestionTagsTab = (props: QuestionTagsTabProps) => {\r\n const {\r\n model,\r\n\r\n questionTags,\r\n linksManager,\r\n } = props;\r\n\r\n const { t } = useTranslation();\r\n\r\n // Returns if this tag is selected or not.\r\n const isSelected = useCallback((id: string) => {\r\n return !!linksManager.model.find(it => it.questionTagId === id);\r\n }, [linksManager]);\r\n\r\n // Toggle the selection of the tag.\r\n const toggleSelected = useCallback((id: string) => {\r\n const existing = linksManager.model.find(it => it.questionTagId === id);\r\n if (existing) {\r\n linksManager.removeFor(existing.id);\r\n } else {\r\n linksManager.addFor({ id: Guid.newGuid(), questionTagId: id, targetId: model?.id, targetType: 'Assessment', archived: false, });\r\n }\r\n }, [linksManager, model?.id]);\r\n \r\n return (\r\n <>\r\n \r\n \r\n\r\n \r\n \r\n \r\n );\r\n};","import { Dispatch, SetStateAction, useCallback, useMemo, useState } from \"react\";\r\nimport { useAsyncCallback } from \"react-use-async-callback\";\r\nimport { useUploadBlobCallback } from \"../../../api/main/blobReferences/useUploadBlobCallback\";\r\nimport { BlobReference } from \"../../../api/main/models/BlobReference\";\r\n\r\nexport type BlobReferenceStateArrayReturnType = [\r\n Array,\r\n Dispatch>>,\r\n {\r\n upload: (files: FileList | null) => Promise,\r\n isUploading: boolean,\r\n uploadErrors: any,\r\n clearUpload: (id: string) => void,\r\n }\r\n];\r\n\r\n/**\r\n * Custom hook to manage a BlobReference in state along with upload options.\r\n */\r\nexport function useBlobReferenceStateArray(initialValue?: Array)\r\n : BlobReferenceStateArrayReturnType\r\n{\r\n // State we store the blob in.\r\n const [blobReferences, setBlobReferences] = useState>(initialValue ?? []);\r\n\r\n // Uploading of a blob.\r\n const [uploadBlob] = useUploadBlobCallback();\r\n const [upload, { isExecuting: isUploading, errors: uploadErrors }] = useAsyncCallback(async (files: FileList | null) => {\r\n if (!files) {\r\n return null;\r\n }\r\n\r\n // Upload the blob.\r\n const blob = await uploadBlob(files);\r\n if (!blob) {\r\n return null;\r\n }\r\n\r\n setBlobReferences(prevState => [\r\n ...prevState,\r\n blob,\r\n ]);\r\n\r\n return blob;\r\n }, [uploadBlob, setBlobReferences]);\r\n\r\n // Clearning a blob.\r\n const clearUpload = useCallback((id: string) => {\r\n setBlobReferences(prevState => prevState.filter(it => it.id !== id));\r\n }, [setBlobReferences]);\r\n\r\n // Return everything in a format that is easy for people to grab the bits they want.\r\n const ret = useMemo((): BlobReferenceStateArrayReturnType => ([\r\n blobReferences,\r\n setBlobReferences,\r\n {\r\n upload,\r\n isUploading,\r\n uploadErrors,\r\n clearUpload,\r\n }\r\n ]), [blobReferences, setBlobReferences, upload, isUploading, uploadErrors, clearUpload]);\r\n\r\n return ret;\r\n}","import gql from \"graphql-tag\";\r\nimport { Guid } from \"guid-string\";\r\nimport { assessmentItemQuestionFields } from \"../generated/assessmentItemQuestionFields\";\r\n\r\nexport const assessmentItemQuestionFieldsFragment = gql`\r\n fragment assessmentItemQuestionFields on AssessmentItemQuestion {\r\n id\r\n assessmentId\r\n assessmentItemId\r\n questionId\r\n archived\r\n }\r\n`;\r\n\r\n\r\nexport type AssessmentItemQuestion = Omit;\r\n\r\n// Default values.\r\nexport const assessmentItemQuestionDefaultValues = (): Partial => ({\r\n id: Guid.newGuid(),\r\n assessmentId: undefined,\r\n assessmentItemId: undefined,\r\n questionId: undefined,\r\n archived: false,\r\n});","import gql from \"graphql-tag\";\r\nimport { Guid } from \"guid-string\";\r\nimport { assessmentItemDriverMetricQuantityFields } from \"../generated/assessmentItemDriverMetricQuantityFields\";\r\n\r\nexport const assessmentItemDriverMetricQuantityFieldsFragment = gql`\r\n fragment assessmentItemDriverMetricQuantityFields on AssessmentItemDriverMetricQuantity {\r\n id\r\n assessmentItemId\r\n driverMetricId\r\n quantity\r\n archived\r\n }\r\n`;\r\n\r\n\r\nexport type AssessmentItemDriverMetricQuantity = Omit;\r\n\r\n// Default values.\r\nexport const assessmentItemDriverMetricQuantityDefaultValues = (): Partial => ({\r\n id: Guid.newGuid(),\r\n assessmentItemId: undefined,\r\n driverMetricId: undefined,\r\n quantity: undefined,\r\n archived: false,\r\n});","import { useMutation } from \"@apollo/react-hooks\";\r\nimport { useAsyncCallback } from 'react-use-async-callback';\r\nimport gql from \"graphql-tag\";\r\nimport { AsyncActionStatus } from '../../../shared/abstractStore';\r\nimport { AssessmentItemQuestionCreateInput } from '../generated/globalTypes';\r\nimport { createAssessmentItemQuestionMutation, createAssessmentItemQuestionMutationVariables } from '../generated/createAssessmentItemQuestionMutation';\r\nimport { assessmentItemQuestionFieldsFragment } from '../models/AssessmentItemQuestion';\r\n\r\n/**\r\n * Get a callback to create a AssessmentItemQuestion in the store.\r\n */\r\nexport function useCreateAssessmentItemQuestionCallback(): [(model: AssessmentItemQuestionCreateInput) => Promise, AsyncActionStatus] {\r\n const [mutationAction, { error }] = useMutation(\r\n gql`\r\n mutation createAssessmentItemQuestionMutation ($model: AssessmentItemQuestionCreateInput!) {\r\n createAssessmentItemQuestion(model: $model) {\r\n ...assessmentItemQuestionFields\r\n }\r\n }\r\n\r\n ${assessmentItemQuestionFieldsFragment}\r\n `\r\n );\r\n\r\n // Wrap the mutation in a standard callback.\r\n const [action, { isExecuting, errors: actionErrors }] = useAsyncCallback(async (model: AssessmentItemQuestionCreateInput) => {\r\n const result = await mutationAction({ variables: { model: model } });\r\n if (result.errors && result.errors.length) {\r\n throw result.errors;\r\n }\r\n }, [mutationAction]);\r\n\r\n return [action, { isExecuting: isExecuting, errors: error ? error.message : actionErrors }];\r\n}\r\n","import { useMutation } from \"@apollo/react-hooks\";\r\nimport { useAsyncCallback } from 'react-use-async-callback';\r\nimport gql from \"graphql-tag\";\r\nimport { AsyncActionStatus } from '../../../shared/abstractStore';\r\nimport { AssessmentItemQuestionUpdateInput } from '../generated/globalTypes';\r\nimport { updateAssessmentItemQuestionMutation, updateAssessmentItemQuestionMutationVariables } from '../generated/updateAssessmentItemQuestionMutation';\r\nimport { assessmentItemQuestionFieldsFragment } from '../models/AssessmentItemQuestion';\r\n\r\n/**\r\n * Get a callback to update a AssessmentItemQuestion in the store.\r\n */\r\nexport function useUpdateAssessmentItemQuestionCallback(): [(id: string, model: AssessmentItemQuestionUpdateInput) => Promise, AsyncActionStatus] {\r\n const [mutationAction, { error }] = useMutation(\r\n gql`\r\n mutation updateAssessmentItemQuestionMutation ($model: AssessmentItemQuestionUpdateInput!) {\r\n updateAssessmentItemQuestion(model: $model) {\r\n ...assessmentItemQuestionFields\r\n }\r\n }\r\n\r\n ${assessmentItemQuestionFieldsFragment}\r\n `\r\n );\r\n\r\n // Wrap the mutation in a standard callback.\r\n const [action, { isExecuting, errors: actionErrors }] = useAsyncCallback(async (id: string, model: AssessmentItemQuestionUpdateInput) => {\r\n const result = await mutationAction({ variables: { model: { ...model, id: id } } });\r\n if (result.errors && result.errors.length) {\r\n throw result.errors;\r\n }\r\n }, [mutationAction]);\r\n\r\n return [action, { isExecuting: isExecuting, errors: error ? error.message : actionErrors }];\r\n}\r\n","import { useMutation } from \"@apollo/react-hooks\";\r\nimport { useAsyncCallback } from 'react-use-async-callback';\r\nimport gql from \"graphql-tag\";\r\nimport { AsyncActionStatus } from '../../../shared/abstractStore';\r\nimport { deleteAssessmentItemQuestionMutation, deleteAssessmentItemQuestionMutationVariables } from '../generated/deleteAssessmentItemQuestionMutation';\r\nimport { assessmentItemQuestionFieldsFragment } from '../models/AssessmentItemQuestion';\r\n\r\n/**\r\n * Get a callback to delete a AssessmentItemQuestion in the store.\r\n */\r\nexport function useDeleteAssessmentItemQuestionCallback(): [(id: string) => Promise, AsyncActionStatus] {\r\n const [mutationAction, { error }] = useMutation(\r\n gql`\r\n mutation deleteAssessmentItemQuestionMutation ($id: ID!) {\r\n deleteAssessmentItemQuestion(id: $id) {\r\n ...assessmentItemQuestionFields\r\n }\r\n }\r\n\r\n ${assessmentItemQuestionFieldsFragment}\r\n `\r\n );\r\n\r\n // Wrap the mutation in a standard callback.\r\n const [action, { isExecuting, errors: actionErrors }] = useAsyncCallback(async (id: string) => {\r\n const result = await mutationAction({ variables: { id: id } });\r\n if (result.errors && result.errors.length) {\r\n throw result.errors;\r\n }\r\n }, [mutationAction]);\r\n\r\n return [action, { isExecuting: isExecuting, errors: error ? error.message : actionErrors }];\r\n}\r\n","import { useCallback, useMemo } from \"react\";\r\nimport { ModelArrayChanges } from \"../../../shared/useChanges\";\r\n\r\nexport type DisplayOrderReturnType = [\r\n Array,\r\n {\r\n moveUp: (id: string) => void,\r\n canMoveUp: (id: string) => boolean,\r\n moveDown: (id: string) => void,\r\n canMoveDown: (id: string) => boolean,\r\n }\r\n];\r\n\r\n/**\r\n * Custom hook to provide an ordered result as well as methods to manage the order of models that use a displayOrder field.\r\n * \r\n * If you only want to manage the display order of a filtered list of all items managed by the manager, pass a filterItems parameter to filter down to only the items you want.\r\n */\r\nexport function useDisplayOrder(managedItems: ModelArrayChanges, filterItems?: (item: T) => boolean)\r\n : DisplayOrderReturnType\r\n{\r\n // Order the items so they show in display order.\r\n const orderedItems = useMemo(() => {\r\n let ret = [...managedItems.model];\r\n\r\n // If we are to filter the items we manage, do so now.\r\n if (filterItems) {\r\n ret = ret.filter(filterItems);\r\n }\r\n\r\n ret.sort((a, b) => {\r\n if (a.displayOrder === b.displayOrder) {\r\n return 0;\r\n } else if (a.displayOrder > b.displayOrder) {\r\n return 1;\r\n } else {\r\n return -1;\r\n }\r\n });\r\n return ret;\r\n }, [managedItems.model, filterItems]);\r\n\r\n // Can we move this item up?\r\n const canMoveUp = useCallback((id: string) => {\r\n const item = orderedItems.find(it => it.id === id);\r\n if (!item) {\r\n return false;\r\n }\r\n\r\n const index = orderedItems.indexOf(item);\r\n if (index <= 0) {\r\n return false;\r\n }\r\n\r\n return true;\r\n }, [orderedItems]);\r\n\r\n // Can we move this item down?\r\n const canMoveDown = useCallback((id: string) => {\r\n const item = orderedItems.find(it => it.id === id);\r\n if (!item) {\r\n return false;\r\n }\r\n\r\n const index = orderedItems.indexOf(item);\r\n if (index >= orderedItems.length - 1) {\r\n return false;\r\n }\r\n\r\n return true;\r\n }, [orderedItems]);\r\n\r\n // Move an item up\r\n const moveUp = useCallback((id: string) => {\r\n const item = orderedItems.find(it => it.id === id);\r\n if (!item) {\r\n return false;\r\n }\r\n\r\n const index = orderedItems.indexOf(item);\r\n if (index <= 0) {\r\n return false;\r\n }\r\n\r\n const otherModel = orderedItems[index - 1];\r\n\r\n // Cope with the fact that sometimes we end up with multiple items withthe same display order when added in bulk (thanks to moment.unix() often being used to generate a display order).\r\n // Without this the reordering wouldn't happen for items that share a displayOrder.\r\n const newDisplayOrderMe = item.displayOrder === otherModel.displayOrder ? otherModel.displayOrder - 1 : otherModel.displayOrder;\r\n\r\n // Swap/update the display orders.\r\n managedItems.changeFor(item.id, { displayOrder: newDisplayOrderMe } as Partial);\r\n managedItems.changeFor(otherModel.id, { displayOrder: item.displayOrder } as Partial);\r\n }, [orderedItems, managedItems]);\r\n\r\n // Move an answer down in the order.\r\n const moveDown = useCallback((id: string) => {\r\n const item = orderedItems.find(it => it.id === id);\r\n if (!item) {\r\n return false;\r\n }\r\n\r\n const index = orderedItems.indexOf(item);\r\n if (index >= orderedItems.length - 1) {\r\n return false;\r\n }\r\n\r\n const otherModel = orderedItems[index + 1];\r\n\r\n // Cope with the fact that sometimes we end up with multiple items withthe same display order when added in bulk (thanks to moment.unix() often being used to generate a display order).\r\n // Without this the reordering wouldn't happen for items that share a displayOrder.\r\n const newDisplayOrderMe = item.displayOrder === otherModel.displayOrder ? otherModel.displayOrder +1 : otherModel.displayOrder;\r\n\r\n // Swap/update the display orders.\r\n\r\n managedItems.changeFor(item.id, { displayOrder: newDisplayOrderMe } as Partial);\r\n managedItems.changeFor(otherModel.id, { displayOrder: item.displayOrder } as Partial);\r\n }, [orderedItems, managedItems]);\r\n\r\n // Return everything in a format that is easy for people to grab the bits they want.\r\n const ret = useMemo((): DisplayOrderReturnType => ([\r\n orderedItems,\r\n {\r\n canMoveUp,\r\n moveUp,\r\n canMoveDown,\r\n moveDown,\r\n }\r\n ]), [orderedItems, canMoveUp, moveUp, canMoveDown, moveDown]);\r\n\r\n return ret;\r\n}","import { TFunction } from \"i18next\";\r\n\r\n/**\r\n * Question types\r\n */\r\nexport enum QuestionType {\r\n MultipleChoiceVideo = \"MultipleChoiceVideo\",\r\n SlidingScaleVideo = \"SlidingScaleVideo\",\r\n ResponseTimeVideo = \"ResponseTimeVideo\",\r\n LocationResponseImage = \"LocationResponseImage\",\r\n LocationDiscriminationImage = \"LocationDiscriminationImage\",\r\n MultipleChoiceImage = \"MultipleChoiceImage\",\r\n SequenceOfQuestions = \"SequenceOfQuestions\",\r\n Questionnaire = \"Questionnaire\",\r\n QuestionnaireInput = \"QuestionnaireInput\",\r\n QuestionnaireMultipleChoice = \"QuestionnaireMultipleChoice\",\r\n QuestionnaireScale = \"QuestionnaireScale\",\r\n LearningVideo = \"LearningVideo\",\r\n LearningImage = \"LearningImage\",\r\n LearningText = \"LearningText\",\r\n InformationVideo = \"InformationVideo\",\r\n InformationImage = \"InformationImage\",\r\n InformationText = \"InformationText\",\r\n}\r\n\r\n/**\r\n * Return translated display name for a question type.\r\n * @param t\r\n */\r\nexport function questionTypeDisplayName(type: QuestionType, t: TFunction): string {\r\n switch (type) {\r\n case QuestionType.MultipleChoiceVideo: return t('questionTypeDisplayName.MutlipleChoiceVideo', 'Multiple choice video');\r\n case QuestionType.SlidingScaleVideo: return t('questionTypeDisplayName.SlidingScaleVideo', 'Sliding scale video');\r\n case QuestionType.ResponseTimeVideo: return t('questionTypeDisplayName.ResponseTimeVideo', 'Response time video');\r\n case QuestionType.LocationResponseImage: return t('questionTypeDisplayName.LocationResponseImage', 'Location response');\r\n case QuestionType.LocationDiscriminationImage: return t('questionTypeDisplayName.LocationDiscriminationImage', 'Location discrimination');\r\n case QuestionType.MultipleChoiceImage: return t('questionTypeDisplayName.MultipleChoiceImage', 'Multiple choice picture');\r\n case QuestionType.Questionnaire: return t('questionTypeDisplayName.Questionnaire', 'Questionnaire');\r\n case QuestionType.QuestionnaireInput: return t('questionTypeDisplayName.QuestionnaireInput', 'Input');\r\n case QuestionType.QuestionnaireScale: return t('questionTypeDisplayName.QuestionnaireScale', 'Scale');\r\n case QuestionType.QuestionnaireMultipleChoice: return t('questionTypeDisplayName.QuestionnaireMultipleChoice', 'Multiple choice');\r\n case QuestionType.LearningVideo: return t('questionTypeDisplayName.LearningVideo', 'Video learning');\r\n case QuestionType.LearningImage: return t('questionTypeDisplayName.LearningImage', 'Image learning');\r\n case QuestionType.LearningText: return t('questionTypeDisplayName.LearningText', 'Textual learning');\r\n case QuestionType.SequenceOfQuestions: return t('questionTypeDisplayName.SequenceOfQuestions', 'Sequence of questions');\r\n case QuestionType.InformationVideo: return t('questionTypeDisplayName.InformationVideo', 'Video information');\r\n case QuestionType.InformationImage: return t('questionTypeDisplayName.InformationImage', 'Image information');\r\n case QuestionType.InformationText: return t('questionTypeDisplayName.InformationText', 'Textual information');\r\n }\r\n}\r\n\r\n/**\r\n * Broad categories that the question types are grouped into that is often useful to display or filter groups of questions together.\r\n */\r\nexport enum QuestionTypeCategory {\r\n Question = 'Question',\r\n Questionnaire = 'Questionnaire',\r\n QuestionnaireQuestion = 'QuesitonnaireQuestion',\r\n Learning = 'Learning',\r\n Informtion = 'Information',\r\n}\r\n\r\n/**\r\n * Return the QuestionTypeCategory that type belongs to.\r\n * @param type\r\n */\r\nexport function getQuestionTypeCategory(type: QuestionType): QuestionTypeCategory {\r\n switch (type) {\r\n case QuestionType.MultipleChoiceVideo: return QuestionTypeCategory.Question;\r\n case QuestionType.SlidingScaleVideo: return QuestionTypeCategory.Question;\r\n case QuestionType.ResponseTimeVideo: return QuestionTypeCategory.Question;\r\n case QuestionType.LocationResponseImage: return QuestionTypeCategory.Question;\r\n case QuestionType.LocationDiscriminationImage: return QuestionTypeCategory.Question;\r\n case QuestionType.MultipleChoiceImage: return QuestionTypeCategory.Question;\r\n case QuestionType.Questionnaire: return QuestionTypeCategory.Questionnaire;\r\n case QuestionType.QuestionnaireInput: return QuestionTypeCategory.QuestionnaireQuestion;\r\n case QuestionType.QuestionnaireScale: return QuestionTypeCategory.QuestionnaireQuestion;\r\n case QuestionType.QuestionnaireMultipleChoice: return QuestionTypeCategory.QuestionnaireQuestion;\r\n case QuestionType.LearningVideo: return QuestionTypeCategory.Learning;\r\n case QuestionType.LearningImage: return QuestionTypeCategory.Learning;\r\n case QuestionType.LearningText: return QuestionTypeCategory.Learning;\r\n case QuestionType.SequenceOfQuestions: return QuestionTypeCategory.Question;\r\n case QuestionType.InformationVideo: return QuestionTypeCategory.Informtion;\r\n case QuestionType.InformationImage: return QuestionTypeCategory.Informtion;\r\n case QuestionType.InformationText: return QuestionTypeCategory.Informtion;\r\n }\r\n}\r\n\r\n/**\r\n * Returns all question types for the given category.\r\n * @param category\r\n */\r\nexport function getQuestionTypes(category: QuestionTypeCategory): Array {\r\n let ret: Array = [];\r\n for (const type of Object.keys(QuestionType).map(item => item as QuestionType)) {\r\n if (getQuestionTypeCategory(type) === category) {\r\n ret.push(type);\r\n }\r\n }\r\n return ret;\r\n}","import { FontAwesomeIcon } from \"@fortawesome/react-fontawesome\";\r\nimport { ChangeEvent, useCallback, useRef, useState } from \"react\";\r\nimport { ConditionalFragment } from \"react-conditionalfragment\";\r\nimport { useTranslation } from \"react-i18next\";\r\nimport { Button, Input, InputGroup, InputGroupAddon, InputProps } from \"reactstrap\";\r\nimport { useToggleState } from \"use-toggle-state\";\r\n\r\nexport interface InputSelectOrTextProps extends InputProps {\r\n}\r\n\r\n/**\r\n * Input component that knows how to toggle itself between being a select and being a text input to add new items.\r\n * @param props\r\n */\r\nexport const InputSelectOrText = (props: InputSelectOrTextProps) => {\r\n const {\r\n onChange,\r\n children,\r\n ...rest\r\n } = props;\r\n\r\n const { t } = useTranslation();\r\n\r\n const [isTextMode, toggleTextMode] = useToggleState();\r\n const [text, setText] = useState('');\r\n const lastTextChangeEvent = useRef>();\r\n\r\n // Save the text entered in textMode (by raising the onChange event) and exist text mode.\r\n const saveText = useCallback(() => {\r\n // If we have an onChange event, call it now as if the text had been typed.\r\n if (onChange && lastTextChangeEvent.current) {\r\n onChange({\r\n ...lastTextChangeEvent.current,\r\n currentTarget: {\r\n ...(lastTextChangeEvent.current.currentTarget ?? {}),\r\n value: text,\r\n },\r\n });\r\n }\r\n\r\n // Toggle out of text mode.\r\n toggleTextMode();\r\n }, [toggleTextMode, onChange, lastTextChangeEvent, text]);\r\n\r\n return (\r\n \r\n \r\n \r\n {children}\r\n \r\n \r\n \r\n \r\n \r\n \r\n {\r\n setText(e.currentTarget.value);\r\n lastTextChangeEvent.current = { ...e };\r\n }}\r\n />\r\n \r\n \r\n \r\n \r\n \r\n \r\n );\r\n};","import { QuestionTag } from \"../../../api/main/models/QuestionTag\";\r\nimport { QuestionTagButton } from \"./QuestionTagButton\";\r\nimport \"./questionTagDisplay.scss\";\r\n\r\nexport interface QuestionTagDisplayProps {\r\n tags: Array,\r\n}\r\n\r\n/**\r\n * Display for toggling a question tag on or off.\r\n */\r\nexport const QuestionTagDisplay = (props: QuestionTagDisplayProps) => {\r\n const {\r\n tags,\r\n } = props;\r\n\r\n return (\r\n
\r\n {\r\n tags\r\n .map(item => (\r\n \r\n ))\r\n }\r\n
\r\n );\r\n};\r\n","import * as React from 'react';\r\nimport { useLazyQuery } from \"@apollo/react-hooks\";\r\nimport gql from \"graphql-tag\";\r\nimport { AsyncLoadPagedResult, AsyncLoadPagedOptions } from '../../../../shared/abstractStore';\r\nimport { useFetchMoreCallback } from '../../../../shared/useFetchMoreCallback';\r\nimport { questionsListViewModelQuery, questionsListViewModelQueryVariables } from '../../generated/questionsListViewModelQuery';\r\nimport { mainApiConfig } from '../../../../configure/mainApiConfig';\r\nimport { questionFieldsFragment } from '../../models/Question';\r\nimport { QuestionType } from '../../models/codeOnly/QuestionType';\r\nimport { questionTagFieldsFragment } from '../../models/QuestionTag';\r\nimport { questionTagLinkFieldsFragment } from '../../models/QuestionTagLink';\r\nimport { driverMetricFieldsFragment } from '../../models/DriverMetric';\r\n\r\nexport interface QuestionsAsyncLoadPageOptions extends AsyncLoadPagedOptions {\r\n questionTypes?: Array,\r\n}\r\n\r\n/**\r\n * Get a list of questions from the store with other details needed for the questions list.\r\n * @param id\r\n * @param options\r\n */\r\nexport function useQuestionsListViewModel(options: QuestionsAsyncLoadPageOptions = {}): AsyncLoadPagedResult {\r\n // Query data we need from the api.\r\n const [load, { data, loading, error, refetch, fetchMore: fetchMoreFromStore }] = useLazyQuery(\r\n gql`\r\n query questionsListViewModelQuery ($offset: Int, $first: Int, $questionTypes: [String!]) {\r\n items: questions (offset: $offset, first: $first, questionTypes: $questionTypes) {\r\n ...questionFields\r\n }\r\n\r\n tags: questionTags {\r\n ...questionTagFields\r\n }\r\n\r\n links: questionTagLinks (targetType: \"Question\") {\r\n ...questionTagLinkFields\r\n }\r\n\r\n driverMetrics {\r\n ...driverMetricFields\r\n }\r\n }\r\n\r\n ${questionFieldsFragment}\r\n ${questionTagFieldsFragment}\r\n ${questionTagLinkFieldsFragment}\r\n ${driverMetricFieldsFragment}\r\n `,\r\n {\r\n\r\n variables: {\r\n offset: options.startOffset,\r\n first: options.pageSize,\r\n questionTypes: options.questionTypes,\r\n },\r\n fetchPolicy: options.fetchPolicy ?? mainApiConfig.defaultFetchPolicy,\r\n pollInterval: options.pollInterval,\r\n onCompleted: (data) => {\r\n if (options.onCompleted) {\r\n options.onCompleted(data);\r\n }\r\n }\r\n }\r\n );\r\n\r\n // Run the query (unless we are being lazy).\r\n React.useEffect(() => {\r\n if (!options.lazy) {\r\n load();\r\n }\r\n }, [options.lazy, load])\r\n\r\n // Get the functions used to manage paging.\r\n const { fetchMore, hasMore: _hasMore } = useFetchMoreCallback(\r\n fetchMoreFromStore,\r\n (options?.startOffset ?? 0) + (data?.items?.length ?? 0),\r\n (prevResults, newResults) => ({\r\n ...prevResults,\r\n ...newResults,\r\n\r\n items: [...(prevResults?.items ?? []), ...(newResults?.items ?? [])],\r\n tags: newResults?.tags ?? [],\r\n links: newResults?.links ?? [],\r\n driverMetrics: newResults?.driverMetrics ?? [],\r\n }),\r\n (newResults) => newResults?.items?.length\r\n );\r\n const hasMore = React.useCallback(() => !options.pageSize ? false : _hasMore(), [options.pageSize, _hasMore]);\r\n \r\n // Return the results.\r\n const refresh = React.useCallback(async () => { !refetch ? await load() : await refetch(); }, [refetch, load]);\r\n return React.useMemo(() => ({\r\n data: data ?? ({} as any),\r\n refresh: refresh,\r\n isLoading: loading,\r\n errors: error,\r\n fetchMore: fetchMore,\r\n hasMore: hasMore,\r\n }), [data, refresh, loading, error, fetchMore, hasMore]);\r\n}\r\n","import './tagDisplay.scss';\r\n\r\nimport * as React from 'react';\r\n\r\nexport interface FormButtonsProps {\r\n className?: string,\r\n noPadding?: boolean,\r\n children: React.ReactNode\r\n}\r\n\r\n/**\r\n * Container for buttons (e.g. sumbit) at the bottom of a form. \r\n */\r\nexport const TagDisplay = (props: FormButtonsProps) => {\r\n const { className, children, noPadding = false } = props;\r\n\r\n return (\r\n
\r\n {children}\r\n
\r\n );\r\n};","import { FontAwesomeIcon } from \"@fortawesome/react-fontawesome\";\r\nimport { useCallback, useMemo, useState } from \"react\";\r\nimport { ConditionalFragment } from \"react-conditionalfragment\";\r\nimport { useTranslation } from \"react-i18next\";\r\nimport { Button, ButtonGroup, Col, Modal, ModalBody, ModalFooter, ModalHeader, ModalProps, Row, Table, Card, CardBody, Collapse, InputGroupAddon } from \"reactstrap\";\r\nimport { getQuestionTypeCategory, QuestionType, QuestionTypeCategory, questionTypeDisplayName } from \"../../../api/main/models/codeOnly/QuestionType\";\r\nimport { LoadingIndicator } from \"../../shared/LoadingIndicator\";\r\nimport { NoResultsFound } from \"../../shared/NoResultsFound\";\r\nimport { SearchInput } from \"../../shared/searchInput/SearchInput\";\r\nimport \"./selectQuestionModal.scss\";\r\nimport { QuestionTagDisplay } from \"../../questionTags/questionTagSelector/QuestionTagDisplay\";\r\nimport { useQuestionsListViewModel } from \"../../../api/main/questions/viewModels/useQuestionsListViewModel\";\r\nimport * as React from 'react';\r\nimport { TagDisplay } from \"../../shared/tagFilter/TagDisplay\";\r\nimport { useToggleState } from 'use-toggle-state';\r\n\r\nexport interface SelectQuestionModalCloseEventArgs {\r\n /**\r\n * All currently selected ids.\r\n * */\r\n selectedIds: Array,\r\n\r\n /**\r\n * Added Ids (those in selectedIds that were not in initialSelectedIds).\r\n */\r\n addedIds: Array,\r\n /**\r\n * Removed Ids (those in selectedIds that were not in initialSelectedIds).\r\n */\r\n removedIds: Array,\r\n\r\n\r\n cancelled: boolean,\r\n}\r\n\r\nexport interface SelectQuestionModalProps extends ModalProps {\r\n isOpen: boolean,\r\n toggle: () => void,\r\n isLoadingQuestions?: boolean,\r\n\r\n onClose: (event: SelectQuestionModalCloseEventArgs) => void,\r\n\r\n initialSelectedIds?: Array,\r\n\r\n questionTypeCategories?: Array,\r\n}\r\n\r\n/**\r\n * Modal that allows the user to select from a list of questions.\r\n * @param props\r\n */\r\nexport const SelectQuestionModal = (props: SelectQuestionModalProps) => {\r\n const {\r\n isOpen,\r\n toggle,\r\n\r\n isLoadingQuestions,\r\n onClose,\r\n questionTypeCategories = [],\r\n\r\n initialSelectedIds,\r\n } = props;\r\n const { t } = useTranslation();\r\n\r\n const isEdit = !!initialSelectedIds;\r\n const { data: {items: allItems, tags, links, driverMetrics } } = useQuestionsListViewModel({ pageSize: undefined });\r\n \r\n // Manage the questions that have been selected.\r\n const [selectedQuestions, setSelectedQuestions] = useState>(initialSelectedIds ?? []);\r\n const toggleSelection = useCallback((id: string) => {\r\n setSelectedQuestions(prevState => {\r\n const existing = prevState.find(it => it === id);\r\n if (existing) {\r\n return prevState.filter(it => it !== id);\r\n } else {\r\n return [\r\n ...prevState,\r\n id,\r\n ];\r\n }\r\n });\r\n }, [setSelectedQuestions]);\r\n const isSelected = useCallback((id: string) => !!selectedQuestions.find(it => it === id), [selectedQuestions]);\r\n\r\n // Close the modal and return the results.\r\n const closeModal = useCallback((event?: { selectedIds: Array, cancelled?: boolean, }) => {\r\n if (onClose) {\r\n const selectedIds = event?.selectedIds ?? selectedQuestions;\r\n\r\n const externalEvent: SelectQuestionModalCloseEventArgs = {\r\n ...(event ?? {}),\r\n\r\n selectedIds: selectedIds,\r\n cancelled: event?.cancelled ?? false,\r\n\r\n addedIds: event?.cancelled? []: selectedIds.filter(id => !initialSelectedIds?.find(it => it === id)),\r\n removedIds: event?.cancelled ? []: initialSelectedIds?.filter(id => !selectedIds.find(it => it === id)) ?? [],\r\n };\r\n onClose(externalEvent);\r\n }\r\n\r\n // Close the modal.\r\n toggle();\r\n }, [selectedQuestions, toggle, onClose, initialSelectedIds]);\r\n\r\n // Manage the toggling of tags on and off.\r\n const [selectedTags, setSelectedTags] = React.useState>([]);\r\n const toggleTagSelected = useCallback((tag: string) => {\r\n setSelectedTags(prevState => {\r\n const existing = prevState.find(it => it === tag);\r\n\r\n if (existing) {\r\n // If we are currently on, toggle to off.\r\n return prevState.filter(it => it !== tag);\r\n } else {\r\n // Add tag to the list of on toggles.\r\n return [...prevState, tag];\r\n }\r\n });\r\n }, [setSelectedTags]);\r\n const isTagSelected = React.useCallback((tag: string) => {\r\n // If no tags are selected, treat it as if all tags are selected.\r\n if (!selectedTags.length) {\r\n return true;\r\n }\r\n\r\n // Return true or false based on if this tag has been selected explictly.\r\n return selectedTags.find(it => it === tag);\r\n }, [selectedTags]);\r\n\r\n // Filtering the display between all and selected only.\r\n const [filter, setFilter] = useState<'all' | 'selected'>('all');\r\n\r\n // Filtering of questions.\r\n const [search, setSearch] = useState('');\r\n\r\n // Filter by the assessment's search client side so it can work when offline as well as online.\r\n const items = useMemo(() => {\r\n if (!allItems) {\r\n return allItems;\r\n }\r\n\r\n let ret = allItems;\r\n\r\n // Filter by selected tags if any tag filters have been selected.\r\n if (selectedTags.length) {\r\n ret = ret.filter(item => {\r\n // Get all questionFilterTags for this question.\r\n const myLinks = links.filter(link => link.targetId === item.id);\r\n\r\n for (const link of myLinks) {\r\n if (isTagSelected(link.questionTagId)) {\r\n return true;\r\n }\r\n }\r\n\r\n return false;\r\n });\r\n }\r\n\r\n\r\n // Filter by question type categories if any are provided.\r\n if (questionTypeCategories !== null && questionTypeCategories.length > 0) {\r\n ret = ret.filter(item => questionTypeCategories.filter(it => it === getQuestionTypeCategory(item.questionType as QuestionType)).length === 1);\r\n } else {\r\n // If we arent specifying a filter, only show specifically questions\r\n ret = ret.filter(item => getQuestionTypeCategory(item.questionType as QuestionType) === QuestionTypeCategory.Question);\r\n }\r\n\r\n // Filter by the selected filter.\r\n switch (filter) {\r\n case 'all':\r\n break;\r\n case 'selected': {\r\n ret = ret.filter(item => selectedQuestions.find(it => it === item.id));\r\n }\r\n }\r\n\r\n // Filter by the user's search text.\r\n let lowerSearch = search.toLocaleLowerCase();\r\n if (lowerSearch) {\r\n // Filter the items being displayed.\r\n ret = ret.filter(item => {\r\n // Get the primary driver metric.\r\n const driverMetricName = driverMetrics?.find(it => it.id === item.driverMetricId)?.name\r\n ?? t('questionsListBase.driverMetric.none', '(No primary safety metric)');\r\n\r\n // Get the tags that are linked to this item.\r\n const myTags = tags?.filter(tag => !!links?.find(it => it.questionTagId === tag.id && it.targetId === item.id)) ?? [];\r\n\r\n return (\r\n item.name.toLocaleLowerCase().indexOf(lowerSearch) >= 0\r\n || questionTypeDisplayName(item.questionType as QuestionType, t).toLocaleLowerCase().indexOf(lowerSearch) >= 0\r\n || !!myTags.find(tag => tag.name.toLocaleLowerCase().indexOf(lowerSearch) >= 0)\r\n || (driverMetricName ?? '').toLocaleLowerCase().indexOf(lowerSearch) >= 0\r\n );\r\n });\r\n }\r\n\r\n return ret;\r\n\r\n \r\n }, [allItems, search, filter, selectedQuestions, questionTypeCategories, links, tags, isTagSelected, selectedTags.length, driverMetrics, t]);\r\n\r\n //controls for filtering by tags\r\n const [isTagFilterOpen, toggleTagFilterOpen] = useToggleState(false);\r\n\r\n // UI\r\n //\r\n const colCount = 6;\r\n\r\n return (\r\n toggle()} size=\"xl\" className=\"select-question-modal\">\r\n toggle()}>\r\n {\r\n t('selectQuestionModal.heading.default', 'Select questions')\r\n }\r\n \r\n \r\n \r\n \r\n setSearch(e.currentTarget.value)}>\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n\r\n \r\n \r\n \r\n \r\n \r\n

\r\n {t('questionsListBase.selectTagsToFilter', 'Select tags to filter by:')}\r\n

\r\n \r\n \r\n \r\n {\r\n tags?.map(item => (\r\n \r\n ))\r\n }\r\n \r\n \r\n
\r\n
\r\n
\r\n
\r\n\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n {\r\n items?.map(item => {\r\n const itemIsSelected = isSelected(item.id);\r\n\r\n return (\r\n closeModal({ selectedIds: [...selectedQuestions.filter(it => it !== item.id), item.id] })}>\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n );\r\n })\r\n }\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n
 {t('selectQuestionModal.question', 'Question')}{t('selectQuestionModal.name', 'Name')}{t('selectQuestionModal.questionType', 'Question type')}{t('selectQuestionModal.safetyMetric', 'Safety metric')}{t('selectQuestionModal.tags', 'Tags')}
\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n
{item.name}
\r\n
{item.name}{questionTypeDisplayName(item.questionType as QuestionType, t)}{driverMetrics?.find(it => it.id === item.driverMetricId)?.name ?? t('selectQuestionModal.driverMetric.none', '(No primary safety metric)')}\r\n !!links?.find(it => it.questionTagId === tag.id && it.targetId === item.id)) ?? []}\r\n />\r\n
\r\n \r\n
\r\n
\r\n \r\n \r\n \r\n <> \r\n \r\n \r\n \r\n
\r\n );\r\n};","import { FontAwesomeIcon } from \"@fortawesome/react-fontawesome\";\r\nimport { useCallback, useMemo, useState } from \"react\";\r\nimport { ConditionalFragment } from \"react-conditionalfragment\";\r\nimport { useTranslation } from \"react-i18next\";\r\nimport { Button, ButtonGroup, Col, Modal, ModalBody, ModalFooter, ModalHeader, ModalProps, Row, Table, Card, CardBody, Collapse, InputGroupAddon } from \"reactstrap\";\r\nimport { getQuestionTypeCategory, QuestionType, QuestionTypeCategory } from \"../../../../api/main/models/codeOnly/QuestionType\";\r\nimport { LoadingIndicator } from \"../../../shared/LoadingIndicator\";\r\nimport { NoResultsFound } from \"../../../shared/NoResultsFound\";\r\nimport { SearchInput } from \"../../../shared/searchInput/SearchInput\";\r\nimport \"./selectQuestionnaireModal.scss\";\r\nimport { QuestionTagDisplay } from \"../../../questionTags/questionTagSelector/QuestionTagDisplay\";\r\nimport { useQuestionsListViewModel } from \"../../../../api/main/questions/viewModels/useQuestionsListViewModel\";\r\nimport * as React from 'react';\r\nimport { TagDisplay } from \"../../../shared/tagFilter/TagDisplay\";\r\nimport { useToggleState } from 'use-toggle-state';\r\n\r\nexport interface selectQuestionnaireModalCloseEventArgs {\r\n /**\r\n * All currently selected ids.\r\n * */\r\n selectedIds: Array,\r\n\r\n /**\r\n * Added Ids (those in selectedIds that were not in initialSelectedIds).\r\n */\r\n addedIds: Array,\r\n /**\r\n * Removed Ids (those in selectedIds that were not in initialSelectedIds).\r\n */\r\n removedIds: Array,\r\n\r\n\r\n cancelled: boolean,\r\n}\r\n\r\nexport interface selectQuestionnaireModalProps extends ModalProps {\r\n isOpen: boolean,\r\n toggle: () => void,\r\n isLoadingQuestions?: boolean,\r\n\r\n onClose: (event: selectQuestionnaireModalCloseEventArgs) => void,\r\n\r\n initialSelectedIds?: Array,\r\n\r\n questionTypeCategory?: QuestionTypeCategory,\r\n}\r\n\r\n/**\r\n * Modal that allows the user to select from a list of questions.\r\n * @param props\r\n */\r\nexport const SelectQuestionnaireModal = (props: selectQuestionnaireModalProps) => {\r\n const {\r\n isOpen,\r\n toggle,\r\n\r\n isLoadingQuestions,\r\n onClose,\r\n questionTypes,\r\n\r\n initialSelectedIds,\r\n } = props;\r\n\r\n const { t } = useTranslation();\r\n const questionTypeCategory = QuestionTypeCategory.Questionnaire;\r\n const isEdit = !!initialSelectedIds;\r\n const { data: { items: allItems, tags, links, driverMetrics } } = useQuestionsListViewModel({ pageSize: undefined, questionTypes: questionTypes, });\r\n \r\n // Manage the questions that have been selected.\r\n const [selectedQuestions, setSelectedQuestions] = useState>(initialSelectedIds ?? []);\r\n const toggleSelection = useCallback((id: string) => {\r\n setSelectedQuestions(prevState => {\r\n const existing = prevState.find(it => it === id);\r\n if (existing) {\r\n return prevState.filter(it => it !== id);\r\n } else {\r\n return [\r\n ...prevState,\r\n id,\r\n ];\r\n }\r\n });\r\n }, [setSelectedQuestions]);\r\n const isSelected = useCallback((id: string) => !!selectedQuestions.find(it => it === id), [selectedQuestions]);\r\n\r\n // Close the modal and return the results.\r\n const closeModal = useCallback((event?: { selectedIds: Array, cancelled?: boolean, }) => {\r\n if (onClose) {\r\n const selectedIds = event?.selectedIds ?? selectedQuestions;\r\n\r\n const externalEvent: selectQuestionnaireModalCloseEventArgs = {\r\n ...(event ?? {}),\r\n\r\n selectedIds: selectedIds,\r\n cancelled: event?.cancelled ?? false,\r\n\r\n addedIds: event?.cancelled? []: selectedIds.filter(id => !initialSelectedIds?.find(it => it === id)),\r\n removedIds: event?.cancelled ? []: initialSelectedIds?.filter(id => !selectedIds.find(it => it === id)) ?? [],\r\n };\r\n onClose(externalEvent);\r\n }\r\n\r\n // Close the modal.\r\n toggle();\r\n }, [selectedQuestions, toggle, onClose, initialSelectedIds]);\r\n\r\n // Manage the toggling of tags on and off.\r\n const [selectedTags, setSelectedTags] = React.useState>([]);\r\n const toggleTagSelected = useCallback((tag: string) => {\r\n setSelectedTags(prevState => {\r\n const existing = prevState.find(it => it === tag);\r\n\r\n if (existing) {\r\n // If we are currently on, toggle to off.\r\n return prevState.filter(it => it !== tag);\r\n } else {\r\n // Add tag to the list of on toggles.\r\n return [...prevState, tag];\r\n }\r\n });\r\n }, [setSelectedTags]);\r\n const isTagSelected = React.useCallback((tag: string) => {\r\n // If no tags are selected, treat it as if all tags are selected.\r\n if (!selectedTags.length) {\r\n return true;\r\n }\r\n\r\n // Return true or false based on if this tag has been selected explictly.\r\n return selectedTags.find(it => it === tag);\r\n }, [selectedTags]);\r\n\r\n // Filtering the display between all and selected only.\r\n const [filter, setFilter] = useState<'all' | 'selected'>('all');\r\n\r\n // Filtering of questions.\r\n const [search, setSearch] = useState('');\r\n\r\n // Filter by the assessment's search client side so it can work when offline as well as online.\r\n const items = useMemo(() => {\r\n if (!allItems) {\r\n return allItems;\r\n }\r\n\r\n let ret = allItems;\r\n\r\n // Filter by selected tags if any tag filters have been selected.\r\n if (selectedTags.length) {\r\n ret = ret.filter(item => {\r\n // Get all questionFilterTags for this question.\r\n const myLinks = links.filter(link => link.targetId === item.id);\r\n\r\n for (const link of myLinks) {\r\n if (isTagSelected(link.questionTagId)) {\r\n return true;\r\n }\r\n }\r\n\r\n return false;\r\n });\r\n }\r\n\r\n\r\n // Filter by the QuestionTypeCategory if one is provided.\r\n if (questionTypeCategory) {\r\n ret = ret.filter(item => getQuestionTypeCategory(item.questionType as QuestionType) === questionTypeCategory);\r\n }\r\n\r\n // Filter by the selected filter.\r\n switch (filter) {\r\n case 'all':\r\n break;\r\n case 'selected': {\r\n ret = ret.filter(item => selectedQuestions.find(it => it === item.id));\r\n }\r\n }\r\n\r\n // Filter by the user's search text.\r\n let lowerSearch = search.toLocaleLowerCase();\r\n if (lowerSearch) {\r\n // Filter the items being displayed.\r\n ret = ret.filter(item => {\r\n // Get the primary driver metric.\r\n const driverMetricName = driverMetrics?.find(it => it.id === item.driverMetricId)?.name\r\n ?? t('questionsListBase.driverMetric.none', '(No primary safety metric)');\r\n\r\n // Get the tags that are linked to this item.\r\n const myTags = tags?.filter(tag => !!links?.find(it => it.questionTagId === tag.id && it.targetId === item.id)) ?? [];\r\n\r\n return (\r\n item.name.toLocaleLowerCase().indexOf(lowerSearch) >= 0\r\n //|| questionTypeDisplayName(item.questionType as QuestionType, t).toLocaleLowerCase().indexOf(lowerSearch) >= 0\r\n || !!myTags.find(tag => tag.name.toLocaleLowerCase().indexOf(lowerSearch) >= 0)\r\n || (driverMetricName ?? '').toLocaleLowerCase().indexOf(lowerSearch) >= 0\r\n );\r\n });\r\n }\r\n\r\n return ret;\r\n\r\n\r\n }, [allItems, search, filter, selectedQuestions, questionTypeCategory, links, tags, isTagSelected, selectedTags.length, driverMetrics, t]);\r\n\r\n //controls for filtering by tags\r\n const [isTagFilterOpen, toggleTagFilterOpen] = useToggleState(false);\r\n\r\n // UI\r\n //\r\n const colCount = 5;\r\n\r\n return (\r\n toggle()} size=\"xl\" className=\"select-questionnaire-modal\">\r\n toggle()}>\r\n {\r\n t('selectQuestionnaireModal.heading.questionnaire', 'Select questionnaires')\r\n }\r\n \r\n \r\n \r\n \r\n setSearch(e.currentTarget.value)}>\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n\r\n \r\n \r\n \r\n \r\n \r\n

\r\n {t('questionsListBase.selectTagsToFilter', 'Select tags to filter by:')}\r\n

\r\n \r\n \r\n \r\n {\r\n tags?.map(item => (\r\n \r\n ))\r\n }\r\n \r\n \r\n
\r\n
\r\n
\r\n
\r\n\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n {\r\n items?.map(item => {\r\n const itemIsSelected = isSelected(item.id);\r\n\r\n return (\r\n closeModal({ selectedIds: [...selectedQuestions.filter(it => it !== item.id), item.id] })}>\r\n \r\n \r\n \r\n {/*}*/}\r\n \r\n \r\n \r\n );\r\n })\r\n }\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n
 {t('administratorsQuestionList.question', 'Question')}{t('administratorsQuestionList.name', 'Name')}{t('administratorsQuestionList.safetyMetric', 'Safety metric')}{t('administratorsQuestionList.tags', 'Tags')}
\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n
{item.name}
\r\n
{item.name}{questionTypeDisplayName(item.questionType as QuestionType, t)}{driverMetrics?.find(it => it.id === item.driverMetricId)?.name ?? t('selectQuestionnaireModal.driverMetric.none', '(No primary safety metric)')}\r\n !!links?.find(it => it.questionTagId === tag.id && it.targetId === item.id)) ?? []}\r\n />\r\n
\r\n \r\n
\r\n
\r\n \r\n \r\n \r\n <> \r\n \r\n \r\n \r\n
\r\n );\r\n};","import { FontAwesomeIcon } from \"@fortawesome/react-fontawesome\";\r\nimport { useCallback, useMemo, useState } from \"react\";\r\nimport { ConditionalFragment } from \"react-conditionalfragment\";\r\nimport { useTranslation } from \"react-i18next\";\r\nimport { Button, ButtonGroup, Col, Modal, ModalBody, ModalFooter, ModalHeader, ModalProps, Row, Table, Card, CardBody, Collapse, InputGroupAddon } from \"reactstrap\";\r\nimport { getQuestionTypeCategory, QuestionType, QuestionTypeCategory, questionTypeDisplayName } from \"../../../../api/main/models/codeOnly/QuestionType\";\r\nimport { LoadingIndicator } from \"../../../shared/LoadingIndicator\";\r\nimport { NoResultsFound } from \"../../../shared/NoResultsFound\";\r\nimport { SearchInput } from \"../../../shared/searchInput/SearchInput\";\r\nimport \"./selectLearningModal.scss\";\r\nimport { QuestionTagDisplay } from \"../../../questionTags/questionTagSelector/QuestionTagDisplay\";\r\nimport { useQuestionsListViewModel } from \"../../../../api/main/questions/viewModels/useQuestionsListViewModel\";\r\nimport * as React from 'react';\r\nimport { TagDisplay } from \"../../../shared/tagFilter/TagDisplay\";\r\nimport { useToggleState } from 'use-toggle-state';\r\n\r\nexport interface selectLearningModalCloseEventArgs {\r\n /**\r\n * All currently selected ids.\r\n * */\r\n selectedIds: Array,\r\n\r\n /**\r\n * Added Ids (those in selectedIds that were not in initialSelectedIds).\r\n */\r\n addedIds: Array,\r\n /**\r\n * Removed Ids (those in selectedIds that were not in initialSelectedIds).\r\n */\r\n removedIds: Array,\r\n\r\n\r\n cancelled: boolean,\r\n}\r\n\r\nexport interface selectLearningModalProps extends ModalProps {\r\n isOpen: boolean,\r\n toggle: () => void,\r\n isLoadingQuestions?: boolean,\r\n\r\n onClose: (event: selectLearningModalCloseEventArgs) => void,\r\n\r\n initialSelectedIds?: Array,\r\n\r\n questionTypeCategory?: QuestionTypeCategory,\r\n}\r\n\r\n/**\r\n * Modal that allows the user to select from a list of questions.\r\n * @param props\r\n */\r\nexport const SelectLearningModal = (props: selectLearningModalProps) => {\r\n const {\r\n isOpen,\r\n toggle,\r\n\r\n isLoadingQuestions,\r\n onClose,\r\n questionTypes,\r\n\r\n initialSelectedIds,\r\n } = props;\r\n\r\n const { t } = useTranslation();\r\n const questionTypeCategory = QuestionTypeCategory.Learning;\r\n const isEdit = !!initialSelectedIds;\r\n const { data: { items: allItems, tags, links, driverMetrics } } = useQuestionsListViewModel({ pageSize: undefined, questionTypes: questionTypes, });\r\n \r\n // Manage the questions that have been selected.\r\n const [selectedQuestions, setSelectedQuestions] = useState>(initialSelectedIds ?? []);\r\n const toggleSelection = useCallback((id: string) => {\r\n setSelectedQuestions(prevState => {\r\n const existing = prevState.find(it => it === id);\r\n if (existing) {\r\n return prevState.filter(it => it !== id);\r\n } else {\r\n return [\r\n ...prevState,\r\n id,\r\n ];\r\n }\r\n });\r\n }, [setSelectedQuestions]);\r\n const isSelected = useCallback((id: string) => !!selectedQuestions.find(it => it === id), [selectedQuestions]);\r\n\r\n // Close the modal and return the results.\r\n const closeModal = useCallback((event?: { selectedIds: Array, cancelled?: boolean, }) => {\r\n if (onClose) {\r\n const selectedIds = event?.selectedIds ?? selectedQuestions;\r\n\r\n const externalEvent: selectLearningModalCloseEventArgs = {\r\n ...(event ?? {}),\r\n\r\n selectedIds: selectedIds,\r\n cancelled: event?.cancelled ?? false,\r\n\r\n addedIds: event?.cancelled? []: selectedIds.filter(id => !initialSelectedIds?.find(it => it === id)),\r\n removedIds: event?.cancelled ? []: initialSelectedIds?.filter(id => !selectedIds.find(it => it === id)) ?? [],\r\n };\r\n onClose(externalEvent);\r\n }\r\n\r\n // Close the modal.\r\n toggle();\r\n }, [selectedQuestions, toggle, onClose, initialSelectedIds]);\r\n\r\n // Manage the toggling of tags on and off.\r\n const [selectedTags, setSelectedTags] = React.useState>([]);\r\n const toggleTagSelected = useCallback((tag: string) => {\r\n setSelectedTags(prevState => {\r\n const existing = prevState.find(it => it === tag);\r\n\r\n if (existing) {\r\n // If we are currently on, toggle to off.\r\n return prevState.filter(it => it !== tag);\r\n } else {\r\n // Add tag to the list of on toggles.\r\n return [...prevState, tag];\r\n }\r\n });\r\n }, [setSelectedTags]);\r\n const isTagSelected = React.useCallback((tag: string) => {\r\n // If no tags are selected, treat it as if all tags are selected.\r\n if (!selectedTags.length) {\r\n return true;\r\n }\r\n\r\n // Return true or false based on if this tag has been selected explictly.\r\n return selectedTags.find(it => it === tag);\r\n }, [selectedTags]);\r\n\r\n // Filtering the display between all and selected only.\r\n const [filter, setFilter] = useState<'all' | 'selected'>('all');\r\n\r\n // Filtering of questions.\r\n const [search, setSearch] = useState('');\r\n\r\n // Filter by the assessment's search client side so it can work when offline as well as online.\r\n const items = useMemo(() => {\r\n if (!allItems) {\r\n return allItems;\r\n }\r\n\r\n let ret = allItems;\r\n\r\n // Filter by selected tags if any tag filters have been selected.\r\n if (selectedTags.length) {\r\n ret = ret.filter(item => {\r\n // Get all questionFilterTags for this question.\r\n const myLinks = links.filter(link => link.targetId === item.id);\r\n\r\n for (const link of myLinks) {\r\n if (isTagSelected(link.questionTagId)) {\r\n return true;\r\n }\r\n }\r\n\r\n return false;\r\n });\r\n }\r\n\r\n // Filter by the QuestionTypeCategory if one is provided.\r\n if (questionTypeCategory) {\r\n ret = ret.filter(item => getQuestionTypeCategory(item.questionType as QuestionType) === questionTypeCategory);\r\n }\r\n\r\n // Filter by the selected filter.\r\n switch (filter) {\r\n case 'all':\r\n break;\r\n case 'selected': {\r\n ret = ret.filter(item => selectedQuestions.find(it => it === item.id));\r\n }\r\n }\r\n\r\n // Filter by the user's search text.\r\n let lowerSearch = search.toLocaleLowerCase();\r\n if (lowerSearch) {\r\n // Filter the items being displayed.\r\n ret = ret.filter(item => {\r\n // Get the primary driver metric.\r\n const driverMetricName = driverMetrics?.find(it => it.id === item.driverMetricId)?.name\r\n ?? t('questionsListBase.driverMetric.none', '(No primary safety metric)');\r\n\r\n // Get the tags that are linked to this item.\r\n const myTags = tags?.filter(tag => !!links?.find(it => it.questionTagId === tag.id && it.targetId === item.id)) ?? [];\r\n\r\n return (\r\n item.name.toLocaleLowerCase().indexOf(lowerSearch) >= 0\r\n || questionTypeDisplayName(item.questionType as QuestionType, t).toLocaleLowerCase().indexOf(lowerSearch) >= 0\r\n || !!myTags.find(tag => tag.name.toLocaleLowerCase().indexOf(lowerSearch) >= 0)\r\n || (driverMetricName ?? '').toLocaleLowerCase().indexOf(lowerSearch) >= 0\r\n );\r\n });\r\n }\r\n\r\n return ret;\r\n\r\n\r\n }, [allItems, search, filter, selectedQuestions, questionTypeCategory, links, tags, isTagSelected, selectedTags.length, driverMetrics, t]);\r\n\r\n //controls for filtering by tags\r\n const [isTagFilterOpen, toggleTagFilterOpen] = useToggleState(false);\r\n\r\n // UI\r\n //\r\n const colCount = 6;\r\n\r\n return (\r\n toggle()} size=\"xl\" className=\"select-learning-modal\">\r\n toggle()}>\r\n {\r\n t('selectLearningModal.heading.questionnaire', 'Select learning')\r\n }\r\n \r\n \r\n \r\n \r\n setSearch(e.currentTarget.value)}>\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n\r\n \r\n \r\n \r\n \r\n \r\n

\r\n {t('questionsListBase.selectTagsToFilter', 'Select tags to filter by:')}\r\n

\r\n \r\n \r\n \r\n {\r\n tags?.map(item => (\r\n \r\n ))\r\n }\r\n \r\n \r\n
\r\n
\r\n
\r\n
\r\n\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n {\r\n items?.map(item => {\r\n const itemIsSelected = isSelected(item.id);\r\n\r\n return (\r\n closeModal({ selectedIds: [...selectedQuestions.filter(it => it !== item.id), item.id] })}>\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n );\r\n })\r\n }\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n
 {t('selectLearningModal.question', 'Question')}{t('selectLearningModal.name', 'Name')}{t('selectLearningModal.questionType', 'Learning type')}{t('selectLearningModal.tags', 'Tags')}
\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n
{item.name}
\r\n
{item.name}{questionTypeDisplayName(item.questionType as QuestionType, t)}{t('selectLearningModal.safetyMetric', 'Safety metric')}\r\n !!links?.find(it => it.questionTagId === tag.id && it.targetId === item.id)) ?? []}\r\n />\r\n
\r\n \r\n
\r\n
\r\n \r\n \r\n \r\n <> \r\n \r\n \r\n \r\n
\r\n );\r\n};","import { FontAwesomeIcon } from \"@fortawesome/react-fontawesome\";\r\nimport { ValidationErrors } from \"pojo-validator\";\r\nimport { ValidateCallback } from \"pojo-validator-react\";\r\nimport { ValidatedInput } from \"pojo-validator-reactstrap\";\r\nimport { useTranslation } from \"react-i18next\";\r\nimport { Button, ButtonGroup, Card, FormGroup } from \"reactstrap\";\r\nimport { DriverMetric } from \"../../../../api/main/models/DriverMetric\";\r\nimport { AssessmentItemDriverMetricQuantity } from \"../../../../api/main/models/AssessmentItemDriverMetricQuantity\";\r\nimport { FormButtons } from \"../../../shared/FormButtons\";\r\n\r\nexport interface AssessmentItemDriverMetricDisplayQuantityRuleComponentProps {\r\n model: AssessmentItemDriverMetricQuantity | undefined,\r\n change: (changes: Partial) => void,\r\n remove: () => void,\r\n\r\n validate: ValidateCallback,\r\n validationErrors: ValidationErrors,\r\n\r\n driverMetrics: Array,\r\n}\r\n\r\n/**\r\n * Component for Assessment Item Safety Metric Display Quantity Rule for questions.\r\n * @param props\r\n */\r\nexport const AssessmentItemDriverMetricDisplayQuantityRuleComponent = (props: AssessmentItemDriverMetricDisplayQuantityRuleComponentProps) => {\r\n const {\r\n model,\r\n change,\r\n remove,\r\n validate,\r\n validationErrors,\r\n driverMetrics,\r\n } = props;\r\n\r\n const { t } = useTranslation();\r\n\r\n return (\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n
\r\n {t('AssessmentItemDriverMetricDisplayQuantityRuleComponent.beforeQuantity', 'Show')}\r\n <> \r\n change({ quantity: e.currentTarget.valueAsNumber })} onBlur={() => validate('quantity')} validationErrors={validationErrors['quantity']} />\r\n <> \r\n {t('AssessmentItemDriverMetricDisplayQuantityRuleComponent.beforeMetric', 'questions with the safety metric')}\r\n <> \r\n change({ driverMetricId: e.currentTarget.value })} onBlur={() => validate('driverMetricId')} validationErrors={validationErrors['driverMetricId']}>\r\n \r\n {\r\n driverMetrics.map(item => (\r\n \r\n ))\r\n }\r\n \r\n\r\n
\r\n
\r\n
\r\n );\r\n};","import { FontAwesomeIcon } from \"@fortawesome/react-fontawesome\";\r\nimport { useTranslation } from \"react-i18next\";\r\nimport { Button, ButtonGroup, Card, CardBody, Col, Collapse, FormGroup, Label, ListGroup, ListGroupItem, Row,} from \"reactstrap\";\r\nimport { Question } from \"../../../../api/main/models/Question\";\r\nimport { AssessmentItem } from \"../../../../api/main/models/AssessmentItem\";\r\nimport { FormButtons } from \"../../../shared/FormButtons\";\r\nimport { AssessmentItemQuestion, assessmentItemQuestionDefaultValues } from \"../../../../api/main/models/AssessmentItemQuestion\";\r\nimport { getQuestionTypeCategory, QuestionType, QuestionTypeCategory, questionTypeDisplayName } from \"../../../../api/main/models/codeOnly/QuestionType\";\r\nimport { ValidatedInput } from \"pojo-validator-reactstrap\";\r\nimport { ValidateCallback } from \"pojo-validator-react\";\r\nimport { ValidationErrors } from \"pojo-validator\";\r\nimport { CardHeaderCollapse } from \"../../../shared/cardHeaderCollapse/CardHeaderCollapse\";\r\nimport { useToggleState } from \"use-toggle-state\";\r\nimport { useCallback, useMemo } from \"react\";\r\nimport { ConditionalFragment } from \"react-conditionalfragment\";\r\nimport { InputSelectOrText } from \"../../../shared/inputSelectOrText/InputSelectOrText\";\r\nimport { SelectQuestionModal } from \"../../../questions/selectQuestionModal/SelectQuestionModal\";\r\nimport { ModelArrayChanges } from \"../../../../shared/useChanges\";\r\nimport { NoResultsFound } from \"../../../shared/NoResultsFound\";\r\nimport { Link } from \"react-router-dom\";\r\nimport { SelectQuestionnaireModal } from \"../../../questions/questionnaires/SelectQuestionnaireModal/SelectQuestionnaireModal\";\r\nimport { SelectLearningModal } from \"../../../questions/learning/SelectLearningModal/SelectLearningModal\";\r\nimport { AssessmentItemDriverMetricQuantity, assessmentItemDriverMetricQuantityDefaultValues } from \"../../../../api/main/models/AssessmentItemDriverMetricQuantity\";\r\nimport { AssessmentItemDriverMetricDisplayQuantityRuleComponent } from \"./assessmentItemDriverMetricDisplayQuantityRuleComponent\";\r\nimport { DriverMetric } from \"../../../../api/main/models/DriverMetric\";\r\n\r\nexport interface AssessmentItemComponentProps {\r\n model: AssessmentItem,\r\n change: (changes: Partial) => void,\r\n remove: () => void,\r\n moveUp: () => void,\r\n canMoveUp: boolean,\r\n moveDown: () => void,\r\n canMoveDown: boolean,\r\n\r\n assessmentItemQuestions: Array,\r\n allQuestions: Array,\r\n assessmentItemQuestionsManager: ModelArrayChanges,\r\n assessmentItemDriverMetricQuantitiesManager: ModelArrayChanges,\r\n\r\n validate: ValidateCallback,\r\n validationErrors: ValidationErrors,\r\n\r\n validateAssessmentItemDriverMetricQuantity: (model: AssessmentItemDriverMetricQuantity) => boolean,\r\n assessmentItemDriverMetricQuantityErrors: (id: string) => ValidationErrors,\r\n\r\n isOpenInitially?: boolean,\r\n\r\n counterbalanceGroups: Array,\r\n\r\n driverMetrics: Array,\r\n}\r\n\r\n/**\r\n * A question that forms part of the AssessmentItem.\r\n * @param props\r\n */\r\nexport const AssessmentItemComponent = (props: AssessmentItemComponentProps) => {\r\n const {\r\n model,\r\n change,\r\n remove,\r\n moveUp,\r\n canMoveUp,\r\n moveDown,\r\n canMoveDown,\r\n\r\n assessmentItemQuestions,\r\n allQuestions,\r\n assessmentItemQuestionsManager,\r\n assessmentItemDriverMetricQuantitiesManager,\r\n\r\n validate,\r\n validationErrors,\r\n\r\n validateAssessmentItemDriverMetricQuantity,\r\n assessmentItemDriverMetricQuantityErrors,\r\n\r\n isOpenInitially = false,\r\n\r\n counterbalanceGroups,\r\n\r\n driverMetrics,\r\n } = props;\r\n\r\n const { t } = useTranslation();\r\n\r\n const currentItemDisplayRules = useMemo(() => {\r\n return assessmentItemDriverMetricQuantitiesManager.model.filter(item => item.assessmentItemId === model.id)\r\n }, [assessmentItemDriverMetricQuantitiesManager, model]);\r\n\r\n // Self management of if we are expanded or not.\r\n const [isOpen, toggleOpen] = useToggleState(isOpenInitially);\r\n\r\n // Work out what category of question we're working with, as we want to be conistant to that type.\r\n const activeQuestionTypeCategory = useMemo(() => {\r\n let ret: QuestionTypeCategory = QuestionTypeCategory.Question;\r\n\r\n // If we have no questions selected, return the default and give up.\r\n if (!assessmentItemQuestions.length) {\r\n return ret;\r\n }\r\n\r\n // If we have a question selected, lets load it and get its type.\r\n const assessmentItemQuestion = assessmentItemQuestions[0];\r\n const question = allQuestions.find(item => item.id === assessmentItemQuestion.questionId);\r\n if (!question) {\r\n return ret;\r\n }\r\n\r\n ret = getQuestionTypeCategory(question.questionType as QuestionType);\r\n\r\n return ret;\r\n }, [assessmentItemQuestions, allQuestions]);\r\n\r\n const addAssessmentItemDriverMetricQuantity = useCallback(() => {\r\n assessmentItemDriverMetricQuantitiesManager.addFor({\r\n ...assessmentItemDriverMetricQuantityDefaultValues(),\r\n assessmentItemId: model.id\r\n })\r\n\r\n }, [assessmentItemDriverMetricQuantitiesManager, model]);\r\n\r\n // Generate a heading for the assessment item.\r\n const { headingText, subheadingText } = useMemo(() => {\r\n let headingText = '';\r\n let subheadingText = '';\r\n\r\n let totalQuantity: number = 0;\r\n // Check if we need to count all the quantities\r\n if (currentItemDisplayRules.length >= 1) {\r\n\r\n // Total up all quantities for the current item to show the correct amount for total to ask in pool\r\n \r\n currentItemDisplayRules.forEach(item => {\r\n\r\n if (item.quantity == null || Number.isNaN(item.quantity)) {\r\n // We dont want to add the quantity if its null\r\n return;\r\n }\r\n // Add the quantity to total\r\n totalQuantity = totalQuantity + item.quantity\r\n });\r\n\r\n // Set numberOfQuestionsToPresent to be the total we calculated\r\n model.numberOfQuestionsToPresent = totalQuantity;\r\n }\r\n\r\n switch (assessmentItemQuestions.length) {\r\n case 0:\r\n headingText =\r\n activeQuestionTypeCategory === QuestionTypeCategory.Learning ? t('assessmentItemComponent.headingText.none.headingText.learning', 'No learning activities selected.')\r\n : activeQuestionTypeCategory === QuestionTypeCategory.Questionnaire ? t('assessmentItemComponent.headingText.none.headingText.questionnaire', 'No questionnaires activities selected.')\r\n : t('assessmentItemComponent.headingText.none.headingText.default', 'No questions selected.');\r\n break;\r\n case 1:\r\n const question = allQuestions.find(it => it.id === assessmentItemQuestions[0].questionId);\r\n headingText = question?.name ?? '';\r\n subheadingText = questionTypeDisplayName(question?.questionType as QuestionType, t);\r\n break;\r\n default:\r\n headingText =\r\n activeQuestionTypeCategory === QuestionTypeCategory.Learning ? t('assessmentItemComponent.headingText.moreThanOne.headingText.learning', 'Present {{count}} activities out of a pool of {{poolCount}} learning activities', { count: model?.numberOfQuestionsToPresent ?? 1, poolCount: assessmentItemQuestions.length})\r\n : activeQuestionTypeCategory === QuestionTypeCategory.Questionnaire ? t('assessmentItemComponent.headingText.moreThanOne.headingText.questionnaires', 'Present {{count}} questionnaires out of a pool of {{poolCount}} questionnaires', { count: model?.numberOfQuestionsToPresent ?? 1, poolCount: assessmentItemQuestions.length})\r\n : t('assessmentItemComponent.headingText.moreThanOne.headingText.default', 'Ask {{count}} questions out of a pool of {{poolCount}} questions', { count: (model?.numberOfQuestionsToPresent ?? totalQuantity) ?? 1, poolCount: assessmentItemQuestions.length });\r\n let questionNames = '';\r\n const maxQuestionNamesToShow = 3;\r\n for (let i = 0; i < maxQuestionNamesToShow && i < assessmentItemQuestions.length; ++i) {\r\n const question = allQuestions.find(it => it.id === assessmentItemQuestions[i].questionId);\r\n \r\n if (!questionNames) {\r\n questionNames = question?.name ?? '';\r\n } else {\r\n questionNames += `, ${question?.name ?? ''}`;\r\n }\r\n }\r\n\r\n if (assessmentItemQuestions.length <= maxQuestionNamesToShow) {\r\n subheadingText = questionNames;\r\n } else {\r\n subheadingText =\r\n activeQuestionTypeCategory === QuestionTypeCategory.Learning ? t('assessmentItemComponent.headingText.moreThanOne.subheadingText.someNames.learning', '{{questionNames}}, and {{count}} more learning activities.', { questionNames, count: (assessmentItemQuestions.length - maxQuestionNamesToShow) })\r\n : activeQuestionTypeCategory === QuestionTypeCategory.Questionnaire ? t('assessmentItemComponent.headingText.moreThanOne.subheadingText.someNames.questionnaire', '{{questionNames}}, and {{count}} more questionnaires.', { questionNames, count: (assessmentItemQuestions.length - maxQuestionNamesToShow) })\r\n : t('assessmentItemComponent.headingText.moreThanOne.subheadingText.someNames.default', '{{questionNames}}, and {{count}} more questions.', { questionNames, count: (assessmentItemQuestions.length - maxQuestionNamesToShow) });\r\n }\r\n }\r\n\r\n return {\r\n headingText,\r\n subheadingText,\r\n };\r\n }, [t, model, assessmentItemQuestions, allQuestions, activeQuestionTypeCategory, currentItemDisplayRules]);\r\n\r\n\r\n // Showing of the question modal.\r\n const [questionModalIsOpen, toggleQuestionModal] = useToggleState();\r\n const[questionnaireModalIsOpen, toggleQuestionnaireModal] = useToggleState();\r\n const[learningModalIsOpen, toggleLearningModal] = useToggleState();\r\n\r\n // Adding of questions selected in the modal\r\n const onQuestionModalClosed = useCallback((event: { addedIds: Array, removedIds: Array }) => {\r\n // Add any new questions that were selected.\r\n for (const selectedId of event.addedIds) {\r\n assessmentItemQuestionsManager.addFor({\r\n ...assessmentItemQuestionDefaultValues(),\r\n\r\n assessmentId: model?.assessmentId,\r\n assessmentItemId: model?.id,\r\n questionId: selectedId,\r\n });\r\n }\r\n\r\n\r\n // Remove any previously selected questions that have been unselected.\r\n for (const unselectedId of event.removedIds) {\r\n const existing = assessmentItemQuestionsManager.model.find(it => it.assessmentItemId === model?.id && it.questionId === unselectedId);\r\n if (!existing) {\r\n continue;\r\n }\r\n\r\n assessmentItemQuestionsManager.removeFor(existing.id);\r\n }\r\n }, [assessmentItemQuestionsManager, model]);\r\n\r\n const onQuestionnaireModalClosed = useCallback((event: { addedIds: Array, removedIds: Array }) => {\r\n // Add any new questions that were selected.\r\n for (const selectedId of event.addedIds) {\r\n assessmentItemQuestionsManager.addFor({\r\n ...assessmentItemQuestionDefaultValues(),\r\n\r\n assessmentId: model?.assessmentId,\r\n assessmentItemId: model?.id,\r\n questionId: selectedId,\r\n });\r\n }\r\n\r\n\r\n // Remove any previously selected questions that have been unselected.\r\n for (const unselectedId of event.removedIds) {\r\n const existing = assessmentItemQuestionsManager.model.find(it => it.assessmentItemId === model?.id && it.questionId === unselectedId);\r\n if (!existing) {\r\n continue;\r\n }\r\n\r\n assessmentItemQuestionsManager.removeFor(existing.id);\r\n }\r\n }, [assessmentItemQuestionsManager, model]);\r\n\r\n const onLearningModalClosed = useCallback((event: { addedIds: Array, removedIds: Array }) => {\r\n // Add any new questions that were selected.\r\n for (const selectedId of event.addedIds) {\r\n assessmentItemQuestionsManager.addFor({\r\n ...assessmentItemQuestionDefaultValues(),\r\n\r\n assessmentId: model?.assessmentId,\r\n assessmentItemId: model?.id,\r\n questionId: selectedId,\r\n });\r\n }\r\n\r\n\r\n // Remove any previously selected questions that have been unselected.\r\n for (const unselectedId of event.removedIds) {\r\n const existing = assessmentItemQuestionsManager.model.find(it => it.assessmentItemId === model?.id && it.questionId === unselectedId);\r\n if (!existing) {\r\n continue;\r\n }\r\n\r\n assessmentItemQuestionsManager.removeFor(existing.id);\r\n }\r\n }, [assessmentItemQuestionsManager, model]);\r\n\r\n const RemoveBoth = useCallback(() => {\r\n // We need to remove the itemQuestion as well as item as we cannot save an ItemQuestion for an item that isnt in the list.\r\n\r\n const existing = assessmentItemQuestionsManager.model.find(it => it.assessmentItemId === model.id);\r\n if (existing) {\r\n assessmentItemQuestionsManager.removeFor(existing.id)\r\n }\r\n remove();\r\n\r\n }, [assessmentItemQuestionsManager, model, remove]);\r\n\r\n\r\n\r\n return (\r\n <>\r\n \r\n \r\n \r\n \r\n {headingText}\r\n
\r\n {subheadingText}\r\n
\r\n \r\n \r\n {model?.counterbalanceGroup}\r\n \r\n
\r\n
\r\n\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n\r\n
\r\n\r\n 1 && currentItemDisplayRules.length === 0}>\r\n \r\n \r\n\r\n change({ numberOfQuestionsToPresent: e.currentTarget.valueAsNumber })} onBlur={() => validate('numberOfQuestionsToPresent')} validationErrors={validationErrors['numberOfQuestionsToPresent']} />\r\n \r\n \r\n\r\n 1}>\r\n
\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n
\r\n \r\n\r\n
\r\n {\r\n currentItemDisplayRules.map(item => (\r\n assessmentItemDriverMetricQuantitiesManager.changeFor(item.id, changes)}\r\n remove={() => assessmentItemDriverMetricQuantitiesManager.removeFor(item.id)}\r\n driverMetrics={driverMetrics}\r\n validate={() => validateAssessmentItemDriverMetricQuantity(item)}\r\n validationErrors={assessmentItemDriverMetricQuantityErrors(item.id)}\r\n />\r\n ))\r\n }\r\n
\r\n\r\n
\r\n
\r\n\r\n\r\n\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n\r\n \r\n {\r\n // To show the questions we loop over allQuesitons and find the ones within this assessment item\r\n // rather than looping over each assessment item. We do it this way so the order of questions is\r\n // preserved (i.e. they will show alphabetically).\r\n allQuestions.map(question => {\r\n const assessmentItemQuestion = assessmentItemQuestions.find(it => it.questionId === question.id);\r\n if (!assessmentItemQuestion) {\r\n return null;\r\n }\r\n\r\n return (\r\n \r\n
\r\n \r\n {question?.name}\r\n \r\n
\r\n
\r\n {questionTypeDisplayName(question?.questionType as QuestionType, t)}\r\n
\r\n
\r\n );\r\n })\r\n }\r\n\r\n \r\n \r\n \r\n \r\n \r\n
\r\n
\r\n\r\n \r\n \r\n change({ counterbalanceGroup: e.currentTarget.value })}>\r\n \r\n {\r\n counterbalanceGroups\r\n .filter(item => !!item)\r\n .map(item => (\r\n \r\n ))\r\n }\r\n \r\n \r\n
\r\n
\r\n
\r\n\r\n\r\n item.questionId)}\r\n />\r\n\r\n item.questionId)}\r\n />\r\n\r\n item.questionId)}\r\n />\r\n\r\n \r\n );\r\n};","import { FontAwesomeIcon } from \"@fortawesome/react-fontawesome\";\r\nimport { useCallback, useMemo, useState } from \"react\";\r\nimport { ConditionalFragment } from \"react-conditionalfragment\";\r\nimport { useTranslation } from \"react-i18next\";\r\nimport { Button, ButtonGroup, Col, Modal, ModalBody, ModalFooter, ModalHeader, ModalProps, Row, Table, Card, CardBody, Collapse, InputGroupAddon } from \"reactstrap\";\r\nimport { getQuestionTypeCategory, QuestionType, QuestionTypeCategory, questionTypeDisplayName } from \"../../../../api/main/models/codeOnly/QuestionType\";\r\nimport { LoadingIndicator } from \"../../../shared/LoadingIndicator\";\r\nimport { NoResultsFound } from \"../../../shared/NoResultsFound\";\r\nimport { SearchInput } from \"../../../shared/searchInput/SearchInput\";\r\nimport \"./selectInformationModal.scss\";\r\nimport { QuestionTagDisplay } from \"../../../questionTags/questionTagSelector/QuestionTagDisplay\";\r\nimport { useQuestionsListViewModel } from \"../../../../api/main/questions/viewModels/useQuestionsListViewModel\";\r\nimport * as React from 'react';\r\nimport { TagDisplay } from \"../../../shared/tagFilter/TagDisplay\";\r\nimport { useToggleState } from 'use-toggle-state';\r\n\r\nexport interface SelectInformationModalCloseEventArgs {\r\n /**\r\n * All currently selected ids.\r\n * */\r\n selectedIds: Array,\r\n\r\n /**\r\n * Added Ids (those in selectedIds that were not in initialSelectedIds).\r\n */\r\n addedIds: Array,\r\n /**\r\n * Removed Ids (those in selectedIds that were not in initialSelectedIds).\r\n */\r\n removedIds: Array,\r\n\r\n\r\n cancelled: boolean,\r\n}\r\n\r\nexport interface SelectInformationModalProps extends ModalProps {\r\n isOpen: boolean,\r\n toggle: () => void,\r\n isLoadingQuestions?: boolean,\r\n\r\n onClose: (event: SelectInformationModalCloseEventArgs) => void,\r\n\r\n initialSelectedIds?: Array,\r\n\r\n questionTypeCategory?: QuestionTypeCategory,\r\n}\r\n\r\n/**\r\n * Modal that allows the user to select from a list of information pages.\r\n * @param props\r\n */\r\nexport const SelectInformationModal = (props: SelectInformationModalProps) => {\r\n const {\r\n isOpen,\r\n toggle,\r\n\r\n isLoadingQuestions,\r\n onClose,\r\n questionTypes,\r\n\r\n initialSelectedIds,\r\n } = props;\r\n\r\n const { t } = useTranslation();\r\n const questionTypeCategory = QuestionTypeCategory.Informtion;\r\n const isEdit = !!initialSelectedIds;\r\n const { data: { items: allItems, tags, links, driverMetrics } } = useQuestionsListViewModel({ pageSize: undefined, questionTypes: questionTypes, });\r\n \r\n // Manage the questions that have been selected.\r\n const [selectedQuestions, setSelectedQuestions] = useState>(initialSelectedIds ?? []);\r\n const toggleSelection = useCallback((id: string) => {\r\n setSelectedQuestions(prevState => {\r\n const existing = prevState.find(it => it === id);\r\n if (existing) {\r\n return prevState.filter(it => it !== id);\r\n } else {\r\n return [\r\n ...prevState,\r\n id,\r\n ];\r\n }\r\n });\r\n }, [setSelectedQuestions]);\r\n const isSelected = useCallback((id: string) => !!selectedQuestions.find(it => it === id), [selectedQuestions]);\r\n\r\n // Close the modal and return the results.\r\n const closeModal = useCallback((event?: { selectedIds: Array, cancelled?: boolean, }) => {\r\n if (onClose) {\r\n const selectedIds = event?.selectedIds ?? selectedQuestions;\r\n\r\n const externalEvent: SelectInformationModalCloseEventArgs = {\r\n ...(event ?? {}),\r\n\r\n selectedIds: selectedIds,\r\n cancelled: event?.cancelled ?? false,\r\n\r\n addedIds: event?.cancelled? []: selectedIds.filter(id => !initialSelectedIds?.find(it => it === id)),\r\n removedIds: event?.cancelled ? []: initialSelectedIds?.filter(id => !selectedIds.find(it => it === id)) ?? [],\r\n };\r\n onClose(externalEvent);\r\n }\r\n\r\n // Close the modal.\r\n toggle();\r\n }, [selectedQuestions, toggle, onClose, initialSelectedIds]);\r\n\r\n // Manage the toggling of tags on and off.\r\n const [selectedTags, setSelectedTags] = React.useState>([]);\r\n const toggleTagSelected = useCallback((tag: string) => {\r\n setSelectedTags(prevState => {\r\n const existing = prevState.find(it => it === tag);\r\n\r\n if (existing) {\r\n // If we are currently on, toggle to off.\r\n return prevState.filter(it => it !== tag);\r\n } else {\r\n // Add tag to the list of on toggles.\r\n return [...prevState, tag];\r\n }\r\n });\r\n }, [setSelectedTags]);\r\n const isTagSelected = React.useCallback((tag: string) => {\r\n // If no tags are selected, treat it as if all tags are selected.\r\n if (!selectedTags.length) {\r\n return true;\r\n }\r\n\r\n // Return true or false based on if this tag has been selected explictly.\r\n return selectedTags.find(it => it === tag);\r\n }, [selectedTags]);\r\n\r\n // Filtering the display between all and selected only.\r\n const [filter, setFilter] = useState<'all' | 'selected'>('all');\r\n\r\n // Filtering of questions.\r\n const [search, setSearch] = useState('');\r\n\r\n // Filter by the assessment's search client side so it can work when offline as well as online.\r\n const items = useMemo(() => {\r\n if (!allItems) {\r\n return allItems;\r\n }\r\n\r\n let ret = allItems;\r\n\r\n // Filter by selected tags if any tag filters have been selected.\r\n if (selectedTags.length) {\r\n ret = ret.filter(item => {\r\n // Get all questionFilterTags for this question.\r\n const myLinks = links.filter(link => link.targetId === item.id);\r\n\r\n for (const link of myLinks) {\r\n if (isTagSelected(link.questionTagId)) {\r\n return true;\r\n }\r\n }\r\n\r\n return false;\r\n });\r\n }\r\n\r\n // Filter by the QuestionTypeCategory if one is provided.\r\n if (questionTypeCategory) {\r\n ret = ret.filter(item => getQuestionTypeCategory(item.questionType as QuestionType) === questionTypeCategory);\r\n }\r\n\r\n // Filter by the selected filter.\r\n switch (filter) {\r\n case 'all':\r\n break;\r\n case 'selected': {\r\n ret = ret.filter(item => selectedQuestions.find(it => it === item.id));\r\n }\r\n }\r\n\r\n // Filter by the user's search text.\r\n let lowerSearch = search.toLocaleLowerCase();\r\n if (lowerSearch) {\r\n // Filter the items being displayed.\r\n ret = ret.filter(item => {\r\n // Get the primary driver metric.\r\n const driverMetricName = driverMetrics?.find(it => it.id === item.driverMetricId)?.name\r\n ?? t('questionsListBase.driverMetric.none', '(No primary safety metric)');\r\n\r\n // Get the tags that are linked to this item.\r\n const myTags = tags?.filter(tag => !!links?.find(it => it.questionTagId === tag.id && it.targetId === item.id)) ?? [];\r\n\r\n return (\r\n item.name.toLocaleLowerCase().indexOf(lowerSearch) >= 0\r\n || questionTypeDisplayName(item.questionType as QuestionType, t).toLocaleLowerCase().indexOf(lowerSearch) >= 0\r\n || !!myTags.find(tag => tag.name.toLocaleLowerCase().indexOf(lowerSearch) >= 0)\r\n || (driverMetricName ?? '').toLocaleLowerCase().indexOf(lowerSearch) >= 0\r\n );\r\n });\r\n }\r\n\r\n return ret;\r\n\r\n\r\n }, [allItems, search, filter, selectedQuestions, questionTypeCategory, links, tags, isTagSelected, selectedTags.length, driverMetrics, t]);\r\n\r\n //controls for filtering by tags\r\n const [isTagFilterOpen, toggleTagFilterOpen] = useToggleState(false);\r\n\r\n // UI\r\n //\r\n const colCount = 6;\r\n\r\n return (\r\n toggle()} size=\"xl\" className=\"select-information-modal\">\r\n toggle()}>\r\n {\r\n t('selectInformationModal.heading.information', 'Select information pages')\r\n }\r\n \r\n \r\n \r\n \r\n setSearch(e.currentTarget.value)}>\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n\r\n \r\n \r\n \r\n \r\n \r\n

\r\n {t('questionsListBase.selectTagsToFilter', 'Select tags to filter by:')}\r\n

\r\n \r\n \r\n \r\n {\r\n tags?.map(item => (\r\n \r\n ))\r\n }\r\n \r\n \r\n
\r\n
\r\n
\r\n
\r\n\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n {\r\n items?.map(item => {\r\n const itemIsSelected = isSelected(item.id);\r\n\r\n return (\r\n closeModal({ selectedIds: [...selectedQuestions.filter(it => it !== item.id), item.id] })}>\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n );\r\n })\r\n }\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n
 {t('selectInformationModal.question', 'Question')}{t('selectInformationModal.name', 'Name')}{t('selectInformationModal.questionType', 'Information type')}{t('selectInformationModal.safetyMetric', 'Safety metric')}{t('selectInformationModal.tags', 'Tags')}
\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n
{item.name}
\r\n
{item.name}{questionTypeDisplayName(item.questionType as QuestionType, t)}{driverMetrics?.find(it => it.id === item.driverMetricId)?.name ?? t('selectInformationModal.driverMetric.none', '(No primary safety metric)')}\r\n !!links?.find(it => it.questionTagId === tag.id && it.targetId === item.id)) ?? []}\r\n />\r\n
\r\n \r\n
\r\n
\r\n \r\n \r\n \r\n <> \r\n \r\n \r\n \r\n
\r\n );\r\n};","import { useCallback, useMemo } from \"react\";\r\nimport { useTranslation } from \"react-i18next\";\r\nimport { Button, ButtonGroup, FormGroup, Label, Input, FormText } from \"reactstrap\";\r\nimport { Question } from \"../../../../api/main/models/Question\";\r\nimport { ModelArrayChanges } from \"../../../../shared/useChanges\";\r\nimport { useDisplayOrder } from \"../../../shared/useDisplayOrder/useDisplayOrder\";\r\nimport { AssessmentItem, assessmentItemDefaultValues } from \"../../../../api/main/models/AssessmentItem\";\r\nimport { AssessmentItemComponent } from \"./AssessmentItemComponent\";\r\nimport { useToggleState } from \"use-toggle-state\";\r\nimport { SelectQuestionModal } from \"../../../questions/selectQuestionModal/SelectQuestionModal\";\r\nimport { AssessmentItemQuestion, assessmentItemQuestionDefaultValues } from \"../../../../api/main/models/AssessmentItemQuestion\";\r\nimport { Guid } from \"guid-string\";\r\nimport { Assessment } from \"../../../../api/main/models/Assessment\";\r\nimport { ValidationErrors } from \"pojo-validator\";\r\nimport { isNullOrUndefined } from \"util\";\r\nimport { ConditionalFragment } from \"react-conditionalfragment\";\r\nimport { AssessmentType } from \"../../../../api/main/models/codeOnly/AssessmentType\";\r\nimport { QuestionTypeCategory } from \"../../../../api/main/models/codeOnly/QuestionType\";\r\nimport { FontAwesomeIcon } from '@fortawesome/react-fontawesome';\r\nimport { SelectQuestionnaireModal } from \"../../../questions/questionnaires/SelectQuestionnaireModal/SelectQuestionnaireModal\";\r\nimport { SelectLearningModal } from \"../../../questions/learning/SelectLearningModal/SelectLearningModal\";\r\nimport { SelectInformationModal } from \"../../../questions/information/SelectInformationModal/SelectInformationModal\";\r\nimport { AssessmentItemDriverMetricQuantity } from \"../../../../api/main/models/AssessmentItemDriverMetricQuantity\";\r\nimport { DriverMetric } from \"../../../../api/main/models/DriverMetric\";\r\nimport { HtmlEditor } from '../../../../shared/htmlEditor';\r\n\r\nexport interface AssessmentItemsTabProps {\r\n model: Assessment | undefined,\r\n change: (changes: Partial) => void,\r\n\r\n assessmentItemsManager: ModelArrayChanges,\r\n assessmentItemQuestionsManager: ModelArrayChanges,\r\n assessmentItemDriverMetricQuantitiesManager: ModelArrayChanges,\r\n\r\n allQuestions: Array,\r\n\r\n validateAssessmentItem: (model: AssessmentItem) => boolean,\r\n assessmentItemValidationErrors: (id: string) => ValidationErrors,\r\n\r\n validateAssessmentItemDriverMetricQuantity: (model: AssessmentItemDriverMetricQuantity) => boolean,\r\n assessmentItemDriverMetricQuantityErrors: (id: string) => ValidationErrors,\r\n\r\n driverMetrics: Array,\r\n}\r\n\r\n/**\r\n * Tab for a maintaining a sequence of questions.\r\n * @param props\r\n */\r\nexport const AssessmentItemsTab = (props: AssessmentItemsTabProps) => {\r\n const {\r\n model,\r\n change,\r\n\r\n assessmentItemsManager,\r\n assessmentItemQuestionsManager,\r\n\r\n allQuestions,\r\n\r\n validateAssessmentItem,\r\n assessmentItemDriverMetricQuantitiesManager,\r\n assessmentItemValidationErrors,\r\n\r\n validateAssessmentItemDriverMetricQuantity,\r\n assessmentItemDriverMetricQuantityErrors,\r\n\r\n driverMetrics,\r\n } = props;\r\n\r\n const { t } = useTranslation();\r\n\r\n // Order the items so they show in and can be managed by displayOrder.\r\n const [orderedItems, {\r\n canMoveUp: canMoveAnswerUp,\r\n moveUp: moveAnswerUp,\r\n canMoveDown: canMoveAnswerDown,\r\n moveDown: moveAnswerDown,\r\n }] = useDisplayOrder(assessmentItemsManager);\r\n\r\n // Get a list of all unique discrimnation groups from the answers\r\n const counterbalanceGroups = useMemo(() => {\r\n let ret: Array = [];\r\n for (const answer of orderedItems) {\r\n const existing = ret.find(it => it === answer.counterbalanceGroup);\r\n if (!isNullOrUndefined(existing)) {\r\n continue;\r\n }\r\n\r\n ret.push(answer.counterbalanceGroup);\r\n }\r\n\r\n // NOTE we don't sort this alphabetically as we want them to appear in the same sequence as their first use.\r\n //ret.sort();\r\n\r\n return ret;\r\n }, [orderedItems]);\r\n \r\n // Showing of the question modal.\r\n const [questionModalIsOpen, toggleQuestionModal] = useToggleState();\r\n const openQuestionModal = useCallback((questionTypeCategory?: QuestionTypeCategory) => {\r\n toggleQuestionModal();\r\n }, [toggleQuestionModal]);\r\n\r\n const [questionnaireModalIsOpen, toggleQuestionnaireModal] = useToggleState();\r\n const openQuestionnaireModal = useCallback((questionTypeCategory?: QuestionTypeCategory) => {\r\n toggleQuestionnaireModal();\r\n }, [toggleQuestionnaireModal]);\r\n\r\n const [learningModalIsOpen, toggleLearningModal] = useToggleState();\r\n const openLearningModal = useCallback((questionTypeCategory?: QuestionTypeCategory) => {\r\n toggleLearningModal();\r\n }, [toggleLearningModal]);\r\n\r\n const [informationModalIsOpen, toggleInformationModal] = useToggleState();\r\n const openInformationModal = useCallback((questionTypeCategory?: QuestionTypeCategory) => {\r\n toggleInformationModal();\r\n }, [toggleInformationModal]);\r\n\r\n // Adding of questions selected in the modal\r\n const onQuestionModalClosed = useCallback((event: { selectedIds: Array }) => {\r\n if (!event.selectedIds.length) {\r\n return;\r\n }\r\n\r\n const newAssessmentItemId = Guid.newGuid();\r\n assessmentItemsManager.addFor({\r\n ...assessmentItemDefaultValues(),\r\n\r\n id: newAssessmentItemId,\r\n assessmentId: model?.id,\r\n });\r\n\r\n for (const selectedId of event.selectedIds) {\r\n assessmentItemQuestionsManager.addFor({\r\n ...assessmentItemQuestionDefaultValues(),\r\n\r\n assessmentId: model?.id,\r\n assessmentItemId: newAssessmentItemId,\r\n questionId: selectedId,\r\n });\r\n }\r\n }, [assessmentItemsManager, assessmentItemQuestionsManager, model?.id]);\r\n\r\n const onQuestionnaireModalClosed = useCallback((event: { selectedIds: Array }) => {\r\n if (!event.selectedIds.length) {\r\n return;\r\n }\r\n\r\n const newAssessmentItemId = Guid.newGuid();\r\n assessmentItemsManager.addFor({\r\n ...assessmentItemDefaultValues(),\r\n\r\n id: newAssessmentItemId,\r\n assessmentId: model?.id,\r\n });\r\n\r\n for (const selectedId of event.selectedIds) {\r\n assessmentItemQuestionsManager.addFor({\r\n ...assessmentItemQuestionDefaultValues(),\r\n\r\n assessmentId: model?.id,\r\n assessmentItemId: newAssessmentItemId,\r\n questionId: selectedId,\r\n });\r\n }\r\n }, [assessmentItemsManager, assessmentItemQuestionsManager, model?.id]);\r\n\r\n const onLearningModalClosed = useCallback((event: { selectedIds: Array }) => {\r\n if (!event.selectedIds.length) {\r\n return;\r\n }\r\n\r\n const newAssessmentItemId = Guid.newGuid();\r\n assessmentItemsManager.addFor({\r\n ...assessmentItemDefaultValues(),\r\n\r\n id: newAssessmentItemId,\r\n assessmentId: model?.id,\r\n });\r\n\r\n for (const selectedId of event.selectedIds) {\r\n assessmentItemQuestionsManager.addFor({\r\n ...assessmentItemQuestionDefaultValues(),\r\n\r\n assessmentId: model?.id,\r\n assessmentItemId: newAssessmentItemId,\r\n questionId: selectedId,\r\n });\r\n }\r\n }, [assessmentItemsManager, assessmentItemQuestionsManager, model?.id]);\r\n\r\n const onInformationModalClosed = useCallback((event: { selectedIds: Array }) => {\r\n if (!event.selectedIds.length) {\r\n return;\r\n }\r\n\r\n const newAssessmentItemId = Guid.newGuid();\r\n assessmentItemsManager.addFor({\r\n ...assessmentItemDefaultValues(),\r\n\r\n id: newAssessmentItemId,\r\n assessmentId: model?.id,\r\n });\r\n\r\n for (const selectedId of event.selectedIds) {\r\n assessmentItemQuestionsManager.addFor({\r\n ...assessmentItemQuestionDefaultValues(),\r\n\r\n assessmentId: model?.id,\r\n assessmentItemId: newAssessmentItemId,\r\n questionId: selectedId,\r\n });\r\n }\r\n }, [assessmentItemsManager, assessmentItemQuestionsManager, model?.id]);\r\n\r\n const isLearning = model?.assessmentType === AssessmentType.TrainingModule;\r\n\r\n const safetyMetricText = useMemo(() => {\r\n var uniqueUsedSafetyMetrics: Array = [];\r\n\r\n // Go through each assessment item\r\n orderedItems.forEach(assessmentItem => {\r\n\r\n // Go through each question for assessment item\r\n var currentAssessmentItemQuestions = assessmentItemQuestionsManager.model.filter(it => it.assessmentItemId === assessmentItem.id);\r\n currentAssessmentItemQuestions.forEach(item => {\r\n var currentQuestion = allQuestions.find(question => question.id === item.questionId);\r\n\r\n // Get the safety metric assigned to the question and add it to the temp array if we dont have it already\r\n var safetyMetric = driverMetrics.find(driverMetric => driverMetric.id === currentQuestion?.driverMetricId) ?? null;\r\n if (!!safetyMetric) {\r\n if (!uniqueUsedSafetyMetrics.includes(safetyMetric.name)) {\r\n uniqueUsedSafetyMetrics.push(safetyMetric.name);\r\n }\r\n }\r\n })\r\n })\r\n\r\n // If we have a list of driver metrics to use, process them as text to show the user\r\n if (uniqueUsedSafetyMetrics.length > 0) {\r\n\r\n if (uniqueUsedSafetyMetrics.length === 1) {\r\n // If we only have one driver metric affected, then show only that one. also use \"score\" instead of \"scores\"\r\n return \"Based on the selected questions this assessment may affect a drivers \" + uniqueUsedSafetyMetrics[0] + \" score.\";\r\n\r\n } else {\r\n // If we have more than one driver metric affected, then show all of them. use \"scores\" instead of \"score\"\r\n\r\n // Create a string of all the safety metrics affected in a easy to read format\r\n var easierSafetyMetricList = \" \";\r\n uniqueUsedSafetyMetrics.forEach(item => {\r\n if (uniqueUsedSafetyMetrics.indexOf(item) === uniqueUsedSafetyMetrics.length - 2) {\r\n // If we are on the second to last item, add \"and\" instead of a comma\r\n easierSafetyMetricList = easierSafetyMetricList + item + \" and \";\r\n } else if (uniqueUsedSafetyMetrics.indexOf(item) === uniqueUsedSafetyMetrics.length - 1) {\r\n // If we are on the last item, add nothing\r\n easierSafetyMetricList = easierSafetyMetricList + item;\r\n } else {\r\n // add a comma seperator for each item\r\n easierSafetyMetricList = easierSafetyMetricList + item + \", \";\r\n }\r\n\r\n })\r\n\r\n // Return text explaining which safety metrics may be affected by the assessment.\r\n return \"Based on the selected questions this assessment may affect a drivers \" + easierSafetyMetricList + \" scores.\";\r\n }\r\n } else {\r\n // If we have no safety metrics affected, then return text explaining that.\r\n return \"Based on the selected questions this assessment will not effect a drivers overall risk score.\";\r\n }\r\n }, [orderedItems, assessmentItemQuestionsManager, allQuestions, driverMetrics])\r\n\r\n return (\r\n <>\r\n \r\n \r\n\r\n {safetyMetricText}\r\n\r\n
\r\n {\r\n orderedItems.map(item => {\r\n return (\r\n assessmentItemsManager.changeFor(item.id, changes)}\r\n remove={() => assessmentItemsManager.removeFor(item.id)}\r\n\r\n moveUp={() => moveAnswerUp(item.id)} canMoveUp={canMoveAnswerUp(item.id)}\r\n moveDown={() => moveAnswerDown(item.id)} canMoveDown={canMoveAnswerDown(item.id)}\r\n\r\n assessmentItemQuestions={assessmentItemQuestionsManager.model.filter(it => it.assessmentItemId === item.id)}\r\n allQuestions={allQuestions}\r\n assessmentItemQuestionsManager={assessmentItemQuestionsManager}\r\n assessmentItemDriverMetricQuantitiesManager={assessmentItemDriverMetricQuantitiesManager}\r\n counterbalanceGroups={counterbalanceGroups}\r\n\r\n validateAssessmentItemDriverMetricQuantity={validateAssessmentItemDriverMetricQuantity}\r\n assessmentItemDriverMetricQuantityErrors={assessmentItemDriverMetricQuantityErrors}\r\n\r\n validate={() => validateAssessmentItem(item)}\r\n validationErrors={assessmentItemValidationErrors(item.id)}\r\n\r\n isOpenInitially={!!assessmentItemsManager.added.find(it => it.id === item.id)}\r\n\r\n driverMetrics={driverMetrics}\r\n />\r\n );\r\n })\r\n }\r\n
\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n
\r\n\r\n \r\n \r\n\r\n change({ maxSuspiciousAnswers: e.currentTarget.valueAsNumber })} />\r\n \r\n {t('assessmentItemsTab.maxSuspiciousAnswers.rule', 'Using 0 will be treated as not having a limit.')}\r\n \r\n \r\n\r\n 0}>\r\n \r\n \r\n\r\n change({ suspiciousAnswerText: html })} />\r\n \r\n {\r\n t('assessmentItemsTab.maxSuspiciousAnswers.formText', 'This will show when the user completes an assessment and has exceeded the maximum potentially suspicious answers.')\r\n }\r\n \r\n \r\n \r\n\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n\r\n \r\n \r\n \r\n\r\n \r\n \r\n \r\n\r\n \r\n );\r\n};","import { useMutation } from \"@apollo/react-hooks\";\r\nimport { useAsyncCallback } from 'react-use-async-callback';\r\nimport gql from \"graphql-tag\";\r\nimport { AsyncActionStatus } from '../../../shared/abstractStore';\r\nimport { AssessmentItemDriverMetricQuantityCreateInput } from '../generated/globalTypes';\r\nimport { createAssessmentItemDriverMetricQuantityMutation, createAssessmentItemDriverMetricQuantityMutationVariables } from '../generated/createAssessmentItemDriverMetricQuantityMutation';\r\nimport { assessmentItemDriverMetricQuantityFieldsFragment } from '../models/AssessmentItemDriverMetricQuantity';\r\n\r\n/**\r\n * Get a callback to create a AssessmentItemDriverMetricQuantity in the store.\r\n */\r\nexport function useCreateAssessmentItemDriverMetricQuantityCallback(): [(model: AssessmentItemDriverMetricQuantityCreateInput) => Promise, AsyncActionStatus] {\r\n const [mutationAction, { error }] = useMutation(\r\n gql`\r\n mutation createAssessmentItemDriverMetricQuantityMutation ($model: AssessmentItemDriverMetricQuantityCreateInput!) {\r\n createAssessmentItemDriverMetricQuantity(model: $model) {\r\n ...assessmentItemDriverMetricQuantityFields\r\n }\r\n }\r\n\r\n ${assessmentItemDriverMetricQuantityFieldsFragment}\r\n `\r\n );\r\n\r\n // Wrap the mutation in a standard callback.\r\n const [action, { isExecuting, errors: actionErrors }] = useAsyncCallback(async (model: AssessmentItemDriverMetricQuantityCreateInput) => {\r\n const result = await mutationAction({ variables: { model: model } });\r\n if (result.errors && result.errors.length) {\r\n throw result.errors;\r\n }\r\n }, [mutationAction]);\r\n\r\n return [action, { isExecuting: isExecuting, errors: error ? error.message : actionErrors }];\r\n}","import { useMutation } from \"@apollo/react-hooks\";\r\nimport { useAsyncCallback } from 'react-use-async-callback';\r\nimport gql from \"graphql-tag\";\r\nimport { AsyncActionStatus } from '../../../shared/abstractStore';\r\nimport { AssessmentItemDriverMetricQuantityUpdateInput } from '../generated/globalTypes';\r\nimport { updateAssessmentItemDriverMetricQuantityMutation, updateAssessmentItemDriverMetricQuantityMutationVariables } from '../generated/updateAssessmentItemDriverMetricQuantityMutation';\r\nimport { assessmentItemDriverMetricQuantityFieldsFragment } from '../models/AssessmentItemDriverMetricQuantity';\r\n\r\n/**\r\n * Get a callback to update a AssessmentItemDriverMetricQuantity in the store.\r\n */\r\nexport function useUpdateAssessmentItemDriverMetricQuantityCallback(): [(id: string, model: AssessmentItemDriverMetricQuantityUpdateInput) => Promise, AsyncActionStatus] {\r\n const [mutationAction, { error }] = useMutation(\r\n gql`\r\n mutation updateAssessmentItemDriverMetricQuantityMutation ($model: AssessmentItemDriverMetricQuantityUpdateInput!) {\r\n updateAssessmentItemDriverMetricQuantity(model: $model) {\r\n ...assessmentItemDriverMetricQuantityFields\r\n }\r\n }\r\n\r\n ${assessmentItemDriverMetricQuantityFieldsFragment}\r\n `\r\n );\r\n\r\n // Wrap the mutation in a standard callback.\r\n const [action, { isExecuting, errors: actionErrors }] = useAsyncCallback(async (id: string, model: AssessmentItemDriverMetricQuantityUpdateInput) => {\r\n const result = await mutationAction({ variables: { model: { ...model, id: id } } });\r\n if (result.errors && result.errors.length) {\r\n throw result.errors;\r\n }\r\n }, [mutationAction]);\r\n\r\n return [action, { isExecuting: isExecuting, errors: error ? error.message : actionErrors }];\r\n}\r\n","import { Button, Row, Col, Form, Label, FormGroup, Spinner, NavItem, NavLink, FormText } from 'reactstrap';\r\nimport { AlertOnErrors } from '../../../shared/alertOnErrors';\r\nimport { LoadingIndicator } from '../../shared/LoadingIndicator';\r\nimport { useTranslation } from 'react-i18next';\r\nimport { FontAwesomeIcon } from '@fortawesome/react-fontawesome';\r\nimport { MainContainer } from '../../shared/MainContainer';\r\nimport { useParams, useHistory } from 'react-router';\r\nimport { useChanges, useChangesArray } from '../../../shared/useChanges';\r\nimport { useSaveAssessmentCallback } from '../../../api/main/assessments/useSaveAssessmentCallback';\r\nimport { useValidatorCallback } from 'pojo-validator-react';\r\nimport { ValidatedInput } from 'pojo-validator-reactstrap';\r\nimport { FormButtons } from '../../shared/FormButtons';\r\nimport { ButtonAsync } from 'reactstrap-buttonasync';\r\nimport { useAsyncCallback } from 'react-use-async-callback';\r\nimport { Guid } from 'guid-string';\r\nimport { ConditionalFragment } from 'react-conditionalfragment';\r\nimport { Banner } from '../../shared/Banner';\r\nimport { Background } from '../../shared/background/Background';\r\nimport { AssessmentType } from '../../../api/main/models/codeOnly/AssessmentType';\r\nimport { PillsNavBar } from '../../shared/pillsNavBar/PillsNavBar';\r\nimport { StickyToolbar } from '../../shared/StickyToolbar';\r\nimport { AssessmentFeedback } from '../../../api/main/models/AssessmentFeedback';\r\nimport { useSaveAssessmentFeedbackCallback } from '../../../api/main/assessmentFeedbacks/useSaveAssessmentFeedbackCallback';\r\nimport { useDeleteAssessmentFeedbackCallback } from '../../../api/main/assessmentFeedbacks/useDeleteAssessmentFeedbackCallback';\r\nimport { useEditAssessmentSupportingData } from '../../../api/main/assessments/viewModels/useEditAssessmentSupportingData';\r\nimport { QuestionTagLink } from '../../../api/main/models/QuestionTagLink';\r\nimport { useDeleteQuestionTagLinkCallback } from '../../../api/main/questionTagLinks/useDeleteQuestionTagLinkCallback';\r\nimport { DriverMetricAdjustment } from '../../../api/main/models/DriverMetricAdjustment';\r\nimport { useSaveDriverMetricAdjustmentCallback } from '../../../api/main/driverMetricAdjustments/useSaveDriverMetricAdjustmentCallback';\r\nimport { useDeleteDriverMetricAdjustmentCallback } from '../../../api/main/driverMetricAdjustments/useDeleteDriverMetricAdjustmentCallback';\r\nimport { DriverMetricRecommendation } from '../../../api/main/models/DriverMetricRecommendation';\r\nimport { useSaveDriverMetricRecommendationCallback } from '../../../api/main/driverMetricRecommendations/useSaveDriverMetricRecommendationCallback';\r\nimport { useDeleteDriverMetricRecommendationCallback } from '../../../api/main/driverMetricRecommendations/useDeleteDriverMetricRecommendationCallback';\r\nimport { useSaveQuestionTagLinkCallback } from '../../../api/main/questionTagLinks/useSaveQuestionTagLinkCallback';\r\nimport { useValidatorArrayCallback } from '../../../shared/validator-react-contrib/useValidatorArrayCallback';\r\nimport { hasAnyValidationErrors } from '../../../utilities/hasAnyValidationErrors';\r\nimport { AssessmentItem } from '../../../api/main/models/AssessmentItem';\r\nimport { useSaveAssessmentItemCallback } from '../../../api/main/assessmentItems/useSaveAssessmentItemCallback';\r\nimport { useDeleteAssessmentItemCallback } from '../../../api/main/assessmentItems/useDeleteAssessmentItemCallback';\r\nimport { FeedbackTab } from './feedback/FeedbackTab';\r\nimport { DriverMetricsTab } from './driverMetrics/DriverMetricsTab';\r\nimport { QuestionTagsTab } from './questionTags/QuestionTagsTab';\r\nimport { useBlobReferenceStateArray } from '../../shared/useBlobReferenceState/useBlobReferenceStateArray';\r\nimport { BlobReference } from '../../../api/main/models/BlobReference';\r\nimport { useEffect, useMemo, useState } from 'react';\r\nimport { useEditAssessmentViewModel } from '../../../api/main/assessments/viewModels/useEditAssessmentViewModel';\r\nimport { Assessment, assessmentDefaultValues } from '../../../api/main/models/Assessment';\r\nimport { AssessmentItemQuestion } from '../../../api/main/models/AssessmentItemQuestion';\r\nimport { useSaveAssessmentItemQuestionCallback } from '../../../api/main/assessmentItemQuestions/useSaveAssessmentItemQuestionCallback';\r\nimport { useDeleteAssessmentItemQuestionCallback } from '../../../api/main/assessmentItemQuestions/useDeleteAssessmentItemQuestionCallback';\r\nimport { AssessmentItemsTab } from './assessmentItems/AssessmentItemsTab';\r\nimport { HtmlEditor } from '../../../shared/htmlEditor';\r\nimport moment from \"moment\";\r\nimport { useSaveAssessmentItemDriverMetricQuantityCallback } from '../../../api/main/AssessmentItemDriverMetricQuantity/useSaveAssessmentItemDriverMetricQuantityCallback';\r\nimport { AssessmentItemDriverMetricQuantity } from '../../../api/main/models/AssessmentItemDriverMetricQuantity';\r\nimport { useDeleteAssessmentItemDriverMetricQuantityCallback } from '../../../api/main/AssessmentItemDriverMetricQuantity/useDeleteAssessmentItemDriverMetricQuantityCallback';\r\nimport { defaultRiskRules, OverallRiskCategory, overallRiskService } from '../../../services/OverallRiskService';\r\n\r\nexport interface EditAssessmentBaseProps {\r\n isCreate?: boolean,\r\n onCreateDefaultValues?: () => Partial,\r\n defaultAssessmentType: AssessmentType,\r\n}\r\n\r\n/**\r\n * Create an Assessment based model.\r\n * @param props\r\n */\r\nexport const CreateAssessmentBase = (props: EditAssessmentBaseProps) => ();\r\n\r\n/**\r\n * Edit an Assessment based model.\r\n */\r\nexport const EditAssessmentBase = (props: EditAssessmentBaseProps) => {\r\n const { isCreate, onCreateDefaultValues, defaultAssessmentType } = props;\r\n\r\n const { t } = useTranslation();\r\n const { id } = useParams<{ id: string | undefined }>();\r\n const { data: {\r\n model: storeModel,\r\n feedbacks: storeFeedbacks,\r\n questionTagLinks: storeQuestionTagLinks,\r\n driverMetricRecommendations: storeDriverMetricRecommendations,\r\n driverMetricAdjustments: storeDriverMetricAdjustments,\r\n assessmentItems: storeAssessmentItems,\r\n assessmentItemDriverMetricQuantities: storeAssessmentItemDriverMetricQuantities,\r\n assessmentItemsQuestions: storeAssessmentItemQuestions,\r\n }, isLoading: _isLoading, errors: loadErrors } = useEditAssessmentViewModel(id);\r\n const { data: { questionTags, driverMetrics, questions: allQuestions }, isLoading: isLoadingSupportingData, errors: loadSupportingDataErrors } = useEditAssessmentSupportingData();\r\n const isLoading = _isLoading || isLoadingSupportingData;\r\n const { model, change, changes } = useChanges(storeModel, isCreate ? { ...assessmentDefaultValues(), ...(onCreateDefaultValues ? onCreateDefaultValues() : {}) } : undefined);\r\n const [save, { errors: saveErrors }] = useSaveAssessmentCallback();\r\n\r\n const history = useHistory();\r\n\r\n // This base component serves both Assessments and Learning Modules which are stored in the same models and share most of their\r\n // functionality. It is sometimes required that we know which we are working with, even when model is still not loaded.\r\n // To make that easy we require a defaultAssessmentType to be passed in and use that and model to calculate an\r\n // activeAssessmentType which can be used conistantly to show the right customisations based on assessment type.\r\n const activeAssessmentType: AssessmentType = useMemo(() => model?.assessmentType as AssessmentType ?? defaultAssessmentType, [model, defaultAssessmentType]);\r\n\r\n\r\n // Feedbacks.\r\n const feedbacksManager = useChangesArray(storeFeedbacks, item => item.id);\r\n const [saveAssessmentFeedback] = useSaveAssessmentFeedbackCallback();\r\n const [removeAssessmentFeedback] = useDeleteAssessmentFeedbackCallback();\r\n\r\n // QuestionTagLinks.\r\n const questionTagLinksManager = useChangesArray(storeQuestionTagLinks, item => item.id);\r\n const [saveQuestionTagLink] = useSaveQuestionTagLinkCallback();\r\n const [removeQuestionTagLink] = useDeleteQuestionTagLinkCallback();\r\n\r\n // DriverMetricAdjustments.\r\n const driverMetricAdjustmentsManager = useChangesArray(storeDriverMetricAdjustments, item => item.id);\r\n const [saveAssessmentDriverMetricAdjustment] = useSaveDriverMetricAdjustmentCallback();\r\n const [removeAssessmentDriverMetricAdjustment] = useDeleteDriverMetricAdjustmentCallback();\r\n\r\n // DriverMetricRecommendations.\r\n const driverMetricRecommendationsManager = useChangesArray(storeDriverMetricRecommendations, item => item.id);\r\n const [saveAssessmentDriverMetricRecommendation] = useSaveDriverMetricRecommendationCallback();\r\n const [removeAssessmentDriverMetricRecommendation] = useDeleteDriverMetricRecommendationCallback();\r\n\r\n // AssessmentItems.\r\n const assessmentItemsManager = useChangesArray(storeAssessmentItems, item => item.id);\r\n const [saveAssessmentItem] = useSaveAssessmentItemCallback();\r\n const [removeAssessmentItem] = useDeleteAssessmentItemCallback();\r\n\r\n // assessmentItemDriverMetricQuantities.\r\n const assessmentItemDriverMetricQuantitiesManager = useChangesArray(storeAssessmentItemDriverMetricQuantities, item => item.id);\r\n const [saveAssessmentItemDriverMetricQuantity] = useSaveAssessmentItemDriverMetricQuantityCallback();\r\n const [removeAssessmentItemDriverMetricQuantity] = useDeleteAssessmentItemDriverMetricQuantityCallback();\r\n\r\n\r\n // AssessmentItemQuestions.\r\n const assessmentItemQuestionsManager = useChangesArray(storeAssessmentItemQuestions, item => item.id);\r\n const [saveAssessmentItemQuestion] = useSaveAssessmentItemQuestionCallback();\r\n const [removeAssessmentItemQuestion] = useDeleteAssessmentItemQuestionCallback();\r\n\r\n // Blobs for child objects need to be managed as a dictionary of id to blobs.\r\n const [childBlobs, setChildBlobs, { upload: uploadChildBlob, uploadErrors: uploadChildBlobErrors }] = useBlobReferenceStateArray();\r\n useEffect(() => {\r\n let ret: Array = [];\r\n\r\n if (storeFeedbacks) {\r\n for (const feedback of storeFeedbacks) {\r\n ret.push(feedback?.videoBlobReference);\r\n ret.push(feedback?.imageBlobReference);\r\n }\r\n }\r\n\r\n setChildBlobs(ret.filter(item => !!item) as Array);\r\n }, [setChildBlobs, storeFeedbacks]);\r\n\r\n // Validation\r\n //\r\n const [validateAssessmentFeedback, assessmentFeedbackValidationErrors] = useValidatorArrayCallback((myModel, validation, fieldsToCheck) => {\r\n const rules = {\r\n // No rules required.\r\n };\r\n\r\n validation.checkRules(rules, fieldsToCheck);\r\n }, []);\r\n\r\n const [validateDriverMetricAdjustment, driverMetricAdjustmentValidationErrors] = useValidatorArrayCallback((myModel, validation, fieldsToCheck) => {\r\n const rules = {\r\n driverMetricId: () => Guid.isEmpty(myModel.driverMetricId) ? t('editAssessmentBase.validateDriverMetricAdjustment.driveMetricRequired', 'Metric is required') : '',\r\n adjustmentValue: () => myModel.adjustmentValue === 0 ? t('editAssessmentBase.validateDriverMetricAdjustment.adjustmentValueRequired', 'Adjustment cannot be zero') : '',\r\n };\r\n\r\n validation.checkRules(rules, fieldsToCheck);\r\n }, []);\r\n\r\n const [validateDriverMetricRecommendation, driverMetricRecommendationValidationErrors] = useValidatorArrayCallback((myModel, validation, fieldsToCheck) => {\r\n const rules = {\r\n driverMetricId: () => Guid.isEmpty(myModel.driverMetricId) ? t('editAssessmentBase.validateDriverMetricRecommendation.driveMetricRequired', 'Metric is required') : '',\r\n };\r\n\r\n validation.checkRules(rules, fieldsToCheck);\r\n }, []);\r\n\r\n const [validateAssessmentItem, assessmentItemValidationErrors] = useValidatorArrayCallback((myModel, validation, fieldsToCheck) => {\r\n const rules = {\r\n //add_field_to_validate_here_if_needed: () => Guid.isEmpty(myModel.driverMetricId) ? t('editAssessmentBase.validateDriverMetricRecommendation.driveMetricRequired', 'Metric is required') : '',\r\n };\r\n\r\n validation.checkRules(rules, fieldsToCheck);\r\n }, []);\r\n\r\n const [validateAssessmentItemDriverMetricQuantity, assessmentItemDriverMetricQuantityErrors] = useValidatorArrayCallback((myModel, validation, fieldsToCheck) => {\r\n const rules = {\r\n quantity: () => myModel.quantity == null || Number.isNaN(myModel.quantity) ? t('editAssessmentBase.AssessmentItemDriverMetricDisplayQuantityRuleComponent.QuantityRequired', 'Quantity is required') : '',\r\n }\r\n validation.checkRules(rules, fieldsToCheck);\r\n }, []);\r\n\r\n // Main model validation.\r\n const [validate, validationErrors] = useValidatorCallback((validation, fieldsToCheck) => {\r\n const rules = {\r\n name: () => !model?.name ? t('editAssessmentBase.nameRequired', 'Name is required') : '',\r\n assessmentType: () => !model?.assessmentType ? t('editAssessmentBase.assessmentType.required', 'Type of assessment is required') : '',\r\n feedbackStyle: () => !model?.feedbackStyle ? t('editAssessmentBase.feedbackType.required', 'Style of feedback is required'): '',\r\n\r\n // Validate related objects\r\n feedback: () => feedbacksManager.model.filter(it => !validateAssessmentFeedback(it)).length ? t('editAssessmentBase.feedbacksInvalid', 'One or more of the feedbacks are invalid') : '',\r\n driverMetricRecommendations: () => driverMetricRecommendationsManager.model.filter(it => !validateDriverMetricRecommendation(it)).length ? t('editAssessmentBase.driverMetricRecommendationsInvalid', 'One or more of the drive metric recommendation rules are invalid') : '',\r\n driverMetricAdjustments: () => driverMetricAdjustmentsManager.model.filter(it => !validateDriverMetricAdjustment(it)).length ? t('editAssessmentBase.driverMetricAdjustmentsInvalid', 'One or more of the drive metric recommendation rules are invalid') : '',\r\n assessmentItems: () => assessmentItemsManager.model.filter(it => !validateAssessmentItem(it)).length ? t('editAssessmentBase.assessmentItems.invalid', 'One or more of the assessment items are invalid') : '',\r\n };\r\n\r\n validation.checkRules(rules, fieldsToCheck);\r\n }, [\r\n model,\r\n feedbacksManager, validateAssessmentFeedback,\r\n driverMetricRecommendationsManager, validateDriverMetricRecommendation,\r\n driverMetricAdjustmentsManager, validateDriverMetricAdjustment,\r\n assessmentItemsManager, validateAssessmentItem,\r\n ]);\r\n\r\n // Saving.\r\n const [saveForm, { isExecuting: isSaving, errors: saveFormErrors }] = useAsyncCallback(async () => {\r\n if (!validate()) {\r\n return;\r\n }\r\n\r\n // Save the main model.\r\n change({ creationDate: moment().toISOString() })\r\n await save(model.id, changes, !!isCreate);\r\n\r\n // Save the feedbacks.\r\n for (const item of feedbacksManager.added) { await saveAssessmentFeedback(item.id, feedbacksManager.changesFor(item.id), true); }\r\n for (const item of feedbacksManager.updated) { await saveAssessmentFeedback(item.id, feedbacksManager.changesFor(item.id), false); }\r\n for (const item of feedbacksManager.removed) { await removeAssessmentFeedback(item.id); }\r\n feedbacksManager.markAsSaved();\r\n\r\n // Save the assessment tag links.\r\n for (const item of questionTagLinksManager.added) { await saveQuestionTagLink(item.id, questionTagLinksManager.changesFor(item.id), true); }\r\n for (const item of questionTagLinksManager.updated) { await saveQuestionTagLink(item.id, questionTagLinksManager.changesFor(item.id), false); }\r\n for (const item of questionTagLinksManager.removed) { await removeQuestionTagLink(item.id); }\r\n questionTagLinksManager.markAsSaved();\r\n\r\n // Save the driver metric recommendations\r\n for (const item of driverMetricRecommendationsManager.added) { await saveAssessmentDriverMetricRecommendation(item.id, driverMetricRecommendationsManager.changesFor(item.id), true); }\r\n for (const item of driverMetricRecommendationsManager.updated) { await saveAssessmentDriverMetricRecommendation(item.id, driverMetricRecommendationsManager.changesFor(item.id), false); }\r\n for (const item of driverMetricRecommendationsManager.removed) { await removeAssessmentDriverMetricRecommendation(item.id); }\r\n driverMetricRecommendationsManager.markAsSaved();\r\n\r\n // Save the driver metric adjustment.\r\n for (const item of driverMetricAdjustmentsManager.added) { await saveAssessmentDriverMetricAdjustment(item.id, driverMetricAdjustmentsManager.changesFor(item.id), true); }\r\n for (const item of driverMetricAdjustmentsManager.updated) { await saveAssessmentDriverMetricAdjustment(item.id, driverMetricAdjustmentsManager.changesFor(item.id), false); }\r\n for (const item of driverMetricAdjustmentsManager.removed) { await removeAssessmentDriverMetricAdjustment(item.id); }\r\n driverMetricAdjustmentsManager.markAsSaved();\r\n\r\n // Save the assessment items\r\n for (const item of assessmentItemsManager.added) { await saveAssessmentItem(item.id, assessmentItemsManager.changesFor(item.id), true); }\r\n for (const item of assessmentItemsManager.updated) { await saveAssessmentItem(item.id, assessmentItemsManager.changesFor(item.id), false); }\r\n for (const item of assessmentItemsManager.removed) { await removeAssessmentItem(item.id); }\r\n assessmentItemsManager.markAsSaved();\r\n\r\n // Save the Assessment item driver metric quantities\r\n for (const item of assessmentItemDriverMetricQuantitiesManager.added) { await saveAssessmentItemDriverMetricQuantity(item.id, assessmentItemDriverMetricQuantitiesManager.changesFor(item.id), true); }\r\n for (const item of assessmentItemDriverMetricQuantitiesManager.updated) { await saveAssessmentItemDriverMetricQuantity(item.id, assessmentItemDriverMetricQuantitiesManager.changesFor(item.id), false); }\r\n for (const item of assessmentItemDriverMetricQuantitiesManager.removed) { await removeAssessmentItemDriverMetricQuantity(item.id); }\r\n\r\n // Save the assessment item questions\r\n for (const item of assessmentItemQuestionsManager.added) { await saveAssessmentItemQuestion(item.id, assessmentItemQuestionsManager.changesFor(item.id), true); }\r\n for (const item of assessmentItemQuestionsManager.updated) { await saveAssessmentItemQuestion(item.id, assessmentItemQuestionsManager.changesFor(item.id), false); }\r\n for (const item of assessmentItemQuestionsManager.removed) { await removeAssessmentItemQuestion(item.id); }\r\n assessmentItemQuestionsManager.markAsSaved();\r\n\r\n history.goBack();\r\n }, [\r\n validate, save, model, changes, isCreate, history,\r\n feedbacksManager, saveAssessmentFeedback, removeAssessmentFeedback,\r\n questionTagLinksManager, saveQuestionTagLink, removeQuestionTagLink,\r\n driverMetricRecommendationsManager, saveAssessmentDriverMetricRecommendation, removeAssessmentDriverMetricRecommendation,\r\n driverMetricAdjustmentsManager, saveAssessmentDriverMetricAdjustment, removeAssessmentDriverMetricAdjustment,\r\n assessmentItemsManager, saveAssessmentItem, removeAssessmentItem,\r\n assessmentItemQuestionsManager, saveAssessmentItemQuestion, removeAssessmentItemQuestion,\r\n ]);\r\n\r\n // Tab tracking and UI matching to specific assessment types.\r\n const [activeTab, setActiveTab] = useState<'main' | 'introduction' | 'items' | 'feedback' | 'driverMetrics' | 'tags'>('main');\r\n\r\n // UI\r\n //\r\n return (\r\n \r\n \r\n \r\n \r\n \r\n \r\n

\r\n {\r\n activeAssessmentType === AssessmentType.TrainingModule ? (\r\n isCreate ? (\r\n <>{t('editAssessmentBase.createHeading.trainingModule', 'Add training module')}\r\n ) : (\r\n <>{t('editAssessmentBase.editHeading.trainingModule', 'Edit training module')}\r\n )\r\n ) : (\r\n isCreate ? (\r\n <>{t('editAssessmentBase.createHeading.assessment', 'Add assessment')}\r\n ) : (\r\n <>{t('editAssessmentBase.editHeading.assessment', 'Edit assessment')}\r\n )\r\n )\r\n }\r\n

\r\n \r\n \r\n \r\n \r\n \r\n setActiveTab('main')}>\r\n {\r\n\r\n activeAssessmentType === AssessmentType.TrainingModule ? <><> {t('editAssessmentBase.tabs.trainingModule', 'Training')}\r\n : <><> {t('editAssessmentBase.tabs.assessment', 'Assessment')}\r\n\r\n }\r\n\r\n \r\n <> \r\n \r\n \r\n \r\n \r\n setActiveTab('introduction')}>\r\n \r\n <> \r\n {t('editAssessmentBasetabs.tabs.introduction', 'Introduction')}\r\n\r\n \r\n <> \r\n \r\n \r\n \r\n \r\n setActiveTab('items')}>\r\n \r\n <> \r\n {t('editAssessmentBasetabs.tabs.activities', 'Questions and activities')}\r\n\r\n \r\n <> \r\n \r\n \r\n \r\n \r\n setActiveTab('feedback')}>\r\n \r\n <> \r\n {t('editAssessmentBase.tabs.feedback', 'Feedback')}\r\n \r\n <> \r\n \r\n \r\n \r\n \r\n setActiveTab('driverMetrics')}>\r\n \r\n {t('editAssessmentBase.tabs.driverMetrics', ' Recommend')}\r\n \r\n <> \r\n \r\n \r\n \r\n \r\n setActiveTab('tags')}>\r\n \r\n {t('editAssessmentBase.tabs.tags', ' Tags')}\r\n \r\n \r\n \r\n \r\n \r\n
\r\n \r\n \r\n \r\n \r\n \r\n \r\n
\r\n
\r\n\r\n \r\n \r\n\r\n
{ e.preventDefault(); saveForm(); }}>\r\n \r\n \r\n change({ name: e.currentTarget.value })} onBlur={e => validate('name')} validationErrors={validationErrors['name']} />\r\n \r\n\r\n <>\r\n {/* Tab contents */}\r\n \r\n \r\n \r\n\r\n change({ tileText: html })} />\r\n\r\n \r\n {\r\n activeAssessmentType === AssessmentType.TrainingModule ? t('editAssessmentBase.tileText.formText.trainingModule', 'This will show on the tile on the user\\'s Home screen before they launch the learning.')\r\n : t('editAssessmentBase.tileText.formText.assessment', 'This will show on the tile on the user\\'s Home screen before they launch the assessment.')\r\n }\r\n \r\n \r\n\r\n \r\n \r\n \r\n \r\n \r\n {overallRiskService.getRiskName(OverallRiskCategory.High)}\r\n \r\n <> \r\n \r\n {t('editSubscription.lessThanSign', '<')}\r\n \r\n \r\n \r\n change({ highRiskBelow: e.currentTarget.valueAsNumber })}\r\n onBlur={e => validate('highRiskBelow')}\r\n validationErrors={validationErrors['highRiskBelow']}\r\n />\r\n \r\n \r\n \r\n {t('editSubscription.lessThanOrEqualsSign', '<=')}\r\n \r\n <> \r\n \r\n {overallRiskService.getRiskName(OverallRiskCategory.Medium)}\r\n \r\n <> \r\n \r\n {t('editSubscription.lessThanSign', '<')}\r\n \r\n \r\n \r\n change({ mediumRiskBelow: e.currentTarget.valueAsNumber })}\r\n onBlur={e => validate('mediumRiskBelow')}\r\n validationErrors={validationErrors['mediumRiskBelow']}\r\n />\r\n\r\n \r\n \r\n \r\n {t('editSubscription.lessThanOrEqualsSign', '<=')}\r\n \r\n <> \r\n {overallRiskService.getRiskName(OverallRiskCategory.Low)}\r\n \r\n \r\n \r\n \r\n {t('editSubscription.riskRules.formText', 'Default rules for new assessments and the Esitu Drive dashboard are: High risk < {{highRiskBelow}} <= Medium risk < {{mediumRiskBelow}} <= Low risk.', defaultRiskRules)}\r\n \r\n \r\n \r\n\r\n \r\n \r\n \r\n\r\n change({ text: html })} />\r\n \r\n {\r\n activeAssessmentType === AssessmentType.TrainingModule ? t('editAssessmentBase.text.formText.trainingModule', 'When the user launches the training this is the first page they will see to introduce them to the training.')\r\n : t('editAssessmentBase.text.formText.assessment', 'When the user launches the assessment this is the first page they will see to introduce them to the assessment.')\r\n }\r\n \r\n \r\n \r\n\r\n \r\n \r\n \r\n\r\n \r\n \r\n \r\n\r\n \r\n \r\n \r\n\r\n \r\n \r\n \r\n \r\n\r\n\r\n \r\n \r\n {t('common.saving', 'Saving...')}}>\r\n \r\n <> {t('common.save', 'Save')}\r\n \r\n \r\n \r\n \r\n
\r\n
\r\n
\r\n );\r\n};\r\n","import * as React from 'react';\r\nimport { useLazyQuery } from \"@apollo/react-hooks\";\r\nimport gql from \"graphql-tag\";\r\nimport { AsyncLoadResult, AsyncLoadOptions } from '../../../../shared/abstractStore';\r\nimport { editAssessmentViewModelQuery, editAssessmentViewModelQueryVariables } from '../../generated/editAssessmentViewModelQuery';\r\nimport { mainApiConfig } from '../../../../configure/mainApiConfig';\r\nimport { assessmentFieldsFragment } from '../../models/Assessment';\r\nimport { blobReferenceFieldsFragment } from '../../models/BlobReference';\r\nimport { Guid } from 'guid-string';\r\nimport { assessmentFeedbackFieldsFragment } from '../../models/AssessmentFeedback';\r\nimport { driverMetricRecommendationFieldsFragment } from '../../models/DriverMetricRecommendation';\r\nimport { driverMetricAdjustmentFieldsFragment } from '../../models/DriverMetricAdjustment';\r\nimport { assessmentItemFieldsFragment } from '../../models/AssessmentItem';\r\nimport { assessmentItemQuestionFieldsFragment } from '../../models/AssessmentItemQuestion';\r\nimport { questionTagLinkFieldsFragment } from '../../models/QuestionTagLink';\r\nimport { assessmentItemDriverMetricQuantityFieldsFragment } from '../../models/AssessmentItemDriverMetricQuantity';\r\n\r\n/**\r\n * View model for EditAssessment that replaces the call to useAssessment() and loads the right related data.\r\n * @param options\r\n */\r\nexport function useEditAssessmentViewModel(id: string | undefined | null, options: AsyncLoadOptions = {}): AsyncLoadResult {\r\n // Query the data we need form the api.\r\n const [load, { data, loading, error, refetch }] = useLazyQuery(\r\n gql`\r\n query editAssessmentViewModelQuery ($id: ID!) {\r\n model: assessment(id: $id) {\r\n ...assessmentFields\r\n }\r\n\r\n assessmentItems: assessmentItems(assessmentId: $id) {\r\n ...assessmentItemFields\r\n }\r\n\r\n assessmentItemDriverMetricQuantities: assessmentItemDriverMetricQuantities(assessmentId: $id) {\r\n ...assessmentItemDriverMetricQuantityFields\r\n }\r\n\r\n assessmentItemsQuestions: assessmentItemQuestions(assessmentId: $id) {\r\n ...assessmentItemQuestionFields\r\n }\r\n\r\n feedbacks: assessmentFeedbacks(assessmentId: $id) {\r\n ...assessmentFeedbackFields\r\n\r\n videoBlobReference {\r\n ...blobReferenceFields\r\n }\r\n\r\n imageBlobReference {\r\n ...blobReferenceFields\r\n }\r\n }\r\n\r\n questionTagLinks: questionTagLinks(targetId: $id) {\r\n ...questionTagLinkFields\r\n }\r\n\r\n driverMetricRecommendations: driverMetricRecommendations(targetId: $id) {\r\n ...driverMetricRecommendationFields\r\n }\r\n\r\n driverMetricAdjustments: driverMetricAdjustments(targetId: $id) {\r\n ...driverMetricAdjustmentFields\r\n }\r\n }\r\n\r\n ${assessmentFieldsFragment}\r\n ${assessmentItemFieldsFragment}\r\n ${assessmentItemDriverMetricQuantityFieldsFragment}\r\n ${assessmentItemQuestionFieldsFragment}\r\n ${blobReferenceFieldsFragment}\r\n ${assessmentFeedbackFieldsFragment}\r\n ${questionTagLinkFieldsFragment}\r\n ${driverMetricRecommendationFieldsFragment}\r\n ${driverMetricAdjustmentFieldsFragment}\r\n `,\r\n {\r\n variables: {\r\n id: id ?? Guid.empty\r\n },\r\n fetchPolicy: options.fetchPolicy ?? mainApiConfig.defaultFetchPolicy,\r\n pollInterval: options.pollInterval,\r\n onCompleted: (data) => {\r\n if (options.onCompleted) {\r\n options.onCompleted(data);\r\n }\r\n }\r\n }\r\n );\r\n\r\n // Run the query (unless we are being lazy).\r\n React.useEffect(() => {\r\n if (!options.lazy) {\r\n load();\r\n }\r\n }, [options.lazy, load])\r\n\r\n // Return the results.\r\n const refresh = React.useCallback(async () => { !refetch ? await load() : await refetch(); }, [refetch, load]);\r\n return React.useMemo(() => ({\r\n data: data ?? ({} as any),\r\n refresh: refresh,\r\n isLoading: loading,\r\n errors: error\r\n }), [data, refresh, loading, error]);\r\n}","import * as React from 'react';\r\nimport { useLazyQuery } from \"@apollo/react-hooks\";\r\nimport gql from \"graphql-tag\";\r\nimport { AsyncLoadResult, AsyncLoadOptions } from '../../../../shared/abstractStore';\r\nimport { editAssessmentSupportingDataQuery } from '../../generated/editAssessmentSupportingDataQuery';\r\nimport { mainApiConfig } from '../../../../configure/mainApiConfig';\r\nimport { questionTagFieldsFragment } from '../../models/QuestionTag';\r\nimport { driverMetricFieldsFragment } from '../../models/DriverMetric';\r\nimport { questionFieldsFragment } from '../../models/Question';\r\n\r\n/**\r\n * Supporting data for EditAssessment that loads static data (e.g. dropdowns) that are not changed by the model being used.\r\n * @param options\r\n */\r\nexport function useEditAssessmentSupportingData(options: AsyncLoadOptions = {}): AsyncLoadResult {\r\n // Query the data we need form the api.\r\n const [load, { data, loading, error, refetch }] = useLazyQuery(\r\n gql`\r\n query editAssessmentSupportingDataQuery {\r\n questionTags {\r\n ...questionTagFields\r\n }\r\n\r\n driverMetrics {\r\n ...driverMetricFields\r\n }\r\n\r\n questions {\r\n ...questionFields\r\n }\r\n\r\n }\r\n\r\n ${questionTagFieldsFragment}\r\n ${driverMetricFieldsFragment}\r\n ${questionFieldsFragment}\r\n `,\r\n {\r\n variables: {\r\n },\r\n fetchPolicy: options.fetchPolicy ?? mainApiConfig.defaultFetchPolicy,\r\n pollInterval: options.pollInterval,\r\n onCompleted: (data) => {\r\n if (options.onCompleted) {\r\n options.onCompleted(data);\r\n }\r\n }\r\n }\r\n );\r\n\r\n // Run the query (unless we are being lazy).\r\n React.useEffect(() => {\r\n if (!options.lazy) {\r\n load();\r\n }\r\n }, [options.lazy, load])\r\n\r\n // Return the results.\r\n const refresh = React.useCallback(async () => { !refetch ? await load() : await refetch(); }, [refetch, load]);\r\n return React.useMemo(() => ({\r\n data: data ?? ({} as any),\r\n refresh: refresh,\r\n isLoading: loading,\r\n errors: error\r\n }), [data, refresh, loading, error]);\r\n}","import * as React from 'react';\r\nimport { AssessmentCreateInput, AssessmentUpdateInput } from '../generated/globalTypes';\r\nimport { useSaveInStore, SaveInStoreOptions } from '../../../shared/useSaveInStore';\r\nimport { useCreateAssessmentCallback } from './useCreateAssessmentCallback';\r\nimport { useUpdateAssessmentCallback } from './useUpdateAssessmentCallback';\r\nimport { Assessment } from '../models/Assessment';\r\n\r\n/**\r\n * Get a callback to save a Assessment in the store using either a create or update.\r\n */\r\nexport function useSaveAssessmentCallback(options: SaveInStoreOptions = {}) {\r\n const [_create, createStatus] = useCreateAssessmentCallback();\r\n const create = React.useCallback((model: Partial) => _create(model as AssessmentCreateInput), [_create]);\r\n\r\n const [_update, updateStatus] = useUpdateAssessmentCallback();\r\n const update = React.useCallback((id: string, changes: Partial) => _update(id, changes as AssessmentUpdateInput), [_update]);\r\n\r\n return useSaveInStore(\r\n [create, createStatus],\r\n [update, updateStatus],\r\n options\r\n );\r\n}\r\n","import * as React from 'react';\r\nimport { AssessmentFeedbackCreateInput, AssessmentFeedbackUpdateInput } from '../generated/globalTypes';\r\nimport { useSaveInStore, SaveInStoreOptions } from '../../../shared/useSaveInStore';\r\nimport { useCreateAssessmentFeedbackCallback } from './useCreateAssessmentFeedbackCallback';\r\nimport { useUpdateAssessmentFeedbackCallback } from './useUpdateAssessmentFeedbackCallback';\r\nimport { AssessmentFeedback } from '../models/AssessmentFeedback';\r\n\r\n/**\r\n * Get a callback to save a AssessmentFeedback in the store using either a create or update.\r\n */\r\nexport function useSaveAssessmentFeedbackCallback(options: SaveInStoreOptions = {}) {\r\n const [_create, createStatus] = useCreateAssessmentFeedbackCallback();\r\n const create = React.useCallback((model: Partial) => _create(model as AssessmentFeedbackCreateInput), [_create]);\r\n\r\n const [_update, updateStatus] = useUpdateAssessmentFeedbackCallback();\r\n const update = React.useCallback((id: string, changes: Partial) => _update(id, changes as AssessmentFeedbackUpdateInput), [_update]);\r\n\r\n return useSaveInStore(\r\n [create, createStatus],\r\n [update, updateStatus],\r\n options\r\n );\r\n}\r\n","import { useMutation } from \"@apollo/react-hooks\";\r\nimport { useAsyncCallback } from 'react-use-async-callback';\r\nimport gql from \"graphql-tag\";\r\nimport { AsyncActionStatus } from '../../../shared/abstractStore';\r\nimport { deleteAssessmentFeedbackMutation, deleteAssessmentFeedbackMutationVariables } from '../generated/deleteAssessmentFeedbackMutation';\r\nimport { assessmentFeedbackFieldsFragment } from '../models/AssessmentFeedback';\r\n\r\n/**\r\n * Get a callback to delete a AssessmentFeedback in the store.\r\n */\r\nexport function useDeleteAssessmentFeedbackCallback(): [(id: string) => Promise, AsyncActionStatus] {\r\n const [mutationAction, { error }] = useMutation(\r\n gql`\r\n mutation deleteAssessmentFeedbackMutation ($id: ID!) {\r\n deleteAssessmentFeedback(id: $id) {\r\n ...assessmentFeedbackFields\r\n }\r\n }\r\n\r\n ${assessmentFeedbackFieldsFragment}\r\n `\r\n );\r\n\r\n // Wrap the mutation in a standard callback.\r\n const [action, { isExecuting, errors: actionErrors }] = useAsyncCallback(async (id: string) => {\r\n const result = await mutationAction({ variables: { id: id } });\r\n if (result.errors && result.errors.length) {\r\n throw result.errors;\r\n }\r\n }, [mutationAction]);\r\n\r\n return [action, { isExecuting: isExecuting, errors: error ? error.message : actionErrors }];\r\n}\r\n","import * as React from 'react';\r\nimport { AssessmentItemCreateInput, AssessmentItemUpdateInput } from '../generated/globalTypes';\r\nimport { useSaveInStore, SaveInStoreOptions } from '../../../shared/useSaveInStore';\r\nimport { useCreateAssessmentItemCallback } from './useCreateAssessmentItemCallback';\r\nimport { useUpdateAssessmentItemCallback } from './useUpdateAssessmentItemCallback';\r\nimport { AssessmentItem } from '../models/AssessmentItem';\r\n\r\n/**\r\n * Get a callback to save a AssessmentItem in the store using either a create or update.\r\n */\r\nexport function useSaveAssessmentItemCallback(options: SaveInStoreOptions = {}) {\r\n const [_create, createStatus] = useCreateAssessmentItemCallback();\r\n const create = React.useCallback((model: Partial) => _create(model as AssessmentItemCreateInput), [_create]);\r\n\r\n const [_update, updateStatus] = useUpdateAssessmentItemCallback();\r\n const update = React.useCallback((id: string, changes: Partial) => _update(id, changes as AssessmentItemUpdateInput), [_update]);\r\n\r\n return useSaveInStore(\r\n [create, createStatus],\r\n [update, updateStatus],\r\n options\r\n );\r\n}\r\n","import { useMutation } from \"@apollo/react-hooks\";\r\nimport { useAsyncCallback } from 'react-use-async-callback';\r\nimport gql from \"graphql-tag\";\r\nimport { AsyncActionStatus } from '../../../shared/abstractStore';\r\nimport { deleteAssessmentItemMutation, deleteAssessmentItemMutationVariables } from '../generated/deleteAssessmentItemMutation';\r\nimport { assessmentItemFieldsFragment } from '../models/AssessmentItem';\r\n\r\n/**\r\n * Get a callback to delete a AssessmentItem in the store.\r\n */\r\nexport function useDeleteAssessmentItemCallback(): [(id: string) => Promise, AsyncActionStatus] {\r\n const [mutationAction, { error }] = useMutation(\r\n gql`\r\n mutation deleteAssessmentItemMutation ($id: ID!) {\r\n deleteAssessmentItem(id: $id) {\r\n ...assessmentItemFields\r\n }\r\n }\r\n\r\n ${assessmentItemFieldsFragment}\r\n `\r\n );\r\n\r\n // Wrap the mutation in a standard callback.\r\n const [action, { isExecuting, errors: actionErrors }] = useAsyncCallback(async (id: string) => {\r\n const result = await mutationAction({ variables: { id: id } });\r\n if (result.errors && result.errors.length) {\r\n throw result.errors;\r\n }\r\n }, [mutationAction]);\r\n\r\n return [action, { isExecuting: isExecuting, errors: error ? error.message : actionErrors }];\r\n}\r\n","import * as React from 'react';\r\nimport { AssessmentItemDriverMetricQuantityCreateInput, AssessmentItemDriverMetricQuantityUpdateInput } from '../generated/globalTypes';\r\nimport { useSaveInStore, SaveInStoreOptions } from '../../../shared/useSaveInStore';\r\nimport { useCreateAssessmentItemDriverMetricQuantityCallback } from './useCreateAssessmentItemDriverMetricQuantityCallback';\r\nimport { useUpdateAssessmentItemDriverMetricQuantityCallback } from './useUpdateAssessmentItemDriverMetricQuantityCallback';\r\nimport { AssessmentItemDriverMetricQuantity } from '../models/AssessmentItemDriverMetricQuantity';\r\n\r\n/**\r\n * Get a callback to save a AssessmentItem in the store using either a create or update.\r\n */\r\nexport function useSaveAssessmentItemDriverMetricQuantityCallback(options: SaveInStoreOptions = {}) {\r\n const [_create, createStatus] = useCreateAssessmentItemDriverMetricQuantityCallback();\r\n const create = React.useCallback((model: Partial) => _create(model as AssessmentItemDriverMetricQuantityCreateInput), [_create]);\r\n\r\n const [_update, updateStatus] = useUpdateAssessmentItemDriverMetricQuantityCallback();\r\n const update = React.useCallback((id: string, changes: Partial) => _update(id, changes as AssessmentItemDriverMetricQuantityUpdateInput), [_update]);\r\n\r\n return useSaveInStore(\r\n [create, createStatus],\r\n [update, updateStatus],\r\n options\r\n );\r\n}\r\n","import { useMutation } from \"@apollo/react-hooks\";\r\nimport { useAsyncCallback } from 'react-use-async-callback';\r\nimport gql from \"graphql-tag\";\r\nimport { AsyncActionStatus } from '../../../shared/abstractStore';\r\nimport { deleteAssessmentItemDriverMetricQuantityMutation, deleteAssessmentItemDriverMetricQuantityMutationVariables } from '../generated/deleteAssessmentItemDriverMetricQuantityMutation';\r\nimport { assessmentItemDriverMetricQuantityFieldsFragment } from '../models/AssessmentItemDriverMetricQuantity';\r\n\r\n/**\r\n * Get a callback to delete a AssessmentItemDriverMetricQuantity in the store.\r\n */\r\nexport function useDeleteAssessmentItemDriverMetricQuantityCallback(): [(id: string) => Promise, AsyncActionStatus] {\r\n const [mutationAction, { error }] = useMutation(\r\n gql`\r\n mutation deleteAssessmentItemDriverMetricQuantityMutation ($id: ID!) {\r\n deleteAssessmentItemDriverMetricQuantity(id: $id) {\r\n ...assessmentItemDriverMetricQuantityFields\r\n }\r\n }\r\n\r\n ${assessmentItemDriverMetricQuantityFieldsFragment}\r\n `\r\n );\r\n\r\n // Wrap the mutation in a standard callback.\r\n const [action, { isExecuting, errors: actionErrors }] = useAsyncCallback(async (id: string) => {\r\n const result = await mutationAction({ variables: { id: id } });\r\n if (result.errors && result.errors.length) {\r\n throw result.errors;\r\n }\r\n }, [mutationAction]);\r\n\r\n return [action, { isExecuting: isExecuting, errors: error ? error.message : actionErrors }];\r\n}\r\n","import * as React from 'react';\r\nimport { AssessmentItemQuestionCreateInput, AssessmentItemQuestionUpdateInput } from '../generated/globalTypes';\r\nimport { useSaveInStore, SaveInStoreOptions } from '../../../shared/useSaveInStore';\r\nimport { useCreateAssessmentItemQuestionCallback } from './useCreateAssessmentItemQuestionCallback';\r\nimport { useUpdateAssessmentItemQuestionCallback } from './useUpdateAssessmentItemQuestionCallback';\r\nimport { AssessmentItemQuestion } from '../models/AssessmentItemQuestion';\r\n\r\n/**\r\n * Get a callback to save a AssessmentItemQuestion in the store using either a create or update.\r\n */\r\nexport function useSaveAssessmentItemQuestionCallback(options: SaveInStoreOptions = {}) {\r\n const [_create, createStatus] = useCreateAssessmentItemQuestionCallback();\r\n const create = React.useCallback((model: Partial) => _create(model as AssessmentItemQuestionCreateInput), [_create]);\r\n\r\n const [_update, updateStatus] = useUpdateAssessmentItemQuestionCallback();\r\n const update = React.useCallback((id: string, changes: Partial) => _update(id, changes as AssessmentItemQuestionUpdateInput), [_update]);\r\n\r\n return useSaveInStore(\r\n [create, createStatus],\r\n [update, updateStatus],\r\n options\r\n );\r\n}\r\n","import { Button, Form, Label, FormGroup, Spinner, Input, Row, Col } from 'reactstrap';\r\nimport { AlertOnErrors } from '../../shared/alertOnErrors';\r\nimport { LoadingIndicator } from '../shared/LoadingIndicator';\r\nimport { useTranslation } from 'react-i18next';\r\nimport { FontAwesomeIcon } from '@fortawesome/react-fontawesome';\r\nimport { MainContainer } from '../shared/MainContainer';\r\nimport { useParams, useHistory } from 'react-router';\r\nimport { FormButtons } from '../shared/FormButtons';\r\nimport { ButtonAsync } from 'reactstrap-buttonasync';\r\nimport { useAsyncCallback } from 'react-use-async-callback';\r\nimport { useAssessment } from '../../api/main/assessments/useAssessment';\r\nimport { useDeleteAssessmentCallback } from '../../api/main/assessments/useDeleteAssessmentCallback';\r\nimport { ConditionalFragment } from 'react-conditionalfragment';\r\nimport { Banner } from '../shared/Banner';\r\nimport { Background } from '../shared/background/Background';\r\nimport { AssessmentType } from '../../api/main/models/codeOnly/AssessmentType';\r\nimport { useMemo } from 'react';\r\n\r\nexport interface DeleteAssessmentBaseProps {\r\n defaultAssessmentType: AssessmentType,\r\n}\r\n\r\n/**\r\n * Delete a record based on the Assessment model.\r\n */\r\nexport const DeleteAssessmentBase = (props: DeleteAssessmentBaseProps) => {\r\n const { defaultAssessmentType } = props;\r\n\r\n const { t } = useTranslation();\r\n const { id } = useParams<{ id: string }>();\r\n const { data: { model }, isLoading, errors: loadErrors } = useAssessment(id);\r\n const [remove, { errors: removeErrors }] = useDeleteAssessmentCallback();\r\n const history = useHistory();\r\n\r\n // This base component serves both Assessments and Learning Modules which are stored in the same models and share most of their\r\n // functionality. It is sometimes required that we know which we are working with, even when model is still not loaded.\r\n // To make that easy we require a defaultAssessmentType to be passed in and use that and model to calculate an\r\n // activeAssessmentType which can be used conistantly to show the right customisations based on assessment type.\r\n const activeAssessmentType: AssessmentType = useMemo(() => model?.assessmentType as AssessmentType ?? defaultAssessmentType, [model, defaultAssessmentType]);\r\n\r\n const [onRemoveFormSubmit, { isExecuting: isRemoving, errors: removeFormErrors }] = useAsyncCallback(async () => {\r\n if (!model) {\r\n return;\r\n }\r\n\r\n await remove(model.id);\r\n\r\n history.goBack();\r\n }, [model, history]);\r\n\r\n return (\r\n \r\n \r\n \r\n \r\n

\r\n {\r\n activeAssessmentType === AssessmentType.TrainingModule ? t('deleteAssessmentBase.heading.learning', 'Are you sure you want to delete this training module?')\r\n : t('deleteAssessmentBase.heading.assessment', 'Are you sure you want to delete this assessment?')\r\n }\r\n

\r\n \r\n \r\n \r\n \r\n \r\n \r\n
\r\n
\r\n\r\n \r\n \r\n\r\n
{ e.preventDefault(); onRemoveFormSubmit(); }}>\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n {t('common.deleting', 'Deleting...')}}>\r\n \r\n <> {t('common.delete', 'Delete')}\r\n \r\n \r\n \r\n \r\n
\r\n
\r\n
\r\n );\r\n};\r\n","import * as React from 'react';\r\nimport { useLazyQuery } from \"@apollo/react-hooks\";\r\nimport gql from \"graphql-tag\";\r\nimport { Guid } from \"guid-string\";\r\nimport { AsyncLoadResult, AsyncLoadOptions } from '../../../shared/abstractStore';\r\nimport { assessmentQuery, assessmentQueryVariables } from '../generated/assessmentQuery';\r\nimport { assessmentFieldsFragment } from '../models/Assessment';\r\nimport { mainApiConfig } from '../../../configure/mainApiConfig';\r\n\r\n/**\r\n * Get a Assessment from the store.\r\n * @param id\r\n * @param options\r\n */\r\nexport function useAssessment(id: string | undefined | null, options: AsyncLoadOptions = {}): AsyncLoadResult {\r\n // Query the data we need form the api.\r\n const [load, { data, loading, error, refetch }] = useLazyQuery(\r\n gql`\r\n query assessmentQuery ($id: ID!) {\r\n model: assessment(id: $id) {\r\n ...assessmentFields\r\n }\r\n }\r\n\r\n ${assessmentFieldsFragment}\r\n `,\r\n {\r\n variables: {\r\n id: id ?? Guid.empty,\r\n },\r\n fetchPolicy: options.fetchPolicy ?? mainApiConfig.defaultFetchPolicy,\r\n pollInterval: options.pollInterval,\r\n onCompleted: (data) => {\r\n if (options.onCompleted) {\r\n options.onCompleted(data);\r\n }\r\n }\r\n }\r\n );\r\n\r\n // Run the query (unless we are being lazy).\r\n React.useEffect(() => {\r\n if (!options.lazy) {\r\n load();\r\n }\r\n }, [options.lazy, load])\r\n\r\n // Return the results.\r\n const refresh = React.useCallback(async () => { !refetch ? await load() : await refetch(); }, [refetch, load]);\r\n return React.useMemo(() => ({\r\n data: data ?? ({} as any),\r\n refresh: refresh,\r\n isLoading: loading,\r\n errors: error\r\n }), [data, refresh, loading, error]);\r\n}\r\n","import { useMutation } from \"@apollo/react-hooks\";\r\nimport { useAsyncCallback } from 'react-use-async-callback';\r\nimport gql from \"graphql-tag\";\r\nimport { AsyncActionStatus } from '../../../shared/abstractStore';\r\nimport { deleteAssessmentMutation, deleteAssessmentMutationVariables } from '../generated/deleteAssessmentMutation';\r\nimport { assessmentFieldsFragment } from '../models/Assessment';\r\n\r\n/**\r\n * Get a callback to delete a Assessment in the store.\r\n */\r\nexport function useDeleteAssessmentCallback(): [(id: string) => Promise, AsyncActionStatus] {\r\n const [mutationAction, { error }] = useMutation(\r\n gql`\r\n mutation deleteAssessmentMutation ($id: ID!) {\r\n deleteAssessment(id: $id) {\r\n ...assessmentFields\r\n }\r\n }\r\n\r\n ${assessmentFieldsFragment}\r\n `\r\n );\r\n\r\n // Wrap the mutation in a standard callback.\r\n const [action, { isExecuting, errors: actionErrors }] = useAsyncCallback(async (id: string) => {\r\n const result = await mutationAction({ variables: { id: id } });\r\n if (result.errors && result.errors.length) {\r\n throw result.errors;\r\n }\r\n }, [mutationAction]);\r\n\r\n return [action, { isExecuting: isExecuting, errors: error ? error.message : actionErrors }];\r\n}\r\n","import * as React from 'react';\r\nimport { Button, Row, Col, ButtonGroup, ButtonDropdown, DropdownToggle, DropdownMenu, DropdownItem, CardTitle, Spinner, InputGroupAddon, Collapse, Card, CardBody } from 'reactstrap';\r\nimport { LinkContainer } from 'react-router-bootstrap';\r\nimport { AlertOnErrors } from '../../shared/alertOnErrors';\r\nimport { LoadingIndicator } from '../shared/LoadingIndicator';\r\nimport { Waypoint } from 'react-waypoint';\r\nimport { useReplaceSearchParamsEffect, useSearchParams } from '../../shared/useURLSearchParams';\r\nimport { useTranslation } from 'react-i18next';\r\nimport { SearchInput } from '../shared/searchInput/SearchInput';\r\nimport { FontAwesomeIcon } from '@fortawesome/react-fontawesome';\r\nimport { MainContainer } from '../shared/MainContainer';\r\nimport { NoResultsFound } from '../shared/NoResultsFound';\r\nimport { StickyToolbar } from '../shared/StickyToolbar';\r\nimport { useHistory } from 'react-router';\r\nimport { ConditionalFragment } from 'react-conditionalfragment';\r\nimport { Banner } from '../shared/Banner';\r\nimport { useToggleStateArray, useToggleState } from 'use-toggle-state';\r\nimport { Background } from '../shared/background/Background';\r\nimport { AssessmentType } from '../../api/main/models/codeOnly/AssessmentType';\r\nimport { QuestionTagDisplay } from '../questionTags/questionTagSelector/QuestionTagDisplay';\r\nimport { useAssessmentsListViewModel } from '../../api/main/assessments/viewModels/useAssessmentListViewModel';\r\nimport { CardsOrTable } from '../shared/cardsOrTable/CardsOrTable';\r\nimport { usePreferredListViewMode } from '../../globalState/preferredListViewMode/usePreferredListViewMode';\r\nimport { FeedbackStyle, feedbackStyleDisplayName } from '../../api/main/models/codeOnly/FeedbackStyle';\r\nimport { useCloneAssessmentCallback } from '../../api/main/assessments/useCloneAssessmentCallback';\r\nimport { useAsyncCallback } from 'react-use-async-callback';\r\nimport { HtmlDisplay } from '../../shared/htmlEditor';\r\nimport { useCallback } from \"react\";\r\nimport { TagDisplay } from \"../shared/tagFilter/TagDisplay\";\r\n\r\nexport interface AssessmentsListBaseBaseProps {\r\n title: string,\r\n\r\n assessmentTypes: Array,\r\n baseRoute: string,\r\n}\r\n\r\n/**\r\n * Base list functionality for Assessments (including Learning).\r\n * \r\n * You most often want to use the components that wrap this one rather than this one directly.\r\n */\r\nexport const AssessmentsListBase = (props: AssessmentsListBaseBaseProps) => {\r\n const {\r\n title,\r\n assessmentTypes,\r\n baseRoute,\r\n } = props;\r\n\r\n const { t } = useTranslation();\r\n const { search: searchParam } = useSearchParams();\r\n const [search, setSearch] = React.useState(searchParam ?? '');\r\n const {\r\n data: { items: allItems, tags, links },\r\n isLoading, errors: loadingErrors, fetchMore, hasMore\r\n } = useAssessmentsListViewModel({ pageSize: undefined, assessmentTypes: assessmentTypes, });\r\n const [isMenuOpen, toggleMenuOpen] = useToggleStateArray();\r\n const history = useHistory();\r\n\r\n // Manage the toggling of tags on and off.\r\n const [selectedTags, setSelectedTags] = React.useState>([]);\r\n const toggleTagSelected = useCallback((tag: string) => {\r\n setSelectedTags(prevState => {\r\n const existing = prevState.find(it => it === tag);\r\n\r\n if (existing) {\r\n // If we are currently on, toggle to off.\r\n return prevState.filter(it => it !== tag);\r\n } else {\r\n // Add tag to the list of on toggles.\r\n return [...prevState, tag];\r\n }\r\n });\r\n }, [setSelectedTags]);\r\n const isTagSelected = React.useCallback((tag: string) => {\r\n // If no tags are selected, treat it as if all tags are selected.\r\n if (!selectedTags.length) {\r\n return true;\r\n }\r\n\r\n // Return true or false based on if this tag has been selected explictly.\r\n return selectedTags.find(it => it === tag);\r\n }, [selectedTags]);\r\n\r\n // Filter by the assessment's search client side so it can work when offline as well as online.\r\n const items = React.useMemo(() => {\r\n if (!allItems) {\r\n return allItems;\r\n }\r\n\r\n let ret = allItems;\r\n\r\n // Filter by selected tags if any tag filters have been selected.\r\n if (selectedTags.length) {\r\n ret = ret.filter(item => {\r\n // Get all questionFilterTags for this question.\r\n const myLinks = links.filter(link => link.targetId === item.id);\r\n\r\n for (const link of myLinks) {\r\n if (isTagSelected(link.questionTagId)) {\r\n return true;\r\n }\r\n }\r\n\r\n return false;\r\n });\r\n }\r\n\r\n let lowerSearch = search.toLocaleLowerCase();\r\n\r\n if (lowerSearch) {\r\n // Filter the items being displayed.\r\n ret = ret.filter(item => {\r\n //Get the tags that are linked to this item.\r\n const myTags = tags?.filter(tag => !!links?.find(it => it.questionTagId === tag.id && it.targetId === item.id)) ?? [];\r\n\r\n\r\n\r\n\r\n // Filter the items being displayed.\r\n return (\r\n item.name.toLocaleLowerCase().indexOf(lowerSearch) >= 0\r\n || !!myTags.find(tag => tag.name.toLocaleLowerCase().indexOf(lowerSearch) >= 0)\r\n );\r\n });\r\n }\r\n\r\n return ret;\r\n }, [allItems, search, tags, links, isTagSelected, selectedTags.length]);\r\n\r\n useReplaceSearchParamsEffect({ search: search });\r\n\r\n const [viewMode, setViewMode] = usePreferredListViewMode();\r\n\r\n // Copy this assessment, and open it.\r\n const [cloneAssessment, { errors: cloneAssessmentErrors }] = useCloneAssessmentCallback();\r\n const [cloneAndEdit, { isExecuting: isCloning, errors: cloneAndEditErrors }] = useAsyncCallback(async (id: string) => {\r\n const cloned = await cloneAssessment(id);\r\n if (!cloned) {\r\n return;\r\n }\r\n\r\n history.push(`${baseRoute}/edit/${cloned.id}`);\r\n }, [cloneAssessment, baseRoute, history]);\r\n\r\n //controls for filtering by tags\r\n const [isTagFilterOpen, toggleTagFilterOpen] = useToggleState(false);\r\n\r\n return (\r\n \r\n \r\n \r\n \r\n \r\n

{title}

\r\n \r\n \r\n \r\n \r\n \r\n \r\n\r\n \r\n setSearch(e.currentTarget.value)}>\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n
\r\n\r\n \r\n \r\n \r\n \r\n \r\n

\r\n {t('questionsListBase.selectTagsToFilter', 'Select tags to filter by:')}\r\n

\r\n \r\n \r\n \r\n {\r\n tags?.map(item => (\r\n \r\n ))\r\n }\r\n \r\n \r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n\r\n \r\n \r\n history.push(`${baseRoute}/edit/${item.id}`)}\r\n tableHeadings={[\r\n t('assessmentsListBase.name', 'Name'),\r\n t('assessmentsListBase.tileText', 'Tile description'),\r\n t('assesssmentsListBase.tags', 'Tags'),\r\n t('assessmentsListBase.feedbackStyle', 'Feedback style'),\r\n t('assessmentsListBase.date', 'Created date'),\r\n ]}\r\n columns={[\r\n (item, view) => view === 'cards' ? ({item.name}) : item.name,\r\n (item) => ,\r\n (item) => (\r\n !!links?.find(it => it.questionTagId === tag.id && it.targetId === item.id)) ?? []}\r\n />\r\n ),\r\n (item, view) => view === 'cards'? null: feedbackStyleDisplayName(item.feedbackStyle as FeedbackStyle, t),\r\n (item, view) => view === 'cards' ? null : t('common.datetime', '{{date, DD/MM/YYYY HH:mm}}', { date: item.creationDate }),\r\n ]}\r\n buttons={(item) => (\r\n \r\n \r\n \r\n \r\n toggleMenuOpen(item.id)}>\r\n \r\n {t('common.menuDropdown', 'More')}\r\n \r\n \r\n cloneAndEdit(item.id)}>\r\n {\r\n isCloning ? (\r\n <>\r\n \r\n <> \r\n {t('assessmentsListBase.copying', 'Copying...')}\r\n \r\n ) : (\r\n <>\r\n \r\n <> \r\n {t('assessmentsListBase.createCopy', 'Create a copy')}\r\n \r\n )\r\n }\r\n \r\n \r\n \r\n \r\n <> {t('common.delete', 'Delete')}\r\n \r\n \r\n \r\n \r\n \r\n )}\r\n />\r\n \r\n \r\n \r\n \r\n\r\n \r\n\r\n \r\n \r\n\r\n \r\n \r\n\r\n \r\n\r\n \r\n
\r\n );\r\n};\r\n","import * as React from 'react';\r\nimport { useLazyQuery } from \"@apollo/react-hooks\";\r\nimport gql from \"graphql-tag\";\r\nimport { AsyncLoadPagedResult, AsyncLoadPagedOptions } from '../../../../shared/abstractStore';\r\nimport { useFetchMoreCallback } from '../../../../shared/useFetchMoreCallback';\r\nimport { assessmentsListViewModelQuery, assessmentsListViewModelQueryVariables } from '../../generated/assessmentsListViewModelQuery';\r\nimport { mainApiConfig } from '../../../../configure/mainApiConfig';\r\nimport { assessmentFieldsFragment } from '../../models/Assessment';\r\nimport { AssessmentType } from '../../models/codeOnly/AssessmentType';\r\nimport { questionTagFieldsFragment } from '../../models/QuestionTag';\r\nimport { questionTagLinkFieldsFragment } from '../../models/QuestionTagLink';\r\n\r\nexport interface QuestionsAsyncLoadPageOptions extends AsyncLoadPagedOptions {\r\n assessmentTypes?: Array,\r\n}\r\n\r\n/**\r\n * Get a list of assessments from the store with other details needed for the assessments list.\r\n * @param id\r\n * @param options\r\n */\r\nexport function useAssessmentsListViewModel(options: QuestionsAsyncLoadPageOptions = {}): AsyncLoadPagedResult {\r\n // Query data we need from the api.\r\n const [load, { data, loading, error, refetch, fetchMore: fetchMoreFromStore }] = useLazyQuery(\r\n gql`\r\n query assessmentsListViewModelQuery ($offset: Int, $first: Int, $assessmentTypes: [String!]) {\r\n items: assessments (offset: $offset, first: $first, assessmentTypes: $assessmentTypes) {\r\n ...assessmentFields\r\n }\r\n\r\n tags: questionTags {\r\n ...questionTagFields\r\n }\r\n\r\n links: questionTagLinks (targetType: \"Assessment\") {\r\n ...questionTagLinkFields\r\n }\r\n }\r\n\r\n ${assessmentFieldsFragment}\r\n ${questionTagFieldsFragment}\r\n ${questionTagLinkFieldsFragment}\r\n `,\r\n {\r\n\r\n variables: {\r\n offset: options.startOffset,\r\n first: options.pageSize,\r\n assessmentTypes: options.assessmentTypes,\r\n },\r\n fetchPolicy: options.fetchPolicy ?? mainApiConfig.defaultFetchPolicy,\r\n pollInterval: options.pollInterval,\r\n onCompleted: (data) => {\r\n if (options.onCompleted) {\r\n options.onCompleted(data);\r\n }\r\n }\r\n }\r\n );\r\n\r\n // Run the query (unless we are being lazy).\r\n React.useEffect(() => {\r\n if (!options.lazy) {\r\n load();\r\n }\r\n }, [options.lazy, load])\r\n\r\n // Get the functions used to manage paging.\r\n const { fetchMore, hasMore: _hasMore } = useFetchMoreCallback(\r\n fetchMoreFromStore,\r\n (options?.startOffset ?? 0) + (data?.items?.length ?? 0),\r\n (prevResults, newResults) => ({\r\n ...prevResults,\r\n ...newResults,\r\n\r\n items: [...(prevResults?.items ?? []), ...(newResults?.items ?? [])],\r\n tags: newResults?.tags ?? [],\r\n links: newResults?.links ?? [],\r\n }),\r\n (newResults) => newResults?.items?.length\r\n );\r\n const hasMore = React.useCallback(() => !options.pageSize ? false : _hasMore(), [options.pageSize, _hasMore]);\r\n \r\n // Return the results.\r\n const refresh = React.useCallback(async () => { !refetch ? await load() : await refetch(); }, [refetch, load]);\r\n return React.useMemo(() => ({\r\n data: data ?? ({} as any),\r\n refresh: refresh,\r\n isLoading: loading,\r\n errors: error,\r\n fetchMore: fetchMore,\r\n hasMore: hasMore,\r\n }), [data, refresh, loading, error, fetchMore, hasMore]);\r\n}\r\n","import { useMutation } from \"@apollo/react-hooks\";\r\nimport { useAsyncCallback } from 'react-use-async-callback';\r\nimport gql from \"graphql-tag\";\r\nimport { AsyncActionStatus } from '../../../shared/abstractStore';\r\nimport { cloneAssessmentMutation, cloneAssessmentMutationVariables } from '../generated/cloneAssessmentMutation';\r\nimport { Assessment, assessmentFieldsFragment } from '../models/Assessment';\r\n\r\n/**\r\n * Get a callback to clone an Assessment in the store.\r\n */\r\nexport function useCloneAssessmentCallback(): [(id: string) => Promise, AsyncActionStatus] {\r\n const [mutationAction, { error }] = useMutation(\r\n gql`\r\n mutation cloneAssessmentMutation ($copyFromAssessmentId: ID!) {\r\n cloneAssessment(copyFromAssessmentId: $copyFromAssessmentId) {\r\n ...assessmentFields\r\n }\r\n }\r\n\r\n ${assessmentFieldsFragment}\r\n `\r\n );\r\n\r\n // Wrap the mutation in a standard callback.\r\n const [action, { isExecuting, errors: actionErrors }] = useAsyncCallback(async (id: string) => {\r\n const result = await mutationAction({ variables: { copyFromAssessmentId: id } });\r\n if (result.errors && result.errors.length) {\r\n throw result.errors;\r\n }\r\n\r\n return result?.data?.cloneAssessment;\r\n }, [mutationAction]);\r\n\r\n return [action, { isExecuting: isExecuting, errors: error ? error.message : actionErrors }];\r\n}\r\n","import { RouteEntry } from \"../../../shared/routes\";\r\nimport { EditAssessment, CreateAssessment } from \"./EditAssessment\";\r\nimport { IdentityRoles } from \"../../../configure/security/IdentityRoles\";\r\nimport { DeleteAssessment } from \"./DeleteAssessment\";\r\nimport { AssessmentsList } from \"./AssessmentsList\";\r\n\r\nexport const assessmentRoutes: Array = [\r\n { path: '/administration/assessments', exact: true, component: AssessmentsList, authorize: true, requireRole: IdentityRoles.Administration },\r\n { path: '/administration/assessments/edit/:id', component: EditAssessment, authorize: true, requireRole: IdentityRoles.Administration },\r\n { path: '/administration/assessments/add', component: CreateAssessment, authorize: true, requireRole: IdentityRoles.Administration },\r\n { path: '/administration/assessments/delete/:id', component: DeleteAssessment, authorize: true, requireRole: IdentityRoles.Administration },\r\n];\r\n","import { useTranslation } from \"react-i18next\";\r\nimport { AssessmentType } from \"../../../api/main/models/codeOnly/AssessmentType\";\r\nimport { AssessmentsListBase } from \"../AssessmentsListBase\";\r\n\r\n/**\r\n * List of actual assessments.\r\n */\r\nexport const AssessmentsList = () => {\r\n const { t } = useTranslation();\r\n\r\n return (\r\n \r\n );\r\n};","import { AssessmentType } from \"../../../api/main/models/codeOnly/AssessmentType\";\r\nimport { CreateAssessmentBase, EditAssessmentBase } from \"../edit/EditAssessmentBase\";\r\n\r\n/**\r\n * Create an actual assessment.\r\n */\r\nexport const CreateAssessment = () => (\r\n ({ assessmentType: AssessmentType.Assessment })}\r\n />);\r\n\r\n/**\r\n * Edit an actual assessment.\r\n */\r\nexport const EditAssessment = () => ();\r\n","import { AssessmentType } from \"../../../api/main/models/codeOnly/AssessmentType\";\r\nimport { DeleteAssessmentBase } from \"../DeleteAssessmentBase\";\r\n\r\n/**\r\n * Delete an actual assessment.\r\n */\r\nexport const DeleteAssessment = () => ();\r\n","import { RouteEntry } from \"../../../shared/routes\";\r\nimport { EditTrainingModule, CreateTrainingModule } from \"./EditTrainingModule\";\r\nimport { IdentityRoles } from \"../../../configure/security/IdentityRoles\";\r\nimport { TrainingModulesList } from \"./TrainingModulesList\";\r\nimport { DeleteTrainingModule } from \"./DeleteTrainingModule\";\r\n\r\nexport const trainingModuleAssessmentRoutes: Array = [\r\n { path: '/administration/training', exact: true, component: TrainingModulesList, authorize: true, requireRole: IdentityRoles.Administration },\r\n { path: '/administration/training/edit/:id', component: EditTrainingModule, authorize: true, requireRole: IdentityRoles.Administration },\r\n { path: '/administration/training/add', component: CreateTrainingModule, authorize: true, requireRole: IdentityRoles.Administration },\r\n { path: '/administration/training/delete/:id', component: DeleteTrainingModule, authorize: true, requireRole: IdentityRoles.Administration },\r\n];\r\n","import { useTranslation } from \"react-i18next\";\r\nimport { AssessmentType } from \"../../../api/main/models/codeOnly/AssessmentType\";\r\nimport { AssessmentsListBase } from \"../AssessmentsListBase\";\r\n\r\n/**\r\n * List of training modules (using the Assessment model).\r\n */\r\nexport const TrainingModulesList = () => {\r\n const { t } = useTranslation();\r\n\r\n return (\r\n \r\n );\r\n};","import { AssessmentType } from \"../../../api/main/models/codeOnly/AssessmentType\";\r\nimport { CreateAssessmentBase, EditAssessmentBase } from \"../edit/EditAssessmentBase\";\r\n\r\n/**\r\n * Create a Training Module assessment.\r\n */\r\nexport const CreateTrainingModule = () => (\r\n ({ assessmentType: AssessmentType.TrainingModule })}\r\n />\r\n);\r\n\r\n/**\r\n * Edit a Training Module assessment.\r\n */\r\nexport const EditTrainingModule = () => ();\r\n","import { AssessmentType } from \"../../../api/main/models/codeOnly/AssessmentType\";\r\nimport { DeleteAssessmentBase } from \"../DeleteAssessmentBase\";\r\n\r\n/**\r\n * Delete a Training Module assessment.\r\n */\r\nexport const DeleteTrainingModule = () => ();\r\n","import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';\r\nimport * as React from 'react';\r\nimport { useCallback } from \"react\";\r\nimport { ConditionalFragment } from 'react-conditionalfragment';\r\nimport { useTranslation } from 'react-i18next';\r\nimport { useHistory } from 'react-router';\r\nimport { LinkContainer } from 'react-router-bootstrap';\r\nimport { Waypoint } from 'react-waypoint';\r\nimport { Button, ButtonDropdown, ButtonGroup, Card, CardBody, CardTitle, Col, Collapse, DropdownItem, DropdownMenu, DropdownToggle, InputGroupAddon, Row } from 'reactstrap';\r\nimport { useToggleState, useToggleStateArray } from 'use-toggle-state';\r\nimport { QuestionType, questionTypeDisplayName } from '../../api/main/models/codeOnly/QuestionType';\r\nimport { useQuestionsListViewModel } from '../../api/main/questions/viewModels/useQuestionsListViewModel';\r\nimport { usePreferredListViewMode } from '../../globalState/preferredListViewMode/usePreferredListViewMode';\r\nimport { AlertOnErrors } from '../../shared/alertOnErrors';\r\nimport { useReplaceSearchParamsEffect, useSearchParams } from '../../shared/useURLSearchParams';\r\nimport { QuestionTagDisplay } from '../questionTags/questionTagSelector/QuestionTagDisplay';\r\nimport { Background } from '../shared/background/Background';\r\nimport { Banner } from '../shared/Banner';\r\nimport { CardsOrTable } from '../shared/cardsOrTable/CardsOrTable';\r\nimport { LoadingIndicator } from '../shared/LoadingIndicator';\r\nimport { MainContainer } from '../shared/MainContainer';\r\nimport { NoResultsFound } from '../shared/NoResultsFound';\r\nimport { SearchInput } from '../shared/searchInput/SearchInput';\r\nimport { StickyToolbar } from '../shared/StickyToolbar';\r\nimport { TagDisplay } from \"../shared/tagFilter/TagDisplay\";\r\n\r\nexport interface QuestionsListBaseProps {\r\n title: string,\r\n questionTypeColumnHidden?: boolean,\r\n questionTypeColumnName?: string,\r\n questionTypes: Array,\r\n baseRoute: string,\r\n}\r\n\r\n/**\r\n * Base list of Questions or other entities that use the Question model.\r\n */\r\nexport const QuestionsListBase = (props: QuestionsListBaseProps) => {\r\n const {\r\n title,\r\n questionTypeColumnHidden = false,\r\n questionTypeColumnName,\r\n questionTypes,\r\n baseRoute,\r\n } = props;\r\n\r\n const { t } = useTranslation();\r\n const { search: searchParam } = useSearchParams();\r\n const [search, setSearch] = React.useState(searchParam ?? '');\r\n const {\r\n data: { items: allItems, tags, links, driverMetrics },\r\n isLoading, errors: loadingErrors, fetchMore, hasMore\r\n } = useQuestionsListViewModel({ pageSize: undefined, questionTypes: questionTypes, });\r\n const [isMenuOpen, toggleMenuOpen] = useToggleStateArray();\r\n const history = useHistory();\r\n\r\n\r\n // Manage the toggling of tags on and off.\r\n const [selectedTags, setSelectedTags] = React.useState>([]);\r\n const toggleTagSelected = useCallback((tag: string) => {\r\n setSelectedTags(prevState => {\r\n const existing = prevState.find(it => it === tag);\r\n\r\n if (existing) {\r\n // If we are currently on, toggle to off.\r\n return prevState.filter(it => it !== tag);\r\n } else {\r\n // Add tag to the list of on toggles.\r\n return [...prevState, tag];\r\n }\r\n });\r\n }, [setSelectedTags]);\r\n const isTagSelected = React.useCallback((tag: string) => {\r\n // If no tags are selected, treat it as if all tags are selected.\r\n if (!selectedTags.length) {\r\n return true;\r\n }\r\n\r\n // Return true or false based on if this tag has been selected explictly.\r\n return selectedTags.find(it => it === tag);\r\n }, [selectedTags]);\r\n\r\n // Filter by the question's search client side so it can work when offline as well as online.\r\n const items = React.useMemo(() => {\r\n if (!allItems) {\r\n return allItems;\r\n }\r\n\r\n let ret = allItems;\r\n\r\n // Filter by selected tags if any tag filters have been selected.\r\n if (selectedTags.length) {\r\n ret = ret.filter(item => {\r\n // Get all questionFilterTags for this question.\r\n const myLinks = links.filter(link => link.targetId === item.id);\r\n\r\n for (const link of myLinks) {\r\n if (isTagSelected(link.questionTagId)) {\r\n return true;\r\n }\r\n }\r\n\r\n return false;\r\n });\r\n }\r\n\r\n // Filter by user search input.\r\n let lowerSearch = search.toLocaleLowerCase();\r\n if (lowerSearch) {\r\n // Filter the items being displayed.\r\n ret = ret.filter(item => {\r\n // Get the primary driver metric.\r\n const driverMetricName = driverMetrics?.find(it => it.id === item.driverMetricId)?.name\r\n ?? t('questionsListBase.driverMetric.none', '(No primary safety metric)');\r\n\r\n // Get the tags that are linked to this item.\r\n const myTags = tags?.filter(tag => !!links?.find(it => it.questionTagId === tag.id && it.targetId === item.id)) ?? [];\r\n\r\n return (\r\n item.name.toLocaleLowerCase().indexOf(lowerSearch) >= 0\r\n || questionTypeDisplayName(item.questionType as QuestionType, t).toLocaleLowerCase().indexOf(lowerSearch) >= 0\r\n || !!myTags.find(tag => tag.name.toLocaleLowerCase().indexOf(lowerSearch) >= 0)\r\n || (driverMetricName ?? '').toLocaleLowerCase().indexOf(lowerSearch) >= 0\r\n );\r\n });\r\n }\r\n\r\n return ret;\r\n }, [allItems, search, t, tags, links, isTagSelected, selectedTags.length, driverMetrics]);\r\n\r\n useReplaceSearchParamsEffect({ search: search });\r\n\r\n const [viewMode, setViewMode] = usePreferredListViewMode();\r\n\r\n //controls for filtering by tags\r\n const [isTagFilterOpen, toggleTagFilterOpen] = useToggleState(false);\r\n\r\n return (\r\n \r\n \r\n \r\n \r\n \r\n

{title}

\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n setSearch(e.currentTarget.value)}>\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n
\r\n\r\n \r\n \r\n \r\n \r\n \r\n

\r\n {t('questionsListBase.selectTagsToFilter', 'Select tags to filter by:')}\r\n

\r\n \r\n \r\n \r\n {\r\n tags?.map(item => (\r\n \r\n ))\r\n }\r\n \r\n \r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n\r\n \r\n \r\n\r\n history.push(`${baseRoute}/edit/${item.id}`)}\r\n tableHeadings={[\r\n t('questionsListBase.name', 'Name'),\r\n questionTypeColumnHidden ? null : questionTypeColumnName,\r\n t('questionsListBase.driverMetric.label', 'Safety metric'),\r\n t('questionsListBase.tags', 'Tags'),\r\n ]}\r\n columns={[\r\n (item, view) => view === 'cards' ? ({item.name}) : item.name,\r\n (item) => questionTypeColumnHidden ? null : questionTypeDisplayName(item.questionType as QuestionType, t),\r\n (item) => driverMetrics?.find(it => it.id === item.driverMetricId)?.name ?? t('questionsListBase.driverMetric.none', '(No primary safety metric)'),\r\n (item) => (\r\n !!links?.find(it => it.questionTagId === tag.id && it.targetId === item.id)) ?? []}\r\n />\r\n ),\r\n ]}\r\n buttons={(item) => (\r\n \r\n \r\n \r\n \r\n toggleMenuOpen(item.id)}>\r\n \r\n {t('common.menuDropdown', 'More')}\r\n \r\n \r\n \r\n \r\n \r\n <> {t('common.delete', 'Delete')}\r\n \r\n \r\n \r\n \r\n \r\n )}\r\n />\r\n\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n
\r\n );\r\n};\r\n","import { useMutation } from \"@apollo/react-hooks\";\r\nimport { useAsyncCallback } from 'react-use-async-callback';\r\nimport gql from \"graphql-tag\";\r\nimport { AsyncActionStatus } from '../../../shared/abstractStore';\r\nimport { QuestionCreateInput } from '../generated/globalTypes';\r\nimport { createQuestionMutation, createQuestionMutationVariables } from '../generated/createQuestionMutation';\r\nimport { questionFieldsFragment } from '../models/Question';\r\n\r\n/**\r\n * Get a callback to create a Question in the store.\r\n */\r\nexport function useCreateQuestionCallback(): [(model: QuestionCreateInput) => Promise, AsyncActionStatus] {\r\n const [mutationAction, { error }] = useMutation(\r\n gql`\r\n mutation createQuestionMutation ($model: QuestionCreateInput!) {\r\n createQuestion(model: $model) {\r\n ...questionFields\r\n }\r\n }\r\n\r\n ${questionFieldsFragment}\r\n `\r\n );\r\n\r\n // Wrap the mutation in a standard callback.\r\n const [action, { isExecuting, errors: actionErrors }] = useAsyncCallback(async (model: QuestionCreateInput) => {\r\n const result = await mutationAction({ variables: { model: model } });\r\n if (result.errors && result.errors.length) {\r\n throw result.errors;\r\n }\r\n }, [mutationAction]);\r\n\r\n return [action, { isExecuting: isExecuting, errors: error ? error.message : actionErrors }];\r\n}\r\n","import { useMutation } from \"@apollo/react-hooks\";\r\nimport { useAsyncCallback } from 'react-use-async-callback';\r\nimport gql from \"graphql-tag\";\r\nimport { AsyncActionStatus } from '../../../shared/abstractStore';\r\nimport { QuestionUpdateInput } from '../generated/globalTypes';\r\nimport { updateQuestionMutation, updateQuestionMutationVariables } from '../generated/updateQuestionMutation';\r\nimport { questionFieldsFragment } from '../models/Question';\r\n\r\n/**\r\n * Get a callback to update a Question in the store.\r\n */\r\nexport function useUpdateQuestionCallback(): [(id: string, model: QuestionUpdateInput) => Promise, AsyncActionStatus] {\r\n const [mutationAction, { error }] = useMutation(\r\n gql`\r\n mutation updateQuestionMutation ($model: QuestionUpdateInput!) {\r\n updateQuestion(model: $model) {\r\n ...questionFields\r\n }\r\n }\r\n\r\n ${questionFieldsFragment}\r\n `\r\n );\r\n\r\n // Wrap the mutation in a standard callback.\r\n const [action, { isExecuting, errors: actionErrors }] = useAsyncCallback(async (id: string, model: QuestionUpdateInput) => {\r\n const result = await mutationAction({ variables: { model: { ...model, id: id } } });\r\n if (result.errors && result.errors.length) {\r\n throw result.errors;\r\n }\r\n }, [mutationAction]);\r\n\r\n return [action, { isExecuting: isExecuting, errors: error ? error.message : actionErrors }];\r\n}\r\n","import { useMutation } from \"@apollo/react-hooks\";\r\nimport { useAsyncCallback } from 'react-use-async-callback';\r\nimport gql from \"graphql-tag\";\r\nimport { AsyncActionStatus } from '../../../shared/abstractStore';\r\nimport { deleteQuestionMutation, deleteQuestionMutationVariables } from '../generated/deleteQuestionMutation';\r\nimport { questionFieldsFragment } from '../models/Question';\r\n\r\n/**\r\n * Get a callback to delete a Question in the store.\r\n */\r\nexport function useDeleteQuestionCallback(): [(id: string) => Promise, AsyncActionStatus] {\r\n const [mutationAction, { error }] = useMutation(\r\n gql`\r\n mutation deleteQuestionMutation ($id: ID!) {\r\n deleteQuestion(id: $id) {\r\n ...questionFields\r\n }\r\n }\r\n\r\n ${questionFieldsFragment}\r\n `\r\n );\r\n\r\n // Wrap the mutation in a standard callback.\r\n const [action, { isExecuting, errors: actionErrors }] = useAsyncCallback(async (id: string) => {\r\n const result = await mutationAction({ variables: { id: id } });\r\n if (result.errors && result.errors.length) {\r\n throw result.errors;\r\n }\r\n }, [mutationAction]);\r\n\r\n return [action, { isExecuting: isExecuting, errors: error ? error.message : actionErrors }];\r\n}\r\n","import gql from \"graphql-tag\";\r\nimport { Guid } from \"guid-string\";\r\nimport moment from \"moment\";\r\nimport { questionAnswerFields } from \"../generated/questionAnswerFields\";\r\n\r\nexport const questionAnswerFieldsFragment = gql`\r\n fragment questionAnswerFields on QuestionAnswer {\r\n id\r\n questionId\r\n displayOrder\r\n archived\r\n answerText\r\n answerTextImageBlobReferenceId\r\n score\r\n isCorrect\r\n startResponseTimeSeconds\r\n endResponseTimeSeconds\r\n scaleImageBlobReferenceId\r\n windowTop\r\n windowLeft\r\n windowBottom\r\n windowRight\r\n discriminationGroup\r\n subQuestionNumber\r\n isSuspicious\r\n suspicionScore\r\n }\r\n`;\r\n\r\n\r\nexport type QuestionAnswer = Omit;\r\n\r\n// Default values.\r\nexport const questionAnswerDefaultValues = (): Partial => ({\r\n id: Guid.newGuid(),\r\n questionId: undefined,\r\n displayOrder: moment().unix(),\r\n answerText: '',\r\n answerTextImageBlobReferenceId: null,\r\n score: 0,\r\n isCorrect: false,\r\n startResponseTimeSeconds: 0,\r\n endResponseTimeSeconds: 0,\r\n scaleImageBlobReferenceId: null,\r\n windowTop: 0,\r\n windowLeft: 0,\r\n windowBottom: 0,\r\n windowRight: 0,\r\n discriminationGroup: '',\r\n subQuestionNumber: 1,\r\n isSuspicious: false,\r\n suspicionScore: undefined,\r\n});","import gql from \"graphql-tag\";\r\nimport { Guid } from \"guid-string\";\r\nimport { questionFeedbackFields } from \"../generated/questionFeedbackFields\";\r\n\r\nexport const questionFeedbackFieldsFragment = gql`\r\n fragment questionFeedbackFields on QuestionFeedback {\r\n id\r\n questionId\r\n minScore\r\n maxScore\r\n archived\r\n feedbackText\r\n imageBlobReferenceId\r\n videoBlobReferenceId\r\n }\r\n`;\r\n\r\n\r\nexport type QuestionFeedback = Omit;\r\n\r\n// Default values.\r\nexport const questionFeedbackDefaultValues = (): Partial => ({\r\n id: Guid.newGuid(),\r\n questionId: undefined,\r\n minScore: 0,\r\n maxScore: 100,\r\n feedbackText: '',\r\n videoBlobReferenceId: null,\r\n imageBlobReferenceId: null,\r\n});","import gql from \"graphql-tag\";\r\nimport { Guid } from \"guid-string\";\r\nimport moment from \"moment\";\r\nimport { questionSequenceQuestionFields } from \"../generated/questionSequenceQuestionFields\";\r\n\r\nexport const questionSequenceQuestionFieldsFragment = gql`\r\n fragment questionSequenceQuestionFields on QuestionSequenceQuestion {\r\n id\r\n parentQuestionId\r\n displayOrder\r\n childQuestionId\r\n archived\r\n }\r\n`;\r\n\r\n\r\nexport type QuestionSequenceQuestion = Omit;\r\n\r\n// Default values.\r\nexport const questionSequenceQuestionDefaultValues = (): Partial => ({\r\n id: Guid.newGuid(),\r\n displayOrder: moment().unix(),\r\n parentQuestionId: undefined,\r\n childQuestionId: undefined,\r\n});","import { useTranslation } from \"react-i18next\";\r\nimport { ButtonGroup, Dropdown, DropdownItem, DropdownMenu, DropdownToggle, FormGroup, Label, Spinner } from \"reactstrap\";\r\nimport { useToggleState } from \"use-toggle-state\";\r\nimport { BlobReference } from \"../../../../api/main/models/BlobReference\";\r\nimport { Question } from \"../../../../api/main/models/Question\";\r\nimport { FileUploadButton } from \"../../../shared/fileUploadButton/FileUploadButton\";\r\nimport { UploadedVideoPreview } from \"../../../shared/uploadedVideoPreview/UploadedVideoPreview\";\r\nimport { FontAwesomeIcon } from \"@fortawesome/react-fontawesome\";\r\n\r\nexport interface VideoTabProps {\r\n model: Question | undefined,\r\n\r\n videoBlob: BlobReference | undefined | null,\r\n uploadVideoBlob: (files: FileList | null) => void,\r\n isUploadingVideoBlob: boolean,\r\n clearVideoBlob: () => void,\r\n\r\n imageBlob: BlobReference | undefined | null,\r\n uploadImageBlob: (files: FileList | null) => void,\r\n isUploadingImageBlob: boolean,\r\n clearImageBlob: () => void,\r\n\r\n}\r\n\r\n/**\r\n * Video upload tab for EditQuestion.\r\n * @param props\r\n */\r\nexport const VideoTab = (props: VideoTabProps) => {\r\n const {\r\n //model,\r\n videoBlob, uploadVideoBlob, isUploadingVideoBlob, clearVideoBlob,\r\n imageBlob, uploadImageBlob, isUploadingImageBlob, clearImageBlob,\r\n } = props;\r\n\r\n const { t } = useTranslation();\r\n\r\n const [isVideoDropdownOpen, toggleVideoDropdown] = useToggleState();\r\n\r\n return (\r\n <>\r\n \r\n \r\n\r\n \r\n\r\n \r\n uploadVideoBlob(files)} isExecuting={isUploadingVideoBlob}\r\n executingChildren={<><> {t('common.uploading', 'Uploading...')}}\r\n >\r\n \r\n {t('editCalendarEvent.uploadVideoImage', ' Upload video...')}\r\n \r\n uploadImageBlob(files)} isExecuting={isUploadingImageBlob}\r\n executingChildren={<><> {t('common.uploading', 'Uploading...')}}\r\n >\r\n \r\n {t('editCalendarEvent.uploadThumbnailImage', ' Upload thumbnail...')}\r\n \r\n\r\n toggleVideoDropdown()}>\r\n \r\n \r\n {t('common.more', 'More')}\r\n \r\n \r\n \r\n \r\n {t('editCalendarHeadline.clearVideo', 'Clear video')}\r\n \r\n \r\n {t('editCalendarHeadline.clearThumbnail', 'Clear thumbnail')}\r\n \r\n \r\n \r\n \r\n \r\n \r\n );\r\n};","import { FontAwesomeIcon } from \"@fortawesome/react-fontawesome\";\r\nimport { ValidationErrors } from \"pojo-validator\";\r\nimport { ValidateCallback } from \"pojo-validator-react\";\r\nimport { ValidatedInput } from \"pojo-validator-reactstrap\";\r\nimport { useCallback } from \"react\";\r\nimport { ConditionalFragment } from \"react-conditionalfragment\";\r\nimport { useTranslation } from \"react-i18next\";\r\nimport { useAsyncCallback } from \"react-use-async-callback\";\r\nimport { Button, ButtonGroup, Card, CardBody, Col, Collapse, Dropdown, DropdownItem, DropdownMenu, DropdownToggle, FormGroup, FormText, InputGroup, InputGroupAddon, Label, Row, Spinner} from \"reactstrap\";\r\nimport { useToggleState } from \"use-toggle-state\";\r\nimport { BlobReference } from \"../../../../api/main/models/BlobReference\";\r\nimport { QuestionAnswer } from \"../../../../api/main/models/QuestionAnswer\";\r\nimport { HtmlDisplay, HtmlEditor } from \"../../../../shared/htmlEditor\";\r\nimport { CardHeaderCollapse } from \"../../../shared/cardHeaderCollapse/CardHeaderCollapse\";\r\nimport { FileUploadButton } from \"../../../shared/fileUploadButton/FileUploadButton\";\r\nimport { FormButtons } from \"../../../shared/FormButtons\";\r\nimport { TwoValueSwitch } from \"../../../shared/TwoValueSwitch\";\r\nimport { UploadedImagePreview } from \"../../../shared/uploadedImagePreview/UploadedImagePreview\";\r\n\r\nexport interface QuestionAnswerMultipleChoiceVideoProps {\r\n model: QuestionAnswer | undefined,\r\n change: (changes: Partial) => void,\r\n remove: () => void,\r\n moveUp: () => void,\r\n canMoveUp: boolean,\r\n moveDown: () => void,\r\n canMoveDown: boolean,\r\n\r\n answerTextImageBlob: BlobReference | undefined | null,\r\n uploadChildBlob: (files: FileList | null) => Promise,\r\n\r\n isOpenInitially?: boolean,\r\n\r\n validate: ValidateCallback,\r\n validationErrors: ValidationErrors,\r\n}\r\n\r\n/**\r\n * Tab for maintaining the prompt for the question and the available multiple choice answers.\r\n * @param props\r\n */\r\nexport const QuestionAnswerMultipleChoiceVideo = (props: QuestionAnswerMultipleChoiceVideoProps) => {\r\n const {\r\n model,\r\n change,\r\n remove,\r\n moveUp,\r\n canMoveUp,\r\n moveDown,\r\n canMoveDown,\r\n\r\n answerTextImageBlob,\r\n uploadChildBlob,\r\n isOpenInitially = false,\r\n\r\n validate,\r\n validationErrors,\r\n } = props;\r\n\r\n const { t } = useTranslation();\r\n\r\n // Self management of if we are expanded or not.\r\n const [isOpen, toggleOpen] = useToggleState(isOpenInitially);\r\n\r\n // Uploading the answer text blob.\r\n const [uploadAnswerTextImageBlob, { isExecuting: isUploadingAnswerTextImageBlob }] = useAsyncCallback(async (files: FileList | null) => {\r\n const blob = await uploadChildBlob(files);\r\n if (!blob) {\r\n return;\r\n }\r\n\r\n change({ answerTextImageBlobReferenceId: blob.id });\r\n }, [uploadChildBlob, change]);\r\n const clearAnswerTextImageBlob = useCallback(() => {\r\n change({ answerTextImageBlobReferenceId: null });\r\n }, [change]);\r\n const [isAnswerImageDropdownOpen, toggleAnswerImageDropdown] = useToggleState();\r\n\r\n return (\r\n \r\n \r\n
\r\n \r\n
\r\n
\r\n\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n\r\n \r\n \r\n change({ answerText: html })} />\r\n \r\n\r\n \r\n \r\n \r\n \r\n\r\n {\r\n // Toggle the flag, and if we're using default scoring at the moment, also default the score.\r\n if (checked && model?.score === 0) {\r\n change({ isCorrect: checked, score: 100 });\r\n } else if (!checked && model?.score === 100) {\r\n change({ isCorrect: checked, score: 0 });\r\n } else {\r\n change({ isCorrect: checked });\r\n }\r\n }}\r\n />\r\n \r\n \r\n \r\n \r\n \r\n\r\n \r\n change({ score: e.currentTarget.valueAsNumber })} onBlur={() => validate('score')} validationErrors={validationErrors['score']} />\r\n \r\n {t('common.percentageSign', '%')}\r\n \r\n \r\n \r\n {t('questionAnswerMultipleChoiceVideo.score.help', 'Score will normally be between 0% (incorrect) and 100% (correct).')}\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n\r\n {\r\n // Toggle the flag\r\n change({ isSuspicious: checked });\r\n if (checked) {\r\n change({ suspicionScore: 1 }); // If we are setting the answer to suspicious, we want to have a suspicion score, so setting this to 1 as default.\r\n } else {\r\n change({ suspicionScore: undefined }); // If we are setting the answer to not suspicious, we no longer need a suspicion score, so we can set this to undefined.\r\n }\r\n \r\n }}\r\n />\r\n \r\n \r\n \r\n \r\n \r\n \r\n\r\n \r\n change({ suspicionScore: e.currentTarget.valueAsNumber })} onBlur={() => validate('suspicionScore')} validationErrors={validationErrors['suspicionScore']} />\r\n \r\n \r\n {t('questionAnswerMultipleChoiceVideo.suspicionScore.help', 'At the end of an assessment, any selected suspicious answers will have their suspicion scores added together to see if they exceed the limit set on the assessment.')}\r\n \r\n \r\n \r\n \r\n \r\n\r\n\r\n \r\n \r\n\r\n \r\n\r\n \r\n uploadAnswerTextImageBlob(files)} isExecuting={isUploadingAnswerTextImageBlob}\r\n executingChildren={<><> {t('common.uploading', 'Uploading...')}}\r\n >\r\n {t('questionAnswerMultipleChoiceVideo.uploadImage', 'Upload image...')}\r\n \r\n toggleAnswerImageDropdown()}>\r\n \r\n \r\n {t('common.more', 'More')}\r\n \r\n \r\n \r\n clearAnswerTextImageBlob()}>\r\n {t('questionAnswerMultipleChoiceVideo.clearImage', 'Clear image')}\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n
\r\n );\r\n};","import { useCallback } from \"react\";\r\nimport { useTranslation } from \"react-i18next\";\r\nimport { Button, ButtonGroup, Dropdown, DropdownItem, DropdownMenu, DropdownToggle, FormGroup, Label, Spinner } from \"reactstrap\";\r\nimport { BlobReference } from \"../../../../api/main/models/BlobReference\";\r\nimport { Question } from \"../../../../api/main/models/Question\";\r\nimport { QuestionAnswer, questionAnswerDefaultValues } from \"../../../../api/main/models/QuestionAnswer\";\r\nimport { HtmlEditor } from \"../../../../shared/htmlEditor\";\r\nimport { ModelArrayChanges } from \"../../../../shared/useChanges\";\r\nimport { FileUploadButton } from \"../../../shared/fileUploadButton/FileUploadButton\";\r\nimport { UploadedImagePreview } from \"../../../shared/uploadedImagePreview/UploadedImagePreview\";\r\nimport { QuestionAnswerMultipleChoiceVideo } from \"./QuestionAnswerMultipleChoiceVideo\";\r\nimport { useDisplayOrder } from \"../../../shared/useDisplayOrder/useDisplayOrder\";\r\nimport { useToggleState } from \"use-toggle-state\";\r\nimport { ValidationErrors } from \"pojo-validator\";\r\n\r\nexport interface QuestionPromptMultipleChoiceVideoTabProps {\r\n model: Question | undefined,\r\n change: (changes: Partial) => void,\r\n\r\n questionTextImageBlob: BlobReference | undefined | null,\r\n uploadQuestionTextImageBlob: (files: FileList | null) => void,\r\n isUploadingQuestionTextImageBlob: boolean,\r\n clearQuestionTextImageBlob: () => void,\r\n\r\n answersManager: ModelArrayChanges,\r\n\r\n childBlobs: Array,\r\n uploadChildBlob: (files: FileList | null) => Promise,\r\n\r\n validateQuestionAnswer: (model: QuestionAnswer) => boolean,\r\n questionAnswerValidationErrors: (id: string) => ValidationErrors,\r\n}\r\n\r\n/**\r\n * Tab for maintaining the prompt for the question and the available multiple choice answers.\r\n * @param props\r\n */\r\nexport const QuestionPromptMultipleChoiceVideoTab = (props: QuestionPromptMultipleChoiceVideoTabProps) => {\r\n const {\r\n model,\r\n change,\r\n\r\n questionTextImageBlob, uploadQuestionTextImageBlob, isUploadingQuestionTextImageBlob, clearQuestionTextImageBlob,\r\n answersManager,\r\n childBlobs,\r\n uploadChildBlob,\r\n\r\n validateQuestionAnswer,\r\n questionAnswerValidationErrors,\r\n } = props;\r\n\r\n const { t } = useTranslation();\r\n\r\n // Order the answers so they show in and can be managed by displayOrder.\r\n const [orderedAnswers, {\r\n canMoveUp: canMoveAnswerUp,\r\n moveUp: moveAnswerUp,\r\n canMoveDown: canMoveAnswerDown,\r\n moveDown: moveAnswerDown,\r\n }] = useDisplayOrder(answersManager);\r\n \r\n\r\n // Adding of an answer.\r\n const addAnswer = useCallback(() => {\r\n answersManager.addFor({\r\n ...questionAnswerDefaultValues(),\r\n\r\n questionId: model?.id,\r\n });\r\n }, [answersManager, model?.id]);\r\n\r\n const [isQuestionTextImageDropdownOpen, toggleQuestionTextImageDropdown] = useToggleState();\r\n\r\n return (\r\n <>\r\n \r\n \r\n\r\n change({ preQuestionText: html })} />\r\n \r\n\r\n \r\n \r\n\r\n change({ questionText: html })} />\r\n \r\n \r\n \r\n\r\n \r\n\r\n \r\n uploadQuestionTextImageBlob(files)} isExecuting={isUploadingQuestionTextImageBlob}\r\n executingChildren={<><> {t('common.uploading', 'Uploading...')}}\r\n >\r\n {t('questionPromptMultipleChoiceVideoTab.uploadPromotionalImage', 'Upload image...')}\r\n \r\n toggleQuestionTextImageDropdown()}>\r\n \r\n \r\n {t('common.more', 'More')}\r\n \r\n \r\n \r\n clearQuestionTextImageBlob()}>\r\n {t('questionPromptMultipleChoiceVideoTab.clearImage', 'Clear image')}\r\n \r\n \r\n \r\n \r\n \r\n\r\n \r\n \r\n\r\n
\r\n {\r\n orderedAnswers.map(item => (\r\n answersManager.changeFor(item.id, changes)}\r\n remove={() => answersManager.removeFor(item.id)}\r\n\r\n isOpenInitially={!!answersManager.added.find(it => it.id === item.id)}\r\n\r\n moveUp={() => moveAnswerUp(item.id)} canMoveUp={canMoveAnswerUp(item.id)}\r\n moveDown={() => moveAnswerDown(item.id)} canMoveDown={canMoveAnswerDown(item.id)}\r\n\r\n answerTextImageBlob={childBlobs.find(it => it.id === item.answerTextImageBlobReferenceId)}\r\n uploadChildBlob={uploadChildBlob}\r\n\r\n validate={() => validateQuestionAnswer(item)}\r\n validationErrors={questionAnswerValidationErrors(item.id)}\r\n />\r\n ))\r\n }\r\n
\r\n\r\n \r\n
\r\n \r\n );\r\n};","import { useMutation } from \"@apollo/react-hooks\";\r\nimport { useAsyncCallback } from 'react-use-async-callback';\r\nimport gql from \"graphql-tag\";\r\nimport { AsyncActionStatus } from '../../../shared/abstractStore';\r\nimport { QuestionAnswerCreateInput } from '../generated/globalTypes';\r\nimport { createQuestionAnswerMutation, createQuestionAnswerMutationVariables } from '../generated/createQuestionAnswerMutation';\r\nimport { questionAnswerFieldsFragment } from '../models/QuestionAnswer';\r\n\r\n/**\r\n * Get a callback to create a QuestionAnswer in the store.\r\n */\r\nexport function useCreateQuestionAnswerCallback(): [(model: QuestionAnswerCreateInput) => Promise, AsyncActionStatus] {\r\n const [mutationAction, { error }] = useMutation(\r\n gql`\r\n mutation createQuestionAnswerMutation ($model: QuestionAnswerCreateInput!) {\r\n createQuestionAnswer(model: $model) {\r\n ...questionAnswerFields\r\n }\r\n }\r\n\r\n ${questionAnswerFieldsFragment}\r\n `\r\n );\r\n\r\n // Wrap the mutation in a standard callback.\r\n const [action, { isExecuting, errors: actionErrors }] = useAsyncCallback(async (model: QuestionAnswerCreateInput) => {\r\n const result = await mutationAction({ variables: { model: model } });\r\n if (result.errors && result.errors.length) {\r\n throw result.errors;\r\n }\r\n }, [mutationAction]);\r\n\r\n return [action, { isExecuting: isExecuting, errors: error ? error.message : actionErrors }];\r\n}\r\n","import { useMutation } from \"@apollo/react-hooks\";\r\nimport { useAsyncCallback } from 'react-use-async-callback';\r\nimport gql from \"graphql-tag\";\r\nimport { AsyncActionStatus } from '../../../shared/abstractStore';\r\nimport { QuestionAnswerUpdateInput } from '../generated/globalTypes';\r\nimport { updateQuestionAnswerMutation, updateQuestionAnswerMutationVariables } from '../generated/updateQuestionAnswerMutation';\r\nimport { questionAnswerFieldsFragment } from '../models/QuestionAnswer';\r\n\r\n/**\r\n * Get a callback to update a QuestionAnswer in the store.\r\n */\r\nexport function useUpdateQuestionAnswerCallback(): [(id: string, model: QuestionAnswerUpdateInput) => Promise, AsyncActionStatus] {\r\n const [mutationAction, { error }] = useMutation(\r\n gql`\r\n mutation updateQuestionAnswerMutation ($model: QuestionAnswerUpdateInput!) {\r\n updateQuestionAnswer(model: $model) {\r\n ...questionAnswerFields\r\n }\r\n }\r\n\r\n ${questionAnswerFieldsFragment}\r\n `\r\n );\r\n\r\n // Wrap the mutation in a standard callback.\r\n const [action, { isExecuting, errors: actionErrors }] = useAsyncCallback(async (id: string, model: QuestionAnswerUpdateInput) => {\r\n const result = await mutationAction({ variables: { model: { ...model, id: id } } });\r\n if (result.errors && result.errors.length) {\r\n throw result.errors;\r\n }\r\n }, [mutationAction]);\r\n\r\n return [action, { isExecuting: isExecuting, errors: error ? error.message : actionErrors }];\r\n}\r\n","import { useMutation } from \"@apollo/react-hooks\";\r\nimport { useAsyncCallback } from 'react-use-async-callback';\r\nimport gql from \"graphql-tag\";\r\nimport { AsyncActionStatus } from '../../../shared/abstractStore';\r\nimport { deleteQuestionAnswerMutation, deleteQuestionAnswerMutationVariables } from '../generated/deleteQuestionAnswerMutation';\r\nimport { questionAnswerFieldsFragment } from '../models/QuestionAnswer';\r\n\r\n/**\r\n * Get a callback to delete a QuestionAnswer in the store.\r\n */\r\nexport function useDeleteQuestionAnswerCallback(): [(id: string) => Promise, AsyncActionStatus] {\r\n const [mutationAction, { error }] = useMutation(\r\n gql`\r\n mutation deleteQuestionAnswerMutation ($id: ID!) {\r\n deleteQuestionAnswer(id: $id) {\r\n ...questionAnswerFields\r\n }\r\n }\r\n\r\n ${questionAnswerFieldsFragment}\r\n `\r\n );\r\n\r\n // Wrap the mutation in a standard callback.\r\n const [action, { isExecuting, errors: actionErrors }] = useAsyncCallback(async (id: string) => {\r\n const result = await mutationAction({ variables: { id: id } });\r\n if (result.errors && result.errors.length) {\r\n throw result.errors;\r\n }\r\n }, [mutationAction]);\r\n\r\n return [action, { isExecuting: isExecuting, errors: error ? error.message : actionErrors }];\r\n}\r\n","import { FontAwesomeIcon } from \"@fortawesome/react-fontawesome\";\r\nimport { Guid } from \"guid-string\";\r\nimport { ValidationErrors } from \"pojo-validator\";\r\nimport { ValidateCallback } from \"pojo-validator-react\";\r\nimport { ValidatedInput } from \"pojo-validator-reactstrap\";\r\nimport { useCallback } from \"react\";\r\nimport { ConditionalFragment } from \"react-conditionalfragment\";\r\nimport { useTranslation } from \"react-i18next\";\r\nimport { useAsyncCallback } from \"react-use-async-callback\";\r\nimport { Button, ButtonGroup, Card, CardBody, Col, Collapse, Dropdown, DropdownItem, DropdownMenu, DropdownToggle, FormGroup, FormText, Label, Row, Spinner} from \"reactstrap\";\r\nimport { useToggleState } from \"use-toggle-state\";\r\nimport { BlobReference } from \"../../../../api/main/models/BlobReference\";\r\nimport { QuestionFeedback } from \"../../../../api/main/models/QuestionFeedback\";\r\nimport { HtmlEditor } from \"../../../../shared/htmlEditor\";\r\nimport { CardHeaderCollapse } from \"../../../shared/cardHeaderCollapse/CardHeaderCollapse\";\r\nimport { FileUploadButton } from \"../../../shared/fileUploadButton/FileUploadButton\";\r\nimport { FormButtons } from \"../../../shared/FormButtons\";\r\nimport { UploadedImagePreview } from \"../../../shared/uploadedImagePreview/UploadedImagePreview\";\r\nimport { UploadedVideoPreview } from \"../../../shared/uploadedVideoPreview/UploadedVideoPreview\";\r\n\r\nexport interface FeedbackProps {\r\n model: QuestionFeedback | undefined,\r\n change: (changes: Partial) => void,\r\n remove: () => void,\r\n\r\n videoBlob: BlobReference | undefined | null,\r\n imageBlob: BlobReference | undefined | null,\r\n uploadChildBlob: (files: FileList | null) => Promise,\r\n\r\n isOpenInitially?: boolean,\r\n\r\n validate: ValidateCallback,\r\n validationErrors: ValidationErrors,\r\n}\r\n\r\n/**\r\n * An item of feedback for a question.\r\n * @param props\r\n */\r\nexport const Feedback = (props: FeedbackProps) => {\r\n const {\r\n model,\r\n change,\r\n remove,\r\n\r\n videoBlob,\r\n imageBlob,\r\n uploadChildBlob,\r\n isOpenInitially = false,\r\n\r\n validate,\r\n validationErrors,\r\n } = props;\r\n\r\n const { t } = useTranslation();\r\n\r\n // Self management of if we are expanded or not.\r\n const [isOpen, toggleOpen] = useToggleState(isOpenInitially);\r\n\r\n // Uploading the video blob.\r\n const [uploadVideoBlob, { isExecuting: isUploadingVideoBlob }] = useAsyncCallback(async (files: FileList | null) => {\r\n const blob = await uploadChildBlob(files);\r\n if (!blob) {\r\n return;\r\n }\r\n\r\n change({ videoBlobReferenceId: blob.id });\r\n }, [uploadChildBlob, change]);\r\n const clearVideoBlob = useCallback(() => {\r\n change({ videoBlobReferenceId: null });\r\n }, [change]);\r\n\r\n // Uploading the image blob.\r\n const [uploadImageBlob, { isExecuting: isUploadingImageBlob }] = useAsyncCallback(async (files: FileList | null) => {\r\n const blob = await uploadChildBlob(files);\r\n if (!blob) {\r\n return;\r\n }\r\n\r\n change({ imageBlobReferenceId: blob.id });\r\n }, [uploadChildBlob, change]);\r\n const clearImageBlob = useCallback(() => {\r\n change({ imageBlobReferenceId: null });\r\n }, [change]);\r\n\r\n\r\n const [isBlobDropdownOpen, toggleBlobDropdown] = useToggleState();\r\n\r\n return (\r\n \r\n \r\n
\r\n {t('feedback.question.heading', 'Feedback when score is between {{minScore}}% and {{maxScore}}%', { minScore: model?.minScore ?? 0, maxScore: model?.maxScore ?? 0})}\r\n
\r\n
\r\n\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n\r\n \r\n \r\n change({ feedbackText: html })} />\r\n \r\n \r\n \r\n \r\n\r\n \r\n \r\n \r\n \r\n\r\n change({ minScore: e.currentTarget.valueAsNumber })} onBlur={() => validate('minScore')} validationErrors={validationErrors['minScore']} />\r\n \r\n \r\n \r\n \r\n \r\n\r\n change({ maxScore: e.currentTarget.valueAsNumber })} onBlur={() => validate('maxScore')} validationErrors={validationErrors['maxScore']} />\r\n \r\n \r\n \r\n\r\n\r\n \r\n \r\n\r\n {/* If we have no video show the image upload area, but including an option to upload a video. */}\r\n \r\n \r\n\r\n \r\n uploadImageBlob(files)} isExecuting={isUploadingImageBlob}\r\n executingChildren={<><> {t('common.uploading', 'Uploading...')}}\r\n >\r\n {t('feedback.question.uploadImage', 'Upload image...')}\r\n \r\n uploadVideoBlob(files)} isExecuting={isUploadingVideoBlob}\r\n executingChildren={<><> {t('common.uploading', 'Uploading...')}}\r\n >\r\n {t('feedback.question.uploadVideo', 'Upload video...')}\r\n \r\n toggleBlobDropdown()}>\r\n \r\n \r\n {t('common.more', 'More')}\r\n \r\n \r\n \r\n clearImageBlob()}>\r\n {t('feedback.question.clearImage', 'Clear image')}\r\n \r\n \r\n \r\n \r\n \r\n\r\n {/* If have a video show the video upload experience. User can return to the image upload experience by clearning the video.. */}\r\n \r\n \r\n\r\n \r\n uploadVideoBlob(files)} isExecuting={isUploadingVideoBlob}\r\n executingChildren={<><> {t('common.uploading', 'Uploading...')}}\r\n >\r\n {t('feedback.question.uploadVideo', 'Upload video...')}\r\n \r\n uploadImageBlob(files)} isExecuting={isUploadingImageBlob}\r\n executingChildren={<><> {t('common.uploading', 'Uploading...')}}\r\n >\r\n {t('feedback.question.uploadThumnail', 'Upload thumbnail...')}\r\n \r\n toggleBlobDropdown()}>\r\n \r\n \r\n {t('common.more', 'More')}\r\n \r\n \r\n \r\n clearVideoBlob()}>\r\n {t('feedback.question.clearVideo', 'Clear video')}\r\n \r\n clearImageBlob()}>\r\n {t('feedback.question.clearThumbnail', 'Clear thumbnail')}\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n
\r\n );\r\n};","import { useCallback, useMemo } from \"react\";\r\nimport { useTranslation } from \"react-i18next\";\r\nimport { Button, FormGroup, Label } from \"reactstrap\";\r\nimport { BlobReference } from \"../../../../api/main/models/BlobReference\";\r\nimport { Question } from \"../../../../api/main/models/Question\";\r\nimport { ModelArrayChanges } from \"../../../../shared/useChanges\";\r\nimport { QuestionFeedback, questionFeedbackDefaultValues } from \"../../../../api/main/models/QuestionFeedback\";\r\nimport { Feedback } from \"./Feedback\";\r\nimport { ValidationErrors } from \"pojo-validator\";\r\n\r\nexport interface FeedbackTabProps {\r\n model: Question | undefined,\r\n\r\n feedbacksManager: ModelArrayChanges,\r\n\r\n childBlobs: Array,\r\n uploadChildBlob: (files: FileList | null) => Promise,\r\n\r\n validateQuestionFeedback: (model: QuestionFeedback) => boolean,\r\n questionFeedbackValidationErrors: (id: string) => ValidationErrors,\r\n}\r\n\r\n/**\r\n * Tab for maintaining the feedback based on the question scores.\r\n * @param props\r\n */\r\nexport const FeedbackTab = (props: FeedbackTabProps) => {\r\n const {\r\n model,\r\n\r\n feedbacksManager,\r\n childBlobs,\r\n uploadChildBlob,\r\n\r\n validateQuestionFeedback,\r\n questionFeedbackValidationErrors,\r\n } = props;\r\n\r\n const { t } = useTranslation();\r\n\r\n // Order the feedback so they are shown based on their minimum score.\r\n const orderedFeedbacks = useMemo(() => {\r\n let ret = [...feedbacksManager.model];\r\n\r\n // Sort by min score, then max score.\r\n ret.sort((a, b) => (a.minScore === b.minScore ? (a.maxScore === b.maxScore? 0: a.maxScore < b.maxScore? -1: 1) : a.minScore < b.minScore ? -1 : 1));\r\n\r\n return ret;\r\n }, [feedbacksManager.model]);\r\n \r\n\r\n // Adding of feedback.\r\n const addFeedback = useCallback(() => {\r\n feedbacksManager.addFor({\r\n ...questionFeedbackDefaultValues(),\r\n\r\n questionId: model?.id,\r\n });\r\n }, [feedbacksManager, model?.id]);\r\n\r\n return (\r\n <>\r\n \r\n \r\n\r\n
\r\n {\r\n orderedFeedbacks.map(item => (\r\n feedbacksManager.changeFor(item.id, changes)}\r\n remove={() => feedbacksManager.removeFor(item.id)}\r\n\r\n isOpenInitially={!!feedbacksManager.added.find(it => it.id === item.id)}\r\n\r\n videoBlob={childBlobs.find(it => it.id === item.videoBlobReferenceId)}\r\n imageBlob={childBlobs.find(it => it.id === item.imageBlobReferenceId)}\r\n uploadChildBlob={uploadChildBlob}\r\n\r\n validate={() => validateQuestionFeedback(item)}\r\n validationErrors={questionFeedbackValidationErrors(item.id)}\r\n />\r\n ))\r\n }\r\n
\r\n\r\n \r\n
\r\n \r\n );\r\n};","import { useMutation } from \"@apollo/react-hooks\";\r\nimport { useAsyncCallback } from 'react-use-async-callback';\r\nimport gql from \"graphql-tag\";\r\nimport { AsyncActionStatus } from '../../../shared/abstractStore';\r\nimport { QuestionFeedbackCreateInput } from '../generated/globalTypes';\r\nimport { createQuestionFeedbackMutation, createQuestionFeedbackMutationVariables } from '../generated/createQuestionFeedbackMutation';\r\nimport { questionFeedbackFieldsFragment } from '../models/QuestionFeedback';\r\n\r\n/**\r\n * Get a callback to create a QuestionFeedback in the store.\r\n */\r\nexport function useCreateQuestionFeedbackCallback(): [(model: QuestionFeedbackCreateInput) => Promise, AsyncActionStatus] {\r\n const [mutationAction, { error }] = useMutation(\r\n gql`\r\n mutation createQuestionFeedbackMutation ($model: QuestionFeedbackCreateInput!) {\r\n createQuestionFeedback(model: $model) {\r\n ...questionFeedbackFields\r\n }\r\n }\r\n\r\n ${questionFeedbackFieldsFragment}\r\n `\r\n );\r\n\r\n // Wrap the mutation in a standard callback.\r\n const [action, { isExecuting, errors: actionErrors }] = useAsyncCallback(async (model: QuestionFeedbackCreateInput) => {\r\n const result = await mutationAction({ variables: { model: model } });\r\n if (result.errors && result.errors.length) {\r\n throw result.errors;\r\n }\r\n }, [mutationAction]);\r\n\r\n return [action, { isExecuting: isExecuting, errors: error ? error.message : actionErrors }];\r\n}\r\n","import { useMutation } from \"@apollo/react-hooks\";\r\nimport { useAsyncCallback } from 'react-use-async-callback';\r\nimport gql from \"graphql-tag\";\r\nimport { AsyncActionStatus } from '../../../shared/abstractStore';\r\nimport { QuestionFeedbackUpdateInput } from '../generated/globalTypes';\r\nimport { updateQuestionFeedbackMutation, updateQuestionFeedbackMutationVariables } from '../generated/updateQuestionFeedbackMutation';\r\nimport { questionFeedbackFieldsFragment } from '../models/QuestionFeedback';\r\n\r\n/**\r\n * Get a callback to update a QuestionFeedback in the store.\r\n */\r\nexport function useUpdateQuestionFeedbackCallback(): [(id: string, model: QuestionFeedbackUpdateInput) => Promise, AsyncActionStatus] {\r\n const [mutationAction, { error }] = useMutation(\r\n gql`\r\n mutation updateQuestionFeedbackMutation ($model: QuestionFeedbackUpdateInput!) {\r\n updateQuestionFeedback(model: $model) {\r\n ...questionFeedbackFields\r\n }\r\n }\r\n\r\n ${questionFeedbackFieldsFragment}\r\n `\r\n );\r\n\r\n // Wrap the mutation in a standard callback.\r\n const [action, { isExecuting, errors: actionErrors }] = useAsyncCallback(async (id: string, model: QuestionFeedbackUpdateInput) => {\r\n const result = await mutationAction({ variables: { model: { ...model, id: id } } });\r\n if (result.errors && result.errors.length) {\r\n throw result.errors;\r\n }\r\n }, [mutationAction]);\r\n\r\n return [action, { isExecuting: isExecuting, errors: error ? error.message : actionErrors }];\r\n}\r\n","import { useMutation } from \"@apollo/react-hooks\";\r\nimport { useAsyncCallback } from 'react-use-async-callback';\r\nimport gql from \"graphql-tag\";\r\nimport { AsyncActionStatus } from '../../../shared/abstractStore';\r\nimport { deleteQuestionFeedbackMutation, deleteQuestionFeedbackMutationVariables } from '../generated/deleteQuestionFeedbackMutation';\r\nimport { questionFeedbackFieldsFragment } from '../models/QuestionFeedback';\r\n\r\n/**\r\n * Get a callback to delete a QuestionFeedback in the store.\r\n */\r\nexport function useDeleteQuestionFeedbackCallback(): [(id: string) => Promise, AsyncActionStatus] {\r\n const [mutationAction, { error }] = useMutation(\r\n gql`\r\n mutation deleteQuestionFeedbackMutation ($id: ID!) {\r\n deleteQuestionFeedback(id: $id) {\r\n ...questionFeedbackFields\r\n }\r\n }\r\n\r\n ${questionFeedbackFieldsFragment}\r\n `\r\n );\r\n\r\n // Wrap the mutation in a standard callback.\r\n const [action, { isExecuting, errors: actionErrors }] = useAsyncCallback(async (id: string) => {\r\n const result = await mutationAction({ variables: { id: id } });\r\n if (result.errors && result.errors.length) {\r\n throw result.errors;\r\n }\r\n }, [mutationAction]);\r\n\r\n return [action, { isExecuting: isExecuting, errors: error ? error.message : actionErrors }];\r\n}\r\n","import { Guid } from \"guid-string\";\r\nimport { useCallback } from \"react\";\r\nimport { useTranslation } from \"react-i18next\";\r\nimport { FormGroup, Label } from \"reactstrap\";\r\nimport { Question } from \"../../../../api/main/models/Question\";\r\nimport { QuestionTag } from \"../../../../api/main/models/QuestionTag\";\r\nimport { QuestionTagLink } from \"../../../../api/main/models/QuestionTagLink\";\r\nimport { ModelArrayChanges } from \"../../../../shared/useChanges\";\r\nimport { QuestionTagSelector } from \"../../../questionTags/questionTagSelector/QuestionTagSelector\";\r\n\r\nexport interface QuestionTagsTabProps {\r\n model: Question | undefined,\r\n\r\n questionTags: Array,\r\n linksManager: ModelArrayChanges,\r\n}\r\n\r\n/**\r\n * Tab for maintaining the tags for this question.\r\n * @param props\r\n */\r\nexport const QuestionTagsTab = (props: QuestionTagsTabProps) => {\r\n const {\r\n model,\r\n\r\n questionTags,\r\n linksManager,\r\n } = props;\r\n\r\n const { t } = useTranslation();\r\n\r\n // Returns if this tag is selected or not.\r\n const isSelected = useCallback((id: string) => {\r\n return !!linksManager.model.find(it => it.questionTagId === id);\r\n }, [linksManager]);\r\n\r\n // Toggle the selection of the tag.\r\n const toggleSelected = useCallback((id: string) => {\r\n const existing = linksManager.model.find(it => it.questionTagId === id);\r\n if (existing) {\r\n linksManager.removeFor(existing.id);\r\n } else {\r\n linksManager.addFor({ id: Guid.newGuid(), questionTagId: id, targetId: model?.id, targetType: 'Question', archived: false, });\r\n }\r\n }, [linksManager, model?.id]);\r\n \r\n return (\r\n <>\r\n \r\n \r\n\r\n \r\n \r\n \r\n );\r\n};","import { FontAwesomeIcon } from \"@fortawesome/react-fontawesome\";\r\nimport { ValidationErrors } from \"pojo-validator\";\r\nimport { ValidateCallback } from \"pojo-validator-react\";\r\nimport { ValidatedInput } from \"pojo-validator-reactstrap\";\r\nimport { useTranslation } from \"react-i18next\";\r\nimport { Button, ButtonGroup, Card, FormGroup } from \"reactstrap\";\r\nimport { DriverMetric } from \"../../../../api/main/models/DriverMetric\";\r\nimport { DriverMetricRecommendation } from \"../../../../api/main/models/DriverMetricRecommendation\";\r\nimport { FormButtons } from \"../../../shared/FormButtons\";\r\n\r\nexport interface DriverMetricRecommendationComponentProps {\r\n model: DriverMetricRecommendation | undefined,\r\n change: (changes: Partial) => void,\r\n remove: () => void,\r\n\r\n validate: ValidateCallback,\r\n validationErrors: ValidationErrors,\r\n\r\n driverMetrics: Array,\r\n}\r\n\r\n/**\r\n * Component for driver metric recommendation rules for questions.\r\n * @param props\r\n */\r\nexport const DriverMetricRecommendationComponent = (props: DriverMetricRecommendationComponentProps) => {\r\n const {\r\n model,\r\n change,\r\n remove,\r\n validate,\r\n validationErrors,\r\n driverMetrics,\r\n } = props;\r\n\r\n const { t } = useTranslation();\r\n\r\n return (\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n
\r\n {t('driverMetricRecommendation.beforeMetric', 'Recommend this question when')}\r\n <> \r\n change({ driverMetricId: e.currentTarget.value })} onBlur={() => validate('driverMetricId')} validationErrors={validationErrors['driverMetricId']}>\r\n \r\n {\r\n driverMetrics.map(item => (\r\n \r\n ))\r\n }\r\n \r\n <> \r\n {t('driverMetricRecommendation.beforeMin', 'is between')}\r\n <> \r\n change({ minScore: e.currentTarget.valueAsNumber })} onBlur={() => validate('minScore')} validationErrors={validationErrors['minScore']} />\r\n <> \r\n {t('driverMetricRecommendation.beforeMax', 'and')}\r\n <> \r\n change({ maxScore: e.currentTarget.valueAsNumber })} onBlur={() => validate('maxScore')} validationErrors={validationErrors['maxScore']} />\r\n <> \r\n {t('driverMetricRecommendation.afterMax', '')}\r\n
\r\n
\r\n
\r\n );\r\n};","import { ValidationErrors } from \"pojo-validator\";\r\nimport { useCallback, useMemo } from \"react\";\r\nimport { useTranslation } from \"react-i18next\";\r\nimport { Button, FormGroup, Label } from \"reactstrap\";\r\nimport { DriverMetric } from \"../../../../api/main/models/DriverMetric\";\r\nimport { DriverMetricAdjustment } from \"../../../../api/main/models/DriverMetricAdjustment\";\r\nimport { DriverMetricRecommendation, driverMetricRecommendationDefaultValues } from \"../../../../api/main/models/DriverMetricRecommendation\";\r\nimport { Question } from \"../../../../api/main/models/Question\";\r\nimport { ModelArrayChanges } from \"../../../../shared/useChanges\";\r\nimport { DriverMetricRecommendationComponent } from \"./DriverMetricRecommendationComponent\";\r\n\r\nexport interface DriverMetricsTabProps {\r\n model: Question | undefined,\r\n\r\n driverMetricRecommendationsManager: ModelArrayChanges,\r\n driverMetricAdjustmentsManager: ModelArrayChanges,\r\n\r\n driverMetrics: Array,\r\n\r\n validateDriverMetricRecommendation: (model: DriverMetricRecommendation) => boolean,\r\n driverMetricRecommendationValidationErrors: (id: string) => ValidationErrors,\r\n\r\n validateDriverMetricAdjustment: (model: DriverMetricAdjustment) => boolean,\r\n driverMetricAdjustmentValidationErrors: (id: string) => ValidationErrors,\r\n}\r\n\r\n/**\r\n * Tab for maintaining driver metrics for a question.\r\n * @param props\r\n */\r\nexport const DriverMetricsTab = (props: DriverMetricsTabProps) => {\r\n const {\r\n model,\r\n\r\n driverMetricRecommendationsManager,\r\n //driverMetricAdjustmentsManager,\r\n driverMetrics,\r\n\r\n validateDriverMetricRecommendation,\r\n driverMetricRecommendationValidationErrors,\r\n\r\n //validateDriverMetricAdjustment,\r\n //driverMetricAdjustmentValidationErrors,\r\n } = props;\r\n\r\n const { t } = useTranslation();\r\n\r\n // Order the recommendations so they are shown based on their minimum score.\r\n const orderedRecommendations = useMemo(() => {\r\n let ret = [...driverMetricRecommendationsManager.model];\r\n\r\n // Sort by min score, then max score.\r\n ret.sort((a, b) => (a.minScore === b.minScore ? (a.maxScore === b.maxScore ? 0 : a.maxScore < b.maxScore ? -1 : 1) : a.minScore < b.minScore ? -1 : 1));\r\n\r\n return ret;\r\n }, [driverMetricRecommendationsManager.model]);\r\n\r\n // Adding of a recommendation.\r\n const addRecommendation = useCallback(() => {\r\n driverMetricRecommendationsManager.addFor({\r\n ...driverMetricRecommendationDefaultValues(),\r\n\r\n targetId: model?.id,\r\n targetType: 'Question',\r\n });\r\n }, [driverMetricRecommendationsManager, model?.id]);\r\n\r\n //// Order the adjustments so they are shown based on their minimum score.\r\n //const orderedAdjustments = useMemo(() => {\r\n // let ret = [...driverMetricAdjustmentsManager.model];\r\n\r\n // // Sort by min score, then max score.\r\n // ret.sort((a, b) => (a.minScore === b.minScore ? (a.maxScore === b.maxScore? 0: a.maxScore < b.maxScore? -1: 1) : a.minScore < b.minScore ? -1 : 1));\r\n\r\n // return ret;\r\n //}, [driverMetricAdjustmentsManager.model]);\r\n\r\n //// Adding of an adjustment.\r\n //const addAdjustment = useCallback(() => {\r\n // driverMetricAdjustmentsManager.addFor({\r\n // ...driverMetricAdjustmentDefaultValues(),\r\n\r\n // targetId: model?.id,\r\n // targetType: 'Question',\r\n // });\r\n //}, [driverMetricAdjustmentsManager, model?.id]);\r\n\r\n \r\n return (\r\n <>\r\n \r\n \r\n\r\n
\r\n {\r\n orderedRecommendations.map(item => (\r\n driverMetricRecommendationsManager.changeFor(item.id, changes)}\r\n remove={() => driverMetricRecommendationsManager.removeFor(item.id)}\r\n driverMetrics={driverMetrics}\r\n validate={() => validateDriverMetricRecommendation(item)}\r\n validationErrors={driverMetricRecommendationValidationErrors(item.id)}\r\n />\r\n ))\r\n }\r\n
\r\n\r\n \r\n
\r\n\r\n {/* Driver metric adjustments have been removed form the UI in favour of using much simplier logic built around the primary driver metrics instead. */}\r\n {/*\r\n \r\n\r\n
\r\n {\r\n orderedAdjustments.map(item => (\r\n driverMetricAdjustmentsManager.changeFor(item.id, changes)}\r\n remove={() => driverMetricAdjustmentsManager.removeFor(item.id)}\r\n driverMetrics={driverMetrics}\r\n validate={() => validateDriverMetricAdjustment(item)}\r\n validationErrors={driverMetricAdjustmentValidationErrors(item.id)}\r\n />\r\n ))\r\n }\r\n
\r\n\r\n \r\n
*/}\r\n \r\n );\r\n};","import { FontAwesomeIcon } from \"@fortawesome/react-fontawesome\";\r\nimport { ValidationErrors } from \"pojo-validator\";\r\nimport { ValidateCallback } from \"pojo-validator-react\";\r\nimport { ValidatedInput } from \"pojo-validator-reactstrap\";\r\nimport { useCallback } from \"react\";\r\nimport { useTranslation } from \"react-i18next\";\r\nimport { useAsyncCallback } from \"react-use-async-callback\";\r\nimport { Button, ButtonGroup, Card, CardBody, Col, Collapse, Dropdown, DropdownItem, DropdownMenu, DropdownToggle, FormGroup, FormText, InputGroup, InputGroupAddon, Label, Row, Spinner} from \"reactstrap\";\r\nimport { useToggleState } from \"use-toggle-state\";\r\nimport { BlobReference } from \"../../../../api/main/models/BlobReference\";\r\nimport { QuestionAnswer } from \"../../../../api/main/models/QuestionAnswer\";\r\nimport { HtmlDisplay, HtmlEditor } from \"../../../../shared/htmlEditor\";\r\nimport { CardHeaderCollapse } from \"../../../shared/cardHeaderCollapse/CardHeaderCollapse\";\r\nimport { FileUploadButton } from \"../../../shared/fileUploadButton/FileUploadButton\";\r\nimport { FormButtons } from \"../../../shared/FormButtons\";\r\nimport { UploadedImagePreview } from \"../../../shared/uploadedImagePreview/UploadedImagePreview\";\r\nimport { TwoValueSwitch } from \"../../../shared/TwoValueSwitch\";\r\nimport { ConditionalFragment } from \"react-conditionalfragment\";\r\n\r\nexport interface QuestionAnswerSlidingScaleVideoProps {\r\n model: QuestionAnswer | undefined,\r\n change: (changes: Partial) => void,\r\n remove: () => void,\r\n moveUp: () => void,\r\n canMoveUp: boolean,\r\n moveDown: () => void,\r\n canMoveDown: boolean,\r\n\r\n answerTextImageBlob: BlobReference | undefined | null,\r\n uploadChildBlob: (files: FileList | null) => Promise,\r\n\r\n isOpenInitially?: boolean,\r\n\r\n validate: ValidateCallback,\r\n validationErrors: ValidationErrors,\r\n}\r\n\r\n/**\r\n * Answer on the scale for SlidingScaleVideo questions.\r\n * @param props\r\n */\r\nexport const QuestionAnswerSlidingScaleVideo = (props: QuestionAnswerSlidingScaleVideoProps) => {\r\n const {\r\n model,\r\n change,\r\n remove,\r\n moveUp,\r\n canMoveUp,\r\n moveDown,\r\n canMoveDown,\r\n\r\n answerTextImageBlob,\r\n uploadChildBlob,\r\n isOpenInitially = false,\r\n\r\n validate,\r\n validationErrors,\r\n } = props;\r\n\r\n const { t } = useTranslation();\r\n\r\n // Self management of if we are expanded or not.\r\n const [isOpen, toggleOpen] = useToggleState(isOpenInitially);\r\n\r\n // Uploading the answer text blob.\r\n const [uploadAnswerTextImageBlob, { isExecuting: isUploadingAnswerTextImageBlob }] = useAsyncCallback(async (files: FileList | null) => {\r\n const blob = await uploadChildBlob(files);\r\n if (!blob) {\r\n return;\r\n }\r\n\r\n change({ answerTextImageBlobReferenceId: blob.id });\r\n }, [uploadChildBlob, change]);\r\n const clearAnswerTextImageBlob = useCallback(() => {\r\n change({ answerTextImageBlobReferenceId: null });\r\n }, [change]);\r\n const [isAnswerImageDropdownOpen, toggleAnswerImageDropdown] = useToggleState();\r\n\r\n return (\r\n \r\n \r\n
\r\n \r\n
\r\n
\r\n\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n\r\n \r\n \r\n change({ answerText: html })} />\r\n \r\n\r\n \r\n {/**/}\r\n {/* */}\r\n {/* */}\r\n\r\n {/* {*/}\r\n {/* // Toggle the flag, and if we're using default scoring at the moment, also default the score.*/}\r\n {/* if (checked && model?.score === 0) {*/}\r\n {/* change({ isCorrect: checked, score: 10 });*/}\r\n {/* } else if (!checked && model?.score === 10) {*/}\r\n {/* change({ isCorrect: checked, score: 0 });*/}\r\n {/* } else {*/}\r\n {/* change({ isCorrect: checked });*/}\r\n {/* }*/}\r\n {/* }}*/}\r\n {/* />*/}\r\n {/* */}\r\n {/**/}\r\n \r\n \r\n \r\n\r\n \r\n change({ score: e.currentTarget.valueAsNumber })} onBlur={() => validate('score')} validationErrors={validationErrors['score']} />\r\n \r\n {t('common.percentageSign', '%')}\r\n \r\n \r\n \r\n {t('questionAnswerSlidingScaleVideo.score.help', 'Score will normally be between 0% (incorrect) and 100% (correct).')}\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n\r\n {\r\n // Toggle the flag\r\n change({ isSuspicious: checked });\r\n if (checked) {\r\n change({ suspicionScore: 1 }); // If we are setting the answer to suspicious, we want to have a suspicion score, so setting this to 1 as default.\r\n } else {\r\n change({ suspicionScore: undefined }); // If we are setting the answer to not suspicious, we no longer need a suspicion score, so we can set this to undefined.\r\n }\r\n }}\r\n />\r\n \r\n \r\n \r\n \r\n \r\n \r\n\r\n \r\n change({ suspicionScore: e.currentTarget.valueAsNumber })} onBlur={() => validate('suspicionScore')} validationErrors={validationErrors['suspicionScore']} />\r\n \r\n \r\n {t('questionAnswerMultipleChoiceVideo.suspicionScore.help', 'At the end of an assessment, any selected suspicious answers will have their suspicion scores added together to see if they exceed the limit set on the assessment.')}\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n\r\n \r\n\r\n \r\n uploadAnswerTextImageBlob(files)} isExecuting={isUploadingAnswerTextImageBlob}\r\n executingChildren={<><> {t('common.uploading', 'Uploading...')}}\r\n >\r\n {t('questionAnswerSlidingScaleVideo.uploadImage', 'Upload image...')}\r\n \r\n toggleAnswerImageDropdown()}>\r\n \r\n \r\n {t('common.more', 'More')}\r\n \r\n \r\n \r\n clearAnswerTextImageBlob()}>\r\n {t('questionAnswerSlidingScaleVideo.clearImage', 'Clear image')}\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n
\r\n );\r\n};","import Slider from \"rc-slider\";\r\nimport { ReactNode, useCallback, useMemo } from \"react\";\r\nimport { QuestionAnswer } from \"../../../../api/main/models/QuestionAnswer\";\r\nimport { HtmlDisplay } from \"../../../../shared/htmlEditor\";\r\nimport \"./slidingScaleSlider.scss\";\r\n\r\nexport interface SlidingScaleSliderProps {\r\n answers: Array,\r\n\r\n selectedAnswerId?: string | undefined,\r\n onSelectedAnswerChanged?: (answer: QuestionAnswer | undefined) => void,\r\n}\r\n\r\n/**\r\n * Slider that shows the answers for SlidingScaleVideo questions.\r\n * @param props\r\n */\r\nexport const SlidingScaleSlider = (props: SlidingScaleSliderProps) => {\r\n const {\r\n answers,\r\n selectedAnswerId,\r\n onSelectedAnswerChanged,\r\n } = props;\r\n\r\n const { min, max, marks } = useMemo(() => {\r\n let marks: { [key: number]: ReactNode } = {};\r\n\r\n // Add an entry for each answer.\r\n for (let i = 0; i < answers.length; ++i) {\r\n const answer = answers[i];\r\n marks[i] = ;\r\n }\r\n\r\n // If we need to, add a fake starting answer to make sure we have one.\r\n if (answers.length <= 0) {\r\n marks[0] = (<>);\r\n }\r\n\r\n // If we need to, add a fake ending answer to make sure we always have one.\r\n if (answers.length <= 1) {\r\n marks[1] = (<>);\r\n }\r\n\r\n return {\r\n min: 0,\r\n max: answers.length < 2 ? 1 : answers.length - 1,\r\n marks: marks,\r\n };\r\n }, [answers]);\r\n\r\n const defaultValue = Math.floor((max - min) / 2);\r\n const selectedAnswerIndex = useMemo(() => {\r\n if (!selectedAnswerId) {\r\n return undefined;\r\n }\r\n\r\n const selected = answers.find(item => item.id === selectedAnswerId);\r\n if (!selected) {\r\n return undefined;\r\n }\r\n\r\n return answers.indexOf(selected);\r\n }, [answers, selectedAnswerId]);\r\n // Select an answer by index.\r\n const onSelectedAnswerIndexChanged = useCallback((index: number) => {\r\n // If we have no callback wanting to handle the event, do nothing.\r\n if (!onSelectedAnswerChanged) {\r\n return;\r\n }\r\n\r\n // If we are out of bounds, unselect an answer.\r\n if (index < 0 || index > answers.length) {\r\n onSelectedAnswerChanged(undefined);\r\n }\r\n\r\n // We have selected an actual answer.\r\n const selectedAnswer = answers[index];\r\n onSelectedAnswerChanged(selectedAnswer);\r\n }, [answers, onSelectedAnswerChanged]);\r\n\r\n return (\r\n
\r\n onSelectedAnswerIndexChanged(index)}\r\n />\r\n
\r\n );\r\n};","import { useCallback } from \"react\";\r\nimport { useTranslation } from \"react-i18next\";\r\nimport { Button, ButtonGroup, Dropdown, DropdownItem, DropdownMenu, DropdownToggle, FormGroup, Label, Spinner } from \"reactstrap\";\r\nimport { BlobReference } from \"../../../../api/main/models/BlobReference\";\r\nimport { Question } from \"../../../../api/main/models/Question\";\r\nimport { QuestionAnswer, questionAnswerDefaultValues } from \"../../../../api/main/models/QuestionAnswer\";\r\nimport { HtmlEditor } from \"../../../../shared/htmlEditor\";\r\nimport { ModelArrayChanges } from \"../../../../shared/useChanges\";\r\nimport { FileUploadButton } from \"../../../shared/fileUploadButton/FileUploadButton\";\r\nimport { UploadedImagePreview } from \"../../../shared/uploadedImagePreview/UploadedImagePreview\";\r\nimport { QuestionAnswerSlidingScaleVideo } from \"./QuestionAnswerSlidingScaleVideo\";\r\nimport { useDisplayOrder } from \"../../../shared/useDisplayOrder/useDisplayOrder\";\r\nimport { useToggleState } from \"use-toggle-state\";\r\nimport { ValidationErrors } from \"pojo-validator\";\r\nimport { SlidingScaleSlider } from \"./SlidingScaleSlider\";\r\n\r\nexport interface QuestionPromptSlidingScaleVideoTabProps {\r\n model: Question | undefined,\r\n change: (changes: Partial) => void,\r\n\r\n questionTextImageBlob: BlobReference | undefined | null,\r\n uploadQuestionTextImageBlob: (files: FileList | null) => void,\r\n isUploadingQuestionTextImageBlob: boolean,\r\n clearQuestionTextImageBlob: () => void,\r\n\r\n answersManager: ModelArrayChanges,\r\n\r\n childBlobs: Array,\r\n uploadChildBlob: (files: FileList | null) => Promise,\r\n\r\n validateQuestionAnswer: (model: QuestionAnswer) => boolean,\r\n questionAnswerValidationErrors: (id: string) => ValidationErrors,\r\n}\r\n\r\n/**\r\n * Tab for maintaining the prompt and scale answers for SlidingScaleVideo questions.\r\n * @param props\r\n */\r\nexport const QuestionPromptSlidingScaleVideoTab = (props: QuestionPromptSlidingScaleVideoTabProps) => {\r\n const {\r\n model,\r\n change,\r\n\r\n questionTextImageBlob, uploadQuestionTextImageBlob, isUploadingQuestionTextImageBlob, clearQuestionTextImageBlob,\r\n answersManager,\r\n childBlobs,\r\n uploadChildBlob,\r\n\r\n validateQuestionAnswer,\r\n questionAnswerValidationErrors,\r\n } = props;\r\n\r\n const { t } = useTranslation();\r\n\r\n // Order the answers so they show in and can be managed by displayOrder.\r\n const [orderedAnswers, {\r\n canMoveUp: canMoveAnswerUp,\r\n moveUp: moveAnswerUp,\r\n canMoveDown: canMoveAnswerDown,\r\n moveDown: moveAnswerDown,\r\n }] = useDisplayOrder(answersManager);\r\n \r\n\r\n // Adding of an answer.\r\n const addAnswer = useCallback(() => {\r\n answersManager.addFor({\r\n ...questionAnswerDefaultValues(),\r\n\r\n questionId: model?.id,\r\n });\r\n }, [answersManager, model?.id]);\r\n\r\n const [isQuestionTextImageDropdownOpen, toggleQuestionTextImageDropdown] = useToggleState();\r\n\r\n return (\r\n <>\r\n \r\n \r\n\r\n change({ preQuestionText: html })} />\r\n \r\n \r\n \r\n\r\n change({ questionText: html })} />\r\n \r\n \r\n \r\n\r\n \r\n\r\n \r\n uploadQuestionTextImageBlob(files)} isExecuting={isUploadingQuestionTextImageBlob}\r\n executingChildren={<><> {t('common.uploading', 'Uploading...')}}\r\n >\r\n {t('questionPromptSlidingScaleVideoTab.uploadPromotionalImage', 'Upload image...')}\r\n \r\n toggleQuestionTextImageDropdown()}>\r\n \r\n \r\n {t('common.more', 'More')}\r\n \r\n \r\n \r\n clearQuestionTextImageBlob()}>\r\n {t('questionPromptSlidingScaleVideoTab.clearImage', 'Clear image')}\r\n \r\n \r\n \r\n \r\n \r\n\r\n \r\n \r\n\r\n
\r\n \r\n
\r\n\r\n
\r\n {\r\n orderedAnswers.map(item => (\r\n answersManager.changeFor(item.id, changes)}\r\n remove={() => answersManager.removeFor(item.id)}\r\n\r\n isOpenInitially={!!answersManager.added.find(it => it.id === item.id)}\r\n\r\n moveUp={() => moveAnswerUp(item.id)} canMoveUp={canMoveAnswerUp(item.id)}\r\n moveDown={() => moveAnswerDown(item.id)} canMoveDown={canMoveAnswerDown(item.id)}\r\n\r\n answerTextImageBlob={childBlobs.find(it => it.id === item.answerTextImageBlobReferenceId)}\r\n uploadChildBlob={uploadChildBlob}\r\n\r\n validate={() => validateQuestionAnswer(item)}\r\n validationErrors={questionAnswerValidationErrors(item.id)}\r\n />\r\n ))\r\n }\r\n
\r\n\r\n \r\n
\r\n \r\n );\r\n};","/**\r\n * Returns a useful formatted time string from the milliseconds passed in.\r\n * @param milliseconds\r\n */\r\nexport function timeStringFromSeconds(seconds: number) {\r\n let minutes = Math.floor(seconds / 60);\r\n let hours = Math.floor(minutes / 60);\r\n minutes = minutes % 60;\r\n\r\n const wholeSeconds = Math.floor(seconds % 60);\r\n const milliseconds = ((seconds % 60) - wholeSeconds);\r\n\r\n const ret = `${hours.toString().padStart(2, '0')}:${minutes.toString().padStart(2, '0')}:${wholeSeconds.toString().padStart(2, '0')}.${milliseconds.toString().substr(2, 4).padStart(4, '0')}`;\r\n return ret;\r\n}","import { FontAwesomeIcon } from \"@fortawesome/react-fontawesome\";\r\nimport { ValidationErrors } from \"pojo-validator\";\r\nimport { ValidateCallback } from \"pojo-validator-react\";\r\nimport { ValidatedInput } from \"pojo-validator-reactstrap\";\r\nimport { MutableRefObject, useMemo } from \"react\";\r\nimport { ConditionalFragment } from \"react-conditionalfragment\";\r\nimport { useTranslation } from \"react-i18next\";\r\nimport { Button, ButtonGroup, Card, CardBody, Col, Collapse, FormGroup, FormText, Input, InputGroup, InputGroupAddon, Label, Row } from \"reactstrap\";\r\nimport { useToggleState } from \"use-toggle-state\";\r\nimport { QuestionAnswer } from \"../../../../api/main/models/QuestionAnswer\";\r\nimport { HtmlDisplay, HtmlEditor } from \"../../../../shared/htmlEditor\";\r\nimport { timeStringFromSeconds } from \"../../../../utilities/timeStringFromSeconds\";\r\nimport { CardHeaderCollapse } from \"../../../shared/cardHeaderCollapse/CardHeaderCollapse\";\r\nimport { FormButtons } from \"../../../shared/FormButtons\";\r\n\r\nexport interface QuestionAnswerResponseTimeVideoProps {\r\n model: QuestionAnswer | undefined,\r\n change: (changes: Partial) => void,\r\n remove: () => void,\r\n moveUp: () => void,\r\n canMoveUp: boolean,\r\n moveDown: () => void,\r\n canMoveDown: boolean,\r\n\r\n isOpenInitially?: boolean,\r\n\r\n validate: ValidateCallback,\r\n validationErrors: ValidationErrors,\r\n\r\n currentVideoTime: MutableRefObject,\r\n\r\n numberOfSubQuestions: number,\r\n}\r\n\r\n/**\r\n * Response time window for ResponseTimeVideo questions.\r\n * @param props\r\n */\r\nexport const QuestionAnswerResponseTimeVideo = (props: QuestionAnswerResponseTimeVideoProps) => {\r\n const {\r\n model,\r\n change,\r\n remove,\r\n moveUp,\r\n canMoveUp,\r\n moveDown,\r\n canMoveDown,\r\n\r\n isOpenInitially = false,\r\n\r\n validate,\r\n validationErrors,\r\n\r\n currentVideoTime,\r\n\r\n numberOfSubQuestions,\r\n } = props;\r\n\r\n const { t } = useTranslation();\r\n\r\n // Self management of if we are expanded or not.\r\n const [isOpen, toggleOpen] = useToggleState(isOpenInitially);\r\n\r\n const startTimeString = useMemo(() => timeStringFromSeconds(model?.startResponseTimeSeconds ?? 0), [model?.startResponseTimeSeconds]);\r\n const endTimeString = useMemo(() => timeStringFromSeconds(model?.endResponseTimeSeconds ?? 0), [model?.endResponseTimeSeconds]);\r\n\r\n return (\r\n \r\n \r\n \r\n \r\n {t('questionAnswerResponseTimeVideo.heading', '{{startTimeString}} to {{endTimeString}}', { startTimeString, endTimeString })}\r\n \r\n \r\n
\r\n \r\n
\r\n \r\n 1 || (model?.subQuestionNumber ?? 1) > 1}>\r\n \r\n {t('questionAnswerResponseTimeVideo.responseGroupHeading', 'Part {{subQuestionNumber}}', { subQuestionNumber: model?.subQuestionNumber ?? 1 })}\r\n \r\n \r\n
\r\n
\r\n\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n\r\n 1 || (model?.subQuestionNumber ?? 1) > 1}>\r\n \r\n \r\n\r\n change({ subQuestionNumber: e.currentTarget.valueAsNumber })} />\r\n \r\n \r\n\r\n \r\n \r\n \r\n \r\n\r\n \r\n change({ startResponseTimeSeconds: e.currentTarget.valueAsNumber / 1000 })} />\r\n \r\n {t('questionAnswerResponseTimeVideo.ms', 'ms')}\r\n \r\n \r\n \r\n \r\n \r\n \r\n {startTimeString}\r\n \r\n \r\n \r\n \r\n \r\n \r\n\r\n \r\n change({ endResponseTimeSeconds: e.currentTarget.valueAsNumber / 1000 })} />\r\n \r\n {t('questionAnswerResponseTimeVideo.ms', 'ms')}\r\n \r\n \r\n \r\n \r\n \r\n \r\n {endTimeString}\r\n \r\n \r\n \r\n \r\n \r\n\r\n \r\n \r\n change({ answerText: html })} />\r\n \r\n\r\n \r\n {/**/}\r\n {/* */}\r\n {/* */}\r\n\r\n {/* {*/}\r\n {/* // Toggle the flag, and if we're using default scoring at the moment, also default the score.*/}\r\n {/* if (checked && model?.score === 0) {*/}\r\n {/* change({ isCorrect: checked, score: 10 });*/}\r\n {/* } else if (!checked && model?.score === 10) {*/}\r\n {/* change({ isCorrect: checked, score: 0 });*/}\r\n {/* } else {*/}\r\n {/* change({ isCorrect: checked });*/}\r\n {/* }*/}\r\n {/* }}*/}\r\n {/* />*/}\r\n {/* */}\r\n {/**/}\r\n \r\n \r\n \r\n\r\n \r\n change({ score: e.currentTarget.valueAsNumber })} onBlur={() => validate('score')} validationErrors={validationErrors['score']} />\r\n \r\n {t('common.percentageSign', '%')}\r\n \r\n \r\n \r\n {t('questionAnswerResponseTimeVideo.score.help', 'Score will normally be between 0% (incorrect) and 100% (correct).')}\r\n \r\n \r\n \r\n \r\n \r\n \r\n
\r\n );\r\n};","import { useCallback, useRef } from \"react\";\r\nimport { useTranslation } from \"react-i18next\";\r\nimport { Button, FormGroup, FormText, Label, Input } from \"reactstrap\";\r\nimport { BlobReference } from \"../../../../api/main/models/BlobReference\";\r\nimport { Question } from \"../../../../api/main/models/Question\";\r\nimport { QuestionAnswer, questionAnswerDefaultValues } from \"../../../../api/main/models/QuestionAnswer\";\r\nimport { HtmlEditor } from \"../../../../shared/htmlEditor\";\r\nimport { ModelArrayChanges } from \"../../../../shared/useChanges\";\r\nimport { QuestionAnswerResponseTimeVideo } from \"./QuestionAnswerResponseTimeVideo\";\r\nimport { useDisplayOrder } from \"../../../shared/useDisplayOrder/useDisplayOrder\";\r\nimport { ValidationErrors } from \"pojo-validator\";\r\nimport { UploadedVideoPreview } from \"../../../shared/uploadedVideoPreview/UploadedVideoPreview\";\r\n\r\nexport interface QuestionPromptResponseTimeVideoTabProps {\r\n model: Question | undefined,\r\n change: (changes: Partial) => void,\r\n\r\n videoBlob: BlobReference | undefined | null,\r\n imageBlob: BlobReference | undefined | null,\r\n\r\n answersManager: ModelArrayChanges,\r\n\r\n validateQuestionAnswer: (model: QuestionAnswer) => boolean,\r\n questionAnswerValidationErrors: (id: string) => ValidationErrors,\r\n}\r\n\r\n/**\r\n * Tab for maintaining the prompt and response time windows for ResponseTimeVideo questions.\r\n * @param props\r\n */\r\nexport const QuestionPromptResponseTimeVideoTab = (props: QuestionPromptResponseTimeVideoTabProps) => {\r\n const {\r\n model,\r\n change,\r\n\r\n videoBlob,\r\n imageBlob,\r\n\r\n answersManager,\r\n\r\n validateQuestionAnswer,\r\n questionAnswerValidationErrors,\r\n } = props;\r\n\r\n const { t } = useTranslation();\r\n\r\n // Order the answers so they show in and can be managed by displayOrder.\r\n const [orderedAnswers, {\r\n canMoveUp: canMoveAnswerUp,\r\n moveUp: moveAnswerUp,\r\n canMoveDown: canMoveAnswerDown,\r\n moveDown: moveAnswerDown,\r\n }] = useDisplayOrder(answersManager);\r\n\r\n // Video playback tracking.\r\n const currentVideoTime = useRef(0);\r\n\r\n // Adding of an answer.\r\n const addAnswer = useCallback(() => {\r\n answersManager.addFor({\r\n ...questionAnswerDefaultValues(),\r\n\r\n questionId: model?.id,\r\n startResponseTimeSeconds: currentVideoTime.current,\r\n endResponseTimeSeconds: currentVideoTime.current,\r\n });\r\n }, [answersManager, model?.id]);\r\n\r\n return (\r\n <>\r\n \r\n \r\n\r\n change({ preQuestionText: html })} />\r\n \r\n\r\n \r\n \r\n\r\n change({ questionText: html })} />\r\n \r\n\r\n \r\n \r\n\r\n { currentVideoTime.current = e.currentTarget.currentTime; }} />\r\n \r\n {t('questionPromptResponseTimeVideoTab.videoPlaybackText', 'Playback or select a time within the video to add or update response windows.')}\r\n \r\n\r\n \r\n \r\n\r\n {\r\n const value = e.currentTarget.valueAsNumber;\r\n let maxScore = value * 100;\r\n if (maxScore < 0) { maxScore = 0; }\r\n\r\n change({\r\n numberOfSubQuestions: value,\r\n maxScore: maxScore,\r\n });\r\n }}\r\n />\r\n \r\n\r\n
\r\n {\r\n orderedAnswers.map(item => (\r\n answersManager.changeFor(item.id, changes)}\r\n remove={() => answersManager.removeFor(item.id)}\r\n\r\n isOpenInitially={!!answersManager.added.find(it => it.id === item.id)}\r\n\r\n moveUp={() => moveAnswerUp(item.id)} canMoveUp={canMoveAnswerUp(item.id)}\r\n moveDown={() => moveAnswerDown(item.id)} canMoveDown={canMoveAnswerDown(item.id)}\r\n\r\n validate={() => validateQuestionAnswer(item)}\r\n validationErrors={questionAnswerValidationErrors(item.id)}\r\n\r\n currentVideoTime={currentVideoTime}\r\n numberOfSubQuestions={model?.numberOfSubQuestions ?? 0}\r\n />\r\n ))\r\n }\r\n
\r\n\r\n \r\n
\r\n\r\n \r\n \r\n change({ maximumClicks: e.currentTarget.valueAsNumber })} />\r\n \r\n \r\n );\r\n};","import { ConditionalFragment } from \"react-conditionalfragment\";\r\nimport { useTranslation } from \"react-i18next\";\r\nimport { ButtonGroup, Dropdown, DropdownItem, DropdownMenu, DropdownToggle, FormGroup, Input, Label, Spinner } from \"reactstrap\";\r\nimport { useToggleState } from \"use-toggle-state\";\r\nimport { BlobReference } from \"../../../../api/main/models/BlobReference\";\r\nimport { QuestionType } from \"../../../../api/main/models/codeOnly/QuestionType\";\r\nimport { Question } from \"../../../../api/main/models/Question\";\r\nimport { FileUploadButton } from \"../../../shared/fileUploadButton/FileUploadButton\";\r\nimport { UploadedImagePreview } from \"../../../shared/uploadedImagePreview/UploadedImagePreview\";\r\n\r\nexport interface ImageTabProps {\r\n model: Question | undefined,\r\n change: (changes: Partial) => void,\r\n activeQuestionType: QuestionType,\r\n\r\n imageBlob: BlobReference | undefined | null,\r\n uploadImageBlob: (files: FileList | null) => void,\r\n isUploadingImageBlob: boolean,\r\n clearImageBlob: () => void,\r\n\r\n}\r\n\r\n/**\r\n * Image upload tab for EditQuestion.\r\n * @param props\r\n */\r\nexport const ImageTab = (props: ImageTabProps) => {\r\n const {\r\n model,\r\n change,\r\n activeQuestionType,\r\n imageBlob, uploadImageBlob, isUploadingImageBlob, clearImageBlob,\r\n } = props;\r\n\r\n const { t } = useTranslation();\r\n\r\n const [isImageDropdownOpen, toggleImageDropdown] = useToggleState();\r\n\r\n return (\r\n <>\r\n \r\n \r\n\r\n \r\n\r\n \r\n uploadImageBlob(files)} isExecuting={isUploadingImageBlob}\r\n executingChildren={<><> {t('common.uploading', 'Uploading...')}}\r\n >\r\n {t('editCalendarEvent.uploadImageImage', 'Upload image...')}\r\n \r\n\r\n toggleImageDropdown()}>\r\n \r\n \r\n {t('common.more', 'More')}\r\n \r\n \r\n \r\n \r\n {t('editCalendarHeadline.clearImage', 'Clear image')}\r\n \r\n \r\n \r\n \r\n \r\n\r\n \r\n \r\n \r\n\r\n change({ timeLimitSeconds: e.currentTarget.valueAsNumber })} />\r\n \r\n \r\n \r\n );\r\n};","import { FontAwesomeIcon } from \"@fortawesome/react-fontawesome\";\r\nimport { ValidationErrors } from \"pojo-validator\";\r\nimport { ValidateCallback } from \"pojo-validator-react\";\r\nimport { ValidatedInput } from \"pojo-validator-reactstrap\";\r\nimport { useMemo } from \"react\";\r\nimport { useTranslation } from \"react-i18next\";\r\nimport { Button, ButtonGroup, Card, CardBody, Col, Collapse, FormGroup, FormText, InputGroup, InputGroupAddon, Input, Label, Row } from \"reactstrap\";\r\nimport { useToggleState } from \"use-toggle-state\";\r\nimport { QuestionAnswer } from \"../../../../api/main/models/QuestionAnswer\";\r\nimport { HtmlDisplay, HtmlEditor } from \"../../../../shared/htmlEditor\";\r\nimport { CardHeaderCollapse } from \"../../../shared/cardHeaderCollapse/CardHeaderCollapse\";\r\nimport { FormButtons } from \"../../../shared/FormButtons\";\r\n\r\nexport interface QuestionAnswerLocationResponseImageProps {\r\n model: QuestionAnswer | undefined,\r\n change: (changes: Partial) => void,\r\n remove: () => void,\r\n moveUp: () => void,\r\n canMoveUp: boolean,\r\n moveDown: () => void,\r\n canMoveDown: boolean,\r\n\r\n isOpenInitially?: boolean,\r\n\r\n validate: ValidateCallback,\r\n validationErrors: ValidationErrors,\r\n}\r\n\r\n/**\r\n * Response window for a LocationResponseImage question.\r\n * @param props\r\n */\r\nexport const QuestionAnswerLocationResponseImage = (props: QuestionAnswerLocationResponseImageProps) => {\r\n const {\r\n model,\r\n change,\r\n remove,\r\n moveUp,\r\n canMoveUp,\r\n moveDown,\r\n canMoveDown,\r\n\r\n isOpenInitially = false,\r\n\r\n validate,\r\n validationErrors,\r\n } = props;\r\n\r\n const { t } = useTranslation();\r\n\r\n // Self management of if we are expanded or not.\r\n const [isOpen, toggleOpen] = useToggleState(isOpenInitially);\r\n\r\n const locationString = useMemo(() => {\r\n if (!model) {\r\n return '';\r\n }\r\n\r\n return `${Math.round(model.windowTop)},${Math.round(model.windowLeft)} to ${Math.round(model.windowBottom)},${Math.round(model.windowRight)}`;\r\n }, [model]);\r\n\r\n return (\r\n \r\n \r\n \r\n \r\n {locationString}\r\n \r\n \r\n
\r\n \r\n
\r\n \r\n
\r\n
\r\n\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n\r\n \r\n \r\n \r\n \r\n\r\n change({ windowTop: e.currentTarget.valueAsNumber })} />\r\n \r\n \r\n \r\n \r\n \r\n\r\n change({ windowLeft: e.currentTarget.valueAsNumber })} />\r\n \r\n \r\n \r\n\r\n \r\n \r\n \r\n \r\n\r\n change({ windowBottom: e.currentTarget.valueAsNumber })} />\r\n \r\n \r\n \r\n \r\n \r\n\r\n change({ windowRight: e.currentTarget.valueAsNumber })} />\r\n \r\n \r\n \r\n \r\n\r\n \r\n \r\n change({ answerText: html })} />\r\n \r\n\r\n \r\n {/**/}\r\n {/* */}\r\n {/* */}\r\n\r\n {/* {*/}\r\n {/* // Toggle the flag, and if we're using default scoring at the moment, also default the score.*/}\r\n {/* if (checked && model?.score === 0) {*/}\r\n {/* change({ isCorrect: checked, score: 10 });*/}\r\n {/* } else if (!checked && model?.score === 10) {*/}\r\n {/* change({ isCorrect: checked, score: 0 });*/}\r\n {/* } else {*/}\r\n {/* change({ isCorrect: checked });*/}\r\n {/* }*/}\r\n {/* }}*/}\r\n {/* />*/}\r\n {/* */}\r\n {/**/}\r\n \r\n \r\n \r\n\r\n \r\n change({ score: e.currentTarget.valueAsNumber })} onBlur={() => validate('score')} validationErrors={validationErrors['score']} />\r\n \r\n {t('common.percentageSign', '%')}\r\n \r\n \r\n \r\n {t('questionAnswerMultipleChoiceVideo.score.help', 'Score will normally be between 0% (incorrect) and 100% (correct).')}\r\n \r\n \r\n \r\n \r\n \r\n \r\n
\r\n );\r\n};","import { useCallback, useEffect, useRef, useState } from \"react\";\r\nimport { ConditionalFragment } from \"react-conditionalfragment\";\r\nimport { Circle, Ellipse, Rect, Text, Transformer } from \"react-konva\";\r\nimport { OverlayShape } from \"./OverlayShape\";\r\n\r\nexport interface ResizableReactangleProps {\r\n shapeProps: OverlayShape,\r\n isSelected: boolean,\r\n onSelect: () => void,\r\n onChange: (newAttrs: any) => void,\r\n allowTransform: boolean,\r\n}\r\n\r\nexport const ResizableOverlay = (props: ResizableReactangleProps) => {\r\n const {\r\n shapeProps,\r\n isSelected: _isSelected,\r\n onSelect,\r\n onChange,\r\n allowTransform,\r\n } = props;\r\n\r\n const isSelected = allowTransform && _isSelected;\r\n\r\n const shapeRef = useRef();\r\n const trRef = useRef();\r\n\r\n useEffect(() => {\r\n if (isSelected) {\r\n if (!trRef.current) {\r\n return;\r\n }\r\n\r\n // we need to attach transformer manually\r\n trRef.current.nodes([shapeRef.current]);\r\n trRef.current.getLayer().batchDraw();\r\n }\r\n }, [isSelected]);\r\n\r\n const onDragEnd = useCallback((e: { target: { x: () => number, y: () => number } }) => {\r\n onChange({\r\n ...shapeProps,\r\n x: e.target.x(),\r\n y: e.target.y(),\r\n });\r\n }, [onChange, shapeProps]);\r\n\r\n const onTransformEnd = useCallback(() => {\r\n // transformer is changing scale of the node\r\n // and NOT its width or height\r\n // but in the store we have only width and height\r\n // to match the data better we will reset scale on transform end\r\n const node = shapeRef.current;\r\n if (!node) {\r\n return;\r\n }\r\n\r\n const scaleX = node.scaleX();\r\n const scaleY = node.scaleY();\r\n\r\n // we will reset it back\r\n node.scaleX(1);\r\n node.scaleY(1);\r\n\r\n onChange({\r\n ...shapeProps,\r\n x: node.x(),\r\n y: node.y(),\r\n // set minimal value\r\n width: Math.max(5, node.width() * scaleX),\r\n height: Math.max(node.height() * scaleY),\r\n });\r\n }, [onChange, shapeProps]);\r\n\r\n // TODO support types other than Rect.\r\n const [textHiddenByAction, setTextHiddenByAction] = useState(false);\r\n const [textHiddenByMouse, setTextHiddenByMouse] = useState(false);\r\n const textHidden = textHiddenByAction || textHiddenByMouse;\r\n\r\n return (\r\n <>\r\n \r\n setTextHiddenByAction(true)}\r\n onDragEnd={e => { setTextHiddenByAction(false); onDragEnd(e); }}\r\n onMouseEnter={() => setTextHiddenByMouse(true)}\r\n onMouseLeave={() => setTextHiddenByMouse(false)}\r\n onTransformEnd={onTransformEnd}\r\n />\r\n \r\n \r\n setTextHiddenByAction(true)}\r\n onDragEnd={e => { setTextHiddenByAction(false); onDragEnd(e); }}\r\n onMouseEnter={() => setTextHiddenByMouse(true)}\r\n onMouseLeave={() => setTextHiddenByMouse(false)}\r\n onTransformEnd={onTransformEnd}\r\n />\r\n \r\n \r\n setTextHiddenByAction(true)}\r\n onDragEnd={e => { setTextHiddenByAction(false); onDragEnd(e); } }\r\n onMouseEnter={() => setTextHiddenByMouse(true)}\r\n onMouseLeave={() => setTextHiddenByMouse(false)}\r\n onTransformEnd={onTransformEnd} />\r\n \r\n setTextHiddenByMouse(true)}\r\n visible={!textHidden}\r\n\r\n />\r\n {isSelected && (\r\n {\r\n // limit resize\r\n if (newBox.width < 5 || newBox.height < 5) {\r\n return oldBox;\r\n }\r\n return newBox;\r\n }}\r\n onTransformStart={() => setTextHiddenByAction(true)}\r\n onTransformEnd={() => setTextHiddenByAction(false)}\r\n />\r\n )}\r\n \r\n );\r\n};\r\n","import { KonvaEventObject } from \"konva/lib/Node\";\r\nimport { useCallback, useEffect, useMemo, useRef, useState } from \"react\";\r\nimport { Stage, Layer } from \"react-konva\";\r\nimport \"./interactiveImage.scss\";\r\nimport { OverlayShape, OverlayShapeType } from \"./OverlayShape\";\r\nimport { ResizableOverlay } from \"./ResizableOverlay\";\r\n\r\nexport type PointConversion = (point: { x: number, y: number }) => { x: number, y: number };\r\n\r\nexport interface InteractiveImageProps {\r\n src: string | undefined,\r\n overlays: Array,\r\n onOverlayTransformed?: (id: string, shapeProps: OverlayShape, conversions: { displayToVirtual: PointConversion, virtualToDisplay: PointConversion }) => void,\r\n onAddOverlay?: (shapeProps: Partial, conversions: { displayToVirtual: PointConversion, virtualToDisplay: PointConversion }) => OverlayShape,\r\n allowAdd?: boolean\r\n addOverlayShapeType?: OverlayShapeType,\r\n onShapeClicked?: (shapeProps: OverlayShape, conversions: { displayToVirtual: PointConversion, virtualToDisplay: PointConversion }) => void,\r\n\r\n virtualSize?: { width: number, height: number },\r\n allowTransform?: boolean,\r\n\r\n onVirtualConversionChanged?: (conversions: { displayToVirtual: PointConversion, virtualToDisplay: PointConversion }) => void,\r\n}\r\n\r\n/**\r\n * An image that can be interacted with by the user.\r\n * @param props\r\n */\r\nexport const InteractiveImage = (props: InteractiveImageProps) => {\r\n const {\r\n src,\r\n overlays: _overlays,\r\n onOverlayTransformed: _onOverlayTransformed,\r\n onAddOverlay: _onAddOverlay,\r\n allowAdd = false,\r\n addOverlayShapeType = 'rect',\r\n allowTransform = false,\r\n onShapeClicked,\r\n onVirtualConversionChanged,\r\n } = props;\r\n\r\n const divRef = useRef(null);\r\n const [selectedId, _selectShape] = useState(null);\r\n\r\n const [_virtualSize, setVirtualSize] = useState<{ width: number, height: number } | undefined>();\r\n const virtualSize = useMemo(() => _virtualSize ?? { width: 1920, height: 1080 } /* Use 1080p HD as a default */, [_virtualSize]);\r\n const needToCalculateVirtualSize = !_virtualSize;\r\n\r\n // Convert a virtual display location/size to a screen location/size.\r\n const virtualToDisplay = useCallback((point: { x: number, y: number }) => {\r\n // If we don't have a current display area then do nothing.\r\n if (!divRef.current) {\r\n return point;\r\n }\r\n\r\n return {\r\n x: ((point?.x ?? 0) / virtualSize.width) * (divRef.current?.clientWidth ?? 1),\r\n y: ((point?.y ?? 0) / virtualSize.height) * (divRef.current?.clientHeight ?? 1),\r\n };\r\n }, [virtualSize, divRef]);\r\n\r\n // Convert a screen location/size to a virtual location/size.\r\n const displayToVirtual = useCallback((point: { x: number, y: number }) => {\r\n // If we don't have a current display area then do nothing.\r\n if (!divRef.current) {\r\n return point;\r\n }\r\n\r\n return {\r\n x: ((point?.x ?? 0) / (divRef.current?.clientWidth ?? 1)) * virtualSize.width,\r\n y: ((point?.y ?? 0) / (divRef.current?.clientHeight ?? 1)) * virtualSize.height,\r\n };\r\n }, [virtualSize, divRef]);\r\n\r\n // Give a chance for the parent component to know the conversions we're using.\r\n useEffect(() => {\r\n if (onVirtualConversionChanged) {\r\n onVirtualConversionChanged({\r\n displayToVirtual,\r\n virtualToDisplay,\r\n });\r\n }\r\n }, [virtualToDisplay, displayToVirtual, onVirtualConversionChanged]);\r\n\r\n const selectShape = useCallback((value: string | null) => {\r\n _selectShape(value);\r\n if (value != null) {\r\n if (onShapeClicked) {\r\n const shape = _overlays.find(item => item.id === value);\r\n if (shape) {\r\n onShapeClicked(shape, { displayToVirtual, virtualToDisplay, });\r\n }\r\n }\r\n }\r\n }, [_selectShape, _overlays, onShapeClicked, displayToVirtual, virtualToDisplay]);\r\n\r\n\r\n // Get all overlays with their screen sizing for x/y.\r\n const overlays = /*useMemo(() =>*/\r\n _overlays.map(item => {\r\n const location = virtualToDisplay({ x: item.x, y: item.y });\r\n const size = virtualToDisplay({ x: item.width, y: item.height });\r\n\r\n return {\r\n ...item,\r\n\r\n x: location.x,\r\n y: location.y,\r\n width: size.x,\r\n height: size.y,\r\n };\r\n }\r\n )/*, [_overlays, virtualToDisplay])*/;\r\n\r\n // Handle conversion to virtual x/y during overlay transformation.\r\n const onOverlayTransformed = useCallback((id: string, shapeProps: OverlayShape) => {\r\n if (!_onOverlayTransformed) {\r\n return;\r\n }\r\n\r\n const location = displayToVirtual({ x: shapeProps.x, y: shapeProps.y });\r\n const size = displayToVirtual({ x: shapeProps.width, y: shapeProps.height });\r\n\r\n const virtualShapeProps = {\r\n ...shapeProps,\r\n\r\n x: location.x,\r\n y: location.y,\r\n width: size.x,\r\n height: size.y,\r\n };\r\n\r\n _onOverlayTransformed(id, virtualShapeProps, { displayToVirtual, virtualToDisplay, });\r\n }, [_onOverlayTransformed, displayToVirtual, virtualToDisplay]);\r\n\r\n // Handle conversion to virtual x/y during item addition.\r\n const onAddOverlay = useCallback((shapeProps: Partial): OverlayShape => {\r\n if (!_onAddOverlay) {\r\n return {\r\n ...shapeProps,\r\n shape: addOverlayShapeType,\r\n }as OverlayShape;\r\n }\r\n\r\n const newDisplaySize = { x: 80, y: 80 }; // Default is to make the size look conistant on screen regardless of underlying image size.\r\n let location = displayToVirtual({ x: shapeProps.x ?? 0, y: (shapeProps.y ?? 0) });\r\n if (addOverlayShapeType === 'rect') {\r\n // Position it so the click is in the middle of the new area rather than the top left as rects have special positioning.\r\n location = displayToVirtual({ x: (shapeProps.x ?? 0) - (newDisplaySize.x / 2), y: (shapeProps.y ?? 0) - (newDisplaySize.y / 2) }); \r\n }\r\n const size = displayToVirtual(newDisplaySize);\r\n\r\n const virtualShapeProps = {\r\n ...shapeProps,\r\n shape: addOverlayShapeType,\r\n \r\n x: location.x,\r\n y: location.y,\r\n width: size.x,\r\n height: size.y,\r\n };\r\n\r\n const ret = _onAddOverlay(virtualShapeProps, { displayToVirtual, virtualToDisplay });\r\n\r\n const retLocation = virtualToDisplay({ x: ret.x, y: ret.y });\r\n const retSize = virtualToDisplay({ x: ret.width, y: ret.height });\r\n\r\n const screenRet = {\r\n ...ret,\r\n\r\n x: retLocation.x,\r\n y: retLocation.y,\r\n width: retSize.x,\r\n height: retSize.y,\r\n };\r\n\r\n return screenRet;\r\n }, [_onAddOverlay, displayToVirtual, virtualToDisplay, addOverlayShapeType]);\r\n\r\n // Handle what happens when we click on the overlay layer.\r\n const handleOverlayLayerClick = useCallback((e: KonvaEventObject | KonvaEventObject) => {\r\n // When we are clicked without a shape targetted then either clear the selection or add a new overlay.\r\n\r\n const clickedOnEmpty = e.target === e.target.getStage();\r\n if (!clickedOnEmpty) {\r\n return;\r\n }\r\n\r\n if (!allowAdd) {\r\n selectShape(null);\r\n return;\r\n }\r\n\r\n if (onAddOverlay) {\r\n const shapePosition = {\r\n x: (e as KonvaEventObject).evt.offsetX ?? (e as KonvaEventObject).evt.touches[0].clientX,\r\n y: (e as KonvaEventObject).evt.offsetY ?? (e as KonvaEventObject).evt.touches[0].clientY,\r\n };\r\n\r\n const newShape = onAddOverlay(shapePosition);\r\n // Automatically select the new overlay.\r\n // NOTE we don't trigger the onShapeClick event here so go straight to _selectShape.\r\n _selectShape(newShape.id);\r\n }\r\n }, [allowAdd, onAddOverlay, selectShape]);\r\n\r\n // Need to force a refresh once everything is displayed once to cope with bugs in react-konva's display.\r\n const [forceInitialRefresh, setForceRefreshCount] = useState(0);\r\n useEffect(() => {\r\n if (forceInitialRefresh > 0) {\r\n return;\r\n }\r\n\r\n setTimeout(() => {\r\n setForceRefreshCount(prevState => prevState + 1);\r\n }, 1);\r\n }, [forceInitialRefresh, setForceRefreshCount]);\r\n\r\n // Calculate the height based on the width available on screen and the virtual dimensions we are working to\r\n // and make sure we trigger a refresh each time the window is resized.\r\n const [calculatedHeight, setCalcualtedHeight] = useState(100);\r\n useEffect(() => {\r\n function handleResize() {\r\n if (!divRef.current) {\r\n return;\r\n }\r\n\r\n const height = (divRef.current.clientWidth / virtualSize.width) * virtualSize.height;\r\n setCalcualtedHeight(height);\r\n }\r\n\r\n // Do the sizeing on first render.\r\n handleResize();\r\n\r\n // Trigger the sizing calculation again when the window size changes.\r\n window.addEventListener('resize', handleResize);\r\n\r\n // Cleanup the resize event handler when the effect is cleaned up\r\n return () => window.removeEventListener('resize', handleResize);\r\n }, [setForceRefreshCount, virtualSize, divRef, setCalcualtedHeight]);\r\n\r\n return (\r\n
\r\n {\r\n needToCalculateVirtualSize ? (\r\n setVirtualSize({ width: e.currentTarget.naturalWidth, height: e.currentTarget.naturalHeight })} alt=\"\" />\r\n ) : (\r\n \r\n \r\n {\r\n overlays.map(item => {\r\n return (\r\n {\r\n selectShape(item.id);\r\n }}\r\n onChange={(newAttrs: any) => {\r\n if (onOverlayTransformed) {\r\n onOverlayTransformed(item.id, newAttrs);\r\n }\r\n }}\r\n />\r\n );\r\n })\r\n }\r\n \r\n \r\n )\r\n }\r\n
\r\n );\r\n};\r\n","/**\r\n * Get text from the passed in HTML.\r\n * @param html\r\n */\r\nexport function textFromHtml(html: string): string {\r\n const doc = new DOMParser().parseFromString(html, 'text/html');\r\n return doc.body.textContent ?? \"\";\r\n}","export interface ResponseWindowColor {\r\n stroke: string,\r\n fill: string,\r\n}\r\n\r\n/**\r\n * Colours to use for different discrimination groups of response windows.\r\n */\r\nexport const responseWindowColors: Array = [\r\n { stroke: 'darkgreen', fill: 'green', },\r\n { stroke: 'darkred', fill: 'red', },\r\n { stroke: 'darkblue', fill: 'blue', },\r\n { stroke: 'darkyellow', fill: 'yellow', },\r\n { stroke: 'darkpurple', fill: 'purple', },\r\n];","import { useCallback, useMemo } from \"react\";\r\nimport { useTranslation } from \"react-i18next\";\r\nimport { Button, FormGroup, FormText, Label, Input } from \"reactstrap\";\r\nimport { BlobReference } from \"../../../../api/main/models/BlobReference\";\r\nimport { Question } from \"../../../../api/main/models/Question\";\r\nimport { QuestionAnswer, questionAnswerDefaultValues } from \"../../../../api/main/models/QuestionAnswer\";\r\nimport { HtmlEditor } from \"../../../../shared/htmlEditor\";\r\nimport { ModelArrayChanges } from \"../../../../shared/useChanges\";\r\nimport { QuestionAnswerLocationResponseImage } from \"./QuestionAnswerLocationResponseImage\";\r\nimport { useDisplayOrder } from \"../../../shared/useDisplayOrder/useDisplayOrder\";\r\nimport { ValidationErrors } from \"pojo-validator\";\r\nimport { InteractiveImage } from \"../../../shared/interactiveImage/InteractiveImage\";\r\nimport { OverlayShape } from \"../../../shared/interactiveImage/OverlayShape\";\r\nimport { useToggleState } from \"use-toggle-state\";\r\nimport { ConditionalFragment } from \"react-conditionalfragment\";\r\nimport { textFromHtml } from \"../../../../utilities/textFromHtml\";\r\nimport { responseWindowColors } from \"../locationDiscriminationImage/reponseWindowColors\";\r\n\r\n\r\nexport interface QuestionPromptLocationResponseImageTabProps {\r\n model: Question | undefined,\r\n change: (changes: Partial) => void,\r\n\r\n imageBlob: BlobReference | undefined | null,\r\n\r\n answersManager: ModelArrayChanges,\r\n\r\n validateQuestionAnswer: (model: QuestionAnswer) => boolean,\r\n questionAnswerValidationErrors: (id: string) => ValidationErrors,\r\n}\r\n\r\n/**\r\n * Tab for maintaining the prompt and response windows for a LocationResponseImage question.\r\n * @param props\r\n */\r\nexport const QuestionPromptLocationResponseImageTab = (props: QuestionPromptLocationResponseImageTabProps) => {\r\n const {\r\n model,\r\n change,\r\n\r\n imageBlob,\r\n\r\n answersManager,\r\n\r\n validateQuestionAnswer,\r\n questionAnswerValidationErrors,\r\n } = props;\r\n\r\n\r\n\r\n const { t } = useTranslation();\r\n\r\n // Order the answers so they show in and can be managed by displayOrder.\r\n const [orderedAnswers, {\r\n canMoveUp: canMoveAnswerUp,\r\n moveUp: moveAnswerUp,\r\n canMoveDown: canMoveAnswerDown,\r\n moveDown: moveAnswerDown,\r\n }] = useDisplayOrder(answersManager);\r\n\r\n // Adding of an answer.\r\n const [isAddingAnswer, toggleAddAnswer] = useToggleState();\r\n const onAnswerAdded = useCallback((shapeProps: Partial): OverlayShape => {\r\n // Genreate a new answer.\r\n const newItem = {\r\n ...questionAnswerDefaultValues(),\r\n\r\n questionId: model?.id,\r\n windowLeft: shapeProps.x ?? 0,\r\n windowTop: shapeProps.y ?? 0,\r\n windowRight: (shapeProps.x ?? 0) + (shapeProps.width ?? 100),\r\n windowBottom: (shapeProps.y ?? 0) + (shapeProps.height ?? 100),\r\n };\r\n\r\n answersManager.addFor(newItem);\r\n\r\n // Turn off the click to add functionality.\r\n toggleAddAnswer();\r\n\r\n // Return information to the interactive image so the new item can be selected automatically.\r\n return {\r\n ...shapeProps,\r\n id: newItem.id,\r\n } as OverlayShape;\r\n }, [answersManager, model?.id, toggleAddAnswer]);\r\n\r\n // Transforming of an overlay using the visual shape editor.\r\n const onAnswerOverlayTransformed = useCallback((id: string, shapeProps: OverlayShape) => {\r\n answersManager.changeFor(id, {\r\n windowLeft: shapeProps.x ?? 0,\r\n windowTop: shapeProps.y ?? 0,\r\n windowRight: (shapeProps.x ?? 0) + (shapeProps.width ?? 100),\r\n windowBottom: (shapeProps.y ?? 0) + (shapeProps.height ?? 100),\r\n });\r\n }, [answersManager]);\r\n\r\n // Generate overlays for each answer.\r\n const overlays: Array = useMemo(() =>\r\n answersManager.model.map(item => ({\r\n id: item.id,\r\n label: textFromHtml(item.answerText),\r\n x: item.windowLeft,\r\n y: item.windowTop,\r\n width: item.windowRight - item.windowLeft,\r\n height: item.windowBottom - item.windowTop,\r\n\r\n opacity: 0.5,\r\n ...responseWindowColors[0],\r\n } as OverlayShape))\r\n , [answersManager.model]);\r\n\r\n return (\r\n <>\r\n \r\n \r\n\r\n change({ preQuestionText: html })} />\r\n \r\n\r\n \r\n \r\n\r\n change({ questionText: html })} />\r\n \r\n\r\n \r\n \r\n\r\n \r\n \r\n {t('questionPromptLocationResponseImageTab.virtualSizeText', 'All locations and sizes are configured based on the original size of the image and are automatically scaled by the software when used to match the size of the device being used.')}\r\n \r\n\r\n \r\n \r\n {t('questionPromptLocationResponseImageTab.clickToAddText', 'Click on the image to add a new response window.')}\r\n \r\n \r\n\r\n
\r\n {\r\n orderedAnswers.map(item => (\r\n answersManager.changeFor(item.id, changes)}\r\n remove={() => answersManager.removeFor(item.id)}\r\n\r\n isOpenInitially={!!answersManager.added.find(it => it.id === item.id)}\r\n\r\n moveUp={() => moveAnswerUp(item.id)} canMoveUp={canMoveAnswerUp(item.id)}\r\n moveDown={() => moveAnswerDown(item.id)} canMoveDown={canMoveAnswerDown(item.id)}\r\n\r\n validate={() => validateQuestionAnswer(item)}\r\n validationErrors={questionAnswerValidationErrors(item.id)}\r\n />\r\n ))\r\n }\r\n
\r\n\r\n \r\n
\r\n\r\n \r\n \r\n change({ maximumClicks: e.currentTarget.valueAsNumber })} />\r\n \r\n \r\n );\r\n};","import { FontAwesomeIcon } from \"@fortawesome/react-fontawesome\";\r\nimport { ValidationErrors } from \"pojo-validator\";\r\nimport { ValidateCallback } from \"pojo-validator-react\";\r\nimport { ValidatedInput } from \"pojo-validator-reactstrap\";\r\nimport { useMemo } from \"react\";\r\nimport { useTranslation } from \"react-i18next\";\r\nimport { Button, ButtonGroup, Card, CardBody, Col, Collapse, FormGroup, FormText, Input, Label, Row, InputGroup, InputGroupAddon, } from \"reactstrap\";\r\nimport { useToggleState } from \"use-toggle-state\";\r\nimport { QuestionAnswer } from \"../../../../api/main/models/QuestionAnswer\";\r\nimport { HtmlDisplay, HtmlEditor } from \"../../../../shared/htmlEditor\";\r\nimport { CardHeaderCollapse } from \"../../../shared/cardHeaderCollapse/CardHeaderCollapse\";\r\nimport { FormButtons } from \"../../../shared/FormButtons\";\r\nimport { InputSelectOrText } from \"../../../shared/inputSelectOrText/InputSelectOrText\";\r\nimport { responseWindowColors } from \"./reponseWindowColors\";\r\n\r\nexport interface QuestionAnswerLocationDiscriminationImageProps {\r\n model: QuestionAnswer | undefined,\r\n change: (changes: Partial) => void,\r\n remove: () => void,\r\n moveUp: () => void,\r\n canMoveUp: boolean,\r\n moveDown: () => void,\r\n canMoveDown: boolean,\r\n\r\n isOpenInitially?: boolean,\r\n\r\n validate: ValidateCallback,\r\n validationErrors: ValidationErrors,\r\n\r\n discriminationGroups: Array,\r\n}\r\n\r\n/**\r\n * Response window for LocationDiscriminationImage questions.\r\n * @param props\r\n */\r\nexport const QuestionAnswerLocationDiscriminationImage = (props: QuestionAnswerLocationDiscriminationImageProps) => {\r\n const {\r\n model,\r\n change,\r\n remove,\r\n moveUp,\r\n canMoveUp,\r\n moveDown,\r\n canMoveDown,\r\n\r\n isOpenInitially = false,\r\n\r\n validate,\r\n validationErrors,\r\n\r\n discriminationGroups,\r\n } = props;\r\n\r\n const { t } = useTranslation();\r\n\r\n // Self management of if we are expanded or not.\r\n const [isOpen, toggleOpen] = useToggleState(isOpenInitially);\r\n\r\n const locationString = useMemo(() => {\r\n if (!model) {\r\n return '';\r\n }\r\n\r\n return `${Math.round(model.windowTop)},${Math.round(model.windowLeft)} to ${Math.round(model.windowBottom)},${Math.round(model.windowRight)}`;\r\n }, [model]);\r\n\r\n const discriminationGroupColor = useMemo(() =>\r\n responseWindowColors[(discriminationGroups.indexOf(model?.discriminationGroup ?? '') || 0) % responseWindowColors.length].fill\r\n , [model, discriminationGroups]);\r\n\r\n return (\r\n \r\n \r\n \r\n \r\n {locationString}\r\n \r\n \r\n {model?.discriminationGroup}\r\n \r\n \r\n
\r\n \r\n
\r\n \r\n
\r\n
\r\n\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n\r\n \r\n \r\n \r\n \r\n\r\n change({ windowTop: e.currentTarget.valueAsNumber })} />\r\n \r\n \r\n \r\n \r\n \r\n\r\n change({ windowLeft: e.currentTarget.valueAsNumber })} />\r\n \r\n \r\n \r\n\r\n \r\n \r\n \r\n \r\n\r\n change({ windowBottom: e.currentTarget.valueAsNumber })} />\r\n \r\n \r\n \r\n \r\n \r\n\r\n change({ windowRight: e.currentTarget.valueAsNumber })} />\r\n \r\n \r\n \r\n\r\n \r\n \r\n change({ discriminationGroup: e.currentTarget.value })}>\r\n {\r\n discriminationGroups.map(item => (\r\n \r\n ))\r\n }\r\n \r\n \r\n\r\n \r\n \r\n change({ answerText: html })} />\r\n \r\n\r\n \r\n {/**/}\r\n {/* */}\r\n {/* */}\r\n\r\n {/* {*/}\r\n {/* // Toggle the flag, and if we're using default scoring at the moment, also default the score.*/}\r\n {/* if (checked && model?.score === 0) {*/}\r\n {/* change({ isCorrect: checked, score: 10 });*/}\r\n {/* } else if (!checked && model?.score === 10) {*/}\r\n {/* change({ isCorrect: checked, score: 0 });*/}\r\n {/* } else {*/}\r\n {/* change({ isCorrect: checked });*/}\r\n {/* }*/}\r\n {/* }}*/}\r\n {/* />*/}\r\n {/* */}\r\n {/**/}\r\n \r\n \r\n \r\n\r\n \r\n change({ score: e.currentTarget.valueAsNumber })} onBlur={() => validate('score')} validationErrors={validationErrors['score']} />\r\n \r\n {t('common.percentageSign', '%')}\r\n \r\n \r\n \r\n {t('questionAnswerMultipleChoiceVideo.score.help', 'Score will normally be between 0% (incorrect) and 100% (correct).')}\r\n \r\n \r\n \r\n \r\n \r\n \r\n
\r\n );\r\n};","import { useCallback, useMemo } from \"react\";\r\nimport { useTranslation } from \"react-i18next\";\r\nimport { Button, FormGroup, FormText, Label, Input } from \"reactstrap\";\r\nimport { BlobReference } from \"../../../../api/main/models/BlobReference\";\r\nimport { Question } from \"../../../../api/main/models/Question\";\r\nimport { QuestionAnswer, questionAnswerDefaultValues } from \"../../../../api/main/models/QuestionAnswer\";\r\nimport { HtmlEditor } from \"../../../../shared/htmlEditor\";\r\nimport { ModelArrayChanges } from \"../../../../shared/useChanges\";\r\nimport { QuestionAnswerLocationDiscriminationImage } from \"./QuestionAnswerLocationDiscriminationImage\";\r\nimport { useDisplayOrder } from \"../../../shared/useDisplayOrder/useDisplayOrder\";\r\nimport { ValidationErrors } from \"pojo-validator\";\r\nimport { InteractiveImage } from \"../../../shared/interactiveImage/InteractiveImage\";\r\nimport { OverlayShape } from \"../../../shared/interactiveImage/OverlayShape\";\r\nimport { useToggleState } from \"use-toggle-state\";\r\nimport { ConditionalFragment } from \"react-conditionalfragment\";\r\nimport { textFromHtml } from \"../../../../utilities/textFromHtml\";\r\nimport { responseWindowColors } from \"./reponseWindowColors\";\r\nimport { isNullOrUndefined } from \"util\";\r\n\r\n\r\nexport interface QuestionPromptLocationDiscriminationImageTabProps {\r\n model: Question | undefined,\r\n change: (changes: Partial) => void,\r\n\r\n imageBlob: BlobReference | undefined | null,\r\n\r\n answersManager: ModelArrayChanges,\r\n\r\n validateQuestionAnswer: (model: QuestionAnswer) => boolean,\r\n questionAnswerValidationErrors: (id: string) => ValidationErrors,\r\n}\r\n\r\n/**\r\n * Tab for maintaining the prompt and response windows for LocationDiscriminationImage questions.\r\n * @param props\r\n */\r\nexport const QuestionPromptLocationDiscriminationImageTab = (props: QuestionPromptLocationDiscriminationImageTabProps) => {\r\n const {\r\n model,\r\n change,\r\n\r\n imageBlob,\r\n\r\n answersManager,\r\n\r\n validateQuestionAnswer,\r\n questionAnswerValidationErrors,\r\n\r\n } = props;\r\n\r\n const { t } = useTranslation();\r\n\r\n\r\n\r\n // Order the answers so they show in and can be managed by displayOrder.\r\n const [orderedAnswers, {\r\n canMoveUp: canMoveAnswerUp,\r\n moveUp: moveAnswerUp,\r\n canMoveDown: canMoveAnswerDown,\r\n moveDown: moveAnswerDown,\r\n }] = useDisplayOrder(answersManager);\r\n\r\n // Adding of an answer.\r\n const [isAddingAnswer, toggleAddAnswer] = useToggleState();\r\n const onAnswerAdded = useCallback((shapeProps: Partial): OverlayShape => {\r\n // Genreate a new answer.\r\n const newItem = {\r\n ...questionAnswerDefaultValues(),\r\n\r\n questionId: model?.id,\r\n windowLeft: shapeProps.x ?? 0,\r\n windowTop: shapeProps.y ?? 0,\r\n windowRight: (shapeProps.x ?? 0) + (shapeProps.width ?? 100),\r\n windowBottom: (shapeProps.y ?? 0) + (shapeProps.height ?? 100),\r\n };\r\n\r\n answersManager.addFor(newItem);\r\n\r\n // Turn off the click to add functionality.\r\n toggleAddAnswer();\r\n\r\n // Return information to the interactive image so the new item can be selected automatically.\r\n return {\r\n ...shapeProps,\r\n id: newItem.id,\r\n } as OverlayShape;\r\n }, [answersManager, model?.id, toggleAddAnswer]);\r\n\r\n // Transforming of an overlay using the visual shape editor.\r\n const onAnswerOverlayTransformed = useCallback((id: string, shapeProps: OverlayShape) => {\r\n answersManager.changeFor(id, {\r\n windowLeft: shapeProps.x ?? 0,\r\n windowTop: shapeProps.y ?? 0,\r\n windowRight: (shapeProps.x ?? 0) + (shapeProps.width ?? 100),\r\n windowBottom: (shapeProps.y ?? 0) + (shapeProps.height ?? 100),\r\n });\r\n }, [answersManager]);\r\n\r\n // Get a list of all unique discrimnation groups from the answers\r\n const discriminationGroups = useMemo(() => {\r\n let ret: Array = [];\r\n for (const answer of orderedAnswers) {\r\n const existing = ret.find(it => it === answer.discriminationGroup);\r\n if (!isNullOrUndefined(existing)) {\r\n continue;\r\n }\r\n\r\n ret.push(answer.discriminationGroup);\r\n }\r\n\r\n // NOTE we don't sort this alphabetically as doing so causes too many colour changes in discrimnation groups and so\r\n // is a worse user experience.\r\n //ret.sort();\r\n\r\n return ret;\r\n }, [orderedAnswers]);\r\n\r\n // Generate overlays for each answer.\r\n const overlays: Array = useMemo(() =>\r\n answersManager.model.map(item => ({\r\n id: item.id,\r\n label: textFromHtml(item.answerText),\r\n x: item.windowLeft,\r\n y: item.windowTop,\r\n width: item.windowRight - item.windowLeft,\r\n height: item.windowBottom - item.windowTop,\r\n\r\n opacity: 0.5,\r\n\r\n // Colour each discrimination group a different colour.\r\n ...responseWindowColors[(discriminationGroups.indexOf(item.discriminationGroup) || 0) % responseWindowColors.length],\r\n } as OverlayShape))\r\n , [answersManager.model, discriminationGroups]);\r\n\r\n\r\n return (\r\n <>\r\n \r\n \r\n\r\n change({ preQuestionText: html })} />\r\n \r\n\r\n \r\n \r\n\r\n change({ questionText: html })} />\r\n \r\n\r\n \r\n \r\n\r\n \r\n \r\n {t('questionPromptLocationDiscriminationImageTab.virtualSizeText', 'All locations and sizes are configured based on the original size of the image and are automatically scaled by the software when used to match the size of the device being used.')}\r\n \r\n\r\n \r\n \r\n {t('questionPromptLocationDiscriminationImageTab.clickToAddText', 'Click on the image to add a new response window.')}\r\n \r\n \r\n\r\n
\r\n {\r\n orderedAnswers.map(item => (\r\n answersManager.changeFor(item.id, changes)}\r\n remove={() => answersManager.removeFor(item.id)}\r\n\r\n isOpenInitially={!!answersManager.added.find(it => it.id === item.id)}\r\n\r\n moveUp={() => moveAnswerUp(item.id)} canMoveUp={canMoveAnswerUp(item.id)}\r\n moveDown={() => moveAnswerDown(item.id)} canMoveDown={canMoveAnswerDown(item.id)}\r\n\r\n validate={() => validateQuestionAnswer(item)}\r\n validationErrors={questionAnswerValidationErrors(item.id)}\r\n\r\n discriminationGroups={discriminationGroups}\r\n />\r\n ))\r\n }\r\n
\r\n\r\n \r\n\r\n \r\n \r\n \r\n change({ maximumClicks: e.currentTarget.valueAsNumber })} />\r\n \r\n\r\n\r\n
\r\n \r\n );\r\n};","import { FontAwesomeIcon } from \"@fortawesome/react-fontawesome\";\r\nimport { useTranslation } from \"react-i18next\";\r\nimport { Link } from \"react-router-dom\";\r\nimport { Button, ButtonGroup, Col, ListGroupItem, Row,} from \"reactstrap\";\r\nimport { QuestionType, questionTypeDisplayName } from \"../../../../api/main/models/codeOnly/QuestionType\";\r\nimport { Question } from \"../../../../api/main/models/Question\";\r\nimport { QuestionSequenceQuestion } from \"../../../../api/main/models/QuestionSequenceQuestion\";\r\nimport { FormButtons } from \"../../../shared/FormButtons\";\r\n\r\n\r\nexport interface QuestionSequenceQuestionComponentProps {\r\n model: QuestionSequenceQuestion,\r\n change: (changes: Partial) => void,\r\n remove: () => void,\r\n moveUp: () => void,\r\n canMoveUp: boolean,\r\n moveDown: () => void,\r\n canMoveDown: boolean,\r\n\r\n\r\n childQuestion: Question | undefined,\r\n}\r\n\r\n/**\r\n * A question that forms part of the QuestionSequenceQuestion.\r\n * @param props\r\n */\r\nexport const QuestionSequenceQuestionComponent = (props: QuestionSequenceQuestionComponentProps) => {\r\n const {\r\n //model,\r\n //change,\r\n remove,\r\n moveUp,\r\n canMoveUp,\r\n moveDown,\r\n canMoveDown,\r\n\r\n\r\n childQuestion,\r\n } = props;\r\n\r\n const { t } = useTranslation();\r\n\r\n\r\n\r\n return (\r\n\r\n \r\n \r\n \r\n
\r\n\r\n \r\n \r\n {childQuestion?.name}\r\n \r\n\r\n\r\n\r\n
\r\n
\r\n {questionTypeDisplayName(childQuestion?.questionType as QuestionType, t)}\r\n
\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n
\r\n
\r\n\r\n\r\n\r\n\r\n );\r\n\r\n\r\n};","import { useCallback } from \"react\";\r\nimport { useTranslation } from \"react-i18next\";\r\nimport { Button, Col, FormGroup, Label, ListGroup, Row } from \"reactstrap\";\r\nimport { Question } from \"../../../../api/main/models/Question\";\r\nimport { ModelArrayChanges } from \"../../../../shared/useChanges\";\r\nimport { useDisplayOrder } from \"../../../shared/useDisplayOrder/useDisplayOrder\";\r\nimport { QuestionSequenceQuestion, questionSequenceQuestionDefaultValues } from \"../../../../api/main/models/QuestionSequenceQuestion\";\r\nimport { QuestionSequenceQuestionComponent } from \"./QuestionSequenceQuestionComponent\";\r\nimport { useToggleState } from \"use-toggle-state\";\r\nimport { SelectQuestionModal } from \"../../selectQuestionModal/SelectQuestionModal\";\r\nimport { FontAwesomeIcon } from '@fortawesome/react-fontawesome';\r\nimport { ConditionalFragment } from \"react-conditionalfragment\";\r\nimport moment from \"moment\";\r\nimport { QuestionType, QuestionTypeCategory } from \"../../../../api/main/models/codeOnly/QuestionType\";\r\nimport { SelectQuestionnaireModal } from \"../../questionnaires/SelectQuestionnaireModal/SelectQuestionnaireModal\";\r\n\r\nexport interface QuestionPromptMultipleChoiceVideoTabProps {\r\n model: Question | undefined,\r\n\r\n questionSequenceQuestionsManager: ModelArrayChanges,\r\n allQuestions: Array,\r\n isLoadingAllQuestions: boolean,\r\n ensureAllQuestionsLoaded: () => void,\r\n}\r\n\r\n/**\r\n * Tab for a maintaining a sequence of questions.\r\n * @param props\r\n */\r\nexport const SequenceOfQuestionsTab = (props: QuestionPromptMultipleChoiceVideoTabProps) => {\r\n const {\r\n model,\r\n\r\n questionSequenceQuestionsManager,\r\n allQuestions,\r\n isLoadingAllQuestions,\r\n ensureAllQuestionsLoaded,\r\n } = props;\r\n\r\n const { t } = useTranslation();\r\n\r\n // Order the answers so they show in and can be managed by displayOrder.\r\n const [orderedQuestions, {\r\n canMoveUp: canMoveAnswerUp,\r\n moveUp: moveAnswerUp,\r\n canMoveDown: canMoveAnswerDown,\r\n moveDown: moveAnswerDown,\r\n }] = useDisplayOrder(questionSequenceQuestionsManager);\r\n \r\n // Showing of the question modal.\r\n const [questionModalIsOpen, _toggleQuestionModal] = useToggleState();\r\n const toggleQuestionModal = useCallback(() => {\r\n ensureAllQuestionsLoaded();\r\n _toggleQuestionModal();\r\n }, [ensureAllQuestionsLoaded, _toggleQuestionModal]);\r\n\r\n // Showing of the questionnaire modal.\r\n const [questionnaireModalIsOpen, _toggleQuestionnaireModal] = useToggleState();\r\n const toggleQuestionnaireModal = useCallback(() => {\r\n ensureAllQuestionsLoaded();\r\n _toggleQuestionnaireModal();\r\n }, [ensureAllQuestionsLoaded, _toggleQuestionnaireModal]);\r\n\r\n // Adding of questions selected in the modal\r\n const onQuestionModalClosed = useCallback((event: { selectedIds: Array }) => {\r\n\r\n var i = 0; // Using i to add on to the display order. This is done so when questions are added in bulk they dont get the same display order.\r\n\r\n for (const selectedId of event.selectedIds) {\r\n questionSequenceQuestionsManager.addFor({\r\n ...questionSequenceQuestionDefaultValues(),\r\n displayOrder: moment().unix() + i,\r\n parentQuestionId: model?.id,\r\n childQuestionId: selectedId,\r\n });\r\n\r\n i++;\r\n }\r\n }, [questionSequenceQuestionsManager, model?.id]);\r\n\r\n return (\r\n <>\r\n \r\n \r\n\r\n \r\n {\r\n orderedQuestions.map(item => {\r\n const childQuestion = allQuestions.find(it => it.id === item.childQuestionId);\r\n\r\n return (\r\n questionSequenceQuestionsManager.changeFor(item.id, changes)}\r\n remove={() => questionSequenceQuestionsManager.removeFor(item.id)}\r\n\r\n moveUp={() => moveAnswerUp(item.id)} canMoveUp={canMoveAnswerUp(item.id)}\r\n moveDown={() => moveAnswerDown(item.id)} canMoveDown={canMoveAnswerDown(item.id)}\r\n\r\n childQuestion={childQuestion}\r\n />\r\n );\r\n })\r\n }\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n );\r\n};","import { useMutation } from \"@apollo/react-hooks\";\r\nimport { useAsyncCallback } from 'react-use-async-callback';\r\nimport gql from \"graphql-tag\";\r\nimport { AsyncActionStatus } from '../../../shared/abstractStore';\r\nimport { QuestionSequenceQuestionCreateInput } from '../generated/globalTypes';\r\nimport { createQuestionSequenceQuestionMutation, createQuestionSequenceQuestionMutationVariables } from '../generated/createQuestionSequenceQuestionMutation';\r\nimport { questionSequenceQuestionFieldsFragment } from '../models/QuestionSequenceQuestion';\r\n\r\n/**\r\n * Get a callback to create a QuestionSequenceQuestion in the store.\r\n */\r\nexport function useCreateQuestionSequenceQuestionCallback(): [(model: QuestionSequenceQuestionCreateInput) => Promise, AsyncActionStatus] {\r\n const [mutationAction, { error }] = useMutation(\r\n gql`\r\n mutation createQuestionSequenceQuestionMutation ($model: QuestionSequenceQuestionCreateInput!) {\r\n createQuestionSequenceQuestion(model: $model) {\r\n ...questionSequenceQuestionFields\r\n }\r\n }\r\n\r\n ${questionSequenceQuestionFieldsFragment}\r\n `\r\n );\r\n\r\n // Wrap the mutation in a standard callback.\r\n const [action, { isExecuting, errors: actionErrors }] = useAsyncCallback(async (model: QuestionSequenceQuestionCreateInput) => {\r\n const result = await mutationAction({ variables: { model: model } });\r\n if (result.errors && result.errors.length) {\r\n throw result.errors;\r\n }\r\n }, [mutationAction]);\r\n\r\n return [action, { isExecuting: isExecuting, errors: error ? error.message : actionErrors }];\r\n}\r\n","import { useMutation } from \"@apollo/react-hooks\";\r\nimport { useAsyncCallback } from 'react-use-async-callback';\r\nimport gql from \"graphql-tag\";\r\nimport { AsyncActionStatus } from '../../../shared/abstractStore';\r\nimport { QuestionSequenceQuestionUpdateInput } from '../generated/globalTypes';\r\nimport { updateQuestionSequenceQuestionMutation, updateQuestionSequenceQuestionMutationVariables } from '../generated/updateQuestionSequenceQuestionMutation';\r\nimport { questionSequenceQuestionFieldsFragment } from '../models/QuestionSequenceQuestion';\r\n\r\n/**\r\n * Get a callback to update a QuestionSequenceQuestion in the store.\r\n */\r\nexport function useUpdateQuestionSequenceQuestionCallback(): [(id: string, model: QuestionSequenceQuestionUpdateInput) => Promise, AsyncActionStatus] {\r\n const [mutationAction, { error }] = useMutation(\r\n gql`\r\n mutation updateQuestionSequenceQuestionMutation ($model: QuestionSequenceQuestionUpdateInput!) {\r\n updateQuestionSequenceQuestion(model: $model) {\r\n ...questionSequenceQuestionFields\r\n }\r\n }\r\n\r\n ${questionSequenceQuestionFieldsFragment}\r\n `\r\n );\r\n\r\n // Wrap the mutation in a standard callback.\r\n const [action, { isExecuting, errors: actionErrors }] = useAsyncCallback(async (id: string, model: QuestionSequenceQuestionUpdateInput) => {\r\n const result = await mutationAction({ variables: { model: { ...model, id: id } } });\r\n if (result.errors && result.errors.length) {\r\n throw result.errors;\r\n }\r\n }, [mutationAction]);\r\n\r\n return [action, { isExecuting: isExecuting, errors: error ? error.message : actionErrors }];\r\n}\r\n","import { useMutation } from \"@apollo/react-hooks\";\r\nimport { useAsyncCallback } from 'react-use-async-callback';\r\nimport gql from \"graphql-tag\";\r\nimport { AsyncActionStatus } from '../../../shared/abstractStore';\r\nimport { deleteQuestionSequenceQuestionMutation, deleteQuestionSequenceQuestionMutationVariables } from '../generated/deleteQuestionSequenceQuestionMutation';\r\nimport { questionSequenceQuestionFieldsFragment } from '../models/QuestionSequenceQuestion';\r\n\r\n/**\r\n * Get a callback to delete a QuestionSequenceQuestion in the store.\r\n */\r\nexport function useDeleteQuestionSequenceQuestionCallback(): [(id: string) => Promise, AsyncActionStatus] {\r\n const [mutationAction, { error }] = useMutation(\r\n gql`\r\n mutation deleteQuestionSequenceQuestionMutation ($id: ID!) {\r\n deleteQuestionSequenceQuestion(id: $id) {\r\n ...questionSequenceQuestionFields\r\n }\r\n }\r\n\r\n ${questionSequenceQuestionFieldsFragment}\r\n `\r\n );\r\n\r\n // Wrap the mutation in a standard callback.\r\n const [action, { isExecuting, errors: actionErrors }] = useAsyncCallback(async (id: string) => {\r\n const result = await mutationAction({ variables: { id: id } });\r\n if (result.errors && result.errors.length) {\r\n throw result.errors;\r\n }\r\n }, [mutationAction]);\r\n\r\n return [action, { isExecuting: isExecuting, errors: error ? error.message : actionErrors }];\r\n}\r\n","import { ConditionalFragment } from \"react-conditionalfragment\";\r\nimport { useTranslation } from \"react-i18next\";\r\nimport { FormGroup, Label } from \"reactstrap\";\r\nimport { QuestionType } from \"../../../../api/main/models/codeOnly/QuestionType\";\r\nimport { Question } from \"../../../../api/main/models/Question\";\r\nimport { HtmlEditor } from \"../../../../shared/htmlEditor\";\r\n\r\nexport interface LearningTextTabProps {\r\n model: Question | undefined,\r\n change: (changes: Partial) => void,\r\n}\r\n\r\n/**\r\n * Tab for the text part of all Learning types.\r\n * @param props\r\n */\r\nexport const LearningTextTab = (props: LearningTextTabProps) => {\r\n const {\r\n model,\r\n change,\r\n } = props;\r\n\r\n const { t } = useTranslation();\r\n\r\n return (\r\n <>\r\n \r\n \r\n \r\n\r\n change({ preQuestionText: html })} />\r\n \r\n \r\n \r\n\r\n change({ questionText: html })} />\r\n \r\n \r\n \r\n \r\n \r\n\r\n change({ questionText: html })} />\r\n \r\n \r\n \r\n );\r\n};","import { FontAwesomeIcon } from \"@fortawesome/react-fontawesome\";\r\nimport { ValidationErrors } from \"pojo-validator\";\r\nimport { useTranslation } from \"react-i18next\";\r\nimport { Button, ButtonGroup, Card, CardBody, Collapse, FormGroup, Label, InputGroupAddon, InputGroup, FormText } from \"reactstrap\";\r\nimport { useToggleState } from \"use-toggle-state\";\r\nimport { QuestionAnswer } from \"../../../../api/main/models/QuestionAnswer\";\r\nimport { HtmlDisplay, HtmlEditor } from \"../../../../shared/htmlEditor\";\r\nimport { CardHeaderCollapse } from \"../../../shared/cardHeaderCollapse/CardHeaderCollapse\";\r\nimport { FormButtons } from \"../../../shared/FormButtons\";\r\nimport { TwoValueSwitch } from \"../../../shared/TwoValueSwitch\";\r\nimport { ConditionalFragment } from \"react-conditionalfragment\";\r\nimport { ValidatedInput } from \"pojo-validator-reactstrap\";\r\nimport { ValidateCallback } from \"pojo-validator-react\";\r\n\r\nexport interface QuestionnaireQuestionAnswerMultipleChoiceProps {\r\n model: QuestionAnswer | undefined,\r\n change: (changes: Partial) => void,\r\n remove: () => void,\r\n moveUp: () => void,\r\n canMoveUp: boolean,\r\n moveDown: () => void,\r\n canMoveDown: boolean,\r\n\r\n isOpenInitially?: boolean,\r\n\r\n validate: ValidateCallback,\r\n validationErrors: ValidationErrors,\r\n}\r\n\r\n/**\r\n * Tab for maintaining the prompt for the question and the available multiple choice answers.\r\n * @param props\r\n */\r\nexport const QuestionnaireQuestionAnswerMultipleChoice = (props: QuestionnaireQuestionAnswerMultipleChoiceProps) => {\r\n const {\r\n model,\r\n change,\r\n remove,\r\n moveUp,\r\n canMoveUp,\r\n moveDown,\r\n canMoveDown,\r\n\r\n isOpenInitially = false,\r\n\r\n validate,\r\n validationErrors,\r\n } = props;\r\n\r\n const { t } = useTranslation();\r\n\r\n // Self management of if we are expanded or not.\r\n const [isOpen, toggleOpen] = useToggleState(isOpenInitially);\r\n\r\n\r\n return (\r\n \r\n \r\n
\r\n \r\n
\r\n
\r\n\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n\r\n \r\n \r\n change({ answerText: html })} />\r\n\r\n \r\n\r\n \r\n {\r\n // Toggle the flag, and if we're using default scoring at the moment, also default the score.\r\n if (checked && model?.score === 0) {\r\n change({ isCorrect: checked, score: 100 });\r\n } else if (!checked && model?.score === 100) {\r\n change({ isCorrect: checked, score: 0 });\r\n } else {\r\n change({ isCorrect: checked });\r\n }\r\n }}\r\n />\r\n \r\n \r\n \r\n change({ score: e.currentTarget.valueAsNumber })}\r\n onBlur={() => validate('score')}\r\n validationErrors={validationErrors[\"score\"]}\r\n />\r\n \r\n {t('common.percentageSign', '%')}\r\n \r\n \r\n \r\n {t('questionnaireAnswerMultipleChoice.score.help', 'Score will normally be between 0% (incorrect) and 100% (correct).')}\r\n \r\n \r\n \r\n\r\n\r\n\r\n\r\n \r\n \r\n
\r\n );\r\n\r\n};\r\n","import { FontAwesomeIcon } from \"@fortawesome/react-fontawesome\";\r\nimport { ValidationErrors } from \"pojo-validator\";\r\nimport { ValidateCallback } from \"pojo-validator-react\";\r\nimport { useTranslation } from \"react-i18next\";\r\nimport { Button, ButtonGroup, Card, CardBody, Collapse, FormGroup, Label, InputGroupAddon, InputGroup, FormText} from \"reactstrap\";\r\nimport { useToggleState } from \"use-toggle-state\";\r\nimport { QuestionAnswer } from \"../../../../api/main/models/QuestionAnswer\";\r\nimport { HtmlDisplay, HtmlEditor } from \"../../../../shared/htmlEditor\";\r\nimport { CardHeaderCollapse } from \"../../../shared/cardHeaderCollapse/CardHeaderCollapse\";\r\nimport { FormButtons } from \"../../../shared/FormButtons\";\r\nimport { TwoValueSwitch } from \"../../../shared/TwoValueSwitch\";\r\nimport { ConditionalFragment } from \"react-conditionalfragment\";\r\nimport { ValidatedInput } from \"pojo-validator-reactstrap\";\r\n\r\nexport interface SlidingScaleQuestionnaireQuestionProps {\r\n\r\n\r\n model: QuestionAnswer | undefined,\r\n change: (changes: Partial) => void,\r\n\r\n remove: () => void,\r\n moveUp: () => void,\r\n canMoveUp: boolean,\r\n moveDown: () => void,\r\n canMoveDown: boolean,\r\n\r\n isOpenInitially?: boolean,\r\n\r\n validate: ValidateCallback,\r\n validationErrors: ValidationErrors,\r\n}\r\n\r\n/**\r\n * Answer on the scale for SlidingScaleVideo questions.\r\n * @param props\r\n */\r\nexport const SlidingScaleQuestionnaireQuestion = (props: SlidingScaleQuestionnaireQuestionProps) => {\r\n const {\r\n\r\n model,\r\n change,\r\n\r\n\r\n remove,\r\n moveUp,\r\n canMoveUp,\r\n moveDown,\r\n canMoveDown,\r\n\r\n isOpenInitially = false,\r\n\r\n validate,\r\n validationErrors\r\n } = props;\r\n\r\n const { t } = useTranslation();\r\n\r\n // Self management of if we are expanded or not.\r\n const [isOpen, toggleOpen] = useToggleState(isOpenInitially);\r\n\r\n\r\n\r\n return (\r\n <>\r\n\r\n \r\n \r\n
\r\n \r\n
\r\n
\r\n\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n\r\n \r\n \r\n change({ answerText: html })} />\r\n \r\n\r\n \r\n\r\n {\r\n // Toggle the flag, and if we're using default scoring at the moment, also default the score.\r\n if (checked && model?.score === 0) {\r\n change({ isCorrect: checked, score: 100 });\r\n } else if (!checked && model?.score === 100) {\r\n change({ isCorrect: checked, score: 0 });\r\n } else {\r\n change({ isCorrect: checked });\r\n }\r\n }}\r\n />\r\n \r\n \r\n \r\n change({ score: e.currentTarget.valueAsNumber })}\r\n onBlur={() => validate('score')}\r\n validationErrors={validationErrors['score']}\r\n />\r\n \r\n {t('common.percentageSign', '%')}\r\n \r\n \r\n \r\n {t('questionAnswerMultipleChoiceVideo.score.help', 'Score will normally be between 0% (incorrect) and 100% (correct).')}\r\n \r\n \r\n \r\n\r\n \r\n \r\n
\r\n\r\n\r\n\r\n \r\n );\r\n};\r\n","import { Button, Modal, ModalBody, ModalHeader, ModalProps, Label, Form, FormGroup, ModalFooter } from \"reactstrap\";\r\nimport { QuestionType, getQuestionTypes, QuestionTypeCategory, questionTypeDisplayName } from \"../../../../../api/main/models/codeOnly/QuestionType\";\r\nimport { useTranslation } from \"react-i18next\";\r\nimport { ValidatedInput } from 'pojo-validator-reactstrap';\r\nimport { useChanges } from '../../../../../shared/useChanges';\r\nimport { Question, questionDefaultValues } from '../../../../../api/main/models/Question';\r\nimport { useCallback } from 'react';\r\nimport { useValidatorCallback } from 'pojo-validator-react';\r\nimport { ConditionalFragment } from \"react-conditionalfragment\";\r\nimport { QuestionSequenceQuestion, questionSequenceQuestionDefaultValues } from '../../../../../api/main/models/QuestionSequenceQuestion';\r\nimport { QuestionAnswer, questionAnswerDefaultValues } from \"../../../../../api/main/models/QuestionAnswer\";\r\nimport { useDisplayOrder } from \"../../../../shared/useDisplayOrder/useDisplayOrder\";\r\nimport { ValidationErrors } from \"pojo-validator\";\r\nimport { QuestionnaireQuestionAnswerMultipleChoice } from \"../QuestionnaireQuestionAnswerMultipleChoice\";\r\nimport { SlidingScaleQuestionnaireQuestion } from \"../SlidingScaleQuestionnaireQuestion\";\r\nimport { HtmlEditor } from \"../../../../../shared/htmlEditor\";\r\nimport { useAsyncCallback } from 'react-use-async-callback';\r\nimport { SlidingScaleSlider } from \"../../../edit/slidingScaleVideo/SlidingScaleSlider\";\r\nimport { ModelArrayChanges } from \"../../../../../shared/useChanges\";\r\nimport { FontAwesomeIcon } from '@fortawesome/react-fontawesome';\r\nimport { DriverMetric } from \"../../../../../api/main/models/DriverMetric\"\r\n\r\nexport interface CreateQuestionnaireQuestionModalCloseEventArgs {\r\n\r\n selectedIds: Array,\r\n\r\n /**\r\n * Added Ids (those in selectedIds that were not in initialSelectedIds).\r\n */\r\n addedIds: Array,\r\n /**\r\n * Removed Ids (those in selectedIds that were not in initialSelectedIds).\r\n */\r\n removedIds: Array,\r\n\r\n cancelled: boolean,\r\n}\r\n\r\n\r\n\r\nexport interface CreateQuestionnaireQuestionModalProps extends ModalProps {\r\n questionnaire: Question,\r\n driverMetrics: Array,\r\n\r\n isOpen: boolean,\r\n toggle: () => void,\r\n\r\n questionTypeCategory?: QuestionTypeCategory,\r\n\r\n isCreate?: boolean,\r\n onCreateDefaultValues?: () => Partial,\r\n\r\n parentId: string,\r\n\r\n validateQuestionAnswer: (model: QuestionAnswer) => boolean,\r\n questionAnswerValidationErrors: (id: string) => ValidationErrors,\r\n\r\n questionnaireQuestionAnswersManager: ModelArrayChanges,\r\n questionSequenceQuestionsManager: ModelArrayChanges,\r\n questionnaireQuestionsManager: ModelArrayChanges,\r\n\r\n refresh: () => void,\r\n}\r\n\r\nexport const CreateQuestionnaireQuestionModal = (props: CreateQuestionnaireQuestionModalProps) => {\r\n const {\r\n\r\n questionnaire,\r\n driverMetrics,\r\n isOpen,\r\n toggle,\r\n\r\n isCreate,\r\n onCreateDefaultValues,\r\n\r\n parentId,\r\n\r\n validateQuestionAnswer,\r\n questionAnswerValidationErrors,\r\n\r\n questionnaireQuestionAnswersManager,\r\n questionSequenceQuestionsManager,\r\n questionnaireQuestionsManager,\r\n } = props;\r\n\r\n\r\n const { t } = useTranslation();\r\n const {model, change, changes } = useChanges(questionnaire, isCreate ? { ...questionDefaultValues(), ...(onCreateDefaultValues ? onCreateDefaultValues() : {}) } : undefined);\r\n\r\n\r\n // Order the answers so they show in and can be managed by displayOrder.\r\n const [orderedAnswers, {\r\n canMoveUp: canMoveAnswerUp,\r\n moveUp: moveAnswerUp,\r\n canMoveDown: canMoveAnswerDown,\r\n moveDown: moveAnswerDown,\r\n }] = useDisplayOrder(\r\n questionnaireQuestionAnswersManager,\r\n // Filter to only the answers for this question.\r\n answer => answer.questionId === model.id\r\n );\r\n\r\n\r\n // Adding of an answer.\r\n const addAnswer = useCallback(() => {\r\n questionnaireQuestionAnswersManager?.addFor({\r\n ...questionAnswerDefaultValues(),\r\n\r\n questionId: model?.id,\r\n });\r\n }, [questionnaireQuestionAnswersManager, model?.id]);\r\n\r\n //when the edit modal is cancelled, we still need to save the questions, as the answers will still exist in the answers manager\r\n //if we dont save it they wont have a question to save against, so we just set it to archived\r\n const [cancelSave] = useAsyncCallback(async () => {\r\n\r\n await questionnaireQuestionsManager.addFor({\r\n ...questionDefaultValues(),\r\n id: model.id,\r\n questionType: model.questionType,\r\n name: \"Questionnaire Question\",\r\n questionText: model.questionText,\r\n\r\n archived: true,\r\n })\r\n\r\n //make sure the answers are all set to archived\r\n await questionnaireQuestionAnswersManager.added.forEach(item => {\r\n if (item.questionId === model.id)\r\n\r\n item.archived = true;\r\n\r\n })\r\n\r\n\r\n toggle()\r\n\r\n }, [toggle, questionnaireQuestionsManager, questionnaireQuestionAnswersManager, model, questionDefaultValues]);\r\n\r\n\r\n //save the Question and the QuestionSequenceQuestion\r\n const [saveForm] = useAsyncCallback(async () => {\r\n if (!validate()) {\r\n return;\r\n }\r\n\r\n\r\n\r\n\r\n //save the question\r\n if (isCreate) {\r\n await questionnaireQuestionsManager.addFor({\r\n ...questionDefaultValues(),\r\n id: model.id,\r\n name: \"Questionnaire Question\",\r\n questionType: model.questionType,\r\n questionText: model.questionText,\r\n });\r\n\r\n\r\n //load an empty sequenceQuestion to save if we dont have one (doesnt need to update as nothing would change)\r\n\r\n let newQuestionSequenceQuestion = {\r\n ...questionSequenceQuestionDefaultValues(),\r\n\r\n childQuestionId: model.id,\r\n parentQuestionId: parentId,\r\n } as QuestionSequenceQuestion;\r\n\r\n //save the created sequenceQuestion\r\n await questionSequenceQuestionsManager.addFor(newQuestionSequenceQuestion)\r\n\r\n }\r\n else if (changes) {\r\n //dont want to commit changes every time, we may not have any changes (e.g. an answer was changed not the question)\r\n\r\n //update the questionnaire question with the changes\r\n questionnaireQuestionsManager.changeFor(model.id, changes)\r\n\r\n }\r\n\r\n toggle()\r\n\r\n }, [model, questionnaireQuestionsManager, parentId, questionSequenceQuestionsManager, questionSequenceQuestionDefaultValues, toggle, changes, ]);\r\n\r\n\r\n const questionTypeCategory = QuestionTypeCategory.QuestionnaireQuestion;\r\n\r\n // Main model validation.\r\n const [validate, validationErrors] = useValidatorCallback((validation, fieldsToCheck) => {\r\n const rules = {\r\n name: () => !model.questionText ? t('CreateQuestionnaireQuestionModal.questionTextRequired', 'Question text is required') : '',\r\n questionType: () => !model.questionType ? t('CreateQuestionnaireQuestionModal.questionTypeRequired', 'Question type is required') : '',\r\n }\r\n\r\n validation.checkRules(rules, fieldsToCheck)\r\n }, [model]);\r\n\r\n return (\r\n toggle()} size=\"xl\" className=\"create-questionnaire-question-modal\">\r\n\r\n toggle()}>\r\n {\r\n t('createQuestiobbaireQuestionModal.heading.question', 'Create question answer')\r\n }\r\n \r\n\r\n \r\n\r\n
{ e.preventDefault(); saveForm(); }}>\r\n \r\n\r\n \r\n change({ questionType: e.currentTarget.value })} onBlur={e => validate('questionType')} validationErrors={validationErrors['questionType']}>\r\n \r\n {\r\n getQuestionTypes(questionTypeCategory).map(item => (\r\n \r\n ))\r\n }\r\n \r\n \r\n \r\n \r\n change({ driverMetricId: e.currentTarget.value || null })} onBlur={e => validate('driverMetricId')} validationErrors={validationErrors['driverMetricId']}>\r\n \r\n {\r\n driverMetrics?.map(item => (\r\n \r\n ))\r\n }\r\n \r\n \r\n \r\n \r\n\r\n \r\n\r\n change({ questionText: html })} />\r\n\r\n
\r\n
\r\n\r\n
\r\n\r\n \r\n\r\n\r\n \r\n\r\n \r\n
\r\n {\r\n orderedAnswers.map(item => (\r\n questionnaireQuestionAnswersManager!.changeFor(item.id, changes)}\r\n remove={() => questionnaireQuestionAnswersManager!.removeFor(item.id)}\r\n\r\n isOpenInitially={!!questionnaireQuestionAnswersManager!.added.find(it => it.id === item.id)}\r\n\r\n moveUp={() => moveAnswerUp(item.id)} canMoveUp={canMoveAnswerUp(item.id)}\r\n moveDown={() => moveAnswerDown(item.id)} canMoveDown={canMoveAnswerDown(item.id)}\r\n\r\n validate={() => validateQuestionAnswer(item)}\r\n validationErrors={questionAnswerValidationErrors(item.id)}\r\n />\r\n ))\r\n }\r\n
\r\n\r\n \r\n
\r\n\r\n \r\n\r\n \r\n\r\n
\r\n \r\n
\r\n
\r\n {\r\n\r\n\r\n orderedAnswers.map(item => (\r\n questionnaireQuestionAnswersManager.changeFor(item.id, changes)}\r\n\r\n remove={() => questionnaireQuestionAnswersManager.removeFor(item.id)}\r\n\r\n isOpenInitially={!!questionnaireQuestionAnswersManager.added.find(it => it.id === item.id)}\r\n\r\n moveUp={() => moveAnswerUp(item.id)} canMoveUp={canMoveAnswerUp(item.id)}\r\n moveDown={() => moveAnswerDown(item.id)} canMoveDown={canMoveAnswerDown(item.id)}\r\n\r\n validate={() => validateQuestionAnswer(item)}\r\n validationErrors={questionAnswerValidationErrors(item.id)}\r\n />\r\n ))\r\n }\r\n
\r\n\r\n \r\n\r\n
\r\n\r\n\r\n
\r\n
\r\n
\r\n\r\n \r\n \r\n <> \r\n \r\n \r\n\r\n
\r\n )\r\n\r\n}","import { FontAwesomeIcon } from \"@fortawesome/react-fontawesome\";\r\nimport { useTranslation } from \"react-i18next\";\r\nimport { Button, ButtonGroup, Col, ListGroupItem, Row, } from \"reactstrap\";\r\nimport { QuestionType, questionTypeDisplayName } from \"../../../../api/main/models/codeOnly/QuestionType\";\r\nimport { Question } from \"../../../../api/main/models/Question\";\r\nimport { QuestionSequenceQuestion } from \"../../../../api/main/models/QuestionSequenceQuestion\";\r\nimport { FormButtons } from \"../../../shared/FormButtons\";\r\nimport { ConditionalFragment } from \"react-conditionalfragment\";\r\nimport { CreateQuestionnaireQuestionModal } from \"../../questionnaires/QuestionnaireQuestion/CreateQuestionnaireQuestionModal/CreateQuestionnaireQuestionModal\";\r\nimport { useCallback } from \"react\";\r\nimport { useToggleState } from \"use-toggle-state\";\r\nimport { ValidationErrors } from \"pojo-validator\";\r\nimport { QuestionAnswer } from \"../../../../api/main/models/QuestionAnswer\";\r\nimport { useAsyncCallback } from 'react-use-async-callback';\r\nimport { ModelArrayChanges } from \"../../../../shared/useChanges\";\r\nimport { HtmlDisplay } from \"../../../../shared/htmlEditor\";\r\nimport { DriverMetric } from \"../../../../api/main/models/DriverMetric\"\r\n\r\nexport interface QuestionnaireQuestionSequenceQuestionComponentProps {\r\n model: QuestionSequenceQuestion,\r\n driverMetrics: Array,\r\n\r\n parent?: Question,\r\n moveUp: () => void,\r\n canMoveUp: boolean,\r\n moveDown: () => void,\r\n canMoveDown: boolean,\r\n\r\n\r\n childQuestion: Question,\r\n\r\n validateQuestionAnswer:(model: QuestionAnswer) => boolean,\r\n questionAnswerValidationErrors: ((id: string) => ValidationErrors)\r\n\r\n questionnaireQuestionAnswersManager: ModelArrayChanges,\r\n questionnaireQuestionsManager: ModelArrayChanges,\r\n questionSequenceQuestionsManager: ModelArrayChanges,\r\n\r\n refresh: () => void,\r\n}\r\n\r\n/**\r\n * A question that forms part of the QuestionSequenceQuestion.\r\n * @param props\r\n */\r\nexport const QuestionnaireQuestionSequenceQuestionComponent = (props: QuestionnaireQuestionSequenceQuestionComponentProps) => {\r\n const {\r\n model,\r\n driverMetrics,\r\n parent,\r\n moveUp,\r\n canMoveUp,\r\n moveDown,\r\n canMoveDown,\r\n\r\n childQuestion,\r\n\r\n validateQuestionAnswer,\r\n questionAnswerValidationErrors,\r\n\r\n questionnaireQuestionAnswersManager,\r\n questionnaireQuestionsManager,\r\n questionSequenceQuestionsManager,\r\n\r\n refresh,\r\n } = props;\r\n\r\n const { t } = useTranslation();\r\n\r\n const divClickedHandler = (event: React.MouseEvent) => {\r\n\r\n toggleQuestionModal();\r\n\r\n }\r\n\r\n // Showing of the question modal.\r\n const [questionModalIsOpen, _toggleQuestionModal] = useToggleState();\r\n const toggleQuestionModal = useCallback(() => {\r\n _toggleQuestionModal();\r\n }, [_toggleQuestionModal]);\r\n\r\n\r\n\r\n //deletes a question and all related objects\r\n const [deleteQuestion] = useAsyncCallback(async () => {\r\n\r\n //take what question needs to be deleted from model before model is deleted\r\n const questionToRemove = childQuestion.id;\r\n\r\n //deleting the relating objects first to prevent errors (if question is deleted first these items wont relate to anything)\r\n //delete the sequence question\r\n await questionSequenceQuestionsManager.removeFor(model.id);\r\n\r\n //delete all relating answers\r\n questionnaireQuestionAnswersManager?.model.forEach(async (item) => {\r\n\r\n if (item.questionId === questionToRemove) {\r\n\r\n await questionnaireQuestionAnswersManager.removeFor(item.id);\r\n\r\n }\r\n });\r\n\r\n //delete the question\r\n await questionnaireQuestionsManager.removeFor(questionToRemove);\r\n\r\n }, [questionSequenceQuestionsManager, questionnaireQuestionsManager, questionnaireQuestionAnswersManager, model]);\r\n\r\n\r\n return (\r\n\r\n <>\r\n\r\n \r\n \r\n \r\n
\r\n\r\n
\r\n\r\n \r\n\r\n
\r\n\r\n\r\n
\r\n
\r\n {questionTypeDisplayName(childQuestion?.questionType as QuestionType, t)}\r\n
\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n
\r\n
\r\n\r\n\r\n\r\n \r\n \r\n \r\n \r\n\r\n\r\n );\r\n\r\n\r\n};","import { useTranslation } from \"react-i18next\";\r\nimport { FormGroup, Label, ListGroup, Button } from \"reactstrap\";\r\nimport { Question } from \"../../../../api/main/models/Question\";\r\nimport { ModelArrayChanges } from \"../../../../shared/useChanges\";\r\nimport { useDisplayOrder } from \"../../../shared/useDisplayOrder/useDisplayOrder\";\r\nimport { QuestionSequenceQuestion } from \"../../../../api/main/models/QuestionSequenceQuestion\";\r\nimport { QuestionnaireQuestionSequenceQuestionComponent } from \"./QuestionnaireQuestionSequenceQuestionComponent\";\r\nimport { QuestionAnswer } from \"../../../../api/main/models/QuestionAnswer\";\r\nimport { useCallback } from \"react\";\r\nimport { useToggleState } from \"use-toggle-state\";\r\nimport { FontAwesomeIcon } from \"@fortawesome/react-fontawesome\";\r\nimport { ConditionalFragment } from \"react-conditionalfragment\";\r\nimport { CreateQuestionnaireQuestionModal } from \"../../questionnaires/QuestionnaireQuestion/CreateQuestionnaireQuestionModal/CreateQuestionnaireQuestionModal\";\r\nimport { Guid } from \"guid-string\";\r\nimport { ValidatedInput } from 'pojo-validator-reactstrap';\r\nimport { ValidationErrors } from \"pojo-validator\";\r\nimport { ValidateCallback } from '../../../../../node_modules/pojo-validator-react/dist/lib/esm/ValidateCallback';\r\nimport { DriverMetric } from \"../../../../api/main/models/DriverMetric\"\r\n\r\nexport interface QuestionnaireQuestionsTabProps {\r\n model: Question | undefined,\r\n driverMetrics: Array,\r\n\r\n change: (changes: Partial) => void,\r\n validate: ValidateCallback,\r\n validationErrors: ValidationErrors,\r\n\r\n questionSequenceQuestionsManager: ModelArrayChanges,\r\n\r\n questionnaireQuestionAnswersManager: ModelArrayChanges,\r\n validateQuestionAnswer: (model: QuestionAnswer) => boolean,\r\n questionAnswerValidationErrors: (id: string) => ValidationErrors,\r\n\r\n refresh: () => void,\r\n\r\n questionnaireQuestionsManager: ModelArrayChanges,\r\n}\r\n\r\nexport const SequenceOfQuestionnaireQuestionsTab = (props: QuestionnaireQuestionsTabProps) => {\r\n const {\r\n model,\r\n driverMetrics,\r\n\r\n change,\r\n validate,\r\n validationErrors,\r\n\r\n questionSequenceQuestionsManager,\r\n\r\n questionnaireQuestionAnswersManager,\r\n validateQuestionAnswer,\r\n questionAnswerValidationErrors,\r\n\r\n refresh,\r\n\r\n questionnaireQuestionsManager,\r\n } = props;\r\n\r\n const { t } = useTranslation();\r\n\r\n // Showing of the question modal.\r\n const [questionModalIsOpen, _toggleQuestionModal] = useToggleState();\r\n const toggleQuestionModal = useCallback(() => {\r\n _toggleQuestionModal();\r\n }, [ _toggleQuestionModal]);\r\n\r\n // Order the answers so they show in and can be managed by displayOrder.\r\n const [orderedQuestions, {\r\n canMoveUp: canMoveAnswerUp,\r\n moveUp: moveAnswerUp,\r\n canMoveDown: canMoveAnswerDown,\r\n moveDown: moveAnswerDown,\r\n }] = useDisplayOrder(questionSequenceQuestionsManager);\r\n\r\n const newQuestion = useCallback(() => {\r\n\r\n toggleQuestionModal();\r\n\r\n }, [toggleQuestionModal]);\r\n\r\n const emptyQuestion = {\r\n id: Guid.newGuid(),\r\n name: '',\r\n questionType: '',\r\n questionText: '',\r\n imageBlobReferenceId: null,\r\n videoBlobReferenceId: null,\r\n questionTextImageBlobReferenceId: null,\r\n preQuestionText: '',\r\n maximumClicks: 10,\r\n } as Question;\r\n\r\n return (\r\n <>\r\n \r\n \r\n change({ questionText: e.currentTarget.value })} onBlur={e => validate('question Text')} validationErrors={validationErrors['question Text']} />\r\n\r\n \r\n\r\n \r\n {\r\n orderedQuestions.map(item => {\r\n const childQuestion = questionnaireQuestionsManager.model.find(it => it.id === item.childQuestionId);\r\n\r\n return (\r\n moveAnswerUp(item.id)} canMoveUp={canMoveAnswerUp(item.id)}\r\n moveDown={() => moveAnswerDown(item.id)} canMoveDown={canMoveAnswerDown(item.id)}\r\n\r\n childQuestion={childQuestion!}\r\n\r\n validateQuestionAnswer={validateQuestionAnswer}\r\n questionAnswerValidationErrors={questionAnswerValidationErrors}\r\n refresh={refresh}\r\n\r\n questionnaireQuestionAnswersManager={questionnaireQuestionAnswersManager}\r\n questionSequenceQuestionsManager={questionSequenceQuestionsManager}\r\n questionnaireQuestionsManager={questionnaireQuestionsManager}\r\n />\r\n );\r\n })\r\n }\r\n \r\n \r\n\r\n \r\n \r\n \r\n\r\n \r\n \r\n \r\n \r\n )\r\n}","import { ConditionalFragment } from \"react-conditionalfragment\";\r\nimport { useTranslation } from \"react-i18next\";\r\nimport { FormGroup, Label } from \"reactstrap\";\r\nimport { QuestionType } from \"../../../../api/main/models/codeOnly/QuestionType\";\r\nimport { Question } from \"../../../../api/main/models/Question\";\r\nimport { HtmlEditor } from \"../../../../shared/htmlEditor\";\r\n\r\nexport interface InformationTextTabProps {\r\n model: Question | undefined,\r\n change: (changes: Partial) => void,\r\n}\r\n\r\n/**\r\n * Tab for the text part of all Learning types.\r\n * @param props\r\n */\r\nexport const InformationTextTab = (props: InformationTextTabProps) => {\r\n const {\r\n model,\r\n change,\r\n } = props;\r\n\r\n const { t } = useTranslation();\r\n\r\n return (\r\n <>\r\n \r\n \r\n \r\n\r\n change({ preQuestionText: html })} />\r\n \r\n \r\n \r\n\r\n change({ questionText: html })} />\r\n \r\n \r\n \r\n \r\n \r\n\r\n change({ questionText: html })} />\r\n \r\n \r\n \r\n );\r\n};","import { FontAwesomeIcon } from \"@fortawesome/react-fontawesome\";\r\nimport { ValidationErrors } from \"pojo-validator\";\r\nimport { ValidateCallback } from \"pojo-validator-react\";\r\nimport { ValidatedInput } from \"pojo-validator-reactstrap\";\r\nimport { useCallback } from \"react\";\r\nimport { useTranslation } from \"react-i18next\";\r\nimport { useAsyncCallback } from \"react-use-async-callback\";\r\nimport { Button, ButtonGroup, Card, CardBody, Col, Collapse, Dropdown, DropdownItem, DropdownMenu, DropdownToggle, FormGroup, FormText, InputGroup, InputGroupAddon, Label, Row, Spinner} from \"reactstrap\";\r\nimport { useToggleState } from \"use-toggle-state\";\r\nimport { BlobReference } from \"../../../../api/main/models/BlobReference\";\r\nimport { QuestionAnswer } from \"../../../../api/main/models/QuestionAnswer\";\r\nimport { HtmlDisplay, HtmlEditor } from \"../../../../shared/htmlEditor\";\r\nimport { CardHeaderCollapse } from \"../../../shared/cardHeaderCollapse/CardHeaderCollapse\";\r\nimport { FileUploadButton } from \"../../../shared/fileUploadButton/FileUploadButton\";\r\nimport { FormButtons } from \"../../../shared/FormButtons\";\r\nimport { TwoValueSwitch } from \"../../../shared/TwoValueSwitch\";\r\nimport { UploadedImagePreview } from \"../../../shared/uploadedImagePreview/UploadedImagePreview\";\r\nimport { ConditionalFragment } from \"react-conditionalfragment\";\r\n\r\nexport interface QuestionAnswerMultipleChoiceImageProps {\r\n model: QuestionAnswer | undefined,\r\n change: (changes: Partial) => void,\r\n remove: () => void,\r\n moveUp: () => void,\r\n canMoveUp: boolean,\r\n moveDown: () => void,\r\n canMoveDown: boolean,\r\n\r\n answerTextImageBlob: BlobReference | undefined | null,\r\n uploadChildBlob: (files: FileList | null) => Promise,\r\n\r\n isOpenInitially?: boolean,\r\n\r\n validate: ValidateCallback,\r\n validationErrors: ValidationErrors,\r\n}\r\n\r\n/**\r\n * Tab for maintaining the prompt for the question and the available multiple choice answers.\r\n * @param props\r\n */\r\nexport const QuestionAnswerMultipleChoiceImage = (props: QuestionAnswerMultipleChoiceImageProps) => {\r\n const {\r\n model,\r\n change,\r\n remove,\r\n moveUp,\r\n canMoveUp,\r\n moveDown,\r\n canMoveDown,\r\n\r\n answerTextImageBlob,\r\n uploadChildBlob,\r\n isOpenInitially = false,\r\n\r\n validate,\r\n validationErrors,\r\n } = props;\r\n\r\n const { t } = useTranslation();\r\n\r\n // Self management of if we are expanded or not.\r\n const [isOpen, toggleOpen] = useToggleState(isOpenInitially);\r\n\r\n // Uploading the answer text blob.\r\n const [uploadAnswerTextImageBlob, { isExecuting: isUploadingAnswerTextImageBlob }] = useAsyncCallback(async (files: FileList | null) => {\r\n const blob = await uploadChildBlob(files);\r\n if (!blob) {\r\n return;\r\n }\r\n\r\n change({ answerTextImageBlobReferenceId: blob.id });\r\n }, [uploadChildBlob, change]);\r\n const clearAnswerTextImageBlob = useCallback(() => {\r\n change({ answerTextImageBlobReferenceId: null });\r\n }, [change]);\r\n const [isAnswerImageDropdownOpen, toggleAnswerImageDropdown] = useToggleState();\r\n\r\n return (\r\n \r\n \r\n
\r\n \r\n
\r\n
\r\n\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n\r\n \r\n \r\n change({ answerText: html })} />\r\n \r\n\r\n \r\n \r\n \r\n \r\n\r\n {\r\n // Toggle the flag, and if we're using default scoring at the moment, also default the score.\r\n if (checked && model?.score === 0) {\r\n change({ isCorrect: checked, score: 100 });\r\n } else if (!checked && model?.score === 100) {\r\n change({ isCorrect: checked, score: 0 });\r\n } else {\r\n change({ isCorrect: checked });\r\n }\r\n }}\r\n />\r\n \r\n \r\n \r\n \r\n \r\n\r\n \r\n change({ score: e.currentTarget.valueAsNumber })} onBlur={() => validate('score')} validationErrors={validationErrors['score']} />\r\n \r\n {t('common.percentageSign', '%')}\r\n \r\n \r\n \r\n {t('questionAnswerMultipleChoiceImage.score.help', 'Score will normally be between 0% (incorrect) and 100% (correct).')}\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n\r\n {\r\n // Toggle the flag\r\n change({ isSuspicious: checked });\r\n if (checked) {\r\n change({ suspicionScore: 1 }); // If we are setting the answer to suspicious, we want to have a suspicion score, so setting this to 1 as default.\r\n } else {\r\n change({ suspicionScore: undefined }); // If we are setting the answer to not suspicious, we no longer need a suspicion score, so we can set this to undefined.\r\n }\r\n\r\n }}\r\n />\r\n \r\n \r\n \r\n \r\n \r\n \r\n\r\n \r\n change({ suspicionScore: e.currentTarget.valueAsNumber })} onBlur={() => validate('suspicionScore')} validationErrors={validationErrors['suspicionScore']} />\r\n \r\n \r\n {t('questionAnswerMultipleChoiceVideo.suspicionScore.help', 'At the end of an assessment, any selected suspicious answers will have their suspicion scores added together to see if they exceed the limit set on the assessment.')}\r\n \r\n \r\n \r\n \r\n \r\n\r\n \r\n \r\n\r\n \r\n\r\n \r\n uploadAnswerTextImageBlob(files)} isExecuting={isUploadingAnswerTextImageBlob}\r\n executingChildren={<><> {t('common.uploading', 'Uploading...')}}\r\n >\r\n {t('questionAnswerMultipleChoiceImage.uploadImage', 'Upload image...')}\r\n \r\n toggleAnswerImageDropdown()}>\r\n \r\n \r\n {t('common.more', 'More')}\r\n \r\n \r\n \r\n clearAnswerTextImageBlob()}>\r\n {t('questionAnswerMultipleChoiceImage.clearImage', 'Clear image')}\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n
\r\n );\r\n};","import { useCallback } from \"react\";\r\nimport { useTranslation } from \"react-i18next\";\r\nimport { Button, FormGroup, Label } from \"reactstrap\";\r\nimport { BlobReference } from \"../../../../api/main/models/BlobReference\";\r\nimport { Question } from \"../../../../api/main/models/Question\";\r\nimport { QuestionAnswer, questionAnswerDefaultValues } from \"../../../../api/main/models/QuestionAnswer\";\r\nimport { HtmlEditor } from \"../../../../shared/htmlEditor\";\r\nimport { ModelArrayChanges } from \"../../../../shared/useChanges\";\r\nimport { QuestionAnswerMultipleChoiceImage } from \"./QuestionAnswerMultipleChoiceImage\";\r\nimport { useDisplayOrder } from \"../../../shared/useDisplayOrder/useDisplayOrder\";\r\nimport { ValidationErrors } from \"pojo-validator\";\r\n\r\nexport interface QuestionPromptMultipleChoiceImageTabProps {\r\n model: Question | undefined,\r\n change: (changes: Partial) => void,\r\n\r\n answersManager: ModelArrayChanges,\r\n\r\n childBlobs: Array,\r\n uploadChildBlob: (files: FileList | null) => Promise,\r\n\r\n validateQuestionAnswer: (model: QuestionAnswer) => boolean,\r\n questionAnswerValidationErrors: (id: string) => ValidationErrors,\r\n}\r\n\r\n/**\r\n * Tab for maintaining the prompt for the question and the available multiple choice answers.\r\n * @param props\r\n */\r\nexport const QuestionPromptMultipleChoiceImageTab = (props: QuestionPromptMultipleChoiceImageTabProps) => {\r\n const {\r\n model,\r\n change,\r\n\r\n answersManager,\r\n childBlobs,\r\n uploadChildBlob,\r\n\r\n validateQuestionAnswer,\r\n questionAnswerValidationErrors,\r\n } = props;\r\n\r\n const { t } = useTranslation();\r\n\r\n // Order the answers so they show in and can be managed by displayOrder.\r\n const [orderedAnswers, {\r\n canMoveUp: canMoveAnswerUp,\r\n moveUp: moveAnswerUp,\r\n canMoveDown: canMoveAnswerDown,\r\n moveDown: moveAnswerDown,\r\n }] = useDisplayOrder(answersManager);\r\n \r\n\r\n // Adding of an answer.\r\n const addAnswer = useCallback(() => {\r\n answersManager.addFor({\r\n ...questionAnswerDefaultValues(),\r\n\r\n questionId: model?.id,\r\n });\r\n }, [answersManager, model?.id]);\r\n\r\n return (\r\n <>\r\n \r\n \r\n\r\n change({ questionText: html })} />\r\n \r\n\r\n \r\n \r\n\r\n
\r\n {\r\n orderedAnswers.map(item => (\r\n answersManager.changeFor(item.id, changes)}\r\n remove={() => answersManager.removeFor(item.id)}\r\n\r\n isOpenInitially={!!answersManager.added.find(it => it.id === item.id)}\r\n\r\n moveUp={() => moveAnswerUp(item.id)} canMoveUp={canMoveAnswerUp(item.id)}\r\n moveDown={() => moveAnswerDown(item.id)} canMoveDown={canMoveAnswerDown(item.id)}\r\n\r\n answerTextImageBlob={childBlobs.find(it => it.id === item.answerTextImageBlobReferenceId)}\r\n uploadChildBlob={uploadChildBlob}\r\n\r\n validate={() => validateQuestionAnswer(item)}\r\n validationErrors={questionAnswerValidationErrors(item.id)}\r\n />\r\n ))\r\n }\r\n
\r\n\r\n \r\n
\r\n \r\n );\r\n};","import { Button, Row, Col, Form, Label, FormGroup, Spinner, NavItem, NavLink } from 'reactstrap';\r\nimport { AlertOnErrors } from '../../../shared/alertOnErrors';\r\nimport { LoadingIndicator } from '../../shared/LoadingIndicator';\r\nimport { useTranslation } from 'react-i18next';\r\nimport { FontAwesomeIcon } from '@fortawesome/react-fontawesome';\r\nimport { MainContainer } from '../../shared/MainContainer';\r\nimport { useParams, useHistory } from 'react-router';\r\nimport { useChanges, useChangesArray } from '../../../shared/useChanges';\r\nimport { useSaveQuestionCallback } from '../../../api/main/questions/useSaveQuestionCallback';\r\nimport { useDeleteQuestionCallback } from '../../../api/main/questions/useDeleteQuestionCallback';\r\nimport { useValidatorCallback } from 'pojo-validator-react';\r\nimport { ValidatedInput } from 'pojo-validator-reactstrap';\r\nimport { FormButtons } from '../../shared/FormButtons';\r\nimport { ButtonAsync } from 'reactstrap-buttonasync';\r\nimport { useAsyncCallback } from 'react-use-async-callback';\r\nimport { Guid } from 'guid-string';\r\nimport { ConditionalFragment } from 'react-conditionalfragment';\r\nimport { Banner } from '../../shared/Banner';\r\nimport { Background } from '../../shared/background/Background';\r\nimport { useEditQuestionViewModel } from '../../../api/main/questions/viewModels/useEditQuestionViewModel';\r\nimport { getQuestionTypeCategory, getQuestionTypes, QuestionType, QuestionTypeCategory, questionTypeDisplayName } from '../../../api/main/models/codeOnly/QuestionType';\r\nimport { PillsNavBar } from '../../shared/pillsNavBar/PillsNavBar';\r\nimport { VideoTab } from './video/VideoTab';\r\nimport { useBlobReferenceState } from '../../shared/useBlobReferenceState/useBlobReferenceState';\r\nimport { QuestionPromptMultipleChoiceVideoTab } from './multipleChoiceVideo/QuestionPromptMultipleChoiceVideoTab';\r\nimport { useSaveQuestionAnswerCallback } from '../../../api/main/questionAnswers/useSaveQuestionAnswerCallback';\r\nimport { useDeleteQuestionAnswerCallback } from '../../../api/main/questionAnswers/useDeleteQuestionAnswerCallback';\r\nimport { QuestionAnswer } from '../../../api/main/models/QuestionAnswer';\r\nimport { BlobReference } from '../../../api/main/models/BlobReference';\r\nimport { useBlobReferenceStateArray } from '../../shared/useBlobReferenceState/useBlobReferenceStateArray';\r\nimport { StickyToolbar } from '../../shared/StickyToolbar';\r\nimport { FeedbackTab } from './feedback/FeedbackTab';\r\nimport { QuestionFeedback } from '../../../api/main/models/QuestionFeedback';\r\nimport { useSaveQuestionFeedbackCallback } from '../../../api/main/questionFeedbacks/useSaveQuestionFeedbackCallback';\r\nimport { useDeleteQuestionFeedbackCallback } from '../../../api/main/questionFeedbacks/useDeleteQuestionFeedbackCallback';\r\nimport { QuestionTagsTab } from './questionTags/QuestionTagsTab';\r\nimport { useEditQuestionSupportingData } from '../../../api/main/questions/viewModels/useEditQuestionSupportingData';\r\nimport { QuestionTagLink } from '../../../api/main/models/QuestionTagLink';\r\nimport { useDeleteQuestionTagLinkCallback } from '../../../api/main/questionTagLinks/useDeleteQuestionTagLinkCallback';\r\nimport { DriverMetricsTab } from './driverMetrics/DriverMetricsTab';\r\nimport { DriverMetricAdjustment } from '../../../api/main/models/DriverMetricAdjustment';\r\nimport { useSaveDriverMetricAdjustmentCallback } from '../../../api/main/driverMetricAdjustments/useSaveDriverMetricAdjustmentCallback';\r\nimport { useDeleteDriverMetricAdjustmentCallback } from '../../../api/main/driverMetricAdjustments/useDeleteDriverMetricAdjustmentCallback';\r\nimport { DriverMetricRecommendation } from '../../../api/main/models/DriverMetricRecommendation';\r\nimport { useSaveDriverMetricRecommendationCallback } from '../../../api/main/driverMetricRecommendations/useSaveDriverMetricRecommendationCallback';\r\nimport { useDeleteDriverMetricRecommendationCallback } from '../../../api/main/driverMetricRecommendations/useDeleteDriverMetricRecommendationCallback';\r\nimport { useSaveQuestionTagLinkCallback } from '../../../api/main/questionTagLinks/useSaveQuestionTagLinkCallback';\r\nimport { useValidatorArrayCallback } from '../../../shared/validator-react-contrib/useValidatorArrayCallback';\r\nimport { hasAnyValidationErrors } from '../../../utilities/hasAnyValidationErrors';\r\nimport { QuestionPromptSlidingScaleVideoTab } from './slidingScaleVideo/QuestionPromptSlidingScaleVideoTab';\r\nimport { QuestionPromptResponseTimeVideoTab } from './responseTimeVideo/QuestionPromptResponseTimeVideoTab';\r\nimport { ImageTab } from './image/ImageTab';\r\nimport { QuestionPromptLocationResponseImageTab } from './locationResponseImage/QuestionPromptLocationResponseImageTab';\r\nimport { QuestionPromptLocationDiscriminationImageTab } from './locationDiscriminationImage/QuestionPromptLocationDiscriminationImageTab';\r\nimport { SequenceOfQuestionsTab } from './sequenceOfQuestions/SequenceOfQuestionsTab';\r\nimport { QuestionSequenceQuestion } from '../../../api/main/models/QuestionSequenceQuestion';\r\nimport { useSaveQuestionSequenceQuestionCallback } from '../../../api/main/questionSequenceQuestions/useSaveQuestionSequenceQuestionCallback';\r\nimport { useDeleteQuestionSequenceQuestionCallback } from '../../../api/main/questionSequenceQuestions/useDeleteQuestionSequenceQuestionCallback';\r\nimport { useCallback, useEffect, useMemo, useState } from 'react';\r\nimport { useQuestions } from '../../../api/main/questions/useQuestions';\r\nimport { Question, questionDefaultValues } from '../../../api/main/models/Question';\r\nimport { LearningTextTab } from './learningText/LearningTextTab';\r\nimport { SequenceOfQuestionnaireQuestionsTab } from '../questionnaires/QuestionnaireQuestion/SequenceOfQuestionnaireQuestionsTab';\r\nimport { InformationTextTab } from './informationText/InformationTextTab';\r\nimport { QuestionPromptMultipleChoiceImageTab } from './multipleChoiceImage/QuestionPromptMultipleChoiceImageTab';\r\n\r\n\r\ninterface EditQuestionBaseProps {\r\n isCreate?: boolean,\r\n onCreateDefaultValues?: () => Partial,\r\n defaultQuestionType: QuestionType,\r\n}\r\n\r\n\r\n/**\r\n * Create and a new question.\r\n */\r\nexport const CreateQuestionBase = (props: EditQuestionBaseProps) => ();\r\n\r\n/**\r\n * Edit a question.\r\n */\r\nexport const EditQuestionBase = (props: EditQuestionBaseProps) => {\r\n const {\r\n isCreate,\r\n onCreateDefaultValues,\r\n defaultQuestionType,\r\n } = props;\r\n\r\n const { t } = useTranslation();\r\n const { id } = useParams<{ id: string | undefined }>();\r\n const { data: {\r\n model: storeModel,\r\n answers: storeAnswers,\r\n questionnaireQuestionAnswers: storeQuestionnaireQuestionAnswers,\r\n feedbacks: storeFeedbacks,\r\n questionTagLinks: storeQuestionTagLinks,\r\n driverMetricRecommendations: storeDriverMetricRecommendations,\r\n driverMetricAdjustments: storeDriverMetricAdjustments,\r\n questionSequenceQuestions: storeQuestionSequenceQuestions,\r\n }, isLoading: _isLoading, errors: loadErrors, refresh: refreshEdit } = useEditQuestionViewModel(id);\r\n const { data: { questionTags, driverMetrics, }, isLoading: isLoadingSupportingData, errors: loadSupportingDataErrors } = useEditQuestionSupportingData();\r\n const isLoading = _isLoading || isLoadingSupportingData;\r\n const { model, change, changes } = useChanges(storeModel, isCreate ? { ...questionDefaultValues(), ...(onCreateDefaultValues ? onCreateDefaultValues() : {}) } : undefined);\r\n const [save, { errors: saveErrors }] = useSaveQuestionCallback();\r\n const history = useHistory();\r\n\r\n // We want to customise the interface based on the category of question we are.\r\n const activeQuestionType = model?.questionType as QuestionType ?? defaultQuestionType;\r\n const activeQuestionTypeCategory: QuestionTypeCategory = useMemo(() => getQuestionTypeCategory(model?.questionType as QuestionType || defaultQuestionType), [model, defaultQuestionType]);\r\n\r\n // Video and image display and uploading\r\n const [videoBlob, setVideoBlob, { upload: uploadVideoBlob, isUploading: isUploadingVideoBlob, uploadErrors: uploadVideoBlobErrors, clearUpload: clearVideoBlob }] = useBlobReferenceState(blob => {\r\n change({ videoBlobReferenceId: blob?.id ?? null });\r\n });\r\n useEffect(() => setVideoBlob(storeModel?.videoBlobReference ?? null), [setVideoBlob, storeModel]);\r\n\r\n const [imageBlob, setImageBlob, { upload: uploadImageBlob, isUploading: isUploadingImageBlob, uploadErrors: uploadImageBlobErrors, clearUpload: clearImageBlob }] = useBlobReferenceState(blob => {\r\n change({ imageBlobReferenceId: blob?.id ?? null });\r\n });\r\n useEffect(() => setImageBlob(storeModel?.imageBlobReference ?? null), [setImageBlob, storeModel]);\r\n\r\n const [questionTextImageBlob, setQuestionTextImageBlob, { upload: uploadQuestionTextImageBlob, isUploading: isUploadingQuestionTextImageBlob, uploadErrors: uploadQuestionTextImageBlobErrors, clearUpload: clearQuestionTextImageBlob }] = useBlobReferenceState(blob => {\r\n change({ questionTextImageBlobReferenceId: blob?.id ?? null });\r\n });\r\n useEffect(() => setQuestionTextImageBlob(storeModel?.questionTextImageBlobReference ?? null), [setQuestionTextImageBlob, storeModel]);\r\n\r\n // Blobs for child objects need to be managed as a dictionary of id to blobs.\r\n const [childBlobs, setChildBlobs, { upload: uploadChildBlob, uploadErrors: uploadChildBlobErrors }] = useBlobReferenceStateArray();\r\n useEffect(() => {\r\n let ret: Array = [];\r\n\r\n if (storeAnswers) {\r\n for (const answer of storeAnswers) {\r\n ret.push(answer?.answerTextImageBlobReference);\r\n ret.push(answer?.scaleImageBlobReference);\r\n }\r\n }\r\n\r\n if (storeFeedbacks) {\r\n for (const feedback of storeFeedbacks) {\r\n ret.push(feedback?.videoBlobReference);\r\n ret.push(feedback?.imageBlobReference);\r\n }\r\n }\r\n\r\n setChildBlobs(ret.filter(item => !!item) as Array);\r\n }, [setChildBlobs, storeAnswers, storeFeedbacks]);\r\n\r\n // Answers.\r\n const answersManager = useChangesArray(storeAnswers, item => item.id);\r\n const [saveQuestionAnswer] = useSaveQuestionAnswerCallback();\r\n const [removeQuestionAnswer] = useDeleteQuestionAnswerCallback();\r\n\r\n // Feedbacks.\r\n const feedbacksManager = useChangesArray(storeFeedbacks, item => item.id);\r\n const [saveQuestionFeedback] = useSaveQuestionFeedbackCallback();\r\n const [removeQuestionFeedback] = useDeleteQuestionFeedbackCallback();\r\n\r\n // QuestionTagLinks.\r\n const questionTagLinksManager = useChangesArray(storeQuestionTagLinks, item => item.id);\r\n const [saveQuestionTagLink] = useSaveQuestionTagLinkCallback();\r\n const [removeQuestionTagLink] = useDeleteQuestionTagLinkCallback();\r\n\r\n // DriverMetricAdjustments.\r\n const driverMetricAdjustmentsManager = useChangesArray(storeDriverMetricAdjustments, item => item.id);\r\n const [saveQuestionDriverMetricAdjustment] = useSaveDriverMetricAdjustmentCallback();\r\n const [removeQuestionDriverMetricAdjustment] = useDeleteDriverMetricAdjustmentCallback();\r\n\r\n // DriverMetricRecommendations.\r\n const driverMetricRecommendationsManager = useChangesArray(storeDriverMetricRecommendations, item => item.id);\r\n const [saveQuestionDriverMetricRecommendation] = useSaveDriverMetricRecommendationCallback();\r\n const [removeQuestionDriverMetricRecommendation] = useDeleteDriverMetricRecommendationCallback();\r\n\r\n // QuestionSequenceQuestion.\r\n const questionSequenceQuestionsManager = useChangesArray(storeQuestionSequenceQuestions, item => item.id);\r\n const [saveQuestionQuestionSequenceQuestion] = useSaveQuestionSequenceQuestionCallback();\r\n const [removeQuestionQuestionSequenceQuestion] = useDeleteQuestionSequenceQuestionCallback();\r\n\r\n //turn the filtered answers into a manager for changes\r\n const questionnaireQuestionAnswersManager = useChangesArray(storeQuestionnaireQuestionAnswers, item => item.id);\r\n\r\n // For QuestionSequenceQuestions we need to allow a list of all (other) questions to be shown. We don't want to load this list until we need it though\r\n // so when the question loads we load the child questions for each of the QuestionSequenceQuestions and we start by just having those loaded. If we need\r\n // to show more questions than that, then we are able to really load all questions at that point.\r\n const { data: { items: _allQuestions }, isLoading: isLoadingAllQuestions, errors: loadAllQuestionsErrors, refresh: loadAllQuestions } = useQuestions({ lazy: true });\r\n const allQuestions = useMemo(() => {\r\n // If we haven't loaded all the questions yet, then fall back on just the child questions we know we've loaded.\r\n if (!_allQuestions) {\r\n return storeQuestionSequenceQuestions?.map(item => item.childQuestion)?.filter(item => !!item) ?? [];\r\n }\r\n\r\n // Otherwise return all questions, with our own question removed so we can't create a circular reference.\r\n return _allQuestions.filter(item => item.id !== model?.id);\r\n }, [storeQuestionSequenceQuestions, _allQuestions, model]);\r\n const ensureAllQuestionsLoaded = useCallback(() => {\r\n // If we've already loaded all questions, then we don't need to do anything.\r\n if (_allQuestions) {\r\n return;\r\n }\r\n\r\n // If we are already loading all questions, then we also don't need to do anything as we'll get there once it completes.\r\n if (isLoadingAllQuestions) {\r\n return;\r\n }\r\n\r\n // Otherwise lets trigger the load of all questions.\r\n loadAllQuestions();\r\n }, [_allQuestions, isLoadingAllQuestions, loadAllQuestions]);\r\n\r\n //QuestionnaireQuestions.\r\n //Save is not needed as it is already added as \"save\".\r\n const questionnaireQuestionsManager = useChangesArray(allQuestions, item => item.id)\r\n const [removeQuestionnaireQuestion] = useDeleteQuestionCallback();\r\n\r\n // Validation\r\n //\r\n const [validateQuestionFeedback, questionFeedbackValidationErrors] = useValidatorArrayCallback((myModel, validation, fieldsToCheck) => {\r\n const rules = {\r\n // No rules required.\r\n };\r\n\r\n validation.checkRules(rules, fieldsToCheck);\r\n }, []);\r\n\r\n const [validateQuestionAnswer, questionAnswerValidationErrors] = useValidatorArrayCallback((myModel, validation, fieldsToCheck) => {\r\n const rules = {\r\n score: () => myModel.score > 100 || myModel.score < 0 ? t('editQuestion.validateQuestionAnswer.score', 'Score must be between 0 and 100') : '',\r\n };\r\n\r\n validation.checkRules(rules, fieldsToCheck);\r\n }, []);\r\n\r\n const [validateDriverMetricAdjustment, driverMetricAdjustmentValidationErrors] = useValidatorArrayCallback((myModel, validation, fieldsToCheck) => {\r\n const rules = {\r\n driverMetricId: () => Guid.isEmpty(myModel.driverMetricId) ? t('editQuestion.validateDriverMetricAdjustment.driveMetricRequired', 'Metric is required') : '',\r\n adjustmentValue: () => myModel.adjustmentValue === 0 ? t('editQuestion.validateDriverMetricAdjustment.adjustmentValueRequired', 'Adjustment cannot be zero') : '',\r\n };\r\n\r\n validation.checkRules(rules, fieldsToCheck);\r\n }, []);\r\n\r\n const [validateDriverMetricRecommendation, driverMetricRecommendationValidationErrors] = useValidatorArrayCallback((myModel, validation, fieldsToCheck) => {\r\n const rules = {\r\n driverMetricId: () => Guid.isEmpty(myModel.driverMetricId) ? t('editQuestion.validateDriverMetricRecommendation.driveMetricRequired', 'Metric is required') : '',\r\n };\r\n\r\n validation.checkRules(rules, fieldsToCheck);\r\n }, []);\r\n\r\n // Main model validation.\r\n const [validate, validationErrors] = useValidatorCallback((validation, fieldsToCheck) => {\r\n const rules = {\r\n name: () => !model?.name ? t('editQuestion.nameRequired', 'Name is required') : '',\r\n questionType: () => !model?.questionType ? (\r\n activeQuestionTypeCategory === QuestionTypeCategory.Learning ? t('editQuestion.questionType.required.learning', 'Type of learning is required')\r\n : activeQuestionTypeCategory === QuestionTypeCategory.Questionnaire ? t('editQuestion.questionType.required.questionnaire', 'Type of questionnaire is required')\r\n : t('editQuestion.questionType.required.default', 'Type of question is required')\r\n ): '',\r\n\r\n // Validate related objects\r\n feedback: () => feedbacksManager.model.filter(it => !validateQuestionFeedback(it)).length ? t('editCalendarEvent.feedbacksInvalid', 'One or more of the feedbacks are invalid') : '',\r\n answers: () => answersManager.model.filter(it => !validateQuestionAnswer(it)).length ? t('editCalendarEvent.answersInvalid', 'One or more of the answers are invalid') : '',\r\n driverMetricRecommendations: () => driverMetricRecommendationsManager.model.filter(it => !validateDriverMetricRecommendation(it)).length ? t('editCalendarEvent.driverMetricRecommendationsInvalid', 'One or more of the drive metric recommendation rules are invalid') : '',\r\n driverMetricAdjustments: () => driverMetricAdjustmentsManager.model.filter(it => !validateDriverMetricAdjustment(it)).length ? t('editCalendarEvent.driverMetricAdjustmentsInvalid', 'One or more of the drive metric recommendation rules are invalid') : '',\r\n };\r\n\r\n validation.checkRules(rules, fieldsToCheck);\r\n }, [\r\n model,\r\n feedbacksManager, validateQuestionFeedback,\r\n answersManager, validateQuestionAnswer,\r\n driverMetricRecommendationsManager, validateDriverMetricRecommendation,\r\n driverMetricAdjustmentsManager, validateDriverMetricAdjustment,\r\n activeQuestionTypeCategory,\r\n ]);\r\n\r\n // Saving.\r\n const [saveForm, { isExecuting: isSaving, errors: saveFormErrors }] = useAsyncCallback(async () => {\r\n if (!validate()) {\r\n return;\r\n }\r\n if (model.questionType === QuestionType.Questionnaire) {\r\n changes.numberOfSubQuestions = questionnaireQuestionsManager.model.length - questionnaireQuestionsManager.removed.length;\r\n }\r\n // Save the main model.\r\n await save(model.id, changes, !!isCreate);\r\n\r\n //Save the questionnaire questions.\r\n //need to happen before the answers and sequence questions are saved so they have something to put as foreign key\r\n for (const item of questionnaireQuestionsManager.added) { await save(item.id, questionnaireQuestionsManager.changesFor(item.id), true); }\r\n for (const item of questionnaireQuestionsManager.updated) { await save(item.id, questionnaireQuestionsManager.changesFor(item.id), false); }\r\n for (const item of questionnaireQuestionsManager.removed) { await removeQuestionnaireQuestion(item.id); }\r\n questionnaireQuestionsManager.markAsSaved();\r\n \r\n // Change any new or updated answer texts to remove blank lines from the end\r\n for (const item of answersManager.added) { await answersManager.changeFor(item.id, ({ answerText: item.answerText.replace(\"
 

\", \"

\") })); }\r\n for (const item of answersManager.updated) { await answersManager.changeFor(item.id, ({ answerText: item.answerText.replace(\"
 

\", \"

\") })); }\r\n\r\n // Save the answers.\r\n for (const item of answersManager.added) { await saveQuestionAnswer(item.id, answersManager.changesFor(item.id), true); }\r\n for (const item of answersManager.updated) { await saveQuestionAnswer(item.id, answersManager.changesFor(item.id), false); }\r\n for (const item of answersManager.removed) { await removeQuestionAnswer(item.id); }\r\n answersManager.markAsSaved();\r\n\r\n // Questionnaire Question Answers\r\n // Save the questionnaire question answers\r\n for (const item of questionnaireQuestionAnswersManager.added) { await saveQuestionAnswer(item.id, questionnaireQuestionAnswersManager.changesFor(item.id), true); }\r\n for (const item of questionnaireQuestionAnswersManager.updated) { await saveQuestionAnswer(item.id, questionnaireQuestionAnswersManager.changesFor(item.id), false); }\r\n for (const item of questionnaireQuestionAnswersManager.removed) { await removeQuestionAnswer(item.id); }\r\n questionnaireQuestionAnswersManager.markAsSaved();\r\n\r\n // Save the feedbacks.\r\n for (const item of feedbacksManager.added) { await saveQuestionFeedback(item.id, feedbacksManager.changesFor(item.id), true); }\r\n for (const item of feedbacksManager.updated) { await saveQuestionFeedback(item.id, feedbacksManager.changesFor(item.id), false); }\r\n for (const item of feedbacksManager.removed) { await removeQuestionFeedback(item.id); }\r\n feedbacksManager.markAsSaved();\r\n\r\n // Save the question tag links.\r\n for (const item of questionTagLinksManager.added) { await saveQuestionTagLink(item.id, questionTagLinksManager.changesFor(item.id), true); }\r\n for (const item of questionTagLinksManager.updated) { await saveQuestionTagLink(item.id, questionTagLinksManager.changesFor(item.id), false); }\r\n for (const item of questionTagLinksManager.removed) { await removeQuestionTagLink(item.id); }\r\n questionTagLinksManager.markAsSaved();\r\n\r\n // Save the driver metric recommendations\r\n for (const item of driverMetricRecommendationsManager.added) { await saveQuestionDriverMetricRecommendation(item.id, driverMetricRecommendationsManager.changesFor(item.id), true); }\r\n for (const item of driverMetricRecommendationsManager.updated) { await saveQuestionDriverMetricRecommendation(item.id, driverMetricRecommendationsManager.changesFor(item.id), false); }\r\n for (const item of driverMetricRecommendationsManager.removed) { await removeQuestionDriverMetricRecommendation(item.id); }\r\n driverMetricRecommendationsManager.markAsSaved();\r\n\r\n // Save the driver metric adjustment.\r\n for (const item of driverMetricAdjustmentsManager.added) { await saveQuestionDriverMetricAdjustment(item.id, driverMetricAdjustmentsManager.changesFor(item.id), true); }\r\n for (const item of driverMetricAdjustmentsManager.updated) { await saveQuestionDriverMetricAdjustment(item.id, driverMetricAdjustmentsManager.changesFor(item.id), false); }\r\n for (const item of driverMetricAdjustmentsManager.removed) { await removeQuestionDriverMetricAdjustment(item.id); }\r\n driverMetricAdjustmentsManager.markAsSaved();\r\n\r\n // Save the sequences of questions.\r\n for (const item of questionSequenceQuestionsManager.added) { await saveQuestionQuestionSequenceQuestion(item.id, questionSequenceQuestionsManager.changesFor(item.id), true); }\r\n for (const item of questionSequenceQuestionsManager.updated) { await saveQuestionQuestionSequenceQuestion(item.id, questionSequenceQuestionsManager.changesFor(item.id), false); }\r\n for (const item of questionSequenceQuestionsManager.removed) { await removeQuestionQuestionSequenceQuestion(item.id); }\r\n questionSequenceQuestionsManager.markAsSaved();\r\n\r\n\r\n\r\n history.goBack();\r\n }, [\r\n validate, save, model, changes, isCreate, history,\r\n answersManager, saveQuestionAnswer, removeQuestionAnswer,\r\n feedbacksManager, saveQuestionFeedback, removeQuestionFeedback,\r\n questionTagLinksManager, saveQuestionTagLink, removeQuestionTagLink,\r\n driverMetricRecommendationsManager, saveQuestionDriverMetricRecommendation, removeQuestionDriverMetricRecommendation,\r\n driverMetricAdjustmentsManager, saveQuestionDriverMetricAdjustment, removeQuestionDriverMetricAdjustment,\r\n questionSequenceQuestionsManager, saveQuestionQuestionSequenceQuestion, removeQuestionQuestionSequenceQuestion,\r\n ]);\r\n\r\n // Tab tracking and UI matching to specific question types.\r\n const [activeTab, setActiveTab] = useState<'main' | 'questionPrompt' | 'feedback' | 'driverMetrics' | 'tags'>('main');\r\n const isVideoQuestion = useCallback(() => (\r\n model?.questionType === QuestionType.MultipleChoiceVideo\r\n || model?.questionType === QuestionType.SlidingScaleVideo\r\n || model?.questionType === QuestionType.ResponseTimeVideo\r\n || model?.questionType === QuestionType.LearningVideo\r\n || model?.questionType === QuestionType.InformationVideo\r\n ), [model]);\r\n const isImageQuestion = useCallback(() => (\r\n model?.questionType === QuestionType.LocationResponseImage\r\n || model?.questionType === QuestionType.LocationDiscriminationImage\r\n || model?.questionType === QuestionType.MultipleChoiceImage\r\n || model?.questionType === QuestionType.LearningImage\r\n || model?.questionType === QuestionType.InformationImage\r\n ), [model]);\r\n const canHaveFeedback = useCallback(() => (\r\n model?.questionType === QuestionType.MultipleChoiceVideo\r\n || model?.questionType === QuestionType.SlidingScaleVideo\r\n || model?.questionType === QuestionType.ResponseTimeVideo\r\n || model?.questionType === QuestionType.LocationResponseImage\r\n || model?.questionType === QuestionType.LocationDiscriminationImage\r\n || model?.questionType === QuestionType.MultipleChoiceImage\r\n || model?.questionType === QuestionType.Questionnaire\r\n ), [model]);\r\n const canHaveDriverMetrics = useCallback(() => (\r\n model?.questionType === QuestionType.MultipleChoiceVideo\r\n || model?.questionType === QuestionType.SlidingScaleVideo\r\n || model?.questionType === QuestionType.ResponseTimeVideo\r\n || model?.questionType === QuestionType.LocationResponseImage\r\n || model?.questionType === QuestionType.LocationDiscriminationImage\r\n || model?.questionType === QuestionType.MultipleChoiceImage\r\n ), [model]);\r\n const canHaveAnswers = useCallback(() => (\r\n model?.questionType === QuestionType.MultipleChoiceVideo\r\n || model?.questionType === QuestionType.SlidingScaleVideo\r\n || model?.questionType === QuestionType.ResponseTimeVideo\r\n || model?.questionType === QuestionType.LocationResponseImage\r\n || model?.questionType === QuestionType.LocationDiscriminationImage\r\n || model?.questionType === QuestionType.MultipleChoiceImage\r\n ), [model]);\r\n\r\n // UI\r\n //\r\n return (\r\n \r\n \r\n \r\n \r\n \r\n \r\n

\r\n {\r\n activeQuestionTypeCategory === QuestionTypeCategory.Learning ? (\r\n isCreate ? (\r\n <>{t('editQuestion.createHeading.learning', 'Add learning activity')}\r\n ) : (\r\n <>{t('editQuestion.editHeading.learning', 'Edit learning activity')}\r\n )\r\n ) : activeQuestionTypeCategory === QuestionTypeCategory.Questionnaire ? (\r\n isCreate ? (\r\n <>{t('editQuestion.createHeading.questionnaire', 'Add Questionnaire')}\r\n ) : (\r\n <>{t('editQuestion.editHeading.questionnaire', 'Edit Questionnaire')}\r\n )\r\n ) : (\r\n isCreate ? (\r\n <>{t('editQuestion.createHeading.default', 'Add question')}\r\n ) : (\r\n <>{t('editQuestion.editHeading.default', 'Edit question')}\r\n )\r\n )\r\n }\r\n

\r\n \r\n \r\n \r\n \r\n \r\n setActiveTab('main')}>\r\n {\r\n isVideoQuestion() ? <> {t('editQuestion.main.video', ' Video')}\r\n : isImageQuestion() && activeQuestionTypeCategory === QuestionTypeCategory.Learning ? <> {t('editQuestion.main.learning', ' Learning')}\r\n : isImageQuestion() ? <> {t('editQuestion.main.image', ' Scene')} \r\n : model?.questionType === QuestionType.SequenceOfQuestions ? <> {t('editQuestion.main.questions', ' Questions')}\r\n : activeQuestionTypeCategory === QuestionTypeCategory.Learning ? <> {t('editQuestion.main.learning', ' Learning')}\r\n : activeQuestionTypeCategory === QuestionTypeCategory.Questionnaire ? <> {t('editQuestion.main.quesitonnaire', ' Questionnaire')}\r\n : activeQuestionTypeCategory === QuestionTypeCategory.Informtion ? <> {t('editQuestion.main.information', ' Information page')}\r\n :<> {t('editQuestion.main.unknown', ' Question')}\r\n }\r\n \r\n <> \r\n \r\n \r\n \r\n \r\n \r\n \r\n setActiveTab('questionPrompt')}>\r\n {\r\n model?.questionType === QuestionType.ResponseTimeVideo ? <> \r\n {t('editQuestion.responseWindows', ' Response windows')} \r\n : <> {t('editQuestion.questionPrompt', ' Question prompt')} \r\n }\r\n \r\n <> \r\n \r\n \r\n \r\n \r\n \r\n \r\n setActiveTab('questionPrompt')}>\r\n {\r\n model?.questionType === QuestionType.MultipleChoiceImage ?\r\n <> {t('editQuestion.questionPrompt', ' Question prompt')} \r\n :<> {t('editQuestion.responseWindows', ' Response windows')} \r\n }\r\n \r\n <> \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n setActiveTab('feedback')}>\r\n \r\n {t('editQuestion.feedback', ' Feedback')}\r\n \r\n <> \r\n \r\n \r\n \r\n \r\n \r\n \r\n setActiveTab('driverMetrics')}>\r\n \r\n {t('editQuestion.driverMetrics', ' Recommend')}\r\n \r\n <> \r\n \r\n \r\n \r\n \r\n \r\n setActiveTab('tags')}>\r\n \r\n {t('editQuestion.tags', ' Tags')}\r\n \r\n \r\n \r\n \r\n \r\n
\r\n \r\n \r\n \r\n \r\n \r\n \r\n
\r\n
\r\n\r\n \r\n \r\n\r\n
{ e.preventDefault(); saveForm(); }}>\r\n \r\n \r\n change({ name: e.currentTarget.value })} onBlur={e => validate('name')} validationErrors={validationErrors['name']} />\r\n \r\n\r\n <>\r\n {/* Tab contents */}\r\n \r\n {/* Quesiton type select is shown on the main tab for all question type categories that support the user changing it. */}\r\n \r\n \r\n \r\n change({ questionType: e.currentTarget.value })} onBlur={e => validate('questionType')} validationErrors={validationErrors['questionType']}>\r\n \r\n {\r\n getQuestionTypes(activeQuestionTypeCategory).map(item => (\r\n \r\n ))\r\n }\r\n \r\n \r\n\r\n \r\n \r\n change({ driverMetricId: e.currentTarget.value || null })} onBlur={e => validate('driverMetricId')} validationErrors={validationErrors['driverMetricId']}>\r\n \r\n {\r\n driverMetrics?.map(item => (\r\n \r\n ))\r\n }\r\n \r\n \r\n \r\n\r\n \r\n \r\n \r\n \r\n \r\n\r\n \r\n \r\n \r\n change({ questionType: e.currentTarget.value })} onBlur={e => validate('questionType')} validationErrors={validationErrors['questionType']}>\r\n \r\n {\r\n getQuestionTypes(activeQuestionTypeCategory).map(item => (\r\n \r\n ))\r\n }\r\n \r\n \r\n \r\n\r\n \r\n \r\n \r\n change({ questionType: e.currentTarget.value })} onBlur={e => validate('questionType')} validationErrors={validationErrors['questionType']}>\r\n \r\n {\r\n getQuestionTypes(activeQuestionTypeCategory).map(item => (\r\n \r\n ))\r\n }\r\n \r\n \r\n \r\n\r\n {/* NOTE other QuestionTypeCategories do not support a dropdown to change their type. */}\r\n\r\n {/* Everything else on the main tab is dependant on the question type */}\r\n \r\n \r\n \r\n\r\n \r\n \r\n \r\n\r\n \r\n \r\n \r\n\r\n \r\n \r\n \r\n\r\n \r\n \r\n \r\n \r\n\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n\r\n \r\n \r\n \r\n\r\n \r\n \r\n \r\n\r\n \r\n \r\n \r\n \r\n\r\n\r\n \r\n \r\n {t('common.saving', 'Saving...')}}>\r\n \r\n <> {t('common.save', 'Save')}\r\n \r\n \r\n \r\n \r\n
\r\n
\r\n
\r\n );\r\n};\r\n","import * as React from 'react';\r\nimport { useLazyQuery } from \"@apollo/react-hooks\";\r\nimport gql from \"graphql-tag\";\r\nimport { AsyncLoadResult, AsyncLoadOptions } from '../../../../shared/abstractStore';\r\nimport { editQuestionViewModelQuery, editQuestionViewModelQueryVariables } from '../../generated/editQuestionViewModelQuery';\r\nimport { mainApiConfig } from '../../../../configure/mainApiConfig';\r\nimport { questionFieldsFragment } from '../../models/Question';\r\nimport { blobReferenceFieldsFragment } from '../../models/BlobReference';\r\nimport { Guid } from 'guid-string';\r\nimport { questionAnswerFieldsFragment } from '../../models/QuestionAnswer';\r\nimport { questionFeedbackFieldsFragment } from '../../models/QuestionFeedback';\r\nimport { questionTagLinkFieldsFragment } from '../../models/QuestionTagLink';\r\nimport { driverMetricRecommendationFieldsFragment } from '../../models/DriverMetricRecommendation';\r\nimport { driverMetricAdjustmentFieldsFragment } from '../../models/DriverMetricAdjustment';\r\nimport { questionSequenceQuestionFieldsFragment } from '../../models/QuestionSequenceQuestion';\r\n\r\n/**\r\n * View model for EditQuestion that replaces the call to useQuestion() and loads the right related data.\r\n * @param options\r\n */\r\nexport function useEditQuestionViewModel(id: string | undefined | null, options: AsyncLoadOptions = {}): AsyncLoadResult {\r\n // Query the data we need form the api.\r\n const [load, { data, loading, error, refetch }] = useLazyQuery(\r\n gql`\r\n query editQuestionViewModelQuery ($id: ID!) {\r\n model: question(id: $id) {\r\n ...questionFields\r\n\r\n videoBlobReference {\r\n ...blobReferenceFields\r\n }\r\n\r\n imageBlobReference {\r\n ...blobReferenceFields\r\n }\r\n\r\n questionTextImageBlobReference {\r\n ...blobReferenceFields\r\n }\r\n }\r\n\r\n answers: questionAnswers(questionId: $id) {\r\n ...questionAnswerFields\r\n\r\n answerTextImageBlobReference {\r\n ...blobReferenceFields\r\n }\r\n\r\n scaleImageBlobReference {\r\n ...blobReferenceFields\r\n }\r\n }\r\n\r\n questionnaireQuestionAnswers: questionAnswers(questionnaireQuestionId: $id) {\r\n ...questionAnswerFields\r\n\r\n answerTextImageBlobReference {\r\n ...blobReferenceFields\r\n }\r\n\r\n scaleImageBlobReference {\r\n ...blobReferenceFields\r\n }\r\n }\r\n\r\n feedbacks: questionFeedbacks(questionId: $id) {\r\n ...questionFeedbackFields\r\n\r\n videoBlobReference {\r\n ...blobReferenceFields\r\n }\r\n\r\n imageBlobReference {\r\n ...blobReferenceFields\r\n }\r\n }\r\n\r\n questionTagLinks: questionTagLinks(targetId: $id) {\r\n ...questionTagLinkFields\r\n }\r\n\r\n driverMetricRecommendations: driverMetricRecommendations(targetId: $id) {\r\n ...driverMetricRecommendationFields\r\n }\r\n\r\n driverMetricAdjustments: driverMetricAdjustments(targetId: $id) {\r\n ...driverMetricAdjustmentFields\r\n }\r\n\r\n questionSequenceQuestions: questionSequenceQuestions(parentQuestionId: $id) {\r\n ...questionSequenceQuestionFields\r\n\r\n childQuestion {\r\n ...questionFields\r\n }\r\n }\r\n }\r\n\r\n ${questionFieldsFragment}\r\n ${blobReferenceFieldsFragment}\r\n ${questionAnswerFieldsFragment}\r\n ${questionFeedbackFieldsFragment}\r\n ${questionTagLinkFieldsFragment}\r\n ${driverMetricRecommendationFieldsFragment}\r\n ${driverMetricAdjustmentFieldsFragment}\r\n ${questionSequenceQuestionFieldsFragment}\r\n `,\r\n {\r\n variables: {\r\n id: id ?? Guid.empty\r\n },\r\n fetchPolicy: options.fetchPolicy ?? mainApiConfig.defaultFetchPolicy,\r\n pollInterval: options.pollInterval,\r\n onCompleted: (data) => {\r\n if (options.onCompleted) {\r\n options.onCompleted(data);\r\n }\r\n }\r\n }\r\n );\r\n\r\n // Run the query (unless we are being lazy).\r\n React.useEffect(() => {\r\n if (!options.lazy) {\r\n load();\r\n }\r\n }, [options.lazy, load])\r\n\r\n // Return the results.\r\n const refresh = React.useCallback(async () => { !refetch ? await load() : await refetch(); }, [refetch, load]);\r\n return React.useMemo(() => ({\r\n data: data ?? ({} as any),\r\n refresh: refresh,\r\n isLoading: loading,\r\n errors: error\r\n }), [data, refresh, loading, error]);\r\n}","import * as React from 'react';\r\nimport { useLazyQuery } from \"@apollo/react-hooks\";\r\nimport gql from \"graphql-tag\";\r\nimport { AsyncLoadResult, AsyncLoadOptions } from '../../../../shared/abstractStore';\r\nimport { editQuestionSupportingDataQuery } from '../../generated/editQuestionSupportingDataQuery';\r\nimport { mainApiConfig } from '../../../../configure/mainApiConfig';\r\nimport { questionTagFieldsFragment } from '../../models/QuestionTag';\r\nimport { driverMetricFieldsFragment } from '../../models/DriverMetric';\r\n\r\n/**\r\n * Supporting data for EditQuestion that loads static data (e.g. dropdowns) that are not changed by the model being used.\r\n * @param options\r\n */\r\nexport function useEditQuestionSupportingData(options: AsyncLoadOptions = {}): AsyncLoadResult {\r\n // Query the data we need form the api.\r\n const [load, { data, loading, error, refetch }] = useLazyQuery(\r\n gql`\r\n query editQuestionSupportingDataQuery {\r\n questionTags {\r\n ...questionTagFields\r\n }\r\n\r\n driverMetrics {\r\n ...driverMetricFields\r\n }\r\n }\r\n\r\n ${questionTagFieldsFragment}\r\n ${driverMetricFieldsFragment}\r\n `,\r\n {\r\n variables: {\r\n },\r\n fetchPolicy: options.fetchPolicy ?? mainApiConfig.defaultFetchPolicy,\r\n pollInterval: options.pollInterval,\r\n onCompleted: (data) => {\r\n if (options.onCompleted) {\r\n options.onCompleted(data);\r\n }\r\n }\r\n }\r\n );\r\n\r\n // Run the query (unless we are being lazy).\r\n React.useEffect(() => {\r\n if (!options.lazy) {\r\n load();\r\n }\r\n }, [options.lazy, load])\r\n\r\n // Return the results.\r\n const refresh = React.useCallback(async () => { !refetch ? await load() : await refetch(); }, [refetch, load]);\r\n return React.useMemo(() => ({\r\n data: data ?? ({} as any),\r\n refresh: refresh,\r\n isLoading: loading,\r\n errors: error\r\n }), [data, refresh, loading, error]);\r\n}","import * as React from 'react';\r\nimport { QuestionCreateInput, QuestionUpdateInput } from '../generated/globalTypes';\r\nimport { useSaveInStore, SaveInStoreOptions } from '../../../shared/useSaveInStore';\r\nimport { useCreateQuestionCallback } from './useCreateQuestionCallback';\r\nimport { useUpdateQuestionCallback } from './useUpdateQuestionCallback';\r\nimport { Question } from '../models/Question';\r\n\r\n/**\r\n * Get a callback to save a Question in the store using either a create or update.\r\n */\r\nexport function useSaveQuestionCallback(options: SaveInStoreOptions = {}) {\r\n const [_create, createStatus] = useCreateQuestionCallback();\r\n const create = React.useCallback((model: Partial) => _create(model as QuestionCreateInput), [_create]);\r\n\r\n const [_update, updateStatus] = useUpdateQuestionCallback();\r\n const update = React.useCallback((id: string, changes: Partial) => _update(id, changes as QuestionUpdateInput), [_update]);\r\n\r\n return useSaveInStore(\r\n [create, createStatus],\r\n [update, updateStatus],\r\n options\r\n );\r\n}\r\n","import * as React from 'react';\r\nimport { QuestionAnswerCreateInput, QuestionAnswerUpdateInput } from '../generated/globalTypes';\r\nimport { useSaveInStore, SaveInStoreOptions } from '../../../shared/useSaveInStore';\r\nimport { useCreateQuestionAnswerCallback } from './useCreateQuestionAnswerCallback';\r\nimport { useUpdateQuestionAnswerCallback } from './useUpdateQuestionAnswerCallback';\r\nimport { QuestionAnswer } from '../models/QuestionAnswer';\r\n\r\n/**\r\n * Get a callback to save a QuestionAnswer in the store using either a create or update.\r\n */\r\nexport function useSaveQuestionAnswerCallback(options: SaveInStoreOptions = {}) {\r\n const [_create, createStatus] = useCreateQuestionAnswerCallback();\r\n const create = React.useCallback((model: Partial) => _create(model as QuestionAnswerCreateInput), [_create]);\r\n\r\n const [_update, updateStatus] = useUpdateQuestionAnswerCallback();\r\n const update = React.useCallback((id: string, changes: Partial) => _update(id, changes as QuestionAnswerUpdateInput), [_update]);\r\n\r\n return useSaveInStore(\r\n [create, createStatus],\r\n [update, updateStatus],\r\n options\r\n );\r\n}\r\n","import * as React from 'react';\r\nimport { QuestionFeedbackCreateInput, QuestionFeedbackUpdateInput } from '../generated/globalTypes';\r\nimport { useSaveInStore, SaveInStoreOptions } from '../../../shared/useSaveInStore';\r\nimport { useCreateQuestionFeedbackCallback } from './useCreateQuestionFeedbackCallback';\r\nimport { useUpdateQuestionFeedbackCallback } from './useUpdateQuestionFeedbackCallback';\r\nimport { QuestionFeedback } from '../models/QuestionFeedback';\r\n\r\n/**\r\n * Get a callback to save a QuestionFeedback in the store using either a create or update.\r\n */\r\nexport function useSaveQuestionFeedbackCallback(options: SaveInStoreOptions = {}) {\r\n const [_create, createStatus] = useCreateQuestionFeedbackCallback();\r\n const create = React.useCallback((model: Partial) => _create(model as QuestionFeedbackCreateInput), [_create]);\r\n\r\n const [_update, updateStatus] = useUpdateQuestionFeedbackCallback();\r\n const update = React.useCallback((id: string, changes: Partial) => _update(id, changes as QuestionFeedbackUpdateInput), [_update]);\r\n\r\n return useSaveInStore(\r\n [create, createStatus],\r\n [update, updateStatus],\r\n options\r\n );\r\n}\r\n","import * as React from 'react';\r\nimport { QuestionSequenceQuestionCreateInput, QuestionSequenceQuestionUpdateInput } from '../generated/globalTypes';\r\nimport { useSaveInStore, SaveInStoreOptions } from '../../../shared/useSaveInStore';\r\nimport { useCreateQuestionSequenceQuestionCallback } from './useCreateQuestionSequenceQuestionCallback';\r\nimport { useUpdateQuestionSequenceQuestionCallback } from './useUpdateQuestionSequenceQuestionCallback';\r\nimport { QuestionSequenceQuestion } from '../models/QuestionSequenceQuestion';\r\n\r\n/**\r\n * Get a callback to save a QuestionSequenceQuestion in the store using either a create or update.\r\n */\r\nexport function useSaveQuestionSequenceQuestionCallback(options: SaveInStoreOptions = {}) {\r\n const [_create, createStatus] = useCreateQuestionSequenceQuestionCallback();\r\n const create = React.useCallback((model: Partial) => _create(model as QuestionSequenceQuestionCreateInput), [_create]);\r\n\r\n const [_update, updateStatus] = useUpdateQuestionSequenceQuestionCallback();\r\n const update = React.useCallback((id: string, changes: Partial) => _update(id, changes as QuestionSequenceQuestionUpdateInput), [_update]);\r\n\r\n return useSaveInStore(\r\n [create, createStatus],\r\n [update, updateStatus],\r\n options\r\n );\r\n}\r\n","import * as React from 'react';\r\nimport { useLazyQuery } from \"@apollo/react-hooks\";\r\nimport gql from \"graphql-tag\";\r\nimport { AsyncLoadPagedResult, AsyncLoadPagedOptions } from '../../../shared/abstractStore';\r\nimport { useFetchMoreCallback } from '../../../shared/useFetchMoreCallback';\r\nimport { questionsQuery, questionsQueryVariables } from '../generated/questionsQuery';\r\nimport { mainApiConfig } from '../../../configure/mainApiConfig';\r\nimport { questionFieldsFragment } from '../models/Question';\r\nimport { QuestionType } from '../models/codeOnly/QuestionType';\r\n\r\nexport interface QuestionsAsyncLoadPageOptions extends AsyncLoadPagedOptions {\r\n questionTypes?: Array,\r\n}\r\n\r\n/**\r\n * Get a list of questions from the store.\r\n * @param id\r\n * @param options\r\n */\r\nexport function useQuestions(options: QuestionsAsyncLoadPageOptions = {}): AsyncLoadPagedResult {\r\n // Query data we need from the api.\r\n const [load, { data, loading, error, refetch, fetchMore: fetchMoreFromStore }] = useLazyQuery(\r\n gql`\r\n query questionsQuery ($offset: Int, $first: Int, $questionTypes: [String!]) {\r\n items: questions (offset: $offset, first: $first, questionTypes: $questionTypes) {\r\n ...questionFields\r\n }\r\n }\r\n\r\n ${questionFieldsFragment}\r\n `,\r\n {\r\n\r\n variables: {\r\n offset: options.startOffset,\r\n first: options.pageSize,\r\n questionTypes: options.questionTypes,\r\n },\r\n fetchPolicy: options.fetchPolicy ?? mainApiConfig.defaultFetchPolicy,\r\n pollInterval: options.pollInterval,\r\n onCompleted: (data) => {\r\n if (options.onCompleted) {\r\n options.onCompleted(data);\r\n }\r\n }\r\n }\r\n );\r\n\r\n // Run the query (unless we are being lazy).\r\n React.useEffect(() => {\r\n if (!options.lazy) {\r\n load();\r\n }\r\n }, [options.lazy, load])\r\n\r\n // Get the functions used to manage paging.\r\n const { fetchMore, hasMore: _hasMore } = useFetchMoreCallback(\r\n fetchMoreFromStore,\r\n (options?.startOffset ?? 0) + (data?.items?.length ?? 0),\r\n (prevResults, newResults) => ({\r\n ...prevResults,\r\n ...newResults,\r\n\r\n items: [...(prevResults?.items ?? []), ...(newResults?.items ?? [])]\r\n }),\r\n (newResults) => newResults?.items?.length\r\n );\r\n const hasMore = React.useCallback(() => !options.pageSize ? false : _hasMore(), [options.pageSize, _hasMore]);\r\n \r\n // Return the results.\r\n const refresh = React.useCallback(async () => { !refetch ? await load() : await refetch(); }, [refetch, load]);\r\n return React.useMemo(() => ({\r\n data: data ?? ({} as any),\r\n refresh: refresh,\r\n isLoading: loading,\r\n errors: error,\r\n fetchMore: fetchMore,\r\n hasMore: hasMore,\r\n }), [data, refresh, loading, error, fetchMore, hasMore]);\r\n}\r\n","import gql from \"graphql-tag\";\r\nimport { Guid } from \"guid-string\";\r\nimport moment from \"moment\";\r\nimport { questionResponseEventFields } from \"../generated/questionResponseEventFields\";\r\n\r\nexport const questionResponseEventFieldsFragment = gql`\r\n fragment questionResponseEventFields on QuestionResponseEvent {\r\n id\r\n questionId\r\n userId\r\n assessmentId\r\n assessmentItemId\r\n assessmentSessionId\r\n eventDate\r\n cancelEventDate\r\n archived\r\n questionAnswerId\r\n score\r\n isCorrect\r\n responseTimeSeconds\r\n clickPositionX\r\n clickPositionY\r\n discriminationGroup\r\n textInput\r\n subQuestionNumber\r\n }\r\n`;\r\n\r\n\r\nexport type QuestionResponseEvent = Omit;\r\n\r\n// Default values.\r\nexport const questionResponseEventDefaultValues = (): Partial => ({\r\n id: Guid.newGuid(),\r\n questionId: undefined,\r\n questionAnswerId: undefined,\r\n archived: false,\r\n assessmentId: undefined,\r\n assessmentItemId: undefined,\r\n assessmentSessionId: undefined,\r\n cancelEventDate: undefined,\r\n clickPositionX: 0,\r\n clickPositionY: 0,\r\n discriminationGroup: '',\r\n eventDate: moment().toISOString(),\r\n isCorrect: false,\r\n responseTimeSeconds: 0,\r\n score: 0,\r\n textInput: '',\r\n userId: '',\r\n subQuestionNumber: 1,\r\n});","import { useMutation } from \"@apollo/react-hooks\";\r\nimport { useAsyncCallback } from 'react-use-async-callback';\r\nimport gql from \"graphql-tag\";\r\nimport { AsyncActionStatus } from '../../../shared/abstractStore';\r\nimport { deleteQuestionResponseEventMutation, deleteQuestionResponseEventMutationVariables } from '../generated/deleteQuestionResponseEventMutation';\r\nimport { questionResponseEventFieldsFragment } from '../models/QuestionResponseEvent';\r\n\r\n/**\r\n * Get a callback to delete a QuestionResponseEvent in the store.\r\n */\r\nexport function useDeleteQuestionResponseEventCallback(): [(id: string) => Promise, AsyncActionStatus] {\r\n const [mutationAction, { error }] = useMutation(\r\n gql`\r\n mutation deleteQuestionResponseEventMutation ($id: ID!) {\r\n deleteQuestionResponseEvent(id: $id) {\r\n ...questionResponseEventFields\r\n }\r\n }\r\n\r\n ${questionResponseEventFieldsFragment}\r\n `\r\n );\r\n\r\n // Wrap the mutation in a standard callback.\r\n const [action, { isExecuting, errors: actionErrors }] = useAsyncCallback(async (id: string) => {\r\n const result = await mutationAction({ variables: { id: id } });\r\n if (result.errors && result.errors.length) {\r\n throw result.errors;\r\n }\r\n }, [mutationAction]);\r\n\r\n return [action, { isExecuting: isExecuting, errors: error ? error.message : actionErrors }];\r\n}\r\n","import { Button, Form, FormGroup, Spinner, Input, Row, Col } from 'reactstrap';\r\nimport { AlertOnErrors } from '../../shared/alertOnErrors';\r\nimport { LoadingIndicator } from '../shared/LoadingIndicator';\r\nimport { useTranslation } from 'react-i18next';\r\nimport { FontAwesomeIcon } from '@fortawesome/react-fontawesome';\r\nimport { MainContainer } from '../shared/MainContainer';\r\nimport { useParams, useHistory } from 'react-router';\r\nimport { FormButtons } from '../shared/FormButtons';\r\nimport { ButtonAsync } from 'reactstrap-buttonasync';\r\nimport { useAsyncCallback } from 'react-use-async-callback';\r\nimport { useDeleteQuestionCallback } from '../../api/main/questions/useDeleteQuestionCallback';\r\nimport { ConditionalFragment } from 'react-conditionalfragment';\r\nimport { Banner } from '../shared/Banner';\r\nimport { Background } from '../shared/background/Background';\r\nimport { getQuestionTypeCategory, QuestionType, QuestionTypeCategory } from '../../api/main/models/codeOnly/QuestionType';\r\nimport { useMemo } from 'react';\r\nimport { useDeleteQuestionAnswerCallback } from '../../api/main/questionAnswers/useDeleteQuestionAnswerCallback';\r\nimport { useDeleteQuestionFeedbackCallback } from '../../api/main/questionFeedbacks/useDeleteQuestionFeedbackCallback';\r\nimport { useDeleteQuestionTagLinkCallback } from '../../api/main/questionTagLinks/useDeleteQuestionTagLinkCallback';\r\nimport { useDeleteDriverMetricRecommendationCallback } from '../../api/main/driverMetricRecommendations/useDeleteDriverMetricRecommendationCallback';\r\nimport { useDeleteDriverMetricAdjustmentCallback } from '../../api/main/driverMetricAdjustments/useDeleteDriverMetricAdjustmentCallback';\r\nimport { useDeleteAssessmentItemQuestionCallback } from '../../api/main/assessmentItemQuestions/useDeleteAssessmentItemQuestionCallback';\r\nimport { useDeleteQuestionResponseEventCallback } from '../../api/main/questionResponseEvents/useDeleteQuestionResponseEventCallback';\r\nimport { useDeleteQuestionSequenceQuestionCallback } from '../../api/main/questionSequenceQuestions/useDeleteQuestionSequenceQuestionCallback';\r\nimport { useQuestionLinksViewModel } from '../../api/main/questions/viewModels/useQuestionLinksViewModel';\r\n\r\nexport interface DeleteQuestionBaseProps {\r\n defaultQuestionType: QuestionType,\r\n}\r\n\r\n/**\r\n * Delete a question.\r\n */\r\nexport const DeleteQuestionBase = (props: DeleteQuestionBaseProps) => {\r\n const { defaultQuestionType } = props;\r\n\r\n const { t } = useTranslation();\r\n const { id } = useParams<{ id: string }>();\r\n\r\n\r\n const { data: {\r\n model,\r\n answers,\r\n questionnaireQuestionAnswers,\r\n feedbacks,\r\n questionTagLinks,\r\n driverMetricRecommendations,\r\n driverMetricAdjustments,\r\n assessmentLinks,\r\n responseEvents,\r\n questionSequenceQuestions,\r\n }, isLoading, errors: loadErrors } = useQuestionLinksViewModel(id);\r\n\r\n const [remove, { errors: removeErrors }] = useDeleteQuestionCallback();\r\n\r\n const [removeQuestionAnswer, { errors: removeQuestionAnswerErrors }] = useDeleteQuestionAnswerCallback();\r\n const [removeQuestionFeedback, { errors: removeQuestionFeedbackErrors }] = useDeleteQuestionFeedbackCallback();\r\n const [removeQuestionTagLink, { errors: removeQuestionTagLinkErrors }] = useDeleteQuestionTagLinkCallback();\r\n const [removeDriverMetricRecommendation, { errors: removeDriverMetricRecommendationErrors }] = useDeleteDriverMetricRecommendationCallback();\r\n const [removeDriverMetricAdjustment, { errors: removeDriverMetricAdjustmentErrors }] = useDeleteDriverMetricAdjustmentCallback();\r\n const [removeAssessmentLink, { errors: removeAssessmentLinkErrors }] = useDeleteAssessmentItemQuestionCallback();\r\n const [removeQuestionResponseEvent, { errors: removeQuestionResponseEventErrors }] = useDeleteQuestionResponseEventCallback();\r\n const [removeQuestionSequenceQuestion, { errors: removeQuestionSequenceQuestionErrors }] = useDeleteQuestionSequenceQuestionCallback();\r\n\r\n const history = useHistory();\r\n\r\n // We want to customise the interface based on the category of question we are.\r\n const activeQuestionTypeCategory: QuestionTypeCategory = useMemo(() => getQuestionTypeCategory(model?.questionType as QuestionType || defaultQuestionType), [model, defaultQuestionType]);\r\n\r\n const [onRemoveFormSubmit, { isExecuting: isRemoving, errors: removeFormErrors }] = useAsyncCallback(async () => {\r\n if (!model) {\r\n return;\r\n }\r\n\r\n //Delete everything linked to the question first\r\n await answers.forEach(item => removeQuestionAnswer(item.id));\r\n await questionnaireQuestionAnswers.forEach(item => removeQuestionAnswer(item.id));\r\n await feedbacks.forEach(item => removeQuestionFeedback(item.id));\r\n await questionTagLinks.forEach(item => removeQuestionTagLink(item.id));\r\n await driverMetricRecommendations.forEach(item => removeDriverMetricRecommendation(item.id));\r\n await driverMetricAdjustments.forEach(item => removeDriverMetricAdjustment(item.id));\r\n await assessmentLinks.forEach(item => removeAssessmentLink(item.id)); \r\n await responseEvents.forEach(item => removeQuestionResponseEvent(item.id)); \r\n await questionSequenceQuestions.forEach(item => removeQuestionSequenceQuestion(item.id));\r\n \r\n\r\n await remove(model.id);\r\n\r\n history.goBack();\r\n }, [model, history]);\r\n\r\n return (\r\n \r\n \r\n \r\n \r\n

{\r\n activeQuestionTypeCategory === QuestionTypeCategory.Learning ? t('deleteQuestion.heading.learning', 'Are you sure you want to delete this learning activity?')\r\n : activeQuestionTypeCategory === QuestionTypeCategory.Questionnaire ? t('deleteQuestion.heading.questionnaire', 'Are you sure you want to delete this questionnaire?')\r\n : t('deleteQuestion.heading.default', 'Are you sure you want to delete this question?')\r\n }

\r\n \r\n \r\n \r\n \r\n \r\n \r\n
\r\n
\r\n\r\n \r\n \r\n\r\n
{ e.preventDefault(); onRemoveFormSubmit(); }}>\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n {t('common.deleting', 'Deleting...')}}>\r\n \r\n <> {t('common.delete', 'Delete')}\r\n \r\n \r\n \r\n \r\n
\r\n
\r\n
\r\n );\r\n};\r\n","import * as React from 'react';\r\nimport { useLazyQuery } from \"@apollo/react-hooks\";\r\nimport gql from \"graphql-tag\";\r\nimport { AsyncLoadResult, AsyncLoadOptions } from '../../../../shared/abstractStore';\r\nimport { QuestionLinksViewModelQuery, QuestionLinksViewModelQueryVariables } from '../../generated/QuestionLinksViewModelQuery';\r\nimport { mainApiConfig } from '../../../../configure/mainApiConfig';\r\nimport { questionFieldsFragment } from '../../models/Question';\r\nimport { blobReferenceFieldsFragment } from '../../models/BlobReference';\r\nimport { Guid } from 'guid-string';\r\nimport { questionAnswerFieldsFragment } from '../../models/QuestionAnswer';\r\nimport { questionFeedbackFieldsFragment } from '../../models/QuestionFeedback';\r\nimport { questionTagLinkFieldsFragment } from '../../models/QuestionTagLink';\r\nimport { driverMetricRecommendationFieldsFragment } from '../../models/DriverMetricRecommendation';\r\nimport { driverMetricAdjustmentFieldsFragment } from '../../models/DriverMetricAdjustment';\r\nimport { questionSequenceQuestionFieldsFragment } from '../../models/QuestionSequenceQuestion';\r\nimport { assessmentItemQuestionFieldsFragment } from '../../models/AssessmentItemQuestion';\r\nimport { questionResponseEventFieldsFragment } from '../../models/QuestionResponseEvent';\r\n\r\n/**\r\n * View model for EditQuestion that replaces the call to useQuestion() and loads the right related data.\r\n * @param options\r\n */\r\nexport function useQuestionLinksViewModel(id: string | undefined | null, options: AsyncLoadOptions = {}): AsyncLoadResult {\r\n // Query the data we need form the api.\r\n const [load, { data, loading, error, refetch }] = useLazyQuery(\r\n gql`\r\n query QuestionLinksViewModelQuery ($id: ID!) {\r\n model: question(id: $id) {\r\n ...questionFields\r\n\r\n videoBlobReference {\r\n ...blobReferenceFields\r\n }\r\n\r\n imageBlobReference {\r\n ...blobReferenceFields\r\n }\r\n\r\n questionTextImageBlobReference {\r\n ...blobReferenceFields\r\n }\r\n }\r\n\r\n answers: questionAnswers(questionId: $id) {\r\n ...questionAnswerFields\r\n\r\n answerTextImageBlobReference {\r\n ...blobReferenceFields\r\n }\r\n\r\n scaleImageBlobReference {\r\n ...blobReferenceFields\r\n }\r\n }\r\n\r\n questionnaireQuestionAnswers: questionAnswers(questionnaireQuestionId: $id) {\r\n ...questionAnswerFields\r\n\r\n answerTextImageBlobReference {\r\n ...blobReferenceFields\r\n }\r\n\r\n scaleImageBlobReference {\r\n ...blobReferenceFields\r\n }\r\n }\r\n\r\n feedbacks: questionFeedbacks(questionId: $id) {\r\n ...questionFeedbackFields\r\n\r\n videoBlobReference {\r\n ...blobReferenceFields\r\n }\r\n\r\n imageBlobReference {\r\n ...blobReferenceFields\r\n }\r\n }\r\n\r\n questionTagLinks: questionTagLinks(targetId: $id) {\r\n ...questionTagLinkFields\r\n }\r\n\r\n driverMetricRecommendations: driverMetricRecommendations(targetId: $id) {\r\n ...driverMetricRecommendationFields\r\n }\r\n\r\n driverMetricAdjustments: driverMetricAdjustments(targetId: $id) {\r\n ...driverMetricAdjustmentFields\r\n }\r\n\r\n assessmentLinks: assessmentItemQuestions (questionId: $id) {\r\n ...assessmentItemQuestionFields\r\n }\r\n\r\n responseEvents: questionResponseEvents (questionId: $id) {\r\n ...questionResponseEventFields\r\n }\r\n\r\n questionSequenceQuestions: questionSequenceQuestions(parentQuestionId: $id) {\r\n ...questionSequenceQuestionFields\r\n\r\n childQuestion {\r\n ...questionFields\r\n }\r\n }\r\n }\r\n\r\n ${questionFieldsFragment}\r\n ${blobReferenceFieldsFragment}\r\n ${questionAnswerFieldsFragment}\r\n ${questionFeedbackFieldsFragment}\r\n ${questionTagLinkFieldsFragment}\r\n ${driverMetricRecommendationFieldsFragment}\r\n ${driverMetricAdjustmentFieldsFragment}\r\n ${questionSequenceQuestionFieldsFragment}\r\n ${assessmentItemQuestionFieldsFragment}\r\n ${questionResponseEventFieldsFragment}\r\n `,\r\n {\r\n variables: {\r\n id: id ?? Guid.empty\r\n },\r\n fetchPolicy: options.fetchPolicy ?? mainApiConfig.defaultFetchPolicy,\r\n pollInterval: options.pollInterval,\r\n onCompleted: (data) => {\r\n if (options.onCompleted) {\r\n options.onCompleted(data);\r\n }\r\n }\r\n }\r\n );\r\n\r\n // Run the query (unless we are being lazy).\r\n React.useEffect(() => {\r\n if (!options.lazy) {\r\n load();\r\n }\r\n }, [options.lazy, load])\r\n\r\n // Return the results.\r\n const refresh = React.useCallback(async () => { !refetch ? await load() : await refetch(); }, [refetch, load]);\r\n return React.useMemo(() => ({\r\n data: data ?? ({} as any),\r\n refresh: refresh,\r\n isLoading: loading,\r\n errors: error\r\n }), [data, refresh, loading, error]);\r\n}","import { RouteEntry } from \"../../../shared/routes\";\r\nimport { QuestionsList } from './QuestionsList';\r\nimport { EditQuestion, CreateQuestion } from \"./EditQuestion\";\r\nimport { IdentityRoles } from \"../../../configure/security/IdentityRoles\";\r\nimport { DeleteQuestion } from \"./DeleteQuestion\";\r\n\r\nexport const questionRoutes: Array = [\r\n { path: '/administration/questions', exact: true, component: QuestionsList, authorize: true, requireRole: IdentityRoles.Administration },\r\n { path: '/administration/questions/edit/:id', component: EditQuestion, authorize: true, requireRole: IdentityRoles.Administration },\r\n { path: '/administration/questions/add', component: CreateQuestion, authorize: true, requireRole: IdentityRoles.Administration },\r\n { path: '/administration/questions/delete/:id', component: DeleteQuestion, authorize: true, requireRole: IdentityRoles.Administration },\r\n];\r\n","import { useTranslation } from \"react-i18next\";\r\nimport { getQuestionTypes, QuestionTypeCategory } from \"../../../api/main/models/codeOnly/QuestionType\";\r\nimport { QuestionsListBase } from \"../QuestionsListBase\";\r\n\r\n/**\r\n * List of actual questions.\r\n */\r\nexport const QuestionsList = () => {\r\n const { t } = useTranslation();\r\n\r\n return (\r\n \r\n );\r\n};","import { QuestionType } from \"../../../api/main/models/codeOnly/QuestionType\";\r\nimport { CreateQuestionBase, EditQuestionBase } from \"../edit/EditQuestionBase\";\r\n\r\n/**\r\n * Create a question.\r\n */\r\nexport const CreateQuestion = () => (\r\n ({ /* No defaults needed */ })}\r\n />);\r\n\r\n/**\r\n * Edit a question.\r\n */\r\nexport const EditQuestion = () => ();\r\n","import { QuestionType } from \"../../../api/main/models/codeOnly/QuestionType\";\r\nimport { DeleteQuestionBase } from \"../DeleteQuestionBase\";\r\n\r\n/**\r\n * Delete a question.\r\n */\r\nexport const DeleteQuestion = () => ();\r\n","import { RouteEntry } from \"../../../shared/routes\";\r\nimport { QuestionnairesList } from './QuestionnairesList';\r\nimport { EditQuestionnaire, CreateQuestionnaire } from \"./EditQuestionnaire\";\r\nimport { IdentityRoles } from \"../../../configure/security/IdentityRoles\";\r\nimport { DeleteQuestionnaire } from \"./DeleteQuestionnaire\";\r\n\r\nexport const questionnaireRoutes: Array = [\r\n { path: '/administration/questionnaires', exact: true, component: QuestionnairesList, authorize: true, requireRole: IdentityRoles.Administration },\r\n { path: '/administration/questionnaires/edit/:id', component: EditQuestionnaire, authorize: true, requireRole: IdentityRoles.Administration },\r\n { path: '/administration/questionnaires/add', component: CreateQuestionnaire, authorize: true, requireRole: IdentityRoles.Administration },\r\n { path: '/administration/questionnaires/delete/:id', component: DeleteQuestionnaire, authorize: true, requireRole: IdentityRoles.Administration },\r\n];\r\n","import { useTranslation } from \"react-i18next\";\r\nimport { getQuestionTypes, QuestionTypeCategory } from \"../../../api/main/models/codeOnly/QuestionType\";\r\nimport { QuestionsListBase } from \"../QuestionsListBase\";\r\n\r\n/**\r\n * List of questionnaires.\r\n */\r\nexport const QuestionnairesList = () => {\r\n const { t } = useTranslation();\r\n\r\n return (\r\n \r\n );\r\n};","import { QuestionType } from \"../../../api/main/models/codeOnly/QuestionType\";\r\nimport { CreateQuestionBase, EditQuestionBase } from \"../edit/EditQuestionBase\";\r\n\r\n/**\r\n * Create a questionnaire.\r\n */\r\nexport const CreateQuestionnaire = () => (\r\n ({ questionType: QuestionType.Questionnaire, })}\r\n />);\r\n\r\n/**\r\n * Edit a questionnaire\r\n */\r\nexport const EditQuestionnaire = () => ();\r\n","import { QuestionType } from \"../../../api/main/models/codeOnly/QuestionType\";\r\nimport { DeleteQuestionBase } from \"../DeleteQuestionBase\";\r\n\r\n/**\r\n * Delete a questionnaire.\r\n */\r\nexport const DeleteQuestionnaire = () => ();\r\n","import { RouteEntry } from \"../../../shared/routes\";\r\nimport { LearningList } from \"./LearningList\";\r\nimport { EditLearning, CreateLearning } from \"./EditLearning\";\r\nimport { IdentityRoles } from \"../../../configure/security/IdentityRoles\";\r\nimport { DeleteLearning } from \"./DeleteLearning\";\r\n\r\nexport const learningRoutes: Array = [\r\n { path: '/administration/learning-activities', exact: true, component: LearningList, authorize: true, requireRole: IdentityRoles.Administration },\r\n { path: '/administration/learning-activities/edit/:id', component: EditLearning, authorize: true, requireRole: IdentityRoles.Administration },\r\n { path: '/administration/learning-activities/add', component: CreateLearning, authorize: true, requireRole: IdentityRoles.Administration },\r\n { path: '/administration/learning-activities/delete/:id', component: DeleteLearning, authorize: true, requireRole: IdentityRoles.Administration },\r\n];\r\n","import { useTranslation } from \"react-i18next\";\r\nimport { getQuestionTypes, QuestionTypeCategory } from \"../../../api/main/models/codeOnly/QuestionType\";\r\nimport { QuestionsListBase } from \"../QuestionsListBase\";\r\n\r\n/**\r\n * List of learning activities.\r\n */\r\nexport const LearningList = () => {\r\n const { t } = useTranslation();\r\n\r\n return (\r\n \r\n );\r\n};","import { QuestionType } from \"../../../api/main/models/codeOnly/QuestionType\";\r\nimport { CreateQuestionBase, EditQuestionBase } from \"../edit/EditQuestionBase\";\r\n\r\n/**\r\n * Create a learning activity.\r\n */\r\nexport const CreateLearning = () => (\r\n ({ /* No defaults needed */ })}\r\n />);\r\n\r\n/**\r\n * Edit a learning activity.\r\n */\r\nexport const EditLearning = () => ();\r\n","import { QuestionType } from \"../../../api/main/models/codeOnly/QuestionType\";\r\nimport { DeleteQuestionBase } from \"../DeleteQuestionBase\";\r\n\r\n/**\r\n * Delete a learning activity.\r\n */\r\nexport const DeleteLearning = () => ();\r\n","import gql from \"graphql-tag\";\r\nimport { Guid } from \"guid-string\";\r\nimport { subscriptionAssessmentFields } from \"../generated/subscriptionAssessmentFields\";\r\n\r\nexport const subscriptionAssessmentFieldsFragment = gql`\r\n fragment subscriptionAssessmentFields on SubscriptionAssessment {\r\n id\r\n subscriptionId\r\n assessmentId\r\n archived\r\n maxRestarts\r\n }\r\n`;\r\n\r\n\r\nexport type SubscriptionAssessment = Omit;\r\n\r\n// Default values.\r\nexport const subscriptionAssessmentDefaultValues = (): Partial => ({\r\n id: Guid.newGuid(),\r\n subscriptionId: undefined,\r\n assessmentId: undefined,\r\n archived: false,\r\n maxRestarts: 0,\r\n});","import { useMutation } from \"@apollo/react-hooks\";\r\nimport { useAsyncCallback } from 'react-use-async-callback';\r\nimport gql from \"graphql-tag\";\r\nimport { AsyncActionStatus } from '../../../shared/abstractStore';\r\nimport { SubscriptionAssessmentCreateInput } from '../generated/globalTypes';\r\nimport { createSubscriptionAssessmentMutation, createSubscriptionAssessmentMutationVariables } from '../generated/createSubscriptionAssessmentMutation';\r\nimport { subscriptionAssessmentFieldsFragment } from '../models/SubscriptionAssessment';\r\n\r\n/**\r\n * Get a callback to create a SubscriptionAssessment in the store.\r\n */\r\nexport function useCreateSubscriptionAssessmentCallback(): [(model: SubscriptionAssessmentCreateInput) => Promise, AsyncActionStatus] {\r\n const [mutationAction, { error }] = useMutation(\r\n gql`\r\n mutation createSubscriptionAssessmentMutation ($model: SubscriptionAssessmentCreateInput!) {\r\n createSubscriptionAssessment(model: $model) {\r\n ...subscriptionAssessmentFields\r\n }\r\n }\r\n\r\n ${subscriptionAssessmentFieldsFragment}\r\n `\r\n );\r\n\r\n // Wrap the mutation in a standard callback.\r\n const [action, { isExecuting, errors: actionErrors }] = useAsyncCallback(async (model: SubscriptionAssessmentCreateInput) => {\r\n const result = await mutationAction({ variables: { model: model } });\r\n if (result.errors && result.errors.length) {\r\n throw result.errors;\r\n }\r\n }, [mutationAction]);\r\n\r\n return [action, { isExecuting: isExecuting, errors: error ? error.message : actionErrors }];\r\n}\r\n","import { useMutation } from \"@apollo/react-hooks\";\r\nimport { useAsyncCallback } from 'react-use-async-callback';\r\nimport gql from \"graphql-tag\";\r\nimport { AsyncActionStatus } from '../../../shared/abstractStore';\r\nimport { SubscriptionAssessmentUpdateInput } from '../generated/globalTypes';\r\nimport { updateSubscriptionAssessmentMutation, updateSubscriptionAssessmentMutationVariables } from '../generated/updateSubscriptionAssessmentMutation';\r\nimport { subscriptionAssessmentFieldsFragment } from '../models/SubscriptionAssessment';\r\n\r\n/**\r\n * Get a callback to update a SubscriptionAssessment in the store.\r\n */\r\nexport function useUpdateSubscriptionAssessmentCallback(): [(id: string, model: SubscriptionAssessmentUpdateInput) => Promise, AsyncActionStatus] {\r\n const [mutationAction, { error }] = useMutation(\r\n gql`\r\n mutation updateSubscriptionAssessmentMutation ($model: SubscriptionAssessmentUpdateInput!) {\r\n updateSubscriptionAssessment(model: $model) {\r\n ...subscriptionAssessmentFields\r\n }\r\n }\r\n\r\n ${subscriptionAssessmentFieldsFragment}\r\n `\r\n );\r\n\r\n // Wrap the mutation in a standard callback.\r\n const [action, { isExecuting, errors: actionErrors }] = useAsyncCallback(async (id: string, model: SubscriptionAssessmentUpdateInput) => {\r\n const result = await mutationAction({ variables: { model: { ...model, id: id } } });\r\n if (result.errors && result.errors.length) {\r\n throw result.errors;\r\n }\r\n }, [mutationAction]);\r\n\r\n return [action, { isExecuting: isExecuting, errors: error ? error.message : actionErrors }];\r\n}\r\n","import * as React from 'react';\r\nimport { Table, Button, Row, Col, ButtonGroup, Input } from 'reactstrap';\r\nimport { AlertOnErrors } from '../../shared/alertOnErrors';\r\nimport { LoadingIndicator } from '../shared/LoadingIndicator';\r\nimport { Waypoint } from 'react-waypoint';\r\nimport { useReplaceSearchParamsEffect, useSearchParams } from '../../shared/useURLSearchParams';\r\nimport { useTranslation } from 'react-i18next';\r\nimport { SearchInput } from '../shared/searchInput/SearchInput';\r\nimport { FontAwesomeIcon } from '@fortawesome/react-fontawesome';\r\nimport { MainContainer } from '../shared/MainContainer';\r\nimport { NoResultsFound } from '../shared/NoResultsFound';\r\nimport { StickyToolbar } from '../shared/StickyToolbar';\r\nimport { useParams } from 'react-router';\r\nimport { ConditionalFragment } from 'react-conditionalfragment';\r\nimport { Banner } from '../shared/Banner';\r\nimport { Background } from '../shared/background/Background';\r\nimport { FeedbackStyle, feedbackStyleDisplayName } from '../../api/main/models/codeOnly/FeedbackStyle';\r\nimport { AssessmentType } from '../../api/main/models/codeOnly/AssessmentType';\r\nimport { PillsNavBar } from '../shared/pillsNavBar/PillsNavBar';\r\nimport { SubscriptionAdministrationNavigation } from '../subscriptions/SubscriptionAdministrationNavigation';\r\nimport { useSubscriptionAssessmentsListViewBaseViewModel } from '../../api/main/subscriptionAssessments/viewModels/useSubscriptionAssessmentsListBaseViewModel';\r\nimport { useChangesArray } from '../../shared/useChanges';\r\nimport { SubscriptionAssessment, subscriptionAssessmentDefaultValues } from '../../api/main/models/SubscriptionAssessment';\r\nimport { useSaveSubscriptionAssessmentCallback } from '../../api/main/subscriptionAssessments/useSaveSubscriptionAssessmentCallback';\r\nimport { useDeleteSubscriptionAssessmentCallback } from '../../api/main/subscriptionAssessments/useDeleteSubscriptionAssessmentCallback';\r\nimport { useAsyncCallback } from 'react-use-async-callback';\r\nimport { useDebouncedCallback } from 'use-debounce/lib';\r\nimport { Link } from 'react-router-dom';\r\nimport { useCallback, useState } from 'react';\r\nimport { useCurrentUserOrEmulatedSubscriptionId } from '../../globalState/subscriptions/useCurrentUserOrEmulatedSubscriptionId';\r\n\r\nexport interface SubscriptionAssessmentsListBaseBaseProps {\r\n title: string,\r\n mobileColumn1Name: string,\r\n assessmentTypes: Array,\r\n baseRoute: string,\r\n navigationPills?: React.ReactNode,\r\n isDistributorSubscription?: boolean,\r\n isStudy?: boolean,\r\n}\r\n\r\n/**\r\n * Base list functionality for Assessments (including Learning).\r\n * \r\n * You most often want to use the components that wrap this one rather than this one directly.\r\n */\r\nexport const SubscriptionAssessmentsListBase = (props: SubscriptionAssessmentsListBaseBaseProps) => {\r\n const {\r\n title,\r\n mobileColumn1Name,\r\n assessmentTypes,\r\n baseRoute,\r\n navigationPills,\r\n isDistributorSubscription,\r\n isStudy = false,\r\n } = props;\r\n\r\n const { subscriptionId } = useParams<{ subscriptionId: string | undefined; }>();\r\n\r\n const currentSubscriptionId = useCurrentUserOrEmulatedSubscriptionId();\r\n const lowerSubscriptionId = subscriptionId ?? undefined;\r\n\r\n const subscriptionIdToUse = React.useMemo(() => {\r\n //values are passed in with different param names, need to determine which to search by\r\n if (isDistributorSubscription) {\r\n return currentSubscriptionId;\r\n } else {\r\n return (subscriptionId);\r\n }\r\n\r\n }, [currentSubscriptionId, subscriptionId, isDistributorSubscription]);\r\n\r\n const { t } = useTranslation();\r\n const { search: searchParam } = useSearchParams();\r\n const [search, setSearch] = React.useState(searchParam ?? '');\r\n const {\r\n data: { items: storeSubscriptionAssessments, selectedItems, assessments: allItems, subscription, },\r\n isLoading, errors: loadingErrors, fetchMore, hasMore\r\n } = useSubscriptionAssessmentsListViewBaseViewModel(subscriptionIdToUse, { pageSize: undefined, assessmentTypes: assessmentTypes, lowerSubscriptionId: lowerSubscriptionId });\r\n\r\n const [currentAssessments, setCurrentAssessments] = React.useState>();\r\n React.useEffect(() => {\r\n //do we need to filter items to just current distributor items\r\n if (isDistributorSubscription) {\r\n setCurrentAssessments(selectedItems);\r\n } else {\r\n setCurrentAssessments(storeSubscriptionAssessments);\r\n }\r\n\r\n\r\n }, [setCurrentAssessments, storeSubscriptionAssessments, selectedItems, isDistributorSubscription]);\r\n\r\n\r\n // Manage the addition and removal of items for this subscription.\r\n const subscriptionAsssessmentsManager = useChangesArray(currentAssessments, item => item.id);\r\n const [saveSubscriptionAssessment] = useSaveSubscriptionAssessmentCallback();\r\n const [removeSubscriptionAssessment] = useDeleteSubscriptionAssessmentCallback();\r\n\r\n // Save all changes to the subscriptionAssessmentManager.\r\n const [saveAllSubscriptionAssessments] = useAsyncCallback(async () => {\r\n // Save to the store.\r\n for (const item of subscriptionAsssessmentsManager.added) { await saveSubscriptionAssessment(item.id, subscriptionAsssessmentsManager.changesFor(item.id), true); }\r\n for (const item of subscriptionAsssessmentsManager.updated) { await saveSubscriptionAssessment(item.id, subscriptionAsssessmentsManager.changesFor(item.id), false); }\r\n for (const item of subscriptionAsssessmentsManager.removed) { await removeSubscriptionAssessment(item.id); }\r\n subscriptionAsssessmentsManager.markAsSaved();\r\n }, [subscriptionAsssessmentsManager, saveSubscriptionAssessment, removeSubscriptionAssessment]);\r\n // Debounced version to avoid going to the server too often.\r\n const saveAllSubscriptionAssessmentsDebounced = useDebouncedCallback(() => {\r\n saveAllSubscriptionAssessments();\r\n });\r\n\r\n //const [subscriptionToUse, setSubscriptionToUse] = React.useState();\r\n\r\n // Toggle if an assessment is selected for the subscription or not.\r\n const toggleSubscriptionAssessment = useCallback((assessmentId: string) => {\r\n const existing = subscriptionAsssessmentsManager.model.find(item => item.assessmentId === assessmentId);\r\n\r\n const subscriptionToUse = subscriptionId ?? currentSubscriptionId;\r\n\r\n if (existing) {\r\n subscriptionAsssessmentsManager.removeFor(existing.id);\r\n\r\n } else {\r\n if (isStudy && subscriptionAsssessmentsManager.model.length > 0) {\r\n // Limit to one assessment for studies.\r\n return;\r\n }\r\n subscriptionAsssessmentsManager.addFor({\r\n ...subscriptionAssessmentDefaultValues(),\r\n\r\n subscriptionId: subscriptionToUse!,\r\n assessmentId: assessmentId,\r\n });\r\n }\r\n\r\n // Save to the store after a debounce to allow grouping of quick actions and the state itself to be updated.\r\n saveAllSubscriptionAssessmentsDebounced();\r\n }, [subscriptionAsssessmentsManager, currentSubscriptionId, saveAllSubscriptionAssessmentsDebounced, subscriptionId, isStudy]);\r\n\r\n // Returns true if the assessment is selected for this subscription.\r\n const isSubscriptionAssessmentSelected = useCallback((assessmentId: string) => !!subscriptionAsssessmentsManager.model.find(item => item.assessmentId === assessmentId), [subscriptionAsssessmentsManager]);\r\n\r\n const isSubscriptionAssessmentSelectedByDistributor = useCallback((assessmentId: string) =>\r\n !!storeSubscriptionAssessments.find(item => item.assessmentId === assessmentId), [storeSubscriptionAssessments]);\r\n\r\n // Filtering the display between all and selected only.\r\n const [filter, setFilter] = useState<'all' | 'selected'>('all');\r\n\r\n // Filter by the assessment's search client side so it can work when offline as well as online.\r\n const items = React.useMemo(() => {\r\n if (!allItems) {\r\n return allItems;\r\n }\r\n\r\n let ret = allItems;\r\n\r\n if (isDistributorSubscription) {\r\n\r\n ret = ret.filter(item => isSubscriptionAssessmentSelectedByDistributor(item.id));\r\n\r\n } else {\r\n\r\n // Filter by the selected filter.\r\n switch (filter) {\r\n case 'all':\r\n break;\r\n case 'selected': {\r\n ret = ret.filter(item => isSubscriptionAssessmentSelected(item.id));\r\n }\r\n }\r\n }\r\n\r\n // Filter by the user's search text.\r\n if (search) {\r\n let lowerSearch = search.toLocaleLowerCase();\r\n\r\n ret = ret.filter(item =>\r\n item.name.toLocaleLowerCase().indexOf(lowerSearch) >= 0\r\n );\r\n }\r\n\r\n return ret;\r\n }, [allItems, search, filter, isSubscriptionAssessmentSelected, isSubscriptionAssessmentSelectedByDistributor, isDistributorSubscription]);\r\n\r\n useReplaceSearchParamsEffect({ search: search });\r\n\r\n const colCount = 5;\r\n\r\n // Limit to one assessment for studies.\r\n const assessmentLimit = 1;\r\n\r\n // Count the number of assessments for this study.\r\n const currentAssessmentCount = React.useMemo(() => {\r\n if (!subscriptionAsssessmentsManager) return 0;\r\n\r\n return subscriptionAsssessmentsManager.model.length;\r\n }, [subscriptionAsssessmentsManager]);\r\n\r\n // Render the UI\r\n //\r\n return (\r\n \r\n \r\n \r\n \r\n \r\n

\r\n {title}\r\n

\r\n \r\n \r\n \r\n {navigationPills}\r\n \r\n \r\n \r\n \r\n \r\n\r\n
\r\n \r\n \r\n

\r\n {subscription?.companyName}\r\n

\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n setSearch(e.currentTarget.value)} />\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n
\r\n \r\n \r\n

{t('', 'A study is limited to {{assessmentLimit}} assessment{{pluraliseOrNot}}. This study has {{currentAssessmentCount}} of {{assessmentLimit}} assessment{{pluraliseOrNot}}', { assessmentLimit, pluraliseOrNot: assessmentLimit > 1 ? 's' : '', currentAssessmentCount })}

\r\n \r\n
\r\n
\r\n
\r\n\r\n \r\n \r\n\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n {\r\n items?.map(item => {\r\n const itemIsSelected = isSubscriptionAssessmentSelected(item.id);\r\n const subscriptionAsssessment = subscriptionAsssessmentsManager.model.find(it => it.assessmentId === item.id);\r\n\r\n return (\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n );\r\n })\r\n }\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n
 {mobileColumn1Name}{t('subscriptionAssessmentsListBase.name', 'Name')}{t('subscriptionAssessmentsListBase.maxRestarts', 'Maximum retakes per user')}{t('subscriptionAssessmentsListBase.feedbackStyle', 'Feedback style')}{t('subscriptionAssessmentsListBase.isSmartIndividuality.heading', 'Smart?')}
\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n
\r\n \r\n {item.name}\r\n \r\n
\r\n
\r\n \r\n {item.name}\r\n \r\n \r\n \r\n subscriptionAsssessmentsManager.changeFor(subscriptionAsssessment?.id ?? '', { maxRestarts: e.currentTarget.valueAsNumber })}\r\n onBlur={() => saveAllSubscriptionAssessmentsDebounced()}\r\n />\r\n \r\n {feedbackStyleDisplayName(item.feedbackStyle as FeedbackStyle, t)}{\r\n item.isSmartIndividuality ? t('subscriptionAssessmentsListBase.isSmartIndividuality.smart', 'Smart')\r\n : t('subscriptionAssessmentsListBase.isSmartIndividuality.standardised', 'Standardised')\r\n }
\r\n \r\n
\r\n \r\n \r\n
\r\n
\r\n
\r\n );\r\n};\r\n","import * as React from 'react';\r\nimport { useLazyQuery } from \"@apollo/react-hooks\";\r\nimport gql from \"graphql-tag\";\r\nimport { AsyncLoadPagedResult, AsyncLoadPagedOptions } from '../../../../shared/abstractStore';\r\nimport { useFetchMoreCallback } from '../../../../shared/useFetchMoreCallback';\r\nimport { subscriptionAssessmentsListViewBaseViewModelQuery, subscriptionAssessmentsListViewBaseViewModelQueryVariables } from '../../generated/subscriptionAssessmentsListViewBaseViewModelQuery';\r\nimport { mainApiConfig } from '../../../../configure/mainApiConfig';\r\nimport { subscriptionAssessmentFieldsFragment } from '../../models/SubscriptionAssessment';\r\nimport { AssessmentType } from '../../models/codeOnly/AssessmentType';\r\nimport { assessmentFieldsFragment } from '../../models/Assessment';\r\nimport { subscriptionFieldsFragment } from '../../models/Subscription';\r\nimport { Guid } from 'guid-string';\r\n\r\n\r\nexport interface SubscriptionAssessmentsListViewBaseViewModelAsyncLoadPageOptions extends AsyncLoadPagedOptions {\r\n assessmentTypes?: Array,\r\n lowerSubscriptionId?: string | undefined | null,\r\n}\r\n\r\n/**\r\n * Get a list of subscriptionAssessments from the store.\r\n * @param options\r\n */\r\nexport function useSubscriptionAssessmentsListViewBaseViewModel(subscriptionId: string | null | undefined, options: SubscriptionAssessmentsListViewBaseViewModelAsyncLoadPageOptions = {}): AsyncLoadPagedResult {\r\n // Query data we need from the api.\r\n const [load, { data, loading, error, refetch, fetchMore: fetchMoreFromStore }] = useLazyQuery(\r\n gql`\r\n query subscriptionAssessmentsListViewBaseViewModelQuery ($subscriptionId: ID!, $lowerSubscriptionId: ID, $offset: Int, $first: Int, $assessmentTypes: [String!]) {\r\n items: subscriptionAssessments (subscriptionId: $subscriptionId) {\r\n ...subscriptionAssessmentFields\r\n }\r\n\r\n selectedItems: subscriptionAssessments(subscriptionId: $lowerSubscriptionId) {\r\n ...subscriptionAssessmentFields\r\n }\r\n\r\n assessments (offset: $offset, first: $first, assessmentTypes: $assessmentTypes) {\r\n ...assessmentFields\r\n }\r\n\r\n subscription (id: $subscriptionId) {\r\n ...subscriptionFields\r\n }\r\n }\r\n\r\n ${subscriptionAssessmentFieldsFragment}\r\n ${assessmentFieldsFragment}\r\n ${subscriptionFieldsFragment}\r\n `,\r\n {\r\n\r\n variables: {\r\n offset: options.startOffset,\r\n first: options.pageSize,\r\n assessmentTypes: options.assessmentTypes,\r\n subscriptionId: subscriptionId ?? Guid.empty,\r\n lowerSubscriptionId: options.lowerSubscriptionId,\r\n },\r\n fetchPolicy: options.fetchPolicy ?? mainApiConfig.defaultFetchPolicy,\r\n pollInterval: options.pollInterval,\r\n onCompleted: (data) => {\r\n if (options.onCompleted) {\r\n options.onCompleted(data);\r\n }\r\n }\r\n }\r\n );\r\n\r\n // Run the query (unless we are being lazy).\r\n React.useEffect(() => {\r\n if (!options.lazy) {\r\n load();\r\n }\r\n }, [options.lazy, load])\r\n\r\n // Get the functions used to manage paging.\r\n const { fetchMore, hasMore: _hasMore } = useFetchMoreCallback(\r\n fetchMoreFromStore,\r\n (options?.startOffset ?? 0) + (data?.items?.length ?? 0),\r\n (prevResults, newResults) => ({\r\n ...prevResults,\r\n ...newResults,\r\n\r\n items: newResults?.items ?? [],\r\n selectedItems: newResults?.selectedItems ?? [],\r\n subscription: newResults?.subscription ?? null,\r\n assessments: [...(prevResults?.assessments ?? []), ...(newResults?.assessments ?? [])]\r\n }),\r\n (newResults) => newResults?.items?.length\r\n );\r\n const hasMore = React.useCallback(() => !options.pageSize ? false : _hasMore(), [options.pageSize, _hasMore]);\r\n \r\n // Return the results.\r\n const refresh = React.useCallback(async () => { !refetch ? await load() : await refetch(); }, [refetch, load]);\r\n return React.useMemo(() => ({\r\n data: data ?? ({} as any),\r\n refresh: refresh,\r\n isLoading: loading,\r\n errors: error,\r\n fetchMore: fetchMore,\r\n hasMore: hasMore,\r\n }), [data, refresh, loading, error, fetchMore, hasMore]);\r\n}\r\n","import * as React from 'react';\r\nimport { SubscriptionAssessmentCreateInput, SubscriptionAssessmentUpdateInput } from '../generated/globalTypes';\r\nimport { useSaveInStore, SaveInStoreOptions } from '../../../shared/useSaveInStore';\r\nimport { useCreateSubscriptionAssessmentCallback } from './useCreateSubscriptionAssessmentCallback';\r\nimport { useUpdateSubscriptionAssessmentCallback } from './useUpdateSubscriptionAssessmentCallback';\r\nimport { SubscriptionAssessment } from '../models/SubscriptionAssessment';\r\n\r\n/**\r\n * Get a callback to save a SubscriptionAssessment in the store using either a create or update.\r\n */\r\nexport function useSaveSubscriptionAssessmentCallback(options: SaveInStoreOptions = {}) {\r\n const [_create, createStatus] = useCreateSubscriptionAssessmentCallback();\r\n const create = React.useCallback((model: Partial) => _create(model as SubscriptionAssessmentCreateInput), [_create]);\r\n\r\n const [_update, updateStatus] = useUpdateSubscriptionAssessmentCallback();\r\n const update = React.useCallback((id: string, changes: Partial) => _update(id, changes as SubscriptionAssessmentUpdateInput), [_update]);\r\n\r\n return useSaveInStore(\r\n [create, createStatus],\r\n [update, updateStatus],\r\n options\r\n );\r\n}\r\n","import { useMutation } from \"@apollo/react-hooks\";\r\nimport { useAsyncCallback } from 'react-use-async-callback';\r\nimport gql from \"graphql-tag\";\r\nimport { AsyncActionStatus } from '../../../shared/abstractStore';\r\nimport { deleteSubscriptionAssessmentMutation, deleteSubscriptionAssessmentMutationVariables } from '../generated/deleteSubscriptionAssessmentMutation';\r\nimport { subscriptionAssessmentFieldsFragment } from '../models/SubscriptionAssessment';\r\n\r\n/**\r\n * Get a callback to delete a SubscriptionAssessment in the store.\r\n */\r\nexport function useDeleteSubscriptionAssessmentCallback(): [(id: string) => Promise, AsyncActionStatus] {\r\n const [mutationAction, { error }] = useMutation(\r\n gql`\r\n mutation deleteSubscriptionAssessmentMutation ($id: ID!) {\r\n deleteSubscriptionAssessment(id: $id) {\r\n ...subscriptionAssessmentFields\r\n }\r\n }\r\n\r\n ${subscriptionAssessmentFieldsFragment}\r\n `\r\n );\r\n\r\n // Wrap the mutation in a standard callback.\r\n const [action, { isExecuting, errors: actionErrors }] = useAsyncCallback(async (id: string) => {\r\n const result = await mutationAction({ variables: { id: id } });\r\n if (result.errors && result.errors.length) {\r\n throw result.errors;\r\n }\r\n }, [mutationAction]);\r\n\r\n return [action, { isExecuting: isExecuting, errors: error ? error.message : actionErrors }];\r\n}\r\n","import { RouteEntry } from \"../../../shared/routes\";\r\nimport { IdentityRoles } from \"../../../configure/security/IdentityRoles\";\r\nimport { SubscriptionAssessmentsList } from \"./SubscriptionAssessmentsList\";\r\n\r\nexport const subscriptionAssessmentRoutes: Array = [\r\n { path: '/administration/subscriptions/details/:subscriptionId/assessments', exact: true, component: SubscriptionAssessmentsList, authorize: true, requireRole: IdentityRoles.Administration },\r\n];\r\n","import { useTranslation } from \"react-i18next\";\r\nimport { AssessmentType } from \"../../../api/main/models/codeOnly/AssessmentType\";\r\nimport { SubscriptionAssessmentsListBase } from \"../SubscriptionAssessmentsListBase\";\r\n\r\n/**\r\n * List of actual assessments for a subscription\r\n */\r\nexport const SubscriptionAssessmentsList = () => {\r\n const { t } = useTranslation();\r\n\r\n return (\r\n \r\n );\r\n};","import { RouteEntry } from \"../../../shared/routes\";\r\nimport { IdentityRoles } from \"../../../configure/security/IdentityRoles\";\r\nimport { SubscriptionTrainingModulesList } from \"./SubscriptionTrainingModulesList\";\r\n\r\nexport const subscriptionTrainingModuleAssessmentRoutes: Array = [\r\n { path: '/administration/subscriptions/details/:subscriptionId/training', exact: true, component: SubscriptionTrainingModulesList, authorize: true, requireRole: IdentityRoles.Administration },\r\n];\r\n","import { useTranslation } from \"react-i18next\";\r\nimport { AssessmentType } from \"../../../api/main/models/codeOnly/AssessmentType\";\r\nimport { SubscriptionAssessmentsListBase } from \"../SubscriptionAssessmentsListBase\";\r\n\r\n/**\r\n * List of actual assessments for a subscription\r\n */\r\nexport const SubscriptionTrainingModulesList = () => {\r\n const { t } = useTranslation();\r\n\r\n return (\r\n \r\n );\r\n};","import gql from \"graphql-tag\";\r\nimport { Guid } from \"guid-string\";\r\nimport moment from \"moment\";\r\nimport { userAssessmentAssignmentFields } from \"../generated/userAssessmentAssignmentFields\";\r\n\r\nexport const userAssessmentAssignmentFieldsFragment = gql`\r\n fragment userAssessmentAssignmentFields on UserAssessmentAssignment {\r\n id\r\n subscriptionId\r\n userId\r\n subscriptionTeamId\r\n assessmentId\r\n targetDate\r\n archived\r\n maxRestarts\r\n }\r\n`;\r\n\r\n\r\nexport type UserAssessmentAssignment = Omit;\r\n\r\n// Default values.\r\nexport const userAssessmentAssignmentDefaultValues = (): Partial => ({\r\n id: Guid.newGuid(),\r\n subscriptionId: undefined,\r\n assessmentId: undefined,\r\n subscriptionTeamId: undefined,\r\n userId: undefined,\r\n targetDate: moment().add('month', 2).toISOString(),\r\n archived: false,\r\n maxRestarts: 0,\r\n});","import gql from \"graphql-tag\";\r\nimport { Guid } from \"guid-string\";\r\nimport moment from \"moment\";\r\nimport { assessmentSessionFields } from \"../generated/assessmentSessionFields\";\r\n\r\nexport const assessmentSessionFieldsFragment = gql`\r\n fragment assessmentSessionFields on AssessmentSession {\r\n id\r\n assessmentId\r\n userId\r\n subscriptionId\r\n archived\r\n startDate\r\n endDate\r\n totalScore\r\n currentPosition\r\n isFinished\r\n sessionInitializationJson\r\n markedSuspicious\r\n browserDataJson\r\n }\r\n`;\r\n\r\n\r\nexport type AssessmentSession = Omit;\r\n\r\n// Default values.\r\nexport const assessmentSessionDefaultValues = (): Partial => ({\r\n id: Guid.newGuid(),\r\n assessmentId: undefined,\r\n userId: undefined,\r\n subscriptionId: undefined,\r\n archived: false,\r\n startDate: moment().toISOString(),\r\n endDate: null,\r\n totalScore: 0,\r\n currentPosition: 0,\r\n isFinished: false,\r\n sessionInitializationJson: '',\r\n markedSuspicious: false,\r\n});","import { ReactNode, useMemo } from \"react\";\r\nimport { CircularProgressbarWithChildren } from \"react-circular-progressbar\";\r\nimport { useTranslation } from \"react-i18next\";\r\nimport { AssessmentType } from \"../../../../api/main/models/codeOnly/AssessmentType\";\r\nimport { overallRiskService } from \"../../../../services/OverallRiskService\";\r\nimport { QuestionScore } from \"../utilities/calculateQuestionScore\";\r\nimport \"./scoreProgressBar.scss\";\r\n\r\nexport interface ScoreProgressBarProps {\r\n value: QuestionScore,\r\n assessmentType?: AssessmentType,\r\n title?: ReactNode,\r\n size?: 'sm' | 'md' | 'lg',\r\n}\r\n\r\n/**\r\n * ProgressBar showing a score.\r\n * @param props\r\n */\r\nexport const ScoreProgressBar = (props: ScoreProgressBarProps) => {\r\n const {\r\n value,\r\n assessmentType = AssessmentType.Assessment,\r\n title,\r\n size = 'md'\r\n } = props;\r\n\r\n const { t } = useTranslation();\r\n\r\n const riskName = useMemo(() => {\r\n return overallRiskService.getRiskName(value.riskCategory);\r\n }, [value]);\r\n \r\n\r\n return (\r\n
\r\n \r\n
\r\n {title ?? t('scoreProgressBar.heading', 'Score')}\r\n
\r\n
\r\n {t('common.percent', '{{value}}%', { value: value.score })}\r\n
\r\n
\r\n {\r\n assessmentType === AssessmentType.TrainingModule ? t('scoreProgressBar.riskName.training', 'Training')\r\n : riskName\r\n }\r\n
\r\n
\r\n
\r\n );\r\n};","import { overallRiskService, RiskRules } from \"../../../../services/OverallRiskService\";\r\nimport { QuestionScore } from \"./calculateQuestionScore\";\r\n\r\n/**\r\n * Creates a QuestionScore from a number.\r\n */\r\nexport function questionScoreFromNumber(value: number, notStarted: boolean, riskRules?: RiskRules | undefined | null): QuestionScore {\r\n let score: number = value;\r\n\r\n if (score < 0) {\r\n score = 0;\r\n }\r\n\r\n if (score > 100) {\r\n score = 100;\r\n }\r\n\r\n const riskCategory = overallRiskService.getRiskCategory(score, notStarted, riskRules);\r\n\r\n return {\r\n score,\r\n minScore: 0,\r\n maxScore: 100,\r\n riskCategory,\r\n };\r\n}","import { FontAwesomeIcon } from \"@fortawesome/react-fontawesome\";\r\nimport moment from \"moment\";\r\nimport { useMemo } from \"react\";\r\nimport { ConditionalFragment } from \"react-conditionalfragment\";\r\nimport { useTranslation } from \"react-i18next\";\r\n\r\nexport interface DueDateLabelProps {\r\n dueDate: string | undefined | null,\r\n completedDate?: string | undefined | null,\r\n}\r\n\r\n/**\r\n * Component for showing a due date (that may optionally also be completed).\r\n * @param props\r\n */\r\nexport const DueDateLabel = (props: DueDateLabelProps) => {\r\n const { dueDate, completedDate, } = props;\r\n\r\n const { t } = useTranslation();\r\n\r\n const color = useMemo(() => {\r\n const now = moment().toISOString();\r\n const dueSoonDateIso = moment().add(7, 'day').toISOString();\r\n const dueDateIso = moment(dueDate).toISOString();\r\n\r\n if (completedDate) {\r\n return 'success';\r\n }\r\n\r\n if (dueDateIso < now) {\r\n return 'danger';\r\n }\r\n\r\n if (dueDateIso < now) {\r\n return 'danger';\r\n }\r\n\r\n if (dueDateIso < dueSoonDateIso) {\r\n return 'warning';\r\n }\r\n\r\n return 'muted';\r\n }, [dueDate, completedDate]);\r\n\r\n return (\r\n \r\n {\r\n completedDate ? (\r\n <>\r\n \r\n <> \r\n {t('dashboardAssessmentCard.finishedOn', 'Completed on: {{date, DD/MM/YYYY}}', { date: moment(completedDate).local() })}\r\n \r\n ) : dueDate ? (\r\n <>\r\n \r\n \r\n <> \r\n \r\n {t('dashboardAssessmentCard.dueBy', 'Due by: {{date, DD/MM/YYYY}}', { date: moment(dueDate).local() })}\r\n \r\n ) : null\r\n }\r\n \r\n );\r\n};","import { useMemo } from \"react\";\r\nimport { ConditionalFragment } from \"react-conditionalfragment\";\r\nimport { useTranslation } from \"react-i18next\";\r\nimport { LinkContainer } from \"react-router-bootstrap\";\r\nimport { Button, ButtonGroup, Card, CardTitle, Col, Row } from \"reactstrap\";\r\nimport { Assessment } from \"../../api/main/models/Assessment\";\r\nimport { AssessmentSession } from \"../../api/main/models/AssessmentSession\";\r\nimport { AssessmentType } from \"../../api/main/models/codeOnly/AssessmentType\";\r\nimport { UserAssessmentAssignment } from \"../../api/main/models/UserAssessmentAssignment\";\r\nimport { IdentityRoles } from \"../../configure/security/IdentityRoles\";\r\nimport { AuthorizeContainer } from \"../../shared/authorizeRoute\";\r\nimport { HtmlDisplay } from \"../../shared/htmlEditor\";\r\nimport { ScoreProgressBar } from \"../assessmentSessions/launch/progress/ScoreProgressBar\";\r\nimport { questionScoreFromNumber } from \"../assessmentSessions/launch/utilities/questionScoreFromNumber\";\r\nimport \"./dashboardAssessmentCard.scss\";\r\nimport { DueDateLabel } from \"./DueDateLabel\";\r\n\r\nexport interface DashboardAssessmentCardProps {\r\n assessment: Assessment,\r\n assignment: UserAssessmentAssignment | undefined | null,\r\n session: AssessmentSession | undefined | null,\r\n canRetake?: boolean,\r\n\r\n inline?: boolean,\r\n}\r\n\r\n/**\r\n * Card for launching an assessment.\r\n * @param props\r\n */\r\nexport const DashboardAssessmentCard = (props: DashboardAssessmentCardProps) => {\r\n const {\r\n assessment,\r\n assignment,\r\n session,\r\n inline = false,\r\n canRetake = false,\r\n } = props;\r\n const { t } = useTranslation();\r\n\r\n const baseRoute = useMemo(() => {\r\n if (assessment.assessmentType === AssessmentType.TrainingModule) {\r\n return '/training';\r\n } else {\r\n return '/assessment';\r\n }\r\n }, [assessment.assessmentType]);\r\n\r\n // We position the date in a couple of places depending on if we are inline or not, so we generate it seperatly here for convienience.\r\n const DateLabelComponent = () => (\r\n \r\n );\r\n\r\n return (\r\n \r\n \r\n {assessment.name}\r\n \r\n \r\n
\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n
\r\n\r\n
\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n\r\n {/* In inline mode we want to show the date under the buttons */}\r\n \r\n
\r\n \r\n
\r\n
\r\n \r\n
\r\n
\r\n
\r\n );\r\n};","import { Guid } from \"guid-string\";\r\nimport { useCallback, useMemo } from \"react\";\r\nimport { ConditionalFragment } from \"react-conditionalfragment\";\r\nimport { useTranslation } from \"react-i18next\";\r\nimport { useParams } from \"react-router-dom\";\r\nimport { Card, CardGroup, Container } from \"reactstrap\";\r\nimport { isUndefined } from \"util\";\r\nimport { useMeDashboardViewModel } from \"../../api/main/meDashboardViewModels/useMeDashboardViewModel\";\r\nimport { AssessmentSession } from \"../../api/main/models/AssessmentSession\";\r\nimport { AssessmentType } from \"../../api/main/models/codeOnly/AssessmentType\";\r\nimport { SubscriptionType } from \"../../api/main/models/codeOnly/SubscriptionType\";\r\nimport { useCurrentUserProfile } from \"../../api/main/profiles/useCurrentUserProfile\";\r\nimport { useSubscription } from \"../../api/main/subscriptions/useSubscription\";\r\nimport { AlertOnErrors } from \"../../shared/alertOnErrors\";\r\nimport { Background } from \"../shared/background/Background\";\r\nimport { Banner } from \"../shared/Banner\";\r\nimport { NoResultsFound } from \"../shared/NoResultsFound\";\r\nimport { DashboardAssessmentCard } from \"./DashboardAssessmentCard\";\r\n\r\nexport interface MeDashboardProps {\r\n\r\n}\r\n\r\nexport const MeDashboard = (props: MeDashboardProps) => {\r\n\r\n const { profileId: profileIdParam } = useParams<{ profileId: string }>();\r\n const { data: { model: currentUserProfile } } = useCurrentUserProfile();\r\n\r\n const profileId = profileIdParam ?? currentUserProfile?.id;\r\n\r\n const { t } = useTranslation();\r\n\r\n const { data: { viewModel, profile }, errors: loadErrors } = useMeDashboardViewModel(profileId);\r\n const { assessments, userAssessmentAssignments, assessmentSessions } = viewModel ?? ({ assessments: [], userAssessmentAssignments: [], assessmentSessions: [] });\r\n\r\n // If the user is part of a study, we want to customise their expeirence a little.\r\n const { data: { model: subscription } } = useSubscription(currentUserProfile?.subscriptionId ?? Guid.empty);\r\n const isStudyParticipant = useMemo(() => !!profile?.subscriptionId && subscription?.subscriptionType === SubscriptionType.Study, [subscription, profile]);\r\n\r\n // Going to need a few counts.\r\n const {\r\n assessmentsCount,\r\n trainingCount,\r\n } = useMemo(() => {\r\n let assessmentsCount = 0;\r\n let trainingCount = 0;\r\n\r\n for (const assignment of userAssessmentAssignments) {\r\n // Lookup the assessment model.\r\n const assessment = assessments.find(it => it.id === assignment.assessmentId);\r\n if (!assessment) {\r\n continue;\r\n }\r\n \r\n if (assessment.assessmentType === AssessmentType.Assessment) {\r\n ++assessmentsCount;\r\n } else if (assessment.assessmentType === AssessmentType.TrainingModule) {\r\n ++trainingCount;\r\n }\r\n }\r\n\r\n return {\r\n assessmentsCount,\r\n trainingCount,\r\n };\r\n }, [userAssessmentAssignments, assessments]);\r\n\r\n // Returns details of what the user can do with this assessment.\r\n const getAssessmentSummary = useCallback((assessmentId: string) => {\r\n const mySessions = assessmentSessions?.filter(item => item.assessmentId === assessmentId) ?? [];\r\n\r\n const completionCount = mySessions.filter(item => item.isFinished).length;\r\n const startedCount = mySessions.filter(item => !!item.startDate).length;\r\n\r\n //The first value we want to try is max restart limit on user assessments\r\n var maxRestartCount = userAssessmentAssignments.find(item => item.assessmentId === assessmentId && item.userId === profile?.userId)?.maxRestarts;\r\n\r\n return {\r\n isEverFinished: completionCount > 0,\r\n isLatestFinished: mySessions.length === 0 ? false : mySessions[0].isFinished,\r\n canRetake:\r\n //Esitu staff (those without subscriptionIds) can always retake assessments (mostly for testing and demo purposes).\r\n startedCount <= maxRestartCount! || !profile?.subscriptionId ? true : false, // Everyone else can only retake up to the specified number of times licensed to the subscription.\r\n };\r\n }, [assessmentSessions, profile, userAssessmentAssignments]);\r\n\r\n // Generate the card components to show for the requested assessmentType,.\r\n const generateCards = useCallback((options: { assessmentType?: AssessmentType, includeIfEverFinishedIs?: boolean, includeIfLatestFinishedIs?: boolean, displayInline?: boolean, }) => (\r\n <>\r\n {\r\n userAssessmentAssignments.map(assignment => {\r\n // Lookup the assessment model.\r\n const assessment = assessments.find(it => it.id === assignment.assessmentId);\r\n if (!assessment) {\r\n return null;\r\n }\r\n\r\n // Skip any of the wrong type that we don't want in this list.\r\n if (options.assessmentType && assessment.assessmentType !== options.assessmentType) {\r\n return null;\r\n }\r\n\r\n // Get some details about what we can and can't do with this assessment.\r\n const { isEverFinished, isLatestFinished, canRetake } = getAssessmentSummary(assessment.id);\r\n\r\n // If we don't match the completion filter then skip it.\r\n if (!isUndefined(options?.includeIfEverFinishedIs) && isEverFinished !== options.includeIfEverFinishedIs) {\r\n return null;\r\n }\r\n\r\n if (!isUndefined(options?.includeIfLatestFinishedIs) && isLatestFinished !== options.includeIfLatestFinishedIs) {\r\n return null;\r\n }\r\n\r\n // Find the newest active session for the assessment.\r\n const latestSession = assessmentSessions.find(item => item.assessmentId === assignment.assessmentId);\r\n const latestFinishedSession = assessmentSessions.find(item => item.assessmentId === assignment.assessmentId && item.isFinished);\r\n\r\n return (\r\n \r\n );\r\n })\r\n }\r\n \r\n ), [userAssessmentAssignments, assessments, assessmentSessions, getAssessmentSummary]);\r\n\r\n // Generate the card components to show for the requested assessmentType,.\r\n const generateHistoryCards = useCallback(() => {\r\n // Create a list of the latest time we've done each assessment.\r\n let latestSessions: Array = [];\r\n for (const session of assessmentSessions) {\r\n // Only care about finished sessions.\r\n if (!session.isFinished) {\r\n continue;\r\n }\r\n\r\n // If this is the first time we've seen this assessment, add it to the list.\r\n const existing = latestSessions.find(it => it.assessmentId === session.assessmentId);\r\n if (!existing) {\r\n latestSessions.push(session);\r\n continue;\r\n }\r\n\r\n // If the new session finished after the old session, swap it in the list.\r\n if (existing.endDate < session.endDate) {\r\n latestSessions[latestSessions.indexOf(existing)] = session;\r\n }\r\n }\r\n\r\n // Order by the latest completion first.\r\n latestSessions.sort((a, b) => {\r\n if (a.endDate === b.endDate) {\r\n return 0;\r\n } else if (a.endDate < b.endDate) {\r\n return 1;\r\n } else {\r\n return -1;\r\n }\r\n });\r\n\r\n return (\r\n <>\r\n {\r\n latestSessions.map(session => {\r\n // Lookup the assessment model.\r\n const assessment = assessments.find(it => it.id === session.assessmentId);\r\n if (!assessment) {\r\n return null;\r\n }\r\n\r\n // Lookup the assignment model (there may not be one.).\r\n const assignment = userAssessmentAssignments.find(it => it.id === session.assessmentId);\r\n\r\n // Get some details about what we can and can't do with this assessment.\r\n const { canRetake } = getAssessmentSummary(assessment.id);\r\n\r\n return (\r\n \r\n );\r\n })\r\n }\r\n \r\n );\r\n }, [userAssessmentAssignments, assessments, assessmentSessions, getAssessmentSummary]);\r\n\r\n\r\n // Render the UI.\r\n return (\r\n \r\n \r\n

{t('common.fullName', '{{firstName}} {{lastName}}', { firstName: profile?.firstName, lastName: profile?.lastName })}

\r\n
\r\n \r\n \r\n\r\n
\r\n

\r\n {\r\n isStudyParticipant ? t('driverDashboard.study.heading', 'Studies')\r\n : t('driverDashboard.assessments.heading', 'Assessments')\r\n }\r\n

\r\n\r\n \r\n {\r\n generateCards({ assessmentType: AssessmentType.Assessment, includeIfLatestFinishedIs: false, })\r\n }\r\n \r\n\r\n \r\n \r\n \r\n {\r\n isStudyParticipant ? t('meDashboard.study.noResults', 'You don\\'t have any studies to complete right now.')\r\n : t('meDashboard.assessments.noResults', 'You don\\'t have any assessments to complete right now.')\r\n }\r\n \r\n \r\n \r\n
\r\n\r\n \r\n
\r\n

\r\n {t('driverDashboard.training.heading', 'Training')}\r\n

\r\n \r\n {\r\n generateCards({ assessmentType: AssessmentType.TrainingModule, includeIfLatestFinishedIs: false, })\r\n }\r\n \r\n\r\n \r\n \r\n \r\n {t('meDashboard.training.noResults', 'You don\\'t have any training to complete right now.')}\r\n \r\n \r\n \r\n
\r\n
\r\n\r\n
\r\n

\r\n {t('driverDashboard.history.heading', 'History')}\r\n

\r\n \r\n {\r\n generateHistoryCards()\r\n }\r\n\r\n \r\n \r\n {t('meDashboard.history.noResults', 'When you complete assessments and training we\\'ll keep a history of it here for you.')}\r\n \r\n \r\n \r\n
\r\n
\r\n
\r\n );\r\n};\r\n","import * as React from 'react';\r\nimport { useLazyQuery } from \"@apollo/react-hooks\";\r\nimport gql from \"graphql-tag\";\r\nimport { Guid } from \"guid-string\";\r\nimport { AsyncLoadResult, AsyncLoadOptions } from '../../../shared/abstractStore';\r\nimport { meDashboardViewModelQuery, meDashboardViewModelQueryVariables } from '../generated/meDashboardViewModelQuery';\r\nimport { mainApiConfig } from '../../../configure/mainApiConfig';\r\nimport { assessmentFieldsFragment } from '../models/Assessment';\r\nimport { userAssessmentAssignmentFieldsFragment } from '../models/UserAssessmentAssignment';\r\nimport { assessmentSessionFieldsFragment } from '../models/AssessmentSession';\r\nimport { profileFieldsFragment } from '../models/Profile';\r\nimport { subscriptionAssessmentFieldsFragment } from '../models/SubscriptionAssessment';\r\nimport { subscriptionFieldsFragment } from '../models/Subscription';\r\n\r\nexport interface MeDashboardViewModelOptions extends AsyncLoadOptions {\r\n isUserId?: boolean,\r\n}\r\n\r\n\r\n/**\r\n * Get a Profile from the store.\r\n * @param id\r\n * @param options\r\n */\r\nexport function useMeDashboardViewModel(id: string | undefined | null, options: MeDashboardViewModelOptions = {}): AsyncLoadResult {\r\n // Query the data we need form the api.\r\n const [load, { data, loading, error, refetch }] = useLazyQuery(\r\n gql`\r\n query meDashboardViewModelQuery ($profileId: ID, $userId: ID) {\r\n viewModel: meDashboardViewModel (profileId: $profileId, userId: $userId) {\r\n id\r\n assessments {\r\n ...assessmentFields\r\n }\r\n userAssessmentAssignments {\r\n ...userAssessmentAssignmentFields\r\n }\r\n assessmentSessions {\r\n ...assessmentSessionFields\r\n }\r\n subscriptionAssessments {\r\n ...subscriptionAssessmentFields\r\n }\r\n\r\n subscription {\r\n ...subscriptionFields\r\n }\r\n }\r\n\r\n profile (id: $profileId, userId: $userId) {\r\n ...profileFields\r\n }\r\n }\r\n\r\n ${assessmentFieldsFragment}\r\n ${userAssessmentAssignmentFieldsFragment}\r\n ${assessmentSessionFieldsFragment}\r\n ${profileFieldsFragment}\r\n ${subscriptionAssessmentFieldsFragment}\r\n ${subscriptionFieldsFragment}\r\n `,\r\n {\r\n variables: {\r\n profileId: !options.isUserId ? id ?? Guid.empty : null,\r\n userId: options.isUserId ? id ?? Guid.empty : null,\r\n },\r\n fetchPolicy: options.fetchPolicy ?? mainApiConfig.defaultFetchPolicy,\r\n pollInterval: options.pollInterval,\r\n onCompleted: (data) => {\r\n if (options.onCompleted) {\r\n options.onCompleted(data);\r\n }\r\n }\r\n }\r\n );\r\n\r\n // Run the query (unless we are being lazy).\r\n React.useEffect(() => {\r\n if (!options.lazy) {\r\n load();\r\n }\r\n }, [options.lazy, load])\r\n\r\n // Return the results.\r\n const refresh = React.useCallback(async () => { !refetch ? await load() : await refetch(); }, [refetch, load]);\r\n return React.useMemo(() => ({\r\n data: data ?? ({} as any),\r\n refresh: refresh,\r\n isLoading: loading,\r\n errors: error\r\n }), [data, refresh, loading, error]);\r\n}\r\n","import { RouteEntry } from \"../../shared/routes\";\r\nimport { MeDashboard } from \"./MeDashboard\";\r\n\r\nexport const meRoutes: Array = [\r\n { path: '/me', exact: true, component: MeDashboard, authorize: true, },\r\n { path: '/drivers/home/:profileId', exact: true, component: MeDashboard, authorize: true, },\r\n];\r\n","import * as React from 'react';\r\nimport { Button, Row, Col, ButtonGroup, ButtonDropdown, DropdownToggle, DropdownMenu, DropdownItem, CardTitle, CardSubtitle, FormText, Modal, ModalHeader, ModalBody } from 'reactstrap';\r\nimport { LinkContainer } from 'react-router-bootstrap';\r\nimport { AlertOnErrors } from '../../shared/alertOnErrors';\r\nimport { LoadingIndicator } from '../shared/LoadingIndicator';\r\nimport { Waypoint } from 'react-waypoint';\r\nimport { useReplaceSearchParamsEffect, useSearchParams } from '../../shared/useURLSearchParams';\r\nimport { useTranslation } from 'react-i18next';\r\nimport { SearchInput } from '../shared/searchInput/SearchInput';\r\nimport { FontAwesomeIcon } from '@fortawesome/react-fontawesome';\r\nimport { MainContainer } from '../shared/MainContainer';\r\nimport { NoResultsFound } from '../shared/NoResultsFound';\r\nimport { StickyToolbar } from '../shared/StickyToolbar';\r\nimport { useHistory } from 'react-router';\r\nimport { ConditionalFragment } from 'react-conditionalfragment';\r\nimport { Banner } from '../shared/Banner';\r\nimport { useToggleStateArray } from 'use-toggle-state';\r\nimport { Background } from '../shared/background/Background';\r\nimport { CardsOrTable } from '../shared/cardsOrTable/CardsOrTable';\r\nimport { usePreferredListViewMode } from '../../globalState/preferredListViewMode/usePreferredListViewMode';\r\nimport { PillsNavBar } from '../shared/pillsNavBar/PillsNavBar';\r\nimport { useUsersListViewBaseViewModel } from '../../api/main/profiles/viewModels/useUsersListViewBaseViewModel';\r\nimport { Guid } from 'guid-string';\r\nimport { FileUploadButton } from '../shared/fileUploadButton/FileUploadButton';\r\n\r\nexport interface UsersListBaseProps {\r\n title: string,\r\n filterByRoleGroups: Array,\r\n roleGroupColumnHidden?: boolean,\r\n baseRoute: string,\r\n subscriptionId?: string | undefined | null,\r\n subscriptionTeamId?: string | undefined | null,\r\n navigationPills?: React.ReactNode,\r\n teamColumnHidden?: boolean,\r\n allowImport?: boolean,\r\n}\r\n\r\n/**\r\n * List of administrator users.\r\n */\r\nexport const UsersListBase = (props: UsersListBaseProps) => {\r\n const {\r\n title,\r\n filterByRoleGroups,\r\n roleGroupColumnHidden,\r\n baseRoute,\r\n subscriptionId,\r\n subscriptionTeamId,\r\n navigationPills,\r\n teamColumnHidden,\r\n allowImport = true,\r\n } = props;\r\n\r\n const { t } = useTranslation();\r\n const { search: searchParam } = useSearchParams();\r\n const [search, setSearch] = React.useState(searchParam ?? '');\r\n const { data: { items: allItems, subscription, subscriptionTeam, subscriptionTeams }, isLoading, errors: loadingErrors, fetchMore, hasMore } = useUsersListViewBaseViewModel({ pageSize: undefined, subscriptionId: subscriptionId, subscriptionTeamId: subscriptionTeamId });\r\n const [isMenuOpen, toggleMenuOpen] = useToggleStateArray();\r\n const history = useHistory();\r\n\r\n // For showing info on max user counts\r\n const [subscriptionUserCount, setSubscriptionUserCount] = React.useState();\r\n const [maxUserCount, setMaxUserCount] = React.useState();\r\n\r\n // Filter by the user's search client side so it can work when offline as well as online.\r\n const items = React.useMemo(() => {\r\n let ret = (allItems ?? []);\r\n\r\n //For showing the user count for the current subscription\r\n setSubscriptionUserCount(subscription?.currentUsers);\r\n\r\n //For showing the current subscriptions user limit\r\n setMaxUserCount(subscription?.maxUsers);\r\n\r\n\r\n // Filter by the role groups allowed.\r\n ret = ret.filter(item => !!filterByRoleGroups.find(it => it === item.user?.roleGroup?.id));\r\n\r\n let lowerSearch = search.toLocaleLowerCase();\r\n\r\n // Filter the items being displayed.\r\n ret = ret.filter(item =>\r\n item.firstName.toLocaleLowerCase().indexOf(lowerSearch) >= 0\r\n || item.lastName.toLocaleLowerCase().indexOf(lowerSearch) >= 0\r\n || item.user.email.toLocaleLowerCase().indexOf(lowerSearch) >= 0\r\n || item.uniqueDriverPin.toLocaleLowerCase().indexOf(lowerSearch) >= 0\r\n || (item.user?.roleGroup?.name?.toLocaleLowerCase()?.indexOf(lowerSearch) ?? -1) >= 0\r\n || `${item.firstName} ${item.lastName}`.toLocaleLowerCase().indexOf(lowerSearch) >= 0 // Full name in languages \"first last\"\r\n || `${item.lastName} ${item.firstName}`.toLocaleLowerCase().indexOf(lowerSearch) >= 0 // Full name in languages \"last first\"\r\n );\r\n\r\n return ret;\r\n }, [allItems, search, filterByRoleGroups, subscription, setMaxUserCount, setSubscriptionUserCount]);\r\n\r\n useReplaceSearchParamsEffect({ search: search });\r\n\r\n const [viewMode, setViewMode] = usePreferredListViewMode();\r\n \r\n return (\r\n \r\n \r\n \r\n \r\n \r\n \r\n

\r\n {title}\r\n

\r\n \r\n \r\n \r\n {navigationPills}\r\n \r\n \r\n\r\n
\r\n
\r\n\r\n \r\n \r\n {\r\n // If we have navigation pills then the title is shown with that (above) so show the subscription name here.\r\n !!navigationPills ? (\r\n

\r\n {\r\n subscriptionTeam? subscriptionTeam.name\r\n : subscription ? subscription.companyName\r\n : ''\r\n }\r\n

\r\n ) : (\r\n

{title}

\r\n )\r\n }\r\n \r\n \r\n \r\n \r\n \r\n \r\n\r\n \r\n setSearch(e.currentTarget.value)} />\r\n \r\n \r\n \r\n \r\n\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n <> {t('usersListBase.export', 'Export users to Excel')} \r\n \r\n \r\n \r\n \r\n \r\n \r\n {t('usersListBase.maxUsers.help', `Current subscription users ${subscriptionUserCount} / ${maxUserCount ?? ''}` )}\r\n \r\n \r\n\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n
\r\n
\r\n
\r\n\r\n \r\n \r\n view === 'cards' ? ({item.firstName + \" \" + item.lastName}) : null,\r\n (item, view) => view === 'cards' ? null : item.firstName,\r\n (item, view) => view === 'cards' ? null : item.lastName,\r\n (item, view) =>\r\n view === 'cards' ? ({!!item.uniqueDriverPin ? `PIN: ${item.uniqueDriverPin}` : item.user?.email ?? ''})\r\n : !!item.uniqueDriverPin ? `PIN: ${item.uniqueDriverPin}` : item.user?.email ?? '',\r\n (item) => roleGroupColumnHidden ? null : item.user?.roleGroup?.name,\r\n (item) => {\r\n if (teamColumnHidden) {\r\n return null;\r\n }\r\n\r\n var myTeam = subscriptionTeams.find(it => it.id === item.subscriptionTeamId);\r\n\r\n if (Guid.isEmpty(item.subscriptionTeamId)) {\r\n return t(\"(No team)\");\r\n }\r\n\r\n\r\n return myTeam?.name;\r\n },\r\n\r\n ]}\r\n buttons={(item) => (\r\n \r\n \r\n \r\n \r\n toggleMenuOpen(item.id)}>\r\n \r\n {t('common.menuDropdown', 'More')}\r\n \r\n \r\n \r\n \r\n \r\n <> {t('common.delete', 'Delete')}\r\n \r\n \r\n \r\n \r\n \r\n )}\r\n onItemClick={item => history.push(`${baseRoute}/edit/${item.id}`)}\r\n />\r\n \r\n \r\n \r\n \r\n\r\n \r\n\r\n \r\n \r\n\r\n \r\n \r\n\r\n \r\n \r\n
\r\n );\r\n};\r\n","import * as React from 'react';\r\nimport { useLazyQuery } from \"@apollo/react-hooks\";\r\nimport gql from \"graphql-tag\";\r\nimport { AsyncLoadResult, AsyncLoadOptions } from '../../../shared/abstractStore';\r\nimport { profileSupportingDataQuery } from '../generated/profileSupportingDataQuery';\r\nimport { mainApiConfig } from '../../../configure/mainApiConfig';\r\nimport { subscriptionTeamFieldsFragment } from '../models/SubscriptionTeam';\r\nimport { subscriptionFieldsFragment } from '../models/Subscription';\r\nimport { Guid } from 'guid-string';\r\n\r\nexport interface ProfileSupportingDataOptions extends AsyncLoadOptions {\r\n subscriptionId?: string,\r\n}\r\n\r\n/**\r\n * Get a the supporting data needed to interactivly edit an Profile.\r\n * @param id\r\n * @param options\r\n */\r\nexport function useProfileSupportingData(options: ProfileSupportingDataOptions = {}): AsyncLoadResult {\r\n // Query the data we need form the api.\r\n const [load, { data, loading, error, refetch }] = useLazyQuery(\r\n gql`\r\n query profileSupportingDataQuery ($subscriptionIdOrEmptyGuid: ID!) {\r\n roleGroups {\r\n id\r\n name\r\n }\r\n\r\n subscription(id: $subscriptionIdOrEmptyGuid) {\r\n ...subscriptionFields\r\n }\r\n\r\n subscriptionTeams (subscriptionId: $subscriptionIdOrEmptyGuid) {\r\n ...subscriptionTeamFields\r\n }\r\n }\r\n ${subscriptionFieldsFragment}\r\n ${subscriptionTeamFieldsFragment}\r\n `,\r\n {\r\n variables: {\r\n subscriptionIdOrEmptyGuid: options.subscriptionId ?? Guid.empty,\r\n },\r\n fetchPolicy: options.fetchPolicy ?? mainApiConfig.defaultFetchPolicy,\r\n pollInterval: options.pollInterval,\r\n onCompleted: (data) => {\r\n if (options.onCompleted) {\r\n options.onCompleted(data);\r\n }\r\n }\r\n }\r\n );\r\n\r\n // Run the query (unless we are being lazy).\r\n React.useEffect(() => {\r\n if (!options.lazy) {\r\n load();\r\n }\r\n }, [options.lazy, load])\r\n\r\n // Return the results.\r\n const refresh = React.useCallback(async () => { !refetch ? await load() : await refetch(); }, [refetch, load]);\r\n return React.useMemo(() => ({\r\n data: data ?? ({} as any),\r\n refresh: refresh,\r\n isLoading: loading,\r\n errors: error\r\n }), [data, refresh, loading, error]);\r\n}\r\n","import * as React from 'react';\r\nimport { Button, Form, Label, FormGroup, Spinner, Input, Row, Col } from 'reactstrap';\r\nimport { AlertOnErrors } from '../../shared/alertOnErrors';\r\nimport { LoadingIndicator } from '../shared/LoadingIndicator';\r\nimport { useTranslation } from 'react-i18next';\r\nimport { FontAwesomeIcon } from '@fortawesome/react-fontawesome';\r\nimport { MainContainer } from '../shared/MainContainer';\r\nimport { useParams, useHistory } from 'react-router';\r\nimport { FormButtons } from '../shared/FormButtons';\r\nimport { ButtonAsync } from 'reactstrap-buttonasync';\r\nimport { useAsyncCallback } from 'react-use-async-callback';\r\nimport { useProfile } from '../../api/main/profiles/useProfile';\r\nimport { useLockoutCallback } from '../../api/account';\r\nimport { useDeleteProfileCallback } from '../../api/main/profiles/useDeleteProfileCallback';\r\nimport { ConditionalFragment } from 'react-conditionalfragment';\r\nimport { Banner } from '../shared/Banner';\r\nimport { Background } from '../shared/background/Background';\r\nimport { useSaveSubscriptionCallback } from '../../api/main/subscriptions/useSaveSubscriptionCallback';\r\nimport { useProfileSupportingData } from '../../api/main/profiles/useProfileSupportingData';\r\n\r\nexport interface DeleteUserBaseProps {\r\n defaultRoleGroup: string,\r\n}\r\n\r\n\r\n/**\r\n * Delete a user (profile) by locking them out permanently.\r\n */\r\nexport const DeleteUserBase = (props: DeleteUserBaseProps) => {\r\n const { defaultRoleGroup } = props;\r\n\r\n const { t } = useTranslation();\r\n const { id } = useParams<{ id: string }>();\r\n const { data: { model }, isLoading, errors: loadErrors } = useProfile(id);\r\n const [remove, { errors: removeErrors }] = useDeleteProfileCallback();\r\n const [lockout, { errors: lockoutErrors }] = useLockoutCallback();\r\n const history = useHistory();\r\n\r\n // Used for updating subscription current users\r\n const [save] = useSaveSubscriptionCallback();\r\n const { data: { subscription } } = useProfileSupportingData({ subscriptionId: model?.subscriptionId ?? undefined});\r\n\r\n const [onRemoveFormSubmit, { isExecuting: isRemoving, errors: removeFormErrors }] = useAsyncCallback(async () => {\r\n if (!model || !model.user) {\r\n return;\r\n }\r\n\r\n if (subscription) {\r\n await save(subscription?.id, { currentUsers: subscription?.currentUsers - 1 }, false);\r\n }\r\n\r\n await remove(model.id);\r\n await lockout({ email: model.user.email, archive: true, });\r\n\r\n history.goBack();\r\n }, [lockout, model, history, subscription]);\r\n\r\n const isDriver = React.useMemo(() => (model?.user?.roleGroup?.id ?? defaultRoleGroup) === 'Driver', [model, defaultRoleGroup]);\r\n\r\n return (\r\n \r\n \r\n \r\n \r\n

{\r\n isDriver ? t('deleteUserBase.heading.driver', 'Are you sure you want to delete this driver?')\r\n : t('deleteUserBase.heading.default', 'Are you sure you want to delete this user?')\r\n }

\r\n \r\n \r\n \r\n \r\n \r\n \r\n
\r\n
\r\n\r\n \r\n \r\n\r\n
{ e.preventDefault(); onRemoveFormSubmit(); }}>\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n\r\n \r\n \r\n {t('common.deleting', 'Deleting...')}}>\r\n \r\n <> {t('common.delete', 'Delete')}\r\n \r\n \r\n \r\n \r\n
\r\n
\r\n
\r\n );\r\n};\r\n","import { useMutation } from \"@apollo/react-hooks\";\r\nimport { useAsyncCallback } from 'react-use-async-callback';\r\nimport gql from \"graphql-tag\";\r\nimport { AsyncActionStatus } from '../../../shared/abstractStore';\r\nimport { ChangeUserRoleGroupInput } from '../generated/globalTypes';\r\nimport { userFieldsFragment } from \"../models/User\";\r\nimport { changeUserRoleGroupMutationVariables, changeUserRoleGroupMutation } from \"../generated/changeUserRoleGroupMutation\";\r\nimport { useResetCurrentUserRolesCallback } from \"../../account\";\r\n\r\n/**\r\n * Get a callback to change the role grup of a user in the store.\r\n */\r\nexport function useChangeUserRoleGroupCallback(): [(model: ChangeUserRoleGroupInput) => Promise, AsyncActionStatus] {\r\n const resetCurrentUserRoles = useResetCurrentUserRolesCallback();\r\n\r\n const [mutationAction, { error }] = useMutation(\r\n gql`\r\n mutation changeUserRoleGroupMutation ($model: ChangeUserRoleGroupInput!) {\r\n changeUserRoleGroup(model: $model) {\r\n ...userFields\r\n }\r\n }\r\n\r\n ${userFieldsFragment}\r\n `,\r\n {\r\n update: () => resetCurrentUserRoles()\r\n }\r\n );\r\n\r\n // Wrap the mutation in a standard callback.\r\n const [action, { isExecuting, errors: actionErrors }] = useAsyncCallback(async (model: ChangeUserRoleGroupInput) => {\r\n const result = await mutationAction({ variables: { model: model } });\r\n if (result.errors && result.errors.length) {\r\n throw result.errors;\r\n }\r\n }, [mutationAction]);\r\n\r\n return [action, { isExecuting: isExecuting, errors: error ? error.message : actionErrors }];\r\n}\r\n","import { MouseEventHandler, useCallback } from \"react\";\r\nimport { useTranslation } from \"react-i18next\";\r\nimport { NavItem, NavLink } from \"reactstrap\";\r\nimport { NavLinkTrackActive } from \"../../shared/NavLinkTrackActive\";\r\nimport { FontAwesomeIcon } from '@fortawesome/react-fontawesome';\r\n\r\nexport interface DriverNavigationProps {\r\n id: string,\r\n onNavigate?: (link: string) => void,\r\n editLink?: string,\r\n}\r\n\r\n/**\r\n * Navigation under editing of a driver.\r\n */\r\nexport const DriverNavigation = (props: DriverNavigationProps) => {\r\n const { id, onNavigate, editLink } = props;\r\n const { t } = useTranslation();\r\n\r\n // If we have an onNavigate event, we should call that instead of leting the links handle themselves.\r\n const onNavLinkClick = useCallback((e) => {\r\n if (onNavigate) {\r\n e.preventDefault();\r\n const link = e.currentTarget.getAttribute(\"href\") ?? '';\r\n onNavigate(link);\r\n }\r\n }, [onNavigate]);\r\n\r\n return (\r\n <>\r\n \r\n \r\n \r\n {t('driverNavigation.driver', ' Driver')}\r\n \r\n \r\n \r\n \r\n \r\n {t('driverNavigation.assessments', ' Assessments')}\r\n \r\n \r\n \r\n \r\n \r\n {t('driverNavigation.training', ' Training modules')}\r\n \r\n \r\n \r\n );\r\n};\r\n","import { MouseEventHandler, useCallback } from \"react\";\r\nimport { useTranslation } from \"react-i18next\";\r\nimport { NavItem, NavLink } from \"reactstrap\";\r\nimport { NavLinkTrackActive } from \"../../shared/NavLinkTrackActive\";\r\nimport { FontAwesomeIcon } from '@fortawesome/react-fontawesome';\r\n\r\nexport interface ManagerNavigationProps {\r\n id: string,\r\n onNavigate?: (link: string) => void,\r\n editLink?: string,\r\n}\r\n\r\n/**\r\n * Navigation under editing of a manager.\r\n */\r\nexport const ManagerNavigation = (props: ManagerNavigationProps) => {\r\n const { id, onNavigate, editLink } = props;\r\n const { t } = useTranslation();\r\n\r\n // If we have an onNavigate event, we should call that instead of leting the links handle themselves.\r\n const onNavLinkClick = useCallback((e) => {\r\n if (onNavigate) {\r\n e.preventDefault();\r\n const link = e.currentTarget.getAttribute(\"href\") ?? '';\r\n onNavigate(link);\r\n }\r\n }, [onNavigate]);\r\n\r\n return (\r\n <>\r\n \r\n \r\n \r\n {t('managerNavigation.manager', ' Manager')}\r\n \r\n \r\n \r\n \r\n \r\n {t('managerNavigation.assessments', ' Assessments')}\r\n \r\n \r\n \r\n \r\n \r\n {t('managerNavigation.training', ' Training modules')}\r\n \r\n \r\n \r\n );\r\n};\r\n","import { MouseEventHandler, useCallback } from \"react\";\r\nimport { useTranslation } from \"react-i18next\";\r\nimport { NavItem, NavLink } from \"reactstrap\";\r\nimport { NavLinkTrackActive } from \"../../shared/NavLinkTrackActive\";\r\nimport { FontAwesomeIcon } from '@fortawesome/react-fontawesome';\r\n\r\nexport interface AdministratorNavigationProps {\r\n id: string,\r\n onNavigate?: (link: string) => void,\r\n editLink?: string,\r\n}\r\n\r\n/**\r\n * Navigation under editing of a Administrator.\r\n */\r\nexport const AdministratorNavigation = (props: AdministratorNavigationProps) => {\r\n const { id, onNavigate, editLink } = props;\r\n const { t } = useTranslation();\r\n\r\n // If we have an onNavigate event, we should call that instead of leting the links handle themselves.\r\n const onNavLinkClick = useCallback((e) => {\r\n if (onNavigate) {\r\n e.preventDefault();\r\n const link = e.currentTarget.getAttribute(\"href\") ?? '';\r\n onNavigate(link);\r\n }\r\n }, [onNavigate]);\r\n\r\n return (\r\n <>\r\n \r\n \r\n \r\n {t('administratorNavigation.administrator', ' Esitu staff')}\r\n \r\n \r\n \r\n \r\n \r\n {t('administratorNavigation.assessments', ' Assessments')}\r\n \r\n \r\n \r\n \r\n \r\n {t('administratorNavigation.training', ' Training modules')}\r\n \r\n \r\n \r\n );\r\n};\r\n","import * as React from 'react';\r\nimport { Button, Row, Col, Form, Label, FormGroup, Spinner, FormText, Alert, Input } from 'reactstrap';\r\nimport { AlertOnErrors } from '../../shared/alertOnErrors';\r\nimport { LoadingIndicator } from '../shared/LoadingIndicator';\r\nimport { useTranslation } from 'react-i18next';\r\nimport { FontAwesomeIcon } from '@fortawesome/react-fontawesome';\r\nimport { MainContainer } from '../shared/MainContainer';\r\nimport { useParams, useHistory } from 'react-router';\r\nimport { useProfile } from '../../api/main/profiles/useProfile';\r\nimport { useChanges, useChangesArray } from '../../shared/useChanges';\r\nimport { useSaveProfileCallback } from '../../api/main/profiles/useSaveProfileCallback';\r\nimport { useValidatorCallback } from 'pojo-validator-react';\r\nimport { ValidatedInput } from 'pojo-validator-reactstrap';\r\nimport { FormButtons } from '../shared/FormButtons';\r\nimport { ButtonAsync } from 'reactstrap-buttonasync';\r\nimport { useInviteCallback, useChangeAccountEmailCallback, useResendInviteEmailCallback } from '../../api/account';\r\nimport { useAsyncCallback } from 'react-use-async-callback';\r\nimport { useChangeUserRoleGroupCallback } from '../../api/main/users/useChangeUserRoleGroupCallback';\r\nimport { ConditionalFragment } from 'react-conditionalfragment';\r\nimport { useProfileSupportingData } from '../../api/main/profiles/useProfileSupportingData';\r\nimport { Banner } from '../shared/Banner';\r\nimport { Background } from '../shared/background/Background';\r\nimport { Profile, profileDefaultValues } from '../../api/main/models/Profile';\r\nimport { SubscriptionTeam } from '../../api/main/models/SubscriptionTeam';\r\nimport { TwoValueSwitch } from '../shared/TwoValueSwitch';\r\nimport { useGenerateUniqueDriverPinCallback } from '../../api/main/profiles/useGenerateUniqueDriverPinCallback';\r\nimport { DriverPinService } from '../../services/DriverPinService';\r\nimport { PillsNavBar } from '../shared/pillsNavBar/PillsNavBar';\r\nimport { DriverNavigation } from './drivers/DriverNavigation';\r\nimport { ManagerNavigation } from './managers/ManagerNavigation';\r\nimport { AdministratorNavigation } from './administrators/AdministratorNavigation';\r\nimport { useSaveSubscriptionCallback } from '../../api/main/subscriptions/useSaveSubscriptionCallback';\r\n\r\nexport interface EditUserBaseProps {\r\n isCreate?: boolean,\r\n onCreateDefaultValues?: () => Partial,\r\n defaultRoleGroup: string,\r\n filterRoleGroups?: (groups: Array<{ id: string, name: string }>) => Array<{ id: string, name: string }>,\r\n}\r\n\r\n\r\n/**\r\n * Create and invite a new user.\r\n */\r\nexport const CreateUserBase = (props: EditUserBaseProps) => ();\r\n\r\n/**\r\n * Edit a user (actually a profile).\r\n */\r\nexport const EditUserBase = (props: EditUserBaseProps) => {\r\n const {\r\n isCreate,\r\n onCreateDefaultValues,\r\n defaultRoleGroup,\r\n filterRoleGroups,\r\n } = props;\r\n\r\n const { t } = useTranslation();\r\n const { id } = useParams<{ id: string | undefined }>();\r\n const { data: { model: storeModel }, isLoading: _isLoading, errors: loadErrors } = useProfile(id);\r\n const { model, change, changes } = useChanges(storeModel, isCreate ? { ...profileDefaultValues(), ...(onCreateDefaultValues ? onCreateDefaultValues() : {}) } : undefined);\r\n const { model: userModel, change: changeUserModel } = useChanges(storeModel?.user);\r\n const { model: roleGroupModel, change: changeRoleGroupModel } = useChanges<{ id: string }>({ id: storeModel?.user?.roleGroup?.id ?? '' }, isCreate ? { id: defaultRoleGroup }: undefined);\r\n const [save, { errors: saveErrors }] = useSaveProfileCallback();\r\n const [invite, { errors: inviteErrors }] = useInviteCallback();\r\n const [resendInviteEmail, { isExecuting: isResendingInviteEmail, errors: resendInviteEmailErrors }] = useResendInviteEmailCallback();\r\n const [hasResentInviteEmail, setHasResentInviteEmail] = React.useState(false);\r\n const [changeAccountEmail, { errors: changeEmailErrors }] = useChangeAccountEmailCallback();\r\n const [changeUserRoleGroupInStore, { errors: changeUserRoleGroupInStoreErrors }] = useChangeUserRoleGroupCallback();\r\n const history = useHistory();\r\n const [willExceedMaxUsers, setWillExceedMaxUsers] = React.useState(false);\r\n\r\n // Supporting data (dependant on the current user's subscription).\r\n const { data: { roleGroups: storeRoleGroups, subscriptionTeams: storeSubscriptionTeams, subscription }, isLoading: isLoadingSupportingData, errors: loadSupportingDataErrors } = useProfileSupportingData({ subscriptionId: model?.subscriptionId ?? undefined });\r\n const isLoading = _isLoading || isLoadingSupportingData;\r\n\r\n // Used for updating subscription current users\r\n const [saveSubscription] = useSaveSubscriptionCallback();\r\n\r\n // Teams\r\n const subscriptionTeamsManager = useChangesArray(storeSubscriptionTeams, item => item.id);\r\n const orderedSubscriptionTeams = React.useMemo(() => {\r\n let ret = [...subscriptionTeamsManager.model];\r\n ret.sort((a, b) => {\r\n if (a.name === b.name) {\r\n return 0;\r\n } else if (a.name > b.name) {\r\n return 1;\r\n } else {\r\n return -1;\r\n }\r\n });\r\n return ret;\r\n }, [subscriptionTeamsManager]);\r\n const roleGroups = React.useMemo(() => {\r\n if (!filterRoleGroups) {\r\n return storeRoleGroups;\r\n }\r\n\r\n return filterRoleGroups(storeRoleGroups ?? []);\r\n }, [storeRoleGroups, filterRoleGroups]);\r\n\r\n\r\n // Unique PINS as an alternative to traditional username and password logins.\r\n const isUsingUniqueDriverPin = !!model?.uniqueDriverPin;\r\n const [generateUniqueDriverPin, { isExecuting: isGeneratingUniqueDriverPin, errors: generateUniqueDriverPinErrors }] = useGenerateUniqueDriverPinCallback();\r\n const [regeneratePin] = useAsyncCallback(async () => {\r\n const newPin = await generateUniqueDriverPin();\r\n change({ uniqueDriverPin: newPin });\r\n const driverPinService = new DriverPinService();\r\n const newEmail = driverPinService.emailFromPin(newPin);\r\n changeUserModel({ email: newEmail });\r\n }, [generateUniqueDriverPin, change, changeUserModel]);\r\n\r\n\r\n const [validate, validationErrors] = useValidatorCallback((validation, fieldsToCheck) => {\r\n const rules = {\r\n firstName: () => !model?.firstName ? t('editUserBase.firstNameRequired', 'First name is required') : '',\r\n lastName: () => !model?.lastName ? t('editUserBase.lastNameRequired', 'Last name is required') : '',\r\n email: () => !userModel?.email ? t('editUserBase.emailRequired', 'Email is required') : '',\r\n };\r\n\r\n validation.checkRules(rules, fieldsToCheck);\r\n }, [model, userModel]);\r\n\r\n const [saveForm, { isExecuting: isSaving, errors: saveFormErrors }] = useAsyncCallback(async (options?: { navigateTo?: string, }) => {\r\n if (!validate()) {\r\n return;\r\n }\r\n\r\n if (subscription && isCreate) {\r\n\r\n if (subscription.maxUsers === 0 || subscription.restrictMaxUsers === false) {\r\n\r\n setWillExceedMaxUsers(false);\r\n\r\n }\r\n else if (subscription.currentUsers + 1 > subscription.maxUsers && subscription.restrictMaxUsers === true) {\r\n\r\n setWillExceedMaxUsers(true);\r\n return;\r\n\r\n }\r\n\r\n\r\n }\r\n\r\n // If we are creating this user, make sure we save the user and get its id before continuing with saving the profile.\r\n let userId = model.userId;\r\n if (isCreate) {\r\n // Create an invited user but don't send the invite yet, we'll send it after the profile has been saved to so we can include their name\r\n // and make it more personal for higher engagement.\r\n const result = await invite({ ...userModel, sendEmail: false });\r\n userId = result.userId;\r\n changeUserModel({ id: userId });\r\n change({ userId: userId });\r\n\r\n if (subscription && result) {\r\n\r\n //update the subscriptions current user count\r\n await saveSubscription(subscription.id, { currentUsers: subscription.currentUsers + 1 }, false);\r\n\r\n }\r\n }\r\n\r\n await save(model.id, { ...changes, userId: userId }, !!isCreate);\r\n\r\n // If we created a user invite, send the email now the profile has been saved so it can include more personal information (e.g. their name).\r\n if (isCreate) {\r\n await resendInviteEmail(userModel.email);\r\n }\r\n\r\n // Handle changes to the email address of existing users.\r\n if (!isCreate && storeModel && storeModel.user.email !== userModel.email) {\r\n await changeAccountEmail(storeModel.user.email, userModel.email);\r\n }\r\n\r\n // Handle the role group change.\r\n if (isCreate || storeModel?.user.roleGroup?.id !== roleGroupModel.id) {\r\n await changeUserRoleGroupInStore({ userId: userId, roleGroupId: roleGroupModel.id });\r\n }\r\n\r\n // Navigate to the next screen.\r\n if (options?.navigateTo) {\r\n history.push(options.navigateTo);\r\n } else {\r\n history.goBack();\r\n }\r\n }, [validate, save, model, changes, isCreate, history, userModel, invite, changeUserModel, change, changeAccountEmail, resendInviteEmail, setWillExceedMaxUsers, subscription, saveSubscription ]);\r\n\r\n const isDriver = React.useMemo(() => (roleGroupModel?.id ?? defaultRoleGroup) === 'Driver', [roleGroupModel, defaultRoleGroup]);\r\n const isManager = React.useMemo(() => (roleGroupModel.id ?? defaultRoleGroup) === 'Driver manager' || (roleGroupModel.id ?? defaultRoleGroup) === 'Overview manager', [roleGroupModel, defaultRoleGroup]);\r\n const isDistributorAdministrator = React.useMemo(() => (roleGroupModel.id ?? defaultRoleGroup) === 'Distributor administrator', [roleGroupModel, defaultRoleGroup]);\r\n const isAdministrator = !isDriver && !isManager && !isDistributorAdministrator;\r\n\r\n\r\n return (\r\n \r\n \r\n \r\n \r\n

\r\n {\r\n isCreate ? (\r\n <>{\r\n isDriver ? t('editUserBase.createHeading.driver', 'Add driver')\r\n : isManager ? t('editUserBase.createHeading.manager', 'Add manager')\r\n : isDistributorAdministrator ? t('editUserBase.createHeading.distributorAdministrator', 'Add distributor administator')\r\n : t('editUserBase.createHeading.default', 'Add user')\r\n }\r\n ) : (\r\n <>{\r\n isDriver ? t('editUserBase.editHeading.driver', 'Add driver')\r\n : isManager ? t('editUserBase.editHeading.manager', 'Edit manager')\r\n : isDistributorAdministrator ? t('editUserBase.editHeading.distributorAdministrator', 'Edit distributor administrator')\r\n : t('editUserBase.editHeading.default', 'Edit user')\r\n }\r\n )\r\n }\r\n

\r\n \r\n \r\n \r\n \r\n saveForm({ navigateTo: link })}\r\n />\r\n \r\n \r\n saveForm({ navigateTo: link })}\r\n />\r\n \r\n \r\n saveForm({ navigateTo: link })}\r\n />\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n
\r\n
\r\n\r\n \r\n \r\n\r\n {\r\n hasResentInviteEmail ? (\r\n \r\n <>{t('editUserBase.confirmationEmailHasBeenResent', 'Invite email for this user has been resent. Please ask the user to check their email to confirm.')} \r\n { e.preventDefault(); await resendInviteEmail(storeModel?.user?.email ?? userModel.email); }}\r\n isExecuting={isResendingInviteEmail}\r\n executingChildren={<>{t('common.sending', 'Sending...')}}>\r\n {t('common.resendEmail', 'Resend email')}\r\n \r\n \r\n ) : null\r\n }\r\n {\r\n willExceedMaxUsers ? (\r\n \r\n <>{t('editUserBase.maxUsersReached', 'Cannot create a new user. Maximum amount of users for this subscription has been reached.')} \r\n \r\n ) : null\r\n }\r\n\r\n
{ e.preventDefault(); saveForm(); }}>\r\n \r\n \r\n \r\n \r\n change({ firstName: e.currentTarget.value })} onBlur={e => validate('firstName')} validationErrors={validationErrors['firstName']} />\r\n \r\n \r\n \r\n \r\n \r\n change({ lastName: e.currentTarget.value })} onBlur={e => validate('lastName')} validationErrors={validationErrors['lastName']} />\r\n \r\n \r\n \r\n\r\n \r\n \r\n \r\n {\r\n if (checked) {\r\n regeneratePin();\r\n } else {\r\n change({ uniqueDriverPin: '' });\r\n changeUserModel({ email: storeModel?.user?.email ?? '' });\r\n }\r\n }}\r\n />\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n regeneratePin()}\r\n isExecuting={isGeneratingUniqueDriverPin}\r\n executingChildren={<>{t('common.generatingPin', 'Generating unique PIN...')}}>\r\n \r\n <> \r\n {t('editUserBase.regeneratePin', 'Generate new PIN')}\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n changeUserModel({ email: e.currentTarget.value })} onBlur={e => validate('email')} validationErrors={validationErrors['email']} />\r\n \r\n {\r\n storeModel && !storeModel.user.emailConfirmed && userModel.email === storeModel.user.email ? (\r\n \r\n { e.preventDefault(); await resendInviteEmail(userModel.email); setHasResentInviteEmail(true); }}\r\n isExecuting={isResendingInviteEmail}\r\n executingChildren={<>{t('editUserBase.resendingInvite', 'Resending invite...')}}>\r\n \r\n <> {t('editUserBase.resendInvite', 'Resend invite')}\r\n \r\n \r\n ) : null\r\n }\r\n \r\n {\r\n storeModel && !storeModel.user.emailConfirmed && userModel.email === storeModel.user.email ? (\r\n \r\n {t('editUserBase.userHasNotAcceptedInvite', 'This user has not accepted the invite. You can change their email if required or resend the invite.')}\r\n \r\n ) : storeModel && !storeModel.user.emailConfirmed && userModel.email !== storeModel.user.email ? (\r\n \r\n {t('editUserBase.userHasNotAcceptedInviteAndEmailChanged', 'This user has not yet accepted the invite, a new invite will be sent to the new email you have supplied.')}\r\n \r\n ) : storeModel && storeModel.user.emailConfirmed && userModel.email !== storeModel.user.email ? (\r\n \r\n {t('editUserBase.userHasAcceptedInviteAndEmailChanged', 'This user will be asked to confirm the email change before it takes affect. The old email address will be shown in the system until the change has been confirmed.')}\r\n \r\n ) : storeModel && storeModel.user.emailConfirmed && userModel.email === storeModel.user.email ? (\r\n \r\n {t('editUserBase.userHasAcceptedInviteAndEmailNotChanged', 'If you change this user\\'s email they will be sent an email to confirm the change before it takes affect.')}\r\n \r\n ) : null\r\n }\r\n \r\n \r\n\r\n \r\n \r\n \r\n change({ subscriptionTeamId: e.currentTarget.value || null })} onBlur={e => validate('subscriptionTeamId')} validationErrors={validationErrors['subscriptionTeamId']}>\r\n \r\n \r\n {\r\n orderedSubscriptionTeams.map(item => (\r\n \r\n ))\r\n }\r\n \r\n \r\n \r\n\r\n 1}>\r\n \r\n \r\n changeRoleGroupModel({ id: e.currentTarget.value })} onBlur={e => validate('roleGroup')} validationErrors={validationErrors['roleGroup']}>\r\n {\r\n roleGroups?.map(item => (\r\n \r\n ))\r\n }\r\n \r\n \r\n \r\n\r\n \r\n \r\n {t('common.saving', 'Saving...')}}>\r\n \r\n <> {t('common.save', 'Save')}\r\n \r\n \r\n \r\n \r\n
\r\n
\r\n
\r\n );\r\n};\r\n","import { AsyncActionStatus } from \"../../shared/abstractStore\";\r\nimport { useAsyncCallback } from \"react-use-async-callback\";\r\nimport { InviteRequest, InviteResult } from \"./AccountService\";\r\nimport { useAccountService } from \"./useAccountService\";\r\n\r\n/**\r\n * Callback to Invite an account to register.\r\n */\r\nexport function useInviteCallback(): [(model: InviteRequest) => Promise, AsyncActionStatus] {\r\n const accountService = useAccountService();\r\n\r\n const [action, { isExecuting, errors }] = useAsyncCallback(async (model: InviteRequest) => {\r\n let result = await accountService.invite(model);\r\n return result;\r\n }, [accountService]);\r\n\r\n return [action, { isExecuting, errors }];\r\n}\r\n","import { AsyncActionStatus } from \"../../shared/abstractStore\";\r\nimport { useAsyncCallback } from \"react-use-async-callback\";\r\nimport { useAccountService } from \"./useAccountService\";\r\n\r\n/**\r\n * Callback to resend the inviten email.\r\n */\r\nexport function useResendInviteEmailCallback(): [(email: string) => Promise, AsyncActionStatus] {\r\n const accountService = useAccountService();\r\n\r\n const [action, { isExecuting, errors }] = useAsyncCallback(async (email: string) => {\r\n return await accountService.resendInviteEmail(email);\r\n }, [accountService]);\r\n\r\n return [action, { isExecuting, errors }];\r\n}\r\n","import { AsyncActionStatus } from \"../../shared/abstractStore\";\r\nimport { useAsyncCallback } from \"react-use-async-callback\";\r\nimport { useAccountService } from \"./useAccountService\";\r\n\r\n/**\r\n * Callback to change the email of another user as an administrator.\r\n */\r\nexport function useChangeAccountEmailCallback(): [(currentEmail: string, newEmail: string) => Promise, AsyncActionStatus] {\r\n const accountService = useAccountService();\r\n\r\n const [action, { isExecuting, errors }] = useAsyncCallback(async (currentEmail: string, newEmail: string) => {\r\n return await accountService.changeAccountEmail({ currentEmail: currentEmail, newEmail: newEmail });\r\n }, [accountService]);\r\n\r\n return [action, { isExecuting, errors }];\r\n}\r\n","import { useMutation } from \"@apollo/react-hooks\";\r\nimport { useAsyncCallback } from 'react-use-async-callback';\r\nimport gql from \"graphql-tag\";\r\nimport { AsyncActionStatus } from '../../../shared/abstractStore';\r\nimport { generateUniqueDriverPinMutation } from '../generated/generateUniqueDriverPinMutation';\r\n//import { generateUniqueDriverPinMutation } from '../generated/generateUniqueDriverPinMutation';\r\n\r\n/**\r\n * Get a callback to generate a unique driver pin that can be used to log in a user.\r\n */\r\nexport function useGenerateUniqueDriverPinCallback(): [() => Promise, AsyncActionStatus] {\r\n const [mutationAction, { error }] = useMutation(\r\n gql`\r\n mutation generateUniqueDriverPinMutation {\r\n generateUniqueDriverPin\r\n }\r\n `\r\n );\r\n\r\n // Wrap the mutation in a standard callback.\r\n const [action, { isExecuting, errors: actionErrors }] = useAsyncCallback(async () => {\r\n const result = await mutationAction({});\r\n if (result.errors && result.errors.length) {\r\n throw result.errors;\r\n }\r\n return result.data?.generateUniqueDriverPin ?? '';\r\n }, [mutationAction]);\r\n\r\n return [action, { isExecuting: isExecuting, errors: error ? error.message : actionErrors }];\r\n}\r\n","import { IdentityRoles } from \"../../../configure/security/IdentityRoles\";\r\nimport { RouteEntry } from \"../../../shared/routes\";\r\nimport { AdministratorsList } from \"./AdministratorsList\";\r\nimport { DeleteAdministrator } from \"./DeleteAdministrator\";\r\nimport { CreateAdministrator, EditAdministrator } from \"./EditAdministrator\";\r\n\r\n\r\nexport const administratorsRoutes: Array = [\r\n { path: '/administration/administrators', exact: true, component: AdministratorsList, authorize: true, requireRole: IdentityRoles.Administration },\r\n { path: '/administration/administrators/edit/:id', component: EditAdministrator, authorize: true, requireRole: IdentityRoles.Administration },\r\n { path: '/administration/administrators/add', component: CreateAdministrator, authorize: true, requireRole: IdentityRoles.Administration },\r\n { path: '/administration/administrators/delete/:id', component: DeleteAdministrator, authorize: true, requireRole: IdentityRoles.Administration },\r\n];\r\n","import { useTranslation } from \"react-i18next\";\r\nimport { UsersListBase } from \"../UsersListBase\";\r\n\r\n/**\r\n * List of administrators.\r\n */\r\nexport const AdministratorsList = () => {\r\n const { t } = useTranslation();\r\n\r\n return (\r\n \r\n );\r\n};","import { CreateUserBase, EditUserBase } from \"../EditUserBase\";\r\n\r\n/**\r\n * Create an administrator.\r\n */\r\nexport const CreateAdministrator = () => (\r\n ({ /* No defaults needed */ })}\r\n defaultRoleGroup=\"Esitu staff\"\r\n filterRoleGroups={(groups) => groups.filter(item => item.id === 'Esitu staff')}\r\n />);\r\n\r\n/**\r\n * Edit an administrator.\r\n */\r\nexport const EditAdministrator = () => (\r\n groups.filter(item => item.id === 'Esitu staff')}\r\n />);\r\n","import { DeleteUserBase } from \"../DeleteUserBase\";\r\n\r\n/**\r\n * Delete a administrator.\r\n */\r\nexport const DeleteAdministrator = () => ();\r\n","import { RouteEntry } from \"../../shared/routes\";\r\nimport { ManageHome } from \"./ManageHome\";\r\nimport { IdentityRoles } from \"../../configure/security/IdentityRoles\";\r\n\r\nexport const manageRoutes: Array = [\r\n { path: '/manage', exact: true, component: ManageHome, authorize: true, requireRole: IdentityRoles.DriverManagement },\r\n];\r\n","import { Redirect } from 'react-router';\r\n\r\n/**\r\n * Default Manage home page.\r\n */\r\nexport const ManageHome = () => {\r\n return (\r\n <>\r\n \r\n \r\n );\r\n};","import { NavItem, NavLink } from 'reactstrap';\r\nimport { AuthorizeContainer } from '../../shared/authorizeRoute';\r\nimport { useTranslation } from 'react-i18next';\r\nimport { FontAwesomeIcon } from '@fortawesome/react-fontawesome';\r\nimport { NavLinkTrackActive } from '../shared/NavLinkTrackActive';\r\nimport { IdentityRoles } from '../../configure/security/IdentityRoles';\r\n\r\n/**\r\n * Manage navigation menu for the app. \r\n */\r\nexport const ManageNavigation = () => {\r\n const { t } = useTranslation();\r\n\r\n return (\r\n <>\r\n \r\n \r\n \r\n \r\n <> {t('manageNavigtion.drivers', 'Drivers')}\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n <> {t('manageNavigtion.teams', 'Teams')}\r\n \r\n \r\n \r\n \r\n \r\n <> {t('manageNavigtion.managers', 'Managers')}\r\n \r\n \r\n \r\n \r\n \r\n <> {t('manageNavigtion.api', 'API and SDK')}\r\n \r\n \r\n \r\n \r\n );\r\n};\r\n","import { MouseEventHandler, useCallback } from \"react\";\r\nimport { useTranslation } from \"react-i18next\";\r\nimport { NavItem, NavLink } from \"reactstrap\";\r\nimport { NavLinkTrackActive } from \"../shared/NavLinkTrackActive\";\r\nimport { FontAwesomeIcon } from '@fortawesome/react-fontawesome';\r\n\r\nexport interface SubscriptionTeamNavigationProps {\r\n id: string,\r\n onNavigate?: (link: string) => void,\r\n editLink?: string,\r\n}\r\n\r\n/**\r\n * Navigation under editing of a Subscription Team.\r\n */\r\nexport const SubscriptionTeamNavigation = (props: SubscriptionTeamNavigationProps) => {\r\n const { id, onNavigate, editLink } = props;\r\n const { t } = useTranslation();\r\n\r\n // If we have an onNavigate event, we should call that instead of leting the links handle themselves.\r\n const onNavLinkClick = useCallback((e) => {\r\n if (onNavigate) {\r\n e.preventDefault();\r\n const link = e.currentTarget.getAttribute(\"href\") ?? '';\r\n onNavigate(link);\r\n }\r\n }, [onNavigate]);\r\n\r\n return (\r\n <>\r\n \r\n \r\n \r\n {t('subscriptionTeamNavigation.team', ' Team')}\r\n \r\n \r\n \r\n \r\n \r\n {t('subscriptionTeamNavigation.drivers', ' Driver members')}\r\n \r\n \r\n \r\n \r\n \r\n {t('subscriptionTeamNavigation.managers', ' Manager members')}\r\n \r\n \r\n \r\n \r\n \r\n {t('subscriptionTeamNavigation.assessments', ' Required assessments')}\r\n \r\n \r\n \r\n \r\n \r\n {t('subscriptionTeamNavigation.training', ' Required training')}\r\n \r\n \r\n \r\n );\r\n};\r\n","import { useTranslation } from \"react-i18next\";\r\nimport { useParams } from \"react-router\";\r\nimport { useCurrentUserOrEmulatedSubscriptionId } from \"../../../globalState/subscriptions/useCurrentUserOrEmulatedSubscriptionId\";\r\nimport { ManageNavigation } from \"../../manage/ManageNavigation\";\r\nimport { SubscriptionTeamNavigation } from \"../../subscriptionTeam/SubscriptionTeamNavigation\";\r\nimport { UsersListBase } from \"../UsersListBase\";\r\n\r\n/**\r\n * List of drivers.\r\n */\r\nexport const DriversList = () => {\r\n const { t } = useTranslation();\r\n\r\n const { subscriptionTeamId } = useParams<{ subscriptionTeamId: string | undefined}>();\r\n\r\n const subscriptionId = useCurrentUserOrEmulatedSubscriptionId();\r\n\r\n const baseRoute = subscriptionTeamId ? `/manage/teams/details/${subscriptionTeamId}/drivers` : '/manage/drivers';\r\n\r\n return (\r\n \r\n : \r\n }\r\n teamColumnHidden={subscriptionTeamId ? true\r\n : false\r\n }\r\n \r\n />\r\n );\r\n};","import { DeleteUserBase } from \"../DeleteUserBase\";\r\n\r\n/**\r\n * Delete a driver.\r\n */\r\nexport const DeleteDriver = () => ();\r\n","import { useParams } from \"react-router\";\r\nimport { useCurrentUserOrEmulatedSubscriptionId } from \"../../../globalState/subscriptions/useCurrentUserOrEmulatedSubscriptionId\";\r\nimport { CreateUserBase, EditUserBase } from \"../EditUserBase\";\r\n\r\n/**\r\n * Create a driver.\r\n */\r\nexport const CreateDriver = () => {\r\n const { subscriptionTeamId } = useParams<{ subscriptionTeamId: string | undefined }>();\r\n\r\n const subscriptionId = useCurrentUserOrEmulatedSubscriptionId();\r\n\r\n return (\r\n ({ subscriptionId: subscriptionId, subscriptionTeamId: subscriptionTeamId ?? undefined, })}\r\n defaultRoleGroup=\"Driver\"\r\n filterRoleGroups={(groups) => groups.filter(item => item.id === 'Driver')}\r\n />);\r\n};\r\n\r\n/**\r\n * Edit a driver.\r\n */\r\nexport const EditDriver = () => (\r\n groups.filter(item => item.id === 'Driver')}\r\n />);\r\n","import { IdentityRoles } from \"../../../configure/security/IdentityRoles\";\r\nimport { RouteEntry } from \"../../../shared/routes\";\r\nimport { DriversList } from \"./DriversList\";\r\nimport { DeleteDriver } from \"./DeleteDriver\";\r\nimport { CreateDriver, EditDriver } from \"./EditDriver\";\r\n\r\n\r\nexport const driversRoutes: Array = [\r\n { path: '/manage/drivers', exact: true, component: DriversList, authorize: true, requireRole: IdentityRoles.DriverManagement },\r\n { path: '/manage/drivers/edit/:id', component: EditDriver, authorize: true, requireRole: IdentityRoles.DriverManagement },\r\n { path: '/manage/drivers/add', component: CreateDriver, authorize: true, requireRole: IdentityRoles.DriverManagement },\r\n { path: '/manage/drivers/delete/:id', component: DeleteDriver, authorize: true, requireRole: IdentityRoles.DriverManagement },\r\n\r\n { path: '/manage/teams/details/:subscriptionTeamId/drivers', exact: true, component: DriversList, authorize: true, requireRole: IdentityRoles.DriverManagement },\r\n { path: '/manage/teams/details/:subscriptionTeamId/drivers/edit/:id', component: EditDriver, authorize: true, requireRole: IdentityRoles.DriverManagement },\r\n { path: '/manage/teams/details/:subscriptionTeamId/drivers/add', component: CreateDriver, authorize: true, requireRole: IdentityRoles.DriverManagement },\r\n { path: '/manage/teams/details/:subscriptionTeamId/drivers/delete/:id', component: DeleteDriver, authorize: true, requireRole: IdentityRoles.DriverManagement },\r\n];\r\n","import { useTranslation } from \"react-i18next\";\r\nimport { useCurrentUserOrEmulatedSubscriptionId } from \"../../../globalState/subscriptions/useCurrentUserOrEmulatedSubscriptionId\";\r\nimport { ManageNavigation } from \"../../manage/ManageNavigation\";\r\nimport { UsersListBase } from \"../UsersListBase\";\r\nimport { SubscriptionTeamNavigation } from \"../../subscriptionTeam/SubscriptionTeamNavigation\";\r\nimport { useParams } from \"react-router\";\r\n\r\n/**\r\n * List of managers.\r\n */\r\nexport const ManagersList = () => {\r\n const { t } = useTranslation();\r\n\r\n const { subscriptionTeamId } = useParams<{ subscriptionTeamId: string | undefined }>();\r\n\r\n const subscriptionId = useCurrentUserOrEmulatedSubscriptionId();\r\n\r\n const baseRoute = subscriptionTeamId ? `/manage/teams/details/${subscriptionTeamId}/managers` : '/manage/managers';\r\n\r\n return (\r\n \r\n : \r\n }\r\n teamColumnHidden={subscriptionTeamId ? true\r\n : false\r\n }\r\n \r\n />\r\n );\r\n};","import { DeleteUserBase } from \"../DeleteUserBase\";\r\n\r\n/**\r\n * Delete a manager.\r\n */\r\nexport const DeleteManager = () => ();\r\n","import { useCurrentUserOrEmulatedSubscriptionId } from \"../../../globalState/subscriptions/useCurrentUserOrEmulatedSubscriptionId\";\r\nimport { CreateUserBase, EditUserBase } from \"../EditUserBase\";\r\nimport { useParams } from \"react-router\";\r\n\r\n/**\r\n * Create a manager.\r\n */\r\nexport const CreateManager = () => {\r\n const { subscriptionTeamId } = useParams<{ subscriptionTeamId: string | undefined }>();\r\n\r\n const subscriptionId = useCurrentUserOrEmulatedSubscriptionId();\r\n\r\n return (\r\n ({ subscriptionId: subscriptionId, subscriptionTeamId:subscriptionTeamId ?? undefined })}\r\n defaultRoleGroup=\"Driver manager\"\r\n filterRoleGroups={(groups) => groups.filter(item => item.id === 'Driver manager' || item.id === 'Overview manager')}\r\n />);\r\n};\r\n\r\n/**\r\n * Edit a manager.\r\n */\r\nexport const EditManager = () => (\r\n groups.filter(item => item.id === 'Driver manager' || item.id === 'Overview manager')}\r\n />);\r\n","import { IdentityRoles } from \"../../../configure/security/IdentityRoles\";\r\nimport { RouteEntry } from \"../../../shared/routes\";\r\nimport { ManagersList } from \"./ManagersList\";\r\nimport { DeleteManager } from \"./DeleteManager\";\r\nimport { CreateManager, EditManager } from \"./EditManager\";\r\n\r\n\r\nexport const managersRoutes: Array = [\r\n { path: '/manage/managers', exact: true, component: ManagersList, authorize: true, requireRole: IdentityRoles.SubscriptionAdministration },\r\n { path: '/manage/managers/edit/:id', component: EditManager, authorize: true, requireRole: IdentityRoles.SubscriptionAdministration },\r\n { path: '/manage/managers/add', component: CreateManager, authorize: true, requireRole: IdentityRoles.SubscriptionAdministration },\r\n { path: '/manage/managers/delete/:id', component: DeleteManager, authorize: true, requireRole: IdentityRoles.SubscriptionAdministration },\r\n\r\n { path: '/manage/teams/details/:subscriptionTeamId/managers', exact: true, component: ManagersList, authorize: true, requireRole: IdentityRoles.SubscriptionAdministration },\r\n { path: '/manage/teams/details/:subscriptionTeamId/managers/edit/:id', component: EditManager, authorize: true, requireRole: IdentityRoles.SubscriptionAdministration },\r\n { path: '/manage/teams/details/:subscriptionTeamId/managers/add', component: CreateManager, authorize: true, requireRole: IdentityRoles.SubscriptionAdministration },\r\n { path: '/manage/teams/details/:subscriptionTeamId/managers/delete/:id', component: DeleteManager, authorize: true, requireRole: IdentityRoles.SubscriptionAdministration},\r\n];\r\n","import * as React from 'react';\r\nimport { Button, Row, Col, ButtonGroup, ButtonDropdown, DropdownToggle, DropdownMenu, DropdownItem, CardTitle } from 'reactstrap';\r\nimport { LinkContainer } from 'react-router-bootstrap';\r\nimport { AlertOnErrors } from '../../shared/alertOnErrors';\r\nimport { LoadingIndicator } from '../shared/LoadingIndicator';\r\nimport { Waypoint } from 'react-waypoint';\r\nimport { useReplaceSearchParamsEffect, useSearchParams } from '../../shared/useURLSearchParams';\r\nimport { useTranslation } from 'react-i18next';\r\nimport { SearchInput } from '../shared/searchInput/SearchInput';\r\nimport { FontAwesomeIcon } from '@fortawesome/react-fontawesome';\r\nimport { MainContainer } from '../shared/MainContainer';\r\nimport { NoResultsFound } from '../shared/NoResultsFound';\r\nimport { StickyToolbar } from '../shared/StickyToolbar';\r\nimport { useHistory } from 'react-router';\r\nimport { ConditionalFragment } from 'react-conditionalfragment';\r\nimport { Banner } from '../shared/Banner';\r\nimport { useToggleStateArray } from 'use-toggle-state';\r\nimport { Background } from '../shared/background/Background';\r\nimport { CardsOrTable } from '../shared/cardsOrTable/CardsOrTable';\r\nimport { usePreferredListViewMode } from '../../globalState/preferredListViewMode/usePreferredListViewMode';\r\nimport { useCurrentUserOrEmulatedSubscriptionId } from '../../globalState/subscriptions/useCurrentUserOrEmulatedSubscriptionId';\r\nimport { PillsNavBar } from '../shared/pillsNavBar/PillsNavBar';\r\nimport { ManageNavigation } from '../manage/ManageNavigation';\r\nimport { useSubscriptionTeamsListViewModel } from '../../api/main/subscriptionTeams/viewModels/useListSubscriptionTeamsViewModel';\r\n\r\n\r\n\r\n/**\r\n * List of SubscriptionTeams.\r\n */\r\nexport const SubscriptionTeamsList = () => {\r\n const { t } = useTranslation();\r\n const { search: searchParam } = useSearchParams();\r\n const [search, setSearch] = React.useState(searchParam ?? '');\r\n\r\n const subscriptionId = useCurrentUserOrEmulatedSubscriptionId();\r\n\r\n const { data: { items: allItems, subscription }, isLoading, errors: loadingErrors, fetchMore, hasMore } = useSubscriptionTeamsListViewModel(subscriptionId, { pageSize: undefined, });\r\n const [isMenuOpen, toggleMenuOpen] = useToggleStateArray();\r\n const history = useHistory();\r\n\r\n // Filter by the subscriptionTeam's search client side so it can work when offline as well as online.\r\n const items = React.useMemo(() => {\r\n if (!allItems || !search) {\r\n return allItems;\r\n }\r\n\r\n let lowerSearch = search.toLocaleLowerCase();\r\n\r\n // Filter the items being displayed.\r\n return allItems.filter(item =>\r\n item.name.toLocaleLowerCase().indexOf(lowerSearch) >= 0\r\n );\r\n }, [allItems, search]);\r\n\r\n useReplaceSearchParamsEffect({ search: search });\r\n\r\n const [viewMode, setViewMode] = usePreferredListViewMode();\r\n\r\n\r\n return (\r\n \r\n \r\n \r\n \r\n \r\n

{t('subscriptionTeamList.heading', 'Teams')}

\r\n \r\n \r\n \r\n \r\n \r\n \r\n\r\n
\r\n \r\n \r\n

\r\n {subscription?.companyName}\r\n

\r\n \r\n \r\n \r\n \r\n \r\n \r\n\r\n \r\n setSearch(e.currentTarget.value)} />\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n
\r\n
\r\n
\r\n\r\n \r\n \r\n history.push(`/manage/teams/edit/${item.id}`)}\r\n tableHeadings={[t('subscriptionTeamBase.name', 'Name'),]}\r\n columns={[(item, view) => view === 'cards' ? ({item.name}) : item.name,]}\r\n buttons={(item) => (\r\n\r\n \r\n \r\n \r\n \r\n toggleMenuOpen(item.id)}>\r\n \r\n {t('common.menuDropdown', 'More')}\r\n \r\n \r\n \r\n \r\n \r\n <> {t('common.delete', 'Delete')}\r\n \r\n \r\n \r\n \r\n \r\n )}\r\n />\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n\r\n \r\n
\r\n );\r\n};\r\n","import * as React from 'react';\r\nimport { useLazyQuery } from \"@apollo/react-hooks\";\r\nimport gql from \"graphql-tag\";\r\nimport { Guid } from \"guid-string\";\r\nimport { AsyncLoadResult, AsyncLoadOptions } from '../../../shared/abstractStore';\r\nimport { subscriptionTeamQuery, subscriptionTeamQueryVariables } from '../generated/subscriptionTeamQuery';\r\nimport { subscriptionTeamFieldsFragment } from '../models/SubscriptionTeam';\r\nimport { mainApiConfig } from '../../../configure/mainApiConfig';\r\n\r\n/**\r\n * Get a SubscriptionTeam from the store.\r\n * @param id\r\n * @param options\r\n */\r\nexport function useSubscriptionTeam(id: string | undefined | null, options: AsyncLoadOptions = {}): AsyncLoadResult {\r\n // Query the data we need form the api.\r\n const [load, { data, loading, error, refetch }] = useLazyQuery(\r\n gql`\r\n query subscriptionTeamQuery ($id: ID!) {\r\n model: subscriptionTeam(id: $id) {\r\n ...subscriptionTeamFields\r\n }\r\n }\r\n\r\n ${subscriptionTeamFieldsFragment}\r\n `,\r\n {\r\n variables: {\r\n id: id ?? Guid.empty,\r\n },\r\n fetchPolicy: options.fetchPolicy ?? mainApiConfig.defaultFetchPolicy,\r\n pollInterval: options.pollInterval,\r\n onCompleted: (data) => {\r\n if (options.onCompleted) {\r\n options.onCompleted(data);\r\n }\r\n }\r\n }\r\n );\r\n\r\n // Run the query (unless we are being lazy).\r\n React.useEffect(() => {\r\n if (!options.lazy) {\r\n load();\r\n }\r\n }, [options.lazy, load])\r\n\r\n // Return the results.\r\n const refresh = React.useCallback(async () => { !refetch ? await load() : await refetch(); }, [refetch, load]);\r\n return React.useMemo(() => ({\r\n data: data ?? ({} as any),\r\n refresh: refresh,\r\n isLoading: loading,\r\n errors: error\r\n }), [data, refresh, loading, error]);\r\n}\r\n","import { useMutation } from \"@apollo/react-hooks\";\r\nimport { useAsyncCallback } from 'react-use-async-callback';\r\nimport gql from \"graphql-tag\";\r\nimport { AsyncActionStatus } from '../../../shared/abstractStore';\r\nimport { SubscriptionTeamCreateInput } from '../generated/globalTypes';\r\nimport { createSubscriptionTeamMutation, createSubscriptionTeamMutationVariables } from '../generated/createSubscriptionTeamMutation';\r\nimport { subscriptionTeamFieldsFragment } from '../models/SubscriptionTeam';\r\n\r\n/**\r\n * Get a callback to create a SubscriptionTeam in the store.\r\n */\r\nexport function useCreateSubscriptionTeamCallback(): [(model: SubscriptionTeamCreateInput) => Promise, AsyncActionStatus] {\r\n const [mutationAction, { error }] = useMutation(\r\n gql`\r\n mutation createSubscriptionTeamMutation ($model: SubscriptionTeamCreateInput!) {\r\n createSubscriptionTeam(model: $model) {\r\n ...subscriptionTeamFields\r\n }\r\n }\r\n\r\n ${subscriptionTeamFieldsFragment}\r\n `\r\n );\r\n\r\n // Wrap the mutation in a standard callback.\r\n const [action, { isExecuting, errors: actionErrors }] = useAsyncCallback(async (model: SubscriptionTeamCreateInput) => {\r\n const result = await mutationAction({ variables: { model: model } });\r\n if (result.errors && result.errors.length) {\r\n throw result.errors;\r\n }\r\n }, [mutationAction]);\r\n\r\n return [action, { isExecuting: isExecuting, errors: error ? error.message : actionErrors }];\r\n}\r\n","import { useMutation } from \"@apollo/react-hooks\";\r\nimport { useAsyncCallback } from 'react-use-async-callback';\r\nimport gql from \"graphql-tag\";\r\nimport { AsyncActionStatus } from '../../../shared/abstractStore';\r\nimport { SubscriptionTeamUpdateInput } from '../generated/globalTypes';\r\nimport { updateSubscriptionTeamMutation, updateSubscriptionTeamMutationVariables } from '../generated/updateSubscriptionTeamMutation';\r\nimport { subscriptionTeamFieldsFragment } from '../models/SubscriptionTeam';\r\n\r\n/**\r\n * Get a callback to update a SubscriptionTeam in the store.\r\n */\r\nexport function useUpdateSubscriptionTeamCallback(): [(id: string, model: SubscriptionTeamUpdateInput) => Promise, AsyncActionStatus] {\r\n const [mutationAction, { error }] = useMutation(\r\n gql`\r\n mutation updateSubscriptionTeamMutation ($model: SubscriptionTeamUpdateInput!) {\r\n updateSubscriptionTeam(model: $model) {\r\n ...subscriptionTeamFields\r\n }\r\n }\r\n\r\n ${subscriptionTeamFieldsFragment}\r\n `\r\n );\r\n\r\n // Wrap the mutation in a standard callback.\r\n const [action, { isExecuting, errors: actionErrors }] = useAsyncCallback(async (id: string, model: SubscriptionTeamUpdateInput) => {\r\n const result = await mutationAction({ variables: { model: { ...model, id: id } } });\r\n if (result.errors && result.errors.length) {\r\n throw result.errors;\r\n }\r\n }, [mutationAction]);\r\n\r\n return [action, { isExecuting: isExecuting, errors: error ? error.message : actionErrors }];\r\n}\r\n","import { Button, Row, Col, Form, Label, FormGroup, Spinner } from 'reactstrap';\r\nimport { AlertOnErrors } from '../../shared/alertOnErrors';\r\nimport { LoadingIndicator } from '../shared/LoadingIndicator';\r\nimport { useTranslation } from 'react-i18next';\r\nimport { FontAwesomeIcon } from '@fortawesome/react-fontawesome';\r\nimport { MainContainer } from '../shared/MainContainer';\r\nimport { useParams, useHistory } from 'react-router';\r\nimport { useSubscriptionTeam } from '../../api/main/subscriptionTeams/useSubscriptionTeam';\r\nimport { useChanges } from '../../shared/useChanges';\r\nimport { useSaveSubscriptionTeamCallback } from '../../api/main/subscriptionTeams/useSaveSubscriptionTeamCallback';\r\nimport { useValidatorCallback } from 'pojo-validator-react';\r\nimport { ValidatedInput } from 'pojo-validator-reactstrap';\r\nimport { FormButtons } from '../shared/FormButtons';\r\nimport { ButtonAsync } from 'reactstrap-buttonasync';\r\nimport { useAsyncCallback } from 'react-use-async-callback';\r\nimport { ConditionalFragment } from 'react-conditionalfragment';\r\nimport { Banner } from '../shared/Banner';\r\nimport { Background } from '../shared/background/Background';\r\nimport { subscriptionTeamDefaultValues } from '../../api/main/models/SubscriptionTeam';\r\nimport { useCurrentUserOrEmulatedSubscriptionId } from '../../globalState/subscriptions/useCurrentUserOrEmulatedSubscriptionId';\r\nimport { SubscriptionTeamNavigation } from './SubscriptionTeamNavigation';\r\nimport { PillsNavBar } from '../shared/pillsNavBar/PillsNavBar';\r\n\r\ninterface EditSubscriptionTeamProps {\r\n isCreate?: boolean,\r\n}\r\n\r\n/**\r\n * Create a new subscription team.\r\n */\r\nexport const CreateSubscriptionTeam = () => ();\r\n\r\n/**\r\n * Edit a subscription team.\r\n */\r\nexport const EditSubscriptionTeam = (props: EditSubscriptionTeamProps) => {\r\n const { isCreate } = props;\r\n\r\n const { t } = useTranslation();\r\n const { id } = useParams<{ id: string | undefined }>();\r\n\r\n const subscriptionId = useCurrentUserOrEmulatedSubscriptionId();\r\n\r\n const { data: { model: storeModel }, isLoading: _isLoading, errors: loadErrors } = useSubscriptionTeam(id);\r\n const isLoading = _isLoading;\r\n const { model, change, changes } = useChanges(storeModel, isCreate ? { ...subscriptionTeamDefaultValues(), subscriptionId: subscriptionId ?? undefined } : undefined);\r\n const [save, { errors: saveErrors }] = useSaveSubscriptionTeamCallback();\r\n const history = useHistory();\r\n\r\n const [validate, validationErrors] = useValidatorCallback((validation, fieldsToCheck) => {\r\n const rules = {\r\n name: () => !model?.name ? t('editSubscriptionTeam.name.required', 'Name is required') : '',\r\n };\r\n\r\n validation.checkRules(rules, fieldsToCheck);\r\n }, [model]);\r\n\r\n const [saveForm, { isExecuting: isSaving, errors: saveFormErrors }] = useAsyncCallback(async (options?: { navigateTo?: string, }) => {\r\n if (!validate()) {\r\n return;\r\n }\r\n\r\n await save(model.id, changes, !!isCreate);\r\n\r\n // Navigate to the next screen.\r\n if (options?.navigateTo) {\r\n history.push(options.navigateTo);\r\n } else {\r\n history.goBack();\r\n }\r\n }, [validate, save, model, changes, isCreate, history]);\r\n\r\n return (\r\n \r\n \r\n \r\n \r\n

\r\n {\r\n isCreate ? (\r\n <>{t('editSubscriptionTeam.createHeading', 'Add team')}\r\n ) : (\r\n <>{t('editSubscriptionTeam.editHeading', 'Edit team')}\r\n )\r\n }\r\n

\r\n \r\n \r\n \r\n saveForm({ navigateTo: link })}\r\n />\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n
\r\n
\r\n\r\n \r\n \r\n\r\n
{ e.preventDefault(); saveForm(); }}>\r\n \r\n \r\n change({ name: e.currentTarget.value })} onBlur={e => validate('name')} validationErrors={validationErrors['name']} />\r\n \r\n \r\n \r\n {t('common.saving', 'Saving...')}}>\r\n \r\n <> {t('common.save', 'Save')}\r\n \r\n \r\n \r\n \r\n
\r\n
\r\n
\r\n );\r\n};\r\n","import * as React from 'react';\r\nimport { SubscriptionTeamCreateInput, SubscriptionTeamUpdateInput } from '../generated/globalTypes';\r\nimport { useSaveInStore, SaveInStoreOptions } from '../../../shared/useSaveInStore';\r\nimport { useCreateSubscriptionTeamCallback } from './useCreateSubscriptionTeamCallback';\r\nimport { useUpdateSubscriptionTeamCallback } from './useUpdateSubscriptionTeamCallback';\r\nimport { SubscriptionTeam } from '../models/SubscriptionTeam';\r\n\r\n/**\r\n * Get a callback to save a SubscriptionTeam in the store using either a create or update.\r\n */\r\nexport function useSaveSubscriptionTeamCallback(options: SaveInStoreOptions = {}) {\r\n const [_create, createStatus] = useCreateSubscriptionTeamCallback();\r\n const create = React.useCallback((model: Partial) => _create(model as SubscriptionTeamCreateInput), [_create]);\r\n\r\n const [_update, updateStatus] = useUpdateSubscriptionTeamCallback();\r\n const update = React.useCallback((id: string, changes: Partial) => _update(id, changes as SubscriptionTeamUpdateInput), [_update]);\r\n\r\n return useSaveInStore(\r\n [create, createStatus],\r\n [update, updateStatus],\r\n options\r\n );\r\n}\r\n","import { RouteEntry } from \"../../shared/routes\";\r\nimport { SubscriptionTeamsList } from './SubscriptionTeamsList';\r\nimport { EditSubscriptionTeam, CreateSubscriptionTeam } from \"./EditSubscriptionTeam\";\r\nimport { IdentityRoles } from \"../../configure/security/IdentityRoles\";\r\nimport { DeleteSubscriptionTeam } from \"./DeleteSubscriptionTeam\";\r\n\r\nexport const subscriptionTeamRoutes: Array = [\r\n { path: '/manage/teams', exact: true, component: SubscriptionTeamsList, authorize: true, requireRole: IdentityRoles.DriverManagement },\r\n { path: '/manage/teams/edit/:id', component: EditSubscriptionTeam, authorize: true, requireRole: IdentityRoles.DriverManagement },\r\n { path: '/manage/teams/add', component: CreateSubscriptionTeam, authorize: true, requireRole: IdentityRoles.DriverManagement },\r\n { path: '/manage/teams/delete/:id', component: DeleteSubscriptionTeam, authorize: true, requireRole: IdentityRoles.DriverManagement },\r\n];\r\n","import * as React from 'react';\r\nimport { useLazyQuery } from \"@apollo/react-hooks\";\r\nimport gql from \"graphql-tag\";\r\nimport { AsyncLoadPagedResult, AsyncLoadPagedOptions } from '../../../../shared/abstractStore';\r\nimport { useFetchMoreCallback } from '../../../../shared/useFetchMoreCallback';\r\nimport { subscriptionTeamsListViewModelQuery, subscriptionTeamsListViewModelQueryVariables } from '../../generated/subscriptionTeamsListViewModelQuery';\r\nimport { mainApiConfig } from '../../../../configure/mainApiConfig';\r\nimport { subscriptionTeamFieldsFragment } from '../../models/SubscriptionTeam';\r\nimport { Guid } from 'guid-string';\r\nimport { subscriptionFieldsFragment } from '../../models/Subscription';\r\n\r\n/**\r\n * Get a list of subscription teams for display as in SubscriptionTeamsList.\r\n * @param id\r\n * @param options\r\n */\r\nexport function useSubscriptionTeamsListViewModel(subscriptionId: string | undefined | null, options: AsyncLoadPagedOptions = {}): AsyncLoadPagedResult {\r\n // Query data we need from the api.\r\n const [load, { data, loading, error, refetch, fetchMore: fetchMoreFromStore }] = useLazyQuery(\r\n gql`\r\n query subscriptionTeamsListViewModelQuery ($offset: Int, $first: Int, $subscriptionId: ID!) {\r\n items: subscriptionTeams (offset: $offset, first: $first, subscriptionId: $subscriptionId) {\r\n ...subscriptionTeamFields\r\n }\r\n\r\n subscription (id: $subscriptionId) {\r\n ...subscriptionFields\r\n }\r\n }\r\n\r\n ${subscriptionTeamFieldsFragment}\r\n ${subscriptionFieldsFragment}\r\n `,\r\n {\r\n\r\n variables: {\r\n offset: options.startOffset,\r\n first: options.pageSize,\r\n subscriptionId: subscriptionId ?? Guid.empty,\r\n },\r\n fetchPolicy: options.fetchPolicy ?? mainApiConfig.defaultFetchPolicy,\r\n pollInterval: options.pollInterval,\r\n onCompleted: (data) => {\r\n if (options.onCompleted) {\r\n options.onCompleted(data);\r\n }\r\n }\r\n }\r\n );\r\n\r\n // Run the query (unless we are being lazy).\r\n React.useEffect(() => {\r\n if (!options.lazy) {\r\n load();\r\n }\r\n }, [options.lazy, load])\r\n\r\n // Get the functions used to manage paging.\r\n const { fetchMore, hasMore: _hasMore } = useFetchMoreCallback(\r\n fetchMoreFromStore,\r\n (options?.startOffset ?? 0) + (data?.items?.length ?? 0),\r\n (prevResults, newResults) => ({\r\n ...prevResults,\r\n ...newResults,\r\n\r\n items: [...(prevResults?.items ?? []), ...(newResults?.items ?? [])],\r\n subscription: newResults?.subscription ?? null,\r\n }),\r\n (newResults) => newResults?.items?.length\r\n );\r\n const hasMore = React.useCallback(() => !options.pageSize ? false : _hasMore(), [options.pageSize, _hasMore]);\r\n \r\n // Return the results.\r\n const refresh = React.useCallback(async () => { !refetch ? await load() : await refetch(); }, [refetch, load]);\r\n return React.useMemo(() => ({\r\n data: data ?? ({} as any),\r\n refresh: refresh,\r\n isLoading: loading,\r\n errors: error,\r\n fetchMore: fetchMore,\r\n hasMore: hasMore,\r\n }), [data, refresh, loading, error, fetchMore, hasMore]);\r\n}\r\n","import { Button, Form, Label, FormGroup, Spinner, Input, Row, Col } from 'reactstrap';\r\nimport { AlertOnErrors } from '../../shared/alertOnErrors';\r\nimport { LoadingIndicator } from '../shared/LoadingIndicator';\r\nimport { useTranslation } from 'react-i18next';\r\nimport { FontAwesomeIcon } from '@fortawesome/react-fontawesome';\r\nimport { MainContainer } from '../shared/MainContainer';\r\nimport { useParams, useHistory } from 'react-router';\r\nimport { FormButtons } from '../shared/FormButtons';\r\nimport { ButtonAsync } from 'reactstrap-buttonasync';\r\nimport { useAsyncCallback } from 'react-use-async-callback';\r\nimport { useSubscriptionTeam } from '../../api/main/subscriptionTeams/useSubscriptionTeam';\r\nimport { useDeleteSubscriptionTeamCallback } from '../../api/main/subscriptionTeams/useDeleteSubscriptionTeamCallback';\r\nimport { ConditionalFragment } from 'react-conditionalfragment';\r\nimport { Banner } from '../shared/Banner';\r\nimport { Background } from '../shared/background/Background';\r\n\r\n/**\r\n * Delete a subscription team.\r\n */\r\nexport const DeleteSubscriptionTeam = () => {\r\n const { t } = useTranslation();\r\n const { id } = useParams<{ id: string }>();\r\n const { data: { model }, isLoading, errors: loadErrors } = useSubscriptionTeam(id);\r\n const [remove, { errors: removeErrors }] = useDeleteSubscriptionTeamCallback();\r\n const history = useHistory();\r\n\r\n const [onRemoveFormSubmit, { isExecuting: isRemoving, errors: removeFormErrors }] = useAsyncCallback(async () => {\r\n if (!model) {\r\n return;\r\n }\r\n\r\n await remove(model.id);\r\n\r\n history.goBack();\r\n }, [model, history]);\r\n\r\n return (\r\n \r\n \r\n \r\n \r\n

{t('deleteSubscriptionTeam.heading', 'Are you sure you want to delete this team?')}

\r\n \r\n \r\n \r\n \r\n \r\n \r\n
\r\n
\r\n\r\n \r\n \r\n\r\n
{ e.preventDefault(); onRemoveFormSubmit(); }}>\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n {t('common.deleting', 'Deleting...')}}>\r\n \r\n <> {t('common.delete', 'Delete')}\r\n \r\n \r\n \r\n \r\n
\r\n
\r\n
\r\n );\r\n};\r\n","import gql from \"graphql-tag\";\r\nimport { userDriverMetricFields } from \"../generated/userDriverMetricFields\";\r\n\r\nexport const userDriverMetricFieldsFragment = gql`\r\n fragment userDriverMetricFields on UserDriverMetric {\r\n id\r\n subscriptionId\r\n userId\r\n driverMetricId\r\n currentValue\r\n archived\r\n }\r\n`;\r\n\r\n\r\nexport type UserDriverMetric = Omit;\r\n","import * as React from 'react';\r\nimport { useLazyQuery } from \"@apollo/react-hooks\";\r\nimport gql from \"graphql-tag\";\r\nimport { AsyncLoadPagedResult, AsyncLoadPagedOptions } from '../../../../shared/abstractStore';\r\nimport { useFetchMoreCallback } from '../../../../shared/useFetchMoreCallback';\r\nimport { userAssessmentAssignmentsListViewBaseViewModelQuery, userAssessmentAssignmentsListViewBaseViewModelQueryVariables } from '../../generated/userAssessmentAssignmentsListViewBaseViewModelQuery';\r\nimport { mainApiConfig } from '../../../../configure/mainApiConfig';\r\nimport { subscriptionAssessmentFieldsFragment } from '../../models/SubscriptionAssessment';\r\nimport { AssessmentType } from '../../models/codeOnly/AssessmentType';\r\nimport { assessmentFieldsFragment } from '../../models/Assessment';\r\nimport { Guid } from 'guid-string';\r\nimport { userAssessmentAssignmentFieldsFragment } from '../../models/UserAssessmentAssignment';\r\nimport { subscriptionTeamFieldsFragment } from '../../models/SubscriptionTeam';\r\nimport { profileFieldsFragment } from '../../models/Profile';\r\nimport { driverMetricRecommendationFieldsFragment } from '../../models/DriverMetricRecommendation';\r\nimport { userDriverMetricFieldsFragment } from '../../models/UserDriverMetric';\r\nimport { driverMetricFieldsFragment } from '../../models/DriverMetric';\r\n\r\n\r\nexport interface UserAssessmentAssignmentsListViewBaseViewModelAsyncLoadPageOptions extends AsyncLoadPagedOptions {\r\n assessmentTypes?: Array,\r\n userId?: string | undefined | null,\r\n subscriptionTeamId?: string | undefined | null,\r\n}\r\n\r\n/**\r\n * Get a list of subscriptionAssessments from the store.\r\n * @param options\r\n */\r\nexport function useUserAssessmentAssignmentsListViewBaseViewModel(subscriptionId: string | null | undefined, options: UserAssessmentAssignmentsListViewBaseViewModelAsyncLoadPageOptions = {}): AsyncLoadPagedResult {\r\n // Query data we need from the api.\r\n const [load, { data, loading, error, refetch, fetchMore: fetchMoreFromStore }] = useLazyQuery(\r\n gql`\r\n query userAssessmentAssignmentsListViewBaseViewModelQuery ($subscriptionId: ID!, $offset: Int, $first: Int, $assessmentTypes: [String!], $userId: ID, $subscriptionTeamId: ID, $userIdOrEmptyGuid: ID!, $subscriptionTeamIdOrEmptyGuid: ID!) {\r\n items: userAssessmentAssignments (userId: $userId, subscriptionTeamId: $subscriptionTeamId) {\r\n ...userAssessmentAssignmentFields\r\n }\r\n\r\n subscriptionAssessments (subscriptionId: $subscriptionId) {\r\n ...subscriptionAssessmentFields\r\n }\r\n\r\n assessments (offset: $offset, first: $first, assessmentTypes: $assessmentTypes) {\r\n ...assessmentFields\r\n }\r\n\r\n subscriptionTeam (id: $subscriptionTeamIdOrEmptyGuid) {\r\n ...subscriptionTeamFields\r\n }\r\n\r\n profile (userId: $userIdOrEmptyGuid) {\r\n ...profileFields\r\n }\r\n\r\n driverMetricRecommendations (targetType: \"Assessment\") {\r\n ...driverMetricRecommendationFields\r\n }\r\n\r\n driverMetrics {\r\n ...driverMetricFields\r\n }\r\n\r\n userDriverMetrics (userId: $userIdOrEmptyGuid) {\r\n ...userDriverMetricFields\r\n }\r\n }\r\n\r\n ${userAssessmentAssignmentFieldsFragment}\r\n ${subscriptionAssessmentFieldsFragment}\r\n ${assessmentFieldsFragment}\r\n ${subscriptionTeamFieldsFragment}\r\n ${profileFieldsFragment}\r\n ${driverMetricRecommendationFieldsFragment}\r\n ${driverMetricFieldsFragment}\r\n ${userDriverMetricFieldsFragment}\r\n `,\r\n {\r\n\r\n variables: {\r\n offset: options.startOffset,\r\n first: options.pageSize,\r\n assessmentTypes: options.assessmentTypes,\r\n subscriptionId: subscriptionId ?? Guid.empty,\r\n userId: options.userId,\r\n userIdOrEmptyGuid: options.userId ?? Guid.empty,\r\n subscriptionTeamId: options.subscriptionTeamId,\r\n subscriptionTeamIdOrEmptyGuid: options.subscriptionTeamId ?? Guid.empty,\r\n },\r\n fetchPolicy: options.fetchPolicy ?? mainApiConfig.defaultFetchPolicy,\r\n pollInterval: options.pollInterval,\r\n onCompleted: (data) => {\r\n if (options.onCompleted) {\r\n options.onCompleted(data);\r\n }\r\n }\r\n }\r\n );\r\n\r\n // Run the query (unless we are being lazy).\r\n React.useEffect(() => {\r\n if (!options.lazy) {\r\n load();\r\n }\r\n }, [options.lazy, load])\r\n\r\n // Get the functions used to manage paging.\r\n const { fetchMore, hasMore: _hasMore } = useFetchMoreCallback(\r\n fetchMoreFromStore,\r\n (options?.startOffset ?? 0) + (data?.items?.length ?? 0),\r\n (prevResults, newResults) => ({\r\n ...prevResults,\r\n ...newResults,\r\n\r\n items: newResults?.items ?? [],\r\n subscriptionAssessments: newResults?.subscriptionAssessments ?? [],\r\n assessments: [...(prevResults?.assessments ?? []), ...(newResults?.assessments ?? [])],\r\n profile: newResults?.profile ?? null,\r\n subscriptionTeam: newResults?.subscriptionTeam ?? null,\r\n driverMetricRecommendations: newResults?.driverMetricRecommendations ?? [],\r\n driverMetrics: newResults?.driverMetrics ?? [],\r\n userDriverMetrics: newResults?.userDriverMetrics ?? [],\r\n }),\r\n (newResults) => newResults?.items?.length\r\n );\r\n const hasMore = React.useCallback(() => !options.pageSize ? false : _hasMore(), [options.pageSize, _hasMore]);\r\n \r\n // Return the results.\r\n const refresh = React.useCallback(async () => { !refetch ? await load() : await refetch(); }, [refetch, load]);\r\n return React.useMemo(() => ({\r\n data: data ?? ({} as any),\r\n refresh: refresh,\r\n isLoading: loading,\r\n errors: error,\r\n fetchMore: fetchMore,\r\n hasMore: hasMore,\r\n }), [data, refresh, loading, error, fetchMore, hasMore]);\r\n}\r\n","import { useMutation } from \"@apollo/react-hooks\";\r\nimport { useAsyncCallback } from 'react-use-async-callback';\r\nimport gql from \"graphql-tag\";\r\nimport { AsyncActionStatus } from '../../../shared/abstractStore';\r\nimport { UserAssessmentAssignmentCreateInput } from '../generated/globalTypes';\r\nimport { createUserAssessmentAssignmentMutation, createUserAssessmentAssignmentMutationVariables } from '../generated/createUserAssessmentAssignmentMutation';\r\nimport { userAssessmentAssignmentFieldsFragment } from '../models/UserAssessmentAssignment';\r\n\r\n/**\r\n * Get a callback to create a UserAssessmentAssignment in the store.\r\n */\r\nexport function useCreateUserAssessmentAssignmentCallback(): [(model: UserAssessmentAssignmentCreateInput) => Promise, AsyncActionStatus] {\r\n const [mutationAction, { error }] = useMutation(\r\n gql`\r\n mutation createUserAssessmentAssignmentMutation ($model: UserAssessmentAssignmentCreateInput!) {\r\n createUserAssessmentAssignment(model: $model) {\r\n ...userAssessmentAssignmentFields\r\n }\r\n }\r\n\r\n ${userAssessmentAssignmentFieldsFragment}\r\n `\r\n );\r\n\r\n // Wrap the mutation in a standard callback.\r\n const [action, { isExecuting, errors: actionErrors }] = useAsyncCallback(async (model: UserAssessmentAssignmentCreateInput) => {\r\n const result = await mutationAction({ variables: { model: model } });\r\n if (result.errors && result.errors.length) {\r\n throw result.errors;\r\n }\r\n }, [mutationAction]);\r\n\r\n return [action, { isExecuting: isExecuting, errors: error ? error.message : actionErrors }];\r\n}\r\n","import { useMutation } from \"@apollo/react-hooks\";\r\nimport { useAsyncCallback } from 'react-use-async-callback';\r\nimport gql from \"graphql-tag\";\r\nimport { AsyncActionStatus } from '../../../shared/abstractStore';\r\nimport { UserAssessmentAssignmentUpdateInput } from '../generated/globalTypes';\r\nimport { updateUserAssessmentAssignmentMutation, updateUserAssessmentAssignmentMutationVariables } from '../generated/updateUserAssessmentAssignmentMutation';\r\nimport { userAssessmentAssignmentFieldsFragment } from '../models/UserAssessmentAssignment';\r\n\r\n/**\r\n * Get a callback to update a UserAssessmentAssignment in the store.\r\n */\r\nexport function useUpdateUserAssessmentAssignmentCallback(): [(id: string, model: UserAssessmentAssignmentUpdateInput) => Promise, AsyncActionStatus] {\r\n const [mutationAction, { error }] = useMutation(\r\n gql`\r\n mutation updateUserAssessmentAssignmentMutation ($model: UserAssessmentAssignmentUpdateInput!) {\r\n updateUserAssessmentAssignment(model: $model) {\r\n ...userAssessmentAssignmentFields\r\n }\r\n }\r\n\r\n ${userAssessmentAssignmentFieldsFragment}\r\n `\r\n );\r\n\r\n // Wrap the mutation in a standard callback.\r\n const [action, { isExecuting, errors: actionErrors }] = useAsyncCallback(async (id: string, model: UserAssessmentAssignmentUpdateInput) => {\r\n const result = await mutationAction({ variables: { model: { ...model, id: id } } });\r\n if (result.errors && result.errors.length) {\r\n throw result.errors;\r\n }\r\n }, [mutationAction]);\r\n\r\n return [action, { isExecuting: isExecuting, errors: error ? error.message : actionErrors }];\r\n}\r\n","import { useMemo } from \"react\";\r\nimport { useLocation } from \"react-router\";\r\nimport { DriverNavigation } from \"./drivers/DriverNavigation\";\r\nimport { ManagerNavigation } from \"./managers/ManagerNavigation\";\r\nimport { AdministratorNavigation } from './administrators/AdministratorNavigation';\r\n\r\nexport interface UserNavigationProps {\r\n id: string,\r\n onNavigate?: (link: string) => void,\r\n editLink?: string,\r\n}\r\n\r\n/**\r\n * Navigation under a user that will automatically select the correct navigation to use for the type of user\r\n * (using the route/URL).\r\n * \r\n * If you know where you are, it is usually better to use the right navigation directly, e.g. DriverNavigation, but in situations where you don't want\r\n * to make the component overly aware of how we split users into Drivers/Managers etc. you can use this one and let the logic here decide which one to show instead.\r\n */\r\nexport const UserNavigation = (props: UserNavigationProps) => {\r\n const { pathname } = useLocation();\r\n\r\n const userType = useMemo((): 'driver' | 'manager' | 'administrator' => (\r\n pathname.indexOf('/drivers') >= 0 ? 'driver'\r\n : pathname.indexOf('/managers') >= 0 ? 'manager'\r\n : 'administrator'\r\n ), [pathname]);\r\n\r\n switch (userType) {\r\n case 'driver':\r\n return ;\r\n case 'manager':\r\n return ;\r\n case 'administrator':\r\n return ;\r\n default:\r\n return null;\r\n }\r\n};\r\n","import * as React from 'react';\r\nimport moment, { Moment, MomentInput } from 'moment';\r\nimport { InputProps, Input } from 'reactstrap';\r\nimport { useTranslation } from 'react-i18next';\r\n\r\nexport interface DateTimeInputProps extends InputProps {\r\n onChange?: (event: React.ChangeEvent) => void,\r\n format?: string,\r\n}\r\n\r\n/**\r\n * Input with validation support for a datetime picker using moment() to keep our dates straight.\r\n * @param props\r\n */\r\nexport const ISODateTimeInput = (props: DateTimeInputProps) => {\r\n const {\r\n type = 'datetime-local',\r\n value,\r\n format,\r\n onChange,\r\n plaintext,\r\n ...rest\r\n } = props;\r\n\r\n const { t } = useTranslation();\r\n\r\n const theValue = React.useMemo(() => {\r\n // Use a moment to get the local datetime and format into formats supported by browser input tags.\r\n const theFormat = format || (type === 'datetime' || type === 'datetime-local' ? 'YYYY-MM-DD[T]HH:mm' : 'YYYY-MM-DD');\r\n const valueMoment: Moment = moment(value as MomentInput).local();\r\n let ret = '';\r\n if (valueMoment.isValid()) {\r\n ret = valueMoment.format(theFormat);\r\n }\r\n\r\n // Special handling for plainText rendering, in this case we need to format ready for consumption not for date picker.\r\n if (plaintext) {\r\n if (type === 'datetime' || type === 'datetime-local') {\r\n ret = t('common.datetime', '{{date, DD/MM/YYYY HH:mm}}', { date: valueMoment });\r\n } else {\r\n ret = t('common.date', '{{date, DD/MM/YYYY}}', { date: valueMoment });\r\n }\r\n }\r\n\r\n return ret;\r\n }, [value, type, format, plaintext, t]);\r\n\r\n // Wrap the real on change event to always return the ISO date string in UTC time.\r\n const onChangeWrapper = React.useCallback((event: React.ChangeEvent) => {\r\n if (onChange) {\r\n const newValueMoment: Moment = moment(event.currentTarget.value);\r\n if (!newValueMoment.isValid()) {\r\n // Don't push changes if they are not valid dates.\r\n return;\r\n }\r\n\r\n // Swap the value out for the ISO date in the moment \r\n const newValue = newValueMoment.utc().toISOString();\r\n\r\n const newEvent = {\r\n ...event,\r\n currentTarget: {\r\n ...event.currentTarget,\r\n value: newValue,\r\n },\r\n target: {\r\n ...event.target,\r\n value: newValue,\r\n }\r\n };\r\n\r\n onChange(newEvent);\r\n }\r\n }, [onChange]);\r\n\r\n return (\r\n \r\n );\r\n};\r\n","import * as React from 'react';\r\nimport { Table, Button, Row, Col, ButtonGroup } from 'reactstrap';\r\nimport { AlertOnErrors } from '../../shared/alertOnErrors';\r\nimport { LoadingIndicator } from '../shared/LoadingIndicator';\r\nimport { Waypoint } from 'react-waypoint';\r\nimport { useReplaceSearchParamsEffect, useSearchParams } from '../../shared/useURLSearchParams';\r\nimport { useTranslation } from 'react-i18next';\r\nimport { SearchInput } from '../shared/searchInput/SearchInput';\r\nimport { FontAwesomeIcon } from '@fortawesome/react-fontawesome';\r\nimport { MainContainer } from '../shared/MainContainer';\r\nimport { NoResultsFound } from '../shared/NoResultsFound';\r\nimport { StickyToolbar } from '../shared/StickyToolbar';\r\nimport { useParams } from 'react-router';\r\nimport { ConditionalFragment } from 'react-conditionalfragment';\r\nimport { Banner } from '../shared/Banner';\r\nimport { Background } from '../shared/background/Background';\r\nimport { AssessmentType } from '../../api/main/models/codeOnly/AssessmentType';\r\nimport { PillsNavBar } from '../shared/pillsNavBar/PillsNavBar';\r\nimport { useUserAssessmentAssignmentsListViewBaseViewModel } from '../../api/main/userAssessmentAssignments/viewModels/useUserAssessmentAssignmentsListViewBaseViewModel';\r\nimport { useChangesArray } from '../../shared/useChanges';\r\nimport { useSaveUserAssessmentAssignmentCallback } from '../../api/main/userAssessmentAssignments/useSaveUserAssessmentAssignmentCallback';\r\nimport { useDeleteUserAssessmentAssignmentCallback } from '../../api/main/userAssessmentAssignments/useDeleteUserAssessmentAssignmentCallback';\r\nimport { useAsyncCallback } from 'react-use-async-callback';\r\nimport { useDebouncedCallback } from 'use-debounce/lib';\r\nimport { useCallback, useState } from 'react';\r\nimport { UserAssessmentAssignment, userAssessmentAssignmentDefaultValues } from '../../api/main/models/UserAssessmentAssignment';\r\nimport { SubscriptionTeamNavigation } from '../subscriptionTeam/SubscriptionTeamNavigation';\r\nimport { useCurrentUserOrEmulatedSubscriptionId } from '../../globalState/subscriptions/useCurrentUserOrEmulatedSubscriptionId';\r\nimport { UserNavigation } from '../users/UserNavigation';\r\nimport { useProfile } from '../../api/main/profiles/useProfile';\r\nimport { ISODateTimeInput } from '../shared/ISODateTimeInput';\r\nimport { useSendAssessmentReminderCallback } from '../../api/main/assessments/useSendAssessmentReminderCallback';\r\nimport { useSendAllAssessmentReminderCallback } from '../../api/main/assessments/useSendAllAssessmentReminderCallback';\r\nimport { ValidatedInput } from \"pojo-validator-reactstrap\";\r\nimport { useValidatorArrayCallback } from '../../shared/validator-react-contrib/useValidatorArrayCallback';\r\nimport { LinkContainer } from \"react-router-bootstrap\";\r\nimport { Assessment } from \"../../api/main/models/Assessment\";\r\n\r\n\r\nexport interface UserAssessmentAssignmentsListBaseBaseProps {\r\n title: string,\r\n mobileColumn1Name: string,\r\n assessmentTypes: Array,\r\n}\r\n\r\n/**\r\n * Assessments (or training) that is assigned to individuals or teams.\r\n */\r\nexport const UserAssessmentAssignmentsListBase = (props: UserAssessmentAssignmentsListBaseBaseProps) => {\r\n const {\r\n title,\r\n mobileColumn1Name,\r\n assessmentTypes,\r\n } = props;\r\n\r\n const { subscriptionTeamId, profileId } = useParams<{ subscriptionTeamId: string | undefined, profileId: string | undefined }>();\r\n const subscriptionId = useCurrentUserOrEmulatedSubscriptionId();\r\n\r\n // Convert the profileId into a userId if we have one.\r\n const { data: { model: _profile } } = useProfile(profileId);\r\n const userId = React.useMemo(() => _profile?.userId, [_profile]);\r\n\r\n \r\n const { t } = useTranslation();\r\n const { search: searchParam } = useSearchParams();\r\n const [search, setSearch] = React.useState(searchParam ?? '');\r\n const {\r\n data: {\r\n items: storeUserAssessmentAssignments,\r\n subscriptionAssessments,\r\n assessments: allItems,\r\n subscriptionTeam,\r\n profile,\r\n driverMetricRecommendations,\r\n driverMetrics,\r\n userDriverMetrics,\r\n },\r\n isLoading, errors: loadingErrors, fetchMore, hasMore\r\n } = useUserAssessmentAssignmentsListViewBaseViewModel(subscriptionId, { pageSize: undefined, assessmentTypes: assessmentTypes, subscriptionTeamId: subscriptionTeamId, userId: userId });\r\n\r\n const baseRouteSolver = useCallback((assessment: Assessment) => {\r\n if (assessment.assessmentType === AssessmentType.TrainingModule) {\r\n return `/training/start/${assessment.id}`;\r\n } else {\r\n return `/assessment/start/${assessment.id}`;\r\n }\r\n }, []);\r\n\r\n\r\n // Manage the addition and removal of items for this subscription.\r\n const userAssessmentAssignmentsManager = useChangesArray(storeUserAssessmentAssignments, item => item.id);\r\n const [saveUserAssessmentAssignment] = useSaveUserAssessmentAssignmentCallback();\r\n const [removeUserAssessmentAssignment] = useDeleteUserAssessmentAssignmentCallback();\r\n\r\n // Save all changes to the userAssessmentAssignmentManager.\r\n const [saveAllUserAssessmentAssignments] = useAsyncCallback(async () => {\r\n // Save to the store.\r\n for (const item of userAssessmentAssignmentsManager.added) { await saveUserAssessmentAssignment(item.id, userAssessmentAssignmentsManager.changesFor(item.id), true); }\r\n for (const item of userAssessmentAssignmentsManager.updated) { await saveUserAssessmentAssignment(item.id, userAssessmentAssignmentsManager.changesFor(item.id), false); }\r\n for (const item of userAssessmentAssignmentsManager.removed) { await removeUserAssessmentAssignment(item.id); }\r\n userAssessmentAssignmentsManager.markAsSaved();\r\n }, [userAssessmentAssignmentsManager, saveUserAssessmentAssignment, removeUserAssessmentAssignment, subscriptionId]);\r\n // Debounced version to avoid going to the server too often.\r\n const saveAllUserAssessmentAssignmentsDebounced = useDebouncedCallback((userAssessmentAssignment?, assessmentId?,) => {\r\n\r\n var allowed\r\n var currentAssignment\r\n\r\n if (userAssessmentAssignment) {\r\n allowed = validateUserAssessmentAssignments(userAssessmentAssignment);\r\n }\r\n else {\r\n currentAssignment = userAssessmentAssignmentsManager.model.find(item => item.assessmentId === assessmentId && item.userId === userId);\r\n if (currentAssignment) {\r\n\r\n allowed = validateUserAssessmentAssignments(currentAssignment);\r\n\r\n }\r\n }\r\n\r\n if (allowed) {\r\n saveAllUserAssessmentAssignments();\r\n }\r\n });\r\n\r\n // Toggle if an assessment is selected for the subscription or not.\r\n const toggleUserAssessmentAssignment = useCallback((assessmentId: string) => {\r\n const existing = userAssessmentAssignmentsManager.model.find(item => item.assessmentId === assessmentId);\r\n\r\n if (existing) {\r\n userAssessmentAssignmentsManager.removeFor(existing.id);\r\n } else {\r\n\r\n const defaultRestarts = subscriptionAssessments.find(it => it.assessmentId === assessmentId)?.maxRestarts ?? 0\r\n\r\n userAssessmentAssignmentsManager.addFor({\r\n ...userAssessmentAssignmentDefaultValues(),\r\n\r\n subscriptionId: profile?.subscriptionId ?? subscriptionTeam?.subscriptionId ?? undefined, // This logic makes sure admins who are emulating a subscription don't end up with assignments in that subscription when setting for Esitu staff.\r\n subscriptionTeamId: subscriptionTeamId ?? undefined,\r\n userId: userId ?? '',\r\n maxRestarts: defaultRestarts,\r\n assessmentId: assessmentId,\r\n });\r\n\r\n }\r\n\r\n // Save to the store after a debounce to allow grouping of quick actions and the state itself to be updated.\r\n saveAllUserAssessmentAssignmentsDebounced(existing ?? undefined, assessmentId);\r\n }, [userAssessmentAssignmentsManager, saveAllUserAssessmentAssignmentsDebounced, subscriptionTeamId, userId, profile, subscriptionTeam, subscriptionAssessments]);\r\n\r\n // Returns true if the assessment is selected for this subscription.\r\n const isUserAssessmentAssignmentSelected = useCallback((assessmentId: string) => !!userAssessmentAssignmentsManager.model.find(item => item.assessmentId === assessmentId), [userAssessmentAssignmentsManager]);\r\n\r\n // Filtering the display between all and selected only.\r\n const [filter, setFilter] = useState<'all' | 'selected'>('all');\r\n\r\n //Assessment Reminder callbacks\r\n const [remind] = useSendAssessmentReminderCallback();\r\n const [remindAll] = useSendAllAssessmentReminderCallback();\r\n\r\n //Handle which reminder callback to use on the remind button depending on if there is a TeamId or a ProfileId.\r\n const [handleRemindButton] = useAsyncCallback(async (assessmentId: string) => {\r\n if (!!subscriptionTeamId) {\r\n //if we have a subscriptionTeamId use remindAll\r\n await remindAll(assessmentId, subscriptionTeamId);\r\n return;\r\n }\r\n //if not we must have a profileId so use remind\r\n if (!!profile) {\r\n await remind(profile.userId, assessmentId);\r\n }\r\n }, [subscriptionTeamId, remind, remindAll, profile])\r\n \r\n // Filter by the assessment's search client side so it can work when offline as well as online.\r\n const items = React.useMemo(() => {\r\n if (!allItems) {\r\n return allItems;\r\n }\r\n\r\n let ret = allItems;\r\n\r\n if (profile?.subscriptionId != null || subscriptionTeam?.subscriptionId != null) {\r\n // Filter down to only items that are licesnced for this subscription.\r\n ret = ret.filter(item => !!subscriptionAssessments?.find(link => link.assessmentId === item.id));\r\n }\r\n\r\n // Filter by the selected filter.\r\n switch (filter) {\r\n case 'all':\r\n break;\r\n case 'selected': {\r\n ret = ret.filter(item => isUserAssessmentAssignmentSelected(item.id));\r\n }\r\n }\r\n\r\n // Filter by the user's search text.\r\n if (search) {\r\n let lowerSearch = search.toLocaleLowerCase();\r\n\r\n ret = ret.filter(item =>\r\n item.name.toLocaleLowerCase().indexOf(lowerSearch) >= 0\r\n );\r\n }\r\n\r\n return ret;\r\n }, [allItems, search, filter, isUserAssessmentAssignmentSelected, subscriptionAssessments, subscriptionTeam, profile]);\r\n\r\n useReplaceSearchParamsEffect({ search: search });\r\n\r\n // Given an assessmentId, check to see if there are any recommendation rules (based off driver metrics) that mean we should recommend this for the user.\r\n const generateRecommendationReasons = useCallback((assessmentId: string) => {\r\n if (!userId) {\r\n return [];\r\n }\r\n\r\n let ret: Array = [];\r\n const myRules = driverMetricRecommendations.filter(item => item.targetId === assessmentId);\r\n for (const rule of myRules) {\r\n const metric = driverMetrics.find(item => item.id === rule.driverMetricId);\r\n const userMetric = userDriverMetrics.find(item => item.userId === userId && item.driverMetricId === rule.driverMetricId);\r\n\r\n const currentValue = userMetric?.currentValue ?? metric?.startValue ?? 0;\r\n\r\n // Make sure we fall within the bounds of the rule.\r\n if (currentValue < rule.minScore) {\r\n continue;\r\n }\r\n\r\n if (currentValue > rule.maxScore) {\r\n continue;\r\n }\r\n\r\n // Load the metric so we can use its name.\r\n if (!metric) {\r\n continue;\r\n }\r\n\r\n // Prepare the reasoning text.\r\n const text = t('userAssessmentAssignmentsListBase.generateRecommendationReasons.text', 'Recommended for this user based on their \"{{metric}}\" score of {{score}}.', { metric: metric.name, score: currentValue, });\r\n ret.push(text);\r\n }\r\n\r\n return ret;\r\n }, [driverMetricRecommendations, userId, userDriverMetrics, driverMetrics, t]);\r\n\r\n const colCount = 6;\r\n\r\n const [validateUserAssessmentAssignments, userAssessmentAssignmentErrors] = useValidatorArrayCallback((myModel, validation, fieldsToCheck) => {\r\n const rules = {\r\n\r\n maxRestarts: () => subscriptionAssessments.find(item => item.assessmentId === myModel.assessmentId)?.maxRestarts! < myModel.maxRestarts && myModel.maxRestarts !== 0 ? t('UserAssessmentAssignmentsListBase.MaxRestarts', 'Max restarts cannot exceed the limit set on subscription') : '',\r\n\r\n };\r\n\r\n validation.checkRules(rules, fieldsToCheck);\r\n\r\n }, [subscriptionAssessments]);\r\n\r\n return (\r\n \r\n \r\n \r\n \r\n \r\n

\r\n {title}\r\n

\r\n \r\n \r\n \r\n {\r\n profileId ? \r\n : subscriptionTeamId ? \r\n : null\r\n }\r\n \r\n \r\n
\r\n \r\n \r\n

\r\n {\r\n profile ? t('common.fullName', '{{firstName}} {{lastName}}', { firstName: profile.firstName, lastName: profile.lastName, })\r\n : subscriptionTeam ? subscriptionTeam.name\r\n : ''\r\n }\r\n

\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n setSearch(e.currentTarget.value)} />\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n
\r\n
\r\n
\r\n\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n {/**/}\r\n {/**/}\r\n \r\n \r\n \r\n \r\n {\r\n items?.map(item => {\r\n const itemIsSelected = isUserAssessmentAssignmentSelected(item.id);\r\n const userAssessmentAssignment = userAssessmentAssignmentsManager.model.find(it => it.assessmentId === item.id);\r\n\r\n const recommendationReasons = generateRecommendationReasons(item.id);\r\n\r\n return (\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n );\r\n })\r\n }\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n
 {mobileColumn1Name}{t('userAssessmentAssignmentsListBase.name', 'Name')}{t('userAssessmentAssignmentsListBase.dueDate', 'Due by date')}{t('userAssessmentAssignmentsListBase.MaxRestarts', 'Maximum retakes')}{t('userAssessmentAssignmentsListBase.feedbackStyle', 'Feedback style')}{t('userAssessmentAssignmentsListBase.isSmartIndividuality.heading', 'Smart?')} 
\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n
\r\n {item.name}\r\n
\r\n 0}>\r\n
\r\n \r\n {\r\n recommendationReasons.map(reason => (\r\n
\r\n {reason}\r\n
\r\n ))\r\n }\r\n
\r\n
\r\n
\r\n
\r\n {item.name}\r\n\r\n 0}>\r\n
\r\n \r\n {\r\n recommendationReasons.map(reason => (\r\n
\r\n {reason}\r\n
\r\n ))\r\n }\r\n
\r\n
\r\n
\r\n
\r\n \r\n userAssessmentAssignmentsManager.changeFor(userAssessmentAssignment?.id ?? '', { targetDate: e.currentTarget.value })}\r\n onBlur={() => saveAllUserAssessmentAssignmentsDebounced(userAssessmentAssignment)}\r\n />\r\n \r\n \r\n \r\n \r\n userAssessmentAssignmentsManager?.changeFor(userAssessmentAssignment?.id ?? '', { maxRestarts: e.currentTarget.valueAsNumber })}\r\n onBlur={() => saveAllUserAssessmentAssignmentsDebounced(userAssessmentAssignment)}\r\n validationErrors={userAssessmentAssignmentErrors(userAssessmentAssignment?.id!)[\"maxRestarts\"]}\r\n />\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n
\r\n \r\n
\r\n \r\n \r\n
\r\n
\r\n
\r\n );\r\n};\r\n","import * as React from 'react';\r\nimport { UserAssessmentAssignmentCreateInput, UserAssessmentAssignmentUpdateInput } from '../generated/globalTypes';\r\nimport { useSaveInStore, SaveInStoreOptions } from '../../../shared/useSaveInStore';\r\nimport { useCreateUserAssessmentAssignmentCallback } from './useCreateUserAssessmentAssignmentCallback';\r\nimport { useUpdateUserAssessmentAssignmentCallback } from './useUpdateUserAssessmentAssignmentCallback';\r\nimport { UserAssessmentAssignment } from '../models/UserAssessmentAssignment';\r\n\r\n/**\r\n * Get a callback to save a UserAssessmentAssignment in the store using either a create or update.\r\n */\r\nexport function useSaveUserAssessmentAssignmentCallback(options: SaveInStoreOptions = {}) {\r\n const [_create, createStatus] = useCreateUserAssessmentAssignmentCallback();\r\n const create = React.useCallback((model: Partial) => _create(model as UserAssessmentAssignmentCreateInput), [_create]);\r\n\r\n const [_update, updateStatus] = useUpdateUserAssessmentAssignmentCallback();\r\n const update = React.useCallback((id: string, changes: Partial) => _update(id, changes as UserAssessmentAssignmentUpdateInput), [_update]);\r\n\r\n return useSaveInStore(\r\n [create, createStatus],\r\n [update, updateStatus],\r\n options\r\n );\r\n}\r\n","import { useMutation } from \"@apollo/react-hooks\";\r\nimport { useAsyncCallback } from 'react-use-async-callback';\r\nimport gql from \"graphql-tag\";\r\nimport { AsyncActionStatus } from '../../../shared/abstractStore';\r\nimport { deleteUserAssessmentAssignmentMutation, deleteUserAssessmentAssignmentMutationVariables } from '../generated/deleteUserAssessmentAssignmentMutation';\r\nimport { userAssessmentAssignmentFieldsFragment } from '../models/UserAssessmentAssignment';\r\n\r\n/**\r\n * Get a callback to delete a UserAssessmentAssignment in the store.\r\n */\r\nexport function useDeleteUserAssessmentAssignmentCallback(): [(id: string) => Promise, AsyncActionStatus] {\r\n const [mutationAction, { error }] = useMutation(\r\n gql`\r\n mutation deleteUserAssessmentAssignmentMutation ($id: ID!) {\r\n deleteUserAssessmentAssignment(id: $id) {\r\n ...userAssessmentAssignmentFields\r\n }\r\n }\r\n\r\n ${userAssessmentAssignmentFieldsFragment}\r\n `\r\n );\r\n\r\n // Wrap the mutation in a standard callback.\r\n const [action, { isExecuting, errors: actionErrors }] = useAsyncCallback(async (id: string) => {\r\n const result = await mutationAction({ variables: { id: id } });\r\n if (result.errors && result.errors.length) {\r\n throw result.errors;\r\n }\r\n }, [mutationAction]);\r\n\r\n return [action, { isExecuting: isExecuting, errors: error ? error.message : actionErrors }];\r\n}\r\n","import { useServices } from \"inject-typesafe-react\";\r\nimport { useAsyncCallback } from \"react-use-async-callback\";\r\nimport { AppServices } from \"../../../configure/configureServices\";\r\nimport { AsyncActionStatus } from \"../../../shared/abstractStore\";\r\n\r\n/*\r\n * Get a callback to send a reminder to a user to complete a questionnaire.\r\n */\r\nexport function useSendAssessmentReminderCallback(): [(userId: string, assessmentId: string) => Promise, AsyncActionStatus]\r\n{\r\n var api = useServices((services: AppServices) => services.apiFetch());\r\n //callback to get the userId, AssessmentId, Assessment Name. \r\n const [callback, status] = useAsyncCallback(async (userId: string, assessmentId: string) => {\r\n await api.post(`/api/reminders/sendReminder`, { userId: userId, assessmentId: assessmentId});\r\n }, [api]);\r\n\r\n return [callback, status];\r\n}","import { useServices } from \"inject-typesafe-react\";\r\nimport { useAsyncCallback } from \"react-use-async-callback\";\r\nimport { AppServices } from \"../../../configure/configureServices\";\r\nimport { AsyncActionStatus } from \"../../../shared/abstractStore\";\r\n\r\n/*\r\n * Get a callback to send a reminder to all users on a team to complete a Assessment.\r\n */\r\nexport function useSendAllAssessmentReminderCallback(): [(assessmentId: string, subscriptionTeamId: string) => Promise, AsyncActionStatus]\r\n{\r\n var api = useServices((services: AppServices) => services.apiFetch());\r\n //callback to get the AssessmentID \r\n const [callback, status] = useAsyncCallback(async (assessmentId: string, subscriptionTeamId: string) => {\r\n await api.post(`/api/reminders/sendAllReminder`, { assessmentId: assessmentId, subscriptionTeamId: subscriptionTeamId });\r\n }, [api]);\r\n\r\n return [callback, status];\r\n}","import { useTranslation } from \"react-i18next\";\r\nimport { AssessmentType } from \"../../../api/main/models/codeOnly/AssessmentType\";\r\nimport { UserAssessmentAssignmentsListBase } from \"../UserAssessmentAssignmentsListBase\";\r\n\r\n/**\r\n * List of actual assessments assigned to a user/team.\r\n */\r\nexport const UserAssessmentAssignmentsList = () => {\r\n const { t } = useTranslation();\r\n\r\n return (\r\n \r\n );\r\n};","import { RouteEntry } from \"../../../shared/routes\";\r\nimport { IdentityRoles } from \"../../../configure/security/IdentityRoles\";\r\nimport { UserAssessmentAssignmentsList } from \"./UserAssessmentAssignmentsList\";\r\n\r\nexport const userAssessmentAssignmentRoutes: Array = [\r\n { path: '/manage/teams/details/:subscriptionTeamId/assessments', exact: true, component: UserAssessmentAssignmentsList, authorize: true, requireRole: IdentityRoles.DriverManagement },\r\n\r\n { path: '/manage/drivers/details/:profileId/assessments', exact: true, component: UserAssessmentAssignmentsList, authorize: true, requireRole: IdentityRoles.DriverManagement },\r\n { path: '/manage/managers/details/:profileId/assessments', exact: true, component: UserAssessmentAssignmentsList, authorize: true, requireRole: IdentityRoles.DriverManagement },\r\n\r\n { path: '/administration/administrators/details/:profileId/assessments', exact: true, component: UserAssessmentAssignmentsList, authorize: true, requireRole: IdentityRoles.DriverManagement },\r\n];\r\n","import { useTranslation } from \"react-i18next\";\r\nimport { AssessmentType } from \"../../../api/main/models/codeOnly/AssessmentType\";\r\nimport { UserAssessmentAssignmentsListBase } from \"../UserAssessmentAssignmentsListBase\";\r\n\r\n/**\r\n * List of training modules (using the assessments model) for a user/team.\r\n */\r\nexport const UserAssessmentTrainingModuleAssignmentsList = () => {\r\n const { t } = useTranslation();\r\n\r\n return (\r\n \r\n );\r\n};","import { RouteEntry } from \"../../../shared/routes\";\r\nimport { IdentityRoles } from \"../../../configure/security/IdentityRoles\";\r\nimport { UserAssessmentTrainingModuleAssignmentsList } from \"./UserAssessmentTrainingModuleAssignmentsList\";\r\n\r\nexport const userTrainingModuleAssessmentAssignmentsRoutes: Array = [\r\n { path: '/manage/teams/details/:subscriptionTeamId/training', exact: true, component: UserAssessmentTrainingModuleAssignmentsList, authorize: true, requireRole: IdentityRoles.DriverManagement },\r\n\r\n { path: '/manage/drivers/details/:profileId/training', exact: true, component: UserAssessmentTrainingModuleAssignmentsList, authorize: true, requireRole: IdentityRoles.DriverManagement },\r\n { path: '/manage/managers/details/:profileId/training', exact: true, component: UserAssessmentTrainingModuleAssignmentsList, authorize: true, requireRole: IdentityRoles.DriverManagement },\r\n\r\n { path: '/administration/administrators/details/:profileId/training', exact: true, component: UserAssessmentTrainingModuleAssignmentsList, authorize: true, requireRole: IdentityRoles.DriverManagement },\r\n];\r\n","import { useMutation } from \"@apollo/react-hooks\";\r\nimport { useAsyncCallback } from 'react-use-async-callback';\r\nimport gql from \"graphql-tag\";\r\nimport { AsyncActionStatus } from '../../../shared/abstractStore';\r\nimport { AssessmentSessionCreateInput } from '../generated/globalTypes';\r\nimport { createAssessmentSessionMutation, createAssessmentSessionMutationVariables } from '../generated/createAssessmentSessionMutation';\r\nimport { assessmentSessionFieldsFragment } from '../models/AssessmentSession';\r\n\r\n/**\r\n * Get a callback to create a AssessmentSession in the store.\r\n */\r\nexport function useCreateAssessmentSessionCallback(): [(model: AssessmentSessionCreateInput) => Promise, AsyncActionStatus] {\r\n const [mutationAction, { error }] = useMutation(\r\n gql`\r\n mutation createAssessmentSessionMutation ($model: AssessmentSessionCreateInput!) {\r\n createAssessmentSession(model: $model) {\r\n ...assessmentSessionFields\r\n }\r\n }\r\n\r\n ${assessmentSessionFieldsFragment}\r\n `\r\n );\r\n\r\n // Wrap the mutation in a standard callback.\r\n const [action, { isExecuting, errors: actionErrors }] = useAsyncCallback(async (model: AssessmentSessionCreateInput) => {\r\n const result = await mutationAction({ variables: { model: model } });\r\n if (result.errors && result.errors.length) {\r\n throw result.errors;\r\n }\r\n }, [mutationAction]);\r\n\r\n return [action, { isExecuting: isExecuting, errors: error ? error.message : actionErrors }];\r\n}\r\n","import { useMutation } from \"@apollo/react-hooks\";\r\nimport { useAsyncCallback } from 'react-use-async-callback';\r\nimport gql from \"graphql-tag\";\r\nimport { AsyncActionStatus } from '../../../shared/abstractStore';\r\nimport { AssessmentSessionUpdateInput } from '../generated/globalTypes';\r\nimport { updateAssessmentSessionMutation, updateAssessmentSessionMutationVariables } from '../generated/updateAssessmentSessionMutation';\r\nimport { assessmentSessionFieldsFragment } from '../models/AssessmentSession';\r\n\r\n/**\r\n * Get a callback to update a AssessmentSession in the store.\r\n */\r\nexport function useUpdateAssessmentSessionCallback(): [(id: string, model: AssessmentSessionUpdateInput) => Promise, AsyncActionStatus] {\r\n const [mutationAction, { error }] = useMutation(\r\n gql`\r\n mutation updateAssessmentSessionMutation ($model: AssessmentSessionUpdateInput!) {\r\n updateAssessmentSession(model: $model) {\r\n ...assessmentSessionFields\r\n }\r\n }\r\n\r\n ${assessmentSessionFieldsFragment}\r\n `\r\n );\r\n\r\n // Wrap the mutation in a standard callback.\r\n const [action, { isExecuting, errors: actionErrors }] = useAsyncCallback(async (id: string, model: AssessmentSessionUpdateInput) => {\r\n const result = await mutationAction({ variables: { model: { ...model, id: id } } });\r\n if (result.errors && result.errors.length) {\r\n throw result.errors;\r\n }\r\n }, [mutationAction]);\r\n\r\n return [action, { isExecuting: isExecuting, errors: error ? error.message : actionErrors }];\r\n}\r\n","import { useMutation } from \"@apollo/react-hooks\";\r\nimport { useAsyncCallback } from 'react-use-async-callback';\r\nimport gql from \"graphql-tag\";\r\nimport { AsyncActionStatus } from '../../../shared/abstractStore';\r\nimport { QuestionResponseEventCreateInput } from '../generated/globalTypes';\r\nimport { createQuestionResponseEventMutation, createQuestionResponseEventMutationVariables } from '../generated/createQuestionResponseEventMutation';\r\nimport { questionResponseEventFieldsFragment } from '../models/QuestionResponseEvent';\r\n\r\n/**\r\n * Get a callback to create a QuestionResponseEvent in the store.\r\n */\r\nexport function useCreateQuestionResponseEventCallback(): [(model: QuestionResponseEventCreateInput) => Promise, AsyncActionStatus] {\r\n const [mutationAction, { error }] = useMutation(\r\n gql`\r\n mutation createQuestionResponseEventMutation ($model: QuestionResponseEventCreateInput!) {\r\n createQuestionResponseEvent(model: $model) {\r\n ...questionResponseEventFields\r\n }\r\n }\r\n\r\n ${questionResponseEventFieldsFragment}\r\n `\r\n );\r\n\r\n // Wrap the mutation in a standard callback.\r\n const [action, { isExecuting, errors: actionErrors }] = useAsyncCallback(async (model: QuestionResponseEventCreateInput) => {\r\n const result = await mutationAction({ variables: { model: model } });\r\n if (result.errors && result.errors.length) {\r\n throw result.errors;\r\n }\r\n }, [mutationAction]);\r\n\r\n return [action, { isExecuting: isExecuting, errors: error ? error.message : actionErrors }];\r\n}\r\n","import { useMutation } from \"@apollo/react-hooks\";\r\nimport { useAsyncCallback } from 'react-use-async-callback';\r\nimport gql from \"graphql-tag\";\r\nimport { AsyncActionStatus } from '../../../shared/abstractStore';\r\nimport { QuestionResponseEventUpdateInput } from '../generated/globalTypes';\r\nimport { updateQuestionResponseEventMutation, updateQuestionResponseEventMutationVariables } from '../generated/updateQuestionResponseEventMutation';\r\nimport { questionResponseEventFieldsFragment } from '../models/QuestionResponseEvent';\r\n\r\n/**\r\n * Get a callback to update a QuestionResponseEvent in the store.\r\n */\r\nexport function useUpdateQuestionResponseEventCallback(): [(id: string, model: QuestionResponseEventUpdateInput) => Promise, AsyncActionStatus] {\r\n const [mutationAction, { error }] = useMutation(\r\n gql`\r\n mutation updateQuestionResponseEventMutation ($model: QuestionResponseEventUpdateInput!) {\r\n updateQuestionResponseEvent(model: $model) {\r\n ...questionResponseEventFields\r\n }\r\n }\r\n\r\n ${questionResponseEventFieldsFragment}\r\n `\r\n );\r\n\r\n // Wrap the mutation in a standard callback.\r\n const [action, { isExecuting, errors: actionErrors }] = useAsyncCallback(async (id: string, model: QuestionResponseEventUpdateInput) => {\r\n const result = await mutationAction({ variables: { model: { ...model, id: id } } });\r\n if (result.errors && result.errors.length) {\r\n throw result.errors;\r\n }\r\n }, [mutationAction]);\r\n\r\n return [action, { isExecuting: isExecuting, errors: error ? error.message : actionErrors }];\r\n}\r\n","/**\r\n * Subsitute the special placeholders in the feedback HTML.\r\n * @param html\r\n */\r\nexport function subsitutePlaceholders(value: string, subsitutions: {[key: string]: any}): string {\r\n let ret = value;\r\n\r\n for (const key in subsitutions) {\r\n const keyValue = subsitutions[key];\r\n ret = ret.replace('{' + key + '}', keyValue);\r\n }\r\n\r\n return ret;\r\n}","import { useEffect, useMemo, useState } from \"react\";\r\nimport { ConditionalFragment } from \"react-conditionalfragment\";\r\nimport { useTranslation } from \"react-i18next\";\r\nimport { BlobReference } from \"../../../../api/main/models/BlobReference\";\r\nimport { Question } from \"../../../../api/main/models/Question\";\r\nimport { QuestionFeedback } from \"../../../../api/main/models/QuestionFeedback\";\r\nimport { HtmlDisplay } from \"../../../../shared/htmlEditor\";\r\nimport { subsitutePlaceholders } from \"../../../../utilities/subsitutePlaceholders\";\r\nimport { QuestionScore } from \"../utilities/calculateQuestionScore\";\r\n\r\nexport interface ShowQuestionFeedbackProps {\r\n model: Question,\r\n feedbacks: Array,\r\n blobReferences: Array,\r\n\r\n questionScore: QuestionScore,\r\n\r\n // Event raised when a question has been completed.\r\n onPageComplete: () => void,\r\n}\r\n\r\n/**\r\n * Show feedback for an individual question for an executing assessments.\r\n * @param props\r\n */\r\nexport const ShowQuestionFeedback = (props: ShowQuestionFeedbackProps) => {\r\n const {\r\n questionScore,\r\n feedbacks,\r\n blobReferences,\r\n onPageComplete,\r\n } = props;\r\n\r\n const { t } = useTranslation();\r\n\r\n // Work out which feedback to show.\r\n const { activeFeedback } = useMemo(() => {\r\n // Calculate the question score.\r\n // Find the best feedback for the total score.\r\n const activeFeedback = feedbacks.find(item => item.minScore <= questionScore.score && questionScore.score <= item.maxScore);\r\n return {\r\n activeFeedback,\r\n };\r\n }, [feedbacks, questionScore]);\r\n\r\n\r\n const videoBlob = useMemo(() => blobReferences.find(it => it.id === activeFeedback?.videoBlobReferenceId), [blobReferences, activeFeedback]);\r\n const imageBlob = useMemo(() => blobReferences.find(it => it.id === activeFeedback?.imageBlobReferenceId), [blobReferences, activeFeedback]);\r\n\r\n // Some calls to apis (such as saving clicks) will cause us to generate a new secure video URL. To make sure this doesn't reset out\r\n // video we cache the poster and video urls as we original receive them into our state and always use them.\r\n const [imageUrl] = useState(imageBlob?.url ?? '');\r\n const [videoUrl] = useState(videoBlob?.url ?? '');\r\n\r\n // Replace placeholders in the feedback HTML.\r\n const feedbackHtml = useMemo(() => {\r\n let ret = activeFeedback?.feedbackText ?? '';\r\n\r\n ret = subsitutePlaceholders(\r\n ret,\r\n {\r\n ...questionScore,\r\n }\r\n );\r\n\r\n return ret;\r\n }, [activeFeedback, questionScore]);\r\n\r\n // Reading of feedback is optional so we are complete as soon as we're shown.\r\n useEffect(() => {\r\n onPageComplete();\r\n }, [onPageComplete]);\r\n\r\n // If we have no feedback, show a default page that just tells the user their score.\r\n if (!activeFeedback) {\r\n return (\r\n
\r\n

{t('showQuestionFeedback.defaultFeedback.heading', 'No feedback available for this question')}

\r\n

\r\n {t('showQuestionFeedback.defaultFeedback.text', 'Sorry there is no feedback available for you on this question')}\r\n

\r\n
\r\n );\r\n }\r\n\r\n // Otherwise show the real feedback.\r\n return (\r\n
\r\n {/* Show video feedback if we have it. */}\r\n \r\n
\r\n \r\n \r\n
\r\n
\r\n\r\n {/* Show image feedback if we have it (and don't have a video) */}\r\n \r\n \"Feedback\"\r\n \r\n\r\n
\r\n \r\n
\r\n
\r\n );\r\n};","import { ReactNode, useCallback, useEffect, useMemo, useState } from \"react\";\r\nimport { ConditionalFragment } from \"react-conditionalfragment\";\r\nimport { useTranslation } from \"react-i18next\";\r\nimport { Button, Card, CardBody, CardHeader, Col, ListGroup, ListGroupItem, Modal, ModalBody, ModalHeader, Row } from \"reactstrap\";\r\nimport { Assessment } from \"../../../api/main/models/Assessment\";\r\nimport { AssessmentFeedback } from \"../../../api/main/models/AssessmentFeedback\";\r\nimport { AssessmentSession } from \"../../../api/main/models/AssessmentSession\";\r\nimport { BlobReference } from \"../../../api/main/models/BlobReference\";\r\nimport { AssessmentType } from \"../../../api/main/models/codeOnly/AssessmentType\";\r\nimport { FeedbackStyle } from \"../../../api/main/models/codeOnly/FeedbackStyle\";\r\nimport { getQuestionTypeCategory, QuestionType, QuestionTypeCategory, questionTypeDisplayName } from \"../../../api/main/models/codeOnly/QuestionType\";\r\nimport { DriverMetric } from \"../../../api/main/models/DriverMetric\";\r\nimport { Question } from \"../../../api/main/models/Question\";\r\nimport { QuestionFeedback } from \"../../../api/main/models/QuestionFeedback\";\r\nimport { QuestionResponseEvent } from \"../../../api/main/models/QuestionResponseEvent\";\r\nimport { Subscription } from \"../../../api/main/models/Subscription\";\r\nimport { RiskRules } from \"../../../services/OverallRiskService\";\r\nimport { HtmlDisplay } from \"../../../shared/htmlEditor\";\r\nimport { subsitutePlaceholders } from \"../../../utilities/subsitutePlaceholders\";\r\nimport { ShowQuestionFeedback } from \"./feedback/ShowQuestionFeedback\";\r\nimport { LaunchAssessmentPage } from \"./LaunchAssessmentBase\";\r\nimport { ScoreProgressBar } from \"./progress/ScoreProgressBar\";\r\nimport { AssessmentScore } from \"./utilities/calculateAssessmentScore\";\r\nimport { QuestionScore } from \"./utilities/calculateQuestionScore\";\r\nimport { questionScoreFromNumber } from \"./utilities/questionScoreFromNumber\";\r\nimport { launchAssessmentSessionViewModelQuery_viewModel_questionSequenceQuestions } from \"../../../api/main/generated/launchAssessmentSessionViewModelQuery\"\r\n\r\nexport interface FinishPageProps {\r\n model: AssessmentSession | undefined | null,\r\n assessment: Assessment | undefined | null,\r\n feedbacks: Array,\r\n blobReferences: Array,\r\n activeAssessmentType: AssessmentType,\r\n totalScore: AssessmentScore,\r\n calculateQuestionScore: (responses: Array, riskRules?: RiskRules) => QuestionScore,\r\n\r\n exceedsSuspiciousLimit: boolean,\r\n\r\n // Event raised when a page has been completed.\r\n onPageComplete: () => void,\r\n\r\n questions: Array,\r\n questionFeedbacks: Array,\r\n questionResponseEvents: Array,\r\n\r\n pages: Array,\r\n driverMetrics: Array,\r\n subscription: Subscription | undefined | null,\r\n allCurrentQuestionSequence: Array | undefined,\r\n\r\n finishPageFeedbackStyle: FeedbackStyle | undefined | null,\r\n}\r\n\r\n\r\n/**\r\n * Show a question for an executing assessments.\r\n * @param props\r\n */\r\nexport const FinishPage = (props: FinishPageProps) => {\r\n const {\r\n assessment,\r\n feedbacks,\r\n blobReferences,\r\n onPageComplete,\r\n totalScore,\r\n calculateQuestionScore,\r\n\r\n exceedsSuspiciousLimit,\r\n\r\n questions,\r\n questionFeedbacks,\r\n questionResponseEvents,\r\n\r\n pages,\r\n driverMetrics,\r\n subscription,\r\n allCurrentQuestionSequence,\r\n\r\n finishPageFeedbackStyle,\r\n } = props;\r\n\r\n const { t } = useTranslation();\r\n\r\n // Work out which feedback to show.\r\n const { activeFeedback } = useMemo(() => {\r\n // Find the best feedback for the total score.\r\n const activeFeedback = feedbacks.find(item => item.minTotalScore <= totalScore.score && totalScore.score <= item.maxTotalScore);\r\n return {\r\n activeFeedback,\r\n };\r\n }, [totalScore, feedbacks]);\r\n\r\n const videoBlob = useMemo(() => blobReferences.find(it => it.id === activeFeedback?.videoBlobReferenceId), [blobReferences, activeFeedback]);\r\n const imageBlob = useMemo(() => blobReferences.find(it => it.id === activeFeedback?.imageBlobReferenceId), [blobReferences, activeFeedback]);\r\n\r\n // Some calls to apis (such as saving clicks) will cause us to generate a new secure video URL. To make sure this doesn't reset out\r\n // video we cache the poster and video urls as we original receive them into our state and always use them.\r\n const [imageUrl] = useState(imageBlob?.url ?? '');\r\n const [videoUrl] = useState(videoBlob?.url ?? '');\r\n\r\n // Replace placeholders in the feedback HTML.\r\n const feedbackHtml = useMemo(() => {\r\n let ret = activeFeedback?.feedbackText ?? '';\r\n\r\n ret = subsitutePlaceholders(\r\n ret,\r\n {\r\n ...totalScore,\r\n }\r\n );\r\n\r\n return ret;\r\n }, [activeFeedback, totalScore]);\r\n\r\n // We will show individual quesiton feedback in a popup modal.\r\n const [showingFeedbackForQuestion, setShowingFeedbackForQuestion] = useState(undefined);\r\n const questionFeedbackModalIsOpen = !!showingFeedbackForQuestion;\r\n const closeQuestionFeedbackModal = useCallback(() => setShowingFeedbackForQuestion(undefined), [setShowingFeedbackForQuestion]);\r\n const openQuestionFeedbackModal = useCallback((question: Question) => setShowingFeedbackForQuestion(question), [setShowingFeedbackForQuestion]);\r\n\r\n // Find all the used driver metrics, and page questions into them.\r\n // We want these to appear in the order of the first page within each group.\r\n const driverMetricPageGroups = useMemo(() => {\r\n let ret: Array<{\r\n driverMetric: DriverMetric | null,\r\n pages: Array,\r\n groupScore: QuestionScore,\r\n }> = [];\r\n\r\n for (const page of pages) {\r\n // We only show results for question pages.\r\n if (page.pageType !== 'question') {\r\n continue;\r\n }\r\n\r\n // Get the question for the page.\r\n const question = questions.find(it => it.id === page.questionId);\r\n if (!question) {\r\n continue;\r\n }\r\n\r\n const questionTypeCategory = getQuestionTypeCategory(question.questionType as QuestionType);\r\n if (questionTypeCategory !== QuestionTypeCategory.Question && questionTypeCategory !== QuestionTypeCategory.Questionnaire) {\r\n continue;\r\n }\r\n\r\n //if we are checking a questionnaire we need to use the questionnaire questions\r\n if (question.questionType === \"Questionnaire\") {\r\n\r\n //filter the sequence questions for only questions from this questionnaire\r\n const questionnaireQuestions = allCurrentQuestionSequence?.filter(item => item.parentQuestionId === question.id && !item.archived);\r\n\r\n questionnaireQuestions?.forEach(item => {\r\n\r\n if (item.childQuestion.questionType === \"QuestionnaireInput\") {\r\n return;\r\n }\r\n\r\n const driverMetric = driverMetrics.find(it => it.id === item.childQuestion.driverMetricId) ?? null;\r\n\r\n // Lookup if we already have an entry for this driver metric, if not create one.\r\n let entry = ret.find(it => it.driverMetric === driverMetric);\r\n if (!entry) {\r\n const metricScore = totalScore.driverMetricBreakdown.find(it => it.driverMetricId === (driverMetric?.id ?? null))?.score\r\n ?? questionScoreFromNumber(0, false, subscription);\r\n\r\n entry = {\r\n driverMetric: driverMetric,\r\n pages: [],\r\n groupScore: metricScore,\r\n };\r\n ret.push(entry);\r\n }\r\n\r\n // Add this page to the entry.\r\n entry.pages.push(page);\r\n })\r\n }\r\n else {\r\n\r\n // Find the driver metric (which may be null).\r\n const driverMetric = driverMetrics.find(it => it.id === question.driverMetricId) ?? null;\r\n\r\n // Lookup if we already have an entry for this driver metric, if not create one.\r\n let entry = ret.find(it => it.driverMetric === driverMetric);\r\n if (!entry) {\r\n const metricScore = totalScore.driverMetricBreakdown.find(item => item.driverMetricId === (driverMetric?.id ?? null))?.score\r\n ?? questionScoreFromNumber(0, false, subscription);\r\n\r\n entry = {\r\n driverMetric: driverMetric,\r\n pages: [],\r\n groupScore: metricScore,\r\n };\r\n ret.push(entry);\r\n }\r\n\r\n // Add this page to the entry.\r\n entry.pages.push(page);\r\n }\r\n }\r\n\r\n return ret;\r\n }, [questions, driverMetrics, subscription, totalScore, pages, allCurrentQuestionSequence]);\r\n\r\n // Reading of feedback is optional so we are complete as soon as we're shown.\r\n useEffect(() => {\r\n onPageComplete();\r\n }, [onPageComplete]);\r\n\r\n // Show the feedback.\r\n return (\r\n
\r\n {/* Show video feedback if we have it. */}\r\n \r\n
\r\n \r\n \r\n
\r\n
\r\n\r\n {/* Show image feedback if we have it (and don't have a video) */}\r\n \r\n \"Feedback\"\r\n \r\n\r\n
\r\n \r\n
\r\n\r\n {/* If the user has answered too many answers suspiciously, show the text from the assessment */}\r\n \r\n \r\n \r\n\r\n {/* Let the user review feedback for each question. */}\r\n \r\n

\r\n {t('finishPage.questionScores.heading', 'Here\\'s what you scored in each area')}\r\n

\r\n
\r\n {\r\n driverMetricPageGroups.map(group => (\r\n \r\n \r\n \r\n \r\n
\r\n {group.driverMetric?.name ?? t('finishPage.groups.generalQuestions', 'General and practice questions')}\r\n
\r\n \r\n {/* Show a subtotal, except on the genreal questions group. */}\r\n \r\n \r\n \r\n \r\n \r\n
\r\n
\r\n \r\n \r\n {\r\n pages.map((page, index) => {\r\n // If page is not part of this group, skip it.\r\n // NOTE we do it this way rather than looping over group.pages because we want to\r\n // maintain consistant screen numbersa across the groups and this combined with index is an easy way to do that.\r\n if (!group.pages.find(it => it === page)) {\r\n return null;\r\n }\r\n\r\n // Grab the related question.\r\n const question = questions.find(it => it.id === page.questionId);\r\n if (!question) {\r\n return null;\r\n }\r\n\r\n // If the question type isn't scored, then skip it.\r\n const questionTypeCategory = getQuestionTypeCategory(question.questionType as QuestionType);\r\n if (questionTypeCategory !== QuestionTypeCategory.Question\r\n && questionTypeCategory !== QuestionTypeCategory.Questionnaire\r\n ) {\r\n return null;\r\n }\r\n\r\n // Generate all the result progress bars for this quesiton (as some have more than one subquestion).\r\n let subQuestionProgressBars: Array = [];\r\n\r\n if (questionTypeCategory === QuestionTypeCategory.Questionnaire) {\r\n // Subquestions in a questionnaire are questionnaire questions so loop through each one.\r\n const myQuestionnaireQuestions = allCurrentQuestionSequence?.filter(item => item.parentQuestionId === question.id);\r\n let questionnaireQuestionNumber = 1;\r\n for (const questionnaireQuestion of myQuestionnaireQuestions!) {\r\n // If this questionnaire question isn't for the current drive metric, skip it.\r\n if (questionnaireQuestion.childQuestion.driverMetricId !== group.driverMetric?.id) {\r\n ++questionnaireQuestionNumber;\r\n continue;\r\n }\r\n\r\n // If we get here then questionnaire question is for this driver metric, so lets make a progress bar.\r\n //\r\n\r\n // Get the score for this questionnaire question.\r\n const score = totalScore.questionBreakdown.find(item => item.questionId === questionnaireQuestion.childQuestionId)?.score\r\n ?? questionScoreFromNumber(0, false, subscription);\r\n\r\n // Create a bar.\r\n subQuestionProgressBars.push(\r\n \r\n 1}>\r\n
\r\n {t('finishPage.questionProgressBars.questionHeading', 'Question {{value}}', { value: questionnaireQuestionNumber })}\r\n
\r\n
\r\n \r\n \r\n );\r\n\r\n ++questionnaireQuestionNumber;\r\n }\r\n } else {\r\n // Subquestions for questions are controlled by quesiton.numberOfSubQuestions so loop around for each of those.\r\n for (let subQuestionNumber = 1; subQuestionNumber <= question.numberOfSubQuestions; ++subQuestionNumber) {\r\n const score = totalScore.questionBreakdown.find(item => item.questionId === question.id && item.subQuestionNumber === subQuestionNumber)?.score\r\n ?? questionScoreFromNumber(0, false, subscription);\r\n\r\n subQuestionProgressBars.push(\r\n \r\n 1}>\r\n
\r\n {t('finishPage.questionProgressBars.partHeading', 'Part {{value}}', { value: subQuestionNumber })}\r\n
\r\n
\r\n \r\n \r\n );\r\n }\r\n }\r\n\r\n // Return the completed UI.\r\n return (\r\n \r\n \r\n \r\n {t('finishPage.screenNumber', 'Screen {{screenNumber}}', { screenNumber: index + 1 })}\r\n \r\n \r\n

\r\n {questionTypeDisplayName(question.questionType as QuestionType, t)}\r\n\r\n { /*If we have an image or video related to the question, show the question name (aka video/image name)*/ }\r\n \r\n : {question.name}\r\n \r\n

\r\n \r\n \r\n {subQuestionProgressBars}\r\n
\r\n
\r\n );\r\n })\r\n }\r\n
\r\n
\r\n
\r\n ))\r\n }\r\n
\r\n
\r\n\r\n \r\n closeQuestionFeedbackModal()} size=\"xl\">\r\n closeQuestionFeedbackModal()}>\r\n {\r\n t('finishPage.questionFeedbackModal.heading', 'Feedback for the question')\r\n }\r\n \r\n \r\n it.questionId === showingFeedbackForQuestion?.id)}\r\n blobReferences={blobReferences}\r\n questionScore={calculateQuestionScore(questionResponseEvents.filter(item => item.questionId === showingFeedbackForQuestion?.id && item.archived === false)!)}\r\n onPageComplete={() => {/* Do nothing */}}\r\n />\r\n \r\n \r\n \r\n
\r\n );\r\n};","import { useEffect, useMemo, useState } from \"react\";\r\nimport { HtmlDisplay } from \"../../../../../shared/htmlEditor\";\r\nimport { ShowQuestionChildProps } from \"../ShowQuestion\";\r\n\r\n/**\r\n * Running of a LearningImage question.\r\n * @param props\r\n */\r\nexport const ShowQuestionLearningImage = (props: ShowQuestionChildProps) => {\r\n const {\r\n model,\r\n blobReferences,\r\n\r\n onPageComplete,\r\n } = props;\r\n\r\n const imageBlob = useMemo(() => blobReferences.find(it => it.id === model.imageBlobReferenceId), [blobReferences, model]);\r\n\r\n // Some calls to apis (such as saving clicks) will cause us to generate a new secure video URL. To make sure this doesn't reset out\r\n // video we cache the poster and video urls as we original receive them into our state and always use them.\r\n const [imageUrl] = useState(imageBlob?.url ?? '');\r\n\r\n // There is no end event for this type of learning so we are complete as soon as we're shown.\r\n useEffect(() => {\r\n onPageComplete();\r\n }, [onPageComplete]);\r\n\r\n return (\r\n
\r\n \"Feedback\"\r\n\r\n
\r\n \r\n
\r\n
\r\n );\r\n};","import { useEffect } from \"react\";\r\nimport { HtmlDisplay } from \"../../../../../shared/htmlEditor\";\r\nimport { ShowQuestionChildProps } from \"../ShowQuestion\";\r\n\r\n/**\r\n * Running of a LearningText question.\r\n * @param props\r\n */\r\nexport const ShowQuestionLearningText = (props: ShowQuestionChildProps) => {\r\n const {\r\n model,\r\n onPageComplete,\r\n } = props;\r\n\r\n // There is no end event for this type of learning so we are complete as soon as we're shown.\r\n useEffect(() => {\r\n onPageComplete();\r\n }, [onPageComplete]);\r\n\r\n return (\r\n
\r\n
\r\n \r\n
\r\n
\r\n );\r\n};","import { FontAwesomeIcon } from \"@fortawesome/react-fontawesome\";\r\nimport { useCallback, useMemo, useRef, useState } from \"react\";\r\nimport { ConditionalFragment } from \"react-conditionalfragment\";\r\nimport { useTranslation } from \"react-i18next\";\r\nimport { Button, Col, Row } from \"reactstrap\";\r\nimport { HtmlDisplay } from \"../../../../../shared/htmlEditor\";\r\nimport { ShowQuestionChildProps } from \"../ShowQuestion\";\r\nimport \"./showQuestionLearningVideo.scss\";\r\n\r\n/**\r\n * Running of a LearningVideo question.\r\n * @param props\r\n */\r\nexport const ShowQuestionLearningVideo = (props: ShowQuestionChildProps) => {\r\n const {\r\n model,\r\n blobReferences,\r\n\r\n onPageComplete,\r\n } = props;\r\n\r\n const { t } = useTranslation();\r\n\r\n const videoBlob = useMemo(() => blobReferences.find(it => it.id === model.videoBlobReferenceId), [blobReferences, model]);\r\n const imageBlob = useMemo(() => blobReferences.find(it => it.id === model.imageBlobReferenceId), [blobReferences, model]);\r\n\r\n // Keep track of if the video has started/finished or not.\r\n const videoRef = useRef(null);\r\n const [hasVideoStarted, setHasVideoStarted] = useState(false);\r\n const [hasVideoFinished, setHasVideoFinished] = useState(false);\r\n\r\n // Some calls to apis (such as saving clicks) will cause us to generate a new secure video URL. To make sure this doesn't reset out\r\n // video we cache the poster and video urls as we original receive them into our state and always use them.\r\n const [imageUrl] = useState(imageBlob?.url ?? '');\r\n const [videoUrl] = useState(videoBlob?.url ?? '');\r\n\r\n // Start the video.\r\n const startVideo = useCallback(() => {\r\n setHasVideoStarted(true);\r\n videoRef.current?.play();\r\n }, [videoRef, setHasVideoStarted]);\r\n\r\n // Video has ended.\r\n const onVideoEnded = useCallback(() => {\r\n setHasVideoFinished(true);\r\n\r\n // Page is complete once learning video has been watched.\r\n onPageComplete();\r\n }, [setHasVideoFinished, onPageComplete]);\r\n \r\n return (\r\n
\r\n\r\n {/* Video has not started */}\r\n \r\n
\r\n
startVideo()}\r\n >\r\n \r\n \r\n \r\n \r\n
\r\n \r\n
\r\n\r\n \r\n

\r\n {t('showQuestionLearningVideo.playText', 'Press play to start the video.')}\r\n

\r\n \r\n \r\n \r\n
\r\n
\r\n
\r\n
\r\n\r\n
\r\n onVideoEnded()}\r\n >\r\n \r\n
\r\n\r\n {/* Video has finished */}\r\n \r\n
\r\n
\r\n
\r\n \r\n
\r\n\r\n
\r\n \r\n
\r\n\r\n

\r\n {t('showQuestionLearningVideo.endText', 'Press Next to continue.')}\r\n

\r\n
\r\n
\r\n
\r\n
\r\n );\r\n};","/**\r\n * Class that prefetches and manages images as blob URLs.\r\n */\r\nexport class ImagePrefetcher {\r\n private _blobs: { [key: string]: CachedImage | undefined } = {};\r\n\r\n /**\r\n * Prefetch an image and add it to the cache.\r\n * @param url\r\n */\r\n async cacheImage(url: string) {\r\n // If we already have an existing cache record for this url, do nothing.\r\n const existing = this._blobs[url];\r\n if (existing) {\r\n return;\r\n }\r\n\r\n // Create a cached record as a placeholder.\r\n let cacheRecord: CachedImage = {\r\n originalUrl: url,\r\n cachedBlobUrl: undefined,\r\n isLoading: true,\r\n };\r\n this._blobs[url] = cacheRecord;\r\n\r\n // Fetch the image.\r\n const result = await fetch(url);\r\n\r\n // Convert the fetched image into a blob.\r\n const blob = await result.blob();\r\n\r\n // Create a blob URL from the results.\r\n const blobUrl = URL.createObjectURL(blob);\r\n\r\n // Update the cached record.\r\n cacheRecord.cachedBlobUrl = blobUrl;\r\n this._blobs[url] = cacheRecord;\r\n }\r\n\r\n /**\r\n * Remove the cached image from the cache.\r\n * @param url\r\n */\r\n removeImage(url: string) {\r\n // Lookup the cached record.\r\n const cacheRecord = this._blobs[url];\r\n if (!cacheRecord) {\r\n return;\r\n }\r\n\r\n // Revoke the blob url object.\r\n if (cacheRecord.cachedBlobUrl) {\r\n URL.revokeObjectURL(cacheRecord?.cachedBlobUrl);\r\n }\r\n\r\n // Remove the cache record.\r\n this._blobs[url] = undefined;\r\n }\r\n\r\n /**\r\n * Returns true if this url has a ready cached item to use.\r\n * @param url\r\n */\r\n isCached(url: string): boolean {\r\n const cacheRecord = this._blobs[url];\r\n if (cacheRecord?.cachedBlobUrl) {\r\n return true;\r\n }\r\n\r\n return false;\r\n }\r\n\r\n /**\r\n * Returns true if this url is currently loading into the cache.\r\n * @param url\r\n */\r\n isLoading(url: string): boolean {\r\n const cacheRecord = this._blobs[url];\r\n return !!cacheRecord?.isLoading;\r\n }\r\n\r\n /**\r\n * Returns the best url to use with the following rules:\r\n * 1. If we have a cached blob URL for this item, we return that.\r\n * 2. Otherwise we return the url unchanged.\r\n * @param url\r\n */\r\n urlFor(url: string): string {\r\n const cacheRecord = this._blobs[url];\r\n return cacheRecord?.cachedBlobUrl ?? url;\r\n }\r\n}\r\n\r\n/**\r\n * An entry in the ImagePrefetcher cache.\r\n */\r\ninterface CachedImage {\r\n originalUrl: string,\r\n cachedBlobUrl: string | undefined,\r\n isLoading: boolean,\r\n}\r\n","import { useCallback, useEffect, useState } from \"react\";\r\nimport { ImagePrefetcher } from \".\";\r\n\r\n/**\r\n * Prefetches multiple image url and caches them for instant reuse as a blob URL.\r\n * @param url\r\n */\r\nexport function usePrefetchImages(urls: Array): (url: string) => string\r\nexport function usePrefetchImages(urls: Array): (url: string | undefined) => string\r\n{\r\n const [imagePrefetcher] = useState(() => new ImagePrefetcher());\r\n\r\n // Prefetch and cache the image if we need to.\r\n useEffect(() => {\r\n for (const url of urls) {\r\n if (!url) {\r\n continue;\r\n }\r\n\r\n if (\r\n imagePrefetcher.isCached(url)\r\n || imagePrefetcher.isLoading(url)\r\n ) {\r\n continue;\r\n }\r\n\r\n imagePrefetcher.cacheImage(url);\r\n }\r\n }, [urls, imagePrefetcher]);\r\n\r\n // Return a method to lookup a url.\r\n const resolve = useCallback((url: string | undefined) => {\r\n const ret = url ? imagePrefetcher.urlFor(url) : '';\r\n return ret;\r\n }, [imagePrefetcher]);\r\n return resolve;\r\n}","import useSound from \"use-sound\";\r\n\r\nexport function useClickSound() {\r\n return useSound(\"/audio/154953__keykrusher__microwave-beep.wav\");\r\n}","import { FontAwesomeIcon } from \"@fortawesome/react-fontawesome\";\r\nimport { useTranslation } from \"react-i18next\";\r\nimport \"./questionTimer.scss\";\r\n\r\nexport interface QuestionTimerProps {\r\n secondsRemaining: number,\r\n}\r\n\r\n/**\r\n * Component that shows a countdown from fromSeconds and calls countdownComplete when the countdown finishes.\r\n * @param props\r\n */\r\nexport const QuestionTimer = (props: QuestionTimerProps) => {\r\n const {\r\n secondsRemaining,\r\n } = props;\r\n\r\n const { t } = useTranslation();\r\n\r\n return (\r\n
\r\n {t('questionTimer.timeReamining', 'Time remaining:')}\r\n <> \r\n
\r\n \r\n <> \r\n {secondsRemaining}\r\n
\r\n
\r\n );\r\n};","import { FontAwesomeIcon } from \"@fortawesome/react-fontawesome\";\r\nimport { Guid } from \"guid-string\";\r\nimport React, { useCallback, useEffect, useMemo, useState } from \"react\";\r\nimport { ConditionalFragment } from \"react-conditionalfragment\";\r\nimport { useTranslation } from \"react-i18next\";\r\nimport { Button, ButtonGroup, Card, Col, Row } from \"reactstrap\";\r\nimport { HtmlDisplay } from \"../../../../../shared/htmlEditor\";\r\nimport { usePrefetchImages } from \"../../../../../shared/prefetchImage\";\r\nimport { ResponseWindowColor, responseWindowColors } from \"../../../../questions/edit/locationDiscriminationImage/reponseWindowColors\";\r\nimport { InteractiveImage, PointConversion } from \"../../../../shared/interactiveImage/InteractiveImage\";\r\nimport { OverlayShape, OverlayShapeType } from \"../../../../shared/interactiveImage/OverlayShape\";\r\nimport { ShowQuestionChildProps } from \"../ShowQuestion\";\r\nimport { useClickSound } from \"../useClickSound/useClickSound\";\r\nimport { QuestionTimer } from \"./QuestionTimer\";\r\nimport \"./showQuestionLocationDiscriminationImage.scss\";\r\n\r\n/**\r\n * Running of a LocationDiscriminationImage question.\r\n * @param props\r\n */\r\nexport const ShowQuestionLocationDiscriminationImage = (props: ShowQuestionChildProps) => {\r\n const {\r\n model,\r\n answers,\r\n blobReferences,\r\n\r\n addResponseEvent,\r\n cancelResponseEvent,\r\n questionResponseEventsManager,\r\n\r\n resetResponseTimeStart,\r\n calculateResponseTime,\r\n hasFailedMaximumClickRule,\r\n isMaximumClickRuleFailtureRecord,\r\n\r\n onPageComplete,\r\n } = props;\r\n\r\n const { t } = useTranslation();\r\n\r\n const imageBlob = useMemo(() => blobReferences.find(it => it.id === model.imageBlobReferenceId), [blobReferences, model]);\r\n const questionTextImageBlob = useMemo(() => blobReferences.find(it => it.id === model.questionTextImageBlobReferenceId), [blobReferences, model]);\r\n\r\n // At the end, with the question, we either want to show a specific image set to show with the question, or the original thumbnail again.\r\n const endImageBlob = questionTextImageBlob ?? imageBlob;\r\n\r\n // Keep track of if the video has started/finished or not.\r\n const [hasActivityStarted, setHasActivityStarted] = useState(false);\r\n const [hasActivityFinished, setHasActivityFinished] = useState(false);\r\n\r\n // Some calls to apis (such as saving clicks) will cause us to generate a new secure video URL. To make sure this doesn't reset out\r\n // video we cache the poster and video urls as we original receive them into our state and always use them.\r\n const [imageUrl] = useState(imageBlob?.url ?? '');\r\n const [endImageUrl] = useState(endImageBlob?.url ?? '');\r\n\r\n // Prefetch the images we use.\r\n const resolveImageUrl = usePrefetchImages([\r\n imageUrl,\r\n endImageUrl,\r\n ]);\r\n\r\n\r\n // Start the video.\r\n const startActivity = useCallback(() => {\r\n setHasActivityStarted(true);\r\n resetResponseTimeStart();\r\n }, [setHasActivityStarted, resetResponseTimeStart]);\r\n\r\n // Activity has ended.\r\n const onActivityEnded = useCallback(() => {\r\n setHasActivityFinished(true);\r\n resetResponseTimeStart();\r\n\r\n // Let the navigation know this question has been completed.\r\n onPageComplete();\r\n }, [setHasActivityFinished, resetResponseTimeStart, onPageComplete]);\r\n\r\n // Work out the discrimination groups and their associated colours.\r\n const discriminationGroups = useMemo(() => {\r\n let ret = Array<{ name: string, color: ResponseWindowColor }>();\r\n\r\n let colorIndex = 0;\r\n for (const answer of answers) {\r\n const existing = ret.find(it => it.name === answer.discriminationGroup);\r\n if (existing) {\r\n continue;\r\n }\r\n\r\n // Add a new entry.\r\n ret.push({\r\n name: answer.discriminationGroup,\r\n color: responseWindowColors[colorIndex % responseWindowColors.length],\r\n });\r\n\r\n // Move on to the next colour.\r\n ++colorIndex;\r\n }\r\n\r\n return ret;\r\n }, [answers]);\r\n\r\n // Generate overlays for each answer.\r\n const displayShapeSize = useMemo(() => ({ x: 50, y: 50 }), []);\r\n const [{ displayToVirtual }, setVirtualConversions] = useState<{ displayToVirtual: PointConversion, virtualToDisplay: PointConversion }>({\r\n displayToVirtual: point => point,\r\n virtualToDisplay: point => point,\r\n });\r\n const onVirtualConversionChanged = useCallback((conversions: { displayToVirtual: PointConversion, virtualToDisplay: PointConversion }) => {\r\n setVirtualConversions(conversions)\r\n }, [setVirtualConversions]);\r\n const shapeType: OverlayShapeType = 'circle';\r\n const overlays: Array = useMemo(() =>\r\n questionResponseEventsManager.model\r\n .filter(item => item.questionId === model.id && !item.archived)\r\n .filter(item => !isMaximumClickRuleFailtureRecord(item))\r\n .map(item => {\r\n const virtualSize = displayToVirtual(displayShapeSize);\r\n\r\n return ({\r\n id: item.id,\r\n label: '', //textFromHtml(item.answerText),\r\n x: item.clickPositionX,\r\n y: item.clickPositionY,\r\n width: virtualSize.x,\r\n height: virtualSize.y,\r\n\r\n shape: shapeType,\r\n\r\n opacity: 0.5,\r\n ...(\r\n discriminationGroups.find(it => it.name === item.discriminationGroup)?.color\r\n ?? responseWindowColors[0]\r\n ),\r\n } as OverlayShape\r\n );\r\n })\r\n , [questionResponseEventsManager.model, displayToVirtual, displayShapeSize, discriminationGroups, model, isMaximumClickRuleFailtureRecord]);\r\n\r\n\r\n // Activity playback tracking.\r\n const [addingShapeForClick, setAddingShapeForClick] = useState | null>(null);\r\n const [discriminationMenuPosition, setDiscriminationMenuPosition] = useState<{ x: number, y: number }>({ x: 0, y: 0 });\r\n const discriminationMenuMaxWidth = 200;\r\n const onResponseClickEventStarted = useCallback((shapeProps: Partial): OverlayShape => {\r\n const newItemId = Guid.newGuid();\r\n const newShapeProps = {\r\n ...shapeProps,\r\n shape: shapeType,\r\n id: newItemId,\r\n } as OverlayShape;\r\n\r\n // Store the fact we are trying to add this shape.\r\n setAddingShapeForClick(newShapeProps);\r\n\r\n // Let something be rendered.\r\n return newShapeProps;\r\n }, [setAddingShapeForClick]);\r\n\r\n const [playClickSound] = useClickSound();\r\n\r\n const onResponseClickEventFinished = useCallback((shapeProps: Partial, discriminationGroup: string): OverlayShape => {\r\n const window = answers.find(item =>\r\n item.windowLeft <= (shapeProps.x ?? 0)\r\n && (shapeProps.x ?? 0) < item.windowRight\r\n && item.windowTop <= (shapeProps.y ?? 0)\r\n && (shapeProps.y ?? 0) < item.windowBottom\r\n );\r\n\r\n // If we are outside a window, we will be applying a default score of 0.\r\n const defaultScoreOutsideOfWindow = 0;\r\n \r\n const newItemId = Guid.newGuid();\r\n addResponseEvent({\r\n id: newItemId,\r\n\r\n questionAnswerId: window?.id,\r\n score: window?.score ?? defaultScoreOutsideOfWindow,\r\n isCorrect: (window?.discriminationGroup === discriminationGroup) ?? false,\r\n responseTimeSeconds: calculateResponseTime(),\r\n discriminationGroup: discriminationGroup ?? '',\r\n\r\n clickPositionX: shapeProps.x ?? 0,\r\n clickPositionY: shapeProps.y ?? 0,\r\n });\r\n\r\n // Clear the shape thats in the process of being added as we've now added it.\r\n setAddingShapeForClick(null);\r\n\r\n // Make a click sound.\r\n playClickSound();\r\n\r\n // Return information to the interactive image so the new item can be selected automatically.\r\n return {\r\n ...shapeProps,\r\n shape: shapeType,\r\n id: newItemId,\r\n } as OverlayShape;\r\n }, [addResponseEvent, setAddingShapeForClick, answers, calculateResponseTime, playClickSound]);\r\n\r\n // Shape has been clicked.\r\n const onShapeClicked = useCallback((shape: OverlayShape) => {\r\n // When a shape is clicked, delete it as a response.\r\n cancelResponseEvent(shape.id)\r\n\r\n playClickSound();\r\n }, [cancelResponseEvent, playClickSound]);\r\n\r\n // Manage the time limit countdown.\r\n const [secondsRemaining, setSecondsRemaining] = useState(model?.timeLimitSeconds ?? 0);\r\n useEffect(() => {\r\n const timer = setInterval(() => {\r\n setSecondsRemaining(prevState => {\r\n const newState = prevState - 1;\r\n\r\n if (newState <= 0) {\r\n clearInterval(timer);\r\n onActivityEnded();\r\n }\r\n\r\n return newState;\r\n })\r\n }, 1000);\r\n\r\n // Cleanup timer if the component is unmounted.\r\n return () => clearInterval(timer);\r\n }, [setSecondsRemaining, onActivityEnded]);\r\n\r\n // Score card, used in lots of places.\r\n const ScoreCard = (props: { includeQuestionTimer?: boolean, }) => (\r\n \r\n \r\n \r\n {\r\n discriminationGroups.map(item => (\r\n \r\n \r\n {item.name}\r\n \r\n <>: \r\n {questionResponseEventsManager.model.filter(response => response.questionId === model.id && !response.archived && response.discriminationGroup === item.name && !isMaximumClickRuleFailtureRecord(response)).length}\r\n
\r\n \r\n ))\r\n }\r\n \r\n {\r\n props.includeQuestionTimer ? (\r\n \r\n ) : null\r\n }\r\n \r\n
\r\n \r\n

\r\n {t('showQuestionLocationDiscrimination.failedMaximumClickRule', 'You exceeded the maximum number of clicks for this question and will score 0% for this question.')}\r\n

\r\n
\r\n
\r\n );\r\n\r\n return (\r\n
\r\n\r\n {/* Activity has not started */}\r\n \r\n
\r\n
startActivity()}\r\n >\r\n \r\n\r\n \r\n \r\n \r\n \r\n \r\n

\r\n {t('showQuestionLocationDiscrimnationImage.playText', 'Press play to show the scene and start the activity. You will have {{timeLimitSeconds}} seconds to complete the activity.', { timeLimitSeconds: model?.timeLimitSeconds ?? 0 })}\r\n

\r\n \r\n \r\n \r\n
\r\n
\r\n
\r\n
\r\n\r\n {/* Activity has started but is not yet finished */}\r\n \r\n
setDiscriminationMenuPosition({ x: e.pageX, y: e.pageY, })}>\r\n \r\n
\r\n\r\n \r\n \r\n \r\n {\r\n discriminationGroups.map(item => (\r\n \r\n ))\r\n }\r\n \r\n
\r\n \r\n\r\n \r\n \r\n\r\n {/* Activity has finished */}\r\n \r\n
\r\n
\r\n \r\n\r\n
\r\n \r\n
\r\n\r\n

\r\n {t('showQuestionLocationDiscrimnationImage.endText', 'Press Next to continue.')}\r\n

\r\n
\r\n
\r\n
\r\n \r\n );\r\n};","import { FontAwesomeIcon } from \"@fortawesome/react-fontawesome\";\r\nimport { Guid } from \"guid-string\";\r\nimport { useCallback, useEffect, useMemo, useState } from \"react\";\r\nimport { ConditionalFragment } from \"react-conditionalfragment\";\r\nimport { useTranslation } from \"react-i18next\";\r\nimport { Card, Col, Row } from \"reactstrap\";\r\nimport { HtmlDisplay } from \"../../../../../shared/htmlEditor\";\r\nimport { usePrefetchImages } from \"../../../../../shared/prefetchImage\";\r\nimport { responseWindowColors } from \"../../../../questions/edit/locationDiscriminationImage/reponseWindowColors\";\r\nimport { InteractiveImage, PointConversion } from \"../../../../shared/interactiveImage/InteractiveImage\";\r\nimport { OverlayShape, OverlayShapeType } from \"../../../../shared/interactiveImage/OverlayShape\";\r\nimport { QuestionTimer } from \"../locationDiscriminationImage/QuestionTimer\";\r\nimport { ShowQuestionChildProps } from \"../ShowQuestion\";\r\nimport { useClickSound } from \"../useClickSound/useClickSound\";\r\nimport \"./showQuestionLocationResponseImage.scss\";\r\n\r\n/**\r\n * Running of a LocationResponseImage question.\r\n * @param props\r\n */\r\nexport const ShowQuestionLocationResponseImage = (props: ShowQuestionChildProps) => {\r\n const {\r\n model,\r\n answers,\r\n blobReferences,\r\n\r\n addResponseEvent,\r\n cancelResponseEvent,\r\n questionResponseEventsManager,\r\n\r\n resetResponseTimeStart,\r\n calculateResponseTime,\r\n hasFailedMaximumClickRule,\r\n isMaximumClickRuleFailtureRecord,\r\n\r\n onPageComplete,\r\n } = props;\r\n\r\n const { t } = useTranslation();\r\n\r\n const imageBlob = useMemo(() => blobReferences.find(it => it.id === model.imageBlobReferenceId), [blobReferences, model]);\r\n const questionTextImageBlob = useMemo(() => blobReferences.find(it => it.id === model.questionTextImageBlobReferenceId), [blobReferences, model]);\r\n\r\n // At the end, with the question, we either want to show a specific image set to show with the question, or the original thumbnail again.\r\n const endImageBlob = questionTextImageBlob ?? imageBlob;\r\n\r\n // Keep track of if the video has started/finished or not.\r\n const [hasActivityStarted, setHasActivityStarted] = useState(false);\r\n const [hasActivityFinished, setHasActivityFinished] = useState(false);\r\n\r\n // Some calls to apis (such as saving clicks) will cause us to generate a new secure video URL. To make sure this doesn't reset out\r\n // video we cache the poster and video urls as we original receive them into our state and always use them.\r\n const [imageUrl] = useState(imageBlob?.url ?? '');\r\n const [endImageUrl] = useState(endImageBlob?.url ?? '');\r\n\r\n // Prefetch the images we use.\r\n const resolveImageUrl = usePrefetchImages([\r\n imageUrl,\r\n endImageUrl,\r\n ]);\r\n\r\n // Start the video.\r\n const startActivity = useCallback(() => {\r\n setHasActivityStarted(true);\r\n resetResponseTimeStart();\r\n }, [setHasActivityStarted, resetResponseTimeStart]);\r\n\r\n // Activity has ended.\r\n const onActivityEnded = useCallback(() => {\r\n setHasActivityFinished(true);\r\n resetResponseTimeStart();\r\n\r\n // Let the navigation know this question has been completed.\r\n onPageComplete();\r\n }, [setHasActivityFinished, resetResponseTimeStart, onPageComplete]);\r\n\r\n // Generate overlays for each answer.\r\n const displayShapeSize = useMemo(() => ({ x: 50, y: 50 }), []);\r\n const [{ displayToVirtual }, setVirtualConversions] = useState<{ displayToVirtual: PointConversion, virtualToDisplay: PointConversion }>({\r\n displayToVirtual: point => point,\r\n virtualToDisplay: point => point,\r\n });\r\n const onVirtualConversionChanged = useCallback((conversions: { displayToVirtual: PointConversion, virtualToDisplay: PointConversion }) => {\r\n setVirtualConversions(conversions)\r\n }, [setVirtualConversions]);\r\n const shapeType: OverlayShapeType = 'circle';\r\n const overlays: Array = useMemo(() =>\r\n questionResponseEventsManager.model\r\n .filter(item => item.questionId === model.id && !item.archived)\r\n .filter(item => !isMaximumClickRuleFailtureRecord(item))\r\n .map(item => {\r\n const virtualSize = displayToVirtual(displayShapeSize);\r\n\r\n return ({\r\n id: item.id,\r\n label: '', //textFromHtml(item.answerText),\r\n x: item.clickPositionX,\r\n y: item.clickPositionY,\r\n width: virtualSize.x,\r\n height: virtualSize.y,\r\n\r\n shape: shapeType,\r\n\r\n opacity: 0.5,\r\n ...responseWindowColors[0],\r\n } as OverlayShape\r\n );\r\n })\r\n , [questionResponseEventsManager.model, displayToVirtual, displayShapeSize, model, isMaximumClickRuleFailtureRecord]);\r\n\r\n\r\n const [playClickSound] = useClickSound();\r\n\r\n // Activity playback tracking.\r\n const onResponseClickEvent = useCallback((shapeProps: Partial): OverlayShape => {\r\n const window = answers.find(item =>\r\n item.windowLeft <= (shapeProps.x ?? 0)\r\n && (shapeProps.x ?? 0) < item.windowRight\r\n && item.windowTop <= (shapeProps.y ?? 0)\r\n && (shapeProps.y ?? 0) < item.windowBottom\r\n );\r\n\r\n // If we are outside a window, we will be applying a default score of 0.\r\n const defaultScoreOutsideOfWindow = 0;\r\n \r\n const newItemId = Guid.newGuid();\r\n addResponseEvent({\r\n id: newItemId,\r\n\r\n questionAnswerId: window?.id,\r\n score: window?.score ?? defaultScoreOutsideOfWindow,\r\n isCorrect: window?.isCorrect ?? false,\r\n responseTimeSeconds: calculateResponseTime(),\r\n\r\n clickPositionX: shapeProps.x ?? 0,\r\n clickPositionY: shapeProps.y ?? 0,\r\n });\r\n\r\n // Play a click sound.\r\n playClickSound();\r\n\r\n // Return information to the interactive image so the new item can be selected automatically.\r\n return {\r\n ...shapeProps,\r\n shape: shapeType,\r\n id: newItemId,\r\n } as OverlayShape;\r\n }, [addResponseEvent, answers, calculateResponseTime, playClickSound]);\r\n\r\n // Shape has been clicked.\r\n const onShapeClicked = useCallback((shape: OverlayShape) => {\r\n // When a shape is clicked, delete it as a response.\r\n cancelResponseEvent(shape.id);\r\n\r\n playClickSound();\r\n }, [cancelResponseEvent, playClickSound]);\r\n\r\n // Manage the time limit countdown.\r\n const [secondsRemaining, setSecondsRemaining] = useState(model?.timeLimitSeconds ?? 0);\r\n useEffect(() => {\r\n const timer = setInterval(() => {\r\n setSecondsRemaining(prevState => {\r\n const newState = prevState - 1;\r\n\r\n if (newState <= 0) {\r\n clearInterval(timer);\r\n onActivityEnded();\r\n }\r\n\r\n return newState;\r\n })\r\n }, 1000);\r\n\r\n // Cleanup timer if the component is unmounted.\r\n return () => clearInterval(timer);\r\n }, [setSecondsRemaining, onActivityEnded]);\r\n\r\n // Score card, used in lots of places.\r\n const ScoreCard = (props: { includeQuestionTimer?: boolean, }) => (\r\n \r\n \r\n \r\n \r\n \r\n {t('showQuestionLocationResponseImage.scoreCardText', 'Highlights')}\r\n \r\n <>: \r\n {questionResponseEventsManager.model.filter(response => response.questionId === model.id && !response.archived && !isMaximumClickRuleFailtureRecord(response)).length}\r\n \r\n \r\n {\r\n props.includeQuestionTimer ? (\r\n \r\n ) : null\r\n }\r\n \r\n \r\n \r\n

\r\n {t('showQuestionLocationDiscrimination.failedMaximumClickRule', 'You exceeded the maximum number of clicks for this question and will score 0% for this question.')}\r\n

\r\n
\r\n
\r\n );\r\n\r\n return (\r\n
\r\n\r\n {/* Activity has not started */}\r\n \r\n
\r\n
startActivity()}\r\n >\r\n \r\n\r\n \r\n \r\n \r\n \r\n \r\n

\r\n {t('showQuestionLocationResponseImage.playText', 'Press play to show the scene and start the activity. You will have {{timeLimitSeconds}} seconds to complete the activity.', { timeLimitSeconds: model?.timeLimitSeconds ?? 0 })}\r\n

\r\n \r\n \r\n \r\n
\r\n
\r\n
\r\n
\r\n\r\n {/* Activity has started but is not yet finished */}\r\n \r\n
\r\n \r\n
\r\n\r\n \r\n
\r\n\r\n {/* Activity has finished */}\r\n \r\n
\r\n
\r\n \r\n\r\n
\r\n \r\n
\r\n\r\n

\r\n {t('showQuestionLocationResponseImage.endText', 'Press Next to continue.')}\r\n

\r\n
\r\n
\r\n
\r\n
\r\n );\r\n};\r\n","import { FontAwesomeIcon } from \"@fortawesome/react-fontawesome\";\r\nimport { useCallback, useMemo, useRef, useState } from \"react\";\r\nimport { ConditionalFragment } from \"react-conditionalfragment\";\r\nimport { useTranslation } from \"react-i18next\";\r\nimport { Button, Col, Row } from \"reactstrap\";\r\nimport { QuestionAnswer } from \"../../../../../api/main/models/QuestionAnswer\";\r\nimport { HtmlDisplay } from \"../../../../../shared/htmlEditor\";\r\nimport { usePrefetchImages } from \"../../../../../shared/prefetchImage\";\r\nimport { ShowQuestionChildProps } from \"../ShowQuestion\";\r\nimport \"./showQuestionMultipleChoiceVideo.scss\";\r\n\r\n/**\r\n * Running of a MultipleChoiceVideo question.\r\n * @param props\r\n */\r\nexport const ShowQuestionMultipleChoiceVideo = (props: ShowQuestionChildProps) => {\r\n const {\r\n model,\r\n answers,\r\n blobReferences,\r\n\r\n selectedAnswerId,\r\n selectSingleAnswer,\r\n questionResponseEventsManager,\r\n\r\n resetResponseTimeStart,\r\n\r\n onPageComplete,\r\n } = props;\r\n\r\n const { t } = useTranslation();\r\n\r\n const videoBlob = useMemo(() => blobReferences.find(it => it.id === model.videoBlobReferenceId), [blobReferences, model]);\r\n const imageBlob = useMemo(() => blobReferences.find(it => it.id === model.imageBlobReferenceId), [blobReferences, model]);\r\n const questionTextImageBlob = useMemo(() => blobReferences.find(it => it.id === model.questionTextImageBlobReferenceId), [blobReferences, model]);\r\n\r\n // At the end, with the question, we either want to show a specific image set to show with the question, or the original thumbnail again.\r\n const endImageBlob = questionTextImageBlob ?? imageBlob;\r\n\r\n // Keep track of if the video has started/finished or not.\r\n const videoRef = useRef(null);\r\n const [hasVideoStarted, setHasVideoStarted] = useState(false);\r\n const [hasVideoFinished, setHasVideoFinished] = useState(false);\r\n\r\n // Some calls to apis (such as saving clicks) will cause us to generate a new secure video URL. To make sure this doesn't reset out\r\n // video we cache the poster and video urls as we original receive them into our state and always use them.\r\n const [imageUrl] = useState(imageBlob?.url ?? '');\r\n const [videoUrl] = useState(videoBlob?.url ?? '');\r\n const [endImageUrl] = useState(endImageBlob?.url ?? '');\r\n\r\n // Prefetch the images we use.\r\n const resolveImageUrl = usePrefetchImages([\r\n imageUrl,\r\n endImageUrl,\r\n ...answers.map(answer => {\r\n const blob = blobReferences.find(item => item.id === answer.answerTextImageBlobReferenceId);\r\n return blob?.url ?? '';\r\n }),\r\n ]);\r\n\r\n // Start the video.\r\n const startVideo = useCallback(() => {\r\n setHasVideoStarted(true);\r\n videoRef.current?.play();\r\n }, [videoRef, setHasVideoStarted]);\r\n\r\n // Video has ended.\r\n const onVideoEnded = useCallback(() => {\r\n setHasVideoFinished(true);\r\n resetResponseTimeStart();\r\n }, [setHasVideoFinished, resetResponseTimeStart]);\r\n\r\n const onSelectSingleAnswer = useCallback((answer: QuestionAnswer | undefined) => {\r\n selectSingleAnswer(answer, model);\r\n\r\n // Let the navigation know this question has been completed.\r\n onPageComplete();\r\n }, [selectSingleAnswer, onPageComplete, model]);\r\n\r\n return (\r\n
\r\n\r\n {/* Video has not started */}\r\n \r\n
\r\n
startVideo()}\r\n >\r\n \r\n \r\n \r\n \r\n \r\n\r\n \r\n

\r\n {t('showQuestionMultipleChoiceVideo.playText', 'Press play to start the video.')}\r\n

\r\n \r\n \r\n \r\n
\r\n
\r\n
\r\n
\r\n\r\n {/* Video has started but is not yet finished */}\r\n \r\n
\r\n onVideoEnded()}\r\n >\r\n \r\n
\r\n
\r\n\r\n {/* Video has finished */}\r\n \r\n
\r\n
\r\n \r\n\r\n \r\n {\r\n answers.map(answer => {\r\n const answerBlob = blobReferences.find(it => it.id === answer.answerTextImageBlobReferenceId);\r\n\r\n return (\r\n \r\n \r\n \r\n );\r\n })\r\n }\r\n \r\n\r\n item.questionId === model.id && !item.archived).length}>\r\n

\r\n {t('showQuestionMultipleChoiceVideo.endText', 'Press Next to confirm your answer and continue.')}\r\n

\r\n
\r\n
\r\n
\r\n
\r\n
\r\n );\r\n};","import { FontAwesomeIcon } from \"@fortawesome/react-fontawesome\";\r\nimport { useCallback, useMemo, useRef, useState } from \"react\";\r\nimport { ConditionalFragment } from \"react-conditionalfragment\";\r\nimport { useTranslation } from \"react-i18next\";\r\nimport { Button, Card, Col, Row } from \"reactstrap\";\r\nimport { HtmlDisplay } from \"../../../../../shared/htmlEditor\";\r\nimport { usePrefetchImages } from \"../../../../../shared/prefetchImage\";\r\nimport { ShowQuestionChildProps } from \"../ShowQuestion\";\r\nimport { useClickSound } from \"../useClickSound/useClickSound\";\r\nimport \"./showQuestionResponseTimeVideo.scss\";\r\n\r\n/**\r\n * Running of a ResponseTimeVideo question.\r\n * @param props\r\n */\r\nexport const ShowQuestionResponseTimeVideo = (props: ShowQuestionChildProps) => {\r\n const {\r\n model,\r\n answers,\r\n blobReferences,\r\n\r\n addResponseEvent,\r\n questionResponseEventsManager,\r\n hasFailedMaximumClickRule,\r\n isMaximumClickRuleFailtureRecord,\r\n\r\n cancelAllButHighestResponse,\r\n\r\n resetResponseTimeStart,\r\n\r\n onPageComplete,\r\n } = props;\r\n\r\n const { t } = useTranslation();\r\n\r\n const videoBlob = useMemo(() => blobReferences.find(it => it.id === model.videoBlobReferenceId), [blobReferences, model]);\r\n const imageBlob = useMemo(() => blobReferences.find(it => it.id === model.imageBlobReferenceId), [blobReferences, model]);\r\n const questionTextImageBlob = useMemo(() => blobReferences.find(it => it.id === model.questionTextImageBlobReferenceId), [blobReferences, model]);\r\n\r\n // At the end, with the question, we either want to show a specific image set to show with the question, or the original thumbnail again.\r\n const endImageBlob = questionTextImageBlob ?? imageBlob;\r\n\r\n // Keep track of if the video has started/finished or not.\r\n const videoRef = useRef(null);\r\n const [hasVideoStarted, setHasVideoStarted] = useState(false);\r\n const [hasVideoFinished, setHasVideoFinished] = useState(false);\r\n\r\n // Some calls to apis (such as saving clicks) will cause us to generate a new secure video URL. To make sure this doesn't reset out\r\n // video we cache the poster and video urls as we original receive them into our state and always use them.\r\n const [imageUrl] = useState(imageBlob?.url ?? '');\r\n const [videoUrl] = useState(videoBlob?.url ?? '');\r\n const [endImageUrl] = useState(endImageBlob?.url ?? '');\r\n\r\n // Prefetch the images we use.\r\n const resolveImageUrl = usePrefetchImages([\r\n imageUrl,\r\n endImageUrl,\r\n ...answers.map(answer => {\r\n const blob = blobReferences.find(item => item.id === answer.answerTextImageBlobReferenceId);\r\n return blob?.url ?? '';\r\n }),\r\n ]);\r\n\r\n // Start the video.\r\n const startVideo = useCallback(() => {\r\n setHasVideoStarted(true);\r\n resetResponseTimeStart();\r\n videoRef.current?.play();\r\n }, [videoRef, setHasVideoStarted, resetResponseTimeStart]);\r\n\r\n // Video has ended.\r\n const onVideoEnded = useCallback(() => {\r\n setHasVideoFinished(true);\r\n resetResponseTimeStart();\r\n\r\n // Correct the scoring so it only takes the highest response (should never be undefinded here but we handle it anyway)\r\n if (!!cancelAllButHighestResponse && questionResponseEventsManager.added.length > 0) {\r\n cancelAllButHighestResponse();\r\n }\r\n\r\n // Let the navigation know this question has been completed.\r\n onPageComplete();\r\n }, [setHasVideoFinished, resetResponseTimeStart, onPageComplete, cancelAllButHighestResponse, questionResponseEventsManager]);\r\n\r\n\r\n // Video playback tracking.\r\n const currentVideoTime = useRef(0);\r\n\r\n // Handle the user responding (a click).\r\n const [isShowingClickIndicator, setIsShowingClickIndicator] = useState(false);\r\n const [playClickSound] = useClickSound();\r\n const onResponseClickEvent = useCallback(() => {\r\n const window = answers.find(item => item.startResponseTimeSeconds <= currentVideoTime.current && currentVideoTime.current < item.endResponseTimeSeconds);\r\n\r\n // If we are outside a window, we will be applying a default score of 0.\r\n const defaultScoreOutsideOfWindow = 0;\r\n\r\n addResponseEvent({\r\n questionAnswerId: window?.id,\r\n score: window?.score ?? defaultScoreOutsideOfWindow,\r\n isCorrect: window?.isCorrect ?? false,\r\n responseTimeSeconds: currentVideoTime.current,\r\n subQuestionNumber: window?.subQuestionNumber ?? 1,\r\n });\r\n\r\n playClickSound();\r\n setIsShowingClickIndicator(true);\r\n setTimeout(() => setIsShowingClickIndicator(false), 200);\r\n }, [addResponseEvent, answers, currentVideoTime, playClickSound, setIsShowingClickIndicator]);\r\n\r\n return (\r\n
\r\n\r\n {/* Video has not started */}\r\n \r\n
\r\n
startVideo()}\r\n >\r\n \r\n\r\n \r\n \r\n \r\n \r\n \r\n

\r\n {t('showQuestionResponseTimeVideo.playText', 'Press play to start the video.')}\r\n

\r\n \r\n \r\n \r\n
\r\n
\r\n
\r\n
\r\n\r\n {/* Video has started but is not yet finished */}\r\n \r\n
\r\n onVideoEnded()}\r\n onTimeUpdate={e => { currentVideoTime.current = e.currentTarget.currentTime; }}\r\n onClick={e => {\r\n e.preventDefault();\r\n\r\n onResponseClickEvent()\r\n }}\r\n onDoubleClick={e => {\r\n e.preventDefault();\r\n\r\n onResponseClickEvent()\r\n }}\r\n >\r\n \r\n
\r\n
\r\n\r\n {/* Video has finished */}\r\n \r\n
\r\n
\r\n \r\n\r\n

\r\n {t('showQuestionResponseTimeVideo.endText', 'Press Next to continue.')}\r\n

\r\n
\r\n
\r\n
\r\n
\r\n );\r\n};","import { FontAwesomeIcon } from \"@fortawesome/react-fontawesome\";\r\nimport { useCallback, useMemo, useRef, useState } from \"react\";\r\nimport { ConditionalFragment } from \"react-conditionalfragment\";\r\nimport { useTranslation } from \"react-i18next\";\r\nimport { Button, Col, Row } from \"reactstrap\";\r\nimport { QuestionAnswer } from \"../../../../../api/main/models/QuestionAnswer\";\r\nimport { HtmlDisplay } from \"../../../../../shared/htmlEditor\";\r\nimport { usePrefetchImages } from \"../../../../../shared/prefetchImage\";\r\nimport { SlidingScaleSlider } from \"../../../../questions/edit/slidingScaleVideo/SlidingScaleSlider\";\r\nimport { ShowQuestionChildProps } from \"../ShowQuestion\";\r\nimport \"./showQuestionSlidingScaleVideo.scss\";\r\n\r\n/**\r\n * Running of a SlidingScaleVideo question.\r\n * @param props\r\n */\r\nexport const ShowQuestionSlidingScaleVideo = (props: ShowQuestionChildProps) => {\r\n const {\r\n model,\r\n answers,\r\n blobReferences,\r\n\r\n selectedAnswerId,\r\n selectSingleAnswer,\r\n questionResponseEventsManager,\r\n\r\n resetResponseTimeStart,\r\n\r\n onPageComplete,\r\n } = props;\r\n\r\n\r\n const { t } = useTranslation();\r\n\r\n const videoBlob = useMemo(() => blobReferences.find(it => it.id === model.videoBlobReferenceId), [blobReferences, model]);\r\n const imageBlob = useMemo(() => blobReferences.find(it => it.id === model.imageBlobReferenceId), [blobReferences, model]);\r\n const questionTextImageBlob = useMemo(() => blobReferences.find(it => it.id === model.questionTextImageBlobReferenceId), [blobReferences, model]);\r\n\r\n // At the end, with the question, we either want to show a specific image set to show with the question, or the original thumbnail again.\r\n const endImageBlob = questionTextImageBlob ?? imageBlob;\r\n\r\n // Keep track of if the video has started/finished or not.\r\n const videoRef = useRef(null);\r\n const [hasVideoStarted, setHasVideoStarted] = useState(false);\r\n const [hasVideoFinished, setHasVideoFinished] = useState(false);\r\n\r\n // Some calls to apis (such as saving clicks) will cause us to generate a new secure video URL. To make sure this doesn't reset out\r\n // video we cache the poster and video urls as we original receive them into our state and always use them.\r\n const [imageUrl] = useState(imageBlob?.url ?? '');\r\n const [videoUrl] = useState(videoBlob?.url ?? '');\r\n const [endImageUrl] = useState(endImageBlob?.url ?? '');\r\n\r\n // Prefetch the images we use.\r\n const resolveImageUrl = usePrefetchImages([\r\n imageUrl,\r\n endImageUrl,\r\n ...answers.map(answer => {\r\n const blob = blobReferences.find(item => item.id === answer.answerTextImageBlobReferenceId);\r\n return blob?.url ?? '';\r\n }),\r\n ]);\r\n\r\n // Start the video.\r\n const startVideo = useCallback(() => {\r\n setHasVideoStarted(true);\r\n videoRef.current?.play();\r\n }, [videoRef, setHasVideoStarted]);\r\n\r\n const onSelectSingleAnswer = useCallback((answer: QuestionAnswer | undefined) => {\r\n selectSingleAnswer(answer, model);\r\n\r\n // Let the navigation know this question has been completed.\r\n onPageComplete();\r\n }, [selectSingleAnswer, onPageComplete, model]);\r\n\r\n // Video has ended.\r\n const onVideoEnded = useCallback(() => {\r\n setHasVideoFinished(true);\r\n resetResponseTimeStart();\r\n\r\n const currentResponse = questionResponseEventsManager.model.filter(item => item.questionId === model.id && !item.archived);\r\n //check if we already have a response saved\r\n if (currentResponse.length === 0) {\r\n\r\n //same logic as in \"\" for deciding where to start the scale dot\r\n const min = 0;\r\n const max = answers.length < 2 ? 1 : answers.length - 1;\r\n\r\n const defaultValue = Math.floor((max - min) / 2);\r\n\r\n //set what was calculated to be the current response\r\n onSelectSingleAnswer(answers[defaultValue]);\r\n\r\n }\r\n\r\n }, [setHasVideoFinished, resetResponseTimeStart, onSelectSingleAnswer, answers, model.id, questionResponseEventsManager.model]);\r\n\r\n // If the selected answer has an image, get it.\r\n const selectedAnswerBlob = useMemo(() => {\r\n if (!selectedAnswerId || !blobReferences) {\r\n return null;\r\n }\r\n\r\n const selectedAnswer = answers.find(it => it.id === selectedAnswerId);\r\n if (!selectedAnswer) {\r\n return null;\r\n }\r\n\r\n const ret = blobReferences.find(it => it.id === selectedAnswer.answerTextImageBlobReferenceId);\r\n if (!ret) {\r\n return null;\r\n }\r\n\r\n return ret;\r\n }, [blobReferences, selectedAnswerId, answers]);\r\n\r\n return (\r\n
\r\n\r\n {/* Video has not started */}\r\n \r\n
\r\n
startVideo()}\r\n >\r\n \r\n \r\n \r\n \r\n \r\n\r\n \r\n

\r\n {t('showQuestionSlidingScaleVideo.playText', 'Press play to start the video.')}\r\n

\r\n \r\n \r\n \r\n
\r\n
\r\n
\r\n
\r\n\r\n {/* Video has started but is not yet finished */}\r\n \r\n
\r\n onVideoEnded()}\r\n >\r\n \r\n
\r\n
\r\n\r\n {/* Video has finished */}\r\n \r\n
\r\n
\r\n \r\n\r\n \r\n \r\n \r\n \r\n \r\n
\r\n
\r\n \r\n
\r\n
\r\n \r\n \r\n \r\n
\r\n
\r\n\r\n
\r\n onSelectSingleAnswer(answer)}\r\n />\r\n
\r\n\r\n\r\n item.questionId === model.id && !item.archived).length}>\r\n

\r\n {t('showQuestionSlidingScaleVideo.endText', 'Press Next to confirm your answer and continue.')}\r\n

\r\n
\r\n
\r\n
\r\n
\r\n
\r\n );\r\n};","import { Button, Col, Row } from \"reactstrap\";\r\nimport { QuestionAnswer } from \"../../../../../api/main/models/QuestionAnswer\";\r\nimport { HtmlDisplay } from \"../../../../../shared/htmlEditor\";\r\nimport { Question } from \"../../../../../api/main/models/Question\";\r\nimport { QuestionResponseEvent } from \"../../../../../api/main/models/QuestionResponseEvent\";\r\nimport { ModelArrayChanges } from \"../../../../../shared/useChanges\";\r\nimport { useCallback } from \"react\";\r\nimport \"./showQuestionnaireMultipleChoice.scss\";\r\nimport { useTranslation } from \"react-i18next\";\r\n\r\n\r\n\r\n/**\r\n * Running of a MultipleChoiceVideo question.\r\n * @param props\r\n */\r\n\r\nexport interface ShowQuestionnaireMultipleChoiceProps {\r\n\r\n model: Question\r\n answers: Array\r\n\r\n // Selecting an answer.\r\n selectedAnswerId: string | undefined,\r\n selectSingleAnswer: (answer: QuestionAnswer | undefined, currentQuestion: Question) => void,\r\n\r\n}\r\n\r\nexport const ShowQuestionnaireMultipleChoice = (props: ShowQuestionnaireMultipleChoiceProps) => {\r\n const {\r\n model,\r\n answers,\r\n\r\n selectedAnswerId,\r\n selectSingleAnswer,\r\n\r\n } = props;\r\n\r\n const { t } = useTranslation();\r\n\r\n const onSelectSingleAnswer = useCallback((answer: QuestionAnswer | undefined) => {\r\n selectSingleAnswer(answer, model);\r\n\r\n }, [selectSingleAnswer, model]);\r\n\r\n return (\r\n
\r\n \r\n\r\n \r\n {\r\n answers.map(answer => {\r\n return (\r\n \r\n \r\n \r\n );\r\n })\r\n }\r\n \r\n\r\n\r\n
\r\n );\r\n}","import { Question } from \"../../../../../api/main/models/Question\";\r\nimport { QuestionAnswer } from \"../../../../../api/main/models/QuestionAnswer\";\r\nimport { HtmlDisplay } from \"../../../../../shared/htmlEditor\";\r\nimport { SlidingScaleSlider } from \"../../../../questions/edit/slidingScaleVideo/SlidingScaleSlider\";\r\nimport { QuestionResponseEvent } from \"../../../../../api/main/models/QuestionResponseEvent\";\r\nimport { ModelArrayChanges } from \"../../../../../shared/useChanges\";\r\nimport { useCallback, useEffect } from \"react\";\r\nimport { useTranslation } from \"react-i18next\";\r\n\r\n/**\r\n * Running of a SlidingScaleVideo question.\r\n * @param props\r\n */\r\n\r\nexport interface ShowQuestionnaireSlidingScaleProps {\r\n\r\n model: Question\r\n answers: Array\r\n\r\n // Selecting an answer.\r\n selectedAnswerId: string | undefined,\r\n selectSingleAnswer: (answer: QuestionAnswer | undefined, currentQuestion: Question) => void,\r\n\r\n questionResponseEventsManager: ModelArrayChanges,\r\n\r\n userId: string | undefined,\r\n}\r\n\r\nexport const ShowQuestionnaireSlidingScale = (props: ShowQuestionnaireSlidingScaleProps) => {\r\n const {\r\n model,\r\n answers,\r\n\r\n questionResponseEventsManager,\r\n selectedAnswerId,\r\n selectSingleAnswer,\r\n\r\n userId,\r\n } = props;\r\n\r\n const { t } = useTranslation();\r\n\r\n const onSelectSingleAnswer = useCallback((answer: QuestionAnswer | undefined) => {\r\n selectSingleAnswer(answer, model);\r\n }, [selectSingleAnswer, model]);\r\n\r\n //pick the answer that is set as the default value and add it to the response manager\r\n useEffect(() => {\r\n\r\n if (userId) {\r\n\r\n const currentResponse = questionResponseEventsManager.model.filter(item => item.questionId === model.id && !item.archived);\r\n //check if we already have a response saved\r\n if (currentResponse.length === 0) {\r\n\r\n //same logic as in \"\" for deciding where to start the scale dot\r\n const min = 0;\r\n const max = answers.length < 2 ? 1 : answers.length - 1;\r\n\r\n const defaultValue = Math.floor((max - min) / 2);\r\n\r\n //set what was calculated to be the current response\r\n onSelectSingleAnswer(answers[defaultValue]);\r\n\r\n }\r\n }\r\n\r\n }, [userId, answers, model, onSelectSingleAnswer, questionResponseEventsManager]);\r\n\r\n\r\n return (\r\n
\r\n \r\n\r\n
\r\n onSelectSingleAnswer(answer)}\r\n />\r\n
\r\n\r\n
\r\n \r\n );\r\n}","import { useTranslation } from \"react-i18next\";\r\nimport { HtmlDisplay } from \"../../../../../shared/htmlEditor\";\r\nimport { Question } from \"../../../../../api/main/models/Question\";\r\nimport { Input } from 'reactstrap';\r\nimport { ModelArrayChanges } from \"../../../../../shared/useChanges\";\r\nimport { QuestionResponseEvent, questionResponseEventDefaultValues } from \"../../../../../api/main/models/QuestionResponseEvent\";\r\nimport moment from \"moment\";\r\nimport { useCurrentUserId } from \"../../../../../api/account\";\r\nimport * as React from \"react\";\r\n\r\n/**\r\n * Running of a MultipleChoiceVideo question.\r\n * @param props\r\n */\r\n\r\nexport interface ShowQuestionnaireInputProps {\r\n\r\n model: Question\r\n questionResponseEventsManager: ModelArrayChanges,\r\n\r\n\r\n //needed for adding to response manager\r\n assessmentId: string,\r\n assessmentItemId: string,\r\n assessmentSessionId: string,\r\n}\r\n\r\nexport const ShowQuestionnaireInput = (props: ShowQuestionnaireInputProps) => {\r\n const {\r\n model,\r\n questionResponseEventsManager,\r\n\r\n\r\n assessmentId,\r\n assessmentItemId,\r\n assessmentSessionId,\r\n } = props;\r\n\r\n const { t } = useTranslation();\r\n\r\n // Current user.\r\n const currentUserId = useCurrentUserId();\r\n\r\n const now = moment().toISOString();\r\n\r\n //for use with the input box and setting its value\r\n const [textInput, setTextInput] = React.useState();\r\n \r\n\r\n const addInput = React.useCallback(() => {\r\n\r\n if (textInput) {\r\n\r\n const existingAnswers = questionResponseEventsManager.model.filter(item => item.questionId === model.id && !item.archived);\r\n\r\n if (existingAnswers) {\r\n //if we already have added to the manager, we need to archive it\r\n\r\n for (const existingAnswer of existingAnswers) {\r\n questionResponseEventsManager.changeFor(existingAnswer.id, { archived: true, cancelEventDate: now });\r\n }\r\n\r\n }\r\n\r\n //add what we have to the manager\r\n questionResponseEventsManager.addFor({\r\n ...questionResponseEventDefaultValues(),\r\n\r\n eventDate: now,\r\n assessmentId: assessmentId,\r\n assessmentItemId: assessmentItemId,\r\n assessmentSessionId: assessmentSessionId,\r\n questionId: model.id,\r\n userId: currentUserId,\r\n textInput: textInput,\r\n });\r\n\r\n }\r\n\r\n }, [questionResponseEventsManager, model, textInput, assessmentId, assessmentItemId, assessmentSessionId, currentUserId, now]);\r\n\r\n return (\r\n
\r\n \r\n\r\n setTextInput(e.currentTarget.value) } />\r\n\r\n
\r\n );\r\n}","import { QuestionType } from \"../../../../../api/main/models/codeOnly/QuestionType\";\r\nimport { Question } from \"../../../../../api/main/models/Question\";\r\nimport { QuestionAnswer } from \"../../../../../api/main/models/QuestionAnswer\";\r\nimport { QuestionResponseEvent } from \"../../../../../api/main/models/QuestionResponseEvent\";\r\nimport { ModelArrayChanges } from \"../../../../../shared/useChanges\";\r\nimport { ShowQuestionnaireMultipleChoice } from \"./ShowQuestionnaireMultipleChoice\";\r\nimport { ShowQuestionnaireSlidingScale } from \"./ShowQuestionnaireSlidingScale\";\r\nimport { ShowQuestionnaireInput } from \"./ShowQuestionnaireInput\";\r\nimport { launchAssessmentSessionViewModelQuery_viewModel_questionSequenceQuestions } from \"../../../../../api/main/generated/launchAssessmentSessionViewModelQuery\"\r\n\r\nexport interface ShowQuestionnaireProps {\r\n\r\n currentQuestionnaire: Question,\r\n\r\n allCurrentQuestionSequence: Array | undefined,\r\n answers: Array,\r\n questionResponseEventsManager: ModelArrayChanges,\r\n\r\n // Selecting an answer.\r\n selectedAnswerId: string | undefined,\r\n selectSingleAnswer: (answer: QuestionAnswer | undefined, currentQuestion: Question) => void,\r\n\r\n\r\n assessmentId: string,\r\n assessmentItemId: string,\r\n assessmentSessionId: string,\r\n\r\n userId: string | undefined,\r\n\r\n}\r\n\r\nexport const ShowQuestionnaireQuestionListComponent = (props: ShowQuestionnaireProps) => {\r\n const {\r\n currentQuestionnaire,\r\n\r\n allCurrentQuestionSequence,\r\n answers,\r\n\r\n questionResponseEventsManager,\r\n selectSingleAnswer,\r\n\r\n assessmentId,\r\n assessmentItemId,\r\n assessmentSessionId,\r\n userId,\r\n } = props;\r\n\r\n const filteredQuestions = allCurrentQuestionSequence?.filter(item => item.parentQuestionId === currentQuestionnaire.id && item.childQuestion.archived === false)\r\n\r\n return (\r\n <>\r\n\r\n

\r\n {\r\n\r\n currentQuestionnaire.questionText\r\n\r\n }\r\n

\r\n\r\n
\r\n\r\n {\r\n filteredQuestions?.map(item => {\r\n //loop through all questions for this questionnaire\r\n\r\n\r\n const filteredAnswers: Array = answers?.filter(it => it.questionId === item.childQuestionId && !item.archived) ?? []\r\n //filter the answers we have to be for the current question\r\n\r\n // Sort filtered answers into display order.\r\n let orderedAnswers = [...filteredAnswers];\r\n orderedAnswers.sort((a, b) => {\r\n if (a.displayOrder === b.displayOrder) {\r\n return 0;\r\n } else if (a.displayOrder > b.displayOrder) {\r\n return 1;\r\n } else {\r\n return -1;\r\n }\r\n });\r\n\r\n\r\n const myQuestionResponseEvent = questionResponseEventsManager.model.find(it => it.questionId === item.childQuestionId && !it.archived);\r\n //find any responses that we already have\r\n\r\n const selectedQuestionAnswerId = myQuestionResponseEvent?.questionAnswerId ?? undefined;\r\n //pass the response we found in for the components, if we didnt have one we use undefined\r\n\r\n const questionType = item.childQuestion.questionType as QuestionType;\r\n\r\n switch (questionType) {\r\n case QuestionType.QuestionnaireMultipleChoice:\r\n return (\r\n <>\r\n \r\n
\r\n \r\n );\r\n\r\n case QuestionType.QuestionnaireScale:\r\n return (\r\n <>\r\n \r\n
\r\n \r\n );\r\n\r\n case QuestionType.QuestionnaireInput:\r\n return (\r\n <>\r\n \r\n
\r\n \r\n );\r\n default:\r\n //should never reach but something to fall back on if it theres no logic for the current question type (avoid errors)\r\n return (\r\n <>\r\n {item.childQuestion.name} [{item.childQuestion.questionType}]\r\n \r\n );\r\n\r\n }\r\n })\r\n }\r\n \r\n );\r\n\r\n}","import { FontAwesomeIcon } from \"@fortawesome/react-fontawesome\";\r\nimport { useCallback, useMemo, useRef, useState } from \"react\";\r\nimport { ConditionalFragment } from \"react-conditionalfragment\";\r\nimport { useTranslation } from \"react-i18next\";\r\nimport { Button, Col, Row } from \"reactstrap\";\r\nimport { HtmlDisplay } from \"../../../../../shared/htmlEditor\";\r\nimport { ShowQuestionChildProps } from \"../ShowQuestion\";\r\nimport \"./showQuestionInformationVideo.scss\";\r\n\r\n/**\r\n * Running of a InformationVideo question.\r\n * @param props\r\n */\r\nexport const ShowQuestionInformationVideo = (props: ShowQuestionChildProps) => {\r\n const {\r\n model,\r\n blobReferences,\r\n\r\n onPageComplete,\r\n } = props;\r\n\r\n const { t } = useTranslation();\r\n\r\n const videoBlob = useMemo(() => blobReferences.find(it => it.id === model.videoBlobReferenceId), [blobReferences, model]);\r\n const imageBlob = useMemo(() => blobReferences.find(it => it.id === model.imageBlobReferenceId), [blobReferences, model]);\r\n\r\n // Keep track of if the video has started/finished or not.\r\n const videoRef = useRef(null);\r\n const [hasVideoStarted, setHasVideoStarted] = useState(false);\r\n const [hasVideoFinished, setHasVideoFinished] = useState(false);\r\n\r\n // Some calls to apis (such as saving clicks) will cause us to generate a new secure video URL. To make sure this doesn't reset out\r\n // video we cache the poster and video urls as we original receive them into our state and always use them.\r\n const [imageUrl] = useState(imageBlob?.url ?? '');\r\n const [videoUrl] = useState(videoBlob?.url ?? '');\r\n\r\n // Start the video.\r\n const startVideo = useCallback(() => {\r\n setHasVideoStarted(true);\r\n videoRef.current?.play();\r\n }, [videoRef, setHasVideoStarted]);\r\n\r\n // Video has ended.\r\n const onVideoEnded = useCallback(() => {\r\n setHasVideoFinished(true);\r\n\r\n // Page is complete once information video has been watched.\r\n onPageComplete();\r\n }, [setHasVideoFinished, onPageComplete]);\r\n \r\n return (\r\n
\r\n\r\n {/* Video has not started */}\r\n \r\n
\r\n
startVideo()}\r\n >\r\n \r\n \r\n \r\n \r\n
\r\n \r\n
\r\n\r\n \r\n

\r\n {t('showQuestionLearningVideo.playText', 'Press play to start the video.')}\r\n

\r\n \r\n \r\n \r\n
\r\n
\r\n
\r\n
\r\n\r\n
\r\n onVideoEnded()}\r\n >\r\n \r\n
\r\n\r\n {/* Video has finished */}\r\n \r\n
\r\n
\r\n
\r\n \r\n
\r\n\r\n
\r\n \r\n
\r\n\r\n

\r\n {t('showQuestionLearningVideo.endText', 'Press Next to continue.')}\r\n

\r\n
\r\n
\r\n
\r\n
\r\n );\r\n};","import { useEffect, useMemo, useState } from \"react\";\r\nimport { HtmlDisplay } from \"../../../../../shared/htmlEditor\";\r\nimport { ShowQuestionChildProps } from \"../ShowQuestion\";\r\n\r\n/**\r\n * Running of a LInformationImage question.\r\n * @param props\r\n */\r\nexport const ShowQuestionInformationImage = (props: ShowQuestionChildProps) => {\r\n const {\r\n model,\r\n blobReferences,\r\n\r\n onPageComplete,\r\n } = props;\r\n\r\n const imageBlob = useMemo(() => blobReferences.find(it => it.id === model.imageBlobReferenceId), [blobReferences, model]);\r\n\r\n // Some calls to apis (such as saving clicks) will cause us to generate a new secure video URL. To make sure this doesn't reset out\r\n // video we cache the poster and video urls as we original receive them into our state and always use them.\r\n const [imageUrl] = useState(imageBlob?.url ?? '');\r\n\r\n // There is no end event for this type of learning so we are complete as soon as we're shown.\r\n useEffect(() => {\r\n onPageComplete();\r\n }, [onPageComplete]);\r\n\r\n return (\r\n
\r\n \"Feedback\"\r\n\r\n
\r\n \r\n
\r\n
\r\n );\r\n};","import { useEffect } from \"react\";\r\nimport { HtmlDisplay } from \"../../../../../shared/htmlEditor\";\r\nimport { ShowQuestionChildProps } from \"../ShowQuestion\";\r\n\r\n/**\r\n * Running of a InformationText question.\r\n * @param props\r\n */\r\nexport const ShowQuestionInformationText = (props: ShowQuestionChildProps) => {\r\n const {\r\n model,\r\n onPageComplete,\r\n } = props;\r\n\r\n // There is no end event for this type of learning so we are complete as soon as we're shown.\r\n useEffect(() => {\r\n onPageComplete();\r\n }, [onPageComplete]);\r\n\r\n return (\r\n
\r\n
\r\n \r\n
\r\n
\r\n );\r\n};","import { useCallback, useMemo, useState } from \"react\";\r\nimport { ConditionalFragment } from \"react-conditionalfragment\";\r\nimport { useTranslation } from \"react-i18next\";\r\nimport { Button, Col, Row } from \"reactstrap\";\r\nimport { QuestionAnswer } from \"../../../../../api/main/models/QuestionAnswer\";\r\nimport { HtmlDisplay } from \"../../../../../shared/htmlEditor\";\r\nimport { usePrefetchImages } from \"../../../../../shared/prefetchImage\";\r\nimport { ShowQuestionChildProps } from \"../ShowQuestion\";\r\nimport \"./showQuestionMultipleChoiceImage.scss\";\r\n\r\n/**\r\n * Running of a MultipleChoiceImage question.\r\n * @param props\r\n */\r\nexport const ShowQuestionMultipleChoiceImage = (props: ShowQuestionChildProps) => {\r\n const {\r\n model,\r\n answers,\r\n blobReferences,\r\n\r\n selectedAnswerId,\r\n selectSingleAnswer,\r\n questionResponseEventsManager,\r\n\r\n onPageComplete,\r\n } = props;\r\n\r\n const { t } = useTranslation();\r\n\r\n const imageBlob = useMemo(() => blobReferences.find(it => it.id === model.imageBlobReferenceId), [blobReferences, model]);\r\n\r\n // Some calls to apis (such as saving clicks) will cause us to generate a new secure image URL. To make sure this doesn't reset out\r\n // image we cache the poster and image urls as we original receive them into our state and always use them.\r\n const [imageUrl] = useState(imageBlob?.url ?? '');\r\n\r\n // Prefetch the images we use.\r\n const resolveImageUrl = usePrefetchImages([\r\n imageUrl,\r\n ...answers.map(answer => {\r\n const blob = blobReferences.find(item => item.id === answer.answerTextImageBlobReferenceId);\r\n return blob?.url ?? '';\r\n }),\r\n ]);\r\n\r\n const onSelectSingleAnswer = useCallback((answer: QuestionAnswer | undefined) => {\r\n selectSingleAnswer(answer, model);\r\n\r\n // Let the navigation know this question has been completed.\r\n onPageComplete();\r\n }, [selectSingleAnswer, onPageComplete, model]);\r\n\r\n return (\r\n
\r\n\r\n
\r\n \"Scene\"\r\n
\r\n\r\n \r\n\r\n
\r\n \r\n {\r\n answers.map(answer => {\r\n const answerBlob = blobReferences.find(it => it.id === answer.answerTextImageBlobReferenceId);\r\n\r\n return (\r\n \r\n \r\n \r\n );\r\n })\r\n }\r\n \r\n
\r\n\r\n item.questionId === model.id && !item.archived).length}>\r\n

\r\n {t('showQuestionMultipleChoiceImage.endText', 'Press Next to confirm your answer and continue.')}\r\n

\r\n
\r\n
\r\n );\r\n};","import moment, { Moment } from \"moment\";\r\nimport { useCallback, useEffect, useMemo, useState } from \"react\";\r\nimport { useCurrentUserId } from \"../../../../api/account\";\r\nimport { Assessment } from \"../../../../api/main/models/Assessment\";\r\nimport { AssessmentItem } from \"../../../../api/main/models/AssessmentItem\";\r\nimport { AssessmentSession } from \"../../../../api/main/models/AssessmentSession\";\r\nimport { BlobReference } from \"../../../../api/main/models/BlobReference\";\r\nimport { QuestionType } from \"../../../../api/main/models/codeOnly/QuestionType\";\r\nimport { Question } from \"../../../../api/main/models/Question\";\r\nimport { launchAssessmentSessionViewModelQuery_viewModel_questionSequenceQuestions } from \"../../../../api/main/generated/launchAssessmentSessionViewModelQuery\"\r\nimport { QuestionAnswer } from \"../../../../api/main/models/QuestionAnswer\";\r\nimport { QuestionResponseEvent, questionResponseEventDefaultValues } from \"../../../../api/main/models/QuestionResponseEvent\";\r\nimport { ModelArrayChanges } from \"../../../../shared/useChanges\";\r\nimport { ShowQuestionLearningImage } from \"./learningImage/ShowQuestionLearningImage\";\r\nimport { ShowQuestionLearningText } from \"./learningText/ShowQuestionLearningText\";\r\nimport { ShowQuestionLearningVideo } from \"./learningVideo/ShowQuestionLearningVideo\";\r\nimport { ShowQuestionLocationDiscriminationImage } from \"./locationDiscriminationImage/ShowQuestionLocationDiscriminationImage\";\r\nimport { ShowQuestionLocationResponseImage } from \"./locationResponseImage/ShowQuestionLocationResponseImage\";\r\nimport { ShowQuestionMultipleChoiceVideo } from \"./multipleChoiceVideo/ShowQuestionMultipleChoiceVideo\";\r\nimport { ShowQuestionResponseTimeVideo } from \"./responseTimeVideo/ShowQuestionResponseTimeVideo\";\r\nimport { ShowQuestionSlidingScaleVideo } from \"./slidingScaleVideo/ShowQuestionSlidingScaleVideo\";\r\nimport { ShowQuestionnaireQuestionListComponent } from \"../questions/QuestionnaireQuestions/QuestionnaireQuestionListComponent\";\r\nimport { ShowQuestionInformationVideo } from \"./informationVideo/ShowQuestionInformationVideo\";\r\nimport { ShowQuestionInformationImage } from \"./informationImage/ShowQuestionInformationImage\";\r\nimport { ShowQuestionInformationText } from \"./informationText/ShowQuestionInformationText\";\r\nimport { ShowQuestionMultipleChoiceImage } from \"./multipleChoiceImage/ShowQuestionMultipleChoiceImage\";\r\n\r\nexport interface ShowQuestionProps {\r\n model: Question,\r\n allCurrentQuestionSequence: Array | undefined,\r\n answers: Array,\r\n questionnaireQuestionAnswers: Array,\r\n assessmentSession: AssessmentSession,\r\n blobReferences: Array,\r\n questionResponseEventsManager: ModelArrayChanges,\r\n assessment: Assessment,\r\n assessmentItem: AssessmentItem,\r\n\r\n // Event raised when a question has been completed.\r\n onPageComplete: () => void,\r\n}\r\n\r\nexport interface ShowQuestionChildProps extends ShowQuestionProps {\r\n // Selecting an answer.\r\n selectedAnswerId: string | undefined,\r\n selectSingleAnswer: (answer: QuestionAnswer | undefined, currentQuestion: Question) => void,\r\n\r\n // Response time calculation.\r\n resetResponseTimeStart: () => void,\r\n calculateResponseTime: (now?: string) => number,\r\n addResponseEvent: (event: Partial) => void,\r\n cancelResponseEvent: (id: string) => void,\r\n\r\n cancelAllButHighestResponse?: () => void,\r\n\r\n // Has the maximum click rule failed?\r\n hasFailedMaximumClickRule: boolean,\r\n isMaximumClickRuleFailtureRecord: (item: QuestionResponseEvent) => boolean,\r\n}\r\n\r\n/**\r\n * Show a question for an executing assessments.\r\n * @param props\r\n */\r\nexport const ShowQuestion = (props: ShowQuestionProps) => {\r\n const {\r\n model,\r\n allCurrentQuestionSequence,\r\n answers,\r\n questionnaireQuestionAnswers,\r\n assessmentSession,\r\n questionResponseEventsManager,\r\n assessment,\r\n assessmentItem,\r\n onPageComplete,\r\n } = props;\r\n\r\n // Current user.\r\n const currentUserId = useCurrentUserId();\r\n\r\n const filteredAnswers = answers.filter(it => it.questionId === model.id && !it.archived) ?? []\r\n\r\n // Response time tracking.\r\n const [responseTimeStart, setResponseTimeStart] = useState(() => moment().toISOString());\r\n const [answerSelected, setAnswerSelected] = useState(false);\r\n const resetResponseTimeStart = useCallback(() => setResponseTimeStart(moment().toISOString()), [setResponseTimeStart]);\r\n const calculateResponseTime = useCallback((now?: string) => {\r\n let nowMoment: Moment;\r\n if (now) {\r\n nowMoment = moment(now);\r\n } else {\r\n nowMoment = moment();\r\n }\r\n\r\n const startMoment = moment(responseTimeStart);\r\n const milliseconds = nowMoment.diff(startMoment, 'milliseconds');\r\n\r\n // Convert to decimal seconds.\r\n const ret = milliseconds / 1000.0;\r\n return ret;\r\n }, [responseTimeStart]);\r\n\r\n const [savedQuestionnaireForJson, setSavedQuestionnaireForJson] = useState('');\r\n useEffect(() => {\r\n\r\n if (model.questionType === QuestionType.Questionnaire) {\r\n\r\n var filteredSequenceQuestions = allCurrentQuestionSequence?.filter(item => !item.archived && item.parentQuestionId === model.id); \r\n\r\n // If a response isnt archived, then it must be a completed response\r\n const completedResponses = questionResponseEventsManager.model.filter(item => !item.archived && !!filteredSequenceQuestions?.find(it => it.childQuestionId === item.questionId))\r\n\r\n // If we have all questions completed, then we should be able to progress\r\n if (completedResponses.length === filteredSequenceQuestions?.length) {\r\n const questionnaireJson = JSON.stringify(completedResponses);\r\n\r\n // If nothing has changed since we last saved, then we dont need to save again\r\n if (savedQuestionnaireForJson !== questionnaireJson) {\r\n\r\n const savedQuestionnaireResponse = questionResponseEventsManager.model.find(item => item.questionId === model.id && !item.archived);\r\n const now = moment().toISOString();\r\n if (savedQuestionnaireResponse) {\r\n // Only want to save a new response for this questionnaire if we dont already have one (this will check with every screen update so needs to check this)\r\n\r\n questionResponseEventsManager.changeFor(savedQuestionnaireResponse.id, { archived: true, cancelEventDate: now });\r\n\r\n }\r\n\r\n var CombinedQuestionScore: number = 0;\r\n var textQuestions: number = 0;\r\n\r\n // Collect all the question scores into one\r\n questionResponseEventsManager.added.forEach(item => {\r\n if (item.questionId !== model.id && !item.archived) { CombinedQuestionScore = CombinedQuestionScore + (item?.score ?? 0) }\r\n if (item.textInput !== \"\") { textQuestions = textQuestions + 1 }\r\n });\r\n\r\n\r\n\r\n // Divide by how many questions there are (for how much you got correct) This will need to remove text questions from th list, as they dont have a correct answer so cannot give score\r\n let totalScore = 0;\r\n if (completedResponses.length - textQuestions === 0) {\r\n // If there are no questions, then the score is 0 (this is to stop a divide by 0 error)\r\n totalScore = 0\r\n } else {\r\n totalScore = Math.floor(CombinedQuestionScore / (completedResponses.length - textQuestions));\r\n if (isNaN(totalScore)) {\r\n totalScore = 0;\r\n }\r\n }\r\n\r\n\r\n // This should be moved now, or atleast have a logic change, as we need the score to update when the user changes an answer, which we werent worried about before.\r\n questionResponseEventsManager.addFor({\r\n ...questionResponseEventDefaultValues(),\r\n\r\n eventDate: now,\r\n assessmentId: assessment.id,\r\n assessmentItemId: assessmentItem.id,\r\n assessmentSessionId: assessmentSession.id,\r\n questionId: model.id,\r\n isCorrect: true,\r\n userId: currentUserId ?? '',\r\n score: totalScore ?? 0\r\n });\r\n\r\n onPageComplete()\r\n setAnswerSelected(false);\r\n setSavedQuestionnaireForJson(questionnaireJson);\r\n } \r\n }\r\n }\r\n }, [model.questionType, allCurrentQuestionSequence, assessment.id, assessmentItem.id, assessmentSession.id, currentUserId, model.id, onPageComplete, questionResponseEventsManager,\r\n answerSelected, setSavedQuestionnaireForJson, savedQuestionnaireForJson]);\r\n\r\n // Keep track of the selected answer.\r\n const selectedAnswerId = useMemo(() =>\r\n questionResponseEventsManager.model.find(item => item.questionId === model.id && !item.archived)?.questionAnswerId ?? undefined\r\n , [questionResponseEventsManager, model]);\r\n\r\n // Used with multiple choices and sliding scale to select one of the answers as current\r\n const selectSingleAnswer = useCallback((answer: QuestionAnswer | undefined, currentQuestion: Question) => {\r\n\r\n // Clear any current answers in the response events.\r\n const existingAnswers = questionResponseEventsManager.model.filter(item => item.questionId === currentQuestion.id && !item.archived);\r\n\r\n const now = moment().toISOString();\r\n\r\n for (const existingAnswer of existingAnswers) {\r\n // Remove an old response if we have any\r\n questionResponseEventsManager.changeFor(existingAnswer.id, { archived: true, cancelEventDate: now });\r\n }\r\n\r\n if (answer) {\r\n // Add an event to show this answer was selected.\r\n questionResponseEventsManager.addFor({\r\n ...questionResponseEventDefaultValues(),\r\n\r\n eventDate: now,\r\n assessmentId: assessment.id,\r\n assessmentItemId: assessmentItem.id,\r\n assessmentSessionId: assessmentSession.id,\r\n questionAnswerId: answer.id,\r\n questionId: currentQuestion.id,\r\n isCorrect: answer.isCorrect,\r\n userId: currentUserId,\r\n score: answer.score,\r\n responseTimeSeconds: calculateResponseTime(now),\r\n subQuestionNumber: answer.subQuestionNumber,\r\n });\r\n\r\n setAnswerSelected(true);\r\n\r\n }\r\n }, [questionResponseEventsManager, currentUserId, assessment, assessmentSession, assessmentItem, calculateResponseTime]);\r\n\r\n // Add a response event (not a single choice answer).\r\n const addResponseEvent = useCallback((event: Partial) => {\r\n // Add an event to show this answer was selected.\r\n const now = moment().toISOString();\r\n questionResponseEventsManager.addFor({\r\n ...questionResponseEventDefaultValues(),\r\n\r\n eventDate: now,\r\n assessmentId: assessment.id,\r\n assessmentItemId: assessmentItem.id,\r\n assessmentSessionId: assessmentSession.id,\r\n questionAnswerId: null,\r\n questionId: model.id,\r\n isCorrect: false,\r\n userId: currentUserId,\r\n score: 0,\r\n responseTimeSeconds: calculateResponseTime(now),\r\n\r\n ...event,\r\n });\r\n }, [questionResponseEventsManager, model, currentUserId, assessment, assessmentSession, assessmentItem, calculateResponseTime]);\r\n\r\n // Cancel a response event (not a single choice answer).\r\n const cancelResponseEvent = useCallback((id: string) => {\r\n const event = questionResponseEventsManager.model.find(item => item.id === id);\r\n if (!event) {\r\n return;\r\n }\r\n\r\n questionResponseEventsManager.changeFor(\r\n event.id,\r\n {\r\n cancelEventDate: moment().toISOString(),\r\n archived: true,\r\n }\r\n );\r\n }, [questionResponseEventsManager]);\r\n\r\n // Check if the maximum number of allowed clicks has expired, if it has, then apply an \"auto fail\" record. If it hasn't then remove the auto fail\r\n // record if it exists.\r\n const maximumClickRuleFailScore = -100000;\r\n const isMaximumClickRuleFailtureRecord = useCallback((item: QuestionResponseEvent) => item.score === maximumClickRuleFailScore ? true : false, [maximumClickRuleFailScore]);\r\n const performMaximumClickRule = useCallback(() => {\r\n // This score is used to auto fail a question (effectivly gives a score of 0).\r\n\r\n // Lookup the active fail record (if any).\r\n const currentFailRecord = questionResponseEventsManager.model.find(it => it.questionId === model.id && isMaximumClickRuleFailtureRecord(it) && !it.archived);\r\n\r\n // Get the current live clicks (exclude any which have been archived/cancelled).\r\n const currentClicks = questionResponseEventsManager.model.filter(it => it.questionId === model.id && !it.archived && !isMaximumClickRuleFailtureRecord(it));\r\n\r\n // If we have more clicks than we allow, fail the record (unless it already has a fail record).\r\n if (currentClicks.length > model.maximumClicks) {\r\n if (currentFailRecord) {\r\n return;\r\n }\r\n\r\n const now = moment().toISOString();\r\n questionResponseEventsManager.addFor({\r\n ...questionResponseEventDefaultValues(),\r\n\r\n eventDate: now,\r\n assessmentId: assessment.id,\r\n assessmentItemId: assessmentItem.id,\r\n assessmentSessionId: assessmentSession.id,\r\n questionAnswerId: null,\r\n questionId: model.id,\r\n isCorrect: false,\r\n userId: currentUserId,\r\n score: maximumClickRuleFailScore,\r\n responseTimeSeconds: calculateResponseTime(now),\r\n textInput: 'FailedMaximumClicks', // Helps when browsing the database, not to be relied upon anywhere.\r\n });\r\n } else {\r\n if (!currentFailRecord) {\r\n return;\r\n }\r\n\r\n questionResponseEventsManager.changeFor(\r\n currentFailRecord?.id || '',\r\n {\r\n cancelEventDate: moment().toISOString(),\r\n archived: true,\r\n }\r\n );\r\n }\r\n }, [questionResponseEventsManager, isMaximumClickRuleFailtureRecord, model, calculateResponseTime, assessment, maximumClickRuleFailScore, assessmentItem, assessmentSession, currentUserId]);\r\n\r\n const [cancelAllButHighestResponseComplete, setCancelAllButHighestResponseComplete] = useState(false);\r\n const calculateHighestResponseTimeScore = useCallback(() => {\r\n\r\n // Get the responses for the current question.\r\n const currentResponses = questionResponseEventsManager.model.filter(item => item.questionId === model.id && !item.archived);\r\n\r\n // Find the highest score response Id.\r\n const highestScore = currentResponses.reduce((prev, current) => (prev.score > current.score) ? prev : current).id;\r\n\r\n // Archive all responses that are not the highest score.\r\n for (const currentResponse of currentResponses) {\r\n // Dont want to archive any max click scores.\r\n if (currentResponse.id !== highestScore && currentResponse.score !== maximumClickRuleFailScore) {\r\n questionResponseEventsManager.changeFor(\r\n currentResponse.id,\r\n {\r\n cancelEventDate: moment().toISOString(),\r\n archived: true,\r\n }\r\n );\r\n }\r\n }\r\n\r\n setCancelAllButHighestResponseComplete(true);\r\n\r\n }, [questionResponseEventsManager, model, maximumClickRuleFailScore]);\r\n\r\n // Automatically apply the max click failure rules each time we have a change in questionResponseEventsManager (via performMaximumClickRule dependancies).\r\n useEffect(() => {\r\n // Dont want to retrigger this if we have completed the cancelAllButHighestResponse, as it leads to an archived max click response.\r\n if (!questionResponseEventsManager.model.length || cancelAllButHighestResponseComplete) {\r\n return;\r\n }\r\n\r\n performMaximumClickRule();\r\n }, [performMaximumClickRule, questionResponseEventsManager]);\r\n\r\n // Have we failed the maximum click rule?\r\n const hasFailedMaximumClickRule = useMemo(() => {\r\n const currentFailRecord = questionResponseEventsManager.model.find(it => it.questionId === model.id && isMaximumClickRuleFailtureRecord(it) && !it.archived);\r\n if (currentFailRecord) {\r\n return true;\r\n }\r\n\r\n return false;\r\n }, [questionResponseEventsManager, isMaximumClickRuleFailtureRecord, model]);\r\n\r\n // Show the right question component based on the question type.\r\n //\r\n const questionType = model.questionType as QuestionType;\r\n switch (questionType) {\r\n case QuestionType.MultipleChoiceVideo:\r\n return (\r\n \r\n );\r\n case QuestionType.SlidingScaleVideo:\r\n return (\r\n \r\n );\r\n case QuestionType.ResponseTimeVideo:\r\n return (\r\n \r\n );\r\n case QuestionType.LocationResponseImage:\r\n return (\r\n \r\n );\r\n case QuestionType.LocationDiscriminationImage:\r\n return (\r\n \r\n );\r\n case QuestionType.MultipleChoiceImage:\r\n return (\r\n \r\n );\r\n case QuestionType.LearningVideo:\r\n return (\r\n \r\n );\r\n case QuestionType.LearningImage:\r\n return (\r\n \r\n );\r\n case QuestionType.LearningText:\r\n return (\r\n \r\n );\r\n case QuestionType.Questionnaire:\r\n return (\r\n <>\r\n \r\n \r\n );\r\n case QuestionType.InformationVideo:\r\n return (\r\n \r\n );\r\n case QuestionType.InformationImage:\r\n return (\r\n \r\n );\r\n case QuestionType.InformationText:\r\n return (\r\n \r\n );\r\n\r\n\r\n default:\r\n return (<>{model.name} [{model.questionType}]);\r\n }\r\n};","import { useEffect } from \"react\";\r\nimport { Assessment } from \"../../../api/main/models/Assessment\";\r\nimport { AssessmentSession } from \"../../../api/main/models/AssessmentSession\";\r\nimport { HtmlDisplay } from \"../../../shared/htmlEditor\";\r\n\r\nexport interface StartPageProps {\r\n model: AssessmentSession | undefined | null,\r\n assessment: Assessment | undefined | null,\r\n \r\n // Event raised when a question has been completed.\r\n onPageComplete: () => void,\r\n}\r\n\r\n\r\n/**\r\n * Show a question for an executing assessments.\r\n * @param props\r\n */\r\nexport const StartPage = (props: StartPageProps) => {\r\n const {\r\n assessment,\r\n onPageComplete,\r\n } = props;\r\n\r\n // Start page has no activity so we are complete as soon as we're shown.\r\n useEffect(() => {\r\n onPageComplete();\r\n }, [onPageComplete]);\r\n\r\n return (\r\n
\r\n \r\n
\r\n );\r\n};","import { QuestionResponseEvent } from \"../../../../api/main/models/QuestionResponseEvent\";\r\nimport { OverallRiskCategory, overallRiskService, RiskRules } from \"../../../../services/OverallRiskService\";\r\n\r\nexport interface QuestionScore {\r\n score: number,\r\n minScore: number,\r\n maxScore: number,\r\n riskCategory: OverallRiskCategory,\r\n}\r\n\r\n/**\r\n * Calculate the question score for a question. Result will always be between 0 and 10.\r\n */\r\nexport function calculateQuestionScore(responses: Array, riskRules?: RiskRules | undefined | null): QuestionScore {\r\n let score: number = 0;\r\n for (const response of responses) {\r\n score += response.score;\r\n }\r\n\r\n if (score < 0) {\r\n score = 0;\r\n }\r\n\r\n if (score > 100) {\r\n score = 100;\r\n }\r\n\r\n var notStarted = true\r\n if (responses.length > 0) {\r\n notStarted = false\r\n }\r\n\r\n const riskCategory = overallRiskService.getRiskCategory(score, notStarted, riskRules);\r\n\r\n return {\r\n score,\r\n minScore: 0,\r\n maxScore: 100,\r\n riskCategory,\r\n };\r\n}","import { overallRiskService, RiskRules } from \"../../../../services/OverallRiskService\";\r\nimport { QuestionScore } from \"./calculateQuestionScore\";\r\n\r\n/**\r\n * Calculate the question score for a question. Result will always be between 0 and 10.\r\n */\r\nexport function combineQuestionScores(scores: Array, riskRules?: RiskRules | undefined | null): QuestionScore {\r\n let totalScore: number = 0;\r\n if (scores) {\r\n for (const score of scores) {\r\n totalScore += score.score;\r\n }\r\n\r\n totalScore = Math.round(totalScore / scores.length)\r\n\r\n if (totalScore < 0) {\r\n totalScore = 0;\r\n }\r\n\r\n if (totalScore > 100) {\r\n totalScore = 100;\r\n }\r\n\r\n const riskCategory = overallRiskService.getRiskCategory(totalScore, false, riskRules);\r\n\r\n\r\n return {\r\n score: totalScore,\r\n minScore: 0,\r\n maxScore: 100,\r\n riskCategory,\r\n };\r\n }\r\n\r\n else {\r\n const riskCategory = overallRiskService.getRiskCategory(0, true, riskRules);\r\n return {\r\n score: 0,\r\n minScore: 0,\r\n maxScore: 100,\r\n riskCategory,\r\n };\r\n }\r\n}","import { getQuestionTypeCategory, QuestionType, QuestionTypeCategory } from \"../../../../api/main/models/codeOnly/QuestionType\";\r\nimport { Question } from \"../../../../api/main/models/Question\";\r\nimport { QuestionResponseEvent } from \"../../../../api/main/models/QuestionResponseEvent\";\r\nimport { overallRiskService, RiskRules } from \"../../../../services/OverallRiskService\";\r\nimport { calculateQuestionScore, QuestionScore } from \"./calculateQuestionScore\";\r\nimport { combineQuestionScores } from \"./combineQuestionScores\";\r\nimport { QuestionSequenceQuestion } from \"../../../../api/main/models/QuestionSequenceQuestion\";\r\n\r\nexport interface AssessmentScore extends QuestionScore {\r\n /**\r\n * Raw score calculation based on all questions across all metrics without doing any metric based grouping.\r\n * We may not use this anywhere but its useful for debugging.\r\n * NOTE score is based on combining the score per safety metric (excluding those that affect no safety metric).\r\n */\r\n rawScore: number,\r\n\r\n questionBreakdown: Array,\r\n driverMetricBreakdown: Array,\r\n}\r\n\r\nexport interface AssessmentScoreQuestionBreakdown {\r\n questionId: string,\r\n subQuestionNumber: number,\r\n driverMetricId: string | null,\r\n score: QuestionScore,\r\n}\r\n\r\nexport interface AssessmentScoreDriverMetricBreakdown {\r\n driverMetricId: string | null,\r\n score: QuestionScore,\r\n}\r\n\r\n/**\r\n * Calculate the question score for a question. Result will always be between 0 and 100.\r\n */\r\nexport function calculateAssessmentScore(questions: Array, responses: Array, riskRules?: RiskRules | undefined | null, questionnaireSequenceQuestions?: Array,\r\n questionnaireQuestions?: Array): AssessmentScore\r\n{\r\n // Work out the score for each question or question subpart.\r\n let questionScores: Array = [];\r\n\r\n for (const question of questions) {\r\n // Skip non-scored questions.\r\n const questionTypeCategory = getQuestionTypeCategory(question.questionType as QuestionType);\r\n\r\n if (questionTypeCategory === QuestionTypeCategory.Question) {\r\n for (let subQuestionNumber = 1; subQuestionNumber <= question.numberOfSubQuestions; ++subQuestionNumber) {\r\n const myResponses = responses.filter(item => item.questionId === question.id && item.subQuestionNumber === subQuestionNumber && !item.archived);\r\n const score = calculateQuestionScore(myResponses, riskRules);\r\n questionScores.push({\r\n questionId: question.id,\r\n subQuestionNumber: subQuestionNumber,\r\n driverMetricId: question.driverMetricId ?? null,\r\n score,\r\n });\r\n }\r\n }\r\n else if (questionTypeCategory === QuestionTypeCategory.Questionnaire) {\r\n //needs to use the questionnaire question responses too so that when its calculating driver metrics it knows what scores to use.\r\n const currentSequenceQuestions = questionnaireSequenceQuestions?.filter(it => it.parentQuestionId === question.id && !it.archived);\r\n if (currentSequenceQuestions && questionnaireQuestions) {\r\n var subQuestionNumber = 1;\r\n for (const questionSequence of currentSequenceQuestions) {\r\n\r\n const currentQuestion = questionnaireQuestions.find(it => it.id === questionSequence.childQuestionId);\r\n\r\n if (currentQuestion) {\r\n\r\n if (currentQuestion.questionType as QuestionType === QuestionType.QuestionnaireInput || subQuestionNumber > question.numberOfSubQuestions) {\r\n subQuestionNumber = subQuestionNumber + 1;\r\n continue;\r\n }\r\n const myResponses = responses.filter(item => item.questionId === currentQuestion.id && !item.archived);\r\n\r\n const score = calculateQuestionScore(myResponses, riskRules);\r\n\r\n questionScores.push({\r\n questionId: currentQuestion.id,\r\n subQuestionNumber: subQuestionNumber,\r\n driverMetricId: currentQuestion.driverMetricId ?? null,\r\n score,\r\n });\r\n subQuestionNumber = subQuestionNumber + 1;\r\n }\r\n }\r\n\r\n }\r\n }\r\n }\r\n\r\n // Calculate the score per safety metric.\r\n let driverMetricScores: Array = [];\r\n\r\n questions.forEach(item => {\r\n\r\n if (item.questionType === QuestionTypeCategory.Questionnaire) {\r\n\r\n const currentSequenceQuestions = questionnaireSequenceQuestions?.filter(it => it.parentQuestionId === item.id);\r\n\r\n if (currentSequenceQuestions && questionnaireQuestions) {\r\n\r\n for (const questionSequence of currentSequenceQuestions) {\r\n const currentQuestion = questionnaireQuestions.find(it => it.id === questionSequence.childQuestionId);\r\n\r\n if (currentQuestion?.driverMetricId) {\r\n const myQuestionScores = questionScores.filter(it => it.driverMetricId === currentQuestion.driverMetricId).map(item => item.score);\r\n const myScore = combineQuestionScores(myQuestionScores, riskRules);\r\n driverMetricScores.push({\r\n driverMetricId: currentQuestion.driverMetricId,\r\n score: myScore,\r\n });\r\n }\r\n }\r\n }\r\n }\r\n\r\n else {\r\n // Use a set to get a distinct list of driver metrics used by the questions.\r\n const myQuestionScores = questionScores.filter(it => it.driverMetricId === item.driverMetricId).map(it => it.score);\r\n const myScore = combineQuestionScores(myQuestionScores, riskRules);\r\n driverMetricScores.push({\r\n driverMetricId: item.driverMetricId,\r\n score: myScore,\r\n });\r\n }\r\n });\r\n \r\n\r\n // Calculate the raw total score if we were treating all questions equally.\r\n let rawScore = 0;\r\n let questionPartCount = 0;\r\n for (const questionScore of questionScores) {\r\n rawScore += questionScore.score.score;\r\n ++questionPartCount;\r\n }\r\n\r\n let rawTotalScore = rawScore;\r\n if (questionPartCount > 0) {\r\n rawTotalScore = Math.round(rawScore / questionPartCount);\r\n }\r\n\r\n const rawRiskCategory = overallRiskService.getRiskCategory(rawTotalScore, false, riskRules);\r\n\r\n // Calculate the actual score, based on treating each safety metric equally (and ignoring questions not assigned to a safety metric).\r\n const metricTotalScore = combineQuestionScores(driverMetricScores.filter(it => it.driverMetricId !== null).map(it => it.score), riskRules);\r\n\r\n // Work out if we should be using the metric based total score or the raw total score. We will always use the metric based score if the assessment\r\n // has one or more metrics in it, and the raw total score if it has no metrics in it.\r\n const isMetricBased = driverMetricScores.filter(it => it.driverMetricId !== null).length > 0;\r\n\r\n return {\r\n score: isMetricBased ? metricTotalScore.score : rawTotalScore,\r\n rawScore: rawTotalScore,\r\n minScore: 0,\r\n maxScore: 100,\r\n riskCategory: isMetricBased? metricTotalScore.riskCategory: rawRiskCategory,\r\n questionBreakdown: questionScores,\r\n driverMetricBreakdown: driverMetricScores,\r\n };\r\n}","import { useTranslation } from \"react-i18next\";\r\nimport { Progress } from \"reactstrap\";\r\nimport \"./pageProgress.scss\";\r\n\r\nexport interface PageProgressProps {\r\n currentPageIndex: number,\r\n pageCount: number,\r\n}\r\n\r\n/**\r\n * Progress bar showing progress through an assessment.\r\n * @param props\r\n */\r\nexport const PageProgress = (props: PageProgressProps) => {\r\n const {\r\n currentPageIndex,\r\n pageCount\r\n } = props;\r\n\r\n const { t } = useTranslation();\r\n\r\n return (\r\n
\r\n \r\n \r\n {t('pageProgress.progressText', 'Screen {{currentPage}} of {{pageCount}}', { currentPage: (currentPageIndex + 1), pageCount: pageCount })}\r\n \r\n \r\n
\r\n );\r\n};","import { FontAwesomeIcon } from \"@fortawesome/react-fontawesome\";\r\nimport { useCallback, useEffect, useMemo, useState } from \"react\";\r\nimport { ConditionalFragment } from \"react-conditionalfragment\";\r\nimport { useTranslation } from \"react-i18next\";\r\nimport { useHistory, useParams } from \"react-router\";\r\nimport { useAsyncCallback } from \"react-use-async-callback\";\r\nimport { Button, Col, Row } from \"reactstrap\";\r\nimport { useSaveAssessmentSessionCallback } from \"../../../api/main/assessmentSessions/useSaveAssessmentSessionCallback\";\r\nimport { useLaunchAssessmentSessionViewModel } from \"../../../api/main/assessmentSessions/viewModels/useLaunchAssessmentSessionViewModel\";\r\nimport { launchAssessmentSessionViewModelQuery_viewModel } from \"../../../api/main/generated/launchAssessmentSessionViewModelQuery\";\r\nimport { AssessmentItem } from \"../../../api/main/models/AssessmentItem\";\r\nimport { AssessmentSession } from \"../../../api/main/models/AssessmentSession\";\r\nimport { AssessmentType } from \"../../../api/main/models/codeOnly/AssessmentType\";\r\nimport { FeedbackStyle } from \"../../../api/main/models/codeOnly/FeedbackStyle\";\r\nimport { getQuestionTypeCategory, QuestionType, QuestionTypeCategory } from \"../../../api/main/models/codeOnly/QuestionType\";\r\nimport { Question } from \"../../../api/main/models/Question\";\r\nimport { QuestionResponseEvent } from \"../../../api/main/models/QuestionResponseEvent\";\r\nimport { useDeleteQuestionResponseEventCallback } from \"../../../api/main/questionResponseEvents/useDeleteQuestionResponseEventCallback\";\r\nimport { useSaveQuestionResponseEventCallback } from \"../../../api/main/questionResponseEvents/useSaveQuestionResponseEventCallback\";\r\nimport { AlertOnErrors } from \"../../../shared/alertOnErrors\";\r\nimport { useChanges, useChangesArray } from \"../../../shared/useChanges\";\r\nimport { Background } from \"../../shared/background/Background\";\r\nimport { Banner } from \"../../shared/Banner\";\r\nimport { FormButtons } from \"../../shared/FormButtons\";\r\nimport { LoadingIndicator } from \"../../shared/LoadingIndicator\";\r\nimport { MainContainer } from \"../../shared/MainContainer\";\r\nimport { ShowQuestionFeedback } from \"./feedback/ShowQuestionFeedback\";\r\nimport { FinishPage } from \"./FinishPage\";\r\nimport { ShowQuestion } from \"./questions/ShowQuestion\";\r\nimport { StartPage } from \"./StartPage\";\r\nimport { calculateAssessmentScore } from \"./utilities/calculateAssessmentScore\";\r\nimport { calculateQuestionScore } from \"./utilities/calculateQuestionScore\";\r\nimport \"./launchAssessmentBase.scss\";\r\nimport moment from \"moment\";\r\nimport { ScoreProgressBar } from \"./progress/ScoreProgressBar\";\r\nimport { PageProgress } from \"./progress/PageProgress\";\r\nimport { useApplyDriverMetricsForAssessmentSessionCallback } from \"../../../api/main/userDriverMetrics/useApplyDriverMetricsForAssessmentSessionCallback\";\r\nimport { questionScoreFromNumber } from \"./utilities/questionScoreFromNumber\";\r\nimport { useLaunchAssessmentSessionSupportingData } from \"../../../api/main/assessmentSessions/viewModels/useLaunchAssessmentSessionSupportingData\";\r\nimport { IdentityRoles } from \"../../../configure/security/IdentityRoles\";\r\nimport { useCurrentUserRoles } from \"../../../api/account\";\r\nimport { SubscriptionType } from \"../../../api/main/models/codeOnly/SubscriptionType\";\r\n\r\nexport interface LaunchAssessmentBaseProps {\r\n defaultAssessmentType: AssessmentType,\r\n finishPageOnly?: boolean,\r\n}\r\n\r\nexport interface LaunchAssessmentPage {\r\n pageType: 'start' | 'question' | 'questionFeedback' | 'finish';\r\n assessmentItemId: string | undefined,\r\n questionId: string | undefined,\r\n fullScreen: boolean, // When true we'll use full screen when showing the page to avoid destractions.\r\n}\r\n\r\n/**\r\n * Launch an assessment so it can be completed.\r\n */\r\nexport const LaunchAssessmentBase = (props: LaunchAssessmentBaseProps) => {\r\n const {\r\n defaultAssessmentType,\r\n finishPageOnly = false,\r\n } = props;\r\n\r\n const { id } = useParams<{ id: string; }>();\r\n const history = useHistory();\r\n\r\n const { t } = useTranslation();\r\n\r\n // Load all the data.\r\n const { data: { viewModel }, isLoading: _isLoading, errors: loadErrors } = useLaunchAssessmentSessionViewModel(id);\r\n const {\r\n assessmentSession: storeModel,\r\n assessment,\r\n assessmentFeedbacks,\r\n questions,\r\n questionSequenceQuestions,\r\n questionAnswers,\r\n questionnaireQuestionAnswers,\r\n questionFeedbacks,\r\n blobReferences,\r\n questionResponseEvents,\r\n assessmentItems,\r\n assessmentItemSessionOrders,\r\n subscription,\r\n } = viewModel ?? {} as launchAssessmentSessionViewModelQuery_viewModel;\r\n const { data: { driverMetrics }, isLoading: isLoadingSupportingData, errors: supportingDataErrors } = useLaunchAssessmentSessionSupportingData();\r\n const isLoading = _isLoading || isLoadingSupportingData;\r\n\r\n // The session is our model.\r\n const { model, change, changes } = useChanges(storeModel);\r\n const [saveAssessmentSession, { errors: saveAssessmentSessionErrors }] = useSaveAssessmentSessionCallback();\r\n const [applyDriverMetricsForAssessmentSession, { errors: applyDriverMetricsForAssessmentSessionErrors }] = useApplyDriverMetricsForAssessmentSessionCallback();\r\n\r\n // Is it an assessment or is it training?\r\n const activeAssessmentType: AssessmentType = useMemo(() => assessment?.assessmentType as AssessmentType ?? defaultAssessmentType, [assessment, defaultAssessmentType]);\r\n\r\n // Want to be able to have a manager around all the events.\r\n const questionResponseEventsManager = useChangesArray(questionResponseEvents, item => item.id);\r\n const [saveQuestionResponseEvent, { errors: saveQuestionResponseEventErrors }] = useSaveQuestionResponseEventCallback();\r\n const [removeQuestionResponseEvent, { errors: removeQuestionResponseEventErrors }] = useDeleteQuestionResponseEventCallback();\r\n\r\n // Generate a list of pages.\r\n const pages = useMemo((): Array => {\r\n let ret: Array = [];\r\n\r\n // Always have a start page to get going.\r\n ret.push(\r\n { pageType: 'start', assessmentItemId: undefined, questionId: undefined, } as LaunchAssessmentPage\r\n );\r\n\r\n // Add questions, and if required the question by question feedback.\r\n if (assessmentItemSessionOrders) {\r\n for (const assessmentItem of assessmentItemSessionOrders) {\r\n for (const questionItem of assessmentItem.questionIds) {\r\n // Add the question page.\r\n ret.push(\r\n { pageType: 'question', assessmentItemId: assessmentItem.id, questionId: questionItem.id, fullScreen: true, } as LaunchAssessmentPage,\r\n );\r\n\r\n // If we are showing question feedback as we go, create a page for feedback after each question.\r\n if (assessment?.feedbackStyle === FeedbackStyle.EachQuestionFeedback) {\r\n // Only add a feedback page for scored questions.\r\n const question = questions.find(item => item.id === questionItem.id);\r\n const questionTypeCategory = getQuestionTypeCategory(question?.questionType as QuestionType);\r\n if (questionTypeCategory === QuestionTypeCategory.Question) {\r\n ret.push(\r\n { pageType: 'questionFeedback', assessmentItemId: assessmentItem.id, questionId: questionItem.id, fullScreen: true, } as LaunchAssessmentPage\r\n );\r\n }\r\n }\r\n }\r\n }\r\n }\r\n\r\n // Add the finish/overal feedback page.\r\n ret.push(\r\n { pageType: 'finish', assessmentItemId: undefined, questionId: undefined, } as LaunchAssessmentPage,\r\n );\r\n\r\n return ret;\r\n }, [assessmentItemSessionOrders, assessment, questions]);\r\n\r\n // Want to know the finished page index as its treated as a special page.\r\n const finishPage = pages.find(item => item.pageType === 'finish');\r\n const finishPageIndex = !finishPage ? 9999999 : pages.indexOf(finishPage);\r\n\r\n const exceedsSuspiciousLimit = useMemo(() => {\r\n // Count up all the responses that relate to answers marked as suspicious.\r\n let suspicionScore = 0;\r\n if (!!questionResponseEvents || !!questionAnswers) {\r\n // We only want to start counting when we have stuff to count\r\n //suspiciousResponses = questionResponseEvents.filter(item => questionAnswers.find(it => it.id === item.questionAnswerId)?.isSuspicious).length ?? 0\r\n // Find all answers that relate to suspicious responses\r\n const pickedSuspiciousAnswers = questionAnswers.filter(item => questionResponseEvents.find(it => it.questionAnswerId === item.id) && item.isSuspicious);\r\n\r\n // Add up all their suspicionScores\r\n pickedSuspiciousAnswers.forEach(item => suspicionScore = suspicionScore + item.suspicionScore!);\r\n\r\n }\r\n\r\n // If the score we counted exceeds the limit set on the assessment we need to mark the session as being suspicious.\r\n if (!!assessment && suspicionScore > assessment.maxSuspiciousAnswers) {\r\n return true;\r\n } else {\r\n return false;\r\n }\r\n }, [questionResponseEvents, questionAnswers, assessment]);\r\n\r\n // Browser detection\r\n const detectBrowser = useCallback(() => {\r\n const userAgent = navigator?.userAgent?.toLowerCase() ?? '';\r\n let browserName;\r\n\r\n if (userAgent.match(/chrome|chromium|crios/i)) {\r\n browserName = 'Chrome';\r\n return browserName;\r\n }\r\n if (userAgent.match(/firefox|fxios/i)) {\r\n browserName = 'Firefox';\r\n return browserName;\r\n }\r\n if (userAgent.match(/safari/i)) {\r\n browserName = 'Safari';\r\n return browserName;\r\n }\r\n if (userAgent.match(/opr\\//i)) {\r\n browserName = 'Opera';\r\n return browserName;\r\n }\r\n if (userAgent.match(/edg/i)) {\r\n browserName = 'Edge';\r\n return browserName;\r\n }\r\n\r\n return \"No browser detection\";\r\n\r\n }, []);\r\n\r\n // Detect Operating System\r\n const detectOS = useCallback(() => {\r\n const userAgent = navigator?.userAgent?.toLowerCase() ?? '';\r\n let osName;\r\n\r\n if (userAgent.indexOf('win') > -1) {\r\n osName = 'Windows';\r\n return osName;\r\n }\r\n if (userAgent.indexOf('iphone') > -1 || userAgent.indexOf('ipad') > -1) {\r\n osName = 'iOS';\r\n return osName;\r\n }\r\n if (userAgent.indexOf('mac') > -1) {\r\n osName = 'MacOS';\r\n return osName;\r\n }\r\n if (userAgent.indexOf('android') > -1) {\r\n osName = 'Android';\r\n return osName;\r\n }\r\n if (userAgent.indexOf('linux') > -1) {\r\n osName = 'Linux';\r\n return osName;\r\n }\r\n if (userAgent.indexOf('x11') > -1) {\r\n osName = 'UNIX';\r\n return osName;\r\n }\r\n return \"No OS detection\";\r\n\r\n }, []);\r\n\r\n // Get device metrics\r\n const browserData = useMemo(() => {\r\n return {\r\n userAgent: window.navigator.userAgent,\r\n browser: detectBrowser(),\r\n platform: detectOS(),\r\n screenResolution: `${window.screen.width}x${window.screen.height}`,\r\n screenOrientation: window.screen.orientation.type,\r\n windowResolution: `${window.innerWidth}x${window.innerHeight}`,\r\n colorDepth: window.screen.colorDepth,\r\n touch: window.navigator.maxTouchPoints > 0 ? 'Touch Device' : 'Non Touch Device',\r\n };\r\n }, [detectBrowser, detectOS]);\r\n \r\n // Save everything events to the database.\r\n const [saveEverything, { errors: saveEverythingErrors }] = useAsyncCallback(async (options?: { currentPosition?: number, }) => {\r\n // Save the question response events.\r\n for (const item of questionResponseEventsManager.added) { await saveQuestionResponseEvent(item.id, questionResponseEventsManager.changesFor(item.id), true); }\r\n for (const item of questionResponseEventsManager.updated) { await saveQuestionResponseEvent(item.id, questionResponseEventsManager.changesFor(item.id), false); }\r\n for (const item of questionResponseEventsManager.removed) { await removeQuestionResponseEvent(item.id); }\r\n questionResponseEventsManager.markAsSaved(questionResponseEventsManager.model);\r\n\r\n const filteredSequenceQuestions = questionSequenceQuestions.filter(item => item.archived === false);\r\n\r\n var questionnaireQuestions: Array = [];\r\n filteredSequenceQuestions.forEach(item => questionnaireQuestions.push(item.childQuestion));\r\n\r\n // Calculate the total score.\r\n const assessmentScore = calculateAssessmentScore(questions ?? [], questionResponseEventsManager.model, subscription, filteredSequenceQuestions, questionnaireQuestions);\r\n\r\n // Store the new score and current position.\r\n const newPosition = options?.currentPosition ?? 0;\r\n\r\n // Work out if we are finished or not.\r\n const isFinished = (newPosition >= finishPageIndex) ? true : false;\r\n\r\n const newChanges = {\r\n totalScore: assessmentScore.score,\r\n markedSuspicious: exceedsSuspiciousLimit,\r\n // Update the saved current position if we have progressed further than before.\r\n currentPosition: newPosition > model.currentPosition ? newPosition : model.currentPosition,\r\n\r\n // If we're newly finished, mark the dates.\r\n isFinished: !model.isFinished && isFinished ? true : model.isFinished,\r\n endDate: !model.endDate && isFinished ? moment().toISOString() : model.endDate,\r\n browserDataJson: model?.browserDataJson === '' ? JSON.stringify(browserData) : model?.browserDataJson,\r\n } as Partial;\r\n\r\n // Update the new changes into the state.\r\n change(newChanges);\r\n\r\n // Save the session with the new changes.\r\n await saveAssessmentSession(model.id, { ...changes, ...newChanges, }, false);\r\n\r\n // If we are newly finished, then we also want to update all the driver metrics etc.\r\n if (isFinished && !model.isFinished) {\r\n const driverMetricScores = assessmentScore.driverMetricBreakdown\r\n .filter(item => !!item.driverMetricId)\r\n .map(item => ({ driverMetricId: item.driverMetricId ?? '', score: item.score.score, }));\r\n\r\n await applyDriverMetricsForAssessmentSession({\r\n assessmentSessionId: model.id,\r\n driverMetricScores: driverMetricScores,\r\n });\r\n }\r\n }, [questionResponseEventsManager, saveQuestionResponseEvent, removeQuestionResponseEvent, change, saveAssessmentSession, pages, applyDriverMetricsForAssessmentSession, finishPageIndex, exceedsSuspiciousLimit]);\r\n\r\n // Track the active question and assessment item.\r\n // NOTE we set the default to -1 as we don't want to start on any page until we have data ready, even the Start Page. In particular not doing this\r\n // can cause funny behaviour for the Next button, which gets enabled by the start page when we load index 0 and then remains enabled when we jump to\r\n // the previous page once the state has been loaded.\r\n const [currentPageIndex, setCurrentPageIndex] = useState(-1);\r\n const {\r\n currentPage,\r\n currentAssessmentItem,\r\n currentQuestion,\r\n } = useMemo(() => {\r\n // If we're at the start then return n\r\n if (currentPageIndex < 0 || currentPageIndex >= pages.length) {\r\n return {\r\n currentPage: undefined,\r\n currentAssessmentItem: undefined,\r\n currentQuestion: undefined,\r\n };\r\n }\r\n\r\n const page = pages[currentPageIndex];\r\n const assessmentItem = assessmentItems?.find(item => item.id === page.assessmentItemId);\r\n const question = questions?.find(item => item.id === page.questionId);\r\n\r\n return {\r\n currentPage: page,\r\n currentAssessmentItem: assessmentItem,\r\n currentQuestion: question,\r\n };\r\n }, [currentPageIndex, pages, assessmentItems, questions,]);\r\n\r\n // If we are continuing a session jump to the right page.\r\n const [hasJumpedToInitialPage, setHasJumpedToInitialPage] = useState(false);\r\n useEffect(() => {\r\n if (!storeModel) {\r\n return;\r\n }\r\n\r\n if (hasJumpedToInitialPage) {\r\n return;\r\n }\r\n\r\n let initialPageIndex = storeModel.currentPosition ?? 0;\r\n if (finishPageOnly) {\r\n initialPageIndex = finishPageIndex;\r\n }\r\n\r\n if (initialPageIndex < 0) {\r\n initialPageIndex = 0;\r\n } else if (initialPageIndex >= pages.length) {\r\n initialPageIndex = pages.length - 1;\r\n } else if (initialPageIndex > finishPageIndex) {\r\n // If we are trying to land past the finish page (i.e. individual question feedback shown at the end),\r\n // land instead on the finish page.\r\n initialPageIndex = finishPageIndex;\r\n }\r\n\r\n setCanNavigateForwards(false);\r\n setHasJumpedToInitialPage(true);\r\n setCurrentPageIndex(initialPageIndex);\r\n }, [model, currentPageIndex, pages, hasJumpedToInitialPage, setHasJumpedToInitialPage, storeModel, finishPageIndex, finishPageOnly]);\r\n\r\n // Navigation backwards and forwards between questions.\r\n const [canNavigateBack, setCanNavigateBack] = useState(false);\r\n const navigateBack = useCallback(() => {\r\n // Move on to the next question.\r\n setCurrentPageIndex(prevState => {\r\n if (prevState <= 0) {\r\n return prevState;\r\n }\r\n\r\n const newPageIndex = prevState - 1;\r\n\r\n // Save everything each time the page changes.\r\n saveEverything({ currentPosition: newPageIndex });\r\n return newPageIndex;\r\n });\r\n }, [setCurrentPageIndex, saveEverything]);\r\n\r\n // Backwards navigation should be available in training but not assessments.\r\n useEffect(() => {\r\n const expectedCanNavigateBack = activeAssessmentType === AssessmentType.TrainingModule ? true : false;\r\n if (canNavigateBack !== expectedCanNavigateBack) {\r\n setCanNavigateBack(expectedCanNavigateBack);\r\n }\r\n }, [activeAssessmentType, setCanNavigateBack, canNavigateBack]);\r\n\r\n const [canNavigateForwards, setCanNavigateForwards] = useState(false);\r\n\r\n const navigateForwards = useCallback(() => {\r\n // Don't allow any further navigation until the question unlocks it again.\r\n setCanNavigateForwards(false);\r\n\r\n // Move on to the next question.\r\n setCurrentPageIndex(prevState => {\r\n if (prevState >= (pages.length - 1)) {\r\n return prevState;\r\n }\r\n\r\n const newPageIndex = prevState + 1;\r\n\r\n // Save everything each time the page changes.\r\n saveEverything({ currentPosition: newPageIndex });\r\n return newPageIndex;\r\n });\r\n }, [setCanNavigateForwards, setCurrentPageIndex, pages, saveEverything]);\r\n\r\n // Finish button handler.\r\n const navigateFinish = useCallback(() => {\r\n // Save everything each time the page changes.\r\n saveEverything();\r\n\r\n // If the subscription is a study, then instead of going back to the page we came from, redirect the user to the study completed page which\r\n // will log them out and return them to their study management website if one is configured.\r\n if (subscription?.subscriptionType === SubscriptionType.Study) {\r\n history.push(`/study-complete/${model.id}`);\r\n return;\r\n }\r\n\r\n // Otherwise go back to the page this was launched from.\r\n history.goBack();\r\n }, [saveEverything, history, subscription, model]);\r\n\r\n // When page is complete we unlock the ability to go forward.\r\n const onPageComplete = useCallback(() => {\r\n setCanNavigateForwards(true);\r\n }, [setCanNavigateForwards]);\r\n\r\n const [furthestTravelled, setFurthestTravelled] = useState(0);\r\n\r\n useEffect(() => {\r\n\r\n if (currentPageIndex > furthestTravelled) {\r\n\r\n setFurthestTravelled(currentPageIndex);\r\n\r\n }\r\n if (currentPageIndex < furthestTravelled) {\r\n\r\n onPageComplete();\r\n\r\n }\r\n\r\n }, [currentPageIndex, furthestTravelled, setFurthestTravelled, onPageComplete]);\r\n\r\n // Admins can always see all feedback breakdowns, regardless of the assessments feedback when they launch in results mode (finsihPageOnly=true).\r\n // Handle that specialk case now.\r\n const { data: { roles: currentUserRoles } } = useCurrentUserRoles();\r\n const finishPageFeedbackStyle = useMemo(() => {\r\n const isAdministrator = !!currentUserRoles?.find(it => it === IdentityRoles.Administration || it === IdentityRoles.DriverManagement || it === IdentityRoles.SubscriptionAdministration);\r\n if (finishPageOnly && isAdministrator) {\r\n if (\r\n assessment?.feedbackStyle !== FeedbackStyle.SummaryFeedback\r\n && assessment?.feedbackStyle !== FeedbackStyle.EachQuestionFeedback\r\n ) {\r\n return FeedbackStyle.SummaryFeedback;\r\n }\r\n }\r\n\r\n return assessment?.feedbackStyle as FeedbackStyle | undefined;\r\n }, [finishPageOnly, currentUserRoles, assessment]);\r\n\r\n return (\r\n \r\n \r\n \r\n \r\n \r\n

\r\n {assessment?.name}\r\n

\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n
\r\n
\r\n
\r\n\r\n \r\n \r\n\r\n
\r\n {\r\n !currentPage ? null\r\n : currentPage.pageType === 'start' ? (\r\n \r\n )\r\n : currentPage.pageType === 'finish' ? (\r\n item.childQuestion))}\r\n onPageComplete={onPageComplete}\r\n questions={questions}\r\n questionFeedbacks={questionFeedbacks}\r\n questionResponseEvents={questionResponseEvents}\r\n calculateQuestionScore={calculateQuestionScore}\r\n pages={pages}\r\n driverMetrics={driverMetrics ?? []}\r\n subscription={subscription}\r\n allCurrentQuestionSequence={questionSequenceQuestions}\r\n exceedsSuspiciousLimit={exceedsSuspiciousLimit}\r\n />\r\n )\r\n : currentPage.pageType === 'question' ? (\r\n <>\r\n \r\n \r\n\r\n )\r\n : currentPage.pageType === 'questionFeedback' ? (\r\n item.questionId === currentQuestion?.id)}\r\n blobReferences={blobReferences}\r\n questionScore={calculateQuestionScore(questionResponseEventsManager.model.filter(item => item.questionId === currentQuestion?.id && item.archived === false) ?? [], subscription)}\r\n onPageComplete={onPageComplete}\r\n />\r\n )\r\n : null\r\n }\r\n
\r\n\r\n \r\n \r\n 0}>\r\n \r\n \r\n \r\n \r\n \r\n 2 /* Only show if we have real activities to do, not while loading */}>\r\n \r\n \r\n \r\n \r\n {\r\n currentPageIndex >= (pages.length - 1) ?\r\n (\r\n \r\n ) : (\r\n \r\n \r\n \r\n )\r\n }\r\n \r\n \r\n \r\n
\r\n
\r\n );\r\n};","import * as React from 'react';\r\nimport { useLazyQuery } from \"@apollo/react-hooks\";\r\nimport gql from \"graphql-tag\";\r\nimport { Guid } from \"guid-string\";\r\nimport { AsyncLoadResult, AsyncLoadOptions } from '../../../../shared/abstractStore';\r\nimport { launchAssessmentSessionViewModelQuery, launchAssessmentSessionViewModelQueryVariables } from '../../generated/launchAssessmentSessionViewModelQuery';\r\nimport { assessmentSessionFieldsFragment } from '../../models/AssessmentSession';\r\nimport { mainApiConfig } from '../../../../configure/mainApiConfig';\r\nimport { questionFieldsFragment } from '../../models/Question';\r\nimport { assessmentFieldsFragment } from '../../models/Assessment';\r\nimport { assessmentFeedbackFieldsFragment } from '../../models/AssessmentFeedback';\r\nimport { questionAnswerFieldsFragment } from '../../models/QuestionAnswer';\r\nimport { questionFeedbackFieldsFragment } from '../../models/QuestionFeedback';\r\nimport { blobReferenceFieldsFragment } from '../../models/BlobReference';\r\nimport { questionResponseEventFieldsFragment } from '../../models/QuestionResponseEvent';\r\nimport { assessmentItemFieldsFragment } from '../../models/AssessmentItem';\r\nimport { assessmentItemQuestionFieldsFragment } from '../../models/AssessmentItemQuestion';\r\nimport { questionSequenceQuestionFieldsFragment } from '../../models/QuestionSequenceQuestion';\r\nimport { subscriptionFieldsFragment } from '../../models/Subscription';\r\n\r\n/**\r\n * Get everything needed to lauch an AssessmentSession.\r\n * @param id\r\n * @param options\r\n */\r\nexport function useLaunchAssessmentSessionViewModel(id: string | undefined | null, options: AsyncLoadOptions = {}): AsyncLoadResult {\r\n // Query the data we need form the api.\r\n const [load, { data, loading, error, refetch }] = useLazyQuery(\r\n gql`\r\n query launchAssessmentSessionViewModelQuery ($id: ID!) {\r\n viewModel: launchAssessmentSessionViewModel(id: $id) {\r\n id\r\n assessmentSession {\r\n ...assessmentSessionFields\r\n }\r\n assessment {\r\n ...assessmentFields\r\n }\r\n assessmentFeedbacks {\r\n ...assessmentFeedbackFields\r\n }\r\n questions {\r\n ...questionFields\r\n }\r\n questionSequenceQuestions {\r\n ...questionSequenceQuestionFields\r\n\r\n childQuestion {\r\n ...questionFields\r\n }\r\n }\r\n questionnaireQuestionAnswers {\r\n ...questionAnswerFields\r\n }\r\n questionAnswers {\r\n ...questionAnswerFields\r\n }\r\n questionFeedbacks {\r\n ...questionFeedbackFields\r\n }\r\n blobReferences {\r\n ...blobReferenceFields\r\n }\r\n questionResponseEvents {\r\n ...questionResponseEventFields\r\n }\r\n assessmentItems {\r\n ...assessmentItemFields\r\n }\r\n assessmentItemQuestions {\r\n ...assessmentItemQuestionFields\r\n }\r\n assessmentItemSessionOrders {\r\n id\r\n questionIds {\r\n id\r\n }\r\n }\r\n subscription {\r\n ...subscriptionFields\r\n }\r\n }\r\n }\r\n\r\n ${assessmentSessionFieldsFragment}\r\n ${assessmentFieldsFragment}\r\n ${assessmentFeedbackFieldsFragment}\r\n ${questionFieldsFragment}\r\n ${questionAnswerFieldsFragment}\r\n ${questionFeedbackFieldsFragment}\r\n ${blobReferenceFieldsFragment}\r\n ${questionResponseEventFieldsFragment}\r\n ${assessmentItemFieldsFragment}\r\n ${assessmentItemQuestionFieldsFragment}\r\n ${questionSequenceQuestionFieldsFragment}\r\n ${subscriptionFieldsFragment}\r\n `,\r\n {\r\n variables: {\r\n id: id ?? Guid.empty\r\n },\r\n fetchPolicy: options.fetchPolicy ?? mainApiConfig.defaultFetchPolicy,\r\n pollInterval: options.pollInterval,\r\n onCompleted: (data) => {\r\n if (options.onCompleted) {\r\n options.onCompleted(data);\r\n }\r\n }\r\n }\r\n );\r\n\r\n // Run the query (unless we are being lazy).\r\n React.useEffect(() => {\r\n if (!options.lazy) {\r\n load();\r\n }\r\n }, [options.lazy, load])\r\n\r\n // Return the results.\r\n const refresh = React.useCallback(async () => { !refetch ? await load() : await refetch(); }, [refetch, load]);\r\n return React.useMemo(() => ({\r\n data: data ?? ({} as any),\r\n refresh: refresh,\r\n isLoading: loading,\r\n errors: error\r\n }), [data, refresh, loading, error]);\r\n}\r\n","import * as React from 'react';\r\nimport { useLazyQuery } from \"@apollo/react-hooks\";\r\nimport gql from \"graphql-tag\";\r\nimport { AsyncLoadResult, AsyncLoadOptions } from '../../../../shared/abstractStore';\r\nimport { launchAssessmentSessionSupportingDataQuery } from '../../generated/launchAssessmentSessionSupportingDataQuery';\r\nimport { mainApiConfig } from '../../../../configure/mainApiConfig';\r\nimport { driverMetricFieldsFragment } from '../../models/DriverMetric';\r\n\r\n/**\r\n * Supporting data for LeaunchAssessment that loads static data (e.g. dropdowns) that are not changed by the model being used.\r\n * @param options\r\n */\r\nexport function useLaunchAssessmentSessionSupportingData(options: AsyncLoadOptions = {}): AsyncLoadResult {\r\n // Query the data we need form the api.\r\n const [load, { data, loading, error, refetch }] = useLazyQuery(\r\n gql`\r\n query launchAssessmentSessionSupportingDataQuery {\r\n driverMetrics {\r\n ...driverMetricFields\r\n }\r\n }\r\n\r\n ${driverMetricFieldsFragment}\r\n `,\r\n {\r\n variables: {\r\n },\r\n fetchPolicy: options.fetchPolicy ?? mainApiConfig.defaultFetchPolicy,\r\n pollInterval: options.pollInterval,\r\n onCompleted: (data) => {\r\n if (options.onCompleted) {\r\n options.onCompleted(data);\r\n }\r\n }\r\n }\r\n );\r\n\r\n // Run the query (unless we are being lazy).\r\n React.useEffect(() => {\r\n if (!options.lazy) {\r\n load();\r\n }\r\n }, [options.lazy, load])\r\n\r\n // Return the results.\r\n const refresh = React.useCallback(async () => { !refetch ? await load() : await refetch(); }, [refetch, load]);\r\n return React.useMemo(() => ({\r\n data: data ?? ({} as any),\r\n refresh: refresh,\r\n isLoading: loading,\r\n errors: error\r\n }), [data, refresh, loading, error]);\r\n}","import * as React from 'react';\r\nimport { AssessmentSessionCreateInput, AssessmentSessionUpdateInput } from '../generated/globalTypes';\r\nimport { useSaveInStore, SaveInStoreOptions } from '../../../shared/useSaveInStore';\r\nimport { useCreateAssessmentSessionCallback } from './useCreateAssessmentSessionCallback';\r\nimport { useUpdateAssessmentSessionCallback } from './useUpdateAssessmentSessionCallback';\r\nimport { AssessmentSession } from '../models/AssessmentSession';\r\n\r\n/**\r\n * Get a callback to save a AssessmentSession in the store using either a create or update.\r\n */\r\nexport function useSaveAssessmentSessionCallback(options: SaveInStoreOptions = {}) {\r\n const [_create, createStatus] = useCreateAssessmentSessionCallback();\r\n const create = React.useCallback((model: Partial) => _create(model as AssessmentSessionCreateInput), [_create]);\r\n\r\n const [_update, updateStatus] = useUpdateAssessmentSessionCallback();\r\n const update = React.useCallback((id: string, changes: Partial) => _update(id, changes as AssessmentSessionUpdateInput), [_update]);\r\n\r\n return useSaveInStore(\r\n [create, createStatus],\r\n [update, updateStatus],\r\n options\r\n );\r\n}\r\n","import { useMutation } from \"@apollo/react-hooks\";\r\nimport { useAsyncCallback } from 'react-use-async-callback';\r\nimport gql from \"graphql-tag\";\r\nimport { AsyncActionStatus } from '../../../shared/abstractStore';\r\nimport { applyDriverMetricsForAssessmentSessionMutation, applyDriverMetricsForAssessmentSessionMutationVariables } from '../generated/applyDriverMetricsForAssessmentSessionMutation';\r\nimport { ApplyDriveMetricForAssessmentSessionInput } from '../generated/globalTypes';\r\nimport { userDriverMetricFieldsFragment } from '../models/UserDriverMetric';\r\n\r\n/**\r\n * Get a callback to apply change to UserDriverMetrics in the store for an assessment.\r\n */\r\nexport function useApplyDriverMetricsForAssessmentSessionCallback(): [(model: ApplyDriveMetricForAssessmentSessionInput) => Promise, AsyncActionStatus] {\r\n const [mutationAction, { error }] = useMutation(\r\n gql`\r\n mutation applyDriverMetricsForAssessmentSessionMutation ($model: ApplyDriveMetricForAssessmentSessionInput!) {\r\n applyDriverMetricsForAssessmentSession(model: $model) {\r\n ...userDriverMetricFields\r\n }\r\n }\r\n\r\n ${userDriverMetricFieldsFragment}\r\n `\r\n );\r\n\r\n // Wrap the mutation in a standard callback.\r\n const [action, { isExecuting, errors: actionErrors }] = useAsyncCallback(async (model: ApplyDriveMetricForAssessmentSessionInput) => {\r\n const result = await mutationAction({ variables: { model: model } });\r\n if (result.errors && result.errors.length) {\r\n throw result.errors;\r\n }\r\n }, [mutationAction]);\r\n\r\n return [action, { isExecuting: isExecuting, errors: error ? error.message : actionErrors }];\r\n}\r\n","import * as React from 'react';\r\nimport { QuestionResponseEventCreateInput, QuestionResponseEventUpdateInput } from '../generated/globalTypes';\r\nimport { useSaveInStore, SaveInStoreOptions } from '../../../shared/useSaveInStore';\r\nimport { useCreateQuestionResponseEventCallback } from './useCreateQuestionResponseEventCallback';\r\nimport { useUpdateQuestionResponseEventCallback } from './useUpdateQuestionResponseEventCallback';\r\nimport { QuestionResponseEvent } from '../models/QuestionResponseEvent';\r\n\r\n/**\r\n * Get a callback to save a QuestionResponseEvent in the store using either a create or update.\r\n */\r\nexport function useSaveQuestionResponseEventCallback(options: SaveInStoreOptions = {}) {\r\n const [_create, createStatus] = useCreateQuestionResponseEventCallback();\r\n const create = React.useCallback((model: Partial) => _create(model as QuestionResponseEventCreateInput), [_create]);\r\n\r\n const [_update, updateStatus] = useUpdateQuestionResponseEventCallback();\r\n const update = React.useCallback((id: string, changes: Partial) => _update(id, changes as QuestionResponseEventUpdateInput), [_update]);\r\n\r\n return useSaveInStore(\r\n [create, createStatus],\r\n [update, updateStatus],\r\n options\r\n );\r\n}\r\n","import { useEffect } from \"react\";\r\nimport { ConditionalFragment } from \"react-conditionalfragment\";\r\nimport { useHistory, useParams } from \"react-router\";\r\nimport { useCurrentUserId } from \"../../api/account\";\r\nimport { useInitializeAssessmentSessionCallback } from \"../../api/main/assessmentSessions/useInitializeAssessmentSessionCallback\";\r\nimport { AssessmentType } from \"../../api/main/models/codeOnly/AssessmentType\";\r\nimport { AlertOnErrors } from \"../../shared/alertOnErrors\";\r\nimport { Background } from \"../shared/background/Background\";\r\nimport { LoadingIndicator } from \"../shared/LoadingIndicator\";\r\nimport { useUserAssessmentAssignmentsListViewBaseViewModel } from '../../api/main/userAssessmentAssignments/viewModels/useUserAssessmentAssignmentsListViewBaseViewModel';\r\nimport { useCreateUserAssessmentAssignmentCallback } from '../../api/main/userAssessmentAssignments/useCreateUserAssessmentAssignmentCallback';\r\nimport { UserAssessmentAssignment, userAssessmentAssignmentDefaultValues } from '../../api/main/models/UserAssessmentAssignment';\r\nimport * as React from 'react';\r\nimport { UserAssessmentAssignmentCreateInput } from '../../api/main/generated/globalTypes';\r\n\r\nexport interface StartAssessmentBaseProps {\r\n defaultAssessmentType: AssessmentType,\r\n}\r\n\r\n/**\r\n * Start an assessment by creating and launching an assessment session.\r\n */\r\nexport const StartAssessmentBase = (props: StartAssessmentBaseProps) => {\r\n const {\r\n defaultAssessmentType\r\n } = props;\r\n\r\n const {\r\n userId: paramUserId,\r\n assessmentId, subscriptionTeamId\r\n } = useParams<{ userId?: string, assessmentId: string, subscriptionTeamId: string | undefined }>();\r\n\r\n const [_create] = useCreateUserAssessmentAssignmentCallback();\r\n const create = React.useCallback((model: Partial) => _create(model as UserAssessmentAssignmentCreateInput), [_create]);\r\n\r\n\r\n const currentUserId = useCurrentUserId();\r\n const userId = paramUserId || currentUserId;\r\n\r\n const history = useHistory();\r\n\r\n const [initializeAssessment, { isExecuting: isInitializingAssessment, errors: initializeAssessmentErrors }] = useInitializeAssessmentSessionCallback();\r\n\r\n const {\r\n data: {\r\n items: storeUserAssessmentAssignments,\r\n }, } = useUserAssessmentAssignmentsListViewBaseViewModel(undefined, { pageSize: undefined, assessmentTypes: [defaultAssessmentType], subscriptionTeamId: subscriptionTeamId, userId: userId });\r\n\r\n // Create the assessment.\r\n const [hasInitializationStarted, setHasInitializationStarted] = React.useState(false);\r\n useEffect(() => {\r\n // If we don't have a user yet, wait until we do.\r\n if (!userId) {\r\n return;\r\n }\r\n\r\n // If we're already in the process of launching, don't do it again.\r\n if (hasInitializationStarted) {\r\n return;\r\n }\r\n\r\n // Record in the state that we are in the process of launching, otherwise we can sometimes have a race condition where\r\n // we end up creating two sessions because we get called again before the first one is complete and redirected us to another screen.\r\n setHasInitializationStarted(true);\r\n\r\n var currentUserAssessmentAssignment;\r\n var checked = false;\r\n if (storeUserAssessmentAssignments) {\r\n //check if we have a user assessment assignment for the current assessment and user\r\n currentUserAssessmentAssignment = storeUserAssessmentAssignments.find(item => item.userId === userId && item.assessmentId === assessmentId) ?? undefined;\r\n checked = true;\r\n }\r\n\r\n if (!currentUserAssessmentAssignment && checked === true) {\r\n // If we dont have a pre-existing user assessment assingment, it means we are previewing and want to create a new one so it shows corrrectly on the dashboard\r\n const newUserAssessmentAssignment = {\r\n ...userAssessmentAssignmentDefaultValues(),\r\n userId: userId,\r\n assessmentId: assessmentId,\r\n }\r\n\r\n create(newUserAssessmentAssignment);\r\n\r\n }\r\n\r\n\r\n // Now we have a user, lets one-time run a create method to create the assessment session and launch it.\r\n (async () => {\r\n const model = await initializeAssessment(assessmentId, userId);\r\n\r\n if (model) {\r\n history.replace(`/assessment/launch/${model.id}`);\r\n }\r\n })();\r\n }, [userId, assessmentId, initializeAssessment, history, storeUserAssessmentAssignments, create, hasInitializationStarted, setHasInitializationStarted]);\r\n\r\n return (\r\n \r\n \r\n\r\n \r\n \r\n \r\n \r\n );\r\n};","import { useMutation } from \"@apollo/react-hooks\";\r\nimport { useAsyncCallback } from 'react-use-async-callback';\r\nimport gql from \"graphql-tag\";\r\nimport { AsyncActionStatus } from '../../../shared/abstractStore';\r\nimport { initializeAssessmentSessionMutation, initializeAssessmentSessionMutationVariables } from '../generated/initializeAssessmentSessionMutation';\r\nimport { AssessmentSession, assessmentSessionFieldsFragment } from '../models/AssessmentSession';\r\n\r\n/**\r\n * Get a callback to create and initialize a AssessmentSession in the store.\r\n */\r\nexport function useInitializeAssessmentSessionCallback(): [(assessmentId: string, userId: string) => Promise, AsyncActionStatus] {\r\n const [mutationAction, { error }] = useMutation(\r\n gql`\r\n mutation initializeAssessmentSessionMutation ($assessmentId: ID!, $userId: ID!) {\r\n initializeAssessmentSession(assessmentId: $assessmentId, userId: $userId) {\r\n ...assessmentSessionFields\r\n }\r\n }\r\n\r\n ${assessmentSessionFieldsFragment}\r\n `\r\n );\r\n\r\n // Wrap the mutation in a standard callback.\r\n const [action, { isExecuting, errors: actionErrors }] = useAsyncCallback(async (assessmentId: string, userId: string) => {\r\n const result = await mutationAction({ variables: { assessmentId: assessmentId, userId: userId } });\r\n if (result.errors && result.errors.length) {\r\n throw result.errors;\r\n }\r\n return result.data?.initializeAssessmentSession;\r\n }, [mutationAction]);\r\n\r\n return [action, { isExecuting: isExecuting, errors: error ? error.message : actionErrors }];\r\n}\r\n","import { AssessmentType } from \"../../../api/main/models/codeOnly/AssessmentType\";\r\nimport { StartAssessmentBase } from \"../StartAssessmentBase\";\r\n\r\n/**\r\n * Start an assessment session.\r\n */\r\nexport const StartAssessment = () => ();\r\n","import { RouteEntry } from \"../../../shared/routes\";\r\nimport { AssessmentResults } from \"./AssessmentResults\";\r\nimport { LaunchAssessment } from \"./LaunchAssessment\";\r\nimport { StartAssessment } from \"./StartAssessment\";\r\n\r\n\r\nexport const assessmentSessionAssessmentRoutes: Array = [\r\n { path: '/assessment/start/:assessmentId', exact: true, component: StartAssessment, authorize: true, },\r\n { path: '/assessment/startFor/:userId/:assessmentId', exact: true, component: StartAssessment, authorize: true, },\r\n { path: '/assessment/launch/:id', component: LaunchAssessment, authorize: true, },\r\n { path: '/assessment/results/:id', component: AssessmentResults, authorize: true, },\r\n];\r\n","import { AssessmentType } from \"../../../api/main/models/codeOnly/AssessmentType\";\r\nimport { LaunchAssessmentBase } from \"../launch/LaunchAssessmentBase\";\r\n\r\n/**\r\n * Launch an assessment session.\r\n */\r\nexport const LaunchAssessment = () => ();\r\n","import { AssessmentType } from \"../../../api/main/models/codeOnly/AssessmentType\";\r\nimport { LaunchAssessmentBase } from \"../launch/LaunchAssessmentBase\";\r\n\r\n/**\r\n * Show results of an assessment session.\r\n */\r\nexport const AssessmentResults = () => ();\r\n","import { AssessmentType } from \"../../../api/main/models/codeOnly/AssessmentType\";\r\nimport { StartAssessmentBase } from \"../StartAssessmentBase\";\r\n\r\n/**\r\n * Start an training session.\r\n */\r\nexport const StartTraining = () => ();\r\n","import { RouteEntry } from \"../../../shared/routes\";\r\nimport { LaunchTraining } from \"./LaunchTraining\";\r\nimport { StartTraining } from \"./StartTraining\";\r\nimport { TrainingResults } from \"./TrainingResults\";\r\n\r\n\r\nexport const assessmentSessionTrainingRoutes: Array = [\r\n { path: '/training/start/:assessmentId', exact: true, component: StartTraining, authorize: true, },\r\n { path: '/training/startFor/:userId/:assessmentId', exact: true, component: StartTraining, authorize: true, },\r\n { path: '/training/launch/:id', component: LaunchTraining, authorize: true, },\r\n { path: '/training/results/:id', component: TrainingResults, authorize: true, },\r\n];\r\n","import { AssessmentType } from \"../../../api/main/models/codeOnly/AssessmentType\";\r\nimport { LaunchAssessmentBase } from \"../launch/LaunchAssessmentBase\";\r\n\r\n/**\r\n * Launch an training session.\r\n */\r\nexport const LaunchTraining = () => ();\r\n","import { AssessmentType } from \"../../../api/main/models/codeOnly/AssessmentType\";\r\nimport { LaunchAssessmentBase } from \"../launch/LaunchAssessmentBase\";\r\n\r\n/**\r\n * View results for a training session.\r\n */\r\nexport const TrainingResults = () => ();\r\n","import { AssessmentSession } from \"../../../api/main/models/AssessmentSession\";\r\n\r\n/**\r\n * Returns the latest session for each user assignment combination.\r\n */\r\nexport function getLatestSessions(\r\n sessions: Array,\r\n) {\r\n // Get only the latest (complete) session for each user and assessment pair.\r\n let latestSessions: Array = [];\r\n for (const session of sessions) {\r\n // If the session is not complete, ignore it.\r\n if (!session.isFinished) {\r\n continue;\r\n }\r\n\r\n // If we already have a session for this assesmsnet/user combination, then we only want to keep\r\n // the one finished most recently.\r\n const existingSession = latestSessions.find(item => item.assessmentId === session.assessmentId && item.userId === session.userId);\r\n if (existingSession) {\r\n if (existingSession.startDate < session.startDate) {\r\n const index = latestSessions.indexOf(existingSession);\r\n latestSessions[index] = session;\r\n }\r\n } else {\r\n latestSessions.push(session);\r\n }\r\n }\r\n\r\n let latestSessionsIncludingIncomplete: Array = [];\r\n for (const session of sessions) {\r\n // If we already have a session for this assesmsnet/user combination, then we only want to keep\r\n // the one finished most recently.\r\n const existingSession = latestSessionsIncludingIncomplete.find(item => item.assessmentId === session.assessmentId && item.userId === session.userId);\r\n if (existingSession) {\r\n if (existingSession.startDate < session.startDate) {\r\n const index = latestSessionsIncludingIncomplete.indexOf(existingSession);\r\n latestSessionsIncludingIncomplete[index] = session;\r\n }\r\n } else {\r\n latestSessionsIncludingIncomplete.push(session);\r\n }\r\n }\r\n\r\n return {\r\n latestSessions,\r\n latestSessionsIncludingIncomplete,\r\n };\r\n}\r\n","import i18next from \"i18next\";\r\nimport { Assessment } from \"../../../api/main/models/Assessment\";\r\nimport { AssessmentSession } from \"../../../api/main/models/AssessmentSession\";\r\nimport { AssessmentType } from \"../../../api/main/models/codeOnly/AssessmentType\";\r\nimport { Profile } from \"../../../api/main/models/Profile\";\r\nimport { Subscription } from \"../../../api/main/models/Subscription\";\r\nimport { SubscriptionAssessment } from \"../../../api/main/models/SubscriptionAssessment\";\r\nimport { UserAssessmentAssignment } from \"../../../api/main/models/UserAssessmentAssignment\";\r\nimport { UserDriverMetric } from \"../../../api/main/models/UserDriverMetric\";\r\nimport { RiskRules } from \"../../../services/OverallRiskService\";\r\nimport { QuestionScore } from \"../../assessmentSessions/launch/utilities/calculateQuestionScore\";\r\nimport { questionScoreFromNumber } from \"../../assessmentSessions/launch/utilities/questionScoreFromNumber\";\r\nimport { calculateAverageScore } from \"./calculateAverageScore\";\r\nimport { getLatestSessions } from \"./getLatestSessions\";\r\n\r\n/**\r\n * Create a summary for the dashboard from the passed in sessions.\r\n */\r\nexport function generateDashboardSummary(\r\n sessions: Array,\r\n assessments: Array,\r\n profiles: Array,\r\n expandedUserAssessmentAssignments: Array,\r\n userDriverMetrics: Array,\r\n riskRules: RiskRules | undefined | null\r\n): DashboardSummary {\r\n const {\r\n latestSessions,\r\n latestSessionsIncludingIncomplete,\r\n } = getLatestSessions(sessions);\r\n\r\n // Get a list of assessments abd profies actually used in the sessions. Changed to assessments to not include any marked suspicious.\r\n const usedAssessments = assessments.filter(item => !!latestSessions.find(it => it.assessmentId === item.id && !it.markedSuspicious));\r\n const usedProfiles = profiles.filter(item => !!latestSessions.find(it => it.userId === item.userId));\r\n\r\n // Get a list of assessments that are suspicious\r\n const suspiciousAssessments = assessments.filter(item => !!latestSessions.find(it => it.assessmentId === item.id && it.markedSuspicious));\r\n\r\n // Calculate the average scores using the users latest sessions only.\r\n const averageScore = calculateAverageScore(latestSessions, riskRules);\r\n\r\n // Find all the unqiue assignments for the user and count them up.\r\n let uniqueAssignedAssessmentUserCombinations: Array<{ userId: string, assessmentId: string | null, }> = [];\r\n for (const assignment of expandedUserAssessmentAssignments) {\r\n\r\n const existing = uniqueAssignedAssessmentUserCombinations.find(it => it.userId === assignment.userId && it.assessmentId === assignment.assessmentId);\r\n if (existing) {\r\n continue;\r\n }\r\n\r\n uniqueAssignedAssessmentUserCombinations.push({ userId: assignment.userId, assessmentId: assignment.assessmentId, });\r\n }\r\n\r\n // Work out the overall summary of not started/starts/complete.\r\n const notStarted = uniqueAssignedAssessmentUserCombinations.filter(assignment => !latestSessionsIncludingIncomplete.find(it => it.assessmentId === assignment.assessmentId && it.userId === assignment.userId) && !!profiles.find(profile => profile.userId === assignment.userId)).length;\r\n const started = latestSessionsIncludingIncomplete.filter(it => !it.isFinished && !!profiles.find(profile => profile.userId === it.userId)).length;\r\n const complete = latestSessionsIncludingIncomplete.filter(it => it.isFinished && !!profiles.find(profile => profile.userId === it.userId)).length;\r\n\r\n // Use the user metrics to work out the user driver metrics score.\r\n let profileTotalUserMetricScores: Array<{ userId: string, score: number, }> = [];\r\n for (const profile of profiles) {\r\n const myDriverMetrics = userDriverMetrics.filter(it => it.userId === profile.userId);\r\n if (myDriverMetrics.length === 0) {\r\n continue;\r\n }\r\n\r\n let myUserDriverMetricTotalScore = 0;\r\n for (const metric of myDriverMetrics) {\r\n myUserDriverMetricTotalScore += metric.currentValue;\r\n }\r\n\r\n if (myDriverMetrics.length > 0) {\r\n myUserDriverMetricTotalScore = Math.round(myUserDriverMetricTotalScore / myDriverMetrics.length);\r\n }\r\n\r\n profileTotalUserMetricScores.push({ userId: profile.userId, score: myUserDriverMetricTotalScore, })\r\n }\r\n\r\n // Calculate the overall average score across all the used profiles.\r\n let totalUserDriverMetricScore = 0;\r\n for (const profileMetricScore of profileTotalUserMetricScores) {\r\n totalUserDriverMetricScore += profileMetricScore.score;\r\n }\r\n\r\n if (profileTotalUserMetricScores.length > 0) {\r\n totalUserDriverMetricScore = Math.round(totalUserDriverMetricScore / profileTotalUserMetricScores.length);\r\n }\r\n \r\n const averageUserDriverMetricScore = questionScoreFromNumber(totalUserDriverMetricScore, profileTotalUserMetricScores.length === 0, riskRules);\r\n\r\n // Return it all in a userful format.\r\n return {\r\n averageScore: averageScore,\r\n averageUserDriverMetricScore: averageUserDriverMetricScore,\r\n\r\n uniqueSessionsCount: latestSessions.length,\r\n totalFinishedSessionsCount: sessions.filter(item => item.isFinished).length,\r\n duplicateSessionsCount: sessions.length - latestSessions.length,\r\n\r\n assessmentsText: getNameSummary(usedAssessments.map(item => item.name), 4),\r\n suspiciousAssessmentText: getNameSummary(suspiciousAssessments.map(item => item.name), 4),\r\n usersText: getNameSummary(usedProfiles.map(item => i18next.t('common.fullName', '{{firstName}} {{lastName}}', { firstName: item.firstName, lastName: item.lastName })), 4),\r\n\r\n notStarted: notStarted,\r\n started: started,\r\n complete: complete,\r\n };\r\n}\r\n\r\nexport function generateDistributorDashboardSummary(\r\n subscriptions: Array,\r\n subscriptionId: string,\r\n userAssessmentAssignment: Array,\r\n subscriptionAssessmentAssignment: Array,\r\n assessments: Array,\r\n): DistributorDashboardSummary {\r\n\r\n const currentDistributorSubscriptions = subscriptions.filter(item => item.distributorSubscriptionId === subscriptionId);\r\n const distributorUserAssignments = userAssessmentAssignment.filter(item => currentDistributorSubscriptions.find(it => it.id === item.subscriptionId));\r\n const distributorAssignedAssessments = subscriptionAssessmentAssignment.filter(item => item.subscriptionId === subscriptionId);\r\n\r\n //attempt at counting individual assessments\r\n const assessmentAssignmentCounts: Array<{ AssessmentId: string, count: number }> = []\r\n distributorUserAssignments.forEach(item => {\r\n assessmentAssignmentCounts.push({ AssessmentId: item.assessmentId!,count: distributorUserAssignments.filter(it => it.assessmentId === item.assessmentId).length })\r\n })\r\n\r\n return {\r\n totalSubscriptionsCount: currentDistributorSubscriptions.length,\r\n distributorUserAssessmentAssignmentCount: distributorUserAssignments.filter(item => assessments.find(it => it.id === item.assessmentId)?.assessmentType === AssessmentType.Assessment).length,\r\n distributorUserTrainingAssignmentCount: distributorUserAssignments.filter(item => assessments.find(it => it.id === item.assessmentId)?.assessmentType === AssessmentType.TrainingModule).length,\r\n filteredAssessments: assessments.filter(item => distributorAssignedAssessments.find(it => it.assessmentId === item.id)),\r\n assessmentAssignments: assessmentAssignmentCounts,\r\n DistributorSubscriptionsText: getNameSummary(currentDistributorSubscriptions.map(item => item.companyName), 4),\r\n }\r\n\r\n}\r\n\r\n/**\r\n * Helpful function that lets us turn a list of names into a limited size list with \"and X others\".\r\n * @param names\r\n * @param maxNamesToShow\r\n */\r\nfunction getNameSummary(names: Array, maxNamesToShow: number) {\r\n let growingNames = '';\r\n for (let i = 0; i < maxNamesToShow && i < names.length; ++i) {\r\n const name = names[i];\r\n\r\n if (!growingNames) {\r\n growingNames = name;\r\n } else {\r\n growingNames += `, ${name ?? ''}`;\r\n }\r\n }\r\n\r\n let ret: string = growingNames;\r\n if (names.length > maxNamesToShow) {\r\n ret = i18next.t('createListOfNames.andSomeMore', '{{names}} and {{count}} others.', { names, count: names.length - maxNamesToShow });\r\n }\r\n \r\n return ret;\r\n}\r\n\r\nexport interface DashboardSummary {\r\n averageScore: QuestionScore,\r\n averageUserDriverMetricScore: QuestionScore,\r\n\r\n uniqueSessionsCount: number,\r\n totalFinishedSessionsCount: number,\r\n duplicateSessionsCount: number,\r\n\r\n assessmentsText: string,\r\n suspiciousAssessmentText: string,\r\n usersText: string,\r\n\r\n notStarted: number,\r\n started: number,\r\n complete: number,\r\n}\r\n\r\nexport interface DistributorDashboardSummary {\r\n totalSubscriptionsCount: number,\r\n distributorUserAssessmentAssignmentCount: number,\r\n distributorUserTrainingAssignmentCount: number,\r\n filteredAssessments: Array,\r\n assessmentAssignments: Array<{ AssessmentId: string, count: number }>,\r\n DistributorSubscriptionsText: string,\r\n\r\n}\r\n","import { AssessmentSession } from \"../../../api/main/models/AssessmentSession\";\r\nimport { overallRiskService, RiskRules } from \"../../../services/OverallRiskService\";\r\nimport { QuestionScore } from \"../../assessmentSessions/launch/utilities/calculateQuestionScore\";\r\n\r\n/**\r\n * Calculate the average score from a set of assessment sessions.\r\n */\r\nexport function calculateAverageScore(sessions: Array, riskRules?: RiskRules | undefined | null): QuestionScore {\r\n let minScore = -1;\r\n let maxScore = -1;\r\n let scoreSum = 0;\r\n let sessionCount = 0;\r\n for (const session of sessions) {\r\n scoreSum += session.totalScore;\r\n\r\n if (minScore === -1) {\r\n minScore = session.totalScore;\r\n } else if (session.totalScore < minScore) {\r\n minScore = session.totalScore;\r\n }\r\n\r\n if (maxScore === -1) {\r\n maxScore = session.totalScore;\r\n } else if (session.totalScore > maxScore) {\r\n maxScore = session.totalScore;\r\n }\r\n\r\n ++sessionCount;\r\n }\r\n\r\n let averageScore = 0;\r\n let notStarted = true;\r\n if (sessionCount > 0) {\r\n averageScore = Math.round(scoreSum / sessionCount);\r\n notStarted = false;\r\n }\r\n\r\n const riskCategory = overallRiskService.getRiskCategory(averageScore, notStarted, riskRules);\r\n\r\n return {\r\n score: averageScore,\r\n minScore: minScore === -1 ? 0 : minScore,\r\n maxScore: maxScore === -1 ? 0 : maxScore,\r\n riskCategory,\r\n };\r\n}","import * as React from 'react';\r\nimport { useLazyQuery } from \"@apollo/react-hooks\";\r\nimport gql from \"graphql-tag\";\r\nimport { AsyncLoadResult, AsyncLoadOptions } from '../../../../shared/abstractStore';\r\nimport { administrationDashboardViewModelQuery } from '../../generated/administrationDashboardViewModelQuery';\r\nimport { mainApiConfig } from '../../../../configure/mainApiConfig';\r\nimport { subscriptionFieldsFragment } from '../../models/Subscription';\r\nimport { subscriptionTeamFieldsFragment } from '../../models/SubscriptionTeam';\r\nimport { profileFieldsFragment } from '../../models/Profile';\r\nimport { subscriptionAssessmentFieldsFragment } from '../../models/SubscriptionAssessment';\r\nimport { assessmentFieldsFragment } from '../../models/Assessment';\r\nimport { assessmentSessionFieldsFragment } from '../../models/AssessmentSession';\r\nimport { userAssessmentAssignmentFieldsFragment } from '../../models/UserAssessmentAssignment';\r\nimport { userDriverMetricFieldsFragment } from '../../models/UserDriverMetric';\r\nimport { driverMetricFieldsFragment } from '../../models/DriverMetric';\r\n\r\n/**\r\n * View model for AdministrationDashboard to loads all the right related data.\r\n * @param options\r\n */\r\nexport function useAdministrationDashboardViewModel(options: AsyncLoadOptions = {}): AsyncLoadResult {\r\n // Query the data we need form the api.\r\n const [load, { data, loading, error, refetch }] = useLazyQuery(\r\n gql`\r\n query administrationDashboardViewModelQuery {\r\n subscriptions {\r\n ...subscriptionFields\r\n }\r\n\r\n subscriptionTeams {\r\n ...subscriptionTeamFields\r\n }\r\n\r\n profiles {\r\n ...profileFields\r\n }\r\n\r\n subscriptionAssessments {\r\n ...subscriptionAssessmentFields\r\n }\r\n\r\n assessments {\r\n ...assessmentFields\r\n }\r\n\r\n assessmentSessions {\r\n ...assessmentSessionFields\r\n }\r\n\r\n userAssessmentAssignments {\r\n ...userAssessmentAssignmentFields\r\n }\r\n\r\n userDriverMetrics {\r\n ...userDriverMetricFields\r\n }\r\n\r\n driverMetrics {\r\n ...driverMetricFields\r\n }\r\n }\r\n\r\n ${subscriptionFieldsFragment}\r\n ${subscriptionTeamFieldsFragment}\r\n ${profileFieldsFragment}\r\n ${subscriptionAssessmentFieldsFragment}\r\n ${assessmentFieldsFragment}\r\n ${assessmentSessionFieldsFragment}\r\n ${userAssessmentAssignmentFieldsFragment}\r\n ${userDriverMetricFieldsFragment}\r\n ${driverMetricFieldsFragment}\r\n `,\r\n {\r\n fetchPolicy: options.fetchPolicy ?? mainApiConfig.defaultFetchPolicy,\r\n pollInterval: options.pollInterval,\r\n onCompleted: (data) => {\r\n if (options.onCompleted) {\r\n options.onCompleted(data);\r\n }\r\n }\r\n }\r\n );\r\n\r\n // Run the query (unless we are being lazy).\r\n React.useEffect(() => {\r\n if (!options.lazy) {\r\n load();\r\n }\r\n }, [options.lazy, load])\r\n\r\n // Return the results.\r\n const refresh = React.useCallback(async () => { !refetch ? await load() : await refetch(); }, [refetch, load]);\r\n return React.useMemo(() => ({\r\n data: data ?? ({} as any),\r\n refresh: refresh,\r\n isLoading: loading,\r\n errors: error\r\n }), [data, refresh, loading, error]);\r\n}","import { useMemo } from \"react\";\r\nimport { Profile } from \"../../../api/main/models/Profile\";\r\nimport { UserAssessmentAssignment } from \"../../../api/main/models/UserAssessmentAssignment\";\r\n\r\n/**\r\n * Expand out the UserAssessmentAssignments so that each team assignment has a record for each affected user.\r\n */\r\nexport function useExpandedUserAssessmentAssignments(userAssessmentAssignments: Array, profiles: Array) {\r\n const ret = useMemo(() => {\r\n if (!userAssessmentAssignments || !profiles) {\r\n return [];\r\n }\r\n\r\n const ret: Array = [];\r\n\r\n // Add all the user specific assignments\r\n for (const assignment of userAssessmentAssignments) {\r\n // If this is for a user, add it to the return result directly.\r\n if (!assignment.userId) {\r\n continue;\r\n }\r\n\r\n ret.push(assignment);\r\n }\r\n\r\n // Expand the team assignments out for each member of the team (unless that member already has their own assignment).\r\n for (const assignment of userAssessmentAssignments) {\r\n // If this is for a user, add it to the return result directly.\r\n if (assignment.userId) {\r\n continue;\r\n }\r\n\r\n // This is for a team, so add an entry for each user in the team, taking care to skip users who already have their own\r\n // entry.\r\n const profilesInTeam = profiles.filter(item => item.subscriptionTeamId === assignment.subscriptionTeamId);\r\n for (const profile of profilesInTeam) {\r\n const usersOwnRecord = ret.find(it => it.assessmentId === assignment.assessmentId && it.userId === profile.userId);\r\n if (usersOwnRecord) {\r\n continue;\r\n }\r\n\r\n ret.push({\r\n ...assignment,\r\n userId: profile.userId,\r\n });\r\n }\r\n }\r\n\r\n return ret;\r\n }, [userAssessmentAssignments, profiles]);\r\n\r\n return ret;\r\n}","import { useCallback, useMemo } from \"react\";\r\nimport { useTranslation } from \"react-i18next\";\r\nimport { AssessmentType } from \"../../../api/main/models/codeOnly/AssessmentType\";\r\nimport { ChartData, ChartDataSeries } from \"../chartDataUtilities/ChartData\";\r\nimport { DashboardSummary } from \"../utilities/generateDashboardSummary\";\r\n\r\n/**\r\n * Data for a chart that shows average scores by groups.\r\n */\r\nexport function useAverageScoreChartData(groups: Array<{ id: string, name: string }>, getDashboardSummary: (id: string, assessmentType: AssessmentType) => DashboardSummary, assessmentType: AssessmentType): Array {\r\n const { t } = useTranslation();\r\n\r\n const generateSeries = useCallback((seriesName: string, assessmentType: AssessmentType) => {\r\n // Generate chart data for each group.\r\n const data = groups.map(group => {\r\n const summary = getDashboardSummary(group.id, assessmentType);\r\n\r\n return {\r\n text: group.name,\r\n value: summary.averageScore.score,\r\n } as ChartData;\r\n });\r\n\r\n return {\r\n name: seriesName,\r\n data: data,\r\n } as ChartDataSeries;\r\n }, [groups, getDashboardSummary]);\r\n\r\n const ret = useMemo(() => {\r\n return [\r\n generateSeries(\r\n assessmentType === AssessmentType.TrainingModule ? t('useAverageScoreChartData.trainingModules.seriesName', 'Training')\r\n : t('useAverageScoreChartData.assessments.seriesName', 'Assessments'),\r\n assessmentType\r\n ),\r\n // We now let the user toggle rather than see both at once as its more consistant with the other graphs being displayed.\r\n //generateSeries(\r\n // t('useAverageScoreChartData.trainingModules.seriesName', 'Training'),\r\n // AssessmentType.TrainingModule\r\n //),\r\n ];\r\n }, [generateSeries, t, assessmentType]);\r\n\r\n return ret;\r\n}\r\n","import { ApexOptions } from \"apexcharts\";\r\nimport moment, { unitOfTime } from \"moment\";\r\nimport { isUndefined } from \"util\";\r\nimport { ChartDataSeries } from \"./ChartData\"\r\n\r\nexport type ChartDataConverterResults = { series: any[], options: Partial };\r\nexport type ChartDataConverter = (data: Array) => ChartDataConverterResults;\r\n\r\nexport interface ChartDataConverterOptions {\r\n maxTextLength?: number,\r\n}\r\n\r\n/**\r\n * Class with export functions for various conversions of ChartDataSeries.\r\n */\r\nexport class ChartDataConverters {\r\n /**\r\n * Convert data to be used in a donut chart.\r\n * @param series\r\n */\r\n public toDonut(data: Array, options?: ChartDataConverterOptions): ChartDataConverterResults {\r\n const series = data.map(dataSeries => dataSeries.data.map(item => item.value)).flat(2);\r\n const labels = data.map(dataSeries => dataSeries.data.map(item => this.shortenText(item.text, options?.maxTextLength))).flat(2);\r\n\r\n return {\r\n series: series,\r\n options: {\r\n labels: labels,\r\n } as ApexOptions,\r\n };\r\n }\r\n\r\n /**\r\n * Convert data to be used in a pie chart.\r\n * @param series\r\n */\r\n public toPie(data: Array, options?: ChartDataConverterOptions): ChartDataConverterResults {\r\n return this.toDonut(data, options);\r\n }\r\n\r\n\r\n /**\r\n * Convert data to be used in a column chart.\r\n */\r\n public toColumn(data: Array, options?: ChartDataConverterOptions): ChartDataConverterResults {\r\n const series = data.map(dataSeries => ({\r\n ...dataSeries,\r\n data: dataSeries.data.map(item => ({\r\n x: this.shortenText(item.text, options?.maxTextLength),\r\n y: item.value,\r\n })),\r\n }));\r\n return {\r\n series: series,\r\n options: {\r\n xaxis: {\r\n type: 'category',\r\n }\r\n } as ApexOptions,\r\n };\r\n }\r\n\r\n /**\r\n * Convert data to be used in a bar chart.\r\n */\r\n public toBar(data: Array, options?: ChartDataConverterOptions): ChartDataConverterResults {\r\n const series = data.map(dataSeries => ({\r\n ...dataSeries,\r\n data: dataSeries.data.map(item => ({\r\n x: item.value,\r\n y: this.shortenText(item.text, options?.maxTextLength),\r\n })),\r\n }));\r\n return {\r\n series: series,\r\n options: {\r\n yaxis: {\r\n type: 'category',\r\n }\r\n } as ApexOptions,\r\n };\r\n }\r\n\r\n /**\r\n * Convert data to be used in a line chart.\r\n */\r\n public toLine(data: Array, options?: ChartDataConverterOptions): ChartDataConverterResults {\r\n const series = data.map(dataSeries => ({\r\n ...dataSeries,\r\n data: dataSeries.data.map(item => ({\r\n x: this.shortenText(item.text, options?.maxTextLength),\r\n y: item.value,\r\n })),\r\n }));\r\n return {\r\n series: series,\r\n options: {\r\n xaxis: {\r\n type: 'category',\r\n }\r\n } as ApexOptions,\r\n };\r\n }\r\n\r\n /**\r\n * Convert data to be used in a area chart.\r\n * @param series\r\n */\r\n public toArea(data: Array, options?: ChartDataConverterOptions): ChartDataConverterResults {\r\n return this.toLine(data);\r\n }\r\n\r\n /**\r\n * Convert data to be used in a line chart with the xaxis being dates.\r\n */\r\n public toDateLine(data: Array, unitOfTime: unitOfTime.StartOf = 'day', options?: ChartDataConverterOptions): ChartDataConverterResults {\r\n // Group by day/week/month etc, as plotting each event as value 1 doesn't work well in apexcharts so we have to do the grouping here.\r\n const groupByDate = (dataSeries: ChartDataSeries) => {\r\n let groupCounts: Array<{ id: string, total: number }> = [];\r\n for (const item of dataSeries.data) {\r\n const groupId = moment(item.text).local().startOf(unitOfTime).toISOString();\r\n let group = groupCounts.find(it => it.id === groupId);\r\n if (!group) {\r\n group = { id: groupId, total: item.value };\r\n groupCounts.push(group);\r\n } else {\r\n group.total += item.value;\r\n }\r\n\r\n }\r\n\r\n return {\r\n ...dataSeries,\r\n data: groupCounts.map(item => ({\r\n x: moment(item.id).toDate().getTime(),\r\n y: item.total,\r\n }))\r\n }\r\n }\r\n\r\n return {\r\n series: data.map(dataSeries => groupByDate(dataSeries)),\r\n options: {\r\n xaxis: {\r\n type: 'datetime',\r\n },\r\n markers: {\r\n size: 5,\r\n }\r\n } as ApexOptions,\r\n };\r\n }\r\n\r\n /**\r\n * Convert data to be used in a area chart with the xaxis being dates.\r\n * @param series\r\n */\r\n public toDateArea(data: Array, options?: ChartDataConverterOptions): ChartDataConverterResults {\r\n return this.toDateLine(data, undefined, options);\r\n }\r\n\r\n /**\r\n * Convert data to be used in a radar chart.\r\n * @param series\r\n */\r\n public toRadar(data: Array, options?: ChartDataConverterOptions): ChartDataConverterResults {\r\n // All series need to have all data points, so extract all text data points to get started.\r\n let uniqueTexts: Array = [];\r\n for (const dataSeries of data) {\r\n for (const item of dataSeries.data) {\r\n const existing = uniqueTexts.find(it => it === item.text);\r\n if (existing) {\r\n continue;\r\n }\r\n\r\n uniqueTexts.push(item.text);\r\n }\r\n }\r\n\r\n // Go through data in a series and return a result for each required uniqueText.\r\n const generateSeriesData = (dataSeries: ChartDataSeries) => {\r\n let ret: Array = [];\r\n for (const text of uniqueTexts) {\r\n const value = dataSeries.data.find(item => item.text === text);\r\n ret.push(value?.value ?? 0);\r\n }\r\n\r\n return ret;\r\n }\r\n\r\n const categories = data.map(dataSeries => dataSeries.data.map(item => this.shortenText(item.text, options?.maxTextLength))).flat(2);\r\n const series = data.map(dataSeries => ({\r\n ...dataSeries,\r\n data: generateSeriesData(dataSeries),\r\n }));\r\n \r\n return {\r\n series: series,\r\n options: {\r\n xaxis: {\r\n categories: categories,\r\n },\r\n } as ApexOptions,\r\n };\r\n }\r\n\r\n /**\r\n * Shorten text to maxLength.\r\n * \r\n * If maxLength is undefined, no change is made.\r\n * If text is already shorter than maxLength, no change is made.\r\n * If maxLength is less than 5\r\n * If text is longer than max length, we append ... at the end or in the middle as part of the shortening and try to preserve the start and the very end depending\r\n * on the length of the string and maxLength.\r\n * @param text\r\n * @param maxLength\r\n */\r\n private shortenText(text: string, maxLength: number | undefined): string {\r\n if (isUndefined(maxLength)) {\r\n return text;\r\n }\r\n\r\n if (text.length < maxLength) {\r\n return text;\r\n }\r\n\r\n const charsAtEnd = 5;\r\n const shortenedIndicator = '...';\r\n\r\n // If we are working with short strings, we need to just pop ... on the end.\r\n if (maxLength <= (charsAtEnd + shortenedIndicator.length)) {\r\n return `${text.substr(0, maxLength - shortenedIndicator.length)}${shortenedIndicator}`;\r\n }\r\n\r\n // Longer strings we keep a few characters at the end, as often they identify the difference between things.\r\n return `${text.substr(0, maxLength - (charsAtEnd + shortenedIndicator.length))}${shortenedIndicator}${text.substr((text.length - 1) - charsAtEnd)}`\r\n }\r\n}\r\n\r\n/**\r\n * Conversions.\r\n */\r\nexport const chartDataConverters = new ChartDataConverters();","// Red, Amber, Green chart colours (Red first).\r\nexport const ragChartColours = [\r\n '#f86c6b',\r\n '#ffc107',\r\n '#4dbd74',\r\n];\r\n\r\n// Green, Amber, Red chart colours (Green first).\r\nexport const garChartColours = [\r\n '#4dbd74',\r\n '#ffc107',\r\n '#f86c6b',\r\n];\r\n\r\n// Consistant colouring for assessments and training,\r\nexport const assessmentsChartColor = '#ec0b62'; // Esitu pink\r\nexport const trainingChartColor = \"#2f5597\"; // Esitu dark blue","import { ApexOptions }from \"apexcharts\";\r\nimport Chart from \"react-apexcharts\";\r\nimport { useMemo } from \"react\";\r\nimport { Card } from \"reactstrap\";\r\nimport { ChartDataSeries } from \"../chartDataUtilities/ChartData\";\r\nimport { chartDataConverters } from \"../chartDataUtilities/ChartDataConverter\";\r\nimport { useTranslation } from \"react-i18next\";\r\nimport { assessmentsChartColor, trainingChartColor } from \"./dashboardChartColors\";\r\nimport { AssessmentType } from \"../../../api/main/models/codeOnly/AssessmentType\";\r\nimport { overallRiskService, RiskRules } from \"../../../services/OverallRiskService\";\r\n\r\nexport interface AverageScoreRadarChartProps {\r\n data: Array,\r\n assessmentType: AssessmentType,\r\n riskRules: RiskRules | undefined | null,\r\n\r\n width?: string | number | undefined,\r\n height?: string | number | undefined,\r\n}\r\n\r\n/**\r\n * Chart that shows average scores as a radar.\r\n */\r\nexport const AverageScoreRadarChart = (props: AverageScoreRadarChartProps) => {\r\n const {\r\n data,\r\n assessmentType,\r\n riskRules,\r\n width,\r\n height,\r\n } = props;\r\n\r\n const { t } = useTranslation();\r\n\r\n // Convert data into format needed for this graph.\r\n const { series, options: seriesOptions } = useMemo(() => chartDataConverters.toRadar(data, { maxTextLength: 20 }), [data]);\r\n\r\n // Compile all the options we want to use.\r\n const options = useMemo(() => (\r\n {\r\n chart: {\r\n toolbar: {\r\n show: false,\r\n },\r\n },\r\n\r\n title: {\r\n text: assessmentType === AssessmentType.TrainingModule ? t('averageScoreRadarChart.title.trainingModule', 'Training scores')\r\n : t('averageScoreRadarChart.title.default', 'Assessment scores'),\r\n align: 'center',\r\n },\r\n\r\n colors:\r\n assessmentType === AssessmentType.TrainingModule ? [trainingChartColor]\r\n : [assessmentsChartColor],\r\n\r\n yaxis: {\r\n min: 0,\r\n max: 100,\r\n tickAmount: 10,\r\n },\r\n\r\n plotOptions: {\r\n radar: {\r\n polygons: {\r\n fill: {\r\n colors: assessmentType === AssessmentType.TrainingModule ? [] : overallRiskService.getSpidergraphBackgroundColors(10, riskRules),\r\n }\r\n }\r\n\r\n }\r\n },\r\n\r\n tooltip: {\r\n y: {\r\n formatter: function (val: any) {\r\n if (assessmentType === AssessmentType.TrainingModule) {\r\n return val;\r\n }\r\n\r\n return `${val} (${overallRiskService.getRiskName(val, riskRules)})`;\r\n }\r\n },\r\n },\r\n\r\n ...seriesOptions,\r\n } as ApexOptions\r\n ), [seriesOptions, t, assessmentType, riskRules]);\r\n\r\n // We need to force the refresh of the chart sometimes by updating its key as its too optomistic with its internal caching and\r\n // so doesn't end up changes top options very well at all if we dont.\r\n const key = useMemo(() => JSON.stringify(options), [options]);\r\n\r\n return (\r\n \r\n \r\n \r\n );\r\n};","import { Col, Row } from \"reactstrap\";\r\nimport { AssessmentType } from \"../../../api/main/models/codeOnly/AssessmentType\";\r\nimport { ScoreProgressBar } from \"../../assessmentSessions/launch/progress/ScoreProgressBar\";\r\nimport { QuestionScore } from \"../../assessmentSessions/launch/utilities/calculateQuestionScore\";\r\n\r\nexport interface IndividualScoreProgressBarProps {\r\n value: QuestionScore,\r\n title?: string,\r\n footer?: string,\r\n assessmentType: AssessmentType,\r\n}\r\n\r\n/**\r\n * Show an individual score as a progress bar, with supporting data around it.\r\n */\r\nexport const IndividualScoreProgressBar = (props: IndividualScoreProgressBarProps) => {\r\n const {\r\n value,\r\n title,\r\n footer,\r\n assessmentType,\r\n } = props;\r\n\r\n return (\r\n
\r\n
\r\n \r\n {title}\r\n \r\n
\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n
\r\n \r\n {footer}\r\n \r\n
\r\n
\r\n );\r\n};","import { useCallback, useMemo } from \"react\";\r\nimport { AssessmentType } from \"../../../api/main/models/codeOnly/AssessmentType\";\r\nimport { DashboardSummary } from \"./generateDashboardSummary\";\r\n\r\nexport type GetCachedDashboardSummary = (id: string, asessmentType: AssessmentType) => DashboardSummary;\r\n\r\n/**\r\n * Hook that returns caches the dashboard summaries for easy lookup by group.\r\n */\r\nexport function useCachedDashboardSummaries(\r\n groups: Array<{ id: string }>,\r\n calculateDashboardSummary: (\r\n group: { id: string },\r\n assessmentType: AssessmentType\r\n ) => DashboardSummary\r\n): GetCachedDashboardSummary\r\n{\r\n // Generate the summary data for each subscription.\r\n const cachedDashboardSummaries = useMemo(() =>\r\n groups.map(group => {\r\n return ({\r\n id: group.id,\r\n assessmentSummaryData: calculateDashboardSummary(group, AssessmentType.Assessment),\r\n trainingSummaryData: calculateDashboardSummary(group, AssessmentType.TrainingModule),\r\n });\r\n })\r\n , [calculateDashboardSummary, groups]);\r\n\r\n // Returns the dashboard summary by id from our cached values.\r\n const getCachedDashboardSummary = useCallback((id: string, assessmentType: AssessmentType) => {\r\n const cachedData = cachedDashboardSummaries.find(it => it.id === id);\r\n if (assessmentType === AssessmentType.TrainingModule) {\r\n return cachedData?.trainingSummaryData as DashboardSummary;\r\n }\r\n\r\n return cachedData?.assessmentSummaryData as DashboardSummary;\r\n }, [cachedDashboardSummaries]);\r\n\r\n return getCachedDashboardSummary;\r\n}","import { useLocation } from \"react-router\";\r\n\r\n/**\r\n * Hook that returns the right base route to use when navigating around the dashboard by working out if we're under the administrator dashboard\r\n * or not.\r\n */\r\nexport function useDashboardBaseRoute() {\r\n const location = useLocation();\r\n\r\n // Things under the admin dashboard subscription navigation will all be under locations starting with the same path including the subscriptionId\r\n // as that is needed to be able to load the data exactly as the subscription would see it.\r\n const administrationSubscriptionPrefix = '/administration/dashboard/subscription/';\r\n if (location.pathname.startsWith(administrationSubscriptionPrefix)) {\r\n const nextSlash = location.pathname.indexOf('/', administrationSubscriptionPrefix.length);\r\n if (nextSlash === -1) {\r\n return location.pathname;\r\n }\r\n\r\n return location.pathname.substring(0, nextSlash);\r\n }\r\n\r\n // Things under the admin dashboard will all be under locations starting with the same path.\r\n if (location.pathname.startsWith('/administration/dashboard')) {\r\n return '/administration/dashboard';\r\n }\r\n\r\n // Otherwise use the primary dashboard.\r\n return '/dashboard';\r\n}","import moment from \"moment\";\r\nimport { useCallback, useMemo } from \"react\";\r\nimport { ConditionalFragment } from \"react-conditionalfragment\";\r\nimport { useTranslation } from \"react-i18next\";\r\nimport { LinkContainer } from \"react-router-bootstrap\";\r\nimport { Link } from \"react-router-dom\";\r\nimport { Badge, Button, ButtonGroup, Col, Collapse, ListGroup, ListGroupItem, ListGroupItemHeading, ListGroupItemText, Row } from \"reactstrap\";\r\nimport { useToggleStateArray } from \"use-toggle-state\";\r\nimport { useCurrentUserId } from \"../../../api/account\";\r\nimport { Assessment } from \"../../../api/main/models/Assessment\";\r\nimport { AssessmentSession } from \"../../../api/main/models/AssessmentSession\";\r\nimport { AssessmentType } from \"../../../api/main/models/codeOnly/AssessmentType\";\r\nimport { Profile } from \"../../../api/main/models/Profile\";\r\nimport { Subscription } from \"../../../api/main/models/Subscription\";\r\nimport { SubscriptionTeam } from \"../../../api/main/models/SubscriptionTeam\";\r\nimport { UserAssessmentAssignment } from \"../../../api/main/models/UserAssessmentAssignment\";\r\nimport { RiskRules } from \"../../../services/OverallRiskService\";\r\nimport { questionScoreFromNumber } from \"../../assessmentSessions/launch/utilities/questionScoreFromNumber\";\r\nimport { DueDateLabel } from \"../../me/DueDateLabel\";\r\nimport { useAverageScoreChartData } from \"../chartData/useAverageScoreChartData\";\r\nimport { AverageScoreRadarChart } from \"../charts/AverageScoreRadarChart\";\r\nimport { IndividualScoreProgressBar } from \"../progress/IndividualScoreProgressBar\";\r\nimport { DashboardSummary } from \"../utilities/generateDashboardSummary\";\r\nimport { getLatestSessions } from \"../utilities/getLatestSessions\";\r\nimport { useCachedDashboardSummaries } from \"../utilities/useCachedDashboardSummaries\";\r\nimport { useDashboardBaseRoute } from \"../utilities/useDashboardBaseRoute\";\r\nimport \"./assessmentProgressDashboardTab.scss\";\r\n\r\nexport interface AssessmentProgressDashboardTabProps {\r\n assessment: Assessment | undefined | null,\r\n profiles: Array,\r\n subscriptions?: Array,\r\n subscriptionTeams: Array,\r\n\r\n assessmentType: AssessmentType,\r\n generateDashboardSummary: (\r\n sessionFilter: (session: AssessmentSession) => boolean,\r\n assignmentFilter: (assignment: UserAssessmentAssignment) => boolean,\r\n assessmentType: AssessmentType\r\n ) => DashboardSummary,\r\n\r\n assessmentSessions: Array,\r\n expandedUserAssessmentAssignments: Array,\r\n\r\n showSubscriptionName?: boolean,\r\n\r\n riskRules: RiskRules | undefined | null,\r\n}\r\n\r\n/**\r\n * Tab for the dasboard that shows under a user to show their assigned assessments/training by status.\r\n * @param props\r\n */\r\nexport const AssessmentProgressDashboardTab = (props: AssessmentProgressDashboardTabProps) => {\r\n const {\r\n assessment,\r\n profiles,\r\n subscriptions,\r\n subscriptionTeams,\r\n\r\n assessmentType,\r\n\r\n generateDashboardSummary,\r\n\r\n assessmentSessions,\r\n expandedUserAssessmentAssignments,\r\n\r\n showSubscriptionName = false,\r\n\r\n riskRules,\r\n } = props;\r\n\r\n const { t } = useTranslation();\r\n\r\n const currentUserId = useCurrentUserId();\r\n\r\n // Method we use to filter sessions by user wherever we need it.\r\n const filterByUser = useCallback((user: { id: string }, item: { userId: string | undefined | null }) => {\r\n return item.userId === user.id;\r\n }, []);\r\n\r\n // Profiles simplified to have a name and id (for which we use the userId).\r\n const users = useMemo(() => profiles.map(profile => ({\r\n id: profile.userId,\r\n name: t('common.fullName', '{{firstName}} {{lastName}}', profile),\r\n subscriptionId: profile.subscriptionId,\r\n subscriptionTeamId: profile.subscriptionTeamId,\r\n })), [profiles, t]);\r\n\r\n // Cache the dashboard summaries so each chart/display doesn't need to recaclulate them and they can be looked up easily by id.\r\n const getCachedDashboardSummary = useCachedDashboardSummaries(\r\n users,\r\n (group, assessmentType) => generateDashboardSummary(\r\n session => filterByUser(group, session),\r\n assignment => filterByUser(group, assignment),\r\n assessmentType\r\n )\r\n );\r\n\r\n // Get the latest session for each assessment.\r\n const { latestSessions, latestSessionsIncludingIncomplete } = useMemo(() => getLatestSessions(assessmentSessions ?? []), [assessmentSessions]);\r\n\r\n // Split the assessments up into groups based on the user's progress.\r\n const { notStarted, started, complete } = useMemo(() => {\r\n let notStarted: Array = [];\r\n let started: Array = [];\r\n let complete: Array = [];\r\n\r\n\r\n for (const profile of profiles) {\r\n const assignment = expandedUserAssessmentAssignments.find(it => it.userId === profile.userId);\r\n const session = latestSessionsIncludingIncomplete.find(it => it.userId === profile.userId);\r\n\r\n // If we have no session, then check if its assigned or not.\r\n if (!session) {\r\n if (!assignment) {\r\n // User has nothing to do with this assessment, just skip it.\r\n continue;\r\n }\r\n\r\n // Add to the notStarted.\r\n notStarted.push(profile);\r\n } else {\r\n // If its complete add it to the complete list.\r\n if (session.isFinished) {\r\n complete.push(profile);\r\n } else {\r\n // Otherwise add it to the started list.\r\n started.push(profile);\r\n }\r\n }\r\n };\r\n\r\n return {\r\n notStarted,\r\n started,\r\n complete,\r\n };\r\n }, [profiles, latestSessionsIncludingIncomplete, expandedUserAssessmentAssignments]);\r\n\r\n // Get data for the various charts.\r\n const averageScoreChartData = useAverageScoreChartData(users, getCachedDashboardSummary, assessmentType);\r\n\r\n const baseRoute = useDashboardBaseRoute();\r\n\r\n // Track which histories are expanded.\r\n const [isHistoryExpandedFor, toggleHistoryExpandedFor] = useToggleStateArray([]);\r\n\r\n // Generate the display items for the passed in assignments.\r\n const generateItems = (myProfiles: Array) => {\r\n return myProfiles.map(profile => {\r\n const latestCompleteSession = latestSessions.find(it => it.userId === profile.userId);\r\n const latestSessionIncludingIncomplete = latestSessionsIncludingIncomplete.find(it => it.userId === profile.userId);\r\n let assignment = expandedUserAssessmentAssignments.find(it => it.userId === profile.userId && !it.subscriptionTeamId);\r\n if (!assignment) {\r\n assignment = expandedUserAssessmentAssignments.find(it => it.subscriptionTeamId === profile.subscriptionTeamId && !!it.subscriptionTeamId);\r\n }\r\n\r\n // The user format alreay has the name how we want it, so look it up.\r\n const user = users.find(it => it.id === profile.userId);\r\n\r\n // Also find the team and if available subscription for the profile.\r\n const team = subscriptionTeams.find(it => it.id === profile.subscriptionTeamId);\r\n const subscription = subscriptions?.find(it => it.id === profile.subscriptionId);\r\n\r\n const isCurrentUser = user?.id === currentUserId;\r\n const launchBaseRoute = assessment?.assessmentType === AssessmentType.TrainingModule ? '/training' : '/assessment';\r\n\r\n // Get any historic completions.\r\n let allMyHistoricCompleteSessions = assessmentSessions\r\n .filter(it => it.userId === profile.userId && it.isFinished)\r\n .filter(it => it.id !== latestSessionIncludingIncomplete?.id);\r\n // Flip the order.\r\n allMyHistoricCompleteSessions.sort((a, b) => {\r\n if (a.startDate === b.startDate) {\r\n return 0;\r\n } else if (a.startDate < b.startDate) {\r\n return 1;\r\n } else {\r\n return -1;\r\n }\r\n });\r\n\r\n return (\r\n \r\n \r\n \r\n \r\n \r\n {user?.name}\r\n \r\n \r\n \r\n \r\n \r\n {team?.name}\r\n \r\n \r\n \r\n <> \r\n {'(' /* Can/should this be made translatable? */}\r\n \r\n {subscription?.companyName}\r\n \r\n {')'}\r\n \r\n \r\n\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n\r\n \r\n
\r\n
\r\n {\r\n latestCompleteSession && latestCompleteSession?.id !== latestSessionIncludingIncomplete?.id ? (\r\n \r\n ) : latestCompleteSession ? (\r\n \r\n ): null\r\n }\r\n
\r\n
\r\n \r\n {\r\n assessmentSessions.filter(item => item.userId === user?.id && !item.isFinished && item.assessmentId === assessment?.id && item.id !== latestSessionIncludingIncomplete?.id).length !== 0 ? (\r\n <>\r\n {t('assessmentProgressDashboardTab.restartCount', `This user had ${assessmentSessions.filter(item => item.userId === user?.id && !item.isFinished && item.assessmentId === assessment?.id && item.id !== latestSessionIncludingIncomplete?.id).length} unfinished attempts before their latest attempt.`)}\r\n \r\n ) : null\r\n }\r\n \r\n
\r\n
\r\n \r\n
\r\n
\r\n \r\n
\r\n\r\n \r\n \r\n\r\n \r\n \r\n {\r\n allMyHistoricCompleteSessions.map(session => (\r\n \r\n \r\n \r\n
\r\n \r\n
\r\n\r\n \r\n \r\n \r\n \r\n \r\n \r\n\r\n \r\n
\r\n
\r\n \r\n
\r\n
\r\n \r\n
\r\n
\r\n ))\r\n }\r\n
\r\n
\r\n
\r\n
\r\n );\r\n })\r\n };\r\n\r\n return (\r\n
\r\n \r\n \r\n {/* Not started */}\r\n
\r\n \r\n \r\n
\r\n {t('assessmentProgressDashboardTab.notStarted.heading', 'Not started')}\r\n <> \r\n \r\n {notStarted.length}\r\n \r\n
\r\n
\r\n {\r\n generateItems(notStarted)\r\n }\r\n
\r\n
\r\n\r\n {/* Started */}\r\n
\r\n \r\n \r\n
\r\n {t('assessmentProgressDashboardTab.started.heading', 'Started')}\r\n <> \r\n \r\n {started.length}\r\n \r\n
\r\n
\r\n {\r\n generateItems(started)\r\n }\r\n
\r\n
\r\n\r\n {/* Complete */}\r\n
\r\n \r\n \r\n
\r\n {t('assessmentProgressDashboardTab.complete.heading', 'Completed')}\r\n <> \r\n \r\n {complete.length}\r\n \r\n
\r\n
\r\n {\r\n generateItems(complete)\r\n }\r\n
\r\n
\r\n \r\n \r\n \r\n \r\n
\r\n
\r\n );\r\n};","import { FontAwesomeIcon } from \"@fortawesome/react-fontawesome\";\r\nimport { useTranslation } from \"react-i18next\";\r\nimport { useHistory } from \"react-router\";\r\nimport { Button } from \"reactstrap\";\r\nimport { useDashboardRequiresBackButton } from \"../utilities/useDashboardRequiresBackButton\";\r\nimport \"./dashboardBackButton.scss\";\r\n\r\n/**\r\n * Back button that goes back in the history, and is formatted for display on the dashboard.\r\n * \r\n * The button will automatically hide itself if it is not required.\r\n */\r\nexport const DashboardBackButton = () => {\r\n const { t } = useTranslation();\r\n const history = useHistory();\r\n\r\n const needBackButton = useDashboardRequiresBackButton();\r\n\r\n // If we don't need a back button, don't show one.\r\n if (!needBackButton) {\r\n return null;\r\n }\r\n\r\n return (\r\n \r\n );\r\n};","import { useLocation } from \"react-router\";\r\n\r\n/**\r\n * Hook that returns if we should show a back button on a dashboard, based off the route.\r\n */\r\nexport function useDashboardRequiresBackButton() {\r\n const location = useLocation();\r\n\r\n // Don't show on the main /dashboard page\r\n if (location.pathname === '/dashboard') {\r\n return false;\r\n }\r\n\r\n // Don't show on the main administration dashboard page.\r\n if (location.pathname === '/administration/dashboard') {\r\n return false;\r\n }\r\n\r\n // Otherwise show the back button.\r\n return true;\r\n}","import { useCallback, useMemo } from \"react\";\r\nimport { ConditionalFragment } from \"react-conditionalfragment\";\r\nimport { useTranslation } from \"react-i18next\";\r\nimport { Col, Container, Row } from \"reactstrap\";\r\nimport { AssessmentType } from \"../../../api/main/models/codeOnly/AssessmentType\";\r\nimport { AlertOnErrors } from \"../../../shared/alertOnErrors\";\r\nimport { Background } from \"../../shared/background/Background\";\r\nimport { Banner } from \"../../shared/Banner\";\r\nimport { LoadingIndicator } from \"../../shared/LoadingIndicator\";\r\nimport { UserAssessmentAssignment } from \"../../../api/main/models/UserAssessmentAssignment\";\r\nimport { AssessmentSession } from \"../../../api/main/models/AssessmentSession\";\r\nimport { generateDashboardSummary as _generateDashboardSummary } from \"../utilities/generateDashboardSummary\";\r\nimport { useParams } from \"react-router\";\r\nimport { useAdministrationDashboardViewModel } from \"../../../api/main/dashboard/viewModels/useAdministrationDashboardViewModel\";\r\nimport { useExpandedUserAssessmentAssignments } from \"../utilities/useExpandedUserAssessmentAssignments\";\r\nimport { AssessmentProgressDashboardTab } from \"../tabs/AssessmentProgressDashboardTab\";\r\nimport { DashboardBackButton } from \"../backButton/DashboardBackButton\";\r\n\r\n/**\r\n * Dashboard for assessment via the administration dashboard data.\r\n */\r\nexport const AdministrationAssessmentDashboard = () => {\r\n // Work out the subscription and user to show for.\r\n const { assessmentId } = useParams<{ assessmentId: string }>();\r\n\r\n\r\n const { t } = useTranslation();\r\n\r\n const {\r\n data: {\r\n subscriptions,\r\n subscriptionTeams,\r\n profiles: allProfiles,\r\n assessments: allAssessments,\r\n assessmentSessions: allAssmentSessions,\r\n userAssessmentAssignments: allUserAssessmentAssignments,\r\n userDriverMetrics: allUserDriverMetrics,\r\n },\r\n isLoading,\r\n errors: loadErrors\r\n } = useAdministrationDashboardViewModel();\r\n\r\n const assessment = useMemo(() => allAssessments?.find(it => it.id === assessmentId), [allAssessments, assessmentId]);\r\n\r\n // Filter the profiles down to only this user.\r\n const assessmentSessions = useMemo(() => allAssmentSessions?.filter(item => item.assessmentId === assessmentId), [allAssmentSessions, assessmentId]);\r\n const userAssessmentAssignments = useMemo(() =>\r\n allUserAssessmentAssignments\r\n ?.filter(item => item.assessmentId === assessmentId)\r\n , [allUserAssessmentAssignments, assessmentId]);\r\n\r\n // Eemove any profiles that have not either been used or assigned to this assessment.\r\n const profiles = useMemo(() =>\r\n allProfiles\r\n ?.filter(profile =>\r\n !!assessmentSessions?.find(it => it.userId === profile.userId)\r\n || !!userAssessmentAssignments?.find(it => it.userId === profile.userId)\r\n || !!userAssessmentAssignments?.find(it => !!it.subscriptionTeamId && it.subscriptionTeamId === profile.subscriptionTeamId)\r\n )\r\n , [allProfiles, userAssessmentAssignments, assessmentSessions]);\r\n\r\n // Expand the UserAssessmentAssignments so we can work with them easier.\r\n const expandedUserAssessmentAssignments = useExpandedUserAssessmentAssignments(userAssessmentAssignments, profiles);\r\n\r\n // Allow the generation of dashboard summary data.\r\n const generateDashboardSummary = useCallback((\r\n sessionFilter: (session: AssessmentSession) => boolean,\r\n assignmentFilter: (assignment: UserAssessmentAssignment) => boolean,\r\n assessmentType: AssessmentType) => {\r\n // Filter by the passed in fitler.\r\n let mySessions = assessmentSessions?.filter(sessionFilter) ?? [];\r\n let myAssignments = expandedUserAssessmentAssignments?.filter(assignmentFilter) ?? [];\r\n\r\n // Filter the driver metrics to contain only users that have assessments or assignments.\r\n const myUserDriverMetrics = allUserDriverMetrics?.filter(\r\n udm => !!mySessions.find(it => it.userId === udm.userId) || !!myAssignments.find(it => it.userId === udm.userId)\r\n ) ?? [];\r\n\r\n // Generate the summary data.\r\n const ret = _generateDashboardSummary(mySessions, assessment ? [assessment] : [], profiles ?? [], myAssignments, myUserDriverMetrics ?? [], null);\r\n return ret;\r\n }, [assessmentSessions, assessment, profiles, expandedUserAssessmentAssignments, allUserDriverMetrics]);\r\n\r\n\r\n // Track the active assessment type.\r\n const activeAssessmentType = assessment?.assessmentType as AssessmentType ?? AssessmentType.Assessment;\r\n\r\n return (\r\n \r\n \r\n \r\n \r\n

\r\n \r\n {\r\n t('administrationAssessmentDashboard.heading', '{{name}} dashboard', { name: assessment?.name })\r\n }\r\n

\r\n \r\n \r\n \r\n \r\n \r\n \r\n
\r\n
\r\n \r\n \r\n\r\n \r\n \r\n
\r\n );\r\n};\r\n","import * as React from 'react';\r\nimport { atom, useRecoilState } from 'recoil';\r\nimport { persistAtom } from '../../configure/recoilPersistConfig';\r\nimport { OverallRiskCategory } from '../../services/OverallRiskService';\r\n\r\nexport const activeDashboardRiskCategoryFilterState = atom({\r\n key: 'activeDashboardRiskCategoryFilterState',\r\n default: undefined,\r\n effects_UNSTABLE: [persistAtom],\r\n \r\n});\r\n\r\n/**\r\n * Hook that returns the active OverallRiskCategory to use for Dashboards.\r\n */\r\nexport function useActiveDashboardRiskCategoryFilter(): [OverallRiskCategory | undefined, React.Dispatch>] {\r\n const [value, setValue] = useRecoilState(activeDashboardRiskCategoryFilterState);\r\n return [value, setValue];\r\n}","import { useCallback, useMemo } from \"react\";\r\nimport { useTranslation } from \"react-i18next\";\r\nimport { AssessmentType } from \"../../../api/main/models/codeOnly/AssessmentType\";\r\nimport { OverallRiskCategory, overallRiskService } from \"../../../services/OverallRiskService\";\r\nimport { ChartData, ChartDataSeries } from \"../chartDataUtilities/ChartData\";\r\nimport { DashboardSummary } from \"../utilities/generateDashboardSummary\";\r\n\r\n/**\r\n * Data for a chart that shows risk category counts.\r\n */\r\nexport function useAverageDriverMetricRiskChartData(groups: Array<{ id: string, name: string }>, getUserMetricSummary: (id: string, assessmentType: AssessmentType) => DashboardSummary, assessmentType: AssessmentType): Array {\r\n const { t } = useTranslation();\r\n\r\n const generateSeries = useCallback((seriesName: string, assessmentType: AssessmentType) => {\r\n // Generate chart data for each group.\r\n\r\n const summaries = groups.map(group => getUserMetricSummary(group.id, assessmentType));\r\n\r\n const data = [\r\n {\r\n text: overallRiskService.getRiskName(OverallRiskCategory.High),\r\n value: summaries.filter(item => item.averageUserDriverMetricScore.riskCategory === OverallRiskCategory.High).length,\r\n } as ChartData,\r\n {\r\n text: overallRiskService.getRiskName(OverallRiskCategory.Medium),\r\n value: summaries.filter(item => item.averageUserDriverMetricScore.riskCategory === OverallRiskCategory.Medium).length,\r\n } as ChartData,\r\n {\r\n text: overallRiskService.getRiskName(OverallRiskCategory.Low),\r\n value: summaries.filter(item => item.averageUserDriverMetricScore.riskCategory === OverallRiskCategory.Low).length,\r\n } as ChartData,\r\n {\r\n text: overallRiskService.getRiskName(OverallRiskCategory.NotAssessed),\r\n value: summaries.filter(item => item.averageUserDriverMetricScore.riskCategory === OverallRiskCategory.NotAssessed).length,\r\n } as ChartData,\r\n ];\r\n\r\n return {\r\n name: seriesName,\r\n data: data,\r\n } as ChartDataSeries;\r\n }, [groups, getUserMetricSummary]);\r\n\r\n const ret = useMemo(() => {\r\n return [\r\n generateSeries(\r\n assessmentType === AssessmentType.TrainingModule ? t('useAverageScoreChartData.trainingModules.seriesName', 'Training')\r\n : t('useAverageScoreChartData.assessments.seriesName', 'Assessments'),\r\n assessmentType\r\n ),\r\n ];\r\n }, [generateSeries, t, assessmentType]);\r\n\r\n return ret;\r\n}\r\n","import { useCallback, useMemo } from \"react\";\r\nimport { useTranslation } from \"react-i18next\";\r\nimport { AssessmentType } from \"../../../api/main/models/codeOnly/AssessmentType\";\r\nimport { ChartData, ChartDataSeries } from \"../chartDataUtilities/ChartData\";\r\nimport { DashboardSummary } from \"../utilities/generateDashboardSummary\";\r\n\r\n/**\r\n * Data for a chart that shows completion data broken down by groups.\r\n */\r\nexport function useCompletionChartData(groups: Array<{ id: string, name: string }>, getDashboardSummary: (id: string, assessmentType: AssessmentType) => DashboardSummary, assessmentType: AssessmentType): Array {\r\n const { t } = useTranslation();\r\n\r\n\r\n const generateSeries = useCallback((seriesName: string, getValue: (summary: DashboardSummary) => number) => {\r\n // Generate chart data for each group.\r\n const data = groups.map(group => {\r\n const summary = getDashboardSummary(group.id ?? null, assessmentType);\r\n\r\n return {\r\n text: group.name,\r\n value: getValue(summary),\r\n } as ChartData;\r\n });\r\n\r\n return {\r\n name: seriesName,\r\n data: data,\r\n } as ChartDataSeries;\r\n }, [groups, getDashboardSummary, assessmentType]);\r\n\r\n const ret = useMemo(() => {\r\n return [\r\n generateSeries(\r\n t('useCompletioneChartData.complete.seriesName', 'Completed'),\r\n summary => summary.complete,\r\n ),\r\n generateSeries(\r\n t('useCompletioneChartData.started.seriesName', 'Started'),\r\n summary => summary.started,\r\n ),\r\n generateSeries(\r\n t('useCompletioneChartData.notStarted.seriesName', 'Not started'),\r\n summary => summary.notStarted,\r\n ),\r\n ];\r\n }, [generateSeries, t]);\r\n\r\n return ret;\r\n}\r\n","import { ApexOptions }from \"apexcharts\";\r\nimport Chart from \"react-apexcharts\";\r\nimport { useMemo } from \"react\";\r\nimport { Card } from \"reactstrap\";\r\nimport { ChartDataSeries } from \"../chartDataUtilities/ChartData\";\r\nimport { chartDataConverters } from \"../chartDataUtilities/ChartDataConverter\";\r\nimport { useTranslation } from \"react-i18next\";\r\nimport { AssessmentType } from \"../../../api/main/models/codeOnly/AssessmentType\";\r\n\r\nexport interface AverageScoreRiskDonutChartProps {\r\n data: Array,\r\n assessmentType: AssessmentType,\r\n\r\n width?: string | number | undefined,\r\n height?: string | number | undefined,\r\n}\r\n\r\n/**\r\n * Chart that shows average driver metric risks as a donut chart.\r\n */\r\nexport const AverageDriverMetricRiskDonutChart = (props: AverageScoreRiskDonutChartProps) => {\r\n const {\r\n data,\r\n width,\r\n height = 500,\r\n } = props;\r\n\r\n const { t } = useTranslation();\r\n\r\n // Convert data into format needed for this graph.\r\n const { series, options: seriesOptions } = useMemo(() => chartDataConverters.toDonut(data), [data]);\r\n\r\n // Compile all the options we want to use.\r\n const options = useMemo(() => (\r\n {\r\n chart: {\r\n toolbar: {\r\n show: false,\r\n },\r\n },\r\n\r\n title: {\r\n text: t('averageScoreRiskDonutChart.title', 'Risk summary'),\r\n align: 'center',\r\n },\r\n\r\n dataLabels: {\r\n enabled: true,\r\n formatter: (val, options) => {\r\n // Show value instead of percentage.\r\n return `${options.w.config.series[options.seriesIndex]}`;\r\n },\r\n },\r\n\r\n legend: {\r\n position: 'bottom',\r\n },\r\n\r\n plotOptions: {\r\n pie: {\r\n donut: {\r\n labels: {\r\n show: true,\r\n total: {\r\n show: true,\r\n }\r\n }\r\n }\r\n }\r\n },\r\n\r\n colors: [\r\n '#f86c6b',\r\n '#ffc107',\r\n '#4dbd74',\r\n '#aeaeae'\r\n ],\r\n\r\n ...seriesOptions,\r\n } as ApexOptions\r\n ), [seriesOptions, t]);\r\n\r\n // We need to force the refresh of the chart sometimes by updating its key as its too optomistic with its internal caching and\r\n // so doesn't end up changes top options very well at all if we dont.\r\n const key = useMemo(() => JSON.stringify(options), [options]);\r\n\r\n return (\r\n \r\n \r\n \r\n );\r\n};","import { ApexOptions }from \"apexcharts\";\r\nimport Chart from \"react-apexcharts\";\r\nimport { useMemo } from \"react\";\r\nimport { Card } from \"reactstrap\";\r\nimport { ChartDataSeries } from \"../chartDataUtilities/ChartData\";\r\nimport { chartDataConverters } from \"../chartDataUtilities/ChartDataConverter\";\r\nimport { useTranslation } from \"react-i18next\";\r\nimport { AssessmentType } from \"../../../api/main/models/codeOnly/AssessmentType\";\r\nimport { garChartColours } from \"./dashboardChartColors\";\r\n\r\nexport interface CompletionBarChartProps {\r\n data: Array,\r\n assessmentType: AssessmentType,\r\n\r\n width?: string | number | undefined,\r\n height?: string | number | undefined,\r\n}\r\n\r\n/**\r\n * Chart that shows completion status totals (not started/started/completed) as a bar chart.\r\n */\r\nexport const CompletionBarChart = (props: CompletionBarChartProps) => {\r\n const {\r\n data,\r\n assessmentType,\r\n width,\r\n height,\r\n } = props;\r\n\r\n const { t } = useTranslation();\r\n\r\n // Convert data into format needed for this graph.\r\n const { series, options: seriesOptions } = useMemo(() => chartDataConverters.toColumn(data, { maxTextLength: 20 }), [data]);\r\n\r\n // Compile all the options we want to use.\r\n const options = useMemo(() => (\r\n {\r\n chart: {\r\n toolbar: {\r\n show: false,\r\n },\r\n\r\n stacked: true,\r\n },\r\n\r\n title: {\r\n text:\r\n assessmentType === AssessmentType.TrainingModule ? t('completionBarChart.title.training', 'Training progress')\r\n : t('completionBarChart.title.assessments', 'Assessment progress'),\r\n align: 'center',\r\n },\r\n\r\n //plotOptions: {\r\n // bar: {\r\n // borderRadius: 10,\r\n // },\r\n //},\r\n\r\n colors: garChartColours,\r\n\r\n ...seriesOptions,\r\n } as ApexOptions\r\n ), [seriesOptions, t, assessmentType]);\r\n\r\n // We need to force the refresh of the chart sometimes by updating its key as its too optomistic with its internal caching and\r\n // so doesn't end up changes top options very well at all if we dont.\r\n const key = useMemo(() => JSON.stringify(options), [options]);\r\n\r\n return (\r\n \r\n \r\n \r\n );\r\n};","import { useTranslation } from \"react-i18next\";\r\nimport { Col, Row } from \"reactstrap\";\r\nimport { AssessmentType } from \"../../../api/main/models/codeOnly/AssessmentType\";\r\nimport { ScoreProgressBar } from \"../../assessmentSessions/launch/progress/ScoreProgressBar\";\r\nimport { DashboardSummary } from \"../utilities/generateDashboardSummary\";\r\n\r\nexport interface AverageScoreProgressBarProps {\r\n summary: DashboardSummary,\r\n title: string,\r\n footer: string,\r\n assessmentType: AssessmentType,\r\n}\r\n\r\n/**\r\n * Show an average score as a progress bar, with supporting data around it.\r\n */\r\nexport const AverageScoreProgressBar = (props: AverageScoreProgressBarProps) => {\r\n const {\r\n summary,\r\n title,\r\n footer,\r\n assessmentType,\r\n } = props;\r\n\r\n const { t } = useTranslation();\r\n\r\n return (\r\n
\r\n
\r\n \r\n {title}\r\n \r\n
\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n
\r\n \r\n {footer}\r\n \r\n
\r\n
\r\n );\r\n};","import { useTranslation } from \"react-i18next\";\r\nimport { AssessmentType } from \"../../../api/main/models/codeOnly/AssessmentType\";\r\nimport { DashboardSummary } from \"../utilities/generateDashboardSummary\";\r\nimport { AverageScoreProgressBar } from \"./AverageScoreProgressBar\";\r\n\r\nexport interface AssessmentAverageScoreProgressBarProps {\r\n summary: DashboardSummary,\r\n}\r\n\r\n/**\r\n * Show an average score for assessments as a progress bar, with supporting data around it.\r\n */\r\nexport const AssessmentAverageScoreProgressBar = (props: AssessmentAverageScoreProgressBarProps) => {\r\n const {\r\n summary,\r\n } = props;\r\n\r\n const { t } = useTranslation();\r\n\r\n return (\r\n \r\n );\r\n};","import { useTranslation } from \"react-i18next\";\r\nimport { AssessmentType } from \"../../../api/main/models/codeOnly/AssessmentType\";\r\nimport { DashboardSummary } from \"../utilities/generateDashboardSummary\";\r\nimport { AverageScoreProgressBar } from \"./AverageScoreProgressBar\";\r\n\r\nexport interface TrainingAverageScoreProgressBarProps {\r\n summary: DashboardSummary,\r\n}\r\n\r\n/**\r\n * Show an average score for trainings as a progress bar, with supporting data around it.\r\n */\r\nexport const TrainingAverageScoreProgressBar = (props: TrainingAverageScoreProgressBarProps) => {\r\n const {\r\n summary,\r\n } = props;\r\n\r\n const { t } = useTranslation();\r\n\r\n return (\r\n \r\n );\r\n};","import { FontAwesomeIcon } from \"@fortawesome/react-fontawesome\";\r\nimport { ReactNode } from \"react\";\r\nimport { ConditionalFragment } from \"react-conditionalfragment\";\r\nimport { useTranslation } from \"react-i18next\";\r\nimport { Badge, Col, ListGroupItem, ListGroupItemText, Row } from \"reactstrap\";\r\nimport { AssessmentType } from \"../../../api/main/models/codeOnly/AssessmentType\";\r\nimport { IdentityRoles } from \"../../../configure/security/IdentityRoles\";\r\nimport { AuthorizeContainer } from \"../../../shared/authorizeRoute\";\r\nimport { AssessmentAverageScoreProgressBar } from \"../progress/AssessmentAverageScoreProgressBar\";\r\nimport { IndividualScoreProgressBar } from \"../progress/IndividualScoreProgressBar\";\r\nimport { TrainingAverageScoreProgressBar } from \"../progress/TrainingAverageScoreProgressBar\";\r\nimport { DashboardSummary } from \"../utilities/generateDashboardSummary\";\r\n\r\nexport interface DashboardListGroupItemProps {\r\n children?: ReactNode,\r\n getDashboardSummary: (assessmentType: AssessmentType) => DashboardSummary,\r\n\r\n hideAssessments?: boolean,\r\n hideTraining?: boolean,\r\n hideSuspicious?: boolean,\r\n\r\n seatExportHref?: string,\r\n\r\n progressType: 'risk' | 'assessments' | 'training',\r\n}\r\n\r\n/**\r\n * List group with items for each group.\r\n * @param props\r\n */\r\nexport const DashboardListGroupItem = (props: DashboardListGroupItemProps) => {\r\n const {\r\n getDashboardSummary,\r\n children,\r\n\r\n hideAssessments = false,\r\n hideTraining = false,\r\n hideSuspicious = true, // We only want to show suspicious when in a user view, for example we dont want to show the assessment under itself in the assessment view if its been marked suspicious\r\n\r\n seatExportHref = undefined,\r\n progressType,\r\n } = props;\r\n\r\n const { t } = useTranslation();\r\n const assessmentsSummary = getDashboardSummary(AssessmentType.Assessment);\r\n const trainingSummary = getDashboardSummary(AssessmentType.TrainingModule);\r\n\r\n return (\r\n \r\n \r\n \r\n
\r\n {children}\r\n
\r\n\r\n \r\n \r\n
\r\n \r\n {t('dashboardListGroupItem.assessments.title', 'Assessments')}\r\n \r\n
\r\n {assessmentsSummary.assessmentsText}\r\n
\r\n \r\n \r\n \r\n {t('dashboardListGroup.notStartedCount', 'Not started')}\r\n <> \r\n \r\n {assessmentsSummary.notStarted}\r\n \r\n \r\n \r\n \r\n \r\n {t('dashboardListGroup.startedCount', 'Started')}\r\n <> \r\n \r\n {assessmentsSummary.started}\r\n \r\n \r\n \r\n \r\n \r\n {t('dashboardListGroup.completedCount', 'Completed')}\r\n <> \r\n \r\n {assessmentsSummary.complete}\r\n \r\n \r\n \r\n \r\n { /*Only want to show for assessments*/ }\r\n {/*Styled to seperate it more from the badges above, also using margin left of 0 keeps it in line with the rest of the content (somehow without it it is more to the left)*/}\r\n \r\n

This assessment has used {assessmentsSummary.totalFinishedSessionsCount} {assessmentsSummary.totalFinishedSessionsCount === 1 ? \"seat\" : \"seats\"}

\r\n {/* Thought this was broken because the number didnt go up, realised I wasnt on an account inside this subscription so it wouldnt track on their dashboard*/}\r\n\r\n
\r\n\r\n \r\n \r\n\r\n \r\n <> {t('assessmentsSummary.export', 'Seat Breakdown')} \r\n \r\n\r\n \r\n \r\n
\r\n
\r\n
\r\n\r\n\r\n \r\n
\r\n
\r\n\r\n \r\n
\r\n \r\n {t('dashboardListGroupItem.training.title', 'Training')}\r\n \r\n
\r\n {trainingSummary.assessmentsText}\r\n
\r\n \r\n \r\n \r\n {t('dashboardListGroup.notStartedCount', 'Not started')}\r\n <> \r\n \r\n {trainingSummary.notStarted}\r\n \r\n \r\n \r\n \r\n \r\n {t('dashboardListGroup.startedCount', 'Started')}\r\n <> \r\n \r\n {trainingSummary.started}\r\n \r\n \r\n \r\n \r\n \r\n {t('dashboardListGroup.completedCount', 'Completed')}\r\n <> \r\n \r\n {trainingSummary.complete}\r\n \r\n \r\n \r\n \r\n
\r\n
\r\n\r\n {/*Should only show marked suspicious section if we have relevant data to show.*/}\r\n
\r\n
\r\n \r\n {t('dashboardListGroupItem.assessments.title', 'Marked Suspicious')}\r\n \r\n
\r\n {assessmentsSummary.suspiciousAssessmentText}\r\n
\r\n
\r\n
\r\n\r\n
\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n
\r\n
\r\n );\r\n};","import { Dispatch, SetStateAction } from \"react\";\r\nimport { Button, ButtonGroup, ListGroupItem } from \"reactstrap\";\r\nimport { OverallRiskCategory, overallRiskService } from \"../../../services/OverallRiskService\";\r\n\r\nexport interface OverallRiskFilterListGroupItemProps {\r\n riskCategoryFilter: OverallRiskCategory | undefined,\r\n setRiskCategoryFilter: Dispatch>,\r\n}\r\n\r\n/**\r\n * ListGroupItem that allows filtering by the overall risk.\r\n * @param props\r\n */\r\nexport const OverallRiskFilterListGroupItem = (props: OverallRiskFilterListGroupItemProps) => {\r\n const {\r\n riskCategoryFilter, setRiskCategoryFilter,\r\n } = props;\r\n\r\n return (\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n );\r\n};","import { useCallback, useMemo } from \"react\";\r\nimport { ConditionalFragment } from \"react-conditionalfragment\";\r\nimport { useTranslation } from \"react-i18next\";\r\nimport { Link } from \"react-router-dom\";\r\nimport { Button, Col, ListGroup, ListGroupItemHeading, Row } from \"reactstrap\";\r\nimport { Assessment } from \"../../../api/main/models/Assessment\";\r\nimport { AssessmentSession } from \"../../../api/main/models/AssessmentSession\";\r\nimport { AssessmentType } from \"../../../api/main/models/codeOnly/AssessmentType\";\r\nimport { Subscription } from \"../../../api/main/models/Subscription\";\r\nimport { UserAssessmentAssignment } from \"../../../api/main/models/UserAssessmentAssignment\";\r\nimport { useActiveDashboardRiskCategoryFilter } from \"../../../globalState/activeDashboardRiskCategoryFilter/useActiveDashboardRiskCategoryFilter\";\r\nimport { AdministrationDashboardTabs } from \"../administrationDashboard/AdministrationDashboard\";\r\nimport { useAverageDriverMetricRiskChartData } from \"../chartData/useAverageDriverMetricRiskChartData\";\r\nimport { useAverageScoreChartData } from \"../chartData/useAverageScoreChartData\";\r\nimport { useCompletionChartData } from \"../chartData/useCompletionChartData\";\r\nimport { AverageDriverMetricRiskDonutChart } from \"../charts/AverageDriverMetricRiskDonutChart\";\r\nimport { AverageScoreRadarChart } from \"../charts/AverageScoreRadarChart\";\r\nimport { CompletionBarChart } from \"../charts/CompletionBarChart\";\r\nimport { DashboardListGroupItem } from \"../listGroups/DashboardListGroupItem\";\r\nimport { OverallRiskFilterListGroupItem } from \"../listGroups/OverallRiskFilterListGroupItem\";\r\nimport { DashboardSummary } from \"../utilities/generateDashboardSummary\";\r\nimport { useCachedDashboardSummaries } from \"../utilities/useCachedDashboardSummaries\";\r\nimport { useDashboardBaseRoute } from \"../utilities/useDashboardBaseRoute\";\r\n\r\nexport interface SubscriptionTabProps {\r\n subscriptions: Array,\r\n generateDashboardSummary: (\r\n sessionFilter: (session: AssessmentSession) => boolean,\r\n assignmentFilter: (assignment: UserAssessmentAssignment) => boolean,\r\n assessmentType: AssessmentType\r\n ) => DashboardSummary,\r\n\r\n assessmentSessions: Array,\r\n assessments: Array,\r\n activeAssessmentType: AssessmentType,\r\n\r\n changeTab: (tabName: AdministrationDashboardTabs) => void,\r\n}\r\n\r\n/**\r\n * Subscriptions tab on the dashboard.\r\n * @param props\r\n */\r\nexport const SubscriptionsDashboardTab = (props: SubscriptionTabProps) => {\r\n const {\r\n subscriptions,\r\n generateDashboardSummary,\r\n changeTab,\r\n activeAssessmentType,\r\n\r\n } = props;\r\n\r\n const { t } = useTranslation();\r\n\r\n // As a special case for subscriptions, we add \"Esitu staff\" on to the subscription lists. As we'll do this several times we store it here for reuse.\r\n const subscriptionsAndEsitu = useMemo(() => [{ id: '', name: t('subscriptionDashboardTab.esituStaff', 'Esitu staff') }, ...(subscriptions?.map(item => ({ id: item.id, name: item.companyName })) ?? [])], [subscriptions, t]);\r\n\r\n // Method we use to filter sessions by subscription wherever we need it.\r\n const filterBySubscription = useCallback((subscription: { id: string }, item: { subscriptionId: string | undefined | null }) => {\r\n if (!subscription.id) {\r\n return !item.subscriptionId;\r\n }\r\n\r\n return item.subscriptionId === subscription.id;\r\n }, []);\r\n\r\n // Cache the dashboard summaries so each chart/display doesn't need to recaclulate them and they can be looked up easily by id.\r\n const getCachedDashboardSummary = useCachedDashboardSummaries(\r\n subscriptionsAndEsitu,\r\n (group, assessmentType) => generateDashboardSummary(\r\n session => filterBySubscription(group, session),\r\n assignment => filterBySubscription(group, assignment),\r\n assessmentType\r\n )\r\n );\r\n\r\n // Get data for the various charts.\r\n const averageScoreChartData = useAverageScoreChartData(subscriptionsAndEsitu, getCachedDashboardSummary, activeAssessmentType);\r\n const averageDriverMetricRiskChartData = useAverageDriverMetricRiskChartData(subscriptionsAndEsitu, getCachedDashboardSummary, activeAssessmentType);\r\n const completionChartData = useCompletionChartData(subscriptionsAndEsitu, getCachedDashboardSummary, activeAssessmentType);\r\n\r\n // Filter the visible results by overall risk category if required.\r\n const [riskCategoryFilter, setRiskCategoryFilter] = useActiveDashboardRiskCategoryFilter();\r\n const filterdSubscriptionsAndEsitu = useMemo(() => {\r\n if (!riskCategoryFilter) {\r\n return subscriptionsAndEsitu;\r\n }\r\n\r\n return subscriptionsAndEsitu.filter(user => {\r\n const summary = getCachedDashboardSummary(user.id, activeAssessmentType);\r\n return (summary.averageUserDriverMetricScore.riskCategory === riskCategoryFilter);\r\n })\r\n }, [subscriptionsAndEsitu, riskCategoryFilter, getCachedDashboardSummary, activeAssessmentType]);\r\n \r\n const baseRoute = useDashboardBaseRoute();\r\n\r\n return (\r\n \r\n \r\n \r\n \r\n {\r\n filterdSubscriptionsAndEsitu.map(subscription => (\r\n getCachedDashboardSummary(subscription.id, assessmentType)}\r\n progressType=\"risk\"\r\n >\r\n {\r\n subscription.id ? (\r\n \r\n \r\n {subscription.name}\r\n \r\n \r\n ) : (\r\n \r\n )\r\n }\r\n \r\n ))\r\n }\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n );\r\n};","import { useCallback, useMemo } from \"react\";\r\nimport { ConditionalFragment } from \"react-conditionalfragment\";\r\nimport { useTranslation } from \"react-i18next\";\r\nimport { Link } from \"react-router-dom\";\r\nimport { Col, ListGroup, ListGroupItemHeading, ListGroupItemText, Row } from \"reactstrap\";\r\nimport { Assessment } from \"../../../api/main/models/Assessment\";\r\nimport { AssessmentSession } from \"../../../api/main/models/AssessmentSession\";\r\nimport { AssessmentType } from \"../../../api/main/models/codeOnly/AssessmentType\";\r\nimport { Profile } from \"../../../api/main/models/Profile\";\r\nimport { Subscription } from \"../../../api/main/models/Subscription\";\r\nimport { SubscriptionTeam } from \"../../../api/main/models/SubscriptionTeam\";\r\nimport { UserAssessmentAssignment } from \"../../../api/main/models/UserAssessmentAssignment\";\r\nimport { useActiveDashboardRiskCategoryFilter } from \"../../../globalState/activeDashboardRiskCategoryFilter/useActiveDashboardRiskCategoryFilter\";\r\nimport { RiskRules } from \"../../../services/OverallRiskService\";\r\nimport { useAverageDriverMetricRiskChartData } from \"../chartData/useAverageDriverMetricRiskChartData\";\r\nimport { useAverageScoreChartData } from \"../chartData/useAverageScoreChartData\";\r\nimport { useCompletionChartData } from \"../chartData/useCompletionChartData\";\r\nimport { AverageDriverMetricRiskDonutChart } from \"../charts/AverageDriverMetricRiskDonutChart\";\r\nimport { AverageScoreRadarChart } from \"../charts/AverageScoreRadarChart\";\r\nimport { CompletionBarChart } from \"../charts/CompletionBarChart\";\r\nimport { DashboardListGroupItem } from \"../listGroups/DashboardListGroupItem\";\r\nimport { OverallRiskFilterListGroupItem } from \"../listGroups/OverallRiskFilterListGroupItem\";\r\nimport { DashboardSummary } from \"../utilities/generateDashboardSummary\";\r\nimport { useCachedDashboardSummaries } from \"../utilities/useCachedDashboardSummaries\";\r\nimport { useDashboardBaseRoute } from \"../utilities/useDashboardBaseRoute\";\r\n\r\nexport interface UsersDashboardTabProps {\r\n profiles: Array,\r\n generateDashboardSummary: (\r\n sessionFilter: (session: AssessmentSession) => boolean,\r\n assignmentFilter: (assignment: UserAssessmentAssignment) => boolean,\r\n assessmentType: AssessmentType,\r\n ) => DashboardSummary,\r\n\r\n assessmentSessions: Array,\r\n assessments: Array,\r\n activeAssessmentType: AssessmentType,\r\n\r\n showSubscriptionName?: boolean,\r\n subscriptions?: Array,\r\n subscriptionTeams?: Array,\r\n\r\n linkToFolder?: string,\r\n\r\n riskRules: RiskRules | undefined | null,\r\n}\r\n\r\n/**\r\n * User based tab on the dashboard.\r\n * @param props\r\n */\r\nexport const UsersDashboardTab = (props: UsersDashboardTabProps) => {\r\n const {\r\n profiles,\r\n generateDashboardSummary,\r\n activeAssessmentType,\r\n\r\n showSubscriptionName = false,\r\n subscriptions,\r\n subscriptionTeams,\r\n\r\n linkToFolder = 'user',\r\n riskRules,\r\n } = props;\r\n\r\n const { t } = useTranslation();\r\n\r\n // Method we use to filter sessions by user wherever we need it.\r\n const filterByUser = useCallback((user: { id: string }, item: { userId: string | undefined | null }) => {\r\n return item.userId === user.id;\r\n }, []);\r\n\r\n // Profiles simplified to have a name and id (for which we use the userId).\r\n const users = useMemo(() => profiles.map(profile => ({\r\n id: profile.userId,\r\n name: t('common.fullName', '{{firstName}} {{lastName}}', profile),\r\n subscriptionId: profile.subscriptionId,\r\n subscriptionTeamId: profile.subscriptionTeamId,\r\n })), [profiles, t]);\r\n\r\n // Cache the dashboard summaries so each chart/display doesn't need to recaclulate them and they can be looked up easily by id.\r\n const getCachedDashboardSummary = useCachedDashboardSummaries(\r\n users,\r\n (group, assessmentType) => generateDashboardSummary(\r\n session => filterByUser(group, session),\r\n assignment => filterByUser(group, assignment),\r\n assessmentType\r\n )\r\n );\r\n\r\n // Filter the visible results by overall risk category if required.\r\n const [riskCategoryFilter, setRiskCategoryFilter] = useActiveDashboardRiskCategoryFilter();\r\n const filterdUsers = useMemo(() => {\r\n if (!riskCategoryFilter) {\r\n return users;\r\n }\r\n\r\n return users.filter(user => {\r\n const summary = getCachedDashboardSummary(user.id, activeAssessmentType);\r\n return (summary.averageUserDriverMetricScore.riskCategory === riskCategoryFilter);\r\n })\r\n }, [users, riskCategoryFilter, getCachedDashboardSummary, activeAssessmentType]);\r\n\r\n // Get data for the various charts.\r\n const averageScoreChartData = useAverageScoreChartData(users, getCachedDashboardSummary, activeAssessmentType);\r\n const averageScoreRiskChartData = useAverageDriverMetricRiskChartData(users, getCachedDashboardSummary, activeAssessmentType);\r\n const completionChartData = useCompletionChartData(users, getCachedDashboardSummary, activeAssessmentType);\r\n \r\n\r\n const baseRoute = useDashboardBaseRoute();\r\n\r\n return (\r\n \r\n \r\n \r\n \r\n {\r\n filterdUsers.map(user => {\r\n\r\n // Also find the team and if available subscription for the profile.\r\n const team = subscriptionTeams?.find(it => it.id === user.subscriptionTeamId);\r\n const subscription = subscriptions?.find(it => it.id === user.subscriptionId);\r\n\r\n return (\r\n getCachedDashboardSummary(user.id, assessmentType)}\r\n progressType=\"risk\"\r\n >\r\n \r\n \r\n {user.name}\r\n \r\n \r\n \r\n \r\n \r\n {team?.name}\r\n \r\n \r\n \r\n <> \r\n {'('}\r\n \r\n {subscription?.companyName}\r\n \r\n {')'}\r\n \r\n \r\n \r\n );\r\n })\r\n }\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n );\r\n};","import { useMemo } from \"react\";\r\nimport { UsersDashboardTab, UsersDashboardTabProps } from \"./UsersDashboardTab\";\r\n\r\n/**\r\n * Esitu staff tab on the dashboard.\r\n * @param props\r\n */\r\nexport const EsituStaffDashboardTab = (props: UsersDashboardTabProps) => {\r\n const {\r\n profiles,\r\n ...rest\r\n } = props;\r\n\r\n const staffProfiles = useMemo(() => profiles.filter(item => !item.subscriptionId), [profiles]);\r\n\r\n return (\r\n \r\n );\r\n};","import { useCallback, useMemo } from \"react\";\r\nimport { ConditionalFragment } from \"react-conditionalfragment\";\r\nimport { Link } from \"react-router-dom\";\r\nimport { Col, ListGroup, ListGroupItemHeading, ListGroupItemText, Row } from \"reactstrap\";\r\nimport { Assessment } from \"../../../api/main/models/Assessment\";\r\nimport { AssessmentSession } from \"../../../api/main/models/AssessmentSession\";\r\nimport { AssessmentType } from \"../../../api/main/models/codeOnly/AssessmentType\";\r\nimport { Profile } from \"../../../api/main/models/Profile\";\r\nimport { Subscription } from \"../../../api/main/models/Subscription\";\r\nimport { SubscriptionTeam } from \"../../../api/main/models/SubscriptionTeam\";\r\nimport { UserAssessmentAssignment } from \"../../../api/main/models/UserAssessmentAssignment\";\r\nimport { useActiveDashboardRiskCategoryFilter } from \"../../../globalState/activeDashboardRiskCategoryFilter/useActiveDashboardRiskCategoryFilter\";\r\nimport { RiskRules } from \"../../../services/OverallRiskService\";\r\nimport { useAverageDriverMetricRiskChartData } from \"../chartData/useAverageDriverMetricRiskChartData\";\r\nimport { useAverageScoreChartData } from \"../chartData/useAverageScoreChartData\";\r\nimport { useCompletionChartData } from \"../chartData/useCompletionChartData\";\r\nimport { AverageDriverMetricRiskDonutChart } from \"../charts/AverageDriverMetricRiskDonutChart\";\r\nimport { AverageScoreRadarChart } from \"../charts/AverageScoreRadarChart\";\r\nimport { CompletionBarChart } from \"../charts/CompletionBarChart\";\r\nimport { DashboardListGroupItem } from \"../listGroups/DashboardListGroupItem\";\r\nimport { OverallRiskFilterListGroupItem } from \"../listGroups/OverallRiskFilterListGroupItem\";\r\nimport { DashboardSummary } from \"../utilities/generateDashboardSummary\";\r\nimport { useCachedDashboardSummaries } from \"../utilities/useCachedDashboardSummaries\";\r\nimport { useDashboardBaseRoute } from \"../utilities/useDashboardBaseRoute\";\r\n\r\nexport interface SubscriptionTeamsDashboardTabProps {\r\n subscriptionTeams: Array,\r\n profiles: Array,\r\n generateDashboardSummary: (\r\n sessionFilter: (session: AssessmentSession) => boolean,\r\n assignmentFilter: (assignment: UserAssessmentAssignment) => boolean,\r\n assessmentType: AssessmentType\r\n ) => DashboardSummary,\r\n\r\n assessmentSessions: Array,\r\n assessments: Array,\r\n activeAssessmentType: AssessmentType,\r\n\r\n showSubscriptionName?: boolean,\r\n subscriptions?: Array,\r\n\r\n riskRules: RiskRules | undefined | null,\r\n}\r\n\r\n/**\r\n * User based tab on the dashboard.\r\n * @param props\r\n */\r\nexport const SubscriptionTeamsDashboardTab = (props: SubscriptionTeamsDashboardTabProps) => {\r\n const {\r\n subscriptionTeams,\r\n profiles,\r\n generateDashboardSummary,\r\n activeAssessmentType,\r\n\r\n showSubscriptionName = false,\r\n subscriptions,\r\n\r\n riskRules,\r\n } = props;\r\n\r\n // Method we use to filter sessions by user wherever we need it.\r\n const filterByTeam = useCallback((subscriptionTeam: { id: string }, item: { userId: string | undefined | null }) => {\r\n const profile = profiles.find(it => it.userId === item.userId);\r\n if (!profile) {\r\n return false;\r\n }\r\n\r\n return profile.subscriptionTeamId === subscriptionTeam.id;\r\n }, [profiles]);\r\n\r\n // Cache the dashboard summaries so each chart/display doesn't need to recaclulate them and they can be looked up easily by id.\r\n const getCachedDashboardSummary = useCachedDashboardSummaries(\r\n subscriptionTeams,\r\n (group, assessmentType) => generateDashboardSummary(\r\n session => filterByTeam(group, session),\r\n assignment => filterByTeam(group, assignment),\r\n assessmentType\r\n )\r\n );\r\n\r\n // Get data for the various charts.\r\n const averageScoreChartData = useAverageScoreChartData(subscriptionTeams, getCachedDashboardSummary, activeAssessmentType);\r\n const averageScoreRiskChartData = useAverageDriverMetricRiskChartData(subscriptionTeams, getCachedDashboardSummary, activeAssessmentType);\r\n const completionChartData = useCompletionChartData(subscriptionTeams, getCachedDashboardSummary, activeAssessmentType);\r\n\r\n // Filter the visible results by overall risk category if required.\r\n const [riskCategoryFilter, setRiskCategoryFilter] = useActiveDashboardRiskCategoryFilter();\r\n const filteredSubscriptionTeams = useMemo(() => {\r\n if (!riskCategoryFilter) {\r\n return subscriptionTeams;\r\n }\r\n\r\n return subscriptionTeams.filter(user => {\r\n const summary = getCachedDashboardSummary(user.id, activeAssessmentType);\r\n return (summary.averageUserDriverMetricScore.riskCategory === riskCategoryFilter);\r\n })\r\n }, [subscriptionTeams, riskCategoryFilter, getCachedDashboardSummary, activeAssessmentType]);\r\n\r\n\r\n const baseRoute = useDashboardBaseRoute();\r\n\r\n return (\r\n \r\n \r\n \r\n \r\n {\r\n filteredSubscriptionTeams.map(team => (\r\n getCachedDashboardSummary(team.id, assessmentType)}\r\n progressType=\"risk\"\r\n >\r\n \r\n \r\n {team.name}\r\n \r\n \r\n\r\n \r\n \r\n {'(' /* Can/should this be made translatable? */}\r\n \r\n {subscriptions?.find(it => it.id === team.subscriptionId)?.companyName}\r\n \r\n {')'}\r\n \r\n \r\n \r\n ))\r\n }\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n );\r\n};","import { useMemo } from \"react\";\r\nimport { UsersDashboardTab, UsersDashboardTabProps } from \"./UsersDashboardTab\";\r\n\r\n/**\r\n * Subscription users tab on the dashboard.\r\n * @param props\r\n */\r\nexport const SubscriptionUsersDashboardTab = (props: UsersDashboardTabProps) => {\r\n const {\r\n profiles,\r\n ...rest\r\n } = props;\r\n\r\n const nonStaffProfiles = useMemo(() => profiles.filter(item => !!item.subscriptionId), [profiles]);\r\n\r\n return (\r\n \r\n );\r\n};","import { useCallback, useMemo } from \"react\";\r\nimport { ConditionalFragment } from \"react-conditionalfragment\";\r\nimport { useTranslation } from \"react-i18next\";\r\nimport { Link } from \"react-router-dom\";\r\nimport { Col, ListGroup, ListGroupItemHeading, Row } from \"reactstrap\";\r\nimport { isNullOrUndefined } from \"util\";\r\nimport { Assessment } from \"../../../api/main/models/Assessment\";\r\nimport { AssessmentSession } from \"../../../api/main/models/AssessmentSession\";\r\nimport { AssessmentType } from \"../../../api/main/models/codeOnly/AssessmentType\";\r\nimport { UserAssessmentAssignment } from \"../../../api/main/models/UserAssessmentAssignment\";\r\nimport { useActiveDashboardRiskCategoryFilter } from \"../../../globalState/activeDashboardRiskCategoryFilter/useActiveDashboardRiskCategoryFilter\";\r\nimport { useCurrentUserOrEmulatedSubscriptionId } from \"../../../globalState/subscriptions/useCurrentUserOrEmulatedSubscriptionId\";\r\nimport { RiskRules } from \"../../../services/OverallRiskService\";\r\nimport { useAverageScoreChartData } from \"../chartData/useAverageScoreChartData\";\r\nimport { useCompletionChartData } from \"../chartData/useCompletionChartData\";\r\nimport { AverageScoreRadarChart } from \"../charts/AverageScoreRadarChart\";\r\nimport { CompletionBarChart } from \"../charts/CompletionBarChart\";\r\nimport { DashboardListGroupItem } from \"../listGroups/DashboardListGroupItem\";\r\nimport { OverallRiskFilterListGroupItem } from \"../listGroups/OverallRiskFilterListGroupItem\";\r\nimport { DashboardSummary } from \"../utilities/generateDashboardSummary\";\r\nimport { useCachedDashboardSummaries } from \"../utilities/useCachedDashboardSummaries\";\r\nimport { useDashboardBaseRoute } from \"../utilities/useDashboardBaseRoute\";\r\n\r\nexport interface AssessmentsDashboardTabBaseProps {\r\n assessmentType?: AssessmentType | undefined,\r\n\r\n assessments: Array,\r\n generateDashboardSummary: (\r\n sessionFilter: (session: AssessmentSession) => boolean,\r\n assignmentFilter: (assignment: UserAssessmentAssignment) => boolean,\r\n assessmentType: AssessmentType,\r\n riskRule: RiskRules | undefined | null\r\n ) => DashboardSummary,\r\n\r\n assessmentSessions: Array,\r\n activeAssessmentType: AssessmentType,\r\n\r\n linkToFolder?: string,\r\n\r\n riskRules: RiskRules | undefined | null,\r\n\r\n subscriptionId?: string,\r\n}\r\n\r\n/**\r\n * Base tab for assessment based tabs on the dashboard (e.g. assessments and training).\r\n * @param props\r\n */\r\nexport const AssessmentsDashboardTabBase = (props: AssessmentsDashboardTabBaseProps) => {\r\n const {\r\n assessments: allAssessments,\r\n assessmentType,\r\n\r\n generateDashboardSummary,\r\n activeAssessmentType: _activeAssessmentType,\r\n\r\n linkToFolder = 'assessment',\r\n\r\n riskRules,\r\n\r\n subscriptionId,\r\n } = props;\r\n\r\n // If we are forced into a single assesment type, set it as the active assessment type automatically.\r\n const activeAssessmentType = assessmentType ?? _activeAssessmentType;\r\n\r\n const mySubscriptionId = useCurrentUserOrEmulatedSubscriptionId();\r\n\r\n const { t } = useTranslation();\r\n const assessments = useMemo(() => {\r\n if (isNullOrUndefined(assessmentType)) {\r\n return allAssessments;\r\n }\r\n\r\n return allAssessments.filter(item => item.assessmentType === assessmentType);\r\n }, [allAssessments, assessmentType]);\r\n\r\n // Method we use to filter sessions by user wherever we need it.\r\n const filterByAssessment = useCallback((assessment: { id: string }, item: { assessmentId: string | undefined | null }) => {\r\n return item.assessmentId === assessment.id;\r\n }, []);\r\n\r\n // Cache the dashboard summaries so each chart/display doesn't need to recaclulate them and they can be looked up easily by id.\r\n const getCachedDashboardSummary = useCachedDashboardSummaries(\r\n assessments,\r\n (group, assessmentType) => generateDashboardSummary(\r\n session => filterByAssessment(group, session),\r\n assignment => filterByAssessment(group, assignment),\r\n assessmentType,\r\n assessments.find(item => item.id === group.id)\r\n )\r\n );\r\n\r\n // Get data for the various charts.\r\n const averageScoreChartData = useAverageScoreChartData(assessments, getCachedDashboardSummary, activeAssessmentType);\r\n const completionChartData = useCompletionChartData(assessments, getCachedDashboardSummary, activeAssessmentType);\r\n\r\n // Filter the visible results by overall risk category if required.\r\n const [riskCategoryFilter, setRiskCategoryFilter] = useActiveDashboardRiskCategoryFilter();\r\n const filterdAssessments = useMemo(() => {\r\n // Only AssessmentType.Assessment can be filtered by risk.\r\n if (activeAssessmentType !== AssessmentType.Assessment) {\r\n return assessments;\r\n }\r\n\r\n if (!riskCategoryFilter) {\r\n return assessments;\r\n }\r\n\r\n return assessments.filter(user => {\r\n const summary = getCachedDashboardSummary(user.id, activeAssessmentType);\r\n return (summary.averageScore.riskCategory === riskCategoryFilter); // For assessments we use averaged score rather than averateUserDriverMetricScore to match the presented progress bars.\r\n })\r\n }, [assessments, riskCategoryFilter, getCachedDashboardSummary, activeAssessmentType]);\r\n\r\n const baseRoute = useDashboardBaseRoute();\r\n\r\n return (\r\n \r\n \r\n \r\n \r\n \r\n \r\n {\r\n filterdAssessments.map(assessment => (\r\n getCachedDashboardSummary(assessment.id, assessmentType)}\r\n hideAssessments={assessmentType === AssessmentType.TrainingModule}\r\n hideTraining={assessmentType === AssessmentType.Assessment}\r\n progressType={assessmentType === AssessmentType.Assessment ? 'assessments' : 'training'}\r\n seatExportHref={`/api/export/SeatsBreakdown?subscriptionId=${encodeURIComponent(mySubscriptionId ?? subscriptionId ?? \"\")}&assessmentId=${encodeURIComponent(assessment.id)}` }\r\n >\r\n \r\n \r\n {assessment.name}\r\n \r\n \r\n \r\n ))\r\n }\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n );\r\n};","import { AssessmentType } from \"../../../api/main/models/codeOnly/AssessmentType\";\r\nimport { AssessmentsDashboardTabBase, AssessmentsDashboardTabBaseProps } from \"./AssessmentsDashboardTabBase\";\r\n\r\n/**\r\n * Assessments tab on the dashboard.\r\n * @param props\r\n */\r\nexport const AssessmentsDashboardTab = (props: AssessmentsDashboardTabBaseProps) => {\r\n return (\r\n \r\n );\r\n};","import { AssessmentType } from \"../../../api/main/models/codeOnly/AssessmentType\";\r\nimport { AssessmentsDashboardTabBase, AssessmentsDashboardTabBaseProps } from \"./AssessmentsDashboardTabBase\";\r\n\r\n/**\r\n * Training tab on the dashboard.\r\n * @param props\r\n */\r\nexport const TrainingDashboardTab = (props: AssessmentsDashboardTabBaseProps) => {\r\n return (\r\n \r\n );\r\n};","import * as React from 'react';\r\nimport { atom, useRecoilState } from 'recoil';\r\nimport { AssessmentType } from '../../api/main/models/codeOnly/AssessmentType';\r\nimport { persistAtom } from '../../configure/recoilPersistConfig';\r\n\r\nexport const activeDashboardAssessmentTypeState = atom({\r\n key: 'activeDashboardAssessmentTypeState',\r\n default: AssessmentType.Assessment,\r\n effects_UNSTABLE: [persistAtom],\r\n \r\n});\r\n\r\n/**\r\n * Hook that returns the active AssessmentType to use for Dashboards.\r\n */\r\nexport function useActiveDashboardAssessmentType(): [AssessmentType, React.Dispatch>] {\r\n const [value, setValue] = useRecoilState(activeDashboardAssessmentTypeState);\r\n return [value, setValue];\r\n}","import { Dispatch, SetStateAction, useCallback } from 'react';\r\nimport { atom, useRecoilState } from 'recoil';\r\nimport { persistAtom } from '../../configure/recoilPersistConfig';\r\n\r\ninterface DashboardActiveTab {\r\n dashboard: string,\r\n activeTab: string,\r\n}\r\n\r\nexport const activeDashboardTabState = atom>({\r\n key: 'activeDashboardTabState',\r\n default: [],\r\n effects_UNSTABLE: [persistAtom],\r\n \r\n});\r\n\r\n/**\r\n * Hook that returns the active tab for a specific dashboard so it can be preserved as we navigate around and between sessions.\r\n */\r\nexport function useActiveDashboardTab(dashboard: string, defaultValue: T): [T, Dispatch>] {\r\n const [array, setArray] = useRecoilState(activeDashboardTabState);\r\n\r\n const myDashboard = array.find(it => it.dashboard === dashboard);\r\n const activeTab = myDashboard?.activeTab as T ?? defaultValue;\r\n\r\n const setActiveTab = useCallback((value: SetStateAction) => setArray(prevState => {\r\n let newValue = value;\r\n\r\n // If we have a function, execute it.\r\n if (value instanceof Function) {\r\n const myPrevState = prevState.find(it => it.dashboard === dashboard)?.activeTab as T ?? defaultValue;\r\n newValue = value(myPrevState);\r\n }\r\n\r\n // Update the array.\r\n return [\r\n ...prevState.filter(it => it.dashboard !== dashboard),\r\n { dashboard: dashboard, activeTab: newValue } as DashboardActiveTab,\r\n ];\r\n }), [setArray, dashboard, defaultValue])\r\n\r\n return [activeTab, setActiveTab];\r\n}","import { ReactNode } from \"react\";\r\nimport { ConditionalFragment } from \"react-conditionalfragment\";\r\nimport { useTranslation } from \"react-i18next\";\r\nimport { Badge, Card, CardBody, CardHeader, Col, ListGroupItem, ListGroupItemText, Row } from \"reactstrap\";\r\nimport { AssessmentType } from \"../../../api/main/models/codeOnly/AssessmentType\";\r\nimport { Subscription } from \"../../../api/main/models/Subscription\";\r\nimport { generateDistributorDashboardSummary } from \"../utilities/generateDashboardSummary\";\r\nimport { Assessment } from \"../../../api/main/models/Assessment\";\r\nimport { UserAssessmentAssignment } from \"../../../api/main/models/UserAssessmentAssignment\";\r\nimport { SubscriptionAssessment } from \"../../../api/main/models/SubscriptionAssessment\";\r\n\r\nexport interface DistributorDashboardListGroupItemProps {\r\n children?: ReactNode,\r\n subscriptionId: string,\r\n subscriptions: Array,\r\n subscriptionAssessments: Array,\r\n userAssessmentAssignment: Array,\r\n assessments: Array,\r\n\r\n}\r\n\r\n/**\r\n * List group with items for each group.\r\n * @param props\r\n */\r\nexport const DistributorDashboardListGroupItem = (props: DistributorDashboardListGroupItemProps) => {\r\n const {\r\n children,\r\n subscriptionId,\r\n subscriptions,\r\n subscriptionAssessments,\r\n assessments,\r\n userAssessmentAssignment,\r\n } = props;\r\n\r\n const { t } = useTranslation();\r\n const distributorSummary = generateDistributorDashboardSummary(subscriptions, subscriptionId, userAssessmentAssignment, subscriptionAssessments, assessments,);\r\n const distributorAssessments = distributorSummary.filteredAssessments.filter(item => item.assessmentType === AssessmentType.Assessment)\r\n const distributorTraining = distributorSummary.filteredAssessments.filter(item => item.assessmentType === AssessmentType.TrainingModule)\r\n\r\n return (\r\n \r\n \r\n \r\n
\r\n {children}\r\n
\r\n \r\n \r\n \r\n
\r\n {\"Subscriptions\"}\r\n
\r\n \r\n {t('dashboardListGroup.NoDataToShow','No data to show')}\r\n \r\n
\r\n {distributorSummary.DistributorSubscriptionsText}\r\n
\r\n \r\n {t('dashboardListGroup.TotalSubscriptions', 'Total subscriptions')}\r\n <> \r\n \r\n {distributorSummary.totalSubscriptionsCount}\r\n \r\n \r\n \r\n
\r\n
\r\n \r\n \r\n
\r\n {\"Assessments\"}\r\n
\r\n \r\n {t('dashboardListGroup.NoDataToShow', 'No data to show')}\r\n \r\n \r\n
\r\n \r\n {\r\n distributorAssessments.map(item =>\r\n it.AssessmentId === item.id)?.count !== undefined}>\r\n \r\n \r\n {item.name}\r\n \r\n {t('dashboardListGroup.TimesAssigned', 'Times assigned: ')}\r\n {distributorSummary.assessmentAssignments.find(it => it.AssessmentId === item.id)?.count}\r\n \r\n \r\n \r\n \r\n )\r\n }\r\n \r\n \r\n \r\n \r\n {t('dashboardListGroup.totalAssessmentAssignments', 'Total assessment assignments')}\r\n <> \r\n \r\n {distributorSummary.distributorUserAssessmentAssignmentCount}\r\n \r\n \r\n \r\n \r\n
\r\n \r\n \r\n
\r\n {\"Training\"}\r\n
\r\n \r\n {t('dashboardListGroup.NoDataToShow', 'No data to show')}\r\n \r\n \r\n
\r\n \r\n {\r\n distributorTraining.map(item =>\r\n it.AssessmentId === item.id)?.count !== undefined}>\r\n \r\n \r\n {item.name}\r\n \r\n {t('dashboardListGroup.TimesAssigned', 'Times assigned: ')}\r\n {distributorSummary.assessmentAssignments.find(it => it.AssessmentId === item.id)?.count}\r\n \r\n \r\n \r\n \r\n )\r\n }\r\n \r\n \r\n \r\n \r\n {t('dashboardListGroup.totalTrainingAssignments', 'Total training assignments')}\r\n <> \r\n \r\n {distributorSummary.distributorUserTrainingAssignmentCount}\r\n \r\n \r\n \r\n \r\n
\r\n \r\n
\r\n
\r\n );\r\n};","import { Link } from \"react-router-dom\";\r\nimport { Button, Col, ListGroup, ListGroupItemHeading, Row } from \"reactstrap\";\r\nimport { Assessment } from \"../../../api/main/models/Assessment\";\r\nimport { AssessmentType } from \"../../../api/main/models/codeOnly/AssessmentType\";\r\nimport { Subscription } from \"../../../api/main/models/Subscription\";\r\nimport { SubscriptionAssessment } from \"../../../api/main/models/SubscriptionAssessment\";\r\nimport { UserAssessmentAssignment } from \"../../../api/main/models/UserAssessmentAssignment\";\r\nimport { AdministrationDashboardTabs } from \"../administrationDashboard/AdministrationDashboard\";\r\nimport { DistributorDashboardListGroupItem } from \"../listGroups/DistributorDashboardListGroupItem\";\r\nimport { useDashboardBaseRoute } from \"../utilities/useDashboardBaseRoute\";\r\n\r\nexport interface DistributorDashboardSummary {\r\n subscriptionId: string,\r\n}\r\n\r\nexport interface DistributorTabProps {\r\n distributors: Array,\r\n subscriptions: Array,\r\n subscriptionAssessments: Array,\r\n userAssessmentAssignment: Array,\r\n assessments: Array,\r\n activeAssessmentType: AssessmentType,\r\n\r\n changeTab: (tabName: AdministrationDashboardTabs) => void,\r\n}\r\n\r\n/**\r\n * Subscriptions tab on the dashboard.\r\n * @param props\r\n */\r\nexport const DistributorsDashboardTab = (props: DistributorTabProps) => {\r\n const {\r\n distributors,\r\n subscriptions,\r\n subscriptionAssessments,\r\n changeTab,\r\n assessments,\r\n userAssessmentAssignment,\r\n\r\n } = props;\r\n\r\n\r\n const baseRoute = useDashboardBaseRoute();\r\n\r\n return (\r\n \r\n \r\n \r\n {\r\n distributors.map(subscription => (\r\n \r\n {\r\n subscription.id ? (\r\n \r\n \r\n {subscription.companyName}\r\n \r\n \r\n ) : (\r\n \r\n )\r\n }\r\n \r\n ))\r\n }\r\n \r\n \r\n \r\n );\r\n};","/**\r\n * Colour palette used by charts.\r\n * \r\n * Note that we've tried to use a larger colour pallet before repeating the colours.\r\n */\r\nexport const chartColors = [\r\n // Brand specific chart colours.\r\n '#ec0b62', '#2f5597', '#00c4de',\r\n\r\n // General chart colours.\r\n '#008FFB', '#00E396', '#FEB019', '#FF4560', '#775DD0',\r\n '#4caf50', '#3f51b5', '#FF9800',\r\n '#546E7A', '#d4526e', '#A5978B',\r\n '#4ecdc4', '#c7f464',\r\n '#f9a3a4', '#69d2e7',\r\n '#F86624', '#EA3546', '#C5D86D',\r\n '#D7263D', '#1B998B', '#2E294E',\r\n '#662E9B', '#f9ce1d',\r\n '#8D5B4C'\r\n];\r\n","import { ApexOptions }from \"apexcharts\";\r\nimport Chart from \"react-apexcharts\";\r\nimport { useMemo } from \"react\";\r\nimport { Card } from \"reactstrap\";\r\nimport { ChartDataSeries } from \"../chartDataUtilities/ChartData\";\r\nimport { chartDataConverters } from \"../chartDataUtilities/ChartDataConverter\";\r\nimport { useTranslation } from \"react-i18next\";\r\nimport { chartColors } from \"../../../configure/chartColors\";\r\nimport { overallRiskService, RiskRules } from \"../../../services/OverallRiskService\";\r\n\r\nexport interface DriverMetricsRadarChartProps {\r\n data: Array,\r\n riskRules?: RiskRules | undefined | null,\r\n\r\n width?: string | number | undefined,\r\n height?: string | number | undefined,\r\n}\r\n\r\n/**\r\n * Chart that shows average scores as a radar.\r\n */\r\nexport const DriverMetricsRadarChart = (props: DriverMetricsRadarChartProps) => {\r\n const {\r\n data,\r\n riskRules,\r\n width,\r\n height,\r\n } = props;\r\n\r\n const { t } = useTranslation();\r\n\r\n // Convert data into format needed for this graph.\r\n const { series, options: seriesOptions } = useMemo(() => chartDataConverters.toRadar(data), [data]);\r\n\r\n // Compile all the options we want to use.\r\n const options = useMemo(() => (\r\n {\r\n chart: {\r\n toolbar: {\r\n show: false,\r\n },\r\n },\r\n\r\n title: {\r\n text: t('driverMetricsRadarChart.title', 'Safety profile'),\r\n align: 'center',\r\n },\r\n\r\n colors: chartColors,\r\n\r\n yaxis: {\r\n min: 0,\r\n max: 100,\r\n tickAmount: 10,\r\n },\r\n\r\n plotOptions: {\r\n radar: {\r\n polygons: {\r\n fill: {\r\n colors: overallRiskService.getSpidergraphBackgroundColors(10, riskRules),\r\n }\r\n }\r\n\r\n }\r\n },\r\n\r\n ...seriesOptions,\r\n } as ApexOptions\r\n ), [seriesOptions, t, riskRules]);\r\n\r\n // We need to force the refresh of the chart sometimes by updating its key as its too optomistic with its internal caching and\r\n // so doesn't end up changes top options very well at all if we dont.\r\n const key = useMemo(() => JSON.stringify(options), [options]);\r\n\r\n return (\r\n \r\n \r\n \r\n );\r\n};","import { useMemo } from \"react\";\r\nimport { useTranslation } from \"react-i18next\";\r\nimport { Card, Col, Row } from \"reactstrap\";\r\nimport { AssessmentType } from \"../../../api/main/models/codeOnly/AssessmentType\";\r\nimport { DriverMetric } from \"../../../api/main/models/DriverMetric\";\r\nimport { UserDriverMetric } from \"../../../api/main/models/UserDriverMetric\";\r\nimport { RiskRules } from \"../../../services/OverallRiskService\";\r\nimport { questionScoreFromNumber } from \"../../assessmentSessions/launch/utilities/questionScoreFromNumber\";\r\nimport { IndividualScoreProgressBar } from \"../progress/IndividualScoreProgressBar\";\r\nimport \"./driverScoreProgressBarAsChart.scss\";\r\n\r\nexport interface DriverScoreProgressBarAsChartProps {\r\n userDriverMetrics: Array,\r\n driverMetrics: Array,\r\n riskRules?: RiskRules | null | undefined,\r\n}\r\n\r\n/**\r\n * Show an AssessmentAverageScoreProgressBar formatted to look like the other charts do.\r\n * @param props\r\n */\r\nexport const DriverScoreProgressBarAsChart = (props: DriverScoreProgressBarAsChartProps) => {\r\n const {\r\n userDriverMetrics,\r\n driverMetrics,\r\n riskRules,\r\n } = props;\r\n\r\n const { t } = useTranslation();\r\n\r\n const totalScore = useMemo(() => {\r\n let score = 0;\r\n for (const metric of userDriverMetrics) {\r\n score += metric.currentValue;\r\n }\r\n\r\n if (userDriverMetrics.length > 0) {\r\n score = Math.round(score / userDriverMetrics.length);\r\n }\r\n\r\n return questionScoreFromNumber(score, userDriverMetrics.length === 0, riskRules);\r\n }, [userDriverMetrics, riskRules]);\r\n\r\n return (\r\n \r\n
\r\n \r\n
\r\n\r\n \r\n \r\n {\r\n driverMetrics.map(metric => {\r\n const userDriveMetric = userDriverMetrics.find(it => it.driverMetricId === metric.id);\r\n\r\n // If we have no UserDriveMetric for this metric, don't show it.\r\n if (!userDriveMetric) {\r\n return null;\r\n }\r\n\r\n // Convert into a question score.\r\n const score = questionScoreFromNumber(userDriveMetric.currentValue, false, riskRules);\r\n\r\n return (\r\n \r\n \r\n \r\n );\r\n })\r\n }\r\n \r\n \r\n
\r\n );\r\n};","import moment from \"moment\";\r\nimport { useCallback, useMemo } from \"react\";\r\nimport { ConditionalFragment } from \"react-conditionalfragment\";\r\nimport { useTranslation } from \"react-i18next\";\r\nimport { LinkContainer } from \"react-router-bootstrap\";\r\nimport { Badge, Button, ButtonGroup, Col, Collapse, ListGroup, ListGroupItem, ListGroupItemHeading, ListGroupItemText, Row } from \"reactstrap\";\r\nimport { useToggleStateArray } from \"use-toggle-state\";\r\nimport { Assessment } from \"../../../api/main/models/Assessment\";\r\nimport { AssessmentSession } from \"../../../api/main/models/AssessmentSession\";\r\nimport { AssessmentType } from \"../../../api/main/models/codeOnly/AssessmentType\";\r\nimport { DriverMetric } from \"../../../api/main/models/DriverMetric\";\r\nimport { UserAssessmentAssignment } from \"../../../api/main/models/UserAssessmentAssignment\";\r\nimport { UserDriverMetric } from \"../../../api/main/models/UserDriverMetric\";\r\nimport { RiskRules } from \"../../../services/OverallRiskService\";\r\nimport { HtmlDisplay } from \"../../../shared/htmlEditor\";\r\nimport { questionScoreFromNumber } from \"../../assessmentSessions/launch/utilities/questionScoreFromNumber\";\r\nimport { DueDateLabel } from \"../../me/DueDateLabel\";\r\nimport { useAverageScoreChartData } from \"../chartData/useAverageScoreChartData\";\r\nimport { useDriverMetricsChartData } from \"../chartData/useDriverMetricsChartData\";\r\nimport { AverageScoreRadarChart } from \"../charts/AverageScoreRadarChart\";\r\nimport { DriverMetricsRadarChart } from \"../charts/DriverMetricsRadarChart\";\r\nimport { DriverScoreProgressBarAsChart } from \"../charts/DriverScoreProgressBarAsChart\";\r\nimport { IndividualScoreProgressBar } from \"../progress/IndividualScoreProgressBar\";\r\nimport { DashboardSummary } from \"../utilities/generateDashboardSummary\";\r\nimport { getLatestSessions } from \"../utilities/getLatestSessions\";\r\nimport { useCachedDashboardSummaries } from \"../utilities/useCachedDashboardSummaries\";\r\nimport \"./userProgressDashboardTab.scss\";\r\n\r\nexport interface UserProgressDashboardTabProps {\r\n assessmentType: AssessmentType,\r\n\r\n assessments: Array,\r\n generateDashboardSummary: (\r\n sessionFilter: (session: AssessmentSession) => boolean,\r\n assignmentFilter: (assignment: UserAssessmentAssignment) => boolean,\r\n assessmentType: AssessmentType\r\n ) => DashboardSummary,\r\n\r\n assessmentSessions: Array,\r\n expandedUserAssessmentAssignments: Array,\r\n\r\n driverMetrics: Array,\r\n userDriverMetrics: Array,\r\n\r\n riskRules: RiskRules | undefined | null,\r\n isCurrentUser: boolean,\r\n}\r\n\r\n/**\r\n * Tab for the dasboard that shows under a user to show their assigned assessments/training by status.\r\n * @param props\r\n */\r\nexport const UserProgressDashboardTab = (props: UserProgressDashboardTabProps) => {\r\n const {\r\n assessments: allAssessments,\r\n assessmentType,\r\n\r\n generateDashboardSummary,\r\n\r\n assessmentSessions,\r\n expandedUserAssessmentAssignments,\r\n\r\n driverMetrics,\r\n userDriverMetrics,\r\n\r\n riskRules,\r\n isCurrentUser,\r\n } = props;\r\n\r\n const { t } = useTranslation();\r\n\r\n\r\n const assessments = useMemo(() => {\r\n return allAssessments.filter(item => item.assessmentType === assessmentType);\r\n }, [allAssessments, assessmentType]);\r\n\r\n // Method we use to filter sessions by assessment and user wherever we need it.\r\n const filterByAssessment = useCallback((assessment: { id: string }, item: { assessmentId: string | undefined | null }) => {\r\n return item.assessmentId === assessment.id;\r\n }, []);\r\n\r\n // Cache the dashboard summaries so each chart/display doesn't need to recaclulate them and they can be looked up easily by id.\r\n const getCachedDashboardSummary = useCachedDashboardSummaries(\r\n assessments,\r\n (group, assessmentType) => generateDashboardSummary(\r\n session => filterByAssessment(group, session),\r\n assignment => filterByAssessment(group, assignment),\r\n assessmentType\r\n )\r\n );\r\n\r\n // Get the latest session for each assessment.\r\n const { latestSessions, latestSessionsIncludingIncomplete } = useMemo(() => getLatestSessions(assessmentSessions ?? []), [assessmentSessions]);\r\n\r\n // Split the assessments up into groups based on the user's progress.\r\n const { notStarted, started, complete, markedSuspicious } = useMemo(() => {\r\n let notStarted: Array = [];\r\n let started: Array = [];\r\n let complete: Array = [];\r\n let markedSuspicious: Array = [];\r\n\r\n\r\n for (const assessment of assessments) {\r\n const assignment = expandedUserAssessmentAssignments.find(it => it.assessmentId === assessment.id);\r\n const session = latestSessionsIncludingIncomplete.find(it => it.assessmentId === assessment.id);\r\n\r\n // If we have no session, then check if its assigned or not.\r\n if (!session) {\r\n if (!assignment) {\r\n // User has nothing to do with this assessment, just skip it.\r\n continue;\r\n }\r\n\r\n // Add to the notStarted.\r\n notStarted.push(assessment);\r\n } else {\r\n // If its complete add it to the complete list.\r\n if (session.isFinished && !session.markedSuspicious) {\r\n complete.push(assessment);\r\n } else if (session.isFinished && session.markedSuspicious) {\r\n // If it is complete and marked suspicious we want to seperate these assessments.\r\n markedSuspicious.push(assessment);\r\n } else {\r\n // Otherwise add it to the started list.\r\n started.push(assessment);\r\n }\r\n }\r\n };\r\n\r\n return {\r\n notStarted,\r\n started,\r\n complete,\r\n markedSuspicious,\r\n };\r\n }, [assessments, latestSessionsIncludingIncomplete, expandedUserAssessmentAssignments]);\r\n\r\n // Get data for the various charts.\r\n const averageScoreChartData = useAverageScoreChartData(assessments, getCachedDashboardSummary, assessmentType);\r\n const driverMetricsChartData = useDriverMetricsChartData(driverMetrics, userDriverMetrics);\r\n\r\n // Track which histories are expanded.\r\n const [isHistoryExpandedFor, toggleHistoryExpandedFor] = useToggleStateArray([]);\r\n\r\n // Generate the display items for the passed in assignments.\r\n const generateItems = (myAssessments: Array) => {\r\n return myAssessments.map(assessment => {\r\n const latestCompleteSession = latestSessions.find(it => it.assessmentId === assessment.id);\r\n const latestSessionIncludingIncomplete = latestSessionsIncludingIncomplete.find(it => it.assessmentId === assessment.id);\r\n let assignment = expandedUserAssessmentAssignments.find(it => it.assessmentId === assessment.id && !it.subscriptionTeamId);\r\n if (!assignment) {\r\n assignment = expandedUserAssessmentAssignments.find(it => it.assessmentId === assessment.id && !!it.subscriptionTeamId);\r\n }\r\n\r\n // Get any historic completions.\r\n let allMyHistoricCompleteSessions = assessmentSessions\r\n .filter(it => it.assessmentId === assessment.id && it.isFinished)\r\n .filter(it => it.id !== latestSessionIncludingIncomplete?.id);\r\n // Flip the order.\r\n allMyHistoricCompleteSessions.sort((a, b) => {\r\n if (a.startDate === b.startDate) {\r\n return 0;\r\n } else if (a.startDate < b.startDate) {\r\n return 1;\r\n } else {\r\n return -1;\r\n }\r\n });\r\n\r\n const launchBaseRoute = assessment.assessmentType === AssessmentType.TrainingModule ? '/training' : '/assessment';\r\n\r\n return (\r\n \r\n \r\n \r\n \r\n {assessment.name}\r\n \r\n \r\n \r\n \r\n\r\n\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n\r\n \r\n
\r\n
\r\n {\r\n latestCompleteSession && latestCompleteSession?.id !== latestSessionIncludingIncomplete?.id ? (\r\n \r\n ) : latestCompleteSession ? (\r\n \r\n ) : null\r\n }\r\n
\r\n
\r\n \r\n {\r\n assessmentSessions.filter(item => !item.isFinished && item.assessmentId === assessment.id && item.id !== latestSessionIncludingIncomplete?.id).length !== 0 ? (\r\n <>\r\n {t('userProgressDashboardTab.restartCount', `This user had ${assessmentSessions.filter(item => !item.isFinished && item.assessmentId === assessment.id && item.id !== latestSessionIncludingIncomplete?.id).length} unfinished attempts before their latest attempt.`)}\r\n \r\n ) : null\r\n }\r\n \r\n
\r\n
\r\n \r\n
\r\n
\r\n \r\n
\r\n\r\n \r\n \r\n\r\n \r\n \r\n {\r\n allMyHistoricCompleteSessions.map(session => (\r\n \r\n \r\n \r\n
\r\n \r\n
\r\n\r\n \r\n \r\n \r\n \r\n \r\n \r\n\r\n \r\n
\r\n
\r\n \r\n
\r\n
\r\n \r\n
\r\n
\r\n ))\r\n }\r\n
\r\n
\r\n
\r\n
\r\n );\r\n })\r\n };\r\n\r\n return (\r\n
\r\n \r\n \r\n {/* Not started */}\r\n
\r\n \r\n \r\n
\r\n {t('userProgressDashboardTab.notStarted.heading', 'Not started')}\r\n <> \r\n \r\n {notStarted.length}\r\n \r\n
\r\n
\r\n {\r\n generateItems(notStarted)\r\n }\r\n
\r\n
\r\n\r\n {/* Started */}\r\n
\r\n \r\n \r\n
\r\n {t('userProgressDashboardTab.started.heading', 'Started')}\r\n <> \r\n \r\n {started.length}\r\n \r\n
\r\n
\r\n {\r\n generateItems(started)\r\n }\r\n
\r\n
\r\n\r\n {/* Complete */}\r\n
\r\n \r\n \r\n
\r\n {t('userProgressDashboardTab.complete.heading', 'Completed')}\r\n <> \r\n \r\n {complete.length}\r\n \r\n
\r\n
\r\n {\r\n generateItems(complete)\r\n }\r\n
\r\n
\r\n\r\n {/* Marked Suspicious */}\r\n
\r\n \r\n \r\n
\r\n {t('userProgressDashboardTab.markedSuspicious.heading', 'Marked Suspicious')}\r\n <> \r\n \r\n {markedSuspicious.length}\r\n \r\n
\r\n
\r\n {\r\n generateItems(markedSuspicious)\r\n }\r\n
\r\n
\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n
\r\n
\r\n );\r\n};","import { useCallback, useMemo } from \"react\";\r\nimport { useTranslation } from \"react-i18next\";\r\nimport { DriverMetric } from \"../../../api/main/models/DriverMetric\";\r\nimport { UserDriverMetric } from \"../../../api/main/models/UserDriverMetric\";\r\nimport { ChartData, ChartDataSeries } from \"../chartDataUtilities/ChartData\";\r\n\r\n/**\r\n * Data for a chart that shows driver metrics values (totaled).\r\n */\r\nexport function useDriverMetricsChartData(driverMetrics: Array, userDriverMetrics: Array): Array {\r\n const { t } = useTranslation();\r\n\r\n const generateSeries = useCallback((seriesName: string) => {\r\n // Generate chart data for each group.\r\n const data = driverMetrics?.map(metric => {\r\n const myUserDriverMetrics = userDriverMetrics?.filter(item => item.driverMetricId === metric.id);\r\n let totalValue = 0; // NOTE metric.startValue is no longer used.\r\n if (myUserDriverMetrics?.length > 0) {\r\n totalValue = myUserDriverMetrics.map(item => item.currentValue).reduce((previousValue, currentValue) => previousValue + currentValue, 0) / myUserDriverMetrics.length;\r\n }\r\n \r\n return {\r\n text: metric.name,\r\n value: totalValue,\r\n } as ChartData;\r\n });\r\n\r\n return {\r\n name: seriesName,\r\n data: data ?? [],\r\n } as ChartDataSeries;\r\n }, [driverMetrics, userDriverMetrics]);\r\n\r\n const ret = useMemo(() => {\r\n return [\r\n generateSeries(\r\n t('useDriverMetricsChartData.seriesName', 'Safety metrics'), \r\n ),\r\n ];\r\n }, [generateSeries, t]);\r\n\r\n return ret;\r\n}\r\n","import { useCallback, useMemo } from \"react\";\r\nimport { ConditionalFragment } from \"react-conditionalfragment\";\r\nimport { useTranslation } from \"react-i18next\";\r\nimport { Button, ButtonGroup, Col, Container, Row } from \"reactstrap\";\r\nimport { AssessmentType } from \"../../../api/main/models/codeOnly/AssessmentType\";\r\nimport { AlertOnErrors } from \"../../../shared/alertOnErrors\";\r\nimport { Background } from \"../../shared/background/Background\";\r\nimport { Banner } from \"../../shared/Banner\";\r\nimport { LoadingIndicator } from \"../../shared/LoadingIndicator\";\r\nimport { UserAssessmentAssignment } from \"../../../api/main/models/UserAssessmentAssignment\";\r\nimport { AssessmentSession } from \"../../../api/main/models/AssessmentSession\";\r\nimport { generateDashboardSummary as _generateDashboardSummary } from \"../utilities/generateDashboardSummary\";\r\nimport { useParams } from \"react-router\";\r\nimport { UserProgressDashboardTab } from \"../tabs/UserProgressDashboardTab\";\r\nimport { useAdministrationDashboardViewModel } from \"../../../api/main/dashboard/viewModels/useAdministrationDashboardViewModel\";\r\nimport { useExpandedUserAssessmentAssignments } from \"../utilities/useExpandedUserAssessmentAssignments\";\r\nimport { useActiveDashboardAssessmentType } from \"../../../globalState/activeDashboardAssessmentType/useActiveDashboardAssessmentType\";\r\nimport { DashboardBackButton } from \"../backButton/DashboardBackButton\";\r\nimport { useCurrentUserId } from \"../../../api/account\";\r\n\r\nexport interface StaffUserDashboardProps {\r\n userId?: string,\r\n}\r\n\r\n\r\n/**\r\n * Dashboard for a staff member/administrator.\r\n */\r\nexport const StaffUserDashboard = (props: StaffUserDashboardProps) => {\r\n const {\r\n userId: userIdProp,\r\n } = props;\r\n\r\n // Work out the subscription and user to show for.\r\n const { userId: userIdParam } = useParams<{ userId: string | undefined }>();\r\n const userId = userIdProp ?? userIdParam;\r\n\r\n // Get the current user, as some extra features are available on people's own dashboard.\r\n const currentUserId = useCurrentUserId();\r\n\r\n const { t } = useTranslation();\r\n\r\n const {\r\n data: {\r\n profiles: allProfiles,\r\n assessments: allAssessments,\r\n assessmentSessions: allAssmentSessions,\r\n userAssessmentAssignments: allUserAssessmentAssignments,\r\n driverMetrics,\r\n userDriverMetrics: allUserDriverMetrics,\r\n },\r\n isLoading,\r\n errors: loadErrors\r\n } = useAdministrationDashboardViewModel();\r\n\r\n const profile = useMemo(() => allProfiles?.find(it => it.userId === userId), [allProfiles, userId]);\r\n\r\n // Filter the sessions down to only this user.\r\n const assessmentSessions = useMemo(() => allAssmentSessions?.filter(item => item.userId === userId), [allAssmentSessions, userId]);\r\n const userAssessmentAssignments = useMemo(() =>\r\n allUserAssessmentAssignments\r\n ?.filter(item => {\r\n // If it is for the user's team keep it.\r\n if (!!item.subscriptionTeamId && item.subscriptionTeamId === profile?.userId) {\r\n return true;\r\n }\r\n\r\n // If it is for this user keep it.\r\n if (item.userId === userId) {\r\n return true;\r\n }\r\n\r\n // Otherwise we don't want it.\r\n return false;\r\n })\r\n , [allUserAssessmentAssignments, userId, profile]);\r\n\r\n // Filter asessments to match those used by this user in some way.\r\n const assessments = useMemo(() =>\r\n allAssessments\r\n ?.filter(assessment =>\r\n !!assessmentSessions?.find(it => it.assessmentId === assessment.id)\r\n || !!userAssessmentAssignments?.find(it => it.assessmentId === assessment.id)\r\n )\r\n , [allAssessments, userAssessmentAssignments, assessmentSessions]);\r\n\r\n // Expand the UserAssessmentAssignments so we can work with them easier.\r\n const expandedUserAssessmentAssignments = useExpandedUserAssessmentAssignments(userAssessmentAssignments ?? [], profile ? [profile] : []);\r\n\r\n // Filter the userDriverMetrics down to only this user.\r\n const userDriverMetrics = useMemo(() => allUserDriverMetrics?.filter(item => item.userId === profile?.userId), [allUserDriverMetrics, profile]);\r\n\r\n // Allow the generation of dashboard summary data.\r\n const generateDashboardSummary = useCallback((\r\n sessionFilter: (session: AssessmentSession) => boolean,\r\n assignmentFilter: (assignment: UserAssessmentAssignment) => boolean,\r\n assessmentType: AssessmentType) => {\r\n // Filter by the passed in fitler.\r\n let mySessions = assessmentSessions?.filter(sessionFilter) ?? [];\r\n let myAssignments = expandedUserAssessmentAssignments?.filter(assignmentFilter) ?? [];\r\n\r\n // Filter the driver metrics to contain only users that have assessments or assignments.\r\n const myUserDriverMetrics = allUserDriverMetrics?.filter(\r\n udm => !!mySessions.find(it => it.userId === udm.userId) || !!myAssignments.find(it => it.userId === udm.userId)\r\n ) ?? [];\r\n\r\n // Generate the summary data.\r\n const ret = _generateDashboardSummary(mySessions, assessments ?? [], profile ? [profile] : [], myAssignments, myUserDriverMetrics ?? [], null);\r\n return ret;\r\n }, [assessmentSessions, assessments, profile, expandedUserAssessmentAssignments, allUserDriverMetrics]);\r\n\r\n\r\n // Track the active assessment type.\r\n const [activeAssessmentType, setActiveAssessmentType] = useActiveDashboardAssessmentType();\r\n\r\n return (\r\n \r\n \r\n \r\n \r\n

\r\n \r\n {\r\n t('staffUserDashboard.heading', '{{firstName}} {{lastName}} dashboard', profile)\r\n }\r\n

\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n
\r\n
\r\n \r\n \r\n\r\n \r\n \r\n
\r\n );\r\n};\r\n","import * as React from 'react';\r\nimport { useLazyQuery } from \"@apollo/react-hooks\";\r\nimport gql from \"graphql-tag\";\r\nimport { AsyncLoadResult, AsyncLoadOptions } from '../../../../shared/abstractStore';\r\nimport { subscriptionDashboardViewModelQuery, subscriptionDashboardViewModelQueryVariables } from '../../generated/subscriptionDashboardViewModelQuery';\r\nimport { mainApiConfig } from '../../../../configure/mainApiConfig';\r\nimport { Guid } from 'guid-string';\r\nimport { subscriptionFieldsFragment } from '../../models/Subscription';\r\nimport { subscriptionTeamFieldsFragment } from '../../models/SubscriptionTeam';\r\nimport { profileFieldsFragment } from '../../models/Profile';\r\nimport { subscriptionAssessmentFieldsFragment } from '../../models/SubscriptionAssessment';\r\nimport { assessmentFieldsFragment } from '../../models/Assessment';\r\nimport { assessmentSessionFieldsFragment } from '../../models/AssessmentSession';\r\nimport { userAssessmentAssignmentFieldsFragment } from '../../models/UserAssessmentAssignment';\r\nimport { userDriverMetricFieldsFragment } from '../../models/UserDriverMetric';\r\nimport { driverMetricFieldsFragment } from '../../models/DriverMetric';\r\n\r\n/**\r\n * View model for SubscriptionDashboard to loads all the right related data.\r\n * @param options\r\n */\r\nexport function useSubscriptionDashboardViewModel(id: string | undefined | null, options: AsyncLoadOptions = {}): AsyncLoadResult {\r\n // Query the data we need form the api.\r\n const [load, { data, loading, error, refetch }] = useLazyQuery(\r\n gql`\r\n query subscriptionDashboardViewModelQuery ($id: ID!) {\r\n model: subscription(id: $id) {\r\n ...subscriptionFields\r\n }\r\n\r\n subscriptionTeams(subscriptionId: $id) {\r\n ...subscriptionTeamFields\r\n }\r\n\r\n profiles(subscriptionId: $id) {\r\n ...profileFields\r\n }\r\n\r\n subscriptionAssessments (subscriptionId: $id) {\r\n ...subscriptionAssessmentFields\r\n }\r\n\r\n assessments {\r\n ...assessmentFields\r\n }\r\n\r\n assessmentSessions (subscriptionId: $id) {\r\n ...assessmentSessionFields\r\n }\r\n\r\n userAssessmentAssignments (subscriptionId: $id) {\r\n ...userAssessmentAssignmentFields\r\n }\r\n\r\n userDriverMetrics (subscriptionId: $id) {\r\n ...userDriverMetricFields\r\n }\r\n\r\n driverMetrics {\r\n ...driverMetricFields\r\n }\r\n }\r\n\r\n ${subscriptionFieldsFragment}\r\n ${subscriptionTeamFieldsFragment}\r\n ${profileFieldsFragment}\r\n ${subscriptionAssessmentFieldsFragment}\r\n ${assessmentFieldsFragment}\r\n ${assessmentSessionFieldsFragment}\r\n ${userAssessmentAssignmentFieldsFragment}\r\n ${userDriverMetricFieldsFragment}\r\n ${driverMetricFieldsFragment}\r\n `,\r\n {\r\n variables: {\r\n id: id ?? Guid.empty\r\n },\r\n fetchPolicy: options.fetchPolicy ?? mainApiConfig.defaultFetchPolicy,\r\n pollInterval: options.pollInterval,\r\n onCompleted: (data) => {\r\n if (options.onCompleted) {\r\n options.onCompleted(data);\r\n }\r\n }\r\n }\r\n );\r\n\r\n // Run the query (unless we are being lazy).\r\n React.useEffect(() => {\r\n if (!options.lazy) {\r\n load();\r\n }\r\n }, [options.lazy, load])\r\n\r\n // Return the results.\r\n const refresh = React.useCallback(async () => { !refetch ? await load() : await refetch(); }, [refetch, load]);\r\n return React.useMemo(() => ({\r\n data: data ?? ({} as any),\r\n refresh: refresh,\r\n isLoading: loading,\r\n errors: error\r\n }), [data, refresh, loading, error]);\r\n}","import { useCallback, useMemo } from \"react\";\r\nimport { ConditionalFragment } from \"react-conditionalfragment\";\r\nimport { useTranslation } from \"react-i18next\";\r\nimport { Button, ButtonGroup, Col, Container, Row } from \"reactstrap\";\r\nimport { AssessmentType } from \"../../../api/main/models/codeOnly/AssessmentType\";\r\nimport { useSubscriptionDashboardViewModel } from \"../../../api/main/dashboard/viewModels/useSubscriptionDashboardViewModel\";\r\nimport { AlertOnErrors } from \"../../../shared/alertOnErrors\";\r\nimport { Background } from \"../../shared/background/Background\";\r\nimport { Banner } from \"../../shared/Banner\";\r\nimport { LoadingIndicator } from \"../../shared/LoadingIndicator\";\r\nimport { UserAssessmentAssignment } from \"../../../api/main/models/UserAssessmentAssignment\";\r\nimport { AssessmentSession } from \"../../../api/main/models/AssessmentSession\";\r\nimport { generateDashboardSummary as _generateDashboardSummary } from \"../utilities/generateDashboardSummary\";\r\nimport { useParams } from \"react-router\";\r\nimport { useCurrentUserOrEmulatedSubscriptionId } from \"../../../globalState/subscriptions/useCurrentUserOrEmulatedSubscriptionId\";\r\nimport { UserProgressDashboardTab } from \"../tabs/UserProgressDashboardTab\";\r\nimport { useExpandedUserAssessmentAssignments } from \"../utilities/useExpandedUserAssessmentAssignments\";\r\nimport { useActiveDashboardAssessmentType } from \"../../../globalState/activeDashboardAssessmentType/useActiveDashboardAssessmentType\";\r\nimport { DashboardBackButton } from \"../backButton/DashboardBackButton\";\r\nimport { useCurrentUserId } from \"../../../api/account\";\r\n\r\nexport interface SubscriptionUserDashboardProps {\r\n userId?: string,\r\n}\r\n\r\n/**\r\n * Dashboard for a user subscription.\r\n */\r\nexport const SubscriptionUserDashboard = (props: SubscriptionUserDashboardProps) => {\r\n const {\r\n userId: userIdProp,\r\n } = props;\r\n\r\n // Work out the subscription and user to show for.\r\n const { subscriptionId: subscriptionIdParam, userId: userIdParam } = useParams<{ subscriptionId: string | undefined, userId: string | undefined }>();\r\n const mySubscriptionId = useCurrentUserOrEmulatedSubscriptionId();\r\n const subscriptionId = subscriptionIdParam ?? mySubscriptionId;\r\n\r\n const userId = userIdProp ?? userIdParam;\r\n\r\n // Get the current user, as some extra features are available on people's own dashboard.\r\n const currentUserId = useCurrentUserId();\r\n\r\n const { t } = useTranslation();\r\n\r\n const {\r\n data: {\r\n profiles: allProfiles,\r\n subscriptionAssessments,\r\n assessments: allAssessments,\r\n assessmentSessions: allAssmentSessions,\r\n userAssessmentAssignments: allUserAssessmentAssignments,\r\n driverMetrics,\r\n userDriverMetrics: allUserDriverMetrics,\r\n model: subscription,\r\n },\r\n isLoading,\r\n errors: loadErrors\r\n } = useSubscriptionDashboardViewModel(subscriptionId);\r\n\r\n const profile = useMemo(() => allProfiles?.find(it => it.userId === userId), [allProfiles, userId]);\r\n\r\n // Filter the profiles down to only this user.\r\n const assessmentSessions = useMemo(() => allAssmentSessions?.filter(item => item.userId === userId), [allAssmentSessions, userId]);\r\n const userAssessmentAssignments = useMemo(() =>\r\n allUserAssessmentAssignments\r\n ?.filter(item => {\r\n // If it is for the user's team keep it.\r\n if (!!item.subscriptionTeamId && item.subscriptionTeamId === profile?.subscriptionTeamId) {\r\n return true;\r\n }\r\n\r\n // If it is for this user keep it.\r\n if (item.userId === userId) {\r\n return true;\r\n }\r\n\r\n // Otherwise we don't want it.\r\n return false;\r\n })\r\n , [allUserAssessmentAssignments, userId, profile]);\r\n\r\n // The subscription is only licensed for some assessments, so remove any that we're not licensed for now\r\n // and also remove any that have not either been used or assigned to this team.\r\n const assessments = useMemo(() =>\r\n allAssessments\r\n ?.filter(assessment => !!subscriptionAssessments?.find(it => it.assessmentId === assessment.id))\r\n ?.filter(assessment =>\r\n !!assessmentSessions?.find(it => it.assessmentId === assessment.id)\r\n || !!userAssessmentAssignments?.find(it => it.assessmentId === assessment.id)\r\n )\r\n , [allAssessments, subscriptionAssessments, userAssessmentAssignments, assessmentSessions]);\r\n\r\n // Expand the UserAssessmentAssignments so we can work with them easier.\r\n const expandedUserAssessmentAssignments = useExpandedUserAssessmentAssignments(userAssessmentAssignments ?? [], profile ? [profile] : []);\r\n\r\n // Allow the generation of dashboard summary data.\r\n const generateDashboardSummary = useCallback((\r\n sessionFilter: (session: AssessmentSession) => boolean,\r\n assignmentFilter: (assignment: UserAssessmentAssignment) => boolean,\r\n assessmentType: AssessmentType) => {\r\n // Filter by the passed in fitler.\r\n let mySessions = assessmentSessions?.filter(sessionFilter) ?? [];\r\n let myAssignments = expandedUserAssessmentAssignments?.filter(assignmentFilter) ?? [];\r\n\r\n // Filter the driver metrics to contain only users that have assessments or assignments.\r\n const myUserDriverMetrics = allUserDriverMetrics?.filter(\r\n udm => !!mySessions.find(it => it.userId === udm.userId) || !!myAssignments.find(it => it.userId === udm.userId)\r\n ) ?? [];\r\n\r\n // Generate the summary data.\r\n const ret = _generateDashboardSummary(mySessions, assessments ?? [], profile ? [profile] : [], myAssignments, myUserDriverMetrics ?? [], subscription);\r\n return ret;\r\n }, [assessmentSessions, assessments, profile, expandedUserAssessmentAssignments, subscription, allUserDriverMetrics]);\r\n\r\n\r\n // Filter the userDriverMetrics down to only this user.\r\n const userDriverMetrics = useMemo(() => allUserDriverMetrics?.filter(item => item.userId === profile?.userId), [allUserDriverMetrics, profile]);\r\n\r\n // Track the active assessment type.\r\n const [activeAssessmentType, setActiveAssessmentType] = useActiveDashboardAssessmentType();\r\n\r\n return (\r\n \r\n \r\n \r\n \r\n

\r\n \r\n {\r\n t('subscriptionUserDashboard.heading', '{{firstName}} {{lastName}} dashboard', profile)\r\n }\r\n

\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n
\r\n
\r\n \r\n \r\n\r\n \r\n \r\n
\r\n );\r\n};\r\n","import { useCurrentUserProfile } from \"../../../api/main/profiles/useCurrentUserProfile\";\r\nimport { LoadingIndicator } from \"../../shared/LoadingIndicator\";\r\nimport { StaffUserDashboard } from \"../administrationDashboard/StaffUserDashboard\";\r\nimport { SubscriptionUserDashboard } from \"../subscriptionDashboard/SubscriptionUserDashboard\";\r\n\r\n/**\r\n * Dashboard for the current user.\r\n */\r\nexport const MyDashboard = () => {\r\n const { data: { model: currentProfile } } = useCurrentUserProfile();\r\n\r\n if (!currentProfile) {\r\n return ();\r\n }\r\n\r\n if (!currentProfile?.subscriptionId) {\r\n return (\r\n \r\n );\r\n }\r\n\r\n return (\r\n \r\n );\r\n};","import { useCallback, useMemo, useState } from \"react\";\r\nimport { ConditionalFragment } from \"react-conditionalfragment\";\r\nimport { Form, FormGroup, Label, Input } from \"reactstrap\";\r\nimport { Assessment } from \"../../../api/main/models/Assessment\";\r\nimport { AssessmentSession } from \"../../../api/main/models/AssessmentSession\";\r\nimport { Background } from \"../../shared/background/Background\";\r\nimport { useTranslation } from 'react-i18next';\r\nimport { FontAwesomeIcon } from \"@fortawesome/react-fontawesome\";\r\nimport { MainContainer } from \"../../shared/MainContainer\";\r\nimport { TwoValueSwitch } from \"../../shared/TwoValueSwitch\";\r\nimport { SubscriptionTeam } from \"../../../api/main/models/SubscriptionTeam\";\r\n\r\nexport interface ExportAssesmentResultsProps {\r\n assessments: Array,\r\n assessmentSessions: Array,\r\n subscriptionId: string\r\n subscriptionTeams: Array,\r\n}\r\n\r\nexport const ExportAssessmentResults = (props: ExportAssesmentResultsProps) => {\r\n const {\r\n assessments,\r\n assessmentSessions,\r\n subscriptionId,\r\n subscriptionTeams = [],\r\n } = props\r\n\r\n const { t } = useTranslation();\r\n const assessmentsWithSessions = assessments.filter(item => assessmentSessions.find(it => it.assessmentId === item.id));\r\n\r\n const [assessmentToUse, setAssessmentToUse] = useState();\r\n const [filterByTeam, setFilterByTeam] = useState();\r\n const [subscriptionTeamToUse, setSubscriptionTeamToUse] = useState();\r\n\r\n const [isDetailed, setisDetailed] = useState();\r\n const [includeDeviceMetrics, setIncludeDeviceMetrics] = useState(false);\r\n\r\n const pickAssessment = useCallback((id: string) => {\r\n if (id !== \"\") {\r\n const pickedAssessment = assessmentsWithSessions.find(item => item.id === id);\r\n setAssessmentToUse(pickedAssessment);\r\n }\r\n }, [setAssessmentToUse, assessmentsWithSessions]);\r\n\r\n const exportToUse = useMemo(() => {\r\n if (isDetailed) {\r\n return `/api/export/DetailedAssessmentResults?subscriptionId=${encodeURIComponent(subscriptionId ?? '')}&assessmentId=${encodeURIComponent(assessmentToUse?.id ?? '')}&subscriptionTeamId=${encodeURIComponent(subscriptionTeamToUse?.id ?? '')}&includeDeviceMetrics=${encodeURIComponent(includeDeviceMetrics ?? false)}`\r\n } else {\r\n return `/api/export/AssessmentResults?subscriptionId=${encodeURIComponent(subscriptionId ?? '')}&assessmentId=${encodeURIComponent(assessmentToUse?.id ?? '')}&subscriptionTeamId=${encodeURIComponent(subscriptionTeamToUse?.id ?? '')}&includeDeviceMetrics=${encodeURIComponent(includeDeviceMetrics ?? false)}`\r\n }\r\n }, [isDetailed, subscriptionId, assessmentToUse, subscriptionTeamToUse, includeDeviceMetrics]);\r\n\r\n const pickSubscriptionTeam = useCallback((id:string) => {\r\n if (id !== \"\") {\r\n const pickedSubscriptionTeam = subscriptionTeams.find(item => item.id === id);\r\n setSubscriptionTeamToUse(pickedSubscriptionTeam)\r\n }\r\n }, [subscriptionTeams, setSubscriptionTeamToUse]);\r\n \r\n return (\r\n \r\n \r\n
\r\n \r\n \r\n pickAssessment(e.currentTarget.value)}>\r\n \r\n {\r\n assessmentsWithSessions.map(item => (\r\n \r\n ))\r\n }\r\n \r\n \r\n \r\n \r\n \r\n\r\n {\r\n // Toggle the flag\r\n setIncludeDeviceMetrics(checked);\r\n }}\r\n />\r\n \r\n \r\n \r\n\r\n {\r\n // Toggle the flag\r\n setisDetailed(checked)\r\n }}\r\n />\r\n \r\n \r\n \r\n {\r\n // Toggle the flag\r\n setFilterByTeam(checked);\r\n if (!checked) {\r\n setSubscriptionTeamToUse(undefined);\r\n }\r\n }}\r\n />\r\n \r\n \r\n \r\n \r\n pickSubscriptionTeam(e.currentTarget.value)}>\r\n \r\n {\r\n subscriptionTeams.map(item => (\r\n \r\n ))\r\n }\r\n \r\n \r\n \r\n\r\n \r\n <> {t('exportAssessmentResults.export', 'Export to Excel')} \r\n \r\n\r\n \r\n
\r\n
\r\n
\r\n );\r\n};","import { useCallback, useMemo } from \"react\";\r\nimport { ConditionalFragment } from \"react-conditionalfragment\";\r\nimport { useTranslation } from \"react-i18next\";\r\nimport { Button, ButtonGroup, Col, Container, NavItem, NavLink, Row } from \"reactstrap\";\r\nimport { AssessmentType } from \"../../../api/main/models/codeOnly/AssessmentType\";\r\nimport { useSubscriptionDashboardViewModel } from \"../../../api/main/dashboard/viewModels/useSubscriptionDashboardViewModel\";\r\nimport { AlertOnErrors } from \"../../../shared/alertOnErrors\";\r\nimport { Background } from \"../../shared/background/Background\";\r\nimport { Banner } from \"../../shared/Banner\";\r\nimport { PillsNavBar } from \"../../shared/pillsNavBar/PillsNavBar\";\r\nimport { LoadingIndicator } from \"../../shared/LoadingIndicator\";\r\nimport { UserAssessmentAssignment } from \"../../../api/main/models/UserAssessmentAssignment\";\r\nimport { AssessmentSession } from \"../../../api/main/models/AssessmentSession\";\r\nimport { generateDashboardSummary as _generateDashboardSummary } from \"../utilities/generateDashboardSummary\";\r\nimport { SubscriptionTeamsDashboardTab } from \"../tabs/SubscriptionTeamsDashboardTab\";\r\nimport { SubscriptionUsersDashboardTab } from \"../tabs/SubscriptionUsersDashboardTab\";\r\nimport { AssessmentsDashboardTab } from \"../tabs/AssessmentsDashboardTab\";\r\nimport { TrainingDashboardTab } from \"../tabs/TrainingDashboardTab\";\r\nimport { useParams } from \"react-router\";\r\nimport { useCurrentUserOrEmulatedSubscriptionId } from \"../../../globalState/subscriptions/useCurrentUserOrEmulatedSubscriptionId\";\r\nimport { useExpandedUserAssessmentAssignments } from \"../utilities/useExpandedUserAssessmentAssignments\";\r\nimport { useActiveDashboardAssessmentType } from \"../../../globalState/activeDashboardAssessmentType/useActiveDashboardAssessmentType\";\r\nimport { useActiveDashboardTab } from \"../../../globalState/activeDashboardTab/useActiveDashboardTab\";\r\nimport { DashboardBackButton } from \"../backButton/DashboardBackButton\";\r\nimport { FontAwesomeIcon } from \"@fortawesome/react-fontawesome\";\r\nimport { ExportAssessmentResults } from \"../tabs/ExportAssessmentResults\";\r\nimport { RiskRules } from \"../../../services/OverallRiskService\";\r\nimport { SubscriptionType } from \"../../../api/main/models/codeOnly/SubscriptionType\";\r\n\r\nexport type SubscriptionDashboardTabs = 'teams' | 'people' | 'assessments' | 'training' | 'export';\r\n\r\n/**\r\n * Dashboard for a subscription.\r\n */\r\nexport const SubscriptionDashboard = () => {\r\n // Work out the subscription to show for.\r\n const { subscriptionId: subscriptionIdParam } = useParams<{ subscriptionId: string | undefined; }>();\r\n const mySubscriptionId = useCurrentUserOrEmulatedSubscriptionId();\r\n const subscriptionId = subscriptionIdParam ?? mySubscriptionId;\r\n\r\n const { t } = useTranslation();\r\n\r\n const {\r\n data: {\r\n model: subscription,\r\n subscriptionTeams,\r\n profiles,\r\n subscriptionAssessments,\r\n assessments: allAssessments,\r\n assessmentSessions,\r\n userAssessmentAssignments,\r\n userDriverMetrics: allUserDriverMetrics,\r\n },\r\n isLoading,\r\n errors: loadErrors\r\n } = useSubscriptionDashboardViewModel(subscriptionId);\r\n\r\n // The subscription is only licensed for some assessments, so remove any that we're not licensed for now.\r\n const assessments = useMemo(() =>\r\n allAssessments?.filter(assessment => !!subscriptionAssessments?.find(it => it.assessmentId === assessment.id))\r\n , [allAssessments, subscriptionAssessments]);\r\n\r\n // Expand the UserAssessmentAssignments so we can work with them easier.\r\n const expandedUserAssessmentAssignments = useExpandedUserAssessmentAssignments(userAssessmentAssignments, profiles);\r\n\r\n // Allow the generation of dashboard summary data.\r\n const generateDashboardSummary = useCallback((\r\n sessionFilter: (session: AssessmentSession) => boolean,\r\n assignmentFilter: (assignment: UserAssessmentAssignment) => boolean,\r\n assessmentType: AssessmentType,\r\n riskRule: RiskRules | undefined | null = subscription) => {\r\n // Filter by the passed in fitler.\r\n let mySessions = assessmentSessions?.filter(sessionFilter) ?? [];\r\n let myAssignments = expandedUserAssessmentAssignments?.filter(assignmentFilter) ?? [];\r\n\r\n // Filter by the passed in type.\r\n mySessions = mySessions.filter(session => {\r\n const assessment = assessments?.find(it => it.id === session.assessmentId);\r\n if (!assessment) {\r\n return false;\r\n }\r\n\r\n return assessment.assessmentType === assessmentType;\r\n });\r\n\r\n myAssignments = myAssignments.filter(session => {\r\n const assessment = assessments?.find(it => it.id === session.assessmentId);\r\n if (!assessment) {\r\n return false;\r\n }\r\n\r\n return assessment.assessmentType === assessmentType;\r\n });\r\n\r\n // Filter the driver metrics to contain only users that have assessments or assignments.\r\n const myUserDriverMetrics = allUserDriverMetrics?.filter(\r\n udm => !!mySessions.find(it => it.userId === udm.userId) || !!myAssignments.find(it => it.userId === udm.userId)\r\n ) ?? [];\r\n\r\n // Generate the summary data.\r\n const ret = _generateDashboardSummary(mySessions, assessments ?? [], profiles ?? [], myAssignments, myUserDriverMetrics ?? [], riskRule);\r\n return ret;\r\n }, [assessmentSessions, assessments, profiles, expandedUserAssessmentAssignments, subscription, allUserDriverMetrics]);\r\n\r\n\r\n // Track the active tab.\r\n const [activeTab, setActiveTab] = useActiveDashboardTab('subscriptionDashboard', 'people');\r\n\r\n // Track the active assessment type.\r\n const [activeAssessmentType, setActiveAssessmentType] = useActiveDashboardAssessmentType();\r\n const hideAssessmentTypeToggle = activeTab === 'assessments' || activeTab === 'training' || activeTab === 'export';\r\n\r\n return (\r\n \r\n \r\n \r\n \r\n

\r\n \r\n {\r\n // If we are showing for our own (or emulated) subscription just show \"Dashboard\" as the name.\r\n !!subscriptionIdParam ? t('subscriptionDashboard.heading.withSubscriptionName', '{{name}} dashboard', { name: subscription?.companyName })\r\n : t('subscriptionDashboard.heading.default', 'Dashboard')\r\n }\r\n

\r\n \r\n \r\n \r\n \r\n setActiveTab('people')}>\r\n \r\n <> \r\n {subscription?.subscriptionType === SubscriptionType.Study ? (\r\n t('subscriptionDashboard.tabs.people', 'Participants')\r\n ) : (\r\n t('subscriptionDashboard.tabs.people', 'People')\r\n )}\r\n \r\n \r\n \r\n \r\n setActiveTab('teams')}>\r\n \r\n <> \r\n {t('subscriptionDashboard.tabs.teams', 'Teams')}\r\n \r\n \r\n \r\n \r\n setActiveTab('assessments')}>\r\n \r\n <> \r\n {t('subscriptionDashboard.tabs.assessments', 'Assessments')}\r\n \r\n \r\n \r\n \r\n setActiveTab('training')}>\r\n \r\n <> \r\n {t('subscriptionDashboard.tabs.training', 'Training')}\r\n \r\n \r\n \r\n \r\n setActiveTab('export')}>\r\n \r\n <> \r\n {t('subscriptionDashboard.export', 'Export results to Excel')}\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n\r\n \r\n \r\n \r\n <> {t('usersListBase.export', 'Export to Excel')} \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n
\r\n\r\n \r\n \r\n \r\n \r\n
\r\n \r\n \r\n\r\n\r\n \r\n \r\n \r\n\r\n \r\n \r\n \r\n\r\n \r\n \r\n \r\n\r\n \r\n \r\n \r\n\r\n \r\n \r\n \r\n \r\n
\r\n );\r\n};\r\n","import { useCallback, useMemo } from \"react\";\r\nimport { ConditionalFragment } from \"react-conditionalfragment\";\r\nimport { useTranslation } from \"react-i18next\";\r\nimport { Col, Container, Row } from \"reactstrap\";\r\nimport { AssessmentType } from \"../../../api/main/models/codeOnly/AssessmentType\";\r\nimport { AlertOnErrors } from \"../../../shared/alertOnErrors\";\r\nimport { Background } from \"../../shared/background/Background\";\r\nimport { Banner } from \"../../shared/Banner\";\r\nimport { LoadingIndicator } from \"../../shared/LoadingIndicator\";\r\nimport { UserAssessmentAssignment } from \"../../../api/main/models/UserAssessmentAssignment\";\r\nimport { AssessmentSession } from \"../../../api/main/models/AssessmentSession\";\r\nimport { generateDashboardSummary as _generateDashboardSummary } from \"../utilities/generateDashboardSummary\";\r\nimport { useParams } from \"react-router\";\r\nimport { useSubscriptionDashboardViewModel } from \"../../../api/main/dashboard/viewModels/useSubscriptionDashboardViewModel\";\r\nimport { useExpandedUserAssessmentAssignments } from \"../utilities/useExpandedUserAssessmentAssignments\";\r\nimport { AssessmentProgressDashboardTab } from \"../tabs/AssessmentProgressDashboardTab\";\r\nimport { useCurrentUserOrEmulatedSubscriptionId } from \"../../../globalState/subscriptions/useCurrentUserOrEmulatedSubscriptionId\";\r\nimport { DashboardBackButton } from \"../backButton/DashboardBackButton\";\r\n\r\n/**\r\n * Dashboard for assessment via the subscription dashboard data.\r\n */\r\nexport const SubscriptionAssessmentDashboard = () => {\r\n // Work out the subscription and user to show for.\r\n const { subscriptionId: subscriptionIdParam, assessmentId } = useParams<{ subscriptionId: string | undefined, assessmentId: string }>();\r\n\r\n // Work out the subscription to show for.\r\n const mySubscriptionId = useCurrentUserOrEmulatedSubscriptionId();\r\n const subscriptionId = subscriptionIdParam ?? mySubscriptionId;\r\n\r\n const { t } = useTranslation();\r\n\r\n const {\r\n data: {\r\n subscriptionTeams,\r\n profiles: allProfiles,\r\n assessments: allAssessments,\r\n assessmentSessions: allAssmentSessions,\r\n userAssessmentAssignments: allUserAssessmentAssignments,\r\n model: subscription,\r\n userDriverMetrics: allUserDriverMetrics,\r\n },\r\n isLoading,\r\n errors: loadErrors\r\n } = useSubscriptionDashboardViewModel(subscriptionId);\r\n\r\n const assessment = useMemo(() => allAssessments?.find(it => it.id === assessmentId), [allAssessments, assessmentId]);\r\n\r\n // Filter the profiles down to only this user.\r\n const assessmentSessions = useMemo(() => allAssmentSessions?.filter(item => item.assessmentId === assessmentId), [allAssmentSessions, assessmentId]);\r\n const userAssessmentAssignments = useMemo(() =>\r\n allUserAssessmentAssignments\r\n ?.filter(item => item.assessmentId === assessmentId)\r\n , [allUserAssessmentAssignments, assessmentId]);\r\n\r\n // Eemove any profiles that have not either been used or assigned to this team.\r\n const profiles = useMemo(() =>\r\n allProfiles\r\n ?.filter(profile =>\r\n !!assessmentSessions?.find(it => it.userId === profile.userId)\r\n || !!userAssessmentAssignments?.find(it => it.userId === profile.userId)\r\n || !!userAssessmentAssignments?.find(it => !!it.subscriptionTeamId && it.subscriptionTeamId === profile.subscriptionTeamId)\r\n )\r\n , [allProfiles, userAssessmentAssignments, assessmentSessions]);\r\n\r\n // Expand the UserAssessmentAssignments so we can work with them easier.\r\n const expandedUserAssessmentAssignments = useExpandedUserAssessmentAssignments(userAssessmentAssignments, profiles);\r\n\r\n // Allow the generation of dashboard summary data.\r\n const generateDashboardSummary = useCallback((\r\n sessionFilter: (session: AssessmentSession) => boolean,\r\n assignmentFilter: (assignment: UserAssessmentAssignment) => boolean,\r\n assessmentType: AssessmentType) => {\r\n // Filter by the passed in fitler.\r\n let mySessions = assessmentSessions?.filter(sessionFilter) ?? [];\r\n let myAssignments = expandedUserAssessmentAssignments?.filter(assignmentFilter) ?? [];\r\n\r\n // Filter the driver metrics to contain only users that have assessments or assignments.\r\n const myUserDriverMetrics = allUserDriverMetrics?.filter(\r\n udm => !!mySessions.find(it => it.userId === udm.userId) || !!myAssignments.find(it => it.userId === udm.userId)\r\n ) ?? [];\r\n\r\n // Generate the summary data.\r\n const ret = _generateDashboardSummary(mySessions, assessment ? [assessment] : [], profiles ?? [], myAssignments, myUserDriverMetrics ?? [], subscription);\r\n return ret;\r\n }, [assessmentSessions, assessment, profiles, expandedUserAssessmentAssignments, subscription, allUserDriverMetrics]);\r\n\r\n // Track the active assessment type.\r\n const activeAssessmentType = assessment?.assessmentType as AssessmentType ?? AssessmentType.Assessment;\r\n\r\n return (\r\n \r\n \r\n \r\n \r\n

\r\n \r\n {\r\n t('subscriptionAssessmentDashboard.heading', '{{name}} dashboard', { name: assessment?.name })\r\n }\r\n

\r\n \r\n \r\n \r\n \r\n \r\n \r\n
\r\n
\r\n \r\n \r\n\r\n \r\n \r\n
\r\n );\r\n};\r\n","import { useCallback, useMemo } from \"react\";\r\nimport { ConditionalFragment } from \"react-conditionalfragment\";\r\nimport { useTranslation } from \"react-i18next\";\r\nimport { Button, ButtonGroup, Col, Container, NavItem, NavLink, Row } from \"reactstrap\";\r\nimport { AssessmentType } from \"../../../api/main/models/codeOnly/AssessmentType\";\r\nimport { useSubscriptionDashboardViewModel } from \"../../../api/main/dashboard/viewModels/useSubscriptionDashboardViewModel\";\r\nimport { AlertOnErrors } from \"../../../shared/alertOnErrors\";\r\nimport { Background } from \"../../shared/background/Background\";\r\nimport { Banner } from \"../../shared/Banner\";\r\nimport { PillsNavBar } from \"../../shared/pillsNavBar/PillsNavBar\";\r\nimport { LoadingIndicator } from \"../../shared/LoadingIndicator\";\r\nimport { UserAssessmentAssignment } from \"../../../api/main/models/UserAssessmentAssignment\";\r\nimport { AssessmentSession } from \"../../../api/main/models/AssessmentSession\";\r\nimport { generateDashboardSummary as _generateDashboardSummary } from \"../utilities/generateDashboardSummary\";\r\nimport { SubscriptionUsersDashboardTab } from \"../tabs/SubscriptionUsersDashboardTab\";\r\nimport { AssessmentsDashboardTab } from \"../tabs/AssessmentsDashboardTab\";\r\nimport { TrainingDashboardTab } from \"../tabs/TrainingDashboardTab\";\r\nimport { useParams } from \"react-router\";\r\nimport { useCurrentUserOrEmulatedSubscriptionId } from \"../../../globalState/subscriptions/useCurrentUserOrEmulatedSubscriptionId\";\r\nimport { useExpandedUserAssessmentAssignments } from \"../utilities/useExpandedUserAssessmentAssignments\";\r\nimport { useActiveDashboardAssessmentType } from \"../../../globalState/activeDashboardAssessmentType/useActiveDashboardAssessmentType\";\r\nimport { useActiveDashboardTab } from \"../../../globalState/activeDashboardTab/useActiveDashboardTab\";\r\nimport { DashboardBackButton } from \"../backButton/DashboardBackButton\";\r\nimport { FontAwesomeIcon } from \"@fortawesome/react-fontawesome\";\r\n\r\nexport type SubscriptionTeamDashboardTabs = 'people' | 'assessments' | 'training';\r\n\r\n/**\r\n * Dashboard for a subscription.\r\n */\r\nexport const SubscriptionTeamDashboard = () => {\r\n // Work out the subscription to show for.\r\n const { subscriptionId: subscriptionIdParam, subscriptionTeamId } = useParams<{ subscriptionId: string | undefined, subscriptionTeamId: string }>();\r\n const mySubscriptionId = useCurrentUserOrEmulatedSubscriptionId();\r\n const subscriptionId = subscriptionIdParam ?? mySubscriptionId;\r\n\r\n const { t } = useTranslation();\r\n\r\n const {\r\n data: {\r\n subscriptionTeams: allSubscriptionTeams,\r\n profiles: allProfiles,\r\n subscriptionAssessments,\r\n assessments: allAssessments,\r\n assessmentSessions: allAssmentSessions,\r\n userAssessmentAssignments: allUserAssessmentAssignments,\r\n model: subscription,\r\n userDriverMetrics: allUserDriverMetrics,\r\n },\r\n isLoading,\r\n errors: loadErrors\r\n } = useSubscriptionDashboardViewModel(subscriptionId);\r\n\r\n const subscriptionTeam = useMemo(() => allSubscriptionTeams?.find(it => it.id === subscriptionTeamId), [allSubscriptionTeams, subscriptionTeamId]);\r\n\r\n // Filter the profiles down to only this team.\r\n const profiles = useMemo(() => allProfiles?.filter(item => item.subscriptionTeamId === subscriptionTeamId), [allProfiles, subscriptionTeamId]);\r\n const assessmentSessions = useMemo(() => allAssmentSessions?.filter(item => !!profiles?.find(it => it.userId === item.userId)), [allAssmentSessions, profiles]);\r\n const userAssessmentAssignments = useMemo(() =>\r\n allUserAssessmentAssignments\r\n ?.filter(item => {\r\n // If it is for the team keep it.\r\n if (item.subscriptionTeamId === subscriptionTeamId) {\r\n return true;\r\n }\r\n\r\n // If it is for a member of the team keep it.\r\n if (!!profiles?.find(it => it.userId === item.userId)) {\r\n return true;\r\n }\r\n\r\n // Otherwise we don't want it.\r\n return false;\r\n })\r\n , [allUserAssessmentAssignments, subscriptionTeamId, profiles]);\r\n\r\n // The subscription is only licensed for some assessments, so remove any that we're not licensed for now\r\n // and also remove any that have not either been used or assigned to this team.\r\n const assessments = useMemo(() =>\r\n allAssessments\r\n ?.filter(assessment => !!subscriptionAssessments?.find(it => it.assessmentId === assessment.id))\r\n ?.filter(assessment =>\r\n !!assessmentSessions?.find(it => it.assessmentId === assessment.id)\r\n || !!userAssessmentAssignments?.find(it => it.assessmentId === assessment.id)\r\n )\r\n , [allAssessments, subscriptionAssessments, userAssessmentAssignments, assessmentSessions]);\r\n\r\n // Expand the UserAssessmentAssignments so we can work with them easier.\r\n const expandedUserAssessmentAssignments = useExpandedUserAssessmentAssignments(userAssessmentAssignments, profiles);\r\n\r\n // Allow the generation of dashboard summary data.\r\n const generateDashboardSummary = useCallback((\r\n sessionFilter: (session: AssessmentSession) => boolean,\r\n assignmentFilter: (assignment: UserAssessmentAssignment) => boolean,\r\n assessmentType: AssessmentType) => {\r\n // Filter by the passed in fitler.\r\n let mySessions = assessmentSessions?.filter(sessionFilter) ?? [];\r\n let myAssignments = expandedUserAssessmentAssignments?.filter(assignmentFilter) ?? [];\r\n\r\n // Filter by the passed in type.\r\n mySessions = mySessions.filter(session => {\r\n const assessment = assessments?.find(it => it.id === session.assessmentId);\r\n if (!assessment) {\r\n return false;\r\n }\r\n\r\n return assessment.assessmentType === assessmentType;\r\n });\r\n\r\n myAssignments = myAssignments.filter(session => {\r\n const assessment = assessments?.find(it => it.id === session.assessmentId);\r\n if (!assessment) {\r\n return false;\r\n }\r\n\r\n return assessment.assessmentType === assessmentType;\r\n });\r\n\r\n // Filter the driver metrics to contain only users that have assessments or assignments.\r\n const myUserDriverMetrics = allUserDriverMetrics?.filter(\r\n udm => !!mySessions.find(it => it.userId === udm.userId) || !!myAssignments.find(it => it.userId === udm.userId)\r\n ) ?? [];\r\n\r\n // Generate the summary data.\r\n const ret = _generateDashboardSummary(mySessions, assessments ?? [], profiles ?? [], myAssignments, myUserDriverMetrics ?? [], subscription);\r\n return ret;\r\n }, [assessmentSessions, assessments, profiles, expandedUserAssessmentAssignments, subscription, allUserDriverMetrics]);\r\n\r\n\r\n // Track the active tab.\r\n const [activeTab, setActiveTab] = useActiveDashboardTab('subscriptionTeamDashboard', 'people');\r\n\r\n // Track the active assessment type.\r\n const [activeAssessmentType, setActiveAssessmentType] = useActiveDashboardAssessmentType();\r\n const hideAssessmentTypeToggle = activeTab === 'assessments' || activeTab === 'training';\r\n\r\n return (\r\n \r\n \r\n \r\n \r\n

\r\n \r\n {\r\n t('subscriptionTeamDashboard.heading', '{{name}} dashboard', { name: subscriptionTeam?.name })\r\n }\r\n

\r\n \r\n \r\n \r\n \r\n setActiveTab('people')}>\r\n \r\n <> \r\n {t('subscriptionTeamDashboard.tabs.people', 'People')}\r\n \r\n \r\n \r\n setActiveTab('assessments')}>\r\n \r\n <> \r\n {t('subscriptionTeamDashboard.tabs.assessments', 'Assessments')}\r\n \r\n \r\n \r\n setActiveTab('training')}>\r\n \r\n <> \r\n {t('subscriptionTeamDashboard.tabs.training', 'Training')}\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n
\r\n
\r\n \r\n \r\n\r\n \r\n \r\n \r\n\r\n \r\n \r\n \r\n\r\n \r\n \r\n \r\n \r\n
\r\n );\r\n};\r\n","import { IdentityRoles } from \"../../configure/security/IdentityRoles\";\r\nimport { RouteEntry } from \"../../shared/routes\";\r\nimport { AdministrationAssessmentDashboard } from \"./administrationDashboard/AdministrationAssessmentDashboard\";\r\nimport { AdministrationDashboard } from \"./administrationDashboard/AdministrationDashboard\";\r\nimport { StaffUserDashboard } from \"./administrationDashboard/StaffUserDashboard\";\r\nimport { Dashboard } from \"./dashboard/Dashboard\";\r\nimport { SubscriptionAssessmentDashboard } from \"./subscriptionDashboard/SubscriptionAssessmentDashboard\";\r\nimport { SubscriptionDashboard } from \"./subscriptionDashboard/SubscriptionDashboard\";\r\nimport { SubscriptionTeamDashboard } from \"./subscriptionDashboard/SubscriptionTeamDashboard\";\r\nimport { SubscriptionUserDashboard } from \"./subscriptionDashboard/SubscriptionUserDashboard\";\r\n\r\nexport const dashboardRoutes: Array = [\r\n { path: '/dashboard', exact: true, component: Dashboard, authorize: true },\r\n { path: '/dashboard/team/:subscriptionTeamId', exact: true, component: SubscriptionTeamDashboard, authorize: true },\r\n { path: '/dashboard/user/:userId', exact: true, component: SubscriptionUserDashboard, authorize: true },\r\n { path: '/dashboard/assessment/:assessmentId', exact: true, component: SubscriptionAssessmentDashboard, authorize: true },\r\n { path: '/dashboard/training/:assessmentId', exact: true, component: SubscriptionAssessmentDashboard, authorize: true },\r\n\r\n { path: '/administration/dashboard', exact: true, component: AdministrationDashboard, authorize: true, requireRole: IdentityRoles.Administration, },\r\n { path: '/administration/dashboard/subscription/:subscriptionId', exact: true, component: SubscriptionDashboard, authorize: true, requireRole: IdentityRoles.Administration, },\r\n { path: '/administration/dashboard/subscription/:subscriptionId/team/:subscriptionTeamId', exact: true, component: SubscriptionTeamDashboard, authorize: true, requireRole: IdentityRoles.Administration, },\r\n { path: '/administration/dashboard/subscription/:subscriptionId/user/:userId', exact: true, component: SubscriptionUserDashboard, authorize: true, requireRole: IdentityRoles.Administration, },\r\n { path: '/administration/dashboard/staff/:userId', exact: true, component: StaffUserDashboard, authorize: true, requireRole: IdentityRoles.Administration, },\r\n { path: '/administration/dashboard/assessment/:assessmentId', exact: true, component: AdministrationAssessmentDashboard, authorize: true, requireRole: IdentityRoles.Administration, },\r\n { path: '/administration/dashboard/training/:assessmentId', exact: true, component: AdministrationAssessmentDashboard, authorize: true, requireRole: IdentityRoles.Administration, },\r\n { path: '/administration/dashboard/subscription/:subscriptionId/assessment/:assessmentId', exact: true, component: SubscriptionAssessmentDashboard, authorize: true, requireRole: IdentityRoles.Administration, },\r\n { path: '/administration/dashboard/subscription/:subscriptionId/training/:assessmentId', exact: true, component: SubscriptionAssessmentDashboard, authorize: true, requireRole: IdentityRoles.Administration, },\r\n];\r\n","import { IdentityRoles } from \"../../../configure/security/IdentityRoles\";\r\nimport { useCurrentUserOrEmulatedSubscriptionId } from \"../../../globalState/subscriptions/useCurrentUserOrEmulatedSubscriptionId\";\r\nimport { AuthorizeContainer } from \"../../../shared/authorizeRoute\";\r\nimport { MyDashboard } from \"../myDashboard/MyDashboard\";\r\nimport { SubscriptionDashboard } from \"../subscriptionDashboard/SubscriptionDashboard\";\r\n\r\n/**\r\n * Top level dashboard that will present either the user's own dashboard or a subscription's dashboard.\r\n */\r\nexport const Dashboard = () => {\r\n const subscriptionId = useCurrentUserOrEmulatedSubscriptionId();\r\n \r\n return (\r\n <>\r\n {/* Logic for admins is based on if we are emulating or not. */}\r\n \r\n {\r\n subscriptionId ? (\r\n \r\n ) : (\r\n \r\n )\r\n }\r\n \r\n\r\n {/* Logic for non-admins is just based on permissions. */}\r\n \r\n {/* Show the right dashboard link */}\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n );\r\n};","import { useCallback } from \"react\";\r\nimport { ConditionalFragment } from \"react-conditionalfragment\";\r\nimport { useTranslation } from \"react-i18next\";\r\nimport { Button, ButtonGroup, Col, Container, NavItem, NavLink, Row } from \"reactstrap\";\r\nimport { AssessmentType } from \"../../../api/main/models/codeOnly/AssessmentType\";\r\nimport { useAdministrationDashboardViewModel } from \"../../../api/main/dashboard/viewModels/useAdministrationDashboardViewModel\";\r\nimport { AlertOnErrors } from \"../../../shared/alertOnErrors\";\r\nimport { Background } from \"../../shared/background/Background\";\r\nimport { Banner } from \"../../shared/Banner\";\r\nimport { PillsNavBar } from \"../../shared/pillsNavBar/PillsNavBar\";\r\nimport { LoadingIndicator } from \"../../shared/LoadingIndicator\";\r\nimport { SubscriptionsDashboardTab } from \"../tabs/SubscriptionsDashboardTab\";\r\nimport { UserAssessmentAssignment } from \"../../../api/main/models/UserAssessmentAssignment\";\r\nimport { AssessmentSession } from \"../../../api/main/models/AssessmentSession\";\r\nimport { generateDashboardSummary as _generateDashboardSummary } from \"../utilities/generateDashboardSummary\";\r\nimport { EsituStaffDashboardTab } from \"../tabs/EsituStaffDashboardTab\";\r\nimport { SubscriptionTeamsDashboardTab } from \"../tabs/SubscriptionTeamsDashboardTab\";\r\nimport { SubscriptionUsersDashboardTab } from \"../tabs/SubscriptionUsersDashboardTab\";\r\nimport { AssessmentsDashboardTab } from \"../tabs/AssessmentsDashboardTab\";\r\nimport { TrainingDashboardTab } from \"../tabs/TrainingDashboardTab\";\r\nimport { useExpandedUserAssessmentAssignments } from \"../utilities/useExpandedUserAssessmentAssignments\";\r\nimport { useActiveDashboardAssessmentType } from \"../../../globalState/activeDashboardAssessmentType/useActiveDashboardAssessmentType\";\r\nimport { useActiveDashboardTab } from \"../../../globalState/activeDashboardTab/useActiveDashboardTab\";\r\nimport { DashboardBackButton } from \"../backButton/DashboardBackButton\";\r\nimport { FontAwesomeIcon } from \"@fortawesome/react-fontawesome\";\r\nimport { DistributorsDashboardTab } from \"../tabs/DistributorsDashboardTab\";\r\nimport { SubscriptionType } from \"../../../api/main/models/codeOnly/SubscriptionType\";\r\nimport { useMemo } from 'react';\r\n\r\nexport type AdministrationDashboardTabs = 'subscriptions' | 'distributors' | 'teams' | 'staff' | 'subscriptionUsers' | 'assessments' | 'training';\r\n\r\n/**\r\n * Dashboard for a subscription.\r\n */\r\nexport const AdministrationDashboard = () => {\r\n const { t } = useTranslation();\r\n\r\n const {\r\n data: {\r\n subscriptions,\r\n subscriptionTeams,\r\n subscriptionAssessments,\r\n profiles,\r\n assessments,\r\n assessmentSessions,\r\n userAssessmentAssignments,\r\n userDriverMetrics: allUserDriverMetrics,\r\n },\r\n isLoading,\r\n errors: loadErrors\r\n } = useAdministrationDashboardViewModel();\r\n\r\n // Expand the UserAssessmentAssignments so we can work with them easier.\r\n const expandedUserAssessmentAssignments = useExpandedUserAssessmentAssignments(userAssessmentAssignments, profiles);\r\n const distributors = useMemo(() => {\r\n\r\n if (subscriptions) {\r\n return subscriptions.filter(item => item.subscriptionType === SubscriptionType.Distributor);\r\n }\r\n\r\n }, [subscriptions]);\r\n\r\n // Allow the generation of dashboard summary data.\r\n const generateDashboardSummary = useCallback((\r\n sessionFilter: (session: AssessmentSession) => boolean,\r\n assignmentFilter: (assignment: UserAssessmentAssignment) => boolean,\r\n assessmentType: AssessmentType) => {\r\n // Filter by the passed in fitler.\r\n let mySessions = assessmentSessions?.filter(sessionFilter) ?? [];\r\n let myAssignments = expandedUserAssessmentAssignments?.filter(assignmentFilter) ?? [];\r\n\r\n // Filter by the passed in type.\r\n mySessions = mySessions.filter(session => {\r\n const assessment = assessments?.find(it => it.id === session.assessmentId);\r\n if (!assessment) {\r\n return false;\r\n }\r\n return assessment.assessmentType === assessmentType;\r\n });\r\n\r\n myAssignments = myAssignments.filter(session => {\r\n const assessment = assessments?.find(it => it.id === session.assessmentId);\r\n if (!assessment) {\r\n return false;\r\n }\r\n return assessment.assessmentType === assessmentType;\r\n });\r\n\r\n // Filter the driver metrics to contain only users that have assessments or assignments.\r\n const myUserDriverMetrics = allUserDriverMetrics?.filter(\r\n udm => !!mySessions.find(it => it.userId === udm.userId) || !!myAssignments.find(it => it.userId === udm.userId)\r\n ) ?? [];\r\n\r\n // Generate the summary data.\r\n const ret = _generateDashboardSummary(mySessions, assessments ?? [], profiles ?? [], myAssignments, myUserDriverMetrics, null);\r\n return ret;\r\n }, [assessmentSessions, assessments, profiles, expandedUserAssessmentAssignments, allUserDriverMetrics]);\r\n\r\n\r\n // Track the active tab.\r\n const [activeTab, setActiveTab] = useActiveDashboardTab('administrationDashboard', 'subscriptions');\r\n\r\n // Track the active assessment type.\r\n const [activeAssessmentType, setActiveAssessmentType] = useActiveDashboardAssessmentType();\r\n const hideAssessmentTypeToggle = activeTab === 'assessments' || activeTab === 'training' || activeTab === 'distributors';\r\n\r\n return (\r\n \r\n \r\n \r\n \r\n

\r\n \r\n {t('administrationDashboard.heading.default', 'Esitu dashboard')}\r\n

\r\n \r\n \r\n \r\n \r\n setActiveTab('subscriptions')}>\r\n \r\n <> \r\n {t('administrationDashboard.tabs.subscriptions', 'Subscriptions')}\r\n \r\n \r\n \r\n setActiveTab('distributors')}>\r\n \r\n <> \r\n {t('administrationDashboard.tabs.distributors', 'Distributors')}\r\n \r\n \r\n \r\n setActiveTab('staff')}>\r\n \r\n <> \r\n {t('administrationDashboard.tabs.staff', 'Esitu staff')}\r\n \r\n \r\n \r\n setActiveTab('subscriptionUsers')}>\r\n \r\n <> \r\n {t('administrationDashboard.tabs.subscriptionUsers', 'Subscription users')}\r\n \r\n \r\n \r\n setActiveTab('teams')}>\r\n \r\n <> \r\n {t('administrationDashboard.tabs.teams', 'Subscription teams')}\r\n \r\n \r\n \r\n setActiveTab('assessments')}>\r\n \r\n <> \r\n {t('administrationDashboard.tabs.assessments', 'Assessments')}\r\n \r\n \r\n \r\n setActiveTab('training')}>\r\n \r\n <> \r\n {t('administrationDashboard.tabs.training', 'Training')}\r\n \r\n \r\n \r\n \r\n
\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n
\r\n \r\n \r\n\r\n \r\n setActiveTab(tabName)}\r\n activeAssessmentType={activeAssessmentType}\r\n\r\n assessmentSessions={assessmentSessions ?? []}\r\n assessments={assessments ?? []}\r\n />\r\n \r\n\r\n \r\n setActiveTab(tabName)}\r\n activeAssessmentType={activeAssessmentType}\r\n userAssessmentAssignment={userAssessmentAssignments ?? []}\r\n assessments={assessments ?? []}\r\n />\r\n \r\n\r\n \r\n \r\n \r\n\r\n \r\n \r\n \r\n\r\n \r\n \r\n \r\n\r\n \r\n \r\n \r\n\r\n \r\n \r\n \r\n \r\n
\r\n );\r\n};\r\n","import { FontAwesomeIcon } from \"@fortawesome/react-fontawesome\";\r\nimport { useMemo, useState } from \"react\";\r\nimport { ConditionalFragment } from \"react-conditionalfragment\";\r\nimport { useTranslation } from \"react-i18next\";\r\nimport { useHistory, useParams } from \"react-router\";\r\nimport { useAsyncCallback } from \"react-use-async-callback\";\r\nimport { Button, Col, FormGroup, Input, Label, Row, Spinner, Alert } from \"reactstrap\";\r\nimport { useUploadBlobCallback } from \"../../../api/main/blobReferences/useUploadBlobCallback\";\r\nimport { SubscriptionTeam } from \"../../../api/main/models/SubscriptionTeam\";\r\nimport { useProfileSupportingData } from \"../../../api/main/profiles/useProfileSupportingData\";\r\nimport { useImportUsersCallback } from \"../../../api/main/users/useImportUsersCallback\";\r\nimport { useCurrentUserOrEmulatedSubscriptionId } from \"../../../globalState/subscriptions/useCurrentUserOrEmulatedSubscriptionId\";\r\nimport { AlertOnErrors } from \"../../../shared/alertOnErrors\";\r\nimport { useChangesArray } from \"../../../shared/useChanges\";\r\nimport { Background } from \"../../shared/background/Background\";\r\nimport { Banner } from \"../../shared/Banner\";\r\nimport { FileUploadButton } from \"../../shared/fileUploadButton/FileUploadButton\";\r\nimport { FormButtons } from \"../../shared/FormButtons\";\r\nimport { LoadingIndicator } from \"../../shared/LoadingIndicator\";\r\nimport { MainContainer } from \"../../shared/MainContainer\";\r\nimport { useSaveSubscriptionCallback } from '../../../api/main/subscriptions/useSaveSubscriptionCallback';\r\nimport { importUsersMutation_importUsers } from \"../../../api/main/generated/importUsersMutation\";\r\n\r\nexport type importUsersTabs = 'users' | 'assessmentAssignments' | 'trainingAssignments';\r\n\r\nexport interface ImportUsersBaseProps {\r\n defaultRoleGroup: string,\r\n}\r\n\r\n/**\r\n * Import users.\r\n */\r\nexport const ImportUsersBase = (props: ImportUsersBaseProps) => {\r\n const {\r\n defaultRoleGroup,\r\n } = props;\r\n\r\n const { t } = useTranslation();\r\n\r\n const history = useHistory();\r\n\r\n const subscriptionId = useCurrentUserOrEmulatedSubscriptionId();\r\n const { subscriptionTeamId: subscriptionTeamIdParam, roleGroup: roleGroupParam } = useParams<{ subscriptionTeamId: string | undefined, roleGroup: string | undefined }>();\r\n\r\n // Supporting data (dependant on the current user's subscription).\r\n const { data: { roleGroups: storeRoleGroups, subscriptionTeams: storeSubscriptionTeams, subscription }, isLoading: isLoadingSupportingData, errors: loadSupportingDataErrors } = useProfileSupportingData({ subscriptionId: subscriptionId ?? undefined });\r\n const isLoading = isLoadingSupportingData;\r\n\r\n // Used for updating subscription current users\r\n const [saveSubscription] = useSaveSubscriptionCallback();\r\n\r\n // Simple state tracking of field changes.\r\n const [subscriptionTeamId, setSubscriptionTeamId] = useState(subscriptionTeamIdParam);\r\n const [_roleGroup, setRoleGroup] = useState(roleGroupParam ?? undefined);\r\n const roleGroup = _roleGroup || defaultRoleGroup;\r\n\r\n // Teams\r\n const subscriptionTeamsManager = useChangesArray(storeSubscriptionTeams, item => item.id);\r\n const orderedSubscriptionTeams = useMemo(() => {\r\n let ret = [...subscriptionTeamsManager.model];\r\n ret.sort((a, b) => {\r\n if (a.name === b.name) {\r\n return 0;\r\n } else if (a.name > b.name) {\r\n return 1;\r\n } else {\r\n return -1;\r\n }\r\n });\r\n return ret;\r\n }, [subscriptionTeamsManager]);\r\n\r\n // Role groups.\r\n const roleGroups = useMemo(() => {\r\n return (storeRoleGroups ?? [])\r\n .filter(item => item.id === 'Driver' || item.id === 'Driver manager' || item.id === 'Overview manager');\r\n }, [storeRoleGroups]);\r\n\r\n // Uploading blobs.\r\n const [uploadBlob, { errors: uploadBlobErrors }] = useUploadBlobCallback();\r\n\r\n // Import users from a blob.\r\n const [importUsers, { errors: importUsersErrors }] = useImportUsersCallback();\r\n\r\n // Results from an import.\r\n const [importUsersResults, setImportUsersResults] = useState | undefined>(undefined);\r\n\r\n const [willExceedMaxUsers, setWillExceedMaxUsers] = useState(false);\r\n\r\n // Perform the user import.\r\n const [performUserImport, { isExecuting: isImportingUsers, errors: performUserImportErrors }] = useAsyncCallback(async (files: FileList | null) => {\r\n if (!files) {\r\n return;\r\n }\r\n\r\n // Upload the file.\r\n const blob = await uploadBlob(files);\r\n if (!blob) {\r\n return;\r\n }\r\n\r\n // Import from the upload.\r\n const results = await importUsers({ blobId: blob.id, subscriptionId: subscriptionId ?? '', subscriptionTeamId: subscriptionTeamId ?? null, roleGroup: roleGroup ?? '' });\r\n\r\n if (results.length === 0) {\r\n\r\n setWillExceedMaxUsers(true);\r\n return;\r\n\r\n }\r\n if (subscription) {\r\n //update the subscriptions current user count\r\n await saveSubscription(subscription.id, { currentUsers: subscription.currentUsers + (results?.filter(it => it.successful)?.length ?? 0) }, false);\r\n }\r\n\r\n setImportUsersResults(results);\r\n }, [uploadBlob, subscriptionId, setImportUsersResults, roleGroup, subscriptionTeamId, subscription, setWillExceedMaxUsers]);\r\n\r\n\r\n return (\r\n \r\n \r\n \r\n \r\n

{t('importUsersBase.createHeading', 'Import users')}

\r\n \r\n \r\n \r\n \r\n \r\n \r\n
\r\n
\r\n\r\n \r\n {\r\n willExceedMaxUsers ? (\r\n \r\n <>{t('importUsersBase.maxUsersReached', 'Cannot import new users. Maximum amount of users for this subscription has been reached or will be exceeded.')} \r\n \r\n ) : null\r\n }\r\n \r\n\r\n \r\n
\r\n {t('importUsersBase.instructions.p1', 'Users can be imported from a file instead of being set up manually within the app. The file can be in Excel (.xlsx), CSV (.csv), or tab-delimited (.txt or .tsv) format and must contain the correct columns as outlined below.')}\r\n
\r\n

\r\n {t('importUsersBase.instructions.p2', 'The file can contain the following columns (in any order). Other columns will be ignored:')}\r\n

\r\n
    \r\n
  • {t('importUsersBase.columns.email', 'Email (Used for login - if omitted or blank user will have a unique driver PIN generated for their login).')}
  • \r\n
  • {t('importUsersBase.columns.firstName', 'First name (optional)')}
  • \r\n
  • {t('importUsersBase.columns.lastName', 'Last name (optional)')}
  • \r\n
  • {t('importUsersBase.columns.team', 'Team (optional - if omitted or blank user will be placed into the team selected below.)')}
  • \r\n
  • {t('importUsersBase.columns.securityGroup', 'Security group (optional - if omitted or blank user will be placed into the security group selected below.)')}
  • \r\n
  • {t('importUsersBase.columns.password', 'Password (optional - if omitted or blank user will be asked to their password when first accessing the system.)')}
  • \r\n
\r\n\r\n \r\n \r\n setSubscriptionTeamId(e.currentTarget.value || undefined)}>\r\n \r\n\r\n {\r\n orderedSubscriptionTeams.map(item => (\r\n \r\n ))\r\n }\r\n \r\n \r\n\r\n \r\n \r\n setRoleGroup(e.currentTarget.value || undefined)}>\r\n {\r\n roleGroups?.map(item => (\r\n \r\n ))\r\n }\r\n \r\n \r\n
\r\n\r\n \r\n
\r\n {t('importUsersBase.results.summary', '{{count}} users have been imported for you.', { count: importUsersResults?.filter(it => it.successful)?.length ?? 0 })}\r\n
\r\n\r\n {\r\n importUsersResults?.map(item => (\r\n
\r\n \r\n \r\n \r\n {t('importUsersBase.results.rowNumber', 'Row {{rowNumber}}', { rowNumber: item.rowNumber })}\r\n \r\n \r\n \r\n \r\n {t('importUsersBase.results.successful', 'User created for {{email}}', { email: item.user?.email })}\r\n \r\n \r\n \r\n {\r\n item.errors.map((error, index) => (\r\n
\r\n {error}\r\n
\r\n ))\r\n }\r\n
\r\n 1}>\r\n
    \r\n {\r\n item.errors.map((error, index) => (\r\n
  • \r\n {error}\r\n
  • \r\n ))\r\n }\r\n
\r\n
\r\n
\r\n \r\n
\r\n
\r\n
\r\n ))\r\n }\r\n
\r\n\r\n \r\n \r\n performUserImport(files)} isExecuting={isImportingUsers}\r\n executingChildren={<><> {t('importUsersBase.importing', 'Importing...')}}\r\n >\r\n \r\n <> \r\n {t('importUsersBase.import', 'Import file...')}\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n
\r\n
\r\n );\r\n};\r\n","import { useMutation } from \"@apollo/react-hooks\";\r\nimport { useAsyncCallback } from 'react-use-async-callback';\r\nimport gql from \"graphql-tag\";\r\nimport { AsyncActionStatus } from '../../../shared/abstractStore';\r\nimport { ImportUsersInput } from '../generated/globalTypes';\r\nimport { userFieldsFragment } from \"../models/User\";\r\nimport { importUsersMutationVariables, importUsersMutation, importUsersMutation_importUsers } from \"../generated/importUsersMutation\";\r\nimport { profileFieldsFragment } from \"../models/Profile\";\r\n\r\n/**\r\n * Get a callback to change the role grup of a user in the store.\r\n */\r\nexport function useImportUsersCallback(): [(model: ImportUsersInput) => Promise>, AsyncActionStatus] {\r\n const [mutationAction, { error }] = useMutation(\r\n gql`\r\n mutation importUsersMutation ($model: ImportUsersInput!) {\r\n importUsers(model: $model) {\r\n id\r\n rowNumber\r\n successful\r\n errors\r\n user {\r\n ...userFields\r\n }\r\n profile {\r\n ...profileFields\r\n }\r\n }\r\n }\r\n\r\n ${userFieldsFragment}\r\n ${profileFieldsFragment}\r\n `,\r\n {\r\n }\r\n );\r\n\r\n // Wrap the mutation in a standard callback.\r\n const [action, { isExecuting, errors: actionErrors }] = useAsyncCallback(async (model: ImportUsersInput) => {\r\n const result = await mutationAction({ variables: { model: model } });\r\n if (result.errors && result.errors.length) {\r\n throw result.errors;\r\n }\r\n\r\n return result.data?.importUsers ?? [];\r\n }, [mutationAction]);\r\n\r\n return [action, { isExecuting: isExecuting, errors: error ? error.message : actionErrors }];\r\n}\r\n","import { ImportUsersBase } from \"./ImportUsersBase\";\r\n\r\nexport const ImportDrivers = () => ();","import { ImportUsersBase } from \"./ImportUsersBase\";\r\n\r\nexport const ImportManagers = () => ();","import { FontAwesomeIcon } from \"@fortawesome/react-fontawesome\";\r\nimport React, { useMemo, useState } from \"react\";\r\nimport { ConditionalFragment } from \"react-conditionalfragment\";\r\nimport { useTranslation } from \"react-i18next\";\r\nimport { useHistory, useParams } from \"react-router\";\r\nimport { useAsyncCallback } from \"react-use-async-callback\";\r\nimport { Button, Col, FormGroup, Input, Label, Row, Spinner, Alert, ButtonGroup } from \"reactstrap\";\r\nimport { useUploadBlobCallback } from \"../../../api/main/blobReferences/useUploadBlobCallback\";\r\nimport { SubscriptionTeam } from \"../../../api/main/models/SubscriptionTeam\";\r\nimport { useProfileSupportingData } from \"../../../api/main/profiles/useProfileSupportingData\";\r\nimport { useCurrentUserOrEmulatedSubscriptionId } from \"../../../globalState/subscriptions/useCurrentUserOrEmulatedSubscriptionId\";\r\nimport { AlertOnErrors } from \"../../../shared/alertOnErrors\";\r\nimport { useChangesArray } from \"../../../shared/useChanges\";\r\nimport { Background } from \"../../shared/background/Background\";\r\nimport { Banner } from \"../../shared/Banner\";\r\nimport { FileUploadButton } from \"../../shared/fileUploadButton/FileUploadButton\";\r\nimport { FormButtons } from \"../../shared/FormButtons\";\r\nimport { LoadingIndicator } from \"../../shared/LoadingIndicator\";\r\nimport { MainContainer } from \"../../shared/MainContainer\";\r\nimport { useImportUserAssessmentAssignmentsCallback } from \"../../../api/main/userAssessmentAssignments/useImportUserAssessmentAssignmentsCallback\";\r\nimport { importUserAssessmentAssignmentsMutation_importUserAssessmentAssignments } from \"../../../api/main/generated/importUserAssessmentAssignmentsMutation\";\r\n\r\nexport type importUsersTabs = 'users' | 'assessmentAssignments' | 'trainingAssignments';\r\n\r\nexport interface ImportUserAssessmentAssignmentsBaseProps {\r\n}\r\n\r\n/**\r\n * Import users.\r\n */\r\nexport const ImportUserAssessmentAssignmentsBase = (props: ImportUserAssessmentAssignmentsBaseProps) => {\r\n\r\n const { t } = useTranslation();\r\n\r\n const history = useHistory();\r\n\r\n const subscriptionId = useCurrentUserOrEmulatedSubscriptionId();\r\n const { subscriptionTeamId: subscriptionTeamIdParam, roleGroup: roleGroupParam } = useParams<{ subscriptionTeamId: string | undefined, roleGroup: string | undefined }>();\r\n\r\n // Supporting data (dependant on the current user's subscription).\r\n const { data: { roleGroups: storeRoleGroups, subscriptionTeams: storeSubscriptionTeams, subscription }, isLoading: isLoadingSupportingData, errors: loadSupportingDataErrors } = useProfileSupportingData({ subscriptionId: subscriptionId ?? undefined });\r\n const isLoading = isLoadingSupportingData;\r\n\r\n // Simple state tracking of field changes.\r\n const [subscriptionTeamId, setSubscriptionTeamId] = useState(subscriptionTeamIdParam);\r\n\r\n // Teams\r\n const subscriptionTeamsManager = useChangesArray(storeSubscriptionTeams, item => item.id);\r\n const orderedSubscriptionTeams = useMemo(() => {\r\n let ret = [...subscriptionTeamsManager.model];\r\n ret.sort((a, b) => {\r\n if (a.name === b.name) {\r\n return 0;\r\n } else if (a.name > b.name) {\r\n return 1;\r\n } else {\r\n return -1;\r\n }\r\n });\r\n return ret;\r\n }, [subscriptionTeamsManager]);\r\n\r\n // Role groups.\r\n const roleGroups = useMemo(() => {\r\n return (storeRoleGroups ?? [])\r\n .filter(item => item.id === 'Driver' || item.id === 'Driver manager' || item.id === 'Overview manager');\r\n }, [storeRoleGroups]);\r\n\r\n // Uploading blobs.\r\n const [uploadBlob, { errors: uploadBlobErrors }] = useUploadBlobCallback();\r\n \r\n const [importUserAssessmentAssignments, { errors: importUserAssessmentAssignmentsErrors }] = useImportUserAssessmentAssignmentsCallback();\r\n\r\n // Results from an import.\r\n const [importUserAssessmentAssignmentsResults, setImportUserAssessmentAssignmentsResults] = React.useState | undefined>(undefined);\r\n\r\n // Perform the assessment assignment import.\r\n const [performUserAssessmentAssignmentImport, { isExecuting: isImportingUserAssessmentAssignments, errors: performUserAssessmentAssignmentImportErrors }] = useAsyncCallback(async (files: FileList | null) => {\r\n if (!files) {\r\n return;\r\n }\r\n\r\n // Upload the file.\r\n const blob = await uploadBlob(files);\r\n if (!blob) {\r\n return;\r\n }\r\n\r\n // Import from the upload.\r\n const results = await importUserAssessmentAssignments({ blobId: blob.id, subscriptionId: subscriptionId ?? '' });\r\n\r\n setImportUserAssessmentAssignmentsResults(results);\r\n }, [uploadBlob, subscriptionId, setImportUserAssessmentAssignmentsResults, subscriptionTeamId, subscription, ]);\r\n\r\n\r\n return (\r\n \r\n \r\n \r\n \r\n

{t('importUserAssessmentAssignmentsBase.createHeading', 'Import user assessment assignments')}

\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n <> \r\n {t('subscriptionDashboard.tabs.assessmentAssignments', 'Export assessment assignments')}\r\n \r\n \r\n \r\n <> \r\n {t('subscriptionDashboard.tabs.assessmentAssignments', 'Export training assignments')}\r\n \r\n \r\n \r\n
\r\n
\r\n\r\n \r\n \r\n\r\n \r\n
\r\n {t('importUserAssessmentAssignmentsBase.instructions.p1', 'User assessment assignments can be imported from a file instead of being set up manually within the app. The file can be in Excel (.xlsx), CSV (.csv), or tab-delimited (.txt or .tsv) format and must contain the correct columns as outlined below.')}\r\n
\r\n

\r\n {t('importUserAssessmentAssignmentsBase.instructions.p2', 'The file must contain the following columns. Other columns will be ignored:')}\r\n

\r\n
    \r\n
  1. {t('importUserAssessmentAssignmentsBase.columns.email', 'Email or PIN.')}
  2. \r\n
  3. {t('importUserAssessmentAssignmentsBase.columns.assignment', 'The exact assessment or training name (any order).')}
  4. \r\n
\r\n\r\n

\r\n {t('importUserAssessmentAssignmentsBase.instructions.p3', 'Underneath the assessment or training name, the following values are accepted:')}\r\n

\r\n
    \r\n
  • {t('importUserAssessmentAssignmentsBase.columns.assignmentYes', '\"Yes\" : Assign the assessment or training to the user.')}
  • \r\n
  • {t('importUserAssessmentAssignmentsBase.columns.assignmentYes', '\"No\" : Remove an assignment from the user.')}
  • \r\n
  • {t('importUserAssessmentAssignmentsBase.columns.assignmentYes', 'It can also be left empty where no changes will occur.')}
  • \r\n
\r\n

\r\n {t('importUserAssessmentAssignmentsBase.instructions.p4', 'Unsure about the file contents? You can use the export assignment buttons in the top right to get the correct layout and make the changes you want to import.')}\r\n

\r\n

\r\n {t('importUserAssessmentAssignmentsBase.instructions.p5', 'Please note that these imports and exports relate to directly assigning users to assessments and training. If you want to assign a full team to an assessment or training you can do this under the \"Teams\" area.')}\r\n

\r\n
\r\n\r\n \r\n
\r\n {t('importUserAssessmentAssignmentsBase.userAssessmentAssignmentResults.summary', '{{count}} assignments have been changed for you.', { count: importUserAssessmentAssignmentsResults?.filter(it => it.successful)?.length ?? 0 })}\r\n
\r\n\r\n {\r\n importUserAssessmentAssignmentsResults?.map(item => (\r\n
\r\n \r\n \r\n \r\n {t('importUserAssessmentAssignmentsBase.results.changeNumber', 'Change {{rowNumber}}', { rowNumber: item.rowNumber })}\r\n \r\n \r\n \r\n \r\n {item.message}\r\n \r\n \r\n \r\n {\r\n item.errors.map((error, index) => (\r\n
\r\n {error}\r\n
\r\n ))\r\n }\r\n
\r\n 1}>\r\n
    \r\n {\r\n item.errors.map((error, index) => (\r\n
  • \r\n {error}\r\n
  • \r\n ))\r\n }\r\n
\r\n
\r\n
\r\n \r\n
\r\n
\r\n
\r\n ))\r\n }\r\n
\r\n\r\n \r\n \r\n performUserAssessmentAssignmentImport(files)} isExecuting={isImportingUserAssessmentAssignments}\r\n executingChildren={<><> {t('importUserAssessmentAssignmentsBase.importing', 'Importing...')}}\r\n >\r\n \r\n <> \r\n {t('importUserAssessmentAssignmentsBase.import', 'Import file...')}\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n
\r\n
\r\n );\r\n};\r\n","import { IdentityRoles } from \"../../../configure/security/IdentityRoles\";\r\nimport { RouteEntry } from \"../../../shared/routes\";\r\nimport { ImportDrivers } from \"./ImportDrivers\";\r\nimport { ImportManagers } from \"./ImportManagers\";\r\nimport { ImportUserAssessmentAssignmentsBase } from \"./ImportUserAssessmentAssignmentBase\";\r\n\r\n\r\nexport const importUsersRoutes: Array = [\r\n { path: '/manage/drivers/import', exact: true, component: ImportDrivers, authorize: true, requireRole: [IdentityRoles.DriverManagement, IdentityRoles.SubscriptionAdministration] },\r\n { path: '/manage/drivers/importUserAssessmentAssignments', exact: true, component: ImportUserAssessmentAssignmentsBase, authorize: true, requireRole: [IdentityRoles.DriverManagement, IdentityRoles.SubscriptionAdministration] },\r\n { path: '/manage/managers/import', exact: true, component: ImportManagers, authorize: true, requireRole: [IdentityRoles.DriverManagement, IdentityRoles.SubscriptionAdministration] },\r\n\r\n { path: '/manage/teams/details/:subscriptionTeamId/drivers/import', exact: true, component: ImportDrivers, authorize: true, requireRole: [IdentityRoles.DriverManagement, IdentityRoles.SubscriptionAdministration] },\r\n { path: '/manage/teams/details/:subscriptionTeamId/managers/import', exact: true, component: ImportManagers, authorize: true, requireRole: [IdentityRoles.DriverManagement, IdentityRoles.SubscriptionAdministration] },\r\n];\r\n","import { useMutation } from \"@apollo/react-hooks\";\r\nimport { useAsyncCallback } from 'react-use-async-callback';\r\nimport gql from \"graphql-tag\";\r\nimport { AsyncActionStatus } from '../../../shared/abstractStore';\r\nimport { ImportUserAssessmentAssignmentsInput } from '../generated/globalTypes';\r\nimport { importUserAssessmentAssignmentsMutationVariables, importUserAssessmentAssignmentsMutation, importUserAssessmentAssignmentsMutation_importUserAssessmentAssignments } from \"../generated/importUserAssessmentAssignmentsMutation\";\r\n\r\n///**\r\n// * Get a callback to import a list of users and an assessment to assign them to (WILL NOT CREATE USERS).\r\n// */\r\nexport function useImportUserAssessmentAssignmentsCallback(): [(model: ImportUserAssessmentAssignmentsInput) => Promise>, AsyncActionStatus] {\r\n const [mutationAction, { error }] = useMutation(\r\n gql`\r\n mutation importUserAssessmentAssignmentsMutation ($model: ImportUserAssessmentAssignmentsInput!) {\r\n importUserAssessmentAssignments(model: $model) {\r\n id\r\n rowNumber\r\n successful\r\n errors\r\n message\r\n }\r\n }\r\n `,\r\n {\r\n }\r\n );\r\n\r\n // Wrap the mutation in a standard callback.\r\n const [action, { isExecuting, errors: actionErrors }] = useAsyncCallback(async (model: ImportUserAssessmentAssignmentsInput) => {\r\n const result = await mutationAction({ variables: { model: model } });\r\n if (result.errors && result.errors.length) {\r\n throw result.errors;\r\n }\r\n\r\n return result.data?.importUserAssessmentAssignments ?? [];\r\n }, [mutationAction]);\r\n\r\n return [action, { isExecuting: isExecuting, errors: error ? error.message : actionErrors }];\r\n}\r\n","import { RouteEntry } from \"../../../shared/routes\";\r\nimport { InformationList } from \"./InformationList\";\r\nimport { EditInformation, CreateInformation } from \"./EditInformation\";\r\nimport { IdentityRoles } from \"../../../configure/security/IdentityRoles\";\r\nimport { DeleteInformation } from \"./DeleteInformation\";\r\n\r\nexport const informationRoutes: Array = [\r\n { path: '/administration/information-pages', exact: true, component: InformationList, authorize: true, requireRole: IdentityRoles.Administration },\r\n { path: '/administration/information-pages/edit/:id', component: EditInformation, authorize: true, requireRole: IdentityRoles.Administration },\r\n { path: '/administration/information-pages/add', component: CreateInformation, authorize: true, requireRole: IdentityRoles.Administration },\r\n { path: '/administration/information-pages/delete/:id', component: DeleteInformation, authorize: true, requireRole: IdentityRoles.Administration },\r\n];\r\n","import { useTranslation } from \"react-i18next\";\r\nimport { getQuestionTypes, QuestionTypeCategory } from \"../../../api/main/models/codeOnly/QuestionType\";\r\nimport { QuestionsListBase } from \"../QuestionsListBase\";\r\n\r\n/**\r\n * List of information pages.\r\n */\r\nexport const InformationList = () => {\r\n const { t } = useTranslation();\r\n\r\n return (\r\n \r\n );\r\n};","import { QuestionType } from \"../../../api/main/models/codeOnly/QuestionType\";\r\nimport { CreateQuestionBase, EditQuestionBase } from \"../edit/EditQuestionBase\";\r\n\r\n/**\r\n * Create an information page.\r\n */\r\nexport const CreateInformation = () => (\r\n ({ /* No defaults needed */ })}\r\n />);\r\n\r\n/**\r\n * Edit an information page.\r\n */\r\nexport const EditInformation = () => ();\r\n","import { QuestionType } from \"../../../api/main/models/codeOnly/QuestionType\";\r\nimport { DeleteQuestionBase } from \"../DeleteQuestionBase\";\r\n\r\n/**\r\n * Delete an information page.\r\n */\r\nexport const DeleteInformation = () => ();\r\n","import { NavItem, NavLink } from 'reactstrap';\r\nimport { useTranslation } from 'react-i18next';\r\nimport { FontAwesomeIcon } from '@fortawesome/react-fontawesome';\r\nimport { NavLinkTrackActive } from '../../../shared/NavLinkTrackActive';\r\n\r\n\r\n\r\n\r\n/**\r\n * Administration navigation menu for distributors.\r\n */\r\nexport const DistributorAdministrationNavigation = () => {\r\n const { t } = useTranslation();\r\n\r\n return (\r\n <>\r\n \r\n \r\n \r\n {t('distributorAdministrationNavigation.dashboard', ' Dashboard')}\r\n \r\n \r\n \r\n \r\n \r\n {t('distributorAdministrationNavigation.subscriptions', ' Subscriptions')}\r\n \r\n \r\n \r\n \r\n \r\n {t('distributorAdministrationNavigation.admins', ' Admins')}\r\n \r\n \r\n \r\n );\r\n}","import { useCallback, useMemo } from \"react\";\r\nimport { ConditionalFragment } from \"react-conditionalfragment\";\r\nimport { Link } from \"react-router-dom\";\r\nimport { Button, Col, ListGroup, ListGroupItemHeading, Row } from \"reactstrap\";\r\nimport { Assessment } from \"../../../api/main/models/Assessment\";\r\nimport { AssessmentSession } from \"../../../api/main/models/AssessmentSession\";\r\nimport { AssessmentType } from \"../../../api/main/models/codeOnly/AssessmentType\";\r\nimport { Subscription } from \"../../../api/main/models/Subscription\";\r\nimport { UserAssessmentAssignment } from \"../../../api/main/models/UserAssessmentAssignment\";\r\nimport { useActiveDashboardRiskCategoryFilter } from \"../../../globalState/activeDashboardRiskCategoryFilter/useActiveDashboardRiskCategoryFilter\";\r\nimport { useAverageDriverMetricRiskChartData } from \"../chartData/useAverageDriverMetricRiskChartData\";\r\nimport { useAverageScoreChartData } from \"../chartData/useAverageScoreChartData\";\r\nimport { useCompletionChartData } from \"../chartData/useCompletionChartData\";\r\nimport { AverageDriverMetricRiskDonutChart } from \"../charts/AverageDriverMetricRiskDonutChart\";\r\nimport { AverageScoreRadarChart } from \"../charts/AverageScoreRadarChart\";\r\nimport { CompletionBarChart } from \"../charts/CompletionBarChart\";\r\nimport { DashboardListGroupItem } from \"../listGroups/DashboardListGroupItem\";\r\nimport { OverallRiskFilterListGroupItem } from \"../listGroups/OverallRiskFilterListGroupItem\";\r\nimport { DashboardSummary } from \"../utilities/generateDashboardSummary\";\r\nimport { useCachedDashboardSummaries } from \"../utilities/useCachedDashboardSummaries\";\r\nimport { useDashboardBaseRoute } from \"../utilities/useDashboardBaseRoute\";\r\nimport { useCurrentUserOrEmulatedSubscriptionId } from \"../../../globalState/subscriptions/useCurrentUserOrEmulatedSubscriptionId\";\r\n\r\nexport interface SubscriptionTabProps {\r\n subscriptions: Array,\r\n generateDashboardSummary: (\r\n sessionFilter: (session: AssessmentSession) => boolean,\r\n assignmentFilter: (assignment: UserAssessmentAssignment) => boolean,\r\n assessmentType: AssessmentType\r\n ) => DashboardSummary,\r\n\r\n assessmentSessions: Array,\r\n assessments: Array,\r\n activeAssessmentType: AssessmentType,\r\n}\r\n\r\n/**\r\n * Subscriptions tab on the dashboard.\r\n * @param props\r\n */\r\nexport const DistributorSubscriptionsDashboardTab = (props: SubscriptionTabProps) => {\r\n const {\r\n subscriptions,\r\n generateDashboardSummary,\r\n activeAssessmentType,\r\n } = props;\r\n\r\n const subscriptionId = useCurrentUserOrEmulatedSubscriptionId();\r\n\r\n const filteredSubscriptions = subscriptions.filter(item => item.distributorSubscriptionId === subscriptionId);\r\n\r\n // As a special case for subscriptions, we add \"Esitu staff\" on to the subscription lists. As we'll do this several times we store it here for reuse.\r\n const subscriptionsAndEsitu = useMemo(() => [...(filteredSubscriptions?.map(item => ({ id: item.id, name: item.companyName })) ?? [])], [filteredSubscriptions]);\r\n\r\n // Method we use to filter sessions by subscription wherever we need it.\r\n const filterBySubscription = useCallback((subscription: { id: string }, item: { subscriptionId: string | undefined | null }) => {\r\n if (!subscription.id) {\r\n return !item.subscriptionId;\r\n }\r\n\r\n return item.subscriptionId === subscription.id;\r\n }, []);\r\n\r\n // Cache the dashboard summaries so each chart/display doesn't need to recaclulate them and they can be looked up easily by id.\r\n const getCachedDashboardSummary = useCachedDashboardSummaries(\r\n subscriptionsAndEsitu,\r\n (group, assessmentType) => generateDashboardSummary(\r\n session => filterBySubscription(group, session),\r\n assignment => filterBySubscription(group, assignment),\r\n assessmentType\r\n )\r\n );\r\n\r\n // Get data for the various charts.\r\n const averageScoreChartData = useAverageScoreChartData(subscriptionsAndEsitu, getCachedDashboardSummary, activeAssessmentType);\r\n const averageDriverMetricRiskChartData = useAverageDriverMetricRiskChartData(subscriptionsAndEsitu, getCachedDashboardSummary, activeAssessmentType);\r\n const completionChartData = useCompletionChartData(subscriptionsAndEsitu, getCachedDashboardSummary, activeAssessmentType);\r\n\r\n // Filter the visible results by overall risk category if required.\r\n const [riskCategoryFilter, setRiskCategoryFilter] = useActiveDashboardRiskCategoryFilter();\r\n const filteredSubscriptionsAndEsitu = useMemo(() => {\r\n if (!riskCategoryFilter) {\r\n return subscriptionsAndEsitu;\r\n }\r\n\r\n return subscriptionsAndEsitu.filter(user => {\r\n const summary = getCachedDashboardSummary(user.id, activeAssessmentType);\r\n return (summary.averageUserDriverMetricScore.riskCategory === riskCategoryFilter);\r\n })\r\n }, [subscriptionsAndEsitu, riskCategoryFilter, getCachedDashboardSummary, activeAssessmentType]);\r\n \r\n const baseRoute = useDashboardBaseRoute();\r\n\r\n return (\r\n \r\n \r\n \r\n \r\n {\r\n filteredSubscriptionsAndEsitu.map(subscription => (\r\n getCachedDashboardSummary(subscription.id, assessmentType)}\r\n progressType=\"risk\"\r\n >\r\n {\r\n subscription.id ? (\r\n \r\n \r\n {subscription.name}\r\n \r\n \r\n ) : (\r\n \r\n )\r\n }\r\n \r\n ))\r\n }\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n );\r\n};","import { RouteEntry } from \"../../../shared/routes\";\r\nimport { DistributorsList } from './DistributorsList';\r\nimport { IdentityRoles } from \"../../../configure/security/IdentityRoles\";\r\nimport { EditDistributor, CreateDistributor } from \"./EditDistributor\";\r\nimport { DistributorAdminsList } from \"./DistributorAdminList\";\r\nimport { CreateDistributorAdmin, EditDistributorAdmin } from \"./Administration/CreateDistributorAdmin\";\r\nimport { DistributorAssessmentsList } from \"./DistributorAssessmentsList\";\r\nimport { DistributorTrainingList } from \"./DistributorTrainingList\";\r\nimport { DistributorAdministrationHome } from \"./Administration/DistributorAdministrationHome\";\r\nimport { DistributorAdministrationDashboard } from \"../../dashboard/administrationDashboard/DistributorAdministrationDashboard\";\r\nimport { DistributorSubscriptionsList } from \"./Administration/DistributorSubscriptionsList\";\r\nimport { CreateDistributorSubscription, EditDistributorSubscription } from \"./Administration/EditDistributorSubscription\";\r\nimport { DistributorSubscriptionAssessmentsList } from \"./Administration/DistributorSubscriptionAssessmentsList\";\r\nimport { DistributorSubscriptionTrainingList } from \"./Administration/DistributorSubscriptionTrainingList\";\r\n\r\nexport const distributorRoutes: Array = [\r\n { path: '/administration/distributors', exact: true, component: DistributorsList, authorize: true, requireRole: IdentityRoles.Administration },\r\n { path: '/administration/distributors/add', component: CreateDistributor, authorize: true, requireRole: IdentityRoles.Administration },\r\n { path: '/administration/distributors/edit/:id', component: EditDistributor, authorize: true, requireRole: IdentityRoles.Administration },\r\n { path: '/administration/distributors/details/:subscriptionId/assessments', exact: true, component: DistributorAssessmentsList, authorize: true, requireRole: IdentityRoles.Administration },\r\n { path: '/administration/distributors/details/:subscriptionId/training', exact: true, component: DistributorTrainingList, authorize: true, requireRole: IdentityRoles.Administration },\r\n\r\n //manage for distributors is the distributors admin page\r\n { path: '/manage/distributor', exact: true, component: DistributorAdministrationHome, authorize: true, requireRole: IdentityRoles.DistributionAdministration },\r\n { path: '/manage/distributor/dashboard', exact: true, component: DistributorAdministrationDashboard, authorize: true, requireRole: IdentityRoles.DistributionAdministration },\r\n { path: '/manage/distributor/admins', exact: true, component: DistributorAdminsList, authorize: true, requireRole: IdentityRoles.DistributionAdministration },\r\n { path: '/manage/distributor/admins/add', component: CreateDistributorAdmin, authorize: true, requireRole: IdentityRoles.DistributionAdministration },\r\n { path: '/manage/distributor/admins/edit/:id', component: EditDistributorAdmin, authorize: true, requireRole: IdentityRoles.DistributionAdministration },\r\n { path: '/manage/distributor/subscriptions', exact: true, component: DistributorSubscriptionsList, authorize: true, requireRole: IdentityRoles.DistributionAdministration },\r\n { path: '/manage/distributor/subscriptions/add', component: CreateDistributorSubscription, authorize: true, requireRole: IdentityRoles.DistributionAdministration },\r\n { path: '/manage/distributor/subscriptions/edit/:id', component: EditDistributorSubscription, authorize: true, requireRole: IdentityRoles.DistributionAdministration},\r\n { path: '/manage/distributor/subscriptions/details/:subscriptionId/assessments', exact: true, component: DistributorSubscriptionAssessmentsList, authorize: true, requireRole: IdentityRoles.DistributionAdministration},\r\n { path: '/manage/distributor/subscriptions/details/:subscriptionId/training', exact: true, component: DistributorSubscriptionTrainingList, authorize: true, requireRole: IdentityRoles.DistributionAdministration },\r\n];\r\n","import { SubscriptionType } from \"../../../api/main/models/codeOnly/SubscriptionType\";\r\nimport { SubscriptionsListBase } from \"../SubscriptionsListBase\";\r\nimport { useTranslation } from \"react-i18next\";\r\n\r\n/**\r\n * List of actual distributors.\r\n */\r\nexport const DistributorsList = () => {\r\n const { t } = useTranslation();\r\n\r\n return (\r\n \r\n );\r\n};","import { SubscriptionType } from \"../../../api/main/models/codeOnly/SubscriptionType\";\r\nimport { CreateSubscriptionBase, EditSubscriptionBase } from \"../EditSubscriptionBase\";\r\n\r\n/**\r\n * Create an actual Distributor.\r\n */\r\nexport const CreateDistributor = () => (\r\n ({ subscriptionType: SubscriptionType.Distributor })}\r\n />);\r\n\r\n/**\r\n * Edit an actual Distributor.\r\n */\r\nexport const EditDistributor = () => ();","import { useTranslation } from \"react-i18next\";\r\nimport { AssessmentType } from \"../../../api/main/models/codeOnly/AssessmentType\";\r\nimport { SubscriptionAssessmentsListBase } from \"../../subscriptionAssessments/SubscriptionAssessmentsListBase\";\r\nimport { useParams } from \"react-router\";\r\nimport { DistributorEditNavigation } from './DistributorEditNavigation';\r\n\r\n/**\r\n * List of actual assessments.\r\n */\r\nexport const DistributorAssessmentsList = () => {\r\n const { t } = useTranslation();\r\n\r\n const { subscriptionId } = useParams<{ subscriptionId: string }>();\r\n\r\n const baseRoute = '/administration/assessments';\r\n\r\n return (\r\n }\r\n />\r\n );\r\n};","import { useTranslation } from \"react-i18next\";\r\nimport { AssessmentType } from \"../../../api/main/models/codeOnly/AssessmentType\";\r\nimport { SubscriptionAssessmentsListBase } from \"../../subscriptionAssessments/SubscriptionAssessmentsListBase\";\r\nimport { useParams } from \"react-router\";\r\nimport { DistributorEditNavigation } from './DistributorEditNavigation';\r\n\r\n/**\r\n * List of actual assessments for a subscription\r\n */\r\nexport const DistributorTrainingList = () => {\r\n const { t } = useTranslation();\r\n\r\n const { subscriptionId } = useParams<{ subscriptionId: string }>();\r\n\r\n const baseRoute = '/administration/training';\r\n\r\n return (\r\n }\r\n />\r\n );\r\n};","import { Redirect } from 'react-router';\r\n\r\n\r\n/**\r\n * Default Distributor Administration home page.\r\n */\r\nexport const DistributorAdministrationHome = () => {\r\n\r\n return (\r\n <>\r\n \r\n \r\n );\r\n};","import { useCallback } from \"react\";\r\nimport { ConditionalFragment } from \"react-conditionalfragment\";\r\nimport { useTranslation } from \"react-i18next\";\r\nimport { Button, ButtonGroup, Col, Container, Row } from \"reactstrap\";\r\nimport { AssessmentType } from \"../../../api/main/models/codeOnly/AssessmentType\";\r\nimport { useAdministrationDashboardViewModel } from \"../../../api/main/dashboard/viewModels/useAdministrationDashboardViewModel\";\r\nimport { AlertOnErrors } from \"../../../shared/alertOnErrors\";\r\nimport { Background } from \"../../shared/background/Background\";\r\nimport { Banner } from \"../../shared/Banner\";\r\nimport { PillsNavBar } from \"../../shared/pillsNavBar/PillsNavBar\";\r\nimport { LoadingIndicator } from \"../../shared/LoadingIndicator\";\r\nimport { DistributorSubscriptionsDashboardTab } from \"../tabs/DistributorSubscriptionsDashboardTab\";\r\nimport { UserAssessmentAssignment } from \"../../../api/main/models/UserAssessmentAssignment\";\r\nimport { AssessmentSession } from \"../../../api/main/models/AssessmentSession\";\r\nimport { generateDashboardSummary as _generateDashboardSummary } from \"../utilities/generateDashboardSummary\";\r\nimport { useExpandedUserAssessmentAssignments } from \"../utilities/useExpandedUserAssessmentAssignments\";\r\nimport { useActiveDashboardAssessmentType } from \"../../../globalState/activeDashboardAssessmentType/useActiveDashboardAssessmentType\";\r\nimport { DashboardBackButton } from \"../backButton/DashboardBackButton\";\r\nimport { useCurrentUserOrEmulatedSubscriptionId } from \"../../../globalState/subscriptions/useCurrentUserOrEmulatedSubscriptionId\";\r\nimport { DistributorAdministrationNavigation } from \"../../subscriptions/Distributors/Administration/DistributorAdministrationNavigation\";\r\n\r\n/**\r\n * Dashboard for a subscription.\r\n */\r\nexport const DistributorAdministrationDashboard = () => {\r\n const { t } = useTranslation();\r\n\r\n const {\r\n data: {\r\n subscriptions,\r\n profiles,\r\n assessments,\r\n assessmentSessions,\r\n userAssessmentAssignments,\r\n userDriverMetrics: allUserDriverMetrics,\r\n },\r\n isLoading,\r\n errors: loadErrors\r\n } = useAdministrationDashboardViewModel();\r\n\r\n // Expand the UserAssessmentAssignments so we can work with them easier.\r\n const expandedUserAssessmentAssignments = useExpandedUserAssessmentAssignments(userAssessmentAssignments, profiles);\r\n\r\n const subscriptionId = useCurrentUserOrEmulatedSubscriptionId();\r\n\r\n\r\n // Allow the generation of dashboard summary data.\r\n const generateDashboardSummary = useCallback((\r\n sessionFilter: (session: AssessmentSession) => boolean,\r\n assignmentFilter: (assignment: UserAssessmentAssignment) => boolean,\r\n assessmentType: AssessmentType) => {\r\n // Filter by the passed in fitler.\r\n let mySessions = assessmentSessions?.filter(sessionFilter) ?? [];\r\n let myAssignments = expandedUserAssessmentAssignments?.filter(assignmentFilter) ?? [];\r\n\r\n // Filter by the passed in type.\r\n mySessions = mySessions.filter(session => {\r\n const assessment = assessments?.find(it => it.id === session.assessmentId);\r\n if (!assessment) {\r\n return false;\r\n }\r\n\r\n var isInDistributor: boolean = false;\r\n\r\n //want to filter to only subscriptions for the current distributor if we are managing one\r\n const currentDistributorsSubscriptions = subscriptions?.filter(item => item.distributorSubscriptionId === subscriptionId);\r\n const currentSubscription = subscriptions?.find(item => item.id === session.subscriptionId) ?? undefined;\r\n\r\n if (currentDistributorsSubscriptions?.find(item => item === currentSubscription) ?? undefined) {\r\n isInDistributor = true;\r\n }\r\n return assessment.assessmentType === assessmentType && isInDistributor;\r\n });\r\n\r\n myAssignments = myAssignments.filter(session => {\r\n const assessment = assessments?.find(it => it.id === session.assessmentId);\r\n if (!assessment) {\r\n return false;\r\n }\r\n\r\n var isInDistributor: boolean = false;\r\n //want to filter to only subscriptions for the current distributor if we are managing one\r\n const currentDistributorsSubscriptions = subscriptions?.filter(item => item.distributorSubscriptionId === subscriptionId);\r\n const currentSubscription = subscriptions?.find(item => item.id === session.subscriptionId) ?? undefined;\r\n\r\n if (currentDistributorsSubscriptions?.find(item => item === currentSubscription) ?? undefined) {\r\n isInDistributor = true;\r\n }\r\n return assessment.assessmentType === assessmentType && isInDistributor;\r\n });\r\n\r\n // Filter the driver metrics to contain only users that have assessments or assignments.\r\n const myUserDriverMetrics = allUserDriverMetrics?.filter(\r\n udm => !!mySessions.find(it => it.userId === udm.userId) || !!myAssignments.find(it => it.userId === udm.userId)\r\n ) ?? [];\r\n\r\n // Generate the summary data.\r\n const ret = _generateDashboardSummary(mySessions, assessments ?? [], profiles ?? [], myAssignments, myUserDriverMetrics, null);\r\n return ret;\r\n }, [assessmentSessions, assessments, profiles, expandedUserAssessmentAssignments, allUserDriverMetrics, subscriptionId, subscriptions]);\r\n\r\n // Track the active assessment type.\r\n const [activeAssessmentType, setActiveAssessmentType] = useActiveDashboardAssessmentType();\r\n return (\r\n \r\n \r\n \r\n \r\n

\r\n \r\n {t('distributorDashboard.heading.default', 'Distributor dashboard')}\r\n

\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n
\r\n
\r\n \r\n \r\n\r\n \r\n \r\n
\r\n );\r\n};\r\n","import { useTranslation } from \"react-i18next\";\r\nimport { UsersListBase } from \"../../users/UsersListBase\";\r\nimport { DistributorAdministrationNavigation } from './Administration/DistributorAdministrationNavigation';\r\nimport { useCurrentUserOrEmulatedSubscriptionId } from '../../../globalState/subscriptions/useCurrentUserOrEmulatedSubscriptionId';\r\n\r\n/**\r\n * List of distributor administrators.\r\n */\r\nexport const DistributorAdminsList = () => {\r\n const { t } = useTranslation();\r\n\r\n const baseRoute = `/manage/distributor/admins`\r\n\r\n const currentSubscriptionId = useCurrentUserOrEmulatedSubscriptionId();\r\n\r\n return (\r\n }\r\n teamColumnHidden={true}\r\n allowImport={true}\r\n />\r\n );\r\n};","import { CreateUserBase, EditUserBase } from \"../../../users/EditUserBase\";\r\nimport { useCurrentUserOrEmulatedSubscriptionId } from '../../../../globalState/subscriptions/useCurrentUserOrEmulatedSubscriptionId';\r\n\r\n/**\r\n * Create a distributor admin.\r\n */\r\nexport const CreateDistributorAdmin = () => {\r\n\r\n\r\n const currentSubscriptionId = useCurrentUserOrEmulatedSubscriptionId();\r\n\r\n return (\r\n ({ subscriptionId: currentSubscriptionId, undefined })}\r\n defaultRoleGroup=\"Distributor administrator\"\r\n filterRoleGroups={(groups) => groups.filter(item => item.id === 'Distributor administrator')}\r\n />);\r\n};\r\n\r\n/**\r\n * Edit a distributor admin.\r\n */\r\nexport const EditDistributorAdmin = () => (\r\n groups.filter(item => item.id === 'Distributor administrator')}\r\n />);","import { SubscriptionType } from \"../../../../api/main/models/codeOnly/SubscriptionType\";\r\nimport { SubscriptionsListBase } from \"../../SubscriptionsListBase\";\r\nimport { useTranslation } from \"react-i18next\";\r\nimport { DistributorAdministrationNavigation } from './DistributorAdministrationNavigation';\r\n\r\n/**\r\n * List of actual subscriptions.\r\n */\r\nexport const DistributorSubscriptionsList = () => {\r\n const { t } = useTranslation();\r\n\r\n return (\r\n }\r\n />\r\n );\r\n};","import { SubscriptionType } from \"../../../../api/main/models/codeOnly/SubscriptionType\";\r\nimport { CreateSubscriptionBase, EditSubscriptionBase } from \"../../EditSubscriptionBase\";\r\n\r\n/**\r\n * Create an actual Distributor.\r\n */\r\nexport const CreateDistributorSubscription = () => (\r\n ({ subscriptionType: SubscriptionType.Subscription })}\r\n isInDistributor={true}\r\n />);\r\n\r\n/**\r\n * Edit an actual Distributor.\r\n */\r\nexport const EditDistributorSubscription = () => ();","import { useTranslation } from \"react-i18next\";\r\nimport { AssessmentType } from \"../../../../api/main/models/codeOnly/AssessmentType\";\r\nimport { SubscriptionAssessmentsListBase } from \"../../../subscriptionAssessments/SubscriptionAssessmentsListBase\";\r\nimport { useParams } from \"react-router\";\r\nimport { DistributorSubscriptionEditNavigation } from './DistributorSubscriptionEditNavigation';\r\n\r\n/**\r\n * List of actual assessments.\r\n */\r\nexport const DistributorSubscriptionAssessmentsList = () => {\r\n const { t } = useTranslation();\r\n\r\n const { subscriptionId } = useParams<{ subscriptionId: string }>();\r\n\r\n const baseRoute = '/administration/assessments';\r\n\r\n return (\r\n }\r\n isDistributorSubscription={true}\r\n />\r\n );\r\n};","import { useTranslation } from \"react-i18next\";\r\nimport { AssessmentType } from \"../../../../api/main/models/codeOnly/AssessmentType\";\r\nimport { SubscriptionAssessmentsListBase } from \"../../../subscriptionAssessments/SubscriptionAssessmentsListBase\";\r\nimport { useParams } from \"react-router\";\r\nimport { DistributorSubscriptionEditNavigation } from './DistributorSubscriptionEditNavigation';\r\n\r\n/**\r\n * List of actual assessments for a subscription\r\n */\r\nexport const DistributorSubscriptionTrainingList = () => {\r\n const { t } = useTranslation();\r\n\r\n const { subscriptionId } = useParams<{ subscriptionId: string }>();\r\n\r\n const baseRoute = '/administration/training';\r\n\r\n return (\r\n }\r\n isDistributorSubscription={true}\r\n />\r\n );\r\n};","import gql from \"graphql-tag\";\r\nimport { Guid } from \"guid-string\";\r\nimport { sdkClientFields } from \"../generated/sdkClientFields\";\r\n\r\nexport const sdkClientFieldsFragment = gql`\r\n fragment sdkClientFields on SdkClient {\r\n id\r\n targetId\r\n targetType\r\n name\r\n apiSecret\r\n ipAllowListJson\r\n rolesJson\r\n archived\r\n }\r\n`;\r\n\r\n\r\nexport type SdkClient = Omit;\r\n\r\nexport const sdkClientDefaultValues = (): Partial => ({\r\n id: Guid.newGuid(),\r\n targetId: undefined,\r\n targetType: '',\r\n name: '',\r\n apiSecret: '',\r\n ipAllowListJson: '[]',\r\n rolesJson: '[\"API\"]',\r\n archived: false,\r\n});","import * as React from 'react';\r\nimport { useLazyQuery } from \"@apollo/react-hooks\";\r\nimport gql from \"graphql-tag\";\r\nimport { Guid } from \"guid-string\";\r\nimport { AsyncLoadResult, AsyncLoadOptions } from '../../../shared/abstractStore';\r\nimport { sdkClientQuery, sdkClientQueryVariables } from '../generated/sdkClientQuery';\r\nimport { sdkClientFieldsFragment } from '../models/SdkClient';\r\nimport { mainApiConfig } from '../../../configure/mainApiConfig';\r\n\r\n/**\r\n * Get a SdkClient from the store.\r\n * @param id\r\n * @param options\r\n */\r\nexport function useSdkClient(id: string | undefined | null, options: AsyncLoadOptions = {}): AsyncLoadResult {\r\n // Query the data we need form the api.\r\n const [load, { data, loading, error, refetch }] = useLazyQuery(\r\n gql`\r\n query sdkClientQuery ($id: ID!) {\r\n model: sdkClient(id: $id) {\r\n ...sdkClientFields\r\n }\r\n }\r\n\r\n ${sdkClientFieldsFragment}\r\n `,\r\n {\r\n variables: {\r\n id: id ?? Guid.empty,\r\n },\r\n fetchPolicy: options.fetchPolicy ?? mainApiConfig.defaultFetchPolicy,\r\n pollInterval: options.pollInterval,\r\n onCompleted: (data) => {\r\n if (options.onCompleted) {\r\n options.onCompleted(data);\r\n }\r\n }\r\n }\r\n );\r\n\r\n // Run the query (unless we are being lazy).\r\n React.useEffect(() => {\r\n if (!options.lazy) {\r\n load();\r\n }\r\n }, [options.lazy, load])\r\n\r\n // Return the results.\r\n const refresh = React.useCallback(async () => { !refetch ? await load() : await refetch(); }, [refetch, load]);\r\n return React.useMemo(() => ({\r\n data: data ?? ({} as any),\r\n refresh: refresh,\r\n isLoading: loading,\r\n errors: error\r\n }), [data, refresh, loading, error]);\r\n}\r\n","import { Button, Form, Label, FormGroup, Spinner, Input, Row, Col } from 'reactstrap';\r\nimport { AlertOnErrors } from '../../../shared/alertOnErrors';\r\nimport { LoadingIndicator } from '../../shared/LoadingIndicator';\r\nimport { useTranslation } from 'react-i18next';\r\nimport { FontAwesomeIcon } from '@fortawesome/react-fontawesome';\r\nimport { MainContainer } from '../../shared/MainContainer';\r\nimport { useParams, useHistory } from 'react-router';\r\nimport { FormButtons } from '../../shared/FormButtons';\r\nimport { ButtonAsync } from 'reactstrap-buttonasync';\r\nimport { useAsyncCallback } from 'react-use-async-callback';\r\nimport { useSdkClient } from '../../../api/main/sdkClients/useSdkClient';\r\nimport { useDeleteSdkClientCallback } from '../../../api/main/sdkClients/useDeleteSdkClientCallback';\r\nimport { ConditionalFragment } from 'react-conditionalfragment';\r\nimport { Banner } from '../../shared/Banner';\r\nimport { Background } from '../../shared/background/Background';\r\n\r\n/**\r\n * Delete a SdkClient and deactivate its integrations.\r\n */\r\nexport const DeleteSdkClient = () => {\r\n const { t } = useTranslation();\r\n const { id } = useParams<{ id: string }>();\r\n const { data: { model }, isLoading, errors: loadErrors } = useSdkClient(id);\r\n const [remove, { errors: removeErrors }] = useDeleteSdkClientCallback();\r\n const history = useHistory();\r\n\r\n const [onRemoveFormSubmit, { isExecuting: isRemoving, errors: removeFormErrors }] = useAsyncCallback(async () => {\r\n if (!model) {\r\n return;\r\n }\r\n\r\n await remove(model.id);\r\n\r\n history.goBack();\r\n }, [model, history]);\r\n\r\n return (\r\n \r\n \r\n \r\n \r\n

{t('deleteSdkClient.heading', 'Are you sure you want to delete this application\\'s API access?')}

\r\n \r\n \r\n \r\n \r\n \r\n \r\n
\r\n
\r\n\r\n \r\n \r\n\r\n
{ e.preventDefault(); onRemoveFormSubmit(); }}>\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n {t('common.deleting', 'Deleting...')}}>\r\n \r\n <> {t('common.delete', 'Delete')}\r\n \r\n \r\n \r\n \r\n
\r\n
\r\n
\r\n );\r\n};\r\n","import { useMutation } from \"@apollo/react-hooks\";\r\nimport { useAsyncCallback } from 'react-use-async-callback';\r\nimport gql from \"graphql-tag\";\r\nimport { AsyncActionStatus } from '../../../shared/abstractStore';\r\nimport { SdkClientCreateInput } from '../generated/globalTypes';\r\nimport { createSdkClientMutation, createSdkClientMutationVariables } from '../generated/createSdkClientMutation';\r\nimport { sdkClientFieldsFragment } from '../models/SdkClient';\r\n\r\n/**\r\n * Get a callback to create a SdkClient in the store.\r\n */\r\nexport function useCreateSdkClientCallback(): [(model: SdkClientCreateInput) => Promise, AsyncActionStatus] {\r\n const [mutationAction, { error }] = useMutation(\r\n gql`\r\n mutation createSdkClientMutation ($model: SdkClientCreateInput!) {\r\n createSdkClient(model: $model) {\r\n ...sdkClientFields\r\n }\r\n }\r\n\r\n ${sdkClientFieldsFragment}\r\n `\r\n );\r\n\r\n // Wrap the mutation in a standard callback.\r\n const [action, { isExecuting, errors: actionErrors }] = useAsyncCallback(async (model: SdkClientCreateInput) => {\r\n const result = await mutationAction({ variables: { model: model } });\r\n if (result.errors && result.errors.length) {\r\n throw result.errors;\r\n }\r\n }, [mutationAction]);\r\n\r\n return [action, { isExecuting: isExecuting, errors: error ? error.message : actionErrors }];\r\n}\r\n","import { useMutation } from \"@apollo/react-hooks\";\r\nimport { useAsyncCallback } from 'react-use-async-callback';\r\nimport gql from \"graphql-tag\";\r\nimport { AsyncActionStatus } from '../../../shared/abstractStore';\r\nimport { SdkClientUpdateInput } from '../generated/globalTypes';\r\nimport { updateSdkClientMutation, updateSdkClientMutationVariables } from '../generated/updateSdkClientMutation';\r\nimport { sdkClientFieldsFragment } from '../models/SdkClient';\r\n\r\n/**\r\n * Get a callback to update a SdkClient in the store.\r\n */\r\nexport function useUpdateSdkClientCallback(): [(id: string, model: SdkClientUpdateInput) => Promise, AsyncActionStatus] {\r\n const [mutationAction, { error }] = useMutation(\r\n gql`\r\n mutation updateSdkClientMutation ($model: SdkClientUpdateInput!) {\r\n updateSdkClient(model: $model) {\r\n ...sdkClientFields\r\n }\r\n }\r\n\r\n ${sdkClientFieldsFragment}\r\n `\r\n );\r\n\r\n // Wrap the mutation in a standard callback.\r\n const [action, { isExecuting, errors: actionErrors }] = useAsyncCallback(async (id: string, model: SdkClientUpdateInput) => {\r\n const result = await mutationAction({ variables: { model: { ...model, id: id } } });\r\n if (result.errors && result.errors.length) {\r\n throw result.errors;\r\n }\r\n }, [mutationAction]);\r\n\r\n return [action, { isExecuting: isExecuting, errors: error ? error.message : actionErrors }];\r\n}\r\n","import { useMemo, SetStateAction, useCallback, Dispatch } from \"react\";\r\n\r\n/**\r\n * Hook that parses json and provides useState style access to the parsed value and access to setting the value. \r\n **/\r\nexport function useJsonObject(json: string, onJsonChanged: (json: string) => void): [T, Dispatch>] {\r\n // Parse the json into an object and cast it as a T.\r\n const value = useMemo(() => JSON.parse(json), [json]) as T;\r\n\r\n // Return a setter that behaves like J\r\n const setValue = useCallback(newValue => {\r\n // Allow value to be a function so we have same API as useState\r\n let valueToStore = newValue;\r\n if (newValue instanceof Function) {\r\n valueToStore = newValue(value);\r\n }\r\n\r\n // Save state back to original source.\r\n const newJson = JSON.stringify(valueToStore);\r\n onJsonChanged(newJson);\r\n }, [value, onJsonChanged]);\r\n\r\n return [value, setValue];\r\n}\r\n","import { FontAwesomeIcon } from \"@fortawesome/react-fontawesome\";\r\nimport { Guid } from \"guid-string\";\r\nimport { useCallback, MouseEvent, useMemo } from \"react\";\r\nimport { useTranslation } from \"react-i18next\";\r\nimport { Button, Input, InputGroup, InputGroupAddon, InputProps, Tooltip } from \"reactstrap\";\r\nimport { useToggleState } from \"use-toggle-state\";\r\nimport \"./secretInput.scss\";\r\n\r\nexport interface SecretInputProps extends InputProps {\r\n valueWhenHidden?: string | number | readonly string[] | undefined,\r\n}\r\n\r\n/**\r\n * Input that hides it's contents as a secret unless revealed.\r\n */\r\nexport const SecretInput = (props: SecretInputProps) => {\r\n const {\r\n value,\r\n valueWhenHidden,\r\n readOnly = true, // Default is readOnly unless overriden.\r\n onClick: _onClick,\r\n ...rest\r\n } = props;\r\n\r\n const { t } = useTranslation();\r\n\r\n // Visiblity of the secret item.\r\n const [isVisible, toggleIsVisible] = useToggleState();\r\n\r\n // Need a uniqueId for the input so the tooltip can work.\r\n const uniqueId = useMemo(() => `secret-input-${Guid.newGuid()}`, []);\r\n\r\n // Toggle if we're showing the \"copied\" tooltip.\r\n const [copiedTooltipIsOpen, toggleCopiedTooltipOpen] = useToggleState();\r\n\r\n // Copy the secret value to the clipboard.\r\n const copyToClipboard = useCallback(() => {\r\n try {\r\n navigator.clipboard.writeText(value?.toString() ?? '');\r\n toggleCopiedTooltipOpen(true);\r\n setTimeout(() => toggleCopiedTooltipOpen(false), 2000);\r\n } catch (error) {\r\n }\r\n }, [value, toggleCopiedTooltipOpen]);\r\n\r\n // For the onClick event want to use the passed in event if we have one, otherwise we want to copy to the clipboard on click.\r\n const onClick = useCallback((event: MouseEvent) => {\r\n if (_onClick) {\r\n _onClick(event);\r\n } else {\r\n copyToClipboard();\r\n }\r\n }, [_onClick, copyToClipboard]);\r\n\r\n // Render the UI\r\n //\r\n return (\r\n <>\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n Hello\r\n \r\n \r\n \r\n \r\n {t('secretInput.copiedToClipboard', 'Copied to clipboard')}\r\n \r\n \r\n );\r\n};","/**\r\n * Service for generating API keys.\r\n */\r\nexport class ApiKeyGenerationService {\r\n private _applicationPrefix = 'ED'; // ED for Esitu Drive.\r\n private _secretLength = 42;\r\n\r\n /**\r\n * Generate an API key for targetId.\r\n * @param targetId\r\n */\r\n generateKey(id: string): string {\r\n const ret = `${this._applicationPrefix}.${id}.${this.generateSecret()}`;\r\n return ret;\r\n }\r\n\r\n /**\r\n * Generate a randomly generated secret for use in a API key.\r\n */\r\n private generateSecret(): string {\r\n // Get a list of all acceptable characters.\r\n const numberChars = \"0123456789\";\r\n const upperChars = \"ABCDEFGHIJKLMNOPQRSTUVWXYZ\";\r\n const lowerChars = \"abcdefghijklmnopqrstuvwxyz\";\r\n\r\n const allChars = `${numberChars}${upperChars}${lowerChars}`;\r\n\r\n let ret = '';\r\n while (ret.length < this._secretLength) {\r\n const random = Math.floor(Math.random() * (allChars.length));\r\n ret += allChars[random];\r\n }\r\n\r\n return ret;\r\n }\r\n}","import { Button, Row, Col, Form, Label, FormGroup, Spinner, Input } from 'reactstrap';\r\nimport { AlertOnErrors } from '../../../shared/alertOnErrors';\r\nimport { LoadingIndicator } from '../../shared/LoadingIndicator';\r\nimport { useTranslation } from 'react-i18next';\r\nimport { FontAwesomeIcon } from '@fortawesome/react-fontawesome';\r\nimport { MainContainer } from '../../shared/MainContainer';\r\nimport { useParams, useHistory } from 'react-router';\r\nimport { useSdkClient } from '../../../api/main/sdkClients/useSdkClient';\r\nimport { useChanges } from '../../../shared/useChanges';\r\nimport { useSaveSdkClientCallback } from '../../../api/main/sdkClients/useSaveSdkClientCallback';\r\nimport { useValidatorCallback } from 'pojo-validator-react';\r\nimport { ValidatedInput } from 'pojo-validator-reactstrap';\r\nimport { FormButtons } from '../../shared/FormButtons';\r\nimport { ButtonAsync } from 'reactstrap-buttonasync';\r\nimport { useAsyncCallback } from 'react-use-async-callback';\r\nimport { ConditionalFragment } from 'react-conditionalfragment';\r\nimport { Banner } from '../../shared/Banner';\r\nimport { Background } from '../../shared/background/Background';\r\nimport { useEffect } from 'react';\r\nimport { useJsonObject } from '../../../shared/useJsonObject';\r\nimport { SecretInput } from '../../shared/secretInput/SecretInput';\r\nimport { SdkClient, sdkClientDefaultValues } from '../../../api/main/models/SdkClient';\r\nimport { useCurrentUserOrEmulatedSubscriptionId } from '../../../globalState/subscriptions/useCurrentUserOrEmulatedSubscriptionId';\r\nimport { ApiKeyGenerationService } from '../../../services/ApiKeyGenerationService';\r\n\r\ninterface EditSdkClientProps {\r\n isCreate?: boolean,\r\n}\r\n\r\n/**\r\n * Create a new sdkClient.\r\n */\r\nexport const CreateSdkClient = () => ();\r\n\r\n/**\r\n * Edit a SdkClient.\r\n */\r\nexport const EditSdkClient = (props: EditSdkClientProps) => {\r\n const { isCreate } = props;\r\n\r\n const { t } = useTranslation();\r\n const { id } = useParams<{ id: string | undefined }>();\r\n const { data: { model: storeModel }, isLoading: _isLoading, errors: loadErrors } = useSdkClient(id);\r\n const isLoading = _isLoading;\r\n const { model, change, changes } = useChanges(storeModel, isCreate ? { ...sdkClientDefaultValues(), } : undefined);\r\n const [save, { errors: saveErrors }] = useSaveSdkClientCallback();\r\n const history = useHistory();\r\n\r\n // When we get the current subscription, set it in the SdkClient (if we are a create) and also at the same time generate a unique API key.\r\n const subscriptionId = useCurrentUserOrEmulatedSubscriptionId();\r\n useEffect(() => {\r\n if (!model) {\r\n return;\r\n }\r\n\r\n // Build a list of defaults we need to set.\r\n let changes: Partial | undefined = undefined;\r\n\r\n // If we haven't set a target, set it to the subscription if we have one.\r\n if (!model.targetId && !!subscriptionId) {\r\n changes = {\r\n ...(changes ?? {}),\r\n targetId: subscriptionId,\r\n targetType: 'SubscriptionId',\r\n };\r\n }\r\n\r\n // If we don't have an API key secret, generate one.\r\n if (!model.apiSecret && !!model.id) {\r\n const service = new ApiKeyGenerationService();\r\n const secret = service.generateKey(model.id);\r\n\r\n changes = {\r\n ...(changes ?? {}),\r\n apiSecret: secret,\r\n };\r\n }\r\n\r\n // Apply the changes to the model.\r\n if (changes) {\r\n change(changes);\r\n }\r\n }, [subscriptionId, change, model]);\r\n\r\n const [validate, validationErrors] = useValidatorCallback((validation, fieldsToCheck) => {\r\n const rules = {\r\n name: () => !model?.name ? t('editSdkClient.nameRequired', 'Name is required') : '',\r\n };\r\n\r\n validation.checkRules(rules, fieldsToCheck);\r\n }, [model]);\r\n\r\n const [saveForm, { isExecuting: isSaving, errors: saveFormErrors }] = useAsyncCallback(async () => {\r\n if (!validate()) {\r\n return;\r\n }\r\n\r\n await save(model.id, changes, !!isCreate);\r\n\r\n history.goBack();\r\n }, [validate, save, model, changes, isCreate, history]);\r\n\r\n // Maintenance of ip addresses (becomes JSON in the model.)\r\n const [ipAddresses, setIpAddresses] = useJsonObject>(model?.ipAllowListJson ?? '[]', json => change({ ipAllowListJson: json }))\r\n\r\n return (\r\n \r\n \r\n \r\n \r\n

\r\n {\r\n isCreate ? (\r\n <>{t('editSdkClient.createHeading', 'Add application API key')}\r\n ) : (\r\n <>{t('editSdkClient.editHeading', 'Edit application API key')}\r\n )\r\n }\r\n

\r\n \r\n \r\n \r\n \r\n \r\n \r\n
\r\n
\r\n\r\n \r\n \r\n\r\n
{ e.preventDefault(); saveForm(); }}>\r\n \r\n \r\n change({ name: e.currentTarget.value })} onBlur={e => validate('name')} validationErrors={validationErrors['name']} />\r\n \r\n \r\n \r\n \r\n \r\n\r\n \r\n \r\n\r\n
\r\n {\r\n ipAddresses.map((item, index) => (\r\n
\r\n \r\n \r\n {\r\n // Edit the right index in the array.\r\n setIpAddresses(prevState => {\r\n let newValue = [...prevState];\r\n newValue[index] = e.currentTarget.value;\r\n return newValue;\r\n })\r\n }}\r\n />\r\n \r\n \r\n \r\n \r\n \r\n
\r\n ))\r\n }\r\n
\r\n
\r\n \r\n
\r\n
\r\n\r\n \r\n \r\n {t('common.saving', 'Saving...')}}>\r\n \r\n <> {t('common.save', 'Save')}\r\n \r\n \r\n \r\n \r\n
\r\n
\r\n
\r\n );\r\n};\r\n","import * as React from 'react';\r\nimport { SdkClientCreateInput, SdkClientUpdateInput } from '../generated/globalTypes';\r\nimport { useSaveInStore, SaveInStoreOptions } from '../../../shared/useSaveInStore';\r\nimport { useCreateSdkClientCallback } from './useCreateSdkClientCallback';\r\nimport { useUpdateSdkClientCallback } from './useUpdateSdkClientCallback';\r\nimport { SdkClient } from '../models/SdkClient';\r\n\r\n/**\r\n * Get a callback to save a SdkClient in the store using either a create or update.\r\n */\r\nexport function useSaveSdkClientCallback(options: SaveInStoreOptions = {}) {\r\n const [_create, createStatus] = useCreateSdkClientCallback();\r\n const create = React.useCallback((model: Partial) => _create(model as SdkClientCreateInput), [_create]);\r\n\r\n const [_update, updateStatus] = useUpdateSdkClientCallback();\r\n const update = React.useCallback((id: string, changes: Partial) => _update(id, changes as SdkClientUpdateInput), [_update]);\r\n\r\n return useSaveInStore(\r\n [create, createStatus],\r\n [update, updateStatus],\r\n options\r\n );\r\n}\r\n","import gql from \"graphql-tag\";\r\nimport { Guid } from \"guid-string\";\r\nimport { sdkWebhookFields } from \"../generated/sdkWebhookFields\";\r\n\r\nexport const sdkWebhookFieldsFragment = gql`\r\n fragment sdkWebhookFields on SdkWebhook {\r\n id\r\n sdkClientId\r\n eventsJson\r\n url\r\n httpMethod\r\n headersJson\r\n archived\r\n }\r\n`;\r\n\r\n\r\nexport type SdkWebhook = Omit;\r\n\r\nexport const sdkWebhookDefaultValues = (): Partial => ({\r\n id: Guid.newGuid(),\r\n sdkClientId: undefined,\r\n eventsJson: '[]',\r\n url: '',\r\n httpMethod: 'POST',\r\n headersJson: '[]',\r\n archived: false,\r\n});","import { FontAwesomeIcon } from \"@fortawesome/react-fontawesome\";\r\nimport { ConditionalFragment } from \"react-conditionalfragment\";\r\nimport { useTranslation } from \"react-i18next\";\r\nimport { useHistory } from \"react-router\";\r\nimport { LinkContainer } from \"react-router-bootstrap\";\r\nimport { Button, ButtonDropdown, ButtonGroup, DropdownItem, DropdownMenu, DropdownToggle, Table } from \"reactstrap\";\r\nimport { useToggleStateArray } from \"use-toggle-state\";\r\nimport { SdkClient } from \"../../../api/main/models/SdkClient\";\r\nimport { NoResultsFound } from \"../../shared/NoResultsFound\";\r\nimport { SecretInput } from \"../../shared/secretInput/SecretInput\";\r\nimport { TableRowButtons } from \"../../shared/TableRowButtons\";\r\n\r\nexport interface SdkClientsTableProps {\r\n items: Array | undefined,\r\n isLoading: boolean,\r\n}\r\n\r\n/**\r\n * Table that shows the loaded SdkClients.\r\n */\r\nexport const SdkClientsTable = (props: SdkClientsTableProps) => {\r\n const {\r\n items,\r\n isLoading,\r\n } = props;\r\n\r\n const { t } = useTranslation();\r\n const history = useHistory();\r\n\r\n // Handle the dropdown of the menus..\r\n const [isMenuOpen, toggleMenuOpen] = useToggleStateArray([]);\r\n\r\n\r\n // Render the UI.\r\n //\r\n return (\r\n <>\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n {\r\n items?.map((item) => (\r\n { history.push(`/manage/sdk/applications/edit/${item.id}`); }}>\r\n \r\n \r\n \r\n\r\n \r\n \r\n ))\r\n }\r\n \r\n
\r\n {t('sdkClientsTable.table.headings.name', 'Application')}\r\n \r\n {t('sdkClientsTable.table.headings.secret', 'API key')}\r\n \r\n {t('sdkClientsTable.table.headings.ipAddresses', 'Allowed IP addresses')}\r\n  
\r\n {item.name}\r\n \r\n \r\n \r\n {\r\n (JSON.parse(item.ipAllowListJson) as Array).map((item, index) => (\r\n
\r\n {item}\r\n
\r\n ))\r\n }\r\n
\r\n \r\n \r\n \r\n \r\n \r\n toggleMenuOpen(item.id)}>\r\n \r\n {t('common.menuDropdown', 'More')}\r\n \r\n \r\n \r\n \r\n \r\n <> {t('common.delete', 'Delete')}\r\n \r\n \r\n \r\n \r\n \r\n \r\n
\r\n \r\n \r\n {t('sdkClientsTable.noApiKeys', 'You have not generated any API keys yet.')}\r\n \r\n \r\n\r\n
\r\n \r\n \r\n \r\n
\r\n \r\n );\r\n};","import { FontAwesomeIcon } from \"@fortawesome/react-fontawesome\";\r\nimport { ConditionalFragment } from \"react-conditionalfragment\";\r\nimport { useTranslation } from \"react-i18next\";\r\nimport { useHistory } from \"react-router\";\r\nimport { LinkContainer } from \"react-router-bootstrap\";\r\nimport { Button, ButtonDropdown, ButtonGroup, DropdownItem, DropdownMenu, DropdownToggle, Table } from \"reactstrap\";\r\nimport { useToggleStateArray } from \"use-toggle-state\";\r\nimport { SdkClient } from \"../../../api/main/models/SdkClient\";\r\nimport { SdkWebhook } from \"../../../api/main/models/SdkWebhook\";\r\nimport { NoResultsFound } from \"../../shared/NoResultsFound\";\r\nimport { TableRowButtons } from \"../../shared/TableRowButtons\";\r\n\r\nexport interface SdkWebhooksTableProps {\r\n items: Array | undefined,\r\n isLoading: boolean,\r\n sdkClients: Array | undefined,\r\n}\r\n\r\n/**\r\n * Table that shows the loaded SdkWebhooks.\r\n */\r\nexport const SdkWebhooksTable = (props: SdkWebhooksTableProps) => {\r\n const {\r\n items,\r\n isLoading,\r\n sdkClients,\r\n } = props;\r\n\r\n const { t } = useTranslation();\r\n const history = useHistory();\r\n\r\n // Handle the dropdown of the menus..\r\n const [isMenuOpen, toggleMenuOpen] = useToggleStateArray([]);\r\n\r\n\r\n // Render the UI.\r\n //\r\n return (\r\n <>\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n {\r\n items?.map((item) => (\r\n { history.push(`/manage/sdk/webhooks/edit/${item.id}`); }}>\r\n \r\n \r\n \r\n \r\n\r\n \r\n \r\n ))\r\n }\r\n \r\n
\r\n {t('sdkWebhooksTable.table.headings.sdkClient', 'Application')}\r\n \r\n {t('sdkWebhooksTable.table.headings.events', 'Events')}\r\n \r\n {t('sdkWebhooksTable.table.headings.url', 'Url')}\r\n \r\n {t('sdkWebhooksTable.table.headings.headers', 'Headers')}\r\n  
\r\n {sdkClients?.find(client => client.id === item.sdkClientId)?.name}\r\n \r\n {\r\n (JSON.parse(item.eventsJson) as Array).map((event, index) => (\r\n
\r\n {event}\r\n
\r\n ))\r\n }\r\n
\r\n {item.url}\r\n \r\n {\r\n (JSON.parse(item.headersJson) as Array<{ name: string, value: string }>).map((header, index) => (\r\n
\r\n {header.name}: {header.value}\r\n
\r\n ))\r\n }\r\n
\r\n \r\n \r\n \r\n \r\n \r\n toggleMenuOpen(item.id)}>\r\n \r\n {t('common.menuDropdown', 'More')}\r\n \r\n \r\n \r\n \r\n \r\n <> {t('common.delete', 'Delete')}\r\n \r\n \r\n \r\n \r\n \r\n \r\n
\r\n \r\n \r\n {t('sdkWebhooksTable.noApiKeys', 'You have not connected any webhooks yet.')}\r\n \r\n \r\n\r\n
\r\n \r\n \r\n \r\n
\r\n \r\n );\r\n};","import * as React from 'react';\r\nimport { useLazyQuery } from \"@apollo/react-hooks\";\r\nimport gql from \"graphql-tag\";\r\nimport { Guid } from \"guid-string\";\r\nimport { AsyncLoadResult, AsyncLoadOptions } from '../../../shared/abstractStore';\r\nimport { sdkWebhookQuery, sdkWebhookQueryVariables } from '../generated/sdkWebhookQuery';\r\nimport { sdkWebhookFieldsFragment } from '../models/SdkWebhook';\r\nimport { mainApiConfig } from '../../../configure/mainApiConfig';\r\n\r\n/**\r\n * Get a SdkWebhook from the store.\r\n * @param id\r\n * @param options\r\n */\r\nexport function useSdkWebhook(id: string | undefined | null, options: AsyncLoadOptions = {}): AsyncLoadResult {\r\n // Query the data we need form the api.\r\n const [load, { data, loading, error, refetch }] = useLazyQuery(\r\n gql`\r\n query sdkWebhookQuery ($id: ID!) {\r\n model: sdkWebhook(id: $id) {\r\n ...sdkWebhookFields\r\n }\r\n }\r\n\r\n ${sdkWebhookFieldsFragment}\r\n `,\r\n {\r\n variables: {\r\n id: id ?? Guid.empty,\r\n },\r\n fetchPolicy: options.fetchPolicy ?? mainApiConfig.defaultFetchPolicy,\r\n pollInterval: options.pollInterval,\r\n onCompleted: (data) => {\r\n if (options.onCompleted) {\r\n options.onCompleted(data);\r\n }\r\n }\r\n }\r\n );\r\n\r\n // Run the query (unless we are being lazy).\r\n React.useEffect(() => {\r\n if (!options.lazy) {\r\n load();\r\n }\r\n }, [options.lazy, load])\r\n\r\n // Return the results.\r\n const refresh = React.useCallback(async () => { !refetch ? await load() : await refetch(); }, [refetch, load]);\r\n return React.useMemo(() => ({\r\n data: data ?? ({} as any),\r\n refresh: refresh,\r\n isLoading: loading,\r\n errors: error\r\n }), [data, refresh, loading, error]);\r\n}\r\n","import * as React from 'react';\r\nimport { useLazyQuery } from \"@apollo/react-hooks\";\r\nimport gql from \"graphql-tag\";\r\nimport { editSdkWebhookSupportingDataQuery, editSdkWebhookSupportingDataQueryVariables } from '../../generated/editSdkWebhookSupportingDataQuery';\r\nimport { mainApiConfig } from '../../../../configure/mainApiConfig';\r\nimport { AsyncLoadOptions, AsyncLoadResult } from '../../../../shared/abstractStore';\r\nimport { sdkClientFieldsFragment } from '../../models/SdkClient';\r\nimport { Guid } from 'guid-string';\r\n\r\n/**\r\n * Get all the supporting data needed for EditSdkWebhook.\r\n * @param id\r\n * @param options\r\n */\r\nexport function useEditSdkWebhookSupportingData(subscriptionId: string | undefined | null, options: AsyncLoadOptions = {}): AsyncLoadResult {\r\n // Query data we need from the api.\r\n const [load, { data, loading, error, refetch }] = useLazyQuery(\r\n gql`\r\n query editSdkWebhookSupportingDataQuery ($subscriptionId: ID!) {\r\n sdkClients (targetId: $subscriptionId) {\r\n ...sdkClientFields\r\n }\r\n }\r\n\r\n ${sdkClientFieldsFragment}\r\n `,\r\n {\r\n\r\n variables: {\r\n subscriptionId: subscriptionId ?? Guid.empty,\r\n },\r\n fetchPolicy: options.fetchPolicy ?? mainApiConfig.defaultFetchPolicy,\r\n pollInterval: options.pollInterval,\r\n onCompleted: (data) => {\r\n if (options.onCompleted) {\r\n options.onCompleted(data);\r\n }\r\n }\r\n }\r\n );\r\n\r\n // Run the query (unless we are being lazy).\r\n React.useEffect(() => {\r\n if (!options.lazy) {\r\n load();\r\n }\r\n }, [options.lazy, load])\r\n\r\n // Return the results.\r\n const refresh = React.useCallback(async () => { !refetch ? await load() : await refetch(); }, [refetch, load]);\r\n return React.useMemo(() => ({\r\n data: data ?? ({} as any),\r\n refresh: refresh,\r\n isLoading: loading,\r\n errors: error,\r\n }), [data, refresh, loading, error]);\r\n}\r\n","import { Button, Form, Label, FormGroup, Spinner, Input, Row, Col } from 'reactstrap';\r\nimport { AlertOnErrors } from '../../../shared/alertOnErrors';\r\nimport { LoadingIndicator } from '../../shared/LoadingIndicator';\r\nimport { useTranslation } from 'react-i18next';\r\nimport { FontAwesomeIcon } from '@fortawesome/react-fontawesome';\r\nimport { MainContainer } from '../../shared/MainContainer';\r\nimport { useParams, useHistory } from 'react-router';\r\nimport { FormButtons } from '../../shared/FormButtons';\r\nimport { ButtonAsync } from 'reactstrap-buttonasync';\r\nimport { useAsyncCallback } from 'react-use-async-callback';\r\nimport { useSdkWebhook } from '../../../api/main/sdkWebhooks/useSdkWebhook';\r\nimport { useDeleteSdkWebhookCallback } from '../../../api/main/sdkWebhooks/useDeleteSdkWebhookCallback';\r\nimport { ConditionalFragment } from 'react-conditionalfragment';\r\nimport { Banner } from '../../shared/Banner';\r\nimport { Background } from '../../shared/background/Background';\r\nimport { useEditSdkWebhookSupportingData } from '../../../api/main/sdkWebhooks/viewModels/useEditSdkWebhookSupportingData';\r\nimport { useMemo } from 'react';\r\nimport { useCurrentUserOrEmulatedSubscriptionId } from '../../../globalState/subscriptions/useCurrentUserOrEmulatedSubscriptionId';\r\n\r\n/**\r\n * Delete a SdkWebhook and deactivate its integrations.\r\n */\r\nexport const DeleteSdkWebhook = () => {\r\n const { id } = useParams<{ id: string }>();\r\n\r\n const subscriptionId = useCurrentUserOrEmulatedSubscriptionId();\r\n\r\n const { t } = useTranslation();\r\n\r\n const { data: { model: model }, isLoading: _isLoading, errors: loadErrors } = useSdkWebhook(id);\r\n const { data: { sdkClients }, isLoading: isLoadingSupportingData, errors: supportingDataErrors } = useEditSdkWebhookSupportingData(subscriptionId);\r\n const isLoading = _isLoading || isLoadingSupportingData;\r\n\r\n const [remove, { errors: removeErrors }] = useDeleteSdkWebhookCallback();\r\n const history = useHistory();\r\n\r\n const [onRemoveFormSubmit, { isExecuting: isRemoving, errors: removeFormErrors }] = useAsyncCallback(async () => {\r\n if (!model) {\r\n return;\r\n }\r\n\r\n await remove(model.id);\r\n\r\n history.goBack();\r\n }, [model, history]);\r\n\r\n const sdkClient = useMemo(() => sdkClients?.find(it => it.id === model?.sdkClientId), [model?.sdkClientId, sdkClients]);\r\n\r\n return (\r\n \r\n \r\n \r\n \r\n

{t('deleteSdkWebhook.heading', 'Are you sure you want to delete this webhook connection?')}

\r\n \r\n \r\n \r\n \r\n \r\n \r\n
\r\n
\r\n\r\n \r\n \r\n\r\n
{ e.preventDefault(); onRemoveFormSubmit(); }}>\r\n \r\n \r\n \r\n \r\n\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n {t('common.deleting', 'Deleting...')}}>\r\n \r\n <> {t('common.delete', 'Delete')}\r\n \r\n \r\n \r\n \r\n
\r\n
\r\n
\r\n );\r\n};\r\n","import { TFunction } from \"i18next\";\r\n\r\n/**\r\n * HttpMethod\r\n */\r\nexport enum HttpMethod {\r\n Get = \"GET\",\r\n Post = \"POST\",\r\n Put = \"PUT\",\r\n Delete = \"DELETE\",\r\n Options = \"OPTIONS\",\r\n}\r\n\r\n/**\r\n * Return translated display name if its needed.\r\n * @param t\r\n */\r\nexport function httpMethodDisplayName(type: HttpMethod, t: TFunction): string {\r\n // We can just return the option unchanged.\r\n return type;\r\n}\r\n","import { useMutation } from \"@apollo/react-hooks\";\r\nimport { useAsyncCallback } from 'react-use-async-callback';\r\nimport gql from \"graphql-tag\";\r\nimport { AsyncActionStatus } from '../../../shared/abstractStore';\r\nimport { SdkWebhookCreateInput } from '../generated/globalTypes';\r\nimport { createSdkWebhookMutation, createSdkWebhookMutationVariables } from '../generated/createSdkWebhookMutation';\r\nimport { sdkWebhookFieldsFragment } from '../models/SdkWebhook';\r\n\r\n/**\r\n * Get a callback to create a SdkWebhook in the store.\r\n */\r\nexport function useCreateSdkWebhookCallback(): [(model: SdkWebhookCreateInput) => Promise, AsyncActionStatus] {\r\n const [mutationAction, { error }] = useMutation(\r\n gql`\r\n mutation createSdkWebhookMutation ($model: SdkWebhookCreateInput!) {\r\n createSdkWebhook(model: $model) {\r\n ...sdkWebhookFields\r\n }\r\n }\r\n\r\n ${sdkWebhookFieldsFragment}\r\n `\r\n );\r\n\r\n // Wrap the mutation in a standard callback.\r\n const [action, { isExecuting, errors: actionErrors }] = useAsyncCallback(async (model: SdkWebhookCreateInput) => {\r\n const result = await mutationAction({ variables: { model: model } });\r\n if (result.errors && result.errors.length) {\r\n throw result.errors;\r\n }\r\n }, [mutationAction]);\r\n\r\n return [action, { isExecuting: isExecuting, errors: error ? error.message : actionErrors }];\r\n}\r\n","import { useMutation } from \"@apollo/react-hooks\";\r\nimport { useAsyncCallback } from 'react-use-async-callback';\r\nimport gql from \"graphql-tag\";\r\nimport { AsyncActionStatus } from '../../../shared/abstractStore';\r\nimport { SdkWebhookUpdateInput } from '../generated/globalTypes';\r\nimport { updateSdkWebhookMutation, updateSdkWebhookMutationVariables } from '../generated/updateSdkWebhookMutation';\r\nimport { sdkWebhookFieldsFragment } from '../models/SdkWebhook';\r\n\r\n/**\r\n * Get a callback to update a SdkWebhook in the store.\r\n */\r\nexport function useUpdateSdkWebhookCallback(): [(id: string, model: SdkWebhookUpdateInput) => Promise, AsyncActionStatus] {\r\n const [mutationAction, { error }] = useMutation(\r\n gql`\r\n mutation updateSdkWebhookMutation ($model: SdkWebhookUpdateInput!) {\r\n updateSdkWebhook(model: $model) {\r\n ...sdkWebhookFields\r\n }\r\n }\r\n\r\n ${sdkWebhookFieldsFragment}\r\n `\r\n );\r\n\r\n // Wrap the mutation in a standard callback.\r\n const [action, { isExecuting, errors: actionErrors }] = useAsyncCallback(async (id: string, model: SdkWebhookUpdateInput) => {\r\n const result = await mutationAction({ variables: { model: { ...model, id: id } } });\r\n if (result.errors && result.errors.length) {\r\n throw result.errors;\r\n }\r\n }, [mutationAction]);\r\n\r\n return [action, { isExecuting: isExecuting, errors: error ? error.message : actionErrors }];\r\n}\r\n","import { FontAwesomeIcon } from \"@fortawesome/react-fontawesome\";\r\nimport { useCallback } from \"react\";\r\nimport { ConditionalFragment } from \"react-conditionalfragment\";\r\nimport { Button, ButtonGroup } from \"reactstrap\";\r\nimport \"./webhookEventTypeButton.scss\";\r\n\r\nexport interface WebhookEventTypeButtonProps {\r\n eventType: string,\r\n isSelected: boolean,\r\n toggleSelected?: () => void,\r\n gray?: boolean,\r\n readonly?: boolean,\r\n}\r\n\r\n/**\r\n * Button for toggling a question tag on or off.\r\n */\r\nexport const WebhookEventTypeButton = (props: WebhookEventTypeButtonProps) => {\r\n const {\r\n eventType,\r\n isSelected,\r\n toggleSelected,\r\n gray = false,\r\n readonly = false,\r\n } = props;\r\n\r\n const onToggleSelected = useCallback(() => {\r\n if (toggleSelected) {\r\n toggleSelected();\r\n }\r\n }, [toggleSelected]);\r\n\r\n return (\r\n \r\n \r\n \r\n \r\n \r\n \r\n );\r\n};\r\n","import { FontAwesomeIcon } from \"@fortawesome/react-fontawesome\";\r\nimport { useCallback, useMemo, KeyboardEvent } from \"react\";\r\nimport { ConditionalFragment } from \"react-conditionalfragment\";\r\nimport { useTranslation } from \"react-i18next\";\r\nimport { Col, Collapse, Row } from \"reactstrap\";\r\nimport { useToggleState } from \"use-toggle-state\";\r\nimport { WebhookEventTypeButton } from \"./WebhookEventTypeButton\";\r\nimport \"./webhookEventTypeSelector.scss\";\r\n\r\nexport interface WebhookEventTypeSelectorProps {\r\n eventTypes: Array,\r\n isSelected: (id: string) => boolean,\r\n toggleSelected?: (id: string) => void,\r\n}\r\n\r\n/**\r\n * Selector for toggling a question tag on or off.\r\n */\r\nexport const WebhookEventTypeSelector = (props: WebhookEventTypeSelectorProps) => {\r\n const {\r\n eventTypes,\r\n isSelected,\r\n toggleSelected,\r\n } = props;\r\n\r\n const { t } = useTranslation();\r\n\r\n const [isOpen, toggleOpen] = useToggleState();\r\n\r\n const selectedEventTypes = useMemo(() => {\r\n return eventTypes.filter(item => isSelected(item));\r\n }, [eventTypes, isSelected]);\r\n\r\n // Handle keyboard keys in a way that let us act select like.\r\n const keyDown = useCallback((event: KeyboardEvent) => {\r\n switch (event.key) {\r\n case 'Down':\r\n case 'ArrowDown':\r\n case 'ArrowUp':\r\n case 'Esc':\r\n case 'Escape':\r\n case ' ':\r\n case 'Enter':\r\n toggleOpen();\r\n break;\r\n default:\r\n break;\r\n }\r\n }, [toggleOpen]);\r\n\r\n return (\r\n
\r\n
toggleOpen()}>\r\n \r\n \r\n {\r\n selectedEventTypes\r\n .map(item => (\r\n \r\n ))\r\n }\r\n \r\n \r\n {t('webhookEventTypeSelector.nothingSelected', 'No events have been selected.')}\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n
\r\n \r\n
\r\n {\r\n eventTypes.map(item => (\r\n {\r\n if (toggleSelected) {\r\n toggleSelected(item);\r\n }\r\n }}\r\n />\r\n ))\r\n }\r\n
\r\n
\r\n
\r\n );\r\n};\r\n","import { Guid } from \"guid-string\";\r\n\r\n/**\r\n * One event type for a webhook.\r\n */\r\nexport interface SdkWebhookEventType {\r\n id: string,\r\n group: string,\r\n dataObject: any,\r\n}\r\n\r\n/**\r\n * All event types for a webhook.\r\n * \r\n * These event id's should be match those used in Services/SdkEvents/SdkEventManager_Events.cs for the backend.\r\n */\r\nexport const sdkWebhookEventTypes: Array = [\r\n // Core activities.\r\n { id: 'assessments.assigned', group: 'assessments', dataObject: { assessmentId: Guid.empty, userId: Guid.empty, subscriptionTeamId: Guid.empty, subscriptionId: Guid.empty, }, },\r\n { id: 'assessments.started', group: 'assessments', dataObject: { assessmentId: Guid.empty, userId: Guid.empty, subscriptionId: Guid.empty, }, },\r\n { id: 'assessments.complete', group: 'assessments', dataObject: { assessmentId: Guid.empty, userId: Guid.empty, subscriptionId: Guid.empty, }, },\r\n\r\n { id: 'training.assigned', group: 'training', dataObject: { assessmentId: Guid.empty, userId: Guid.empty, subscriptionTeamId: Guid.empty, subscriptionId: Guid.empty, }, },\r\n { id: 'training.started', group: 'training', dataObject: { assessmentId: Guid.empty, userId: Guid.empty, subscriptionId: Guid.empty, }, },\r\n { id: 'training.complete', group: 'training', dataObject: { assessmentId: Guid.empty, userId: Guid.empty, subscriptionId: Guid.empty, }, },\r\n\r\n // Maintenance.\r\n { id: 'users.created', group: 'users', dataObject: { userId: Guid.empty, profileId: Guid.empty, subscriptionId: Guid.empty, }, },\r\n { id: 'users.updated', group: 'users', dataObject: { userId: Guid.empty, profileId: Guid.empty, subscriptionId: Guid.empty, }, },\r\n { id: 'users.deleted', group: 'users', dataObject: { userId: Guid.empty, profileId: Guid.empty, subscriptionId: Guid.empty, }, },\r\n\r\n { id: 'subscriptionTeams.created', group: 'subscriptionTeams', dataObject: { subscriptionTeamId: Guid.empty, subscriptionId: Guid.empty, }, },\r\n { id: 'subscriptionTeams.updated', group: 'subscriptionTeams', dataObject: { subscriptionTeamId: Guid.empty, subscriptionId: Guid.empty, }, },\r\n { id: 'subscriptionTeams.deleted', group: 'subscriptionTeams', dataObject: { subscriptionTeamId: Guid.empty, subscriptionId: Guid.empty, }, },\r\n];\r\n","import { Button, Row, Col, Form, Label, FormGroup, Spinner, Input, Card } from 'reactstrap';\r\nimport { AlertOnErrors } from '../../../shared/alertOnErrors';\r\nimport { LoadingIndicator } from '../../shared/LoadingIndicator';\r\nimport { useTranslation } from 'react-i18next';\r\nimport { FontAwesomeIcon } from '@fortawesome/react-fontawesome';\r\nimport { MainContainer } from '../../shared/MainContainer';\r\nimport { useParams, useHistory } from 'react-router';\r\nimport { useSdkWebhook } from '../../../api/main/sdkWebhooks/useSdkWebhook';\r\nimport { useChanges } from '../../../shared/useChanges';\r\nimport { useSaveSdkWebhookCallback } from '../../../api/main/sdkWebhooks/useSaveSdkWebhookCallback';\r\nimport { useValidatorCallback } from 'pojo-validator-react';\r\nimport { ValidatedInput } from 'pojo-validator-reactstrap';\r\nimport { FormButtons } from '../../shared/FormButtons';\r\nimport { ButtonAsync } from 'reactstrap-buttonasync';\r\nimport { useAsyncCallback } from 'react-use-async-callback';\r\nimport { ConditionalFragment } from 'react-conditionalfragment';\r\nimport { Banner } from '../../shared/Banner';\r\nimport { Background } from '../../shared/background/Background';\r\nimport { useJsonObject } from '../../../shared/useJsonObject';\r\nimport { sdkWebhookDefaultValues } from '../../../api/main/models/SdkWebhook';\r\nimport { useCurrentUserOrEmulatedSubscriptionId } from '../../../globalState/subscriptions/useCurrentUserOrEmulatedSubscriptionId';\r\nimport { useEditSdkWebhookSupportingData } from '../../../api/main/sdkWebhooks/viewModels/useEditSdkWebhookSupportingData';\r\nimport { HttpMethod, httpMethodDisplayName } from '../../../api/main/models/codeOnly/HttpMethod';\r\nimport { useMemo } from 'react';\r\nimport moment from 'moment';\r\nimport { WebhookEventTypeSelector } from './webhookEventTypeSelector/WebhookEventTypeSelector';\r\nimport { sdkWebhookEventTypes } from '../../../api/main/models/codeOnly/SdkWebhookEventType';\r\nimport { Guid } from 'guid-string';\r\n\r\ninterface EditSdkWebhookProps {\r\n isCreate?: boolean,\r\n}\r\n\r\n/**\r\n * Create a new sdkWebhook.\r\n */\r\nexport const CreateSdkWebhook = () => ();\r\n\r\n/**\r\n * Edit a SdkWebhook.\r\n */\r\nexport const EditSdkWebhook = (props: EditSdkWebhookProps) => {\r\n const { isCreate } = props;\r\n\r\n const subscriptionId = useCurrentUserOrEmulatedSubscriptionId();\r\n\r\n const { t } = useTranslation();\r\n const { id } = useParams<{ id: string | undefined }>();\r\n const { data: { model: storeModel }, isLoading: _isLoading, errors: loadErrors } = useSdkWebhook(id);\r\n const { data: { sdkClients }, isLoading: isLoadingSupportingData, errors: supportingDataErrors } = useEditSdkWebhookSupportingData(subscriptionId);\r\n const isLoading = _isLoading || isLoadingSupportingData;\r\n const { model, change, changes } = useChanges(storeModel, isCreate ? { ...sdkWebhookDefaultValues(), } : undefined);\r\n const [save, { errors: saveErrors }] = useSaveSdkWebhookCallback();\r\n const history = useHistory();\r\n\r\n const [validate, validationErrors] = useValidatorCallback((validation, fieldsToCheck) => {\r\n const rules = {\r\n sdkClientId: () => !model?.sdkClientId ? t('editSdkWebhook.sdkClientId.required', 'SDK application is required') : '',\r\n url: () => !model?.url ? t('editSdkWebhook.url.required', 'URL is required') : '',\r\n httpMethod: () => !model?.httpMethod ? t('editSdkWebhook.httpMethod.required', 'HTTP method is required') : '',\r\n };\r\n\r\n validation.checkRules(rules, fieldsToCheck);\r\n }, [model]);\r\n\r\n const [saveForm, { isExecuting: isSaving, errors: saveFormErrors }] = useAsyncCallback(async () => {\r\n if (!validate()) {\r\n return;\r\n }\r\n\r\n await save(model.id, changes, !!isCreate);\r\n\r\n history.goBack();\r\n }, [validate, save, model, changes, isCreate, history]);\r\n\r\n // Maintenance of header details (becomes JSON in the model.)\r\n const [headers, setHeaders] = useJsonObject>(model?.headersJson ?? '[]', json => change({ headersJson: json }));\r\n\r\n // Maintenance of selected event types (becomes JSON in the model.)\r\n const [selectedEventTypes, setSelectedEventTypes] = useJsonObject>(model?.eventsJson ?? '[]', json => change({ eventsJson: json }));\r\n\r\n\r\n // Generate the sample JSON we will send.\r\n const { sampleJson, sampleQueryString } = useMemo(() => {\r\n // Use the selected events to generate the most overlapping detail we can from the event's combined data objects.\r\n let dataObject: any = null;\r\n for (const eventType of selectedEventTypes) {\r\n const myDataObject = sdkWebhookEventTypes.find(item => item.id === eventType)?.dataObject ?? {};\r\n\r\n // If we don't already have a data object, just use this one and move on.\r\n if (!dataObject) {\r\n dataObject = { ...myDataObject };\r\n } else {\r\n // We have a data object from another event type, so we want to create a new object with only keys that are in both.\r\n const myKeys = Object.keys(myDataObject);\r\n for (const key of Object.keys(dataObject)) {\r\n if (!myKeys.find(it => it === key)) {\r\n delete dataObject[key];\r\n }\r\n }\r\n }\r\n\r\n \r\n }\r\n\r\n // Generate an object that contains all properties.\r\n const eventData = {\r\n event: selectedEventTypes.length === 1 ? selectedEventTypes[0] : 'EVENT_NAME',\r\n eventDate: moment().toISOString(),\r\n uniqueId: Guid.empty,\r\n data: dataObject ?? {},\r\n };\r\n\r\n // Generate the json.\r\n const json = JSON.stringify(eventData, null, 4);\r\n\r\n // Generate the query string.\r\n let queryString = '';\r\n for (const key of Object.keys(eventData).filter(it => it !== 'data')) {\r\n queryString += `&${key}=${encodeURIComponent((eventData as any)[key] ?? '')}`;\r\n }\r\n for (const key of Object.keys(eventData.data)) {\r\n queryString += `&${key}=${encodeURIComponent((eventData as any).data[key] ?? '')}`;\r\n }\r\n queryString = `?${queryString.substr(1)}`;\r\n\r\n return {\r\n sampleJson: json,\r\n sampleQueryString: queryString,\r\n }\r\n }, [selectedEventTypes]);\r\n\r\n return (\r\n \r\n \r\n \r\n \r\n

\r\n {\r\n isCreate ? (\r\n <>{t('editSdkWebhook.createHeading', 'Add webhook connection')}\r\n ) : (\r\n <>{t('editSdkWebhook.editHeading', 'Edit webhook connection')}\r\n )\r\n }\r\n

\r\n \r\n \r\n \r\n \r\n \r\n \r\n
\r\n
\r\n\r\n \r\n \r\n\r\n
{ e.preventDefault(); saveForm(); }}>\r\n \r\n \r\n change({ sdkClientId: e.currentTarget.value })} onBlur={e => validate('sdkClientId')} validationErrors={validationErrors['sdkClientId']}>\r\n \r\n {\r\n sdkClients?.map(item => (\r\n \r\n ))\r\n }\r\n \r\n \r\n \r\n \r\n \r\n \r\n change({ httpMethod: e.currentTarget.value })} onBlur={e => validate('httpMethod')} validationErrors={validationErrors['httpMethod']}>\r\n {\r\n Object.values(HttpMethod)\r\n .map(item => (\r\n \r\n ))\r\n }\r\n \r\n \r\n \r\n change({ url: e.currentTarget.value })} onBlur={e => validate('url')} validationErrors={validationErrors['url']} />\r\n \r\n \r\n \r\n\r\n \r\n \r\n\r\n
\r\n {\r\n headers.map((item, index) => (\r\n
\r\n \r\n \r\n {\r\n // Edit the right index in the array.\r\n setHeaders(prevState => {\r\n let newValue = [...prevState];\r\n newValue[index].name = e.currentTarget.value;\r\n return newValue;\r\n })\r\n }}\r\n />\r\n \r\n \r\n {\r\n // Edit the right index in the array.\r\n setHeaders(prevState => {\r\n let newValue = [...prevState];\r\n newValue[index].value = e.currentTarget.value;\r\n return newValue;\r\n })\r\n }}\r\n />\r\n \r\n \r\n \r\n \r\n \r\n
\r\n ))\r\n }\r\n
\r\n
\r\n \r\n
\r\n
\r\n\r\n \r\n \r\n\r\n item.id)}\r\n isSelected={event => !!selectedEventTypes.find(it => it === event)}\r\n toggleSelected={event => setSelectedEventTypes(prevState => {\r\n if (!!prevState.find(it => it === event)) {\r\n return prevState.filter(it => it !== event);\r\n } else {\r\n let ret = [\r\n ...prevState,\r\n event,\r\n ];\r\n ret.sort();\r\n return ret;\r\n }\r\n })}\r\n />\r\n\r\n \r\n\r\n {/* Show either the body as JSON or the URL query string that will be passed based on the HTTP method being used. */}\r\n {\r\n model?.httpMethod === HttpMethod.Post || model?.httpMethod === HttpMethod.Put ? (\r\n \r\n \r\n\r\n \r\n
\r\n                                        {sampleJson}\r\n                                    
\r\n
\r\n
\r\n ) : (\r\n \r\n \r\n\r\n \r\n {sampleQueryString}\r\n \r\n \r\n )\r\n }\r\n\r\n \r\n \r\n {t('common.saving', 'Saving...')}}>\r\n \r\n <> {t('common.save', 'Save')}\r\n \r\n \r\n \r\n \r\n
\r\n
\r\n
\r\n );\r\n};\r\n","import * as React from 'react';\r\nimport { SdkWebhookCreateInput, SdkWebhookUpdateInput } from '../generated/globalTypes';\r\nimport { useSaveInStore, SaveInStoreOptions } from '../../../shared/useSaveInStore';\r\nimport { useCreateSdkWebhookCallback } from './useCreateSdkWebhookCallback';\r\nimport { useUpdateSdkWebhookCallback } from './useUpdateSdkWebhookCallback';\r\nimport { SdkWebhook } from '../models/SdkWebhook';\r\n\r\n/**\r\n * Get a callback to save a SdkWebhook in the store using either a create or update.\r\n */\r\nexport function useSaveSdkWebhookCallback(options: SaveInStoreOptions = {}) {\r\n const [_create, createStatus] = useCreateSdkWebhookCallback();\r\n const create = React.useCallback((model: Partial) => _create(model as SdkWebhookCreateInput), [_create]);\r\n\r\n const [_update, updateStatus] = useUpdateSdkWebhookCallback();\r\n const update = React.useCallback((id: string, changes: Partial) => _update(id, changes as SdkWebhookUpdateInput), [_update]);\r\n\r\n return useSaveInStore(\r\n [create, createStatus],\r\n [update, updateStatus],\r\n options\r\n );\r\n}\r\n","import { IdentityRoles } from \"../../configure/security/IdentityRoles\";\r\nimport { RouteEntry } from \"../../shared/routes\";\r\nimport { DeleteSdkClient } from \"./sdkClients/DeleteSdkClient\";\r\nimport { CreateSdkClient, EditSdkClient } from \"./sdkClients/EditSdkClient\";\r\nimport { SdkOverview } from \"./SdkOverview\";\r\nimport { DeleteSdkWebhook } from \"./sdkWebhooks/DeleteSdkWebhook\";\r\nimport { CreateSdkWebhook, EditSdkWebhook } from \"./sdkWebhooks/EditSdkWebhook\";\r\n\r\nexport const sdkRoutes: Array = [\r\n { path: '/manage/sdk', exact: true, component: SdkOverview, authorize: true, requireRole: IdentityRoles.SubscriptionAdministration },\r\n\r\n // SdkClient\r\n { path: '/manage/sdk/applications/add', exact: true, component: CreateSdkClient, authorize: true, requireRole: IdentityRoles.SubscriptionAdministration },\r\n { path: '/manage/sdk/applications/edit/:id', exact: true, component: EditSdkClient, authorize: true, requireRole: IdentityRoles.SubscriptionAdministration },\r\n { path: '/manage/sdk/applications/delete/:id', exact: true, component: DeleteSdkClient, authorize: true, requireRole: IdentityRoles.SubscriptionAdministration },\r\n\r\n // SdkWebhook\r\n { path: '/manage/sdk/webhooks/add', exact: true, component: CreateSdkWebhook, authorize: true, requireRole: IdentityRoles.SubscriptionAdministration },\r\n { path: '/manage/sdk/webhooks/edit/:id', exact: true, component: EditSdkWebhook, authorize: true, requireRole: IdentityRoles.SubscriptionAdministration },\r\n { path: '/manage/sdk/webhooks/delete/:id', exact: true, component: DeleteSdkWebhook, authorize: true, requireRole: IdentityRoles.SubscriptionAdministration },\r\n];\r\n","import { FontAwesomeIcon } from \"@fortawesome/react-fontawesome\";\r\nimport { ConditionalFragment } from \"react-conditionalfragment\";\r\nimport { useTranslation } from \"react-i18next\";\r\nimport { Card, CardBody, CardHeader, Col, Row } from \"reactstrap\";\r\nimport { useSdkOverviewViewModel } from \"../../api/main/sdkClients/viewModels/useSdkOverviewViewModel\";\r\nimport { useCurrentUserOrEmulatedSubscriptionId } from \"../../globalState/subscriptions/useCurrentUserOrEmulatedSubscriptionId\";\r\nimport { AlertOnErrors } from \"../../shared/alertOnErrors\";\r\nimport { ManageNavigation } from \"../manage/ManageNavigation\";\r\nimport { Background } from \"../shared/background/Background\";\r\nimport { Banner } from \"../shared/Banner\";\r\nimport { LoadingIndicator } from \"../shared/LoadingIndicator\";\r\nimport { MainContainer } from \"../shared/MainContainer\";\r\nimport { PillsNavBar } from \"../shared/pillsNavBar/PillsNavBar\";\r\nimport { StickyToolbar } from \"../shared/StickyToolbar\";\r\nimport { SdkClientsTable } from \"./sdkClients/SdkClientsTable\";\r\nimport \"./sdkOverview.scss\";\r\nimport { SdkWebhooksTable } from \"./sdkWebhooks/SdkWebhooksTable\";\r\n\r\n/**\r\n * SDK/API overview screen for a subscription.\r\n */\r\nexport const SdkOverview = () => {\r\n // We always show for the current subscription.\r\n const subscriptionId = useCurrentUserOrEmulatedSubscriptionId();\r\n\r\n const { t } = useTranslation();\r\n\r\n // Load the data.\r\n const {\r\n data: { subscription, sdkClients, sdkWebhooks },\r\n isLoading, errors: loadErrors\r\n } = useSdkOverviewViewModel(subscriptionId);\r\n\r\n // Render the UI.\r\n //\r\n return (\r\n \r\n \r\n \r\n \r\n \r\n

\r\n {t('sdkOverview.heading', 'API and SDK')}\r\n

\r\n \r\n \r\n \r\n \r\n \r\n \r\n
\r\n \r\n \r\n

\r\n {subscription?.companyName}\r\n

\r\n \r\n \r\n \r\n \r\n \r\n \r\n
\r\n
\r\n
\r\n\r\n \r\n \r\n\r\n {/* Introduction text */}\r\n
\r\n

\r\n {t('sdkOverview.documentation.heading', 'API and SDK documentation')}\r\n

\r\n
\r\n

\r\n {t('sdkOverview.documentation.info.p1', 'Esitu Drive allows integration with other applications and SaaS services through standards based APIs and webhooks.')}\r\n

\r\n

\r\n {t('sdkOverview.documentation.info.p2', 'You can use the available APIs to connect your own applications or SaaS services to Esitu Drive. These APIs give you access to query or mutate information within Esitu Drive on demand, on a schedule, or when events happen within your own application. To be notified of events happening within Esitu Drive, you can combine these APIs with webhooks to allow us to notify your application when events happen and let you react to those events in realtime.')}\r\n

\r\n

\r\n {t('sdkOverview.documentation.info.p3', 'Our API is entirely HTTP/HTTPS based so it can be used from any programming language, operating system, and environment. You just need to generate a unique API key for your application to get started.')}\r\n

\r\n

\r\n\r\n {t('sdkOverview.documentation.info.p4', 'We recommend each application/integration should be given its own unique API key to keep management and expiration of them secure.')}\r\n

\r\n

\r\n {t('sdkOverview.documentation.info.p5', 'API keys should be kept secret and passed in the HTTP header with every request in the format:')}\r\n
\r\n \r\n {t('sdkOverview.documentation.info.apiKeyHeaderFormat', 'x-api-key: YOURAPIKEY')}\r\n \r\n

\r\n

\r\n {t('sdkOverview.documentation.info.p6', 'For additional security each API key has a restricted list of IP addresses that access is allowed from. When developing be sure to allow your development IP address in the list as well as any IP addresses that may be used in your production environment.')}\r\n

\r\n

\r\n {t('sdkOverview.documentation.info.p7', 'We provide both GraphQL and REST apis to allow you to use the technology that is most compatible with your own applications and technical teams when building integrations. For full details of the APIs select the most suitable documentation link below. Each link includes an interactive playground environment to allow you to expiriment with the API directly from your browser.')}\r\n

\r\n
\r\n
\r\n\r\n {/* Links to documentation */}\r\n \r\n\r\n {/* SDK Clients */}\r\n \r\n \r\n {t('sdkOverview.sdkClients.heading', 'Application API keys')}\r\n \r\n \r\n \r\n \r\n \r\n\r\n {/* Webhooks */}\r\n \r\n \r\n {t('sdkOverview.sdkWebhooks.heading', 'Webhooks')}\r\n \r\n \r\n \r\n \r\n \r\n
\r\n
\r\n );\r\n};","import * as React from 'react';\r\nimport { useLazyQuery } from \"@apollo/react-hooks\";\r\nimport gql from \"graphql-tag\";\r\nimport { sdkOverviewViewModelQuery, sdkOverviewViewModelQueryVariables } from '../../generated/sdkOverviewViewModelQuery';\r\nimport { mainApiConfig } from '../../../../configure/mainApiConfig';\r\nimport { AsyncLoadOptions, AsyncLoadResult } from '../../../../shared/abstractStore';\r\nimport { sdkClientFieldsFragment } from '../../models/SdkClient';\r\nimport { sdkWebhookFieldsFragment } from '../../models/SdkWebhook';\r\nimport { subscriptionFieldsFragment } from '../../models/Subscription';\r\nimport { Guid } from 'guid-string';\r\n\r\n/**\r\n * Get a list of questions from the store with other details needed for the questions list.\r\n * @param id\r\n * @param options\r\n */\r\nexport function useSdkOverviewViewModel(subscriptionId: string | undefined | null, options: AsyncLoadOptions = {}): AsyncLoadResult {\r\n // Query data we need from the api.\r\n const [load, { data, loading, error, refetch }] = useLazyQuery(\r\n gql`\r\n query sdkOverviewViewModelQuery ($subscriptionId: ID!) {\r\n sdkClients (targetId: $subscriptionId) {\r\n ...sdkClientFields\r\n }\r\n\r\n sdkWebhooks (targetId: $subscriptionId) {\r\n ...sdkWebhookFields\r\n }\r\n\r\n subscription (id: $subscriptionId) {\r\n ...subscriptionFields\r\n }\r\n }\r\n\r\n ${sdkClientFieldsFragment}\r\n ${sdkWebhookFieldsFragment}\r\n ${subscriptionFieldsFragment}\r\n `,\r\n {\r\n\r\n variables: {\r\n subscriptionId: subscriptionId ?? Guid.empty,\r\n },\r\n fetchPolicy: options.fetchPolicy ?? mainApiConfig.defaultFetchPolicy,\r\n pollInterval: options.pollInterval,\r\n onCompleted: (data) => {\r\n if (options.onCompleted) {\r\n options.onCompleted(data);\r\n }\r\n }\r\n }\r\n );\r\n\r\n // Run the query (unless we are being lazy).\r\n React.useEffect(() => {\r\n if (!options.lazy) {\r\n load();\r\n }\r\n }, [options.lazy, load])\r\n\r\n // Return the results.\r\n const refresh = React.useCallback(async () => { !refetch ? await load() : await refetch(); }, [refetch, load]);\r\n return React.useMemo(() => ({\r\n data: data ?? ({} as any),\r\n refresh: refresh,\r\n isLoading: loading,\r\n errors: error,\r\n }), [data, refresh, loading, error]);\r\n}\r\n","import { useMutation } from \"@apollo/react-hooks\";\r\nimport { useAsyncCallback } from 'react-use-async-callback';\r\nimport gql from \"graphql-tag\";\r\nimport { AsyncActionStatus } from '../../../shared/abstractStore';\r\nimport { deleteSdkClientMutation, deleteSdkClientMutationVariables } from '../generated/deleteSdkClientMutation';\r\nimport { sdkClientFieldsFragment } from '../models/SdkClient';\r\n\r\n/**\r\n * Get a callback to delete a SdkClient in the store.\r\n */\r\nexport function useDeleteSdkClientCallback(): [(id: string) => Promise, AsyncActionStatus] {\r\n const [mutationAction, { error }] = useMutation(\r\n gql`\r\n mutation deleteSdkClientMutation ($id: ID!) {\r\n deleteSdkClient(id: $id) {\r\n ...sdkClientFields\r\n }\r\n }\r\n\r\n ${sdkClientFieldsFragment}\r\n `\r\n );\r\n\r\n // Wrap the mutation in a standard callback.\r\n const [action, { isExecuting, errors: actionErrors }] = useAsyncCallback(async (id: string) => {\r\n const result = await mutationAction({ variables: { id: id } });\r\n if (result.errors && result.errors.length) {\r\n throw result.errors;\r\n }\r\n }, [mutationAction]);\r\n\r\n return [action, { isExecuting: isExecuting, errors: error ? error.message : actionErrors }];\r\n}\r\n","import { useMutation } from \"@apollo/react-hooks\";\r\nimport { useAsyncCallback } from 'react-use-async-callback';\r\nimport gql from \"graphql-tag\";\r\nimport { AsyncActionStatus } from '../../../shared/abstractStore';\r\nimport { deleteSdkWebhookMutation, deleteSdkWebhookMutationVariables } from '../generated/deleteSdkWebhookMutation';\r\nimport { sdkWebhookFieldsFragment } from '../models/SdkWebhook';\r\n\r\n/**\r\n * Get a callback to delete a SdkWebhook in the store.\r\n */\r\nexport function useDeleteSdkWebhookCallback(): [(id: string) => Promise, AsyncActionStatus] {\r\n const [mutationAction, { error }] = useMutation(\r\n gql`\r\n mutation deleteSdkWebhookMutation ($id: ID!) {\r\n deleteSdkWebhook(id: $id) {\r\n ...sdkWebhookFields\r\n }\r\n }\r\n\r\n ${sdkWebhookFieldsFragment}\r\n `\r\n );\r\n\r\n // Wrap the mutation in a standard callback.\r\n const [action, { isExecuting, errors: actionErrors }] = useAsyncCallback(async (id: string) => {\r\n const result = await mutationAction({ variables: { id: id } });\r\n if (result.errors && result.errors.length) {\r\n throw result.errors;\r\n }\r\n }, [mutationAction]);\r\n\r\n return [action, { isExecuting: isExecuting, errors: error ? error.message : actionErrors }];\r\n}\r\n","import { RouteEntry } from \"../../shared/routes\";\r\nimport { TermsAndConditionsPage } from \"./TermsAndConditionsPage\";\r\nimport { PrivacyPolicyPage } from \"./PrivacyPolicyPage\";\r\nimport { CookiePolicyPage } from \"./CookiePolicyPage\";\r\n\r\nexport const cmsPageRoutes: Array = [\r\n { path: '/terms-and-conditions', exact: true, component: TermsAndConditionsPage, },\r\n { path: '/privacy-policy', exact: true, component: PrivacyPolicyPage, },\r\n { path: '/cookie-policy', exact: true, component: CookiePolicyPage, },\r\n];\r\n","import { useEffect } from 'react';\r\nimport { useTranslation } from 'react-i18next';\r\nimport { Col, Row } from 'reactstrap';\r\nimport { AlertOnErrors } from '../../shared/alertOnErrors';\r\nimport { Background } from '../shared/background/Background';\r\nimport { Banner } from '../shared/Banner';\r\nimport { MainContainer } from '../shared/MainContainer';\r\nimport { StickyToolbar } from '../shared/StickyToolbar';\r\nimport './termsAndConditionsPage.scss';\r\n\r\n/**\r\n * Terms & Conditions Page.\r\n */\r\nexport const TermsAndConditionsPage = () => {\r\n\r\n const { t } = useTranslation();\r\n\r\n useEffect(() => {\r\n window.scrollTo(0, 0);\r\n }, []);\r\n\r\n return (\r\n \r\n \r\n \r\n \r\n \r\n

{t(\"termsAndConditionsPage.title\", \"Terms & Conditions\")}

\r\n \r\n\r\n
\r\n
\r\n
\r\n\r\n \r\n \r\n\r\n
\r\n

{t(\"termsAndConditionsPage.heading\", \"Terms and Conditions\")}

\r\n

{t(\"termsAndConditionsPage.para.1\", \"This is a contract with Esitu Solutions Ltd, whose registered office is at 50 Shakespeare Street, Nottingham, NG1 4FQ, UK.\")}

\r\n

{t(\"termsAndConditionsPage.para.2\", \"You may contact us on info@esitusolutions.com\")}

\r\n

{t(\"termsAndConditionsPage.para.3\", \"Registration Number: 12783669\")}

\r\n

{t(\"termsAndConditionsPage.para.4\", \"VAT number: 380260809\")}

\r\n

{t(\"termsAndConditionsPage.para.5\", \"Esitu Solutions Limited is referred to in the Terms and Conditions as \\\"Esitu Solutions\\\", \\\"we\\\" or \\\"us\\\". \")}

\r\n

{t(\"termsAndConditionsPage.para.6\", \"These terms and conditions apply to products and services provided by Esitu Solutions Ltd. Please carefully read the following terms before accessing any of our products. By accessing the products or services (which includes accessing an online assessments or training modules) you accept and agree to all the covenants and conditions imposed in this agreement. If you do not agree to these terms, you may not access our products. \")}

\r\n
    \r\n
  1. {t(\"termsAndConditionsPage.subHeading.1\", \"Use of these Terms\")}\r\n
      \r\n
    1. {t(\"termsAndConditionsPage.para1.1\", \"These terms and conditions, together with the documents referred to in it, ('Terms of Use') set out the terms on which You may make use of the App (as defined below), Your rights and obligations, and those of Esitu Solutions Limited in relation to the App and its Content (as defined below). Use of the App includes use as a guest or as a registered user and includes downloading, streaming, accessing, browsing, or registering to use the App.\")}
    2. \r\n
    3. {t(\"termsAndConditionsPage.para1.2\", \"Please read these Terms of Use carefully before You start to use the App, as these will apply to Your use of the App.\")}
    4. \r\n
    5. {t(\"termsAndConditionsPage.para1.3\", \"By using the App, You confirm that you agree to these Terms of Use and You agree to comply with them. If You do not agree to these Terms of Use, You must not use the App.\")}
    6. \r\n
    \r\n\r\n
  2. \r\n
  3. {t(\"termsAndConditionsPage.subHeading.2\", \"Other Applicable Terms\")}\r\n
      \r\n
    1. {t(\"termsAndConditionsPage.para2.1\", \"These Terms of Use refer to the following additional terms, which also apply to your use of our site:\")}\r\n
        \r\n
      1. Our Privacy Policy, {t(\"termsAndConditionsPage.para2.1.1\", \" which sets out the terms on which We process any personal data we collect from You, or that You provide to Us. By using our App, You consent to such processing and You warrant that all data provided by You is accurate.\")}
      2. \r\n
      3. Our Cookie Policy, {t(\"termsAndConditionsPage.para2.1.2\", \" which sets out information about the cookies on the App.\")}
      4. \r\n
      \r\n
    2. \r\n
    \r\n\r\n
  4. \r\n
  5. {t(\"termsAndConditionsPage.subHeading.3\", \"Interpretation\")}\r\n
      \r\n
    1. {t(\"termsAndConditionsPage.para3.1\", \"The following definitions and rules of interpretation apply in these Terms of Use:\")}\r\n
        \r\n
      1. {t(\"termsAndConditionsPage.para3.1.1\", \"\\\"Content\\\" includes, but is not limited to, all text, graphics and images that appear on the App, the design, look and feel of the app itself and any other material published on the App.\")}
      2. \r\n
      3. {t(\"termsAndConditionsPage.para3.1.2\", \"\\\"Intellectual Property Rights\\\" means patents, utility models, rights to inventions, copyright and neighbouring and related rights, trade marks and service marks, business names and domain names, rights in get-up and trade dress, goodwill and the right to sue for passing off or unfair competition, rights in designs, database rights, rights to use, and protect the confidentiality of, confidential information (including know-how and trade secrets), and all other intellectual property rights, in each case whether registered or unregistered and including all applications and rights to apply for and be granted, renewals or extensions of, and rights to claim priority from, such rights and all similar or equivalent rights or forms of protection which subsist or will subsist now or in the future in any part of the world.\")}
      4. \r\n
      5. {t(\"termsAndConditionsPage.para3.1.3\", \"\\\"Personal Information\\\" means the information that You provide while using the mobile app, that We obtain from You. You may request a change to Your Personal Information by contacting Our customer support department on 07870406529\")}
      6. \r\n
      7. {t(\"termsAndConditionsPage.para3.1.4\", \"\\\"App\\\" means Our web application.\")}
      8. \r\n
      9. {t(\"termsAndConditionsPage.para3.1.5\", \"\\\"Third Party Content\\\" means the material on the App or accessed through the App that is controlled by parties other than Esitu Solutions Limited.\")}
      10. \r\n
      11. {t(\"termsAndConditionsPage.para3.1.6\", \"\\\"Us\\\" means Esitu Solutions Limited.\")}
      12. \r\n
      13. {t(\"termsAndConditionsPage.para3.1.7\", \"\\\"We\\\" means Esitu Solutions Limited.\")}
      14. \r\n
      15. {t(\"termsAndConditionsPage.para3.1.8\", \"\\\"You\\\" and \\\"Your\\\" means the person entering the Agreement or accessing the App as the case may be.\")}
      16. \r\n
      \r\n
    2. \r\n
    \r\n\r\n
  6. \r\n
  7. {t(\"termsAndConditionsPage.subHeading.4\", \"Changes to these Terms of Use\")}\r\n
      \r\n
    1. {t(\"termsAndConditionsPage.para4.1\", \"We may change these Terms of Use at any time.\")}
    2. \r\n
    3. {t(\"termsAndConditionsPage.para4.2\", \"It is Your responsibility to check these Terms of Use in case there are any changes. If You access and use the App after We have made a change to these Terms You shall be treated as having accepted the change.\")}
    4. \r\n
    \r\n\r\n
  8. \r\n
  9. {t(\"termsAndConditionsPage.subHeading.5\", \"Accuracy of Content\")}\r\n
      \r\n
    1. {t(\"termsAndConditionsPage.para5.1\", \"The App and Content is provided for Your general information only. It is not intended to amount to advice on which you should rely. You must obtain professional or specialist advice before taking, or refraining from, any action on the basis of the Content on the App.\")}
    2. \r\n
    3. {t(\"termsAndConditionsPage.para5.2\", \"Although we make reasonable efforts to update the information on our App, we make no representations, warranties or guarantees, whether express or implied that the Content on our App is accurate, complete or up-to-date. For example, distances on our website are calculated as a straight line from point to point, not driving distances using public roads.\")}
    4. \r\n
    5. {t(\"termsAndConditionsPage.para5.3\", \"We advise that, You should not plan to do, or refrain from doing, anything in reliance upon Content without first checking the accuracy of the relevant Content by some other means. For example, if You propose to establish an itinerary based on number of vehicles, You must check information of that type You obtain on the App with the relevant properties themselves. All such information on this App is necessarily subject to change, sometimes at short notice.\")}
    6. \r\n
    \r\n\r\n
  10. \r\n
  11. {t(\"termsAndConditionsPage.subHeading.6\", \" Third Party Content, \\\"Partners\\\" and Links from the App\")}\r\n
      \r\n
    1. {t(\"termsAndConditionsPage.para6.1\", \"Where the App contains links to other sites, mobile applications and/ or resources provided by third parties (\\\"Third Party Sites\\\"), these links are provided for your information only.\")}
    2. \r\n
    3. {t(\"termsAndConditionsPage.para6.2\", \"We have no control over the content of those sites or resources.\")}
    4. \r\n
    5. {t(\"termsAndConditionsPage.para6.3\", \"We are not responsible for the content of Third Party Sites linked to the App or for Third Party content. They are independent of Us, and their content is not endorsed or approved by Us.\")}
    6. \r\n
    7. {t(\"termsAndConditionsPage.para6.4\", \"\\\"Partners\\\" are persons (corporate or otherwise) with whom we have developed affinity products specifically to support Esitu Solutions Limited.\")}
    8. \r\n
    \r\n\r\n
  12. \r\n
  13. {t(\"termsAndConditionsPage.subHeading.7\", \"Contact Between Us\")}\r\n
      \r\n
    1. {t(\"termsAndConditionsPage.para7.1\", \"You are responsible for ensuring that Your instructions (including all the details We may require to carry out Your instructions) and any information You give to Us are accurate and complete. We shall not be liable for any loss or damage You suffer if they are in any way inaccurate or incomplete and Our records will be conclusive evidence of Your instructions unless We agree otherwise. Except where required to amend personal data that we process about you, we may in Our absolute discretion refuse to carry out any instruction or reverse any action taken by Us in response to any instruction.\")}
    2. \r\n
    3. {t(\"termsAndConditionsPage.para7.2\", \"To contact Us with enquiries or complaints about our App, please contact us at: info@esitusolutions.com or in writing to:\")}\r\n
      Dryden Enterprise Centre\r\n
      Dryden Street\r\n
      Nottingham\r\n
      NG1 4FQ\r\n
    4. \r\n
    \r\n\r\n
  14. \r\n
  15. {t(\"termsAndConditionsPage.subHeading.8\", \"Intellectual Property\")}\r\n
      \r\n
    1. {t(\"termsAndConditionsPage.para8.1\", \"Our App and the Intellectual Property Rights in the Content on the App are owned by or licensed to Us.\")}
    2. \r\n
    3. {t(\"termsAndConditionsPage.para8.2\", \"Certain names, words, images or logos identifying Us and the products and services featured in the App are the trade marks of Esitu Solutions Limited.\")}
    4. \r\n
    5. {t(\"termsAndConditionsPage.para8.3\", \"The names and logos of third parties mentioned in the App (whether that appears in the App or in third party content) may be the trade marks, trade names or unregistered trade marks of those third parties and they are used with the permission of such organisations.\")}
    6. \r\n
    7. {t(\"termsAndConditionsPage.para8.4\", \"You may view, print, download or store temporarily extracts from the App for Your own personal reference or for the purpose of applying to Us to access or use the products and services featured on the App. No other use (including, without limitation, the alteration, deletion, utilisation or extraction) of the Content and materials featured on the App is permitted without Our written permission. Otherwise, than as provided, the App cannot, whether in whole or as to any part, be copied, reproduced, distributed or transmitted in any medium (including, without limitation, by the internet) without Our written permission. You must not modify the paper or digital copies of any Content that you have printed off or downloaded in any way, and you must not use any illustrations, photographs, video or audio sequences or any graphics separately from any accompanying text.\")}
    8. \r\n
    9. {t(\"termsAndConditionsPage.para8.5\", \"Where downloads of third party software are made available on the App, they are owned by the third party licensor in question, and will be subject to any terms and conditions applied by the relevant third party.\")}
    10. \r\n
    11. {t(\"termsAndConditionsPage.para8.6\", \"The App may contain proprietary notices (such as moral rights and trade mark notices) and copyright information, the terms of which must be observed. Our status (and that of any identified contributors) as the authors of Content on the App must always be acknowledged.\")}
    12. \r\n
    13. {t(\"termsAndConditionsPage.para8.7\", \"You must not use any part of the Content on our App for commercial purposes without obtaining a licence to do so from us or our licensors.\")}
    14. \r\n
    15. {t(\"termsAndConditionsPage.para8.8\", \"If you print off, copy, download or modify any part of the Content of our App in breach of these Terms of Use, your right to use the App will cease immediately and you must, at our option, return or destroy any copies of the materials you have made.\")}
    16. \r\n
    \r\n\r\n
  16. \r\n
  17. {t(\"termsAndConditionsPage.subHeading.9\", \"Access to the App \")}\r\n
      \r\n
    1. {t(\"termsAndConditionsPage.para9.1\", \"Access to our App is chargeable.\")}
    2. \r\n
    3. {t(\"termsAndConditionsPage.para9.2\", \"In parts of the App You may be enabled to interact with other users or with Us, through (for example) message boards and email. You must ensure that any such interaction by You or through Your email address will not:\")}\r\n
        \r\n
      1. {t(\"termsAndConditionsPage.para9.2.1\", \"be capable of infringing the Intellectual Property Rights or other rights of any person;\")}
      2. \r\n
      3. {t(\"termsAndConditionsPage.para9.2.2\", \"breach any applicable law or regulation;\")}
      4. \r\n
      5. {t(\"termsAndConditionsPage.para9.2.3\", \"breach these Terms of Use;\")}
      6. \r\n
      7. {t(\"termsAndConditionsPage.para9.2.4\", \"be used fraudulently or amount to fraudulent misrepresentation; or\")}
      8. \r\n
      9. {t(\"termsAndConditionsPage.para9.2.5\", \"be perceived as inappropriate for the App, offensive or misleading.\")}
      10. \r\n
      \r\n
    4. \r\n
    5. {t(\"termsAndConditionsPage.para9.3\", \"We may remove any postings or other interaction at our entire discretion.\")}
    6. \r\n
    7. {t(\"termsAndConditionsPage.para9.4\", \"We have no obligation to monitor, censor or edit the content of any material transmitted or received by You or other users of the App. You are responsible for the content of any material You transmit.\")}
    8. \r\n
    9. {t(\"termsAndConditionsPage.para9.5\", \"\\\"Equipment\\\" means all such compatible equipment, software and communications lines (including any public communication lines) required by You to properly access the App.\")}
    10. \r\n
    11. {t(\"termsAndConditionsPage.para9.6\", \"You are responsible for making all arrangements necessary for you to have access to the App. You are responsible for obtaining and maintaining Your Equipment and for ensuring that it is compatible with the App. We have no responsibility or liability with respect to Your Equipment.\")}
    12. \r\n
    13. {t(\"termsAndConditionsPage.para9.7\", \"We may change the minimum specification required to access the App at any time. We give no guarantee that you will have access the App on your mobile device (or continue to have access to the App). We shall not be liable to You if any such change in specification results in Your Equipment becoming incompatible with the App or becoming unable to perform, within the App, all of the functions previously performed.\")}
    14. \r\n
    15. {t(\"termsAndConditionsPage.para9.8\", \"You will be responsible for the cost of all charges You incur in accessing and using the App. We shall have no liability to you in respect of any such charges, costs or expenses that you may incur.\")}
    16. \r\n
    17. {t(\"termsAndConditionsPage.para9.9\", \"If You access the App outside of a WIFI connection zone, You may incur data charges by using the App. By accessing the App outside of a WIFI connection zone You agree to allow the App access to use your 3G Data.\")}
    18. \r\n
    19. {t(\"termsAndConditionsPage.para9.10\", \"We do not guarantee that that App, or any Content on it, will always be available or be uninterrupted. Access to the App is permitted on a temporary basis. We may suspend, withdraw, discontinue or change all or any part of the App without notice. We will not be liable to You if for any reason our App is unavailable at any time or for any period. We do not guarantee the speed with which You will be able to access and use the App (as it will depend upon factors such as the specification of Your Equipment and the number of people using the App) or that You will have uninterrupted or continuous access to the App.\")}
    20. \r\n
    21. {t(\"termsAndConditionsPage.para9.11\", \"You must not:\")}\r\n
        \r\n
      1. {t(\"termsAndConditionsPage.para9.11.1\", \"introduce or attempt to introduce any virus or any other contaminant to the App or any of Our computer systems;\")}
      2. \r\n
      3. {t(\"termsAndConditionsPage.para9.11.2\", \"in any way attempt to access, alter, de-compile, reverse engineer, destroy or otherwise tamper with any part of the App or any of Our computer systems;\")}
      4. \r\n
      5. {t(\"termsAndConditionsPage.para9.11.3\", \"interfere with the use of another person's access to or use of the App;\")}
      6. \r\n
      7. {t(\"termsAndConditionsPage.para9.11.4\", \"obtain access to information relating to another person which is on Our computer system;\")}
      8. \r\n
      9. {t(\"termsAndConditionsPage.para9.11.5\", \"use or attempt to use the App or any of Our computer systems for any unlawful or immoral purpose.\")}
      10. \r\n
      \r\n
    22. \r\n
    23. {t(\"termsAndConditionsPage.para9.12\", \"We may suspend or terminate Your access and use (in whole or in part) of the App at any time with or without notice.\")}
    24. \r\n
    25. {t(\"termsAndConditionsPage.para9.13\", \"You are responsible for getting an appropriate connection with a telecommunications provider in order to access the App.\")}
    26. \r\n
    27. {t(\"termsAndConditionsPage.para9.14\", \"We shall control, direct and establish technical procedures for using the App (and We may vary them from time to time). You must follow Our instructions and adhere to Our procedures as given on the App when using any the App.\")}
    28. \r\n
    29. {t(\"termsAndConditionsPage.para9.15\", \"You must ensure that any material and / or information downloaded or otherwise obtained through the use of the App is at Your own discretion and that You will be responsible for any damage to Your Equipment or loss of data that results from the download of such material and / or data.\")}
    30. \r\n
    31. {t(\"termsAndConditionsPage.para9.16\", \"We shall use reasonable endeavours to keep the App free from viruses and corrupt files but We do not warrant or guarantee that the App is free from infection by viruses, bugs or anything else with contaminating or destructive properties. We recommend that You \\\"virus check\\\" all information sent to You by Us. We shall not be liable for any corrupt information sent to You by Us or for any corrupt information You send to Us. You are responsible for configuring your information technology, computer programmes and platform in order to access our site. You should use your own virus protection software.\")}
    32. \r\n
    33. {t(\"termsAndConditionsPage.para9.17\", \"You must not misuse Our App by knowingly introducing viruses, trojans, worms, logic bombs or other material which is malicious or technologically harmful. You must not attempt to gain unauthorised access to our App, the server on which our App is stored, or any server, computer or database connected to our App. You must not attack our App via a denial-of-service attack or a distributed denial-of service attack. By breaching this provision, you would commit a criminal offence under the Computer Misuse Act 1990. We will report any such breach to the relevant law enforcement authorities, and We will co-operate with those authorities by disclosing Your identity to them. In the event of such a breach, Your right to use our App will cease immediately.\")}
    34. \r\n
    35. {t(\"termsAndConditionsPage.para9.18\", \"You are also responsible for ensuring that all persons who access our App through your internet connection are aware of these Terms of Use and any other applicable terms and conditions, and that they comply with them.\")}
    36. \r\n
    37. {t(\"termsAndConditionsPage.para9.19\", \"We regularly update the App. However, We do not warrant that the content of the App or the products and services featured are available (either as featured or at all). The content of and the products and services featured in the App are subject to change at any time without notice.\")}
    38. \r\n
    \r\n\r\n
  18. \r\n
  19. {t(\"termsAndConditionsPage.subHeading.10\", \"Acceptable Use and Content Standards\")}\r\n
      \r\n
    1. {t(\"termsAndConditionsPage.para10.1\", \"You may use the App only for lawful purposes. You may not use the App:\")}\r\n
        \r\n
      1. {t(\"termsAndConditionsPage.para10.1.1\", \"In any way that breaches any applicable local, national or international law or regulation.\")}
      2. \r\n
      3. {t(\"termsAndConditionsPage.para10.1.2\", \"In any way that is unlawful or fraudulent or has any unlawful or fraudulent purpose or effect.\")}
      4. \r\n
      5. {t(\"termsAndConditionsPage.para10.1.3\", \"For the purpose of harming or attempting to harm minors in any way.\")}
      6. \r\n
      7. {t(\"termsAndConditionsPage.para10.1.4\", \"To send, knowingly receive, upload, download, use or re-use any material which does not comply with our content standards in clause 10.3 and 10.4 below.\")}
      8. \r\n
      9. {t(\"termsAndConditionsPage.para10.1.5\", \"To transmit, or procure the sending of, any unsolicited or unauthorised advertising or promotional material or any other form of similar solicitation (spam).\")}
      10. \r\n
      11. {t(\"termsAndConditionsPage.para10.1.6\", \"To knowingly transmit any data, send or upload any material that contains viruses, Trojan horses, worms, time-bombs, keystroke loggers, spyware, adware or any other harmful programs or similar computer code designed to adversely affect the operation of any computer software or hardware.\")}
      12. \r\n
      \r\n
    2. \r\n
    3. {t(\"termsAndConditionsPage.para10.2\", \"You also agree:\")}\r\n
        \r\n
      1. {t(\"termsAndConditionsPage.para10.2.1\", \"Not to access without authority, interfere with, damage or disrupt:\")}\r\n
          \r\n
        1. {t(\"termsAndConditionsPage.para10.2.1.1\", \"any part of the App;\")}
        2. \r\n
        3. {t(\"termsAndConditionsPage.para10.2.1.2\", \"any software used in the provision of the App; or\")}
        4. \r\n
        5. {t(\"termsAndConditionsPage.para10.2.1.3\", \"any equipment or network or software owned or used by any third party.\")}
        6. \r\n
        \r\n
      2. \r\n
      \r\n
    4. \r\n
    5. {t(\"termsAndConditionsPage.para10.3\", \"All material which you contribute to the App (contributions), and to social media which is linked to the App must:\")}\r\n
        \r\n
      1. {t(\"termsAndConditionsPage.para10.2.1.1\", \"Be accurate (where they state facts)\")}
      2. \r\n
      3. {t(\"termsAndConditionsPage.para10.2.1.1\", \"Be genuinely held (where they state opinions).\")}
      4. \r\n
      5. {t(\"termsAndConditionsPage.para10.2.1.1\", \"Comply with applicable law in the UK and in any country from which they are posted.\")}
      6. \r\n
      \r\n
    6. \r\n
    7. {t(\"termsAndConditionsPage.para10.4\", \"Contributions must not:\")}\r\n
        \r\n
      1. {t(\"termsAndConditionsPage.para10.4.1\", \"Contain any material which is defamatory of any person.\")}
      2. \r\n
      3. {t(\"termsAndConditionsPage.para10.4.2\", \"Contain any material which is obscene, offensive, hateful or inflammatory.\")}
      4. \r\n
      5. {t(\"termsAndConditionsPage.para10.4.2\", \"Promote sexually explicit material.\")}
      6. \r\n
      7. {t(\"termsAndConditionsPage.para10.4.4\", \"Promote violence.\")}
      8. \r\n
      9. {t(\"termsAndConditionsPage.para10.4.5\", \"Promote discrimination based on race, sex, religion, nationality, disability, sexual orientation or age.\")}
      10. \r\n
      11. {t(\"termsAndConditionsPage.para10.4.6\", \"Infringe any copyright, database right or trade mark of any other person.\")}
      12. \r\n
      13. {t(\"termsAndConditionsPage.para10.4.7\", \"Be likely to deceive any person.\")}
      14. \r\n
      15. {t(\"termsAndConditionsPage.para10.4.8\", \"Be made in breach of any legal duty owed to a third party, such as a contractual duty or a duty of confidence.\")}
      16. \r\n
      17. {t(\"termsAndConditionsPage.para10.4.9\", \"Promote any illegal activity.\")}
      18. \r\n
      19. {t(\"termsAndConditionsPage.para10.4.10\", \"Be threatening, abuse or invade another's privacy, or cause annoyance, inconvenience or needless anxiety.\")}
      20. \r\n
      21. {t(\"termsAndConditionsPage.para10.4.11\", \"Be likely to harass, upset, embarrass, alarm or annoy any other person.\")}
      22. \r\n
      23. {t(\"termsAndConditionsPage.para10.4.12\", \"Be used to impersonate any person, or to misrepresent your identity or affiliation with any person.\")}
      24. \r\n
      25. {t(\"termsAndConditionsPage.para10.4.13\", \"Give the impression that they emanate from us, if this is not the case.\")}
      26. \r\n
      27. {t(\"termsAndConditionsPage.para10.4.14\", \"Advocate, promote or assist any unlawful act such as (by way of example only) copyright infringement or computer misuse.\")}
      28. \r\n
      \r\n
    8. \r\n
    \r\n
  20. \r\n
  21. {t(\"termsAndConditionsPage.subHeading.11\", \"Liability\")}\r\n
      \r\n
    1. {t(\"termsAndConditionsPage.para11.1\", \"Nothing in these Terms of Use excludes or limits either party's liability for death or personal injury arising from that party's negligence, fraud or fraudulent misrepresentation or any other liability that cannot be excluded or limited by English law.\")}
    2. \r\n
    3. {t(\"termsAndConditionsPage.para11.2\", \"To the extent permitted by law, we exclude all conditions, warranties, representations or other terms which may apply to our App or any Content on it, whether express or implied.\")}
    4. \r\n
    5. {t(\"termsAndConditionsPage.para11.3\", \"Subject to clause 11.1, We shall not be liable to You for any loss or damage, whether in contract, tort (including negligence), breach of statutory duty, or otherwise, even if foreseeable, arising under or in connection with:\")}\r\n
        \r\n
      1. {t(\"termsAndConditionsPage.para11.3.1\", \"Use or, or inability to use, the App; or\")}
      2. \r\n
      3. {t(\"termsAndConditionsPage.para11.3.2\", \"Use of, or reliance on any Content displayed on the App.\")}
      4. \r\n
      \r\n
    6. \r\n
    7. {t(\"termsAndConditionsPage.para11.4\", \"If you are a business user, please note that in particular, we will not be liable for:\")}\r\n
        \r\n
      1. {t(\"termsAndConditionsPage.para11.4.1\", \"Loss of profits, sales, business or revenue;\")}
      2. \r\n
      3. {t(\"termsAndConditionsPage.para11.4.2\", \"Business interruption;\")}
      4. \r\n
      5. {t(\"termsAndConditionsPage.para11.4.3\", \"Loss of anticipated savings;\")}
      6. \r\n
      7. {t(\"termsAndConditionsPage.para11.4.4\", \"Loss of business opportunity, goodwill or reputation; or\")}
      8. \r\n
      9. {t(\"termsAndConditionsPage.para11.4.5\", \"Any indirect or consequential loss or damage.\")}
      10. \r\n
      \r\n
    8. \r\n
    9. {t(\"termsAndConditionsPage.para11.5\", \"If you are a consumer user, please note that we only provide our App for domestic and private use. You agree not to use the App for any commercial or business purposes, and We have no liability to You for any loss of profit, loss of business, business interruption, or loss of business opportunity.\")}
    10. \r\n
    11. {t(\"termsAndConditionsPage.para11.6\", \"We will not be liable for any loss or damage caused by a virus, distributed denial-of-service attack, or other technologically harmful material that may infect Your computer equipment, computer programs, data or other proprietary material due to Your use of the App or to Your downloading of any content on it, or on any website linked to it.\")}
    12. \r\n
    13. {t(\"termsAndConditionsPage.para11.7\", \"We assume no responsibility for the content of websites linked on our site. Such links should not be interpreted as endorsement by us of those linked websites. We will not be liable for any loss or damage that may arise from Your use of them.\")}
    14. \r\n
    15. {t(\"termsAndConditionsPage.para11.8\", \"Different limitations and exclusions of liability will apply to liability arising as a result of the supply of any goods by use to you, which will be set out in our Terms and conditions of supply.\")}
    16. \r\n
    \r\n\r\n
  22. \r\n
  23. {t(\"termsAndConditionsPage.subHeading.12\", \"Generally\")}\r\n
      \r\n
    1. {t(\"termsAndConditionsPage.para12.1\", \"Each of these conditions is separate from all other conditions, so that if one condition is found to be void or otherwise unenforceable it will not affect the validity of any of the others.\")}
    2. \r\n
    3. {t(\"termsAndConditionsPage.para12.2\", \"If We do not enforce any of the rights We have under this Agreement, or if We delay in enforcing them, that does not prevent Us from taking any action to enforce Our rights in the future.\")}
    4. \r\n
    \r\n
  24. \r\n
  25. {t(\"termsAndConditionsPage.subHeading.13\", \"Applicable Law\")}\r\n
      \r\n
    1. {t(\"termsAndConditionsPage.para13.1\", \"If you are a consumer, please note that these Terms of Use, its subject matter and its formation, are governed by English law. You and We both agree to that the courts of England and Wales will have exclusive jurisdiction.\")}
    2. \r\n
    3. {t(\"termsAndConditionsPage.para13.2\", \"If You are a business, these Terms of Use, its subject matter and its formation (and any non-contractual disputes or claims) are governed by English law. We both agree to the exclusive jurisdiction of the courts of England and Wales.\")}
    4. \r\n
    \r\n
  26. \r\n
  27. {t(\"termsAndConditionsPage.subHeading.14\", \"Queries or Complaints\")}\r\n
      \r\n
    1. {t(\"termsAndConditionsPage.para14.1\", \"If you have any queries or complaints about the App or these Terms of Use, please contact Us via the feedback button in the App, by email (info@esitusolutions.com), by phone on [07870406529], or by writing to us at:\")}\r\n
      Dryden Enterprise Centre\r\n
      Dryden Street\r\n
      Nottingham\r\n
      NG1 4FQ\r\n
    2. \r\n
    3. {t(\"termsAndConditionsPage.para14.2\", \"If you contact us then we will make every effort to respond to You directly, however, due to email volumes we may not always be able to respond directly to every user. We will take on board email feedback and ensure it feeds into future developments of the App.\")}
    4. \r\n
    \r\n
  28. \r\n
    \r\n

    Consent from end users in the E.U. for the transfer, storage, and use of their information in the the United States and other countries where Twitter and/or Crashlytics (as applicable) operate.

    \r\n
\r\n\r\n
\r\n
\r\n
\r\n );\r\n};\r\n\r\n\r\n \r\n\r\n \r\n","import { useCallback, useEffect } from 'react';\r\nimport { useTranslation } from 'react-i18next';\r\nimport { Col, Row, } from 'reactstrap';\r\nimport { AlertOnErrors } from '../../shared/alertOnErrors';\r\nimport { Background } from '../shared/background/Background';\r\nimport { Banner } from '../shared/Banner';\r\nimport { MainContainer } from '../shared/MainContainer';\r\nimport { StickyToolbar } from '../shared/StickyToolbar';\r\nimport './privacyPolicyPage.scss';\r\n\r\n/**\r\n * Privacy Policy Page.\r\n */\r\nexport const PrivacyPolicyPage = () => {\r\n\r\n const { t } = useTranslation();\r\n\r\n useEffect(() => {\r\n window.scrollTo(0, 0);\r\n }, []);\r\n\r\n // a formatted table with a lower case alpha in the first column and the item in the second column\r\n // presents a a pseudo ordered list\r\n const LowerAlphaList = useCallback((props: {\r\n listItems: object[],\r\n }) => {\r\n const { listItems } = props;\r\n const alphaCharacters: Array = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'y'];\r\n\r\n return (\r\n\r\n \r\n \r\n {\r\n listItems.map((item, index) => {\r\n return (\r\n \r\n \r\n \r\n \r\n );\r\n })\r\n }\r\n \r\n
{alphaCharacters[index]}){item}
\r\n );\r\n\r\n }, []);\r\n\r\n return (\r\n \r\n \r\n \r\n \r\n \r\n

{t(\"privacyPolicyPage.title\", \"Privacy Policy\")}

\r\n \r\n\r\n
\r\n
\r\n
\r\n\r\n \r\n \r\n
\r\n

{t(\"privacyPolicyPage.heading\", \"Privacy Notice\")}

\r\n\r\n

{t(\"privacyPolicyPage.background.header\", \"Introduction\")}

\r\n

{t(\"privacyPolicyPage.background.paragraph.1\", \"Welcome to Esitu Solutions Limited privacy policy.\")}

\r\n

{t(\"privacyPolicyPage.background.paragraph.2\", \"The Esitu Solutions Limited respects your privacy and is committed to protecting your personal data. This privacy policy will inform you as to how we look after your personal data when you visit our website (regardless of where you visit it from) and tell you about your privacy rights and how the law protects you.\")}

\r\n

{t(\"privacyPolicyPage.background.paragraph.3\", \"This privacy policy is provided in a layered format so you can click through to the specific areas set out below. Please also use the Glossary to understand the meaning of some of the terms used in this privacy policy.\")}

\r\n\r\n { /*gave the contents a margin to seperate it from the start of the main page list, this may need to be done in a better way*/ }\r\n
    \r\n
  1. {t(\"privacyPolicyPage.content.link.1\", \"IMPORTANT INFORMATION AND WHO WE ARE\")}
  2. \r\n
  3. {t(\"privacyPolicyPage.content.link.2\", \"THE DATA WE COLLECT ABOUT YOU\")}
  4. \r\n
  5. {t(\"privacyPolicyPage.content.link.3\", \"HOW IS YOUR PERSONAL DATA COLLECTED?\")}
  6. \r\n
  7. {t(\"privacyPolicyPage.content.link.4\", \"HOW WE USE YOUR PERSONAL DATA\")}
  8. \r\n
  9. {t(\"privacyPolicyPage.content.link.5\", \"DISCLOSURES OF YOUR PERSONAL DATA\")}
  10. \r\n
  11. {t(\"privacyPolicyPage.content.link.6\", \"INTERNATIONAL TRANSFERS\")}
  12. \r\n
  13. {t(\"privacyPolicyPage.content.link.7\", \"DATA SECURITY\")}
  14. \r\n
  15. {t(\"privacyPolicyPage.content.link.8\", \"DATA RETENTION\")}
  16. \r\n
  17. {t(\"privacyPolicyPage.content.link.9\", \"YOUR LEGAL RIGHTS\")}
  18. \r\n
  19. {t(\"privacyPolicyPage.content.link.10\", \"GLOSSARY\")}
  20. \r\n
\r\n\r\n
    \r\n
  1. {t(\"privacyPolicyPage.subHeading.1\", \"Important information and who we are\")}\r\n

    {t(\"privacyPolicyPage.paragraph1.1.header\", \"Purpose of this privacy policy\")}

    \r\n

    {t(\"privacyPolicyPage.paragraph1.1.1\", \"This privacy policy aims to give you information on how Esitu Solutions Limited collects and processes your personal data through your use of this website, including any data you may provide through this website when you sign up to our newsletter or purchase a product or service.\")}

    \r\n

    {t(\"privacyPolicyPage.paragraph1.1.2\", \"This website is not intended for children and we do not knowingly collect data relating to children.\")}

    \r\n

    {t(\"privacyPolicyPage.paragraph1.1.3\", \"It is important that you read this privacy policy together with any other privacy policy or fair processing policy we may provide on specific occasions when we are collecting or processing personal data about you so that you are fully aware of how and why we are using your data. This privacy policy supplements other notices and privacy policies and is not intended to override them.\")}

    \r\n\r\n

    {t(\"privacyPolicyPage.paragraph1.2.header\", \"Controller\")}

    \r\n

    {t(\"privacyPolicyPage.paragraph1.2.1\", \"The Esitu Solutions Limited is the controller and is registered with the Information Commissioners Office (ICO) under reference number ZB097590 and is responsible for your personal data in this privacy policy.\")}

    \r\n

    {t(\"privacyPolicyPage.paragraph1.2.2\", \"We have appointed a data privacy manager who is responsible for overseeing questions in relation to this privacy policy. If you have any questions about this privacy policy, including any requests to exercise your legal rights, please contact the data privacy manager using the details set out below.\")}

    \r\n\r\n

    {t(\"privacyPolicyPage.paragraph1.3.header\", \"Contact details\")}

    \r\n

    {t(\"privacyPolicyPage.paragraph1.3.1\", \"If you have any questions about this privacy policy or our privacy practices, please contact our data privacy manager in the following ways:\")}

    \r\n

    {t(\"privacyPolicyPage.paragraph1.3.2\", \"Full name of legal entity: Esitu Solutions Limited\")}

    \r\n

    {t(\"privacyPolicyPage.paragraph1.3.3\", \"Email address: victoria@esitusolution.com\")}

    \r\n

    {t(\"privacyPolicyPage.paragraph1.3.4\", \"Postal address: Dryden Enterprise Centre, Dryden Street, Nottingham, England, NG1 4FQ\")}

    \r\n

    {t(\"privacyPolicyPage.paragraph1.3.5\", \"You have the right to make a complaint at any time to the Information Commissioner's Office (ICO), the UK supervisory authority for data protection issues (www.ico.org.uk). We would, however, appreciate the chance to deal with your concerns before you approach the ICO so please contact us in the first instance.\")}

    \r\n\r\n

    {t(\"privacyPolicyPage.paragraph1.4.header\", \"Changes to the privacy policy and your duty to inform us of changes\")}

    \r\n

    {t(\"privacyPolicyPage.paragraph1.4.1\", \"We keep our privacy policy under regular review. This version was last updated on August 2022.\")}

    \r\n

    {t(\"privacyPolicyPage.paragraph1.4.2\", \"It is important that the personal data we hold about you is accurate and current. Please keep us informed if your personal data changes during your relationship with us.\")}

    \r\n\r\n

    {t(\"privacyPolicyPage.paragraph1.5.header\", \"Third-party links\")}

    \r\n

    {t(\"privacyPolicyPage.paragraph1.5.1\", \"This website may include links to third-party websites, plug-ins and applications. Clicking on those links or enabling those connections may allow third parties to collect or share technical data about you. We do not control these third-party websites and are not responsible for their privacy statements. When you leave our website, we encourage you to read the privacy policy of every website you visit.\")}

    \r\n\r\n
  2. \r\n
  3. {t(\"privacyPolicyPage.subHeading.2\", \"The data we collect about you\")}\r\n

    {t(\"privacyPolicyPage.paragraph2.1\", \"Personal data, or personal information, means any information about an individual from which that person can be identified. It does not include data where the identity has been removed (anonymous data).\")}

    \r\n

    {t(\"privacyPolicyPage.paragraph2.2\", \"We may collect, use, store and transfer different kinds of personal data about you which we have grouped together as follows:\")}\r\n

    \r\n

    Identity Data {t(\"privacyPolicyPage.paragraph2.2.1\", \" includes first name, maiden name, last name, username or similar identifier, marital status, title, date of birth and gender.\")}

    \r\n

    Contact Data{t(\"privacyPolicyPage.paragraph2.2.2\", \" includes billing address, delivery address, email address and telephone numbers.\")}

    \r\n

    Financial Data{t(\"privacyPolicyPage.paragraph2.2.3\", \" includes bank account and payment card details.\")}

    \r\n

    Transaction Data{t(\"privacyPolicyPage.paragraph2.2.4\", \" includes details about payments to and from you and other details of products and services you have purchased from us.\")}

    \r\n

    Tecnhical Data{t(\"privacyPolicyPage.paragraph2.2.5\", \" includes internet protocol (IP) address, your login data, browser type and version, time zone setting and location, browser plug-in types and versions, operating system and platform, and other technology on the devices you use to access this website.\")}

    \r\n

    Profile Data{t(\"privacyPolicyPage.paragraph2.2.6\", \" includes your username and password, purchases or orders made by you, your interests, preferences, feedback and survey responses.\")}

    \r\n

    Usage Data{t(\"privacyPolicyPage.paragraph2.2.7\", \" includes information about how you use our website, products and services.\")}

    \r\n

    Marketing and Communications Data{t(\"privacyPolicyPage.paragraph2.2.8\", \" includes your preferences in receiving marketing from us and our third parties and your communication preferences.\")}

    \r\n\r\n
    \r\n

    \r\n\r\n

    We also collect, use and share Aggregated Data{t(\"privacyPolicyPage.paragraph2.3.1\", \" such as statistical or demographic data for any purpose. Aggregated Data could be derived from your personal data but is not considered personal data in law as this data will \")} not {t(\"privacyPolicyPage.paragraph2.3.2\", \" directly or indirectly reveal your identity. For example, we may aggregate your Usage Data to calculate the percentage of users accessing a specific website feature. However, if we combine or connect Aggregated Data with your personal data so that it can directly or indirectly identify you, we treat the combined data as personal data which will be used in accordance with this privacy policy.\")}

    \r\n

    We do not collect any Special Categories of Personal Data{t(\"privacyPolicyPage.paragraph2.4\", \" about you (this includes details about your race or ethnicity, religious or philosophical beliefs, sex life, sexual orientation, political opinions, trade union membership, information about your health, and genetic and biometric data). Nor do we collect any information about criminal convictions and offences.\")}

    \r\n\r\n

    {t(\"privacyPolicyPage.paragraph2.5.header\", \"If you fail to provide personal data\")}

    \r\n

    {t(\"privacyPolicyPage.paragraph2.5.1\", \"Where we need to collect personal data by law, or under the terms of a contract we have with you, and you fail to provide that data when requested, we may not be able to perform the contract we have or are trying to enter into with you (for example, to provide you with goods or services). In this case, we may have to cancel a product or service you have with us but we will notify you if this is the case at the time.\")}

    \r\n\r\n
  4. \r\n
  5. {t(\"privacyPolicyPage.subHeading.3\", \"How is your personal data collected?\")}\r\n

    {t(\"privacyPolicyPage.paragraph3.1\", \"We use different methods to collect data from and about you including through:\")}

    \r\n

    {t(\"privacyPolicyPage.paragraph3.2.directInteractions\", \"Direct interactions.\")}{t(\"privacyPolicyPage.paragraph3.2\", \" You may give us your Identity, Contact and Financial Data by filling in forms or by corresponding with us by post, phone, email or otherwise. This includes personal data you provide when you:\")}\r\n

    \r\n

    • {t(\"privacyPolicyPage.paragraph3.2.1\", \"apply for our products or services;\")}

    \r\n

    • {t(\"privacyPolicyPage.paragraph3.2.2\", \"create an account on our website;\")}

    \r\n

    • {t(\"privacyPolicyPage.paragraph3.2.3\", \"subscribe to our service or publications;\")}

    \r\n

    • {t(\"privacyPolicyPage.paragraph3.2.4\", \"request marketing to be sent to you;\")}

    \r\n

    • {t(\"privacyPolicyPage.paragraph3.2.5\", \"enter a competition, promotion or survey; or\")}

    \r\n

    • {t(\"privacyPolicyPage.paragraph3.2.6\", \"give us feedback or contact us.\")}

    \r\n
    \r\n

    \r\n

    {t(\"privacyPolicyPage.paragraph3.3.automatedTechnologiesOrInteractions\", \"Automated technologies or interactions.\")} {t(\"privacyPolicyPage.paragraph3.3\", \" As you interact with our website, we will automatically collect Technical Data about your equipment, browsing actions and patterns. We collect this personal data by using cookies and other similar technologies. We may also receive Technical Data about you if you visit other websites employing our cookies.\")} { /*not included stuff on the right in the use translate as it contains html*/} Please see our cookie policy for further details.

    \r\n

    {t(\"privacyPolicyPage.paragraph3.4.thirdPartiesOrPubliclyAvailableSources\", \"Third parties or publicly available sources.\")}{t(\"privacyPolicyPage.paragraph3.4\", \" We will receive personal data about you from various third parties and public sources as set out below: \")}

    \r\n\r\n

    {t(\"privacyPolicyPage.paragraph3.5\", \"Technical Data from the following parties:\")}\r\n \r\n

    \r\n {/*below line is unfinished? seems to only have one payment provider listed, not in a way that joins the rest of the sentence and also a left in note for any other providers*/}\r\n

    • {t(\"privacyPolicyPage.paragraph3.6\", \"Contact, Financial and Transaction Data from providers of technical, payment and delivery services such as PayPal or any other payment providers\")}

    \r\n

    • {t(\"privacyPolicyPage.paragraph3.7\", \"Identity and Contact Data from publicly available sources such as Companies House and the Electoral Register based inside the UK and EU.\")}

    \r\n

    • {t(\"privacyPolicyPage.paragraph3.8\", \"Facebook, LinkedIn, and Instagram lead generation tools\")}

    \r\n

    • {t(\"privacyPolicyPage.paragraph3.9\", \"Mailing lists via Zymplify\")}

    \r\n\r\n
  6. \r\n
  7. {t(\"privacyPolicyPage.subHeading.4\", \"How we use your personal data\")}\r\n

    {t(\"privacyPolicyPage.paragraph4.1\", \"We will only use your personal data when the law allows us to. Most commonly, we will use your personal data in the following circumstances:\")}\r\n

    \r\n

    • {t(\"privacyPolicyPage.paragraph4.1.1\", \"Where we need to perform the contract, we are about to enter into or have entered into with you.\")}

    \r\n

    • {t(\"privacyPolicyPage.paragraph4.1.2\", \"Where it is necessary for our legitimate interests (or those of a third party) and your interests and fundamental rights do not override those interests.\")}

    \r\n

    • {t(\"privacyPolicyPage.paragraph4.1.3\", \"Where we need to comply with a legal obligation.\")}

    \r\n
    \r\n

    \r\n\r\n

    {t(\"privacyPolicyPage.paragraph4.2\", \"Generally, we do not rely on consent as a legal basis for processing your personal data although we will get your consent before sending third party direct marketing communications to you via email or text message. You have the right to withdraw consent to marketing at any time by contacting us.\")}

    \r\n\r\n

    {t(\"privacyPolicyPage.paragraph4.3.header\", \"Purposes for which we will use your personal data\")}

    \r\n\r\n

    {t(\"privacyPolicyPage.paragraph4.4\", \"We have set out below, in a table format, a description of all the ways we plan to use your personal data, and which of the legal bases we rely on to do so. We have also identified what our legitimate interests are where appropriate.\")}

    \r\n

    {t(\"privacyPolicyPage.paragraph4.5\", \"Note that we may process your personal data for more than one lawful ground depending on the specific purpose for which we are using your data. Please contact us if you need details about the specific legal ground we are relying on to process your personal data where more than one ground has been set out in the table below.\")}

    \r\n\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n
    {t(\"privacyPolicyPage.paragraph4.tableHeader.1\", \"Purpose/Activity\")}{t(\"privacyPolicyPage.paragraph4.tableHeader.2\", \"Type of data\")}{t(\"privacyPolicyPage.paragraph4.tableHeader.3\", \"Lawful basis for processing including basis of legitimate interest\")}
    {t(\"privacyPolicyPage.paragraph4.tableRow1.1\", \"To register you as a new customer\")}\r\n \r\n {t(\"privacyPolicyPage.paragraph4.tableRow1.3\", \"Performance of a contract with you\")}
    \r\n

    {t(\"privacyPolicyPage.paragraph4.tableRow2.1\", \"To process and deliver your order including:\")}\r\n \r\n

    \r\n
    \r\n \r\n \r\n \r\n
    \r\n

    {t(\"privacyPolicyPage.paragraph4.tableRow3.1\", \"To manage our relationship with you which will include:\")}\r\n \r\n

    \r\n
    \r\n \r\n \r\n \r\n
    {t(\"privacyPolicyPage.paragraph4.tableRow4.1\", \"To enable you to partake in a prize draw, competition or complete a survey\")}\r\n \r\n \r\n \r\n
    {t(\"privacyPolicyPage.paragraph4.tableRow5.1\", \"To administer and protect our business and this website (including troubleshooting, data analysis, testing, system maintenance, support, reporting and hosting of data)\")}\r\n \r\n \r\n \r\n
    {t(\"privacyPolicyPage.paragraph4.tableRow6.1\", \"To deliver relevant website content and advertisements to you and measure or understand the effectiveness of the advertising we serve to you\")}\r\n \r\n {t(\"privacyPolicyPage.paragraph4.tableRow6.3\", \"Necessary for our legitimate interests (to study how customers use our products/services, to develop them, to grow our business and to inform our marketing strategy)\")}
    {t(\"privacyPolicyPage.paragraph4.tableRow7.1\", \"To use data analytics to improve our website, products/services, marketing, customer relationships and experiences\")}\r\n {t(\"privacyPolicyPage.paragraph4.tableRow7.3\", \"Necessary for our legitimate interests (to define types of customers for our products and services, to keep our website updated and relevant, to develop our business and to inform our marketing strategy)\")}
    {t(\"privacyPolicyPage.paragraph4.tableRow8.1\", \"To make suggestions and recommendations to you about goods or services that may be of interest to you\")}\r\n {t(\"privacyPolicyPage.paragraph4.tableRow8.3\", \"Necessary for our legitimate interests (to develop our products/services and grow our business)\")}
    \r\n\r\n

    {t(\"privacyPolicyPage.paragraph4.6.header\", \"Marketing\")}

    \r\n

    {t(\"privacyPolicyPage.paragraph4.6\", \"We strive to provide you with choices regarding certain personal data uses, particularly around marketing and advertising.\")}

    \r\n\r\n

    {t(\"privacyPolicyPage.paragraph4.7.header\", \"Promotional offers from us\")}

    \r\n

    {t(\"privacyPolicyPage.paragraph4.7\", \"We may use your Identity, Contact, Technical, Usage and Profile Data to form a view on what we think you may want or need, or what may be of interest to you. This is how we decide which products, services and offers may be relevant for you (we call this marketing).\")}

    \r\n

    {t(\"privacyPolicyPage.paragraph4.8\", \"You will receive marketing communications from us if you have requested information from us or purchased goods or services from us and you have not opted out of receiving that marketing.\")}

    \r\n\r\n

    {t(\"privacyPolicyPage.paragraph4.9.header\", \"Third-party marketing\")}

    \r\n

    {t(\"privacyPolicyPage.paragraph4.9\", \"We will get your express opt-in consent before we share your personal data with any third party for marketing purposes.\")}

    \r\n\r\n

    {t(\"privacyPolicyPage.paragraph4.10.header\", \"Opting out\")}

    \r\n

    {t(\"privacyPolicyPage.paragraph4.10\", \"You can ask us or third parties to stop sending you marketing messages at any time by following the opt-out links on any marketing message sent to you or by contacting us at any time.\")}

    \r\n

    {t(\"privacyPolicyPage.paragraph4.11\", \"Where you opt out of receiving these marketing messages, this will not apply to personal data provided to us as a result of a product/service purchase, warranty registration, product/service experience or other transactions.\")}

    \r\n\r\n

    {t(\"privacyPolicyPage.paragraph4.12.header\", \"Cookies\")}

    \r\n

    {t(\"privacyPolicyPage.paragraph4.12\", \"You can set your browser to refuse all or some browser cookies, or to alert you when websites set or access cookies. If you disable or refuse cookies, please note that some parts of this website may become inaccessible or not function properly.\")}{ /*not included stuff on the right in the use translate as it contains html*/} For more information about the cookies we use, please see our cookie policy.

    \r\n\r\n

    {t(\"privacyPolicyPage.paragraph4.13.header\", \"Change of purpose\")}

    \r\n

    {t(\"privacyPolicyPage.paragraph4.13\", \"We will only use your personal data for the purposes for which we collected it, unless we reasonably consider that we need to use it for another reason and that reason is compatible with the original purpose. If you wish to get an explanation as to how the processing for the new purpose is compatible with the original purpose, please contact us.\")}

    \r\n

    {t(\"privacyPolicyPage.paragraph4.14\", \"If we need to use your personal data for an unrelated purpose, we will notify you and we will explain the legal basis which allows us to do so.\")}

    \r\n

    {t(\"privacyPolicyPage.paragraph4.15\", \"Please note that we may process your personal data without your knowledge or consent, in compliance with the above rules, where this is required or permitted by law.\")}

    \r\n
  8. \r\n
  9. {t(\"privacyPolicyPage.subHeading.5\", \"Disclosures of your personal data\")}\r\n

    {t(\"privacyPolicyPage.paragraph5.1\", \"We may share your personal data with the parties set out below for the purposes set out in the table Purposes for which we will use your personal data above.\")}\r\n

    • {t(\"privacyPolicyPage.paragraph5.1.1\", \"External Third Parties as set out in the Glossary.\")}

    \r\n

    • {t(\"privacyPolicyPage.paragraph5.1.2Third parties to whom we may choose to sell, transfer or merge parts of our business or our assets. Alternatively, we may seek to acquire other businesses or merge with them. If a change happens to our business, then the new owners may use your personal data in the same way as set out in this privacy policy.\")}

    \r\n

    \r\n\r\n

    {t(\"privacyPolicyPage.paragraph5.2\", \"We require all third parties to respect the security of your personal data and to treat it in accordance with the law. We do not allow our third-party service providers to use your personal data for their own purposes and only permit them to process your personal data for specified purposes and in accordance with our instructions.\")}

    \r\n\r\n \r\n
  10. \r\n
  11. {t(\"privacyPolicyPage.subHeading.6\", \"International transfers\")}\r\n

    {t(\"privacyPolicyPage.paragraph6.1\", \"Many of our external third parties are based outside the EEA so their processing of your personal data will involve a transfer of data outside the EEA.\")}

    \r\n\r\n

    {t(\"privacyPolicyPage.paragraph6.2\", \"Whenever we transfer your personal data out of the EEA, we ensure a similar degree of protection is afforded to it by ensuring at least one of the following safeguards is implemented\")}\r\n

    • {t(\"privacyPolicyPage.paragraph6.2.1\", \"We will only transfer your personal data to countries that have been deemed to provide an adequate level of protection for personal data by the European Commission. For further details, see European Commission: Adequacy of the protection of personal data in non-EU countries.\")}

    \r\n

    • {t(\"privacyPolicyPage.paragraph6.2.1\", \"Where we use certain service providers, we may use specific contracts approved by the European Commission which give personal data the same protection it has in Europe. For further details, see European Commission: Model contracts for the transfer of personal data to third countries.\")}

    \r\n

    • {t(\"privacyPolicyPage.paragraph6.2.1\", \"Where we use providers based in the US, we may transfer data to them if they are part of the Privacy Shield which requires them to provide similar protection to personal data shared between Europe and the US. For further details, see European Commission: EU-US Privacy Shield.\")}

    \r\n

    \r\n

    {t(\"privacyPolicyPage.paragraph6.3\", \"Where we use providers based in the US, we may transfer data to them if they are part of the Privacy Shield which requires them to provide similar protection to personal data shared between Europe and the US. For further details, see European Commission: EU-US Privacy Shield.\")}

    \r\n\r\n
  12. \r\n
  13. {t(\"privacyPolicyPage.subHeading.7\", \"7.\tData security\")}\r\n

    {t(\"privacyPolicyPage.paragraph7.1\", \"We have put in place appropriate security measures to prevent your personal data from being accidentally lost, used or accessed in an unauthorised way, altered or disclosed. In addition, we limit access to your personal data to those employees, agents, contractors and other third parties who have a business need to know. They will only process your personal data on our instructions, and they are subject to a duty of confidentiality.\")}

    \r\n

    {t(\"privacyPolicyPage.paragraph7.2\", \"We have put in place procedures to deal with any suspected personal data breach and will notify you and any applicable regulator of a breach where we are legally required to do so.\")}

    \r\n
  14. \r\n
  15. {t(\"privacyPolicyPage.subHeading.8\", \"Data retention\")}\r\n

    {t(\"privacyPolicyPage.paragraph8.1.header\", \"How long will you use my personal data for?\")}

    \r\n

    {t(\"privacyPolicyPage.paragraph8.1\", \"We will only retain your personal data for as long as reasonably necessary to fulfil the purposes we collected it for, including for the purposes of satisfying any legal, regulatory, tax, accounting or reporting requirements. We may retain your personal data for a longer period in the event of a complaint or if we reasonably believe there is a prospect of litigation in respect to our relationship with you.\")}

    \r\n

    {t(\"privacyPolicyPage.paragraph8.2\", \"To determine the appropriate retention period for personal data, we consider the amount, nature and sensitivity of the personal data, the potential risk of harm from unauthorised use or disclosure of your personal data, the purposes for which we process your personal data and whether we can achieve those purposes through other means, and the applicable legal, regulatory, tax, accounting or other requirements.\")}

    \r\n

    {t(\"privacyPolicyPage.paragraph8.3\", \"In some circumstances you can ask us to delete your data: see your legal rights below for further information.\")}

    \r\n

    {t(\"privacyPolicyPage.paragraph8.4\", \"In some circumstances we will anonymise your personal data (so that it can no longer be associated with you) for research or statistical purposes, in which case we may use this information indefinitely without further notice to you.\")}

    \r\n\r\n\r\n
  16. \r\n
  17. {t(\"privacyPolicyPage.subHeading.9\", \"Your legal rights\")}\r\n

    {t(\"privacyPolicyPage.paragraph9.1\", \"Under certain circumstances, you have rights under data protection laws in relation to your personal data. Please see Your Legal Rights section below to find out more about these rights:\")}

    \r\n {/*Sent over document had a set of links here to further down the document. looping this in with the discussion I had with Scott about a glossary where it was decided we arent linking to specific points on pages*/}\r\n\r\n

    {t(\"privacyPolicyPage.paragraph9.2\", \"If you wish to exercise any of these rights, please contact us.\")}

    \r\n\r\n

    {t(\"privacyPolicyPage.paragraph9.3.header\", \"No fee usually required\")}

    \r\n

    {t(\"privacyPolicyPage.paragraph9.3\", \"You will not have to pay a fee to access your personal data (or to exercise any of the other rights). However, we may charge a reasonable fee if your request is clearly unfounded, repetitive or excessive. Alternatively, we could refuse to comply with your request in these circumstances.\")}

    \r\n\r\n

    {t(\"privacyPolicyPage.paragraph9.4.header\", \"What we may need from you\")}

    \r\n

    {t(\"privacyPolicyPage.paragraph9.4\", \"We may need to request specific information from you to help us confirm your identity and ensure your right to access your personal data (or to exercise any of your other rights). This is a security measure to ensure that personal data is not disclosed to any person who has no right to receive it. We may also contact you to ask you for further information in relation to your request to speed up our response.\")}

    \r\n\r\n

    {t(\"privacyPolicyPage.paragraph9.4.header\", \"Time limit to respond\")}

    \r\n

    {t(\"privacyPolicyPage.paragraph9.4\", \"We try to respond to all legitimate requests within one month. Occasionally it could take us longer than a month if your request is particularly complex or you have made a number of requests. In this case, we will notify you and keep you updated.\")}

    \r\n
  18. \r\n
  19. {t(\"privacyPolicyPage.subHeading.10\", \"Glossary\")}\r\n\r\n

    {t(\"privacyPolicyPage.paragraph10.1.header\", \"LAWFUL BASIS\")}

    \r\n

    {t(\"privacyPolicyPage.paragraph10.1\", \"Legitimate Interest means the interest of our business in conducting and managing our business to enable us to give you the best service/product and the best and most secure experience. We make sure we consider and balance any potential impact on you (both positive and negative) and your rights before we process your personal data for our legitimate interests. We do not use your personal data for activities where our interests are overridden by the impact on you (unless we have your consent or are otherwise required or permitted to by law). You can obtain further information about how we assess our legitimate interests against any potential impact on you in respect of specific activities by contacting us.\")}

    \r\n

    {t(\"privacyPolicyPage.paragraph10.2\", \"Performance of Contract means processing your data where it is necessary for the performance of a contract to which you are a party or to take steps at your request before entering into such a contract.\")}

    \r\n

    {t(\"privacyPolicyPage.paragraph10.3\", \"Comply with a legal obligation means processing your personal data where it is necessary for compliance with a legal obligation that we are subject to.\")}

    \r\n\r\n

    {t(\"privacyPolicyPage.paragraph10.4.header\", \"THIRD PARTIES\")}

    \r\n

    {t(\"privacyPolicyPage.paragraph10.5.header\", \"Internal Third Parties\")}

    \r\n

    {t(\"privacyPolicyPage.paragraph10.5\", \"No other companies act as joint controllers or processors internally.\")}

    \r\n

    {t(\"privacyPolicyPage.paragraph10.6.header\", \"External Third Parties\")}\r\n

    • {t(\"privacyPolicyPage.paragraph10.6.1\", \"Service providers based outside the European Union who provide IT and system administration services.\")}

    \r\n

    • {t(\"privacyPolicyPage.paragraph10.6.2\", \"Professional advisers including lawyers, bankers, auditors and insurers based within the United Kingdom, European Union who provide consultancy, banking, legal, insurance and accounting services\")}

    \r\n

    • {t(\"privacyPolicyPage.paragraph10.6.3\", \"HM Revenue & Customs, regulators and other authorities based in the United Kingdom who require reporting of processing activities in certain circumstances.\")}

    \r\n

    \r\n\r\n

    {t(\"privacyPolicyPage.paragraph10.7.header\", \"YOUR LEGAL RIGHTS\")}

    \r\n

    {t(\"privacyPolicyPage.paragraph10.7\", \"You have the right to:\")}

    \r\n

    Request access{t(\"privacyPolicyPage.paragraph10.8\", \" to your personal data (commonly known as a \\\"data subject access request\\\"). This enables you to receive a copy of the personal data we hold about you and to check that we are lawfully processing it.\")}

    \r\n

    Request correction{t(\"privacyPolicyPage.paragraph10.9\", \" of the personal data that we hold about you. This enables you to have any incomplete or inaccurate data we hold about you corrected, though we may need to verify the accuracy of the new data you provide to us.\")}

    \r\n

    Request erasure{t(\"privacyPolicyPage.paragraph10.10\", \" of your personal data. This enables you to ask us to delete or remove personal data where there is no good reason for us continuing to process it. You also have the right to ask us to delete or remove your personal data where you have successfully exercised your right to object to processing (see below), where we may have processed your information unlawfully or where we are required to erase your personal data to comply with local law. Note, however, that we may not always be able to comply with your request of erasure for specific legal reasons which will be notified to you, if applicable, at the time of your request. \")}

    \r\n

    Object to processing{t(\"privacyPolicyPage.paragraph10.11\", \" of your personal data where we are relying on a legitimate interest (or those of a third party) and there is something about your particular situation which makes you want to object to processing on this ground as you feel it impacts on your fundamental rights and freedoms. You also have the right to object where we are processing your personal data for direct marketing purposes. In some cases, we may demonstrate that we have compelling legitimate grounds to process your information which override your rights and freedoms.\")}

    \r\n

    Request restriction{t(\"privacyPolicyPage.paragraph10.12\", \" of processing of your personal data. This enables you to ask us to suspend the processing of your personal data in the following scenarios: \")}\r\n

    • {t(\"privacyPolicyPage.paragraph10.12.1\", \"If you want us to establish the data's accuracy.\")}

    \r\n

    • {t(\"privacyPolicyPage.paragraph10.12.2\", \"Where our use of the data is unlawful but you do not want us to erase it.\")}

    \r\n

    • {t(\"privacyPolicyPage.paragraph10.12.3\", \"Where you need us to hold the data even if we no longer require it as you need it to establish, exercise or defend legal claims.\")}

    \r\n

    • {t(\"privacyPolicyPage.paragraph10.12.4\", \"You have objected to our use of your data but we need to verify whether we have overriding legitimate grounds to use it.\")}

    \r\n

    \r\n

    Request the transfer{t(\"privacyPolicyPage.paragraph10.13\", \" of your personal data to you or to a third party. We will provide to you, or a third party you have chosen, your personal data in a structured, commonly used, machine-readable format. Note that this right only applies to automated information which you initially provided consent for us to use or where we used the information to perform a contract with you.\")}

    \r\n

    Withdraw consent at any time{t(\"privacyPolicyPage.paragraph10.14\", \" where we are relying on consent to process your personal data. However, this will not affect the lawfulness of any processing carried out before you withdraw your consent. If you withdraw your consent, we may not be able to provide certain products or services to you. We will advise you if this is the case at the time you withdraw your consent.\")}

    \r\n\r\n
  20. \r\n
\r\n
\r\n
\r\n
\r\n );\r\n};\r\n\r\n\r\n","import { useCallback, useEffect } from 'react';\r\nimport { useTranslation } from 'react-i18next';\r\nimport { Col, Row } from 'reactstrap';\r\nimport { AlertOnErrors } from '../../shared/alertOnErrors';\r\nimport { Background } from '../shared/background/Background';\r\nimport { Banner } from '../shared/Banner';\r\nimport { MainContainer } from '../shared/MainContainer';\r\nimport { StickyToolbar } from '../shared/StickyToolbar';\r\nimport './cookiePolicyPage.scss';\r\n\r\n/**\r\n * Cookie Policy Page.\r\n */\r\nexport const CookiePolicyPage = () => {\r\n\r\n const { t } = useTranslation();\r\n\r\n // a formatted table with a lower case alpha in the first column and the item in the second column\r\n // presents a a pseudo ordered list\r\n const LowerAlphaList = useCallback((props: {\r\n listItems: object[],\r\n }) => {\r\n const { listItems } = props;\r\n const alphaCharacters: Array = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'y'];\r\n\r\n return (\r\n\r\n \r\n \r\n {\r\n listItems.map((item, index) => {\r\n return (\r\n \r\n \r\n \r\n \r\n );\r\n })\r\n }\r\n \r\n
{alphaCharacters[index]}){item}
\r\n );\r\n\r\n }, []);\r\n\r\n useEffect(() => {\r\n window.scrollTo(0, 0);\r\n }, []);\r\n\r\n\r\n return (\r\n \r\n \r\n \r\n \r\n \r\n

{t(\"cookiePolicyPage.title\", \"Cookie Policy\")}

\r\n \r\n\r\n
\r\n
\r\n
\r\n\r\n \r\n \r\n
\r\n\r\n

{t(\"cookiePolicyPage.background.paragraph.1\", \"Our website uses cookies to distinguish you from other users of our website. This helps us to provide you with a good experience when you browse our website and also allows us to improve our site.\")}

\r\n

{t(\"cookiePolicyPage.background.paragraph.2\", \"A cookie is a small file of letters and numbers that we store on your browser or the hard drive of your computer if you agree. Cookies contain information that is transferred to your computer's hard drive.\")}

\r\n

{t(\"cookiePolicyPage.background.paragraph.3\", \"We use the following cookies:\")}\r\n

{t(\"cookiePolicyPage.background.paragraph.3.1.strictlyNecessaryCookies\", \"Strictly necessary cookies.\")} {t(\"cookiePolicyPage.background.paragraph.3.1\", \"These are cookies that are required for the operation of our website. They include, for example, cookies that enable you to log into secure areas of our website, use a shopping cart or make use of e-billing services.\")}

\r\n

{t(\"cookiePolicyPage.background.paragraph.3.2.analyticalOrPerformanceCookies\", \"Analytical or performance cookies.\")} {t(\"cookiePolicyPage.background.paragraph.3.2\", \"These allow us to recognise and count the number of visitors and to see how visitors move around our website when they are using it. This helps us to improve the way our website works, for example, by ensuring that users are finding what they are looking for easily.\")}

\r\n

{t(\"cookiePolicyPage.background.paragraph.3.3.functionalityCookies\", \"Functionality Cookies.\")} {t(\"cookiePolicyPage.background.paragraph.3.3\", \"These are used to recognise you when you return to our website. This enables us to personalise our content for you, greet you by name and remember your preferences (for example, your choice of language or region).\")}

\r\n

{t(\"cookiePolicyPage.background.paragraph.3.4.targetingCookies\", \"Targeting Cookies.\")} {t(\"cookiePolicyPage.background.paragraph.3.4\", \"These cookies record your visit to our website, the pages you have visited and the links you have followed. We will use this information to make our website and the advertising displayed on it more relevant to your interests. We may also share this information with third parties for this purpose.\")}

\r\n

\r\n

{t(\"cookiePolicyPage.background.paragraph.4\", \"You can find more information about the individual cookies we use and the purposes for which we use them in the table below:\")}

\r\n\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n
{t(\"privacyPolicyPage.paragraph4.tableHeader.1.2\", \"Cookie Name\")}{t(\"privacyPolicyPage.paragraph4.tableHeader.2\", \"Purpose\")}{t(\"privacyPolicyPage.paragraph4.tableHeader.3\", \"More information\")}
{t(\"privacyPolicyPage.paragraph4.tableRow1.1\", \".AspNetCore.Identity.Application\")}{t(\"privacyPolicyPage.paragraph4.tableRow1.2\", \"Used to identify the logged in user\")}\r\n

{t(\"privacyPolicyPage.paragraph4.tableRow1.3\", \"These cookies are essential for our site to OR enables us to:\")}

\r\n\r\n \r\n\r\n
{t(\"privacyPolicyPage.paragraph4.tableRow2.1\", \"idsrv.session\")}{t(\"privacyPolicyPage.paragraph4.tableRow2.2\", \"Used to attach the logged in user to an individual session.\")}
{t(\"privacyPolicyPage.paragraph4.tableRow3.1\", \"ARRAffinity and ARRAffinitySameSite\")}{t(\"privacyPolicyPage.paragraph4.tableRow3.1\", \"Used to optimise the routing of the user across multiple web servers in the server farm behind the website.\")}
\r\n\r\n

{t(\"cookiePolicyPage.background.paragraph.5\", \"Please note that the following third parties may also use cookies, over which we have no control. These named third parties may include, for example, advertising networks and providers of external services like web traffic analysis services. These third party cookies are likely to be analytical cookies or performance cookies or targeting cookies:\")}\r\n

{t(\"cookiePolicyPage.background.paragraph.6\", \"We do not use any third party cookies on our app website.\")}

\r\n

\r\n

{t(\"cookiePolicyPage.background.paragraph.7\", \"To deactivate the use of third party advertising cookies, you may visit the consumer page to manage the use of these types of cookies.\")}

\r\n

{t(\"cookiePolicyPage.background.paragraph.8\", \"You can block cookies by activating the setting on your browser that allows you to refuse the setting of all or some cookies. However, if you use your browser settings to block all cookies (including essential cookies) you may not be able to access all or parts of our website.\")}

\r\n
\r\n
\r\n
\r\n );\r\n\r\n}","import { NavItem, NavLink } from 'reactstrap';\r\nimport { useTranslation } from 'react-i18next';\r\nimport { FontAwesomeIcon } from '@fortawesome/react-fontawesome';\r\nimport { NavLinkTrackActive } from '../../../shared/NavLinkTrackActive';\r\n\r\n/**\r\n * Administration navigation menu for studies.\r\n */\r\nexport const StudyAdministrationNavigation = () => {\r\n const { t } = useTranslation();\r\n\r\n return (\r\n <>\r\n \r\n \r\n \r\n {t('studyAdministrationNavigation.participants', ' Study participants')}\r\n \r\n \r\n \r\n \r\n \r\n {t('studyAdministrationNavigation.export', ' Study export')}\r\n \r\n \r\n \r\n );\r\n};","import { RouteEntry } from \"../../../shared/routes\";\r\nimport { IdentityRoles } from \"../../../configure/security/IdentityRoles\";\r\nimport { StudiesList } from \"./StudiesList\";\r\nimport { CreateStudy, EditStudy } from \"./EditStudy\";\r\nimport { StudyAssessmentsList } from \"./StudyAssesmentsList\";\r\nimport { StudyAdministrationDashboard } from \"../../dashboard/administrationDashboard/StudyAdministrationDashboard\";\r\nimport { StudyAdministrationHome } from \"./Administration/StudyAdministrationHome\";\r\n\r\nexport const studyRoutes: Array = [\r\n { path: '/administration/studies', exact: true, component: StudiesList, authorize: true, requireRole: IdentityRoles.Administration },\r\n { path: '/administration/studies/add', component: CreateStudy, authorize: true, requireRole: IdentityRoles.Administration },\r\n { path: '/administration/studies/edit/:id', component: EditStudy, authorize: true, requireRole: IdentityRoles.Administration },\r\n { path: '/administration/studies/details/:subscriptionId/assessments', exact: true, component: StudyAssessmentsList, authorize: true, requireRole: IdentityRoles.Administration },\r\n\r\n // manage\r\n { path: '/manage/study', exact: true, component: StudyAdministrationHome, authorize: true, requireRole: IdentityRoles.Administration },\r\n { path: '/manage/study/participants', exact: true, component: StudyAdministrationDashboard, authorize: true, requireRole: IdentityRoles.Administration },\r\n];\r\n","import { useTranslation } from \"react-i18next\";\r\nimport { SubscriptionType } from \"../../../api/main/models/codeOnly/SubscriptionType\";\r\nimport { SubscriptionsListBase } from \"../SubscriptionsListBase\";\r\n\r\n/**\r\n * List of actual studies\r\n */\r\nexport const StudiesList = () => {\r\n const { t } = useTranslation();\r\n\r\n return (\r\n \r\n );\r\n};","import { SubscriptionType } from \"../../../api/main/models/codeOnly/SubscriptionType\";\r\nimport { CreateSubscriptionBase, EditSubscriptionBase } from \"../EditSubscriptionBase\";\r\n\r\n/**\r\n * Create an actual Study\r\n */\r\nexport const CreateStudy = () => (\r\n ({ subscriptionType: SubscriptionType.Study })}\r\n />);\r\n\r\n/**\r\n * Edit an actual Study\r\n */\r\nexport const EditStudy = () => ();","import { useTranslation } from \"react-i18next\";\r\nimport { AssessmentType } from \"../../../api/main/models/codeOnly/AssessmentType\";\r\nimport { SubscriptionAssessmentsListBase } from \"../../subscriptionAssessments/SubscriptionAssessmentsListBase\";\r\nimport { useParams } from \"react-router\";\r\nimport { StudyEditNavigation } from './StudyEditNavigation';\r\n\r\n/**\r\n * List of actual assessments.\r\n */\r\nexport const StudyAssessmentsList = () => {\r\n const { t } = useTranslation();\r\n\r\n const { subscriptionId } = useParams<{ subscriptionId: string; }>();\r\n\r\n const baseRoute = '/administration/assessments';\r\n\r\n return (\r\n }\r\n isStudy={true}\r\n />\r\n );\r\n};","import { Redirect } from 'react-router';\r\n\r\n\r\n/**\r\n * Default Study Administration home page.\r\n */\r\nexport const StudyAdministrationHome = () => {\r\n\r\n return (\r\n <>\r\n \r\n \r\n );\r\n};","import { FontAwesomeIcon } from \"@fortawesome/react-fontawesome\";\r\nimport { useMemo } from \"react\";\r\nimport { ConditionalFragment } from \"react-conditionalfragment\";\r\nimport { useTranslation } from \"react-i18next\";\r\nimport { Waypoint } from \"react-waypoint\";\r\nimport { Button, ButtonGroup, CardTitle, Col, Row } from \"reactstrap\";\r\nimport { useStudyAdministrationDashboardViewModel } from \"../../../api/main/dashboard/viewModels/useStudyAdministrationDashboardViewModel\";\r\nimport { usePreferredListViewMode } from \"../../../globalState/preferredListViewMode/usePreferredListViewMode\";\r\nimport { useCurrentUserOrEmulatedSubscriptionId } from \"../../../globalState/subscriptions/useCurrentUserOrEmulatedSubscriptionId\";\r\nimport { AlertOnErrors } from \"../../../shared/alertOnErrors\";\r\nimport { Background } from \"../../shared/background/Background\";\r\nimport { Banner } from \"../../shared/Banner\";\r\nimport { CardsOrTable } from \"../../shared/cardsOrTable/CardsOrTable\";\r\nimport { LoadingIndicator } from \"../../shared/LoadingIndicator\";\r\nimport { MainContainer } from \"../../shared/MainContainer\";\r\nimport { PillsNavBar } from \"../../shared/pillsNavBar/PillsNavBar\";\r\nimport { StudyAdministrationNavigation } from \"../../subscriptions/Studies/Administration/StudyAdministrationNavigation\";\r\nimport { DashboardBackButton } from \"../backButton/DashboardBackButton\";\r\n\r\n/**\r\n * Dashboard for a Study\r\n */\r\nexport const StudyAdministrationDashboard = () => {\r\n const { t } = useTranslation();\r\n\r\n const subscriptionId = useCurrentUserOrEmulatedSubscriptionId();\r\n\r\n const {\r\n data: {\r\n items: allItems,\r\n profiles\r\n }, isLoading, errors: loadErrors, fetchMore, hasMore\r\n } = useStudyAdministrationDashboardViewModel(subscriptionId);\r\n\r\n // Combine all the data into a single object\r\n const items = useMemo(() => allItems?.map(item => {\r\n const user = profiles?.find(it => it.userId === item.userId);\r\n\r\n return {\r\n ...item,\r\n user\r\n };\r\n }), [allItems, profiles]);\r\n\r\n const [viewMode, setViewMode] = usePreferredListViewMode();\r\n\r\n // Render the UI\r\n //\r\n return (\r\n \r\n \r\n \r\n \r\n

\r\n \r\n {t('studyDashboard.heading.default', 'Study dashboard')}\r\n

\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n
\r\n
\r\n\r\n \r\n \r\n\r\n view === 'cards' ? ({t('common.fullNamw', '{{firstName}} {{lastName}}', { firstName: item.user?.firstName, lastName: item.user?.lastName })}) : t('common.fullNamw', '{{firstName}} {{lastName}}', { firstName: item.user?.firstName, lastName: item.user?.lastName }),\r\n (item, view) => view === 'cards' ? ({item.isFinished ? 'Complete' : 'Incomplete'}) : item.isFinished ? 'Yes' : 'No',\r\n ]}\r\n />\r\n\r\n \r\n \r\n \r\n\r\n {/**/}\r\n {/* */}\r\n {/**/}\r\n\r\n \r\n \r\n \r\n \r\n \r\n
\r\n );\r\n};","import * as React from 'react';\r\nimport { useLazyQuery } from \"@apollo/react-hooks\";\r\nimport gql from \"graphql-tag\";\r\nimport { AsyncLoadPagedOptions, AsyncLoadPagedResult } from '../../../../shared/abstractStore';\r\nimport { mainApiConfig } from '../../../../configure/mainApiConfig';\r\nimport { useFetchMoreCallback } from '../../../../shared/useFetchMoreCallback';\r\nimport { assessmentSessionFieldsFragment } from '../../models/AssessmentSession';\r\nimport { studyAdministrationDashboardViewModelQuery, studyAdministrationDashboardViewModelQueryVariables } from '../../generated/studyAdministrationDashboardViewModelQuery';\r\nimport { Guid } from 'guid-string';\r\nimport { profileFieldsFragment } from '../../models/Profile';\r\n\r\n/**\r\n * Get a list of assessmentSessions from the store.\r\n * @param studyId\r\n * @param options\r\n */\r\nexport function useStudyAdministrationDashboardViewModel(studyId: string | undefined | null, options: AsyncLoadPagedOptions = {}): AsyncLoadPagedResult {\r\n // Query data we need from the api.\r\n const [load, { data, loading, error, refetch, fetchMore: fetchMoreFromStore }] = useLazyQuery(\r\n gql`\r\n query studyAdministrationDashboardViewModelQuery ($offset: Int, $first: Int, $studyId: ID!) {\r\n items: assessmentSessions (offset: $offset, first: $first, subscriptionId: $studyId) {\r\n ...assessmentSessionFields\r\n }\r\n\r\n profiles {\r\n ...profileFields\r\n }\r\n }\r\n\r\n ${assessmentSessionFieldsFragment}\r\n ${profileFieldsFragment}\r\n `,\r\n {\r\n\r\n variables: {\r\n offset: options.startOffset,\r\n first: options.pageSize,\r\n studyId: studyId ?? Guid.empty\r\n },\r\n fetchPolicy: options.fetchPolicy ?? mainApiConfig.defaultFetchPolicy,\r\n pollInterval: options.pollInterval,\r\n onCompleted: (data) => {\r\n if (options.onCompleted) {\r\n options.onCompleted(data);\r\n }\r\n }\r\n }\r\n );\r\n\r\n // Run the query (unless we are being lazy).\r\n React.useEffect(() => {\r\n if (!options.lazy) {\r\n load();\r\n }\r\n }, [options.lazy, load]);\r\n\r\n // Get the functions used to manage paging.\r\n const { fetchMore, hasMore: _hasMore } = useFetchMoreCallback(\r\n fetchMoreFromStore,\r\n (options?.startOffset ?? 0) + (data?.items?.length ?? 0),\r\n (prevResults, newResults) => ({\r\n ...prevResults,\r\n ...newResults,\r\n\r\n items: [...(prevResults?.items ?? []), ...(newResults?.items ?? [])],\r\n profiles: [...(prevResults?.profiles ?? []), ...(newResults?.profiles ?? [])],\r\n }),\r\n (newResults) => newResults?.items?.length\r\n );\r\n const hasMore = React.useCallback(() => !options.pageSize ? false : _hasMore(), [options.pageSize, _hasMore]);\r\n\r\n // Return the results.\r\n const refresh = React.useCallback(async () => { !refetch ? await load() : await refetch(); }, [refetch, load]);\r\n return React.useMemo(() => ({\r\n data: data ?? ({} as any),\r\n refresh: refresh,\r\n isLoading: loading,\r\n errors: error,\r\n fetchMore: fetchMore,\r\n hasMore: hasMore,\r\n }), [data, refresh, loading, error, fetchMore, hasMore]);\r\n}\r\n","import * as React from \"react\";\r\nimport { Form, FormGroup, Label, Spinner, Card, CardHeader, CardBody } from \"reactstrap\";\r\nimport { AlertOnErrors } from \"../../shared/alertOnErrors\";\r\nimport { useParams } from \"react-router-dom\";\r\nimport { useChanges } from \"../../shared/useChanges\";\r\nimport { useValidatorCallback } from \"pojo-validator-react\";\r\nimport { ValidatedInput } from \"pojo-validator-reactstrap\";\r\nimport { ButtonAsync } from \"reactstrap-buttonasync\"\r\nimport { StudyLoginRequest } from \"../../api/account\";\r\nimport { useTranslation } from \"react-i18next\";\r\nimport { FormButtons } from \"../shared/FormButtons\";\r\nimport { MainContainer } from \"../shared/MainContainer\";\r\nimport { Background } from \"../shared/background/Background\";\r\nimport { Guid } from \"guid-string\";\r\nimport { useStudyLoginCallback } from \"../../api/account/useStudyLoginCallback\";\r\n\r\n/**\r\n * Study login screen where users are able to log in to a study.\r\n */\r\nexport const StudyLogin = () => {\r\n const { t } = useTranslation();\r\n //const { data: { externalAuthenticationSchemes }, isLoading, errors: loadErrors } = useExternalAuthenticationSchemes();\r\n const [studyLogin, { isExecuting: isLoggingIn, errors: loginErrors }] = useStudyLoginCallback();\r\n \r\n // Get the study from the route parameters.\r\n const { studyUniqueCode: studyUniqueCodeParam } = useParams<{ studyUniqueCode: string }>();\r\n\r\n // Get the user identifier from the query string, we allow several different query string parameters to be used.\r\n const params = new URLSearchParams(window.location.search);\r\n const userIdentifierParam = params.get('user') || params.get('User')\r\n || params.get('participant') || params.get('Participant')\r\n || params.get('prolific_pid') || params.get('PROLIFIC_PID') || params.get('Prolific_PID')\r\n || params.get('session') || params.get('Session')\r\n || params.get('id') || params.get('Id');\r\n // The default if we don't have a parameter is to generate a random guid.\r\n const [uniqueIdentifierDefault] = React.useState(() => Guid.newGuid());\r\n \r\n const { model, change } = useChanges({ studyUniqueCode: studyUniqueCodeParam, userIdentifier: userIdentifierParam || uniqueIdentifierDefault, });\r\n\r\n /**\r\n * Validate the model before trying to use it.\r\n */\r\n const [validate, validationErrors] = useValidatorCallback((validation, fieldsToCheck) => {\r\n const rules = {\r\n studyUniqueCode: () => !model.studyUniqueCode ? t('studyLogin.studyUniqueCode.required', 'Study code is required. You should have received this from the study organiser.') : '',\r\n userIdentifier: () => !model.userIdentifier ? t('studyLogin.userIdentifier.required', 'A unique identifier for you as a study participant is required.') : '',\r\n };\r\n\r\n validation.checkRules(rules, fieldsToCheck);\r\n }, [model]);\r\n\r\n /**\r\n * Perform a study login and handle the result.\r\n */\r\n const [isDoingFullPageRedirect, setIsDoingFullPageRedirect] = React.useState(false);\r\n const performStudyLogin = React.useCallback(async (): Promise => {\r\n if (!validate()) {\r\n return;\r\n }\r\n\r\n let result = await studyLogin(model);\r\n\r\n if (result) {\r\n if (result.succeeded) {\r\n // Redirect the whole page (not just react) to the returnUrl to let the server handle as well as the client.\r\n setIsDoingFullPageRedirect(true);\r\n window.location.href = result.returnUrl;\r\n }\r\n }\r\n }, [studyLogin, model, validate]);\r\n\r\n // If we have a study id, we can auto login.\r\n const [autoLoginStarted, setAutoLoginStarted] = React.useState(false);\r\n React.useEffect(() => {\r\n if (studyUniqueCodeParam && !autoLoginStarted) {\r\n setAutoLoginStarted(true);\r\n performStudyLogin();\r\n }\r\n }, [studyUniqueCodeParam, performStudyLogin, autoLoginStarted, setAutoLoginStarted]);\r\n\r\n // Render the UI.\r\n return (\r\n \r\n \r\n \r\n \r\n

\r\n {t('studyLogin.signInHeading', 'Participate in study')}\r\n

\r\n
\r\n \r\n
{ e.preventDefault(); await performStudyLogin(); }}>\r\n \r\n \r\n \r\n change({ studyUniqueCode: e.currentTarget.value })} onBlur={e => validate('studyUniqueCode')} validationErrors={validationErrors['studyUniqueCode']} />\r\n \r\n \r\n \r\n change({ userIdentifier: e.currentTarget.value })} onBlur={e => validate('userIdentifier')} validationErrors={validationErrors['userIdentifier']} />\r\n \r\n\r\n \r\n {t('studyLogin.loggingIn', 'Checking...')}}>\r\n {t('studyLogin.signIn', 'Start study')}\r\n \r\n \r\n \r\n
\r\n
\r\n
\r\n
\r\n );\r\n};\r\n","import { LoginResult } from \"../../api/account\";\r\nimport { AsyncActionStatus } from \"../../shared/abstractStore\";\r\nimport { useAsyncCallback } from \"react-use-async-callback\";\r\nimport { StudyLoginRequest } from \"./AccountService\";\r\nimport { useAccountService } from \"./useAccountService\";\r\n\r\n/**\r\n * Callback to login to a study.\r\n */\r\nexport function useStudyLoginCallback(): [(model: StudyLoginRequest) => Promise, AsyncActionStatus] {\r\n const accountService = useAccountService();\r\n\r\n const [action, { isExecuting, errors }] = useAsyncCallback(async (model: StudyLoginRequest) => {\r\n let result = await accountService.studyLogin(model);\r\n\r\n // If we get here we have a successful login\r\n return result;\r\n }, [accountService]);\r\n\r\n return [action, { isExecuting, errors }];\r\n}\r\n","import { RouteEntry } from \"../../shared/routes\";\r\nimport { StudyCompletes } from \"./StudyComplete\";\r\nimport { StudyLogin } from \"./StudyLogin\";\r\nimport { StudyThanks } from \"./StudyThanks\";\r\n\r\nexport const studyAccountRoutes: Array = [\r\n { path: '/study/:studyUniqueCode', component: StudyLogin },\r\n { path: '/study', component: StudyLogin },\r\n\r\n { path: '/study-complete/:assessmentSessionId', component: StudyCompletes },\r\n { path: '/study-thanks', component: StudyThanks },\r\n];\r\n","import * as React from \"react\";\r\nimport { Background } from \"../shared/background/Background\";\r\nimport { useParams } from \"react-router\";\r\nimport { LoadingIndicator } from \"../shared/LoadingIndicator\";\r\nimport { useStudyLogoutCallback } from \"../../api/account/useStudyLogoutCallback\";\r\nimport { AlertOnErrors } from \"../../shared/alertOnErrors\";\r\n\r\n/**\r\n * Screen to direct users to when they have completed their study.\r\n */\r\nexport const StudyCompletes = () => {\r\n // Get the assessmentSessionId from the parameters.\r\n const { assessmentSessionId } = useParams<{ assessmentSessionId: string }>();\r\n\r\n // Get the study logout callback and invoke it.\r\n const [studyLogout, { errors: studyLogoutErrors }] = useStudyLogoutCallback();\r\n const [attemptedLogout, setAttemptedLogout] = React.useState(false);\r\n React.useEffect(() => {\r\n (async () => {\r\n if (attemptedLogout) {\r\n return;\r\n }\r\n\r\n setAttemptedLogout(true);\r\n const result = await studyLogout({ assessmentSessionId });\r\n const returnUrl = result?.returnUrl ?? '/study-thanks';\r\n window.location.href = returnUrl\r\n })();\r\n }, [studyLogout, assessmentSessionId, attemptedLogout]);\r\n\r\n // Render the UI as a loading indicator while we process the completion..\r\n return (\r\n \r\n \r\n \r\n \r\n );\r\n};\r\n","import { LoginResult } from \"../../api/account\";\r\nimport { AsyncActionStatus } from \"../../shared/abstractStore\";\r\nimport { useAsyncCallback } from \"react-use-async-callback\";\r\nimport { StudyLogoutRequest } from \"./AccountService\";\r\nimport { useAccountService } from \"./useAccountService\";\r\n\r\n/**\r\n * Callback to log out of a study.\r\n */\r\nexport function useStudyLogoutCallback(): [(model: StudyLogoutRequest) => Promise, AsyncActionStatus] {\r\n const accountService = useAccountService();\r\n\r\n const [action, { isExecuting, errors }] = useAsyncCallback(async (model: StudyLogoutRequest) => {\r\n let result = await accountService.studyLogout(model);\r\n\r\n // If we get here we have a successful logout.\r\n return result;\r\n }, [accountService]);\r\n\r\n return [action, { isExecuting, errors }];\r\n}\r\n","import * as React from \"react\";\r\nimport { Card, CardHeader, CardBody } from \"reactstrap\";\r\nimport { useTranslation } from \"react-i18next\";\r\nimport { MainContainer } from \"../shared/MainContainer\";\r\nimport { Background } from \"../shared/background/Background\";\r\n\r\n/**\r\n * Default thanks screen after user has completed a study and been logged out.\r\n */\r\nexport const StudyThanks = () => {\r\n const { t } = useTranslation();\r\n\r\n // Render the UI.\r\n return (\r\n \r\n \r\n \r\n \r\n

\r\n {t('studyThanks.heading', 'Thank you for participating in this study')}\r\n

\r\n
\r\n \r\n {t('studyThanks.message', 'Thank you for participating in this study. You responses have been captured and you can now close this window.')}\r\n \r\n
\r\n
\r\n
\r\n );\r\n};\r\n","import { RouteEntry } from \"../shared/routes\";\r\nimport { apiAuthorizationRoutes } from \"../components/api-authorization/routes\";\r\nimport { accountRoutes } from \"../components/account/routes\";\r\nimport { profileRoutes } from \"../components/profiles/routes\";\r\nimport { NotFound } from \"../components/shared/NotFound\";\r\nimport { homeRoutes } from \"../components/home/routes\";\r\nimport { administrationRoutes, administrationSidebarRoutes } from \"../components/administration/routes\";\r\nimport { questionTagRoutes } from \"../components/questionTags/routes\";\r\nimport { driverMetricRoutes } from \"../components/driverMetrics/routes\";\r\nimport { subscriptionRoutes } from \"../components/subscriptions/routes\";\r\nimport { assessmentRoutes } from \"../components/assessments/assessments/routes\";\r\nimport { trainingModuleAssessmentRoutes } from \"../components/assessments/trainingModules/routes\";\r\nimport { questionRoutes } from \"../components/questions/questions/routes\";\r\nimport { questionnaireRoutes } from \"../components/questions/questionnaires/routes\";\r\nimport { learningRoutes } from \"../components/questions/learning/routes\";\r\nimport { subscriptionAssessmentRoutes } from \"../components/subscriptionAssessments/assessments/routes\";\r\nimport { subscriptionTrainingModuleAssessmentRoutes } from \"../components/subscriptionAssessments/trainingModules/routes\";\r\nimport { meRoutes } from \"../components/me/routes\";\r\nimport { administratorsRoutes } from \"../components/users/administrators/routes\";\r\nimport { manageRoutes } from \"../components/manage/routes\";\r\nimport { driversRoutes } from \"../components/users/drivers/routes\";\r\nimport { managersRoutes } from \"../components/users/managers/routes\";\r\nimport { subscriptionTeamRoutes } from \"../components/subscriptionTeam/routes\";\r\nimport { userAssessmentAssignmentRoutes } from \"../components/userAssessmentAssignment/assessments/routes\";\r\nimport { userTrainingModuleAssessmentAssignmentsRoutes } from \"../components/userAssessmentAssignment/trainingModules/routes\";\r\nimport { assessmentSessionAssessmentRoutes } from \"../components/assessmentSessions/assessments/routes\";\r\nimport { assessmentSessionTrainingRoutes } from \"../components/assessmentSessions/trainingModules/routes\";\r\nimport { dashboardRoutes } from \"../components/dashboard/routes\";\r\nimport { importUsersRoutes } from \"../components/users/import/routes\";\r\nimport { informationRoutes } from \"../components/questions/information/routes\";\r\nimport { distributorRoutes } from \"../components/subscriptions/Distributors/routes\"\r\nimport { sdkRoutes } from \"../components/sdk/routes\";\r\nimport { cmsPageRoutes } from \"../components/cmsPages/routes\";\r\nimport { studyRoutes } from \"../components/subscriptions/Studies/routes\";\r\nimport { studyAccountRoutes } from \"../components/studyAccount/routes\";\r\n\r\nexport const appRoutes: Array = [\r\n ...apiAuthorizationRoutes,\r\n ...accountRoutes,\r\n ...homeRoutes,\r\n ...profileRoutes,\r\n\r\n ...administrationRoutes,\r\n ...administratorsRoutes,\r\n ...assessmentRoutes,\r\n ...assessmentSessionAssessmentRoutes,\r\n ...assessmentSessionTrainingRoutes,\r\n ...cmsPageRoutes,\r\n ...dashboardRoutes,\r\n ...driverMetricRoutes,\r\n ...driversRoutes,\r\n ...importUsersRoutes,\r\n ...informationRoutes,\r\n ...learningRoutes,\r\n ...manageRoutes,\r\n ...managersRoutes,\r\n ...meRoutes,\r\n ...trainingModuleAssessmentRoutes,\r\n ...questionRoutes,\r\n ...questionnaireRoutes,\r\n ...questionTagRoutes,\r\n ...sdkRoutes,\r\n ...studyRoutes,\r\n ...studyAccountRoutes,\r\n ...subscriptionAssessmentRoutes,\r\n ...subscriptionRoutes,\r\n ...subscriptionTeamRoutes,\r\n ...subscriptionTrainingModuleAssessmentRoutes,\r\n ...userAssessmentAssignmentRoutes,\r\n ...userTrainingModuleAssessmentAssignmentsRoutes,\r\n ...distributorRoutes,\r\n\r\n { path: undefined, component: NotFound }\r\n];\r\n\r\nexport const sidebarRoutes: Array = [\r\n ...administrationSidebarRoutes,\r\n];","import * as React from 'react';\r\nimport { Button } from 'reactstrap';\r\nimport { useTranslation } from 'react-i18next';\r\nimport { useHistory } from 'react-router';\r\nimport { MainContainer } from './MainContainer';\r\nimport { Banner } from './Banner';\r\nimport { Background } from './background/Background';\r\n\r\n/**\r\n * Component to show when a route is not found. \r\n */\r\nexport const NotFound = () => {\r\n const { t } = useTranslation();\r\n const history = useHistory();\r\n\r\n return (\r\n \r\n \r\n

{t('notFound.notFoundHeading', 'Sorry the page you have requested cannot be found')}

\r\n
\r\n \r\n

\r\n {t('notFound.helpText', 'The link you have accessed is for a page that could not be found. Please check and try again, or try navigating to the page you want using the apps menus.')}\r\n

\r\n\r\n \r\n
\r\n
\r\n );\r\n};","import './sidebar.scss';\r\n\r\nimport * as React from 'react';\r\nimport { AppSidebar, AppSidebarFooter, AppSidebarForm, AppSidebarHeader, AppSidebarMinimizer } from '@coreui/react';\r\nimport { SidebarNav } from '../../shared/sidebarNav';\r\nimport { AppRoutes } from '../shared/AppRoutes';\r\nimport { sidebarRoutes } from '../../configure/routeConfig';\r\nimport { Nav } from 'reactstrap';\r\nimport { Navigation } from '../home/Navigation';\r\n\r\nexport const Sidebar = () => {\r\n return (\r\n \r\n \r\n \r\n\r\n \r\n \r\n\r\n \r\n \r\n\r\n \r\n \r\n \r\n );\r\n};\r\n","import './layout.scss';\r\n\r\nimport * as React from 'react';\r\n//import { AppBreadcrumb } from '@coreui/react';\r\nimport { Header } from './Header';\r\nimport { Footer } from './Footer';\r\n\r\nimport { Sidebar } from './Sidebar';\r\nimport { LoadingIndicator } from '../../components/shared/LoadingIndicator';\r\n\r\nimport { RouteEntry } from '../../shared/routes';\r\n\r\nexport interface LayoutProps {\r\n appRoutes: Array,\r\n children: React.ReactNode\r\n}\r\n\r\nexport const Layout = (props: LayoutProps) => {\r\n return (\r\n
\r\n
\r\n
\r\n \r\n
\r\n {/**/}\r\n }>\r\n {props.children}\r\n \r\n
\r\n
\r\n
\r\n
\r\n );\r\n};\r\n","import { Library, library } from '@fortawesome/fontawesome-svg-core';\r\nimport { faSpinner, faLock, faUser, faSearch, faPlus, faCogs, faSave, faEdit, faUsers, faTrash, faCaretUp, faCaretDown, faCaretLeft, faUndo, faMinus, faExclamationCircle, faCaretRight, faTimesCircle, faStopwatch, faUserClock, faTimes, faStop, faDesktop, faRuler, faFlagCheckered, faPlay, faUserCheck, faCreditCard, faPhone, faEnvelope, faSchool, faPoundSign, faVoteYea, faPersonBooth, faTrashAlt, faChevronLeft, faChevronRight, faDownload, faCross, faCheckCircle, faEye, faTrashRestore, faSync, faThumbsDown, faThumbsUp, faCloudDownloadAlt, faPhotoVideo, faTag, faUserTag, faLink, faFileAlt, faInfo, faUserGraduate, faIdCardAlt, faTachometerAlt, faUsersCog, faBuilding, faGraduationCap, faCarCrash, faChalkboardTeacher, faClipboardCheck, faTags, faSolarPanel, faVideo, faExclamationTriangle, faCheck, faMeh, faClone, faThLarge, faThList, faBus, faCommentDots, faTicketAlt, faWindowRestore, faUpload, faFolderMinus, faPlayCircle, faHome, faHistory, faUserShield, faBook, faShippingFast, faCode, faProjectDiagram, faTerminal, faCopy, faEyeSlash, faPen, faDice } from '@fortawesome/free-solid-svg-icons';\r\nimport { faFrown as farFrown, faFrownOpen as farFrownOpen, faCircle as farCircle, faClock as farClock, faCalendarAlt as farCalendarAlt, faListAlt as farListAlt, faCalendarTimes as farCalendarTimes, faSmile as farSmile } from '@fortawesome/free-regular-svg-icons';\r\n\r\n// Import the fontawsome icons we actually want to use.\r\nexport const initializeIcons = () => {\r\n configureIcons(library);\r\n};\r\n\r\nexport const configureIcons = (library: Library) => {\r\n library.add(\r\n // solid\r\n faBook,\r\n faBuilding,\r\n faBus,\r\n faCarCrash,\r\n faCaretUp,\r\n faCaretDown,\r\n faCaretLeft,\r\n faCaretRight,\r\n faChalkboardTeacher,\r\n faCheck,\r\n faCheckCircle,\r\n faChevronLeft,\r\n faChevronRight,\r\n faClipboardCheck,\r\n faClone,\r\n faCloudDownloadAlt,\r\n faCode,\r\n faCogs,\r\n faCommentDots,\r\n faCopy,\r\n faCreditCard,\r\n faCross,\r\n faDesktop,\r\n faDice,\r\n faDownload,\r\n faEdit,\r\n faExclamationCircle,\r\n faExclamationTriangle,\r\n faEye,\r\n faEyeSlash,\r\n faFileAlt,\r\n faFlagCheckered,\r\n faFolderMinus,\r\n faGraduationCap,\r\n faHistory,\r\n faHome,\r\n faIdCardAlt,\r\n faInfo,\r\n faLink,\r\n faLock,\r\n faMeh,\r\n faMinus,\r\n faPen,\r\n faPersonBooth,\r\n faPhotoVideo,\r\n faPlay,\r\n faPlayCircle,\r\n faPlus,\r\n faPoundSign,\r\n faProjectDiagram,\r\n faRuler,\r\n faSave,\r\n faSchool,\r\n faSearch,\r\n faShippingFast,\r\n faSolarPanel,\r\n faSpinner,\r\n faStop,\r\n faStopwatch,\r\n faSync,\r\n faTachometerAlt,\r\n faTag,\r\n faTags,\r\n faTerminal,\r\n faThLarge,\r\n faThList,\r\n faThumbsDown,\r\n faThumbsUp,\r\n faTicketAlt,\r\n faTimes,\r\n faTimesCircle,\r\n faTrash,\r\n faTrashAlt,\r\n faTrashRestore,\r\n faUndo,\r\n faUpload,\r\n faUser,\r\n faUserCheck,\r\n faUserClock,\r\n faUsersCog,\r\n faUserGraduate,\r\n faUserTag,\r\n faUsers,\r\n faUserShield,\r\n faVideo,\r\n faVoteYea,\r\n faWindowRestore,\r\n\r\n // regular\r\n farCalendarAlt,\r\n farCalendarTimes,\r\n farCircle,\r\n farClock,\r\n farFrown,\r\n farFrownOpen,\r\n farListAlt,\r\n farSmile,\r\n faPhone,\r\n faEnvelope,\r\n );\r\n};\r\n","import { mainApiConfig } from \"./mainApiConfig\";\r\nimport { CachePersistor } from 'apollo3-cache-persist';\r\n\r\nimport { ApolloClient, HttpLink, InMemoryCache } from \"@apollo/client\";\r\n\r\nconst cache = new InMemoryCache();\r\n\r\n// Load cache from the persisited storage.\r\nexport const apolloCachePersistor = new CachePersistor({\r\n cache,\r\n storage: (window.localStorage as any),\r\n});\r\napolloCachePersistor.restore();\r\n\r\nconst link = new HttpLink({\r\n uri: mainApiConfig.endpoint,\r\n credentials: 'same-origin',\r\n});\r\n\r\nexport const apolloClient = new ApolloClient({\r\n link: link,\r\n cache: cache,\r\n});","// Import the required localization files for momentjs.\r\n//import 'moment/locale/en-us'; // Built in.\r\nimport 'moment/locale/en-gb';\r\n//import 'moment/locale/fr';\r\n\r\n// Import the required localization files for numeraljs.\r\n//import 'numeral/locale/en-us'; // Built in.\r\nimport 'numeral/locales/en-gb';\r\n//import 'numeral/locales/fr';\r\n\r\n\r\n/**\r\n * Languages available in the application. \r\n */\r\nexport const availableLanguages = [\r\n // Always put the default language and locale first.\r\n { code: 'en-GB', name: 'English (British)', flagCountryCode: 'gb', momentLocale: 'en-gb', numeralLocale: 'en-gb' },\r\n\r\n // Other languages.\r\n { code: 'en-US', name: 'English (American)', flagCountryCode: 'us', momentLocale: 'en', numeralLocale: 'en' },\r\n // { code: 'fr', name: 'Français', flagCountryCode: 'fr', momentLocale: 'fr', numeralLocale: 'fr' },\r\n //{ code: 'pt', name: 'Português', flagCountryCode: 'pt', momentLocale: 'pt', numeralLocale: 'pt-pt' },\r\n //{ code: 'es', name: 'Español', flagCountryCode: 'es', momentLocale: 'es', numeralLocale: 'es' }\r\n];\r\n\r\n/**\r\n * Lookup the best matching language for the language code given.\r\n */\r\nexport const findLanguage = (code: string) => {\r\n // If the code matches a fully language code then use it.\r\n let ret = availableLanguages.find(item => item.code === code);\r\n if (ret) {\r\n return ret;\r\n }\r\n\r\n // Try find a matching language with a shorter version of the code if we can, e.g. en-GB will look for en.\r\n const indexOfDash = code.indexOf('-');\r\n if (indexOfDash !== -1) {\r\n const shortCode = code.substring(0, indexOfDash);\r\n\r\n // If we have a short code language available, use it.\r\n ret = availableLanguages.find(item => item.code === shortCode);\r\n if (ret) {\r\n return ret;\r\n }\r\n\r\n // If we have a short code, but didn't find an exact match, try find any language that shares the short code and return the first one we find.\r\n ret = availableLanguages.find(item => item.code.indexOf(`${shortCode}-`) === 0);\r\n if (ret) {\r\n return ret;\r\n }\r\n }\r\n\r\n // If we get here, we couldn't match a language at all, so just return the default language.\r\n return availableLanguages[0];\r\n};\r\n","import en from './en/translation.json';\r\n//import fr from './fr/translation.json';\r\n\r\n/**\r\n * Returns all locale translation resources for use by i18next .\r\n * \r\n * This approach is great for apps with limited languages or text as it does away with any need to serve the translations from the backend (more PWA offline friendly).\r\n * If the number of translations in memory becomes a concern for your app, use i18next-http-backend or i18next-resoruces-to-backend instead of this approach.\r\n * \r\n * NOTE FOR SPECIAL CHARACTERS if you are having problems with special characters in any of the files not showing when running, it is probably down to the file encoding \r\n * of the json file. To fix open the .json file in Windows Notepad, go to Save As... and select the file encoding (e.g. UTF-8) on save and overwrite the file.\r\n */\r\nexport const localeResources = {\r\n en: { translation: en },\r\n //fr: { translation: fr },\r\n};\r\n","import { useMemo } from \"react\";\r\nimport { useSubscriptionStyleOverridesViewModel } from \"../../api/main/subscriptions/viewModels/useSubscriptionStyleOverridesViewModel\";\r\nimport { useCurrentUserOrEmulatedSubscriptionId } from \"../../globalState/subscriptions/useCurrentUserOrEmulatedSubscriptionId\";\r\n\r\n/**\r\n * Component that renders some style overrides based on the theming of specific components.\r\n */\r\nexport const SubscriptionStyleOverrides = () => {\r\n const subscriptionId = useCurrentUserOrEmulatedSubscriptionId();\r\n const { data: { model: subscription } } = useSubscriptionStyleOverridesViewModel(subscriptionId);\r\n\r\n // Generate the styles.\r\n const style = useMemo(() => {\r\n if (!subscription?.allowBranding) {\r\n return '';\r\n }\r\n\r\n const logoUrl = subscription?.brandImageBlobReference?.url;\r\n let brandColor = subscription?.brandColor;\r\n\r\n // Treat a fully black colour as a not being overrided colour.\r\n if (brandColor === '#000000') {\r\n brandColor = '';\r\n }\r\n\r\n let ret = '';\r\n\r\n // If a logo is uploaded against the subscription, swap our brand image for the logo.\r\n if (logoUrl) {\r\n ret += `\r\n .navbar-brand {\r\n background-image: url(\"${logoUrl}\") !important;\r\n }\r\n `;\r\n }\r\n\r\n // If a brand colour is specificed against the subscription, swap our primary colour for the colour.\r\n if (brandColor) {\r\n const borderColor = shadeBlend(-0.2, brandColor);\r\n const hoverColor = shadeBlend(-0.1, brandColor);\r\n\r\n ret += `\r\n /* Text and backgrounds that are primary coloured should be switched to the brand colour. */\r\n .text-primary {\r\n color: ${brandColor} !important;\r\n }\r\n\r\n .bg-primary {\r\n background-color: ${brandColor} !important;\r\n }\r\n\r\n /* Primary buttons should use the brand colour. */\r\n .btn-primary:not(:hover) {\r\n background-color: ${brandColor} !important;\r\n border-color: ${borderColor} !important;\r\n }\r\n\r\n .btn-primary:hover {\r\n background-color: ${hoverColor} !important;\r\n border-color: ${borderColor} !important;\r\n }\r\n\r\n .btn-outline-primary:not(:hover):not(.dropdown-toggle[aria-expanded=\"true\"]) {\r\n color: ${brandColor} !important;\r\n border-color: ${borderColor} !important;\r\n }\r\n\r\n .btn-outline-primary:hover {\r\n background-color: ${hoverColor} !important;\r\n border-color: ${borderColor} !important;\r\n }\r\n\r\n .btn-outline-primary.dropdown-toggle[aria-expanded=\"true\"]:not(:hover) {\r\n background-color: ${brandColor} !important;\r\n border-color: ${borderColor} !important;\r\n }\r\n\r\n .btn-primary.disabled:hover, .btn-outline-primary.disabled:hover {\r\n background-color: transparent !important;\r\n color: ${borderColor} !important;\r\n }\r\n\r\n /* Navigation pills should use the brand colour. */\r\n .pills-nav-bar .nav-item .nav-link:not(.active) {\r\n color: ${brandColor} !important;\r\n border-color: ${borderColor} !important;\r\n }\r\n\r\n .pills-nav-bar .nav-item .nav-link.active {\r\n background-color: ${brandColor} !important;\r\n border-color: ${borderColor} !important;\r\n }\r\n\r\n /* Sidebar links (mostly used on mobile by non-admins) need to use the brand colour */\r\n .sidebar .nav-link.active {\r\n background-color: ${brandColor} !important;\r\n }\r\n\r\n .sidebar .nav-link:hover {\r\n background-color: ${brandColor} !important;\r\n }\r\n `;\r\n }\r\n\r\n return ret;\r\n }, [subscription]);\r\n\r\n return (\r\n \r\n );\r\n};\r\n\r\n/**\r\n * Shade a color.\r\n * \r\n * Taken from v2 universal B from: https://github.com/PimpTrizkit/PJs/wiki/12.-Shade,-Blend-and-Convert-a-Web-Color-(pSBC.js)#stackoverflow-archive-begin\r\n * @param p\r\n * @param c0\r\n * @param c1\r\n */\r\nfunction shadeBlend(p: number, c0: string, c1?: string) {\r\n var n = p < 0 ? p * -1 : p, u = Math.round, w = parseInt;\r\n if (c0.length > 7) {\r\n // eslint-disable-next-line no-mixed-operators\r\n const f = c0.split(\",\"), t = (c1 ? c1 : p < 0 ? \"rgb(0,0,0)\" : \"rgb(255,255,255)\").split(\",\"), R = w(f[0].slice(4)), G = w(f[1]), B = w(f[2]);\r\n // eslint-disable-next-line no-mixed-operators\r\n return \"rgb(\" + (u((w(t[0].slice(4)) - R) * n) + R) + \",\" + (u((w(t[1]) - G) * n) + G) + \",\" + (u((w(t[2]) - B) * n) + B) + \")\"\r\n } else {\r\n // eslint-disable-next-line no-mixed-operators\r\n const f = w(c0.slice(1), 16), t = w((c1 ? c1 : p < 0 ? \"#000000\" : \"#FFFFFF\").slice(1), 16), R1 = f >> 16, G1 = f >> 8 & 0x00FF, B1 = f & 0x0000FF;\r\n // eslint-disable-next-line no-mixed-operators\r\n return \"#\" + (0x1000000 + (u(((t >> 16) - R1) * n) + R1) * 0x10000 + (u(((t >> 8 & 0x00FF) - G1) * n) + G1) * 0x100 + (u(((t & 0x0000FF) - B1) * n) + B1)).toString(16).slice(1)\r\n }\r\n}\r\n","import * as React from 'react';\r\nimport { useLazyQuery } from \"@apollo/react-hooks\";\r\nimport gql from \"graphql-tag\";\r\nimport { AsyncLoadResult, AsyncLoadOptions } from '../../../../shared/abstractStore';\r\nimport { subscriptionStyleOverridesViewModelQuery, subscriptionStyleOverridesViewModelQueryVariables } from '../../generated/subscriptionStyleOverridesViewModelQuery';\r\nimport { mainApiConfig } from '../../../../configure/mainApiConfig';\r\nimport { blobReferenceFieldsFragment } from '../../models/BlobReference';\r\nimport { Guid } from 'guid-string';\r\nimport { subscriptionFieldsFragment } from '../../models/Subscription';\r\n\r\n/**\r\n * View model for SubscriptionStyleOverrides that replaces the call to useSubscription() and loads the right related data.\r\n * @param options\r\n */\r\nexport function useSubscriptionStyleOverridesViewModel(id: string | undefined | null, options: AsyncLoadOptions = {}): AsyncLoadResult {\r\n // Query the data we need form the api.\r\n const [load, { data, loading, error, refetch }] = useLazyQuery(\r\n gql`\r\n query subscriptionStyleOverridesViewModelQuery ($id: ID!) {\r\n model: subscription(id: $id) {\r\n ...subscriptionFields\r\n\r\n brandImageBlobReference {\r\n ...blobReferenceFields\r\n }\r\n }\r\n }\r\n\r\n ${subscriptionFieldsFragment}\r\n ${blobReferenceFieldsFragment}\r\n\r\n `,\r\n {\r\n variables: {\r\n id: id ?? Guid.empty\r\n },\r\n fetchPolicy: options.fetchPolicy ?? mainApiConfig.defaultFetchPolicy,\r\n pollInterval: options.pollInterval,\r\n onCompleted: (data) => {\r\n if (options.onCompleted) {\r\n options.onCompleted(data);\r\n }\r\n }\r\n }\r\n );\r\n\r\n // Run the query (unless we are being lazy).\r\n React.useEffect(() => {\r\n if (!options.lazy) {\r\n load();\r\n }\r\n }, [options.lazy, load])\r\n\r\n // Return the results.\r\n const refresh = React.useCallback(async () => { !refetch ? await load() : await refetch(); }, [refetch, load]);\r\n return React.useMemo(() => ({\r\n data: data ?? ({} as any),\r\n refresh: refresh,\r\n isLoading: loading,\r\n errors: error\r\n }), [data, refresh, loading, error]);\r\n}\r\n","import * as React from 'react';\r\nimport { Layout } from './components/layout/Layout';\r\nimport { ServiceProviderContext } from 'inject-typesafe-react';\r\nimport { createServiceProvider } from './configure/configureServices';\r\nimport { AppRoutes } from './components/shared/AppRoutes';\r\nimport { appRoutes } from './configure/routeConfig';\r\nimport { initializeIcons } from './configure/iconsConfig';\r\nimport { Helmet, HelmetProvider } from 'react-helmet-async';\r\nimport { ApolloProvider } from '@apollo/react-hooks';\r\nimport { apolloClient, apolloCachePersistor } from './configure/configureApollo';\r\nimport { configurei18n } from './configure/i18n';\r\nimport { LoadingIndicator } from './components/shared/LoadingIndicator';\r\nimport { I18nextProvider } from 'react-i18next';\r\nimport authService from './api/api-authorization/AuthorizeService';\r\nimport { configureErrorMessages } from './configure/errorMessageConfig';\r\nimport { RecoilRoot } from 'recoil';\r\nimport { purgeRecoilPersist } from './configure/recoilPersistConfig';\r\nimport { SubscriptionStyleOverrides } from './components/subscriptions/SubscriptionStyleOverrides';\r\n\r\n// Configure services.\r\nconst serviceProvider = createServiceProvider();\r\n\r\n// When the authorization state changes, clear the right parts of our caches.\r\nauthService.subscribe(() => {\r\n purgeRecoilPersist();\r\n apolloCachePersistor.purge();\r\n});\r\n\r\n// Configure icons.\r\ninitializeIcons();\r\n\r\n// Configure i18n\r\nconst i18n = configurei18n();\r\n\r\n// Configure server and 3rd party error messages to make them friendly and translatable.\r\nconfigureErrorMessages();\r\n\r\n\r\n\r\n// App component.\r\nexport const App = () => {\r\n return (\r\n \r\n \r\n \r\n \r\n \r\n }>\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n );\r\n};\r\n","import { ServiceResolver, ServiceProvider, IServiceCollectionBuilder } from \"inject-typesafe\";\r\nimport { AccountService } from \"../api/account\";\r\nimport { ApiFetch } from 'apifetch-json';\r\n\r\n/**\r\n * Returns a configured service provider.\r\n */\r\nexport function createServiceProvider() {\r\n return new ServiceProvider((builder: IServiceCollectionBuilder) => ({\r\n accountService: builder.singleton(services => new AccountService()),\r\n apiFetch: builder.singleton(services => new ApiFetch()),\r\n }));\r\n}\r\n\r\nexport interface AppServices {\r\n accountService: ServiceResolver,\r\n apiFetch: ServiceResolver,\r\n}\r\n\r\n","import i18n from 'i18next';\r\nimport { initReactI18next } from 'react-i18next';\r\nimport LanguageDetector from 'i18next-browser-languagedetector';\r\nimport moment, { isMoment } from 'moment';\r\nimport numeral from 'numeral';\r\nimport { isNumber } from 'util';\r\nimport { findLanguage } from './languageConfig';\r\nimport { localeResources } from '../locales/localeResources';\r\n\r\n/**\r\n * Configure the i18n layer using i18next.\r\n */\r\nexport function configurei18n() {\r\n i18n\r\n // detect user language\r\n // learn more: https://github.com/i18next/i18next-browser-languageDetector\r\n .use(LanguageDetector)\r\n // pass the i18n instance to react-i18next.\r\n .use(initReactI18next)\r\n // init i18next\r\n // for all options read: https://www.i18next.com/overview/configuration-options\r\n .init({\r\n fallbackLng: 'en-GB',\r\n //debug: true,\r\n\r\n resources: {\r\n ...localeResources,\r\n },\r\n\r\n interpolation: {\r\n escapeValue: false, // not needed for react as it escapes by default\r\n\r\n format: function (value, format, lang) {\r\n // Handle dates with moment.\r\n if (value instanceof Date) {\r\n return moment(value).format(format);\r\n } else if (isMoment(value)) {\r\n return moment(value).format(format);\r\n }\r\n\r\n // Handle numbers with numeral.\r\n if (value instanceof Number) {\r\n return numeral(value).format(format);\r\n } else if (isNumber(value)) {\r\n return numeral(value).format(format);\r\n }\r\n\r\n return value;\r\n }\r\n }\r\n });\r\n\r\n // Keep the moment and numeral formats in sync with the i18n formats.\r\n i18n.on('languageChanged', (languageCode) => {\r\n // Find the mapped language for the new language.\r\n const thisLanguage = findLanguage(languageCode);\r\n\r\n moment.locale(thisLanguage?.momentLocale ?? languageCode);\r\n numeral.locale(thisLanguage?.numeralLocale ?? languageCode);\r\n });\r\n\r\n return i18n;\r\n}\r\n","import { registerErrorMessageConverters } from \"../shared/userFriendlyErrorMessage\";\r\nimport i18next from \"i18next\";\r\n\r\n// Register the converters to make friendly versions of error messages.\r\n// This is primarily used to make friendly versions of message from 3rd party libraries, or the server.\r\n// By convention tranlsation keys for returned errors should start \"error.\" rather than \"errorMessageConfig.\".\r\nexport function configureErrorMessages() {\r\n registerErrorMessageConverters([\r\n // Convert the apollo graphql errors message to something more friendly.\r\n (error) => {\r\n let shouldHandle = false;\r\n let message = error?.message ?? error?.toString() ?? ''; /* Sometimes we get an Error sometimes we get a String */\r\n let graphQLErrors: Array = [];\r\n switch (message) {\r\n // Network errors get a friendly message that is nicer given the use of cache for offline support.\r\n case 'Network error: Failed to fetch':\r\n message = i18next.t('error.apollo.networkErrorFailedToFetch', 'Could not synchronize information with the cloud.');\r\n shouldHandle = true;\r\n break;\r\n default:\r\n break;\r\n }\r\n\r\n // Handle graphQL errors as they all start with GraphQL error: in their message.\r\n if (message.indexOf('GraphQL error: ') === 0) {\r\n if (message.indexOf('GraphQL error: GraphQL.Validation.ValidationError: ') === 0) {\r\n message = i18next.t('error.apollo.graphQLValidationError', 'GraphQL error: request is not not a valid GraphQL query or mutation.');\r\n } else if (message.indexOf('GraphQL error: GraphQL.ExecutionError: ') === 0) {\r\n message = i18next.t('error.apollo.graphQLExecutionError', 'GraphQL error: query or mutation could not be executed.');\r\n }\r\n\r\n shouldHandle = true;\r\n }\r\n\r\n // If we have a graphQL errors, then lets handle those as seperate errors for the purpose of showing them.\r\n if (error?.graphQLErrors) {\r\n graphQLErrors = error?.graphQLErrors;\r\n shouldHandle = true;\r\n }\r\n\r\n // If we haven't decided we should handle this error by this point then just skip it.\r\n if (!shouldHandle) {\r\n console.log(error);\r\n return null;\r\n }\r\n\r\n // If we have multiple graphQLErrors in one Error object, lets return one error for each GraphQL error.\r\n if (graphQLErrors.length) {\r\n return graphQLErrors.map(item => ({\r\n message: message,\r\n details: i18next.t('errors.apollo.graphQLErrors.detail', '{{message}} location: {{location}}', { message: item.message, location: item.location }),\r\n error: error,\r\n }));\r\n }\r\n\r\n // Return the error.\r\n return { message, error };\r\n },\r\n\r\n // Convert error messages from the Account REST API to make them translatable.\r\n // Note that the original messages are friendly enough so we just use those for English but pass them for translation.\r\n (error) => {\r\n switch (error?.message) {\r\n // General messages used by multiple actions in the API.\r\n case 'This email does not have an account here.':\r\n return i18next.t('error.accountApi.common.NoAccountHere', 'This email does not have an account here.');\r\n case 'This account is not allowed to use this site.':\r\n return i18next.t('error.accountApi.common.notAllowed', 'This account is not allowed to use this site.');\r\n case '\"This account has been locked out, please try again later.':\r\n return i18next.t('error.accountApi.common.lockedOut', '\"This account has been locked out, please try again later.');\r\n case 'This email is already registered.':\r\n return i18next.t('error.accountApi.common.alreadyRegistered', 'This email is already registered.');\r\n case 'Unknown user':\r\n return i18next.t('error.accountApi.common.unknownUser', 'Unknown user');\r\n\r\n // Specific messages that are only used by individual actions.\r\n // Login\r\n case 'Invalid password':\r\n return i18next.t('error.accountApi.login.invalidPassword', 'Invalid password');\r\n // CreateAccountForExternalLogin\r\n case 'Error loading external login information during confirmation.':\r\n return i18next.t('error.accountApi.createAccountForExternalLogin', 'Error loading external login information during confirmation.');\r\n // CompleteExternalLogin\r\n case 'Error loading external login information.':\r\n return i18next.t('error.accountApi.completeExternalLogin.errorLoadingExternalLoginInformation', 'Error loading external login information.');\r\n // SendPasswordResetModel\r\n case 'This email has not been confirmed, so we can\\'t send a password reset until it has been confirmed.':\r\n return i18next.t('error.accountApi.sendPasswordReset.errorConfirmingChange', 'This email has not been confirmed, so we can\\'t send a password reset until it has been confirmed.');\r\n // ConfirmEmail\r\n case 'Error confirming your email.':\r\n return i18next.t('error.accountApi.confirmEmail.errorConfirmingEmail', 'Error confirming your email.');\r\n // ConfirmEmailChange\r\n case 'Error changing email.':\r\n return i18next.t('error.accountApi.errorChangingEmail', 'Error changing email.');\r\n // ConfirmInvite\r\n case 'This email has not been invited.':\r\n return i18next.t('error.accountApi.confirmInvite.notInvited', 'This email has not been invited.');\r\n case 'This invite has already been accepted.':\r\n return i18next.t('error.accountApi.confirmInvite.alreadyAccepted', 'This invite has already been accepted.');\r\n // Lockout\r\n case 'Error setting lockout for user':\r\n return i18next.t('error.accountApi.lockout.errorSettingLockout', 'Error setting lockout for user');\r\n default:\r\n break;\r\n }\r\n\r\n // Handle external authentication provider errors (from CompleteExternalLogin) by passing on the error with a chance to translate the prefix.\r\n if (error?.message?.indexOf('Error from external provider: ') === 0) {\r\n const externalProviderError = error.message.subStr(30);\r\n return i18next.t('error.accountApi.completeExternalLogin.externalProviderError', 'Error from external provider: {{error}}', { error: externalProviderError });\r\n }\r\n\r\n return null;\r\n },\r\n\r\n //(error) => {\r\n // // If we are in debug mode, log any error messages we get that were not made friendly.\r\n // console.debug(error);\r\n //}\r\n ]);\r\n}\r\n","// In production, we register a service worker to serve assets from local cache.\r\n\r\n// This lets the app load faster on subsequent visits in production, and gives\r\n// it offline capabilities. However, it also means that developers (and users)\r\n// will only see deployed updates on the \"N+1\" visit to a page, since previously\r\n// cached resources are updated in the background.\r\n\r\n// To learn more about the benefits of this model, read https://goo.gl/KwvDNy.\r\n// This link also includes instructions on opting out of this behavior.\r\n\r\n//let window: any;\r\n\r\nconst isLocalhost = Boolean(\r\n window.location.hostname === 'localhost' ||\r\n // [::1] is the IPv6 localhost address.\r\n window.location.hostname === '[::1]' ||\r\n // 127.0.0.1/8 is considered localhost for IPv4.\r\n window.location.hostname.match(\r\n /^127(?:\\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$/\r\n )\r\n);\r\n\r\nexport default function register() {\r\n if (process.env.NODE_ENV === 'production' && 'serviceWorker' in navigator) {\r\n // The URL constructor is available in all browsers that support SW.\r\n const publicUrl = new URL(process.env.PUBLIC_URL, window.location.href);\r\n if (publicUrl.origin !== window.location.origin) {\r\n // Our service worker won't work if PUBLIC_URL is on a different origin\r\n // from what our page is served on. This might happen if a CDN is used to\r\n // serve assets; see https://github.com/facebookincubator/create-react-app/issues/2374\r\n return;\r\n }\r\n\r\n window.addEventListener('load', () => {\r\n const swUrl = `${process.env.PUBLIC_URL}/service-worker.js`;\r\n\r\n if (isLocalhost) {\r\n // This is running on localhost. Lets check if a service worker still exists or not.\r\n checkValidServiceWorker(swUrl);\r\n } else {\r\n // Is not local host. Just register service worker\r\n registerValidSW(swUrl);\r\n }\r\n });\r\n }\r\n}\r\n\r\nfunction registerValidSW(swUrl: any) {\r\n navigator.serviceWorker\r\n .register(swUrl)\r\n .then(registration => {\r\n registration.onupdatefound = () => {\r\n const installingWorker: any = registration.installing;\r\n installingWorker.onstatechange = () => {\r\n if (installingWorker.state === 'installed') {\r\n if (navigator.serviceWorker.controller) {\r\n // At this point, the old content will have been purged and\r\n // the fresh content will have been added to the cache.\r\n // It's the perfect time to display a \"New content is\r\n // available; please refresh.\" message in your web app.\r\n console.log('New content is available; please refresh.');\r\n } else {\r\n // At this point, everything has been precached.\r\n // It's the perfect time to display a\r\n // \"Content is cached for offline use.\" message.\r\n console.log('Content is cached for offline use.');\r\n }\r\n }\r\n };\r\n };\r\n })\r\n .catch(error => {\r\n console.error('Error during service worker registration:', error);\r\n });\r\n}\r\n\r\nfunction checkValidServiceWorker(swUrl: any) {\r\n // Check if the service worker can be found. If it can't reload the page.\r\n fetch(swUrl)\r\n .then((response: any) => {\r\n // Ensure service worker exists, and that we really are getting a JS file.\r\n if (\r\n response.status === 404 ||\r\n response.headers.get('content-type').indexOf('javascript') === -1\r\n ) {\r\n // No service worker found. Probably a different app. Reload the page.\r\n navigator.serviceWorker.ready.then(registration => {\r\n registration.unregister().then(() => {\r\n window.location.reload();\r\n });\r\n });\r\n } else {\r\n // Service worker found. Proceed as normal.\r\n registerValidSW(swUrl);\r\n }\r\n })\r\n .catch(() => {\r\n console.log(\r\n 'No internet connection found. App is running in offline mode.'\r\n );\r\n });\r\n}\r\n\r\nexport function unregister() {\r\n if ('serviceWorker' in navigator) {\r\n navigator.serviceWorker.ready.then(registration => {\r\n registration.unregister();\r\n });\r\n }\r\n}\r\n","import { ReportHandler } from 'web-vitals';\r\n\r\nconst reportWebVitals = (onPerfEntry?: ReportHandler) => {\r\n if (onPerfEntry && onPerfEntry instanceof Function) {\r\n import('web-vitals').then(({ getCLS, getFID, getFCP, getLCP, getTTFB }) => {\r\n getCLS(onPerfEntry);\r\n getFID(onPerfEntry);\r\n getFCP(onPerfEntry);\r\n getLCP(onPerfEntry);\r\n getTTFB(onPerfEntry);\r\n });\r\n }\r\n};\r\n\r\nexport default reportWebVitals;\r\n","import './configure/polyfill';\r\n\r\nimport * as React from 'react';\r\nimport * as ReactDOM from 'react-dom';\r\nimport { BrowserRouter } from 'react-router-dom';\r\nimport { App } from './App';\r\nimport registerServiceWorker from './registerServiceWorker';\r\nimport reportWebVitals from './reportWebVitals';\r\n\r\nconst baseUrl = document.getElementsByTagName('base')[0].getAttribute('href') || undefined;\r\nconst rootElement = document.getElementById('root');\r\n\r\nReactDOM.render(\r\n \r\n \r\n ,\r\n rootElement);\r\n\r\nregisterServiceWorker();\r\n\r\n// If you want to start measuring performance in your app, pass a function\r\n// to log results (for example: reportWebVitals(console.log))\r\n// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals\r\nreportWebVitals();\r\n\r\n"],"sourceRoot":""}