منصة الخطة الإستراتيجية إدارة المبادرات والمؤشرات

تحديث المشاريع

يُرجى تعبئة التفاصيل التالية حول المبادرة، المسؤوليات، والفترة الزمنية. يتم استخدام هذه البيانات لمتابعة الأداء في لوحة المؤشرات.

// === Event Hub config (demo use) === const eventHubNameSpace = "esehdmck61ls47yj1x9ari"; const eventHubName = "es_f8d6f8b6-d4bf-45cd-936b-0db0f95bacf0"; const keyName = "key_40c79d66-92c7-4d4f-8ea0-bd308c4dc596"; const key = "2uPjGD8h/zJQGOgSk4GoHBQtNees5h+3p+AEhLbZtxo="; function generateSasToken(namespace, hub, keyName, key) { const expireSecondsFromNow = 60 * 60 * 24 * 7; // 1 week const expiry = Math.floor(Date.now() / 1000) + expireSecondsFromNow; const resourceUri = encodeURIComponent( "https://" + namespace + ".servicebus.windows.net/" + hub ); const stringToSign = resourceUri + "\n" + expiry; const enc = new TextEncoder(); const keyBytes = enc.encode(key); const dataBytes = enc.encode(stringToSign); return crypto.subtle .importKey( "raw", keyBytes, { name: "HMAC", hash: "SHA-256" }, false, ["sign"] ) .then(cryptoKey => crypto.subtle.sign("HMAC", cryptoKey, dataBytes)) .then(sigBuffer => { const sigArray = Array.from(new Uint8Array(sigBuffer)); const base64Sig = btoa(String.fromCharCode.apply(null, sigArray)); const encodedSig = encodeURIComponent(base64Sig); return ( "SharedAccessSignature sr=" + resourceUri + "&sig=" + encodedSig + "&se=" + expiry + "&skn=" + keyName ); }); } async function sendToEventHub(payloadObj) { const sasToken = await generateSasToken( eventHubNameSpace, eventHubName, keyName, key ); const url = "https://" + eventHubNameSpace + ".servicebus.windows.net/" + eventHubName + "/messages"; const res = await fetch(url, { method: "POST", headers: { Authorization: sasToken, "Content-Type": "application/json" }, body: JSON.stringify(payloadObj) }); return { status: res.status, text: await res.text() }; } const formEl = document.getElementById("progressForm"); const statusBox = document.getElementById("statusBox"); formEl.addEventListener("submit", async (e) => { e.preventDefault(); // If user didn't enter EndDate, we generate an ISO timestamp now let endDateVal = document.getElementById("EndDate").value; if (!endDateVal) { endDateVal = new Date().toISOString(); } // Build payload to match EXACTLY the schema column names const data = { RowID: document.getElementById("RowID").value ? parseInt(document.getElementById("RowID").value, 10) : null, Sector: document.getElementById("Sector").value.trim(), DirectorateOrInstitute: document.getElementById("DirectorateOrInstitute").value.trim(), Department: document.getElementById("Department").value.trim(), Others: document.getElementById("Others").value.trim(), StrategicGoal: document.getElementById("StrategicGoal").value.trim(), ProjectName: document.getElementById("ProjectName").value.trim(), OperationalObjective: document.getElementById("OperationalObjective").value.trim(), RelativeWeight: document.getElementById("RelativeWeight").value.trim(), PrimaryResponsible: document.getElementById("PrimaryResponsible").value.trim(), SecondaryResponsible: document.getElementById("SecondaryResponsible").value.trim(), SupportingEntity: document.getElementById("SupportingEntity").value.trim(), ExpectedRisks: document.getElementById("ExpectedRisks").value.trim(), TargetGrowthIndicator: document.getElementById("TargetGrowthIndicator").value.trim(), ProgressNotes: document.getElementById("ProgressNotes").value.trim(), Deliverables: document.getElementById("Deliverables").value.trim(), SuccessCriteria: document.getElementById("SuccessCriteria").value.trim(), StartDate: document.getElementById("StartDate").value, EndDate: endDateVal }; statusBox.style.display = "block"; statusBox.className = "status-box"; statusBox.textContent = "جاري الإرسال...\n"; try { const result = await sendToEventHub(data); if (result.status >= 200 && result.status < 300) { statusBox.classList.add("status-success"); statusBox.textContent = "✔ تم الإرسال بنجاح\nStatus: " + result.status + "\nResponse:\n" + result.text; formEl.reset(); } else { statusBox.classList.add("status-error"); statusBox.textContent = "✘ فشل الإرسال\nStatus: " + result.status + "\nResponse:\n" + result.text; } } catch (err) { statusBox.classList.add("status-error"); statusBox.textContent = "✘ حدث خطأ أثناء الإرسال:\n" + err; } });