@grafana/scenes 6.35.1 → 6.35.2--canary.1148.17723429933.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,14 @@ 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
+ * Returns the current state of the isInView flag. Useful for various edge cases like Dashboard datasource
610
+ */
611
+ getIsInView?(): boolean;
604
612
  }
605
613
  interface SceneDataLayerProviderState extends SceneDataState {
606
614
  name: string;
@@ -1781,6 +1789,8 @@ declare class SceneQueryRunner extends SceneObjectBase<QueryRunnerState> impleme
1781
1789
  private _scopedVars;
1782
1790
  private _layerAnnotations?;
1783
1791
  private _resultAnnotations?;
1792
+ private _isInView;
1793
+ private _queryNotExecutedWhenOutOfView;
1784
1794
  getResultsStream(): ReplaySubject<SceneDataProviderResult>;
1785
1795
  protected _variableDependency: VariableDependencyConfig<QueryRunnerState>;
1786
1796
  private _drilldownDependenciesManager;
@@ -1829,6 +1839,8 @@ declare class SceneQueryRunner extends SceneObjectBase<QueryRunnerState> impleme
1829
1839
  */
1830
1840
  private getClosestExtraQueryProviders;
1831
1841
  private isQueryModeAuto;
1842
+ isInViewChanged(isInView: boolean): void;
1843
+ getIsInView(): boolean;
1832
1844
  }
1833
1845
 
