mirror of
https://framagit.org/enfance-libre/statistiques
synced 2025-12-07 13:13:44 +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";
|
} from "./StatutFamille";
|
||||||
import { StatutSocial } from "./StatutSocial";
|
import { StatutSocial } from "./StatutSocial";
|
||||||
import { StatutPenal } from "./StatutPenal";
|
import { StatutPenal } from "./StatutPenal";
|
||||||
|
import { Mission } from "./Mission";
|
||||||
|
|
||||||
export type Famille = Readonly<{
|
export type Famille = Readonly<{
|
||||||
notionId: string;
|
notionId: string;
|
||||||
|
|
@ -34,6 +35,7 @@ export type Famille = Readonly<{
|
||||||
EvenementsApresEL: EvenementFamille[];
|
EvenementsApresEL: EvenementFamille[];
|
||||||
|
|
||||||
DerniereModification: Date;
|
DerniereModification: Date;
|
||||||
|
Missions: Mission[];
|
||||||
}>;
|
}>;
|
||||||
|
|
||||||
export function periodOfResistance(
|
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 familEventsDbId: string = "c4d434b4603c4481a4d445618ecdf999";
|
||||||
export const departementsDbId: string = "787779be614544069f609bf9d2a7cd15";
|
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 { titlePropertyToText } from "../utils/properties/titlePropertyToText";
|
||||||
import { queryAllDbResults } from "../utils/queryAllDbResults";
|
import { queryAllDbResults } from "../utils/queryAllDbResults";
|
||||||
import { richTextPropertyToPlainText } from "../utils/text/richTextPropertyToPlainText";
|
import { richTextPropertyToPlainText } from "../utils/text/richTextPropertyToPlainText";
|
||||||
import { departementsDbId, familEventsDbId } from "./dbIds";
|
import {
|
||||||
|
contactsDbId,
|
||||||
|
departementsDbId,
|
||||||
|
familEventsDbId,
|
||||||
|
missionsDbId,
|
||||||
|
} from "./dbIds";
|
||||||
import {
|
import {
|
||||||
propContexteEntree,
|
propContexteEntree,
|
||||||
familiesDbId,
|
familiesDbId,
|
||||||
|
|
@ -22,6 +27,9 @@ import {
|
||||||
} from "./dbfamilleDesc";
|
} from "./dbfamilleDesc";
|
||||||
import { StatutPenal } from "../../data/StatutPenal";
|
import { StatutPenal } from "../../data/StatutPenal";
|
||||||
import { StatutSocial } from "../../data/StatutSocial";
|
import { StatutSocial } from "../../data/StatutSocial";
|
||||||
|
import { Contact } from "../../data/Contact";
|
||||||
|
import { Mission } from "../../data/Mission";
|
||||||
|
import { relationPropertyToPageIds } from "../utils/properties/relationPropertyToPageIds";
|
||||||
|
|
||||||
type Departement = {
|
type Departement = {
|
||||||
notionId: string;
|
notionId: string;
|
||||||
|
|
@ -42,6 +50,18 @@ export async function fetchFamiliesWithEventsFromNotion(
|
||||||
})
|
})
|
||||||
).filter(isFullPage);
|
).filter(isFullPage);
|
||||||
|
|
||||||
|
const contactPages = (
|
||||||
|
await queryAllDbResults(notionClient, {
|
||||||
|
database_id: contactsDbId,
|
||||||
|
})
|
||||||
|
).filter(isFullPage);
|
||||||
|
|
||||||
|
const missionsPages = (
|
||||||
|
await queryAllDbResults(notionClient, {
|
||||||
|
database_id: missionsDbId,
|
||||||
|
})
|
||||||
|
).filter(isFullPage);
|
||||||
|
|
||||||
const departementPages = (
|
const departementPages = (
|
||||||
await queryAllDbResults(notionClient, {
|
await queryAllDbResults(notionClient, {
|
||||||
database_id: departementsDbId,
|
database_id: departementsDbId,
|
||||||
|
|
@ -53,13 +73,35 @@ export async function fetchFamiliesWithEventsFromNotion(
|
||||||
name: titlePropertyToText(page.properties, "Nom"),
|
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) => {
|
const familyEvents = eventPages.map((pageObjectResponse) => {
|
||||||
return buildFamilyEvent(pageObjectResponse);
|
return buildFamilyEvent(pageObjectResponse);
|
||||||
});
|
});
|
||||||
|
|
||||||
const familles: Famille[] = await Promise.all(
|
const familles: Famille[] = await Promise.all(
|
||||||
familyPages.map((pageObjectResponse) => {
|
familyPages.map((pageObjectResponse) => {
|
||||||
return buildFamily(pageObjectResponse, familyEvents, departements);
|
return buildFamily(
|
||||||
|
pageObjectResponse,
|
||||||
|
familyEvents,
|
||||||
|
departements,
|
||||||
|
contacts
|
||||||
|
);
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
return familles;
|
return familles;
|
||||||
|
|
@ -85,7 +127,8 @@ function buildFamilyEvent(page: PageObjectResponse): EvenementFamille {
|
||||||
function buildFamily(
|
function buildFamily(
|
||||||
page: PageObjectResponse,
|
page: PageObjectResponse,
|
||||||
familyEvents: EvenementFamille[],
|
familyEvents: EvenementFamille[],
|
||||||
departements: Departement[]
|
departements: Departement[],
|
||||||
|
contacts: Contact[]
|
||||||
): Famille {
|
): Famille {
|
||||||
const pageProperties = page.properties;
|
const pageProperties = page.properties;
|
||||||
|
|
||||||
|
|
@ -93,6 +136,7 @@ function buildFamily(
|
||||||
const departement = departementId
|
const departement = departementId
|
||||||
? departements.find((d) => d.notionId === departementId)
|
? departements.find((d) => d.notionId === departementId)
|
||||||
: null;
|
: null;
|
||||||
|
|
||||||
const family: Famille = {
|
const family: Famille = {
|
||||||
notionId: page.id,
|
notionId: page.id,
|
||||||
Titre: titlePropertyToText(pageProperties, ""),
|
Titre: titlePropertyToText(pageProperties, ""),
|
||||||
|
|
@ -115,6 +159,9 @@ function buildFamily(
|
||||||
)!,
|
)!,
|
||||||
Penal: statusPropertyToText(pageProperties, propPenal) as StatutPenal,
|
Penal: statusPropertyToText(pageProperties, propPenal) as StatutPenal,
|
||||||
Social: statusPropertyToText(pageProperties, propSocial) as StatutSocial,
|
Social: statusPropertyToText(pageProperties, propSocial) as StatutSocial,
|
||||||
|
Missions: contacts
|
||||||
|
.filter((c) => c.notionIdFamille === page.id)
|
||||||
|
.flatMap((c) => c.Missions),
|
||||||
};
|
};
|
||||||
return family;
|
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(
|
export async function queryAllDbResults(
|
||||||
notion: Client,
|
notion: Client,
|
||||||
dbQuery: QueryDatabaseParameters,
|
dbQuery: QueryDatabaseParameters,
|
||||||
{ cache: cacheConfig }: QueryExtraOptions = { cache: false }
|
{ cache: cacheConfig }: QueryExtraOptions = { cache: { ttl: 3600 * 1000 } }
|
||||||
): Promise<QueryDatabaseResponse["results"]> {
|
): Promise<QueryDatabaseResponse["results"]> {
|
||||||
const queryHash = createHash("sha1")
|
const queryHash = createHash("sha1")
|
||||||
.update(JSON.stringify(dbQuery))
|
.update(JSON.stringify(dbQuery))
|
||||||
|
|
|
||||||
|
|
@ -41,6 +41,9 @@ export const statsGeneralesDesc = {
|
||||||
label: "Nb familles actuellement résistante par département",
|
label: "Nb familles actuellement résistante par département",
|
||||||
type: "multi",
|
type: "multi",
|
||||||
},
|
},
|
||||||
|
nbFamillesResistantesAssumantDesMissionsEL: {
|
||||||
|
label: "Nb familles actuellement résistante assumant des missions EL",
|
||||||
|
},
|
||||||
},
|
},
|
||||||
} as const;
|
} as const;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -24,6 +24,10 @@ export function computeStatsGenerales(familles: Famille[]): StatsGenerales {
|
||||||
const dureesResistances = famillesResistantesOrEx.map(
|
const dureesResistances = famillesResistantesOrEx.map(
|
||||||
(f) => dureeResistanceInDays(f)!
|
(f) => dureeResistanceInDays(f)!
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const famillesResistantesAssumantDesMissionsEL = famillesResistantes.filter(
|
||||||
|
(f) => f.Missions.length > 0
|
||||||
|
);
|
||||||
const statsGenerales: StatsGenerales = {
|
const statsGenerales: StatsGenerales = {
|
||||||
nbFamillesResistantesActuelles:
|
nbFamillesResistantesActuelles:
|
||||||
nbFamillesAvecPagesLiees(famillesResistantes),
|
nbFamillesAvecPagesLiees(famillesResistantes),
|
||||||
|
|
@ -49,6 +53,8 @@ export function computeStatsGenerales(familles: Famille[]): StatsGenerales {
|
||||||
isIntegrationEnCours(f.Statut)
|
isIntegrationEnCours(f.Statut)
|
||||||
).length,
|
).length,
|
||||||
nbFicheFamillesParStatut: sortByKey(countBy(familles, (f) => f.Statut)),
|
nbFicheFamillesParStatut: sortByKey(countBy(familles, (f) => f.Statut)),
|
||||||
|
nbFamillesResistantesAssumantDesMissionsEL:
|
||||||
|
famillesResistantesAssumantDesMissionsEL.length,
|
||||||
};
|
};
|
||||||
return statsGenerales;
|
return statsGenerales;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue