mirror of
https://github.com/Tria-plc/edr-platform.git
synced 2026-08-26 18:42:49 +00:00
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>
This commit is contained in:
@@ -2653,6 +2653,7 @@
|
||||
"copyPermissionsHint": "የነበረ የቦታ አይነት ይምረጡ፤ ፍቃዶቹ አስቀድመው ይሞላሉ፣ ከታች ማስተካከል ይችላሉ።",
|
||||
"copyPermissionsFailed": "ፍቃዶችን መቅዳት አልተቻለም",
|
||||
"selectOrganizationToCopy": "መቅዳት የሚችሏቸውን የቦታ ዓይነቶች ለማየት መጀመሪያ ድርጅት ይምረጡ",
|
||||
"selectUnitToCopy": "መቅዳት የሚችሏቸውን የቦታ ዓይነቶች ለማየት መጀመሪያ ክፍል ይምረጡ",
|
||||
"cannotClearAllPermissions": "ተቀምጧል። ፍቃዶቹ አልተቀየሩም — ይህ የቦታ ዓይነት ቢያንስ አንድ ፍቃድ ሊኖረው ይገባል።",
|
||||
"permissionsSelected": "{{count}} ተመርጠዋል",
|
||||
"positionTypeCreated": "የቦታ ዓይነት ተፈጥሯል",
|
||||
|
||||
@@ -2762,6 +2762,7 @@
|
||||
"copyPermissionsHint": "Pick an existing position type to pre-fill its permissions, then edit below.",
|
||||
"copyPermissionsFailed": "Failed to copy permissions",
|
||||
"selectOrganizationToCopy": "Select an organization to see the position types you can copy from",
|
||||
"selectUnitToCopy": "Select a unit to see the position types you can copy from",
|
||||
"cannotClearAllPermissions": "Saved. Permissions were left unchanged — this position type must keep at least one permission.",
|
||||
"permissionsSelected": "{{count}} selected",
|
||||
"positionTypeCreated": "Position type created",
|
||||
|
||||
@@ -1888,6 +1888,7 @@
|
||||
"copyPermissionsHint": "Choisissez un type de poste existant pour préremplir ses autorisations, puis modifiez ci-dessous.",
|
||||
"copyPermissionsFailed": "Échec de la copie des autorisations",
|
||||
"selectOrganizationToCopy": "Sélectionnez une organisation pour voir les types de poste que vous pouvez copier",
|
||||
"selectUnitToCopy": "Sélectionnez une unité pour voir les types de poste que vous pouvez copier",
|
||||
"cannotClearAllPermissions": "Enregistré. Les autorisations n'ont pas été modifiées — ce type de poste doit conserver au moins une autorisation.",
|
||||
"permissionsSelected": "{{count}} sélectionné(s)",
|
||||
"positionTypeCreated": "Type de poste créé",
|
||||
|
||||
@@ -115,6 +115,7 @@ export const CreatePositionForm = ({
|
||||
});
|
||||
|
||||
const selectedOrganizationId = form.watch("organizationId");
|
||||
const selectedUnitId = form.watch("unitId");
|
||||
|
||||
const { organizationsResponse, isLoading: isLoadingOrgs } = useOrganizations(
|
||||
"Org",
|
||||
@@ -163,36 +164,32 @@ export const CreatePositionForm = ({
|
||||
enabled: mode === "edit" && !!positionTypeId,
|
||||
});
|
||||
|
||||
// A position type belongs to a unit, and a unit to an organization — IAM has
|
||||
// no organizationId on the type itself and no organization-scoped route, so
|
||||
// the picked org narrows the list through its units. isSystem types are the
|
||||
// shared "commons" and stay available to every organization.
|
||||
const orgUnitIds = useMemo(
|
||||
() =>
|
||||
new Set(
|
||||
(unitsResponse?.data?.items ?? []).map((unit: UnitDto) => unit.id),
|
||||
),
|
||||
[unitsResponse],
|
||||
);
|
||||
|
||||
// A position type belongs to a single unit — scope copy sources to the
|
||||
// selected unit, same as the "Select Unit" filter on the position list page.
|
||||
// isSystem types are the shared "commons" and stay available everywhere.
|
||||
const copyFromOptions = useMemo(() => {
|
||||
if (!selectedOrganizationId) return [];
|
||||
if (!selectedUnitId) return [];
|
||||
return positionTypes.filter(
|
||||
(type: PositionTypeDto) =>
|
||||
type.id !== positionTypeId &&
|
||||
(type.isSystem || (!!type.unitId && orgUnitIds.has(type.unitId))),
|
||||
(type.isSystem || type.unitId === selectedUnitId),
|
||||
);
|
||||
}, [positionTypes, orgUnitIds, selectedOrganizationId, positionTypeId]);
|
||||
}, [positionTypes, selectedUnitId, positionTypeId]);
|
||||
|
||||
// Reset the selected unit when the organization changes so a unit from a
|
||||
// different org can't be submitted by mistake. The copy source is cleared
|
||||
// too — it is scoped to the old organization.
|
||||
// different org can't be submitted by mistake.
|
||||
useEffect(() => {
|
||||
if (mode === "edit") return;
|
||||
form.setValue("unitId", "");
|
||||
setCopyFromPositionId("");
|
||||
}, [selectedOrganizationId, mode, form]);
|
||||
|
||||
// The copy source is scoped to the selected unit — clear it whenever the
|
||||
// unit changes (including as a side effect of the org reset above) so a
|
||||
// stale selection from a different unit can't be submitted.
|
||||
useEffect(() => {
|
||||
setCopyFromPositionId("");
|
||||
}, [selectedUnitId]);
|
||||
|
||||
useEffect(() => {
|
||||
if (mode !== "edit" || !initialValues || !positionTypeId) return;
|
||||
if (hasLoadedEditData.current) return;
|
||||
@@ -335,11 +332,13 @@ export const CreatePositionForm = ({
|
||||
|
||||
const copyFromPlaceholder = !selectedOrganizationId
|
||||
? t("contentManagement.selectOrganizationToCopy")
|
||||
: isCopying || isLoadingPositionTypes || isLoadingUnits
|
||||
? t("common.loading")
|
||||
: isErrorPositionTypes
|
||||
? t("contentManagement.failedToLoadPositionTypes")
|
||||
: t("contentManagement.selectPositionToCopy");
|
||||
: !selectedUnitId
|
||||
? t("contentManagement.selectUnitToCopy")
|
||||
: isCopying || isLoadingPositionTypes || isLoadingUnits
|
||||
? t("common.loading")
|
||||
: isErrorPositionTypes
|
||||
? t("contentManagement.failedToLoadPositionTypes")
|
||||
: t("contentManagement.selectPositionToCopy");
|
||||
|
||||
return (
|
||||
<Form {...form}>
|
||||
@@ -454,6 +453,7 @@ export const CreatePositionForm = ({
|
||||
onValueChange={handleCopyFrom}
|
||||
disabled={
|
||||
!selectedOrganizationId ||
|
||||
!selectedUnitId ||
|
||||
isLoadingPositionTypes ||
|
||||
isLoadingUnits ||
|
||||
isCopying
|
||||
|
||||
Reference in New Issue
Block a user