refactor: remove unused modal components and related files

This commit is contained in:
NicolasCantu 2025-11-25 10:42:02 +01:00
parent d072eb0831
commit 3eeef3fc9a
10 changed files with 1 additions and 689 deletions

View File

@ -1,84 +0,0 @@
import globalCss from '../../assets/styles/style.css?inline';
export class ConfirmationModal extends HTMLElement {
private _title: string = '';
private _content: string = '';
private _onConfirm: () => void = () => {};
private _onCancel: () => void = () => {};
constructor() {
super();
this.attachShadow({ mode: 'open' });
}
configure(title: string, content: string, onConfirm: () => void, onCancel: () => void) {
this._title = title;
this._content = content;
this._onConfirm = onConfirm;
this._onCancel = onCancel;
this.render();
}
render() {
if (!this.shadowRoot) return;
this.shadowRoot.innerHTML = `
<style>
${globalCss}
.modal-overlay {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: rgba(0, 0, 0, 0.5);
display: flex;
justify-content: center;
align-items: center;
z-index: 3000;
}
.modal-content {
background: white;
padding: 20px;
border-radius: 8px;
width: 90%;
max-width: 500px;
text-align: left;
}
.modal-footer {
display: flex;
justify-content: flex-end;
gap: 10px;
margin-top: 20px;
padding-top: 15px;
border-top: 1px solid #eee;
}
</style>
<div class="modal-overlay">
<div class="modal-content">
<h2>${this._title}</h2>
<div class="modal-body">
${this._content}
</div>
<div class="modal-footer">
<button id="cancel-button" class="btn" style="background-color: #B0BEC5;">Annuler</button>
<button id="confirm-button" class="btn">Confirmer</button>
</div>
</div>
</div>
`;
this.shadowRoot.querySelector('#confirm-button')?.addEventListener('click', () => {
this._onConfirm();
this.remove();
});
this.shadowRoot.querySelector('#cancel-button')?.addEventListener('click', () => {
this._onCancel();
this.remove();
});
}
}
customElements.define('confirmation-modal', ConfirmationModal);

View File

@ -1,82 +0,0 @@
import globalCss from '../../assets/styles/style.css?inline';
import ModalService from '../../services/modal.service';
export class LoginModal extends HTMLElement {
private _device1: string = '';
private _device2: string = '';
constructor() {
super();
this.attachShadow({ mode: 'open' });
}
set devices(data: { device1: string; device2: string }) {
this._device1 = data.device1;
this._device2 = data.device2;
this.render();
}
connectedCallback() {
this.render();
}
render() {
if (!this.shadowRoot) return;
this.shadowRoot.innerHTML = `
<style>
${globalCss}
.modal {
display: flex; /* Flex pour centrer */
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: rgba(0, 0, 0, 0.5);
justify-content: center;
align-items: center;
z-index: 2000;
}
.modal-content {
width: 55%;
min-width: 300px;
background-color: white;
border-radius: 4px;
padding: 20px;
text-align: center;
display: flex;
flex-direction: column;
align-items: center;
}
</style>
<div id="login-modal" class="modal">
<div class="modal-content">
<div class="modal-title">Login Confirmation</div>
<div class="confirmation-box">
<div class="message">
Attempting to pair device with address:<br>
<strong>${this._device1}</strong><br>
with device with address:<br>
<strong>${this._device2}</strong>
</div>
<div style="margin-top: 20px; font-style: italic;">
Awaiting pairing validation on the other device...
</div>
<div style="margin-top: 20px;">
<button class="btn" id="close-login-btn">Cancel / Close</button>
</div>
</div>
</div>
</div>
`;
this.shadowRoot.querySelector('#close-login-btn')?.addEventListener('click', async () => {
const service = await ModalService.getInstance();
service.closeLoginModal();
});
}
}
customElements.define('login-modal', LoginModal);

View File

