Skip to content

Commit f6aa025

Browse files
authored
feat: use active users instead of total users in Template views (#3900)
1 parent 346583f commit f6aa025

File tree

20 files changed

+250
-141
lines changed

20 files changed

+250
-141
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ site/out/
4141
.terraform/
4242

4343
.vscode/*.log
44+
.vscode/launch.json
4445
**/*.swp
4546
.coderv2/*
4647
**/__debug_bin

.vscode/settings.json

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -161,16 +161,10 @@
161161
// To reduce redundancy in tests, it's covered by other packages.
162162
// Since package coverage pairing can't be defined, all packages cover
163163
// all other packages.
164-
"go.testFlags": ["-short", "-coverpkg=./..."],
165-
"go.coverageDecorator": {
166-
"type": "gutter",
167-
"coveredHighlightColor": "rgba(64,128,128,0.5)",
168-
"uncoveredHighlightColor": "rgba(128,64,64,0.25)",
169-
"coveredBorderColor": "rgba(64,128,128,0.5)",
170-
"uncoveredBorderColor": "rgba(128,64,64,0.25)",
171-
"coveredGutterStyle": "blockgreen",
172-
"uncoveredGutterStyle": "blockred"
173-
},
164+
"go.testFlags": [
165+
"-short",
166+
"-coverpkg=./..."
167+
],
174168
// We often use a version of TypeScript that's ahead of the version shipped
175169
// with VS Code.
176170
"typescript.tsdk": "./site/node_modules/typescript/lib"

cli/create.go

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ func create() *cobra.Command {
7272
}
7373

7474
slices.SortFunc(templates, func(a, b codersdk.Template) bool {
75-
return a.WorkspaceOwnerCount > b.WorkspaceOwnerCount
75+
return a.ActiveUserCount > b.ActiveUserCount
7676
})
7777

7878
templateNames := make([]string, 0, len(templates))
@@ -81,13 +81,13 @@ func create() *cobra.Command {
8181
for _, template := range templates {
8282
templateName := template.Name
8383

84-
if template.WorkspaceOwnerCount > 0 {
85-
developerText := "developer"
86-
if template.WorkspaceOwnerCount != 1 {
87-
developerText = "developers"
88-
}
89-
90-
templateName += cliui.Styles.Placeholder.Render(fmt.Sprintf(" (used by %d %s)", template.WorkspaceOwnerCount, developerText))
84+
if template.ActiveUserCount > 0 {
85+
templateName += cliui.Styles.Placeholder.Render(
86+
fmt.Sprintf(
87+
" (used by %s)",
88+
formatActiveDevelopers(template.ActiveUserCount),
89+
),
90+
)
9191
}
9292

9393
templateNames = append(templateNames, templateName)

cli/templates.go

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
package cli
22

33
import (
4-
"fmt"
54
"time"
65

76
"github.com/google/uuid"
@@ -64,19 +63,14 @@ type templateTableRow struct {
6463
func displayTemplates(filterColumns []string, templates ...codersdk.Template) (string, error) {
6564
rows := make([]templateTableRow, len(templates))
6665
for i, template := range templates {
67-
suffix := ""
68-
if template.WorkspaceOwnerCount != 1 {
69-
suffix = "s"
70-
}
71-
7266
rows[i] = templateTableRow{
7367
Name: template.Name,
7468
CreatedAt: template.CreatedAt.Format("January 2, 2006"),
7569
LastUpdated: template.UpdatedAt.Format("January 2, 2006"),
7670
OrganizationID: template.OrganizationID,
7771
Provisioner: template.Provisioner,
7872
ActiveVersionID: template.ActiveVersionID,
79-
UsedBy: cliui.Styles.Fuchsia.Render(fmt.Sprintf("%d developer%s", template.WorkspaceOwnerCount, suffix)),
73+
UsedBy: cliui.Styles.Fuchsia.Render(formatActiveDevelopers(template.ActiveUserCount)),
8074
MaxTTL: (time.Duration(template.MaxTTLMillis) * time.Millisecond),
8175
MinAutostartInterval: (time.Duration(template.MinAutostartIntervalMillis) * time.Millisecond),
8276
}

cli/util.go

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package cli
22

33
import (
44
"fmt"
5+
"strconv"
56
"strings"
67
"time"
78

@@ -175,3 +176,19 @@ func parseTime(s string) (time.Time, error) {
175176
}
176177
return time.Time{}, errInvalidTimeFormat
177178
}
179+
180+
func formatActiveDevelopers(n int) string {
181+
developerText := "developer"
182+
if n != 1 {
183+
developerText = "developers"
184+
}
185+
186+
var nStr string
187+
if n < 0 {
188+
nStr = "-"
189+
} else {
190+
nStr = strconv.Itoa(n)
191+
}
192+
193+
return fmt.Sprintf("%s active %s", nStr, developerText)
194+
}

coderd/database/databasefake/databasefake.go

Lines changed: 17 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -163,34 +163,37 @@ func (q *fakeQuerier) GetTemplateDAUs(_ context.Context, templateID uuid.UUID) (
163163
q.mutex.Lock()
164164
defer q.mutex.Unlock()
165165

166-
counts := make(map[time.Time]map[string]struct{})
166+
seens := make(map[time.Time]map[uuid.UUID]struct{})
167167

168168
for _, as := range q.agentStats {
169169
if as.TemplateID != templateID {
170170
continue
171171
}
172172

173173
date := as.CreatedAt.Truncate(time.Hour * 24)
174-
dateEntry := counts[date]
174+
175+
dateEntry := seens[date]
175176
if dateEntry == nil {
176-
dateEntry = make(map[string]struct{})
177+
dateEntry = make(map[uuid.UUID]struct{})
177178
}
178-
counts[date] = dateEntry
179-
180-
dateEntry[as.UserID.String()] = struct{}{}
179+
dateEntry[as.UserID] = struct{}{}
180+
seens[date] = dateEntry
181181
}
182182

183-
countKeys := maps.Keys(counts)
184-
sort.Slice(countKeys, func(i, j int) bool {
185-
return countKeys[i].Before(countKeys[j])
183+
seenKeys := maps.Keys(seens)
184+
sort.Slice(seenKeys, func(i, j int) bool {
185+
return seenKeys[i].Before(seenKeys[j])
186186
})
187187

188188
var rs []database.GetTemplateDAUsRow
189-
for _, key := range countKeys {
190-
rs = append(rs, database.GetTemplateDAUsRow{
191-
Date: key,
192-
Amount: int64(len(counts[key])),
193-
})
189+
for _, key := range seenKeys {
190+
ids := seens[key]
191+
for id := range ids {
192+
rs = append(rs, database.GetTemplateDAUsRow{
193+
Date: key,
194+
UserID: id,
195+
})
196+
}
194197
}
195198

196199
return rs, nil

coderd/database/queries.sql.go

Lines changed: 4 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

coderd/database/queries/agentstats.sql

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,12 +15,12 @@ VALUES
1515
-- name: GetTemplateDAUs :many
1616
select
1717
(created_at at TIME ZONE 'UTC')::date as date,
18-
count(distinct(user_id)) as amount
18+
user_id
1919
from
2020
agent_stats
2121
where template_id = $1
2222
group by
23-
date
23+
date, user_id
2424
order by
2525
date asc;
2626

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy