Skip to content

Commit

Permalink
front AgencyDtoWithoutEmails replaced by AgencyDtoForAgencyUsersAndAd…
Browse files Browse the repository at this point in the history
…mins
  • Loading branch information
bbohec committed Jan 13, 2025
1 parent 83813bb commit cc7b0b7
Show file tree
Hide file tree
Showing 18 changed files with 428 additions and 370 deletions.
120 changes: 59 additions & 61 deletions front/src/app/components/agency/IcUserAgenciesToReview.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { createPortal } from "react-dom";
import { SubmitHandler, useForm } from "react-hook-form";
import { useDispatch } from "react-redux";
import {
AgencyDtoWithoutEmails,
AgencyDtoForAgencyUsersAndAdmins,
AgencyId,
AgencyRight,
RejectIcUserRoleForAgencyParams,
Expand All @@ -32,85 +32,83 @@ type IcUserAgenciesToReviewModalProps = {
mode: "register" | "reject";
};

function AgencyReviewForm({
const AgencyReviewForm = ({
agency,
setSelectedAgency,
selectedUser,
setModalProps,
}: {
agency: AgencyDtoWithoutEmails;
agency: AgencyDtoForAgencyUsersAndAdmins;
selectedUser: User;
setSelectedAgency: (agency: AgencyDtoWithoutEmails) => void;
setSelectedAgency: (agency: AgencyDtoForAgencyUsersAndAdmins) => void;
setModalProps: (modalProps: IcUserAgenciesToReviewModalProps) => void;
}) {
return (
<div className={fr.cx("fr-col-4")}>
<div className={fr.cx("fr-card")}>
<div className={fr.cx("fr-card__body")}>
<div className={fr.cx("fr-card__content")}>
<h3 className={fr.cx("fr-card__title")}>{agency.name}</h3>
<p className={fr.cx("fr-card__desc")}>
{agency.address.streetNumberAndAddress} {agency.address.postcode}{" "}
{agency.address.city}
</p>
<p className={fr.cx("fr-card__desc")}>
<a
{...routes.adminAgencyDetail({ agencyId: agency.id }).link}
target="_blank"
>
Voir les détails de l'agence
</a>
</p>
</div>
<div className={fr.cx("fr-card__footer")}>
<ButtonsGroup
alignment="center"
inlineLayoutWhen="always"
buttonsSize="small"
buttons={[
{
type: "button",
priority: "primary",
id: `${domElementIds.admin.agencyTab.registerIcUserToAgencyButton}-${agency.id}-${selectedUser.id}`,
onClick: () => {
setModalProps({
title: "Rattacher cet utilisateur",
mode: "register",
});
setSelectedAgency(agency);
openIcUserRegistrationToAgencyModal();
},
children: "Valider",
}) => (
<div className={fr.cx("fr-col-4")}>
<div className={fr.cx("fr-card")}>
<div className={fr.cx("fr-card__body")}>
<div className={fr.cx("fr-card__content")}>
<h3 className={fr.cx("fr-card__title")}>{agency.name}</h3>
<p className={fr.cx("fr-card__desc")}>
{agency.address.streetNumberAndAddress} {agency.address.postcode}{" "}
{agency.address.city}
</p>
<p className={fr.cx("fr-card__desc")}>
<a
{...routes.adminAgencyDetail({ agencyId: agency.id }).link}
target="_blank"
>
Voir les détails de l'agence
</a>
</p>
</div>
<div className={fr.cx("fr-card__footer")}>
<ButtonsGroup
alignment="center"
inlineLayoutWhen="always"
buttonsSize="small"
buttons={[
{
type: "button",
priority: "primary",
id: `${domElementIds.admin.agencyTab.registerIcUserToAgencyButton}-${agency.id}-${selectedUser.id}`,
onClick: () => {
setModalProps({
title: "Rattacher cet utilisateur",
mode: "register",
});
setSelectedAgency(agency);
openIcUserRegistrationToAgencyModal();
},
{
type: "button",
priority: "secondary",
onClick: () => {
setModalProps({
title: "Refuser le rattachement",
mode: "reject",
});
setSelectedAgency(agency);
openIcUserRegistrationToAgencyModal();
},
children: "Refuser",
children: "Valider",
},
{
type: "button",
priority: "secondary",
onClick: () => {
setModalProps({
title: "Refuser le rattachement",
mode: "reject",
});
setSelectedAgency(agency);
openIcUserRegistrationToAgencyModal();
},
]}
/>
</div>
children: "Refuser",
},
]}
/>
</div>
</div>
</div>
);
}
</div>
);

export const IcUserAgenciesToReview = ({
agenciesNeedingReviewForUser,
selectedUser,
}: IcUserAgenciesToReviewProps) => {
const dispatch = useDispatch();
const [selectedAgency, setSelectedAgency] =
useState<AgencyDtoWithoutEmails>();
useState<AgencyDtoForAgencyUsersAndAdmins>();
const [modalProps, setModalProps] =
useState<IcUserAgenciesToReviewModalProps | null>(null);

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
import { fr } from "@codegouvfr/react-dsfr";
import Table from "@codegouvfr/react-dsfr/Table";
import { ReactNode } from "react";
import { AgencyRight } from "shared";
import { agencyRoleToDisplay } from "../AgencyUsers";
import { AgencyLineAdminEmails } from "./agency-line/AgencyLineAdminEmails";
import { AgencyLineAgencyName } from "./agency-line/AgencyLineAgencyName";
import { AgencyLineCaracteristics } from "./agency-line/AgencyLineCaracteristics";
import { AgencyLineRightsCTAs } from "./agency-line/AgencyLineRightsCTAs";

export const ActiveAgencyRightsTable = ({
agenciesWithoutToReviewRights,
onUpdateClicked,
isBackofficeAdmin,
}: {
agenciesWithoutToReviewRights: AgencyRight[];
onUpdateClicked: (agencyRight: AgencyRight) => void;
isBackofficeAdmin?: boolean;
}) => (
<>
<h2 className={fr.cx("fr-h4")}>
Organismes rattachés au profil ({agenciesWithoutToReviewRights.length}{" "}
{agenciesWithoutToReviewRights.length === 1 ? "agence" : "agences"})
</h2>

<Table
headers={[
"Organisme",
"Caractéristiques de l'agence",
"Administrateurs",
"Roles",
"Reçoit les notifications",
"Actions",
]}
data={agenciesWithoutToReviewRights
.sort((a, b) => a.agency.name.localeCompare(b.agency.name))
.map(makeAgencyRightLine(onUpdateClicked, isBackofficeAdmin))}
/>
</>
);

const makeAgencyRightLine =
(
onUpdateClicked: (agencyRight: AgencyRight) => void,
isBackofficeAdmin?: boolean,
) =>
(agencyRight: AgencyRight): ReactNode[] => [
AgencyLineAgencyName({ agencyRight }),
AgencyLineCaracteristics({ agencyRight }),
AgencyLineAdminEmails({ agencyRight }),
agencyRight.roles.map((role) => agencyRoleToDisplay[role].label).join(", "),
agencyRight.isNotifiedByEmail ? "Oui" : "Non",
AgencyLineRightsCTAs({
agencyRight,
onUpdateClicked,
isBackofficeAdmin,
}),
];
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
import { createModal } from "@codegouvfr/react-dsfr/Modal";
import { useState } from "react";
import { createPortal } from "react-dom";
import { AgencyRight, User, UserParamsForAgency, domElementIds } from "shared";
import { Feedback } from "../../feedback/Feedback";
import { AgencyUserModificationForm } from "../AgencyUserModificationForm";
import { ActiveAgencyRightsTable } from "./ActiveAgencyRightsTable";
import { OnGoingAgencyRightsTable } from "./OnGoingAgencyRightsTable";

const manageUserModal = createModal({
isOpenedByDefault: false,
id: domElementIds.admin.agencyTab.editAgencyManageUserModal,
});

export const AgenciesTablesSection = ({
user,
agencyRights,
isBackofficeAdmin,
onUserUpdateRequested,
}: {
user: User;
agencyRights: AgencyRight[];
isBackofficeAdmin?: boolean;
onUserUpdateRequested: (userParamsForAgency: UserParamsForAgency) => void;
}) => {
if (!agencyRights.length)
return <p>Cet utilisateur n'est lié à aucune agence</p>;

const [selectedAgencyRight, setSelectedAgencyRight] =
useState<AgencyRight | null>(null);

const onUpdateClicked = (agencyRight: AgencyRight) => {
setSelectedAgencyRight(agencyRight);
manageUserModal.open();
};

const toReviewAgencyRights = agencyRights.filter((agencyRight) =>
agencyRight.roles.includes("to-review"),
);
const activeAgencyRights = agencyRights.filter(
(agencyRight) => !agencyRight.roles.includes("to-review"),
);

return (
<>
<Feedback topic="user" />
{toReviewAgencyRights.length > 0 && (
<OnGoingAgencyRightsTable
agenciesWithToReviewRights={toReviewAgencyRights}
/>
)}
{activeAgencyRights.length > 0 && (
<ActiveAgencyRightsTable
agenciesWithoutToReviewRights={activeAgencyRights}
onUpdateClicked={onUpdateClicked}
isBackofficeAdmin={isBackofficeAdmin}
/>
)}
{createPortal(
<manageUserModal.Component title={"Modifier le rôle de l'utilisateur"}>
{selectedAgencyRight && (
<AgencyUserModificationForm
agencyUser={{
agencyId: selectedAgencyRight.agency.id,
userId: user.id,
roles: selectedAgencyRight.roles,
email: user.email,
isNotifiedByEmail: selectedAgencyRight.isNotifiedByEmail,
isIcUser: !!user.externalId,
}}
closeModal={() => manageUserModal.close()}
agencyHasRefersTo={!!selectedAgencyRight.agency.refersToAgencyId}
isEmailDisabled={true}
areRolesDisabled={
!isBackofficeAdmin &&
!selectedAgencyRight.roles.includes("agency-admin")
}
onSubmit={onUserUpdateRequested}
routeName="myProfile"
/>
)}
</manageUserModal.Component>,
document.body,
)}
</>
);
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import { fr } from "@codegouvfr/react-dsfr";
import Table from "@codegouvfr/react-dsfr/Table";
import { ReactNode } from "react";
import { AgencyRight } from "shared";
import { AgencyLineAdminEmails } from "./agency-line/AgencyLineAdminEmails";
import { AgencyLineAgencyName } from "./agency-line/AgencyLineAgencyName";
import { AgencyLineCaracteristics } from "./agency-line/AgencyLineCaracteristics";

export const OnGoingAgencyRightsTable = ({
agenciesWithToReviewRights,
}: { agenciesWithToReviewRights: AgencyRight[] }) => (
<>
<h2 className={fr.cx("fr-h4")}>
Demandes d'accès en cours ({agenciesWithToReviewRights.length}{" "}
{agenciesWithToReviewRights.length === 1 ? "agence" : "agences"})
</h2>
<Table
headers={["Organisme", "Caractéristiques de l'agence", "Administrateurs"]}
data={agenciesWithToReviewRights
.sort((a, b) => a.agency.name.localeCompare(b.agency.name))
.map(makeAgencyWithToReviewRightLine())}
/>
</>
);

const makeAgencyWithToReviewRightLine =
() =>
(agencyRight: AgencyRight): ReactNode[] => [
AgencyLineAgencyName({ agencyRight }),
AgencyLineCaracteristics({ agencyRight }),
AgencyLineAdminEmails({ agencyRight }),
];
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { fr } from "@codegouvfr/react-dsfr";
import { ReactNode } from "react";
import { AgencyRight } from "shared";

export const AgencyLineAdminEmails = ({
agencyRight,
}: { agencyRight: AgencyRight }): ReactNode => (
<ul className={fr.cx("fr-raw-list")}>
{agencyRight.agency.admins.map((admin) => (
<li>{admin}</li>
))}
</ul>
);
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import { fr } from "@codegouvfr/react-dsfr";
import { ReactNode } from "react";
import { AgencyRight, addressDtoToString } from "shared";
import { routes } from "src/app/routes/routes";

export const AgencyLineAgencyName = ({
agencyRight,
}: { agencyRight: AgencyRight }): ReactNode => (
<div key={agencyRight.agency.id}>
{agencyRight.agency.name}
<span className={fr.cx("fr-hint-text")}>
{addressDtoToString(agencyRight.agency.address)}
</span>

{agencyRight.roles.includes("agency-admin") && (
<a
className={fr.cx(
"fr-link",
"fr-text--sm",
"fr-icon-arrow-right-line",
"fr-link--icon-right",
)}
{...routes.agencyDashboardAgencyDetails({
agencyId: agencyRight.agency.id,
}).link}
>
Voir l'agence
</a>
)}
</div>
);
Loading

0 comments on commit cc7b0b7

Please sign in to comment.