Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions .github/actions/yarn-nm-install/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -67,8 +67,9 @@ runs:
with:
path: ${{ steps.yarn-config.outputs.CACHE_FOLDER }}
key: yarn-download-cache-${{ hashFiles(format('{0}/yarn.lock', inputs.cwd), format('{0}/.yarnrc.yml', inputs.cwd)) }}
restore-keys: |
yarn-download-cache-
# No restore-keys: avoid restoring a stale cache from a different lockfile.
# A stale cache can miss artifacts (e.g. react-data-grid git dependency zip)
# and cause ENOENT during `yarn install --immutable`.

- name: Restore node_modules
if: inputs.cache-node-modules == 'true'
Expand Down
13 changes: 13 additions & 0 deletions .github/workflows/node-ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,14 @@ jobs:

- name: Install dependencies
uses: ./.github/actions/yarn-nm-install
with:
# Disable node_modules and install-state cache to avoid ENOENT when
# .yarn/cache (e.g. react-data-grid git dependency zip) is missing.
# The release job runs on a fresh runner; restoring node_modules without
# the matching .yarn/cache causes "stat .../react-data-grid-https-*.zip"
# to fail during the Fetch step.
cache-node-modules: false
cache-install-state: false

- name: Build library
run: yarn run lerna run build --no-private
Expand All @@ -89,3 +97,8 @@ jobs:
run: yarn auto shipit
env:
GITHUB_TOKEN: ${{ steps.generate-token.outputs.token }}
# Disable hardened mode so Lerna's `yarn install --mode update-lockfile`
# can access .yarn/cache. Hardened mode runs resolution in a sandbox where
# the react-data-grid git dependency artifact never reaches the cache,
# causing ENOENT during the Fetch step.
YARN_ENABLE_HARDENED_MODE: '0'
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,8 @@
},
"resolutions": {
"@types/react": "18.2.74",
"@rollup/plugin-eslint/eslint": "^9.28.0"
"@rollup/plugin-eslint/eslint": "^9.28.0",
"rxjs": "7.8.1"
},
"packageManager": "yarn@4.1.1",
"workspaces": [
Expand Down
14 changes: 7 additions & 7 deletions packages/scenes-app/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,12 @@
"@babel/core": "^7.16.7",
"@eslint/compat": "1.3.0",
"@grafana/e2e": "9.2.1",
"@grafana/e2e-selectors": "^11.5.0",
"@grafana/e2e-selectors": "^12.3.0",
"@grafana/eslint-config": "8.1.0",
"@grafana/tsconfig": "1.3.0-rc1",
"@stylistic/eslint-plugin-ts": "3.1.0",
"@swc/core": "^1.2.144",
"@swc/helpers": "^0.3.6",
"@swc/helpers": "~0.5.0",
"@swc/jest": "^0.2.36",
"@testing-library/jest-dom": "^6.4.2",
"@testing-library/react": "^12.1.3",
Expand Down Expand Up @@ -64,13 +64,13 @@
},
"dependencies": {
"@emotion/css": "^11.1.3",
"@grafana/data": "^11.6.0",
"@grafana/runtime": "^11.6.0",
"@grafana/data": "^12.3.0",
"@grafana/runtime": "^12.3.0",
"@grafana/scenes": "workspace:*",
"@grafana/scenes-ml": "^0.2.0",
"@grafana/scenes-ml": "^0.5.0",
"@grafana/scenes-react": "workspace:*",
"@grafana/schema": "^11.6.0",
"@grafana/ui": "^11.6.0",
"@grafana/schema": "^12.3.0",
"@grafana/ui": "^12.3.0",
"@types/lodash": "latest",
"react": "18.2.0",
"react-dom": "18.2.0",
Expand Down
29 changes: 18 additions & 11 deletions packages/scenes-app/src/demos/filteringData.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,19 @@ import React from 'react';
import {
EmbeddedScene,
PanelBuilders,
PanelOptionsBuilders,
SceneAppPage,
SceneAppPageState,
SceneComponentProps,
SceneDataTransformer,
SceneFlexItem,
SceneFlexLayout,
SceneObjectBase,
SceneObjectRef,
SceneObjectState,
SceneQueryRunner,
SceneObjectRef,
VizPanel,
} from '@grafana/scenes';
import { InlineSwitch, Input } from '@grafana/ui';
import { Input, InlineSwitch } from '@grafana/ui';
import { getEmbeddedSceneDefaults } from './utils';
import { ControlsLabel } from '@grafana/scenes/src/utils/ControlsLabel';
import { DataTransformerConfig, MatcherConfig } from '@grafana/schema';
Expand Down Expand Up @@ -54,7 +53,10 @@ export function getDataFilteringTest(defaults: SceneAppPageState) {
});

