1
0
mirror of https://github.com/PanJiaChen/vue-element-admin.git synced 2025-08-10 12:01:57 +08:00

Add lock and unlock record to record access dialog box (#805)

* Add lock and unlock record to record access dialog box

* minima change

* support mobile

* minimal changes

* delete comment

* minimal changes

Co-authored-by: elsiosanchez <elsiosanche@gmail.com>
Co-authored-by: elsiosanchez <elsiossanches@gmail.com>
This commit is contained in:
Elsio Sanchez 2021-05-05 18:01:37 -04:00 committed by GitHub
parent 51a412499f
commit 7fe1ea0f88
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 372 additions and 70 deletions

View File

@ -119,6 +119,28 @@
</div> </div>
</div> </div>
</el-dropdown-item> </el-dropdown-item>
<el-dropdown-item
command="shareLink"
:divided="true"
>
<div class="contents">
<div style="margin-right: 5%;margin-top: 10%;">
<i class="el-icon-copy-document" style="font-weight: bolder;" />
</div>
<div>
<span class="contents">
<b class="label">
{{ $t('components.contextMenuShareLink') }}
</b>
</span>
<p
class="description"
>
{{ $t('data.noDescription') }}
</p>
</div>
</div>
</el-dropdown-item>
</el-scrollbar> </el-scrollbar>
</el-dropdown-menu> </el-dropdown-menu>
</el-dropdown> </el-dropdown>
@ -268,6 +290,8 @@ export default {
clickRunAction(action) { clickRunAction(action) {
if (action === 'refreshData') { if (action === 'refreshData') {
this.refreshData() this.refreshData()
} else if (action === 'shareLink') {
this.setShareLink()
} else if (action.action === 'recordAccess') { } else if (action.action === 'recordAccess') {
this.$store.commit('changeShowRigthPanel', true) this.$store.commit('changeShowRigthPanel', true)
this.$store.commit('setRecordAccess', true) this.$store.commit('setRecordAccess', true)

View File

@ -73,6 +73,28 @@
</div> </div>
</div> </div>
</el-dropdown-item> </el-dropdown-item>
<el-dropdown-item
command="shareLink"
:divided="true"
>
<div class="contents">
<div style="margin-right: 5%;margin-top: 10%;">
<i class="el-icon-copy-document" style="font-weight: bolder;" />
</div>
<div>
<span class="contents">
<b class="label">
{{ $t('components.contextMenuShareLink') }}
</b>
</span>
<p
class="description"
>
{{ $t('data.noDescription') }}
</p>
</div>
</div>
</el-dropdown-item>
</el-dropdown-menu> </el-dropdown-menu>
</el-dropdown> </el-dropdown>
<!-- menu relations --> <!-- menu relations -->
@ -218,6 +240,8 @@ export default {
clickRunAction(action) { clickRunAction(action) {
if (action === 'refreshData') { if (action === 'refreshData') {
this.refreshData() this.refreshData()
} else if (action === 'shareLink') {
this.setShareLink()
} else if (action.action === 'recordAccess') { } else if (action.action === 'recordAccess') {
this.$store.commit('changeShowRigthPanel', true) this.$store.commit('changeShowRigthPanel', true)
this.$store.commit('setRecordAccess', true) this.$store.commit('setRecordAccess', true)

View File

@ -21,6 +21,7 @@
show-close show-close
:before-close="closeDialog" :before-close="closeDialog"
:width="width + '%'" :width="width + '%'"
custom-class="embedded-style"
top="5vh" top="5vh"
close-on-press-escape close-on-press-escape
close-on-click-modal close-on-click-modal
@ -80,7 +81,7 @@ export default {
if (this.isMobile) { if (this.isMobile) {
return 80 return 80
} }
return 70 return 90
}, },
attributeEmbedded() { attributeEmbedded() {
return this.$store.getters.getAttributeEmbedded return this.$store.getters.getAttributeEmbedded
@ -213,7 +214,7 @@ export default {
<style> <style>
.el-dialog__body { .el-dialog__body {
padding: 10px 20px; padding: 10px 20px;
max-height: 75vh; max-height: 90%;
overflow: auto; overflow: auto;
} }
.el-dialog__header { .el-dialog__header {
@ -221,4 +222,7 @@ export default {
padding-bottom: 10px; padding-bottom: 10px;
background: #dae6f38c; background: #dae6f38c;
} }
.embedded-style {
height: 77%;
}
</style> </style>

View File

@ -58,7 +58,6 @@
icon="el-icon-close" icon="el-icon-close"
@click="closeDialog" @click="closeDialog"
/> />
alooooooooo
<el-button <el-button
type="primary" type="primary"
icon="el-icon-check" icon="el-icon-check"
@ -225,11 +224,6 @@ export default {
} }
} }
} }
if (action.action === undefined) {
const list = this.$store.getters.getListRecordAcces
// updateAccessRecord(list)
console.log(list)
}
} }
} }
} }

View File

@ -68,7 +68,7 @@ export default {
excludedList: { excludedList: {
get() { get() {
if (this.recordAccess.roles) { if (this.recordAccess.roles) {
return this.recordAccess.roles.filter(role => !role.isLocked) return this.recordAccess.roles.filter(role => !role.isRoleConfig)
} else { } else {
return [] return []
} }
@ -79,7 +79,7 @@ export default {
includedList: { includedList: {
get() { get() {
if (this.recordAccess.roles) { if (this.recordAccess.roles) {
return this.recordAccess.roles.filter(role => role.isLocked) return this.recordAccess.roles.filter(role => role.isRoleConfig)
} else { } else {
return [] return []
} }
@ -105,13 +105,16 @@ export default {
access.availableRoles.forEach(role => { access.availableRoles.forEach(role => {
this.recordAccess.roles.push({ this.recordAccess.roles.push({
...role, ...role,
isLocked: false isRoleConfig: false,
isLocked: role.isExclude
}) })
}) })
access.currentRoles.forEach(role => { access.currentRoles.forEach(role => {
this.recordAccess.roles.find(availableRole => availableRole.roleId === role.roleId).isLocked = true this.recordAccess.roles.find(availableRole => availableRole.roleId === role.roleId).isLocked = role.isExclude
this.recordAccess.roles.find(availableRole => availableRole.roleId === role.roleId).isRoleConfig = true
this.recordAccess.roles.find(availableRole => availableRole.roleId === role.roleId).isDependentEntities = role.isDependentEntities this.recordAccess.roles.find(availableRole => availableRole.roleId === role.roleId).isDependentEntities = role.isDependentEntities
this.recordAccess.roles.find(availableRole => availableRole.roleId === role.roleId).isReadOnly = role.isReadOnly this.recordAccess.roles.find(availableRole => availableRole.roleId === role.roleId).isReadOnly = role.isReadOnly
this.recordAccess.roles.find(availableRole => availableRole.roleId === role.roleId).isExclude = role.isExclude
}) })
}) })
}, },
@ -143,7 +146,7 @@ export default {
index, index,
element element
}) { }) {
this.recordAccess.roles[index].isLocked = true this.recordAccess.roles[index].isRoleConfig = true
}, },
/** /**
* @param {number} index: the index of the element before remove * @param {number} index: the index of the element before remove
@ -153,7 +156,7 @@ export default {
index, index,
element element
}) { }) {
this.recordAccess.roles[index].isLocked = false this.recordAccess.roles[index].isRoleConfig = false
}, },
getOrder(arrayToSort, orderBy = this.order) { getOrder(arrayToSort, orderBy = this.order) {
return arrayToSort.sort((itemA, itemB) => { return arrayToSort.sort((itemA, itemB) => {
@ -181,6 +184,16 @@ export default {
console.warn(`setPreference error: ${error.message}.`) console.warn(`setPreference error: ${error.message}.`)
}) })
}, },
validateList(list) {
list.forEach(element => {
if (element.isExclude) {
element.isReadOnly = false
} else {
element.isDependentEntities = false
}
})
return list
},
close() { close() {
this.$store.dispatch('setShowDialog', { this.$store.dispatch('setShowDialog', {
type: 'window', type: 'window',

View File

@ -22,11 +22,11 @@
:key="1" :key="1"
class="kanban todo" class="kanban todo"
header-text="Todo" header-text="Todo"
style="padding: 0px;margin: 0px;width: 35%;padding-right: 3%;" style="padding: 0px;margin: 0px;width: 35%;padding-right: 2%;"
> >
<div class="board-column"> <div class="board-column">
<div class="board-column-header"> <div class="board-column-header">
{{ $t('data.recordAccess.hideRecord') }} ({{ excludedList.length }}) {{ $t('data.recordAccess.availableRoles') }} ({{ excludedList.length }})
</div> </div>
<draggable <draggable
v-model="excludedList" v-model="excludedList"
@ -38,17 +38,24 @@
v-for="(element, index) in excludedList" v-for="(element, index) in excludedList"
:key="element.roleUuid" :key="element.roleUuid"
class="board-item" class="board-item"
style="height: 50%;padding-left: 0px;padding-right: 0px;" style="height: 50%;padding-left: 0px;padding-right: 0px;min-width: 250px;max-width: 100%;"
> >
<el-table <el-table
v-if="!isEmptyValue(excludedList)" v-if="!isEmptyValue(excludedList)"
:data="[excludedList[index]]" :data="[excludedList[index]]"
border border
:show-header="false" :show-header="false"
style="min-width: 100%;padding-left: 0%;padding-right: 0%;"
> >
<el-table-column <el-table-column>
prop="roleName" <template slot-scope="scope">
/> <b style="white-space: normal;">
{{
scope.row.roleName
}}
</b>
</template>
</el-table-column>
</el-table> </el-table>
</div> </div>
@ -59,11 +66,11 @@
:key="2" :key="2"
class="kanban working" class="kanban working"
header-text="Working" header-text="Working"
style="padding: 0px;margin: 0px;width: 65%;padding-right: 3%;" style="padding: 0px;margin: 0px;width: 65%;padding-right: 1.5%;"
> >
<div class="board-column"> <div class="board-column">
<div class="board-column-header"> <div class="board-column-header">
{{ $t('data.recordAccess.recordDisplay') }} ({{ includedList.length }}) {{ $t('data.recordAccess.configRoles') }} ({{ includedList.length }})
</div> </div>
<draggable <draggable
v-model="includedList" v-model="includedList"
@ -76,26 +83,50 @@
v-for="(element, index) in includedList" v-for="(element, index) in includedList"
:key="element.roleUuid" :key="element.roleUuid"
class="board-item" class="board-item"
style="height: 50%;padding-left: 0px;padding-right: 0px;min-width: 550px;max-width: 100%;" style="height: 50%;padding-left: 0px;padding-right: 0px;min-width: 400px;max-width: 100%;"
> >
<el-table <el-table
v-if="!isEmptyValue(includedList)" v-if="!isEmptyValue(includedList)"
:data="[includedList[index]]" :data="[includedList[index]]"
border border
:show-header="false" :show-header="false"
style="min-width: 120%;padding-left: 0%;padding-right: 0%;" style="padding-left: 0%;padding-right: 0%;"
> >
<el-table-column
prop="roleName"
/>
<el-table-column> <el-table-column>
<template slot-scope="scope"> <template slot-scope="scope">
{{ $t('data.recordAccess.isReadonly') }} <el-switch v-model="scope.row.isReadOnly" /> <b style="white-space: normal;">
{{
scope.row.roleName
}}
</b>
</template>
</el-table-column>
<el-table-column min-width="100">
<template slot-scope="scope">
<el-switch
v-model="scope.row.isExclude"
active-color="#13ce66"
inactive-color="#ff4949"
:inactive-text="$t('data.recordAccess.isLock')"
:active-text="$t('data.recordAccess.isUnlock')"
/>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column> <el-table-column>
<template slot-scope="scope" min-width="150"> <template slot-scope="scope">
{{ $t('data.recordAccess.isDependentEntities') }} <el-switch v-model="scope.row.isDependentEntities" /> <div v-if="scope.row.isExclude">
<el-switch
v-model="scope.row.isReadOnly"
:inactive-text="$t('data.recordAccess.isReadonly')"
active-text="Editable"
/>
</div>
<div v-else>
<b>
{{ $t('data.recordAccess.isDependentEntities') }}
</b>
<el-switch v-model="scope.row.isDependentEntities" />
</div>
</template> </template>
</el-table-column> </el-table-column>
</el-table> </el-table>
@ -174,8 +205,19 @@ export default {
} }
</style> </style>
<style lang="scss"> <style lang="scss">
.el-table .warning-row {
border: solid;
border-color: red;
background: white;
}
.el-table .success-row {
background: white;
border: solid;
border-color: #11b95c42;
}
.board-column .board-column-content[data-v-67e5b2d0] { .board-column .board-column-content[data-v-67e5b2d0] {
max-height: 350px; max-height: 55vh;
height: auto; height: auto;
overflow: auto; overflow: auto;
border: 10px solid transparent; border: 10px solid transparent;
@ -195,7 +237,7 @@ export default {
align-items: center; align-items: center;
} }
.board { .board {
height: 400px; height: 90%;
width: 100%; width: 100%;
margin-left: 20px; margin-left: 20px;
display: flex; display: flex;

View File

@ -1,20 +1,20 @@
<template> <template>
<div> <div>
<el-card class="box-card"> <el-card class="box-card">
<div slot="header" class="clearfix"> <div slot="header" class="clearfix" style="padding-bottom: 2%;">
<span> <span>
{{ $t('data.recordAccess.actions') }} {{ $t('data.recordAccess.actions') }}
</span> </span>
</div> </div>
<div style="margin-bottom: 10%;"> <div style="margin-bottom: 5%;">
<span style="margin-bottom: 10%;"> <span style="margin-bottom: 5%;">
{{ $t('data.recordAccess.hideRecord') }} ({{ labelListExcludo.length }}) {{ $t('data.recordAccess.availableRoles') }} ({{ labelListExcludo.length }})
</span> </span>
<br> <br>
<el-select <el-select
v-model="labelListExcludo" v-model="labelListExcludo"
multiple multiple
style="margin-top: 5%;" style="margin-top: 2.5%;"
filterable filterable
placeholder="Select" placeholder="Select"
collapse-tags collapse-tags
@ -28,22 +28,20 @@
/> />
</el-select> </el-select>
</div> </div>
<div <div>
style="margin-bottom: 10%;"
>
<span <span
style="margin-bottom: 10%;" style="margin-bottom: 5%;"
> >
{{ $t('data.recordAccess.recordDisplay') }} ({{ labelListInclude.length }}) {{ $t('data.recordAccess.modeMobile.accessRoles') }} ({{ labelListInclude.length }})
</span> </span>
<br> <br>
<el-select <el-select
v-model="labelListInclude" v-model="labelListInclude"
multiple multiple
style="margin-top: 5%;"
placeholder="Select" placeholder="Select"
filterable filterable
collapse-tags collapse-tags
style="margin-top: 2.5%;"
@change="addListInclude" @change="addListInclude"
> >
<el-option <el-option
@ -54,24 +52,87 @@
/> />
</el-select> </el-select>
</div> </div>
<el-form <!-- Roles with Access and Read Only -->
label-position="top" <div
size="small" style="padding-top: 9%;"
class="create-bp"
> >
<el-scrollbar wrap-class="scroll-panel-right-mode-mobile" style="max-height: 200px;"> <span
<el-row :gutter="24"> style="margin-bottom: 5%;"
<div style="margin-left: 5%;"> >
<p> {{ $t('data.recordAccess.modeMobile.accessRolesIsReadonly') }} ({{ listRolesLockReadOnly.length }})
{{ $t('data.recordAccess.isReadonly') }} <el-switch v-model="isReadonly" /> </span>
</p> <br>
<p> <el-select
{{ $t('data.recordAccess.isDependentEntities') }} <el-switch v-model="isDependentEntities" /> v-model="listRolesLockReadOnly"
</p> multiple
</div> placeholder="Select"
</el-row> filterable
</el-scrollbar> collapse-tags
</el-form> style="margin-top: 2.5%;"
@change="addRolesLockReadOnly"
>
<el-option
v-for="item in includedList.filter(element => element.isExclude)"
:key="item.roleUuid"
:label="item.roleName"
:value="item.roleName"
/>
</el-select>
</div>
<!-- Locked Roles -->
<div
style="padding-top: 9%;"
>
<span
style="margin-bottom: 5%;"
>
{{ $t('data.recordAccess.modeMobile.lockedRoles') }} ({{ listRolesLock.length }})
</span>
<br>
<el-select
v-model="listRolesLock"
multiple
placeholder="Select"
filterable
collapse-tags
style="margin-top: 2.5%;"
@change="addRolesLock"
>
<el-option
v-for="item in includedList"
:key="item.roleUuid"
:label="item.roleName"
:value="item.roleName"
/>
</el-select>
</div>
<!-- Locked Roles with Dependent Entities -->
<div
style="padding-top: 9%;"
>
<span
style="margin-bottom: 5%;"
>
{{ $t('data.recordAccess.modeMobile.lockedRolesIsDependentEntities') }} ({{ listRolesUnLock.length }})
</span>
<br>
<el-select
v-model="listRolesUnLock"
multiple
placeholder="Select"
filterable
collapse-tags
style="margin-top: 2.5%;"
@change="addlockedRolesIsDependentEntities"
>
<el-option
v-for="item in includedList.filter(element => !element.isExclude)"
:key="item.roleUuid"
:label="item.roleName"
:value="item.roleName"
/>
</el-select>
</div>
</el-card> </el-card>
<span style="float: right;padding-top: 1%;"> <span style="float: right;padding-top: 1%;">
<el-button <el-button
@ -139,6 +200,72 @@ export default {
return this.includedList.map(element => { return this.includedList.map(element => {
return element.roleName return element.roleName
}) })
},
listRolesLock: {
get() {
const list = this.includedList.filter(element => {
return !element.isExclude
})
if (list) {
return list.map(element => {
return element.roleName
})
}
return []
},
set(value) {
}
},
listRolesLockReadOnly: {
get() {
const list = this.includedList.filter(element => {
if (element.isExclude && element.isReadOnly) {
return element
}
})
if (list) {
return list.map(element => {
return element.roleName
})
}
return []
},
set(value) {
}
},
listLabelRolesLockReadOnly: {
get() {
const list = this.includedList.filter(element => {
if (!element.isExclude && element.isReadOnly) {
return element
}
})
if (list) {
return list.map(element => {
return element.roleName
})
}
return []
},
set(value) {
}
},
listRolesUnLock: {
get() {
const list = this.includedList.filter(element => {
if (!element.isExclude && element.isDependentEntities) {
return element
}
})
if (list) {
return list.map(element => {
return element.roleName
})
}
return []
},
set(value) {
}
} }
}, },
watch: { watch: {
@ -176,11 +303,56 @@ export default {
}) })
} }
}, },
SendRecorAccess(list) { addRolesLock(element) {
list.forEach(element => { const index = this.recordAccess.roles.findIndex(item => {
element.isReadOnly = this.isReadonly if (element[element.length - 1] === item.roleName) {
element.isDependentEntities = this.isDependentEntities return item
}
}) })
if (index >= 0) {
this.recordAccess.roles[index].isExclude = !this.recordAccess.roles[index].isExclude
}
},
addRolesLockReadOnly(element) {
const index = this.recordAccess.roles.find(item => {
if (element[element.length - 1] === item.roleName) {
return item
}
})
if (index) {
index.isReadOnly = !index.isReadOnly
} else {
const undo = this.recordAccess.roles.find(item => {
if (this.listRolesLockReadOnly[0] === item.roleName) {
return item
}
})
undo.isReadOnly = !undo.isReadOnly
}
},
addlockedRolesIsDependentEntities(element) {
const index = this.recordAccess.roles.find(item => {
if (element[element.length - 1] === item.roleName) {
return item
}
})
if (index) {
index.isDependentEntities = !index.isDependentEntities
} else {
const undo = this.recordAccess.roles.find(item => {
if (this.listRolesUnLock[0] === item.roleName) {
return item
}
})
undo.isDependentEntities = !undo.isDependentEntities
}
},
SendRecorAccess(list) {
// list.forEach(element => {
// element.isReadOnly = this.isReadonly
// element.isDependentEntities = this.isDependentEntities
// })
this.saveRecordAccess(list) this.saveRecordAccess(list)
} }
} }
@ -233,6 +405,19 @@ export default {
} }
</style> </style>
<style lang="scss"> <style lang="scss">
.el-card__header {
background: rgba(245, 247, 250, 0.75);
padding-top: 18px;
padding-right: 20px;
padding-bottom: 1%;
padding-left: 20px;
border-bottom: 1px solid #f5f7fa;
-webkit-box-sizing: border-box;
box-sizing: border-box;
}
.el-card__body {
padding-top: 2.5%;
}
.scroll-panel-right-mode-mobile { .scroll-panel-right-mode-mobile {
max-height: 200px; max-height: 200px;
overflow-y: auto; overflow-y: auto;

View File

@ -346,11 +346,19 @@ export default {
lockRecord: 'Lock Record', lockRecord: 'Lock Record',
noDescription: 'No Description', noDescription: 'No Description',
recordAccess: { recordAccess: {
modeMobile: {
accessRoles: 'Access Roles',
accessRolesIsReadonly: 'Roles with Access and Read Only',
lockedRoles: 'Locked Roles',
lockedRolesIsDependentEntities: 'Locked Roles with Dependent Entities'
},
actions: 'Record Access', actions: 'Record Access',
hideRecord: 'Hide Record', configRoles: 'Roles Configurados',
recordDisplay: 'Allow Record Display', availableRoles: 'Roles Configured',
isReadonly: 'Reading Only', isReadonly: 'Reading Only',
isDependentEntities: 'Dependent Entities' isDependentEntities: 'Dependent Entities',
isLock: 'Block',
isUnlock: 'Unblock'
}, },
selectionRequired: 'You must select a record', selectionRequired: 'You must select a record',
undo: 'Undo', undo: 'Undo',

View File

@ -322,11 +322,19 @@ export default {
lockRecord: 'Bloquear Registro', lockRecord: 'Bloquear Registro',
noDescription: 'Sin Descripción', noDescription: 'Sin Descripción',
recordAccess: { recordAccess: {
modeMobile: {
accessRoles: 'Roles con Acceso',
accessRolesIsReadonly: 'Roles con Acceso y Solo lectura',
lockedRoles: 'Roles Bloqueados',
lockedRolesIsDependentEntities: 'Roles Bloqueados con Entidades Dependientes'
},
actions: 'Acceso a Registros', actions: 'Acceso a Registros',
hideRecord: 'Ocultar Registro', availableRoles: 'Roles Disponibles',
recordDisplay: 'Permitir Visualización del Registro', configRoles: 'Roles Configurados',
isReadonly: 'Solo Lectura', isReadonly: 'Solo Lectura',
isDependentEntities: 'Entidades Dependientes' isDependentEntities: 'Entidades Dependientes',
isLock: 'Bloquear',
isUnlock: 'Desbloquear'
}, },
selectionRequired: 'Debe seleccionar un registro', selectionRequired: 'Debe seleccionar un registro',
undo: 'Deshacer', undo: 'Deshacer',