@ -1,195 +0,0 @@
import globalCss from '../../assets/styles/style.css?inline';
import validationCss from './validation-modal.css?inline'; // On va créer ce fichier juste après ou utiliser le string
import validationHtml from './validation-modal.html?raw'; // Idem
import ModalService from '../../services/modal.service';
export class ValidationModal extends HTMLElement {
private _diffs: any;
constructor() {
super();
this.attachShadow({ mode: 'open' });
}
connectedCallback() {
this.render();
}
set processDiffs(data: any) {
this._diffs = data;
this.render();
this.initLogic();
}
render() {
if (!this.shadowRoot) return;
// On fusionne le CSS global et le CSS spécifique
// Note: J'intègre directement le CSS spécifique ici pour simplifier si tu n'as pas le fichier séparé
const specificCss = `
.validation-modal {
display: block;
position: fixed;
z-index: 1000; /* Z-index élevé pour être au-dessus */
left: 0;
top: 0;
width: 100%;
height: 100%;
overflow: auto;
background-color: rgba(0, 0, 0, 0.4);
padding-top: 60px;
}
.modal-content {
background-color: #fefefe;
margin: 5% auto;
padding: 20px;
border: 1px solid #888;
width: 80%;
max-width: 800px;
height: fit-content;
border-radius: 8px;
}
.modal-title {
font-size: 24px;
font-weight: bold;
margin-bottom: 20px;
}
.validation-box {
margin-bottom: 15px;
width: 100%;
}
.expansion-panel-header {
background-color: #e0e0e0;
padding: 10px;
cursor: pointer;
margin-top: 5px;
font-weight: bold;
}
.expansion-panel-body {
display: none; /* Caché par défaut */
background-color: #fafafa;
padding: 10px;
border: 1px solid #ddd;
border-top: none;
}
.expansion-panel-body pre {
background-color: #f6f8fa;
padding: 10px;
border-left: 4px solid #d1d5da;
overflow-x: auto;
}
.diff {
display: flex;
justify-content: space-between;
margin-bottom: 10px;
}
.diff-side {
width: 48%;
padding: 10px;
box-sizing: border-box;
}
.diff-old {
background-color: #fee;
border: 1px solid #f00;
}
.diff-new {
background-color: #e6ffe6;
border: 1px solid #0f0;
}
.radio-buttons {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 10px;
padding: 10px;
background: #eee;
}
`;
const processId = this._diffs?.processId || 'Unknown';
this.shadowRoot.innerHTML = `
<style>
${globalCss}
${specificCss}
</style>
<div id="validation-modal" class="validation-modal">
<div class="modal-content">
<div class="modal-title">Validate Process ${processId}</div>
<div class="validation-box">
</div>
<div class="modal-action" style="display: flex; justify-content: flex-end; margin-top: 20px;">
<button class="btn" id="validate-btn">Validate</button>
</div>
</div>
</div>
`;
}
initLogic() {
if (!this._diffs || !this.shadowRoot) return;
const box = this.shadowRoot.querySelector('.validation-box');
const btn = this.shadowRoot.querySelector('#validate-btn');
if (!box) return;
// Génération du HTML des diffs (Logique migrée de ton ancien validation-modal.ts)
// Note: ton objet processDiffs a une structure { diffs: [ [val1, val2], ... ] }
if (this._diffs.diffs) {
for (const diffGroup of this._diffs.diffs) {
let diffsHtml = '';
let merkleRoot = '';
for (const value of diffGroup) {
merkleRoot = value.new_state_merkle_root || 'Unknown'; // On récupère le root pour le header
diffsHtml += `
<div class="radio-buttons">
<label><input type="radio" name="val_${merkleRoot}" value="old" /> Keep Old</label>
<label><input type="radio" name="val_${merkleRoot}" value="new" checked /> Keep New</label>
</div>
<div class="diff">
<div class="diff-side diff-old">
<strong>Old:</strong>
<pre>${value.previous_value || 'null'}</pre>
</div>
<div class="diff-side diff-new">
<strong>New:</strong>
<pre>${value.new_value}</pre>
</div>
</div>
`;
}
const stateHtml = `
<div class="expansion-panel">
<div class="expansion-panel-header">State ${merkleRoot.substring(0, 10)}...</div>
<div class="expansion-panel-body" style="display:block"> ${diffsHtml}
</div>
</div>
`;
box.innerHTML += stateHtml;
}
}
// Gestionnaire pour les accordéons
this.shadowRoot.querySelectorAll('.expansion-panel-header').forEach((header) => {
header.addEventListener('click', (event) => {
const target = event.target as HTMLElement;
const body = target.nextElementSibling as HTMLElement;
if (body) {
body.style.display = body.style.display === 'none' ? 'block' : 'none';
}
});
});
// Gestionnaire du bouton Validate
btn?.addEventListener('click', async () => {
console.log('==> VALIDATE CLICKED');
const modalService = await ModalService.getInstance();
modalService.closeValidationModal();
});
}
}
customElements.define('validation-modal', ValidationModal);

View File

@ -1,14 +0,0 @@
<div id="login-modal" class="modal">
<div class="modal-content">
<div class="modal-title">Login</div>
<div class="confirmation-box">
<div class="message">
Attempting to pair device with address
<strong>{{device1}}</strong>
with device with address
<strong>{{device2}}</strong>
</div>
<div>Awaiting pairing validation...</div>
</div>
</div>
</div>

View File

