Skip to content

Commit 71ffb6a

Browse files
authored
Merge pull request #1530 from finos/correct-types
Use TypeScript for `@finos/perspective-viewer`
2 parents 9a0427a + f7f6097 commit 71ffb6a

27 files changed

+1584
-1388
lines changed

examples/react/package.json

+1-2
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@
2222
"@types/react": "^16.8.6",
2323
"@types/react-dom": "^16.9.4",
2424
"source-map-loader": "^0.2.4",
25-
"ts-loader": "^6.2.1",
26-
"typescript": "^3.7.4"
25+
"ts-loader": "^6.2.1"
2726
}
2827
}

examples/react/src/index.css

+4-2
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,14 @@
66
* the Apache License 2.0. The full license can be found in the LICENSE file.
77
*
88
*/
9+
10+
@import "~@finos/perspective-viewer/dist/umd/material-dense.css";
911

10-
perspective-viewer {
12+
perspective-viewer {
1113
position: absolute;
1214
top: 0;
1315
left: 0;
1416
right: 0;
1517
bottom: 0;
16-
}
18+
}
1719

examples/react/src/index.tsx

+13-13
Original file line numberDiff line numberDiff line change
@@ -9,43 +9,43 @@
99

1010
import * as React from "react";
1111
import * as ReactDOM from "react-dom";
12-
import {useEffect, useRef} from "react";
13-
import perspective, {Table} from "@finos/perspective";
12+
import * as perspective from "@finos/perspective";
13+
1414
import "@finos/perspective-viewer";
1515
import "@finos/perspective-viewer-datagrid";
1616
import "@finos/perspective-viewer-d3fc";
17+
import {PerspectiveViewerConfig, PerspectiveViewerElement} from "@finos/perspective-viewer";
18+
1719
import "./index.css";
18-
import "@finos/perspective-viewer/dist/umd/material.css";
19-
import {HTMLPerspectiveViewerElement, PerspectiveViewerOptions} from "@finos/perspective-viewer";
2020

21-
const worker = perspective.shared_worker();
21+
const worker = perspective.default.shared_worker();
2222

