Skip to main content

Build a Career Development Plan App in Power Apps — Part 8: Build the Review Screen for Manager Approvals

· 30 min read
Jagdish Kumawat
Founder @ Dewiride

This part builds the screen where a manager decides: approve a response, or decline it with a comment the employee sees. Then it tests the whole loop with a real employee in her own browser. That test found a bug: the employee didn't see her manager's decision. The fix, a Refresh button on every screen, ends the part.

This is Part 8 of a 14-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: Create the Solution, Environment Variables and Canvas App
  4. Part 4: Build the Home Screen
  5. Part 5: Build the My Plan Screen
  6. Part 6: Build the Response Screen
  7. Part 7: Share the App and Build the My Team Screens
  8. Part 8: Build the Review Screen for Manager Approvals (you are here)
  9. Part 9: Let Managers Manage Competencies
  10. Part 10: Test Every Role, Joiners and Leavers (coming soon)
  11. Part 11: Build a Setup Flow That Creates the SharePoint Lists (coming soon)
  12. Part 12: Run the Solution Checker and Export the Solutions (coming soon)
  13. Part 13: Install the App in a New Environment (coming soon)
  14. Part 14: Recap, Production Checklist and Next Steps (coming soon)

Part 7 gave managers their team and each person's waiting responses. Those responses can't be opened yet. This part adds the Review screen, connects it, and runs every decision with Olivia, the Head of Sales, in her own browser. Four problems came up on the way: an error on a copied header, a failed paste, data that didn't update, and a header cut off on a phone. Each is shown where it happened, with how I found the cause and fixed it.

What You'll Build​

The Review screen, with the employee's response, a comment box and the two decisions:

The Review response screen for Sales strategy, Level: Expert, Olivia Bennett sent this on Tuesday, October 27, 2026, her response in a shaded box, the comment Good results. At Expert level, also explain how you coached the account managers through the change, then send it again., 120 of 1,000 characters, and the Approve and Decline buttons

How it fits in:

  • Each waiting response opens the Review screen, which reads the response again from SharePoint.
  • Approve saves the decision, with an optional comment. Decline needs a comment.
  • A change made at the same time is caught: if the employee edits the response while the manager reviews it, the decision isn't saved.
  • Every screen has a Refresh button and refreshes when it opens, so people see each other's changes.

Prerequisites​

Step 1: Add the Comment Limit to App.Formulas​

Manager comments are capped at 1,000 characters. Like the response limit in Part 6, the number gets a name, used by the comment box and its character count (How to Use Named Formulas in Power Apps):

App → Formulas (added)
CommentMaxLength = 1000;

The expanded formula bar of App.Formulas ending with StatusPending, StatusApproved, StatusDeclined, ResponseMaxLength = 4000; and the new line CommentMaxLength = 1000; selected

Step 2: Add the Review Screen and Its Layout​

Select Team Member Screen and add a blank screen named Review Screen, so it lands after it (How to Add a New Screen in Power Apps). Its controls end in RVS. This is the structure Steps 2 to 7 build:

Review Screen layout
Review Screen
└── conMainRVS vertical container, the whole screen
├── conHeaderRVS copied from the Team Member screen
│ ├── btnBackRVS
│ └── lblTitleRVS
└── conBodyRVS vertical container, scrolls
├── lblCompetencyRVS
├── lblLevelRVS
├── spnLoadingRVS
├── lblInfoRVS
├── lblResponseRVS
├── lblCommentHintRVS
├── txtCommentRVS
├── lblCountRVS
└── conActionsRVS horizontal container
├── btnApproveRVS
└── btnDeclineRVS

Insert a vertical container, conMainRVS, with the same values as conMainTMS: X 0, Y 0, Width Parent.Width, Height Parent.Height, LayoutAlignItems LayoutAlignItems.Stretch, and all paddings, DropShadow and radius values 0 or None.

The copied header's error​

Then copy conHeaderTMS from the Team Member screen and paste it on conMainRVS (How to Copy and Paste Controls Between Screens). The pasted title showed a red ⊗, and its formula, locMember.displayName, was underlined:

The formula bar with locMember.displayName underlined in red and a hover box reading The '.' operator cannot be used on Error values., and a red error icon on the pasted header's title

View Problem listed a second problem first: Name isn't valid. 'locMember' isn't recognized. Microsoft's article on variables explains it: a context variable belongs to one screen. locMember exists on the Team Member screen, which receives it from Navigate, so on the Review screen it's an error, and the dot can't read a field from it (Fixed: "The '.' Operator Cannot Be Used on Error Values"). The fix is this screen's own title:

lblTitleRVS → Text
"Review response"

Rename the pasted controls conHeaderRVS, btnBackRVS and lblTitleRVS. The Back button keeps Back(). Its AccessibleLabel gets the person's name in Step 4.

Finally, insert a vertical container named conBodyRVS inside conMainRVS, with the values of Part 6's conBodyRS: LayoutAlignItems LayoutAlignItems.Stretch, LayoutGap 16, all paddings 24, DropShadow DropShadow.None, radius 0, and LayoutOverflowY LayoutOverflow.Scroll, so a long response scrolls on a phone.

The empty Review Screen on the canvas with the teal header, Back and Review response, and Tree view showing conMainRVS with conHeaderRVS (btnBackRVS and lblTitleRVS) and conBodyRVS

Step 3: Make Waiting Responses Open the Review Screen​

The Review screen will read the response by its ID, from a variable called locResponseId. Part 7's error taught the order: write the Navigate that creates the variable before anything uses it.

On the Team Member screen, the gallery of waiting responses was a plain list. Make it selectable and give it an OnSelect (How to Open Another Screen When a Gallery Row Is Selected):

PropertyValue
Selectabletrue
OnSelectNavigate('Review Screen', ScreenTransition.None, {locResponseId: ThisItem.ID})

Only the ID travels. The Review screen reads the response itself, so it always shows the version SharePoint has when it opens (How to Get a SharePoint List Item by Its ID).

A gallery is hidden in Studio while its variable is empty, so preview My team → Open on Olivia once to load her response. Then select the gallery's Edit gallery pencil and insert a Button, btnReviewTMS:

PropertyValue
Text, Appearance"Review", ButtonAppearance.Secondary
Width, Height96, 40
XParent.TemplateWidth - Self.Width - 16
Y(Parent.TemplateHeight - Self.Height) / 2
AccessibleLabel"Review " & ThisItem.Competency

Its OnSelect is already Select(Parent), so it opens the row (How to Use the Select Function). To make room for it, change the Width of lblPendCompetencyTMS, lblPendLevelTMS and lblPendSentTMS to Parent.TemplateWidth - 144.

The formula bar with the gallery's OnSelect set to Navigate to 'Review Screen' with locResponseId set to ThisItem.ID, the Sales strategy row with a Review button, and Tree view showing btnReviewTMS inside galPendingTMS

note

Part 9 makes Review a chevron icon on phones, and the row labels' Width Parent.TemplateWidth - btnReviewTMS.Width - 48 (Fixed: Text and Buttons Cut Off on Narrow Phones).

Step 4: Load the Response When the Screen Opens​

Select Review Screen and set its OnVisible (How to Run a Formula When a Screen Opens):

Review Screen → OnVisible
UpdateContext({locIsLoading: true, locIsSaving: false});
UpdateContext(
{
locReview: LookUp(
CompetencyResponses,
ID = locResponseId
)
}
);
UpdateContext({locCanReview: locReview.Status.Value = StatusPending});
UpdateContext({locIsLoading: false})

The expanded formula bar with the Review screen's OnVisible: locIsLoading and locIsSaving, locReview from a LookUp in CompetencyResponses where ID = locResponseId, locCanReview from the status, and locIsLoading set to false

  • LookUp by ID is delegable to SharePoint, as long as it's =: Microsoft's SharePoint delegation table says only = delegates on an ID field. Studio showed no warning.
  • locCanReview is true only while the response is Pending. If it was decided while the list was open, for example on another device, the screen shows the decision and no buttons.
  • locCanReview needs its own UpdateContext. Inside one record, the other fields would still see the old locReview (How to Use Context Variables with UpdateContext).

