mirror of
https://github.com/coder/coder.git
synced 2025-07-03 16:13:58 +00:00
feat: store and display template creator (#2228)
* design commit * add owner_id to templates table * add owner information in apis and ui * update minWidth for statItem * rename owner to created_by * missing refactor to created_by * handle errors in fetching created_by names
This commit is contained in:
@ -1,6 +1,7 @@
|
||||
package coderd
|
||||
|
||||
import (
|
||||
"context"
|
||||
"database/sql"
|
||||
"errors"
|
||||
"fmt"
|
||||
@ -49,7 +50,16 @@ func (api *API) template(rw http.ResponseWriter, r *http.Request) {
|
||||
count = uint32(workspaceCounts[0].Count)
|
||||
}
|
||||
|
||||
httpapi.Write(rw, http.StatusOK, convertTemplate(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) {
|
||||
@ -97,6 +107,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 +186,10 @@ func (api *API) postTemplateByOrganization(rw http.ResponseWriter, r *http.Reque
|
||||
Description: createTemplate.Description,
|
||||
MaxTtl: int64(maxTTL),
|
||||
MinAutostartInterval: int64(minAutostartInterval),
|
||||
CreatedBy: uuid.NullUUID{
|
||||
UUID: apiKey.UserID,
|
||||
Valid: true,
|
||||
},
|
||||
})
|
||||
if err != nil {
|
||||
return xerrors.Errorf("insert template: %s", err)
|
||||
@ -208,7 +223,12 @@ func (api *API) postTemplateByOrganization(rw http.ResponseWriter, r *http.Reque
|
||||
}
|
||||
}
|
||||
|
||||
template = convertTemplate(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 {
|
||||
@ -258,7 +278,16 @@ func (api *API) templatesByOrganization(rw http.ResponseWriter, r *http.Request)
|
||||
return
|
||||
}
|
||||
|
||||
httpapi.Write(rw, http.StatusOK, convertTemplates(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) {
|
||||
@ -304,7 +333,16 @@ func (api *API) templateByOrganizationAndName(rw http.ResponseWriter, r *http.Re
|
||||
count = uint32(workspaceCounts[0].Count)
|
||||
}
|
||||
|
||||
httpapi.Write(rw, http.StatusOK, convertTemplate(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) {
|
||||
@ -400,10 +438,35 @@ func (api *API) patchTemplateMeta(rw http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
httpapi.Write(rw, http.StatusOK, convertTemplate(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 convertTemplates(templates []database.Template, workspaceCounts []database.GetWorkspaceOwnerCountsByTemplateIDsRow) []codersdk.Template {
|
||||
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(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
|
||||
@ -411,18 +474,18 @@ 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(template, uint32(workspaceCount.Count), createdByNameMap[template.ID.String()]))
|
||||
found = true
|
||||
break
|
||||
}
|
||||
if !found {
|
||||
apiTemplates = append(apiTemplates, convertTemplate(template, uint32(0)))
|
||||
apiTemplates = append(apiTemplates, convertTemplate(template, uint32(0), createdByNameMap[template.ID.String()]))
|
||||
}
|
||||
}
|
||||
return apiTemplates
|
||||
}
|
||||
|
||||
func convertTemplate(template database.Template, workspaceOwnerCount uint32) codersdk.Template {
|
||||
func convertTemplate(template database.Template, workspaceOwnerCount uint32, createdByName string) codersdk.Template {
|
||||
return codersdk.Template{
|
||||
ID: template.ID,
|
||||
CreatedAt: template.CreatedAt,
|
||||
@ -435,5 +498,7 @@ func convertTemplate(template database.Template, workspaceOwnerCount uint32) cod
|
||||
Description: template.Description,
|
||||
MaxTTLMillis: time.Duration(template.MaxTtl).Milliseconds(),
|
||||
MinAutostartIntervalMillis: time.Duration(template.MinAutostartInterval).Milliseconds(),
|
||||
CreatedByID: template.CreatedBy,
|
||||
CreatedByName: createdByName,
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user