cancel
Showing results for 
Search instead for 
Did you mean: 
KC
Kudo Kingpin

PowerApps Department Org Chart

Scope:

Department Org Chart that surfaces the selected employee's direct reports.

 

Requirements:

 

Office365Users.png

2 Blank Vertical Galleries

1 Blank Horizontal Gallery

 

 

First Things First!

Azure Active Directory.

I am using my developer tenant in this post but this will work the same on any tenant.

You may wish to check with your company policies on displaying org charts.

I have a client where displaying an Org Chart of all personnel is not allowed.

 

Settings

Turn off Scale to fit and Lock aspect ratio located under File->App settings->Screen size + orientation ->Advanced settings

 

Connect

Add the Office365Users connector.

 

In the App OnStart property add the following:

// OrgChart - Set to the Department Manager
// We reset the variable TopLevelManager to the selected manager and their direct reports. Set( TopLevelManager, [DEPARTMENT MANAGER EMAIL ADDRESS / USERPRINCIPALNAME] )

 

Department Manager

Insert a Blank Vertical Gallery on the canvas,

Height: 161

Width: Parent.Width

Name: DepartmentManager

X: 0

Y: 0

Items: 

Office365Users.UserProfile(TopLevelManager)

Place in the DepartmentManager gallery an image control, three labels, a Rectangle icon, a Person icon, and a button.

Image: (Rounded Photo centered horizontally and vertically within the gallery)

Name: ManagerPhoto

Width: 100

Height: 100

BorderRadius: 60

X: Parent.Width / 2 - ManagerPhoto.Width / 2

Y: Parent.Height / 2 - ManagerPhoto.Height / 2

Image:

// Determine if employee has uploaded an Image to their profile. 
// Profile images can be uploaded through Delve.
// If no image is available, display the Person Icon.
If( !IsBlank(ThisItem.UserPrincipalName), If( Office365Users.UserPhotoMetadata(ThisItem.UserPrincipalName).HasPhoto = true, Office365Users.UserPhotoV2(ThisItem.UserPrincipalName) ) )

 

Label 1:

Name: ManagerName

Text: ThisItem.DisplayName

Color: RGBA(34, 181, 176, 1)

X: ManagerPhoto.X + ManagerPhoto.Width + 20 (Place to the right of the ManagerPhoto with 20 pixels of padding)

Y: 44

 

Label 2:

Name: ManagerTitle

Text: ThisItem.JobTitle

Color: RGBA(0, 0, 0, 1)

X: ManagerName.X

Y: 84

 

Label 3:

Name: ManagerDept

Text: ThisItem.JobTitle

Color: RGBA(0, 0, 0, 1)

X: ManagerName.X

Y: 116

 

Vertical Bar Icon: 

Icon: Rectangle

Width: 5

Height: 30

Fill: RGBA(34, 181, 176, 1)

X: ManagerPhoto.X + ManagerPhoto.Width / 2

Y: ManagerPhoto.Y + ManagerPhoto.Height + 10 (Place below the ManagerPhoto with 10 pixels of padding on top)

 

Person Icon: 

Icon: Person

Name: PersonIcon

Width: ManagerPhoto.Width

Height: ManagerPhoto.Height

Fill: RGBA(0, 0, 0, 0)

X: ManagerPhoto.X

Y: ManagerPhoto.Y

 

Button: 

Name: btnDeptManager

Width: 160

Height: 76

Text: Department Manager

X: 40

Y: 40

OnSelect: 

 

Set(
    TopLevelManager,
    [DEPARTMENT MANAGER EMAIL ADDRESS / USERPRINCIPALNAME]
)

NOTE: As you make changes to the app your controls may dissappear from time to time and you will see the Error icon, X in a red circle.

 

To fix this just select Run On Start in the App layer.

 

Also NOTE:

Responsive Design, if you manually move the control, the formula will be deleted and the X and Y will be set to a new hard coded coordinate. To fix this just add the appropriate formula once more.

 

1st Level Reports

Insert a Blank Horizontal Gallery onto the canvas just below the DepartmentManager gallery.

Height: Parent.Height

Width: Parent.Width

Name: Department

X: 0

Y: DepartmentManager.Y + DepartmentManager.Height

Items:

// We need to filter the DepartmentManager Direct Reports to only surface the direct reports for the given manager.
// We need to use the Not operator to only surface actual employee accounts whom have been assigned to a department
// due to some accounts in Active Directory are not actual Employee Accounts. These accounts could be
// Test Accounts, Room Accounts, Resource Accounts, Security Groups etc...

