Do proper averaging and collect more samples for the memory analytics pane.
Added an ETag for the alerts endpoint when you're not logged to save bandwidth. The Page Manager now uses dyntmpl. The Setting Manager now uses dyntmpl. The Word Filter Manager now uses dyntmpl. Fixed the padding on the noavatar alerts for Nox. Tweaked the panel_word_filters_to phrase. Tweaked the panel_statistics_memory_head phrase. Added the panel_statistics_memory_chart_aria phrase. Added the panel_statistics_memory_table_aria phrase. Added the panel_statistics_memory_no_memory phrase.
This commit is contained in:
parent
5dc238f196
commit
a8e1076f7c
|
@ -1,6 +1,8 @@
|
||||||
package counters
|
package counters
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"time"
|
||||||
|
"sync"
|
||||||
"runtime"
|
"runtime"
|
||||||
"database/sql"
|
"database/sql"
|
||||||
|
|
||||||
|
@ -12,6 +14,9 @@ var MemoryCounter *DefaultMemoryCounter
|
||||||
|
|
||||||
type DefaultMemoryCounter struct {
|
type DefaultMemoryCounter struct {
|
||||||
insert *sql.Stmt
|
insert *sql.Stmt
|
||||||
|
totMem uint64
|
||||||
|
totCount uint64
|
||||||
|
sync.Mutex
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewMemoryCounter(acc *qgen.Accumulator) (*DefaultMemoryCounter, error) {
|
func NewMemoryCounter(acc *qgen.Accumulator) (*DefaultMemoryCounter, error) {
|
||||||
|
@ -21,13 +26,35 @@ func NewMemoryCounter(acc *qgen.Accumulator) (*DefaultMemoryCounter, error) {
|
||||||
c.AddScheduledFifteenMinuteTask(co.Tick)
|
c.AddScheduledFifteenMinuteTask(co.Tick)
|
||||||
//c.AddScheduledSecondTask(co.Tick)
|
//c.AddScheduledSecondTask(co.Tick)
|
||||||
c.AddShutdownTask(co.Tick)
|
c.AddShutdownTask(co.Tick)
|
||||||
|
ticker := time.NewTicker(time.Minute)
|
||||||
|
go func() {
|
||||||
|
for {
|
||||||
|
select {
|
||||||
|
case <-ticker.C:
|
||||||
|
var m runtime.MemStats
|
||||||
|
runtime.ReadMemStats(&m)
|
||||||
|
co.Lock()
|
||||||
|
co.totCount++
|
||||||
|
co.totMem += m.Sys
|
||||||
|
co.Unlock()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}()
|
||||||
return co, acc.FirstError()
|
return co, acc.FirstError()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (co *DefaultMemoryCounter) Tick() (err error) {
|
func (co *DefaultMemoryCounter) Tick() (err error) {
|
||||||
var m runtime.MemStats
|
var m runtime.MemStats
|
||||||
runtime.ReadMemStats(&m)
|
runtime.ReadMemStats(&m)
|
||||||
c.DebugLogf("Inserting a memchunk with a value of %d", m.Sys)
|
var avgMem uint64
|
||||||
_, err = co.insert.Exec(m.Sys)
|
co.Lock()
|
||||||
|
co.totCount++
|
||||||
|
co.totMem += m.Sys
|
||||||
|
avgMem = co.totMem / co.totCount
|
||||||
|
co.totMem = 0
|
||||||
|
co.totCount = 0
|
||||||
|
co.Unlock()
|
||||||
|
c.DebugLogf("Inserting a memchunk with a value of %d", avgMem)
|
||||||
|
_, err = co.insert.Exec(avgMem)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
*
|
*
|
||||||
* Gosora Task System
|
* Gosora Task System
|
||||||
* Copyright Azareal 2017 - 2019
|
* Copyright Azareal 2017 - 2020
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
package common
|
package common
|
||||||
|
|
|
@ -844,7 +844,7 @@
|
||||||
"panel_group_extended_permissions":"Extended Permissions",
|
"panel_group_extended_permissions":"Extended Permissions",
|
||||||
|
|
||||||
"panel_word_filters_head":"Word Filters",
|
"panel_word_filters_head":"Word Filters",
|
||||||
"panel_word_filters_to":"...to...",
|
"panel_word_filters_to":"to",
|
||||||
"panel_word_filters_edit_button_aria":"Edit Word Filter",
|
"panel_word_filters_edit_button_aria":"Edit Word Filter",
|
||||||
"panel_word_filters_update_button":"Update",
|
"panel_word_filters_update_button":"Update",
|
||||||
"panel_word_filters_delete_button_aria":"Delete Word Filter",
|
"panel_word_filters_delete_button_aria":"Delete Word Filter",
|
||||||
|
@ -883,7 +883,7 @@
|
||||||
"panel_statistics_operating_systems_head":"Operating Systems",
|
"panel_statistics_operating_systems_head":"Operating Systems",
|
||||||
"panel_statistics_topic_counts_head":"Topic Counts",
|
"panel_statistics_topic_counts_head":"Topic Counts",
|
||||||
"panel_statistics_requests_head":"Requests",
|
"panel_statistics_requests_head":"Requests",
|
||||||
"panel_statistics_memory_head":"Memory",
|
"panel_statistics_memory_head":"Memory Usage",
|
||||||
|
|
||||||
"panel_statistics_time_range_one_year":"1 year",
|
"panel_statistics_time_range_one_year":"1 year",
|
||||||
"panel_statistics_time_range_three_months":"3 months",
|
"panel_statistics_time_range_three_months":"3 months",
|
||||||
|
@ -897,11 +897,13 @@
|
||||||
"panel_statistics_post_counts_chart_aria":"Post Chart",
|
"panel_statistics_post_counts_chart_aria":"Post Chart",
|
||||||
"panel_statistics_topic_counts_chart_aria":"Topic Chart",
|
"panel_statistics_topic_counts_chart_aria":"Topic Chart",
|
||||||
"panel_statistics_requests_chart_aria":"Requests Chart",
|
"panel_statistics_requests_chart_aria":"Requests Chart",
|
||||||
|
"panel_statistics_memory_chart_aria":"Memory Use Chart",
|
||||||
"panel_statistics_details_head":"Details",
|
"panel_statistics_details_head":"Details",
|
||||||
"panel_statistics_post_counts_table_aria":"Post Table, this has the same information as the post chart",
|
"panel_statistics_post_counts_table_aria":"Post Table, this has the same information as the post chart",
|
||||||
"panel_statistics_topic_counts_table_aria":"Topic Table, this has the same information as the topic chart",
|
"panel_statistics_topic_counts_table_aria":"Topic Table, this has the same information as the topic chart",
|
||||||
"panel_statistics_route_views_table_aria":"View Table, this has the same information as the view chart",
|
"panel_statistics_route_views_table_aria":"View Table, this has the same information as the view chart",
|
||||||
"panel_statistics_requests_table_aria":"View Table, this has the same information as the view chart",
|
"panel_statistics_requests_table_aria":"View Table, this has the same information as the view chart",
|
||||||
|
"panel_statistics_memory_table_aria":"Memory Use Table, this has the same information as the memory use chart",
|
||||||
"panel_statistics_views_suffix":" views",
|
"panel_statistics_views_suffix":" views",
|
||||||
"panel_statistics_posts_suffix":" posts",
|
"panel_statistics_posts_suffix":" posts",
|
||||||
"panel_statistics_topics_suffix":" topics",
|
"panel_statistics_topics_suffix":" topics",
|
||||||
|
@ -913,6 +915,7 @@
|
||||||
"panel_statistics_referrers_no_referrers":"No referrers could be found in the selected time range",
|
"panel_statistics_referrers_no_referrers":"No referrers could be found in the selected time range",
|
||||||
"panel_statistics_routes_no_routes":"No route view counts could be found in the selected time range",
|
"panel_statistics_routes_no_routes":"No route view counts could be found in the selected time range",
|
||||||
"panel_statistics_operating_systems_no_operating_systems":"No operating systems could be found in the selected time range",
|
"panel_statistics_operating_systems_no_operating_systems":"No operating systems could be found in the selected time range",
|
||||||
|
"panel_statistics_memory_no_memory":"No memory chunks could be found in the selected time range",
|
||||||
|
|
||||||
"panel_logs_menu_head":"Logs",
|
"panel_logs_menu_head":"Logs",
|
||||||
"panel_logs_registration_head":"Registrations",
|
"panel_logs_registration_head":"Registrations",
|
||||||
|
|
14
routes.go
14
routes.go
|
@ -67,6 +67,20 @@ func routeAPI(w http.ResponseWriter, r *http.Request, user c.User) c.RouteError
|
||||||
// TODO: Split this into it's own function
|
// TODO: Split this into it's own function
|
||||||
case "alerts": // A feed of events tailored for a specific user
|
case "alerts": // A feed of events tailored for a specific user
|
||||||
if !user.Loggedin {
|
if !user.Loggedin {
|
||||||
|
var etag string
|
||||||
|
_, ok := w.(c.GzipResponseWriter)
|
||||||
|
if ok {
|
||||||
|
etag = "\""+strconv.FormatInt(c.StartTime.Unix(), 10)+"-ng\""
|
||||||
|
} else {
|
||||||
|
etag = "\""+strconv.FormatInt(c.StartTime.Unix(), 10)+"-n\""
|
||||||
|
}
|
||||||
|
w.Header().Set("ETag", etag)
|
||||||
|
if match := r.Header.Get("If-None-Match"); match != "" {
|
||||||
|
if strings.Contains(match, etag) {
|
||||||
|
w.WriteHeader(http.StatusNotModified)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
w.Write(phraseLoginAlerts)
|
w.Write(phraseLoginAlerts)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -119,6 +119,44 @@ func analyticsRowsToViewMap(rows *sql.Rows, labelList []int64, viewMap map[int64
|
||||||
return viewMap, rows.Err()
|
return viewMap, rows.Err()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type pAvg struct {
|
||||||
|
Avg int64
|
||||||
|
Tot int64
|
||||||
|
}
|
||||||
|
|
||||||
|
func analyticsRowsToAverageMap(rows *sql.Rows, labelList []int64, avgMap map[int64]int64) (map[int64]int64, error) {
|
||||||
|
defer rows.Close()
|
||||||
|
for rows.Next() {
|
||||||
|
var count int64
|
||||||
|
var createdAt time.Time
|
||||||
|
err := rows.Scan(&count, &createdAt)
|
||||||
|
if err != nil {
|
||||||
|
return avgMap, err
|
||||||
|
}
|
||||||
|
var unixCreatedAt = createdAt.Unix()
|
||||||
|
// TODO: Bulk log this
|
||||||
|
if c.Dev.SuperDebug {
|
||||||
|
log.Print("count: ", count)
|
||||||
|
log.Print("createdAt: ", createdAt)
|
||||||
|
log.Print("unixCreatedAt: ", unixCreatedAt)
|
||||||
|
}
|
||||||
|
var pAvgMap = make(map[int64]pAvg)
|
||||||
|
for _, value := range labelList {
|
||||||
|
if unixCreatedAt > value {
|
||||||
|
prev := pAvgMap[value]
|
||||||
|
prev.Avg += count
|
||||||
|
prev.Tot++
|
||||||
|
pAvgMap[value] = prev
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for key, pAvg := range pAvgMap {
|
||||||
|
avgMap[key] = pAvg.Avg / pAvg.Tot
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return avgMap, rows.Err()
|
||||||
|
}
|
||||||
|
|
||||||
func PreAnalyticsDetail(w http.ResponseWriter, r *http.Request, user *c.User) (*c.BasePanelPage, c.RouteError) {
|
func PreAnalyticsDetail(w http.ResponseWriter, r *http.Request, user *c.User) (*c.BasePanelPage, c.RouteError) {
|
||||||
basePage, ferr := buildBasePage(w, r, user, "analytics", "analytics")
|
basePage, ferr := buildBasePage(w, r, user, "analytics", "analytics")
|
||||||
if ferr != nil {
|
if ferr != nil {
|
||||||
|
@ -473,46 +511,29 @@ func AnalyticsMemory(w http.ResponseWriter, r *http.Request, user c.User) c.Rout
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return c.LocalError(err.Error(), w, r, user)
|
return c.LocalError(err.Error(), w, r, user)
|
||||||
}
|
}
|
||||||
revLabelList, labelList, viewMap := analyticsTimeRangeToLabelList(timeRange)
|
revLabelList, labelList, avgMap := analyticsTimeRangeToLabelList(timeRange)
|
||||||
|
|
||||||
c.DebugLog("in panel.AnalyticsMemory")
|
c.DebugLog("in panel.AnalyticsMemory")
|
||||||
rows, err := qgen.NewAcc().Select("memchunks").Columns("count, createdAt").DateCutoff("createdAt", timeRange.Quantity, timeRange.Unit).Query()
|
rows, err := qgen.NewAcc().Select("memchunks").Columns("count, createdAt").DateCutoff("createdAt", timeRange.Quantity, timeRange.Unit).Query()
|
||||||
if err != nil && err != sql.ErrNoRows {
|
if err != nil && err != sql.ErrNoRows {
|
||||||
return c.InternalError(err, w, r)
|
return c.InternalError(err, w, r)
|
||||||
}
|
}
|
||||||
viewMap, err = analyticsRowsToViewMap(rows, labelList, viewMap)
|
avgMap, err = analyticsRowsToAverageMap(rows, labelList, avgMap)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return c.InternalError(err, w, r)
|
return c.InternalError(err, w, r)
|
||||||
}
|
}
|
||||||
|
|
||||||
var divBy int64 = 1
|
|
||||||
switch timeRange.Range {
|
|
||||||
case "one-year":
|
|
||||||
divBy = 2 * 30 * 12
|
|
||||||
case "three-months":
|
|
||||||
divBy = 2 * 30 * 3
|
|
||||||
case "one-month":
|
|
||||||
divBy = 2 * 30
|
|
||||||
case "one-week":
|
|
||||||
divBy = 1 * 7
|
|
||||||
case "two-days":
|
|
||||||
divBy = 4
|
|
||||||
case "one-day":
|
|
||||||
divBy = 2
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: Adjust for the missing chunks in week and month
|
// TODO: Adjust for the missing chunks in week and month
|
||||||
var viewList []int64
|
var avgList []int64
|
||||||
var viewItems []c.PanelAnalyticsItemUnit
|
var avgItems []c.PanelAnalyticsItemUnit
|
||||||
for _, value := range revLabelList {
|
for _, value := range revLabelList {
|
||||||
viewMap[value] = viewMap[value] / divBy
|
avgList = append(avgList, avgMap[value])
|
||||||
viewList = append(viewList, viewMap[value])
|
cv, cu := c.ConvertByteUnit(float64(avgMap[value]))
|
||||||
cv, cu := c.ConvertByteUnit(float64(viewMap[value]))
|
avgItems = append(avgItems, c.PanelAnalyticsItemUnit{Time: value, Unit: cu, Count: int64(cv)})
|
||||||
viewItems = append(viewItems, c.PanelAnalyticsItemUnit{Time: value, Unit: cu, Count: int64(cv)})
|
|
||||||
}
|
}
|
||||||
graph := c.PanelTimeGraph{Series: [][]int64{viewList}, Labels: labelList}
|
graph := c.PanelTimeGraph{Series: [][]int64{avgList}, Labels: labelList}
|
||||||
c.DebugLogf("graph: %+v\n", graph)
|
c.DebugLogf("graph: %+v\n", graph)
|
||||||
pi := c.PanelAnalyticsStdUnit{graph, viewItems, timeRange.Range, timeRange.Unit, "time"}
|
pi := c.PanelAnalyticsStdUnit{graph, avgItems, timeRange.Range, timeRange.Unit, "time"}
|
||||||
return renderTemplate("panel", w, r, basePage.Header, c.Panel{basePage, "panel_analytics_right","analytics","panel_analytics_memory", pi})
|
return renderTemplate("panel", w, r, basePage.Header, c.Panel{basePage, "panel_analytics_right","analytics","panel_analytics_memory", pi})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -33,7 +33,7 @@ func Pages(w http.ResponseWriter, r *http.Request, user c.User) c.RouteError {
|
||||||
|
|
||||||
pageList := c.Paginate(pageCount, perPage, 5)
|
pageList := c.Paginate(pageCount, perPage, 5)
|
||||||
pi := c.PanelCustomPagesPage{basePage, cPages, c.Paginator{pageList, page, lastPage}}
|
pi := c.PanelCustomPagesPage{basePage, cPages, c.Paginator{pageList, page, lastPage}}
|
||||||
return renderTemplate("panel_pages", w, r, basePage.Header, &pi)
|
return renderTemplate("panel", w, r, basePage.Header, c.Panel{basePage,"panel_page_list","","panel_pages",&pi})
|
||||||
}
|
}
|
||||||
|
|
||||||
func PagesCreateSubmit(w http.ResponseWriter, r *http.Request, user c.User) c.RouteError {
|
func PagesCreateSubmit(w http.ResponseWriter, r *http.Request, user c.User) c.RouteError {
|
||||||
|
@ -90,7 +90,7 @@ func PagesEdit(w http.ResponseWriter, r *http.Request, user c.User, spid string)
|
||||||
}
|
}
|
||||||
|
|
||||||
pi := c.PanelCustomPageEditPage{basePage, page}
|
pi := c.PanelCustomPageEditPage{basePage, page}
|
||||||
return renderTemplate("panel_pages_edit", w, r, basePage.Header, &pi)
|
return renderTemplate("panel", w, r, basePage.Header, c.Panel{basePage,"panel_page_edit","","panel_pages_edit",&pi})
|
||||||
}
|
}
|
||||||
|
|
||||||
func PagesEditSubmit(w http.ResponseWriter, r *http.Request, user c.User, spid string) c.RouteError {
|
func PagesEditSubmit(w http.ResponseWriter, r *http.Request, user c.User, spid string) c.RouteError {
|
||||||
|
|
|
@ -50,7 +50,7 @@ func Settings(w http.ResponseWriter, r *http.Request, user c.User) c.RouteError
|
||||||
}
|
}
|
||||||
|
|
||||||
pi := c.PanelPage{basePage, tList, settingList}
|
pi := c.PanelPage{basePage, tList, settingList}
|
||||||
return renderTemplate("panel_settings", w, r, basePage.Header, &pi)
|
return renderTemplate("panel", w, r, basePage.Header, c.Panel{basePage,"","","panel_settings",&pi})
|
||||||
}
|
}
|
||||||
|
|
||||||
func SettingEdit(w http.ResponseWriter, r *http.Request, user c.User, sname string) c.RouteError {
|
func SettingEdit(w http.ResponseWriter, r *http.Request, user c.User, sname string) c.RouteError {
|
||||||
|
@ -90,7 +90,7 @@ func SettingEdit(w http.ResponseWriter, r *http.Request, user c.User, sname stri
|
||||||
|
|
||||||
pSetting := &c.PanelSetting{setting, phrases.GetSettingPhrase(setting.Name)}
|
pSetting := &c.PanelSetting{setting, phrases.GetSettingPhrase(setting.Name)}
|
||||||
pi := c.PanelSettingPage{basePage, itemList, pSetting}
|
pi := c.PanelSettingPage{basePage, itemList, pSetting}
|
||||||
return renderTemplate("panel_setting", w, r, basePage.Header, &pi)
|
return renderTemplate("panel", w, r, basePage.Header, c.Panel{basePage,"","","panel_setting",&pi})
|
||||||
}
|
}
|
||||||
|
|
||||||
func SettingEditSubmit(w http.ResponseWriter, r *http.Request, user c.User, sname string) c.RouteError {
|
func SettingEditSubmit(w http.ResponseWriter, r *http.Request, user c.User, sname string) c.RouteError {
|
||||||
|
|
|
@ -25,7 +25,7 @@ func WordFilters(w http.ResponseWriter, r *http.Request, user c.User) c.RouteErr
|
||||||
}
|
}
|
||||||
|
|
||||||
pi := c.PanelPage{basePage, tList, filterList}
|
pi := c.PanelPage{basePage, tList, filterList}
|
||||||
return renderTemplate("panel_word_filters", w, r, basePage.Header, &pi)
|
return renderTemplate("panel", w, r, basePage.Header, c.Panel{basePage,"","","panel_word_filters",&pi})
|
||||||
}
|
}
|
||||||
|
|
||||||
func WordFiltersCreateSubmit(w http.ResponseWriter, r *http.Request, user c.User) c.RouteError {
|
func WordFiltersCreateSubmit(w http.ResponseWriter, r *http.Request, user c.User) c.RouteError {
|
||||||
|
@ -67,7 +67,7 @@ func WordFiltersEdit(w http.ResponseWriter, r *http.Request, user c.User, wfid s
|
||||||
_ = wfid
|
_ = wfid
|
||||||
|
|
||||||
pi := c.PanelPage{basePage, tList, nil}
|
pi := c.PanelPage{basePage, tList, nil}
|
||||||
return renderTemplate("panel_word_filters_edit", w, r, basePage.Header, &pi)
|
return renderTemplate("panel", w, r, basePage.Header, c.Panel{basePage,"","","panel_word_filters_edit",&pi})
|
||||||
}
|
}
|
||||||
|
|
||||||
func WordFiltersEditSubmit(w http.ResponseWriter, r *http.Request, user c.User, wfid string) c.RouteError {
|
func WordFiltersEditSubmit(w http.ResponseWriter, r *http.Request, user c.User, wfid string) c.RouteError {
|
||||||
|
|
|
@ -13,20 +13,20 @@
|
||||||
</div>
|
</div>
|
||||||
<form id="timeRangeForm" name="timeRangeForm" action="/panel/analytics/memory/" method="get"></form>
|
<form id="timeRangeForm" name="timeRangeForm" action="/panel/analytics/memory/" method="get"></form>
|
||||||
<div id="panel_analytics_memory" class="colstack_graph_holder">
|
<div id="panel_analytics_memory" class="colstack_graph_holder">
|
||||||
<div class="ct_chart" aria-label="{{lang "panel_statistics_post_counts_chart_aria"}}"></div>
|
<div class="ct_chart" aria-label="{{lang "panel_statistics_memory_chart_aria"}}"></div>
|
||||||
</div>
|
</div>
|
||||||
<div class="colstack_item colstack_head">
|
<div class="colstack_item colstack_head">
|
||||||
<div class="rowitem">
|
<div class="rowitem">
|
||||||
<h1>{{lang "panel_statistics_details_head"}}</h1>
|
<h1>{{lang "panel_statistics_details_head"}}</h1>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div id="panel_analytics_posts_table" class="colstack_item rowlist" aria-label="{{lang "panel_statistics_post_counts_table_aria"}}">
|
<div id="panel_analytics_posts_table" class="colstack_item rowlist" aria-label="{{lang "panel_statistics_memory_table_aria"}}">
|
||||||
{{range .ViewItems}}
|
{{range .ViewItems}}
|
||||||
<div class="rowitem panel_compactrow editable_parent">
|
<div class="rowitem panel_compactrow editable_parent">
|
||||||
<a class="panel_upshift {{if or (or (or (eq $.TimeRange "six-hours") (eq $.TimeRange "twelve-hours")) (eq $.TimeRange "one-day")) (eq $.TimeRange "two-days")}}unix_to_24_hour_time{{else}}unix_to_date{{end}}">{{.Time}}</a>
|
<a class="panel_upshift unix_{{if or (or (or (eq $.TimeRange "six-hours") (eq $.TimeRange "twelve-hours")) (eq $.TimeRange "one-day")) (eq $.TimeRange "two-days")}}to_24_hour_time{{else}}to_date{{end}}">{{.Time}}</a>
|
||||||
<span class="panel_compacttext to_right">{{.Count}}{{.Unit}}</span>
|
<span class="panel_compacttext to_right">{{.Count}}{{.Unit}}</span>
|
||||||
</div>
|
</div>
|
||||||
{{else}}<div class="rowitem passive rowmsg">{{lang "panel_statistics_post_counts_no_post_counts"}}</div>{{end}}
|
{{else}}<div class="rowitem passive rowmsg">{{lang "panel_statistics_memory_no_memory"}}</div>{{end}}
|
||||||
</div>
|
</div>
|
||||||
<script>
|
<script>
|
||||||
let rawLabels = [{{range .Graph.Labels}}
|
let rawLabels = [{{range .Graph.Labels}}
|
||||||
|
|
|
@ -1,8 +1,3 @@
|
||||||
{{template "header.html" . }}
|
|
||||||
<div id="panel_page_list" class="colstack panel_stack">
|
|
||||||
{{template "panel_menu.html" . }}
|
|
||||||
<main class="colstack_right">
|
|
||||||
{{template "panel_before_head.html" . }}
|
|
||||||
<div class="colstack_item colstack_head">
|
<div class="colstack_item colstack_head">
|
||||||
<div class="rowitem"><h1>{{lang "panel_pages_head"}}</h1></div>
|
<div class="rowitem"><h1>{{lang "panel_pages_head"}}</h1></div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -45,6 +40,3 @@
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
</main>
|
|
||||||
</div>
|
|
||||||
{{template "footer.html" . }}
|
|
||||||
|
|
|
@ -1,8 +1,3 @@
|
||||||
{{template "header.html" . }}
|
|
||||||
<div id="panel_page_edit" class="colstack panel_stack">
|
|
||||||
{{template "panel_menu.html" . }}
|
|
||||||
<main class="colstack_right">
|
|
||||||
{{template "panel_before_head.html" . }}
|
|
||||||
<div class="colstack_item colstack_head">
|
<div class="colstack_item colstack_head">
|
||||||
<div class="rowitem"><h1>{{lang "panel_pages_edit_head"}}</h1></div>
|
<div class="rowitem"><h1>{{lang "panel_pages_edit_head"}}</h1></div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -26,7 +21,3 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
</main>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
{{template "footer.html" . }}
|
|
||||||
|
|
|
@ -1,9 +1,3 @@
|
||||||
{{template "header.html" . }}
|
|
||||||
<div class="colstack panel_stack">
|
|
||||||
|
|
||||||
{{template "panel_menu.html" . }}
|
|
||||||
<main class="colstack_right">
|
|
||||||
{{template "panel_before_head.html" . }}
|
|
||||||
<div class="colstack_item colstack_head">
|
<div class="colstack_item colstack_head">
|
||||||
<div class="rowitem"><h1>{{.Setting.FriendlyName}}</h1></div>
|
<div class="rowitem"><h1>{{.Setting.FriendlyName}}</h1></div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -41,7 +35,3 @@
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
</main>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
{{template "footer.html" . }}
|
|
||||||
|
|
|
@ -1,8 +1,3 @@
|
||||||
{{template "header.html" . }}
|
|
||||||
<div class="colstack panel_stack">
|
|
||||||
{{template "panel_menu.html" . }}
|
|
||||||
<main class="colstack_right">
|
|
||||||
{{template "panel_before_head.html" . }}
|
|
||||||
<div class="colstack_item colstack_head">
|
<div class="colstack_item colstack_head">
|
||||||
<div class="rowitem"><h1>{{lang "panel_settings_head"}}</h1></div>
|
<div class="rowitem"><h1>{{lang "panel_settings_head"}}</h1></div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -14,6 +9,3 @@
|
||||||
</div>
|
</div>
|
||||||
{{end}}
|
{{end}}
|
||||||
</div>
|
</div>
|
||||||
</main>
|
|
||||||
</div>
|
|
||||||
{{template "footer.html" . }}
|
|
||||||
|
|
|
@ -1,9 +1,3 @@
|
||||||
{{template "header.html" . }}
|
|
||||||
<div class="colstack panel_stack">
|
|
||||||
|
|
||||||
{{template "panel_menu.html" . }}
|
|
||||||
<main class="colstack_right">
|
|
||||||
{{template "panel_before_head.html" . }}
|
|
||||||
<div class="colstack_item colstack_head">
|
<div class="colstack_item colstack_head">
|
||||||
<div class="rowitem"><h1>{{lang "panel_word_filters_head"}}</h1></div>
|
<div class="rowitem"><h1>{{lang "panel_word_filters_head"}}</h1></div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -44,7 +38,3 @@
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
</main>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
{{template "footer.html" . }}
|
|
||||||
|
|
|
@ -74,6 +74,15 @@ li a {
|
||||||
padding-left: 8px;
|
padding-left: 8px;
|
||||||
padding-right: 8px;
|
padding-right: 8px;
|
||||||
}
|
}
|
||||||
|
.alertItem:not(.withAvatar) {
|
||||||
|
padding-top: 0px;
|
||||||
|
padding-bottom: 0px;
|
||||||
|
}
|
||||||
|
.alertItem:not(.withAvatar) a {
|
||||||
|
padding-top: 14px;
|
||||||
|
padding-bottom: 18px;
|
||||||
|
font-size: 17px;
|
||||||
|
}
|
||||||
.alertItem.withAvatar {
|
.alertItem.withAvatar {
|
||||||
background: none !important;
|
background: none !important;
|
||||||
height: 66px;
|
height: 66px;
|
||||||
|
|
Loading…
Reference in New Issue