/home/techb158/trello.abdallabala.com/public
Edit: /home/techb158/trello.abdallabala.com/public/risk-modal.js (4656B)
import { apiFetch, canWriteCard, escapeHtml, powerUpOptions, statusClass } from './client-utils.js';
const t = window.TrelloPowerUp.iframe(powerUpOptions());
const form = document.getElementById('risk-form');
const result = document.getElementById('result');
const closeBtn = document.getElementById('close');
const checklistBtn = document.getElementById('create-checklist');
function numberValue(id) {
return Number(document.getElementById(id).value);
}
function textValue(id) {
return document.getElementById(id).value.trim();
}
function selectValue(id) {
return document.getElementById(id).value;
}
function checked(id) {
return document.getElementById(id).checked;
}
function buildPayload() {
return {
projectTypology: selectValue('projectTypology'),
lifecyclePhase: selectValue('lifecyclePhase'),
measurementMaturity: selectValue('measurementMaturity'),
approvalState: selectValue('approvalState'),
metrics: {
modelPerformanceScore: numberValue('modelPerformanceScore'),
dataReadinessScore: numberValue('dataReadinessScore'),
ethicalReviewCompleted: checked('ethicalReviewCompleted'),
legalReviewCompleted: checked('legalReviewCompleted')
},
risks: [{
title: textValue('title'),
dimension: selectValue('dimension'),
category: selectValue('category'),
lifecyclePhase: selectValue('lifecyclePhase'),
probability: numberValue('probability'),
impact: numberValue('impact'),
detectionDifficulty: numberValue('detectionDifficulty'),
mitigationCompleteness: numberValue('mitigationCompleteness'),
mitigation: textValue('mitigation'),
approvalState: selectValue('approvalState')
}]
};
}
function renderScore(score) {
const reasons = score.gate?.blockingReasons || [];
result.hidden = false;
result.innerHTML = `
${score.score}
${escapeHtml(score.status)}
${score.gate?.deploymentReady ? 'Gate ready' : 'Gate blocked'}
${escapeHtml(score.interpretation)}
${reasons.length ? `
${reasons.map((reason) => `- ${escapeHtml(reason)}
`).join('')}
` : ''}
`;
}
async function saveRisk(event) {
event.preventDefault();
const writable = await canWriteCard(t);
if (!writable) throw new Error('You do not have permission to write to this card.');
const payload = buildPayload();
const card = await t.card('id', 'name');
const board = await t.board('id', 'name');
const assessment = await apiFetch(t, `/api/boards/${board.id}/cards/${card.id}/assessments`, {
method: 'POST',
body: JSON.stringify(payload)
});
await t.set('card', 'shared', 'cosmicRisk', assessment.score);
await t.set('card', 'shared', 'cosmicRiskAssessmentId', assessment.id);
renderScore(assessment.score);
}
async function createMitigationChecklist() {
const writable = await canWriteCard(t);
if (!writable) throw new Error('You do not have permission to write to this card.');
const restApi = t.getRestApi();
const authorized = await restApi.isAuthorized();
if (!authorized) {
await restApi.authorize({ scope: 'read,write' });
}
const token = await restApi.getToken();
const context = await t.getContext();
const key = window.COSMIC_TRELLO_API_KEY || 'replace_with_power_up_api_key';
const checklistResponse = await fetch(`https://api.trello.com/1/cards/${context.card}/checklists?key=${key}&token=${token}`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ name: 'COSMIC Risk Mitigation' })
});
const checklist = await checklistResponse.json();
const items = [
'Define mitigation owner',
'Attach evidence for data readiness',
'Attach model performance evaluation',
'Complete ethical review',
'Complete legal review',
'Record residual risk approval'
];
for (const name of items) {
await fetch(`https://api.trello.com/1/checklists/${checklist.id}/checkItems?key=${key}&token=${token}`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ name })
});
}
alert('Mitigation checklist created.');
}
form.addEventListener('submit', (event) => saveRisk(event).catch((error) => alert(error.message)));
checklistBtn.addEventListener('click', () => createMitigationChecklist().catch((error) => alert(error.message)));
closeBtn.addEventListener('click', () => t.closeModal());
t.render(() => Promise.resolve());