← Back to Policy Tracker guide

Dialog Component — Replacing the Delete/Discard Modals

One shared cmpEnhancedDialog instance replaces all three confirmation modals on ViewItem: Delete Item, Delete Link, and Discard Unsaved Changes. Instead of three separate hand-built overlays, one dialog changes its title/message/buttons based on which action opened it. Source: powerappsui.com/components/dialog, archived at yaml/components/Dialog/.

Good news on risk: the dialog's control family (Text@0.0.51, Button@0.0.45) isn't actually new to this app — both are already used live today in the exact modals this replaces (txtModalTitle1, btnCancelModal1, etc. on DeleteItemModal1). The one genuinely new thing is the Component workflow itself (Insert → Custom → New Component) — this project has never created a real Component before, only screen-level control groups. That's what step 1 verifies before anything else.

Jump to: 1. Verify the component pastes cleanly (do this first) 2. Two new variables 3. Place the dialog on ViewItem, wire its properties 4. Retarget the three trigger buttons 5. Retire the old modals (only after confirming)

1. Verify the component pastes cleanly

In Studio: Insert → Custom → New Component (or the Components tab → New component → Import from code). Paste the full contents of yaml/components/Dialog/Dialog.yaml into that new blank component — not onto a screen. Name it cmpEnhancedDialog to match its own internal name.

Test: confirm it imports with zero errors and the component shows up in your Components list before doing anything else. If it errors, stop here and tell me the exact error — don't proceed to wiring it up against a component that didn't even import cleanly.

2. Two new variables

