mirror of
https://github.com/coder/coder.git
synced 2025-07-03 16:13:58 +00:00
feat: filter for running workspaces (#4157)
* Refactor workspaces xservice * Remove layout comment * Format * Add comments * Add running workspaces filter to frontend * Start on backend - add status to filter * Update sql and add test - wip * Attempt to unconvert status for easier querying * Fix syntax * Join jobs table, untested * sql * Add Status to GetAuthorizedWorkspaces * Update job tests to have canceled time * fmt * add status filter to database fake Co-authored-by: Colin Adler <colin1adler@gmail.com>
This commit is contained in:
@ -5431,48 +5431,133 @@ func (q *sqlQuerier) GetWorkspaceOwnerCountsByTemplateIDs(ctx context.Context, i
|
||||
|
||||
const getWorkspaces = `-- name: GetWorkspaces :many
|
||||
SELECT
|
||||
id, created_at, updated_at, owner_id, organization_id, template_id, deleted, name, autostart_schedule, ttl, last_used_at
|
||||
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
|
||||
FROM
|
||||
workspaces
|
||||
workspaces
|
||||
LEFT JOIN LATERAL (
|
||||
SELECT
|
||||
workspace_builds.transition,
|
||||
provisioner_jobs.started_at,
|
||||
provisioner_jobs.updated_at,
|
||||
provisioner_jobs.canceled_at,
|
||||
provisioner_jobs.completed_at,
|
||||
provisioner_jobs.error
|
||||
FROM
|
||||
workspace_builds
|
||||
LEFT JOIN
|
||||
provisioner_jobs
|
||||
ON
|
||||
provisioner_jobs.id = workspace_builds.job_id
|
||||
WHERE
|
||||
workspace_builds.workspace_id = workspaces.id
|
||||
ORDER BY
|
||||
build_number DESC
|
||||
LIMIT
|
||||
1
|
||||
) latest_build ON TRUE
|
||||
WHERE
|
||||
-- Optionally include deleted workspaces
|
||||
-- Optionally include deleted workspaces
|
||||
workspaces.deleted = $1
|
||||
-- Filter by owner_id
|
||||
AND CASE
|
||||
WHEN $2 :: uuid != '00000000-00000000-00000000-00000000' THEN
|
||||
owner_id = $2
|
||||
WHEN $2 :: text != '' THEN
|
||||
CASE
|
||||
WHEN $2 = 'pending' THEN
|
||||
latest_build.started_at IS NULL
|
||||
WHEN $2 = 'starting' THEN
|
||||
latest_build.started_at IS NOT NULL AND
|
||||
latest_build.canceled_at IS NULL AND
|
||||
latest_build.completed_at IS NULL AND
|
||||
latest_build.updated_at - INTERVAL '30 seconds' < NOW() AND
|
||||
latest_build.transition = 'start'::workspace_transition
|
||||
|
||||
WHEN $2 = 'running' THEN
|
||||
latest_build.completed_at IS NOT NULL AND
|
||||
latest_build.canceled_at IS NULL AND
|
||||
latest_build.error IS NULL AND
|
||||
latest_build.transition = 'start'::workspace_transition
|
||||
|
||||
WHEN $2 = 'stopping' THEN
|
||||
latest_build.started_at IS NOT NULL AND
|
||||
latest_build.canceled_at IS NULL AND
|
||||
latest_build.completed_at IS NULL AND
|
||||
latest_build.updated_at - INTERVAL '30 seconds' < NOW() AND
|
||||
latest_build.transition = 'stop'::workspace_transition
|
||||
|
||||
WHEN $2 = 'stopped' THEN
|
||||
latest_build.completed_at IS NOT NULL AND
|
||||
latest_build.canceled_at IS NULL AND
|
||||
latest_build.error IS NULL AND
|
||||
latest_build.transition = 'stop'::workspace_transition
|
||||
|
||||
WHEN $2 = 'failed' THEN
|
||||
(latest_build.canceled_at IS NOT NULL AND
|
||||
latest_build.error IS NOT NULL) OR
|
||||
(latest_build.completed_at IS NOT NULL AND
|
||||
latest_build.error IS NOT NULL)
|
||||
|
||||
WHEN $2 = 'canceling' THEN
|
||||
latest_build.canceled_at IS NOT NULL AND
|
||||
latest_build.completed_at IS NULL
|
||||
|
||||
WHEN $2 = 'canceled' THEN
|
||||
latest_build.canceled_at IS NOT NULL AND
|
||||
latest_build.completed_at IS NOT NULL
|
||||
|
||||
WHEN $2 = 'deleted' THEN
|
||||
latest_build.started_at IS NOT NULL AND
|
||||
latest_build.canceled_at IS NULL AND
|
||||
latest_build.completed_at IS NOT NULL AND
|
||||
latest_build.updated_at - INTERVAL '30 seconds' < NOW() AND
|
||||
latest_build.transition = 'delete'::workspace_transition
|
||||
|
||||
WHEN $2 = 'deleting' THEN
|
||||
latest_build.completed_at IS NOT NULL AND
|
||||
latest_build.canceled_at IS NULL AND
|
||||
latest_build.error IS NULL AND
|
||||
latest_build.transition = 'delete'::workspace_transition
|
||||
|
||||
ELSE
|
||||
true
|
||||
END
|
||||
ELSE true
|
||||
END
|
||||
-- Filter by owner_name
|
||||
-- Filter by owner_id
|
||||
AND CASE
|
||||
WHEN $3 :: text != '' THEN
|
||||
owner_id = (SELECT id FROM users WHERE lower(username) = lower($3))
|
||||
WHEN $3 :: uuid != '00000000-00000000-00000000-00000000' THEN
|
||||
owner_id = $3
|
||||
ELSE true
|
||||
END
|
||||
-- Filter by owner_name
|
||||
AND CASE
|
||||
WHEN $4 :: text != '' THEN
|
||||
owner_id = (SELECT id FROM users WHERE lower(username) = lower($4))
|
||||
ELSE true
|
||||
END
|
||||
-- Filter by template_name
|
||||
-- There can be more than 1 template with the same name across organizations.
|
||||
-- Use the organization filter to restrict to 1 org if needed.
|
||||
-- Use the organization filter to restrict to 1 org if needed.
|
||||
AND CASE
|
||||
WHEN $4 :: text != '' THEN
|
||||
template_id = ANY(SELECT id FROM templates WHERE lower(name) = lower($4))
|
||||
WHEN $5 :: text != '' THEN
|
||||
template_id = ANY(SELECT id FROM templates WHERE lower(name) = lower($5))
|
||||
ELSE true
|
||||
END
|
||||
-- Filter by template_ids
|
||||
AND CASE
|
||||
WHEN array_length($5 :: uuid[], 1) > 0 THEN
|
||||
template_id = ANY($5)
|
||||
WHEN array_length($6 :: uuid[], 1) > 0 THEN
|
||||
template_id = ANY($6)
|
||||
ELSE true
|
||||
END
|
||||
-- Filter by name, matching on substring
|
||||
AND CASE
|
||||
WHEN $6 :: text != '' THEN
|
||||
name ILIKE '%' || $6 || '%'
|
||||
WHEN $7 :: text != '' THEN
|
||||
name ILIKE '%' || $7 || '%'
|
||||
ELSE true
|
||||
END
|
||||
`
|
||||
|
||||
type GetWorkspacesParams struct {
|
||||
Deleted bool `db:"deleted" json:"deleted"`
|
||||
Status string `db:"status" json:"status"`
|
||||
OwnerID uuid.UUID `db:"owner_id" json:"owner_id"`
|
||||
OwnerUsername string `db:"owner_username" json:"owner_username"`
|
||||
TemplateName string `db:"template_name" json:"template_name"`
|
||||
@ -5483,6 +5568,7 @@ type GetWorkspacesParams struct {
|
||||
func (q *sqlQuerier) GetWorkspaces(ctx context.Context, arg GetWorkspacesParams) ([]Workspace, error) {
|
||||
rows, err := q.db.QueryContext(ctx, getWorkspaces,
|
||||
arg.Deleted,
|
||||
arg.Status,
|
||||
arg.OwnerID,
|
||||
arg.OwnerUsername,
|
||||
arg.TemplateName,
|
||||
|
Reference in New Issue
Block a user