mirror of
https://github.com/PanJiaChen/vue-element-admin.git
synced 2025-08-07 18:25:45 +08:00
fix: Process logs request duplicated (#940)
* fix: Process logs request duplicated * deleted mutations.
This commit is contained in:
parent
f152ed0f8d
commit
548bb2f165
@ -1,6 +1,5 @@
|
||||
import {
|
||||
requestRunProcess,
|
||||
requestListProcessesLogs
|
||||
requestRunProcess
|
||||
} from '@/api/ADempiere/process'
|
||||
import { showNotification } from '@/utils/ADempiere/notification'
|
||||
import { isEmptyValue } from '@/utils/ADempiere/valueUtils'
|
||||
@ -989,60 +988,7 @@ export default {
|
||||
})
|
||||
}
|
||||
},
|
||||
/**
|
||||
* List log of process/reports executed
|
||||
* @author Edwin Betancourt <EdwinBetanc0urt@outlook.com>
|
||||
* @param {string} pageToken
|
||||
* @param {number} pageSize default 50
|
||||
*/
|
||||
getSessionProcessFromServer({ commit, dispatch, getters, rootGetters }, {
|
||||
pageToken,
|
||||
pageSize
|
||||
}) {
|
||||
// process Activity
|
||||
return requestListProcessesLogs({ pageToken, pageSize })
|
||||
.then(processActivityResponse => {
|
||||
const responseList = processActivityResponse.processLogsList.map(processLogItem => {
|
||||
const processMetadata = rootGetters.getProcess(processLogItem.uuid)
|
||||
|
||||
// if no exists metadata into store and no request in progess
|
||||
if (isEmptyValue(processMetadata)) {
|
||||
const processRequest = getters.getInRequestMetadata(processLogItem.uuid)
|
||||
if (isEmptyValue(processRequest)) {
|
||||
commit('addInRequestMetadata', processLogItem.uuid)
|
||||
dispatch('getProcessFromServer', {
|
||||
containerUuid: processLogItem.uuid
|
||||
})
|
||||
.finally(() => {
|
||||
commit('deleteInRequestMetadata', processLogItem.uuid)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
const process = {
|
||||
...processLogItem,
|
||||
processUuid: processLogItem.uuid
|
||||
}
|
||||
return process
|
||||
})
|
||||
|
||||
const processResponseList = {
|
||||
recordCount: processActivityResponse.recordCount,
|
||||
processList: responseList,
|
||||
nextPageToken: processActivityResponse.nextPageToken
|
||||
}
|
||||
commit('setSessionProcess', processResponseList)
|
||||
return processResponseList
|
||||
})
|
||||
.catch(error => {
|
||||
showNotification({
|
||||
title: language.t('notifications.error'),
|
||||
message: error.message,
|
||||
type: 'error'
|
||||
})
|
||||
console.warn(`Error getting process activity: ${error.message}. Code: ${error.code}.`)
|
||||
})
|
||||
},
|
||||
/**
|
||||
* Show modal dialog with process/report, tab (sequence) metadata
|
||||
* @param {String} type of panel or panelType ('process', 'report', 'window')
|
||||
|
@ -25,18 +25,7 @@ export default {
|
||||
getNotificationProcess: (state) => {
|
||||
return state.notificationProcess
|
||||
},
|
||||
/**
|
||||
* Process receibed from server associated whith this session
|
||||
*/
|
||||
getAllSessionProcess: (state) => {
|
||||
return state.sessionProcess
|
||||
},
|
||||
/**
|
||||
* Process request metadata from server filter form uuid process
|
||||
*/
|
||||
getInRequestMetadata: (state) => (containerUuid) => {
|
||||
return state.inRequestMetadata.find(item => item === containerUuid)
|
||||
},
|
||||
|
||||
getProcessResult: (state) => {
|
||||
return state.reportObject
|
||||
},
|
||||
|
@ -18,14 +18,7 @@ export default {
|
||||
deleteInExecution(state, payload) {
|
||||
state.inExecution = state.inExecution.filter(item => item.containerUuid !== payload.containerUuid)
|
||||
},
|
||||
// Add process in request metadata from server
|
||||
addInRequestMetadata(state, payload) {
|
||||
state.inRequestMetadata.push(payload)
|
||||
},
|
||||
// Delete process in request metadata
|
||||
deleteInRequestMetadata(state, payload) {
|
||||
state.inRequestMetadata = state.inRequestMetadata.filter(item => item !== payload)
|
||||
},
|
||||
|
||||
addStartedProcess(state, payload) {
|
||||
state.process.push(payload)
|
||||
},
|
||||
@ -52,9 +45,7 @@ export default {
|
||||
state.reportList.push(payload)
|
||||
}
|
||||
},
|
||||
setSessionProcess(state, payload) {
|
||||
state.sessionProcess = payload.processList
|
||||
},
|
||||
|
||||
changeFormatReport(state, payload) {
|
||||
state.reportFormat = payload
|
||||
},
|
||||
@ -64,9 +55,7 @@ export default {
|
||||
setTotalResponse(state, payload) {
|
||||
state.totalResponse = payload
|
||||
},
|
||||
setTotalSelection(state, payload) {
|
||||
state.totalSelection = payload
|
||||
},
|
||||
|
||||
setSuccessSelection(state, payload) {
|
||||
state.successSelection = payload
|
||||
},
|
||||
|
@ -9,9 +9,7 @@ export default {
|
||||
reportList: [],
|
||||
metadata: {},
|
||||
process: [], // process to run finish
|
||||
sessionProcess: [],
|
||||
notificationProcess: [],
|
||||
inRequestMetadata: [],
|
||||
reportViewList: [],
|
||||
totalResponse: 0,
|
||||
totalRequest: 0,
|
||||
|
128
src/store/modules/ADempiere/processLog.js
Normal file
128
src/store/modules/ADempiere/processLog.js
Normal file
@ -0,0 +1,128 @@
|
||||
// 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/>.
|
||||
|
||||
import {
|
||||
requestListProcessesLogs
|
||||
} from '@/api/ADempiere/process.js'
|
||||
import { showNotification } from '@/utils/ADempiere/notification.js'
|
||||
import { isEmptyValue } from '@/utils/ADempiere/valueUtils.js'
|
||||
import language from '@/lang'
|
||||
|
||||
/**
|
||||
* Process Vuex Module
|
||||
* @author Edwin Betancourt <EdwinBetanc0urt@outlook.com>
|
||||
*/
|
||||
const processLog = {
|
||||
state: {
|
||||
sessionProcess: [],
|
||||
inRequestMetadata: []
|
||||
},
|
||||
|
||||
mutations: {
|
||||
setSessionProcess(state, payload) {
|
||||
state.sessionProcess = payload.processList
|
||||
},
|
||||
|
||||
// Add process in request metadata from server
|
||||
addInRequestMetadata(state, payload) {
|
||||
state.inRequestMetadata.push(payload)
|
||||
},
|
||||
|
||||
// Delete process in request metadata
|
||||
deleteInRequestMetadata(state, payload) {
|
||||
state.inRequestMetadata = state.inRequestMetadata.filter(item => item !== payload)
|
||||
}
|
||||
},
|
||||
|
||||
actions: {
|
||||
/**
|
||||
* List log of process/reports executed
|
||||
* @author Edwin Betancourt <EdwinBetanc0urt@outlook.com>
|
||||
* @param {string} pageToken
|
||||
* @param {number} pageSize default 50
|
||||
*/
|
||||
getSessionProcessFromServer({ commit, dispatch, getters, rootGetters }, {
|
||||
pageToken,
|
||||
pageSize
|
||||
}) {
|
||||
// process Activity
|
||||
return requestListProcessesLogs({ pageToken, pageSize })
|
||||
.then(processActivityResponse => {
|
||||
const responseList = processActivityResponse.processLogsList.map(processLogItem => {
|
||||
const { uuid: containerUuid } = processLogItem
|
||||
const processMetadata = rootGetters.getProcess(containerUuid)
|
||||
|
||||
// if no exists metadata into store
|
||||
if (isEmptyValue(processMetadata)) {
|
||||
const processRequest = getters.getInRequestMetadata(containerUuid)
|
||||
// if no request dictionary metadata in progess
|
||||
if (isEmptyValue(processRequest)) {
|
||||
commit('addInRequestMetadata', containerUuid)
|
||||
|
||||
dispatch('getProcessFromServer', {
|
||||
containerUuid
|
||||
})
|
||||
.finally(() => {
|
||||
commit('deleteInRequestMetadata', containerUuid)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
const process = {
|
||||
...processLogItem,
|
||||
processUuid: containerUuid
|
||||
}
|
||||
return process
|
||||
})
|
||||
|
||||
const processResponseList = {
|
||||
recordCount: processActivityResponse.recordCount,
|
||||
processList: responseList,
|
||||
nextPageToken: processActivityResponse.nextPageToken
|
||||
}
|
||||
commit('setSessionProcess', processResponseList)
|
||||
|
||||
return processResponseList
|
||||
})
|
||||
.catch(error => {
|
||||
showNotification({
|
||||
title: language.t('notifications.error'),
|
||||
message: error.message,
|
||||
type: 'error'
|
||||
})
|
||||
console.warn(`Error getting process activity: ${error.message}. Code: ${error.code}.`)
|
||||
})
|
||||
}
|
||||
},
|
||||
|
||||
getters: {
|
||||
/**
|
||||
* Process request metadata from server filter form uuid process
|
||||
*/
|
||||
getInRequestMetadata: (state) => (containerUuid) => {
|
||||
return state.inRequestMetadata.find(item => item === containerUuid)
|
||||
},
|
||||
|
||||
/**
|
||||
* Process receibed from server associated whith this session
|
||||
*/
|
||||
getAllSessionProcess: (state) => {
|
||||
return state.sessionProcess
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default processLog
|
@ -20,7 +20,7 @@ import { convertReportOutput } from './report.js'
|
||||
|
||||
export function convertProcessLog(processLog) {
|
||||
const convertedProcessLog = camelizeObjectKeys(processLog)
|
||||
convertedProcessLog.paramenters = []
|
||||
convertedProcessLog.parameters = []
|
||||
convertedProcessLog.output = isEmptyValue(processLog.output) ? {} : convertReportOutput(processLog.output)
|
||||
return convertedProcessLog
|
||||
}
|
||||
|
@ -22,168 +22,29 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { recursiveTreeSearch } from '@/utils/ADempiere/valueUtils'
|
||||
import { defineComponent, computed } from '@vue/composition-api'
|
||||
|
||||
export default {
|
||||
name: 'MixinProcessActivity',
|
||||
data() {
|
||||
return {
|
||||
processActivity: [],
|
||||
recordCount: 0,
|
||||
pageToken: '',
|
||||
pageSize: 50
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
// process local not sent
|
||||
getterAllInExecution() {
|
||||
return this.$store.getters.getAllInExecution
|
||||
},
|
||||
// process local and send with response
|
||||
getterAllFinishProcess() {
|
||||
return this.$store.getters.getAllFinishProcess
|
||||
},
|
||||
// session process from server
|
||||
getterAllSessionProcess() {
|
||||
return this.$store.getters.getAllSessionProcess
|
||||
},
|
||||
// all process
|
||||
getRunProcessAll() {
|
||||
var processAll = this.getterAllInExecution.concat(this.getterAllFinishProcess, this.getterAllSessionProcess)
|
||||
var processAllReturned = []
|
||||
export default defineComponent({
|
||||
name: 'ProcessActivityFromDevice',
|
||||
|
||||
processAll.forEach(element => {
|
||||
var processMetadataReturned = {}
|
||||
var infoMetadata = this.getProcessMetadata(element.processUuid)
|
||||
if (!infoMetadata) {
|
||||
infoMetadata = {}
|
||||
}
|
||||
Object.assign(processMetadataReturned, element, infoMetadata)
|
||||
processMetadataReturned.parametersList = element.parametersList
|
||||
var indexRepeat = processAllReturned.findIndex(item => item.instanceUuid === element.instanceUuid && !this.isEmptyValue(element.instanceUuid))
|
||||
if (indexRepeat > -1) {
|
||||
// update attributes in exists process to return
|
||||
// Object.assign(processAllReturned[indexRepeat], processMetadataReturned)
|
||||
var other = Object.assign(processMetadataReturned, processAllReturned[indexRepeat])
|
||||
processAllReturned[indexRepeat] = other
|
||||
return
|
||||
}
|
||||
setup(props, { root }) {
|
||||
const isMobile = computed(() => {
|
||||
return root.$store.state.app.device === 'mobile'
|
||||
})
|
||||
|
||||
// add new process to show
|
||||
processAllReturned.push(processMetadataReturned)
|
||||
})
|
||||
return processAllReturned.sort((a, b) => {
|
||||
// sort by date and reverse string to order by most recently
|
||||
return new Date(a.lastRun) - new Date(b.lastRun)
|
||||
}).reverse()
|
||||
},
|
||||
getProcessLog() {
|
||||
var log = this.getRunProcessAll.filter(element => {
|
||||
if (element.isError !== undefined && (element.isProcessing !== undefined)) {
|
||||
return element
|
||||
}
|
||||
})
|
||||
return log
|
||||
},
|
||||
language() {
|
||||
return this.$store.getters.language
|
||||
},
|
||||
permissionRoutes() {
|
||||
return this.$store.getters.permission_routes
|
||||
},
|
||||
isMobile() {
|
||||
return this.$store.state.app.device === 'mobile'
|
||||
},
|
||||
templateDevice() {
|
||||
if (this.isMobile) {
|
||||
const templateDevice = computed(() => {
|
||||
if (isMobile.value) {
|
||||
return () => import('@/views/ADempiere/ProcessActivity/modeMobile')
|
||||
}
|
||||
return () => import('@/views/ADempiere/ProcessActivity/modeDesktop')
|
||||
}
|
||||
},
|
||||
beforeMount() {
|
||||
this.$store.dispatch('getSessionProcessFromServer', {
|
||||
pageToken: this.pageToken,
|
||||
pageSize: this.pageSize
|
||||
})
|
||||
.then(response => {
|
||||
if (response.nextPageToken !== this.pageToken) {
|
||||
this.pageToken = response.nextPageToken
|
||||
}
|
||||
})
|
||||
},
|
||||
methods: {
|
||||
getProcessMetadata(uuid) {
|
||||
return this.$store.getters.getProcess(uuid)
|
||||
},
|
||||
handleCommand(activity) {
|
||||
if (activity.command === 'seeReport') {
|
||||
this.$router.push({
|
||||
name: 'Report Viewer',
|
||||
params: {
|
||||
processId: activity.processId,
|
||||
instanceUuid: activity.instanceUuid,
|
||||
fileName: activity.output.fileName
|
||||
}
|
||||
}, () => {})
|
||||
} else if (activity.command === 'zoomIn') {
|
||||
const viewSearch = recursiveTreeSearch({
|
||||
treeData: this.permissionRoutes,
|
||||
attributeValue: activity.uuid,
|
||||
attributeName: 'meta',
|
||||
secondAttribute: 'uuid',
|
||||
attributeChilds: 'children'
|
||||
})
|
||||
if (viewSearch) {
|
||||
this.$router.push({
|
||||
name: viewSearch.name,
|
||||
query: {
|
||||
...this.$route.query,
|
||||
...activity.parametersList
|
||||
}
|
||||
}, () => {})
|
||||
}
|
||||
}
|
||||
},
|
||||
checkStatus({ isError, isProcessing, isReport }) {
|
||||
const status = {
|
||||
text: this.$t('notifications.completed'),
|
||||
type: 'success',
|
||||
color: '#67C23A'
|
||||
}
|
||||
// if (isReport) {
|
||||
// return status
|
||||
// }
|
||||
// is executing
|
||||
if (isProcessing) {
|
||||
status.text = this.$t('notifications.processing')
|
||||
status.type = 'info'
|
||||
status.color = '#909399'
|
||||
return status
|
||||
}
|
||||
if (isError) {
|
||||
status.text = this.$t('notifications.error')
|
||||
status.type = 'danger'
|
||||
status.color = '#F56C6C'
|
||||
return status
|
||||
}
|
||||
// is completed
|
||||
return status
|
||||
},
|
||||
generateTitle(title) {
|
||||
const hasKey = this.$te('table.ProcessActivity.' + title)
|
||||
if (hasKey) {
|
||||
// $t :this method from vue-i18n, inject in @/lang/index.js
|
||||
const translatedTitle = this.$t('table.ProcessActivity.' + title)
|
||||
return translatedTitle
|
||||
}
|
||||
return title
|
||||
},
|
||||
translateDate(value) {
|
||||
return this.$d(new Date(value), 'long', this.language)
|
||||
|
||||
return {
|
||||
// computeds
|
||||
templateDevice
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped src="./processActivityStyle.scss">
|
||||
|
@ -30,96 +30,127 @@
|
||||
>
|
||||
<el-card>
|
||||
<div slot="header" class="clearfix">
|
||||
<span><b>{{ activity.name }}</b></span>
|
||||
<span>
|
||||
<b> {{ activity.name }} </b>
|
||||
</span>
|
||||
|
||||
<div class="actions">
|
||||
<el-dropdown @command="handleCommand">
|
||||
<span class="el-dropdown-link">
|
||||
{{ $t('components.contextMenuActions') }}<i class="el-icon-arrow-down el-icon--right" />
|
||||
{{ $t('components.contextMenuActions') }}
|
||||
<i class="el-icon-arrow-down el-icon--right" />
|
||||
</span>
|
||||
|
||||
<el-dropdown-menu slot="dropdown">
|
||||
<el-dropdown-item v-if="activity.isReport" :command="{ ...activity, command: 'seeReport' }">
|
||||
<el-dropdown-item
|
||||
v-if="activity.isReport"
|
||||
:command="{ ...activity, command: 'seeReport' }"
|
||||
>
|
||||
{{ $t('views.seeReport') }}
|
||||
</el-dropdown-item>
|
||||
|
||||
<el-dropdown-item :command="{ ...activity, command: 'zoomIn' }">
|
||||
{{ $t('table.ProcessActivity.zoomIn') }}
|
||||
</el-dropdown-item>
|
||||
|
||||
<!-- TODO: add more actions -->
|
||||
</el-dropdown-menu>
|
||||
</el-dropdown>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<el-form label-position="top">
|
||||
<el-form-item v-if="activity.description" :label="generateTitle('Description')">
|
||||
<span><b>{{ activity.description }}</b></span>
|
||||
<span v-if="activity.isReport">{{ activity.output.description }}</span>
|
||||
<span>
|
||||
<b> {{ activity.description }} </b>
|
||||
</span>
|
||||
|
||||
<span v-if="activity.isReport">
|
||||
{{ activity.output.description }}
|
||||
</span>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item :label="generateTitle('Status')">
|
||||
<!-- show only when it is error -->
|
||||
<el-popover
|
||||
v-if="activity.isError && !activity.summary && !activity.isReport"
|
||||
v-if="activity.isError && !activity.isReport"
|
||||
:key="index + 'is-error'"
|
||||
placement="right"
|
||||
title="Error"
|
||||
width="700"
|
||||
trigger="hover"
|
||||
>
|
||||
<div>
|
||||
{{ activity.message }}
|
||||
<div v-if="!isEmptyValue(activity.summary)" key="withSummary">
|
||||
{{ activity.summary }}
|
||||
</div>
|
||||
<div v-else key="withoutSummary">
|
||||
{{ $t('route.withoutLog') }}
|
||||
</div>
|
||||
|
||||
<el-tag slot="reference" :type="checkStatus(activity).type">
|
||||
{{ checkStatus(activity).text }}
|
||||
</el-tag>
|
||||
</el-popover>
|
||||
|
||||
<!-- show only when bring logs -->
|
||||
<el-popover
|
||||
v-else-if="!isEmptyValue(activity.logsList) || !isEmptyValue(activity.summary)"
|
||||
:key="index + 'is-summary'"
|
||||
placement="right"
|
||||
:title="$t('table.ProcessActivity.Logs')"
|
||||
width="500"
|
||||
trigger="hover"
|
||||
>
|
||||
<b>{{ $t('table.ProcessActivity.Logs') }}</b><br>
|
||||
<ul>
|
||||
<li @click="handleCommand({ ...activity, command: 'zoomIn' })"> {{ activity.summary }} </li>
|
||||
<li @click="handleCommand({ ...activity, command: 'zoomIn' })">
|
||||
{{ activity.summary }}
|
||||
</li>
|
||||
<el-scrollbar wrap-class="popover-scroll">
|
||||
<li v-for="(logItem, key) in activity.logsList" :key="key" @click="zoomIn(activity)">
|
||||
{{ logItem.log }}
|
||||
</li>
|
||||
</el-scrollbar>
|
||||
</ul>
|
||||
|
||||
<el-tag slot="reference" :type="checkStatus(activity).type">
|
||||
{{ checkStatus(activity).text }}
|
||||
</el-tag>
|
||||
</el-popover>
|
||||
|
||||
<!-- show only when bring output -->
|
||||
<el-popover
|
||||
v-else-if="activity.isReport"
|
||||
:key="index + 'is-output'"
|
||||
placement="right"
|
||||
:title="$t('table.ProcessActivity.Output')"
|
||||
width="700"
|
||||
trigger="hover"
|
||||
>
|
||||
<div>
|
||||
<span> {{ $t('table.ProcessActivity.Output') }} </span><br>
|
||||
<span>{{ $t('table.ProcessActivity.Name') }}: {{ activity.output.name }}</span><br>
|
||||
<span>{{ $t('table.ProcessActivity.Description') }}: {{ activity.output.description }}</span><br>
|
||||
<span>{{ $t('table.ProcessActivity.FileName') }}: {{ activity.output.fileName }}</span><br>
|
||||
<div v-if="!activity.isError" key="withOutput">
|
||||
<span>
|
||||
{{ $t('table.ProcessActivity.Name') }}: {{ activity.output.name }}
|
||||
</span><br>
|
||||
<span>
|
||||
{{ $t('table.ProcessActivity.Description') }}: {{ activity.output.description }}
|
||||
</span><br>
|
||||
<span>
|
||||
{{ $t('table.ProcessActivity.FileName') }}: {{ activity.output.fileName }}
|
||||
</span><br>
|
||||
<a type="text" :href="activity.url" :download="activity.download">
|
||||
{{ $t('components.contextMenuDownload') }} <i class="el-icon-download" />
|
||||
{{ $t('components.contextMenuDownload') }}
|
||||
<i class="el-icon-download" />
|
||||
</a>
|
||||
</div>
|
||||
<el-tag slot="reference" :type="checkStatus(activity).type">
|
||||
{{ checkStatus(activity).text }}
|
||||
</el-tag>
|
||||
</el-popover>
|
||||
<el-popover
|
||||
v-else
|
||||
:key="index + 'is-other'"
|
||||
placement="top-start"
|
||||
:title="$t('table.ProcessActivity.Logs')"
|
||||
width="200"
|
||||
trigger="hover"
|
||||
:content="activity.summary"
|
||||
>
|
||||
|
||||
<div v-else key="withError">
|
||||
<template v-if="!isEmptyValue(activity.summary)">
|
||||
{{ activity.summary }}
|
||||
</template>
|
||||
<template v-else>
|
||||
{{ $t('route.withoutLog') }}
|
||||
</template>
|
||||
</div>
|
||||
|
||||
<el-tag slot="reference" :type="checkStatus(activity).type">
|
||||
{{ checkStatus(activity).text }}
|
||||
</el-tag>
|
||||
@ -130,20 +161,15 @@
|
||||
</el-timeline-item>
|
||||
</el-timeline>
|
||||
</div>
|
||||
|
||||
<div v-else key="without-process">
|
||||
<h1 class="text-center">{{ $t('views.noProcess') }}</h1>
|
||||
<h1 class="text-center">
|
||||
{{ $t('views.noProcess') }}
|
||||
</h1>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import MixinProcessActivity from './index.vue'
|
||||
|
||||
export default {
|
||||
name: 'ModeDesktop',
|
||||
mixins: [
|
||||
MixinProcessActivity
|
||||
]
|
||||
}
|
||||
<script src="./processActivity.js">
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped src="./processActivityStyle.scss">
|
||||
|
@ -30,102 +30,127 @@
|
||||
>
|
||||
<el-card>
|
||||
<div slot="header" class="clearfix">
|
||||
<span><b>{{ activity.name }}</b></span>
|
||||
<span>
|
||||
<b> {{ activity.name }} </b>
|
||||
</span>
|
||||
|
||||
<div class="actions">
|
||||
<el-dropdown @command="handleCommand">
|
||||
<span class="el-dropdown-link">
|
||||
{{ $t('components.contextMenuActions') }}<i class="el-icon-arrow-down el-icon--right" />
|
||||
{{ $t('components.contextMenuActions') }}
|
||||
<i class="el-icon-arrow-down el-icon--right" />
|
||||
</span>
|
||||
|
||||
<el-dropdown-menu slot="dropdown">
|
||||
<el-dropdown-item v-if="activity.isReport" :command="{ ...activity, command: 'seeReport' }">
|
||||
<el-dropdown-item
|
||||
v-if="activity.isReport"
|
||||
:command="{ ...activity, command: 'seeReport' }"
|
||||
>
|
||||
{{ $t('views.seeReport') }}
|
||||
</el-dropdown-item>
|
||||
|
||||
<el-dropdown-item :command="{ ...activity, command: 'zoomIn' }">
|
||||
{{ $t('table.ProcessActivity.zoomIn') }}
|
||||
</el-dropdown-item>
|
||||
|
||||
<!-- TODO: add more actions -->
|
||||
</el-dropdown-menu>
|
||||
</el-dropdown>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<el-form label-position="top">
|
||||
<el-form-item v-if="activity.description" :label="generateTitle('Description')">
|
||||
<span><b>{{ activity.description }}</b></span>
|
||||
<span v-if="activity.isReport">{{ activity.output.description }}</span>
|
||||
<span>
|
||||
<b> {{ activity.description }} </b>
|
||||
</span>
|
||||
|
||||
<span v-if="activity.isReport">
|
||||
{{ activity.output.description }}
|
||||
</span>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item :label="generateTitle('Status')">
|
||||
<!-- show only when it is error -->
|
||||
<el-popover
|
||||
v-if="activity.isError"
|
||||
v-if="activity.isError && !activity.isReport"
|
||||
:key="index + 'is-error'"
|
||||
placement="right"
|
||||
width="300"
|
||||
trigger="click"
|
||||
>
|
||||
<div v-if="!isEmptyValue(activity.summary)">
|
||||
{{ activity.message }}
|
||||
<div v-if="!isEmptyValue(activity.summary)" key="withSummary">
|
||||
{{ activity.summary }}
|
||||
</div>
|
||||
<div v-else>
|
||||
<div v-else key="withoutSummary">
|
||||
{{ $t('route.withoutLog') }}
|
||||
</div>
|
||||
|
||||
<el-tag slot="reference" :type="checkStatus(activity).type">
|
||||
{{ checkStatus(activity).text }}
|
||||
</el-tag>
|
||||
</el-popover>
|
||||
|
||||
<!-- show only when bring logs -->
|
||||
<el-popover
|
||||
v-else-if="activity.panelType === 'process'"
|
||||
v-else-if="!isEmptyValue(activity.logsList) || !isEmptyValue(activity.summary)"
|
||||
:key="index + 'is-summary'"
|
||||
placement="right"
|
||||
:title="$t('table.ProcessActivity.Logs')"
|
||||
width="300"
|
||||
trigger="click"
|
||||
>
|
||||
<b>{{ $t('table.ProcessActivity.Logs') }}</b><br>
|
||||
<ul>
|
||||
<li @click="handleCommand({ ...activity, command: 'zoomIn' })"> {{ activity.summary }} </li>
|
||||
<li @click="handleCommand({ ...activity, command: 'zoomIn' })">
|
||||
{{ activity.summary }}
|
||||
</li>
|
||||
|
||||
<el-scrollbar wrap-class="popover-scroll">
|
||||
<li v-for="(logItem, key) in activity.logsList" :key="key" @click="zoomIn(activity)">
|
||||
{{ logItem.log }}
|
||||
</li>
|
||||
</el-scrollbar>
|
||||
</ul>
|
||||
|
||||
<el-tag slot="reference" :type="checkStatus(activity).type">
|
||||
{{ checkStatus(activity).text }}
|
||||
</el-tag>
|
||||
</el-popover>
|
||||
|
||||
<!-- show only when bring output -->
|
||||
<el-popover
|
||||
v-else-if="activity.panelType === 'report'"
|
||||
v-else-if="activity.isReport"
|
||||
:key="index + 'is-output'"
|
||||
placement="right"
|
||||
:title="$t('table.ProcessActivity.Output')"
|
||||
width="300"
|
||||
trigger="click"
|
||||
>
|
||||
<div v-if="!isEmptyValue(activity.summary)">
|
||||
<span> {{ $t('table.ProcessActivity.Output') }} </span><br>
|
||||
<span>{{ $t('table.ProcessActivity.Name') }}: {{ activity.output.name }}</span><br>
|
||||
<span>{{ $t('table.ProcessActivity.Description') }}: {{ activity.output.description }}</span><br>
|
||||
<span>{{ $t('table.ProcessActivity.FileName') }}: {{ activity.output.fileName }}</span><br>
|
||||
<div v-if="!activity.isError" key="withOutput">
|
||||
<span>
|
||||
{{ $t('table.ProcessActivity.Name') }}: {{ activity.output.name }}
|
||||
</span><br>
|
||||
<span>
|
||||
{{ $t('table.ProcessActivity.Description') }}: {{ activity.output.description }}
|
||||
</span><br>
|
||||
<span>
|
||||
{{ $t('table.ProcessActivity.FileName') }}: {{ activity.output.fileName }}
|
||||
</span><br>
|
||||
<a type="text" :href="activity.url" :download="activity.download">
|
||||
{{ $t('components.contextMenuDownload') }} <i class="el-icon-download" />
|
||||
{{ $t('components.contextMenuDownload') }}
|
||||
<i class="el-icon-download" />
|
||||
</a>
|
||||
</div>
|
||||
<div v-else>
|
||||
{{ $t('route.withoutLog') }}
|
||||
|
||||
<div v-else key="withError">
|
||||
<template v-if="!isEmptyValue(activity.summary)">
|
||||
{{ activity.summary }}
|
||||
</template>
|
||||
<template v-else>
|
||||
{{ $t('route.withoutLog') }}
|
||||
</template>
|
||||
</div>
|
||||
<el-tag slot="reference" :type="checkStatus(activity).type">
|
||||
{{ checkStatus(activity).text }} {{ activity.type }}
|
||||
</el-tag>
|
||||
</el-popover>
|
||||
<el-popover
|
||||
v-else
|
||||
:key="index + 'is-other'"
|
||||
placement="top-start"
|
||||
:title="$t('table.ProcessActivity.Logs')"
|
||||
width="200"
|
||||
trigger="click"
|
||||
:content="activity.summary"
|
||||
>
|
||||
|
||||
<el-tag slot="reference" :type="checkStatus(activity).type">
|
||||
{{ checkStatus(activity).text }}
|
||||
</el-tag>
|
||||
@ -136,20 +161,15 @@
|
||||
</el-timeline-item>
|
||||
</el-timeline>
|
||||
</div>
|
||||
|
||||
<div v-else key="without-process">
|
||||
<h1 class="text-center">{{ $t('views.noProcess') }}</h1>
|
||||
<h1 class="text-center">
|
||||
{{ $t('views.noProcess') }}
|
||||
</h1>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import MixinProcessActivity from './index.vue'
|
||||
|
||||
export default {
|
||||
name: 'ProcessActivity',
|
||||
mixins: [
|
||||
MixinProcessActivity
|
||||
]
|
||||
}
|
||||
<script src="./processActivity.js">
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped src="./processActivityStyle.scss">
|
||||
|
203
src/views/ADempiere/ProcessActivity/processActivity.js
Normal file
203
src/views/ADempiere/ProcessActivity/processActivity.js
Normal file
@ -0,0 +1,203 @@
|
||||
// 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/>.
|
||||
|
||||
import { defineComponent, computed, onMounted, ref } from '@vue/composition-api'
|
||||
|
||||
import { recursiveTreeSearch } from '@/utils/ADempiere/valueUtils.js'
|
||||
|
||||
export default defineComponent({
|
||||
name: 'ProcessActivity',
|
||||
|
||||
setup(props, { root }) {
|
||||
const processActivity = ref([])
|
||||
const recordCount = ref(0)
|
||||
const pageToken = ref('')
|
||||
const pageSize = ref(50)
|
||||
|
||||
// process local is running
|
||||
const getterAllInExecution = computed(() => {
|
||||
return root.$store.getters.getAllInExecution
|
||||
})
|
||||
|
||||
// process local and send with response
|
||||
const getterAllFinishProcess = computed(() => {
|
||||
return root.$store.getters.getAllFinishProcess
|
||||
})
|
||||
|
||||
// session process from server
|
||||
const getterAllSessionProcess = computed(() => {
|
||||
return root.$store.getters.getAllSessionProcess
|
||||
})
|
||||
|
||||
// all process
|
||||
const getRunProcessAll = computed(() => {
|
||||
const processAll = [].concat(
|
||||
getterAllInExecution.value,
|
||||
getterAllFinishProcess.value,
|
||||
getterAllSessionProcess.value
|
||||
)
|
||||
const processAllReturned = []
|
||||
|
||||
processAll.forEach(element => {
|
||||
const processMetadataReturned = {}
|
||||
let infoMetadata = getProcessMetadata(element.processUuid)
|
||||
if (!infoMetadata) {
|
||||
infoMetadata = {}
|
||||
}
|
||||
|
||||
Object.assign(processMetadataReturned, element, infoMetadata)
|
||||
processMetadataReturned.parametersList = element.parametersList
|
||||
const indexRepeat = processAllReturned.findIndex(item => {
|
||||
return item.instanceUuid === element.instanceUuid && !root.isEmptyValue(element.instanceUuid)
|
||||
})
|
||||
|
||||
if (indexRepeat > -1) {
|
||||
// update attributes in exists process to return
|
||||
// Object.assign(processAllReturned[indexRepeat], processMetadataReturned)
|
||||
const other = Object.assign(processMetadataReturned, processAllReturned[indexRepeat])
|
||||
processAllReturned[indexRepeat] = other
|
||||
return
|
||||
}
|
||||
|
||||
// add new process to show
|
||||
processAllReturned.push(processMetadataReturned)
|
||||
})
|
||||
|
||||
return processAllReturned.sort((a, b) => {
|
||||
// sort by most recently date
|
||||
return new Date(b.lastRun) - new Date(a.lastRun)
|
||||
})
|
||||
})
|
||||
|
||||
const getProcessLog = computed(() => {
|
||||
return getRunProcessAll.value.filter(element => {
|
||||
const { isError, isProcessing } = element
|
||||
if (!root.isEmptyValue(isError) && !root.isEmptyValue(isProcessing)) {
|
||||
return element
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
const language = computed(() => {
|
||||
return root.$store.getters.language
|
||||
})
|
||||
|
||||
const permissionRoutes = computed(() => {
|
||||
return root.$store.getters.permission_routes
|
||||
})
|
||||
|
||||
onMounted(() => {
|
||||
root.$store.dispatch('getSessionProcessFromServer', {
|
||||
pageToken: pageToken.value,
|
||||
pageSize: pageSize.value
|
||||
})
|
||||
.then(response => {
|
||||
pageToken.value = response.nextPageToken
|
||||
})
|
||||
})
|
||||
|
||||
const getProcessMetadata = (uuid) => {
|
||||
return root.$store.getters.getProcess(uuid)
|
||||
}
|
||||
|
||||
const handleCommand = (activity) => {
|
||||
if (activity.command === 'seeReport') {
|
||||
root.$router.push({
|
||||
name: 'Report Viewer',
|
||||
params: {
|
||||
processId: activity.processId,
|
||||
instanceUuid: activity.instanceUuid,
|
||||
fileName: activity.output.fileName
|
||||
}
|
||||
}, () => {})
|
||||
} else if (activity.command === 'zoomIn') {
|
||||
const viewSearch = recursiveTreeSearch({
|
||||
treeData: permissionRoutes.value,
|
||||
attributeValue: activity.uuid,
|
||||
attributeName: 'meta',
|
||||
secondAttribute: 'uuid',
|
||||
attributeChilds: 'children'
|
||||
})
|
||||
|
||||
if (viewSearch) {
|
||||
root.$router.push({
|
||||
name: viewSearch.name,
|
||||
query: {
|
||||
...root.$route.query,
|
||||
...activity.parametersList
|
||||
}
|
||||
}, () => {})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const checkStatus = ({ isError, isProcessing, isReport }) => {
|
||||
const status = {
|
||||
text: root.$t('notifications.completed'),
|
||||
type: 'success',
|
||||
color: '#67C23A'
|
||||
}
|
||||
// is executing
|
||||
if (isProcessing) {
|
||||
status.text = root.$t('notifications.processing')
|
||||
status.type = 'info'
|
||||
status.color = '#909399'
|
||||
return status
|
||||
}
|
||||
// is with error
|
||||
if (isError) {
|
||||
status.text = root.$t('notifications.error')
|
||||
status.type = 'danger'
|
||||
status.color = '#F56C6C'
|
||||
return status
|
||||
}
|
||||
// is completed
|
||||
return status
|
||||
}
|
||||
|
||||
const generateTitle = (title) => {
|
||||
const hasKey = root.$te('table.ProcessActivity.' + title)
|
||||
if (hasKey) {
|
||||
// $t : this method from vue-i18n, inject in @/lang/index.js
|
||||
const translatedTitle = root.$t('table.ProcessActivity.' + title)
|
||||
return translatedTitle
|
||||
}
|
||||
return title
|
||||
}
|
||||
|
||||
const translateDate = (value) => {
|
||||
return root.$d(new Date(value), 'long', language.value)
|
||||
}
|
||||
|
||||
return {
|
||||
processActivity,
|
||||
recordCount,
|
||||
pageToken,
|
||||
pageSize,
|
||||
// computeds
|
||||
getRunProcessAll,
|
||||
getProcessLog,
|
||||
language,
|
||||
permissionRoutes,
|
||||
// methods
|
||||
getProcessMetadata,
|
||||
handleCommand,
|
||||
checkStatus,
|
||||
generateTitle,
|
||||
translateDate
|
||||
}
|
||||
}
|
||||
})
|
Loading…
x
Reference in New Issue
Block a user