mirror of
https://github.com/vuejs/vue-cli.git
synced 2026-03-13 12:40:18 -05:00
feat(ui): PluginApi: notify
This commit is contained in:
@@ -966,6 +966,23 @@ api.db.get('posts')
|
||||
const { storageGet, storageSet } = api.namespace('my-plugin.')
|
||||
```
|
||||
|
||||
### Notification
|
||||
|
||||
You can display notifications using the user OS notification system:
|
||||
|
||||
```js
|
||||
api.notify({
|
||||
title: 'Some title',
|
||||
message: 'Some message',
|
||||
icon: 'path-to-icon.png'
|
||||
})
|
||||
```
|
||||
|
||||
There are some builtin icons:
|
||||
|
||||
- `'done'`
|
||||
- `'error'`
|
||||
|
||||
### Localization
|
||||
|
||||
You can put locale files compatible with [vue-i18n](https://github.com/kazupon/vue-i18n) in a `locales` folder at the root of your plugin. They will be automatically loaded into the client when the project is opened. You can then use `$t` to translate strings in your components and other vue-i18n helpers. Also, the strings used in the UI API (like `describeTask`) will go through vue-i18n as well to you can localize them.
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
module.exports = api => {
|
||||
const { setSharedData, removeSharedData } = api.namespace('webpack-dashboard-')
|
||||
|
||||
let firstRun = true
|
||||
let hadFailed = false
|
||||
|
||||
function resetSharedData (key) {
|
||||
setSharedData(`${key}-status`, null)
|
||||
setSharedData(`${key}-progress`, 0)
|
||||
@@ -15,6 +18,33 @@ module.exports = api => {
|
||||
const type = message.webpackDashboardData.type
|
||||
for (const data of message.webpackDashboardData.value) {
|
||||
setSharedData(`${type}-${data.type}`, data.value)
|
||||
|
||||
if (type === 'serve' && data.type === 'status') {
|
||||
if (data.value === 'Failed') {
|
||||
api.notify({
|
||||
title: 'Build failed',
|
||||
message: 'The build has errors.',
|
||||
icon: 'error'
|
||||
})
|
||||
hadFailed = true
|
||||
} else if (data.value === 'Success') {
|
||||
if (hadFailed) {
|
||||
api.notify({
|
||||
title: 'Build fixed',
|
||||
message: 'The build succeeded.',
|
||||
icon: 'done'
|
||||
})
|
||||
hadFailed = false
|
||||
} else if (firstRun) {
|
||||
api.notify({
|
||||
title: 'App ready',
|
||||
message: 'The build succeeded.',
|
||||
icon: 'done'
|
||||
})
|
||||
firstRun = false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -107,6 +137,8 @@ module.exports = api => {
|
||||
// Data
|
||||
resetSharedData('serve')
|
||||
removeSharedData('serve-url')
|
||||
firstRun = true
|
||||
hadFailed = false
|
||||
},
|
||||
onRun: () => {
|
||||
api.ipcOn(onWebpackMessage)
|
||||
|
||||
@@ -4,11 +4,13 @@ const sharedData = require('../connectors/shared-data')
|
||||
const views = require('../connectors/views')
|
||||
// Utils
|
||||
const ipc = require('../utils/ipc')
|
||||
const { notify } = require('../utils/notification')
|
||||
// Validators
|
||||
const { validateConfiguration } = require('./configuration')
|
||||
const { validateDescribeTask, validateAddTask } = require('./task')
|
||||
const { validateClientAddon } = require('./client-addon')
|
||||
const { validateView, validateBadge } = require('./view')
|
||||
const { validateNotify } = require('./notify')
|
||||
|
||||
class PluginApi {
|
||||
constructor (context) {
|
||||
@@ -264,6 +266,24 @@ class PluginApi {
|
||||
return this.context.db
|
||||
}
|
||||
|
||||
/**
|
||||
* Display a notification in the user OS
|
||||
* @param {object} options Notification options
|
||||
*/
|
||||
notify (options) {
|
||||
try {
|
||||
validateNotify(options)
|
||||
notify(options)
|
||||
} catch (e) {
|
||||
logs.add({
|
||||
type: 'error',
|
||||
tag: 'PluginApi',
|
||||
message: `(${this.pluginId || 'unknown plugin'}) 'notify' options are invalid\n${e.message}`
|
||||
}, this.context)
|
||||
console.error(new Error(`Invalid options: ${e.message}`))
|
||||
}
|
||||
}
|
||||
|
||||
/* Namespaced */
|
||||
|
||||
/**
|
||||
|
||||
11
packages/@vue/cli-ui/src/graphql-api/api/notify.js
Normal file
11
packages/@vue/cli-ui/src/graphql-api/api/notify.js
Normal file
@@ -0,0 +1,11 @@
|
||||
const { createSchema, validateSync } = require('@vue/cli-shared-utils')
|
||||
|
||||
const schema = createSchema(joi => ({
|
||||
title: joi.string().required(),
|
||||
message: joi.string().required(),
|
||||
icon: joi.string()
|
||||
}))
|
||||
|
||||
exports.validateNotify = (options) => {
|
||||
validateSync(options, schema)
|
||||
}
|
||||
@@ -16,7 +16,6 @@ const {
|
||||
updatePackage
|
||||
} = require('@vue/cli/lib/util/installDeps')
|
||||
const invoke = require('@vue/cli/lib/invoke')
|
||||
const notifier = require('node-notifier')
|
||||
// Subs
|
||||
const channels = require('../channels')
|
||||
// Connectors
|
||||
@@ -36,6 +35,7 @@ const { getCommand } = require('../utils/command')
|
||||
const { resolveModuleRoot } = require('../utils/resolve-path')
|
||||
const ipc = require('../utils/ipc')
|
||||
const { log } = require('../utils/logger')
|
||||
const { notify } = require('../utils/notification')
|
||||
|
||||
const PROGRESS_ID = 'plugin-installation'
|
||||
const CLI_SERVICE = '@vue/cli-service'
|
||||
@@ -264,10 +264,10 @@ function install (id, context) {
|
||||
await initPrompts(id, context)
|
||||
installationStep = 'config'
|
||||
|
||||
notifier.notify({
|
||||
notify({
|
||||
title: `Plugin installed`,
|
||||
message: `Plugin ${id} installed, next step is configuration`,
|
||||
icon: path.resolve(__dirname, '../../assets/done.png')
|
||||
icon: 'done'
|
||||
})
|
||||
|
||||
return getInstallation(context)
|
||||
@@ -297,10 +297,10 @@ function uninstall (id, context) {
|
||||
currentPluginId = null
|
||||
installationStep = null
|
||||
|
||||
notifier.notify({
|
||||
notify({
|
||||
title: `Plugin uninstalled`,
|
||||
message: `Plugin ${id} uninstalled`,
|
||||
icon: path.resolve(__dirname, '../../assets/done.png')
|
||||
icon: 'done'
|
||||
})
|
||||
|
||||
return getInstallation(context)
|
||||
@@ -329,10 +329,10 @@ function runInvoke (id, context) {
|
||||
runPluginApi(id, context)
|
||||
installationStep = 'diff'
|
||||
|
||||
notifier.notify({
|
||||
notify({
|
||||
title: `Plugin invoke sucess`,
|
||||
message: `Plugin ${id} invoked successfully`,
|
||||
icon: path.resolve(__dirname, '../../assets/done.png')
|
||||
icon: 'done'
|
||||
})
|
||||
|
||||
return getInstallation(context)
|
||||
@@ -377,10 +377,10 @@ function update (id, context, notify = true) {
|
||||
}, context)
|
||||
|
||||
if (notify) {
|
||||
notifier.notify({
|
||||
notify({
|
||||
title: `Plugin updated`,
|
||||
message: `Plugin ${id} was successfully updated`,
|
||||
icon: path.resolve(__dirname, '../../assets/done.png')
|
||||
icon: 'done'
|
||||
})
|
||||
}
|
||||
|
||||
@@ -399,10 +399,10 @@ async function updateAll (context) {
|
||||
}
|
||||
}
|
||||
|
||||
notifier.notify({
|
||||
notify({
|
||||
title: `Plugins updated`,
|
||||
message: `${updatedPlugins.length} plugin(s) were successfully updated`,
|
||||
icon: path.resolve(__dirname, '../../assets/done.png')
|
||||
icon: 'done'
|
||||
})
|
||||
|
||||
return updatedPlugins
|
||||
|
||||
@@ -7,7 +7,6 @@ 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 notifier = require('node-notifier')
|
||||
// Connectors
|
||||
const progress = require('./progress')
|
||||
const cwd = require('./cwd')
|
||||
@@ -19,6 +18,7 @@ const locales = require('./locales')
|
||||
const getContext = require('../context')
|
||||
// Utils
|
||||
const { log } = require('../utils/logger')
|
||||
const { notify } = require('../utils/notification')
|
||||
|
||||
const PROGRESS_ID = 'project-create'
|
||||
|
||||
@@ -309,10 +309,10 @@ async function create (input, context) {
|
||||
await creator.create({ git: true }, preset)
|
||||
removeCreator()
|
||||
|
||||
notifier.notify({
|
||||
notify({
|
||||
title: `Project created`,
|
||||
message: `Project ${cwd.get()} created`,
|
||||
icon: path.resolve(__dirname, '../../assets/done.png')
|
||||
icon: 'done'
|
||||
})
|
||||
|
||||
return importProject({
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
const path = require('path')
|
||||
const execa = require('execa')
|
||||
const terminate = require('terminate')
|
||||
const notifier = require('node-notifier')
|
||||
// Subs
|
||||
const channels = require('../channels')
|
||||
// Connectors
|
||||
@@ -14,6 +12,7 @@ const views = require('./views')
|
||||
// Utils
|
||||
const { getCommand } = require('../utils/command')
|
||||
const { log } = require('../utils/logger')
|
||||
const { notify } = require('../utils/notification')
|
||||
|
||||
const MAX_LOGS = 2000
|
||||
const VIEW_ID = 'vue-project-tasks'
|
||||
@@ -329,10 +328,10 @@ async function run (id, context) {
|
||||
message: `Task ${task.id} ended with error code ${code}`,
|
||||
type: 'error'
|
||||
}, context)
|
||||
notifier.notify({
|
||||
notify({
|
||||
title: `Task error`,
|
||||
message: `Task ${task.id} ended with error code ${code}`,
|
||||
icon: path.resolve(__dirname, '../../assets/error.png')
|
||||
icon: 'error'
|
||||
})
|
||||
} else {
|
||||
updateOne({
|
||||
@@ -343,10 +342,10 @@ async function run (id, context) {
|
||||
message: `Task ${task.id} completed`,
|
||||
type: 'done'
|
||||
}, context)
|
||||
notifier.notify({
|
||||
notify({
|
||||
title: `Task completed`,
|
||||
message: `Task ${task.id} completed`,
|
||||
icon: path.resolve(__dirname, '../../assets/done.png')
|
||||
icon: 'done'
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
15
packages/@vue/cli-ui/src/graphql-api/utils/notification.js
Normal file
15
packages/@vue/cli-ui/src/graphql-api/utils/notification.js
Normal file
@@ -0,0 +1,15 @@
|
||||
const path = require('path')
|
||||
const notifier = require('node-notifier')
|
||||
|
||||
const builtinIcons = {
|
||||
'done': path.resolve(__dirname, '../../assets/done.png'),
|
||||
'error': path.resolve(__dirname, '../../assets/error.png')
|
||||
}
|
||||
|
||||
exports.notify = ({ title, message, icon }) => {
|
||||
notifier.notify({
|
||||
title,
|
||||
message,
|
||||
icon: builtinIcons[icon] || icon
|
||||
})
|
||||
}
|
||||
Reference in New Issue
Block a user