Support record Log of container info (#266)

* creating structure for the service

* structure container info

* waiting for service

* service test

* Support record Log of container info

* style of the option Change Detail

* Text formats

* add color to event type

* Add Disable of textLong

* change style text long
pull/3759/head
elsiosanchez 2020-01-27 11:00:34 -04:00 committed by Yamel Senih
parent 44940dee0e
commit b9cc5ff276
7 changed files with 512 additions and 133 deletions

View File

@ -1,5 +1,5 @@
<template>
<div :id="id" />
<div :id="id" :class="classDisable" />
</template>
<script>
@ -32,6 +32,12 @@ export default {
}
},
computed: {
classDisable() {
if (this.isDisabled) {
return 'isdisable'
}
return ''
},
language() {
// https://github.com/nhnent/tui.editor/tree/master/src/js/langs
if (this.isEmptyValue(getLanguage())) {
@ -98,6 +104,7 @@ export default {
this.editor.height(heightValue)
},
isDisabled(value) {
this.classDisable
this.destroyEditor()
this.initEditor()
}
@ -164,3 +171,8 @@ export default {
}
}
</script>
<style>
.isdisable {
background: #F5F7FA;
}
</style>

View File

@ -268,7 +268,21 @@ export default {
window: {
newRecord: 'New Record',
deleteRecord: 'Delete Record',
undoNew: 'Undo New Record'
undoNew: 'Undo New Record',
containerInfo: {
notes: 'Notes',
changeLog: 'Change Log',
workflowLog: 'Workflow Log',
changeDetail: 'Detalle del cambio',
eventType: {
insert: 'Insert',
update: 'Update',
delete: 'Delete',
field: 'The Fiel',
newValue: 'New Value',
oldValue: 'Old Value'
}
}
},
data: {
emtpyTableName: 'Error: Table Name is not defined',

View File

@ -243,7 +243,21 @@ export default {
window: {
newRecord: 'Nuevo Registro',
deleteRecord: 'Eliminar Registro',
undoNew: 'Descartar Nuevo Registro'
undoNew: 'Descartar Nuevo Registro',
containerInfo: {
notes: 'Notas',
changeLog: 'Histórico de Cambios',
workflowLog: 'Histórico de Flujo de Trabajo',
changeDetail: 'Detalle del cambio',
eventType: {
insert: 'Se Creo',
update: 'Se Actualizo',
delete: 'Eliminar',
field: 'El Campo',
newValue: 'Nuevo Valor',
oldValue: 'Antiguo Valor'
}
}
},
data: {
emtpyTableName: 'Error: El nombre de la tabla no esta definida',

View File

@ -0,0 +1,140 @@
import { requestListRecordsLogs, requestListWorkflowsLogs, requestListRecordChats, requestListChatEntries } from '@/api/ADempiere/data'
import { isEmptyValue } from '@/utils/ADempiere/valueUtils'
const containerInfo = {
state: {
listworkflowLog: [],
listRecordLogs: [],
listRecordChats: [],
listChatEntries: []
},
mutations: {
addListWorkflow(state, payload) {
state.listworkflowLog = payload
},
addListRecordLogs(state, payload) {
state.listRecordLogs = payload
},
addListRecordChats(state, payload) {
state.listRecordChats = payload
},
addListChatEntries(state, payload) {
state.listChatEntries = payload
}
},
actions: {
listWorkflowLogs({ commit, state }, params) {
const tableName = params.tableName
const recordId = params.recordId
const page_size = 0
const page_token = 0
return requestListWorkflowsLogs({ tableName, recordId, page_size, page_token })
.then(response => {
commit('addListWorkflow', response)
})
.catch(error => {
console.warn(`Error getting List workflow: ${error.message}. Code: ${error.code}.`)
})
},
listRecordLogs({ commit, state }, params) {
const tableName = params.tableName
const recordId = params.recordId
const page_size = 0
const page_token = 0
return requestListRecordsLogs({ tableName, recordId, page_size, page_token })
.then(response => {
var listRecord = {
recordCount: response.recordCount,
recorLogs: response.recordLogsList
}
commit('addListRecordLogs', listRecord)
})
.catch(error => {
console.warn(`Error getting List Record Logs: ${error.message}. Code: ${error.code}.`)
})
},
listChatEntries({ commit, state }, params) {
const tableName = params.tableName
const recordId = params.recordId
const page_size = 0
const page_token = 0
return requestListRecordChats({ tableName, recordId, page_size, page_token })
.then(response => {
console.log('requestListRecordChats response =>', response)
commit('addListChatEntries', response)
})
.catch(error => {
console.warn(`Error getting List Chat: ${error.message}. Code: ${error.code}.`)
})
},
listRecordChat({ commit, state }, params) {
const uuid = params.uuid
const page_size = 0
const page_token = 0
return requestListChatEntries({ uuid, page_size, page_token })
.then(response => {
console.log('requestListChatEntries response =>', response)
commit('addListChatEntries', response)
})
.catch(error => {
console.warn(`Error getting List Chat: ${error.message}. Code: ${error.code}.`)
})
}
},
getters: {
getWorkflow: (state) => {
return state.listworkflowLog.workflowLogsList
},
getRecordLogs: (state) => {
const recordLogs = state.listRecordLogs.recorLogs
if (isEmptyValue(recordLogs)) {
var listRecord = [{
columnName: 'Compañía',
description: 'Compañía',
displayColumnName: 'Compañía',
eventType: 0,
eventTypeName: 'INSERT',
logDate: 0,
logUuid: 'e0c976cc-b49e-40fd-b52b-f2f5020436f6',
newDisplayValue: '',
newValue: '',
oldDisplayValue: '',
oldValue: '',
recordId: 100000,
sessionUuid: '',
tableName: '',
transactionName: '',
userName: '',
userUuid: ''
},
{
columnName: 'Compañía',
description: 'Compañía',
displayColumnName: 'Compañía',
eventType: 0,
eventTypeName: 'INSERT',
logDate: 0,
logUuid: 'e0c976cc-b49e-40fd-b52b-f2f5020436f6',
newDisplayValue: '',
newValue: '',
oldDisplayValue: '',
oldValue: '',
recordId: 100000,
sessionUuid: '',
tableName: '',
transactionName: '',
userName: '',
userUuid: ''
}]
return listRecord
} else {
return state.listRecordLogs
}
},
getChatEntries: (state) => {
return state.listChatEntries
}
}
}
export default containerInfo

View File

@ -13,7 +13,8 @@ const utils = {
recordUuidTable: 0,
isShowedTabChildren: false,
recordTable: 0,
selectionProcess: []
selectionProcess: [],
isContainerInfo: false
},
mutations: {
setWidth(state, width) {
@ -31,6 +32,9 @@ const utils = {
showMenuTable(state, isShowedTable) {
state.isShowedTable = isShowedTable
},
showContainerInfo(state, isContainerInfo) {
state.isContainerInfo = isContainerInfo
},
showMenuTabChildren(state, isShowedTabChildren) {
state.isShowedTabChildren = isShowedTabChildren
},
@ -66,6 +70,9 @@ const utils = {
showMenuTable({ commit }, isShowedTable) {
commit('showMenuTable', isShowedTable)
},
showContainerInfo({ commit, state }, isContainerInfo) {
commit('showContainerInfo', isContainerInfo)
},
showMenuTabChildren({ commit }, isShowedTabChildren) {
commit('showMenuTabChildren', isShowedTabChildren)
},
@ -126,6 +133,10 @@ const utils = {
const menu = state.isShowedTable.isShowedTable
return menu
},
getShowContainerInfo: (state) => {
const showInfo = state.isContainerInfo
return showInfo
},
getShowContextMenuTabChildren: (state) => {
const menu = state.isShowedTabChildren.isShowedTabChildren
return menu

View File

@ -275,7 +275,12 @@ const windowControl = {
}
return true
})
// if (rootGetters.getShowContainerInfo) {
// dispatch('listRecordLogs', {
// tableName: panel.tableName,
// recordId
// })
// }
return updateEntity({
tableName: panel.tableName,
recordUuid,
@ -283,7 +288,6 @@ const windowControl = {
})
.then(updateEntityResponse => {
const newValues = updateEntityResponse.values
// set data log to undo action
// TODO: Verify performance with tableName_ID
let recordId = updateEntityResponse.id
@ -309,7 +313,12 @@ const windowControl = {
recordUuid,
eventType: 'UPDATE'
})
// if (containerInfo) {
dispatch('listRecordLogs', {
tableName: panel.tableName,
recordId
})
// }
return newValues
})
.catch(error => {

View File

@ -4,139 +4,217 @@
key="window-loaded"
>
<el-container style="height: 86vh;">
<el-main>
<split-pane :min-percent="10" :default-percent="defaultPorcentSplitPane" split="vertical">
<template>
<!-- this slot is 'paneL' (with 'L' in uppercase) do not change -->
<div slot="paneL" class="left-container">
<el-aside v-show="isShowedRecordNavigation" width="100%">
<div class="small-4 columns">
<div class="w">
<div class="open-left" />
<div class="open-datatable-aside">
<el-button
v-show="!isPanel"
:icon="iconIsShowedRecordNavigation"
circle
style="margin-left: 10px;"
@click="handleChangeShowedRecordNavigation()"
/>
<el-button
v-show="!isPanel"
:icon="iconIsShowedAside"
circle
@click="handleChangeShowedPanel()"
/>
</div>
<data-table
:parent-uuid="windowUuid"
:container-uuid="windowMetadata.currentTab.uuid"
:table-name="windowMetadata.currentTab.tableName"
:is-showed-panel-record="true"
:is-parent="true"
/>
<div class="close-datatable">
<el-button
v-show="isPanel"
icon="el-icon-caret-left"
circle
@click="handleChangeShowedPanel()"
/>
</div>
</div>
</div>
<i
v-if="isMobile"
class="el-icon-close"
style="position: fixed;padding-top: 15px; color: #000000;font-size: 121%;font-weight: 615!important;padding-left: 9px;"
@click="handleChangeShowedRecordNavigation()"
/>
</el-aside>
</div>
</template>
<template slot="paneR">
<el-container style="height: 86vh;">
<Split v-shortkey="['f8']" direction="vertical" @onDrag="onDrag" @shortkey.native="handleChangeShowedRecordNavigation">
<SplitArea :size="sizeAreaStyle" :style="splitAreaStyle">
<el-header style="height: 39px;">
<context-menu
v-show="!isShowedRecordPanel"
:menu-parent-uuid="$route.meta.parentUuid"
:parent-uuid="windowUuid"
:container-uuid="windowMetadata.currentTabUuid"
:panel-type="panelType"
:is-insert-record="getterIsInsertRecord"
/>
</el-header>
<!-- das -->
<el-main :style="styleMainIsShowedTabChildren">
<tab-parent
:window-uuid="windowUuid"
:tabs-list="windowMetadata.tabsListParent"
class="tab-window"
/>
<div class="small-4 columns">
<div class="wrapper">
<div
v-show="windowMetadata.tabsListChildren && windowMetadata.tabsListChildren.length"
class="open-detail"
/>
<el-button
v-if="windowMetadata.tabsListChildren && windowMetadata.tabsListChildren.length &&
(isMobile && !isShowedRecordNavigation || !isMobile)"
v-show="!isShowedTabChildren"
icon="el-icon-caret-top"
:class="classIsMobile"
circle
@click="handleChangeShowedTabChildren()"
/>
</div>
</div>
<modal-dialog
:parent-uuid="windowUuid"
:container-uuid="windowMetadata.currentTabUuid"
/>
<Split>
<SplitArea :size="!show ? 100 : 70" :min-size="100">
<el-aside width="100%">
<split-pane :min-percent="10" :default-percent="defaultPorcentSplitPane" split="vertical">
<template>
<!-- this slot is 'paneL' (with 'L' in uppercase) do not change -->
<div slot="paneL" class="left-container">
<el-aside v-show="isShowedRecordNavigation" width="100%">
<div class="small-4 columns">
<div class="w">
<div class="open-left" />
<el-button
v-show="!isShowedRecordNavigation"
:icon="iconIsShowedRecordNavigation"
class="open-navegation"
circle
@click="handleChangeShowedRecordNavigation()"
<div class="open-datatable-aside">
<el-button
v-show="!isPanel"
:icon="iconIsShowedRecordNavigation"
circle
style="margin-left: 10px;"
@click="handleChangeShowedRecordNavigation()"
/>
<el-button
v-show="!isPanel"
:icon="iconIsShowedAside"
circle
@click="handleChangeShowedPanel()"
/>
</div>
<data-table
:parent-uuid="windowUuid"
:container-uuid="windowMetadata.currentTab.uuid"
:table-name="windowMetadata.currentTab.tableName"
:is-showed-panel-record="true"
:is-parent="true"
/>
<div class="close-datatable">
<el-button
v-show="isPanel"
icon="el-icon-caret-left"
circle
@click="handleChangeShowedPanel()"
/>
</div>
</div>
</div>
</el-main>
</SplitArea>
<SplitArea v-show="isShowedTabChildren" :size="50">
<el-header
v-if="isShowedTabChildren && windowMetadata.tabsListChildren && windowMetadata.tabsListChildren.length"
style="height: auto; padding-right: 35px !important;padding-bottom: 33px;"
>
<div class="w-33">
<div class="center">
<el-button
icon="el-icon-caret-bottom"
circle
@click="handleChangeShowedTabChildren()"
/>
</div>
</div>
<tab-children
:window-uuid="windowUuid"
:tabs-list="windowMetadata.tabsListChildren"
:first-tab-uuid="windowMetadata.firstTabUuid"
:style="{ 'height': getHeightPanelBottom + 'vh' }"
<i
v-if="isMobile"
class="el-icon-close"
style="position: fixed;padding-top: 15px; color: #000000;font-size: 121%;font-weight: 615!important;padding-left: 9px;"
@click="handleChangeShowedRecordNavigation()"
/>
</el-header>
</SplitArea>
</Split>
</el-container>
</template>
</split-pane>
</el-main>
</el-aside>
</div>
</template>
<template slot="paneR">
<el-container style="height: 86vh;">
<Split v-shortkey="['f8']" direction="vertical" @onDrag="onDrag" @shortkey.native="handleChangeShowedRecordNavigation">
<SplitArea :size="sizeAreaStyle" :style="splitAreaStyle">
<el-header style="height: 39px;">
<context-menu
v-show="!isShowedRecordPanel"
:menu-parent-uuid="$route.meta.parentUuid"
:parent-uuid="windowUuid"
:container-uuid="windowMetadata.currentTabUuid"
:panel-type="panelType"
:is-insert-record="getterIsInsertRecord"
/>
</el-header>
<el-main :style="styleMainIsShowedTabChildren">
<tab-parent
:window-uuid="windowUuid"
:tabs-list="windowMetadata.tabsListParent"
class="tab-window"
/>
<div style="right: 0%;top: 40%;position: absolute;">
<el-button v-show="!show" type="info" icon="el-icon-info" circle style="float: right;" @click="conteInfo" />
</div>
<div class="small-4 columns">
<div class="wrapper">
<div
v-show="windowMetadata.tabsListChildren && windowMetadata.tabsListChildren.length"
class="open-detail"
/>
<el-button
v-if="windowMetadata.tabsListChildren && windowMetadata.tabsListChildren.length &&
(isMobile && !isShowedRecordNavigation || !isMobile)"
v-show="!isShowedTabChildren"
icon="el-icon-caret-top"
:class="classIsMobile"
circle
@click="handleChangeShowedTabChildren()"
/>
</div>
</div>
<modal-dialog
:parent-uuid="windowUuid"
:container-uuid="windowMetadata.currentTabUuid"
/>
<div class="small-4 columns">
<div class="w">
<div class="open-left" />
<el-button
v-show="!isShowedRecordNavigation"
:icon="iconIsShowedRecordNavigation"
class="open-navegation"
circle
@click="handleChangeShowedRecordNavigation()"
/>
</div>
</div>
</el-main>
</SplitArea>
<SplitArea v-show="isShowedTabChildren" :size="50">
<el-header
v-if="isShowedTabChildren && windowMetadata.tabsListChildren && windowMetadata.tabsListChildren.length"
style="height: auto; padding-right: 35px !important;padding-bottom: 33px;"
>
<div class="w-33">
<div class="center">
<el-button
icon="el-icon-caret-bottom"
circle
@click="handleChangeShowedTabChildren()"
/>
</div>
</div>
<tab-children
:window-uuid="windowUuid"
:tabs-list="windowMetadata.tabsListChildren"
:first-tab-uuid="windowMetadata.firstTabUuid"
:style="{ 'height': getHeightPanelBottom + 'vh' }"
/>
</el-header>
</SplitArea>
</Split>
</el-container>
</template>
</split-pane>
</el-aside>
</SplitArea>
<SplitArea :size="show ? 30 : 0">
<el-main>
<div style="top: 40%;position: absolute;">
<el-button v-show="show" type="info" icon="el-icon-info" circle style="float: right;" @click="conteInfo" />
</div>
<div id="example-1">
<transition name="slide-fade">
<p v-if="show">
<el-card class="box-card">
<el-tabs v-model="activeName" @tab-click="handleClick">
<el-tab-pane
:label="$t('window.containerInfo.changeLog')"
name="listRecordLogs"
style="overflow: auto;max-height: 74vh;"
>
<span slot="label"><svg-icon icon-class="tree-table" /> {{ $t('window.containerInfo.changeLog') }} </span>
<el-card
v-for="(listLogs, index) in getTypeLogs"
:key="index"
>
<el-timeline>
<el-timeline-item
v-for="(evenType, key) in listLogs.logs"
:key="key"
:timestamp="translateDate(evenType.logDate)"
placement="top"
:color="listLogs.eventTypeName === 'UPDATE' ? 'rgb(22, 130, 230)' : '#52c384'"
>
<el-card shadow="hover" @click.native="changeField(evenType)">
<div>
<span>{{ evenType.userName }}</span>
<el-dropdown style="float: right;">
<span class="el-dropdown-link" style="color: #1682e6" @click="showkey(key)">
{{ $t('window.containerInfo.changeDetail') }}
</span>
</el-dropdown>
</div>
<br>
<el-collapse-transition>
<div v-show="currentKey === key" :key="key" class="text item">
<span><p><b><i> {{ evenType.displayColumnName }}: </i></b> <strike>{{ evenType.oldDisplayValue }} </strike> {{ evenType.newDisplayValue }}</p></span>
</div>
</el-collapse-transition>
</el-card>
</el-timeline-item>
</el-timeline>
</el-card>
</el-tab-pane>
<el-tab-pane
name="listWorkflowLogs"
>
<span slot="label"><i class="el-icon-s-help" /> {{ $t('window.containerInfo.workflowLog') }} </span>
<el-card
class="box-card"
style="overflow: auto;height: 50vh;"
>
{{ gettersrecorCount }}
</el-card>
</el-tab-pane>
<el-tab-pane
name="listChatEntries"
>
<span slot="label"><i class="el-icon-s-comment" /> {{ $t('window.containerInfo.notes') }} </span>
</el-tab-pane>
</el-tabs>
</el-card>
</p>
</transition>
</div>
</el-main>
</SplitArea>
</Split>
</el-container>
</div>
<div
@ -177,14 +255,19 @@ export default {
panelType: 'window',
isLoaded: false,
isPanel: false,
activeName: 'listRecordLogs',
show: false,
isLoadingFromServer: false,
listRecordNavigation: 0,
show3: false,
currentKey: 100,
isShowedTabChildren: true,
isShowedRecordPanel: false,
isShowedRecordNavigation: this.$route.query.action === 'advancedQuery'
}
},
beforeRouteUpdate(to, from, next) {
// this.activeName = this.$t('window.containerInfo.changeLog')
this.$store.dispatch('setWindowOldRoute', {
path: from.path,
fullPath: from.fullPath,
@ -279,6 +362,37 @@ export default {
return tab.isInsertRecord
}
return false
},
gettersListRecordLogs() {
return this.$store.getters.getRecordLogs.recorLogs
},
getTypeLogs() {
const reducer = this.gettersListRecordLogs.reduce((reducer, item) => {
if (!reducer.includes(item.eventTypeName)) {
reducer.push(item.eventTypeName)
}
return reducer
}, [])
.map(i => {
// agrup for logId
return {
logs: this.gettersListRecordLogs.filter(b => b.eventTypeName === i),
eventTypeName: i
}
})
return reducer
},
gettersListWorkflow() {
return this.$store.getters.getWorkflow
},
gettersrecorCount() {
return 1
},
language() {
return this.$store.getters.language
},
getterShowContainerInfo() {
return this.$store.getters.getShowContainerInfo
}
},
watch: {
@ -292,6 +406,58 @@ export default {
this.getWindow()
},
methods: {
showkey(key) {
if (key === this.currentKey) {
this.currentKey = 1000
} else {
this.currentKey = key
}
this.show3 = !this.show3
},
changeField(log) {
this.$store.dispatch('notifyPanelChange', {
newValues: log.oldDisplayValue,
isSendToServer: false,
isSendCallout: false,
isPrivateAccess: false
})
},
translateDate(value) {
return this.$d(new Date(value), 'long', this.language)
},
conteInfo() {
this.show = !this.show
this.$store.dispatch('listRecordChat', {
uuid: this.$route.query.action
})
this.$store.dispatch('listChatEntries', {
tableName: this.$route.params.tableName,
recordId: this.$route.params.recordId
})
this.$store.dispatch('showContainerInfo', !this.getterShowContainerInfo)
if (this.show) {
this.$store.dispatch('listRecordLogs', {
tableName: this.$route.params.tableName,
recordId: this.$route.params.recordId
})
}
},
handleClick(tab, event) {
if (tab.name === 'listChatEntries') {
this.$store.dispatch('listRecordChat', {
uuid: this.$route.query.action
})
this.$store.dispatch(tab.name, {
tableName: this.$route.params.tableName,
recordId: this.$route.params.recordId
})
} else {
this.$store.dispatch(tab.name, {
tableName: this.$route.params.tableName,
recordId: this.$route.params.recordId
})
}
},
// callback new size
onDrag(size) {
var bottomPanel = size[1]
@ -373,6 +539,19 @@ export default {
</script>
<style scoped>
/* Enter and leave animations can use different */
/* durations and timing functions. */
.slide-fade-enter-active {
transition: all .2s ease;
}
.slide-fade-leave-active {
transition: all .3s cubic-bezier(1.0, 0.5, 0.8, 1.0);
}
.slide-fade-enter, .slide-fade-leave-to
/* .slide-fade-leave-active below version 2.1.8 */ {
transform: translateX(10px);
opacity: 0;
}
.el-tabs__content {
overflow: hidden;
position: relative;