diff --git a/src/pages/account/key-value-section.ts b/src/pages/account/key-value-section.ts new file mode 100644 index 0000000..9a8d35e --- /dev/null +++ b/src/pages/account/key-value-section.ts @@ -0,0 +1,145 @@ +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);'; + + 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 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[]; + }[] = []; + + 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 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'); + + 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 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); + + roleRowStates.push({ roleNameInput: roleName, membersInput: members, storagesInput: storages, validationRules: rules }); + } else { + const keyInput = document.createElement('input'); + const valueInput = document.createElement('input'); + 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(deleteBtn); + } + + 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'; + } + }); + }; + + createRow(); + addBtn.addEventListener('click', createRow); + + return { + element: section, + getData: () => { + if (isRoleSection) { + const data: Record = {}; + 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 = {}; + rowContainer.querySelectorAll('div').forEach(row => { + const inputs = row.querySelectorAll('input'); + const k = inputs[0]?.value.trim(); + const v = inputs[1]?.value.trim(); + if (k) data[k] = v; + }); + return data; + } + } + }; +} diff --git a/src/pages/account/process-creation.ts b/src/pages/account/process-creation.ts new file mode 100644 index 0000000..fb41220 --- /dev/null +++ b/src/pages/account/process-creation.ts @@ -0,0 +1,58 @@ +import { createKeyValueSection } from './key-value-section'; +import { loadValidationRuleModal } from '../../components/validation-rule-modal/validation-rule-modal'; +import Services from '../../services/service'; + +export async function getProcessCreation(container: HTMLElement) { + await loadValidationRuleModal(); + + container.style.display = 'block'; + container.innerHTML = `
Process Creation
`; + 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); + + 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(); + + console.log('Private:', privateData); + console.log('Public:', publicData); + console.log('Roles:', roles); + + 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); + + // 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); + }; + + container.appendChild(btn); +}