Commented all files in /src/pages/account

This commit is contained in:
NicolasCantu 2025-11-04 23:02:39 +01:00
parent f78ed88cb1
commit dddbe04a2d
8 changed files with 1999 additions and 1999 deletions

View File

@ -1,20 +1,20 @@
import { SignatureComponent } from './pages/signature/signature-component';
import { SignatureElement } from './pages/signature/signature';
/*import { ChatComponent } from './pages/chat/chat-component';
import { ChatElement } from './pages/chat/chat';*/
import { AccountComponent } from './pages/account/account-component';
import { AccountElement } from './pages/account/account';
// import { ChatComponent } from './pages/chat/chat-component';
// import { ChatElement } from './pages/chat/chat';
// import { AccountComponent } from './pages/account/account-component';
// import { AccountElement } from './pages/account/account';
export { SignatureComponent, SignatureElement, AccountComponent, AccountElement };
export { SignatureComponent, SignatureElement };
declare global {
interface HTMLElementTagNameMap {
'signature-component': SignatureComponent;
'signature-element': SignatureElement;
/*'chat-component': ChatComponent;
'chat-element': ChatElement;*/
'account-component': AccountComponent;
'account-element': AccountElement;
// 'chat-component': ChatComponent;
// 'chat-element': ChatElement;
// 'account-component': AccountComponent;
// 'account-element': AccountElement;
}
}
@ -25,6 +25,6 @@ if ((import.meta as any).env.VITE_IS_INDEPENDANT_LIB) {
customElements.define('signature-element', SignatureElement);
/*customElements.define('chat-component', ChatComponent);
customElements.define('chat-element', ChatElement);*/
customElements.define('account-component', AccountComponent);
customElements.define('account-element', AccountElement);
// customElements.define('account-component', AccountComponent);
// customElements.define('account-element', AccountElement);
}

View File

@ -1,62 +1,62 @@
import { AccountElement } from './account';
import accountCss from '../../../public/style/account.css?raw';
import Services from '../../services/service.js';
// import { AccountElement } from './account';
// import accountCss from '../../../style/account.css?raw';
// import Services from '../../services/service.js';
class AccountComponent extends HTMLElement {
_callback: any;
accountElement: AccountElement | null = null;
// class AccountComponent extends HTMLElement {
// _callback: any;
// accountElement: AccountElement | null = null;
constructor() {
super();
console.log('INIT');
this.attachShadow({ mode: 'open' });
// constructor() {
// super();
// console.log('INIT');
// this.attachShadow({ mode: 'open' });
this.accountElement = this.shadowRoot?.querySelector('account-element') || null;
}
// this.accountElement = this.shadowRoot?.querySelector('account-element') || null;
// }
connectedCallback() {
console.log('CALLBACKs');
this.render();
this.fetchData();
// connectedCallback() {
// console.log('CALLBACKs');
// this.render();
// this.fetchData();
if (!customElements.get('account-element')) {
customElements.define('account-element', AccountElement);
}
}
// if (!customElements.get('account-element')) {
// customElements.define('account-element', AccountElement);
// }
// }
async fetchData() {
if ((import.meta as any).env.VITE_IS_INDEPENDANT_LIB === false) {
const data = await (window as any).myService?.getProcesses();
} else {
const service = await Services.getInstance();
const data = await service.getProcesses();
}
}
// async fetchData() {
// if ((import.meta as any).env.VITE_IS_INDEPENDANT_LIB === false) {
// const data = await (window as any).myService?.getProcesses();
// } else {
// const service = await Services.getInstance();
// const data = await service.getProcesses();
// }
// }
set callback(fn) {
if (typeof fn === 'function') {
this._callback = fn;
} else {
console.error('Callback is not a function');
}
}
// set callback(fn) {
// if (typeof fn === 'function') {
// this._callback = fn;
// } else {
// console.error('Callback is not a function');
// }
// }
get callback() {
return this._callback;
}
// get callback() {
// return this._callback;
// }
render() {
if (this.shadowRoot && !this.shadowRoot.querySelector('account-element')) {
const style = document.createElement('style');
style.textContent = accountCss;
// render() {
// if (this.shadowRoot && !this.shadowRoot.querySelector('account-element')) {
// const style = document.createElement('style');
// style.textContent = accountCss;
const accountElement = document.createElement('account-element');
// const accountElement = document.createElement('account-element');
this.shadowRoot.appendChild(style);
this.shadowRoot.appendChild(accountElement);
}
}
}
// this.shadowRoot.appendChild(style);
// this.shadowRoot.appendChild(accountElement);
// }
// }
// }
export { AccountComponent };
customElements.define('account-component', AccountComponent);
// export { AccountComponent };
// customElements.define('account-component', AccountComponent);

View File

@ -1,4 +1,4 @@
<!DOCTYPE html>
<!-- <!DOCTYPE html>
<html lang="en">
<head>
<title>Account</title>
@ -7,4 +7,4 @@
<account-component></account-component>
<script type="module" src="./account.ts"></script>
</body>
</html>
</html> -->

File diff suppressed because it is too large Load Diff

View File