1834
1846
  interface DataProviderSharerState extends SceneDataState {
@@ -1921,6 +1933,8 @@ declare class SceneDataTransformer extends SceneObjectBase<SceneDataTransformerS
1921
1933
  cancelQuery(): void;
1922
1934
  getResultsStream(): ReplaySubject<SceneDataProviderResult>;
1923
1935
  clone(withState?: Partial<SceneDataTransformerState>): this;
1936
+ isInViewChanged(isInView: boolean): void;
1937
+ getIsInView(): boolean;
1924
1938
  private haveAlreadyTransformedData;
1925
1939
  private transform;
1926
1940
  private _interpolateVariablesInTransformationConfigs;
package/dist/index.js CHANGED
@@ -6473,6 +6473,8 @@ 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._queryNotExecutedWhenOutOfView = false;
6476
6478
  this._variableDependency = new VariableDependencyConfig(this, {
6477
6479
  statePaths: ["queries", "datasource", "minInterval"],
6478
6480
  onVariableUpdateCompleted: this.onVariableUpdatesCompleted.bind(this),
@@ -6712,6 +6714,11 @@ class SceneQueryRunner extends SceneObjectBase {
6712
6714
  if (!this.state.maxDataPoints && this.state.maxDataPointsFromWidth && !this._containerWidth) {
6713
6715
  return;
6714
6716
  }
6717
+ if (this.isQueryModeAuto() && !this._isInView) {
6718
+ this._queryNotExecutedWhenOutOfView = true;
6719
+ return;
6720
+ }
6721
+ this._queryNotExecutedWhenOutOfView = false;
6715
6722
  if (!this._dataLayersSub) {
6716
6723
  this._handleDataLayers();
6717
6724
  }
@@ -6875,6 +6882,16 @@ class SceneQueryRunner extends SceneObjectBase {
6875
6882
  var _a;
6876
6883
  return ((_a = this.state.runQueriesMode) != null ? _a : "auto") === "auto";
6877
6884
  }
6885
+ isInViewChanged(isInView) {
6886
+ writeSceneLog("SceneQueryRunner", `isInViewChanged: ${isInView}`, this.state.key);
6887
+ this._isInView = isInView;
6888
+ if (isInView && this._queryNotExecutedWhenOutOfView) {
6889
+ this.runQueries();
6890
+ }
6891
+ }
6892
+ getIsInView() {
6893
+ return this._isInView;
6894
+ }
6878
6895
  }
6879
6896
  function findFirstDatasource(targets) {
6880
6897
  var _a, _b;
@@ -8315,6 +8332,71 @@ const getStyles$8 = (theme) => ({
8315
8332
  })
8316
8333
  });
8317
8334
 
8335
+ function useUniqueId() {
8336
+ var _a;
8337
+ const idRefLazy = React.useRef(void 0);
8338
+ (_a = idRefLazy.current) != null ? _a : idRefLazy.current = lodash.uniqueId();
8339
+ return idRefLazy.current;
8340
+ }
8341
+ const LazyLoader = React__default.default.forwardRef(
8342
+ ({ children, onLoad, onChange, className, ...rest }, ref) => {
8343
+ const id = useUniqueId();
8344
+ const { hideEmpty } = ui.useStyles2(getStyles$7);
8345
+ const [loaded, setLoaded] = React.useState(false);
8346
+ const [isInView, setIsInView] = React.useState(false);
8347
+ const innerRef = React.useRef(null);
8348
+ React.useImperativeHandle(ref, () => innerRef.current);
8349
+ reactUse.useEffectOnce(() => {
8350
+ LazyLoader.addCallback(id, (entry) => {
8351
+ if (!loaded && entry.isIntersecting) {
8352
+ setLoaded(true);
8353
+ onLoad == null ? void 0 : onLoad();
8354
+ }
8355
+ setIsInView(entry.isIntersecting);
8356
+ onChange == null ? void 0 : onChange(entry.isIntersecting);
8357
+ });
8358
+ const wrapperEl = innerRef.current;
8359
+ if (wrapperEl) {
8360
+ LazyLoader.observer.observe(wrapperEl);
8361
+ }
8362
+ return () => {
8363
+ wrapperEl && LazyLoader.observer.unobserve(wrapperEl);
8364
+ delete LazyLoader.callbacks[id];
8365
+ if (Object.keys(LazyLoader.callbacks).length === 0) {
8366
+ LazyLoader.observer.disconnect();
8367
+ }
8368
+ };
8369
+ });
8370
+ 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));
8371
+ }
8372
+ );
8373
+ function getStyles$7() {
8374
+ return {
8375
+ hideEmpty: css.css({
8376
+ "&:empty": {
8377
+ display: "none"
8378
+ }
8379
+ })
8380
+ };
8381
+ }
8382
+ LazyLoader.displayName = "LazyLoader";
8383
+ LazyLoader.callbacks = {};
8384
+ LazyLoader.addCallback = (id, c) => LazyLoader.callbacks[id] = c;
8385
+ LazyLoader.observer = new IntersectionObserver(
8386
+ (entries) => {
8387
+ for (const entry of entries) {
8388
+ if (typeof LazyLoader.callbacks[entry.target.id] === "function") {
8389
+ LazyLoader.callbacks[entry.target.id](entry);
8390
+ }
8391
+ }
8392
+ },
8393
+ { rootMargin: "100px" }
8394
+ );
8395
+ const LazyLoaderInViewContext = React__default.default.createContext(true);
8396
+ function useLazyLoaderIsInView() {
8397
+ return React__default.default.useContext(LazyLoaderInViewContext);
8398
+ }
8399
+
8318
8400
  function VizPanelRenderer({ model }) {
8319
8401
  var _a;
8320
8402
  const {
@@ -8357,6 +8439,12 @@ function VizPanelRenderer({ model }) {
8357
8439
  const sceneTimeRange = sceneGraph.getTimeRange(model);
8358
8440
  const timeZone = sceneTimeRange.getTimeZone();
8359
8441
  const timeRange = model.getTimeRange(dataWithFieldConfig);
8442
+ const isInView = useLazyLoaderIsInView();
8443
+ React.useEffect(() => {
8444
+ if (dataObject.isInViewChanged) {
8445
+ dataObject.isInViewChanged(isInView);
8446
+ }
8447
+ }, [isInView, dataObject]);
8360
8448
  const titleInterpolated = model.interpolate(title, void 0, "text");
8361
8449
  const alertStateStyles = ui.useStyles2(getAlertStateStyles);
8362
8450
  if (!plugin) {
@@ -8917,6 +9005,14 @@ class SceneDataTransformer extends SceneObjectBase {
8917
9005
  }
8918
9006
  return clone;
8919
9007
  }
9008
+ isInViewChanged(isInView) {
9009
+ var _a, _b;
9010
+ (_b = (_a = this.state.$data) == null ? void 0 : _a.isInViewChanged) == null ? void 0 : _b.call(_a, isInView);
9011
+ }
9012
+ getIsInView() {
9013
+ var _a, _b, _c;
9014
+ return (_c = (_b = (_a = this.state.$data) == null ? void 0 : _a.getIsInView) == null ? void 0 : _b.call(_a)) != null ? _c : true;
9015
+ }
8920
9016
  haveAlreadyTransformedData(data) {
8921
9017
  if (!this._prevDataFromSource) {
8922
9018
  return false;
@@ -11224,10 +11320,10 @@ class EmbeddedScene extends SceneObjectBase {
11224
11320
  EmbeddedScene.Component = EmbeddedSceneRenderer;
11225
11321
  function EmbeddedSceneRenderer({ model }) {
11226
11322
  const { body, controls } = model.useState();
11227
- const styles = ui.useStyles2(getStyles$7);
11323
+ const styles = ui.useStyles2(getStyles$6);
11228
11324
  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
11325
  }
11230
- const getStyles$7 = (theme) => {
11326
+ const getStyles$6 = (theme) => {
11231
11327
  return {
11232
11328
  container: css.css({
11233
11329
  flexGrow: 1,
@@ -11413,67 +11509,6 @@ function isSceneGridLayout(child) {
11413
11509
  return child instanceof SceneGridLayout;
11414
11510
  }
11415
11511
 
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
11512
  function SceneGridLayoutRenderer({ model }) {
11478
11513
  const { children, isLazy, isDraggable, isResizable } = model.useState();
11479
11514
  const [outerDivRef, { width, height }] = reactUse.useMeasure();