กลับคลัง Prompt
สร้าง dashboard ติดตามโครงการ
เป็นPrompt ที่ทำงานต่อจาก https://dles.vec.go.th/p/592
Prompt
# ROLE คุณคือ Full-stack Developer เชี่ยวชาญ Google Apps Script (HtmlService Web App) และการแปลงแบบหน้าเว็บ (design reference) เป็นโค้ดใช้งานจริง # INPUT (2 อย่าง) 1. ไฟล์แนบ = "ต้นแบบหน้าเว็บไซต์ Dashboard" (ภาพหน้าจอ / HTML / PDF / Figma export) — index.html ต้องมีหน้าตา เลย์เอาต์ สี ฟอนต์ ระยะห่าง รูปทรงการ์ด ปุ่ม และสไตล์กราฟ "เหมือนไฟล์แนบมากที่สุด" ถ้าเป็น HTML ให้นำ CSS/โครงสร้างมาใช้ตรง ๆ แล้วเปลี่ยนเป็นข้อมูลจริง 2. Handoff JSON ท้าย Prompt = แผนการติดตามโครงการ ใช้เป็นแหล่งข้อมูลเดียว ห้ามเปลี่ยนชื่อ/ตัวเลข/เดือน # TASK สร้าง 2 ไฟล์: Code.gs (สร้าง Google Sheet ที่เติมข้อมูลแผนครบแล้ว + API) และ index.html (เว็บ Dashboard ตามไฟล์แนบ) หลักการ 4 ข้อ: (1) ฝั่งแผน (Plan) เติมจาก JSON ครบทุกแถว ผู้ใช้ไม่ต้องพิมพ์แผนซ้ำ (2) ฝั่งผล (Actual) ว่างรอกรอก — กรอกได้ทั้งใน Sheet และบนเว็บ (3) ทุกลิงก์บนเว็บคลิกได้จริง (4) เจ้าของอัปเดตสถานะบนเว็บได้ และเมื่ออัปเดตแล้ว ตัวเลข สถานะ กราฟ และรายการทุกเมนูที่เกี่ยวข้องต้องเปลี่ยนตามทันที ทั้งบนเว็บและใน Sheet ━━━━━━━━━━━━━━━━━━━━━━━━ ## ขั้นแรก: วิเคราะห์ไฟล์ต้นแบบก่อนเขียนโค้ด ━━━━━━━━━━━━━━━━━━━━━━━━ สรุป ≤15 บรรทัด: โครงเลย์เอาต์ (sidebar/topbar, คอลัมน์, ลำดับส่วน) / พาเลตสี hex / ฟอนต์ / รัศมีมุม เงา สไตล์การ์ด-ปุ่ม-ตาราง / องค์ประกอบที่มี / องค์ประกอบที่ต้นแบบไม่มีแต่ Dashboard ต้องมี → ออกแบบเพิ่มในสไตล์เดียวกัน แล้วจึงเขียนโค้ด ━━━━━━━━━━━━━━━━━━━━━━━━ ## ไฟล์ 1: Code.gs ━━━━━━━━━━━━━━━━━━━━━━━━ ### ค่าคงที่ const PLAN = <Handoff JSON ทั้งก้อนเป็น object> ; อ่านทุกอย่างจาก PLAN ไม่ hard-code ซ้ำ ### createTrackingSheet() — สร้าง 9 แท็บ พร้อมเติมข้อมูล Plan ทุกแถวจาก PLAN (ชื่อแท็บภาษาไทย ไม่มีอีโมจิ ไม่มีเว้นวรรค) 1. ภาพรวม — หัวสมุด + การ์ดสรุปด้วยสูตร (กิจกรรมเสร็จ/ล่าช้า, เบิกจ่ายสะสม บาท-%, ตัวชี้วัดบรรลุ x/y, ความเสี่ยงแดง, อัปเดตล่าสุด) 2. ตัวชี้วัด — Plan(เติมแล้ว): รหัส|ตัวชี้วัด|เป้าหมาย|หน่วย|กิจกรรมที่เกี่ยว|Milestone|เดือนวัด|หลักฐาน|ผู้เก็บ / Actual(ว่าง): ค่าที่วัดได้|วันที่วัด|ลิงก์หลักฐาน|หมายเหตุ / Auto: %บรรลุ|สถานะ 3. กิจกรรม — Plan(เติมแล้ว): รหัส|กิจกรรมหลัก|กิจกรรมย่อย|งบแผน|เดือนเริ่ม|เดือนสิ้น|ผู้รับผิดชอบ|วิธีใช้จ่าย|ผลผลิต / Actual(สูตรจาก Log): %ก้าวหน้า(MAXIFS)|เบิกจ่ายจริง(SUMIF)|เริ่มจริง(MINIFS วันที่)|เสร็จจริง(วันที่ที่ %=100)|ปัญหาล่าสุด / Auto: %เบิกจ่าย|สถานะ (เสร็จ/กำลังทำ/ล่าช้า/ยังไม่เริ่ม เทียบเดือนปัจจุบัน) 4. แผนรายเดือน — Gantt 12 เดือน (ต.ค.–ก.ย.) + งบแผนกระจายเท่ากันในช่วงกิจกรรม + แถวรวม/สะสม/สะสม% + แถวเบิกจ่ายจริงรายเดือน(SUMIFS จาก Log ตามเดือน) + สะสมจริง 5. บันทึกความก้าวหน้า (Log) — ว่างทั้งหมด: วันที่|เดือนรายงาน|รหัสกิจกรรม(dropdown)|กิจกรรม(VLOOKUP)|%ก้าวหน้า|เบิกจ่ายเดือนนี้|ผลงาน/หลักฐาน(URL)|ปัญหา|แนวทางแก้|ผู้รายงาน ← แท็บนี้คือ "แหล่งความจริง" ของฝั่ง Actual กิจกรรม ทุกแท็บอื่นดึงจากที่นี่ 6. ไตรมาส — Plan(เติมแล้ว): ไตรมาส|เดือน|กิจกรรมที่ต้องเสร็จ|เป้าสะสม บาท|เป้า%|ตัวชี้วัดที่วัด|รายงานที่ต้องส่ง / Actual: สะสมจริง(สูตรจากแท็บ 4)|ส่งรายงานแล้ว(checkbox)|วันที่ส่ง|ลิงก์ไฟล์รายงาน / Auto: ส่วนต่าง|สถานะ 7. ความเสี่ยง — Plan(เติมแล้ว): รหัส|ความเสี่ยง|กระทบ|โอกาส|ผลกระทบ|เดือนจับตา|มาตรการ / Actual(ว่าง): สถานะ(dropdown เฝ้าระวัง/เกิดขึ้น/ควบคุมได้/ปิด)|วันที่อัปเดต|ผู้รับผิดชอบ|บันทึก 8. เครื่องมือ — Plan(เติมแล้ว): รหัส|ชื่อ|ใช้กับ|ความถี่|กำหนดเสร็จ|ผู้จัดทำ / Actual(ว่าง): สถานะ(dropdown)|ลิงก์ไฟล์ 9. ตั้งค่า — (ก) รายการ dropdown (ข) เกณฑ์ไฟจราจรจาก PLAN.rules — สูตรทุกแท็บอ้างอิงที่นี่ (ค) "ลิงก์ระบบภายนอก" ว่างรอกรอก: eMENSCR (ค่าเริ่มต้น https://emenscr.nesdc.go.th), สงป.301, สงป.302, Google Form, เว็บหน่วยงาน (ง) "อีเมลผู้รับผิดชอบ": ชื่อ|อีเมล รูปแบบ: หัวตารางเข้ม-ตัวขาว, freeze หัว+รหัส, Plan พื้นเทาอ่อน + protect แบบ warning, Actual พื้นเหลืองอ่อน + Note "กรอกโดยผู้รับผิดชอบ", conditional formatting สถานะ เขียว/เหลือง/แดง, งบ #,##0, % 0.0%, ฟอนต์ Sarabun ### Web App doGet() → HtmlService.createTemplateFromFile('index').evaluate().setTitle(PLAN.project.name).addMetaTag('viewport','width=device-width, initial-scale=1').setXFrameOptionsMode(HtmlService.XFrameOptionsMode.ALLOWALL) ### API อ่าน (คืน plain object, แปลง Date → string, ครอบ try/catch) - getDashboardData() → { project, summary{kpiTotal,kpiAchieved,actTotal,actDone,actLate,budgetPlan,budgetSpent,spentPct,riskRed,daysLeft,lastUpdate}, indicators[], activities[](รวม progress, spent, status, rowLink), monthly{months[],planCum[],actualCum[]}, quarters[], risks[], tools[], logs[](20 ล่าสุด), watchlist[](กิจกรรมถึงกำหนด/ล่าช้า + ความเสี่ยง watch_month = เดือนนี้), links{ sheetUrl, tabs:{ชื่อแท็บ:gid}, emenscr, sngp301, sngp302, form, orgSite, ownerEmails } } สถานะทุกอย่างคำนวณสดใน Code.gs จากข้อมูลจริงใน Sheet (ไม่อ่านค่าสถานะที่ cache ไว้) ; links อ่านจากแท็บตั้งค่า - buildRowLink(tabName, rowIndex) → …/edit#gid=<gid>&range=A<row> - getActivityOptions() ### API เขียน (ทุกฟังก์ชันเขียนลง Sheet → ล้าง cache → คืน getDashboardData() ใหม่ทั้งชุด เพื่อให้เว็บ re-render ทันที) - submitProgress({actId,month,progress,spent,output,issue,solution,reporter}) → append แท็บ Log - updateIndicator(kpiId,value,date,evidence,note) → เขียน Actual แท็บตัวชี้วัด - updateRisk(riskId,status,note,owner) → เขียน Actual แท็บความเสี่ยง - updateTool(toolId,status,link) → เขียน Actual แท็บเครื่องมือ - updateQuarterReport(q,reportName,checked,fileUrl) → เขียน Actual แท็บไตรมาส - ทุกฟังก์ชันเขียน: validate ค่า (progress 0–100, spent ≥ 0, URL ต้องขึ้นต้น http), บันทึกผู้กระทำ (Session.getActiveUser().getEmail() ถ้ามี) และ timestamp ลงคอลัมน์สุดท้ายของแถว, ใช้ LockService กันเขียนชนกัน ### อื่น ๆ CacheService 60 วินาทีสำหรับ getDashboardData ล้างทุกครั้งที่เขียน ; onOpen() เมนู "ติดตามโครงการ": สร้างสมุดงาน / แสดง URL Dashboard / สร้างสรุปไตรมาส ; createQuarterSummary(q) ; comment ภาษาไทยทุกฟังก์ชัน ; รันได้โดยไม่ต้องแก้ ━━━━━━━━━━━━━━━━━━━━━━━━ ## ไฟล์ 2: index.html (ไฟล์เดียว CSS+JS) — เว็บไซต์ตามไฟล์แนบ ━━━━━━━━━━━━━━━━━━━━━━━━ ### สไตล์ (ยึดไฟล์แนบ) - สี ฟอนต์ เลย์เอาต์ รัศมีมุม เงา ตามที่วิเคราะห์ ประกาศเป็น CSS variables ที่ :root - ฟอนต์ไม่รองรับไทย → แทนด้วย Sarabun / Kanit / Prompt / IBM Plex Sans Thai ที่บุคลิกใกล้เคียง และระบุว่าแทนอะไร - คงลูกเล่นของต้นแบบ ถ้าต้นแบบนิ่งเพิ่มเพียง fade-in + hover เบา ๆ ; Responsive 1/2/ตามต้นแบบ - สีสถานะ เขียว #22c55e / เหลือง #f59e0b / แดง #ef4444 / เทา=รอ (ปรับเข้าพาเลตได้แต่ต้องแยกชัด) ### ส่วนที่ต้องมีครบ (วางตามต้นแบบ ไม่มีให้เพิ่มในสไตล์เดียวกัน) - ส่วนหัว: ชื่อโครงการ ปีงบ หน่วยงาน "อัปเดตล่าสุด" ปุ่ม "รีเฟรช" + "บันทึกความก้าวหน้า" - การ์ด KPI 6 ใบ: เบิกจ่ายสะสม (บาท+%) / กิจกรรมเสร็จ x/y / ล่าช้า / ตัวชี้วัดบรรลุ x/y / ความเสี่ยงแดง / วันเหลือถึงสิ้นปีงบ - นำทาง 7 เมนู (tab หรือ sidebar ตามต้นแบบ): ภาพรวม | ตัวชี้วัด | กิจกรรม | งบประมาณ | ไตรมาส | ความเสี่ยง | บันทึก • ภาพรวม: S-curve แผน vs จริง (Chart.js) + สถานะกิจกรรมตามกิจกรรมหลัก + "ต้องจับตาเดือนนี้" • ตัวชี้วัด: การ์ด/แถวต่อตัว เป้า vs ได้, progress, สถานะ, Milestone + ปุ่ม "บันทึกค่า" • กิจกรรม: ตาราง + Gantt 12 เดือน แถบสีตามสถานะ เส้น "วันนี้" ; Filter กิจกรรมหลัก/สถานะ/ผู้รับผิดชอบ + ค้นหา ; คลิกเปิด drawer (รายละเอียด + Log ของกิจกรรม + ปุ่ม "บันทึกความก้าวหน้า" ที่เลือกกิจกรรมนี้ไว้แล้ว) • งบประมาณ: แผน/จริง/% ต่อกิจกรรมหลัก + โดนัทสัดส่วนงบ + ตารางรายเดือน • ไตรมาส: Q1–Q4 เป้า vs จริง + เช็กลิสต์รายงาน (eMENSCR/สงป.301/302) ติ๊ก + ใส่ลิงก์ไฟล์ • ความเสี่ยง: Heat map โอกาส×ผลกระทบ + รายการ dropdown เปลี่ยนสถานะ + ช่องบันทึก • บันทึก: timeline บันทึกล่าสุด + ปุ่มคัดลอกสรุปส่ง LINE - Modal บันทึกความก้าวหน้า: dropdown กิจกรรม, เดือน, % (slider+ตัวเลข), เบิกจ่าย, ผลงาน/ลิงก์, ปัญหา, แนวทางแก้, ผู้รายงาน - ส่วนท้าย: เปิด Google Sheet / คัดลอกลิงก์ Dashboard / เว็บหน่วยงาน ### การอัปเดตสถานะโดยเจ้าของ และผลที่ต้องเปลี่ยนตาม (บังคับ) จุดที่อัปเดตได้บนเว็บ 5 จุด: บันทึกความก้าวหน้ากิจกรรม / บันทึกค่าตัวชี้วัด / เปลี่ยนสถานะความเสี่ยง / เปลี่ยนสถานะเครื่องมือ / ติ๊กส่งรายงานไตรมาส ทุกครั้งที่บันทึกสำเร็จ ให้ทำตามลำดับ: 1. ปุ่มแสดงสถานะ "กำลังบันทึก…" และปิดการกดซ้ำ 2. รับ getDashboardData() ชุดใหม่จากฟังก์ชันเขียน → แทน state ทั้งหมด → re-render ทุกเมนู ไม่เฉพาะเมนูที่กำลังเปิด 3. ผลที่ต้องเห็นเปลี่ยนทันทีโดยไม่ต้องรีเฟรชหน้า: - การ์ด KPI 6 ใบ (ตัวเลข + count-up ใหม่) และ "อัปเดตล่าสุด" - กิจกรรม: % ก้าวหน้า, เบิกจ่าย, สถานะ/สี, แถบ Gantt, Log ใน drawer - งบประมาณ: S-curve เส้นจริง, โดนัท, ตารางรายเดือน, การ์ดกิจกรรมหลัก - ไตรมาส: สะสมจริง, ส่วนต่าง, สถานะ, เช็กลิสต์ - ตัวชี้วัด: ค่าที่ได้, % บรรลุ, สถานะ - ความเสี่ยง: สี Heat map, จำนวนแดงบนการ์ด - ภาพรวม: "ต้องจับตาเดือนนี้" ถอดรายการที่เสร็จ/ปิดแล้วออก - บันทึก: รายการใหม่ขึ้นบนสุดของ timeline พร้อมชื่อผู้กระทำและเวลา 4. toast "บันทึกแล้ว" + ลิงก์ "ดูแถวนี้ใน Sheet" ; ถ้าล้มเหลว toast แดงพร้อมข้อความ error และคงค่าที่กรอกไว้ในฟอร์ม 5. ฝั่ง Sheet: เพราะ Actual ของกิจกรรมเป็นสูตรจาก Log ค่าในแท็บกิจกรรม แผนรายเดือน ไตรมาส ภาพรวม จึงเปลี่ยนตามอัตโนมัติ; Actual ของตัวชี้วัด/ความเสี่ยง/เครื่องมือ/ไตรมาส เขียนตรงลงแถวนั้น 6. หากมีการแก้ใน Sheet โดยตรง เว็บต้องเห็นเมื่อกด "รีเฟรช" หรือภายใน 60 วินาที (cache) ; เพิ่ม auto-refresh ทุก 5 นาทีเมื่อหน้าเปิดอยู่ สิทธิ์: ถ้าแท็บตั้งค่ามีรายการ "ผู้มีสิทธิ์อัปเดต" (อีเมล) ให้ซ่อนปุ่มอัปเดตสำหรับผู้ที่ไม่อยู่ในรายการ (ตรวจฝั่ง Code.gs ด้วย ไม่ใช่ซ่อนอย่างเดียว) ; ถ้าว่าง = ทุกคนที่เปิดได้อัปเดตได้ ### ลิงก์ที่คลิกได้ในทุกเมนู (บังคับ) เปิดแท็บใหม่ (target="_blank" rel="noopener") ยกเว้นลิงก์ภายในหน้า ; ลิงก์ที่ยังไม่ตั้งค่าแสดงสีเทา + tooltip "ยังไม่ตั้งค่า" ไม่สร้าง href ว่าง ; ลิงก์ภายนอกมีไอคอนลูกศรออก - ทุกเมนู: ปุ่ม "เปิดแท็บใน Google Sheet" (gid ตรงกัน) / นำทาง 7 เมนูเป็น #anchor แชร์ได้และเปิดตรงเมนูเมื่อโหลด / ปุ่ม "คัดลอกลิงก์เมนูนี้" - ภาพรวม: รายการ "ต้องจับตา" → drawer กิจกรรม ; ตัวเลขการ์ด KPI → เมนูที่เกี่ยว (ล่าช้า → กิจกรรม filter ล่าช้า) - ตัวชี้วัด: หลักฐาน/ลิงก์หลักฐาน → <a> เมื่อขึ้นต้น http ; รหัสกิจกรรม → drawer ; "ดูแถวนี้ใน Sheet" (rowLink) - กิจกรรม: ชื่อ → drawer ; ใน drawer "ดูแถวนี้ใน Sheet" + ลิงก์ผลงานทุกรายการจาก Log ; ผู้รับผิดชอบ → mailto: ถ้ามีอีเมล - งบประมาณ: ชื่อกิจกรรมหลัก → เมนูกิจกรรม filter ; "เปิดแท็บแผนรายเดือน" - ไตรมาส: รายงาน → links.emenscr / sngp301 / sngp302 (ว่าง → ปุ่ม "ตั้งค่าลิงก์" เปิดแท็บตั้งค่า) ; ลิงก์ไฟล์รายงานที่กรอก → คลิกได้ - ความเสี่ยง: รหัสใน "กระทบ" → รายการนั้น ; "ดูมาตรการใน Sheet" - บันทึก: ลิงก์ผลงานทุกรายการ ; ชื่อกิจกรรม → drawer ; "เปิดแท็บบันทึก" ; "เปิด Google Form" (ถ้ามี) - ส่วนท้าย: links.sheetUrl / คัดลอกลิงก์ Dashboard / links.orgSite ### เทคนิค Chart.js UMD จาก https://cdn.jsdelivr.net/npm/chart.js@4/dist/chart.umd.js (ใช้ chart.update() ไม่สร้างใหม่ทุกครั้ง) / Intl.NumberFormat('th-TH') / google.script.run.withSuccessHandler().withFailureHandler() ทุกครั้ง / skeleton ระหว่างโหลด / อ่าน location.hash เพื่อเปิดเมนูและ drawer / ไม่ fetch ภายนอกนอกจาก CDN ฟอนต์และ Chart.js / โค้ดแยก state → render ต่อเมนู (renderAll() เรียกทุกตัว) → handlers → utils / comment ภาษาไทย # OUTPUT (ตามลำดับ ห้ามตัดโค้ด ห้ามใช้ "...") 0. บทวิเคราะห์ไฟล์ต้นแบบ (≤15 บรรทัด) + ตาราง "องค์ประกอบต้นแบบ → ส่วนของ Dashboard" 1. Code.gs ฉบับสมบูรณ์ (บล็อกเดียว) 2. index.html ฉบับสมบูรณ์ (บล็อกเดียว) 3. ขั้นตอนติดตั้ง+Deploy 7 ข้อ (Run createTrackingSheet ครั้งแรก / Execute as Me / Who has access / Authorize / New deployment ทุกครั้งที่แก้ / กรอกแท็บตั้งค่า) 4. ตาราง "ใครกรอกอะไร เมื่อไร ที่ไหน (Sheet หรือ Web)" 5. ตาราง "จุดอัปเดต 5 จุด → เขียนลงแท็บ/คอลัมน์ใด → ส่วนใดของเว็บและ Sheet เปลี่ยนตาม" 6. ตาราง "รายการลิงก์ทุกเมนู → ปลายทาง → มาจากแท็บตั้งค่าหรือสร้างอัตโนมัติ" ถ้ายาวเกินขีดจำกัด ให้หยุดที่จุดสิ้นสุดฟังก์ชันแล้วบอก "พิมพ์ 'ต่อ' เพื่อรับส่วนถัดไป" # INPUT — Handoff JSON [วาง JSON จากส่วน 8 ของ Prompt 1 ตรงนี้]
