[Feature][UI Next] Add workflow instance startup params

This commit is contained in:
Devosend 2022-02-23 15:49:50 +08:00 committed by GitHub
parent 60ddede6a6
commit 22d63b80fa
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 316 additions and 5 deletions

View File

@ -472,7 +472,9 @@ const project = {
delay_execution: 'Delay execution',
forced_success: 'Forced success',
serial_wait: 'Serial wait',
executing: 'Executing'
executing: 'Executing',
startup_type: 'Startup Type',
complement_range: 'Complement Range'
},
task: {
task_name: 'Task Name',

View File

@ -470,7 +470,9 @@ const project = {
delay_execution: '延时执行',
forced_success: '强制成功',
serial_wait: '串行等待',
executing: '正在执行'
executing: '正在执行',
startup_type: '启动类型',
complement_range: '补数范围'
},
task: {
task_name: '任务名称',

View File

@ -331,3 +331,22 @@ export function uuid(prefix: string) {
: prefix + id
: id
}
export const warningTypeList = [
{
id: 'NONE',
code: 'project.workflow.none_send'
},
{
id: 'SUCCESS',
code: 'project.workflow.success_send'
},
{
id: 'FAILURE',
code: 'project.workflow.failure_send'
},
{
id: 'ALL',
code: 'project.workflow.all_send'
}
]

View File

@ -0,0 +1,173 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import _ from 'lodash'
import { defineComponent, onMounted, PropType, ref, computed } from 'vue'
import { useI18n } from 'vue-i18n'
import { listAlertGroupById } from '@/service/modules/alert-group'
import { queryAllWorkerGroups } from '@/service/modules/worker-groups'
import { runningType, warningTypeList } from '@/utils/common'
import { IStartupParam } from './types'
import styles from './startup.module.scss'
const props = {
startupParam: {
type: Object as PropType<IStartupParam>,
require: true
}
}
export default defineComponent({
name: 'dag-start-param',
props,
setup(props) {
const { t } = useI18n()
const alertGroupListRef = ref<any>([])
const workerGroupListRef = ref<any>([])
const commandParam = JSON.parse(props.startupParam?.commandParam || '{}')
const getAlertGroupList = () => {
listAlertGroupById().then((res: any) => {
alertGroupListRef.value = res.map((item: any) => ({
label: item.groupName,
value: item.id
}))
})
}
const getWorkerGroupList = () => {
queryAllWorkerGroups().then((res: any) => {
workerGroupListRef.value = res
})
}
const runType = computed(
() =>
(
_.filter(
runningType(t),
(v) => v.code === props.startupParam?.commandType
)[0] || {}
).desc
)
const warningType = computed(() => {
const id = props.startupParam?.warningType as string
const o = _.filter(warningTypeList, (v) => v.id === id)
if (o && o.length) {
return t(o[0].code)
}
return '-'
})
const alertGroupName = computed(() => {
const id = props.startupParam?.warningGroupId
if (!alertGroupListRef.value || !alertGroupListRef.value.length) {
return '-'
}
const o = _.filter(alertGroupListRef.value, (v) => v.id === id)
if (o && o.length) {
return o[0].code
}
return '-'
})
onMounted(() => {
getAlertGroupList()
getWorkerGroupList()
})
return {
t,
alertGroupListRef,
workerGroupListRef,
commandParam,
runType,
warningType,
alertGroupName
}
},
render() {
const { t } = this
return (
<div class={styles.box}>
<ul class={styles['box-bd']}>
<li>
<span class={styles.tab}>
{t('project.workflow.startup_type')}:
</span>
<span class={styles.content}>{this.runType}</span>
</li>
<li>
<span class={styles.tab}>
{t('project.workflow.complement_range')}:
</span>
{this.commandParam && this.commandParam.complementStartDate ? (
<span class={styles.content}>
{this.commandParam.complementStartDate}-
{this.commandParam.complementEndDate}
</span>
) : (
'-'
)}
</li>
<li>
<span class={styles.tab}>
{t('project.workflow.failure_strategy')}:
</span>
<span class={styles.content}>
{this.startupParam?.failureStrategy === 'END'
? t('project.workflow.end')
: t('project.workflow.continue')}
</span>
</li>
<li>
<span class={styles.tab}>
{t('project.workflow.workflow_priority')}:
</span>
<span class={styles.content}>
{this.startupParam?.processInstancePriority}
</span>
</li>
<li>
<span class={styles.tab}>
{t('project.workflow.worker_group')}:
</span>
<span class={styles.content}>
{this.workerGroupListRef.length
? this.startupParam?.workerGroup
: '-'}
</span>
</li>
<li>
<span class={styles.tab}>
{t('project.workflow.notification_strategy')}:
</span>
<span class={styles.content}>{this.warningType}</span>
</li>
<li>
<span class={styles.tab}>{t('project.workflow.alarm_group')}:</span>
<span class={styles.content}>{this.alertGroupName}</span>
</li>
</ul>
</div>
)
}
})

View File

@ -18,7 +18,7 @@
import { defineComponent, ref, inject, PropType, Ref } from 'vue'
import { useI18n } from 'vue-i18n'
import Styles from './dag.module.scss'
import { NTooltip, NIcon, NButton, NSelect } from 'naive-ui'
import { NTooltip, NIcon, NButton, NSelect, NPopover, NText } from 'naive-ui'
import {
SearchOutlined,
DownloadOutlined,
@ -27,14 +27,17 @@ import {
InfoCircleOutlined,
FormatPainterOutlined,
CopyOutlined,
DeleteOutlined
DeleteOutlined,
RightCircleOutlined,
FundViewOutlined
} from '@vicons/antd'
import { useNodeSearch, useTextCopy } from './dag-hooks'
import { DataUri } from '@antv/x6'
import { useFullscreen } from '@vueuse/core'
import { useRouter } from 'vue-router'
import { useRoute, useRouter } from 'vue-router'
import { useThemeStore } from '@/store/theme/theme'
import type { Graph } from '@antv/x6'
import StartParam from './dag-startup-param'
const props = {
layoutToggle: {
@ -42,6 +45,10 @@ const props = {
default: () => {}
},
// If this prop is passed, it means from definition detail
instance: {
type: Object as PropType<any>,
default: null
},
definition: {
// The same as the structure responsed by the queryProcessDefinitionByCode api
type: Object as PropType<any>,
@ -56,10 +63,13 @@ export default defineComponent({
setup(props, context) {
const { t } = useI18n()
const startupPopover = ref(false)
const themeStore = useThemeStore()
const graph = inject<Ref<Graph | undefined>>('graph', ref())
const router = useRouter()
const route = useRoute()
/**
* Node search and navigate
@ -142,6 +152,10 @@ export default defineComponent({
}
}
// const handleUpdateShow = () => {
// startupPopover.value
// }
return () => (
<div
class={[
@ -166,6 +180,50 @@ export default defineComponent({
</NIcon>
</NButton>
)}
{route.name === 'workflow-instance-detail' && (
<>
<NButton
quaternary
circle
onClick={() => copy(props.definition?.processDefinition?.name)}
class={Styles['copy-btn']}
>
<NIcon>
<FundViewOutlined />
</NIcon>
</NButton>
<NPopover
show={startupPopover.value}
placement='bottom'
trigger='manual'
>
{{
trigger: () => (
<NButton
quaternary
circle
onClick={() =>
(startupPopover.value = !startupPopover.value)
}
class={Styles['copy-btn']}
>
<NIcon>
<RightCircleOutlined />
</NIcon>
</NButton>
),
header: () => (
<NText strong depth={1}>
{t('project.workflow.startup_parameter')}
</NText>
),
default: () => (
<StartParam startupParam={props.instance.value} />
)
}}
</NPopover>
</>
)}
</div>
<div class={Styles['toolbar-right-part']}>
{/* Search node */}

View File

@ -41,6 +41,10 @@ import './x6-style.scss'
const props = {
// If this prop is passed, it means from definition detail
instance: {
type: Object as PropType<any>,
default: undefined
},
definition: {
type: Object as PropType<WorkflowDefinition>,
default: undefined
@ -160,6 +164,7 @@ export default defineComponent({
>
<DagToolbar
layoutToggle={layoutToggle}
instance={props.instance}
definition={props.definition}
onVersionToggle={versionToggle}
onSaveModelToggle={saveModelToggle}

View File

@ -0,0 +1,39 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
.box {
padding: 5px 10px 10px;
.box-bd {
list-style: none;
padding-left: 0;
margin-top: 5px;
margin-bottom: 5px;
.tab {
font-size: 12px;
font-weight: bold;
margin-right: 10px;
}
.content {
font-size: 12px;
&:hover {
color: #18a058;
}
}
}
}

View File

@ -133,3 +133,13 @@ export interface Location {
x: number
y: number
}
export interface IStartupParam {
commandType: string
commandParam: string
failureStrategy: string
processInstancePriority: string
workerGroup: string
warningType: string
warningGroupId: number
}

View File

@ -33,9 +33,11 @@ export default defineComponent({
const id = Number(route.params.id)
const definition = ref<WorkflowDefinition>()
const instance = ref<any>()
const refresh = () => {
queryProcessInstanceById(id, projectCode).then((res: any) => {
instance.value = res
if (res.dagData) {
definition.value = res.dagData
}
@ -57,6 +59,7 @@ export default defineComponent({
]}
>
<Dag
instance={instance}
definition={definition.value}
onRefresh={refresh}
projectCode={projectCode}