Skip to content

Commit 39c1435

Browse files
committed
add deleting_by query param
1 parent 55ece93 commit 39c1435

File tree

6 files changed

+98
-30
lines changed

6 files changed

+98
-30
lines changed

coderd/apidoc/docs.go

Lines changed: 6 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

coderd/apidoc/swagger.json

Lines changed: 6 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

coderd/searchquery/search.go

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import (
1212

1313
"github.com/coder/coder/coderd/database"
1414
"github.com/coder/coder/coderd/httpapi"
15+
"github.com/coder/coder/coderd/util/ptr"
1516
"github.com/coder/coder/codersdk"
1617
)
1718

@@ -66,16 +67,24 @@ func Users(query string) (database.GetUsersParams, []codersdk.ValidationError) {
6667
return filter, parser.Errors
6768
}
6869

69-
func Workspaces(query string, page codersdk.Pagination, agentInactiveDisconnectTimeout time.Duration) (database.GetWorkspacesParams, []codersdk.ValidationError) {
70+
type PostFilter struct {
71+
DeletingBy *time.Time `json:"deleting_by" format:"date-time"`
72+
}
73+
74+
func Workspaces(query string, page codersdk.Pagination, agentInactiveDisconnectTimeout time.Duration) (database.GetWorkspacesParams, PostFilter, []codersdk.ValidationError) {
7075
filter := database.GetWorkspacesParams{
7176
AgentInactiveDisconnectTimeoutSeconds: int64(agentInactiveDisconnectTimeout.Seconds()),
7277

7378
Offset: int32(page.Offset),
7479
Limit: int32(page.Limit),
7580
}
7681

82+
postFilter := PostFilter{
83+
DeletingBy: nil,
84+
}
85+
7786
if query == "" {
78-
return filter, nil
87+
return filter, postFilter, nil
7988
}
8089

8190
// Always lowercase for all searches.
@@ -95,7 +104,7 @@ func Workspaces(query string, page codersdk.Pagination, agentInactiveDisconnectT
95104
return nil
96105
})
97106
if len(errors) > 0 {
98-
return filter, errors
107+
return filter, postFilter, errors
99108
}
100109

101110
parser := httpapi.NewQueryParamParser()
@@ -104,8 +113,14 @@ func Workspaces(query string, page codersdk.Pagination, agentInactiveDisconnectT
104113
filter.Name = parser.String(values, "", "name")
105114
filter.Status = string(httpapi.ParseCustom(parser, values, "", "status", httpapi.ParseEnum[database.WorkspaceStatus]))
106115
filter.HasAgent = parser.String(values, "", "has-agent")
116+
117+
if _, ok := values["deleting_by"]; ok {
118+
db := parser.Time(values, time.Time{}, "deleting_by", "2006-01-02")
119+
postFilter.DeletingBy = ptr.Ref(db)
120+
}
121+
107122
parser.ErrorExcessParams(values)
108-
return filter, parser.Errors
123+
return filter, postFilter, parser.Errors
109124
}
110125

111126
func searchTerms(query string, defaultKey func(term string, values url.Values) error) (url.Values, []codersdk.ValidationError) {

coderd/workspaces.go

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,7 @@ func (api *API) workspace(rw http.ResponseWriter, r *http.Request) {
106106
// @Param name query string false "Filter with partial-match by workspace name"
107107
// @Param status query string false "Filter by workspace status" Enums(pending,running,stopping,stopped,failed,canceling,canceled,deleted,deleting)
108108
// @Param has_agent query string false "Filter by agent status" Enums(connected,connecting,disconnected,timeout)
109+
// @Param deleting_by query string false "Filter by DeletingAt time"
109110
// @Success 200 {object} codersdk.WorkspacesResponse
110111
// @Router /workspaces [get]
111112
func (api *API) workspaces(rw http.ResponseWriter, r *http.Request) {
@@ -118,7 +119,7 @@ func (api *API) workspaces(rw http.ResponseWriter, r *http.Request) {
118119
}
119120

120121
queryStr := r.URL.Query().Get("q")
121-
filter, errs := searchquery.Workspaces(queryStr, page, api.AgentInactiveDisconnectTimeout)
122+
filter, postFilter, errs := searchquery.Workspaces(queryStr, page, api.AgentInactiveDisconnectTimeout)
122123
if len(errs) > 0 {
123124
httpapi.Write(ctx, rw, http.StatusBadRequest, codersdk.Response{
124125
Message: "Invalid workspace search query.",
@@ -178,8 +179,25 @@ func (api *API) workspaces(rw http.ResponseWriter, r *http.Request) {
178179
return
179180
}
180181

182+
var filteredWorkspaces []codersdk.Workspace
183+
// apply post filters, if they exist
184+
if postFilter.DeletingBy == nil {
185+
filteredWorkspaces = append(filteredWorkspaces, wss...)
186+
} else {
187+
for _, v := range wss {
188+
if v.DeletingAt == nil {
189+
break
190+
}
191+
// get the beginning of the day on which deletion is scheduled
192+
truncatedDeletionAt := v.DeletingAt.Truncate(24 * time.Hour)
193+
if v.DeletingAt != nil && (truncatedDeletionAt.Before(*postFilter.DeletingBy) || truncatedDeletionAt.Equal(*postFilter.DeletingBy)) {
194+
filteredWorkspaces = append(filteredWorkspaces, v)
195+
}
196+
}
197+
}
198+
181199
httpapi.Write(ctx, rw, http.StatusOK, codersdk.WorkspacesResponse{
182-
Workspaces: wss,
200+
Workspaces: filteredWorkspaces,
183201
Count: int(workspaceRows[0].Count),
184202
})
185203
}

docs/api/workspaces.md

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -390,13 +390,14 @@ curl -X GET http://coder-server:8080/api/v2/workspaces \
390390

391391
### Parameters
392392

393-
| Name | In | Type | Required | Description |
394-
| ----------- | ----- | ------ | -------- | ------------------------------------------- |
395-
| `owner` | query | string | false | Filter by owner username |
396-
| `template` | query | string | false | Filter by template name |
397-
| `name` | query | string | false | Filter with partial-match by workspace name |
398-
| `status` | query | string | false | Filter by workspace status |
399-
| `has_agent` | query | string | false | Filter by agent status |
393+
| Name | In | Type | Required | Description |
394+
| ------------- | ----- | ------ | -------- | ------------------------------------------- |
395+
| `owner` | query | string | false | Filter by owner username |
396+
| `template` | query | string | false | Filter by template name |
397+
| `name` | query | string | false | Filter with partial-match by workspace name |
398+
| `status` | query | string | false | Filter by workspace status |
399+
| `has_agent` | query | string | false | Filter by agent status |
400+
| `deleting_by` | query | string | false | Filter by DeletingAt time |
400401

401402
#### Enumerated Values
402403

site/src/pages/TemplateSettingsPage/TemplateSchedulePage/TemplateScheduleForm.tsx

Lines changed: 39 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -149,24 +149,25 @@ export const TemplateScheduleForm: FC<TemplateScheduleForm> = ({
149149
if (form.values.inactivity_cleanup_enabled) {
150150
setIsInactivityDialogOpen(true)
151151
} else {
152+
actuallySubmit(formData)
152153
// on submit, convert from hours => ms
153-
onSubmit({
154-
default_ttl_ms: formData.default_ttl_ms
155-
? formData.default_ttl_ms * MS_HOUR_CONVERSION
156-
: undefined,
157-
max_ttl_ms: formData.max_ttl_ms
158-
? formData.max_ttl_ms * MS_HOUR_CONVERSION
159-
: undefined,
160-
failure_ttl_ms: formData.failure_ttl_ms
161-
? formData.failure_ttl_ms * MS_DAY_CONVERSION
162-
: undefined,
163-
inactivity_ttl_ms: formData.inactivity_ttl_ms
164-
? formData.inactivity_ttl_ms * MS_DAY_CONVERSION
165-
: undefined,
154+
// onSubmit({
155+
// default_ttl_ms: formData.default_ttl_ms
156+
// ? formData.default_ttl_ms * MS_HOUR_CONVERSION
157+
// : undefined,
158+
// max_ttl_ms: formData.max_ttl_ms
159+
// ? formData.max_ttl_ms * MS_HOUR_CONVERSION
160+
// : undefined,
161+
// failure_ttl_ms: formData.failure_ttl_ms
162+
// ? formData.failure_ttl_ms * MS_DAY_CONVERSION
163+
// : undefined,
164+
// inactivity_ttl_ms: formData.inactivity_ttl_ms
165+
// ? formData.inactivity_ttl_ms * MS_DAY_CONVERSION
166+
// : undefined,
166167

167-
allow_user_autostart: formData.allow_user_autostart,
168-
allow_user_autostop: formData.allow_user_autostop,
169-
})
168+
// allow_user_autostart: formData.allow_user_autostart,
169+
// allow_user_autostop: formData.allow_user_autostop,
170+
// })
170171
}
171172
},
172173
initialTouched,
@@ -218,6 +219,27 @@ export const TemplateScheduleForm: FC<TemplateScheduleForm> = ({
218219
}
219220
}
220221

222+
const actuallySubmit = (formData: any) => {
223+
// on submit, convert from hours => ms
224+
onSubmit({
225+
default_ttl_ms: formData.default_ttl_ms
226+
? formData.default_ttl_ms * MS_HOUR_CONVERSION
227+
: undefined,
228+
max_ttl_ms: formData.max_ttl_ms
229+
? formData.max_ttl_ms * MS_HOUR_CONVERSION
230+
: undefined,
231+
failure_ttl_ms: formData.failure_ttl_ms
232+
? formData.failure_ttl_ms * MS_DAY_CONVERSION
233+
: undefined,
234+
inactivity_ttl_ms: formData.inactivity_ttl_ms
235+
? formData.inactivity_ttl_ms * MS_DAY_CONVERSION
236+
: undefined,
237+
238+
allow_user_autostart: formData.allow_user_autostart,
239+
allow_user_autostop: formData.allow_user_autostop,
240+
})
241+
}
242+
221243
return (
222244
<HorizontalForm
223245
onSubmit={form.handleSubmit}
@@ -400,7 +422,7 @@ export const TemplateScheduleForm: FC<TemplateScheduleForm> = ({
400422
<ConfirmDialog
401423
type="delete"
402424
open={isInactivityDialogOpen}
403-
onConfirm={form.handleSubmit}
425+
onConfirm={() => actuallySubmit(form.values)}
404426
onClose={() => setIsInactivityDialogOpen(false)}
405427
title="Delete inactive workspaces"
406428
confirmText="Delete Workspaces"

0 commit comments

Comments
 (0)