Skip to content

Commit

Permalink
Move Data fetching to Prisma (#53)
Browse files Browse the repository at this point in the history
* Move depute main page fetching to prisma

* move deputes amendements to prisma

* start votes

* migrate votse

* Use nex prisma definition

* move commission to server

* Finish to migrate the Dossier main page to prisma

* remove console.log

* Use prisma for debates

* Move to prisma Dossier/amendements

* Move deputes list to prisma

* move dossiers page to prisma

* delete unused files

* remove unused functions

* Finish prisma migration
  • Loading branch information
alexfauquette authored Aug 13, 2024
1 parent b38ffa9 commit b6de5bd
Show file tree
Hide file tree
Showing 84 changed files with 8,876 additions and 117,426 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ yarn-error.log*

# local env files
.env*.local
.env

# vercel
.vercel
Expand Down
118 changes: 118 additions & 0 deletions app/[legislature]/dossier/[id]/AdditionalInfoCard.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
import * as React from "react";

import Accordion from "@mui/material/Accordion";
import AccordionSummary from "@mui/material/AccordionSummary";
import AccordionDetails from "@mui/material/AccordionDetails";
import Typography from "@mui/material/Typography";
import Stack from "@mui/material/Stack";
import MuiLink from "@mui/material/Link";
import InfoIcon from "@/icons/InfoIcon";
import Link from "next/link";
import Signataires from "../../../../components/folders/Signataires";
import { prisma } from "@/prisma";

async function getDocumentsUnCached(ids: string[]) {
if (ids.length === 0) {
return [];
}

try {
return prisma.document.findMany({
where: { uid: { in: ids } },
include: {
_count: {
// TODO: Check with HEnry if the naming `amendements` make sens for amendements
select: { amendementsCommission: true, amendements: true },
},
coSignataires: {
include: { acteurRef: { include: { groupeParlementaire: true } } },
},
},
});
} catch (error) {
console.error("Error fetching commission:", error);
throw error;
}
}

const getDocuments = React.cache(getDocumentsUnCached);

export const AdditionalInfoCard = async (props: {
documentIds: string[];
legislature: string;
dossierUid: string;
}) => {
const data = await getDocuments(props.documentIds);

const documentsWithAmendements = data.filter(
(document) =>
document._count.amendements + document._count.amendementsCommission > 0
);
return (
<Accordion elevation={0} disableGutters defaultExpanded color="secondary">
<AccordionSummary
aria-controls="additional-info-content"
id="additional-info-header"
>
<Typography>Informations complémentaires</Typography>
</AccordionSummary>
<AccordionDetails>
<Stack direction="column" spacing={2}>
{documentsWithAmendements.length > 0 && (
<React.Fragment>
<Stack direction="row" spacing={0.5} alignItems="center">
<Typography variant="body2" fontWeight="light">
Amendements
</Typography>
<InfoIcon sx={{ fontSize: "14px" }} />
</Stack>
<Stack direction="column" spacing={1}>
{documentsWithAmendements.map(({ uid, titrePrincipalCourt, _count }) => (
<div key={uid}>
<Typography variant="body2" fontWeight="bold">
{_count.amendementsCommission + _count.amendements}{" "}
amendements
</Typography>
<MuiLink
variant="body2"
fontWeight="light"
component={Link}
href={`/${props.legislature}/dossier/${props.dossierUid}/amendement?document=${uid}`}
>
{titrePrincipalCourt}
</MuiLink>
</div>
))}
</Stack>
</React.Fragment>
)}

<Signataires
signataires={data
.flatMap((doc) =>
doc.coSignataires.map((coSign) => coSign.acteurRef)
)
.filter((acteur) => acteur !== null)}
limite={3}
/>

{/* <Stack direction="column" spacing={1}>
<Stack direction="row" spacing={0.5} alignItems="center">
<Typography variant="body2" fontWeight="light">
Orateur (TODO)
</Typography>
<InfoIcon sx={{ fontSize: "14px" }} />
</Stack>
<DeputyPreview />
<DeputyPreview />
<DeputyPreview />
<DeputyPreview />
<Button fullWidth variant="contained" color="secondary">
Tous les orateurs (7)
</Button>
</Stack>*/}
</Stack>
</AccordionDetails>
</Accordion>
);
};
194 changes: 194 additions & 0 deletions app/[legislature]/dossier/[id]/CommissionsCard.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,194 @@
import * as React from "react";

import Accordion from "@mui/material/Accordion";
import AccordionSummary from "@mui/material/AccordionSummary";
import AccordionDetails from "@mui/material/AccordionDetails";
import Typography from "@mui/material/Typography";
import Stack from "@mui/material/Stack";
import InfoIcon from "@/icons/InfoIcon";
import DeputeCard from "../../../../components/folders/DeputeCard";
import { prisma } from "@/prisma";

async function getCommissionsUnCached(ids: string[]) {
if (ids.length === 0) {
return [];
}

try {
return prisma.organe.findMany({
where: { uid: { in: ids } },
});
} catch (error) {
console.error("Error fetching commission:", error);
throw error;
}
}

const getCommissions = React.cache(getCommissionsUnCached);

async function getRapporteursUnCached(ids: string[]) {
if (ids.length === 0) {
return [];
}

try {
const rapporteurs = await prisma.rapporteur.findMany({
where: { acteLegislatifRefUid: { in: ids } },
include: {
acteurRef: {
include: {
groupeParlementaire: true,
},
},
},
});
return rapporteurs
.filter((nomi) => nomi !== null)
.map((nomi) => nomi.acteurRef);
} catch (error) {
console.error("Error fetching rapporteur:", error);
throw error;
}
}

const getRapporteurs = React.cache(getRapporteursUnCached);

interface CommissionsCardProps {
fondIds: string[];
avisIds: string[];
fondNomination: string[];
avisNomination: string[];
}

export const CommissionsCard = async ({
fondIds,
avisIds,
fondNomination,
avisNomination,
}: CommissionsCardProps) => {
const commissionFond = await getCommissions(fondIds);
const commissionAvis = await getCommissions(avisIds);

const rapporteursFond = (await getRapporteurs(fondNomination)).filter(
(rapporteur) => rapporteur !== null
);
const rapporteursAvis = (await getRapporteurs(avisNomination)).filter(
(rapporteur) => rapporteur !== null
);

if (
(!commissionFond || commissionFond.length === 0) &&
(!commissionAvis || commissionAvis.length === 0) &&
(!rapporteursFond || rapporteursFond.length === 0) &&
(!rapporteursAvis || rapporteursAvis.length === 0)
) {
return null;
}

return (
<Accordion elevation={0} disableGutters defaultExpanded color="secondary">
<AccordionSummary
aria-controls="commission-content"
id="commission-header"
>
<Typography>Commissions</Typography>
</AccordionSummary>
<AccordionDetails>
<Stack direction="column" spacing={2}>
{commissionFond && commissionFond.length > 0 && (
<div>
<Stack direction="row" spacing={0.5} alignItems="center">
<Typography variant="body2" fontWeight="light">
Commission saisie au fond
</Typography>
<InfoIcon sx={{ fontSize: "14px" }} />
</Stack>
{commissionFond.map((commission) => (
<Typography
key={commission.uid}
variant="body2"
fontWeight="bold"
pb={2}
>
{commission.libelleAbrege || commission.libelle}
</Typography>
))}
</div>
)}
{rapporteursFond && rapporteursFond.length > 0 && (
<div>
<Typography variant="body2" fontWeight="light" pb={1}>
Rapporteur
</Typography>
{rapporteursFond.map((acteur) => {
const { prenom, nom, slug, groupeParlementaire } = acteur;

return (
<DeputeCard
key={acteur.uid}
prenom={prenom}
nom={nom}
slug={slug}
group={
groupeParlementaire && {
fullName: "",
shortName: groupeParlementaire?.libelleAbrev,
color: groupeParlementaire?.couleurAssociee,
}
}
/>
);
})}
</div>
)}
{commissionAvis && commissionAvis.length > 0 && (
<div>
<Stack direction="row" spacing={0.5} alignItems="center">
<Typography variant="body2" fontWeight="light">
Comission saisie pour avis
</Typography>
<InfoIcon sx={{ fontSize: "14px" }} />
</Stack>
{commissionAvis.map((commission) => (
<Typography
variant="body2"
fontWeight="bold"
pb={2}
key={commission.uid}
>
{commission.libelleAbrege || commission.libelle}
</Typography>
))}
</div>
)}
{rapporteursAvis && rapporteursAvis.length > 0 && (
<div>
<Typography variant="body2" fontWeight="light" pb={1}>
Rapporteur
</Typography>
{rapporteursAvis.map((acteur) => {
const { prenom, nom, slug, groupeParlementaire } = acteur;

return (
<DeputeCard
key={acteur.uid}
prenom={prenom}
nom={nom}
slug={slug}
group={
groupeParlementaire && {
fullName: "",
shortName: groupeParlementaire?.libelleAbrev,
color: groupeParlementaire?.couleurAssociee,
}
}
/>
);
})}
</div>
)}
</Stack>
</AccordionDetails>
</Accordion>
);
};
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,33 @@ import AccordionDetails from "@mui/material/AccordionDetails";
import LinkIcon from "@/icons/LinkIcon";

import Link from "next/link";
import { DossierData } from "@/repository/database";
import { getDocumentURL } from "@/domain/dataTransform";
import { prisma } from "@/prisma";

async function getDocumentsUnCached(ids: string[]) {
if (ids.length === 0) {
return [];
}

try {
return prisma.document.findMany({
where: { uid: { in: ids } },
});
} catch (error) {
console.error("Error fetching commission:", error);
throw error;
}
}

const getDocuments = React.cache(getDocumentsUnCached);

export const LegislativeDocumentsCard = async ({
documentIds,
}: {
documentIds: string[];
}) => {
const documents = await getDocuments(documentIds);

export const LegislativeDocumentsCard = ({
documents,
}: Pick<DossierData, "documents">) => {
return (
<Accordion elevation={0} disableGutters defaultExpanded color="secondary">
<AccordionSummary
Expand All @@ -26,6 +47,9 @@ export const LegislativeDocumentsCard = ({
<AccordionDetails>
<Stack direction="column" spacing={2}>
{Object.values(documents).map((document) => {
if (!document) {
return null;
}
const url = getDocumentURL(document);

return (
Expand Down
Loading

0 comments on commit b6de5bd

Please sign in to comment.