This is an automated email from the ASF dual-hosted git repository. xxyu pushed a commit to branch kylin5_beta in repository https://gitbox.apache.org/repos/asf/kylin.git
commit 163ca4eb5f66d585c5a0834c60233979c52b492d Author: Qian Xia <lauraxiaq...@gmail.com> AuthorDate: Thu Jul 20 18:25:59 2023 +0800 KYLIN-5662 model list lite issue --- .../common/ModelERDiagram/ModelERDiagram.vue | 18 +++--- kystudio/src/components/query/query_result.vue | 6 -- .../ModelList/ModelActions/modelActions.vue | 17 +++++- .../ModelList/ModelBuildModal/build.vue | 2 +- .../ModelList/ModelLayout/modelLayout.vue | 29 +++------- .../StudioModel/ModelList/ModelPartition/index.vue | 2 +- .../studio/StudioModel/ModelList/index.vue | 66 +++++++++------------- 7 files changed, 62 insertions(+), 78 deletions(-) diff --git a/kystudio/src/components/common/ModelERDiagram/ModelERDiagram.vue b/kystudio/src/components/common/ModelERDiagram/ModelERDiagram.vue index 4c945b356c..f978fa52d9 100644 --- a/kystudio/src/components/common/ModelERDiagram/ModelERDiagram.vue +++ b/kystudio/src/components/common/ModelERDiagram/ModelERDiagram.vue @@ -45,7 +45,7 @@ <script> import Vue from 'vue' import { Component } from 'vue-property-decorator' -import { handleSuccessAsync, objectClone } from 'util' +import { handleSuccessAsync, objectClone, dataGenerator } from 'util' import { columnTypeIcon } from '../../../config' import { mapActions, mapGetters, mapState, mapMutations } from 'vuex' import { initPlumb, drawLines, customCanvasPosition, createAndUpdateSvgGroup } from './handler' @@ -78,13 +78,14 @@ import locales from './locales' modelList: state => state.model.modelsList }), ...mapGetters([ - 'currentProjectData', + 'currentSelectedProject', 'isFullScreen' ]) }, methods: { ...mapActions({ - loadColumnOfModel: 'LOAD_DATASOURCE_OF_MODEL' + loadColumnOfModel: 'LOAD_DATASOURCE_OF_MODEL', + getModelByModelName: 'LOAD_MODEL_INFO' }), ...mapMutations({ toggleFullScreen: 'TOGGLE_SCREEN' @@ -97,6 +98,7 @@ import locales from './locales' }) export default class ModelERDiagram extends Vue { currentModel = null + modelData = null columnTypeIconMap = columnTypeIcon plumbTool = null plumbInstance = null @@ -137,6 +139,9 @@ export default class ModelERDiagram extends Vue { } async created () { this.loadingER = true + const res = await this.getModelByModelName({model_name: this.model.alias, project: this.currentSelectedProject}) + const { value } = await handleSuccessAsync(res) + this.modelData = dataGenerator.generateModel(value[0]) await this.getTableColumns() this.$nextTick(() => { const { plumbInstance, plumbTool } = initPlumb(this.$el.querySelector('.er-layout'), this.currentModel.canvas ?? this.defaultZoom) @@ -180,13 +185,12 @@ export default class ModelERDiagram extends Vue { } getTableColumns () { return new Promise((resolve, reject) => { - const { name } = this.currentProjectData const [{ canvas }] = this.modelList.filter(item => item.alias === this.model.name) - this.loadColumnOfModel({project: name, model_name: this.model.name}).then(async (result) => { + this.loadColumnOfModel({project: this.currentSelectedProject, model_name: this.model.name}).then(async (result) => { const values = await handleSuccessAsync(result) this.currentModel = { - ...this.model, - tables: this.model.tables.map(table => { + ...this.modelData, + tables: this.modelData.tables.map(table => { const [{ columns }] = values.filter(v => table.name === `${v.database}.${v.name}`) return { ...table, diff --git a/kystudio/src/components/query/query_result.vue b/kystudio/src/components/query/query_result.vue index c091bb7445..0217620557 100644 --- a/kystudio/src/components/query/query_result.vue +++ b/kystudio/src/components/query/query_result.vue @@ -200,8 +200,6 @@ import { scToFloat, showNull, handleSuccessAsync } from '../../util/index' import { hasRole, transToGmtTime, handleError } from '../../util/business' import { pageRefTags, pageCount } from 'config' import { getOptions, compareDataSize } from './handler' -import IndexDetails from '../studio/StudioModel/ModelList/ModelAggregate/indexDetails' -import ModelAggregate from '../studio/StudioModel/ModelList/ModelAggregate/index.vue' import echarts from 'echarts' @Component({ props: ['extraoption', 'isWorkspace', 'queryExportData', 'isStop', 'tabsItem'], @@ -223,10 +221,6 @@ import echarts from 'echarts' 'datasourceActions' ]) }, - components: { - IndexDetails, - ModelAggregate - }, locales: { 'en': { username: 'Username', diff --git a/kystudio/src/components/studio/StudioModel/ModelList/ModelActions/modelActions.vue b/kystudio/src/components/studio/StudioModel/ModelList/ModelActions/modelActions.vue index db0ff9c2f4..9541ecb172 100644 --- a/kystudio/src/components/studio/StudioModel/ModelList/ModelActions/modelActions.vue +++ b/kystudio/src/components/studio/StudioModel/ModelList/ModelActions/modelActions.vue @@ -272,7 +272,8 @@ import locales from './locales' disableModel: 'DISABLE_MODEL', enableModel: 'ENABLE_MODEL', delModel: 'DELETE_MODEL', - exportValidation: 'VALIDATE_EXPORT_TDS' + exportValidation: 'VALIDATE_EXPORT_TDS', + loadDataSourceByModel: 'LOAD_DATASOURCE_OF_MODEL' }), ...mapActions('DetailDialogModal', { callGlobalDetailDialog: 'CALL_MODAL' @@ -425,9 +426,19 @@ export default class ModelActions extends Vue { if (!(modelDesc.partition_desc && modelDesc.partition_desc.partition_date_column)) { type = 'fullLoad' } + let modelInfo = objectClone(modelDesc) + if (!modelDesc.simplified_tables) { + const result = await this.loadDataSourceByModel({ project: projectName, model_name: modelDesc.alias }) + const datasource = await handleSuccessAsync(result) + datasource.forEach((item) => { + item.table = item.database + '.' + item.name + }) + modelInfo.global_datasource = {} + modelInfo.global_datasource[this.currentSelectedProject] = datasource + } this.$nextTick(async () => { await this.callModelBuildDialog({ - modelDesc: modelDesc, + modelDesc: modelInfo, type: type, title: this.$t('build'), isHaveSegment: !!total_size, @@ -596,7 +607,7 @@ export default class ModelActions extends Vue { } get isHaveNoDimMeas () { - return this.currentModel.simplified_dimensions.length === 0 && this.currentModel.simplified_measures.length === 1 && this.currentModel.simplified_measures[0].name === 'COUNT_ALL' // 没有设置维度,只有默认度量 + return this.currentModel.empty_model // 没有设置维度,只有默认度量 } get isHavePartitionColumn () { diff --git a/kystudio/src/components/studio/StudioModel/ModelList/ModelBuildModal/build.vue b/kystudio/src/components/studio/StudioModel/ModelList/ModelBuildModal/build.vue index 010c41ed35..d5e5d6dab2 100644 --- a/kystudio/src/components/studio/StudioModel/ModelList/ModelBuildModal/build.vue +++ b/kystudio/src/components/studio/StudioModel/ModelList/ModelBuildModal/build.vue @@ -901,7 +901,7 @@ await (this.$refs.rangeForm && this.$refs.rangeForm.validate()) || Promise.resolve() await (this.$refs.partitionForm && this.$refs.partitionForm.validate()) || Promise.resolve() const { column, table } = this.partitionMeta - if (this.modelDesc.second_storage_enabled && !this.modelDesc.simplified_dimensions.map(it => it.column).includes(`${table}.${column}`)) { + if (this.modelDesc.second_storage_enabled && !(this.modelDesc.partition_column_in_dims || this.modelDesc.simplified_dimensions.map(it => it.column).includes(`${table}.${column}`))) { this.secondStoragePartitionTips = true this.btnLoading = false return diff --git a/kystudio/src/components/studio/StudioModel/ModelList/ModelLayout/modelLayout.vue b/kystudio/src/components/studio/StudioModel/ModelList/ModelLayout/modelLayout.vue index a84af715b4..438e62f9d1 100644 --- a/kystudio/src/components/studio/StudioModel/ModelList/ModelLayout/modelLayout.vue +++ b/kystudio/src/components/studio/StudioModel/ModelList/ModelLayout/modelLayout.vue @@ -250,16 +250,12 @@ export default class ModelLayout extends Vue { this.initModelData() } - initModelData () { + async initModelData () { const { modelName, searchModelName, tabTypes } = this.$route.params this.modelName = modelName this.searchModelName = searchModelName || '' - if (!this.modelList.filter(it => it.alias === this.modelName).length) { - // 没有匹配到相应的 model - this.$router.replace({name: 'ModelList'}) - return - } - this.currentModelRow = {...this.modelList.filter(it => it.alias === this.modelName)[0], tabTypes: typeof tabTypes !== 'undefined' ? tabTypes : 'overview'} + await this.refreshModelData() + this.currentModelRow = {...this.currentModelRow, tabTypes: typeof tabTypes !== 'undefined' ? tabTypes : 'overview'} if (this.currentModelRow.tabTypes === 'second' && localStorage.getItem('isFirstSaveModel') === 'true') { this.showGuide() } @@ -286,18 +282,6 @@ export default class ModelLayout extends Vue { }) } - selectModel ({model, ...args}) { - let data = {searchModelName: this.searchModelName, ...args} - let modelData = this.modelList.filter(it => it.alias === this.modelName) - this.modelName = model.alias - if (!modelData.length) { - this.$router.replace({name: 'ModelList'}) - return - } - this.$set(this, 'currentModelRow', {...modelData[0], tabTypes: typeof data.tabTypes !== 'undefined' ? data.tabTypes : 'overview'}) - this.randomKey = Date.now().toString(32) - } - loadModelList (name = '') { const { modelPageOffest } = this return new Promise((resolve, reject) => { @@ -331,6 +315,9 @@ export default class ModelLayout extends Vue { const { value } = await handleSuccessAsync(response) if (value.length) { this.currentModelRow = {...this.currentModelRow, ...value[0]} + } else { + // 没有匹配到相应的 model + this.$router.replace({ name: 'ModelList', params: {searchModelName: this.searchModelName} }) } } @@ -470,8 +457,8 @@ export default class ModelLayout extends Vue { // 重新加载模型数据 async reloadModel () { - await this.loadModelList() - this.selectModel({model: this.currentModelRow, tabTypes: this.currentModelRow.tabTypes}) + await this.refreshModelData() + this.randomKey = Date.now().toString(32) } // 首次创建模型引导 diff --git a/kystudio/src/components/studio/StudioModel/ModelList/ModelPartition/index.vue b/kystudio/src/components/studio/StudioModel/ModelList/ModelPartition/index.vue index fa0841949f..a26f90e44e 100644 --- a/kystudio/src/components/studio/StudioModel/ModelList/ModelPartition/index.vue +++ b/kystudio/src/components/studio/StudioModel/ModelList/ModelPartition/index.vue @@ -402,7 +402,7 @@ export default class ModelPartition extends Vue { const { table, column } = this.partitionMeta await (this.$refs.rangeForm && this.$refs.rangeForm.validate()) || Promise.resolve() await (this.$refs.partitionForm && this.$refs.partitionForm.validate()) || Promise.resolve() - if (this.partitionMeta.table && this.modelDesc.second_storage_enabled && !this.modelDesc.simplified_dimensions.map(it => it.column).includes(`${table}.${column}`)) { + if (this.partitionMeta.table && this.modelDesc.second_storage_enabled && !(this.modelDesc.partition_column_in_dims || this.modelDesc.simplified_dimensions.map(it => it.column).includes(`${table}.${column}`))) { this.secondStoragePartitionTips = true return } diff --git a/kystudio/src/components/studio/StudioModel/ModelList/index.vue b/kystudio/src/components/studio/StudioModel/ModelList/index.vue index 57c4a18ff3..4b9b34423e 100644 --- a/kystudio/src/components/studio/StudioModel/ModelList/index.vue +++ b/kystudio/src/components/studio/StudioModel/ModelList/index.vue @@ -98,6 +98,8 @@ :expand-row-keys="expandedRows" :row-key="renderRowKey" @expand-change="expandRow" + virtual-cell-height="64.57px" + :scroll-ancestors="() => ['#scrollContent']" ref="modelListTable" style="width: 100%"> <el-table-column @@ -123,7 +125,7 @@ @after-enter="(e) => afterPoppoverEnter(e, scope.row)" popper-class="er-popover-layout" > - <div class="model-ER-layout"><ModelERDiagram v-if="scope.row.showER" ref="erDiagram" source="modelList" :show-shortcuts-group="false" :show-change-alert="false" :model="dataGenerator.generateModel(scope.row)" /></div> + <div class="model-ER-layout"><ModelERDiagram v-if="scope.row.showER" ref="erDiagram" source="modelList" :show-shortcuts-group="false" :show-change-alert="false" :model="scope.row" /></div> </el-popover> <span class="model-ER" v-popover="`${scope.row.alias}-ERPopover`"> <el-icon name="el-ksd-icon-table_er_diagram_22" class="ksd-fs-22" type="mult"></el-icon> @@ -209,10 +211,6 @@ <ModelCloneModal/> <!-- 模型添加 --> <ModelAddModal/> - <!-- 聚合索引编辑 --> - <AggregateModal v-on:needShowBuildTips="needShowBuildTips" v-on:openBuildDialog="setModelBuldRange" v-on:openComplementAllIndexesDialog="openComplementSegment"/> - <!-- 表索引编辑 --> - <TableIndexEdit v-on:needShowBuildTips="needShowBuildTips" v-on:openBuildDialog="setModelBuldRange" v-on:openComplementAllIndexesDialog="openComplementSegment"/> <!-- 选择去构建的segment --> <ConfirmSegment v-on:reloadModelAndSegment="reloadModelAndSegment"/> </div> @@ -226,12 +224,10 @@ import { NamedRegex, pageRefTags, pageCount } from '../../../../config' import { ModelStatusTagType } from '../../../../config/model.js' import locales from './locales' import { handleError, kylinMessage, jumpToJobs } from 'util/business' -import { handleSuccessAsync, dataGenerator, sliceNumber, transToServerGmtTime } from 'util' +import { sliceNumber, transToServerGmtTime } from 'util' import TableIndex from '../TableIndex/index.vue' import ModelSegment from './ModelSegment/index.vue' import SegmentTabs from './ModelSegment/SegmentTabs.vue' -import ModelAggregate from './ModelAggregate/index.vue' -import ModelAggregateView from './ModelAggregateView/index.vue' import TableIndexView from './TableIndexView/index.vue' import ModelRenameModal from './ModelRenameModal/rename.vue' import ModelCloneModal from './ModelCloneModal/clone.vue' @@ -246,8 +242,6 @@ import ModelStreamingJob from './ModelStreamingJob/ModelStreamingJob.vue' import { mockSQL } from './mock' import DropdownFilter from '../../../common/DropdownFilter/DropdownFilter.vue' import ModelOverview from './ModelOverview/ModelOverview.vue' -import AggregateModal from './AggregateModal/index.vue' -import TableIndexEdit from '../TableIndexEdit/tableindex_edit' import ModelActions from './ModelActions/modelActions' import ModelERDiagram from '../../../common/ModelERDiagram/ModelERDiagram' import ModelTitleDescription from './Components/ModelTitleDescription' @@ -265,7 +259,8 @@ function getDefaultFilters (that) { model_alias_or_owner: '', last_modify: [], owner: '', - model_attributes: [] + model_attributes: [], + lite: true } } @@ -350,8 +345,6 @@ function getDefaultFilters (that) { TableIndex, ModelSegment, SegmentTabs, - ModelAggregate, - ModelAggregateView, TableIndexView, ModelRenameModal, ModelCloneModal, @@ -363,8 +356,6 @@ function getDefaultFilters (that) { ModelSql, ModelStreamingJob, DropdownFilter, - AggregateModal, - TableIndexEdit, ModelOverview, ModelActions, ModelERDiagram, @@ -375,7 +366,6 @@ function getDefaultFilters (that) { export default class ModelList extends Vue { pageRefTags = pageRefTags mockSQL = mockSQL - dataGenerator = dataGenerator sliceNumber = sliceNumber transToServerGmtTime = transToServerGmtTime filterArgs = getDefaultFilters(this) @@ -598,29 +588,7 @@ export default class ModelList extends Vue { ) } } - async setModelBuldRange (modelDesc, isNeedBuildGuild) { - if (!modelDesc.total_indexes && !isNeedBuildGuild || (!this.$store.state.project.multi_partition_enabled && modelDesc.multi_partition_desc)) return - const projectName = this.currentSelectedProject - const modelName = modelDesc.uuid - const res = await this.fetchSegments({ projectName, modelName }) - const { total_size, value } = await handleSuccessAsync(res) - let type = 'incremental' - if (!(modelDesc.partition_desc && modelDesc.partition_desc.partition_date_column) && modelDesc.model_type !== 'STREAMING') { - type = 'fullLoad' - } - this.isModelListOpen = true - this.$nextTick(async () => { - await this.callModelBuildDialog({ - modelDesc: modelDesc, - type: type, - title: this.$t('build'), - isHaveSegment: !!total_size, - disableFullLoad: type === 'fullLoad' && value.length > 0 && value[0].status_to_display !== 'ONLINE' // 已存在全量加载任务时,屏蔽 - }) - await this.refreshSegment(modelDesc.alias) - this.isModelListOpen = false - }) - } + async refreshSegment (alias) { this.$refs['segmentComp' + alias] && await this.$refs['segmentComp' + alias].$emit('refresh') this.prevExpendContent = this.modelArray.filter(item => this.expandedRows.includes(item.alias)) @@ -876,6 +844,26 @@ export default class ModelList extends Vue { }) }) } + handleAnimateChanged (event) { + const { className } = event.target + const isValidClass = className.indexOf('mode-list') !== -1 || className.indexOf('el-loading-mask') !== -1 || className.indexOf('el-button') !== -1 + if (isValidClass) { + const $table = this.$refs['modelListTable'] + if ($table) $table.verifyPosition() + } + } + mounted () { + const $contentPage = document.querySelector('.main-content .mode-list') + if ($contentPage) { + $contentPage.addEventListener('transitionend', this.handleAnimateChanged) + } + } + beforeDestroy () { + const $contentPage = document.querySelector('.main-content .mode-list') + if ($contentPage) { + $contentPage.removeEventListener('transitionend', this.handleAnimateChanged) + } + } } </script> <style lang="less">