Skip to content

Commit 46e0953

Browse files
refactor: Show template versions as timeline (coder#4800)
1 parent cc65567 commit 46e0953

21 files changed

+218
-218
lines changed

cli/templateversions.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ func displayTemplateVersions(activeVersionID uuid.UUID, templateVersions ...code
9494
rows[i] = templateVersionRow{
9595
Name: templateVersion.Name,
9696
CreatedAt: templateVersion.CreatedAt,
97-
CreatedBy: templateVersion.CreatedByName,
97+
CreatedBy: templateVersion.CreatedBy.Username,
9898
Status: strings.Title(string(templateVersion.Job.Status)),
9999
Active: activeStatus,
100100
}

cli/templateversions_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ func TestTemplateVersions(t *testing.T) {
3535
require.NoError(t, <-errC)
3636

3737
pty.ExpectMatch(version.Name)
38-
pty.ExpectMatch(version.CreatedByName)
38+
pty.ExpectMatch(version.CreatedBy.Username)
3939
pty.ExpectMatch("Active")
4040
})
4141
}

coderd/database/dump.sql

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
ALTER TABLE template_versions ALTER COLUMN created_by DROP NOT NULL;
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
BEGIN;
2+
ALTER TABLE template_versions ALTER COLUMN created_by SET NOT NULL;
3+
UPDATE template_versions SET created_by = '00000000-0000-0000-0000-000000000000'::uuid WHERE created_by IS NULL;
4+
COMMIT;

coderd/database/models.go

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

coderd/database/queries.sql.go

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

coderd/templates.go

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -658,10 +658,7 @@ func (api *API) autoImportTemplate(ctx context.Context, opts autoImportTemplateO
658658
Name: namesgenerator.GetRandomName(1),
659659
Readme: "",
660660
JobID: job.ID,
661-
CreatedBy: uuid.NullUUID{
662-
UUID: opts.userID,
663-
Valid: true,
664-
},
661+
CreatedBy: opts.userID,
665662
})
666663
if err != nil {
667664
return xerrors.Errorf("insert template version: %w", err)

coderd/templateversions.go

Lines changed: 23 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
package coderd
22

33
import (
4-
"context"
54
"database/sql"
65
"encoding/json"
76
"errors"
@@ -43,16 +42,16 @@ func (api *API) templateVersion(rw http.ResponseWriter, r *http.Request) {
4342
return
4443
}
4544

46-
createdByName, err := getUsernameByUserID(ctx, api.Database, templateVersion.CreatedBy)
45+
user, err := api.Database.GetUserByID(ctx, templateVersion.CreatedBy)
4746
if err != nil {
4847
httpapi.Write(ctx, rw, http.StatusInternalServerError, codersdk.Response{
49-
Message: "Internal error fetching creator name.",
48+
Message: "Internal error on fetching user.",
5049
Detail: err.Error(),
5150
})
5251
return
5352
}
5453

55-
httpapi.Write(ctx, rw, http.StatusOK, convertTemplateVersion(templateVersion, convertProvisionerJob(job), createdByName))
54+
httpapi.Write(ctx, rw, http.StatusOK, convertTemplateVersion(templateVersion, convertProvisionerJob(job), user))
5655
}
5756

5857
func (api *API) patchCancelTemplateVersion(rw http.ResponseWriter, r *http.Request) {
@@ -523,15 +522,15 @@ func (api *API) templateVersionsByTemplate(rw http.ResponseWriter, r *http.Reque
523522
})
524523
return err
525524
}
526-
createdByName, err := getUsernameByUserID(ctx, store, version.CreatedBy)
525+
user, err := store.GetUserByID(ctx, version.CreatedBy)
527526
if err != nil {
528527
httpapi.Write(ctx, rw, http.StatusInternalServerError, codersdk.Response{
529-
Message: "Internal error fetching creator name.",
528+
Message: "Internal error on fetching user.",
530529
Detail: err.Error(),
531530
})
532531
return err
533532
}
534-
apiVersions = append(apiVersions, convertTemplateVersion(version, convertProvisionerJob(job), createdByName))
533+
apiVersions = append(apiVersions, convertTemplateVersion(version, convertProvisionerJob(job), user))
535534
}
536535

537536
return nil
@@ -581,16 +580,16 @@ func (api *API) templateVersionByName(rw http.ResponseWriter, r *http.Request) {
581580
return
582581
}
583582

584-
createdByName, err := getUsernameByUserID(ctx, api.Database, templateVersion.CreatedBy)
583+
user, err := api.Database.GetUserByID(ctx, templateVersion.CreatedBy)
585584
if err != nil {
586585
httpapi.Write(ctx, rw, http.StatusInternalServerError, codersdk.Response{
587-
Message: "Internal error fetching creator name.",
586+
Message: "Internal error on fetching user.",
588587
Detail: err.Error(),
589588
})
590589
return
591590
}
592591

