diff --git a/packages/builder/src/pages/builder/portal/users/groups/[groupId].svelte b/packages/builder/src/pages/builder/portal/users/groups/[groupId].svelte
index 1be019b83e..ccd945fc24 100644
--- a/packages/builder/src/pages/builder/portal/users/groups/[groupId].svelte
+++ b/packages/builder/src/pages/builder/portal/users/groups/[groupId].svelte
@@ -11,9 +11,11 @@
ActionMenu,
MenuItem,
Modal,
+ Pagination,
} from "@budibase/bbui"
+ import { fetchData } from "@budibase/frontend-core"
+ import { API } from "api"
import UserGroupPicker from "components/settings/UserGroupPicker.svelte"
- import { createPaginationStore } from "helpers/pagination"
import { users, apps, groups, auth, features } from "stores/portal"
import { onMount, setContext } from "svelte"
import { roles } from "stores/backend"
@@ -28,6 +30,18 @@
export let groupId
+ const fetchUsers = fetchData({
+ API,
+ datasource: {
+ type: "groupUser",
+ },
+ options: {
+ query: {
+ groupId,
+ },
+ },
+ })
+
$: userSchema = {
email: {
width: "1fr",
@@ -70,17 +84,12 @@
let popoverAnchor
let popover
let searchTerm = ""
- let prevSearch = undefined
- let pageInfo = createPaginationStore()
let loaded = false
let editModal, deleteModal
$: scimEnabled = $features.isScimEnabled
$: readonly = !$auth.isAdmin || scimEnabled
- $: page = $pageInfo.page
- $: fetchUsers(page, searchTerm)
$: group = $groups.find(x => x._id === groupId)
- $: filtered = $users.data
$: groupApps = $apps
.filter(app =>
groups.actions
@@ -97,25 +106,6 @@
}
}
- async function fetchUsers(page, search) {
- if ($pageInfo.loading) {
- return
- }
- // need to remove the page if they've started searching
- if (search && !prevSearch) {
- pageInfo.reset()
- page = undefined
- }
- prevSearch = search
- try {
- pageInfo.loading()
- await users.search({ page, email: search })
- pageInfo.fetched($users.hasNextPage, $users.nextPage)
- } catch (error) {
- notifications.error("Error getting user list")
- }
- }
-
async function deleteGroup() {
try {
await groups.actions.delete(group)
@@ -211,7 +201,7 @@
This user group doesn't have any users
+
+
diff --git a/packages/frontend-core/src/api/groups.js b/packages/frontend-core/src/api/groups.js
index c27f11e0ea..cbc5bfd72a 100644
--- a/packages/frontend-core/src/api/groups.js
+++ b/packages/frontend-core/src/api/groups.js
@@ -52,6 +52,20 @@ export const buildGroupsEndpoints = API => {
})
},
+ /**
+ * Gets a group users by the group id
+ */
+ getGroupUsers: async ({ id, bookmark }) => {
+ let url = `/api/global/groups/${id}/users?`
+ if (bookmark) {
+ url += `bookmark=${bookmark}`
+ }
+
+ return await API.get({
+ url,
+ })
+ },
+
/**
* Adds users to a group
* @param groupId The group to update
diff --git a/packages/frontend-core/src/fetch/GroupUserFetch.js b/packages/frontend-core/src/fetch/GroupUserFetch.js
new file mode 100644
index 0000000000..b0ca9a5388
--- /dev/null
+++ b/packages/frontend-core/src/fetch/GroupUserFetch.js
@@ -0,0 +1,50 @@
+import { get } from "svelte/store"
+import DataFetch from "./DataFetch.js"
+import { TableNames } from "../constants"
+
+export default class GroupUserFetch extends DataFetch {
+ constructor(opts) {
+ super({
+ ...opts,
+ datasource: {
+ tableId: TableNames.USERS,
+ },
+ })
+ }
+
+ determineFeatureFlags() {
+ return {
+ supportsSearch: true,
+ supportsSort: false,
+ supportsPagination: true,
+ }
+ }
+
+ async getDefinition() {
+ return {
+ schema: {},
+ }
+ }
+
+ async getData() {
+ const { query, cursor } = get(this.store)
+ try {
+ const res = await this.API.getGroupUsers({
+ id: query.groupId,
+ bookmark: cursor,
+ })
+
+ return {
+ rows: res?.users || [],
+ hasNextPage: res?.hasNextPage || false,
+ cursor: res?.bookmark || null,
+ }
+ } catch (error) {
+ return {
+ rows: [],
+ hasNextPage: false,
+ error,
+ }
+ }
+ }
+}
diff --git a/packages/frontend-core/src/fetch/fetchData.js b/packages/frontend-core/src/fetch/fetchData.js
index 4974816496..c4968eabc0 100644
--- a/packages/frontend-core/src/fetch/fetchData.js
+++ b/packages/frontend-core/src/fetch/fetchData.js
@@ -6,6 +6,7 @@ import NestedProviderFetch from "./NestedProviderFetch.js"
import FieldFetch from "./FieldFetch.js"
import JSONArrayFetch from "./JSONArrayFetch.js"
import UserFetch from "./UserFetch.js"
+import GroupUserFetch from "./GroupUserFetch.js"
const DataFetchMap = {
table: TableFetch,
@@ -13,6 +14,7 @@ const DataFetchMap = {
query: QueryFetch,
link: RelationshipFetch,
user: UserFetch,
+ groupUser: GroupUserFetch,
// Client specific datasource types
provider: NestedProviderFetch,
diff --git a/packages/types/src/documents/global/userGroup.ts b/packages/types/src/documents/global/userGroup.ts
index fa48c1636e..b74e59c020 100644
--- a/packages/types/src/documents/global/userGroup.ts
+++ b/packages/types/src/documents/global/userGroup.ts
@@ -1,3 +1,4 @@
+import { PaginationResponse } from "../../api"
import { Document } from "../document"
export interface UserGroup extends Document {
@@ -26,3 +27,10 @@ export interface SearchGroupRequest {}
export interface SearchGroupResponse {
data: UserGroup[]
}
+
+export interface SearchUserGroupResponse extends PaginationResponse {
+ users: {
+ _id: any
+ email: any
+ }[]
+}
diff --git a/packages/types/src/sdk/db.ts b/packages/types/src/sdk/db.ts
index 2cccd3be6a..58b3b7e5bc 100644
--- a/packages/types/src/sdk/db.ts
+++ b/packages/types/src/sdk/db.ts
@@ -65,6 +65,7 @@ export type DatabaseQueryOpts = {
key?: string
keys?: string[]
group?: boolean
+ startkey_docid?: string
}
export const isDocument = (doc: any): doc is Document => {