Browse Source

fix: render mini table cells faithfully with same components as real table

- MiniCellRenderer now mirrors the real cellRenderer logic (slots, TzDateTime, dicts)
- Removed useless hard-coded nth-child flex selectors
- Each mini-cell now uses inline styles via getMiniCellStyle() to match real column widths
- Update DEV_MODE_TS timestamp

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
dev
hechang27-sprt 3 months ago
parent
commit
854a8f6872
  1. 81
      packages/base/data/list-table-v2.vue
  2. 2
      packages/manage/router/index.vue

81
packages/base/data/list-table-v2.vue

@ -1,13 +1,17 @@
<template> <template>
<div class="list-table-v2" :style="containerStyle"> <div class="list-table-v2" :style="containerStyle">
<!-- Mini hidden table for measuring row height (only when using dynamic height mode) --> <!-- Mini hidden table for measuring row height (only when using dynamic height mode) -->
<!-- This mirrors the real table's cell rendering for accurate height estimation -->
<div v-if="shouldUseProbeRow" ref="miniTableRef" class="mini-table" aria-hidden="true"> <div v-if="shouldUseProbeRow" ref="miniTableRef" class="mini-table" aria-hidden="true">
<div v-if="miniTableData.length > 0" class="mini-table-inner"> <div v-if="miniTableData.length > 0" class="mini-table-inner">
<div v-for="(row, idx) in miniTableData" :key="idx" class="mini-row"> <div v-for="(row, rowIdx) in miniTableData" :key="rowIdx" class="mini-row">
<div v-for="item in prop.columns || []" :key="item.key" class="mini-cell"> <div
<span class="mini-cell-content"> v-for="item in prop.columns || []"
{{ getProbeCellText(row, item) }} :key="item.key"
</span> class="mini-cell"
:style="getMiniCellStyle(item)"
>
<MiniCellRenderer :item="item" :row="row" :slots="slots" />
</div> </div>
</div> </div>
</div> </div>
@ -448,6 +452,56 @@ const tableColumns = computed(() => {
return col; return col;
}); });
}); });
// Mini cell renderer - mirrors the real table's cellRenderer for faithful height estimation
const MiniCellRenderer = (props: { item: TableColumn; row: any; slots: ReturnType<typeof useSlots> }) => {
const { item, row, slots } = props;
const slotName = item.key;
// If column has slot=true, render the parent's slot content
if (item.slot && slots[slotName]) {
return renderSlot(slots, slotName, { row });
}
const value = lodash.get(row, item.dataKey || item.key);
// Handle timestamp display using TzDateTime component
if (item.timestamp) {
const tzProps = resolveTimestampProps(item.timestamp);
if (tzProps) {
const { valueFormat, valueTz, displayFormat, locale, type } = tzProps;
return (
<TzDateTime
value={value}
valueFormat={valueFormat}
valueTz={valueTz}
displayFormat={displayFormat}
locale={locale}
type={type}
/>
);
}
}
// Handle dict display
if (item.dict) {
return <span>{formatterByDist(item.dict, value)}</span>;
}
// Handle formatting
const formatted = formatCellValue(value, item, row);
return <span>{formatted}</span>;
};
// Get mini cell style - mirrors the real table's column width/flex distribution
const getMiniCellStyle = (item: TableColumn): Record<string, string> => {
if (item.width !== undefined) {
const w = typeof item.width === "number" ? item.width : parseInt(String(item.width)) || 120;
return { width: `${w}px`, flex: "none" };
}
// Use flex: 1 to auto-expand columns to fill available width (same as flexGrow: 1)
return { flex: "1", minWidth: "120px" };
};
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
@ -466,8 +520,7 @@ const tableColumns = computed(() => {
pointer-events: none; pointer-events: none;
left: -9999px; left: -9999px;
top: 0; top: 0;
width: 100%; // Width responds to parent container width: 100%;
max-width: 100%;
} }
.mini-table-inner { .mini-table-inner {
@ -485,28 +538,16 @@ const tableColumns = computed(() => {
background: v-bind("state.style.tableBg"); background: v-bind("state.style.tableBg");
color: v-bind("state.style.tableColor"); color: v-bind("state.style.tableColor");
box-sizing: border-box; box-sizing: border-box;
overflow: hidden;
} }
.mini-cell { .mini-cell {
flex: 1;
min-width: 120px;
padding-right: 8px;
box-sizing: border-box; box-sizing: border-box;
overflow: hidden; overflow: hidden;
text-overflow: ellipsis; text-overflow: ellipsis;
white-space: nowrap; white-space: nowrap;
} }
// Flex grow columns match the real table's flex distribution
.mini-cell:nth-child(1) { flex: 1; min-width: 120px; }
.mini-cell:nth-child(2) { flex: 1; min-width: 120px; }
.mini-cell:nth-child(3) { flex: 1; min-width: 120px; }
.mini-cell:nth-child(4) { flex: 1; min-width: 120px; }
.mini-cell:nth-child(5) { flex: 1; min-width: 120px; }
.mini-cell:nth-child(6) { flex: 1; min-width: 120px; }
.mini-cell:nth-child(7) { flex: 1; min-width: 120px; }
.mini-cell:nth-child(8) { flex: 1; min-width: 120px; }
.mini-cell-content { .mini-cell-content {
overflow: hidden; overflow: hidden;
text-overflow: ellipsis; text-overflow: ellipsis;

2
packages/manage/router/index.vue

@ -37,7 +37,7 @@ import { useRouter, useRoute } from "vue-router";
import { Api, NoobHead } from "noob-mengyxu"; import { Api, NoobHead } from "noob-mengyxu";
import md5 from "js-md5"; import md5 from "js-md5";
const DEV_MODE_TS = "2026-03-26T07:50:00.000Z"; const DEV_MODE_TS = "2026-03-26T08:00:00.000Z";
const { VITE_APP_VERSION, VITE_GIT_HASH, NODE_ENV } = import.meta.env; const { VITE_APP_VERSION, VITE_GIT_HASH, NODE_ENV } = import.meta.env;
const { Head, MenuTree, HeadPersonal, Fullscreen, StyleChange, LangChange, SizeChange } = NoobHead; const { Head, MenuTree, HeadPersonal, Fullscreen, StyleChange, LangChange, SizeChange } = NoobHead;

Loading…
Cancel
Save