Commit Graph

8 Commits

Author SHA1 Message Date
Nathnael
f39ae77401 fix(backoffice): map raw IAM error codes to friendly messages (EDRFREIGHT-223, EDRFREIGHT-225)
@tria-plc/iamapi-common throws BadRequestException with a raw,
untranslated code as the message (e.g. "user_role_not_found",
"unit_employee_limit_reached:5") — useErrorHandler's extractMessage
returned that string verbatim, so removing an org/unit admin whose
role row didn't match, or inviting past a unit's employee cap, toasted
the raw backend code instead of an explanation. Adds a small code→i18n
map checked before the raw-message fallback, shared by both the async
and sync error handlers so every caller (org-admin removal, employee
invites, etc.) picks it up for free.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-28 12:28:11 +00:00
Nathnael
b1cb149c44 feat(backoffice): add organization admin permission assignment page (EDRFREIGHT-242)
There was no UI to assign permissions to the Organization Admin role,
even though the backend's Role→Permission endpoints
(@tria-plc/iamapi-common's role-permissions routes) were already live
and unused. Adds a dedicated page — application picker + the existing
permission checklist — that assigns/reads permissions for the fixed
Organization Admin role, linked from the Organization Admins page.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-28 12:27:44 +00:00
Nathnael
c2375a5306 fix(backoffice): scope copy-permissions-from to the selected unit (EDRFREIGHT-308)
The "Copy Permissions From" dropdown in the position-type form only
filtered candidates by the selected organization's full unit set,
ignoring the form's own "Select Unit" field entirely — so switching
units never re-scoped the list, unlike the equivalent unit filter on
the position-management table.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-28 12:27:14 +00:00
Nathnael
346d4718bf fix(backoffice): scope permission copying to the selected organization
"Copy permissions from" listed every position type in every
organization, because the dropdown read an unfiltered GET
/position-types. IAM exposes no organization-scoped route and carries no
organizationId on a position type, so the list is now narrowed
client-side to the built-in (isSystem) types plus those whose unit
belongs to the selected organization, with the type being edited
excluded.

Also in position management:

- Invalidate every position-type cache key root after a mutation. React
  Query matches prefixes element by element, so ["position-type"] never
  reached ["position-types-common", ...] and the department pickers kept
  serving a stale list. invalidatePositionTypeQueries() covers all three
  roots and is shared by the hook and the form.
- Drop getByOrganizationId and getCommonTypesByOrganizationId. Both
  issued the same requests as their unit counterparts and had no callers.
- Surface errors that were being swallowed. Three mutations had empty
  onError handlers, hiding IAM's 403 for built-in position types, and
  CreatePositionForm's bare catch discarded the reason for every failure.
- Move organization and unit into the zod schema so they validate with
  translated messages and inline errors instead of an ad-hoc toast, and
  keep submit disabled through the permission-assignment call that
  follows the save.
- Report the two outcomes the form used to hide: a save that succeeded
  while permission assignment failed, and clearing every permission,
  which assign-seconds-for-first cannot express.
- Fix the list page's loading and error states, which rendered the
  "Add User" string as a spinner, ignored the unit-scoped query, and
  left the export button stuck after a failed download.
- Halve PermissionSearch's requests. It fetched 50 rows, read the total
  off the response and immediately refetched, and it re-filtered results
  on the undebounced term, blanking the list while typing.

Remove the three record toggles. They never worked: IAM's
PositionTypeConfiguration holds only { id, organizationId,
positionTypeId, timeframe } in every published build, canAssignRecord
and canCreateBankRecord exist nowhere in the package, and the global
ValidationPipe runs with forbidNonWhitelisted, so every write was a 400.
The reads were broken too, passing a positionTypeId to a route that
filters on organizationId. A TODO records where the real flag lives:
PositionConfiguration.canReceiveRecord, keyed by positionId.

Delete ActionsColumn.tsx, which had no references.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-23 13:42:08 +00:00
Nathnael
d47e3ae4f5 docker exefix: reimplement the admin form 2026-07-23 11:48:08 +00:00
Nathnael
cbff529e31 feat: rebuild the admin pages 2026-07-23 07:40:48 +00:00
natib21
0d98ccb04b fix 2026-07-17 13:10:27 +00:00
natib21
a8234a4044 resolve build issue 2026-07-11 05:49:10 +00:00