{"version":3,"file":"main.7e2a75a5742a155c.js","mappings":"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","names":["defaultOptions","allowAnonymous","BaseHubService","constructor","hub","options","this","hubUrl","environment","Utilities","subscriptions","inject","AuthService","getLoginStatusEvent","subscribe","isLoggedIn","isConnected","connection","stop","connect","HubConnectionState","includes","state","HubConnectionBuilder","withUrl","withAutomaticReconnect","nextRetryDelayInMilliseconds","retryContext","previousRetryCount","build","connect$","Promise","resolve","reject","start","then","catch","error","ngOnDestroy","unsubscribe","factory","AccountHubService","authService","super","onRefresh","refresh$","from","pipe","mergeMap","Subject","on","refreshUser","catchError","err","console","warn","EMPTY","user","next","asObservable","throwError","i0","AppComponent","storageManager","router","document","accountHubService","initialiseStorageSyncListener","status","signOut","of","finalizeInit","loginOption","localStorage","getItem","Constants","Utility","events","event","NavigationStart","isBusy","NavigationEnd","NavigationCancel","NavigationError","redirectLogoutUser","reLoginDelegate","refreshAccountSubscription","DOCUMENT","selectors","AvatarDialogComponent","data","dialogRef","studentService","formBuilder","appComponent","buildPreferredContactOptions","buildBestTimeToReachOptions","imageUrl","student","id","showStudentPageLink","hideStudentPageLink","form","group","ngOnInit","returnStudentInformationById","studentInformation","phonePattern","notes","Validators","guardianName","preferredWayToContactGuardian","bestTimeToReachGuardian","guardianPhoneNumber","guardianEmailAddress","guardianIsSubscribedToWeeklySnapshotEmail","secondaryGuardianIsSubscribedToWeeklySnapshotEmail","guardianRelationship","secondaryGuardianName","secondaryGuardianPhoneNumber","secondaryGuardianEmailAddress","secondaryGuardianRelationship","preferredWayToContactStudent","bestTimeToReachStudent","homeAddress","city","county","zipCode","notesAboutMe","studentPhoneNumber","studentEmailAddress","studentBirthday","studentId","schoolEmailAddress","studentEmail","confirm","valid","item","Object","assign","value","updateStudentInformation","formDirective","resetForm","close","normalizeResult","keyDown","e","enterKeyCode","keyCode","pristine","preventDefault","bestTimeToReachOptions","filter","option","name","preferredContactOptions","result","push","MAT_DIALOG_DATA","ctx","ConfirmationDialogComponent","_a","confirmationMessage","_b","title","cancel","DialogComponent","_hasTitleIcon","titleIcon","length","_hasNotes","_hasPanel","hasPanel","_isDefault","dialogType","_isPrimary","_isSecondary","_isSuccess","_isDanger","_isWarning","_isInfo","_fullWidth","fullWidth","GradeLevelSelectorComponent","EventEmitter","selectedGrades","gradeListK5","grade","selected","gradeList68","gradeList912","_selectedGrades","gradesK5Selected","some","x","grades68Selected","grades912Selected","toggleKThrough5","gradesSelected","emit","Set","g","toggle6Through8","toggle9Through12","gradeSelectedChange","outputGrades","SignaturePadComponent","elementRef","onBeginEvent","onEndEvent","ngAfterContentInit","canvas","nativeElement","querySelector","canvasHeight","height","canvasWidth","width","signaturePad","SignaturePadNative","onBegin","bind","onEnd","resizeCanvas","ratio","Math","max","window","devicePixelRatio","offsetWidth","offsetHeight","getContext","scale","clear","toData","fromData","points","toDataURL","imageType","quality","fromDataURL","dataURL","hasOwnProperty","isEmpty","off","set","queryPad","SignatureFieldComponent","backgroundColor","penColor","signature","_signature","propagateChange","writeValue","registerOnChange","fn","registerOnTouched","ngAfterViewInit","drawBegin","drawComplete","disableSignaturePad","enableSignaturePad","provide","NG_VALUE_ACCESSOR","useExisting","forwardRef","multi","decls","ToolbarComponent","commonService","isSignedIn","cachedValue","loginType","Number","getEnvironment","message","toUpperCase","logout","_componentDestroyed$","complete","changeGradeLevel","setStudentGradeLevel","currentUser","userId","location","reload","TypeSafeMatCellDef","MatCellDef","static","dir","t","CdkCellDef","ClassDialogComponent","Trend","MatTableDataSource","isPerformance","endDate","startDate","dateRangeColumns","allTimeColumns","shift","pop","isCurrent","today","Date","getFullYear","getMonth","getDate","asOfDate","dataSource","returnClassUsersByStudentId","classUsers","studentClasses","studentClass","EnrollmentStatus","sort","noResultsMessage","getStatusName","classUser","MatSort","NotAuthorizedComponent","userName","email","signedIn","PageNotFoundComponent","goBack","back","INTL_DATE_INPUT_FORMAT","year","month","day","hourCycle","hour","minute","hour12","MAT_DATE_FORMATS","parse","dateInput","display","monthYearLabel","dateA11yLabel","monthYearA11yLabel","DesignModule","NGX_MAT_DATE_FORMATS","useValue","imports","AngularEditorModule","CommonModule","FormsModule","ReactiveFormsModule","LazyLoadImageModule","MatAutocompleteModule","MatBottomSheetModule","MatButtonModule","MatButtonToggleModule","MatCardModule","MatCheckboxModule","MatChipsModule","MatDatepickerModule","MatDialogModule","MatDividerModule","MatExpansionModule","MatFormFieldModule","MatGridListModule","MatIconModule","MatInputModule","MatListModule","MatMenuModule","MatNativeDateModule","MatPaginatorModule","MatProgressBarModule","MatRadioModule","MatSelectModule","MatSidenavModule","MatSnackBarModule","MatSortModule","MatTableModule","MatTabsModule","MatSlideToggleModule","MatToolbarModule","MatTooltipModule","MatProgressSpinnerModule","MatTableExporterModule","NgxMatDatetimePickerModule","NgxMatTimepickerModule","NgxMatNativeDateModule","RouterModule","UiScrollModule","FlexLayoutModule","MatBadgeModule","AppEnvironment","UserRoles","AuthenticationGuard","navigationService","canActivate","route","redirectUrl","url","navigateByUrl","AdminGuard","authorizationService","isAdmin","getUserByUserName","map","AuthorizationGuard","_zone","orientationService","snackBar","isStaff","setTimeout","run","getStudentStepsAndProgress","parseInt","toString","hasCompletedAllSteps","studentProgress","completedSteps","totalSteps","open","duration","MentorAdminGuard","isMentor","MentorGuard","StaffGuard","TeacherGuard","isTeacher","DBkeys","renderer2","appendScript","createElement","type","src","createRenderer","appendChild","body","paramString","params","param","split","keyValue","splitInTwo","firstPart","secondPart","text","separator","separatorIndex","indexOf","substr","trim","JSON","replace","subString","charAt","toLowerCase","base","origin","protocol","hostname","port","AdminService","ApiService","http","returnBreaks","get","returnInterventionThresholds","returnAppShortcuts","createBreak","post","uploadEnrollmentImportData","file","addAppTileMetadata","appTile","updateInterventionThreshold","put","updateEnrollments","items","updateAppTileMetadata","uploadAppTileMetadataImage","updateAppTileGradeLevels","updateStaffMember","staff","deleteBreak","delete","returnStudentResources","addStudentResource","studentResource","updateStudentResource","updateStudentResourceGradeLevels","deleteStudentResource","deleteAppShortcut","deleteElectiveGroupChoice","electiveGroupChoice","deleteElectiveGroup","electiveGroup","createElectiveGroup","createElectiveGroupChoice","updateElectiveGroup","addElective","elective","updateElective","deleteElective","updateElectiveSettings","electiveSettings","returnAppShortcutsBySearch","searchTerm","addAppTileMetadataContent","shortcutContentModel","returnStudentResourcesBySearch","addStudentResourcesContent","studentResourceContent","UserDtoModel","isInRole","isInterventionist","isReFuelCoordinator","isSecondaryMentor","signInProvider","hasAnyViewRole","rolePrefix","roles","r","startsWith","role","undefined","ApiBase","baseUrl","_get","getUrl","buildUrl","_getById","encodeURIComponent","_getBySearch","ops","merge","query","_post","postUrl","_put","putUrl","_putById","_delete","deleteUrl","_deleteByItem","apiOptions","_count","head","observe","resp","headers","_downloadFile","downloadUrl","reportProgress","responseType","tap","HttpEventType","filename","rootUrl","queryString","toQueryString","relativeUrl","substring","endsWith","withQuestionMark","URLSearchParams","key","appendArray","elem","append","toISOString","Array","isArray","ControllerBase","controller","$get","$getById","$getBySearch","$post","$put","$putById","$delete","$deleteByItem","$getCount","AccountApiService","signIn","password","rememberMe","backdoor","me","confirmEmail","emailAddress","code","resendConfirmEmail","forgotPassword","resetPassword","impersonate","identityId","abortImpersonate","updateProfile","accountApiService","initializeLoginStatus","getDataObject","reevaluateLoginStatus","savePermanentData","getReturnUrl","redirect","loginRedirectUrl","urlParamsAndFragment","urlAndParams","navigationExtras","fragment","queryParams","queryParamsHandling","extras","wholePart","redirectLoginUser","returnUrl","getData","LocalStoreManager","deleteData","navigate","logoutRedirectUrl","redirectForLogin","reLogin","response","processLoginResponse","switchMap","service","Observable","subscriber","refreshing","subscription","sub","impersonateUser","clearUser","loginStatus","saveUserDetails","saveData","previousIsLoggedInCheck","getInitEvent","AuthorizationService","username","CommonService","httpBackend","getAllStudents","alwaysIncludeActive","Boolean","join","getAllStaff","getMentors","hasMentees","getCounselors","gradeLevel","getStudentsByMentor","mentorId","getStudentById","apiUrl","isPerformanceSnapshot","setDate","adjustedStartDate","adjustedEndDate","returnElectivesBySearch","returnElectives","returnElectiveGroups","returnElectiveSettings","assignMentorToStudent","setAdmin","setTeacher","setReFuelCoordinator","setInterventionist","assignStudentsToMentor","studentList","sendMessageToMentor","sendErrorEmail","assignSecondaryMentorToStudent","unsubscribeFromWeeklySnapshotEmail","studentGoogleId","HttpClient","obj","returnStaffBySearch","returnUserById","returnStudentResourceById","returnAppShortcutById","DirectoryService","returnUnreadInboxCount","returnCalendarEvents","now","sendCommunicationEmail","formData","FormData","fromEmailAddress","subject","bccAllRecipients","attachment","attachments","i","optionalRecipients","includeStudent","userEmailAddress","includeGuardian1","includeGuardian2","includeMentor","mentorEmail","includeStaff","validAdditionalRecipients","additionalRecipients","interventionId","StudentService","newValue","sessionStorage","localStorageSetItem","removeItem","syncKeys","loadSyncKeys","syncKeysContains","sessionStorageSetItem","onInit","addToSessionStorageHelper","removeFromSessionStorageHelper","clearInstanceSessionStorage","addToSyncKeysHelper","removeFromSyncKeysHelper","syncListenerInitialised","addEventListener","sessionStorageTransferHandler","syncSessionStorage","deinitialiseStorageSyncListener","removeEventListener","clearAllStorage","clearAllSessionsStorage","clearLocalStorage","DBKEY_SYNC_KEYS","DBKEY_USER_DATA","saveSyncedSessionData","saveSessionData","testForInvalidKeys","removeFromSyncKeys","addToSessionStorage","removeFromSessionStorage","moveDataToSessionStorage","moveDataToSyncedSessionStorage","moveDataToPermanentStorage","exists","sessionStorageGetItem","localStorageGetItem","isDateType","initEvent","setItem","addToSyncKeysBackup","keyToRemove","removeFromSyncKeysBackup","Error","reservedKeys","getSyncKeysFromStorage","defaultValue","storedSyncKeys","index","splice","stringify","NavigationService","BehaviorSubject","studentSteps$","takeUntil","onDestroy$","redirectUrlKey","navigateToStep","step","skipLocationChange","contentFileName","relativeTo","pushUpdatedStudentStepsAndProgress","studentSteps","OrientationService","date","toLocaleDateString","returnSteps","returnStepContent","stepId","returnStudentSignatureContent","signatureContentId","returnQuizContent","quizContentId","returnCommunityPassportForms","returnCommunityPassportFormByGradeLevel","createStep","updateStep","deleteStep","updateStepOrder","steps","updateStudentSignatureContent","duplicateStep","resetStudentOrientation","getStepIntro","getStepConnectionSurveyData","getUserQuizAnswers","semester","schoolYear","getOrientationReportData","getStepSendUsASelfieData","completeStep","stayOnStepAfterComplete","panelClass","skipHand2HandStep","submitConnectionSurveyStep","startOrientation","submitUserQuizAnswers","generateEmailVerificationCode","submitVerificationCode","verificationCode","codeIsCorrect","submitUserElectivesStep","submitSendUsASelfieStep","controllerUrlPrefix","buildStandardHeaders","format","parseResponse","File","postFile","putFile","httpHeaders","Accept","TimezoneOffset","getTimezoneOffset","keys","forEach","HttpHeaders","staffPath","adminPath","mentorPath","reportsPath","teacherPath","reFuelCoordinatorPath","studentPath","interventionsPath","html","files","iteration","f","setUniqueFileName","defineProperty","writable","getEasternTime","getDay","setHours","setMinutes","setSeconds","setMilliseconds","getBeginningOfWeek","getHours","diff","toLocaleString","timeZone","records","outputString","end","a","b","unshift","j","startGradeLevel","endGradeLevel","totalSeconds","minutes","floor","hours","days","timeFormatBuilder","getElementById","setAttribute","test","String","getAdminNavigationTab","getReportsNavigationTab","getStaffNavigationTab","getTeacherNavigationTab","getCommunicationNavigationTab","getInterventionNavigationTab","tab","adminTab","createDropdownTab","engagementSubmenu","tabs","createRouterTab","orientationSubmenu","signupsSubmenu","studentDashboardSubmenu","userSettingsSubmenu","reportsTab","interventionsTab","label","path","formattedPathParts","routerPath","configuration","cacheLocation","expireOffsetSeconds","inboxUrl","microsoftInboxUrl","chatUrl","storageUrl","appInsightsConfiguration","connectionString","enableAutoRouteTracking","GlobalLoadingIndicatorService","isLoading","startEvent","suppressNextEventCount","eventCount","endEvent","eventRunning","suppressNextEvent","ApiHttpInterceptor","globalLoadingIndicatorService","intercept","request","setHeaders","clone","loadingEventRunning","handle","HttpResponse","convert","finalize","isRequest","isIsoDateString","isoDateFormat","AuthCallbackComponent","log","afterDismissed","EmailOptOutComponent","snapshot","href","goHome","LoginComponent","color","loginOptions","selectedLoginOption","initializing","selectLogin","chooseNewLogin","provider","providerInput","externalSignInForm","submit","ResourcesComponent","adminService","resourcesByCategoryK5","buildGradeMap","gradesK5","resourcesByCategory68","grades68","resourcesByCategory912","grades912","gradeLevels","resourceMap","Map","filtered","resource","resourceGradeLevels","studentResourceGradeLevels","has","category","routes","component","loadChildren","m","StaffModule","StudentModule","redirectTo","AppRoutingModule","scrollPositionRestoration","onSameUrlNavigation","relativeLinkResolution","ErrorService","getClientErrorMessage","getServerErrorMessage","navigator","onLine","getClientStack","stack","getServerStack","ApplicationInsightsService","appInsights","ApplicationInsights","config","loadAppInsights","GlobalErrorHandler","injector","appInsightsService","handleError","errorService","stackTrace","trackException","exception","serverError","HttpErrorResponse","mes","MatSnackBarConfig","verticalPosition","horizontalPosition","onActionSubscription","onAction","dismiss","newError","em","chunkFailedErrorMessage","match","ServerErrorInterceptor","method","AppModule","ReactiveFormConfig","internationalization","dateFormat","seperator","validationMessage","range","required","minLength","maxLength","minNumber","maxNumber","minDate","maxDate","notEmpty","requiredTrue","alpha","numeric","alphaNumeric","ascii","compare","matDatepickerParse","bootstrap","HTTP_INTERCEPTORS","useClass","ErrorHandler","BrowserModule","BrowserAnimationsModule","HttpClientModule","NgxMaskModule","enableProdMode","__NgCli_bootstrap_1","bootstrapModule"],"sourceRoot":"webpack:///","sources":["./src/app/services/api/base-hub.service.ts","./src/app/modules/account/services/account-hub.service.ts","./src/app/app.component.html","./src/app/app.component.ts","./src/app/design/components/avatar-dialog/avatar-dialog.component.html","./src/app/design/components/avatar-dialog/avatar-dialog.component.ts","./src/app/design/components/confirmation-dialog/confirmation-dialog.component.ts","./src/app/design/components/confirmation-dialog/confirmation-dialog.component.html","./src/app/design/components/dialog/dialog.component.ts","./src/app/design/components/dialog/dialog.component.html","./src/app/design/components/grade-level-selector/grade-level-selector.component.html","./src/app/design/components/grade-level-selector/grade-level-selector.component.ts","./src/app/design/components/signature-pad/signature-pad.component.ts","./src/app/design/components/signature-field/signature-field.component.ts","./src/app/design/components/signature-field/signature-field.component.html","./src/app/design/components/toolbar/toolbar.component.html","./src/app/design/components/toolbar/toolbar.component.ts","./src/app/design/directives/type-safe-mat-cell-def.directive.ts","./src/app/design/components/class-dialog/class-dialog.component.html","./src/app/design/components/class-dialog/class-dialog.component.ts","./src/app/design/components/not-authorized/not-authorized.component.html","./src/app/design/components/not-authorized/not-authorized.component.ts","./src/app/design/components/page-not-found/page-not-found.component.ts","./src/app/design/components/page-not-found/page-not-found.component.html","./src/app/design/design.module.ts","./src/app/enums/enrollment-status.enum.ts","./src/app/enums/repository/app-environment.enum.ts","./src/app/enums/repository/user-roles.enum.ts","./src/app/enums/trend.enum.ts","./src/app/guards/authentication.guard.ts","./src/app/guards/admin.guard.ts","./src/app/guards/authorization.guard.ts","./src/app/guards/mentor-admin.guard.ts","./src/app/guards/mentor.guard.ts","./src/app/guards/staff.guard.ts","./src/app/guards/teacher.guard.ts","./src/app/helpers/constants/db-keys.constants.ts","./src/app/helpers/utilities/utilities.ts","./src/app/services/admin.service.ts","./src/app/modules/account/models/user-dto.model.ts","./src/app/services/api/api-base.service.ts","./src/app/services/api/controller-base.ts","./src/app/modules/account/services/account-api.service.ts","./src/app/services/auth/auth.service.ts","./src/app/services/authorization.service.ts","./src/app/services/common.service.ts","./src/app/services/directory.service.ts","./src/app/services/student.service.ts","./src/app/services/local-store-manager.service.ts","./src/app/services/navigation.service.ts","./src/app/services/orientation.service.ts","./src/app/shared/api.service.ts","./src/app/shared/constants.ts","./src/app/shared/utility.ts","./src/environments/environment.definition.ts","./src/environments/environment.testing.ts","./src/app/services/global-loading-indicator.service.ts","./src/app/services/api/api.http-interceptor.ts","./src/app/components/auth-callback/auth-callback.component.ts","./src/app/components/auth-callback/auth-callback.component.html","./src/app/components/email-opt-out/email-opt-out.component.ts","./src/app/components/email-opt-out/email-opt-out.component.html","./src/app/components/login/login.component.html","./src/app/components/login/login.component.ts","./src/app/components/resources/resources.component.html","./src/app/components/resources/resources.component.ts","./src/app/app-routing.module.ts","./src/app/services/error.service.ts","./src/app/services/application-insights.service.ts","./src/app/global-error-handler.ts","./src/app/server-error-interceptor.ts","./src/app/app.module.ts","./src/main.ts"],"sourcesContent":["import { Injectable, OnDestroy, inject } from \"@angular/core\";\r\nimport { HubConnection, HubConnectionBuilder, HubConnectionState, RetryContext } from \"@microsoft/signalr\";\r\nimport { Utilities } from \"app/helpers/utilities/utilities\";\r\nimport { environment } from \"environments/environment\";\r\nimport { Subscription } from \"rxjs\";\r\nimport { AuthService } from \"../auth/auth.service\";\r\n\r\nexport type HubServiceOptions = { allowAnonymous?: boolean };\r\nconst defaultOptions: HubServiceOptions = { allowAnonymous: false };\r\n\r\n@Injectable({\r\n providedIn: \"root\",\r\n})\r\nexport abstract class BaseHubService implements OnDestroy {\r\n private connect$: Promise;\r\n\r\n protected readonly subscriptions: Subscription;\r\n protected connection: HubConnection;\r\n protected hubUrl: string;\r\n\r\n constructor(hub: string, options = defaultOptions) {\r\n this.hubUrl = `${environment.baseUrl || Utilities.baseUrl()}/api/${hub}`;\r\n\r\n if (!options.allowAnonymous) {\r\n this.subscriptions = inject(AuthService)\r\n .getLoginStatusEvent()\r\n .subscribe(isLoggedIn => {\r\n if (!isLoggedIn && this.isConnected) {\r\n this.connection.stop(); // terminate the connection once logged out because this hub requires the user to be authenticated\r\n this.connection = null;\r\n }\r\n });\r\n }\r\n }\r\n\r\n protected connect() {\r\n if (\r\n [HubConnectionState.Connected, HubConnectionState.Connecting, HubConnectionState.Reconnecting].includes(\r\n this.connection?.state\r\n )\r\n ) {\r\n return this.connect$;\r\n }\r\n if (!this.connection) {\r\n this.connection = new HubConnectionBuilder()\r\n .withUrl(this.hubUrl)\r\n .withAutomaticReconnect({\r\n nextRetryDelayInMilliseconds: (retryContext: RetryContext): number | null => {\r\n // the default retry behavior retries connection after 0 seconds, 2 seconds, 10 seconds, and one last time at 30 seconds.\r\n // this custom retry policy does the same thing, but instead of giving up after 30 seconds, we try to reconnect every minute forever or until the connection is null\r\n if (!this.connection) {\r\n return null;\r\n }\r\n\r\n switch (retryContext.previousRetryCount) {\r\n case 0:\r\n return 0;\r\n case 1:\r\n return 2000;\r\n case 2:\r\n return 10000;\r\n case 3:\r\n return 30000;\r\n default:\r\n return 60000;\r\n }\r\n },\r\n })\r\n .build();\r\n }\r\n this.connect$ = new Promise((resolve, reject) => {\r\n this.connection\r\n .start()\r\n .then(() => {\r\n resolve();\r\n })\r\n .catch(error => reject(error));\r\n });\r\n return this.connect$;\r\n }\r\n\r\n public get isConnected() {\r\n return this.connection?.state == HubConnectionState.Connected;\r\n }\r\n\r\n ngOnDestroy(): void {\r\n if (this.isConnected) {\r\n this.connection?.stop();\r\n }\r\n this.subscriptions?.unsubscribe();\r\n }\r\n}\r\n","import { Injectable } from \"@angular/core\";\r\nimport { BaseHubService } from \"@services/api/base-hub.service\";\r\nimport { AuthService } from \"@services/auth/auth.service\";\r\nimport { EMPTY, from, Subject, throwError } from \"rxjs\";\r\nimport { catchError, mergeMap } from \"rxjs/operators\";\r\n\r\n@Injectable({\r\n providedIn: \"root\",\r\n})\r\nexport class AccountHubService extends BaseHubService {\r\n private refresh$: Subject;\r\n\r\n constructor(private authService: AuthService) {\r\n super(\"account/hub\");\r\n }\r\n\r\n onRefresh() {\r\n if (!this.authService.isLoggedIn) {\r\n return throwError(\"Not signed in.\");\r\n }\r\n\r\n if (this.refresh$) {\r\n return this.refresh$;\r\n }\r\n\r\n // ensure a connection\r\n return from(this.connect()).pipe(\r\n mergeMap(() => {\r\n this.refresh$ = new Subject();\r\n\r\n this.connection.on(\"Refresh\", () => {\r\n if (this.authService.isLoggedIn) {\r\n this.authService\r\n .refreshUser()\r\n .pipe(\r\n catchError(err => {\r\n // this error would have been caught and handled elsewhere, so just log this error to the console and return null\r\n console.warn(err);\r\n return EMPTY;\r\n })\r\n )\r\n .subscribe(user => {\r\n if (user) {\r\n this.refresh$.next();\r\n }\r\n });\r\n }\r\n });\r\n\r\n return this.refresh$.asObservable();\r\n })\r\n );\r\n }\r\n}\r\n","\r\n\r\n","import { Component, Inject } from \"@angular/core\";\r\n\r\nimport { DOCUMENT } from \"@angular/common\";\r\nimport { Event, NavigationCancel, NavigationEnd, NavigationError, NavigationStart, Router } from \"@angular/router\";\r\nimport { AuthService } from \"@services/auth/auth.service\";\r\nimport { LocalStoreManager } from \"@services/local-store-manager.service\";\r\nimport { Subscription, of } from \"rxjs\";\r\nimport { catchError } from \"rxjs/operators\";\r\nimport { AccountHubService } from \"./modules/account/services/account-hub.service\";\r\nimport { Constants, Utility } from \"./shared\";\r\n\r\n@Component({\r\n selector: \"app-root\",\r\n templateUrl: \"./app.component.html\",\r\n styleUrls: [\"./app.component.scss\"],\r\n})\r\nexport class AppComponent {\r\n title = \"iCademyEnrollmentWeb\";\r\n isBusy = false;\r\n refreshAccountSubscription: Subscription;\r\n\r\n constructor(\r\n storageManager: LocalStoreManager,\r\n private router: Router,\r\n @Inject(DOCUMENT) private document: HTMLDocument,\r\n private authService: AuthService,\r\n private accountHubService: AccountHubService\r\n ) {\r\n storageManager.initialiseStorageSyncListener();\r\n\r\n if (this.authService.isLoggedIn) {\r\n this.authService\r\n .refreshUser()\r\n .pipe(\r\n catchError(err => {\r\n if (err.status === 401) {\r\n this.signOut();\r\n }\r\n\r\n return of(false);\r\n })\r\n )\r\n .subscribe();\r\n }\r\n\r\n this.finalizeInit();\r\n\r\n const loginOption = localStorage.getItem(Constants.loginTypeKey);\r\n Utility.setFavicon(loginOption, this.document);\r\n\r\n this.router.events.subscribe((event: Event) => {\r\n switch (true) {\r\n case event instanceof NavigationStart: {\r\n this.isBusy = true;\r\n break;\r\n }\r\n case event instanceof NavigationEnd:\r\n case event instanceof NavigationCancel:\r\n case event instanceof NavigationError: {\r\n this.isBusy = false;\r\n break;\r\n }\r\n default: {\r\n break;\r\n }\r\n }\r\n });\r\n }\r\n\r\n signOut(): void {\r\n this.authService.signOut().subscribe();\r\n this.authService.redirectLogoutUser();\r\n }\r\n\r\n private finalizeInit() {\r\n this.authService.reLoginDelegate = () => {};\r\n\r\n this.authService.getLoginStatusEvent().subscribe(() => {\r\n if (this.authService.isLoggedIn) {\r\n if (!this.refreshAccountSubscription) {\r\n this.refreshAccountSubscription = this.accountHubService.onRefresh().subscribe();\r\n }\r\n } else {\r\n this.refreshAccountSubscription?.unsubscribe();\r\n this.refreshAccountSubscription = null;\r\n }\r\n });\r\n }\r\n}\r\n","
\r\n \r\n
\r\n {{ student.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 \r\n \r\n \r\n The max length is 250 characters.\r\n \r\n \r\n \r\n \r\n \r\n \r\n The max length is 1000 characters.\r\n \r\n \r\n \r\n \r\n \r\n \r\n The max length is 100 characters.\r\n \r\n \r\n \r\n \r\n \r\n \r\n The max length is 60 characters.\r\n \r\n \r\n
\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n The max length is 100 characters.\r\n \r\n \r\n \r\n \r\n The max length is 40 characters.\r\n \r\n \r\n \r\n \r\n Zip codes must be 5 digits.\r\n \r\n \r\n \r\n \r\n The max length is 25 characters.\r\n \r\n
\r\n \r\n \r\n \r\n {{ option.name }}\r\n \r\n \r\n \r\n \r\n \r\n Guardian Subscribed to\r\n
\r\n Weekly Snapshot Email\r\n
\r\n
\r\n \r\n Secondary Guardian Subscribed to\r\n
\r\n Weekly Snapshot Email\r\n
\r\n
\r\n \r\n \r\n \r\n {{ option.name }}\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n {{ option.name }}\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n The max length is 100 characters.\r\n \r\n
\r\n \r\n \r\n \r\n \r\n The max length is 20 characters.\r\n \r\n \r\n Phone number must be of the format: (xxx) xxx-xxxx\r\n \r\n \r\n \r\n \r\n \r\n \r\n The max length is 20 characters.\r\n \r\n \r\n Phone number must be of the format: (xxx) xxx-xxxx\r\n \r\n \r\n \r\n \r\n \r\n \r\n The max length is 20 characters.\r\n \r\n \r\n Phone number must be of the format: (xxx) xxx-xxxx\r\n \r\n
\r\n \r\n \r\n \r\n \r\n The max length is 320 characters.\r\n \r\n \r\n Invalid email address.\r\n \r\n \r\n \r\n \r\n \r\n \r\n The max length is 320 characters.\r\n \r\n \r\n Invalid email address.\r\n \r\n \r\n \r\n \r\n \r\n \r\n The max length is 320 characters.\r\n \r\n \r\n Invalid email address.\r\n \r\n
\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n The max length is 50 characters.\r\n \r\n \r\n \r\n \r\n The max length is 50 characters.\r\n \r\n
\r\n
Loading Contact Information...
\r\n
\r\n
\r\n
\r\n \r\n Go to student's page\r\n \r\n
\r\n
\r\n \r\n Submit\r\n \r\n \r\n
\r\n
\r\n
\r\n
\r\n","import { Component, HostListener, Inject, OnInit, ViewChild } from \"@angular/core\";\r\nimport { NgForm, UntypedFormBuilder, UntypedFormGroup, Validators } from \"@angular/forms\";\r\nimport { MAT_DIALOG_DATA, MatDialogRef } from \"@angular/material/dialog\";\r\nimport { Student, StudentInformation } from \"app/models\";\r\nimport { StudentService } from \"app/services\";\r\nimport { environment } from \"environments/environment\";\r\nimport { AppComponent } from \"../../../app.component\";\r\n\r\n@Component({\r\n selector: \"app-avatar-dialog\",\r\n templateUrl: \"./avatar-dialog.component.html\",\r\n styleUrls: [\"./avatar-dialog.component.scss\"],\r\n})\r\nexport class AvatarDialogComponent implements OnInit {\r\n @ViewChild(\"formDirective\") private formDirective: NgForm;\r\n form: UntypedFormGroup;\r\n\r\n imageUrl = \"\";\r\n student: Student;\r\n studentInformation: StudentInformation;\r\n showStudentPageLink = true;\r\n\r\n preferredContactOptions = this.buildPreferredContactOptions();\r\n bestTimeToReachOptions = this.buildBestTimeToReachOptions();\r\n\r\n constructor(\r\n @Inject(MAT_DIALOG_DATA) public data: { student: Student; hideStudentPageLink?: boolean },\r\n private dialogRef: MatDialogRef,\r\n private studentService: StudentService,\r\n private formBuilder: UntypedFormBuilder,\r\n public appComponent: AppComponent\r\n ) {\r\n this.imageUrl = environment.apiUrl + \"/Common/ReturnProfilePicture/\" + data.student.id;\r\n this.student = data.student;\r\n this.showStudentPageLink = !data.hideStudentPageLink;\r\n this.form = formBuilder.group({});\r\n }\r\n\r\n ngOnInit() {\r\n this.appComponent.isBusy = true;\r\n this.studentService.returnStudentInformationById(this.student.id).subscribe(studentInformation => {\r\n this.appComponent.isBusy = false;\r\n this.studentInformation = studentInformation;\r\n const phonePattern = /\\([0-9]{3}\\) [0-9]{3}-[0-9]{4}/;\r\n this.form = this.formBuilder.group({\r\n notes: [studentInformation.notes, Validators.maxLength(250)],\r\n // guardian contact information\r\n guardianName: [studentInformation.guardianName, Validators.maxLength(100)],\r\n preferredWayToContactGuardian: [studentInformation.preferredWayToContactGuardian || 1],\r\n bestTimeToReachGuardian: [studentInformation.bestTimeToReachGuardian || 1],\r\n guardianPhoneNumber: [\r\n studentInformation.guardianPhoneNumber,\r\n [Validators.maxLength(20), Validators.pattern(phonePattern)],\r\n ],\r\n guardianEmailAddress: [studentInformation.guardianEmailAddress, [Validators.maxLength(320), Validators.email]],\r\n guardianIsSubscribedToWeeklySnapshotEmail: [studentInformation.guardianIsSubscribedToWeeklySnapshotEmail],\r\n secondaryGuardianIsSubscribedToWeeklySnapshotEmail: [\r\n studentInformation.secondaryGuardianIsSubscribedToWeeklySnapshotEmail,\r\n ],\r\n guardianRelationship: [\r\n studentInformation.guardianRelationship,\r\n [Validators.required, Validators.maxLength(50)],\r\n ],\r\n // secondary guardian contact information\r\n secondaryGuardianName: [studentInformation.secondaryGuardianName, Validators.maxLength(100)],\r\n secondaryGuardianPhoneNumber: [\r\n studentInformation.secondaryGuardianPhoneNumber,\r\n [Validators.maxLength(20), Validators.pattern(phonePattern)],\r\n ],\r\n secondaryGuardianEmailAddress: [\r\n studentInformation.secondaryGuardianEmailAddress,\r\n [Validators.maxLength(320), Validators.email],\r\n ],\r\n secondaryGuardianRelationship: [studentInformation.secondaryGuardianRelationship, [Validators.maxLength(50)]],\r\n // student contact information\r\n preferredWayToContactStudent: [studentInformation.preferredWayToContactStudent || 1],\r\n bestTimeToReachStudent: [studentInformation.bestTimeToReachStudent || 1],\r\n homeAddress: [studentInformation.homeAddress, Validators.maxLength(100)],\r\n city: [studentInformation.city, Validators.maxLength(60)],\r\n state: [studentInformation.state, Validators.maxLength(40)],\r\n county: [studentInformation.county, Validators.maxLength(25)],\r\n zipCode: [studentInformation.zipCode, Validators.pattern(/^\\d{5}$/)],\r\n notesAboutMe: [studentInformation.notesAboutMe, Validators.maxLength(1000)],\r\n studentPhoneNumber: [\r\n studentInformation.studentPhoneNumber,\r\n [Validators.maxLength(20), Validators.pattern(phonePattern)],\r\n ],\r\n studentEmailAddress: [studentInformation.studentEmailAddress, [Validators.maxLength(320), Validators.email]],\r\n studentBirthday: [studentInformation.studentBirthday],\r\n // readonly fields\r\n studentId: [this.student.id],\r\n schoolEmailAddress: [this.student.studentEmail],\r\n });\r\n });\r\n }\r\n\r\n confirm() {\r\n if (this.appComponent.isBusy || !this.form.valid) {\r\n return;\r\n }\r\n this.appComponent.isBusy = true;\r\n\r\n const item: StudentInformation = Object.assign({}, this.form.value);\r\n this.studentService.updateStudentInformation(item).subscribe(() => {\r\n this.appComponent.isBusy = false;\r\n this.formDirective.resetForm();\r\n this.dialogRef.close(this.normalizeResult(item));\r\n });\r\n }\r\n\r\n close() {\r\n this.formDirective.resetForm();\r\n this.dialogRef.close();\r\n }\r\n\r\n @HostListener(\"window:keydown\", [\"$event\"])\r\n keyDown(e) {\r\n const enterKeyCode = 13;\r\n if (e.keyCode === enterKeyCode) {\r\n if (this.form.pristine) {\r\n this.close();\r\n } else {\r\n this.confirm();\r\n }\r\n e.preventDefault();\r\n }\r\n }\r\n\r\n private normalizeResult(item: StudentInformation): StudentInformation {\r\n item.bestTimeToReachGuardian = this.bestTimeToReachOptions.filter(\r\n option => option.value === item.bestTimeToReachGuardian\r\n )[0].name;\r\n item.bestTimeToReachStudent = this.bestTimeToReachOptions.filter(\r\n option => option.value === item.bestTimeToReachStudent\r\n )[0].name;\r\n item.preferredWayToContactGuardian = this.preferredContactOptions.filter(\r\n option => option.value === item.preferredWayToContactGuardian\r\n )[0].name;\r\n item.preferredWayToContactStudent = this.preferredContactOptions.filter(\r\n option => option.value === item.preferredWayToContactStudent\r\n )[0].name;\r\n return item;\r\n }\r\n\r\n private buildPreferredContactOptions(): { name: string; value: number }[] {\r\n const result = [];\r\n result.push({ name: \"Email\", value: 1 });\r\n result.push({ name: \"Phone\", value: 2 });\r\n result.push({ name: \"Text\", value: 3 });\r\n return result;\r\n }\r\n\r\n private buildBestTimeToReachOptions(): { name: string; value: number }[] {\r\n const result = [];\r\n result.push({ name: \"Morning\", value: 1 });\r\n result.push({ name: \"Afternoon\", value: 2 });\r\n result.push({ name: \"Evening\", value: 3 });\r\n return result;\r\n }\r\n}\r\n","import { Component, Inject } from \"@angular/core\";\r\nimport { MAT_DIALOG_DATA, MatDialogRef } from \"@angular/material/dialog\";\r\n\r\n@Component({\r\n selector: \"app-confirmation-dialog\",\r\n templateUrl: \"./confirmation-dialog.component.html\",\r\n styleUrls: [\"./confirmation-dialog.component.scss\"],\r\n})\r\nexport class ConfirmationDialogComponent {\r\n constructor(\r\n private dialogRef: MatDialogRef,\r\n @Inject(MAT_DIALOG_DATA)\r\n public data: {\r\n confirmationMessage?: string;\r\n title?: string;\r\n }\r\n ) {\r\n this.data.confirmationMessage ??= \"Are you sure?\";\r\n this.data.title ??= \"Confirm\";\r\n }\r\n\r\n confirm(): void {\r\n this.dialogRef.close(true);\r\n }\r\n\r\n cancel(): void {\r\n this.dialogRef.close(false);\r\n }\r\n}\r\n","\r\n
{{ data.title }}
\r\n
\r\n {{ data.confirmationMessage }}\r\n
\r\n
\r\n \r\n \r\n
\r\n
\r\n","import { Component, HostBinding, Input, OnInit, ViewEncapsulation } from \"@angular/core\";\r\n\r\n@Component({\r\n selector: \"app-dialog\",\r\n templateUrl: \"./dialog.component.html\",\r\n styleUrls: [\"./dialog.component.scss\"],\r\n encapsulation: ViewEncapsulation.None,\r\n})\r\nexport class DialogComponent implements OnInit {\r\n @Input() titleIcon: string = null;\r\n @Input() dialogType: \"default\" | \"primary\" | \"secondary\" | \"success\" | \"danger\" | \"warning\" | \"info\" = \"default\";\r\n @Input() notes: string[];\r\n @Input() hasPanel: boolean = false;\r\n @Input() fullWidth: boolean = false;\r\n\r\n @HostBinding(\"class.has-title-icon\") private _hasTitleIcon: boolean = false;\r\n @HostBinding(\"class.has-notes\") private _hasNotes: boolean = false;\r\n @HostBinding(\"class.paneled\") private _hasPanel: boolean = false;\r\n @HostBinding(\"class.default\") private _isDefault: boolean = false;\r\n @HostBinding(\"class.primary\") private _isPrimary: boolean = false;\r\n @HostBinding(\"class.secondary\") private _isSecondary: boolean = false;\r\n @HostBinding(\"class.success\") private _isSuccess: boolean = false;\r\n @HostBinding(\"class.danger\") private _isDanger: boolean = false;\r\n @HostBinding(\"class.warning\") private _isWarning: boolean = false;\r\n @HostBinding(\"class.info\") private _isInfo: boolean = false;\r\n @HostBinding(\"class.full-width\") private _fullWidth: boolean = false;\r\n\r\n ngOnInit(): void {\r\n this._hasTitleIcon = this.titleIcon !== null && this.titleIcon.length > 0;\r\n this._hasNotes = this.notes && this.notes.length > 0;\r\n this._hasPanel = this.hasPanel;\r\n this._isDefault = this.dialogType === \"default\";\r\n this._isPrimary = this.dialogType === \"primary\";\r\n this._isSecondary = this.dialogType === \"secondary\";\r\n this._isSuccess = this.dialogType === \"success\";\r\n this._isDanger = this.dialogType === \"danger\";\r\n this._isWarning = this.dialogType === \"warning\";\r\n this._isInfo = this.dialogType === \"info\";\r\n this._fullWidth = this.fullWidth;\r\n }\r\n}\r\n","
\r\n
\r\n \r\n
\r\n
\r\n\r\n
\r\n \r\n
\r\n\r\n
\r\n \r\n
\r\n","{{ label }}\r\n\r\n
\r\n
\r\n
\r\n K-5\r\n
\r\n
\r\n \r\n {{ grade.value }}\r\n \r\n
\r\n
\r\n\r\n
\r\n
\r\n 6-8\r\n
\r\n
\r\n \r\n {{ grade.value }}\r\n \r\n
\r\n
\r\n\r\n
\r\n
\r\n 9-12\r\n
\r\n
\r\n \r\n {{ grade.value }}\r\n \r\n
\r\n
\r\n
\r\n","import { Component, EventEmitter, Input, Output } from \"@angular/core\";\r\nimport { Constants } from \"app/shared\";\r\n\r\ntype GradeOption = { value: string; selected: boolean };\r\n\r\n@Component({\r\n selector: \"app-grade-level-selector\",\r\n templateUrl: \"./grade-level-selector.component.html\",\r\n styleUrls: [\"./grade-level-selector.component.scss\"],\r\n})\r\nexport class GradeLevelSelectorComponent {\r\n @Input() label = \"Grade Levels\";\r\n @Input() set selectedGrades(value: string[]) {\r\n this.gradeListK5 = Constants.gradesK5.map(grade => {\r\n return {\r\n value: grade,\r\n selected: value.includes(grade),\r\n };\r\n });\r\n this.gradeList68 = Constants.grades68.map(grade => {\r\n return {\r\n value: grade,\r\n selected: value.includes(grade),\r\n };\r\n });\r\n this.gradeList912 = Constants.grades912.map(grade => {\r\n return {\r\n value: grade,\r\n selected: value.includes(grade),\r\n };\r\n });\r\n\r\n this._selectedGrades = value;\r\n }\r\n @Output() gradesSelected = new EventEmitter();\r\n\r\n gradeListK5: GradeOption[];\r\n gradeList68: GradeOption[];\r\n gradeList912: GradeOption[];\r\n\r\n private _selectedGrades: string[];\r\n get selectedGrades() {\r\n return this._selectedGrades;\r\n }\r\n\r\n get gradesK5Selected() {\r\n return !this.gradeListK5.some(x => !x.selected);\r\n }\r\n\r\n get grades68Selected() {\r\n return !this.gradeList68.some(x => !x.selected);\r\n }\r\n\r\n get grades912Selected() {\r\n return !this.gradeList912.some(x => !x.selected);\r\n }\r\n\r\n toggleKThrough5() {\r\n if (this.gradesK5Selected) {\r\n this.gradesSelected.emit(...new Set([this.selectedGrades.filter(g => !Constants.gradesK5.some(e => e === g))]));\r\n } else {\r\n this.gradesSelected.emit([...new Set([...this.selectedGrades, ...Constants.gradesK5])]);\r\n }\r\n }\r\n\r\n toggle6Through8() {\r\n if (this.grades68Selected) {\r\n this.gradesSelected.emit(...new Set([this.selectedGrades.filter(g => !Constants.grades68.some(e => e === g))]));\r\n } else {\r\n this.gradesSelected.emit([...new Set([...this.selectedGrades, ...Constants.grades68])]);\r\n }\r\n }\r\n\r\n toggle9Through12() {\r\n if (this.grades912Selected) {\r\n this.gradesSelected.emit(...new Set([this.selectedGrades.filter(g => !Constants.grades912.some(e => e === g))]));\r\n } else {\r\n this.gradesSelected.emit([...new Set([...this.selectedGrades, ...Constants.grades912])]);\r\n }\r\n }\r\n\r\n gradeSelectedChange(grade: string) {\r\n let outputGrades: string[];\r\n if (this._selectedGrades.includes(grade)) {\r\n //remove\r\n outputGrades = this._selectedGrades.filter(g => g != grade);\r\n } else {\r\n //add\r\n outputGrades = [...this._selectedGrades, grade];\r\n }\r\n\r\n this.gradesSelected.emit(outputGrades);\r\n }\r\n}\r\n","// This file is a legal copy of the following repo under MIT licensing.https://github.com/wulfsolter/angular2-signaturepad\r\n// See the license file in this directory.\r\n\r\nimport { AfterContentInit, Component, ElementRef, EventEmitter, Input, OnDestroy, Output } from \"@angular/core\";\r\n\r\nimport * as SignaturePadNative from \"signature_pad\";\r\n\r\nexport interface Point {\r\n x: number;\r\n y: number;\r\n time: number;\r\n}\r\n\r\nexport type PointGroup = Array;\r\n\r\n@Component({\r\n template: \"\",\r\n selector: \"signature-pad\",\r\n})\r\nexport class SignaturePadComponent implements AfterContentInit, OnDestroy {\r\n @Input() public options: any;\r\n @Output() public onBeginEvent: EventEmitter;\r\n @Output() public onEndEvent: EventEmitter;\r\n\r\n private signaturePad: any;\r\n private elementRef: ElementRef;\r\n\r\n constructor(elementRef: ElementRef) {\r\n // no op\r\n this.elementRef = elementRef;\r\n this.options = this.options || {};\r\n this.onBeginEvent = new EventEmitter();\r\n this.onEndEvent = new EventEmitter();\r\n }\r\n\r\n public ngAfterContentInit(): void {\r\n const canvas: any = this.elementRef.nativeElement.querySelector(\"canvas\");\r\n\r\n if ((this.options as any).canvasHeight) {\r\n canvas.height = (this.options as any).canvasHeight;\r\n }\r\n\r\n if ((this.options as any).canvasWidth) {\r\n canvas.width = (this.options as any).canvasWidth;\r\n }\r\n\r\n this.signaturePad = new SignaturePadNative.default(canvas, this.options);\r\n this.signaturePad.onBegin = this.onBegin.bind(this);\r\n this.signaturePad.onEnd = this.onEnd.bind(this);\r\n }\r\n\r\n public ngOnDestroy(): void {\r\n const canvas: any = this.elementRef.nativeElement.querySelector(\"canvas\");\r\n canvas.width = 0;\r\n canvas.height = 0;\r\n }\r\n\r\n public resizeCanvas(): void {\r\n // When zoomed out to less than 100%, for some very strange reason,\r\n // some browsers report devicePixelRatio as less than 1\r\n // and only part of the canvas is cleared then.\r\n const ratio: number = Math.max(window.devicePixelRatio || 1, 1);\r\n const canvas: any = this.signaturePad.canvas;\r\n canvas.width = canvas.offsetWidth * ratio;\r\n canvas.height = canvas.offsetHeight * ratio;\r\n canvas.getContext(\"2d\").scale(ratio, ratio);\r\n this.signaturePad.clear(); // otherwise isEmpty() might return incorrect value\r\n }\r\n\r\n // Returns signature image as an array of point groups\r\n public toData(): Array {\r\n if (this.signaturePad) {\r\n return this.signaturePad.toData();\r\n } else {\r\n return [];\r\n }\r\n }\r\n\r\n // Draws signature image from an array of point groups\r\n public fromData(points: Array): void {\r\n this.signaturePad.fromData(points as any);\r\n }\r\n\r\n // Returns signature image as data URL (see https://mdn.io/todataurl for the list of possible paramters)\r\n public toDataURL(imageType?: string, quality?: number): string {\r\n return this.signaturePad.toDataURL(imageType, quality); // save image as data URL\r\n }\r\n\r\n // Draws signature image from data URL\r\n public fromDataURL(dataURL: string, options: any = {}): void {\r\n // set default height and width on read data from URL\r\n if (!options.hasOwnProperty(\"height\") && (this.options as any).canvasHeight) {\r\n options.height = (this.options as any).canvasHeight;\r\n }\r\n if (!options.hasOwnProperty(\"width\") && (this.options as any).canvasWidth) {\r\n options.width = (this.options as any).canvasWidth;\r\n }\r\n this.signaturePad.fromDataURL(dataURL, options);\r\n }\r\n\r\n // Clears the canvas\r\n public clear(): void {\r\n this.signaturePad.clear();\r\n }\r\n\r\n // Returns true if canvas is empty, otherwise returns false\r\n public isEmpty(): boolean {\r\n return this.signaturePad.isEmpty();\r\n }\r\n\r\n // Unbinds all event handlers\r\n public off(): void {\r\n this.signaturePad.off();\r\n }\r\n\r\n // Rebinds all event handlers\r\n public on(): void {\r\n this.signaturePad.on();\r\n }\r\n\r\n // set an option on the signaturePad - e.g. set('minWidth', 50);\r\n public set(option: string, value: any): void {\r\n switch (option) {\r\n case \"canvasHeight\":\r\n this.signaturePad.canvas.height = value;\r\n break;\r\n case \"canvasWidth\":\r\n this.signaturePad.canvas.width = value;\r\n break;\r\n default:\r\n this.signaturePad[option] = value;\r\n }\r\n }\r\n\r\n // notify subscribers on signature begin\r\n public onBegin(): void {\r\n this.onBeginEvent.emit(true);\r\n }\r\n\r\n // notify subscribers on signature end\r\n public onEnd(): void {\r\n this.onEndEvent.emit(true);\r\n }\r\n\r\n public queryPad(): any {\r\n return this.signaturePad;\r\n }\r\n}\r\n","import { Component, ViewChild, forwardRef } from \"@angular/core\";\r\nimport { ControlValueAccessor, NG_VALUE_ACCESSOR } from \"@angular/forms\";\r\nimport { SignaturePadComponent } from \"@design/signature-pad/signature-pad.component\";\r\n\r\n@Component({\r\n selector: \"app-signature-field\",\r\n templateUrl: \"./signature-field.component.html\",\r\n styleUrls: [\"./signature-field.component.scss\"],\r\n providers: [\r\n {\r\n provide: NG_VALUE_ACCESSOR,\r\n useExisting: forwardRef(() => SignatureFieldComponent),\r\n multi: true,\r\n },\r\n ],\r\n})\r\nexport class SignatureFieldComponent implements ControlValueAccessor {\r\n @ViewChild(SignaturePadComponent) public signaturePad: SignaturePadComponent;\r\n\r\n public options: Object = {\r\n backgroundColor: \"rgb(255,255,255)\",\r\n canvasWidth: 600,\r\n canvasHeight: 150,\r\n penColor: \"rgb(255, 0, 0)\",\r\n };\r\n public _signature: any = null;\r\n public propagateChange: Function = null;\r\n\r\n get signature(): any {\r\n return this._signature;\r\n }\r\n\r\n set signature(value: any) {\r\n this._signature = value;\r\n this.propagateChange(this.signature);\r\n }\r\n\r\n public writeValue(value: any): void {\r\n if (!value) {\r\n return;\r\n }\r\n this._signature = value;\r\n this.signaturePad?.fromDataURL(this.signature);\r\n }\r\n\r\n public registerOnChange(fn: any): void {\r\n this.propagateChange = fn;\r\n }\r\n\r\n public registerOnTouched(): void {\r\n // no-op\r\n }\r\n\r\n public ngAfterViewInit(): void {\r\n this.signaturePad.clear();\r\n }\r\n\r\n public drawBegin(): void {}\r\n\r\n public drawComplete(): void {\r\n this.signature = this.signaturePad.toDataURL(\"image/jpeg\", 0.5);\r\n }\r\n\r\n public clear(): void {\r\n this.signaturePad.clear();\r\n this.signature = \"\";\r\n }\r\n\r\n public disableSignaturePad() {\r\n this.signaturePad.off();\r\n }\r\n\r\n public enableSignaturePad() {\r\n this.signaturePad.on();\r\n }\r\n}\r\n","\r\n","
\r\n
\r\n \r\n \r\n \r\n \r\n
\r\n
\r\n
\r\n
\r\n
\r\n \r\n
\r\n
\r\n {{ message }}\r\n \r\n - Grade Level:\r\n \r\n \r\n
\r\n \r\n
\r\n","import { Component, OnDestroy, OnInit } from \"@angular/core\";\r\nimport { AuthService } from \"@services/auth/auth.service\";\r\nimport { CommonService } from \"@services/common.service\";\r\nimport { Subject } from \"rxjs\";\r\nimport { AppComponent } from \"../../../app.component\";\r\nimport { Constants } from \"../../../shared\";\r\n\r\n@Component({\r\n selector: \"app-toolbar\",\r\n templateUrl: \"./toolbar.component.html\",\r\n styleUrls: [\"./toolbar.component.scss\"],\r\n})\r\nexport class ToolbarComponent implements OnInit, OnDestroy {\r\n message = \"\";\r\n private _componentDestroyed$: Subject = new Subject();\r\n\r\n isSignedIn = false;\r\n loginType = 2; // icademy global is default\r\n\r\n constructor(\r\n private appComponent: AppComponent,\r\n private authService: AuthService,\r\n public commonService: CommonService\r\n ) {\r\n this.isSignedIn = this.authService.isLoggedIn;\r\n try {\r\n const cachedValue = localStorage.getItem(Constants.loginTypeKey);\r\n if (cachedValue) {\r\n this.loginType = Number(cachedValue);\r\n }\r\n } catch (e) {\r\n // local storage is unsupported\r\n }\r\n }\r\n\r\n ngOnInit() {\r\n this.commonService.getEnvironment().subscribe(result => {\r\n this.message = result.toUpperCase();\r\n });\r\n }\r\n\r\n logout() {\r\n this.authService.signOut().subscribe();\r\n this.authService.redirectLogoutUser();\r\n }\r\n\r\n ngOnDestroy() {\r\n this._componentDestroyed$.next(true);\r\n this._componentDestroyed$.complete();\r\n }\r\n\r\n changeGradeLevel(value) {\r\n this.appComponent.isBusy = true;\r\n this.commonService\r\n .setStudentGradeLevel(this.authService.currentUser.userId, value)\r\n .subscribe(() => location.reload());\r\n }\r\n}\r\n","import { CdkCellDef } from \"@angular/cdk/table\";\r\nimport { Directive, Input } from \"@angular/core\";\r\nimport { MatCellDef, MatTableDataSource } from \"@angular/material/table\";\r\nimport { Observable } from \"rxjs\";\r\n\r\n@Directive({\r\n /* eslint-disable */\r\n selector: \"[matCellDef]\", // same selector as MatCellDef\r\n providers: [{ provide: CdkCellDef, useExisting: TypeSafeMatCellDef }],\r\n})\r\nexport class TypeSafeMatCellDef extends MatCellDef {\r\n // leveraging syntactic-sugar syntax when we use *matCellDef\r\n @Input() matCellDefDataSource: T[] | Observable | MatTableDataSource;\r\n\r\n // @ts-ignore - hack: these unused parameters are used to help the Language Service\r\n static ngTemplateContextGuard(dir: TypeSafeMatCellDef, ctx: unknown): ctx is { $implicit: T; index: number } {\r\n return true;\r\n }\r\n}\r\n","\r\n
\r\n {{ title }}\r\n {{ startDate | date : \"MM/dd/yy\" }} - {{ endDate | date : \"MM/dd/yy\" }}\r\n
\r\n
\r\n \r\n

\r\n Class data last updated as of {{ asOfDate | date }}\r\n \r\n There is no class data available for this student. Please check back later.\r\n \r\n

\r\n

\r\n \r\n This class data is a\r\n snapshot\r\n of the student's classes and grades as of {{ asOfDate | date }}.\r\n
\r\n If you would like to see current class data for this student, please adjust your date range on the main page.\r\n
\r\n \r\n There is no class data available for this student for the selected date range.\r\n
\r\n Please adjust your date range on the main page and try again.\r\n
\r\n

\r\n
\r\n\r\n \r\n \r\n \r\n \r\n \r\n\r\n \r\n \r\n \r\n \r\n\r\n \r\n \r\n Time Spent\r\n \r\n \r\n \r\n\r\n \r\n \r\n Time Spent\r\n \r\n \r\n \r\n\r\n \r\n \r\n \r\n \r\n\r\n \r\n \r\n \r\n \r\n\r\n \r\n \r\n \r\n \r\n\r\n \r\n \r\n \r\n \r\n\r\n \r\n \r\n \r\n \r\n\r\n \r\n \r\n \r\n \r\n\r\n \r\n \r\n \r\n \r\n\r\n \r\n \r\n \r\n \r\n\r\n \r\n \r\n \r\n\r\n \r\n \r\n \r\n\r\n \r\n \r\n \r\n\r\n \r\n \r\n \r\n\r\n \r\n \r\n \r\n
Class{{ row.className }}Live Lessons\r\n {{ row.liveLessonPoints }} out of {{ row.liveLessonsOffered }}\r\n \r\n {{ Utility.toTimeFormat(row.onlineHoursSpentThisWeek * 3600.0) }}\r\n \r\n {{ Utility.toTimeFormat(row.totalSecondsSpentOnline) }}\r\n Score\r\n \r\n {{ row.score }}\r\n \r\n \r\n trending_up\r\n \r\n \r\n trending_down\r\n \r\n Enrollment Status{{ getStatusName(row) }}Assignment Progress\r\n {{ row.assignmentsAssignedDateRange ? (row.assignmentProgressDateRange | percent) : \"-\" }}\r\n Tasks Assigned\r\n {{ row.assignmentsAssignedDateRange }}\r\n Completed In Grace\r\n {{ row.assignmentsCompletedInGraceDateRange }}\r\n Completed In Grace\r\n {{ row.assignmentsCompletedInGraceUpUntilEndDate }}\r\n \r\n Completed On Time\r\n \r\n {{ row.assignmentsCompletedOnTime }}\r\n Assignments In Grace Period{{ row.assignmentsInGracePeriod }}\r\n {{ isPerformance ? \"This Week\" : \"Selected Date Range\" }}\r\n \r\n Course Start to\r\n
\r\n Selected End Date\r\n
\r\n All Time\r\n
\r\n\r\n
\r\n {{ appComponent.isBusy ? \"Loading...\" : noResultsMessage }}\r\n
\r\n
\r\n
\r\n \r\n
\r\n
\r\n","import { Component, HostListener, Inject, OnInit, ViewChild } from \"@angular/core\";\r\nimport { MAT_DIALOG_DATA, MatDialogRef } from \"@angular/material/dialog\";\r\nimport { MatSort } from \"@angular/material/sort\";\r\nimport { MatTableDataSource } from \"@angular/material/table\";\r\nimport { AppComponent } from \"app/app.component\";\r\nimport { Trend } from \"app/enums\";\r\nimport { ClassUser, Student } from \"app/models\";\r\nimport { CommonService } from \"app/services\";\r\nimport { Utility } from \"app/shared\";\r\nimport { EnrollmentStatus } from \"../../../enums/enrollment-status.enum\";\r\n\r\n@Component({\r\n selector: \"app-class-dialog-dialog\",\r\n templateUrl: \"./class-dialog.component.html\",\r\n styleUrls: [\"./class-dialog.component.scss\"],\r\n})\r\nexport class ClassDialogComponent implements OnInit {\r\n @ViewChild(MatSort) sort: MatSort;\r\n\r\n Utility = Utility;\r\n Trend = Trend;\r\n noResultsMessage = \"Loading...\";\r\n title: string;\r\n isPerformance: boolean;\r\n\r\n student: Student;\r\n startDate: Date;\r\n endDate: Date;\r\n\r\n dateRangeColumns: string[] = [\"className\", \"liveLessonPoints\", \"onlineHoursSpentThisWeek\"];\r\n allTimeColumns: string[] = [\"totalSecondsSpentOnline\", \"score\"];\r\n dataSource = new MatTableDataSource();\r\n\r\n get isCurrent(): boolean {\r\n const today = new Date();\r\n return !this.startDate || this.endDate >= new Date(today.getFullYear(), today.getMonth(), today.getDate());\r\n }\r\n\r\n get asOfDate(): Date | null {\r\n const asOfDate = this.dataSource.data[0]?.asOfDate;\r\n return asOfDate ? new Date(asOfDate) : null;\r\n }\r\n\r\n constructor(\r\n public appComponent: AppComponent,\r\n private commonService: CommonService,\r\n private dialogRef: MatDialogRef,\r\n @Inject(MAT_DIALOG_DATA) data: { student: Student; startDate?: Date; endDate?: Date }\r\n ) {\r\n if (!data || !data.student) {\r\n throw \"Class Dialog Expects Student\";\r\n }\r\n\r\n this.student = data.student;\r\n this.isPerformance = !data.endDate;\r\n\r\n if (this.isPerformance) {\r\n this.title = `Performance Snapshot`;\r\n this.startDate = Utility.getBeginningOfWeek();\r\n this.endDate = Utility.getEndOfWeek();\r\n } else {\r\n this.title = `${this.student.name} Performance Snapshot`;\r\n this.startDate = data.startDate;\r\n this.endDate = data.endDate;\r\n this.dateRangeColumns.push(\r\n \"assignmentsAssignedDateRange\",\r\n \"assignmentsCompletedInGraceDateRange\",\r\n \"assignmentsCompletedOnTime\",\r\n \"assignmentProgressDateRange\"\r\n );\r\n this.allTimeColumns.push(\r\n \"assignmentsCompletedInGraceUpUntilEndDate\",\r\n this.allTimeColumns.shift(),\r\n \"assignmentsInGracePeriod\",\r\n this.allTimeColumns.pop(),\r\n \"status\"\r\n );\r\n }\r\n }\r\n\r\n ngOnInit() {\r\n this.appComponent.isBusy = true;\r\n this.commonService\r\n .returnClassUsersByStudentId(this.student.id, this.startDate, this.endDate, true)\r\n .subscribe(({ classUsers: studentClasses, startDate, endDate }) => {\r\n this.startDate = startDate;\r\n this.endDate = endDate;\r\n\r\n if (this.isPerformance) {\r\n studentClasses = studentClasses.filter(studentClass => studentClass.status === EnrollmentStatus.Active);\r\n }\r\n\r\n this.dataSource = new MatTableDataSource(studentClasses);\r\n this.dataSource.sort = this.sort;\r\n this.appComponent.isBusy = false;\r\n this.noResultsMessage = \"No classes found.\";\r\n });\r\n }\r\n\r\n close(): void {\r\n this.dialogRef.close();\r\n }\r\n\r\n getStatusName(classUser: ClassUser): string {\r\n switch (classUser.status) {\r\n case EnrollmentStatus.CompletedNoCredit:\r\n return \"Completed - No Credit\";\r\n case EnrollmentStatus.WithdrawnFailed:\r\n return \"Withdrawn Failed\";\r\n default:\r\n return EnrollmentStatus[classUser.status];\r\n }\r\n }\r\n\r\n @HostListener(\"window:keydown\", [\"$event\"])\r\n keyDown(e) {\r\n const enterKeyCode = 13;\r\n if (e.keyCode === enterKeyCode) {\r\n this.close();\r\n e.preventDefault();\r\n }\r\n }\r\n}\r\n","
\r\n
\r\n lock\r\n
\r\n
\r\n

You ({{ userName }}) are not an authorized user.

\r\n

\r\n Please reach out to support@icademyglobal.org or contact your mentor if you need access or think this is a\r\n mistake.\r\n

\r\n
\r\n \r\n
\r\n
\r\n
You are not signed in.
\r\n \r\n home\r\n Sign in\r\n \r\n
\r\n
\r\n
\r\n","import { Component } from \"@angular/core\";\r\nimport { AuthService } from \"@services/auth/auth.service\";\r\n\r\n@Component({\r\n selector: \"app-not-authorized\",\r\n templateUrl: \"./not-authorized.component.html\",\r\n styleUrls: [\"./not-authorized.component.scss\"],\r\n})\r\nexport class NotAuthorizedComponent {\r\n userName: string;\r\n signedIn = true;\r\n\r\n constructor(private authService: AuthService) {\r\n try {\r\n this.userName = this.authService.currentUser?.email;\r\n } catch (e) {}\r\n\r\n if (!this.userName) {\r\n this.userName = \"Not signed in.\";\r\n this.signedIn = false;\r\n }\r\n }\r\n\r\n logout() {\r\n this.authService.signOut().subscribe();\r\n this.authService.redirectLogoutUser();\r\n }\r\n}\r\n","import { Location } from \"@angular/common\";\r\nimport { Component, OnInit } from \"@angular/core\";\r\n\r\n@Component({\r\n selector: \"app-page-not-found\",\r\n templateUrl: \"./page-not-found.component.html\",\r\n styleUrls: [\"./page-not-found.component.scss\"],\r\n})\r\nexport class PageNotFoundComponent implements OnInit {\r\n constructor(private location: Location) {}\r\n\r\n ngOnInit() {}\r\n\r\n goBack() {\r\n this.location.back();\r\n }\r\n}\r\n","
\r\n
\r\n
\r\n

SORRY, PAGE WAS NOT FOUND

\r\n

\r\n The page you are looking for might have been removed, had it's name changed, or is temporarily unavailable\r\n

\r\n
\r\n
\r\n \r\n
\r\n
\r\n
\r\n","import {\r\n NGX_MAT_DATE_FORMATS,\r\n NgxMatDateFormats,\r\n NgxMatDatetimePickerModule,\r\n NgxMatNativeDateModule,\r\n NgxMatTimepickerModule,\r\n} from \"@angular-material-components/datetime-picker\";\r\nimport { CommonModule } from \"@angular/common\";\r\nimport { NgModule } from \"@angular/core\";\r\nimport { FlexLayoutModule } from \"@angular/flex-layout\";\r\nimport { FormsModule, ReactiveFormsModule } from \"@angular/forms\";\r\nimport { MatAutocompleteModule } from \"@angular/material/autocomplete\";\r\nimport { MatBadgeModule } from \"@angular/material/badge\";\r\nimport { MatBottomSheetModule } from \"@angular/material/bottom-sheet\";\r\nimport { MatButtonModule } from \"@angular/material/button\";\r\nimport { MatButtonToggleModule } from \"@angular/material/button-toggle\";\r\nimport { MatCardModule } from \"@angular/material/card\";\r\nimport { MatCheckboxModule } from \"@angular/material/checkbox\";\r\nimport { MatChipsModule } from \"@angular/material/chips\";\r\nimport { MatNativeDateModule } from \"@angular/material/core\";\r\nimport { MatDatepickerModule } from \"@angular/material/datepicker\";\r\nimport { MatDialogModule } from \"@angular/material/dialog\";\r\nimport { MatDividerModule } from \"@angular/material/divider\";\r\nimport { MatExpansionModule } from \"@angular/material/expansion\";\r\nimport { MatFormFieldModule } from \"@angular/material/form-field\";\r\nimport { MatGridListModule } from \"@angular/material/grid-list\";\r\nimport { MatIconModule } from \"@angular/material/icon\";\r\nimport { MatInputModule } from \"@angular/material/input\";\r\nimport { MatListModule } from \"@angular/material/list\";\r\nimport { MatMenuModule } from \"@angular/material/menu\";\r\nimport { MatPaginatorModule } from \"@angular/material/paginator\";\r\nimport { MatProgressBarModule } from \"@angular/material/progress-bar\";\r\nimport { MatProgressSpinnerModule } from \"@angular/material/progress-spinner\";\r\nimport { MatRadioModule } from \"@angular/material/radio\";\r\nimport { MatSelectModule } from \"@angular/material/select\";\r\nimport { MatSidenavModule } from \"@angular/material/sidenav\";\r\nimport { MatSlideToggleModule } from \"@angular/material/slide-toggle\";\r\nimport { MatSnackBarModule } from \"@angular/material/snack-bar\";\r\nimport { MatSortModule } from \"@angular/material/sort\";\r\nimport { MatTableModule } from \"@angular/material/table\";\r\nimport { MatTabsModule } from \"@angular/material/tabs\";\r\nimport { MatToolbarModule } from \"@angular/material/toolbar\";\r\nimport { MatTooltipModule } from \"@angular/material/tooltip\";\r\nimport { RouterModule } from \"@angular/router\";\r\nimport { FDAngularRichTextWrapperComponent } from \"@design/fdangular-rich-text-wrapper/fdangular-rich-text-wrapper.component\";\r\nimport { SignaturePadComponent } from \"@design/signature-pad/signature-pad.component\";\r\nimport { AngularEditorModule } from \"@kolkov/angular-editor\";\r\nimport { MatTableExporterModule } from \"mat-table-exporter\";\r\nimport { LazyLoadImageModule } from \"ng-lazyload-image\";\r\nimport { UiScrollModule } from \"ngx-ui-scroll\";\r\nimport {\r\n AvatarDialogComponent,\r\n ClassDialogComponent,\r\n ConfirmationDialogComponent,\r\n DialogComponent,\r\n GradeLevelSelectorComponent,\r\n NotAuthorizedComponent,\r\n PageNotFoundComponent,\r\n QuizComponent,\r\n SignatureFieldComponent,\r\n TabGroupComponent,\r\n ToolbarComponent,\r\n} from \"./components\";\r\nimport { ChooseAGradeComponent } from \"./components/choose-a-grade/choose-a-grade.component\";\r\nimport { EngagementMetricBreakdownDialogComponent } from \"./components/engagement-metric-breakdown-dialog/engagement-metric-breakdown-dialog.component\";\r\nimport { ScrollIntoViewDirective } from \"./directives/scroll-into-view.directive\";\r\nimport { TypeSafeMatCellDef } from \"./directives/type-safe-mat-cell-def.directive\";\r\nimport { SafePipe } from \"./pipes\";\r\nimport { AddDaysPipe } from \"./pipes/add-days.pipe\";\r\nimport { AddWeeksPipe } from \"./pipes/add-weeks.pipe\";\r\nimport { CellNamePipe } from \"./pipes/cell-name.pipe\";\r\nimport { CommunicationTypePipe } from \"./pipes/communication-type-name-pipe\";\r\nimport { DividePipe } from \"./pipes/divide.pipe\";\r\nimport { GradeNamePipe } from \"./pipes/grade-name.pipe\";\r\nimport { GradePipe } from \"./pipes/grade.pipe\";\r\nimport { InterventionStatusPipe } from \"./pipes/intervention-status.pipe\";\r\nimport { YearsPipe } from \"./pipes/years.pipe\";\r\n\r\nconst INTL_DATE_INPUT_FORMAT = {\r\n year: \"2-digit\",\r\n month: \"numeric\",\r\n day: \"numeric\",\r\n hourCycle: \"h23\",\r\n hour: \"numeric\",\r\n minute: \"2-digit\",\r\n hour12: true,\r\n};\r\n\r\nconst MAT_DATE_FORMATS: NgxMatDateFormats = {\r\n parse: {\r\n dateInput: INTL_DATE_INPUT_FORMAT,\r\n },\r\n display: {\r\n dateInput: INTL_DATE_INPUT_FORMAT,\r\n monthYearLabel: { year: \"numeric\", month: \"short\" },\r\n dateA11yLabel: { year: \"numeric\", month: \"long\", day: \"numeric\" },\r\n monthYearA11yLabel: { year: \"numeric\", month: \"long\" },\r\n },\r\n};\r\n\r\n@NgModule({\r\n declarations: [\r\n AvatarDialogComponent,\r\n ClassDialogComponent,\r\n ConfirmationDialogComponent,\r\n DialogComponent,\r\n NotAuthorizedComponent,\r\n PageNotFoundComponent,\r\n QuizComponent,\r\n SignaturePadComponent,\r\n SignatureFieldComponent,\r\n TabGroupComponent,\r\n ToolbarComponent,\r\n GradeLevelSelectorComponent,\r\n ChooseAGradeComponent,\r\n FDAngularRichTextWrapperComponent,\r\n EngagementMetricBreakdownDialogComponent,\r\n\r\n // Pipes\r\n SafePipe,\r\n GradePipe,\r\n GradeNamePipe,\r\n DividePipe,\r\n AddWeeksPipe,\r\n AddDaysPipe,\r\n InterventionStatusPipe,\r\n CommunicationTypePipe,\r\n CellNamePipe,\r\n\r\n // Directives\r\n ScrollIntoViewDirective,\r\n TypeSafeMatCellDef,\r\n YearsPipe,\r\n ],\r\n imports: [\r\n AngularEditorModule,\r\n CommonModule,\r\n FormsModule,\r\n ReactiveFormsModule,\r\n LazyLoadImageModule,\r\n MatAutocompleteModule,\r\n MatBottomSheetModule,\r\n MatButtonModule,\r\n MatButtonToggleModule,\r\n MatCardModule,\r\n MatCheckboxModule,\r\n MatChipsModule,\r\n MatDatepickerModule,\r\n MatDialogModule,\r\n MatDividerModule,\r\n MatExpansionModule,\r\n MatFormFieldModule,\r\n MatGridListModule,\r\n MatIconModule,\r\n MatInputModule,\r\n MatListModule,\r\n MatMenuModule,\r\n MatNativeDateModule,\r\n MatPaginatorModule,\r\n MatProgressBarModule,\r\n MatRadioModule,\r\n MatSelectModule,\r\n MatSidenavModule,\r\n MatSnackBarModule,\r\n MatSortModule,\r\n MatTableModule,\r\n MatTabsModule,\r\n MatSlideToggleModule,\r\n MatToolbarModule,\r\n MatTooltipModule,\r\n MatProgressSpinnerModule,\r\n MatTableExporterModule,\r\n NgxMatDatetimePickerModule,\r\n NgxMatTimepickerModule,\r\n NgxMatNativeDateModule,\r\n ReactiveFormsModule,\r\n RouterModule,\r\n UiScrollModule,\r\n FlexLayoutModule,\r\n ],\r\n exports: [\r\n // Modules\r\n AngularEditorModule,\r\n CommonModule,\r\n FormsModule,\r\n LazyLoadImageModule,\r\n MatAutocompleteModule,\r\n MatBadgeModule,\r\n MatBottomSheetModule,\r\n MatButtonModule,\r\n MatButtonToggleModule,\r\n MatCardModule,\r\n MatCheckboxModule,\r\n MatChipsModule,\r\n MatDatepickerModule,\r\n MatDialogModule,\r\n MatDividerModule,\r\n MatExpansionModule,\r\n MatFormFieldModule,\r\n MatGridListModule,\r\n MatIconModule,\r\n MatInputModule,\r\n MatListModule,\r\n MatMenuModule,\r\n MatNativeDateModule,\r\n MatPaginatorModule,\r\n MatProgressBarModule,\r\n MatRadioModule,\r\n MatSelectModule,\r\n MatSidenavModule,\r\n MatSnackBarModule,\r\n MatSortModule,\r\n MatTableModule,\r\n MatTabsModule,\r\n MatSlideToggleModule,\r\n MatToolbarModule,\r\n MatTooltipModule,\r\n MatProgressSpinnerModule,\r\n MatTableExporterModule,\r\n NgxMatDatetimePickerModule,\r\n NgxMatTimepickerModule,\r\n NgxMatNativeDateModule,\r\n ReactiveFormsModule,\r\n RouterModule,\r\n UiScrollModule,\r\n\r\n // Components,\r\n AvatarDialogComponent,\r\n ClassDialogComponent,\r\n DialogComponent,\r\n PageNotFoundComponent,\r\n QuizComponent,\r\n SignatureFieldComponent,\r\n TabGroupComponent,\r\n ToolbarComponent,\r\n GradeLevelSelectorComponent,\r\n ChooseAGradeComponent,\r\n FDAngularRichTextWrapperComponent,\r\n\r\n // Pipes\r\n CellNamePipe,\r\n DividePipe,\r\n SafePipe,\r\n GradePipe,\r\n GradeNamePipe,\r\n AddWeeksPipe,\r\n AddDaysPipe,\r\n InterventionStatusPipe,\r\n CommunicationTypePipe,\r\n YearsPipe,\r\n\r\n // Directives\r\n ScrollIntoViewDirective,\r\n TypeSafeMatCellDef,\r\n ],\r\n providers: [{ provide: NGX_MAT_DATE_FORMATS, useValue: MAT_DATE_FORMATS }],\r\n})\r\nexport class DesignModule {}\r\n","export enum EnrollmentStatus {\r\n Active = 1,\r\n Withdrawn = 4,\r\n WithdrawnFailed = 5,\r\n Transferred = 6,\r\n Completed = 7,\r\n CompletedNoCredit = 8,\r\n Suspended = 9,\r\n Inactive = 10,\r\n}\r\n","/** Client-side model of the Server's AppEnvironment enum. */\r\nexport enum AppEnvironment {\r\n Development,\r\n Testing,\r\n Production,\r\n}\r\n","/**\r\n * Client version of Repository/Infrastructure/UserRoles.cs\r\n * TODO: Code generation - for now, we will have to manually update both files so that they match\r\n */\r\nexport enum UserRoles {\r\n FdAdmin = \"FdAdmin\",\r\n Admin_Users_View = \"Admin_Users_View\",\r\n Admin_Users_Edit = \"Admin_Users_Edit\",\r\n Admin_SecurityGroups_View = \"Admin_SecurityGroups_View\",\r\n Admin_SecurityGroups_Edit = \"Admin_SecurityGroups_Edit\",\r\n Admin_Localization_View = \"Admin_Localization_View\",\r\n Admin_Localization_Edit = \"Admin_Localization_Edit\",\r\n Admin_ImpersonateUser = \"Admin_ImpersonateUser\",\r\n\r\n Admin = \"Admin\",\r\n Staff = \"Staff\",\r\n Interventionist = \"Interventionist\",\r\n ReFuelCoordinator = \"ReFuel Coordinator\",\r\n Mentor = \"Mentor\",\r\n Teacher = \"Teacher\",\r\n SecondaryMentor = \"Secondary Mentor\",\r\n}\r\n","export enum Trend {\r\n Downwards = -1,\r\n Flat = 0,\r\n Upwards = 1,\r\n}\r\n","import { Injectable } from \"@angular/core\";\r\nimport { ActivatedRouteSnapshot, CanActivate, Router, RouterStateSnapshot } from \"@angular/router\";\r\nimport { AuthService } from \"@services/auth/auth.service\";\r\nimport { NavigationService } from \"@services/navigation.service\";\r\nimport { Observable } from \"rxjs\";\r\n\r\n@Injectable({ providedIn: \"root\" })\r\nexport class AuthenticationGuard implements CanActivate {\r\n constructor(private authService: AuthService, private router: Router, private navigationService: NavigationService) {}\r\n\r\n canActivate(\r\n route: ActivatedRouteSnapshot,\r\n state: RouterStateSnapshot\r\n ): boolean | Promise | Observable {\r\n if (this.authService.isLoggedIn) {\r\n return true;\r\n } else {\r\n this.navigationService.redirectUrl = state.url;\r\n this.router.navigateByUrl(\"/login\");\r\n return false;\r\n }\r\n }\r\n}\r\n","import { Injectable } from \"@angular/core\";\r\nimport { CanActivate, Router } from \"@angular/router\";\r\nimport { AuthService } from \"@services/auth/auth.service\";\r\nimport { AuthorizationService } from \"@services/authorization.service\";\r\nimport { Observable } from \"rxjs\";\r\nimport { map } from \"rxjs/operators\";\r\n\r\n@Injectable({ providedIn: \"root\" })\r\nexport class AdminGuard implements CanActivate {\r\n constructor(\r\n private router: Router,\r\n private authService: AuthService,\r\n private authorizationService: AuthorizationService\r\n ) {}\r\n\r\n canActivate(): Observable | boolean {\r\n return this.authorizationService.user.isAdmin\r\n ? true\r\n : this.authorizationService.getUserByUserName(this.authService.currentUser.email).pipe(\r\n map(user => {\r\n if (user.isAdmin) {\r\n return true;\r\n } else {\r\n this.router.navigateByUrl(\"/\");\r\n return false;\r\n }\r\n })\r\n );\r\n }\r\n}\r\n","import { Injectable, NgZone } from \"@angular/core\";\r\nimport { MatSnackBar } from \"@angular/material/snack-bar\";\r\nimport { CanActivate, Router } from \"@angular/router\";\r\nimport { AuthService } from \"@services/auth/auth.service\";\r\nimport { AuthorizationService } from \"@services/authorization.service\";\r\nimport { CommonService } from \"@services/common.service\";\r\nimport { OrientationService } from \"../services/orientation.service\";\r\nimport { Constants } from \"../shared\";\r\n\r\n@Injectable({ providedIn: \"root\" })\r\nexport class AuthorizationGuard implements CanActivate {\r\n constructor(\r\n private authService: AuthService,\r\n private authorizationService: AuthorizationService,\r\n private router: Router,\r\n private _zone: NgZone,\r\n private orientationService: OrientationService,\r\n private commonService: CommonService,\r\n private snackBar: MatSnackBar\r\n ) {}\r\n\r\n canActivate() {\r\n if (this.authService.isLoggedIn) {\r\n this.authorizationService.getUserByUserName(this.authService.currentUser.email).subscribe(result => {\r\n if (result && !this.commonService.isEmpty(result)) {\r\n if (result.id) {\r\n if (result.isStaff) {\r\n setTimeout(() => {\r\n this._zone.run(() => this.router.navigateByUrl(Constants.studentsPath));\r\n });\r\n } else {\r\n this.orientationService.getStudentStepsAndProgress(parseInt(result.id.toString())).subscribe(data => {\r\n const hasCompletedAllSteps =\r\n data !== null &&\r\n data.studentProgress.completedSteps === data.studentProgress.totalSteps &&\r\n data.studentProgress.totalSteps > 0;\r\n\r\n setTimeout(() => {\r\n this._zone.run(() =>\r\n this.router.navigateByUrl(\r\n hasCompletedAllSteps ? Constants.dashboardPath : Constants.orientationPath\r\n )\r\n );\r\n });\r\n });\r\n }\r\n } else {\r\n this.snackBar.open(\r\n \"No user account with the provided username and password was found. Please reach out to support@icademyglobal.org or contact your mentor if you need access or think this is a mistake.\",\r\n \"Dismiss\",\r\n {\r\n duration: 6000,\r\n }\r\n );\r\n setTimeout(() => {\r\n this._zone.run(() => this.router.navigateByUrl(\"/not-authorized\"));\r\n }, 200);\r\n }\r\n }\r\n });\r\n return true;\r\n } else {\r\n return false;\r\n }\r\n }\r\n}\r\n","import { Injectable } from \"@angular/core\";\r\nimport { CanActivate, Router } from \"@angular/router\";\r\nimport { AuthService } from \"@services/auth/auth.service\";\r\nimport { AuthorizationService } from \"@services/authorization.service\";\r\nimport { Observable } from \"rxjs\";\r\nimport { map } from \"rxjs/operators\";\r\n\r\n@Injectable({ providedIn: \"root\" })\r\nexport class MentorAdminGuard implements CanActivate {\r\n constructor(\r\n private router: Router,\r\n private authService: AuthService,\r\n private authorizationService: AuthorizationService\r\n ) {}\r\n\r\n canActivate(): Observable | boolean {\r\n return this.authService.currentUser.isMentor || this.authService.currentUser.isAdmin\r\n ? true\r\n : this.authorizationService.getUserByUserName(this.authService.currentUser.email).pipe(\r\n map(user => {\r\n if (user.isMentor || user.isAdmin) {\r\n return true;\r\n } else {\r\n this.router.navigateByUrl(\"/\");\r\n return false;\r\n }\r\n })\r\n );\r\n }\r\n}\r\n","import { Injectable } from \"@angular/core\";\r\nimport { CanActivate, Router } from \"@angular/router\";\r\nimport { AuthService } from \"@services/auth/auth.service\";\r\nimport { AuthorizationService } from \"@services/authorization.service\";\r\nimport { Observable } from \"rxjs\";\r\nimport { map } from \"rxjs/operators\";\r\n\r\n@Injectable({ providedIn: \"root\" })\r\nexport class MentorGuard implements CanActivate {\r\n constructor(\r\n private router: Router,\r\n private authService: AuthService,\r\n private authorizationService: AuthorizationService\r\n ) {}\r\n\r\n canActivate(): Observable | boolean {\r\n return this.authService.currentUser.isMentor\r\n ? true\r\n : this.authorizationService.getUserByUserName(this.authService.currentUser.email).pipe(\r\n map(user => {\r\n if (user.isMentor) {\r\n return true;\r\n } else {\r\n this.router.navigateByUrl(\"/\");\r\n return false;\r\n }\r\n })\r\n );\r\n }\r\n}\r\n","import { Injectable } from \"@angular/core\";\r\nimport { CanActivate, Router } from \"@angular/router\";\r\nimport { AuthService } from \"@services/auth/auth.service\";\r\nimport { AuthorizationService } from \"@services/authorization.service\";\r\nimport { Observable } from \"rxjs\";\r\nimport { map } from \"rxjs/operators\";\r\n\r\n@Injectable({ providedIn: \"root\" })\r\nexport class StaffGuard implements CanActivate {\r\n isStaff: boolean = false;\r\n\r\n constructor(\r\n private router: Router,\r\n private authService: AuthService,\r\n private authorizationService: AuthorizationService\r\n ) {}\r\n\r\n canActivate(): Observable | boolean {\r\n return this.authorizationService.user.isStaff\r\n ? true\r\n : this.authorizationService.getUserByUserName(this.authService.currentUser.email).pipe(\r\n map(user => {\r\n if (user.isStaff) {\r\n return true;\r\n } else {\r\n this.router.navigateByUrl(\"/\");\r\n return false;\r\n }\r\n })\r\n );\r\n }\r\n}\r\n","import { Injectable } from \"@angular/core\";\r\nimport { CanActivate, Router } from \"@angular/router\";\r\nimport { AuthService } from \"@services/auth/auth.service\";\r\nimport { AuthorizationService } from \"@services/authorization.service\";\r\nimport { User } from \"app/models\";\r\nimport { Observable } from \"rxjs\";\r\nimport { map } from \"rxjs/operators\";\r\n\r\n@Injectable({ providedIn: \"root\" })\r\nexport class TeacherGuard implements CanActivate {\r\n user: User;\r\n\r\n constructor(\r\n private router: Router,\r\n private authService: AuthService,\r\n private authorizationService: AuthorizationService\r\n ) {}\r\n\r\n canActivate(): Observable | boolean {\r\n return this.authorizationService.user.isTeacher || this.authorizationService.user.isAdmin\r\n ? true\r\n : this.authorizationService.getUserByUserName(this.authService.currentUser.email).pipe(\r\n map(user => {\r\n if (user.isTeacher || user.isAdmin) {\r\n return true;\r\n } else {\r\n this.router.navigateByUrl(\"/\");\r\n return false;\r\n }\r\n })\r\n );\r\n }\r\n}\r\n","import { Injectable } from \"@angular/core\";\r\n\r\n@Injectable({ providedIn: \"root\" })\r\nexport class DBkeys {\r\n public static readonly CURRENT_USER = \"current_user\";\r\n public static readonly USER_PERMISSIONS = \"user_permissions\";\r\n public static readonly REMEMBER_ME = \"remember_me\";\r\n public static readonly LANGUAGE = \"language\";\r\n public static readonly HOME_URL = \"home_url\";\r\n public static readonly DRAWER_OPEN = \"drawer_open\";\r\n public static readonly PAGINATOR_SETTINGS = \"paginator_settings\";\r\n}\r\n","import { DOCUMENT } from \"@angular/common\";\r\nimport { Inject, Injectable, RendererFactory2 } from \"@angular/core\";\r\n\r\n@Injectable({ providedIn: \"root\" })\r\nexport class Utilities {\r\n public static readonly captionAndMessageSeparator = \":\";\r\n public static readonly noNetworkMessageCaption = \"No Network\";\r\n public static readonly noNetworkMessageDetail = \"The server cannot be reached\";\r\n public static readonly accessDeniedMessageCaption = \"Access Denied!\";\r\n public static readonly accessDeniedMessageDetail = \"\";\r\n public static readonly notFoundMessageCaption = \"Not Found\";\r\n public static readonly notFoundMessageDetail = \"The target resource cannot be found\";\r\n\r\n constructor(@Inject(DOCUMENT) private document, private renderer2: RendererFactory2) {}\r\n\r\n public appendScript(url: string) {\r\n var item = this.document.createElement(\"script\");\r\n item.type = \"text/javascript\";\r\n item.src = url;\r\n this.renderer2.createRenderer(null, null).appendChild(this.document.body, item);\r\n }\r\n\r\n public static getQueryParamsFromString(paramString: string) {\r\n if (!paramString) {\r\n return null;\r\n }\r\n\r\n const params: { [key: string]: string } = {};\r\n\r\n for (const param of paramString.split(\"&\")) {\r\n const keyValue = Utilities.splitInTwo(param, \"=\");\r\n params[keyValue.firstPart] = keyValue.secondPart;\r\n }\r\n\r\n return params;\r\n }\r\n\r\n public static splitInTwo(text: string, separator: string): { firstPart: string; secondPart: string } {\r\n const separatorIndex = text.indexOf(separator);\r\n\r\n if (separatorIndex === -1) {\r\n return { firstPart: text, secondPart: null };\r\n }\r\n\r\n const part1 = text.substr(0, separatorIndex).trim();\r\n const part2 = text.substr(separatorIndex + 1).trim();\r\n\r\n return { firstPart: part1, secondPart: part2 };\r\n }\r\n\r\n public static JsonTryParse(value: string) {\r\n try {\r\n return JSON.parse(value);\r\n } catch (e) {\r\n if (value === \"undefined\") {\r\n return void 0;\r\n }\r\n return value;\r\n }\r\n }\r\n\r\n public static toTitleCase(text: string) {\r\n return text.replace(/\\w\\S*/g, subString => {\r\n return subString.charAt(0).toUpperCase() + subString.substr(1).toLowerCase();\r\n });\r\n }\r\n\r\n /** Dynamically determine the base URL from current URL. */\r\n public static baseUrl() {\r\n let base = \"\";\r\n\r\n if (window.location.origin) {\r\n base = window.location.origin;\r\n } else {\r\n base =\r\n window.location.protocol +\r\n \"//\" +\r\n window.location.hostname +\r\n (window.location.port ? \":\" + window.location.port : \"\");\r\n }\r\n\r\n return base.replace(/\\/$/, \"\");\r\n }\r\n}\r\n","import { HttpClient } from \"@angular/common/http\";\r\nimport { Injectable } from \"@angular/core\";\r\nimport { Elective } from \"@models/elective\";\r\nimport { ElectiveGroup } from \"@models/elective-group\";\r\nimport { ElectiveGroupChoice } from \"@models/elective-group-choice\";\r\nimport { ShortcutContentModel, StudentResourceContent } from \"@models/step-content.model\";\r\nimport { StudentResource } from \"@models/student-resource.model\";\r\nimport { AppTileMetadata, Break, ElectiveSetting, Enrollment, InterventionThreshold, Staff } from \"app/models\";\r\nimport { ApiService } from \"app/shared\";\r\nimport { Observable } from \"rxjs\";\r\n\r\n@Injectable({ providedIn: \"root\" })\r\nexport class AdminService extends ApiService {\r\n constructor(http: HttpClient) {\r\n super(http, \"admin\");\r\n }\r\n\r\n // Gets\r\n returnBreaks(year: number): Observable {\r\n return this.get(`returnBreaks/${year}`);\r\n }\r\n\r\n returnInterventionThresholds(): Observable {\r\n return this.get(`returnInterventionThresholds`);\r\n }\r\n\r\n returnAppShortcuts(): Observable {\r\n return this.get(\"returnAppTiles\");\r\n }\r\n\r\n // Posts\r\n createBreak(item: Break): Observable {\r\n return this.post(`createBreak`, item);\r\n }\r\n\r\n uploadEnrollmentImportData(file: File): Observable {\r\n return this.post(\"uploadEnrollmentImportData\", file);\r\n }\r\n\r\n addAppTileMetadata(appTile: AppTileMetadata): Observable {\r\n return this.post(\"addAppTileMetadata\", appTile);\r\n }\r\n\r\n // Puts\r\n updateInterventionThreshold(item: InterventionThreshold): Observable {\r\n return this.put(`updateInterventionThreshold`, item);\r\n }\r\n\r\n updateEnrollments(items: Enrollment[]): Observable {\r\n return this.put(`updateEnrollments`, items);\r\n }\r\n\r\n updateAppTileMetadata(appTile: AppTileMetadata): Observable {\r\n return this.put(`updateAppTileMetadata`, appTile);\r\n }\r\n\r\n uploadAppTileMetadataImage(id: number, file: File) {\r\n return this.put(`uploadAppTileImage/${id}`, file);\r\n }\r\n\r\n updateAppTileGradeLevels(appTile: AppTileMetadata): Observable {\r\n return this.put(`updateAppTileGradeLevels`, appTile);\r\n }\r\n\r\n updateStaffMember(staff: Staff): Observable {\r\n return this.put(\"updateStaffMember\", staff);\r\n }\r\n\r\n // Deletes\r\n deleteBreak(id: number): Observable {\r\n return this.delete(`deleteBreak/${id}`);\r\n }\r\n\r\n //StudentResources\r\n returnStudentResources(): Observable {\r\n return this.get(\"returnStudentResources\");\r\n }\r\n\r\n addStudentResource(studentResource: StudentResource): Observable {\r\n return this.post(\"addStudentResource\", studentResource);\r\n }\r\n\r\n updateStudentResource(studentResource: StudentResource): Observable {\r\n return this.put(`updateStudentResource`, studentResource);\r\n }\r\n\r\n updateStudentResourceGradeLevels(studentResource: StudentResource): Observable {\r\n return this.post(`updateStudentResourceGradeLevels`, studentResource);\r\n }\r\n\r\n deleteStudentResource(id: number): Observable {\r\n return this.delete(`deleteStudentResource/${id}`);\r\n }\r\n\r\n deleteAppShortcut(id: number): Observable {\r\n return this.delete(`deleteAppTileMetadata/${id}`);\r\n }\r\n\r\n deleteElectiveGroupChoice(electiveGroupChoice: ElectiveGroupChoice) {\r\n return this.delete(`deleteElectiveGroupChoice/${electiveGroupChoice.id}`);\r\n }\r\n\r\n deleteElectiveGroup(electiveGroup: ElectiveGroup) {\r\n return this.delete(`deleteElectiveGroup/${electiveGroup.id}`);\r\n }\r\n\r\n createElectiveGroup(electiveGroup: ElectiveGroup) {\r\n return this.post(`createElectiveGroup`, electiveGroup);\r\n }\r\n\r\n createElectiveGroupChoice(electiveGroupChoice: ElectiveGroupChoice) {\r\n return this.post(`CreateElectiveGroupChoice`, electiveGroupChoice);\r\n }\r\n\r\n updateElectiveGroup(electiveGroup: ElectiveGroup) {\r\n return this.put(`updateElectiveGroup`, electiveGroup);\r\n }\r\n\r\n //Electives\r\n\r\n addElective(elective: Elective): Observable {\r\n return this.post(\"addElective\", elective);\r\n }\r\n\r\n updateElective(elective: Elective): Observable {\r\n return this.put(`updateElective`, elective);\r\n }\r\n\r\n deleteElective(id: number): Observable {\r\n return this.delete(`deleteElective/${id}`);\r\n }\r\n\r\n updateElectiveSettings(electiveSettings: ElectiveSetting[]): Observable {\r\n return this.put(`updateElectiveSettings`, electiveSettings);\r\n }\r\n\r\n returnAppShortcutsBySearch(searchTerm: string): Observable {\r\n return this.get(`returnAppTileMetadataBySearch`, { searchTerm: searchTerm });\r\n }\r\n\r\n addAppTileMetadataContent(shortcutContentModel: ShortcutContentModel) {\r\n return this.post(\"addAppTileMetadataContent\", shortcutContentModel);\r\n }\r\n\r\n returnStudentResourcesBySearch(searchTerm: string): Observable {\r\n return this.get(`returnStudentResourcesBySearch`, { searchTerm: searchTerm });\r\n }\r\n\r\n addStudentResourcesContent(studentResourceContent: StudentResourceContent) {\r\n return this.post(\"addStudentResourceContent\", studentResourceContent);\r\n }\r\n}\r\n","import { UserRoles } from \"app/enums/repository/user-roles.enum\";\r\nimport { Constants } from \"app/shared\";\r\n\r\n/** The cached data contract for the current user */\r\nexport interface UserDtoInterface {\r\n id: string;\r\n impersonatingIdentityId?: string;\r\n userId: number;\r\n email: string;\r\n firstName: string;\r\n lastName: string;\r\n emailConfirmed: boolean;\r\n roles: string[];\r\n\r\n isStaff: boolean;\r\n isTeacher: boolean;\r\n isAdmin: boolean;\r\n isInterventionist: boolean;\r\n isReFuelCoordinator: boolean;\r\n isMentor: boolean;\r\n isSecondaryMentor: boolean;\r\n counselorAssignments?: string[];\r\n gradeLevel: string;\r\n\r\n signInProvider?: \"Microsoft\" | \"Google\";\r\n\r\n isInRole: (...role: string[]) => boolean;\r\n hasAnyViewRole: (rolePrefix: string) => boolean;\r\n}\r\n\r\nexport class UserDtoModel implements UserDtoInterface {\r\n id: string;\r\n impersonatingIdentityId?: string;\r\n userId: number;\r\n email: string;\r\n firstName: string;\r\n lastName: string;\r\n emailConfirmed: boolean;\r\n roles: string[];\r\n gradeLevel: string;\r\n counselorAssignments?: string[];\r\n\r\n get isStaff() {\r\n return this.isInRole(UserRoles.Staff);\r\n }\r\n get isTeacher() {\r\n return this.isStaff && this.isInRole(UserRoles.Teacher);\r\n }\r\n get isAdmin() {\r\n return this.isStaff && this.isInRole(UserRoles.Admin);\r\n }\r\n get isInterventionist() {\r\n return this.isStaff && this.isInRole(UserRoles.Interventionist);\r\n }\r\n get isReFuelCoordinator() {\r\n return this.isStaff && this.isInRole(UserRoles.ReFuelCoordinator);\r\n }\r\n get isMentor() {\r\n return this.isStaff && this.isInRole(UserRoles.Mentor);\r\n }\r\n get isSecondaryMentor() {\r\n return this.isStaff && this.isInRole(UserRoles.SecondaryMentor);\r\n }\r\n\r\n /** todo: remove once iCademy fully transitions to Google */\r\n get signInProvider() {\r\n if (new Date() > new Date(2023, 6, 28)) {\r\n return \"Google\"; // always return Google if it's after July 28, 2023\r\n }\r\n\r\n return localStorage.getItem(Constants.loginProvider) as \"Microsoft\" | \"Google\";\r\n }\r\n\r\n /**\r\n * Returns true if the logged in user has any \"view\" role with the provided prefix or if `rolePrefix` is falsey.\r\n * @param role\r\n */\r\n hasAnyViewRole(rolePrefix: string) {\r\n if (!rolePrefix) {\r\n return true;\r\n }\r\n\r\n return this.roles && this.roles.some(r => r.startsWith(rolePrefix));\r\n }\r\n\r\n /**\r\n * Returns true if the logged in user has any of the provided role or if `role` is falsey.\r\n * @param role\r\n */\r\n isInRole(...role: string[]) {\r\n if (!role || role[0] == undefined) {\r\n return true;\r\n }\r\n return this.roles && this.roles.some(r => role.indexOf(r) !== -1);\r\n }\r\n}\r\n","import { HttpClient, HttpEvent, HttpEventType } from \"@angular/common/http\";\r\nimport { Injectable } from \"@angular/core\";\r\nimport { Utilities } from \"app/helpers/utilities/utilities\";\r\nimport { environment } from \"environments/environment\";\r\nimport { merge } from \"lodash\";\r\nimport { Observable } from \"rxjs\";\r\nimport { map, tap } from \"rxjs/operators\";\r\n\r\n@Injectable({ providedIn: \"root\" })\r\nexport class ApiBase {\r\n protected baseUrl: string;\r\n protected environment = environment;\r\n\r\n constructor(protected http: HttpClient) {\r\n this.baseUrl = `${this.environment.baseUrl || Utilities.baseUrl()}/api`;\r\n }\r\n\r\n protected _get(options: ApiOptions = null): Observable {\r\n const getUrl = this.buildUrl(options);\r\n return this.http.get(getUrl);\r\n }\r\n\r\n protected _getById(id: number | string, options: ApiOptions = null): Observable {\r\n const getUrl = this.buildUrl(options, `${this.baseUrl}/${encodeURIComponent(id)}`);\r\n return this.http.get(getUrl);\r\n }\r\n\r\n protected _getBySearch(searchTerm: string | string, options: ApiOptions = null): Observable {\r\n const ops = merge({ query: { searchTerm } }, options);\r\n const getUrl = this.buildUrl(ops, `${this.baseUrl}/Search`);\r\n return this.http.get(getUrl);\r\n }\r\n\r\n protected _post(body: any, options: ApiOptions = null): Observable {\r\n const postUrl = this.buildUrl(options);\r\n return this.http.post(postUrl, body);\r\n }\r\n\r\n protected _put(body: any, options: ApiOptions = null): Observable {\r\n const putUrl = this.buildUrl(options);\r\n return this.http.put(putUrl, body);\r\n }\r\n\r\n protected _putById(body: any, id: number | string, options: ApiOptions = null): Observable {\r\n const putUrl = this.buildUrl(options, `${this.baseUrl}/${encodeURIComponent(id)}`);\r\n return this.http.put(putUrl, body);\r\n }\r\n\r\n protected _delete(id: number | string = \"\", options: ApiOptions = null): Observable {\r\n const deleteUrl = this.buildUrl(options, `${this.baseUrl}/${encodeURIComponent(id)}`);\r\n return this.http.delete(deleteUrl);\r\n }\r\n\r\n protected _deleteByItem(body: any, apiOptions: ApiOptions = null): Observable {\r\n const deleteUrl = this.buildUrl(apiOptions, this.baseUrl);\r\n return this.http.delete(deleteUrl, { body });\r\n }\r\n\r\n protected _count(options: ApiOptions = null): Observable {\r\n const getUrl = this.buildUrl(options, `${this.baseUrl}`);\r\n return this.http.head(getUrl, { observe: \"response\" }).pipe(\r\n map(resp => {\r\n return parseInt(resp.headers.get(\"count\"));\r\n })\r\n );\r\n }\r\n\r\n protected _downloadFile(options: ApiOptions = null, body?: any) {\r\n const downloadUrl = this.buildUrl(options, options.url ? null : `${this.baseUrl}/Export`);\r\n const downloadRequest =\r\n body != null\r\n ? this.http.post(downloadUrl, body, {\r\n reportProgress: true,\r\n responseType: \"blob\",\r\n observe: \"events\",\r\n })\r\n : this.http.get(downloadUrl, {\r\n reportProgress: true,\r\n responseType: \"blob\",\r\n observe: \"events\",\r\n });\r\n\r\n return downloadRequest.pipe(\r\n tap((event: HttpEvent & { filename: string }) => {\r\n if (event.type === HttpEventType.Response) {\r\n event.filename = event.headers.get(\"content-disposition\")?.split(\"filename=\")[1]?.split(\";\")[0];\r\n }\r\n })\r\n );\r\n }\r\n\r\n /**\r\n * Builds the API URL based on the input.\r\n * @param options The url and query properties are appended to the rootUrl\r\n * @param rootUrl The root of the API url. If falsey or not provided, then the baseUrl is used by default.\r\n */\r\n protected buildUrl(options: ApiOptions, rootUrl: string = null) {\r\n let url = rootUrl || this.baseUrl;\r\n const queryString = ApiBase.toQueryString(options?.query);\r\n\r\n if (options?.url) {\r\n let relativeUrl = options.url;\r\n if (relativeUrl.startsWith(\"/\")) {\r\n relativeUrl = relativeUrl.substring(1);\r\n }\r\n\r\n if (url.endsWith(\"/\")) {\r\n url += relativeUrl;\r\n } else {\r\n url += \"/\" + relativeUrl;\r\n }\r\n }\r\n\r\n return url + queryString;\r\n }\r\n\r\n /**\r\n * If query is a string, it is returned with the question mark conditionally trimmed based on withQuestionMark.\r\n * If query is an object, the object's keys are iterated and converted into a key-value pairs with encoding.\r\n * @param query\r\n * @param withQuestionMark Conditionally ensures the result is prepended with a question mark. Defaults to true.\r\n * @returns {string} An encoded query string without the leading '?'.\r\n */\r\n public static toQueryString(query: string | {}, withQuestionMark: boolean = true): string {\r\n let queryString = \"\";\r\n\r\n if (!query) {\r\n return \"\";\r\n }\r\n\r\n if (typeof query === \"string\") {\r\n queryString = query.startsWith(\"?\")\r\n ? query.substring(1) // trim the leading question mark\r\n : query;\r\n } else {\r\n const params = new URLSearchParams();\r\n\r\n for (let key in query) {\r\n const appendArray = (value: any[]) => {\r\n for (let elem of value) {\r\n params.append(key, elem instanceof Date ? elem.toISOString() : elem);\r\n }\r\n };\r\n\r\n if (Array.isArray(query[key])) {\r\n appendArray(query[key]);\r\n } else if (query[key] !== null && query[key] !== undefined) {\r\n let value = query[key];\r\n\r\n if (value instanceof Date) {\r\n value = value.toISOString();\r\n } else if (value instanceof Set) {\r\n appendArray([...value]);\r\n continue;\r\n }\r\n\r\n params.set(key, query[key] instanceof Date ? query[key].toISOString() : query[key]);\r\n }\r\n }\r\n\r\n queryString = params.toString();\r\n }\r\n\r\n return withQuestionMark ? \"?\" + queryString : queryString;\r\n }\r\n}\r\n\r\nexport interface ApiOptions {\r\n /** Query to append to the URL */\r\n query?: string | {};\r\n /** URL to append to the base URL */\r\n url?: string;\r\n}\r\n","import { HttpClient } from \"@angular/common/http\";\r\nimport { Injectable } from \"@angular/core\";\r\nimport { Observable } from \"rxjs\";\r\nimport { ApiBase } from \"./api-base.service\";\r\n\r\n@Injectable({ providedIn: \"root\" })\r\nexport class ControllerBase extends ApiBase {\r\n constructor(http: HttpClient, protected controller: string) {\r\n super(http);\r\n this.baseUrl = `${this.baseUrl}/${controller}`;\r\n }\r\n\r\n protected $get(filter: object = undefined): Observable {\r\n return this._get({ query: filter });\r\n }\r\n\r\n protected $getById(id: string | number): Observable {\r\n return this._getById(id);\r\n }\r\n\r\n protected $getBySearch(searchTerm: string, filter: object = undefined): Observable {\r\n return this._getBySearch(searchTerm, { query: filter });\r\n }\r\n\r\n protected $post(body: Interface): Observable {\r\n return this._post(body);\r\n }\r\n\r\n protected $put(body: Interface): Observable {\r\n return this._put(body);\r\n }\r\n\r\n protected $putById(body: Interface, id: number | string): Observable {\r\n return this._putById(body, id);\r\n }\r\n\r\n protected $delete(id: number | string): Observable {\r\n return this._delete(id);\r\n }\r\n\r\n protected $deleteByItem(body: Interface): Observable {\r\n return this._deleteByItem(body);\r\n }\r\n\r\n protected $getCount(): Observable {\r\n return this._count();\r\n }\r\n}\r\n","import { HttpClient } from \"@angular/common/http\";\r\nimport { Injectable } from \"@angular/core\";\r\nimport { Observable } from \"rxjs\";\r\nimport { ControllerBase } from \"../../../services/api/controller-base\";\r\nimport { ApplicationIdentityUser } from \"../models/application-identity-user.model\";\r\nimport { ProfileDtoInterface } from \"../models/profile-dto.model\";\r\nimport { UserDtoInterface } from \"../models/user-dto.model\";\r\n\r\n@Injectable({ providedIn: \"root\" })\r\nexport class AccountApiService extends ControllerBase {\r\n constructor(http: HttpClient) {\r\n super(http, \"Account/Account\");\r\n }\r\n\r\n /** Signs user into server. If successful, the user is returned from the server. */\r\n signIn(userName: string, password: string, rememberMe?: boolean, backdoor?: boolean) {\r\n return this._post(\r\n {\r\n userName,\r\n password,\r\n rememberMe,\r\n backdoor,\r\n },\r\n { url: \"SignIn\" }\r\n );\r\n }\r\n\r\n /** Signs user out of server. */\r\n signOut() {\r\n return this._post(null, { url: \"SignOut\" });\r\n }\r\n\r\n /** Returns currently signed in user. */\r\n me() {\r\n return this._get({ url: \"me\" });\r\n }\r\n\r\n confirmEmail(emailAddress: string, code: string): Observable {\r\n return this._post(null, {\r\n url: \"ConfirmEmail\",\r\n query: { emailAddress, code },\r\n });\r\n }\r\n\r\n resendConfirmEmail(): Observable {\r\n return this._post(null, {\r\n url: \"ResendConfirmEmail\",\r\n });\r\n }\r\n\r\n forgotPassword(emailAddress: string): Observable {\r\n return this._post(null, {\r\n url: \"ForgotPassword\",\r\n query: { emailAddress },\r\n });\r\n }\r\n\r\n resetPassword(emailAddress: string, password: string, code: string): Observable {\r\n const body = {\r\n emailAddress,\r\n password,\r\n code,\r\n };\r\n\r\n return this._post(body, { url: \"ResetPassword\" });\r\n }\r\n\r\n impersonate(identityId: string): Observable {\r\n return this._post(null, {\r\n url: \"Impersonate\",\r\n query: { identityId },\r\n });\r\n }\r\n\r\n abortImpersonate(): Observable {\r\n return this._post(null, {\r\n url: \"AbortImpersonate\",\r\n });\r\n }\r\n\r\n updateProfile(user: ProfileDtoInterface): Observable {\r\n return this._post(user, { url: \"UpdateProfile\" });\r\n }\r\n}\r\n","import { Injectable } from \"@angular/core\";\r\nimport { NavigationExtras, Router } from \"@angular/router\";\r\nimport { Observable, Subject, Subscriber } from \"rxjs\";\r\nimport { map, switchMap } from \"rxjs/operators\";\r\n\r\nimport { DBkeys } from \"app/helpers/constants/db-keys.constants\";\r\nimport { Utilities } from \"app/helpers/utilities/utilities\";\r\nimport { UserDtoInterface, UserDtoModel } from \"../../modules/account/models/user-dto.model\";\r\nimport { AccountApiService } from \"../../modules/account/services/account-api.service\";\r\nimport { LocalStoreManager } from \"../local-store-manager.service\";\r\n\r\n@Injectable({ providedIn: \"root\" })\r\nexport class AuthService {\r\n private previousIsLoggedInCheck = false;\r\n private loginStatus = new Subject();\r\n\r\n loginRedirectUrl: string;\r\n logoutRedirectUrl: string;\r\n\r\n reLoginDelegate: () => void;\r\n\r\n private readonly refreshing: Subscriber[] = [];\r\n\r\n get currentUser(): UserDtoInterface {\r\n const user = this.localStorage.getDataObject(DBkeys.CURRENT_USER);\r\n this.reevaluateLoginStatus(user);\r\n return user ? Object.assign(new UserDtoModel(), user) : null;\r\n }\r\n\r\n get isLoggedIn(): boolean {\r\n return this.currentUser != null;\r\n }\r\n\r\n get rememberMe(): boolean {\r\n return this.localStorage.getDataObject(DBkeys.REMEMBER_ME) === true;\r\n }\r\n\r\n set rememberMe(value: boolean) {\r\n this.localStorage.savePermanentData(value, DBkeys.REMEMBER_ME);\r\n }\r\n\r\n constructor(\r\n private router: Router,\r\n private localStorage: LocalStoreManager,\r\n private accountApiService: AccountApiService\r\n ) {\r\n this.initializeLoginStatus();\r\n }\r\n\r\n getReturnUrl(): {\r\n firstPart: string;\r\n extras: NavigationExtras;\r\n wholePart: string;\r\n } {\r\n const redirect =\r\n this.loginRedirectUrl && this.loginRedirectUrl !== \"/\" && this.loginRedirectUrl !== \"/\"\r\n ? this.loginRedirectUrl\r\n : \"/\";\r\n this.loginRedirectUrl = null;\r\n\r\n const urlParamsAndFragment = Utilities.splitInTwo(redirect, \"#\");\r\n const urlAndParams = Utilities.splitInTwo(urlParamsAndFragment.firstPart, \"?\");\r\n\r\n const navigationExtras: NavigationExtras = {\r\n fragment: urlParamsAndFragment.secondPart,\r\n queryParams: Utilities.getQueryParamsFromString(urlAndParams.secondPart),\r\n queryParamsHandling: \"merge\",\r\n };\r\n\r\n return {\r\n firstPart: urlParamsAndFragment.firstPart,\r\n extras: navigationExtras,\r\n wholePart: redirect,\r\n };\r\n }\r\n\r\n redirectLoginUser() {\r\n const returnUrl: string = this.localStorage.getData(LocalStoreManager.DBKEY_RETURN_URL);\r\n if (returnUrl) {\r\n this.localStorage.deleteData(LocalStoreManager.DBKEY_RETURN_URL);\r\n this.router.navigateByUrl(returnUrl);\r\n } else {\r\n const { firstPart, extras } = this.getReturnUrl();\r\n this.router.navigate([firstPart], extras);\r\n }\r\n }\r\n\r\n redirectLogoutUser() {\r\n const redirect = this.logoutRedirectUrl ? this.logoutRedirectUrl : \"/login\";\r\n this.logoutRedirectUrl = null;\r\n\r\n this.router.navigate([redirect]);\r\n }\r\n\r\n redirectForLogin() {\r\n this.loginRedirectUrl = this.router.url;\r\n this.router.navigateByUrl(\"/login\");\r\n }\r\n\r\n reLogin() {\r\n if (this.reLoginDelegate) {\r\n this.reLoginDelegate();\r\n } else {\r\n this.redirectForLogin();\r\n }\r\n }\r\n\r\n signIn(userName: string, password: string, rememberMe?: boolean, backdoor?: boolean): Observable {\r\n let signIn = this.accountApiService\r\n .signIn(userName, password, rememberMe, backdoor)\r\n .pipe(map((response: UserDtoInterface) => this.processLoginResponse(response, rememberMe)));\r\n\r\n if (this.isLoggedIn) {\r\n signIn = this.signOut().pipe(switchMap(() => signIn));\r\n }\r\n\r\n return signIn;\r\n }\r\n\r\n confirmEmail(emailAddress: string, code: string): Observable {\r\n return this.accountApiService\r\n .confirmEmail(emailAddress, code)\r\n .pipe(map((response: UserDtoInterface) => this.processLoginResponse(response)));\r\n }\r\n\r\n refreshUser(): Observable {\r\n const service = this;\r\n\r\n return new Observable(subscriber => {\r\n service.refreshing.push(subscriber);\r\n\r\n if (service.refreshing.length <= 1) {\r\n const subscription = service.accountApiService\r\n .me()\r\n .pipe(\r\n map((response: UserDtoInterface) => {\r\n if (response) {\r\n service.processLoginResponse(response);\r\n }\r\n return response;\r\n })\r\n )\r\n .subscribe({\r\n next(value) {\r\n while (service.refreshing.length) {\r\n const sub = service.refreshing.pop();\r\n sub.next(value);\r\n sub.complete();\r\n }\r\n },\r\n error(err) {\r\n while (service.refreshing.length) {\r\n const sub = service.refreshing.pop();\r\n sub.error(err);\r\n }\r\n },\r\n complete() {\r\n while (service.refreshing.length) {\r\n service.refreshing.pop().complete();\r\n }\r\n },\r\n });\r\n\r\n return () => {\r\n subscription.unsubscribe();\r\n };\r\n }\r\n\r\n return () => {};\r\n });\r\n }\r\n\r\n impersonateUser(id: string) {\r\n return this.accountApiService.impersonate(id).pipe(\r\n map((response: UserDtoInterface) => {\r\n if (response) {\r\n this.processLoginResponse(response);\r\n }\r\n return response;\r\n })\r\n );\r\n }\r\n\r\n abortImpersonate() {\r\n return this.accountApiService.abortImpersonate().pipe(\r\n map((response: UserDtoInterface) => {\r\n if (response) {\r\n this.processLoginResponse(response);\r\n }\r\n return response;\r\n })\r\n );\r\n }\r\n\r\n signOut(): Observable {\r\n while (this.refreshing.length) {\r\n const sub = this.refreshing.pop();\r\n sub.complete();\r\n }\r\n\r\n this.clearUser();\r\n return this.accountApiService.signOut();\r\n }\r\n\r\n getLoginStatusEvent(): Observable {\r\n return this.loginStatus.asObservable();\r\n }\r\n\r\n private processLoginResponse(user: UserDtoInterface, rememberMe?: boolean) {\r\n rememberMe ??= this.rememberMe;\r\n\r\n this.saveUserDetails(user, rememberMe);\r\n this.reevaluateLoginStatus(user);\r\n\r\n return user;\r\n }\r\n\r\n private saveUserDetails(user: UserDtoInterface, rememberMe: boolean) {\r\n this.localStorage.savePermanentData(rememberMe, DBkeys.REMEMBER_ME);\r\n this.localStorage.saveData(user, DBkeys.CURRENT_USER);\r\n }\r\n\r\n private clearUser() {\r\n this.localStorage.deleteData(DBkeys.USER_PERMISSIONS);\r\n this.localStorage.deleteData(DBkeys.CURRENT_USER);\r\n this.reevaluateLoginStatus();\r\n }\r\n\r\n private reevaluateLoginStatus(currentUser?: UserDtoInterface) {\r\n const user = currentUser || this.localStorage.getDataObject(DBkeys.CURRENT_USER);\r\n const isLoggedIn = user != null;\r\n\r\n if (this.previousIsLoggedInCheck !== isLoggedIn) {\r\n setTimeout(() => {\r\n this.loginStatus.next(isLoggedIn);\r\n });\r\n }\r\n\r\n this.previousIsLoggedInCheck = isLoggedIn;\r\n }\r\n\r\n private initializeLoginStatus() {\r\n this.localStorage.getInitEvent().subscribe(() => {\r\n this.reevaluateLoginStatus();\r\n });\r\n }\r\n}\r\n","import { HttpClient } from \"@angular/common/http\";\r\nimport { Injectable } from \"@angular/core\";\r\nimport { User } from \"app/models\";\r\nimport { Observable } from \"rxjs\";\r\nimport { ApiService } from \"../shared\";\r\n\r\n@Injectable({ providedIn: \"root\" })\r\nexport class AuthorizationService extends ApiService {\r\n isAuthorizing = false;\r\n\r\n constructor(http: HttpClient) {\r\n super(http, \"authorization\");\r\n }\r\n\r\n getUserByUserName(username: string): Observable {\r\n return this.get(username);\r\n }\r\n}\r\n","import { HttpBackend, HttpClient } from \"@angular/common/http\";\r\nimport { Injectable } from \"@angular/core\";\r\nimport { Elective } from \"@models/elective\";\r\nimport { ElectiveGroup } from \"@models/elective-group\";\r\nimport { StudentResource } from \"@models/student-resource.model\";\r\nimport { AppTileMetadata, ClassUser, ElectiveSetting, Staff, Student, User } from \"app/models\";\r\nimport { ApiService, Utility } from \"app/shared\";\r\nimport { Observable, throwError } from \"rxjs\";\r\nimport { catchError, map } from \"rxjs/operators\";\r\n\r\n@Injectable({ providedIn: \"root\" })\r\nexport class CommonService extends ApiService {\r\n constructor(http: HttpClient, private httpBackend: HttpBackend) {\r\n super(http, \"common\");\r\n }\r\n\r\n /* #region Http Gets */\r\n\r\n getAllStudents(query?: { startDate?: Date; endDate?: Date; alwaysIncludeActive?: boolean }): Observable {\r\n const queryString = [\r\n query?.startDate ? `startDate=${Utility.getDateQueryFormat(query.startDate)}` : \"\",\r\n query?.endDate ? `endDate=${Utility.getDateQueryFormat(query.endDate)}` : \"\",\r\n `alwaysIncludeActive=${query?.alwaysIncludeActive ?? false}`,\r\n ]\r\n .filter(Boolean)\r\n .join(\"&\");\r\n\r\n return this.get(`returnAllStudents?${queryString}`);\r\n }\r\n\r\n getAllStaff(): Observable {\r\n return this.get(`returnAllStaff`);\r\n }\r\n\r\n getMentors(hasMentees: boolean = null): Observable {\r\n return this.get(`returnMentors/${hasMentees === null ? \"\" : hasMentees}`);\r\n }\r\n\r\n getCounselors(gradeLevel: string = null): Observable {\r\n return this.get(`returnCounselors/${gradeLevel || \"\"}`);\r\n }\r\n\r\n getStudentsByMentor(mentorId: number): Observable {\r\n return this.get(`returnStudentsByMentor/${mentorId}`);\r\n }\r\n\r\n getStudentById(studentId: number): Observable {\r\n return this.get(`returnStudentById/${studentId}`);\r\n }\r\n\r\n getEnvironment(): Observable {\r\n return this.http\r\n .get(this.apiUrl + \"returnEnvironment\", { responseType: \"text\" as \"json\" })\r\n .pipe(catchError(error => throwError(error)));\r\n }\r\n\r\n returnClassUsersByStudentId(studentId: number, startDate?: Date, endDate?: Date, isPerformanceSnapshot = false) {\r\n if (!startDate) {\r\n startDate = Utility.getBeginningOfWeek();\r\n }\r\n if (!endDate) {\r\n endDate = new Date(startDate);\r\n endDate.setDate(startDate.getDate() + 7);\r\n }\r\n return this.get<{ classUsers: ClassUser[]; adjustedStartDate: Date; adjustedEndDate: Date }>(\r\n `returnClassUsersByStudentId/${studentId}/${Utility.getDateQueryFormat(startDate)}/${Utility.getDateQueryFormat(\r\n endDate\r\n )}?isPerformanceSnapshot=${isPerformanceSnapshot}`\r\n ).pipe(\r\n map(result => ({\r\n classUsers: result.classUsers,\r\n startDate: new Date(result.adjustedStartDate),\r\n endDate: new Date(result.adjustedEndDate),\r\n }))\r\n );\r\n }\r\n\r\n returnElectivesBySearch(searchTerm = \"\") {\r\n return this.get(`returnElectivesBySearch`, { searchTerm: searchTerm });\r\n }\r\n\r\n returnElectives(): Observable {\r\n return this.get(`returnElectives`);\r\n }\r\n\r\n returnElectiveGroups(): Observable {\r\n return this.get(\"returnElectiveGroups\");\r\n }\r\n\r\n returnElectiveSettings(): Observable {\r\n return this.get(`returnElectiveSettings`);\r\n }\r\n\r\n /* #endregion */\r\n\r\n /* #region Http Posts */\r\n\r\n assignMentorToStudent(studentId: number, mentorId: number): Observable {\r\n const item = { studentId: studentId, mentorId: mentorId };\r\n return this.post(`assignMentorToStudent`, item);\r\n }\r\n\r\n setAdmin(userId: number, isAdmin: boolean): Observable {\r\n const item: User = { id: userId, isAdmin };\r\n return this.post(`setAdmin`, item);\r\n }\r\n\r\n setTeacher(userId: number, isTeacher: boolean): Observable {\r\n const item: User = { id: userId, isTeacher };\r\n return this.post(`setTeacher`, item);\r\n }\r\n\r\n setReFuelCoordinator(userId: number, isReFuelCoordinator: boolean): Observable {\r\n const item: User = { id: userId, isReFuelCoordinator };\r\n return this.post(`setRefuelCoordinator`, item);\r\n }\r\n\r\n setInterventionist(userId: number, isInterventionist: boolean): Observable {\r\n const item: User = { id: userId, isInterventionist };\r\n return this.post(`setInterventionist`, item);\r\n }\r\n\r\n assignStudentsToMentor(mentorId: number, studentList: number[]): Observable {\r\n const item = { mentorId: mentorId, studentList };\r\n return this.post(`assignStudentsToMentor`, item);\r\n }\r\n\r\n setStudentGradeLevel(userId: number, gradeLevel: string): Observable {\r\n const item = { userId: userId, gradeLevel };\r\n return this.post(`setStudentGradeLevel`, item);\r\n }\r\n\r\n sendMessageToMentor(student: Student, message: string, isSecondaryMentor: boolean): Observable {\r\n const item = { student, message, isSecondaryMentor };\r\n return this.post(`sendMessageToMentor`, item);\r\n }\r\n\r\n sendErrorEmail(item): Observable {\r\n return this.post(`SendErrorEmail`, item);\r\n }\r\n\r\n assignSecondaryMentorToStudent(studentId: number, mentorId: number): Observable {\r\n const item = { studentId: studentId, mentorId: mentorId };\r\n return this.post(`assignSecondaryMentorToStudent`, item);\r\n }\r\n\r\n unsubscribeFromWeeklySnapshotEmail(studentGoogleId: string): Observable {\r\n return this.post(\r\n \"unsubscribeFromWeeklySnapshotEmail\",\r\n { studentGoogleId },\r\n new HttpClient(this.httpBackend)\r\n );\r\n }\r\n\r\n /* #endregion */\r\n\r\n /* Region Shared Methods */\r\n\r\n isEmpty(obj) {\r\n for (const key in obj) {\r\n if (obj.hasOwnProperty(key)) return false;\r\n }\r\n return true;\r\n }\r\n\r\n /* #endregion */\r\n\r\n returnStaffBySearch(searchTerm = \"\"): Observable {\r\n return this.get(`returnStaffBySearch`, { searchTerm: searchTerm });\r\n }\r\n\r\n returnUserById(id: number): Observable {\r\n return this.get(`returnUserById/${id}`);\r\n }\r\n\r\n returnStudentResourceById(id: number): Observable {\r\n return this.get(`returnStudentResourceById/${id}`);\r\n }\r\n\r\n returnAppShortcutById(id: number): Observable {\r\n return this.get(`returnAppTileMetadataById/${id}`);\r\n }\r\n}\r\n","import { HttpClient } from \"@angular/common/http\";\r\nimport { Injectable } from \"@angular/core\";\r\nimport { Observable } from \"rxjs\";\r\nimport { DirectoryEvent } from \"../models\";\r\nimport { ApiService, Utility } from \"../shared\";\r\nimport { PreviewEmailModel } from \"../staff/components/emailing/preview-email-dialog/preview-email.model\";\r\n\r\n@Injectable({ providedIn: \"root\" })\r\nexport class DirectoryService extends ApiService {\r\n constructor(http: HttpClient) {\r\n super(http, \"directory\");\r\n }\r\n\r\n returnUnreadInboxCount(emailAddress: string): Observable {\r\n return this.get(`returnUnreadInboxCount/${emailAddress}`);\r\n }\r\n\r\n returnCalendarEvents(emailAddress: string): Observable {\r\n const now = new Date();\r\n const startDate = Utility.getDateQueryFormat();\r\n const endDate = Utility.getDateQueryFormat(new Date(now.getFullYear(), now.getMonth(), now.getDate() + 15));\r\n\r\n // return max 10 items within the next two weeks\r\n return this.get(`returnCalendarEvents/${emailAddress}/${startDate}/${endDate}`);\r\n }\r\n\r\n sendCommunicationEmail(email: PreviewEmailModel, options: { interventionId: number } = null): Observable {\r\n // in order to make this post since we are posting several files, we need to use FormData and build the form by hand\r\n const formData = new FormData();\r\n\r\n formData.append(\"fromEmailAddress\", email.fromEmailAddress);\r\n formData.append(\"subject\", email.subject);\r\n formData.append(\"body\", email.body);\r\n formData.append(\"bccAllRecipients\", (email.bccAllRecipients || false).toString());\r\n for (let attachment of email?.attachments) {\r\n formData.append(\"attachments\", attachment);\r\n }\r\n\r\n for (let i = 0; i < email.optionalRecipients?.length; i++) {\r\n formData.append(\r\n `recipients[${i}].includeStudent`,\r\n (\r\n (email.optionalRecipients[i].includeStudent &&\r\n Utility.emailAddressIsValid(email.optionalRecipients[i].userEmailAddress)) ||\r\n false\r\n ).toString()\r\n );\r\n formData.append(\r\n `recipients[${i}].includeGuardian1`,\r\n (\r\n (email.optionalRecipients[i].includeGuardian1 &&\r\n Utility.emailAddressIsValid(email.optionalRecipients[i].guardianEmailAddress)) ||\r\n false\r\n ).toString()\r\n );\r\n formData.append(\r\n `recipients[${i}].includeGuardian2`,\r\n (\r\n (email.optionalRecipients[i].includeGuardian2 &&\r\n Utility.emailAddressIsValid(email.optionalRecipients[i].secondaryGuardianEmailAddress)) ||\r\n false\r\n ).toString()\r\n );\r\n formData.append(\r\n `recipients[${i}].includeMentor`,\r\n (\r\n (email.optionalRecipients[i].includeMentor &&\r\n Utility.emailAddressIsValid(email.optionalRecipients[i].mentorEmail)) ||\r\n false\r\n ).toString()\r\n );\r\n formData.append(\r\n `recipients[${i}].includeStaff`,\r\n (\r\n (email.optionalRecipients[i].includeStaff &&\r\n Utility.emailAddressIsValid(email.optionalRecipients[i].userEmailAddress)) ||\r\n false\r\n ).toString()\r\n );\r\n formData.append(`recipients[${i}].userId`, (email.optionalRecipients[i].userId || 0).toString());\r\n formData.append(`recipients[${i}].userEmailAddress`, email.optionalRecipients[i].userEmailAddress);\r\n formData.append(`recipients[${i}].isStaff`, (email.optionalRecipients[i].isStaff || false).toString());\r\n formData.append(`recipients[${i}].guardianEmailAddress`, email.optionalRecipients[i].guardianEmailAddress);\r\n formData.append(\r\n `recipients[${i}].secondaryGuardianEmailAddress`,\r\n email.optionalRecipients[i].secondaryGuardianEmailAddress\r\n );\r\n formData.append(`recipients[${i}].mentorEmail`, email.optionalRecipients[i].mentorEmail);\r\n }\r\n\r\n const validAdditionalRecipients = email.additionalRecipients?.filter(x => Utility.emailAddressIsValid(x)) ?? [];\r\n for (let i = 0; i < validAdditionalRecipients.length; i++) {\r\n formData.append(`additionalRecipients[${i}]`, validAdditionalRecipients[i]);\r\n }\r\n\r\n return this.post(`sendCommunicationEmail/${options?.interventionId || \"\"}`, formData, this.http, {\r\n \"Content-Type\": \"\",\r\n });\r\n }\r\n}\r\n","import { HttpClient } from \"@angular/common/http\";\r\nimport { Injectable } from \"@angular/core\";\r\nimport { StudentInformation } from \"app/models\";\r\nimport { Observable } from \"rxjs\";\r\nimport { ApiService } from \"../shared\";\r\n\r\n@Injectable({ providedIn: \"root\" })\r\nexport class StudentService extends ApiService {\r\n constructor(http: HttpClient) {\r\n super(http, \"student\");\r\n }\r\n\r\n returnStudentInformationById(studentId: number): Observable {\r\n return this.get(`returnStudentInformationById/${studentId}`);\r\n }\r\n\r\n updateStudentInformation(item: StudentInformation): Observable {\r\n return this.put(\"updateStudentInformation\", item);\r\n }\r\n}\r\n","import { Injectable } from \"@angular/core\";\r\nimport { Observable, Subject } from \"rxjs\";\r\nimport { DBkeys } from \"../helpers/constants/db-keys.constants\";\r\n\r\nimport { Utilities } from \"../helpers/utilities/utilities\";\r\n\r\n@Injectable({ providedIn: \"root\" })\r\n/**\r\n * Provides a wrapper for accessing the web storage API and synchronizing session storage across tabs/windows.\r\n */\r\nexport class LocalStoreManager {\r\n private static syncListenerInitialised = false;\r\n private static readonly DBKEY_SYNC_KEYS = \"sync_keys\";\r\n private syncKeys: string[] = [];\r\n private initEvent = new Subject();\r\n\r\n static readonly DBKEY_USER_DATA = \"user_data\";\r\n static readonly DBKEY_RETURN_URL = \"return_url\";\r\n\r\n private reservedKeys: string[] = [\r\n \"sync_keys\",\r\n \"addToSyncKeys\",\r\n \"removeFromSyncKeys\",\r\n \"getSessionStorage\",\r\n \"setSessionStorage\",\r\n \"addToSessionStorage\",\r\n \"removeFromSessionStorage\",\r\n \"clearAllSessionsStorage\",\r\n ];\r\n\r\n initialiseStorageSyncListener() {\r\n if (LocalStoreManager.syncListenerInitialised === true) {\r\n return;\r\n }\r\n\r\n LocalStoreManager.syncListenerInitialised = true;\r\n window.addEventListener(\"storage\", this.sessionStorageTransferHandler, false);\r\n this.syncSessionStorage();\r\n }\r\n\r\n deinitialiseStorageSyncListener() {\r\n window.removeEventListener(\"storage\", this.sessionStorageTransferHandler, false);\r\n LocalStoreManager.syncListenerInitialised = false;\r\n }\r\n\r\n clearAllStorage() {\r\n this.clearAllSessionsStorage();\r\n this.clearLocalStorage();\r\n }\r\n\r\n clearAllSessionsStorage() {\r\n this.clearInstanceSessionStorage();\r\n localStorage.removeItem(LocalStoreManager.DBKEY_SYNC_KEYS);\r\n }\r\n\r\n clearInstanceSessionStorage() {\r\n sessionStorage.clear();\r\n this.syncKeys = [];\r\n }\r\n\r\n clearLocalStorage() {\r\n localStorage.clear();\r\n }\r\n\r\n /**\r\n * Based on whether a user chose to be remembered or not, this will save data to either local or session storage.\r\n * @param data Data to be stored\r\n * @param key Key of the data to be stored\r\n */\r\n saveData(data: any, key = LocalStoreManager.DBKEY_USER_DATA) {\r\n if (this.getDataObject(DBkeys.REMEMBER_ME)) {\r\n this.savePermanentData(data, key);\r\n } else {\r\n this.saveSyncedSessionData(data, key);\r\n }\r\n }\r\n\r\n saveSessionData(data: any, key = LocalStoreManager.DBKEY_USER_DATA) {\r\n this.testForInvalidKeys(key);\r\n\r\n this.removeFromSyncKeys(key);\r\n localStorage.removeItem(key);\r\n this.sessionStorageSetItem(key, data);\r\n }\r\n\r\n saveSyncedSessionData(data: any, key = LocalStoreManager.DBKEY_USER_DATA) {\r\n this.testForInvalidKeys(key);\r\n\r\n localStorage.removeItem(key);\r\n this.addToSessionStorage(data, key);\r\n }\r\n\r\n savePermanentData(data: any, key = LocalStoreManager.DBKEY_USER_DATA) {\r\n this.testForInvalidKeys(key);\r\n\r\n this.removeFromSessionStorage(key);\r\n this.localStorageSetItem(key, data);\r\n }\r\n\r\n moveDataToSessionStorage(key = LocalStoreManager.DBKEY_USER_DATA) {\r\n this.testForInvalidKeys(key);\r\n\r\n const data = this.getData(key);\r\n\r\n if (data == null) {\r\n return;\r\n }\r\n\r\n this.saveSessionData(data, key);\r\n }\r\n\r\n moveDataToSyncedSessionStorage(key = LocalStoreManager.DBKEY_USER_DATA) {\r\n this.testForInvalidKeys(key);\r\n\r\n const data = this.getData(key);\r\n\r\n if (data == null) {\r\n return;\r\n }\r\n\r\n this.saveSyncedSessionData(data, key);\r\n }\r\n\r\n moveDataToPermanentStorage(key = LocalStoreManager.DBKEY_USER_DATA) {\r\n this.testForInvalidKeys(key);\r\n\r\n const data = this.getData(key);\r\n\r\n if (data == null) {\r\n return;\r\n }\r\n\r\n this.savePermanentData(data, key);\r\n }\r\n\r\n exists(key = LocalStoreManager.DBKEY_USER_DATA) {\r\n let data = sessionStorage.getItem(key);\r\n\r\n if (data == null) {\r\n data = localStorage.getItem(key);\r\n }\r\n\r\n return data != null;\r\n }\r\n\r\n getData(key = LocalStoreManager.DBKEY_USER_DATA) {\r\n this.testForInvalidKeys(key);\r\n\r\n let data = this.sessionStorageGetItem(key);\r\n\r\n if (data == null) {\r\n data = this.localStorageGetItem(key);\r\n }\r\n\r\n return data;\r\n }\r\n\r\n getDataObject(key = LocalStoreManager.DBKEY_USER_DATA, isDateType = false): T {\r\n let data = this.getData(key);\r\n\r\n if (data != null) {\r\n if (isDateType) {\r\n data = new Date(data);\r\n }\r\n return data as T;\r\n } else {\r\n return null;\r\n }\r\n }\r\n\r\n deleteData(key = LocalStoreManager.DBKEY_USER_DATA) {\r\n this.testForInvalidKeys(key);\r\n\r\n this.removeFromSessionStorage(key);\r\n localStorage.removeItem(key);\r\n }\r\n\r\n getInitEvent(): Observable<{}> {\r\n return this.initEvent.asObservable();\r\n }\r\n\r\n private sessionStorageTransferHandler = (event: StorageEvent) => {\r\n if (!event.newValue) {\r\n return;\r\n }\r\n\r\n if (event.key === \"getSessionStorage\") {\r\n if (sessionStorage.length) {\r\n this.localStorageSetItem(\"setSessionStorage\", sessionStorage);\r\n localStorage.removeItem(\"setSessionStorage\");\r\n }\r\n } else if (event.key === \"setSessionStorage\") {\r\n if (!this.syncKeys.length) {\r\n this.loadSyncKeys();\r\n }\r\n const data = JSON.parse(event.newValue);\r\n // console.info(\"Set => Key: Transfer setSessionStorage\" + \", data: \" + JSON.stringify(data));\r\n\r\n for (const key in data) {\r\n if (this.syncKeysContains(key)) {\r\n this.sessionStorageSetItem(key, JSON.parse(data[key]));\r\n }\r\n }\r\n\r\n this.onInit();\r\n } else if (event.key === \"addToSessionStorage\") {\r\n const data = JSON.parse(event.newValue);\r\n\r\n // console.warn(\"Set => Key: Transfer addToSessionStorage\" + \", data: \" + JSON.stringify(data));\r\n\r\n this.addToSessionStorageHelper(data.data, data.key);\r\n } else if (event.key === \"removeFromSessionStorage\") {\r\n this.removeFromSessionStorageHelper(event.newValue);\r\n } else if (event.key === \"clearAllSessionsStorage\" && sessionStorage.length) {\r\n this.clearInstanceSessionStorage();\r\n } else if (event.key === \"addToSyncKeys\") {\r\n this.addToSyncKeysHelper(event.newValue);\r\n } else if (event.key === \"removeFromSyncKeys\") {\r\n this.removeFromSyncKeysHelper(event.newValue);\r\n }\r\n };\r\n\r\n private syncSessionStorage() {\r\n localStorage.setItem(\"getSessionStorage\", \"_dummy\");\r\n localStorage.removeItem(\"getSessionStorage\");\r\n }\r\n\r\n private addToSessionStorage(data: any, key: string) {\r\n this.addToSessionStorageHelper(data, key);\r\n this.addToSyncKeysBackup(key);\r\n\r\n this.localStorageSetItem(\"addToSessionStorage\", { key, data });\r\n localStorage.removeItem(\"addToSessionStorage\");\r\n }\r\n\r\n private addToSessionStorageHelper(data: any, key: string) {\r\n this.addToSyncKeysHelper(key);\r\n this.sessionStorageSetItem(key, data);\r\n }\r\n\r\n private removeFromSessionStorage(keyToRemove: string) {\r\n this.removeFromSessionStorageHelper(keyToRemove);\r\n this.removeFromSyncKeysBackup(keyToRemove);\r\n\r\n localStorage.setItem(\"removeFromSessionStorage\", keyToRemove);\r\n localStorage.removeItem(\"removeFromSessionStorage\");\r\n }\r\n\r\n private removeFromSessionStorageHelper(keyToRemove: string) {\r\n sessionStorage.removeItem(keyToRemove);\r\n this.removeFromSyncKeysHelper(keyToRemove);\r\n }\r\n\r\n private testForInvalidKeys(key: string) {\r\n if (!key) {\r\n throw new Error(\"key cannot be empty\");\r\n }\r\n\r\n if (this.reservedKeys.some(x => x === key)) {\r\n throw new Error(`The storage key \"${key}\" is reserved and cannot be used. Please use a different key`);\r\n }\r\n }\r\n\r\n private syncKeysContains(key: string) {\r\n return this.syncKeys.some(x => x === key);\r\n }\r\n\r\n private loadSyncKeys() {\r\n if (this.syncKeys.length) {\r\n return;\r\n }\r\n\r\n this.syncKeys = this.getSyncKeysFromStorage();\r\n }\r\n\r\n private getSyncKeysFromStorage(defaultValue: string[] = []): string[] {\r\n const data = this.localStorageGetItem(LocalStoreManager.DBKEY_SYNC_KEYS);\r\n\r\n if (data == null) {\r\n return defaultValue;\r\n } else {\r\n return data as string[];\r\n }\r\n }\r\n\r\n private addToSyncKeysBackup(key: string) {\r\n const storedSyncKeys = this.getSyncKeysFromStorage();\r\n\r\n if (!storedSyncKeys.some(x => x === key)) {\r\n storedSyncKeys.push(key);\r\n this.localStorageSetItem(LocalStoreManager.DBKEY_SYNC_KEYS, storedSyncKeys);\r\n }\r\n }\r\n\r\n private removeFromSyncKeysBackup(key: string) {\r\n const storedSyncKeys = this.getSyncKeysFromStorage();\r\n\r\n const index = storedSyncKeys.indexOf(key);\r\n\r\n if (index > -1) {\r\n storedSyncKeys.splice(index, 1);\r\n this.localStorageSetItem(LocalStoreManager.DBKEY_SYNC_KEYS, storedSyncKeys);\r\n }\r\n }\r\n\r\n private addToSyncKeysHelper(key: string) {\r\n if (!this.syncKeysContains(key)) {\r\n this.syncKeys.push(key);\r\n }\r\n }\r\n\r\n private removeFromSyncKeys(key: string) {\r\n this.removeFromSyncKeysHelper(key);\r\n this.removeFromSyncKeysBackup(key);\r\n\r\n localStorage.setItem(\"removeFromSyncKeys\", key);\r\n localStorage.removeItem(\"removeFromSyncKeys\");\r\n }\r\n\r\n private removeFromSyncKeysHelper(key: string) {\r\n const index = this.syncKeys.indexOf(key);\r\n\r\n if (index > -1) {\r\n this.syncKeys.splice(index, 1);\r\n }\r\n }\r\n\r\n private localStorageSetItem(key: string, data: any) {\r\n localStorage.setItem(key, JSON.stringify(data));\r\n }\r\n\r\n private sessionStorageSetItem(key: string, data: any) {\r\n sessionStorage.setItem(key, JSON.stringify(data));\r\n }\r\n\r\n private localStorageGetItem(key: string) {\r\n return Utilities.JsonTryParse(localStorage.getItem(key));\r\n }\r\n\r\n private sessionStorageGetItem(key: string) {\r\n return Utilities.JsonTryParse(sessionStorage.getItem(key));\r\n }\r\n\r\n private onInit() {\r\n setTimeout(() => {\r\n this.initEvent.next();\r\n this.initEvent.complete();\r\n });\r\n }\r\n}\r\n","import { Injectable, OnDestroy } from \"@angular/core\";\r\nimport { ActivatedRoute, Router } from \"@angular/router\";\r\nimport { StepsByStudent, StudentStepsAndProgress } from \"app/models\";\r\nimport { BehaviorSubject, Subject } from \"rxjs\";\r\nimport { takeUntil } from \"rxjs/operators\";\r\n\r\n@Injectable({ providedIn: \"root\" })\r\nexport class NavigationService implements OnDestroy {\r\n private readonly redirectUrlKey = \"redirect-url\";\r\n private onDestroy$ = new Subject();\r\n studentSteps$: BehaviorSubject = new BehaviorSubject(null);\r\n currentStudentStepsAndProgress = this.studentSteps$.asObservable().pipe(takeUntil(this.onDestroy$));\r\n\r\n get redirectUrl() {\r\n return localStorage.getItem(this.redirectUrlKey);\r\n }\r\n set redirectUrl(redirectUrl: string) {\r\n if (!redirectUrl || redirectUrl === \"/\") {\r\n localStorage.removeItem(this.redirectUrlKey);\r\n } else {\r\n localStorage.setItem(this.redirectUrlKey, redirectUrl);\r\n }\r\n }\r\n\r\n constructor(private router: Router, private route: ActivatedRoute) {}\r\n\r\n ngOnDestroy() {\r\n this.onDestroy$.next(true);\r\n this.onDestroy$.complete();\r\n }\r\n\r\n navigateToStep(step: StepsByStudent) {\r\n this.router\r\n .navigateByUrl(\"/student/orientation\", { skipLocationChange: true })\r\n .then(() =>\r\n this.router.navigate([\"student/orientation/\" + step.contentFileName, step.id], { relativeTo: this.route })\r\n );\r\n }\r\n\r\n pushUpdatedStudentStepsAndProgress(studentSteps: StudentStepsAndProgress) {\r\n this.studentSteps$.next(studentSteps);\r\n }\r\n}\r\n","import { HttpClient } from \"@angular/common/http\";\r\nimport { Injectable } from \"@angular/core\";\r\nimport { MatSnackBar } from \"@angular/material/snack-bar\";\r\nimport { Router } from \"@angular/router\";\r\nimport { CommunityPassportForm } from \"@models/community-passport-form.model\";\r\nimport { IntroStep } from \"@models/intro-step.model\";\r\nimport { StepContent } from \"@models/step-content.model\";\r\nimport { Step } from \"@models/step.model\";\r\nimport { StudentSignatureContentModel } from \"@models/student-signature-content.model\";\r\nimport { UserElectiveStep } from \"@models/user-elective-step.model\";\r\nimport {\r\n ConnectionSurveyStep,\r\n OrientationReprt,\r\n Question,\r\n SemesterElective,\r\n SendUsASelfieStep,\r\n StepsByStudent,\r\n StudentStepsAndProgress,\r\n UserAnswers,\r\n UserQuizAnswer,\r\n} from \"app/models\";\r\nimport { Observable } from \"rxjs\";\r\nimport { map, tap } from \"rxjs/operators\";\r\nimport { ApiService, Utility } from \"../shared\";\r\n\r\n@Injectable({ providedIn: \"root\" })\r\nexport class OrientationService extends ApiService {\r\n constructor(http: HttpClient, private snackBar: MatSnackBar, private router: Router) {\r\n super(http, \"orientation\");\r\n }\r\n\r\n getStudentStepsAndProgress(userId: number, date: string | Date = null): Observable {\r\n if (!date) {\r\n date = new Date().toLocaleDateString();\r\n }\r\n\r\n return this.get(\r\n `returnStepsByStudent/${userId}/${Utility.getDateQueryFormat(new Date(date))}`\r\n );\r\n }\r\n\r\n returnSteps(): Observable {\r\n return this.get(`returnSteps`);\r\n }\r\n\r\n returnStepContent(stepId: number): Observable {\r\n return this.get(`returnStepContent/${stepId}`);\r\n }\r\n\r\n returnStudentSignatureContent(\r\n studentId: number,\r\n signatureContentId: number\r\n ): Observable {\r\n return this.get(`returnStudentSignatureContent/${studentId}/${signatureContentId}`);\r\n }\r\n\r\n returnQuizContent(quizContentId: number, userId: number = null): Observable {\r\n return this.get(`returnQuizContent/${quizContentId}/${userId || \"\"}`);\r\n }\r\n\r\n returnCommunityPassportForms() {\r\n return this.get(\"returnCommunityPassportForms\");\r\n }\r\n\r\n returnCommunityPassportFormByGradeLevel(gradeLevel: string) {\r\n return this.get(`returnCommunityPassportFormByGradeLevel/${gradeLevel}`);\r\n }\r\n\r\n createStep(step: Partial): Observable {\r\n return this.post(`createStep`, step);\r\n }\r\n\r\n updateStep(step: Step): Observable {\r\n return this.put(`updateStep`, step);\r\n }\r\n\r\n deleteStep(step: Step): Observable {\r\n return this.delete(`deleteStep/${step.id}`);\r\n }\r\n\r\n updateStepOrder(steps: Step[]): Observable {\r\n return this.put(`updateStepOrder`, steps);\r\n }\r\n\r\n updateStudentSignatureContent(item: StudentSignatureContentModel): Observable {\r\n return this.post(\"updateStudentSignatureContent\", item);\r\n }\r\n\r\n duplicateStep(id: number): Observable {\r\n return this.post(`duplicateStep/${id}`);\r\n }\r\n\r\n resetStudentOrientation(): Observable {\r\n return this.post(`resetStudentOrientation`);\r\n }\r\n\r\n /* #region Http Gets */\r\n\r\n getStepIntro(userId: number): Observable {\r\n return this.get(`returnStepIntro/${userId}`);\r\n }\r\n\r\n getStepConnectionSurveyData(userId: number): Observable {\r\n return this.get(`returnStepConnectionSurveyData/${userId}`);\r\n }\r\n\r\n getUserQuizAnswers(userId: number, stepId: number): Observable {\r\n return this.get(`returnUserQuizAnswers/${userId}/${stepId}`);\r\n }\r\n\r\n returnElectives(userId: number, semester: 1 | 2, schoolYear: number): Observable {\r\n return this.get(`returnElectives/${userId}/${semester}/${schoolYear}`);\r\n }\r\n\r\n getOrientationReportData(year: number): Observable {\r\n return this.get(`returnOrientationReportData/${year}`);\r\n }\r\n\r\n getStepSendUsASelfieData(userId: number): Observable {\r\n return this.get(`returnStepSendUsASelfieData/${userId}`);\r\n }\r\n\r\n /* #endregion */\r\n\r\n /* #region Http Posts */\r\n\r\n completeStep(userId: number, stepId: number, stayOnStepAfterComplete?: boolean): Observable {\r\n const item = { userId: userId, stepId: stepId };\r\n return this.post(`completeStep/`, item).pipe(\r\n map((step: StepsByStudent) => {\r\n if (step) {\r\n this.snackBar.open(\"Step Completed Successfully\", \"Close\", { panelClass: \"success\", duration: 3500 });\r\n }\r\n return step;\r\n }),\r\n tap((step: StepsByStudent) => {\r\n if (step === null) {\r\n this.snackBar.open(\"Congratulations! You have finished your iCademy Orientation\", \"Close\", {\r\n panelClass: \"success\",\r\n duration: 3500,\r\n });\r\n if (stayOnStepAfterComplete !== true) {\r\n this.router.navigateByUrl(\"/student/dashboard\");\r\n }\r\n }\r\n })\r\n );\r\n }\r\n\r\n skipHand2HandStep(userId: number): Observable {\r\n return this.post(`Skip_Hand2HandStep`, userId);\r\n }\r\n\r\n submitConnectionSurveyStep(item: ConnectionSurveyStep): Observable {\r\n item.zipCode = item.zipCode?.toString(); // make sure this is converted to a string\r\n return this.post(`Submit_ConnectionSurveyStep`, item);\r\n }\r\n\r\n startOrientation(userId: number): Observable {\r\n return this.post(`StartOrientation/${userId}`);\r\n }\r\n\r\n submitUserQuizAnswers(item: UserAnswers): Observable {\r\n return this.post(`Submit_UserAnswers`, item);\r\n }\r\n\r\n generateEmailVerificationCode(userId: number): Observable {\r\n return this.post(`Step_EmailVerification_ReturnCode/${userId}`);\r\n }\r\n\r\n submitVerificationCode(userId: number, verificationCode: string, codeIsCorrect: boolean): Observable {\r\n const item = { userId: userId, verificationCode: verificationCode, codeIsCorrect: codeIsCorrect };\r\n return this.post(`Step_EmailVerification_VerifyCode`, item);\r\n }\r\n\r\n submitUserElectivesStep(item: UserElectiveStep): Observable {\r\n return this.post(`Submit_UserElectivesStep`, item);\r\n }\r\n\r\n submitSendUsASelfieStep(item: SendUsASelfieStep): Observable {\r\n return this.post(`Submit_SendUsASelfieStep`, item);\r\n }\r\n\r\n /* #endregion */\r\n}\r\n","import { HttpClient, HttpHeaders, HttpResponse } from \"@angular/common/http\";\r\nimport { inject } from \"@angular/core\";\r\nimport { AuthService } from \"@services/auth/auth.service\";\r\nimport { UserDtoInterface } from \"app/modules/account/models/user-dto.model\";\r\nimport { environment } from \"environments/environment\";\r\nimport { Observable, throwError } from \"rxjs\";\r\nimport { catchError, map } from \"rxjs/operators\";\r\n\r\nexport abstract class ApiService {\r\n protected apiUrl = environment.apiUrl + \"/\";\r\n protected headers = this.buildStandardHeaders();\r\n\r\n private authService = inject(AuthService);\r\n\r\n get user(): UserDtoInterface {\r\n return this.authService.currentUser;\r\n }\r\n\r\n constructor(protected http: HttpClient, controllerUrlPrefix?: string) {\r\n if (controllerUrlPrefix) {\r\n this.apiUrl += controllerUrlPrefix.startsWith(\"/\") ? controllerUrlPrefix.substring(1) : controllerUrlPrefix;\r\n\r\n if (!this.apiUrl.endsWith(\"/\")) {\r\n this.apiUrl += \"/\";\r\n }\r\n }\r\n }\r\n\r\n protected get(url: string, headers?: { [name: string]: string }): Observable {\r\n return this.http\r\n .get(this.format(url), { headers: this.buildStandardHeaders(headers), observe: \"response\" })\r\n .pipe(map(this.parseResponse))\r\n .pipe(catchError(error => throwError(error)));\r\n }\r\n\r\n protected post(\r\n url: string,\r\n item = null,\r\n http: HttpClient = null,\r\n headers: { [name: string]: string } = null\r\n ): Observable {\r\n if (item instanceof File) {\r\n return this.postFile(url, item, http);\r\n }\r\n\r\n return (http || this.http)\r\n .post(this.format(url), item, { headers: this.buildStandardHeaders(headers), observe: \"response\" })\r\n .pipe(map(this.parseResponse))\r\n .pipe(catchError(error => throwError(error)));\r\n }\r\n\r\n private postFile(url: string, file: File, http?: HttpClient): Observable {\r\n const formData = new FormData();\r\n formData.append(\"file\", file, file.name);\r\n return this.post(url, formData, http, { \"Content-Type\": \"\" });\r\n }\r\n\r\n protected put(url: string, item = null, headers: { [name: string]: string } = null): Observable {\r\n if (item instanceof File) {\r\n return this.putFile(url, item);\r\n }\r\n\r\n return this.http\r\n .put(this.format(url), item, { headers: this.buildStandardHeaders(headers), observe: \"response\" })\r\n .pipe(map(this.parseResponse))\r\n .pipe(catchError(error => throwError(error)));\r\n }\r\n\r\n private putFile(url: string, file: File): Observable {\r\n const formData = new FormData();\r\n formData.append(\"file\", file, file.name);\r\n return this.put(url, formData, { \"Content-Type\": \"\" });\r\n }\r\n\r\n protected delete(url: string, headers?: { [name: string]: string }): Observable {\r\n return this.http\r\n .delete(this.format(url), { headers: this.buildStandardHeaders(headers), observe: \"response\" })\r\n .pipe(map(this.parseResponse))\r\n .pipe(catchError(error => throwError(error)));\r\n }\r\n\r\n protected buildStandardHeaders(headers?: { [name: string]: string }) {\r\n const httpHeaders = {\r\n \"Content-Type\": \"application/json; charset=utf-8;\",\r\n Accept: \"*/*\",\r\n TimezoneOffset: new Date().getTimezoneOffset().toString(),\r\n };\r\n\r\n if (!headers) {\r\n headers = {};\r\n }\r\n\r\n Object.keys(headers).forEach(key => {\r\n if (!headers[key]) {\r\n delete httpHeaders[key];\r\n }\r\n });\r\n\r\n return new HttpHeaders(httpHeaders);\r\n }\r\n\r\n private format(url: string) {\r\n return this.apiUrl + (url.startsWith(\"/\") ? url.substring(1) : url);\r\n }\r\n\r\n private parseResponse(response: HttpResponse): T {\r\n return response.body;\r\n }\r\n}\r\n","export abstract class Constants {\r\n static readonly loginTypeKey: string = \"login-type\";\r\n static readonly loginProvider: string = \"login-provider\"; // \"Google\"|\"Microsoft\"\r\n\r\n // base paths\r\n static readonly studentPath: string = \"/student\";\r\n static readonly staffPath: string = \"/staff\";\r\n\r\n // admin paths\r\n static readonly adminPath: string = Constants.staffPath + \"/admin\";\r\n static readonly breaksPath: string = Constants.adminPath + \"/breaks\";\r\n static readonly breaksLabel: string = \"School Breaks\";\r\n static readonly enrollmentImportPath: string = Constants.adminPath + \"/enrollment-import\";\r\n static readonly enrollmentImportLabel: string = \"Student Enrollment Import\";\r\n static readonly interventionThresholdsPath: string = Constants.adminPath + \"/intervention-thresholds\";\r\n static readonly interventionThresholdsLabel: string = \"Intervention Thresholds\";\r\n static readonly manageStaffPath: string = Constants.adminPath + \"/manage-staff\";\r\n static readonly manageStaffLabel: string = \"Staff\";\r\n static readonly manageOrientationPath: string = Constants.staffPath + \"/manage-orientation\";\r\n static readonly manageOrientationLabel: string = \"Slides\";\r\n static readonly manageStudentsPath: string = Constants.adminPath + \"/manage-students\";\r\n static readonly manageStudentsLabel: string = \"Students\";\r\n static readonly manageStudentResourcesPath: string = Constants.adminPath + \"/manage-student-resources\";\r\n static readonly manageStudentResourcesLabel: string = \"Student Resources\";\r\n static readonly appShortcutsPath: string = Constants.adminPath + \"/app-shortcuts\";\r\n static readonly appShortcutsLabel: string = \"App Shortcuts\";\r\n static readonly manageElectivesPath: string = Constants.adminPath + \"/manage-electives\";\r\n static readonly manageElectivesLabel: string = \"Electives\";\r\n\r\n // staff paths\r\n static readonly studentsPath: string = Constants.staffPath + \"/students\";\r\n static readonly studentsLabel: string = \"Students\";\r\n static readonly quotesPath: string = Constants.staffPath + \"/quotes\";\r\n static readonly quotesLabel: string = \"Quote of the Day\";\r\n static readonly communicationPath: string = Constants.staffPath + \"/communication\";\r\n static readonly communicationLabel: string = \"Emailing\";\r\n\r\n // mentor paths\r\n static readonly mentorPath: string = Constants.staffPath + \"/mentor\";\r\n static readonly studentListPath: string = Constants.mentorPath + \"/student-list\";\r\n static readonly studentListLabel: string = \"Orientation Progress\";\r\n\r\n // report paths\r\n static readonly reportsPath: string = Constants.staffPath + \"/reports\";\r\n static readonly engagementReportPath: string = Constants.reportsPath + \"/engagement-report\";\r\n static readonly engagmentReportLabel: string = \"Engagement Report\";\r\n static readonly enrollmentReportPath: string = Constants.reportsPath + \"/attendance-report\";\r\n static readonly enrollmentReportLabel: string = \"Attendance Report\";\r\n static readonly orientationReportPath: string = Constants.reportsPath + \"/orientation-report\";\r\n static readonly orientationReportLabel: string = \"Student Orientation Report\";\r\n static readonly studentPictureExportReportPath: string = Constants.reportsPath + \"/student-picture-report\";\r\n static readonly studentPictureExportReportLabel: string = \"Student Picture Export\";\r\n static readonly pbisDashboardPath: string = Constants.reportsPath + \"/pbis-dashboard\";\r\n static readonly pbisDashboardLabel: string = \"PBIS Dashboard\";\r\n\r\n // teacher paths\r\n static readonly teacherPath: string = Constants.staffPath + \"/teacher\";\r\n static readonly liveLessonsPath: string = Constants.teacherPath + \"/live-lessons\";\r\n static readonly liveLessonsLabel: string = \"Live Lessons\";\r\n\r\n // RE:Fuel Coordinator paths\r\n static readonly reFuelCoordinatorPath: string = Constants.staffPath + \"/re-fuel\";\r\n static readonly reFuelPath: string = Constants.reFuelCoordinatorPath;\r\n static readonly reFuelLabel: string = \"RE:Fuel\";\r\n\r\n // student paths\r\n static readonly dashboardPath: string = Constants.studentPath + \"/dashboard\";\r\n static readonly orientationPath: string = Constants.studentPath + \"/orientation\";\r\n\r\n // intervention paths\r\n static readonly interventionsPath: string = Constants.staffPath + \"/interventions\";\r\n static readonly interventionsStudentLabel: string = \"Student\";\r\n static readonly interventionsStudentPath: string = Constants.interventionsPath + \"/student\";\r\n static readonly interventionsReportLabel: string = \"Report\";\r\n static readonly interventionsReportPath: string = Constants.interventionsPath + \"/report\";\r\n static readonly interventionsEmailTemplatesLabel: string = \"Email Templates\";\r\n static readonly interventionsEmailTemplatesPath: string = Constants.interventionsPath + \"/email-templates\";\r\n\r\n //GradeLevelSelector arrays\r\n static readonly grades: string[] = [\"K\", \"1\", \"2\", \"3\", \"4\", \"5\", \"6\", \"7\", \"8\", \"9\", \"10\", \"11\", \"12\"];\r\n static readonly gradesK5: string[] = [\"K\", \"1\", \"2\", \"3\", \"4\", \"5\"];\r\n static readonly grades68: string[] = [\"6\", \"7\", \"8\"];\r\n static readonly grades912: string[] = [\"9\", \"10\", \"11\", \"12\"];\r\n\r\n static readonly youtubeUrlPrefix = \"https://www.youtube.com/watch?v=\";\r\n}\r\n","import { Validators } from \"@angular/forms\";\r\nimport { Tab, User } from \"app/models\";\r\nimport { Constants } from \"./constants\";\r\n\r\nexport abstract class Utility {\r\n static urlValidator = Validators.pattern(\r\n /^[A-Za-z][A-Za-z\\d.+-]*:\\/*(?:\\w+(?::\\w+)?@)?[^\\s/]+(?::\\d+)?(?:\\/[\\w#!:.?+=&%@\\-/]*)?$/\r\n );\r\n static orientationModuleIsLoaded = false;\r\n\r\n /**\r\n * Takes an HTML string and cleans it for an email.\r\n * 1. Adds https:// to each href attribute that does not start with http:/ or https:/\r\n * 2. Removes any white-space: pre styles (causes rendering issue in email clients)\r\n */\r\n static cleanAngularEditorHtml(html: string): string {\r\n return html\r\n ?.replace(/(?<=href=(\"|'))(?!http)[a-zA-Z\\.]+/gi, \"https://$&\") // clean hrefs\r\n ?.replace(/white-space:\\s?pre/gi, \"\"); // clean white-space: pre styles\r\n }\r\n\r\n static setUniqueFileName(files: { name: string }[], file: File, iteration = 0) {\r\n const name = iteration ? `${file.name} (${iteration})` : file.name;\r\n\r\n if (files.some(f => f.name === name)) {\r\n return this.setUniqueFileName(files, file, ++iteration);\r\n }\r\n\r\n Object.defineProperty(file, \"name\", {\r\n writable: true,\r\n value: name,\r\n });\r\n }\r\n\r\n static getBeginningOfWeek(): Date {\r\n // Monday at Midnight is the beginning of the week\r\n const date = this.getEasternTime();\r\n date.setDate(date.getDate() - 1); // subtract 1 in case it is Sunday, we want to get the previous Monday not the next Monday\r\n date.setDate(date.getDate() - date.getDay() + 1); // subtract the day of the week - gets us to current / prev sunday - add 1 gets us to monday\r\n date.setHours(0);\r\n date.setMinutes(0);\r\n date.setSeconds(0);\r\n date.setMilliseconds(0);\r\n return date;\r\n }\r\n\r\n static getEndOfWeek(): Date {\r\n const date = this.getBeginningOfWeek();\r\n date.setDate(date.getDate() + 7);\r\n return date;\r\n }\r\n\r\n static getFridayAtNoon(): Date {\r\n const date = this.getEasternTime();\r\n\r\n // if today is not friday after noon, calculate the nearest past friday\r\n if (!(date.getDay() === 5 && date.getHours() >= 12)) {\r\n const diff = date.getDay() <= 5 ? 7 - 5 + date.getDay() : date.getDay() - 5;\r\n date.setDate(date.getDate() - diff);\r\n }\r\n\r\n // return date (friday) at noon\r\n return new Date(date.getFullYear(), date.getMonth(), date.getDate(), 12);\r\n }\r\n\r\n static getBeginningOfSchoolYear(): Date {\r\n const now = this.getEasternTime();\r\n return new Date(now.getFullYear() - (now.getMonth() >= 6 ? 0 : 1), 6, 1);\r\n }\r\n\r\n static getEasternTime(date?: Date): Date {\r\n if (!date) {\r\n date = new Date();\r\n }\r\n\r\n return new Date(date.toLocaleString(\"en-US\", { timeZone: \"America/New_York\" }));\r\n }\r\n\r\n static buildGradeLevelString(records: string[]): string {\r\n let outputString = \"\";\r\n records = [...new Set(records)];\r\n\r\n if (records?.length) {\r\n if (records.length === 13) {\r\n return \"K-12\";\r\n } else if (records.length > 0) {\r\n records = records.sort((a, b) => Number(a) - Number(b));\r\n if (records[records.length - 1] === \"K\") {\r\n records.unshift(records.pop());\r\n }\r\n\r\n let start, end; // track start and end\r\n end = start = records[0];\r\n for (let j = 1; j < records.length; j++) {\r\n // as long as entries are consecutive, move end forward\r\n let lastGradeLevel = records[j - 1] === \"K\" ? 0 : +records[j - 1];\r\n let currentGradeLevel = records[j] === \"K\" ? 0 : +records[j];\r\n\r\n if (currentGradeLevel == lastGradeLevel + 1) {\r\n end = records[j];\r\n } else {\r\n // when no longer consecutive, add group to result\r\n // depending on whether start=end (single item) or not\r\n let startGradeLevel = start === \"K\" ? 0 : +start;\r\n let endGradeLevel = end === \"K\" ? 0 : +end;\r\n\r\n if (startGradeLevel == endGradeLevel) outputString += start + \",\";\r\n else if (endGradeLevel == startGradeLevel + 1) outputString += start + \",\" + end + \",\";\r\n else outputString += start + \"-\" + end + \",\";\r\n\r\n start = end = records[j];\r\n }\r\n }\r\n\r\n // handle the final group\r\n if (start == end) outputString += start;\r\n else outputString += start + \"-\" + end;\r\n }\r\n\r\n return outputString;\r\n }\r\n }\r\n\r\n static getDateQueryFormat(date?: Date): string {\r\n if (!date) {\r\n date = new Date();\r\n }\r\n return date.getFullYear() + \"-\" + (date.getMonth() + 1) + \"-\" + date.getDate();\r\n }\r\n\r\n static toTimeFormat(totalSeconds: number) {\r\n if (!totalSeconds || totalSeconds < 60) {\r\n return \"-\";\r\n }\r\n\r\n const minutes = Math.floor(totalSeconds / 60) % 60;\r\n const hours = Math.floor(totalSeconds / 3600) % 24;\r\n const days = Math.floor(totalSeconds / 86400);\r\n\r\n const timeFormatBuilder = [];\r\n if (days) {\r\n timeFormatBuilder.push(`${days}d`);\r\n }\r\n if (hours) {\r\n timeFormatBuilder.push(`${hours}h`);\r\n }\r\n if (minutes) {\r\n timeFormatBuilder.push(`${minutes}m`);\r\n }\r\n\r\n return timeFormatBuilder.join(\" \");\r\n }\r\n\r\n static setFavicon(loginType: number | string, document: HTMLDocument) {\r\n if (loginType) {\r\n if (Number(loginType) === 1) {\r\n document.getElementById(\"app-favicon\").setAttribute(\"href\", \"/assets/k-5-favicon.ico\");\r\n } else {\r\n document.getElementById(\"app-favicon\").setAttribute(\"href\", \"/assets/favicon.ico\");\r\n }\r\n }\r\n }\r\n\r\n static emailAddressIsValid(email: string) {\r\n const re =\r\n /^(([^<>()[\\]\\\\.,;:\\s@\"]+(\\.[^<>()[\\]\\\\.,;:\\s@\"]+)*)|(\".+\"))@((\\[[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\])|(([a-zA-Z\\-0-9]+\\.)+[a-zA-Z]{2,}))$/;\r\n return !!email && re.test(String(email).toLowerCase());\r\n }\r\n\r\n static getNavigationTabs(user: User): Tab[] {\r\n return [\r\n Utility.getAdminNavigationTab(user),\r\n Utility.getReportsNavigationTab(user),\r\n Utility.getStaffNavigationTab(user),\r\n Utility.getTeacherNavigationTab(user),\r\n Utility.getCommunicationNavigationTab(user),\r\n Utility.getInterventionNavigationTab(user),\r\n ].filter(tab => tab !== null);\r\n }\r\n\r\n static getAdminNavigationTab(user: User): Tab {\r\n const adminTab = this.createDropdownTab(\"Admin\");\r\n\r\n if (user.isAdmin) {\r\n const engagementSubmenu = this.createDropdownTab(\"Engagement\");\r\n engagementSubmenu.tabs.push(\r\n this.createRouterTab(Constants.interventionThresholdsLabel, Constants.interventionThresholdsPath)\r\n );\r\n engagementSubmenu.tabs.push(this.createRouterTab(Constants.breaksLabel, Constants.breaksPath));\r\n adminTab.tabs.push(engagementSubmenu);\r\n\r\n const orientationSubmenu = this.createDropdownTab(\"Orientation\");\r\n orientationSubmenu.tabs.push(this.createRouterTab(Constants.manageElectivesLabel, Constants.manageElectivesPath));\r\n orientationSubmenu.tabs.push(\r\n this.createRouterTab(Constants.manageOrientationLabel, Constants.manageOrientationPath)\r\n );\r\n adminTab.tabs.push(orientationSubmenu);\r\n }\r\n\r\n const signupsSubmenu = this.createDropdownTab(\"Signups\");\r\n signupsSubmenu.tabs.push(this.createRouterTab(Constants.reFuelLabel, Constants.reFuelPath)); // available to all staff\r\n adminTab.tabs.push(signupsSubmenu);\r\n\r\n const studentDashboardSubmenu = this.createDropdownTab(\"Student Dashboard\");\r\n if (user.isAdmin) {\r\n studentDashboardSubmenu.tabs.push(this.createRouterTab(Constants.appShortcutsLabel, Constants.appShortcutsPath));\r\n }\r\n studentDashboardSubmenu.tabs.push(this.createRouterTab(Constants.quotesLabel, Constants.quotesPath)); // available to all staff\r\n if (user.isAdmin) {\r\n studentDashboardSubmenu.tabs.push(\r\n this.createRouterTab(Constants.manageStudentResourcesLabel, Constants.manageStudentResourcesPath)\r\n );\r\n }\r\n adminTab.tabs.push(studentDashboardSubmenu);\r\n\r\n if (user.isAdmin) {\r\n const userSettingsSubmenu = this.createDropdownTab(\"User Settings\");\r\n userSettingsSubmenu.tabs.push(this.createRouterTab(Constants.manageStaffLabel, Constants.manageStaffPath));\r\n userSettingsSubmenu.tabs.push(this.createRouterTab(Constants.manageStudentsLabel, Constants.manageStudentsPath));\r\n userSettingsSubmenu.tabs.push(\r\n this.createRouterTab(Constants.enrollmentImportLabel, Constants.enrollmentImportPath)\r\n );\r\n adminTab.tabs.push(userSettingsSubmenu);\r\n }\r\n\r\n return adminTab;\r\n }\r\n\r\n static getReportsNavigationTab(user: User): Tab {\r\n const reportsTab = this.createDropdownTab(\"Reports\");\r\n reportsTab.tabs.push(this.createRouterTab(Constants.engagmentReportLabel, Constants.engagementReportPath));\r\n reportsTab.tabs.push(this.createRouterTab(Constants.enrollmentReportLabel, Constants.enrollmentReportPath));\r\n reportsTab.tabs.push(\r\n this.createRouterTab(Constants.studentPictureExportReportLabel, Constants.studentPictureExportReportPath)\r\n );\r\n if (user.isMentor) {\r\n reportsTab.tabs.push(this.createRouterTab(Constants.studentListLabel, Constants.studentListPath));\r\n }\r\n if (user.isMentor || user.isAdmin) {\r\n reportsTab.tabs.push(this.createRouterTab(Constants.orientationReportLabel, Constants.orientationReportPath));\r\n }\r\n\r\n reportsTab.tabs.push(this.createRouterTab(Constants.pbisDashboardLabel, Constants.pbisDashboardPath));\r\n\r\n return reportsTab;\r\n }\r\n\r\n static getStaffNavigationTab(user: User): Tab {\r\n return user.isStaff ? this.createRouterTab(Constants.studentsLabel, Constants.studentsPath) : null;\r\n }\r\n\r\n static getTeacherNavigationTab(user: User): Tab {\r\n return user.isTeacher || user.isAdmin\r\n ? this.createRouterTab(Constants.liveLessonsLabel, Constants.liveLessonsPath)\r\n : null;\r\n }\r\n\r\n static getCommunicationNavigationTab(user: User): Tab {\r\n return user.isStaff ? this.createRouterTab(Constants.communicationLabel, Constants.communicationPath) : null;\r\n }\r\n\r\n static getInterventionNavigationTab(user: User): Tab {\r\n if (!user.isStaff) {\r\n return null;\r\n }\r\n\r\n const interventionsTab = this.createDropdownTab(\"Interventions\");\r\n interventionsTab.tabs.push(\r\n this.createRouterTab(Constants.interventionsStudentLabel, Constants.interventionsStudentPath)\r\n );\r\n interventionsTab.tabs.push(\r\n this.createRouterTab(Constants.interventionsReportLabel, Constants.interventionsReportPath)\r\n );\r\n\r\n if (user.isInterventionist || user.isAdmin) {\r\n interventionsTab.tabs.push(\r\n this.createRouterTab(Constants.interventionsEmailTemplatesLabel, Constants.interventionsEmailTemplatesPath)\r\n );\r\n }\r\n return interventionsTab;\r\n }\r\n\r\n private static createDropdownTab(label: string): Tab {\r\n return { label, tabs: [] };\r\n }\r\n\r\n private static createRouterTab(label: string, path: string): Tab {\r\n const formattedPathParts = path.split(\"/\").filter(value => !!value);\r\n formattedPathParts.unshift(\"..\");\r\n return { routerPath: formattedPathParts.join(\"/\"), path, label };\r\n }\r\n}\r\n","import { IConfig, IConfiguration } from \"@microsoft/applicationinsights-web\";\r\nimport { AppEnvironment } from \"../app/enums/repository/app-environment.enum\";\r\n\r\nexport abstract class IEnvironment {\r\n configuration: AppEnvironment;\r\n baseUrl: string;\r\n apiUrl: string;\r\n cacheLocation: string;\r\n expireOffsetSeconds: number;\r\n inboxUrl: string;\r\n microsoftInboxUrl: string; // todo: remove this once iCademy fully transitions to Google\r\n chatUrl: string;\r\n storageUrl: string;\r\n appInsightsConfiguration: IConfiguration & IConfig;\r\n}\r\n\r\nexport const defaultEnvironment: IEnvironment = {\r\n configuration: AppEnvironment.Development,\r\n baseUrl: null, // Change this to the address of your backend API if different from frontend address\r\n apiUrl: \"/api\",\r\n cacheLocation: \"localStorage\",\r\n expireOffsetSeconds: 600,\r\n inboxUrl: \"https://gmail.com\",\r\n microsoftInboxUrl: \"https://outlook.office.com/mail/inbox\",\r\n chatUrl: \"https://chat.google.com\",\r\n storageUrl: \"https://icademyportaldev.blob.core.windows.net/public\",\r\n appInsightsConfiguration: {\r\n connectionString:\r\n \"InstrumentationKey=4634f8a2-a593-49ee-88ff-917dac49a037;IngestionEndpoint=https://eastus-2.in.applicationinsights.azure.com/;LiveEndpoint=https://eastus.livediagnostics.monitor.azure.com/\",\r\n enableAutoRouteTracking: true,\r\n },\r\n};\r\n","import { AppEnvironment } from \"app/enums/repository/app-environment.enum\";\r\nimport { IEnvironment, defaultEnvironment } from \"./environment.definition\";\r\n\r\nexport const environment: IEnvironment = Object.assign(defaultEnvironment, {\r\n configuration: AppEnvironment.Testing,\r\n});\r\n","import { Injectable } from \"@angular/core\";\r\nimport { Subject } from \"rxjs\";\r\n\r\n@Injectable({\r\n providedIn: \"root\",\r\n})\r\nexport class GlobalLoadingIndicatorService {\r\n private eventCount = 0;\r\n private suppressNextEventCount = 0;\r\n\r\n private isLoading = new Subject();\r\n\r\n /** Triggered when the global loading indicator should start (when at least one event has started) and when it should end (when all events have ended) */\r\n isLoading$ = this.isLoading.asObservable();\r\n\r\n /**\r\n * Adds a loading event to the service. Call end() only if this returns a value of true.\r\n * Triggers isLoading with value true if this is the only event running.\r\n */\r\n startEvent() {\r\n if (this.suppressNextEventCount > 0) {\r\n // caller asked to bypass the next loading event. Decrement the value and return.\r\n this.suppressNextEventCount--;\r\n return false;\r\n }\r\n\r\n if (this.eventCount++ === 0) {\r\n this.isLoading.next(true);\r\n }\r\n\r\n return true;\r\n }\r\n\r\n /**\r\n * Removes a loading event from the service.\r\n * Triggers isLoading with value false if the last event running.\r\n * Optional flag to provide the result of startEvent() in uncontrolled situations, such as the API interceptor.\r\n */\r\n endEvent(eventRunning: boolean = true) {\r\n if (eventRunning) {\r\n this.eventCount = Math.max(0, this.eventCount - 1);\r\n\r\n if (this.eventCount === 0) {\r\n this.isLoading.next(false);\r\n }\r\n }\r\n }\r\n\r\n /** Simple way to virtually \"ignore\" the next startEvent(), so that it takes at least one more to trigger the global loading indicator. */\r\n suppressNextEvent() {\r\n this.suppressNextEventCount++;\r\n }\r\n}\r\n","import { HttpEvent, HttpHandler, HttpInterceptor, HttpRequest, HttpResponse } from \"@angular/common/http\";\r\nimport { Injectable } from \"@angular/core\";\r\nimport { Constants } from \"app/shared\";\r\nimport { Observable, throwError } from \"rxjs\";\r\nimport { catchError, finalize, map } from \"rxjs/operators\";\r\nimport { GlobalLoadingIndicatorService } from \"../global-loading-indicator.service\";\r\n\r\n@Injectable({\r\n providedIn: \"root\",\r\n})\r\nexport class ApiHttpInterceptor implements HttpInterceptor {\r\n private isoDateFormat = /^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}(?:\\.\\d*)?Z$/;\r\n\r\n constructor(private globalLoadingIndicatorService: GlobalLoadingIndicatorService) {}\r\n\r\n intercept(request: HttpRequest, next: HttpHandler): Observable> {\r\n if (!(request.body instanceof FormData)) {\r\n request = this.setHeaders(request);\r\n }\r\n\r\n // todo: this can be removed once iCademy fully transitions to Google\r\n request = request.clone({\r\n headers: request.headers.set(\"Login-Provider\", localStorage.getItem(Constants.loginProvider)),\r\n });\r\n\r\n const loadingEventRunning = this.globalLoadingIndicatorService.startEvent();\r\n\r\n return next.handle(request).pipe(\r\n map((event: HttpEvent) => {\r\n if (event instanceof HttpResponse) {\r\n this.convert(event.body, false);\r\n }\r\n\r\n return event;\r\n }),\r\n catchError(err => throwError(err)),\r\n finalize(() => this.globalLoadingIndicatorService.endEvent(loadingEventRunning))\r\n );\r\n }\r\n\r\n private setHeaders(request: HttpRequest) {\r\n return request.clone({\r\n setHeaders: {\r\n \"Content-Type\": \"application/json\",\r\n Accept: \"application/json, text/plain, */*\",\r\n },\r\n body: this.convert(request.body, true),\r\n });\r\n }\r\n\r\n private convert(body: any, isRequest: boolean) {\r\n if (body === null || body === undefined || body instanceof Date || typeof body !== \"object\") {\r\n return body;\r\n }\r\n\r\n if (Array.isArray(body)) {\r\n return body.map(item => this.convert(item, isRequest));\r\n }\r\n\r\n if (isRequest) {\r\n // clone the object so we don't mutate the caller's object\r\n body = Object.assign({}, body);\r\n }\r\n\r\n for (const key of Object.keys(body)) {\r\n const value = body[key];\r\n if (this.isIsoDateString(value) && !isRequest) {\r\n // don't convert UTC dates to local time for iCademy backwards compatibility\r\n body[key] = new Date(value.replace(\"Z\", \"\"));\r\n } else if (value instanceof Set) {\r\n // convert sets into arrays so that they get serialized as an array with values instead of as empty object\r\n body[key] = this.convert([...value], isRequest);\r\n } else if (typeof value === \"object\") {\r\n body[key] = this.convert(value, isRequest);\r\n }\r\n }\r\n\r\n return body;\r\n }\r\n\r\n private isIsoDateString(value: any): boolean {\r\n if (value === null || value === undefined) {\r\n return false;\r\n }\r\n\r\n return typeof value === \"string\" && this.isoDateFormat.test(value);\r\n }\r\n}\r\n","import { Component, NgZone, OnInit } from \"@angular/core\";\r\nimport { MatSnackBar } from \"@angular/material/snack-bar\";\r\nimport { Router } from \"@angular/router\";\r\nimport { AuthService } from \"@services/auth/auth.service\";\r\nimport { AuthorizationService } from \"@services/authorization.service\";\r\nimport { CommonService } from \"@services/common.service\";\r\nimport { NavigationService } from \"@services/navigation.service\";\r\nimport { OrientationService } from \"@services/orientation.service\";\r\nimport { Constants } from \"../../shared\";\r\n\r\n@Component({\r\n selector: \"app-auth-callback\",\r\n templateUrl: \"./auth-callback.component.html\",\r\n styleUrls: [\"./auth-callback.component.scss\"],\r\n})\r\nexport class AuthCallbackComponent implements OnInit {\r\n constructor(\r\n private router: Router,\r\n private authService: AuthService,\r\n private _zone: NgZone,\r\n private authorizationService: AuthorizationService,\r\n private orientationService: OrientationService,\r\n private commonService: CommonService,\r\n private snackBar: MatSnackBar,\r\n private navigationService: NavigationService\r\n ) {}\r\n\r\n ngOnInit() {\r\n this.authService.refreshUser().subscribe(\r\n () => {\r\n const result = this.authService.currentUser;\r\n if (result && !this.commonService.isEmpty(result)) {\r\n if (result.id) {\r\n if (result.isStaff) {\r\n this.router.navigateByUrl(this.navigationService.redirectUrl || Constants.studentsPath);\r\n } else {\r\n this.orientationService.getStudentStepsAndProgress(result.userId).subscribe(data => {\r\n const completedSteps = data.studentProgress.completedSteps;\r\n const totalSteps = data.studentProgress.totalSteps;\r\n const hasCompletedAllSteps = completedSteps === totalSteps && totalSteps > 0;\r\n\r\n if (hasCompletedAllSteps) {\r\n this.router.navigateByUrl(this.navigationService.redirectUrl || Constants.dashboardPath);\r\n } else {\r\n this.router.navigateByUrl(Constants.orientationPath);\r\n }\r\n });\r\n }\r\n this.navigationService.redirectUrl = null;\r\n } else {\r\n this.snackBar.open(\r\n \"No user account with the provided username and password was found. Please reach out to support@icademyglobal.org or contact your mentor if you need access or think this is a mistake.\",\r\n \"Dismiss\",\r\n {\r\n duration: 6000,\r\n }\r\n );\r\n setTimeout(() => {\r\n this._zone.run(() => this.router.navigateByUrl(\"/not-authorized\"));\r\n }, 200);\r\n }\r\n }\r\n },\r\n err => {\r\n console.log(err);\r\n this.snackBar\r\n .open(`There was a problem signing you into the portal with the provided username.`, \"Dismiss\")\r\n .afterDismissed()\r\n .subscribe(() => this._zone.run(() => this.router.navigateByUrl(\"/not-authorized\")));\r\n }\r\n );\r\n }\r\n}\r\n","\r\n","import { Component } from \"@angular/core\";\r\nimport { ActivatedRoute } from \"@angular/router\";\r\n\r\n@Component({\r\n selector: \"app-email-opt-out\",\r\n templateUrl: \"./email-opt-out.component.html\",\r\n styleUrls: [\"./email-opt-out.component.scss\"],\r\n})\r\nexport class EmailOptOutComponent {\r\n userUnsubscribed = false;\r\n userUnsubscribing = false;\r\n userUnsubscribedResult = false;\r\n studentGoogleId = \"\";\r\n\r\n constructor(private route: ActivatedRoute) {\r\n this.studentGoogleId = this.route.snapshot.params.studentGoogleId;\r\n if (!this.studentGoogleId) {\r\n location.href = \"/\";\r\n }\r\n }\r\n\r\n goHome() {\r\n location.href = \"/\";\r\n }\r\n}\r\n","\r\n\r\n
\r\n

Please contact an administrator to unsubscribe you from the weekly snapshot 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 \r\n\r\n
\r\n \r\n
\r\n \r\n \r\n \r\n \r\n\r\n \r\n \r\n \r\n
\r\n
\r\n
\r\n
\r\n You will be redirected to a\r\n {{ showMicrosoftLogin && showGoogleLogin ? \"Microsoft/Google\" : showMicrosoftLogin ? \"Microsoft\" : \"Google\" }}\r\n login page. Please use your iCademy email credentials to login.\r\n
\r\n
\r\n
\r\n \r\n
\r\n
\r\n
\r\n \r\n {{ option.text }}\r\n \r\n
\r\n
\r\n \r\n
\r\n","import { DOCUMENT } from \"@angular/common\";\r\nimport { Component, ElementRef, Inject, OnDestroy, OnInit, ViewChild } from \"@angular/core\";\r\nimport { AuthService } from \"@services/auth/auth.service\";\r\nimport { AppEnvironment } from \"app/enums/repository/app-environment.enum\";\r\nimport { environment } from \"environments/environment\";\r\nimport { Subscription } from \"rxjs\";\r\nimport { Constants, Utility } from \"../../shared\";\r\n\r\n@Component({\r\n selector: \"app-login\",\r\n templateUrl: \"./login.component.html\",\r\n styleUrls: [\"./login.component.scss\"],\r\n})\r\nexport class LoginComponent implements OnInit, OnDestroy {\r\n @ViewChild(\"provider\") providerInput: ElementRef;\r\n @ViewChild(\"externalSignIn\") externalSignInForm: ElementRef;\r\n\r\n readonly showMicrosoftLogin = new Date() < new Date(2023, 6, 28); // starting July 28, 2023 only Google login should be available\r\n readonly showGoogleLogin =\r\n environment.configuration !== AppEnvironment.Production || // always show Google login in dev/test\r\n new Date() > new Date(2023, 5, 19); // starting June 19, 2023 Google login should be available\r\n\r\n subscription: Subscription;\r\n\r\n initializing = true;\r\n selectedLoginOption = 0;\r\n loginOptions = [\r\n { value: 1, text: \"iCademy Elementary Login\", color: \"primary\" },\r\n { value: 2, text: \"iCademy Global Login\", color: \"accent\" },\r\n { value: 3, text: \"Staff Login\", color: \"warn\" },\r\n ];\r\n\r\n constructor(@Inject(DOCUMENT) private document: HTMLDocument, private authService: AuthService) {\r\n try {\r\n const cachedValue = localStorage.getItem(Constants.loginTypeKey);\r\n if (cachedValue && this.loginOptions.some(option => option.value === Number(cachedValue))) {\r\n this.selectedLoginOption = Number(cachedValue);\r\n }\r\n } catch (e) {\r\n // local storage is unsupported\r\n }\r\n Utility.setFavicon(this.selectedLoginOption, this.document);\r\n }\r\n\r\n ngOnInit(): void {\r\n this.subscription = this.authService.getLoginStatusEvent().subscribe(isLoggedIn => {\r\n if (isLoggedIn) {\r\n this.authService.redirectLoginUser();\r\n }\r\n });\r\n\r\n setTimeout(() => {\r\n if (this.authService.isLoggedIn) {\r\n this.authService.redirectLoginUser();\r\n } else {\r\n this.initializing = false;\r\n }\r\n });\r\n }\r\n\r\n ngOnDestroy(): void {\r\n this.subscription.unsubscribe();\r\n }\r\n\r\n selectLogin(value) {\r\n this.selectedLoginOption = value;\r\n try {\r\n localStorage.setItem(Constants.loginTypeKey, value);\r\n } catch (e) {\r\n // local storage is unsupported\r\n }\r\n Utility.setFavicon(this.selectedLoginOption, this.document);\r\n }\r\n\r\n chooseNewLogin() {\r\n this.selectedLoginOption = 0;\r\n try {\r\n localStorage.removeItem(Constants.loginTypeKey);\r\n } catch (e) {\r\n // local storage is unsupported\r\n }\r\n }\r\n\r\n signIn(provider: \"Google\" | \"Microsoft\") {\r\n localStorage.setItem(Constants.loginProvider, provider);\r\n this.providerInput.nativeElement.value = provider;\r\n this.externalSignInForm.nativeElement.submit();\r\n }\r\n}\r\n","\r\n \r\n Resources\r\n \r\n \r\n \r\n \r\n \r\n \r\n
\r\n

{{ entry.key }}

\r\n \r\n insert_drive_file\r\n {{ resource.title }}\r\n \r\n
\r\n
\r\n
\r\n \r\n \r\n
\r\n

{{ entry.key }}

\r\n \r\n insert_drive_file\r\n {{ resource.title }}\r\n \r\n
\r\n
\r\n
\r\n \r\n \r\n
\r\n

{{ entry.key }}

\r\n \r\n insert_drive_file\r\n {{ resource.title }}\r\n \r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n","import { Component, OnInit } from \"@angular/core\";\r\nimport { StudentResource } from \"@models/student-resource.model\";\r\nimport { AdminService } from \"@services/admin.service\";\r\nimport { Constants } from \"app/shared\";\r\n\r\n@Component({\r\n selector: \"app-resources\",\r\n templateUrl: \"./resources.component.html\",\r\n styleUrls: [\"./resources.component.scss\"],\r\n})\r\nexport class ResourcesComponent implements OnInit {\r\n resourcesByCategoryK5: Map;\r\n resourcesByCategory68: Map;\r\n resourcesByCategory912: Map;\r\n gradesK5 = Constants.gradesK5;\r\n grades68 = Constants.grades68;\r\n grades912 = Constants.grades912;\r\n\r\n constructor(private adminService: AdminService) {}\r\n\r\n ngOnInit() {\r\n this.adminService.returnStudentResources().subscribe(result => {\r\n this.resourcesByCategoryK5 = this.buildGradeMap(this.gradesK5, result);\r\n this.resourcesByCategory68 = this.buildGradeMap(this.grades68, result);\r\n this.resourcesByCategory912 = this.buildGradeMap(this.grades912, result);\r\n });\r\n }\r\n\r\n private buildGradeMap(gradeLevels: string[], result: StudentResource[]): Map {\r\n const resourceMap = new Map();\r\n\r\n let filtered = result.filter(resource => {\r\n let resourceGradeLevels = resource.studentResourceGradeLevels.map(x => x.gradeLevel);\r\n return gradeLevels.some(x => resourceGradeLevels.indexOf(x) !== -1);\r\n });\r\n\r\n filtered.forEach(resource => {\r\n if (resourceMap.has(resource.category)) {\r\n resourceMap.get(resource.category).push(resource);\r\n } else {\r\n resourceMap.set(resource.category, [resource]);\r\n }\r\n });\r\n\r\n return resourceMap;\r\n }\r\n}\r\n","import { NgModule } from \"@angular/core\";\r\nimport { RouterModule, Routes } from \"@angular/router\";\r\nimport { AppComponent } from \"./app.component\";\r\nimport { AuthCallbackComponent, EmailOptOutComponent, LoginComponent, ResourcesComponent } from \"./components\";\r\nimport { NotAuthorizedComponent, PageNotFoundComponent } from \"./design\";\r\nimport { AuthenticationGuard, AuthorizationGuard, StaffGuard } from \"./guards\";\r\n\r\n// Route table\r\nconst routes: Routes = [\r\n {\r\n path: \"login\",\r\n component: LoginComponent,\r\n },\r\n {\r\n path: \"staff\",\r\n loadChildren: () => import(\"./staff/staff.module\").then(m => m.StaffModule),\r\n canActivate: [AuthenticationGuard, StaffGuard],\r\n },\r\n {\r\n path: \"student\",\r\n loadChildren: () => import(\"./student/student.module\").then(m => m.StudentModule),\r\n canActivate: [AuthenticationGuard],\r\n },\r\n {\r\n path: \"authCallback\",\r\n redirectTo: \"auth-callback\",\r\n },\r\n {\r\n path: \"auth-callback\",\r\n component: AuthCallbackComponent,\r\n },\r\n {\r\n path: \"resources\",\r\n component: ResourcesComponent,\r\n },\r\n {\r\n path: \"emailOptOut/:studentGoogleId\", // used by azure functions\r\n redirectTo: \"email-opt-out/:studentGoogleId\",\r\n },\r\n {\r\n path: \"email-opt-out/:studentGoogleId\",\r\n component: EmailOptOutComponent,\r\n },\r\n {\r\n path: \"page-not-found\",\r\n component: PageNotFoundComponent,\r\n },\r\n {\r\n path: \"not-authorized\",\r\n component: NotAuthorizedComponent,\r\n },\r\n {\r\n path: \"\",\r\n component: AppComponent,\r\n canActivate: [AuthenticationGuard, AuthorizationGuard],\r\n },\r\n {\r\n path: \"**\",\r\n redirectTo: \"page-not-found\",\r\n },\r\n // these redirects only exist as they were the previous routes\r\n {\r\n path: \"admin\",\r\n redirectTo: \"staff/admin\",\r\n },\r\n {\r\n path: \"mentor\",\r\n redirectTo: \"staff/mentor\",\r\n },\r\n {\r\n path: \"reports\",\r\n redirectTo: \"staff/reports\",\r\n },\r\n];\r\n\r\n@NgModule({\r\n imports: [\r\n RouterModule.forRoot(routes, {\r\n scrollPositionRestoration: \"enabled\",\r\n onSameUrlNavigation: \"reload\",\r\n relativeLinkResolution: \"legacy\",\r\n }),\r\n ],\r\n exports: [RouterModule],\r\n})\r\nexport class AppRoutingModule {}\r\n","import { HttpErrorResponse } from \"@angular/common/http\";\r\nimport { Injectable } from \"@angular/core\";\r\n\r\n@Injectable({ providedIn: \"root\" })\r\nexport class ErrorService {\r\n getClientErrorMessage(error: Error): string {\r\n return error.message ? error.message : error.toString();\r\n }\r\n\r\n getServerErrorMessage(error: HttpErrorResponse): string {\r\n return navigator.onLine ? error.message : \"No Internet Connection\";\r\n }\r\n\r\n getClientStack(error: Error): string {\r\n return error.stack ? error.stack : error.toString();\r\n }\r\n\r\n getServerStack(error: Error): string {\r\n return error.stack ? error.stack : error.toString();\r\n }\r\n}\r\n","import { Injectable } from \"@angular/core\";\r\nimport { ApplicationInsights } from \"@microsoft/applicationinsights-web\";\r\nimport { environment } from \"environments/environment\";\r\n\r\n@Injectable({\r\n providedIn: \"root\",\r\n})\r\nexport class ApplicationInsightsService {\r\n appInsights: ApplicationInsights;\r\n\r\n constructor() {\r\n this.appInsights = new ApplicationInsights({ config: environment.appInsightsConfiguration });\r\n this.appInsights.loadAppInsights();\r\n }\r\n}\r\n","import { HttpErrorResponse } from \"@angular/common/http\";\r\nimport { ErrorHandler, Injectable, Injector, NgZone } from \"@angular/core\";\r\nimport { MatSnackBar, MatSnackBarConfig } from \"@angular/material/snack-bar\";\r\nimport { ApplicationInsightsService } from \"@services/application-insights.service\";\r\nimport { AuthService } from \"@services/auth/auth.service\";\r\nimport { CommonService } from \"@services/common.service\";\r\nimport { environment } from \"environments/environment\";\r\nimport { AppEnvironment } from \"./enums/repository/app-environment.enum\";\r\nimport { ErrorService } from \"./services/error.service\";\r\n\r\n@Injectable({ providedIn: \"root\" })\r\nexport class GlobalErrorHandler implements ErrorHandler {\r\n constructor(\r\n private injector: Injector,\r\n private authService: AuthService,\r\n private commonService: CommonService,\r\n private snackBar: MatSnackBar,\r\n private _zone: NgZone,\r\n private appInsightsService: ApplicationInsightsService\r\n ) {}\r\n\r\n handleError(error: Error | HttpErrorResponse) {\r\n const errorService = this.injector.get(ErrorService);\r\n const username = this.authService.currentUser?.email ?? \"anonymous\";\r\n\r\n let message;\r\n let stackTrace;\r\n\r\n if (environment.configuration !== AppEnvironment.Development) {\r\n this.appInsightsService.appInsights.trackException(\r\n {\r\n exception: new Error(JSON.stringify(error)),\r\n },\r\n {\r\n username,\r\n serverError: error instanceof HttpErrorResponse,\r\n }\r\n );\r\n }\r\n\r\n if (error instanceof HttpErrorResponse) {\r\n // Server Error\r\n message = errorService.getServerErrorMessage(error);\r\n stackTrace = errorService.getServerStack(error);\r\n throw error;\r\n } else {\r\n // Client Error\r\n message =\r\n \"User \" + username + \" has encountered the following error: \" + errorService.getClientErrorMessage(error);\r\n stackTrace = errorService.getClientStack(error);\r\n\r\n const mes = errorService.getClientErrorMessage(error);\r\n if (\r\n mes === \"Uncaught (in promise): NotAllowedError: Permission denied\" ||\r\n mes === \"Uncaught (in promise): NotAllowedError: Permission dismissed\"\r\n ) {\r\n this._zone.run(() => {\r\n const config = new MatSnackBarConfig();\r\n config.verticalPosition = \"bottom\";\r\n config.horizontalPosition = \"center\";\r\n config.duration = 4000;\r\n config.panelClass = \"error\";\r\n const snackBar = this.snackBar.open(\r\n \"You must allow access to the camera in order to take the selfie\",\r\n \"Close\",\r\n config\r\n );\r\n const onActionSubscription = snackBar.onAction().subscribe(() => {\r\n snackBar.dismiss();\r\n });\r\n snackBar.afterDismissed().subscribe(() => onActionSubscription.unsubscribe());\r\n });\r\n }\r\n\r\n const newError = {\r\n message: message,\r\n stackTrace: stackTrace,\r\n };\r\n const em = errorService.getClientErrorMessage(error);\r\n\r\n if (environment.configuration !== AppEnvironment.Production) {\r\n console.error(error);\r\n } else {\r\n // Code block is here to account for instances where after a new version of the application has been deployed, a user tries to navigate to a specific area\r\n // while working off a cached version. When this happens, the user receives a \"Loading Chunk [insert number here] failed\" error.\r\n // This will not send the error message to the Notify Developers method server side\r\n const chunkFailedErrorMessage = /Loading chunk [\\d]+ failed/;\r\n\r\n if (\r\n em !== \"Uncaught (in promise): User login is required\" &&\r\n em !== \"Cannot send request to registered endpoint if the user is not authenticated.\" &&\r\n !em.includes(\"Uncaught (in promise): NotAllowedError: Permission denied\") &&\r\n !em.includes(\"Uncaught (in promise): NotAllowedError: Permission dismissed\") &&\r\n !em.includes(\"ExpressionChangedAfterItHasBeenCheckedError: Expression has changed after it was checked\") &&\r\n !em.includes(\"The data area passed to a system call is too small\") &&\r\n !em.includes(\"TypeError: null is not an object (evaluating 'localStorage.getItem')\") &&\r\n !em.match(chunkFailedErrorMessage)\r\n ) {\r\n this.commonService.sendErrorEmail(newError).subscribe();\r\n } else if (chunkFailedErrorMessage.test(em.toString())) {\r\n // Force a full refresh of the page to ensure the user is working off the latest set of code, instead of a cached version\r\n window.location.reload();\r\n }\r\n }\r\n }\r\n }\r\n}\r\n","import { HttpErrorResponse, HttpEvent, HttpHandler, HttpInterceptor, HttpRequest } from \"@angular/common/http\";\r\nimport { Injectable } from \"@angular/core\";\r\nimport { MatSnackBar } from \"@angular/material/snack-bar\";\r\nimport { Observable, throwError } from \"rxjs\";\r\nimport { catchError } from \"rxjs/operators\";\r\n\r\n@Injectable({ providedIn: \"root\" })\r\nexport class ServerErrorInterceptor implements HttpInterceptor {\r\n constructor(private snackBar: MatSnackBar) {}\r\n\r\n intercept(request: HttpRequest, next: HttpHandler): Observable> {\r\n return next.handle(request).pipe(\r\n catchError((error: Error | HttpErrorResponse) => {\r\n if (error[\"status\"] !== 400) {\r\n // allow the caller to handle 400 errors\r\n switch (request.method) {\r\n case \"POST\":\r\n this.snackBar.open(\"An error has occurred.\", \"Dismiss\", {\r\n duration: 6000,\r\n });\r\n break;\r\n case \"GET\":\r\n this.snackBar.open(\"An error has occurred\", \"Dismiss\", {\r\n duration: 6000,\r\n });\r\n break;\r\n default:\r\n break;\r\n }\r\n }\r\n return throwError(error);\r\n })\r\n );\r\n }\r\n}\r\n","import { CommonModule } from \"@angular/common\";\r\nimport { HTTP_INTERCEPTORS, HttpClientModule } from \"@angular/common/http\";\r\nimport { ErrorHandler, NgModule } from \"@angular/core\";\r\nimport { FlexLayoutModule } from \"@angular/flex-layout\";\r\nimport { BrowserModule } from \"@angular/platform-browser\";\r\nimport { BrowserAnimationsModule } from \"@angular/platform-browser/animations\";\r\nimport { ReactiveFormConfig } from \"@rxweb/reactive-form-validators\";\r\nimport { ApiHttpInterceptor } from \"@services/api/api.http-interceptor\";\r\nimport { LazyLoadImageModule } from \"ng-lazyload-image\";\r\nimport { NgxMaskModule } from \"ngx-mask\";\r\nimport { AppRoutingModule } from \"./app-routing.module\";\r\nimport { AppComponent } from \"./app.component\";\r\nimport { AuthCallbackComponent, EmailOptOutComponent, LoginComponent, ResourcesComponent } from \"./components\";\r\nimport { DirtyFormDialogComponent } from \"./components/dirty-form-dialog/dirty-form-dialog.component\";\r\nimport { DesignModule } from \"./design\";\r\nimport { GlobalErrorHandler } from \"./global-error-handler\";\r\nimport { ServerErrorInterceptor } from \"./server-error-interceptor\";\r\n\r\n@NgModule({\r\n declarations: [\r\n AppComponent,\r\n AuthCallbackComponent,\r\n LoginComponent,\r\n ResourcesComponent,\r\n EmailOptOutComponent,\r\n DirtyFormDialogComponent,\r\n ],\r\n imports: [\r\n AppRoutingModule,\r\n BrowserModule,\r\n BrowserAnimationsModule,\r\n CommonModule,\r\n DesignModule,\r\n FlexLayoutModule,\r\n HttpClientModule,\r\n LazyLoadImageModule,\r\n NgxMaskModule.forRoot(),\r\n ],\r\n providers: [\r\n // interceptors/handlers\r\n { provide: HTTP_INTERCEPTORS, useClass: ServerErrorInterceptor, multi: true },\r\n { provide: ErrorHandler, useClass: GlobalErrorHandler },\r\n {\r\n provide: HTTP_INTERCEPTORS,\r\n useClass: ApiHttpInterceptor,\r\n multi: true,\r\n },\r\n\r\n // components\r\n AppComponent,\r\n ],\r\n bootstrap: [AppComponent],\r\n})\r\nexport class AppModule {\r\n constructor() {\r\n ReactiveFormConfig.set({\r\n internationalization: {\r\n dateFormat: \"mdy\",\r\n seperator: \"/\",\r\n },\r\n validationMessage: {\r\n range: \"This field must be between {{1}} and {{2}}.\",\r\n required: \"This field is required.\",\r\n minLength: \"A minimum of {{1}} character(s) are allowed.\",\r\n maxLength: \"A maximum of {{1}} character(s) are allowed.\",\r\n minNumber: \"A minimum number of {{1}} is allowed.\",\r\n maxNumber: \"A maximum number of {{1}} is allowed.\",\r\n minDate: \"A minimum date of {{1}} is allowed.\",\r\n maxDate: \"A maximum date of {{1}} is allowed.\",\r\n notEmpty: \"This field cannot be empty.\",\r\n requiredTrue: \"This field must be checked.\",\r\n alpha: \"Only letters are allowed.\",\r\n numeric: \"Only numbers are allowed.\",\r\n alphaNumeric: \"Only letters and numbers are allowed.\",\r\n ascii: \"Only ASCII characters are allowed.\",\r\n url: \"Invalid URL format.\",\r\n email: \"Invalid email format.\",\r\n password: \"Your password is not strong enough.\",\r\n compare: \"This value doesn't match.\",\r\n matDatepickerParse: \"The format is invalid.\",\r\n },\r\n });\r\n }\r\n}\r\n","import { enableProdMode } from \"@angular/core\";\r\nimport { platformBrowserDynamic } from \"@angular/platform-browser-dynamic\";\r\n\r\nimport { AppEnvironment } from \"app/enums/repository/app-environment.enum\";\r\nimport { AppModule } from \"./app/app.module\";\r\nimport { environment } from \"./environments/environment\";\r\n\r\nif (environment.configuration !== AppEnvironment.Development) {\r\n enableProdMode();\r\n}\r\n\r\nplatformBrowserDynamic()\r\n .bootstrapModule(AppModule)\r\n .catch(err => console.error(err));\r\n"],"x_google_ignoreList":[]}