Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions packages/chart/src/LazyChart.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { LoadingOverlay } from '@deephaven/components';
import { lazy, Suspense } from 'react';

const Chart = lazy(() => import('./Chart.js'));
Comment thread
mofojed marked this conversation as resolved.

function LazyChart(props: React.ComponentProps<typeof Chart>): JSX.Element {
return (
<Suspense fallback={<LoadingOverlay />}>
{/* eslint-disable-next-line react/jsx-props-no-spreading */}
<Chart {...props} />
</Suspense>
);
}

export default LazyChart;
4 changes: 2 additions & 2 deletions packages/chart/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
export { default as Chart } from './Chart';
export { default as Chart } from './LazyChart';
export { default as ChartModelFactory } from './ChartModelFactory';
export { default as ChartModel } from './ChartModel';
export { default as ChartUtils } from './ChartUtils';
export * from './ChartUtils';
export * from './DownsamplingError';
export { default as FigureChartModel } from './FigureChartModel';
export { default as MockChartModel } from './MockChartModel';
export { default as Plot } from './plotly/Plot';
export { default as Plot } from './plotly/LazyPlot';
Comment thread
bmingles marked this conversation as resolved.
export * from './ChartTheme';
export * from './ChartThemeProvider';
export { default as isFigureChartModel } from './isFigureChartModel';
Expand Down
15 changes: 15 additions & 0 deletions packages/chart/src/plotly/LazyPlot.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { LoadingOverlay } from '@deephaven/components';
import { lazy, Suspense } from 'react';

const PlotBase = lazy(() => import('./Plot.js'));

function Plot(props: React.ComponentProps<typeof PlotBase>): JSX.Element {
return (
<Suspense fallback={<LoadingOverlay />}>
{/* eslint-disable react/jsx-props-no-spreading */}
<PlotBase {...props} />
</Suspense>
);
}

