Updated the process and process-element page

This commit is contained in:
NicolasCantu 2025-11-04 23:03:24 +01:00
parent 465a4a3c18
commit 614569f5aa
5 changed files with 620 additions and 575 deletions

View File

@ -1,12 +1,12 @@
import processHtml from './process-element.html?raw'; // src/pages/process-element/process-component.ts
import processScript from './process-element.ts?raw';
import processCss from '../../4nk.css?raw';
import { initProcessElement } from './process-element';
export class ProcessListComponent extends HTMLElement { import processHtml from './process-element.html?raw';
import processCss from '../../4nk.css?raw';
import { initProcessElement } from './process-element'; // On importe la vraie fonction
// 1. Nom de classe corrigé (plus logique)
export class ProcessElementComponent extends HTMLElement {
_callback: any; _callback: any;
id: string = '';
zone: string = '';
constructor() { constructor() {
super(); super();
@ -14,38 +14,61 @@ export class ProcessListComponent extends HTMLElement {
} }
connectedCallback() { connectedCallback() {
console.log('CALLBACK PROCESS LIST PAGE'); console.log('[ProcessElementComponent] 1. Composant connecté.');
// 2. Lire les attributs passés par le routeur (router.ts)
const processId = this.getAttribute('process-id');
const stateId = this.getAttribute('state-id');
if (!processId || !stateId) {
console.error("💥 ProcessElementComponent a été créé sans 'process-id' ou 'state-id'.");
this.renderError("Erreur: ID de processus ou d'état manquant.");
return;
}
// 3. Afficher le HTML/CSS du squelette
this.render(); this.render();
setTimeout(() => {
initProcessElement(this.id, this.zone);
}, 500);
}
set callback(fn) { // 4. Appeler la logique (init) en lui passant le shadowRoot et les IDs
if (typeof fn === 'function') { try {
this._callback = fn; if (this.shadowRoot) {
console.log(`[ProcessElementComponent] 2. Appel de initProcessElement pour ${processId}_${stateId}`);
initProcessElement(this.shadowRoot, processId, stateId);
} else { } else {
console.error('Callback is not a function'); console.error("[ProcessElementComponent] 💥 ShadowRoot est nul.");
} }
} catch (e) {
console.error("[ProcessElementComponent] 💥 Échec de l'initProcessElement():", e);
} }
get callback() {
return this._callback;
} }
render() { render() {
if (this.shadowRoot) if (this.shadowRoot) {
this.shadowRoot.innerHTML = ` this.shadowRoot.innerHTML = `
<style> <style>${processCss}</style>
${processCss} ${processHtml}
</style>${processHtml}
<script type="module">
${processScript}
</scipt>
`; `;
} }
}
renderError(message: string) {
if (this.shadowRoot) {
this.shadowRoot.innerHTML = `<style>${processCss}</style>
<div class="title-container"><h1>Erreur</h1></div>
<div class="process-container"><p>${message}</p></div>`;
}
}
// ... (Tes callbacks) ...
set callback(fn) {
    if (typeof fn === 'function') { this._callback = fn; }
else { console.error('Callback is not a function'); }
  }
  get callback() { return this._callback; }
} }
// 6. Utilisation du bon nom de classe
if (!customElements.get('process-4nk-component')) { if (!customElements.get('process-4nk-component')) {
customElements.define('process-4nk-component', ProcessListComponent); console.log('[ProcessElementComponent] Définition de <process-4nk-component>.');
customElements.define('process-4nk-component', ProcessElementComponent);
} }

View File

@ -1,50 +1,111 @@
// src/pages/process-element/process-element.ts
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'; import { Process, ProcessState } from 'pkg/sdk_client';
import { getCorrectDOM } from '~/utils/document.utils'; // 1. Plus besoin de 'getCorrectDOM'
let currentPageStyle: HTMLStyleElement | null = null; /**
* Fonction d'initialisation, appelée par process-component.ts
* Reçoit le shadowRoot et les IDs.
*/
export async function initProcessElement(container: ShadowRoot, processId: string, stateId: string) {
console.log(`[process-element.ts] 3. init() appelé pour ${processId}_${stateId}`);
export async function initProcessElement(id: string, zone: string) { const services = await Services.getInstance();
const processes = await getProcesses();
const container = getCorrectDOM('process-4nk-component'); // 2. Récupérer les éléments du DOM *dans* le shadowRoot (container)
// const currentProcess = processes.find((process) => process[0] === id)[1]; const titleH1 = container.querySelector('h1');
// const currentProcess = {title: 'Hello', html: '', css: ''}; const processContainer = container.querySelector('.process-container');
// await loadPage({ processTitle: currentProcess.title, inputValue: 'Hello World !' });
// const wrapper = document.querySelector('.process-container'); if (!titleH1 || !processContainer) {
// if (wrapper) { console.error("[process-element.ts] 💥 Le HTML de base (h1 ou .process-container) est introuvable !");
// wrapper.innerHTML = interpolate(currentProcess.html, { processTitle: currentProcess.title, inputValue: 'Hello World !' }); return;
// injectCss(currentProcess.css); }
// }
// 3. Récupérer les données
const process = await services.getProcess(processId);
if (!process) {
console.error(`[process-element.ts] 💥 Processus ${processId} non trouvé !`);
titleH1.innerText = "Erreur";
processContainer.innerHTML = `<p>Le processus ${processId} n'a pas pu être chargé.</p>`;
return;
}
const state = services.getStateFromId(process, stateId);
if (!state) {
console.error(`[process-element.ts] 💥 État ${stateId} non trouvé dans le processus ${processId} !`);
titleH1.innerText = "Erreur";
processContainer.innerHTML = `<p>L'état ${stateId} n'a pas pu être chargé.</p>`;
return;
}
console.log("[process-element.ts] ✅ Processus et État chargés.");
// 4. Mettre à jour le titre
const processName = services.getProcessName(process) || "Processus";
titleH1.innerHTML = interpolate(titleH1.innerHTML, { processTitle: processName });
// 5. Logique de rendu de l'élément (À COMPLÉTER PAR TES SOINS)
// C'est là que tu dois construire le HTML pour cet état spécifique
// Par exemple, déchiffrer les attributs et les afficher.
processContainer.innerHTML = `
<div class="card" style="margin: 1rem; padding: 1rem;">
<h3>État: ${stateId.substring(0, 10)}...</h3>
<p>Commit: ${state.commited_in}</p>
<div id="attributes-list">
<p><em>Chargement des attributs...</em></p>
</div>
</div>
`;
// 6. Tenter de déchiffrer les données de cet état
await decryptAndDisplayAttributes(services, container, processId, state);
} }
async function loadPage(data?: any) { /**
const content = document.getElementById('containerId'); * Helper (exemple) pour déchiffrer et afficher les données dans le conteneur
if (content && data) { */
if (data) { async function decryptAndDisplayAttributes(services: Services, container: ShadowRoot, processId: string, state: ProcessState) {
content.innerHTML = interpolate(content.innerHTML, data); const attributesList = container.querySelector('#attributes-list');
if (!attributesList) return;
console.log(`[process-element.ts] 🔐 Déchiffrement des attributs pour l'état ${state.state_id}...`);
attributesList.innerHTML = ''; // Vide le message "Chargement..."
let hasPrivateData = false;
// Affiche les données publiques
if (state.public_data) {
for (const [key, value] of Object.entries(state.public_data)) {
const el = document.createElement('div');
el.className = 'attribute-pair public';
el.innerHTML = `<strong>${key} (public):</strong> ${JSON.stringify(services.decodeValue(value))}`;
attributesList.appendChild(el);
} }
} }
}
function injectCss(cssContent: string) { // Affiche les données privées
removeCss(); // Ensure that the previous CSS is removed for (const attribute of Object.keys(state.pcd_commitment)) {
if (attribute === 'roles' || (state.public_data && state.public_data[attribute])) {
continue; // Skip les données publiques (déjà fait) et les rôles
}
currentPageStyle = document.createElement('style'); const decryptedValue = await services.decryptAttribute(processId, state, attribute);
currentPageStyle.type = 'text/css';
currentPageStyle.appendChild(document.createTextNode(cssContent));
document.head.appendChild(currentPageStyle);
}
function removeCss() { const el = document.createElement('div');
if (currentPageStyle) { el.className = 'attribute-pair private';
document.head.removeChild(currentPageStyle);
currentPageStyle = null; if (decryptedValue) {
hasPrivateData = true;
el.innerHTML = `<strong>${attribute} (privé):</strong> ${JSON.stringify(decryptedValue)}`;
} else {
el.innerHTML = `<strong>${attribute} (privé):</strong> <span style="color: red;">[Déchiffrement impossible / Clé manquante]</span>`;
}
attributesList.appendChild(el);
}
if (!hasPrivateData && !(state.public_data && Object.keys(state.public_data).length > 0)) {
console.log("[process-element.ts] Aucun attribut (public ou privé) trouvé pour cet état.");
attributesList.innerHTML = '<p>Cet état ne contient aucun attribut visible.</p>';
} }
} }
async function getProcesses(): Promise<Record<string, Process>> {
const service = await Services.getInstance();
const processes = await service.getProcesses();
return processes;
}

