Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

KYLIN-5309 exclude columns frontend #2080

Merged
merged 1 commit into from
Jan 29, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,332 @@
<template>
<el-dialog class="edit-exclude-column-dialog"
width="800px"
:title="$t(excludeColumntitle)"
:visible="isShow"
:close-on-press-escape="false"
:close-on-click-modal="false"
@close="handleClose">
<div class="ksd-mb-16" v-html="$t('excludeDesc')"></div>
<div class="ksd-title-label-mini ksd-mb-8">{{$t('selectTable')}}</div>
<el-select
class="exclude_rule-select ksd-mb-16"
v-model="excluded_table"
@change="getExcludeColumns"
filterable
:disabled="!!excludeTable"
remote
:remote-method="filterExcludeTables"
:placeholder="$t('kylinLang.common.pleaseSelectOrSearch')"
style="width: 100%"
:loading="loading">
<el-option
v-for="item in excludeRuleOptions"
:key="item.value"
:label="item.label"
:value="item.value">
<span>{{item.label}}<i v-if="item.fact" class="el-icon-ksd-fact_table ksd-ml-5"></i></span>
</el-option>
<p class="limit-excluded-tables-msg" v-if="showIimitExcludedTableMsg">{{$t('limitExcludedTablesTip')}}</p>
</el-select>
<div class="ksd-title-label-mini columns-header ksd-mb-8">
<span>{{$t('selectColumns')}}</span>
<el-input
class="filter-input"
prefix-icon="el-ksd-icon-search_22"
size="small"
v-model="filterText"
@input="filterChange"
:placeholder="$t('filterByColumns')">
</el-input>
</div>
<el-table
:data="columns"
:empty-text="emptyText"
class="column-table"
@selection-change="handleSelectionChange"
style="width: 100%">
<el-table-column type="selection" align="center" width="42"></el-table-column>
<el-table-column
type="index"
label="ID"
width="64"
show-overflow-tooltip
:index="startIndex">
</el-table-column>
<el-table-column
prop="name"
min-width="300"
show-overflow-tooltip
:label="$t('kylinLang.dataSource.columnName')">
</el-table-column>
<el-table-column
prop="datatype"
min-width="120"
show-overflow-tooltip
:label="$t('kylinLang.dataSource.dataType')">
</el-table-column>
<el-table-column
prop="comment"
min-width="100"
show-overflow-tooltip
:render-header="renderCommentHeader">
<template slot-scope="scope">
<span :title="scope.row.comment">{{scope.row.comment}}</span>
</template>
</el-table-column>
</el-table>
<kap-pager
class="ksd-center ksd-mt-16" ref="columnPager"
:refTag="pageRefTags.exclusionColumnsPager"
:totalSize="columnsTotalSize"
:curPage="pagination.page_offset + 1"
:perPageSize="pagination.page_size"
@handleCurrentChange="handleCurrentChange">
</kap-pager>
<div slot="footer" class="dialog-footer">
<el-popover
ref="popover"
placement="top"
width="200"
v-model="confirmSubmitVisible"
trigger="click">
<div class="popover-title">
<el-icon name="el-ksd-n-icon-warning-color-filled" class="ksd-fs-16" type="mult"></el-icon><span class="ksd-title-label-mini">{{isDelExcludeMode ? $t('delAllColumnTitle') : $t('addAllColumnTitle')}}</span>
</div>
<div class="ksd-center ksd-mt-16">
<el-button style="width: 96px" size="small" @click="confirmSubmitVisible = false">{{$t('kylinLang.common.cancel')}}</el-button><el-button
type="primary" size="small" style="width: 96px" @click="confirmSubmit">{{$t('kylinLang.common.ok')}}</el-button>
</div>
</el-popover>

<el-button type="primary" text v-popover:popover v-show="columnsTotalSize&&!loadingSubmit">{{isDelExcludeMode ? $t('delAllColumnBtn') : $t('addAllColumnBtn')}}</el-button>
<el-button size="medium" @click="handleClose">{{$t('kylinLang.common.cancel')}}</el-button>
<el-button type="primary" size="medium" :loading="loadingSubmit" :disabled="!selectCols.length" @click="submit(false)">{{isDelExcludeMode ? $t('kylinLang.common.delete') : $t('kylinLang.common.add')}}</el-button>
</div>
</el-dialog>
</template>

