Skip to content

Commit ad38851

Browse files
authored
Use webpack and react in resultview subproject (#128)
* Use webpack in result view, rewrite components using react * Rename buttons, change styling, improve other things * Create new components, add support for new webview * Fix explorer icons, fix resultview rows reloading * Improve resultview graphics, add statement, add record offset input * Improve logging, improve ui and ux * Change Pager to display page number instead of row offset * Remove html subproject test command
1 parent 399f67f commit ad38851

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

93 files changed

+5442
-1311
lines changed

.gitignore

+4
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,8 @@
1+
.vscode/extensions.json
2+
.vscode/settings.json
13
dist/
4+
out/
25
node_modules/
6+
.data/
37
*.vsix
48
*.db

.vscode/extensions.json

-7
This file was deleted.

.vscode/settings.json

-5
This file was deleted.

.vscodeignore

+1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
.vscode/
2+
.data/
23
tests/
34
dist/**/*.map
45
src/

package-lock.json

+29-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

+6-5
Original file line numberDiff line numberDiff line change
@@ -414,9 +414,10 @@
414414
"compile": "webpack --mode development",
415415
"watch": "webpack --mode development --watch",
416416
"test": "jest --silent --config jest.config.js",
417-
"install-html": "cd ./src/resultview/htmlcontent && npm install",
418-
"build-html": "cd ./src/resultview/htmlcontent && npm run build",
419-
"test-html": "cd ./src/resultview/htmlcontent && npm run test",
417+
"install-html": "cd ./src/resultview/html && npm install",
418+
"build-html": "cd ./src/resultview/html && npm run build",
419+
"test-html": "cd ./src/resultview/html && npm run test",
420+
"watch-html": "cd ./src/resultview/html && npm run watch",
420421
"package": "vsce package"
421422
},
422423
"devDependencies": {
@@ -435,8 +436,8 @@
435436
"webpack-cli": "^3.3.11"
436437
},
437438
"dependencies": {
439+
"clipboardy": "~2.3.0",
438440
"csv-parser": "~2.3.0",
439-
"csv-stringify": "~5.3.0",
440-
"clipboardy": "~2.3.0"
441+
"csv-stringify": "~5.3.0"
441442
}
442443
}

src/explorer/explorerTreeProvider.ts

+7-5
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { TreeDataProvider, Event, TreeItem, EventEmitter, ProviderResult } from "vscode";
1+
import { TreeDataProvider, Event, TreeItem, EventEmitter, ProviderResult, ExtensionContext } from "vscode";
22
import { DBItem, TableItem, ColumnItem } from "./treeItem";
33
import { Schema } from "../common";
44

