[Update] 拆分table action left side

This commit is contained in:
ibuler 2020-05-15 12:24:34 +08:00
parent 7b98582a7f
commit c5ab4befab
7 changed files with 240 additions and 176 deletions

View File

@ -83,7 +83,6 @@ export default {
if (!item) { if (!item) {
return true return true
} }
// this.$log.debug('Item is: ', item)
let ok = item[attr] let ok = item[attr]
if (ok && typeof ok === 'function') { if (ok && typeof ok === 'function') {
ok = ok(item) ok = ok(item)
@ -94,12 +93,12 @@ export default {
}, },
cleanActions(actions) { cleanActions(actions) {
const cleanedActions = [] const cleanedActions = []
// this.$log.debug('Start clean actions: ', actions) const cloneActions = _.cloneDeep(actions)
for (const v of actions) { for (const v of cloneActions) {
if (!v) { if (!v) {
continue continue
} }
const action = _.cloneDeep(v) const action = Object.assign({}, v)
// action // action
const has = this.checkItem(action, 'has') const has = this.checkItem(action, 'has')
delete action['has'] delete action['has']
@ -111,7 +110,6 @@ export default {
delete action['can'] delete action['can']
action.disabled = !can action.disabled = !can
cleanedActions.push(action) cleanedActions.push(action)
// callback // callback
delete action['callback'] delete action['callback']
} }

View File

@ -0,0 +1,155 @@
<template>
<ActionsGroup v-if="hasLeftActions" :actions="actions" :more-actions="moreActions" :more-actions-title="moreActionsTitle" class="header-action" />
</template>
<script>
import ActionsGroup from '@/components/ActionsGroup'
import { createSourceIdCache } from '@/api/common'
import { cleanActions } from './utils'
const defaultTrue = { type: Boolean, default: true }
const defaultFalse = { type: Boolean, default: false }
export default {
name: 'LeftSide',
components: {
ActionsGroup
},
props: {
hasCreate: defaultTrue,
hasBulkDelete: defaultTrue,
hasBulkUpdate: defaultFalse,
hasLeftActions: defaultTrue,
tableUrl: {
type: String,
default: ''
},
createRoute: {
type: String,
default: function() {
return this.$route.name.replace('List', 'Create')
}
},
reloadTable: {
type: Function,
default: () => {}
},
performBulkDelete: {
type: Function,
default: null
},
selectedRows: {
type: Array,
default: () => ([])
},
extraActions: {
type: Array,
default: () => ([])
},
extraMoreActions: {
type: Array,
default: () => ([])
},
moreActionsTitle: {
type: String,
default: null
}
},
data() {
return {
defaultActions: [
{
name: 'actionCreate',
title: this.$t('common.Create'),
type: 'primary',
has: this.hasCreate,
can: true,
callback: this.handleCreate
}
],
defaultMoreActions: [
{
title: this.$t('common.deleteSelected'),
name: 'actionDeleteSelected',
has: this.hasBulkDelete,
can({ selectedRows }) {
return selectedRows.length > 0
},
callback: this.defaultBulkDeleteCallback
},
{
title: this.$t('common.updateSelected'),
name: 'actionUpdateSelected',
has: this.hasBulkUpdate,
can: ({ selectedRows }) => selectedRows.length > 0,
callback: this.handleBulkUpdate
}
]
}
},
computed: {
actions() {
const actions = [...this.defaultActions, ...this.extraActions]
return cleanActions(actions, true, {
selectedRows: this.selectedRows,
reloadTable: this.reloadTable
})
},
moreActions() {
const actions = [...this.defaultMoreActions, ...this.extraMoreActions]
return cleanActions(actions, true, {
selectedRows: this.selectedRows,
reloadTable: this.reloadTable
})
},
hasSelectedRows() {
return this.selectedRows.length > 0
}
},
methods: {
handleCreate() {
const routeName = this.createRoute
this.$router.push({ name: routeName })
this.$log.debug('handle create')
},
defaultBulkDeleteCallback({ selectedRows, reloadTable }) {
const msg = this.$t('common.deleteWarningMsg') + ' ' + selectedRows.length + ' ' + this.$t('common.rows') + ' ?'
const title = this.$t('common.Info')
const performDelete = this.performBulkDelete || this.defaultPerformBulkDelete
this.$alert(msg, title, {
type: 'warning',
confirmButtonClass: 'el-button--danger',
showCancelButton: true,
beforeClose: async(action, instance, done) => {
if (action !== 'confirm') return done()
instance.confirmButtonLoading = true
try {
await performDelete(selectedRows)
done()
reloadTable()
this.$message.success(this.$t('common.bulkDeleteSuccessMsg'))
} catch (error) {
this.$message.error(this.$t('common.bulkDeleteErrorMsg') + error)
} finally {
instance.confirmButtonLoading = false
}
}
}).catch(() => {
/* 取消*/
})
},
async defaultPerformBulkDelete(selectedRows) {
const ids = selectedRows.map((v) => {
return v.id
})
const data = await createSourceIdCache(ids)
const url = `${this.tableUrl}?spm=` + data.spm
return this.$axios.delete(url)
},
handleBulkUpdate({ selectedRows }) {
}
}
}
</script>
<style scoped>
</style>

View File

@ -2,7 +2,7 @@
<div class="table-header"> <div class="table-header">
<slot name="header"> <slot name="header">
<div class="table-header-left-side"> <div class="table-header-left-side">
<ActionsGroup v-if="hasLeftActions" :actions="actions" :more-actions="moreActions" :more-actions-title="moreActionsTitle" class="header-action" /> <LeftSide v-if="hasLeftActions" :selected-rows="selectedRows" v-bind="$attrs" v-on="$listeners" />
<span v-else> <span v-else>
<AutoDataSearch v-if="hasSearch" class="right-side-item action-search" :config="searchConfig" :url="tableUrl" @tagSearch="handleTagSearch" /> <AutoDataSearch v-if="hasSearch" class="right-side-item action-search" :config="searchConfig" :url="tableUrl" @tagSearch="handleTagSearch" />
</span> </span>
@ -20,7 +20,8 @@
import AutoDataSearch from '@/components/AutoDataSearch' import AutoDataSearch from '@/components/AutoDataSearch'
import DialogAction from '@/components/DialogAction' import DialogAction from '@/components/DialogAction'
import ActionsGroup from '@/components/ActionsGroup' import ActionsGroup from '@/components/ActionsGroup'
import { createSourceIdCache } from '@/api/common' import LeftSide from './LeftSide'
import { cleanActions } from './utils'
import _ from 'lodash' import _ from 'lodash'
const defaultTrue = { type: Boolean, default: true } const defaultTrue = { type: Boolean, default: true }
@ -31,18 +32,16 @@ export default {
components: { components: {
ActionsGroup, ActionsGroup,
DialogAction, DialogAction,
AutoDataSearch AutoDataSearch,
LeftSide
}, },
props: { props: {
hasExport: defaultTrue, hasExport: defaultTrue,
hasImport: defaultTrue, hasImport: defaultTrue,
hasRefresh: defaultTrue, hasRefresh: defaultTrue,
hasCreate: defaultTrue,
hasBulkDelete: defaultTrue,
hasBulkUpdate: defaultFalse,
hasLeftActions: defaultTrue, hasLeftActions: defaultTrue,
hasSearch: defaultTrue, hasSearch: defaultTrue,
hasRightActions: defaultTrue, hasRightActions: defaultFalse,
searchConfig: { searchConfig: {
type: Object, type: Object,
default: () => ({}) default: () => ({})
@ -51,83 +50,28 @@ export default {
type: String, type: String,
default: '' default: ''
}, },
createRoute: {
type: String,
default: function() {
return this.$route.name.replace('List', 'Create')
}
},
reloadTable: {
type: Function,
default: () => {}
},
performBulkDelete: {
type: Function,
default: null
},
searchTable: { searchTable: {
type: Function, type: Function,
default: () => {} default: () => {}
}, },
selectedRows: { selectedRows: {
type: Array, type: Array,
default: () => ([]) default: () => []
},
extraActions: {
type: Array,
default: () => ([])
},
extraMoreActions: {
type: Array,
default: () => ([])
},
extraRightSideActions: {
type: Array,
default: () => ([])
},
moreActionsTitle: {
type: String,
default: null
}, },
testFields: { testFields: {
type: Array, type: Array,
default() { default() {
return [] return []
} }
},
extraRightSideActions: {
type: Array,
default: () => []
} }
}, },
data() { data() {
return { return {
keyword: '', keyword: '',
defaultActions: [
{
name: 'actionCreate',
title: this.$t('common.Create'),
type: 'primary',
has: this.hasCreate,
can: true,
callback: this.handleCreate
}
],
defaultMoreActions: [
{
title: this.$t('common.deleteSelected'),
name: 'actionDeleteSelected',
has: this.hasBulkDelete,
can({ selectedRows }) {
console.log('Select rows lenght: ', selectedRows.length)
return selectedRows.length > 0
},
callback: this.defaultBulkDeleteCallback
},
{
title: this.$t('common.updateSelected'),
name: 'actionUpdateSelected',
has: this.hasBulkUpdate,
can: ({ selectedRows }) => selectedRows.length > 0,
callback: this.handleBulkUpdate
}
],
defaultRightSideActions: [ defaultRightSideActions: [
{ name: 'actionExport', fa: 'fa-download', has: this.hasExport, callback: this.handleExport }, { name: 'actionExport', fa: 'fa-download', has: this.hasExport, callback: this.handleExport },
{ name: 'actionImport', fa: 'fa-upload', has: this.hasImport, callback: this.handleImport }, { name: 'actionImport', fa: 'fa-upload', has: this.hasImport, callback: this.handleImport },
@ -140,15 +84,11 @@ export default {
computed: { computed: {
rightSideActions() { rightSideActions() {
const actions = [...this.defaultRightSideActions, ...this.extraRightSideActions] const actions = [...this.defaultRightSideActions, ...this.extraRightSideActions]
return this.cleanActions(actions) const params = {
}, selectedRows: this.selectedRows,
actions() { reloadTable: this.reloadTable
const actions = [...this.defaultActions, ...this.extraActions] }
return this.cleanActions(actions) return cleanActions(actions, true, params)
},
moreActions() {
const actions = [...this.defaultMoreActions, ...this.extraMoreActions]
return this.cleanActions(actions, true)
}, },
hasSelectedRows() { hasSelectedRows() {
return this.selectedRows.length > 0 return this.selectedRows.length > 0
@ -161,47 +101,6 @@ export default {
handleTagSearch(val) { handleTagSearch(val) {
this.searchTable(val) this.searchTable(val)
}, },
handleCreate() {
const routeName = this.createRoute
this.$router.push({ name: routeName })
this.$log.debug('handle create')
},
defaultBulkDeleteCallback({ selectedRows, reloadTable }) {
const msg = this.$t('common.deleteWarningMsg') + ' ' + selectedRows.length + ' ' + this.$t('common.rows') + ' ?'
const title = this.$t('common.Info')
const performDelete = this.performBulkDelete || this.defaultPerformBulkDelete
this.$alert(msg, title, {
type: 'warning',
confirmButtonClass: 'el-button--danger',
showCancelButton: true,
beforeClose: async(action, instance, done) => {
if (action !== 'confirm') return done()
instance.confirmButtonLoading = true
try {
await performDelete(selectedRows)
done()
reloadTable()
this.$message.success(this.$t('common.bulkDeleteSuccessMsg'))
} catch (error) {
this.$message.error(this.$t('common.bulkDeleteErrorMsg'))
} finally {
instance.confirmButtonLoading = false
}
}
}).catch(() => {
/* 取消*/
})
},
async defaultPerformBulkDelete({ selectedRows }) {
const ids = selectedRows.map((v) => {
return v.id
})
const data = await createSourceIdCache(ids)
const url = `${this.tableUrl}?spm=` + data.spm
return this.$axios.delete(url)
},
handleBulkUpdate({ selectedRows }) {
},
handleExport({ selectedRows }) { handleExport({ selectedRows }) {
this.$eventBus.$emit('showExportDialog', { selectedRows }) this.$eventBus.$emit('showExportDialog', { selectedRows })
}, },
@ -210,47 +109,6 @@ export default {
}, },
handleRefresh() { handleRefresh() {
this.reloadTable() this.reloadTable()
},
cleanActions(actions, canDefaults) {
// this.$log.debug('Start clean actions: ', canDefaults)
actions = actions.map((action) => {
action.has = this.cleanBoolean(action, 'has')
action.can = this.cleanBoolean(action, 'can', canDefaults)
action.callback = this.cleanCallback(action)
return action
})
return actions
},
cleanBoolean(action, attr, defaults) {
// this.$log.debug('Clean boolean', action, attr)
let v = action[attr]
if (defaults === undefined) {
defaults = true
}
if (v === undefined) {
// console.log('Defaults is: ', attr, defaults)
v = defaults
}
if (typeof v === 'function') {
return () => v({
selectedRows: this.selectedRows,
reloadTable: this.reloadTable
})
} else {
return v
}
},
cleanCallback(action) {
const v = action.callback
if (!v && typeof callback !== 'function') {
return null
}
return () => v({
selectedRows: this.selectedRows,
reloadTable: this.reloadTable
})
} }
} }
} }

View File

@ -0,0 +1,40 @@
export function cleanActions(actions, canDefaults, { selectedRows, reloadTable }) {
// console.log('Start clean actions: ', selectedRows.length, reloadTable)
const cleanedActions = []
const cloneActions = _.cloneDeep(actions)
cloneActions.forEach((action) => {
action.has = cleanBoolean(action, 'has', true, { selectedRows, reloadTable })
action.can = cleanBoolean(action, 'can', true, { selectedRows, reloadTable })
action.callback = cleanCallback(action, { selectedRows, reloadTable })
cleanedActions.push(action)
})
return cleanedActions
}
export function cleanBoolean(action, attr, defaults, { selectedRows, reloadTable }) {
// this.$log.debug('Clean boolean', action, attr)
let valueOrCallback = action[attr]
if (defaults === undefined) {
defaults = true
}
if (valueOrCallback === undefined) {
valueOrCallback = defaults
}
if (typeof valueOrCallback !== 'function') {
return valueOrCallback
}
function wrapperCallback() {
return valueOrCallback({ selectedRows, reloadTable })
}
return wrapperCallback
}
export function cleanCallback(action, { selectedRows, reloadTable }) {
const v = action.callback
if (!v && typeof callback !== 'function') {
return null
}
return () => v({ selectedRows, reloadTable })
}

View File

@ -174,8 +174,8 @@
"Open": "打开", "Open": "打开",
"Close": "关闭", "Close": "关闭",
"DateCreated": "创建日期", "DateCreated": "创建日期",
"bulkDeleteSuccessMsg": "", "bulkDeleteSuccessMsg": "批量删除成功",
"bulkDeleteErrorMsg": "", "bulkDeleteErrorMsg": "批量删除失败: ",
"Test": "", "Test": "",
"Action": "动作", "Action": "动作",
"Update success": "", "Update success": "",
@ -183,10 +183,23 @@
"Push": "", "Push": "",
"createBy": "创建者", "createBy": "创建者",
"isValid": "", "isValid": "",
"Update": "更新" "Update": "更新",
"comment": "",
"delete": "",
"actions": {
"Create": "",
"cancel": ""
}
}, },
"applications": { "applications": {
"type": "",
"host": "",
"port": "",
"database": "",
"": "",
"asset": "",
"appType": "",
"appPath": ""
}, },
"assets": { "assets": {
"Assets": "资产", "Assets": "资产",

View File

@ -19,12 +19,12 @@ export default {
'name', 'username', 'groups_display', 'role', 'source', 'is_valid', 'actions' 'name', 'username', 'groups_display', 'role', 'source', 'is_valid', 'actions'
], ],
columnsMeta: { columnsMeta: {
source: { // source: {
width: '120px' // width: '120px'
}, // },
role: { // role: {
width: '100px' // width: '100px'
}, // },
groups_display: { groups_display: {
width: '200px', width: '200px',
showOverflowTooltip: true showOverflowTooltip: true
@ -48,8 +48,8 @@ export default {
{ {
name: 'disableSelected', name: 'disableSelected',
title: this.$t('common.disableSelected'), title: this.$t('common.disableSelected'),
can: ({ selectedRows }) => { can({ selectedRows }) {
console.log('can select rows lenght: ', selectedRows.length) console.log('disableSelected Select rows length: ', selectedRows.length)
return selectedRows.length > 0 return selectedRows.length > 0
}, },
callback({ selectedRows, reloadTable }) { callback({ selectedRows, reloadTable }) {