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 useLayout from '../hooks/useLayout';
|
||||||
import getObject from '../object/get-object';
|
import getObject from '../object/get-object';
|
||||||
import Cell from './Cell';
|
import Cell from './Cell';
|
||||||
@@ -17,7 +17,7 @@ const SheetElement = {
|
|||||||
className: 'njs-sheet',
|
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;
|
const { x, y, width, height } = cell.bounds;
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
@@ -34,6 +34,7 @@ function getCellRenderer(cell, halo, initialSnOptions, initialSnPlugins, initial
|
|||||||
initialError={initialError}
|
initialError={initialError}
|
||||||
onMount={onMount}
|
onMount={onMount}
|
||||||
navigation={navigation}
|
navigation={navigation}
|
||||||
|
onError={onError}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
@@ -53,7 +54,17 @@ function getBounds(pos, columns, rows) {
|
|||||||
|
|
||||||
const Sheet = forwardRef(
|
const Sheet = forwardRef(
|
||||||
(
|
(
|
||||||
{ model: inputModel, halo, initialSnOptions, initialSnPlugins, initialError, onMount, unmount, navigation },
|
{
|
||||||
|
model: inputModel,
|
||||||
|
halo,
|
||||||
|
initialSnOptions,
|
||||||
|
initialSnPlugins,
|
||||||
|
initialError,
|
||||||
|
onMount,
|
||||||
|
unmount,
|
||||||
|
navigation,
|
||||||
|
onError,
|
||||||
|
},
|
||||||
ref
|
ref
|
||||||
) => {
|
) => {
|
||||||
const { root } = halo;
|
const { root } = halo;
|
||||||
@@ -64,6 +75,8 @@ const Sheet = forwardRef(
|
|||||||
const [bgColor, setBgColor] = useState(undefined);
|
const [bgColor, setBgColor] = useState(undefined);
|
||||||
const [bgImage, setBgImage] = useState(undefined);
|
const [bgImage, setBgImage] = useState(undefined);
|
||||||
const [deepHash, setDeepHash] = useState('');
|
const [deepHash, setDeepHash] = useState('');
|
||||||
|
const renderState = useRef({ cellCount: 0, cellsRendered: 0, initialRender: false });
|
||||||
|
|
||||||
navigation?.setCurrentSheetId?.(model.id);
|
navigation?.setCurrentSheetId?.(model.id);
|
||||||
/// For each object
|
/// For each object
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@@ -85,6 +98,17 @@ const Sheet = forwardRef(
|
|||||||
});
|
});
|
||||||
|
|
||||||
const lCells = layout.cells;
|
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;
|
const { columns, rows } = layout;
|
||||||
// TODO - should try reuse existing objects on subsequent renders
|
// TODO - should try reuse existing objects on subsequent renders
|
||||||
// Non-id updates should only change the "css"
|
// Non-id updates should only change the "css"
|
||||||
@@ -110,6 +134,12 @@ const Sheet = forwardRef(
|
|||||||
currentId: uid(),
|
currentId: uid(),
|
||||||
mounted,
|
mounted,
|
||||||
mountedPromise,
|
mountedPromise,
|
||||||
|
options: {
|
||||||
|
...initialSnOptions,
|
||||||
|
...{
|
||||||
|
onInitialRender: renderCallback,
|
||||||
|
},
|
||||||
|
},
|
||||||
};
|
};
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
@@ -133,7 +163,7 @@ const Sheet = forwardRef(
|
|||||||
() =>
|
() =>
|
||||||
cells
|
cells
|
||||||
? cells.map((c) =>
|
? cells.map((c) =>
|
||||||
getCellRenderer(c, halo, initialSnOptions, initialSnPlugins, initialError, c.mounted, navigation)
|
getCellRenderer(c, halo, c.options, initialSnPlugins, initialError, c.mounted, navigation, onError)
|
||||||
)
|
)
|
||||||
: [],
|
: [],
|
||||||
[cells]
|
[cells]
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ export default function glue({
|
|||||||
onMount,
|
onMount,
|
||||||
initialError,
|
initialError,
|
||||||
navigation,
|
navigation,
|
||||||
|
onError,
|
||||||
}) {
|
}) {
|
||||||
const { root } = halo;
|
const { root } = halo;
|
||||||
const sheetRef = React.createRef();
|
const sheetRef = React.createRef();
|
||||||
@@ -29,6 +30,7 @@ export default function glue({
|
|||||||
onMount={onMount}
|
onMount={onMount}
|
||||||
unmount={unmount}
|
unmount={unmount}
|
||||||
navigation={navigation}
|
navigation={navigation}
|
||||||
|
onError={onError}
|
||||||
/>,
|
/>,
|
||||||
element,
|
element,
|
||||||
model.id
|
model.id
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ export default async function getObject(
|
|||||||
const navigation =
|
const navigation =
|
||||||
inputNavigation || (model.genericType === 'sheet' ? createNavigationApi(halo, store, model) : undefined);
|
inputNavigation || (model.genericType === 'sheet' ? createNavigationApi(halo, store, model) : undefined);
|
||||||
if (model.genericType === 'sheet') {
|
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);
|
return init(model, { options, plugins, element, onRender, onError }, halo, navigation);
|
||||||
|
|||||||
@@ -2,12 +2,15 @@
|
|||||||
import sheetAPI from '../sheet';
|
import sheetAPI from '../sheet';
|
||||||
|
|
||||||
export default async function initSheet(model, optional, halo, navigation, initialError, onDestroy = async () => {}) {
|
export default async function initSheet(model, optional, halo, navigation, initialError, onDestroy = async () => {}) {
|
||||||
|
const { onRender, onError } = optional;
|
||||||
const api = sheetAPI({
|
const api = sheetAPI({
|
||||||
model,
|
model,
|
||||||
halo,
|
halo,
|
||||||
navigation,
|
navigation,
|
||||||
initialError,
|
initialError,
|
||||||
onDestroy,
|
onDestroy,
|
||||||
|
onRender,
|
||||||
|
onError,
|
||||||
});
|
});
|
||||||
if (optional.options) {
|
if (optional.options) {
|
||||||
api.__DO_NOT_USE__.options(optional.options);
|
api.__DO_NOT_USE__.options(optional.options);
|
||||||
|
|||||||
@@ -5,25 +5,49 @@ import getPatches from './utils/patcher';
|
|||||||
|
|
||||||
const noopi = () => {};
|
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 unmountSheet = noopi;
|
||||||
let sheetRef = null;
|
let sheetRef = null;
|
||||||
let mountedReference = null;
|
let mountedReference = null;
|
||||||
let onMount = null;
|
let onMount = null;
|
||||||
|
let onRenderResolve = null;
|
||||||
|
|
||||||
const mounted = new Promise((resolve) => {
|
const mounted = new Promise((resolve) => {
|
||||||
onMount = 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 initialSnOptions = {};
|
||||||
let initialSnPlugins = [];
|
let initialSnPlugins = [];
|
||||||
|
|
||||||
const setSnOptions = async (opts) => {
|
const setSnOptions = async (opts) => {
|
||||||
|
const override = opts.onInitialRender;
|
||||||
if (mountedReference) {
|
if (mountedReference) {
|
||||||
(async () => {
|
(async () => {
|
||||||
await mounted;
|
await mounted;
|
||||||
sheetRef.current.setSnOptions({
|
sheetRef.current.setSnOptions({
|
||||||
...initialSnOptions,
|
...initialSnOptions,
|
||||||
...opts,
|
...opts,
|
||||||
|
...{
|
||||||
|
onInitialRender: createOnInitialRender(override),
|
||||||
|
},
|
||||||
});
|
});
|
||||||
})();
|
})();
|
||||||
} else {
|
} else {
|
||||||
@@ -31,6 +55,9 @@ export default function sheet({ model, halo, navigation, initialError, onDestroy
|
|||||||
initialSnOptions = {
|
initialSnOptions = {
|
||||||
...initialSnOptions,
|
...initialSnOptions,
|
||||||
...opts,
|
...opts,
|
||||||
|
...{
|
||||||
|
onInitialRender: createOnInitialRender(override),
|
||||||
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -79,6 +106,15 @@ export default function sheet({ model, halo, navigation, initialError, onDestroy
|
|||||||
* @type {Navigation}
|
* @type {Navigation}
|
||||||
*/
|
*/
|
||||||
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.
|
* Destroys the sheet and removes it from the the DOM.
|
||||||
* @example
|
* @example
|
||||||
@@ -112,6 +148,7 @@ export default function sheet({ model, halo, navigation, initialError, onDestroy
|
|||||||
initialError,
|
initialError,
|
||||||
onMount,
|
onMount,
|
||||||
navigation,
|
navigation,
|
||||||
|
onError,
|
||||||
});
|
});
|
||||||
return mounted;
|
return mounted;
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -189,4 +189,4 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user