<script>
import Vue from 'vue'
import { Component, Watch } from 'vue-property-decorator'
import { mapState, mapMutations, mapActions, mapGetters } from 'vuex'
import { handleError, handleSuccessAsync, ArrayFlat } from 'util'
import { pageRefTags, pageCount } from 'config'

import store from './store'
import locales from './locales'
import vuex, { actionTypes } from '../../../store'

vuex.registerModule(['modals', 'ExcludeColumnsDialog'], store)

@Component({
computed: {
...mapGetters([
'currentSelectedProject'
]),
...mapState('ExcludeColumnsDialog', {
isShow: state => state.isShow,
excludeTable: state => state.excludeTable,
excludeColumntitle: state => state.excludeColumntitle,
callback: state => state.callback
})
},
methods: {
...mapActions({
fetchDBandTables: 'FETCH_DB_AND_TABLES',
loadExcludeColumns: 'LOAD_EXCLUDE_COLUMNS',
updateExcludeColumns: 'UPDATE_EXCLUDE_CLUMNS'
}),
...mapMutations('ExcludeColumnsDialog', {
setModalForm: actionTypes.SET_MODAL_FORM,
setModal: actionTypes.SET_MODAL,
hideModal: actionTypes.HIDE_MODAL,
initModal: actionTypes.INIT_MODAL
})
},
locales
})
export default class ExcludeColumnsDialog extends Vue {
pageRefTags = pageRefTags
loadingSubmit = false
excludeRuleOptions = []
showIimitExcludedTableMsg = false
filterExcludeTablesTimer = null
dbInfoFilter = {
project_name: '',
source_type: 9,
page_offset: 0,
page_size: 10,
table: ''
}
excluded_table = ''
loading = false
pagination = {
page_offset: 0,
page_size: +localStorage.getItem(this.pageRefTags.exclusionColumnsPager) || pageCount
}
filterText = ''
columns = []
columnsTotalSize = 0
confirmSubmitVisible = false
selectCols = []

get startIndex () {
const { page_offset, page_size } = this.pagination
return page_offset * page_size + 1
}

get emptyText () {
return this.filterText ? this.$t('kylinLang.common.noResults') : this.$t('kylinLang.common.noData')
}

filterChange () {
this.pagination.page_offset = 0
this.getExcludeColumns(this.excluded_table)
}

reset () {
this.loadingSubmit = false
this.excludeRuleOptions = []
this.showIimitExcludedTableMsg = false
this.excluded_table = ''
this.filterText = ''
this.columns = []
this.columnsTotalSize = 0
this.confirmSubmitVisible = false
this.selectCols = []
}

handleClose (isSubmit = false) {
this.reset()
this.hideModal()
this.callback && this.callback(isSubmit)
}

handleSelectionChange (cols) {
this.selectCols = cols
}

async submit (isExcludedAll) {
try {
this.loadingSubmit = true
const data = {
project: this.currentSelectedProject,
canceled_tables: !!isExcludedAll && this.isDelExcludeMode ? [this.excluded_table] : [],
excluded_tables: [
{
table: this.excluded_table,
excluded: !!isExcludedAll && !this.isDelExcludeMode,
added_columns: !isExcludedAll && !this.isDelExcludeMode ? this.selectCols.map((c) => {
return c.name
}) : [],
removed_columns: !isExcludedAll && this.isDelExcludeMode ? this.selectCols.map((c) => {
return c.name
}) : []
}
]
}
await this.updateExcludeColumns(data)
this.callback && this.callback(true)
this.hideModal()
} catch (e) {
this.loadingSubmit = false
handleError(e)
}
}
confirmSubmit () {
this.confirmSubmitVisible = false
this.submit(true)
}

get isDelExcludeMode () {
return this.excludeColumntitle === 'delExcludeColumns'
}

async getExcludeColumns (val) {
try {
if (!val) return
// excluded_col_type 展示的屏蔽列类型,可选,默认值 0代表待屏蔽列,1代表屏蔽列,其他值无效
const res = await this.loadExcludeColumns({ ...this.pagination, project: this.currentSelectedProject, table: val, key: this.filterText, col_type: this.isDelExcludeMode ? 1 : 0 })
const { admitted_columns, excluded_columns, total_size } = await handleSuccessAsync(res)
this.columns = this.isDelExcludeMode ? excluded_columns : admitted_columns
this.columnsTotalSize = total_size
} catch (e) {
handleError(e)
}
}

handleCurrentChange (page_offset, pageSize) {
this.pagination.page_offset = page_offset
this.pagination.page_size = pageSize
this.getExcludeColumns(this.excluded_table)
}

renderCommentHeader (h, { column, $index }) {
return (<span class="ky-hover-icon" onClick={e => (e.stopPropagation())}>
<span>{this.$t('kylinLang.dataSource.comment')}</span>&nbsp;
<common-tip placement="top" content={this.$t('commentTip')}>
<span class='el-ksd-icon-more_info_22 ksd-fs-22'></span>
</common-tip>
</span>)
}

// 获取 database 和 tables 信息(显示前 50 条记录)
async getDbAndTablesInfo () {
try {
this.dbInfoFilter.project_name = this.currentSelectedProject
const response = await this.fetchDBandTables(this.dbInfoFilter)
const results = await handleSuccessAsync(response)
const { databases } = results
let dbList = databases ? ArrayFlat(databases.map(item => item.tables)) : []
if (dbList.length) {
this.excludeRuleOptions = dbList.map(it => ({label: `${it.database}.${it.name}`, value: `${it.database}.${it.name}`, fact: it.root_fact})).slice(0, 50)
this.showIimitExcludedTableMsg = dbList.length > 50
}
} catch (e) {
handleError(e)
}
}

// 过滤 db 或 table
filterExcludeTables (name) {
clearTimeout(this.filterExcludeTablesTimer)
this.filterExcludeTablesTimer = setTimeout(() => {
this.dbInfoFilter.table = name
this.getDbAndTablesInfo()
}, 500)
}

@Watch('isShow')
onModalShow (val) {
if (val) {
// 新增一张表的屏蔽列时,要拉取数据源表数据
if (this.excludeColumntitle === 'addExcludeColumns') {
this.getDbAndTablesInfo()
}
if (this.excludeTable) {
this.excluded_table = this.excludeTable
this.getExcludeColumns(this.excluded_table)
}
}
}
}
</script>

<style lang="less">
@import '../../../assets/styles/variables.less';
.edit-exclude-column-dialog {
.el-dialog__body {
padding: 20px;
.columns-header span{
display: inline-block;
height: 30px;
line-height: 30px;
}
.filter-input {
width: 210px;
float: right;
}
}
}
</style>
32 changes: 32 additions & 0 deletions kystudio/src/components/common/EditExcludeColumnsDialog/locales.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
export default {
en: {
addExcludeColumns: 'Add Exclude Columns',
appendExcludeColumns: 'Append Exclude Columns',
delExcludeColumns: 'Delete Exclude Columns',
limitExcludedTablesTip: 'Only 50 tables would be displayed. Please enter keyword to search.',
selectTable: 'Select Table',
selectColumns: 'Select Columns',
filterByColumns: 'Search by column name',
delAllColumnTitle: 'Are you sure you want to delete all exclude columns?',
addAllColumnTitle: 'Are you sure you want to exclude all columns?',
delAllColumnBtn: 'Delete all columns',
addAllColumnBtn: 'Add all columns',
commentTip: 'Synced from the source table.',
excludeDesc: 'Please pay attention that excluded column can only be set to lookup table,in order to solve SCD problems.<br/>If you want to exclude a whole table,you can exclude all columns of the table.'
},
'zh-cn': {
addExcludeColumns: '添加屏蔽列',
appendExcludeColumns: '增加屏蔽列',
delExcludeColumns: '删除屏蔽列',
limitExcludedTablesTip: '默认仅展示 50 张表。请输入关键词进行搜索。',
selectTable: '选择表',
selectColumns: '选择列',
filterByColumns: '搜索列名',
delAllColumnTitle: '确定要删除所有屏蔽列?',
addAllColumnTitle: '确定要屏蔽所有列?',
delAllColumnBtn: '删除所有屏蔽列',
addAllColumnBtn: '屏蔽所有列',
commentTip: '从数据源中同步的注释信息。',
excludeDesc: '请注意屏蔽列仅用于维度表,用于解决缓慢变化维的问题。<br/> 如果您想使用旧版本的“屏蔽表”功能,在当前版本等同于屏蔽一张表中所有的列。'
}
}