@ -1,13 +0,0 @@
import Routing from '/src/services/routing.service.ts';
const router = await Routing.getInstance();
export async function confirmLogin() {
router.confirmLogin();
}
export async function closeLoginModal() {
router.closeLoginModal();
}
window.confirmLogin = confirmLogin;
window.closeLoginModal = closeLoginModal;

View File

@ -1,70 +0,0 @@
.validation-modal {
display: block; /* Show the modal for demo purposes */
position: fixed;
z-index: 1;
left: 0;
top: 0;
width: 100%;
height: 100%;
overflow: auto;
background-color: rgb(0, 0, 0);
background-color: rgba(0, 0, 0, 0.4);
padding-top: 60px;
}
.modal-content {
background-color: #fefefe;
margin: 5% auto;
padding: 20px;
border: 1px solid #888;
width: 80%;
height: fit-content;
}
.modal-title {
font-size: 24px;
font-weight: bold;
margin-bottom: 20px;
}
.validation-box {
margin-bottom: 15px;
width: 100%;
}
.expansion-panel-header {
background-color: #e0e0e0;
padding: 10px;
cursor: pointer;
}
.expansion-panel-body {
display: none;
background-color: #fafafa;
padding: 10px;
border-top: 1px solid #ddd;
}
.expansion-panel-body pre {
background-color: #f6f8fa;
padding: 10px;
border-left: 4px solid #d1d5da;
overflow-x: auto;
}
.diff {
display: flex;
justify-content: space-between;
margin-bottom: 10px;
}
.diff-side {
width: 48%;
padding: 10px;
}
.diff-old {
background-color: #fee;
border: 1px solid #f00;
}
.diff-new {
background-color: #e6ffe6;
border: 1px solid #0f0;
}
.radio-buttons {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 10px;
}

View File

@ -1,11 +0,0 @@
<div id="validation-modal" class="validation-modal">
<div class="modal-content">
<div class="modal-title">Validate Process {{processId}}</div>
<div class="validation-box">
</div>
<div class="modal-action">
<button onclick="validate()">Validate</button>
</div>
</div>
</div>

View File

@ -1,56 +0,0 @@
import ModalService from '~/services/modal.service';
async function validate() {
console.log('==> VALIDATE');
const modalservice = await ModalService.getInstance();
modalservice.closeValidationModal();
}
export async function initValidationModal(processDiffs: any) {
console.log("🚀 ~ initValidationModal ~ processDiffs:", processDiffs)
for(const diff of processDiffs.diffs) {
let diffs = ''
for(const value of diff) {
diffs+= `
<div class="radio-buttons">
<label>
<input type="radio" name="validation1" value="old" />
Keep Old
</label>
<label>
<input type="radio" name="validation1" value="new" />
Keep New
</label>
</div>
<div class="diff">
<div class="diff-side diff-old">
<pre>-${value.previous_value}</pre>
</div>
<div class="diff-side diff-new">
<pre>+${value.new_value}</pre>
</div>
</div>
`
}
const state = `
<div class="expansion-panel">
<div class="expansion-panel-header">State ${diff[0].new_state_merkle_root}</div>
<div class="expansion-panel-body">
${diffs}
</div>
</div>
`
const box = document.querySelector('.validation-box')
if(box) box.innerHTML += state
}
document.querySelectorAll('.expansion-panel-header').forEach((header) => {
header.addEventListener('click', function (event) {
const target = event.target as HTMLElement;
const body = target.nextElementSibling as HTMLElement;
if (body?.style) body.style.display = body.style.display === 'block' ? 'none' : 'block';
});
});
}
(window as any).validate = validate;

View File

