diff --git a/cpone-dashboard/db/migrations/012_publish_n_to_y_sync_details.sql b/cpone-dashboard/db/migrations/012_publish_n_to_y_sync_details.sql index de1690c..1943367 100644 --- a/cpone-dashboard/db/migrations/012_publish_n_to_y_sync_details.sql +++ b/cpone-dashboard/db/migrations/012_publish_n_to_y_sync_details.sql @@ -38,10 +38,10 @@ BEGIN ORDER BY mn.Mcu_NumberID DESC LIMIT 1; - DELETE FROM cpone_corporate.kelainan_details + DELETE FROM cpone_dashboard.kelainan_details WHERE T_OrderHeaderID = p_order_header_id; - INSERT INTO cpone_corporate.kelainan_details ( + INSERT INTO cpone_dashboard.kelainan_details ( Numbering, Tx_KelainanID, Tx_Type, T_OrderHeaderID, T_OrderHeaderDate, T_OrderHeaderLabNumber, AgePatient, M_PatientID, M_PatientNoReg, M_PatientDOB, M_PatientGender, M_PatientIdentifierValue, M_PatientNIP, M_PatientJob, M_PatientPosisi, M_PatientDivisi, M_PatientLocation, M_PatientDepartement, @@ -75,7 +75,7 @@ BEGIN LEFT JOIN cpone.m_title ON M_PatientM_TitleID=M_TitleID AND M_TitleIsActive='Y' WHERE T_KelainanNonLabIsActive='Y' AND T_OrderHeaderID=p_order_header_id; - INSERT INTO cpone_corporate.kelainan_details ( + INSERT INTO cpone_dashboard.kelainan_details ( Numbering, Tx_KelainanID, Tx_Type, T_OrderHeaderID, T_OrderHeaderDate, T_OrderHeaderLabNumber, AgePatient, M_PatientID, M_PatientNoReg, M_PatientDOB, M_PatientGender, M_PatientIdentifierValue, M_PatientNIP, M_PatientJob, M_PatientPosisi, M_PatientDivisi, M_PatientLocation, M_PatientDepartement, @@ -108,7 +108,7 @@ BEGIN WHERE T_KelainanLabIsActive='Y' AND T_OrderHeaderID=p_order_header_id GROUP BY T_KelainanLabID; - INSERT INTO cpone_corporate.kelainan_details ( + INSERT INTO cpone_dashboard.kelainan_details ( Numbering, Tx_KelainanID, Tx_Type, T_OrderHeaderID, T_OrderHeaderDate, T_OrderHeaderLabNumber, AgePatient, M_PatientID, M_PatientNoReg, M_PatientDOB, M_PatientGender, M_PatientIdentifierValue, M_PatientNIP, M_PatientJob, M_PatientPosisi, M_PatientDivisi, M_PatientLocation, M_PatientDepartement, @@ -169,10 +169,10 @@ BEGIN ORDER BY mn.Mcu_NumberID DESC LIMIT 1; - DELETE FROM cpone_corporate.mcu_result_all + DELETE FROM cpone_dashboard.mcu_result_all WHERE Mcu_ResultAllT_OrderHeaderID = p_order_header_id; - INSERT INTO cpone_corporate.mcu_result_all ( + INSERT INTO cpone_dashboard.mcu_result_all ( Numbering, Mcu_ResultAllM_LangID, Mcu_ResultAllMgm_McuID, Mcu_ResultAllT_OrderHeaderID, Mcu_ResultAllT_OrderHeaderLabNumber, Mcu_ResultAllReffID, Mcu_ResultAllT_TestCode, Mcu_ResultAllT_TestName, Mcu_ResultAllResult, Mcu_ResultAllUnit, Mcu_ResultAllRefference, diff --git a/cpone-dashboard/menu/arrival/handler.go b/cpone-dashboard/menu/arrival/handler.go index f823cdf..2e76b99 100644 --- a/cpone-dashboard/menu/arrival/handler.go +++ b/cpone-dashboard/menu/arrival/handler.go @@ -6,11 +6,14 @@ import ( "encoding/json" "html/template" "net/http" + "strconv" ) var tmpl *template.Template var basePath string +const defaultPageSize = 30 + func SetTemplates(t *template.Template) { tmpl = t } func SetBasePath(p string) { basePath = p } @@ -28,6 +31,12 @@ type pageData struct { DepartmentOptions []string OverviewJSON template.JS DepartmentJSON template.JS + Page int + PageSize int + HasMore bool + VisibleCount int + TotalFiltered int + NextPage int } func toJS(v interface{}) template.JS { @@ -35,33 +44,36 @@ func toJS(v interface{}) template.JS { return template.JS(b) } -func Index(w http.ResponseWriter, r *http.Request) { +func parsePage(q string) int { + p, err := strconv.Atoi(q) + if err != nil || p < 1 { + return 1 + } + return p +} + +func buildArrivalData(r *http.Request) (pageData, int, error) { username := auth.Username(r) mcuID := auth.SelectedProjectID(r) if mcuID == 0 { - http.Redirect(w, r, basePath+"/projects", http.StatusSeeOther) - return + return pageData{}, http.StatusSeeOther, nil } project, ok, err := projects.GetUserProject(username, mcuID) if err != nil { - http.Error(w, "query error", http.StatusInternalServerError) - return + return pageData{}, http.StatusInternalServerError, err } if !ok { - http.Redirect(w, r, basePath+"/projects", http.StatusSeeOther) - return + return pageData{}, http.StatusSeeOther, nil } dates, err := GetArrivalDates(mcuID) if err != nil { - http.Error(w, "query error", http.StatusInternalServerError) - return + return pageData{}, http.StatusInternalServerError, err } selectedDate := activeDateOrLatest(dates, r.URL.Query().Get("date"), project.StartDate) rows, err := GetArrivalRows(mcuID, selectedDate) if err != nil { - http.Error(w, "query error", http.StatusInternalServerError) - return + return pageData{}, http.StatusInternalServerError, err } summary, deptStats := BuildArrivalStats(rows) filteredRows := FilterArrivalRows(rows, r.URL.Query().Get("search"), r.URL.Query().Get("dept")) @@ -69,14 +81,12 @@ func Index(w http.ResponseWriter, r *http.Request) { stationMap, err := GetStationProgress(mcuID, selectedDate) if err != nil { - http.Error(w, "query error", http.StatusInternalServerError) - return + return pageData{}, http.StatusInternalServerError, err } for i := range filteredRows { filteredRows[i].Stations = stationMap[filteredRows[i].PreregisterID] } - // Chart 1: double donut — inner: checked-in vs pending, outer: total per posisi/dept outerDepts := []map[string]any{} for _, d := range deptStats { if d.Total > 0 { @@ -89,7 +99,6 @@ func Index(w http.ResponseWriter, r *http.Request) { "depts": outerDepts, } - // Chart 2: per-station patient count bar chart stationStats := BuildStationChart(stationMap) stationLabels := make([]string, len(stationStats)) stationCounts := make([]int, len(stationStats)) @@ -102,12 +111,14 @@ func Index(w http.ResponseWriter, r *http.Request) { "counts": stationCounts, } - t := tmpl - if t == nil { - http.Error(w, "template not ready", http.StatusInternalServerError) - return + page := parsePage(r.URL.Query().Get("page")) + pagedRows, hasMore := PaginateArrivalRows(filteredRows, page, defaultPageSize) + visibleCount := page * defaultPageSize + if visibleCount > len(filteredRows) { + visibleCount = len(filteredRows) } - data := pageData{ + + return pageData{ Username: username, CurrentProject: project, Date: selectedDate, @@ -115,14 +126,61 @@ func Index(w http.ResponseWriter, r *http.Request) { Search: r.URL.Query().Get("search"), Department: r.URL.Query().Get("dept"), Rows: rows, - FilteredRows: filteredRows, + FilteredRows: pagedRows, Summary: summary, Departments: deptStats, DepartmentOptions: deptOptions, OverviewJSON: toJS(overview), DepartmentJSON: toJS(stationChart), + Page: page, + PageSize: defaultPageSize, + HasMore: hasMore, + VisibleCount: visibleCount, + TotalFiltered: len(filteredRows), + NextPage: page + 1, + }, http.StatusOK, nil +} + +func Index(w http.ResponseWriter, r *http.Request) { + t := tmpl + if t == nil { + http.Error(w, "template not ready", http.StatusInternalServerError) + return } + + data, status, err := buildArrivalData(r) + if err != nil { + http.Error(w, "query error", status) + return + } + if status == http.StatusSeeOther { + http.Redirect(w, r, basePath+"/projects", http.StatusSeeOther) + return + } + if err := t.ExecuteTemplate(w, "base", data); err != nil { http.Error(w, "template error", http.StatusInternalServerError) } } + +func List(w http.ResponseWriter, r *http.Request) { + t := tmpl + if t == nil { + http.Error(w, "template not ready", http.StatusInternalServerError) + return + } + + data, status, err := buildArrivalData(r) + if err != nil { + http.Error(w, "query error", status) + return + } + if status == http.StatusSeeOther { + http.Error(w, "unauthorized", http.StatusUnauthorized) + return + } + + if err := t.ExecuteTemplate(w, "arrival-list-chunk", data); err != nil { + http.Error(w, "template error", http.StatusInternalServerError) + } +} diff --git a/cpone-dashboard/menu/arrival/query.go b/cpone-dashboard/menu/arrival/query.go index 2205116..7520238 100644 --- a/cpone-dashboard/menu/arrival/query.go +++ b/cpone-dashboard/menu/arrival/query.go @@ -270,6 +270,24 @@ func FilterArrivalRows(rows []ArrivalRow, search, dept string) []ArrivalRow { return out } +func PaginateArrivalRows(rows []ArrivalRow, page, pageSize int) ([]ArrivalRow, bool) { + if page < 1 { + page = 1 + } + if pageSize < 1 { + pageSize = 30 + } + start := (page - 1) * pageSize + if start >= len(rows) { + return []ArrivalRow{}, false + } + end := start + pageSize + if end > len(rows) { + end = len(rows) + } + return rows[start:end], end < len(rows) +} + func UniqueDepartments(rows []ArrivalRow) []string { seen := map[string]struct{}{} var out []string diff --git a/cpone-dashboard/menu/arrival/route.go b/cpone-dashboard/menu/arrival/route.go index 53fd8a9..c9104eb 100644 --- a/cpone-dashboard/menu/arrival/route.go +++ b/cpone-dashboard/menu/arrival/route.go @@ -4,4 +4,5 @@ import "github.com/go-chi/chi/v5" func Routes(r chi.Router) { r.Get("/", Index) + r.Get("/list", List) } diff --git a/cpone-dashboard/menu/progress/handler.go b/cpone-dashboard/menu/progress/handler.go index 7bc5a91..f23cca8 100644 --- a/cpone-dashboard/menu/progress/handler.go +++ b/cpone-dashboard/menu/progress/handler.go @@ -5,11 +5,14 @@ import ( "cpone-dashboard/menu/projects" "html/template" "net/http" + "strconv" ) var tmpl *template.Template var basePath string +const defaultPageSize = 30 + func SetTemplates(t *template.Template) { tmpl = t } func SetBasePath(p string) { basePath = p } @@ -23,52 +26,108 @@ type pageData struct { Summary ProgressSummary ValidatedPct int PublishedPct int + Page int + PageSize int + HasMore bool + VisibleCount int + TotalFiltered int + NextPage int } -func Index(w http.ResponseWriter, r *http.Request) { +func parsePage(q string) int { + p, err := strconv.Atoi(q) + if err != nil || p < 1 { + return 1 + } + return p +} + +func buildProgressData(r *http.Request) (pageData, int, error) { username := auth.Username(r) mcuID := auth.SelectedProjectID(r) if mcuID == 0 { - http.Redirect(w, r, basePath+"/projects", http.StatusSeeOther) - return + return pageData{}, http.StatusSeeOther, nil } project, ok, err := projects.GetUserProject(username, mcuID) if err != nil { - http.Error(w, "query error", http.StatusInternalServerError) - return + return pageData{}, http.StatusInternalServerError, err } if !ok { - http.Redirect(w, r, basePath+"/projects", http.StatusSeeOther) - return + return pageData{}, http.StatusSeeOther, nil } rows, err := GetProgressRows(mcuID) if err != nil { - http.Error(w, "query error", http.StatusInternalServerError) - return + return pageData{}, http.StatusInternalServerError, err } summary := BuildProgressSummary(rows) search := r.URL.Query().Get("search") status := r.URL.Query().Get("status") filteredRows := FilterProgressRows(rows, search, status) - - t := tmpl - if t == nil { - http.Error(w, "template not ready", http.StatusInternalServerError) - return + page := parsePage(r.URL.Query().Get("page")) + pagedRows, hasMore := PaginateProgressRows(filteredRows, page, defaultPageSize) + visibleCount := page * defaultPageSize + if visibleCount > len(filteredRows) { + visibleCount = len(filteredRows) } - if err := t.ExecuteTemplate(w, "base", pageData{ + + return pageData{ Username: username, CurrentProject: project, Search: search, Status: status, Rows: rows, - FilteredRows: filteredRows, + FilteredRows: pagedRows, Summary: summary, ValidatedPct: Pct(summary.Validated, summary.Total), PublishedPct: Pct(summary.Published, summary.Total), - }); err != nil { + Page: page, + PageSize: defaultPageSize, + HasMore: hasMore, + VisibleCount: visibleCount, + TotalFiltered: len(filteredRows), + NextPage: page + 1, + }, http.StatusOK, nil +} + +func Index(w http.ResponseWriter, r *http.Request) { + t := tmpl + if t == nil { + http.Error(w, "template not ready", http.StatusInternalServerError) + return + } + + data, status, err := buildProgressData(r) + if err != nil { + http.Error(w, "query error", status) + return + } + if status == http.StatusSeeOther { + http.Redirect(w, r, basePath+"/projects", http.StatusSeeOther) + return + } + if err := t.ExecuteTemplate(w, "base", data); err != nil { + http.Error(w, "template error", http.StatusInternalServerError) + } +} + +func List(w http.ResponseWriter, r *http.Request) { + t := tmpl + if t == nil { + http.Error(w, "template not ready", http.StatusInternalServerError) + return + } + data, status, err := buildProgressData(r) + if err != nil { + http.Error(w, "query error", status) + return + } + if status == http.StatusSeeOther { + http.Error(w, "unauthorized", http.StatusUnauthorized) + return + } + if err := t.ExecuteTemplate(w, "progress-list-chunk", data); err != nil { http.Error(w, "template error", http.StatusInternalServerError) } } diff --git a/cpone-dashboard/menu/progress/query.go b/cpone-dashboard/menu/progress/query.go index a6e8737..015a370 100644 --- a/cpone-dashboard/menu/progress/query.go +++ b/cpone-dashboard/menu/progress/query.go @@ -118,3 +118,21 @@ func Pct(num, total int) int { } return num * 100 / total } + +func PaginateProgressRows(rows []ProgressRow, page, pageSize int) ([]ProgressRow, bool) { + if page < 1 { + page = 1 + } + if pageSize < 1 { + pageSize = 30 + } + start := (page - 1) * pageSize + if start >= len(rows) { + return []ProgressRow{}, false + } + end := start + pageSize + if end > len(rows) { + end = len(rows) + } + return rows[start:end], end < len(rows) +} diff --git a/cpone-dashboard/menu/progress/route.go b/cpone-dashboard/menu/progress/route.go index e8eaaf9..07099a7 100644 --- a/cpone-dashboard/menu/progress/route.go +++ b/cpone-dashboard/menu/progress/route.go @@ -4,4 +4,5 @@ import "github.com/go-chi/chi/v5" func Routes(r chi.Router) { r.Get("/", Index) + r.Get("/list", List) } diff --git a/cpone-dashboard/menu/result/handler.go b/cpone-dashboard/menu/result/handler.go index 140dc1e..7c25f0d 100644 --- a/cpone-dashboard/menu/result/handler.go +++ b/cpone-dashboard/menu/result/handler.go @@ -5,12 +5,15 @@ import ( "cpone-dashboard/menu/projects" "html/template" "net/http" + "strconv" ) var tmpl *template.Template var pdfBaseURL string var basePath string +const defaultPageSize = 30 + func SetTemplates(t *template.Template) { tmpl = t } func SetPDFBaseURL(u string) { pdfBaseURL = u } func SetBasePath(p string) { basePath = p } @@ -24,51 +27,108 @@ type pageData struct { FilteredRows []ResultRow Summary ResultSummary PDFBaseURL string + Page int + PageSize int + HasMore bool + VisibleCount int + TotalFiltered int + NextPage int } -func Index(w http.ResponseWriter, r *http.Request) { +func parsePage(q string) int { + p, err := strconv.Atoi(q) + if err != nil || p < 1 { + return 1 + } + return p +} + +func buildResultData(r *http.Request) (pageData, int, error) { username := auth.Username(r) mcuID := auth.SelectedProjectID(r) if mcuID == 0 { - http.Redirect(w, r, basePath+"/projects", http.StatusSeeOther) - return + return pageData{}, http.StatusSeeOther, nil } project, ok, err := projects.GetUserProject(username, mcuID) if err != nil { - http.Error(w, "query error", http.StatusInternalServerError) - return + return pageData{}, http.StatusInternalServerError, err } if !ok { - http.Redirect(w, r, basePath+"/projects", http.StatusSeeOther) - return + return pageData{}, http.StatusSeeOther, nil } rows, err := GetResultRows(mcuID) if err != nil { - http.Error(w, "query error", http.StatusInternalServerError) - return + return pageData{}, http.StatusInternalServerError, err } summary := BuildResultSummary(rows) search := r.URL.Query().Get("search") filter := r.URL.Query().Get("filter") filteredRows := FilterResultRows(rows, search, filter) - - t := tmpl - if t == nil { - http.Error(w, "template not ready", http.StatusInternalServerError) - return + page := parsePage(r.URL.Query().Get("page")) + pagedRows, hasMore := PaginateResultRows(filteredRows, page, defaultPageSize) + visibleCount := page * defaultPageSize + if visibleCount > len(filteredRows) { + visibleCount = len(filteredRows) } - if err := t.ExecuteTemplate(w, "base", pageData{ + + return pageData{ Username: username, CurrentProject: project, Search: search, Filter: filter, Rows: rows, - FilteredRows: filteredRows, + FilteredRows: pagedRows, Summary: summary, PDFBaseURL: pdfBaseURL, - }); err != nil { + Page: page, + PageSize: defaultPageSize, + HasMore: hasMore, + VisibleCount: visibleCount, + TotalFiltered: len(filteredRows), + NextPage: page + 1, + }, http.StatusOK, nil +} + +func Index(w http.ResponseWriter, r *http.Request) { + t := tmpl + if t == nil { + http.Error(w, "template not ready", http.StatusInternalServerError) + return + } + + data, status, err := buildResultData(r) + if err != nil { + http.Error(w, "query error", status) + return + } + if status == http.StatusSeeOther { + http.Redirect(w, r, basePath+"/projects", http.StatusSeeOther) + return + } + + if err := t.ExecuteTemplate(w, "base", data); err != nil { + http.Error(w, "template error", http.StatusInternalServerError) + } +} + +func List(w http.ResponseWriter, r *http.Request) { + t := tmpl + if t == nil { + http.Error(w, "template not ready", http.StatusInternalServerError) + return + } + data, status, err := buildResultData(r) + if err != nil { + http.Error(w, "query error", status) + return + } + if status == http.StatusSeeOther { + http.Error(w, "unauthorized", http.StatusUnauthorized) + return + } + if err := t.ExecuteTemplate(w, "result-list-chunk", data); err != nil { http.Error(w, "template error", http.StatusInternalServerError) } } diff --git a/cpone-dashboard/menu/result/query.go b/cpone-dashboard/menu/result/query.go index 6a56e45..c54ac5a 100644 --- a/cpone-dashboard/menu/result/query.go +++ b/cpone-dashboard/menu/result/query.go @@ -99,3 +99,21 @@ func FilterResultRows(rows []ResultRow, search, filter string) []ResultRow { } return out } + +func PaginateResultRows(rows []ResultRow, page, pageSize int) ([]ResultRow, bool) { + if page < 1 { + page = 1 + } + if pageSize < 1 { + pageSize = 30 + } + start := (page - 1) * pageSize + if start >= len(rows) { + return []ResultRow{}, false + } + end := start + pageSize + if end > len(rows) { + end = len(rows) + } + return rows[start:end], end < len(rows) +} diff --git a/cpone-dashboard/menu/result/route.go b/cpone-dashboard/menu/result/route.go index 291dd3d..6e7f00e 100644 --- a/cpone-dashboard/menu/result/route.go +++ b/cpone-dashboard/menu/result/route.go @@ -4,4 +4,5 @@ import "github.com/go-chi/chi/v5" func Routes(r chi.Router) { r.Get("/", Index) + r.Get("/list", List) } diff --git a/cpone-dashboard/templates/arrival/index.html b/cpone-dashboard/templates/arrival/index.html index 8fd5ec4..7b5aa2f 100644 --- a/cpone-dashboard/templates/arrival/index.html +++ b/cpone-dashboard/templates/arrival/index.html @@ -39,19 +39,19 @@
-
+

Checked In

-

{{.Summary.CheckedIn}}

+

{{.Summary.CheckedIn}}

Sudah check-in pada tanggal ini

-
+

Not Check-in Yet

-

{{.Summary.Pending}}

+

{{.Summary.Pending}}

Belum masuk ke area MCU

-
+

Total Schedule

-

{{.Summary.Total}}

+

{{.Summary.Total}}

Peserta yang dijadwalkan hari ini

@@ -62,7 +62,8 @@

Check-in Overview

Inner ring: checked-in summary, outer ring: distribution by department / posisi

-
+
+
@@ -105,7 +106,7 @@

Live Arrival List

Tanggal: {{.Date | fmtDate}}

- {{len .FilteredRows}} ditampilkan + {{.VisibleCount}} / {{.TotalFiltered}} ditampilkan
@@ -128,7 +129,7 @@ Status - + {{range .FilteredRows}} {{if .InTime}}{{.InTime}}{{else}}-{{end}} @@ -166,44 +167,91 @@
-
+
{{range .FilteredRows}}

{{.Name}}

{{if .InTime}}{{.InTime}}{{else}}-{{end}} • {{.NIP}} • {{.Department}}

-
+
{{if .Stations}} {{range .Stations}} {{if eq .Tone "success"}} - {{.Name}} + + + + + {{.Name}} + {{else if eq .Tone "warning"}} - {{.Name}} + + + + + {{.Name}} + {{else if eq .Tone "danger"}} - {{.Name}} + + + + + {{.Name}} + {{else}} - {{.Name}} + + + + + {{.Name}} + {{end}} {{end}} {{else}} {{if eq .StatusTone "success"}} - {{.Status}} + + + + + {{.Status}} + {{else if eq .StatusTone "warning"}} - {{.Status}} + + + + + {{.Status}} + {{else}} - {{.Status}} + + + + + {{.Status}} + {{end}} {{end}}
{{end}}
+
+ {{if .HasMore}} +
+ Memuat data berikutnya... +
+ {{else}} +
Semua data sudah ditampilkan
+ {{end}} +
{{else}}
Belum ada data arrival pada tanggal ini.
{{end}} - {{end}} + +{{define "arrival-list-chunk"}} + + {{range .FilteredRows}} + + {{if .InTime}}{{.InTime}}{{else}}-{{end}} + {{.NIP}} + {{.Name}} + {{.Department}} + + {{if .Stations}} +
+ {{range .Stations}} + {{if eq .Tone "success"}} + {{.Name}} + {{else if eq .Tone "warning"}} + {{.Name}} + {{else if eq .Tone "danger"}} + {{.Name}} + {{else}} + {{.Name}} + {{end}} + {{end}} +
+ {{else}} + {{if eq .StatusTone "success"}} + {{.Status}} + {{else if eq .StatusTone "warning"}} + {{.Status}} + {{else}} + {{.Status}} + {{end}} + {{end}} + + + {{end}} + + +
+ {{range .FilteredRows}} +
+

{{.Name}}

+

{{if .InTime}}{{.InTime}}{{else}}-{{end}} • {{.NIP}} • {{.Department}}

+
+ {{if .Stations}} + {{range .Stations}} + {{if eq .Tone "success"}} + + + {{.Name}} + + {{else if eq .Tone "warning"}} + + + {{.Name}} + + {{else if eq .Tone "danger"}} + + + {{.Name}} + + {{else}} + + + {{.Name}} + + {{end}} + {{end}} + {{else}} + {{if eq .StatusTone "success"}} + + + {{.Status}} + + {{else if eq .StatusTone "warning"}} + + + {{.Status}} + + {{else}} + + + {{.Status}} + + {{end}} + {{end}} +
+
+ {{end}} +
+ +
+ {{if .HasMore}} +
+ Memuat data berikutnya... +
+ {{else}} +
Semua data sudah ditampilkan
+ {{end}} +
+{{end}} diff --git a/cpone-dashboard/templates/dashboard/index.html b/cpone-dashboard/templates/dashboard/index.html index bdf5664..ecfb0bb 100644 --- a/cpone-dashboard/templates/dashboard/index.html +++ b/cpone-dashboard/templates/dashboard/index.html @@ -207,22 +207,16 @@ Lihat - {{if gt .KPI.InvitedStaff 0}} -
-

Invited Staff

-

{{.KPI.InvitedStaff}}

-
- {{end}}
-
- {{range $i := seq 3}} + {{range $i := seq 4}}
{{end}}
diff --git a/cpone-dashboard/templates/dashboard/partials/kpi.html b/cpone-dashboard/templates/dashboard/partials/kpi.html index 7cd3fa7..fce8c92 100644 --- a/cpone-dashboard/templates/dashboard/partials/kpi.html +++ b/cpone-dashboard/templates/dashboard/partials/kpi.html @@ -1,4 +1,16 @@ {{define "kpi"}} + +
+
+

Invited Staff

+ + + +
+

{{.InvitedStaff}}

+

Total staff undangan

+
+
diff --git a/cpone-dashboard/templates/dashboard/partials/stations.html b/cpone-dashboard/templates/dashboard/partials/stations.html index de16015..d93c07c 100644 --- a/cpone-dashboard/templates/dashboard/partials/stations.html +++ b/cpone-dashboard/templates/dashboard/partials/stations.html @@ -8,15 +8,15 @@ {{end}}
{{if .Rows}} -
- +
+
- + - + @@ -29,7 +29,7 @@ - + - + {{range .FilteredRows}} @@ -160,7 +160,7 @@
StationSudah Belum TotalProgressProgress
{{.Station | stationShort}} {{.Processed}} {{.Pending}} {{.Total}} diff --git a/cpone-dashboard/templates/layout/base.html b/cpone-dashboard/templates/layout/base.html index 1efab2c..9e3c1e0 100644 --- a/cpone-dashboard/templates/layout/base.html +++ b/cpone-dashboard/templates/layout/base.html @@ -53,16 +53,27 @@ -
-
+
+
Logo -
+

{{block "header-title" .}}Dashboard{{end}}

+
+
{{block "content" .}}{{end}}
+ {{end}} diff --git a/cpone-dashboard/templates/progress/index.html b/cpone-dashboard/templates/progress/index.html index ff17e48..132881b 100644 --- a/cpone-dashboard/templates/progress/index.html +++ b/cpone-dashboard/templates/progress/index.html @@ -23,19 +23,19 @@
-
+

Total Patients

-

{{.Summary.Total}}

+

{{.Summary.Total}}

Peserta dalam project ini

-
+

Validated

-

{{.Summary.Validated}}

+

{{.Summary.Validated}}

Resume sudah divalidasi dokter

-
+

Published

-

{{.Summary.Published}}

+

{{.Summary.Published}}

Hasil sudah diupload

@@ -102,7 +102,7 @@

Patient Resume List

Data dari mcu_patient_resume_status

- {{len .FilteredRows}} ditampilkan + {{.VisibleCount}} / {{.TotalFiltered}} ditampilkan
@@ -127,7 +127,7 @@
Published
{{.Name}}
-
+
{{range .FilteredRows}}
@@ -187,6 +187,19 @@
{{end}}
+
+ {{if .HasMore}} +
+ Memuat data berikutnya... +
+ {{else}} +
Semua data sudah ditampilkan
+ {{end}} +
{{else}}
Belum ada data resume untuk project ini. @@ -215,3 +228,78 @@ })(); {{end}} + +{{define "progress-list-chunk"}} + + {{range .FilteredRows}} + + {{.Name}} + {{.NIP}} + {{.Posisi}} + + {{if .ResumeStatus}} + {{.ResumeStatus}} + {{else}} + + {{end}} + + + {{if eq .Validated "Y"}} + Y + {{else}} + N + {{end}} + + + {{if eq .Published "Y"}} + Y + {{else}} + N + {{end}} + + + {{end}} + + +
+ {{range .FilteredRows}} +
+
+
+

{{.Name}}

+

{{.NIP}} • {{.Posisi}}

+
+ {{if .ResumeStatus}} + {{.ResumeStatus}} + {{end}} +
+
+ {{if eq .Validated "Y"}} + Validated + {{else}} + Not Validated + {{end}} + {{if eq .Published "Y"}} + Published + {{else}} + Not Published + {{end}} +
+
+ {{end}} +
+ +
+ {{if .HasMore}} +
+ Memuat data berikutnya... +
+ {{else}} +
Semua data sudah ditampilkan
+ {{end}} +
+{{end}} diff --git a/cpone-dashboard/templates/result/index.html b/cpone-dashboard/templates/result/index.html index 80d072a..e4cf595 100644 --- a/cpone-dashboard/templates/result/index.html +++ b/cpone-dashboard/templates/result/index.html @@ -25,14 +25,14 @@ {{/* Section 2: Summary cards */}}
-
+

Total Patients

-

{{.Summary.Total}}

+

{{.Summary.Total}}

Peserta dalam project ini

-
-

Has PDF

-

{{.Summary.HasPDF}}

+
+

Sudah Ada Report Hasil

+

{{.Summary.HasPDF}}

Laporan hasil sudah tersedia

@@ -69,7 +69,7 @@

Patient Result List

Data dari published_mcu_dashboard_sync

- {{len .FilteredRows}} ditampilkan + {{.VisibleCount}} / {{.TotalFiltered}} ditampilkan
{{if .FilteredRows}} @@ -84,7 +84,7 @@ Action - + {{range .FilteredRows}} {{.NIP}} @@ -109,7 +109,7 @@ -
+
{{range .FilteredRows}}
@@ -130,6 +130,19 @@
{{end}}
+
+ {{if .HasMore}} +
+ Memuat data berikutnya... +
+ {{else}} +
Semua data sudah ditampilkan
+ {{end}} +
{{else}}
Belum ada data untuk project ini. @@ -196,3 +209,64 @@ document.addEventListener('keydown', function(e) { }); {{end}} + +{{define "result-list-chunk"}} + + {{range .FilteredRows}} + + {{.NIP}} + {{.Name}} + {{.Posisi}} + + {{if .ReportDate}}{{.ReportDate | fmtDate}}{{else}}{{end}} + + + {{if .FileUrl}} + + {{else}} + + {{end}} + + + {{end}} + + +
+ {{range .FilteredRows}} +
+
+
+

{{.Name}}

+

{{.NIP}} • {{.Posisi}}

+ {{if .ReportDate}}

{{.ReportDate | fmtDate}}

{{end}} +
+ {{if .FileUrl}} + + {{else}} + No PDF + {{end}} +
+
+ {{end}} +
+ +
+ {{if .HasMore}} +
+ Memuat data berikutnya... +
+ {{else}} +
Semua data sudah ditampilkan
+ {{end}} +
+{{end}}