Skip to content

[Bug]: ResourceManager file list right-click context menu always opens the last file's actions instead of the right-clicked file's actions #7441

Description

@gvnrajput

Is there an existing issue for this?

  • I have searched the existing issues

What happened?

After upgrading to DNN 10.3.2, right-clicking any file in the Resource Manager (Site Assets) opens the context menu of the LAST file in the visible list, not the file that was actually right-clicked. Clicking "Open" from the right-click menu therefore opens the wrong file (the last one in the list), producing a different fileticket and navigating to unintended content.

This is a regression introduced by the new ResourceManager Stencil.js bundle shipped with DNN 10.3.2. The pre-10.3.2 bundle (p-ded0f91c.entry.js, used in DNN 10.1.x) handled context menus correctly.

Steps to reproduce?

  1. Open a page hosting the Resource Manager (e.g. the Site Assets admin page).
  2. Ensure the folder has at least 3 files (the more files, the easier to confirm).
  3. Right-click any file that is NOT the last one in the list.
  4. Click "Open" in the context menu that appears.

Expected: the right-clicked file opens.
Actual: the LAST file in the list opens (different fileticket, wrong file).

Alternatively:

  • Right-click the LAST file in the list → Open works correctly (it happens to be the same file).
  • Right-click any other file → Open opens the last file instead.

Current Behavior

Right-clicking any file in the Resource Manager file list (card view or table view) always opens the context menu actions that belong to the LAST rendered file in the list. "Open", "Download", "Delete", "Move", "Edit", and "Copy URL" all operate on the wrong file. Only the last file in the list behaves correctly when right-clicked.

Expected Behavior

Right-clicking a specific file should open a context menu whose actions (Open, Download, Delete, etc.) operate on that specific right-clicked file.

Relevant log output

No server-side error. The issue is purely client-side in the Stencil.js bundle.

Browser observation: right-clicking FILE-A (not the last) and clicking "Open" fires:
  window.open(LAST_FILE.path, "_blank")
instead of:
  window.open(FILE_A.path, "_blank")

The fileticket in the URL belongs to the last file in the list, not the right-clicked file.

Anything else?

ROOT CAUSE — shared this.contextMenu ref overwritten on every render loop iteration:

The file list component (card view and table view) renders rows using Array.map(). Each row creates a dnn-context-menu Stencil component and assigns its DOM reference to this.contextMenu via a ref callback:

// Inside the render loop — both card view and table view:
currentItems.items.map((e =>
s("button", {
onContextMenu: e => {
e.preventDefault();
this.contextMenu.open(e).catch(console.error); // ← uses shared ref
}
},
...
s("dnn-context-menu", {
ref: e => this.contextMenu = e, // ← OVERWRITES on every iteration
closeOnClick: true
},
e.isFolder
? s("dnn-rm-folder-context-menu", { item: e })
: s("dnn-rm-file-context-menu", { item: e }) // ← correct item per row
)
)))

Because ref: e => this.contextMenu = e runs once per row during rendering, this.contextMenu always ends up pointing to the last row's dnn-context-menu DOM element after the render completes. When onContextMenu fires on any row, it calls this.contextMenu.open() which opens the LAST row's context menu (whose item is the last file), regardless of which row was right-clicked.

AFFECTED FILES (DNN 10.3.2 ResourceManager bundle):
p-199354a0.entry.js — ESM format, card view + table view, 2 occurrences
p-c3895ed9.entry.js — ESM format, card view + table view, 2 occurrences

REGRESSION CONFIRMED — comparison with pre-10.3.2 bundle (p-ded0f91c.entry.js):

The old bundle used a completely different, correct approach:

// OLD approach (DNN 10.1.x — correct):
onContextMenu: t => this.handleContextMenu(t, e) // passes BOTH event and item

handleContextMenu(e, t) {
e.preventDefault();
M.selectedItems = [t]; // selects the right-clicked item
this.dismissContextMenu();
const i = document.createElement("dnn-rm-file-context-menu");
i.item = t; // correct item set dynamically
const s = document.createElement("dnn-collapsible");
s.appendChild(i);
s.style.left = ${e.pageX}px;
s.style.top = ${e.pageY}px;
s.style.display = "block";
this.el.shadowRoot.appendChild(s);
setTimeout(() => { s.expanded = true }, 100);
}

The old code dynamically created a fresh context menu element for the specific right-clicked item at event time. The new code uses a declarative dnn-context-menu component with a shared ref, which is a valid Stencil.js pattern — but only when there is one context menu per component instance, not one per loop row.

MINIMAL FIX — use e.currentTarget to find the correct per-row context menu:

Replace:
this.contextMenu.open(e).catch(console.error)

With:
e.currentTarget.querySelector("dnn-context-menu").open(e).catch(console.error)

e.currentTarget is the button (card view) or tr (table view) that owns this specific row's dnn-context-menu as a direct child. querySelector("dnn-context-menu") retrieves the correct per-row context menu without relying on the shared this.contextMenu ref.

This fix requires changes in 4 places (card view + table view in each of the 2 affected entry.js files). The ref: e => this.contextMenu = e assignments can remain or be removed; they are harmless once this.contextMenu.open() is no longer called.

ROBUST FIX — refactor to store context menus per item (similar to rootItemContextMenu and itemContextMenu which are correctly scoped per component instance):

// Option: use a Map keyed by item ID
ref: cm => { if (!this._ctxMenus) this._ctxMenus = new Map(); this._ctxMenus.set(e.itemId, cm); }
onContextMenu: evt => { evt.preventDefault(); this._ctxMenus.get(e.itemId)?.open(evt).catch(console.error); }

Affected Versions

10.3.3 (latest release)

What browsers are you seeing the problem on?

Chrome

Code of Conduct

  • I agree to follow this project's Code of Conduct

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions