Skip to main content

Build an Overtime Timesheet App in Power Apps — Part 9: Show Approvers What's Waiting

· 38 min read
Jagdish Kumawat
Founder @ Dewiride

Approvers get each overtime request in Teams and Outlook. This part gives them a screen in the app with everything waiting for their decision. Approvers can't open other people's entries in SharePoint, so a flow reads the pending entries and returns only those from the departments the approver looks after.

This is Part 9 of a 20-part series.

  1. Part 1: Plan the App and Set Up the Demo Organization
  2. Part 2: Create the SharePoint Site and Lists
  3. Part 3: Keep Overtime Private with SharePoint Permissions
  4. Part 4: Create the Solution, Environment Variables and Canvas App
  5. Part 5: Build the Home Screen
  6. Part 6: Build the Log Overtime Screen
  7. Part 7: Build the My Overtime Screen
  8. Part 8: Build the Approval Flow for Teams and Outlook
  9. Part 9: Show Approvers What's Waiting (you are here)
  10. Part 10: Build the Departments Screen (coming soon)
  11. Part 11: Build the Reports Screen (coming soon)
  12. Part 12: Import the Old Excel Timesheet (coming soon)
  13. Part 13: Create the Monthly Payroll Workbook with Office Scripts (coming soon)
  14. Part 14: Build the Power BI Overtime Report (coming soon)
  15. Part 15: Share the App and Add It to Microsoft Teams (coming soon)
  16. Part 16: Test Every Role and Department (coming soon)
  17. Part 17: Build a Setup Flow That Creates the Lists (coming soon)
  18. Part 18: Run the Solution Checker and Export the Solutions (coming soon)
  19. Part 19: Install the App in a New Environment (coming soon)
  20. Part 20: Recap, Production Checklist and Next Steps (coming soon)

Since Part 5, the Home screen has shown approvers a Waiting for approval button that did nothing. This part builds what it opens: Get Waiting Approvals, a flow the app runs, and the Waiting for Approval screen. Then it shares both with two approvers and tests the screen as each of them. Each generic task has its own guide; this part gives the values for this app, and why.

What You'll Build​

The finished flow, action by action:

Get Waiting Approvals
When Power Apps calls a flow (V2)
├─ Get the caller Get my profile (V2): who is running the flow
├─ Initialize MyDepartmentIds Initialize variable: an empty list
├─ Get the departments Get items: every department
├─ For each department
│ ├─ Approver emails Select: its approvers' emails, lower case
│ └─ Check the caller approves it Condition: is the caller one of them?
│ └─ True: Add the department Append to array variable: its ID
├─ Get the pending entries Get items: Status Pending, oldest shift first
├─ Entries waiting for the caller Filter array: their departments, not their own
├─ Waiting entries Select: seven fields of each entry
└─ Respond to the app Respond to a Power App or flow: entries, as JSON text

What an approver sees, here Olivia Bennett, who approves the Emergency Department:

The Waiting for approval screen with Back and Refresh in the green header, the line 2 entries are waiting for your decision, a note that each entry is approved or rejected in the Approvals app in Microsoft Teams, from its email in Outlook, or in Power Automate, and two cards for Admin User: Thu 29/10/2026, 18:00 to 20:00, 2.00 hours, Emergency Department, waiting since 10/11/2026 11:21, and Sun 08/11/2026, 08:00 to 11:00, 3.00 hours, Emergency Department, waiting since 10/11/2026 11:20

How It Works​

The decisions behind the screen:

  • A flow, because approvers can't read the entries. Part 3 set OvertimeEntries so that people can read only their own items. An approver's own SharePoint connection would return only their own entries. The flow reads the list with its owner's SharePoint connection instead, and decides itself what each approver gets.
  • The flow finds out who's asking. Its Office 365 Users connection belongs to the person running it, so Get my profile (V2) returns that person. The app sends the flow nothing, so nobody can ask for someone else's entries by changing what the app sends.
  • The departments come from the Departments list. An approver is anyone in a department's Approvers column, as in Part 8's flow. SharePoint can't filter on a column that holds several people, so the flow checks each department itself. Inactive departments are included: their pending entries still need a decision.
  • Only what the screen shows. The flow returns seven fields of each entry, without the reason or anything else on the list.
  • Approvers' own entries are left out. Part 8 sends those to the approver's manager, so they don't belong on the approver's own list.
  • The screen lists; it doesn't decide. Each entry's approval request is already waiting in the Approvals service from Part 8. The screen says where to answer it: the Approvals app in Teams, the Outlook email, or Power Automate.

