Skip to content

Commit

Permalink
added role to connected user data, filtered establishment on Establis…
Browse files Browse the repository at this point in the history
…hmentDashboardPage if user is not establishment-admin
  • Loading branch information
enguerranws committed Jan 23, 2025
1 parent 6ddf47e commit 2bd1356
Show file tree
Hide file tree
Showing 10 changed files with 97 additions and 44 deletions.
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Phone, UserId } from "shared";
import { EstablishmentRole, Phone, UserId } from "shared";
import { EstablishmentEntity } from "./EstablishmentEntity";
import { OfferEntity } from "./OfferEntity";

Expand All @@ -12,7 +12,6 @@ export type WithEstablishmentAggregate = {
establishmentAggregate: EstablishmentAggregate;
};

type EstablishmentRole = "establishment-admin" | "establishment-contact";
type GenericEstablishmentUserRight<Role extends EstablishmentRole> = {
userId: UserId;
role: Role;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import {
EstablishmentDashboards,
InclusionConnectedUser,
WithDashboards,
WithEstablismentsSiretAndName,
WithEstablishmentData,
WithOptionalUserId,
agencyRoleIsNotToReview,
errors,
Expand Down Expand Up @@ -85,20 +85,32 @@ export class GetInclusionConnectedUser extends TransactionalUseCase<
async #withEstablishments(
uow: UnitOfWork,
user: InclusionConnectedUser,
): Promise<{ establishments?: WithEstablismentsSiretAndName[] }> {
): Promise<{ establishments?: WithEstablishmentData[] }> {
const establishmentAggregates =
await uow.establishmentAggregateRepository.getEstablishmentAggregatesByFilters(
{
userId: user.id,
},
);

const establishments = establishmentAggregates.map(({ establishment }) => ({
siret: establishment.siret,
businessName: establishment.customizedName
? establishment.customizedName
: establishment.name,
}));
const establishments = establishmentAggregates.map(
({ establishment, userRights }) => {
const userRight = userRights.find(
(userRight) => userRight.userId === user.id,
);
if (!userRight) {
throw errors.establishment.noUserRights({
siret: establishment.siret,
});
}
return {
siret: establishment.siret,
businessName: establishment.customizedName
? establishment.customizedName
: establishment.name,
role: userRight.role,
};
},
);
return establishments.length ? { establishments } : {};
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,14 @@ describe("GetUserAgencyDashboardUrl", () => {
.withFirstName("John")
.withIsAdmin(false)
.withEstablishments(undefined);
const anotherUserBuilder = new InclusionConnectedUserBuilder()
.withId("another-user-id")
.withFirstName("Jane")
.withIsAdmin(false)
.withEstablishments(undefined);
const icNotAdmin = notAdminBuilder.build();
const notAdmin = notAdminBuilder.buildUser();
const anotherUser = anotherUserBuilder.build();

const agencyWithoutCounsellorAndValidatorBuilder = new AgencyDtoBuilder();

Expand Down Expand Up @@ -438,23 +444,40 @@ describe("GetUserAgencyDashboardUrl", () => {
it("retrieve establishments when IC user is establishement rep in at least one establishment", async () => {
uow.userRepository.users = [notAdmin];

const establishmentUserRights: EstablishmentUserRight[] = [
{
job: "Chef",
role: "establishment-admin",
userId: notAdmin.id,
phone: "+33600000000",
},
];
const establishmentUserRightsForFirstEstablishment: EstablishmentUserRight[] =
[
{
job: "Chef",
role: "establishment-admin",
userId: notAdmin.id,
phone: "+33600000000",
},
{
job: "Dev",
role: "establishment-admin",
userId: anotherUser.id,
phone: "+33600000001",
},
];

const establishmentUserRightsForSecondEstablishment: EstablishmentUserRight[] =
[
{
job: "Chef",
role: "establishment-contact",
userId: notAdmin.id,
phone: "+33600000000",
},
];

const establishmentAggregate1 = new EstablishmentAggregateBuilder()
.withEstablishmentSiret("89114285300012")
.withUserRights(establishmentUserRights)
.withUserRights(establishmentUserRightsForFirstEstablishment)
.build();

const establishmentAggregate2 = new EstablishmentAggregateBuilder()
.withEstablishmentSiret("89114285300013")
.withUserRights(establishmentUserRights)
.withUserRights(establishmentUserRightsForSecondEstablishment)
.build();

uow.establishmentAggregateRepository.establishmentAggregates = [
Expand All @@ -471,10 +494,12 @@ describe("GetUserAgencyDashboardUrl", () => {
{
siret: establishmentAggregate1.establishment.siret,
businessName: establishmentAggregate1.establishment.name,
role: "establishment-admin",
},
{
siret: establishmentAggregate2.establishment.siret,
businessName: establishmentAggregate2.establishment.name,
role: "establishment-contact",
},
]);
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import Tabs from "@codegouvfr/react-dsfr/Tabs";
import { ReactJSXElement } from "@emotion/react/types/jsx-namespace";
import React from "react";
import { Loader } from "react-design-system";
import { EstablishmentRole, InclusionConnectedUser } from "shared";
import { ConventionEstablishmentRole, InclusionConnectedUser } from "shared";
import { MetabaseView } from "src/app/components/MetabaseView";
import { SelectConventionFromIdForm } from "src/app/components/SelectConventionFromIdForm";
import { useAppSelector } from "src/app/hooks/reduxHooks";
Expand All @@ -20,7 +20,7 @@ import { P, match } from "ts-pattern";
import { Route } from "type-route";
import { ManageDiscussionFormSection } from "./ManageDiscussionFormSection";

const currentUserRoleToDisplay = (role: EstablishmentRole) =>
const currentUserRoleToDisplay = (role: ConventionEstablishmentRole) =>
role === "establishment-representative"
? "responsable d'entreprise"
: "tuteur de l'entreprise";
Expand Down Expand Up @@ -96,7 +96,10 @@ export const EstablishmentDashboardPage = ({
tabId: "fiche-entreprise",
content: (
<ManageEstablishmentsTab
establishments={establishments}
establishments={establishments.filter(
(establishment) =>
establishment.role === "establishment-admin",
)}
route={route}
/>
),
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
import { fr } from "@codegouvfr/react-dsfr";
import Select from "@codegouvfr/react-dsfr/SelectNext";
import React from "react";
import { WithEstablismentsSiretAndName, domElementIds } from "shared";
import { WithEstablishmentData, domElementIds } from "shared";
import { EstablishmentForm } from "src/app/components/forms/establishment/EstablishmentForm";
import { routes } from "src/app/routes/routes";
import { getUrlParameters } from "src/app/utils/url.utils";
import { Route } from "type-route";
type ManageEstablishmentTabProps = {
establishments: WithEstablismentsSiretAndName[];
establishments: WithEstablishmentData[];
route: Route<typeof routes.establishmentDashboard>;
};
export const ManageEstablishmentsTab = ({
Expand Down
4 changes: 2 additions & 2 deletions shared/src/inclusionConnect/inclusionConnect.dto.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import {
InclusionConnectedUser,
User,
} from "../inclusionConnectedAllowed/inclusionConnectedAllowed.dto";
import { EstablishmentRole, Role } from "../role/role.dto";
import { ConventionEstablishmentRole, Role } from "../role/role.dto";
import { allowedStartInclusionConnectLoginPages } from "../routes/routes";
import { ExcludeFromExisting, ExtractFromExisting } from "../utils";

Expand All @@ -32,7 +32,7 @@ export type AuthenticatedUserQueryParams = {
} & Pick<User, "email" | "firstName" | "lastName">;

type InclusionConnectConventionManageAllowedRole =
| EstablishmentRole
| ConventionEstablishmentRole
| ExtractFromExisting<Role, "back-office">
| ExcludeFromExisting<AgencyRole, "to-review">;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import {
User,
UserId,
UserWithAdminRights,
WithEstablismentsSiretAndName,
WithEstablishmentData,
} from "./inclusionConnectedAllowed.dto";

const defaultUser: User = {
Expand Down Expand Up @@ -126,9 +126,7 @@ export class InclusionConnectedUserBuilder
return new InclusionConnectedUserBuilder({ ...this.#dto, agencyRights });
}

withEstablishments(
establishments: WithEstablismentsSiretAndName[] | undefined,
) {
withEstablishments(establishments: WithEstablishmentData[] | undefined) {
return new InclusionConnectedUserBuilder({ ...this.#dto, establishments });
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,10 @@ import {
import { DiscussionId } from "../discussion/discussion.dto";
import { Email } from "../email/email.dto";
import { WithSourcePage } from "../inclusionConnect/inclusionConnect.dto";
import { EstablishmentRole } from "../role/role.dto";
import {
ConventionEstablishmentRole,
EstablishmentRole,
} from "../role/role.dto";
import { SiretDto } from "../siret/siret";
import { Flavor } from "../typeFlavors";
import { DateTimeIsoString } from "../utils/date";
Expand Down Expand Up @@ -48,18 +51,19 @@ type WithAgencyRights = {
agencyRights: AgencyRight[];
};

export type WithEstablismentsSiretAndName = {
export type WithEstablishmentData = {
siret: SiretDto;
businessName: string;
role: EstablishmentRole;
};

export type WithEstablishments = {
establishments?: WithEstablismentsSiretAndName[];
establishments?: WithEstablishmentData[];
};

export type ConventionsEstablishmentDashboard = {
url: AbsoluteUrl;
role: EstablishmentRole;
role: ConventionEstablishmentRole;
};
export type WithDiscussionId = {
discussionId: DiscussionId;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,10 @@ import { agencyDtoForAgencyUsersAndAdminsSchema } from "../agency/agency.schema"
import { discussionIdSchema } from "../discussion/discussion.schema";
import { emailSchema } from "../email/email.schema";
import { IdToken } from "../inclusionConnect/inclusionConnect.dto";
import { establishmentsRoles } from "../role/role.dto";
import {
conventionEstablishmentsRoles,
establishmentsRoles,
} from "../role/role.dto";
import { dateTimeIsoStringSchema } from "../schedule/Schedule.schema";
import { siretSchema } from "../siret/siret.schema";
import { zStringCanBeEmpty, zStringMinLength1 } from "../zodUtils";
Expand All @@ -17,7 +20,7 @@ import {
WithAgencyDashboards,
WithDiscussionId,
WithEstablishmentDashboards,
WithEstablismentsSiretAndName,
WithEstablishmentData,
WithOptionalUserId,
allAgencyRoles,
} from "./inclusionConnectedAllowed.dto";
Expand All @@ -40,11 +43,13 @@ export const withOptionalUserIdSchema: z.Schema<WithOptionalUserId> = z.object({
userId: userIdSchema.optional(),
});

const withEstablishmentSiretAndName: z.Schema<WithEstablismentsSiretAndName> =
z.object({
const withEstablishmentSiretAndName: z.Schema<WithEstablishmentData> = z.object(
{
siret: siretSchema,
businessName: zStringMinLength1,
});
role: z.enum(establishmentsRoles),
},
);

const dashboardsSchema: z.Schema<
WithAgencyDashboards & WithEstablishmentDashboards
Expand All @@ -53,7 +58,7 @@ const dashboardsSchema: z.Schema<
conventions: z
.object({
url: absoluteUrlSchema,
role: z.enum(establishmentsRoles),
role: z.enum(conventionEstablishmentsRoles),
})
.optional(),
discussions: absoluteUrlSchema.optional(),
Expand Down
11 changes: 9 additions & 2 deletions shared/src/role/role.dto.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,9 @@ export type Role = (typeof allRoles)[number];
export type SignatoryRole = (typeof allSignatoryRoles)[number];
export type AgencyModifierRole = (typeof agencyModifierRoles)[number];
export type ModifierRole = (typeof allModifierRoles)[number];
export type EstablishmentRole = (typeof establishmentsRoles)[number];
export type AssessmentRole = (typeof assessmentRoles)[number];
export type ConventionEstablishmentRole =
(typeof conventionEstablishmentsRoles)[number];
export const allRoles = [
"beneficiary",
"beneficiary-representative",
Expand All @@ -29,7 +30,7 @@ export const allSignatoryRoles = [
Required<Signatories>[keyof Required<Signatories>]["role"]
>;

export const establishmentsRoles = [
export const conventionEstablishmentsRoles = [
"establishment-representative",
"establishment-tutor",
] as const;
Expand All @@ -53,3 +54,9 @@ export const getRequesterRole = (roles: Role[]): Role => {
if (roles.includes("counsellor")) return "counsellor";
return roles[0];
};

export const establishmentsRoles = [
"establishment-admin",
"establishment-contact",
] as const;
export type EstablishmentRole = (typeof establishmentsRoles)[number];

0 comments on commit 2bd1356

Please sign in to comment.