Now that locReview exists, give the Back button a label that names the person:

btnBackRVS → AccessibleLabel
"Back to " & locReview.EmployeeName

Step 5: Show the Response​

Insert these into conBodyRVS, in order: two Text controls, a Spinner and two more Text controls (How to Add a Text Control, How to Add a Loading Spinner).

ControlPropertyValue
lblCompetencyRVSTextlocReview.Competency
Size, FontWeight20, FontWeight.Semibold
lblLevelRVSText"Level: " & locReview.Level
spnLoadingRVSLabel, Visible"Loading the response", locIsLoading
lblInfoRVSTextthe formula below
lblResponseRVSTextlocReview.Response
FillApp.Theme.Colors.Lighter80
PaddingTop, PaddingBottom, PaddingLeft, PaddingRight12

The four Text controls have AutoHeight true, AccessibleLabel Self.Text and Visible !locIsLoading. Level is a text snapshot in this list, so it has no .Value.

lblInfoRVS says who sent the response and when, or, if someone already decided it, what happened (How to Use the Switch Function, How to Format a Date with Text):

lblInfoRVS → Text
Switch(
locReview.Status.Value,
StatusPending, locReview.EmployeeName & " sent this on " & Text(locReview.SubmittedOn, DateTimeFormat.LongDate) & ".",
StatusApproved, "This response was approved on " & Text(locReview.ReviewedOn, DateTimeFormat.LongDate) & ", so there's nothing left to review.",
StatusDeclined, "This response was declined on " & Text(locReview.ReviewedOn, DateTimeFormat.LongDate) & ". You can review it again when " & locReview.EmployeeName & " sends a new version."
)

Step 6: Add the Comment Box​

Insert a Text control, a Text input and another Text control into conBodyRVS (How to Add a Multi-Line Text Input):

ControlPropertyValue
lblCommentHintRVSText"Comment for " & locReview.EmployeeName & " (required to decline)"
FontWeightFontWeight.Semibold
txtCommentRVSTypeTextInputType.Multiline
Placeholder"Write your comment"
MaxLength, HeightCommentMaxLength, 120
AccessibleLabel"Comment for " & locReview.EmployeeName
DisplayModeIf(locIsSaving, DisplayMode.Disabled, DisplayMode.Edit)
lblCountRVSTextLen(txtCommentRVS.Text) & " of " & Text(CommentMaxLength, "#,##0") & " characters"

All three have Visible !locIsLoading && locCanReview, and the two Text controls have AccessibleLabel Self.Text. The visible label tells everyone, before they try, that Decline needs a comment (How to Limit Text Length and Show a Character Count).

A text box keeps what someone typed until its Default changes, so last time's comment would still be there for the next response (Fixed: Power Apps Text Input Shows Old, Unsaved Text When a Screen Opens Again). Add Reset to OnVisible, just before its last line (How to Reset a Control):

Review Screen → OnVisible (added before the last line)
Reset(txtCommentRVS);

Step 7: Add the Approve and Decline Buttons​

Insert a Horizontal container, conActionsRVS, into conBodyRVS, with the Home screen's conActionsHS values: Flexible height off (FillPortions 0), Height 48, LayoutGap 16, LayoutAlignItems LayoutAlignItems.Center, padding 0, DropShadow None and radius 0 (How to Add a Horizontal Container). Its Visible is !locIsLoading && locCanReview.

Inside it, insert two Buttons (How to Add a Button, How to Add an Icon to a Button):

PropertybtnApproveRVSbtnDeclineRVS
Text"Approve""Decline"
Icon"Checkmark""Dismiss"
AppearancePrimary (the default)ButtonAppearance.Secondary
Width, Height160, 40160, 40
AccessibleLabelSelf.TextSelf.Text
DisplayModeIf(locIsSaving, DisplayMode.Disabled, DisplayMode.Edit)If(locIsSaving || IsBlank(Trim(txtCommentRVS.Text)), DisplayMode.Disabled, DisplayMode.Edit)