@ -1,321 +1,321 @@
import { ProcessState } from '../../../pkg/sdk_client';
import Services from '../../services/service';
// import { ProcessState } from '../../../pkg/sdk_client';
// import Services from '../../services/service';
interface State {
file: File | null;
fileHash: string | null;
certificate: ProcessState | null;
commitmentHashes: string[];
}
// interface State {
// file: File | null;
// fileHash: string | null;
// certificate: ProcessState | null;
// commitmentHashes: string[];
// }
export interface Vin {
txid: string; // The txid of the previous transaction (being spent)
vout: number; // The output index in the previous tx
prevout: {
scriptpubkey: string;
scriptpubkey_asm: string;
scriptpubkey_type: string;
scriptpubkey_address: string;
value: number;
};
scriptsig: string;
scriptsig_asm: string;
witness: string[];
is_coinbase: boolean;
sequence: number;
}
// export interface Vin {
// txid: string; // The txid of the previous transaction (being spent)
// vout: number; // The output index in the previous tx
// prevout: {
// scriptpubkey: string;
// scriptpubkey_asm: string;
// scriptpubkey_type: string;
// scriptpubkey_address: string;
// value: number;
// };
// scriptsig: string;
// scriptsig_asm: string;
// witness: string[];
// is_coinbase: boolean;
// sequence: number;
// }
export interface TransactionInfo {
txid: string;
version: number;
locktime: number;
vin: Vin[];
vout: any[];
size: number;
weight: number;
fee: number;
status: {
confirmed: boolean;
block_height: number;
block_hash: string;
block_time: number;
};
}
// export interface TransactionInfo {
// txid: string;
// version: number;
// locktime: number;
// vin: Vin[];
// vout: any[];
// size: number;
// weight: number;
// fee: number;
// status: {
// confirmed: boolean;
// block_height: number;
// block_hash: string;
// block_time: number;
// };
// }
export function getDocumentValidation(container: HTMLElement) {
const state: State = {
file: null,
fileHash: null,
certificate: null,
commitmentHashes: []
}
// export function getDocumentValidation(container: HTMLElement) {
// const state: State = {
// file: null,
// fileHash: null,
// certificate: null,
// commitmentHashes: []
// }
container.innerHTML = '';
container.style.cssText = `
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
min-height: 100vh;
gap: 2rem;
`;
// container.innerHTML = '';
// container.style.cssText = `
// display: flex;
// flex-direction: column;
// justify-content: center;
// align-items: center;
// min-height: 100vh;
// gap: 2rem;
// `;
function createDropButton(
label: string,
onDrop: (file: File, updateVisuals: (file: File) => void) => void,
accept: string = '*/*'
): HTMLElement {
const wrapper = document.createElement('div');
wrapper.style.cssText = `
width: 200px;
height: 100px;
border: 2px dashed #888;
border-radius: 8px;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
cursor: pointer;
font-weight: bold;
background: #f8f8f8;
text-align: center;
padding: 0.5rem;
box-sizing: border-box;
`;
// function createDropButton(
// label: string,
// onDrop: (file: File, updateVisuals: (file: File) => void) => void,
// accept: string = '*/*'
// ): HTMLElement {
// const wrapper = document.createElement('div');
// wrapper.style.cssText = `
// width: 200px;
// height: 100px;
// border: 2px dashed #888;
// border-radius: 8px;
// display: flex;
// flex-direction: column;
// align-items: center;
// justify-content: center;
// cursor: pointer;
// font-weight: bold;
// background: #f8f8f8;
// text-align: center;
// padding: 0.5rem;
// box-sizing: border-box;
// `;
const title = document.createElement('div');
title.textContent = label;
// const title = document.createElement('div');
// title.textContent = label;
const filename = document.createElement('div');
filename.style.cssText = `
font-size: 0.85rem;
margin-top: 0.5rem;
color: #444;
word-break: break-word;
text-align: center;
`;
// const filename = document.createElement('div');
// filename.style.cssText = `
// font-size: 0.85rem;
// margin-top: 0.5rem;
// color: #444;
// word-break: break-word;
// text-align: center;
// `;
wrapper.appendChild(title);
wrapper.appendChild(filename);
// wrapper.appendChild(title);
// wrapper.appendChild(filename);
const updateVisuals = (file: File) => {
wrapper.style.borderColor = 'green';
wrapper.style.background = '#e6ffed';
filename.textContent = file.name;
};
// const updateVisuals = (file: File) => {
// wrapper.style.borderColor = 'green';
// wrapper.style.background = '#e6ffed';
// filename.textContent = file.name;
// };
// === Hidden file input ===
const fileInput = document.createElement('input');
fileInput.type = 'file';
fileInput.accept = accept;
fileInput.style.display = 'none';
document.body.appendChild(fileInput);
// // === Hidden file input ===
// const fileInput = document.createElement('input');
// fileInput.type = 'file';
// fileInput.accept = accept;
// fileInput.style.display = 'none';
// document.body.appendChild(fileInput);
fileInput.onchange = () => {
const file = fileInput.files?.[0];
if (file) {
onDrop(file, updateVisuals);
fileInput.value = ''; // reset so same file can be re-selected
}
};
// fileInput.onchange = () => {
// const file = fileInput.files?.[0];
// if (file) {
// onDrop(file, updateVisuals);
// fileInput.value = ''; // reset so same file can be re-selected
// }
// };
// === Handle drag-and-drop ===
wrapper.ondragover = e => {
e.preventDefault();
wrapper.style.background = '#e0e0e0';
};
// // === Handle drag-and-drop ===
// wrapper.ondragover = e => {
// e.preventDefault();
// wrapper.style.background = '#e0e0e0';
// };
wrapper.ondragleave = () => {
wrapper.style.background = '#f8f8f8';
};
// wrapper.ondragleave = () => {
// wrapper.style.background = '#f8f8f8';
// };
wrapper.ondrop = e => {
e.preventDefault();
wrapper.style.background = '#f8f8f8';
// wrapper.ondrop = e => {
// e.preventDefault();
// wrapper.style.background = '#f8f8f8';
const file = e.dataTransfer?.files?.[0];
if (file) {
onDrop(file, updateVisuals);
}
};
// const file = e.dataTransfer?.files?.[0];
// if (file) {
// onDrop(file, updateVisuals);
// }
// };
// === Handle click to open file manager ===
wrapper.onclick = () => {
fileInput.click();
};
// // === Handle click to open file manager ===
// wrapper.onclick = () => {
// fileInput.click();
// };
return wrapper;
}
// return wrapper;
// }
const fileDropButton = createDropButton('Drop file', async (file, updateVisuals) => {
try {
state.file = file;
updateVisuals(file);
console.log('Loaded file:', state.file);
checkReady();
} catch (err) {
alert('Failed to drop the file.');
console.error(err);
}
});
// const fileDropButton = createDropButton('Drop file', async (file, updateVisuals) => {
// try {
// state.file = file;
// updateVisuals(file);
// console.log('Loaded file:', state.file);
// checkReady();
// } catch (err) {
// alert('Failed to drop the file.');
// console.error(err);
// }
// });
const certDropButton = createDropButton('Drop certificate', async (file, updateVisuals) => {
try {
const text = await file.text();
const json = JSON.parse(text);
if (
typeof json === 'object' &&
json !== null &&
typeof json.pcd_commitment === 'object' &&
typeof json.state_id === 'string'
) {
state.certificate = json as ProcessState;
// const certDropButton = createDropButton('Drop certificate', async (file, updateVisuals) => {
// try {
// const text = await file.text();
// const json = JSON.parse(text);
// if (
// typeof json === 'object' &&
// json !== null &&
// typeof json.pcd_commitment === 'object' &&
// typeof json.state_id === 'string'
// ) {
// state.certificate = json as ProcessState;
state.commitmentHashes = Object.values(json.pcd_commitment).map((h: string) =>
h.toLowerCase()
);
// state.commitmentHashes = Object.values(json.pcd_commitment).map((h: string) =>
// h.toLowerCase()
// );
updateVisuals(file);
console.log('Loaded certificate, extracted hashes:', state.commitmentHashes);
checkReady();
} else {
alert('Invalid certificate structure.');
}
} catch (err) {
alert('Failed to parse certificate JSON.');
console.error(err);
}
});
// updateVisuals(file);
// console.log('Loaded certificate, extracted hashes:', state.commitmentHashes);
// checkReady();
// } else {
// alert('Invalid certificate structure.');
// }
// } catch (err) {
// alert('Failed to parse certificate JSON.');
// console.error(err);
// }
// });
const buttonRow = document.createElement('div');
buttonRow.style.display = 'flex';
buttonRow.style.gap = '2rem';
buttonRow.appendChild(fileDropButton);
buttonRow.appendChild(certDropButton);
// const buttonRow = document.createElement('div');
// buttonRow.style.display = 'flex';
// buttonRow.style.gap = '2rem';
// buttonRow.appendChild(fileDropButton);
// buttonRow.appendChild(certDropButton);
container.appendChild(buttonRow);
// container.appendChild(buttonRow);
async function checkReady() {
if (state.file && state.certificate && state.commitmentHashes.length > 0) {
// We take the commited_in and all pcd_commitment keys to reconstruct all the possible hash
const fileBlob = {
type: state.file.type,
data: new Uint8Array(await state.file.arrayBuffer())
};
const service = await Services.getInstance();
const commitedIn = state.certificate.commited_in;
if (!commitedIn) return;
const [prevTxid, prevTxVout] = commitedIn.split(':');
const processId = state.certificate.process_id;
const stateId = state.certificate.state_id;
const process = await service.getProcess(processId);
if (!process) return;
// async function checkReady() {
// if (state.file && state.certificate && state.commitmentHashes.length > 0) {
// // We take the commited_in and all pcd_commitment keys to reconstruct all the possible hash
// const fileBlob = {
// type: state.file.type,
// data: new Uint8Array(await state.file.arrayBuffer())
// };
// const service = await Services.getInstance();
// const commitedIn = state.certificate.commited_in;
// if (!commitedIn) return;
// const [prevTxid, prevTxVout] = commitedIn.split(':');
// const processId = state.certificate.process_id;
// const stateId = state.certificate.state_id;
// const process = await service.getProcess(processId);
// if (!process) return;
// Get the transaction that comes right after the commited_in
const nextState = service.getNextStateAfterId(process, stateId);
// // Get the transaction that comes right after the commited_in
// const nextState = service.getNextStateAfterId(process, stateId);
if (!nextState) {
alert(`❌ Validation failed: No next state, is the state you're trying to validate commited?`);
return;
}
// if (!nextState) {
// alert(`❌ Validation failed: No next state, is the state you're trying to validate commited?`);
// return;
// }
const [outspentTxId, _] = nextState.commited_in.split(':');
console.log(outspentTxId);
// const [outspentTxId, _] = nextState.commited_in.split(':');
// console.log(outspentTxId);
// Check that the commitment transaction exists, and that it commits to the state id
// // Check that the commitment transaction exists, and that it commits to the state id
const txInfo = await fetchTransaction(outspentTxId);
if (!txInfo) {
console.error(`Validation error: Can't fetch new state commitment transaction`);
alert(`❌ Validation failed: invalid or non existent commited_in for state ${stateId}.`);
return;
}
// const txInfo = await fetchTransaction(outspentTxId);
// if (!txInfo) {
// console.error(`Validation error: Can't fetch new state commitment transaction`);
// alert(`❌ Validation failed: invalid or non existent commited_in for state ${stateId}.`);
// return;
// }
// We must check that this transaction indeed spend the commited_in we have in the certificate
let found = false;
for (const vin of txInfo.vin) {
if (vin.txid === prevTxid) {
found = true;
break;
}
}
// // We must check that this transaction indeed spend the commited_in we have in the certificate
// let found = false;
// for (const vin of txInfo.vin) {
// if (vin.txid === prevTxid) {
// found = true;
// break;
// }
// }
if (!found) {
console.error(`Validation error: new state doesn't spend previous state commitment transaction`);
alert('❌ Validation failed: Unconsistent commitment transactions history.');
return;
}
// if (!found) {
// console.error(`Validation error: new state doesn't spend previous state commitment transaction`);
// alert('❌ Validation failed: Unconsistent commitment transactions history.');
// return;
// }
// set found back to false for next check
found = false;
// // set found back to false for next check
// found = false;
// is the state_id commited in the transaction?
for (const vout of txInfo.vout) {
console.log(vout);
if (vout.scriptpubkey_type && vout.scriptpubkey_type === 'op_return') {
found = true;
} else {
continue;
}
// // is the state_id commited in the transaction?
// for (const vout of txInfo.vout) {
// console.log(vout);
// if (vout.scriptpubkey_type && vout.scriptpubkey_type === 'op_return') {
// found = true;
// } else {
// continue;
// }
if (vout.scriptpubkey_asm) {
const hash = extractHexFromScriptAsm(vout.scriptpubkey_asm);
if (hash) {
if (hash !== stateId) {
console.error(`Validation error: expected stateId ${stateId}, got ${hash}`);
alert('❌ Validation failed: Transaction does not commit to that state.');
return;
}
}
}
}
// if (vout.scriptpubkey_asm) {
// const hash = extractHexFromScriptAsm(vout.scriptpubkey_asm);
// if (hash) {
// if (hash !== stateId) {
// console.error(`Validation error: expected stateId ${stateId}, got ${hash}`);
// alert('❌ Validation failed: Transaction does not commit to that state.');
// return;
// }
// }
// }
// }
if (!found) {
alert('❌ Validation failed: Transaction does not contain data.');
return;
}
// if (!found) {
// alert('❌ Validation failed: Transaction does not contain data.');
// return;
// }
// set found back to false for next check
found = false;
// // set found back to false for next check
// found = false;
for (const label of Object.keys(state.certificate.pcd_commitment)) {
// Compute the hash for this label
console.log(`Computing hash with label ${label}`)
const fileHex = service.getHashForFile(commitedIn, label, fileBlob);
console.log(`Found hash ${fileHex}`);
found = state.commitmentHashes.includes(fileHex);
if (found) break;
}
// for (const label of Object.keys(state.certificate.pcd_commitment)) {
// // Compute the hash for this label
// console.log(`Computing hash with label ${label}`)
// const fileHex = service.getHashForFile(commitedIn, label, fileBlob);
// console.log(`Found hash ${fileHex}`);
// found = state.commitmentHashes.includes(fileHex);
// if (found) break;
// }
if (found) {
alert('✅ Validation successful: file hash found in pcd_commitment.');
} else {
alert('❌ Validation failed: file hash NOT found in pcd_commitment.');
}
}
}
// if (found) {
// alert('✅ Validation successful: file hash found in pcd_commitment.');
// } else {
// alert('❌ Validation failed: file hash NOT found in pcd_commitment.');
// }
// }
// }
async function fetchTransaction(txid: string): Promise<TransactionInfo> {
const url = `https://mempool.4nkweb.com/api/tx/${txid}`;
// async function fetchTransaction(txid: string): Promise<TransactionInfo> {
// const url = `https://mempool.4nkweb.com/api/tx/${txid}`;
const response = await fetch(url);
if (!response.ok) {
throw new Error(`Failed to fetch outspend status: ${response.statusText}`);
}
// const response = await fetch(url);
// if (!response.ok) {
// throw new Error(`Failed to fetch outspend status: ${response.statusText}`);
// }
const outspend: TransactionInfo = await response.json();
return outspend;
}
// const outspend: TransactionInfo = await response.json();
// return outspend;
// }
function extractHexFromScriptAsm(scriptAsm: string): string | null {
const parts = scriptAsm.trim().split(/\s+/);
const last = parts[parts.length - 1];
// function extractHexFromScriptAsm(scriptAsm: string): string | null {
// const parts = scriptAsm.trim().split(/\s+/);
// const last = parts[parts.length - 1];
// Basic validation: must be 64-char hex (32 bytes)
if (/^[0-9a-fA-F]{64}$/.test(last)) {
return last.toLowerCase();
}
// // Basic validation: must be 64-char hex (32 bytes)
// if (/^[0-9a-fA-F]{64}$/.test(last)) {
// return last.toLowerCase();
// }
return null;
}
}
// return null;
// }
// }

