Skip to content

Commit 08514eb

Browse files
author
Guillaume Chau
committed
feat(ui): FolderExplorer path edit + folder isPackage/isVueProject
1 parent 3333c94 commit 08514eb

File tree

9 files changed

+162
-42
lines changed

9 files changed

+162
-42
lines changed

packages/@vue/cli-ui/src/components/FolderExplorer.vue

+106-20
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,36 @@
11
<template>
2-
<div class="folder-explorer">
2+
<div
3+
class="folder-explorer"
4+
:class="{
5+
error
6+
}"
7+
>
38
<div class="toolbar">
49
<VueButton
510
class="icon-button"
611
icon-left="keyboard_arrow_up"
12+
v-tooltip="'Open parent folder'"
713
@click="openParentFolder"
814
/>
915

16+
<div v-if="editingPath" class="path-edit">
17+
<VueInput
18+
ref="pathInput"
19+
v-model="editedPath"
20+
placeholder="Enter the full path to a folder"
21+
icon-left="edit"
22+
@keyup.esc="editingPath = false"
23+
@keyup.enter="submitPathEdit()"
24+
/>
25+
</div>
26+
1027
<ApolloQuery
28+
v-else
29+
ref="cwd"
1130
:query="require('@/graphql/cwd.gql')"
1231
class="current-path"
32+
v-tooltip="'Edit path'"
33+
@click.native="openPathEdit()"
1334
>
1435
<ApolloSubscribeToMore
1536
:document="require('@/graphql/cwdChanged.gql')"
@@ -20,6 +41,19 @@
2041
<span v-if="data">{{ data.cwd }}</span>
2142
</template>
2243
</ApolloQuery>
44+
45+
<VueIcon
46+
v-if="error"
47+
icon="error"
48+
class="error-icon big"
49+
/>
50+
51+
<VueButton
52+
class="icon-button"
53+
icon-left="refresh"
54+
v-tooltip="'Refresh'"
55+
@click="refreshFolder"
56+
/>
2357
</div>
2458