Decline stays disabled until the comment has text that isn't only spaces (How to Disable a Button Until a Text Box Has Text).

One Patch per decision​

Each button saves three columns of the response it read: the status as a Choice record, the trimmed comment, and the review time (How to Create or Update a SharePoint List Item with Patch, Write to a Choice Column, Now). IfError handles a failure the way Part 6 does, with a plain message when someone changed the response first (IfError, Notify):

A code window titled btnApproveRVS → OnSelect: it sets locIsSaving to true, then IfError wraps a Patch to CompetencyResponses on locReview that sets Status to Approved, ManagerComment to the trimmed comment and ReviewedOn to Now; on an error it clears locIsSaving and shows a conflict or failure message, and on success it clears locIsSaving, shows You approved and the employee's name, and goes back

btnApproveRVS → OnSelect
UpdateContext({locIsSaving: true});
IfError(
Patch(
CompetencyResponses,
locReview,
{
Status: {Value: StatusApproved},
ManagerComment: Trim(txtCommentRVS.Text),
ReviewedOn: Now()
}
),
UpdateContext({locIsSaving: false});
Notify(
If(
FirstError.Kind = ErrorKind.Conflict,
"This response changed while you were reviewing it. Go back, open it again and review the new version.",
"Your decision wasn't saved. " & FirstError.Message
),
NotificationType.Error
),
UpdateContext({locIsSaving: false});
Notify("You approved " & locReview.EmployeeName & "'s response.", NotificationType.Success);
Back()
)

Decline is the same formula with two changes:

btnDeclineRVS → OnSelect (the two differences)
Status: {Value: StatusDeclined},
Notify("You declined " & locReview.EmployeeName & "'s response and sent your comment.", NotificationType.Success);

Back() returns to the Team Member screen, whose OnVisible loads the person's responses again (How to Go Back with Back). The finished screen in Studio, after one preview to load data:

The Review Screen in Studio showing Sales strategy, Level: Expert, Olivia Bennett sent this on Tuesday, October 27, 2026, her response, the comment label, an empty comment box, 0 of 1,000 characters and Approve and Decline buttons, next to Tree view listing all the screen's controls

note

On 360-pixel phones, two 160-pixel buttons don't fit side by side. Part 9 sets both buttons' Width to If(App.ActiveScreen.Size = ScreenSize.Small, (Parent.Width - Parent.LayoutGap) / 2, 160), and every screen title's Size to If(App.ActiveScreen.Size = ScreenSize.Small, 18, 20).

Step 8: Decline a Response​

Preview from the Home screen: My team → Open on Olivia → Review on Sales strategy. The comment box is empty, so Decline is disabled:

The Review screen in preview with Olivia's Sales strategy response, an empty comment box, 0 of 1,000 characters, Approve enabled and Decline greyed out

Type a comment, as at the top of this part, and Decline turns on. Select it. A green banner confirms it, the app goes back, and the Team Member screen has nothing waiting, with Sales strategy marked Declined:

A green banner reading You declined Olivia Bennett's response and sent your comment., above Olivia's screen: Nothing is waiting for your review, and Sales strategy with a red Declined badge in her plan

Back to My team: Olivia's badge is gone.

The My team screen with Olivia Bennett, Head of Sales, and no badge

Step 9: See It as the Employee​

Olivia's screens haven't changed since Part 7, so the published version is enough. In her browser, open the app with its web link (How to Find the Web Link of a Canvas App). Her My plan shows the decision:

Olivia's My plan screen with Sales strategy showing a red Declined badge, and Leadership and Stakeholder management Not started

Opening it shows the date and her manager's comment, built in Part 6:

Olivia's My response screen for Sales strategy with a Declined badge, Your manager declined this on Wednesday, October 28, 2026. Update your response and send it again., the comment from her manager in bold, her editable response and Send again

