Admin Dashboard Certificate And Reminder Visibility
This pass lets Jackie click a person on scrAdminDash, see each course's completion date, open the stored certificate from the right-side detail list, and see whether the automatic reminder system has already emailed that person.
1. What This Adds
- A View cert button on each completed course row in the admin drill-down panel.
- An admin-only certificate lightbox on
scrAdminDashusing the existingTT - Email Certificate Libraryflow. - A Last reminder pill on each person row, read from
TT ReminderLog. - No email sending and no reminder-flow changes. This page only reads the reminder log and opens certificates.
TestMode is false and LiveEmailsEnabled is true, so a dry-run email to your inbox does not appear as a real staff reminder.
2. Data Sources And Permissions
- In Power Apps Studio, open the Data pane.
- Add the SharePoint list
TT ReminderLog. - Add or refresh the flow data source
TT - Email Certificate Library. - Refresh
TT Personnel,TT Courses,TT TrainingRecords,TT AuditLog, andTT ReminderLog.
TT ReminderLog is locked down, but Jackie must have read permission because scrAdminDash reads the list directly. Normal staff do not need access because they do not use the admin dashboard.
TT - Email Certificate Library in Power Automate, refresh or remove-and-re-add that flow in the app's Data pane before testing the button. Power Apps can otherwise keep calling an older cached flow shape.
3. Update scrAdminDash.OnVisible
Open scrAdminDash and edit its OnVisible. These are targeted edits, not a full formula replacement.
3.1 Add Viewer Variable Resets
Near the top, just after the existing Set(varAdminStatusFilter, "All"); line, add this block.
Set(varAdminCertViewerOpen, false); Set(varAdminCertDataUri, ""); Set(varAdminCertError, ""); Set(varAdminCertStatusText, ""); Set(varAdminCertBusy, false);
3.2 Refresh And Cache TT ReminderLog
After the existing Refresh('TT AuditLog'); line, add this.
Refresh('TT ReminderLog');
After the existing ClearCollect(colAuditLog, 'TT AuditLog'); line, add this.
ClearCollect(
colReminderLog,
Filter(
'TT ReminderLog',
Coalesce(TestMode, false) = false &&
Coalesce(LiveEmailsEnabled, false) = true
)
);
3.3 Add LastReminderText To colCompliance
Inside the record built by ClearCollect(colCompliance, ForAll(...)), add this new field just before AttentionState:.
TT ReminderLog.ReminderType is a Choice column, use the first block. If it is Single line text, use the second block. Do not paste both.
LastReminderText: With(
{
lastRem: First(
SortByColumns(
Filter(colReminderLog, Lower(PersonEmail) = Lower(P.Email)),
"SentOn",
SortOrder.Descending
)
)
},
If(
IsBlank(lastRem.SentOn),
"",
Switch(
Text(lastRem.ReminderType.Value),
"DUE_30", "30-day email",
"DUE_7", "7-day email",
"EXPIRED_TODAY", "Expired email",
"OVERDUE_30", "30-day overdue",
"OVERDUE_WEEKLY", "Overdue email",
"OVERDUE_ESCALATED", "Escalated overdue",
"Reminder email"
) &
" " & Char(183) & " " &
If(
DateDiff(DateValue(lastRem.SentOn), Today(), "Days") = 0,
"today",
Text(lastRem.SentOn, "dd mmm yyyy")
)
)
),
LastReminderText: With(
{
lastRem: First(
SortByColumns(
Filter(colReminderLog, Lower(PersonEmail) = Lower(P.Email)),
"SentOn",
SortOrder.Descending
)
)
},
If(
IsBlank(lastRem.SentOn),
"",
Switch(
Text(lastRem.ReminderType),
"DUE_30", "30-day email",
"DUE_7", "7-day email",
"EXPIRED_TODAY", "Expired email",
"OVERDUE_30", "30-day overdue",
"OVERDUE_WEEKLY", "Overdue email",
"OVERDUE_ESCALATED", "Escalated overdue",
"Reminder email"
) &
" " & Char(183) & " " &
If(
DateDiff(DateValue(lastRem.SentOn), Today(), "Days") = 0,
"today",
Text(lastRem.SentOn, "dd mmm yyyy")
)
)
),
This deliberately stays blank if no live reminder row exists for that person.
4. Add The Last Reminder Pill To galCompliance
Add a small header label outside the gallery, then a pill button inside the gallery template.
4.1 Header Label
Insert a Label directly on scrAdminDash, not inside the gallery. Rename it lblAdminTableHeadReminder.
| Property | Value |
|---|---|
Text | "Last reminder" |
X | 218 |
Y | 284 |
Width | 146 |
Height | 22 |
Align | Align.Center |
Size | 9 |
FontWeight | FontWeight.Semibold |
4.2 Pill In The Person Row
Select galCompliance, add a classic Button inside the gallery template, and rename it btnLastReminderPill.
| Property | Value |
|---|---|
Text | ThisItem.LastReminderText |
Visible | !IsBlank(ThisItem.LastReminderText) |
OnSelect | Select(Parent) |
X | 218 |
Y | 31 |
Width | 146 |
Height | 20 |
Fill | RGBA(232,244,239,1) |
Color | RGBA(0,78,66,1) |
BorderColor | RGBA(0,78,66,0.35) |
BorderThickness | 1 |
RadiusTopLeft, RadiusTopRight, RadiusBottomLeft, RadiusBottomRight | 10 |
Size | 8 |
Select(Parent) to keep the whole row clickable. Setting it to View mode would block the tap.
5. Add Certificate Viewing To The Detail Gallery
The existing right-side detail list already has lblDetailDate. This pass keeps that label and adds one button per completed training record.
5.1 Make The Detail Rows Taller
Select galPersonDetail and set this property.
| Property | Value |
|---|---|
TemplateSize | 68 |
Move btnDetailPill.Y to 8 and move lblDetailDate.Y to 42.
5.2 Confirm The Completed Date Label
Select lblDetailDate. Its Text should be this.
If(
IsBlank(ThisItem.DateDone),
"Not completed",
Text(ThisItem.DateDone, "dd mmm yyyy") &
If(!IsBlank(ThisItem.UploadedBy), " (via " & ThisItem.UploadedBy & ")", "")
)
5.3 Add The View cert Button
Select galPersonDetail, add a classic Button inside the gallery template, and rename it btnAdminViewDetailCert.
| Property | Value |
|---|---|
Text | "View cert" |
Visible | !IsBlank(ThisItem.RecordID) && !IsBlank(ThisItem.DateDone) |
DisplayMode | If(varAdminCertBusy, DisplayMode.Disabled, DisplayMode.Edit) |
X | 320 |
Y | 40 |
Width | 110 |
Height | 22 |
Fill | RGBA(255,255,255,1) |
Color | RGBA(0,78,66,1) |
BorderColor | RGBA(0,78,66,1) |
BorderThickness | 1 |
RadiusTopLeft, RadiusTopRight, RadiusBottomLeft, RadiusBottomRight | 11 |
Size | 8 |
Set btnAdminViewDetailCert.OnSelect to this full formula.
TT - Email Certificate Library flow is added as a data source and the viewer controls in section 6 exist. Finish this page, then recheck it.
Set(varAdminCertError, "");
Set(varAdminCertStatusText, "Fetching certificate...");
Set(varAdminCertBusy, true);
Set(
varAdminCertRaw,
IfError(
'TT - Email Certificate Library'.Run(ThisItem.RecordID, varMyEmail, varIsAdmin),
Blank()
)
);
Set(varAdminCertBusy, false);
If(
IsBlank(varAdminCertRaw),
Set(varAdminCertError, "Flow could not be reached. Check your connection and try again.");
Notify("Could not open certificate - see the error below.", NotificationType.Error),
With(
{parsed: ParseJSON(varAdminCertRaw.payload)},
If(
Boolean(parsed.success),
Set(varAdminCertStatusText, "");
Set(varAdminCertFileNameLower, Lower(Text(parsed.fileName)));
Set(varAdminCertIsPdf, EndsWith(varAdminCertFileNameLower, ".pdf"));
Set(
varAdminCertMimeType,
If(
varAdminCertIsPdf, "application/pdf",
EndsWith(varAdminCertFileNameLower, ".png"), "image/png",
"image/jpeg"
)
);
Set(varAdminCertDataUri, "data:" & varAdminCertMimeType & ";base64," & Trim(Text(parsed.fileContentBase64)));
Set(varAdminCertViewerOpen, true),
Set(varAdminCertError, Text(parsed.message));
Notify("Could not open certificate - see the error below.", NotificationType.Error)
)
)
)
6. Add The Admin Certificate Lightbox
Add these controls directly on scrAdminDash, not inside any gallery or group. Put them at the end of the tree so they sit above the dashboard when visible.
scrAdminDash ├── existing dashboard controls ├── galCompliance ├── galPersonDetail ├── existing loading overlay ├── recAdminCertViewerBG ├── pdfAdminCertViewer ├── imgAdminCertViewer ├── btnCloseAdminCertViewer └── lblAdminCertError
6.1 Dimmed Background
Insert a classic Button and rename it recAdminCertViewerBG.
| Property | Value |
|---|---|
Text | "" |
DisplayMode | DisplayMode.View |
Visible | varAdminCertViewerOpen |
Fill, HoverFill, PressedFill | RGBA(0,0,0,0.75) |
X, Y | 0 |
Width | Parent.Width |
Height | Parent.Height |
6.2 PDF Viewer
Insert PDF viewer and rename it pdfAdminCertViewer.
| Property | Value |
|---|---|
Document | varAdminCertDataUri |
Visible | varAdminCertViewerOpen && varAdminCertIsPdf |
X | Parent.Width * 0.11 |
Y | Parent.Height * 0.1 |
Width | Parent.Width * 0.78 |
Height | Parent.Height * 0.74 |
6.3 Image Viewer
Insert an Image control and rename it imgAdminCertViewer.
| Property | Value |
|---|---|
Image | varAdminCertDataUri |
ImagePosition | ImagePosition.Fit |
Visible | varAdminCertViewerOpen && !varAdminCertIsPdf |
X | Parent.Width * 0.11 |
Y | Parent.Height * 0.1 |
Width | Parent.Width * 0.78 |
Height | Parent.Height * 0.74 |
6.4 Close Button
Insert a Modern Button and rename it btnCloseAdminCertViewer.
| Property | Value |
|---|---|
Text | "Close" |
Visible | varAdminCertViewerOpen |
OnSelect | Set(varAdminCertViewerOpen, false); Set(varAdminCertDataUri, "") |
BasePaletteColor | RGBA(108,117,125,1) |
Color | RGBA(255,255,255,1) |
X | Parent.Width * 0.11 |
Y | (Parent.Height * 0.84) + 12 |
Width | 130 |
Height | 42 |
6.5 Error Label
Insert a Label and rename it lblAdminCertError.
| Property | Value |
|---|---|
Text | varAdminCertError |
Visible | !IsBlank(varAdminCertError) |
Color | RGBA(255,255,255,1) |
Align | Align.Right |
X | Parent.Width * 0.29 |
Y | (Parent.Height * 0.84) + 12 |
Width | Parent.Width * 0.6 |
Height | 42 |
7. Test Script
- Run App.OnStart, then open
scrAdminDashin Preview. - Click a person who has at least one completed course with a certificate in
TT Certificates_LTD. - Confirm the right-side detail row shows the completed date.
- Click View cert. Confirm the screen dims and the certificate opens inline.
- Close the viewer and open the same certificate again to prove the state resets cleanly.
- Check a person who has no reminder log rows. Their row should have no reminder pill.
- Check a person with a real live reminder row. Their row should show a pill like
30-day email · 12 Aug 2026orOverdue email · today. - Create or inspect a test-mode reminder row. Confirm it does not appear on the dashboard row.
8. Checklist
TT ReminderLogadded as a data source.- Jackie has read permission to
TT ReminderLogif the list is locked down. TT - Email Certificate Libraryadded or refreshed as a flow data source.scrAdminDash.OnVisiblerefreshes and collectscolReminderLog.colComplianceincludesLastReminderText.galCompliancehasbtnLastReminderPill.galPersonDetailhasbtnAdminViewDetailCert.- Viewer controls are direct children of
scrAdminDashand last in the tree. - PDF and image certificates both render inline.
- No reminder emails are sent by anything on this page.