@@ -8,9 +8,11 @@ export class ExplorerTreeProvider implements TreeDataProvider<Schema.Item> {
88
private _onDidChangeTreeData: EventEmitter<Schema.Item | undefined> = new EventEmitter<Schema.Item | undefined>();
99
readonly onDidChangeTreeData: Event<Schema.Item | undefined> = this._onDidChangeTreeData.event;
1010

11+
private context: ExtensionContext;
1112
private databaseList: Schema.Database[];
1213

13-
constructor() {
14+
constructor(context: ExtensionContext) {
15+
this.context = context;
1416
this.databaseList = [];
1517
}
1618

@@ -42,13 +44,13 @@ export class ExplorerTreeProvider implements TreeDataProvider<Schema.Item> {
4244
getTreeItem(item: Schema.Item): TreeItem {
4345
if ('tables' in item) {
4446
// Database
45-
return new DBItem(item.path);
47+
return new DBItem(this.context, item.path);
4648
} else if ('columns' in item) {
4749
// Table
48-
return new TableItem(item.name, item.type);
50+
return new TableItem(this.context, item.name, item.type);
4951
} else {
5052
// Column
51-
return new ColumnItem(item.name, item.type, item.notnull, item.pk, item.defVal);
53+
return new ColumnItem(this.context, item.name, item.type, item.notnull, item.pk, item.defVal);
5254
}
5355
}
5456

src/explorer/index.ts

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { Disposable, commands, window } from "vscode";
1+
import { Disposable, commands, window, ExtensionContext } from "vscode";
22
import { ExplorerTreeProvider } from "./explorerTreeProvider";
33
import * as treeItem from "./treeItem";
44
import { Constants } from "../constants/constants";
@@ -10,10 +10,10 @@ class Explorer implements Disposable {
1010

1111
private explorerTreeProvider: ExplorerTreeProvider;
1212

13-
constructor() {
13+
constructor(context: ExtensionContext) {
1414
let subscriptions = [];
1515

16-
this.explorerTreeProvider = new ExplorerTreeProvider();
16+
this.explorerTreeProvider = new ExplorerTreeProvider(context);
1717
subscriptions.push(window.createTreeView(Constants.sqliteExplorerViewId, { treeDataProvider: this.explorerTreeProvider }));
1818

1919
this.disposable = Disposable.from(...subscriptions);

src/explorer/treeItem.ts

+12-10
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { TreeItem, TreeItemCollapsibleState, Command } from "vscode";
1+
import { TreeItem, TreeItemCollapsibleState, Command, ExtensionContext } from "vscode";
22
import { join, basename } from "path";
33

44
export interface SQLTree {
@@ -19,17 +19,19 @@ export class SQLItem extends TreeItem {
1919

2020
export class DBItem extends SQLItem {
2121

22-
constructor(public dbPath: string, command?: Command) {
22+
constructor(context: ExtensionContext, public dbPath: string, command?: Command) {
2323
super(
2424
dbPath,
2525
basename(dbPath),
2626
TreeItemCollapsibleState.Collapsed,
2727
command
2828
);
2929

30+
console.log(__filename);
31+
3032
this.iconPath = {
31-
light: join(__filename, '..', '..', '..', 'resources', 'light', 'database.svg'),
32-
dark: join(__filename, '..', '..', '..', 'resources', 'dark', 'database.svg')
33+
light: context.asAbsolutePath(join('resources', 'light', 'database.svg')),
34+
dark: context.asAbsolutePath(join('resources', 'dark', 'database.svg'))
3335
};
3436

3537
this.contextValue = 'sqlite.databaseItem';
@@ -42,7 +44,7 @@ export class DBItem extends SQLItem {
4244

4345
export class TableItem extends SQLItem {
4446

45-
constructor(name: string, private type: string, command?: Command) {
47+
constructor(context: ExtensionContext, name: string, private type: string, command?: Command) {
4648
super(
4749
name,
4850
name,
@@ -56,8 +58,8 @@ export class TableItem extends SQLItem {
5658
icon_name = "table_view.svg";
5759
}
5860
this.iconPath = {
59-
light: join(__filename, '..', '..', '..', 'resources', 'light', icon_name),
60-
dark: join(__filename, '..', '..', '..', 'resources', 'dark', icon_name)
61+
light: context.asAbsolutePath(join('resources', 'light', icon_name)),
62+
dark: context.asAbsolutePath(join('resources', 'dark', icon_name))
6163
};
6264
}
6365

@@ -70,7 +72,7 @@ export class TableItem extends SQLItem {
7072

7173
export class ColumnItem extends SQLItem {
7274

73-
constructor(name:string, private type: string,
75+
constructor(context: ExtensionContext, name:string, private type: string,
7476
private notnull: boolean, private pk: number, private defVal: string, command?: Command) {
7577
super(
7678
name,
@@ -85,8 +87,8 @@ export class ColumnItem extends SQLItem {
8587
iconName = pk > 0? 'col_pk.svg' : iconName;
8688

8789
this.iconPath = {
88-
light: join(__filename, '..', '..', '..', 'resources', 'light', iconName),
89-
dark: join(__filename, '..', '..', '..', 'resources', 'dark', iconName)
90+
light: context.asAbsolutePath(join('resources', 'light', iconName)),
91+
dark: context.asAbsolutePath(join('resources', 'dark', iconName))
9092
};
9193
}
9294

src/extension.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ export function activate(context: ExtensionContext): Promise<boolean> {
6161
languageserver = new LanguageServer();
6262
sqlWorkspace = new SqlWorkspace();
6363
sqlite = new SQLite(context.extensionPath);
64-
explorer = new Explorer();
64+
explorer = new Explorer(context);
6565
resultView = new ResultView(context.extensionPath);
6666

6767
languageserver.setSchemaHandler(doc => {

src/resultview/customview.ts

+19-48
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,10 @@
11
import { WebviewPanel, window, ViewColumn, Disposable, Uri } from "vscode";
2-
import { dirname } from "path";
3-
import { readFile } from "fs";
4-
import { randomString } from "../utils/utils";
52
import { EventEmitter } from "events";
3+
import { join } from "path";
64

75
export interface Message {
8-
command: string;
9-
data: Object;
10-
id?: string;
6+
type: string;
7+
payload: any;
118
}
129

1310
export class CustomView extends EventEmitter implements Disposable {
@@ -17,28 +14,32 @@ export class CustomView extends EventEmitter implements Disposable {
1714

1815
private resourcesPath: string;
1916
private panel: WebviewPanel | undefined;
20-
private htmlCache: {[path: string]: string};
2117

2218
constructor(private type: string, private title: string) {
2319
super();
2420
this.resourcesPath = "";
25-
this.htmlCache = {};
2621
}
2722

28-
show(htmlPath: string) {
29-
this.resourcesPath = dirname(htmlPath);
23+
show(basePath: string, recordsPerPage: number) {
24+
this.resourcesPath = join(basePath, "dist");
3025

3126
if (!this.panel) {
3227
this.init();
3328
}
34-
35-
this.readWithCache(htmlPath, (html: string) => {
36-
if (this.panel) {
37-
// little hack to make the html unique so that the webview is reloaded
38-
html = html.replace(/\<\/body\>/, `<div id="${randomString(8)}"></div></body>`);
39-
this.panel.webview.html = html;
40-
}
41-
});
29+
30+
const jsPath = join(this.resourcesPath, "resultview.js");
31+
this.panel!.webview.html = `
32+
<html>
33+
<head>
34+
<title>ResultView</title>
35+
</head>
36+
<body>
37+
<div id="root"></div>
38+
<script>const RECORDS_PER_PAGE=${recordsPerPage || 20}</script>
39+
<script src="${(this.panel!.webview as any).asWebviewUri(Uri.file(jsPath)).toString()}"></script>
40+
</body>
41+
</html>
42+
`;
4243
}
4344

4445
send(message: Message) {
@@ -73,39 +74,9 @@ export class CustomView extends EventEmitter implements Disposable {
7374
subscriptions.push(this.panel.onDidDispose(() => this.dispose()));
7475

7576
subscriptions.push(this.panel.webview.onDidReceiveMessage((message: Message) => {
76-
//console.log("Received message from webview: "+JSON.stringify(message));
7777
this.handleMessage(message);
7878
}));
7979

8080
this.disposable = Disposable.from(...subscriptions);
8181
}
82-
83-
private readWithCache(path: string, callback: (html: string) => void) {
84-
let html: string = '';
85-
if (path in this.htmlCache) {
86-
html = this.htmlCache[path];
87-
callback(html);
88-
} else {
89-
readFile(path, 'utf8', (err, content) => {
90-
html = content || "";
91-
html = this.replaceUris(html, path);
92-
this.htmlCache[path] = html;
93-
callback(html);
94-
});
95-
}
96-
}
97-
98-
private replaceUris(html: string, htmlPath: string) {
99-
if (!this.panel) return html;
100-
101-
let basePath = Uri.file(dirname(htmlPath)).with({scheme: this.resourceScheme}).toString();
102-
try {
103-
basePath = (this.panel.webview as any).asWebviewUri(Uri.file(dirname(htmlPath))).toString();
104-
} catch(err) {
105-
// Note: This is a relly bad way to assign base path but for now it will do
106-
}
107-
let regex = /(href|src)\=\"(.+?)\"/g;
108-
html = html.replace(regex, `$1="${basePath+'$2'}"`);
109-
return html;
110-
}
11182
}

0 commit comments

Comments
 (0)