She adds how she coached the team and selects Send again. Her plan shows Waiting for review again:

A green banner reading Your response was sent to your manager., above Olivia's My plan screen with Sales strategy back to Waiting for review

Step 10: Approve, and Catch a Change Made at the Same Time​

Back as the manager, open Olivia's response again. Before approving, test the risk this screen exists for: the employee edits the response while the manager is reading it.

With the Review screen open, Olivia added one more sentence in her browser and selected Update response. Then the manager selected Approve on the copy loaded before her change. SharePoint refused it, and the app said so:

A red banner reading This response changed while you were reviewing it. Go back, open it again and review the new version., above the Review screen still showing the older text

Nothing was approved. Patch sends the version of the item it read, and SharePoint rejects an update to an item that changed since then (Fixed: "Network Error When Using Patch Function: ETAG Mismatch"). Going back and opening it again read the new version, with Olivia's last sentence about onboarding:

The Review screen reopened, with Olivia's response now ending with The playbook cut partner onboarding from six weeks to three.

Select Approve, this time without a comment, because a comment is optional for approvals. The banner confirms it, and the plan shows Approved:

A green banner reading You approved Olivia Bennett's response., above Olivia's screen with nothing waiting and Sales strategy Approved

Step 11: The Bug: Olivia Didn't See the Approval​

In Olivia's browser, I went back to the Home screen and opened My plan. Sales strategy still said Waiting for review:

Olivia's My plan screen with Sales strategy still showing Waiting for review after the approval

Opening the response itself showed Approved, so the decision was saved. I opened My plan again after 12 seconds, and once more six minutes later: still Waiting for review.

Part 6 never saw this, because there the change came from the app's own Patch, and the new status showed at once. This time someone else made the change. Microsoft documents the difference: a running app doesn't detect changes made outside it, and the Refresh function gets a fresh copy so you see changes other users made. The full investigation is in Fixed: Power Apps Doesn't Show Changes Other People Made.

Every screen that shows SharePoint data has the same weakness: an employee waits for decisions, and a manager waits for responses. So every one of them gets the fix.

Step 12: Add a Refresh Button to Every Screen​

Each data screen gets two things (How to Refresh Data with the Refresh Function):

  • It refreshes when it opens, for the case that failed.
  • A Refresh button in its header, for someone who stays on the screen.

Both run one formula. It moves from the screen's OnVisible into the button's OnSelect, with Refresh added, and OnVisible selects the button (How to Add a Refresh Button to a Screen).

Build it once, on My plan​

Select conHeaderMPS and insert a Button. It lands after the title, at the right edge. Name it btnRefreshMPS:

PropertyValue
Text"Refresh"
Icon"ArrowClockwise"
Width, Height112, 40
AccessibleLabel"Refresh this screen"

Cut the My Plan screen's OnVisible formula from Part 5, paste it into the button's OnSelect, and add a Refresh line for each list it reads, after the first line:

A code window titled btnRefreshMPS → OnSelect: UpdateContext sets locIsLoading to true, Refresh runs on RoleCompetencies and CompetencyResponses, Concurrent loads locMyPlan and locMyResponses, and locIsLoading is set back to false

btnRefreshMPS → OnSelect
UpdateContext({locIsLoading: true});
Refresh(RoleCompetencies);
Refresh(CompetencyResponses);
Concurrent(
UpdateContext(
{
locMyPlan: Sort(
Filter(
RoleCompetencies,
JobTitle = MyJobTitle && IsActive
),
Competency
)
}
),
UpdateContext(
{
locMyResponses: Filter(
CompetencyResponses,
EmployeeId = MyProfile.id
)
}
)
);
UpdateContext({locIsLoading: false})
My Plan Screen → OnVisible
Select(btnRefreshMPS)

Select runs the button's OnSelect as if someone selected it. Microsoft's reference allows it in OnVisible for a control on the same screen.

Copy it to the other screens​

