Skip to content

Commit 5b80c47

Browse files
authored
feat: add author filter command to template filtering (#19202)
Can do `author:username` to filter templates created by a certain author. Adding to help clean out some templates that I created on our dev instance. This makes sorting a bit easier.
1 parent 408e19f commit 5b80c47

File tree

6 files changed

+81
-1
lines changed

6 files changed

+81
-1
lines changed

coderd/database/modelqueries.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,8 @@ func (q *sqlQuerier) GetAuthorizedTemplates(ctx context.Context, arg GetTemplate
8282
pq.Array(arg.IDs),
8383
arg.Deprecated,
8484
arg.HasAITask,
85+
arg.AuthorID,
86+
arg.AuthorUsername,
8587
)
8688
if err != nil {
8789
return nil, err

coderd/database/queries.sql.go

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

coderd/database/queries/templates.sql

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,19 @@ WHERE
5959
tv.has_ai_task = sqlc.narg('has_ai_task') :: boolean
6060
ELSE true
6161
END
62+
-- Filter by author_id
63+
AND CASE
64+
WHEN @author_id :: uuid != '00000000-0000-0000-0000-000000000000'::uuid THEN
65+
t.created_by = @author_id
66+
ELSE true
67+
END
68+
-- Filter by author_username
69+
AND CASE
70+
WHEN @author_username :: text != '' THEN
71+
t.created_by = (SELECT id FROM users WHERE lower(users.username) = lower(@author_username) AND deleted = false)
72+
ELSE true
73+
END
74+
6275
-- Authorize Filter clause will be injected below in GetAuthorizedTemplates
6376
-- @authorize_filter
6477
ORDER BY (t.name, t.id) ASC

coderd/searchquery/search.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -278,12 +278,14 @@ func Templates(ctx context.Context, db database.Store, query string) (database.G
278278
parser := httpapi.NewQueryParamParser()
279279
filter := database.GetTemplatesWithFilterParams{
280280
Deleted: parser.Boolean(values, false, "deleted"),
281+
OrganizationID: parseOrganization(ctx, db, parser, values, "organization"),
281282
ExactName: parser.String(values, "", "exact_name"),
282283
FuzzyName: parser.String(values, "", "name"),
283284
IDs: parser.UUIDs(values, []uuid.UUID{}, "ids"),
284285
Deprecated: parser.NullableBoolean(values, sql.NullBool{}, "deprecated"),
285-
OrganizationID: parseOrganization(ctx, db, parser, values, "organization"),
286286
HasAITask: parser.NullableBoolean(values, sql.NullBool{}, "has-ai-task"),
287+
AuthorID: parser.UUID(values, uuid.Nil, "author_id"),
288+
AuthorUsername: parser.String(values, "", "author"),
287289
}
288290

289291
parser.ErrorExcessParams(values)

coderd/templates_test.go

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -814,6 +814,46 @@ func TestTemplatesByOrganization(t *testing.T) {
814814
require.False(t, templates[0].Deprecated)
815815
require.Empty(t, templates[0].DeprecationMessage)
816816
})
817+
818+
t.Run("ListByAuthor", func(t *testing.T) {
819+
t.Parallel()
820+
client := coderdtest.New(t, nil)
821+
owner := coderdtest.CreateFirstUser(t, client)
822+
adminAlpha, adminAlphaData := coderdtest.CreateAnotherUser(t, client, owner.OrganizationID, rbac.RoleTemplateAdmin())
823+
adminBravo, adminBravoData := coderdtest.CreateAnotherUser(t, client, owner.OrganizationID, rbac.RoleTemplateAdmin())
824+
adminCharlie, _ := coderdtest.CreateAnotherUser(t, client, owner.OrganizationID, rbac.RoleTemplateAdmin())
825+
826+
versionA := coderdtest.CreateTemplateVersion(t, client, owner.OrganizationID, nil)
827+
versionB := coderdtest.CreateTemplateVersion(t, client, owner.OrganizationID, nil)
828+
versionC := coderdtest.CreateTemplateVersion(t, client, owner.OrganizationID, nil)
829+
foo := coderdtest.CreateTemplate(t, adminAlpha, owner.OrganizationID, versionA.ID, func(request *codersdk.CreateTemplateRequest) {
830+
request.Name = "foo"
831+
})
832+
bar := coderdtest.CreateTemplate(t, adminBravo, owner.OrganizationID, versionB.ID, func(request *codersdk.CreateTemplateRequest) {
833+
request.Name = "bar"
834+
})
835+
_ = coderdtest.CreateTemplate(t, adminCharlie, owner.OrganizationID, versionC.ID, func(request *codersdk.CreateTemplateRequest) {
836+
request.Name = "baz"
837+
})
838+
839+
ctx := testutil.Context(t, testutil.WaitLong)
840+
841+
// List alpha
842+
alpha, err := client.Templates(ctx, codersdk.TemplateFilter{
843+
AuthorUsername: adminAlphaData.Username,
844+
})
845+
require.NoError(t, err)
846+
require.Len(t, alpha, 1)
847+
require.Equal(t, foo.ID, alpha[0].ID)
848+
849+
// List bravo
850+
bravo, err := client.Templates(ctx, codersdk.TemplateFilter{
851+
AuthorUsername: adminBravoData.Username,
852+
})
853+
require.NoError(t, err)
854+
require.Len(t, bravo, 1)
855+
require.Equal(t, bar.ID, bravo[0].ID)
856+
})
817857
}
818858

819859
func TestTemplateByOrganizationAndName(t *testing.T) {

codersdk/organizations.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -541,6 +541,7 @@ type TemplateFilter struct {
541541
OrganizationID uuid.UUID `typescript:"-"`
542542
ExactName string `typescript:"-"`
543543
FuzzyName string `typescript:"-"`
544+
AuthorUsername string `typescript:"-"`
544545
SearchQuery string `json:"q,omitempty"`
545546
}
546547

@@ -562,6 +563,11 @@ func (f TemplateFilter) asRequestOption() RequestOption {
562563
if f.FuzzyName != "" {
563564
params = append(params, fmt.Sprintf("name:%q", f.FuzzyName))
564565
}
566+
567+
if f.AuthorUsername != "" {
568+
params = append(params, fmt.Sprintf("author:%q", f.AuthorUsername))
569+
}
570+
565571
if f.SearchQuery != "" {
566572
params = append(params, f.SearchQuery)
567573
}

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