{# ========================================================================= Shared permission-matrix macros. These render the three-page admin UX used by every onboarded app: 1. perm_matrix_checkbox \u2014 dept \u00d7 value grid (baseline per dept). 2. perm_matrix_tristate \u2014 role \u00d7 value grid with grant/revoke/Inherit per cell. 3. perm_simulate_panel \u2014 one role's effective list with source badges. The tri-state grid renders a live "Effective" column by delegating to /ui/js/permissions.js (initPermMatrix). The Python-side equivalent is coffeehouse_ui.permissions.compute_effective. ========================================================================= #} {# ------------------------------------------------------------------------- perm_matrix_checkbox rows : list[{slug, display_name}] \u2014 departments cols : list[{slug, display_name}] \u2014 dimension values (permissions / branch_types / branch_brands / categories etc.) values : set[(row_slug, col_slug)] \u2014 currently-true cells save_url: form POST target labels : optional {empty: str, save: str, row_header: str, col_header: str} ------------------------------------------------------------------------- #} {% macro perm_matrix_checkbox(rows, cols, values, save_url, labels=None) %} {% set lbl = labels or {} %}
{% endmacro %} {# ------------------------------------------------------------------------- perm_matrix_tristate rows : list[{slug, display_name, dept_slug}] role rows; dept_slug is used to look up the dept's baseline. cols : list[{slug, display_name}] dimension values. The display_name is what the live "Effective" column renders for each badge; the slug is preserved as the badge `title=` tooltip so admins can still see the underlying identifier on hover. groupings : optional list[{dept_slug, display_name}] when set, column header shows "grouped by dept" headings. (cols stay flat; groupings is just the legend). dept_values: dict[dept_slug -> list[str]] \u2014 baseline per dept. role_modes : dict[(role_slug, value) -> "grant"|"revoke"] save_url : form POST target labels : optional {save: str, empty: str, effective: str} ------------------------------------------------------------------------- #} {% macro perm_matrix_tristate(rows, cols, dept_values, role_modes, save_url, labels=None, groupings=None) %} {% set lbl = labels or {} %} {# Build slug -> display_name map. Jinja has no dict comprehensions, so we use the standard side-effect `update` idiom: `update` returns None (falsy), so the empty `{% if %}` body never renders -- only the side effect lands. #} {% set _col_display = {} %} {%- for _c in cols -%} {%- if _col_display.update({_c.slug: _c.display_name}) -%}{%- endif -%} {%- endfor -%} {% endmacro %} {# ------------------------------------------------------------------------- perm_simulate_panel role : {slug, display_name, dept_slug} rows : list[{value, source: "dept"|"grant"|"revoke", dept_slug?}] already sorted. "dept" rows come from the baseline; "grant" rows come from the role's grants; "revoke" rows are the struck-through values that would otherwise apply. display_lookup: optional dict[str, str] mapping value-slug -> display_name. When omitted (or missing a key) the raw slug renders. The slug is always set as a `title=` tooltip for hover lookup. ------------------------------------------------------------------------- #} {% macro perm_simulate_panel(role, rows, display_lookup=None) %} {% set _disp = display_lookup or {} %}No effective values.
{% endif %}