Dashboard gadget: approvals list with space filter and role-based visibility

Description

Add a Jira dashboard gadget that displays the approvals available to the viewing user. Visibility is consistent with the existing personal / space / global admin views, and the gadget reuses the existing "filter by space" control from those views instead of introducing a new scope concept. The gadget inherits the existing list view's behaviour: a default, user-adjustable set of columns, sorting by selected columns, CSV export, and the toggle to detailed mode for inspecting a single approval and casting a vote. JQL filtering and per-instance filter state are persisted in browser localStorage.

Visibility model (computed server-side, per viewing user)

The gadget configuration includes selecting a space. By default, the set of approvals shown is computed per viewing user, based on their role relative to the selected space:

  • Global admin or admin of the selected space: sees all approvals in that space, across all work items.

  • Regular user: sees only their own approvals in that space.

Without a selected space, the gadget follows the existing views' default (global admin sees all instance approvals; a regular user sees their own). Selecting a space narrows to that space. The gadget reuses the existing "filter by space" control from the personal / space / global admin views. JQL filters only within the already-resolved set; it never widens visibility.

Modes

The gadget reuses the existing view's list/detailed toggle. Detailed mode lets the viewing user inspect a single approval and cast a vote (approve / reject / abstain), following the same rules as the full view. Detailed mode is transient and is not persisted; the gadget returns to list mode on dashboard refresh.

Optional: shared owner-permissions mode

In addition to the default per-viewer visibility above, the gadget can optionally be configured to render a single space with the configuring user's permissions, so an admin can share a dashboard exposing a whole space's approvals to users who would otherwise see only their own.

  • Required permission: configuring owner-permissions mode is gated by a dedicated custom global permission defined by the app via Forge's jira:globalPermission module (e.g. "Configure shared Approval Path dashboards"), managed by Jira admins in the native global permissions UI and checked with has_global_permission. Default grant is restricted to jira-administrators. This is a two-layer model: the global permission gates whether a user may configure such gadgets at all, and the existing space-admin / global-admin check restricts configuration to the specific selected space. Holding the global permission alone does not let a user configure owner mode for a space they do not administer.

  • Scope: exactly one space, optionally narrowed by a JQL filter within that space. Never multiple spaces or the whole instance.

  • Who can configure it: only a user who, at configuration time, is admin of the selected space or a global admin. The configured owner identity (accountId) and the selected space are stored in the gadget instance configuration.

  • Re-validation on every render: the backend re-checks that the configured owner still has admin rights to the configured space. If not, the gadget shows no approvals and a message that the configured owner no longer has access.

  • Data vs. voting are independent: approvals shown are those visible under the owner's permissions for that space. Voting is never performed with the owner's permissions; a vote (approve / reject / abstain) is cast as the viewing user and only when that viewing user is themselves an approver of the step. Others see the approval read-only.

  • No anonymous exposure: owner mode never renders approval data for an anonymous viewer (e.g. a publicly shared dashboard).

  • Transparency: the gadget indicates that it is showing data shared with the configured owner's permissions, not the viewer's own.

Persistence

  • Gadget scope/config: per gadget instance, native gadget configuration (edit view).

  • Per-user filter state: persisted in browser localStorage, keyed per gadget instance (gadgetInstanceId). The backend does not store user settings, so filter persistence uses localStorage. The list/detailed mode is not part of persisted state.

  • Owner-mode config (when enabled): part of the per-instance gadget configuration (configured owner accountId, selected space, optional JQL), not localStorage. Per-user filter state in localStorage still applies on top, within what the resolved visibility exposes.

Acceptance criteria

  • The gadget displays approvals filtered to the viewer's permissions, consistent with the existing personal, space, and global admin views.

  • When a space is selected, a viewer who is admin of that space or a global admin sees all approvals in the space; a regular user sees only their own approvals in that space.

  • Different roles viewing the same shared dashboard see correspondingly different sets of approvals.

  • The space filter reuses the control from the existing views.

  • The gadget shows the list view's default column set, and the columns can be changed.

  • The list can be sorted by the supported columns.

  • The list can be exported to CSV.

  • The user can toggle to detailed mode to inspect an approval and cast a vote (approve / reject / abstain), as in the existing view.

  • Detailed mode is transient and resets to list mode on dashboard refresh.

  • Optionally, the gadget can be configured in owner-permissions mode for a single space (optionally narrowed by JQL), only by a space admin of that space or a global admin at configuration time.

  • Configuring owner-permissions mode requires the dedicated custom global permission (jira:globalPermission); users without it cannot enable the mode.

  • The global permission gates the capability; the per-space admin check still restricts configuration to the selected space (holding the permission does not bypass the space-admin requirement).

  • In owner-permissions mode, viewers see the configured space's approvals as permitted by the configured owner; on every render this re-validates that the owner still has admin access, otherwise no approvals are shown.

  • In owner-permissions mode, a viewer can vote only on steps where they are themselves an approver; all other approvals are read-only.

  • Owner-permissions mode never shows approval data to an anonymous viewer.

Notes / open points

  • JQL input must be validated/sanitized; queries execute within the resolved visibility set.

  • Audit logging (server-side) for owner-permissions mode: record which space's approvals were rendered and under whose configured permissions, since data is shown beyond the viewer's own permissions. To be scoped (possibly a separate ticket).

  • The jira:globalPermission module status should be verified as GA on the target platform version at implementation time (it was introduced via EAP).