Spaces:
Running
Running
Update app.js
Browse files
app.js
CHANGED
|
@@ -29,10 +29,10 @@ function buildTable(rows){const theadRow=document.getElementById("theadRow");con
|
|
| 29 |
function readTable(){const tbody=document.getElementById("tbody");const rows=[];[...tbody.querySelectorAll("tr")].forEach(tr=>{const obj={};[...tr.children].forEach((td,idx)=>{const col=EXPORT_COLUMNS[idx];obj[col]=td.textContent.trim()});rows.push(obj)});return rows}
|
| 30 |
function updateBadge(n){const b=document.getElementById("countBadge");b.textContent=n;b.hidden=(n===0)}
|
| 31 |
function setButtonsEnabled(hasRows){document.getElementById("btn-export").disabled=!hasRows;document.getElementById("btn-copy").disabled=!hasRows}
|
| 32 |
-
function validateCells(){const tbody=document.getElementById("tbody");const idxPhone=EXPORT_COLUMNS.indexOf("رقم الجوال");const idxID=EXPORT_COLUMNS.indexOf("رقم الهوية");[...tbody.rows].forEach(tr=>{
|
| 33 |
document.addEventListener("input",e=>{if(e.target&&e.target.closest&&e.target.closest("#tbody")){validateCells();saveState()}})
|
| 34 |
function toast(msg){const t=document.getElementById("toast");t.textContent=msg;t.hidden=false;t.classList.remove("show");void t.offsetWidth;t.classList.add("show");setTimeout(()=>{t.hidden=true},2000)}
|
| 35 |
-
async function exportExcel(){const rows=readTable();if(!rows.length){toast("لا يوجد بيانات لتصديرها.");return}const TEMPLATE_HEADERS=["نوع المشكلة","وصف المشكلة","المنطقة","اسم المسح","اسم المشغل","رقم الجوال","رقم الهوية ID","رقم الجهاز","تاريخ اليوم بالميلادي","الحالة","اسم الدعم الفني"];const mapRow=r=>{const today=new Date();const yyyy=today.getFullYear(),mm=String(today.getMonth()+1).padStart(2,"0"),dd=String(today.getDate()).padStart(2,"0");const todayStr=`${yyyy}-${mm}-${dd}`;return{"نوع المشكلة":r["نوع المشكلة"]||"","وصف المشكلة":r["التصنيف"]||r["نوع المشكلة"]||"","المنطقة":r["المنطقة"]||"","اسم المسح":r["المسح"]||"","اسم المشغل":r["اسم صاحب المشكلة"]||"","رقم الجوال":(r["رقم الجوال"]||"").toString(),"رقم الهوية ID":(r["رقم الهوية"]||"").toString(),"رقم الجهاز":(r["رقم الجهاز"]||"").toString(),"تاريخ اليوم بالميلادي":todayStr,"الحالة":r["الحالة"]||"تم الحل","اسم الدعم الفني":r["اسم الدعم الفني"]||""}};const wb=new ExcelJS.Workbook();const ws=wb.addWorksheet("التذاكر",{views:[{rightToLeft:true}]});const colWidths=[18,
|
| 36 |
async function copyToClipboardTSV(){const rows=readTable();if(!rows.length){toast("لا يوجد بيانات لنسخها.");return}const textCols=new Set(["رقم الهوية","رقم الجهاز","رقم الجوال"]);const header=EXPORT_COLUMNS.join("\t");const body=rows.map(r=>EXPORT_COLUMNS.map(c=>{let v=(r[c]??"").toString().replace(/\t/g," ");if(textCols.has(c)&&v&&/^[0-9]+$/.test(v))v="'"+v;return v}).join("\t")).join("\r\n");const tsv="\uFEFF"+header+"\r\n"+body;try{await navigator.clipboard.writeText(tsv);toast("تم النسخ — الصق/ي مباشرة في Excel.")}catch(e){const ta=document.createElement("textarea");ta.value=tsv;document.body.appendChild(ta);ta.select();document.execCommand("copy");document.body.removeChild(ta);toast("تم النسخ — الصق/ي مباشرة في Excel.")}}
|
| 37 |
const SAMPLE=`نوع المشكلة: لا استطيع اكمال الاستمارة بسبب تعليق عند الحفظ
|
| 38 |
وقت حدوث المشكلة: 1446/09/10 هـ
|
|
@@ -40,15 +40,16 @@ const SAMPLE=`نوع المشكلة: لا استطيع اكمال الاستما
|
|
| 40 |
رقم الهوية: 1234567890
|
| 41 |
رقم الجهاز: 01234
|
| 42 |
رقم الجوال: 0558174717
|
| 43 |
-
المسح: الخبر
|
| 44 |
المنطقة: الشرقية`;
|
| 45 |
-
const STATE_KEY="
|
| 46 |
-
const ALL_STATE_KEYS=["ticketParserState_v8","ticketParserState_v9","ticketParserState_v10","ticketParserState_v10_1","ticketParserState_v10_2","ticketParserState_v10_3","ticketParserState_v10_5","ticketParserState_v10_6","ticketParserState_v10_7","ticketParserState_v10_8"];
|
| 47 |
function ensureColumns(rows,agentName,defaultRegion){if(!Array.isArray(rows))return rows||[];return rows.map(r=>{const out={...r};if(!("التصنيف"in out)||!out["التصنيف"]){const fakeText=Object.values(out).join("\n");out["التصنيف"]=classifyTicket(fakeText,out)}if(!("اسم الدعم الفني"in out))out["اسم الدعم الفني"]=agentName||out["اسم الدعم الفني"]||"";if(!("الحالة"in out)||!out["الحالة"])out["الحالة"]="تم الحل";if(defaultRegion)out["المنطقة"]=defaultRegion;return out})}
|
| 48 |
function saveState(){try{const raw=document.getElementById("raw")?.value||"";const agent=document.getElementById("agentName")?.value||"";const region=document.getElementById("regionDefault")?.value||"";const rows=readTable();localStorage.setItem(STATE_KEY,JSON.stringify({raw,agent,region,rows,theme:document.body.classList.contains("dark")?"dark":"light"}))}catch{}}
|
| 49 |
-
function loadState(){try{const s=localStorage.getItem(STATE_KEY);if(!s)return false;let{raw,agent,region,rows,theme}=JSON.parse(s);if(typeof raw==="string"){const el=document.getElementById("raw");if(el)el.value=raw}if(typeof agent==="string"){const el=document.getElementById("agentName");if(el)el.value=agent}if(typeof region==="string"){const el=document.getElementById("regionDefault");if(el)el.value=region}if(theme==="dark")document.body.classList.add("dark");updateThemeLabel();rows=ensureColumns(rows,agent,region);if(Array.isArray(rows)&&rows.length){buildTable(rows);validateCells();updateBadge(rows.length);setButtonsEnabled(true)}return true}catch{return false}}
|
| 50 |
-
function clearAll(){const rawEl=document.getElementById("raw");const tbody=document.getElementById("tbody");const agentEl=document.getElementById("agentName");const regionEl=document.getElementById("regionDefault");if(rawEl)rawEl.value="";if(tbody)tbody.innerHTML="";if(agentEl)agentEl.value="";if(regionEl)regionEl.value="";updateBadge(0);setButtonsEnabled(false);try{ALL_STATE_KEYS.forEach(k=>localStorage.removeItem(k))}catch{}toast("تم مسح كل البيانات والتخزين.")}
|
| 51 |
function mergeDuplicatesRows(rows){if(!rows.length)return rows;const map=new Map();rows.forEach(r=>{const key=[r["رقم الهوية"]||"",r["رقم الجهاز"]||"",r["رقم الجوال"]||"",r["وقت حدوث المشكلة"]||"",(r["نوع المشكلة"]||"").slice(0,40)].join("|");if(!map.has(key))map.set(key,r)});return[...map.values()]}
|
| 52 |
function updateThemeLabel(){const btn=document.getElementById("btn-theme");if(!btn)return;btn.textContent=document.body.classList.contains("dark")?"وضع نهار":"وضع ليلي"}
|
| 53 |
-
function
|
|
|
|
| 54 |
init();
|
|
|
|
| 29 |
function readTable(){const tbody=document.getElementById("tbody");const rows=[];[...tbody.querySelectorAll("tr")].forEach(tr=>{const obj={};[...tr.children].forEach((td,idx)=>{const col=EXPORT_COLUMNS[idx];obj[col]=td.textContent.trim()});rows.push(obj)});return rows}
|
| 30 |
function updateBadge(n){const b=document.getElementById("countBadge");b.textContent=n;b.hidden=(n===0)}
|
| 31 |
function setButtonsEnabled(hasRows){document.getElementById("btn-export").disabled=!hasRows;document.getElementById("btn-copy").disabled=!hasRows}
|
| 32 |
+
function validateCells(){const tbody=document.getElementById("tbody");const idxPhone=EXPORT_COLUMNS.indexOf("رقم الجوال");const idxID=EXPORT_COLUMNS.indexOf("رقم الهوية");const required=new Set(["نوع المشكلة","اسم صاحب المشكلة","رقم الهوية","رقم الجهاز","رقم الجوال","المسح","المنطقة","وقت حدوث المشكلة"]);let missing=0;[...tbody.rows].forEach(tr=>{[...tr.children].forEach((td,idx)=>{const col=EXPORT_COLUMNS[idx];const val=(td.textContent||"").trim();let invalid=false;if(required.has(col)&&!val){invalid=true;missing++}if(col==="رقم الهوية"){const digits=val.replace(/\D/g,"");if(val&&digits.length!==10){invalid=true}}if(col==="رقم الجوال"){const digits=val.replace(/\D/g,"");if(val&&digits.length<9){invalid=true}}td.classList.toggle("invalid",invalid)})});const warn=document.getElementById("warn");if(missing>0){warn.hidden=false;warn.textContent=`هناك ${missing} حقول مطلوبة فارغة أو غير صحيحة. يرجى إكمالها.`}else{warn.hidden=true;warn.textContent=""}}
|
| 33 |
document.addEventListener("input",e=>{if(e.target&&e.target.closest&&e.target.closest("#tbody")){validateCells();saveState()}})
|
| 34 |
function toast(msg){const t=document.getElementById("toast");t.textContent=msg;t.hidden=false;t.classList.remove("show");void t.offsetWidth;t.classList.add("show");setTimeout(()=>{t.hidden=true},2000)}
|
| 35 |
+
async function exportExcel(){const rows=readTable();if(!rows.length){toast("لا يوجد بيانات لتصديرها.");return}const TEMPLATE_HEADERS=["التصنيف","نوع المشكلة","وصف المشكلة","المنطقة","اسم المسح","اسم المشغل","رقم الجوال","رقم الهوية ID","رقم الجهاز","تاريخ اليوم بالميلادي","الحالة","اسم الدعم الفني"];const mapRow=r=>{const today=new Date();const yyyy=today.getFullYear(),mm=String(today.getMonth()+1).padStart(2,"0"),dd=String(today.getDate()).padStart(2,"0");const todayStr=`${yyyy}-${mm}-${dd}`;return{"التصنيف":r["التصنيف"]||"","نوع المشكلة":r["نوع المشكلة"]||"","وصف المشكلة":r["التصنيف"]||r["نوع المشكلة"]||"","المنطقة":r["المنطقة"]||"","اسم المسح":r["المسح"]||"","اسم المشغل":r["اسم صاحب المشكلة"]||"","رقم الجوال":(r["رقم الجوال"]||"").toString(),"رقم الهوية ID":(r["رقم الهوية"]||"").toString(),"رقم الجهاز":(r["رقم الجهاز"]||"").toString(),"تاريخ اليوم بالميلادي":todayStr,"الحالة":r["الحالة"]||"تم الحل","اسم الدعم الفني":r["اسم الدعم الفني"]||""}};const wb=new ExcelJS.Workbook();const ws=wb.addWorksheet("التذاكر",{views:[{rightToLeft:true}]});const colWidths=[16,18,24,16,18,20,18,18,18,22,14,18];TEMPLATE_HEADERS.forEach((h,i)=>ws.getColumn(i+1).width=colWidths[i]||18);ws.addRow(TEMPLATE_HEADERS);const headerRow=ws.getRow(1);headerRow.height=24;headerRow.eachCell(cell=>{cell.font={bold:true,color:{argb:"FFFFFFFF"}};cell.alignment={horizontal:"center",vertical:"middle"};cell.fill={type:"pattern",pattern:"solid",fgColor:{argb:"FF4137A8"}};cell.border={top:{style:"thin",color:{argb:"FFCDD2E1"}},bottom:{style:"thin",color:{argb:"FFCDD2E1"}},left:{style:"thin",color:{argb:"FFE5E7EB"}},right:{style:"thin",color:{argb:"FFE5E7EB"}}}});const toTextCols=new Set(["رقم الجوال","رقم الهوية ID","رقم الجهاز"]);const rawRows=readTable();rawRows.forEach((r,idx)=>{const m=mapRow(r);const vals=TEMPLATE_HEADERS.map(h=>m[h]??"");const row=ws.addRow(vals);row.alignment={horizontal:"center",vertical:"middle"};const even=(idx%2)===1;row.eachCell((cell,colNumber)=>{cell.border={top:{style:"thin",color:{argb:"FFE5E7EB"}},bottom:{style:"thin",color:{argb:"FFE5E7EB"}},left:{style:"thin",color:{argb:"FFE5E7EB"}},right:{style:"thin",color:{argb:"FFE5E7EB"}}};if(even)cell.fill={type:"pattern",pattern:"solid",fgColor:{argb:"FFF5F8FF"}};const header=TEMPLATE_HEADERS[colNumber-1];if(toTextCols.has(header))cell.value=String(cell.value??"")})});const ts=new Date().toISOString().replace(/\D/g,"").slice(0,14);const filename=`Ticket_${ts}.xlsx`;const buffer=await wb.xlsx.writeBuffer();const blob=new Blob([buffer],{type:"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"});const file=new File([blob],filename,{type:blob.type});if(navigator.canShare&&navigator.canShare({files:[file]})){try{await navigator.share({files:[file],title:"ملف التذاكر"});toast("تمت المشاركة/الحفظ.");return}catch(e){}}const url=URL.createObjectURL(blob);const a=document.createElement("a");a.href=url;a.download=filename;document.body.appendChild(a);a.click();a.remove();setTimeout(()=>URL.revokeObjectURL(url),1000);toast("تم تنزيل الملف بتنسيق القالب.")}
|
| 36 |
async function copyToClipboardTSV(){const rows=readTable();if(!rows.length){toast("لا يوجد بيانات لنسخها.");return}const textCols=new Set(["رقم الهوية","رقم الجهاز","رقم الجوال"]);const header=EXPORT_COLUMNS.join("\t");const body=rows.map(r=>EXPORT_COLUMNS.map(c=>{let v=(r[c]??"").toString().replace(/\t/g," ");if(textCols.has(c)&&v&&/^[0-9]+$/.test(v))v="'"+v;return v}).join("\t")).join("\r\n");const tsv="\uFEFF"+header+"\r\n"+body;try{await navigator.clipboard.writeText(tsv);toast("تم النسخ — الصق/ي مباشرة في Excel.")}catch(e){const ta=document.createElement("textarea");ta.value=tsv;document.body.appendChild(ta);ta.select();document.execCommand("copy");document.body.removeChild(ta);toast("تم النسخ — الصق/ي مباشرة في Excel.")}}
|
| 37 |
const SAMPLE=`نوع المشكلة: لا استطيع اكمال الاستمارة بسبب تعليق عند الحفظ
|
| 38 |
وقت حدوث المشكلة: 1446/09/10 هـ
|
|
|
|
| 40 |
رقم الهوية: 1234567890
|
| 41 |
رقم الجهاز: 01234
|
| 42 |
رقم الجوال: 0558174717
|
| 43 |
+
المسح: الخبر
|
| 44 |
المنطقة: الشرقية`;
|
| 45 |
+
const STATE_KEY="ticketParserState_v10_9";
|
| 46 |
+
const ALL_STATE_KEYS=["ticketParserState_v8","ticketParserState_v9","ticketParserState_v10","ticketParserState_v10_1","ticketParserState_v10_2","ticketParserState_v10_3","ticketParserState_v10_5","ticketParserState_v10_6","ticketParserState_v10_7","ticketParserState_v10_8","ticketParserState_v10_9"];
|
| 47 |
function ensureColumns(rows,agentName,defaultRegion){if(!Array.isArray(rows))return rows||[];return rows.map(r=>{const out={...r};if(!("التصنيف"in out)||!out["التصنيف"]){const fakeText=Object.values(out).join("\n");out["التصنيف"]=classifyTicket(fakeText,out)}if(!("اسم الدعم الفني"in out))out["اسم الدعم الفني"]=agentName||out["اسم الدعم الفني"]||"";if(!("الحالة"in out)||!out["الحالة"])out["الحالة"]="تم الحل";if(defaultRegion)out["المنطقة"]=defaultRegion;return out})}
|
| 48 |
function saveState(){try{const raw=document.getElementById("raw")?.value||"";const agent=document.getElementById("agentName")?.value||"";const region=document.getElementById("regionDefault")?.value||"";const rows=readTable();localStorage.setItem(STATE_KEY,JSON.stringify({raw,agent,region,rows,theme:document.body.classList.contains("dark")?"dark":"light"}))}catch{}}
|
| 49 |
+
function loadState(){try{const s=localStorage.getItem(STATE_KEY);if(!s)return false;let{raw,agent,region,rows,theme}=JSON.parse(s);if(typeof raw==="string"){const el=document.getElementById("raw");if(el)el.value=raw}if(typeof agent==="string"){const el=document.getElementById("agentName");if(el)el.value=agent}if(typeof region==="string"){const el=document.getElementById("regionDefault");if(el)el.value=region}if(theme==="dark")document.body.classList.add("dark");updateThemeLabel();rows=ensureColumns(rows,agent,region);if(Array.isArray(rows)&&rows.length){buildTable(rows);validateCells();updateBadge(rows.length);setButtonsEnabled(true)}toggleSampleOverlay();return true}catch{return false}}
|
| 50 |
+
function clearAll(){const rawEl=document.getElementById("raw");const tbody=document.getElementById("tbody");const agentEl=document.getElementById("agentName");const regionEl=document.getElementById("regionDefault");if(rawEl)rawEl.value="";if(tbody)tbody.innerHTML="";if(agentEl)agentEl.value="";if(regionEl)regionEl.value="";updateBadge(0);setButtonsEnabled(false);document.getElementById("warn").hidden=true;try{ALL_STATE_KEYS.forEach(k=>localStorage.removeItem(k))}catch{}toast("تم مسح كل البيانات والتخزين.");toggleSampleOverlay()}
|
| 51 |
function mergeDuplicatesRows(rows){if(!rows.length)return rows;const map=new Map();rows.forEach(r=>{const key=[r["رقم الهوية"]||"",r["رقم الجهاز"]||"",r["رقم الجوال"]||"",r["وقت حدوث المشكلة"]||"",(r["نوع المشكلة"]||"").slice(0,40)].join("|");if(!map.has(key))map.set(key,r)});return[...map.values()]}
|
| 52 |
function updateThemeLabel(){const btn=document.getElementById("btn-theme");if(!btn)return;btn.textContent=document.body.classList.contains("dark")?"وضع نهار":"وضع ليلي"}
|
| 53 |
+
function toggleSampleOverlay(){const raw=document.getElementById("raw");const ov=document.getElementById("sampleOverlay");if(!ov||!raw)return;ov.style.display=raw.value.trim()? "none":"flex"}
|
| 54 |
+
function init(){const parseBtn=document.getElementById("btn-parse");const exportBtn=document.getElementById("btn-export");const copyBtn=document.getElementById("btn-copy");const clearBtn=document.getElementById("btn-clear");const themeBtn=document.getElementById("btn-theme");const rawEl=document.getElementById("raw");const agentEl=document.getElementById("agentName");const regionEl=document.getElementById("regionDefault");const ov=document.getElementById("sampleOverlay");loadState();parseBtn.addEventListener("click",()=>{const raw=(rawEl.value||"").trim();if(!raw){toast("فضلاً الصق/ي تذاكر أولاً.");return}const cleaned=normalizeText(fixLabels(raw));const agent=agentEl.value||"";const defRegion=regionEl.value||"";let rows=parseTicketsWithExtras(cleaned,agent,defRegion);rows=mergeDuplicatesRows(rows);buildTable(rows);validateCells();updateBadge(rows.length);setButtonsEnabled(rows.length>0);saveState();toast(`تم استخراج ${rows.length} تذكرة.`)});exportBtn.addEventListener("click",exportExcel);copyBtn.addEventListener("click",copyToClipboardTSV);clearBtn.addEventListener("click",clearAll);themeBtn.addEventListener("click",()=>{document.body.classList.toggle("dark");updateThemeLabel();saveState()});rawEl.addEventListener("input",()=>{toggleSampleOverlay();saveState()});agentEl.addEventListener("input",saveState);regionEl.addEventListener("change",saveState);if(ov){const insertSample=()=>{document.getElementById("raw").value=SAMPLE;toggleSampleOverlay();saveState();toast("تم إدراج المثال.")};ov.addEventListener("click",insertSample);ov.addEventListener("keydown",e=>{if(e.key==="Enter"||e.key===" "){e.preventDefault();insertSample()}})}document.addEventListener("keydown",e=>{const ctrl=e.ctrlKey||e.metaKey;if(ctrl&&e.key==="Enter"){e.preventDefault();parseBtn.click()}else if(ctrl&&e.key.toLowerCase()==="e"){e.preventDefault();exportBtn.click()}else if(ctrl&&e.shiftKey&&e.key.toLowerCase()==="c"){e.preventDefault();copyBtn.click()}else if(e.key==="Escape"){e.preventDefault();clearAll()}});setButtonsEnabled(!!document.getElementById("tbody")?.children.length);updateThemeLabel();toggleSampleOverlay()}
|
| 55 |
init();
|