mirror of
https://framagit.org/enfance-libre/statistiques
synced 2025-03-13 19:05:02 +00:00
feat: ajout nbFamillesResistantesAssumantDesMissionsEL
This commit is contained in:
parent
3d6b9a873e
commit
a64557c5b4
9 changed files with 93 additions and 4 deletions
7
src/data/Contact.ts
Normal file
7
src/data/Contact.ts
Normal file
|
@ -0,0 +1,7 @@
|
|||
import { Mission } from "./Mission";
|
||||
|
||||
export type Contact = {
|
||||
notionId: string;
|
||||
notionIdFamille: string;
|
||||
Missions: Mission[];
|
||||
};
|
|
@ -11,6 +11,7 @@ import {
|
|||
} from "./StatutFamille";
|
||||
import { StatutSocial } from "./StatutSocial";
|
||||
import { StatutPenal } from "./StatutPenal";
|
||||
import { Mission } from "./Mission";
|
||||
|
||||
export type Famille = Readonly<{
|
||||
notionId: string;
|
||||
|
@ -34,6 +35,7 @@ export type Famille = Readonly<{
|
|||
EvenementsApresEL: EvenementFamille[];
|
||||
|
||||
DerniereModification: Date;
|
||||
Missions: Mission[];
|
||||
}>;
|
||||
|
||||
export function periodOfResistance(
|
||||
|
|
6
src/data/Mission.ts
Normal file
6
src/data/Mission.ts
Normal file
|
@ -0,0 +1,6 @@
|
|||
export type Mission = {
|
||||
notionId: string;
|
||||
Nom: string;
|
||||
Equipe: string;
|
||||
ContactsNotionIds: string[];
|
||||
};
|
|
@ -1,2 +1,5 @@
|
|||
export const familEventsDbId: string = "c4d434b4603c4481a4d445618ecdf999";
|
||||
export const departementsDbId: string = "787779be614544069f609bf9d2a7cd15";
|
||||
export const contactsDbId: string = "be112427dd314c14b93dfd027323c908";
|
||||
|
||||
export const missionsDbId: string = "fa2ab021a5dc4e239b7e7201ae579162";
|
||||
|
|
|
@ -12,7 +12,12 @@ import { statusPropertyToText } from "../utils/properties/statusPropertyToText";
|
|||
import { titlePropertyToText } from "../utils/properties/titlePropertyToText";
|
||||
import { queryAllDbResults } from "../utils/queryAllDbResults";
|
||||
import { richTextPropertyToPlainText } from "../utils/text/richTextPropertyToPlainText";
|
||||
import { departementsDbId, familEventsDbId } from "./dbIds";
|
||||
import {
|
||||
contactsDbId,
|
||||
departementsDbId,
|
||||
familEventsDbId,
|
||||
missionsDbId,
|
||||
} from "./dbIds";
|
||||
import {
|
||||
propContexteEntree,
|
||||
familiesDbId,
|
||||
|
@ -22,6 +27,9 @@ import {
|
|||
} from "./dbfamilleDesc";
|
||||
import { StatutPenal } from "../../data/StatutPenal";
|
||||
import { StatutSocial } from "../../data/StatutSocial";
|
||||
import { Contact } from "../../data/Contact";
|
||||
import { Mission } from "../../data/Mission";
|
||||
import { relationPropertyToPageIds } from "../utils/properties/relationPropertyToPageIds";
|
||||
|
||||
type Departement = {
|
||||
notionId: string;
|
||||
|
@ -42,6 +50,18 @@ export async function fetchFamiliesWithEventsFromNotion(
|
|||
})
|
||||
).filter(isFullPage);
|
||||
|
||||
const contactPages = (
|
||||
await queryAllDbResults(notionClient, {
|
||||
database_id: contactsDbId,
|
||||
})
|
||||
).filter(isFullPage);
|
||||
|
||||
const missionsPages = (
|
||||
await queryAllDbResults(notionClient, {
|
||||
database_id: missionsDbId,
|
||||
})
|
||||
).filter(isFullPage);
|
||||
|
||||
const departementPages = (
|
||||
await queryAllDbResults(notionClient, {
|
||||
database_id: departementsDbId,
|
||||
|
@ -53,13 +73,35 @@ export async function fetchFamiliesWithEventsFromNotion(
|
|||
name: titlePropertyToText(page.properties, "Nom"),
|
||||
}));
|
||||
|
||||
const missions: Mission[] = missionsPages.map((page) => ({
|
||||
notionId: page.id,
|
||||
Nom: titlePropertyToText(page.properties, "Nom"),
|
||||
Equipe: selectPropertyToText(page.properties, "Équipe")!,
|
||||
ContactsNotionIds: relationPropertyToPageIds(
|
||||
page.properties,
|
||||
"📔 Contacts"
|
||||
),
|
||||
}));
|
||||
|
||||
const contacts: Contact[] = contactPages.map((page) => ({
|
||||
notionId: page.id,
|
||||
name: titlePropertyToText(page.properties, "Nom"),
|
||||
notionIdFamille: relationPropertyToPageId(page.properties, "Famille")!,
|
||||
Missions: missions.filter((m) => m.ContactsNotionIds.includes(page.id)),
|
||||
}));
|
||||
|
||||
const familyEvents = eventPages.map((pageObjectResponse) => {
|
||||
return buildFamilyEvent(pageObjectResponse);
|
||||
});
|
||||
|
||||
const familles: Famille[] = await Promise.all(
|
||||
familyPages.map((pageObjectResponse) => {
|
||||
return buildFamily(pageObjectResponse, familyEvents, departements);
|
||||
return buildFamily(
|
||||
pageObjectResponse,
|
||||
familyEvents,
|
||||
departements,
|
||||
contacts
|
||||
);
|
||||
})
|
||||
);
|
||||
return familles;
|
||||
|
@ -85,7 +127,8 @@ function buildFamilyEvent(page: PageObjectResponse): EvenementFamille {
|
|||
function buildFamily(
|
||||
page: PageObjectResponse,
|
||||
familyEvents: EvenementFamille[],
|
||||
departements: Departement[]
|
||||
departements: Departement[],
|
||||
contacts: Contact[]
|
||||
): Famille {
|
||||
const pageProperties = page.properties;
|
||||
|
||||
|
@ -93,6 +136,7 @@ function buildFamily(
|
|||
const departement = departementId
|
||||
? departements.find((d) => d.notionId === departementId)
|
||||
: null;
|
||||
|
||||
const family: Famille = {
|
||||
notionId: page.id,
|
||||
Titre: titlePropertyToText(pageProperties, ""),
|
||||
|
@ -115,6 +159,9 @@ function buildFamily(
|
|||
)!,
|
||||
Penal: statusPropertyToText(pageProperties, propPenal) as StatutPenal,
|
||||
Social: statusPropertyToText(pageProperties, propSocial) as StatutSocial,
|
||||
Missions: contacts
|
||||
.filter((c) => c.notionIdFamille === page.id)
|
||||
.flatMap((c) => c.Missions),
|
||||
};
|
||||
return family;
|
||||
}
|
||||
|
|
15
src/notion/utils/properties/relationPropertyToPageIds.ts
Normal file
15
src/notion/utils/properties/relationPropertyToPageIds.ts
Normal file
|
@ -0,0 +1,15 @@
|
|||
import { PageProperties } from "../types/PageProperties";
|
||||
import { extractPagePropertyValue } from "./extractPagePropertyValue";
|
||||
|
||||
export function relationPropertyToPageIds(
|
||||
pageProperties: PageProperties,
|
||||
propName: string
|
||||
): string[] {
|
||||
const propValue = extractPagePropertyValue(pageProperties, propName);
|
||||
if (propValue.type !== "relation") {
|
||||
throw new Error(
|
||||
`Property ${propName} was expected to have type "relation" but got "${propValue.type}".`
|
||||
);
|
||||
}
|
||||
return propValue.relation.map((v) => v.id);
|
||||
}
|
|
@ -22,7 +22,7 @@ type CacheConfig =
|
|||
export async function queryAllDbResults(
|
||||
notion: Client,
|
||||
dbQuery: QueryDatabaseParameters,
|
||||
{ cache: cacheConfig }: QueryExtraOptions = { cache: false }
|
||||
{ cache: cacheConfig }: QueryExtraOptions = { cache: { ttl: 3600 * 1000 } }
|
||||
): Promise<QueryDatabaseResponse["results"]> {
|
||||
const queryHash = createHash("sha1")
|
||||
.update(JSON.stringify(dbQuery))
|
||||
|
|
|
@ -41,6 +41,9 @@ export const statsGeneralesDesc = {
|
|||
label: "Nb familles actuellement résistante par département",
|
||||
type: "multi",
|
||||
},
|
||||
nbFamillesResistantesAssumantDesMissionsEL: {
|
||||
label: "Nb familles actuellement résistante assumant des missions EL",
|
||||
},
|
||||
},
|
||||
} as const;
|
||||
|
||||
|
|
|
@ -24,6 +24,10 @@ export function computeStatsGenerales(familles: Famille[]): StatsGenerales {
|
|||
const dureesResistances = famillesResistantesOrEx.map(
|
||||
(f) => dureeResistanceInDays(f)!
|
||||
);
|
||||
|
||||
const famillesResistantesAssumantDesMissionsEL = famillesResistantes.filter(
|
||||
(f) => f.Missions.length > 0
|
||||
);
|
||||
const statsGenerales: StatsGenerales = {
|
||||
nbFamillesResistantesActuelles:
|
||||
nbFamillesAvecPagesLiees(famillesResistantes),
|
||||
|
@ -49,6 +53,8 @@ export function computeStatsGenerales(familles: Famille[]): StatsGenerales {
|
|||
isIntegrationEnCours(f.Statut)
|
||||
).length,
|
||||
nbFicheFamillesParStatut: sortByKey(countBy(familles, (f) => f.Statut)),
|
||||
nbFamillesResistantesAssumantDesMissionsEL:
|
||||
famillesResistantesAssumantDesMissionsEL.length,
|
||||
};
|
||||
return statsGenerales;
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue