Browse Source
* [Feature][UI Next] Add project workflow relation. * [Feature][UI Next] Add tooltip component.3.0.0/version-upgrade
songjianet
3 years ago
committed by
GitHub
9 changed files with 444 additions and 184 deletions
@ -1,152 +0,0 @@
|
||||
/* |
||||
* 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 { defineComponent, PropType, ref } from 'vue' |
||||
import initChart from '@/components/chart' |
||||
import type { Ref } from 'vue' |
||||
|
||||
const props = { |
||||
height: { |
||||
type: [String, Number] as PropType<string | number>, |
||||
default: 400 |
||||
}, |
||||
width: { |
||||
type: [String, Number] as PropType<string | number>, |
||||
default: '100%' |
||||
}, |
||||
tooltipFormat: { |
||||
type: String as PropType<string>, |
||||
default: '' |
||||
}, |
||||
legendData: { |
||||
type: Array as PropType<Array<string>>, |
||||
default: () => [] |
||||
}, |
||||
seriesData: { |
||||
type: Array as PropType<Array<string>>, |
||||
default: () => [] |
||||
}, |
||||
labelShow: { |
||||
type: Array as PropType<Array<string>>, |
||||
default: () => [] |
||||
}, |
||||
linksData: { |
||||
type: Array as PropType<Array<string>>, |
||||
default: () => [] |
||||
}, |
||||
labelFormat: { |
||||
type: String as PropType<string>, |
||||
default: '' |
||||
} |
||||
} |
||||
|
||||
const GraphChart = defineComponent({ |
||||
name: 'GraphChart', |
||||
props, |
||||
setup(props) { |
||||
const graphChartRef: Ref<HTMLDivElement | null> = ref(null) |
||||
|
||||
const option = { |
||||
tooltip: { |
||||
trigger: 'item', |
||||
triggerOn: 'mousemove', |
||||
backgroundColor: '#2D303A', |
||||
padding: [8, 12], |
||||
formatter: props.tooltipFormat, |
||||
color: '#2D303A', |
||||
textStyle: { |
||||
rich: { |
||||
a: { |
||||
fontSize: 12, |
||||
color: '#2D303A', |
||||
lineHeight: 12, |
||||
align: 'left', |
||||
padding: [4, 4, 4, 4] |
||||
} |
||||
} |
||||
} |
||||
}, |
||||
legend: [ |
||||
{ |
||||
orient: 'horizontal', |
||||
top: 6, |
||||
left: 6, |
||||
data: props.legendData |
||||
} |
||||
], |
||||
series: [ |
||||
{ |
||||
type: 'graph', |
||||
layout: 'force', |
||||
nodeScaleRatio: 1.2, |
||||
draggable: true, |
||||
animation: false, |
||||
data: props.seriesData, |
||||
roam: true, |
||||
symbol: 'roundRect', |
||||
symbolSize: 70, |
||||
categories: props.legendData, |
||||
label: { |
||||
show: props.labelShow, |
||||
position: 'inside', |
||||
formatter: props.labelFormat, |
||||
color: '#222222', |
||||
textStyle: { |
||||
rich: { |
||||
a: { |
||||
fontSize: 12, |
||||
color: '#222222', |
||||
lineHeight: 12, |
||||
align: 'left', |
||||
padding: [4, 4, 4, 4] |
||||
} |
||||
} |
||||
} |
||||
}, |
||||
edgeSymbol: ['circle', 'arrow'], |
||||
edgeSymbolSize: [4, 12], |
||||
force: { |
||||
repulsion: 1000, |
||||
edgeLength: 300 |
||||
}, |
||||
links: props.linksData, |
||||
lineStyle: { |
||||
color: '#999999' |
||||
} |
||||
} |
||||
] |
||||
} |
||||
|
||||
initChart(graphChartRef, option) |
||||
|
||||
return { graphChartRef } |
||||
}, |
||||
render() { |
||||
const { height, width } = this |
||||
return ( |
||||
<div |
||||
ref='graphChartRef' |
||||
style={{ |
||||
height: typeof height === 'number' ? height + 'px' : height, |
||||
width: typeof width === 'number' ? width + 'px' : width |
||||
}} |
||||
/> |
||||
) |
||||
} |
||||
}) |
||||
|
||||
export default GraphChart |
@ -0,0 +1,189 @@
|
||||
/* |
||||
* 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 { defineComponent, PropType, ref } from 'vue' |
||||
import initChart from '@/components/chart' |
||||
import { useI18n } from 'vue-i18n' |
||||
import type { Ref } from 'vue' |
||||
import { format } from 'date-fns' |
||||
|
||||
const props = { |
||||
height: { |
||||
type: [String, Number] as PropType<string | number>, |
||||
default: window.innerHeight - 174 |
||||
}, |
||||
width: { |
||||
type: [String, Number] as PropType<string | number>, |
||||
default: '100%' |
||||
}, |
||||
seriesData: { |
||||
type: Array as PropType<Array<any>>, |
||||
default: () => [] |
||||
}, |
||||
labelShow: { |
||||
type: Boolean as PropType<boolean>, |
||||
default: true |
||||
} |
||||
} |
||||
|
||||
const GraphChart = defineComponent({ |
||||
name: 'GraphChart', |
||||
props, |
||||
setup(props) { |
||||
const graphChartRef: Ref<HTMLDivElement | null> = ref(null) |
||||
const { t } = useI18n() |
||||
|
||||
console.log(props.seriesData) |
||||
|
||||
const legendData = [ |
||||
{ name: t('project.workflow.online') }, |
||||
{ name: t('project.workflow.workflow_offline') }, |
||||
{ name: t('project.workflow.schedule_offline') } |
||||
] |
||||
|
||||
const getCategory = (schedulerStatus: number, workflowStatus: number) => { |
||||
console.log(schedulerStatus, workflowStatus) |
||||
|
||||
switch (true) { |
||||
case workflowStatus === 0: |
||||
return 1 |
||||
case workflowStatus === 1 && schedulerStatus === 0: |
||||
return 2 |
||||
case workflowStatus === 1 && schedulerStatus === 1: |
||||
default: |
||||
return 0 |
||||
} |
||||
} |
||||
|
||||
const option: any = { |
||||
tooltip: { |
||||
confine: true, |
||||
backgroundColor: '#fff', |
||||
formatter: (params: any) => { |
||||
if (!params.data.name) { |
||||
return false |
||||
} |
||||
|
||||
const { |
||||
name, |
||||
scheduleStartTime, |
||||
scheduleEndTime, |
||||
crontab, |
||||
workFlowPublishStatus, |
||||
schedulePublishStatus |
||||
} = params.data |
||||
|
||||
return ` |
||||
${t('project.workflow.workflow_name')}:${name}<br/> |
||||
${t( |
||||
'project.workflow.schedule_start_time' |
||||
)}:${scheduleStartTime}<br/> |
||||
${t('project.workflow.schedule_end_time')}:${scheduleEndTime}<br/> |
||||
${t('project.workflow.crontab_expression')}:${ |
||||
crontab ? crontab : ' - ' |
||||
}<br/> |
||||
${t( |
||||
'project.workflow.workflow_publish_status' |
||||
)}:${workFlowPublishStatus}<br/> |
||||
${t( |
||||
'project.workflow.schedule_publish_status' |
||||
)}:${schedulePublishStatus}<br/> |
||||
` |
||||
} |
||||
}, |
||||
legend: [ |
||||
{ |
||||
data: legendData?.map((item) => item.name) |
||||
} |
||||
], |
||||
series: [ |
||||
{ |
||||
type: 'graph', |
||||
layout: 'force', |
||||
draggable: true, |
||||
force: { |
||||
repulsion: 300, |
||||
edgeLength: 100 |
||||
}, |
||||
symbol: 'roundRect', |
||||
symbolSize: 70, |
||||
roam: false, |
||||
label: { |
||||
show: props.labelShow, |
||||
formatter: (val: any) => { |
||||
let newStr = '' |
||||
const str = val.data.name.split('') |
||||
|
||||
for (let i = 0, s; (s = str[i++]); ) { |
||||
newStr += s |
||||
if (!(i % 10)) newStr += '\n' |
||||
} |
||||
|
||||
return newStr.length > 60 ? newStr.slice(0, 60) + '...' : newStr |
||||
} |
||||
}, |
||||
data: props.seriesData.map((item) => { |
||||
return { |
||||
name: item.name, |
||||
id: item.id, |
||||
category: getCategory( |
||||
Number(item.schedulePublishStatus), |
||||
Number(item.workFlowPublishStatus) |
||||
), |
||||
workFlowPublishStatus: format( |
||||
new Date(item.workFlowPublishStatus), |
||||
'yyyy-MM-dd HH:mm:ss' |
||||
), |
||||
schedulePublishStatus: format( |
||||
new Date(item.schedulePublishStatus), |
||||
'yyyy-MM-dd HH:mm:ss' |
||||
), |
||||
crontab: item.crontab, |
||||
scheduleStartTime: |
||||
Number(item.scheduleStartTime) === 0 |
||||
? t('project.workflow.offline') |
||||
: t('project.workflow.online'), |
||||
scheduleEndTime: |
||||
Number(item.scheduleEndTime) === 0 |
||||
? t('project.workflow.offline') |
||||
: t('project.workflow.online') |
||||
} |
||||
}), |
||||
categories: legendData |
||||
} |
||||
] |
||||
} |
||||
|
||||
initChart(graphChartRef, option) |
||||
|
||||
return { graphChartRef } |
||||
}, |
||||
render() { |
||||
const { height, width } = this |
||||
return ( |
||||
<div |
||||
ref='graphChartRef' |
||||
style={{ |
||||
height: typeof height === 'number' ? height + 'px' : height, |
||||
width: typeof width === 'number' ? width + 'px' : width |
||||
}} |
||||
/> |
||||
) |
||||
} |
||||
}) |
||||
|
||||
export default GraphChart |
@ -0,0 +1,97 @@
|
||||
/* |
||||
* 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 { reactive, ref } from 'vue' |
||||
import { useAsyncState } from '@vueuse/core' |
||||
import { |
||||
queryWorkFlowList, |
||||
queryLineageByWorkFlowCode, |
||||
queryLineageByWorkFlowName |
||||
} from '@/service/modules/lineages' |
||||
import type { |
||||
WorkflowRes, |
||||
WorkFlowListRes |
||||
} from '@/service/modules/lineages/types' |
||||
|
||||
export function useRelation() { |
||||
const variables = reactive({ |
||||
workflowOptions: [], |
||||
workflow: ref(null), |
||||
seriesData: [], |
||||
labelShow: ref(true) |
||||
}) |
||||
|
||||
const formatWorkflow = (obj: Array<WorkFlowListRes>) => { |
||||
variables.seriesData = [] |
||||
|
||||
variables.seriesData = obj.map((item) => { |
||||
console.log(item) |
||||
return { |
||||
name: item.workFlowName, |
||||
id: item.workFlowCode, |
||||
...item |
||||
} |
||||
}) as any |
||||
} |
||||
|
||||
const getWorkflowName = (projectCode: number) => { |
||||
const { state } = useAsyncState( |
||||
queryLineageByWorkFlowName({ projectCode }).then( |
||||
(res: Array<WorkFlowListRes>) => { |
||||
variables.workflowOptions = res.map((item) => { |
||||
return { |
||||
label: item.workFlowName, |
||||
value: item.workFlowCode |
||||
} |
||||
}) as any |
||||
} |
||||
), |
||||
{} |
||||
) |
||||
|
||||
return state |
||||
} |
||||
|
||||
const getOneWorkflow = (workflowCode: number, projectCode: number) => { |
||||
const { state } = useAsyncState( |
||||
queryLineageByWorkFlowCode( |
||||
{ workFlowCode: workflowCode }, |
||||
{ projectCode } |
||||
).then((res: WorkflowRes) => { |
||||
formatWorkflow(res.workFlowList) |
||||
}), |
||||
{} |
||||
) |
||||
|
||||
return state |
||||
} |
||||
|
||||
const getWorkflowList = (projectCode: number) => { |
||||
const { state } = useAsyncState( |
||||
queryWorkFlowList({ |
||||
projectCode |
||||
}).then((res: WorkflowRes) => { |
||||
formatWorkflow(res.workFlowList) |
||||
}), |
||||
{} |
||||
) |
||||
|
||||
return state |
||||
} |
||||
|
||||
return { variables, getWorkflowName, getOneWorkflow, getWorkflowList } |
||||
} |
Loading…
Reference in new issue