mirror of
https://github.com/netbirdio/netbird.git
synced 2026-09-28 09:39:05 +02:00
[client] UI refactor (#6069)
Refactor UI --------- Co-authored-by: Eduard Gert <kontakt@eduardgert.de> Co-authored-by: braginini <bangvalo@gmail.com> Co-authored-by: Pascal Fischer <32096965+pascal-fischer@users.noreply.github.com> Co-authored-by: Claude <noreply@anthropic.com> Co-authored-by: riccardom <riccardomanfrin@gmail.com>
This commit is contained in:
co-authored by
Eduard Gert
braginini
Pascal Fischer
Claude
riccardom
parent
679c7182a4
commit
8b7ce337d8
@@ -55,6 +55,10 @@ type ConvertOptions struct {
|
||||
IPsFilter map[string]struct{}
|
||||
ConnectionTypeFilter string
|
||||
ProfileName string
|
||||
// SessionExpiresAt is the absolute UTC instant at which the peer's SSO
|
||||
// session expires. Zero when the peer is not SSO-tracked or login
|
||||
// expiration is disabled. Sourced from StatusResponse.SessionExpiresAt.
|
||||
SessionExpiresAt time.Time
|
||||
}
|
||||
|
||||
type PeerStateDetailOutput struct {
|
||||
@@ -155,6 +159,11 @@ type OutputOverview struct {
|
||||
LazyConnectionEnabled bool `json:"lazyConnectionEnabled" yaml:"lazyConnectionEnabled"`
|
||||
ProfileName string `json:"profileName" yaml:"profileName"`
|
||||
SSHServerState SSHServerStateOutput `json:"sshServer" yaml:"sshServer"`
|
||||
// SessionExpiresAt is the absolute UTC instant at which the peer's SSO
|
||||
// session expires. nil when the peer is not SSO-tracked or login
|
||||
// expiration is disabled. Pointer (rather than zero-value time.Time) so
|
||||
// JSON / YAML omit the field entirely with `,omitempty`.
|
||||
SessionExpiresAt *time.Time `json:"sessionExpiresAt,omitempty" yaml:"sessionExpiresAt,omitempty"`
|
||||
}
|
||||
|
||||
// ConvertToStatusOutputOverview converts protobuf status to the output overview.
|
||||
@@ -201,6 +210,10 @@ func ConvertToStatusOutputOverview(pbFullStatus *proto.FullStatus, opts ConvertO
|
||||
ProfileName: opts.ProfileName,
|
||||
SSHServerState: sshServerOverview,
|
||||
}
|
||||
if !opts.SessionExpiresAt.IsZero() {
|
||||
t := opts.SessionExpiresAt
|
||||
overview.SessionExpiresAt = &t
|
||||
}
|
||||
|
||||
if opts.Anonymize {
|
||||
anonymizer := anonymize.NewAnonymizer(anonymize.DefaultAddresses())
|
||||
@@ -547,6 +560,15 @@ func (o *OutputOverview) GeneralSummary(showURL bool, showRelays bool, showNameS
|
||||
|
||||
peersCountString := fmt.Sprintf("%d/%d Connected", o.Peers.Connected, o.Peers.Total)
|
||||
|
||||
var sessionExpiryString string
|
||||
if o.SessionExpiresAt != nil && !o.SessionExpiresAt.IsZero() {
|
||||
sessionExpiryString = fmt.Sprintf(
|
||||
"Session expires: %s (in %s)\n",
|
||||
o.SessionExpiresAt.Format(time.RFC3339),
|
||||
FormatRemainingDuration(time.Until(*o.SessionExpiresAt)),
|
||||
)
|
||||
}
|
||||
|
||||
var forwardingRulesString string
|
||||
if o.NumberOfForwardingRules > 0 {
|
||||
forwardingRulesString = fmt.Sprintf("Forwarding rules: %d\n", o.NumberOfForwardingRules)
|
||||
@@ -593,6 +615,7 @@ func (o *OutputOverview) GeneralSummary(showURL bool, showRelays bool, showNameS
|
||||
"SSH Server: %s\n"+
|
||||
"Networks: %s\n"+
|
||||
"%s"+
|
||||
"%s"+
|
||||
"Peers count: %s\n",
|
||||
fmt.Sprintf("%s/%s%s", goos, goarch, goarm),
|
||||
daemonVersion,
|
||||
@@ -612,6 +635,7 @@ func (o *OutputOverview) GeneralSummary(showURL bool, showRelays bool, showNameS
|
||||
sshServerStatus,
|
||||
networks,
|
||||
forwardingRulesString,
|
||||
sessionExpiryString,
|
||||
peersCountString,
|
||||
)
|
||||
return summary
|
||||
@@ -1025,3 +1049,57 @@ func anonymizeOverview(a *anonymize.Anonymizer, overview *OutputOverview) {
|
||||
overview.SSHServerState.Sessions[i].Command = a.AnonymizeString(session.Command)
|
||||
}
|
||||
}
|
||||
|
||||
// FormatRemainingDuration renders a time.Duration for the "Session expires"
|
||||
// line. Examples: "2h 15m", "47m 12s", "8s", "expired 3m ago".
|
||||
//
|
||||
// Granularity drops to seconds only under a minute, otherwise minutes are
|
||||
// the smallest unit shown — sub-minute precision is noise for a deadline
|
||||
// that's hours or days out.
|
||||
func FormatRemainingDuration(d time.Duration) string {
|
||||
if d <= 0 {
|
||||
return "expired " + HumaniseDuration(-d) + " ago"
|
||||
}
|
||||
return HumaniseDuration(d)
|
||||
}
|
||||
|
||||
// HumaniseDuration renders a positive duration in compact form (e.g.
|
||||
// "2h 15m", "47m", "8s"). Exposed alongside FormatRemainingDuration so
|
||||
// callers that don't need the "expired … ago" wording can format
|
||||
// positive durations directly.
|
||||
func HumaniseDuration(d time.Duration) string {
|
||||
if d < time.Minute {
|
||||
s := int(d.Round(time.Second).Seconds())
|
||||
if s < 1 {
|
||||
s = 1
|
||||
}
|
||||
return fmt.Sprintf("%ds", s)
|
||||
}
|
||||
|
||||
const (
|
||||
day = 24 * time.Hour
|
||||
hour = time.Hour
|
||||
minute = time.Minute
|
||||
)
|
||||
|
||||
days := int64(d / day)
|
||||
d -= time.Duration(days) * day
|
||||
hours := int64(d / hour)
|
||||
d -= time.Duration(hours) * hour
|
||||
minutes := int64(d / minute)
|
||||
|
||||
switch {
|
||||
case days > 0:
|
||||
if hours == 0 {
|
||||
return fmt.Sprintf("%dd", days)
|
||||
}
|
||||
return fmt.Sprintf("%dd %dh", days, hours)
|
||||
case hours > 0:
|
||||
if minutes == 0 {
|
||||
return fmt.Sprintf("%dh", hours)
|
||||
}
|
||||
return fmt.Sprintf("%dh %dm", hours, minutes)
|
||||
default:
|
||||
return fmt.Sprintf("%dm", minutes)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user