mirror of
https://github.com/coder/coder.git
synced 2025-07-03 16:13:58 +00:00
feat(coderd): allow workspace owners to mark workspaces as favorite (#11791)
- Adds column `favorite` to workspaces table - Adds API endpoints to favorite/unfavorite workspaces - Modifies sorting order to return owners' favorite workspaces first
This commit is contained in:
@ -10849,6 +10849,15 @@ func (q *sqlQuerier) BatchUpdateWorkspaceLastUsedAt(ctx context.Context, arg Bat
|
||||
return err
|
||||
}
|
||||
|
||||
const favoriteWorkspace = `-- name: FavoriteWorkspace :exec
|
||||
UPDATE workspaces SET favorite = true WHERE id = $1
|
||||
`
|
||||
|
||||
func (q *sqlQuerier) FavoriteWorkspace(ctx context.Context, id uuid.UUID) error {
|
||||
_, err := q.db.ExecContext(ctx, favoriteWorkspace, id)
|
||||
return err
|
||||
}
|
||||
|
||||
const getDeploymentWorkspaceStats = `-- name: GetDeploymentWorkspaceStats :one
|
||||
WITH workspaces_with_jobs AS (
|
||||
SELECT
|
||||
@ -10935,7 +10944,7 @@ func (q *sqlQuerier) GetDeploymentWorkspaceStats(ctx context.Context) (GetDeploy
|
||||
|
||||
const getWorkspaceByAgentID = `-- name: GetWorkspaceByAgentID :one
|
||||
SELECT
|
||||
workspaces.id, workspaces.created_at, workspaces.updated_at, workspaces.owner_id, workspaces.organization_id, workspaces.template_id, workspaces.deleted, workspaces.name, workspaces.autostart_schedule, workspaces.ttl, workspaces.last_used_at, workspaces.dormant_at, workspaces.deleting_at, workspaces.automatic_updates,
|
||||
workspaces.id, workspaces.created_at, workspaces.updated_at, workspaces.owner_id, workspaces.organization_id, workspaces.template_id, workspaces.deleted, workspaces.name, workspaces.autostart_schedule, workspaces.ttl, workspaces.last_used_at, workspaces.dormant_at, workspaces.deleting_at, workspaces.automatic_updates, workspaces.favorite,
|
||||
templates.name as template_name
|
||||
FROM
|
||||
workspaces
|
||||
@ -10989,6 +10998,7 @@ func (q *sqlQuerier) GetWorkspaceByAgentID(ctx context.Context, agentID uuid.UUI
|
||||
&i.Workspace.DormantAt,
|
||||
&i.Workspace.DeletingAt,
|
||||
&i.Workspace.AutomaticUpdates,
|
||||
&i.Workspace.Favorite,
|
||||
&i.TemplateName,
|
||||
)
|
||||
return i, err
|
||||
@ -10996,7 +11006,7 @@ func (q *sqlQuerier) GetWorkspaceByAgentID(ctx context.Context, agentID uuid.UUI
|
||||
|
||||
const getWorkspaceByID = `-- name: GetWorkspaceByID :one
|
||||
SELECT
|
||||
id, created_at, updated_at, owner_id, organization_id, template_id, deleted, name, autostart_schedule, ttl, last_used_at, dormant_at, deleting_at, automatic_updates
|
||||
id, created_at, updated_at, owner_id, organization_id, template_id, deleted, name, autostart_schedule, ttl, last_used_at, dormant_at, deleting_at, automatic_updates, favorite
|
||||
FROM
|
||||
workspaces
|
||||
WHERE
|
||||
@ -11023,13 +11033,14 @@ func (q *sqlQuerier) GetWorkspaceByID(ctx context.Context, id uuid.UUID) (Worksp
|
||||
&i.DormantAt,
|
||||
&i.DeletingAt,
|
||||
&i.AutomaticUpdates,
|
||||
&i.Favorite,
|
||||
)
|
||||
return i, err
|
||||
}
|
||||
|
||||
const getWorkspaceByOwnerIDAndName = `-- name: GetWorkspaceByOwnerIDAndName :one
|
||||
SELECT
|
||||
id, created_at, updated_at, owner_id, organization_id, template_id, deleted, name, autostart_schedule, ttl, last_used_at, dormant_at, deleting_at, automatic_updates
|
||||
id, created_at, updated_at, owner_id, organization_id, template_id, deleted, name, autostart_schedule, ttl, last_used_at, dormant_at, deleting_at, automatic_updates, favorite
|
||||
FROM
|
||||
workspaces
|
||||
WHERE
|
||||
@ -11063,13 +11074,14 @@ func (q *sqlQuerier) GetWorkspaceByOwnerIDAndName(ctx context.Context, arg GetWo
|
||||
&i.DormantAt,
|
||||
&i.DeletingAt,
|
||||
&i.AutomaticUpdates,
|
||||
&i.Favorite,
|
||||
)
|
||||
return i, err
|
||||
}
|
||||
|
||||
const getWorkspaceByWorkspaceAppID = `-- name: GetWorkspaceByWorkspaceAppID :one
|
||||
SELECT
|
||||
id, created_at, updated_at, owner_id, organization_id, template_id, deleted, name, autostart_schedule, ttl, last_used_at, dormant_at, deleting_at, automatic_updates
|
||||
id, created_at, updated_at, owner_id, organization_id, template_id, deleted, name, autostart_schedule, ttl, last_used_at, dormant_at, deleting_at, automatic_updates, favorite
|
||||
FROM
|
||||
workspaces
|
||||
WHERE
|
||||
@ -11122,6 +11134,7 @@ func (q *sqlQuerier) GetWorkspaceByWorkspaceAppID(ctx context.Context, workspace
|
||||
&i.DormantAt,
|
||||
&i.DeletingAt,
|
||||
&i.AutomaticUpdates,
|
||||
&i.Favorite,
|
||||
)
|
||||
return i, err
|
||||
}
|
||||
@ -11166,7 +11179,7 @@ func (q *sqlQuerier) GetWorkspaceUniqueOwnerCountByTemplateIDs(ctx context.Conte
|
||||
|
||||
const getWorkspaces = `-- name: GetWorkspaces :many
|
||||
SELECT
|
||||
workspaces.id, workspaces.created_at, workspaces.updated_at, workspaces.owner_id, workspaces.organization_id, workspaces.template_id, workspaces.deleted, workspaces.name, workspaces.autostart_schedule, workspaces.ttl, workspaces.last_used_at, workspaces.dormant_at, workspaces.deleting_at, workspaces.automatic_updates,
|
||||
workspaces.id, workspaces.created_at, workspaces.updated_at, workspaces.owner_id, workspaces.organization_id, workspaces.template_id, workspaces.deleted, workspaces.name, workspaces.autostart_schedule, workspaces.ttl, workspaces.last_used_at, workspaces.dormant_at, workspaces.deleting_at, workspaces.automatic_updates, workspaces.favorite,
|
||||
COALESCE(template.name, 'unknown') as template_name,
|
||||
latest_build.template_version_id,
|
||||
latest_build.template_version_name,
|
||||
@ -11355,6 +11368,8 @@ WHERE
|
||||
-- Authorize Filter clause will be injected below in GetAuthorizedWorkspaces
|
||||
-- @authorize_filter
|
||||
ORDER BY
|
||||
-- To ensure that 'favorite' workspaces show up first in the list only for their owner.
|
||||
CASE WHEN workspaces.owner_id = $14 AND workspaces.favorite THEN 0 ELSE 1 END ASC,
|
||||
(latest_build.completed_at IS NOT NULL AND
|
||||
latest_build.canceled_at IS NULL AND
|
||||
latest_build.error IS NULL AND
|
||||
@ -11363,11 +11378,11 @@ ORDER BY
|
||||
LOWER(workspaces.name) ASC
|
||||
LIMIT
|
||||
CASE
|
||||
WHEN $15 :: integer > 0 THEN
|
||||
$15
|
||||
WHEN $16 :: integer > 0 THEN
|
||||
$16
|
||||
END
|
||||
OFFSET
|
||||
$14
|
||||
$15
|
||||
`
|
||||
|
||||
type GetWorkspacesParams struct {
|
||||
@ -11384,6 +11399,7 @@ type GetWorkspacesParams struct {
|
||||
LastUsedBefore time.Time `db:"last_used_before" json:"last_used_before"`
|
||||
LastUsedAfter time.Time `db:"last_used_after" json:"last_used_after"`
|
||||
UsingActive sql.NullBool `db:"using_active" json:"using_active"`
|
||||
RequesterID uuid.UUID `db:"requester_id" json:"requester_id"`
|
||||
Offset int32 `db:"offset_" json:"offset_"`
|
||||
Limit int32 `db:"limit_" json:"limit_"`
|
||||
}
|
||||
@ -11403,6 +11419,7 @@ type GetWorkspacesRow struct {
|
||||
DormantAt sql.NullTime `db:"dormant_at" json:"dormant_at"`
|
||||
DeletingAt sql.NullTime `db:"deleting_at" json:"deleting_at"`
|
||||
AutomaticUpdates AutomaticUpdates `db:"automatic_updates" json:"automatic_updates"`
|
||||
Favorite bool `db:"favorite" json:"favorite"`
|
||||
TemplateName string `db:"template_name" json:"template_name"`
|
||||
TemplateVersionID uuid.UUID `db:"template_version_id" json:"template_version_id"`
|
||||
TemplateVersionName sql.NullString `db:"template_version_name" json:"template_version_name"`
|
||||
@ -11424,6 +11441,7 @@ func (q *sqlQuerier) GetWorkspaces(ctx context.Context, arg GetWorkspacesParams)
|
||||
arg.LastUsedBefore,
|
||||
arg.LastUsedAfter,
|
||||
arg.UsingActive,
|
||||
arg.RequesterID,
|
||||
arg.Offset,
|
||||
arg.Limit,
|
||||
)
|
||||
@ -11449,6 +11467,7 @@ func (q *sqlQuerier) GetWorkspaces(ctx context.Context, arg GetWorkspacesParams)
|
||||
&i.DormantAt,
|
||||
&i.DeletingAt,
|
||||
&i.AutomaticUpdates,
|
||||
&i.Favorite,
|
||||
&i.TemplateName,
|
||||
&i.TemplateVersionID,
|
||||
&i.TemplateVersionName,
|
||||
@ -11469,7 +11488,7 @@ func (q *sqlQuerier) GetWorkspaces(ctx context.Context, arg GetWorkspacesParams)
|
||||
|
||||
const getWorkspacesEligibleForTransition = `-- name: GetWorkspacesEligibleForTransition :many
|
||||
SELECT
|
||||
workspaces.id, workspaces.created_at, workspaces.updated_at, workspaces.owner_id, workspaces.organization_id, workspaces.template_id, workspaces.deleted, workspaces.name, workspaces.autostart_schedule, workspaces.ttl, workspaces.last_used_at, workspaces.dormant_at, workspaces.deleting_at, workspaces.automatic_updates
|
||||
workspaces.id, workspaces.created_at, workspaces.updated_at, workspaces.owner_id, workspaces.organization_id, workspaces.template_id, workspaces.deleted, workspaces.name, workspaces.autostart_schedule, workspaces.ttl, workspaces.last_used_at, workspaces.dormant_at, workspaces.deleting_at, workspaces.automatic_updates, workspaces.favorite
|
||||
FROM
|
||||
workspaces
|
||||
LEFT JOIN
|
||||
@ -11557,6 +11576,7 @@ func (q *sqlQuerier) GetWorkspacesEligibleForTransition(ctx context.Context, now
|
||||
&i.DormantAt,
|
||||
&i.DeletingAt,
|
||||
&i.AutomaticUpdates,
|
||||
&i.Favorite,
|
||||
); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -11587,7 +11607,7 @@ INSERT INTO
|
||||
automatic_updates
|
||||
)
|
||||
VALUES
|
||||
($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11) RETURNING id, created_at, updated_at, owner_id, organization_id, template_id, deleted, name, autostart_schedule, ttl, last_used_at, dormant_at, deleting_at, automatic_updates
|
||||
($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11) RETURNING id, created_at, updated_at, owner_id, organization_id, template_id, deleted, name, autostart_schedule, ttl, last_used_at, dormant_at, deleting_at, automatic_updates, favorite
|
||||
`
|
||||
|
||||
type InsertWorkspaceParams struct {
|
||||
@ -11634,10 +11654,20 @@ func (q *sqlQuerier) InsertWorkspace(ctx context.Context, arg InsertWorkspacePar
|
||||
&i.DormantAt,
|
||||
&i.DeletingAt,
|
||||
&i.AutomaticUpdates,
|
||||
&i.Favorite,
|
||||
)
|
||||
return i, err
|
||||
}
|
||||
|
||||
const unfavoriteWorkspace = `-- name: UnfavoriteWorkspace :exec
|
||||
UPDATE workspaces SET favorite = false WHERE id = $1
|
||||
`
|
||||
|
||||
func (q *sqlQuerier) UnfavoriteWorkspace(ctx context.Context, id uuid.UUID) error {
|
||||
_, err := q.db.ExecContext(ctx, unfavoriteWorkspace, id)
|
||||
return err
|
||||
}
|
||||
|
||||
const updateTemplateWorkspacesLastUsedAt = `-- name: UpdateTemplateWorkspacesLastUsedAt :exec
|
||||
UPDATE workspaces
|
||||
SET
|
||||
@ -11664,7 +11694,7 @@ SET
|
||||
WHERE
|
||||
id = $1
|
||||
AND deleted = false
|
||||
RETURNING id, created_at, updated_at, owner_id, organization_id, template_id, deleted, name, autostart_schedule, ttl, last_used_at, dormant_at, deleting_at, automatic_updates
|
||||
RETURNING id, created_at, updated_at, owner_id, organization_id, template_id, deleted, name, autostart_schedule, ttl, last_used_at, dormant_at, deleting_at, automatic_updates, favorite
|
||||
`
|
||||
|
||||
type UpdateWorkspaceParams struct {
|
||||
@ -11690,6 +11720,7 @@ func (q *sqlQuerier) UpdateWorkspace(ctx context.Context, arg UpdateWorkspacePar
|
||||
&i.DormantAt,
|
||||
&i.DeletingAt,
|
||||
&i.AutomaticUpdates,
|
||||
&i.Favorite,
|
||||
)
|
||||
return i, err
|
||||
}
|
||||
@ -11776,7 +11807,7 @@ WHERE
|
||||
workspaces.id = $1
|
||||
AND templates.id = workspaces.template_id
|
||||
RETURNING
|
||||
workspaces.id, workspaces.created_at, workspaces.updated_at, workspaces.owner_id, workspaces.organization_id, workspaces.template_id, workspaces.deleted, workspaces.name, workspaces.autostart_schedule, workspaces.ttl, workspaces.last_used_at, workspaces.dormant_at, workspaces.deleting_at, workspaces.automatic_updates
|
||||
workspaces.id, workspaces.created_at, workspaces.updated_at, workspaces.owner_id, workspaces.organization_id, workspaces.template_id, workspaces.deleted, workspaces.name, workspaces.autostart_schedule, workspaces.ttl, workspaces.last_used_at, workspaces.dormant_at, workspaces.deleting_at, workspaces.automatic_updates, workspaces.favorite
|
||||
`
|
||||
|
||||
type UpdateWorkspaceDormantDeletingAtParams struct {
|
||||
@ -11802,6 +11833,7 @@ func (q *sqlQuerier) UpdateWorkspaceDormantDeletingAt(ctx context.Context, arg U
|
||||
&i.DormantAt,
|
||||
&i.DeletingAt,
|
||||
&i.AutomaticUpdates,
|
||||
&i.Favorite,
|
||||
)
|
||||
return i, err
|
||||
}
|
||||
|
Reference in New Issue
Block a user