mirror of
https://github.com/qlik-oss/nebula.js.git
synced 2025-12-19 17:58:43 -05:00
feat: add more correct onRender callback for sheets (#1681)
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
import React, { useEffect, useState, useContext, useMemo, forwardRef, useImperativeHandle } from 'react';
|
||||
import React, { useEffect, useState, useContext, useMemo, forwardRef, useImperativeHandle, useRef } from 'react';
|
||||
import useLayout from '../hooks/useLayout';
|
||||
import getObject from '../object/get-object';
|
||||
import Cell from './Cell';
|
||||
@@ -17,7 +17,7 @@ const SheetElement = {
|
||||
className: 'njs-sheet',
|
||||
};
|
||||
|
||||
function getCellRenderer(cell, halo, initialSnOptions, initialSnPlugins, initialError, onMount, navigation) {
|
||||
function getCellRenderer(cell, halo, initialSnOptions, initialSnPlugins, initialError, onMount, navigation, onError) {
|
||||
const { x, y, width, height } = cell.bounds;
|
||||
return (
|
||||
<div
|
||||
@@ -34,6 +34,7 @@ function getCellRenderer(cell, halo, initialSnOptions, initialSnPlugins, initial
|
||||
initialError={initialError}
|
||||
onMount={onMount}
|
||||
navigation={navigation}
|
||||
onError={onError}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
@@ -53,7 +54,17 @@ function getBounds(pos, columns, rows) {
|
||||
|
||||
const Sheet = forwardRef(
|
||||
(
|
||||
{ model: inputModel, halo, initialSnOptions, initialSnPlugins, initialError, onMount, unmount, navigation },
|
||||
{
|
||||
model: inputModel,
|
||||
halo,
|
||||
initialSnOptions,
|
||||
initialSnPlugins,
|
||||
initialError,
|
||||
onMount,
|
||||
unmount,
|
||||
navigation,
|
||||
onError,
|
||||
},
|
||||
ref
|
||||
) => {
|
||||
const { root } = halo;
|
||||
@@ -64,6 +75,8 @@ const Sheet = forwardRef(
|
||||
const [bgColor, setBgColor] = useState(undefined);
|
||||
const [bgImage, setBgImage] = useState(undefined);
|
||||
const [deepHash, setDeepHash] = useState('');
|
||||
const renderState = useRef({ cellCount: 0, cellsRendered: 0, initialRender: false });
|
||||
|
||||
navigation?.setCurrentSheetId?.(model.id);
|
||||
/// For each object
|
||||
useEffect(() => {
|
||||
@@ -85,6 +98,17 @@ const Sheet = forwardRef(
|
||||
});
|
||||
|
||||
const lCells = layout.cells;
|
||||
renderState.cellCount = lCells.length;
|
||||
renderState.cellsRendered = 0;
|
||||
|
||||
const renderCallback = () => {
|
||||
renderState.cellsRendered++;
|
||||
if (renderState.cellsRendered === renderState.cellCount && !renderState.initialRender) {
|
||||
renderState.initialRender = true;
|
||||
initialSnOptions.onInitialRender();
|
||||
}
|
||||
};
|
||||
|
||||
const { columns, rows } = layout;
|
||||
// TODO - should try reuse existing objects on subsequent renders
|
||||
// Non-id updates should only change the "css"
|
||||
@@ -110,6 +134,12 @@ const Sheet = forwardRef(
|
||||
currentId: uid(),
|
||||
mounted,
|
||||
mountedPromise,
|
||||
options: {
|
||||
...initialSnOptions,
|
||||
...{
|
||||
onInitialRender: renderCallback,
|
||||
},
|
||||
},
|
||||
};
|
||||
})
|
||||
);
|
||||
@@ -133,7 +163,7 @@ const Sheet = forwardRef(
|
||||
() =>
|
||||
cells
|
||||
? cells.map((c) =>
|
||||
getCellRenderer(c, halo, initialSnOptions, initialSnPlugins, initialError, c.mounted, navigation)
|
||||
getCellRenderer(c, halo, c.options, initialSnPlugins, initialError, c.mounted, navigation, onError)
|
||||
)
|
||||
: [],
|
||||
[cells]
|
||||
|
||||
@@ -11,6 +11,7 @@ export default function glue({
|
||||
onMount,
|
||||
initialError,
|
||||
navigation,
|
||||
onError,
|
||||
}) {
|
||||
const { root } = halo;
|
||||
const sheetRef = React.createRef();
|
||||
@@ -29,6 +30,7 @@ export default function glue({
|
||||
onMount={onMount}
|
||||
unmount={unmount}
|
||||
navigation={navigation}
|
||||
onError={onError}
|
||||
/>,
|
||||
element,
|
||||
model.id
|
||||
|
||||
@@ -19,7 +19,7 @@ export default async function getObject(
|
||||
const navigation =
|
||||
inputNavigation || (model.genericType === 'sheet' ? createNavigationApi(halo, store, model) : undefined);
|
||||
if (model.genericType === 'sheet') {
|
||||
return initSheet(model, { options, plugins, element }, halo, navigation);
|
||||
return initSheet(model, { options, plugins, element, onRender, onError }, halo, navigation);
|
||||
}
|
||||
|
||||
return init(model, { options, plugins, element, onRender, onError }, halo, navigation);
|
||||
|
||||
@@ -2,12 +2,15 @@
|
||||
import sheetAPI from '../sheet';
|
||||
|
||||
export default async function initSheet(model, optional, halo, navigation, initialError, onDestroy = async () => {}) {
|
||||
const { onRender, onError } = optional;
|
||||
const api = sheetAPI({
|
||||
model,
|
||||
halo,
|
||||
navigation,
|
||||
initialError,
|
||||
onDestroy,
|
||||
onRender,
|
||||
onError,
|
||||
});
|
||||
if (optional.options) {
|
||||
api.__DO_NOT_USE__.options(optional.options);
|
||||
|
||||
@@ -5,25 +5,49 @@ import getPatches from './utils/patcher';
|
||||
|
||||
const noopi = () => {};
|
||||
|
||||
export default function sheet({ model, halo, navigation, initialError, onDestroy = async () => {} } = {}) {
|
||||
export default function sheet({
|
||||
model,
|
||||
halo,
|
||||
navigation,
|
||||
initialError,
|
||||
onDestroy = async () => {},
|
||||
onRender = () => {},
|
||||
onError = () => {},
|
||||
} = {}) {
|
||||
let unmountSheet = noopi;
|
||||
let sheetRef = null;
|
||||
let mountedReference = null;
|
||||
let onMount = null;
|
||||
let onRenderResolve = null;
|
||||
|
||||
const mounted = new Promise((resolve) => {
|
||||
onMount = resolve;
|
||||
});
|
||||
|
||||
const rendered = new Promise((resolve) => {
|
||||
onRenderResolve = resolve;
|
||||
});
|
||||
|
||||
const createOnInitialRender = (override) => () => {
|
||||
override?.(); // from options.onInitialRender
|
||||
onRenderResolve(); // internal promise in viz to wait for render
|
||||
onRender(); // from RenderConfig
|
||||
};
|
||||
|
||||
let initialSnOptions = {};
|
||||
let initialSnPlugins = [];
|
||||
|
||||
const setSnOptions = async (opts) => {
|
||||
const override = opts.onInitialRender;
|
||||
if (mountedReference) {
|
||||
(async () => {
|
||||
await mounted;
|
||||
sheetRef.current.setSnOptions({
|
||||
...initialSnOptions,
|
||||
...opts,
|
||||
...{
|
||||
onInitialRender: createOnInitialRender(override),
|
||||
},
|
||||
});
|
||||
})();
|
||||
} else {
|
||||
@@ -31,6 +55,9 @@ export default function sheet({ model, halo, navigation, initialError, onDestroy
|
||||
initialSnOptions = {
|
||||
...initialSnOptions,
|
||||
...opts,
|
||||
...{
|
||||
onInitialRender: createOnInitialRender(override),
|
||||
},
|
||||
};
|
||||
}
|
||||
};
|
||||
@@ -79,6 +106,15 @@ export default function sheet({ model, halo, navigation, initialError, onDestroy
|
||||
* @type {Navigation}
|
||||
*/
|
||||
navigation,
|
||||
/**
|
||||
* Gets the specific api that a Viz exposes.
|
||||
* @private currently empty and private
|
||||
* @returns {Promise<object>} object that contains the internal Viz api.
|
||||
*/
|
||||
async getImperativeHandle() {
|
||||
await rendered;
|
||||
return sheetRef.current.getImperativeHandle();
|
||||
},
|
||||
/**
|
||||
* Destroys the sheet and removes it from the the DOM.
|
||||
* @example
|
||||
@@ -112,6 +148,7 @@ export default function sheet({ model, halo, navigation, initialError, onDestroy
|
||||
initialError,
|
||||
onMount,
|
||||
navigation,
|
||||
onError,
|
||||
});
|
||||
return mounted;
|
||||
},
|
||||
|
||||
@@ -189,4 +189,4 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user