Content-Length: 11399 | pFad | http://github.com/lowcoder-org/lowcoder/pull/1800.patch
thub.com
From 4a9d29271e74d445a74cdef6eaff86eb87a6fdc8 Mon Sep 17 00:00:00 2001
From: Kamal Qureshi
Date: Mon, 23 Jun 2025 13:25:18 +0500
Subject: [PATCH 1/2] Adds search bar in "Add Members" for groups
---
client/packages/lowcoder/src/api/orgApi.ts | 5 +++
.../src/constants/reduxActionConstants.ts | 1 +
.../packages/lowcoder/src/i18n/locales/en.ts | 1 +
.../setting/permission/addGroupUserDialog.tsx | 33 ++++++++++++++++---
.../src/redux/reduxActions/orgActions.ts | 8 +++++
.../lowcoder/src/redux/sagas/orgSagas.ts | 22 ++++++++++++-
6 files changed, 65 insertions(+), 5 deletions(-)
diff --git a/client/packages/lowcoder/src/api/orgApi.ts b/client/packages/lowcoder/src/api/orgApi.ts
index 588a20df51..379234b32e 100644
--- a/client/packages/lowcoder/src/api/orgApi.ts
+++ b/client/packages/lowcoder/src/api/orgApi.ts
@@ -62,6 +62,7 @@ export class OrgApi extends Api {
static updateOrgURL = (orgId: string) => `/organizations/${orgId}/update`;
static fetchUsage = (orgId: string) => `/organizations/${orgId}/api-usage`;
static fetchOrgsByEmailURL = (email: string) => `organizations/byuser/${email}`;
+ static fetchGroupPotentialMembersURL = (groupId: string) => `/groups/${groupId}/potential-members`;
static createGroup(request: { name: string }): AxiosPromise> {
return Api.post(OrgApi.createGroupURL, request);
@@ -110,6 +111,10 @@ export class OrgApi extends Api {
return Api.get(OrgApi.fetchGroupUsersURL(groupId));
}
+ static fetchGroupPotentialMembers(searchName: string, groupId: string): AxiosPromise {
+ return Api.get(OrgApi.fetchGroupPotentialMembersURL(groupId), {searchName})
+ }
+
static fetchGroupUsersPagination(request: fetchGroupUserRequestType): AxiosPromise {
const {groupId, ...res} = request;
return Api.get(OrgApi.fetchGroupUsersURL(groupId), {...res});
diff --git a/client/packages/lowcoder/src/constants/reduxActionConstants.ts b/client/packages/lowcoder/src/constants/reduxActionConstants.ts
index f14f40c73d..821470ac56 100644
--- a/client/packages/lowcoder/src/constants/reduxActionConstants.ts
+++ b/client/packages/lowcoder/src/constants/reduxActionConstants.ts
@@ -86,6 +86,7 @@ export const ReduxActionTypes = {
UPDATE_USER_ORG_ROLE: "UPDATE_USER_ORG_ROLE",
UPDATE_USER_GROUP_ROLE: "UPDATE_USER_GROUP_ROLE",
FETCH_ORG_ALL_USERS: "FETCH_ORG_ALL_USERS",
+ FETCH_GROUP_POTENTIAL_MEMBERS: "FETCH_ORG_ALL_GROUP_MEMBERS",
FETCH_ORG_ALL_USERS_SUCCESS: "FETCH_ORG_ALL_USERS_SUCCESS",
FETCH_GROUP_USERS: "FETCH_GROUP_USERS",
FETCH_GROUP_USERS_SUCCESS: "FETCH_GROUP_USERS_SUCCESS",
diff --git a/client/packages/lowcoder/src/i18n/locales/en.ts b/client/packages/lowcoder/src/i18n/locales/en.ts
index fee16d1030..48774170c9 100644
--- a/client/packages/lowcoder/src/i18n/locales/en.ts
+++ b/client/packages/lowcoder/src/i18n/locales/en.ts
@@ -3008,6 +3008,7 @@ export const en = {
"deleteModalTitle": "Delete This Group",
"deleteModalContent": "The Deleted Group Cannot Be Restored. Are You Sure to Delete the Group?",
"addMember": "Add Members",
+ "searchMember": "Search Members",
"nameColumn": "User Name",
"joinTimeColumn": "Joining Time",
"actionColumn": "Operation",
diff --git a/client/packages/lowcoder/src/pages/setting/permission/addGroupUserDialog.tsx b/client/packages/lowcoder/src/pages/setting/permission/addGroupUserDialog.tsx
index 8af0e3cecc..0a11b018b5 100644
--- a/client/packages/lowcoder/src/pages/setting/permission/addGroupUserDialog.tsx
+++ b/client/packages/lowcoder/src/pages/setting/permission/addGroupUserDialog.tsx
@@ -1,11 +1,14 @@
import Column from "antd/es/table/Column";
import OrgApi from "api/orgApi";
import { GroupUser, MEMBER_ROLE, OrgUser } from "constants/orgConstants";
-import { CheckBox, CustomModal } from "lowcoder-design";
+import { CheckBox, CustomModal, Search } from "lowcoder-design";
import { CSSProperties, ReactNode, useEffect, useRef, useState } from "react";
import { connect, useDispatch } from "react-redux";
import { AppState } from "redux/reducers";
-import { fetchGroupUsersAction, fetchOrgUsersAction } from "redux/reduxActions/orgActions";
+import { fetchGroupUsersAction,
+ fetchOrgUsersAction,
+ fetchGroupPotentialMembersAction
+} from "redux/reduxActions/orgActions";
import styled from "styled-components";
import { StyledTable, UserTableCellWrapper } from "./styledComponents";
import { formatTimestamp } from "util/dateTimeUtils";
@@ -40,7 +43,18 @@ function AddGroupUserDialog(props: {
const addableUsers = orgUsers.filter((user) => !groupUserIdMap.has(user.userId));
const toAddUserIdRecord = useRef>({});
const [confirmLoading, setConfirmLoading] = useState(false);
+ const [searchValue, setSearchValue] = useState("")
const dispatch = useDispatch();
+
+ useEffect(() => {
+ const timer = setTimeout(() => {
+ if (searchValue.length > 2 || searchValue === "")
+ dispatch(fetchGroupPotentialMembersAction(searchValue, groupId));
+ return
+ }, 500);
+ return () => clearTimeout(timer);
+ }, [searchValue])
+
useEffect(() => {
if (dialogVisible) {
dispatch(fetchOrgUsersAction(orgId));
@@ -92,7 +106,18 @@ function AddGroupUserDialog(props: {
setDialogVisible(false);
}}
>
- {!addableUsers || addableUsers.length === 0 ? (
+ setSearchValue(e.target.value)}
+ style={{
+ width: "100%",
+ height: "32px",
+ paddingRight: "20px",
+ marginBottom: "10px"
+ }}
+ />
+ {(!addableUsers || addableUsers.length === 0) ? (
) : (
@@ -106,7 +131,7 @@ function AddGroupUserDialog(props: {
scroll={{ y: 309 }}
>
({
payload: payload,
});
+export const fetchGroupPotentialMembersAction = (searchName: string, groupId: string) => ({
+ type: ReduxActionTypes.FETCH_GROUP_POTENTIAL_MEMBERS,
+ payload: {
+ searchName,
+ groupId
+ },
+});
+
export type AddGroupUserPayload = {
role: string;
groupId: string;
diff --git a/client/packages/lowcoder/src/redux/sagas/orgSagas.ts b/client/packages/lowcoder/src/redux/sagas/orgSagas.ts
index b259f12a00..a2339dca92 100644
--- a/client/packages/lowcoder/src/redux/sagas/orgSagas.ts
+++ b/client/packages/lowcoder/src/redux/sagas/orgSagas.ts
@@ -107,11 +107,30 @@ export function* updateUserGroupRoleSaga(action: ReduxAction) {
+ try {
+ const response: AxiosResponse = yield call(
+ OrgApi.fetchGroupPotentialMembers,
+ action.payload.searchName,
+ action.payload.groupId
+ );
+ const isValidResponse: boolean = validateResponse(response);
+ if (isValidResponse) {
+ yield put({
+ type: ReduxActionTypes.FETCH_ORG_ALL_USERS_SUCCESS,
+ payload: response.data.data,
+ });
+ }
+ } catch (error) {
+ log.error(error);
+ }
+}
+
export function* fetchOrgUsersSaga(action: ReduxAction<{ orgId: string }>) {
try {
const response: AxiosResponse = yield call(
OrgApi.fetchOrgUsers,
- action.payload.orgId
+ action.payload.orgId,
);
const isValidResponse: boolean = validateResponse(response);
if (isValidResponse) {
@@ -377,6 +396,7 @@ export default function* orgSagas() {
takeLatest(ReduxActionTypes.UPDATE_USER_ORG_ROLE, updateUserOrgRoleSaga),
takeLatest(ReduxActionTypes.UPDATE_USER_GROUP_ROLE, updateUserGroupRoleSaga),
takeLatest(ReduxActionTypes.FETCH_ORG_ALL_USERS, fetchOrgUsersSaga),
+ takeLatest(ReduxActionTypes.FETCH_GROUP_POTENTIAL_MEMBERS, fetchGroupPotentialMembersSaga),
takeLatest(ReduxActionTypes.DELETE_ORG_USER, deleteOrgUserSaga),
takeLatest(ReduxActionTypes.QUIT_GROUP, quitGroupSaga),
takeLatest(ReduxActionTypes.QUIT_ORG, quitOrgSaga),
From 28161b046b89ff96150f858317f2812ea60df76f Mon Sep 17 00:00:00 2001
From: Kamal Qureshi
Date: Mon, 23 Jun 2025 13:39:05 +0500
Subject: [PATCH 2/2] Added debounce for searching
---
.../setting/permission/addGroupUserDialog.tsx | 24 ++++++++++++-------
1 file changed, 16 insertions(+), 8 deletions(-)
diff --git a/client/packages/lowcoder/src/pages/setting/permission/addGroupUserDialog.tsx b/client/packages/lowcoder/src/pages/setting/permission/addGroupUserDialog.tsx
index 0a11b018b5..46cad16b67 100644
--- a/client/packages/lowcoder/src/pages/setting/permission/addGroupUserDialog.tsx
+++ b/client/packages/lowcoder/src/pages/setting/permission/addGroupUserDialog.tsx
@@ -2,7 +2,7 @@ import Column from "antd/es/table/Column";
import OrgApi from "api/orgApi";
import { GroupUser, MEMBER_ROLE, OrgUser } from "constants/orgConstants";
import { CheckBox, CustomModal, Search } from "lowcoder-design";
-import { CSSProperties, ReactNode, useEffect, useRef, useState } from "react";
+import { CSSProperties, ReactNode, useEffect, useRef, useState, useCallback } from "react";
import { connect, useDispatch } from "react-redux";
import { AppState } from "redux/reducers";
import { fetchGroupUsersAction,
@@ -17,6 +17,7 @@ import { isGroupAdmin } from "util/permissionUtils";
import { SuperUserIcon } from "lowcoder-design";
import { EmptyContent } from "pages/common/styledComponent";
import { trans } from "i18n";
+import { debounce } from "lodash";
const TableWrapper = styled.div`
margin-right: -16px;
@@ -46,14 +47,21 @@ function AddGroupUserDialog(props: {
const [searchValue, setSearchValue] = useState("")
const dispatch = useDispatch();
+ const debouncedFetchPotentialMembers = useCallback(
+ debounce((searchVal: string) => {
+ dispatch(fetchGroupPotentialMembersAction(searchVal, groupId));
+ }, 500),
+ [dispatch, groupId]
+ );
+
useEffect(() => {
- const timer = setTimeout(() => {
- if (searchValue.length > 2 || searchValue === "")
- dispatch(fetchGroupPotentialMembersAction(searchValue, groupId));
- return
- }, 500);
- return () => clearTimeout(timer);
- }, [searchValue])
+ if (searchValue.length > 2 || searchValue === "") {
+ debouncedFetchPotentialMembers(searchValue);
+ }
+ return () => {
+ debouncedFetchPotentialMembers.cancel();
+ };
+ }, [searchValue, debouncedFetchPotentialMembers]);
useEffect(() => {
if (dialogVisible) {
--- a PPN by Garber Painting Akron. With Image Size Reduction included!Fetched URL: http://github.com/lowcoder-org/lowcoder/pull/1800.patch
Alternative Proxies:
Alternative Proxy
pFad Proxy
pFad v3 Proxy
pFad v4 Proxy