View File

@ -1,196 +1,196 @@
import { ValidationRule, RoleDefinition } from '../../../pkg/sdk_client';
import { showValidationRuleModal } from '../../components/validation-rule-modal/validation-rule-modal';
// import { ValidationRule, RoleDefinition } from '../../../pkg/sdk_client';
// import { showValidationRuleModal } from '../../components/validation-rule-modal/validation-rule-modal';
export function createKeyValueSection(title: string, id: string, isRoleSection = false) {
const section = document.createElement('div');
section.id = id;
section.style.cssText = 'margin-bottom: 2rem; background: #fff; padding: 1rem; border-radius: 0.5rem; box-shadow: 0 1px 3px rgba(0,0,0,0.1);';
// export function createKeyValueSection(title: string, id: string, isRoleSection = false) {
// const section = document.createElement('div');
// section.id = id;
// section.style.cssText = 'margin-bottom: 2rem; background: #fff; padding: 1rem; border-radius: 0.5rem; box-shadow: 0 1px 3px rgba(0,0,0,0.1);';
const titleEl = document.createElement('h2');
titleEl.textContent = title;
titleEl.style.cssText = 'font-size: 1.25rem; font-weight: bold; margin-bottom: 1rem;';
section.appendChild(titleEl);
// const titleEl = document.createElement('h2');
// titleEl.textContent = title;
// titleEl.style.cssText = 'font-size: 1.25rem; font-weight: bold; margin-bottom: 1rem;';
// section.appendChild(titleEl);
const rowContainer = document.createElement('div');
section.appendChild(rowContainer);
// const rowContainer = document.createElement('div');
// section.appendChild(rowContainer);
const addBtn = document.createElement('button');
addBtn.textContent = '+ Add Row';
addBtn.style.cssText = `
margin-top: 1rem;
padding: 0.5rem 1rem;
border: 1px solid #888;
border-radius: 0.375rem;
background-color: #f9f9f9;
cursor: pointer;
`;
section.appendChild(addBtn);
// const addBtn = document.createElement('button');
// addBtn.textContent = '+ Add Row';
// addBtn.style.cssText = `
// margin-top: 1rem;
// padding: 0.5rem 1rem;
// border: 1px solid #888;
// border-radius: 0.375rem;
// background-color: #f9f9f9;
// cursor: pointer;
// `;
// section.appendChild(addBtn);
const roleRowStates: {
roleNameInput: HTMLInputElement;
membersInput: HTMLInputElement;
storagesInput: HTMLInputElement;
validationRules: ValidationRule[];
}[] = [];
type fileBlob = {
type: string,
data: Uint8Array
};
const nonRoleRowStates: {
keyInput: HTMLInputElement,
valueInput: HTMLInputElement,
fileInput: HTMLInputElement,
fileBlob: fileBlob | null
}[] = [];
// const roleRowStates: {
// roleNameInput: HTMLInputElement;
// membersInput: HTMLInputElement;
// storagesInput: HTMLInputElement;
// validationRules: ValidationRule[];
// }[] = [];
// type fileBlob = {
// type: string,
// data: Uint8Array
// };
// const nonRoleRowStates: {
// keyInput: HTMLInputElement,
// valueInput: HTMLInputElement,
// fileInput: HTMLInputElement,
// fileBlob: fileBlob | null
// }[] = [];
const inputStyle = 'flex: 1; height: 2.5rem; padding: 0.5rem; border: 1px solid #ccc; border-radius: 0.375rem;';
// const inputStyle = 'flex: 1; height: 2.5rem; padding: 0.5rem; border: 1px solid #ccc; border-radius: 0.375rem;';
const createRow = () => {
const row = document.createElement('div');
row.style.cssText = 'display: flex; gap: 1rem; margin-bottom: 0.5rem; align-items: center;';
// const createRow = () => {
// const row = document.createElement('div');
// row.style.cssText = 'display: flex; gap: 1rem; margin-bottom: 0.5rem; align-items: center;';
const deleteBtn = document.createElement('button');
deleteBtn.textContent = '🗑️';
deleteBtn.style.cssText = 'background: none; border: none; font-size: 1.2rem; cursor: pointer;';
deleteBtn.onclick = () => {
row.remove();
updateDeleteButtons();
};
// const deleteBtn = document.createElement('button');
// deleteBtn.textContent = '🗑️';
// deleteBtn.style.cssText = 'background: none; border: none; font-size: 1.2rem; cursor: pointer;';
// deleteBtn.onclick = () => {
// row.remove();
// updateDeleteButtons();
// };
if (isRoleSection) {
const roleName = document.createElement('input');
const members = document.createElement('input');
const storages = document.createElement('input');
// if (isRoleSection) {
// const roleName = document.createElement('input');
// const members = document.createElement('input');
// const storages = document.createElement('input');
roleName.placeholder = 'Role name';
members.placeholder = 'members';
storages.placeholder = 'storages';
[roleName, members, storages].forEach(input => {
input.type = 'text';
input.style.cssText = inputStyle;
});
// roleName.placeholder = 'Role name';
// members.placeholder = 'members';
// storages.placeholder = 'storages';
// [roleName, members, storages].forEach(input => {
// input.type = 'text';
// input.style.cssText = inputStyle;
// });
const ruleButton = document.createElement('button');
ruleButton.textContent = 'Add Validation Rule';
ruleButton.style.cssText = 'padding: 0.3rem 0.75rem; border: 1px solid #ccc; border-radius: 0.375rem; background: #f0f0f0; cursor: pointer;';
// const ruleButton = document.createElement('button');
// ruleButton.textContent = 'Add Validation Rule';
// ruleButton.style.cssText = 'padding: 0.3rem 0.75rem; border: 1px solid #ccc; border-radius: 0.375rem; background: #f0f0f0; cursor: pointer;';
const rules: ValidationRule[] = [];
ruleButton.onclick = () => {
showValidationRuleModal(rule => {
rules.push(rule);
ruleButton.textContent = `Rules (${rules.length})`;
});
};
// const rules: ValidationRule[] = [];
// ruleButton.onclick = () => {
// showValidationRuleModal(rule => {
// rules.push(rule);
// ruleButton.textContent = `Rules (${rules.length})`;
// });
// };
row.appendChild(roleName);
row.appendChild(members);
row.appendChild(storages);
row.appendChild(ruleButton);
row.appendChild(deleteBtn);
// row.appendChild(roleName);
// row.appendChild(members);
// row.appendChild(storages);
// row.appendChild(ruleButton);
// row.appendChild(deleteBtn);
roleRowStates.push({ roleNameInput: roleName, membersInput: members, storagesInput: storages, validationRules: rules });
} else {
const fileInput = document.createElement('input');
fileInput.type = 'file';
fileInput.style.display = 'none';
fileInput.onchange = async () => {
const file = fileInput.files?.[0];
if (!file) return;
// roleRowStates.push({ roleNameInput: roleName, membersInput: members, storagesInput: storages, validationRules: rules });
// } else {
// const fileInput = document.createElement('input');
// fileInput.type = 'file';
// fileInput.style.display = 'none';
// fileInput.onchange = async () => {
// const file = fileInput.files?.[0];
// if (!file) return;
const buffer = await file.arrayBuffer();
const uint8 = new Uint8Array(buffer);
// const buffer = await file.arrayBuffer();
// const uint8 = new Uint8Array(buffer);
rowState.fileBlob = {
type: file.type,
data: uint8,
};
// rowState.fileBlob = {
// type: file.type,
// data: uint8,
// };
valueInput.value = `📄 ${file.name}`;
valueInput.disabled = true;
attachBtn.textContent = `📎 ${file.name}`;
};
// valueInput.value = `📄 ${file.name}`;
// valueInput.disabled = true;
// attachBtn.textContent = `📎 ${file.name}`;
// };
const attachBtn = document.createElement('button');
attachBtn.textContent = '📎 Attach';
attachBtn.style.cssText = 'padding: 0.3rem 0.75rem; border: 1px solid #ccc; border-radius: 0.375rem; background: #f0f0f0; cursor: pointer;';
attachBtn.onclick = () => fileInput.click();
// const attachBtn = document.createElement('button');
// attachBtn.textContent = '📎 Attach';
// attachBtn.style.cssText = 'padding: 0.3rem 0.75rem; border: 1px solid #ccc; border-radius: 0.375rem; background: #f0f0f0; cursor: pointer;';
// attachBtn.onclick = () => fileInput.click();
const keyInput = document.createElement('input');
const valueInput = document.createElement('input');
// const keyInput = document.createElement('input');
// const valueInput = document.createElement('input');
const rowState = {
keyInput,
valueInput,
fileInput,
fileBlob: null as fileBlob | null
};
nonRoleRowStates.push(rowState);
// const rowState = {
// keyInput,
// valueInput,
// fileInput,
// fileBlob: null as fileBlob | null
// };
// nonRoleRowStates.push(rowState);
keyInput.placeholder = 'Key';
valueInput.placeholder = 'Value';
[keyInput, valueInput].forEach(input => {
input.type = 'text';
input.style.cssText = inputStyle;
});
// keyInput.placeholder = 'Key';
// valueInput.placeholder = 'Value';
// [keyInput, valueInput].forEach(input => {
// input.type = 'text';
// input.style.cssText = inputStyle;
// });
row.appendChild(keyInput);
row.appendChild(valueInput);
// row.appendChild(keyInput);
// row.appendChild(valueInput);
row.appendChild(attachBtn);
row.appendChild(fileInput);
// row.appendChild(attachBtn);
// row.appendChild(fileInput);
row.appendChild(deleteBtn);
}
// row.appendChild(deleteBtn);
// }
rowContainer.appendChild(row);
updateDeleteButtons();
};
// rowContainer.appendChild(row);
// updateDeleteButtons();
// };
const updateDeleteButtons = () => {
const rows = Array.from(rowContainer.children);
rows.forEach(row => {
const btn = row.querySelector('button:last-child') as HTMLButtonElement;
if (rows.length === 1) {
btn.disabled = true;
btn.style.visibility = 'hidden';
} else {
btn.disabled = false;
btn.style.visibility = 'visible';
}
});
};
// const updateDeleteButtons = () => {
// const rows = Array.from(rowContainer.children);
// rows.forEach(row => {
// const btn = row.querySelector('button:last-child') as HTMLButtonElement;
// if (rows.length === 1) {
// btn.disabled = true;
// btn.style.visibility = 'hidden';
// } else {
// btn.disabled = false;
// btn.style.visibility = 'visible';
// }
// });
// };
createRow();
addBtn.addEventListener('click', createRow);
// createRow();
// addBtn.addEventListener('click', createRow);
return {
element: section,
getData: () => {
if (isRoleSection) {
const data: Record<string, RoleDefinition> = {};
for (const row of roleRowStates) {
const key = row.roleNameInput.value.trim();
if (!key) continue;
data[key] = {
members: row.membersInput.value.split(',').map(x => x.trim()).filter(Boolean),
storages: row.storagesInput.value.split(',').map(x => x.trim()).filter(Boolean),
validation_rules: row.validationRules
};
}
return data;
} else {
const data: Record<string, string | fileBlob> = {};
for (const row of nonRoleRowStates) {
const key = row.keyInput.value.trim();
if (!key) continue;
if (row.fileBlob) {
data[key] = row.fileBlob;
} else {
data[key] = row.valueInput.value.trim();
}
}
return data;
}
}
};
}
// return {
// element: section,
// getData: () => {
// if (isRoleSection) {
// const data: Record<string, RoleDefinition> = {};
// for (const row of roleRowStates) {
// const key = row.roleNameInput.value.trim();
// if (!key) continue;
// data[key] = {
// members: row.membersInput.value.split(',').map(x => x.trim()).filter(Boolean),
// storages: row.storagesInput.value.split(',').map(x => x.trim()).filter(Boolean),
// validation_rules: row.validationRules
// };
// }
// return data;
// } else {
// const data: Record<string, string | fileBlob> = {};
// for (const row of nonRoleRowStates) {
// const key = row.keyInput.value.trim();
// if (!key) continue;
// if (row.fileBlob) {
// data[key] = row.fileBlob;
// } else {
// data[key] = row.valueInput.value.trim();
// }
// }
// return data;
// }
// }
// };
// }

View File

@ -1,91 +1,91 @@
import { createKeyValueSection } from './key-value-section';
import { loadValidationRuleModal } from '../../components/validation-rule-modal/validation-rule-modal';
import Services from '../../services/service';
import { RoleDefinition } from '../../../pkg/sdk_client';
// import { createKeyValueSection } from './key-value-section';
// import { loadValidationRuleModal } from '../../components/validation-rule-modal/validation-rule-modal';
// import Services from '../../services/service';
// import { RoleDefinition } from '../../../pkg/sdk_client';
export async function getProcessCreation(container: HTMLElement) {
await loadValidationRuleModal();
// export async function getProcessCreation(container: HTMLElement) {
// await loadValidationRuleModal();
container.style.display = 'block';
container.innerHTML = `<div class="parameter-header">Process Creation</div>`;
const privateSec = createKeyValueSection('Private Data', 'private-section');
const publicSec = createKeyValueSection('Public Data', 'public-section');
const rolesSec = createKeyValueSection('Roles', 'roles-section', true);
// container.style.display = 'block';
// container.innerHTML = `<div class="parameter-header">Process Creation</div>`;
// const privateSec = createKeyValueSection('Private Data', 'private-section');
// const publicSec = createKeyValueSection('Public Data', 'public-section');
// const rolesSec = createKeyValueSection('Roles', 'roles-section', true);
container.appendChild(privateSec.element);
container.appendChild(publicSec.element);
container.appendChild(rolesSec.element);
// container.appendChild(privateSec.element);
// container.appendChild(publicSec.element);
// container.appendChild(rolesSec.element);
const btn = document.createElement('button');
btn.textContent = 'Create Process';
btn.style.cssText = `
display: block;
margin: 2rem auto 0;
padding: 0.75rem 2rem;
font-size: 1rem;
font-weight: bold;
background-color: #4f46e5;
color: white;
border: none;
border-radius: 0.5rem;
cursor: pointer;
`;
// const btn = document.createElement('button');
// btn.textContent = 'Create Process';
// btn.style.cssText = `
// display: block;
// margin: 2rem auto 0;
// padding: 0.75rem 2rem;
// font-size: 1rem;
// font-weight: bold;
// background-color: #4f46e5;
// color: white;
// border: none;
// border-radius: 0.5rem;
// cursor: pointer;
// `;
btn.onclick = async () => {
const privateData = privateSec.getData();
const publicData = publicSec.getData();
const roles = rolesSec.getData() as Record<string, RoleDefinition>;
// btn.onclick = async () => {
// const privateData = privateSec.getData();
// const publicData = publicSec.getData();
// const roles = rolesSec.getData() as Record<string, RoleDefinition>;
console.log('Private:', privateData);
console.log('Public:', publicData);
console.log('Roles:', roles);
// console.log('Private:', privateData);
// console.log('Public:', publicData);
// console.log('Roles:', roles);
const service = await Services.getInstance();
// const service = await Services.getInstance();
const createProcessResult = await service.createProcess(privateData, publicData, roles);
const processId = createProcessResult.updated_process!.process_id;
const stateId = createProcessResult.updated_process!.current_process.states[0].state_id;
await service.handleApiReturn(createProcessResult);
// const createProcessResult = await service.createProcess(privateData, publicData, roles);
// const processId = createProcessResult.updated_process!.process_id;
// const stateId = createProcessResult.updated_process!.current_process.states[0].state_id;
// await service.handleApiReturn(createProcessResult);
// Now we want to validate the update and register the first state of our new process
const updateProcessResult = await service.createPrdUpdate(processId, stateId);
await service.handleApiReturn(createProcessResult);
// // Now we want to validate the update and register the first state of our new process
// const updateProcessResult = await service.createPrdUpdate(processId, stateId);
// await service.handleApiReturn(createProcessResult);
const approveChangeResult = await service.approveChange(processId, stateId);
await service.handleApiReturn(approveChangeResult);
if (approveChangeResult) {
const process = await service.getProcess(processId);
let newState = service.getStateFromId(process, stateId);
if (!newState) return;
for (const label of Object.keys(newState.keys)) {
const hash = newState.pcd_commitment[label];
const encryptedData = await service.getBlobFromDb(hash);
const filename = `${label}-${hash.slice(0,8)}.bin`;
// const approveChangeResult = await service.approveChange(processId, stateId);
// await service.handleApiReturn(approveChangeResult);
// if (approveChangeResult) {
// const process = await service.getProcess(processId);
// let newState = service.getStateFromId(process, stateId);
// if (!newState) return;
// for (const label of Object.keys(newState.keys)) {
// const hash = newState.pcd_commitment[label];
// const encryptedData = await service.getBlobFromDb(hash);
// const filename = `${label}-${hash.slice(0,8)}.bin`;
const blob = new Blob([encryptedData], { type: "application/octet-stream" });
const link = document.createElement("a");
link.href = URL.createObjectURL(blob);
link.download = filename;
link.click();
// const blob = new Blob([encryptedData], { type: "application/octet-stream" });
// const link = document.createElement("a");
// link.href = URL.createObjectURL(blob);
// link.download = filename;
// link.click();
setTimeout(() => URL.revokeObjectURL(link.href), 1000);
}
// setTimeout(() => URL.revokeObjectURL(link.href), 1000);
// }
await service.generateProcessPdf(processId, newState);
// await service.generateProcessPdf(processId, newState);
// Add processId to the state we export
newState['process_id'] = processId;
const blob = new Blob([JSON.stringify(newState, null, 2)], { type: 'application/json' });
const url = URL.createObjectURL(blob);
// // Add processId to the state we export
// newState['process_id'] = processId;
// const blob = new Blob([JSON.stringify(newState, null, 2)], { type: 'application/json' });
// const url = URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = `process_${processId}_${stateId}.json`;
a.click();
// const a = document.createElement('a');
// a.href = url;
// a.download = `process_${processId}_${stateId}.json`;
// a.click();
URL.revokeObjectURL(url); // Clean up
}
};
// URL.revokeObjectURL(url); // Clean up
// }
// };
container.appendChild(btn);
}
// container.appendChild(btn);
// }