const tablePanel = PanelBuilders.table().setData(filteredData).build();
const paginationControl = new PaginationControl({ vizPanelRef: new SceneObjectRef(tablePanel) });

const paginationControl = new PaginationControl({
vizPanelRef: new SceneObjectRef(tablePanel),
});

return new SceneAppPage({
...defaults,
Expand Down Expand Up @@ -86,7 +88,7 @@ interface PaginationControlState extends SceneObjectState {
class PaginationControl extends SceneObjectBase<PaginationControlState> {
static Component = PaginationControlRenderer;

public constructor(initialState: Omit<PaginationControlState, 'isEnabled'>) {
public constructor(initialState: Omit<PaginationControlState, 'isEnabled'> & { isEnabled?: boolean }) {
super({
isEnabled: false,
...initialState,
Expand All @@ -97,13 +99,18 @@ class PaginationControl extends SceneObjectBase<PaginationControlState> {
const isEnabled = !this.state.isEnabled;
this.setState({ isEnabled });

const nextOptions = PanelOptionsBuilders.table()
.setOption('footer', {
const panel = this.state.vizPanelRef.resolve();
const currentOptions = panel.state.options as Record<string, unknown>;
const nextOptions = {
...currentOptions,
enablePagination: isEnabled,
// Legacy path: some table panel versions still read from footer.enablePagination
footer: {
...(typeof currentOptions.footer === 'object' && currentOptions.footer ? currentOptions.footer : {}),
enablePagination: isEnabled,
})
.build();

this.state.vizPanelRef.resolve().onOptionsChange(nextOptions);
},
};
panel.onOptionsChange(nextOptions, true);
};
}

Expand Down
5 changes: 0 additions & 5 deletions packages/scenes-app/src/monitoring-app/scenes.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -52,15 +52,10 @@ export function getHttpHandlerListScene(): EmbeddedScene {
const httpHandlersTable = PanelBuilders.table()
.setTitle('Handlers')
.setData(httpHandlerQueriesFiltered)
.setOption('footer', {
enablePagination: true,
})
.setOverrides((b) =>
b
.matchFieldsWithNameByRegex('.*')
.overrideFilterable(false)
.matchFieldsWithName('Time')
.overrideCustomFieldConfig('hidden', true)
.matchFieldsWithName('Value')
.overrideDisplayName('Duration (Avg)')
.matchFieldsWithName('handler')
Expand Down
11 changes: 7 additions & 4 deletions packages/scenes-app/src/monitoring-app/traffic.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,13 +29,10 @@ export function getTrafficScene(): EmbeddedScene {
})
)
.setTitle('Handlers')
.setOption('footer', { enablePagination: true })
.setOverrides((b) =>
b
.matchFieldsWithNameByRegex('.*')
.overrideFilterable(false)
.matchFieldsWithName('Time')
.overrideCustomFieldConfig('hidden', true)
.matchFieldsWithName('Value')
.overrideDisplayName('Duration (Avg)')
.matchFieldsWithName('handler')
Expand Down Expand Up @@ -103,7 +100,13 @@ export class HandlerDrilldownViewBehavior extends SceneObjectBase<HandlerDrilldo
)
.setTitle(`Handler: ${handler} details`)
.setHeaderActions(
<Button size="sm" variant="secondary" icon="times" onClick={() => this.setState({ handler: undefined })} />
<Button
size="sm"
variant="secondary"
icon="times"
aria-label="Close"
onClick={() => this.setState({ handler: undefined })}
/>
)
.build(),
});
Expand Down
8 changes: 8 additions & 0 deletions packages/scenes-app/webpack.config.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import path from 'path';
import type { Configuration } from 'webpack';
import { merge } from 'webpack-merge';
import grafanaConfig from './.config/webpack/webpack.config';
Expand All @@ -14,6 +15,13 @@ const config = (env: any): Configuration => {
publicPath: `public/plugins/${pluginId}/`,
uniqueName: pluginId,
},
resolve: {
fallback: {
fs: false,
'fs/promises': false,
path: false,
},
},
module: {
rules: [
{
Expand Down
10 changes: 5 additions & 5 deletions packages/scenes-react/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -42,11 +42,11 @@
"react-use": "^17.4.0"
},
"peerDependencies": {
"@grafana/data": "^11.0.0",
"@grafana/e2e-selectors": "^11.0.0",
"@grafana/runtime": "^11.0.0",
"@grafana/schema": "^11.0.0",
"@grafana/ui": "^11.0.0",
"@grafana/data": ">=12.3.0",
"@grafana/e2e-selectors": ">=12.3.0",
"@grafana/runtime": ">=12.3.0",
"@grafana/schema": ">=12.3.0",
"@grafana/ui": ">=12.3.0",
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Per https://grafana.com/docs/grafana/latest/upgrade-guide/when-to-upgrade/#what-to-know-about-version-support, I think we need to keep supporting 11.6.x until 2026 June 25. See also: #1213.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's true this wouldn't fully support 11.6 although everything runs locally with GRAFANA_VERSION:-11.1.0-181853 I do wonder if this will become a moot point with the react 19 upgrades that requires 12.3.0 in April.

"react": "^18.0.0",
"react-dom": "^18.0.0",
"react-router-dom": "^6.28.0"
Expand Down
1 change: 1 addition & 0 deletions packages/scenes-react/rollup.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ const plugins = [
export default [
{
input: 'src/index.ts',
treeshake: env === 'development' ? false : true,
plugins: env === 'development' ? [...plugins] : plugins,
output: [
{
Expand Down
2 changes: 2 additions & 0 deletions packages/scenes-react/src/hooks/useDataTransformer.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,8 @@ describe('useDataTransformer', () => {
);
},
},
imageDark: '',
imageLight: '',
});
});

Expand Down
10 changes: 5 additions & 5 deletions packages/scenes/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -48,12 +48,12 @@
"uuid": "^9.0.0"
},
"peerDependencies": {
"@grafana/data": ">=10.4",
"@grafana/e2e-selectors": ">=10.4",
"@grafana/data": ">=12.3.0",
"@grafana/e2e-selectors": ">=12.3.0",
"@grafana/i18n": "*",
"@grafana/runtime": ">=10.4",
"@grafana/schema": ">=10.4",
"@grafana/ui": ">=10.4",
"@grafana/runtime": ">=12.3.0",
"@grafana/schema": ">=12.3.0",
"@grafana/ui": ">=12.3.0",
"react": "^18.0.0",
"react-dom": "^18.0.0",
"react-router-dom": "^6.28.0"
Expand Down
1 change: 1 addition & 0 deletions packages/scenes/rollup.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ const plugins = [
export default [
{
input: 'src/index.ts',
treeshake: env === 'development' ? false : true,
plugins: env === 'development' ? [...plugins] : plugins,
output: [
{
Expand Down
1 change: 0 additions & 1 deletion packages/scenes/src/components/SceneTimePicker.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,6 @@ function SceneTimePickerRenderer({ model }: SceneComponentProps<SceneTimePicker>
fiscalYearStartMonth={timeRangeState.fiscalYearStartMonth}
onMoveBackward={model.onMoveBackward}
onMoveForward={model.onMoveForward}
// @ts-expect-error (temporary till we update grafana/ui)
moveForwardTooltip={
moveForwardDuration
? t('grafana-scenes.components.time-picker.move-forward-tooltip', 'Move {{moveForwardDuration}} forward', {
Expand Down
3 changes: 0 additions & 3 deletions packages/scenes/src/components/VizPanel/VizPanel.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -660,7 +660,6 @@ describe('VizPanel', () => {

pluginToLoad = getTestPlugin1();
pluginToLoad.onPanelMigration = onPanelMigration;
// @ts-expect-error
pluginToLoad.shouldMigrate = shouldMigrate.mockReturnValue(true);

await panel.activate();
Expand All @@ -678,7 +677,6 @@ describe('VizPanel', () => {

pluginToLoad = getTestPlugin1();
pluginToLoad.onPanelMigration = onPanelMigration;
// @ts-expect-error
pluginToLoad.shouldMigrate = shouldMigrate.mockReturnValue(false);

await panel.activate();
Expand All @@ -696,7 +694,6 @@ describe('VizPanel', () => {

pluginToLoad = getTestPlugin1();
pluginToLoad.onPanelMigration = onPanelMigration;
// @ts-expect-error
pluginToLoad.shouldMigrate = shouldMigrate.mockReturnValue(false);

await panel.activate();
Expand Down
1 change: 0 additions & 1 deletion packages/scenes/src/components/VizPanel/VizPanel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -276,7 +276,6 @@ export class VizPanel<TOptions = {}, TFieldConfig extends {} = {}> extends Scene

_UNSAFE_customMigrationHandler?.(panel, plugin);

//@ts-expect-error (TODO: remove after upgrading with https://github.com/grafana/grafana/pull/108998)
const needsMigration = currentVersion !== pluginVersion || plugin.shouldMigrate?.(panel);

if (plugin.onPanelMigration && needsMigration && !isAfterPluginChange) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -288,11 +288,6 @@ exports[`VizPanelBuilder options and field config standard panels defaults provi
exports[`VizPanelBuilder options and field config standard panels defaults provides table defaults 1`] = `
{
"cellHeight": "sm",
"footer": {
"countRows": false,
"reducer": [],
"show": false,
},
"frameIndex": 0,
"showHeader": true,
"showTypeIcons": false,
Expand Down
8 changes: 4 additions & 4 deletions packages/scenes/src/core/SceneTimeRange.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -406,11 +406,11 @@ describe('SceneTimeRange', () => {

expect(timeRange.getTimeZone()).toBe('Africa/Addis_Ababa');

// Verify the time start panel reads the correct start time
expect(timeRange.state.value.from.format('YYYY-MM-DD HH:mm:ss')).toBe('2025-01-01 00:00:00');
// Verify the stored start time is correct (assert in UTC for deterministic test)
expect(timeRange.state.value.from.utc().format('YYYY-MM-DD HH:mm:ss')).toBe('2025-01-01 00:00:00');

// Verify the time picker tooltip reads the correct start time
const tooltipStartTime = timeRange.state.value.from.format('HH:mm:ss');
// Verify the time picker tooltip reads the correct start time (UTC)
const tooltipStartTime = timeRange.state.value.from.utc().format('HH:mm:ss');
expect(tooltipStartTime).toBe('00:00:00');
});
});
Expand Down
4 changes: 0 additions & 4 deletions packages/scenes/src/querying/SceneQueryRunner.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2718,9 +2718,6 @@ describe.each(['11.1.2', '11.1.1'])('SceneQueryRunner', (v) => {
metadata: { name: 'Scope 1' },
spec: {
title: 'Scope 1',
type: 'test',
description: 'Test scope',
category: 'test',
filters: [],
},
},
Expand All @@ -2743,7 +2740,6 @@ describe.each(['11.1.2', '11.1.1'])('SceneQueryRunner', (v) => {
metadata: { name: 'Scope 1' },
spec: {
title: 'Scope 1',
type: 'test',
},
});
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -432,9 +432,6 @@ describe.each(['11.1.2', '11.1.1'])('AnnotationsDataLayer', (v) => {
metadata: { name: `Scope 1` },
spec: {
title: `Scope 1`,
type: 'test',
description: 'Test scope',
category: 'test',
filters: [],
},
},
Expand Down Expand Up @@ -659,9 +656,6 @@ function newScopesVariableFromScopeFilters(filters: ScopeSpecFilter[]) {
metadata: { name: `Scope 1` },
spec: {
title: `Scope 1`,
type: 'test',
description: 'Test scope',
category: 'test',
filters,
},
},
Expand Down
2 changes: 2 additions & 0 deletions packages/scenes/src/utils/mockTransformationsRegistry.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ export const mockTransformationsRegistry = (transformers: Array<DataTransformerI
transformation: t,
description: t.description,
editor: () => null,
imageDark: '',
imageLight: '',
};
});
});
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,5 @@
import React from 'react';
import {
// @ts-expect-error (temporary till we update grafana/data)
DrilldownsApplicability,
store,
} from '@grafana/data';
import { DrilldownsApplicability, store } from '@grafana/data';
import { sceneGraph } from '../../core/sceneGraph';
import { getEnrichedDataRequest } from '../../querying/getEnrichedDataRequest';
import { getQueriesForVariables } from '../utils';
Expand Down
Loading