Training Tracker only Admin dashboard pass Updated 14 Aug 2026

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 scrAdminDash using the existing TT - Email Certificate Library flow.
  • 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.
Important safety point: the reminder pill ignores test-mode rows. It only shows rows where 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

  1. In Power Apps Studio, open the Data pane.
  2. Add the SharePoint list TT ReminderLog.
  3. Add or refresh the flow data source TT - Email Certificate Library.
  4. Refresh TT Personnel, TT Courses, TT TrainingRecords, TT AuditLog, and TT ReminderLog.
Locked reminder log: this still works if 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.
Flow refresh rule: if you edit 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.

Power Fx - add after varAdminStatusFilter
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.

Power Fx - reminder log refresh
Refresh('TT ReminderLog');

After the existing ClearCollect(colAuditLog, 'TT AuditLog'); line, add this.

Power Fx - reminder log collection
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:.

Pick the version that matches your SharePoint column. If 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.
Power Fx - LastReminderText if ReminderType is Choice
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")
        )
    )
),
Power Fx - LastReminderText if ReminderType is Text
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.

PropertyValue
Text"Last reminder"
X218
Y284
Width146
Height22
AlignAlign.Center
Size9
FontWeightFontWeight.Semibold

4.2 Pill In The Person Row

Select galCompliance, add a classic Button inside the gallery template, and rename it btnLastReminderPill.

PropertyValue
TextThisItem.LastReminderText
Visible!IsBlank(ThisItem.LastReminderText)
OnSelectSelect(Parent)
X218
Y31
Width146
Height20
FillRGBA(232,244,239,1)
ColorRGBA(0,78,66,1)
BorderColorRGBA(0,78,66,0.35)
BorderThickness1
RadiusTopLeft, RadiusTopRight, RadiusBottomLeft, RadiusBottomRight10
Size8
Keep this pill clickable. Leave its display mode editable because the pill uses Select(Parent) to keep the whole row clickable. Setting it to View mode would block the tap.

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.

PropertyValue
Text""
DisplayModeDisplayMode.View
VisiblevarAdminCertViewerOpen
Fill, HoverFill, PressedFillRGBA(0,0,0,0.75)
X, Y0
WidthParent.Width
HeightParent.Height

6.2 PDF Viewer

Insert PDF viewer and rename it pdfAdminCertViewer.

PropertyValue
DocumentvarAdminCertDataUri
VisiblevarAdminCertViewerOpen && varAdminCertIsPdf
XParent.Width * 0.11
YParent.Height * 0.1
WidthParent.Width * 0.78
HeightParent.Height * 0.74

6.3 Image Viewer

Insert an Image control and rename it imgAdminCertViewer.

PropertyValue
ImagevarAdminCertDataUri
ImagePositionImagePosition.Fit
VisiblevarAdminCertViewerOpen && !varAdminCertIsPdf
XParent.Width * 0.11
YParent.Height * 0.1
WidthParent.Width * 0.78
HeightParent.Height * 0.74

6.4 Close Button

Insert a Modern Button and rename it btnCloseAdminCertViewer.

PropertyValue
Text"Close"
VisiblevarAdminCertViewerOpen
OnSelectSet(varAdminCertViewerOpen, false); Set(varAdminCertDataUri, "")
BasePaletteColorRGBA(108,117,125,1)
ColorRGBA(255,255,255,1)
XParent.Width * 0.11
Y(Parent.Height * 0.84) + 12
Width130
Height42

6.5 Error Label

Insert a Label and rename it lblAdminCertError.

PropertyValue
TextvarAdminCertError
Visible!IsBlank(varAdminCertError)
ColorRGBA(255,255,255,1)
AlignAlign.Right
XParent.Width * 0.29
Y(Parent.Height * 0.84) + 12
WidthParent.Width * 0.6
Height42

7. Test Script

  1. Run App.OnStart, then open scrAdminDash in Preview.
  2. Click a person who has at least one completed course with a certificate in TT Certificates_LTD.
  3. Confirm the right-side detail row shows the completed date.
  4. Click View cert. Confirm the screen dims and the certificate opens inline.
  5. Close the viewer and open the same certificate again to prove the state resets cleanly.
  6. Check a person who has no reminder log rows. Their row should have no reminder pill.
  7. Check a person with a real live reminder row. Their row should show a pill like 30-day email · 12 Aug 2026 or Overdue email · today.
  8. Create or inspect a test-mode reminder row. Confirm it does not appear on the dashboard row.

8. Checklist

  • TT ReminderLog added as a data source.
  • Jackie has read permission to TT ReminderLog if the list is locked down.
  • TT - Email Certificate Library added or refreshed as a flow data source.
  • scrAdminDash.OnVisible refreshes and collects colReminderLog.
  • colCompliance includes LastReminderText.
  • galCompliance has btnLastReminderPill.
  • galPersonDetail has btnAdminViewDetailCert.
  • Viewer controls are direct children of scrAdminDash and last in the tree.
  • PDF and image certificates both render inline.
  • No reminder emails are sent by anything on this page.