src/lib/components/pages/TenantUser.vue (333 lines of code) (raw):

<template> <TenantHome :title="title" :breadcrumb-links="breadcrumbLinks" :errors="errors"> <template #header-right> <div style="display: flex; flex-direction: row;"> <div style="font-size: 14px; font-weight: 500;padding-right: 20px;"> <b-icon icon="envelope"></b-icon> {{ email }} <br/> <b-icon icon="person"></b-icon> {{ username }} </div> <div> <b-button variant="primary" v-on:click="onClickSave">Save</b-button> </div> </div> </template> <b-overlay :show="processing"> <div class="p-2" style="display: flex; flex-direction: row;"> <div style="flex: 1;padding-right: 10px;"> <div class="pt-3"> <label class="form-label" for="first-name">First Name</label> <b-form-input v-model="firstName" :state="inputState.firstName" id="first-name" trim size="sm"> </b-form-input> <b-form-invalid-feedback> </b-form-invalid-feedback> </div> <div class="pt-3"> <label class="form-label" for="last-name">Last Name</label> <b-form-input v-model="lastName" :state="inputState.lastName" id="last-name" trim size="sm"> </b-form-input> <b-form-invalid-feedback> </b-form-invalid-feedback> </div> <div class="pt-3" v-if="availableTenantRoles && availableTenantRoles.length > 0"> <label class="form-label" for="realm-roles">Roles</label> <b-form-checkbox-group v-model="realmRoles" :options="availableTenantRoles" :state="inputState.realmRoles" id="realm-roles" trim size="sm" aria-describedby="scope-help-block"> </b-form-checkbox-group> <b-form-text id="scope-help-block"></b-form-text> <b-form-invalid-feedback></b-form-invalid-feedback> </div> <!-- <div class="pt-3" v-if="tenant && tenant.hasAdminPrivileges">--> <!-- <label class="form-label" for="client-roles">Client Roles</label>--> <!-- <b-form-checkbox-group--> <!-- v-model="clientRoles"--> <!-- :options="availableClientRoles"--> <!-- :state="inputState.clientRoles"--> <!-- id="client-roles"--> <!-- trim--> <!-- size="sm"--> <!-- aria-describedby="scope-help-block">--> <!-- </b-form-checkbox-group>--> <!-- <b-form-text id="scope-help-block"></b-form-text>--> <!-- <b-form-invalid-feedback></b-form-invalid-feedback>--> <!-- </div>--> </div> <div style="flex: 1;padding-left: 10px;"> <div class="pt-3"> <label class="form-label" for="attributes">Attributes</label> <table-overlay-info :rows="5" :columns="2" :data="attributes" empty-label="No attributes."> <template #empty> No attributes to show. <b-button variant="link" size="sm" v-on:click="attributes.push({key: '', values: ''})"> Create an attribute </b-button> </template> <b-table-simple> <b-thead> <b-tr> <b-th></b-th> <b-th>Key</b-th> <b-th>Values</b-th> </b-tr> </b-thead> <b-tbody> <b-tr v-for="(attribute, attributesIndex) in availableAttributes" :key="attributesIndex"> <b-td>#{{ attributesIndex + 1 }}</b-td> <b-td> <label :for="`attribute-key-${attributesIndex + 1}`" style="visibility: hidden; position: fixed; top: -100px;"> Attribute #{{ attributesIndex + 1 }} key </label> <b-form-input :id="`attributes-key-${attributesIndex + 1}`" v-model="attribute.key" size="sm"/> </b-td> <b-td> <label :for="`attribute-values-${attributesIndex + 1}`" style="visibility: hidden; position: fixed; top: -100px;"> Attribute #{{ attributesIndex + 1 }} values </label> <b-form-input :id="`attributes-values-${attributesIndex + 1}`" v-model="attribute.values" size="sm"/> </b-td> <b-td> <b-button variant="link" v-on:click="attribute.deleted = true;"> <b-icon icon="x"></b-icon> </b-button> </b-td> </b-tr> </b-tbody> </b-table-simple> <b-button variant="link" size="sm" v-on:click="attributes.push({key: '', values: '', deleted:false, saved: false})"> Add new attribute </b-button> <!-- <ul v-if="attributes.length > 0" class="list-inline d-inline-block mb-2">--> <!-- <li v-for="(attribute, attributesIndex) in attributes" :key="attributesIndex" class="list-inline-item">--> <!-- <b-form-tag variant="primary" :title="`${attribute.key} = ${attribute.values}`">--> <!-- <div style="display: flex; flex-direction: row;">--> <!-- <label :for="`attributes-${attributesIndex}`">{{ attribute.key }} =</label>--> <!-- <b-form-input :id="`attributes-${attributesIndex}`" v-model="attribute.values"/>--> <!-- </div>--> <!-- </b-form-tag>--> <!-- </li>--> <!-- </ul>--> </table-overlay-info> </div> </div> </div> </b-overlay> </TenantHome> </template> <script> import TenantHome from "./TenantHome"; import store from "../../store"; import TableOverlayInfo from "../overlay/table-overlay-info"; import { VALIDATION_REGEX_EMAIL, VALIDATION_REGEX_FIRST_NAME, VALIDATION_REGEX_LAST_NAME } from "../../../components/validation-regex"; export default { name: "TenantUser", components: {TableOverlayInfo, TenantHome}, store: store, data() { return { processing: false, errors: [], firstName: null, lastName: null, email: null, realmRoles: [], clientRoles: [], attributes: null, // [{key: "a", values: ["1", "2", "3"]}, {key: "b", values: ["fhfhf"]}] rolesToBeDisabled: ["uma_authorization", "offline_access", "admin"], inputFieldsList: ["firstName", "lastName", "email", "realmRoles", "clientRoles", "attributes"] } }, computed: { inputState() { return { username: this.username === null ? null : this.isValid.username, firstName: this.firstName === null ? null : this.isValid.firstName, lastName: this.lastName === null ? null : this.isValid.lastName, email: this.email === null ? null : this.isValid.email, realmRoles: null, clientRoles: null, attributes: null } }, isValid() { return { username: !!this.username && this.username.length > 0, firstName: !!this.firstName && VALIDATION_REGEX_FIRST_NAME.test(this.firstName), lastName: !!this.lastName && VALIDATION_REGEX_LAST_NAME.test(this.lastName), email: !!this.email && VALIDATION_REGEX_EMAIL.test(this.email), realmRoles: true, clientRoles: true, attributes: true } }, title() { if (this.user) { return `${this.user.firstName}, ${this.user.lastName}`; } else { return ""; } }, clientId() { return this.$route.params.clientId; }, username() { return this.$route.params.username; }, user() { return this.$store.getters["user/getUser"]({clientId: this.clientId, username: this.username}) }, tenant() { return this.$store.getters["tenant/getTenant"]({clientId: this.clientId}); }, breadcrumbLinks() { const _breadcrumbLinks = []; if (this.tenant) { _breadcrumbLinks.push({ to: `/tenants/${this.clientId}/users`, name: "Users", disabled: !this.tenant.hasAdminPrivileges }); } if (this.user && this.tenant) { // alert("this.tenant.hasAdminPrivileges " + this.tenant.hasAdminPrivileges) _breadcrumbLinks.push({ to: `/tenants/${this.clientId}/users/${this.username}`, name: this.title, disabled: !this.tenant.hasAdminPrivileges }); } return _breadcrumbLinks; }, deletedAttributes() { return this.attributes ? this.attributes.filter(({saved, deleted}) => saved && deleted) : this.attributes; }, availableAttributes() { return this.attributes ? this.attributes.filter(({deleted}) => !deleted) : this.attributes; }, availableClientRoles() { const _roles = this.$store.getters["tenant/getTenantRoles"]({clientId: this.clientId, clientLevel: true}); if (_roles) { return _roles.map(({name}) => { return { value: name, text: name, disabled: !this.tenant.hasAdminPrivileges } }); } else { return []; } }, availableTenantRoles() { let _roles = this.$store.getters["tenant/getTenantRoles"]({clientId: this.clientId, clientLevel: false}); if (_roles) { _roles = _roles.map(({name}) => { return { value: name, text: name, disabled: !this.tenant.hasAdminPrivileges || this.rolesToBeDisabled.indexOf(name) >= 0 } }); } else { _roles = []; } if (!this.tenant.hasAdminPrivileges) { _roles = _roles.filter(({text}) => ["Tenant Requester"].indexOf(text) >= 0); } return _roles; }, isFormValid() { let _isFormValid = true; for (let i = 0; i < this.inputFieldsList.length; i++) { _isFormValid = _isFormValid && this.isValid[this.inputFieldsList[i]]; } return _isFormValid; } }, methods: { makeFormVisited() { for (let i = 0; i < this.inputFieldsList.length; i++) { if (this[this.inputFieldsList[i]] === null) this[this.inputFieldsList[i]] = ""; } }, async onClickSave() { this.makeFormVisited(); if (this.isFormValid) { this.processing = true; try { if (this.tenant.hasAdminPrivileges) { await this.$store.dispatch("user/updateUser", { clientId: this.clientId, username: this.username, firstName: this.firstName, lastName: this.lastName, email: this.email, realmRoles: this.realmRoles, clientRoles: this.clientRoles, attributes: this.availableAttributes.map(({key, values}) => { return {key: key, values: values.split(",").map(value => value.trim())}; }).filter(({key}) => key.length > 0), deletedAttributes: this.deletedAttributes.map(({key, values}) => { return {key: key, values: values.split(",").map(value => value.trim())}; }).filter(({key}) => key.length > 0) }); } else { await this.$store.dispatch("user/updateUser", { clientId: this.clientId, username: this.username, firstName: this.firstName, lastName: this.lastName, email: this.email, attributes: this.availableAttributes.map(({key, values}) => { return {key: key, values: values.split(",").map(value => value.trim())}; }).filter(({key}) => key.length > 0), deletedAttributes: this.deletedAttributes.map(({key, values}) => { return {key: key, values: values.split(",").map(value => value.trim())}; }).filter(({key}) => key.length > 0) }); } } catch (error) { this.errors.push({ title: "Unknown error when updating the user profile.", source: error, variant: "danger" }); } this.processing = false; } } }, watch: { user() { if (this.user) { this.firstName = this.user.firstName; this.lastName = this.user.lastName; this.email = this.user.email; this.realmRoles = this.user.realmRoles; this.clientRoles = this.user.clientRoles; this.attributes = this.user.attributes.map(({key, values}) => { return {key: key, values: values.join(", "), deleted: false, saved: true}; }); } } } , mounted() { this.$store.dispatch("user/fetchUsers", {clientId: this.clientId, username: this.username}); this.$store.dispatch("tenant/fetchTenantRoles", {clientId: this.clientId, clientLevel: true}); this.$store.dispatch("tenant/fetchTenantRoles", {clientId: this.clientId, clientLevel: false}); if (this.user) { this.firstName = this.user.firstName; this.lastName = this.user.lastName; this.email = this.user.email; this.realmRoles = this.user.realmRoles; this.clientRoles = this.user.clientRoles; this.attributes = this.user.attributes.map(({key, values}) => { return {key: key, values: values.join(", "), deleted: false, saved: true}; }); } } } </script> <style scoped> </style>