Prerequisites​

Step 1: Create the Flow in the Solution​

In the Overtime Timesheet solution, select New > Automation > Cloud flow > Instant. Name the flow Get Waiting Approvals, choose When Power Apps calls a flow (V2), and select Create (How to Create a Flow That Power Apps Can Run in Power Automate). The trigger needs no inputs: the flow works out everything from who calls it.

It opened in the classic designer, where Save stays unavailable until a flow has an action. I added the first action, Get my profile (V2) from Step 2, saved, then opened the flow from My flows and selected Edit to build the rest in the new designer.

Step 2: Find Out Who's Asking​

The first action is Office 365 Users' Get my profile (V2), renamed Get the caller (How to Get the Profile of the Person Running a Flow in Power Automate). Its pane said it was connected to Office 365 Users, the solution's own connection reference from Part 8, so nothing needed changing.

Later expressions read the caller's email, in lower case:

The caller's email
toLower(outputs('Get_the_caller')?['body/mail'])

Step 3: Find the Departments the Caller Approves​

These actions build MyDepartmentIds, the list of the IDs of the departments the caller approves.

ActionNameSettings
Initialize variable (guide)Initialize MyDepartmentIdsName MyDepartmentIds; Type Array; Value []
Get items (SharePoint)Get the departmentsSite Address: the Overtime Timesheet Site variable; List Name: the Departments variable; Top Count 5000
Apply to each (guide)For each departmentThe body/value of Get the departments
Select, inside the loopApprover emailsFrom and Map below
Condition, after itCheck the caller approves itBelow
Append to array variable, in TrueAdd the departmentName MyDepartmentIds; Value below

Two things went wrong while I added them:

  • My first attempt at Initialize MyDepartmentIds typed into the wrong box. The name went into the flow's own name at the top of the designer, renaming the flow. I typed the flow's name back, removed the half-made action with Undo, and added it again.
  • The SharePoint action connected to another solution's reference. Like the trigger in Part 8, Get the departments picked up a SharePoint connection reference from another solution in the environment. Change connection reference at the bottom of its pane switched it to Overtime Timesheet SharePoint (How to Change an Action's Connection Reference in Power Automate). The second SharePoint action, in Step 4, needed the same change.

Approver emails reads the current department's Approvers with items() (How to Check If a Person Is in a Multi-Person Column in Power Automate):

Approver emails → From
items('For_each_department')?['Approvers']
Approver emails → Map (text mode)
toLower(item()?['Email'])

My first try picked Approvers from the dynamic content list instead, and the designer wrapped Approver emails in a second For each over all the departments. Undo and the expression above fixed it (Fixed: Power Automate Adds a Second For Each Loop When You Pick a Token).

Check the caller approves it compares with is equal to, true on the right:

Check the caller approves it → left value
contains(body('Approver_emails'), toLower(outputs('Get_the_caller')?['body/mail']))
Add the department → Value
items('For_each_department')?['ID']

Each expression went in through Insert expression, and each needed Add selected twice: the first time showed This expression has a problem (Fixed: "This expression has a problem" in Power Automate). The loop with its two actions:

For each department containing Approver emails and Check the caller approves it, with Add the department in the True branch and 0 Actions in the False branch

After the loop, MyDepartmentIds holds the IDs of the departments the caller approves. For anyone who approves none, it stays empty.

Step 4: Get the Pending Entries​

A second Get items, named Get the pending entries, reads OvertimeEntries through its environment variables, with three advanced parameters (How to Filter SharePoint Items with a Filter Query in Power Automate and How to Sort SharePoint Items and Get More Than 100 in Power Automate):

ParameterValueWhy
Filter QueryStatus eq 'Pending'Only entries waiting for a decision leave SharePoint
Order ByStartTimeOldest shift first
Top Count5000Microsoft documents a default of 100 items

The Get the pending entries pane with Site Address and List Name set to environment variables, Filter Query Status eq 'Pending', Order By StartTime, Top Count 5000, and the line Connected to Overtime Timesheet SharePoint

Step 5: Keep the Caller's Entries​

Filter array, named Entries waiting for the caller, takes the body/value of Get the pending entries. In advanced mode, one expression keeps an entry when its department is in MyDepartmentIds and the caller didn't write it (How to Filter an Array by Two Conditions in Power Automate):

