{"version":3,"file":"app-d466cfc4.f584a1446b2fc034d810.bundle.js","mappings":"AAGA","sources":["webpack://lernplattform-admin-frontend/./src/resources/pages/tfa-page/tfa-page.html","webpack://lernplattform-admin-frontend/./src/resources/pages/training-result-page/training-result-page.html","webpack://lernplattform-admin-frontend/./src/resources/pages/uce-demo-page/uce-demo-page.html","webpack://lernplattform-admin-frontend/./src/resources/pages/user-administration-page/user-administration-page.html","webpack://lernplattform-admin-frontend/./src/resources/pages/user-details-page/user-details-page.html","webpack://lernplattform-admin-frontend/./src/resources/pages/user-editor-page/user-editor-page.html","webpack://lernplattform-admin-frontend/./src/resources/pages/user-editor-page/user-form.html","webpack://lernplattform-admin-frontend/./src/resources/pages/user-settings-page/user-settings-page.html","webpack://lernplattform-admin-frontend/./src/resources/pages/tfa-page/tfa-page.ts","webpack://lernplattform-admin-frontend/./src/resources/pages/training-result-page/training-result-page.ts","webpack://lernplattform-admin-frontend/./src/resources/pages/uce-demo-page/uce-demo-page.ts","webpack://lernplattform-admin-frontend/./src/resources/pages/user-administration-page/user-administration-page.ts","webpack://lernplattform-admin-frontend/./src/resources/pages/user-details-page/user-details-page.ts","webpack://lernplattform-admin-frontend/./src/resources/pages/user-editor-page/index.ts","webpack://lernplattform-admin-frontend/./src/resources/pages/user-editor-page/user-editor-page.ts","webpack://lernplattform-admin-frontend/./src/resources/pages/user-editor-page/user-form.ts","webpack://lernplattform-admin-frontend/./src/resources/pages/user-settings-page/user-settings-page.ts"],"sourcesContent":["// Module\nvar code = \"<template> <div class=\\\"page-header\\\"> <h1 class=\\\"page-title\\\" t=\\\"pages.tfa.title\\\"></h1> </div> <alert-message message-style=\\\"alert-warning\\\" if.to-view=\\\"tfaErrorTk\\\" message.to-view=\\\"{ tk: tfaErrorTk }\\\"></alert-message> <div class=\\\"row\\\" show.bind=\\\"initialized\\\"> <div class=\\\"col mx-auto col-login\\\" show.bind=\\\"!isActive\\\"> <div class=\\\"card\\\"> <div class=\\\"card-body\\\"> <img src.to-view=\\\"qrData\\\" class=\\\"card-img\\\"> <textarea class=\\\"form-control mt-2\\\" disabled=\\\"true\\\" value.two-way=\\\"secret\\\"></textarea> </div> <form class=\\\"card-body\\\"> <div class=\\\"form-group\\\"> <input class=\\\"form-control\\\" value.two-way=\\\"token\\\" t=\\\"[placeholder]pages.tfa.placeholder\\\"> </div> <div class=\\\"form-group\\\"> <button class=\\\"form-control btn btn-primary\\\" click.delegate=\\\"enable()\\\" t=\\\"globals.activate\\\"></button> </div> <div class=\\\"mt-3 text-muted text-justify\\\" t=\\\"pages.tfa.helpText\\\"></div> </form> </div> </div> <div class=\\\"col mx-auto col-login\\\" show.bind=\\\"isActive\\\"> <div class=\\\"card\\\"> <div class=\\\"card-body\\\"> <div class=\\\"card-title text-center card-title\\\" t=\\\"pages.tfa.isActive\\\"></div> </div> <div class=\\\"card-body\\\"> <button class=\\\"form-control btn btn-danger\\\" click.delegate=\\\"disable()\\\" t=\\\"globals.deactivate\\\"></button> </div> </div> </div> </div> </template> \";\n// Exports\nexport default code;","// Module\nvar code = \"<template> <button-standard click.trigger=\\\"back()\\\" class=\\\"mb-2\\\" t=\\\"[btnText]globals.back\\\" icon-name=\\\"System/Tabler/Chevron-Left\\\" btn-size=\\\"btn-sm\\\" btn-color=\\\"secondary\\\"></button-standard> <div class=\\\"bg-white border\\\"> <train-result-header class=\\\"mt-8\\\" question-count.to-view=\\\"questions.length\\\" correct-count.to-view=\\\"correctCount\\\" time-taken.to-view=\\\"timeTaken\\\"></train-result-header> <div class=\\\"lp-site-content-small\\\"> <button class=\\\"btn btn-outline-primary w-100 mt-5 text-uppercase\\\" click.delegate=\\\"showCorrectQuestions = !showCorrectQuestions\\\" t=\\\"globals.${showCorrectQuestions ? 'hideCorrectQuestions' : 'showCorrectQuestions'}\\\"> </button> <exam-result-legend></exam-result-legend> <quiz-result-question-block repeat.for=\\\"question of questions\\\" show.to-view=\\\"!question.isCorrect || showCorrectQuestions\\\" question.to-view=\\\"question\\\" question-index.to-view=\\\"$index\\\"></quiz-result-question-block> </div> </div> </template> \";\n// Exports\nexport default code;","// Module\nvar code = \"<template> </template>\";\n// Exports\nexport default code;","// Module\nvar code = \"<template> <div class=\\\"page-header\\\"> <div class=\\\"row\\\"> <h1 class=\\\"page-title col-12\\\" t=\\\"pages.user-administration.title\\\"></h1> <small class=\\\"text-muted col-12\\\">${ assignedStatesFormatted }</small> </div> <div class=\\\"ml-auto mb-2 d-flex\\\"> <filtered-export-widget filter.to-view=\\\"filter\\\" t=\\\"[btn-text]globals.personnelExport\\\" export-csv.trigger=\\\"exportCsv($event)\\\"></filtered-export-widget> <button-standard if.to-view=\\\"!powerUserMode\\\" click.delegate=\\\"linkOrCreatePowerUser()\\\" class=\\\"d-inline-block ml-2\\\" t=\\\"[btnText]pages.user-administration.addPowerUser\\\" icon-name=\\\"System/Tabler/User-Plus\\\" btn-color=\\\"primary\\\"></button-standard> </div> </div> <div class=\\\"row row-cards row-deck\\\"> <div class=\\\"col-12\\\"> <user-administration-table tenant-id.to-view=\\\"tenantId\\\" power-user-mode.to-view=\\\"powerUserMode\\\" filter.from-view=\\\"filter\\\" table-refresh-version.to-view=\\\"tableRefreshVersion\\\"></user-administration-table> </div> </div> </template>\";\n// Exports\nexport default code;","// Module\nvar code = \"<template> <button-standard click.trigger=\\\"navigateBack()\\\" t=\\\"[btnText]globals.back\\\" icon-name=\\\"System/Tabler/Chevron-Left\\\" btn-size=\\\"btn-sm\\\" btn-color=\\\"secondary\\\"></button-standard> <div class=\\\"page-header\\\"> <h1 class=\\\"page-title\\\" t=\\\"pages.user-details.title\\\"></h1> </div> <tenant-user-form if.to-view=\\\"user\\\" user.to-view=\\\"user\\\" assigned-states.to-view=\\\"user.assignedStates\\\" allow-change-email.to-view=\\\"!newUser\\\" is-power-user.to-view=\\\"isPowerUser\\\" save-user-data.trigger=\\\"saveOrCreate($event)\\\"> <div class=\\\"card-footer d-flex\\\"> <button-standard if.to-view=\\\"!newUser\\\" click.delegate=\\\"toggleEnabled()\\\" disabled.to-view=\\\"loading\\\" t=\\\"[btnText]elements.tenantUserForm.${ user.enabled ? 'blockAccess' : 'unblockAccess' }\\\" icon-name=\\\"System/Tabler/Alert-Triangle\\\" btn-type.to-view=\\\"user.enabled ? 'outline' : null\\\" btn-color=\\\"${ user.enabled ? 'danger' : 'secondary' }\\\"></button-standard> <button-standard if.to-view=\\\"newUser\\\" click.delegate=\\\"cancel()\\\" disabled.to-view=\\\"loading\\\" t=\\\"[btnText]globals.cancel\\\" btn-type=\\\"outline\\\" btn-color=\\\"secondary\\\"></button-standard> <button-standard class=\\\"ml-auto\\\" disabled.to-view=\\\"loading\\\" t=\\\"[btnText]globals.save\\\" submit.to-view=\\\"true\\\" btn-color=\\\"primary\\\"></button-standard> </div> </tenant-user-form> </template> \";\n// Exports\nexport default code;","// Module\nvar code = \"<template> <button-standard click.trigger=\\\"navigateBack()\\\" t=\\\"[btnText]globals.back\\\" icon-name=\\\"System/Tabler/Chevron-Left\\\" btn-size=\\\"btn-sm\\\" btn-color=\\\"secondary\\\"></button-standard> <div if.to-view=\\\"editMode\\\" class=\\\"page-header\\\"> <h1 class=\\\"page-title\\\" t=\\\"pages.userEditor.editOperator\\\"></h1> <div class=\\\"ml-auto\\\"> <button class=\\\"btn btn-outline-danger\\\" click.delegate=\\\"deleteOperator()\\\" t=\\\"globals.delete\\\"></button> </div> </div> <div else class=\\\"page-header\\\"> <h1 class=\\\"page-title\\\" t=\\\"pages.userEditor.newOperator\\\"></h1> </div> <div class=\\\"row\\\"> <div class=\\\"col-12\\\"> <form class=\\\"card\\\"> <div class=\\\"card-header\\\"> <h3 class=\\\"card-title\\\" t=\\\"pages.userEditor.userData\\\"></h3> </div> <div class=\\\"card-body\\\"> <user-form data.two-way=\\\"userData\\\" view-model.ref=\\\"userForm\\\"></user-form> </div> <div class=\\\"card-footer text-right\\\"> <div class=\\\"d-flex\\\"> <button-standard if.to-view=\\\"createMode\\\" click.delegate=\\\"createOperator()\\\" disabled.to-view=\\\"loading\\\" class=\\\"ml-auto\\\" t=\\\"[btnText]pages.userEditor.newOperatorButton\\\" icon-name=\\\"System/Tabler/User-Plus\\\" btn-color=\\\"primary\\\"></button-standard> <button-standard if.to-view=\\\"editMode\\\" click.delegate=\\\"editOperator()\\\" disabled.to-view=\\\"loading\\\" class=\\\"ml-auto\\\" t=\\\"[btnText]pages.userEditor.editOperatorButton\\\" btn-color=\\\"primary\\\"></button-standard> </div> </div> </form> </div> </div> </template>\";\n// Exports\nexport default code;","// Module\nvar code = \"<template> <div class=\\\"row\\\"> <div class=\\\"col-md-6\\\"> <div class=\\\"form-group\\\"> <div class=\\\"form-label\\\" t=\\\"pages.userEditor.form.titlePrefix\\\"></div> <input type=\\\"text\\\" class=\\\"form-control\\\" value.two-way=\\\"data.titlePrefix\\\"> </div> </div> <div class=\\\"col-md-6\\\"> <div class=\\\"form-group\\\"> <div class=\\\"form-label\\\" t=\\\"pages.userEditor.form.titleSuffix\\\"></div> <input type=\\\"text\\\" class=\\\"form-control\\\" value.two-way=\\\"data.titleSuffix\\\"> </div> </div> <div class=\\\"col-md-6\\\"> <div class=\\\"form-group\\\"> <div class=\\\"form-label\\\" t=\\\"pages.userEditor.form.firstname\\\"></div> <input type=\\\"text\\\" input.trigger=\\\"resetErrorTkByKey('firstname')\\\" class=\\\"form-control ${errorTks.firstname ? 'is-invalid' : ''}\\\" value.two-way=\\\"data.firstname\\\"> <div if.to-view=\\\"errorTks.firstname\\\" class=\\\"invalid-feedback\\\" t=\\\"${errorTks.firstname}\\\"></div> </div> </div> <div class=\\\"col-md-6\\\"> <div class=\\\"form-group\\\"> <div class=\\\"form-label\\\" t=\\\"pages.userEditor.form.lastname\\\"></div> <input type=\\\"text\\\" input.trigger=\\\"resetErrorTkByKey('lastname')\\\" class=\\\"form-control ${errorTks.lastname ? 'is-invalid' : ''}\\\" value.two-way=\\\"data.lastname\\\"> <div if.to-view=\\\"errorTks.lastname\\\" class=\\\"invalid-feedback\\\" t=\\\"${errorTks.lastname}\\\"></div> </div> </div> <div class=\\\"col-md-6\\\"> <div class=\\\"form-group\\\"> <div class=\\\"form-label\\\" t=\\\"pages.userEditor.form.email\\\"></div> <input type=\\\"text\\\" class=\\\"form-control\\\" value.two-way=\\\"data.email\\\"> </div> </div> <div class=\\\"col-md-6\\\"> <div class=\\\"form-group\\\"> <div class=\\\"form-label\\\" t=\\\"pages.userEditor.form.phoneNumber\\\"></div> <input type=\\\"text\\\" class=\\\"form-control\\\" value.two-way=\\\"data.phoneNumber\\\"> </div> </div> </div> </template>\";\n// Exports\nexport default code;","// Module\nvar code = \"<template> <div class=\\\"page-header\\\"> <h1 class=\\\"page-title\\\" t=\\\"pages.userSettings.title\\\"></h1> </div> <div if.to-view=\\\"languageSettingsEnabled\\\" class=\\\"row row-cards row-deck\\\"> <div class=\\\"card\\\"> <div class=\\\"card-header\\\"> <h3 class=\\\"card-title\\\" t=\\\"globals.language\\\"></h3> </div> <div class=\\\"card-body\\\"> <div class=\\\"row\\\"> <div class=\\\"col-6\\\"> <div class=\\\"form-group\\\"> <select class=\\\"custom-select\\\" change.delegate=\\\"setLanguage()\\\" value.bind=\\\"settings.language\\\"> <option repeat.for=\\\"language of languages\\\" model.bind=\\\"language\\\" t=\\\"globals.languageOptions.${language}\\\"> </option> </select> </div> </div> </div> </div> </div> </div> <div if.to-view=\\\"showMessageSettings\\\" class=\\\"row row-cards row-deck\\\"> <div class=\\\"card\\\"> <div class=\\\"card-header\\\"> <h3 class=\\\"card-title\\\" t=\\\"pages.userSettings.messagesTitle\\\"></h3> </div> <div class=\\\"card-body\\\"> <label class=\\\"custom-control custom-checkbox\\\"> <input type=\\\"checkbox\\\" class=\\\"custom-control-input\\\" name=\\\"can-receive-messages\\\" checked.two-way=\\\"canReceiveMessages\\\" disabled.to-view=\\\"canReceiveMessages == null\\\" change.delegate=\\\"onCanReceiveMessagesChanged($event)\\\"> <span class=\\\"custom-control-label\\\" t=\\\"pages.userSettings.canReceiveMessages\\\"></span> </label> </div> </div> </div> <div class=\\\"row row-cards row-deck\\\"> <form submit.trigger=\\\"savePassword()\\\" class=\\\"card\\\"> <div class=\\\"card-header\\\"> <h3 class=\\\"card-title\\\" t=\\\"pages.userSettings.newPasswordTitle\\\"></h3> </div> <div class=\\\"card-body\\\"> <div class=\\\"row\\\"> <div class=\\\"col-md-6\\\"> <div class=\\\"form-group\\\"> <div class=\\\"form-label\\\" t=\\\"pages.userSettings.oldPasswordLabel\\\"></div> <input role=\\\"textbox\\\" type=\\\"password\\\" autocomplete=\\\"current-password\\\" input.trigger=\\\"oldPasswordErrorTk = null\\\" class=\\\"form-control ${oldPasswordErrorTk ? 'is-invalid' : ''}\\\" value.two-way=\\\"oldPassword\\\" t=\\\"[placeholder]pages.login.password.placeholder\\\"> <div if.to-view=\\\"oldPasswordErrorTk\\\" class=\\\"invalid-feedback\\\" t.to-view=\\\"oldPasswordErrorTk\\\"></div> </div> <div class=\\\"form-group\\\"> <div class=\\\"form-label\\\" t=\\\"pages.userSettings.newPasswordLabel\\\"></div> <input role=\\\"textbox\\\" type=\\\"password\\\" autocomplete=\\\"new-password\\\" input.trigger=\\\"passwordError = null\\\" class=\\\"form-control ${passwordError ? 'is-invalid' : ''}\\\" value.two-way=\\\"password\\\" t=\\\"[placeholder]pages.login.password.placeholder\\\"> <div if.to-view=\\\"passwordError\\\" class=\\\"invalid-feedback\\\" t=\\\"${passwordError.errorTk}\\\" t-params.to-view=\\\"passwordError.errorTkParams\\\"></div> </div> <div class=\\\"form-group\\\"> <div class=\\\"form-label\\\" t=\\\"pages.userSettings.passwordRepeatLabel\\\"></div> <input role=\\\"textbox\\\" type=\\\"password\\\" autocomplete=\\\"new-password-retype\\\" input.trigger=\\\"passwordError = null\\\" class=\\\"form-control ${passwordError ? 'is-invalid' : ''}\\\" is-invalid.to-view=\\\"!!passwordError\\\" value.two-way=\\\"passwordRepeat\\\" t=\\\"[placeholder]pages.login.password.placeholder\\\"> <div if.to-view=\\\"passwordError\\\" class=\\\"invalid-feedback\\\" t=\\\"${passwordError.errorTk}\\\" t-params.to-view=\\\"passwordError.errorTkParams\\\"></div> </div> <password-strength-indicator if.to-view=\\\"password\\\" class=\\\"password-reset-page__strength-indicator\\\" password.to-view=\\\"password\\\" strength.from-view=\\\"passwordStrength\\\"></password-strength-indicator> </div> </div> </div> <div class=\\\"card-footer\\\"> <div class=\\\"text-right\\\"> <button type=\\\"submit\\\" class=\\\"btn btn-primary\\\" t=\\\"globals.save\\\"></button> </div> </div> </form> </div> </template>\";\n// Exports\nexport default code;","import { autoinject } from 'aurelia-framework';\nimport { ErrorType } from 'common/enum/errortype.enum';\nimport { LogUtils } from 'common/utils/LogUtils';\nimport { toDataURL } from 'qrcode';\nimport { AuthApiService } from 'services/api/AuthApiService';\n\n@autoinject\nexport class TfaPage {\n  protected secretUrl = '';\n  protected secret = '';\n  protected qrData = '';\n\n  protected token = '';\n  protected isActive = false;\n  protected initialized = false;\n\n  protected tfaErrorTk: string | null = null;\n\n  constructor(private authApiService: AuthApiService) {\n  }\n\n  protected activate(): void {\n    this.initialize();\n  }\n\n  protected async initialize(): Promise<void> {\n    this.initialized = false;\n    this.qrData = '';\n    this.secret = '';\n    try {\n      const res = await this.authApiService.initializeTfa();\n      this.secretUrl = res.secretUrl;\n      this.secret = res.secret;\n      this.qrData = await toDataURL(this.secretUrl, {\n        margin: 0,\n        scale: 8\n      });\n      this.initialized = true;\n    } catch(e) {\n      if(e.message === ErrorType.TFA_ALREADY_ENABLED) {\n        this.isActive = true;\n        this.initialized = true;\n      } else if(e.message === ErrorType.USER_NOT_FOUND) {\n        this.tfaErrorTk = 'pages.tfa.errorNoLocalProvider';\n      } else {\n        this.tfaErrorTk = 'pages.tfa.errorGeneric';\n        LogUtils.exception(e);\n      }\n    }\n  }\n\n  protected async enable(): Promise<void> {\n    try {\n      await this.authApiService.enableTfa(this.token);\n      this.isActive = true;\n    } catch(e) {\n      this.token = '';\n    }\n  }\n\n  protected async disable(): Promise<void> {\n    try {\n      await this.authApiService.disableTfa();\n      this.isActive = false;\n    } catch(e) {\n      this.isActive = true;\n    }\n    this.initialize();\n  }\n}\n","import { autoinject } from 'aurelia-framework';\nimport { IQuizQuestionDto } from 'common/dto/course/quiz/quiz.question.interface';\nimport { TrainingSessionType } from 'common/enum/quiz.enum';\nimport { LogUtils } from 'common/utils/LogUtils';\nimport { PageLoadingIndicatorService } from '../../../services/PageLoadingIndicatorService';\nimport { ToastService } from '../../../services/ToastService';\nimport { ProgressApiService } from '../../../services/api/ProgressApiService';\n\ninterface IParams {\n  quizSessionId: string;\n  invitationId: string;\n}\n\n@autoinject()\nexport class TrainingResultPage {\n  private questions: IQuizQuestionDto[] = [];\n  private correctCount = 0;\n  private timeTaken: number | null = null;\n  private showCorrectQuestions = false;\n  private trainingType: TrainingSessionType = TrainingSessionType.Free;\n\n  constructor(\n    private progressApiService: ProgressApiService,\n    private indicatorService: PageLoadingIndicatorService,\n    private toastService: ToastService\n  ) { }\n\n  protected activate(params: IParams): void {\n    const invitationId = parseInt(params.invitationId, 10);\n    const quizSessionId = parseInt(params.quizSessionId, 10);\n    this.getTrainingResult(invitationId, quizSessionId);\n  }\n\n  private async getTrainingResult(invitationId: number, quizSessionId: number): Promise<void> {\n    this.indicatorService.start();\n    try {\n      const result = await this.progressApiService.getTrainingResult(invitationId, quizSessionId);\n      this.questions = result.questions;\n      this.trainingType = result?.trainingSessionType ?? TrainingSessionType.Unknown;\n      this.correctCount = result?.numCorrect ?? 0;\n      this.timeTaken = Math.ceil(result?.durationInMinutes ?? 0);\n    } catch(error) {\n      this.toastService.error('pages.training-result-page.fetchError');\n      LogUtils.exception(error);\n    }\n    this.indicatorService.stop();\n  }\n\n  private back(): void {\n    window.history.back();\n  }\n}","export class UceDemoPage { }","import { autoinject, computedFrom } from 'aurelia-framework';\nimport { Router } from 'aurelia-router';\nimport { StoreService } from 'common/aurelia-services/StoreService';\nimport { IFilterDto } from 'common/dto/filter/filter.interface';\nimport { ITenantUserInfoDto } from 'common/dto/tenant/other/tenant.user.info.interface';\nimport { ErrorType } from 'common/enum/errortype.enum';\nimport { RoleName } from 'common/enum/role.enums';\nimport { assertNotNullOrUndefined } from 'common/utils/assert';\nimport { LogUtils } from 'common/utils/LogUtils';\nimport { TenantApiService } from '../../../services/api/TenantApiService';\nimport { CustomDialogService } from '../../../services/CustomDialogService';\nimport { ToastService } from '../../../services/ToastService';\nimport { IState } from '../../../store/state';\nimport { FilteredExportWidgetExportCsvEvent } from '../../elements/filtered-export-widget/filtered-export-widget';\n\n@autoinject()\nexport class UserAdministrationPage {\n  private powerUserMode: boolean = false;\n  private tenantId: number | null = null;\n  private tableRefreshVersion = 0;\n  private assignedStates: string[] = [];\n  private filter: IFilterDto<ITenantUserInfoDto> = {\n    offset: 0,\n    limit: 10,\n    order: [],\n    filter: [],\n  };\n\n  constructor(\n    private tenantApiService: TenantApiService,\n    private storeService: StoreService<IState>,\n    private customDialogService: CustomDialogService,\n    private toastService: ToastService,\n    private router: Router,\n  ) { }\n\n  protected async activate(): Promise<void> {\n    this.storeService.subscribeToDetailedChanges(this, [\n      state => state.currentRole ?? null,\n      state => state.user.id ?? null,\n    ], (_, currentRole, userId) => {\n      this.tenantId = currentRole?.tenantId ?? null;\n      this.powerUserMode = currentRole?.role === RoleName.PowerUser;\n      if(userId) this.updateAssignedStates(userId);\n    });\n  }\n\n  protected detached(): void {\n    this.storeService.disposeAllSubscriptions(this);\n  }\n\n  private async linkOrCreatePowerUser(): Promise<void> {\n    assertNotNullOrUndefined(this.tenantId, 'tenantId cannot be null or undefined');\n    const email = await this.customDialogService.promptEmail({\n      labelTk: `pages.employees.dialogs.link${RoleName.PowerUser}`,\n      placeholderTk: 'globals.email'\n    });\n    if(!email) return;\n    try {\n      await this.tenantApiService.linkPowerUser(this.tenantId, email);\n      this.tableRefreshVersion++;\n      this.toastService.success('pages.employees.notifications.linkUserInviteSent', { email });\n      return;\n    } catch(e) {\n      if(e.message === ErrorType.USER_EXISTS_AS_STUDENT) {\n        this.toastService.error('common.validationUtils.userExistsAsStudentError');\n        return;\n      }\n      if(e.message === ErrorType.USER_ALREADY_BELONGS_TO_TENANT) {\n        this.toastService.error('pages.employees.dialogs.userExistsAsAdministratorError');\n        return;\n      }\n      if(e.message === ErrorType.USER_NOT_FOUND) {\n        this.router.navigateToRoute('user-details/id', {\n          isPowerUser: true,\n          email,\n        });\n        return;\n      }\n      LogUtils.exception(e);\n      this.toastService.error(`pages.employees.dialogs.link${RoleName.PowerUser}Error`);\n      return;\n    }\n  }\n\n  @computedFrom('assignedStates')\n  private get assignedStatesFormatted(): string {\n    return this.assignedStates.sort((a, b) => a.localeCompare(b)).join(', ');\n  }\n\n  private async updateAssignedStates(userId: number): Promise<void> {\n    const response = await this.tenantApiService.getUserData(userId);\n    this.assignedStates = response.assignedStates ?? [];\n  }\n\n  private async exportCsv(event: FilteredExportWidgetExportCsvEvent): Promise<void> {\n    this.tenantApiService.exportTenantUsers(this.filter, event.detail.csvType);\n  }\n}\n","import { autoinject } from 'aurelia-framework';\nimport { Router } from 'aurelia-router';\nimport { StoreService } from 'common/aurelia-services/StoreService';\nimport { ITenantUserInfoDto, IUpdateTenantUserInfoDto } from 'common/dto/tenant/other/tenant.user.info.interface';\nimport { ErrorType } from 'common/enum/errortype.enum';\nimport { RoleName } from 'common/enum/role.enums';\nimport { LogUtils } from 'common/utils/LogUtils';\nimport { assertNotNullOrUndefined } from 'common/utils/assert';\nimport { ToastService } from '../../../services/ToastService';\nimport { TenantApiService } from '../../../services/api/TenantApiService';\nimport { IState } from '../../../store/state';\nimport { SaveUserDataEvent } from '../../elements/tenant-user-form/tenant-user-form';\n\ninterface IParams {\n  userId?: string;\n  isPowerUser?: string;\n  email?: string;\n}\n\n@autoinject()\nexport class UserDetailsPage {\n  private userId: number | null = null;\n  private user: ITenantUserInfoDto | null = null;\n  private isPowerUser = false;\n  private newUser = false;\n\n  private tenantId: number | null = null;\n  private loading: boolean = false;\n\n  constructor(\n    private tenantApiService: TenantApiService,\n    private storeService: StoreService<IState>,\n    private toastService: ToastService,\n    private router: Router,\n  ) { }\n\n  protected async activate(params: IParams): Promise<void> {\n    this.userId = params.userId ? parseInt(params.userId) : null;\n    this.newUser = !this.userId;\n    this.isPowerUser = params.isPowerUser === 'true';\n    const { email } = params;\n\n    this.storeService.subscribeToDetailedChanges(this, [\n      state => state.currentRole?.tenantId ?? null,\n    ], (_, tenantId) => {\n      this.tenantId = tenantId;\n    });\n\n    this.fetchData(email);\n  }\n\n  protected deactivate(): void {\n    this.storeService.disposeAllSubscriptions(this);\n  }\n\n  private async fetchData(email?: string): Promise<void> {\n    if(!this.userId) {\n      this.user = this.getEmptyUserData(email);\n      return;\n    }\n    this.user = await this.tenantApiService.getUserData(this.userId);\n  }\n\n  private async saveOrCreate(event: SaveUserDataEvent): Promise<void> {\n    if(!this.newUser) {\n      return this.updateUser(event.detail);\n    }\n    return this.createPowerUser(event.detail);\n  }\n\n  private async updateUser(\n    dto: IUpdateTenantUserInfoDto<string>,\n  ): Promise<void> {\n    assertNotNullOrUndefined(this.user, 'user cannot be null or undefined');\n\n    this.loading = true;\n    try {\n      this.user = await this.tenantApiService.updateUserData(this.user.id, dto);\n      this.toastService.success('globals.editSuccess');\n    } catch(e) {\n      if(e.message === ErrorType.INVALID_EMAIL) {\n        this.toastService.error('common.validationUtils.emailInvalidError');\n      } else {\n        this.toastService.genericUpdateError('globals.user');\n        LogUtils.exception(e);\n      }\n    } finally {\n      this.loading = false;\n    }\n  }\n\n  private async createPowerUser(\n    dto: ITenantUserInfoDto,\n  ): Promise<void> {\n    assertNotNullOrUndefined(this.tenantId, 'tenantId cannot be null or undefined');\n    try {\n      await this.tenantApiService.createPowerUser(this.tenantId, dto);\n      this.toastService.genericCreateSuccess('globals.poweruser');\n      this.router.navigateToRoute('user-administration');\n    } catch(e) {\n      if(e.message === ErrorType.INVALID_EMAIL) {\n        this.toastService.error('common.validationUtils.emailInvalidError');\n      } else {\n        this.toastService.genericCreateError('globals.poweruser');\n        LogUtils.exception(e);\n      }\n    }\n  }\n\n  private cancel(): void {\n    this.router.navigateBack();\n  }\n\n  private async toggleEnabled(): Promise<void> {\n    assertNotNullOrUndefined(this.tenantId, 'tenantId cannot be null or undefined');\n    assertNotNullOrUndefined(this.user, 'user cannot be null or undefined');\n\n    this.loading = true;\n    try {\n      this.user = await this.tenantApiService.setTenantUserStatus(this.tenantId, this.user.id, !this.user.enabled);\n      this.toastService.success('globals.editSuccess');\n    } catch(e) {\n      this.toastService.genericUpdateError('globals.user');\n      LogUtils.exception(e);\n    } finally {\n      this.loading = false;\n    }\n  }\n\n  private getEmptyUserData(email?: string): ITenantUserInfoDto {\n    return {\n      id: -1,\n      email: email ?? '',\n      enabled: true,\n      pending: false,\n      phoneNumber: null,\n      firstname: null,\n      lastname: null,\n      titlePrefix: null,\n      titleSuffix: null,\n      role: RoleName.PowerUser,\n      tenantId: null,\n      tenantName: null,\n      assignedStates: null,\n      address: {\n        country: '',\n        state: '',\n        postalCode: '',\n        city: '',\n        street: '',\n      }\n    };\n  }\n\n  private navigateBack(): void {\n    this.router.navigateToRoute('user-administration');\n  }\n}\n","import { PLATFORM } from 'aurelia-pal';\nimport { FrameworkConfiguration } from 'aurelia-framework';\n\nexport function configure(config: FrameworkConfiguration): void {\n  config.globalResources(PLATFORM.moduleName('resources/pages/user-editor-page/user-form'));\n}\n","import { autoinject, computedFrom } from 'aurelia-framework';\nimport { Router } from 'aurelia-router';\nimport { IUserData } from 'common/dto/auth/auth.interface';\nimport { ITenantUserInfoDto, IUpdateTenantUserInfoDto } from 'common/dto/tenant/other/tenant.user.info.interface';\nimport { ErrorType } from 'common/enum/errortype.enum';\nimport { LogUtils } from 'common/utils/LogUtils';\nimport { ToastService } from '../../../services/ToastService';\nimport { TenantApiService } from '../../../services/api/TenantApiService';\nimport { UserForm } from './user-form';\n\ninterface IParams {\n  tenantId: string;\n  userId: string;\n  email: string;\n}\n\n@autoinject()\nexport class UserEditorPage {\n  private tenantId: number = 0;\n  private userId: number = 0;\n  private userForm: UserForm | null = null;\n  private userData: IUserData<string> | ITenantUserInfoDto = {\n    email: '',\n    firstname: '',\n    lastname: '',\n  };\n  private loading: boolean = false;\n\n  constructor(\n    private toastService: ToastService,\n    private tenantApiService: TenantApiService,\n    private router: Router\n  ) { }\n\n  protected async activate(params: IParams): Promise<void> {\n    this.tenantId = parseInt(params.tenantId);\n    this.userId = 0;\n    if(params.userId === 'new') {\n      const email = params.email || '';\n      this.userData.email = email;\n      return;\n    }\n    this.userId = parseInt(params.userId);\n    this.fetchUserData();\n  }\n\n  @computedFrom('userId')\n  private get editMode(): boolean {\n    return this.userId > 0;\n  }\n\n  @computedFrom('userId')\n  private get createMode(): boolean {\n    return this.userId === 0;\n  }\n\n  private async fetchUserData(): Promise<void> {\n    this.userData = await this.tenantApiService.getUserData(this.userId);\n  }\n\n  private async createOperator(): Promise<void> {\n    if(this.checkUserData()) {\n      this.loading = true;\n      try {\n        const dto: IUserData<string> = {\n          address: this.userData.address,\n          email: this.userData.email,\n          firstname: this.userData.firstname,\n          lastname: this.userData.lastname,\n          phoneNumber: this.userData.phoneNumber,\n          titlePrefix: this.userData.titlePrefix,\n          titleSuffix: this.userData.titleSuffix,\n        };\n        await this.tenantApiService.createOperator(this.tenantId, dto);\n        this.toastService.success('pages.userEditor.newOperatorSuccess');\n        this.router.navigateToRoute('tenants/id', { id: this.tenantId });\n      } catch(e) {\n        if(e.message === ErrorType.INVALID_EMAIL) {\n          this.toastService.error('common.validationUtils.emailInvalidError');\n        } else if(e.message === ErrorType.USER_EXISTS_AS_STUDENT) {\n          this.toastService.error('common.validationUtils.userExistsAsStudentError');\n        } else if(e.message === ErrorType.TENANT_ALREADY_HAS_OPERATOR) {\n          this.toastService.error('pages.userEditor.tenantHasOperatorError');\n        } else {\n          LogUtils.exception(e);\n          this.toastService.error('pages.userEditor.newOperatorError');\n        }\n      } finally {\n        this.loading = false;\n      }\n    }\n  }\n\n  private async editOperator(): Promise<void> {\n    if(this.checkUserData()) {\n      this.loading = true;\n      try {\n        if(!('id' in this.userData)) throw new Error('Cannot update user without id');\n        const dto: IUpdateTenantUserInfoDto<string> = {\n          address: this.userData.address,\n          email: this.userData.email,\n          firstname: this.userData.firstname,\n          lastname: this.userData.lastname,\n          phoneNumber: this.userData.phoneNumber,\n          titlePrefix: this.userData.titlePrefix,\n          titleSuffix: this.userData.titleSuffix,\n        };\n        await this.tenantApiService.updateUserData(this.userData.id, dto);\n        this.toastService.success('pages.userEditor.editOperatorSuccess');\n        this.navigateBack();\n      } catch(e) {\n        if(e.message === ErrorType.PHONE_NUMBER_EXISTS) {\n          this.toastService.error('common.validationUtils.phoneNumberExistsError');\n        } else if(e.message === ErrorType.USER_EXISTS) {\n          this.toastService.error('common.validationUtils.emailExistsError');\n        } else if(e.message === ErrorType.INVALID_EMAIL) {\n          this.toastService.error('common.validationUtils.emailInvalidError');\n        } else {\n          LogUtils.exception(e);\n          this.toastService.error('pages.userEditor.editOperatorError');\n        }\n      } finally {\n        this.loading = false;\n      }\n    }\n  }\n\n  private async deleteOperator(): Promise<void> {\n    this.loading = true;\n    try {\n      await this.tenantApiService.unlinkUser(this.tenantId, this.userId);\n      this.toastService.success('pages.userEditor.deleteOperatorSuccess');\n      this.navigateBack();\n    } catch(e) {\n      LogUtils.exception(e);\n      this.toastService.error('pages.userEditor.deleteOperatorError');\n    } finally {\n      this.loading = false;\n    }\n  }\n\n  private checkUserData(): boolean {\n    return this.userForm?.validate() ?? false;\n  }\n\n  private navigateBack(): void {\n    this.router.navigateBack();\n  }\n}\n","import { autoinject, bindable } from 'aurelia-framework';\nimport { IUserData } from 'common/dto/auth/auth.interface';\nimport { ValidationUtils } from 'common/utils/ValidationUtils';\n\n@autoinject\nexport class UserForm {\n  @bindable public data!: IUserData<string>;\n  private errorTks: IErrorTk = {\n    firstname: null,\n    lastname: null,\n  };\n\n  private resetErrorTkByKey(key: keyof IErrorTk): void {\n    this.errorTks[key] = null;\n  }\n\n  /**\n  * userData must have firstname, lastname\n  */\n  public validate(): boolean {\n    this.errorTks.firstname = ValidationUtils.checkFirstname(this.data.firstname);\n    this.errorTks.lastname = ValidationUtils.checkLastname(this.data.lastname);\n    return Object.values(this.errorTks).every(value => !value);\n  }\n}\n\nexport interface IErrorTk {\n  firstname: string | null;\n  lastname: string | null;\n}","import { autoinject, computedFrom } from 'aurelia-framework';\nimport { ChatApiService } from 'common/aurelia-services/ChatApiService';\nimport { StoreService, StoreSubscriptionManager } from 'common/aurelia-services/StoreService';\nimport { Language } from 'common/dto/other/language.enum';\nimport { ISettingsDto } from 'common/dto/setting/setting.interface';\nimport { ErrorType } from 'common/enum/errortype.enum';\nimport { Config } from 'common/fe-config/config';\nimport { LogUtils } from 'common/utils/LogUtils';\nimport { ToastService } from '../../../services/ToastService';\nimport { AuthApiService } from '../../../services/api/AuthApiService';\nimport { UserSettingsApiService } from '../../../services/api/UserSettingsApiService';\nimport { setLanguageAction } from '../../../store/actions';\nimport { IState } from '../../../store/state';\nimport { IErrorTk, ValidationUtils } from '../../../utils/ValidationUtils';\n\n@autoinject()\nexport class UserSettingsPage {\n  private storeSubscriptionManager: StoreSubscriptionManager<IState>;\n  private settings?: ISettingsDto;\n  private oldPassword: string = '';\n  private oldPasswordErrorTk: string | null = null;\n  private password: string = '';\n  private passwordRepeat: string = '';\n  private passwordError: IErrorTk | null = null;\n  private passwordStrength = 0;\n  private canReceiveMessages: boolean | null = null;\n  private isProvider: boolean | null = null;\n  private languages: string[] = Object.values(Language);\n  private languageSettingsEnabled = Config().languageSettings.enabled;\n  private messageSettingsEnabled = Config().messageSettings.enabled;\n\n  constructor(\n    storeService: StoreService<IState>,\n    private settingsApiService: UserSettingsApiService,\n    private authApiService: AuthApiService,\n    private chatApiService: ChatApiService,\n    private toastService: ToastService\n  ) {\n    this.storeSubscriptionManager = storeService.createStoreSubscriptionManager();\n  }\n\n  protected async attached(): Promise<void> {\n    this.settings = await this.settingsApiService.getSettings();\n    this.canReceiveMessages = await this.chatApiService.checkIfMessagingIsAllowed();\n\n    this.storeSubscriptionManager.subscribeToDetailedChanges([\n      state => state.user.isProvider,\n    ], (_, isProvider) => {\n      this.isProvider = isProvider;\n    });\n  }\n\n  protected async detached(): Promise<void> {\n    this.storeSubscriptionManager.unsubscribe();\n  }\n\n  private async onCanReceiveMessagesChanged(): Promise<void> {\n    if(this.canReceiveMessages == null) return;\n\n    try {\n      await this.chatApiService.setCanReceiveMessages(this.canReceiveMessages);\n      this.toastService.success('pages.userSettings.changeCanReceiveMessagesSuccess');\n    } catch(e) {\n      LogUtils.exception(e);\n      this.toastService.error('pages.userSettings.changeCanReceiveMessagesError');\n    }\n  }\n\n  @computedFrom('isProvider', 'messageSettingsEnabled')\n  private get showMessageSettings(): boolean {\n    return this.messageSettingsEnabled && this.isProvider != null && !this.isProvider;\n  }\n\n  private async savePassword(): Promise<void> {\n    this.passwordError = ValidationUtils.checkPasswords(this.password, this.passwordRepeat, this.passwordStrength);\n\n    if(!this.passwordError) {\n      try {\n        await this.authApiService.setNewPassword({ newPassword: this.password, oldPassword: this.oldPassword });\n        this.toastService.success('pages.userSettings.changePasswordSuccess');\n        this.oldPassword = '';\n        this.password = '';\n        this.passwordRepeat = '';\n      } catch(e) {\n        if(e.message === ErrorType.INVALID_LOGIN) {\n          this.oldPasswordErrorTk = 'pages.userSettings.passwordInvalid';\n        } else {\n          LogUtils.exception(e);\n          this.toastService.error('pages.userSettings.changePasswordError');\n        }\n      }\n    }\n  }\n\n  private async setLanguage(): Promise<void> {\n    if(this.settings?.language) {\n      try {\n        await this.settingsApiService.updateSettings({ language: this.settings.language });\n        await this.storeSubscriptionManager.getStore().dispatch(setLanguageAction, this.settings.language);\n        this.toastService.genericUpdateSuccess('globals.settings');\n      } catch(e) {\n        LogUtils.exception(e);\n        this.toastService.genericUpdateError('globals.settings');\n      }\n    }\n  }\n}\n"],"names":[],"sourceRoot":""}