diff options
author | rakekniven <2069590+rakekniven@users.noreply.github.com> | 2023-07-29 10:26:56 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-07-29 10:26:56 +0200 |
commit | 7c82c7a4b2de57490b590735bdbeeb4ca0113e9b (patch) | |
tree | 45ba911ee6b4721d40d4e800a24e5b0a81caa5ba /apps/settings/src | |
parent | f4981413faa6de7b9ece14b3c667c0397fe9cf24 (diff) | |
parent | 2b13f50f4a05d98f45f41dd327f7abb49942e6f4 (diff) | |
download | nextcloud-server-7c82c7a4b2de57490b590735bdbeeb4ca0113e9b.tar.gz nextcloud-server-7c82c7a4b2de57490b590735bdbeeb4ca0113e9b.zip |
Merge branch 'master' into rakekniven-patch-2
Signed-off-by: rakekniven <2069590+rakekniven@users.noreply.github.com>
Diffstat (limited to 'apps/settings/src')
-rw-r--r-- | apps/settings/src/components/PersonalInfo/shared/FederationControl.vue | 11 | ||||
-rw-r--r-- | apps/settings/src/components/Users/UserSettingsDialog.vue | 280 | ||||
-rw-r--r-- | apps/settings/src/views/Users.vue | 383 |
3 files changed, 399 insertions, 275 deletions
diff --git a/apps/settings/src/components/PersonalInfo/shared/FederationControl.vue b/apps/settings/src/components/PersonalInfo/shared/FederationControl.vue index 51c4afbe8da..37f50792f97 100644 --- a/apps/settings/src/components/PersonalInfo/shared/FederationControl.vue +++ b/apps/settings/src/components/PersonalInfo/shared/FederationControl.vue @@ -195,17 +195,6 @@ export default { </script> <style lang="scss" scoped> - .federation-actions, - .federation-actions--additional { - opacity: 0.4 !important; - - &:hover, - &:focus, - &:active { - opacity: 0.8 !important; - } - } - .federation-actions--additional { &::v-deep button { // TODO remove this hack diff --git a/apps/settings/src/components/Users/UserSettingsDialog.vue b/apps/settings/src/components/Users/UserSettingsDialog.vue new file mode 100644 index 00000000000..818f5bd9c7f --- /dev/null +++ b/apps/settings/src/components/Users/UserSettingsDialog.vue @@ -0,0 +1,280 @@ +<!-- + - @copyright 2023 Christopher Ng <chrng8@gmail.com> + - + - @author Christopher Ng <chrng8@gmail.com> + - + - @license AGPL-3.0-or-later + - + - This program is free software: you can redistribute it and/or modify + - it under the terms of the GNU Affero General Public License as + - published by the Free Software Foundation, either version 3 of the + - License, or (at your option) any later version. + - + - This program is distributed in the hope that it will be useful, + - but WITHOUT ANY WARRANTY; without even the implied warranty of + - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + - GNU Affero General Public License for more details. + - + - You should have received a copy of the GNU Affero General Public License + - along with this program. If not, see <http://www.gnu.org/licenses/>. + - +--> + +<template> + <NcAppSettingsDialog :open.sync="isModalOpen" + :show-navigation="true" + :title="t('settings', 'User management settings')"> + <NcAppSettingsSection id="visibility-settings" + :title="t('settings', 'Visibility')"> + <NcCheckboxRadioSwitch type="switch" + data-test="showLanguages" + :checked.sync="showLanguages"> + {{ t('settings', 'Show language') }} + </NcCheckboxRadioSwitch> + <NcCheckboxRadioSwitch type="switch" + data-test="showUserBackend" + :checked.sync="showUserBackend"> + {{ t('settings', 'Show user backend') }} + </NcCheckboxRadioSwitch> + <NcCheckboxRadioSwitch type="switch" + data-test="showStoragePath" + :checked.sync="showStoragePath"> + {{ t('settings', 'Show storage path') }} + </NcCheckboxRadioSwitch> + <NcCheckboxRadioSwitch type="switch" + data-test="showLastLogin" + :checked.sync="showLastLogin"> + {{ t('settings', 'Show last login') }} + </NcCheckboxRadioSwitch> + </NcAppSettingsSection> + + <NcAppSettingsSection id="email-settings" + :title="t('settings', 'Send email')"> + <NcCheckboxRadioSwitch type="switch" + data-test="sendWelcomeMail" + :checked.sync="sendWelcomeMail" + :disabled="loadingSendMail"> + {{ t('settings', 'Send welcome email to new users') }} + </NcCheckboxRadioSwitch> + </NcAppSettingsSection> + + <NcAppSettingsSection id="default-settings" + :title="t('settings', 'Defaults')"> + <label for="default-quota-select">{{ t('settings', 'Default quota') }}</label> + <NcSelect v-model="defaultQuota" + input-id="default-quota-select" + placement="top" + :taggable="true" + :options="quotaOptions" + :create-option="validateQuota" + :placeholder="t('settings', 'Select default quota')" + :clearable="false" + @option:selected="setDefaultQuota" /> + </NcAppSettingsSection> + </NcAppSettingsDialog> +</template> + +<script> +import axios from '@nextcloud/axios' +import { generateUrl } from '@nextcloud/router' + +import NcAppSettingsDialog from '@nextcloud/vue/dist/Components/NcAppSettingsDialog.js' +import NcAppSettingsSection from '@nextcloud/vue/dist/Components/NcAppSettingsSection.js' +import NcCheckboxRadioSwitch from '@nextcloud/vue/dist/Components/NcCheckboxRadioSwitch.js' +import NcSelect from '@nextcloud/vue/dist/Components/NcSelect.js' + +import { unlimitedQuota } from '../../utils/userUtils.ts' + +export default { + name: 'UserSettingsDialog', + + components: { + NcAppSettingsDialog, + NcAppSettingsSection, + NcCheckboxRadioSwitch, + NcSelect, + }, + + props: { + open: { + type: Boolean, + required: true, + }, + }, + + data() { + return { + selectedQuota: false, + loadingSendMail: false, + } + }, + + computed: { + isModalOpen: { + get() { + return this.open + }, + set(open) { + this.$emit('update:open', open) + }, + }, + + showConfig() { + return this.$store.getters.getShowConfig + }, + + settings() { + return this.$store.getters.getServerData + }, + + showLanguages: { + get() { + return this.getLocalstorage('showLanguages') + }, + set(status) { + this.setLocalStorage('showLanguages', status) + }, + }, + + showLastLogin: { + get() { + return this.getLocalstorage('showLastLogin') + }, + set(status) { + this.setLocalStorage('showLastLogin', status) + }, + }, + + showUserBackend: { + get() { + return this.getLocalstorage('showUserBackend') + }, + set(status) { + this.setLocalStorage('showUserBackend', status) + }, + }, + + showStoragePath: { + get() { + return this.getLocalstorage('showStoragePath') + }, + set(status) { + this.setLocalStorage('showStoragePath', status) + }, + }, + + quotaOptions() { + // convert the preset array into objects + const quotaPreset = this.settings.quotaPreset.reduce((acc, cur) => acc.concat({ id: cur, label: cur }), []) + // add default presets + if (this.settings.allowUnlimitedQuota) { + quotaPreset.unshift(unlimitedQuota) + } + return quotaPreset + }, + + defaultQuota: { + get() { + if (this.selectedQuota !== false) { + return this.selectedQuota + } + if (this.settings.defaultQuota !== unlimitedQuota.id && OC.Util.computerFileSize(this.settings.defaultQuota) >= 0) { + // if value is valid, let's map the quotaOptions or return custom quota + return { id: this.settings.defaultQuota, label: this.settings.defaultQuota } + } + return unlimitedQuota // unlimited + }, + set(quota) { + this.selectedQuota = quota + }, + }, + + sendWelcomeMail: { + get() { + return this.settings.newUserSendEmail + }, + async set(value) { + try { + this.loadingSendMail = true + this.$store.commit('setServerData', { + ...this.settings, + newUserSendEmail: value, + }) + await axios.post(generateUrl('/settings/users/preferences/newUser.sendEmail'), { value: value ? 'yes' : 'no' }) + } catch (e) { + console.error('could not update newUser.sendEmail preference: ' + e.message, e) + } finally { + this.loadingSendMail = false + } + }, + }, + }, + + methods: { + getLocalstorage(key) { + // force initialization + const localConfig = this.$localStorage.get(key) + // if localstorage is null, fallback to original values + this.$store.commit('setShowConfig', { key, value: localConfig !== null ? localConfig === 'true' : this.showConfig[key] }) + return this.showConfig[key] + }, + + setLocalStorage(key, status) { + this.$store.commit('setShowConfig', { key, value: status }) + this.$localStorage.set(key, status) + return status + }, + + /** + * Validate quota string to make sure it's a valid human file size + * + * @param {string | object} quota Quota in readable format '5 GB' or Object {id: '5 GB', label: '5GB'} + * @return {object} The validated quota object or unlimited quota if input is invalid + */ + validateQuota(quota) { + if (typeof quota === 'object') { + quota = quota?.id || quota.label + } + // only used for new presets sent through @Tag + const validQuota = OC.Util.computerFileSize(quota) + if (validQuota === null) { + return unlimitedQuota + } else { + // unify format output + quota = OC.Util.humanFileSize(OC.Util.computerFileSize(quota)) + return { id: quota, label: quota } + } + }, + + /** + * Dispatch default quota set request + * + * @param {string | object} quota Quota in readable format '5 GB' or Object {id: '5 GB', label: '5GB'} + */ + setDefaultQuota(quota = 'none') { + // Make sure correct label is set for unlimited quota + if (quota === 'none') { + quota = unlimitedQuota + } + this.$store.dispatch('setAppConfig', { + app: 'files', + key: 'default_quota', + // ensure we only send the preset id + value: quota.id ? quota.id : quota, + }).then(() => { + if (typeof quota !== 'object') { + quota = { id: quota, label: quota } + } + this.defaultQuota = quota + }) + }, + }, +} +</script> + +<style lang="scss" scoped> +label[for="default-quota-select"] { + display: block; + padding: 4px 0; +} +</style> diff --git a/apps/settings/src/views/Users.vue b/apps/settings/src/views/Users.vue index e1f26ea6ea3..449308104ea 100644 --- a/apps/settings/src/views/Users.vue +++ b/apps/settings/src/views/Users.vue @@ -21,123 +21,102 @@ --> <template> - <NcContent app-name="settings" :navigation-class="{ 'icon-loading': loadingAddGroup }"> - <NcAppNavigation> - <NcAppNavigationNew button-id="new-user-button" - :text="t('settings','New user')" - button-class="icon-add" - @click="showNewUserMenu" - @keyup.enter="showNewUserMenu" - @keyup.space="showNewUserMenu" /> - <template #list> - <NcAppNavigationNewItem id="addgroup" - ref="addGroup" - :edit-placeholder="t('settings', 'Enter group name')" - :editable="true" - :loading="loadingAddGroup" - :title="t('settings', 'Add group')" - @click="showAddGroupForm" - @new-item="createGroup"> - <template #icon> - <Plus :size="20" /> - </template> - </NcAppNavigationNewItem> - <NcAppNavigationItem id="everyone" - :exact="true" - :title="t('settings', 'Active users')" - :to="{ name: 'users' }" - icon="icon-contacts-dark"> - <template #counter> - <NcCounterBubble :type="!selectedGroupDecoded ? 'highlighted' : undefined"> - {{ userCount }} - </NcCounterBubble> - </template> - </NcAppNavigationItem> - <NcAppNavigationItem v-if="settings.isAdmin" - id="admin" - :exact="true" - :title="t('settings', 'Admins')" - :to="{ name: 'group', params: { selectedGroup: 'admin' } }" - icon="icon-user-admin"> - <template v-if="adminGroupMenu.count > 0" #counter> - <NcCounterBubble :type="selectedGroupDecoded === 'admin' ? 'highlighted' : undefined"> - {{ adminGroupMenu.count }} - </NcCounterBubble> - </template> - </NcAppNavigationItem> - - <!-- Hide the disabled if none, if we don't have the data (-1) show it --> - <NcAppNavigationItem v-if="disabledGroupMenu.usercount > 0 || disabledGroupMenu.usercount === -1" - id="disabled" - :exact="true" - :title="t('settings', 'Disabled users')" - :to="{ name: 'group', params: { selectedGroup: 'disabled' } }" - icon="icon-disabled-users"> - <template v-if="disabledGroupMenu.usercount > 0" #counter> - <NcCounterBubble :type="selectedGroupDecoded === 'disabled' ? 'highlighted' : undefined"> - {{ disabledGroupMenu.usercount }} - </NcCounterBubble> - </template> - </NcAppNavigationItem> - - <NcAppNavigationCaption v-if="groupList.length > 0" :title="t('settings', 'Groups')" /> - <GroupListItem v-for="group in groupList" - :id="group.id" - :key="group.id" - :active="selectedGroupDecoded === group.id" - :title="group.title" - :count="group.count" /> - </template> - <template #footer> - <NcAppNavigationSettings exclude-click-outside-selectors=".vs__dropdown-menu"> - <label for="default-quota-select">{{ t('settings', 'Default quota:') }}</label> - <NcSelect v-model="defaultQuota" - input-id="default-quota-select" - :taggable="true" - :options="quotaOptions" - :create-option="validateQuota" - :placeholder="t('settings', 'Select default quota')" - :clearable="false" - @option:selected="setDefaultQuota" /> - <NcCheckboxRadioSwitch type="switch" - data-test="showLanguages" - :checked.sync="showLanguages"> - {{ t('settings', 'Show languages') }} - </NcCheckboxRadioSwitch> - <NcCheckboxRadioSwitch type="switch" - data-test="showLastLogin" - :checked.sync="showLastLogin"> - {{ t('settings', 'Show last login') }} - </NcCheckboxRadioSwitch> - <NcCheckboxRadioSwitch type="switch" - data-test="showUserBackend" - :checked.sync="showUserBackend"> - {{ t('settings', 'Show user backend') }} - </NcCheckboxRadioSwitch> - <NcCheckboxRadioSwitch type="switch" - data-test="showStoragePath" - :checked.sync="showStoragePath"> - {{ t('settings', 'Show storage path') }} - </NcCheckboxRadioSwitch> - <NcCheckboxRadioSwitch type="switch" - data-test="sendWelcomeMail" - :checked.sync="sendWelcomeMail" - :disabled="loadingSendMail"> - {{ t('settings', 'Send email to new user') }} - </NcCheckboxRadioSwitch> - </NcAppNavigationSettings> - </template> - </NcAppNavigation> - <NcAppContent> - <UserList :selected-group="selectedGroupDecoded" - :external-actions="externalActions" /> - </NcAppContent> - </NcContent> + <Fragment> + <NcContent app-name="settings" :navigation-class="{ 'icon-loading': loadingAddGroup }"> + <NcAppNavigation> + <NcAppNavigationNew button-id="new-user-button" + :text="t('settings','New user')" + button-class="icon-add" + @click="showNewUserMenu" + @keyup.enter="showNewUserMenu" + @keyup.space="showNewUserMenu" /> + + <template #list> + <NcAppNavigationNewItem id="addgroup" + ref="addGroup" + :edit-placeholder="t('settings', 'Enter group name')" + :editable="true" + :loading="loadingAddGroup" + :title="t('settings', 'Add group')" + @click="showAddGroupForm" + @new-item="createGroup"> + <template #icon> + <Plus :size="20" /> + </template> + </NcAppNavigationNewItem> + <NcAppNavigationItem id="everyone" + :exact="true" + :title="t('settings', 'Active users')" + :to="{ name: 'users' }" + icon="icon-contacts-dark"> + <template #counter> + <NcCounterBubble :type="!selectedGroupDecoded ? 'highlighted' : undefined"> + {{ userCount }} + </NcCounterBubble> + </template> + </NcAppNavigationItem> + <NcAppNavigationItem v-if="settings.isAdmin" + id="admin" + :exact="true" + :title="t('settings', 'Admins')" + :to="{ name: 'group', params: { selectedGroup: 'admin' } }" + icon="icon-user-admin"> + <template v-if="adminGroupMenu.count > 0" #counter> + <NcCounterBubble :type="selectedGroupDecoded === 'admin' ? 'highlighted' : undefined"> + {{ adminGroupMenu.count }} + </NcCounterBubble> + </template> + </NcAppNavigationItem> + + <!-- Hide the disabled if none, if we don't have the data (-1) show it --> + <NcAppNavigationItem v-if="disabledGroupMenu.usercount > 0 || disabledGroupMenu.usercount === -1" + id="disabled" + :exact="true" + :title="t('settings', 'Disabled users')" + :to="{ name: 'group', params: { selectedGroup: 'disabled' } }" + icon="icon-disabled-users"> + <template v-if="disabledGroupMenu.usercount > 0" #counter> + <NcCounterBubble :type="selectedGroupDecoded === 'disabled' ? 'highlighted' : undefined"> + {{ disabledGroupMenu.usercount }} + </NcCounterBubble> + </template> + </NcAppNavigationItem> + + <NcAppNavigationCaption v-if="groupList.length > 0" :title="t('settings', 'Groups')" /> + <GroupListItem v-for="group in groupList" + :id="group.id" + :key="group.id" + :active="selectedGroupDecoded === group.id" + :title="group.title" + :count="group.count" /> + </template> + + <template #footer> + <ul class="app-navigation-entry__settings"> + <NcAppNavigationItem :title="t('settings', 'User management settings')" + @click="isDialogOpen = true"> + <template #icon> + <Cog :size="20" /> + </template> + </NcAppNavigationItem> + </ul> + </template> + </NcAppNavigation> + + <NcAppContent> + <UserList :selected-group="selectedGroupDecoded" + :external-actions="externalActions" /> + </NcAppContent> + </NcContent> + + <UserSettingsDialog :open.sync="isDialogOpen" /> + </Fragment> </template> <script> import Vue from 'vue' import VueLocalStorage from 'vue-localstorage' +import { Fragment } from 'vue-frag' import NcAppContent from '@nextcloud/vue/dist/Components/NcAppContent.js' import NcAppNavigation from '@nextcloud/vue/dist/Components/NcAppNavigation.js' @@ -145,26 +124,24 @@ import NcAppNavigationCaption from '@nextcloud/vue/dist/Components/NcAppNavigati import NcAppNavigationItem from '@nextcloud/vue/dist/Components/NcAppNavigationItem.js' import NcAppNavigationNew from '@nextcloud/vue/dist/Components/NcAppNavigationNew.js' import NcAppNavigationNewItem from '@nextcloud/vue/dist/Components/NcAppNavigationNewItem.js' -import NcAppNavigationSettings from '@nextcloud/vue/dist/Components/NcAppNavigationSettings.js' -import NcCheckboxRadioSwitch from '@nextcloud/vue/dist/Components/NcCheckboxRadioSwitch.js' -import NcCounterBubble from '@nextcloud/vue/dist/Components/NcCounterBubble.js' import NcContent from '@nextcloud/vue/dist/Components/NcContent.js' -import NcSelect from '@nextcloud/vue/dist/Components/NcSelect.js' +import NcCounterBubble from '@nextcloud/vue/dist/Components/NcCounterBubble.js' +import Cog from 'vue-material-design-icons/Cog.vue' import Plus from 'vue-material-design-icons/Plus.vue' -import axios from '@nextcloud/axios' -import { generateUrl } from '@nextcloud/router' - import GroupListItem from '../components/GroupListItem.vue' import UserList from '../components/UserList.vue' -import { unlimitedQuota } from '../utils/userUtils.ts' +import UserSettingsDialog from '../components/Users/UserSettingsDialog.vue' Vue.use(VueLocalStorage) export default { name: 'Users', + components: { + Cog, + Fragment, GroupListItem, NcAppContent, NcAppNavigation, @@ -172,138 +149,62 @@ export default { NcAppNavigationItem, NcAppNavigationNew, NcAppNavigationNewItem, - NcAppNavigationSettings, - NcCheckboxRadioSwitch, - NcCounterBubble, NcContent, - NcSelect, + NcCounterBubble, Plus, UserList, + UserSettingsDialog, }, + props: { selectedGroup: { type: String, default: null, }, }, + data() { return { // temporary value used for multiselect change - selectedQuota: false, externalActions: [], loadingAddGroup: false, - loadingSendMail: false, + isDialogOpen: false, } }, + computed: { showConfig() { return this.$store.getters.getShowConfig }, + selectedGroupDecoded() { return this.selectedGroup ? decodeURIComponent(this.selectedGroup) : null }, + users() { return this.$store.getters.getUsers }, + groups() { return this.$store.getters.getGroups }, + usersOffset() { return this.$store.getters.getUsersOffset }, + usersLimit() { return this.$store.getters.getUsersLimit }, - // Local settings - showLanguages: { - get() { - return this.getLocalstorage('showLanguages') - }, - set(status) { - this.setLocalStorage('showLanguages', status) - }, - }, - showLastLogin: { - get() { - return this.getLocalstorage('showLastLogin') - }, - set(status) { - this.setLocalStorage('showLastLogin', status) - }, - }, - showUserBackend: { - get() { - return this.getLocalstorage('showUserBackend') - }, - set(status) { - this.setLocalStorage('showUserBackend', status) - }, - }, - showStoragePath: { - get() { - return this.getLocalstorage('showStoragePath') - }, - set(status) { - this.setLocalStorage('showStoragePath', status) - }, - }, - userCount() { return this.$store.getters.getUserCount }, + settings() { return this.$store.getters.getServerData }, - // default quota - quotaOptions() { - // convert the preset array into objects - const quotaPreset = this.settings.quotaPreset.reduce((acc, cur) => acc.concat({ id: cur, label: cur }), []) - // add default presets - if (this.settings.allowUnlimitedQuota) { - quotaPreset.unshift(unlimitedQuota) - } - return quotaPreset - }, - // mapping saved values to objects - defaultQuota: { - get() { - if (this.selectedQuota !== false) { - return this.selectedQuota - } - if (this.settings.defaultQuota !== unlimitedQuota.id && OC.Util.computerFileSize(this.settings.defaultQuota) >= 0) { - // if value is valid, let's map the quotaOptions or return custom quota - return { id: this.settings.defaultQuota, label: this.settings.defaultQuota } - } - return unlimitedQuota // unlimited - }, - set(quota) { - this.selectedQuota = quota - }, - - }, - - sendWelcomeMail: { - get() { - return this.settings.newUserSendEmail - }, - async set(value) { - try { - this.loadingSendMail = true - this.$store.commit('setServerData', { - ...this.settings, - newUserSendEmail: value, - }) - await axios.post(generateUrl('/settings/users/preferences/newUser.sendEmail'), { value: value ? 'yes' : 'no' }) - } catch (e) { - console.error('could not update newUser.sendEmail preference: ' + e.message, e) - } finally { - this.loadingSendMail = false - } - }, - }, - groupList() { const groups = Array.isArray(this.groups) ? this.groups : [] @@ -316,10 +217,12 @@ export default { adminGroupMenu() { return this.formatGroupMenu(this.groups.find(group => group.id === 'admin')) }, + disabledGroupMenu() { return this.formatGroupMenu(this.groups.find(group => group.id === 'disabled')) }, }, + beforeMount() { this.$store.commit('initGroups', { groups: this.$store.getters.getServerData.groups, @@ -328,6 +231,7 @@ export default { }) this.$store.dispatch('getPasswordPolicyMinLength') }, + created() { // init the OCA.Settings.UserList object // and add the registerAction method @@ -339,6 +243,7 @@ export default { }, }) }, + methods: { showNewUserMenu() { this.$store.commit('setShowConfig', { @@ -346,62 +251,6 @@ export default { value: true, }) }, - getLocalstorage(key) { - // force initialization - const localConfig = this.$localStorage.get(key) - // if localstorage is null, fallback to original values - this.$store.commit('setShowConfig', { key, value: localConfig !== null ? localConfig === 'true' : this.showConfig[key] }) - return this.showConfig[key] - }, - setLocalStorage(key, status) { - this.$store.commit('setShowConfig', { key, value: status }) - this.$localStorage.set(key, status) - return status - }, - - /** - * Dispatch default quota set request - * - * @param {string | object} quota Quota in readable format '5 GB' or Object {id: '5 GB', label: '5GB'} - */ - setDefaultQuota(quota = 'none') { - // Make sure correct label is set for unlimited quota - if (quota === 'none') { - quota = unlimitedQuota - } - this.$store.dispatch('setAppConfig', { - app: 'files', - key: 'default_quota', - // ensure we only send the preset id - value: quota.id ? quota.id : quota, - }).then(() => { - if (typeof quota !== 'object') { - quota = { id: quota, label: quota } - } - this.defaultQuota = quota - }) - }, - - /** - * Validate quota string to make sure it's a valid human file size - * - * @param {string | object} quota Quota in readable format '5 GB' or Object {id: '5 GB', label: '5GB'} - * @return {object} The validated quota object or unlimited quota if input is invalid - */ - validateQuota(quota) { - if (typeof quota === 'object') { - quota = quota?.id || quota.label - } - // only used for new presets sent through @Tag - const validQuota = OC.Util.computerFileSize(quota) - if (validQuota === null) { - return unlimitedQuota - } else { - // unify format output - quota = OC.Util.humanFileSize(OC.Util.computerFileSize(quota)) - return { id: quota, label: quota } - } - }, /** * Register a new action for the user menu @@ -501,4 +350,10 @@ export default { .app-navigation__list #addgroup::v-deep .app-navigation-entry__utils { display: none; } + +.app-navigation-entry__settings { + height: auto !important; + // Prevent shrinking or growing + flex: 0 0 auto; +} </style> |