Thanks to visit codestin.com
Credit goes to github.com

Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
c712b1b
feat: add server-side search and pagination for the Groups page
aqandrew Jul 15, 2026
50991b1
fix: hide Filter preset menu if no presets are provided
aqandrew Jul 15, 2026
83ab444
fix: move "Create group" button to GroupsPageView to match Organizati…
aqandrew Jul 15, 2026
956d69a
Merge remote-tracking branch 'origin/main' into aqandrew/devex-434-gr…
aqandrew Jul 15, 2026
3f71e1c
docs: regenerate enterprise API reference after merging main
aqandrew Jul 15, 2026
3d3e674
fix(site/src/pages/GroupsPage): keep GroupsPageView presentational
aqandrew Jul 15, 2026
2475ca8
test: set correct pagination number labels for WithSearchAndPaginatio…
aqandrew Jul 15, 2026
0855898
refactor: replace GroupsParams struct with string
aqandrew Jul 20, 2026
7f6e800
fix: order PaginatedOrganizationGroups by name, then id
aqandrew Jul 22, 2026
8400587
style: add spaces around cast operators
aqandrew Jul 22, 2026
05291c5
Merge remote-tracking branch 'origin/main' into aqandrew/devex-434-gr…
aqandrew Jul 23, 2026
3a8076e
Merge remote-tracking branch 'origin/aqandrew/devex-434-groups-search…
aqandrew Jul 23, 2026
7b6c520
fix(coderd/database): restore OFFSET in PaginatedOrganizationGroups
aqandrew Jul 23, 2026
970626a
refactor(codersdk): add PaginatedGroupsRequest and rename Organizatio…
aqandrew Jul 23, 2026
8980b1b
docs(codersdk): document org-wide read requirement on OrganizationGro…
aqandrew Jul 24, 2026
c23def7
fix(coderd/searchquery): support multi-word group search
aqandrew Jul 24, 2026
a0d56a8
fix(enterprise/coderd): drop dead sql.ErrNoRows check in paginatedGroups
aqandrew Jul 24, 2026
cbfc62f
test(enterprise/coderd): assert paginated group member hydration
aqandrew Jul 24, 2026
5225bc2
test(coderd): strengthen paginated groups query and search coverage
aqandrew Jul 24, 2026
b008254
feat(site/src/pages/GroupsPage): show filter-aware empty state
aqandrew Jul 24, 2026
af3cd63
refactor(site/src/components/Filter): drop unused GroupsFilter error …
aqandrew Jul 24, 2026
c498b25
refactor(site/src/pages/GroupsPage): use Array.from map callback in s…
aqandrew Jul 24, 2026
2e53869
Merge branch 'main' into aqandrew/devex-434-groups-search-pagination
aqandrew Jul 28, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
66 changes: 66 additions & 0 deletions coderd/apidoc/docs.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

62 changes: 62 additions & 0 deletions coderd/apidoc/swagger.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

11 changes: 11 additions & 0 deletions coderd/database/dbauthz/dbauthz.go
Original file line number Diff line number Diff line change
Expand Up @@ -7023,6 +7023,17 @@ func (q *querier) OrganizationMembers(ctx context.Context, arg database.Organiza
return fetchWithPostFilter(q.auth, policy.ActionRead, q.db.OrganizationMembers)(ctx, arg)
}

func (q *querier) PaginatedOrganizationGroups(ctx context.Context, arg database.PaginatedOrganizationGroupsParams) ([]database.PaginatedOrganizationGroupsRow, error) {
// Required to have permission to read all groups in the organization. This
// mirrors PaginatedOrganizationMembers: a single org-wide read check with no
// per-row post-filter, so that SQL LIMIT/OFFSET and COUNT(*) OVER() stay
// consistent across pages.
if err := q.authorizeContext(ctx, policy.ActionRead, rbac.ResourceGroup.InOrg(arg.OrganizationID)); err != nil {
return nil, err
Comment thread
aqandrew marked this conversation as resolved.
}
return q.db.PaginatedOrganizationGroups(ctx, arg)
}

func (q *querier) PaginatedOrganizationMembers(ctx context.Context, arg database.PaginatedOrganizationMembersParams) ([]database.PaginatedOrganizationMembersRow, error) {
// Required to have permission to read all members in the organization
if err := q.authorizeContext(ctx, policy.ActionRead, rbac.ResourceOrganizationMember.InOrg(arg.OrganizationID)); err != nil {
Expand Down
13 changes: 13 additions & 0 deletions coderd/database/dbauthz/dbauthz_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2585,6 +2585,19 @@ func (s *MethodTestSuite) TestOrganization() {

check.Args(arg).Asserts(mem, policy.ActionRead)
}))
s.Run("PaginatedOrganizationGroups", s.Mocked(func(dbm *dbmock.MockStore, faker *gofakeit.Faker, check *expects) {
o := testutil.Fake(s.T(), faker, database.Organization{})
g := testutil.Fake(s.T(), faker, database.Group{OrganizationID: o.ID})
arg := database.PaginatedOrganizationGroupsParams{OrganizationID: o.ID, LimitOpt: 0}
rows := []database.PaginatedOrganizationGroupsRow{{
Group: g,
OrganizationName: o.Name,
OrganizationDisplayName: o.DisplayName,
Count: 1,
}}
dbm.EXPECT().PaginatedOrganizationGroups(gomock.Any(), arg).Return(rows, nil).AnyTimes()
check.Args(arg).Asserts(rbac.ResourceGroup.InOrg(o.ID), policy.ActionRead).Returns(rows)
}))
s.Run("PaginatedOrganizationMembers", s.Mocked(func(dbm *dbmock.MockStore, faker *gofakeit.Faker, check *expects) {
o := testutil.Fake(s.T(), faker, database.Organization{})
u := testutil.Fake(s.T(), faker, database.User{})
Expand Down
8 changes: 8 additions & 0 deletions coderd/database/dbmetrics/querymetrics.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

15 changes: 15 additions & 0 deletions coderd/database/dbmock/dbmock.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions coderd/database/querier.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

86 changes: 86 additions & 0 deletions coderd/database/queries.sql.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

31 changes: 31 additions & 0 deletions coderd/database/queries/groups.sql
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,37 @@ WHERE
LIMIT NULLIF(@limit_opt :: int, 0)
;

-- name: PaginatedOrganizationGroups :many
SELECT
sqlc.embed(groups),
organizations.name AS organization_name,
organizations.display_name AS organization_display_name,
COUNT(*) OVER() AS count
FROM
groups
INNER JOIN
organizations ON groups.organization_id = organizations.id
WHERE
true
AND CASE
WHEN @organization_id :: uuid != '00000000-0000-0000-0000-000000000000' :: uuid THEN
groups.organization_id = @organization_id
Comment thread
aqandrew marked this conversation as resolved.
ELSE true
END
-- Filter by group name or display name (substring, case-insensitive).
AND CASE WHEN @search :: text != '' THEN (
groups.name ILIKE concat('%', @search, '%')
OR groups.display_name ILIKE concat('%', @search, '%')
)
ELSE true
END
ORDER BY
-- Deterministic and consistent ordering of all groups. This is to ensure consistent pagination.
LOWER(groups.name) ASC, groups.id ASC OFFSET @offset_opt
LIMIT
Comment thread
aqandrew marked this conversation as resolved.
-- A null limit means "no limit", so 0 means return all
NULLIF(@limit_opt :: int, 0);

-- name: InsertGroup :one
INSERT INTO groups (
id,
Expand Down
Loading
Loading