mirror of
https://git.ptzo.gdn/feditools/relay.git
synced 2024-09-21 11:37:13 +00:00
parent
7eff78b91c
commit
515ca0fde1
4
crowdin.yml
Normal file
4
crowdin.yml
Normal file
@ -0,0 +1,4 @@
|
||||
---
|
||||
files:
|
||||
- source: /web/locales/active.en.yaml
|
||||
translation: /web/locales/active.%two_letters_code%.yaml
|
@ -1,6 +1,7 @@
|
||||
package webapp
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
libhttp "github.com/feditools/go-lib/http"
|
||||
libtemplate "github.com/feditools/go-lib/template"
|
||||
"github.com/feditools/relay/internal/http/template"
|
||||
@ -280,3 +281,62 @@ func (m *Module) displayAdminBlockList(w http.ResponseWriter, r *http.Request, c
|
||||
|
||||
m.executeTemplate(w, r, template.AdminBlockName, tmplVars)
|
||||
}
|
||||
|
||||
const jsAdminBlock = `
|
||||
const deleteModal = document.getElementById('deleteModal')
|
||||
deleteModal.addEventListener('show.bs.modal', event => {
|
||||
// Button that triggered the modal
|
||||
const button = event.relatedTarget
|
||||
|
||||
// Extract info from data-bs-* attributes
|
||||
const token = button.getAttribute('data-bs-token')
|
||||
const domain = button.getAttribute('data-bs-domain')
|
||||
|
||||
// Update the modal's content.
|
||||
const modalTitle = deleteModal.querySelector('.modal-title')
|
||||
const confirmText = deleteModal.querySelector('.confirm-text')
|
||||
const inputToken = deleteModal.querySelector('.modal-body #formDeleteInputToken')
|
||||
|
||||
modalTitle.textContent = %s
|
||||
confirmText.textContent = %s
|
||||
inputToken.value = token
|
||||
})
|
||||
|
||||
const editModal = document.getElementById('editModal')
|
||||
editModal.addEventListener('show.bs.modal', event => {
|
||||
// Button that triggered the modal
|
||||
const button = event.relatedTarget
|
||||
|
||||
// Extract info from data-bs-* attributes
|
||||
const token = button.getAttribute('data-bs-token')
|
||||
const domain = button.getAttribute('data-bs-domain')
|
||||
const obfuscatedDomain = button.getAttribute('data-bs-obfuscated-domain')
|
||||
const blockSubdomains = button.getAttribute('data-bs-block-subdomains')
|
||||
|
||||
// Update the modal's content.
|
||||
const modalTitle = editModal.querySelector('.modal-title')
|
||||
const inputToken = editModal.querySelector('.modal-body #formEditInputToken')
|
||||
const inputDomain = editModal.querySelector('.modal-body #formEditInputDomain')
|
||||
const inputObfuscatedDomain = editModal.querySelector('.modal-body #formEditInputObfuscatedDomain')
|
||||
const inputSubdomain = editModal.querySelector('.modal-body #formEditInputSubdomain')
|
||||
|
||||
modalTitle.textContent = %s
|
||||
inputToken.value = token
|
||||
inputDomain.value = domain
|
||||
inputObfuscatedDomain.value = obfuscatedDomain
|
||||
if (blockSubdomains == "true") {
|
||||
inputSubdomain.checked = true
|
||||
} else {
|
||||
inputSubdomain.checked = false
|
||||
}
|
||||
})
|
||||
`
|
||||
|
||||
func JSAdminBlock(deleteTitleText, deleteConfirmText, editTitleText *language.LocalizedString) string {
|
||||
return fmt.Sprintf(
|
||||
jsAdminBlock,
|
||||
"`"+deleteTitleText.String()+"`",
|
||||
"`"+deleteConfirmText.String()+"`",
|
||||
"`"+editTitleText.String()+"`",
|
||||
)
|
||||
}
|
||||
|
@ -2,15 +2,19 @@ package webapp
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
libtemplate "github.com/feditools/go-lib/template"
|
||||
"github.com/feditools/relay/internal/db"
|
||||
"github.com/feditools/relay/internal/http/template"
|
||||
"github.com/feditools/relay/internal/language"
|
||||
"github.com/feditools/relay/internal/logic"
|
||||
"github.com/feditools/relay/internal/models"
|
||||
"github.com/feditools/relay/internal/path"
|
||||
"github.com/feditools/relay/internal/token"
|
||||
"github.com/gorilla/mux"
|
||||
"net/http"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// AdminInstanceViewGetHandler serves the instance info page.
|
||||
@ -111,3 +115,78 @@ func (m *Module) displayAdminInstanceView(w http.ResponseWriter, r *http.Request
|
||||
|
||||
m.executeTemplate(w, r, template.AdminInstanceViewName, tmplVars)
|
||||
}
|
||||
|
||||
const jsAdminInstanceView = `
|
||||
new Chart(document.getElementById("deliveryChartContainer"), {
|
||||
type: 'line',
|
||||
data: {
|
||||
labels: [%s],
|
||||
datasets: [{
|
||||
data: [%s],
|
||||
label: "Error",
|
||||
borderColor: "#c45850",
|
||||
fill: false,
|
||||
lineTension: 0.2
|
||||
}, {
|
||||
data: [%s],
|
||||
label: "Success",
|
||||
borderColor: "#3cba9f",
|
||||
fill: false,
|
||||
lineTension: 0.2
|
||||
}
|
||||
]
|
||||
},
|
||||
options: {}
|
||||
});
|
||||
|
||||
new Chart(document.getElementById("receiveChartContainer"), {
|
||||
type: 'line',
|
||||
data: {
|
||||
labels: [%s],
|
||||
datasets: [{
|
||||
data: [%s],
|
||||
label: "Received",
|
||||
borderColor: "#3e95cd",
|
||||
fill: false,
|
||||
lineTension: 0.2
|
||||
}
|
||||
]
|
||||
},
|
||||
options: {}
|
||||
});
|
||||
`
|
||||
|
||||
func JSAdminInstanceView(deliverErrors, deliverSuccess, receive *logic.MetricsDataPointsTime) string {
|
||||
labelsLen := len(*deliverErrors)
|
||||
labels := make([]string, labelsLen)
|
||||
for i, dp := range *deliverErrors {
|
||||
labels[labelsLen-1-i] = dp.X.Format("\"Jan 02 2006\"")
|
||||
}
|
||||
|
||||
deliverErrorsLen := len(*deliverErrors)
|
||||
deliverErrorsData := make([]string, deliverErrorsLen)
|
||||
for i, dp := range *deliverErrors {
|
||||
deliverErrorsData[deliverErrorsLen-1-i] = strconv.FormatInt(int64(dp.Y), 10)
|
||||
}
|
||||
|
||||
deliverSuccessLen := len(*deliverSuccess)
|
||||
deliverSuccessData := make([]string, deliverSuccessLen)
|
||||
for i, dp := range *deliverSuccess {
|
||||
deliverSuccessData[deliverSuccessLen-1-i] = strconv.FormatInt(int64(dp.Y), 10)
|
||||
}
|
||||
|
||||
receiveLen := len(*receive)
|
||||
receiveData := make([]string, receiveLen)
|
||||
for i, dp := range *receive {
|
||||
receiveData[receiveLen-1-i] = strconv.FormatInt(int64(dp.Y), 10)
|
||||
}
|
||||
|
||||
return fmt.Sprintf(
|
||||
jsAdminInstanceView,
|
||||
strings.Join(labels, ","),
|
||||
strings.Join(deliverErrorsData, ","),
|
||||
strings.Join(deliverSuccessData, ","),
|
||||
strings.Join(labels, ","),
|
||||
strings.Join(receiveData, ","),
|
||||
)
|
||||
}
|
||||
|
@ -1,11 +1,15 @@
|
||||
package webapp
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/feditools/relay/internal/http/template"
|
||||
"github.com/feditools/relay/internal/language"
|
||||
"github.com/feditools/relay/internal/logic"
|
||||
"github.com/feditools/relay/internal/models"
|
||||
"github.com/feditools/relay/internal/path"
|
||||
"net/http"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
const defaultHomeBody = `This is another Activity Relay for fediverse instances.`
|
||||
@ -60,6 +64,17 @@ func (m *Module) HomeGetHandler(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
tmplVars.FollowingInstances = followingInstance
|
||||
|
||||
// get metrics
|
||||
received, err := m.logic.MetricsGetReceivedTotalWeek(r.Context())
|
||||
if err != nil {
|
||||
l.Errorf("get metrics deliver error: %s", err.Error())
|
||||
m.returnErrorPage(w, r, http.StatusInternalServerError, err.Error())
|
||||
|
||||
return
|
||||
}
|
||||
tmplVars.AddFooterExtraScript(JSHome(received))
|
||||
tmplVars.AddFooterScript(m.footerScriptChartJS)
|
||||
|
||||
m.executeTemplate(w, r, template.HomeName, tmplVars)
|
||||
}
|
||||
|
||||
@ -67,3 +82,47 @@ func (m *Module) HomeGetHandler(w http.ResponseWriter, r *http.Request) {
|
||||
func (m *Module) ForwardToHomeHandler(w http.ResponseWriter, r *http.Request) {
|
||||
http.Redirect(w, r, path.AppHome, http.StatusFound)
|
||||
}
|
||||
|
||||
const jsHome = `
|
||||
new Chart(document.getElementById("receiveChartContainer"), {
|
||||
type: 'line',
|
||||
data: {
|
||||
labels: [%s],
|
||||
datasets: [{
|
||||
data: [%s],
|
||||
label: "Received",
|
||||
borderColor: "#3e95cd",
|
||||
fill: false,
|
||||
lineTension: 0.2
|
||||
}
|
||||
]
|
||||
},
|
||||
options: {
|
||||
plugins: {
|
||||
legend: {
|
||||
display: false
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
`
|
||||
|
||||
func JSHome(receive *logic.MetricsDataPointsTime) string {
|
||||
labelsLen := len(*receive)
|
||||
labels := make([]string, labelsLen)
|
||||
for i, dp := range *receive {
|
||||
labels[labelsLen-1-i] = dp.X.Format("\"Jan 02 2006\"")
|
||||
}
|
||||
|
||||
receiveLen := len(*receive)
|
||||
receiveData := make([]string, receiveLen)
|
||||
for i, dp := range *receive {
|
||||
receiveData[receiveLen-1-i] = strconv.FormatInt(int64(dp.Y), 10)
|
||||
}
|
||||
|
||||
return fmt.Sprintf(
|
||||
jsHome,
|
||||
strings.Join(labels, ","),
|
||||
strings.Join(receiveData, ","),
|
||||
)
|
||||
}
|
||||
|
@ -2,68 +2,8 @@ package webapp
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/feditools/relay/internal/language"
|
||||
)
|
||||
|
||||
const jsAdminBlock = `
|
||||
const deleteModal = document.getElementById('deleteModal')
|
||||
deleteModal.addEventListener('show.bs.modal', event => {
|
||||
// Button that triggered the modal
|
||||
const button = event.relatedTarget
|
||||
|
||||
// Extract info from data-bs-* attributes
|
||||
const token = button.getAttribute('data-bs-token')
|
||||
const domain = button.getAttribute('data-bs-domain')
|
||||
|
||||
// Update the modal's content.
|
||||
const modalTitle = deleteModal.querySelector('.modal-title')
|
||||
const confirmText = deleteModal.querySelector('.confirm-text')
|
||||
const inputToken = deleteModal.querySelector('.modal-body #formDeleteInputToken')
|
||||
|
||||
modalTitle.textContent = %s
|
||||
confirmText.textContent = %s
|
||||
inputToken.value = token
|
||||
})
|
||||
|
||||
const editModal = document.getElementById('editModal')
|
||||
editModal.addEventListener('show.bs.modal', event => {
|
||||
// Button that triggered the modal
|
||||
const button = event.relatedTarget
|
||||
|
||||
// Extract info from data-bs-* attributes
|
||||
const token = button.getAttribute('data-bs-token')
|
||||
const domain = button.getAttribute('data-bs-domain')
|
||||
const obfuscatedDomain = button.getAttribute('data-bs-obfuscated-domain')
|
||||
const blockSubdomains = button.getAttribute('data-bs-block-subdomains')
|
||||
|
||||
// Update the modal's content.
|
||||
const modalTitle = editModal.querySelector('.modal-title')
|
||||
const inputToken = editModal.querySelector('.modal-body #formEditInputToken')
|
||||
const inputDomain = editModal.querySelector('.modal-body #formEditInputDomain')
|
||||
const inputObfuscatedDomain = editModal.querySelector('.modal-body #formEditInputObfuscatedDomain')
|
||||
const inputSubdomain = editModal.querySelector('.modal-body #formEditInputSubdomain')
|
||||
|
||||
modalTitle.textContent = %s
|
||||
inputToken.value = token
|
||||
inputDomain.value = domain
|
||||
inputObfuscatedDomain.value = obfuscatedDomain
|
||||
if (blockSubdomains == "true") {
|
||||
inputSubdomain.checked = true
|
||||
} else {
|
||||
inputSubdomain.checked = false
|
||||
}
|
||||
})
|
||||
`
|
||||
|
||||
func JSAdminBlock(deleteTitleText, deleteConfirmText, editTitleText *language.LocalizedString) string {
|
||||
return fmt.Sprintf(
|
||||
jsAdminBlock,
|
||||
"`"+deleteTitleText.String()+"`",
|
||||
"`"+deleteConfirmText.String()+"`",
|
||||
"`"+editTitleText.String()+"`",
|
||||
)
|
||||
}
|
||||
|
||||
const jsOpenModal = `
|
||||
var autoOpenModal = new bootstrap.Modal(document.getElementById('%s'), {})
|
||||
autoOpenModal.toggle()
|
||||
|
@ -1,83 +0,0 @@
|
||||
package webapp
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/feditools/relay/internal/logic"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
const jsAdminInstanceView = `
|
||||
new Chart(document.getElementById("deliveryChartContainer"), {
|
||||
type: 'line',
|
||||
data: {
|
||||
labels: [%s],
|
||||
datasets: [{
|
||||
data: [%s],
|
||||
label: "Error",
|
||||
borderColor: "#c45850",
|
||||
fill: false,
|
||||
lineTension: 0.2
|
||||
}, {
|
||||
data: [%s],
|
||||
label: "Success",
|
||||
borderColor: "#3cba9f",
|
||||
fill: false,
|
||||
lineTension: 0.2
|
||||
}
|
||||
]
|
||||
},
|
||||
options: {}
|
||||
});
|
||||
|
||||
new Chart(document.getElementById("receiveChartContainer"), {
|
||||
type: 'line',
|
||||
data: {
|
||||
labels: [%s],
|
||||
datasets: [{
|
||||
data: [%s],
|
||||
label: "Received",
|
||||
borderColor: "#3e95cd",
|
||||
fill: false,
|
||||
lineTension: 0.2
|
||||
}
|
||||
]
|
||||
},
|
||||
options: {}
|
||||
});
|
||||
`
|
||||
|
||||
func JSAdminInstanceView(deliverErrors, deliverSuccess, receive *logic.MetricsDataPointsTime) string {
|
||||
labelsLen := len(*deliverErrors)
|
||||
labels := make([]string, labelsLen)
|
||||
for i, dp := range *deliverErrors {
|
||||
labels[labelsLen-1-i] = dp.X.Format("\"Jan 02 2006\"")
|
||||
}
|
||||
|
||||
deliverErrorsLen := len(*deliverErrors)
|
||||
deliverErrorsData := make([]string, deliverErrorsLen)
|
||||
for i, dp := range *deliverErrors {
|
||||
deliverErrorsData[deliverErrorsLen-1-i] = strconv.FormatInt(int64(dp.Y), 10)
|
||||
}
|
||||
|
||||
deliverSuccessLen := len(*deliverSuccess)
|
||||
deliverSuccessData := make([]string, deliverSuccessLen)
|
||||
for i, dp := range *deliverSuccess {
|
||||
deliverSuccessData[deliverSuccessLen-1-i] = strconv.FormatInt(int64(dp.Y), 10)
|
||||
}
|
||||
|
||||
receiveLen := len(*receive)
|
||||
receiveData := make([]string, receiveLen)
|
||||
for i, dp := range *receive {
|
||||
receiveData[receiveLen-1-i] = strconv.FormatInt(int64(dp.Y), 10)
|
||||
}
|
||||
|
||||
return fmt.Sprintf(
|
||||
jsAdminInstanceView,
|
||||
strings.Join(labels, ","),
|
||||
strings.Join(deliverErrorsData, ","),
|
||||
strings.Join(deliverSuccessData, ","),
|
||||
strings.Join(labels, ","),
|
||||
strings.Join(receiveData, ","),
|
||||
)
|
||||
}
|
@ -24,6 +24,28 @@ func (l *Localizer) TextAccount(count int) *LocalizedString {
|
||||
}
|
||||
}
|
||||
|
||||
// TextActivity returns a translated phrase.
|
||||
func (l *Localizer) TextActivity(count int) *LocalizedString {
|
||||
lg := logger.WithField("func", "TextActivity")
|
||||
|
||||
text, tag, err := l.localizer.LocalizeWithTag(&i18n.LocalizeConfig{
|
||||
DefaultMessage: &i18n.Message{
|
||||
ID: "Activity",
|
||||
One: "Activity",
|
||||
Other: "Activities",
|
||||
},
|
||||
PluralCount: count,
|
||||
})
|
||||
if err != nil {
|
||||
lg.Warningf(missingTranslationWarning, err.Error())
|
||||
}
|
||||
|
||||
return &LocalizedString{
|
||||
language: tag,
|
||||
string: text,
|
||||
}
|
||||
}
|
||||
|
||||
// TextActivityLog returns a translated phrase.
|
||||
func (l *Localizer) TextActivityLog(count int) *LocalizedString {
|
||||
lg := logger.WithField("func", "TextActivityLog")
|
||||
|
@ -46,6 +46,45 @@ func TestLocalizer_TextAccount(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestLocalizer_TextActivity(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
tables := []testTextTable{
|
||||
{
|
||||
inputLang: language.English,
|
||||
inputCount: 1,
|
||||
outputString: "Activity",
|
||||
outputLang: language.English,
|
||||
},
|
||||
{
|
||||
inputLang: language.English,
|
||||
inputCount: 2,
|
||||
outputString: "Activities",
|
||||
outputLang: language.English,
|
||||
},
|
||||
}
|
||||
|
||||
langMod, _ := New()
|
||||
for i, table := range tables {
|
||||
i := i
|
||||
table := table
|
||||
|
||||
name := fmt.Sprintf(testTranslatedTo, i, table.inputLang)
|
||||
t.Run(name, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
localizer, err := langMod.NewLocalizer(table.inputLang.String())
|
||||
if err != nil {
|
||||
t.Errorf(testCantGetLocalizer, i, table.inputLang, err.Error())
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
testTextWithCount(t, i, localizer.TextActivity, table)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestLocalizer_TextActivityLog(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
|
@ -68,18 +68,18 @@ func (l *Localizer) TextDeleteBlockConfirmDomain(domain string) *LocalizedString
|
||||
}
|
||||
}
|
||||
|
||||
// TextDeliveryStat returns a translated phrase.
|
||||
func (l *Localizer) TextDeliveryStat(count int) *LocalizedString {
|
||||
// TextDeliveredActivity returns a translated phrase.
|
||||
func (l *Localizer) TextDeliveredActivity(count int) *LocalizedString {
|
||||
text, tag, err := l.localizer.LocalizeWithTag(&i18n.LocalizeConfig{
|
||||
DefaultMessage: &i18n.Message{
|
||||
ID: "DeliveryStat",
|
||||
One: "Delivery Stat",
|
||||
Other: "Delivery Stats",
|
||||
ID: "DeliveredActivity",
|
||||
One: "Delivered Activity",
|
||||
Other: "Delivered Activities",
|
||||
},
|
||||
PluralCount: count,
|
||||
})
|
||||
if err != nil {
|
||||
logger.WithField("func", "TextDeliveryStat").Warningf(missingTranslationWarning, err.Error())
|
||||
logger.WithField("func", "TextDeliveredActivity").Warningf(missingTranslationWarning, err.Error())
|
||||
}
|
||||
|
||||
return &LocalizedString{
|
||||
|
@ -117,20 +117,20 @@ func TestLocalizer_TextDeleteBlockConfirmDomain(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestLocalizer_TextDeliveryStat(t *testing.T) {
|
||||
func TestLocalizer_TextDeliveredActivity(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
tables := []testTextTable{
|
||||
{
|
||||
inputLang: language.English,
|
||||
inputCount: 1,
|
||||
outputString: "Delivery Stat",
|
||||
outputString: "Delivered Activity",
|
||||
outputLang: language.English,
|
||||
},
|
||||
{
|
||||
inputLang: language.English,
|
||||
inputCount: 2,
|
||||
outputString: "Delivery Stats",
|
||||
outputString: "Delivered Activities",
|
||||
outputLang: language.English,
|
||||
},
|
||||
}
|
||||
@ -151,7 +151,7 @@ func TestLocalizer_TextDeliveryStat(t *testing.T) {
|
||||
return
|
||||
}
|
||||
|
||||
testTextWithCount(t, i, localizer.TextDeliveryStat, table)
|
||||
testTextWithCount(t, i, localizer.TextDeliveredActivity, table)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -2,18 +2,18 @@ package language
|
||||
|
||||
import "github.com/nicksnyder/go-i18n/v2/i18n"
|
||||
|
||||
// TextReceivedStat returns a translated phrase.
|
||||
func (l *Localizer) TextReceivedStat(count int) *LocalizedString {
|
||||
// TextReceivedActivity returns a translated phrase.
|
||||
func (l *Localizer) TextReceivedActivity(count int) *LocalizedString {
|
||||
text, tag, err := l.localizer.LocalizeWithTag(&i18n.LocalizeConfig{
|
||||
DefaultMessage: &i18n.Message{
|
||||
ID: "ReceivedStat",
|
||||
One: "Received Stat",
|
||||
Other: "Received Stats",
|
||||
ID: "ReceivedActivity",
|
||||
One: "Received Activity",
|
||||
Other: "Received Activities",
|
||||
},
|
||||
PluralCount: count,
|
||||
})
|
||||
if err != nil {
|
||||
logger.WithField("func", "TextReceivedStat").Warningf(missingTranslationWarning, err.Error())
|
||||
logger.WithField("func", "TextReceivedActivity").Warningf(missingTranslationWarning, err.Error())
|
||||
}
|
||||
|
||||
return &LocalizedString{
|
||||
|
@ -7,20 +7,20 @@ import (
|
||||
"golang.org/x/text/language"
|
||||
)
|
||||
|
||||
func TestLocalizer_TextReceivedStat(t *testing.T) {
|
||||
func TestLocalizer_TextReceivedActivity(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
tables := []testTextTable{
|
||||
{
|
||||
inputLang: language.English,
|
||||
inputCount: 1,
|
||||
outputString: "Received Stat",
|
||||
outputString: "Received Activity",
|
||||
outputLang: language.English,
|
||||
},
|
||||
{
|
||||
inputLang: language.English,
|
||||
inputCount: 2,
|
||||
outputString: "Received Stats",
|
||||
outputString: "Received Activities",
|
||||
outputLang: language.English,
|
||||
},
|
||||
}
|
||||
@ -41,7 +41,7 @@ func TestLocalizer_TextReceivedStat(t *testing.T) {
|
||||
return
|
||||
}
|
||||
|
||||
testTextWithCount(t, i, localizer.TextReceivedStat, table)
|
||||
testTextWithCount(t, i, localizer.TextReceivedActivity, table)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -28,6 +28,7 @@ type Logic interface {
|
||||
MetricsGetDeliverErrorWeek(ctx context.Context, instanceID int64) (*MetricsDataPointsTime, error)
|
||||
MetricsGetDeliverSuccessWeek(ctx context.Context, instanceID int64) (*MetricsDataPointsTime, error)
|
||||
MetricsGetReceivedWeek(ctx context.Context, instanceID int64) (*MetricsDataPointsTime, error)
|
||||
MetricsGetReceivedTotalWeek(ctx context.Context) (*MetricsDataPointsTime, error)
|
||||
MetricsIncDeliverError(ctx context.Context, instanceID int64)
|
||||
MetricsIncDeliverSuccess(ctx context.Context, instanceID int64)
|
||||
MetricsIncReceived(ctx context.Context, instanceID int64)
|
||||
|
@ -79,3 +79,27 @@ func (l *Logic) MetricsGetReceivedWeek(ctx context.Context, instanceID int64) (*
|
||||
|
||||
return &days, nil
|
||||
}
|
||||
|
||||
func (l *Logic) MetricsGetReceivedTotalWeek(ctx context.Context) (*logic.MetricsDataPointsTime, error) {
|
||||
now := time.Now().UTC()
|
||||
now = time.Date(now.Year(), now.Month(), now.Day(), 0, 0, 0, 0, time.UTC)
|
||||
|
||||
var days logic.MetricsDataPointsTime = make([]logic.MetricsDataPointTime, 7)
|
||||
for i := 0; i < 7; i++ {
|
||||
day := now.Add(-24 * time.Duration(i) * time.Hour)
|
||||
|
||||
count := 0
|
||||
var err error
|
||||
count, err = l.kv.GetMetricsReceivedTotal(ctx, day)
|
||||
if err != nil && !errors.Is(err, kv.ErrNil) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
days[i] = logic.MetricsDataPointTime{
|
||||
X: day,
|
||||
Y: count,
|
||||
}
|
||||
}
|
||||
|
||||
return &days, nil
|
||||
}
|
||||
|
@ -2,6 +2,9 @@
|
||||
Account:
|
||||
one: Account
|
||||
other: Accounts
|
||||
Activity:
|
||||
one: Activity
|
||||
other: Activities
|
||||
ActivityLog:
|
||||
one: Activity Log
|
||||
other: Activity Logs
|
||||
@ -34,9 +37,9 @@ Create: Create
|
||||
Delete: Delete
|
||||
DeleteBlockConfirmDomain: Are you sure you want to delete the block for {{.Domain}}?
|
||||
DeleteBlockDomain: Delete Block {{.Domain}}
|
||||
DeliveryStat:
|
||||
one: Delivery Stat
|
||||
other: Delivery Stats
|
||||
DeliveredActivity:
|
||||
one: Delivered Activity
|
||||
other: Delivered Activities
|
||||
Description:
|
||||
one: Description
|
||||
other: Descriptions
|
||||
@ -78,9 +81,9 @@ OAuthConfigured: OAuth Configured
|
||||
ObfuscatedDomain:
|
||||
one: Obfuscated Domain
|
||||
other: Obfuscated Domains
|
||||
ReceivedStat:
|
||||
one: Received Stat
|
||||
other: Received Stats
|
||||
ReceivedActivity:
|
||||
one: Received Activity
|
||||
other: Received Activities
|
||||
Relay:
|
||||
one: Relay
|
||||
other: Relays
|
||||
|
@ -1,7 +1,7 @@
|
||||
{{ define "admin_instance_view" -}}
|
||||
{{- $textActorURI := .Localizer.TextActorURI 1 -}}
|
||||
{{- $textBlock := .Localizer.TextBlock 1 -}}
|
||||
{{- $textDeliveryStats := .Localizer.TextDeliveryStat 2 -}}
|
||||
{{- $textDeliveredActivities := .Localizer.TextDeliveredActivity 2 -}}
|
||||
{{- $textDomain := .Localizer.TextDomain 1 -}}
|
||||
{{- $textFederation := .Localizer.TextFederation -}}
|
||||
{{- $textFollowing := .Localizer.TextFollowing -}}
|
||||
@ -10,7 +10,7 @@
|
||||
{{- $textInstance := .Localizer.TextInstance 1 -}}
|
||||
{{- $textMetrics := .Localizer.TextMetric 2 -}}
|
||||
{{- $textOAuthConfigured := .Localizer.TextOAuthConfigured -}}
|
||||
{{- $textReceivedStats := .Localizer.TextReceivedStat 2 -}}
|
||||
{{- $textReceivedActivities := .Localizer.TextReceivedActivity 2 -}}
|
||||
{{- $textServerHostname := .Localizer.TextServerHostname 1 -}}
|
||||
{{- $textSoftware := .Localizer.TextSoftware -}}
|
||||
{{- template "header" . }}
|
||||
@ -118,11 +118,11 @@
|
||||
<div class="col mb-3">
|
||||
<div class="row mb-3">
|
||||
<div class="col-lg">
|
||||
<div class="fw-bold" lang="{{ $textDeliveryStats.Language }}">{{ $textDeliveryStats }}</div>
|
||||
<div class="fw-bold" lang="{{ $textDeliveredActivities.Language }}">{{ $textDeliveredActivities }}</div>
|
||||
<canvas id="deliveryChartContainer" style="height: 300px; width: 100%;"></canvas>
|
||||
</div>
|
||||
<div class="col-lg">
|
||||
<div class="fw-bold" lang="{{ $textReceivedStats.Language }}">{{ $textReceivedStats }}</div>
|
||||
<div class="fw-bold" lang="{{ $textReceivedActivities.Language }}">{{ $textReceivedActivities }}</div>
|
||||
<canvas id="receiveChartContainer" style="height: 300px; width: 100%;"></canvas>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -2,6 +2,7 @@
|
||||
{{- $textBlockedDomains := .Localizer.TextBlockedDomain 2 -}}
|
||||
{{- $textHowToJoin := .Localizer.TextHowToJoin -}}
|
||||
{{- $textInstances := .Localizer.TextInstance 2 -}}
|
||||
{{- $extReceivedActivities := .Localizer.TextReceivedActivity 2 -}}
|
||||
{{- $textRelay := .Localizer.TextRelay 1 -}}
|
||||
{{- template "header" . }}
|
||||
<div class="container">
|
||||
@ -50,6 +51,16 @@
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col mt-4">
|
||||
<h2 lang="{{ $extReceivedActivities.Language }}"><i class="fa-solid fa-inbox"></i> {{ $extReceivedActivities }}</h2>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col mt-4">
|
||||
<canvas id="receiveChartContainer" style="height: 350px; width: 100%;"></canvas>
|
||||
</div>
|
||||
</div>
|
||||
</div><!-- /.container -->
|
||||
{{ template "footer" . }}
|
||||
{{ end }}
|
||||
|
Loading…
Reference in New Issue
Block a user