Entries waiting for the caller → Filter Query (advanced mode)
@and(contains(variables('MyDepartmentIds'), int(string(item()?['DepartmentId']))), not(equals(toLower(item()?['Author']?['Email']), toLower(outputs('Get_the_caller')?['body/mail']))))

The Code view of Entries waiting for the caller: type Query, from the outputs of Get_the_pending_entries body/value, and the where expression with contains, int(string(...)) and not(equals(...))

The first version didn't have int(string(...)), and it kept nothing: the run showed MyDepartmentIds as [2] and two entries with DepartmentId 2, and contains() still said false. A temporary Select that showed each part of the condition found that equals() matched the same number. Converting the SharePoint number to a whole number fixed it (Fixed: contains() Returns False for a SharePoint Number in Power Automate).

Step 6: Return Seven Fields as JSON​

Select, named Waiting entries, takes the Body of Entries waiting for the caller and keeps seven fields, each an expression on item() (How to Keep Several Fields from Each Item with Select in Power Automate):

KeyValue
iditem()?['ID']
employeeitem()?['Author']?['DisplayName']
departmentitem()?['Department']
startTimeitem()?['StartTime']
endTimeitem()?['EndTime']
breakMinutesitem()?['BreakMinutes']
savedOnitem()?['Modified']

The Waiting entries pane with From set to Body and seven key and value rows: id with ID, employee with Author.DisplayN..., department with Department, startTime with StartTime, endTime with EndTime, breakMinutes with BreakMinutes and savedOn with Modified

The first version also returned reason. When the screen turned out not to show it (Step 10), I removed the row and published the flow again, so the reason stays in SharePoint.

The last action, Respond to a Power App or flow, named Respond to the app, has one Text output, entries (How to Return a Table from a Flow to Power Apps as JSON in Power Automate):

Respond to the app → entries
string(body('Waiting_entries'))

The Respond to the app pane with one Text output named entries, set to the expression token string(...)

Step 7: Check, Publish and Test the Flow​

Flow checker found no errors and no warnings, and Publish said Your flow is ready to go. The whole flow:

The finished flow: When Power Apps calls a flow (V2), Get the caller, Initialize MyDepartmentIds, Get the departments, For each department with 2 actions, Get the pending entries, Entries waiting for the caller, Waiting entries and Respond to the app

I tested it manually (How to Test a Cloud Flow Manually in Power Automate). The Run flow panel listed the two connections it would use, and the run succeeded. Respond to the app returned entries as [], an empty list: the flow's maker approves no department.

Step 8: Choose the Flow's Connections for Approvers​

On the flow's details page, select Edit on the Run only users card. Under Connections Used, set (How to Choose the Connections Run-Only Users Use in Power Automate):