If( !IsBlank(First(DepartmentManager.AllItems).UserPrincipalName), Filter( Office365Users.DirectReports(First(DepartmentManager.AllItems).UserPrincipalName), Not(IsBlank(Department)) ) )

Place in the Department Gallery an Image control, three Labels, a Rectangle icon, a Person icon.

Image: (Rounded Photo centered horizontally and vertically within the gallery)

Name: ReportPhoto

Width: 88

Height: 88

BorderRadius: 60

X: Parent.X / 2 + ReportPhoto.Width / 2

Y: Parent.Y / 2 - ReportPhoto.Height / 2

OnSelect: 

Set(TopLevelManager,UserPrincipalName)

Image:

// Determine if employee has uploaded an Image to their profile. 
// Profile images can be uploaded through Delve.

If( !IsBlank(ThisItem.UserPrincipalName), If( Office365Users.UserPhotoMetadata(ThisItem.UserPrincipalName).HasPhoto = true, Office365Users.UserPhotoV2(ThisItem.UserPrincipalName) ) )

Person Icon: 

Icon: Person

Name: ReportIcon

Width: ReportPhoto.Width

Height: ReportPhoto.Height

Fill: RGBA(0, 0, 0, 0)

X: ReportPhoto.X

Y: ReportPhoto.Y

OnSelect: 

Set(TopLevelManager,UserPrincipalName)

Visible: true

Color

