fdb2 1.0.11 → 1.0.12
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/fdb2.js +43 -33
- package/dist/public/explorer.css +185 -103
- package/dist/public/explorer.js +855 -896
- package/dist/public/index.css +30 -2
- package/dist/public/index.js +61 -16
- package/dist/public/vue.js +18 -25
- package/package.json +20 -20
- package/src/components/dataGrid/index.vue +62 -4
- package/src/platform/database/components/database-detail.vue +31 -6
- package/src/platform/database/components/table-data-grid.vue +273 -0
- package/src/platform/database/components/table-detail.vue +64 -267
package/dist/public/index.css
CHANGED
|
@@ -1062,10 +1062,38 @@ pre {
|
|
|
1062
1062
|
}
|
|
1063
1063
|
}
|
|
1064
1064
|
|
|
1065
|
-
.datagrid-
|
|
1065
|
+
.datagrid-container[data-v-ae552d25] {
|
|
1066
|
+
display: flex;
|
|
1067
|
+
flex-direction: column;
|
|
1068
|
+
height: 100%;
|
|
1069
|
+
}
|
|
1070
|
+
.datagrid-inner[data-v-ae552d25] {
|
|
1071
|
+
flex: 1;
|
|
1066
1072
|
overflow: auto;
|
|
1067
1073
|
margin-bottom: 10px;
|
|
1068
1074
|
}
|
|
1069
|
-
.datagrid-th[data-v-
|
|
1075
|
+
.datagrid-th[data-v-ae552d25] {
|
|
1070
1076
|
min-width: 80px;
|
|
1077
|
+
white-space: nowrap;
|
|
1078
|
+
position: sticky;
|
|
1079
|
+
top: 0;
|
|
1080
|
+
z-index: 10;
|
|
1081
|
+
background-color: #f8f9fa;
|
|
1082
|
+
}
|
|
1083
|
+
.datagrid-th.sortable[data-v-ae552d25] {
|
|
1084
|
+
cursor: pointer;
|
|
1085
|
+
user-select: none;
|
|
1086
|
+
}
|
|
1087
|
+
.datagrid-th.sortable[data-v-ae552d25]:hover {
|
|
1088
|
+
background-color: #e9ecef;
|
|
1089
|
+
}
|
|
1090
|
+
.header-content[data-v-ae552d25] {
|
|
1091
|
+
display: flex;
|
|
1092
|
+
align-items: center;
|
|
1093
|
+
gap: 0.5rem;
|
|
1094
|
+
}
|
|
1095
|
+
.sort-icon[data-v-ae552d25] {
|
|
1096
|
+
display: flex;
|
|
1097
|
+
align-items: center;
|
|
1098
|
+
font-size: 0.75rem;
|
|
1071
1099
|
}
|
package/dist/public/index.js
CHANGED
|
@@ -12051,8 +12051,8 @@ const _hoisted_7$1 = {
|
|
|
12051
12051
|
key: 0,
|
|
12052
12052
|
class: "error-details-content mt-2"
|
|
12053
12053
|
};
|
|
12054
|
-
const _hoisted_8 = { class: "error-json" };
|
|
12055
|
-
const _hoisted_9 = { class: "modal-footer" };
|
|
12054
|
+
const _hoisted_8$1 = { class: "error-json" };
|
|
12055
|
+
const _hoisted_9$1 = { class: "modal-footer" };
|
|
12056
12056
|
const _sfc_main$2 = /* @__PURE__ */ defineComponent({
|
|
12057
12057
|
__name: "index",
|
|
12058
12058
|
props: {
|
|
@@ -12423,12 +12423,12 @@ const _sfc_main$2 = /* @__PURE__ */ defineComponent({
|
|
|
12423
12423
|
_cache[0] || (_cache[0] = createBaseVNode("i", { class: "bi bi-chevron-{{detailsExpanded ? 'up' : 'down'}} ms-1" }, null, -1))
|
|
12424
12424
|
]),
|
|
12425
12425
|
detailsExpanded.value ? (openBlock(), createElementBlock("div", _hoisted_7$1, [
|
|
12426
|
-
createBaseVNode("pre", _hoisted_8, toDisplayString(formatErrorDetails()), 1)
|
|
12426
|
+
createBaseVNode("pre", _hoisted_8$1, toDisplayString(formatErrorDetails()), 1)
|
|
12427
12427
|
])) : createCommentVNode("", true)
|
|
12428
12428
|
])) : createCommentVNode("", true)
|
|
12429
12429
|
]))
|
|
12430
12430
|
])) : createCommentVNode("", true),
|
|
12431
|
-
createBaseVNode("div", _hoisted_9, [
|
|
12431
|
+
createBaseVNode("div", _hoisted_9$1, [
|
|
12432
12432
|
_ctx.$slots.footer ? renderSlot(_ctx.$slots, "footer", { key: 0 }, void 0) : (openBlock(), createElementBlock(Fragment, { key: 1 }, [
|
|
12433
12433
|
dynamicShowCancel.value || props.closeButton.show ? (openBlock(), createElementBlock("button", {
|
|
12434
12434
|
key: 0,
|
|
@@ -12563,9 +12563,27 @@ const _hoisted_1 = { class: "datagrid-container" };
|
|
|
12563
12563
|
const _hoisted_2 = { class: "datagrid-inner" };
|
|
12564
12564
|
const _hoisted_3 = { class: "table table-light table-striped table-hover" };
|
|
12565
12565
|
const _hoisted_4 = { class: "table-light" };
|
|
12566
|
-
const _hoisted_5 =
|
|
12567
|
-
const _hoisted_6 =
|
|
12568
|
-
const _hoisted_7 = {
|
|
12566
|
+
const _hoisted_5 = ["onClick"];
|
|
12567
|
+
const _hoisted_6 = { class: "header-content" };
|
|
12568
|
+
const _hoisted_7 = {
|
|
12569
|
+
key: 0,
|
|
12570
|
+
class: "sort-icon"
|
|
12571
|
+
};
|
|
12572
|
+
const _hoisted_8 = {
|
|
12573
|
+
key: 0,
|
|
12574
|
+
class: "bi bi-caret-up-fill"
|
|
12575
|
+
};
|
|
12576
|
+
const _hoisted_9 = {
|
|
12577
|
+
key: 1,
|
|
12578
|
+
class: "bi bi-caret-down-fill"
|
|
12579
|
+
};
|
|
12580
|
+
const _hoisted_10 = {
|
|
12581
|
+
key: 2,
|
|
12582
|
+
class: "bi bi-caret-up text-muted opacity-50"
|
|
12583
|
+
};
|
|
12584
|
+
const _hoisted_11 = { class: "table-group-divider" };
|
|
12585
|
+
const _hoisted_12 = ["onClick"];
|
|
12586
|
+
const _hoisted_13 = { key: 1 };
|
|
12569
12587
|
const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
12570
12588
|
__name: "index",
|
|
12571
12589
|
props: {
|
|
@@ -12597,9 +12615,18 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
|
12597
12615
|
columns: {
|
|
12598
12616
|
type: Array,
|
|
12599
12617
|
default: []
|
|
12618
|
+
},
|
|
12619
|
+
sortField: {
|
|
12620
|
+
type: String,
|
|
12621
|
+
default: ""
|
|
12622
|
+
},
|
|
12623
|
+
sortOrder: {
|
|
12624
|
+
type: String,
|
|
12625
|
+
default: ""
|
|
12626
|
+
// ASC, DESC, ''
|
|
12600
12627
|
}
|
|
12601
12628
|
},
|
|
12602
|
-
emits: ["pageChanged", "rowClicked"],
|
|
12629
|
+
emits: ["pageChanged", "rowClicked", "sortChanged"],
|
|
12603
12630
|
setup(__props, { emit: __emit }) {
|
|
12604
12631
|
const props = __props;
|
|
12605
12632
|
const emits = __emit;
|
|
@@ -12613,6 +12640,17 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
|
12613
12640
|
function pageChanged(page) {
|
|
12614
12641
|
emits("pageChanged", page);
|
|
12615
12642
|
}
|
|
12643
|
+
function handleSort(field) {
|
|
12644
|
+
let order = "ASC";
|
|
12645
|
+
if (props.sortField === field) {
|
|
12646
|
+
if (props.sortOrder === "ASC") {
|
|
12647
|
+
order = "DESC";
|
|
12648
|
+
} else if (props.sortOrder === "DESC") {
|
|
12649
|
+
order = "";
|
|
12650
|
+
}
|
|
12651
|
+
}
|
|
12652
|
+
emits("sortChanged", { field: order ? field : "", order });
|
|
12653
|
+
}
|
|
12616
12654
|
return (_ctx, _cache) => {
|
|
12617
12655
|
return openBlock(), createElementBlock("div", _hoisted_1, [
|
|
12618
12656
|
createBaseVNode("div", _hoisted_2, [
|
|
@@ -12623,17 +12661,23 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
|
12623
12661
|
return openBlock(), createElementBlock("th", {
|
|
12624
12662
|
key: column.name,
|
|
12625
12663
|
scope: "col",
|
|
12626
|
-
class: "datagrid-th",
|
|
12627
|
-
style: normalizeStyle(column.headerStyle || "")
|
|
12664
|
+
class: normalizeClass(["datagrid-th", { "sortable": column.sortable !== false }]),
|
|
12665
|
+
style: normalizeStyle(column.headerStyle || ""),
|
|
12666
|
+
onClick: ($event) => column.sortable !== false && handleSort(column.name)
|
|
12628
12667
|
}, [
|
|
12629
12668
|
renderSlot(_ctx.$slots, column.name + "_header", { column }, () => [
|
|
12630
|
-
createBaseVNode("
|
|
12669
|
+
createBaseVNode("div", _hoisted_6, [
|
|
12670
|
+
createBaseVNode("span", null, toDisplayString(column.text || column.name || ""), 1),
|
|
12671
|
+
column.sortable !== false ? (openBlock(), createElementBlock("span", _hoisted_7, [
|
|
12672
|
+
props.sortField === column.name && props.sortOrder === "ASC" ? (openBlock(), createElementBlock("i", _hoisted_8)) : props.sortField === column.name && props.sortOrder === "DESC" ? (openBlock(), createElementBlock("i", _hoisted_9)) : (openBlock(), createElementBlock("i", _hoisted_10))
|
|
12673
|
+
])) : createCommentVNode("", true)
|
|
12674
|
+
])
|
|
12631
12675
|
])
|
|
12632
|
-
],
|
|
12676
|
+
], 14, _hoisted_5);
|
|
12633
12677
|
}), 128))
|
|
12634
12678
|
])
|
|
12635
12679
|
]),
|
|
12636
|
-
createBaseVNode("tbody",
|
|
12680
|
+
createBaseVNode("tbody", _hoisted_11, [
|
|
12637
12681
|
(openBlock(true), createElementBlock(Fragment, null, renderList(props.data, (row, index) => {
|
|
12638
12682
|
return openBlock(), createElementBlock("tr", {
|
|
12639
12683
|
key: index,
|
|
@@ -12648,11 +12692,11 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
|
12648
12692
|
row,
|
|
12649
12693
|
column
|
|
12650
12694
|
}, () => [
|
|
12651
|
-
column.component ? (openBlock(), createBlock(resolveDynamicComponent(column.component), { key: 0 })) : (openBlock(), createElementBlock("span",
|
|
12695
|
+
column.component ? (openBlock(), createBlock(resolveDynamicComponent(column.component), { key: 0 })) : (openBlock(), createElementBlock("span", _hoisted_13, toDisplayString(renderDataItem(row, column)), 1))
|
|
12652
12696
|
])
|
|
12653
12697
|
]);
|
|
12654
12698
|
}), 128))
|
|
12655
|
-
], 8,
|
|
12699
|
+
], 8, _hoisted_12);
|
|
12656
12700
|
}), 128))
|
|
12657
12701
|
]),
|
|
12658
12702
|
createBaseVNode("tfoot", null, [
|
|
@@ -12676,7 +12720,7 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
|
12676
12720
|
};
|
|
12677
12721
|
}
|
|
12678
12722
|
});
|
|
12679
|
-
const DataGrid = /* @__PURE__ */ _export_sfc(_sfc_main, [["__scopeId", "data-v-
|
|
12723
|
+
const DataGrid = /* @__PURE__ */ _export_sfc(_sfc_main, [["__scopeId", "data-v-ae552d25"]]);
|
|
12680
12724
|
let globalModalInstance = null;
|
|
12681
12725
|
let modalInstance;
|
|
12682
12726
|
const modalPlugin = {
|
|
@@ -12804,6 +12848,7 @@ app.component("Modal", Modal);
|
|
|
12804
12848
|
app.component("DataGrid", DataGrid);
|
|
12805
12849
|
app.mount("#app");
|
|
12806
12850
|
export {
|
|
12851
|
+
DataGrid as D,
|
|
12807
12852
|
Modal as M,
|
|
12808
12853
|
Toast as T,
|
|
12809
12854
|
_export_sfc as _,
|
package/dist/public/vue.js
CHANGED
|
@@ -2690,6 +2690,23 @@ function renderList(source, renderItem, cache, index) {
|
|
|
2690
2690
|
}
|
|
2691
2691
|
return ret;
|
|
2692
2692
|
}
|
|
2693
|
+
function createSlots(slots, dynamicSlots) {
|
|
2694
|
+
for (let i2 = 0; i2 < dynamicSlots.length; i2++) {
|
|
2695
|
+
const slot = dynamicSlots[i2];
|
|
2696
|
+
if (isArray$1(slot)) {
|
|
2697
|
+
for (let j2 = 0; j2 < slot.length; j2++) {
|
|
2698
|
+
slots[slot[j2].name] = slot[j2].fn;
|
|
2699
|
+
}
|
|
2700
|
+
} else if (slot) {
|
|
2701
|
+
slots[slot.name] = slot.key ? (...args) => {
|
|
2702
|
+
const res = slot.fn(...args);
|
|
2703
|
+
if (res) res.key = slot.key;
|
|
2704
|
+
return res;
|
|
2705
|
+
} : slot.fn;
|
|
2706
|
+
}
|
|
2707
|
+
}
|
|
2708
|
+
return slots;
|
|
2709
|
+
}
|
|
2693
2710
|
function renderSlot(slots, name, props = {}, fallback, noSlotted) {
|
|
2694
2711
|
if (currentRenderingInstance.ce || currentRenderingInstance.parent && isAsyncWrapper(currentRenderingInstance.parent) && currentRenderingInstance.parent.ce) {
|
|
2695
2712
|
const hasProps = Object.keys(props).length > 0;
|
|
@@ -6661,30 +6678,6 @@ const withModifiers = (fn, modifiers) => {
|
|
|
6661
6678
|
return fn(event, ...args);
|
|
6662
6679
|
}));
|
|
6663
6680
|
};
|
|
6664
|
-
const keyNames = {
|
|
6665
|
-
esc: "escape",
|
|
6666
|
-
space: " ",
|
|
6667
|
-
up: "arrow-up",
|
|
6668
|
-
left: "arrow-left",
|
|
6669
|
-
right: "arrow-right",
|
|
6670
|
-
down: "arrow-down",
|
|
6671
|
-
delete: "backspace"
|
|
6672
|
-
};
|
|
6673
|
-
const withKeys = (fn, modifiers) => {
|
|
6674
|
-
const cache = fn._withKeys || (fn._withKeys = {});
|
|
6675
|
-
const cacheKey = modifiers.join(".");
|
|
6676
|
-
return cache[cacheKey] || (cache[cacheKey] = ((event) => {
|
|
6677
|
-
if (!("key" in event)) {
|
|
6678
|
-
return;
|
|
6679
|
-
}
|
|
6680
|
-
const eventKey = hyphenate(event.key);
|
|
6681
|
-
if (modifiers.some(
|
|
6682
|
-
(k2) => k2 === eventKey || keyNames[k2] === eventKey
|
|
6683
|
-
)) {
|
|
6684
|
-
return fn(event);
|
|
6685
|
-
}
|
|
6686
|
-
}));
|
|
6687
|
-
};
|
|
6688
6681
|
const rendererOptions = /* @__PURE__ */ extend({ patchProp }, nodeOps);
|
|
6689
6682
|
let renderer;
|
|
6690
6683
|
function ensureRenderer() {
|
|
@@ -9086,7 +9079,7 @@ export {
|
|
|
9086
9079
|
vShow as S,
|
|
9087
9080
|
useRouter as T,
|
|
9088
9081
|
createStaticVNode as U,
|
|
9089
|
-
|
|
9082
|
+
createSlots as V,
|
|
9090
9083
|
useRoute as W,
|
|
9091
9084
|
ref as a,
|
|
9092
9085
|
isRef as b,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "fdb2",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.12",
|
|
4
4
|
"private": false,
|
|
5
5
|
"type": "commonjs",
|
|
6
6
|
"main": "view/index.html",
|
|
@@ -45,64 +45,64 @@
|
|
|
45
45
|
},
|
|
46
46
|
"dependencies": {
|
|
47
47
|
"@fefeding/common": "^1.0.58",
|
|
48
|
-
"axios": "^1.13.
|
|
49
|
-
"
|
|
48
|
+
"axios": "^1.13.6",
|
|
49
|
+
"better-sqlite3": "^11.10.0",
|
|
50
|
+
"dayjs": "^1.11.20",
|
|
50
51
|
"express": "^5.2.1",
|
|
51
|
-
"mysql2": "^3.
|
|
52
|
+
"mysql2": "^3.20.0",
|
|
52
53
|
"oracledb": "^6.10.0",
|
|
53
|
-
"pg": "^8.
|
|
54
|
+
"pg": "^8.20.0",
|
|
54
55
|
"reflect-metadata": "^0.2.2",
|
|
55
|
-
"better-sqlite3": "^11.0.0",
|
|
56
56
|
"typeorm": "^0.3.28"
|
|
57
57
|
},
|
|
58
58
|
"devDependencies": {
|
|
59
|
-
"@codemirror/commands": "^6.10.
|
|
59
|
+
"@codemirror/commands": "^6.10.3",
|
|
60
60
|
"@codemirror/fold": "^0.19.4",
|
|
61
61
|
"@codemirror/lang-json": "^6.0.2",
|
|
62
62
|
"@codemirror/lang-sql": "^6.10.0",
|
|
63
|
-
"@codemirror/language": "^6.12.
|
|
64
|
-
"@codemirror/state": "^6.
|
|
63
|
+
"@codemirror/language": "^6.12.3",
|
|
64
|
+
"@codemirror/state": "^6.6.0",
|
|
65
65
|
"@codemirror/theme-one-dark": "^6.1.3",
|
|
66
|
-
"@codemirror/view": "^6.
|
|
66
|
+
"@codemirror/view": "^6.40.0",
|
|
67
67
|
"@fefeding/eventemitter": "^1.0.5",
|
|
68
68
|
"@fefeding/vite-nunjucks-plugin": "^1.0.2",
|
|
69
69
|
"@popperjs/core": "^2.11.8",
|
|
70
70
|
"@rollup/pluginutils": "^5.3.0",
|
|
71
71
|
"@types/bootstrap": "^5.2.10",
|
|
72
72
|
"@types/jsdom": "^21.1.7",
|
|
73
|
-
"@types/node": "^24.
|
|
73
|
+
"@types/node": "^24.12.0",
|
|
74
74
|
"@types/vue": "^2.0.0",
|
|
75
|
-
"@vitejs/plugin-vue": "^6.0.
|
|
76
|
-
"@vitejs/plugin-vue-jsx": "^5.1.
|
|
75
|
+
"@vitejs/plugin-vue": "^6.0.5",
|
|
76
|
+
"@vitejs/plugin-vue-jsx": "^5.1.5",
|
|
77
77
|
"@vue/tsconfig": "^0.8.1",
|
|
78
78
|
"@vueuse/core": "^13.9.0",
|
|
79
79
|
"@zumer/snapdom": "^1.9.14",
|
|
80
|
-
"autoprefixer": "^10.4.
|
|
80
|
+
"autoprefixer": "^10.4.27",
|
|
81
81
|
"bootstrap": "^5.3.8",
|
|
82
82
|
"bootstrap-icons": "^1.13.1",
|
|
83
83
|
"codemirror": "^6.0.2",
|
|
84
|
-
"dotenv": "^17.
|
|
84
|
+
"dotenv": "^17.3.1",
|
|
85
85
|
"echarts": "^6.0.0",
|
|
86
86
|
"exceljs": "^4.4.0",
|
|
87
87
|
"js-cookie": "^3.0.5",
|
|
88
88
|
"jsdom": "^26.1.0",
|
|
89
89
|
"jszip": "^3.10.1",
|
|
90
90
|
"nw": "^0.107.0",
|
|
91
|
-
"nw-builder": "^4.17.
|
|
91
|
+
"nw-builder": "^4.17.5",
|
|
92
92
|
"pinia": "^3.0.4",
|
|
93
93
|
"pinia-plugin-persistedstate": "^4.7.1",
|
|
94
|
-
"postcss": "^8.5.
|
|
95
|
-
"sass": "^1.
|
|
94
|
+
"postcss": "^8.5.8",
|
|
95
|
+
"sass": "^1.98.0",
|
|
96
96
|
"tailwindcss": "^3.4.19",
|
|
97
97
|
"typescript": "^5.9.3",
|
|
98
98
|
"vconsole": "^3.15.1",
|
|
99
99
|
"vite": "latest",
|
|
100
100
|
"vite-plugin-files-copy": "^3.8.0",
|
|
101
101
|
"vitest": "^3.2.4",
|
|
102
|
-
"vue": "^3.5.
|
|
102
|
+
"vue": "^3.5.31",
|
|
103
103
|
"vue-json-pretty": "^2.6.0",
|
|
104
104
|
"vue-router": "^4.6.4",
|
|
105
|
-
"vue-tsc": "^3.2.
|
|
105
|
+
"vue-tsc": "^3.2.6",
|
|
106
106
|
"vuex": "^4.1.0",
|
|
107
107
|
"xlsx": "^0.18.5"
|
|
108
108
|
},
|
|
@@ -4,9 +4,18 @@
|
|
|
4
4
|
<table class="table table-light table-striped table-hover">
|
|
5
5
|
<thead class="table-light">
|
|
6
6
|
<tr>
|
|
7
|
-
<th v-for="column in props.columns" :key="column.name" scope="col" class="datagrid-th" :style="column.headerStyle||''"
|
|
7
|
+
<th v-for="column in props.columns" :key="column.name" scope="col" class="datagrid-th" :style="column.headerStyle||''"
|
|
8
|
+
@click="column.sortable !== false && handleSort(column.name)"
|
|
9
|
+
:class="{ 'sortable': column.sortable !== false }">
|
|
8
10
|
<slot :name="column.name+'_header'" :column="column">
|
|
9
|
-
<
|
|
11
|
+
<div class="header-content">
|
|
12
|
+
<span>{{column.text||column.name||''}}</span>
|
|
13
|
+
<span v-if="column.sortable !== false" class="sort-icon">
|
|
14
|
+
<i v-if="props.sortField === column.name && props.sortOrder === 'ASC'" class="bi bi-caret-up-fill"></i>
|
|
15
|
+
<i v-else-if="props.sortField === column.name && props.sortOrder === 'DESC'" class="bi bi-caret-down-fill"></i>
|
|
16
|
+
<i v-else class="bi bi-caret-up text-muted opacity-50"></i>
|
|
17
|
+
</span>
|
|
18
|
+
</div>
|
|
10
19
|
</slot>
|
|
11
20
|
</th>
|
|
12
21
|
</tr>
|
|
@@ -43,7 +52,8 @@
|
|
|
43
52
|
component?: Component;
|
|
44
53
|
headerStyle?: string;
|
|
45
54
|
style?: string;
|
|
46
|
-
|
|
55
|
+
sortable?: boolean;
|
|
56
|
+
formatter?: (row: any, column: ColumnType) => string;
|
|
47
57
|
};
|
|
48
58
|
|
|
49
59
|
const props = defineProps({
|
|
@@ -75,10 +85,18 @@
|
|
|
75
85
|
columns: {
|
|
76
86
|
type: Array<ColumnType>,
|
|
77
87
|
default: []
|
|
88
|
+
},
|
|
89
|
+
sortField: {
|
|
90
|
+
type: String,
|
|
91
|
+
default: ''
|
|
92
|
+
},
|
|
93
|
+
sortOrder: {
|
|
94
|
+
type: String,
|
|
95
|
+
default: '' // ASC, DESC, ''
|
|
78
96
|
}
|
|
79
97
|
});
|
|
80
98
|
|
|
81
|
-
const emits = defineEmits(['pageChanged', 'rowClicked']);
|
|
99
|
+
const emits = defineEmits(['pageChanged', 'rowClicked', 'sortChanged']);
|
|
82
100
|
|
|
83
101
|
function renderDataItem(row: any, column: any) {
|
|
84
102
|
if(typeof column === 'string') return row[column];
|
|
@@ -92,14 +110,54 @@
|
|
|
92
110
|
emits('pageChanged', page);
|
|
93
111
|
}
|
|
94
112
|
|
|
113
|
+
function handleSort(field: string) {
|
|
114
|
+
let order: 'ASC' | 'DESC' | '' = 'ASC';
|
|
115
|
+
if (props.sortField === field) {
|
|
116
|
+
if (props.sortOrder === 'ASC') {
|
|
117
|
+
order = 'DESC';
|
|
118
|
+
} else if (props.sortOrder === 'DESC') {
|
|
119
|
+
order = ''; // 取消排序
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
emits('sortChanged', { field: order ? field : '', order });
|
|
123
|
+
}
|
|
124
|
+
|
|
95
125
|
</script>
|
|
96
126
|
|
|
97
127
|
<style scoped>
|
|
128
|
+
.datagrid-container {
|
|
129
|
+
display: flex;
|
|
130
|
+
flex-direction: column;
|
|
131
|
+
height: 100%;
|
|
132
|
+
}
|
|
98
133
|
.datagrid-inner {
|
|
134
|
+
flex: 1;
|
|
99
135
|
overflow: auto;
|
|
100
136
|
margin-bottom: 10px;
|
|
101
137
|
}
|
|
102
138
|
.datagrid-th {
|
|
103
139
|
min-width: 80px;
|
|
140
|
+
white-space: nowrap;
|
|
141
|
+
position: sticky;
|
|
142
|
+
top: 0;
|
|
143
|
+
z-index: 10;
|
|
144
|
+
background-color: #f8f9fa;
|
|
145
|
+
}
|
|
146
|
+
.datagrid-th.sortable {
|
|
147
|
+
cursor: pointer;
|
|
148
|
+
user-select: none;
|
|
149
|
+
}
|
|
150
|
+
.datagrid-th.sortable:hover {
|
|
151
|
+
background-color: #e9ecef;
|
|
152
|
+
}
|
|
153
|
+
.header-content {
|
|
154
|
+
display: flex;
|
|
155
|
+
align-items: center;
|
|
156
|
+
gap: 0.5rem;
|
|
157
|
+
}
|
|
158
|
+
.sort-icon {
|
|
159
|
+
display: flex;
|
|
160
|
+
align-items: center;
|
|
161
|
+
font-size: 0.75rem;
|
|
104
162
|
}
|
|
105
163
|
</style>
|
|
@@ -122,8 +122,13 @@
|
|
|
122
122
|
<i class="bi bi-table"></i>
|
|
123
123
|
</div>
|
|
124
124
|
<div class="table-info">
|
|
125
|
-
<div class="table-name">
|
|
126
|
-
|
|
125
|
+
<div class="table-name-wrapper">
|
|
126
|
+
<div class="table-name" :title="table.name">{{ table.name }}</div>
|
|
127
|
+
<div class="table-engine">{{ table.engine || '-' }}</div>
|
|
128
|
+
</div>
|
|
129
|
+
<div class="table-comment-header" v-if="table.comment" :title="table.comment">
|
|
130
|
+
{{ table.comment }}
|
|
131
|
+
</div>
|
|
127
132
|
</div>
|
|
128
133
|
</div>
|
|
129
134
|
<div class="card-body">
|
|
@@ -137,9 +142,6 @@
|
|
|
137
142
|
<span class="stat-value">{{ formatSize(table.dataSize) }}</span>
|
|
138
143
|
</div>
|
|
139
144
|
</div>
|
|
140
|
-
<div class="table-comment" v-if="table.comment">
|
|
141
|
-
{{ table.comment }}
|
|
142
|
-
</div>
|
|
143
145
|
<div class="table-actions">
|
|
144
146
|
<button class="btn btn-sm btn-outline-primary" @click.stop="editTable(table)">
|
|
145
147
|
<i class="bi bi-pencil"></i>
|
|
@@ -998,10 +1000,24 @@ function handleExecuteSQL(sql: string) {
|
|
|
998
1000
|
color: white;
|
|
999
1001
|
}
|
|
1000
1002
|
|
|
1003
|
+
.table-info {
|
|
1004
|
+
flex: 1;
|
|
1005
|
+
min-width: 0; /* 允许子元素截断 */
|
|
1006
|
+
}
|
|
1007
|
+
|
|
1008
|
+
.table-name-wrapper {
|
|
1009
|
+
display: flex;
|
|
1010
|
+
align-items: center;
|
|
1011
|
+
gap: 0.5rem;
|
|
1012
|
+
margin-bottom: 0.25rem;
|
|
1013
|
+
}
|
|
1014
|
+
|
|
1001
1015
|
.table-name {
|
|
1002
1016
|
font-weight: 600;
|
|
1003
1017
|
color: #1e293b;
|
|
1004
|
-
|
|
1018
|
+
white-space: nowrap;
|
|
1019
|
+
overflow: hidden;
|
|
1020
|
+
text-overflow: ellipsis;
|
|
1005
1021
|
}
|
|
1006
1022
|
|
|
1007
1023
|
.table-engine {
|
|
@@ -1010,6 +1026,15 @@ function handleExecuteSQL(sql: string) {
|
|
|
1010
1026
|
background: #f1f5f9;
|
|
1011
1027
|
padding: 0.125rem 0.375rem;
|
|
1012
1028
|
border-radius: 8px;
|
|
1029
|
+
flex-shrink: 0;
|
|
1030
|
+
}
|
|
1031
|
+
|
|
1032
|
+
.table-comment-header {
|
|
1033
|
+
font-size: 0.75rem;
|
|
1034
|
+
color: #64748b;
|
|
1035
|
+
white-space: nowrap;
|
|
1036
|
+
overflow: hidden;
|
|
1037
|
+
text-overflow: ellipsis;
|
|
1013
1038
|
}
|
|
1014
1039
|
|
|
1015
1040
|
.card-body {
|