@gravity-ui/dashkit 3.0.2 → 3.1.0-alpha.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/build/cjs/components/DashKit/DashKit.d.ts +1 -0
- package/build/cjs/components/DashKit/DashKit.js +1 -0
- package/build/cjs/components/DashKitView/DashKitView.js +2 -1
- package/build/cjs/hocs/withContext.d.ts +4 -0
- package/build/cjs/hocs/withContext.js +185 -1
- package/build/esm/components/DashKit/DashKit.d.ts +1 -0
- package/build/esm/components/DashKit/DashKit.js +1 -0
- package/build/esm/components/DashKitView/DashKitView.js +3 -2
- package/build/esm/hocs/withContext.d.ts +4 -0
- package/build/esm/hocs/withContext.js +183 -0
- package/package.json +1 -1
|
@@ -22,6 +22,7 @@ interface DashKitDefaultProps {
|
|
|
22
22
|
noOverlay?: boolean;
|
|
23
23
|
draggableHandleClassName?: string;
|
|
24
24
|
_EXPERIMENTAL_preventDoubleCompact?: boolean;
|
|
25
|
+
_EXPERIMENTAL_memoContext?: boolean;
|
|
25
26
|
}
|
|
26
27
|
export interface DashKitProps extends DashKitGeneralProps, Partial<DashKitDefaultProps> {
|
|
27
28
|
}
|
|
@@ -15,9 +15,10 @@ function DashKitView() {
|
|
|
15
15
|
return (react_1.default.createElement("div", { className: b({ theme: registerManager.settings.theme }) }, registerManager.settings.isMobile ? (react_1.default.createElement(MobileLayout_1.default, null)) : (react_1.default.createElement(GridLayout_1.default, { ref: forwardedMetaRef }))));
|
|
16
16
|
}
|
|
17
17
|
const DashKitViewWithContext = (0, withContext_1.withContext)(DashKitView);
|
|
18
|
+
const DashKitViewWithMemoContext = (0, withContext_1.withMemoContext)(DashKitView);
|
|
18
19
|
const DashKitViewForwardedMeta = react_1.default.forwardRef((props, ref) => {
|
|
19
20
|
const layout = (0, useCalcLayout_1.useCalcPropsLayout)(props.config, props.registerManager);
|
|
20
|
-
return react_1.default.createElement(DashKitViewWithContext, Object.assign({}, props, { layout: layout, forwardedMetaRef: ref }));
|
|
21
|
+
return props._EXPERIMENTAL_memoContext ? (react_1.default.createElement(DashKitViewWithMemoContext, Object.assign({}, props, { layout: layout, forwardedMetaRef: ref }))) : (react_1.default.createElement(DashKitViewWithContext, Object.assign({}, props, { layout: layout, forwardedMetaRef: ref })));
|
|
21
22
|
});
|
|
22
23
|
DashKitViewForwardedMeta.displayName = 'DashKitViewForwardedMeta';
|
|
23
24
|
exports.default = DashKitViewForwardedMeta;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.withContext = void 0;
|
|
3
|
+
exports.withMemoContext = exports.withContext = void 0;
|
|
4
4
|
const tslib_1 = require("tslib");
|
|
5
5
|
const react_1 = tslib_1.__importDefault(require("react"));
|
|
6
6
|
const DashKitContext_1 = require("../context/DashKitContext");
|
|
@@ -201,3 +201,187 @@ function withContext(Component) {
|
|
|
201
201
|
_a;
|
|
202
202
|
}
|
|
203
203
|
exports.withContext = withContext;
|
|
204
|
+
function useMemoStateContext(props) {
|
|
205
|
+
// так как мы не хотим хранить параметры виджета с активированной автовысотой в сторе и на сервере, актуальный
|
|
206
|
+
// (видимый юзером в конкретный момент времени) лэйаут (массив объектов с данными о ширине, высоте,
|
|
207
|
+
// расположении конкретного виджета на сетке) будет храниться в стейте, но, для того, чтобы в стор попадал
|
|
208
|
+
// лэйаут без учета вижетов с активированной автовысотой, в момент "подстройки" высоты виджета значение h
|
|
209
|
+
// (высота) из конфига будет запоминаться в originalLayouts, новое значение высоты в adjustedLayouts
|
|
210
|
+
const originalLayouts = react_1.default.useRef({});
|
|
211
|
+
const adjustedLayouts = react_1.default.useRef({});
|
|
212
|
+
// TODO: need move originalLayouts, adjustedLayouts to state
|
|
213
|
+
const [layoutUpdateCounter, forceUpdateLayout] = react_1.default.useState(0);
|
|
214
|
+
const onChange = react_1.default.useCallback(({ config = props.config, itemsStateAndParams = props.itemsStateAndParams }) => {
|
|
215
|
+
if (!((0, isEqual_1.default)(config, props.config) &&
|
|
216
|
+
(0, isEqual_1.default)(itemsStateAndParams, props.itemsStateAndParams))) {
|
|
217
|
+
props.onChange({ config, itemsStateAndParams });
|
|
218
|
+
}
|
|
219
|
+
}, [props.config, props.itemsStateAndParams, props.onChange]);
|
|
220
|
+
// каллбэк вызывающийся при изменение лэйаута сетки, первым аргументом приходит актуальный конфиг лэйаута,
|
|
221
|
+
// т.е. если на текущей сетке есть виджеты, с активированной опцией автовысоты, их параметр "h" будет
|
|
222
|
+
// "подстроенный"; чтобы, для сохранения в сторе "ушли" значения без учёта подстройки (как если бы у этих
|
|
223
|
+
// виджетов автовысота была деактивирована) корректируем их используя this.originalLayouts
|
|
224
|
+
const onLayoutChange = react_1.default.useCallback((layout) => {
|
|
225
|
+
const currentInnerLayout = layout.map((item) => {
|
|
226
|
+
if (item.i in originalLayouts.current) {
|
|
227
|
+
return Object.assign(Object.assign({}, originalLayouts.current[item.i]), { w: item.w, x: item.x, y: item.y });
|
|
228
|
+
}
|
|
229
|
+
else {
|
|
230
|
+
return Object.assign({}, item);
|
|
231
|
+
}
|
|
232
|
+
});
|
|
233
|
+
// [experimental] if the _prevent Double Compact is enabled, then skip recalculate layout with auto height
|
|
234
|
+
// после того, как у виждета активировали автовысоту и его параметр "h" изменился, это приведёт, также, и к
|
|
235
|
+
// изменению параметра (координаты) "y" у элементов расположенных под ним, поэтому, после того, как
|
|
236
|
+
// значения параметра "h" виджетов с активированной автовысотой были изменены, необходимо изменить и
|
|
237
|
+
// координату "y" виджетов расположенных ниже
|
|
238
|
+
const compactedLayout = props._EXPERIMENTAL_preventDoubleCompact
|
|
239
|
+
? currentInnerLayout
|
|
240
|
+
: react_grid_layout_1.utils.compact(currentInnerLayout, LAYOUT_COMPACTING_TYPE, props.registerManager.gridLayout.cols);
|
|
241
|
+
const newConfig = utils_1.UpdateManager.updateLayout({
|
|
242
|
+
layout: compactedLayout,
|
|
243
|
+
config: props.config,
|
|
244
|
+
});
|
|
245
|
+
if (!(0, isEqual_1.default)(newConfig.layout, props.config.layout)) {
|
|
246
|
+
onChange({ config: newConfig });
|
|
247
|
+
}
|
|
248
|
+
}, [props._EXPERIMENTAL_preventDoubleCompact, props.registerManager, props.config, onChange]);
|
|
249
|
+
const onItemRemove = react_1.default.useCallback((id) => {
|
|
250
|
+
onChange(utils_1.UpdateManager.removeItem({
|
|
251
|
+
id,
|
|
252
|
+
config: props.config,
|
|
253
|
+
itemsStateAndParams: props.itemsStateAndParams,
|
|
254
|
+
}));
|
|
255
|
+
}, [props.config, props.itemsStateAndParams, onChange]);
|
|
256
|
+
const onItemStateAndParamsChange = react_1.default.useCallback((id, stateAndParams) => {
|
|
257
|
+
onChange({
|
|
258
|
+
itemsStateAndParams: utils_1.UpdateManager.changeStateAndParams({
|
|
259
|
+
id,
|
|
260
|
+
config: props.config,
|
|
261
|
+
stateAndParams,
|
|
262
|
+
itemsStateAndParams: props.itemsStateAndParams,
|
|
263
|
+
}),
|
|
264
|
+
});
|
|
265
|
+
}, [props.config, props.itemsStateAndParams, onChange]);
|
|
266
|
+
const memorizeOriginalLayout = react_1.default.useCallback((widgetId, preAutoHeightLayout, postAutoHeightLayout) => {
|
|
267
|
+
let needUpdateLayout = false;
|
|
268
|
+
if (!(widgetId in originalLayouts.current)) {
|
|
269
|
+
originalLayouts.current[widgetId] = preAutoHeightLayout;
|
|
270
|
+
needUpdateLayout = true;
|
|
271
|
+
}
|
|
272
|
+
if (adjustedLayouts.current[widgetId] !== postAutoHeightLayout) {
|
|
273
|
+
adjustedLayouts.current[widgetId] = postAutoHeightLayout;
|
|
274
|
+
needUpdateLayout = true;
|
|
275
|
+
}
|
|
276
|
+
if (needUpdateLayout) {
|
|
277
|
+
forceUpdateLayout((prev) => prev + 1);
|
|
278
|
+
}
|
|
279
|
+
}, []);
|
|
280
|
+
const revertToOriginalLayout = react_1.default.useCallback((widgetId) => {
|
|
281
|
+
const needUpdateLayout = widgetId in adjustedLayouts.current || widgetId in originalLayouts.current;
|
|
282
|
+
delete adjustedLayouts.current[widgetId];
|
|
283
|
+
delete originalLayouts.current[widgetId];
|
|
284
|
+
if (needUpdateLayout) {
|
|
285
|
+
forceUpdateLayout((prev) => prev + 1);
|
|
286
|
+
}
|
|
287
|
+
}, []);
|
|
288
|
+
const itemsParams = react_1.default.useMemo(() => (0, shared_1.getItemsParams)({
|
|
289
|
+
defaultGlobalParams: props.defaultGlobalParams,
|
|
290
|
+
globalParams: props.globalParams,
|
|
291
|
+
config: props.config,
|
|
292
|
+
itemsStateAndParams: props.itemsStateAndParams,
|
|
293
|
+
plugins: props.registerManager.getPlugins(),
|
|
294
|
+
}), [
|
|
295
|
+
props.defaultGlobalParams,
|
|
296
|
+
props.globalParams,
|
|
297
|
+
props.config,
|
|
298
|
+
props.itemsStateAndParams,
|
|
299
|
+
props.registerManager,
|
|
300
|
+
]);
|
|
301
|
+
const itemsState = react_1.default.useMemo(() => (0, shared_1.getItemsState)({
|
|
302
|
+
config: props.config,
|
|
303
|
+
itemsStateAndParams: props.itemsStateAndParams,
|
|
304
|
+
}), [props.config, props.itemsStateAndParams]);
|
|
305
|
+
const getItemsMeta = react_1.default.useCallback((pluginsRefs) => {
|
|
306
|
+
return pluginsRefs
|
|
307
|
+
.map((ref) => {
|
|
308
|
+
if (!(ref && typeof ref.getMeta === 'function')) {
|
|
309
|
+
return undefined;
|
|
310
|
+
}
|
|
311
|
+
return ref.getMeta();
|
|
312
|
+
})
|
|
313
|
+
.filter(Boolean);
|
|
314
|
+
}, []);
|
|
315
|
+
const resultLayout = react_1.default.useMemo(() => {
|
|
316
|
+
return props.layout.map((item) => {
|
|
317
|
+
if (item.i in adjustedLayouts.current) {
|
|
318
|
+
return Object.assign(Object.assign({}, adjustedLayouts.current[item.i]), { w: item.w, x: item.x, y: item.y });
|
|
319
|
+
}
|
|
320
|
+
else {
|
|
321
|
+
return Object.assign({}, item);
|
|
322
|
+
}
|
|
323
|
+
});
|
|
324
|
+
}, [props.layout, layoutUpdateCounter]);
|
|
325
|
+
// TODO: don't use getLayout when finished experiment _EXPERIMENTAL_memoContext
|
|
326
|
+
// need use resultLayout like layout props
|
|
327
|
+
const getLayout = react_1.default.useCallback(() => resultLayout, [resultLayout]);
|
|
328
|
+
const reloadItems = react_1.default.useCallback((pluginsRefs, data) => {
|
|
329
|
+
pluginsRefs.forEach((ref) => ref && ref.reload && ref.reload(data));
|
|
330
|
+
}, []);
|
|
331
|
+
return react_1.default.useMemo(() => ({
|
|
332
|
+
getLayout,
|
|
333
|
+
config: props.config,
|
|
334
|
+
context: props.context,
|
|
335
|
+
overlayControls: props.overlayControls,
|
|
336
|
+
noOverlay: props.noOverlay,
|
|
337
|
+
defaultGlobalParams: props.globalParams,
|
|
338
|
+
globalParams: props.globalParams,
|
|
339
|
+
editMode: props.editMode,
|
|
340
|
+
settings: props.settings,
|
|
341
|
+
itemsState,
|
|
342
|
+
itemsParams,
|
|
343
|
+
registerManager: props.registerManager,
|
|
344
|
+
onItemStateAndParamsChange,
|
|
345
|
+
removeItem: onItemRemove,
|
|
346
|
+
editItem: props.onItemEdit,
|
|
347
|
+
layoutChange: onLayoutChange,
|
|
348
|
+
getItemsMeta,
|
|
349
|
+
reloadItems,
|
|
350
|
+
memorizeOriginalLayout,
|
|
351
|
+
revertToOriginalLayout,
|
|
352
|
+
forwardedMetaRef: props.forwardedMetaRef,
|
|
353
|
+
draggableHandleClassName: props.draggableHandleClassName,
|
|
354
|
+
}), [
|
|
355
|
+
getLayout,
|
|
356
|
+
props.config,
|
|
357
|
+
props.context,
|
|
358
|
+
props.overlayControls,
|
|
359
|
+
props.noOverlay,
|
|
360
|
+
props.globalParams,
|
|
361
|
+
props.editMode,
|
|
362
|
+
props.settings,
|
|
363
|
+
itemsState,
|
|
364
|
+
itemsParams,
|
|
365
|
+
props.registerManager,
|
|
366
|
+
onItemStateAndParamsChange,
|
|
367
|
+
onItemRemove,
|
|
368
|
+
props.onItemEdit,
|
|
369
|
+
onLayoutChange,
|
|
370
|
+
getItemsMeta,
|
|
371
|
+
reloadItems,
|
|
372
|
+
memorizeOriginalLayout,
|
|
373
|
+
revertToOriginalLayout,
|
|
374
|
+
props.forwardedMetaRef,
|
|
375
|
+
props.draggableHandleClassName,
|
|
376
|
+
]);
|
|
377
|
+
}
|
|
378
|
+
function withMemoContext(Component) {
|
|
379
|
+
const WithMemoContext = (props) => {
|
|
380
|
+
const contextValue = useMemoStateContext(props);
|
|
381
|
+
return (react_1.default.createElement(DashKitContext_1.DashKitContext.Provider, { value: contextValue },
|
|
382
|
+
react_1.default.createElement(Component, null)));
|
|
383
|
+
};
|
|
384
|
+
WithMemoContext.displayName = `withMemoContext(${Component.displayName || Component.name || 'Component'}`;
|
|
385
|
+
return WithMemoContext;
|
|
386
|
+
}
|
|
387
|
+
exports.withMemoContext = withMemoContext;
|
|
@@ -22,6 +22,7 @@ interface DashKitDefaultProps {
|
|
|
22
22
|
noOverlay?: boolean;
|
|
23
23
|
draggableHandleClassName?: string;
|
|
24
24
|
_EXPERIMENTAL_preventDoubleCompact?: boolean;
|
|
25
|
+
_EXPERIMENTAL_memoContext?: boolean;
|
|
25
26
|
}
|
|
26
27
|
export interface DashKitProps extends DashKitGeneralProps, Partial<DashKitDefaultProps> {
|
|
27
28
|
}
|
|
@@ -3,7 +3,7 @@ import block from 'bem-cn-lite';
|
|
|
3
3
|
import { DashKitContext } from '../../context/DashKitContext';
|
|
4
4
|
import GridLayout from '../GridLayout/GridLayout';
|
|
5
5
|
import MobileLayout from '../MobileLayout/MobileLayout';
|
|
6
|
-
import { withContext } from '../../hocs/withContext';
|
|
6
|
+
import { withContext, withMemoContext } from '../../hocs/withContext';
|
|
7
7
|
import { useCalcPropsLayout } from '../../hooks/useCalcLayout';
|
|
8
8
|
import './DashKitView.css';
|
|
9
9
|
const b = block('dashkit');
|
|
@@ -13,9 +13,10 @@ function DashKitView() {
|
|
|
13
13
|
return (React.createElement("div", { className: b({ theme: registerManager.settings.theme }) }, registerManager.settings.isMobile ? (React.createElement(MobileLayout, null)) : (React.createElement(GridLayout, { ref: forwardedMetaRef }))));
|
|
14
14
|
}
|
|
15
15
|
const DashKitViewWithContext = withContext(DashKitView);
|
|
16
|
+
const DashKitViewWithMemoContext = withMemoContext(DashKitView);
|
|
16
17
|
const DashKitViewForwardedMeta = React.forwardRef((props, ref) => {
|
|
17
18
|
const layout = useCalcPropsLayout(props.config, props.registerManager);
|
|
18
|
-
return React.createElement(DashKitViewWithContext, Object.assign({}, props, { layout: layout, forwardedMetaRef: ref }));
|
|
19
|
+
return props._EXPERIMENTAL_memoContext ? (React.createElement(DashKitViewWithMemoContext, Object.assign({}, props, { layout: layout, forwardedMetaRef: ref }))) : (React.createElement(DashKitViewWithContext, Object.assign({}, props, { layout: layout, forwardedMetaRef: ref })));
|
|
19
20
|
});
|
|
20
21
|
DashKitViewForwardedMeta.displayName = 'DashKitViewForwardedMeta';
|
|
21
22
|
export default DashKitViewForwardedMeta;
|
|
@@ -196,3 +196,186 @@ export function withContext(Component) {
|
|
|
196
196
|
},
|
|
197
197
|
_a;
|
|
198
198
|
}
|
|
199
|
+
function useMemoStateContext(props) {
|
|
200
|
+
// так как мы не хотим хранить параметры виджета с активированной автовысотой в сторе и на сервере, актуальный
|
|
201
|
+
// (видимый юзером в конкретный момент времени) лэйаут (массив объектов с данными о ширине, высоте,
|
|
202
|
+
// расположении конкретного виджета на сетке) будет храниться в стейте, но, для того, чтобы в стор попадал
|
|
203
|
+
// лэйаут без учета вижетов с активированной автовысотой, в момент "подстройки" высоты виджета значение h
|
|
204
|
+
// (высота) из конфига будет запоминаться в originalLayouts, новое значение высоты в adjustedLayouts
|
|
205
|
+
const originalLayouts = React.useRef({});
|
|
206
|
+
const adjustedLayouts = React.useRef({});
|
|
207
|
+
// TODO: need move originalLayouts, adjustedLayouts to state
|
|
208
|
+
const [layoutUpdateCounter, forceUpdateLayout] = React.useState(0);
|
|
209
|
+
const onChange = React.useCallback(({ config = props.config, itemsStateAndParams = props.itemsStateAndParams }) => {
|
|
210
|
+
if (!(isEqual(config, props.config) &&
|
|
211
|
+
isEqual(itemsStateAndParams, props.itemsStateAndParams))) {
|
|
212
|
+
props.onChange({ config, itemsStateAndParams });
|
|
213
|
+
}
|
|
214
|
+
}, [props.config, props.itemsStateAndParams, props.onChange]);
|
|
215
|
+
// каллбэк вызывающийся при изменение лэйаута сетки, первым аргументом приходит актуальный конфиг лэйаута,
|
|
216
|
+
// т.е. если на текущей сетке есть виджеты, с активированной опцией автовысоты, их параметр "h" будет
|
|
217
|
+
// "подстроенный"; чтобы, для сохранения в сторе "ушли" значения без учёта подстройки (как если бы у этих
|
|
218
|
+
// виджетов автовысота была деактивирована) корректируем их используя this.originalLayouts
|
|
219
|
+
const onLayoutChange = React.useCallback((layout) => {
|
|
220
|
+
const currentInnerLayout = layout.map((item) => {
|
|
221
|
+
if (item.i in originalLayouts.current) {
|
|
222
|
+
return Object.assign(Object.assign({}, originalLayouts.current[item.i]), { w: item.w, x: item.x, y: item.y });
|
|
223
|
+
}
|
|
224
|
+
else {
|
|
225
|
+
return Object.assign({}, item);
|
|
226
|
+
}
|
|
227
|
+
});
|
|
228
|
+
// [experimental] if the _prevent Double Compact is enabled, then skip recalculate layout with auto height
|
|
229
|
+
// после того, как у виждета активировали автовысоту и его параметр "h" изменился, это приведёт, также, и к
|
|
230
|
+
// изменению параметра (координаты) "y" у элементов расположенных под ним, поэтому, после того, как
|
|
231
|
+
// значения параметра "h" виджетов с активированной автовысотой были изменены, необходимо изменить и
|
|
232
|
+
// координату "y" виджетов расположенных ниже
|
|
233
|
+
const compactedLayout = props._EXPERIMENTAL_preventDoubleCompact
|
|
234
|
+
? currentInnerLayout
|
|
235
|
+
: gridLayoutUtils.compact(currentInnerLayout, LAYOUT_COMPACTING_TYPE, props.registerManager.gridLayout.cols);
|
|
236
|
+
const newConfig = UpdateManager.updateLayout({
|
|
237
|
+
layout: compactedLayout,
|
|
238
|
+
config: props.config,
|
|
239
|
+
});
|
|
240
|
+
if (!isEqual(newConfig.layout, props.config.layout)) {
|
|
241
|
+
onChange({ config: newConfig });
|
|
242
|
+
}
|
|
243
|
+
}, [props._EXPERIMENTAL_preventDoubleCompact, props.registerManager, props.config, onChange]);
|
|
244
|
+
const onItemRemove = React.useCallback((id) => {
|
|
245
|
+
onChange(UpdateManager.removeItem({
|
|
246
|
+
id,
|
|
247
|
+
config: props.config,
|
|
248
|
+
itemsStateAndParams: props.itemsStateAndParams,
|
|
249
|
+
}));
|
|
250
|
+
}, [props.config, props.itemsStateAndParams, onChange]);
|
|
251
|
+
const onItemStateAndParamsChange = React.useCallback((id, stateAndParams) => {
|
|
252
|
+
onChange({
|
|
253
|
+
itemsStateAndParams: UpdateManager.changeStateAndParams({
|
|
254
|
+
id,
|
|
255
|
+
config: props.config,
|
|
256
|
+
stateAndParams,
|
|
257
|
+
itemsStateAndParams: props.itemsStateAndParams,
|
|
258
|
+
}),
|
|
259
|
+
});
|
|
260
|
+
}, [props.config, props.itemsStateAndParams, onChange]);
|
|
261
|
+
const memorizeOriginalLayout = React.useCallback((widgetId, preAutoHeightLayout, postAutoHeightLayout) => {
|
|
262
|
+
let needUpdateLayout = false;
|
|
263
|
+
if (!(widgetId in originalLayouts.current)) {
|
|
264
|
+
originalLayouts.current[widgetId] = preAutoHeightLayout;
|
|
265
|
+
needUpdateLayout = true;
|
|
266
|
+
}
|
|
267
|
+
if (adjustedLayouts.current[widgetId] !== postAutoHeightLayout) {
|
|
268
|
+
adjustedLayouts.current[widgetId] = postAutoHeightLayout;
|
|
269
|
+
needUpdateLayout = true;
|
|
270
|
+
}
|
|
271
|
+
if (needUpdateLayout) {
|
|
272
|
+
forceUpdateLayout((prev) => prev + 1);
|
|
273
|
+
}
|
|
274
|
+
}, []);
|
|
275
|
+
const revertToOriginalLayout = React.useCallback((widgetId) => {
|
|
276
|
+
const needUpdateLayout = widgetId in adjustedLayouts.current || widgetId in originalLayouts.current;
|
|
277
|
+
delete adjustedLayouts.current[widgetId];
|
|
278
|
+
delete originalLayouts.current[widgetId];
|
|
279
|
+
if (needUpdateLayout) {
|
|
280
|
+
forceUpdateLayout((prev) => prev + 1);
|
|
281
|
+
}
|
|
282
|
+
}, []);
|
|
283
|
+
const itemsParams = React.useMemo(() => getItemsParams({
|
|
284
|
+
defaultGlobalParams: props.defaultGlobalParams,
|
|
285
|
+
globalParams: props.globalParams,
|
|
286
|
+
config: props.config,
|
|
287
|
+
itemsStateAndParams: props.itemsStateAndParams,
|
|
288
|
+
plugins: props.registerManager.getPlugins(),
|
|
289
|
+
}), [
|
|
290
|
+
props.defaultGlobalParams,
|
|
291
|
+
props.globalParams,
|
|
292
|
+
props.config,
|
|
293
|
+
props.itemsStateAndParams,
|
|
294
|
+
props.registerManager,
|
|
295
|
+
]);
|
|
296
|
+
const itemsState = React.useMemo(() => getItemsState({
|
|
297
|
+
config: props.config,
|
|
298
|
+
itemsStateAndParams: props.itemsStateAndParams,
|
|
299
|
+
}), [props.config, props.itemsStateAndParams]);
|
|
300
|
+
const getItemsMeta = React.useCallback((pluginsRefs) => {
|
|
301
|
+
return pluginsRefs
|
|
302
|
+
.map((ref) => {
|
|
303
|
+
if (!(ref && typeof ref.getMeta === 'function')) {
|
|
304
|
+
return undefined;
|
|
305
|
+
}
|
|
306
|
+
return ref.getMeta();
|
|
307
|
+
})
|
|
308
|
+
.filter(Boolean);
|
|
309
|
+
}, []);
|
|
310
|
+
const resultLayout = React.useMemo(() => {
|
|
311
|
+
return props.layout.map((item) => {
|
|
312
|
+
if (item.i in adjustedLayouts.current) {
|
|
313
|
+
return Object.assign(Object.assign({}, adjustedLayouts.current[item.i]), { w: item.w, x: item.x, y: item.y });
|
|
314
|
+
}
|
|
315
|
+
else {
|
|
316
|
+
return Object.assign({}, item);
|
|
317
|
+
}
|
|
318
|
+
});
|
|
319
|
+
}, [props.layout, layoutUpdateCounter]);
|
|
320
|
+
// TODO: don't use getLayout when finished experiment _EXPERIMENTAL_memoContext
|
|
321
|
+
// need use resultLayout like layout props
|
|
322
|
+
const getLayout = React.useCallback(() => resultLayout, [resultLayout]);
|
|
323
|
+
const reloadItems = React.useCallback((pluginsRefs, data) => {
|
|
324
|
+
pluginsRefs.forEach((ref) => ref && ref.reload && ref.reload(data));
|
|
325
|
+
}, []);
|
|
326
|
+
return React.useMemo(() => ({
|
|
327
|
+
getLayout,
|
|
328
|
+
config: props.config,
|
|
329
|
+
context: props.context,
|
|
330
|
+
overlayControls: props.overlayControls,
|
|
331
|
+
noOverlay: props.noOverlay,
|
|
332
|
+
defaultGlobalParams: props.globalParams,
|
|
333
|
+
globalParams: props.globalParams,
|
|
334
|
+
editMode: props.editMode,
|
|
335
|
+
settings: props.settings,
|
|
336
|
+
itemsState,
|
|
337
|
+
itemsParams,
|
|
338
|
+
registerManager: props.registerManager,
|
|
339
|
+
onItemStateAndParamsChange,
|
|
340
|
+
removeItem: onItemRemove,
|
|
341
|
+
editItem: props.onItemEdit,
|
|
342
|
+
layoutChange: onLayoutChange,
|
|
343
|
+
getItemsMeta,
|
|
344
|
+
reloadItems,
|
|
345
|
+
memorizeOriginalLayout,
|
|
346
|
+
revertToOriginalLayout,
|
|
347
|
+
forwardedMetaRef: props.forwardedMetaRef,
|
|
348
|
+
draggableHandleClassName: props.draggableHandleClassName,
|
|
349
|
+
}), [
|
|
350
|
+
getLayout,
|
|
351
|
+
props.config,
|
|
352
|
+
props.context,
|
|
353
|
+
props.overlayControls,
|
|
354
|
+
props.noOverlay,
|
|
355
|
+
props.globalParams,
|
|
356
|
+
props.editMode,
|
|
357
|
+
props.settings,
|
|
358
|
+
itemsState,
|
|
359
|
+
itemsParams,
|
|
360
|
+
props.registerManager,
|
|
361
|
+
onItemStateAndParamsChange,
|
|
362
|
+
onItemRemove,
|
|
363
|
+
props.onItemEdit,
|
|
364
|
+
onLayoutChange,
|
|
365
|
+
getItemsMeta,
|
|
366
|
+
reloadItems,
|
|
367
|
+
memorizeOriginalLayout,
|
|
368
|
+
revertToOriginalLayout,
|
|
369
|
+
props.forwardedMetaRef,
|
|
370
|
+
props.draggableHandleClassName,
|
|
371
|
+
]);
|
|
372
|
+
}
|
|
373
|
+
export function withMemoContext(Component) {
|
|
374
|
+
const WithMemoContext = (props) => {
|
|
375
|
+
const contextValue = useMemoStateContext(props);
|
|
376
|
+
return (React.createElement(DashKitContext.Provider, { value: contextValue },
|
|
377
|
+
React.createElement(Component, null)));
|
|
378
|
+
};
|
|
379
|
+
WithMemoContext.displayName = `withMemoContext(${Component.displayName || Component.name || 'Component'}`;
|
|
380
|
+
return WithMemoContext;
|
|
381
|
+
}
|