diff --git a/packages/@vue/cli-shared-utils/lib/logger.js b/packages/@vue/cli-shared-utils/lib/logger.js index c03005c421..a1b1fa8faf 100644 --- a/packages/@vue/cli-shared-utils/lib/logger.js +++ b/packages/@vue/cli-shared-utils/lib/logger.js @@ -1,6 +1,19 @@ const chalk = require('chalk') const readline = require('readline') const padStart = require('string.prototype.padstart') +const EventEmitter = require('events') + +exports.events = new EventEmitter() + +function _log (type, tag, message) { + if (process.env.VUE_CLI_API_MODE && message) { + exports.events.emit('log', { + message, + type, + tag + }) + } +} const format = (label, msg) => { return msg.split('\n').map((line, i) => { @@ -12,24 +25,32 @@ const format = (label, msg) => { const chalkTag = msg => chalk.bgBlackBright.white.dim(` ${msg} `) -exports.log = (msg = '', tag = null) => tag ? console.log(format(chalkTag(tag), msg)) : console.log(msg) +exports.log = (msg = '', tag = null) => { + tag ? console.log(format(chalkTag(tag), msg)) : console.log(msg) + _log('log', tag, msg) +} exports.info = (msg, tag = null) => { console.log(format(chalk.bgBlue.black(' INFO ') + (tag ? chalkTag(tag) : ''), msg)) + _log('info', tag, msg) } exports.done = (msg, tag = null) => { console.log(format(chalk.bgGreen.black(' DONE ') + (tag ? chalkTag(tag) : ''), msg)) + _log('done', tag, msg) } exports.warn = (msg, tag = null) => { console.warn(format(chalk.bgYellow.black(' WARN ') + (tag ? chalkTag(tag) : ''), chalk.yellow(msg))) + _log('warn', tag, msg) } exports.error = (msg, tag = null) => { console.error(format(chalk.bgRed(' ERROR ') + (tag ? chalkTag(tag) : ''), chalk.red(msg))) + _log('error', tag, msg) if (msg instanceof Error) { console.error(msg.stack) + _log('error', tag, msg.stack) } } diff --git a/packages/@vue/cli-ui/package.json b/packages/@vue/cli-ui/package.json index dccef85175..33ef10c335 100644 --- a/packages/@vue/cli-ui/package.json +++ b/packages/@vue/cli-ui/package.json @@ -21,6 +21,7 @@ "@vue/cli-service": "^3.0.0-beta.3", "@vue/eslint-config-standard": "^3.0.0-beta.3", "@vue/ui": "^0.1.9", + "ansi_up": "^2.0.2", "apollo-cache-inmemory": "^1.1.10", "apollo-client": "^2.2.6", "apollo-link": "^1.2.1", @@ -38,7 +39,8 @@ "vue-apollo": "^3.0.0-alpha.1", "vue-cli-plugin-apollo": "^0.4.1", "vue-router": "^3.0.1", - "vue-template-compiler": "^2.5.13" + "vue-template-compiler": "^2.5.13", + "xterm": "^3.2.0" }, "browserslist": [ "> 1%", diff --git a/packages/@vue/cli-ui/src/App.vue b/packages/@vue/cli-ui/src/App.vue index a0719d33a1..f6c783fa51 100644 --- a/packages/@vue/cli-ui/src/App.vue +++ b/packages/@vue/cli-ui/src/App.vue @@ -31,7 +31,7 @@ export default { .app display grid grid-template-columns 1fr - grid-template-rows auto 28px + grid-template-rows 1fr auto grid-template-areas "content" "status" .content diff --git a/packages/@vue/cli-ui/src/components/ListItemInfo.vue b/packages/@vue/cli-ui/src/components/ListItemInfo.vue index a9e9651bc3..5f5d8fb75f 100644 --- a/packages/@vue/cli-ui/src/components/ListItemInfo.vue +++ b/packages/@vue/cli-ui/src/components/ListItemInfo.vue @@ -55,7 +55,7 @@ export default { justify-content center .description - color lighten($vue-color-dark, 40%) + color $color-text-light &.selected .name diff --git a/packages/@vue/cli-ui/src/components/LoadingScreen.vue b/packages/@vue/cli-ui/src/components/LoadingScreen.vue deleted file mode 100644 index 753e8992d7..0000000000 --- a/packages/@vue/cli-ui/src/components/LoadingScreen.vue +++ /dev/null @@ -1,64 +0,0 @@ - - - - - diff --git a/packages/@vue/cli-ui/src/components/LoggerMessage.vue b/packages/@vue/cli-ui/src/components/LoggerMessage.vue new file mode 100644 index 0000000000..78bac05599 --- /dev/null +++ b/packages/@vue/cli-ui/src/components/LoggerMessage.vue @@ -0,0 +1,105 @@ + + + + + diff --git a/packages/@vue/cli-ui/src/components/LoggerView.vue b/packages/@vue/cli-ui/src/components/LoggerView.vue new file mode 100644 index 0000000000..b0464a0603 --- /dev/null +++ b/packages/@vue/cli-ui/src/components/LoggerView.vue @@ -0,0 +1,83 @@ + + + + + diff --git a/packages/@vue/cli-ui/src/components/ProgressScreen.vue b/packages/@vue/cli-ui/src/components/ProgressScreen.vue new file mode 100644 index 0000000000..950c7097c8 --- /dev/null +++ b/packages/@vue/cli-ui/src/components/ProgressScreen.vue @@ -0,0 +1,117 @@ + + + + + diff --git a/packages/@vue/cli-ui/src/components/ProjectNav.vue b/packages/@vue/cli-ui/src/components/ProjectNav.vue index 1f2a3ed700..0dd3b82b44 100644 --- a/packages/@vue/cli-ui/src/components/ProjectNav.vue +++ b/packages/@vue/cli-ui/src/components/ProjectNav.vue @@ -52,7 +52,8 @@ export default { button-colors(rgba($vue-color-light, .7), transparent) border-radius 0 &:hover - button-colors($vue-color-light, lighten($vue-color-dark, 10%)) + $bg = darken($vue-color-dark, 70%) + button-colors($vue-color-light, $bg) &.selected - button-colors($vue-color-primary, lighten($vue-color-dark, 10%)) + button-colors(lighten($vue-color-primary, 40%), $bg) diff --git a/packages/@vue/cli-ui/src/components/StatusBar.vue b/packages/@vue/cli-ui/src/components/StatusBar.vue index c91d38a652..7ec68713eb 100644 --- a/packages/@vue/cli-ui/src/components/StatusBar.vue +++ b/packages/@vue/cli-ui/src/components/StatusBar.vue @@ -1,58 +1,112 @@ @@ -62,10 +116,14 @@ export default { @import "~@/style/imports" .status-bar - h-box() - align-items center - background $vue-color-light-neutral - font-size $padding-item + $bg = $vue-color-light-neutral + + .content + h-box() + align-items center + background $bg + font-size $padding-item + height 28px .section h-box() @@ -77,11 +135,20 @@ export default { &:hover opacity 1 - background lighten(@background, 40%) + background lighten($bg, 40%) > .vue-icon + * margin-left 4px .label color lighten($vue-color-dark, 20%) + + .console-log + &, + .last-message + flex 100% 1 1 + width 0 + + .last-message + font-size .9em diff --git a/packages/@vue/cli-ui/src/components/TerminalView.vue b/packages/@vue/cli-ui/src/components/TerminalView.vue new file mode 100644 index 0000000000..2984a8161e --- /dev/null +++ b/packages/@vue/cli-ui/src/components/TerminalView.vue @@ -0,0 +1,159 @@ + + + + + + + diff --git a/packages/@vue/cli-ui/src/graphql-api/channels.js b/packages/@vue/cli-ui/src/graphql-api/channels.js index f205c04259..6fd0584afc 100644 --- a/packages/@vue/cli-ui/src/graphql-api/channels.js +++ b/packages/@vue/cli-ui/src/graphql-api/channels.js @@ -1,4 +1,5 @@ module.exports = { CWD_CHANGED: 'cwd_changed', - CREATE_STATUS: 'create_status' + PROGRESS_CHANGED: 'progress_changed', + CONSOLE_LOG_ADDED: 'console_log_added' } diff --git a/packages/@vue/cli-ui/src/graphql-api/connectors/folders.js b/packages/@vue/cli-ui/src/graphql-api/connectors/folders.js index ba56d8911d..e8703918fc 100644 --- a/packages/@vue/cli-ui/src/graphql-api/connectors/folders.js +++ b/packages/@vue/cli-ui/src/graphql-api/connectors/folders.js @@ -1,5 +1,6 @@ const path = require('path') const fs = require('fs') +const rimraf = require('rimraf') const cwd = require('./cwd') @@ -77,6 +78,18 @@ function setFavorite ({ file, favorite }, context) { return generateFolder(file, context) } +function deleteFolder (file) { + return new Promise((resolve, reject) => { + rimraf(file, err => { + if (err) { + reject(err) + } else { + resolve() + } + }) + }) +} + module.exports = { getCurrent, list, @@ -86,5 +99,6 @@ module.exports = { readPackage, isVueProject, listFavorite, - setFavorite + setFavorite, + delete: deleteFolder } diff --git a/packages/@vue/cli-ui/src/graphql-api/connectors/logs.js b/packages/@vue/cli-ui/src/graphql-api/connectors/logs.js new file mode 100644 index 0000000000..8041d8af8b --- /dev/null +++ b/packages/@vue/cli-ui/src/graphql-api/connectors/logs.js @@ -0,0 +1,53 @@ +const shortId = require('shortid') +const { events } = require('@vue/cli-shared-utils/lib/logger') +const { generateTitle } = require('@vue/cli/lib/util/clearConsole') + +const channels = require('../channels') + +let init = false +let logs = [] + +exports.add = function (log, context) { + const item = { + id: shortId.generate(), + date: new Date().toISOString(), + tag: null, + ...log + } + logs.push(item) + context.pubsub.publish(channels.CONSOLE_LOG_ADDED, { + consoleLogAdded: item + }) + return item +} + +exports.init = function (context) { + if (!init) { + init = true + events.on('log', log => { + exports.add(log, context) + }) + + exports.add({ + type: 'info', + tag: null, + message: generateTitle(true) + }, context) + } +} + +exports.list = function (context) { + return logs +} + +exports.last = function (context) { + if (logs.length) { + return logs[logs.length - 1] + } + return null +} + +exports.clear = function (context) { + logs = [] + return logs +} diff --git a/packages/@vue/cli-ui/src/graphql-api/connectors/progress.js b/packages/@vue/cli-ui/src/graphql-api/connectors/progress.js new file mode 100644 index 0000000000..9de2630d04 --- /dev/null +++ b/packages/@vue/cli-ui/src/graphql-api/connectors/progress.js @@ -0,0 +1,59 @@ +const channels = require('../channels') + +let map = new Map() + +function get (id, context) { + return map.get(id) +} + +function set (data, context) { + const { id } = data + let progress = get(id, context) + if (!progress) { + progress = data + map.set(id, Object.assign({}, { + status: null, + error: null, + info: null, + progress: -1 + }, progress)) + } else { + Object.assign(progress, data) + } + context.pubsub.publish(channels.PROGRESS_CHANGED, { progressChanged: progress }) + return progress +} + +function remove (id, context) { + return map.delete(id) +} + +async function wrap (id, context, operation) { + set({ id }, context) + + let result + let error = null + try { + result = await operation(data => { + set(Object.assign({ id }, data), context) + }) + } catch (e) { + error = e + set({ id, error: error.message }, context) + } + + remove(id, context) + + if (error) { + throw error + } + + return result +} + +module.exports = { + get, + set, + remove, + wrap +} diff --git a/packages/@vue/cli-ui/src/graphql-api/connectors/projects.js b/packages/@vue/cli-ui/src/graphql-api/connectors/projects.js index c0294c21d4..5c505e3e87 100644 --- a/packages/@vue/cli-ui/src/graphql-api/connectors/projects.js +++ b/packages/@vue/cli-ui/src/graphql-api/connectors/projects.js @@ -1,24 +1,27 @@ const path = require('path') const fs = require('fs') const shortId = require('shortid') -const rimraf = require('rimraf') const Creator = require('@vue/cli/lib/Creator') const { getPromptModules } = require('@vue/cli/lib/util/createTools') const { getFeatures } = require('@vue/cli/lib/util/features') const { defaults } = require('@vue/cli/lib/options') const { toShortPluginId } = require('@vue/cli-shared-utils') +const { progress: installProgress } = require('@vue/cli/lib/util/installDeps') -const channels = require('../channels') - +const progress = require('./progress') const cwd = require('./cwd') const prompts = require('./prompts') const folders = require('./folders') +const PROGRESS_ID = 'project-create' + let currentProject = null let creator = null let presets = [] let features = [] let onCreationEvent = null +let onInstallProgress = null +let onInstallLog = null function list (context) { return context.db.get('projects').value() @@ -50,9 +53,23 @@ function initCreator (context) { const creator = new Creator('', cwd.get(), getPromptModules()) onCreationEvent = ({ event }) => { - context.pubsub.publish(channels.CREATE_STATUS, { createStatus: event }) + progress.set({ id: PROGRESS_ID, status: event, info: null }, context) + } + creator.on('creation', onCreationEvent) + + onInstallProgress = value => { + if (progress.get(PROGRESS_ID)) { + progress.set({ id: PROGRESS_ID, progress: value }, context) + } + } + installProgress.on('progress', onInstallProgress) + + onInstallLog = message => { + if (progress.get(PROGRESS_ID)) { + progress.set({ id: PROGRESS_ID, info: message }, context) + } } - creator.addListener('creation', onCreationEvent) + installProgress.on('log', onInstallLog) // Presets const presetsData = creator.getPresets() @@ -116,6 +133,8 @@ function initCreator (context) { function removeCreator (context) { if (creator) { creator.removeListener('creation', onCreationEvent) + installProgress.removeListener('progress', onInstallProgress) + installProgress.removeListener('log', onInstallLog) creator = null } } @@ -185,59 +204,77 @@ function answerPrompt ({ id, value }, context) { } async function create (input, context) { - const targetDir = path.join(cwd.get(), input.folder) - creator.context = targetDir - - const inCurrent = input.folder === '.' - const name = inCurrent ? path.relative('../', process.cwd()) : input.folder - creator.name = name - - if (fs.existsSync(targetDir)) { - if (input.force) { - rimraf.sync(targetDir) - } else { - throw new Error(`Folder ${targetDir} already exists`) + return progress.wrap(PROGRESS_ID, context, async setProgress => { + setProgress({ + status: 'creating' + }) + + const targetDir = path.join(cwd.get(), input.folder) + creator.context = targetDir + + const inCurrent = input.folder === '.' + const name = inCurrent ? path.relative('../', process.cwd()) : input.folder + creator.name = name + + if (fs.existsSync(targetDir)) { + if (input.force) { + setProgress({ + info: 'Cleaning folder...' + }) + await folders.delete(targetDir) + setProgress({ + info: null + }) + } else { + throw new Error(`Folder ${targetDir} already exists`) + } } - } - const answers = prompts.getAnswers() - prompts.reset() - let index + const answers = prompts.getAnswers() + prompts.reset() + let index - // Package Manager - answers.packageManager = input.packageManager + // Package Manager + answers.packageManager = input.packageManager - // Config files - if ((index = answers.features.includes('use-config-files')) !== -1) { - answers.features.splice(index, 1) - answers.useConfigFiles = 'files' - } + // Config files + if ((index = answers.features.includes('use-config-files')) !== -1) { + answers.features.splice(index, 1) + answers.useConfigFiles = 'files' + } - // Preset - answers.preset = input.preset - if (input.save) { - answers.save = true - answers.saveName = input.save - } + // Preset + answers.preset = input.preset + if (input.save) { + answers.save = true + answers.saveName = input.save + } - let preset - if (input.remote) { - // vue create foo --preset bar - preset = await creator.resolvePreset(input.preset, input.clone) - } else if (input.preset === 'default') { - // vue create foo --default - preset = defaults.presets.default - } else { - preset = await creator.promptAndResolvePreset(answers) - } + setProgress({ + info: 'Resolving preset...' + }) + let preset + if (input.remote) { + // vue create foo --preset bar + preset = await creator.resolvePreset(input.preset, input.clone) + } else if (input.preset === 'default') { + // vue create foo --default + preset = defaults.presets.default + } else { + preset = await creator.promptAndResolvePreset(answers) + } + setProgress({ + info: null + }) - await creator.create({}, preset) + await creator.create({}, preset) - removeCreator() + removeCreator() - return importProject({ - path: targetDir - }, context) + return importProject({ + path: targetDir + }, context) + }) } async function importProject (input, context) { diff --git a/packages/@vue/cli-ui/src/graphql-api/resolvers.js b/packages/@vue/cli-ui/src/graphql-api/resolvers.js index 715479bc25..dce421ac72 100644 --- a/packages/@vue/cli-ui/src/graphql-api/resolvers.js +++ b/packages/@vue/cli-ui/src/graphql-api/resolvers.js @@ -1,12 +1,20 @@ +const { withFilter } = require('graphql-subscriptions') const exit = require('@vue/cli-shared-utils/lib/exit') + const channels = require('./channels') + +// Connectors const cwd = require('./connectors/cwd') const folders = require('./connectors/folders') const projects = require('./connectors/projects') +const progress = require('./connectors/progress') +const logs = require('./connectors/logs') // Prevent code from exiting server process exit.exitProcess = false +process.env.VUE_CLI_API_MODE = true + module.exports = { Folder: { children: (folder, args, context) => folders.list(folder.path, context), @@ -20,6 +28,9 @@ module.exports = { Query: { cwd: () => cwd.get(), + consoleLogs: (root, args, context) => logs.list(context), + consoleLogLast: (root, args, context) => logs.last(context), + progress: (root, { id }, context) => progress.get(id, context), folderCurrent: (root, args, context) => folders.getCurrent(args, context), foldersFavorite: (root, args, context) => folders.listFavorite(context), projects: (root, args, context) => projects.list(context), @@ -28,6 +39,7 @@ module.exports = { }, Mutation: { + consoleLogsClear: (root, args, context) => logs.clear(context), folderOpen: (root, { path }, context) => folders.open(path, context), folderOpenParent: (root, args, context) => folders.openParent(cwd.get(), context), folderSetFavorite: (root, args, context) => folders.setFavorite({ @@ -47,8 +59,19 @@ module.exports = { cwdChanged: { subscribe: (parent, args, { pubsub }) => pubsub.asyncIterator(channels.CWD_CHANGED) }, - createStatus: { - subscribe: (parent, args, { pubsub }) => pubsub.asyncIterator(channels.CREATE_STATUS) + progressChanged: { + subscribe: withFilter( + // Iterator + (parent, args, { pubsub }) => pubsub.asyncIterator(channels.PROGRESS_CHANGED), + // Filter + (payload, variables) => payload.progressChanged.id === variables.id + ) + }, + consoleLogAdded: { + subscribe: (parent, args, context) => { + logs.init(context) + return context.pubsub.asyncIterator(channels.CONSOLE_LOG_ADDED) + } } } } 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 0b0cd67b2b..c5f9430910 100644 --- a/packages/@vue/cli-ui/src/graphql-api/type-defs.js +++ b/packages/@vue/cli-ui/src/graphql-api/type-defs.js @@ -3,9 +3,9 @@ module.exports = ` type ConsoleLog { id: ID! message: String! - label: String tag: String type: ConsoleLogType! + date: String } enum ConsoleLogType { @@ -140,8 +140,20 @@ input PromptInput { value: String! } +type Progress { + id: ID! + status: String + info: String + error: String + # Progress from 0 to 1 (-1 means disabled) + progress: Float +} + type Query { + progress (id: ID!): Progress cwd: String! + consoleLogs: [ConsoleLog] + consoleLogLast: ConsoleLog folderCurrent: Folder foldersFavorite: [Folder] projects: [Project] @@ -151,6 +163,7 @@ type Query { } type Mutation { + consoleLogsClear: [ConsoleLog] folderOpen (path: String!): Folder folderOpenParent: Folder folderSetFavorite (path: String!, favorite: Boolean!): Folder @@ -166,8 +179,8 @@ type Mutation { } type Subscription { + progressChanged (id: ID!): Progress consoleLogAdded: ConsoleLog! cwdChanged: String! - createStatus: String! } ` diff --git a/packages/@vue/cli-ui/src/graphql/consoleLogAdded.gql b/packages/@vue/cli-ui/src/graphql/consoleLogAdded.gql new file mode 100644 index 0000000000..3e5e5bb46a --- /dev/null +++ b/packages/@vue/cli-ui/src/graphql/consoleLogAdded.gql @@ -0,0 +1,7 @@ +#import "./consoleLogFragment.gql" + +subscription consoleLogAdded { + consoleLogAdded { + ...consoleLog + } +} diff --git a/packages/@vue/cli-ui/src/graphql/consoleLogFragment.gql b/packages/@vue/cli-ui/src/graphql/consoleLogFragment.gql new file mode 100644 index 0000000000..fcf64b1f26 --- /dev/null +++ b/packages/@vue/cli-ui/src/graphql/consoleLogFragment.gql @@ -0,0 +1,7 @@ +fragment consoleLog on ConsoleLog { + id + type + message + tag + date +} diff --git a/packages/@vue/cli-ui/src/graphql/consoleLogLast.gql b/packages/@vue/cli-ui/src/graphql/consoleLogLast.gql new file mode 100644 index 0000000000..e7fca0d77d --- /dev/null +++ b/packages/@vue/cli-ui/src/graphql/consoleLogLast.gql @@ -0,0 +1,7 @@ +#import "./consoleLogFragment.gql" + +query consoleLogLast { + consoleLogLast { + ...consoleLog + } +} diff --git a/packages/@vue/cli-ui/src/graphql/consoleLogs.gql b/packages/@vue/cli-ui/src/graphql/consoleLogs.gql new file mode 100644 index 0000000000..685181b651 --- /dev/null +++ b/packages/@vue/cli-ui/src/graphql/consoleLogs.gql @@ -0,0 +1,7 @@ +#import "./consoleLogFragment.gql" + +query consoleLogs { + consoleLogs { + ...consoleLog + } +} diff --git a/packages/@vue/cli-ui/src/graphql/consoleLogsClear.gql b/packages/@vue/cli-ui/src/graphql/consoleLogsClear.gql new file mode 100644 index 0000000000..4aea6b9140 --- /dev/null +++ b/packages/@vue/cli-ui/src/graphql/consoleLogsClear.gql @@ -0,0 +1,7 @@ +#import "./consoleLogFragment.gql" + +mutation consoleLogsClear { + consoleLogsClear { + ...consoleLog + } +} diff --git a/packages/@vue/cli-ui/src/graphql/createStatus.gql b/packages/@vue/cli-ui/src/graphql/createStatus.gql deleted file mode 100644 index 1b2d42caff..0000000000 --- a/packages/@vue/cli-ui/src/graphql/createStatus.gql +++ /dev/null @@ -1,3 +0,0 @@ -subscription createStatus { - createStatus -} diff --git a/packages/@vue/cli-ui/src/graphql/progress.gql b/packages/@vue/cli-ui/src/graphql/progress.gql new file mode 100644 index 0000000000..697ced8324 --- /dev/null +++ b/packages/@vue/cli-ui/src/graphql/progress.gql @@ -0,0 +1,7 @@ +#import "./progressFragment.gql" + +query progress ($id: ID!) { + progress (id: $id) { + ...progress + } +} diff --git a/packages/@vue/cli-ui/src/graphql/progressChanged.gql b/packages/@vue/cli-ui/src/graphql/progressChanged.gql new file mode 100644 index 0000000000..fa2b5a803c --- /dev/null +++ b/packages/@vue/cli-ui/src/graphql/progressChanged.gql @@ -0,0 +1,7 @@ +#import "./progressFragment.gql" + +subscription progressChanged ($id: ID!) { + progressChanged (id: $id) { + ...progress + } +} diff --git a/packages/@vue/cli-ui/src/graphql/progressFragment.gql b/packages/@vue/cli-ui/src/graphql/progressFragment.gql new file mode 100644 index 0000000000..633cb11de1 --- /dev/null +++ b/packages/@vue/cli-ui/src/graphql/progressFragment.gql @@ -0,0 +1,7 @@ +fragment progress on Progress { + id + status + info + error + progress +} diff --git a/packages/@vue/cli-ui/src/mixins/Progress.js b/packages/@vue/cli-ui/src/mixins/Progress.js new file mode 100644 index 0000000000..712b0701cf --- /dev/null +++ b/packages/@vue/cli-ui/src/mixins/Progress.js @@ -0,0 +1,68 @@ +import PROGRESS from '../graphql/progress.gql' +import PROGRESS_CHANGED from '../graphql/progressChanged.gql' + +const messages = { + 'creating': 'Creating project...', + 'git-init': 'Initializing git repository...', + 'plugins-install': 'Installing CLI plugins. This might take a while...', + 'invoking-generators': 'Invoking generators...', + 'deps-install': 'Installing additional dependencies...', + 'completion-hooks': 'Running completion hooks...', + 'fetch-remote-preset': `Fetching remote preset...`, + 'done': 'Successfully created project' +} + +// @vue/component +export default { + props: { + progressId: { + type: String, + required: true + } + }, + + data () { + return { + progress: null + } + }, + + apollo: { + progress: { + query: PROGRESS, + variables () { + return { + id: this.progressId + } + }, + fetchPolicy: 'network-only', + subscribeToMore: { + document: PROGRESS_CHANGED, + variables () { + return { + id: this.progressId + } + }, + updateQuery: (previousResult, { subscriptionData }) => { + return { + progress: subscriptionData.data.progressChanged + } + } + } + } + }, + + computed: { + loading () { + return this.progress && !this.progress.error + }, + + statusMessage () { + if (!this.progress) return null + + const { status } = this.progress + const message = messages[status] + return message || status || '' + } + } +} diff --git a/packages/@vue/cli-ui/src/style/colors.styl b/packages/@vue/cli-ui/src/style/colors.styl index f1ee08c99a..033dd3000a 100644 --- a/packages/@vue/cli-ui/src/style/colors.styl +++ b/packages/@vue/cli-ui/src/style/colors.styl @@ -1 +1,2 @@ $color-light-background = lighten($vue-color-light-neutral, 80%) +$color-text-light = lighten($vue-color-dark, 40%) diff --git a/packages/@vue/cli-ui/src/style/main.styl b/packages/@vue/cli-ui/src/style/main.styl index 8e36bd280f..dc4d6385d9 100644 --- a/packages/@vue/cli-ui/src/style/main.styl +++ b/packages/@vue/cli-ui/src/style/main.styl @@ -32,8 +32,17 @@ body, .cta-text margin $padding-item - color lighten($vue-color-dark, 40%) + color $color-text-light font-size 18px .list-item list-item() + +ansi-colors('black', $vue-color-dark) +ansi-colors('red', $vue-color-danger) +ansi-colors('green', $vue-color-primary) +ansi-colors('yellow', $vue-color-warning) +ansi-colors('blue', $md-blue) +ansi-colors('magenta', $vue-color-accent) +ansi-colors('cyan', $vue-color-info) +ansi-colors('white', $vue-color-light) diff --git a/packages/@vue/cli-ui/src/style/mixins.styl b/packages/@vue/cli-ui/src/style/mixins.styl index de10c8b9b1..49e16a2043 100644 --- a/packages/@vue/cli-ui/src/style/mixins.styl +++ b/packages/@vue/cli-ui/src/style/mixins.styl @@ -7,3 +7,14 @@ list-item() &:hover background rgba($vue-color-primary, .1) + + +ansi-colors($name, $color) + .ansi-{$name}-fg + color $color + .ansi-{$name}-bg + background $color + .ansi-bright-{$name}-fg + color lighten($color, 10%) + .ansi-bright-{$name}-bg + background lighten($color, 10%) diff --git a/packages/@vue/cli-ui/src/views/ProjectCreate.vue b/packages/@vue/cli-ui/src/views/ProjectCreate.vue index bb1c47c202..f3adf67a6c 100644 --- a/packages/@vue/cli-ui/src/views/ProjectCreate.vue +++ b/packages/@vue/cli-ui/src/views/ProjectCreate.vue @@ -297,7 +297,7 @@ @close="showCancel = false" >
- Are you sure you want to cancel the project creation? + Are you sure you want to reset the project creation?
@@ -312,7 +312,7 @@ label="Clear project" icon-left="delete_forever" class="danger" - @click="cancel()" + @click="reset()" />
@@ -358,36 +358,14 @@ - - -
- -
{{ error }}
-
- -
-
- - -
-
+