Skip to content

Commit ccde77c

Browse files
author
Guillaume Chau
committedJun 17, 2018
feat(ui): folder explorer: create new folders
1 parent 6c4ebb0 commit ccde77c

File tree

6 files changed

+103
-3
lines changed

6 files changed

+103
-3
lines changed
 

‎packages/@vue/cli-ui/locales/en.json

+10
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,16 @@
4646
"placeholder": "Enter the full path to a folder",
4747
"empty": "No favorite folders yet.",
4848
"show-hidden": "Show hidden folders"
49+
},
50+
"new-folder": {
51+
"action": "New folder",
52+
"title": "Create new folder",
53+
"field": {
54+
"title": "New folder",
55+
"subtitle": "You can use the folder separator to create multiple nested folders at once."
56+
},
57+
"cancel": "Cancel",
58+
"create": "Create"
4959
}
5060
},
5161
"list-item-info": {

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

+70-1
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,12 @@
116116
class="icon-button"
117117
/>
118118

119+
<VueDropdownButton
120+
:label="$t('components.folder-explorer.new-folder.action')"
121+
icon-left="create_new_folder"
122+
@click="showNewFolder = true"
123+
/>
124+
119125
<VueSwitch
120126
icon="visibility"
121127
v-model="showHidden"
@@ -141,16 +147,55 @@
141147
/>
142148
</template>
143149
</div>
150+
151+
<VueModal
152+
v-if="showNewFolder"
153+
:title="$t('components.folder-explorer.new-folder.title')"
154+
class="small new-folder-modal"
155+
@close="showNewFolder = false"
156+
>
157+
<div class="default-body">
158+
<VueFormField
159+
:title="$t('components.folder-explorer.new-folder.field.title')"
160+
:subtitle="$t('components.folder-explorer.new-folder.field.subtitle')"
161+
>
162+
<VueInput
163+
v-model="newFolderName"
164+
icon-left="folder"
165+
@keyup.enter="createFolder()"
166+
/>
167+
</VueFormField>
168+
</div>
169+
170+
<div slot="footer" class="actions space-between">
171+
<VueButton
172+
:label="$t('components.folder-explorer.new-folder.cancel')"
173+
class="flat close"
174+
@click="showNewFolder = false"
175+
/>
176+
177+
<VueButton
178+
:label="$t('components.folder-explorer.new-folder.create')"
179+
icon-left="create_new_folder"
180+
class="primary save"
181+
:disabled="!newFolderValid"
182+
@click="createFolder()"
183+
/>
184+
</div>
185+
</VueModal>
144186
</div>
145187
</template>
146188

147189
<script>
190+
import { isValidMultiName } from '../util/folders'
191+
148192
import FOLDER_CURRENT from '../graphql/folderCurrent.gql'
149193
import FOLDERS_FAVORITE from '../graphql/foldersFavorite.gql'
150194
import FOLDER_OPEN from '../graphql/folderOpen.gql'
151195
import FOLDER_OPEN_PARENT from '../graphql/folderOpenParent.gql'
152196
import FOLDER_SET_FAVORITE from '../graphql/folderSetFavorite.gql'
153197
import PROJECT_CWD_RESET from '../graphql/projectCwdReset.gql'
198+
import FOLDER_CREATE from '../graphql/folderCreate.gql'
154199
155200
const SHOW_HIDDEN = 'vue-ui.show-hidden-folders'
156201
@@ -163,7 +208,9 @@ export default {
163208
editedPath: '',
164209
folderCurrent: {},
165210
foldersFavorite: [],
166-
showHidden: localStorage.getItem(SHOW_HIDDEN) === 'true'
211+
showHidden: localStorage.getItem(SHOW_HIDDEN) === 'true',
212+
showNewFolder: false,
213+
newFolderName: ''
167214
}
168215
},
169216
@@ -181,6 +228,12 @@ export default {
181228
foldersFavorite: FOLDERS_FAVORITE
182229
},
183230
231+
computed: {
232+
newFolderValid () {
233+
return isValidMultiName(this.newFolderName)
234+
}
235+
},
236+
184237
watch: {
185238
showHidden (value) {
186239
if (value) {
@@ -311,6 +364,22 @@ export default {
311364
if (startIndex < path.length) addPart(path.length)
312365
313366
return parts
367+
},
368+
369+
async createFolder () {
370+
if (!this.newFolderValid) return
371+
372+
const result = await this.$apollo.mutate({
373+
mutation: FOLDER_CREATE,
374+
variables: {
375+
name: this.newFolderName
376+
}
377+
})
378+
379+
this.openFolder(result.data.folderCreate.path)
380+
381+
this.newFolderName = ''
382+
this.showNewFolder = false
314383
}
315384
}
316385
}

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

+8-1
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,12 @@ async function deleteFolder (file) {
135135
await fs.remove(file)
136136
}
137137

138+
function createFolder (name, context) {
139+
const file = path.join(cwd.get(), name)
140+
fs.mkdirpSync(file)
141+
return generateFolder(file, context)
142+
}
143+
138144
module.exports = {
139145
isDirectory,
140146
getCurrent,
@@ -148,5 +154,6 @@ module.exports = {
148154
isFavorite,
149155
listFavorite,
150156
setFavorite,
151-
delete: deleteFolder
157+
delete: deleteFolder,
158+
create: createFolder
152159
}

‎packages/@vue/cli-ui/src/graphql-api/schema/folder.js

+3-1
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ extend type Mutation {
1414
folderOpen (path: String!): Folder
1515
folderOpenParent: Folder
1616
folderSetFavorite (path: String!, favorite: Boolean!): Folder
17+
folderCreate(name: String!): Folder
1718
}
1819
1920
type Folder {
@@ -47,6 +48,7 @@ exports.resolvers = {
4748
folderSetFavorite: (root, args, context) => folders.setFavorite({
4849
file: args.path,
4950
favorite: args.favorite
50-
}, context)
51+
}, context),
52+
folderCreate: (root, { name }, context) => folders.create(name, context)
5153
}
5254
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
#import "./folderCurrentFragment.gql"
2+
3+
mutation folderCreate ($name: String!) {
4+
folderCreate (name: $name) {
5+
...folderCurrent
6+
}
7+
}
+5
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
11
export function isValidName (name) {
22
return !name.match(/[/@\s+%:]/) && encodeURIComponent(name) === name
33
}
4+
5+
export function isValidMultiName (name) {
6+
name = name.replace(/\\/g, '/')
7+
return name.split('/').every(isValidName)
8+
}

0 commit comments

Comments
 (0)
Please sign in to comment.