mirror of
https://github.com/coder/coder.git
synced 2025-07-15 22:20:27 +00:00
feat(workspaces): change sorting order of the workspace list (#7594)
* feat(workspaces): implement sorting order on workspace list * split slice into its own function and test it * use require instead of assert * Update coderd/workspaces_internal_test.go Co-authored-by: Cian Johnston <cian@coder.com> * refactor tests into table tests * fix test --------- Co-authored-by: Cian Johnston <cian@coder.com>
This commit is contained in:
@ -1147,16 +1147,34 @@ func convertWorkspaces(workspaces []database.Workspace, data workspaceData) ([]c
|
||||
&owner,
|
||||
))
|
||||
}
|
||||
sort.Slice(apiWorkspaces, func(i, j int) bool {
|
||||
iw := apiWorkspaces[i]
|
||||
jw := apiWorkspaces[j]
|
||||
|
||||
sortWorkspaces(apiWorkspaces)
|
||||
|
||||
return apiWorkspaces, nil
|
||||
}
|
||||
|
||||
func sortWorkspaces(workspaces []codersdk.Workspace) {
|
||||
sort.Slice(workspaces, func(i, j int) bool {
|
||||
iw := workspaces[i]
|
||||
jw := workspaces[j]
|
||||
|
||||
if iw.LatestBuild.Status == codersdk.WorkspaceStatusRunning && jw.LatestBuild.Status != codersdk.WorkspaceStatusRunning {
|
||||
return true
|
||||
}
|
||||
|
||||
if jw.LatestBuild.Status == codersdk.WorkspaceStatusRunning && iw.LatestBuild.Status != codersdk.WorkspaceStatusRunning {
|
||||
return false
|
||||
}
|
||||
|
||||
if iw.OwnerID != jw.OwnerID {
|
||||
return iw.OwnerName < jw.OwnerName
|
||||
}
|
||||
|
||||
if jw.LastUsedAt.IsZero() && iw.LastUsedAt.IsZero() {
|
||||
return iw.Name < jw.Name
|
||||
}
|
||||
return iw.LastUsedAt.After(jw.LastUsedAt)
|
||||
})
|
||||
|
||||
return apiWorkspaces, nil
|
||||
}
|
||||
|
||||
func convertWorkspace(
|
||||
|
@ -4,6 +4,7 @@ import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/google/uuid"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/coder/coder/coderd/database"
|
||||
@ -80,3 +81,96 @@ func Test_calculateDeletingAt(t *testing.T) {
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestSortWorkspaces(t *testing.T) {
|
||||
// the correct sorting order is:
|
||||
// 1. first show workspaces that are currently running,
|
||||
// 2. then sort by user_name,
|
||||
// 3. then sort by last_used_at (descending),
|
||||
t.Parallel()
|
||||
|
||||
workspaceFactory := func(t *testing.T, name string, ownerID uuid.UUID, ownerName string, status codersdk.WorkspaceStatus, lastUsedAt time.Time) codersdk.Workspace {
|
||||
t.Helper()
|
||||
return codersdk.Workspace{
|
||||
ID: uuid.New(),
|
||||
OwnerID: ownerID,
|
||||
OwnerName: ownerName,
|
||||
LatestBuild: codersdk.WorkspaceBuild{
|
||||
Status: status,
|
||||
},
|
||||
Name: name,
|
||||
LastUsedAt: lastUsedAt,
|
||||
}
|
||||
}
|
||||
|
||||
userAuuid := uuid.New()
|
||||
|
||||
workspaceRunningUserA := workspaceFactory(t, "running-userA", userAuuid, "userA", codersdk.WorkspaceStatusRunning, time.Now())
|
||||
workspaceRunningUserB := workspaceFactory(t, "running-userB", uuid.New(), "userB", codersdk.WorkspaceStatusRunning, time.Now())
|
||||
workspacePendingUserC := workspaceFactory(t, "pending-userC", uuid.New(), "userC", codersdk.WorkspaceStatusPending, time.Now())
|
||||
workspaceRunningUserA2 := workspaceFactory(t, "running-userA2", userAuuid, "userA", codersdk.WorkspaceStatusRunning, time.Now().Add(time.Minute))
|
||||
workspaceRunningUserZ := workspaceFactory(t, "running-userZ", uuid.New(), "userZ", codersdk.WorkspaceStatusRunning, time.Now())
|
||||
workspaceRunningUserA3 := workspaceFactory(t, "running-userA3", userAuuid, "userA", codersdk.WorkspaceStatusRunning, time.Now().Add(time.Hour))
|
||||
|
||||
testCases := []struct {
|
||||
name string
|
||||
input []codersdk.Workspace
|
||||
expectedOrder []string
|
||||
}{
|
||||
{
|
||||
name: "Running workspaces should be first",
|
||||
input: []codersdk.Workspace{
|
||||
workspaceRunningUserB,
|
||||
workspacePendingUserC,
|
||||
workspaceRunningUserA,
|
||||
},
|
||||
expectedOrder: []string{
|
||||
"running-userA",
|
||||
"running-userB",
|
||||
"pending-userC",
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "then sort by owner name",
|
||||
input: []codersdk.Workspace{
|
||||
workspaceRunningUserZ,
|
||||
workspaceRunningUserA,
|
||||
workspaceRunningUserB,
|
||||
},
|
||||
expectedOrder: []string{
|
||||
"running-userA",
|
||||
"running-userB",
|
||||
"running-userZ",
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "then sort by last used at (recent first)",
|
||||
input: []codersdk.Workspace{
|
||||
workspaceRunningUserA,
|
||||
workspaceRunningUserA2,
|
||||
workspaceRunningUserA3,
|
||||
},
|
||||
expectedOrder: []string{
|
||||
"running-userA3",
|
||||
"running-userA2",
|
||||
"running-userA",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
tc := tc
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
workspaces := tc.input
|
||||
sortWorkspaces(workspaces)
|
||||
|
||||
var resultNames []string
|
||||
for _, workspace := range workspaces {
|
||||
resultNames = append(resultNames, workspace.Name)
|
||||
}
|
||||
|
||||
require.Equal(t, tc.expectedOrder, resultNames, tc.name)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user