My first pass added the button to each screen from scratch. Building it once and copying it is faster, and keeps all five identical, so that's how I redid them. For each screen in the table: copy btnRefreshMPS, paste it on that screen's header container, rename the copy, put that screen's OnVisible formula in its OnSelect with the Refresh lines after the first line, and set the screen's OnVisible to Select() on it.

ScreenButtonRefresh lines to add
Response ScreenbtnRefreshRSRefresh(CompetencyResponses);
My Team ScreenbtnRefreshMTSRefresh(CompetencyResponses);
Team Member ScreenbtnRefreshTMSRefresh(RoleCompetencies); and Refresh(CompetencyResponses);
Review ScreenbtnRefreshRVSRefresh(CompetencyResponses);

The Home screen reads only Microsoft 365 profiles, so it has no button. For the Review screen, the result is:

btnRefreshRVS → OnSelect
UpdateContext({locIsLoading: true, locIsSaving: false});
Refresh(CompetencyResponses);
UpdateContext(
{
locReview: LookUp(
CompetencyResponses,
ID = locResponseId
)
}
);
UpdateContext({locCanReview: locReview.Status.Value = StatusPending});
Reset(txtCommentRVS);
UpdateContext({locIsLoading: false})

The second paste failed with There's something wrong with the pasted code. Copying a control puts its code on the clipboard, and I'd pasted the first screen's formula since, which replaced it. Copy the button again before each paste (Fixed: "There's Something Wrong with the Pasted Code").

Step 13: Fix the Header on Phones​

At Apple iPhone 12, 13, 14 size (How to Test on Phone and Tablet Sizes), the new button squeezed the title. Olivia Bennett wrapped onto two lines and was cut off:

A phone preview of the Team Member screen with Back, the title Olivia Bennett wrapped and clipped, and Refresh

Microsoft's Button reference has a Layout property whose ButtonLayout.IconOnly shows only the icon. My first attempt changed only the Refresh buttons, and the title still didn't fit. Both header buttons need it, so set these on every Back and Refresh button in the five headers (How to Show Only the Icon on a Button on Phones):

PropertyBack buttonsRefresh buttons
LayoutIf(App.ActiveScreen.Size = ScreenSize.Small, ButtonLayout.IconOnly, ButtonLayout.IconBefore)the same
WidthIf(App.ActiveScreen.Size = ScreenSize.Small, 40, 96)If(App.ActiveScreen.Size = ScreenSize.Small, 40, 112)
Tooltip"Back""Refresh this screen"

Their accessible labels already describe them, which Microsoft recommends for icon-only buttons. On a phone, the longest title fits:

A phone preview of the Review screen with a back arrow, the title Review response on one line and a refresh icon

When I switched the preview size while a screen was already open, its buttons kept their text until I went to another screen and back. Microsoft's responsive layout article warns that the authoring canvas doesn't respond to sizing formulas, so Step 14 tests the published app. The whole story is in Fixed: Text Is Cut Off Inside a Container on Small Screens.

Step 14: Check, Publish and Test with Olivia​

Open the App checker and select Recheck all. Accessibility (10) lists the five screen headings, each with Focus isn't showing and Missing tab stop, the case Part 5 explains (Fixed: "Focus Isn't Showing", Fixed: "Missing Tab Stop"). Everything else is clear:

The App checker's Accessibility pane with Errors (10): Focus isn't showing (5) and Missing tab stop (5), both on lblTitleMPS, lblTitleRS, lblTitleMTS, lblTitleTMS and lblTitleRVS

Save, then Publish → Publish this version (How to Publish a Canvas App). In Olivia's browser, a reload three minutes later still opened the old version. A second, four minutes after publishing, had the Refresh buttons (Fixed: Users Still See the Old Version After You Publish).

The header button. The manager's My team was open when Olivia sent her Leadership response, so it showed no badge. After Refresh, it did:

The My team screen after Refresh, with a Refresh button in the header and a Waiting for review badge on Olivia's row

The manager approved it with a comment. Olivia's My plan, loaded before that, still said Waiting for review. After Refresh, it said Approved:

Olivia's My plan screen after Refresh, with Leadership and Sales strategy Approved

And opening it shows the manager's comment on an approval too:

Olivia's My response screen for Leadership with an Approved badge, Your manager approved this on Wednesday, October 28, 2026., and the comment Strong example. Running the client recovery yourself is the leadership we expect at this level.

The path that failed. Olivia sent a third response and went to the Home screen, and her manager declined it. Seventeen seconds later, she opened My plan, without Refresh or a reload. It showed Declined:

Olivia's My plan screen with Leadership and Sales strategy Approved and Stakeholder management Declined

A response decided somewhere else. Olivia added an example to that response and sent it again. The manager had her screen open in one browser tab, with the response waiting, and approved it in a second tab. Back in the first tab, Review on the old row showed the decision instead of the comment box and buttons, because the Review screen reads the response when it opens:

The Review response screen for Stakeholder management reading This response was approved on Wednesday, October 28, 2026, so there's nothing left to review., with Olivia's response and no comment box or buttons

The phone header, published. With Olivia's browser window narrowed to 390 × 844, the header showed icons only. Widened again, the button text came back at once:

The published app at phone width: the My response header with a back arrow, the title and a refresh icon, above Olivia's approved Leadership response and the manager's comment

Common Mistakes​

MistakeWhat happensDo this instead
Keeping a copied header's title formulaThe '.' operator cannot be used on Error valuesGive the title this screen's own text
Passing the whole record to the Review screenThe manager may decide on an old versionPass the ID and read the response when the screen opens
Setting locCanReview in the same UpdateContext as locReviewIt reads the previous responseUse a separate UpdateContext
Testing with one accountOther people's changes never come upTest with the employee in another browser
Calling only Refresh(...) in the buttonScreens keep their old variablesRun the screen's queries again after it
Pasting a formula between control pastesThere's something wrong with the pasted codeCopy the control again before each paste

Troubleshooting​

SymptomLikely causeFix
Decline stays disabledThe comment is empty or only spacesType a comment
This response changed while you were reviewing itThe employee changed it after the screen loaded itGo back, open it again and review the new version
The employee doesn't see the decisionTheir screen kept an older copyRefresh in OnVisible and the header button (Fixed: Power Apps Doesn't Show Changes Other People Made)
The screen opens emptylocResponseId is blank, for example when previewing the Review screen directlyOpen it from the Team Member screen
Header buttons keep their text on a phone previewThe preview size changed while the screen was openGo to another screen and back, or test the published app
Users don't have the Refresh buttonsThey still have the old versionFixed: Users Still See the Old Version After You Publish

FAQ​

Who can approve a response?​

The app shows the Review screen only for the manager's own direct reports, from Microsoft 365. As Part 1 explains, the SharePoint permission is the real boundary: anyone in the group could edit the list directly. SharePoint's version history records who changed what.

Why isn't the reviewer saved in the list?​

The reviewer is always the employee's current manager in Microsoft 365, so the app doesn't store one. SharePoint's Modified By and version history record who made each decision.

Can a manager change a decision?​

Not in the app. The Review screen shows its buttons only while a response is Pending. A declined response comes back when the employee sends it again, and an approved one is final.

Conclusion​

Managers can now decide, and employees see the decisions:

  • each waiting response opens the Review screen, which reads it by ID when it opens;
  • Approve saves with an optional comment, Decline needs one, and a change made at the same time is caught instead of overwritten;
  • every data screen refreshes when it opens and has a Refresh button, built once and copied, with icon-only header buttons on phones.

On the way, a copied header's error, a failed paste, a status that didn't update and a clipped phone header each showed how to find the cause and fix it, starting from Microsoft's documentation.

← Previous: Part 7: Share the App and Build the My Team Screens

Next → Part 9: Let Managers Manage Competencies. Managers add competencies to a job title, change their levels and remove them.

Additional Resources​

Stay Updated

Subscribe to our newsletter for the latest tutorials, tech insights, and developer news.

By subscribing, you agree to our privacy policy. Unsubscribe at any time.