Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/nextcloud/server.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSimounet <contact@simounet.net>2020-10-16 21:40:17 +0300
committerSimounet <contact@simounet.net>2021-04-21 15:42:46 +0300
commit45c3b2a478c10136e27b70f4cb439612ca5babb9 (patch)
treecf6a7ef1fac94929625677d086116785c5e024c9 /apps/settings/src
parentd2ea068552eb144d491b76e0a0ef8266144dcf45 (diff)
Settings: new user row replaced by a modal
Signed-off-by: Simounet <contact@simounet.net>
Diffstat (limited to 'apps/settings/src')
-rw-r--r--apps/settings/src/components/UserList.vue239
-rw-r--r--apps/settings/src/views/Users.vue8
2 files changed, 135 insertions, 112 deletions
diff --git a/apps/settings/src/components/UserList.vue b/apps/settings/src/components/UserList.vue
index 506d9538a50..7e40304e2ec 100644
--- a/apps/settings/src/components/UserList.vue
+++ b/apps/settings/src/components/UserList.vue
@@ -22,14 +22,12 @@
<template>
<div id="app-content" class="user-list-grid" @scroll.passive="onScroll">
- <form v-show="showConfig.showNewUserForm"
- id="new-user"
- :class="{'sticky': scrolled && showConfig.showNewUserForm}"
- :disabled="loading.all"
- class="row"
- @submit.prevent="createUser">
- <div :class="loading.all?'icon-loading-small':'icon-add'" />
- <div class="name">
+ <Modal v-if="showConfig.showNewUserForm" @close="closeModal">
+ <form id="new-user"
+ :disabled="loading.all"
+ class="modal__content"
+ @submit.prevent="createUser">
+ <h2>{{ t('settings','New user') }}</h2>
<input id="newusername"
ref="newusername"
v-model="newUser.id"
@@ -40,22 +38,20 @@
autocapitalize="none"
autocomplete="off"
autocorrect="off"
+ class="modal__item"
name="username"
pattern="[a-zA-Z0-9 _\.@\-']+"
required
type="text">
- <div class="displayName">
- <input id="newdisplayname"
- v-model="newUser.displayName"
- :placeholder="t('settings', 'Display name')"
- autocapitalize="none"
- autocomplete="off"
- autocorrect="off"
- name="displayname"
- type="text">
- </div>
- </div>
- <div class="password">
+ <input id="newdisplayname"
+ v-model="newUser.displayName"
+ :placeholder="t('settings', 'Display name')"
+ autocapitalize="none"
+ autocomplete="off"
+ autocorrect="off"
+ class="modal__item"
+ name="displayname"
+ type="text">
<input id="newuserpassword"
ref="newuserpassword"
v-model="newUser.password"
@@ -65,10 +61,9 @@
autocapitalize="none"
autocomplete="new-password"
autocorrect="off"
+ class="modal__item"
name="password"
type="password">
- </div>
- <div class="mailAddress">
<input id="newemail"
v-model="newUser.mailAddress"
:placeholder="t('settings', 'Email')"
@@ -76,91 +71,86 @@
autocapitalize="none"
autocomplete="off"
autocorrect="off"
+ class="modal__item"
name="email"
type="email">
- </div>
- <div class="groups">
- <!-- hidden input trick for vanilla html5 form validation -->
- <input v-if="!settings.isAdmin"
- id="newgroups"
- :class="{'icon-loading-small': loading.groups}"
- :required="!settings.isAdmin"
- :value="newUser.groups"
- tabindex="-1"
- type="text">
- <Multiselect v-model="newUser.groups"
- :close-on-select="false"
- :disabled="loading.groups||loading.all"
- :multiple="true"
- :options="canAddGroups"
- :placeholder="t('settings', 'Add user to group')"
- :tag-width="60"
- :taggable="true"
- class="multiselect-vue"
- label="name"
- tag-placeholder="create"
- track-by="id"
- @tag="createGroup">
- <!-- If user is not admin, he is a subadmin.
- Subadmins can't create users outside their groups
- Therefore, empty select is forbidden -->
- <span slot="noResult">{{ t('settings', 'No results') }}</span>
- </Multiselect>
- </div>
- <div v-if="subAdminsGroups.length>0 && settings.isAdmin"
- class="subadmins">
- <Multiselect v-model="newUser.subAdminsGroups"
- :close-on-select="false"
- :multiple="true"
- :options="subAdminsGroups"
- :placeholder="t('settings', 'Set user as admin for')"
- :tag-width="60"
- class="multiselect-vue"
- label="name"
- track-by="id">
- <span slot="noResult">{{ t('settings', 'No results') }}</span>
- </Multiselect>
- </div>
- <div class="quota">
- <Multiselect v-model="newUser.quota"
- :allow-empty="false"
- :options="quotaOptions"
- :placeholder="t('settings', 'Select user quota')"
- :taggable="true"
- class="multiselect-vue"
- label="label"
- track-by="id"
- @tag="validateQuota" />
- </div>
- <div v-if="showConfig.showLanguages" class="languages">
- <Multiselect v-model="newUser.language"
- :allow-empty="false"
- :options="languages"
- :placeholder="t('settings', 'Default language')"
- class="multiselect-vue"
- group-label="label"
- group-values="languages"
- label="name"
- track-by="code" />
- </div>
- <div v-if="showConfig.showStoragePath" class="storageLocation" />
- <div v-if="showConfig.showUserBackend" class="userBackend" />
- <div v-if="showConfig.showLastLogin" class="lastLogin" />
- <div class="userActions">
- <input id="newsubmit"
- :title="t('settings', 'Add a new user')"
- class="button primary icon-checkmark-white has-tooltip"
- type="submit"
- value="">
- <div class="closeButton">
- <Actions>
- <ActionButton icon="icon-close" @click="onClose">
- {{ t('settings', 'Close') }}
- </ActionButton>
- </Actions>
+ <div class="groups modal__item">
+ <!-- hidden input trick for vanilla html5 form validation -->
+ <input v-if="!settings.isAdmin"
+ id="newgroups"
+ :class="{'icon-loading-small': loading.groups}"
+ :required="!settings.isAdmin"
+ :value="newUser.groups"
+ tabindex="-1"
+ type="text">
+ <Multiselect v-model="newUser.groups"
+ :close-on-select="false"
+ :disabled="loading.groups||loading.all"
+ :multiple="true"
+ :options="canAddGroups"
+ :placeholder="t('settings', 'Add user to group')"
+ :tag-width="60"
+ :taggable="true"
+ class="multiselect-vue"
+ label="name"
+ tag-placeholder="create"
+ track-by="id"
+ @tag="createGroup">
+ <!-- If user is not admin, he is a subadmin.
+ Subadmins can't create users outside their groups
+ Therefore, empty select is forbidden -->
+ <span slot="noResult">{{ t('settings', 'No results') }}</span>
+ </Multiselect>
</div>
- </div>
- </form>
+ <div v-if="subAdminsGroups.length>0 && settings.isAdmin"
+ class="subadmins modal__item">
+ <Multiselect v-model="newUser.subAdminsGroups"
+ :close-on-select="false"
+ :multiple="true"
+ :options="subAdminsGroups"
+ :placeholder="t('settings', 'Set user as admin for')"
+ :tag-width="60"
+ class="multiselect-vue"
+ label="name"
+ track-by="id">
+ <span slot="noResult">{{ t('settings', 'No results') }}</span>
+ </Multiselect>
+ </div>
+ <div class="quota modal__item">
+ <Multiselect v-model="newUser.quota"
+ :allow-empty="false"
+ :options="quotaOptions"
+ :placeholder="t('settings', 'Select user quota')"
+ :taggable="true"
+ class="multiselect-vue"
+ label="label"
+ track-by="id"
+ @tag="validateQuota" />
+ </div>
+ <div v-if="showConfig.showLanguages" class="languages modal__item">
+ <Multiselect v-model="newUser.language"
+ :allow-empty="false"
+ :options="languages"
+ :placeholder="t('settings', 'Default language')"
+ class="multiselect-vue"
+ group-label="label"
+ group-values="languages"
+ label="name"
+ track-by="code" />
+ </div>
+ <div v-if="showConfig.showStoragePath" class="storageLocation" />
+ <div v-if="showConfig.showUserBackend" class="userBackend" />
+ <div v-if="showConfig.showLastLogin" class="lastLogin" />
+ <div class="user-actions">
+ <button id="newsubmit"
+ class="button primary"
+ type="submit"
+ value="">
+ {{ t('settings', 'Add a new user') }}
+ </button>
+ </div>
+ </form>
+ </Modal>
<div id="grid-header"
:class="{'sticky': scrolled && !showConfig.showNewUserForm}"
class="row">
@@ -244,10 +234,9 @@
import { subscribe, unsubscribe } from '@nextcloud/event-bus'
import InfiniteLoading from 'vue-infinite-loading'
import Vue from 'vue'
+import { Modal } from '@nextcloud/vue'
import Multiselect from '@nextcloud/vue/dist/Components/Multiselect'
-import Actions from '@nextcloud/vue/dist/Components/Actions'
-import ActionButton from '@nextcloud/vue/dist/Components/ActionButton'
import userRow from './UserList/UserRow'
@@ -276,11 +265,10 @@ const newUser = {
export default {
name: 'UserList',
components: {
+ Modal,
userRow,
Multiselect,
InfiniteLoading,
- Actions,
- ActionButton,
},
props: {
users: {
@@ -522,6 +510,7 @@ export default {
.then(() => {
this.resetForm()
this.$refs.newusername.focus()
+ this.closeModal()
})
.catch((error) => {
this.loading.all = false
@@ -584,13 +573,45 @@ export default {
this.$refs.infiniteLoading.stateChanger.reset()
}
},
- onClose() {
+ closeModal() {
this.showConfig.showNewUserForm = false
},
},
}
</script>
<style scoped>
+ .modal-wrapper {
+ margin: 2vh 0;
+ align-items: flex-start;
+ }
+ .modal__content {
+ display: flex;
+ padding: 20px;
+ flex-direction: column;
+ align-items: center;
+ text-align: center;
+ overflow: auto;
+ }
+ .modal__item {
+ margin-bottom: 16px;
+ width: 100%;
+ }
+ .modal__item:not(:focus):not(:active) {
+ border-color: var(--color-border-dark);
+ }
+ .modal__item::v-deep .multiselect {
+ width: 100%;
+ }
+ .user-actions {
+ margin-top: 20px;
+ }
+ .modal__content::v-deep .multiselect__single {
+ text-align: left;
+ box-sizing: border-box;
+ }
+ .modal__content::v-deep .multiselect__content-wrapper {
+ box-sizing: border-box;
+ }
.row::v-deep .multiselect__single {
z-index: auto !important;
}
diff --git a/apps/settings/src/views/Users.vue b/apps/settings/src/views/Users.vue
index 95a8faf1516..ba739d1050b 100644
--- a/apps/settings/src/views/Users.vue
+++ b/apps/settings/src/views/Users.vue
@@ -26,7 +26,9 @@
<AppNavigationNew button-id="new-user-button"
:text="t('settings','New user')"
button-class="icon-add"
- @click="toggleNewUserMenu" />
+ @click="showNewUserMenu"
+ @keyup.enter="showNewUserMenu"
+ @keyup.space="showNewUserMenu" />
<template #list>
<AppNavigationItem
id="addgroup"
@@ -348,8 +350,8 @@ export default {
})
},
methods: {
- toggleNewUserMenu() {
- this.showConfig.showNewUserForm = !this.showConfig.showNewUserForm
+ showNewUserMenu() {
+ this.showConfig.showNewUserForm = true
if (this.showConfig.showNewUserForm) {
Vue.nextTick(() => {
window.newusername.focus()