Skip to content

Commit 4663ad4

Browse files
Merge pull request #623 from lukecotter/fix-find-in-groups
fix: find to work in groups
2 parents e2e84d4 + b45097a commit 4663ad4

6 files changed

Lines changed: 130 additions & 111 deletions

File tree

log-viewer/modules/components/analysis-view/AnalysisView.ts

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -185,7 +185,9 @@ export class AnalysisView extends LitElement {
185185
return (this.tableContainer ??= this.renderRoot?.querySelector('#analysis-table'));
186186
}
187187

188-
_findEvt = ((event: FindEvt) => this._find(event)) as EventListener;
188+
_findEvt = ((event: FindEvt) => {
189+
this._find(event);
190+
}) as EventListener;
189191

190192
_groupBy(event: Event) {
191193
const target = event.target as HTMLInputElement;
@@ -208,7 +210,7 @@ export class AnalysisView extends LitElement {
208210
});
209211
}
210212

211-
_find(e: CustomEvent<{ text: string; count: number; options: { matchCase: boolean } }>) {
213+
async _find(e: CustomEvent<{ text: string; count: number; options: { matchCase: boolean } }>) {
212214
const isTableVisible = !!this.analysisTable?.element?.clientHeight;
213215
if (!isTableVisible && !this.totalMatches) {
214216
return;
@@ -226,8 +228,8 @@ export class AnalysisView extends LitElement {
226228
}
227229
if (newSearch || clearHighlights) {
228230
this.blockClearHighlights = true;
229-
//@ts-expect-error This is a custom function added in by Find custom module
230-
const result = this.analysisTable.find(this.findArgs);
231+
// @ts-expect-error This is a custom function added in by Find custom module
232+
const result = await this.analysisTable?.find(this.findArgs);
231233
this.blockClearHighlights = false;
232234
this.totalMatches = result.totalMatches;
233235
this.findMap = result.matchIndexes;

log-viewer/modules/components/calltree-view/CalltreeView.ts

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -218,7 +218,9 @@ export class CalltreeView extends LitElement {
218218
`;
219219
}
220220

221-
_findEvt = ((event: FindEvt) => this._find(event)) as EventListener;
221+
_findEvt = ((event: FindEvt) => {
222+
this._find(event);
223+
}) as EventListener;
222224

223225
_getAllTypes(data: LogLine[]): string[] {
224226
const flattened = this._flatten(data);
@@ -345,7 +347,7 @@ export class CalltreeView extends LitElement {
345347
this.calltreeTable.goToRow(treeRow, { scrollIfVisible: true, focusRow: true });
346348
}
347349

348-
_find(e: CustomEvent<{ text: string; count: number; options: { matchCase: boolean } }>) {
350+
async _find(e: CustomEvent<{ text: string; count: number; options: { matchCase: boolean } }>) {
349351
const isTableVisible = !!this.calltreeTable?.element?.clientHeight;
350352
if (!isTableVisible && !this.totalMatches) {
351353
return;
@@ -365,7 +367,7 @@ export class CalltreeView extends LitElement {
365367
if (newSearch || clearHighlights) {
366368
this.blockClearHighlights = true;
367369
//@ts-expect-error This is a custom function added in by Find custom module
368-
const result = this.calltreeTable.find(this.findArgs);
370+
const result = await this.calltreeTable.find(this.findArgs);
369371
this.blockClearHighlights = false;
370372
this.totalMatches = result.totalMatches;
371373
this.findMap = result.matchIndexes;

log-viewer/modules/components/calltree-view/module/Find.ts

Lines changed: 51 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,7 @@
11
/*
22
* Copyright (c) 2024 Certinia Inc. All rights reserved.
33
*/
4-
import {
5-
Module,
6-
type CellComponent,
7-
type GroupComponent,
8-
type RowComponent,
9-
type Tabulator,
10-
} from 'tabulator-tables';
4+
import { Module, type GroupComponent, type RowComponent, type Tabulator } from 'tabulator-tables';
115

126
export class Find extends Module {
137
static moduleName = 'FindModule';
@@ -22,14 +16,15 @@ export class Find extends Module {
2216

2317
initialize() {}
2418

25-
_find(findArgs: FindArgs) {
19+
async _find(findArgs: FindArgs) {
2620
const result: { totalMatches: number; matchIndexes: { [key: number]: RowComponent } } = {
2721
totalMatches: 0,
2822
matchIndexes: {},
2923
};
3024

3125
this._clearMatches();
3226

27+
// We only do this when groups exist to get row order
3328
const flattenFromGrps = (row: GroupComponent): RowComponent[] => {
3429
const mergedArray: RowComponent[] = [];
3530
Array.prototype.push.apply(mergedArray, row.getRows());
@@ -52,51 +47,50 @@ export class Find extends Module {
5247
const regex = new RegExp(searchString, `g${findArgs.options.matchCase ? '' : 'i'}`);
5348

5449
tbl.blockRedraw();
55-
let totalMatches = 0;
56-
const rowsToReformat = [];
57-
const len = flattenedRows.length;
58-
for (let i = 0; i < len; i++) {
59-
const row = flattenedRows[i];
60-
if (!row) {
61-
continue;
62-
}
63-
64-
let clearHighlight = false;
50+
for (const row of flattenedRows) {
6551
const data = row.getData();
66-
if (data.highlightIndexes?.length) {
67-
clearHighlight = true;
68-
rowsToReformat.push(row);
52+
if (data.highlightIndexes?.length > 0) {
53+
data.highlightIndexes.length = 0;
54+
row.reformat();
55+
} else if (!data.highlightIndexes) {
56+
data.highlightIndexes = [];
6957
}
58+
}
59+
tbl.restoreRedraw();
7060

71-
data.highlightIndexes = [];
72-
73-
if (!searchString) {
74-
continue;
75-
}
76-
let reformat = false;
77-
78-
row.getCells().forEach((cell: CellComponent) => {
79-
const elem = cell.getElement();
80-
const matchCount = this._countMatches(elem, findArgs, regex);
81-
if (matchCount) {
82-
const kLen = matchCount;
83-
for (let k = 0; k < kLen; k++) {
84-
totalMatches++;
85-
data.highlightIndexes.push(totalMatches);
86-
result.matchIndexes[totalMatches] = row;
87-
}
88-
reformat = true;
61+
await new Promise((resolve) => requestAnimationFrame(resolve));
62+
let totalMatches = 0;
63+
if (searchString) {
64+
const rowsToReformat = new Set<RowComponent>();
65+
const len = flattenedRows.length;
66+
for (let i = 0; i < len; i++) {
67+
const row = flattenedRows[i];
68+
if (!row) {
69+
continue;
8970
}
90-
});
9171

92-
if (reformat && !clearHighlight) {
93-
rowsToReformat.push(row);
72+
const data = row.getData();
73+
data.highlightIndexes = [];
74+
row.getCells().forEach((cell) => {
75+
const elem = cell.getElement();
76+
const matchCount = this._countMatches(elem, findArgs, regex);
77+
if (matchCount) {
78+
const kLen = matchCount;
79+
for (let k = 0; k < kLen; k++) {
80+
totalMatches++;
81+
data.highlightIndexes.push(totalMatches);
82+
result.matchIndexes[totalMatches] = row;
83+
}
84+
rowsToReformat.add(row);
85+
}
86+
});
9487
}
88+
tbl.blockRedraw();
89+
rowsToReformat.forEach((row) => {
90+
row?.reformat();
91+
});
92+
tbl.restoreRedraw();
9593
}
96-
rowsToReformat.forEach((row) => {
97-
row?.reformat();
98-
});
99-
tbl.restoreRedraw();
10094

10195
result.totalMatches = totalMatches;
10296
return result;
@@ -212,21 +206,28 @@ export class Find extends Module {
212206
}
213207

214208
export function formatter(row: RowComponent, findArgs: FindArgs) {
215-
const { text, count } = findArgs;
216-
if (!text || !count || !row.getData() || !row.getData().highlightIndexes?.length) {
209+
const { text } = findArgs;
210+
if (!text) {
217211
return;
218212
}
219-
220213
const data = row.getData();
214+
if (!data || !data.highlightIndexes?.length) {
215+
return;
216+
}
217+
221218
const highlights = {
222219
indexes: data.highlightIndexes,
223220
currentMatch: 0,
224221
};
225-
226222
row.getCells().forEach((cell) => {
227223
const cellElem = cell.getElement();
228224
_highlightText(cellElem, findArgs, highlights);
229225
});
226+
227+
//@ts-expect-error This is private to tabulator, but we have no other choice atm.
228+
if (row._getSelf().type === 'row') {
229+
row.normalizeHeight();
230+
}
230231
}
231232

232233
function _highlightText(

log-viewer/modules/components/database-view/DMLView.ts

Lines changed: 35 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -159,7 +159,9 @@ export class DMLView extends LitElement {
159159
this.dmlTable?.download('csv', 'dml.csv', { bom: true, delimiter: ',' });
160160
}
161161

162-
_findEvt = ((event: FindEvt) => this._find(event)) as EventListener;
162+
_findEvt = ((event: FindEvt) => {
163+
this._find(event);
164+
}) as EventListener;
163165

164166
_dmlGroupBy(event: Event) {
165167
const target = event.target as HTMLInputElement;
@@ -219,7 +221,7 @@ export class DMLView extends LitElement {
219221
this.oldIndex = highlightIndex;
220222
}
221223

222-
_find(e: CustomEvent<{ text: string; count: number; options: { matchCase: boolean } }>) {
224+
async _find(e: CustomEvent<{ text: string; count: number; options: { matchCase: boolean } }>) {
223225
const isTableVisible = !!this.dmlTable?.element?.clientHeight;
224226
if (!isTableVisible && !this.totalMatches) {
225227
return;
@@ -242,7 +244,7 @@ export class DMLView extends LitElement {
242244
if (newSearch || clearHighlights) {
243245
this.blockClearHighlights = true;
244246
//@ts-expect-error This is a custom function added in by Find custom module
245-
const result = this.dmlTable.find(this.findArgs);
247+
const result = await this.dmlTable.find(this.findArgs);
246248
this.blockClearHighlights = false;
247249
this.totalMatches = result.totalMatches;
248250
this.findMap = result.matchIndexes;
@@ -270,7 +272,6 @@ export class DMLView extends LitElement {
270272
});
271273
}
272274
}
273-
const dmlText = this.sortByFrequency(dmlData || [], 'dml');
274275

275276
this.dmlTable = new Tabulator(dmlTableContainer, {
276277
height: '100%',
@@ -296,8 +297,6 @@ export class DMLView extends LitElement {
296297
groupSort: true,
297298
groupClosedShowCalcs: true,
298299
groupStartOpen: false,
299-
groupValues: [dmlText],
300-
groupBy: ['dml'],
301300
groupToggleElement: false,
302301
selectableRowsCheck: function (row: RowComponent) {
303302
return !row.getData().isDetail;
@@ -379,7 +378,6 @@ export class DMLView extends LitElement {
379378
if (data.isDetail && data.timestamp) {
380379
const detailContainer = this.createDetailPanel(data.timestamp);
381380
row.getElement().replaceChildren(detailContainer);
382-
row.normalizeHeight();
383381
}
384382

385383
requestAnimationFrame(() => {
@@ -422,22 +420,39 @@ export class DMLView extends LitElement {
422420
row.getCell('dml').getElement().style.height = origRowHeight + 'px';
423421
});
424422

425-
this.dmlTable.on('renderStarted', () => {
426-
if (!this.blockClearHighlights && this.totalMatches > 0) {
427-
this._resetFindWidget();
428-
this._clearSearchHighlights();
429-
}
430-
423+
this.dmlTable.on('tableBuilt', () => {
431424
const holder = this._getTableHolder();
432-
holder.style.minHeight = holder.clientHeight + 'px';
433425
holder.style.overflowAnchor = 'none';
426+
//@ts-expect-error This is a custom function added in the GroupSort custom module
427+
this.dmlTable?.setSortedGroupBy('dml');
434428
});
435429

436430
this.dmlTable.on('renderComplete', () => {
437431
const holder = this._getTableHolder();
438432
const table = this._getTable();
439433
holder.style.minHeight = Math.min(holder.clientHeight, table.clientHeight) + 'px';
440434
});
435+
436+
this.dmlTable.on('dataSorted', () => {
437+
if (!this.blockClearHighlights && this.totalMatches > 0) {
438+
this._resetFindWidget();
439+
this._clearSearchHighlights();
440+
}
441+
});
442+
443+
this.dmlTable.on('dataGrouped', () => {
444+
if (!this.blockClearHighlights && this.totalMatches > 0) {
445+
this._resetFindWidget();
446+
this._clearSearchHighlights();
447+
}
448+
});
449+
450+
this.dmlTable.on('dataFiltering', () => {
451+
if (!this.blockClearHighlights && this.totalMatches > 0) {
452+
this._resetFindWidget();
453+
this._clearSearchHighlights();
454+
}
455+
});
441456
}
442457

443458
_resetFindWidget() {
@@ -455,6 +470,12 @@ export class DMLView extends LitElement {
455470
this.dmlTable.clearFindHighlights(Object.values(this.findMap));
456471
this.findMap = {};
457472
this.totalMatches = 0;
473+
474+
document.dispatchEvent(
475+
new CustomEvent('db-find-results', {
476+
detail: { totalMatches: this.totalMatches, type: 'dml' },
477+
}),
478+
);
458479
}
459480

460481
_getTable() {
@@ -475,17 +496,6 @@ export class DMLView extends LitElement {
475496
return detailContainer;
476497
}
477498

478-
sortByFrequency(dataArray: DMLRow[], field: keyof DMLRow) {
479-
const map = new Map<unknown, number>();
480-
dataArray.forEach((row) => {
481-
const val = row[field];
482-
map.set(val, (map.get(val) || 0) + 1);
483-
});
484-
const newMap = new Map([...map.entries()].sort((a, b) => b[1] - a[1]));
485-
486-
return [...newMap.keys()];
487-
}
488-
489499
downlodEncoder(defaultFileName: string) {
490500
return function (fileContents: string, mimeType: string) {
491501
const vscode = vscodeMessenger.getVsCodeAPI();

log-viewer/modules/components/database-view/DatabaseView.ts

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -84,10 +84,6 @@ export class DatabaseView extends LitElement {
8484
};
8585

8686
_findResults = (e: CustomEvent<{ totalMatches: number; type: 'dml' | 'soql' }>) => {
87-
if (!this.shadowRoot?.host.clientHeight) {
88-
return;
89-
}
90-
9187
if (e.detail.type === 'dml') {
9288
this.dmlMatches = e.detail.totalMatches;
9389
} else if (e.detail.type === 'soql') {

0 commit comments

Comments
 (0)