ConnectorSettingWhy
Office 365 UsersProvided by run-only userGet the caller must return the approver
SharePointUse this connection (the owner's)Approvers can't read other people's entries

The Manage run-only permissions panel with Office 365 Users on Provided by run-only user and SharePoint on Use this connection (admin@example.com), outlined in red

Confirm with OK and Save. The approvers themselves are added in Step 13.

With the owner's SharePoint connection, the flow can read every entry for anyone who runs it. That's why Steps 2 to 6 decide everything from the caller's own identity and return nothing else.

Step 9: Add the Flow to the App​

Open the app in Power Apps Studio. Select More (…) on the left bar, then Power Automate, Add flow, and Get Waiting Approvals (How to Add a Flow to a Canvas App in Power Apps). Formulas call it as GetWaitingApprovals:

The Power Automate pane in Studio with Get Waiting Approvals under In your app, and GetWaitingApprovals below it

Step 10: Build the Waiting for Approval Screen​

The screen follows the same pattern as My Overtime in Part 7:

Waiting for Approval Screen
Waiting for Approval Screen
└─ conMainWA vertical: fills the screen
├─ conHeaderWA horizontal: copied from the My Overtime screen
│ ├─ btnBackWA
│ ├─ lblTitleWA "Waiting for approval"
│ └─ btnRefreshWA loads the entries
└─ conBodyWA vertical: scrolling
├─ lblSummaryWA how many entries are waiting
├─ lblWhereWA where to approve or reject them
├─ lblMessageWA nothing waiting, or the load failed
├─ spnLoadingWA while the flow runs
└─ galEntriesWA one card per entry

The screen. Add a blank screen named Waiting for Approval Screen (How to Add a New Screen in Power Apps).

The main container. Insert a vertical container, conMainWA, with the same settings as My Overtime's: X, Y 0; Width Parent.Width; Height Parent.Height; Align (horizontal) Stretch; Padding 0; Drop shadow None; Border radius 0 (How to Add a Vertical Container in Power Apps).

The header. Copy conHeaderMO on the My Overtime screen and paste it into conMainWA (How to Copy and Paste Controls Between Screens in Power Apps). Rename the copies conHeaderWA, btnBackWA, lblTitleWA and btnRefreshWA, and set the title's Text to "Waiting for approval". The buttons keep their layout formulas, so Refresh shows only its icon on phones.

The body. Insert a vertical container after the header, conBodyWA: Flexible height On; Align (horizontal) Start; Gap 16; Padding 24; Vertical overflow Scroll; Drop shadow None; Border radius 0.

The text above the list. Three Text controls in conBodyWA, each with Width Min(640, Parent.Width - 48), Auto height on, Align in container Start and AccessibleLabel Self.Text:

ControlSizeText
lblSummaryWA20, SemiboldIf(CountRows(locEntriesWA) = 1, "1 entry is waiting for your decision.", $"{CountRows(locEntriesWA)} entries are waiting for your decision.")
lblWhereWA12"Approve or reject each entry in the Approvals app in Microsoft Teams, from its email in Outlook, or in Power Automate. Select Refresh to update this list."
lblMessageWA14Step 11

The spinner. A Spinner, spnLoadingWA, with Label "Loading what's waiting for you...", Visible locIsLoadingWA and Align in container Start (How to Add a Loading Spinner in Power Apps).

The list. Insert a Vertical gallery, set Layout to Blank, and name it galEntriesWA (How to Add a Vertical Gallery in Power Apps and Connect It to a SharePoint List). Studio put it in the middle of the body, so move it to the end with Reorder > Move to end (How to Reorder Controls in a Container in Power Apps). Its properties:

PropertyValue
ItemslocEntriesWA
WidthMin(640, Parent.Width - 48)
Align in containerStart
Template size130
Template padding8
Template fillApp.Theme.Colors.Lighter80
Flexible heightOn, with Minimum height 240
Selectablefalse
AccessibleLabel"Overtime entries waiting for your decision"

The card. Four Text controls in the gallery's template, each with X 16, Width Parent.TemplateWidth - 32, Height 24, Size 14 unless shown, top and bottom padding 0, and AccessibleLabel Self.Text (How to Use ThisItem in a Power Apps Gallery):

ControlYText
lblEmployeeWA (size 16, Semibold)12ThisItem.Employee
lblShiftWA42Below
lblHoursWA68Below
lblWaitingWA94$"Waiting since {Text(ThisItem.SavedOn, "dd/mm/yyyy hh:mm")}"
lblShiftWA → Text
$"{Text(ThisItem.StartTime, "ddd dd/mm/yyyy")}, {Text(ThisItem.StartTime, "hh:mm")} to {Text(ThisItem.EndTime, "hh:mm")}{If(Day(ThisItem.EndTime) <> Day(ThisItem.StartTime), " next day", "")}"
lblHoursWA → Text
$"{Text((DateDiff(ThisItem.StartTime, ThisItem.EndTime, TimeUnit.Minutes) - ThisItem.BreakMinutes) / 60, "0.00")} hours, {ThisItem.Department}"

The hours come from the times and the break, as in Part 8's approval request, not from the Hours column, which can be edited in SharePoint (How to Calculate the Minutes Between Two Times in Power Apps with DateDiff and How to Show That a Shift Ends the Next Day in Power Apps).

I inserted the four Text controls with the gallery selected, and they went into conBodyWA beside the gallery, not into its template. I cut them from the tree view, selected the gallery's template with its pencil icon, and pasted them there; they kept their names, and I set their X and Y again (Fixed: New Control Lands Outside the Gallery Instead of Inside It in Power Apps).

The entry's Reason isn't on the card: the Log Overtime screen allows up to 500 characters (Part 6), and the card has a fixed height for four lines. Approvers see the reason in the approval request itself.

The Tree view filtered by WA, showing Waiting for Approval Screen with conMainWA, conHeaderWA holding btnBackWA, lblTitleWA and btnRefreshWA, and conBodyWA holding lblSummaryWA, lblWhereWA, lblMessageWA, spnLoadingWA and galEntriesWA with its four text controls, next to the screen in Studio saying Nothing is waiting for your decision. Select Refresh to check again.

Step 11: Load the Entries​

Refresh runs the flow and turns its JSON into a table (How to Run a Flow and Use Its Result in Power Apps, How to Turn JSON Text into a Table with ParseJSON in Power Apps and How to Handle a Failed Flow Call in Power Apps):

A macOS-style code window titled btnRefreshWA → OnSelect, showing the formula that sets locIsLoadingWA, runs GetWaitingApprovals inside IfError and With, sets locLoadFailedWA and shows a Notify message when the result is blank, and otherwise turns ParseJSON of response.entries into a table of seven typed fields in locEntriesWA

btnRefreshWA → OnSelect
UpdateContext({ locIsLoadingWA: true });
With(
{ response: IfError(GetWaitingApprovals.Run(), Blank()) },
If(
IsBlank(response),
UpdateContext({ locLoadFailedWA: true });
Notify("The entries waiting for you couldn't be loaded. Select Refresh to try again.", NotificationType.Error),
UpdateContext({
locLoadFailedWA: false,
locEntriesWA: ForAll(
ParseJSON(response.entries),
{
ID: Value(ThisRecord.id),
Employee: Text(ThisRecord.employee),
Department: Text(ThisRecord.department),
StartTime: DateTimeValue(ThisRecord.startTime),
EndTime: DateTimeValue(ThisRecord.endTime),
BreakMinutes: Value(ThisRecord.breakMinutes),
SavedOn: DateTimeValue(ThisRecord.savedOn)
}
)
})
)
);
UpdateContext({ locIsLoadingWA: false })
  • locIsLoadingWA shows the spinner while the flow runs.
  • IfError(GetWaitingApprovals.Run(), Blank()) turns a failed call into a blank.
  • locLoadFailedWA remembers that the last load failed, so the screen can say so.
  • ForAll(ParseJSON(...)) turns the JSON text into a table, with each field converted to its type.

The screen loads the entries when it opens:

Waiting for Approval Screen → OnVisible
Select(btnRefreshWA)

The labels show or hide from those variables. lblMessageWA shows one of two sentences:

lblMessageWA → Text
If(
locLoadFailedWA,
"The entries waiting for you couldn't be loaded. Select Refresh to try again.",
"Nothing is waiting for your decision. Select Refresh to check again."
)
lblMessageWA → Visible
!locIsLoadingWA && (locLoadFailedWA || IsEmpty(locEntriesWA))
lblSummaryWA, lblWhereWA and galEntriesWA → Visible
!locIsLoadingWA && !locLoadFailedWA && !IsEmpty(locEntriesWA)

This isn't the formula I wrote first. My first version put IfError around the UpdateContext, and the first time the flow call failed, Power Apps showed its raw Run failed banner and the screen went blank. UpdateContext stores an error in the variable instead of failing, so IfError never saw it (Fixed: IfError Doesn't Catch a Flow's Run Failed Error in Power Apps).

In Studio, selecting the screen in the tree view ran its OnVisible, so the flow ran as the maker: the screen said Nothing is waiting for your decision.

Step 12: Open the Screen from the Home Screen​

On the Home screen, the Waiting for approval button, btnApprovalsHS, shows only for approvers since Part 5. Its OnSelect was false; now it opens the screen (How to Go to Another Screen in Power Apps with Navigate):

btnApprovalsHS → OnSelect
Navigate('Waiting for Approval Screen')

Step 13: Check, Publish and Share​

Run the App checker. Its Accessibility section listed 13 errors: the two that each screen title has had since Part 5, now for four titles, and five on the new gallery and its card labels:

The Accessibility page of the App checker with Errors (13): Focus isn't showing (4), Missing tab stop (5) on lblTitleHS, lblTitleLO, lblTitleMO, lblTitleWA and galEntriesWA, and Missing accessible label (4) on lblEmployeeWA, lblHoursWA, lblShiftWA and lblWaitingWA

The four card labels needed AccessibleLabel Self.Text (Fixed: "Missing Accessible Label" in the Power Apps App Checker), and the gallery needed TabIndex 0 (Fixed: "Missing Tab Stop" in the Power Apps App Checker). The eight left are the title errors, as in Parts 5 to 7:

The Accessibility page with Errors (8): Focus isn't showing (4) and Missing tab stop (4), each on lblTitleHS, lblTitleLO, lblTitleMO and lblTitleWA

Refresh the flow in the app. I had removed reason from the flow (Step 6) after adding it to the app. Microsoft's Power Automate pane article says a flow changed outside Studio must be refreshed in the app, or it may fail to run, so I selected More > Refresh on it (How to Refresh a Flow in a Canvas App in Power Apps).

Save and publish the app. Then, in the solution, the app's Show dependencies > Uses listed the flow as a Process, beside the environment variables. Before the publish, it hadn't: the list follows the published version (How to See What a Canvas App Uses with Show Dependencies in Power Apps).

The Dependencies panel for Overtime Timesheet on the Uses tab, listing under Unmanaged solution (5) Departments, Get Waiting Approvals as a Process, Overtime Timesheet Site, OvertimeEntries and Settings, each Published

Share the app and the flow with the approvers. This share is for testing with the two approvers. Part 15 shares the app with the Overtime Timesheet Users group and adds it to Microsoft Teams.

  1. Share the app with Olivia and Daniel as User (How to Share a Canvas App with Specific People in Power Apps). The share's Additional data access listed the flow, as Logic flows:

    The Share Overtime Timesheet dialog with Olivia Bennett and Daniel Brooks added as chips and the Share button available

  2. Add them as run-only users of Get Waiting Approvals (How to Share a Flow with Run-Only Users in Power Automate):

    The Run-only user card showing the initials OB and DB with an Edit link

I did the first and not the second at first. When Daniel opened the screen, the flow call failed before the flow even started, and no run appeared in its history:

A red error banner reading GetWaitingApprovals.Run failed, with the error code 0x80048306 and the message that a user does not have ReadAccess right(s) for a record of entity Process

The flow is a record in Dataverse, and sharing the app doesn't share it (Fixed: "Does Not Have ReadAccess Right(s) … of Entity Process" When Power Apps Runs a Flow). Once the two approvers were run-only users, the flow ran for them.

Step 14: Test as the Approvers​

Four entries were pending: two of mine in the Emergency Department, one of mine in Radiology, and one of Daniel's in Radiology. I signed in as each approver in their own browser profile.

Daniel opens the app. In Apps > Shared with me, selecting the app's name showed There was a problem opening this app: the name opens it for editing, which a User can't do (Fixed: "There Was a Problem Opening This App" in Power Apps). More commands > Play opened it (How to Find Apps Shared with You in Power Apps). The first time, it asked him to allow its connections, including the Office 365 Users connection the flow uses as him:

The dialog Allow Overtime Timesheet to access your data?, listing Office 365 Users with Some actions connected through a Power Automate flow, Get my profile (V2) and Get user photo metadata, SharePoint with Read records and Write records, and Office 365 Groups with List group members, each for daniel.brooks@example.com, with Allow and Don't allow

The flow's SharePoint connection isn't in the list: it's the owner's. After Allow, his Home screen showed the Waiting for approval button:

The Home screen for Daniel: Welcome, Daniel, Department: Radiology, You approve overtime for Radiology, and the Log overtime, My overtime, Waiting for approval and Reports buttons

Daniel's list. One entry: my Radiology shift. His own Radiology entry isn't there, as the filter intends:

The Waiting for approval screen saying 1 entry is waiting for your decision, with one card: Admin User, Mon 09/11/2026, 17:00 to 19:00, 2.00 hours, Radiology, Waiting since 10/11/2026 11:20

The flow's run history showed his runs. In one of them, Get the caller returned his profile, so the flow ran as him:

Part of the outputs of Get the caller in a run: department Radiology, displayName Daniel Brooks, givenName Daniel

Olivia's list. My two Emergency Department entries, oldest shift first, as in the picture at the top of this part. She approved the 29 October entry in Power Automate's Approvals (How to Respond to Approvals in Power Automate), and about a minute later, Refresh showed one entry left:

The Waiting for approval screen saying 1 entry is waiting for your decision, with one card: Admin User, Sun 08/11/2026, 08:00 to 11:00, 3.00 hours, Emergency Department, Waiting since 10/11/2026 11:20

She approved that one too, and Refresh showed the empty message:

The Waiting for approval screen with the sentence Nothing is waiting for your decision. Select Refresh to check again. below the header

On a phone. In a browser window 390 wide, the title wrapped onto two lines and the second was cut off: the label was 40 high with padding, inside a header 64 high. Setting the title's Height to Parent.Height and its top and bottom padding to 0 let both lines show (Fixed: Text Is Cut Off Inside a Container on Small Screens in Power Apps):

The app at phone width for Daniel: Back, the title Waiting for approval on two complete lines and a refresh icon, above 1 entry is waiting for your decision and one entry card

After each publish. For several minutes after I published a fix, the approvers' browsers still loaded the old version, even in a new tab, with the notices A new version of this app is coming and You're using an old version of this app. Opening the app again a few minutes later loaded the new one (Fixed: Users Still See the Old Version After You Publish a Canvas App in Power Apps).

What the Screen Doesn't Show​

The screen lists the entries in the departments a person approves. In Part 8, an approver's own overtime goes to their manager instead. Daniel's own Radiology entry goes to me, as his manager, and I approve no department, so it isn't on any Waiting for Approval screen: managers answer those requests in Teams, Outlook or Power Automate, where Part 8 sends them. The screen is a convenience; the approval requests stay the record of what's waiting.

Common Mistakes​

MistakeWhat happensDo this instead
Reading the entries in the app with the approver's own connectionThey see only their own entriesA flow with the owner's SharePoint connection
Sending the approver's email from the app to the flowAnyone could ask for another person's entriesGet my profile (V2) with the runner's connection
Picking Approvers from dynamic content inside the loopA second loop over all the departmentsitems('For_each_department')?['Approvers']
contains() on the SharePoint numberNothing matchesint(string(item()?['DepartmentId']))
IfError around UpdateContextThe raw banner shows, and the screen goes blankIfError around Run()
Sharing the app but not the flowReadAccess right(s) … of entity ProcessRun-only users on the flow
Changing the flow without refreshing it in the appThe app may fail to run itRefresh it in the Power Automate pane
Returning every field of each entryData the screen doesn't need reaches the deviceSelect seven fields

Troubleshooting​

SymptomLikely causeFix
The screen says nothing is waiting, but entries are pendingThe filter matches nothing, or the person approves no departmentCheck MyDepartmentIds and the filter's output in the run
GetWaitingApprovals.Run failed with entity ProcessThe flow isn't shared with the personAdd them as run-only users
No run in the flow's historyThe call failed before the flow startedCheck the flow's sharing
There was a problem opening this appThe app was opened for editingMore commands > Play
A fix doesn't show for an approverTheir browser has the old versionOpen the app again a few minutes later
An approver's own entry isn't listedExpected: it goes to their managerTheir manager answers it in Teams or Outlook
The title is cut off on a phoneThe label is shorter than the headerHeight Parent.Height, padding 0

FAQ​

Why not let approvers read the list in SharePoint?​

Part 3 keeps each person's overtime private, even in SharePoint. The flow reads with the owner's connection and returns only what each approver needs, so the list stays private.

Can approvers approve from the screen?​

Not in this part. The request each entry needs is already waiting in the Approvals service, and the flow from Part 8 is waiting for its answer, so the screen says where to give it.

Does this need premium licenses?​

No. SharePoint and Office 365 Users are standard connectors. The flow's details page says it runs on The user who runs the flow, and Microsoft's licensing FAQ says instant flows, including those Power Apps runs, use the invoking user's license.

Why does it take a moment to load?​

The app waits for the flow, which reads two lists and goes through every department. The spinner shows while it runs, and a flow has 120 seconds to respond.

What happens when someone stops being an approver?​

The flow reads the Departments list on every run, so the next Refresh shows the change. The Waiting for approval button follows the same list, as Part 5 set it up.

Conclusion​

Approvers now have a screen with everything waiting for them:

  • Get Waiting Approvals, a flow in the app's solution with the Power Apps (V2) trigger;
  • the caller identified with their own Office 365 Users connection, and the entries read with the owner's SharePoint connection;
  • the approver's departments from the Departments list, their pending entries, and none of their own;
  • seven fields of each entry returned as JSON text, turned into a table in the app;
  • a screen with a spinner, a count, a card per entry and plain messages when nothing is waiting or the load fails;
  • the app and the flow shared with the approvers, and tested as each of them, on a phone too.

Part 10 builds the Departments screen, where admins add departments and choose their approvers.

Additional Resources​

← Previous: Part 8: Build the Approval Flow for Teams and Outlook Next → Part 10: Build the Departments Screen (coming soon)