From d14a7f028f9f4a6a2dd9bd7dfdf705dafb77f63b Mon Sep 17 00:00:00 2001 From: Azareal Date: Mon, 29 Apr 2019 11:28:55 +1000 Subject: [PATCH] Panel Dashboard now uses dyntmpl to make it a little bit faster. Fixed a bug in the dashboard where report stats were being fetched by day rather than by week. Reduced the amount of boilerplate in the dashboard with the GE type alias. Tweaked the colour of hguides on Cosora. Added the panel template. Added the panel_dashboard_cpu_desc phrase. Added the panel_dashboard_ram_desc phrase. Added the panel_dashboard_online_desc phrase. Added the panel_dashboard_guests_online_desc phrase. Added the panel_dashboard_users_online_desc phrase. Added the panel_dashboard_coming_soon phrase. --- common/pages.go | 8 ++++ common/template_init.go | 3 ++ langs/english.json | 6 +++ routes/panel/common.go | 1 + routes/panel/dashboard.go | 84 ++++++++++++++++++---------------- templates/panel.html | 9 ++++ templates/panel_dashboard.html | 12 +---- themes/cosora/public/panel.css | 1 + 8 files changed, 74 insertions(+), 50 deletions(-) create mode 100644 templates/panel.html diff --git a/common/pages.go b/common/pages.go index d3f9257b..e498ed9b 100644 --- a/common/pages.go +++ b/common/pages.go @@ -279,6 +279,14 @@ type ResetPage struct { MFA bool } +/* WIP for dyntmpl */ +type Panel struct { + *BasePanelPage + HTMLID string + TmplName string + Inner nobreak +} + type PanelStats struct { Users int Groups int diff --git a/common/template_init.go b/common/template_init.go index 6698e9e5..dc6797b6 100644 --- a/common/template_init.go +++ b/common/template_init.go @@ -300,6 +300,9 @@ func compileTemplates(wg *sync.WaitGroup, c *tmpl.CTemplateSet, themeName string accountPage := Account{header, "dashboard", "account_own_edit", inter} tmpls.AddStd("account", "common.Account", accountPage) + basePage := &BasePanelPage{header, PanelStats{}, "dashboard", ReportForumID} + tmpls.AddStd("panel", "common.Panel", Panel{basePage, "panel_dashboard_right","panel_dashboard", inter}) + var writeTemplate = func(name string, content interface{}) { log.Print("Writing template '" + name + "'") var writeTmpl = func(name string, content string) { diff --git a/langs/english.json b/langs/english.json index 6941f83f..b66ff2a4 100644 --- a/langs/english.json +++ b/langs/english.json @@ -751,11 +751,17 @@ "panel_menu_debug":"Debug", "panel_dashboard_head":"Dashboard", + "panel_dashboard_cpu_desc":"The global CPU usage of this server", + "panel_dashboard_ram_desc":"The global RAM usage of this server", "panel_dashboard_online": "%d%s online", + "panel_dashboard_online_desc":"The number of people who are currently online", "panel_dashboard_guests_online":"%d%s guests online", + "panel_dashboard_guests_online_desc":"The number of guests who are currently online", "panel_dashboard_users_online":"%d%s users online", + "panel_dashboard_users_online_desc":"The number of logged-in users who are currently online", "panel_dashboard_day_suffix":" / day", "panel_dashboard_week_suffix":" / week", + "panel_dashboard_coming_soon":"Coming Soon!", "panel_users_head":"Users", "panel_users_profile":"Profile", diff --git a/routes/panel/common.go b/routes/panel/common.go index 4f7e8e02..1c9453d5 100644 --- a/routes/panel/common.go +++ b/routes/panel/common.go @@ -21,6 +21,7 @@ func successRedirect(dest string, w http.ResponseWriter, r *http.Request, isJs b return nil } +// TODO: Prerender needs to handle dyntmpl templates better... func renderTemplate(tmplName string, w http.ResponseWriter, r *http.Request, header *c.Header, pi interface{}) c.RouteError { header.AddScript("global.js") if c.RunPreRenderHook("pre_render_"+tmplName, w, r, &header.CurrentUser, pi) { diff --git a/routes/panel/dashboard.go b/routes/panel/dashboard.go index c22a17be..460b220f 100644 --- a/routes/panel/dashboard.go +++ b/routes/panel/dashboard.go @@ -7,7 +7,7 @@ import ( "strconv" c "github.com/Azareal/Gosora/common" - "github.com/Azareal/Gosora/common/phrases" + p "github.com/Azareal/Gosora/common/phrases" "github.com/Azareal/Gosora/query_gen" "github.com/Azareal/gopsutil/mem" "github.com/pkg/errors" @@ -18,25 +18,27 @@ type dashStmts struct { todaysTopicCount *sql.Stmt todaysTopicCountByForum *sql.Stmt todaysNewUserCount *sql.Stmt + weeklyTopicCountByForum *sql.Stmt } // TODO: Stop hard-coding these queries func dashMySQLStmts() (stmts dashStmts, err error) { db := qgen.Builder.GetConn() - var prepareStmt = func(table string, ext string) *sql.Stmt { + var prepareStmt = func(table string, ext string, dur string) *sql.Stmt { if err != nil { return nil } - stmt, ierr := db.Prepare("select count(*) from " + table + " where createdAt BETWEEN (utc_timestamp() - interval 1 day) and utc_timestamp() " + ext) + stmt, ierr := db.Prepare("select count(*) from " + table + " where createdAt BETWEEN (utc_timestamp() - interval 1 "+dur+") and utc_timestamp() " + ext) err = errors.WithStack(ierr) return stmt } - stmts.todaysPostCount = prepareStmt("replies", "") - stmts.todaysTopicCount = prepareStmt("topics", "") - stmts.todaysNewUserCount = prepareStmt("users", "") - stmts.todaysTopicCountByForum = prepareStmt("topics", " and parentID = ?") + stmts.todaysPostCount = prepareStmt("replies", "","day") + stmts.todaysTopicCount = prepareStmt("topics", "","day") + stmts.todaysNewUserCount = prepareStmt("users", "","day") + stmts.todaysTopicCountByForum = prepareStmt("topics", " and parentID = ?","day") + stmts.weeklyTopicCountByForum = prepareStmt("topics", " and parentID = ?","week") return stmts, err } @@ -45,23 +47,26 @@ func dashMySQLStmts() (stmts dashStmts, err error) { func dashMSSQLStmts() (stmts dashStmts, err error) { db := qgen.Builder.GetConn() - var prepareStmt = func(table string, ext string) *sql.Stmt { + var prepareStmt = func(table string, ext string, dur string) *sql.Stmt { if err != nil { return nil } - stmt, ierr := db.Prepare("select count(*) from " + table + " where createdAt >= DATEADD(DAY, -1, GETUTCDATE())" + ext) + stmt, ierr := db.Prepare("select count(*) from " + table + " where createdAt >= DATEADD("+dur+", -1, GETUTCDATE())" + ext) err = errors.WithStack(ierr) return stmt } - stmts.todaysPostCount = prepareStmt("replies", "") - stmts.todaysTopicCount = prepareStmt("topics", "") - stmts.todaysNewUserCount = prepareStmt("users", "") - stmts.todaysTopicCountByForum = prepareStmt("topics", " and parentID = ?") + stmts.todaysPostCount = prepareStmt("replies", "","DAY") + stmts.todaysTopicCount = prepareStmt("topics", "","DAY") + stmts.todaysNewUserCount = prepareStmt("users", "","DAY") + stmts.todaysTopicCountByForum = prepareStmt("topics", " and parentID = ?","DAY") + stmts.weeklyTopicCountByForum = prepareStmt("topics", " and parentID = ?","WEEK") return stmts, err } +type GE = c.GridElement + func Dashboard(w http.ResponseWriter, r *http.Request, user c.User) c.RouteError { basePage, ferr := buildBasePage(w, r, &user, "dashboard", "dashboard") if ferr != nil { @@ -143,18 +148,18 @@ func Dashboard(w http.ResponseWriter, r *http.Request, user c.User) c.RouteError // TODO: Allow for more complex phrase structures than just suffixes var postCount = extractStat(stmts.todaysPostCount) - var postInterval = phrases.GetTmplPhrase("panel_dashboard_day_suffix") + var postInterval = p.GetTmplPhrase("panel_dashboard_day_suffix") var postColour = greaterThanSwitch(postCount, 5, 25) var topicCount = extractStat(stmts.todaysTopicCount) - var topicInterval = phrases.GetTmplPhrase("panel_dashboard_day_suffix") + var topicInterval = p.GetTmplPhrase("panel_dashboard_day_suffix") var topicColour = greaterThanSwitch(topicCount, 0, 8) - var reportCount = extractStat(stmts.todaysTopicCountByForum, c.ReportForumID) - var reportInterval = phrases.GetTmplPhrase("panel_dashboard_week_suffix") + var reportCount = extractStat(stmts.weeklyTopicCountByForum, c.ReportForumID) + var reportInterval = p.GetTmplPhrase("panel_dashboard_week_suffix") var newUserCount = extractStat(stmts.todaysNewUserCount) - var newUserInterval = phrases.GetTmplPhrase("panel_dashboard_week_suffix") + var newUserInterval = p.GetTmplPhrase("panel_dashboard_week_suffix") // Did any of the extractStats fail? if intErr != nil { @@ -162,15 +167,15 @@ func Dashboard(w http.ResponseWriter, r *http.Request, user c.User) c.RouteError } // TODO: Localise these - var gridElements = []c.GridElement{ + var gridElements = []GE{ // TODO: Implement a check for new versions of Gosora - //c.GridElement{"dash-version", "v" + version.String(), 0, "grid_istat stat_green", "", "", "Gosora is up-to-date :)"}, - c.GridElement{"dash-version", "v" + c.SoftwareVersion.String(), 0, "grid_istat", "", "", ""}, + //GE{"dash-version", "v" + version.String(), 0, "grid_istat stat_green", "", "", "Gosora is up-to-date :)"}, + GE{"dash-version", "v" + c.SoftwareVersion.String(), 0, "grid_istat", "", "", ""}, - c.GridElement{"dash-cpu", "CPU: " + cpustr, 1, "grid_istat " + cpuColour, "", "", "The global CPU usage of this server"}, - c.GridElement{"dash-ram", "RAM: " + ramstr, 2, "grid_istat " + ramColour, "", "", "The global RAM usage of this server"}, + GE{"dash-cpu", "CPU: " + cpustr, 1, "grid_istat " + cpuColour, "", "", p.GetTmplPhrase("panel_dashboard_cpu_desc")}, + GE{"dash-ram", "RAM: " + ramstr, 2, "grid_istat " + ramColour, "", "", p.GetTmplPhrase("panel_dashboard_ram_desc")}, } - var addElement = func(element c.GridElement) { + var addElement = func(element GE) { gridElements = append(gridElements, element) } @@ -178,7 +183,7 @@ func Dashboard(w http.ResponseWriter, r *http.Request, user c.User) c.RouteError uonline := c.WsHub.UserCount() gonline := c.WsHub.GuestCount() totonline := uonline + gonline - reqCount := 0 + //reqCount := 0 var onlineColour = greaterThanSwitch(totonline, 3, 10) var onlineGuestsColour = greaterThanSwitch(gonline, 1, 10) @@ -188,26 +193,25 @@ func Dashboard(w http.ResponseWriter, r *http.Request, user c.User) c.RouteError uonline, uunit := c.ConvertFriendlyUnit(uonline) gonline, gunit := c.ConvertFriendlyUnit(gonline) - addElement(c.GridElement{"dash-totonline", phrases.GetTmplPhrasef("panel_dashboard_online", totonline, totunit), 3, "grid_stat " + onlineColour, "", "", "The number of people who are currently online"}) - addElement(c.GridElement{"dash-gonline", phrases.GetTmplPhrasef("panel_dashboard_guests_online", gonline, gunit), 4, "grid_stat " + onlineGuestsColour, "", "", "The number of guests who are currently online"}) - addElement(c.GridElement{"dash-uonline", phrases.GetTmplPhrasef("panel_dashboard_users_online", uonline, uunit), 5, "grid_stat " + onlineUsersColour, "", "", "The number of logged-in users who are currently online"}) - addElement(c.GridElement{"dash-reqs", strconv.Itoa(reqCount) + " reqs / second", 7, "grid_stat grid_end_group " + topicColour, "", "", "The number of requests over the last 24 hours"}) + addElement(GE{"dash-totonline", p.GetTmplPhrasef("panel_dashboard_online", totonline, totunit), 3, "grid_stat " + onlineColour, "", "", p.GetTmplPhrase("panel_dashboard_online_desc")}) + addElement(GE{"dash-gonline", p.GetTmplPhrasef("panel_dashboard_guests_online", gonline, gunit), 4, "grid_stat " + onlineGuestsColour, "", "", p.GetTmplPhrase("panel_dashboard_guests_online_desc")}) + addElement(GE{"dash-uonline", p.GetTmplPhrasef("panel_dashboard_users_online", uonline, uunit), 5, "grid_stat " + onlineUsersColour, "", "", p.GetTmplPhrase("panel_dashboard_users_online_desc")}) + //addElement(GE{"dash-reqs", strconv.Itoa(reqCount) + " reqs / second", 7, "grid_stat grid_end_group " + topicColour, "", "", "The number of requests over the last 24 hours"}) } - addElement(c.GridElement{"dash-postsperday", strconv.Itoa(postCount) + " posts" + postInterval, 6, "grid_stat " + postColour, "", "", "The number of new posts over the last 24 hours"}) - addElement(c.GridElement{"dash-topicsperday", strconv.Itoa(topicCount) + " topics" + topicInterval, 7, "grid_stat " + topicColour, "", "", "The number of new topics over the last 24 hours"}) - addElement(c.GridElement{"dash-totonlineperday", "20 online / day", 8, "grid_stat stat_disabled", "", "", "Coming Soon!" /*, "The people online over the last 24 hours"*/}) + addElement(GE{"dash-postsperday", strconv.Itoa(postCount) + " posts" + postInterval, 6, "grid_stat " + postColour, "", "", "The number of new posts over the last 24 hours"}) + addElement(GE{"dash-topicsperday", strconv.Itoa(topicCount) + " topics" + topicInterval, 7, "grid_stat " + topicColour, "", "", "The number of new topics over the last 24 hours"}) + addElement(GE{"dash-totonlineperday", "?? online / day", 8, "grid_stat stat_disabled", "", "", p.GetTmplPhrase("panel_dashboard_coming_soon") /*, "The people online over the last 24 hours"*/}) - addElement(c.GridElement{"dash-searches", "8 searches / week", 9, "grid_stat stat_disabled", "", "", "Coming Soon!" /*"The number of searches over the last 7 days"*/}) - addElement(c.GridElement{"dash-newusers", strconv.Itoa(newUserCount) + " new users" + newUserInterval, 10, "grid_stat", "", "", "The number of new users over the last 7 days"}) - addElement(c.GridElement{"dash-reports", strconv.Itoa(reportCount) + " reports" + reportInterval, 11, "grid_stat", "", "", "The number of reports over the last 7 days"}) + addElement(GE{"dash-searches", "?? searches / week", 9, "grid_stat stat_disabled", "", "", p.GetTmplPhrase("panel_dashboard_coming_soon") /*"The number of searches over the last 7 days"*/}) + addElement(GE{"dash-newusers", strconv.Itoa(newUserCount) + " new users" + newUserInterval, 10, "grid_stat", "", "", "The number of new users over the last 7 days"}) + addElement(GE{"dash-reports", strconv.Itoa(reportCount) + " reports" + reportInterval, 11, "grid_stat", "", "", "The number of reports over the last 7 days"}) if false { - addElement(c.GridElement{"dash-minperuser", "2 minutes / user / week", 12, "grid_stat stat_disabled", "", "", "Coming Soon!" /*"The average number of number of minutes spent by each active user over the last 7 days"*/}) - addElement(c.GridElement{"dash-visitorsperweek", "2 visitors / week", 13, "grid_stat stat_disabled", "", "", "Coming Soon!" /*"The number of unique visitors we've had over the last 7 days"*/}) - addElement(c.GridElement{"dash-postsperuser", "5 posts / user / week", 14, "grid_stat stat_disabled", "", "", "Coming Soon!" /*"The average number of posts made by each active user over the past week"*/}) + addElement(GE{"dash-minperuser", "2 minutes / user / week", 12, "grid_stat stat_disabled", "", "", p.GetTmplPhrase("panel_dashboard_coming_soon") /*"The average number of number of minutes spent by each active user over the last 7 days"*/}) + addElement(GE{"dash-visitorsperweek", "2 visitors / week", 13, "grid_stat stat_disabled", "", "", p.GetTmplPhrase("panel_dashboard_coming_soon") /*"The number of unique visitors we've had over the last 7 days"*/}) + addElement(GE{"dash-postsperuser", "5 posts / user / week", 14, "grid_stat stat_disabled", "", "", p.GetTmplPhrase("panel_dashboard_coming_soon") /*"The average number of posts made by each active user over the past week"*/}) } - pi := c.PanelDashboardPage{basePage, gridElements} - return renderTemplate("panel_dashboard", w, r, basePage.Header, &pi) + return renderTemplate("panel", w, r, basePage.Header, c.Panel{basePage, "panel_dashboard_right","panel_dashboard", gridElements}) } diff --git a/templates/panel.html b/templates/panel.html new file mode 100644 index 00000000..78be733c --- /dev/null +++ b/templates/panel.html @@ -0,0 +1,9 @@ +{{template "header.html" . }} +
+{{template "panel_menu.html" . }} +
+{{template "panel_before_head.html" . }} +{{dyntmpl .TmplName .Inner .Header}} +
+
+{{template "footer.html" . }} \ No newline at end of file diff --git a/templates/panel_dashboard.html b/templates/panel_dashboard.html index c0568df5..ed1817a1 100644 --- a/templates/panel_dashboard.html +++ b/templates/panel_dashboard.html @@ -1,17 +1,9 @@ -{{template "header.html" . }} -
-{{template "panel_menu.html" . }} -
-{{template "panel_before_head.html" . }}

{{lang "panel_dashboard_head"}}

-{{range .GridItems}} +{{range .}}
{{.Body}}
{{end}} -
-
-
-{{template "footer.html" . }} + \ No newline at end of file diff --git a/themes/cosora/public/panel.css b/themes/cosora/public/panel.css index fa9477cd..d53645c4 100644 --- a/themes/cosora/public/panel.css +++ b/themes/cosora/public/panel.css @@ -67,6 +67,7 @@ } .colstack_right .colstack_head h1 + h2.hguide { margin-left: auto; + color: var(--extra-lightened-primary-text-color); } .footer { margin-top: 0px;