Fix some issues

This commit is contained in:
Anthony Janin 2025-07-08 15:53:01 +02:00
parent dc54ec1a9b
commit 6edde3781b
25 changed files with 499 additions and 132 deletions

View File

@ -7,6 +7,8 @@ export default class CustomerService {
private static readonly messageBus: MessageBus = MessageBus.getInstance();
private static readonly CACHE_TTL = 5 * 60 * 1000; // 5 minutes cache TTL
private constructor() { }
public static createCustomer(customerData: any, validatorId: string): Promise<any> {
@ -70,7 +72,7 @@ export default class CustomerService {
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.getCustomerByUid(processCreated.processData.uid).then(resolve).catch(reject);
}).catch(reject);
}).catch(reject);
}).catch(reject);
@ -78,16 +80,64 @@ export default class CustomerService {
}
public static getCustomers(): Promise<any[]> {
return this.messageBus.getProcessesDecoded((publicValues: any) => publicValues['uid'] && publicValues['utype'] && publicValues['utype'] === 'customer' && publicValues['isDeleted'] && publicValues['isDeleted'] === 'false');
// Check if we have valid cache
const cacheProcesses: any[] = [];
const now = Date.now();
const customers: any[] = JSON.parse(sessionStorage.getItem('_customers_') || '[]');
for (const customer of customers) {
if (now - customer.timestamp < this.CACHE_TTL) {
cacheProcesses.push(customer.process);
}
}
const cacheUids: string[] = cacheProcesses.map((process: any) => process.processData.uid);
return this.messageBus.getProcessesDecoded((publicValues: any) =>
publicValues['uid'] &&
publicValues['utype'] &&
publicValues['utype'] === 'customer' &&
publicValues['isDeleted'] &&
publicValues['isDeleted'] === 'false' &&
!cacheUids.includes(publicValues['uid'])
).then((processes: any[]) => {
if (processes.length === 0) {
return cacheProcesses;
} else {
for (const process of processes) {
// Update cache
this.setCache(process);
cacheProcesses.push(process);
}
return cacheProcesses;
}
});
}
public static getCustomerByUid(uid: string): Promise<any> {
// Check if we have valid cache
const now = Date.now();
const cache: any = this.getCache(uid);
if (cache && (now - cache.timestamp) < this.CACHE_TTL) {
return Promise.resolve(cache.process);
}
return new Promise<any>((resolve: (process: any) => void, reject: (error: string) => void) => {
this.messageBus.getProcessesDecoded((publicValues: any) => publicValues['uid'] && publicValues['uid'] === uid && publicValues['utype'] && publicValues['utype'] === 'customer' && publicValues['isDeleted'] && publicValues['isDeleted'] === 'false').then((processes: any[]) => {
this.messageBus.getProcessesDecoded((publicValues: any) =>
publicValues['uid'] &&
publicValues['uid'] === uid &&
publicValues['utype'] &&
publicValues['utype'] === 'customer' &&
publicValues['isDeleted'] &&
publicValues['isDeleted'] === 'false'
).then((processes: any[]) => {
if (processes.length === 0) {
resolve(null);
} else {
const process: any = processes[0];
// Update cache
this.setCache(process);
resolve(process);
}
}).catch(reject);
@ -100,10 +150,56 @@ export default class CustomerService {
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 customerUid: string = process.processData.uid;
this.removeCache(customerUid);
this.getCustomerByUid(customerUid).then(resolve).catch(reject);
}).catch(reject);
}).catch(reject);
}).catch(reject);
});
}
private static setCache(process: any): void {
const key: string = '_customers_';
const customers: any[] = JSON.parse(sessionStorage.getItem(key) || '[]');
const index: number = customers.findIndex((customer: any) => customer.process.processData.uid === process.processData.uid);
if (index !== -1) {
customers[index] = {
process: process,
timestamp: Date.now()
};
} else {
customers.push({
process: process,
timestamp: Date.now()
});
}
sessionStorage.setItem(key, JSON.stringify(customers));
}
private static getCache(uid: string): any {
const key: string = '_customers_';
const customers: any[] = JSON.parse(sessionStorage.getItem(key) || '[]');
if (customers.length === 0) {
return null;
}
return customers.find((customer: any) => customer.process.processData.uid === uid);
}
private static removeCache(uid: string): void {
const key: string = '_customers_';
const customers: any[] = JSON.parse(sessionStorage.getItem(key) || '[]');
const index: number = customers.findIndex((customer: any) => customer.process.processData.uid === uid);
if (index !== -1) {
customers.splice(index, 1);
}
sessionStorage.setItem(key, JSON.stringify(customers));
}
}

View File

@ -7,6 +7,8 @@ export default class DocumentService {
private static readonly messageBus: MessageBus = MessageBus.getInstance();
private static readonly CACHE_TTL = 5 * 60 * 1000; // 5 minutes cache TTL
private constructor() { }
public static createDocument(documentData: any, validatorId: string): Promise<any> {
@ -70,7 +72,7 @@ export default class DocumentService {
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.getDocumentByUid(processCreated.processData.uid).then(resolve).catch(reject);
}).catch(reject);
}).catch(reject);
}).catch(reject);
@ -78,16 +80,64 @@ export default class DocumentService {
}
public static getDocuments(): Promise<any[]> {
return this.messageBus.getProcessesDecoded((publicValues: any) => publicValues['uid'] && publicValues['utype'] && publicValues['utype'] === 'document' && publicValues['isDeleted'] && publicValues['isDeleted'] === 'false');
// Check if we have valid cache
const cacheProcesses: any[] = [];
const now = Date.now();
const customers: any[] = JSON.parse(sessionStorage.getItem('_documents') || '[]');
for (const customer of customers) {
if (now - customer.timestamp < this.CACHE_TTL) {
cacheProcesses.push(customer.process);
}
}
const cacheUids: string[] = cacheProcesses.map((process: any) => process.processData.uid);
return this.messageBus.getProcessesDecoded((publicValues: any) =>
publicValues['uid'] &&
publicValues['utype'] &&
publicValues['utype'] === 'document' &&
publicValues['isDeleted'] &&
publicValues['isDeleted'] === 'false' &&
!cacheUids.includes(publicValues['uid'])
).then((processes: any[]) => {
if (processes.length === 0) {
return cacheProcesses;
} else {
for (const process of processes) {
// Update cache
this.setCache(process);
cacheProcesses.push(process);
}
return cacheProcesses;
}
});
}
public static getDocumentByUid(uid: string): Promise<any> {
// Check if we have valid cache
const now = Date.now();
const cache: any = this.getCache(uid);
if (cache && (now - cache.timestamp) < this.CACHE_TTL) {
return Promise.resolve(cache.process);
}
return new Promise<any>((resolve: (process: any) => void, reject: (error: string) => void) => {
this.messageBus.getProcessesDecoded((publicValues: any) => publicValues['uid'] && publicValues['uid'] === uid && publicValues['utype'] && publicValues['utype'] === 'document' && publicValues['isDeleted'] && publicValues['isDeleted'] === 'false').then((processes: any[]) => {
this.messageBus.getProcessesDecoded((publicValues: any) =>
publicValues['uid'] &&
publicValues['uid'] === uid &&
publicValues['utype'] &&
publicValues['utype'] === 'document' &&
publicValues['isDeleted'] &&
publicValues['isDeleted'] === 'false'
).then((processes: any[]) => {
if (processes.length === 0) {
resolve(null);
} else {
const process: any = processes[0];
// Update cache
this.setCache(process);
resolve(process);
}
}).catch(reject);
@ -100,10 +150,56 @@ export default class DocumentService {
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 documentUid: string = process.processData.uid;
this.removeCache(documentUid);
this.getDocumentByUid(documentUid).then(resolve).catch(reject);
}).catch(reject);
}).catch(reject);
}).catch(reject);
});
}
private static setCache(process: any): void {
const key: string = '_documents_';
const documents: any[] = JSON.parse(sessionStorage.getItem(key) || '[]');
const index: number = documents.findIndex((document: any) => document.process.processData.uid === process.processData.uid);
if (index !== -1) {
documents[index] = {
process: process,
timestamp: Date.now()
};
} else {
documents.push({
process: process,
timestamp: Date.now()
});
}
sessionStorage.setItem(key, JSON.stringify(documents));
}
private static getCache(uid: string): any {
const key: string = '_documents_';
const documents: any[] = JSON.parse(sessionStorage.getItem(key) || '[]');
if (documents.length === 0) {
return null;
}
return documents.find((document: any) => document.process.processData.uid === uid);
}
private static removeCache(uid: string): void {
const key: string = '_documents_';
const documents: any[] = JSON.parse(sessionStorage.getItem(key) || '[]');
const index: number = documents.findIndex((document: any) => document.process.processData.uid === uid);
if (index !== -1) {
documents.splice(index, 1);
}
sessionStorage.setItem(key, JSON.stringify(documents));
}
}

View File

