aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristopher Ng <chrng8@gmail.com>2025-03-25 14:31:44 -0700
committerChristopher Ng <chrng8@gmail.com>2025-03-28 14:12:52 -0700
commit8a3a38815faf1591d9be9601da17c246b57a431c (patch)
treee204a3254507a9882b22ae111eaa2c095381f1f2
parenta1a4988c27e32fda951881781ae0383449d9ab55 (diff)
downloadnextcloud-server-8a3a38815faf1591d9be9601da17c246b57a431c.tar.gz
nextcloud-server-8a3a38815faf1591d9be9601da17c246b57a431c.zip
perf(settings): Cancel request on new search
Signed-off-by: Christopher Ng <chrng8@gmail.com>
-rw-r--r--apps/settings/src/components/AppNavigationGroupList.vue29
-rw-r--r--apps/settings/src/service/groups.ts35
-rw-r--r--apps/settings/src/store/users.js19
-rw-r--r--apps/settings/src/utils/groups.ts22
4 files changed, 70 insertions, 35 deletions
diff --git a/apps/settings/src/components/AppNavigationGroupList.vue b/apps/settings/src/components/AppNavigationGroupList.vue
index d5362d6cf4c..ea5be964c31 100644
--- a/apps/settings/src/components/AppNavigationGroupList.vue
+++ b/apps/settings/src/components/AppNavigationGroupList.vue
@@ -42,7 +42,7 @@
<NcAppNavigationList class="account-management__group-list"
aria-describedby="group-list-desc"
data-cy-users-settings-navigation-groups="custom">
- <GroupListItem v-for="group in filteredGroups"
+ <GroupListItem v-for="group in userGroups"
:id="group.id"
ref="groupListItems"
:key="group.id"
@@ -57,6 +57,8 @@
</template>
<script setup lang="ts">
+import type { Group } from '../utils/groups.ts'
+
import { computed, ref, watch, onBeforeMount } from 'vue'
import { Fragment } from 'vue-frag'
import { useRoute, useRouter } from 'vue-router/composables'
@@ -76,17 +78,9 @@ import GroupListItem from './GroupListItem.vue'
import { useFormatGroups } from '../composables/useGroupsNavigation.ts'
import { useStore } from '../store'
+import { searchGroups } from '../service/groups.ts'
import logger from '../logger.ts'
-interface Group {
- id: string
- displayname: string
- usercount: number
- disabled: number
- canAdd: boolean
- canRemove: boolean
-}
-
const store = useStore()
const route = useRoute()
const router = useRouter()
@@ -123,10 +117,6 @@ const loadingGroups = ref(false)
const offset = ref(0)
/** Search query for groups */
const groupsSearchQuery = ref('')
-/** Filtered groups */
-const filteredGroups = computed(() => userGroups.value.filter((group) => {
- return group.title.toLocaleLowerCase().includes(groupsSearchQuery.value.toLocaleLowerCase())
-}))
const groupListItems = ref([])
const lastGroupListItem = computed(() => {
@@ -148,18 +138,24 @@ watch(groupsSearchQuery, async () => {
await loadGroups()
})
+/** Cancelable promise for search groups request */
+const promise = ref(null)
+
/**
* Load groups
*/
async function loadGroups() {
+ if (promise.value) {
+ promise.value.cancel()
+ }
loadingGroups.value = true
try {
- const { data } = await store.dispatch('searchGroups', {
+ promise.value = searchGroups({
search: groupsSearchQuery.value,
offset: offset.value,
limit: 25,
})
- const groups: Group[] = data.ocs?.data?.groups ?? []
+ const groups: Group[] = (await promise.value).data.ocs?.data?.groups ?? []
if (groups.length > 0) {
offset.value += 25
}
@@ -176,6 +172,7 @@ async function loadGroups() {
} catch (error) {
logger.error(t('settings', 'Failed to load groups'), { error })
}
+ promise.value = null
loadingGroups.value = false
}
diff --git a/apps/settings/src/service/groups.ts b/apps/settings/src/service/groups.ts
new file mode 100644
index 00000000000..87b83a91140
--- /dev/null
+++ b/apps/settings/src/service/groups.ts
@@ -0,0 +1,35 @@
+/**
+ * SPDX-FileCopyrightText: 2025 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ */
+
+import type { AxiosResponse } from '@nextcloud/axios'
+
+import axios from '@nextcloud/axios'
+import { generateOcsUrl } from '@nextcloud/router'
+import { CancelablePromise } from 'cancelable-promise'
+
+/**
+ * Search groups
+ *
+ * @param {object} options Options
+ * @param {string} options.search Search query
+ * @param {number} options.offset Offset
+ * @param {number} options.limit Limit
+ */
+export const searchGroups = ({ search, offset, limit }): CancelablePromise<AxiosResponse> => {
+ const controller = new AbortController()
+ return new CancelablePromise(async (resolve, reject, onCancel) => {
+ onCancel(() => controller.abort())
+ try {
+ const response = await axios.get(
+ generateOcsUrl('/cloud/groups/details?search={search}&offset={offset}&limit={limit}', { search, offset, limit }), {
+ signal: controller.signal,
+ },
+ )
+ resolve(response)
+ } catch (error) {
+ reject(error)
+ }
+ })
+}
diff --git a/apps/settings/src/store/users.js b/apps/settings/src/store/users.js
index c997b04b40c..2a3a2d272d9 100644
--- a/apps/settings/src/store/users.js
+++ b/apps/settings/src/store/users.js
@@ -324,25 +324,6 @@ const actions = {
},
/**
- * search groups
- *
- * @param {object} context Store context
- * @param {object} options Options
- * @param {string} options.search Search query
- * @param {number} options.offset List offset
- * @param {number} options.limit List limit
- * @return {Promise}
- */
- searchGroups(context, { search, offset, limit }) {
- return api.get(generateOcsUrl('cloud/groups/details?search={search}&offset={offset}&limit={limit}', { search, offset, limit }))
- .catch((error) => {
- if (!axios.isCancel(error)) {
- context.commit('API_FAILURE', error)
- }
- })
- },
-
- /**
* Get user details
*
* @param {object} context store context
diff --git a/apps/settings/src/utils/groups.ts b/apps/settings/src/utils/groups.ts
new file mode 100644
index 00000000000..bc2c789ec35
--- /dev/null
+++ b/apps/settings/src/utils/groups.ts
@@ -0,0 +1,22 @@
+/**
+ * SPDX-FileCopyrightText: 2025 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ */
+
+export interface Group {
+ id: string
+ displayname: string
+ usercount: number
+ disabled: number
+ canAdd: boolean
+ canRemove: boolean
+}
+
+export const formatGroup = (group: Group) => ({
+ id: group.id,
+ name: group.displayname,
+ usercount: group.usercount,
+ disabled: group.disabled,
+ canAdd: group.canAdd,
+ canRemove: group.canRemove,
+})