snapshot of https://github.com/traggo/server.git (master, 2026-09-16; blobs > 131072B omitted)
Some checks failed
build / build (push) Failing after 3s
Some checks failed
build / build (push) Failing after 3s
This commit is contained in:
37
dashboard/convert/dashboard.go
Normal file
37
dashboard/convert/dashboard.go
Normal file
@@ -0,0 +1,37 @@
|
||||
package convert
|
||||
|
||||
import (
|
||||
"github.com/traggo/server/generated/gqlmodel"
|
||||
"github.com/traggo/server/model"
|
||||
)
|
||||
|
||||
// ToExternalDashboards converts dashboards.
|
||||
func ToExternalDashboards(dashboards []model.Dashboard) ([]*gqlmodel.Dashboard, error) {
|
||||
result := []*gqlmodel.Dashboard{}
|
||||
for _, dashboard := range dashboards {
|
||||
if converted, err := ToExternalDashboard(dashboard); err == nil {
|
||||
result = append(result, converted)
|
||||
} else {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
|
||||
// ToExternalDashboard converts a dashboard.
|
||||
func ToExternalDashboard(dashboard model.Dashboard) (*gqlmodel.Dashboard, error) {
|
||||
entries, err := toExternalEntries(dashboard.Entries)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
ranges, err := toExternalDashboardsRanges(dashboard.Ranges)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &gqlmodel.Dashboard{
|
||||
ID: dashboard.ID,
|
||||
Name: dashboard.Name,
|
||||
Items: entries,
|
||||
Ranges: ranges,
|
||||
}, nil
|
||||
}
|
||||
39
dashboard/convert/dashboardtag.go
Normal file
39
dashboard/convert/dashboardtag.go
Normal file
@@ -0,0 +1,39 @@
|
||||
package convert
|
||||
|
||||
import (
|
||||
"github.com/traggo/server/generated/gqlmodel"
|
||||
"github.com/traggo/server/model"
|
||||
)
|
||||
|
||||
func tagFiltersToExternal(tags []model.DashboardTagFilter, include bool) []*gqlmodel.TimeSpanTag {
|
||||
if len(tags) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
result := []*gqlmodel.TimeSpanTag{}
|
||||
for _, tag := range tags {
|
||||
if tag.Include == include {
|
||||
result = append(result, &gqlmodel.TimeSpanTag{
|
||||
Key: tag.Key,
|
||||
Value: tag.StringValue,
|
||||
})
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
func TagFiltersToInternal(gqls []*gqlmodel.InputTimeSpanTag, include bool) []model.DashboardTagFilter {
|
||||
result := make([]model.DashboardTagFilter, 0)
|
||||
for _, tag := range gqls {
|
||||
result = append(result, tagFilterToInternal(*tag, include))
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
func tagFilterToInternal(gqls gqlmodel.InputTimeSpanTag, include bool) model.DashboardTagFilter {
|
||||
return model.DashboardTagFilter{
|
||||
Key: gqls.Key,
|
||||
StringValue: gqls.Value,
|
||||
Include: include,
|
||||
}
|
||||
}
|
||||
59
dashboard/convert/entry.go
Normal file
59
dashboard/convert/entry.go
Normal file
@@ -0,0 +1,59 @@
|
||||
package convert
|
||||
|
||||
import (
|
||||
"strings"
|
||||
|
||||
"github.com/traggo/server/generated/gqlmodel"
|
||||
"github.com/traggo/server/model"
|
||||
)
|
||||
|
||||
func toExternalEntries(entries []model.DashboardEntry) ([]*gqlmodel.DashboardEntry, error) {
|
||||
result := []*gqlmodel.DashboardEntry{}
|
||||
for _, entry := range entries {
|
||||
converted, err := ToExternalEntry(entry)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
result = append(result, converted)
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
|
||||
// ToExternalEntry converts entries.
|
||||
func ToExternalEntry(entry model.DashboardEntry) (*gqlmodel.DashboardEntry, error) {
|
||||
mobilePosition, err := toExternalPosition(entry.MobilePosition)
|
||||
if err != nil {
|
||||
return &gqlmodel.DashboardEntry{}, err
|
||||
}
|
||||
desktopPos, err := toExternalPosition(entry.DesktopPosition)
|
||||
if err != nil {
|
||||
return &gqlmodel.DashboardEntry{}, err
|
||||
}
|
||||
pos := gqlmodel.ResponsiveDashboardEntryPos{
|
||||
Mobile: enhancePos(mobilePosition, "mobile"),
|
||||
Desktop: enhancePos(desktopPos, "desktop"),
|
||||
}
|
||||
dateRange := &gqlmodel.RelativeOrStaticRange{
|
||||
From: entry.RangeFrom,
|
||||
To: entry.RangeTo,
|
||||
}
|
||||
stats := &gqlmodel.StatsSelection{
|
||||
Interval: ExternalInterval(entry.Interval),
|
||||
Tags: strings.Split(entry.Keys, ","),
|
||||
Range: dateRange,
|
||||
ExcludeTags: tagFiltersToExternal(entry.TagFilters, false),
|
||||
IncludeTags: tagFiltersToExternal(entry.TagFilters, true),
|
||||
}
|
||||
if entry.RangeID != model.NoRangeIDDefined {
|
||||
stats.RangeID = &entry.RangeID
|
||||
stats.Range = nil
|
||||
}
|
||||
return &gqlmodel.DashboardEntry{
|
||||
ID: entry.ID,
|
||||
Title: entry.Title,
|
||||
Total: entry.Total,
|
||||
Pos: &pos,
|
||||
StatsSelection: stats,
|
||||
EntryType: ExternalEntryType(entry.Type),
|
||||
}, nil
|
||||
}
|
||||
46
dashboard/convert/entrytype.go
Normal file
46
dashboard/convert/entrytype.go
Normal file
@@ -0,0 +1,46 @@
|
||||
package convert
|
||||
|
||||
import (
|
||||
"github.com/traggo/server/generated/gqlmodel"
|
||||
"github.com/traggo/server/model"
|
||||
)
|
||||
|
||||
// InternalEntryType converts entry type.
|
||||
func InternalEntryType(entryType gqlmodel.EntryType) model.DashboardType {
|
||||
switch entryType {
|
||||
case gqlmodel.EntryTypeBarChart:
|
||||
return model.TypeBarChart
|
||||
case gqlmodel.EntryTypePieChart:
|
||||
return model.TypePieChart
|
||||
case gqlmodel.EntryTypeStackedBarChart:
|
||||
return model.TypeStackedBarChart
|
||||
case gqlmodel.EntryTypeLineChart:
|
||||
return model.TypeLineChart
|
||||
case gqlmodel.EntryTypeHorizontalTable:
|
||||
return model.HorizontalTable
|
||||
case gqlmodel.EntryTypeVerticalTable:
|
||||
return model.VerticalTable
|
||||
default:
|
||||
panic("unknown entry type " + entryType)
|
||||
}
|
||||
}
|
||||
|
||||
// ExternalEntryType converts entry type.
|
||||
func ExternalEntryType(entryType model.DashboardType) gqlmodel.EntryType {
|
||||
switch entryType {
|
||||
case model.TypeBarChart:
|
||||
return gqlmodel.EntryTypeBarChart
|
||||
case model.TypePieChart:
|
||||
return gqlmodel.EntryTypePieChart
|
||||
case model.TypeStackedBarChart:
|
||||
return gqlmodel.EntryTypeStackedBarChart
|
||||
case model.TypeLineChart:
|
||||
return gqlmodel.EntryTypeLineChart
|
||||
case model.HorizontalTable:
|
||||
return gqlmodel.EntryTypeHorizontalTable
|
||||
case model.VerticalTable:
|
||||
return gqlmodel.EntryTypeVerticalTable
|
||||
default:
|
||||
panic("unknown entry type " + entryType)
|
||||
}
|
||||
}
|
||||
46
dashboard/convert/interval.go
Normal file
46
dashboard/convert/interval.go
Normal file
@@ -0,0 +1,46 @@
|
||||
package convert
|
||||
|
||||
import (
|
||||
"github.com/traggo/server/generated/gqlmodel"
|
||||
"github.com/traggo/server/model"
|
||||
)
|
||||
|
||||
// InternalInterval converts interval.
|
||||
func InternalInterval(interval gqlmodel.StatsInterval) model.Interval {
|
||||
switch interval {
|
||||
case gqlmodel.StatsIntervalHourly:
|
||||
return model.IntervalHourly
|
||||
case gqlmodel.StatsIntervalDaily:
|
||||
return model.IntervalDaily
|
||||
case gqlmodel.StatsIntervalWeekly:
|
||||
return model.IntervalWeekly
|
||||
case gqlmodel.StatsIntervalMonthly:
|
||||
return model.IntervalMonthly
|
||||
case gqlmodel.StatsIntervalYearly:
|
||||
return model.IntervalYearly
|
||||
case gqlmodel.StatsIntervalSingle:
|
||||
return model.IntervalSingle
|
||||
default:
|
||||
panic("unknown interval type " + interval)
|
||||
}
|
||||
}
|
||||
|
||||
// ExternalInterval converts interval.
|
||||
func ExternalInterval(interval model.Interval) gqlmodel.StatsInterval {
|
||||
switch interval {
|
||||
case model.IntervalHourly:
|
||||
return gqlmodel.StatsIntervalHourly
|
||||
case model.IntervalDaily:
|
||||
return gqlmodel.StatsIntervalDaily
|
||||
case model.IntervalWeekly:
|
||||
return gqlmodel.StatsIntervalWeekly
|
||||
case model.IntervalMonthly:
|
||||
return gqlmodel.StatsIntervalMonthly
|
||||
case model.IntervalYearly:
|
||||
return gqlmodel.StatsIntervalYearly
|
||||
case model.IntervalSingle:
|
||||
return gqlmodel.StatsIntervalSingle
|
||||
default:
|
||||
panic("unknown interval type " + interval)
|
||||
}
|
||||
}
|
||||
111
dashboard/convert/position.go
Normal file
111
dashboard/convert/position.go
Normal file
@@ -0,0 +1,111 @@
|
||||
package convert
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
|
||||
"github.com/jinzhu/copier"
|
||||
"github.com/rs/zerolog/log"
|
||||
"github.com/traggo/server/generated/gqlmodel"
|
||||
"github.com/traggo/server/model"
|
||||
)
|
||||
|
||||
func enhancePos(pos *gqlmodel.DashboardEntryPos, size string) *gqlmodel.DashboardEntryPos {
|
||||
switch size {
|
||||
case "mobile":
|
||||
pos.MinH = 2
|
||||
pos.MinW = 1
|
||||
case "desktop":
|
||||
pos.MinH = 3
|
||||
pos.MinW = 2
|
||||
default:
|
||||
panic("unknown size")
|
||||
}
|
||||
if pos.MinW > pos.W {
|
||||
pos.W = pos.MinW
|
||||
}
|
||||
if pos.MinH > pos.H {
|
||||
pos.H = pos.MinH
|
||||
}
|
||||
return pos
|
||||
}
|
||||
|
||||
// EmptyPos returns a empty position.
|
||||
func EmptyPos() string {
|
||||
internal := internalDashboardPositionV1{
|
||||
Version: "v1",
|
||||
H: 0,
|
||||
W: 0,
|
||||
X: 0,
|
||||
Y: 0,
|
||||
}
|
||||
|
||||
if bytes, err := json.Marshal(&internal); err != nil {
|
||||
panic(err)
|
||||
} else {
|
||||
return string(bytes)
|
||||
}
|
||||
}
|
||||
|
||||
func toInternalPosition(external gqlmodel.InputDashboardEntryPos) (string, error) {
|
||||
internal := internalDashboardPositionV1{Version: "v1"}
|
||||
if err := copier.Copy(&internal, &external); err != nil {
|
||||
return "", err
|
||||
}
|
||||
bytes, err := json.Marshal(&internal)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return string(bytes), nil
|
||||
}
|
||||
|
||||
// ApplyPos copies the position to the external position.
|
||||
func ApplyPos(entry *model.DashboardEntry, pos *gqlmodel.InputResponsiveDashboardEntryPos) error {
|
||||
if pos == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
if pos.Mobile != nil {
|
||||
lpos, err := toInternalPosition(*pos.Mobile)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
entry.MobilePosition = lpos
|
||||
}
|
||||
if pos.Desktop != nil {
|
||||
mpos, err := toInternalPosition(*pos.Desktop)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
entry.DesktopPosition = mpos
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func toExternalPosition(pos string) (*gqlmodel.DashboardEntryPos, error) {
|
||||
if pos == "" {
|
||||
return nil, nil
|
||||
}
|
||||
internal := internalDashboardPositionV1{}
|
||||
if err := json.Unmarshal([]byte(pos), &internal); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if internal.Version != "v1" {
|
||||
log.Error().Interface("pos", internal).Msg("Invalid position version")
|
||||
}
|
||||
external := gqlmodel.DashboardEntryPos{}
|
||||
|
||||
if err := copier.Copy(&external, &internal); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &external, nil
|
||||
}
|
||||
|
||||
type internalDashboardPositionV1 struct {
|
||||
Version string
|
||||
W int `json:"w"`
|
||||
H int `json:"h"`
|
||||
X int `json:"x"`
|
||||
Y int `json:"y"`
|
||||
}
|
||||
46
dashboard/convert/range.go
Normal file
46
dashboard/convert/range.go
Normal file
@@ -0,0 +1,46 @@
|
||||
package convert
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/traggo/server/generated/gqlmodel"
|
||||
"github.com/traggo/server/model"
|
||||
"github.com/traggo/server/time"
|
||||
)
|
||||
|
||||
func toExternalDashboardsRanges(ranges []model.DashboardRange) ([]*gqlmodel.NamedDateRange, error) {
|
||||
result := []*gqlmodel.NamedDateRange{}
|
||||
for _, xrange := range ranges {
|
||||
result = append(result, ToExternalDashboardRange(xrange))
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
|
||||
// ToExternalDashboardRange converts a range.
|
||||
func ToExternalDashboardRange(xrange model.DashboardRange) *gqlmodel.NamedDateRange {
|
||||
return &gqlmodel.NamedDateRange{
|
||||
ID: xrange.ID,
|
||||
Name: xrange.Name,
|
||||
Editable: xrange.Editable,
|
||||
Range: &gqlmodel.RelativeOrStaticRange{
|
||||
From: xrange.From,
|
||||
To: xrange.To,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
// ToInternalDashboardRange converts a range.
|
||||
func ToInternalDashboardRange(xrange gqlmodel.InputNamedDateRange) (model.DashboardRange, error) {
|
||||
if err := time.Validate(xrange.Range.From); err != nil {
|
||||
return model.DashboardRange{}, fmt.Errorf("range from (%s) invalid: %s", xrange.Range.From, err)
|
||||
}
|
||||
if err := time.Validate(xrange.Range.To); err != nil {
|
||||
return model.DashboardRange{}, fmt.Errorf("range to (%s) invalid: %s", xrange.Range.To, err)
|
||||
}
|
||||
return model.DashboardRange{
|
||||
Editable: xrange.Editable,
|
||||
From: xrange.Range.From,
|
||||
To: xrange.Range.To,
|
||||
Name: xrange.Name,
|
||||
}, nil
|
||||
}
|
||||
Reference in New Issue
Block a user