{{--
Add New Role — docs/wireframes-v12/add-role.html (the card at lines 114-350),
minus everything CR-14 §0 removes.
## Shape
ONE `.card`. Inside it, a `.form-section` per heading — each with its
`.form-section-title` and the wireframe's own icon — and a `.card-footer` at
the bottom. Fields are laid out by v12's `.form-row.form-row-2` grids, not by
Bootstrap columns, which is why no field carries a `group-class`: the row
owns the columns and `.form-group` owns its own margin.
## The twin rule (recipe §9)
This file and roles/edit.blade.php are twins. Every field is written out in
both, and neither includes a shared form partial. **A field added, removed or
renamed here must be mirrored in edit.blade.php in the same commit**, and the
permission matrix is one field for that purpose even though it draws
thirty-eight boxes — it is generated from App\Support\RolePermissionMatrix on
both screens, so a module added there appears on both without either file
changing.
Both twins are in tests/Feature/TwinViewParityTest.php ('roles' dataset row),
which fetches the two screens over real authenticated GETs and compares their
rendered `name` sets and required-attribute sets. What that test does NOT
cover, and what therefore stays this docblock's job: label wording, field
order and validation-rule drift.
### What this screen has that its twin does not
* the action (`roles.store`) and the method (POST, not PUT);
* the submit label — "Save Role", where the twin says "Update Role";
* the rule source — StoreRoleRequest, where the twin names
UpdateRoleRequest (whose unique rule ignores the row being edited and
which refuses the Super Admin role in after());
* the header wording and the breadcrumb's last crumb;
* **no info box above the card** — the twin draws the wireframe's "This
role is assigned to N users" strip, and a role that does not exist yet is
assigned to nobody.
Everything else is identical, prefills included: `$role`, `$modules` and
`$granted` are the same three keys on both screens, and this one is handed a
fresh model and an empty grant list rather than a different shape.
## Deliberate differences from the wireframe
* **The Role Code field is gone** (client instruction, CR-14 §0.3;
add-role.html:123-127). There is no code column on `roles` and no
sequence to generate one from; the wireframe's own helper text calls it
auto-generated-and-editable, which is two behaviours this module does not
have. Its slot in the row is kept EMPTY so Role Name stays half a row
wide rather than stretching to full, exactly as the users twins keep the
removed Username slot.
* **The Description textarea is gone** (§0.3; :129-132). No column.
* **The Status toggle is gone** (§0.3; :141-149), and so are the three
`.toggle-*` rules that styled it — see the CR-14 block in
nrems-wireframe.css. A role has no status: it is held or it is not.
* **The whole Additional Permissions section is gone** (§0.3; :310-343).
Its seven checkboxes — Approve Bookings, Generate Reports, Bulk
Import/Export, System Configuration, Audit Log Access … — name features
this application does not have, and a checkbox that grants nothing is
furniture.
* **The matrix draws the client's TEN modules, not the wireframe's
seventeen** (§0.5), and **its Export column is gone** (§0.3). See
App\Support\RolePermissionMatrix, which owns the list.
* **Booking and Cancellation have no Delete checkbox** (decision D7). The
cells still render, empty, so the grid stays aligned.
* **There are no "select all" controls**, on a row or on a column — the
wireframe draws none, and none is invented.
--}}
@extends('layouts.app')
@section('title', __('roles.create_title'))
@section('breadcrumbs')
| {{ __('roles.matrix.columns.module') }} | @foreach (\App\Support\RolePermissionMatrix::ACTIONS as $action){{ __('roles.matrix.columns.'.$action) }} | @endforeach|
|---|---|---|
| {{ __('roles.matrix.modules.'.$module['key']) }} | @foreach ($module['cells'] as $action => $permission) {{-- A null cell renders EMPTY and keeps its(decision D7): Booking and Cancellation have no Delete checkbox, and dropping the cell would shift every column after it out of line. --}} | @if ($permission !== null) {{-- The two data- attributes are how nrems-role-form.js finds a box. It never parses the label beside it, which would have made the auto-check rules one translation away from silently not firing. aria-label because the visible label for these boxes is the column header plus the row heading, and a screen reader announcing "checkbox" thirty- eight times is not a form. --}} @endif | @endforeach