23-
const getTable = async (): Promise<Table> => {
23+
const getTable = async (): Promise<perspective.Table> => {
2424
const req = fetch("./superstore.arrow");
2525
const resp = await req;
2626
const buffer = await resp.arrayBuffer();
2727
return await worker.table(buffer as any);
2828
};
2929

30-
const config: PerspectiveViewerOptions = {
31-
"row-pivots": ["State"]
30+
const config: PerspectiveViewerConfig = {
31+
row_pivots: ["State"]
3232
};
3333

3434
const App = (): React.ReactElement => {
35-
const viewer = useRef<HTMLPerspectiveViewerElement>(null);
35+
const viewer = React.useRef<PerspectiveViewerElement>(null);
3636

37-
useEffect(() => {
37+
React.useEffect(() => {
3838
getTable().then(table => {
3939
if (viewer.current) {
40-
viewer.current.load(table);
40+
viewer.current.load(Promise.resolve(table));
4141
viewer.current.restore(config);
4242
}
4343
});
4444
}, []);
4545

46-
// You can also the use the stringified config values as attributes
47-
return <perspective-viewer ref={viewer} /*row-pivots='["State"]'*/></perspective-viewer>;
46+
return <perspective-viewer ref={viewer}></perspective-viewer>;
4847
};
48+
4949
window.addEventListener("load", () => {
5050
ReactDOM.render(<App />, document.getElementById("root"));
5151
});

examples/react/webpack.config.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -35,12 +35,12 @@ module.exports = {
3535
},
3636
{
3737
test: /\.css$/,
38+
exclude: /node_modules/,
3839
use: [{loader: "style-loader"}, {loader: "css-loader"}]
3940
}
4041
]
4142
},
4243
devServer: {
43-
// superstore.arrow is served from here
4444
contentBase: [path.join(__dirname, "dist"), path.join(__dirname, "../../node_modules/superstore-arrow")]
4545
}
4646
};

package.json

+5-5
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
"@babel/preset-env": "^7.8.4",
3333
"@rollup/plugin-babel": "^5.2.3",
3434
"@rollup/plugin-node-resolve": "^11.1.1",
35+
"@rollup/plugin-typescript": "^8.2.5",
3536
"@types/ws": "^7.2.2",
3637
"@typescript-eslint/eslint-plugin": "^2.4.0",
3738
"@typescript-eslint/parser": "^2.4.0",
@@ -72,11 +73,7 @@
7273
"npm-pack-here": "^1.2.0",
7374
"npm-run-all": "^4.1.3",
7475
"postcss": "^8.2.6",
75-
"postcss-copy-assets": "^0.3.1",
76-
"postcss-easy-import": "^3.0.0",
77-
"postcss-font-grabber": "^3.0.2",
7876
"postcss-loader": "^4.1.0",
79-
"postcss-url": "^10.1.3",
8077
"pre-commit": "^1.2.2",
8178
"prettier": "^1.19.1",
8279
"puppeteer": "^10.2.0",
@@ -91,7 +88,10 @@
9188
"term-img": "^4.1.0",
9289
"ts-jest": "^25.1.0",
9390
"ts-loader": "^6.2.0",
94-
"typescript": "^3.7.4",
91+
"typedoc": "^0.21.9",
92+
"typedoc-plugin-markdown": "^3.10.4",
93+
"typedoc-plugin-no-inherit": "^1.3.0",
94+
"typescript": "4.3.3",
9595
"webfontloader": "^1.6.28",
9696
"webpack": "^5.14.0",
9797
"webpack-cli": "^4.3.1",

packages/perspective-jupyterlab/package.json

+1-2
Original file line numberDiff line numberDiff line change
@@ -53,8 +53,7 @@
5353
"isomorphic-fetch": "^2.2.1",
5454
"jest-transform-css": "^2.0.0",
5555
"source-map-support": "^0.5.9",
56-
"ts-jest": "^25.1.0",
57-
"typescript": "^3.7.4"
56+
"ts-jest": "^25.1.0"
5857
},
5958
"jupyterlab": {
6059
"extension": true

packages/perspective-jupyterlab/src/ts/psp_widget.ts

+33-34
Original file line numberDiff line numberDiff line change
@@ -9,16 +9,16 @@
99

1010
import "@finos/perspective-viewer";
1111

12-
import {Table, TableData} from "@finos/perspective";
12+
import {Table, TableData, Aggregate, Sort, Expression, Filter, ColumnName} from "@finos/perspective";
1313
import {Message} from "@lumino/messaging";
1414
import {Widget} from "@lumino/widgets";
1515
import {MIME_TYPE, PSP_CLASS, PSP_CONTAINER_CLASS, PSP_CONTAINER_CLASS_DARK} from "./utils";
1616

17-
import {HTMLPerspectiveViewerElement, Pivots, Aggregates, Sort, Expressions, PerspectiveViewerOptions, Filters, Columns} from "@finos/perspective-viewer";
17+
import {PerspectiveViewerElement, PerspectiveViewerConfig} from "@finos/perspective-viewer";
1818

1919
let _increment = 0;
2020

21-
export interface PerspectiveWidgetOptions extends PerspectiveViewerOptions {
21+
export interface PerspectiveWidgetOptions extends PerspectiveViewerConfig {
2222
dark?: boolean;
2323
client?: boolean;
2424
server?: boolean;
@@ -27,9 +27,9 @@ export interface PerspectiveWidgetOptions extends PerspectiveViewerOptions {
2727

2828
// these shouldn't exist, PerspectiveViewerOptions should be sufficient e.g.
2929
// ["row-pivots"]
30-
column_pivots?: Pivots;
31-
row_pivots?: Pivots;
32-
expressions?: Expressions;
30+
column_pivots?: Array<ColumnName>;
31+
row_pivots?: Array<ColumnName>;
32+
expressions?: Array<Expression>;
3333
editable?: boolean;
3434
}
3535

@@ -56,21 +56,21 @@ export class PerspectiveWidget extends Widget {
5656
*
5757
* @param options
5858
*/
59-
_set_attributes(options: PerspectiveViewerOptions & PerspectiveWidgetOptions): void {
59+
_set_attributes(options: PerspectiveViewerConfig & PerspectiveWidgetOptions): void {
6060
const plugin: string = options.plugin || "datagrid";
61-
const columns: Columns = options.columns || [];
62-
const row_pivots: Pivots = options.row_pivots || options.row_pivots || [];
63-
const column_pivots: Pivots = options.column_pivots || options.column_pivots || [];
64-
const aggregates: Aggregates = options.aggregates || {};
65-
const sort: Sort = options.sort || [];
66-
const filter: Filters = options.filter || [];
67-
const expressions: Expressions = options.expressions || options.expressions || [];
61+
const columns: ColumnName[] = options.columns || [];
62+
const row_pivots: ColumnName[] = options.row_pivots || options.row_pivots || [];
63+
const column_pivots: ColumnName[] = options.column_pivots || options.column_pivots || [];
64+
const aggregates: {[column: string]: Aggregate} = options.aggregates || {};
65+
const sort: Sort[] = options.sort || [];
66+
const filter: Filter[] = options.filter || [];
67+
const expressions: Expression[] = options.expressions || options.expressions || [];
6868
const plugin_config: object = options.plugin_config || {};
6969
const dark: boolean = options.dark || false;
7070
const editable: boolean = options.editable || false;
7171
const server: boolean = options.server || false;
7272
const client: boolean = options.client || false;
73-
const selectable: boolean = options.selectable || false;
73+
// const selectable: boolean = options.selectable || false;
7474

7575
this.server = server;
7676
this.client = client;
@@ -89,7 +89,7 @@ export class PerspectiveWidget extends Widget {
8989
};
9090

9191
// this.plugin_config = plugin_config;
92-
this.selectable = selectable;
92+
// this.selectable = selectable;
9393
}
9494

9595
/**********************/
@@ -122,22 +122,18 @@ export class PerspectiveWidget extends Widget {
122122
}
123123

124124
async notifyResize(): Promise<void> {
125-
if (this.isVisible) {
126-
await this.viewer.notifyResize();
127-
}
125+
await this.viewer.notifyResize();
128126
}
129127

130128
async toggleConfig(): Promise<void> {
131-
if (this.isVisible) {
132-
await this.viewer.toggleConfig();
133-
}
129+
await this.viewer.toggleConfig();
134130
}
135131

136-
async save(): Promise<PerspectiveViewerOptions> {
132+
async save(): Promise<PerspectiveViewerConfig> {
137133
return await this.viewer.save();
138134
}
139135

140-
async restore(config: PerspectiveViewerOptions): Promise<void> {
136+
async restore(config: PerspectiveViewerConfig): Promise<void> {
141137
return await this.viewer.restore(config);
142138
}
143139

@@ -156,15 +152,17 @@ export class PerspectiveWidget extends Widget {
156152
*
157153
* @param data
158154
*/
159-
_update(data: TableData): void {
160-
this.viewer.table.update(data);
155+
async _update(data: TableData): Promise<void> {
156+
const table = await this.viewer.getTable();
157+
await table.update(data);
161158
}
162159

163160
/**
164161
* Removes all rows from the viewer's table. Does not reset viewer state.
165162
*/
166163
async clear(): Promise<void> {
167-
await this.viewer.table.clear();
164+
const table = await this.viewer.getTable();
165+
await table.clear();
168166
}
169167

170168
/**
@@ -174,7 +172,8 @@ export class PerspectiveWidget extends Widget {
174172
* @param data
175173
*/
176174
async replace(data: TableData): Promise<void> {
177-
await this.viewer.table.replace(data);
175+
const table = await this.viewer.getTable();
176+
await table.replace(data);
178177
}
179178

180179
/**
@@ -194,8 +193,8 @@ export class PerspectiveWidget extends Widget {
194193
return await this.viewer.getEditPort();
195194
}
196195

197-
get table(): Table {
198-
return this.viewer.table;
196+
async getTable(): Promise<Table> {
197+
return await this.viewer.getTable();
199198
}
200199

201200
/***************************************************************************
@@ -209,7 +208,7 @@ export class PerspectiveWidget extends Widget {
209208
*
210209
* @returns {PerspectiveViewer} The widget's viewer instance.
211210
*/
212-
get viewer(): HTMLPerspectiveViewerElement {
211+
get viewer(): PerspectiveViewerElement {
213212
return this._viewer;
214213
}
215214

@@ -306,7 +305,7 @@ export class PerspectiveWidget extends Widget {
306305
}
307306
}
308307

309-
static createNode(node: HTMLDivElement): HTMLPerspectiveViewerElement {
308+
static createNode(node: HTMLDivElement): PerspectiveViewerElement {
310309
node.classList.add("p-Widget");
311310
node.classList.add(PSP_CONTAINER_CLASS);
312311
const viewer = document.createElement("perspective-viewer");
@@ -342,11 +341,11 @@ export class PerspectiveWidget extends Widget {
342341
return viewer;
343342
}
344343

345-
private _viewer: HTMLPerspectiveViewerElement;
344+
private _viewer: PerspectiveViewerElement;
346345
private _plugin_config: object;
347346
private _client: boolean;
348347
private _server: boolean;
349348
private _dark: boolean;
350349
private _editable: boolean;
351-
private _viewer_config: PerspectiveViewerOptions;
350+
private _viewer_config: PerspectiveViewerConfig;
352351
}

packages/perspective-jupyterlab/src/ts/renderer.ts

+5-5
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,10 @@ export class PerspectiveDocumentWidget extends DocumentWidget<PerspectiveWidget>
8383
throw "Not handled";
8484
}
8585

86-
if (this._psp.viewer.table === undefined) {
86+
try {
87+
const table = await this._psp.viewer.getTable();
88+
table.replace(data);
89+
} catch (e) {
8790
// construct new table
8891
const table_promise = WORKER.table(data);
8992

@@ -109,10 +112,7 @@ export class PerspectiveDocumentWidget extends DocumentWidget<PerspectiveWidget>
109112
this.context.model.fromJSON(result);
110113
this.context.save();
111114
}
112-
});
113-
} else {
114-
// replace existing table for whatever reason
115-
this._psp.replace(data);
115+
});
116116
}
117117
} catch (e) {
118118
baddialog();

packages/perspective-jupyterlab/src/ts/widget.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
import {Message} from "@lumino/messaging";
1111
import {DOMWidgetView} from "@jupyter-widgets/base";
1212

13-
import {PerspectiveViewerOptions} from "@finos/perspective-viewer";
13+
import {PerspectiveViewerConfig} from "@finos/perspective-viewer";
1414
import {PerspectiveWidget, PerspectiveWidgetOptions} from "./psp_widget";
1515

1616
export type PerspectiveJupyterWidgetOptions = {
@@ -21,7 +21,7 @@ export type PerspectiveJupyterWidgetOptions = {
2121
* PerspectiveJupyterWidget is the ipywidgets front-end for the Perspective Jupyterlab plugin.
2222
*/
2323
export class PerspectiveJupyterWidget extends PerspectiveWidget {
24-
constructor(name = "Perspective", options: PerspectiveViewerOptions & PerspectiveJupyterWidgetOptions & PerspectiveWidgetOptions) {
24+
constructor(name = "Perspective", options: PerspectiveViewerConfig & PerspectiveJupyterWidgetOptions & PerspectiveWidgetOptions) {
2525
const view = options.view;
2626
delete options.view;
2727
super(name, options);

0 commit comments

Comments
 (0)