Init import data

This commit is contained in:
Anthony Janin 2025-08-04 14:31:37 +02:00
parent d596f4212e
commit b0f699f6f0
2 changed files with 448 additions and 217 deletions

View File

@ -0,0 +1,372 @@
import RuleService from './RuleService';
import RuleGroupService from './RuleGroupService';
import RoleService from './RoleService';
import OfficeRoleService from './OfficeRoleService';
/**
* Type pour le callback de progression
*/
export interface ProgressInfo {
/** Progression globale (0-100) */
globalProgress: number;
/** Nom de l'étape en cours */
currentStep: string;
/** Progression de l'étape en cours (0-100) */
stepProgress: number;
/** Description optionnelle de l'action en cours */
description?: string;
}
export default class ImportData {
public static async import(office: any, onProgress?: (info: ProgressInfo) => void): Promise<void> {
// Définir les étapes d'importation dynamiquement
const importSteps = [
{
name: 'Règles',
function: async (progressCallback?: (subProgress: number, description?: string) => void) =>
await this.importRules(progressCallback)
},
{
name: 'Groupes de règles',
function: async (progressCallback?: (subProgress: number, description?: string) => void, prevResults?: any[]) =>
await this.importRuleGroups(prevResults![0], progressCallback)
},
{
name: 'Rôles',
function: async (progressCallback?: (subProgress: number, description?: string) => void) =>
await this.importRoles(progressCallback)
},
{
name: 'Rôles d\'office',
function: async (progressCallback?: (subProgress: number, description?: string) => void, prevResults?: any[]) =>
await this.importOfficeRoles(office, prevResults![1], progressCallback)
}
];
// Calculer la part de progression pour chaque étape
const totalSteps = importSteps.length;
const stepWeight = 100 / totalSteps;
// Appel du callback avec 0% au début
onProgress?.({
globalProgress: 0,
currentStep: 'Initialisation',
stepProgress: 0,
description: 'Début de l\'importation des données'
});
// Exécuter chaque étape d'importation séquentiellement
const results: any[] = [];
for (let i = 0; i < importSteps.length; i++) {
const step = importSteps[i];
if (!step) continue; // S'assurer que l'étape existe
const startProgress = i * stepWeight;
// Créer un callback de progression pour cette étape
const stepProgressCallback = (subProgress: number, description?: string) => {
onProgress?.({
globalProgress: startProgress + (subProgress * stepWeight / 100),
currentStep: step.name,
stepProgress: subProgress,
description
});
};
// Exécuter l'étape et stocker le résultat si nécessaire
const result = await step.function(stepProgressCallback, results);
if (result) {
results.push(result);
}
}
}
private static async importRules(onProgress?: (progress: number, description?: string) => void): Promise<any[]> {
// Constantes de progression - pourraient être paramétrées
const INIT_PROGRESS = 0;
const FETCH_PROGRESS = 30;
const CREATE_START_PROGRESS = FETCH_PROGRESS;
const CREATE_END_PROGRESS = 90;
const FINAL_PROGRESS = 100;
onProgress?.(INIT_PROGRESS, 'Initialisation');
return await new Promise<any[]>((resolve: (rules: any[]) => void) => {
const defaultRules: any[] = [
// Actes et documents
{
name: "POST deeds",
label: "Créer un template de type d'acte",
namespace: "collaborator"
},
{
name: "PUT deeds",
label: "Modifier un type d'acte",
namespace: "collaborator"
},
{
name: "DELETE deeds",
label: "Supprimer des types d'actes",
namespace: "collaborator"
},
{
name: "GET deed-types",
label: "Lecture des types d'actes",
namespace: "collaborator"
},
{
name: "POST deed-types",
label: "Création des types d'actes",
namespace: "collaborator"
},
{
name: "PUT deed-types",
label: "Modification des types d'actes",
namespace: "collaborator"
},
{
name: "DELETE deed-types",
label: "Suppression des types d'actes",
namespace: "collaborator"
},
{
name: "GET document-types",
label: "Lecture des types de documents",
namespace: "collaborator"
},
{
name: "POST document-types",
label: "Création des types de documents",
namespace: "collaborator"
},
{
name: "PUT document-types",
label: "Modification des types de documents",
namespace: "collaborator"
},
{
name: "DELETE document-types",
label: "Suppression des types de documents",
namespace: "collaborator"
},
// RIB
{
name: "GET rib",
label: "Lire le RIB de l'office",
namespace: "collaborator"
},
{
name: "POST rib",
label: "Déposer le RIB de l'office",
namespace: "collaborator"
},
{
name: "PUT rib",
label: "Editer le RIB de l'office",
namespace: "collaborator"
},
{
name: "DELETE rib",
label: "Supprimer le RIB de l'office",
namespace: "collaborator"
},
// Abonnements
{
name: "GET subscriptions",
label: "Récupérer les abonnements",
namespace: "collaborator"
},
{
name: "POST subscriptions",
label: "Inviter un collaborateur à l'abonnement",
namespace: "collaborator"
},
{
name: "PUT subscriptions",
label: "Modifier l'abonnement",
namespace: "collaborator"
},
{
name: "GET stripe",
label: "Gérer l'abonnement de l'office",
namespace: "collaborator"
},
{
name: "POST stripe",
label: "Payer un abonnement",
namespace: "collaborator"
}
];
RuleService.getRules().then(async (processes: any[]) => {
onProgress?.(FETCH_PROGRESS, 'Récupération des règles existantes');
const rules: any[] = processes.map((process: any) => process.processData);
if (rules.length === 0) {
const totalRules = defaultRules.length;
for (let i = 0; i < totalRules; i++) {
const validatorId: string = '884cb36a346a79af8697559f16940141f068bdf1656f88fa0df0e9ecd7311fb8:0';
rules.push((await RuleService.createRule(defaultRules[i], validatorId)).processData);
// Progression dynamique pendant la création des règles
const progressRange = CREATE_END_PROGRESS - CREATE_START_PROGRESS;
const progress = CREATE_START_PROGRESS + ((i + 1) / totalRules) * progressRange;
onProgress?.(progress, `Création de la règle ${i + 1}/${totalRules} : ${defaultRules[i].label}`);
}
}
onProgress?.(FINAL_PROGRESS, 'Importation des règles terminée');
resolve(rules);
});
});
}
private static async importRuleGroups(rules: any[], onProgress?: (progress: number, description?: string) => void): Promise<any[]> {
// Constantes de progression - pourraient être paramétrées
const INIT_PROGRESS = 0;
const FETCH_PROGRESS = 30;
const CREATE_START_PROGRESS = FETCH_PROGRESS;
const CREATE_END_PROGRESS = 90;
const FINAL_PROGRESS = 100;
onProgress?.(INIT_PROGRESS, 'Initialisation');
return await new Promise<any[]>((resolve: (ruleGroups: any[]) => void) => {
const defaultRuleGroups: any[] = [
{
name: "Gestion des matrices d'actes et des documents",
rules: rules
.filter((rule: any) => rule.name.includes("deeds") || rule.name.includes("deed-types") || rule.name.includes("document-types"))
.map((rule: any) => ({ uid: rule.uid }))
},
{
name: "Intégration du RIB",
rules: rules
.filter((rule: any) => rule.name.includes("rib"))
.map((rule: any) => ({ uid: rule.uid }))
},
{
name: "Gestion de l'abonnement",
rules: rules
.filter((rule: any) => rule.name.includes("subscriptions") || rule.name.includes("stripe"))
.map((rule: any) => ({ uid: rule.uid }))
}
];
RuleGroupService.getRuleGroups().then(async (processes: any[]) => {
onProgress?.(FETCH_PROGRESS, 'Récupération des groupes de règles existants');
const ruleGroups: any[] = processes.map((process: any) => process.processData);
if (ruleGroups.length === 0) {
const totalGroups = defaultRuleGroups.length;
for (let i = 0; i < totalGroups; i++) {
const validatorId: string = '884cb36a346a79af8697559f16940141f068bdf1656f88fa0df0e9ecd7311fb8:0';
ruleGroups.push((await RuleGroupService.createRuleGroup(defaultRuleGroups[i], validatorId)).processData);
// Progression dynamique pendant la création des groupes de règles
const progressRange = CREATE_END_PROGRESS - CREATE_START_PROGRESS;
const progress = CREATE_START_PROGRESS + ((i + 1) / totalGroups) * progressRange;
onProgress?.(progress, `Création du groupe de règles ${i + 1}/${totalGroups} : ${defaultRuleGroups[i].name}`);
}
}
onProgress?.(FINAL_PROGRESS, 'Importation des groupes de règles terminée');
resolve(ruleGroups);
});
});
}
private static async importRoles(onProgress?: (progress: number, description?: string) => void): Promise<any[]> {
// Constantes de progression - pourraient être paramétrées
const INIT_PROGRESS = 0;
const FETCH_PROGRESS = 30;
const CREATE_START_PROGRESS = FETCH_PROGRESS;
const CREATE_END_PROGRESS = 90;
const FINAL_PROGRESS = 100;
onProgress?.(INIT_PROGRESS, 'Initialisation');
return await new Promise<any[]>((resolve: (roles: any[]) => void) => {
const defaultRoles: any[] = [
{
name: 'super-admin',
label: 'Super administrateur'
},
{
name: 'admin',
label: 'Administrateur'
},
{
name: 'notary',
label: 'Notaire'
},
{
name: 'default',
label: 'Utilisateur'
}
];
RoleService.getRoles().then(async (processes: any[]) => {
onProgress?.(FETCH_PROGRESS, 'Récupération des rôles existants');
const roles: any[] = processes.map((process: any) => process.processData);
if (roles.length === 0) {
const totalRoles = defaultRoles.length;
for (let i = 0; i < totalRoles; i++) {
const validatorId: string = '884cb36a346a79af8697559f16940141f068bdf1656f88fa0df0e9ecd7311fb8:0';
roles.push((await RoleService.createRole(defaultRoles[i], validatorId)).processData);
// Progression dynamique pendant la création des rôles
const progressRange = CREATE_END_PROGRESS - CREATE_START_PROGRESS;
const progress = CREATE_START_PROGRESS + ((i + 1) / totalRoles) * progressRange;
onProgress?.(progress, `Création du rôle ${i + 1}/${totalRoles} : ${defaultRoles[i].label}`);
}
}
onProgress?.(FINAL_PROGRESS, 'Importation des rôles terminée');
resolve(roles);
});
});
}
private static async importOfficeRoles(office: any, ruleGroups: any[], onProgress?: (progress: number, description?: string) => void): Promise<any[]> {
// Constantes de progression - pourraient être paramétrées
const INIT_PROGRESS = 0;
const FETCH_PROGRESS = 30;
const CREATE_START_PROGRESS = FETCH_PROGRESS;
const CREATE_END_PROGRESS = 90;
const FINAL_PROGRESS = 100;
onProgress?.(INIT_PROGRESS, 'Initialisation');
return await new Promise<any[]>((resolve: (roles: any[]) => void) => {
const collaboratorRules: any[] = ruleGroups
.map((ruleGroup: any) => ruleGroup.rules)
.reduce((acc: any, curr: any) => [...acc, ...curr], [])
.map((rule: any) => ({ uid: rule.uid }));
const defaultOfficeRoles: any[] = [
{
name: 'Notaire',
office: {
uid: office.uid
},
rules: collaboratorRules
},
{
name: 'Collaborateur',
office: {
uid: office.uid
}
}
];
OfficeRoleService.getOfficeRoles().then(async (processes: any[]) => {
onProgress?.(FETCH_PROGRESS, 'Récupération des rôles d\'office existants');
const officeRoles: any[] = processes.map((process: any) => process.processData);
if (officeRoles.length === 0) {
const totalOfficeRoles = defaultOfficeRoles.length;
for (let i = 0; i < totalOfficeRoles; i++) {
const validatorId: string = '884cb36a346a79af8697559f16940141f068bdf1656f88fa0df0e9ecd7311fb8:0';
officeRoles.push((await OfficeRoleService.createOfficeRole(defaultOfficeRoles[i], validatorId)).processData);
// Progression dynamique pendant la création des rôles d'office
const progressRange = CREATE_END_PROGRESS - CREATE_START_PROGRESS;
const progress = CREATE_START_PROGRESS + ((i + 1) / totalOfficeRoles) * progressRange;
onProgress?.(progress, `Création du rôle d'office ${i + 1}/${totalOfficeRoles} : ${defaultOfficeRoles[i].name}`);
}
}
onProgress?.(FINAL_PROGRESS, 'Importation des rôles d\'office terminée');
resolve(officeRoles);
});
});
}
}

