1
0
mirror of https://github.com/PanJiaChen/vue-element-admin.git synced 2025-08-12 22:29:59 +08:00

add context menu field mode mobile (#705)

* add context menu field mode mobile

* minimal change

* minimal changes

* minimal changes

* minimal changes

* style button

* change style

Co-authored-by: Elsio Sanchez <elsiosanche@gmail.com>
This commit is contained in:
Elsio Sanchez 2021-04-07 11:35:31 -04:00 committed by GitHub
parent 8b43985c89
commit a91d027920
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
18 changed files with 939 additions and 524 deletions

View File

@ -1,131 +1,125 @@
<template> <template>
<div class="container-submenu container-context-menu"> <div v-if="!isListRecord" class="container-submenu-mobile container-context-menu">
<el-menu <!-- actions or process on container -->
ref="contextMenu" <el-dropdown
v-shortkey="shorcutKey" size="mini"
:router="false" :hide-on-click="true"
class="el-menu-demo" split-button
mode="horizontal" trigger="click"
menu-trigger="hover" @command="clickRunAction"
unique-opened @click="runAction(defaultActionToRun)"
@shortkey.native="actionContextMenu"
> >
<!-- actions or process on container --> {{ defaultActionName }}
<el-submenu v-if="!isEmptyValue(actions)" class="el-menu-item" index="actions" @click.native="runAction(actions[0])"> <el-dropdown-menu slot="dropdown">
<template slot="title"> <el-scrollbar wrap-class="scroll-child">
{{ $t('components.contextMenuActions') }} <el-dropdown-item
</template> command="refreshData"
<template v-for="(action, index) in actions"> >
<el-submenu v-if="action.childs" :key="index" :index="action.name" :disabled="action.disabled"> <div class="contents">
<template slot="title"> <div style="margin-right: 5%;margin-top: 10%;">
{{ action.name }} <i class="el-icon-refresh" style="font-weight: bolder;" />
</template> </div>
<el-scrollbar wrap-class="scroll-child"> <div>
<el-menu-item <span class="contents">
v-for="(child, key) in action.childs" <b class="label">
:key="key" {{ $t('components.contextMenuRefresh') }}
:index="child.uuid" </b>
@click="runAction(child)" </span>
> <p
{{ child.name }} class="description"
</el-menu-item> >
</el-scrollbar> {{ $t('data.noDescription') }}
</el-submenu> </p>
<el-menu-item </div>
v-else </div>
v-show="!action.hidden" </el-dropdown-item>
<el-dropdown-item
v-for="(action, index) in actions"
:key="index" :key="index"
:index="action.name" :command="action"
:disabled="panelType === 'browser' ? isEmptyValue(getDataSelection) : action.disabled" :divided="true"
@click="runAction(action)"
> >
{{ action.name }} <div class="contents">
</el-menu-item> <div style="margin-right: 5%;margin-top: 10%;">
</template> <i :class="iconAction(action)" style="font-weight: bolder;" />
<!-- other actions --> </div>
<el-menu-item v-show="isReport" index="downloadReport"> <div>
<a :href="downloads" :download="file"> <span class="contents">
{{ $t('components.contextMenuDownload') }} <b class="label">
</a> {{ action.name }}
</el-menu-item> </b>
<el-submenu </span>
v-if="isManageDataRecords" <p
:disabled="isDisabledExportRecord" class="description"
index="exportRecord" >
@click.native="exportRecord(defaultFromatExport)" {{ $t('data.noDescription') }}
> </p>
<template slot="title"> </div>
{{ $t('data.exportRecord') }} </div>
</template> </el-dropdown-item>
<el-menu-item
v-for="(format, keyFormat) in supportedTypes"
:key="keyFormat"
:index="keyFormat"
@click.native="exportRecord(keyFormat)"
>
{{ format }}
</el-menu-item>
</el-submenu>
<el-menu-item
v-show="$route.name === 'Report Viewer'"
index="printFormat"
@click="redirect"
>
{{ $t('components.contextMenuPrintFormatSetup') }}
</el-menu-item>
<el-menu-item
v-if="isManageDataRecords"
index="refreshData"
@click="refreshData"
>
{{ $t('components.contextMenuRefresh') }}
</el-menu-item>
<el-menu-item index="shareLink" @click="setShareLink">
{{ $t('components.contextMenuShareLink') }}
</el-menu-item>
</el-submenu>
<el-menu-item v-else disabled index="actionsDisabled">
{{ $t('components.contextMenuActions') }}
</el-menu-item>
<!-- menu relations -->
<el-submenu v-if="!isEmptyChilds" class="el-menu-item" index="1">
<template slot="title">
{{ $t('components.contextMenuRelations') }}
</template>
<el-scrollbar wrap-class="scroll">
<items-relations v-for="(relation, index) in relationsList" :key="index" :item="relation" />
</el-scrollbar> </el-scrollbar>
</el-submenu> </el-dropdown-menu>
<el-menu-item v-else disabled index="relations"> </el-dropdown>
{{ $t('components.contextMenuRelations') }} <!-- menu relations -->
</el-menu-item> <el-dropdown size="mini" @command="clickRelation">
<!-- references of record --> <el-button size="mini">
<el-submenu {{ $t('components.contextMenuRelations') }} <i class="el-icon-arrow-down el-icon--right" />
:disabled="!(isReferecesContent && isLoadedReferences)" </el-button>
class="el-menu-item" <el-dropdown-menu slot="dropdown">
index="references" <el-dropdown-item
> v-for="(relation, index) in relationsList"
<template slot="title"> :key="index"
{{ $t('components.contextMenuReferences') }} :command="relation"
</template> :divided="true"
<template v-if="references && !isEmptyValue(references.referencesList)"> >
<el-scrollbar wrap-class="scroll-child"> <div class="contents">
<el-menu-item <div style="margin-right: 5%;margin-top: 10%;">
v-for="(reference, index) in references.referencesList" <svg-icon :icon-class="relation.meta.icon" />
:key="index" </div>
:index="reference.displayName" <div>
@click="openReference(reference)" <span class="contents">
> <b class="label">
{{ reference.displayName }} {{ relation.meta.title }}
</el-menu-item> </b>
</el-scrollbar> </span>
</template> <p
<el-menu-item v-else index="not-references" disabled> class="description"
{{ $t('components.withOutReferences') }} >
</el-menu-item> {{ relation.meta.description }}
</el-submenu> </p>
</el-menu> </div>
</div>
</el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
<el-dropdown size="mini" @command="clickReferences">
<el-button size="mini" :disabled="!(isReferecesContent && isLoadedReferences)">
{{ $t('components.contextMenuReferences') }} <i class="el-icon-arrow-down el-icon--right" />
</el-button>
<el-dropdown-menu slot="dropdown">
<el-dropdown-item
v-for="(reference, index) in references.referencesList"
:key="index"
:command="reference"
:divided="true"
>
<div class="contents">
<div>
<span class="contents">
<b class="label">
{{ reference.displayName }}
</b>
</span>
<p
class="description"
>
{{ $t('data.noDescription') }}
</p>
</div>
</div>
</el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
</div> </div>
</template> </template>
@ -133,9 +127,181 @@
import contextMixin from './contextMenuMixin.js' import contextMixin from './contextMenuMixin.js'
export default { export default {
name: 'ContextMenuDesktop', name: 'ContextMenuMobile',
mixins: [ mixins: [
contextMixin contextMixin
] ],
data() {
return {
openedsMenu: [
'actions'
]
}
},
computed: {
isPanelTypeMobile() {
if (['process', 'report'].includes(this.$route.meta.type)) {
return true
}
return false
},
isUndoAction() {
if (this.isWindow) {
if (!this.isWithRecord) {
return true
}
}
return false
},
typeOfAction() {
if (this.isUndoAction) {
return 'warning'
}
return 'default'
},
isPlain() {
if (this.isUndoAction) {
return true
}
return false
},
defaultActionToRun() {
if (this.isUndoAction) {
return this.actions[2]
}
return this.actions[0]
},
defaultActionName() {
if (this.isWindow) {
if (this.isWithRecord) {
return this.$t('window.newRecord')
}
return this.$t('data.undo')
}
return this.$t('components.RunProcess')
},
iconDefault() {
if (this.isPanelTypeMobile) {
return 'component'
}
return 'skill'
}
},
methods: {
clickRelation(item) {
this.$router.push({
name: item.name,
query: {
tabParent: 0
}
}, () => {})
},
clickRunAction(action) {
if (action === 'refreshData') {
this.refreshData()
} else {
this.runAction(action)
}
},
clickReferences(reference) {
this.openReference(reference)
},
iconAction(action) {
let icon
if (action.type === 'dataAction') {
switch (action.action) {
case 'setDefaultValues':
icon = 'el-icon-news'
break
case 'deleteEntity':
icon = 'el-icon-delete'
break
case 'undoModifyData':
icon = 'el-icon-refresh-left'
break
case 'lockRecord':
icon = 'el-icon-lock'
break
case 'unlockRecord':
icon = 'el-icon-unlock'
break
case 'recordAccess':
icon = 'el-icon-c-scale-to-original'
break
}
} else if (action.type === 'process') {
icon = 'el-icon-setting'
} else {
icon = 'el-icon-setting'
}
return icon
},
styleLabelAction(value) {
if (value) {
return 'font-size: 14px;margin-top: 0% !important;margin-left: 0px;margin-bottom: 10%;display: contents;'
} else {
return 'font-size: 14px;margin-top: 1.5% !important;margin-left: 2%;margin-bottom: 5%;display: contents;'
}
}
}
} }
</script> </script>
<style scoped>
.el-tree-node__children {
overflow: hidden;
background-color: transparent;
max-width: 99%;
overflow: auto;
}
.el-dropdown .el-button-group {
display: flex;
}
.el-dropdown-menu {
position: absolute;
top: 0;
left: 0;
z-index: 10;
padding: 10px 0;
margin: 5px 0;
background-color: #FFFFFF;
border: 1px solid #e6ebf5;
border-radius: 4px;
-webkit-box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
max-height: 250px;
max-width: 220px;
overflow: auto;
}
.el-dropdown-menu--mini .el-dropdown-menu__item {
line-height: 14px;
padding: 0px 15px;
font-size: 10px;
}
.el-dropdown-menu__item--divided {
position: relative;
/* margin-top: 6px; */
border-top: 1px solid #e6ebf5;
}
.svg-icon {
width: 1em;
height: 2em;
vertical-align: -0.15em;
fill: currentColor;
overflow: hidden;
}
.label {
font-size: 14px;
margin-top: 0% !important;
margin-left: 0px;
text-align: initial;
}
.description {
margin: 0px;
font-size: 12px;
text-align: initial;
}
.contents {
display: inline-flex;
}
</style>

View File

@ -77,6 +77,16 @@ export default {
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
.selector {
/* definir una altura pequeña para forzar el scroll */
height: 100px;
overflow-y: scroll;
width: 300px;
/* cambiar el estilo por defecto de la barra de scroll */
scrollbar-color: yellow #800080;
scrollbar-width: 10px;
}
.el-submenu .el-menu-item { .el-submenu .el-menu-item {
height: 50px; height: 50px;
line-height: 50px; line-height: 50px;

View File

@ -1,100 +1,97 @@
<template> <template>
<el-dropdown trigger="click"> <el-card class="box-card">
<el-button type="text" :disabled="fieldAttributes.readonly" @click="focusCalc"> <div slot="header" class="clearfix">
<i class="el-icon-s-operation el-icon--right" /> <span>
</el-button> {{ $t('field.field') }}
<b> {{ fieldAttributes.name }} </b>
<el-dropdown-menu slot="dropdown" class="dropdown-calc"> </span>
<el-input </div>
ref="calculatorInput" <el-form ref="form" label-position="top" label-width="120px" @submit.native.prevent="notSubmitForm">
v-model="calcValue" <el-form-item label="Valor">
class="calculator-input" <el-input
size="mini" ref="calculatorInput"
readonly v-model="calcValue"
@keydown.native="calculateValue" class="calculator-input"
@keyup.enter.native="changeValue" size="mini"
readonly
@keydown.native="calculateValue"
@keyup.enter.native="changeValue"
/>
</el-form-item>
</el-form>
<el-table
ref="calculator"
:data="tableData"
style="width: 100%"
border
size="mini"
:show-header="false"
:span-method="spanMethod"
class="calculator-table"
@cell-click="sendValue"
>
<el-table-column
align="center"
prop="row1"
height="15"
width="45"
> >
<!-- <template slot-scope="{ row, column }">
<template slot="append"> <el-button type="text" :disabled="isDisabled(row, column)">
{{ valueToDisplay }} {{ row.row1.value }}
</el-button>
</template> </template>
--> </el-table-column>
</el-input> <el-table-column
align="center"
<el-table prop="row2"
ref="calculator" height="15"
:data="tableData" width="45"
style="width: 100%"
border
size="mini"
:show-header="false"
:span-method="spanMethod"
class="calculator-table"
@cell-click="sendValue"
> >
<el-table-column <template slot-scope="{ row, column }">
align="center" <el-button type="text" :disabled="isDisabled(row, column)">
prop="row1" {{ row.row2.value }}
height="15" </el-button>
width="35" </template>
> </el-table-column>
<template slot-scope="{ row, column }"> <el-table-column
<el-button type="text" :disabled="isDisabled(row, column)"> align="center"
{{ row.row1.value }} prop="row3"
</el-button> height="15"
</template> width="45"
</el-table-column> >
<el-table-column <template slot-scope="{ row, column }">
align="center" <el-button type="text" :disabled="isDisabled(row, column)">
prop="row2" {{ row.row3.value }}
height="15" </el-button>
width="35" </template>
> </el-table-column>
<template slot-scope="{ row, column }"> <el-table-column
<el-button type="text" :disabled="isDisabled(row, column)"> align="center"
{{ row.row2.value }} prop="row4"
</el-button> height="15"
</template> width="45"
</el-table-column> >
<el-table-column <template slot-scope="{ row, column }">
align="center" <el-button type="text" :disabled="isDisabled(row, column)">
prop="row3" {{ row.row4.value }}
height="15" </el-button>
width="35" </template>
> </el-table-column>
<template slot-scope="{ row, column }"> <el-table-column
<el-button type="text" :disabled="isDisabled(row, column)"> align="center"
{{ row.row3.value }} prop="row5"
</el-button> height="15"
</template> width="45"
</el-table-column> >
<el-table-column <template slot-scope="{ row, column }">
align="center" <el-button type="text" :disabled="isDisabled(row, column)">
prop="row4" {{ row.row5.value }}
height="15" </el-button>
width="35" </template>
> </el-table-column>
<template slot-scope="{ row, column }"> </el-table>
<el-button type="text" :disabled="isDisabled(row, column)"> </el-card>
{{ row.row4.value }}
</el-button>
</template>
</el-table-column>
<el-table-column
align="center"
prop="row5"
height="15"
width="35"
>
<template slot-scope="{ row, column }">
<el-button type="text" :disabled="isDisabled(row, column)">
{{ row.row5.value }}
</el-button>
</template>
</el-table-column>
</el-table>
</el-dropdown-menu>
</el-dropdown>
</template> </template>
<script> <script>
@ -115,20 +112,33 @@ export default {
}, },
data() { data() {
return { return {
calcValue: this.fieldValue, calcValue: this.valueField,
valueToDisplay: '' valueToDisplay: ''
} }
}, },
computed: { computed: {
tableData() { tableData() {
return buttons return buttons
},
valueField() {
return this.$store.getters.getValueOfField({
parentUuid: this.fieldAttributes.parentUuid,
containerUuid: this.fieldAttributes.containerUuid,
columnName: this.fieldAttributes.columnName
})
} }
}, },
watch: { watch: {
valueField(value) {
console.log(value)
},
fieldValue(value) { fieldValue(value) {
this.calcValue = value this.calcValue = value
} }
}, },
created() {
this.calcValue = this.valueField
},
methods: { methods: {
sendValue(row, column) { sendValue(row, column) {
const button = row[column.property] const button = row[column.property]
@ -182,6 +192,7 @@ export default {
.finally(() => { .finally(() => {
this.clearVariables() this.clearVariables()
this.$children[0].visible = false this.$children[0].visible = false
this.$store.commit('changeShowRigthPanel', false)
}) })
}, },
spanMethod({ row, column }) { spanMethod({ row, column }) {
@ -221,7 +232,7 @@ export default {
return false return false
}, },
calculateValue(event) { calculateValue(event) {
const result = this.calculationValue(this.fieldValue, event) const result = this.calculationValue(this.valueField, event)
if (!this.isEmptyValue(result)) { if (!this.isEmptyValue(result)) {
this.valueToDisplay = result this.valueToDisplay = result
} else { } else {

View File

@ -1,36 +1,32 @@
<template> <template>
<span> <div>
<el-popover <el-card class="box-card">
ref="contextInfoField" <div slot="header" class="clearfix">
placement="top" <span>
width="300" {{ $t('field.field') }}
trigger="click" <b> {{ fieldAttributes.name }} </b>
>
<p
class="pre-formatted"
v-html="fieldAttributes.contextInfo.messageText.msgText"
/>
<div>
<span class="custom-tittle-popover">
{{ fieldAttributes.name }}
</span> </span>
{{ fieldAttributes.help }}
</div> </div>
<template v-for="(zoomItem, index) in fieldAttributes.reference.zoomWindows"> <el-form ref="form" label-position="top" label-width="120px" style="max-height: 70vh; overflow: auto;" @submit.native.prevent="notSubmitForm">
<el-button <el-form-item :label="$t('field.container.description')">
:key="index" {{ fieldAttributes.description }}
type="text" </el-form-item>
@click="redirect({ window: zoomItem })" <el-form-item :label="$t('field.container.help')">
> {{ fieldAttributes.help }}
{{ $t('table.ProcessActivity.zoomIn') }} </el-form-item>
{{ zoomItem.name }} </el-form>
</el-button> </el-card>
</template> <template v-for="(zoomItem, index) in fieldAttributes.reference.zoomWindows">
</el-popover> <el-button
<span v-popover:contextInfoField> :key="index"
{{ fieldAttributes.name }} type="text"
</span> @click="redirect({ window: zoomItem })"
</span> >
{{ $t('table.ProcessActivity.zoomIn') }}
{{ zoomItem.name }}
</el-button>
</template>
</div>
</template> </template>
<script> <script>
@ -64,6 +60,10 @@ export default {
} }
}, },
methods: { methods: {
notSubmitForm(event) {
event.preventDefault()
return false
},
redirect({ window }) { redirect({ window }) {
const viewSearch = recursiveTreeSearch({ const viewSearch = recursiveTreeSearch({
treeData: this.permissionRoutes, treeData: this.permissionRoutes,
@ -89,6 +89,7 @@ export default {
message: this.$t('notifications.noRoleAccess') message: this.$t('notifications.noRoleAccess')
}) })
} }
this.$store.commit('changeShowRigthPanel', false)
} }
} }
} }

View File

@ -1,93 +1,89 @@
<template> <template>
<el-dropdown trigger="click"> <el-card
<el-button type="text" :disabled="sourceField.readonly"> v-if="!isEmptyValue(metadataList)"
<i class="el-icon-notebook-2 el-icon--right" @click="isActive = !isActive" /> class="box-card"
</el-button> >
<el-dropdown-menu slot="dropdown" class="dropdown-calc"> <div slot="header" class="clearfix">
<el-card <span>
v-if="!isEmptyValue(metadataList)" {{ $t('components.preference.title') }}
class="box-card" <b>
> {{ sourceField.name }}
<div slot="header" class="clearfix">
<span>
{{ $t('components.preference.title') }}
<b>
{{ sourceField.name }}
</b>
</span>
</div>
<div class="text item">
{{ {{
getDescriptionOfPreference fieldValue
}} }}
</div> </b>
<br> </span>
<div class="text item"> </div>
<el-form <div class="text item">
:inline="true" {{
> getDescriptionOfPreference
<el-form-item> }}
<p slot="label"> </div>
{{ sourceField.name }}: {{ code }} <br>
</p> <div class="text item">
</el-form-item> <el-form
</el-form> :inline="true"
<el-form >
label-position="top" <el-form-item>
:inline="true" <p slot="label">
class="demo-form-inline" {{ sourceField.name }}: {{ fieldValue }}
size="medium" </p>
> </el-form-item>
<el-form-item </el-form>
v-for="(field) in metadataList" <el-form
:key="field.sequence" label-position="top"
> :inline="true"
<p slot="label"> class="demo-form-inline"
{{ field.name }} size="medium"
</p> >
<el-switch <el-form-item
v-model="field.value" v-for="(field) in metadataList"
/> :key="field.sequence"
</el-form-item> >
</el-form> <p slot="label">
</div> {{ field.name }}
<br> </p>
<el-row> <el-switch
<el-col :span="24"> v-model="field.value"
<samp style="float: left; padding-right: 10px;"> />
<el-button </el-form-item>
type="danger" </el-form>
class="custom-button-address-location" </div>
icon="el-icon-delete" <br>
@click="remove()" <el-row>
/> <el-col :span="24">
</samp> <samp style="float: left; padding-right: 10px;">
<samp style="float: right; padding-right: 10px;"> <el-button
<el-button type="danger"
type="danger" class="custom-button-address-location"
class="custom-button-address-location" icon="el-icon-delete"
icon="el-icon-close" @click="remove()"
@click="close()" />
/> </samp>
<el-button <samp style="float: right; padding-right: 10px;">
type="primary" <el-button
class="custom-button-address-location" type="danger"
icon="el-icon-check" class="custom-button-address-location"
@click="sendValue()" icon="el-icon-close"
/> @click="close()"
</samp> />
</el-col> <el-button
</el-row> type="primary"
</el-card> class="custom-button-address-location"
<div icon="el-icon-check"
v-else @click="sendValue()"
v-loading="isEmptyValue(metadataList)" />
:element-loading-text="$t('notifications.loading')" </samp>
element-loading-background="rgba(255, 255, 255, 0.8)" </el-col>
class="loading-window" </el-row>
/> </el-card>
</el-dropdown-menu> <div
</el-dropdown> v-else
v-loading="isEmptyValue(metadataList)"
:element-loading-text="$t('notifications.loading')"
element-loading-background="rgba(255, 255, 255, 0.8)"
class="loading-window"
/>
</template> </template>
<script> <script>
@ -184,10 +180,16 @@ export default {
} }
} }
}, },
beforeMount() {
if (this.isEmptyValue(this.metadataList)) {
this.setFieldsList()
}
},
methods: { methods: {
createFieldFromDictionary, createFieldFromDictionary,
close() { close() {
this.$children[0].visible = false this.$children[0].visible = false
this.$store.commit('changeShowRigthPanel', false)
}, },
remove() { remove() {
const isForCurrentUser = this.metadataList.find(field => field.columnName === 'AD_User_ID').value const isForCurrentUser = this.metadataList.find(field => field.columnName === 'AD_User_ID').value
@ -249,7 +251,7 @@ export default {
setPreference({ setPreference({
parentUuid: this.sourceField.parentUuid, parentUuid: this.sourceField.parentUuid,
attribute: this.sourceField.columnName, attribute: this.sourceField.columnName,
value: this.code, value: this.fieldValue,
isForCurrentUser, isForCurrentUser,
isForCurrentClient, isForCurrentClient,
isForCurrentOrganization, isForCurrentOrganization,
@ -266,6 +268,7 @@ export default {
message: error.message, message: error.message,
type: 'error' type: 'error'
}) })
this.close()
console.warn(`setPreference error: ${error.message}.`) console.warn(`setPreference error: ${error.message}.`)
}) })
} }

View File

@ -1,63 +1,58 @@
<template> <template>
<span> <el-card class="box-card">
<el-popover <div slot="header" class="clearfix">
ref="translatedField" <span>
placement="top" {{ $t('field.field') }}
width="300" <b> {{ fieldAttributes.name }} </b>
trigger="click" </span>
@show="getTranslation" </div>
> <div>
<div> <el-form ref="form" label-position="top">
<span class="custom-tittle-popover"> <el-form-item :label="$t('field.container.description')">
{{ fieldAttributes.name }} {{ fieldAttributes.description }}
</span> </el-form-item>
<template v-if="!isEmptyValue(fieldAttributes.help)"> <el-form-item :label="$t('field.container.help')">
: {{ fieldAttributes.help }} {{ fieldAttributes.help }}
</template> </el-form-item>
</div> <el-form-item
<el-form-item :required="true"
:required="true"
>
<template slot="label">
{{ $t('language') + ':' }}
</template>
<el-select
v-model="langValue"
size="medium"
style="width: 100%;"
filterable
@change="getTranslation"
> >
<!-- <el-option <template slot="label">
key="blank-option" {{ $t('language') + ':' }}
:value="undefined" </template>
label=" " <el-select
/> --> v-model="langValue"
<el-option size="medium"
v-for="(optionLang, key) in languageList" style="width: 100%;"
:key="key" filterable
:value="optionLang.language" @change="getTranslation"
:label="optionLang.languageName" >
<!-- <el-option
key="blank-option"
:value="undefined"
label=" "
/> -->
<el-option
v-for="(optionLang, key) in languageList"
:key="key"
:value="optionLang.language"
:label="optionLang.languageName"
/>
</el-select>
</el-form-item>
<el-form-item
:label="$t('field.container.codeTranslation')"
:required="true"
>
<el-input
v-model="translatedValue"
:disabled="isEmptyValue(langValue)"
@change="changeTranslationValue"
/> />
</el-select> </el-form-item>
</el-form-item> </el-form>
<el-form-item </div>
label="Translated Value:" </el-card>
:required="true"
>
<el-input
v-model="translatedValue"
:disabled="isEmptyValue(langValue)"
@change="changeTranslationValue"
/>
</el-form-item>
</el-popover>
<svg-icon
v-popover:translatedField
class-name="international-icon"
icon-class="language"
/>
</span>
</template> </template>
<script> <script>

