@grafana/scenes 6.35.1 → 6.35.2--canary.1148.17723712400.0

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/dist/index.d.ts CHANGED
@@ -601,6 +601,15 @@ interface SceneDataProvider<T extends SceneObjectState = SceneDataState> extends
601
601
  isDataReadyToDisplay?: () => boolean;
602
602
  cancelQuery?: () => void;
603
603
  getResultsStream(): Observable<SceneDataProviderResult>;
604
+ /**
605
+ * Can be used to disable query execution for scene elements that are out of view
606
+ */
607
+ isInViewChanged?(isInView: boolean): void;
608
+ /**
609
+ * Allow activating or deactivating the isInView behavior
610
+ * This is useful for external consumers of a data provider (i.e., the Dashboard datasource)
611
+ */
612
+ bypassIsInViewChanged?(bypassIsInView: boolean): void;
604
613
  }
605
614
  interface SceneDataLayerProviderState extends SceneDataState {
606
615
  name: string;
@@ -1781,6 +1790,9 @@ declare class SceneQueryRunner extends SceneObjectBase<QueryRunnerState> impleme
1781
1790
  private _scopedVars;
1782
1791
  private _layerAnnotations?;
1783
1792
  private _resultAnnotations?;
1793
+ private _isInView;
1794
+ private _bypassIsInView;
1795
+ private _queryNotExecutedWhenOutOfView;
1784
1796
  getResultsStream(): ReplaySubject<SceneDataProviderResult>;
1785
1797
  protected _variableDependency: VariableDependencyConfig<QueryRunnerState>;
1786
1798
  private _drilldownDependenciesManager;
@@ -1829,6 +1841,8 @@ declare class SceneQueryRunner extends SceneObjectBase<QueryRunnerState> impleme
1829
1841
  */
1830
1842
  private getClosestExtraQueryProviders;
1831
1843
  private isQueryModeAuto;
1844
+ isInViewChanged(isInView: boolean): void;
1845
+ bypassIsInViewChanged(bypassIsInView: boolean): void;
1832
1846
  }
1833
1847
 