View File

@ -1,49 +1,40 @@
// import processHtml from './process.html?raw'; // src/pages/process/process-list-component.ts
// import processScript from './process.ts?raw';
// import processCss from '../../4nk.css?raw';
// import { init } from './process';
// export class ProcessListComponent extends HTMLElement { import processHtml from './process.html?raw';
// _callback: any; import processCss from '../../4nk.css?raw';
// constructor() { import { init } from './process';
// super();
// this.attachShadow({ mode: 'open' });
// }
// connectedCallback() { export class ProcessListComponent extends HTMLElement {
// console.log('CALLBACK PROCESS LIST PAGE'); constructor() {
// this.render(); super();
// setTimeout(() => { this.attachShadow({ mode: 'open' });
// init(); }
// }, 500);
// }
// set callback(fn) { connectedCallback() {
// if (typeof fn === 'function') { this.render();
// this._callback = fn;
// } else {
// console.error('Callback is not a function');
// }
// }
// get callback() { try {
// return this._callback; if (this.shadowRoot) {
// } init(this.shadowRoot);
} else {
console.error('[ProcessListComponent] 💥 ShadowRoot est nul.');
}
} catch (e) {
console.error("[ProcessListComponent] 💥 Échec de l'init():", e);
}
}
// render() { render() {
// if (this.shadowRoot) if (this.shadowRoot) {
// this.shadowRoot.innerHTML = ` this.shadowRoot.innerHTML = `
// <style> <style>${processCss}</style>
// ${processCss} ${processHtml}
// </style>${processHtml} `;
// <script type="module"> }
// ${processScript} }
// </scipt>
// `; }
// }
// }
// if (!customElements.get('process-list-4nk-component')) { if (!customElements.get('process-list-4nk-component')) {
// customElements.define('process-list-4nk-component', ProcessListComponent); customElements.define('process-list-4nk-component', ProcessListComponent);
// } }

View File

@ -1,4 +1,4 @@
<!-- <div class="title-container"> <div class="title-container">
<h1>Process Selection</h1> <h1>Process Selection</h1>
</div> </div>
@ -7,13 +7,17 @@
<div class="process-card-description"> <div class="process-card-description">
<div class="input-container"> <div class="input-container">
<select multiple data-multi-select-plugin id="autocomplete" placeholder="Filter processes..." class="select-field"></select> <select multiple data-multi-select-plugin id="autocomplete" placeholder="Filter processes..." class="select-field"></select>
<label for="autocomplete" class="input-label">Filter processes :</label> <label for="autocomplete" class="input-label">Filter processes :</label>
<div class="selected-processes"></div> <div class="selected-processes"></div>
</div> </div>
<div class="process-card-content"></div> <div class="process-card-content"></div>
</div> </div>
<div class="process-card-action"> <div class="process-card-action">
<a class="btn" onclick="goToProcessPage()">OK</a> <a class="btn" id="go-to-process-btn">OK</a>
</div> </div>
</div> </div>
</div> --> </div>

File diff suppressed because it is too large Load Diff