mirror of
https://github.com/PanJiaChen/vue-element-admin.git
synced 2025-08-07 18:25:45 +08:00
support Product Configuration (#969)
* support Product Configuration * paint flowchart dynamically * minimal changes Workflow * remove comment Co-authored-by: elsiosanchez <elsiossanches@gmail.com>
This commit is contained in:
parent
07bb5bd692
commit
44ad3521ba
41
src/api/ADempiere/dictionary/workflow.js
Normal file
41
src/api/ADempiere/dictionary/workflow.js
Normal file
@ -0,0 +1,41 @@
|
||||
// ADempiere-Vue (Frontend) for ADempiere ERP & CRM Smart Business Solution
|
||||
// Copyright (C) 2017-Present E.R.P. Consultores y Asociados, C.A.
|
||||
// Contributor(s): Yamel Senih ysenih@erpya.com www.erpya.com
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
// Get Instance for connection
|
||||
import { request } from '@/utils/ADempiere/request'
|
||||
|
||||
/**
|
||||
* Request dictionary workflow metadata
|
||||
* @param {string} uuid universally unique identifier
|
||||
* @param {number} id, identifier
|
||||
*/
|
||||
export function requestWorkflowMetadata({
|
||||
uuid,
|
||||
id
|
||||
}) {
|
||||
return request({
|
||||
url: '/dictionary/workflow',
|
||||
method: 'get',
|
||||
params: {
|
||||
uuid,
|
||||
id
|
||||
}
|
||||
})
|
||||
.then(workflowResponse => {
|
||||
const { convertWorkflow } = require('@/utils/ADempiere/apiConverts/dictionary.js')
|
||||
return convertWorkflow(workflowResponse)
|
||||
})
|
||||
}
|
@ -117,3 +117,29 @@ export function workflowActivities({
|
||||
}
|
||||
})
|
||||
}
|
||||
// GET Workflows
|
||||
/**
|
||||
* Request Document Status List
|
||||
* @param {string} tableName
|
||||
* @param {number} pageSize
|
||||
* @param {string} pageToken
|
||||
*/
|
||||
export function getWorkflow({
|
||||
tableName,
|
||||
pageSize,
|
||||
pageToken
|
||||
}) {
|
||||
return request({
|
||||
url: '/workflow/workflows',
|
||||
method: 'get',
|
||||
params: {
|
||||
table_name: tableName,
|
||||
// Page Data
|
||||
pageToken,
|
||||
pageSize
|
||||
}
|
||||
})
|
||||
.then(listWorkflowActivities => {
|
||||
return listWorkflowActivities
|
||||
})
|
||||
}
|
||||
|
@ -69,7 +69,16 @@ export default {
|
||||
},
|
||||
computed: {
|
||||
getRecordNotification() {
|
||||
return this.$store.getters.getNotificationProcess
|
||||
return this.$store.getters.getNotificationProcess.map(item => {
|
||||
if (item.typeActivity) {
|
||||
return {
|
||||
...item,
|
||||
name: item.name + ' ' + item.quantityActivities
|
||||
}
|
||||
} else {
|
||||
return item
|
||||
}
|
||||
})
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
|
@ -45,37 +45,12 @@
|
||||
<el-main class="main">
|
||||
<el-container style="height: 100%;">
|
||||
<el-aside v-if="!isEmptyValue(currentActivity)" id="workflow" width="70%" style="background: white;">
|
||||
<transition name="el-zoom-in-center">
|
||||
<el-card v-show="show" :style="{position: 'absolute', zIndex: '5', left: leftContextualMenu + 'px', top: topContextualMenu + 'px'}" class="box-card">
|
||||
<div slot="header" class="clearfix">
|
||||
<span>
|
||||
{{ infoNode.description }}
|
||||
</span>
|
||||
<el-button style="float: right; padding: 3px 0" type="text" icon="el-icon-close" @click="show = !show" />
|
||||
</div>
|
||||
<div v-if="!isEmptyValue(infoNode.nodeLogs)" class="text item" style="padding: 20px">
|
||||
<el-timeline class="info">
|
||||
<el-timeline-item
|
||||
v-for="(logs, key) in infoNode.nodeLogs"
|
||||
:key="key"
|
||||
:timestamp="translateDate(logs.log_date)"
|
||||
placement="top"
|
||||
>
|
||||
<el-card style="padding: 20px!important;">
|
||||
<b> {{ $t('login.userName') }} </b> {{ logs.user_name }} <br>
|
||||
{{ logs.text_message }}
|
||||
</el-card>
|
||||
</el-timeline-item>
|
||||
</el-timeline>
|
||||
</div>
|
||||
</el-card>
|
||||
</transition>
|
||||
<workflow-chart
|
||||
<workflow
|
||||
v-if="!isEmptyValue(node) && !isEmptyValue(currentActivity)"
|
||||
:transitions="listWorkflowTransition"
|
||||
:states="node"
|
||||
:state-semantics="currentNode"
|
||||
@state-click="onLabelClicked(node, $event)"
|
||||
:node-transition-list="listWorkflowTransition"
|
||||
:node-list="node"
|
||||
:current-node="currentNode"
|
||||
:workflow-logs="listProcessWorkflow"
|
||||
/>
|
||||
</el-aside>
|
||||
<el-main v-if="!isEmptyValue(currentActivity)" style="overflow: hidden;">
|
||||
@ -105,12 +80,12 @@
|
||||
<script>
|
||||
import formMixin from '@/components/ADempiere/Form/formMixin.js'
|
||||
import fieldsList from './fieldsList.js'
|
||||
import WorkflowChart from 'vue-workflow-chart'
|
||||
import Workflow from '@/components/ADempiere/Workflow'
|
||||
|
||||
export default {
|
||||
name: 'WorkflowActivity',
|
||||
components: {
|
||||
WorkflowChart
|
||||
Workflow
|
||||
},
|
||||
mixins: [
|
||||
formMixin
|
||||
@ -184,9 +159,6 @@ export default {
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
activityList(list) {
|
||||
this.SendActivityListNotifier(list)
|
||||
},
|
||||
currentActivity(value) {
|
||||
this.listWorkflow(value)
|
||||
this.setCurrent()
|
||||
@ -199,9 +171,6 @@ export default {
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
SendActivityListNotifier() {
|
||||
this.$store.commit('addNotificationProcess', { name: this.$t('navbar.badge.activity') + ' ' + this.activityList.length, typeActivity: true })
|
||||
},
|
||||
setCurrent() {
|
||||
const activity = this.activityList.find(activity => activity.node === this.currentActivity.node)
|
||||
this.$refs.WorkflowActivity.setCurrentRow(activity)
|
||||
@ -347,27 +316,6 @@ export default {
|
||||
}
|
||||
</style>
|
||||
<style scoped>
|
||||
.info {
|
||||
margin: 0px;
|
||||
font-size: 14px;
|
||||
list-style: none;
|
||||
padding: 10px;
|
||||
}
|
||||
.vue-workflow-chart-state {
|
||||
background-color: #fff;
|
||||
padding: 20px;
|
||||
border-radius: 3px;
|
||||
color: #11353d;
|
||||
font-size: 15px;
|
||||
font-family: Open Sans;
|
||||
/* font-weight: 600; */
|
||||
margin-right: 20px;
|
||||
margin-bottom: 20px;
|
||||
max-width: 15%;
|
||||
text-align: center;
|
||||
-webkit-box-shadow: 0 2px 4px 0 rgb(0 0 0 / 20%);
|
||||
box-shadow: 0 2px 4px 0 rgb(0 0 0 / 20%);
|
||||
}
|
||||
.panel_main {
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
@ -387,15 +335,3 @@ export default {
|
||||
transition: 0.3s;
|
||||
display: block;
|
||||
}
|
||||
@import '~vue-workflow-chart/dist/vue-workflow-chart.css';
|
||||
.vue-workflow-chart-state-delete {
|
||||
color: white;
|
||||
background: #AED5FE;
|
||||
}
|
||||
.vue-workflow-chart-transition-arrow-delete {
|
||||
fill: #AED5FE;
|
||||
}
|
||||
.vue-workflow-chart-transition-path-delete {
|
||||
stroke: #AED5FE;
|
||||
}
|
||||
</style>
|
||||
|
173
src/components/ADempiere/Workflow/index.vue
Normal file
173
src/components/ADempiere/Workflow/index.vue
Normal file
@ -0,0 +1,173 @@
|
||||
<!--
|
||||
ADempiere-Vue (Frontend) for ADempiere ERP & CRM Smart Business Solution
|
||||
Copyright (C) 2017-Present E.R.P. Consultores y Asociados, C.A.
|
||||
Contributor(s): Elsio Sanchez esanchez@erpya.com www.erpya.com
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <https:www.gnu.org/licenses/>.
|
||||
-->
|
||||
<template>
|
||||
<el-container style="height: 100% !important;">
|
||||
<el-main style="overflow: hidden;">
|
||||
<transition name="el-zoom-in-bottom">
|
||||
<el-card v-show="show" :style="{position: 'absolute', zIndex: '5', left: leftContextualMenu + 'px', top: topContextualMenu + 'px'}" class="box-card">
|
||||
<div slot="header" class="clearfix">
|
||||
<span>
|
||||
{{ infoNode.description }}
|
||||
</span>
|
||||
<el-button style="float: right; padding: 3px 0" type="text" icon="el-icon-close" @click="show = !show" />
|
||||
</div>
|
||||
<div v-if="!isEmptyValue(infoNode.nodeLogs)" class="text item" style="padding: 20px">
|
||||
<el-timeline class="info">
|
||||
<el-timeline-item
|
||||
v-for="(logs, key) in infoNode.nodeLogs"
|
||||
:key="key"
|
||||
:timestamp="translateDate(logs.log_date)"
|
||||
placement="top"
|
||||
>
|
||||
<el-card style="padding: 20px!important;">
|
||||
<b> {{ $t('login.userName') }} </b> {{ logs.user_name }} <br>
|
||||
{{ logs.text_message }}
|
||||
</el-card>
|
||||
</el-timeline-item>
|
||||
</el-timeline>
|
||||
</div>
|
||||
</el-card>
|
||||
</transition>
|
||||
<workflow-chart
|
||||
v-if="!isEmptyValue(nodeList)"
|
||||
id="Diagrama"
|
||||
:transitions="nodeTransitionList"
|
||||
:states="nodeList"
|
||||
:state-semantics="currentNode"
|
||||
@state-click="onLabelClicked(nodeList, $event)"
|
||||
/>
|
||||
</el-main>
|
||||
</el-container>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import WorkflowChart from 'vue-workflow-chart'
|
||||
|
||||
export default {
|
||||
name: 'Workflow',
|
||||
components: {
|
||||
WorkflowChart
|
||||
},
|
||||
props: {
|
||||
nodeList: {
|
||||
type: Array,
|
||||
default: () => []
|
||||
},
|
||||
nodeTransitionList: {
|
||||
type: Array,
|
||||
default: () => []
|
||||
},
|
||||
currentNode: {
|
||||
type: Array,
|
||||
default: () => [{
|
||||
classname: 'delete',
|
||||
id: ''
|
||||
}]
|
||||
},
|
||||
workflowLogs: {
|
||||
type: Array,
|
||||
default: () => []
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
show: false,
|
||||
infoNode: {},
|
||||
topContextualMenu: 0,
|
||||
leftContextualMenu: 0
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
onLabelClicked(type, id) {
|
||||
this.infoNode = type.find(node => node.id === id)
|
||||
const nodeLogs = this.workflowLogs.filter(node => node.node_uuid === this.infoNode.uuid)
|
||||
this.infoNode.nodeLogs = nodeLogs
|
||||
const menuMinWidth = 105
|
||||
const offsetLeft = this.$el.getBoundingClientRect().left // container margin left
|
||||
const offsetWidth = this.$el.offsetWidth // container width
|
||||
const maxLeft = offsetWidth - menuMinWidth // left boundary
|
||||
const left = event.clientX - offsetLeft + 15 // 15: margin right
|
||||
|
||||
this.leftContextualMenu = left
|
||||
if (left > maxLeft) {
|
||||
this.leftContextualMenu = maxLeft
|
||||
}
|
||||
|
||||
const offsetTop = this.$el.getBoundingClientRect().top
|
||||
const top = event.clientY - offsetTop + 500
|
||||
this.topContextualMenu = top
|
||||
this.show = true
|
||||
},
|
||||
translateDate(value) {
|
||||
return this.$d(new Date(value), 'long', this.language)
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.info {
|
||||
margin: 0px;
|
||||
font-size: 14px;
|
||||
list-style: none;
|
||||
padding: 10px;
|
||||
}
|
||||
.vue-workflow-chart-state {
|
||||
background-color: #fff;
|
||||
padding: 20px;
|
||||
border-radius: 3px;
|
||||
color: #11353d;
|
||||
font-size: 15px;
|
||||
font-family: Open Sans;
|
||||
/* font-weight: 600; */
|
||||
margin-right: 20px;
|
||||
margin-bottom: 20px;
|
||||
max-width: 15%;
|
||||
text-align: center;
|
||||
-webkit-box-shadow: 0 2px 4px 0 rgb(0 0 0 / 20%);
|
||||
box-shadow: 0 2px 4px 0 rgb(0 0 0 / 20%);
|
||||
}
|
||||
.panel_main {
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
}
|
||||
</style>
|
||||
<style lang='scss'>
|
||||
.scroll-child {
|
||||
max-height: 450px;
|
||||
}
|
||||
.el-card {
|
||||
border-radius: 4px;
|
||||
border: 1px solid #e6ebf5;
|
||||
background-color: #FFFFFF;
|
||||
overflow: hidden;
|
||||
color: #303133;
|
||||
-webkit-transition: 0.3s;
|
||||
transition: 0.3s;
|
||||
display: block;
|
||||
}
|
||||
@import '~vue-workflow-chart/dist/vue-workflow-chart.css';
|
||||
.vue-workflow-chart-state-delete {
|
||||
color: white;
|
||||
background: #AED5FE;
|
||||
}
|
||||
.vue-workflow-chart-transition-arrow-delete {
|
||||
fill: #AED5FE;
|
||||
}
|
||||
.vue-workflow-chart-transition-path-delete {
|
||||
stroke: #AED5FE;
|
||||
}
|
||||
</style>
|
@ -1,7 +1,9 @@
|
||||
import {
|
||||
workflowActivities
|
||||
} from '@/api/ADempiere/workflow.js'
|
||||
import { isEmptyValue } from '@/utils/ADempiere'
|
||||
import { showMessage } from '@/utils/ADempiere/notification.js'
|
||||
import language from '@/lang'
|
||||
|
||||
const activity = {
|
||||
listActivity: [],
|
||||
@ -19,9 +21,11 @@ export default {
|
||||
}
|
||||
},
|
||||
actions: {
|
||||
serverListActivity({ commit, getters, rootGetters }) {
|
||||
serverListActivity({ commit, state, dispatch, rootGetters }, params) {
|
||||
const userUuid = isEmptyValue(params) ? rootGetters['user/getUserUuid'] : params
|
||||
const name = language.t('navbar.badge.activity')
|
||||
workflowActivities({
|
||||
userUuid: rootGetters['user/getUserUuid']
|
||||
userUuid
|
||||
})
|
||||
.then(response => {
|
||||
const { listWorkflowActivities } = response
|
||||
@ -35,6 +39,26 @@ export default {
|
||||
showClose: true
|
||||
})
|
||||
})
|
||||
.finally(() => {
|
||||
const notification = rootGetters.getNotificationProcess.find(notification => {
|
||||
if (notification.typeActivity && notification.quantityActivities === state.listActivity.length) {
|
||||
return notification
|
||||
}
|
||||
})
|
||||
if (isEmptyValue(notification)) {
|
||||
commit('addNotificationProcess', {
|
||||
name,
|
||||
typeActivity: true,
|
||||
quantityActivities: state.listActivity.length
|
||||
})
|
||||
} else {
|
||||
dispatch('updateNotifications', {
|
||||
name,
|
||||
typeActivity: true,
|
||||
quantityActivities: state.listActivity.length
|
||||
})
|
||||
}
|
||||
})
|
||||
},
|
||||
selectedActivity({ commit }, activity) {
|
||||
commit('setCurrentActivity', activity)
|
||||
|
@ -783,6 +783,9 @@ const actions = {
|
||||
default:
|
||||
executeAction = 'getFieldsFromTab'
|
||||
break
|
||||
case 'workflow':
|
||||
executeAction = 'getWorkflowFromServer'
|
||||
break
|
||||
}
|
||||
|
||||
return dispatch(executeAction, {
|
||||
|
@ -1220,5 +1220,17 @@ export default {
|
||||
dispatch('updateOrderPos', false)
|
||||
})
|
||||
})
|
||||
},
|
||||
updateNotifications({ commit, state },
|
||||
update
|
||||
) {
|
||||
const notification = state.notificationProcess.map(notification => {
|
||||
if (notification.name === update.name && notification.typeActivity && notification.quantityActivities !== update.quantityActivities) {
|
||||
return {
|
||||
...update
|
||||
}
|
||||
}
|
||||
})
|
||||
commit('updateNotificationProcess', notification)
|
||||
}
|
||||
}
|
||||
|
@ -14,6 +14,9 @@ export default {
|
||||
addNotificationProcess(state, payload) {
|
||||
state.notificationProcess.push(payload)
|
||||
},
|
||||
updateNotificationProcess(state, update) {
|
||||
state.notificationProcess = update
|
||||
},
|
||||
// Delete process in execution afther some response from server
|
||||
deleteInExecution(state, payload) {
|
||||
state.inExecution = state.inExecution.filter(item => item.containerUuid !== payload.containerUuid)
|
||||
|
75
src/store/modules/ADempiere/workflowDefinition.js
Normal file
75
src/store/modules/ADempiere/workflowDefinition.js
Normal file
@ -0,0 +1,75 @@
|
||||
import { requestWorkflowMetadata } from '@/api/ADempiere/dictionary/workflow'
|
||||
import { showMessage } from '@/utils/ADempiere/notification'
|
||||
// import router from '@/router'
|
||||
import language from '@/lang'
|
||||
|
||||
const workflow = {
|
||||
state: {
|
||||
workflow: []
|
||||
},
|
||||
mutations: {
|
||||
addWorkflow(state, payload) {
|
||||
state.workflow.push(payload)
|
||||
},
|
||||
dictionaryResetCacheWorkflow(state) {
|
||||
state.workflow = []
|
||||
}
|
||||
},
|
||||
actions: {
|
||||
getWorkflowFromServer({ commit, dispatch }, {
|
||||
id,
|
||||
containerUuid,
|
||||
routeToDelete
|
||||
}) {
|
||||
return new Promise(resolve => {
|
||||
requestWorkflowMetadata({
|
||||
uuid: containerUuid,
|
||||
id
|
||||
})
|
||||
.then(workflowResponse => {
|
||||
const panelType = 'workflow'
|
||||
|
||||
// Panel for save on store
|
||||
const newWorkflow = {
|
||||
...workflowResponse,
|
||||
containerUuid,
|
||||
fieldsList: [],
|
||||
panelType
|
||||
}
|
||||
|
||||
commit('addWorkflow', newWorkflow)
|
||||
|
||||
resolve(newWorkflow)
|
||||
|
||||
const actions = []
|
||||
|
||||
// Add process menu
|
||||
dispatch('setContextMenu', {
|
||||
containerUuid,
|
||||
actions
|
||||
})
|
||||
})
|
||||
.catch(error => {
|
||||
// router.push({
|
||||
// path: '/dashboard'
|
||||
// }, () => {})
|
||||
// dispatch('tagsView/delView', routeToDelete)
|
||||
showMessage({
|
||||
message: language.t('login.unexpectedError'),
|
||||
type: 'error'
|
||||
})
|
||||
console.warn(`Dictionary Workflow - Error ${error.code}: ${error.message}.`)
|
||||
})
|
||||
})
|
||||
}
|
||||
},
|
||||
getters: {
|
||||
getWorkflowUuid: (state) => (workflowUuid) => {
|
||||
return state.workflow.find(
|
||||
item => item.uuid === workflowUuid
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default workflow
|
@ -672,7 +672,6 @@ export function convertAction(action) {
|
||||
isIndex: false,
|
||||
component: () => import('@/views/ADempiere/Unsupported')
|
||||
}
|
||||
|
||||
switch (action) {
|
||||
case 'B':
|
||||
actionAttributes.name = 'workbech'
|
||||
@ -681,6 +680,7 @@ export function convertAction(action) {
|
||||
case 'F':
|
||||
actionAttributes.name = 'workflow'
|
||||
actionAttributes.icon = 'example'
|
||||
actionAttributes.component = () => import('@/views/ADempiere/Workflow')
|
||||
break
|
||||
case 'P':
|
||||
actionAttributes.name = 'process'
|
||||
|
206
src/views/ADempiere/Workflow/index.vue
Normal file
206
src/views/ADempiere/Workflow/index.vue
Normal file
@ -0,0 +1,206 @@
|
||||
<!--
|
||||
ADempiere-Vue (Frontend) for ADempiere ERP & CRM Smart Business Solution
|
||||
Copyright (C) 2017-Present E.R.P. Consultores y Asociados, C.A.
|
||||
Contributor(s): Edwin Betancourt EdwinBetanc0urt@outlook.com www.erpya.com
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <https:www.gnu.org/licenses/>.
|
||||
-->
|
||||
<template>
|
||||
<el-container class="panel_main">
|
||||
<el-header>
|
||||
<title-and-help
|
||||
:name="workflowFileName"
|
||||
:help="$route.meta.description"
|
||||
/>
|
||||
</el-header>
|
||||
<el-main v-if="isLoadedMetadata">
|
||||
<workflow
|
||||
v-if="!isEmptyValue(node)"
|
||||
:node-transition-list="listWorkflowTransition"
|
||||
:node-list="node"
|
||||
:current-node="currentNode"
|
||||
/>
|
||||
</el-main>
|
||||
<div
|
||||
v-else
|
||||
key="form-loading"
|
||||
v-loading="!isLoadedMetadata"
|
||||
:element-loading-text="$t('notifications.loading')"
|
||||
element-loading-spinner="el-icon-loading"
|
||||
element-loading-background="rgba(255, 255, 255, 0.8)"
|
||||
class="view-loading"
|
||||
/>
|
||||
</el-container>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
// When supporting the workflow, smart browser and reports,
|
||||
// the ContextMenu and sticky must be placed in the layout
|
||||
// import ContextMenu from '@/components/ADempiere/ContextMenu'
|
||||
// import MainPanel from '@/components/ADempiere/Panel'
|
||||
import TitleAndHelp from '@/components/ADempiere/TitleAndHelp'
|
||||
import Workflow from '@/components/ADempiere/Workflow'
|
||||
import { getWorkflow } from '@/api/ADempiere/workflow.js'
|
||||
|
||||
export default {
|
||||
name: 'Workflow',
|
||||
components: {
|
||||
Workflow,
|
||||
TitleAndHelp
|
||||
},
|
||||
props: {
|
||||
isEdit: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
size: {
|
||||
width: '20px',
|
||||
height: '2px'
|
||||
},
|
||||
workflowMetadata: {},
|
||||
node: [],
|
||||
listWorkflowTransition: [],
|
||||
isLoadedMetadata: false,
|
||||
panelType: 'workflow'
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
workflowUuid() {
|
||||
return this.$route.meta.uuid
|
||||
},
|
||||
workflowFileName() {
|
||||
return this.workflowMetadata.fileName || this.$route.meta.title
|
||||
},
|
||||
getWorkflow() {
|
||||
return this.$store.getters.getWorkflowUuid(this.workflowUuid)
|
||||
},
|
||||
nodoWorkflow() {
|
||||
return this.workflowMetadata.node.map(node => {
|
||||
return {
|
||||
id: node.id,
|
||||
label: node.name
|
||||
}
|
||||
})
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.gettWorkflow()
|
||||
},
|
||||
methods: {
|
||||
gettWorkflow() {
|
||||
const workflow = this.getWorkflow
|
||||
if (workflow) {
|
||||
this.workflowMetadata = workflow
|
||||
this.isLoadedMetadata = true
|
||||
} else {
|
||||
this.$store.dispatch('getPanelAndFields', {
|
||||
containerUuid: this.workflowUuid,
|
||||
panelType: this.panelType,
|
||||
routeToDelete: this.$route
|
||||
}).then(workflowResponse => {
|
||||
this.workflowMetadata = workflowResponse
|
||||
this.listWorkflow(this.workflowMetadata)
|
||||
}).finally(() => {
|
||||
this.isLoadedMetadata = true
|
||||
})
|
||||
}
|
||||
this.serverWorkflow(this.workflowMetadata)
|
||||
},
|
||||
serverWorkflow({ tableName }) {
|
||||
if (this.isEmptyValue(tableName)) {
|
||||
return ''
|
||||
}
|
||||
getWorkflow({
|
||||
tableName
|
||||
})
|
||||
.then(response => {
|
||||
this.listWorkflow(response.records)
|
||||
})
|
||||
.catch(error => {
|
||||
console.warn(`serverWorkflow: ${error.message}. Code: ${error.code}.`)
|
||||
})
|
||||
},
|
||||
listWorkflow(workflow) {
|
||||
// Highlight Current Node
|
||||
this.transitions = []
|
||||
if (!this.isEmptyValue(workflow.node.uuid)) {
|
||||
this.currentNode = [{
|
||||
classname: 'delete',
|
||||
id: workflow.start_node.uuid
|
||||
}]
|
||||
}
|
||||
const nodes = workflow.workflow_nodes.filter(node => !this.isEmptyValue(node.uuid))
|
||||
this.listNodeTransitions(nodes)
|
||||
if (!this.isEmptyValue(nodes)) {
|
||||
this.node = nodes.map((workflow, key) => {
|
||||
return {
|
||||
...workflow,
|
||||
transitions: workflow.transitions,
|
||||
id: workflow.uuid,
|
||||
key,
|
||||
label: workflow.name
|
||||
}
|
||||
})
|
||||
} else {
|
||||
this.node = []
|
||||
}
|
||||
},
|
||||
listNodeTransitions(nodes) {
|
||||
nodes.forEach(element => {
|
||||
const uuid = element.uuid
|
||||
const id = element.value
|
||||
if (!this.isEmptyValue(element.transitions)) {
|
||||
element.transitions.forEach((nextNode, key) => {
|
||||
if (!this.isEmptyValue(nextNode.node_next_uuid)) {
|
||||
if (this.isEmptyValue(nextNode.description)) {
|
||||
this.transitions.push({
|
||||
id: id + key,
|
||||
target: uuid,
|
||||
source: nextNode.node_next_uuid
|
||||
})
|
||||
} else {
|
||||
this.transitions.push({
|
||||
id: id + key,
|
||||
label: nextNode.description,
|
||||
target: uuid,
|
||||
source: nextNode.node_next_uuid
|
||||
})
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
const blon = nodes.map(item => {
|
||||
return {
|
||||
uuid: item.uuid
|
||||
}
|
||||
})
|
||||
this.listWorkflowTransition = this.transitions.filter(data => {
|
||||
const verificar = blon.find(mode => mode.uuid === data.source)
|
||||
if (!this.isEmptyValue(verificar)) {
|
||||
return data
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style scoped>
|
||||
.panel_main {
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
}
|
||||
</style>
|
@ -196,6 +196,7 @@ export default {
|
||||
})
|
||||
.finally(() => {
|
||||
this.loading = false
|
||||
this.$store.dispatch('serverListActivity')
|
||||
})
|
||||
} else {
|
||||
console.log('error submit!!')
|
||||
|
Loading…
x
Reference in New Issue
Block a user