Add these two lines to ViewItem.OnVisible, anywhere near the other initial Set(...) lines at the top (order doesn't matter, they just need a default before first use):

Set(varDialogVisible, false);
Set(varDialogPurpose, "");

varDialogPurpose is one of "DeleteItem", "DeleteLink", or "Discard" — it's what makes one dialog instance serve all three jobs.

3. Place the dialog on ViewItem, wire its properties

Drag one instance of cmpEnhancedDialog onto the ViewItem screen (as a top-level screen child, same as the existing modals) and set:

Visible: =varDialogVisible
DialogType: ="Confirmation"
Theme: ="Light"
ShowCloseIcon: =true
HeaderText: =Switch(
    varDialogPurpose,
    "DeleteItem", "Delete",
    "DeleteLink", "Delete link",
    "Discard", "Discard changes?",
    ""
)
MessageText: =Switch(
    varDialogPurpose,
    "DeleteItem", "Are you sure you want to proceed with deleting this item? This action cannot be undone.",
    "DeleteLink", "Are you sure you want to delete this document link? This action cannot be undone",
    "Discard", "You have unsaved changes. Are you sure you want to close without saving?",
    ""
)
IconName: =Switch(
    varDialogPurpose,
    "DeleteItem", "Danger",
    "DeleteLink", "Danger",
    "Discard", "Warning",
    "None"
)
Buttons: =Table(
    {Label: "Cancel", ButtonType: "Outline", Action: "cancel", Visible: true},
    {
        Label: Switch(varDialogPurpose, "DeleteItem", "Delete", "DeleteLink", "Delete", "Discard", "Yes, Discard", "Confirm"),
        ButtonType: "Primary",
        Action: "confirm",
        Visible: true
    }
)

Every line of actual behaviour that used to live scattered across three separate btnModalAction*/btnCancelModal* handlers now lives in one place, OnButtonSelect:

=If(
    SelectedButton.Action = "cancel",
    Set(varDialogVisible, false),
    Switch(
        varDialogPurpose,
        "DeleteItem",
        Set(varDeletingItem, true);
        IfError(
            Remove('Policy Proof Tracker', varSelectedRelease),
            Set(varDeletingItem, false);
            Set(varDialogVisible, false);
            ShowToast("Delete failed", "The item may still exist, please check and try again.", "error"),
            Set(varDialogVisible, false);
            ClearCollect(colUnpublishedPolicies, Filter('Policy Proof Tracker', Published = false));
            ShowToast("Item deleted", "The item was removed successfully.", "success");
            Set(varSelectedRelease, Blank());
            Set(varDeletingItem, false);
            Navigate(Main, ScreenTransition.Fade)
        ),
        "DeleteLink",
        IfError(
            Remove(PolicyLinks, varSelectedLink),
            Set(varDialogVisible, false);
            ShowToast("Delete failed", "Check your connection and try again.", "error"),
            Set(varLoadingLinks, true);
            BuildLinksForSource(varSelectedRelease.ID);
            Set(varLoadingLinks, false);
            Set(varDialogVisible, false);
            Set(varSelectedLink, Blank());
            ShowToast("Link deleted", "The document link was removed.", "success")
        ),
        "Discard",
        Set(varDialogVisible, false);
        Set(varSelectPolicy, "Empty");
        Set(varSelectedRelease, Blank());
        Set(varUnsavedChanges, false);
        Set(varShowLinkModal, false);
        If(varSourceScreen = "Historic", Navigate(Historic, ScreenTransition.Fade), Navigate(Main, ScreenTransition.Fade))
    )
)

Every branch above is the exact logic already in the current modals, byte-for-byte, just re-homed under one dialog and one dispatch — the only substantive change is swapping the old Notify(...) calls for ShowToast(...) (the toast component from earlier), so confirmations, deletes, and discards all get the same visual treatment going forward. Also set OnCloseSelect (fires on the X icon or clicking outside):

=Set(varDialogVisible, false)

4. Retarget the three trigger buttons

These are the buttons that open a confirmation, not the ones inside it — three separate places, each currently sets an old context variable that no longer does anything once the dialog stops reading it.

btnDelete1 (top bar, opens Delete Item) — replace:

=UpdateContext({locDisplayDeletePopUp1: true})

with:

=Set(varDialogPurpose, "DeleteItem");
Set(varDialogVisible, true)

btnClose1 (top bar Close button) — only the discard branch changes, the rest of this formula stays exactly as-is:

=If(
    varUnsavedChanges,
    Set(varDialogPurpose, "Discard");
    Set(varDialogVisible, true),
    Set(varSelectPolicy, "Empty");
    Set(varSelectedRelease, Blank());
    Set(varUnsavedChanges, false);
    Set(varShowLinkModal, false);
    If(varSourceScreen = "Historic", Navigate(Historic, ScreenTransition.Fade), Navigate(Main, ScreenTransition.Fade))
)

DeleteLink_2 (the per-link delete icon, opens Delete Link) — replace:

=Set(varSelectedLink, LookUp(PolicyLinks, ID = ThisItem.ID));
UpdateContext({locDisplayAttDeletePopUp: true})

with:

=Set(varSelectedLink, LookUp(PolicyLinks, ID = ThisItem.ID));
Set(varDialogPurpose, "DeleteLink");
Set(varDialogVisible, true)
Test all three end to end: (1) click Delete on the top bar, confirm the dialog shows "Delete" / the item-delete message, Cancel closes it with no change, Delete actually removes the item and lands on Main with a toast. (2) Click the delete icon on a document link, confirm "Delete link" wording, same cancel/confirm behaviour. (3) Edit a field then click Close, confirm "Discard changes?" wording, Cancel keeps you on the form with your edit intact, "Yes, Discard" throws it away and navigates.

5. Retire the old modals (only after confirming)

Don't delete DeleteItemModal1, DeleteLinkModal1, or UnsavedChangesModal yet. Once step 4 is done, their trigger buttons no longer set locDisplayDeletePopUp1/locDisplayAttDeletePopUp/locDisplayDiscardPopUp to true, so they simply can't appear anymore — effectively already retired, just still sitting there as an inert safety net. Once you've tested all three flows above and you're confident the new dialog covers everything, come back and delete those three controls for real. No rush on that part.