593-
httpapi.Write(ctx, rw, http.StatusOK, convertTemplateVersion(templateVersion, convertProvisionerJob(job), createdByName))
592+
httpapi.Write(ctx, rw, http.StatusOK, convertTemplateVersion(templateVersion, convertProvisionerJob(job), user))
594593
}
595594

596595
func (api *API) patchActiveTemplateVersion(rw http.ResponseWriter, r *http.Request) {
@@ -841,10 +840,7 @@ func (api *API) postTemplateVersionsByOrganization(rw http.ResponseWriter, r *ht
841840
Name: req.Name,
842841
Readme: "",
843842
JobID: provisionerJob.ID,
844-
CreatedBy: uuid.NullUUID{
845-
UUID: apiKey.UserID,
846-
Valid: true,
847-
},
843+
CreatedBy: apiKey.UserID,
848844
})
849845
if err != nil {
850846
return xerrors.Errorf("insert template version: %w", err)
@@ -859,16 +855,16 @@ func (api *API) postTemplateVersionsByOrganization(rw http.ResponseWriter, r *ht
859855
}
860856
aReq.New = templateVersion
861857

862-
createdByName, err := getUsernameByUserID(ctx, api.Database, templateVersion.CreatedBy)
858+
user, err := api.Database.GetUserByID(ctx, templateVersion.CreatedBy)
863859
if err != nil {
864860
httpapi.Write(ctx, rw, http.StatusInternalServerError, codersdk.Response{
865-
Message: "Internal error fetching creator name.",
861+
Message: "Internal error on fetching user.",
866862
Detail: err.Error(),
867863
})
868864
return
869865
}
870866

871-
httpapi.Write(ctx, rw, http.StatusCreated, convertTemplateVersion(templateVersion, convertProvisionerJob(provisionerJob), createdByName))
867+
httpapi.Write(ctx, rw, http.StatusCreated, convertTemplateVersion(templateVersion, convertProvisionerJob(provisionerJob), user))
872868
}
873869

874870
// templateVersionResources returns the workspace agent resources associated
@@ -926,18 +922,17 @@ func (api *API) templateVersionLogs(rw http.ResponseWriter, r *http.Request) {
926922
api.provisionerJobLogs(rw, r, job)
927923
}
928924

