Skip to content

Commit e0429d3

Browse files
committed
Implement relationship grouping for table widget
1 parent dd8bbd4 commit e0429d3

File tree

3 files changed

+111
-10
lines changed

3 files changed

+111
-10
lines changed

etc/js/common.js

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,13 @@ explorer = {
1515

1616
parsePair: function(expr) {
1717
if (expr[0] !== "(") {
18-
console.error("Invalid pair: " + expr);
1918
return undefined;
2019
}
2120

22-
return expr.slice(1, -1).split(",");
21+
let pair = expr.slice(1, -1).split(",");
22+
pair[0] = pair[0].trim();
23+
pair[1] = pair[1].trim();
24+
return pair;
2325
},
2426

2527
shortenComponent: function(component) {

etc/js/components/pages/internals/tables.vue

Lines changed: 61 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,8 @@
44
:headers="headers"
55
:data="filteredTables"
66
v-model:filter="filter"
7-
show_filter="true">
7+
show_filter="true"
8+
@selectItem="onSelectItem">
89
</data-table>
910
</div>
1011
</template>
@@ -21,34 +22,43 @@ const props = defineProps({
2122
});
2223
2324
const filter = ref("");
25+
const group = ref(null);
2426
2527
const headers = computed(() => {
28+
let IdHeader = "ID";
29+
if (group.value) {
30+
IdHeader = "Count";
31+
}
2632
return [
27-
{name: "ID", schema: ["table-id"], get: (table) => table.id},
33+
{name: IdHeader, schema: ["table-id"], get: (table) => table.id},
2834
{name: "Entities", schema: ["int"], totals: true, get: (table) => table.count},
2935
{name: "Capacity", schema: ["int"], totals: true, get: (table) => table.size},
3036
{name: "Columns", schema: ["int"], get: (table) => table.type.length},
3137
{name: "Memory (KB)", schema: ["float"], totals: true, get: (table) => {
3238
if (!table.memory) {
3339
return 0;
3440
}
41+
if (typeof table.memory === "number") {
42+
return table.memory / 1000;
43+
}
3544
return ((explorer.calculateMemoryTotal(table.memory.table) +
3645
explorer.calculateMemoryTotal(table.memory.components)) / 1000);
3746
}},
38-
{name: "Components", schema: ["table-type"],get: (table) => formatType(table.type)},
47+
{name: "Components", list: true, get: (table) => formatType(table.type)},
3948
];
4049
});
4150
4251
const searchableType = computed(() => {
4352
return props.tables.map((table) => {
44-
return formatType(table.type).toLowerCase().split(" ").join("");
53+
return formatType(table.type).join("").split(" ").join("").toLowerCase();
4554
});
4655
});
4756
4857
const filteredTables = computed(() => {
58+
let tables = props.tables;
4959
if (filter.value && filter.value.length > 0) {
5060
const F = filter.value.toLowerCase().split(" ").join("").split(",");
51-
return props.tables.filter((table, index) => {
61+
tables = tables.filter((table, index) => {
5262
const v = searchableType.value[index];
5363
for (let f of F) {
5464
if (!v.includes(f)) {
@@ -58,7 +68,37 @@ const filteredTables = computed(() => {
5868
return true;
5969
});
6070
}
61-
return props.tables;
71+
72+
if (group.value) {
73+
// create map for group strings
74+
let groups = {};
75+
76+
for (let table of tables) {
77+
for (let i = 0; i < table.type.length; i++) {
78+
const id = table.type[i];
79+
if (id.includes(group.value)) {
80+
let copy = table.type.slice();
81+
copy[i] = "(" + group.value + "," + "*)";
82+
83+
const key = copy.join(", ");
84+
let val = groups[key];
85+
if (!val) {
86+
val = groups[key] = {id: 0, count: 0, size: 0, memory: 0, type: copy};
87+
}
88+
val.id ++;
89+
val.count += table.count;
90+
val.size += table.size;
91+
val.memory += explorer.calculateMemoryTotal(table.memory.table);
92+
val.memory += explorer.calculateMemoryTotal(table.memory.components);
93+
break;
94+
}
95+
}
96+
}
97+
98+
tables = Object.values(groups);
99+
}
100+
101+
return tables;
62102
});
63103
64104
function formatType(type) {
@@ -69,7 +109,21 @@ function formatType(type) {
69109
result.push(str);
70110
}
71111
72-
return result.join(", ");;
112+
return result;
113+
}
114+
115+
function onSelectItem(evt) {
116+
const pair = explorer.parsePair(evt.item);
117+
if (!pair) {
118+
return;
119+
}
120+
121+
if (pair[1] === "*") {
122+
group.value = undefined;
123+
return;
124+
}
125+
126+
group.value = pair[0];
73127
}
74128
75129
</script>

etc/js/components/widgets/data-table.vue

Lines changed: 46 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,12 @@
5858
fieldClass="table-field">
5959
</entity-inspector-preview>
6060
</template>
61+
<template v-else-if="col.list">
62+
<template v-for="(item, i) in col.get(row)">
63+
<span class="data-table-list-item-comma" v-if="i > 0">,</span>
64+
<span :class="itemClass(item)" @click.stop="onSelectItem({column: col, item: item})">{{ item }}</span>
65+
</template>
66+
</template>
6167
<template v-else>
6268
{{ col.get(row) }}
6369
</template>
@@ -97,7 +103,7 @@ import { defineProps, defineEmits, defineExpose, defineModel,computed, ref, watc
97103
98104
const orderByModes = ["none", "asc", "desc"];
99105
const orderBy = ref({});
100-
const emit = defineEmits(["select"]);
106+
const emit = defineEmits(["select", "selectItem"]);
101107
const offset = ref(0);
102108
const limit = ref(50);
103109
@@ -110,6 +116,14 @@ const props = defineProps({
110116
111117
const filter = defineModel("filter");
112118
119+
function itemClass(item) {
120+
let result = ["data-table-list-item"];
121+
if (!item || item.includes("*")) {
122+
result.push("data-table-list-item-highlight");
123+
}
124+
return result;
125+
}
126+
113127
const orderByIndices = computed(() => {
114128
if (!orderBy.value.mode || orderBy.value.mode === 'none') {
115129
return undefined;
@@ -286,6 +300,10 @@ function onSelectEntity(e) {
286300
return emit("select", e);
287301
}
288302
303+
function onSelectItem(evt) {
304+
return emit("selectItem", evt);
305+
}
306+
289307
function onPrev() {
290308
offset.value -= limit.value;
291309
if (offset.value < 0) {
@@ -437,4 +455,31 @@ tr.data-table-row-selectable:hover td {
437455
span.entity-link:hover {
438456
color: var(--green);
439457
}
458+
459+
span.data-table-list-item {
460+
border-radius: var(--border-radius-medium);
461+
color: var(--secondary-text);
462+
cursor: pointer;
463+
transition: color var(--animation-duration);
464+
}
465+
466+
span.data-table-list-item-comma {
467+
color: var(--secondary-text);
468+
padding-left: 0px;
469+
padding-right: 4px;
470+
}
471+
472+
span.data-table-list-item-highlight {
473+
font-weight: 500;
474+
background-color: var(--bg-cell-hover);
475+
padding: 4px;
476+
border-radius: var(--border-radius-medium);
477+
cursor: pointer;
478+
}
479+
480+
span.data-table-list-item:hover {
481+
color: var(--primary-text);
482+
background-color: var(--bg-cell-hover);
483+
}
484+
440485
</style>

0 commit comments

Comments
 (0)