Merge branch 'dev' of https://git.4nkweb.com/4nk/lecoffre-front into dev
This commit is contained in:
commit
b6899cbf3f
@ -4,9 +4,6 @@ import User from 'src/sdk/User';
|
||||
|
||||
import AbstractService from './AbstractService';
|
||||
|
||||
import OfficeService from './OfficeService';
|
||||
import RoleService from './RoleService';
|
||||
import OfficeRoleService from './OfficeRoleService';
|
||||
import { DEFAULT_STORAGE_URLS } from '@Front/Config/AppConstants';
|
||||
|
||||
export default class CollaboratorService extends AbstractService {
|
||||
@ -15,7 +12,7 @@ export default class CollaboratorService extends AbstractService {
|
||||
super();
|
||||
}
|
||||
|
||||
public static createCollaborator(collaboratorData: any, validatorId: string): Promise<any> {
|
||||
public static async createCollaborator(collaboratorData: any, validatorId: string): Promise<{ processId: string, processData: any }> {
|
||||
const ownerId: string = User.getInstance().getPairingId()!;
|
||||
|
||||
const processData: any = {
|
||||
@ -28,134 +25,85 @@ export default class CollaboratorService extends AbstractService {
|
||||
};
|
||||
|
||||
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 allFields: string[] = [...privateFields, 'roles'];
|
||||
|
||||
const roles: any = {
|
||||
demiurge: {
|
||||
members: [ownerId],
|
||||
members: [ownerId, validatorId],
|
||||
validation_rules: [],
|
||||
storages: []
|
||||
},
|
||||
owner: {
|
||||
members: [ownerId],
|
||||
members: [ownerId, validatorId],
|
||||
validation_rules: [
|
||||
{
|
||||
quorum: 1,
|
||||
fields: [...privateFields, 'roles', 'uid', 'utype', 'isDeleted'],
|
||||
min_sig_member: 1,
|
||||
},
|
||||
],
|
||||
storages: [...DEFAULT_STORAGE_URLS]
|
||||
},
|
||||
validator: {
|
||||
members: [validatorId],
|
||||
validation_rules: [
|
||||
{
|
||||
quorum: 1,
|
||||
fields: [...privateFields, 'roles', 'uid', 'utype', 'isDeleted'],
|
||||
min_sig_member: 1,
|
||||
quorum: 0.01,
|
||||
fields: allFields,
|
||||
min_sig_member: 0.01,
|
||||
},
|
||||
],
|
||||
storages: [...DEFAULT_STORAGE_URLS]
|
||||
},
|
||||
apophis: {
|
||||
members: [ownerId],
|
||||
members: [ownerId, validatorId],
|
||||
validation_rules: [],
|
||||
storages: []
|
||||
}
|
||||
};
|
||||
|
||||
return new Promise<any>((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.getCollaboratorByUid(processCreated.processData.uid).then(resolve).catch(reject);
|
||||
}).catch(reject);
|
||||
}).catch(reject);
|
||||
}).catch(reject);
|
||||
});
|
||||
try {
|
||||
const processCreated = await this.messageBus.createProcess(processData, privateFields, roles);
|
||||
await this.messageBus.notifyUpdate(processCreated.processId, processCreated.process.states[0].state_id);
|
||||
await this.messageBus.validateState(processCreated.processId, processCreated.process.states[0].state_id);
|
||||
const finalProcessData = await this.messageBus.getProcessData(processCreated.processId);
|
||||
return { processId: processCreated.processId, processData: finalProcessData };
|
||||
} catch (error) {
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
public static getCollaborators(callback: (processes: any[]) => void, waitForAll: boolean = false): void {
|
||||
// Check if we have valid cache
|
||||
const items: any[] = this.getItems('_collaborators_');
|
||||
if (items.length > 0 && !waitForAll) {
|
||||
setTimeout(() => callback([...items]), 0);
|
||||
public static getCollaborators(callback: (processes: Record<string, any>) => void): void {
|
||||
const items: Record<string, any> = this.getItems('_collaborators_');
|
||||
if (Object.keys(items).length > 0) {
|
||||
setTimeout(() => callback(items), 0);
|
||||
}
|
||||
|
||||
this.messageBus.getProcessesDecoded((publicValues: any) =>
|
||||
publicValues['uid'] &&
|
||||
publicValues['utype'] &&
|
||||
publicValues['utype'] === 'collaborator' &&
|
||||
publicValues['isDeleted'] &&
|
||||
publicValues['isDeleted'] === 'false' &&
|
||||
!items.map((item: any) => item.processData.uid).includes(publicValues['uid'])
|
||||
).then(async (processes: any[]) => {
|
||||
if (processes.length === 0) {
|
||||
if (waitForAll) {
|
||||
callback([...items]);
|
||||
this.messageBus.getProcessesDecoded((processId: string, data: any) =>
|
||||
data['utype'] &&
|
||||
data['utype'] === 'collaborator' &&
|
||||
data['isDeleted'] &&
|
||||
data['isDeleted'] === 'false' &&
|
||||
!Object.keys(items).includes(processId)
|
||||
).then(async (processesData: Record<string, any>) => {
|
||||
if (Object.keys(processesData).length === 0) {
|
||||
// If no new processes and no cached items, return empty array
|
||||
if (Object.keys(items).length === 0) {
|
||||
callback([]);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
const updatedItems: any[] = [...items];
|
||||
|
||||
for (let processIndex = 0; processIndex < processes.length; processIndex++) {
|
||||
let process = processes[processIndex];
|
||||
|
||||
if (!waitForAll) {
|
||||
process = await this.completeCollaborator(process, (processInProgress: any) => {
|
||||
const currentItems: any[] = [...updatedItems];
|
||||
|
||||
const existingIndex: number = currentItems.findIndex(item => item.processData?.uid === processInProgress.processData?.uid);
|
||||
if (existingIndex >= 0) {
|
||||
currentItems[existingIndex] = processInProgress;
|
||||
} else {
|
||||
currentItems.push(processInProgress);
|
||||
}
|
||||
|
||||
callback(currentItems);
|
||||
});
|
||||
} else {
|
||||
process = await this.completeCollaborator(process);
|
||||
}
|
||||
|
||||
// Update cache
|
||||
this.setItem('_collaborators_', process);
|
||||
|
||||
const existingIndex: number = updatedItems.findIndex(item => item.processData?.uid === process.processData?.uid);
|
||||
if (existingIndex >= 0) {
|
||||
updatedItems[existingIndex] = process;
|
||||
} else {
|
||||
updatedItems.push(process);
|
||||
}
|
||||
|
||||
if (!waitForAll) {
|
||||
callback([...updatedItems]);
|
||||
}
|
||||
}
|
||||
|
||||
if (waitForAll) {
|
||||
callback([...updatedItems]);
|
||||
}
|
||||
// Single callback with all completed items
|
||||
callback(items);
|
||||
}).catch(error => {
|
||||
console.error('Failed to fetch collaborators:', error);
|
||||
// Return cached data if available, otherwise empty array
|
||||
callback(items);
|
||||
});
|
||||
}
|
||||
|
||||
public static getCollaboratorsBy(whereClause: { [path: string]: any }): Promise<any[]> {
|
||||
return new Promise<any[]>((resolve: (collaborators: any[]) => void) => {
|
||||
this.getCollaborators((processes: any[]) => {
|
||||
if (processes.length === 0) {
|
||||
resolve([]);
|
||||
public static getCollaboratorsBy(whereClause: { [path: string]: any }): Promise<Record<string, any>> {
|
||||
return new Promise<Record<string, any>>((resolve: (collaborators: Record<string, any>) => void) => {
|
||||
this.getCollaborators((processes: Record<string, any>) => {
|
||||
if (Object.keys(processes).length === 0) {
|
||||
resolve({});
|
||||
} else {
|
||||
resolve(processes.filter((process: any) => {
|
||||
const collaborator: any = process.processData;
|
||||
|
||||
const filteredEntries = Object.entries(processes).filter(([processId, process]) => {
|
||||
for (const path in whereClause) {
|
||||
const paths: string[] = path.split('.');
|
||||
|
||||
let value: any = collaborator;
|
||||
let value: any = process;
|
||||
value['processId'] = processId;
|
||||
for (let i = 0; i < paths.length; i++) {
|
||||
const currentPath = paths[i];
|
||||
if (!currentPath || value === undefined || value === null) {
|
||||
@ -170,19 +118,28 @@ export default class CollaboratorService extends AbstractService {
|
||||
}
|
||||
|
||||
return true;
|
||||
}));
|
||||
});
|
||||
|
||||
// Convert filtered entries back to a Record
|
||||
const filteredProcesses: Record<string, any> = {};
|
||||
filteredEntries.forEach(([processId, process]) => {
|
||||
filteredProcesses[processId] = process;
|
||||
});
|
||||
|
||||
resolve(filteredProcesses);
|
||||
}
|
||||
}, true);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
public static getCollaboratorBy(whereClause: { [path: string]: any }): Promise<any | null> {
|
||||
return new Promise<any | null>((resolve: (collaborator: any | null) => void) => {
|
||||
this.getCollaborators((processes: any[]) => {
|
||||
if (processes.length === 0) {
|
||||
this.getCollaborators((processes: Record<string, any>) => {
|
||||
const processArray = Object.values(processes);
|
||||
if (processArray.length === 0) {
|
||||
resolve(null);
|
||||
} else {
|
||||
resolve(processes.find((process: any) => {
|
||||
resolve(processArray.find((process: any) => {
|
||||
const collaborator: any = process.processData;
|
||||
|
||||
for (const path in whereClause) {
|
||||
@ -205,120 +162,30 @@ export default class CollaboratorService extends AbstractService {
|
||||
return true;
|
||||
}));
|
||||
}
|
||||
}, true);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
public static getCollaboratorByUid(uid: string, forceRefresh: boolean = false): Promise<any> {
|
||||
// Check if we have valid cache
|
||||
const item: any = this.getItem('_collaborators_', uid);
|
||||
if (item && !forceRefresh) {
|
||||
return Promise.resolve(item);
|
||||
}
|
||||
public static async updateCollaborator(processId: string, newData: any): Promise<void> {
|
||||
try {
|
||||
const processUpdated = await this.messageBus.updateProcess(
|
||||
processId,
|
||||
{ updated_at: new Date().toISOString(), ...newData },
|
||||
[],
|
||||
null
|
||||
);
|
||||
|
||||
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'] === 'collaborator' &&
|
||||
publicValues['isDeleted'] &&
|
||||
publicValues['isDeleted'] === 'false'
|
||||
).then(async (processes: any[]) => {
|
||||
if (processes.length === 0) {
|
||||
resolve(null);
|
||||
} else {
|
||||
let process: any = processes[0];
|
||||
process = await this.completeCollaborator(process);
|
||||
const newStateId: string = processUpdated.diffs[0]?.state_id;
|
||||
await this.messageBus.notifyUpdate(processId, newStateId);
|
||||
await this.messageBus.validateState(processId, newStateId);
|
||||
|
||||
const processData = await this.messageBus.getProcessData(processId);
|
||||
|
||||
// Update cache
|
||||
this.setItem('_collaborators_', process);
|
||||
|
||||
resolve(process);
|
||||
}
|
||||
}).catch(reject);
|
||||
});
|
||||
}
|
||||
|
||||
public static updateCollaborator(process: any, newData: any): Promise<void> {
|
||||
return new Promise<void>((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 collaboratorUid: string = process.processData.uid;
|
||||
this.removeItem('_collaborators_', collaboratorUid);
|
||||
|
||||
this.getCollaboratorByUid(collaboratorUid, true).then(resolve).catch(reject);
|
||||
}).catch(reject);
|
||||
}).catch(reject);
|
||||
}).catch(reject);
|
||||
});
|
||||
}
|
||||
|
||||
private static async completeCollaborator(process: any, progressCallback?: (processInProgress: any) => void): Promise<any> {
|
||||
const progressiveProcess: any = JSON.parse(JSON.stringify(process));
|
||||
|
||||
if (process.processData.office) {
|
||||
const office: any = (await OfficeService.getOfficeByUid(process.processData.office.uid)).processData;
|
||||
if (office) {
|
||||
process.processData.office = {
|
||||
uid: office.uid,
|
||||
idNot: office.idNot,
|
||||
crpcen: office.crpcen,
|
||||
name: office.name,
|
||||
office_status: office.office_status
|
||||
};
|
||||
|
||||
if (progressCallback) {
|
||||
progressiveProcess.processData.office = process.processData.office;
|
||||
progressCallback(JSON.parse(JSON.stringify(progressiveProcess)));
|
||||
}
|
||||
} else {
|
||||
console.error('Office not found');
|
||||
this.setItem('_collaborators_', processId, processData);
|
||||
} catch (error) {
|
||||
console.error('Failed to update collaborator:', error);
|
||||
throw error; // Re-throw to allow caller to handle
|
||||
}
|
||||
}
|
||||
|
||||
if (process.processData.role) {
|
||||
const role: any = (await RoleService.getRoleByUid(process.processData.role.uid)).processData;
|
||||
if (!role) {
|
||||
console.error('Role not found');
|
||||
} else {
|
||||
process.processData.role = {
|
||||
uid: role.uid,
|
||||
name: role.name
|
||||
};
|
||||
}
|
||||
|
||||
if (progressCallback) {
|
||||
progressiveProcess.processData.role = process.processData.role;
|
||||
progressCallback(JSON.parse(JSON.stringify(progressiveProcess)));
|
||||
}
|
||||
}
|
||||
|
||||
if (process.processData.office_role) {
|
||||
const officeRole: any = (await OfficeRoleService.getOfficeRoleByUid(process.processData.office_role.uid)).processData;
|
||||
if (!officeRole) {
|
||||
console.error('Office role not found');
|
||||
} else {
|
||||
process.processData.office_role = {
|
||||
uid: officeRole.uid,
|
||||
name: officeRole.name,
|
||||
rules: officeRole.rules?.map((rule: any) => {
|
||||
return {
|
||||
uid: rule.uid,
|
||||
name: rule.name
|
||||
};
|
||||
})
|
||||
};
|
||||
}
|
||||
|
||||
if (progressCallback) {
|
||||
progressiveProcess.processData.office_role = process.processData.office_role;
|
||||
progressCallback(JSON.parse(JSON.stringify(progressiveProcess)));
|
||||
}
|
||||
}
|
||||
|
||||
return process;
|
||||
}
|
||||
}
|
||||
|
@ -21,6 +21,7 @@ export default class DeedTypeService extends AbstractService {
|
||||
isDeleted: 'false',
|
||||
created_at: new Date().toISOString(),
|
||||
updated_at: new Date().toISOString(),
|
||||
document_types: [],
|
||||
...deedTypeData
|
||||
};
|
||||
|
||||
@ -63,39 +64,36 @@ export default class DeedTypeService extends AbstractService {
|
||||
}
|
||||
}
|
||||
|
||||
public static getDeedTypes(callback: (processes: any[]) => void): void {
|
||||
public static getDeedTypes(callback: (processes: Record<string, any>) => void): void {
|
||||
// Check if we have valid cache
|
||||
const items: any[] = this.getItems('_deed_types_');
|
||||
if (items.length > 0) {
|
||||
setTimeout(() => callback([...items]), 0);
|
||||
const items: Record<string, any> = this.getItems('_deed_types_');
|
||||
if (Object.keys(items).length > 0) {
|
||||
setTimeout(() => callback(items), 0);
|
||||
}
|
||||
|
||||
this.messageBus.getProcessesDecoded((values: any) => {
|
||||
return values['utype'] === 'deedType'
|
||||
this.messageBus.getProcessesDecoded((_processId: string, values: any) => {
|
||||
return values['utype']
|
||||
&& values['utype'] === 'deedType'
|
||||
&& values['isDeleted']
|
||||
&& values['isDeleted'] === 'false';
|
||||
}).then(async (processes: any) => {
|
||||
if (processes.length === 0) {
|
||||
callback([...items]);
|
||||
}).then(async (processes: Record<string, any>) => {
|
||||
if (Object.keys(processes).length === 0) {
|
||||
callback(items);
|
||||
return;
|
||||
}
|
||||
|
||||
const updatedItems: any[] = [...items];
|
||||
console.log('[DeedTypeService/getDeedTypes] processes', processes);
|
||||
|
||||
for (let processIndex = 0; processIndex < processes.length; processIndex++) {
|
||||
const process = processes[processIndex];
|
||||
const updatedItems: Record<string, any> = { ...items };
|
||||
|
||||
for (const [processId, process] of Object.entries(processes)) {
|
||||
// Update cache
|
||||
this.setItem('_deed_types_', process);
|
||||
this.setItem('_deed_types_', processId, process);
|
||||
|
||||
const existingIndex: number = updatedItems.findIndex(item => item.processData?.uid === process.processData?.uid);
|
||||
if (existingIndex >= 0) {
|
||||
updatedItems[existingIndex] = process;
|
||||
} else {
|
||||
updatedItems.push(process);
|
||||
}
|
||||
updatedItems[processId] = process;
|
||||
}
|
||||
|
||||
callback([...updatedItems]);
|
||||
callback(updatedItems);
|
||||
});
|
||||
}
|
||||
|
||||
@ -115,7 +113,7 @@ export default class DeedTypeService extends AbstractService {
|
||||
const processData = await this.messageBus.getProcessData(processId);
|
||||
|
||||
// Update cache
|
||||
this.setItem('_deed_types_', processData);
|
||||
this.setItem('_deed_types_', processId, processData);
|
||||
} catch (error) {
|
||||
console.error('Failed to update deed type:', error);
|
||||
throw error; // Re-throw to allow caller to handle
|
||||
|
@ -63,106 +63,55 @@ export default class DocumentTypeService extends AbstractService {
|
||||
});
|
||||
}
|
||||
|
||||
public static getDocumentTypes(callback: (processes: any[]) => void): void {
|
||||
public static getDocumentTypes(callback: (processes: Record<string, any>) => void): void {
|
||||
// Check if we have valid cache
|
||||
const items: any[] = this.getItems('_document_types_');
|
||||
if (items.length > 0) {
|
||||
setTimeout(() => callback([...items]), 0);
|
||||
const items: Record<string, any> = this.getItems('_document_types_');
|
||||
if (Object.keys(items).length > 0) {
|
||||
setTimeout(() => callback(items), 0);
|
||||
}
|
||||
|
||||
this.messageBus.getProcessesDecoded((values: any) => {
|
||||
this.messageBus.getProcessesDecoded((_processId: string, values: any) => {
|
||||
return values['utype'] === 'documentType'
|
||||
&& values['isDeleted'] === 'false';
|
||||
}).then(async (processes: any) => {
|
||||
if (processes.length === 0) {
|
||||
callback([...items]);
|
||||
}).then(async (processes: Record<string, any>) => {
|
||||
if (Object.keys(processes).length === 0) {
|
||||
callback(items);
|
||||
return;
|
||||
}
|
||||
|
||||
const updatedItems: any[] = [...items];
|
||||
|
||||
for (let processIndex = 0; processIndex < processes.length; processIndex++) {
|
||||
const process = processes[processIndex];
|
||||
const updatedItems: Record<string, any> = { ...items };
|
||||
|
||||
for (const [processId, process] of Object.entries(processes)) {
|
||||
// Update cache
|
||||
this.setItem('_document_types_', process);
|
||||
this.setItem('_document_types_', processId, process);
|
||||
|
||||
const existingIndex: number = updatedItems.findIndex(item => item.processId === process.processId);
|
||||
if (existingIndex >= 0) {
|
||||
updatedItems[existingIndex] = process;
|
||||
} else {
|
||||
updatedItems.push(process);
|
||||
}
|
||||
updatedItems[processId] = process;
|
||||
}
|
||||
|
||||
callback([...updatedItems]);
|
||||
callback(updatedItems);
|
||||
});
|
||||
}
|
||||
|
||||
public static getDocumentTypeByProcessId(processId: string): Promise<any> {
|
||||
// Check if we have valid cache
|
||||
const item: any = this.getItem('_document_types_', processId);
|
||||
if (item) {
|
||||
return Promise.resolve(item);
|
||||
}
|
||||
public static async updateDocumentType(processId: string, newData: any): Promise<void> {
|
||||
try {
|
||||
const processUpdated = await this.messageBus.updateProcess(
|
||||
processId,
|
||||
{ updated_at: new Date().toISOString(), ...newData },
|
||||
[],
|
||||
null
|
||||
);
|
||||
|
||||
return new Promise<any>((resolve: (process: any) => void, reject: (error: string) => void) => {
|
||||
this.messageBus.getProcessesDecoded((publicValues: any) => {
|
||||
return publicValues['utype'] === 'documentType' && publicValues['isDeleted'] === 'false';
|
||||
}).then((processes: any[]) => {
|
||||
// Find the process with matching processId
|
||||
const process = processes.find((p: any) => p.processId === processId);
|
||||
|
||||
if (!process) {
|
||||
resolve(null);
|
||||
return;
|
||||
}
|
||||
|
||||
// Update cache
|
||||
this.setItem('_document_types_', process);
|
||||
|
||||
resolve(process);
|
||||
}).catch(reject);
|
||||
});
|
||||
}
|
||||
|
||||
// Keep the old method for backward compatibility but mark as deprecated
|
||||
/** @deprecated Use getDocumentTypeByProcessId instead */
|
||||
public static getDocumentTypeByUid(uid: string): Promise<any> {
|
||||
// Check if we have valid cache
|
||||
const item: any = this.getItem('_document_types_', uid);
|
||||
if (item) {
|
||||
return Promise.resolve(item);
|
||||
}
|
||||
|
||||
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'] === 'documentType' && publicValues['isDeleted'] && publicValues['isDeleted'] === 'false').then((processes: any[]) => {
|
||||
if (processes.length === 0) {
|
||||
resolve(null);
|
||||
} else {
|
||||
const process: any = processes[0];
|
||||
|
||||
// Update cache
|
||||
this.setItem('_document_types_', process);
|
||||
|
||||
resolve(process);
|
||||
}
|
||||
}).catch(reject);
|
||||
});
|
||||
}
|
||||
|
||||
public static updateDocumentType(process: any, newData: any): Promise<void> {
|
||||
return new Promise<void>((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) => {
|
||||
this.removeItem('_document_types_', process.processId);
|
||||
await this.messageBus.notifyUpdate(processId, newStateId);
|
||||
await this.messageBus.validateState(processId, newStateId);
|
||||
|
||||
this.getDocumentTypeByProcessId(process.processId).then(resolve).catch(reject);
|
||||
}).catch(reject);
|
||||
}).catch(reject);
|
||||
}).catch(reject);
|
||||
});
|
||||
const processData = await this.messageBus.getProcessData(processId);
|
||||
|
||||
// Update cache
|
||||
this.setItem('_document_types_', processId, processData);
|
||||
} catch (error) {
|
||||
console.error('Failed to update deed type:', error);
|
||||
throw error; // Re-throw to allow caller to handle
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -3,13 +3,7 @@ import { v4 as uuidv4 } from 'uuid';
|
||||
import User from 'src/sdk/User';
|
||||
|
||||
import AbstractService from './AbstractService';
|
||||
import CustomerService from './CustomerService';
|
||||
import CollaboratorService from './CollaboratorService';
|
||||
import DeedTypeService from './DeedTypeService';
|
||||
import DocumentTypeService from './DocumentTypeService';
|
||||
import DocumentService from './DocumentService';
|
||||
import FileService from './FileService';
|
||||
import NoteService from './NoteService';
|
||||
import { DEFAULT_STORAGE_URLS, DEFAULT_VALIDATOR_ID } from '@Front/Config/AppConstants';
|
||||
|
||||
export default class FolderService extends AbstractService {
|
||||
|
||||
@ -17,7 +11,7 @@ export default class FolderService extends AbstractService {
|
||||
super();
|
||||
}
|
||||
|
||||
public static createFolder(folderData: any, stakeholdersId: string[], customersId: string[]): Promise<any> {
|
||||
public static async createFolder(folderData: any, customersId: string[]): Promise<{ processId: string, processData: any }> {
|
||||
const ownerId: string = User.getInstance().getPairingId()!;
|
||||
|
||||
const processData: any = {
|
||||
@ -30,9 +24,7 @@ export default class FolderService extends AbstractService {
|
||||
};
|
||||
|
||||
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 allFields: string[] = [...privateFields, 'roles'];
|
||||
|
||||
const roles: any = {
|
||||
demiurge: {
|
||||
@ -40,135 +32,101 @@ export default class FolderService extends AbstractService {
|
||||
validation_rules: [],
|
||||
storages: []
|
||||
},
|
||||
owner: {
|
||||
members: [ownerId],
|
||||
owners: {
|
||||
members: [ownerId, DEFAULT_VALIDATOR_ID],
|
||||
validation_rules: [
|
||||
{
|
||||
quorum: 0.5,
|
||||
fields: [...privateFields, 'roles', 'uid', 'utype'],
|
||||
min_sig_member: 1,
|
||||
quorum: 0.01,
|
||||
fields: allFields,
|
||||
min_sig_member: 0.01,
|
||||
},
|
||||
],
|
||||
storages: []
|
||||
storages: [...DEFAULT_STORAGE_URLS]
|
||||
},
|
||||
stakeholders: {
|
||||
members: stakeholdersId,
|
||||
validation_rules: [
|
||||
{
|
||||
quorum: 0.5,
|
||||
fields: ['documents', 'motes'],
|
||||
min_sig_member: 1,
|
||||
},
|
||||
],
|
||||
storages: []
|
||||
guests: {
|
||||
members: [],
|
||||
validation_rules: [{
|
||||
quorum: 0.01,
|
||||
fields: allFields,
|
||||
min_sig_member: 0.01,
|
||||
}],
|
||||
storages: [...DEFAULT_STORAGE_URLS]
|
||||
},
|
||||
customers: {
|
||||
members: customersId,
|
||||
validation_rules: [
|
||||
{
|
||||
quorum: 0.0,
|
||||
fields: privateFields,
|
||||
fields: allFields,
|
||||
min_sig_member: 0.0,
|
||||
},
|
||||
],
|
||||
storages: []
|
||||
storages: [...DEFAULT_STORAGE_URLS]
|
||||
},
|
||||
apophis: {
|
||||
members: [ownerId],
|
||||
members: [ownerId, DEFAULT_VALIDATOR_ID],
|
||||
validation_rules: [],
|
||||
storages: []
|
||||
}
|
||||
};
|
||||
|
||||
return new Promise<any>((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.getFolderByUid(processCreated.processData.uid).then(resolve).catch(reject);
|
||||
}).catch(reject);
|
||||
}).catch(reject);
|
||||
}).catch(reject);
|
||||
});
|
||||
try {
|
||||
const processCreated = await this.messageBus.createProcess(processData, privateFields, roles);
|
||||
await this.messageBus.notifyUpdate(processCreated.processId, processCreated.process.states[0].state_id);
|
||||
await this.messageBus.validateState(processCreated.processId, processCreated.process.states[0].state_id);
|
||||
const finalProcessData = await this.messageBus.getProcessData(processCreated.processId);
|
||||
|
||||
return { processId: processCreated.processId, processData: finalProcessData };
|
||||
} catch (error) {
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
public static getFolders(callback: (processes: any[]) => void, waitForAll: boolean = false): void {
|
||||
public static getFolders(callback: (processes: Record<string, any>) => void): void {
|
||||
// Check if we have valid cache
|
||||
const items: any[] = this.getItems('_folders_');
|
||||
if (items.length > 0 && !waitForAll) {
|
||||
setTimeout(() => callback([...items]), 0);
|
||||
const items: Record<string, any> = this.getItems('_folders_');
|
||||
if (Object.keys(items).length > 0) {
|
||||
setTimeout(() => callback(items), 0);
|
||||
}
|
||||
|
||||
this.messageBus.getProcessesDecoded((publicValues: any) =>
|
||||
publicValues['uid'] &&
|
||||
publicValues['utype'] &&
|
||||
publicValues['utype'] === 'folder' &&
|
||||
publicValues['isDeleted'] &&
|
||||
publicValues['isDeleted'] === 'false' &&
|
||||
!items.map((item: any) => item.processData.uid).includes(publicValues['uid'])
|
||||
).then(async (processes: any[]) => {
|
||||
if (processes.length === 0) {
|
||||
if (waitForAll) {
|
||||
callback([...items]);
|
||||
}
|
||||
this.messageBus.getProcessesDecoded((_processId: string, values: any) => {
|
||||
return values['utype']
|
||||
&& values['utype'] === 'folder'
|
||||
&& values['isDeleted']
|
||||
&& values['isDeleted'] === 'false';
|
||||
}).then(async (processes: Record<string, any>) => {
|
||||
if (Object.keys(processes).length === 0) {
|
||||
callback(items);
|
||||
return;
|
||||
}
|
||||
|
||||
const updatedItems: any[] = [...items];
|
||||
console.log('[FolderService/getFolders] processes', processes);
|
||||
|
||||
for (let processIndex = 0; processIndex < processes.length; processIndex++) {
|
||||
let process = processes[processIndex];
|
||||
|
||||
if (!waitForAll) {
|
||||
process = await this.completeFolder(process, (processInProgress: any) => {
|
||||
const currentItems: any[] = [...updatedItems];
|
||||
|
||||
const existingIndex: number = currentItems.findIndex(item => item.processData?.uid === processInProgress.processData?.uid);
|
||||
if (existingIndex >= 0) {
|
||||
currentItems[existingIndex] = processInProgress;
|
||||
} else {
|
||||
currentItems.push(processInProgress);
|
||||
}
|
||||
|
||||
callback(currentItems);
|
||||
});
|
||||
} else {
|
||||
process = await this.completeFolder(process);
|
||||
}
|
||||
const updatedItems: Record<string, any> = { ...items };
|
||||
|
||||
for (const [processId, process] of Object.entries(processes)) {
|
||||
// Update cache
|
||||
this.setItem('_folders_', process);
|
||||
this.setItem('_folders_', processId, process);
|
||||
|
||||
const existingIndex: number = updatedItems.findIndex(item => item.processData?.uid === process.processData?.uid);
|
||||
if (existingIndex >= 0) {
|
||||
updatedItems[existingIndex] = process;
|
||||
} else {
|
||||
updatedItems.push(process);
|
||||
updatedItems[processId] = process;
|
||||
}
|
||||
|
||||
if (!waitForAll) {
|
||||
callback([...updatedItems]);
|
||||
}
|
||||
}
|
||||
|
||||
if (waitForAll) {
|
||||
callback([...updatedItems]);
|
||||
}
|
||||
callback(updatedItems);
|
||||
});
|
||||
}
|
||||
|
||||
public static getFoldersBy(whereClause: { [path: string]: any }): Promise<any[]> {
|
||||
return new Promise<any[]>((resolve: (folders: any[]) => void) => {
|
||||
this.getFolders((processes: any[]) => {
|
||||
if (processes.length === 0) {
|
||||
resolve([]);
|
||||
public static getFoldersBy(whereClause: { [path: string]: any }): Promise<Record<string, any>> {
|
||||
return new Promise<Record<string, any>>((resolve: (folders: Record<string, any>) => void) => {
|
||||
this.getFolders((processes: Record<string, any>) => {
|
||||
if (Object.keys(processes).length === 0) {
|
||||
resolve({});
|
||||
} else {
|
||||
resolve(processes.filter((process: any) => {
|
||||
const folder: any = process.processData;
|
||||
|
||||
const filteredEntries = Object.entries(processes).filter(([processId, process]) => {
|
||||
for (const path in whereClause) {
|
||||
const paths: string[] = path.split('.');
|
||||
|
||||
let value: any = folder;
|
||||
let value: any = process;
|
||||
value['processId'] = processId;
|
||||
for (let i = 0; i < paths.length; i++) {
|
||||
const currentPath = paths[i];
|
||||
if (!currentPath || value === undefined || value === null) {
|
||||
@ -183,146 +141,40 @@ export default class FolderService extends AbstractService {
|
||||
}
|
||||
|
||||
return true;
|
||||
}));
|
||||
});
|
||||
|
||||
// Convert filtered entries back to a Record
|
||||
const filteredProcesses: Record<string, any> = {};
|
||||
filteredEntries.forEach(([processId, process]) => {
|
||||
filteredProcesses[processId] = process;
|
||||
});
|
||||
|
||||
resolve(filteredProcesses);
|
||||
}
|
||||
}, true);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
public static getFolderByUid(uid: string): Promise<any> {
|
||||
// Check if we have valid cache
|
||||
const item: any = this.getItem('_folders_', uid);
|
||||
if (item) {
|
||||
return Promise.resolve(item);
|
||||
}
|
||||
public static async updateFolder(processId: string, newData: any): Promise<void> {
|
||||
try {
|
||||
const processUpdated = await this.messageBus.updateProcess(
|
||||
processId,
|
||||
{ updated_at: new Date().toISOString(), ...newData },
|
||||
[],
|
||||
null
|
||||
);
|
||||
|
||||
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[]) => {
|
||||
if (processes.length === 0) {
|
||||
resolve(null);
|
||||
} else {
|
||||
let process: any = processes[0];
|
||||
process = await this.completeFolder(process);
|
||||
const newStateId: string = processUpdated.diffs[0]?.state_id;
|
||||
await this.messageBus.notifyUpdate(processId, newStateId);
|
||||
await this.messageBus.validateState(processId, newStateId);
|
||||
|
||||
const processData = await this.messageBus.getProcessData(processId);
|
||||
|
||||
// Update cache
|
||||
this.setItem('_folders_', process);
|
||||
|
||||
resolve(process);
|
||||
}
|
||||
}).catch(reject);
|
||||
});
|
||||
}
|
||||
|
||||
public static updateFolder(process: any, newData: any): Promise<void> {
|
||||
return new Promise<void>((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 folderUid: string = process.processData.uid;
|
||||
this.removeItem('_folders_', folderUid);
|
||||
|
||||
this.getFolderByUid(folderUid).then(resolve).catch(reject);
|
||||
}).catch(reject);
|
||||
}).catch(reject);
|
||||
}).catch(reject);
|
||||
});
|
||||
}
|
||||
|
||||
public static refreshFolderByUid(uid: string): Promise<void> {
|
||||
return new Promise<void>((resolve: () => void, reject: (error: string) => void) => {
|
||||
this.getFolderByUid(uid).then((process: any) => {
|
||||
this.updateFolder(process, {}).then(resolve).catch(reject);
|
||||
}).catch(reject);
|
||||
});
|
||||
}
|
||||
|
||||
private static async completeFolder(process: any, progressCallback?: (processInProgress: any) => void): Promise<any> {
|
||||
const progressiveProcess: any = JSON.parse(JSON.stringify(process));
|
||||
|
||||
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) {
|
||||
customers.push((await CustomerService.getCustomerByUid(customer.uid)).processData);
|
||||
}
|
||||
resolve(customers);
|
||||
});
|
||||
|
||||
if (process.processData.customers && process.processData.customers.length > 0) {
|
||||
const documents: any[] = (await DocumentService.getDocuments()).map((process: any) => process.processData);
|
||||
for (const customer of process.processData.customers) {
|
||||
customer.documents = documents.filter((document: any) => (document.depositor && document.depositor.uid === customer.uid) || (document.customer && document.customer.uid === customer.uid));
|
||||
|
||||
for (const document of customer.documents) {
|
||||
if (document.document_type) {
|
||||
document.document_type = (await DocumentTypeService.getDocumentTypeByUid(document.document_type.uid)).processData;
|
||||
}
|
||||
|
||||
if (document.files && document.files.length > 0) {
|
||||
const files: any[] = [];
|
||||
for (const file of document.files) {
|
||||
files.push({ uid: file.uid, file_name: (await FileService.getFileByUid(file.uid)).processData.file_name });
|
||||
}
|
||||
document.files = files;
|
||||
this.setItem('_folders_', processId, processData);
|
||||
} catch (error) {
|
||||
console.error('Failed to update folder:', error);
|
||||
throw error; // Re-throw to allow caller to handle
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (progressCallback) {
|
||||
progressiveProcess.processData.customers = process.processData.customers;
|
||||
progressCallback(JSON.parse(JSON.stringify(progressiveProcess)));
|
||||
}
|
||||
}
|
||||
|
||||
if (process.processData.stakeholders && process.processData.stakeholders.length > 0) {
|
||||
process.processData.stakeholders = await new Promise<any[]>(async (resolve: (stakeholders: any[]) => void) => {
|
||||
const stakeholders: any[] = [];
|
||||
for (const stakeholder of process.processData.stakeholders) {
|
||||
stakeholders.push((await CollaboratorService.getCollaboratorByUid(stakeholder.uid)).processData);
|
||||
}
|
||||
resolve(stakeholders);
|
||||
});
|
||||
|
||||
if (progressCallback) {
|
||||
progressiveProcess.processData.stakeholders = process.processData.stakeholders;
|
||||
progressCallback(JSON.parse(JSON.stringify(progressiveProcess)));
|
||||
}
|
||||
}
|
||||
|
||||
if (process.processData.deed && process.processData.deed.deed_type) {
|
||||
const deed_type: any = (await DeedTypeService.getDeedTypeByUid(process.processData.deed.deed_type.uid)).processData;
|
||||
process.processData.deed.deed_type = deed_type;
|
||||
|
||||
if (deed_type.document_types && deed_type.document_types.length > 0) {
|
||||
// Remove duplicates
|
||||
process.processData.deed.document_types = deed_type.document_types.filter((item: any, index: number) => deed_type.document_types.findIndex((t: any) => t.uid === item.uid) === index);
|
||||
}
|
||||
|
||||
if (progressCallback) {
|
||||
progressiveProcess.processData.deed = process.processData.deed;
|
||||
progressCallback(JSON.parse(JSON.stringify(progressiveProcess)));
|
||||
}
|
||||
}
|
||||
|
||||
const notes: any[] = (await NoteService.getNotes()).map((process: any) => process.processData);
|
||||
if (notes.length > 0) {
|
||||
process.processData.notes = notes.filter((note: any) => note.folder.uid === process.processData.uid);
|
||||
|
||||
if (progressCallback) {
|
||||
progressiveProcess.processData.notes = process.processData.notes;
|
||||
progressCallback(JSON.parse(JSON.stringify(progressiveProcess)));
|
||||
}
|
||||
}
|
||||
|
||||
return process;
|
||||
}
|
||||
}
|
||||
|
@ -108,7 +108,7 @@ export default class Auth extends BaseApiService {
|
||||
}
|
||||
}
|
||||
|
||||
public async getOfficeProcessByIdNot(): Promise<any> {
|
||||
public async getOfficeProcessByIdNot(): Promise<{ success: boolean; data: { processId: string, processData: { [key: string]: any } } }> {
|
||||
const baseBackUrl = 'http://localhost:8080';//variables.BACK_API_PROTOCOL + variables.BACK_API_HOST;
|
||||
|
||||
const url = new URL(`${baseBackUrl}/api/v1/process/office`);
|
||||
|
@ -7,7 +7,6 @@ import Typography, { ETypo } from "@Front/Components/DesignSystem/Typography";
|
||||
import DefaultDeedTypesDashboard from "@Front/Components/LayoutTemplates/DefaultDeedTypeDashboard";
|
||||
import { ToasterService } from "@Front/Components/DesignSystem/Toaster";
|
||||
import Module from "@Front/Config/Module";
|
||||
import { DeedType, Office } from "le-coffre-resources/dist/Admin";
|
||||
import { useRouter } from "next/router";
|
||||
import { useCallback, useState } from "react";
|
||||
|
||||
@ -19,6 +18,7 @@ import UserStore from "@Front/Stores/UserStore";
|
||||
import LoaderService from "src/common/Api/LeCoffreApi/sdk/Loader/LoaderService";
|
||||
import DeedTypeService from "src/common/Api/LeCoffreApi/sdk/DeedTypeService";
|
||||
import { DEFAULT_VALIDATOR_ID } from "@Front/Config/AppConstants";
|
||||
import Auth from "@Front/Api/Auth/IdNot";
|
||||
|
||||
type IProps = {};
|
||||
export default function DeedTypesCreate(props: IProps) {
|
||||
@ -31,27 +31,44 @@ export default function DeedTypesCreate(props: IProps) {
|
||||
async (e: React.FormEvent<HTMLFormElement> | null, values: { [key: string]: string }) => {
|
||||
try {
|
||||
const user: any = UserStore.instance.getUser();
|
||||
const officeId: string = user.office.uid;
|
||||
|
||||
const deedType = DeedType.hydrate<DeedType>({
|
||||
name: values["name"],
|
||||
description: values["description"],
|
||||
office: Office.hydrate<Office>({
|
||||
uid: officeId,
|
||||
}),
|
||||
});
|
||||
try {
|
||||
await validateOrReject(deedType, { groups: ["createDeedType"], forbidUnknownValues: true });
|
||||
} catch (validationErrors: Array<ValidationError> | any) {
|
||||
setValidationError(validationErrors as ValidationError[]);
|
||||
if (!user) {
|
||||
console.error("DeedTypesCreate: User not found - user is null or undefined");
|
||||
return;
|
||||
}
|
||||
const res = await Auth.getInstance().getOfficeProcessByIdNot();
|
||||
if (!res.success) {
|
||||
console.error("DeedTypesCreate: Office not found - office is null or undefined");
|
||||
return;
|
||||
}
|
||||
const officeId: string | undefined = res.data.processId;
|
||||
const officeIdNot: string | undefined = res.data.processData['idNot'];
|
||||
if (!officeId || !officeIdNot) {
|
||||
console.error("DeedTypesCreate: officeId or officeIdNot is undefined - office.processData.idNot is missing");
|
||||
return;
|
||||
}
|
||||
|
||||
// TODO: We should update the type definition to be able to use validation again
|
||||
// const deedType = DeedType.hydrate<DeedType>({
|
||||
// name: values["name"],
|
||||
// description: values["description"],
|
||||
// office: Office.hydrate<Office>({
|
||||
// idNot: officeId,
|
||||
// }),
|
||||
// });
|
||||
// try {
|
||||
// await validateOrReject(deedType, { groups: ["createDeedType"], forbidUnknownValues: true });
|
||||
// } catch (validationErrors: Array<ValidationError> | any) {
|
||||
// console.log("validationErrors", validationErrors);
|
||||
// setValidationError(Array.isArray(validationErrors) ? validationErrors : []);
|
||||
// return;
|
||||
// }
|
||||
|
||||
const deedTypeData: any = {
|
||||
name: values["name"],
|
||||
description: values["description"],
|
||||
office: {
|
||||
uid: officeId,
|
||||
idNot: officeIdNot,
|
||||
}
|
||||
};
|
||||
|
||||
@ -61,15 +78,18 @@ export default function DeedTypesCreate(props: IProps) {
|
||||
title: "Succès !",
|
||||
description: "Type d'acte créé avec succès"
|
||||
});
|
||||
const deedTypeUid = processCreated.processId;
|
||||
// Remove ':0' suffix from processId for URL navigation
|
||||
const urlId = deedTypeUid.replace(/:0$/, '');
|
||||
router.push(
|
||||
Module.getInstance()
|
||||
.get()
|
||||
.modules.pages.DeedTypes.pages.DeedTypesInformations.props.path.replace("[uid]", processCreated.processData.uid),
|
||||
.modules.pages.DeedTypes.pages.DeedTypesInformations.props.path.replace("[uid]", urlId),
|
||||
);
|
||||
LoaderService.getInstance().hide();
|
||||
});
|
||||
} catch (validationErrors: Array<ValidationError> | any) {
|
||||
setValidationError(validationErrors as ValidationError[]);
|
||||
setValidationError(Array.isArray(validationErrors) ? validationErrors : []);
|
||||
return;
|
||||
}
|
||||
},
|
||||
@ -106,12 +126,12 @@ export default function DeedTypesCreate(props: IProps) {
|
||||
<TextField
|
||||
name="name"
|
||||
placeholder="Nom de l'acte"
|
||||
validationError={validationError.find((error) => error.property === "name")}
|
||||
validationError={Array.isArray(validationError) ? validationError.find((error) => error.property === "name") : undefined}
|
||||
/>
|
||||
<TextAreaField
|
||||
name="description"
|
||||
placeholder="Description"
|
||||
validationError={validationError.find((error) => error.property === "description")}
|
||||
validationError={Array.isArray(validationError) ? validationError.find((error) => error.property === "description") : undefined}
|
||||
/>
|
||||
<div className={classes["buttons-container"]}>
|
||||
<Button variant={EButtonVariant.PRIMARY} styletype={EButtonstyletype.OUTLINED} onClick={onCancel}>
|
||||
|
@ -16,6 +16,7 @@ import classes from "./classes.module.scss";
|
||||
|
||||
import DeedTypeService from "src/common/Api/LeCoffreApi/sdk/DeedTypeService";
|
||||
import LoaderService from "src/common/Api/LeCoffreApi/sdk/Loader/LoaderService";
|
||||
import MessageBus from "src/sdk/MessageBus";
|
||||
|
||||
export default function DeedTypesEdit() {
|
||||
const router = useRouter();
|
||||
@ -31,10 +32,11 @@ export default function DeedTypesEdit() {
|
||||
async function getDeedType() {
|
||||
if (!deedTypeUid) return;
|
||||
LoaderService.getInstance().show();
|
||||
DeedTypeService.getDeedTypeByUid(deedTypeUid as string).then((process: any) => {
|
||||
if (process) {
|
||||
const deedType: any = process.processData;
|
||||
setDeedTypeSelected(deedType);
|
||||
// deedTypeUid comes from URL without ':0' suffix, add it back for API calls
|
||||
const processId = (deedTypeUid as string) + ':0';
|
||||
MessageBus.getInstance().getProcessData(processId).then((processData: any) => {
|
||||
if (processData) {
|
||||
setDeedTypeSelected(processData);
|
||||
}
|
||||
LoaderService.getInstance().hide();
|
||||
});
|
||||
@ -47,24 +49,28 @@ export default function DeedTypesEdit() {
|
||||
setIsConfirmModalVisible(false);
|
||||
}, []);
|
||||
|
||||
const onSubmitHandler = useCallback(
|
||||
async (e: React.FormEvent<HTMLFormElement> | null, values: { [key: string]: string | undefined }) => {
|
||||
const deedType = DeedType.hydrate<DeedType>({
|
||||
uid: deedTypeUid as string,
|
||||
name: values["name"],
|
||||
description: values["description"],
|
||||
});
|
||||
try {
|
||||
await deedType.validateOrReject?.({ groups: ["updateDeedType"], forbidUnknownValues: true });
|
||||
} catch (validationErrors: Array<ValidationError> | any) {
|
||||
if (!Array.isArray(validationErrors)) return;
|
||||
setValidationError(validationErrors as ValidationError[]);
|
||||
return;
|
||||
}
|
||||
const onSubmitHandler = async (e: React.FormEvent<HTMLFormElement> | null, values: { [key: string]: string | undefined }) => {
|
||||
// const deedType = DeedType.hydrate<DeedType>({
|
||||
// name: values["name"],
|
||||
// description: values["description"],
|
||||
// });
|
||||
|
||||
// try {
|
||||
// await deedType.validateOrReject?.({ groups: ["updateDeedType"], forbidUnknownValues: true });
|
||||
// } catch (validationErrors: Array<ValidationError> | any) {
|
||||
// if (!Array.isArray(validationErrors)) return;
|
||||
// setValidationError(validationErrors as ValidationError[]);
|
||||
// return;
|
||||
// }
|
||||
|
||||
try {
|
||||
LoaderService.getInstance().show();
|
||||
DeedTypeService.getDeedTypeByUid(deedTypeUid as string).then(async (process: any) => {
|
||||
// deedTypeUid comes from URL without ':0' suffix, add it back for API calls
|
||||
const processId = (deedTypeUid as string) + ':0';
|
||||
|
||||
const process = await MessageBus.getInstance().getProcessData(processId);
|
||||
if (process) {
|
||||
console.log('process', process);
|
||||
// New data
|
||||
const newData: any = {
|
||||
name: values["name"],
|
||||
@ -72,26 +78,23 @@ export default function DeedTypesEdit() {
|
||||
};
|
||||
|
||||
// Merge process data with new data & update process
|
||||
process.processData.name = newData.name;
|
||||
process.processData.description = newData.description;
|
||||
await DeedTypeService.updateDeedType(process, newData);
|
||||
process[processId].name = newData.name;
|
||||
process[processId].description = newData.description;
|
||||
await DeedTypeService.updateDeedType(processId, newData);
|
||||
|
||||
router.push(
|
||||
Module.getInstance()
|
||||
.get()
|
||||
.modules.pages.DeedTypes.pages.DeedTypesInformations.props.path.replace("[uid]", deedTypeUid as string),
|
||||
);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Error updating deed type:', error);
|
||||
// Handle error appropriately
|
||||
} finally {
|
||||
LoaderService.getInstance().hide();
|
||||
}
|
||||
});
|
||||
} catch (validationErrors) {
|
||||
if (!Array.isArray(validationErrors)) return;
|
||||
setValidationError(validationErrors as ValidationError[]);
|
||||
return;
|
||||
}
|
||||
},
|
||||
[deedTypeUid, router],
|
||||
);
|
||||
};
|
||||
|
||||
const onFieldChange = useCallback((name: string, field: any) => {
|
||||
setHasChanged(true);
|
||||
|
@ -21,6 +21,7 @@ import classes from "./classes.module.scss";
|
||||
import DeedTypeService from "src/common/Api/LeCoffreApi/sdk/DeedTypeService";
|
||||
import DocumentTypeService from "src/common/Api/LeCoffreApi/sdk/DocumentTypeService";
|
||||
import LoaderService from "src/common/Api/LeCoffreApi/sdk/Loader/LoaderService";
|
||||
import MessageBus from "src/sdk/MessageBus";
|
||||
|
||||
type IProps = {};
|
||||
export default function DeedTypesInformations(props: IProps) {
|
||||
@ -52,7 +53,9 @@ export default function DeedTypesInformations(props: IProps) {
|
||||
|
||||
const deleteDeedType = useCallback(async () => {
|
||||
LoaderService.getInstance().show();
|
||||
DeedTypeService.getDeedTypeByUid(deedTypeUid as string).then(async (process: any) => {
|
||||
// deedTypeUid comes from URL without ':0' suffix, add it back for API calls
|
||||
const processId = (deedTypeUid as string) + ':0';
|
||||
MessageBus.getInstance().getProcessData(processId).then(async (process: any) => {
|
||||
if (process) {
|
||||
// New data
|
||||
const newData: any = {
|
||||
@ -80,9 +83,12 @@ export default function DeedTypesInformations(props: IProps) {
|
||||
if (!deedTypeUid) return;
|
||||
|
||||
setSelectedDocuments([]);
|
||||
DeedTypeService.getDeedTypeByUid(deedTypeUid as string).then((process: any) => {
|
||||
// deedTypeUid comes from URL without ':0' suffix, add it back for API calls
|
||||
const processId = (deedTypeUid as string) + ':0';
|
||||
MessageBus.getInstance().getProcessData(processId).then((process: any) => {
|
||||
if (process) {
|
||||
const deedType: any = process.processData;
|
||||
console.log('[DeedTypesInformations] process', process);
|
||||
const deedType: any = process;
|
||||
setDeedTypeSelected(deedType);
|
||||
|
||||
if (!deedType.document_types) return;
|
||||
@ -95,15 +101,17 @@ export default function DeedTypesInformations(props: IProps) {
|
||||
})
|
||||
.sort((a: any, b: any) => a.label.localeCompare(b.label));
|
||||
setSelectedDocuments(documentsOptions);
|
||||
} else {
|
||||
console.warn('[DeedTypesInformations] process not found:', processId);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
async function getDocuments() {
|
||||
function getDocuments() {
|
||||
setAvailableDocuments([]);
|
||||
DocumentTypeService.getDocumentTypes().then((processes: any[]) => {
|
||||
if (processes.length) {
|
||||
const documents: any[] = processes.map((process: any) => process.processData);
|
||||
DocumentTypeService.getDocumentTypes((processes: Record<string, any>) => {
|
||||
const documents = Object.values(processes);
|
||||
if (documents.length) {
|
||||
setAvailableDocuments(documents);
|
||||
}
|
||||
});
|
||||
@ -120,13 +128,16 @@ export default function DeedTypesInformations(props: IProps) {
|
||||
[openSaveModal],
|
||||
);
|
||||
|
||||
const saveDocumentTypes = useCallback(() => {
|
||||
const saveDocumentTypes = useCallback(async () => {
|
||||
LoaderService.getInstance().show();
|
||||
DeedTypeService.getDeedTypeByUid(deedTypeUid as string).then(async (process: any) => {
|
||||
if (process) {
|
||||
const deedType: any = process.processData;
|
||||
// deedTypeUid comes from URL without ':0' suffix, add it back for API calls
|
||||
const processId = (deedTypeUid as string) + ':0';
|
||||
console.log('[DeedTypesInformations] processId', processId);
|
||||
const deedType = (await MessageBus.getInstance().getProcessData(processId))[processId];
|
||||
if (deedType) {
|
||||
console.log('[DeedTypesInformations] deedType', deedType);
|
||||
|
||||
let document_types: any[] = deedType.document_types;
|
||||
let document_types: any[] = deedType['document_types'];
|
||||
if (!document_types) {
|
||||
document_types = [];
|
||||
}
|
||||
@ -138,14 +149,15 @@ export default function DeedTypesInformations(props: IProps) {
|
||||
document_types: document_types
|
||||
};
|
||||
|
||||
// Merge process data with new data & update process
|
||||
process.processData.document_types = newData.document_types;
|
||||
await DeedTypeService.updateDeedType(process, newData);
|
||||
console.log('[DeedTypesInformations] newData', newData);
|
||||
|
||||
await DeedTypeService.updateDeedType(processId, newData);
|
||||
|
||||
LoaderService.getInstance().hide();
|
||||
closeSaveModal();
|
||||
} else {
|
||||
console.warn('[DeedTypesInformations] process not found:', processId);
|
||||
}
|
||||
});
|
||||
}, [closeSaveModal, deedTypeUid, selectedDocuments]);
|
||||
|
||||
const onDocumentChangeHandler = useCallback((options: IOption[] | null) => {
|
||||
|
@ -17,9 +17,10 @@ import EmailReminder from "./EmailReminder";
|
||||
|
||||
import FolderService from "src/common/Api/LeCoffreApi/sdk/FolderService";
|
||||
import LoaderService from "src/common/Api/LeCoffreApi/sdk/Loader/LoaderService";
|
||||
import MessageBus from "src/sdk/MessageBus";
|
||||
|
||||
type IProps = {
|
||||
folder: OfficeFolder;
|
||||
folder: { processId: string, FolderData: OfficeFolder};
|
||||
anchorStatus: AnchorStatus;
|
||||
};
|
||||
|
||||
@ -30,7 +31,7 @@ export default function ClientView(props: IProps) {
|
||||
|
||||
const customers: ICustomer[] = useMemo(
|
||||
() => {
|
||||
return folder?.customers
|
||||
return folder?.FolderData?.customers
|
||||
?.map((customer: any) => ({
|
||||
id: customer.uid ?? '',
|
||||
...customer,
|
||||
@ -62,16 +63,17 @@ export default function ClientView(props: IProps) {
|
||||
|
||||
const handleClientDelete = useCallback(
|
||||
(customerUid: string) => {
|
||||
if (!folder.uid) return;
|
||||
if (!folder.processId) return;
|
||||
LoaderService.getInstance().show();
|
||||
FolderService.getFolderByUid(folder.uid).then((process: any) => {
|
||||
MessageBus.getInstance().getProcessData(folder.processId).then((process: { [key: string]: any }) => {
|
||||
if (process) {
|
||||
const folder: any = process.processData;
|
||||
const processId = folder.processId;
|
||||
const folderData = process[processId];
|
||||
|
||||
// FilterBy customerUid
|
||||
const customers = folder.customers.filter((uid: string) => uid !== customerUid);
|
||||
const customers = folderData.customers.filter((uid: string) => uid !== customerUid);
|
||||
|
||||
FolderService.updateFolder(process, { customers: customers }).then(() => {
|
||||
FolderService.updateFolder(processId, { customers: customers }).then(() => {
|
||||
LoaderService.getInstance().hide();
|
||||
window.location.reload();
|
||||
});
|
||||
@ -90,7 +92,7 @@ export default function ClientView(props: IProps) {
|
||||
<Link
|
||||
href={Module.getInstance()
|
||||
.get()
|
||||
.modules.pages.Folder.pages.AddClient.props.path.replace("[folderUid]", folder.uid ?? "")}>
|
||||
.modules.pages.Folder.pages.AddClient.props.path.replace("[folderUid]", folder.processId ?? "")}>
|
||||
<Button
|
||||
size={EButtonSize.MD}
|
||||
rightIcon={<UserPlusIcon />}
|
||||
@ -106,17 +108,17 @@ export default function ClientView(props: IProps) {
|
||||
<ClientBox
|
||||
customer={customer}
|
||||
anchorStatus={anchorStatus}
|
||||
folderUid={folder.uid}
|
||||
folderUid={folder.processId}
|
||||
onDelete={handleClientDelete}
|
||||
customerNote={folder.notes!.find((value: any) => value.customer?.uid === customer.uid) ?? null}
|
||||
customerNote={folder.FolderData?.notes?.find((value: any) => value.customer?.uid === customer.uid) ?? null}
|
||||
/>
|
||||
<div className={classes["button-container"]}>
|
||||
{anchorStatus === AnchorStatus.NOT_ANCHORED && (
|
||||
<Link
|
||||
href={Module.getInstance()
|
||||
.get()
|
||||
.modules.pages.Folder.pages.AskDocument.props.path.replace("[folderUid]", folder.uid ?? "")
|
||||
.replace("[customerUid]", customer.uid ?? "")}>
|
||||
.modules.pages.Folder.pages.AskDocument.props.path.replace("[folderUid]", folder.processId ?? "")
|
||||
.replace("[customerUid]", customer?.uid ?? "")}>
|
||||
<Button rightIcon={<DocumentIcon />} variant={EButtonVariant.PRIMARY} fullwidth>
|
||||
Demander un document
|
||||
</Button>
|
||||
@ -126,7 +128,7 @@ export default function ClientView(props: IProps) {
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{customer.uid && folder.uid && <DocumentTables customerUid={customer.uid} folderUid={folder.uid} />}
|
||||
{customer?.uid && folder.processId && <DocumentTables customerUid={customer.uid} folderUid={folder.processId} />}
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
|
@ -25,40 +25,36 @@ export default function Folder() {
|
||||
|
||||
useEffect(() => {
|
||||
// TODO: review
|
||||
FolderService.getFoldersBy({ status: EFolderStatus.LIVE }).then((processes: any[]) => {
|
||||
if (processes.length > 0) {
|
||||
let folders: any[] = processes.map((process: any) => process.processData);
|
||||
FolderService.getFoldersBy({ status: EFolderStatus.LIVE }).then((processes: Record<string, any>) => {
|
||||
if (Object.keys(processes).length > 0) {
|
||||
let folders: any[] = Object.entries(processes).map(([processId, process]) => {
|
||||
const res = {
|
||||
...process,
|
||||
processId: processId
|
||||
};
|
||||
return res;
|
||||
});
|
||||
|
||||
// OrderBy created_at desc
|
||||
folders = folders.sort((a: any, b: any) => new Date(b.created_at).getTime() - new Date(a.created_at).getTime());
|
||||
|
||||
if (folders.length > 0) {
|
||||
router.push(
|
||||
Module.getInstance()
|
||||
.get()
|
||||
.modules.pages.Folder.pages.FolderInformation.props.path.replace("[folderUid]", folders[0].uid)
|
||||
);
|
||||
}
|
||||
}
|
||||
});
|
||||
const folderUid = folders[0]?.processId;
|
||||
|
||||
if (!folderUid) {
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
Folders.getInstance()
|
||||
.get({
|
||||
q: {
|
||||
where: { status: EFolderStatus.LIVE },
|
||||
orderBy: { created_at: "desc" },
|
||||
},
|
||||
})
|
||||
.then((folders) => {
|
||||
if (folders.length > 0)
|
||||
router.push(
|
||||
Module.getInstance()
|
||||
.get()
|
||||
.modules.pages.Folder.pages.FolderInformation.props.path.replace("[folderUid]", folders[0]?.uid ?? ""),
|
||||
.modules.pages.Folder.pages.FolderInformation.props.path.replace("[folderUid]", folderUid as string)
|
||||
);
|
||||
}
|
||||
} else {
|
||||
console.debug('[Folder] No folders found');
|
||||
}
|
||||
});
|
||||
*/
|
||||
}, [router]);
|
||||
return (
|
||||
<DefaultNotaryDashboard title={"Dossier"} mobileBackText={"Liste des dossiers"}>
|
||||
|
@ -7,6 +7,7 @@ import HelpBox from "@Front/Components/Elements/HelpBox";
|
||||
import DefaultDoubleSidePage from "@Front/Components/LayoutTemplates/DefaultDoubleSidePage";
|
||||
import Module from "@Front/Config/Module";
|
||||
import UserStore from "@Front/Stores/UserStore";
|
||||
import CookieService from "@Front/Services/CookieService/CookieService";
|
||||
import Image from "next/image";
|
||||
import { useRouter } from "next/router";
|
||||
import React, { useEffect, useState } from "react";
|
||||
@ -21,16 +22,10 @@ import MessageBus from "src/sdk/MessageBus";
|
||||
import Iframe from "src/sdk/Iframe";
|
||||
|
||||
import LoaderService from "src/common/Api/LeCoffreApi/sdk/Loader/LoaderService";
|
||||
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 OfficeRoleService from "src/common/Api/LeCoffreApi/sdk/OfficeRoleService";
|
||||
import CollaboratorService from "src/common/Api/LeCoffreApi/sdk/CollaboratorService";
|
||||
import { DEFAULT_STORAGE_URLS, DEFAULT_VALIDATOR_ID } from "@Front/Config/AppConstants";
|
||||
import { ProgressInfo } from "src/common/Api/LeCoffreApi/sdk/ImportData";
|
||||
|
||||
export default function LoginCallBack() {
|
||||
const router = useRouter();
|
||||
const [idNotUser, setIdNotUser] = useState<any>(null);
|
||||
const [isAuthModalOpen, setIsAuthModalOpen] = useState(false);
|
||||
const [isConnected, setIsConnected] = useState(false);
|
||||
|
||||
@ -43,169 +38,26 @@ export default function LoginCallBack() {
|
||||
description: ''
|
||||
});
|
||||
|
||||
const getOffice = async (idNotUser: any) => {
|
||||
return await new Promise<any>((resolve: (office: any) => void) => {
|
||||
OfficeService.getOffices().then((processes: any[]) => {
|
||||
const officeFound: any = processes.length > 0 ? processes.find((office: any) => office.processData.idNot === idNotUser.office.idNot) : null;
|
||||
if (officeFound) {
|
||||
resolve(officeFound);
|
||||
} else {
|
||||
// Some info must be here or have some value, just to be sure
|
||||
if (!idNotUser.office.office_status || idNotUser.office.office_status !== 'ACTIVATED') {
|
||||
console.error(`[LoginCallback] office_status is not ACTIVATED for idNot ${idNotUser.office.idNot}`);
|
||||
const waitForUserInfo = (): Promise<any> => {
|
||||
return new Promise((resolve, reject) => {
|
||||
if (UserStore.instance.getUser()) {
|
||||
resolve(UserStore.instance.getUser());
|
||||
return;
|
||||
}
|
||||
|
||||
// I guess if we don't have crpcen that's also a big problem
|
||||
if (!idNotUser.office.crpcen) {
|
||||
console.error(`[LoginCallback] crpcen is not set for idNot ${idNotUser.office.idNot}`);
|
||||
return;
|
||||
// Poll for userInfo every 100ms
|
||||
const checkInterval = setInterval(() => {
|
||||
if (UserStore.instance.getUser()) {
|
||||
clearInterval(checkInterval);
|
||||
resolve(UserStore.instance.getUser());
|
||||
}
|
||||
}, 100);
|
||||
|
||||
// We create office
|
||||
const officeData: any = {
|
||||
idNot: idNotUser.office.idNot,
|
||||
name: idNotUser.office.name,
|
||||
crpcen: idNotUser.office.crpcen,
|
||||
address: {
|
||||
create: {
|
||||
address: idNotUser.office.address.address,
|
||||
zip_code: idNotUser.office.address.zip_code,
|
||||
city: idNotUser.office.address.city
|
||||
}
|
||||
},
|
||||
office_status: idNotUser.office.office_status // must be ACTIVATED though
|
||||
};
|
||||
|
||||
Auth.getInstance().getIdNotUserForOffice(idNotUser.office.idNot).then((users: any) => {
|
||||
console.log('users : ', users);
|
||||
const activeUsers = users.result.filter((user: any) => user.activite === 'En exercice');
|
||||
let officeCollaborators: any[] = [];
|
||||
for (const user of activeUsers) {
|
||||
CollaboratorService.getCollaboratorByUid(user.uid).then((collaborator: any) => {
|
||||
console.log('collaborator : ', collaborator);
|
||||
officeCollaborators.push(collaborator);
|
||||
});
|
||||
}
|
||||
|
||||
OfficeService.createOffice(officeData, officeCollaborators, DEFAULT_VALIDATOR_ID, [...DEFAULT_STORAGE_URLS]).then((process: any) => {
|
||||
if (process) {
|
||||
const office: any = process.processData;
|
||||
resolve(office);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
return;
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
const getCollaborator = async (idNotUser: any) => {
|
||||
return await new Promise<any>(async (resolve: (role: any) => void) => {
|
||||
const processFound: any | null = await CollaboratorService.getCollaboratorBy({ idNot: idNotUser.idNot });
|
||||
if (processFound) {
|
||||
console.log('Found a collaborator for idNot', idNotUser.idNot);
|
||||
// TODO: check if the collaborator is in the office process
|
||||
const office: any = await getOffice(idNotUser);
|
||||
// Take the role of the collaborator
|
||||
MessageBus.getInstance().getRolesForProcess(processFound.processId).then((roles: any) => {
|
||||
console.log('roles : ', roles);
|
||||
// We should find one pairing id in the role 'owner'
|
||||
const owners = roles['owner'].members;
|
||||
if (owners.length !== 1) {
|
||||
console.error('[LoginCallback] owner should have 1 member');
|
||||
return;
|
||||
}
|
||||
const ownerPairingId = owners[0];
|
||||
// Now we can check if the owner pairing id is in the office roles
|
||||
MessageBus.getInstance().getRolesForProcess(office.processId).then((officeRoles: any) => {
|
||||
const officeOwners = officeRoles['owner'].members;
|
||||
if (!officeOwners.includes(ownerPairingId)) {
|
||||
// We add the newly created collaborator to the office roles
|
||||
OfficeService.addCollaborators(office, officeRoles, [ownerPairingId]).then((process: any) => {
|
||||
resolve(processFound);
|
||||
});
|
||||
} else {
|
||||
// Nothing to do
|
||||
resolve(processFound);
|
||||
}
|
||||
});
|
||||
});
|
||||
} else {
|
||||
console.log('No collaborator found for idNot', idNotUser.idNot);
|
||||
const office: any = await getOffice(idNotUser);
|
||||
|
||||
const role: any = (await RoleService.getRoles())
|
||||
.map((process: any) => process.processData)
|
||||
.find((role: any) => role.name === idNotUser.role.name);
|
||||
|
||||
const officeRole: any = (await OfficeRoleService.getOfficeRoles())
|
||||
.map((process: any) => process.processData)
|
||||
.filter((officeRole: any) => officeRole.office.uid === office.processData.uid)
|
||||
.find((officeRole: any) => officeRole.name === idNotUser.office_role.name);
|
||||
|
||||
if (!office || !role || !officeRole) {
|
||||
LoaderService.getInstance().hide();
|
||||
setShowProgress(true);
|
||||
|
||||
await ImportData.import(office, DEFAULT_VALIDATOR_ID, (info: ProgressInfo) => {
|
||||
setProgressInfo(info);
|
||||
});
|
||||
|
||||
setShowProgress(false);
|
||||
LoaderService.getInstance().show();
|
||||
}
|
||||
|
||||
const collaboratorData: any = {
|
||||
idNot: idNotUser.idNot,
|
||||
contact: idNotUser.contact,
|
||||
office: {
|
||||
uid: office.uid
|
||||
},
|
||||
role: {
|
||||
uid: role.uid
|
||||
},
|
||||
office_role: {
|
||||
uid: officeRole.uid
|
||||
}
|
||||
};
|
||||
|
||||
CollaboratorService.createCollaborator(collaboratorData, DEFAULT_VALIDATOR_ID).then((newCollaborator: any) => {
|
||||
if (newCollaborator) {
|
||||
// Now that we created the collaborator, we must check that it's in the office roles (probably not)
|
||||
MessageBus.getInstance().getRolesForProcess(newCollaborator.processId).then((roles: any) => {
|
||||
console.log('roles : ', roles);
|
||||
// We should have our own pairing id in roles['owner']
|
||||
const owner = roles['owner'].members;
|
||||
if (owner.length !== 1) {
|
||||
console.error('[LoginCallback] owner should have 1 member');
|
||||
return;
|
||||
}
|
||||
const ownerPairingId = owner[0];
|
||||
if (ownerPairingId !== newCollaborator.processData.uid) {
|
||||
console.error('[LoginCallback] owner pairing id is not the same as the collaborator uid');
|
||||
return;
|
||||
}
|
||||
|
||||
// is ownerPairingId in roles for the office process?
|
||||
MessageBus.getInstance().getRolesForProcess(office.processId).then((officeRoles: any) => {
|
||||
const officeOwners = officeRoles['owner'].members;
|
||||
if (!officeOwners.includes(ownerPairingId)) {
|
||||
// We add the newly created collaborator to the office roles
|
||||
OfficeService.addCollaborators(office, officeRoles, [ownerPairingId]).then((process: any) => {
|
||||
resolve(newCollaborator);
|
||||
});
|
||||
} else {
|
||||
// Nothing to do
|
||||
resolve(newCollaborator);
|
||||
}
|
||||
});
|
||||
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
// Timeout after 60 seconds
|
||||
setTimeout(() => {
|
||||
clearInterval(checkInterval);
|
||||
reject(new Error('Timeout waiting for user info'));
|
||||
}, 60000);
|
||||
});
|
||||
};
|
||||
|
||||
@ -216,8 +68,8 @@ export default function LoginCallBack() {
|
||||
// TODO: review
|
||||
// HACK: If start with http://local.lecoffreio.4nkweb:3000/authorized-client
|
||||
// Replace with http://localhost:3000/authorized-client
|
||||
if (window.location.href.startsWith('http://local.4nkweb.com')) {
|
||||
window.location.href = window.location.href.replace('http://local.4nkweb.com:3000/authorized-client', 'http://localhost:3000/authorized-client');
|
||||
if (window.location.href.startsWith('http://local.lecoffreio.4nkweb')) {
|
||||
window.location.href = window.location.href.replace('http://local.lecoffreio.4nkweb:3000/authorized-client', 'http://localhost:3000/authorized-client');
|
||||
return;
|
||||
}
|
||||
|
||||
@ -230,22 +82,34 @@ export default function LoginCallBack() {
|
||||
window.history.replaceState({}, document.title, rootUrl);
|
||||
}
|
||||
|
||||
const user: any = await Auth.getInstance().getIdNotUser(code as string);
|
||||
setIdNotUser(user.idNotUser);
|
||||
setIsAuthModalOpen(true);
|
||||
console.log('[LoginCallback] idNotUser', idNotUser);
|
||||
/*
|
||||
const token: any = null;
|
||||
if (!token) return router.push(Module.getInstance().get().modules.pages.Login.props.path);
|
||||
await UserStore.instance.connect(token.accessToken, token.refreshToken);
|
||||
const jwt = JwtService.getInstance().decodeJwt();
|
||||
if (!jwt) return router.push(Module.getInstance().get().modules.pages.Login.props.path + "?error=1");
|
||||
if (jwt.rules && !jwt.rules.includes("GET folders")) {
|
||||
return router.push(Module.getInstance().get().modules.pages.Subscription.pages.New.props.path);
|
||||
const user: any = await Auth.getInstance().idNotAuth(code as string);
|
||||
|
||||
// Extract both user data and auth token from the response
|
||||
const { idNotUser, authToken } = user;
|
||||
|
||||
if (!authToken) {
|
||||
console.error('[LoginCallback] No authToken received from backend');
|
||||
return router.push(Module.getInstance().get().modules.pages.Login.props.path + "?error=1");
|
||||
}
|
||||
|
||||
// Store the auth token for API authentication
|
||||
// TODO The authToken is just a uuid for now, it's very broken
|
||||
CookieService.getInstance().setCookie("leCoffreAccessToken", authToken);
|
||||
|
||||
// Test that we can get user info and the authToken works
|
||||
// TODO test that what's returned is identical to what we got before
|
||||
const userInfoResponse = await Auth.getInstance().getIdNotUser();
|
||||
console.log('[LoginCallback] userInfoResponse:', userInfoResponse);
|
||||
if (!userInfoResponse || !userInfoResponse.success || !userInfoResponse.data) {
|
||||
console.error('[LoginCallback] No userInfo received from backend');
|
||||
return router.push(Module.getInstance().get().modules.pages.Login.props.path + "?error=1");
|
||||
}
|
||||
|
||||
// Store user info as a cookie
|
||||
CookieService.getInstance().setCookie("leCoffreUserInfo", JSON.stringify(userInfoResponse.data));
|
||||
setIsAuthModalOpen(true);
|
||||
//return router.push(Module.getInstance().get().modules.pages.Folder.props.path);
|
||||
*/
|
||||
console.log('[LoginCallback] authToken stored successfully');
|
||||
|
||||
return;
|
||||
} catch (e: any) {
|
||||
if (e.http_status === 401 && e.message === "Email not found") {
|
||||
@ -257,21 +121,6 @@ export default function LoginCallBack() {
|
||||
return router.push(Module.getInstance().get().modules.pages.Login.props.path + "?error=1");
|
||||
}
|
||||
}
|
||||
/*
|
||||
const refreshToken = CookieService.getInstance().getCookie("leCoffreRefreshToken");
|
||||
if (!refreshToken) return router.push(Module.getInstance().get().modules.pages.Login.props.path + "?error=1");
|
||||
const isTokenRefreshed = await JwtService.getInstance().refreshToken(refreshToken);
|
||||
const jwt = JwtService.getInstance().decodeJwt();
|
||||
if (!jwt) return router.push(Module.getInstance().get().modules.pages.Login.props.path + "?error=1");
|
||||
if (!jwt.rules.includes("GET folders")) {
|
||||
return router.push(Module.getInstance().get().modules.pages.Subscription.pages.New.props.path);
|
||||
}
|
||||
if (isTokenRefreshed) {
|
||||
//setIsAuthModalOpen(true);
|
||||
//return router.push(Module.getInstance().get().modules.pages.Folder.props.path);
|
||||
return;
|
||||
}
|
||||
*/
|
||||
return router.push(Module.getInstance().get().modules.pages.Login.props.path + "?error=2");
|
||||
}
|
||||
getUser();
|
||||
@ -354,23 +203,110 @@ export default function LoginCallBack() {
|
||||
LoaderService.getInstance().show();
|
||||
MessageBus.getInstance().initMessageListener();
|
||||
MessageBus.getInstance().isReady().then(async () => {
|
||||
const collaborator: any = await getCollaborator(idNotUser);
|
||||
if (!UserStore.instance.connect(collaborator)) {
|
||||
try {
|
||||
const userInfo = await waitForUserInfo();
|
||||
if (!userInfo) {
|
||||
console.error('[LoginCallback] No userInfo received from backend');
|
||||
return router.push(Module.getInstance().get().modules.pages.Login.props.path + "?error=1");
|
||||
}
|
||||
// console.log('userInfo : ', userInfo);
|
||||
|
||||
// Here we are now authenticated with idNot, we have our idnot user info
|
||||
// We also have a device and it should be paired
|
||||
// What we may not have yet is a collaborator process
|
||||
// Office may not have a process too
|
||||
let collaboratorProcess: { processId: string, processData: { [key: string]: any } } | null = null;
|
||||
let officeProcess: { processId: string, processData: { [key: string]: any } } | null = null;
|
||||
|
||||
// Initialize collaborator process
|
||||
try {
|
||||
// Wait for pairing ID to be available before proceeding
|
||||
const pairingId = await MessageBus.getInstance().getPairingId();
|
||||
console.log('[LoginCallback] Pairing ID obtained:', pairingId);
|
||||
// Check if we are part of the right collaborator process
|
||||
const myCollaboratorProcessesData = await MessageBus.getInstance().getProcessesDecoded((processId: string, values: { [key: string]: any }) => {
|
||||
return values['utype'] === 'collaborator'
|
||||
&& values['idNot'] === userInfo.idNot
|
||||
&& values['isDeleted'] === 'false';
|
||||
});
|
||||
if (myCollaboratorProcessesData && Object.keys(myCollaboratorProcessesData).length !== 0) {
|
||||
collaboratorProcess = { processId: Object.keys(myCollaboratorProcessesData)[0]!, processData: Object.values(myCollaboratorProcessesData)[0]! };
|
||||
} else {
|
||||
const res = await Auth.getInstance().getUserProcessByIdNot(pairingId);
|
||||
if (res.success) {
|
||||
collaboratorProcess = res.data;
|
||||
} else {
|
||||
console.error('[LoginCallback] Error getting collaborator process');
|
||||
router.push(Module.getInstance().get().modules.pages.Login.props.path + "?error=1");
|
||||
return;
|
||||
}
|
||||
// await new Promise(resolve => setTimeout(resolve, 100));
|
||||
}
|
||||
// If we're on a new device, signer should notice and add us to the process
|
||||
// TODO check that we're part of the collaborator process
|
||||
} catch (error: any) {
|
||||
console.error('[LoginCallback] Error getting collaborator process:', error);
|
||||
if (error.message === 'Timeout waiting for pairing ID') {
|
||||
console.error('[LoginCallback] Pairing ID not available after timeout');
|
||||
return router.push(Module.getInstance().get().modules.pages.Login.props.path + "?error=1");
|
||||
}
|
||||
// If we can't get collaborator process, we can't proceed
|
||||
return router.push(Module.getInstance().get().modules.pages.Login.props.path + "?error=1");
|
||||
}
|
||||
|
||||
// Initialize office process
|
||||
try {
|
||||
// Wait for pairing ID to be available before proceeding
|
||||
const pairingId = await MessageBus.getInstance().getPairingId();
|
||||
console.log('[LoginCallback] Pairing ID obtained:', pairingId);
|
||||
// Now we need to check for office process
|
||||
const myOfficeProcessesData = await MessageBus.getInstance().getProcessesDecoded((processId: string, values: { [key: string]: any }) => {
|
||||
return values['utype'] === 'office'
|
||||
&& values['idNot'] === userInfo.office.idNot
|
||||
&& values['isDeleted'] === 'false';
|
||||
});
|
||||
if (myOfficeProcessesData && Object.keys(myOfficeProcessesData).length !== 0) {
|
||||
officeProcess = { processId: Object.keys(myOfficeProcessesData)[0]!, processData: Object.values(myOfficeProcessesData)[0]! };
|
||||
} else {
|
||||
const res = await Auth.getInstance().getUserProcessByIdNot(pairingId);
|
||||
if (res.success) {
|
||||
officeProcess = res.data;
|
||||
} else {
|
||||
console.error('[LoginCallback] Error getting collaborator process');
|
||||
router.push(Module.getInstance().get().modules.pages.Login.props.path + "?error=1");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// TODO Check that we're part of the office process
|
||||
// For now we rely on the signer to get office data, for the sake of simplicity
|
||||
} catch (error: any) {
|
||||
console.error('[LoginCallback] Error getting office process:', error);
|
||||
return router.push(Module.getInstance().get().modules.pages.Login.props.path + "?error=1");
|
||||
}
|
||||
|
||||
// Verify both processes are initialized before proceeding
|
||||
if (!collaboratorProcess || !officeProcess) {
|
||||
console.error('[LoginCallback] Failed to initialize required processes');
|
||||
router.push(Module.getInstance().get().modules.pages.Login.props.path + "?error=1");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!UserStore.instance.connect(collaboratorProcess.processData, officeProcess.processData)) {
|
||||
console.error('[LoginCallback] collaborator not connected');
|
||||
router.push(Module.getInstance().get().modules.pages.Login.props.path + "?error=1");
|
||||
return;
|
||||
}
|
||||
|
||||
window.location.href = Module.getInstance().get().modules.pages.Folder.props.path;
|
||||
} catch (error) {
|
||||
console.error('[LoginCallback] Error waiting for user info or processing collaborator:', error);
|
||||
router.push(Module.getInstance().get().modules.pages.Login.props.path + "?error=1");
|
||||
} finally {
|
||||
MessageBus.getInstance().destroyMessageListener();
|
||||
LoaderService.getInstance().hide();
|
||||
|
||||
/*
|
||||
if (jwt.rules && !jwt.rules.includes("GET folders")) {
|
||||
router.push(Module.getInstance().get().modules.pages.Subscription.pages.New.props.path);
|
||||
}
|
||||
*/
|
||||
|
||||
window.location.href = Module.getInstance().get().modules.pages.Folder.props.path;
|
||||
return;
|
||||
});
|
||||
}, 100);
|
||||
}}
|
||||
|
Loading…
x
Reference in New Issue
Block a user