From 2500e19e716016271f7f8fce1ea0d2fb876c2dc6 Mon Sep 17 00:00:00 2001 From: Anthony Janin Date: Thu, 17 Jul 2025 08:17:15 +0200 Subject: [PATCH] Fix some issues --- src/common/Api/LeCoffreApi/sdk/RoleService.ts | 88 ++++++++-- src/common/Api/LeCoffreApi/sdk/RuleService.ts | 152 ++++++++++++++++++ .../DefaultRoleDashboard/index.tsx | 115 +++---------- .../Layouts/Folder/ViewDocuments/index.tsx | 15 +- src/front/Components/Layouts/Login/index.tsx | 3 - .../Layouts/LoginCallback/index.tsx | 92 ++++++++--- .../Layouts/Roles/RolesInformations/index.tsx | 4 +- .../Components/Layouts/SelectFolder/index.tsx | 7 +- src/sdk/MessageBus.ts | 8 +- 9 files changed, 331 insertions(+), 153 deletions(-) create mode 100644 src/common/Api/LeCoffreApi/sdk/RuleService.ts diff --git a/src/common/Api/LeCoffreApi/sdk/RoleService.ts b/src/common/Api/LeCoffreApi/sdk/RoleService.ts index 30dea627..588c3df6 100644 --- a/src/common/Api/LeCoffreApi/sdk/RoleService.ts +++ b/src/common/Api/LeCoffreApi/sdk/RoleService.ts @@ -1,13 +1,17 @@ import { v4 as uuidv4 } from 'uuid'; -import MessageBus from 'src/sdk/MessageBus'; import User from 'src/sdk/User'; -export default class RoleService { +import AbstractService from './AbstractService'; - private static readonly messageBus: MessageBus = MessageBus.getInstance(); +import OfficeService from './OfficeService'; +import RuleService from './RuleService'; - private constructor() { } +export default class RoleService extends AbstractService { + + private constructor() { + super(); + } public static createRole(roleData: any, validatorId: string): Promise { const ownerId = User.getInstance().getPairingId()!; @@ -70,7 +74,7 @@ export default class RoleService { this.messageBus.createProcess(processData, privateFields, roles).then((processCreated: any) => { this.messageBus.notifyUpdate(processCreated.processId, processCreated.process.states[0].state_id).then(() => { this.messageBus.validateState(processCreated.processId, processCreated.process.states[0].state_id).then((_stateValidated: any) => { - resolve(processCreated); + this.getRoleByUid(processCreated.processData.uid).then(resolve).catch(reject); }).catch(reject); }).catch(reject); }).catch(reject); @@ -78,16 +82,58 @@ export default class RoleService { } public static getRoles(): Promise { - return this.messageBus.getProcessesDecoded((publicValues: any) => publicValues['uid'] && publicValues['utype'] && publicValues['utype'] === 'role' && publicValues['isDeleted'] && publicValues['isDeleted'] === 'false'); + // Check if we have valid cache + const items: any[] = this.getItems('_roles_'); + + return this.messageBus.getProcessesDecoded((publicValues: any) => + publicValues['uid'] && + publicValues['utype'] && + publicValues['utype'] === 'role' && + publicValues['isDeleted'] && + publicValues['isDeleted'] === 'false' && + !items.map((item: any) => item.processData.uid).includes(publicValues['uid']) + ).then(async (processes: any[]) => { + if (processes.length === 0) { + return items; + } else { + for (let process of processes) { + process = await this.completeRole(process); + + // Update cache + this.setItem('_roles_', process); + + items.push(process); + } + return items; + } + }); } public static getRoleByUid(uid: string): Promise { + // Check if we have valid cache + const item: any = this.getItem('_roles_', uid); + if (item) { + return Promise.resolve(item); + } + return new Promise((resolve: (process: any) => void, reject: (error: string) => void) => { - this.messageBus.getProcessesDecoded((publicValues: any) => publicValues['uid'] && publicValues['uid'] === uid && publicValues['utype'] && publicValues['utype'] === 'role' && publicValues['isDeleted'] && publicValues['isDeleted'] === 'false').then(async (processes: any[]) => { + this.messageBus.getProcessesDecoded((publicValues: any) => + publicValues['uid'] && + publicValues['uid'] === uid && + publicValues['utype'] && + publicValues['utype'] === 'role' && + publicValues['isDeleted'] && + publicValues['isDeleted'] === 'false' + ).then(async (processes: any[]) => { if (processes.length === 0) { resolve(null); } else { - const process: any = processes[0]; + let process: any = processes[0]; + process = await this.completeRole(process); + + // Update cache + this.setItem('_roles_', process); + resolve(process); } }).catch(reject); @@ -100,10 +146,34 @@ export default class RoleService { const newStateId: string = processUpdated.diffs[0]?.state_id; this.messageBus.notifyUpdate(process.processId, newStateId).then(() => { this.messageBus.validateState(process.processId, newStateId).then((_stateValidated) => { - resolve(); + const roleUid: string = process.processData.uid; + this.removeItem('_roles_', roleUid); + + this.getRoleByUid(roleUid).then(resolve).catch(reject); }).catch(reject); }).catch(reject); }).catch(reject); }); } + + private static async completeRole(process: any): Promise { + if (process.processData.office) { + process.processData.office = await new Promise(async (resolve: (office: any) => void) => { + const office: any = (await OfficeService.getOfficeByUid(process.processData.office.uid)).processData; + resolve(office); + }); + } + + if (process.processData.rules && process.processData.rules.length > 0) { + process.processData.rules = await new Promise(async (resolve: (rules: any[]) => void) => { + const rules: any[] = []; + for (const rule of process.processData.rules) { + rules.push((await RuleService.getRuleByUid(rule.uid)).processData); + } + resolve(rules); + }); + } + + return process; + } } diff --git a/src/common/Api/LeCoffreApi/sdk/RuleService.ts b/src/common/Api/LeCoffreApi/sdk/RuleService.ts new file mode 100644 index 00000000..d7f1cf97 --- /dev/null +++ b/src/common/Api/LeCoffreApi/sdk/RuleService.ts @@ -0,0 +1,152 @@ +import { v4 as uuidv4 } from 'uuid'; + +import User from 'src/sdk/User'; + +import AbstractService from './AbstractService'; + +export default class RuleService extends AbstractService { + + private constructor() { + super(); + } + + public static createRule(ruleData: any, validatorId: string): Promise { + const ownerId = User.getInstance().getPairingId()!; + + const processData: any = { + uid: uuidv4(), + utype: 'rule', + isDeleted: 'false', + created_at: new Date().toISOString(), + updated_at: new Date().toISOString(), + ...ruleData, + }; + + const privateFields: string[] = Object.keys(processData); + privateFields.splice(privateFields.indexOf('uid'), 1); + privateFields.splice(privateFields.indexOf('utype'), 1); + privateFields.splice(privateFields.indexOf('isDeleted'), 1); + + const roles: any = { + demiurge: { + members: [...[ownerId], validatorId], + validation_rules: [], + storages: [] + }, + owner: { + members: [ownerId], + validation_rules: [ + { + quorum: 0.5, + fields: [...privateFields, 'roles', 'uid', 'utype'], + min_sig_member: 1, + }, + ], + storages: [] + }, + validator: { + members: [validatorId], + validation_rules: [ + { + quorum: 0.5, + fields: ['idCertified', 'roles'], + min_sig_member: 1, + }, + { + quorum: 0.0, + fields: [...privateFields], + min_sig_member: 0, + }, + ], + storages: [] + }, + apophis: { + members: [ownerId], + validation_rules: [], + storages: [] + } + }; + + return new Promise((resolve: (processCreated: any) => void, reject: (error: string) => void) => { + this.messageBus.createProcess(processData, privateFields, roles).then((processCreated: any) => { + this.messageBus.notifyUpdate(processCreated.processId, processCreated.process.states[0].state_id).then(() => { + this.messageBus.validateState(processCreated.processId, processCreated.process.states[0].state_id).then((_stateValidated: any) => { + this.getRuleByUid(processCreated.processData.uid).then(resolve).catch(reject); + }).catch(reject); + }).catch(reject); + }).catch(reject); + }); + } + + public static getRules(): Promise { + // Check if we have valid cache + const items: any[] = this.getItems('_rules_'); + + return this.messageBus.getProcessesDecoded((publicValues: any) => + publicValues['uid'] && + publicValues['utype'] && + publicValues['utype'] === 'rule' && + publicValues['isDeleted'] && + publicValues['isDeleted'] === 'false' && + !items.map((item: any) => item.processData.uid).includes(publicValues['uid']) + ).then((processes: any[]) => { + if (processes.length === 0) { + return items; + } else { + for (const process of processes) { + // Update cache + this.setItem('_rules_', process); + + items.push(process); + } + return items; + } + }); + } + + public static getRuleByUid(uid: string): Promise { + // Check if we have valid cache + const item: any = this.getItem('_rules_', uid); + if (item) { + return Promise.resolve(item); + } + + return new Promise((resolve: (process: any) => void, reject: (error: string) => void) => { + this.messageBus.getProcessesDecoded((publicValues: any) => + publicValues['uid'] && + publicValues['uid'] === uid && + publicValues['utype'] && + publicValues['utype'] === 'rule' && + publicValues['isDeleted'] && + publicValues['isDeleted'] === 'false' + ).then((processes: any[]) => { + if (processes.length === 0) { + resolve(null); + } else { + const process: any = processes[0]; + + // Update cache + this.setItem('_rules_', process); + + resolve(process); + } + }).catch(reject); + }); + } + + public static updateRule(process: any, newData: any): Promise { + return new Promise((resolve: () => void, reject: (error: string) => void) => { + this.messageBus.updateProcess(process.processId, { updated_at: new Date().toISOString(), ...newData }, [], null).then((processUpdated: any) => { + const newStateId: string = processUpdated.diffs[0]?.state_id; + this.messageBus.notifyUpdate(process.processId, newStateId).then(() => { + this.messageBus.validateState(process.processId, newStateId).then((_stateValidated) => { + const ruleUid: string = process.processData.uid; + this.removeItem('_rules_', ruleUid); + + this.getRuleByUid(ruleUid).then(resolve).catch(reject); + }).catch(reject); + }).catch(reject); + }).catch(reject); + }); + } +} diff --git a/src/front/Components/LayoutTemplates/DefaultRoleDashboard/index.tsx b/src/front/Components/LayoutTemplates/DefaultRoleDashboard/index.tsx index b701b441..aa5295a3 100644 --- a/src/front/Components/LayoutTemplates/DefaultRoleDashboard/index.tsx +++ b/src/front/Components/LayoutTemplates/DefaultRoleDashboard/index.tsx @@ -5,7 +5,7 @@ import Module from "@Front/Config/Module"; import { IBlock } from "@Front/Components/DesignSystem/SearchBlockList/BlockList/Block"; import DefaultDashboardWithList, { IPropsDashboardWithList } from "../DefaultDashboardWithList"; -import { v4 as uuidv4 } from 'uuid'; +import UserStore from "@Front/Stores/UserStore"; import RoleService from "src/common/Api/LeCoffreApi/sdk/RoleService"; @@ -13,111 +13,32 @@ type IProps = IPropsDashboardWithList; export default function DefaultRoleDashboard(props: IProps) { const [roles, setRoles] = React.useState(null); + const router = useRouter(); const { roleUid } = router.query; + useEffect(() => { - /* TODO: review - const query: IGetRolesParams = { - include: { rules: true }, - }; + const user: any = UserStore.instance.getUser(); + if (!user) { + return; + } - OfficeRoles.getInstance() - .get(query) - .then((roles) => setRoles(roles)); - */ - - const roles: any[] = [ - { - uid: uuidv4(), - name: 'Notaire', - office: { - name: '', - crpcen: '', - created_at: new Date(), - updated_at: new Date() - }, - rules: [ - { - uid: uuidv4(), - name: "Gestion de l'abonnement", - label: "Gestion de l'abonnement", - namespace: "Gestion de l'abonnement", - created_at: new Date(), - updated_at: new Date() - }, - { - uid: uuidv4(), - name: "Gestion des matrices d'actes et des documents", - label: "Gestion des matrices d'actes et des documents", - namespace: "Gestion des matrices d'actes et des documents", - created_at: new Date(), - updated_at: new Date() - }, - { - uid: uuidv4(), - name: "Intégration du RIB", - label: "Intégration du RIB", - namespace: "Intégration du RIB", - created_at: new Date(), - updated_at: new Date() - } - ], - created_at: new Date(), - updated_at: new Date(), - }, - { - uid: uuidv4(), - name: 'Collaborateur', - office: { - name: '', - crpcen: '', - created_at: new Date(), - updated_at: new Date() - }, - rules: [ - { - uid: uuidv4(), - name: "Gestion de l'abonnement", - label: "Gestion de l'abonnement", - namespace: "Gestion de l'abonnement", - created_at: new Date(), - updated_at: new Date() - }, - { - uid: uuidv4(), - name: "Gestion des matrices d'actes et des documents", - label: "Gestion des matrices d'actes et des documents", - namespace: "Gestion des matrices d'actes et des documents", - created_at: new Date(), - updated_at: new Date() - }, - { - uid: uuidv4(), - name: "Intégration du RIB", - label: "Intégration du RIB", - namespace: "Intégration du RIB", - created_at: new Date(), - updated_at: new Date() - } - ], - created_at: new Date(), - updated_at: new Date(), - } - ]; + const office: any = user.office; + if (!office) { + return; + } RoleService.getRoles().then(async (processes: any[]) => { if (processes.length > 0) { - const roles: any[] = processes.map((process: any) => process.processData); - setRoles(roles); - } else { - /* - for (let role of roles) { - const validatorId: string = '884cb36a346a79af8697559f16940141f068bdf1656f88fa0df0e9ecd7311fb8:0'; + let roles: any[] = processes.map((process: any) => process.processData); + + // FilterBy office.uid + roles = roles.filter((role: any) => role.office.uid === office.uid); + + // OrderBy label + roles = roles.sort((a: any, b: any) => a.label.localeCompare(b.label)); - await RoleService.createRole(role, validatorId); - } setRoles(roles); - */ } }); }, []); diff --git a/src/front/Components/Layouts/Folder/ViewDocuments/index.tsx b/src/front/Components/Layouts/Folder/ViewDocuments/index.tsx index d369a864..834b2586 100644 --- a/src/front/Components/Layouts/Folder/ViewDocuments/index.tsx +++ b/src/front/Components/Layouts/Folder/ViewDocuments/index.tsx @@ -348,19 +348,14 @@ class ViewDocumentsClass extends BasePage { await new Promise((resolve: () => void) => { FileService.getFileByUid(process.processData.files[0].uid).then((p) => { if (p) { - alert(`aplc-${p.processData.file_name}`) - FileService.updateFile(p, { file_name: `aplc-${p.processData.file_name}` }).then(resolve); + FileService.updateFile(p, { + file_name: `aplc-${p.processData.file_name}` + }).then(resolve); } }); }); - - FileService.getFileByUid(process.processData.files[0].uid).then((process) => { - if (process) { - console.log(process.processData); - } - }); -/* + /* this.props.router.push( Module.getInstance() .get() @@ -370,7 +365,6 @@ class ViewDocumentsClass extends BasePage { ); */ - /* DocumentService.updateDocument(process, { document_status: EDocumentStatus.VALIDATED }).then(() => { this.props.router.push( Module.getInstance() @@ -380,7 +374,6 @@ class ViewDocumentsClass extends BasePage { this.state.document?.depositor?.uid, ); }); - */ } }); } catch (e) { diff --git a/src/front/Components/Layouts/Login/index.tsx b/src/front/Components/Layouts/Login/index.tsx index a72a55ac..4173b937 100644 --- a/src/front/Components/Layouts/Login/index.tsx +++ b/src/front/Components/Layouts/Login/index.tsx @@ -85,9 +85,6 @@ export default function Login() { const onSmsCodeSubmit = useCallback( async (e: React.FormEvent | null, values: { [key: string]: string }) => { try { - console.log(values); - console.log(email); - if (!values["totpCode"]) return; /* const res = await Auth.getInstance().verifyTotpCode({ totpCode: values["totpCode"], email }); diff --git a/src/front/Components/Layouts/LoginCallback/index.tsx b/src/front/Components/Layouts/LoginCallback/index.tsx index 9117561f..41bff8a6 100644 --- a/src/front/Components/Layouts/LoginCallback/index.tsx +++ b/src/front/Components/Layouts/LoginCallback/index.tsx @@ -17,8 +17,9 @@ import AuthModal from "src/sdk/AuthModal"; import MessageBus from "src/sdk/MessageBus"; import Iframe from "src/sdk/Iframe"; -import OfficeService from "src/common/Api/LeCoffreApi/sdk/OfficeService"; +import RuleService from "src/common/Api/LeCoffreApi/sdk/RuleService"; 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"; export default function LoginCallBack() { @@ -42,13 +43,12 @@ export default function LoginCallBack() { create: { address: idNotUser.office.address.address, zip_code: idNotUser.office.address.zip_code, - city: idNotUser.office.address.city, - }, + city: idNotUser.office.address.city + } }, office_status: 'ACTIVATED' }; const validatorId: string = '884cb36a346a79af8697559f16940141f068bdf1656f88fa0df0e9ecd7311fb8:0'; - OfficeService.createOffice(officeData, validatorId).then((process: any) => { if (process) { const office: any = process.processData; @@ -60,28 +60,69 @@ export default function LoginCallBack() { }); }; - const getRole = async (idNotUser: any) => { - return await new Promise((resolve: (role: any) => void) => { - RoleService.getRoles().then((processes: any[]) => { - const roleFound: any = processes.length > 0 ? processes.map((process: any) => process.processData).find((role: any) => role.name === idNotUser.role.name) : null; - if (roleFound) { - resolve(roleFound); - } else { - const roleData: any = { - name: idNotUser.role!.name, - label: idNotUser.role!.label - }; - const validatorId: string = '884cb36a346a79af8697559f16940141f068bdf1656f88fa0df0e9ecd7311fb8:0'; - - RoleService.createRole(roleData, validatorId).then((process: any) => { - if (process) { - const role: any = process.processData; - resolve(role); - } - }); + const getRoles = async (office: any) => { + const rules: any[] = await new Promise((resolve: (rules: any[]) => void) => { + const defaultRules: any[] = [ + { + name: "subscription", + label: "Gestion de l'abonnement", + namespace: "Gestion de l'abonnement" + }, + { + name: "document_types", + label: "Gestion des matrices d'actes et des documents", + namespace: "Gestion des matrices d'actes et des documents" + }, + { + name: "rib", + label: "Intégration du RIB", + namespace: "Intégration du RIB" } + ]; + 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); }); }); + + const roles: any[] = await new Promise((resolve: (roles: any[]) => void) => { + const defaultRoles: any[] = [ + { + name: 'notary', + label: 'Notaire', + office: { + uid: office.uid + }, + rules: rules.map((rule: any) => ({ uid: rule.uid })) + }, + { + name: 'collaborator', + label: 'Collaborateur', + office: { + uid: office.uid + }, + rules: rules.map((rule: any) => ({ uid: rule.uid })) + } + ]; + 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(roles); + }); + }); + + return roles; }; const getCollaborator = async (collaboratorData: any) => { @@ -92,7 +133,6 @@ export default function LoginCallBack() { resolve(collaboratorFound); } else { const validatorId: string = '884cb36a346a79af8697559f16940141f068bdf1656f88fa0df0e9ecd7311fb8:0'; - CollaboratorService.createCollaborator(collaboratorData, validatorId).then((process: any) => { if (process) { const collaborator: any = process.processData; @@ -191,7 +231,9 @@ export default function LoginCallBack() { MessageBus.getInstance().initMessageListener(); MessageBus.getInstance().isReady().then(async () => { const office: any = await getOffice(idNotUser); - const role: any = await getRole(idNotUser); + + const roles: any[] = await getRoles(office); + const role: any = roles.find((role: any) => role.name === idNotUser.role.name); const collaboratorData: any = { idNot: idNotUser.idNot, diff --git a/src/front/Components/Layouts/Roles/RolesInformations/index.tsx b/src/front/Components/Layouts/Roles/RolesInformations/index.tsx index 22f1fd7c..ef40d023 100644 --- a/src/front/Components/Layouts/Roles/RolesInformations/index.tsx +++ b/src/front/Components/Layouts/Roles/RolesInformations/index.tsx @@ -25,7 +25,7 @@ export default function RolesInformations() { let { roleUid } = router.query; const [roleSelected, setRoleSelected] = useState(null); - const [rulesGroupsCheckboxes, setRulesGroupsCheckboxes] = useState([]); + const [rulesGroupsCheckboxes, setRulesGroupsCheckboxes] = useState([]); const [selectAll, setSelectAll] = useState(false); const [isConfirmModalOpened, setIsConfirmModalOpened] = useState(false); @@ -190,7 +190,7 @@ export default function RolesInformations() { {rulesGroupsCheckboxes.map((ruleGroup) => (
diff --git a/src/front/Components/Layouts/SelectFolder/index.tsx b/src/front/Components/Layouts/SelectFolder/index.tsx index 1167ea39..323cd6f4 100644 --- a/src/front/Components/Layouts/SelectFolder/index.tsx +++ b/src/front/Components/Layouts/SelectFolder/index.tsx @@ -19,7 +19,6 @@ import FolderService from "src/common/Api/LeCoffreApi/sdk/FolderService"; export default function SelectFolder() { const router = useRouter(); - const [customer, setCustomer] = useState(null); const [folders, setFolders] = useState([]); useEffect(() => { @@ -27,8 +26,6 @@ export default function SelectFolder() { if (!customer) { return; } - setCustomer(customer); - LoaderService.getInstance().show(); FolderService.getFolders().then((processes: any[]) => { if (processes.length > 0) { @@ -48,6 +45,10 @@ export default function SelectFolder() { const handleSelectBlock = useCallback( (folder: IBlock) => { + const customer: any = UserStore.instance.getUser(); + if (!customer) { + return; + } router.push( Module.getInstance() .get() diff --git a/src/sdk/MessageBus.ts b/src/sdk/MessageBus.ts index aeb6316f..12dabda7 100644 --- a/src/sdk/MessageBus.ts +++ b/src/sdk/MessageBus.ts @@ -140,13 +140,15 @@ export default class MessageBus { let file: any; // Which is the last state that updated file_blob? + const lastUpdatedFileNameState = process.states.findLast((state: any) => state.pcd_commitment['file_name']); const lastUpdatedFileState = process.states.findLast((state: any) => state.pcd_commitment['file_blob']); - - if (!lastUpdatedFileState) { + if (!lastUpdatedFileNameState || !lastUpdatedFileState) { continue; } try { + const fileName: string = (await this.getData(processId, lastUpdatedFileNameState.state_id)).file_name; + const processData = await this.getData(processId, lastUpdatedFileState.state_id); const isEmpty = Object.keys(processData).length === 0; if (isEmpty) { @@ -158,7 +160,6 @@ export default class MessageBus { continue; } - if (!file) { file = { processId, @@ -175,6 +176,7 @@ export default class MessageBus { file.publicDataDecoded[key] = publicDataDecoded[key]; } } + file.processData.file_name = fileName; } catch (error) { console.error(error); } -- 2.39.5