1834
1848
  interface DataProviderSharerState extends SceneDataState {
@@ -1921,6 +1935,8 @@ declare class SceneDataTransformer extends SceneObjectBase<SceneDataTransformerS
1921
1935
  cancelQuery(): void;
1922
1936
  getResultsStream(): ReplaySubject<SceneDataProviderResult>;
1923
1937
  clone(withState?: Partial<SceneDataTransformerState>): this;
1938
+ isInViewChanged(isInView: boolean): void;
1939
+ bypassIsInViewChanged(bypassIsInView: boolean): void;
1924
1940
  private haveAlreadyTransformedData;
1925
1941
  private transform;
1926
1942
  private _interpolateVariablesInTransformationConfigs;
package/dist/index.js CHANGED
@@ -6473,6 +6473,9 @@ class SceneQueryRunner extends SceneObjectBase {
6473
6473
  this._variableValueRecorder = new VariableValueRecorder();
6474
6474
  this._results = new rxjs.ReplaySubject(1);
6475
6475
  this._scopedVars = { __sceneObject: wrapInSafeSerializableSceneObject(this) };
6476
+ this._isInView = true;
6477
+ this._bypassIsInView = false;
6478
+ this._queryNotExecutedWhenOutOfView = false;
6476
6479
  this._variableDependency = new VariableDependencyConfig(this, {
6477
6480
  statePaths: ["queries", "datasource", "minInterval"],
6478
6481
  onVariableUpdateCompleted: this.onVariableUpdatesCompleted.bind(this),
@@ -6712,6 +6715,11 @@ class SceneQueryRunner extends SceneObjectBase {
6712
6715
  if (!this.state.maxDataPoints && this.state.maxDataPointsFromWidth && !this._containerWidth) {
6713
6716
  return;
6714
6717
  }
6718
+ if (this.isQueryModeAuto() && !this._isInView && !this._bypassIsInView) {
6719
+ this._queryNotExecutedWhenOutOfView = true;
6720
+ return;
6721
+ }
6722
+ this._queryNotExecutedWhenOutOfView = false;
6715
6723
  if (!this._dataLayersSub) {
6716
6724
  this._handleDataLayers();
6717
6725
  }
@@ -6875,6 +6883,20 @@ class SceneQueryRunner extends SceneObjectBase {
6875
6883
  var _a;
6876
6884
  return ((_a = this.state.runQueriesMode) != null ? _a : "auto") === "auto";
6877
6885
  }
6886
+ isInViewChanged(isInView) {
6887
+ writeSceneLog("SceneQueryRunner", `isInViewChanged: ${isInView}`, this.state.key);
6888
+ this._isInView = isInView;
6889
+ if (isInView && this._queryNotExecutedWhenOutOfView) {
6890
+ this.runQueries();
6891
+ }
6892
+ }
6893
+ bypassIsInViewChanged(bypassIsInView) {
6894
+ writeSceneLog("SceneQueryRunner", `bypassIsInViewChanged: ${bypassIsInView}`, this.state.key);
6895
+ this._bypassIsInView = bypassIsInView;
6896
+ if (bypassIsInView && this._queryNotExecutedWhenOutOfView) {
6897
+ this.runQueries();
6898
+ }
6899
+ }
6878
6900
  }
6879
6901
  function findFirstDatasource(targets) {
6880
6902
  var _a, _b;
@@ -8315,6 +8337,71 @@ const getStyles$8 = (theme) => ({
8315
8337
  })
8316
8338
  });
8317
8339
 
8340
+ function useUniqueId() {
8341
+ var _a;
8342
+ const idRefLazy = React.useRef(void 0);
8343
+ (_a = idRefLazy.current) != null ? _a : idRefLazy.current = lodash.uniqueId();
8344
+ return idRefLazy.current;
8345
+ }
8346
+ const LazyLoader = React__default.default.forwardRef(
8347
+ ({ children, onLoad, onChange, className, ...rest }, ref) => {
8348
+ const id = useUniqueId();
8349
+ const { hideEmpty } = ui.useStyles2(getStyles$7);
8350
+ const [loaded, setLoaded] = React.useState(false);
8351
+ const [isInView, setIsInView] = React.useState(false);
8352
+ const innerRef = React.useRef(null);
8353
+ React.useImperativeHandle(ref, () => innerRef.current);
8354
+ reactUse.useEffectOnce(() => {
8355
+ LazyLoader.addCallback(id, (entry) => {
8356
+ if (!loaded && entry.isIntersecting) {
8357
+ setLoaded(true);
8358
+ onLoad == null ? void 0 : onLoad();
8359
+ }
8360
+ setIsInView(entry.isIntersecting);
8361
+ onChange == null ? void 0 : onChange(entry.isIntersecting);
8362
+ });
8363
+ const wrapperEl = innerRef.current;
8364
+ if (wrapperEl) {
8365
+ LazyLoader.observer.observe(wrapperEl);
8366
+ }
8367
+ return () => {
8368
+ wrapperEl && LazyLoader.observer.unobserve(wrapperEl);
8369
+ delete LazyLoader.callbacks[id];
8370
+ if (Object.keys(LazyLoader.callbacks).length === 0) {
8371
+ LazyLoader.observer.disconnect();
8372
+ }
8373
+ };
8374
+ });
8375
+ return /* @__PURE__ */ React__default.default.createElement("div", { id, ref: innerRef, className: `${hideEmpty} ${className}`, ...rest }, !loaded ? i18n.t("grafana-scenes.components.lazy-loader.placeholder", "\xA0") : /* @__PURE__ */ React__default.default.createElement(LazyLoaderInViewContext.Provider, { value: isInView }, children));
8376
+ }
8377
+ );
8378
+ function getStyles$7() {
8379
+ return {
8380
+ hideEmpty: css.css({
8381
+ "&:empty": {
8382
+ display: "none"
8383
+ }
8384
+ })
8385
+ };
8386
+ }
8387
+ LazyLoader.displayName = "LazyLoader";
8388
+ LazyLoader.callbacks = {};
8389
+ LazyLoader.addCallback = (id, c) => LazyLoader.callbacks[id] = c;
8390
+ LazyLoader.observer = new IntersectionObserver(
8391
+ (entries) => {
8392
+ for (const entry of entries) {
8393
+ if (typeof LazyLoader.callbacks[entry.target.id] === "function") {
8394
+ LazyLoader.callbacks[entry.target.id](entry);
8395
+ }
8396
+ }
8397
+ },
8398
+ { rootMargin: "100px" }
8399
+ );
8400
+ const LazyLoaderInViewContext = React__default.default.createContext(true);
8401
+ function useLazyLoaderIsInView() {
8402
+ return React__default.default.useContext(LazyLoaderInViewContext);
8403
+ }
8404
+
8318
8405
  function VizPanelRenderer({ model }) {
8319
8406
  var _a;
8320
8407
  const {
@@ -8357,6 +8444,12 @@ function VizPanelRenderer({ model }) {
8357
8444
  const sceneTimeRange = sceneGraph.getTimeRange(model);
8358
8445
  const timeZone = sceneTimeRange.getTimeZone();
8359
8446
  const timeRange = model.getTimeRange(dataWithFieldConfig);
8447
+ const isInView = useLazyLoaderIsInView();
8448
+ React.useEffect(() => {
8449
+ if (dataObject.isInViewChanged) {
8450
+ dataObject.isInViewChanged(isInView);
8451
+ }
8452
+ }, [isInView, dataObject]);
8360
8453
  const titleInterpolated = model.interpolate(title, void 0, "text");
8361
8454
  const alertStateStyles = ui.useStyles2(getAlertStateStyles);
8362
8455
  if (!plugin) {
@@ -8917,6 +9010,14 @@ class SceneDataTransformer extends SceneObjectBase {
8917
9010
  }
8918
9011
  return clone;
8919
9012
  }
9013
+ isInViewChanged(isInView) {
9014
+ var _a, _b;
9015
+ (_b = (_a = this.state.$data) == null ? void 0 : _a.isInViewChanged) == null ? void 0 : _b.call(_a, isInView);
9016
+ }
9017
+ bypassIsInViewChanged(bypassIsInView) {
9018
+ var _a, _b;
9019
+ (_b = (_a = this.state.$data) == null ? void 0 : _a.bypassIsInViewChanged) == null ? void 0 : _b.call(_a, bypassIsInView);
9020
+ }
8920
9021
  haveAlreadyTransformedData(data) {
8921
9022
  if (!this._prevDataFromSource) {
8922
9023
  return false;
@@ -11224,10 +11325,10 @@ class EmbeddedScene extends SceneObjectBase {
11224
11325
  EmbeddedScene.Component = EmbeddedSceneRenderer;
11225
11326
  function EmbeddedSceneRenderer({ model }) {
11226
11327
  const { body, controls } = model.useState();
11227
- const styles = ui.useStyles2(getStyles$7);
11328
+ const styles = ui.useStyles2(getStyles$6);
11228
11329
  return /* @__PURE__ */ React__default.default.createElement("div", { className: styles.container }, controls && /* @__PURE__ */ React__default.default.createElement("div", { className: styles.controls }, controls.map((control) => /* @__PURE__ */ React__default.default.createElement(control.Component, { key: control.state.key, model: control }))), /* @__PURE__ */ React__default.default.createElement("div", { className: styles.body }, /* @__PURE__ */ React__default.default.createElement(body.Component, { model: body })));
11229
11330
  }
11230
- const getStyles$7 = (theme) => {
11331
+ const getStyles$6 = (theme) => {
11231
11332
  return {
11232
11333
  container: css.css({
11233
11334
  flexGrow: 1,
@@ -11413,67 +11514,6 @@ function isSceneGridLayout(child) {
11413
11514
  return child instanceof SceneGridLayout;
11414
11515
  }
11415
11516
 
11416
- function useUniqueId() {
11417
- var _a;
11418
- const idRefLazy = React.useRef(void 0);
11419
- (_a = idRefLazy.current) != null ? _a : idRefLazy.current = lodash.uniqueId();
11420
- return idRefLazy.current;
11421
- }
11422
- const LazyLoader = React__default.default.forwardRef(
11423
- ({ children, onLoad, onChange, className, ...rest }, ref) => {
11424
- const id = useUniqueId();
11425
- const { hideEmpty } = ui.useStyles2(getStyles$6);
11426
- const [loaded, setLoaded] = React.useState(false);
11427
- const [isInView, setIsInView] = React.useState(false);
11428
- const innerRef = React.useRef(null);
11429
- React.useImperativeHandle(ref, () => innerRef.current);
11430
- reactUse.useEffectOnce(() => {
11431
- LazyLoader.addCallback(id, (entry) => {
11432
- if (!loaded && entry.isIntersecting) {
11433
- setLoaded(true);
11434
- onLoad == null ? void 0 : onLoad();
11435
- }
11436
- setIsInView(entry.isIntersecting);
11437
- onChange == null ? void 0 : onChange(entry.isIntersecting);
11438
- });
11439
- const wrapperEl = innerRef.current;
11440
- if (wrapperEl) {
11441
- LazyLoader.observer.observe(wrapperEl);
11442
- }
11443
- return () => {
11444
- wrapperEl && LazyLoader.observer.unobserve(wrapperEl);
11445
- delete LazyLoader.callbacks[id];
11446
- if (Object.keys(LazyLoader.callbacks).length === 0) {
11447
- LazyLoader.observer.disconnect();
11448
- }
11449
- };
11450
- });
11451
- return /* @__PURE__ */ React__default.default.createElement("div", { id, ref: innerRef, className: `${hideEmpty} ${className}`, ...rest }, !loaded || !isInView ? i18n.t("grafana-scenes.components.lazy-loader.placeholder", "\xA0") : children);
11452
- }
11453
- );
11454
- function getStyles$6() {
11455
- return {
11456
- hideEmpty: css.css({
11457
- "&:empty": {
11458
- display: "none"
11459
- }
11460
- })
11461
- };
11462
- }
11463
- LazyLoader.displayName = "LazyLoader";
11464
- LazyLoader.callbacks = {};
11465
- LazyLoader.addCallback = (id, c) => LazyLoader.callbacks[id] = c;
11466
- LazyLoader.observer = new IntersectionObserver(
11467
- (entries) => {
11468
- for (const entry of entries) {
11469
- if (typeof LazyLoader.callbacks[entry.target.id] === "function") {
11470
- LazyLoader.callbacks[entry.target.id](entry);
11471
- }
11472
- }
11473
- },
11474
- { rootMargin: "100px" }
11475
- );
11476
-
11477
11517
  function SceneGridLayoutRenderer({ model }) {
11478
11518
  const { children, isLazy, isDraggable, isResizable } = model.useState();
11479
11519
  const [outerDivRef, { width, height }] = reactUse.useMeasure();