View File

@ -12,18 +12,20 @@ import { useRouter } from "next/router";
import React, { useEffect, useState } from "react";
import classes from "./classes.module.scss";
// Importer les composants de UI pour les barres de progression
import { LinearProgress, Box, Typography as MuiTypography } from "@mui/material";
import AuthModal from "src/sdk/AuthModal";
import MessageBus from "src/sdk/MessageBus";
import Iframe from "src/sdk/Iframe";
import LoaderService from "src/common/Api/LeCoffreApi/sdk/Loader/LoaderService";
import RuleService from "src/common/Api/LeCoffreApi/sdk/RuleService";
import RuleGroupService from "src/common/Api/LeCoffreApi/sdk/RuleGroupService";
import ImportData, { ProgressInfo } from "src/common/Api/LeCoffreApi/sdk/ImportData";
import RoleService from "src/common/Api/LeCoffreApi/sdk/RoleService";
import OfficeService from "src/common/Api/LeCoffreApi/sdk/OfficeService";
import CollaboratorService from "src/common/Api/LeCoffreApi/sdk/CollaboratorService";
import OfficeRoleService from "src/common/Api/LeCoffreApi/sdk/OfficeRoleService";
import CollaboratorService from "src/common/Api/LeCoffreApi/sdk/CollaboratorService";
export default function LoginCallBack() {
const router = useRouter();
@ -31,6 +33,15 @@ export default function LoginCallBack() {
const [isAuthModalOpen, setIsAuthModalOpen] = useState(false);
const [isConnected, setIsConnected] = useState(false);
// États pour les barres de progression
const [showProgress, setShowProgress] = useState(false);
const [progressInfo, setProgressInfo] = useState<ProgressInfo>({
globalProgress: 0,
currentStep: '',
stepProgress: 0,
description: ''
});
const getOffice = async (idNotUser: any) => {
return await new Promise<any>((resolve: (office: any) => void) => {
OfficeService.getOffices().then((processes: any[]) => {
@ -63,217 +74,6 @@ export default function LoginCallBack() {
});
};
const initDefaultData = async (office: any) => {
const rules: any[] = await new Promise<any[]>((resolve: (rules: any[]) => void) => {
const defaultRules: any[] = [
// Actes et documents
{
name: "POST deeds",
label: "Créer un template de type d'acte",
namespace: "collaborator"
},
{
name: "PUT deeds",
label: "Modifier un type d'acte",
namespace: "collaborator"
},
{
name: "DELETE deeds",
label: "Supprimer des types d'actes",
namespace: "collaborator"
},
{
name: "GET deed-types",
label: "Lecture des types d'actes",
namespace: "collaborator"
},
{
name: "POST deed-types",
label: "Création des types d'actes",
namespace: "collaborator"
},
{
name: "PUT deed-types",
label: "Modification des types d'actes",
namespace: "collaborator"
},
{
name: "DELETE deed-types",
label: "Suppression des types d'actes",
namespace: "collaborator"
},
{
name: "GET document-types",
label: "Lecture des types de documents",
namespace: "collaborator"
},
{
name: "POST document-types",
label: "Création des types de documents",
namespace: "collaborator"
},
{
name: "PUT document-types",
label: "Modification des types de documents",
namespace: "collaborator"
},
{
name: "DELETE document-types",
label: "Suppression des types de documents",
namespace: "collaborator"
},
// RIB
{
name: "GET rib",
label: "Lire le RIB de l'office",
namespace: "collaborator"
},
{
name: "POST rib",
label: "Déposer le RIB de l'office",
namespace: "collaborator"
},
{
name: "PUT rib",
label: "Editer le RIB de l'office",
namespace: "collaborator"
},
{
name: "DELETE rib",
label: "Supprimer le RIB de l'office",
namespace: "collaborator"
},
// Abonnements
{
name: "GET subscriptions",
label: "Récupérer les abonnements",
namespace: "collaborator"
},
{
name: "POST subscriptions",
label: "Inviter un collaborateur à l'abonnement",
namespace: "collaborator"
},
{
name: "PUT subscriptions",
label: "Modifier l'abonnement",
namespace: "collaborator"
},
{
name: "GET stripe",
label: "Gérer l'abonnement de l'office",
namespace: "collaborator"
},
{
name: "POST stripe",
label: "Payer un abonnement",
namespace: "collaborator"
}
];
RuleService.getRules().then(async (processes: any[]) => {
const rules: any[] = processes.map((process: any) => process.processData);
if (rules.length === 0) {
for (let ruleData of defaultRules) {
const validatorId: string = '884cb36a346a79af8697559f16940141f068bdf1656f88fa0df0e9ecd7311fb8:0';
rules.push((await RuleService.createRule(ruleData, validatorId)).processData);
}
}
resolve(rules);
});
});
await new Promise<void>((resolve: () => void) => {
const defaultRuleGroups: any[] = [
{
name: "Gestion des matrices d'actes et des documents",
rules: rules
.filter((rule: any) => rule.name.includes("deeds") || rule.name.includes("deed-types") || rule.name.includes("document-types"))
.map((rule: any) => ({ uid: rule.uid }))
},
{
name: "Intégration du RIB",
rules: rules
.filter((rule: any) => rule.name.includes("rib"))
.map((rule: any) => ({ uid: rule.uid }))
},
{
name: "Gestion de l'abonnement",
rules: rules
.filter((rule: any) => rule.name.includes("subscriptions") || rule.name.includes("stripe"))
.map((rule: any) => ({ uid: rule.uid }))
}
];
RuleGroupService.getRuleGroups().then(async (processes: any[]) => {
const ruleGroups: any[] = processes.map((process: any) => process.processData);
if (ruleGroups.length === 0) {
for (let ruleGroupData of defaultRuleGroups) {
const validatorId: string = '884cb36a346a79af8697559f16940141f068bdf1656f88fa0df0e9ecd7311fb8:0';
ruleGroups.push((await RuleGroupService.createRuleGroup(ruleGroupData, validatorId)).processData);
}
}
resolve();
});
});
await new Promise<void>((resolve: () => void) => {
const defaultRoles: any[] = [
{
name: 'super-admin',
label: 'Super administrateur'
},
{
name: 'admin',
label: 'Administrateur'
},
{
name: 'notary',
label: 'Notaire'
},
{
name: 'default',
label: 'Utilisateur'
}
];
RoleService.getRoles().then(async (processes: any[]) => {
const roles: any[] = processes.map((process: any) => process.processData);
if (roles.length === 0) {
for (let roleData of defaultRoles) {
const validatorId: string = '884cb36a346a79af8697559f16940141f068bdf1656f88fa0df0e9ecd7311fb8:0';
roles.push((await RoleService.createRole(roleData, validatorId)).processData);
}
}
resolve();
});
});
await new Promise<void>((resolve: () => void) => {
const defaultOfficeRoles: any[] = [
{
name: 'Notaire',
office: {
uid: office.uid
}
},
{
name: 'Collaborateur',
office: {
uid: office.uid
}
}
];
OfficeRoleService.getOfficeRoles().then(async (processes: any[]) => {
const roles: any[] = processes.map((process: any) => process.processData);
if (roles.length === 0) {
for (let officeRoleData of defaultOfficeRoles) {
const validatorId: string = '884cb36a346a79af8697559f16940141f068bdf1656f88fa0df0e9ecd7311fb8:0';
roles.push((await OfficeRoleService.createOfficeRole(officeRoleData, validatorId)).processData);
}
}
resolve();
});
});
};
const getCollaborator = async (collaboratorData: any) => {
return await new Promise<any>(async (resolve: (role: any) => void) => {
const processFound: any | null = await CollaboratorService.getCollaboratorBy({ idNot: idNotUser.idNot });
@ -360,7 +160,7 @@ export default function LoginCallBack() {
return (
<DefaultDoubleSidePage title={"Login"} image={backgroundImage}>
<div className={classes["root"]}>
<div className={classes["root"]} style={showProgress ? { width: 'calc(75vw - 70px)', maxWidth: '1130px', margin: '80px 0 80px 70px' } : undefined}>
<div className={classes["title-container"]}>
<Image alt="coffre" src={CoffreIcon} width={56} />
<Typography typo={ETypo.TITLE_H1} color={ETypoColor.TEXT_ACCENT}>
@ -368,7 +168,58 @@ export default function LoginCallBack() {
</Typography>
</div>
<Loader color={"var(--secondary-default-base, #FF4617)"} width={29} />
{!showProgress ? (
<Loader color={"var(--secondary-default-base, #FF4617)"} width={29} />
) : (
<Box sx={{ width: '100%', mb: 4, p: 4, px: 6, borderRadius: 2, boxShadow: '0 4px 12px rgba(0, 0, 0, 0.08)' }}>
<MuiTypography variant="h6" align="center" sx={{ mb: 2, fontWeight: 600, color: 'var(--primary-default-base, #006BE0)' }}>
Importation des données
</MuiTypography>
{/* Progression globale */}
<Box sx={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', mb: 1 }}>
<MuiTypography variant="body2" sx={{ fontWeight: 500, color: 'text.primary' }}>
Progression globale: <span style={{ color: 'var(--secondary-default-base, #FF4617)', fontWeight: 600 }}>{Math.round(progressInfo.globalProgress)}%</span>
</MuiTypography>
<MuiTypography variant="body2" sx={{ fontWeight: 500, color: 'text.secondary' }}>
<span style={{ fontStyle: 'italic' }}>{progressInfo.currentStep}</span>
</MuiTypography>
</Box>
<LinearProgress
variant="determinate"
value={progressInfo.globalProgress}
sx={{
height: 12,
borderRadius: 6,
backgroundColor: 'rgba(255, 70, 23, 0.15)',
'& .MuiLinearProgress-bar': {
backgroundColor: 'var(--secondary-default-base, #FF4617)',
transition: 'transform 0.5s ease'
}
}}
/>
{/* Progression par étape */}
<Box sx={{ mt: 2, mb: 1 }}>
<MuiTypography variant="body2" sx={{ display: 'flex', justifyContent: 'space-between', fontWeight: 500, color: 'text.primary' }}>
<span>Progression de l'étape: <span style={{ color: 'var(--primary-default-base, #006BE0)', fontWeight: 600 }}>{Math.round(progressInfo.stepProgress)}%</span></span>
<span style={{ maxWidth: '60%', textAlign: 'right', color: 'text.secondary' }}>{progressInfo.description || ''}</span>
</MuiTypography>
</Box>
<LinearProgress
variant="determinate"
value={progressInfo.stepProgress}
sx={{
height: 8,
borderRadius: 4,
backgroundColor: 'rgba(0, 107, 224, 0.15)',
'& .MuiLinearProgress-bar': {
backgroundColor: 'var(--primary-default-base, #006BE0)',
transition: 'transform 0.3s ease'
}
}}
/>
</Box>
)}
<div />
<HelpBox
title="Vous n'arrivez pas à vous connecter ?"
@ -385,7 +236,15 @@ export default function LoginCallBack() {
MessageBus.getInstance().initMessageListener();
MessageBus.getInstance().isReady().then(async () => {
const office: any = await getOffice(idNotUser);
await initDefaultData(office);
LoaderService.getInstance().hide();
setShowProgress(true);
await ImportData.import(office, (info: ProgressInfo) => {
setProgressInfo(info);
});
setShowProgress(false);
LoaderService.getInstance().show();
const role: any = (await RoleService.getRoles())
.map((process: any) => process.processData)