ci: docker_tag=ext fix(ihm_client): build passes locally; adjust pkg imports, null-guards, types

This commit is contained in:
4NK CI Bot 2025-09-22 12:48:30 +00:00
parent 3f3fdc6b55
commit 2d3ac5a884
10 changed files with 106 additions and 98 deletions

View File

@ -1,4 +1,4 @@
import { Device, Process, SecretsStore } from ".././pkg/sdk_client.js"; import { Device, Process, SecretsStore } from "../../pkg/sdk_client.js";
export interface BackUp { export interface BackUp {
device: Device, device: Device,

View File

@ -188,16 +188,16 @@ class AccountElement extends HTMLElement {
<div class="content-container"> <div class="content-container">
<div id="pairing-content"></div> <div id="pairing-content"></div>
<!-- <div id="wallet-content"></div> --> <!-- <div id="wallet-content"></div> -->
<div id="process-content"></div> <div id="process-content"></div>
<div id="process-creation-content"></div> <div id="process-creation-content"></div>
<div id="document-validation-content"></div> <div id="document-validation-content"></div>
<!-- <div id="data-content"></div> --> <!-- <div id="data-content"></div> -->
</div> </div>
</div> </div>
</div> </div>
`; `;
window.showPairing = () => this.showPairing(); window.showPairing = () => this.showPairing();
window.showWallet = () => this.showWallet(); window.showWallet = () => this.showWallet();
window.showProcess = () => this.showProcess(); window.showProcess = () => this.showProcess();
@ -238,22 +238,22 @@ class AccountElement extends HTMLElement {
this.initializeEventListeners(); this.initializeEventListeners();
this.loadSavedBanner(); this.loadSavedBanner();
this.loadUserInfo(); this.loadUserInfo();
const savedAvatar = localStorage.getItem('userAvatar'); const savedAvatar = localStorage.getItem('userAvatar');
const savedBanner = localStorage.getItem('userBanner'); const savedBanner = localStorage.getItem('userBanner');
const savedName = localStorage.getItem('userName'); const savedName = localStorage.getItem('userName');
const savedLastName = localStorage.getItem('userLastName'); const savedLastName = localStorage.getItem('userLastName');
if (savedAvatar) { if (savedAvatar) {
const navAvatar = this.shadowRoot?.querySelector('.avatar') as HTMLImageElement; const navAvatar = this.shadowRoot?.querySelector('.avatar') as HTMLImageElement;
if (navAvatar) navAvatar.src = savedAvatar; if (navAvatar) navAvatar.src = savedAvatar;
} }
if (savedBanner) { if (savedBanner) {
const navBanner = this.shadowRoot?.querySelector('.banner-image') as HTMLImageElement; const navBanner = this.shadowRoot?.querySelector('.banner-image') as HTMLImageElement;
if (navBanner) navBanner.src = savedBanner; if (navBanner) navBanner.src = savedBanner;
} }
if (savedName) { if (savedName) {
this.updateNavbarName(savedName); this.updateNavbarName(savedName);
} }
@ -270,17 +270,17 @@ class AccountElement extends HTMLElement {
alertPopup.className = 'alert-popup'; alertPopup.className = 'alert-popup';
this.shadowRoot?.appendChild(alertPopup); this.shadowRoot?.appendChild(alertPopup);
} }
// Définir le message et afficher la popup // Définir le message et afficher la popup
alertPopup.textContent = message; alertPopup.textContent = message;
(alertPopup as HTMLElement).style.display = 'block'; (alertPopup as HTMLElement).style.display = 'block';
// Cacher la popup après 3 secondes // Cacher la popup après 3 secondes
setTimeout(() => { setTimeout(() => {
(alertPopup as HTMLElement).style.display = 'none'; (alertPopup as HTMLElement).style.display = 'none';
}, 3000); }, 3000);
} }
// Fonctions de gestion des comptes et de l'interface utilisateur // Fonctions de gestion des comptes et de l'interface utilisateur
private confirmDeleteAccount(): void { private confirmDeleteAccount(): void {
@ -321,13 +321,13 @@ private updateNavbarBanner(imageUrl: string): void {
if (!navbarSection) return; if (!navbarSection) return;
let bannerImg = navbarSection.querySelector<HTMLImageElement>('.banner-image'); let bannerImg = navbarSection.querySelector<HTMLImageElement>('.banner-image');
if (!bannerImg) { if (!bannerImg) {
bannerImg = document.createElement('img'); bannerImg = document.createElement('img');
bannerImg.className = 'banner-image'; bannerImg.className = 'banner-image';
navbarSection.insertBefore(bannerImg, navbarSection.firstChild); navbarSection.insertBefore(bannerImg, navbarSection.firstChild);
} }
bannerImg.src = imageUrl; bannerImg.src = imageUrl;
} }
@ -368,7 +368,7 @@ private markAsRead(processName: string, messageId: number, element: HTMLElement)
element.classList.remove('unread'); element.classList.remove('unread');
element.classList.add('read'); element.classList.add('read');
const statusIcon = element.querySelector('.notification-status'); const statusIcon = element.querySelector('.notification-status');
if (statusIcon) { if (statusIcon) {
statusIcon.innerHTML = ` statusIcon.innerHTML = `
@ -381,7 +381,7 @@ private markAsRead(processName: string, messageId: number, element: HTMLElement)
const countElement = this.shadowRoot?.querySelector(`.notification-count[data-process="${processName}"]`); const countElement = this.shadowRoot?.querySelector(`.notification-count[data-process="${processName}"]`);
if (countElement) { if (countElement) {
countElement.textContent = `${notifCount.unread}/${notifCount.total}`; countElement.textContent = `${notifCount.unread}/${notifCount.total}`;
const bellContainer = countElement.closest('.notification-container'); const bellContainer = countElement.closest('.notification-container');
const bell = bellContainer?.querySelector('svg'); // Changé de .fa-bell à svg const bell = bellContainer?.querySelector('svg'); // Changé de .fa-bell à svg
if (bell && bellContainer && notifCount.unread === 0) { if (bell && bellContainer && notifCount.unread === 0) {
@ -418,7 +418,7 @@ private exportRecovery(): void {
if (result.isConfirmed) { if (result.isConfirmed) {
const recoveryWords = this.generateRecoveryWords(); const recoveryWords = this.generateRecoveryWords();
localStorage.setItem('recoveryWords', JSON.stringify(recoveryWords)); localStorage.setItem('recoveryWords', JSON.stringify(recoveryWords));
Swal.fire({ Swal.fire({
title: 'Your Recovery Words', title: 'Your Recovery Words',
html: ` html: `
@ -447,7 +447,7 @@ private exportRecovery(): void {
if (result.isConfirmed) { if (result.isConfirmed) {
// Stocker l'état du bouton dans le localStorage // Stocker l'état du bouton dans le localStorage
localStorage.setItem('recoveryExported', 'true'); localStorage.setItem('recoveryExported', 'true');
const exportRecoveryBtn = this.shadowRoot?.querySelector('.recovery-btn') as HTMLButtonElement; const exportRecoveryBtn = this.shadowRoot?.querySelector('.recovery-btn') as HTMLButtonElement;
if (exportRecoveryBtn) { if (exportRecoveryBtn) {
exportRecoveryBtn.disabled = true; exportRecoveryBtn.disabled = true;
@ -627,8 +627,8 @@ private updateTableContent(rows: Row[]): void {
<td class="device-name" onclick="window.editDeviceName(this)">${row.column2}</td> <td class="device-name" onclick="window.editDeviceName(this)">${row.column2}</td>
<td>${row.column3}</td> <td>${row.column3}</td>
<td> <td>
<img src="https://api.qrserver.com/v1/create-qr-code/?size=50x50&data=${encodeURIComponent(row.column1)}" <img src="https://api.qrserver.com/v1/create-qr-code/?size=50x50&data=${encodeURIComponent(row.column1)}"
alt="QR Code" alt="QR Code"
title="${row.column1}" title="${row.column1}"
class="qr-code" class="qr-code"
onclick="window.showQRCodeModal('${encodeURIComponent(row.column1)}')"> onclick="window.showQRCodeModal('${encodeURIComponent(row.column1)}')">
@ -677,18 +677,18 @@ private confirmRowPairing(): void {
isAddingRow = false; isAddingRow = false;
currentRow = null; currentRow = null;
this.resetButtonContainer(); this.resetButtonContainer();
this.updateTableContent(rows); this.updateTableContent(rows);
} }
private cancelRowPairing(): void { private cancelRowPairing(): void {
if (!currentRow) return; if (!currentRow) return;
currentRow.remove(); currentRow.remove();
isAddingRow = false; isAddingRow = false;
currentRow = null; currentRow = null;
this.resetButtonContainer(); this.resetButtonContainer();
} }
@ -739,7 +739,7 @@ private deleteRowPairing(button: HTMLButtonElement): void {
const index = Array.from(table.children).indexOf(row); const index = Array.from(table.children).indexOf(row);
const storageKey = STORAGE_KEYS[currentMode]; const storageKey = STORAGE_KEYS[currentMode];
const rows = JSON.parse(localStorage.getItem(storageKey) || '[]'); const rows = JSON.parse(localStorage.getItem(storageKey) || '[]');
// Supprimer du localStorage // Supprimer du localStorage
if (index > -1) { if (index > -1) {
rows.splice(index, 1); rows.splice(index, 1);
@ -771,7 +771,7 @@ private editDeviceName(cell: HTMLTableCellElement): void {
input.type = 'text'; input.type = 'text';
input.value = currentValue; input.value = currentValue;
input.className = 'edit-input'; input.className = 'edit-input';
input.addEventListener('blur', () => this.finishEditing(cell, input)); input.addEventListener('blur', () => this.finishEditing(cell, input));
input.addEventListener('keypress', (e: KeyboardEvent) => { input.addEventListener('keypress', (e: KeyboardEvent) => {
if (e.key === 'Enter') { if (e.key === 'Enter') {
@ -797,7 +797,7 @@ private async finishEditing(cell: HTMLTableCellElement, input: HTMLInputElement)
const service = await Services.getInstance(); const service = await Services.getInstance();
const pairingProcessId = service.getPairingProcessId(); const pairingProcessId = service.getPairingProcessId();
const process = await service.getProcess(pairingProcessId); const process = await service.getProcess(pairingProcessId);
if (!process) throw new Error('Pairing process not found');
// Mettre à jour le nom via le service // Mettre à jour le nom via le service
await service.updateMemberPublicName(process, newValue); await service.updateMemberPublicName(process, newValue);
@ -816,17 +816,17 @@ private async finishEditing(cell: HTMLTableCellElement, input: HTMLInputElement)
private handleAvatarUpload(event: Event): void { private handleAvatarUpload(event: Event): void {
const input = event.target as HTMLInputElement; const input = event.target as HTMLInputElement;
const file = input.files?.[0]; const file = input.files?.[0];
if (file) { if (file) {
const reader = new FileReader(); const reader = new FileReader();
reader.onload = (e: ProgressEvent<FileReader>) => { reader.onload = (e: ProgressEvent<FileReader>) => {
const result = e.target?.result as string; const result = e.target?.result as string;
const popupAvatar = this.shadowRoot?.getElementById('popup-avatar-img') as HTMLImageElement; const popupAvatar = this.shadowRoot?.getElementById('popup-avatar-img') as HTMLImageElement;
const navAvatar = this.shadowRoot?.querySelector('.nav-wrapper .avatar') as HTMLImageElement; const navAvatar = this.shadowRoot?.querySelector('.nav-wrapper .avatar') as HTMLImageElement;
if (popupAvatar) popupAvatar.src = result; if (popupAvatar) popupAvatar.src = result;
if (navAvatar) navAvatar.src = result; if (navAvatar) navAvatar.src = result;
localStorage.setItem('userAvatar', result); localStorage.setItem('userAvatar', result);
}; };
reader.readAsDataURL(file); reader.readAsDataURL(file);
@ -856,8 +856,9 @@ private async showProcess(): Promise<void> {
const service = await Services.getInstance(); const service = await Services.getInstance();
const myProcesses = await service.getMyProcesses(); const myProcesses = await service.getMyProcesses();
if (myProcesses && myProcesses.length != 0) { if (myProcesses && myProcesses.length != 0) {
const myProcessesDataUnfiltered: { name: string, publicData: Record<string, any> }[] = await Promise.all(myProcesses.map(async processId => { const myProcessesDataUnfiltered = await Promise.all(myProcesses.map(async processId => {
const process = await service.getProcess(processId); const process = await service.getProcess(processId);
if (!process) return undefined;
const lastState = service.getLastCommitedState(process); const lastState = service.getLastCommitedState(process);
if (!lastState) { if (!lastState) {
return { return {
@ -879,9 +880,9 @@ private async showProcess(): Promise<void> {
publicData: publicData publicData: publicData
}; };
})); }));
const myProcessesData = myProcessesDataUnfiltered.filter( const myProcessesData = (myProcessesDataUnfiltered.filter(
(p) => p.name !== '' && Object.keys(p.publicData).length != 0 (p) => p && p.name !== '' && Object.keys(p.publicData).length != 0
); )) as { name: string, publicData: Record<string, any> }[];
createProcessTab(container, myProcessesData); createProcessTab(container, myProcessesData);
} else { } else {
@ -896,15 +897,15 @@ private showProcessNotifications(processName: string): void {
const modal = document.createElement('div'); const modal = document.createElement('div');
modal.className = 'notifications-modal'; modal.className = 'notifications-modal';
let notificationsList = process.notification.messages.map(msg => ` let notificationsList = process.notification.messages.map(msg => `
<div class="notification-item ${msg.read ? 'read' : 'unread'}" <div class="notification-item ${msg.read ? 'read' : 'unread'}"
onclick="window.markAsRead('${processName}', ${msg.id}, this)"> onclick="window.markAsRead('${processName}', ${msg.id}, this)">
<div class="notification-status"> <div class="notification-status">
${msg.read ? ${msg.read ?
`<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512" width="16" height="16" fill="green"> `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512" width="16" height="16" fill="green">
<path d="M438.6 105.4c12.5 12.5 12.5 32.8 0 45.3l-256 256c-12.5 12.5-32.8 12.5-45.3 0l-128-128c-12.5-12.5-12.5-32.8 0-45.3s32.8-12.5 45.3 0L160 338.7 393.4 105.4c12.5-12.5 32.8-12.5 45.3 0z"/> <path d="M438.6 105.4c12.5 12.5 12.5 32.8 0 45.3l-256 256c-12.5 12.5-32.8 12.5-45.3 0l-128-128c-12.5-12.5-12.5-32.8 0-45.3s32.8-12.5 45.3 0L160 338.7 393.4 105.4c12.5-12.5 32.8-12.5 45.3 0z"/>
</svg>` : </svg>` :
`<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" width="16" height="16" fill="black"> `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" width="16" height="16" fill="black">
<path d="M256 512A256 256 0 1 0 256 0a256 256 0 1 0 0 512z"/> <path d="M256 512A256 256 0 1 0 256 0a256 256 0 1 0 0 512z"/>
</svg>` </svg>`
@ -959,7 +960,7 @@ private showContractPopup(contractId: string, event?: Event) {
if (event) { if (event) {
event.preventDefault(); event.preventDefault();
} }
// Check if the contract exists in mockContracts // Check if the contract exists in mockContracts
const contract = mockContracts[contractId as keyof typeof mockContracts]; const contract = mockContracts[contractId as keyof typeof mockContracts];
if (!contract) { if (!contract) {
@ -989,7 +990,7 @@ private showContractPopup(contractId: string, event?: Event) {
const closeBtn = popup.querySelector('.close-contract-popup'); const closeBtn = popup.querySelector('.close-contract-popup');
const closePopup = () => popup.remove(); const closePopup = () => popup.remove();
closeBtn?.addEventListener('click', closePopup); closeBtn?.addEventListener('click', closePopup);
popup.addEventListener('click', (e) => { popup.addEventListener('click', (e) => {
if (e.target === popup) closePopup(); if (e.target === popup) closePopup();
@ -1011,13 +1012,13 @@ private hideAllContent(): void {
private async showPairing(): Promise<void> { private async showPairing(): Promise<void> {
const service = await Services.getInstance(); const service = await Services.getInstance();
const spAddress = await service.getDeviceAddress(); const spAddress = await service.getDeviceAddress();
isAddingRow = false; isAddingRow = false;
currentRow = null; currentRow = null;
currentMode = 'pairing'; currentMode = 'pairing';
this.hideAllContent(); this.hideAllContent();
const headerElement = this.shadowRoot?.getElementById('parameter-header'); const headerElement = this.shadowRoot?.getElementById('parameter-header');
if (headerElement) { if (headerElement) {
headerElement.textContent = 'Pairing'; headerElement.textContent = 'Pairing';
@ -1047,23 +1048,23 @@ private async showPairing(): Promise<void> {
`; `;
let rows = JSON.parse(localStorage.getItem(STORAGE_KEYS.pairing) || '[]'); let rows = JSON.parse(localStorage.getItem(STORAGE_KEYS.pairing) || '[]');
const deviceExists = rows.some((row: Row) => row.column1 === spAddress); const deviceExists = rows.some((row: Row) => row.column1 === spAddress);
if (!deviceExists && spAddress) { if (!deviceExists && spAddress) {
const emojis = await addressToEmoji(spAddress); const emojis = await addressToEmoji(spAddress);
try { try {
// Déboguer le processus de pairing // Déboguer le processus de pairing
const pairingProcessId = await service.getPairingProcessId(); const pairingProcessId = await service.getPairingProcessId();
console.log('Pairing Process ID:', pairingProcessId); console.log('Pairing Process ID:', pairingProcessId);
const pairingProcess = await service.getProcess(pairingProcessId); const pairingProcess = await service.getProcess(pairingProcessId);
console.log('Pairing Process:', pairingProcess); console.log('Pairing Process:', pairingProcess);
const userName = pairingProcess?.states?.[0]?.public_data?.memberPublicName const userName = pairingProcess?.states?.[0]?.public_data?.memberPublicName
|| localStorage.getItem('userName') || localStorage.getItem('userName')
console.log('Username found:', userName); console.log('Username found:', userName);
const newRow = { const newRow = {
@ -1084,7 +1085,7 @@ private async showPairing(): Promise<void> {
localStorage.setItem(STORAGE_KEYS.pairing, JSON.stringify(rows)); localStorage.setItem(STORAGE_KEYS.pairing, JSON.stringify(rows));
} }
} }
this.updateTableContent(rows); this.updateTableContent(rows);
} }
} }
@ -1095,11 +1096,11 @@ private showWallet(): void {
currentMode = 'wallet'; currentMode = 'wallet';
this.hideAllContent(); this.hideAllContent();
// Mettre à jour le titre // Mettre à jour le titre
const headerTitle = this.shadowRoot?.getElementById('header-title'); const headerTitle = this.shadowRoot?.getElementById('header-title');
if (headerTitle) headerTitle.textContent = 'Wallet'; if (headerTitle) headerTitle.textContent = 'Wallet';
const walletContent = this.shadowRoot?.getElementById('wallet-content'); const walletContent = this.shadowRoot?.getElementById('wallet-content');
if (!walletContent) return; if (!walletContent) return;
walletContent.style.display = 'block'; walletContent.style.display = 'block';
@ -1121,7 +1122,7 @@ private showWallet(): void {
</div> </div>
</div> </div>
`; `;
const rows = JSON.parse(localStorage.getItem(STORAGE_KEYS.wallet) || '[]'); const rows = JSON.parse(localStorage.getItem(STORAGE_KEYS.wallet) || '[]');
this.updateWalletTableContent(rows); this.updateWalletTableContent(rows);
} }
@ -1144,10 +1145,10 @@ private showData(): void {
//console.log("showData called"); //console.log("showData called");
currentMode = 'data'; currentMode = 'data';
this.hideAllContent(); this.hideAllContent();
const headerTitle = this.shadowRoot?.getElementById('header-title'); const headerTitle = this.shadowRoot?.getElementById('header-title');
if (headerTitle) headerTitle.textContent = 'Data'; if (headerTitle) headerTitle.textContent = 'Data';
const dataContent = this.shadowRoot?.getElementById('data-content'); const dataContent = this.shadowRoot?.getElementById('data-content');
if (dataContent) { if (dataContent) {
dataContent.style.display = 'block'; dataContent.style.display = 'block';
@ -1169,7 +1170,7 @@ private showData(): void {
</table> </table>
</div> </div>
`; `;
const rows = mockDataRows || JSON.parse(localStorage.getItem(STORAGE_KEYS.data) || '[]'); const rows = mockDataRows || JSON.parse(localStorage.getItem(STORAGE_KEYS.data) || '[]');
this.updateDataTableContent(rows); this.updateDataTableContent(rows);
} }
@ -1198,7 +1199,7 @@ private addWalletRow(): void {
// Remplacer le bouton "Add a line" par les boutons de confirmation/annulation // Remplacer le bouton "Add a line" par les boutons de confirmation/annulation
const buttonContainer = this.shadowRoot?.querySelector('#wallet-content .button-container'); const buttonContainer = this.shadowRoot?.querySelector('#wallet-content .button-container');
if (!buttonContainer) return; if (!buttonContainer) return;
buttonContainer.innerHTML = ` buttonContainer.innerHTML = `
<div class="action-buttons-wrapper"> <div class="action-buttons-wrapper">
<button onclick="confirmWalletRow()" class="action-button confirm-button"></button> <button onclick="confirmWalletRow()" class="action-button confirm-button"></button>
@ -1236,20 +1237,20 @@ private confirmWalletRow(): void {
private cancelWalletRow(): void { private cancelWalletRow(): void {
if (!currentRow) return; if (!currentRow) return;
currentRow.remove(); currentRow.remove();
isAddingRow = false; isAddingRow = false;
currentRow = null; currentRow = null;
// Réinitialiser le conteneur de boutons avec le bouton "Add a line" // Réinitialiser le conteneur de boutons avec le bouton "Add a line"
const buttonContainer = this.shadowRoot?.querySelector('#wallet-content .button-container'); const buttonContainer = this.shadowRoot?.querySelector('#wallet-content .button-container');
if (!buttonContainer) return; if (!buttonContainer) return;
buttonContainer.innerHTML = ` buttonContainer.innerHTML = `
<button class="add-row-button button-style" onclick="window.addWalletRow()">Add a line</button> <button class="add-row-button button-style" onclick="window.addWalletRow()">Add a line</button>
`; `;
} }
private updateDataTableContent(rows: DataRow[]): void { private updateDataTableContent(rows: DataRow[]): void {
@ -1318,7 +1319,7 @@ private openAvatarPopup(): void {
<span>${savedAddress}</span> <span>${savedAddress}</span>
</div> </div>
</div> </div>
<div class="popup-button-container"> <div class="popup-button-container">
<div class="action-buttons-row"> <div class="action-buttons-row">
<button class="export-btn" onclick="window.exportUserData()">Export User Data</button> <button class="export-btn" onclick="window.exportUserData()">Export User Data</button>
@ -1336,7 +1337,7 @@ private openAvatarPopup(): void {
// Ajouter le gestionnaire d'événements pour la bannière // Ajouter le gestionnaire d'événements pour la bannière
const bannerImg = popup.querySelector('#popup-banner-img'); const bannerImg = popup.querySelector('#popup-banner-img');
const bannerInput = popup.querySelector('#banner-upload') as HTMLInputElement; const bannerInput = popup.querySelector('#banner-upload') as HTMLInputElement;
if (bannerImg && bannerInput) { if (bannerImg && bannerInput) {
bannerImg.addEventListener('click', () => { bannerImg.addEventListener('click', () => {
bannerInput.click(); bannerInput.click();
@ -1375,10 +1376,10 @@ private setupEventListeners(popup: HTMLElement): void {
// Mise à jour de l'avatar dans la preview et le popup // Mise à jour de l'avatar dans la preview et le popup
const popupAvatar = this.shadowRoot?.getElementById('popup-avatar-img') as HTMLImageElement; const popupAvatar = this.shadowRoot?.getElementById('popup-avatar-img') as HTMLImageElement;
const previewAvatar = this.shadowRoot?.querySelector('.preview-avatar') as HTMLImageElement; const previewAvatar = this.shadowRoot?.querySelector('.preview-avatar') as HTMLImageElement;
if (popupAvatar) popupAvatar.src = result; if (popupAvatar) popupAvatar.src = result;
if (previewAvatar) previewAvatar.src = result; if (previewAvatar) previewAvatar.src = result;
localStorage.setItem('userAvatar', result); localStorage.setItem('userAvatar', result);
}; };
reader.readAsDataURL(file); reader.readAsDataURL(file);
@ -1398,10 +1399,10 @@ private setupEventListeners(popup: HTMLElement): void {
// Mise à jour de la bannière dans la preview et le popup // Mise à jour de la bannière dans la preview et le popup
const popupBanner = this.shadowRoot?.getElementById('popup-banner-img') as HTMLImageElement; const popupBanner = this.shadowRoot?.getElementById('popup-banner-img') as HTMLImageElement;
const previewBanner = this.shadowRoot?.querySelector('.preview-banner-img') as HTMLImageElement; const previewBanner = this.shadowRoot?.querySelector('.preview-banner-img') as HTMLImageElement;
if (popupBanner) popupBanner.src = result; if (popupBanner) popupBanner.src = result;
if (previewBanner) previewBanner.src = result; if (previewBanner) previewBanner.src = result;
localStorage.setItem('userBanner', result); localStorage.setItem('userBanner', result);
}; };
reader.readAsDataURL(file); reader.readAsDataURL(file);
@ -1454,7 +1455,7 @@ private loadUserInfo(): void {
const savedLastName = localStorage.getItem('userLastName'); const savedLastName = localStorage.getItem('userLastName');
const savedAvatar = localStorage.getItem('userAvatar'); const savedAvatar = localStorage.getItem('userAvatar');
const savedBanner = localStorage.getItem('userBanner'); const savedBanner = localStorage.getItem('userBanner');
// Mise à jour du nom dans la preview // Mise à jour du nom dans la preview
if (savedName) { if (savedName) {
const previewName = this.shadowRoot?.querySelector('.preview-name'); const previewName = this.shadowRoot?.querySelector('.preview-name');
@ -1470,7 +1471,7 @@ private loadUserInfo(): void {
previewLastName.textContent = savedLastName; previewLastName.textContent = savedLastName;
} }
} }
// Mise à jour de l'avatar dans la preview // Mise à jour de l'avatar dans la preview
if (savedAvatar) { if (savedAvatar) {
const previewAvatar = this.shadowRoot?.querySelector('.preview-avatar') as HTMLImageElement; const previewAvatar = this.shadowRoot?.querySelector('.preview-avatar') as HTMLImageElement;
@ -1478,7 +1479,7 @@ private loadUserInfo(): void {
previewAvatar.src = savedAvatar; previewAvatar.src = savedAvatar;
} }
} }
// Mise à jour de la bannière dans la preview // Mise à jour de la bannière dans la preview
if (savedBanner) { if (savedBanner) {
const previewBanner = this.shadowRoot?.querySelector('.preview-banner-img') as HTMLImageElement; const previewBanner = this.shadowRoot?.querySelector('.preview-banner-img') as HTMLImageElement;
@ -1502,11 +1503,11 @@ private updateNavbarLastName(lastName: string): void {
} }
} }
private updateProfilePreview(data: { private updateProfilePreview(data: {
avatar?: string, avatar?: string,
banner?: string, banner?: string,
name?: string, name?: string,
lastName?: string lastName?: string
}): void { }): void {
if (data.avatar) { if (data.avatar) {
const previewAvatar = this.shadowRoot?.querySelector('.preview-avatar') as HTMLImageElement; const previewAvatar = this.shadowRoot?.querySelector('.preview-avatar') as HTMLImageElement;
@ -1544,7 +1545,7 @@ private initializeEventListeners() {
input.type = 'text'; input.type = 'text';
input.value = currentValue; input.value = currentValue;
input.className = 'edit-input'; input.className = 'edit-input';
field.textContent = ''; field.textContent = '';
field.appendChild(input); field.appendChild(input);
field.classList.add('editing'); field.classList.add('editing');
@ -1566,8 +1567,8 @@ private showQRCodeModal(pairingId: string): void {
modal.innerHTML = ` modal.innerHTML = `
<div class="qr-modal-content"> <div class="qr-modal-content">
<span class="close-qr-modal">&times;</span> <span class="close-qr-modal">&times;</span>
<img src="https://api.qrserver.com/v1/create-qr-code/?size=300x300&data=${pairingId}" <img src="https://api.qrserver.com/v1/create-qr-code/?size=300x300&data=${pairingId}"
alt="QR Code Large" alt="QR Code Large"
class="qr-code-large"> class="qr-code-large">
<div class="qr-address">${decodeURIComponent(pairingId)}</div> <div class="qr-address">${decodeURIComponent(pairingId)}</div>
</div> </div>

View File

@ -1,4 +1,4 @@
import { ProcessState } from '.././pkg/sdk_client.js'; import { ProcessState } from '../../../pkg/sdk_client.js';
import Services from '../../services/service'; import Services from '../../services/service';
interface State { interface State {
@ -171,8 +171,8 @@ export function getDocumentValidation(container: HTMLElement) {
) { ) {
state.certificate = json as ProcessState; state.certificate = json as ProcessState;
state.commitmentHashes = Object.values(json.pcd_commitment).map((h: string) => state.commitmentHashes = Object.values(json.pcd_commitment).map((value: unknown, _idx: number, _arr: unknown[]) =>
h.toLowerCase() String(value).toLowerCase()
); );
updateVisuals(file); updateVisuals(file);
@ -206,7 +206,7 @@ export function getDocumentValidation(container: HTMLElement) {
const commitedIn = state.certificate.commited_in; const commitedIn = state.certificate.commited_in;
if (!commitedIn) return; if (!commitedIn) return;
const [prevTxid, prevTxVout] = commitedIn.split(':'); const [prevTxid, prevTxVout] = commitedIn.split(':');
const processId = state.certificate.process_id; const processId = (state.certificate as any).process_id as string;
const stateId = state.certificate.state_id; const stateId = state.certificate.state_id;
const process = await service.getProcess(processId); const process = await service.getProcess(processId);
if (!process) return; if (!process) return;

View File

@ -1,4 +1,4 @@
import { ValidationRule, RoleDefinition } from '.././pkg/sdk_client.js'; import { ValidationRule, RoleDefinition } from '../../../pkg/sdk_client.js';
import { showValidationRuleModal } from '../../components/validation-rule-modal/validation-rule-modal'; import { showValidationRuleModal } from '../../components/validation-rule-modal/validation-rule-modal';
export function createKeyValueSection(title: string, id: string, isRoleSection = false) { export function createKeyValueSection(title: string, id: string, isRoleSection = false) {

View File

@ -1,7 +1,7 @@
import { createKeyValueSection } from './key-value-section'; import { createKeyValueSection } from './key-value-section';
import { loadValidationRuleModal } from '../../components/validation-rule-modal/validation-rule-modal'; import { loadValidationRuleModal } from '../../components/validation-rule-modal/validation-rule-modal';
import Services from '../../services/service'; import Services from '../../services/service';
import { RoleDefinition } from '.././pkg/sdk_client.js'; import { RoleDefinition } from '../../../pkg/sdk_client.js';
export async function getProcessCreation(container: HTMLElement) { export async function getProcessCreation(container: HTMLElement) {
await loadValidationRuleModal(); await loadValidationRuleModal();
@ -55,11 +55,13 @@ export async function getProcessCreation(container: HTMLElement) {
await service.handleApiReturn(approveChangeResult); await service.handleApiReturn(approveChangeResult);
if (approveChangeResult) { if (approveChangeResult) {
const process = await service.getProcess(processId); const process = await service.getProcess(processId);
let newState = service.getStateFromId(process, stateId); if (!process) return;
const newState = service.getStateFromId(process, stateId);
if (!newState) return; if (!newState) return;
for (const label of Object.keys(newState.keys)) { for (const label of Object.keys(newState.keys)) {
const hash = newState.pcd_commitment[label]; const hash = newState.pcd_commitment[label];
const encryptedData = await service.getBlobFromDb(hash); const encryptedData = await service.getBlobFromDb(hash);
if (!encryptedData) continue;
const filename = `${label}-${hash.slice(0,8)}.bin`; const filename = `${label}-${hash.slice(0,8)}.bin`;
const blob = new Blob([encryptedData], { type: "application/octet-stream" }); const blob = new Blob([encryptedData], { type: "application/octet-stream" });
@ -71,11 +73,13 @@ export async function getProcessCreation(container: HTMLElement) {
setTimeout(() => URL.revokeObjectURL(link.href), 1000); setTimeout(() => URL.revokeObjectURL(link.href), 1000);
} }
await service.generateProcessPdf(processId, newState); if (typeof (service as any).generateProcessPdf === 'function') {
await (service as any).generateProcessPdf(processId, newState);
}
// Add processId to the state we export // Add processId to the state we export
newState['process_id'] = processId; (newState as any)['process_id'] = processId;
const blob = new Blob([JSON.stringify(newState, null, 2)], { type: 'application/json' }); const blob = new Blob([JSON.stringify(newState as unknown as object, null, 2)], { type: 'application/json' });
const url = URL.createObjectURL(blob); const url = URL.createObjectURL(blob);
const a = document.createElement('a'); const a = document.createElement('a');

View File

@ -5,7 +5,7 @@
} }
import { membersMock } from '../../mocks/mock-signature/membersMocks'; import { membersMock } from '../../mocks/mock-signature/membersMocks';
import { ApiReturn, Device, Member, Process, RoleDefinition } from '.././pkg/sdk_client.js'; import { ApiReturn, Device, Member, Process, RoleDefinition } from '../pkg/sdk_client.js';
import { getCorrectDOM } from '../../utils/document.utils'; import { getCorrectDOM } from '../../utils/document.utils';
import chatStyle from '../../../public/style/chat.css?inline'; import chatStyle from '../../../public/style/chat.css?inline';
import { addressToEmoji } from '../../utils/sp-address.utils'; import { addressToEmoji } from '../../utils/sp-address.utils';

View File

@ -1,6 +1,6 @@
import { interpolate } from '../../utils/html.utils'; import { interpolate } from '../../utils/html.utils';
import Services from '../../services/service'; import Services from '../../services/service';
import { Process } from '.././pkg/sdk_client.js'; import { Process } from '../../../pkg/sdk_client.js';
import { getCorrectDOM } from '~/utils/document.utils'; import { getCorrectDOM } from '~/utils/document.utils';
let currentPageStyle: HTMLStyleElement | null = null; let currentPageStyle: HTMLStyleElement | null = null;

View File

@ -10,7 +10,7 @@ import { prepareAndSendPairingTx } from './utils/sp-address.utils';
import ModalService from './services/modal.service'; import ModalService from './services/modal.service';
import { MessageType } from './models/process.model'; import { MessageType } from './models/process.model';
import { splitPrivateData, isValid32ByteHex } from './utils/service.utils'; import { splitPrivateData, isValid32ByteHex } from './utils/service.utils';
import { MerkleProofResult } from '.././pkg/sdk_client.js'; import { MerkleProofResult } from '../pkg/sdk_client.js';
const routes: { [key: string]: string } = { const routes: { [key: string]: string } = {
home: '/src/pages/home/home.html', home: '/src/pages/home/home.html',

View File

@ -4,7 +4,7 @@ import validationModalStyle from '../components/validation-modal/validation-moda
import Services from './service'; import Services from './service';
import { init, navigate } from '../router'; import { init, navigate } from '../router';
import { addressToEmoji } from '../utils/sp-address.utils'; import { addressToEmoji } from '../utils/sp-address.utils';
import { RoleDefinition } from '.././pkg/sdk_client.js'; import { RoleDefinition } from '../../pkg/sdk_client.js';
import { initValidationModal } from '~/components/validation-modal/validation-modal'; import { initValidationModal } from '~/components/validation-modal/validation-modal';
import { interpolate } from '~/utils/html.utils'; import { interpolate } from '~/utils/html.utils';

View File

@ -438,7 +438,7 @@ export default class Services {
} }
} catch (error) { } catch (error) {
// Vérifier si l'erreur est liée à des fonds insuffisants // Vérifier si l'erreur est liée à des fonds insuffisants
const errorMessage = error.toString().toLowerCase(); const errorMessage = String(error).toLowerCase();
if (errorMessage.includes('insufficient funds') || errorMessage.includes('missing') && errorMessage.includes('sats')) { if (errorMessage.includes('insufficient funds') || errorMessage.includes('missing') && errorMessage.includes('sats')) {
console.log('🔍 Fonds insuffisants détectés, tentative de transfert automatique...'); console.log('🔍 Fonds insuffisants détectés, tentative de transfert automatique...');
@ -466,11 +466,11 @@ export default class Services {
} }
} catch (transferError) { } catch (transferError) {
console.error('❌ Échec du transfert automatique de fonds:', transferError); console.error('❌ Échec du transfert automatique de fonds:', transferError);
throw new Error(`Failed to create process due to insufficient funds and automatic transfer failed: ${transferError}`); throw new Error(`Failed to create process due to insufficient funds and automatic transfer failed: ${String(transferError)}`);
} }
} else { } else {
// Re-lancer l'erreur originale si ce n'est pas un problème de fonds // Re-lancer l'erreur originale si ce n'est pas un problème de fonds
throw error; throw (error instanceof Error ? error : new Error(String(error)));
} }
} }
} }
@ -515,7 +515,8 @@ export default class Services {
// une API ou un service pour déclencher le transfert // une API ou un service pour déclencher le transfert
throw new Error('Fallback not implemented in browser environment'); throw new Error('Fallback not implemented in browser environment');
} catch (fallbackError) { } catch (fallbackError) {
throw new Error(`Automatic funds transfer failed: ${error.message}`); const errMsg = (error instanceof Error) ? error.message : String(error);
throw new Error(`Automatic funds transfer failed: ${errMsg}`);
} }
} }
} }
@ -1747,8 +1748,10 @@ export default class Services {
public hexToBlob(hexString: string): Blob { public hexToBlob(hexString: string): Blob {
const uint8Array = this.hexToUInt8Array(hexString); const uint8Array = this.hexToUInt8Array(hexString);
// Ensure BlobPart compatibility by passing ArrayBuffer
return new Blob([uint8Array], { type: "application/octet-stream" }); // Use a copy to ensure a regular ArrayBuffer, avoiding SharedArrayBuffer issues
const copy = new Uint8Array(uint8Array);
return new Blob([copy.buffer.slice(0)], { type: "application/octet-stream" });
} }
public hexToUInt8Array(hexString: string): Uint8Array { public hexToUInt8Array(hexString: string): Uint8Array {