Skip to content

Commit 32a4a5a

Browse files
Merge pull request #578 from lukecotter/feat-table-action-buttons
feat: table action buttons
2 parents 2fb3b85 + 2e82b96 commit 32a4a5a

7 files changed

Lines changed: 211 additions & 95 deletions

File tree

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1010
### Added
1111

1212
- Column totals for Grouped rows will now be shown inside the groups instead of on a seperate row ([#583][#583]).
13+
- Table actions: Copy to clipboard and Export to CSV directly from the button above the Analysis and Database table ([#589]).
1314

1415
### Changed
1516

@@ -384,6 +385,7 @@ Skipped due to adopting odd numbering for pre releases and even number for relea
384385
[#582]: https://github.com/certinia/debug-log-analyzer/issues/582
385386
[#588]: https://github.com/certinia/debug-log-analyzer/issues/588
386387
[#583]: https://github.com/certinia/debug-log-analyzer/issues/583
388+
[#589]: https://github.com/certinia/debug-log-analyzer/issues/589
387389

388390
<!-- 1.16.1 -->
389391

README.md

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77

88
Apex Log Analyzer makes performance analysis of Salesforce debug logs much easier and quicker. Visualize code execution via a Flame chart and Call Tree, identify and resolve performance and SOQL/DML problems via Method and Database Analysis.
99

10+
Visualize code execution via a Flame chart and identify performance and SOQL/DML problems via Method and Database analysis
11+
1012
![preview](https://raw.githubusercontent.com/certinia/debug-log-analyzer/main/lana/dist/images/lana-preview.gif)
1113

1214
## WARNING
@@ -163,8 +165,8 @@ The rows can be grouped by Type or Namespace
163165

164166
#### Export to CSV + copy to clipboard
165167

166-
Click the header menu,``, and use `Export to CSV` to save the table content to a file.
167-
Focus the Analysis table and use `CMD / CTRL + c` to copy the table content to clipboard. This can then be pasted into a spreadsheet or other file.
168+
Use `Export to CSV` above the table to save the table content to a file or `Copy to Clipboard`.
169+
You can also focus the Analysis table and use `CMD / CTRL + c` to copy the table content to clipboard. This can then be pasted into a spreadsheet or other file.
168170

169171
### Database
170172

@@ -202,8 +204,8 @@ For SOQL rows, to the right of the Call Stack is SOQL Analysis which shows infor
202204

203205
#### Export to CSV + copy to clipboard
204206

205-
Click the header menu,``, and use `Export to CSV` to save the table content to a file.
206-
Focus the Analysis table and use `CMD / CTRL + c` to copy the table content to clipboard. This can then be pasted into a spreadsheet or other file.
207+
Use `Export to CSV` above the table to save the table content to a file or `Copy to Clipboard`.
208+
You can also focus the DML/ SOQL tables and use `CMD / CTRL + c` to copy the table content to clipboard. This can then be pasted into a spreadsheet or other file.
207209

208210
### Find
209211

lana-docs-site/docs/docs/features.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -91,8 +91,8 @@ The rows can be grouped by Type or Namespace
9191

9292
### Export to CSV + copy to clipboard
9393

94-
Click the header menu,``, and use `Export to CSV` to save the table content to a file.
95-
Focus the Analysis table and use `CMD / CTRL + c` to copy the table content to clipboard. This can then be pasted into a spreadsheet or other file.
94+
Use `Export to CSV` above the table to save the table content to a file or `Copy to Clipboard`.
95+
You can also focus the Analysis tables and use `CMD / CTRL + c` to copy the table content to clipboard. This can then be pasted into a spreadsheet or other file.
9696

9797
## 💾 Database
9898

@@ -130,8 +130,8 @@ For SOQL rows, to the right of the Call Stack is SOQL Analysis which shows infor
130130

131131
### Export to CSV + copy to clipboard
132132

133-
Click the header menu,``, and use `Export to CSV` to save the table content to a file.
134-
Focus the Analysis table and use `CMD / CTRL + c` to copy the table content to clipboard. This can then be pasted into a spreadsheet or other file.
133+
Use `Export to CSV` above the table to save the table content to a file or `Copy to Clipboard`.
134+
You can also focus the DML/ SOQL tables and use `CMD / CTRL + c` to copy the table content to clipboard. This can then be pasted into a spreadsheet or other file.
135135

136136
## 🔍 Find
137137

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

Lines changed: 59 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -3,39 +3,47 @@
33
*/
44
import {
55
provideVSCodeDesignSystem,
6+
vsCodeButton,
67
vsCodeCheckbox,
78
vsCodeDropdown,
89
vsCodeOption,
910
} from '@vscode/webview-ui-toolkit';
1011
import { LitElement, css, html, unsafeCSS, type PropertyValues } from 'lit';
1112
import { customElement, property } from 'lit/decorators.js';
12-
import { Tabulator, type ColumnComponent, type RowComponent } from 'tabulator-tables';
13-
import * as CommonModules from '../../datagrid/module/CommonModules.js';
14-
15-
import NumberAccessor from '../../datagrid/dataaccessor/Number.js';
16-
import { progressFormatter } from '../../datagrid/format/Progress.js';
17-
import { RowKeyboardNavigation } from '../../datagrid/module/RowKeyboardNavigation.js';
18-
import dataGridStyles from '../../datagrid/style/DataGrid.scss';
1913
import { ApexLog, LogLine } from '../../parsers/ApexLogParser.js';
2014
import { vscodeMessenger } from '../../services/VSCodeExtensionMessenger.js';
2115
import { globalStyles } from '../../styles/global.styles.js';
22-
import { isVisible } from '../../Util.js';
2316

17+
// Tabulator custom modules, imports + styles
18+
import { Tabulator, type RowComponent } from 'tabulator-tables';
19+
import { isVisible } from '../../Util.js';
20+
import NumberAccessor from '../../datagrid/dataaccessor/Number.js';
21+
import { progressFormatter } from '../../datagrid/format/Progress.js';
22+
import { GroupCalcs } from '../../datagrid/group-calcs/GroupCalcs.js';
23+
import * as CommonModules from '../../datagrid/module/CommonModules.js';
24+
import { RowKeyboardNavigation } from '../../datagrid/module/RowKeyboardNavigation.js';
2425
import { RowNavigation } from '../../datagrid/module/RowNavigation.js';
26+
import dataGridStyles from '../../datagrid/style/DataGrid.scss';
27+
import codiconStyles from '../../styles/codicon.css';
2528
import { Find, formatter } from '../calltree-view/module/Find.js';
2629
import { callStackSum } from './column-calcs/CallStackSum.js';
2730

28-
import { GroupCalcs } from '../../datagrid/group-calcs/GroupCalcs.js';
29-
3031
// Components
32+
import '../datagrid/datagrid-filter-bar.js';
3133
import '../skeleton/GridSkeleton.js';
3234

33-
provideVSCodeDesignSystem().register(vsCodeCheckbox(), vsCodeDropdown(), vsCodeOption());
35+
provideVSCodeDesignSystem().register(
36+
vsCodeButton(),
37+
vsCodeCheckbox(),
38+
vsCodeDropdown(),
39+
vsCodeOption(),
40+
);
3441

3542
@customElement('analysis-view')
3643
export class AnalysisView extends LitElement {
3744
static styles = [
3845
unsafeCSS(dataGridStyles),
46+
unsafeCSS(codiconStyles),
3947
globalStyles,
4048
css`
4149
:host {
@@ -58,15 +66,15 @@ export class AnalysisView extends LitElement {
5866
flex-flow: column nowrap;
5967
align-items: flex-start;
6068
justify-content: flex-start;
61-
}
6269
63-
.dropdown-container label {
64-
display: block;
65-
color: var(--vscode-foreground);
66-
cursor: pointer;
67-
font-size: var(--vscode-font-size);
68-
line-height: normal;
69-
margin-bottom: 2px;
70+
label {
71+
display: block;
72+
color: var(--vscode-foreground);
73+
cursor: pointer;
74+
font-size: var(--vscode-font-size);
75+
line-height: normal;
76+
margin-bottom: 2px;
77+
}
7078
}
7179
`,
7280
];
@@ -106,23 +114,51 @@ export class AnalysisView extends LitElement {
106114
const skeleton = !this.timelineRoot ? html`<grid-skeleton></grid-skeleton>` : '';
107115

108116
return html`
109-
<div class="filter-container">
110-
<div class="dropdown-container">
111-
<label for="groupby-dropdown">Group by</label>
117+
<datagrid-filter-bar>
118+
<div slot="filters" class="dropdown-container">
119+
<label for="groupby-dropdown"><strong>Group by</strong></label>
112120
<vscode-dropdown id="groupby-dropdown" @change="${this._groupBy}">
113121
<vscode-option>None</vscode-option>
114122
<vscode-option>Namespace</vscode-option>
115123
<vscode-option>Type</vscode-option>
116124
</vscode-dropdown>
117125
</div>
118-
</div>
126+
127+
<div slot="actions">
128+
<vscode-button
129+
appearance="icon"
130+
aria-label="Export to CSV"
131+
title="Export to CSV"
132+
@click=${this._exportToCSV}
133+
>
134+
<span class="codicon codicon-desktop-download"></span>
135+
</vscode-button>
136+
<vscode-button
137+
appearance="icon"
138+
aria-label="Copy to clipboard"
139+
title="Copy to clipboard"
140+
@click=${this._copyToClipboard}
141+
>
142+
<span class="codicon codicon-copy"></span>
143+
</vscode-button>
144+
</div>
145+
</datagrid-filter-bar>
146+
119147
<div id="analysis-table-container">
120148
${skeleton}
121149
<div id="analysis-table"></div>
122150
</div>
123151
`;
124152
}
125153

154+
_copyToClipboard() {
155+
this.analysisTable?.copyToClipboard('all');
156+
}
157+
158+
_exportToCSV() {
159+
this.analysisTable?.download('csv', 'analysis.csv', { bom: true, delimiter: ',' });
160+
}
161+
126162
get _tableWrapper(): HTMLDivElement | null | undefined {
127163
return (this.tableContainer ??= this.renderRoot?.querySelector('#analysis-table'));
128164
}
@@ -197,15 +233,6 @@ export class AnalysisView extends LitElement {
197233
}
198234
const metricList = groupMetrics(rootMethod);
199235

200-
const headerMenu = [
201-
{
202-
label: 'Export to CSV',
203-
action: function (_e: PointerEvent, column: ColumnComponent) {
204-
column.getTable().download('csv', 'analysis.csv', { bom: true, delimiter: ',' });
205-
},
206-
},
207-
];
208-
209236
Tabulator.registerModule(Object.values(CommonModules));
210237
Tabulator.registerModule([RowKeyboardNavigation, RowNavigation, Find, GroupCalcs]);
211238
this.analysisTable = new Tabulator(this._tableWrapper, {
@@ -254,7 +281,6 @@ export class AnalysisView extends LitElement {
254281
resizable: true,
255282
headerSortStartingDir: 'desc',
256283
headerTooltip: true,
257-
headerMenu: headerMenu,
258284
headerWordWrap: true,
259285
},
260286
initialSort: [{ column: 'selfTime', dir: 'desc' }],

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

Lines changed: 45 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,14 @@
11
/*
22
* Copyright (c) 2022 Certinia Inc. All rights reserved.
33
*/
4-
import { provideVSCodeDesignSystem, vsCodeCheckbox } from '@vscode/webview-ui-toolkit';
4+
import {
5+
provideVSCodeDesignSystem,
6+
vsCodeButton,
7+
vsCodeCheckbox,
8+
} from '@vscode/webview-ui-toolkit';
59
import { LitElement, css, html, render, unsafeCSS, type PropertyValues } from 'lit';
610
import { customElement, property, state } from 'lit/decorators.js';
7-
import {
8-
Tabulator,
9-
type ColumnComponent,
10-
type GroupComponent,
11-
type RowComponent,
12-
} from 'tabulator-tables';
11+
import { Tabulator, type GroupComponent, type RowComponent } from 'tabulator-tables';
1312

1413
// tabulator custom modules
1514
import * as CommonModules from '../../datagrid/module/CommonModules.js';
@@ -27,6 +26,7 @@ import dataGridStyles from '../../datagrid/style/DataGrid.scss';
2726
import { DatabaseAccess } from '../../Database.js';
2827
import { ApexLog, DMLBeginLine } from '../../parsers/ApexLogParser.js';
2928
import { vscodeMessenger } from '../../services/VSCodeExtensionMessenger.js';
29+
import codiconStyles from '../../styles/codicon.css';
3030
import { globalStyles } from '../../styles/global.styles.js';
3131
import { isVisible } from '../../Util.js';
3232
import databaseViewStyles from './DatabaseView.scss';
@@ -35,7 +35,7 @@ import databaseViewStyles from './DatabaseView.scss';
3535
import '../CallStack.js';
3636
import './DatabaseSection.js';
3737

38-
provideVSCodeDesignSystem().register(vsCodeCheckbox());
38+
provideVSCodeDesignSystem().register(vsCodeButton(), vsCodeCheckbox());
3939

4040
@customElement('dml-view')
4141
export class DMLView extends LitElement {
@@ -86,6 +86,7 @@ export class DMLView extends LitElement {
8686
static styles = [
8787
unsafeCSS(dataGridStyles),
8888
unsafeCSS(databaseViewStyles),
89+
unsafeCSS(codiconStyles),
8990
globalStyles,
9091
css`
9192
:host {
@@ -112,19 +113,50 @@ export class DMLView extends LitElement {
112113

113114
return html`
114115
<database-section title="DML Statements" .dbLines="${this.dmlLines}"></database-section>
115-
<div>
116-
<strong>Group by</strong>
117-
<div>
118-
<vscode-checkbox @change="${this._dmlGroupBy}" checked>DML</vscode-checkbox>
116+
117+
<datagrid-filter-bar>
118+
<div slot="filters">
119+
<strong>Group by</strong>
120+
<div>
121+
<vscode-checkbox @change="${this._dmlGroupBy}" checked>DML</vscode-checkbox>
122+
</div>
119123
</div>
120-
</div>
124+
125+
<div slot="actions">
126+
<vscode-button
127+
appearance="icon"
128+
aria-label="Export to CSV"
129+
title="Export to CSV"
130+
@click=${this._exportToCSV}
131+
>
132+
<span class="codicon codicon-desktop-download"></span>
133+
</vscode-button>
134+
<vscode-button
135+
appearance="icon"
136+
aria-label="Copy to clipboard"
137+
title="Copy to clipboard"
138+
@click=${this._copyToClipboard}
139+
>
140+
<span class="codicon codicon-copy"></span>
141+
</vscode-button>
142+
</div>
143+
</datagrid-filter-bar>
144+
121145
<div id="dml-table-container">
122146
${dmlSkeleton}
123147
<div id="db-dml-table"></div>
124148
</div>
125149
`;
126150
}
127151

152+
_copyToClipboard() {
153+
this.dmlTable?.copyToClipboard('all');
154+
}
155+
156+
_exportToCSV() {
157+
this.dmlTable?.download('csv', 'dml.csv', { bom: true, delimiter: ',' });
158+
}
159+
128160
_findEvt = ((event: FindEvt) => this._find(event)) as EventListener;
129161

130162
_dmlGroupBy(event: Event) {
@@ -261,7 +293,6 @@ export class DMLView extends LitElement {
261293
resizable: true,
262294
headerSortStartingDir: 'desc',
263295
headerTooltip: true,
264-
headerMenu: this.csvheaderMenu('dml.csv'),
265296
headerWordWrap: true,
266297
},
267298
initialSort: [{ column: 'rowCount', dir: 'desc' }],
@@ -436,17 +467,6 @@ export class DMLView extends LitElement {
436467
return [...newMap.keys()];
437468
}
438469

439-
csvheaderMenu(csvFileName: string) {
440-
return [
441-
{
442-
label: 'Export to CSV',
443-
action: function (_e: PointerEvent, column: ColumnComponent) {
444-
column.getTable().download('csv', csvFileName, { bom: true, delimiter: ',' });
445-
},
446-
},
447-
];
448-
}
449-
450470
downlodEncoder(defaultFileName: string) {
451471
return function (fileContents: string, mimeType: string) {
452472
const vscode = vscodeMessenger.getVsCodeAPI();

0 commit comments

Comments
 (0)