From b956a6466c5798c8b9f17d9d7703d33bcfe851b5 Mon Sep 17 00:00:00 2001 From: Abhineet Jain Date: Wed, 8 Jun 2022 15:21:39 +0000 Subject: [PATCH 1/7] design commit --- site/src/components/TemplateStats/TemplateStats.tsx | 6 ++++++ site/src/pages/TemplatesPage/TemplatesPageView.tsx | 3 +++ 2 files changed, 9 insertions(+) diff --git a/site/src/components/TemplateStats/TemplateStats.tsx b/site/src/components/TemplateStats/TemplateStats.tsx index 24da983939975..458d2d58c2119 100644 --- a/site/src/components/TemplateStats/TemplateStats.tsx +++ b/site/src/components/TemplateStats/TemplateStats.tsx @@ -13,6 +13,7 @@ const Language = { lastUpdateLabel: "Last updated", userPlural: "users", userSingular: "user", + createdByLabel: "Created by" } export interface TemplateStatsProps { @@ -45,6 +46,11 @@ export const TemplateStats: FC = ({ template, activeVersion {dayjs().to(dayjs(template.updated_at))} +
+
+ {Language.createdByLabel} + admin +
) } diff --git a/site/src/pages/TemplatesPage/TemplatesPageView.tsx b/site/src/pages/TemplatesPage/TemplatesPageView.tsx index a27cf2cacf5c1..023f934ef2a30 100644 --- a/site/src/pages/TemplatesPage/TemplatesPageView.tsx +++ b/site/src/pages/TemplatesPage/TemplatesPageView.tsx @@ -49,6 +49,7 @@ export const Language = { templateTooltipTitle: "What is template?", templateTooltipText: "With templates you can create a common configuration for your workspaces using Terraform.", templateTooltipLink: "Manage templates", + createdByLabel: "Created by", } const TemplateHelpTooltip: React.FC = () => { @@ -95,6 +96,7 @@ export const TemplatesPageView: FC = (props) => { {Language.nameLabel} {Language.usedByLabel} {Language.lastUpdatedLabel} + {Language.createdByLabel} @@ -137,6 +139,7 @@ export const TemplatesPageView: FC = (props) => { {Language.developerCount(template.workspace_owner_count)} {dayjs().to(dayjs(template.updated_at))} + admin
From c2880130f0e7bbd5e3736c0b76d2e36995021abf Mon Sep 17 00:00:00 2001 From: Abhineet Jain Date: Thu, 9 Jun 2022 15:14:50 +0000 Subject: [PATCH 2/7] add owner_id to templates table --- coderd/database/dump.sql | 6 ++++- .../migrations/000022_template_owner.down.sql | 1 + .../migrations/000022_template_owner.up.sql | 1 + coderd/database/models.go | 1 + coderd/database/queries.sql.go | 22 +++++++++++++------ coderd/database/queries/templates.sql | 5 +++-- 6 files changed, 26 insertions(+), 10 deletions(-) create mode 100644 coderd/database/migrations/000022_template_owner.down.sql create mode 100644 coderd/database/migrations/000022_template_owner.up.sql diff --git a/coderd/database/dump.sql b/coderd/database/dump.sql index eff1e9ea6350c..6d83b3cc0f4a0 100644 --- a/coderd/database/dump.sql +++ b/coderd/database/dump.sql @@ -248,7 +248,8 @@ CREATE TABLE templates ( active_version_id uuid NOT NULL, description character varying(128) DEFAULT ''::character varying NOT NULL, max_ttl bigint DEFAULT '604800000000000'::bigint NOT NULL, - min_autostart_interval bigint DEFAULT '3600000000000'::bigint NOT NULL + min_autostart_interval bigint DEFAULT '3600000000000'::bigint NOT NULL, + owner_id uuid ); CREATE TABLE users ( @@ -479,6 +480,9 @@ ALTER TABLE ONLY template_versions ALTER TABLE ONLY templates ADD CONSTRAINT templates_organization_id_fkey FOREIGN KEY (organization_id) REFERENCES organizations(id) ON DELETE CASCADE; +ALTER TABLE ONLY templates + ADD CONSTRAINT templates_owner_id_fkey FOREIGN KEY (owner_id) REFERENCES users(id) ON DELETE RESTRICT; + ALTER TABLE ONLY workspace_agents ADD CONSTRAINT workspace_agents_resource_id_fkey FOREIGN KEY (resource_id) REFERENCES workspace_resources(id) ON DELETE CASCADE; diff --git a/coderd/database/migrations/000022_template_owner.down.sql b/coderd/database/migrations/000022_template_owner.down.sql new file mode 100644 index 0000000000000..ec6a5ee949da8 --- /dev/null +++ b/coderd/database/migrations/000022_template_owner.down.sql @@ -0,0 +1 @@ +ALTER TABLE ONLY templates DROP COLUMN IF EXISTS owner_id; diff --git a/coderd/database/migrations/000022_template_owner.up.sql b/coderd/database/migrations/000022_template_owner.up.sql new file mode 100644 index 0000000000000..800a7c590696d --- /dev/null +++ b/coderd/database/migrations/000022_template_owner.up.sql @@ -0,0 +1 @@ +ALTER TABLE ONLY templates ADD COLUMN IF NOT EXISTS owner_id uuid REFERENCES users (id) ON DELETE RESTRICT; diff --git a/coderd/database/models.go b/coderd/database/models.go index 22f47053c3955..944e11fa8187a 100644 --- a/coderd/database/models.go +++ b/coderd/database/models.go @@ -438,6 +438,7 @@ type Template struct { Description string `db:"description" json:"description"` MaxTtl int64 `db:"max_ttl" json:"max_ttl"` MinAutostartInterval int64 `db:"min_autostart_interval" json:"min_autostart_interval"` + OwnerID uuid.NullUUID `db:"owner_id" json:"owner_id"` } type TemplateVersion struct { diff --git a/coderd/database/queries.sql.go b/coderd/database/queries.sql.go index 06e5f61105269..bcf4358002c73 100644 --- a/coderd/database/queries.sql.go +++ b/coderd/database/queries.sql.go @@ -1603,7 +1603,7 @@ func (q *sqlQuerier) UpdateProvisionerJobWithCompleteByID(ctx context.Context, a const getTemplateByID = `-- name: GetTemplateByID :one SELECT - id, created_at, updated_at, organization_id, deleted, name, provisioner, active_version_id, description, max_ttl, min_autostart_interval + id, created_at, updated_at, organization_id, deleted, name, provisioner, active_version_id, description, max_ttl, min_autostart_interval, owner_id FROM templates WHERE @@ -1627,13 +1627,14 @@ func (q *sqlQuerier) GetTemplateByID(ctx context.Context, id uuid.UUID) (Templat &i.Description, &i.MaxTtl, &i.MinAutostartInterval, + &i.OwnerID, ) return i, err } const getTemplateByOrganizationAndName = `-- name: GetTemplateByOrganizationAndName :one SELECT - id, created_at, updated_at, organization_id, deleted, name, provisioner, active_version_id, description, max_ttl, min_autostart_interval + id, created_at, updated_at, organization_id, deleted, name, provisioner, active_version_id, description, max_ttl, min_autostart_interval, owner_id FROM templates WHERE @@ -1665,13 +1666,14 @@ func (q *sqlQuerier) GetTemplateByOrganizationAndName(ctx context.Context, arg G &i.Description, &i.MaxTtl, &i.MinAutostartInterval, + &i.OwnerID, ) return i, err } const getTemplatesByIDs = `-- name: GetTemplatesByIDs :many SELECT - id, created_at, updated_at, organization_id, deleted, name, provisioner, active_version_id, description, max_ttl, min_autostart_interval + id, created_at, updated_at, organization_id, deleted, name, provisioner, active_version_id, description, max_ttl, min_autostart_interval, owner_id FROM templates WHERE @@ -1699,6 +1701,7 @@ func (q *sqlQuerier) GetTemplatesByIDs(ctx context.Context, ids []uuid.UUID) ([] &i.Description, &i.MaxTtl, &i.MinAutostartInterval, + &i.OwnerID, ); err != nil { return nil, err } @@ -1715,7 +1718,7 @@ func (q *sqlQuerier) GetTemplatesByIDs(ctx context.Context, ids []uuid.UUID) ([] const getTemplatesByOrganization = `-- name: GetTemplatesByOrganization :many SELECT - id, created_at, updated_at, organization_id, deleted, name, provisioner, active_version_id, description, max_ttl, min_autostart_interval + id, created_at, updated_at, organization_id, deleted, name, provisioner, active_version_id, description, max_ttl, min_autostart_interval, owner_id FROM templates WHERE @@ -1749,6 +1752,7 @@ func (q *sqlQuerier) GetTemplatesByOrganization(ctx context.Context, arg GetTemp &i.Description, &i.MaxTtl, &i.MinAutostartInterval, + &i.OwnerID, ); err != nil { return nil, err } @@ -1775,10 +1779,11 @@ INSERT INTO active_version_id, description, max_ttl, - min_autostart_interval + min_autostart_interval, + owner_id ) VALUES - ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10) RETURNING id, created_at, updated_at, organization_id, deleted, name, provisioner, active_version_id, description, max_ttl, min_autostart_interval + ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11) RETURNING id, created_at, updated_at, organization_id, deleted, name, provisioner, active_version_id, description, max_ttl, min_autostart_interval, owner_id ` type InsertTemplateParams struct { @@ -1792,6 +1797,7 @@ type InsertTemplateParams struct { Description string `db:"description" json:"description"` MaxTtl int64 `db:"max_ttl" json:"max_ttl"` MinAutostartInterval int64 `db:"min_autostart_interval" json:"min_autostart_interval"` + OwnerID uuid.NullUUID `db:"owner_id" json:"owner_id"` } func (q *sqlQuerier) InsertTemplate(ctx context.Context, arg InsertTemplateParams) (Template, error) { @@ -1806,6 +1812,7 @@ func (q *sqlQuerier) InsertTemplate(ctx context.Context, arg InsertTemplateParam arg.Description, arg.MaxTtl, arg.MinAutostartInterval, + arg.OwnerID, ) var i Template err := row.Scan( @@ -1820,6 +1827,7 @@ func (q *sqlQuerier) InsertTemplate(ctx context.Context, arg InsertTemplateParam &i.Description, &i.MaxTtl, &i.MinAutostartInterval, + &i.OwnerID, ) return i, err } @@ -1873,7 +1881,7 @@ SET WHERE id = $1 RETURNING - id, created_at, updated_at, organization_id, deleted, name, provisioner, active_version_id, description, max_ttl, min_autostart_interval + id, created_at, updated_at, organization_id, deleted, name, provisioner, active_version_id, description, max_ttl, min_autostart_interval, owner_id ` type UpdateTemplateMetaByIDParams struct { diff --git a/coderd/database/queries/templates.sql b/coderd/database/queries/templates.sql index ffc0b9dabfb38..2ac81781d1188 100644 --- a/coderd/database/queries/templates.sql +++ b/coderd/database/queries/templates.sql @@ -49,10 +49,11 @@ INSERT INTO active_version_id, description, max_ttl, - min_autostart_interval + min_autostart_interval, + owner_id ) VALUES - ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10) RETURNING *; + ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11) RETURNING *; -- name: UpdateTemplateActiveVersionByID :exec UPDATE From 02cb2930ce57d244c3d34fe12687e41d86451369 Mon Sep 17 00:00:00 2001 From: Abhineet Jain Date: Fri, 10 Jun 2022 03:02:36 +0000 Subject: [PATCH 3/7] add owner information in apis and ui --- coderd/audit/diff_test.go | 2 ++ coderd/audit/table.go | 1 + coderd/database/databasefake/databasefake.go | 1 + coderd/templates.go | 33 ++++++++++++++----- codersdk/templates.go | 2 ++ site/src/api/typesGenerated.ts | 8 +++-- .../TemplateStats/TemplateStats.stories.tsx | 9 +++++ .../TemplateStats/TemplateStats.tsx | 5 +-- .../pages/TemplatesPage/TemplatesPageView.tsx | 3 +- site/src/testHelpers/entities.ts | 2 ++ 10 files changed, 51 insertions(+), 15 deletions(-) diff --git a/coderd/audit/diff_test.go b/coderd/audit/diff_test.go index 53f2110f07c26..912ed7d791944 100644 --- a/coderd/audit/diff_test.go +++ b/coderd/audit/diff_test.go @@ -88,6 +88,7 @@ func TestDiff(t *testing.T) { ActiveVersionID: uuid.UUID{3}, MaxTtl: int64(time.Hour), MinAutostartInterval: int64(time.Minute), + OwnerID: uuid.NullUUID{UUID: uuid.UUID{4}, Valid: true}, }, exp: audit.Map{ "id": uuid.UUID{1}.String(), @@ -97,6 +98,7 @@ func TestDiff(t *testing.T) { "active_version_id": uuid.UUID{3}.String(), "max_ttl": int64(3600000000000), "min_autostart_interval": int64(60000000000), + "owner_id": uuid.UUID{4}.String(), }, }, }) diff --git a/coderd/audit/table.go b/coderd/audit/table.go index efdf0de1d6431..09a33facd0b81 100644 --- a/coderd/audit/table.go +++ b/coderd/audit/table.go @@ -72,6 +72,7 @@ var AuditableResources = auditMap(map[any]map[string]Action{ "description": ActionTrack, "max_ttl": ActionTrack, "min_autostart_interval": ActionTrack, + "owner_id": ActionTrack, }, &database.TemplateVersion{}: { "id": ActionTrack, diff --git a/coderd/database/databasefake/databasefake.go b/coderd/database/databasefake/databasefake.go index 78f85e71c597c..87ad44a83a71c 100644 --- a/coderd/database/databasefake/databasefake.go +++ b/coderd/database/databasefake/databasefake.go @@ -1316,6 +1316,7 @@ func (q *fakeQuerier) InsertTemplate(_ context.Context, arg database.InsertTempl Description: arg.Description, MaxTtl: arg.MaxTtl, MinAutostartInterval: arg.MinAutostartInterval, + OwnerID: arg.OwnerID, } q.templates = append(q.templates, template) return template, nil diff --git a/coderd/templates.go b/coderd/templates.go index 386a360111960..88c30c953efd8 100644 --- a/coderd/templates.go +++ b/coderd/templates.go @@ -1,6 +1,7 @@ package coderd import ( + "context" "database/sql" "errors" "fmt" @@ -49,7 +50,7 @@ func (api *API) template(rw http.ResponseWriter, r *http.Request) { count = uint32(workspaceCounts[0].Count) } - httpapi.Write(rw, http.StatusOK, convertTemplate(template, count)) + httpapi.Write(rw, http.StatusOK, convertTemplate(r.Context(), api.Database, template, count)) } func (api *API) deleteTemplate(rw http.ResponseWriter, r *http.Request) { @@ -97,6 +98,7 @@ func (api *API) deleteTemplate(rw http.ResponseWriter, r *http.Request) { func (api *API) postTemplateByOrganization(rw http.ResponseWriter, r *http.Request) { var createTemplate codersdk.CreateTemplateRequest organization := httpmw.OrganizationParam(r) + apiKey := httpmw.APIKey(r) if !api.Authorize(rw, r, rbac.ActionCreate, rbac.ResourceTemplate.InOrg(organization.ID)) { return } @@ -175,6 +177,10 @@ func (api *API) postTemplateByOrganization(rw http.ResponseWriter, r *http.Reque Description: createTemplate.Description, MaxTtl: int64(maxTTL), MinAutostartInterval: int64(minAutostartInterval), + OwnerID: uuid.NullUUID{ + UUID: apiKey.UserID, + Valid: true, + }, }) if err != nil { return xerrors.Errorf("insert template: %s", err) @@ -208,7 +214,7 @@ func (api *API) postTemplateByOrganization(rw http.ResponseWriter, r *http.Reque } } - template = convertTemplate(dbTemplate, 0) + template = convertTemplate(r.Context(), db, dbTemplate, 0) return nil }) if err != nil { @@ -258,7 +264,7 @@ func (api *API) templatesByOrganization(rw http.ResponseWriter, r *http.Request) return } - httpapi.Write(rw, http.StatusOK, convertTemplates(templates, workspaceCounts)) + httpapi.Write(rw, http.StatusOK, convertTemplates(r.Context(), api.Database, templates, workspaceCounts)) } func (api *API) templateByOrganizationAndName(rw http.ResponseWriter, r *http.Request) { @@ -304,7 +310,7 @@ func (api *API) templateByOrganizationAndName(rw http.ResponseWriter, r *http.Re count = uint32(workspaceCounts[0].Count) } - httpapi.Write(rw, http.StatusOK, convertTemplate(template, count)) + httpapi.Write(rw, http.StatusOK, convertTemplate(r.Context(), api.Database, template, count)) } func (api *API) patchTemplateMeta(rw http.ResponseWriter, r *http.Request) { @@ -400,10 +406,10 @@ func (api *API) patchTemplateMeta(rw http.ResponseWriter, r *http.Request) { return } - httpapi.Write(rw, http.StatusOK, convertTemplate(updated, count)) + httpapi.Write(rw, http.StatusOK, convertTemplate(r.Context(), api.Database, updated, count)) } -func convertTemplates(templates []database.Template, workspaceCounts []database.GetWorkspaceOwnerCountsByTemplateIDsRow) []codersdk.Template { +func convertTemplates(ctx context.Context, db database.Store, templates []database.Template, workspaceCounts []database.GetWorkspaceOwnerCountsByTemplateIDsRow) []codersdk.Template { apiTemplates := make([]codersdk.Template, 0, len(templates)) for _, template := range templates { found := false @@ -411,18 +417,25 @@ func convertTemplates(templates []database.Template, workspaceCounts []database. if workspaceCount.TemplateID.String() != template.ID.String() { continue } - apiTemplates = append(apiTemplates, convertTemplate(template, uint32(workspaceCount.Count))) + apiTemplates = append(apiTemplates, convertTemplate(ctx, db, template, uint32(workspaceCount.Count))) found = true break } if !found { - apiTemplates = append(apiTemplates, convertTemplate(template, uint32(0))) + apiTemplates = append(apiTemplates, convertTemplate(ctx, db, template, uint32(0))) } } return apiTemplates } -func convertTemplate(template database.Template, workspaceOwnerCount uint32) codersdk.Template { +func convertTemplate(ctx context.Context, db database.Store, template database.Template, workspaceOwnerCount uint32) codersdk.Template { + var ownerName string + if template.OwnerID.Valid { + owner, err := db.GetUserByID(ctx, template.OwnerID.UUID) + if err == nil { + ownerName = owner.Username + } + } return codersdk.Template{ ID: template.ID, CreatedAt: template.CreatedAt, @@ -435,5 +448,7 @@ func convertTemplate(template database.Template, workspaceOwnerCount uint32) cod Description: template.Description, MaxTTLMillis: time.Duration(template.MaxTtl).Milliseconds(), MinAutostartIntervalMillis: time.Duration(template.MinAutostartInterval).Milliseconds(), + OwnerID: template.OwnerID, + OwnerName: ownerName, } } diff --git a/codersdk/templates.go b/codersdk/templates.go index e137c3fca05b3..97a4507916438 100644 --- a/codersdk/templates.go +++ b/codersdk/templates.go @@ -25,6 +25,8 @@ type Template struct { Description string `json:"description"` MaxTTLMillis int64 `json:"max_ttl_ms"` MinAutostartIntervalMillis int64 `json:"min_autostart_interval_ms"` + OwnerID uuid.NullUUID `json:"owner_id"` + OwnerName string `json:"owner_name"` } type UpdateActiveTemplateVersion struct { diff --git a/site/src/api/typesGenerated.ts b/site/src/api/typesGenerated.ts index 90c651c61cd9a..40d133b4d550a 100644 --- a/site/src/api/typesGenerated.ts +++ b/site/src/api/typesGenerated.ts @@ -247,6 +247,8 @@ export interface Template { readonly description: string readonly max_ttl_ms: number readonly min_autostart_interval_ms: number + readonly owner_id?: string + readonly owner_name: string } // From codersdk/templateversions.go:14:6 @@ -276,12 +278,12 @@ export interface TemplateVersionParameter { readonly default_source_value: boolean } -// From codersdk/templates.go:98:6 +// From codersdk/templates.go:100:6 export interface TemplateVersionsByTemplateRequest extends Pagination { readonly template_id: string } -// From codersdk/templates.go:30:6 +// From codersdk/templates.go:32:6 export interface UpdateActiveTemplateVersion { readonly id: string } @@ -291,7 +293,7 @@ export interface UpdateRoles { readonly roles: string[] } -// From codersdk/templates.go:34:6 +// From codersdk/templates.go:36:6 export interface UpdateTemplateMeta { readonly description?: string readonly max_ttl_ms?: number diff --git a/site/src/components/TemplateStats/TemplateStats.stories.tsx b/site/src/components/TemplateStats/TemplateStats.stories.tsx index 3056187d110d4..c8e3a912a6f8f 100644 --- a/site/src/components/TemplateStats/TemplateStats.stories.tsx +++ b/site/src/components/TemplateStats/TemplateStats.stories.tsx @@ -23,3 +23,12 @@ UsedByMany.args = { }, activeVersion: Mocks.MockTemplateVersion, } + +export const UnknownOwner = Template.bind({}) +UnknownOwner.args = { + template: { + ...Mocks.MockTemplate, + owner_name: "", + }, + activeVersion: Mocks.MockTemplateVersion, +} diff --git a/site/src/components/TemplateStats/TemplateStats.tsx b/site/src/components/TemplateStats/TemplateStats.tsx index 458d2d58c2119..d38176cefea14 100644 --- a/site/src/components/TemplateStats/TemplateStats.tsx +++ b/site/src/components/TemplateStats/TemplateStats.tsx @@ -13,7 +13,8 @@ const Language = { lastUpdateLabel: "Last updated", userPlural: "users", userSingular: "user", - createdByLabel: "Created by" + createdByLabel: "Created by", + defaultTemplateCreator: "", } export interface TemplateStatsProps { @@ -49,7 +50,7 @@ export const TemplateStats: FC = ({ template, activeVersion
{Language.createdByLabel} - admin + {template.owner_name || Language.defaultTemplateCreator}
) diff --git a/site/src/pages/TemplatesPage/TemplatesPageView.tsx b/site/src/pages/TemplatesPage/TemplatesPageView.tsx index 023f934ef2a30..4801e6a619fb0 100644 --- a/site/src/pages/TemplatesPage/TemplatesPageView.tsx +++ b/site/src/pages/TemplatesPage/TemplatesPageView.tsx @@ -50,6 +50,7 @@ export const Language = { templateTooltipText: "With templates you can create a common configuration for your workspaces using Terraform.", templateTooltipLink: "Manage templates", createdByLabel: "Created by", + defaultTemplateOwner: "", } const TemplateHelpTooltip: React.FC = () => { @@ -139,7 +140,7 @@ export const TemplatesPageView: FC = (props) => { {Language.developerCount(template.workspace_owner_count)} {dayjs().to(dayjs(template.updated_at))} - admin + {template.owner_name || Language.defaultTemplateOwner}
diff --git a/site/src/testHelpers/entities.ts b/site/src/testHelpers/entities.ts index 53414283e4cc9..6db3b5f04e628 100644 --- a/site/src/testHelpers/entities.ts +++ b/site/src/testHelpers/entities.ts @@ -114,6 +114,8 @@ export const MockTemplate: TypesGen.Template = { description: "This is a test description.", max_ttl_ms: 604800000, min_autostart_interval_ms: 3600000, + owner_id: "test-owner-id", + owner_name: "test_owner", } export const MockWorkspaceAutostartDisabled: TypesGen.UpdateWorkspaceAutostartRequest = { From 460a8189bfed4bee5dc2151e5f987518e7dad5a0 Mon Sep 17 00:00:00 2001 From: Abhineet Jain Date: Fri, 10 Jun 2022 15:35:43 +0000 Subject: [PATCH 4/7] update minWidth for statItem --- site/src/components/TemplateStats/TemplateStats.tsx | 2 +- site/src/components/WorkspaceBuildStats/WorkspaceBuildStats.tsx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/site/src/components/TemplateStats/TemplateStats.tsx b/site/src/components/TemplateStats/TemplateStats.tsx index d38176cefea14..ad6f619d10027 100644 --- a/site/src/components/TemplateStats/TemplateStats.tsx +++ b/site/src/components/TemplateStats/TemplateStats.tsx @@ -70,7 +70,7 @@ const useStyles = makeStyles((theme) => ({ }, statItem: { - minWidth: theme.spacing(20), + minWidth: "20%", padding: theme.spacing(2), paddingTop: theme.spacing(1.75), }, diff --git a/site/src/components/WorkspaceBuildStats/WorkspaceBuildStats.tsx b/site/src/components/WorkspaceBuildStats/WorkspaceBuildStats.tsx index 0db8dfc143362..4b00dd0584f55 100644 --- a/site/src/components/WorkspaceBuildStats/WorkspaceBuildStats.tsx +++ b/site/src/components/WorkspaceBuildStats/WorkspaceBuildStats.tsx @@ -69,7 +69,7 @@ const useStyles = makeStyles((theme) => ({ }, statItem: { - minWidth: theme.spacing(20), + minWidth: "16%", padding: theme.spacing(2), paddingTop: theme.spacing(1.75), }, From 6760cf968761ba7dce47e13cb54846c061f11676 Mon Sep 17 00:00:00 2001 From: Abhineet Jain Date: Fri, 10 Jun 2022 17:25:54 +0000 Subject: [PATCH 5/7] rename owner to created_by --- coderd/audit/diff_test.go | 4 +-- coderd/audit/table.go | 2 +- coderd/database/databasefake/databasefake.go | 2 +- coderd/database/dump.sql | 6 ++-- .../migrations/000022_template_owner.down.sql | 2 +- .../migrations/000022_template_owner.up.sql | 2 +- coderd/database/models.go | 2 +- coderd/database/queries.sql.go | 28 +++++++++---------- coderd/database/queries/templates.sql | 2 +- coderd/templates.go | 14 +++++----- codersdk/templates.go | 4 +-- site/src/api/typesGenerated.ts | 4 +-- .../TemplateStats/TemplateStats.stories.tsx | 6 ++-- .../TemplateStats/TemplateStats.tsx | 2 +- .../pages/TemplatesPage/TemplatesPageView.tsx | 2 +- site/src/testHelpers/entities.ts | 4 +-- 16 files changed, 43 insertions(+), 43 deletions(-) diff --git a/coderd/audit/diff_test.go b/coderd/audit/diff_test.go index 912ed7d791944..ba91692a0734f 100644 --- a/coderd/audit/diff_test.go +++ b/coderd/audit/diff_test.go @@ -88,7 +88,7 @@ func TestDiff(t *testing.T) { ActiveVersionID: uuid.UUID{3}, MaxTtl: int64(time.Hour), MinAutostartInterval: int64(time.Minute), - OwnerID: uuid.NullUUID{UUID: uuid.UUID{4}, Valid: true}, + CreatedBy: uuid.NullUUID{UUID: uuid.UUID{4}, Valid: true}, }, exp: audit.Map{ "id": uuid.UUID{1}.String(), @@ -98,7 +98,7 @@ func TestDiff(t *testing.T) { "active_version_id": uuid.UUID{3}.String(), "max_ttl": int64(3600000000000), "min_autostart_interval": int64(60000000000), - "owner_id": uuid.UUID{4}.String(), + "created_by": uuid.UUID{4}.String(), }, }, }) diff --git a/coderd/audit/table.go b/coderd/audit/table.go index 09a33facd0b81..7562472f3c583 100644 --- a/coderd/audit/table.go +++ b/coderd/audit/table.go @@ -72,7 +72,7 @@ var AuditableResources = auditMap(map[any]map[string]Action{ "description": ActionTrack, "max_ttl": ActionTrack, "min_autostart_interval": ActionTrack, - "owner_id": ActionTrack, + "created_by": ActionTrack, }, &database.TemplateVersion{}: { "id": ActionTrack, diff --git a/coderd/database/databasefake/databasefake.go b/coderd/database/databasefake/databasefake.go index 87ad44a83a71c..4374a502c3dcc 100644 --- a/coderd/database/databasefake/databasefake.go +++ b/coderd/database/databasefake/databasefake.go @@ -1316,7 +1316,7 @@ func (q *fakeQuerier) InsertTemplate(_ context.Context, arg database.InsertTempl Description: arg.Description, MaxTtl: arg.MaxTtl, MinAutostartInterval: arg.MinAutostartInterval, - OwnerID: arg.OwnerID, + CreatedBy: arg.CreatedBy, } q.templates = append(q.templates, template) return template, nil diff --git a/coderd/database/dump.sql b/coderd/database/dump.sql index 6d83b3cc0f4a0..95ef9ff0df3d6 100644 --- a/coderd/database/dump.sql +++ b/coderd/database/dump.sql @@ -249,7 +249,7 @@ CREATE TABLE templates ( description character varying(128) DEFAULT ''::character varying NOT NULL, max_ttl bigint DEFAULT '604800000000000'::bigint NOT NULL, min_autostart_interval bigint DEFAULT '3600000000000'::bigint NOT NULL, - owner_id uuid + created_by uuid ); CREATE TABLE users ( @@ -478,10 +478,10 @@ ALTER TABLE ONLY template_versions ADD CONSTRAINT template_versions_template_id_fkey FOREIGN KEY (template_id) REFERENCES templates(id) ON DELETE CASCADE; ALTER TABLE ONLY templates - ADD CONSTRAINT templates_organization_id_fkey FOREIGN KEY (organization_id) REFERENCES organizations(id) ON DELETE CASCADE; + ADD CONSTRAINT templates_created_by_fkey FOREIGN KEY (created_by) REFERENCES users(id) ON DELETE RESTRICT; ALTER TABLE ONLY templates - ADD CONSTRAINT templates_owner_id_fkey FOREIGN KEY (owner_id) REFERENCES users(id) ON DELETE RESTRICT; + ADD CONSTRAINT templates_organization_id_fkey FOREIGN KEY (organization_id) REFERENCES organizations(id) ON DELETE CASCADE; ALTER TABLE ONLY workspace_agents ADD CONSTRAINT workspace_agents_resource_id_fkey FOREIGN KEY (resource_id) REFERENCES workspace_resources(id) ON DELETE CASCADE; diff --git a/coderd/database/migrations/000022_template_owner.down.sql b/coderd/database/migrations/000022_template_owner.down.sql index ec6a5ee949da8..435291e5ccb10 100644 --- a/coderd/database/migrations/000022_template_owner.down.sql +++ b/coderd/database/migrations/000022_template_owner.down.sql @@ -1 +1 @@ -ALTER TABLE ONLY templates DROP COLUMN IF EXISTS owner_id; +ALTER TABLE ONLY templates DROP COLUMN IF EXISTS created_by; diff --git a/coderd/database/migrations/000022_template_owner.up.sql b/coderd/database/migrations/000022_template_owner.up.sql index 800a7c590696d..7ca6f235591bc 100644 --- a/coderd/database/migrations/000022_template_owner.up.sql +++ b/coderd/database/migrations/000022_template_owner.up.sql @@ -1 +1 @@ -ALTER TABLE ONLY templates ADD COLUMN IF NOT EXISTS owner_id uuid REFERENCES users (id) ON DELETE RESTRICT; +ALTER TABLE ONLY templates ADD COLUMN IF NOT EXISTS created_by uuid REFERENCES users (id) ON DELETE RESTRICT; diff --git a/coderd/database/models.go b/coderd/database/models.go index 944e11fa8187a..2454049da0ac0 100644 --- a/coderd/database/models.go +++ b/coderd/database/models.go @@ -438,7 +438,7 @@ type Template struct { Description string `db:"description" json:"description"` MaxTtl int64 `db:"max_ttl" json:"max_ttl"` MinAutostartInterval int64 `db:"min_autostart_interval" json:"min_autostart_interval"` - OwnerID uuid.NullUUID `db:"owner_id" json:"owner_id"` + CreatedBy uuid.NullUUID `db:"created_by" json:"created_by"` } type TemplateVersion struct { diff --git a/coderd/database/queries.sql.go b/coderd/database/queries.sql.go index bcf4358002c73..9091bd57b6caa 100644 --- a/coderd/database/queries.sql.go +++ b/coderd/database/queries.sql.go @@ -1603,7 +1603,7 @@ func (q *sqlQuerier) UpdateProvisionerJobWithCompleteByID(ctx context.Context, a const getTemplateByID = `-- name: GetTemplateByID :one SELECT - id, created_at, updated_at, organization_id, deleted, name, provisioner, active_version_id, description, max_ttl, min_autostart_interval, owner_id + id, created_at, updated_at, organization_id, deleted, name, provisioner, active_version_id, description, max_ttl, min_autostart_interval, created_by FROM templates WHERE @@ -1627,14 +1627,14 @@ func (q *sqlQuerier) GetTemplateByID(ctx context.Context, id uuid.UUID) (Templat &i.Description, &i.MaxTtl, &i.MinAutostartInterval, - &i.OwnerID, + &i.CreatedBy, ) return i, err } const getTemplateByOrganizationAndName = `-- name: GetTemplateByOrganizationAndName :one SELECT - id, created_at, updated_at, organization_id, deleted, name, provisioner, active_version_id, description, max_ttl, min_autostart_interval, owner_id + id, created_at, updated_at, organization_id, deleted, name, provisioner, active_version_id, description, max_ttl, min_autostart_interval, created_by FROM templates WHERE @@ -1666,14 +1666,14 @@ func (q *sqlQuerier) GetTemplateByOrganizationAndName(ctx context.Context, arg G &i.Description, &i.MaxTtl, &i.MinAutostartInterval, - &i.OwnerID, + &i.CreatedBy, ) return i, err } const getTemplatesByIDs = `-- name: GetTemplatesByIDs :many SELECT - id, created_at, updated_at, organization_id, deleted, name, provisioner, active_version_id, description, max_ttl, min_autostart_interval, owner_id + id, created_at, updated_at, organization_id, deleted, name, provisioner, active_version_id, description, max_ttl, min_autostart_interval, created_by FROM templates WHERE @@ -1701,7 +1701,7 @@ func (q *sqlQuerier) GetTemplatesByIDs(ctx context.Context, ids []uuid.UUID) ([] &i.Description, &i.MaxTtl, &i.MinAutostartInterval, - &i.OwnerID, + &i.CreatedBy, ); err != nil { return nil, err } @@ -1718,7 +1718,7 @@ func (q *sqlQuerier) GetTemplatesByIDs(ctx context.Context, ids []uuid.UUID) ([] const getTemplatesByOrganization = `-- name: GetTemplatesByOrganization :many SELECT - id, created_at, updated_at, organization_id, deleted, name, provisioner, active_version_id, description, max_ttl, min_autostart_interval, owner_id + id, created_at, updated_at, organization_id, deleted, name, provisioner, active_version_id, description, max_ttl, min_autostart_interval, created_by FROM templates WHERE @@ -1752,7 +1752,7 @@ func (q *sqlQuerier) GetTemplatesByOrganization(ctx context.Context, arg GetTemp &i.Description, &i.MaxTtl, &i.MinAutostartInterval, - &i.OwnerID, + &i.CreatedBy, ); err != nil { return nil, err } @@ -1780,10 +1780,10 @@ INSERT INTO description, max_ttl, min_autostart_interval, - owner_id + created_by ) VALUES - ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11) RETURNING id, created_at, updated_at, organization_id, deleted, name, provisioner, active_version_id, description, max_ttl, min_autostart_interval, owner_id + ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11) RETURNING id, created_at, updated_at, organization_id, deleted, name, provisioner, active_version_id, description, max_ttl, min_autostart_interval, created_by ` type InsertTemplateParams struct { @@ -1797,7 +1797,7 @@ type InsertTemplateParams struct { Description string `db:"description" json:"description"` MaxTtl int64 `db:"max_ttl" json:"max_ttl"` MinAutostartInterval int64 `db:"min_autostart_interval" json:"min_autostart_interval"` - OwnerID uuid.NullUUID `db:"owner_id" json:"owner_id"` + CreatedBy uuid.NullUUID `db:"created_by" json:"created_by"` } func (q *sqlQuerier) InsertTemplate(ctx context.Context, arg InsertTemplateParams) (Template, error) { @@ -1812,7 +1812,7 @@ func (q *sqlQuerier) InsertTemplate(ctx context.Context, arg InsertTemplateParam arg.Description, arg.MaxTtl, arg.MinAutostartInterval, - arg.OwnerID, + arg.CreatedBy, ) var i Template err := row.Scan( @@ -1827,7 +1827,7 @@ func (q *sqlQuerier) InsertTemplate(ctx context.Context, arg InsertTemplateParam &i.Description, &i.MaxTtl, &i.MinAutostartInterval, - &i.OwnerID, + &i.CreatedBy, ) return i, err } @@ -1881,7 +1881,7 @@ SET WHERE id = $1 RETURNING - id, created_at, updated_at, organization_id, deleted, name, provisioner, active_version_id, description, max_ttl, min_autostart_interval, owner_id + id, created_at, updated_at, organization_id, deleted, name, provisioner, active_version_id, description, max_ttl, min_autostart_interval, created_by ` type UpdateTemplateMetaByIDParams struct { diff --git a/coderd/database/queries/templates.sql b/coderd/database/queries/templates.sql index 2ac81781d1188..c3b3753083351 100644 --- a/coderd/database/queries/templates.sql +++ b/coderd/database/queries/templates.sql @@ -50,7 +50,7 @@ INSERT INTO description, max_ttl, min_autostart_interval, - owner_id + created_by ) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11) RETURNING *; diff --git a/coderd/templates.go b/coderd/templates.go index 88c30c953efd8..05f5227c9cafc 100644 --- a/coderd/templates.go +++ b/coderd/templates.go @@ -177,7 +177,7 @@ func (api *API) postTemplateByOrganization(rw http.ResponseWriter, r *http.Reque Description: createTemplate.Description, MaxTtl: int64(maxTTL), MinAutostartInterval: int64(minAutostartInterval), - OwnerID: uuid.NullUUID{ + CreatedBy: uuid.NullUUID{ UUID: apiKey.UserID, Valid: true, }, @@ -429,11 +429,11 @@ func convertTemplates(ctx context.Context, db database.Store, templates []databa } func convertTemplate(ctx context.Context, db database.Store, template database.Template, workspaceOwnerCount uint32) codersdk.Template { - var ownerName string - if template.OwnerID.Valid { - owner, err := db.GetUserByID(ctx, template.OwnerID.UUID) + var createdByName string + if template.CreatedBy.Valid { + creator, err := db.GetUserByID(ctx, template.CreatedBy.UUID) if err == nil { - ownerName = owner.Username + createdByName = creator.Username } } return codersdk.Template{ @@ -448,7 +448,7 @@ func convertTemplate(ctx context.Context, db database.Store, template database.T Description: template.Description, MaxTTLMillis: time.Duration(template.MaxTtl).Milliseconds(), MinAutostartIntervalMillis: time.Duration(template.MinAutostartInterval).Milliseconds(), - OwnerID: template.OwnerID, - OwnerName: ownerName, + CreatedByID: template.CreatedBy, + CreatedByName: createdByName, } } diff --git a/codersdk/templates.go b/codersdk/templates.go index 97a4507916438..31f1ea97d9b59 100644 --- a/codersdk/templates.go +++ b/codersdk/templates.go @@ -25,8 +25,8 @@ type Template struct { Description string `json:"description"` MaxTTLMillis int64 `json:"max_ttl_ms"` MinAutostartIntervalMillis int64 `json:"min_autostart_interval_ms"` - OwnerID uuid.NullUUID `json:"owner_id"` - OwnerName string `json:"owner_name"` + CreatedByID uuid.NullUUID `json:"created_by_id"` + CreatedByName string `json:"created_by_name"` } type UpdateActiveTemplateVersion struct { diff --git a/site/src/api/typesGenerated.ts b/site/src/api/typesGenerated.ts index 40d133b4d550a..9922816060317 100644 --- a/site/src/api/typesGenerated.ts +++ b/site/src/api/typesGenerated.ts @@ -247,8 +247,8 @@ export interface Template { readonly description: string readonly max_ttl_ms: number readonly min_autostart_interval_ms: number - readonly owner_id?: string - readonly owner_name: string + readonly created_by_id?: string + readonly created_by_name: string } // From codersdk/templateversions.go:14:6 diff --git a/site/src/components/TemplateStats/TemplateStats.stories.tsx b/site/src/components/TemplateStats/TemplateStats.stories.tsx index c8e3a912a6f8f..fb7f36d894652 100644 --- a/site/src/components/TemplateStats/TemplateStats.stories.tsx +++ b/site/src/components/TemplateStats/TemplateStats.stories.tsx @@ -24,11 +24,11 @@ UsedByMany.args = { activeVersion: Mocks.MockTemplateVersion, } -export const UnknownOwner = Template.bind({}) -UnknownOwner.args = { +export const UnknownCreator = Template.bind({}) +UnknownCreator.args = { template: { ...Mocks.MockTemplate, - owner_name: "", + created_by_name: "", }, activeVersion: Mocks.MockTemplateVersion, } diff --git a/site/src/components/TemplateStats/TemplateStats.tsx b/site/src/components/TemplateStats/TemplateStats.tsx index ad6f619d10027..fed612f45f019 100644 --- a/site/src/components/TemplateStats/TemplateStats.tsx +++ b/site/src/components/TemplateStats/TemplateStats.tsx @@ -50,7 +50,7 @@ export const TemplateStats: FC = ({ template, activeVersion
{Language.createdByLabel} - {template.owner_name || Language.defaultTemplateCreator} + {template.created_by_name || Language.defaultTemplateCreator}
) diff --git a/site/src/pages/TemplatesPage/TemplatesPageView.tsx b/site/src/pages/TemplatesPage/TemplatesPageView.tsx index 4801e6a619fb0..9ce4a9d67b090 100644 --- a/site/src/pages/TemplatesPage/TemplatesPageView.tsx +++ b/site/src/pages/TemplatesPage/TemplatesPageView.tsx @@ -140,7 +140,7 @@ export const TemplatesPageView: FC = (props) => { {Language.developerCount(template.workspace_owner_count)} {dayjs().to(dayjs(template.updated_at))} - {template.owner_name || Language.defaultTemplateOwner} + {template.created_by_name || Language.defaultTemplateOwner}
diff --git a/site/src/testHelpers/entities.ts b/site/src/testHelpers/entities.ts index 6db3b5f04e628..c96e35dc116ff 100644 --- a/site/src/testHelpers/entities.ts +++ b/site/src/testHelpers/entities.ts @@ -114,8 +114,8 @@ export const MockTemplate: TypesGen.Template = { description: "This is a test description.", max_ttl_ms: 604800000, min_autostart_interval_ms: 3600000, - owner_id: "test-owner-id", - owner_name: "test_owner", + created_by_id: "test-owner-id", + created_by_name: "test_owner", } export const MockWorkspaceAutostartDisabled: TypesGen.UpdateWorkspaceAutostartRequest = { From 5eaf8ad5268f8e0a8ee76987f648158f5565e3eb Mon Sep 17 00:00:00 2001 From: Abhineet Jain Date: Fri, 10 Jun 2022 17:33:53 +0000 Subject: [PATCH 6/7] missing refactor to created_by --- ...ate_owner.down.sql => 000022_template_created_by.down.sql} | 0 ...emplate_owner.up.sql => 000022_template_created_by.up.sql} | 0 site/src/pages/TemplatesPage/TemplatesPageView.tsx | 4 ++-- site/src/testHelpers/entities.ts | 4 ++-- 4 files changed, 4 insertions(+), 4 deletions(-) rename coderd/database/migrations/{000022_template_owner.down.sql => 000022_template_created_by.down.sql} (100%) rename coderd/database/migrations/{000022_template_owner.up.sql => 000022_template_created_by.up.sql} (100%) diff --git a/coderd/database/migrations/000022_template_owner.down.sql b/coderd/database/migrations/000022_template_created_by.down.sql similarity index 100% rename from coderd/database/migrations/000022_template_owner.down.sql rename to coderd/database/migrations/000022_template_created_by.down.sql diff --git a/coderd/database/migrations/000022_template_owner.up.sql b/coderd/database/migrations/000022_template_created_by.up.sql similarity index 100% rename from coderd/database/migrations/000022_template_owner.up.sql rename to coderd/database/migrations/000022_template_created_by.up.sql diff --git a/site/src/pages/TemplatesPage/TemplatesPageView.tsx b/site/src/pages/TemplatesPage/TemplatesPageView.tsx index 9ce4a9d67b090..deda1cad6cdcc 100644 --- a/site/src/pages/TemplatesPage/TemplatesPageView.tsx +++ b/site/src/pages/TemplatesPage/TemplatesPageView.tsx @@ -50,7 +50,7 @@ export const Language = { templateTooltipText: "With templates you can create a common configuration for your workspaces using Terraform.", templateTooltipLink: "Manage templates", createdByLabel: "Created by", - defaultTemplateOwner: "", + defaultTemplateCreator: "", } const TemplateHelpTooltip: React.FC = () => { @@ -140,7 +140,7 @@ export const TemplatesPageView: FC = (props) => { {Language.developerCount(template.workspace_owner_count)} {dayjs().to(dayjs(template.updated_at))} - {template.created_by_name || Language.defaultTemplateOwner} + {template.created_by_name || Language.defaultTemplateCreator}
diff --git a/site/src/testHelpers/entities.ts b/site/src/testHelpers/entities.ts index c96e35dc116ff..b37e038529dbc 100644 --- a/site/src/testHelpers/entities.ts +++ b/site/src/testHelpers/entities.ts @@ -114,8 +114,8 @@ export const MockTemplate: TypesGen.Template = { description: "This is a test description.", max_ttl_ms: 604800000, min_autostart_interval_ms: 3600000, - created_by_id: "test-owner-id", - created_by_name: "test_owner", + created_by_id: "test-creator-id", + created_by_name: "test_creator", } export const MockWorkspaceAutostartDisabled: TypesGen.UpdateWorkspaceAutostartRequest = { From 3f73dfd2447dbe60b22d537d205bc827f09b3ebb Mon Sep 17 00:00:00 2001 From: Abhineet Jain Date: Fri, 10 Jun 2022 19:02:41 +0000 Subject: [PATCH 7/7] handle errors in fetching created_by names --- coderd/templates.go | 82 ++++++++++++++++++++++++++++++++++++--------- 1 file changed, 66 insertions(+), 16 deletions(-) diff --git a/coderd/templates.go b/coderd/templates.go index 05f5227c9cafc..d79bd19f70fa2 100644 --- a/coderd/templates.go +++ b/coderd/templates.go @@ -50,7 +50,16 @@ func (api *API) template(rw http.ResponseWriter, r *http.Request) { count = uint32(workspaceCounts[0].Count) } - httpapi.Write(rw, http.StatusOK, convertTemplate(r.Context(), api.Database, template, count)) + createdByNameMap, err := getCreatedByNamesByTemplateIDs(r.Context(), api.Database, []database.Template{template}) + if err != nil { + httpapi.Write(rw, http.StatusInternalServerError, httpapi.Response{ + Message: "Internal error fetching creator name.", + Detail: err.Error(), + }) + return + } + + httpapi.Write(rw, http.StatusOK, convertTemplate(template, count, createdByNameMap[template.ID.String()])) } func (api *API) deleteTemplate(rw http.ResponseWriter, r *http.Request) { @@ -214,7 +223,12 @@ func (api *API) postTemplateByOrganization(rw http.ResponseWriter, r *http.Reque } } - template = convertTemplate(r.Context(), db, dbTemplate, 0) + createdByNameMap, err := getCreatedByNamesByTemplateIDs(r.Context(), db, []database.Template{dbTemplate}) + if err != nil { + return xerrors.Errorf("get creator name: %w", err) + } + + template = convertTemplate(dbTemplate, 0, createdByNameMap[dbTemplate.ID.String()]) return nil }) if err != nil { @@ -264,7 +278,16 @@ func (api *API) templatesByOrganization(rw http.ResponseWriter, r *http.Request) return } - httpapi.Write(rw, http.StatusOK, convertTemplates(r.Context(), api.Database, templates, workspaceCounts)) + createdByNameMap, err := getCreatedByNamesByTemplateIDs(r.Context(), api.Database, templates) + if err != nil { + httpapi.Write(rw, http.StatusInternalServerError, httpapi.Response{ + Message: "Internal error fetching creator names.", + Detail: err.Error(), + }) + return + } + + httpapi.Write(rw, http.StatusOK, convertTemplates(templates, workspaceCounts, createdByNameMap)) } func (api *API) templateByOrganizationAndName(rw http.ResponseWriter, r *http.Request) { @@ -310,7 +333,16 @@ func (api *API) templateByOrganizationAndName(rw http.ResponseWriter, r *http.Re count = uint32(workspaceCounts[0].Count) } - httpapi.Write(rw, http.StatusOK, convertTemplate(r.Context(), api.Database, template, count)) + createdByNameMap, err := getCreatedByNamesByTemplateIDs(r.Context(), api.Database, []database.Template{template}) + if err != nil { + httpapi.Write(rw, http.StatusInternalServerError, httpapi.Response{ + Message: "Internal error fetching creator name.", + Detail: err.Error(), + }) + return + } + + httpapi.Write(rw, http.StatusOK, convertTemplate(template, count, createdByNameMap[template.ID.String()])) } func (api *API) patchTemplateMeta(rw http.ResponseWriter, r *http.Request) { @@ -406,10 +438,35 @@ func (api *API) patchTemplateMeta(rw http.ResponseWriter, r *http.Request) { return } - httpapi.Write(rw, http.StatusOK, convertTemplate(r.Context(), api.Database, updated, count)) + createdByNameMap, err := getCreatedByNamesByTemplateIDs(r.Context(), api.Database, []database.Template{updated}) + if err != nil { + httpapi.Write(rw, http.StatusInternalServerError, httpapi.Response{ + Message: "Internal error fetching creator name.", + Detail: err.Error(), + }) + return + } + + httpapi.Write(rw, http.StatusOK, convertTemplate(updated, count, createdByNameMap[updated.ID.String()])) +} + +func getCreatedByNamesByTemplateIDs(ctx context.Context, db database.Store, templates []database.Template) (map[string]string, error) { + creators := make(map[string]string, len(templates)) + for _, template := range templates { + if template.CreatedBy.Valid { + creator, err := db.GetUserByID(ctx, template.CreatedBy.UUID) + if err != nil { + return map[string]string{}, err + } + creators[template.ID.String()] = creator.Username + } else { + creators[template.ID.String()] = "" + } + } + return creators, nil } -func convertTemplates(ctx context.Context, db database.Store, templates []database.Template, workspaceCounts []database.GetWorkspaceOwnerCountsByTemplateIDsRow) []codersdk.Template { +func convertTemplates(templates []database.Template, workspaceCounts []database.GetWorkspaceOwnerCountsByTemplateIDsRow, createdByNameMap map[string]string) []codersdk.Template { apiTemplates := make([]codersdk.Template, 0, len(templates)) for _, template := range templates { found := false @@ -417,25 +474,18 @@ func convertTemplates(ctx context.Context, db database.Store, templates []databa if workspaceCount.TemplateID.String() != template.ID.String() { continue } - apiTemplates = append(apiTemplates, convertTemplate(ctx, db, template, uint32(workspaceCount.Count))) + apiTemplates = append(apiTemplates, convertTemplate(template, uint32(workspaceCount.Count), createdByNameMap[template.ID.String()])) found = true break } if !found { - apiTemplates = append(apiTemplates, convertTemplate(ctx, db, template, uint32(0))) + apiTemplates = append(apiTemplates, convertTemplate(template, uint32(0), createdByNameMap[template.ID.String()])) } } return apiTemplates } -func convertTemplate(ctx context.Context, db database.Store, template database.Template, workspaceOwnerCount uint32) codersdk.Template { - var createdByName string - if template.CreatedBy.Valid { - creator, err := db.GetUserByID(ctx, template.CreatedBy.UUID) - if err == nil { - createdByName = creator.Username - } - } +func convertTemplate(template database.Template, workspaceOwnerCount uint32, createdByName string) codersdk.Template { return codersdk.Template{ ID: template.ID, CreatedAt: template.CreatedAt, 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