Compare commits
19 Commits
a6a67d4b7c
...
2213168f8e
Author | SHA1 | Date | |
---|---|---|---|
![]() |
2213168f8e | ||
![]() |
6ec7d8318e | ||
![]() |
cfad52c5ec | ||
![]() |
4c67ac5986 | ||
![]() |
3f413a885f | ||
![]() |
cf51fff97a | ||
![]() |
429d3243a4 | ||
![]() |
6f1f542dd2 | ||
![]() |
c8f7c3e08e | ||
![]() |
e4d8064abc | ||
![]() |
87483af243 | ||
![]() |
e081585fd9 | ||
![]() |
58d421ae57 | ||
![]() |
371ff69a35 | ||
![]() |
108419b381 | ||
![]() |
b97bbcd087 | ||
![]() |
0536b98ea8 | ||
![]() |
0986d60974 | ||
![]() |
a78666b4a9 |
1
.github/workflows/dev.yml
vendored
1
.github/workflows/dev.yml
vendored
@ -38,4 +38,5 @@ jobs:
|
|||||||
ssh: default
|
ssh: default
|
||||||
tags: |
|
tags: |
|
||||||
${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:latest
|
${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:latest
|
||||||
|
${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:dev
|
||||||
${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ gitea.sha }}
|
${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ gitea.sha }}
|
@ -9,6 +9,7 @@ const nextConfig = {
|
|||||||
// Will be available on both server and client
|
// Will be available on both server and client
|
||||||
NEXT_PUBLIC_BACK_API_PROTOCOL: process.env.NEXT_PUBLIC_BACK_API_PROTOCOL,
|
NEXT_PUBLIC_BACK_API_PROTOCOL: process.env.NEXT_PUBLIC_BACK_API_PROTOCOL,
|
||||||
NEXT_PUBLIC_BACK_API_HOST: process.env.NEXT_PUBLIC_BACK_API_HOST,
|
NEXT_PUBLIC_BACK_API_HOST: process.env.NEXT_PUBLIC_BACK_API_HOST,
|
||||||
|
NEXT_PUBLIC_BACK_API_PORT: process.env.NEXT_PUBLIC_BACK_API_PORT,
|
||||||
NEXT_PUBLIC_BACK_API_ROOT_URL: process.env.NEXT_PUBLIC_BACK_API_ROOT_URL,
|
NEXT_PUBLIC_BACK_API_ROOT_URL: process.env.NEXT_PUBLIC_BACK_API_ROOT_URL,
|
||||||
NEXT_PUBLIC_BACK_API_VERSION: process.env.NEXT_PUBLIC_BACK_API_VERSION,
|
NEXT_PUBLIC_BACK_API_VERSION: process.env.NEXT_PUBLIC_BACK_API_VERSION,
|
||||||
NEXT_PUBLIC_FRONT_APP_HOST: process.env.NEXT_PUBLIC_FRONT_APP_HOST,
|
NEXT_PUBLIC_FRONT_APP_HOST: process.env.NEXT_PUBLIC_FRONT_APP_HOST,
|
||||||
@ -26,6 +27,7 @@ const nextConfig = {
|
|||||||
serverRuntimeConfig: {
|
serverRuntimeConfig: {
|
||||||
NEXT_PUBLIC_BACK_API_PROTOCOL: process.env.NEXT_PUBLIC_BACK_API_PROTOCOL,
|
NEXT_PUBLIC_BACK_API_PROTOCOL: process.env.NEXT_PUBLIC_BACK_API_PROTOCOL,
|
||||||
NEXT_PUBLIC_BACK_API_HOST: process.env.NEXT_PUBLIC_BACK_API_HOST,
|
NEXT_PUBLIC_BACK_API_HOST: process.env.NEXT_PUBLIC_BACK_API_HOST,
|
||||||
|
NEXT_PUBLIC_BACK_API_PORT: process.env.NEXT_PUBLIC_BACK_API_PORT,
|
||||||
NEXT_PUBLIC_BACK_API_ROOT_URL: process.env.NEXT_PUBLIC_BACK_API_ROOT_URL,
|
NEXT_PUBLIC_BACK_API_ROOT_URL: process.env.NEXT_PUBLIC_BACK_API_ROOT_URL,
|
||||||
NEXT_PUBLIC_BACK_API_VERSION: process.env.NEXT_PUBLIC_BACK_API_VERSION,
|
NEXT_PUBLIC_BACK_API_VERSION: process.env.NEXT_PUBLIC_BACK_API_VERSION,
|
||||||
NEXT_PUBLIC_FRONT_APP_HOST: process.env.NEXT_PUBLIC_FRONT_APP_HOST,
|
NEXT_PUBLIC_FRONT_APP_HOST: process.env.NEXT_PUBLIC_FRONT_APP_HOST,
|
||||||
@ -43,6 +45,7 @@ const nextConfig = {
|
|||||||
env: {
|
env: {
|
||||||
NEXT_PUBLIC_BACK_API_PROTOCOL: process.env.NEXT_PUBLIC_BACK_API_PROTOCOL,
|
NEXT_PUBLIC_BACK_API_PROTOCOL: process.env.NEXT_PUBLIC_BACK_API_PROTOCOL,
|
||||||
NEXT_PUBLIC_BACK_API_HOST: process.env.NEXT_PUBLIC_BACK_API_HOST,
|
NEXT_PUBLIC_BACK_API_HOST: process.env.NEXT_PUBLIC_BACK_API_HOST,
|
||||||
|
NEXT_PUBLIC_BACK_API_PORT: process.env.NEXT_PUBLIC_BACK_API_PORT,
|
||||||
NEXT_PUBLIC_BACK_API_ROOT_URL: process.env.NEXT_PUBLIC_BACK_API_ROOT_URL,
|
NEXT_PUBLIC_BACK_API_ROOT_URL: process.env.NEXT_PUBLIC_BACK_API_ROOT_URL,
|
||||||
NEXT_PUBLIC_BACK_API_VERSION: process.env.NEXT_PUBLIC_BACK_API_VERSION,
|
NEXT_PUBLIC_BACK_API_VERSION: process.env.NEXT_PUBLIC_BACK_API_VERSION,
|
||||||
NEXT_PUBLIC_FRONT_APP_HOST: process.env.NEXT_PUBLIC_FRONT_APP_HOST,
|
NEXT_PUBLIC_FRONT_APP_HOST: process.env.NEXT_PUBLIC_FRONT_APP_HOST,
|
||||||
|
@ -7,6 +7,7 @@ import AbstractService from './AbstractService';
|
|||||||
import OfficeService from './OfficeService';
|
import OfficeService from './OfficeService';
|
||||||
import RoleService from './RoleService';
|
import RoleService from './RoleService';
|
||||||
import OfficeRoleService from './OfficeRoleService';
|
import OfficeRoleService from './OfficeRoleService';
|
||||||
|
import { DEFAULT_STORAGE_URLS } from '@Front/Config/AppConstants';
|
||||||
|
|
||||||
export default class CollaboratorService extends AbstractService {
|
export default class CollaboratorService extends AbstractService {
|
||||||
|
|
||||||
@ -33,7 +34,7 @@ export default class CollaboratorService extends AbstractService {
|
|||||||
|
|
||||||
const roles: any = {
|
const roles: any = {
|
||||||
demiurge: {
|
demiurge: {
|
||||||
members: [...[ownerId], validatorId],
|
members: [ownerId],
|
||||||
validation_rules: [],
|
validation_rules: [],
|
||||||
storages: []
|
storages: []
|
||||||
},
|
},
|
||||||
@ -41,28 +42,23 @@ export default class CollaboratorService extends AbstractService {
|
|||||||
members: [ownerId],
|
members: [ownerId],
|
||||||
validation_rules: [
|
validation_rules: [
|
||||||
{
|
{
|
||||||
quorum: 0.5,
|
quorum: 1,
|
||||||
fields: [...privateFields, 'roles', 'uid', 'utype'],
|
fields: [...privateFields, 'roles', 'uid', 'utype', 'isDeleted'],
|
||||||
min_sig_member: 1,
|
min_sig_member: 1,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
storages: []
|
storages: [...DEFAULT_STORAGE_URLS]
|
||||||
},
|
},
|
||||||
validator: {
|
validator: {
|
||||||
members: [validatorId],
|
members: [validatorId],
|
||||||
validation_rules: [
|
validation_rules: [
|
||||||
{
|
{
|
||||||
quorum: 0.5,
|
quorum: 1,
|
||||||
fields: ['idCertified', 'roles'],
|
fields: [...privateFields, 'roles', 'uid', 'utype', 'isDeleted'],
|
||||||
min_sig_member: 1,
|
min_sig_member: 1,
|
||||||
},
|
},
|
||||||
{
|
|
||||||
quorum: 0.0,
|
|
||||||
fields: [...privateFields],
|
|
||||||
min_sig_member: 0,
|
|
||||||
},
|
|
||||||
],
|
],
|
||||||
storages: []
|
storages: [...DEFAULT_STORAGE_URLS]
|
||||||
},
|
},
|
||||||
apophis: {
|
apophis: {
|
||||||
members: [ownerId],
|
members: [ownerId],
|
||||||
@ -265,26 +261,34 @@ export default class CollaboratorService extends AbstractService {
|
|||||||
|
|
||||||
if (process.processData.office) {
|
if (process.processData.office) {
|
||||||
const office: any = (await OfficeService.getOfficeByUid(process.processData.office.uid)).processData;
|
const office: any = (await OfficeService.getOfficeByUid(process.processData.office.uid)).processData;
|
||||||
process.processData.office = {
|
if (office) {
|
||||||
uid: office.uid,
|
process.processData.office = {
|
||||||
idNot: office.idNot,
|
uid: office.uid,
|
||||||
crpcen: office.crpcen,
|
idNot: office.idNot,
|
||||||
name: office.name,
|
crpcen: office.crpcen,
|
||||||
office_status: office.office_status
|
name: office.name,
|
||||||
};
|
office_status: office.office_status
|
||||||
|
};
|
||||||
|
|
||||||
if (progressCallback) {
|
if (progressCallback) {
|
||||||
progressiveProcess.processData.office = process.processData.office;
|
progressiveProcess.processData.office = process.processData.office;
|
||||||
progressCallback(JSON.parse(JSON.stringify(progressiveProcess)));
|
progressCallback(JSON.parse(JSON.stringify(progressiveProcess)));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
console.error('Office not found');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (process.processData.role) {
|
if (process.processData.role) {
|
||||||
const role: any = (await RoleService.getRoleByUid(process.processData.role.uid)).processData;
|
const role: any = (await RoleService.getRoleByUid(process.processData.role.uid)).processData;
|
||||||
process.processData.role = {
|
if (!role) {
|
||||||
uid: role.uid,
|
console.error('Role not found');
|
||||||
name: role.name
|
} else {
|
||||||
};
|
process.processData.role = {
|
||||||
|
uid: role.uid,
|
||||||
|
name: role.name
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
if (progressCallback) {
|
if (progressCallback) {
|
||||||
progressiveProcess.processData.role = process.processData.role;
|
progressiveProcess.processData.role = process.processData.role;
|
||||||
@ -294,16 +298,20 @@ export default class CollaboratorService extends AbstractService {
|
|||||||
|
|
||||||
if (process.processData.office_role) {
|
if (process.processData.office_role) {
|
||||||
const officeRole: any = (await OfficeRoleService.getOfficeRoleByUid(process.processData.office_role.uid)).processData;
|
const officeRole: any = (await OfficeRoleService.getOfficeRoleByUid(process.processData.office_role.uid)).processData;
|
||||||
process.processData.office_role = {
|
if (!officeRole) {
|
||||||
uid: officeRole.uid,
|
console.error('Office role not found');
|
||||||
name: officeRole.name,
|
} else {
|
||||||
rules: officeRole.rules?.map((rule: any) => {
|
process.processData.office_role = {
|
||||||
return {
|
uid: officeRole.uid,
|
||||||
uid: rule.uid,
|
name: officeRole.name,
|
||||||
name: rule.name
|
rules: officeRole.rules?.map((rule: any) => {
|
||||||
};
|
return {
|
||||||
})
|
uid: rule.uid,
|
||||||
};
|
name: rule.name
|
||||||
|
};
|
||||||
|
})
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
if (progressCallback) {
|
if (progressCallback) {
|
||||||
progressiveProcess.processData.office_role = process.processData.office_role;
|
progressiveProcess.processData.office_role = process.processData.office_role;
|
||||||
|
@ -27,7 +27,8 @@ export default class DatabaseService {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
// Construction de l'URL avec paramètres de pagination
|
// Construction de l'URL avec paramètres de pagination
|
||||||
const url = `${publicRuntimeConfig.NEXT_PUBLIC_API_URL}/db/${tableName}?page=${page}&limit=${limit}`;
|
const baseUrl = DatabaseService.buildBaseUrl();
|
||||||
|
const url = `${baseUrl}/db/${tableName}?page=${page}&limit=${limit}`;
|
||||||
|
|
||||||
// Appel à l'API REST
|
// Appel à l'API REST
|
||||||
const response = await fetch(url, {
|
const response = await fetch(url, {
|
||||||
@ -49,4 +50,28 @@ export default class DatabaseService {
|
|||||||
throw error;
|
throw error;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Construit l'URL de base en utilisant les variables d'environnement
|
||||||
|
* @returns URL de base de l'API
|
||||||
|
*/
|
||||||
|
private static buildBaseUrl(): string {
|
||||||
|
// Vérification des variables d'environnement requises
|
||||||
|
const requiredVars = [
|
||||||
|
'NEXT_PUBLIC_BACK_API_PROTOCOL',
|
||||||
|
'NEXT_PUBLIC_BACK_API_HOST',
|
||||||
|
'NEXT_PUBLIC_BACK_API_PORT',
|
||||||
|
'NEXT_PUBLIC_BACK_API_ROOT_URL',
|
||||||
|
'NEXT_PUBLIC_BACK_API_VERSION'
|
||||||
|
];
|
||||||
|
|
||||||
|
for (const varName of requiredVars) {
|
||||||
|
if (!publicRuntimeConfig[varName]) {
|
||||||
|
throw new Error(`${varName} is not defined in environment variables`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Construction de l'URL de base
|
||||||
|
return `${publicRuntimeConfig.NEXT_PUBLIC_BACK_API_PROTOCOL}${publicRuntimeConfig.NEXT_PUBLIC_BACK_API_HOST}:${publicRuntimeConfig.NEXT_PUBLIC_BACK_API_PORT}${publicRuntimeConfig.NEXT_PUBLIC_BACK_API_ROOT_URL}${publicRuntimeConfig.NEXT_PUBLIC_BACK_API_VERSION}`;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,7 +4,7 @@ import User from 'src/sdk/User';
|
|||||||
|
|
||||||
import AbstractService from './AbstractService';
|
import AbstractService from './AbstractService';
|
||||||
|
|
||||||
import DocumentTypeService from './DocumentTypeService';
|
import { DEFAULT_STORAGE_URLS } from '@Front/Config/AppConstants';
|
||||||
|
|
||||||
export default class DeedTypeService extends AbstractService {
|
export default class DeedTypeService extends AbstractService {
|
||||||
|
|
||||||
@ -12,7 +12,7 @@ export default class DeedTypeService extends AbstractService {
|
|||||||
super();
|
super();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static createDeedType(deedTypeData: any, validatorId: string): Promise<any> {
|
public static async createDeedType(deedTypeData: any, validatorId: string): Promise<{ processId: string, processData: any }> {
|
||||||
const ownerId: string = User.getInstance().getPairingId()!;
|
const ownerId: string = User.getInstance().getPairingId()!;
|
||||||
|
|
||||||
const processData: any = {
|
const processData: any = {
|
||||||
@ -25,105 +25,65 @@ export default class DeedTypeService extends AbstractService {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const privateFields: string[] = Object.keys(processData);
|
const privateFields: string[] = Object.keys(processData);
|
||||||
privateFields.splice(privateFields.indexOf('uid'), 1);
|
const allFields: string[] = [...privateFields, 'roles'];
|
||||||
privateFields.splice(privateFields.indexOf('utype'), 1);
|
|
||||||
privateFields.splice(privateFields.indexOf('isDeleted'), 1);
|
|
||||||
|
|
||||||
const roles: any = {
|
const roles: any = {
|
||||||
demiurge: {
|
demiurge: {
|
||||||
members: [...[ownerId], validatorId],
|
members: [ownerId],
|
||||||
validation_rules: [],
|
validation_rules: [],
|
||||||
storages: []
|
storages: []
|
||||||
},
|
},
|
||||||
owner: {
|
owner: {
|
||||||
members: [ownerId],
|
members: [ownerId, validatorId],
|
||||||
validation_rules: [
|
validation_rules: [
|
||||||
{
|
{
|
||||||
quorum: 0.5,
|
quorum: 0.01,
|
||||||
fields: [...privateFields, 'roles', 'uid', 'utype'],
|
fields: allFields,
|
||||||
min_sig_member: 1,
|
min_sig_member: 0.01,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
storages: []
|
storages: [...DEFAULT_STORAGE_URLS]
|
||||||
},
|
|
||||||
validator: {
|
|
||||||
members: [validatorId],
|
|
||||||
validation_rules: [
|
|
||||||
{
|
|
||||||
quorum: 0.5,
|
|
||||||
fields: ['idCertified', 'roles'],
|
|
||||||
min_sig_member: 1,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
quorum: 0.0,
|
|
||||||
fields: [...privateFields],
|
|
||||||
min_sig_member: 0,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
storages: []
|
|
||||||
},
|
},
|
||||||
apophis: {
|
apophis: {
|
||||||
members: [ownerId],
|
members: [ownerId, validatorId],
|
||||||
validation_rules: [],
|
validation_rules: [],
|
||||||
storages: []
|
storages: []
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
return new Promise<any>((resolve: (processCreated: any) => void, reject: (error: string) => void) => {
|
try {
|
||||||
this.messageBus.createProcess(processData, privateFields, roles).then((processCreated: any) => {
|
const processCreated = await this.messageBus.createProcess(processData, privateFields, roles);
|
||||||
this.messageBus.notifyUpdate(processCreated.processId, processCreated.process.states[0].state_id).then(() => {
|
await this.messageBus.notifyUpdate(processCreated.processId, processCreated.process.states[0].state_id);
|
||||||
this.messageBus.validateState(processCreated.processId, processCreated.process.states[0].state_id).then((_stateValidated: any) => {
|
await this.messageBus.validateState(processCreated.processId, processCreated.process.states[0].state_id);
|
||||||
this.getDeedTypeByUid(processCreated.processData.uid).then(resolve).catch(reject);
|
const finalProcessData = await this.messageBus.getProcessData(processCreated.processId);
|
||||||
}).catch(reject);
|
|
||||||
}).catch(reject);
|
return { processId: processCreated.processId, processData: finalProcessData };
|
||||||
}).catch(reject);
|
} catch (error) {
|
||||||
});
|
throw error;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static getDeedTypes(callback: (processes: any[]) => void, waitForAll: boolean = false): void {
|
public static getDeedTypes(callback: (processes: any[]) => void): void {
|
||||||
// Check if we have valid cache
|
// Check if we have valid cache
|
||||||
const items: any[] = this.getItems('_deed_types_');
|
const items: any[] = this.getItems('_deed_types_');
|
||||||
if (items.length > 0 && !waitForAll) {
|
if (items.length > 0) {
|
||||||
setTimeout(() => callback([...items]), 0);
|
setTimeout(() => callback([...items]), 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.messageBus.getProcessesDecoded((publicValues: any) =>
|
this.messageBus.getProcessesDecoded((values: any) => {
|
||||||
publicValues['uid'] &&
|
return values['utype'] === 'deedType'
|
||||||
publicValues['utype'] &&
|
&& values['isDeleted'] === 'false';
|
||||||
publicValues['utype'] === 'deedType' &&
|
}).then(async (processes: any) => {
|
||||||
publicValues['isDeleted'] &&
|
|
||||||
publicValues['isDeleted'] === 'false' &&
|
|
||||||
!items.map((item: any) => item.processData.uid).includes(publicValues['uid'])
|
|
||||||
).then(async (processes: any[]) => {
|
|
||||||
if (processes.length === 0) {
|
if (processes.length === 0) {
|
||||||
if (waitForAll) {
|
callback([...items]);
|
||||||
callback([...items]);
|
|
||||||
}
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const updatedItems: any[] = [...items];
|
const updatedItems: any[] = [...items];
|
||||||
|
|
||||||
for (let processIndex = 0; processIndex < processes.length; processIndex++) {
|
for (let processIndex = 0; processIndex < processes.length; processIndex++) {
|
||||||
let process = processes[processIndex];
|
const process = processes[processIndex];
|
||||||
|
|
||||||
if (!waitForAll) {
|
|
||||||
process = await this.completeDeedType(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.completeDeedType(process);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Update cache
|
// Update cache
|
||||||
this.setItem('_deed_types_', process);
|
this.setItem('_deed_types_', process);
|
||||||
|
|
||||||
@ -133,90 +93,33 @@ export default class DeedTypeService extends AbstractService {
|
|||||||
} else {
|
} else {
|
||||||
updatedItems.push(process);
|
updatedItems.push(process);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!waitForAll) {
|
|
||||||
callback([...updatedItems]);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (waitForAll) {
|
callback([...updatedItems]);
|
||||||
callback([...updatedItems]);
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public static getDeedTypeByUid(uid: string): Promise<any> {
|
public static async updateDeedType(processId: string, newData: any): Promise<void> {
|
||||||
// Check if we have valid cache
|
try {
|
||||||
const item: any = this.getItem('_deed_types_', uid);
|
const processUpdated = await this.messageBus.updateProcess(
|
||||||
if (item) {
|
processId,
|
||||||
return Promise.resolve(item);
|
{ updated_at: new Date().toISOString(), ...newData },
|
||||||
|
[],
|
||||||
|
null
|
||||||
|
);
|
||||||
|
|
||||||
|
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('_deed_types_', processData);
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Failed to update deed type:', error);
|
||||||
|
throw error; // Re-throw to allow caller to handle
|
||||||
}
|
}
|
||||||
|
|
||||||
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'] === 'deedType' &&
|
|
||||||
publicValues['isDeleted'] &&
|
|
||||||
publicValues['isDeleted'] === 'false'
|
|
||||||
).then(async (processes: any[]) => {
|
|
||||||
if (processes.length === 0) {
|
|
||||||
resolve(null);
|
|
||||||
} else {
|
|
||||||
let process: any = processes[0];
|
|
||||||
process = await this.completeDeedType(process);
|
|
||||||
|
|
||||||
// Update cache
|
|
||||||
this.setItem('_deed_types_', process);
|
|
||||||
|
|
||||||
resolve(process);
|
|
||||||
}
|
|
||||||
}).catch(reject);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static updateDeedType(process: any, newData: any): Promise<void> {
|
|
||||||
return new Promise<void>((resolve: () => 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(() => {
|
|
||||||
// Update cache
|
|
||||||
this.setItem('_deed_types_', process);
|
|
||||||
|
|
||||||
resolve();
|
|
||||||
}).catch((error) => console.error('Failed to validate state', error));
|
|
||||||
}).catch((error) => console.error('Failed to notify update', error));
|
|
||||||
}).catch((error) => console.error('Failed to update', error));
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
private static async completeDeedType(process: any, progressCallback?: (processInProgress: any) => void): Promise<any> {
|
|
||||||
const progressiveProcess: any = JSON.parse(JSON.stringify(process));
|
|
||||||
|
|
||||||
if (process.processData.document_types && process.processData.document_types.length > 0) {
|
|
||||||
progressiveProcess.processData.document_types = [];
|
|
||||||
if (progressCallback) {
|
|
||||||
progressCallback(progressiveProcess);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (const document_type of process.processData.document_types) {
|
|
||||||
const documentTypeData = (await DocumentTypeService.getDocumentTypeByUid(document_type.uid)).processData;
|
|
||||||
progressiveProcess.processData.document_types.push(documentTypeData);
|
|
||||||
|
|
||||||
// Remove duplicates
|
|
||||||
progressiveProcess.processData.document_types = progressiveProcess.processData.document_types
|
|
||||||
.filter((item: any, index: number) => progressiveProcess.processData.document_types.findIndex((t: any) => t.uid === item.uid) === index);
|
|
||||||
|
|
||||||
if (progressCallback) {
|
|
||||||
progressCallback(JSON.parse(JSON.stringify(progressiveProcess)));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
process.processData.document_types = progressiveProcess.processData.document_types;
|
|
||||||
}
|
|
||||||
|
|
||||||
return process;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -3,6 +3,7 @@ import { v4 as uuidv4 } from 'uuid';
|
|||||||
import User from 'src/sdk/User';
|
import User from 'src/sdk/User';
|
||||||
|
|
||||||
import AbstractService from './AbstractService';
|
import AbstractService from './AbstractService';
|
||||||
|
import { DEFAULT_STORAGE_URLS } from '@Front/Config/AppConstants';
|
||||||
|
|
||||||
export default class DocumentTypeService extends AbstractService {
|
export default class DocumentTypeService extends AbstractService {
|
||||||
|
|
||||||
@ -10,7 +11,7 @@ export default class DocumentTypeService extends AbstractService {
|
|||||||
super();
|
super();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static createDocumentType(documentTypeData: any, validatorId: string): Promise<any> {
|
public static createDocumentType(documentTypeData: any, validatorId: string): Promise<{ processId: string, processData: any }> {
|
||||||
const ownerId: string = User.getInstance().getPairingId()!;
|
const ownerId: string = User.getInstance().getPairingId()!;
|
||||||
|
|
||||||
const processData: any = {
|
const processData: any = {
|
||||||
@ -23,45 +24,27 @@ export default class DocumentTypeService extends AbstractService {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const privateFields: string[] = Object.keys(processData);
|
const privateFields: string[] = Object.keys(processData);
|
||||||
privateFields.splice(privateFields.indexOf('uid'), 1);
|
const allFields: string[] = [...privateFields, 'roles'];
|
||||||
privateFields.splice(privateFields.indexOf('utype'), 1);
|
|
||||||
privateFields.splice(privateFields.indexOf('isDeleted'), 1);
|
|
||||||
|
|
||||||
const roles: any = {
|
const roles: any = {
|
||||||
demiurge: {
|
demiurge: {
|
||||||
members: [...[ownerId], validatorId],
|
members: [ownerId],
|
||||||
validation_rules: [],
|
validation_rules: [],
|
||||||
storages: []
|
storages: []
|
||||||
},
|
},
|
||||||
owner: {
|
owner: {
|
||||||
members: [ownerId],
|
members: [ownerId, validatorId],
|
||||||
validation_rules: [
|
validation_rules: [
|
||||||
{
|
{
|
||||||
quorum: 0.5,
|
quorum: 0.01,
|
||||||
fields: [...privateFields, 'roles', 'uid', 'utype'],
|
fields: allFields,
|
||||||
min_sig_member: 1,
|
min_sig_member: 0.01,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
storages: []
|
storages: [...DEFAULT_STORAGE_URLS]
|
||||||
},
|
|
||||||
validator: {
|
|
||||||
members: [validatorId],
|
|
||||||
validation_rules: [
|
|
||||||
{
|
|
||||||
quorum: 0.5,
|
|
||||||
fields: ['idCertified', 'roles'],
|
|
||||||
min_sig_member: 1,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
quorum: 0.0,
|
|
||||||
fields: [...privateFields],
|
|
||||||
min_sig_member: 0,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
storages: []
|
|
||||||
},
|
},
|
||||||
apophis: {
|
apophis: {
|
||||||
members: [ownerId],
|
members: [ownerId, validatorId],
|
||||||
validation_rules: [],
|
validation_rules: [],
|
||||||
storages: []
|
storages: []
|
||||||
}
|
}
|
||||||
@ -71,39 +54,80 @@ export default class DocumentTypeService extends AbstractService {
|
|||||||
this.messageBus.createProcess(processData, privateFields, roles).then((processCreated: any) => {
|
this.messageBus.createProcess(processData, privateFields, roles).then((processCreated: any) => {
|
||||||
this.messageBus.notifyUpdate(processCreated.processId, processCreated.process.states[0].state_id).then(() => {
|
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.messageBus.validateState(processCreated.processId, processCreated.process.states[0].state_id).then((_stateValidated: any) => {
|
||||||
this.getDocumentTypeByUid(processCreated.processData.uid).then(resolve).catch(reject);
|
this.messageBus.getProcessData(processCreated.processId).then((processData: any) => {
|
||||||
|
resolve({ processId: processCreated.processId, processData: processData });
|
||||||
|
}).catch(reject);
|
||||||
}).catch(reject);
|
}).catch(reject);
|
||||||
}).catch(reject);
|
}).catch(reject);
|
||||||
}).catch(reject);
|
}).catch(reject);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public static getDocumentTypes(): Promise<any[]> {
|
public static getDocumentTypes(callback: (processes: any[]) => void): void {
|
||||||
// Check if we have valid cache
|
// Check if we have valid cache
|
||||||
const items: any[] = this.getItems('_document_types_');
|
const items: any[] = this.getItems('_document_types_');
|
||||||
|
if (items.length > 0) {
|
||||||
return this.messageBus.getProcessesDecoded((publicValues: any) =>
|
setTimeout(() => callback([...items]), 0);
|
||||||
publicValues['uid'] &&
|
}
|
||||||
publicValues['utype'] &&
|
|
||||||
publicValues['utype'] === 'documentType' &&
|
this.messageBus.getProcessesDecoded((values: any) => {
|
||||||
publicValues['isDeleted'] &&
|
return values['utype'] === 'documentType'
|
||||||
publicValues['isDeleted'] === 'false' &&
|
&& values['isDeleted'] === 'false';
|
||||||
!items.map((item: any) => item.processData.uid).includes(publicValues['uid'])
|
}).then(async (processes: any) => {
|
||||||
).then(async (processes: any[]) => {
|
|
||||||
if (processes.length === 0) {
|
if (processes.length === 0) {
|
||||||
return items;
|
callback([...items]);
|
||||||
} else {
|
return;
|
||||||
for (const process of processes) {
|
|
||||||
// Update cache
|
|
||||||
this.setItem('_document_types_', process);
|
|
||||||
|
|
||||||
items.push(process);
|
|
||||||
}
|
|
||||||
return items;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const updatedItems: any[] = [...items];
|
||||||
|
|
||||||
|
for (let processIndex = 0; processIndex < processes.length; processIndex++) {
|
||||||
|
const process = processes[processIndex];
|
||||||
|
|
||||||
|
// Update cache
|
||||||
|
this.setItem('_document_types_', process);
|
||||||
|
|
||||||
|
const existingIndex: number = updatedItems.findIndex(item => item.processId === process.processId);
|
||||||
|
if (existingIndex >= 0) {
|
||||||
|
updatedItems[existingIndex] = process;
|
||||||
|
} else {
|
||||||
|
updatedItems.push(process);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
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> {
|
public static getDocumentTypeByUid(uid: string): Promise<any> {
|
||||||
// Check if we have valid cache
|
// Check if we have valid cache
|
||||||
const item: any = this.getItem('_document_types_', uid);
|
const item: any = this.getItem('_document_types_', uid);
|
||||||
@ -133,10 +157,9 @@ export default class DocumentTypeService extends AbstractService {
|
|||||||
const newStateId: string = processUpdated.diffs[0]?.state_id;
|
const newStateId: string = processUpdated.diffs[0]?.state_id;
|
||||||
this.messageBus.notifyUpdate(process.processId, newStateId).then(() => {
|
this.messageBus.notifyUpdate(process.processId, newStateId).then(() => {
|
||||||
this.messageBus.validateState(process.processId, newStateId).then((_stateValidated) => {
|
this.messageBus.validateState(process.processId, newStateId).then((_stateValidated) => {
|
||||||
const documentTypeUid: string = process.processData.uid;
|
this.removeItem('_document_types_', process.processId);
|
||||||
this.removeItem('_document_types_', documentTypeUid);
|
|
||||||
|
|
||||||
this.getDocumentTypeByUid(documentTypeUid).then(resolve).catch(reject);
|
this.getDocumentTypeByProcessId(process.processId).then(resolve).catch(reject);
|
||||||
}).catch(reject);
|
}).catch(reject);
|
||||||
}).catch(reject);
|
}).catch(reject);
|
||||||
}).catch(reject);
|
}).catch(reject);
|
||||||
|
@ -8,6 +8,9 @@ import RuleService from './RuleService';
|
|||||||
import RuleGroupService from './RuleGroupService';
|
import RuleGroupService from './RuleGroupService';
|
||||||
import RoleService from './RoleService';
|
import RoleService from './RoleService';
|
||||||
import OfficeRoleService from './OfficeRoleService';
|
import OfficeRoleService from './OfficeRoleService';
|
||||||
|
import { DEFAULT_VALIDATOR_ID } from '@Front/Config/AppConstants';
|
||||||
|
|
||||||
|
const mandatoryRoles = ['Notaire', 'Collaborateur'];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Type pour le callback de progression
|
* Type pour le callback de progression
|
||||||
@ -85,9 +88,13 @@ export default class ImportData {
|
|||||||
|
|
||||||
// Exécuter l'étape et stocker le résultat si nécessaire
|
// Exécuter l'étape et stocker le résultat si nécessaire
|
||||||
const result = await step.function(stepProgressCallback, results);
|
const result = await step.function(stepProgressCallback, results);
|
||||||
if (result) {
|
if (result !== undefined) {
|
||||||
results.push(result);
|
results.push(result);
|
||||||
|
} else {
|
||||||
|
// Push empty array to maintain consistent indexing
|
||||||
|
results.push([]);
|
||||||
}
|
}
|
||||||
|
console.log(`Step ${i} (${step.name}): ${result?.length || 0} items`);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!await this.isDone()) {
|
if (!await this.isDone()) {
|
||||||
@ -122,7 +129,7 @@ export default class ImportData {
|
|||||||
|
|
||||||
const roles: any = {
|
const roles: any = {
|
||||||
demiurge: {
|
demiurge: {
|
||||||
members: [...[ownerId], validatorId],
|
members: [ownerId],
|
||||||
validation_rules: [],
|
validation_rules: [],
|
||||||
storages: []
|
storages: []
|
||||||
},
|
},
|
||||||
@ -172,6 +179,7 @@ export default class ImportData {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static async importRules(onProgress?: (progress: number, description?: string) => void): Promise<any[]> {
|
private static async importRules(onProgress?: (progress: number, description?: string) => void): Promise<any[]> {
|
||||||
|
console.log('Importing rules');
|
||||||
const rules: any[] = [];
|
const rules: any[] = [];
|
||||||
|
|
||||||
const INIT_PROGRESS = 0;
|
const INIT_PROGRESS = 0;
|
||||||
@ -201,10 +209,14 @@ export default class ImportData {
|
|||||||
const existingRules: any[] = (await RuleService.getRules()).map((process: any) => process.processData);
|
const existingRules: any[] = (await RuleService.getRules()).map((process: any) => process.processData);
|
||||||
const filteredRules: any[] = result.data.filter((rule: any) => !existingRules.some((existingRule: any) => existingRule.uid === rule.uid));
|
const filteredRules: any[] = result.data.filter((rule: any) => !existingRules.some((existingRule: any) => existingRule.uid === rule.uid));
|
||||||
|
|
||||||
|
if (filteredRules.length === 0) {
|
||||||
|
console.debug('All rules already imported');
|
||||||
|
}
|
||||||
|
|
||||||
const totalFilteredRules = filteredRules.length;
|
const totalFilteredRules = filteredRules.length;
|
||||||
for (let i = 0; i < totalFilteredRules; i++) {
|
for (let i = 0; i < totalFilteredRules; i++) {
|
||||||
const validatorId: string = '884cb36a346a79af8697559f16940141f068bdf1656f88fa0df0e9ecd7311fb8:0';
|
console.log(`Adding rule ${filteredRules[i].name}`);
|
||||||
rules.push((await RuleService.createRule(filteredRules[i], validatorId)).processData);
|
rules.push((await RuleService.createRule(filteredRules[i], DEFAULT_VALIDATOR_ID)).processData);
|
||||||
|
|
||||||
const progressRange = CREATE_END_PROGRESS - CREATE_START_PROGRESS;
|
const progressRange = CREATE_END_PROGRESS - CREATE_START_PROGRESS;
|
||||||
const ruleProgressIncrement = progressRange / (totalFilteredRules * totalPages);
|
const ruleProgressIncrement = progressRange / (totalFilteredRules * totalPages);
|
||||||
@ -225,6 +237,7 @@ export default class ImportData {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static async importRuleGroups(onProgress?: (progress: number, description?: string) => void): Promise<any[]> {
|
private static async importRuleGroups(onProgress?: (progress: number, description?: string) => void): Promise<any[]> {
|
||||||
|
console.log('Importing rule groups');
|
||||||
const ruleGroups: any[] = [];
|
const ruleGroups: any[] = [];
|
||||||
|
|
||||||
const INIT_PROGRESS = 0;
|
const INIT_PROGRESS = 0;
|
||||||
@ -256,8 +269,8 @@ export default class ImportData {
|
|||||||
|
|
||||||
const totalFilteredRuleGroups = filteredRuleGroups.length;
|
const totalFilteredRuleGroups = filteredRuleGroups.length;
|
||||||
for (let i = 0; i < totalFilteredRuleGroups; i++) {
|
for (let i = 0; i < totalFilteredRuleGroups; i++) {
|
||||||
const validatorId: string = '884cb36a346a79af8697559f16940141f068bdf1656f88fa0df0e9ecd7311fb8:0';
|
console.log(`Adding rule group ${filteredRuleGroups[i].name}`);
|
||||||
ruleGroups.push((await RuleGroupService.createRuleGroup(filteredRuleGroups[i], validatorId)).processData);
|
ruleGroups.push((await RuleGroupService.createRuleGroup(filteredRuleGroups[i], DEFAULT_VALIDATOR_ID)).processData);
|
||||||
|
|
||||||
const progressRange = CREATE_END_PROGRESS - CREATE_START_PROGRESS;
|
const progressRange = CREATE_END_PROGRESS - CREATE_START_PROGRESS;
|
||||||
const ruleProgressIncrement = progressRange / (totalFilteredRuleGroups * totalPages);
|
const ruleProgressIncrement = progressRange / (totalFilteredRuleGroups * totalPages);
|
||||||
@ -278,6 +291,7 @@ export default class ImportData {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static async importRoles(onProgress?: (progress: number, description?: string) => void): Promise<any[]> {
|
private static async importRoles(onProgress?: (progress: number, description?: string) => void): Promise<any[]> {
|
||||||
|
console.log('Importing roles');
|
||||||
// Constantes de progression - pourraient être paramétrées
|
// Constantes de progression - pourraient être paramétrées
|
||||||
const INIT_PROGRESS = 0;
|
const INIT_PROGRESS = 0;
|
||||||
const FETCH_PROGRESS = 30;
|
const FETCH_PROGRESS = 30;
|
||||||
@ -309,10 +323,14 @@ export default class ImportData {
|
|||||||
onProgress?.(FETCH_PROGRESS, 'Récupération des rôles existants');
|
onProgress?.(FETCH_PROGRESS, 'Récupération des rôles existants');
|
||||||
const roles: any[] = processes.map((process: any) => process.processData);
|
const roles: any[] = processes.map((process: any) => process.processData);
|
||||||
if (roles.length === 0) {
|
if (roles.length === 0) {
|
||||||
|
const defaultRolesNames: string[] = defaultRoles.map((role: any) => role.name);
|
||||||
const totalRoles = defaultRoles.length;
|
const totalRoles = defaultRoles.length;
|
||||||
for (let i = 0; i < totalRoles; i++) {
|
for (let i = 0; i < totalRoles; i++) {
|
||||||
const validatorId: string = '884cb36a346a79af8697559f16940141f068bdf1656f88fa0df0e9ecd7311fb8:0';
|
if (!defaultRolesNames.includes(roles[i].name)) {
|
||||||
roles.push((await RoleService.createRole(defaultRoles[i], validatorId)).processData);
|
roles.push((await RoleService.createRole(defaultRoles[i], DEFAULT_VALIDATOR_ID)).processData);
|
||||||
|
} else {
|
||||||
|
console.log(`Role ${defaultRoles[i].name} already exists`);
|
||||||
|
}
|
||||||
|
|
||||||
// Progression dynamique pendant la création des rôles
|
// Progression dynamique pendant la création des rôles
|
||||||
const progressRange = CREATE_END_PROGRESS - CREATE_START_PROGRESS;
|
const progressRange = CREATE_END_PROGRESS - CREATE_START_PROGRESS;
|
||||||
@ -326,54 +344,166 @@ export default class ImportData {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static async importDefaultRoles(officeUid: string, ruleGroups: any[], onProgress?: (progress: number, description?: string) => void): Promise<any[]> {
|
||||||
|
console.log('Importing default roles');
|
||||||
|
let officeRoles: any[] = [];
|
||||||
|
|
||||||
|
const CREATE_START_PROGRESS = 60;
|
||||||
|
const CREATE_END_PROGRESS = 90;
|
||||||
|
|
||||||
|
onProgress?.(CREATE_START_PROGRESS, 'Création des rôles par défaut');
|
||||||
|
|
||||||
|
// Prepare the collaborator rules from rule groups
|
||||||
|
const collaboratorRules: any[] = ruleGroups
|
||||||
|
.map((ruleGroup: any) => ruleGroup.rules || [])
|
||||||
|
.reduce((acc: any, curr: any) => [...acc, ...curr], [])
|
||||||
|
.map((rule: any) => ({ uid: rule.uid }));
|
||||||
|
|
||||||
|
console.log(`Found ${collaboratorRules.length} collaborator rules from ${ruleGroups.length} rule groups`);
|
||||||
|
|
||||||
|
// Get fresh list of existing roles (including ones we just created)
|
||||||
|
const updatedExistingRoles = await OfficeRoleService.getOfficeRoles();
|
||||||
|
const existingRoles = updatedExistingRoles
|
||||||
|
.map((role: any) => role.processData)
|
||||||
|
.filter((roleData: any) => roleData.office?.uid === officeUid);
|
||||||
|
|
||||||
|
const existingRoleNames = existingRoles.map((role: any) => role.name);
|
||||||
|
|
||||||
|
const missingMandatoryRoles = mandatoryRoles.filter(roleName =>
|
||||||
|
!existingRoleNames.includes(roleName)
|
||||||
|
);
|
||||||
|
|
||||||
|
console.log(`Found ${existingRoleNames.length} existing roles, ${missingMandatoryRoles.length} mandatory roles missing`);
|
||||||
|
|
||||||
|
if (missingMandatoryRoles.length === 0) {
|
||||||
|
onProgress?.(CREATE_END_PROGRESS, 'Tous les rôles obligatoires existent déjà');
|
||||||
|
return officeRoles;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (let i = 0; i < missingMandatoryRoles.length; i++) {
|
||||||
|
const roleName = missingMandatoryRoles[i];
|
||||||
|
const fallbackRole = {
|
||||||
|
name: roleName,
|
||||||
|
office: { uid: officeUid },
|
||||||
|
// Only Notaire gets rules, Collaborateur gets none
|
||||||
|
...(roleName === 'Notaire' && { rules: collaboratorRules })
|
||||||
|
};
|
||||||
|
|
||||||
|
console.log(`Creating missing mandatory role: ${roleName}`);
|
||||||
|
|
||||||
|
officeRoles.push((await OfficeRoleService.createOfficeRole(fallbackRole, DEFAULT_VALIDATOR_ID)).processData);
|
||||||
|
|
||||||
|
const progressRange = CREATE_END_PROGRESS - CREATE_START_PROGRESS;
|
||||||
|
const progress = CREATE_START_PROGRESS + ((i + 1) / missingMandatoryRoles.length) * progressRange;
|
||||||
|
onProgress?.(progress, `Création rôle obligatoire ${i + 1}/${missingMandatoryRoles.length} - ${roleName}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
return officeRoles;
|
||||||
|
}
|
||||||
|
|
||||||
private static async importOfficeRoles(office: any, ruleGroups: any[], onProgress?: (progress: number, description?: string) => void): Promise<any[]> {
|
private static async importOfficeRoles(office: any, ruleGroups: any[], onProgress?: (progress: number, description?: string) => void): Promise<any[]> {
|
||||||
// Constantes de progression - pourraient être paramétrées
|
console.log('Importing office roles');
|
||||||
|
let officeRoles: any[] = [];
|
||||||
|
const officeUid = office.processData?.uid;
|
||||||
|
if (!officeUid) {
|
||||||
|
console.error('Office UID is not set');
|
||||||
|
return officeRoles;
|
||||||
|
}
|
||||||
|
console.log(`Processing ${ruleGroups.length} rule groups for office ${officeUid}`);
|
||||||
|
|
||||||
const INIT_PROGRESS = 0;
|
const INIT_PROGRESS = 0;
|
||||||
const FETCH_PROGRESS = 30;
|
const FETCH_PROGRESS = 30;
|
||||||
const CREATE_START_PROGRESS = FETCH_PROGRESS;
|
|
||||||
const CREATE_END_PROGRESS = 90;
|
const CREATE_END_PROGRESS = 90;
|
||||||
const FINAL_PROGRESS = 100;
|
const FINAL_PROGRESS = 100;
|
||||||
|
|
||||||
onProgress?.(INIT_PROGRESS, 'Initialisation');
|
onProgress?.(INIT_PROGRESS, 'Initialisation');
|
||||||
return await new Promise<any[]>((resolve: (roles: any[]) => void) => {
|
|
||||||
const collaboratorRules: any[] = ruleGroups
|
|
||||||
.map((ruleGroup: any) => ruleGroup.rules)
|
|
||||||
.reduce((acc: any, curr: any) => [...acc, ...curr], [])
|
|
||||||
.map((rule: any) => ({ uid: rule.uid }));
|
|
||||||
|
|
||||||
const defaultOfficeRoles: any[] = [
|
let page = 1;
|
||||||
{
|
let limit = 10;
|
||||||
name: 'Notaire',
|
let totalPages = 1;
|
||||||
office: {
|
|
||||||
uid: office.uid
|
|
||||||
},
|
|
||||||
rules: collaboratorRules
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'Collaborateur',
|
|
||||||
office: {
|
|
||||||
uid: office.uid
|
|
||||||
}
|
|
||||||
}
|
|
||||||
];
|
|
||||||
OfficeRoleService.getOfficeRoles().then(async (processes: any[]) => {
|
|
||||||
onProgress?.(FETCH_PROGRESS, 'Récupération des rôles d\'office existants');
|
|
||||||
const officeRoles: any[] = processes.map((process: any) => process.processData);
|
|
||||||
if (officeRoles.length === 0) {
|
|
||||||
const totalOfficeRoles = defaultOfficeRoles.length;
|
|
||||||
for (let i = 0; i < totalOfficeRoles; i++) {
|
|
||||||
const validatorId: string = '884cb36a346a79af8697559f16940141f068bdf1656f88fa0df0e9ecd7311fb8:0';
|
|
||||||
officeRoles.push((await OfficeRoleService.createOfficeRole(defaultOfficeRoles[i], validatorId)).processData);
|
|
||||||
|
|
||||||
// Progression dynamique pendant la création des rôles d'office
|
onProgress?.(FETCH_PROGRESS, 'Récupération des rôles d\'office existants');
|
||||||
const progressRange = CREATE_END_PROGRESS - CREATE_START_PROGRESS;
|
let result = await DatabaseService.getTableData('office_roles', page, limit);
|
||||||
const progress = CREATE_START_PROGRESS + ((i + 1) / totalOfficeRoles) * progressRange;
|
if (result && result.success && result.pagination) {
|
||||||
onProgress?.(progress, `Création du rôle d'office ${i + 1}/${totalOfficeRoles} : ${defaultOfficeRoles[i].name}`);
|
totalPages = result.pagination.totalPages || 1;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
onProgress?.(FINAL_PROGRESS, 'Importation des rôles d\'office terminée');
|
const FETCH_PAGE_PROGRESS_START = FETCH_PROGRESS;
|
||||||
resolve(officeRoles);
|
const FETCH_PAGE_PROGRESS_END = 60;
|
||||||
});
|
const CREATE_START_PROGRESS = 60;
|
||||||
|
|
||||||
|
// Collect all office roles for this office from all pages
|
||||||
|
const allOfficeRolesForThisOffice: any[] = [];
|
||||||
|
while (result && result.success) {
|
||||||
|
const fetchPageProgress = FETCH_PAGE_PROGRESS_START + ((page / totalPages) * (FETCH_PAGE_PROGRESS_END - FETCH_PAGE_PROGRESS_START));
|
||||||
|
onProgress?.(fetchPageProgress, `Page ${page}/${totalPages} : Récupération des rôles d'office`);
|
||||||
|
|
||||||
|
// Collect office roles for this office from current page
|
||||||
|
const officeRolesFromPage = result.data.filter((officeRole: any) =>
|
||||||
|
officeRole.office?.uid === officeUid
|
||||||
|
);
|
||||||
|
allOfficeRolesForThisOffice.push(...officeRolesFromPage);
|
||||||
|
|
||||||
|
if (!result.pagination.hasNextPage) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
page++;
|
||||||
|
result = await DatabaseService.getTableData('office_roles', page, limit);
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log(`Found ${allOfficeRolesForThisOffice.length} office roles in database for this office`);
|
||||||
|
|
||||||
|
if (allOfficeRolesForThisOffice.length === 0) {
|
||||||
|
console.log('No office roles found in database, creating defaults');
|
||||||
|
return await this.importDefaultRoles(officeUid, ruleGroups, onProgress);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get all existing office role processes (to avoid duplicates)
|
||||||
|
const existingOfficeRoles: any[] = await OfficeRoleService.getOfficeRoles();
|
||||||
|
const existingOfficeRoleUids = existingOfficeRoles.map((existingRole: any) =>
|
||||||
|
existingRole.processData.uid
|
||||||
|
);
|
||||||
|
|
||||||
|
console.log(`Found ${existingOfficeRoles.length} existing office role processes`);
|
||||||
|
|
||||||
|
// Import all office roles found in database (if not already imported)
|
||||||
|
const dbRolesToImport = allOfficeRolesForThisOffice.filter((dbRole: any) =>
|
||||||
|
!existingOfficeRoleUids.includes(dbRole.uid)
|
||||||
|
);
|
||||||
|
|
||||||
|
console.log(`Importing ${dbRolesToImport.length} new office roles from database`);
|
||||||
|
|
||||||
|
for (let i = 0; i < dbRolesToImport.length; i++) {
|
||||||
|
const roleData = dbRolesToImport[i];
|
||||||
|
|
||||||
|
// Ensure office UID is set correctly
|
||||||
|
if (!roleData.office) {
|
||||||
|
roleData.office = { uid: officeUid };
|
||||||
|
} else if (!roleData.office.uid) {
|
||||||
|
roleData.office.uid = officeUid;
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log(`Importing office role: ${roleData.name}`);
|
||||||
|
|
||||||
|
officeRoles.push((await OfficeRoleService.createOfficeRole(roleData, DEFAULT_VALIDATOR_ID)).processData);
|
||||||
|
|
||||||
|
const progressRange = (CREATE_END_PROGRESS - CREATE_START_PROGRESS) * 0.7; // 70% for db imports
|
||||||
|
const progress = CREATE_START_PROGRESS + ((i + 1) / dbRolesToImport.length) * progressRange;
|
||||||
|
onProgress?.(progress, `Import base de données ${i + 1}/${dbRolesToImport.length} - ${roleData.name}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Now check for mandatory roles and create any missing ones
|
||||||
|
const mandatoryRolesProgress = CREATE_START_PROGRESS + (CREATE_END_PROGRESS - CREATE_START_PROGRESS) * 0.7;
|
||||||
|
onProgress?.(mandatoryRolesProgress, 'Vérification des rôles obligatoires');
|
||||||
|
|
||||||
|
const defaultRolesCreated = await this.importDefaultRoles(officeUid, ruleGroups, (subProgress, description) => {
|
||||||
|
// Map sub-progress to remaining 20% of total progress
|
||||||
|
const mappedProgress = mandatoryRolesProgress + (subProgress - 60) * 0.3 / 30; // Scale 60-90 to remaining 30%
|
||||||
|
onProgress?.(mappedProgress, description);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
officeRoles.push(...defaultRolesCreated);
|
||||||
|
|
||||||
|
onProgress?.(FINAL_PROGRESS, 'Importation des rôles d\'office terminée');
|
||||||
|
return officeRoles;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6,6 +6,7 @@ import AbstractService from './AbstractService';
|
|||||||
|
|
||||||
import OfficeService from './OfficeService';
|
import OfficeService from './OfficeService';
|
||||||
import RuleService from './RuleService';
|
import RuleService from './RuleService';
|
||||||
|
import { DEFAULT_STORAGE_URLS } from '@Front/Config/AppConstants';
|
||||||
|
|
||||||
export default class OfficeRoleService extends AbstractService {
|
export default class OfficeRoleService extends AbstractService {
|
||||||
|
|
||||||
@ -32,7 +33,7 @@ export default class OfficeRoleService extends AbstractService {
|
|||||||
|
|
||||||
const roles: any = {
|
const roles: any = {
|
||||||
demiurge: {
|
demiurge: {
|
||||||
members: [...[ownerId], validatorId],
|
members: [ownerId],
|
||||||
validation_rules: [],
|
validation_rules: [],
|
||||||
storages: []
|
storages: []
|
||||||
},
|
},
|
||||||
@ -40,31 +41,26 @@ export default class OfficeRoleService extends AbstractService {
|
|||||||
members: [ownerId],
|
members: [ownerId],
|
||||||
validation_rules: [
|
validation_rules: [
|
||||||
{
|
{
|
||||||
quorum: 0.5,
|
quorum: 0.01,
|
||||||
fields: [...privateFields, 'roles', 'uid', 'utype'],
|
fields: [...privateFields, 'roles', 'uid', 'utype', 'isDeleted'],
|
||||||
min_sig_member: 1,
|
min_sig_member: 0.01,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
storages: []
|
storages: [...DEFAULT_STORAGE_URLS]
|
||||||
},
|
},
|
||||||
validator: {
|
validator: {
|
||||||
members: [validatorId],
|
members: [validatorId],
|
||||||
validation_rules: [
|
validation_rules: [
|
||||||
{
|
{
|
||||||
quorum: 0.5,
|
quorum: 1,
|
||||||
fields: ['idCertified', 'roles'],
|
fields: [...privateFields, 'roles', 'uid', 'utype', 'isDeleted'],
|
||||||
min_sig_member: 1,
|
min_sig_member: 1,
|
||||||
},
|
},
|
||||||
{
|
|
||||||
quorum: 0.0,
|
|
||||||
fields: [...privateFields],
|
|
||||||
min_sig_member: 0,
|
|
||||||
},
|
|
||||||
],
|
],
|
||||||
storages: []
|
storages: [...DEFAULT_STORAGE_URLS]
|
||||||
},
|
},
|
||||||
apophis: {
|
apophis: {
|
||||||
members: [ownerId],
|
members: [ownerId, validatorId],
|
||||||
validation_rules: [],
|
validation_rules: [],
|
||||||
storages: []
|
storages: []
|
||||||
}
|
}
|
||||||
@ -97,8 +93,6 @@ export default class OfficeRoleService extends AbstractService {
|
|||||||
return items;
|
return items;
|
||||||
} else {
|
} else {
|
||||||
for (let process of processes) {
|
for (let process of processes) {
|
||||||
process = await this.completeOfficeRole(process);
|
|
||||||
|
|
||||||
// Update cache
|
// Update cache
|
||||||
this.setItem('_office_roles_', process);
|
this.setItem('_office_roles_', process);
|
||||||
|
|
||||||
@ -125,14 +119,11 @@ export default class OfficeRoleService extends AbstractService {
|
|||||||
publicValues['isDeleted'] &&
|
publicValues['isDeleted'] &&
|
||||||
publicValues['isDeleted'] === 'false'
|
publicValues['isDeleted'] === 'false'
|
||||||
).then(async (processes: any[]) => {
|
).then(async (processes: any[]) => {
|
||||||
if (processes.length === 0) {
|
if (processes.length !== 1) {
|
||||||
resolve(null);
|
resolve(null);
|
||||||
} else {
|
} else {
|
||||||
let process: any = processes[0];
|
|
||||||
process = await this.completeOfficeRole(process);
|
|
||||||
|
|
||||||
// Update cache
|
// Update cache
|
||||||
this.setItem('_office_roles_', process);
|
this.setItem('_office_roles_', processes[0]);
|
||||||
|
|
||||||
resolve(process);
|
resolve(process);
|
||||||
}
|
}
|
||||||
@ -156,24 +147,4 @@ export default class OfficeRoleService extends AbstractService {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private static async completeOfficeRole(process: any): Promise<any> {
|
|
||||||
if (process.processData.office) {
|
|
||||||
process.processData.office = await new Promise<any>(async (resolve: (office: any) => void) => {
|
|
||||||
const office: any = (await OfficeService.getOfficeByUid(process.processData.office.uid)).processData;
|
|
||||||
resolve(office);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
if (process.processData.rules && process.processData.rules.length > 0) {
|
|
||||||
process.processData.rules = await new Promise<any[]>(async (resolve: (rules: any[]) => void) => {
|
|
||||||
const rules: any[] = [];
|
|
||||||
for (const rule of process.processData.rules) {
|
|
||||||
rules.push((await RuleService.getRuleByUid(rule.uid)).processData);
|
|
||||||
}
|
|
||||||
resolve(rules);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
return process;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -10,9 +10,12 @@ export default class OfficeService extends AbstractService {
|
|||||||
super();
|
super();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static createOffice(officeData: any, validatorId: string): Promise<any> {
|
public static createOffice(officeData: any, owners: string[], validatorId: string, storageUrls: string[]): Promise<any> {
|
||||||
const ownerId: string = User.getInstance().getPairingId()!;
|
const ownerId: string = User.getInstance().getPairingId()!;
|
||||||
|
|
||||||
|
// Create a set for all owners to avoid duplicates
|
||||||
|
const ownersSet: Set<string> = new Set([...owners, ownerId]);
|
||||||
|
|
||||||
const processData: any = {
|
const processData: any = {
|
||||||
uid: uuidv4(),
|
uid: uuidv4(),
|
||||||
utype: 'office',
|
utype: 'office',
|
||||||
@ -29,39 +32,34 @@ export default class OfficeService extends AbstractService {
|
|||||||
|
|
||||||
const roles: any = {
|
const roles: any = {
|
||||||
demiurge: {
|
demiurge: {
|
||||||
members: [...[ownerId], validatorId],
|
members: Array.from(ownersSet),
|
||||||
validation_rules: [],
|
validation_rules: [],
|
||||||
storages: []
|
storages: []
|
||||||
},
|
},
|
||||||
owner: {
|
owner: {
|
||||||
members: [ownerId],
|
members: Array.from(ownersSet),
|
||||||
validation_rules: [
|
validation_rules: [
|
||||||
{
|
{
|
||||||
quorum: 0.5,
|
quorum: 0.01, // effectively any owner can make any change
|
||||||
fields: [...privateFields, 'roles', 'uid', 'utype'],
|
fields: [...privateFields, 'roles', 'uid', 'utype', 'isDeleted'],
|
||||||
min_sig_member: 1,
|
min_sig_member: 0.01, // need to sign with at least one device
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
storages: []
|
storages: storageUrls
|
||||||
},
|
},
|
||||||
validator: {
|
validator: {
|
||||||
members: [validatorId],
|
members: [validatorId],
|
||||||
validation_rules: [
|
validation_rules: [
|
||||||
{
|
{
|
||||||
quorum: 0.5,
|
quorum: 1, // validator can do anything alone
|
||||||
fields: ['idCertified', 'roles'],
|
fields: [...privateFields, 'roles', 'uid', 'utype', 'isDeleted'],
|
||||||
min_sig_member: 1,
|
min_sig_member: 1,
|
||||||
},
|
},
|
||||||
{
|
|
||||||
quorum: 0.0,
|
|
||||||
fields: [...privateFields],
|
|
||||||
min_sig_member: 0,
|
|
||||||
},
|
|
||||||
],
|
],
|
||||||
storages: []
|
storages: storageUrls
|
||||||
},
|
},
|
||||||
apophis: {
|
apophis: {
|
||||||
members: [ownerId],
|
members: Array.from(ownersSet), // any owner can terminate the office
|
||||||
validation_rules: [],
|
validation_rules: [],
|
||||||
storages: []
|
storages: []
|
||||||
}
|
}
|
||||||
@ -149,4 +147,43 @@ export default class OfficeService extends AbstractService {
|
|||||||
}).catch(reject);
|
}).catch(reject);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
public static addCollaborators(process: any, existingRoles: any, collaborators: any[]): Promise<void> {
|
||||||
|
return new Promise<void>((resolve: () => void, reject: (error: string) => void) => {
|
||||||
|
const newRoles: any = existingRoles;
|
||||||
|
const owners: string[] = newRoles['owner'].members;
|
||||||
|
if (!owners) {
|
||||||
|
console.error('[addCollaborators] owner role not found');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const previousOwnersLength: number = owners.length;
|
||||||
|
for (const collaborator of collaborators) {
|
||||||
|
if (owners.includes(collaborator)) {
|
||||||
|
console.debug('[addCollaborators] collaborator already in owner role');
|
||||||
|
continue;
|
||||||
|
} else {
|
||||||
|
owners.push(collaborator);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (previousOwnersLength === owners.length) {
|
||||||
|
console.error('[addCollaborators] no new collaborators added');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log('newRoles : ', newRoles);
|
||||||
|
this.messageBus.updateProcess(process.processId, { updated_at: new Date().toISOString() }, [], newRoles).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 officeUid: string = process.processData.uid;
|
||||||
|
this.removeItem('_offices_', officeUid);
|
||||||
|
|
||||||
|
this.getOfficeByUid(officeUid).then(resolve).catch(reject);
|
||||||
|
}).catch(reject);
|
||||||
|
}).catch(reject);
|
||||||
|
}).catch(reject);
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,6 +3,7 @@ import { v4 as uuidv4 } from 'uuid';
|
|||||||
import User from 'src/sdk/User';
|
import User from 'src/sdk/User';
|
||||||
|
|
||||||
import AbstractService from './AbstractService';
|
import AbstractService from './AbstractService';
|
||||||
|
import { DEFAULT_STORAGE_URLS } from '@Front/Config/AppConstants';
|
||||||
|
|
||||||
export default class RoleService extends AbstractService {
|
export default class RoleService extends AbstractService {
|
||||||
|
|
||||||
@ -29,7 +30,7 @@ export default class RoleService extends AbstractService {
|
|||||||
|
|
||||||
const roles: any = {
|
const roles: any = {
|
||||||
demiurge: {
|
demiurge: {
|
||||||
members: [...[ownerId], validatorId],
|
members: [ownerId],
|
||||||
validation_rules: [],
|
validation_rules: [],
|
||||||
storages: []
|
storages: []
|
||||||
},
|
},
|
||||||
@ -37,31 +38,26 @@ export default class RoleService extends AbstractService {
|
|||||||
members: [ownerId],
|
members: [ownerId],
|
||||||
validation_rules: [
|
validation_rules: [
|
||||||
{
|
{
|
||||||
quorum: 0.5,
|
quorum: 0.01,
|
||||||
fields: [...privateFields, 'roles', 'uid', 'utype'],
|
fields: [...privateFields, 'roles', 'uid', 'utype', 'isDeleted'],
|
||||||
min_sig_member: 1,
|
min_sig_member: 0.01,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
storages: []
|
storages: [...DEFAULT_STORAGE_URLS]
|
||||||
},
|
},
|
||||||
validator: {
|
validator: {
|
||||||
members: [validatorId],
|
members: [validatorId],
|
||||||
validation_rules: [
|
validation_rules: [
|
||||||
{
|
{
|
||||||
quorum: 0.5,
|
quorum: 1,
|
||||||
fields: ['idCertified', 'roles'],
|
fields: [...privateFields, 'roles', 'uid', 'utype', 'isDeleted'],
|
||||||
min_sig_member: 1,
|
min_sig_member: 1,
|
||||||
},
|
},
|
||||||
{
|
|
||||||
quorum: 0.0,
|
|
||||||
fields: [...privateFields],
|
|
||||||
min_sig_member: 0,
|
|
||||||
},
|
|
||||||
],
|
],
|
||||||
storages: []
|
storages: [...DEFAULT_STORAGE_URLS]
|
||||||
},
|
},
|
||||||
apophis: {
|
apophis: {
|
||||||
members: [ownerId],
|
members: [ownerId, validatorId],
|
||||||
validation_rules: [],
|
validation_rules: [],
|
||||||
storages: []
|
storages: []
|
||||||
}
|
}
|
||||||
|
@ -5,6 +5,7 @@ import User from 'src/sdk/User';
|
|||||||
import AbstractService from './AbstractService';
|
import AbstractService from './AbstractService';
|
||||||
|
|
||||||
import RuleService from './RuleService';
|
import RuleService from './RuleService';
|
||||||
|
import { DEFAULT_STORAGE_URLS } from '@Front/Config/AppConstants';
|
||||||
|
|
||||||
export default class RuleGroupService extends AbstractService {
|
export default class RuleGroupService extends AbstractService {
|
||||||
|
|
||||||
@ -31,7 +32,7 @@ export default class RuleGroupService extends AbstractService {
|
|||||||
|
|
||||||
const roles: any = {
|
const roles: any = {
|
||||||
demiurge: {
|
demiurge: {
|
||||||
members: [...[ownerId], validatorId],
|
members: [ownerId],
|
||||||
validation_rules: [],
|
validation_rules: [],
|
||||||
storages: []
|
storages: []
|
||||||
},
|
},
|
||||||
@ -39,31 +40,26 @@ export default class RuleGroupService extends AbstractService {
|
|||||||
members: [ownerId],
|
members: [ownerId],
|
||||||
validation_rules: [
|
validation_rules: [
|
||||||
{
|
{
|
||||||
quorum: 0.5,
|
quorum: 0.01,
|
||||||
fields: [...privateFields, 'roles', 'uid', 'utype'],
|
fields: [...privateFields, 'roles', 'uid', 'utype', 'isDeleted'],
|
||||||
min_sig_member: 1,
|
min_sig_member: 0.01,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
storages: []
|
storages: [...DEFAULT_STORAGE_URLS]
|
||||||
},
|
},
|
||||||
validator: {
|
validator: {
|
||||||
members: [validatorId],
|
members: [validatorId],
|
||||||
validation_rules: [
|
validation_rules: [
|
||||||
{
|
{
|
||||||
quorum: 0.5,
|
quorum: 1,
|
||||||
fields: ['idCertified', 'roles'],
|
fields: [...privateFields, 'roles', 'uid', 'utype', 'isDeleted'],
|
||||||
min_sig_member: 1,
|
min_sig_member: 1,
|
||||||
},
|
},
|
||||||
{
|
|
||||||
quorum: 0.0,
|
|
||||||
fields: [...privateFields],
|
|
||||||
min_sig_member: 0,
|
|
||||||
},
|
|
||||||
],
|
],
|
||||||
storages: []
|
storages: [...DEFAULT_STORAGE_URLS]
|
||||||
},
|
},
|
||||||
apophis: {
|
apophis: {
|
||||||
members: [ownerId],
|
members: [ownerId, validatorId],
|
||||||
validation_rules: [],
|
validation_rules: [],
|
||||||
storages: []
|
storages: []
|
||||||
}
|
}
|
||||||
|
@ -3,6 +3,7 @@ import { v4 as uuidv4 } from 'uuid';
|
|||||||
import User from 'src/sdk/User';
|
import User from 'src/sdk/User';
|
||||||
|
|
||||||
import AbstractService from './AbstractService';
|
import AbstractService from './AbstractService';
|
||||||
|
import { DEFAULT_STORAGE_URLS } from '@Front/Config/AppConstants';
|
||||||
|
|
||||||
export default class RuleService extends AbstractService {
|
export default class RuleService extends AbstractService {
|
||||||
|
|
||||||
@ -29,7 +30,7 @@ export default class RuleService extends AbstractService {
|
|||||||
|
|
||||||
const roles: any = {
|
const roles: any = {
|
||||||
demiurge: {
|
demiurge: {
|
||||||
members: [...[ownerId], validatorId],
|
members: [ownerId],
|
||||||
validation_rules: [],
|
validation_rules: [],
|
||||||
storages: []
|
storages: []
|
||||||
},
|
},
|
||||||
@ -37,31 +38,26 @@ export default class RuleService extends AbstractService {
|
|||||||
members: [ownerId],
|
members: [ownerId],
|
||||||
validation_rules: [
|
validation_rules: [
|
||||||
{
|
{
|
||||||
quorum: 0.5,
|
quorum: 0.01,
|
||||||
fields: [...privateFields, 'roles', 'uid', 'utype'],
|
fields: [...privateFields, 'roles', 'uid', 'utype', 'isDeleted'],
|
||||||
min_sig_member: 1,
|
min_sig_member: 0.01,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
storages: []
|
storages: [...DEFAULT_STORAGE_URLS]
|
||||||
},
|
},
|
||||||
validator: {
|
validator: {
|
||||||
members: [validatorId],
|
members: [validatorId],
|
||||||
validation_rules: [
|
validation_rules: [
|
||||||
{
|
{
|
||||||
quorum: 0.5,
|
quorum: 1,
|
||||||
fields: ['idCertified', 'roles'],
|
fields: [...privateFields, 'roles', 'isDeleted', 'uid', 'utype'],
|
||||||
min_sig_member: 1,
|
min_sig_member: 1,
|
||||||
},
|
},
|
||||||
{
|
|
||||||
quorum: 0.0,
|
|
||||||
fields: [...privateFields],
|
|
||||||
min_sig_member: 0,
|
|
||||||
},
|
|
||||||
],
|
],
|
||||||
storages: []
|
storages: [...DEFAULT_STORAGE_URLS]
|
||||||
},
|
},
|
||||||
apophis: {
|
apophis: {
|
||||||
members: [ownerId],
|
members: [ownerId, validatorId],
|
||||||
validation_rules: [],
|
validation_rules: [],
|
||||||
storages: []
|
storages: []
|
||||||
}
|
}
|
||||||
|
@ -54,4 +54,17 @@ export default class Auth extends BaseApiService {
|
|||||||
return Promise.reject(err);
|
return Promise.reject(err);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async getIdNotUserForOffice(officeId: string): Promise<any[]> {
|
||||||
|
const baseBackUrl = 'http://localhost:8080';//variables.BACK_API_PROTOCOL + variables.BACK_API_HOST;
|
||||||
|
|
||||||
|
const url = new URL(`${baseBackUrl}/api/v1/idnot/office/rattachements`);
|
||||||
|
url.searchParams.set('idNot', officeId);
|
||||||
|
try {
|
||||||
|
return await this.getRequest(url);
|
||||||
|
} catch (err) {
|
||||||
|
this.onError(err);
|
||||||
|
return Promise.reject(err);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -21,6 +21,7 @@ import DocumentService from "src/common/Api/LeCoffreApi/sdk/DocumentService";
|
|||||||
import FileService from "src/common/Api/LeCoffreApi/sdk/FileService";
|
import FileService from "src/common/Api/LeCoffreApi/sdk/FileService";
|
||||||
import CustomerService from "src/common/Api/LeCoffreApi/sdk/CustomerService";
|
import CustomerService from "src/common/Api/LeCoffreApi/sdk/CustomerService";
|
||||||
import FolderService from "src/common/Api/LeCoffreApi/sdk/FolderService";
|
import FolderService from "src/common/Api/LeCoffreApi/sdk/FolderService";
|
||||||
|
import { DEFAULT_VALIDATOR_ID } from "@Front/Config/AppConstants";
|
||||||
|
|
||||||
type IProps = {
|
type IProps = {
|
||||||
onChange?: (files: File[]) => void;
|
onChange?: (files: File[]) => void;
|
||||||
@ -226,9 +227,8 @@ export default class DepositOtherDocument extends React.Component<IProps, IState
|
|||||||
uid: this.props.customer_uid,
|
uid: this.props.customer_uid,
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
const validatorId: string = '884cb36a346a79af8697559f16940141f068bdf1656f88fa0df0e9ecd7311fb8:0';
|
|
||||||
|
|
||||||
DocumentService.createDocument(documentTypeData, validatorId).then((processCreated: any) => {
|
DocumentService.createDocument(documentTypeData, DEFAULT_VALIDATOR_ID).then((processCreated: any) => {
|
||||||
if (processCreated) {
|
if (processCreated) {
|
||||||
const document: any = processCreated.processData;
|
const document: any = processCreated.processData;
|
||||||
resolve(document);
|
resolve(document);
|
||||||
@ -272,9 +272,8 @@ export default class DepositOtherDocument extends React.Component<IProps, IState
|
|||||||
file_blob: fileBlob,
|
file_blob: fileBlob,
|
||||||
file_name: fileName
|
file_name: fileName
|
||||||
};
|
};
|
||||||
const validatorId: string = '884cb36a346a79af8697559f16940141f068bdf1656f88fa0df0e9ecd7311fb8:0';
|
|
||||||
|
|
||||||
FileService.createFile(fileData, validatorId).then((processCreated: any) => {
|
FileService.createFile(fileData, DEFAULT_VALIDATOR_ID).then((processCreated: any) => {
|
||||||
const fileUid: string = processCreated.processData.uid;
|
const fileUid: string = processCreated.processData.uid;
|
||||||
|
|
||||||
DocumentService.getDocumentByUid(documentCreated.uid).then((process: any) => {
|
DocumentService.getDocumentByUid(documentCreated.uid).then((process: any) => {
|
||||||
|
@ -28,6 +28,8 @@ export default function DefaultDeedTypeDashboard(props: IProps) {
|
|||||||
deedTypes.sort((a: any, b: any) => a.name.localeCompare(b.name));
|
deedTypes.sort((a: any, b: any) => a.name.localeCompare(b.name));
|
||||||
|
|
||||||
setDeedTypes(deedTypes);
|
setDeedTypes(deedTypes);
|
||||||
|
} else {
|
||||||
|
console.log('[DefaultDeedTypeDashboard] No deed types found');
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}, []);
|
}, []);
|
||||||
@ -51,7 +53,7 @@ export default function DefaultDeedTypeDashboard(props: IProps) {
|
|||||||
}
|
}
|
||||||
bottomButton={{
|
bottomButton={{
|
||||||
link: Module.getInstance().get().modules.pages.DeedTypes.pages.Create.props.path,
|
link: Module.getInstance().get().modules.pages.DeedTypes.pages.Create.props.path,
|
||||||
text: "Créer une liste de pièces",
|
text: "Créer une liste de pièces", // TODO I think this is misleading, should be "Créer un type d'acte"
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
|
@ -13,6 +13,7 @@ import FileService from "src/common/Api/LeCoffreApi/sdk/FileService";
|
|||||||
|
|
||||||
import { FileBlob, FileData } from "@Front/Api/Entities/types";
|
import { FileBlob, FileData } from "@Front/Api/Entities/types";
|
||||||
import WatermarkService from "@Front/Services/WatermarkService";
|
import WatermarkService from "@Front/Services/WatermarkService";
|
||||||
|
import { DEFAULT_VALIDATOR_ID } from "@Front/Config/AppConstants";
|
||||||
|
|
||||||
type IProps = {
|
type IProps = {
|
||||||
document: any;
|
document: any;
|
||||||
@ -62,9 +63,8 @@ export default function DepositDocumentComponent(props: IProps) {
|
|||||||
file_blob: fileBlob,
|
file_blob: fileBlob,
|
||||||
file_name: fileName
|
file_name: fileName
|
||||||
};
|
};
|
||||||
const validatorId: string = '884cb36a346a79af8697559f16940141f068bdf1656f88fa0df0e9ecd7311fb8:0';
|
|
||||||
|
|
||||||
FileService.createFile(fileData, validatorId).then((processCreated: any) => {
|
FileService.createFile(fileData, DEFAULT_VALIDATOR_ID).then((processCreated: any) => {
|
||||||
const fileUid: string = processCreated.processData.uid;
|
const fileUid: string = processCreated.processData.uid;
|
||||||
|
|
||||||
DocumentService.getDocumentByUid(document.uid!).then((process: any) => {
|
DocumentService.getDocumentByUid(document.uid!).then((process: any) => {
|
||||||
@ -115,9 +115,8 @@ export default function DepositDocumentComponent(props: IProps) {
|
|||||||
file_blob: fileBlob,
|
file_blob: fileBlob,
|
||||||
file_name: fileName
|
file_name: fileName
|
||||||
};
|
};
|
||||||
const validatorId: string = '884cb36a346a79af8697559f16940141f068bdf1656f88fa0df0e9ecd7311fb8:0';
|
|
||||||
|
|
||||||
FileService.createFile(fileData, validatorId).then((processCreated: any) => {
|
FileService.createFile(fileData, DEFAULT_VALIDATOR_ID).then((processCreated: any) => {
|
||||||
const fileUid: string = processCreated.processData.uid;
|
const fileUid: string = processCreated.processData.uid;
|
||||||
|
|
||||||
DocumentService.getDocumentByUid(document.uid!).then((process: any) => {
|
DocumentService.getDocumentByUid(document.uid!).then((process: any) => {
|
||||||
|
@ -18,6 +18,7 @@ import UserStore from "@Front/Stores/UserStore";
|
|||||||
|
|
||||||
import LoaderService from "src/common/Api/LeCoffreApi/sdk/Loader/LoaderService";
|
import LoaderService from "src/common/Api/LeCoffreApi/sdk/Loader/LoaderService";
|
||||||
import DeedTypeService from "src/common/Api/LeCoffreApi/sdk/DeedTypeService";
|
import DeedTypeService from "src/common/Api/LeCoffreApi/sdk/DeedTypeService";
|
||||||
|
import { DEFAULT_VALIDATOR_ID } from "@Front/Config/AppConstants";
|
||||||
|
|
||||||
type IProps = {};
|
type IProps = {};
|
||||||
export default function DeedTypesCreate(props: IProps) {
|
export default function DeedTypesCreate(props: IProps) {
|
||||||
@ -53,10 +54,9 @@ export default function DeedTypesCreate(props: IProps) {
|
|||||||
uid: officeId,
|
uid: officeId,
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
const validatorId: string = '884cb36a346a79af8697559f16940141f068bdf1656f88fa0df0e9ecd7311fb8:0';
|
|
||||||
|
|
||||||
LoaderService.getInstance().show();
|
LoaderService.getInstance().show();
|
||||||
DeedTypeService.createDeedType(deedTypeData, validatorId).then((processCreated: any) => {
|
DeedTypeService.createDeedType(deedTypeData, DEFAULT_VALIDATOR_ID).then((processCreated: any) => {
|
||||||
ToasterService.getInstance().success({
|
ToasterService.getInstance().success({
|
||||||
title: "Succès !",
|
title: "Succès !",
|
||||||
description: "Type d'acte créé avec succès"
|
description: "Type d'acte créé avec succès"
|
||||||
|
@ -17,51 +17,81 @@ import classes from "./classes.module.scss";
|
|||||||
import DocumentTypeService from "src/common/Api/LeCoffreApi/sdk/DocumentTypeService";
|
import DocumentTypeService from "src/common/Api/LeCoffreApi/sdk/DocumentTypeService";
|
||||||
import LoaderService from "src/common/Api/LeCoffreApi/sdk/Loader/LoaderService";
|
import LoaderService from "src/common/Api/LeCoffreApi/sdk/Loader/LoaderService";
|
||||||
import UserStore from "@Front/Stores/UserStore";
|
import UserStore from "@Front/Stores/UserStore";
|
||||||
|
import { DEFAULT_VALIDATOR_ID } from "@Front/Config/AppConstants";
|
||||||
|
|
||||||
type IProps = {};
|
type IProps = {};
|
||||||
export default function DocumentTypesCreate(props: IProps) {
|
export default function DocumentTypesCreate(props: IProps) {
|
||||||
const [validationError, setValidationError] = useState<ValidationError[]>([]);
|
const [validationError, setValidationError] = useState<ValidationError[]>([]);
|
||||||
|
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
|
|
||||||
|
const handleCancel = useCallback(() => {
|
||||||
|
router.push(Module.getInstance().get().modules.pages.DocumentTypes.props.path);
|
||||||
|
}, [router]);
|
||||||
|
|
||||||
const onSubmitHandler = useCallback(
|
const onSubmitHandler = useCallback(
|
||||||
async (e: React.FormEvent<HTMLFormElement> | null, values: { [key: string]: string }) => {
|
async (e: React.FormEvent<HTMLFormElement> | null, values: { [key: string]: string }) => {
|
||||||
try {
|
try {
|
||||||
const user: any = UserStore.instance.getUser();
|
const user: any = UserStore.instance.getUser();
|
||||||
const officeId: string = user.office.uid;
|
if (!user) {
|
||||||
|
console.error("DocumentTypesCreate: User not found - user is null or undefined");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const office = UserStore.instance.getOffice();
|
||||||
|
if (!office) {
|
||||||
|
console.error("DocumentTypesCreate: office not found - office is undefined or null");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const officeId = office.processId;
|
||||||
|
const officeIdNot = office.processData.idNot;
|
||||||
|
|
||||||
const documentFormModel = DocumentType.hydrate<DocumentType>({
|
// const documentFormModel = DocumentType.hydrate<DocumentType>({
|
||||||
...values,
|
// ...values,
|
||||||
office: Office.hydrate<Office>({
|
// office: Office.hydrate<Office>({
|
||||||
uid: officeId,
|
// uid: officeId,
|
||||||
})
|
// })
|
||||||
});
|
// });
|
||||||
await validateOrReject(documentFormModel, { groups: ["createDocumentType"] });
|
// await validateOrReject(documentFormModel, { groups: ["createDocumentType"] });
|
||||||
|
|
||||||
const documentTypeData: any = {
|
const documentTypeData: any = {
|
||||||
...values,
|
...values,
|
||||||
office: {
|
office: {
|
||||||
uid: officeId,
|
uid: officeId,
|
||||||
|
idNot: officeIdNot,
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
const validatorId: string = '884cb36a346a79af8697559f16940141f068bdf1656f88fa0df0e9ecd7311fb8:0';
|
|
||||||
|
|
||||||
LoaderService.getInstance().show();
|
LoaderService.getInstance().show();
|
||||||
DocumentTypeService.createDocumentType(documentTypeData, validatorId).then((processCreated: any) => {
|
try {
|
||||||
|
const processCreated = await DocumentTypeService.createDocumentType(documentTypeData, DEFAULT_VALIDATOR_ID);
|
||||||
ToasterService.getInstance().success({
|
ToasterService.getInstance().success({
|
||||||
title: "Succès !",
|
title: "Succès !",
|
||||||
description: "Type de document créé avec succès"
|
description: "Type de document créé avec succès"
|
||||||
});
|
});
|
||||||
|
const documentTypeUid = processCreated.processId.split(':')[0];
|
||||||
|
if (!documentTypeUid) {
|
||||||
|
console.error("DocumentTypesCreate: documentTypeUid is undefined - processCreated.processId is missing");
|
||||||
|
return;
|
||||||
|
}
|
||||||
router.push(
|
router.push(
|
||||||
Module.getInstance()
|
Module.getInstance()
|
||||||
.get()
|
.get()
|
||||||
.modules.pages.DocumentTypes.pages.DocumentTypesInformations.props.path.replace("[uid]", processCreated.processData.uid),
|
.modules.pages.DocumentTypes.pages.DocumentTypesInformations.props.path.replace("[uid]", documentTypeUid),
|
||||||
);
|
);
|
||||||
|
} catch (apiError) {
|
||||||
|
ToasterService.getInstance().error({
|
||||||
|
title: "Erreur !",
|
||||||
|
description: "Une erreur est survenue lors de la création du type de document"
|
||||||
|
});
|
||||||
|
console.error("Document type creation error:", apiError);
|
||||||
|
} finally {
|
||||||
LoaderService.getInstance().hide();
|
LoaderService.getInstance().hide();
|
||||||
});
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
if (e instanceof Array) {
|
if (e instanceof Array) {
|
||||||
setValidationError(e);
|
setValidationError(e);
|
||||||
}
|
}
|
||||||
|
LoaderService.getInstance().hide();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
[router],
|
[router],
|
||||||
@ -90,7 +120,7 @@ export default function DocumentTypesCreate(props: IProps) {
|
|||||||
validationError={validationError.find((error) => error.property === "public_description")}
|
validationError={validationError.find((error) => error.property === "public_description")}
|
||||||
/>
|
/>
|
||||||
<div className={classes["buttons-container"]}>
|
<div className={classes["buttons-container"]}>
|
||||||
<Button variant={EButtonVariant.PRIMARY} styletype={EButtonstyletype.OUTLINED}>
|
<Button variant={EButtonVariant.PRIMARY} styletype={EButtonstyletype.OUTLINED} onClick={handleCancel}>
|
||||||
Annuler
|
Annuler
|
||||||
</Button>
|
</Button>
|
||||||
<Button type="submit">Créer le document</Button>
|
<Button type="submit">Créer le document</Button>
|
||||||
|
@ -26,9 +26,12 @@ export default function DocumentTypesEdit() {
|
|||||||
async function getDocumentType() {
|
async function getDocumentType() {
|
||||||
if (!documentTypeUid) return;
|
if (!documentTypeUid) return;
|
||||||
LoaderService.getInstance().show();
|
LoaderService.getInstance().show();
|
||||||
DocumentTypeService.getDocumentTypeByUid(documentTypeUid as string).then((process: any) => {
|
DocumentTypeService.getDocumentTypeByProcessId(documentTypeUid as string).then((process: any) => {
|
||||||
if (process) {
|
if (process) {
|
||||||
const documentType: any = process.processData;
|
const documentType: any = {
|
||||||
|
...process.processData,
|
||||||
|
processId: process.processId
|
||||||
|
};
|
||||||
setDocumentTypeSelected(documentType);
|
setDocumentTypeSelected(documentType);
|
||||||
}
|
}
|
||||||
LoaderService.getInstance().hide();
|
LoaderService.getInstance().hide();
|
||||||
@ -53,7 +56,7 @@ export default function DocumentTypesEdit() {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
LoaderService.getInstance().show();
|
LoaderService.getInstance().show();
|
||||||
DocumentTypeService.getDocumentTypeByUid(documentTypeUid as string).then((process: any) => {
|
DocumentTypeService.getDocumentTypeByProcessId(documentTypeUid as string).then((process: any) => {
|
||||||
if (process) {
|
if (process) {
|
||||||
DocumentTypeService.updateDocumentType(process, values).then(() => {
|
DocumentTypeService.updateDocumentType(process, values).then(() => {
|
||||||
router.push(
|
router.push(
|
||||||
|
@ -22,13 +22,23 @@ export default function DocumentTypesInformations() {
|
|||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
async function getDocument() {
|
async function getDocument() {
|
||||||
if (!documentTypeUid) return;
|
if (!documentTypeUid) {
|
||||||
|
console.log('DocumentTypesInformations: documentTypeUid is not available yet');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
DocumentTypeService.getDocumentTypeByUid(documentTypeUid as string).then((process: any) => {
|
DocumentTypeService.getDocumentTypeByProcessId(documentTypeUid as string).then((process: any) => {
|
||||||
if (process) {
|
if (process) {
|
||||||
const document: any = process.processData;
|
const document: any = {
|
||||||
|
...process.processData,
|
||||||
|
processId: process.processId
|
||||||
|
};
|
||||||
setDocumentSelected(document);
|
setDocumentSelected(document);
|
||||||
|
} else {
|
||||||
|
console.log('DocumentTypesInformations: No process found for processId:', documentTypeUid);
|
||||||
}
|
}
|
||||||
|
}).catch((error) => {
|
||||||
|
console.error('DocumentTypesInformations: Error fetching document:', error);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -69,13 +79,15 @@ export default function DocumentTypesInformations() {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className={classes["right"]}>
|
<div className={classes["right"]}>
|
||||||
<Link
|
{(documentSelected as any)?.processId && (
|
||||||
href={Module.getInstance()
|
<Link
|
||||||
.get()
|
href={Module.getInstance()
|
||||||
.modules.pages.DocumentTypes.pages.Edit.props.path.replace("[uid]", documentSelected?.uid ?? "")}
|
.get()
|
||||||
className={classes["edit-icon-container"]}>
|
.modules.pages.DocumentTypes.pages.Edit.props.path.replace("[uid]", (documentSelected as any).processId)}
|
||||||
<Image src={PenICon} alt="edit informations" />
|
className={classes["edit-icon-container"]}>
|
||||||
</Link>
|
<Image src={PenICon} alt="edit informations" />
|
||||||
|
</Link>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -21,6 +21,7 @@ import DefaultDoubleSidePage from "@Front/Components/LayoutTemplates/DefaultDoub
|
|||||||
import LoaderService from "src/common/Api/LeCoffreApi/sdk/Loader/LoaderService";
|
import LoaderService from "src/common/Api/LeCoffreApi/sdk/Loader/LoaderService";
|
||||||
import CustomerService from "src/common/Api/LeCoffreApi/sdk/CustomerService";
|
import CustomerService from "src/common/Api/LeCoffreApi/sdk/CustomerService";
|
||||||
import FolderService from "src/common/Api/LeCoffreApi/sdk/FolderService";
|
import FolderService from "src/common/Api/LeCoffreApi/sdk/FolderService";
|
||||||
|
import { DEFAULT_VALIDATOR_ID } from "../../../../Config/AppConstants";
|
||||||
|
|
||||||
enum ESelectedOption {
|
enum ESelectedOption {
|
||||||
EXISTING_CUSTOMER = "existing_customer",
|
EXISTING_CUSTOMER = "existing_customer",
|
||||||
@ -78,10 +79,9 @@ export default function AddClientToFolder(props: IProps) {
|
|||||||
const customerData: any = {
|
const customerData: any = {
|
||||||
contact: values
|
contact: values
|
||||||
};
|
};
|
||||||
const validatorId: string = '884cb36a346a79af8697559f16940141f068bdf1656f88fa0df0e9ecd7311fb8:0';
|
|
||||||
|
|
||||||
LoaderService.getInstance().show();
|
LoaderService.getInstance().show();
|
||||||
CustomerService.createCustomer(customerData, validatorId).then((processCreated: any) => {
|
CustomerService.createCustomer(customerData, DEFAULT_VALIDATOR_ID).then((processCreated: any) => {
|
||||||
FolderService.getFolderByUid(folderUid as string).then((process: any) => {
|
FolderService.getFolderByUid(folderUid as string).then((process: any) => {
|
||||||
if (process) {
|
if (process) {
|
||||||
const customers: any[] = [];
|
const customers: any[] = [];
|
||||||
|
@ -13,6 +13,7 @@ import classes from "./classes.module.scss";
|
|||||||
import DocumentTypeService from "src/common/Api/LeCoffreApi/sdk/DocumentTypeService";
|
import DocumentTypeService from "src/common/Api/LeCoffreApi/sdk/DocumentTypeService";
|
||||||
import DeedTypeService from "src/common/Api/LeCoffreApi/sdk/DeedTypeService";
|
import DeedTypeService from "src/common/Api/LeCoffreApi/sdk/DeedTypeService";
|
||||||
import LoaderService from "src/common/Api/LeCoffreApi/sdk/Loader/LoaderService";
|
import LoaderService from "src/common/Api/LeCoffreApi/sdk/Loader/LoaderService";
|
||||||
|
import { DEFAULT_VALIDATOR_ID } from "@Front/Config/AppConstants";
|
||||||
|
|
||||||
type IProps = {
|
type IProps = {
|
||||||
isCreateDocumentModalVisible: boolean;
|
isCreateDocumentModalVisible: boolean;
|
||||||
@ -85,10 +86,9 @@ export default function ParameterDocuments(props: IProps) {
|
|||||||
},
|
},
|
||||||
public_description: visibleDescription,
|
public_description: visibleDescription,
|
||||||
};
|
};
|
||||||
const validatorId: string = '884cb36a346a79af8697559f16940141f068bdf1656f88fa0df0e9ecd7311fb8:0';
|
|
||||||
|
|
||||||
const documentType: any = await new Promise<any>((resolve: (documentType: any) => void) => {
|
const documentType: any = await new Promise<any>((resolve: (documentType: any) => void) => {
|
||||||
DocumentTypeService.createDocumentType(documentTypeData, validatorId).then((processCreated: any) => {
|
DocumentTypeService.createDocumentType(documentTypeData, DEFAULT_VALIDATOR_ID).then((processCreated: any) => {
|
||||||
const documentType: any = processCreated.processData;
|
const documentType: any = processCreated.processData;
|
||||||
resolve(documentType);
|
resolve(documentType);
|
||||||
});
|
});
|
||||||
|
@ -18,6 +18,7 @@ import backgroundImage from "@Assets/images/background_refonte.svg";
|
|||||||
import FolderService from "src/common/Api/LeCoffreApi/sdk/FolderService";
|
import FolderService from "src/common/Api/LeCoffreApi/sdk/FolderService";
|
||||||
import DocumentService from "src/common/Api/LeCoffreApi/sdk/DocumentService";
|
import DocumentService from "src/common/Api/LeCoffreApi/sdk/DocumentService";
|
||||||
import LoaderService from "src/common/Api/LeCoffreApi/sdk/Loader/LoaderService";
|
import LoaderService from "src/common/Api/LeCoffreApi/sdk/Loader/LoaderService";
|
||||||
|
import { DEFAULT_VALIDATOR_ID } from "@Front/Config/AppConstants";
|
||||||
|
|
||||||
export default function AskDocuments() {
|
export default function AskDocuments() {
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
@ -78,9 +79,8 @@ export default function AskDocuments() {
|
|||||||
document_status: EDocumentStatus.ASKED,
|
document_status: EDocumentStatus.ASKED,
|
||||||
file_uid: null,
|
file_uid: null,
|
||||||
};
|
};
|
||||||
const validatorId: string = '884cb36a346a79af8697559f16940141f068bdf1656f88fa0df0e9ecd7311fb8:0';
|
|
||||||
|
|
||||||
await DocumentService.createDocument(documentData, validatorId);
|
await DocumentService.createDocument(documentData, DEFAULT_VALIDATOR_ID);
|
||||||
}
|
}
|
||||||
|
|
||||||
FolderService.refreshFolderByUid(folderUid as string).then(() => {
|
FolderService.refreshFolderByUid(folderUid as string).then(() => {
|
||||||
|
@ -18,6 +18,7 @@ import FolderService from "src/common/Api/LeCoffreApi/sdk/FolderService";
|
|||||||
import CustomerService from "src/common/Api/LeCoffreApi/sdk/CustomerService";
|
import CustomerService from "src/common/Api/LeCoffreApi/sdk/CustomerService";
|
||||||
import NoteService from "src/common/Api/LeCoffreApi/sdk/NoteService";
|
import NoteService from "src/common/Api/LeCoffreApi/sdk/NoteService";
|
||||||
import LoaderService from "src/common/Api/LeCoffreApi/sdk/Loader/LoaderService";
|
import LoaderService from "src/common/Api/LeCoffreApi/sdk/Loader/LoaderService";
|
||||||
|
import { DEFAULT_VALIDATOR_ID } from "@Front/Config/AppConstants";
|
||||||
|
|
||||||
type IProps = {};
|
type IProps = {};
|
||||||
|
|
||||||
@ -124,10 +125,8 @@ class CreateCustomerNoteClass extends BasePage<IPropsClass, IState> {
|
|||||||
uid: this.state.customer.uid
|
uid: this.state.customer.uid
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
const validatorId: string = '884cb36a346a79af8697559f16940141f068bdf1656f88fa0df0e9ecd7311fb8:0';
|
|
||||||
|
|
||||||
LoaderService.getInstance().show();
|
LoaderService.getInstance().show();
|
||||||
NoteService.createNote(noteData, validatorId).then(() => {
|
NoteService.createNote(noteData, DEFAULT_VALIDATOR_ID).then(() => {
|
||||||
this.props.router.push(this.backwardPath);
|
this.props.router.push(this.backwardPath);
|
||||||
});
|
});
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
@ -23,6 +23,7 @@ import FolderService from "src/common/Api/LeCoffreApi/sdk/FolderService";
|
|||||||
import DocumentService from "src/common/Api/LeCoffreApi/sdk/DocumentService";
|
import DocumentService from "src/common/Api/LeCoffreApi/sdk/DocumentService";
|
||||||
import FileService from "src/common/Api/LeCoffreApi/sdk/FileService";
|
import FileService from "src/common/Api/LeCoffreApi/sdk/FileService";
|
||||||
import CustomerService from "src/common/Api/LeCoffreApi/sdk/CustomerService";
|
import CustomerService from "src/common/Api/LeCoffreApi/sdk/CustomerService";
|
||||||
|
import { DEFAULT_VALIDATOR_ID } from "@Front/Config/AppConstants";
|
||||||
|
|
||||||
enum EClientSelection {
|
enum EClientSelection {
|
||||||
ALL_CLIENTS = "all_clients",
|
ALL_CLIENTS = "all_clients",
|
||||||
@ -97,9 +98,8 @@ export default function SendDocuments() {
|
|||||||
file_blob: fileBlob,
|
file_blob: fileBlob,
|
||||||
file_name: fileName
|
file_name: fileName
|
||||||
};
|
};
|
||||||
const validatorId: string = '884cb36a346a79af8697559f16940141f068bdf1656f88fa0df0e9ecd7311fb8:0';
|
|
||||||
|
|
||||||
FileService.createFile(fileData, validatorId).then((processCreated: any) => {
|
FileService.createFile(fileData, DEFAULT_VALIDATOR_ID).then((processCreated: any) => {
|
||||||
const fileUid: string = processCreated.processData.uid;
|
const fileUid: string = processCreated.processData.uid;
|
||||||
|
|
||||||
const documentData: any = {
|
const documentData: any = {
|
||||||
@ -117,7 +117,7 @@ export default function SendDocuments() {
|
|||||||
document_status: EDocumentNotaryStatus.SENT
|
document_status: EDocumentNotaryStatus.SENT
|
||||||
};
|
};
|
||||||
|
|
||||||
DocumentService.createDocument(documentData, validatorId).then(() => {
|
DocumentService.createDocument(documentData, DEFAULT_VALIDATOR_ID).then(() => {
|
||||||
FolderService.refreshFolderByUid(folderUid as string).then(() => resolve());
|
FolderService.refreshFolderByUid(folderUid as string).then(() => resolve());
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -51,7 +51,7 @@ export default function StepEmail(props: IProps) {
|
|||||||
);
|
);
|
||||||
*/
|
*/
|
||||||
router.push(
|
router.push(
|
||||||
`https://qual-connexion.idnot.fr/user/IdPOAuth2/authorize/idnot_idp_v1?client_id=B3CE56353EDB15A9&redirect_uri=http://local.lecoffreio.4nkweb:3000/authorized-client&scope=openid,profile&response_type=code`,
|
`https://qual-connexion.idnot.fr/user/IdPOAuth2/authorize/idnot_idp_v1?client_id=B3CE56353EDB15A9&redirect_uri=http://127.0.0.1:3000/authorized-client&scope=openid,profile&response_type=code`,
|
||||||
);
|
);
|
||||||
}, [router]);
|
}, [router]);
|
||||||
|
|
||||||
|
@ -21,6 +21,8 @@ import UserStore from "@Front/Stores/UserStore";
|
|||||||
|
|
||||||
import AuthModal from "src/sdk/AuthModal";
|
import AuthModal from "src/sdk/AuthModal";
|
||||||
import CustomerService from "src/common/Api/LeCoffreApi/sdk/CustomerService";
|
import CustomerService from "src/common/Api/LeCoffreApi/sdk/CustomerService";
|
||||||
|
import MessageBus from "src/sdk/MessageBus";
|
||||||
|
import { resolve } from "path";
|
||||||
|
|
||||||
export enum LoginStep {
|
export enum LoginStep {
|
||||||
EMAIL,
|
EMAIL,
|
||||||
@ -41,6 +43,7 @@ export default function Login() {
|
|||||||
const [totpCode, setTotpCode] = useState<string>("");
|
const [totpCode, setTotpCode] = useState<string>("");
|
||||||
const [email, setEmail] = useState<string>("");
|
const [email, setEmail] = useState<string>("");
|
||||||
const [partialPhoneNumber, setPartialPhoneNumber] = useState<string>("");
|
const [partialPhoneNumber, setPartialPhoneNumber] = useState<string>("");
|
||||||
|
const [sessionId, setSessionId] = useState<string>("");
|
||||||
const [validationErrors, setValidationErrors] = useState<ValidationError[]>([]);
|
const [validationErrors, setValidationErrors] = useState<ValidationError[]>([]);
|
||||||
const [isAuthModalOpen, setIsAuthModalOpen] = useState(false);
|
const [isAuthModalOpen, setIsAuthModalOpen] = useState(false);
|
||||||
|
|
||||||
@ -92,10 +95,13 @@ export default function Login() {
|
|||||||
// If the code is valid setting it in state
|
// If the code is valid setting it in state
|
||||||
if (res.validCode) {
|
if (res.validCode) {
|
||||||
setTotpCode(values["totpCode"]);
|
setTotpCode(values["totpCode"]);
|
||||||
|
setSessionId(res.sessionId); // Store the session ID
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
if ('1234' === values["totpCode"]) {
|
if ('1234' === values["totpCode"]) {
|
||||||
setTotpCode(values["totpCode"]);
|
setTotpCode(values["totpCode"]);
|
||||||
|
// For testing, set a mock session ID
|
||||||
|
setSessionId("mock-session-id-123");
|
||||||
}
|
}
|
||||||
|
|
||||||
setValidationErrors([]);
|
setValidationErrors([]);
|
||||||
@ -265,17 +271,43 @@ export default function Login() {
|
|||||||
{isAuthModalOpen && <AuthModal
|
{isAuthModalOpen && <AuthModal
|
||||||
isOpen={isAuthModalOpen}
|
isOpen={isAuthModalOpen}
|
||||||
onClose={() => {
|
onClose={() => {
|
||||||
CustomerService.getCustomers().then((processes: any[]) => {
|
// After 4nk authentication is complete, get the process for the pairing ID
|
||||||
if (processes.length > 0) {
|
MessageBus.getInstance().initMessageListener();
|
||||||
const customers: any[] = processes.map((process: any) => process.processData);
|
MessageBus.getInstance().isReady().then(async () => {
|
||||||
const customer: any = customers.find((customer: any) => customer.contact.email === email);
|
try {
|
||||||
if (customer) {
|
// Find the customer
|
||||||
UserStore.instance.connect(customer);
|
const customer: any = (await CustomerService.getCustomers())
|
||||||
|
.map((process: any) => process.processData)
|
||||||
|
.find((customer: any) => customer.contact.email === email);
|
||||||
|
|
||||||
|
// Get the pairing ID
|
||||||
|
const pairingId = await MessageBus.getInstance().getPairingId();
|
||||||
|
console.log('[Login] Got pairing ID:', pairingId);
|
||||||
|
|
||||||
|
// Get all processes
|
||||||
|
const processes = await MessageBus.getInstance().getProcesses();
|
||||||
|
console.log('[Login] Got processes:', Object.keys(processes));
|
||||||
|
|
||||||
|
const targetProcess = processes[pairingId];
|
||||||
|
|
||||||
|
if (targetProcess) {
|
||||||
|
console.log('[Login] Found target process:', targetProcess);
|
||||||
|
// Connect the user with the process data
|
||||||
|
UserStore.instance.connect(customer /*targetProcess*/);
|
||||||
router.push(Module.getInstance().get().modules.pages.Folder.pages.Select.props.path);
|
router.push(Module.getInstance().get().modules.pages.Folder.pages.Select.props.path);
|
||||||
|
} else {
|
||||||
|
console.error('[Login] No process found for pairing ID:', pairingId);
|
||||||
|
// Handle the case where no process is found
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MessageBus.getInstance().destroyMessageListener();
|
||||||
|
} catch (error) {
|
||||||
|
console.error('[Login] Error getting process:', error);
|
||||||
|
MessageBus.getInstance().destroyMessageListener();
|
||||||
}
|
}
|
||||||
setIsAuthModalOpen(false);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
setIsAuthModalOpen(false);
|
||||||
}}
|
}}
|
||||||
/>}
|
/>}
|
||||||
</div>
|
</div>
|
||||||
|
@ -26,6 +26,7 @@ import RoleService from "src/common/Api/LeCoffreApi/sdk/RoleService";
|
|||||||
import OfficeService from "src/common/Api/LeCoffreApi/sdk/OfficeService";
|
import OfficeService from "src/common/Api/LeCoffreApi/sdk/OfficeService";
|
||||||
import OfficeRoleService from "src/common/Api/LeCoffreApi/sdk/OfficeRoleService";
|
import OfficeRoleService from "src/common/Api/LeCoffreApi/sdk/OfficeRoleService";
|
||||||
import CollaboratorService from "src/common/Api/LeCoffreApi/sdk/CollaboratorService";
|
import CollaboratorService from "src/common/Api/LeCoffreApi/sdk/CollaboratorService";
|
||||||
|
import { DEFAULT_STORAGE_URLS, DEFAULT_VALIDATOR_ID } from "@Front/Config/AppConstants";
|
||||||
|
|
||||||
export default function LoginCallBack() {
|
export default function LoginCallBack() {
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
@ -45,10 +46,23 @@ export default function LoginCallBack() {
|
|||||||
const getOffice = async (idNotUser: any) => {
|
const getOffice = async (idNotUser: any) => {
|
||||||
return await new Promise<any>((resolve: (office: any) => void) => {
|
return await new Promise<any>((resolve: (office: any) => void) => {
|
||||||
OfficeService.getOffices().then((processes: any[]) => {
|
OfficeService.getOffices().then((processes: any[]) => {
|
||||||
const officeFound: any = processes.length > 0 ? processes.map((process: any) => process.processData).find((office: any) => office.idNot === idNotUser.office.idNot) : null;
|
const officeFound: any = processes.length > 0 ? processes.find((office: any) => office.processData.idNot === idNotUser.office.idNot) : null;
|
||||||
if (officeFound) {
|
if (officeFound) {
|
||||||
resolve(officeFound);
|
resolve(officeFound);
|
||||||
} else {
|
} 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}`);
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
// We create office
|
||||||
const officeData: any = {
|
const officeData: any = {
|
||||||
idNot: idNotUser.office.idNot,
|
idNot: idNotUser.office.idNot,
|
||||||
name: idNotUser.office.name,
|
name: idNotUser.office.name,
|
||||||
@ -60,17 +74,29 @@ export default function LoginCallBack() {
|
|||||||
city: idNotUser.office.address.city
|
city: idNotUser.office.address.city
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
office_status: 'ACTIVATED'
|
office_status: idNotUser.office.office_status // must be ACTIVATED though
|
||||||
};
|
};
|
||||||
const validatorId: string = '884cb36a346a79af8697559f16940141f068bdf1656f88fa0df0e9ecd7311fb8:0';
|
|
||||||
|
|
||||||
OfficeService.createOffice(officeData, validatorId).then((process: any) => {
|
Auth.getInstance().getIdNotUserForOffice(idNotUser.office.idNot).then((users: any) => {
|
||||||
if (process) {
|
console.log('users : ', users);
|
||||||
const office: any = process.processData;
|
const activeUsers = users.result.filter((user: any) => user.activite === 'En exercice');
|
||||||
resolve(office);
|
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;
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
@ -79,22 +105,36 @@ export default function LoginCallBack() {
|
|||||||
return await new Promise<any>(async (resolve: (role: any) => void) => {
|
return await new Promise<any>(async (resolve: (role: any) => void) => {
|
||||||
const processFound: any | null = await CollaboratorService.getCollaboratorBy({ idNot: idNotUser.idNot });
|
const processFound: any | null = await CollaboratorService.getCollaboratorBy({ idNot: idNotUser.idNot });
|
||||||
if (processFound) {
|
if (processFound) {
|
||||||
resolve(processFound.processData);
|
console.log('Found a collaborator for idNot', idNotUser.idNot);
|
||||||
} else {
|
// TODO: check if the collaborator is in the office process
|
||||||
const validatorId: string = '884cb36a346a79af8697559f16940141f068bdf1656f88fa0df0e9ecd7311fb8:0';
|
|
||||||
const office: any = await getOffice(idNotUser);
|
const office: any = await getOffice(idNotUser);
|
||||||
|
// Take the role of the collaborator
|
||||||
if (!await ImportData.isDone()) {
|
MessageBus.getInstance().getRolesForProcess(processFound.processId).then((roles: any) => {
|
||||||
LoaderService.getInstance().hide();
|
console.log('roles : ', roles);
|
||||||
setShowProgress(true);
|
// We should find one pairing id in the role 'owner'
|
||||||
|
const owners = roles['owner'].members;
|
||||||
await ImportData.import(office, validatorId, (info: ProgressInfo) => {
|
if (owners.length !== 1) {
|
||||||
setProgressInfo(info);
|
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);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
});
|
||||||
setShowProgress(false);
|
} else {
|
||||||
LoaderService.getInstance().show();
|
console.log('No collaborator found for idNot', idNotUser.idNot);
|
||||||
}
|
const office: any = await getOffice(idNotUser);
|
||||||
|
|
||||||
const role: any = (await RoleService.getRoles())
|
const role: any = (await RoleService.getRoles())
|
||||||
.map((process: any) => process.processData)
|
.map((process: any) => process.processData)
|
||||||
@ -102,9 +142,21 @@ export default function LoginCallBack() {
|
|||||||
|
|
||||||
const officeRole: any = (await OfficeRoleService.getOfficeRoles())
|
const officeRole: any = (await OfficeRoleService.getOfficeRoles())
|
||||||
.map((process: any) => process.processData)
|
.map((process: any) => process.processData)
|
||||||
.filter((officeRole: any) => officeRole.office.uid === office.uid)
|
.filter((officeRole: any) => officeRole.office.uid === office.processData.uid)
|
||||||
.find((officeRole: any) => officeRole.name === idNotUser.office_role.name);
|
.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 = {
|
const collaboratorData: any = {
|
||||||
idNot: idNotUser.idNot,
|
idNot: idNotUser.idNot,
|
||||||
contact: idNotUser.contact,
|
contact: idNotUser.contact,
|
||||||
@ -119,12 +171,40 @@ export default function LoginCallBack() {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
CollaboratorService.createCollaborator(collaboratorData, validatorId).then((process: any) => {
|
CollaboratorService.createCollaborator(collaboratorData, DEFAULT_VALIDATOR_ID).then((newCollaborator: any) => {
|
||||||
if (process) {
|
if (newCollaborator) {
|
||||||
const collaborator: any = process.processData;
|
// Now that we created the collaborator, we must check that it's in the office roles (probably not)
|
||||||
resolve(collaborator);
|
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);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
@ -153,6 +233,7 @@ export default function LoginCallBack() {
|
|||||||
const user: any = await Auth.getInstance().getIdNotUser(code as string);
|
const user: any = await Auth.getInstance().getIdNotUser(code as string);
|
||||||
setIdNotUser(user.idNotUser);
|
setIdNotUser(user.idNotUser);
|
||||||
setIsAuthModalOpen(true);
|
setIsAuthModalOpen(true);
|
||||||
|
console.log('[LoginCallback] idNotUser', idNotUser);
|
||||||
/*
|
/*
|
||||||
const token: any = null;
|
const token: any = null;
|
||||||
if (!token) return router.push(Module.getInstance().get().modules.pages.Login.props.path);
|
if (!token) return router.push(Module.getInstance().get().modules.pages.Login.props.path);
|
||||||
@ -274,7 +355,11 @@ export default function LoginCallBack() {
|
|||||||
MessageBus.getInstance().initMessageListener();
|
MessageBus.getInstance().initMessageListener();
|
||||||
MessageBus.getInstance().isReady().then(async () => {
|
MessageBus.getInstance().isReady().then(async () => {
|
||||||
const collaborator: any = await getCollaborator(idNotUser);
|
const collaborator: any = await getCollaborator(idNotUser);
|
||||||
UserStore.instance.connect(collaborator);
|
if (!UserStore.instance.connect(collaborator)) {
|
||||||
|
console.error('[LoginCallback] collaborator not connected');
|
||||||
|
router.push(Module.getInstance().get().modules.pages.Login.props.path + "?error=1");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
MessageBus.getInstance().destroyMessageListener();
|
MessageBus.getInstance().destroyMessageListener();
|
||||||
LoaderService.getInstance().hide();
|
LoaderService.getInstance().hide();
|
||||||
|
@ -11,6 +11,7 @@ import Loader from "@Front/Components/DesignSystem/Loader";
|
|||||||
|
|
||||||
import LoaderService from "src/common/Api/LeCoffreApi/sdk/Loader/LoaderService";
|
import LoaderService from "src/common/Api/LeCoffreApi/sdk/Loader/LoaderService";
|
||||||
import OfficeRibService from "src/common/Api/LeCoffreApi/sdk/OfficeRibService";
|
import OfficeRibService from "src/common/Api/LeCoffreApi/sdk/OfficeRibService";
|
||||||
|
import { DEFAULT_VALIDATOR_ID } from "../../../Config/AppConstants";
|
||||||
|
|
||||||
export default function Rib() {
|
export default function Rib() {
|
||||||
const [documentList, setDocumentList] = useState<File[]>([]);
|
const [documentList, setDocumentList] = useState<File[]>([]);
|
||||||
@ -80,9 +81,8 @@ export default function Rib() {
|
|||||||
file_blob: fileBlob,
|
file_blob: fileBlob,
|
||||||
file_name: fileName
|
file_name: fileName
|
||||||
};
|
};
|
||||||
const validatorId: string = '884cb36a346a79af8697559f16940141f068bdf1656f88fa0df0e9ecd7311fb8:0';
|
|
||||||
|
|
||||||
OfficeRibService.createOfficeRib(fileData, validatorId).then(() => {
|
OfficeRibService.createOfficeRib(fileData, DEFAULT_VALIDATOR_ID).then(() => {
|
||||||
LoaderService.getInstance().hide();
|
LoaderService.getInstance().hide();
|
||||||
onCloseRibModal();
|
onCloseRibModal();
|
||||||
|
|
||||||
|
@ -20,6 +20,7 @@ import { ValidationError } from "class-validator";
|
|||||||
import RoleService from "src/common/Api/LeCoffreApi/sdk/RoleService";
|
import RoleService from "src/common/Api/LeCoffreApi/sdk/RoleService";
|
||||||
import LoaderService from "src/common/Api/LeCoffreApi/sdk/Loader/LoaderService";
|
import LoaderService from "src/common/Api/LeCoffreApi/sdk/Loader/LoaderService";
|
||||||
import UserStore from "@Front/Stores/UserStore";
|
import UserStore from "@Front/Stores/UserStore";
|
||||||
|
import { DEFAULT_VALIDATOR_ID } from "@Front/Config/AppConstants";
|
||||||
|
|
||||||
type IProps = {};
|
type IProps = {};
|
||||||
export default function RolesCreate(props: IProps) {
|
export default function RolesCreate(props: IProps) {
|
||||||
@ -54,10 +55,9 @@ export default function RolesCreate(props: IProps) {
|
|||||||
uid: officeId,
|
uid: officeId,
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
const validatorId: string = '884cb36a346a79af8697559f16940141f068bdf1656f88fa0df0e9ecd7311fb8:0';
|
|
||||||
|
|
||||||
LoaderService.getInstance().show();
|
LoaderService.getInstance().show();
|
||||||
RoleService.createRole(roleData, validatorId).then((processCreated: any) => {
|
RoleService.createRole(roleData, DEFAULT_VALIDATOR_ID).then((processCreated: any) => {
|
||||||
if (processCreated) {
|
if (processCreated) {
|
||||||
ToasterService.getInstance().success({
|
ToasterService.getInstance().success({
|
||||||
title: "Succès !",
|
title: "Succès !",
|
||||||
|
20
src/front/Config/AppConstants.ts
Normal file
20
src/front/Config/AppConstants.ts
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
/**
|
||||||
|
* Application-wide constants
|
||||||
|
* This file contains constants that are used across multiple components and services
|
||||||
|
*/
|
||||||
|
|
||||||
|
export const APP_CONSTANTS = {
|
||||||
|
/**
|
||||||
|
* Default validator ID used for creating various entities (customers, documents, roles, etc.)
|
||||||
|
* This is a system-level validator that has permissions to create and manage entities
|
||||||
|
*/
|
||||||
|
DEFAULT_VALIDATOR_ID: 'c87bbb4873fd4c8427655b083b098c4b3f3a8ebf436d286b69c8036db4a2a029:0',
|
||||||
|
} as const;
|
||||||
|
|
||||||
|
// Export individual constants for easier imports
|
||||||
|
export const DEFAULT_VALIDATOR_ID = APP_CONSTANTS.DEFAULT_VALIDATOR_ID;
|
||||||
|
|
||||||
|
// Define
|
||||||
|
export const DEFAULT_STORAGE_URLS = [
|
||||||
|
'https://dev3.4nkweb.com/storage'
|
||||||
|
] as const;
|
@ -5,6 +5,8 @@ export class FrontendVariables {
|
|||||||
|
|
||||||
public BACK_API_HOST!: string;
|
public BACK_API_HOST!: string;
|
||||||
|
|
||||||
|
public BACK_API_PORT!: string;
|
||||||
|
|
||||||
public BACK_API_ROOT_URL!: string;
|
public BACK_API_ROOT_URL!: string;
|
||||||
|
|
||||||
public BACK_API_VERSION!: string;
|
public BACK_API_VERSION!: string;
|
||||||
|
@ -24,6 +24,7 @@ type AppPropsWithLayout = AppProps & {
|
|||||||
} & {
|
} & {
|
||||||
backApiProtocol: string;
|
backApiProtocol: string;
|
||||||
backApiHost: string;
|
backApiHost: string;
|
||||||
|
backApiPort: string;
|
||||||
backApiRootUrl: string;
|
backApiRootUrl: string;
|
||||||
backApiVersion: string;
|
backApiVersion: string;
|
||||||
frontAppHost: string;
|
frontAppHost: string;
|
||||||
@ -46,6 +47,7 @@ const MyApp = (({
|
|||||||
pageProps,
|
pageProps,
|
||||||
backApiProtocol,
|
backApiProtocol,
|
||||||
backApiHost,
|
backApiHost,
|
||||||
|
backApiPort,
|
||||||
backApiRootUrl,
|
backApiRootUrl,
|
||||||
backApiVersion,
|
backApiVersion,
|
||||||
frontAppHost,
|
frontAppHost,
|
||||||
@ -65,6 +67,7 @@ const MyApp = (({
|
|||||||
const instance = FrontendVariables.getInstance();
|
const instance = FrontendVariables.getInstance();
|
||||||
instance.BACK_API_PROTOCOL = backApiProtocol;
|
instance.BACK_API_PROTOCOL = backApiProtocol;
|
||||||
instance.BACK_API_HOST = backApiHost;
|
instance.BACK_API_HOST = backApiHost;
|
||||||
|
instance.BACK_API_PORT = backApiPort;
|
||||||
instance.BACK_API_ROOT_URL = backApiRootUrl;
|
instance.BACK_API_ROOT_URL = backApiRootUrl;
|
||||||
instance.BACK_API_VERSION = backApiVersion;
|
instance.BACK_API_VERSION = backApiVersion;
|
||||||
instance.FRONT_APP_HOST = frontAppHost;
|
instance.FRONT_APP_HOST = frontAppHost;
|
||||||
@ -129,6 +132,7 @@ MyApp.getInitialProps = async () => {
|
|||||||
return {
|
return {
|
||||||
backApiProtocol: publicRuntimeConfig.NEXT_PUBLIC_BACK_API_PROTOCOL,
|
backApiProtocol: publicRuntimeConfig.NEXT_PUBLIC_BACK_API_PROTOCOL,
|
||||||
backApiHost: publicRuntimeConfig.NEXT_PUBLIC_BACK_API_HOST,
|
backApiHost: publicRuntimeConfig.NEXT_PUBLIC_BACK_API_HOST,
|
||||||
|
backApiPort: publicRuntimeConfig.NEXT_PUBLIC_BACK_API_PORT,
|
||||||
backApiRootUrl: publicRuntimeConfig.NEXT_PUBLIC_BACK_API_ROOT_URL,
|
backApiRootUrl: publicRuntimeConfig.NEXT_PUBLIC_BACK_API_ROOT_URL,
|
||||||
backApiVersion: publicRuntimeConfig.NEXT_PUBLIC_BACK_API_VERSION,
|
backApiVersion: publicRuntimeConfig.NEXT_PUBLIC_BACK_API_VERSION,
|
||||||
frontAppHost: publicRuntimeConfig.NEXT_PUBLIC_FRONT_APP_HOST,
|
frontAppHost: publicRuntimeConfig.NEXT_PUBLIC_FRONT_APP_HOST,
|
||||||
|
@ -70,6 +70,20 @@ export default function AuthModal({ isOpen, onClose }: AuthModalProps) {
|
|||||||
iframeRef.current.contentWindow!.postMessage({ type: 'GET_PAIRING_ID', accessToken: message.accessToken, messageId }, targetOrigin);
|
iframeRef.current.contentWindow!.postMessage({ type: 'GET_PAIRING_ID', accessToken: message.accessToken, messageId }, targetOrigin);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case 'PAIRING_CREATED': {
|
||||||
|
console.log('[AuthModal] PAIRING_CREATED:', message);
|
||||||
|
User.getInstance().setPairingId(message.userPairingId);
|
||||||
|
setAuthSuccess(true);
|
||||||
|
|
||||||
|
setTimeout(() => {
|
||||||
|
setShowIframe(false);
|
||||||
|
setIsIframeReady(false);
|
||||||
|
setAuthSuccess(false);
|
||||||
|
onClose();
|
||||||
|
}, 500);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case 'GET_PAIRING_ID': {
|
case 'GET_PAIRING_ID': {
|
||||||
User.getInstance().setPairingId(message.userPairingId);
|
User.getInstance().setPairingId(message.userPairingId);
|
||||||
@ -83,6 +97,36 @@ export default function AuthModal({ isOpen, onClose }: AuthModalProps) {
|
|||||||
}, 500);
|
}, 500);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case 'ERROR': {
|
||||||
|
console.error('[AuthModal] handleMessage: error', message);
|
||||||
|
if (message.messageId.includes('GET_PAIRING_ID')) {
|
||||||
|
// We are not paired yet
|
||||||
|
const accessToken = User.getInstance().getAccessToken();
|
||||||
|
if (accessToken) {
|
||||||
|
// create a new pairing
|
||||||
|
const messageId = `CREATE_PAIRING_${uuidv4()}`;
|
||||||
|
iframeRef.current.contentWindow!.postMessage({ type: 'CREATE_PAIRING', accessToken, messageId }, targetOrigin);
|
||||||
|
} else {
|
||||||
|
// We don't have an access token
|
||||||
|
// Shouldn't happen
|
||||||
|
console.error('[AuthModal] handleMessage: error: we don\'t have an access token');
|
||||||
|
setShowIframe(false);
|
||||||
|
setIsIframeReady(false);
|
||||||
|
setAuthSuccess(false);
|
||||||
|
onClose();
|
||||||
|
}
|
||||||
|
} else if (message.messageId.includes('CREATE_PAIRING')) {
|
||||||
|
// Something went wrong while creating a pairing
|
||||||
|
// show stopper for now
|
||||||
|
console.error('[AuthModal] CREATE_PAIRING error:', message.error);
|
||||||
|
setShowIframe(false);
|
||||||
|
setIsIframeReady(false);
|
||||||
|
setAuthSuccess(false);
|
||||||
|
onClose();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
window.addEventListener('message', handleMessage);
|
window.addEventListener('message', handleMessage);
|
||||||
|
@ -11,8 +11,8 @@ import { FileBlob } from '../front/Api/Entities/types';
|
|||||||
|
|
||||||
export default class MessageBus {
|
export default class MessageBus {
|
||||||
private static instance: MessageBus;
|
private static instance: MessageBus;
|
||||||
private errors: { [key: string]: string } = {};
|
|
||||||
private isListening: boolean = false;
|
private isListening: boolean = false;
|
||||||
|
private messagesSent: Set<string> = new Set();
|
||||||
|
|
||||||
public static getInstance(): MessageBus {
|
public static getInstance(): MessageBus {
|
||||||
if (!MessageBus.instance) {
|
if (!MessageBus.instance) {
|
||||||
@ -27,6 +27,11 @@ export default class MessageBus {
|
|||||||
|
|
||||||
public destroyMessageListener(): void {
|
public destroyMessageListener(): void {
|
||||||
window.removeEventListener('message', this.handleMessage.bind(this));
|
window.removeEventListener('message', this.handleMessage.bind(this));
|
||||||
|
this.isListening = false; // Reset the flag when destroying listener
|
||||||
|
}
|
||||||
|
|
||||||
|
public resetListeningState(): void {
|
||||||
|
this.isListening = false; // Allow external components to reset listening state
|
||||||
}
|
}
|
||||||
|
|
||||||
public isReady(): Promise<void> {
|
public isReady(): Promise<void> {
|
||||||
@ -41,27 +46,39 @@ export default class MessageBus {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public isWaitingForMessage(): boolean {
|
||||||
|
return this.messagesSent.size > 0;
|
||||||
|
}
|
||||||
|
|
||||||
public requestLink(): Promise<void> {
|
public requestLink(): Promise<void> {
|
||||||
return new Promise<void>((resolve: () => void, reject: (error: string) => void) => {
|
return new Promise<void>((resolve: () => void, reject: (error: string) => void) => {
|
||||||
const messageId = `REQUEST_LINK_${uuidv4()}`;
|
const messageId = `REQUEST_LINK_${uuidv4()}`;
|
||||||
|
console.log('[MessageBus] requestLink - waiting for messageId:', messageId);
|
||||||
|
|
||||||
const unsubscribe = EventBus.getInstance().on('LINK_ACCEPTED', (responseId: string, message: { accessToken: string, refreshToken: string }) => {
|
const unsubscribe = EventBus.getInstance().on('LINK_ACCEPTED', (responseId: string, message: { accessToken: string, refreshToken: string }) => {
|
||||||
|
console.log('[MessageBus] LINK_ACCEPTED received with responseId:', responseId, 'expected:', messageId);
|
||||||
if (responseId !== messageId) {
|
if (responseId !== messageId) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
console.log('[MessageBus] LINK_ACCEPTED matched - resolving');
|
||||||
unsubscribe();
|
unsubscribe();
|
||||||
|
unsubscribeError();
|
||||||
User.getInstance().setTokens(message.accessToken, message.refreshToken);
|
User.getInstance().setTokens(message.accessToken, message.refreshToken);
|
||||||
resolve();
|
resolve();
|
||||||
});
|
});
|
||||||
|
|
||||||
const unsubscribeError = EventBus.getInstance().on('ERROR_LINK_ACCEPTED', (responseId: string, error: string) => {
|
const unsubscribeError = EventBus.getInstance().on('ERROR_LINK_ACCEPTED', (responseId: string, error: string) => {
|
||||||
|
console.log('[MessageBus] ERROR_LINK_ACCEPTED received with responseId:', responseId, 'expected:', messageId);
|
||||||
if (responseId !== messageId) {
|
if (responseId !== messageId) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
console.log('[MessageBus] ERROR_LINK_ACCEPTED matched - rejecting with error:', error);
|
||||||
|
unsubscribe();
|
||||||
unsubscribeError();
|
unsubscribeError();
|
||||||
reject(error);
|
reject(error);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
console.log('[MessageBus] requestLink - sending REQUEST_LINK message');
|
||||||
this.sendMessage({
|
this.sendMessage({
|
||||||
type: 'REQUEST_LINK',
|
type: 'REQUEST_LINK',
|
||||||
messageId
|
messageId
|
||||||
@ -69,6 +86,40 @@ export default class MessageBus {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public createPairing(): Promise<void> {
|
||||||
|
return new Promise<void>((resolve: () => void, reject: (error: string) => void) => {
|
||||||
|
this.checkToken().then(() => {
|
||||||
|
const messageId = `CREATE_PAIRING_${uuidv4()}`;
|
||||||
|
|
||||||
|
const unsubscribe = EventBus.getInstance().on('PAIRING_CREATED', (responseId: string, pairingId: string) => {
|
||||||
|
if (responseId !== messageId) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
unsubscribe();
|
||||||
|
User.getInstance().setPairingId(pairingId);
|
||||||
|
resolve();
|
||||||
|
});
|
||||||
|
|
||||||
|
const unsubscribeError = EventBus.getInstance().on('ERROR_CREATE_PAIRING', (responseId: string, error: string) => {
|
||||||
|
if (responseId !== messageId) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
unsubscribeError();
|
||||||
|
reject(error);
|
||||||
|
});
|
||||||
|
|
||||||
|
const user = User.getInstance();
|
||||||
|
const accessToken = user.getAccessToken()!;
|
||||||
|
|
||||||
|
this.sendMessage({
|
||||||
|
type: 'CREATE_PAIRING',
|
||||||
|
accessToken,
|
||||||
|
messageId
|
||||||
|
});
|
||||||
|
}).catch(reject);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
public getPairingId(): Promise<string> {
|
public getPairingId(): Promise<string> {
|
||||||
return new Promise<string>((resolve: (pairingId: string) => void, reject: (error: string) => void) => {
|
return new Promise<string>((resolve: (pairingId: string) => void, reject: (error: string) => void) => {
|
||||||
this.checkToken().then(() => {
|
this.checkToken().then(() => {
|
||||||
@ -98,7 +149,7 @@ export default class MessageBus {
|
|||||||
accessToken,
|
accessToken,
|
||||||
messageId
|
messageId
|
||||||
});
|
});
|
||||||
}).catch(console.error);
|
}).catch(reject);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -298,6 +349,114 @@ export default class MessageBus {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public getRolesForProcess(processId: string): Promise<any> {
|
||||||
|
return new Promise<any>((resolve: (roles: any[]) => void, reject: (error: string) => void) => {
|
||||||
|
this.getAllProcesses().then((processes: any) => {
|
||||||
|
const process = processes[processId];
|
||||||
|
|
||||||
|
if (!process.states || process.states.length < 2) {
|
||||||
|
reject('No states found for process');
|
||||||
|
}
|
||||||
|
|
||||||
|
const roles = process.states[process.states.length - 2].roles;
|
||||||
|
if (!roles) {
|
||||||
|
reject('No roles found for process');
|
||||||
|
}
|
||||||
|
|
||||||
|
resolve(roles);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Returns all processes details, including processes we only have public data for
|
||||||
|
public getAllProcessesDecoded(filterPublicValues: (publicValues: { [key: string]: any }) => boolean): Promise<any[]> {
|
||||||
|
return new Promise<any[]>((resolve: (processesDecoded: any[]) => void, reject: (error: string) => void) => {
|
||||||
|
this.getAllProcesses().then(async (processes: any) => {
|
||||||
|
const processesDecoded: any[] = [];
|
||||||
|
|
||||||
|
for (const processId of Object.keys(processes)) {
|
||||||
|
const process = processes[processId];
|
||||||
|
if (!process.states) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
const publicDataDecoded: { [key: string]: any } = {};
|
||||||
|
|
||||||
|
for (let stateId = 0; stateId < process.states.length - 1; stateId++) {
|
||||||
|
const state = process.states[stateId];
|
||||||
|
if (!state) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
const publicDataEncoded = state.public_data;
|
||||||
|
if (!publicDataEncoded) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const key of Object.keys(publicDataEncoded)) {
|
||||||
|
publicDataDecoded[key] = await this.getPublicData(publicDataEncoded[key]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!filterPublicValues(publicDataDecoded)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
let processDecoded: any;
|
||||||
|
|
||||||
|
for (let stateId = 0; stateId < process.states.length - 1; stateId++) {
|
||||||
|
const lastState = process.states[stateId];
|
||||||
|
if (!lastState) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
const lastStateId = lastState.state_id;
|
||||||
|
if (!lastStateId) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
let processData = await this.getData(processId, lastStateId);
|
||||||
|
if (!processData) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
const isEmpty = Object.keys(processData).length === 0;
|
||||||
|
if (isEmpty) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const key of Object.keys(publicDataDecoded)) {
|
||||||
|
processData[key] = publicDataDecoded[key];
|
||||||
|
}
|
||||||
|
processData = MapUtils.toJson(processData);
|
||||||
|
|
||||||
|
if (!processDecoded) {
|
||||||
|
processDecoded = {
|
||||||
|
processId,
|
||||||
|
lastStateId,
|
||||||
|
processData,
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
for (const key of Object.keys(processData)) {
|
||||||
|
processDecoded.processData[key] = processData[key];
|
||||||
|
}
|
||||||
|
processDecoded.lastStateId = lastStateId;
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
processesDecoded.push(processDecoded);
|
||||||
|
}
|
||||||
|
|
||||||
|
resolve(processesDecoded);
|
||||||
|
}).catch(reject);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Returns details about processes that we are involved in
|
||||||
public getProcessesDecoded(filterPublicValues: (publicValues: { [key: string]: any }) => boolean): Promise<any[]> {
|
public getProcessesDecoded(filterPublicValues: (publicValues: { [key: string]: any }) => boolean): Promise<any[]> {
|
||||||
return new Promise<any[]>((resolve: (processesDecoded: any[]) => void, reject: (error: string) => void) => {
|
return new Promise<any[]>((resolve: (processesDecoded: any[]) => void, reject: (error: string) => void) => {
|
||||||
this.getProcesses().then(async (processes: any) => {
|
this.getProcesses().then(async (processes: any) => {
|
||||||
@ -417,7 +576,7 @@ export default class MessageBus {
|
|||||||
accessToken,
|
accessToken,
|
||||||
messageId
|
messageId
|
||||||
});
|
});
|
||||||
}).catch(console.error);
|
}).catch(reject);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -454,12 +613,48 @@ export default class MessageBus {
|
|||||||
accessToken,
|
accessToken,
|
||||||
messageId
|
messageId
|
||||||
});
|
});
|
||||||
}).catch(console.error);
|
}).catch(reject);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public getProcesses(): Promise<any> {
|
// Returns all processes, including processes that have nothing to do with us
|
||||||
return new Promise<any>((resolve: (processes: any) => void, reject: (error: string) => void) => {
|
public getAllProcesses(): Promise<{ [processId: string]: any }> {
|
||||||
|
return new Promise<{ [processId: string]: any }>((resolve: (processes: { [processId: string]: any }) => void, reject: (error: string) => void) => {
|
||||||
|
this.checkToken().then(() => {
|
||||||
|
const messageId = `GET_PROCESSES_${uuidv4()}`;
|
||||||
|
|
||||||
|
const unsubscribe = EventBus.getInstance().on('PROCESSES_RETRIEVED', (responseId: string, processes: any) => {
|
||||||
|
if (responseId !== messageId) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
unsubscribe();
|
||||||
|
|
||||||
|
resolve(processes);
|
||||||
|
});
|
||||||
|
|
||||||
|
const unsubscribeError = EventBus.getInstance().on('ERROR_PROCESSES_RETRIEVED', (responseId: string, error: string) => {
|
||||||
|
if (responseId !== messageId) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
unsubscribeError();
|
||||||
|
reject(error);
|
||||||
|
});
|
||||||
|
|
||||||
|
const user = User.getInstance();
|
||||||
|
const accessToken = user.getAccessToken()!;
|
||||||
|
|
||||||
|
this.sendMessage({
|
||||||
|
type: 'GET_PROCESSES',
|
||||||
|
accessToken,
|
||||||
|
messageId
|
||||||
|
});
|
||||||
|
}).catch(reject);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Returns processes that we are involved in
|
||||||
|
public getProcesses(): Promise<{ [processId: string]: any }> {
|
||||||
|
return new Promise<{ [processId: string]: any }>((resolve: (processes: { [processId: string]: any }) => void, reject: (error: string) => void) => {
|
||||||
this.checkToken().then(() => {
|
this.checkToken().then(() => {
|
||||||
const messageId = `GET_PROCESSES_${uuidv4()}`;
|
const messageId = `GET_PROCESSES_${uuidv4()}`;
|
||||||
|
|
||||||
@ -471,7 +666,7 @@ export default class MessageBus {
|
|||||||
|
|
||||||
// Filter processes by my processes
|
// Filter processes by my processes
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
this.getMyProcesses().then((myProcesses: any) => {
|
this.getMyProcesses().then((myProcesses: string[]) => {
|
||||||
const processesFiltered: { [processId: string]: any } = {};
|
const processesFiltered: { [processId: string]: any } = {};
|
||||||
for (const processId of myProcesses) {
|
for (const processId of myProcesses) {
|
||||||
const process = processes[processId];
|
const process = processes[processId];
|
||||||
@ -500,16 +695,18 @@ export default class MessageBus {
|
|||||||
accessToken,
|
accessToken,
|
||||||
messageId
|
messageId
|
||||||
});
|
});
|
||||||
}).catch(console.error);
|
}).catch(reject);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public getMyProcesses(): Promise<any> {
|
// Returns the processes id of processes we are involved in
|
||||||
return new Promise<any>((resolve: (processes: any) => void, reject: (error: string) => void) => {
|
// It's meant to be used to filter processes in the getProcesses() method
|
||||||
|
public getMyProcesses(): Promise<string[]> {
|
||||||
|
return new Promise<string[]>((resolve: (processes: string[]) => void, reject: (error: string) => void) => {
|
||||||
this.checkToken().then(() => {
|
this.checkToken().then(() => {
|
||||||
const messageId = `GET_MY_PROCESSES_${uuidv4()}`;
|
const messageId = `GET_MY_PROCESSES_${uuidv4()}`;
|
||||||
|
|
||||||
const unsubscribe = EventBus.getInstance().on('GET_MY_PROCESSES', (responseId: string, processes: any) => {
|
const unsubscribe = EventBus.getInstance().on('GET_MY_PROCESSES', (responseId: string, processes: string[]) => {
|
||||||
if (responseId !== messageId) {
|
if (responseId !== messageId) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -533,7 +730,7 @@ export default class MessageBus {
|
|||||||
accessToken,
|
accessToken,
|
||||||
messageId
|
messageId
|
||||||
});
|
});
|
||||||
}).catch(console.error);
|
}).catch(reject);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -568,7 +765,7 @@ export default class MessageBus {
|
|||||||
accessToken,
|
accessToken,
|
||||||
messageId
|
messageId
|
||||||
});
|
});
|
||||||
}).catch(console.error);
|
}).catch(reject);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -603,7 +800,7 @@ export default class MessageBus {
|
|||||||
accessToken,
|
accessToken,
|
||||||
messageId
|
messageId
|
||||||
});
|
});
|
||||||
}).catch(console.error);
|
}).catch(reject);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -638,7 +835,7 @@ export default class MessageBus {
|
|||||||
accessToken,
|
accessToken,
|
||||||
messageId
|
messageId
|
||||||
});
|
});
|
||||||
}).catch(console.error);
|
}).catch(reject);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -672,7 +869,7 @@ export default class MessageBus {
|
|||||||
accessToken,
|
accessToken,
|
||||||
messageId
|
messageId
|
||||||
});
|
});
|
||||||
}).catch(console.error);
|
}).catch(reject);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -874,6 +1071,7 @@ export default class MessageBus {
|
|||||||
const targetOrigin = IframeReference.getTargetOrigin();
|
const targetOrigin = IframeReference.getTargetOrigin();
|
||||||
const iframe = IframeReference.getIframe();
|
const iframe = IframeReference.getIframe();
|
||||||
iframe.contentWindow?.postMessage(message, targetOrigin);
|
iframe.contentWindow?.postMessage(message, targetOrigin);
|
||||||
|
this.messagesSent.add(message.messageId);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('[MessageBus] sendMessage: error', error);
|
console.error('[MessageBus] sendMessage: error', error);
|
||||||
}
|
}
|
||||||
@ -975,19 +1173,26 @@ export default class MessageBus {
|
|||||||
|
|
||||||
case 'ERROR':
|
case 'ERROR':
|
||||||
console.error('Error:', message);
|
console.error('Error:', message);
|
||||||
this.errors[message.messageId] = message.error;
|
// Extract operation type from messageId by splitting on last underscore
|
||||||
|
const operationType = this.extractOperationTypeFromMessageId(message.messageId);
|
||||||
|
EventBus.getInstance().emit(`ERROR_${operationType}`, message.messageId, message.error);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private doHandleMessage(messageId: string, messageType: string, message: any, callback: (message: any) => any) {
|
private extractOperationTypeFromMessageId(messageId: string): string {
|
||||||
if (this.errors[messageId]) {
|
// Split on last underscore to extract operation type
|
||||||
const error = this.errors[messageId];
|
// e.g., "GET_PAIRING_ID_abc123" -> "GET_PAIRING_ID"
|
||||||
delete this.errors[messageId];
|
const lastUnderscoreIndex = messageId.lastIndexOf('_');
|
||||||
EventBus.getInstance().emit(`ERROR_${messageType}`, messageId, error);
|
if (lastUnderscoreIndex === -1) {
|
||||||
return;
|
return messageId; // No underscore found, return as-is
|
||||||
}
|
}
|
||||||
|
return messageId.substring(0, lastUnderscoreIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
private doHandleMessage(messageId: string, messageType: string, message: any, callback: (message: any) => any) {
|
||||||
EventBus.getInstance().emit('MESSAGE_RECEIVED', message);
|
EventBus.getInstance().emit('MESSAGE_RECEIVED', message);
|
||||||
EventBus.getInstance().emit(messageType, messageId, callback(message));
|
EventBus.getInstance().emit(messageType, messageId, callback(message));
|
||||||
|
this.messagesSent.delete(messageId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user