// If profile image is available set the PersonIcon color Opacity to 0 to hide it or 1 to show
// IMPORTANT: Person Icon must placed on top of the Profile Image for the 
// Hand Cursor to appear when the user rolls mouse pointer over the image
If(
    !IsBlank(Office365Users.UserPhotoMetadata(ThisItem.UserPrincipalName).HasPhoto = true,
    RGBA(
        0,
        18,
        107,
        0
    ),
    RGBA(
        0,
        18,
        107,
        1
    )
)

Label 1:

Name: titlePName

Text: ThisItem.UserPrincipalName

Color: RGBA(0, 0, 0, 1)

X: 0

Y: 0

Visible: False

 

Label 2:

Name: ReportName

Text: ThisItem.DisplayName

Color: RGBA(34, 181, 176, 1)

X: 0

Y: ReportPhoto.Y + ReportPhoto.Height + 10 (Place below the ReportPhoto with 10 pixels of padding on top)

Visible: True

 

Label 3:

Name: ReportDepartment

Text: ThisItem.Department

Color: RGBA(0, 0, 0, 1)

X: 0

Y: ReportName.Y + ReportName.Height + 10 (Place below the ReportName with 10 pixels of padding on top)

Visible: True

 

Vertical Bar Icon: 

Icon: Rectangle

Name: tieLine

Width: 5

Height: 30

Fill: RGBA(34, 181, 176, 1)

X: ReportDepartment.X + ReportDepartment.Width / 2

Y: ReportDepartment.Y + ReportDepartment.Height + 5 (Place below the ReportDepartment with 5 pixels of padding on top)

 

2nd Level Reports

Embed a Blank Vertical Gallery into the Department Gallery just below the Vertical Bar named tieLine.

 

Height: Parent.Height

Width: Parent.Width

Name: DirectReports

X: 0

Y: tieLine.Y + tieLine.Height

Items:

If(
    !IsBlank(titlePName.Text),
    Filter(
        Office365Users.DirectReports(titlePName.Text),
        Not(IsBlank(Department))
    )
)

Image: (Rounded Photo centered horizontally and vertically within the gallery)

Name: ReportPhoto_2

Width: 88

Height: 88

BorderRadius: 60

X: Parent.X / 2 + ReportPhoto_2.Width / 2

Y: Parent.Y / 2 - ReportPhoto_2.Height

 

OnSelect: 

Set(TopLevelManager,UserPrincipalName)

Image:

// Determine if employee has uploaded an Image to their profile. Profile images can be uploaded through Delve.
// If no image is available, display the Person Icon.
If( !IsBlank(ThisItem.UserPrincipalName), If( Office365Users.UserPhotoMetadata(ThisItem.UserPrincipalName).HasPhoto = true, Office365Users.UserPhotoV2(ThisItem.UserPrincipalName) ) )

 

Person Icon: 

Icon: Person

Name: ReportIcon

Width: ReportPhoto_2.Width

Height: ReportPhoto_2.Height

Fill: RGBA(0, 0, 0, 0)

X: ReportPhoto_2.X

Y: ReportPhoto_2.Y

OnSelect: 

Set(TopLevelManager,UserPrincipalName)

Visible: true

Color

// If profile image is available set the PersonIcon color Opacity to 0 to hide it or 1 to show
// IMPORTANT: Person Icon must placed on top of the Profile Image for the 
// Hand Cursor to appear when the user rolls mouse pointer over the image
If(
    !IsBlank(Office365Users.UserPhotoMetadata(ThisItem.UserPrincipalName).HasPhoto = true,
    RGBA(
        0,
        18,
        107,
        0
    ),
    RGBA(
        0,
        18,
        107,
        1
    )
)

 

Label 2:

Name: ReportName_2

Text: ThisItem.DisplayName

Color: RGBA(34, 181, 176, 1)

X: 0

Y: ReportPhoto_2.Y + ReportPhoto_2.Height + 10 (Place below the ReportPhoto_2 with 10 pixels of padding on top)

Visible: True

 

Label 3:

Name: ReportDepartment_2

Text: ThisItem.Department

Color: RGBA(0, 0, 0, 1)

X: 0

Y: ReportName_2.Y + ReportName_2.Height + 10 (Place below the ReportName_2 with 10 pixels of padding on top)

Visible: True

 

You should now have something similiar to

 

OrgChart.png

 

Comments

hello ... thank you for your efforts ,

can you just explain this step in more detail ,

I got an error when perform it 

 

Set(
    TopLevelManager,
    [DEPARTMENT MANAGER EMAIL ADDRESS / USERPRINCIPALNAME]
)
Kudo Kingpin

Hi Mays,

This variable would be set to the managers company email address, usually, the email address is also the same as the UserPrincipalName registered in your organizations Active Directory.

 

 

Hi @KC , thanks for this - I am getting it to work ok for the first 2 levels, but for the direct reports I am only getting the gallery going down and not accross if you see what I mean. I am getting test user and test user2 in your example but cant see how to get pebbles flintstone to be visable at the same time.

 

If I click on Barney Rubble I get him but then I miss out on Testuser2

 

thanks

 

Jambo

Having slept on it - I got it sorted - I hadnt embedded the direct reports gallery in the department gallery

thanks

 

Jambo

Kudo Kingpin

Hi Jambo,

Sorry for the late reply, I'm glad you were able to sort this out.

Hi KC,

 

I tried to set up the org chart following your tuto but, I can't make it worked correctly.

In the App "OnStart" function, I've set up : Set(TopLevelManager,"name@domain.com") replacing by my manager email. I have done the same in the btnDptManager "OnSelect" function.

In the "Items" function of the gallery DepartmentManager, I've set : Office365Users.UserProfile(TopLevelManager) but I have the issue : Invalid argument type (Error). Expecting a text value instead.

Same for ReportIcon and ReportPhoto "OnSelect" function, I've set : Set(TopLevelManager,UserPrincipalName) and I have issue : "Name isn"t valid. This identifier isn't recognized.

 

I am pretty sure it's only a little issue, but I've spent time on it and I cannot find a solution... I've made it work using ThisItem.UserPrincipalName for some functions but some others are not working well if I do that.

 

Thanks for the help,

 

ArtS

This is great, and helpful;  I really wanted to build a table dynamically of where a user sits in the organizational hierarchy.  This is what I came up with;  I made an assumption that any individual is never more than 10 levels deep.

 

combined a few things to get this working;
collections (table)
using ForAll() to "do something a number of times"

"iterated over" a static "Loop" collection... I'm sure there are simpler ways to control the "number of times"
referencing the last table row's value when adding another row to the collection/table

Last(<collection>).<attribute_name>
and checking for errors... if using Office365Users.ManagerV2() has an error, don't add anything the the collection.
its not the most elegant, but hey, this is powerapps.
results in a collection of the User and their management hierarchy; and saves a comma separated list of all the email addresses.
The collection can be used as the data source for a vertical gallery, for example.

 

ClearCollect(Loop,
{Index:0},
{Index:1},
{Index:2},
{Index:3},
{Index:4},
{Index:5},
{Index:6},
{Index:7},
{Index:8},
{Index:9},
{Index:10}
);
ClearCollect(org_hier,
{email:Office365Users.UserProfileV2(User().Email).mail, name:Office365Users.UserProfileV2(User().Email).displayName});
ForAll(Filter(Loop,Index<=10),
If(!IsError(Office365Users.ManagerV2(Last(org_hier).email).mail),
Collect(org_hier,
{email:Office365Users.ManagerV2(Last(org_hier).email).mail, name:Office365Users.ManagerV2(Last(org_hier).email).displayName})
)
);
Set(org_string,Concat(org_hier.email, email, ", "));