Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit12b6c73

Browse files
committed
Merge branch 'main' into fixwsroutes
2 parentsf82a755 +60102cb commit12b6c73

File tree

15 files changed

+348
-127
lines changed

15 files changed

+348
-127
lines changed

‎.github/codecov.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ coverage:
1919
ignore:
2020
# This is generated code.
2121
-coderd/database/models.go
22-
-coderd/database/query.sql.go
22+
-coderd/database/queries.sql.go
2323
-coderd/database/databasefake
2424
# These are generated or don't require tests.
2525
-cmd

‎cli/delete.go

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -30,11 +30,7 @@ func delete() *cobra.Command {
3030
iferr!=nil {
3131
returnerr
3232
}
33-
organization,err:=currentOrganization(cmd,client)
34-
iferr!=nil {
35-
returnerr
36-
}
37-
workspace,err:=client.WorkspaceByOwnerAndName(cmd.Context(),organization.ID,codersdk.Me,args[0])
33+
workspace,err:=client.WorkspaceByOwnerAndName(cmd.Context(),codersdk.Me,args[0])
3834
iferr!=nil {
3935
returnerr
4036
}

‎coderd/database/databasefake/databasefake.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -328,6 +328,9 @@ func (q *fakeQuerier) GetWorkspacesWithFilter(_ context.Context, arg database.Ge
328328
if!arg.Deleted&&workspace.Deleted {
329329
continue
330330
}
331+
ifarg.Name!=""&&workspace.Name!=arg.Name {
332+
continue
333+
}
331334
workspaces=append(workspaces,workspace)
332335
}
333336

‎coderd/database/queries.sql.go

Lines changed: 13 additions & 1 deletion
Some generated files are not rendered by default. Learn more aboutcustomizing how changed files appear on GitHub.

‎coderd/database/queries/workspaces.sql

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,12 @@ WHERE
2828
owner_id= @owner_id
2929
ELSE true
3030
END
31+
-- Filter by name
32+
AND CASE
33+
WHEN @name ::text!='' THEN
34+
LOWER(name)=LOWER(@name)
35+
ELSE true
36+
END
3137
;
3238

3339
-- name: GetWorkspacesByOrganizationIDs :many

‎coderd/workspaces.go

Lines changed: 10 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -108,17 +108,14 @@ func (api *API) workspaces(rw http.ResponseWriter, r *http.Request) {
108108
// Empty strings mean no filter
109109
orgFilter:=r.URL.Query().Get("organization_id")
110110
ownerFilter:=r.URL.Query().Get("owner")
111+
nameFilter:=r.URL.Query().Get("name")
111112

112113
filter:= database.GetWorkspacesWithFilterParams{Deleted:false}
113114
iforgFilter!="" {
114115
orgID,err:=uuid.Parse(orgFilter)
115-
iferr!=nil {
116-
httpapi.Write(rw,http.StatusBadRequest, httpapi.Response{
117-
Message:fmt.Sprintf("organization_id must be a uuid: %s",err.Error()),
118-
})
119-
return
116+
iferr==nil {
117+
filter.OrganizationID=orgID
120118
}
121-
filter.OrganizationID=orgID
122119
}
123120
ifownerFilter=="me" {
124121
filter.OwnerID=apiKey.UserID
@@ -131,15 +128,15 @@ func (api *API) workspaces(rw http.ResponseWriter, r *http.Request) {
131128
Username:ownerFilter,
132129
Email:ownerFilter,
133130
})
134-
iferr!=nil {
135-
httpapi.Write(rw,http.StatusBadRequest, httpapi.Response{
136-
Message:"owner must be a uuid or username",
137-
})
138-
return
131+
iferr==nil {
132+
filter.OwnerID=user.ID
139133
}
140-
userID=user.ID
134+
}else {
135+
filter.OwnerID=userID
141136
}
142-
filter.OwnerID=userID
137+
}
138+
ifnameFilter!="" {
139+
filter.Name=nameFilter
143140
}
144141

145142
workspaces,err:=api.Database.GetWorkspacesWithFilter(r.Context(),filter)

‎codersdk/workspaces.go

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -198,9 +198,10 @@ func (c *Client) PutExtendWorkspace(ctx context.Context, id uuid.UUID, req PutEx
198198
}
199199

200200
typeWorkspaceFilterstruct {
201-
OrganizationID uuid.UUID
201+
OrganizationID uuid.UUID`json:"organization_id,omitempty"`
202202
// Owner can be a user_id (uuid), "me", or a username
203-
Ownerstring
203+
Ownerstring`json:"owner,omitempty"`
204+
Namestring`json:"name,omitempty"`
204205
}
205206

206207
// asRequestOption returns a function that can be used in (*Client).Request.
@@ -214,6 +215,9 @@ func (f WorkspaceFilter) asRequestOption() requestOption {
214215
iff.Owner!="" {
215216
q.Set("owner",f.Owner)
216217
}
218+
iff.Name!="" {
219+
q.Set("name",f.Name)
220+
}
217221
r.URL.RawQuery=q.Encode()
218222
}
219223
}

‎site/src/api/api.test.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -118,10 +118,10 @@ describe("api.ts", () => {
118118
it.each<[TypesGen.WorkspaceFilter|undefined,string]>([
119119
[undefined,"/api/v2/workspaces"],
120120

121-
[{OrganizationID:"1",Owner:""},"/api/v2/workspaces?organization_id=1"],
122-
[{OrganizationID:"",Owner:"1"},"/api/v2/workspaces?owner=1"],
121+
[{organization_id:"1",owner:""},"/api/v2/workspaces?organization_id=1"],
122+
[{organization_id:"",owner:"1"},"/api/v2/workspaces?owner=1"],
123123

124-
[{OrganizationID:"1",Owner:"me"},"/api/v2/workspaces?organization_id=1&owner=me"],
124+
[{organization_id:"1",owner:"me"},"/api/v2/workspaces?organization_id=1&owner=me"],
125125
])(`getWorkspacesURL(%p) returns %p`,(filter,expected)=>{
126126
expect(getWorkspacesURL(filter)).toBe(expected)
127127
})

‎site/src/api/api.ts

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -117,11 +117,14 @@ export const getWorkspacesURL = (filter?: TypesGen.WorkspaceFilter): string => {
117117
constbasePath="/api/v2/workspaces"
118118
constsearchParams=newURLSearchParams()
119119

120-
if(filter?.OrganizationID){
121-
searchParams.append("organization_id",filter.OrganizationID)
120+
if(filter?.organization_id){
121+
searchParams.append("organization_id",filter.organization_id)
122122
}
123-
if(filter?.Owner){
124-
searchParams.append("owner",filter.Owner)
123+
if(filter?.owner){
124+
searchParams.append("owner",filter.owner)
125+
}
126+
if(filter?.name){
127+
searchParams.append("name",filter.name)
125128
}
126129

127130
constsearchString=searchParams.toString()

‎site/src/api/typesGenerated.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -443,8 +443,9 @@ export interface WorkspaceBuildsRequest extends Pagination {
443443

444444
// From codersdk/workspaces.go:200:6
445445
exportinterfaceWorkspaceFilter{
446-
readonlyOrganizationID:string
447-
readonlyOwner:string
446+
readonlyorganization_id?:string
447+
readonlyowner?:string
448+
readonlyname?:string
448449
}
449450

450451
// From codersdk/workspaceresources.go:21:6
Lines changed: 158 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,169 @@
1+
importButtonfrom"@material-ui/core/Button"
2+
importFadefrom"@material-ui/core/Fade"
3+
importInputAdornmentfrom"@material-ui/core/InputAdornment"
4+
importLinkfrom"@material-ui/core/Link"
5+
importMenufrom"@material-ui/core/Menu"
6+
importMenuItemfrom"@material-ui/core/MenuItem"
7+
import{makeStyles}from"@material-ui/core/styles"
8+
importTextFieldfrom"@material-ui/core/TextField"
9+
importAddCircleOutlinefrom"@material-ui/icons/AddCircleOutline"
10+
importSearchIconfrom"@material-ui/icons/Search"
111
import{useMachine}from"@xstate/react"
2-
import{FC}from"react"
12+
import{FormikErrors,useFormik}from"formik"
13+
import{FC,useState}from"react"
14+
import{LinkasRouterLink}from"react-router-dom"
15+
import{CloseDropdown,OpenDropdown}from"../../components/DropdownArrows/DropdownArrows"
16+
import{Margins}from"../../components/Margins/Margins"
17+
import{Stack}from"../../components/Stack/Stack"
18+
import{getFormHelpers,onChangeTrimmed}from"../../util/formUtils"
319
import{workspacesMachine}from"../../xServices/workspaces/workspacesXService"
420
import{WorkspacesPageView}from"./WorkspacesPageView"
521

22+
interfaceFilterFormValues{
23+
query:string
24+
}
25+
26+
constLanguage={
27+
filterName:"Filters",
28+
createWorkspaceButton:"Create workspace",
29+
yourWorkspacesButton:"Your workspaces",
30+
allWorkspacesButton:"All workspaces",
31+
}
32+
33+
exporttypeFilterFormErrors=FormikErrors<FilterFormValues>
34+
635
constWorkspacesPage:FC=()=>{
7-
const[workspacesState]=useMachine(workspacesMachine)
36+
conststyles=useStyles()
37+
const[workspacesState,send]=useMachine(workspacesMachine)
38+
39+
constform=useFormik<FilterFormValues>({
40+
initialValues:{
41+
query:workspacesState.context.filter||"",
42+
},
43+
onSubmit:(values)=>{
44+
send({
45+
type:"SET_FILTER",
46+
query:values.query,
47+
})
48+
},
49+
})
50+
51+
constgetFieldHelpers=getFormHelpers<FilterFormValues>(form)
52+
53+
const[anchorEl,setAnchorEl]=useState<null|HTMLElement>(null)
54+
55+
consthandleClick=(event:React.MouseEvent<HTMLButtonElement>)=>{
56+
setAnchorEl(event.currentTarget)
57+
}
58+
59+
consthandleClose=()=>{
60+
setAnchorEl(null)
61+
}
62+
63+
constsetYourWorkspaces=()=>{
64+
voidform.setFieldValue("query","owner:me")
65+
voidform.submitForm()
66+
handleClose()
67+
}
68+
69+
constsetAllWorkspaces=()=>{
70+
voidform.setFieldValue("query","")
71+
voidform.submitForm()
72+
handleClose()
73+
}
874

975
return(
10-
<>
11-
<WorkspacesPageView
12-
loading={workspacesState.hasTag("loading")}
13-
workspaces={workspacesState.context.workspaces}
14-
error={workspacesState.context.getWorkspacesError}
15-
/>
16-
</>
76+
<Margins>
77+
<Stackdirection="row"className={styles.workspacesHeaderContainer}>
78+
<Stackdirection="column"className={styles.filterColumn}>
79+
<Stackdirection="row"spacing={0}className={styles.filterContainer}>
80+
<Button
81+
aria-controls="filter-menu"
82+
aria-haspopup="true"
83+
onClick={handleClick}
84+
className={styles.buttonRoot}
85+
>
86+
{Language.filterName}{anchorEl ?<CloseDropdown/> :<OpenDropdown/>}
87+
</Button>
88+
89+
<formonSubmit={form.handleSubmit}className={styles.filterForm}>
90+
<TextField
91+
{...getFieldHelpers("query")}
92+
className={styles.textFieldRoot}
93+
onChange={onChangeTrimmed(form)}
94+
fullWidth
95+
variant="outlined"
96+
InputProps={{
97+
startAdornment:(
98+
<InputAdornmentposition="start">
99+
<SearchIconfontSize="small"/>
100+
</InputAdornment>
101+
),
102+
}}
103+
/>
104+
</form>
105+
106+
<Menu
107+
id="filter-menu"
108+
anchorEl={anchorEl}
109+
keepMounted
110+
open={Boolean(anchorEl)}
111+
onClose={handleClose}
112+
TransitionComponent={Fade}
113+
anchorOrigin={{
114+
vertical:"bottom",
115+
horizontal:"left",
116+
}}
117+
transformOrigin={{
118+
vertical:"top",
119+
horizontal:"left",
120+
}}
121+
>
122+
<MenuItemonClick={setYourWorkspaces}>{Language.yourWorkspacesButton}</MenuItem>
123+
<MenuItemonClick={setAllWorkspaces}>{Language.allWorkspacesButton}</MenuItem>
124+
</Menu>
125+
</Stack>
126+
</Stack>
127+
128+
<Linkunderline="none"component={RouterLink}to="/workspaces/new">
129+
<ButtonstartIcon={<AddCircleOutline/>}style={{height:"44px"}}>
130+
{Language.createWorkspaceButton}
131+
</Button>
132+
</Link>
133+
</Stack>
134+
<WorkspacesPageViewloading={workspacesState.hasTag("loading")}workspaces={workspacesState.context.workspaces}/>
135+
</Margins>
17136
)
18137
}
19138

139+
constuseStyles=makeStyles((theme)=>({
140+
workspacesHeaderContainer:{
141+
marginTop:theme.spacing(3),
142+
marginBottom:theme.spacing(3),
143+
justifyContent:"space-between",
144+
},
145+
filterColumn:{
146+
width:"60%",
147+
cursor:"text",
148+
},
149+
filterContainer:{
150+
border:`1px solid${theme.palette.divider}`,
151+
borderRadius:"6px",
152+
},
153+
filterForm:{
154+
width:"100%",
155+
},
156+
buttonRoot:{
157+
border:"none",
158+
borderRight:`1px solid${theme.palette.divider}`,
159+
borderRadius:"6px 0px 0px 6px",
160+
},
161+
textFieldRoot:{
162+
margin:"0px",
163+
"& fieldset":{
164+
border:"none",
165+
},
166+
},
167+
}))
168+
20169
exportdefaultWorkspacesPage

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp