stat2025 commited on
Commit
db69a0c
·
verified ·
1 Parent(s): bfc1c58

Upload 6 files

Browse files
Files changed (2) hide show
  1. script.js +8 -4
  2. style.css +4 -0
script.js CHANGED
@@ -116,6 +116,10 @@ async function loadData() {
116
 
117
  function escapeHtml(v) { return String(v ?? "").replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;").replace(/'/g, "&#39;"); }
118
  function td(label, content) { return `<td data-label="${escapeHtml(label)}">${content}</td>`; }
 
 
 
 
119
  function metric(value, label, target = "", description = "") {
120
  const action = target ? ` role="button" tabindex="0" data-dashboard-detail="${target}"` : "";
121
  const note = description ? `<small>${escapeHtml(description)}</small>` : "";
@@ -252,7 +256,7 @@ function renderDashboardDetail(type) {
252
  .sort((a, b) => a.surveyName.localeCompare(b.surveyName, "ar"))
253
  .map((row) => `${row.surveyName}: ${row.collectionStatus || "-"}`);
254
  const count = new Set(group.rows.map((row) => plain(row.collectionStatus)).filter(Boolean)).size;
255
- return `<tr>${td("السجل التجاري", `<button class="row-button" data-entity="${escapeHtml(group.key)}">${escapeHtml(group.commercialRegister)}</button>`)}${td("اسم المنشأة", escapeHtml(group.name))}${td("الحالات حسب المسح", escapeHtml(statuses.join(" | ")))}${td("عدد الحالات", count)}</tr>`;
256
  }).join("")}</tbody></table></div>`;
257
  } else if (type === "researchers") {
258
  const researchers = [...countBy(sharedRows, (row) => row.researcher).entries()].sort((a, b) => b[1] - a[1]).slice(0, 20);
@@ -263,7 +267,7 @@ function renderDashboardDetail(type) {
263
  const title = type === "establishments" ? "المنشآت المتقاطعة" : "تفاصيل التقاطعات";
264
  const subtitle = "السجلات التجارية التي ظهرت في أكثر من مسح.";
265
  panel.innerHTML = `${dashboardDetailHeader(title, subtitle)}
266
- <div class="table-wrap"><table><thead><tr><th>السجل التجاري</th><th>اسم المنشأة</th><th>عدد المسوح</th><th>المسوح</th><th>الباحثون</th></tr></thead><tbody>${filtered.slice(0, 50).map((group) => `<tr>${td("السجل التجاري", `<button class="row-button" data-entity="${escapeHtml(group.key)}">${escapeHtml(group.commercialRegister)}</button>`)}${td("اسم المنشأة", escapeHtml(group.name))}${td("عدد المسوح", group.surveys.length)}${td("المسوح", escapeHtml(group.surveys.join("، ")))}${td("الباحثون", escapeHtml(group.researchers.join("، ")))}</tr>`).join("")}</tbody></table></div>`;
267
  }
268
 
269
  panel.scrollIntoView({ behavior: "smooth", block: "start" });
@@ -375,11 +379,11 @@ function renderIntersections() {
375
  const three = groups.filter((group) => group.surveys.length >= 3).length;
376
  $("intersectionMetrics").innerHTML = [metric(groups.length, "منشآت مشتركة"), metric(two, "في مسحين"), metric(three, "في 3 مسوح أو أكثر"), metric(app.byRegister.size, "سجلات قابلة للمطابقة"), metric(app.surveys.size, "إجمالي المسوح")].join("");
377
  $("intersectionResults").className = "results";
378
- $("intersectionResults").innerHTML = groups.length ? `<div class="table-wrap"><table><thead><tr><th>السجل التجاري</th><th>اسم المنشأة</th><th>عدد المسوح</th><th>المسوح</th><th>الباحثون</th></tr></thead><tbody>${groups.slice(0, 200).map((group) => `<tr>${td("السجل التجاري", `<button class="row-button" data-entity="${escapeHtml(group.key)}">${escapeHtml(group.commercialRegister)}</button>`)}${td("اسم المنشأة", escapeHtml(group.name))}${td("عدد المسوح", group.surveys.length)}${td("المسوح", escapeHtml(group.surveys.join("، ")))}${td("الباحثون", escapeHtml(group.researchers.join("، ")))}</tr>`).join("")}</tbody></table></div>` : "<div class='empty-state'>لا توجد تقاطعات قابلة للحساب.</div>";
379
  }
380
 
381
  function renderCompactEntities(groups) {
382
- return `<div class="table-wrap compact-table"><table><thead><tr><th>السجل التجاري</th><th>اسم المنشأة</th><th>المسوح</th><th>الباحثون</th></tr></thead><tbody>${groups.map((group) => `<tr>${td("السجل التجاري", `<button class="row-button" data-entity="${escapeHtml(group.key)}">${escapeHtml(group.commercialRegister || "-")}</button>`)}${td("اسم المنشأة", escapeHtml(group.name))}${td("المسوح", escapeHtml(group.surveys.join("، ")))}${td("الباحثون", escapeHtml(group.researchers.join("، ")))}</tr>`).join("")}</tbody></table></div>`;
383
  }
384
 
385
  function renderResearchers() {
 
116
 
117
  function escapeHtml(v) { return String(v ?? "").replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;").replace(/'/g, "&#39;"); }
118
  function td(label, content) { return `<td data-label="${escapeHtml(label)}">${content}</td>`; }
119
+ function stackedList(items) {
120
+ const clean = items.map((item) => plain(item)).filter(Boolean);
121
+ return clean.length ? `<div class="stacked-list">${clean.map((item) => `<span>${escapeHtml(item)}</span>`).join("")}</div>` : "-";
122
+ }
123
  function metric(value, label, target = "", description = "") {
124
  const action = target ? ` role="button" tabindex="0" data-dashboard-detail="${target}"` : "";
125
  const note = description ? `<small>${escapeHtml(description)}</small>` : "";
 
256
  .sort((a, b) => a.surveyName.localeCompare(b.surveyName, "ar"))
257
  .map((row) => `${row.surveyName}: ${row.collectionStatus || "-"}`);
258
  const count = new Set(group.rows.map((row) => plain(row.collectionStatus)).filter(Boolean)).size;
259
+ return `<tr>${td("السجل التجاري", `<button class="row-button" data-entity="${escapeHtml(group.key)}">${escapeHtml(group.commercialRegister)}</button>`)}${td("اسم المنشأة", escapeHtml(group.name))}${td("الحالات حسب المسح", stackedList(statuses))}${td("عدد الحالات", count)}</tr>`;
260
  }).join("")}</tbody></table></div>`;
261
  } else if (type === "researchers") {
262
  const researchers = [...countBy(sharedRows, (row) => row.researcher).entries()].sort((a, b) => b[1] - a[1]).slice(0, 20);
 
267
  const title = type === "establishments" ? "المنشآت المتقاطعة" : "تفاصيل التقاطعات";
268
  const subtitle = "السجلات التجارية التي ظهرت في أكثر من مسح.";
269
  panel.innerHTML = `${dashboardDetailHeader(title, subtitle)}
270
+ <div class="table-wrap"><table><thead><tr><th>السجل التجاري</th><th>اسم المنشأة</th><th>عدد المسوح</th><th>المسوح</th><th>الباحثون</th></tr></thead><tbody>${filtered.slice(0, 50).map((group) => `<tr>${td("السجل التجاري", `<button class="row-button" data-entity="${escapeHtml(group.key)}">${escapeHtml(group.commercialRegister)}</button>`)}${td("اسم المنشأة", escapeHtml(group.name))}${td("عدد المسوح", group.surveys.length)}${td("المسوح", stackedList(group.surveys))}${td("الباحثون", stackedList(group.researchers))}</tr>`).join("")}</tbody></table></div>`;
271
  }
272
 
273
  panel.scrollIntoView({ behavior: "smooth", block: "start" });
 
379
  const three = groups.filter((group) => group.surveys.length >= 3).length;
380
  $("intersectionMetrics").innerHTML = [metric(groups.length, "منشآت مشتركة"), metric(two, "في مسحين"), metric(three, "في 3 مسوح أو أكثر"), metric(app.byRegister.size, "سجلات قابلة للمطابقة"), metric(app.surveys.size, "إجمالي المسوح")].join("");
381
  $("intersectionResults").className = "results";
382
+ $("intersectionResults").innerHTML = groups.length ? `<div class="table-wrap"><table><thead><tr><th>السجل التجاري</th><th>اسم المنشأة</th><th>عدد المسوح</th><th>المسوح</th><th>الباحثون</th></tr></thead><tbody>${groups.slice(0, 200).map((group) => `<tr>${td("السجل التجاري", `<button class="row-button" data-entity="${escapeHtml(group.key)}">${escapeHtml(group.commercialRegister)}</button>`)}${td("اسم المنشأة", escapeHtml(group.name))}${td("عدد المسوح", group.surveys.length)}${td("المسوح", stackedList(group.surveys))}${td("الباحثون", stackedList(group.researchers))}</tr>`).join("")}</tbody></table></div>` : "<div class='empty-state'>لا توجد تقاطعات قابلة للحساب.</div>";
383
  }
