aboutsummaryrefslogtreecommitdiffstats
path: root/apps/settings/src
diff options
context:
space:
mode:
Diffstat (limited to 'apps/settings/src')
-rw-r--r--apps/settings/src/components/AppNavigationGroupList.vue18
-rw-r--r--apps/settings/src/components/PersonalInfo/FediverseSection.vue9
-rw-r--r--apps/settings/src/components/PersonalInfo/TwitterSection.vue4
-rw-r--r--apps/settings/src/components/UserList.vue6
-rw-r--r--apps/settings/src/components/Users/NewUserDialog.vue17
-rw-r--r--apps/settings/src/store/apps.js3
-rw-r--r--apps/settings/src/store/users.js19
7 files changed, 56 insertions, 20 deletions
diff --git a/apps/settings/src/components/AppNavigationGroupList.vue b/apps/settings/src/components/AppNavigationGroupList.vue
index b32a07bc9b8..5c648a17098 100644
--- a/apps/settings/src/components/AppNavigationGroupList.vue
+++ b/apps/settings/src/components/AppNavigationGroupList.vue
@@ -57,12 +57,16 @@
</template>
<script setup lang="ts">
+import type CancelablePromise from 'cancelable-promise'
+import type { IGroup } from '../views/user-types.d.ts'
+
+import { mdiAccountGroup, mdiPlus } from '@mdi/js'
+import { showError } from '@nextcloud/dialogs'
+import { t } from '@nextcloud/l10n'
+import { useElementVisibility } from '@vueuse/core'
import { computed, ref, watch, onBeforeMount } from 'vue'
import { Fragment } from 'vue-frag'
import { useRoute, useRouter } from 'vue-router/composables'
-import { useElementVisibility } from '@vueuse/core'
-import { showError } from '@nextcloud/dialogs'
-import { mdiAccountGroup, mdiPlus } from '@mdi/js'
import NcActionInput from '@nextcloud/vue/components/NcActionInput'
import NcActionText from '@nextcloud/vue/components/NcActionText'
@@ -137,12 +141,16 @@ watch(groupsSearchQuery, async () => {
})
/** Cancelable promise for search groups request */
-const promise = ref(null)
+const promise = ref<CancelablePromise<IGroup[]>>()
/**
* Load groups
*/
async function loadGroups() {
+ if (!isAdminOrDelegatedAdmin.value) {
+ return
+ }
+
if (promise.value) {
promise.value.cancel()
}
@@ -163,7 +171,7 @@ async function loadGroups() {
} catch (error) {
logger.error(t('settings', 'Failed to load groups'), { error })
}
- promise.value = null
+ promise.value = undefined
loadingGroups.value = false
}
diff --git a/apps/settings/src/components/PersonalInfo/FediverseSection.vue b/apps/settings/src/components/PersonalInfo/FediverseSection.vue
index 65400ce0e45..043fa6e64b9 100644
--- a/apps/settings/src/components/PersonalInfo/FediverseSection.vue
+++ b/apps/settings/src/components/PersonalInfo/FediverseSection.vue
@@ -19,7 +19,7 @@ import { NAME_READABLE_ENUM } from '../../constants/AccountPropertyConstants.js'
import AccountPropertySection from './shared/AccountPropertySection.vue'
-const { fediverse } = loadState<AccountProperties>('settings', 'personalInfoParameters', {})
+const { fediverse } = loadState<AccountProperties>('settings', 'personalInfoParameters')
const value = ref({ ...fediverse })
const readable = NAME_READABLE_ENUM[fediverse.name]
@@ -29,11 +29,18 @@ const readable = NAME_READABLE_ENUM[fediverse.name]
* @param text The potential fediverse handle
*/
function onValidate(text: string): boolean {
+ // allow to clear the value
+ if (text === '') {
+ return true
+ }
+
+ // check its in valid format
const result = text.match(/^@?([^@/]+)@([^@/]+)$/)
if (result === null) {
return false
}
+ // check its a valid URL
try {
return URL.parse(`https://${result[2]}/`) !== null
} catch {
diff --git a/apps/settings/src/components/PersonalInfo/TwitterSection.vue b/apps/settings/src/components/PersonalInfo/TwitterSection.vue
index 802f96087c2..43d08f81e3f 100644
--- a/apps/settings/src/components/PersonalInfo/TwitterSection.vue
+++ b/apps/settings/src/components/PersonalInfo/TwitterSection.vue
@@ -19,7 +19,7 @@ import { ref } from 'vue'
import { NAME_READABLE_ENUM } from '../../constants/AccountPropertyConstants.ts'
import AccountPropertySection from './shared/AccountPropertySection.vue'
-const { twitter } = loadState<AccountProperties>('settings', 'personalInfoParameters', {})
+const { twitter } = loadState<AccountProperties>('settings', 'personalInfoParameters')
const value = ref({ ...twitter })
const readable = NAME_READABLE_ENUM[twitter.name]
@@ -29,6 +29,6 @@ const readable = NAME_READABLE_ENUM[twitter.name]
* @param text The potential twitter handle
*/
function onValidate(text: string): boolean {
- return text.match(/^@?([a-zA-Z0-9_]{2,15})$/) !== null
+ return text === '' || text.match(/^@?([a-zA-Z0-9_]{2,15})$/) !== null
}
</script>
diff --git a/apps/settings/src/components/UserList.vue b/apps/settings/src/components/UserList.vue
index 5d6bd5f04ee..84c204805cc 100644
--- a/apps/settings/src/components/UserList.vue
+++ b/apps/settings/src/components/UserList.vue
@@ -350,11 +350,13 @@ export default {
setNewUserDefaultGroup(value) {
// Is no value set, but user is a line manager we set their group as this is a requirement for line manager
if (!value && !this.settings.isAdmin && !this.settings.isDelegatedAdmin) {
+ const groups = this.$store.getters.getSubAdminGroups
// if there are multiple groups we do not know which to add,
// so we cannot make the managers life easier by preselecting it.
- if (this.groups.length === 1) {
- value = this.groups[0].id
+ if (groups.length === 1) {
+ this.newUser.groups = [...groups]
}
+ return
}
if (value) {
diff --git a/apps/settings/src/components/Users/NewUserDialog.vue b/apps/settings/src/components/Users/NewUserDialog.vue
index 3e50efc2072..19445bc187e 100644
--- a/apps/settings/src/components/Users/NewUserDialog.vue
+++ b/apps/settings/src/components/Users/NewUserDialog.vue
@@ -61,6 +61,7 @@
:required="newUser.password === '' || settings.newUserRequireEmail" />
<div class="dialog__item">
<NcSelect class="dialog__select"
+ data-test="groups"
:input-label="!settings.isAdmin && !settings.isDelegatedAdmin ? t('settings', 'Member of the following groups (required)') : t('settings', 'Member of the following groups')"
:placeholder="t('settings', 'Set account groups')"
:disabled="loading.groups || loading.all"
@@ -69,7 +70,7 @@
label="name"
:close-on-select="false"
:multiple="true"
- :taggable="true"
+ :taggable="settings.isAdmin || settings.isDelegatedAdmin"
:required="!settings.isAdmin && !settings.isDelegatedAdmin"
:create-option="(value) => ({ id: value, name: value, isCreating: true })"
@search="searchGroups"
@@ -178,7 +179,7 @@ export default {
data() {
return {
- availableGroups: this.$store.getters.getSortedGroups.filter(group => group.id !== '__nc_internal_recent' && group.id !== 'disabled'),
+ availableGroups: [],
possibleManagers: [],
// TRANSLATORS This string describes a manager in the context of an organization
managerInputLabel: t('settings', 'Manager'),
@@ -235,6 +236,13 @@ export default {
},
mounted() {
+ // admins also can assign the system groups
+ if (this.isAdmin || this.isDelegatedAdmin) {
+ this.availableGroups = this.$store.getters.getSortedGroups.filter(group => group.id !== '__nc_internal_recent' && group.id !== 'disabled')
+ } else {
+ this.availableGroups = [...this.$store.getters.getSubAdminGroups]
+ }
+
this.$refs.username?.focus?.()
},
@@ -273,6 +281,11 @@ export default {
},
async searchGroups(query, toggleLoading) {
+ if (!this.isAdmin && !this.isDelegatedAdmin) {
+ // managers cannot search for groups
+ return
+ }
+
if (this.promise) {
this.promise.cancel()
}
diff --git a/apps/settings/src/store/apps.js b/apps/settings/src/store/apps.js
index c58651a3cf5..e0068d3892e 100644
--- a/apps/settings/src/store/apps.js
+++ b/apps/settings/src/store/apps.js
@@ -5,6 +5,7 @@
import api from './api.js'
import Vue from 'vue'
+import axios from '@nextcloud/axios'
import { generateUrl } from '@nextcloud/router'
import { showError, showInfo } from '@nextcloud/dialogs'
import { loadState } from '@nextcloud/initial-state'
@@ -191,7 +192,7 @@ const actions = {
})
// check for server health
- return api.get(generateUrl('apps/files/'))
+ return axios.get(generateUrl('apps/files/'))
.then(() => {
if (response.data.update_required) {
showInfo(
diff --git a/apps/settings/src/store/users.js b/apps/settings/src/store/users.js
index a6298a38e2d..3734b7008df 100644
--- a/apps/settings/src/store/users.js
+++ b/apps/settings/src/store/users.js
@@ -36,7 +36,10 @@ const defaults = {
const state = {
users: [],
- groups: [...(usersSettings.systemGroups ?? [])],
+ groups: [
+ ...(usersSettings.getSubAdminGroups ?? []),
+ ...(usersSettings.systemGroups ?? []),
+ ],
orderBy: usersSettings.sortGroups ?? GroupSorting.UserCount,
minPasswordLength: 0,
usersOffset: 0,
@@ -232,12 +235,10 @@ const mutations = {
* @param {object} state the store state
*/
resetGroups(state) {
- const systemGroups = state.groups.filter(group => [
- 'admin',
- '__nc_internal_recent',
- 'disabled',
- ].includes(group.id))
- state.groups = [...systemGroups]
+ state.groups = [
+ ...(usersSettings.getSubAdminGroups ?? []),
+ ...(usersSettings.systemGroups ?? []),
+ ]
},
setShowConfig(state, { key, value }) {
@@ -270,6 +271,10 @@ const getters = {
getGroups(state) {
return state.groups
},
+ getSubAdminGroups() {
+ return usersSettings.subAdminGroups ?? []
+ },
+
getSortedGroups(state) {
const groups = [...state.groups]
if (state.orderBy === GroupSorting.UserCount) {