@ -1,145 +0,0 @@
import Services from './service';
import { addressToEmoji } from '../utils/sp-address.utils';
import { RoleDefinition } from '../../pkg/sdk_client';
// Import des composants pour s'assurer qu'ils sont enregistrés
import '../components/modal/ValidationModal';
import '../components/modal/LoginModal';
import '../components/modal/ConfirmationModal';
interface ConfirmationModalOptions {
title: string;
content: string;
confirmText?: string;
cancelText?: string;
}
export default class ModalService {
private static instance: ModalService;
private currentModal: HTMLElement | null = null;
private constructor() {}
public static async getInstance(): Promise<ModalService> {
if (!ModalService.instance) {
ModalService.instance = new ModalService();
}
return ModalService.instance;
}
// --- Gestion LOGIN MODAL ---
public openLoginModal(myAddress: string, receiverAddress: string) {
this.closeCurrentModal(); // Sécurité
const modal = document.createElement('login-modal') as any;
// On passe les données au composant
modal.devices = { device1: myAddress, device2: receiverAddress };
document.body.appendChild(modal);
this.currentModal = modal;
}
public async closeLoginModal() {
if (this.currentModal && this.currentModal.tagName === 'LOGIN-MODAL') {
this.currentModal.remove();
this.currentModal = null;
}
}
public confirmLogin() {
console.log('=============> Confirm Login');
// Logique de confirmation à implémenter si besoin
}
// --- Gestion VALIDATION MODAL ---
async injectValidationModal(processDiff: any) {
this.closeCurrentModal();
const modal = document.createElement('validation-modal') as any;
modal.processDiffs = processDiff;
document.body.appendChild(modal);
this.currentModal = modal;
}
async closeValidationModal() {
if (this.currentModal && this.currentModal.tagName === 'VALIDATION-MODAL') {
this.currentModal.remove();
this.currentModal = null;
}
}
// --- Gestion CONFIRMATION MODAL (Generic) ---
// Utilisé pour la confirmation d'appairage
public async openPairingConfirmationModal(roleDefinition: Record<string, RoleDefinition>, processId: string, stateId: string) {
let members;
if (roleDefinition['pairing']) {
members = roleDefinition['pairing'].members;
} else {
throw new Error('No "pairing" role');
}
// On veut afficher les émojis des autres membres
const service = await Services.getInstance();
const localAddress = service.getDeviceAddress();
let contentHtml = `<p>Confirmation de l'appairage pour le processus ${processId.substring(0, 8)}...</p>`;
// Récupération des emojis (simplifié)
// Note: Dans ton ancien code, tu récupérais les membres et affichais les emojis.
// Ici on utilise notre modale générique.
const confirmAction = async () => {
console.log('Pairing confirmed via Modal');
// Ajouter ici la logique de confirmation si nécessaire
};
const cancelAction = async () => {
console.log('Pairing cancelled via Modal');
await this.closeConfirmationModal();
};
// On utilise showConfirmationModal qui fait tout le travail
await this.showConfirmationModal({
title: 'Confirm Pairing',
content: contentHtml,
confirmText: 'Valider',
cancelText: 'Refuser',
});
}
async showConfirmationModal(options: ConfirmationModalOptions, fullscreen: boolean = false): Promise<boolean> {
return new Promise((resolve) => {
const modal = document.createElement('confirmation-modal') as any;
modal.configure(
options.title,
options.content,
() => {
resolve(true);
}, // Confirm
() => {
resolve(false);
}, // Cancel
);
document.body.appendChild(modal);
// Note: ConfirmationModal se supprime lui-même du DOM après clic, pas besoin de le stocker dans currentModal
// sauf si on veut pouvoir le fermer par programme.
});
}
async closeConfirmationModal() {
const service = await Services.getInstance();
await service.unpairDevice();
// Le composant ConfirmationModal se gère lui-même, mais on peut ajouter une logique ici si on le stocke.
}
private closeCurrentModal() {
if (this.currentModal) {
this.currentModal.remove();
this.currentModal = null;
}
}
}

View File

@ -1,6 +1,5 @@
import { initWebsocket, sendMessage } from './websockets.service.ts';
import { ApiReturn, Device, HandshakeMessage, Member, MerkleProofResult, NewTxMessage, OutPointProcessMap, Process, ProcessState, RoleDefinition, SecretsStore, UserDiff } from '../../pkg/sdk_client';
import ModalService from './modal.service';
import Database from './database.service';
import { storeData, retrieveData, testData } from './storage.service';
import { BackUp } from '../types/index';
@ -25,7 +24,6 @@ export default class Services {
private notifications: any[] | null = null;
private subscriptions: { element: Element; event: string; eventHandler: string }[] = [];
private database: any;
private routingInstance!: ModalService;
private relayAddresses: { [wsurl: string]: string } = {};
private membersList: Record<string, Member> = {};
private currentBlockHeight: number = -1;
@ -45,7 +43,6 @@ export default class Services {
Services.initializing = (async () => {
const instance = new Services();
await instance.init();
instance.routingInstance = await ModalService.getInstance();
return instance;
})();
}
@ -1213,22 +1210,7 @@ export default class Services {
this.sendCipherMessages(ciphers);
}
public async openPairingConfirmationModal(processId: string) {
console.log('[Services:openPairingConfirmationModal] 띄 Ouverture du modal de confirmation...');
const process = await this.getProcess(processId);
if (!process) {
console.error('[Services:openPairingConfirmationModal] 💥 Échec: processus de pairing non trouvé');
return;
}
const firstState = process.states[0];
const roles = firstState.roles;
const stateId = firstState.state_id;
try {
await this.routingInstance.openPairingConfirmationModal(roles, processId, stateId);
} catch (e) {
console.error(e);
}
}
public async confirmPairing() {
console.log('[Services:confirmPairing] 🤝 Confirmation du pairing...');