@ -10,6 +10,8 @@ export default class FolderService {
private static readonly messageBus: MessageBus = MessageBus.getInstance();
private static readonly CACHE_TTL = 5 * 60 * 1000; // 5 minutes cache TTL
private constructor() { }
public static createFolder(folderData: any, stakeholdersId: string[], customersId: string[]): Promise<any> {
@ -79,7 +81,7 @@ export default class FolderService {
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.getFolderByUid(processCreated.processData.uid).then(resolve).catch(reject);
}).catch(reject);
}).catch(reject);
}).catch(reject);
@ -87,34 +89,66 @@ export default class FolderService {
}
public static getFolders(): Promise<any[]> {
return this.messageBus.getProcessesDecoded((publicValues: any) => publicValues['uid'] && publicValues['utype'] && publicValues['utype'] === 'folder' && publicValues['isDeleted'] && publicValues['isDeleted'] === 'false');
// Check if we have valid cache
const cacheProcesses: any[] = [];
const now = Date.now();
const folders: any[] = JSON.parse(sessionStorage.getItem('_folders_') || '[]');
for (const folder of folders) {
if (now - folder.timestamp < this.CACHE_TTL) {
cacheProcesses.push(folder.process);
}
}
const cacheUids: string[] = cacheProcesses.map((process: any) => process.processData.uid);
return this.messageBus.getProcessesDecoded((publicValues: any) =>
publicValues['uid'] &&
publicValues['utype'] &&
publicValues['utype'] === 'folder' &&
publicValues['isDeleted'] &&
publicValues['isDeleted'] === 'false' &&
!cacheUids.includes(publicValues['uid'])
).then(async (processes: any[]) => {
if (processes.length === 0) {
return cacheProcesses;
} else {
for (const process of processes) {
await this.completeFolder(process);
// Update cache
this.setCache(process);
cacheProcesses.push(process);
}
return cacheProcesses;
}
});
}
public static getFolderByUid(uid: string, includeCustomers: boolean = true, includeDeedType: boolean = true): Promise<any> {
public static getFolderByUid(uid: string): Promise<any> {
// Check if we have valid cache
const now = Date.now();
const cache: any = this.getCache(uid);
if (cache && (now - cache.timestamp) < this.CACHE_TTL) {
return Promise.resolve(cache.process);
}
return new Promise<any>((resolve: (process: any) => void, reject: (error: string) => void) => {
this.messageBus.getProcessesDecoded((publicValues: any) => publicValues['uid'] && publicValues['uid'] === uid && publicValues['utype'] && publicValues['utype'] === 'folder' && publicValues['isDeleted'] && publicValues['isDeleted'] === 'false').then(async (processes: any[]) => {
this.messageBus.getProcessesDecoded((publicValues: any) =>
publicValues['uid'] &&
publicValues['uid'] === uid &&
publicValues['utype'] &&
publicValues['utype'] === 'folder' &&
publicValues['isDeleted'] &&
publicValues['isDeleted'] === 'false'
).then(async (processes: any[]) => {
if (processes.length === 0) {
resolve(null);
} else {
const process: any = processes[0];
await this.completeFolder(process);
if (includeCustomers && process.processData.customers && process.processData.customers.length > 0) {
process.processData.customers = await new Promise<any[]>(async (resolve: (customers: any[]) => void) => {
const customers: any[] = [];
for (const uid of process.processData.customers) {
const p: any = await CustomerService.getCustomerByUid(uid);
customers.push(p.processData);
}
resolve(customers);
});
}
if (includeDeedType && process.processData.deed && process.processData.deed.deed_type) {
const p: any = await DeedTypeService.getDeedTypeByUid(process.processData.deed.deed_type.uid);
process.processData.deed.deed_type = p.processData;
// Remove duplicates
process.processData.deed.document_types = p.processData.document_types.filter((item: any, index: number) => p.processData.document_types.findIndex((t: any) => t.uid === item.uid) === index);
}
// Update cache
this.setCache(process);
resolve(process);
}
@ -128,10 +162,81 @@ export default class FolderService {
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 folderUid: string = process.processData.uid;
this.removeCache(folderUid);
this.getFolderByUid(folderUid).then(resolve).catch(reject);
}).catch(reject);
}).catch(reject);
}).catch(reject);
});
}
private static async completeFolder(process: any): Promise<any> {
if (process.processData.customers && process.processData.customers.length > 0) {
process.processData.customers = await new Promise<any[]>(async (resolve: (customers: any[]) => void) => {
const customers: any[] = [];
for (const customer of process.processData.customers) {
const p: any = await CustomerService.getCustomerByUid(customer.uid);
customers.push(p.processData);
}
resolve(customers);
});
}
if (process.processData.deed && process.processData.deed.deed_type) {
const p: any = await DeedTypeService.getDeedTypeByUid(process.processData.deed.deed_type.uid);
process.processData.deed.deed_type = p.processData;
// Remove duplicates
if (p.processData.document_types && p.processData.document_types.length > 0) {
process.processData.deed.document_types = p.processData.document_types.filter((item: any, index: number) => p.processData.document_types.findIndex((t: any) => t.uid === item.uid) === index);
}
}
return process;
}
private static setCache(process: any): void {
const key: string = '_folders_';
const folders: any[] = JSON.parse(sessionStorage.getItem(key) || '[]');
const index: number = folders.findIndex((folder: any) => folder.process.processData.uid === process.processData.uid);
if (index !== -1) {
folders[index] = {
process: process,
timestamp: Date.now()
};
} else {
folders.push({
process: process,
timestamp: Date.now()
});
}
sessionStorage.setItem(key, JSON.stringify(folders));
}
private static getCache(uid: string): any {
const key: string = '_folders_';
const folders: any[] = JSON.parse(sessionStorage.getItem(key) || '[]');
if (folders.length === 0) {
return null;
}
return folders.find((folder: any) => folder.process.processData.uid === uid);
}
private static removeCache(uid: string): void {
const key: string = '_folders_';
const folders: any[] = JSON.parse(sessionStorage.getItem(key) || '[]');
const index: number = folders.findIndex((folder: any) => folder.process.processData.uid === uid);
if (index !== -1) {
folders.splice(index, 1);
}
sessionStorage.setItem(key, JSON.stringify(folders));
}
}

View File

@ -44,7 +44,7 @@ export default class Auth extends BaseApiService {
// const variables = FrontendVariables.getInstance();
// TODO: review
const baseBackUrl = 'http://local.lecoffreio.4nkweb:3001'//variables.BACK_API_PROTOCOL + variables.BACK_API_HOST;
const baseBackUrl = 'http://localhost:8080';//variables.BACK_API_PROTOCOL + variables.BACK_API_HOST;
const url = new URL(`${baseBackUrl}/api/v1/idnot/user/${autorizationCode}`);
try {

View File

@ -7,6 +7,8 @@ import DefaultDashboardWithList, { IPropsDashboardWithList } from "../DefaultDas
import { OfficeRole } from "le-coffre-resources/dist/Notary";
// import OfficeRoles, { IGetRolesParams } from "@Front/Api/LeCoffreApi/Admin/OfficeRoles/OfficeRoles";
import { v4 as uuidv4 } from 'uuid';
import RoleService from "src/common/Api/LeCoffreApi/sdk/RoleService";
type IProps = IPropsDashboardWithList;
@ -26,10 +28,96 @@ export default function DefaultRoleDashboard(props: IProps) {
.then((roles) => setRoles(roles));
*/
RoleService.getRoles().then((processes: any[]) => {
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(),
}
];
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';
await RoleService.createRole(role, validatorId);
}
setRoles(roles);
}
});
}, []);

View File

