Commits (5)
{
"name": "@coscine/usermanagement",
"version": "1.6.0",
"version": "1.6.1",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
......@@ -1297,9 +1297,9 @@
}
},
"@coscine/api-connection": {
"version": "1.18.0",
"resolved": "https://registry.npmjs.org/@coscine/api-connection/-/api-connection-1.18.0.tgz",
"integrity": "sha512-U/BrsZRJGKEpBvvtaoFHT16t4uYqqYRvmkoSjXdNux2xU3tG44AsKFfhJcmcgMup+FrhaW/nkwjdvoJoeulvow==",
"version": "1.20.0",
"resolved": "https://registry.npmjs.org/@coscine/api-connection/-/api-connection-1.20.0.tgz",
"integrity": "sha512-VuKrtlWbik+vwtRmNMju8y/SXXN3pPrA2ovWX7drXJ/qnc0oChm8SiN0fcBBjEq+4/143awI43jgPclDKu0kqA==",
"requires": {
"@types/file-saver": "^2.0.1",
"axios": "^0.19.2",
......@@ -1312,9 +1312,9 @@
"integrity": "sha512-Y58IOiPGoVTNBb0TjikM1Z9W6DYVFTFWxGVI5V8x9bIh2lXSZqoTkql6MHFNIbx/vMq2G/XUxggWdZb2TaGejQ=="
},
"@coscine/component-library": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/@coscine/component-library/-/component-library-1.0.0.tgz",
"integrity": "sha512-+t/a9cONLrQfcLV88ApmQme1egl/XZzA+MxHlXswikhfI0ONzbXnlB9kpKcoCW0KZ4TKn/42ziZKX46Hl+h4cA==",
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/@coscine/component-library/-/component-library-1.1.0.tgz",
"integrity": "sha512-FkaHE0dPPyg52fdK17rygRJ6EiN99gx0acawOC6Ws7vHIFvCIvvFdwD2KenbBbH2ue3qiZtwY+7EPOF6v5g+Aw==",
"requires": {
"@types/jquery": "^3.5.1",
"bootstrap-vue": "^2.16.0",
......@@ -2390,16 +2390,6 @@
"integrity": "sha512-Jus9s4CDbqwocc5pOAnh8ShfrnMcPHuJYzVcSUU7lrh8Ni5HuIqX3oilL86p3dlTrk0LzHRCgA/GQ7uNCw6l2Q==",
"dev": true
},
"@types/mini-css-extract-plugin": {
"version": "0.9.1",
"resolved": "https://registry.npmjs.org/@types/mini-css-extract-plugin/-/mini-css-extract-plugin-0.9.1.tgz",
"integrity": "sha512-+mN04Oszdz9tGjUP/c1ReVwJXxSniLd7lF++sv+8dkABxVNthg6uccei+4ssKxRHGoMmPxdn7uBdJWONSJGTGQ==",
"dev": true,
"optional": true,
"requires": {
"@types/webpack": "*"
}
},
"@types/minimatch": {
"version": "3.0.3",
"resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.3.tgz",
......@@ -7816,9 +7806,9 @@
"dev": true
},
"copy-webpack-plugin": {
"version": "5.1.1",
"resolved": "https://registry.npmjs.org/copy-webpack-plugin/-/copy-webpack-plugin-5.1.1.tgz",
"integrity": "sha512-P15M5ZC8dyCjQHWwd4Ia/dm0SgVvZJMYeykVIVYXbGyqO4dWB5oyPHp9i7wjwo5LhtlhKbiBCdS2NvM07Wlybg==",
"version": "5.1.2",
"resolved": "https://registry.npmjs.org/copy-webpack-plugin/-/copy-webpack-plugin-5.1.2.tgz",
"integrity": "sha512-Uh7crJAco3AjBvgAy9Z75CjK8IG+gxaErro71THQ+vv/bl4HaQcpkexAY8KVW/T6D2W2IRr+couF/knIRkZMIQ==",
"dev": true,
"requires": {
"cacache": "^12.0.3",
......@@ -7831,7 +7821,7 @@
"normalize-path": "^3.0.0",
"p-limit": "^2.2.1",
"schema-utils": "^1.0.0",
"serialize-javascript": "^2.1.2",
"serialize-javascript": "^4.0.0",
"webpack-log": "^2.0.0"
},
"dependencies": {
......@@ -7920,12 +7910,6 @@
"ajv-keywords": "^3.1.0"
}
},
"serialize-javascript": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-2.1.2.tgz",
"integrity": "sha512-rs9OggEUF0V4jUSecXazOYsLfu7OGK2qIn3c7IPBiffz32XniEp/TX9Xmc9LQfK2nQ2QKHvZ2oygKUGU0lG4jQ==",
"dev": true
},
"slash": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/slash/-/slash-1.0.0.tgz",
......@@ -9761,9 +9745,9 @@
}
},
"fork-ts-checker-webpack-plugin-v5": {
"version": "npm:fork-ts-checker-webpack-plugin@5.0.14",
"resolved": "https://registry.npmjs.org/fork-ts-checker-webpack-plugin/-/fork-ts-checker-webpack-plugin-5.0.14.tgz",
"integrity": "sha512-iwRdjgZx1Ll0DAMhmtOF4ffoICpiUxOqOHLrbIHmeCtZiwCrL/qscm+EXOJyzj3a9X8hLRLDEHy9FOyD6Gm42g==",
"version": "npm:fork-ts-checker-webpack-plugin@5.2.0",
"resolved": "https://registry.npmjs.org/fork-ts-checker-webpack-plugin/-/fork-ts-checker-webpack-plugin-5.2.0.tgz",
"integrity": "sha512-NEKcI0+osT5bBFZ1SFGzJMQETjQWZrSvMO1g0nAR/w0t328Z41eN8BJEIZyFCl2HsuiJpa9AN474Nh2qLVwGLQ==",
"dev": true,
"optional": true,
"requires": {
......@@ -9834,9 +9818,9 @@
"optional": true
},
"supports-color": {
"version": "7.1.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz",
"integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==",
"version": "7.2.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
"integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
"dev": true,
"optional": true,
"requires": {
......@@ -13706,9 +13690,9 @@
}
},
"node-fetch": {
"version": "2.6.0",
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.0.tgz",
"integrity": "sha512-8dG4H5ujfvFiqDmVu9fQ5bOHUC15JMjMY/Zumv26oOvvVJjM67KF8koCWIabKQ1GJIa9r2mMZscBq/TbdOcmNA=="
"version": "2.6.1",
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.1.tgz",
"integrity": "sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw=="
},
"node-forge": {
"version": "0.9.0",
......@@ -21691,18 +21675,15 @@
}
},
"vue-loader-v16": {
"version": "npm:vue-loader@16.0.0-beta.5",
"resolved": "https://registry.npmjs.org/vue-loader/-/vue-loader-16.0.0-beta.5.tgz",
"integrity": "sha512-ciWfzNefqWlmzKznCWY9hl+fPP4KlQ0A9MtHbJ/8DpyY+dAM8gDrjufIdxwTgC4szE4EZC3A6ip/BbrqM84GqA==",
"version": "npm:vue-loader@16.0.0-beta.8",
"resolved": "https://registry.npmjs.org/vue-loader/-/vue-loader-16.0.0-beta.8.tgz",
"integrity": "sha512-oouKUQWWHbSihqSD7mhymGPX1OQ4hedzAHyvm8RdyHh6m3oIvoRF+NM45i/bhNOlo8jCnuJhaSUf/6oDjv978g==",
"dev": true,
"optional": true,
"requires": {
"@types/mini-css-extract-plugin": "^0.9.1",
"chalk": "^3.0.0",
"chalk": "^4.1.0",
"hash-sum": "^2.0.0",
"loader-utils": "^1.2.3",
"merge-source-map": "^1.1.0",
"source-map": "^0.6.1"
"loader-utils": "^2.0.0"
},
"dependencies": {
"ansi-styles": {
......@@ -21717,9 +21698,9 @@
}
},
"chalk": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz",
"integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==",
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz",
"integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==",
"dev": true,
"optional": true,
"requires": {
......@@ -21751,10 +21732,22 @@
"dev": true,
"optional": true
},
"loader-utils": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.0.tgz",
"integrity": "sha512-rP4F0h2RaWSvPEkD7BLDFQnvSf+nK+wr3ESUjNTyAGobqrijmW92zc+SO6d4p4B1wh7+B/Jg1mkQe5NYUEHtHQ==",
"dev": true,
"optional": true,
"requires": {
"big.js": "^5.2.2",
"emojis-list": "^3.0.0",
"json5": "^2.1.2"
}
},
"supports-color": {
"version": "7.1.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz",
"integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==",
"version": "7.2.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
"integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
"dev": true,
"optional": true,
"requires": {
......@@ -21764,14 +21757,14 @@
}
},
"vue-loading-overlay": {
"version": "3.3.3",
"resolved": "https://registry.npmjs.org/vue-loading-overlay/-/vue-loading-overlay-3.3.3.tgz",
"integrity": "sha512-wq07DyzqAtQ7A5Q1VPNMGhFLlSWTGAEdzhXgJqN4Xbr/RKpUYvW3EsdRIiwBXKawracJwnV4lTpqS8HrjI20iA=="
"version": "3.4.1",
"resolved": "https://registry.npmjs.org/vue-loading-overlay/-/vue-loading-overlay-3.4.1.tgz",
"integrity": "sha512-NhmVr9pNQMdpFIqHauOlzSpBWlzrPUDUBVu/Q0iyvie7m0aFEjGeHBp3fwBeAVPwIteUL/iYe8nSQuAggbhAfg=="
},
"vue-material-design-icons": {
"version": "4.8.0",
"resolved": "https://registry.npmjs.org/vue-material-design-icons/-/vue-material-design-icons-4.8.0.tgz",
"integrity": "sha512-NNbwK/a14mk92ofBvJa6oBdWi+SO2f27pimoCWziirrbN5Nmt9q0pzELOfvqyy0ncoMJ2BLkd8KfQuXIAhL3Fw=="
"version": "4.9.0",
"resolved": "https://registry.npmjs.org/vue-material-design-icons/-/vue-material-design-icons-4.9.0.tgz",
"integrity": "sha512-g+4dKL2Dk0oHljLoUoeeu41z1moHaUcjEIz5H+ml52KTzimPA86W/kj9/kfbI7Ex24lEMGFAxpD6jU3rEJvlwg=="
},
"vue-runtime-helpers": {
"version": "1.1.2",
......
{
"name": "@coscine/usermanagement",
"version": "1.6.1",
"version": "1.7.0",
"private": true,
"directories": {
"doc": "docs"
......@@ -12,9 +12,9 @@
"test:unit": "vue-cli-service test:unit"
},
"dependencies": {
"@coscine/api-connection": "^1.18.0",
"@coscine/api-connection": "^1.20.0",
"@coscine/app-util": "^1.5.0",
"@coscine/component-library": "1.0.0",
"@coscine/component-library": "1.1.0",
"@types/jquery": "^3.5.1",
"@types/vue-select": "^2.5.0",
"bootstrap-vue": "^2.16.0",
......
<template>
<div id="users">
<h4 style="text-align: left;">{{ $t('userManagement') }}:</h4>
<coscine-headline :headline="$t('userManagement')"></coscine-headline>
<component :is="currentUserComponent" v-bind:parentId="this.projectId" />
</div>
</template>
......@@ -9,6 +9,7 @@
import Vue from 'vue';
import UserManagement from './components/UserManagement.vue';
import { GuidUtil } from '@coscine/app-util';
import { CoscineHeadline } from '@coscine/component-library';
export default Vue.extend({
name: 'users',
......@@ -23,6 +24,7 @@ export default Vue.extend({
},
components: {
UserManagement,
CoscineHeadline,
},
});
</script>
......@@ -35,8 +37,4 @@ export default Vue.extend({
text-align: center;
color: #2c3e50;
}
#users h4 {
color: #000;
font-family: "Avenir", Helvetica, Arial, sans-serif;
}
</style>
<template>
<div class="rolesTable">
<b-table
:id="id"
:fields="headers"
:items="items"
:busy="busy"
:locale="$i18n.locale"
:filter="filter"
:sort-by.sync="sortBy"
:sort-desc.sync="sortDesc"
:show-empty="true"
:empty-text="emptyText"
:empty-filtered-text="emptyFilteredText"
fixed
sticky-header="100%"
no-border-collapse
sort-icon-right
striped
bordered
outlined
hover
head-variant="dark"
@filtered="onFiltered">
<div slot="table-busy" class="text-center text-danger my-2">
<b-spinner class="align-middle"></b-spinner>
<strong style="margin-left: 1%;">{{ $t('loading') }}</strong>
</div>
<template v-slot:cell(roleName)="row">
<b-form-select
v-model="row.item.role.id"
:options="roles"
v-on:change="role(row.item)"
:disabled="!row.item.enabledControls" />
</template>
<template v-slot:cell(actions)="row">
<coscine-delete :btnText="removeText" @delete="deleteItem(row.item)"></coscine-delete>
</template>
</b-table>
</div>
</template>
<script lang="ts">
import Vue from 'vue';
import { CoscineDelete } from '@coscine/component-library';
export default Vue.extend({
name: 'MembersTable',
components: {
CoscineDelete,
},
data() {
return {
sortBy: 'lastName',
sortDesc: false,
filteredRows: 0,
headers: [
{
label: this.$t('firstName'),
key: 'firstName',
sortable: true,
},
{
label: this.$t('lastName'),
key: 'lastName',
sortable: true,
},
{
label: this.$t('email'),
key: 'emailAddress',
sortable: true,
},
{
label: this.$t('role'),
key: 'roleName',
sortable: true,
},
{
label: this.$t('actions'),
key: 'actions',
sortable: true,
},
],
};
},
props: {
id: String,
items: {},
filter: String,
busy: Boolean,
emptyText: String,
emptyFilteredText: String,
removeText: String,
roles: {},
},
methods: {
onFiltered(filteredItems: any) {
this.filteredRows = filteredItems.length;
this.$emit('tableFilteredRows', this.filteredRows);
},
deleteItem(item: any) {
this.$emit('selectedItem', item);
},
role(item: any) {
this.$emit('setRole', item);
},
},
});
</script>
<style>
.rolesTable {
max-height: 65vh;
table-layout: fixed;
border: 1px solid #e5e5e5;
height: 100vh;
}
.rolesTable td, th {
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
vertical-align: middle;
text-align: center;
}
</style>
\ No newline at end of file
......@@ -2,10 +2,10 @@
<div class="UserManagement">
<b-container>
<b-row align-h="between">
<b-col md="6" align-self="start">
<b-col sm="10" align-self="start">
<div class="adaptAlign">
<b-row>
<b-col sm="5" @keydown.enter.prevent.self="">
<b-col sm="5" @keydown.enter.prevent.self="" id="firstCol">
<v-select v-model="searchString" :class="{'adaptSelect':true, 'no-results':(queriedUsers.length === 0)}" :placeholder="$t('searchUserPlaceholder')" :options="queriedUsers" :filterBy="filterMock" @change="validateSelection()" @input="setNewRole" @search="triggerFetchOptions" :selectable="option => !option.hasProjectRole">
<template v-if="searchString !== ''" slot="no-options">
{{ $t('noUserOptions') }}
......@@ -25,7 +25,7 @@
</template>
</v-select>
</b-col>
<b-col sm="3">
<b-col sm="2" id="secondCol">
<b-form-select
v-model="newUserRole.role.id"
:options="roles"
......@@ -33,13 +33,14 @@
@input="validateSelection()">
</b-form-select>
</b-col>
<b-col sm="4">
<button type="button" class="btn btn-secondary" name="setRole" v-on:click="addUser(newUserRole)" :disabled="!selectionIsValid">{{ $t('setRole') }}</button>
<b-col sm="5" id="thirdCol">
<b-button name="setRole" v-on:click="addUser(newUserRole)" :disabled="!selectionIsValid">{{ $t('setRole') }}</b-button>
<b-button name="importUser" v-on:click="$bvModal.show('importUserModal')">{{ $t('importUserButton') }}</b-button>
</b-col>
</b-row>
</div>
</b-col>
<b-col md="4" offset-md="2" align-self="end" @keydown.enter.prevent.self="">
<b-col sm="2" align-self="end" @keydown.enter.prevent.self="" id="forthCol">
<b-input-group>
<b-form-input
v-model="filter"
......@@ -53,78 +54,81 @@
<br>
<b-row>
<b-col>
<b-table
<members-table
id="userTable"
:fields="headers"
:items="projectRoles"
:busy="isBusy"
:locale="$i18n.locale"
:filter="filter"
:per-page="perPage"
:current-page="currentPage"
:sort-by.sync="sortBy"
:sort-desc.sync="sortDesc"
:show-empty="true"
:empty-text="$t('emptyTableText')"
:empty-filtered-text="$t('emptyFilterText')"
sort-icon-right
striped
bordered
outlined
hover
head-variant="dark"
class="adaptTable"
@filtered="onFiltered"
>
<div slot="table-busy" class="text-center text-danger my-2">
<b-spinner class="align-middle"></b-spinner>
<strong style="margin-left: 1%;">{{ $t('loading') }}</strong>
</div>
<template v-slot:cell(roleName)="row">
<b-form-select
v-model="row.item.role.id"
:options="roles"
v-on:change="setRole(row.item)"
:disabled="!row.item.enabledControls"
/>
</template>
<template v-slot:cell(actions)="row">
<button type="button" class="btn btn-secondary deleteUser" :disabled="!row.item.enabledControls" name="deleteUser" v-on:click="prepareDeletion(row.item)">{{ $t('deleteUser') }}</button>
</template>
</b-table>
</b-col>
</b-row>
<b-row>
<b-col id="perPageSelection" sm="2">
<label for="perPageSelect">{{ $t('perPage') }}</label>
<b-form-select
v-model="perPage"
id="perPageSelect"
size="sm"
:options="pageOptions"
></b-form-select>
</b-col>
<b-col v-if="filteredRows > perPage" offset-sm="7" sm="3">
<b-pagination
v-model="currentPage"
:total-rows="filteredRows"
:per-page="perPage"
aria-controls="userTable"
size="sm"
class="rightFloating"
></b-pagination>
:busy="isBusy"
:roles="roles"
:emptyText="$t('emptyTableText')"
:emptyFilteredText="$t('emptyFilterText')"
:removeText="$t('deleteUser')"
@tableFilteredRows="onFilteredRows"
@setRole="setRole"
@selectedItem="prepareDeletion">
</members-table>
</b-col>
</b-row>
</b-container>
<b-modal id="deleteUserModal"
:title="$t('deleteUserTitle')"
@ok = 'deleteUser'
ok-variant="danger"
:ok-title="$t('delete')"
:cancel-title="$t('cancel')">
<div>
{{ $t('deleteUser1') + this.candidateForDeletion.user.displayName + $t('deleteUser2') + this.projectName + $t('deleteUser3')}}
</div>
<b-modal
id="deleteUserModal"
:title="$t('deleteUserTitle')"
@ok = 'deleteUser'
ok-variant="danger"
:ok-title="$t('delete')"
:cancel-title="$t('cancel')">
<div>
{{ $t('deleteUser1') + this.candidateForDeletion.user.displayName + $t('deleteUser2') + this.projectName + $t('deleteUser3')}}
</div>
</b-modal>
<b-modal
id="importUserModal"
:title="$t('importUserTitle')"
@hidden="resetModal"
size="lg"
hide-footer>
<b-row>
<b-col md="4" align-self="start">
<b-form-select
v-model="selectedProject"
@change="setNewRoles" >
<template v-slot:first>
<b-form-select-option :value="null" disabled>{{ $t('searchProjectPlaceholder') }}</b-form-select-option>
</template>
<b-form-select-option v-for="project in additionalProjects" :value="project.id" :key="project.id">
{{ project.projectName }}
</b-form-select-option>
</b-form-select>
</b-col>
</b-row>
<br/>
<b-row>
<b-col>
<div class="modalTable">
<members-table
id="projectRolesTable"
:items="additionalMembers"
:filter="filter"
:busy="isBusy"
:roles="roles"
:emptyText="$t('emptyImportTableText')"
:emptyFilteredText="$t('emptyImportTableFilterText')"
:removeText="$t('removeUser')"
@tableFilteredRows="onFilteredRows"
@selectedItem="removeSelectedRow">
</members-table>
</div>
</b-col>
</b-row>
<br/>
<b-row>
<b-col>
<div align="right">
<b-button name="importUsers" v-on:click="importUser" :disabled="additionalMembers.length === 0">{{ $t('importUserButton') }}</b-button>
</div>
</b-col>
</b-row>
<br/>
</b-modal>
</div>
</template>
......@@ -136,12 +140,16 @@ import { LanguageUtil } from '@coscine/app-util';
import vSelect from 'vue-select';
import 'vue-select/dist/vue-select.css';
import { ToastPlugin } from 'bootstrap-vue';
import MembersTable from './MembersTable.vue';
Vue.use(ToastPlugin);
Vue.component('v-select', vSelect);
export default Vue.extend({
name: 'UserManagement',
components: {
MembersTable,
},
created() {
ProjectApi.getProjectInformation(this.parentId,
(response: any) => {this.projectName = response.data.displayName; });
......@@ -157,9 +165,18 @@ export default Vue.extend({
}
});
this.getProjectRoles();
ProjectApi.getProjects(
(response: any) => {
for (const datum of response.data) {
if (datum.id !== this.parentId) {
this.additionalProjects.push(datum);
}
}
});
},
data() {
return {
selectedProject: null,
sortBy: 'lastName',
sortDesc: false,
headers: [
......@@ -189,15 +206,14 @@ export default Vue.extend({
sortable: true,
},
],
additionalProjects: [] as object[],
additionalMembers: [] as object[],
isBusy: true,
currentPage: 1,
filteredRows: 0,
filter: '',
roleDefaultId: '',
roles: [] as object[],
projectRoles: [] as object[],
perPage: 10,
pageOptions: [10, 25, 50],
newUserRole: {
projectId: '',
user: {
......@@ -254,6 +270,33 @@ export default Vue.extend({
this.newUserRole.user = value;
this.validateSelection();
},
resetModal(value: any) {
this.selectedProject = null;
this.additionalMembers = [];
},
setNewRoles(value: any) {
ProjectRoleApi.getProjectRoles(
value,
(response: any) => {
this.additionalMembers = [];
for (const datum of response.data) {
const found = this.projectRoles.some((el) => (el as any).displayName === datum.user.displayName);
if (!found) {
datum.firstName = datum.user.givenname;
datum.lastName = datum.user.surname;
datum.displayName = datum.user.displayName;
datum.emailAddress = datum.user.emailAddress;
datum.roleName = 'Member';
datum.role.id = this.roleDefaultId;
datum.enabledControls = true;
this.additionalMembers.push(datum);
}
}
this.isBusy = false;
this.filteredRows = this.additionalMembers.length;
},
);
},
triggerFetchOptions(search: string, loading: (value: boolean) => {}) {
clearTimeout(this.queryTimer);
if (search.length < 3) {
......@@ -349,6 +392,16 @@ export default Vue.extend({
}
}
},
importUser() {
this.selectedProject = null;
for (const projectRole of this.additionalMembers) {
(projectRole as any).projectId = this.parentId;
this.addUser(projectRole as any);
}
this.$bvModal.hide('importUserModal');
this.additionalMembers = [];
},
addUser(projectRole: {
projectId: string,
user: { id: string, displayName: string, givenname: string, surname: string, emailAddress: string },
......@@ -395,12 +448,18 @@ export default Vue.extend({
this.getProjectRoles();
this.makeToast(text, this.$t('userManagement').toString()); });
},
removeSelectedRow(projectRole: any) {
const index = this.additionalMembers.indexOf(projectRole);
this.additionalMembers.splice(index, 1);
},
filterMock(option: any, label: any, search: string) {
return search.length > 0;
},
onFiltered(filteredItems: any) {
this.filteredRows = filteredItems.length;
this.currentPage = 1;
},
onFilteredRows(value: any) {
this.filteredRows = value;
},
makeToast(text: string = 'Message', givenTitle: string = 'Title') {
this.$bvToast.toast(
......@@ -421,53 +480,60 @@ export default Vue.extend({
.UserManagement .adaptSelect .vs__dropdown-toggle {
height: calc(1.4em + .75rem + 2px);
}
.UserManagement .adaptTable td {
vertical-align: middle;
}
.UserManagement .adaptAlign .col-sm-5 {
padding-right: 4px;
padding-left: 15px;
.UserManagement .adaptAlign #firstCol {
padding-right: 4px;
padding-left: 15px;
}
.UserManagement .adaptAlign .col-sm-5 .no-results .vs__actions {
display: none;
}
.UserManagement .adaptAlign .col-sm-4 {
padding-right: 4px;
.UserManagement .adaptAlign #secondCol {
padding-right: 4px;
padding-left: 0px;
text-align: left;
}
.UserManagement .adaptAlign .col-sm-4 .btn{
.UserManagement .adaptAlign #thirdCol {
padding-right: 4px;
padding-left: 0px;
text-align: left;
margin-top: 0px;
}
.UserManagement .adaptAlign #thirdCol .btn {
margin: 0px;
margin-right: 4px;
}
.UserManagement .col-sm-3 {
padding-right: 4px;
padding-left: 0px;
.UserManagement .adaptAlign #forthCol {
padding-right: 4px;
padding-left: 0px;
text-align: left;
}
.UserManagement .col-sm-3 #perPageSelect{
padding-right: 4px;
text-align: left;
margin-left: 0px;
padding-left: 0px;
.UserManagement .adaptAlign .col-sm-5 .no-results .vs__actions {
display: none;
}
.UserManagement .adaptTable .deleteUser:hover{
background-color: #9b0517;
border-color: #8e0515;
color: #ffffff;
/* set userImort modal size */
#importUserModal .modal-content {
min-height: 50vh;
margin: 0 auto;
}
.UserManagement #perPageSelection{
text-align: left;
/* place userImort modal to center */
#importUserModal .modal-dialog {
margin: 0 auto;
top: 20vh;
}
.UserManagement #perPageSelection select{
width: max-content;
margin-left: 5px;
#importUserModal .modal-header {
border: 0;
padding-right: 20px;
padding-left: 20px;
}
.UserManagement #perPageSelection label{
width: max-content;
margin-top: auto;
margin-bottom: auto;
#importUserModal .modalTable .rolesTable {
height: 30vh;
text-align: center;
vertical-align: middle;
}
#importUserModal .modal-body {
position: relative;
-webkit-box-flex: 1;
flex: 1 1 auto;
padding: 0px 20px;
}
#importUserModal .btn {
margin: 0px;
}
.modal-header .modal-title {
margin-block-start: 0;
......
......@@ -3,4 +3,4 @@ declare var coscine: {
usermanagement: {},
},
};
declare var _spPageContextInfo: any;
\ No newline at end of file
declare var _spPageContextInfo: any;
......@@ -8,7 +8,7 @@ declare module '@coscine/project-creation';
declare module '@coscine/app-util';
declare module '@coscine/component-library';
declare module "*.png" {
declare module '*.png' {
const value: any;
export default value;
}
\ No newline at end of file
}