View File

@ -18,44 +18,49 @@
:required="isMandatory" :required="isMandatory"
> >
<template slot="label"> <template slot="label">
<operator-comparison <el-dropdown
v-if="field.isComparisonField" size="mini"
key="is-field-operator-comparison" :hide-on-click="true"
:field-attributes="fieldAttributes" trigger="click"
:field-value="field.value" @command="handleCommand"
/> >
<context-info <span class="el-dropdown-link">
v-else-if="isContextInfo" <span key="is-field-name">
key="is-field-context-info" {{ field.name }}
:field-attributes="fieldAttributes" </span>
:field-value="field.value" <i
/> class="el-icon-more el-icon--right"
<span v-else key="is-field-name"> />
{{ isFieldOnly }} </span>
</span> <el-dropdown-menu slot="dropdown">
<template
<document-status v-for="(option, key) in optionField"
v-if="isDocuemntStatus" >
:field="fieldAttributes" <el-dropdown-item
/> v-if="option.enabled"
:key="key"
<translated :command="option"
v-if="field.isTranslatedField" :divided="true"
:field-attributes="fieldAttributes" >
:record-uuid="field.recordUuid" <div class="contents">
/> <div v-if="option.name !== $t('language')" style="margin-right: 5%;padding-top: 3%;">
<i :class="option.icon" style="font-weight: bolder;" />
<calculator </div>
v-if="field.isNumericField && !field.isReadOnlyFromLogic" <div v-else style="margin-right: 5%">
:field-attributes="fieldAttributes" <svg-icon :icon-class="option.icon" style="margin-right: 5px;" />
:field-value="recordDataFields" </div>
/> <div>
<preference <span class="contents">
v-if="field.panelType !== 'form'" <b class="label">
:source-field="fieldAttributes" {{ option.name }}
:field-value="recordDataFields" </b>
:panel-type="field.panelType" </span>
/> </div>
</div>
</el-dropdown-item>
</template>
</el-dropdown-menu>
</el-dropdown>
</template> </template>
<component <component
:is="componentRender" :is="componentRender"
@ -78,14 +83,11 @@
</template> </template>
<script> <script>
import contextInfo from '@/components/ADempiere/Field/popover/contextInfo'
import documentStatus from '@/components/ADempiere/Field/popover/documentStatus' import documentStatus from '@/components/ADempiere/Field/popover/documentStatus'
import preference from '@/components/ADempiere/Field/popover/preference/index'
import operatorComparison from '@/components/ADempiere/Field/popover/operatorComparison' import operatorComparison from '@/components/ADempiere/Field/popover/operatorComparison'
import translated from '@/components/ADempiere/Field/popover/translated'
import calculator from '@/components/ADempiere/Field/popover/calculator'
import { DEFAULT_SIZE } from '@/utils/ADempiere/references' import { DEFAULT_SIZE } from '@/utils/ADempiere/references'
import { evalutateTypeField, fieldIsDisplayed } from '@/utils/ADempiere/dictionaryUtils' import { evalutateTypeField, fieldIsDisplayed } from '@/utils/ADempiere/dictionaryUtils'
import { recursiveTreeSearch } from '@/utils/ADempiere/valueUtils.js'
/** /**
* This is the base component for linking the components according to the * This is the base component for linking the components according to the
@ -94,12 +96,8 @@ import { evalutateTypeField, fieldIsDisplayed } from '@/utils/ADempiere/dictiona
export default { export default {
name: 'FieldDefinition', name: 'FieldDefinition',
components: { components: {
contextInfo,
documentStatus, documentStatus,
operatorComparison, operatorComparison
translated,
calculator,
preference
}, },
props: { props: {
// receives the property that is an object with all the attributes // receives the property that is an object with all the attributes
@ -126,11 +124,15 @@ export default {
}, },
data() { data() {
return { return {
field: {} field: {},
visible: this.$store.state.contextMenu.isShowPopoverField
} }
}, },
computed: { computed: {
// load the component that is indicated in the attributes of received property // load the component that is indicated in the attributes of received property
isMobile() {
return this.$store.state.app.device === 'mobile'
},
componentRender() { componentRender() {
if (this.isEmptyValue(this.field.componentPath || !this.field.isSupported)) { if (this.isEmptyValue(this.field.componentPath || !this.field.isSupported)) {
return () => import('@/components/ADempiere/Field/FieldText') return () => import('@/components/ADempiere/Field/FieldText')
@ -379,6 +381,53 @@ export default {
} }
return Boolean(this.field.contextInfo && this.field.contextInfo.isActive) || return Boolean(this.field.contextInfo && this.field.contextInfo.isActive) ||
Boolean(this.field.reference && this.field.reference.zoomWindows.length) Boolean(this.field.reference && this.field.reference.zoomWindows.length)
},
optionField() {
return [
{
name: this.$t('field.info'),
enabled: true,
fieldAttributes: this.fieldAttributes,
icon: 'el-icon-info'
},
{
name: this.$t('table.ProcessActivity.zoomIn'),
enabled: this.isContextInfo,
fieldAttributes: this.fieldAttributes,
icon: 'el-icon-files'
},
{
name: this.$t('language'),
enabled: this.field.isTranslatedField,
fieldAttributes: this.fieldAttributes,
icon: 'language'
},
{
name: this.$t('field.calculator'),
enabled: this.field.isNumericField,
fieldAttributes: this.fieldAttributes,
recordDataFields: this.recordDataFields,
valueField: this.valueField,
icon: 'el-icon-s-operation'
},
{
name: this.$t('field.preference'),
enabled: true,
fieldAttributes: this.fieldAttributes,
valueField: this.valueField,
icon: 'el-icon-notebook-2'
}
]
},
permissionRoutes() {
return this.$store.getters.permission_routes
},
valueField() {
return this.$store.getters.getValueOfField({
parentUuid: this.fieldAttributes.parentUuid,
containerUuid: this.fieldAttributes.containerUuid,
columnName: this.fieldAttributes.columnName
})
} }
}, },
watch: { watch: {
@ -408,14 +457,108 @@ export default {
} }
}, },
methods: { methods: {
recursiveTreeSearch,
focusField() { focusField() {
if (this.field.handleRequestFocus || (this.field.displayed && !this.field.readonly)) { if (this.field.handleRequestFocus || (this.field.displayed && !this.field.readonly)) {
this.$refs[this.field.columnName].requestFocus() this.$refs[this.field.columnName].requestFocus()
} }
},
handleCommand(command) {
if (command.name === this.$t('table.ProcessActivity.zoomIn')) {
this.redirect({ window: command.fieldAttributes.reference.zoomWindows[0] })
return
}
if (this.isMobile) {
this.$store.commit('changeShowRigthPanel', true)
}
this.$store.commit('changeShowPopoverField', true)
this.$store.dispatch('setOptionField', command)
},
redirect({ window }) {
const viewSearch = recursiveTreeSearch({
treeData: this.permissionRoutes,
attributeValue: window.uuid,
attributeName: 'meta',
secondAttribute: 'uuid',
attributeChilds: 'children'
})
if (viewSearch) {
this.$router.push({
name: viewSearch.name,
query: {
action: 'advancedQuery',
tabParent: 0,
[this.fieldAttributes.columnName]: this.value
}
}, () => {})
} else {
this.$message({
type: 'error',
showClose: true,
message: this.$t('notifications.noRoleAccess')
})
}
} }
} }
} }
</script> </script>
<style scoped>
.svg-icon {
width: 1em;
height: 1.5em;
vertical-align: -0.15em;
fill: currentColor;
overflow: hidden;
}
.el-dropdown .el-button-group {
display: flex;
}
.el-dropdown-menu {
position: absolute;
top: 0;
left: 0;
z-index: 10;
padding: 10px 0;
margin: 5px 0;
background-color: #FFFFFF;
border: 1px solid #e6ebf5;
border-radius: 4px;
-webkit-box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
max-height: 250px;
max-width: 220px;
overflow: auto;
}
.el-dropdown-menu--mini .el-dropdown-menu__item {
line-height: 14px;
padding: 0px 15px;
padding-top: 1%;
padding-right: 15px;
padding-bottom: 1%;
padding-left: 15px;
font-size: 10px;
}
.el-dropdown-menu__item--divided {
position: relative;
/* margin-top: 6px; */
border-top: 1px solid #e6ebf5;
}
.label {
font-size: 14px;
margin-top: 0% !important;
margin-left: 0px;
text-align: initial;
}
.description {
margin: 0px;
font-size: 12px;
text-align: initial;
}
.contents {
display: inline-flex;
}
</style>
<style lang="scss"> <style lang="scss">
.custom-tittle-popover { .custom-tittle-popover {

View File

@ -10,10 +10,10 @@
<div class="rightMenu"> <div class="rightMenu">
<div <div
class="handle-button" class="handle-button"
:style="{ 'top': buttonTop+'%' }" :style="{'top':buttonTop+'px','background-color':theme}"
@click="isShowRightPanel=!isShowRightPanel" @click="isShowRightPanel=!isShowRightPanel"
> >
<i :class="icon" style="color: gray;" /> <i :class="icon" style="color: white;" />
</div> </div>
<div class="rightMenu-items"> <div class="rightMenu-items">
@ -36,7 +36,7 @@ export default {
type: Boolean type: Boolean
}, },
buttonTop: { buttonTop: {
default: 16, default: 250,
type: Number type: Number
} }
}, },
@ -145,7 +145,7 @@ export default {
position: fixed; position: fixed;
height: 100vh; height: 100vh;
width: 100%; width: 100%;
max-width: 260px; max-width: 80%;
top: 0px; top: 0px;
left: 0px; left: 0px;
box-shadow: 0px 0px 15px 0px rgba(0, 0, 0, .05); box-shadow: 0px 0px 15px 0px rgba(0, 0, 0, .05);
@ -172,25 +172,21 @@ export default {
} }
.handle-button { .handle-button {
width: 48px;
height: 48px;
position: absolute; position: absolute;
border: 1px solid #d9d9d9; left: -48px;
background: white;
left: -34px;
border-radius: 6px 0 0 6px !important;
width: 35px;
height: 35px;
pointer-events: auto;
z-index: 0;
cursor: pointer;
pointer-events: auto;
font-size: 0px;
text-align: center; text-align: center;
font-size: 24px;
border-radius: 6px 0 0 6px !important;
z-index: 0;
pointer-events: auto;
cursor: pointer;
color: #fff; color: #fff;
line-height: 48px; line-height: 48px;
i { i {
font-size: 17px; font-size: 24px;
line-height: 17px; line-height: 48px;
} }
} }
</style> </style>

View File

@ -1,5 +1,5 @@
<template> <template>
<div ref="rightPanel" :class="{show:show}" class="rightPanel-container"> <div v-if="false" ref="rightPanel" :class="{show:show}" class="rightPanel-container">
<div class="setting"> <div class="setting">
<div class="showme"> <div class="showme">
<div class="rightPanel-background" /> <div class="rightPanel-background" />

View File

@ -269,12 +269,14 @@ export default {
advancedQuery: 'Advanced Query' advancedQuery: 'Advanced Query'
}, },
settings: { settings: {
title: 'Page style setting', title: 'setting',
theme: 'Theme Color', theme: 'Theme Color',
tagsView: 'Open Tags-View', tagsView: 'Open Tags-View',
fixedHeader: 'Fixed Header', fixedHeader: 'Fixed Header',
sidebarLogo: 'Sidebar Logo', sidebarLogo: 'Sidebar Logo',
showContextMenu: 'Show Context Information' showContextMenu: 'Show Context Information',
isShowTitle: 'Show Títle',
isShowMenu: 'Show Menu'
}, },
profile: { profile: {
aboutMe: 'About Me', aboutMe: 'About Me',
@ -312,6 +314,17 @@ export default {
error: 'Error In Callout' error: 'Error In Callout'
} }
}, },
field: {
field: 'Field',
info: 'Information',
calculator: 'Calculator',
preference: 'Preference',
codeTranslation: 'Traduccion de Codigo',
container: {
help: 'Help',
description: 'Description'
}
},
data: { data: {
createRecordSuccessful: 'New record created successfully', createRecordSuccessful: 'New record created successfully',
createNewRecord: 'Mode New record', createNewRecord: 'Mode New record',

View File

@ -244,12 +244,14 @@ export default {
advancedQuery: 'Consulta Avanzada' advancedQuery: 'Consulta Avanzada'
}, },
settings: { settings: {
title: 'Configuración de estilo de página', title: 'Configuración',
theme: 'Color del tema', theme: 'Color del tema',
tagsView: 'Habilitar Tags-View', tagsView: 'Habilitar Tags-View',
fixedHeader: 'Encabezado fijo', fixedHeader: 'Encabezado fijo',
sidebarLogo: 'Logotipo de la barra lateral', sidebarLogo: 'Logotipo de la barra lateral',
showContextMenu: 'Mostrar Menu de Contexto' showContextMenu: 'Mostrar Menu de Contexto',
isShowTitle: 'Mostrar Título',
isShowMenu: 'Mostrar Menu'
}, },
profile: { profile: {
aboutMe: 'Sobre Mi', aboutMe: 'Sobre Mi',
@ -287,6 +289,17 @@ export default {
error: 'Error En Callout' error: 'Error En Callout'
} }
}, },
field: {
field: 'Campo',
info: 'Informacion',
calculator: 'Calculadora',
preference: 'Preferencia',
codeTranslation: 'Traduccion de Codigo',
container: {
help: 'Ayuda',
description: 'Descripción'
}
},
data: { data: {
createRecordSuccessful: 'Nuevo registro creado con exito', createRecordSuccessful: 'Nuevo registro creado con exito',
createNewRecord: 'Modo nuevo registro', createNewRecord: 'Modo nuevo registro',

View File

@ -1,60 +1,48 @@
<template> <template>
<div class="drawer-container"> <div class="drawer-container">
<div> <div>
<h3 class="drawer-title">{{ $t('settings.title') }}</h3> <el-form label-position="top" :inline="true">
<el-form-item
<div class="drawer-item"> :label="$t('settings.theme')"
<span>{{ $t('settings.theme') }}</span> >
<theme-picker style="float: right;height: 26px;margin: -3px 8px 0 0;" @change="themeChange" /> <theme-picker @change="themeChange" />
</div> </el-form-item>
<el-form-item
<div class="drawer-item"> :label="$t('settings.fixedHeader')"
<span>{{ $t('settings.tagsView') }}</span> >
<el-switch v-model="tagsView" class="drawer-switch" /> <el-switch v-model="fixedHeader" />
</div> </el-form-item>
<el-form-item
<div class="drawer-item"> :label="$t('settings.tagsView')"
<span>{{ $t('settings.showContextMenu') }}</span> >
<el-switch v-model="showContextMenu" class="drawer-switch" /> <el-switch v-model="tagsView" />
</div> </el-form-item>
<el-form-item
<div class="drawer-item"> :label="$t('settings.fixedHeader')"
<span>show Title</span> >
<el-switch v-model="isShowTitleForm" class="drawer-switch" /> <el-switch v-model="showNavar" />
</div> </el-form-item>
<el-form-item
<div class="drawer-item"> :label="$t('settings.showContextMenu')"
<span>{{ $t('settings.fixedHeader') }}</span> >
<el-switch v-model="fixedHeader" class="drawer-switch" /> <el-switch v-model="showContextMenu" />
</div> </el-form-item>
<el-form-item
<div class="drawer-item"> :label="$t('settings.isShowTitle')"
<span>Show Header</span> >
<el-switch v-model="showNavar" class="drawer-switch" /> <el-switch v-model="isShowTitleForm" />
</div> </el-form-item>
<el-form-item
<div class="drawer-item"> :label="$t('settings.isShowMenu')"
<span>Show Menu</span> >
<el-switch v-model="showMenu" class="drawer-switch" /> <el-switch v-model="showMenu" />
</div> </el-form-item>
<el-form-item
<div class="drawer-item"> :label="$t('settings.sidebarLogo')"
<span>{{ $t('settings.sidebarLogo') }}</span> >
<el-switch v-model="sidebarLogo" class="drawer-switch" /> <el-switch v-model="sidebarLogo" />
</div> </el-form-item>
<a v-if="isShowJob" href="https://panjiachen.github.io/vue-element-admin-site/zh/job/" target="_blank" class="job-link"> </el-form>
<el-alert
title="部门目前非常缺人!有兴趣的可以点击了解详情。坐标: 字节跳动"
type="success"
:closable="false"
/>
</a>
<div v-if="lang === 'zh'" class="drawer-item">
<span>菜单支持拼音搜索</span>
<el-switch v-model="supportPinyinSearch" class="drawer-switch" />
</div>
</div> </div>
</div> </div>
</template> </template>
@ -65,7 +53,9 @@ import ThemePicker from '@/components/ThemePicker'
export default { export default {
components: { ThemePicker }, components: { ThemePicker },
data() { data() {
return {} return {
activeName: '1'
}
}, },
computed: { computed: {
isShowTitleForm: { isShowTitleForm: {

View File

@ -14,6 +14,8 @@ import { requestListDocumentActions, requestListDocumentStatuses } from '@/api/A
// ] // ]
const initStateContextMenu = { const initStateContextMenu = {
isShowRightPanel: false, isShowRightPanel: false,
isShowPopoverField: false,
optionField: {},
contextMenu: [], contextMenu: [],
listDocumentStatus: { listDocumentStatus: {
defaultDocumentAction: undefined, defaultDocumentAction: undefined,
@ -47,8 +49,14 @@ const contextMenu = {
changeShowRigthPanel(state) { changeShowRigthPanel(state) {
state.isShowRightPanel = !state.isShowRightPanel state.isShowRightPanel = !state.isShowRightPanel
}, },
changeShowPopoverField(state) {
state.isShowPopoverField = !state.isShowPopoverField
},
resetContextMenu(state) { resetContextMenu(state) {
state = initStateContextMenu state = initStateContextMenu
},
fieldContextMenu(state, payload) {
state.optionField = payload
} }
}, },
actions: { actions: {
@ -143,6 +151,9 @@ const contextMenu = {
console.warn(`Error getting document statuses list. Code ${error.code}: ${error.message}.`) console.warn(`Error getting document statuses list. Code ${error.code}: ${error.message}.`)
}) })
}) })
},
setOptionField({ commit }, params) {
commit('fieldContextMenu', params)
} }
}, },
getters: { getters: {
@ -175,6 +186,9 @@ const contextMenu = {
}, },
getListDocumentActionByUuid: (state) => (recordUuid) => { getListDocumentActionByUuid: (state) => (recordUuid) => {
return state.listDocumentAction.find(itemDocumentAction => itemDocumentAction.recordUuid === recordUuid) return state.listDocumentAction.find(itemDocumentAction => itemDocumentAction.recordUuid === recordUuid)
},
getFieldContextMenu: (state) => {
return state.optionField
} }
} }
} }

