diff --git a/app/client/cypress/integration/Smoke_TestSuite/OrganisationTests/OrgUserIconTest_spec.js b/app/client/cypress/integration/Smoke_TestSuite/OrganisationTests/OrgUserIconTest_spec.js
new file mode 100644
index 0000000000..9b45f42465
--- /dev/null
+++ b/app/client/cypress/integration/Smoke_TestSuite/OrganisationTests/OrgUserIconTest_spec.js
@@ -0,0 +1,25 @@
+///
+
+const homePage = require("../../../locators/HomePage.json");
+
+describe("Check if org has user icons on homepage", function() {
+ let orgid;
+
+ it("create org and check if user icons exists in that org on homepage", function() {
+ cy.NavigateToHome();
+ cy.generateUUID().then(uid => {
+ orgid = uid;
+ localStorage.setItem("OrgName", orgid);
+ cy.createOrg(orgid);
+ cy.get(homePage.orgList.concat(orgid).concat(")"))
+ .scrollIntoView()
+ .should("be.visible")
+ .within(() => {
+ cy.get(homePage.shareUserIcons)
+ .first()
+ .should("be.visible");
+ });
+ });
+ cy.LogOut();
+ });
+});
diff --git a/app/client/cypress/locators/HomePage.json b/app/client/cypress/locators/HomePage.json
index 3a31c08531..728dd5800e 100644
--- a/app/client/cypress/locators/HomePage.json
+++ b/app/client/cypress/locators/HomePage.json
@@ -61,5 +61,6 @@
"orgWebsiteInput": "[data-cy=t--org-website-input]",
"orgHeaderName": ".t--organization-header",
"leftPanelContainer": "[data-cy=t--left-panel]",
- "themeText": "label div"
+ "themeText": "label div",
+ "shareUserIcons": ".org-share-user-icons"
}
diff --git a/app/client/src/api/ApplicationApi.tsx b/app/client/src/api/ApplicationApi.tsx
index fe630e57c9..693c0940b0 100644
--- a/app/client/src/api/ApplicationApi.tsx
+++ b/app/client/src/api/ApplicationApi.tsx
@@ -83,12 +83,19 @@ export interface ApplicationObject {
userPermissions: string[];
}
+export interface UserRoles {
+ name: string;
+ roleName: string;
+ username: string;
+}
+
export interface OrganizationApplicationObject {
applications: Array;
organization: {
id: string;
name: string;
};
+ userRoles: Array;
}
export interface FetchUsersApplicationsOrgsResponse extends ApiResponse {
data: {
diff --git a/app/client/src/pages/Applications/index.tsx b/app/client/src/pages/Applications/index.tsx
index 660c9374be..665de33701 100644
--- a/app/client/src/pages/Applications/index.tsx
+++ b/app/client/src/pages/Applications/index.tsx
@@ -28,10 +28,7 @@ import FormDialogComponent from "components/editorComponents/form/FormDialogComp
import { User } from "constants/userConstants";
import { getCurrentUser } from "selectors/usersSelectors";
import CreateOrganizationForm from "pages/organization/CreateOrganizationForm";
-import {
- CREATE_ORGANIZATION_FORM_NAME,
- CREATE_APPLICATION_FORM_NAME,
-} from "constants/forms";
+import { CREATE_ORGANIZATION_FORM_NAME } from "constants/forms";
import {
getOnSelectAction,
DropdownOnSelectActions,
@@ -48,7 +45,7 @@ import { Classes } from "components/ads/common";
import Menu from "components/ads/Menu";
import { Position } from "@blueprintjs/core/lib/esm/common/position";
import HelpModal from "components/designSystems/appsmith/help/HelpModal";
-import { UpdateApplicationPayload } from "api/ApplicationApi";
+import { UpdateApplicationPayload, UserRoles } from "api/ApplicationApi";
import PerformanceTracker, {
PerformanceTransactionName,
} from "utils/PerformanceTracker";
@@ -58,6 +55,7 @@ import CenteredWrapper from "../../components/designSystems/appsmith/CenteredWra
import NoSearchImage from "../../assets/images/NoSearchResult.svg";
import { getNextEntityName } from "utils/AppsmithUtils";
import Spinner from "components/ads/Spinner";
+import ProfileImage from "pages/common/ProfileImage";
const OrgDropDown = styled.div`
display: flex;
@@ -193,6 +191,25 @@ const ItemWrapper = styled.div`
const StyledIcon = styled(Icon)`
margin-right: 11px;
`;
+const UserImageContainer = styled.div`
+ display: flex;
+ margin-right: 8px;
+
+ div {
+ cursor: default;
+ margin-right: -6px;
+ width: 24px;
+ height: 24px;
+ }
+
+ div:last-child {
+ margin-right: 0px;
+ }
+`;
+const OrgShareUsers = styled.div`
+ display: flex;
+ align-items: center;
+`;
function Item(props: {
label: string;
@@ -536,7 +553,7 @@ const ApplicationsSection = (props: any) => {
} else {
organizationsListComponent = updatedOrgs.map(
(organizationObject: any, index: number) => {
- const { organization, applications } = organizationObject;
+ const { organization, applications, userRoles } = organizationObject;
const hasManageOrgPermissions = isPermitted(
organization.userPermissions,
PERMISSION_TYPE.MANAGE_ORGANIZATION,
@@ -572,15 +589,30 @@ const ApplicationsSection = (props: any) => {
PERMISSION_TYPE.INVITE_USER_TO_ORGANIZATION,
) &&
!isFetchingApplications && (
-
- }
- canOutsideClickClose={true}
- Form={OrgInviteUsersForm}
- orgId={organization.id}
- title={`Invite Users to ${organization.name}`}
- />
+
+
+ {userRoles.map((el: UserRoles) => (
+
+ ))}
+
+
+ }
+ canOutsideClickClose={true}
+ Form={OrgInviteUsersForm}
+ orgId={organization.id}
+ title={`Invite Users to ${organization.name}`}
+ />
+
)}
diff --git a/app/client/src/pages/common/ProfileDropdown.tsx b/app/client/src/pages/common/ProfileDropdown.tsx
index 77608a724f..c27296b588 100644
--- a/app/client/src/pages/common/ProfileDropdown.tsx
+++ b/app/client/src/pages/common/ProfileDropdown.tsx
@@ -1,8 +1,5 @@
import React, { Fragment } from "react";
import { CommonComponentProps, Classes } from "components/ads/common";
-import { getInitialsAndColorCode } from "utils/AppsmithUtils";
-import { useSelector } from "react-redux";
-import { getThemeDetails } from "selectors/themeSelectors";
import Text, { TextType } from "components/ads/Text";
import styled, { createGlobalStyle } from "styled-components";
import { Position } from "@blueprintjs/core";
@@ -15,23 +12,13 @@ import {
DropdownOnSelectActions,
} from "./CustomizedDropdown/dropdownHelpers";
import { ReduxActionTypes } from "constants/ReduxActionConstants";
+import ProfileImage from "./ProfileImage";
type TagProps = CommonComponentProps & {
onClick?: (text: string) => void;
userName?: string;
};
-export const ProfileImage = styled.div<{ backgroundColor?: string }>`
- width: 34px;
- height: 34px;
- display: flex;
- align-items: center;
- border-radius: 50%;
- justify-content: center;
- cursor: pointer;
- background-color: ${props => props.backgroundColor};
-`;
-
const ProfileMenuStyle = createGlobalStyle`
.bp3-popover {
box-shadow: none;
@@ -67,20 +54,8 @@ const UserInformation = styled.div`
`;
export default function ProfileDropdown(props: TagProps) {
- const themeDetails = useSelector(getThemeDetails);
+ const Profile = ;
- const initialsAndColorCode = getInitialsAndColorCode(
- props.userName,
- themeDetails.theme.colors.appCardColors,
- );
-
- const Profile = (
-
-
- {initialsAndColorCode[0]}
-
-
- );
return (
diff --git a/app/client/src/pages/common/ProfileImage.tsx b/app/client/src/pages/common/ProfileImage.tsx
new file mode 100644
index 0000000000..83eef9b28f
--- /dev/null
+++ b/app/client/src/pages/common/ProfileImage.tsx
@@ -0,0 +1,40 @@
+import React from "react";
+import { useSelector } from "react-redux";
+import { getThemeDetails } from "selectors/themeSelectors";
+import { getInitialsAndColorCode } from "utils/AppsmithUtils";
+import Text, { TextType } from "components/ads/Text";
+import styled from "styled-components";
+
+export const Profile = styled.div<{ backgroundColor?: string }>`
+ width: 34px;
+ height: 34px;
+ display: flex;
+ align-items: center;
+ border-radius: 50%;
+ justify-content: center;
+ cursor: pointer;
+ background-color: ${props => props.backgroundColor};
+`;
+
+export default function ProfileImage(props: {
+ userName?: string;
+ className?: string;
+}) {
+ const themeDetails = useSelector(getThemeDetails);
+
+ const initialsAndColorCode = getInitialsAndColorCode(
+ props.userName,
+ themeDetails.theme.colors.appCardColors,
+ );
+
+ return (
+
+
+ {initialsAndColorCode[0]}
+
+
+ );
+}
diff --git a/app/client/src/pages/organization/OrgInviteUsersForm.tsx b/app/client/src/pages/organization/OrgInviteUsersForm.tsx
index a021b08207..6618083799 100644
--- a/app/client/src/pages/organization/OrgInviteUsersForm.tsx
+++ b/app/client/src/pages/organization/OrgInviteUsersForm.tsx
@@ -38,8 +38,8 @@ import { Classes } from "components/ads/common";
import Callout from "components/ads/Callout";
import { getInitialsAndColorCode } from "utils/AppsmithUtils";
import { getThemeDetails } from "selectors/themeSelectors";
-import { ProfileImage } from "pages/common/ProfileDropdown";
import { scrollbarDark } from "constants/DefaultTheme";
+import ProfileImage from "pages/common/ProfileImage";
const OrgInviteTitle = styled.div`
padding: 10px 0px;
@@ -280,7 +280,6 @@ const OrgInviteUsersForm = (props: any) => {
);
return {
...user,
- imageBackground: details[1],
initials: details[0],
};
},
@@ -358,18 +357,13 @@ const OrgInviteUsersForm = (props: any) => {
username: string;
name: string;
roleName: string;
- imageBackground: string;
initials: string;
}) => {
return (
-
-
- {user.initials}
-
-
+
{user.name}
{user.username}
diff --git a/app/client/src/sagas/ApplicationSagas.tsx b/app/client/src/sagas/ApplicationSagas.tsx
index d7dd6d6983..686f083382 100644
--- a/app/client/src/sagas/ApplicationSagas.tsx
+++ b/app/client/src/sagas/ApplicationSagas.tsx
@@ -88,6 +88,7 @@ export function* getAllApplicationSaga() {
const organizationApplication: OrganizationApplicationObject[] = response.data.organizationApplications.map(
(userOrgs: OrganizationApplicationObject) => ({
organization: userOrgs.organization,
+ userRoles: userOrgs.userRoles,
applications: !userOrgs.applications
? []
: userOrgs.applications.map((application: ApplicationObject) => {