export default Plot;
3 changes: 3 additions & 0 deletions packages/code-studio/vite.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,9 @@ export default defineConfig(({ mode }) => {
if (id.includes('plotly.js')) {
return 'plotly';
}
if (id.includes('mathjax')) {
return 'mathjax';
}
return 'vendor';
}
},
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
/* stylelint-disable custom-property-empty-line-before */
/* stylelint-disable alpha-value-notation */
.dh-spectrum-alias {

/**
* Intentionally using the classname twice so we have higher specificity than spectrum's definitions
* This is to ensure that our overrides are applied regardless of CSS chunk loading order
*/
.dh-spectrum-alias.dh-spectrum-alias {
/*********** Override variables in spectrum-global.css **********************/
--spectrum-alias-background-color-default: var(--dh-color-bg);
--spectrum-alias-background-color-disabled: var(--dh-color-disabled-bg);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
.dh-spectrum-palette {
/**
* Intentionally using the classname twice so we have higher specificity than spectrum's definitions
* This is to ensure that our overrides are applied regardless of CSS chunk loading order
*/
.dh-spectrum-palette.dh-spectrum-palette {
/* Gray */
--spectrum-gray-50: var(--dh-color-gray-50);
--spectrum-gray-75: var(--dh-color-gray-75);
Expand Down
2 changes: 1 addition & 1 deletion packages/console/src/notebook/ScriptEditor.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { LoadingOverlay, ShortcutRegistry } from '@deephaven/components';
import Log from '@deephaven/log';
import type { IdeSession } from '@deephaven/jsapi-types';
import { assertNotNull } from '@deephaven/utils';
import { editor, IDisposable } from 'monaco-editor';
import type { editor, IDisposable } from 'monaco-editor';
import Editor from './Editor';
import { MonacoProviders, MonacoUtils } from '../monaco';
import './ScriptEditor.scss';
Expand Down
3 changes: 2 additions & 1 deletion packages/dashboard-core-plugins/src/panels/IrisGridPanel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import {
import {
AdvancedSettings,
IrisGrid,
type IrisGridType,
IrisGridModel,
IrisGridUtils,
isIrisGridTableModelTemplate,
Expand Down Expand Up @@ -362,7 +363,7 @@ export class IrisGridPanel extends PureComponent<
}
}

irisGrid: RefObject<IrisGrid>;
irisGrid: RefObject<IrisGridType>;

pluginRef: RefObject<TablePluginElement>;

Expand Down
2 changes: 1 addition & 1 deletion packages/iris-grid/src/IrisGrid.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import dh from '@deephaven/jsapi-shim';
import { DateUtils, Settings } from '@deephaven/jsapi-utils';
import { TestUtils } from '@deephaven/utils';
import { TypeValue } from '@deephaven/filters';
import { IrisGrid } from './IrisGrid';
import IrisGrid from './IrisGrid';
import IrisGridTestUtils from './IrisGridTestUtils';

class MockPath2D {
Expand Down
3 changes: 2 additions & 1 deletion packages/iris-grid/src/IrisGrid.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -249,6 +249,7 @@ function isEmptyConfig({
sorts.length === 0
);
}

export type FilterData = {
operator: FilterTypeValue;
text: string;
Expand Down Expand Up @@ -451,7 +452,7 @@ export interface IrisGridState {
columnHeaderGroups: readonly ColumnHeaderGroup[];
}

export class IrisGrid extends Component<IrisGridProps, IrisGridState> {
class IrisGrid extends Component<IrisGridProps, IrisGridState> {
Comment thread
bmingles marked this conversation as resolved.
static contextType = IrisGridThemeContext;

static minDebounce = 150;
Expand Down
2 changes: 1 addition & 1 deletion packages/iris-grid/src/IrisGridCellOverflowModal.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import React, { useEffect, useRef, useState } from 'react';
import { Editor } from '@deephaven/console';
import * as monaco from 'monaco-editor';
import type * as monaco from 'monaco-editor';
import {
Button,
CopyButton,
Expand Down
26 changes: 26 additions & 0 deletions packages/iris-grid/src/LazyIrisGrid.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import { forwardRef, lazy, Suspense } from 'react';
import { LoadingOverlay } from '@deephaven/components';
import type IrisGridType from './IrisGrid';
import type { IrisGridProps } from './IrisGrid';

const IrisGrid = lazy(() => import('./IrisGrid.js'));

const LazyIrisGrid = forwardRef<
IrisGridType,
JSX.LibraryManagedAttributes<typeof IrisGridType, IrisGridProps>
>(
(
// This creates the correct type to make defaultProps optional
props,
ref
): JSX.Element => (
<Suspense fallback={<LoadingOverlay />}>
{/* eslint-disable-next-line react/jsx-props-no-spreading */}
<IrisGrid ref={ref} {...props} />
</Suspense>
)
);

LazyIrisGrid.displayName = 'LazyIrisGrid';

export default LazyIrisGrid;
3 changes: 2 additions & 1 deletion packages/iris-grid/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import IrisGrid from './IrisGrid';
import IrisGrid from './LazyIrisGrid';

export default IrisGrid;
export { IrisGrid };
Expand All @@ -8,6 +8,7 @@ export * from './CommonTypes';
export { default as ColumnHeaderGroup } from './ColumnHeaderGroup';
export * from './PartitionedGridModel';
export * from './IrisGrid';
export type { default as IrisGridType } from './IrisGrid';
export { default as SHORTCUTS } from './IrisGridShortcuts';
export { default as IrisGridModel } from './IrisGridModel';
export { default as IrisGridTableModel } from './IrisGridTableModel';
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { KeyboardEvent } from 'react';
import { KeyHandler } from '@deephaven/grid';
import { IrisGrid } from '../IrisGrid';
import type IrisGrid from '../IrisGrid';
import IrisGridShortcuts from '../IrisGridShortcuts';

class ClearFilterKeyHandler extends KeyHandler {
Expand Down
2 changes: 1 addition & 1 deletion packages/iris-grid/src/key-handlers/CopyCellKeyHandler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { KeyboardEvent } from 'react';
import { KeyHandler } from '@deephaven/grid';
import { ContextActionUtils } from '@deephaven/components';
import type { Grid } from '@deephaven/grid';
import { IrisGrid } from '../IrisGrid';
import type IrisGrid from '../IrisGrid';

class CopyCellKeyHandler extends KeyHandler {
private irisGrid: IrisGrid;
Expand Down
2 changes: 1 addition & 1 deletion packages/iris-grid/src/key-handlers/CopyKeyHandler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
import { KeyboardEvent } from 'react';
import { ContextActionUtils } from '@deephaven/components';
import { KeyHandler } from '@deephaven/grid';
import { IrisGrid } from '../IrisGrid';
import type IrisGrid from '../IrisGrid';
import IrisGridUtils from '../IrisGridUtils';

class CopyKeyHandler extends KeyHandler {
Expand Down
2 changes: 1 addition & 1 deletion packages/iris-grid/src/key-handlers/ReverseKeyHandler.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { KeyboardEvent } from 'react';
import { KeyHandler } from '@deephaven/grid';
import { TableUtils } from '@deephaven/jsapi-utils';
import { IrisGrid } from '../IrisGrid';
import type IrisGrid from '../IrisGrid';
import IrisGridShortcuts from '../IrisGridShortcuts';

class ReverseKeyHandler extends KeyHandler {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import {
EventHandlerResult,
} from '@deephaven/grid';
import type { Column } from '@deephaven/jsapi-types';
import { IrisGrid } from '../IrisGrid';
import type IrisGrid from '../IrisGrid';
import { DisplayColumn } from '../IrisGridModel';

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import {
Grid,
GridMouseEvent,
} from '@deephaven/grid';
import type { IrisGrid } from '../IrisGrid';
import type IrisGrid from '../IrisGrid';

/**
* Detects mouse hover over column headers and displays the appropriate tooltip
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import {
GridPoint,
EventHandlerResult,
} from '@deephaven/grid';
import type { IrisGrid } from '../IrisGrid';
import type IrisGrid from '../IrisGrid';

/**
* Handles sending data selected via double click
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import {
GridPoint,
EventHandlerResult,
} from '@deephaven/grid';
import type { IrisGrid } from '../IrisGrid';
import type IrisGrid from '../IrisGrid';

/**
* Trigger quick filters and advanced filters
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import {
GridRangeIndex,
EventHandlerResult,
} from '@deephaven/grid';
import type { IrisGrid } from '../IrisGrid';
import type IrisGrid from '../IrisGrid';

/**
* Used to handle sorting on column header clicks
Expand Down
70 changes: 70 additions & 0 deletions tests/lazy-loading.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
import { test, expect, Request } from '@playwright/test';
import { openPlot } from './utils';

/**
* Checks the size of the response body of a request
* If the response body size is 0, the request is not checked
* This seems to happen for Safari sometimes
*
* @param request The request object. Playwright provides size on the request, not the response
* @param size The minimum size in bytes
*/
async function expectMinimumResponseSize(
request: Request | undefined,
size: number
) {
if (!request) {
throw new Error('Request is undefined');
}

const responseSize = (await request.sizes()).responseBodySize;

// Safari doesn't seem to provide response size for some requests
if (responseSize > 0) {
expect(responseSize).toBeGreaterThan(size);
}
}

test('lazy loads plotly', async ({ page }) => {
const requests: Request[] = [];
page.on('request', req => requests.push(req));

await page.goto('');
await page.waitForLoadState('networkidle');

expect(requests.some(req => req.url().includes('assets/plotly'))).toBe(false);

await openPlot(page, 'simple_plot');

const plotlyRequest = requests.find(req =>
req.url().includes('assets/plotly')
);
expect(plotlyRequest).toBeDefined();
await expectMinimumResponseSize(plotlyRequest, 300 * 1000); // 300kB
});

test('lazy loads mathjax', async ({ page }) => {
const requests: Request[] = [];
page.on('request', req => requests.push(req));

await page.goto('');
await page.waitForLoadState('networkidle');

expect(requests.some(req => req.url().includes('assets/mathjax'))).toBe(
false
);

const controlsButton = page.getByText('Controls');
await controlsButton.click();
const markdownButton = page.getByText('Markdown Widget');
await markdownButton.click();

await expect(page.locator('.markdown-panel')).toBeVisible();
await expect(page.locator('.markdown-panel .loading-spinner')).toHaveCount(0);

const mathjaxRequest = requests.find(req =>
req.url().includes('assets/mathjax')
);
expect(mathjaxRequest).toBeDefined();
await expectMinimumResponseSize(mathjaxRequest, 500 * 1000); // 500kB
});
4 changes: 4 additions & 0 deletions tests/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -107,9 +107,13 @@ export async function openPlot(

if (waitForLoadFinished) {
// Wait until it's done loading
await expect(page.locator('.chart-panel-container')).toHaveCount(1);
await expect(
page.locator('.chart-panel-container .loading-spinner')
).toHaveCount(0);
await expect(
page.locator('.chart-panel-container .chart-wrapper')
).toHaveCount(1);
}
}

Expand Down