added module of real time sharing icon tile when sharing user (#8908)

Co-authored-by: Albin <albin@appsmith.com>
This commit is contained in:
haojin111 2021-11-02 06:33:51 +02:00 committed by GitHub
parent f17d2793c0
commit 77e3c4f4db
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 52 additions and 14 deletions

View File

@ -326,6 +326,7 @@ export const ReduxActionTypes = {
FETCH_APPLICATION_SUCCESS: "FETCH_APPLICATION_SUCCESS", FETCH_APPLICATION_SUCCESS: "FETCH_APPLICATION_SUCCESS",
CREATE_APPLICATION_INIT: "CREATE_APPLICATION_INIT", CREATE_APPLICATION_INIT: "CREATE_APPLICATION_INIT",
CREATE_APPLICATION_SUCCESS: "CREATE_APPLICATION_SUCCESS", CREATE_APPLICATION_SUCCESS: "CREATE_APPLICATION_SUCCESS",
INVITED_USERS_TO_ORGANIZATION: "INVITED_USERS_TO_ORGANIZATION",
UPDATE_WIDGET_PROPERTY_VALIDATION: "UPDATE_WIDGET_PROPERTY_VALIDATION", UPDATE_WIDGET_PROPERTY_VALIDATION: "UPDATE_WIDGET_PROPERTY_VALIDATION",
HIDE_PROPERTY_PANE: "HIDE_PROPERTY_PANE", HIDE_PROPERTY_PANE: "HIDE_PROPERTY_PANE",
INIT_DATASOURCE_PANE: "INIT_DATASOURCE_PANE", INIT_DATASOURCE_PANE: "INIT_DATASOURCE_PANE",

View File

@ -28,4 +28,5 @@ export type OrgUser = {
export type Organization = { export type Organization = {
applications: ApplicationPayload[]; applications: ApplicationPayload[];
organization: Org; organization: Org;
userRoles: OrgUser[];
}; };

View File

@ -661,7 +661,7 @@ function ApplicationsSection(props: any) {
} else { } else {
organizationsListComponent = updatedOrgs.map( organizationsListComponent = updatedOrgs.map(
(organizationObject: any, index: number) => { (organizationObject: any, index: number) => {
const { applications, organization, userRoles } = organizationObject; const { applications, organization } = organizationObject;
const hasManageOrgPermissions = isPermitted( const hasManageOrgPermissions = isPermitted(
organization.userPermissions, organization.userPermissions,
PERMISSION_TYPE.MANAGE_ORGANIZATION, PERMISSION_TYPE.MANAGE_ORGANIZATION,
@ -700,7 +700,7 @@ function ApplicationsSection(props: any) {
) && ) &&
!isFetchingApplications && ( !isFetchingApplications && (
<OrgShareUsers> <OrgShareUsers>
<SharedUserList userRoles={userRoles} /> <SharedUserList orgId={organization.id} />
<FormDialogComponent <FormDialogComponent
Form={OrgInviteUsersForm} Form={OrgInviteUsersForm}
canOutsideClickClose canOutsideClickClose

View File

@ -1,12 +1,13 @@
import { Popover, PopoverInteractionKind, Position } from "@blueprintjs/core"; import { Popover, PopoverInteractionKind, Position } from "@blueprintjs/core";
import { UserRoles } from "api/ApplicationApi";
import UserApi from "api/UserApi"; import UserApi from "api/UserApi";
import React from "react"; import React, { useMemo } from "react";
import { getCurrentUser } from "selectors/usersSelectors"; import { getCurrentUser } from "selectors/usersSelectors";
import { useSelector } from "store"; import { useSelector } from "store";
import styled from "styled-components"; import styled from "styled-components";
import ProfileImage from "./ProfileImage"; import ProfileImage from "./ProfileImage";
import ScrollIndicator from "components/ads/ScrollIndicator"; import ScrollIndicator from "components/ads/ScrollIndicator";
import { OrgUser } from "constants/orgConstants";
import { getUserApplicationsOrgsList } from "selectors/applicationSelectors";
const UserImageContainer = styled.div` const UserImageContainer = styled.div`
display: flex; display: flex;
@ -62,17 +63,22 @@ const ProfileImageMore = styled(ProfileImage)`
} }
`; `;
type SharedUserListProps = { export default function SharedUserList(props: any) {
userRoles: UserRoles[];
};
export default function SharedUserList({ userRoles }: SharedUserListProps) {
const currentUser = useSelector(getCurrentUser); const currentUser = useSelector(getCurrentUser);
const scrollWrapperRef = React.createRef<HTMLUListElement>(); const scrollWrapperRef = React.createRef<HTMLUListElement>();
const userOrgs = useSelector(getUserApplicationsOrgsList);
const allUsers = useMemo(() => {
const org: any = userOrgs.find((organizationObject: any) => {
const { organization } = organizationObject;
return organization.id === props.orgId;
});
const { userRoles } = org;
return userRoles || [];
}, [userOrgs]);
return ( return (
<UserImageContainer> <UserImageContainer>
{userRoles.slice(0, 5).map((el: UserRoles) => ( {allUsers.slice(0, 5).map((el: OrgUser) => (
<Popover <Popover
boundary="viewport" boundary="viewport"
hoverCloseDelay={100} hoverCloseDelay={100}
@ -92,7 +98,7 @@ export default function SharedUserList({ userRoles }: SharedUserListProps) {
</ProfileImagePopover> </ProfileImagePopover>
</Popover> </Popover>
))} ))}
{userRoles.length > 5 ? ( {allUsers.length > 5 ? (
<Popover <Popover
hoverCloseDelay={0} hoverCloseDelay={0}
interactionKind={PopoverInteractionKind.CLICK} interactionKind={PopoverInteractionKind.CLICK}
@ -101,10 +107,10 @@ export default function SharedUserList({ userRoles }: SharedUserListProps) {
> >
<ProfileImageMore <ProfileImageMore
className="org-share-user-icons" className="org-share-user-icons"
commonName={`+${userRoles.length - 5}`} commonName={`+${allUsers.length - 5}`}
/> />
<ProfileImageListPopover ref={scrollWrapperRef}> <ProfileImageListPopover ref={scrollWrapperRef}>
{userRoles.slice(5).map((el) => ( {allUsers.slice(5).map((el: OrgUser) => (
<ProfileImageListItem key={el.username}> <ProfileImageListItem key={el.username}>
<ProfileImage <ProfileImage
className="org-share-user-icons" className="org-share-user-icons"

View File

@ -6,7 +6,7 @@ import {
ApplicationPayload, ApplicationPayload,
CurrentApplicationData, CurrentApplicationData,
} from "constants/ReduxActionConstants"; } from "constants/ReduxActionConstants";
import { Organization } from "constants/orgConstants"; import { Organization, OrgUser } from "constants/orgConstants";
import { import {
createMessage, createMessage,
ERROR_MESSAGE_CREATE_APPLICATION, ERROR_MESSAGE_CREATE_APPLICATION,
@ -174,6 +174,26 @@ const applicationsReducer = createReducer(initialState, {
userOrgs: _organizations, userOrgs: _organizations,
}; };
}, },
[ReduxActionTypes.INVITED_USERS_TO_ORGANIZATION]: (
state: ApplicationsReduxState,
action: ReduxAction<{ orgId: string; users: OrgUser[] }>,
) => {
const _organizations = state.userOrgs.map((org: Organization) => {
if (org.organization.id === action.payload.orgId) {
const userRoles = org.userRoles;
org.userRoles = [...userRoles, ...action.payload.users];
return {
...org,
};
}
return org;
});
return {
...state,
userOrgs: _organizations,
};
},
[ReduxActionErrorTypes.CREATE_APPLICATION_ERROR]: ( [ReduxActionErrorTypes.CREATE_APPLICATION_ERROR]: (
state: ApplicationsReduxState, state: ApplicationsReduxState,
action: ReduxAction<{ orgId: string }>, action: ReduxAction<{ orgId: string }>,

View File

@ -293,6 +293,16 @@ export function* inviteUsers(
orgId: data.orgId, orgId: data.orgId,
}, },
}); });
yield put({
type: ReduxActionTypes.INVITED_USERS_TO_ORGANIZATION,
payload: {
orgId: data.orgId,
users: data.usernames.map((name: string) => ({
username: name,
roleName: data.roleName,
})),
},
});
yield call(resolve); yield call(resolve);
yield put(reset(INVITE_USERS_TO_ORG_FORM)); yield put(reset(INVITE_USERS_TO_ORG_FORM));
} catch (error) { } catch (error) {