تحديث المشاريع
يُرجى تعبئة التفاصيل التالية حول المبادرة، المسؤوليات، والفترة الزمنية.
يتم استخدام هذه البيانات لمتابعة الأداء في لوحة المؤشرات.
// === 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;
}
});