@ -30,7 +30,7 @@ type IState = {
refuseText: string;
selectedFileIndex: number;
selectedFile: { uid: string; file_name: string; file_blob: FileBlob } | null;
documentNotary: DocumentNotary | null;
documentNotary: any | null;
fileBlob: Blob | null;
isLoading: boolean;
};
@ -168,7 +168,7 @@ class ViewDocumentsNotaryClass extends BasePage<IPropsClass, IState> {
private async getFilePreview(): Promise<void> {
try {
const fileBlob: Blob = new Blob([this.state.selectedFile.file_blob.data], { type: this.state.selectedFile.file_blob.type });
const fileBlob: Blob = new Blob([this.state.selectedFile!.file_blob.data], { type: this.state.selectedFile!.file_blob.type });
this.setState({
fileBlob,
});

View File

@ -60,12 +60,12 @@ export default function DeedTypesCreate(props: IProps) {
title: "Succès !",
description: "Type d'acte créé avec succès"
});
setTimeout(() => LoaderService.getInstance().hide(), 2000);
router.push(
Module.getInstance()
.get()
.modules.pages.DeedTypes.pages.DeedTypesInformations.props.path.replace("[uid]", processCreated.processData.uid),
);
LoaderService.getInstance().hide();
});
} catch (validationErrors: Array<ValidationError> | any) {
setValidationError(validationErrors as ValidationError[]);

View File

@ -36,7 +36,7 @@ export default function DeedTypesEdit() {
const deedType: any = process.processData;
setDeedTypeSelected(deedType);
}
setTimeout(() => LoaderService.getInstance().hide(), 2000);
LoaderService.getInstance().hide();
});
}
@ -66,12 +66,12 @@ export default function DeedTypesEdit() {
DeedTypeService.getDeedTypeByUid(deedTypeUid as string).then((process: any) => {
if (process) {
DeedTypeService.updateDeedType(process, { name: values["name"], description: values["description"] }).then(() => {
setTimeout(() => LoaderService.getInstance().hide(), 2000);
router.push(
Module.getInstance()
.get()
.modules.pages.DeedTypes.pages.DeedTypesInformations.props.path.replace("[uid]", deedTypeUid as string),
);
LoaderService.getInstance().hide();
});
}
});

View File

@ -55,8 +55,8 @@ export default function DeedTypesInformations(props: IProps) {
DeedTypeService.getDeedTypeByUid(deedTypeUid as string).then((process: any) => {
if (process) {
DeedTypeService.updateDeedType(process, { archived_at: new Date().toISOString() }).then(() => {
setTimeout(() => LoaderService.getInstance().hide(), 2000);
router.push(Module.getInstance().get().modules.pages.DeedTypes.props.path);
LoaderService.getInstance().hide();
});
}
});
@ -119,7 +119,7 @@ export default function DeedTypesInformations(props: IProps) {
.forEach((selectedDocument: any) => document_types.push(selectedDocument));
DeedTypeService.updateDeedType(process, { document_types: document_types }).then(() => {
setTimeout(() => LoaderService.getInstance().hide(), 2000);
LoaderService.getInstance().hide();
closeSaveModal();
});
}

View File

@ -53,12 +53,12 @@ export default function DocumentTypesCreate(props: IProps) {
title: "Succès !",
description: "Type de document créé avec succès"
});
setTimeout(() => LoaderService.getInstance().hide(), 2000);
router.push(
Module.getInstance()
.get()
.modules.pages.DocumentTypes.pages.DocumentTypesInformations.props.path.replace("[uid]", processCreated.processData.uid),
);
LoaderService.getInstance().hide();
});
} catch (e) {
if (e instanceof Array) {

View File

@ -31,7 +31,7 @@ export default function DocumentTypesEdit() {
const documentType: any = process.processData;
setDocumentTypeSelected(documentType);
}
setTimeout(() => LoaderService.getInstance().hide(), 2000);
LoaderService.getInstance().hide();
});
}
@ -56,7 +56,6 @@ export default function DocumentTypesEdit() {
DocumentTypeService.getDocumentTypeByUid(documentTypeUid as string).then((process: any) => {
if (process) {
DocumentTypeService.updateDocumentType(process, values).then(() => {
setTimeout(() => LoaderService.getInstance().hide(), 2000);
router.push(
Module.getInstance()
.get()
@ -65,6 +64,7 @@ export default function DocumentTypesEdit() {
documentTypeUid as string ?? "",
)
);
LoaderService.getInstance().hide();
});
}
});

View File

@ -82,21 +82,21 @@ export default function AddClientToFolder(props: IProps) {
LoaderService.getInstance().show();
CustomerService.createCustomer(customerData, validatorId).then((processCreated: any) => {
FolderService.getFolderByUid(folderUid as string, false, false).then((process: any) => {
FolderService.getFolderByUid(folderUid as string).then((process: any) => {
if (process) {
let customers: any[] = process.processData.customers;
if (!customers) {
customers = [];
const customers: any[] = [];
for (const customerUid of process.processData.customers.map((customer: any) => customer.uid)) {
customers.push({ uid: customerUid });
}
customers.push(processCreated.processData.uid);
customers.push({ uid: processCreated.processData.uid });
FolderService.updateFolder(process, { customers: customers }).then(() => {
ToasterService.getInstance().success({
title: "Succès !",
description: "Client ajouté avec succès au dossier"
ToasterService.getInstance().success({
title: "Succès !",
description: "Client ajouté avec succès au dossier"
});
setTimeout(() => LoaderService.getInstance().hide(), 2000);
router.push(`/folders/${folderUid}`);
LoaderService.getInstance().hide();
});
}
});
@ -108,17 +108,20 @@ export default function AddClientToFolder(props: IProps) {
}
} else {
LoaderService.getInstance().show();
FolderService.getFolderByUid(folderUid as string, false, false).then((process: any) => {
FolderService.getFolderByUid(folderUid as string).then((process: any) => {
if (process) {
const customers: any[] = customersToLink.map((customer: any) => customer.uid);
const customers: any[] = [];
for (const customerUid of customersToLink.map((customer: any) => customer.uid)) {
customers.push({ uid: customerUid });
}
FolderService.updateFolder(process, { customers: customers }).then(() => {
ToasterService.getInstance().success({
title: "Succès !",
description: selectedCustomers.length > 1 ? "Clients associés avec succès au dossier" : "Client associé avec succès au dossier"
ToasterService.getInstance().success({
title: "Succès !",
description: selectedCustomers.length > 1 ? "Clients associés avec succès au dossier" : "Client associé avec succès au dossier"
});
setTimeout(() => LoaderService.getInstance().hide(), 2000);
router.push(`/folders/${folderUid}`);
LoaderService.getInstance().hide();
});
}
});

View File

@ -18,7 +18,6 @@ import backgroundImage from "@Assets/images/background_refonte.svg";
import FolderService from "src/common/Api/LeCoffreApi/sdk/FolderService";
import DocumentService from "src/common/Api/LeCoffreApi/sdk/DocumentService";
import LoaderService from "src/common/Api/LeCoffreApi/sdk/Loader/LoaderService";
import { DocumentData } from "../FolderInformation/ClientView/DocumentTables/types";
export default function AskDocuments() {
const router = useRouter();
@ -65,7 +64,7 @@ export default function AskDocuments() {
for (let i = 0; i < documentAsked.length; i++) {
const documentTypeUid = documentAsked[i];
if (!documentTypeUid) continue;
const documentData: any = {
folder: {
uid: folderUid as string,
@ -106,7 +105,7 @@ export default function AskDocuments() {
// If those UIDs are already asked, filter them to not show them in the list and only
// show the documents that are not asked yet
const documentTypes = folder.deed!.document_types!.filter((documentType) => {
const documentTypes = folder.deed?.document_types?.filter((documentType) => {
if (userDocumentTypesUids.includes(documentType!.uid!)) return false;
return true;
});

View File

@ -103,9 +103,9 @@ export default function CreateFolder(): JSX.Element {
title: "Succès !",
description: "Dossier créé avec succès"
});
setTimeout(() => LoaderService.getInstance().hide(), 2000);
const folderUid: string = processCreated.processData.uid;
router.push(`/folders/${folderUid}`);
LoaderService.getInstance().hide();
});
} catch (backError) {
if (!Array.isArray(backError)) return;

View File

@ -64,12 +64,6 @@ export default function DocumentTables(props: IProps) {
// FilterBy folder.uid & depositor.uid
documents = documents.filter((document: any) => document.folder.uid === folderUid && document.depositor && document.depositor.uid === customerUid);
console.log('[DocumentTables] fetchDocuments: all documents for this folder/customer:', documents.map(doc => ({
uid: doc.uid,
status: doc.document_status,
type: doc.document_type?.name
})));
for (const document of documents) {
if (document.document_type) {
document.document_type = (await DocumentTypeService.getDocumentTypeByUid(document.document_type.uid)).processData;
@ -187,7 +181,6 @@ export default function DocumentTables(props: IProps) {
const onDownloadCertificate = useCallback(async (doc: any) => {
try {
console.log('[DocumentTables] onDownloadCertificate: doc', doc);
const certificateData: CertificateData = {
customer: {
firstName: doc.depositor.first_name || doc.depositor.firstName || "N/A",
@ -221,14 +214,12 @@ export default function DocumentTables(props: IProps) {
// Process only the files for this specific document
for (const file of documentProcess.processData.files) {
const fileProcess = await FileService.getFileByUid(file.uid);
console.log('[DocumentTables] onDownloadCertificate: fileProcess', fileProcess);
const hash = fileProcess.lastUpdatedFileState.pcd_commitment.file_blob;
certificateData.documentHash = hash;
const proof = await MessageBus.getInstance().generateMerkleProof(fileProcess.lastUpdatedFileState, 'file_blob');
console.log('[DocumentTables] onDownloadCertificate: proof', proof);
const metadata: Metadata = {
fileName: fileProcess.processData.file_name,
isDeleted: false,
@ -241,8 +232,6 @@ export default function DocumentTables(props: IProps) {
};
certificateData.metadata = metadata;
}
console.log('[DocumentTables] onDownloadCertificate: certificateData', certificateData);
await PdfService.getInstance().downloadCertificate(certificateData);
} catch (error) {
@ -381,7 +370,7 @@ export default function DocumentTables(props: IProps) {
};
})
.filter((document) => document !== null) as IRowProps[];
return validated;
},
[documents, folderUid, onDownload, onDownloadCertificate],

View File

@ -64,7 +64,7 @@ export default function ClientView(props: IProps) {
(customerUid: string) => {
if (!folder.uid) return;
LoaderService.getInstance().show();
FolderService.getFolderByUid(folder.uid, false, false).then((process: any) => {
FolderService.getFolderByUid(folder.uid).then((process: any) => {
if (process) {
const folder: any = process.processData;
@ -72,7 +72,7 @@ export default function ClientView(props: IProps) {
const customers = folder.customers.filter((uid: string) => uid !== customerUid);
FolderService.updateFolder(process, { customers: customers }).then(() => {
setTimeout(() => LoaderService.getInstance().hide(), 2000);
LoaderService.getInstance().hide();
window.location.reload();
});
}

View File

@ -29,7 +29,7 @@ export default function DeleteFolderModal(props: IProps) {
FolderService.getFolderByUid(folder.uid!).then((process: any) => {
if (process) {
FolderService.updateFolder(process, { isDeleted: 'true' }).then(() => {
setTimeout(() => LoaderService.getInstance().hide(), 2000);
LoaderService.getInstance().hide();
resolve();
});
}

View File

@ -109,7 +109,6 @@ export default function FolderInformation(props: IProps) {
*/
// TODO: review
LoaderService.getInstance().show();
return FolderService.getFolderByUid(folderUid).then(async (process: any) => {
if (process) {
const folder: any = process.processData;
@ -143,7 +142,6 @@ export default function FolderInformation(props: IProps) {
});
setFolder(folder);
setTimeout(() => LoaderService.getInstance().hide(), 2000);
}
});
}, [folderUid]);

View File

@ -41,7 +41,7 @@ export default function UpdateClient() {
if (process) {
const customer: any = process.processData;
setCustomer(customer);
setTimeout(() => LoaderService.getInstance().hide(), 2000);
LoaderService.getInstance().hide();
}
});
} catch (error) {
@ -77,8 +77,8 @@ export default function UpdateClient() {
if (process) {
// TODO: review - address
CustomerService.updateCustomer(process, { contact: contact }).then(() => {
setTimeout(() => LoaderService.getInstance().hide(), 2000);
router.push(backwardPath);
LoaderService.getInstance().hide();
});
}
});

View File

@ -54,10 +54,10 @@ export default function UpdateFolderMetadata() {
FolderService.getFolderByUid(folderUid).then((process: any) => {
if (process) {
FolderService.updateFolder(process, { ...values, deed: { uid: values["deed"] } }).then(() => {
setTimeout(() => LoaderService.getInstance().hide(), 2000);
router.push(Module.getInstance()
.get()
.modules.pages.Folder.pages.FolderInformation.props.path.replace("[folderUid]", folderUid));
LoaderService.getInstance().hide();
});
}
});
@ -75,7 +75,7 @@ export default function UpdateFolderMetadata() {
if (process) {
const folder: any = process.processData;
setSelectedFolder(folder);
setTimeout(() => LoaderService.getInstance().hide(), 2000);
LoaderService.getInstance().hide();
}
});
}, [folderUid]);

View File

@ -64,9 +64,9 @@ export default function RolesCreate(props: IProps) {
title: "Succès !",
description: "Rôle créé avec succès"
});
setTimeout(() => LoaderService.getInstance().hide(), 2000);
const role: any = processCreated.processData;
router.push(Module.getInstance().get().modules.pages.Roles.pages.RolesInformations.props.path.replace("[uid]", role.uid!));
LoaderService.getInstance().hide();
}
});

View File

@ -57,7 +57,7 @@ export default function RolesInformations() {
if (process) {
const role: any = process.processData;
resolve(role);
setTimeout(() => LoaderService.getInstance().hide(), 2000);
LoaderService.getInstance().hide();
}
});
})
@ -69,6 +69,8 @@ export default function RolesInformations() {
},
});
*/
/*
const rulesGroups: RulesGroup[] = [
{
uid: 'toto',
@ -87,12 +89,14 @@ export default function RolesInformations() {
updated_at: new Date(),
}
];
*/
if (!role) return;
setRoleSelected(role);
// TODO: review
if (!role.rules) return;
/*
const rulesCheckboxes = rulesGroups
.map((ruleGroup) => {
if (ruleGroup.rules?.every((rule) => role.rules?.find((r: any) => r.uid === rule.uid))) {
@ -106,6 +110,8 @@ export default function RolesInformations() {
const selectAll = rulesCheckboxes.every((rule) => rule.checked);
setSelectAll(selectAll);
setRulesGroupsCheckboxes(rulesCheckboxes);
*/
setRulesGroupsCheckboxes(role.rules);
}
getUser();

View File

@ -19,7 +19,7 @@ export interface Metadata {
fileName: string,
createdAt: Date,
isDeleted: boolean,
updatedAt: Date,
updatedAt: Date,
commitmentId: string,
documentUid: string;
documentType: string;
@ -247,14 +247,14 @@ export default class PdfService {
private splitTextToFit(font: any, text: string, maxWidth: number, fontSize: number): string[] {
const lines: string[] = [];
let currentLine = '';
// Split by characters (pdf-lib doesn't have word-level text measurement)
const chars = text.split('');
for (const char of chars) {
const testLine = currentLine + char;
const testWidth = font.widthOfTextAtSize(testLine, fontSize);
if (testWidth <= maxWidth) {
currentLine = testLine;
} else {
@ -267,11 +267,11 @@ export default class PdfService {
}
}
}
if (currentLine) {
lines.push(currentLine);
}
return lines;
}
@ -296,12 +296,10 @@ export default class PdfService {
* @param pdfBlob - The PDF file as a blob
* @returns Promise<{documentHash: string, documentUid: string, commitmentId: string, merkleProof?: string}> - Extracted information
*/
public async parseCertificate(certificateFile: File): Promise<{documentHash: string, commitmentId: string, merkleProof: any}> {
public async parseCertificate(certificateFile: File): Promise<{ documentHash: string, commitmentId: string, merkleProof: any }> {
return new Promise((resolve, reject) => {
const fileReader = new FileReader();
console.log("certificateFile", certificateFile);
fileReader.onload = async () => {
try {
// Read the metadata and get the validation data from the keywords
@ -312,8 +310,6 @@ export default class PdfService {
throw new Error("No keywords found in certificate");
}
console.log(keywords);
if (keywords.length !== 3) {
throw new Error("Invalid keywords found in certificate");
}
@ -326,20 +322,15 @@ export default class PdfService {
throw new Error("Invalid keywords found in certificate");
}
console.log("documentHash", documentHash);
console.log("commitmentId", commitmentId);
console.log("merkleProof", merkleProof);
resolve({ documentHash, commitmentId, merkleProof });
} catch (error) {
reject(error);
}
};
fileReader.onerror = () => {
reject(new Error('Failed to read PDF file'));
};
};
fileReader.readAsArrayBuffer(certificateFile);
});

View File

@ -15,7 +15,7 @@ export default class WatermarkService {
*/
public async addWatermark(file: File): Promise<File> {
const fileType = file.type;
try {
if (fileType.startsWith('image/')) {
return await this.addWatermarkToImage(file);
@ -23,7 +23,7 @@ export default class WatermarkService {
return await this.addWatermarkToPdf(file);
} else {
// For other file types, return the original file
console.log(`Watermark not supported for file type: ${fileType}`);
console.warn(`Watermark not supported for file type: ${fileType}`);
return file;
}
} catch (error) {
@ -49,22 +49,22 @@ export default class WatermarkService {
// Create canvas
const canvas = document.createElement('canvas');
const ctx = canvas.getContext('2d');
if (!ctx) {
reject(new Error('Could not get canvas context'));
return;
}
// Set canvas size to image size
canvas.width = img.width;
canvas.height = img.height;
// Draw original image
ctx.drawImage(img, 0, 0);
// Add watermark
this.addImageWatermark(ctx, img.width, img.height);
// Convert to blob
canvas.toBlob((blob) => {
if (blob) {
@ -100,26 +100,26 @@ export default class WatermarkService {
reader.onload = async (event) => {
try {
const arrayBuffer = event.target?.result as ArrayBuffer;
// Import pdf-lib dynamically to avoid SSR issues
const { PDFDocument, rgb } = await import('pdf-lib');
// Load the existing PDF
const pdfDoc = await PDFDocument.load(arrayBuffer);
// Get all pages
const pages = pdfDoc.getPages();
// Add watermark to each page
for (const page of pages) {
this.addPdfWatermark(page, rgb(0.8, 0.2, 0.2)); // Pale red color
}
// Save the modified PDF
const pdfBytes = await pdfDoc.save();
const watermarkedFile = new File([pdfBytes], file.name, { type: file.type });
resolve(watermarkedFile);
} catch (error) {
console.error('Error adding watermark to PDF:', error);
// If PDF watermarking fails, return original file
@ -140,21 +140,21 @@ export default class WatermarkService {
private addImageWatermark(ctx: CanvasRenderingContext2D, width: number, height: number): void {
// Save current state
ctx.save();
// Set watermark properties
ctx.fillStyle = 'rgba(128, 128, 128, 0.7)'; // Semi-transparent gray
ctx.font = '12px Arial';
ctx.textAlign = 'right';
ctx.textBaseline = 'bottom';
// Position watermark in bottom-right corner
const text = 'Processed by LeCoffre';
const x = width - 10; // 10 pixels from right edge
const y = height - 10; // 10 pixels from bottom
// Add watermark text
ctx.fillText(text, x, y);
// Restore state
ctx.restore();
}
@ -166,7 +166,7 @@ export default class WatermarkService {
*/
private addPdfWatermark(page: any, color: any): void {
const { width, height } = page.getSize();
// Calculate watermark position (bottom-right corner)
const text = 'Processed by LeCoffre';
const dateTime = new Date().toLocaleString('fr-FR', {
@ -176,20 +176,20 @@ export default class WatermarkService {
hour: '2-digit',
minute: '2-digit'
});
const fontSize = 10;
const lineHeight = 12; // Space between lines
// Calculate text widths (approximate - pdf-lib doesn't have a direct method for this)
// Using a conservative estimate: ~6 points per character for 10pt font
const estimatedTextWidth1 = text.length * 6;
const estimatedTextWidth2 = dateTime.length * 6;
const maxTextWidth = Math.max(estimatedTextWidth1, estimatedTextWidth2);
// Position watermark with proper margins (20 points from edges)
const x = width - maxTextWidth - 20; // 20 points from right edge
const y = 20; // 20 points from bottom
// Add watermark text with transparency (first line)
page.drawText(text, {
x: x,
@ -198,7 +198,7 @@ export default class WatermarkService {
color: color,
opacity: 0.7
});
// Add date/time with transparency (second line)
page.drawText(dateTime, {
x: x,

View File

@ -6,6 +6,7 @@ import EventBus from './EventBus';
import User from './User';
import MapUtils from './MapUtils';
import { FileBlob } from '../front/Api/Entities/types';
export default class MessageBus {
@ -768,9 +769,6 @@ export default class MessageBus {
console.error('[MessageBus] sendMessage: iframe not found');
return;
}
if (message.type === 'VALIDATE_MERKLE_PROOF') {
console.log('[MessageBus] sendMessage:', message);
}
iframe.contentWindow?.postMessage(message, targetOrigin);
}
@ -807,8 +805,6 @@ export default class MessageBus {
}
const message = event.data;
// console.log('[MessageBus] handleMessage:', message);
switch (message.type) {
case 'LISTENING':
this.isListening = true;