384
 
385
  function renderCompactEntities(groups) {
386
+ return `<div class="table-wrap compact-table"><table><thead><tr><th>السجل التجاري</th><th>اسم المنشأة</th><th>المسوح</th><th>الباحثون</th></tr></thead><tbody>${groups.map((group) => `<tr>${td("السجل التجاري", `<button class="row-button" data-entity="${escapeHtml(group.key)}">${escapeHtml(group.commercialRegister || "-")}</button>`)}${td("اسم المنشأة", escapeHtml(group.name))}${td("المسوح", stackedList(group.surveys))}${td("الباحثون", stackedList(group.researchers))}</tr>`).join("")}</tbody></table></div>`;
387
  }
388
 
389
  function renderResearchers() {
style.css CHANGED
@@ -112,6 +112,9 @@ td:nth-child(1),td:nth-child(3),td:nth-child(4){white-space:nowrap}
112
  td:nth-child(2),td:nth-child(5){max-width:380px;white-space:normal}
113
  .row-button{display:block;width:100%;border:0;background:transparent;text-align:center;font:inherit;cursor:pointer;padding:0;color:var(--primary);font-weight:950;letter-spacing:.2px}
114
  .row-button:hover{text-decoration:underline;text-underline-offset:4px;color:#145f74}
 
 
 
115
  .batch-card textarea{width:100%;padding:15px;resize:vertical;line-height:1.7;min-height:250px}
116
  .batch-actions{display:flex;align-items:center;justify-content:space-between;gap:12px;margin-top:12px}
117
  .batch-actions div{display:flex;gap:8px}
@@ -183,6 +186,7 @@ footer b{color:var(--primary)}
183
  tr td:last-child{border-bottom:0}
184
  td:before{content:attr(data-label);color:var(--primary);font-weight:950;text-align:right}
185
  .row-button{text-align:right}
 
186
  .badge{white-space:normal;text-align:center}
187
  .occurrences{display:grid;gap:10px;padding:12px;background:#f8fbfd}
188
  .occurrence-head{display:none}
 
112
  td:nth-child(2),td:nth-child(5){max-width:380px;white-space:normal}
113
  .row-button{display:block;width:100%;border:0;background:transparent;text-align:center;font:inherit;cursor:pointer;padding:0;color:var(--primary);font-weight:950;letter-spacing:.2px}
114
  .row-button:hover{text-decoration:underline;text-underline-offset:4px;color:#145f74}
115
+ .stacked-list{display:grid;gap:6px;justify-items:center;text-align:center;line-height:1.65}
116
+ .stacked-list span{display:block;width:100%;padding-bottom:6px;border-bottom:1px solid #e7eef6}
117
+ .stacked-list span:last-child{padding-bottom:0;border-bottom:0}
118
  .batch-card textarea{width:100%;padding:15px;resize:vertical;line-height:1.7;min-height:250px}
119
  .batch-actions{display:flex;align-items:center;justify-content:space-between;gap:12px;margin-top:12px}
120
  .batch-actions div{display:flex;gap:8px}
 
186
  tr td:last-child{border-bottom:0}
187
  td:before{content:attr(data-label);color:var(--primary);font-weight:950;text-align:right}
188
  .row-button{text-align:right}
189
+ .stacked-list{justify-items:start;text-align:right;gap:5px}
190
  .badge{white-space:normal;text-align:center}
191
  .occurrences{display:grid;gap:10px;padding:12px;background:#f8fbfd}
192
  .occurrence-head{display:none}