929-
func getUsernameByUserID(ctx context.Context, db database.Store, userID uuid.NullUUID) (string, error) {
930-
if !userID.Valid {
931-
return "", nil
932-
}
933-
user, err := db.GetUserByID(ctx, userID.UUID)
934-
if err != nil {
935-
return "", err
925+
func convertTemplateVersion(version database.TemplateVersion, job codersdk.ProvisionerJob, user database.User) codersdk.TemplateVersion {
926+
createdBy := codersdk.User{
927+
ID: user.ID,
928+
Username: user.Username,
929+
Email: user.Email,
930+
CreatedAt: user.CreatedAt,
931+
Status: codersdk.UserStatus(user.Status),
932+
Roles: []codersdk.Role{},
933+
AvatarURL: user.AvatarURL.String,
936934
}
937-
return user.Username, nil
938-
}
939935

940-
func convertTemplateVersion(version database.TemplateVersion, job codersdk.ProvisionerJob, createdByName string) codersdk.TemplateVersion {
941936
return codersdk.TemplateVersion{
942937
ID: version.ID,
943938
TemplateID: &version.TemplateID.UUID,
@@ -947,7 +942,6 @@ func convertTemplateVersion(version database.TemplateVersion, job codersdk.Provi
947942
Name: version.Name,
948943
Job: job,
949944
Readme: version.Readme,
950-
CreatedByID: version.CreatedBy.UUID,
951-
CreatedByName: createdByName,
945+
CreatedBy: createdBy,
952946
}
953947
}

codersdk/templateversions.go

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,7 @@ type TemplateVersion struct {
2121
Name string `json:"name"`
2222
Job ProvisionerJob `json:"job"`
2323
Readme string `json:"readme"`
24-
CreatedByID uuid.UUID `json:"created_by_id"`
25-
CreatedByName string `json:"created_by_name"`
24+
CreatedBy User `json:"created_by"`
2625
}
2726

2827
// TemplateVersion returns a template version by ID.

enterprise/audit/diff_internal_test.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -277,7 +277,7 @@ func Test_diff(t *testing.T) {
277277
UpdatedAt: time.Now(),
278278
OrganizationID: uuid.UUID{3},
279279
Name: "rust",
280-
CreatedBy: uuid.NullUUID{UUID: uuid.UUID{4}, Valid: true},
280+
CreatedBy: uuid.UUID{4},
281281
},
282282
exp: audit.Map{
283283
"id": audit.OldNew{Old: "", New: uuid.UUID{1}.String()},
@@ -296,11 +296,11 @@ func Test_diff(t *testing.T) {
296296
UpdatedAt: time.Now(),
297297
OrganizationID: uuid.UUID{3},
298298
Name: "rust",
299-
CreatedBy: uuid.NullUUID{UUID: uuid.UUID{4}, Valid: true},
299+
CreatedBy: uuid.UUID{4},
300300
},
301301
exp: audit.Map{
302302
"id": audit.OldNew{Old: "", New: uuid.UUID{1}.String()},
303-
"created_by": audit.OldNew{Old: "null", New: uuid.UUID{4}.String()},
303+
"created_by": audit.OldNew{Old: "", New: uuid.UUID{4}.String()},
304304
"name": audit.OldNew{Old: "", New: "rust"},
305305
},
306306
},

site/src/api/typesGenerated.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -656,8 +656,7 @@ export interface TemplateVersion {
656656
readonly name: string
657657
readonly job: ProvisionerJob
658658
readonly readme: string
659-
readonly created_by_id: string
660-
readonly created_by_name: string
659+
readonly created_by: User
661660
}
662661

663662
// From codersdk/templates.go

site/src/components/BuildsTable/BuildDateRow.tsx

Lines changed: 0 additions & 46 deletions
This file was deleted.

site/src/components/BuildsTable/BuildsTable.tsx

Lines changed: 11 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -4,73 +4,37 @@ import TableBody from "@material-ui/core/TableBody"
44
import TableCell from "@material-ui/core/TableCell"
55
import TableContainer from "@material-ui/core/TableContainer"
66
import TableRow from "@material-ui/core/TableRow"
7-
import { FC, Fragment } from "react"
7+
import { Timeline } from "components/Timeline/Timeline"
8+
import { FC } from "react"
89
import * as TypesGen from "../../api/typesGenerated"
910
import { EmptyState } from "../EmptyState/EmptyState"
1011
import { TableLoader } from "../TableLoader/TableLoader"
11-
import { BuildDateRow } from "./BuildDateRow"
1212
import { BuildRow } from "./BuildRow"
1313

1414
export const Language = {
1515
emptyMessage: "No builds found",
16-
inProgressLabel: "In progress",
17-
actionLabel: "Action",
18-
durationLabel: "Duration",
19-
startedAtLabel: "Started at",
20-
statusLabel: "Status",
2116
}
2217

2318
export interface BuildsTableProps {
2419
builds?: TypesGen.WorkspaceBuild[]
2520
}
2621

27-
const groupBuildsByDate = (builds?: TypesGen.WorkspaceBuild[]) => {
28-
const buildsByDate: Record<string, TypesGen.WorkspaceBuild[]> = {}
29-
30-
if (!builds) {
31-
return
32-
}
33-
34-
builds.forEach((build) => {
35-
const dateKey = new Date(build.created_at).toDateString()
36-
37-
// Unsure why this is here but we probably need to fix it.
38-
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition -- see above
39-
if (buildsByDate[dateKey]) {
40-
buildsByDate[dateKey].push(build)
41-
} else {
42-
buildsByDate[dateKey] = [build]
43-
}
44-
})
45-
46-
return buildsByDate
47-
}
48-
4922
export const BuildsTable: FC<React.PropsWithChildren<BuildsTableProps>> = ({
5023
builds,
5124
}) => {
52-
const isLoading = !builds
53-
const buildsByDate = groupBuildsByDate(builds)
54-
5525
return (
5626
<TableContainer>
5727
<Table data-testid="builds-table" aria-describedby="builds table">
5828
<TableBody>
59-
{isLoading && <TableLoader />}
60-
61-
{buildsByDate &&
62-
Object.keys(buildsByDate).map((dateStr) => {
63-
const builds = buildsByDate[dateStr]
64-
65-
return (
66-
<Fragment key={dateStr}>
67-
<BuildDateRow date={new Date(dateStr)} />
68-
{builds.map((build) => (
69-
<BuildRow key={build.id} build={build} />
70-
))}
71-
</Fragment>
72-
)
73-
})}
29+
{builds ? (
30+
<Timeline
31+
items={builds}
32+
getDate={(build) => new Date(build.created_at)}
33+
row={(build) => <BuildRow key={build.id} build={build} />}
34+
/>
35+
) : (
36+
<TableLoader />
37+
)}
7438

7539
{builds && builds.length === 0 && (
7640
<TableRow>

0 commit comments

Comments
 (0)