View File

@ -295,6 +295,17 @@
</el-main> </el-main>
</SplitArea> </SplitArea>
</Split> </Split>
<right-panel
v-if="panelContextMenu && isMobile"
>
<component
:is="componentRender"
:field-attributes="contextMenuField.fieldAttributes"
:source-field="contextMenuField.fieldAttributes"
:record-uuid="contextMenuField.fieldAttributes.recordUuid"
:field-value="contextMenuField.valueField"
/>
</right-panel>
</el-container> </el-container>
</div> </div>
<div <div

View File

@ -13,6 +13,8 @@ import RecordLogs from '@/components/ADempiere/ContainerInfo/recordLogs'
import WorkflowLogs from '@/components/ADempiere/ContainerInfo/workflowLogs' import WorkflowLogs from '@/components/ADempiere/ContainerInfo/workflowLogs'
// Workflow // Workflow
import WorkflowStatusBar from '@/components/ADempiere/WorkflowStatusBar' import WorkflowStatusBar from '@/components/ADempiere/WorkflowStatusBar'
// Panel right the Context Menu Field
import RightPanel from '@/components/ADempiere/RightPanel'
/** /**
* Window Logic Component View * Window Logic Component View
@ -30,6 +32,7 @@ export default {
DataTable, DataTable,
splitPane, splitPane,
ModalDialog, ModalDialog,
RightPanel,
ChatEntries, ChatEntries,
RecordLogs, RecordLogs,
WorkflowLogs, WorkflowLogs,
@ -68,6 +71,30 @@ export default {
} }
}, },
computed: { computed: {
contextMenuField() {
return this.$store.getters.getFieldContextMenu
},
panelContextMenu() {
return this.$store.state.contextMenu.isShowRightPanel
},
componentRender() {
let component
switch (this.contextMenuField.name) {
case this.$t('field.info'):
component = () => import('@/components/ADempiere/Field/contextMenuField/contextInfo')
break
case this.$t('language'):
component = () => import('@/components/ADempiere/Field/contextMenuField/translated/index')
break
case this.$t('field.calculator'):
component = () => import('@/components/ADempiere/Field/contextMenuField/calculator')
break
case this.$t('field.preference'):
component = () => import('@/components/ADempiere/Field/contextMenuField/preference/index')
break
}
return component
},
isNewRecord() { isNewRecord() {
return this.isEmptyValue(this.$route.query) || return this.isEmptyValue(this.$route.query) ||
this.isEmptyValue(this.$route.query.action) || this.isEmptyValue(this.$route.query.action) ||

View File

@ -13,6 +13,9 @@
<el-tab-pane :label="$t('profile.role')" name="role"> <el-tab-pane :label="$t('profile.role')" name="role">
<role /> <role />
</el-tab-pane> </el-tab-pane>
<el-tab-pane :label="$t('settings.title')" :name="$t('settings.title')">
<settings />
</el-tab-pane>
</el-tabs> </el-tabs>
</el-card> </el-card>
</el-col> </el-col>
@ -23,15 +26,17 @@
</template> </template>
<script> <script>
import { mapGetters } from 'vuex' import { mapGetters, mapState } from 'vuex'
import UserCard from './components/UserCard' import UserCard from './components/UserCard'
import Role from '@/views/profile/components/role' import Role from '@/views/profile/components/role'
import { Settings } from '@/layout/components'
export default { export default {
name: 'Profile', name: 'Profile',
components: { components: {
UserCard, UserCard,
Role Role,
Settings
}, },
data() { data() {
return { return {
@ -44,7 +49,24 @@ export default {
'name', 'name',
'avatar', 'avatar',
'roles' 'roles'
]) ]),
...mapState({
sidebar: state => state.app.sidebar,
device: state => state.app.device,
showSettings: state => state.settings.showSettings,
needTagsView: state => state.settings.tagsView,
fixedHeader: state => state.settings.fixedHeader,
showNavar: state => state.settings.showNavar,
showMenu: state => state.settings.showMenu
}),
classObj() {
return {
hideSidebar: !this.sidebar.opened,
openSidebar: this.sidebar.opened,
withoutAnimation: this.sidebar.withoutAnimation,
mobile: this.device === 'mobile'
}
}
}, },
created() { created() {
this.getUser() this.getUser()