From 5a80c247a59402c4bd3d0e08b7484d98039919d0 Mon Sep 17 00:00:00 2001 From: Guillaume Chau Date: Sat, 17 Mar 2018 14:14:32 +0100 Subject: [PATCH] feat(ui): tasks list --- .../cli-ui/src/components/ContentView.vue | 2 +- .../cli-ui/src/components/FolderExplorer.vue | 2 +- .../src/components/InstantSearchInput.vue | 2 +- .../@vue/cli-ui/src/components/LoggerView.vue | 10 +++- .../@vue/cli-ui/src/components/NavContent.vue | 44 ++++++++++++++ .../@vue/cli-ui/src/components/NavList.vue | 55 +++++++++++++++++ .../cli-ui/src/components/ProgressScreen.vue | 1 - .../src/components/ProjectPluginItem.vue | 2 +- .../@vue/cli-ui/src/components/StatusBar.vue | 1 - .../@vue/cli-ui/src/components/TaskItem.vue | 58 ++++++++++++++++++ .../src/graphql-api/connectors/tasks.js | 32 ++++++++++ .../@vue/cli-ui/src/graphql-api/resolvers.js | 5 +- .../@vue/cli-ui/src/graphql-api/type-defs.js | 17 ++++++ packages/@vue/cli-ui/src/graphql/task.gql | 7 +++ .../@vue/cli-ui/src/graphql/taskFragment.gql | 7 +++ packages/@vue/cli-ui/src/graphql/tasks.gql | 7 +++ packages/@vue/cli-ui/src/locales/en.json | 13 +++- packages/@vue/cli-ui/src/router.js | 11 +++- packages/@vue/cli-ui/src/style/main.styl | 3 + packages/@vue/cli-ui/src/util/route.js | 60 +++++++++++++++++++ .../@vue/cli-ui/src/views/ProjectCreate.vue | 12 ++-- .../@vue/cli-ui/src/views/ProjectHome.vue | 2 +- .../cli-ui/src/views/ProjectPluginsAdd.vue | 13 ++-- .../cli-ui/src/views/ProjectTaskDetails.vue | 18 ++++++ .../@vue/cli-ui/src/views/ProjectTasks.vue | 45 +++++++++++++- 25 files changed, 403 insertions(+), 26 deletions(-) create mode 100644 packages/@vue/cli-ui/src/components/NavContent.vue create mode 100644 packages/@vue/cli-ui/src/components/NavList.vue create mode 100644 packages/@vue/cli-ui/src/components/TaskItem.vue create mode 100644 packages/@vue/cli-ui/src/graphql-api/connectors/tasks.js create mode 100644 packages/@vue/cli-ui/src/graphql/task.gql create mode 100644 packages/@vue/cli-ui/src/graphql/taskFragment.gql create mode 100644 packages/@vue/cli-ui/src/graphql/tasks.gql create mode 100644 packages/@vue/cli-ui/src/util/route.js create mode 100644 packages/@vue/cli-ui/src/views/ProjectTaskDetails.vue diff --git a/packages/@vue/cli-ui/src/components/ContentView.vue b/packages/@vue/cli-ui/src/components/ContentView.vue index 92fc3355f0..4956d56723 100644 --- a/packages/@vue/cli-ui/src/components/ContentView.vue +++ b/packages/@vue/cli-ui/src/components/ContentView.vue @@ -20,7 +20,7 @@ export default { props: { title: { type: String, - default: false + default: null } } } diff --git a/packages/@vue/cli-ui/src/components/FolderExplorer.vue b/packages/@vue/cli-ui/src/components/FolderExplorer.vue index 4ae66727f5..bbe075e4c0 100644 --- a/packages/@vue/cli-ui/src/components/FolderExplorer.vue +++ b/packages/@vue/cli-ui/src/components/FolderExplorer.vue @@ -115,7 +115,7 @@ export default { editingPath: false, editedPath: '', folderCurrent: {}, - foldersFavorite: [], + foldersFavorite: [] } }, diff --git a/packages/@vue/cli-ui/src/components/InstantSearchInput.vue b/packages/@vue/cli-ui/src/components/InstantSearchInput.vue index f944aaa20c..c571373bab 100644 --- a/packages/@vue/cli-ui/src/components/InstantSearchInput.vue +++ b/packages/@vue/cli-ui/src/components/InstantSearchInput.vue @@ -35,7 +35,7 @@ export default { computed: { query: { - get() { + get () { return this.searchStore.query }, set (value) { diff --git a/packages/@vue/cli-ui/src/components/LoggerView.vue b/packages/@vue/cli-ui/src/components/LoggerView.vue index a45a2cdc4b..e6b30a0821 100644 --- a/packages/@vue/cli-ui/src/components/LoggerView.vue +++ b/packages/@vue/cli-ui/src/components/LoggerView.vue @@ -91,8 +91,14 @@ export default { await this.$apollo.mutate({ mutation: CONSOLE_LOGS_CLEAR, update: store => { - store.writeQuery({ query: CONSOLE_LOGS, data: { consoleLogs: [] }}) - store.writeQuery({ query: CONSOLE_LOG_LAST, data: { consoleLogLast: null }}) + store.writeQuery({ + query: CONSOLE_LOGS, + data: { consoleLogs: [] } + }) + store.writeQuery({ + query: CONSOLE_LOG_LAST, + data: { consoleLogLast: null } + }) } }) this.close() diff --git a/packages/@vue/cli-ui/src/components/NavContent.vue b/packages/@vue/cli-ui/src/components/NavContent.vue new file mode 100644 index 0000000000..24200f7a52 --- /dev/null +++ b/packages/@vue/cli-ui/src/components/NavContent.vue @@ -0,0 +1,44 @@ + + + + + diff --git a/packages/@vue/cli-ui/src/components/NavList.vue b/packages/@vue/cli-ui/src/components/NavList.vue new file mode 100644 index 0000000000..855809374a --- /dev/null +++ b/packages/@vue/cli-ui/src/components/NavList.vue @@ -0,0 +1,55 @@ + + + + + diff --git a/packages/@vue/cli-ui/src/components/ProgressScreen.vue b/packages/@vue/cli-ui/src/components/ProgressScreen.vue index 768afd4c3d..62edc6285d 100644 --- a/packages/@vue/cli-ui/src/components/ProgressScreen.vue +++ b/packages/@vue/cli-ui/src/components/ProgressScreen.vue @@ -105,7 +105,6 @@ export default { max-width 400px margin-top 24px - &:not(.loading) .vue-ui-loading-indicator >>> .animation diff --git a/packages/@vue/cli-ui/src/components/ProjectPluginItem.vue b/packages/@vue/cli-ui/src/components/ProjectPluginItem.vue index 88432a7d6c..7d9c9c1784 100644 --- a/packages/@vue/cli-ui/src/components/ProjectPluginItem.vue +++ b/packages/@vue/cli-ui/src/components/ProjectPluginItem.vue @@ -76,7 +76,7 @@ export default { data () { return { pluginDetails: null, - pluginLogo:! null, + pluginLogo: null, updating: false } }, diff --git a/packages/@vue/cli-ui/src/components/StatusBar.vue b/packages/@vue/cli-ui/src/components/StatusBar.vue index 19ad2dc562..488f9ca9ae 100644 --- a/packages/@vue/cli-ui/src/components/StatusBar.vue +++ b/packages/@vue/cli-ui/src/components/StatusBar.vue @@ -126,7 +126,6 @@ export default { } - diff --git a/packages/@vue/cli-ui/src/graphql-api/connectors/tasks.js b/packages/@vue/cli-ui/src/graphql-api/connectors/tasks.js new file mode 100644 index 0000000000..b7f9e9c712 --- /dev/null +++ b/packages/@vue/cli-ui/src/graphql-api/connectors/tasks.js @@ -0,0 +1,32 @@ +const cwd = require('./cwd') +const folders = require('./folders') + +let tasks = [] + +function list (context) { + const file = cwd.get() + const pkg = folders.readPackage(file, context) + tasks = [] + if (pkg.scripts) { + tasks = Object.keys(pkg.scripts).map( + name => ({ + id: `${file}${name}`, + name, + command: pkg.scripts[name], + status: 'idle' + }) + ) + } + return tasks +} + +function findOne (id, context) { + return tasks.find( + t => t.id === id + ) +} + +module.exports = { + list, + findOne +} diff --git a/packages/@vue/cli-ui/src/graphql-api/resolvers.js b/packages/@vue/cli-ui/src/graphql-api/resolvers.js index 2b3a032e50..6f11c32e0e 100644 --- a/packages/@vue/cli-ui/src/graphql-api/resolvers.js +++ b/packages/@vue/cli-ui/src/graphql-api/resolvers.js @@ -10,6 +10,7 @@ const projects = require('./connectors/projects') const progress = require('./connectors/progress') const logs = require('./connectors/logs') const plugins = require('./connectors/plugins') +const tasks = require('./connectors/tasks') // Prevent code from exiting server process exit.exitProcess = false @@ -44,7 +45,9 @@ module.exports = { projectCurrent: (root, args, context) => projects.getCurrent(context), projectCreation: (root, args, context) => projects.getCreation(context), pluginInstallation: (root, args, context) => plugins.getInstallation(context), - plugin: (root, { id }, context) => plugins.findOne(id, context) + plugin: (root, { id }, context) => plugins.findOne(id, context), + tasks: (root, args, context) => tasks.list(context), + task: (root, { id }, context) => tasks.findOne(id, context) }, Mutation: { diff --git a/packages/@vue/cli-ui/src/graphql-api/type-defs.js b/packages/@vue/cli-ui/src/graphql-api/type-defs.js index ea62d4121a..5eb55bacb9 100644 --- a/packages/@vue/cli-ui/src/graphql-api/type-defs.js +++ b/packages/@vue/cli-ui/src/graphql-api/type-defs.js @@ -154,6 +154,21 @@ type Progress { args: [String] } +type Task { + id: ID! + status: TaskStatus! + name: String! + command: String! + description: String +} + +enum TaskStatus { + idle + running + done + error +} + type Query { progress (id: ID!): Progress cwd: String! @@ -166,6 +181,8 @@ type Query { projectCreation: ProjectCreation pluginInstallation: PluginInstallation plugin (id: ID!): Plugin + tasks: [Task] + task (id: ID!): Task } type Mutation { diff --git a/packages/@vue/cli-ui/src/graphql/task.gql b/packages/@vue/cli-ui/src/graphql/task.gql new file mode 100644 index 0000000000..4a30295b40 --- /dev/null +++ b/packages/@vue/cli-ui/src/graphql/task.gql @@ -0,0 +1,7 @@ +#import "./taskFragment.gql" + +query task ($id: ID!) { + task (id: $id) { + ...task + } +} diff --git a/packages/@vue/cli-ui/src/graphql/taskFragment.gql b/packages/@vue/cli-ui/src/graphql/taskFragment.gql new file mode 100644 index 0000000000..43bb3416bd --- /dev/null +++ b/packages/@vue/cli-ui/src/graphql/taskFragment.gql @@ -0,0 +1,7 @@ +fragment task on Task { + id + status + name + command + description +} diff --git a/packages/@vue/cli-ui/src/graphql/tasks.gql b/packages/@vue/cli-ui/src/graphql/tasks.gql new file mode 100644 index 0000000000..a503157836 --- /dev/null +++ b/packages/@vue/cli-ui/src/graphql/tasks.gql @@ -0,0 +1,7 @@ +#import "./taskFragment.gql" + +query tasks { + tasks { + ...task + } +} diff --git a/packages/@vue/cli-ui/src/locales/en.json b/packages/@vue/cli-ui/src/locales/en.json index c25ba47639..10df3c1982 100644 --- a/packages/@vue/cli-ui/src/locales/en.json +++ b/packages/@vue/cli-ui/src/locales/en.json @@ -90,6 +90,16 @@ "plugin-update": "Updating {arg0}..." } }, + "types": { + "task": { + "status": { + "idle": "Idle", + "running": "Running", + "done": "Done", + "error": "Error" + } + } + }, "views": { "project-select": { "title": "Vue Project Manager", @@ -223,7 +233,8 @@ "title": "Project configuration" }, "project-tasks": { - "title": "Project tasks" + "title": "Project tasks", + "heading": "Scripts" } } } diff --git a/packages/@vue/cli-ui/src/router.js b/packages/@vue/cli-ui/src/router.js index 3993f8c56a..a2c5411916 100644 --- a/packages/@vue/cli-ui/src/router.js +++ b/packages/@vue/cli-ui/src/router.js @@ -7,6 +7,7 @@ import ProjectPlugins from './views/ProjectPlugins.vue' import ProjectPluginsAdd from './views/ProjectPluginsAdd.vue' import ProjectConfiguration from './views/ProjectConfiguration.vue' import ProjectTasks from './views/ProjectTasks.vue' +import ProjectTaskDetails from './views/ProjectTaskDetails.vue' import ProjectSelect from './views/ProjectSelect.vue' import ProjectCreate from './views/ProjectCreate.vue' import About from './views/About.vue' @@ -48,7 +49,15 @@ const router = new Router({ { path: 'tasks', name: 'project-tasks', - component: ProjectTasks + component: ProjectTasks, + children: [ + { + path: ':id', + name: 'project-task-details', + component: ProjectTaskDetails, + props: true + } + ] } ] }, diff --git a/packages/@vue/cli-ui/src/style/main.styl b/packages/@vue/cli-ui/src/style/main.styl index 2c393537e7..ad7dd78062 100644 --- a/packages/@vue/cli-ui/src/style/main.styl +++ b/packages/@vue/cli-ui/src/style/main.styl @@ -98,3 +98,6 @@ ansi-colors('white', $vue-ui-color-light) .no-margin-y margin-top 0 margin-bottom 0 + +.fill-height + height 100% diff --git a/packages/@vue/cli-ui/src/util/route.js b/packages/@vue/cli-ui/src/util/route.js new file mode 100644 index 0000000000..27b689771f --- /dev/null +++ b/packages/@vue/cli-ui/src/util/route.js @@ -0,0 +1,60 @@ +const trailingSlashRE = /\/?$/ + +export function isSameRoute (a, b) { + if (!b) { + return false + } else if (a.path && b.path) { + return ( + a.path.replace(trailingSlashRE, '') === b.path.replace(trailingSlashRE, '') && + a.hash === b.hash && + isObjectEqual(a.query, b.query) + ) + } else if (a.name && b.name) { + return ( + a.name === b.name && + a.hash === b.hash && + isObjectEqual(a.query, b.query) && + isObjectEqual(a.params, b.params) + ) + } else { + return false + } +} + +function isObjectEqual (a = {}, b = {}) { + // handle null value #1566 + if (!a || !b) return a === b + const aKeys = Object.keys(a) + const bKeys = Object.keys(b) + if (aKeys.length !== bKeys.length) { + return false + } + return aKeys.every(key => { + const aVal = a[key] + const bVal = b[key] + // check nested equality + if (typeof aVal === 'object' && typeof bVal === 'object') { + return isObjectEqual(aVal, bVal) + } + return String(aVal) === String(bVal) + }) +} + +export function isIncludedRoute (current, target) { + return ( + current.path.replace(trailingSlashRE, '/').indexOf( + target.path.replace(trailingSlashRE, '/') + ) === 0 && + (!target.hash || current.hash === target.hash) && + queryIncludes(current.query, target.query) + ) +} + +function queryIncludes (current, target) { + for (const key in target) { + if (!(key in current)) { + return false + } + } + return true +} diff --git a/packages/@vue/cli-ui/src/views/ProjectCreate.vue b/packages/@vue/cli-ui/src/views/ProjectCreate.vue index 7961d382e8..8fb81d4f3b 100644 --- a/packages/@vue/cli-ui/src/views/ProjectCreate.vue +++ b/packages/@vue/cli-ui/src/views/ProjectCreate.vue @@ -404,7 +404,7 @@ export default { Prompts({ field: 'projectCreation', query: PROJECT_CREATION - }), + }) ], data () { @@ -414,19 +414,19 @@ export default { projectCreation: null, showCancel: false, showRemotePreset: false, - showSavePreset: false, + showSavePreset: false } }, apollo: { cwd: { query: CWD, - fetchPolicy: 'network-only', + fetchPolicy: 'network-only' }, projectCreation: { query: PROJECT_CREATION, - fetchPolicy: 'network-only', + fetchPolicy: 'network-only' } }, @@ -512,10 +512,10 @@ export default { }) this.$router.push({ name: 'project-home' }) this.reset() - } catch(e) { + } catch (e) { console.error(e) } - }, + } } } diff --git a/packages/@vue/cli-ui/src/views/ProjectHome.vue b/packages/@vue/cli-ui/src/views/ProjectHome.vue index a61d8573b4..8545a1fab7 100644 --- a/packages/@vue/cli-ui/src/views/ProjectHome.vue +++ b/packages/@vue/cli-ui/src/views/ProjectHome.vue @@ -10,7 +10,7 @@ diff --git a/packages/@vue/cli-ui/src/views/ProjectPluginsAdd.vue b/packages/@vue/cli-ui/src/views/ProjectPluginsAdd.vue index f095ec9934..fd7dc74724 100644 --- a/packages/@vue/cli-ui/src/views/ProjectPluginsAdd.vue +++ b/packages/@vue/cli-ui/src/views/ProjectPluginsAdd.vue @@ -163,7 +163,6 @@ import PLUGIN_INSTALLATION from '../graphql/pluginInstallation.gql' import PLUGIN_INSTALL from '../graphql/pluginInstall.gql' import PLUGIN_UNINSTALL from '../graphql/pluginUninstall.gql' import PLUGIN_INVOKE from '../graphql/pluginInvoke.gql' -import PROMPT_ANSWER from '../graphql/promptAnswer.gql' export default { name: 'ProjectPluginsAdd', @@ -190,7 +189,7 @@ export default { fetchPolicy: 'netork-only', result () { this.checkTab() - }, + } } }, @@ -231,12 +230,12 @@ export default { } }) this.tabId = 'config' - } catch(e) { + } catch (e) { console.error(e) } }, - cancelInstall () { + cancelInstall () { this.selectedId = null this.tabId = 'search' this.showCancelInstall = false @@ -252,7 +251,7 @@ export default { } }) this.cancelInstall() - } catch(e) { + } catch (e) { console.error(e) } }, @@ -266,10 +265,10 @@ export default { } }) this.close() - } catch(e) { + } catch (e) { console.error(e) } - }, + } } } diff --git a/packages/@vue/cli-ui/src/views/ProjectTaskDetails.vue b/packages/@vue/cli-ui/src/views/ProjectTaskDetails.vue new file mode 100644 index 0000000000..7924d6273b --- /dev/null +++ b/packages/@vue/cli-ui/src/views/ProjectTaskDetails.vue @@ -0,0 +1,18 @@ + + + diff --git a/packages/@vue/cli-ui/src/views/ProjectTasks.vue b/packages/@vue/cli-ui/src/views/ProjectTasks.vue index 6eacf2db57..950d4c4918 100644 --- a/packages/@vue/cli-ui/src/views/ProjectTasks.vue +++ b/packages/@vue/cli-ui/src/views/ProjectTasks.vue @@ -3,7 +3,50 @@ - WIP + + + + +