{"version":3,"sources":["webpack:///./src/main.ts","webpack:///./src/pages/add-users.ts","webpack:///./src/pages/add-users.html"],"names":["configure","aurelia","use","standardConfiguration","feature","plugin","config","useDefaults","useCSS","initialize","container","registerInstance","app","fileService","API_HOST","db","connect","start","then","setRoot","navigator","window","addEventListener","serviceWorker","register","registration","console","log","catch","registrationError","getLogger","errorMessage","error","Error","message","AddUsersPage","actionService","alerts","api","controllerFactory","storage","dialogService","allUsersSelected","isDragover","loading","pageNumber","perPage","programs","programRolesToAdd","singleEmail","singleFirstName","singleLastName","uploadPending","appRoles","bulkOrg","bulkRole","licenseCount","licenseStatusClass","programRoles","rowsToShow","singleFile","usersToInvite","organization","id","name","orgOptions","this","controller","createForCurrentScope","singleOrg","singleRole","auth","me","getOrganizations","license_limit","updateLicenseCount","getPrograms","getRoles","get","userList","data","users","updateRowsToShow","e","debug","programRoleList","find","pr","programId","create","level","label","dismissable","program","p","push","programTitle","title","roleId","action","programInput","value","updateLocalStorage","u","email","singleUser","firstName","lastName","appRole","organizationId","__checked","undefined","appRoleId","map","user","orgId","filter","programRole","forEach","deleteSingleUser","files","query","$path","result","Array","isArray","templateIndex","findIndex","file","template","fileName","split","length","target","loadingMessage","roles","$limit","role","scopes","includes","public","orgs","organizations","$sort","org","ids","partner_orgs","userOrgId","$select","$eager","$skip","managementOrganizationId","$or","join","info","emails","authManagement","currentUser","fullName","fullname","invitedCount","invitedUsers","existingUsers","invalidEmails","failedUsers","remove","openInviteErrorsDialog","f","type","invite","dialog","model","getProgramString","callback","inviteUsers","delete","deleteSelected","selectAppRole","valueField","labelField","options","bulkChangeAppRole","selectOrg","bulkChangeOrg","open","viewModel","whenClosed","wasCancelled","output","errorList","errors","object","list","reset","existingEmails","failedMessages","messages","concat","over","programUsersRoles","program_org_id","$joinRelation","index","array","licenseExempt","v","user_id","licenseRatio","first","i","fileList","Promise","resolve","reject","reader","FileReader","onload","event","csvData","parse","header","skipEmptyLines","complete","promises","userObj","validatedUser","validate","userInTable","valid","addError","all","openBulkErrorDialog","readAsText","ensure","required","withMessage","on","module","exports"],"mappings":"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","file":"app~5a11b65b.0f7788130971ef4916ae.chunk.js","sourcesContent":["/* eslint-disable no-console */\nimport { Aurelia } from 'aurelia-framework';\nimport * as environment from '../config/environment.json';\nimport { PLATFORM } from 'aurelia-pal';\nimport { setupLogging } from 'logging';\nimport { AppConfig } from './services/util/AppConfig';\nimport { createApp } from './services/api/feathers';\nimport { createFileService, FileService } from './services/api/file';\nimport { FeathersApplication } from './types/Application';\nimport { DB } from './services/util/DB';\n\nif ('serviceWorker' in navigator) {\n    window.addEventListener('load', () => {\n        navigator.serviceWorker.register('/service-worker.js').then((registration) => {\n            console.log('SW registered: ', registration);\n        }).catch((registrationError) => {\n            console.log('SW registration failed: ', registrationError);\n        });\n    });\n}\n\nexport async function configure(aurelia: Aurelia): Promise<void> {\n\n    aurelia.use\n        .standardConfiguration()\n        .feature(PLATFORM.moduleName('resources/index'))\n\n        // misc\n        .plugin(PLATFORM.moduleName('aurelia-gridstack'))\n        .plugin(PLATFORM.moduleName('aurelia-validation'))\n        .plugin(PLATFORM.moduleName('aurelia-dialog'), (config) => {\n            config.useDefaults();\n            config.useCSS('');\n        })\n\n        // ux\n        .plugin(PLATFORM.moduleName('@aurelia-mdc-web/all'))\n        .plugin(PLATFORM.moduleName('bcx-aurelia-reorderable-repeat'));\n\n    if (environment.testing) {\n        aurelia.use.plugin(PLATFORM.moduleName('aurelia-testing'));\n    }\n\n    // di registration\n    const config = new AppConfig();\n    await config.initialize();\n    setupLogging();\n    aurelia.container.registerInstance(AppConfig, config);\n    const app = createApp(config);\n    const fileService = createFileService(config.API_HOST, app);\n    aurelia.container.registerInstance(FileService, fileService);\n    aurelia.container.registerInstance(FeathersApplication, app);\n    // aurelia.container.registerTransient(OfflineService, OfflineService);\n\n    const db = new DB();\n    await db.connect();\n    aurelia.container.registerInstance(DB, db);\n\n    await aurelia.start().then(() => aurelia.setRoot(PLATFORM.moduleName('app')));\n}\n","\nimport { autoinject, bindable, computedFrom, LogManager } from 'aurelia-framework';\nimport { AlertService } from '../services/util/Alert';\nimport { ActionService } from '../services/actions/ActionService';\nimport { BrowserStorage } from '../services/util/BrowserStorage';\nimport { DatafiProAPI } from '../services/api/DatafiProAPI';\nimport { APIFile, ProgramUserRole, Role, SaveFileActionData } from '@wsb_dev/datafi-shared/lib/types';\nimport { ValidationController, ValidationControllerFactory, ValidationRules } from 'aurelia-validation';\nimport Papa from 'papaparse';\nimport { ValidatedOrganization } from 'types/Organizations';\nimport { userHasPermission } from '@wsb_dev/datafi-shared/lib/util/users/userHasPermission';\nimport { Program } from 'types/Program';\nimport { Paginated } from '@feathersjs/feathers';\nimport { SelectDialog } from '../components/select-dialog/select-dialog';\nimport { DialogService } from 'aurelia-dialog';\nimport { ProgramUser } from './admin/admin-edit-user-programs/admin-edit-user-programs';\nimport { ConfirmDialog } from '../components/confirm-dialog/confirm-dialog';\nimport { ListDialog, ListDialogActivate } from '../components/list-dialog/list-dialog';\nimport { UserToInvite } from '../types/UserToInvite';\n\nconst log = LogManager.getLogger('dfp:add-users');\n\nfunction errorMessage(error: unknown): string {\n    if (error instanceof Error) return error.message;\n    if (typeof error === 'string') return error;\n    return 'Unknown error';\n}\n\n@autoinject\nexport class AddUsersPage {\n    /** Bindables */\n    @bindable allUsersSelected = false;\n    @bindable isDragover = false;\n    @bindable loading = false;\n    @bindable pageNumber = 1;\n    @bindable perPage = 10;\n    @bindable programs: Program[] = [];\n    @bindable programRolesToAdd: ProgramUser[] = [];\n    @bindable singleEmail = '';\n    @bindable singleFirstName = '';\n    @bindable singleLastName = '';\n    @bindable singleOrg: number | undefined;\n    @bindable singleRole: number | undefined;\n    @computedFrom('singleFirstName', 'singleLastName', 'singleEmail', 'singleOrg', 'singleRole')\n    get singleFields(): boolean {\n        return !!(this.singleFirstName && this.singleLastName && this.singleEmail && (this.singleOrg || this.singleOrg === 0) && this.singleRole);\n    }\n    @bindable uploadPending = false;\n\n    /** Internal */\n    appRoles: Role[] = [];\n    bulkOrg = 0;\n    bulkRole = 0;\n    controller: ValidationController;\n    licenseCount = 0;\n    licenseStatusClass = '';\n    programRoles: Role[] = [];\n    rowsToShow: UserToInvite[] = [];\n    singleFile = true;\n    usersToInvite: UserToInvite[] = [];\n    organization: ValidatedOrganization = { id: 0, name: 'No Organization' } as ValidatedOrganization;\n    orgOptions: ValidatedOrganization[] = [];\n    programInput!: HTMLInputElement;\n\n    constructor(\n        private actionService: ActionService,\n        private alerts: AlertService,\n        private api: DatafiProAPI,\n        private controllerFactory: ValidationControllerFactory,\n        private storage: BrowserStorage,\n        private dialogService: DialogService,\n    ) {\n        this.controller = this.controllerFactory.createForCurrentScope();\n    }\n\n    canActivate(): boolean {\n        return userHasPermission(this.api.auth.me!, 'api/v1/users', 'create');\n    }\n\n    async activate(): Promise<void> {\n        await this.getOrganizations();\n        if (this.organization?.license_limit) await this.updateLicenseCount();\n        await this.getPrograms();\n        await this.getRoles();\n    }\n\n    attached(): void {\n        this.storage.get('usersToInvite')\n            .then((userList) => {\n                this.usersToInvite = userList.data.users;\n                this.updateRowsToShow();\n            }).catch((e) => {\n                log.debug(e);\n                this.usersToInvite = [];\n            });\n        this.storage.get('programRolesToAdd')\n            .then((programRoleList) => {\n                this.programRolesToAdd = programRoleList.data;\n            }).catch((e) => {\n                log.debug(e);\n                this.programRolesToAdd = [];\n            });\n    }\n\n    addProgramRole(id: number): void {\n        if (this.programRolesToAdd.find((pr) => pr.programId === id)) {\n            this.alerts.create({\n                level: 'error',\n                label: 'This program has already been selected.',\n                dismissable: true,\n            });\n            return;\n        }\n\n        const program = this.programs.find((p) => p.id === id);\n        if (!program) return;\n\n        this.programRolesToAdd.push({\n            programTitle: program.title || '',\n            roleId: this.programRoles[0]?.id ?? 0,\n            programId: program.id as number,\n            action: 'create',\n        });\n        this.programInput.value = '';\n        this.updateLocalStorage();\n    }\n\n    addSingleUser(): void {\n        const userExists = this.usersToInvite.find((u) => u.email === this.singleEmail);\n        if (userExists) {\n            this.alerts.create({\n                level: 'error',\n                label: 'A user with that email address already exists.',\n                dismissable: true,\n            });\n            return;\n        }\n        const singleUser: UserToInvite = {\n            firstName: this.singleFirstName,\n            lastName: this.singleLastName,\n            email: this.singleEmail,\n            appRole: this.singleRole as number,\n            organizationId: this.singleOrg as number,\n            __checked: false,\n        };\n        this.usersToInvite = [...this.usersToInvite, singleUser];\n        this.updateLocalStorage();\n        this.updateRowsToShow();\n        this.singleFirstName = '';\n        this.singleLastName = '';\n        this.singleEmail = '';\n        this.singleOrg = undefined;\n        this.singleRole = undefined;\n    }\n\n    bulkChangeAppRole(appRoleId: number): void {\n        this.usersToInvite = this.usersToInvite.map((user) => ({\n            ...user,\n            appRole: user.__checked ? appRoleId : user.appRole,\n            __checked: false,\n        }));\n        this.updateRowsToShow();\n        this.updateLocalStorage();\n    }\n\n    bulkChangeOrg(orgId: number): void {\n        this.usersToInvite = this.usersToInvite.map((user) => ({\n            ...user,\n            organizationId: user.__checked ? orgId : user.organizationId,\n            __checked: false,\n        }));\n        this.updateRowsToShow();\n        this.updateLocalStorage();\n    }\n\n    deleteProgramRole(programId: number): void {\n        this.programRolesToAdd = this.programRolesToAdd.filter((programRole: ProgramUser) => {\n            return programRole.programId !== programId;\n        });\n        this.updateLocalStorage();\n    }\n\n    deleteSelected(): void {\n        this.usersToInvite.forEach((user) => {\n            if (user.__checked) {\n                this.deleteSingleUser(user.email);\n            }\n        });\n    }\n\n    deleteSingleUser(email: string): void {\n        this.usersToInvite = this.usersToInvite.filter((user: UserToInvite): boolean => {\n            return user.email !== email;\n        });\n        this.updateRowsToShow();\n        this.updateLocalStorage();\n    }\n\n    downloadTemplate(): void {\n        this.api.files.find({ query: { $path: 'static/' } }).then((result) => {\n            const files = (Array.isArray(result) ? result : []) as APIFile[];\n            const templateIndex = files.findIndex((file) => {\n                return file.id === 'static/dfp-invite-user-template.csv';\n            });\n            if (templateIndex < 0) return;\n            const template = files[templateIndex];\n            if (!template?.id) return;\n            const fileName = template.id.split('/');\n            const name = fileName[fileName.length - 1];\n            this.actionService.create({\n                id: 'SaveFile',\n                target: [{ id: template.id }],\n                loadingMessage: 'Fetching file, please wait...',\n                errorMessage: 'Error: file could not be downloaded',\n                name,\n            } as SaveFileActionData);\n        }).catch((e: unknown) => {\n            this.alerts.create({\n                label: errorMessage(e),\n                level: 'error',\n                dismissable: true,\n            });\n        });\n    }\n\n    async getRoles(): Promise<void> {\n        await this.api.roles.find({ query: { $limit: 50 } })\n            .then((result) => {\n                const data = (result as Paginated<Role>).data || [];\n                this.programRoles = data.filter((role) => role.scopes?.includes('program'));\n                this.appRoles = data.filter((role) => role.scopes?.includes('app') && role.public);\n                this.bulkRole = this.appRoles[0]?.id ?? 0;\n            });\n    }\n\n    async getOrganizations(): Promise<void> {\n        const result = await this.api.organizations.find({\n            query: { $sort: { id: 1 } },\n        }) as Paginated<ValidatedOrganization>;\n        const orgs = result.data || [];\n\n        const orgId = this.api.auth.me?.organizationId || 0;\n        this.organization = orgs.find((org) => org.id === orgId)\n            || orgs[0]\n            || ({ id: 0, name: 'No Organization' } as ValidatedOrganization);\n\n        const isAdmin = userHasPermission(this.api.auth.me!, '*', '*');\n        if (isAdmin) {\n            this.orgOptions = orgs;\n            this.bulkOrg = 0;\n            return;\n        }\n\n        const ids = this.organization.partner_orgs && this.organization.partner_orgs.length ?\n            [this.organization.id, ...this.organization.partner_orgs] :\n            [this.organization.id];\n\n        this.orgOptions = orgs.filter((org: ValidatedOrganization) => ids.includes(org.id));\n\n        this.bulkOrg = this.api.auth.me?.organizationId || orgs[0]?.id || 0;\n    }\n\n    async getPrograms(): Promise<void> {\n        const userOrgId = this.api.auth.me?.organizationId;\n        const query = {\n            $select: ['id', 'title'],\n            $eager: 'roles.role',\n            $limit: 25,\n            $skip: 0,\n            $sort: { title: 1 },\n            ...(userOrgId\n                ? { managementOrganizationId: userOrgId }\n                : { $or: [{ managementOrganizationId: 0 }, { managementOrganizationId: null }] }\n            ),\n        };\n\n        await this.api.programs.find({ query: query }).then((result) => {\n            this.programs = (result as Paginated<Program>).data || [];\n        });\n    }\n\n    getProgramString(): string {\n        return this.programRolesToAdd.length ?\n            this.programRolesToAdd.length === 1 ? this.programRolesToAdd[0].programTitle :\n                this.programRolesToAdd.map((pr) => pr.programTitle).join(', ') :\n            'no programs';\n    }\n\n    async inviteUsers(): Promise<{ action: string; message: string }> {\n        if (!this.usersToInvite.length) {\n            return { action: 'no-users', message: 'No users to invite' };\n        }\n\n        this.loading = true;\n        log.info('inviteUsers: starting', {\n            emails: this.usersToInvite.map((u) => u.email),\n            programRoles: this.programRolesToAdd.map((pr) => ({\n                programId: pr.programId,\n                roleId: pr.roleId,\n                programTitle: pr.programTitle,\n            })),\n        });\n\n        try {\n            // Roles are assigned server-side in the same request so a browser hang/crash\n            // after user create cannot leave invitees without program membership.\n            const result = await this.api.authManagement.create({\n                action: 'invite-users',\n                usersToInvite: this.usersToInvite,\n                programRoles: this.programRolesToAdd.map((pr) => ({\n                    programId: pr.programId,\n                    roleId: pr.roleId,\n                    programTitle: pr.programTitle,\n                })),\n                currentUser: {\n                    email: this.api.auth.me?.email,\n                    fullName: this.api.auth.me?.fullname,\n                },\n            });\n\n            log.info('inviteUsers: account-management response', {\n                action: result?.action,\n                invitedCount: result?.invitedUsers?.length,\n                existingUsers: result?.existingUsers,\n                invalidEmails: result?.invalidEmails,\n                failedUsers: result?.failedUsers,\n            });\n\n            if (result?.action === 'users-invited') {\n                this.usersToInvite = [];\n                this.storage.remove('usersToInvite');\n                this.storage.remove('programRolesToAdd');\n                this.updateRowsToShow();\n\n                this.alerts.create({\n                    level: result.failedUsers?.length ? 'warning' : 'success',\n                    label: result.message,\n                    dismissable: true,\n                });\n\n                if (result.existingUsers?.length || result.invalidEmails?.length || result.failedUsers?.length) {\n                    this.openInviteErrorsDialog(\n                        result.existingUsers || [],\n                        result.invalidEmails || [],\n                        (result.failedUsers || []).map((f: { email: string; error?: string }) =>\n                            `${f.email}: ${f.error || 'failed'}`),\n                    );\n                }\n\n                return { action: 'success', message: result.message };\n            }\n\n            if (result?.action === 'error') {\n                this.alerts.create({\n                    level: 'error',\n                    label: result.message || 'Invite failed. Please try again.',\n                    dismissable: true,\n                });\n                return { action: 'error', message: result.message };\n            }\n\n            log.error('inviteUsers: Invalid response from server', { result });\n            this.alerts.create({\n                level: 'error',\n                label: 'Unexpected response while inviting users. Refresh and check whether the user appears under the program.',\n                dismissable: true,\n            });\n            return { action: 'error', message: 'Invalid response from server' };\n        } catch (e) {\n            const message = errorMessage(e);\n            log.error('inviteUsers: request failed', e);\n            this.alerts.create({\n                level: 'error',\n                label: `Invite failed: ${message}. Refresh and check the program Users list — the account may already exist.`,\n                dismissable: true,\n            });\n            return { action: 'error', message };\n        } finally {\n            this.loading = false;\n        }\n    }\n\n    openDialog(type: string): void {\n        const actions: Record<string, {\n            dialog: typeof ConfirmDialog | typeof SelectDialog;\n            model: Record<string, unknown>;\n            callback: (value?: number) => void | Promise<{ action: string; message: string }>;\n        }> = {\n            invite: {\n                dialog: ConfirmDialog,\n                model: {\n                    title: 'Confirm Invitations',\n                    message: `Invite ${this.usersToInvite.length} users to ${this.getProgramString()}?`,\n                },\n                callback: () => this.inviteUsers(),\n            },\n            delete: {\n                dialog: ConfirmDialog,\n                model: {\n                    title: 'Confirm Deletion',\n                    message: `Delete ${this.usersToInvite.filter((u) => u.__checked).length} users?`,\n                },\n                callback: () => this.deleteSelected(),\n            },\n            selectAppRole: {\n                dialog: SelectDialog,\n                model: {\n                    label: 'App Role',\n                    valueField: 'id',\n                    labelField: 'role_name',\n                    options: this.appRoles,\n                },\n                callback: (value?: number) => this.bulkChangeAppRole(value as number),\n            },\n            selectOrg: {\n                dialog: SelectDialog,\n                model: {\n                    label: 'Organization',\n                    valueField: 'id',\n                    labelField: 'name',\n                    options: this.orgOptions,\n                },\n                callback: (value?: number) => this.bulkChangeOrg(value as number),\n            },\n        };\n\n        const action = actions[type];\n        if (!action) return;\n\n        this.dialogService.open({\n            viewModel: action.dialog,\n            model: action.model,\n        }).whenClosed((result) => {\n            if (!result.wasCancelled) {\n                action.callback(result.output);\n            }\n        });\n\n    }\n\n    openBulkErrorDialog(): void {\n        const errorList = this.controller.errors.map((e) => {\n            return `${e.message} for ${e.object.email ? e.object.email : e.object.firstName + ' ' + e.object.lastName}`;\n        });\n        this.dialogService.open({\n            viewModel: ListDialog,\n            model: {\n                title: 'Bulk User Errors',\n                message: 'Some users were not added:',\n                list: errorList,\n            } as ListDialogActivate,\n        }).whenClosed(() => {\n            this.controller.reset();\n        });\n    }\n\n    openInviteErrorsDialog(existingEmails: string[], invalidEmails: string[], failedMessages: string[] = []): void {\n        const messages = existingEmails.map((email) => {\n            return `A user already exists with the email ${email}`;\n        }).concat(invalidEmails.map((email) => {\n            return `${email} is not a valid email`;\n        })).concat(failedMessages);\n\n        this.dialogService.open({\n            viewModel: ListDialog,\n            model: {\n                title: 'Invite results',\n                message: 'Some emails already existed, were invalid, or failed:',\n                list: messages,\n            } as ListDialogActivate,\n        });\n    }\n\n    pageNumberChanged(): void {\n        this.usersToInvite = this.usersToInvite.map((user) => {\n            return { ...user, __checked: false };\n        });\n        this.updateRowsToShow();\n    }\n\n    perPageChanged(): void {\n        this.updateRowsToShow();\n    }\n\n    selectAllUsers(): void {\n        if (this.usersToInvite.length) {\n            if (this.allUsersSelected) {\n                this.rowsToShow.forEach((user) => {\n                    user.__checked = true;\n                });\n            } else {\n                this.rowsToShow.forEach((user) => {\n                    user.__checked = false;\n                });\n            }\n        }\n    }\n\n    updateDragover(over: boolean): void {\n        this.isDragover = over;\n    }\n\n    async updateLicenseCount(): Promise<void> {\n        await this.api.programUsersRoles.find({\n            query: {\n                program_org_id: this.organization.id,\n                $eager: 'user',\n                $joinRelation: 'user',\n                $limit: 5000,\n            },\n        }).then((result) => {\n            const data = (result as Paginated<ProgramUserRole>).data || [];\n            this.licenseCount = data.filter((value, index, array) => {\n                return !value.user?.licenseExempt && array.findIndex((v) => v.user_id === value.user_id) === index;\n            }).length;\n            const licenseRatio = this.licenseCount / this.organization.license_limit;\n            this.licenseStatusClass = licenseRatio >= 0.75 && licenseRatio < 0.9 ? 'text-warning' :\n                licenseRatio >= 0.9 ? 'text-error' : '';\n        }).catch((e: unknown) => {\n            this.alerts.create({\n                label: errorMessage(e),\n                level: 'error',\n                dismissable: true,\n            });\n        });\n    }\n\n    updateLocalStorage(): void {\n        this.storage.create({\n            id: 'usersToInvite',\n            data: {\n                users: this.usersToInvite,\n            },\n        });\n        this.storage.create({\n            id: 'programRolesToAdd',\n            data: this.programRolesToAdd,\n        });\n    }\n\n    updateRowsToShow(): void {\n        this.allUsersSelected = false;\n        const first = this.perPage * (this.pageNumber - 1);\n        const rowsToShow: UserToInvite[] = [];\n        for (let i = first; i < first + this.perPage; i++) {\n            if (this.usersToInvite[i]) rowsToShow.push(this.usersToInvite[i]);\n        }\n        this.rowsToShow = rowsToShow;\n    }\n\n    async uploadUserInviteList(fileList: Array<File>): Promise<Record<string, string>[] | void> {\n        if (!this.bulkRole) {\n            this.alerts.create({\n                level: 'error',\n                label: 'No app role is selected.',\n                dismissable: true,\n            });\n            return;\n        }\n\n        const file = fileList[0];\n        return new Promise((resolve, reject) => {\n            if (!file || file.type !== 'text/csv') {\n                this.alerts.create({\n                    level: 'error',\n                    label: 'Please upload a valid CSV file.',\n                    dismissable: true,\n                });\n                return;\n            }\n\n            const reader = new FileReader();\n            reader.onload = (event) => {\n                const csvData = event.target?.result as string;\n\n                Papa.parse(csvData, {\n                    header: true,\n                    skipEmptyLines: true,\n                    complete: async (result) => {\n                        this.uploadPending = true;\n                        const promises = result.data.map(async (user: Record<string, string>) => {\n                            const userObj = new UserToInvite({\n                                firstName: user['First Name'],\n                                lastName: user['Last Name'],\n                                email: user['Email'],\n                                appRole: this.bulkRole,\n                                organizationId: this.bulkOrg,\n                                __checked: false,\n                            });\n                            const validatedUser = await this.controller.validate({ object: userObj });\n                            const userInTable = this.usersToInvite.find((u) => {\n                                return u.email === userObj.email;\n                            });\n                            if (validatedUser.valid && !userInTable) {\n                                this.usersToInvite.push(userObj);\n                            }\n                            if (userInTable) this.controller.addError('Email already exists in table', userObj);\n                        });\n                        await Promise.all(promises);\n\n                        resolve(result.data);\n                        this.uploadPending = false;\n                        this.updateRowsToShow();\n                        this.updateLocalStorage();\n                        if (this.controller.errors.length) this.openBulkErrorDialog();\n                    },\n                    error: (error: Error) => {\n                        reject(error);\n                    },\n                });\n            };\n            reader.readAsText(file);\n        });\n    }\n\n}\n\nValidationRules\n    .ensure('singleEmail').required().withMessage('A valid email is required.').email().withMessage('Please enter a valid email.')\n    .ensure('singleFirstName').required().withMessage('A first name is required.')\n    .ensure('singleLastName').required().withMessage('A last name is required.')\n    .ensure('singleOrg').required().withMessage('An organization is required.')\n    .ensure('singleRole').required().withMessage('An app role is required.')\n    .on(AddUsersPage);\n","// Module\nvar code = \"<template> <require from=\\\"components/admin/admin-table\\\"></require> <require from=\\\"components/mdc-pagination/mdc-pagination\\\"></require> <div class=\\\"container h-100 d-flex flex-column add-users\\\"> <div if.bind=\\\"loading\\\" class=\\\"loading-overlay\\\"></div> <div class=\\\"columns\\\"> <div class=\\\"column col-6 col-xl-12\\\"> <div class=\\\"row px-4 mt-4\\\"> <h2>Select Programs</h2> <div mdc-menu-surface-anchor> <mdc-text-field outlined label=\\\"Search for a Program\\\" ref=\\\"programInput\\\" value.bind=\\\"inputValue\\\"> </mdc-text-field> <mdc-text-field-helper-line></mdc-text-field-helper-line> <mdc-lookup options.bind=\\\"programs\\\" display-field=\\\"title\\\" input.bind=\\\"programInput\\\" preload-options change.delegate=\\\"addProgramRole($event.detail.value.id)\\\"> </mdc-lookup> </div> <mdc-data-table class=\\\"w-100 mt-3\\\"> <table style=\\\"border:none\\\"> <thead> <th>Current Programs</th> <th>Program Role</th> <th></th> </thead> <tbody> <tr mdc-data-table-row if.bind=\\\"!programRolesToAdd.length\\\" style=\\\"background-color:#f1efee\\\"> <td class=\\\"text-gray\\\">No programs have been added.</td> <td></td> <td></td> </tr> <tr mdc-data-table-row repeat.for=\\\"p of programRolesToAdd\\\"> <td><strong>${p.programTitle}</strong></td> <td> <mdc-select naturalWidth fixed outlined value.bind=\\\"p.roleId\\\" mdcselect:change.delegate=\\\"updateLocalStorage()\\\"> <mdc-list> <mdc-list-item repeat.for=\\\"pr of programRoles\\\" value.bind=\\\"pr.id\\\">${pr.role_name} </mdc-list-item> </mdc-list> </mdc-select> </td> <td> <button click.delegate=\\\"deleteProgramRole(p.programId)\\\" mdc-icon-button class=\\\"button--color--danger\\\" icon=\\\"delete\\\"></button> </td> </tr> </tbody> </table> </mdc-data-table> </div> <div if.bind=\\\"organization.license_limit\\\" class=\\\"d-flex align-center px-4 mt-4\\\"> <h2>${organization.name} Licenses: <span class=\\\"${licenseStatusClass}\\\">${licenseCount}/${organization.license_limit}</span> </h2> <p class=\\\"ml-5 text-bold text-gray\\\"> An organization has a limited number of licenses for users.</p> </div> <p if.bind=\\\"(licenseCount + usersToInvite.length) > organization.license_limit\\\" class=\\\"text-error px-4 mt-0\\\"> Inviting the added users will exceed the license limit. Please remove some users. </p> <div class=\\\"row w-100 mt-4 px-4\\\"> <div class=\\\"columns\\\"> <div class=\\\"column col-6 col-md-12\\\"> <h2>Add Single User</h2> <div class=\\\"py-4\\\"> <form action=\\\"\\\"> <div class=\\\"form-group columns mb-3\\\"> <div class=\\\"column col-6 col-sm-12\\\"> <div class=\\\"pr-1\\\"> <mdc-text-field outlined value.bind=\\\"singleFirstName & validate\\\" type=\\\"text\\\" label=\\\"First Name\\\" label=\\\"Type 'error'\\\"> </mdc-text-field> <mdc-text-field-helper-line> <mdc-text-field-helper-text validation>Required</mdc-text-field-helper-text> </mdc-text-field-helper-line> </div> </div> <div class=\\\"column col-6 col-sm-12\\\"> <div class=\\\"pl-1\\\"> <mdc-text-field outlined value.bind=\\\"singleLastName & validate\\\" type=\\\"text\\\" label=\\\"Last Name\\\" label=\\\"Type 'error'\\\"> </mdc-text-field> <mdc-text-field-helper-line> <mdc-text-field-helper-text validation>Required</mdc-text-field-helper-text> </mdc-text-field-helper-line> </div> </div> </div> <mdc-text-field outlined value.bind=\\\"singleEmail & validate\\\" type=\\\"text\\\" label=\\\"Email\\\" label=\\\"Type 'error'\\\"> </mdc-text-field> <mdc-text-field-helper-line class=\\\"mb-3\\\"> <mdc-text-field-helper-text validation>Required</mdc-text-field-helper-text> </mdc-text-field-helper-line> <div class=\\\"form-group columns mb-3\\\"> <div class=\\\"column col-6 col-sm-12\\\"> <mdc-select value.bind=\\\"singleRole & validate\\\" label=\\\"App Role\\\" fixed outlined class=\\\"w-100\\\" disabled.bind=\\\"!appRoles.length\\\"> <mdc-list> <mdc-list-item value.bind=\\\"ar.id\\\" repeat.for=\\\"ar of appRoles\\\"> ${ar.role_name}</mdc-list-item> </mdc-list> </mdc-select> <mdc-select-helper-text validation></mdc-select-helper-text> </div> <div class=\\\"column col-6 col-sm-12\\\"> <mdc-select value.bind=\\\"singleOrg & validate\\\" label=\\\"Organization\\\" fixed outlined class=\\\"w-100\\\"> <mdc-list> <mdc-list-item value.bind=\\\"org.id\\\" repeat.for=\\\"org of orgOptions\\\"> ${org.name}</mdc-list-item> </mdc-list> </mdc-select> <mdc-select-helper-text validation></mdc-select-helper-text> </div> </div> <div class=\\\"text-center\\\"> <button disabled.bind=\\\"!singleFields || controller.errors.length\\\" click.trigger=\\\"addSingleUser()\\\" type=\\\"submit\\\" class=\\\"mx-auto mb-3\\\" mdc-button raised> <mdc-icon>add</mdc-icon> Add User </button> </div> </form> </div> </div> <div class=\\\"column col-6 col-xl-6 col-lg-6 col-md-12 col-sm-12\\\"> <h2>Add Bulk Users</h2> <p class=\\\"text-note-gray\\\"> Upload a .csv with user first names, last names, and emails.</p> <div class=\\\"text-center py-4\\\"> <button click.trigger=\\\"downloadTemplate()\\\" type=\\\"submit\\\" class=\\\"mx-auto\\\" mdc-button raised> <mdc-icon>download</mdc-icon> User Invite Template </button> </div> <div class=\\\"container mw-xs\\\"> <mdc-select label=\\\"App Role\\\" value.bind=\\\"bulkRole\\\" fixed outlined class=\\\"w-100 mb-5\\\" disabled.bind=\\\"!appRoles.length\\\"> <mdc-list> <mdc-list-item value.bind=\\\"ar.id\\\" repeat.for=\\\"ar of appRoles\\\"> ${ar.role_name}</mdc-list-item> </mdc-list> </mdc-select> <mdc-select label=\\\"Organization\\\" value.bind=\\\"bulkOrg\\\" fixed outlined class=\\\"w-100\\\"> <mdc-list> <mdc-list-item value.bind=\\\"org.id\\\" repeat.for=\\\"org of orgOptions\\\"> ${org.name}</mdc-list-item> </mdc-list> </mdc-select> </div> <mdc-select-helper-text validation></mdc-select-helper-text> <div class=\\\"pb-4 mb-4 mw-xs container border border-secondary border-rounded border-dashed ${isDragover ? 'is-dragover': ''}\\\" drop.trigger=\\\"uploadUserInviteList($event.dataTransfer.files)\\\" dragover.trigger=\\\"updateDragover(true)\\\" dragleave.trigger=\\\"updateDragover(false)\\\"> <p class=\\\"text-center\\\"> <mdc-icon class=\\\"icon-md\\\">cloud_upload</mdc-icon> </p> <h3 class=\\\"text-center\\\">Drag and drop files here</h3> <p class=\\\"text-center\\\">or</p> <label if.bind=\\\"!uploadPending\\\" class=\\\"text-center d-block pt-2\\\" mdc-button raised> <input type=\\\"file\\\" multiple=\\\"${singleFile ? 'false' : 'multiple'}\\\" class=\\\"d-none\\\" change.delegate=\\\"uploadUserInviteList($event.target.files)\\\"/> Browse Files... </label> <mdc-linear-progress class=\\\"pb-4 mb-4\\\" buffer=\\\"${progress}\\\" progress=\\\"${progress}\\\" open=\\\"true\\\" if.bind=\\\"uploadPending\\\"> </mdc-linear-progress> </div> </div> </div> </div> </div> <div class=\\\"column col-6 col-xl-12 flex-1 flex-column\\\"> <div class=\\\"row mt-4 px-4 w-100 flex-1 flex-column\\\"> <div class=\\\"w-100 flex-grow-1 p-relative\\\" style=\\\"min-height:60vh\\\"> <div class=\\\"absolute-cover\\\"> <mdc-data-table class=\\\"w-100 h-100\\\" sticky-header> <mdc-menu anchor-margin.bind=\\\"{top: 50, left: 60}\\\" view-model.ref=\\\"allMenu\\\" anchor.bind=\\\"hierarchicalAnchor\\\" hoistToBody> <mdc-list class=\\\"p-0\\\"> <mdc-list-item click.delegate=\\\"openDialog('delete')\\\"> <span class=\\\"mdc-list-item__text d-flex align-items-center\\\"> <mdc-icon class=\\\"mr-1\\\" style=\\\"padding-top:1px\\\">delete</mdc-icon>Delete Selected </span> </mdc-list-item> <mdc-list-item click.delegate=\\\"openDialog('selectAppRole')\\\"> <span class=\\\"mdc-list-item__text d-flex align-items-center\\\"> <mdc-icon class=\\\"mr-1\\\" style=\\\"padding-top:1px\\\">verified</mdc-icon>Change App Role </span> </mdc-list-item> <mdc-list-item click.delegate=\\\"openDialog('selectOrg')\\\"> <span class=\\\"mdc-list-item__text d-flex align-items-center\\\"> <mdc-icon class=\\\"mr-1\\\" style=\\\"padding-top:1px\\\">groups</mdc-icon>Change Organization </span> </mdc-list-item> </mdc-list> </mdc-menu> <table> <thead> <th> <mdc-checkbox checked.bind=\\\"allUsersSelected\\\" change.trigger=\\\"selectAllUsers()\\\"></mdc-checkbox> <div class=\\\"d-inline\\\"> <button mdc-button click.trigger=\\\"allMenu.open = !allMenu.open\\\" ref=\\\"hierarchicalAnchor\\\"> Actions <mdc-icon>arrow_drop_down</mdc-icon> </button> </div> </th> <th>First</th> <th>Last</th> <th>Email</th> <th>App Role</th> <th>Organization</th> </thead> <tbody> <tr mdc-data-table-row repeat.for=\\\"user of rowsToShow\\\"> <td> <mdc-checkbox checked.bind=\\\"user.__checked\\\"></mdc-checkbox> <button click.delegate=\\\"deleteSingleUser(user.email)\\\" mdc-icon-button class=\\\"button--color--danger\\\" icon=\\\"delete\\\"></button> </td> <td>${user.firstName}</td> <td>${user.lastName}</td> <td>${user.email}</td> <td> <mdc-select value.to-view=\\\"user.appRole\\\" fixed outlined> <mdc-list> <mdc-list-item value.bind=\\\"ar.id\\\" repeat.for=\\\"ar of appRoles\\\"> ${ar.role_name}</mdc-list-item> </mdc-list> </mdc-select> </td> <td> <mdc-select value.to-view=\\\"user.organizationId\\\" fixed outlined> <mdc-list> <mdc-list-item value.bind=\\\"org.id\\\" repeat.for=\\\"org of orgOptions\\\"> ${org.name}</mdc-list-item> </mdc-list> </mdc-select> </td> </tr> </tbody> </table> <mdc-linear-progress if.bind=\\\"loading\\\" open.bind=\\\"loading\\\"></mdc-linear-progress> </mdc-data-table> </div> </div> <mdc-pagination per-page-options.bind=\\\"[10,25,50,100]\\\" per-page.from-view=\\\"perPage\\\" page.two-way=\\\"pageNumber\\\" total.bind=\\\"usersToInvite.length\\\" class=\\\"w-100\\\"> </mdc-pagination> </div> <div class=\\\"row text-center my-4 w-100\\\"> <button click.trigger=\\\"openDialog('invite')\\\" type=\\\"submit\\\" class=\\\"mx-auto\\\" disabled.bind=\\\"!usersToInvite.length || (licenseCount + usersToInvite.length) > organization.license_limit\\\" mdc-button raised> <mdc-icon>mail</mdc-icon> Invite Users </button> <p if.bind=\\\"(licenseCount + usersToInvite.length) > organization.license_limit\\\" class=\\\"text-center text-error\\\">Inviting the added users will exceed the license limit. Please remove some users.</p> </div> </div> </div> </div> </template> \";\n// Exports\nmodule.exports = code;"],"sourceRoot":""}