diff --git a/back/src/adapters/primary/routers/admin/createAdminRouter.ts b/back/src/adapters/primary/routers/admin/createAdminRouter.ts index 690bd5c584..909dc94af3 100644 --- a/back/src/adapters/primary/routers/admin/createAdminRouter.ts +++ b/back/src/adapters/primary/routers/admin/createAdminRouter.ts @@ -100,17 +100,6 @@ export const createAdminRouter = (deps: AppDependencies): Router => { ), ); - sharedAdminRouter.removeUserFromAgency( - deps.connectedUserAuthMiddleware, - (req, res) => - sendHttpResponse(req, res, () => - deps.useCases.removeUserFromAgency.execute( - req.params, - getGenericAuthOrThrow(req.payloads?.currentUser), - ), - ), - ); - sharedAdminRouter.rejectIcUserForAgency( deps.connectedUserAuthMiddleware, (req, res) => diff --git a/back/src/config/bootstrap/createUseCases.ts b/back/src/config/bootstrap/createUseCases.ts index 806862a054..ebe1770fb3 100644 --- a/back/src/config/bootstrap/createUseCases.ts +++ b/back/src/config/bootstrap/createUseCases.ts @@ -16,6 +16,7 @@ import { makeListAgencyOptionsByFilter } from "../../domains/agency/use-cases/Li import { makeNotifyAgencyHasBeenPutOnHold } from "../../domains/agency/use-cases/NotifyAgencyHasBeenPutOnHold"; import { makeNotifyDelegationConventionReminder } from "../../domains/agency/use-cases/notifications/NotifyDelegationConventionReminder"; import { makeRegisterAgencyToConnectedUser } from "../../domains/agency/use-cases/RegisterAgencyToConnectedUser"; +import { makeRemoveUserFromAgency } from "../../domains/agency/use-cases/RemoveUserFromAgency"; import { makeUpdateAgency } from "../../domains/agency/use-cases/UpdateAgency"; import { makeUpdateAgencyReferringToUpdatedAgency } from "../../domains/agency/use-cases/UpdateAgencyReferringToUpdatedAgency"; import { makeUpdateAgencyStatus } from "../../domains/agency/use-cases/UpdateAgencyStatus"; @@ -27,7 +28,6 @@ import { makeGetConnectedUsers } from "../../domains/connected-users/use-cases/G import { makeGetUsers } from "../../domains/connected-users/use-cases/GetUsers"; import { makeLinkFranceTravailUsersToTheirAgencies } from "../../domains/connected-users/use-cases/LinkFranceTravailUsersToTheirAgencies"; import { makeRejectUserForAgency } from "../../domains/connected-users/use-cases/RejectUserForAgency"; -import { makeRemoveUserFromAgency } from "../../domains/connected-users/use-cases/RemoveUserFromAgency"; import { makeUpdateUserForAgency } from "../../domains/connected-users/use-cases/UpdateUserForAgency"; import { makeAddConvention } from "../../domains/convention/use-cases/AddConvention"; import { makeAddValidatedConventionNps } from "../../domains/convention/use-cases/AddValidatedConventionNps"; diff --git a/back/src/domains/connected-users/use-cases/RemoveUserFromAgency.ts b/back/src/domains/agency/use-cases/RemoveUserFromAgency.ts similarity index 92% rename from back/src/domains/connected-users/use-cases/RemoveUserFromAgency.ts rename to back/src/domains/agency/use-cases/RemoveUserFromAgency.ts index a0b07f7749..d0cb31b5c7 100644 --- a/back/src/domains/connected-users/use-cases/RemoveUserFromAgency.ts +++ b/back/src/domains/agency/use-cases/RemoveUserFromAgency.ts @@ -4,13 +4,13 @@ import { type WithAgencyIdAndUserId, withAgencyIdAndUserIdSchema, } from "shared"; -import type { CreateNewEvent } from "../../core/events/ports/EventBus"; -import { useCaseBuilder } from "../../core/useCaseBuilder"; import { rejectIfEditionOfValidatorsOfAgencyWithRefersTo, validateAgencyRights, -} from "../helpers/agencyRights.helper"; -import { throwIfNotAgencyAdminOrBackofficeAdmin } from "../helpers/authorization.helper"; +} from "../../connected-users/helpers/agencyRights.helper"; +import { throwIfNotAgencyAdminOrBackofficeAdmin } from "../../connected-users/helpers/authorization.helper"; +import type { CreateNewEvent } from "../../core/events/ports/EventBus"; +import { useCaseBuilder } from "../../core/useCaseBuilder"; export type RemoveUserFromAgency = ReturnType; diff --git a/back/src/domains/connected-users/use-cases/RemoveUserFromAgency.unit.test.ts b/back/src/domains/agency/use-cases/RemoveUserFromAgency.unit.test.ts similarity index 65% rename from back/src/domains/connected-users/use-cases/RemoveUserFromAgency.unit.test.ts rename to back/src/domains/agency/use-cases/RemoveUserFromAgency.unit.test.ts index e9230dbfbd..71a3736538 100644 --- a/back/src/domains/connected-users/use-cases/RemoveUserFromAgency.unit.test.ts +++ b/back/src/domains/agency/use-cases/RemoveUserFromAgency.unit.test.ts @@ -1,6 +1,7 @@ import { type AgencyDto, AgencyDtoBuilder, + type AgencyRole, ConnectedUserBuilder, errors, expectArraysToMatch, @@ -279,152 +280,162 @@ describe("RemoveUserFromAgency", () => { }); }); - it("User to-review can remove himself", async () => { - const agency2 = new AgencyDtoBuilder().withId("agency-2-id").build(); - const otherUserWithRightOnAgencies: User = { - ...notAdmin, - id: "other-user-id", - }; - - uow.userRepository.users = [notAdminUser, otherUserWithRightOnAgencies]; - uow.agencyRepository.agencies = [ - toAgencyWithRights(agency, { - [notAdminUser.id]: { - roles: ["to-review"], - isNotifiedByEmail: false, - }, - [otherUserWithRightOnAgencies.id]: { - roles: ["validator"], - isNotifiedByEmail: true, - }, - }), - toAgencyWithRights(agency2, { - [notAdminUser.id]: { - roles: ["validator"], - isNotifiedByEmail: true, - }, - [otherUserWithRightOnAgencies.id]: { - roles: ["validator"], - isNotifiedByEmail: true, - }, - }), - ]; - - const inputParams: WithAgencyIdAndUserId = { - agencyId: agency.id, - userId: notAdminUser.id, - }; - await removeUserFromAgency.execute(inputParams, notAdmin); - - expectToEqual(uow.agencyRepository.agencies, [ - toAgencyWithRights(agency, { - [otherUserWithRightOnAgencies.id]: { - roles: ["validator"], - isNotifiedByEmail: true, - }, - }), - toAgencyWithRights(agency2, { - [notAdminUser.id]: { - roles: ["validator"], - isNotifiedByEmail: true, - }, - [otherUserWithRightOnAgencies.id]: { - roles: ["validator"], - isNotifiedByEmail: true, - }, - }), - ]); - expectArraysToMatch(uow.outboxRepository.events, [ - { - topic: "ConnectedUserAgencyRightChanged", - payload: { - ...inputParams, - triggeredBy: { - kind: "connected-user", - userId: notAdmin.id, + describe("Right paths", () => { + describe("user can remove himself from agency", () => { + it.each([ + "to-review", + "agency-viewer", + "counsellor", + "validator", + "agency-admin", + ] satisfies AgencyRole[])("with right %s", async (role) => { + const agency2 = new AgencyDtoBuilder().withId("agency-2-id").build(); + const otherUserWithRightOnAgencies: User = { + ...notAdmin, + id: "other-user-id", + }; + + uow.userRepository.users = [notAdminUser, otherUserWithRightOnAgencies]; + uow.agencyRepository.agencies = [ + toAgencyWithRights(agency, { + [notAdminUser.id]: { + roles: [role], + isNotifiedByEmail: false, + }, + [otherUserWithRightOnAgencies.id]: { + roles: ["validator"], + isNotifiedByEmail: true, + }, + }), + toAgencyWithRights(agency2, { + [notAdminUser.id]: { + roles: ["validator"], + isNotifiedByEmail: true, + }, + [otherUserWithRightOnAgencies.id]: { + roles: ["validator"], + isNotifiedByEmail: true, + }, + }), + ]; + + const inputParams: WithAgencyIdAndUserId = { + agencyId: agency.id, + userId: notAdminUser.id, + }; + await removeUserFromAgency.execute(inputParams, notAdmin); + + expectToEqual(uow.agencyRepository.agencies, [ + toAgencyWithRights(agency, { + [otherUserWithRightOnAgencies.id]: { + roles: ["validator"], + isNotifiedByEmail: true, + }, + }), + toAgencyWithRights(agency2, { + [notAdminUser.id]: { + roles: ["validator"], + isNotifiedByEmail: true, + }, + [otherUserWithRightOnAgencies.id]: { + roles: ["validator"], + isNotifiedByEmail: true, + }, + }), + ]); + expectArraysToMatch(uow.outboxRepository.events, [ + { + topic: "ConnectedUserAgencyRightChanged", + payload: { + ...inputParams, + triggeredBy: { + kind: "connected-user", + userId: notAdmin.id, + }, + }, }, - }, - }, - ]); - }); + ]); + }); + }); - it.each([ - { - triggeredByRole: "backoffice-admin", - triggeredByUser: connectedAdmin, - }, - { - triggeredByRole: "agency-admin", - triggeredByUser: agencyAdminUser, - }, - ])("$triggeredByRole can remove user from agency", async ({ - triggeredByUser, - }) => { - const agency2 = new AgencyDtoBuilder().withId("agency-2-id").build(); - const otherUserWithRightOnAgencies: User = { - ...notAdmin, - id: "other-user-id", - }; - - uow.userRepository.users = [notAdminUser, otherUserWithRightOnAgencies]; - uow.agencyRepository.agencies = [ - toAgencyWithRights(agency, { - [notAdminUser.id]: { - roles: ["validator"], - isNotifiedByEmail: true, - }, - [otherUserWithRightOnAgencies.id]: { - roles: ["validator"], - isNotifiedByEmail: true, - }, - }), - toAgencyWithRights(agency2, { - [notAdminUser.id]: { - roles: ["validator"], - isNotifiedByEmail: true, - }, - [otherUserWithRightOnAgencies.id]: { - roles: ["validator"], - isNotifiedByEmail: true, - }, - }), - ]; - - const inputParams: WithAgencyIdAndUserId = { - agencyId: agency.id, - userId: notAdminUser.id, - }; - await removeUserFromAgency.execute(inputParams, triggeredByUser); - - expectToEqual(uow.agencyRepository.agencies, [ - toAgencyWithRights(agency, { - [otherUserWithRightOnAgencies.id]: { - roles: ["validator"], - isNotifiedByEmail: true, - }, - }), - toAgencyWithRights(agency2, { - [notAdminUser.id]: { - roles: ["validator"], - isNotifiedByEmail: true, + describe("can remove another user from agency", () => { + it.each([ + { + triggeredByRole: "backoffice-admin", + triggeredByUser: connectedAdmin, }, - [otherUserWithRightOnAgencies.id]: { - roles: ["validator"], - isNotifiedByEmail: true, + { + triggeredByRole: "agency-admin", + triggeredByUser: agencyAdminUser, }, - }), - ]); - expectArraysToMatch(uow.outboxRepository.events, [ - { - topic: "ConnectedUserAgencyRightChanged", - payload: { - ...inputParams, - triggeredBy: { - kind: "connected-user", - userId: triggeredByUser.id, + ])("when user has $triggeredByRole role", async ({ triggeredByUser }) => { + const agency2 = new AgencyDtoBuilder().withId("agency-2-id").build(); + const otherUserWithRightOnAgencies: User = { + ...notAdmin, + id: "other-user-id", + }; + + uow.userRepository.users = [notAdminUser, otherUserWithRightOnAgencies]; + uow.agencyRepository.agencies = [ + toAgencyWithRights(agency, { + [notAdminUser.id]: { + roles: ["validator"], + isNotifiedByEmail: true, + }, + [otherUserWithRightOnAgencies.id]: { + roles: ["validator"], + isNotifiedByEmail: true, + }, + }), + toAgencyWithRights(agency2, { + [notAdminUser.id]: { + roles: ["validator"], + isNotifiedByEmail: true, + }, + [otherUserWithRightOnAgencies.id]: { + roles: ["validator"], + isNotifiedByEmail: true, + }, + }), + ]; + + const inputParams: WithAgencyIdAndUserId = { + agencyId: agency.id, + userId: notAdminUser.id, + }; + await removeUserFromAgency.execute(inputParams, triggeredByUser); + + expectToEqual(uow.agencyRepository.agencies, [ + toAgencyWithRights(agency, { + [otherUserWithRightOnAgencies.id]: { + roles: ["validator"], + isNotifiedByEmail: true, + }, + }), + toAgencyWithRights(agency2, { + [notAdminUser.id]: { + roles: ["validator"], + isNotifiedByEmail: true, + }, + [otherUserWithRightOnAgencies.id]: { + roles: ["validator"], + isNotifiedByEmail: true, + }, + }), + ]); + expectArraysToMatch(uow.outboxRepository.events, [ + { + topic: "ConnectedUserAgencyRightChanged", + payload: { + ...inputParams, + triggeredBy: { + kind: "connected-user", + userId: triggeredByUser.id, + }, + }, }, - }, - }, - ]); + ]); + }); + }); }); }); diff --git a/front/src/app/components/agency/AgencyUsers.tsx b/front/src/app/components/agency/AgencyUsers.tsx index 9472d398d0..3b3c6a191d 100644 --- a/front/src/app/components/agency/AgencyUsers.tsx +++ b/front/src/app/components/agency/AgencyUsers.tsx @@ -1,6 +1,5 @@ import { fr } from "@codegouvfr/react-dsfr"; import Button from "@codegouvfr/react-dsfr/Button"; -import { ButtonsGroup } from "@codegouvfr/react-dsfr/ButtonsGroup"; import { createModal } from "@codegouvfr/react-dsfr/Modal"; import { partition, values } from "ramda"; import { Fragment, useMemo, useState } from "react"; @@ -22,7 +21,6 @@ import { connectedUsersAdminSlice, } from "src/core-logic/domain/admin/connectedUsersAdmin/connectedUsersAdmin.slice"; import { createUserOnAgencySlice } from "src/core-logic/domain/agencies/create-user-on-agency/createUserOnAgency.slice"; -import { removeUserFromAgencySlice } from "src/core-logic/domain/agencies/remove-user-from-agency/removeUserFromAgency.slice"; import { updateUserOnAgencySlice } from "src/core-logic/domain/agencies/update-user-on-agency/updateUserOnAgency.slice"; import { feedbackSlice } from "src/core-logic/domain/feedback/feedback.slice"; import { v4 as uuidV4 } from "uuid"; @@ -45,9 +43,6 @@ export const AgencyUsers = ({ const manageUserModalId = isLocationAdmin ? domElementIds.admin.agencyTab.editAgencyManageUserModal : domElementIds.agencyDashboard.agencyDetails.editAgencyManageUserModal; - const removeUserModalId = isLocationAdmin - ? domElementIds.admin.agencyTab.editAgencyRemoveUserModal - : domElementIds.agencyDashboard.agencyDetails.editAgencyRemoveUserModal; const manageUserModal = useMemo( () => createModal({ @@ -57,21 +52,13 @@ export const AgencyUsers = ({ [manageUserModalId], ); - const removeUserModal = useMemo( - () => - createModal({ - isOpenedByDefault: false, - id: removeUserModalId, - }), - [removeUserModalId], - ); const dispatch = useDispatch(); const [selectedUserData, setSelectedUserData] = useState< (UserParamsForAgency & { isIcUser: boolean }) | null >(null); - const [mode, setMode] = useState<"add" | "update" | "delete" | null>(null); + const [mode, setMode] = useState<"add" | "update" | null>(null); const onModifyClicked = ( agencyUser: ConnectedUserWithNormalizedAgencyRights, @@ -89,22 +76,6 @@ export const AgencyUsers = ({ manageUserModal.open(); }; - const onDeleteClicked = ( - agencyUser: ConnectedUserWithNormalizedAgencyRights, - ) => { - dispatch(feedbackSlice.actions.clearFeedbacksTriggered()); - setMode("delete"); - setSelectedUserData({ - agencyId: agency.id, - userId: agencyUser.id, - roles: agencyUser.agencyRights[agency.id].roles, - email: agencyUser.email, - isNotifiedByEmail: agencyUser.agencyRights[agency.id].isNotifiedByEmail, - isIcUser: !!agencyUser.proConnect, - }); - removeUserModal.open(); - }; - const agencyRefersToOtherAgency = agency.refersToAgencyId !== null; const [agencyUsers, agencyUsersInOtherAgency] = agencyRefersToOtherAgency @@ -153,28 +124,6 @@ export const AgencyUsers = ({ ); }; - const onUserRemoveSubmitted = () => { - if (!selectedUserData) return; - - isLocationAdmin - ? dispatch( - connectedUsersAdminSlice.actions.removeUserFromAgencyRequested({ - userId: selectedUserData.userId, - agencyId: agency.id, - feedbackTopic: "agency-user", - }), - ) - : dispatch( - removeUserFromAgencySlice.actions.removeUserFromAgencyRequested({ - userId: selectedUserData.userId, - agencyId: agency.id, - feedbackTopic: "agency-user-for-dashboard", - }), - ); - - removeUserModal.close(); - }; - return ( <>

Utilisateurs

@@ -226,7 +175,6 @@ export const AgencyUsers = ({ agencyUsers={agencyUsers} agency={agency} onModifyClicked={onModifyClicked} - onDeleteClicked={onDeleteClicked} routeName={routeName} /> @@ -243,7 +191,6 @@ export const AgencyUsers = ({ agencyUsers={agencyUsersInOtherAgency} agency={agency} onModifyClicked={onModifyClicked} - onDeleteClicked={onDeleteClicked} routeName={routeName} /> @@ -290,36 +237,6 @@ export const AgencyUsers = ({ , document.body, )} - - {createPortal( - -

- Vous êtes sur le point de supprimer le rattachement de{" "} - {selectedUserData?.email} à l'agence "{agency.name}". -

-

Souhaitez-vous continuer ?

- { - removeUserModal.close(); - }, - }, - { - id: domElementIds.admin.agencyTab - .editAgencyRemoveUserConfirmationButton, - priority: "primary", - children: "Supprimer le rattachement", - onClick: () => onUserRemoveSubmitted(), - }, - ]} - /> -
, - document.body, - )} ); }; diff --git a/front/src/app/components/agency/AgencyUsersTable.tsx b/front/src/app/components/agency/AgencyUsersTable.tsx index 2c254eca69..3e61fcf417 100644 --- a/front/src/app/components/agency/AgencyUsersTable.tsx +++ b/front/src/app/components/agency/AgencyUsersTable.tsx @@ -1,20 +1,29 @@ import { fr } from "@codegouvfr/react-dsfr"; import { Badge } from "@codegouvfr/react-dsfr/Badge"; import { ButtonsGroup } from "@codegouvfr/react-dsfr/ButtonsGroup"; +import { createModal } from "@codegouvfr/react-dsfr/Modal"; import { Table } from "@codegouvfr/react-dsfr/Table"; +import { useMemo, useState } from "react"; import { NotificationIndicator } from "react-design-system"; - +import { createPortal } from "react-dom"; +import { useDispatch } from "react-redux"; import { type AgencyDto, domElementIds } from "shared"; import { NameAndEmailInTable } from "src/app/components/admin/NameAndEmailInTable"; import type { AgencyOverviewRouteName } from "src/app/components/forms/agency/AgencyOverview"; import { agencyRolesToDisplay } from "src/app/contents/userRolesToDisplay"; import type { ConnectedUserWithNormalizedAgencyRights } from "src/core-logic/domain/admin/connectedUsersAdmin/connectedUsersAdmin.slice"; +import { removeUserFromAgencySlice } from "src/core-logic/domain/agencies/remove-user-from-agency/removeUserFromAgency.slice"; +import { feedbackSlice } from "src/core-logic/domain/feedback/feedback.slice"; +import { + makeRemoveUserAgencyRightsButtonProps, + makeRemoveUserAgencyRightsModalProps, + type UserRightToRemove, +} from "./removeUserAgencyRights"; type AgencyUsersTableProps = { agencyUsers: ConnectedUserWithNormalizedAgencyRights[]; agency: AgencyDto; onModifyClicked: (user: ConnectedUserWithNormalizedAgencyRights) => void; - onDeleteClicked: (user: ConnectedUserWithNormalizedAgencyRights) => void; routeName: AgencyOverviewRouteName; }; @@ -22,91 +31,170 @@ export const AgencyUsersTable = ({ agency, agencyUsers, onModifyClicked, - onDeleteClicked, routeName, }: AgencyUsersTableProps) => { - const id = - routeName === "adminAgencies" || routeName === "adminAgencyDetail" - ? domElementIds.admin.agencyTab.agencyUsersTable - : domElementIds.agencyDashboard.agencyDetails.agencyUsersTable; + const dispatch = useDispatch(); + const [userRightToRemove, setUserRightToRemove] = + useState(null); + + const isLocationAdmin = + routeName === "adminAgencies" || routeName === "adminAgencyDetail"; + + const tableId = isLocationAdmin + ? domElementIds.admin.agencyTab.agencyUsersTable + : domElementIds.agencyDashboard.agencyDetails.agencyUsersTable; + + const domElementIdSection = isLocationAdmin + ? domElementIds.admin.agencyTab + : domElementIds.agencyDashboard.agencyDetails; + + const removeUserModal = useMemo( + () => + createModal({ + isOpenedByDefault: false, + id: domElementIdSection.editAgencyRemoveUserModal, + }), + [domElementIdSection.editAgencyRemoveUserModal], + ); + return ( - [ - , - , - agencyUser.agencyRights[agency.id].roles.map((role) => { - return ( - - {agencyRolesToDisplay[role].label} - - ); - }), - onModifyClicked(agencyUser), + <> +
+ TableLine({ + agency, + agencyUser, + index, + isLocationAdmin, + onDeleteClicked: (userRightToRemove) => { + setUserRightToRemove(userRightToRemove); + dispatch(feedbackSlice.actions.clearFeedbacksTriggered()); + removeUserModal.open(); }, - { - children: "Supprimer", - priority: "secondary", - disabled: - agency.refersToAgencyId !== null && - agencyUser.agencyRights[agency.id].roles.includes("validator"), - className: fr.cx("fr-my-1v"), - id: `${ - routeName === "adminAgencies" || - routeName === "adminAgencyDetail" - ? domElementIds.admin.agencyTab.editAgencyRemoveUserButton - : domElementIds.agencyDashboard.agencyDetails - .editAgencyRemoveUserButton - }-${agency.id}-${index}`, - onClick: () => onDeleteClicked(agencyUser), - }, - ]} + onModifyClicked, + setUserRightToRemove, + }), + )} + /> + {createPortal( + removeUserModal.close(), + onSubmitted: (userRightToRemove) => { + dispatch( + removeUserFromAgencySlice.actions.removeUserFromAgencyRequested( + { + userId: userRightToRemove.userId, + agencyId: userRightToRemove.agencyRight.agency.id, + feedbackTopic: isLocationAdmin + ? "agency-user" + : "agency-user-for-dashboard", + }, + ), + ); + removeUserModal.close(); + }, + userRightToRemove, + }) + : { title: "", children: "" })} />, - ])} - /> + document.body, + )} + ); }; + +const TableLine = ({ + isLocationAdmin, + agency, + agencyUser, + index, + onModifyClicked, + onDeleteClicked, +}: { + isLocationAdmin: boolean; + agency: AgencyDto; + agencyUser: ConnectedUserWithNormalizedAgencyRights; + setUserRightToRemove: React.Dispatch< + React.SetStateAction + >; + index: number; + onModifyClicked: (user: ConnectedUserWithNormalizedAgencyRights) => void; + onDeleteClicked: (userRightToRemove: UserRightToRemove) => void; +}): React.ReactNode[] => { + const domElementIdSection = isLocationAdmin + ? domElementIds.admin.agencyTab + : domElementIds.agencyDashboard.agencyDetails; + const removeUserButtonId = `${domElementIdSection.editAgencyRemoveUserButton}-${agency.id}-${agencyUser.id}`; + + const userRightToRemove = { + agencyRight: agencyUser.agencyRights[agency.id], + userEmail: agencyUser.email, + userId: agencyUser.id, + isSelfRemoval: false, + }; + + return [ + , + , + agencyUser.agencyRights[agency.id].roles.map((role) => ( + + {agencyRolesToDisplay[role].label} + + )), + onModifyClicked(agencyUser), + }, + { + ...makeRemoveUserAgencyRightsButtonProps({ + onDeleteClicked: () => onDeleteClicked(userRightToRemove), + userRightToRemove, + removeUserButtonId, + }), + className: fr.cx("fr-my-1v"), + }, + ]} + />, + ]; +}; diff --git a/front/src/app/components/agency/agencies-table/AgenciesTablesSection.tsx b/front/src/app/components/agency/agencies-table/AgenciesTablesSection.tsx index b0658728e3..0f413803c4 100644 --- a/front/src/app/components/agency/agencies-table/AgenciesTablesSection.tsx +++ b/front/src/app/components/agency/agencies-table/AgenciesTablesSection.tsx @@ -13,6 +13,7 @@ import { updateUserOnAgencySlice } from "src/core-logic/domain/agencies/update-u import { connectedUserSelectors } from "src/core-logic/domain/connected-user/connectedUser.selectors"; import type { FeedbackTopic } from "src/core-logic/domain/feedback/feedback.content"; import { Feedback } from "../../feedback/Feedback"; +import { SelfRemoveUserAgencyRightFeedback } from "../removeUserAgencyRights"; import { AgencyRightsTable } from "./AgencyRightsTable"; export const AgenciesTablesSection = ({ @@ -58,6 +59,7 @@ export const AgenciesTablesSection = ({ return ( <> + {toReviewAgencyRights.length > 0 && ( <> diff --git a/front/src/app/components/agency/agencies-table/AgencyRightsTable.tsx b/front/src/app/components/agency/agencies-table/AgencyRightsTable.tsx index 83858b20d8..d045fcf260 100644 --- a/front/src/app/components/agency/agencies-table/AgencyRightsTable.tsx +++ b/front/src/app/components/agency/agencies-table/AgencyRightsTable.tsx @@ -106,12 +106,14 @@ export const AgencyRightsTable = ({ return a.agency.name.localeCompare(b.agency.name); }) .map((agencyRight) => - AgencyRightLine( + AgencyRightLine({ agencyRight, - onUserUpdateRequested && onUpdateClicked, - onUserRegistrationCancelledRequested, + user, + onUpdateClicked: onUserUpdateRequested && onUpdateClicked, + onRegistrationCancelledClicked: + onUserRegistrationCancelledRequested, isBackofficeAdmin, - ), + }), )} /> {onUserUpdateRequested && @@ -159,12 +161,19 @@ export const AgencyRightsTable = ({ ); }; -const AgencyRightLine = ( - agencyRight: AgencyRight, - onUpdateClicked?: (agencyRight: AgencyRight) => void, - onRegistrationCancelledClicked?: (agencyRight: AgencyRight) => void, - isBackofficeAdmin?: boolean, -) => [ +const AgencyRightLine = ({ + agencyRight, + user, + onUpdateClicked, + onRegistrationCancelledClicked, + isBackofficeAdmin, +}: { + agencyRight: AgencyRight; + user: User; + onUpdateClicked?: (agencyRight: AgencyRight) => void; + onRegistrationCancelledClicked?: (agencyRight: AgencyRight) => void; + isBackofficeAdmin?: boolean; +}) => [ @@ -211,6 +220,7 @@ const AgencyRightLine = ( agencyRight={agencyRight} onUpdateClicked={onUpdateClicked} onRegistrationCancelledClicked={onRegistrationCancelledClicked} + user={user} isBackofficeAdmin={isBackofficeAdmin} /> , diff --git a/front/src/app/components/agency/agencies-table/agency-line/AgencyLineRightsCTAs.tsx b/front/src/app/components/agency/agencies-table/agency-line/AgencyLineRightsCTAs.tsx index 75200a3cb7..76ff727e0d 100644 --- a/front/src/app/components/agency/agencies-table/agency-line/AgencyLineRightsCTAs.tsx +++ b/front/src/app/components/agency/agencies-table/agency-line/AgencyLineRightsCTAs.tsx @@ -1,56 +1,125 @@ +import { fr } from "@codegouvfr/react-dsfr"; import Button from "@codegouvfr/react-dsfr/Button"; -import type { ReactNode } from "react"; -import { type AgencyRight, domElementIds, frontRoutes } from "shared"; +import { createModal } from "@codegouvfr/react-dsfr/Modal"; +import { type ReactNode, useMemo } from "react"; +import { createPortal } from "react-dom"; +import { useDispatch } from "react-redux"; +import { + type AgencyRight, + domElementIds, + frontRoutes, + type User, +} from "shared"; +import { removeUserFromAgencySlice } from "src/core-logic/domain/agencies/remove-user-from-agency/removeUserFromAgency.slice"; +import { feedbackSlice } from "src/core-logic/domain/feedback/feedback.slice"; +import { + makeRemoveUserAgencyRightsButtonProps, + makeRemoveUserAgencyRightsModalProps, +} from "../../removeUserAgencyRights"; export const AgencyLineRightsCTAs = ({ agencyRight, isBackofficeAdmin, onUpdateClicked, onRegistrationCancelledClicked, + user, }: { agencyRight: AgencyRight; onUpdateClicked?: (agencyRight: AgencyRight) => void; onRegistrationCancelledClicked?: (agencyRight: AgencyRight) => void; - isBackofficeAdmin?: boolean | undefined; -}): ReactNode => ( - <> - {onUpdateClicked && ( - - )} - {isBackofficeAdmin && ( - - )} - {onRegistrationCancelledClicked && ( + isBackofficeAdmin?: boolean; + user: User; +}): ReactNode => { + const removeUserModalId = `${domElementIds.myAccount.removeAgencyRightModal}-${agencyRight.agency.id}-${user.id}`; + const userRightToRemove = { + agencyRight, + userEmail: user.email, + userId: user.id, + isSelfRemoval: true, + }; + const dispatch = useDispatch(); + const removeUserModal = useMemo( + () => + createModal({ + isOpenedByDefault: false, + id: removeUserModalId, + }), + [removeUserModalId], + ); + + return ( + <> + {onUpdateClicked && ( + + )} - )} - -); + {...makeRemoveUserAgencyRightsButtonProps({ + onDeleteClicked: () => { + dispatch(feedbackSlice.actions.clearFeedbacksTriggered()); + removeUserModal.open(); + }, + removeUserButtonId: `${domElementIds.myAccount.removeAgencyRightButton}-${agencyRight.agency.id}-${user.id}`, + userRightToRemove, + size: "small", + })} + className={fr.cx("fr-mx-1w")} + /> + {isBackofficeAdmin && ( + + )} + {onRegistrationCancelledClicked && ( + + )} + {createPortal( + removeUserModal.Component( + makeRemoveUserAgencyRightsModalProps({ + onCancel: () => removeUserModal.close(), + onSubmitted: () => { + dispatch( + removeUserFromAgencySlice.actions.removeUserFromAgencyRequested( + { + userId: userRightToRemove.userId, + agencyId: userRightToRemove.agencyRight.agency.id, + feedbackTopic: "agency-user-right-self", + }, + ), + ); + removeUserModal.close(); + }, + userRightToRemove, + }), + ), + document.body, + )} + + ); +}; diff --git a/front/src/app/components/agency/removeUserAgencyRights.tsx b/front/src/app/components/agency/removeUserAgencyRights.tsx new file mode 100644 index 0000000000..bd164ad425 --- /dev/null +++ b/front/src/app/components/agency/removeUserAgencyRights.tsx @@ -0,0 +1,132 @@ +import Alert from "@codegouvfr/react-dsfr/Alert"; +import type { ButtonProps } from "@codegouvfr/react-dsfr/Button"; +import ButtonsGroup from "@codegouvfr/react-dsfr/ButtonsGroup"; +import type { ModalProps } from "@codegouvfr/react-dsfr/Modal"; +import { + type AgencyRight, + domElementIds, + type Email, + type UserId, +} from "shared"; +import { Feedback } from "../feedback/Feedback"; + +export const SelfRemoveUserAgencyRightFeedback = () => ( + ( + + Impossible de procéder à votre détachement pour le moment. + Veuillez réessayer ultérieurement ou contacter le support. +
+ {message} + + ) : ( + `Vous avez bien été détaché de l'organisme. Vous n'avez désormais plus accès à ses conventions, bilans et statistiques.` + ) + } + severity={level} + small + /> + )} + /> +); + +export type UserRightToRemove = { + agencyRight: AgencyRight; + userEmail: Email; + userId: UserId; + isSelfRemoval: boolean; +}; + +export const makeRemoveUserAgencyRightsButtonProps = ({ + userRightToRemove, + removeUserButtonId, + size, + onDeleteClicked, +}: { + removeUserButtonId: string; + userRightToRemove: UserRightToRemove; + onDeleteClicked: (userRightToRemove: UserRightToRemove) => void; + size?: ButtonProps.Common["size"]; +}): ButtonProps => ({ + children: "Supprimer", + priority: "secondary", + disabled: + userRightToRemove.agencyRight.agency.refersToAgencyId !== null && + userRightToRemove.agencyRight.roles.includes("validator"), + id: removeUserButtonId, + onClick: () => onDeleteClicked(userRightToRemove), + size, +}); + +export const makeRemoveUserAgencyRightsModalProps = ({ + userRightToRemove, + onCancel, + onSubmitted, +}: { + userRightToRemove: UserRightToRemove; + onSubmitted: (userRightToRemove: UserRightToRemove) => void; + onCancel: () => void; +}): ModalProps => { + return { + title: + userRightToRemove.isSelfRemoval === true + ? `Se détacher de ${userRightToRemove.agencyRight.agency.name}` + : "Confirmer la suppression", + children: ( + <> + {userRightToRemove.isSelfRemoval ? ( + userRightToRemove.agencyRight.roles.includes("agency-admin") ? ( + <> +

+ Vous êtes sur le point de vous détacher de cet organisme. En + tant qu'administrateur, vous perdrez tous vos droits de gestion + ainsi que l'accès aux données qui y sont liés. +

+

Êtes-vous sûr de vouloir continuer ?

+ + ) : ( +

+ Êtes-vous sûr de vouloir quitter cet organisme ? Vous perdrez + immédiatement l'accès à l'ensemble des conventions, bilans, + statistiques et fonctionnalités qui y sont liés. +

+ ) + ) : ( + <> +

+ Vous êtes sur le point de supprimer le rattachement de{" "} + {userRightToRemove.userEmail} à l'agence " + {userRightToRemove.agencyRight.agency.name}". +

+

Souhaitez-vous continuer ?

+ + )} + + onSubmitted(userRightToRemove), + }, + ]} + /> + + ), + }; +}; diff --git a/front/src/app/pages/agency-dashboard/AgencyDashboardMainTab.tsx b/front/src/app/pages/agency-dashboard/AgencyDashboardMainTab.tsx index a22e110f5a..db14d03a19 100644 --- a/front/src/app/pages/agency-dashboard/AgencyDashboardMainTab.tsx +++ b/front/src/app/pages/agency-dashboard/AgencyDashboardMainTab.tsx @@ -6,6 +6,7 @@ import { Loader } from "react-design-system"; import { useDispatch } from "react-redux"; import { type AgencyRight, distinguishAgencyRights } from "shared"; import { NoActiveAgencyRights } from "src/app/components/agency/agency-dashboard/NoActiveAgencyRights"; +import { SelfRemoveUserAgencyRightFeedback } from "src/app/components/agency/removeUserAgencyRights"; import { Feedback } from "src/app/components/feedback/Feedback"; import { useAppSelector } from "src/app/hooks/reduxHooks"; import type { FrontAgencyDashboardRoute } from "src/app/pages/auth/ConnectedPrivateRoutePage"; @@ -43,6 +44,7 @@ export const AgencyDashboardMainTab = ({

Mon espace prescripteur

{isLoading && } + {match({ currentUser }) .with( diff --git a/front/src/core-logic/adapters/AdminGateway/HttpAdminGateway.ts b/front/src/core-logic/adapters/AdminGateway/HttpAdminGateway.ts index 056dc437ea..e519cc6382 100644 --- a/front/src/core-logic/adapters/AdminGateway/HttpAdminGateway.ts +++ b/front/src/core-logic/adapters/AdminGateway/HttpAdminGateway.ts @@ -18,7 +18,6 @@ import { type UserId, type UserParamsForAgency, type UserWithNumberOfAgenciesAndEstablishments, - type WithAgencyIdAndUserId, } from "shared"; import type { HttpClient } from "shared-routes"; import { @@ -209,26 +208,6 @@ export class HttpAdminGateway implements AdminGateway { ); } - public removeUserFromAgency$( - params: WithAgencyIdAndUserId, - token: string, - ): Observable { - return from( - this.httpClient - .removeUserFromAgency({ - headers: { authorization: token }, - urlParams: params, - }) - .then((response) => - match(response) - .with({ status: 200 }, () => undefined) - .with({ status: 400 }, throwBadRequestWithExplicitMessage) - .with({ status: P.union(401, 403, 404) }, logBodyAndThrow) - .otherwise(otherwiseThrow), - ), - ); - } - public listUsers$( filters: GetUsersFilters, token: ConnectedUserJwt, diff --git a/front/src/core-logic/adapters/AdminGateway/SimulatedAdminGateway.ts b/front/src/core-logic/adapters/AdminGateway/SimulatedAdminGateway.ts index 0ce3b1ecfc..1f52d900db 100644 --- a/front/src/core-logic/adapters/AdminGateway/SimulatedAdminGateway.ts +++ b/front/src/core-logic/adapters/AdminGateway/SimulatedAdminGateway.ts @@ -20,7 +20,6 @@ import { type UserId, type UserParamsForAgency, type UserWithNumberOfAgenciesAndEstablishments, - type WithAgencyIdAndUserId, } from "shared"; import type { AdminGateway } from "src/core-logic/ports/AdminGateway"; @@ -125,13 +124,6 @@ export class SimulatedAdminGateway implements AdminGateway { : of(undefined); } - public removeUserFromAgency$( - _params: WithAgencyIdAndUserId, - _token: string, - ): Observable { - return of(undefined); - } - public listUsers$( { emailContains }: GetUsersFilters, _token: string, diff --git a/front/src/core-logic/adapters/AdminGateway/TestAdminGateway.ts b/front/src/core-logic/adapters/AdminGateway/TestAdminGateway.ts index d0767f7b20..7730bcbf26 100644 --- a/front/src/core-logic/adapters/AdminGateway/TestAdminGateway.ts +++ b/front/src/core-logic/adapters/AdminGateway/TestAdminGateway.ts @@ -15,7 +15,6 @@ import type { SetFeatureFlagParam, UserParamsForAgency, UserWithNumberOfAgenciesAndEstablishments, - WithAgencyIdAndUserId, } from "shared"; import type { AdminGateway } from "src/core-logic/ports/AdminGateway"; @@ -44,8 +43,6 @@ export class TestAdminGateway implements AdminGateway { public updateAgencyRoleForUserResponse$ = new Subject(); - public removeUserFromAgencyResponse$ = new Subject(); - public createUserForAgencyResponse$ = new Subject(); public banEstablishmentResponse$ = new Subject(); @@ -109,13 +106,6 @@ export class TestAdminGateway implements AdminGateway { return this.updateAgencyRoleForUserResponse$; } - public removeUserFromAgency$( - _params: WithAgencyIdAndUserId, - _token: string, - ): Observable { - return this.removeUserFromAgencyResponse$; - } - public listUsers$( _params: GetUsersFilters, _token: string, diff --git a/front/src/core-logic/domain/admin/connectedUsersAdmin/connectedUsersAdmin.epics.ts b/front/src/core-logic/domain/admin/connectedUsersAdmin/connectedUsersAdmin.epics.ts index 10cca4fa1b..8eb310f756 100644 --- a/front/src/core-logic/domain/admin/connectedUsersAdmin/connectedUsersAdmin.epics.ts +++ b/front/src/core-logic/domain/admin/connectedUsersAdmin/connectedUsersAdmin.epics.ts @@ -191,34 +191,6 @@ const updateUserOnAgencyEpic: ConnectedUsersAdminActionEpic = ( ), ); -const removeAgencyUserRequestedEpic: ConnectedUsersAdminActionEpic = ( - action$, - state$, - { adminGateway }, -) => - action$.pipe( - filter( - connectedUsersAdminSlice.actions.removeUserFromAgencyRequested.match, - ), - switchMap((action) => - adminGateway - .removeUserFromAgency$(action.payload, getAdminToken(state$.value)) - .pipe( - map(() => - connectedUsersAdminSlice.actions.removeUserFromAgencySucceeded( - action.payload, - ), - ), - catchEpicError((error) => - connectedUsersAdminSlice.actions.removeUserFromAgencyFailed({ - errorMessage: error.message, - feedbackTopic: action.payload.feedbackTopic, - }), - ), - ), - ), - ); - const fetchConnectedUserOnAgencyUpdateEpic: AppEpic< ConnectedUsersAdminAction | AgencyAction | UpdateAgencyAction > = (action$) => @@ -260,5 +232,4 @@ export const connectedUsersAdminEpics = [ updateUserOnAgencyEpic, fetchConnectedUserOnAgencyUpdateEpic, createUserOnAgencyEpic, - removeAgencyUserRequestedEpic, ]; diff --git a/front/src/core-logic/domain/admin/connectedUsersAdmin/connectedUsersAdmin.slice.ts b/front/src/core-logic/domain/admin/connectedUsersAdmin/connectedUsersAdmin.slice.ts index 6aa3885ccf..aea1c20370 100644 --- a/front/src/core-logic/domain/admin/connectedUsersAdmin/connectedUsersAdmin.slice.ts +++ b/front/src/core-logic/domain/admin/connectedUsersAdmin/connectedUsersAdmin.slice.ts @@ -1,5 +1,4 @@ import { createSlice, type PayloadAction } from "@reduxjs/toolkit"; -import { filter } from "ramda"; import type { AgencyId, AgencyRight, @@ -10,7 +9,6 @@ import type { UserId, UserParamsForAgency, WithAgencyId, - WithAgencyIdAndUserId, WithUserFilters, } from "shared"; import type { SubmitFeedBack } from "src/core-logic/domain/SubmitFeedback"; @@ -223,30 +221,5 @@ export const connectedUsersAdminSlice = createSlice({ ) => { state.isUpdatingConnectedUserAgency = false; }, - - removeUserFromAgencyRequested: ( - state, - _action: PayloadActionWithFeedbackTopic, - ) => { - state.isUpdatingConnectedUserAgency = true; - }, - - removeUserFromAgencySucceeded: ( - state, - action: PayloadActionWithFeedbackTopic, - ) => { - state.isUpdatingConnectedUserAgency = false; - state.agencyUsers = filter( - (agencyUser) => agencyUser.id !== action.payload.userId, - state.agencyUsers, - ); - }, - - removeUserFromAgencyFailed: ( - state, - _action: PayloadActionWithFeedbackTopic<{ errorMessage: string }>, - ) => { - state.isUpdatingConnectedUserAgency = false; - }, }, }); diff --git a/front/src/core-logic/domain/admin/connectedUsersAdmin/connectedUsersAdmin.test.ts b/front/src/core-logic/domain/admin/connectedUsersAdmin/connectedUsersAdmin.test.ts index 547ffbdef9..c90799e3c2 100644 --- a/front/src/core-logic/domain/admin/connectedUsersAdmin/connectedUsersAdmin.test.ts +++ b/front/src/core-logic/domain/admin/connectedUsersAdmin/connectedUsersAdmin.test.ts @@ -735,99 +735,6 @@ describe("Agency registration for authenticated users", () => { }); }); - describe("Remove users from agency", () => { - it("should remove user successfully", () => { - const prefilledAdminState = adminPreloadedState({ - connectedUsersAdmin: { - ...connectedUsersAdminInitialState, - agencyUsers: testUserSet, - }, - }); - ({ store, dependencies } = createTestStore({ - admin: prefilledAdminState, - })); - const userToRemove = testUserSet[authUser1.id]; - - expectToEqual( - store.getState().admin.connectedUsersAdmin, - prefilledAdminState.connectedUsersAdmin, - ); - - store.dispatch( - connectedUsersAdminSlice.actions.removeUserFromAgencyRequested({ - userId: userToRemove.id, - agencyId: agency1.id, - feedbackTopic: "agency-user", - }), - ); - - expectIsUpdatingUserAgencyToBe(true); - dependencies.adminGateway.removeUserFromAgencyResponse$.next(undefined); - - expectIsUpdatingUserAgencyToBe(false); - expectToEqual( - connectedUsersAdminSelectors.agencyUsers(store.getState()), - { - [authUser2.id]: testUserSet[authUser2.id], - }, - ); - expectToEqual( - feedbacksSelectors.feedbacks(store.getState())["agency-user"], - { - level: "success", - message: "Les données de l'utilisateur (rôles) ont été mises à jour.", - on: "delete", - title: "L'utilisateur n'est plus rattaché à cette agence", - }, - ); - }); - - it("should return an error if user removal went wrong", () => { - const prefilledAdminState = adminPreloadedState({ - connectedUsersAdmin: { - ...connectedUsersAdminInitialState, - agencyUsers: testUserSet, - }, - }); - ({ store, dependencies } = createTestStore({ - admin: prefilledAdminState, - })); - const userToRemove = testUserSet[authUser1.id]; - const errorMessage = - "Une erreur est survenue lors de la suppression du rattachement de l'utilisateur"; - - expectToEqual( - store.getState().admin.connectedUsersAdmin, - prefilledAdminState.connectedUsersAdmin, - ); - - store.dispatch( - connectedUsersAdminSlice.actions.removeUserFromAgencyRequested({ - userId: userToRemove.id, - agencyId: agency1.id, - feedbackTopic: "agency-user", - }), - ); - - expectIsUpdatingUserAgencyToBe(true); - dependencies.adminGateway.removeUserFromAgencyResponse$.error( - new Error(errorMessage), - ); - expectIsUpdatingUserAgencyToBe(false); - - expectToEqual( - feedbacksSelectors.feedbacks(store.getState())["agency-user"], - { - level: "error", - message: errorMessage, - on: "delete", - title: - "Problème lors de la suppression du rattachement l'utilisateur à cette agence", - }, - ); - }); - }); - const expectIsUpdatingUserAgencyToBe = (expected: boolean) => { expect( connectedUsersAdminSelectors.isUpdatingConnectedUserAgency( diff --git a/front/src/core-logic/domain/agencies/fetch-agency/fetchAgency.epics.ts b/front/src/core-logic/domain/agencies/fetch-agency/fetchAgency.epics.ts index ba2cf43fbb..6cbb646f85 100644 --- a/front/src/core-logic/domain/agencies/fetch-agency/fetchAgency.epics.ts +++ b/front/src/core-logic/domain/agencies/fetch-agency/fetchAgency.epics.ts @@ -28,9 +28,6 @@ const getAgencyEpic: FetchAgencyEpic = (action$, state$, dependencies) => connectedUsersAdminSlice.actions.updateUserOnAgencySucceeded.match( action, ) || - connectedUsersAdminSlice.actions.removeUserFromAgencySucceeded.match( - action, - ) || connectedUsersAdminSlice.actions.createUserOnAgencySucceeded.match( action, ) || diff --git a/front/src/core-logic/domain/feedback/feedback.content.ts b/front/src/core-logic/domain/feedback/feedback.content.ts index cfef45ac81..b55ebdc7f2 100644 --- a/front/src/core-logic/domain/feedback/feedback.content.ts +++ b/front/src/core-logic/domain/feedback/feedback.content.ts @@ -45,6 +45,7 @@ const topics = [ "agency-for-dashboard", "agency-user-for-dashboard", "agency-user", + "agency-user-right-self", "api-consumer-global", "api-consumer-names", "api-consumer-renew", @@ -342,12 +343,12 @@ export const feedbacks: Record< message: "Une erreur est survenue lors de la création de l'utilisateur", }, "delete.success": { - action: connectedUsersAdminSlice.actions.removeUserFromAgencySucceeded, + action: removeUserFromAgencySlice.actions.removeUserFromAgencySucceeded, title: "L'utilisateur n'est plus rattaché à cette agence", message: "Les données de l'utilisateur (rôles) ont été mises à jour.", }, "delete.error": { - action: connectedUsersAdminSlice.actions.removeUserFromAgencyFailed, + action: removeUserFromAgencySlice.actions.removeUserFromAgencyFailed, title: "Problème lors de la suppression du rattachement l'utilisateur à cette agence", message: @@ -516,6 +517,20 @@ export const feedbacks: Record< message: "L'import en masse a réussi, voici le détail :", }, }, + "agency-user-right-self": { + "delete.success": { + action: removeUserFromAgencySlice.actions.removeUserFromAgencySucceeded, + title: "Détachement effectué avec succès", + message: + "Vous avez bien été détaché de l'organisme. Vous n'avez désormais plus accès à ses conventions, bilans et statistiques.", + }, + "delete.error": { + action: removeUserFromAgencySlice.actions.removeUserFromAgencyFailed, + title: "Une erreur est survenue", + message: + "Impossible de procéder à votre détachement pour le moment. Veuillez réessayer ultérieurement ou contacter le support.", + }, + }, user: { "update.success": { action: updateUserOnAgencySlice.actions.updateUserAgencyRightSucceeded, diff --git a/front/src/core-logic/ports/AdminGateway.ts b/front/src/core-logic/ports/AdminGateway.ts index 4a98a95663..aaab09f8f6 100644 --- a/front/src/core-logic/ports/AdminGateway.ts +++ b/front/src/core-logic/ports/AdminGateway.ts @@ -17,7 +17,6 @@ import type { UserId, UserParamsForAgency, UserWithNumberOfAgenciesAndEstablishments, - WithAgencyIdAndUserId, } from "shared"; export interface AdminGateway { @@ -52,11 +51,6 @@ export interface AdminGateway { token: ConnectedUserJwt, ): Observable; - removeUserFromAgency$( - params: WithAgencyIdAndUserId, - token: ConnectedUserJwt, - ): Observable; - rejectUserForAgency$( params: RejectConnectedUserRoleForAgencyParams, token: ConnectedUserJwt, diff --git a/shared/src/admin/admin.routes.ts b/shared/src/admin/admin.routes.ts index 2db9122c11..e7b903b5bc 100644 --- a/shared/src/admin/admin.routes.ts +++ b/shared/src/admin/admin.routes.ts @@ -61,18 +61,6 @@ export const adminRoutes = defineRoutes({ 404: httpErrorSchema, }, }), - removeUserFromAgency: defineRoute({ - method: "delete", - url: "/admin/inclusion-connected/users/:userId/agency/:agencyId", - ...withAuthorizationHeaders, - responses: { - 200: expressEmptyResponseBody, - 400: httpErrorSchema, - 401: httpErrorSchema, - 403: httpErrorSchema, - 404: httpErrorSchema, - }, - }), // Cette route existe aussi dans le agency router, qui enclenche le même usecase >> c'est un bordel ici ... createUserForAgency: defineRoute({ diff --git a/shared/src/domElementIds.ts b/shared/src/domElementIds.ts index 0478c70202..b3be436c1a 100644 --- a/shared/src/domElementIds.ts +++ b/shared/src/domElementIds.ts @@ -931,6 +931,8 @@ export const domElementIds = { adminAgencyLink: "im-profile__admin-agency-link", adminEstablishmentLink: "im-profile__admin-establishment-link", cancelRegistrationButton: "im-profile__cancel-registration-button", + removeAgencyRightButton: "im-profile__remove-agency-right-button", + removeAgencyRightModal: "im-profile__remove-agency-right-modal", updateOwnInfosLink: "im-profile__update-own-infos-link", editAgencyUserEmail: "im-profile-edit-agency-user__email", editAgencyManageUserCheckbox: