mirror of
https://github.com/vuejs/vue-cli.git
synced 2026-01-25 16:48:56 -06:00
feat(ui): PluginApi -> describeTask initial impl.
This commit is contained in:
74
packages/@vue/cli-plugin-eslint/ui.js
Normal file
74
packages/@vue/cli-plugin-eslint/ui.js
Normal file
@@ -0,0 +1,74 @@
|
||||
module.exports = api => {
|
||||
// Config file
|
||||
api.describeConfig({
|
||||
name: 'ESLint configuration',
|
||||
description: 'Error checking & Code quality',
|
||||
link: 'https://eslint.org',
|
||||
files: {
|
||||
json: ['eslintrc', 'eslintrc.json'],
|
||||
js: ['eslintrc.js'],
|
||||
package: 'eslintConfig'
|
||||
},
|
||||
onRead: ({ data }) => {
|
||||
return {
|
||||
prompts: [
|
||||
{
|
||||
name: 'rules.commaDangle',
|
||||
type: 'list',
|
||||
message: 'Trailing commas',
|
||||
description: 'Enforce or disallow trailing commas at the end of the lines',
|
||||
link: 'https://eslint.org/docs/rules/comma-dangle',
|
||||
choices: [
|
||||
{
|
||||
name: 'Off',
|
||||
value: 'off'
|
||||
},
|
||||
{
|
||||
name: 'Never',
|
||||
value: JSON.stringify(['error', 'never'])
|
||||
},
|
||||
{
|
||||
name: 'Always',
|
||||
value: JSON.stringify(['error', 'always'])
|
||||
},
|
||||
{
|
||||
name: 'Always on multiline',
|
||||
value: JSON.stringify(['error', 'always-multiline'])
|
||||
},
|
||||
{
|
||||
name: 'Only on multiline',
|
||||
value: JSON.stringify(['error', 'only-multiline'])
|
||||
}
|
||||
],
|
||||
value: JSON.stringify(data.rules['comma-dangle'] || ['error', 'never'])
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
onWrite: ({ file, answers }) => {
|
||||
file.assignData({
|
||||
'rules.comma-dangle': answers.rules.commaDangle
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
// Tasks
|
||||
api.describeTask({
|
||||
match: /vue-cli-service lint/,
|
||||
description: 'Lints and fixes files',
|
||||
link: 'https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-eslint#injected-commands',
|
||||
prompts: [
|
||||
{
|
||||
name: 'noFix',
|
||||
type: 'confirm',
|
||||
default: false,
|
||||
description: 'Do not fix errors'
|
||||
}
|
||||
],
|
||||
onRun: ({ answers, args }) => {
|
||||
if (answers.noFix) {
|
||||
args.push('--no-fix')
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
@@ -17,7 +17,7 @@
|
||||
|
||||
<ListItemInfo
|
||||
:name="task.name"
|
||||
:description="task.description || status"
|
||||
:description="(task.status === 'idle' && task.description) || status"
|
||||
:selected="selected"
|
||||
/>
|
||||
</div>
|
||||
@@ -72,6 +72,11 @@ export default {
|
||||
flex 100% 1 1
|
||||
width 0
|
||||
|
||||
>>> .description
|
||||
white-space nowrap
|
||||
overflow hidden
|
||||
text-overflow ellipsis
|
||||
|
||||
&.selected
|
||||
&.status-error .list-item-info >>> .name
|
||||
color $vue-ui-color-danger
|
||||
|
||||
22
packages/@vue/cli-ui/src/graphql-api/api/PluginApi.js
Normal file
22
packages/@vue/cli-ui/src/graphql-api/api/PluginApi.js
Normal file
@@ -0,0 +1,22 @@
|
||||
class PluginApi {
|
||||
constructor () {
|
||||
this.configurations = []
|
||||
this.tasks = []
|
||||
}
|
||||
|
||||
describeConfig (options) {
|
||||
this.configurations.push(options)
|
||||
}
|
||||
|
||||
describeTask (options) {
|
||||
this.tasks.push(options)
|
||||
}
|
||||
|
||||
getTask (command) {
|
||||
return this.tasks.find(
|
||||
options => options.match.test(command)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = PluginApi
|
||||
@@ -1,7 +1,7 @@
|
||||
const shortId = require('shortid')
|
||||
const { events } = require('@vue/cli-shared-utils/lib/logger')
|
||||
const { generateTitle } = require('@vue/cli/lib/util/clearConsole')
|
||||
|
||||
// Subs
|
||||
const channels = require('../channels')
|
||||
|
||||
let init = false
|
||||
|
||||
@@ -8,6 +8,7 @@ const {
|
||||
getPluginLink
|
||||
} = require('@vue/cli-shared-utils')
|
||||
const getPackageVersion = require('@vue/cli/lib/util/getPackageVersion')
|
||||
const { resolveModule, loadModule } = require('@vue/cli/lib/util/module')
|
||||
const {
|
||||
progress: installProgress,
|
||||
installPackage,
|
||||
@@ -15,34 +16,36 @@ const {
|
||||
updatePackage
|
||||
} = require('@vue/cli/lib/util/installDeps')
|
||||
const invoke = require('@vue/cli/lib/invoke')
|
||||
|
||||
// Connectors
|
||||
const cwd = require('./cwd')
|
||||
const folders = require('./folders')
|
||||
const prompts = require('./prompts')
|
||||
const progress = require('./progress')
|
||||
const logs = require('./logs')
|
||||
|
||||
// Api
|
||||
const PluginApi = require('../api/PluginApi')
|
||||
// Utils
|
||||
const { getCommand } = require('../utils/command')
|
||||
|
||||
const PROGRESS_ID = 'plugin-installation'
|
||||
|
||||
// Caches
|
||||
const metadataCache = new LRU({
|
||||
max: 200,
|
||||
maxAge: 1000 * 60 * 30
|
||||
})
|
||||
|
||||
const logoCache = new LRU({
|
||||
max: 50
|
||||
})
|
||||
|
||||
const PROGRESS_ID = 'plugin-installation'
|
||||
|
||||
// Local
|
||||
let currentPluginId
|
||||
let eventsInstalled = false
|
||||
let plugins = []
|
||||
let pluginApi
|
||||
|
||||
function getPath (id) {
|
||||
return path.dirname(require.resolve(id, {
|
||||
paths: [cwd.get()]
|
||||
}))
|
||||
return path.dirname(resolveModule(id, cwd.get()))
|
||||
}
|
||||
|
||||
function findPlugins (deps) {
|
||||
@@ -64,9 +67,23 @@ function list (file, context) {
|
||||
plugins = []
|
||||
plugins = plugins.concat(findPlugins(pkg.dependencies || {}))
|
||||
plugins = plugins.concat(findPlugins(pkg.devDependencies || {}))
|
||||
resetPluginApi(context)
|
||||
return plugins
|
||||
}
|
||||
|
||||
function resetPluginApi (context) {
|
||||
pluginApi = new PluginApi()
|
||||
plugins.forEach(plugin => runPluginApi(plugin.id, context))
|
||||
}
|
||||
|
||||
function runPluginApi (id, context) {
|
||||
const module = loadModule(`${id}/ui`, cwd.get(), true)
|
||||
if (module) {
|
||||
module(pluginApi)
|
||||
console.log(`PluginApi called for ${id}`)
|
||||
}
|
||||
}
|
||||
|
||||
function findOne (id, context) {
|
||||
return plugins.find(
|
||||
p => p.id === id
|
||||
@@ -175,13 +192,9 @@ function install (id, context) {
|
||||
status: 'plugin-install',
|
||||
args: [id]
|
||||
})
|
||||
|
||||
currentPluginId = id
|
||||
|
||||
await installPackage(cwd.get(), getCommand(), null, id)
|
||||
|
||||
await initPrompts(id, context)
|
||||
|
||||
return getInstallation(context)
|
||||
})
|
||||
}
|
||||
@@ -192,13 +205,9 @@ function uninstall (id, context) {
|
||||
status: 'plugin-uninstall',
|
||||
args: [id]
|
||||
})
|
||||
|
||||
currentPluginId = id
|
||||
|
||||
await uninstallPackage(cwd.get(), getCommand(), null, id)
|
||||
|
||||
currentPluginId = null
|
||||
|
||||
return getInstallation(context)
|
||||
})
|
||||
}
|
||||
@@ -209,13 +218,14 @@ function runInvoke (id, context) {
|
||||
status: 'plugin-invoke',
|
||||
args: [id]
|
||||
})
|
||||
|
||||
currentPluginId = id
|
||||
|
||||
await invoke(id, prompts.getAnswers(), cwd.get())
|
||||
|
||||
// Allow plugins that don't have a generator
|
||||
if (resolveModule(`${id}/generator`, cwd.get())) {
|
||||
await invoke(id, prompts.getAnswers(), cwd.get())
|
||||
}
|
||||
// Run plugin api
|
||||
runPluginApi(id, context)
|
||||
currentPluginId = null
|
||||
|
||||
return getInstallation(context)
|
||||
})
|
||||
}
|
||||
@@ -240,25 +250,23 @@ function update (id, context) {
|
||||
status: 'plugin-update',
|
||||
args: [id]
|
||||
})
|
||||
|
||||
currentPluginId = id
|
||||
|
||||
const plugin = findOne(id, context)
|
||||
const { current, wanted } = await getVersion(plugin, context)
|
||||
|
||||
await updatePackage(cwd.get(), getCommand(), null, id)
|
||||
|
||||
logs.add({
|
||||
message: `Plugin ${id} updated from ${current} to ${wanted}`,
|
||||
type: 'info'
|
||||
}, context)
|
||||
|
||||
currentPluginId = null
|
||||
|
||||
return findOne(id)
|
||||
})
|
||||
}
|
||||
|
||||
function getApi () {
|
||||
return pluginApi
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
list,
|
||||
findOne,
|
||||
@@ -269,5 +277,7 @@ module.exports = {
|
||||
install,
|
||||
uninstall,
|
||||
update,
|
||||
runInvoke
|
||||
runInvoke,
|
||||
resetPluginApi,
|
||||
getApi
|
||||
}
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
// Subs
|
||||
const channels = require('../channels')
|
||||
|
||||
let map = new Map()
|
||||
|
||||
@@ -7,11 +7,12 @@ 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')
|
||||
|
||||
// Connectors
|
||||
const progress = require('./progress')
|
||||
const cwd = require('./cwd')
|
||||
const prompts = require('./prompts')
|
||||
const folders = require('./folders')
|
||||
const plugins = require('./plugins')
|
||||
|
||||
const PROGRESS_ID = 'project-create'
|
||||
|
||||
@@ -33,11 +34,9 @@ function getCurrent (context) {
|
||||
|
||||
function generatePresetDescription (preset) {
|
||||
let description = `Features: ${preset.features.join(', ')}`
|
||||
|
||||
if (preset.raw.useConfigFiles) {
|
||||
description += ` (Use config files)`
|
||||
}
|
||||
|
||||
return description
|
||||
}
|
||||
|
||||
@@ -52,18 +51,20 @@ function generateProjectCreation (creator) {
|
||||
function initCreator (context) {
|
||||
const creator = new Creator('', cwd.get(), getPromptModules())
|
||||
|
||||
/* Event listeners */
|
||||
// Creator emits creation events (the project creation steps)
|
||||
onCreationEvent = ({ event }) => {
|
||||
progress.set({ id: PROGRESS_ID, status: event, info: null }, context)
|
||||
}
|
||||
creator.on('creation', onCreationEvent)
|
||||
|
||||
// Progress bar
|
||||
onInstallProgress = value => {
|
||||
if (progress.get(PROGRESS_ID)) {
|
||||
progress.set({ id: PROGRESS_ID, progress: value }, context)
|
||||
}
|
||||
}
|
||||
installProgress.on('progress', onInstallProgress)
|
||||
|
||||
// Package manager steps
|
||||
onInstallLog = message => {
|
||||
if (progress.get(PROGRESS_ID)) {
|
||||
progress.set({ id: PROGRESS_ID, info: message }, context)
|
||||
@@ -218,6 +219,7 @@ async function create (input, context) {
|
||||
const name = inCurrent ? path.relative('../', process.cwd()) : input.folder
|
||||
creator.name = name
|
||||
|
||||
// Delete existing folder
|
||||
if (fs.existsSync(targetDir)) {
|
||||
if (input.force) {
|
||||
setProgress({
|
||||
@@ -232,6 +234,7 @@ async function create (input, context) {
|
||||
}
|
||||
}
|
||||
|
||||
// Answers
|
||||
const answers = prompts.getAnswers()
|
||||
prompts.reset()
|
||||
let index
|
||||
@@ -269,8 +272,8 @@ async function create (input, context) {
|
||||
info: null
|
||||
})
|
||||
|
||||
// Create
|
||||
await creator.create({}, preset)
|
||||
|
||||
removeCreator()
|
||||
|
||||
return importProject({
|
||||
@@ -285,12 +288,9 @@ async function importProject (input, context) {
|
||||
path: input.path,
|
||||
favorite: 0
|
||||
}
|
||||
|
||||
const packageData = folders.readPackage(project.path, context)
|
||||
project.name = packageData.name
|
||||
|
||||
context.db.get('projects').push(project).write()
|
||||
|
||||
return open(project.id, context)
|
||||
}
|
||||
|
||||
@@ -305,6 +305,8 @@ async function open (id, context) {
|
||||
|
||||
currentProject = project
|
||||
cwd.set(project.path, context)
|
||||
// Load plugins
|
||||
plugins.list(project.path, context)
|
||||
|
||||
return project
|
||||
}
|
||||
@@ -313,9 +315,7 @@ async function remove (id, context) {
|
||||
if (currentProject && currentProject.id === id) {
|
||||
currentProject = null
|
||||
}
|
||||
|
||||
context.db.get('projects').remove({ id }).write()
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
@@ -331,7 +331,6 @@ function findOne (id, context) {
|
||||
|
||||
function setFavorite ({ id, favorite }, context) {
|
||||
context.db.get('projects').find({ id }).assign({ favorite }).write()
|
||||
|
||||
return findOne(id, context)
|
||||
}
|
||||
|
||||
|
||||
@@ -20,6 +20,9 @@ function generatePromptError (value) {
|
||||
}
|
||||
|
||||
function getDefaultValue (prompt) {
|
||||
if (typeof prompt.raw.value !== 'undefined') {
|
||||
return prompt.raw.value
|
||||
}
|
||||
const defaultValue = prompt.raw.default
|
||||
if (typeof defaultValue === 'function') {
|
||||
return defaultValue(answers)
|
||||
@@ -113,6 +116,20 @@ function setAnswer (id, value) {
|
||||
obj[fields[l - 1]] = value
|
||||
}
|
||||
|
||||
function getAnswer (id) {
|
||||
const fields = id.split('.')
|
||||
let obj = answers
|
||||
const l = fields.length
|
||||
for (let i = 0; i < l - 1; i++) {
|
||||
const key = fields[i]
|
||||
if (!obj[key]) {
|
||||
return undefined
|
||||
}
|
||||
obj = obj[key]
|
||||
}
|
||||
return obj[fields[l - 1]]
|
||||
}
|
||||
|
||||
function removeAnswer (id) {
|
||||
const fields = id.split('.')
|
||||
let obj = answers
|
||||
@@ -164,7 +181,13 @@ function updatePrompts () {
|
||||
removeAnswer(prompt.id)
|
||||
prompt.valueChanged = false
|
||||
} else if (prompt.visible && !prompt.valueChanged) {
|
||||
let value = getDefaultValue(prompt)
|
||||
let value
|
||||
const answer = getAnswer(prompt.id)
|
||||
if (typeof answer !== 'undefined') {
|
||||
value = answer
|
||||
} else {
|
||||
value = getDefaultValue(prompt)
|
||||
}
|
||||
prompt.value = getDisplayedValue(prompt, value)
|
||||
setAnswer(prompt.id, getValue(prompt, value))
|
||||
}
|
||||
|
||||
@@ -5,12 +5,15 @@ const channels = require('../channels')
|
||||
const cwd = require('./cwd')
|
||||
const folders = require('./folders')
|
||||
const logs = require('./logs')
|
||||
const plugins = require('./plugins')
|
||||
const prompts = require('./prompts')
|
||||
|
||||
const { getCommand } = require('../utils/command')
|
||||
|
||||
const MAX_LOGS = 2000
|
||||
|
||||
const tasks = new Map()
|
||||
let promptMemoId
|
||||
|
||||
function getTasks () {
|
||||
const file = cwd.get()
|
||||
@@ -34,11 +37,15 @@ function list (context) {
|
||||
name => {
|
||||
const id = `${file}:${name}`
|
||||
existing.set(id, true)
|
||||
const command = pkg.scripts[name]
|
||||
const moreData = plugins.getApi().getTask(command)
|
||||
return {
|
||||
id,
|
||||
name,
|
||||
command: pkg.scripts[name],
|
||||
index: list.findIndex(t => t.id === id)
|
||||
command,
|
||||
index: list.findIndex(t => t.id === id),
|
||||
prompts: [],
|
||||
...moreData
|
||||
}
|
||||
}
|
||||
)
|
||||
@@ -84,6 +91,39 @@ function findOne (id, context) {
|
||||
)
|
||||
}
|
||||
|
||||
function getSavedData (id, context) {
|
||||
return context.db.get('tasks').find({
|
||||
id
|
||||
}).value()
|
||||
}
|
||||
|
||||
function updateSavedData (data, context) {
|
||||
if (getSavedData(data.id, context)) {
|
||||
context.db.get('tasks').find({ id: data.id }).assign(data).write()
|
||||
} else {
|
||||
context.db.get('tasks').push(data).write()
|
||||
}
|
||||
}
|
||||
|
||||
function getPrompts (id, context) {
|
||||
const task = findOne(id, context)
|
||||
if (task) {
|
||||
if (promptMemoId !== id) {
|
||||
promptMemoId = id
|
||||
|
||||
prompts.reset()
|
||||
task.prompts.forEach(prompts.add)
|
||||
|
||||
const data = getSavedData(id, context)
|
||||
if (data) {
|
||||
prompts.setAnswers(data.answers)
|
||||
}
|
||||
}
|
||||
|
||||
return prompts.list()
|
||||
}
|
||||
}
|
||||
|
||||
function updateOne (data, context) {
|
||||
const task = findOne(data.id)
|
||||
if (task) {
|
||||
@@ -99,6 +139,21 @@ function run (id, context) {
|
||||
const task = findOne(id, context)
|
||||
if (task && task.status !== 'running') {
|
||||
const args = ['run', task.name]
|
||||
const answers = prompts.getAnswers()
|
||||
|
||||
// Save parameters
|
||||
updateSavedData({
|
||||
id,
|
||||
answers
|
||||
}, context)
|
||||
|
||||
// Plugin api
|
||||
if (task.onRun) {
|
||||
task.onRun({
|
||||
answers,
|
||||
args
|
||||
})
|
||||
}
|
||||
|
||||
const child = execa(getCommand(), args, {
|
||||
cwd: cwd.get(),
|
||||
@@ -200,6 +255,7 @@ function clearLogs (id, context) {
|
||||
module.exports = {
|
||||
list,
|
||||
findOne,
|
||||
getPrompts,
|
||||
run,
|
||||
stop,
|
||||
updateOne,
|
||||
|
||||
@@ -34,6 +34,10 @@ module.exports = {
|
||||
logo: (plugin, args, context) => plugins.getLogo(plugin, context)
|
||||
},
|
||||
|
||||
Task: {
|
||||
prompts: (task, args, context) => tasks.getPrompts(task.id, context)
|
||||
},
|
||||
|
||||
Query: {
|
||||
cwd: () => cwd.get(),
|
||||
consoleLogs: (root, args, context) => logs.list(context),
|
||||
|
||||
@@ -164,11 +164,12 @@ type Progress {
|
||||
type Task implements DescribedEntity {
|
||||
id: ID!
|
||||
status: TaskStatus!
|
||||
name: String
|
||||
command: String!
|
||||
name: String
|
||||
description: String
|
||||
link: String
|
||||
logs: [TaskLog]
|
||||
prompts: [Prompt]
|
||||
}
|
||||
|
||||
enum TaskStatus {
|
||||
|
||||
@@ -10,7 +10,8 @@ const db = new Lowdb(new FileSync(resolve(__dirname, '../../../live/db.json')))
|
||||
// Seed an empty DB
|
||||
db.defaults({
|
||||
projects: [],
|
||||
foldersFavorite: []
|
||||
foldersFavorite: [],
|
||||
tasks: []
|
||||
}).write()
|
||||
|
||||
module.exports = {
|
||||
|
||||
@@ -1,7 +1,12 @@
|
||||
#import "./taskFragment.gql"
|
||||
#import "./promptFragment.gql"
|
||||
|
||||
query task ($id: ID!) {
|
||||
task (id: $id) {
|
||||
...task
|
||||
prompts {
|
||||
...prompt
|
||||
}
|
||||
link
|
||||
}
|
||||
}
|
||||
|
||||
@@ -248,6 +248,8 @@
|
||||
"stop": "Stop task"
|
||||
},
|
||||
"command": "Script command",
|
||||
"parameters": "Parameters",
|
||||
"more-info": "More Info",
|
||||
"output": "Output"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -248,6 +248,8 @@
|
||||
"stop": "Arrêter la tâche"
|
||||
},
|
||||
"command": "Commande de script",
|
||||
"parameters": "Paramètres",
|
||||
"more-info": "Plus d'infos",
|
||||
"output": "Sortie"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -37,9 +37,13 @@ export default function ({
|
||||
}
|
||||
},
|
||||
update: (store, { data: { promptAnswer } }) => {
|
||||
const data = store.readQuery({ query })
|
||||
let variables = this.$apollo.queries[field].options.variables || undefined
|
||||
if (typeof variables === 'function') {
|
||||
variables = variables.call(this)
|
||||
}
|
||||
const data = store.readQuery({ query, variables })
|
||||
data[field].prompts = promptAnswer
|
||||
store.writeQuery({ query, data })
|
||||
store.writeQuery({ query, variables, data })
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
@@ -1,52 +1,97 @@
|
||||
<template>
|
||||
<div class="project-task-details">
|
||||
<div v-if="task" class="actions-bar">
|
||||
<VueButton
|
||||
v-if="task.status !== 'running'"
|
||||
icon-left="play_arrow"
|
||||
class="primary"
|
||||
:label="$t('views.project-task-details.actions.play')"
|
||||
@click="runTask()"
|
||||
/>
|
||||
<VueButton
|
||||
v-else
|
||||
icon-left="stop"
|
||||
class="primary"
|
||||
:label="$t('views.project-task-details.actions.stop')"
|
||||
@click="stopTask()"
|
||||
/>
|
||||
|
||||
<div
|
||||
class="command"
|
||||
v-tooltip="$t('views.project-task-details.command')"
|
||||
>
|
||||
{{ task.command }}
|
||||
<template v-if="task">
|
||||
<div class="header">
|
||||
<div class="name">{{ task.name }}</div>
|
||||
<div class="description">{{ task.description }}</div>
|
||||
</div>
|
||||
|
||||
<div class="vue-ui-spacer"/>
|
||||
</div>
|
||||
<div class="actions-bar">
|
||||
<VueButton
|
||||
v-if="task.status !== 'running'"
|
||||
icon-left="play_arrow"
|
||||
class="primary"
|
||||
:label="$t('views.project-task-details.actions.play')"
|
||||
@click="runTask()"
|
||||
/>
|
||||
<VueButton
|
||||
v-else
|
||||
icon-left="stop"
|
||||
class="primary"
|
||||
:label="$t('views.project-task-details.actions.stop')"
|
||||
@click="stopTask()"
|
||||
/>
|
||||
|
||||
<div class="content">
|
||||
<TerminalView
|
||||
ref="terminal"
|
||||
:key="id"
|
||||
:cols="100"
|
||||
:rows="24"
|
||||
auto-size
|
||||
:options="{
|
||||
scrollback: 1000,
|
||||
disableStdin: true,
|
||||
useFlowControl: true
|
||||
}"
|
||||
:title="$t('views.project-task-details.output')"
|
||||
toolbar
|
||||
@clear="clearLogs()"
|
||||
/>
|
||||
</div>
|
||||
<VueButton
|
||||
v-if="task.prompts.length"
|
||||
icon-left="settings"
|
||||
class="icon-button primary"
|
||||
:disabled="task.status === 'running'"
|
||||
v-tooltip="$t('views.project-task-details.parameters')"
|
||||
@click="showParameters = true"
|
||||
/>
|
||||
|
||||
<div
|
||||
class="command"
|
||||
v-tooltip="$t('views.project-task-details.command')"
|
||||
>
|
||||
{{ task.command }}
|
||||
</div>
|
||||
|
||||
<VueButton
|
||||
v-if="task.link"
|
||||
:href="task.link"
|
||||
target="_blank"
|
||||
icon-left="open_in_new"
|
||||
class="icon-button"
|
||||
v-tooltip="$t('views.project-task-details.more-info')"
|
||||
/>
|
||||
|
||||
<div class="vue-ui-spacer"/>
|
||||
</div>
|
||||
|
||||
<div class="content">
|
||||
<TerminalView
|
||||
ref="terminal"
|
||||
:key="id"
|
||||
:cols="100"
|
||||
:rows="24"
|
||||
auto-size
|
||||
:options="{
|
||||
scrollback: 1000,
|
||||
disableStdin: true,
|
||||
useFlowControl: true
|
||||
}"
|
||||
:title="$t('views.project-task-details.output')"
|
||||
toolbar
|
||||
@clear="clearLogs()"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<VueModal
|
||||
v-if="showParameters"
|
||||
:title="$t('views.project-task-details.parameters')"
|
||||
class="medium"
|
||||
@close="showParameters = false"
|
||||
>
|
||||
<div class="default-body">
|
||||
<PromptsList
|
||||
:prompts="visiblePrompts"
|
||||
@answer="answerPrompt"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div slot="footer" class="actions">
|
||||
<VueButton class="primary" @click="showParameters = false">Close</VueButton>
|
||||
</div>
|
||||
</VueModal>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import Prompts from '../mixins/Prompts'
|
||||
|
||||
import TASK from '../graphql/task.gql'
|
||||
import TASK_LOGS from '../graphql/taskLogs.gql'
|
||||
import TASK_RUN from '../graphql/taskRun.gql'
|
||||
@@ -57,6 +102,13 @@ import TASK_LOG_ADDED from '../graphql/taskLogAdded.gql'
|
||||
export default {
|
||||
name: 'ProjectTaskDetails',
|
||||
|
||||
mixins: [
|
||||
Prompts({
|
||||
field: 'task',
|
||||
query: TASK
|
||||
})
|
||||
],
|
||||
|
||||
props: {
|
||||
id: {
|
||||
type: String,
|
||||
@@ -67,6 +119,7 @@ export default {
|
||||
data () {
|
||||
return {
|
||||
task: null,
|
||||
showParameters: false
|
||||
}
|
||||
},
|
||||
|
||||
@@ -116,6 +169,12 @@ export default {
|
||||
}
|
||||
},
|
||||
|
||||
watch: {
|
||||
id () {
|
||||
this.showParameters = false
|
||||
}
|
||||
},
|
||||
|
||||
methods: {
|
||||
runTask () {
|
||||
this.$apollo.mutate({
|
||||
@@ -158,8 +217,8 @@ export default {
|
||||
.command
|
||||
font-family 'Roboto Mono', monospace
|
||||
font-size 12px
|
||||
background lighten($vue-ui-color-dark, 40%)
|
||||
color $vue-ui-color-light
|
||||
background $vue-ui-color-light-neutral
|
||||
color $vue-ui-color-dark
|
||||
padding 0 16px
|
||||
height 32px
|
||||
h-box()
|
||||
@@ -174,4 +233,16 @@ export default {
|
||||
.terminal-view
|
||||
height 100%
|
||||
border-radius $br
|
||||
|
||||
.header
|
||||
padding $padding-item $padding-item 0
|
||||
h-box()
|
||||
align-items center
|
||||
|
||||
.name
|
||||
font-size 18px
|
||||
|
||||
.description
|
||||
color $color-text-light
|
||||
margin-left $padding-item
|
||||
</style>
|
||||
|
||||
@@ -1,16 +1,19 @@
|
||||
const resolve = require('resolve')
|
||||
|
||||
exports.resolveModule = function resolveModule (request, context) {
|
||||
exports.resolveModule = function (request, context) {
|
||||
let resolvedPath
|
||||
try {
|
||||
resolvedPath = resolve.sync(request, { basedir: context })
|
||||
resolvedPath = require.resolve(request, {
|
||||
paths: [context]
|
||||
})
|
||||
} catch (e) {}
|
||||
return resolvedPath
|
||||
}
|
||||
|
||||
exports.loadModule = function loadModule (request, context) {
|
||||
exports.loadModule = function (request, context, force = false) {
|
||||
const resolvedPath = exports.resolveModule(request, context)
|
||||
if (resolvedPath) {
|
||||
if (force) {
|
||||
delete require.cache[resolvedPath]
|
||||
}
|
||||
return require(resolvedPath)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -45,7 +45,6 @@
|
||||
"minimist": "^1.2.0",
|
||||
"mkdirp": "^0.5.1",
|
||||
"recast": "^0.13.0",
|
||||
"resolve": "^1.5.0",
|
||||
"rimraf": "^2.6.2",
|
||||
"semver": "^5.4.1",
|
||||
"slash": "^1.0.0",
|
||||
|
||||
Reference in New Issue
Block a user