2559
<ApolloQuery
@@ -32,7 +66,7 @@
3266
v-for="folder of data.folderCurrent.children"
3367
:key="folder.name"
3468
:folder="folder"
35-
@click.native="openFolder(folder)"
69+
@click.native="openFolder(folder.path)"
3670
/>
3771
</template>
3872
</template>
@@ -51,32 +85,67 @@ export default {
5185
FolderExplorerItem,
5286
},
5387
88+
data () {
89+
return {
90+
error: false,
91+
editingPath: false,
92+
editedPath: '',
93+
}
94+
},
95+
5496
methods: {
55-
openFolder (folder) {
56-
this.$apollo.mutate({
57-
mutation: FOLDER_OPEN,
58-
variables: {
59-
path: folder.path
60-
},
61-
update: (store, { data: { folderOpen } }) => {
62-
store.writeQuery({ query: FOLDER_CURRENT, data: { folderCurrent: folderOpen } })
63-
}
64-
})
97+
async openFolder (path) {
98+
this.editingPath = false
99+
this.error = false
100+
try {
101+
await this.$apollo.mutate({
102+
mutation: FOLDER_OPEN,
103+
variables: {
104+
path
105+
},
106+
update: (store, { data: { folderOpen } }) => {
107+
store.writeQuery({ query: FOLDER_CURRENT, data: { folderCurrent: folderOpen } })
108+
}
109+
})
110+
} catch (e) {
111+
this.error = true
112+
}
65113
},
66114
67-
openParentFolder (folder) {
68-
this.$apollo.mutate({
69-
mutation: FOLDER_OPEN_PARENT,
70-
update: (store, { data: { folderOpenParent } }) => {
71-
store.writeQuery({ query: FOLDER_CURRENT, data: { folderCurrent: folderOpenParent } })
72-
}
73-
})
115+
async openParentFolder (folder) {
116+
this.editingPath = false
117+
this.error = false
118+
try {
119+
await this.$apollo.mutate({
120+
mutation: FOLDER_OPEN_PARENT,
121+
update: (store, { data: { folderOpenParent } }) => {
122+
store.writeQuery({ query: FOLDER_CURRENT, data: { folderCurrent: folderOpenParent } })
123+
}
124+
})
125+
} catch (e) {
126+
this.error = true
127+
}
74128
},
75129
76130
cwdChangedUpdate (previousResult, { subscriptionData }) {
77131
return {
78132
cwd: subscriptionData.data.cwd
79133
}
134+
},
135+
136+
async openPathEdit () {
137+
this.editedPath = this.$refs.cwd.result.data.cwd
138+
this.editingPath = true
139+
await this.$nextTick()
140+
this.$refs.pathInput.focus()
141+
},
142+
143+
submitPathEdit () {
144+
this.openFolder(this.editedPath)
145+
},
146+
147+
refreshFolder () {
148+
this.openFolder(this.$refs.cwd.result.data.cwd)
80149
}
81150
}
82151
}
@@ -91,8 +160,25 @@ export default {
91160
h-box()
92161
align-items center
93162
163+
>>> > *
164+
space-between-x(12px)
165+
94166
.current-path
95167
flex 100% 1 1
96168
ellipsis()
97-
margin-left 12px
169+
cursor pointer
170+
171+
.path-edit
172+
flex 100% 1 1
173+
> .vue-input
174+
width 100%
175+
176+
.error-icon
177+
>>> svg
178+
fill $vue-color-danger
179+
180+
.folder-explorer
181+
&.error
182+
.current-path
183+
color $vue-color-danger
98184
</style>

packages/@vue/cli-ui/src/components/FolderExplorerItem.vue

+17-2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,14 @@
11
<template>
22
<div class="foder-explorer-item">
3-
<VueIcon icon="folder" class="folder-icon big"/>
4-
<div class="folder-name">{{ folder.name }}</div>
3+
<VueIcon :icon="folder.isPackage ? 'folder' : 'folder_open'" class="folder-icon big"/>
4+
<div class="folder-name">
5+
{{ folder.name }}
6+
<img
7+
v-if="folder.isVueProject"
8+
class="vue-project-icon"
9+
src="~@/assets/logo.png"
10+
>
11+
</div>
512
</div>
613
</template>
714

@@ -29,12 +36,20 @@ export default {
2936
margin-left 12px
3037
ellipsis()
3138
39+
.vue-project-icon
40+
width 14px
41+
height @width
42+
vertical-align top
43+
position relative
44+
top 5px
45+
3246
.foder-explorer-item
3347
padding 12px
3448
h-box()
3549
align-items center
3650
user-select none
3751
cursor pointer
52+
position relative
3853
3954
&:hover
4055
background rgba($vue-color-primary, .1)

packages/@vue/cli-ui/src/graphql-api/connectors/folders.js

+14-1
Original file line numberDiff line numberDiff line change
@@ -45,9 +45,22 @@ function openParent (file, context) {
4545
return generateFolder(newFile)
4646
}
4747

48+
function isPackage (file, context) {
49+
return fs.existsSync(path.join(file, 'package.json'))
50+
}
51+
52+
function isVueProject (file, context) {
53+
if (!isPackage(file)) return false
54+
55+
const contents = fs.readFileSync(path.join(file, 'package.json'), { encoding: 'utf8' })
56+
return contents.includes('@vue/cli-service')
57+
}
58+
4859
module.exports = {
4960
getCurrent,
5061
list,
5162
open,
52-
openParent
63+
openParent,
64+
isPackage,
65+
isVueProject
5366
}

packages/@vue/cli-ui/src/graphql-api/resolvers.js

+3-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,9 @@ const projects = require('./connectors/projects')
55

66
module.exports = {
77
Folder: {
8-
children: (folder, args, context) => folders.list(folder.path, context)
8+
children: (folder, args, context) => folders.list(folder.path, context),
9+
isPackage: (folder, args, context) => folders.isPackage(folder.path, context),
10+
isVueProject: (folder, args, context) => folders.isVueProject(folder.path, context)
911
},
1012

1113
Query: {

packages/@vue/cli-ui/src/graphql-api/type-defs.js

+3
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@ enum ConsoleLogType {
1919
type Folder {
2020
name: String!
2121
path: String!
22+
isPackage: Boolean
23+
isVueProject: Boolean
2224
children: [Folder]
2325
}
2426
@@ -122,6 +124,7 @@ type Mutation {
122124
folderOpenParent: Folder
123125
projectCreate (input: ProjectCreateInput!): Project!
124126
projectImport (input: ProjectImportInput!): Project!
127+
projectOpen (id: ID!): Project!
125128
projectSetFavorite (id: ID!, favorite: Int!): Project!
126129
pluginAdd (id: ID!): Plugin
127130
promptAnswer (input: PromptInput!): Prompt
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,7 @@
1+
#import "./folderCurrentFragment.gql"
2+
13
{
24
folderCurrent {
3-
name
4-
path
5-
children {
6-
name
7-
path
8-
}
5+
...folderCurrent
96
}
107
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
fragment folderCurrent on Folder {
2+
name
3+
path
4+
children {
5+
name
6+
path
7+
isPackage
8+
isVueProject
9+
}
10+
}
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,7 @@
1+
#import "./folderCurrentFragment.gql"
2+
13
mutation ($path: String!) {
24
folderOpen(path: $path) {
3-
name
4-
path
5-
children {
6-
name
7-
path
8-
}
5+
...folderCurrent
96
}
107
}
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,7 @@
1+
#import "./folderCurrentFragment.gql"
2+
13
mutation {
24
folderOpenParent {
3-
name
4-
path
5-
children {
6-
name
7-
path
8-
}
5+
...folderCurrent
96
}
107
}

0 commit comments

Comments
 (0)