mirror of
https://github.com/jumpserver/lina.git
synced 2026-01-29 21:28:52 +00:00
perf: 重新设计菜单和交互流程
This commit is contained in:
@@ -691,8 +691,10 @@
|
||||
"privilegeOnly": "仅选择特权账号",
|
||||
"privilegeFirst": "优先选择特权账号",
|
||||
"skip": "忽略当前资产",
|
||||
"QuickJob": "快捷作业",
|
||||
"instantAdhoc": "即时命令",
|
||||
"myAdhoc": "我的命令",
|
||||
"AdhocManage": "命令管理",
|
||||
"PlaybookManage": "Playbook管理",
|
||||
"history": "历史记录",
|
||||
"createAdhoc": "创建命令",
|
||||
"AdhocDetail": "命令详情",
|
||||
@@ -840,6 +842,8 @@
|
||||
"SessionList": "会话记录",
|
||||
"BatchCommand": "批量命令",
|
||||
"BatchScript": "批量脚本",
|
||||
"Executions": "执行历史",
|
||||
"ScriptManage": "脚本管理",
|
||||
"TicketsTodo": "待办工单",
|
||||
"TicketsDone": "已办工单",
|
||||
"TicketsNew": "提交工单",
|
||||
@@ -896,7 +900,7 @@
|
||||
"GatewayUpdate": "更新网关",
|
||||
"TaskCenter": "任务中心",
|
||||
"JobCenter": "作业中心",
|
||||
"JobList": "作业列表",
|
||||
"JobList": "作业管理",
|
||||
"JobCreate": "创建作业",
|
||||
"JobUpdate": "更新作业",
|
||||
"JobDetail": "作业详情",
|
||||
|
||||
@@ -89,6 +89,17 @@ export default {
|
||||
permissions: []
|
||||
},
|
||||
children: [
|
||||
{
|
||||
path: 'quick-job',
|
||||
name: 'QuickJob',
|
||||
hidden: true,
|
||||
component: () => import('@/views/ops/Job/QuickJob'),
|
||||
meta: {
|
||||
title: i18n.t('ops.QuickJob'),
|
||||
permissions: [],
|
||||
activeMenu: '/workbench/ops/job'
|
||||
}
|
||||
},
|
||||
{
|
||||
path: 'job',
|
||||
name: 'Job',
|
||||
@@ -144,17 +155,49 @@ export default {
|
||||
]
|
||||
},
|
||||
{
|
||||
path: 'adhoc',
|
||||
name: 'Adhoc',
|
||||
component: () => import('@/views/ops/Adhoc'),
|
||||
path: 'scripts',
|
||||
name: 'ScriptManage',
|
||||
component: () => import('@/views/ops/ScriptManage'),
|
||||
meta: {
|
||||
title: i18n.t('route.BatchCommand'),
|
||||
title: i18n.t('route.ScriptManage'),
|
||||
permissions: []
|
||||
}
|
||||
},
|
||||
{
|
||||
path: 'command/:id',
|
||||
component: () => import('@/views/ops/Adhoc/my/AdhocDetail'),
|
||||
path: 'executions',
|
||||
name: 'Executions',
|
||||
component: () => import('@/views/ops/Executions'),
|
||||
meta: {
|
||||
title: i18n.t('route.Executions'),
|
||||
permissions: []
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
path: 'adhoc/:id/update',
|
||||
name: 'AdhocUpdate',
|
||||
component: () => import('@/views/ops/ScriptManage/Adhoc/AdhocUpdateCreate'),
|
||||
hidden: true,
|
||||
meta: {
|
||||
title: i18n.t('route.updateAdhoc'),
|
||||
permissions: [],
|
||||
activeMenu: '/workbench/ops/adhoc'
|
||||
}
|
||||
},
|
||||
{
|
||||
path: 'adhoc/create',
|
||||
name: 'AdhocCreate',
|
||||
hidden: true,
|
||||
component: () => import('@/views/ops/ScriptManage/Adhoc/AdhocUpdateCreate'),
|
||||
meta: {
|
||||
title: i18n.t('ops.createAdhoc'),
|
||||
permissions: [],
|
||||
activeMenu: '/workbench/ops/adhoc'
|
||||
}
|
||||
},
|
||||
{
|
||||
path: 'adhoc/:id',
|
||||
component: () => import('@/views/ops/ScriptManage/Adhoc/AdhocDetail'),
|
||||
name: 'AdhocDetail',
|
||||
hidden: true,
|
||||
meta: {
|
||||
@@ -164,41 +207,10 @@ export default {
|
||||
}
|
||||
},
|
||||
{
|
||||
path: 'command/:id/update',
|
||||
name: 'AdhocUpdate',
|
||||
component: () => import('@/views/ops/Adhoc/my/AdhocUpdateCreate'),
|
||||
hidden: true,
|
||||
meta: {
|
||||
title: i18n.t('route.updateAdhoc'),
|
||||
permissions: [],
|
||||
activeMenu: '/workbench/ops/adhoc'
|
||||
}
|
||||
},
|
||||
{
|
||||
path: 'command/create',
|
||||
name: 'AdhocCreate',
|
||||
hidden: true,
|
||||
component: () => import('@/views/ops/Adhoc/my/AdhocUpdateCreate'),
|
||||
meta: {
|
||||
title: i18n.t('ops.createAdhoc'),
|
||||
permissions: [],
|
||||
activeMenu: '/workbench/ops/adhoc'
|
||||
}
|
||||
},
|
||||
{
|
||||
path: 'playbook',
|
||||
name: 'Playbook',
|
||||
component: () => import('@/views/ops/Playbook'),
|
||||
meta: {
|
||||
title: i18n.t('route.BatchScript'),
|
||||
permissions: []
|
||||
}
|
||||
},
|
||||
{
|
||||
path: 'flow/create',
|
||||
path: 'playbook/create',
|
||||
name: 'PlaybookCreate',
|
||||
hidden: true,
|
||||
component: () => import('@/views/ops/Playbook/PlaybookUpdateCreate'),
|
||||
component: () => import('@/views/ops/ScriptManage/Playbook/PlaybookUpdateCreate'),
|
||||
meta: {
|
||||
title: i18n.t('route.PlaybookCreate'),
|
||||
permissions: [],
|
||||
|
||||
@@ -1,51 +0,0 @@
|
||||
<template>
|
||||
<TabPage
|
||||
:submenu="submenu"
|
||||
:active-menu.sync="activeMenu"
|
||||
>
|
||||
<component :is="activeMenu" :query="{type:'adhoc'}" />
|
||||
</TabPage>
|
||||
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { TabPage } from '@/layout/components'
|
||||
import MyAdhoc from '@/views/ops/Adhoc/MyAdhoc'
|
||||
import InstantAdhoc from '@/views/ops/Adhoc/InstantAdhoc'
|
||||
import JobHistory from '@/views/ops/Job/JobDetail/JobHistory'
|
||||
|
||||
export default {
|
||||
name: 'Index',
|
||||
components: {
|
||||
TabPage,
|
||||
MyAdhoc,
|
||||
InstantAdhoc,
|
||||
JobHistory
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
activeMenu: 'MyAdhoc',
|
||||
submenu: [
|
||||
{
|
||||
title: this.$t('ops.instantAdhoc'),
|
||||
name: 'InstantAdhoc'
|
||||
},
|
||||
{
|
||||
title: this.$t('ops.myAdhoc'),
|
||||
name: 'MyAdhoc'
|
||||
},
|
||||
{
|
||||
title: this.$t('ops.history'),
|
||||
name: 'JobHistory'
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
114
src/views/ops/Executions/index.vue
Normal file
114
src/views/ops/Executions/index.vue
Normal file
@@ -0,0 +1,114 @@
|
||||
<template>
|
||||
<div>
|
||||
<GenericListPage :table-config="tableConfig" :header-actions="headerActions" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { ActionsFormatter } from '@/components/TableFormatters'
|
||||
import { GenericListPage } from '@/layout/components'
|
||||
|
||||
export default {
|
||||
components: {
|
||||
GenericListPage
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
uploadDialogVisible: false,
|
||||
tableConfig: {
|
||||
url: '/api/v1/ops/job-executions/',
|
||||
columns: [
|
||||
'id', 'job_type', 'is_finished', 'is_success', 'time_cost', 'date_created', 'actions'
|
||||
],
|
||||
columnsMeta: {
|
||||
name: {
|
||||
formatterArgs: {
|
||||
can: true
|
||||
}
|
||||
},
|
||||
is_finished: {
|
||||
label: this.$t('ops.isFinished'),
|
||||
width: '96px',
|
||||
formatter: (row) => {
|
||||
if (row.is_finished) {
|
||||
return <i Class='fa fa-check text-primary'/>
|
||||
}
|
||||
return <i Class='fa fa-times text-danger'/>
|
||||
},
|
||||
formatterArgs: {
|
||||
width: '14px'
|
||||
}
|
||||
},
|
||||
is_success: {
|
||||
label: this.$t('ops.isSuccess'),
|
||||
width: '96px',
|
||||
formatter: (row) => {
|
||||
if (!row.is_finished) {
|
||||
return <i Class='fa fa fa-spinner fa-spin'/>
|
||||
}
|
||||
if (row.is_success) {
|
||||
return <i Class='fa fa-check text-primary'/>
|
||||
}
|
||||
return <i Class='fa fa-times text-danger'/>
|
||||
},
|
||||
formatterArgs: {
|
||||
width: '14px'
|
||||
}
|
||||
},
|
||||
time_cost: {
|
||||
label: this.$t('ops.time'),
|
||||
width: '100px',
|
||||
formatter: function(row) {
|
||||
if (row.time_cost) {
|
||||
return row.time_cost.toFixed(2) + 's'
|
||||
}
|
||||
return '-'
|
||||
}
|
||||
},
|
||||
actions: {
|
||||
formatter: ActionsFormatter,
|
||||
formatterArgs: {
|
||||
hasUpdate: false,
|
||||
hasDelete: false,
|
||||
hasClone: false,
|
||||
extraActions: [
|
||||
{
|
||||
title: this.$t('详情'),
|
||||
name: 'detail',
|
||||
can: true,
|
||||
callback: ({ row }) => {
|
||||
// this.$router.push({name: 'JobCreate', query: {type: 'adhoc', id: row.id}})
|
||||
}
|
||||
},
|
||||
{
|
||||
title: this.$t('日志'),
|
||||
name: 'detail',
|
||||
can: true,
|
||||
callback: ({ row }) => {
|
||||
// this.$router.push({name: 'JobCreate', query: {type: 'adhoc', id: row.id}})
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
headerActions: {
|
||||
hasCreate: false,
|
||||
canCreate: false,
|
||||
hasRefresh: true,
|
||||
hasExport: false,
|
||||
hasImport: false,
|
||||
hasMoreActions: false,
|
||||
onCreate: () => {
|
||||
this.uploadDialogVisible = true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
|
||||
</style>
|
||||
@@ -27,8 +27,8 @@ export default {
|
||||
[this.$t('common.Basic'), ['name', 'type', 'instant', 'comment']],
|
||||
[this.$t('common.Task'), ['module', 'args', 'playbook', 'chdir', 'timeout']],
|
||||
[this.$t('ops.Asset'), ['assets', 'runas', 'runas_policy']],
|
||||
[this.$t('ops.Plan'), ['runAfterSave', 'is_periodic', 'crontab']],
|
||||
[this.$t('ops.Parameter'), ['use_parameter_define', 'parameters_define']]
|
||||
[this.$t('ops.Parameter'), ['use_parameter_define', 'parameters_define']],
|
||||
[this.$t('ops.Plan'), ['runAfterSave', 'is_periodic', 'crontab']]
|
||||
],
|
||||
initial: {
|
||||
type: 'adhoc',
|
||||
@@ -121,7 +121,6 @@ export default {
|
||||
}
|
||||
},
|
||||
use_parameter_define: {
|
||||
label: this.$t('ops.UseParameterDefine'),
|
||||
type: 'switch',
|
||||
hidden: () => {
|
||||
return this.instantTask
|
||||
@@ -168,8 +167,7 @@ export default {
|
||||
this.ready = true
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
}
|
||||
methods: {}
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
@@ -1,45 +1,51 @@
|
||||
<template>
|
||||
<el-collapse-transition>
|
||||
<div style="display: flex;justify-items: center; flex-wrap: nowrap;justify-content:space-between;">
|
||||
<div
|
||||
v-show="iShowTree"
|
||||
:style="{width: iShowTree?'20%': 0}"
|
||||
class="transition-box tree-box"
|
||||
>
|
||||
<AutoDataZTree
|
||||
ref="AutoDataZTree"
|
||||
:key="DataZTree"
|
||||
:setting="treeSetting"
|
||||
class="auto-data-ztree"
|
||||
/>
|
||||
</div>
|
||||
<div :style="iShowTree?('display: flex;width: 80%;'):('display: flex;width:100%;')">
|
||||
<div class="mini">
|
||||
<div style="display:block" class="mini-button" @click="iShowTree=!iShowTree">
|
||||
<i v-show="iShowTree" class="fa fa-angle-left fa-x" /><i v-show="!iShowTree" class="fa fa-angle-right fa-x" />
|
||||
</div>
|
||||
</div>
|
||||
<IBox class="transition-box" style="width: calc(100% - 17px);">
|
||||
<el-form label-width="160px">
|
||||
<el-form-item label="runas">
|
||||
<el-input v-model="runas" />
|
||||
</el-form-item>
|
||||
<el-form-item label="runas policy">
|
||||
<el-select v-model="runasPolicy">
|
||||
<el-option v-for="(item,index) of runasPolicyOptions" :key="index" :value="item">
|
||||
{{ item.label }}
|
||||
</el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
|
||||
<CodeEditor style="margin-bottom: 20px" :toolbar="toolbar" />
|
||||
<Term ref="xterm" />
|
||||
<div style="display: flex;margin-top:10px;justify-content: space-between" />
|
||||
</IBox>
|
||||
<Page>
|
||||
<el-collapse-transition>
|
||||
<div style="display: flex;justify-items: center; flex-wrap: nowrap;justify-content:space-between;">
|
||||
<div
|
||||
v-show="iShowTree"
|
||||
:style="{width: iShowTree?'20%': 0}"
|
||||
class="transition-box tree-box"
|
||||
>
|
||||
<AutoDataZTree
|
||||
ref="AutoDataZTree"
|
||||
:key="DataZTree"
|
||||
:setting="treeSetting"
|
||||
class="auto-data-ztree"
|
||||
/>
|
||||
</div>
|
||||
<div :style="iShowTree?('display: flex;width: 80%;'):('display: flex;width:100%;')">
|
||||
<div class="mini">
|
||||
<div style="display:block" class="mini-button" @click="iShowTree=!iShowTree">
|
||||
<i v-show="iShowTree" class="fa fa-angle-left fa-x" /><i
|
||||
v-show="!iShowTree"
|
||||
class="fa fa-angle-right fa-x"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<IBox class="transition-box" style="width: calc(100% - 17px);">
|
||||
<el-form label-width="160px">
|
||||
<el-form-item label="runas">
|
||||
<el-input v-model="runas" />
|
||||
</el-form-item>
|
||||
<el-form-item label="runas policy">
|
||||
<el-select v-model="runasPolicy">
|
||||
<el-option v-for="(item,index) of runasPolicyOptions" :key="index" :value="item">
|
||||
{{ item.label }}
|
||||
</el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
|
||||
<CodeEditor style="margin-bottom: 20px" :toolbar="toolbar" />
|
||||
<Term ref="xterm" />
|
||||
<div style="display: flex;margin-top:10px;justify-content: space-between" />
|
||||
</IBox>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</el-collapse-transition>
|
||||
</el-collapse-transition>
|
||||
</Page>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
@@ -47,10 +53,12 @@ import AutoDataZTree from '@/components/AutoDataZTree'
|
||||
import Term from '@/components/Term'
|
||||
import IBox from '@/components/IBox'
|
||||
import CodeEditor from '@/components/FormFields/CodeEditor'
|
||||
import Page from '@/layout/components/Page'
|
||||
|
||||
export default {
|
||||
name: 'CommandExecution',
|
||||
components: {
|
||||
Page,
|
||||
Term,
|
||||
AutoDataZTree,
|
||||
IBox,
|
||||
@@ -147,17 +155,6 @@ export default {
|
||||
},
|
||||
getSelectedAssetsNode() {
|
||||
const nodes = this.$refs.AutoDataZTree.$refs.dataztree.$refs.ztree.getCheckedNodes()
|
||||
// const assetsNodeId = []
|
||||
// const assetsNode = []
|
||||
// nodes.forEach(function (node) {
|
||||
// if (node.meta.type === 'asset' && !node.isHidden) {
|
||||
// const protocolsStr = node.meta.data.protocols + ''
|
||||
// if (assetsNodeId.indexOf(node.id) === -1 && protocolsStr.indexOf('ssh') > -1) {
|
||||
// assetsNodeId.push(node.id)
|
||||
// assetsNode.push(node)
|
||||
// }
|
||||
// }
|
||||
// })
|
||||
return nodes
|
||||
},
|
||||
enableWS() {
|
||||
@@ -204,12 +201,7 @@ export default {
|
||||
this.$axios.post(
|
||||
url, data
|
||||
).then(res => {
|
||||
console.log(res)
|
||||
setTimeout(() => {
|
||||
this.$axios.get(`/api/v1/ops/jobs/${res.id}/`).then((data) => {
|
||||
this.writeExecutionOutput(data.task_id)
|
||||
}, 100)
|
||||
})
|
||||
this.writeExecutionOutput(res.task_id)
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -108,18 +108,30 @@ export default {
|
||||
hasRefresh: true,
|
||||
hasExport: false,
|
||||
hasImport: false,
|
||||
hasMoreActions: false
|
||||
hasMoreActions: false,
|
||||
extraActions: [
|
||||
{
|
||||
name: this.$t('ops.QuickJob'),
|
||||
title: this.$t('ops.QuickJob'),
|
||||
has: () => {
|
||||
return true
|
||||
},
|
||||
callback: () => {
|
||||
this.$router.push({ name: 'QuickJob' })
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
runJob(row, parameters) {
|
||||
console.log(row)
|
||||
this.$axios.post('/api/v1/ops/job-executions/', {
|
||||
job: row.id,
|
||||
parameters: parameters
|
||||
}).then(() => {
|
||||
this.$message.success(this.$tc('ops.TaskDispatch'))
|
||||
this.$router.push({ name: 'Executions' })
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,12 +0,0 @@
|
||||
<template>
|
||||
<div />
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
@@ -8,7 +8,7 @@
|
||||
|
||||
<script>
|
||||
import { GenericDetailPage } from '@/layout/components'
|
||||
import AdhocDetail from '@/views/ops/Adhoc/my/AdhocDetail/AdhocDetail'
|
||||
import AdhocDetail from '@/views/ops/ScriptManage/Adhoc/AdhocDetail/AdhocDetail'
|
||||
|
||||
export default {
|
||||
components: {
|
||||
@@ -8,7 +8,7 @@
|
||||
<script>
|
||||
import GenericListTable from '@/layout/components/GenericListTable'
|
||||
import { ActionsFormatter } from '@/components/TableFormatters'
|
||||
import UploadDialog from '@/views/ops/Playbook/UploadDialog'
|
||||
import UploadDialog from '@/views/ops/ScriptManage/Playbook/UploadDialog'
|
||||
|
||||
export default {
|
||||
components: {
|
||||
@@ -10,27 +10,27 @@
|
||||
|
||||
<script>
|
||||
import { TabPage } from '@/layout/components'
|
||||
import PlaybookList from '@/views/ops/Playbook/PlaybookList'
|
||||
import History from '@/views/ops/Playbook/HIstory'
|
||||
import Adhoc from '@/views/ops/ScriptManage/Adhoc'
|
||||
import Playbook from '@/views/ops/ScriptManage/Playbook'
|
||||
|
||||
export default {
|
||||
name: 'Index',
|
||||
components: {
|
||||
TabPage,
|
||||
PlaybookList,
|
||||
History
|
||||
Adhoc,
|
||||
Playbook
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
activeMenu: 'PlaybookList',
|
||||
activeMenu: 'Adhoc',
|
||||
submenu: [
|
||||
{
|
||||
title: 'Playbook',
|
||||
name: 'PlaybookList'
|
||||
title: this.$t('ops.AdhocManage'),
|
||||
name: 'Adhoc'
|
||||
},
|
||||
{
|
||||
title: this.$t('ops.history'),
|
||||
name: 'History'
|
||||
title: this.$t('ops.PlaybookManage'),
|
||||
name: 'Playbook'
|
||||
}
|
||||
]
|
||||
}
|
||||
Reference in New Issue
Block a user