Browse Source

1、表格列隐藏与form中统一使用showIf。

2、支持hideHeader属性。
main
likunming 4 months ago
parent
commit
0a15224d65
  1. 8
      io.sc.platform.core.frontend/src/platform/components/grid/GridConfig.vue
  2. 99
      io.sc.platform.core.frontend/src/platform/components/grid/WGrid.vue
  3. 6
      io.sc.platform.core.frontend/src/platform/components/grid/css/separator.css
  4. 23
      io.sc.platform.core.frontend/src/platform/components/grid/ts/grid.ts

8
io.sc.platform.core.frontend/src/platform/components/grid/GridConfig.vue

@ -93,7 +93,7 @@
unelevated
@click="
() => {
table.columns[0].hidden = false;
table.columns[0].showIf = true;
table.sortNo = true;
grid.refreshStyle(100);
}
@ -107,7 +107,7 @@
unelevated
@click="
() => {
table.columns[0].hidden = true;
table.columns[0].showIf = false;
table.sortNo = false;
grid.refreshStyle(100);
}
@ -238,9 +238,7 @@
<q-item v-if="showColumn(col.name)" v-ripple tag="label" dense>
<q-item-section side>
<q-checkbox
v-model="col.hidden"
:false-value="true"
:true-value="false"
v-model="col.showIf"
dense
@update:model-value="
() => {

99
io.sc.platform.core.frontend/src/platform/components/grid/WGrid.vue

@ -11,6 +11,7 @@
:loading-label="$t('tip.dataLoading')"
v-bind="attrs"
:separator="table.separator"
:hide-header="props.hideHeader"
:selection="selectionComputed"
:rows="table.rows"
:columns="columnsComputed"
@ -18,7 +19,6 @@
:loading="state.loading"
:class="tableClassComputed"
:table-style="tableHeightComputed"
card-container-class="card-container-class3333"
:row-key="rowKey_"
:visible-columns="visibleColumnsComputed"
:hide-bottom="pageable && !props.localMode && !tree ? false : true"
@ -95,6 +95,11 @@
:request="onRequest"
></GridPagination>
</template>
<!-- 隐藏表头且无数据时 -->
<template v-if="table.rows.length === 0 && props.hideHeader" #top-row>
<div :style="hideHeaderAndNoDataStyleComputed"><q-icon size="2em" name="info" />{{ $t('tip.noData') }}</div>
</template>
</q-table>
<!-- 新增与编辑窗口 -->
@ -128,7 +133,7 @@ import GridPagination from './GridPagination.vue';
import GridEditor from './GridEditor.vue';
import CellEditor from './CellEditor.vue';
import GridView from './GridView.vue';
import { selectMode as selectMode_, getMergeColumns, sortByProperties, editStatus } from './ts/grid.ts';
import { selectMode as selectMode_, sortByProperties, editStatus, groupMode as groupMode_ } from './ts/grid.ts';
import { columnDefaultProps } from './ts/grid.ts';
@ -183,10 +188,13 @@ const props = defineProps({
foreignKey: { type: String, default: 'parent' }, //
refreshData: { type: Boolean, default: false }, // primaryKey
dbClickOperation: { type: String, default: 'view' }, // nameclickexpand()none()
separator: { type: String, default: 'horizontal' },
groupMode: { type: String, default: '' },
group: {
type: Array,
separator: { type: String, default: 'cell' }, // 线horizontalverticalcellnone
hideHeader: { type: Boolean, default: false }, //
groupMode: { type: String, default: undefined }, // alonemerge
groupStartOpen: { type: [String, Array], default: undefined }, // aloneallfirstnone
groupByField: {
// alone
type: [String, Array],
default: () => {
return [];
},
@ -343,7 +351,6 @@ const tableColumnsMap = ref(arrayToMap('name', rawColumns.value));
const rowKey_ = '_rowKey_'; // UUID
const queryFormFieldsMap = arrayToMap('name', props.queryFormFields);
const tableColumns = ref(columnDefaultProps(rawColumns.value, props.sortNo));
const mergeColumns = getMergeColumns(tableColumns.value);
const url = {
dataUrl: props.dataUrl,
fetchDataUrl: props.fetchDataUrl,
@ -450,8 +457,12 @@ const denseBottomComputed = computed(() => {
const visibleColumnsComputed = computed(() => {
const visibleColumns: string[] = [];
table.columns.forEach((item) => {
if (!item.hidden && (!props.tree || (props.tree && item.name !== '_sortNo_'))) {
visibleColumns.push(item.name);
if (!props.tree || (props.tree && item.name !== '_sortNo_')) {
if (Tools.isEmpty(item.showIf)) {
visibleColumns.push(item.name);
} else if (typeof item.showIf === 'boolean' && item.showIf) {
visibleColumns.push(item.name);
}
}
});
return visibleColumns;
@ -472,8 +483,8 @@ const state = reactive({
middleScrollWidth: 0, // middleWidth
middleHeight: 0, // middle()
columnHeadHeight: 0, //
tableTitleWidth: 0, // title
titleTotalHeight: 0, // title
hideHeaderNoDataHeight: 0, //
},
pagination: {
config: {
@ -559,6 +570,14 @@ const noDataTrHeightComputed = computed(() => {
};
return style;
});
const hideHeaderAndNoDataStyleComputed = computed(() => {
return {
height: state.refHeightWidth.hideHeaderNoDataHeight + 'px',
display: 'flex',
'align-items': 'center',
'justify-content': 'center',
};
});
const noDataTrColspanComputed = computed(() => {
let colspan = excludeColumnNum.value;
@ -625,6 +644,7 @@ const onResize = () => {
state.refHeightWidth.middleWidth = tableRef.value.$el.getElementsByClassName('q-table__middle')[0]?.clientWidth;
state.refHeightWidth.middleScrollWidth = tableRef.value.$el.getElementsByClassName('q-table__middle')[0]?.scrollWidth;
state.refHeightWidth.columnHeadHeight = tableRef.value.$el.getElementsByTagName('thead')[0]?.clientHeight;
state.refHeightWidth.hideHeaderNoDataHeight = tableRef.value.$el.getElementsByClassName('q-table__middle')[0]?.clientHeight;
// middleHeight
if ((table.rows && table.rows.length > 0) || attrs['hide-bottom']) {
state.refHeightWidth.middleHeight = tableRef.value.$el.getElementsByClassName('q-table__middle')[0]?.clientHeight;
@ -635,12 +655,15 @@ const onResize = () => {
}
state.refHeightWidth.middleHeight = state.refHeightWidth.columnHeadHeight + scrollHeight;
}
state.refHeightWidth.tableTitleWidth = tableRef.value.$el.getElementsByClassName('_table-title')[0]?.clientWidth;
let titleTotalHeight = tableRef.value.$el.getElementsByTagName('thead')[0].offsetHeight;
let titleTotalHeight = tableRef.value.$el.getElementsByTagName('thead')[0]?.offsetHeight;
// top
if (table.rows.length === 0) {
const noDataTrHeight = tableRef.value.$el.getElementsByClassName('noDataTr')[0].offsetHeight;
titleTotalHeight = titleTotalHeight - noDataTrHeight;
const noDataTrHeight = tableRef.value.$el.getElementsByClassName('noDataTr')[0]?.offsetHeight;
if (titleTotalHeight && titleTotalHeight > 0) {
titleTotalHeight = titleTotalHeight - noDataTrHeight;
} else {
titleTotalHeight = noDataTrHeight;
}
}
state.refHeightWidth.titleTotalHeight = titleTotalHeight;
}
@ -901,10 +924,10 @@ const initRowDataExtraProperty = (rowData) => {
* @param rows 数据行集合
*/
const setRowDataExtraProperty = (rows: []) => {
if (mergeColumns.length > 0 && !props.tree) {
if (props.groupMode === groupMode_.merge && !props.tree) {
//
table.mergeRecords = {};
sortByProperties(rows, mergeColumns);
// sortByProperties(rows, mergeColumns);
}
if (rows && rows.length > 0) {
rows.forEach((item: any, index) => {
@ -954,20 +977,20 @@ const setOldValue = (rowData) => {
* desc: { 天安门: [5,1] }
*/
const addMergeRecords = (rowData) => {
if (mergeColumns.length > 0 && !props.tree) {
mergeColumns.forEach((columnName) => {
const tmpArr = [rowData[rowDataExtraPropertyName.rowKey]];
if (table.mergeRecords[columnName]) {
if (table.mergeRecords[columnName][rowData[columnName]]) {
table.mergeRecords[columnName][rowData[columnName]].push(rowData[rowDataExtraPropertyName.rowKey]);
} else {
table.mergeRecords[columnName][rowData[columnName]] = tmpArr;
}
} else {
table.mergeRecords[columnName] = { [rowData[columnName]]: tmpArr };
}
});
}
// if (mergeColumns.length > 0 && !props.tree) {
// mergeColumns.forEach((columnName) => {
// const tmpArr = [rowData[rowDataExtraPropertyName.rowKey]];
// if (table.mergeRecords[columnName]) {
// if (table.mergeRecords[columnName][rowData[columnName]]) {
// table.mergeRecords[columnName][rowData[columnName]].push(rowData[rowDataExtraPropertyName.rowKey]);
// } else {
// table.mergeRecords[columnName][rowData[columnName]] = tmpArr;
// }
// } else {
// table.mergeRecords[columnName] = { [rowData[columnName]]: tmpArr };
// }
// });
// }
};
watchEffect(() => {
@ -1004,7 +1027,7 @@ watchEffect(() => {
});
const tableClassComputed = computed(() => {
const classArr = <string[]>['sticky-header-column-table', 'w-grid'];
const classArr = <string[]>['sticky-header-column-table'];
if (table.stickyNum && table.stickyNum > 0) {
if (headerRef.value?.getColumnTitleState()?.columnTitleRowNum > 1) {
//
@ -1666,14 +1689,14 @@ const refreshStyle = (time = 500) => {
if (tableRef.value) {
state.refHeightWidth.yLocation = tableRef.value.$el.getBoundingClientRect()?.y;
if (tableRef.value.$el.getElementsByClassName('noDataTr').length > 0) {
state.refHeightWidth.noDataTrYLocation = tableRef.value.$el.getElementsByClassName('noDataTr')[0].getBoundingClientRect().y;
state.refHeightWidth.noDataTrYLocation = tableRef.value.$el.getElementsByClassName('noDataTr')[0]?.getBoundingClientRect().y;
}
state.refHeightWidth.topHeight = tableRef.value.$el.getElementsByClassName('q-table__top')[0]?.clientHeight;
state.refHeightWidth.bottomHeight = tableRef.value.$el.getElementsByClassName('q-table__bottom')[0]?.clientHeight;
state.refHeightWidth.middleWidth = tableRef.value.$el.getElementsByClassName('q-table__middle')[0]?.clientWidth;
state.refHeightWidth.middleScrollWidth = tableRef.value.$el.getElementsByClassName('q-table__middle')[0]?.scrollWidth;
state.refHeightWidth.columnHeadHeight = tableRef.value.$el.getElementsByTagName('thead')[0]?.clientHeight;
state.refHeightWidth.tableTitleWidth = tableRef.value.$el.getElementsByClassName('_table-title')[0]?.clientWidth;
state.refHeightWidth.hideHeaderNoDataHeight = tableRef.value.$el.getElementsByClassName('q-table__middle')[0]?.clientHeight;
// middleHeight
if ((table.rows && table.rows.length > 0) || attrs['hide-bottom']) {
state.refHeightWidth.middleHeight = tableRef.value.$el.getElementsByClassName('q-table__middle')[0]?.clientHeight;
@ -1728,11 +1751,15 @@ const refreshStyle = (time = 500) => {
column1Width + column2Width + column3Width + column4Width + column5Width + column6Width + column7Width + column8Width + column9Width + 'px',
);
}
let titleTotalHeight = tableDom.getElementsByTagName('thead')[0].offsetHeight;
let titleTotalHeight = tableDom.getElementsByTagName('thead')[0]?.offsetHeight;
// top
if (table.rows.length === 0) {
const noDataTrHeight = tableRef.value.$el.getElementsByClassName('noDataTr')[0].offsetHeight;
titleTotalHeight = titleTotalHeight - noDataTrHeight;
const noDataTrHeight = tableRef.value.$el.getElementsByClassName('noDataTr')[0]?.offsetHeight;
if (titleTotalHeight && titleTotalHeight > 0) {
titleTotalHeight = titleTotalHeight - noDataTrHeight;
} else {
titleTotalHeight = noDataTrHeight;
}
}
state.refHeightWidth.titleTotalHeight = titleTotalHeight;
}

6
io.sc.platform.core.frontend/src/platform/components/grid/css/separator.css

@ -45,6 +45,9 @@
.w-grid .q-table--vertical-separator th:first-child.firstColumn {
border-left: 0;
}
.w-grid .q-table--vertical-separator th:first-child:not([rowspan]) {
border-left: 0;
}
/*
* vertical
* 数据最后一行底部边框
@ -71,6 +74,9 @@
.w-grid .q-table--cell-separator th:first-child.firstColumn {
border-left: 0;
}
.w-grid .q-table--cell-separator th:first-child:not([rowspan]) {
border-left: 0;
}
/*
* cell
* 数据最后一行底部边框

23
io.sc.platform.core.frontend/src/platform/components/grid/ts/grid.ts

@ -14,6 +14,12 @@ export const selectMode = {
cell: 'cell', // 单元格选择
};
// 分组模式
export const groupMode = {
alone: 'alone', // 单独行进行分组
merge: 'merge', // 合并行进行分组
};
// 表格内容区域快速编辑状态
export const editStatus = {
none: 'none', // 不在编辑状态
@ -62,7 +68,7 @@ const childrenHandler = (item: any, gridColumns: any) => {
} else {
columnStyle(item);
const col = {
...{ align: 'left', label: item.name, field: item.name, name: item.name, sortable: true, hidden: false },
...{ align: 'left', label: item.name, field: item.name, name: item.name, sortable: true, showIf: true },
...item,
};
if (Tools.isEmpty(col.name)) {
@ -76,7 +82,7 @@ const childrenHandler = (item: any, gridColumns: any) => {
export const columnDefaultProps = (columns: any, sortNo: boolean) => {
const gridColumns = <any>[];
if (columns && columns.length > 0) {
gridColumns.push({ name: '_sortNo_', align: 'center', label: t('rownum'), field: '_sortNo_', hidden: sortNo ? false : true });
gridColumns.push({ name: '_sortNo_', align: 'center', label: t('rownum'), field: '_sortNo_', showIf: sortNo });
columns.forEach((item: any) => {
childrenHandler(item, gridColumns);
});
@ -85,19 +91,6 @@ export const columnDefaultProps = (columns: any, sortNo: boolean) => {
return [];
};
// 获取所有需要合并的列名
export const getMergeColumns = (columns) => {
const columnNames = <any>[];
if (columns && columns.length > 0) {
columns.forEach((item) => {
if (Tools.hasOwnProperty(item, 'autoMerge') && item['autoMerge']) {
columnNames.push(item['name']);
}
});
}
return columnNames;
};
export const sortByProperties = (arr, properties) => {
for (const prop of properties) {
arr.sort((a, b) => {

Loading…
Cancel
Save