Skip to content

Commit d086fb7

Browse files
Merge pull request #1920 from iamfaran/fix/1904-usergroups
[Fix]: #1904 usergroups permission modal empty list
2 parents 1094c43 + 24b78af commit d086fb7

File tree

4 files changed

+101
-29
lines changed

4 files changed

+101
-29
lines changed

client/packages/lowcoder/src/components/PermissionDialog/DatasourcePermissionDialog.tsx

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import { DatasourceRole } from "../../api/datasourcePermissionApi";
1313
import { getDataSourcePermissionInfo } from "../../redux/selectors/datasourceSelectors";
1414
import { StyledLoading } from "./commonComponents";
1515
import { PermissionRole } from "./Permission";
16+
import { getUser } from "../../redux/selectors/usersSelectors";
1617

1718
export const DatasourcePermissionDialog = (props: {
1819
datasourceId: string;
@@ -22,6 +23,7 @@ export const DatasourcePermissionDialog = (props: {
2223
const { datasourceId } = props;
2324
const dispatch = useDispatch();
2425
const permissionInfo = useSelector(getDataSourcePermissionInfo)[datasourceId];
26+
const user = useSelector(getUser);
2527

2628
useEffect(() => {
2729
dispatch(fetchDatasourcePermissions({ datasourceId: datasourceId }));
@@ -75,6 +77,8 @@ export const DatasourcePermissionDialog = (props: {
7577
{ label: trans("share.datasourceOwner"), value: PermissionRole.Owner },
7678
]}
7779
permissionItems={permissions}
80+
contextType="organization"
81+
organizationId={user.currentOrgId}
7882
viewBodyRender={(list) => {
7983
if (!permissionInfo) {
8084
return <StyledLoading size={18} />;

client/packages/lowcoder/src/components/PermissionDialog/Permission.tsx

Lines changed: 38 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ import { EmptyContent } from "pages/common/styledComponent";
2727
import { trans } from "i18n";
2828
import { PermissionItem } from "./PermissionList";
2929
import { currentApplication } from "@lowcoder-ee/redux/selectors/applicationSelector";
30-
import { fetchAvailableGroupsMembers } from "@lowcoder-ee/util/pagination/axios";
30+
import { fetchAvailableGroupsMembers, fetchAvailableOrgGroupsMembers } from "@lowcoder-ee/util/pagination/axios";
3131

3232
const AddAppUserContent = styled.div`
3333
display: flex;
@@ -186,6 +186,13 @@ const AddRoleSelect = styled(StyledRoleSelect)<{ $isVisible: boolean }>`
186186
display: ${(props) => (props.$isVisible ? "unset" : "none")};
187187
`;
188188

189+
type PermissionContextType = "application" | "organization";
190+
191+
type PermissionContextProps = {
192+
contextType: PermissionContextType;
193+
organizationId?: string;
194+
};
195+
189196
type AddAppOptionView = {
190197
type: ApplicationPermissionType;
191198
id: string;
@@ -294,8 +301,10 @@ const PermissionSelector = (props: {
294301
user: User;
295302
filterItems: PermissionItem[];
296303
supportRoles: { label: string; value: PermissionRole }[];
304+
contextType: PermissionContextType;
305+
organizationId?: string;
297306
}) => {
298-
const { selectedItems, setSelectRole, setSelectedItems, user } = props;
307+
const { selectedItems, setSelectRole, setSelectedItems, user, contextType, organizationId } = props;
299308
const [roleSelectVisible, setRoleSelectVisible] = useState(false);
300309
const selectRef = useRef<HTMLDivElement>(null);
301310
const [optionViews, setOptionViews] = useState<AddAppOptionView[]>()
@@ -305,42 +314,41 @@ const PermissionSelector = (props: {
305314

306315
const debouncedUserSearch = useCallback(
307316
debounce((searchTerm: string) => {
308-
if (!application) return;
309-
310317
setIsLoading(true);
311-
fetchAvailableGroupsMembers(application.applicationId, searchTerm).then(res => {
312-
if(res.success) {
313-
setOptionViews(getPermissionOptionView(res.data, props.filterItems))
314-
}
315-
setIsLoading(false);
316-
}).catch(() => {
318+
319+
if (contextType === "application" && application) {
320+
fetchAvailableGroupsMembers(application.applicationId, searchTerm).then(res => {
321+
if(res.success) {
322+
setOptionViews(getPermissionOptionView(res.data, props.filterItems))
323+
}
324+
setIsLoading(false);
325+
}).catch(() => {
326+
setIsLoading(false);
327+
});
328+
} else if (contextType === "organization" && organizationId) {
329+
fetchAvailableOrgGroupsMembers(organizationId, searchTerm).then(res => {
330+
if(res.success) {
331+
setOptionViews(getPermissionOptionView(res.data || [], props.filterItems))
332+
}
333+
setIsLoading(false);
334+
}).catch(() => {
335+
setIsLoading(false);
336+
});
337+
} else {
317338
setIsLoading(false);
318-
});
339+
}
319340
}, 500),
320-
[application, props.filterItems]
341+
[application, props.filterItems, contextType, organizationId]
321342
);
322343

323344
useEffect(() => {
324345
debouncedUserSearch(searchValue);
325-
326346
return () => {
327347
debouncedUserSearch.cancel();
328348
};
329349
}, [searchValue, debouncedUserSearch]);
330350

331-
useEffect(() => {
332-
if (!application) return;
333-
334-
setIsLoading(true);
335-
fetchAvailableGroupsMembers(application.applicationId, "").then(res => {
336-
if(res.success) {
337-
setOptionViews(getPermissionOptionView(res.data, props.filterItems))
338-
}
339-
setIsLoading(false);
340-
}).catch(() => {
341-
setIsLoading(false);
342-
});
343-
}, [application, props.filterItems]);
351+
344352

345353
useEffect(() => {
346354
setRoleSelectVisible(selectedItems.length > 0);
@@ -425,8 +433,8 @@ export const Permission = (props: {
425433
supportRoles: { label: string; value: PermissionRole }[];
426434
onCancel: () => void;
427435
addPermission: (userIds: string[], groupIds: string[], role: string) => void;
428-
}) => {
429-
const { onCancel } = props;
436+
} & PermissionContextProps) => {
437+
const { onCancel, contextType = "application", organizationId } = props;
430438
const user = useSelector(getUser);
431439
const [selectRole, setSelectRole] = useState<ApplicationRoleType>("viewer");
432440
const [selectedItems, setSelectedItems] = useState<PermissionAddEntity[]>([]);
@@ -443,6 +451,8 @@ export const Permission = (props: {
443451
user={user}
444452
filterItems={props.filterItems}
445453
supportRoles={props.supportRoles}
454+
contextType={contextType}
455+
organizationId={organizationId}
446456
/>
447457
<BottomButton>
448458
<TacoButton style={{ marginRight: "8px" }} onClick={onCancel}>

client/packages/lowcoder/src/components/PermissionDialog/PermissionDialog.tsx

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,8 +57,10 @@ export const PermissionDialog = (props: {
5757
) => void;
5858
updatePermission: (permissionId: string, role: string) => void;
5959
deletePermission: (permissionId: string) => void;
60+
contextType?: "application" | "organization";
61+
organizationId?: string;
6062
}) => {
61-
const { supportRoles, permissionItems, visible, onVisibleChange, addPermission, viewBodyRender } =
63+
const { supportRoles, permissionItems, visible, onVisibleChange, addPermission, viewBodyRender, contextType, organizationId } =
6264
props;
6365
const [activeStepKey, setActiveStepKey] = useState("view");
6466

@@ -117,6 +119,8 @@ export const PermissionDialog = (props: {
117119
addPermission={(userIds, groupIds, role) =>
118120
addPermission(userIds, groupIds, role, props.back)
119121
}
122+
contextType={contextType || "application"}
123+
organizationId={organizationId}
120124
/>
121125
),
122126
footerRender: (props) => null,

client/packages/lowcoder/src/util/pagination/axios.ts

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,60 @@ export const fetchAvailableGroupsMembers = async (applicationId: string, search:
118118
}
119119
}
120120

121+
export const fetchAvailableOrgGroupsMembers = async (orgId: string, search: string = "") => {
122+
try {
123+
124+
125+
// Fetch org members and groups in parallel
126+
const [orgMembersResponse, groupsResponse] = await Promise.all([
127+
OrgApi.fetchOrgUsers(orgId),
128+
OrgApi.fetchGroup()
129+
]);
130+
131+
const orgMembers = orgMembersResponse.data.data.members || [];
132+
const groups = groupsResponse.data.data || [];
133+
134+
// Transform to the same format as application groups/members
135+
const transformedData = [
136+
// Add groups
137+
...groups.map((group: any) => ({
138+
type: "Group",
139+
data: {
140+
groupId: group.groupId,
141+
groupName: group.groupName,
142+
}
143+
})),
144+
// Add users
145+
...orgMembers.map((member: any) => ({
146+
type: "User",
147+
data: {
148+
userId: member.userId,
149+
name: member.name,
150+
avatarUrl: member.avatarUrl,
151+
}
152+
}))
153+
];
154+
155+
// Filter by search term if provided
156+
const filteredData = search ?
157+
transformedData.filter((item: any) => {
158+
const name = item.type === "Group" ? item.data.groupName : item.data.name;
159+
return name.toLowerCase().includes(search.toLowerCase());
160+
}) : transformedData;
161+
162+
return {
163+
success: true,
164+
data: filteredData
165+
};
166+
} catch (error: any) {
167+
console.error('Failed to fetch org data: ', error);
168+
return {
169+
success: false,
170+
error: error
171+
};
172+
}
173+
}
174+
121175
export const fetchOrgUsrPagination = async (request: fetchOrgUserRequestType)=> {
122176
try {
123177
const response = await OrgApi.fetchOrgUsersPagination(request);

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy