From d8ee1b8f7bd47c597193d83f13760a481b87d64d Mon Sep 17 00:00:00 2001 From: Edwin Betancourt Date: Tue, 16 Feb 2021 14:07:37 -0400 Subject: [PATCH] fix: Error window loading record undefined. (#585) Co-authored-by: EdwinBetanc0urt --- src/views/ADempiere/Window/index.vue | 703 +----------------- .../ADempiere/Window/windowLogicComponent.js | 462 ++++++++++++ .../ADempiere/Window/windowStyleGlobal.scss | 81 ++ .../ADempiere/Window/windowStyleScoped.scss | 164 ++++ 4 files changed, 715 insertions(+), 695 deletions(-) create mode 100644 src/views/ADempiere/Window/windowLogicComponent.js create mode 100644 src/views/ADempiere/Window/windowStyleGlobal.scss create mode 100644 src/views/ADempiere/Window/windowStyleScoped.scss diff --git a/src/views/ADempiere/Window/index.vue b/src/views/ADempiere/Window/index.vue index 73c780e3..94c9a3ff 100644 --- a/src/views/ADempiere/Window/index.vue +++ b/src/views/ADempiere/Window/index.vue @@ -297,702 +297,15 @@ /> - - - diff --git a/src/views/ADempiere/Window/windowLogicComponent.js b/src/views/ADempiere/Window/windowLogicComponent.js new file mode 100644 index 00000000..403db8ef --- /dev/null +++ b/src/views/ADempiere/Window/windowLogicComponent.js @@ -0,0 +1,462 @@ + +import TabParent from '@/components/ADempiere/Tab' +import TabChildren from '@/components/ADempiere/Tab/tabChildren' +// When supporting the processes, smart browser and reports, +// the submenu and sticky must be placed in the layout +import ContextMenu from '@/components/ADempiere/ContextMenu' +import ModalDialog from '@/components/ADempiere/Dialog' +import DataTable from '@/components/ADempiere/DataTable' +import splitPane from 'vue-splitpane' +// Container Info +import ChatEntries from '@/components/ADempiere/ChatEntries' +import RecordLogs from '@/components/ADempiere/ContainerInfo/recordLogs' +import WorkflowLogs from '@/components/ADempiere/ContainerInfo/workflowLogs' +// Workflow +import WorkflowStatusBar from '@/components/ADempiere/WorkflowStatusBar' + +/** + * Window Logic Component View + * Build and show window, tab and records view, generates with + * metadata from adempiere dictionary aplication. + * @author Edwin Betancourt + * TODO: Add manage record change and set with common method + */ +export default { + name: 'WindowView', + components: { + TabParent, + TabChildren, + ContextMenu, + DataTable, + splitPane, + ModalDialog, + ChatEntries, + RecordLogs, + WorkflowLogs, + WorkflowStatusBar + }, + beforeRouteUpdate(to, from, next) { + this.$store.dispatch('setWindowOldRoute', { + path: from.path, + fullPath: from.fullPath, + params: { + ...from.params + }, + query: { + ...from.query + } + }) + next() + }, + props: { + styleSteps: { + type: Object, + default: () => {} + } + }, + data() { + return { + windowMetadata: {}, + windowUuid: this.$route.meta.uuid, + panelType: 'window', + isLoaded: false, + // TODO: Manage attribute with store + activeInfo: 'listChatEntries', + showContainerInfo: false, + // TODO: Manage attribute with store + isShowedRecordPanel: false + } + }, + computed: { + showContextMenu() { + return this.$store.state.settings.showContextMenu + }, + defaultPorcentSplitPane() { + if (this.isShowedRecordPanel) { + if (this.isShowedRecordNavigation) { + return 100 + } + return 50 + } + if (this.isShowedRecordNavigation) { + if (this.isMobile) { + return 100 + } + return 50 + } + return -1 + }, + isMobile() { + return this.$store.state.app.device === 'mobile' + }, + // convert ternary operator into computed property + classIsMobile() { + if (this.isMobile) { + return 'open-table-detail-mobile' + } + return 'open-table-detail' + }, + isSize() { + if (this.isMobile && this.showContainerInfo) { + return 98 + } + return 50 + }, + sizePanel() { + if (this.showContainerInfo) { + if (this.isMobile) { + return 2 + } + return 50 + } + return 100 + }, + isCloseInfo() { + if (this.isMobile) { + return 'close-info-mobile' + } + return 'close-info' + }, + iconShowedRecordNavigation() { + if (this.isShowedRecordNavigation) { + return 'el-icon-caret-left' + } + return 'el-icon-caret-right' + }, + iconIsShowedAside() { + if (this.isShowedRecordPanel) { + return 'el-icon-caret-left' + } + return 'el-icon-caret-right' + }, + styleMainTab() { + if (this.isShowedTabsChildren) { + return { + height: 'initial', + overflow: 'auto' + } + } + return { + height: 'initial', + overflow: 'hidden' + } + }, + styleTableNavigation() { + if (this.isShowedRecordNavigation && this.isMobile) { + return 'open-datatable-aside-mobile' + } + return 'open-datatable-aside' + }, + splitAreaStyle() { + if (this.isShowedTabsChildren || this.isMobile) { + return { + overflowX: 'hidden', + overflowY: 'auto' + } + } + return { + overflow: 'hidden' + } + }, + styleStepsSimple() { + const baseStyle = { + paddingTop: '0px', + paddingBottom: '0px', + paddingLeft: '0px', + paddingRight: '0px', + borderRadius: '4px', + background: '#F5F7FA', + overflowX: 'auto', + overflowY: 'hidden' + } + if (this.isShowedRecordNavigation) { + return { + ...baseStyle, + width: this.$store.getters.getPanelRight + 'px' + } + } + return { + ...baseStyle, + width: 'auto' + } + }, + sizeAreaStyle() { + if (this.isShowedTabsChildren) { + return 50 + } + return 110 + }, + getterWindow() { + return this.$store.getters.getWindow(this.windowUuid) + }, + isShowedTabsChildren() { + if (this.windowMetadata && this.windowMetadata.isShowedTabsChildren) { + return this.windowMetadata.isShowedTabsChildren + } + return false + }, + isShowedRecordNavigation() { + if (this.windowMetadata && this.windowMetadata.isShowedRecordNavigation) { + return this.windowMetadata.isShowedRecordNavigation + } + return false + }, + getHeightPanelBottom() { + return this.$store.getters.getSplitHeight - 11 + }, + getterRecordList() { + return this.$store.getters.getDataRecordsList(this.windowMetadata.currentTabUuid).length + }, + gettersListRecordLogs() { + const changeLog = this.$store.getters.getRecordLogs.entityLogs + if (this.isEmptyValue(changeLog)) { + return changeLog + } + // TODO: Verify it, parse date value + changeLog.sort((a, b) => { + const c = new Date(a.logDate) + const d = new Date(b.logDate) + return d - c + }) + return changeLog + }, + getIsChangeLog() { + if (this.isEmptyValue(this.gettersListRecordLogs)) { + return false + } + return true + }, + getIsWorkflowLog() { + if (this.isEmptyValue(this.$store.getters.getNodeWorkflow)) { + return false + } + return true + }, + getterShowContainerInfo() { + return this.$store.getters.getShowContainerInfo + }, + getterDataRecordsAndSelection() { + return this.$store.getters.getDataRecordAndSelection(this.windowMetadata.firstTabUuid) + }, + getterDataRecords() { + return this.getterDataRecordsAndSelection.record + }, + getTableName() { + if (this.windowMetadata && this.windowMetadata.firstTab.tableName) { + return this.windowMetadata.firstTab.tableName + } + return undefined + }, + // current record + getRecord() { + const { action } = this.$route.query + if (!this.isEmptyValue(action) && action !== 'create-new') { + return this.getterDataRecords.find(record => { + return record.UUID === action + }) + } + return undefined + }, + recordId() { + const currentRecord = this.getRecord + if (this.isEmptyValue(currentRecord)) { + return undefined + } + return currentRecord[`${this.getTableName}_ID`] + }, + currentRecord() { + const currentRecord = this.$store.getters.getCurrentRecord + if (this.isEmptyValue(currentRecord)) { + return this.getterDataRecords[0] + } + return currentRecord + }, + isDocument() { + const panel = this.$store.getters.getPanel(this.windowMetadata.currentTabUuid) + return panel.isDocument + }, + isWorkflowBarStatus() { + const panel = this.$store.getters.getPanel(this.windowMetadata.currentTabUuid) + if (!this.isEmptyValue(panel) && this.isDocument && this.$route.query.action !== 'create-new') { + return true + } + return false + } + }, + watch: { + $route(value) { + if (this.showContainerInfo) { + this.$store.dispatch(this.activeInfo, { + tableName: this.$route.params.tableName, + recordId: this.$route.params.recordId + }) + .then(response => { + if (value.query.action === 'create-new') { + this.$store.commit('isNote', false) + } + }) + } + } + }, + created() { + this.getWindow() + if (this.isShowedRecordNavigation) { + this.handleResize() + } + this.$store.dispatch('settings/changeSetting', { + key: 'showContextMenu', + value: true + }) + }, + methods: { + handleResize() { + const panelRight = document.getElementById('PanelRight') + if (!this.isEmptyValue(panelRight)) { + const widthPanel = panelRight.clientWidth - 350 + this.$store.commit('setPanelRight', widthPanel) + } + }, + contentInfo() { + this.showContainerInfo = !this.showContainerInfo + if (this.showContainerInfo) { + let tableName = this.$route.params.tableName + if (this.isEmptyValue(tableName)) { + tableName = this.getTableName + } + + const record = this.currentRecord + let recordId + if (!this.isEmptyValue(record)) { + recordId = record[tableName + '_ID'] + } + this.$router.push({ + params: { + recordId, + tableName + }, + query: { + ...this.$route.query + } + }, () => {}) + + const action = this.$route.query.action + let recordUuid + if (!this.isEmptyValue(action) && action !== 'create-new') { + recordUuid = action + } + + // TODO: Verify if first tab is document + this.$store.dispatch('listWorkflowLogs', { + tableName, + recordUuid, + recordId + }) + this.$store.dispatch(this.activeInfo, { + tableName, + recordId, + recordUuid + }) + } + this.$store.dispatch('showContainerInfo', !this.getterShowContainerInfo) + }, + handleClick(tab, event) { + let tableName = this.$route.params.tableName + if (this.isEmptyValue(tableName)) { + tableName = this.getTableName + } + + const action = this.$route.query.action + let recordUuid + if (!this.isEmptyValue(action) && action !== 'create-new') { + recordUuid = action + } + + const record = this.currentRecord + let recordId + if (!this.isEmptyValue(record)) { + recordId = record[tableName + '_ID'] + } + + this.$store.dispatch(tab.name, { + tableName, + recordId, + recordUuid + }) + }, + // callback new size + onDrag(size) { + this.$store.dispatch('setSplitHeightTop', { + splitHeightTop: size[0] + }) + this.$store.dispatch('setSplitHeight', { + splitHeight: size[1] + }) + }, + // get window from vuex store or server + getWindow() { + const window = this.getterWindow + if (window) { + this.generateWindow(window) + return + } + this.$store.dispatch('getWindowFromServer', { + windowUuid: this.windowUuid, + routeToDelete: this.$route + }) + .then(response => { + this.generateWindow(response) + }) + }, + generateWindow(window) { + this.windowMetadata = window + let isShowRecords = this.isShowedRecordNavigation + if (isShowRecords === undefined) { + if ((['M', 'Q'].includes(this.windowMetadata.windowType) && this.getterRecordList >= 10 && this.$route.query.action !== 'create-new') || + this.$route.query.action === 'advancedQuery') { + isShowRecords = true + } else if (this.windowMetadata.windowType === 'T' || this.$route.query.action === 'create-new') { + isShowRecords = false + } else if (this.$route.query.action === 'listRecords') { + isShowRecords = true + this.handleChangeShowedPanel(true) + } + this.handleChangeShowedRecordNavigation(isShowRecords) + } + this.isLoaded = true + + const record = this.currentRecord + const tableName = this.getTableName + let recordId + if (!this.isEmptyValue(record)) { + recordId = record[tableName + '_ID'] + } + this.$store.dispatch('listDocumentStatus', { + tableName, + recordUuid: this.$route.query.action, + recordId + }) + }, + handleChangeShowedRecordNavigation(valueToChange) { + const panelRight = document.getElementById('PanelRight') + const heightPanel = panelRight.clientHeight + 50 + this.$store.dispatch('setHeight', heightPanel) + this.$store.dispatch('changeWindowAttribute', { + parentUuid: this.windowUuid, // act as parentUuid + window: this.windowMetadata, + attributeName: 'isShowedRecordNavigation', + attributeValue: valueToChange + }) + }, + handleChangeShowedPanel(value) { + this.isShowedRecordPanel = !this.isShowedRecordPanel + }, + handleChangeShowedTabChildren(isShowedChilds) { + this.$store.dispatch('changeWindowAttribute', { + parentUuid: this.windowUuid, // act as parentUuid + window: this.windowMetadata, + attributeName: 'isShowedTabsChildren', + attributeValue: isShowedChilds + }) + } + } +} diff --git a/src/views/ADempiere/Window/windowStyleGlobal.scss b/src/views/ADempiere/Window/windowStyleGlobal.scss new file mode 100644 index 00000000..f277b0b3 --- /dev/null +++ b/src/views/ADempiere/Window/windowStyleGlobal.scss @@ -0,0 +1,81 @@ + +.el-step.is-simple .el-step__icon-inner { + font-size: 18px; + padding-top: 30px; +} +.el-steps--simple { + /* padding: 13px 8%; */ + padding-top: 0px; + padding-bottom: 0px; + padding-left: 0%; + padding-right: 0px; + border-radius: 4px; + background: #F5F7FA; + overflow-x: auto; + overflow-y: hidden; + width: auto; +} +.scroll-window-log-change { + max-height: 74vh !important; +} +.scroll-window-log-workflow { + max-height: 68vh !important; +} +.scroll-window-log-chat { + max-height: 28vh !important; +} +.el-card__header { + background: rgba(245, 247, 250, 0.75); + padding: 18px 20px; + border-bottom: 1px solid #f5f7fa; + -webkit-box-sizing: border-box; + box-sizing: border-box; +} +.split { + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; + overflow-y: hidden; + overflow-x: hidden; + height: 102%; + width: 100%; +} +.components-container { + position: relative; + height: 100vh; +} +.left-container { + background-color: #ffffff; + height: 100%; +} +.right-container { + background-color: #ffffff; + height: 200px; +} +.top-container { + background-color: #ffffff; + width: 100%; + height: 100%; +} +.bottom-container { + width: 100%; + background-color: #95E1D3; + height: 100%; +} +.splitter-pane-resizer.vertical { + width: 11px !important; + /* width: 9px; */ + height: 100%; + background: gray !important; + margin-left: -10px; + /* margin-left: -5px; */ + border-left: 5px solid hsla(0,0%,100%,0); + border-right: 5px solid hsla(0,0%,100%,0); + cursor: col-resize; +} +.splitter-pane.vertical.splitter-paneR { + position: absolute; + right: 0; + height: 100%; + padding-left: 10px; +} diff --git a/src/views/ADempiere/Window/windowStyleScoped.scss b/src/views/ADempiere/Window/windowStyleScoped.scss new file mode 100644 index 00000000..b8e5fc18 --- /dev/null +++ b/src/views/ADempiere/Window/windowStyleScoped.scss @@ -0,0 +1,164 @@ +.scroll { + max-height: 60vh; +} +/* 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; + padding-top: 0px !important; + padding-right: 15px !important; + padding-bottom: 0px !important; + padding-left: 15px !important; +} +.el-header { + background-color: #fff; + color: #333; + line-height: 21px; +} +.el-aside { + height: 100%; + color: #333; + overflow-y: hidden; + overflow-x: hidden; +} +aside { + background: #fff; + padding: 0px; + margin-bottom: 0px; + border-radius: 2px; + display: block; + line-height: 32px; + font-size: 16px; + font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Fira Sans", "Droid Sans", "Helvetica Neue", sans-serif; + color: #2c3e50; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; +} +.el-main { + display: block; + -webkit-box-flex: 1; + flex: 1; + flex-basis: auto; + overflow: hidden; + height: 90vh; + box-sizing: border-box; + padding-top: 0px !important; + padding-right: 0px !important; + padding-bottom: 0px !important; + padding-left: 0px !important; +} +.center{ + text-align: center; +} +.close{ + text-align: right; +} +.w-33 { + width: 100%; + background-color: transparent; +} +.w { + height: 100%; +} +.open-table-detail-mobile { + position: absolute; + right: 50%; + bottom: 4%; +} +.open-table-detail { + position: absolute; + right: 50%; + bottom: 4%; + display: none; +} +.open-navegation { + position: fixed; + top: 50%; + display: none; + z-index: 5; +} +.open-datatable-aside { + position: absolute; + top: 41%; + display: none; + z-index: 5; + right: 1%!important; +} +.open-datatable-aside-mobile { + position: absolute; + top: 41%; + display: grid; + z-index: 5; + right: 1%!important; +} +.button { + display: none; +} +.wrapper:hover .open-table-detail { + display: inline-block; +} +.w:hover .open-navegation { + display: inline-block; +} +.w:hover .open-datatable-aside { + display: grid; +} +.open-detail { + width: 100%; + height: 20px; + position: absolute; + bottom: 5%; +} +.open-left { + width: 2%; + height: 97%; + position: absolute; + top: 2%; + left: 1%; +} +.el-button-window { + cursor: pointer; + background: #FFFFFF; + border: 1px solid #DCDFE6; + border-color: #DCDFE6; + color: white; + background: #008fd3; +} +.close-info { + top: 40%; + position: absolute; +} +.close-info-mobile { + top: 29%; + position: absolute; +} +.vertical-panes { + width: 100%; + height: 85vh; + border: 1px solid #ccc; +} +.vertical-panes > .pane { + text-align: left; + padding: 15px; + overflow: hidden; + background: #fff; +} +.vertical-panes > .pane ~ .pane { + border-left: 1px solid #ccc; +} +.loading-window { + padding: 100px 100px; + height: 100%; +}