View File

@ -1,66 +1,66 @@
export function createProcessTab(container: HTMLElement, processes: { name: string, publicData: Record<string, any> }[]): HTMLElement {
container.id = 'process-tab';
container.style.display = 'block';
container.style.cssText = 'padding: 1.5rem;';
// export function createProcessTab(container: HTMLElement, processes: { name: string, publicData: Record<string, any> }[]): HTMLElement {
// container.id = 'process-tab';
// container.style.display = 'block';
// container.style.cssText = 'padding: 1.5rem;';
const title = document.createElement('h2');
title.textContent = 'Processes';
title.style.cssText = 'font-size: 1.5rem; font-weight: bold; margin-bottom: 1rem;';
container.appendChild(title);
// const title = document.createElement('h2');
// title.textContent = 'Processes';
// title.style.cssText = 'font-size: 1.5rem; font-weight: bold; margin-bottom: 1rem;';
// container.appendChild(title);
processes.forEach(proc => {
const card = document.createElement('div');
card.style.cssText = 'margin-bottom: 1rem; padding: 1rem; border: 1px solid #ddd; border-radius: 0.5rem; background: #fff;';
// processes.forEach(proc => {
// const card = document.createElement('div');
// card.style.cssText = 'margin-bottom: 1rem; padding: 1rem; border: 1px solid #ddd; border-radius: 0.5rem; background: #fff;';
const nameEl = document.createElement('h3');
nameEl.textContent = proc.name;
nameEl.style.cssText = 'font-size: 1.2rem; font-weight: bold; margin-bottom: 0.5rem;';
card.appendChild(nameEl);
// const nameEl = document.createElement('h3');
// nameEl.textContent = proc.name;
// nameEl.style.cssText = 'font-size: 1.2rem; font-weight: bold; margin-bottom: 0.5rem;';
// card.appendChild(nameEl);
const dataList = document.createElement('div');
for (const [key, value] of Object.entries(proc.publicData)) {
const item = document.createElement('div');
item.style.cssText = 'margin-bottom: 0.5rem;';
// const dataList = document.createElement('div');
// for (const [key, value] of Object.entries(proc.publicData)) {
// const item = document.createElement('div');
// item.style.cssText = 'margin-bottom: 0.5rem;';
const label = document.createElement('strong');
label.textContent = key + ': ';
item.appendChild(label);
// const label = document.createElement('strong');
// label.textContent = key + ': ';
// item.appendChild(label);
// Let's trim the quotes
const trimmed = value.replace(/^'|'$/g, '');
let parsed;
try {
parsed = JSON.parse(trimmed);
} catch (_) {
parsed = trimmed;
}
// // Let's trim the quotes
// const trimmed = value.replace(/^'|'$/g, '');
// let parsed;
// try {
// parsed = JSON.parse(trimmed);
// } catch (_) {
// parsed = trimmed;
// }
if (parsed && typeof parsed === 'object') {
const saveBtn = document.createElement('button');
saveBtn.textContent = '💾 Save as JSON';
saveBtn.style.cssText = 'margin-left: 0.5rem; padding: 0.25rem 0.5rem; border: 1px solid #ccc; border-radius: 0.375rem; background: #f0f0f0; cursor: pointer;';
saveBtn.onclick = () => {
const blob = new Blob([JSON.stringify(parsed, null, 2)], { type: 'application/json' });
const url = URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = `${proc.name}_${key}.json`;
a.click();
URL.revokeObjectURL(url);
};
item.appendChild(saveBtn);
} else {
const span = document.createElement('span');
span.textContent = String(parsed);
item.appendChild(span);
}
// if (parsed && typeof parsed === 'object') {
// const saveBtn = document.createElement('button');
// saveBtn.textContent = '💾 Save as JSON';
// saveBtn.style.cssText = 'margin-left: 0.5rem; padding: 0.25rem 0.5rem; border: 1px solid #ccc; border-radius: 0.375rem; background: #f0f0f0; cursor: pointer;';
// saveBtn.onclick = () => {
// const blob = new Blob([JSON.stringify(parsed, null, 2)], { type: 'application/json' });
// const url = URL.createObjectURL(blob);
// const a = document.createElement('a');
// a.href = url;
// a.download = `${proc.name}_${key}.json`;
// a.click();
// URL.revokeObjectURL(url);
// };
// item.appendChild(saveBtn);
// } else {
// const span = document.createElement('span');
// span.textContent = String(parsed);
// item.appendChild(span);
// }
dataList.appendChild(item);
}
// dataList.appendChild(item);
// }
card.appendChild(dataList);
container.appendChild(card);
});
// card.appendChild(dataList);
// container.appendChild(card);
// });
return container;
}
// return container;
// }