diff options
author | Christopher Ng <chrng8@gmail.com> | 2025-03-25 14:31:44 -0700 |
---|---|---|
committer | Christopher Ng <chrng8@gmail.com> | 2025-03-28 14:12:52 -0700 |
commit | 8a3a38815faf1591d9be9601da17c246b57a431c (patch) | |
tree | e204a3254507a9882b22ae111eaa2c095381f1f2 | |
parent | a1a4988c27e32fda951881781ae0383449d9ab55 (diff) | |
download | nextcloud-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.vue | 29 | ||||
-rw-r--r-- | apps/settings/src/service/groups.ts | 35 | ||||
-rw-r--r-- | apps/settings/src/store/users.js | 19 | ||||
-rw-r--r-- | apps/settings/src/utils/groups.ts | 22 |
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, +}) |