@@ -3,16 +3,15 @@ import {
33 CloseIcon ,
44 CommonTextLabel ,
55 CustomSelect ,
6+ Search ,
67 TacoButton ,
78} from "lowcoder-design" ;
8- import { useEffect , useRef , useState } from "react" ;
9+ import { useEffect , useRef , useState , useCallback } from "react" ;
910import styled from "styled-components" ;
11+ import { debounce } from "lodash" ;
1012import ProfileImage from "pages/common/profileImage" ;
11- import { useDispatch , useSelector } from "react-redux" ;
12- import { fetchGroupsAction , fetchOrgUsersAction } from "redux/reduxActions/orgActions" ;
13- import { getOrgGroups , getOrgUsers } from "redux/selectors/orgSelectors" ;
14- import { OrgGroup , OrgUser } from "constants/orgConstants" ;
15- import { ApplicationPermissionType , ApplicationRoleType } from "constants/applicationConstants" ;
13+ import { useSelector } from "react-redux" ;
14+ import { ApplicationPermissionType , ApplicationRoleType , GroupsMembersPermission } from "constants/applicationConstants" ;
1615import {
1716 PermissionItemName ,
1817 RoleSelectOption ,
@@ -27,6 +26,8 @@ import { getUser } from "redux/selectors/usersSelectors";
2726import { EmptyContent } from "pages/common/styledComponent" ;
2827import { trans } from "i18n" ;
2928import { PermissionItem } from "./PermissionList" ;
29+ import { currentApplication } from "@lowcoder-ee/redux/selectors/applicationSelector" ;
30+ import { fetchAvailableGroupsMembers } from "@lowcoder-ee/util/pagination/axios" ;
3031
3132const AddAppUserContent = styled . div `
3233 display: flex;
@@ -86,20 +87,19 @@ const PermissionSelectWrapper = styled.div`
8687 padding: 4px 8px;
8788 margin-top: 8px;
8889 background: #fdfdfd;
89- outline: 1px solid #d7d9e0;
90- border-radius: 4px;
90+ outline: 1px dashed #d7d9e0;
9191
9292 .ant-select {
9393 font-size: 13px;
9494 line-height: 13px;
9595 }
9696
9797 &:hover {
98- outline: 1px solid #8b8fa3;
98+ outline: 1px dashed #8b8fa3;
9999 }
100100
101101 &:focus-within {
102- outline: 1px solid #315efb ;
102+ outline: 1px dashed rgb(203, 212, 245) ;
103103 border-radius: 4px;
104104 box-shadow: 0 0 0 3px rgb(24 144 255 / 20%);
105105 }
@@ -199,48 +199,34 @@ type PermissionAddEntity = {
199199 key : string ;
200200} ;
201201
202- /**
203- * compose users and groups's permissions, filter the data
204- *
205- * @param orgGroups groups
206- * @param orgUsers users
207- * @param currentUser currentUser
208- * @param filterItems filterItems
209- */
202+ function isGroup ( data : GroupsMembersPermission ) {
203+ return data ?. type === "Group"
204+ }
205+
210206function getPermissionOptionView (
211- orgGroups : OrgGroup [ ] ,
212- orgUsers : OrgUser [ ] ,
213- currentUser : User ,
207+ groupsMembers : GroupsMembersPermission [ ] ,
214208 filterItems : PermissionItem [ ]
215209) : AddAppOptionView [ ] {
216- let permissionViews : AddAppOptionView [ ] = orgGroups . map ( ( group ) => {
210+
211+ let permissionsViews = groupsMembers ?. map ( ( user ) => {
217212 return {
218- type : "GROUP" ,
219- id : group . groupId ,
220- name : group . groupName ,
221- } ;
222- } ) ;
223- permissionViews = permissionViews . concat (
224- orgUsers . map ( ( user ) => {
225- return {
226- type : "USER" ,
227- id : user . userId ,
228- name : user . name ,
229- avatarUrl : user . avatarUrl ,
230- } ;
231- } )
232- ) ;
233- permissionViews = permissionViews . filter (
234- ( v ) =>
235- ! filterItems . find ( ( i ) => i . id === v . id && i . type === v . type ) &&
236- ! ( v . type === "USER" && v . id === currentUser . id )
213+ type : user . type as ApplicationPermissionType ,
214+ id : isGroup ( user ) ? user . data . groupId : user . data . userId ,
215+ name : isGroup ( user ) ? user . data . groupName : user . data . name ,
216+ ...( isGroup ( user ) ? { } : { avatarUrl : user . data . avatarUrl } )
217+ }
218+ } )
219+
220+ permissionsViews = permissionsViews . filter ( ( v ) =>
221+ ! filterItems . find ( ( i ) => i . id === v . id && i . type === v . type )
237222 ) ;
238- return permissionViews ;
223+
224+ return permissionsViews . filter ( ( v ) => v . id && v . name ) as AddAppOptionView [ ] ;
239225}
240226
241227function PermissionSelectorOption ( props : { optionView : AddAppOptionView } ) {
242228 const { optionView } = props ;
243- const groupIcon = optionView . type === "GROUP " && (
229+ const groupIcon = optionView . type === "Group " && (
244230 < StyledGroupIcon $color = { getInitialsAndColorCode ( optionView . name ) [ 1 ] } />
245231 ) ;
246232 return (
@@ -258,7 +244,7 @@ function PermissionSelectorOption(props: { optionView: AddAppOptionView }) {
258244
259245function PermissionSelectorLabel ( props : { view : AddAppOptionView } ) {
260246 const { view } = props ;
261- const groupIcon = view . type === "GROUP " && (
247+ const groupIcon = view . type === "Group " && (
262248 < StyledGroupIcon $color = { getInitialsAndColorCode ( view . name ) [ 1 ] } $side = { 9 } />
263249 ) ;
264250 return (
@@ -309,12 +295,52 @@ const PermissionSelector = (props: {
309295 filterItems : PermissionItem [ ] ;
310296 supportRoles : { label : string ; value : PermissionRole } [ ] ;
311297} ) => {
312- const orgGroups = useSelector ( getOrgGroups ) ;
313- const orgUsers = useSelector ( getOrgUsers ) ;
314298 const { selectedItems, setSelectRole, setSelectedItems, user } = props ;
315- const optionViews = getPermissionOptionView ( orgGroups , orgUsers , user , props . filterItems ) ;
316299 const [ roleSelectVisible , setRoleSelectVisible ] = useState ( false ) ;
317300 const selectRef = useRef < HTMLDivElement > ( null ) ;
301+ const [ optionViews , setOptionViews ] = useState < AddAppOptionView [ ] > ( )
302+ const [ searchValue , setSearchValue ] = useState ( "" ) ;
303+ const [ isLoading , setIsLoading ] = useState ( false ) ;
304+ const application = useSelector ( currentApplication )
305+
306+ const debouncedUserSearch = useCallback (
307+ debounce ( ( searchTerm : string ) => {
308+ if ( ! application ) return ;
309+
310+ 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 ( ( ) => {
317+ setIsLoading ( false ) ;
318+ } ) ;
319+ } , 500 ) ,
320+ [ application , props . filterItems ]
321+ ) ;
322+
323+ useEffect ( ( ) => {
324+ debouncedUserSearch ( searchValue ) ;
325+
326+ return ( ) => {
327+ debouncedUserSearch . cancel ( ) ;
328+ } ;
329+ } , [ searchValue , debouncedUserSearch ] ) ;
330+
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 ] ) ;
318344
319345 useEffect ( ( ) => {
320346 setRoleSelectVisible ( selectedItems . length > 0 ) ;
@@ -325,12 +351,18 @@ const PermissionSelector = (props: {
325351
326352 return (
327353 < >
354+ < Search
355+ placeholder = { trans ( "home.addPermissionPlaceholder" ) }
356+ value = { searchValue }
357+ onChange = { ( e ) => setSearchValue ( e . target . value ) }
358+ />
328359 < PermissionSelectWrapper >
329360 < AddPermissionsSelect
330361 open
331362 ref = { selectRef }
332- placeholder = { trans ( "home.addPermissionPlaceholder " ) }
363+ placeholder = { trans ( "home.selectedUsersAndGroups " ) }
333364 mode = "multiple"
365+ showSearch = { false }
334366 getPopupContainer = { ( ) => document . getElementById ( "add-app-user-permission-dropdown" ) ! }
335367 optionLabelProp = "label"
336368 tagRender = { PermissionTagRender }
@@ -350,7 +382,7 @@ const PermissionSelector = (props: {
350382 setSelectedItems ( selectedItems . filter ( ( item ) => item . key !== option . key ) ) ;
351383 } }
352384 >
353- { optionViews . map ( ( view ) => {
385+ { optionViews ? .map ( ( view ) => {
354386 return (
355387 < CustomSelect . Option
356388 key = { `${ view . type } -${ view . id } ` }
@@ -395,16 +427,10 @@ export const Permission = (props: {
395427 addPermission : ( userIds : string [ ] , groupIds : string [ ] , role : string ) => void ;
396428} ) => {
397429 const { onCancel } = props ;
398- const dispatch = useDispatch ( ) ;
399430 const user = useSelector ( getUser ) ;
400431 const [ selectRole , setSelectRole ] = useState < ApplicationRoleType > ( "viewer" ) ;
401432 const [ selectedItems , setSelectedItems ] = useState < PermissionAddEntity [ ] > ( [ ] ) ;
402433
403- useEffect ( ( ) => {
404- dispatch ( fetchOrgUsersAction ( user . currentOrgId ) ) ;
405- dispatch ( fetchGroupsAction ( user . currentOrgId ) ) ;
406- } , [ ] ) ;
407-
408434 return (
409435 < AddAppUserContent >
410436 < CommonTextLabel style = { { marginTop : "16px" } } >
@@ -426,10 +452,10 @@ export const Permission = (props: {
426452 buttonType = "primary"
427453 onClick = { ( ) => {
428454 const uids = selectedItems
429- . filter ( ( item ) => item . type === "USER " )
455+ . filter ( ( item ) => item . type === "User " )
430456 . map ( ( item ) => item . id ) ;
431457 const gids = selectedItems
432- . filter ( ( item ) => item . type === "GROUP " )
458+ . filter ( ( item ) => item . type === "Group " )
433459 . map ( ( item ) => item . id ) ;
434460 if ( uids . length === 0 && gids . length === 0 ) {
435461 onCancel ( ) ;
0 commit comments