From ad5690ca205cbe2b63ff2e353f473c1e3ee59c76 Mon Sep 17 00:00:00 2001 From: vitPinchuk Date: Fri, 23 Feb 2024 12:34:14 +0300 Subject: [PATCH 1/8] ft added css support for containers and rows --- package-lock.json | 28 +++++++++++++++++--------- src/components/Text/Text.tsx | 3 ++- src/components/TextPanel/TextPanel.tsx | 13 ++++++++++-- 3 files changed, 32 insertions(+), 12 deletions(-) diff --git a/package-lock.json b/package-lock.json index 4d7a7c3..5552a18 100644 --- a/package-lock.json +++ b/package-lock.json @@ -39,7 +39,7 @@ "@swc/core": "^1.3.96", "@swc/helpers": "^0.5.3", "@swc/jest": "^0.2.29", - "@testing-library/jest-dom": "^6.1.4", + "@testing-library/jest-dom": "^6.1.5", "@testing-library/react": "^14.1.2", "@types/jest": "^29.5.8", "@types/lodash": "^4.14.201", @@ -82,9 +82,9 @@ } }, "node_modules/@adobe/css-tools": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/@adobe/css-tools/-/css-tools-4.3.1.tgz", - "integrity": "sha512-/62yikz7NLScCGAAST5SHdnjaDJQBDq0M2muyRTpf2VQhw6StBg2ALiu73zSJQ4fMVLA+0uBhBHAle7Wg+2kSg==", + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/@adobe/css-tools/-/css-tools-4.3.3.tgz", + "integrity": "sha512-rE0Pygv0sEZ4vBWHlAgJLGDU7Pm8xoO6p3wsEceb7GYAjScrOHpEo8KK/eVkAcnSM+slAEtXjA2JpdjLp4fJQQ==", "dev": true }, "node_modules/@ampproject/remapping": { @@ -5713,17 +5713,17 @@ } }, "node_modules/@testing-library/jest-dom": { - "version": "6.1.4", - "resolved": "https://registry.npmjs.org/@testing-library/jest-dom/-/jest-dom-6.1.4.tgz", - "integrity": "sha512-wpoYrCYwSZ5/AxcrjLxJmCU6I5QAJXslEeSiMQqaWmP2Kzpd1LvF/qxmAIW2qposULGWq2gw30GgVNFLSc2Jnw==", + "version": "6.4.2", + "resolved": "https://registry.npmjs.org/@testing-library/jest-dom/-/jest-dom-6.4.2.tgz", + "integrity": "sha512-CzqH0AFymEMG48CpzXFriYYkOjk6ZGPCLMhW9e9jg3KMCn5OfJecF8GtGW7yGfR/IgCe3SX8BSwjdzI6BBbZLw==", "dev": true, "dependencies": { - "@adobe/css-tools": "^4.3.1", + "@adobe/css-tools": "^4.3.2", "@babel/runtime": "^7.9.2", "aria-query": "^5.0.0", "chalk": "^3.0.0", "css.escape": "^1.5.1", - "dom-accessibility-api": "^0.5.6", + "dom-accessibility-api": "^0.6.3", "lodash": "^4.17.15", "redent": "^3.0.0" }, @@ -5734,6 +5734,7 @@ }, "peerDependencies": { "@jest/globals": ">= 28", + "@types/bun": "latest", "@types/jest": ">= 28", "jest": ">= 28", "vitest": ">= 0.32" @@ -5742,6 +5743,9 @@ "@jest/globals": { "optional": true }, + "@types/bun": { + "optional": true + }, "@types/jest": { "optional": true }, @@ -5799,6 +5803,12 @@ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true }, + "node_modules/@testing-library/jest-dom/node_modules/dom-accessibility-api": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/dom-accessibility-api/-/dom-accessibility-api-0.6.3.tgz", + "integrity": "sha512-7ZgogeTnjuHbo+ct10G9Ffp0mif17idi0IyWNVA/wcwcm7NPOD/WEHVP3n7n3MhXqxoIYm8d6MuZohYWIZ4T3w==", + "dev": true + }, "node_modules/@testing-library/jest-dom/node_modules/has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", diff --git a/src/components/Text/Text.tsx b/src/components/Text/Text.tsx index 4ef1bb3..95f46a0 100644 --- a/src/components/Text/Text.tsx +++ b/src/components/Text/Text.tsx @@ -95,7 +95,8 @@ export const Text: React.FC = ({ styles.frame, css` ${options.styles ? replaceVariables(options.styles) : ''} - ` + `, + 'dt-row' ); /** diff --git a/src/components/TextPanel/TextPanel.tsx b/src/components/TextPanel/TextPanel.tsx index 2092989..0594df0 100644 --- a/src/components/TextPanel/TextPanel.tsx +++ b/src/components/TextPanel/TextPanel.tsx @@ -1,4 +1,4 @@ -import { css, cx } from '@emotion/css'; +import { css, cx, injectGlobal } from '@emotion/css'; import { PanelProps, SelectableValue } from '@grafana/data'; import { RefreshEvent } from '@grafana/runtime'; import { Select, useStyles2 } from '@grafana/ui'; @@ -26,6 +26,7 @@ export const TextPanel: React.FC = ({ timeRange, timeZone, eventBus, + id, replaceVariables, }) => { /** @@ -38,6 +39,12 @@ export const TextPanel: React.FC = ({ * Styles */ const styles = useStyles2(getStyles); + const panelStyles = options.styles ? replaceVariables(options.styles) : ''; + + /** + * Injects styles into the global scope (need for dt-row-___ classes) + */ + injectGlobal(panelStyles); /** * Change Frame @@ -121,7 +128,9 @@ export const TextPanel: React.FC = ({ css` flex-grow: 1; overflow: auto; - ` + `, + 'dt-row-container', + `dt-row-container-${id}` )} > Date: Fri, 23 Feb 2024 13:35:32 +0300 Subject: [PATCH 2/8] fix: test for injectGlobal --- src/components/TextPanel/TextPanel.test.tsx | 43 +++++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/src/components/TextPanel/TextPanel.test.tsx b/src/components/TextPanel/TextPanel.test.tsx index c4a7d82..9c45258 100644 --- a/src/components/TextPanel/TextPanel.test.tsx +++ b/src/components/TextPanel/TextPanel.test.tsx @@ -6,6 +6,7 @@ import React from 'react'; import { CodeLanguage, Format, TEST_IDS } from '../../constants'; import { PanelOptions, RenderMode } from '../../types'; import { TextPanel } from './TextPanel'; +import { injectGlobal } from '@emotion/css'; /** * Props @@ -19,6 +20,14 @@ jest.mock('@grafana/runtime', () => ({ ...jest.requireActual('@grafana/runtime'), })); +/** + * Mock @emotion/css + */ +jest.mock('@emotion/css', () => ({ + ...jest.requireActual('@emotion/css'), + injectGlobal: jest.fn(), +})); + /** * Mock @grafana/ui */ @@ -159,6 +168,40 @@ describe('Panel', () => { expect(streamSubscribe).toHaveBeenCalled(); }); + it('Should apply css for component', async () => { + jest.mocked(injectGlobal); + + const streamSubscribe = jest.fn(() => ({ + unsubscribe: jest.fn(), + })); + + const eventBus = { + getStream: jest.fn(() => ({ + subscribe: streamSubscribe, + })), + }; + + await act(async () => + render( + getComponent({ + options: { + ...defaultOptions, + defaultContent: 'hello', + styles: 'styles-test', + }, + replaceVariables: (str: string) => str, + data: { series: [] } as any, + eventBus: eventBus as any, + }) + ) + ); + + expect(screen.getByTestId(TEST_IDS.panel.root)).toBeInTheDocument(); + expect(injectGlobal).toHaveBeenCalledTimes(2); + expect(injectGlobal).toHaveBeenCalledWith(''); + expect(injectGlobal).toHaveBeenCalledWith('styles-test'); + }); + describe('Helpers execution', () => { const helpers = ` const subscription = eventBus.subscribe('event', () => {}); From e5c875aaf4d0de60635b6c1f6ea14c97f7529ab3 Mon Sep 17 00:00:00 2001 From: vitPinchuk Date: Fri, 23 Feb 2024 14:01:49 +0300 Subject: [PATCH 3/8] fix: added test cases to check classes in document on elements --- src/components/TextPanel/TextPanel.test.tsx | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/src/components/TextPanel/TextPanel.test.tsx b/src/components/TextPanel/TextPanel.test.tsx index 9c45258..7f1e975 100644 --- a/src/components/TextPanel/TextPanel.test.tsx +++ b/src/components/TextPanel/TextPanel.test.tsx @@ -187,19 +187,31 @@ describe('Panel', () => { options: { ...defaultOptions, defaultContent: 'hello', - styles: 'styles-test', + styles: '.styles-test{}', }, replaceVariables: (str: string) => str, data: { series: [] } as any, eventBus: eventBus as any, + id: 5, }) ) ); - expect(screen.getByTestId(TEST_IDS.panel.root)).toBeInTheDocument(); + const panel = screen.getByTestId(TEST_IDS.panel.root); + expect(panel).toBeInTheDocument(); + + const rowContainerIdClass = panel.querySelectorAll('.dt-row-container-5'); + expect(rowContainerIdClass.length).toBeGreaterThan(0); + + const rowContainerClass = panel.querySelectorAll('.dt-row-container'); + expect(rowContainerClass.length).toBeGreaterThan(0); + + const rowClass = panel.querySelectorAll('.dt-row'); + expect(rowClass.length).toBeGreaterThan(0); + expect(injectGlobal).toHaveBeenCalledTimes(2); expect(injectGlobal).toHaveBeenCalledWith(''); - expect(injectGlobal).toHaveBeenCalledWith('styles-test'); + expect(injectGlobal).toHaveBeenCalledWith('.styles-test{}'); }); describe('Helpers execution', () => { From 4de0d2f167c8683c97bf152e89b20070a9bce572 Mon Sep 17 00:00:00 2001 From: Mikhail Volkov Date: Sun, 25 Feb 2024 21:51:15 -0500 Subject: [PATCH 4/8] Update to Node 20 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 7b43457..0658550 100644 --- a/package.json +++ b/package.json @@ -62,7 +62,7 @@ "webpack-livereload-plugin": "^3.0.2" }, "engines": { - "node": ">=18" + "node": ">=20" }, "license": "Apache-2.0", "name": "marcusolsson-dynamictext-panel", From eee6b8008345f2797eb7208bae7643abd1145ebb Mon Sep 17 00:00:00 2001 From: vitPinchuk Date: Mon, 26 Feb 2024 11:48:28 +0300 Subject: [PATCH 5/8] fix: use Global instead injectGlobal; rename dt-row-container to dt-container --- package-lock.json | 2 +- src/components/TextPanel/TextPanel.test.tsx | 19 +--- src/components/TextPanel/TextPanel.tsx | 101 ++++++++++---------- 3 files changed, 53 insertions(+), 69 deletions(-) diff --git a/package-lock.json b/package-lock.json index 965046c..6ab052c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -69,7 +69,7 @@ "webpack-livereload-plugin": "^3.0.2" }, "engines": { - "node": ">=18" + "node": ">=20" } }, "node_modules/@aashutoshrathi/word-wrap": { diff --git a/src/components/TextPanel/TextPanel.test.tsx b/src/components/TextPanel/TextPanel.test.tsx index 7f1e975..0859184 100644 --- a/src/components/TextPanel/TextPanel.test.tsx +++ b/src/components/TextPanel/TextPanel.test.tsx @@ -6,7 +6,6 @@ import React from 'react'; import { CodeLanguage, Format, TEST_IDS } from '../../constants'; import { PanelOptions, RenderMode } from '../../types'; import { TextPanel } from './TextPanel'; -import { injectGlobal } from '@emotion/css'; /** * Props @@ -20,14 +19,6 @@ jest.mock('@grafana/runtime', () => ({ ...jest.requireActual('@grafana/runtime'), })); -/** - * Mock @emotion/css - */ -jest.mock('@emotion/css', () => ({ - ...jest.requireActual('@emotion/css'), - injectGlobal: jest.fn(), -})); - /** * Mock @grafana/ui */ @@ -169,8 +160,6 @@ describe('Panel', () => { }); it('Should apply css for component', async () => { - jest.mocked(injectGlobal); - const streamSubscribe = jest.fn(() => ({ unsubscribe: jest.fn(), })); @@ -200,18 +189,14 @@ describe('Panel', () => { const panel = screen.getByTestId(TEST_IDS.panel.root); expect(panel).toBeInTheDocument(); - const rowContainerIdClass = panel.querySelectorAll('.dt-row-container-5'); + const rowContainerIdClass = panel.querySelectorAll('.dt-container-5'); expect(rowContainerIdClass.length).toBeGreaterThan(0); - const rowContainerClass = panel.querySelectorAll('.dt-row-container'); + const rowContainerClass = panel.querySelectorAll('.dt-container'); expect(rowContainerClass.length).toBeGreaterThan(0); const rowClass = panel.querySelectorAll('.dt-row'); expect(rowClass.length).toBeGreaterThan(0); - - expect(injectGlobal).toHaveBeenCalledTimes(2); - expect(injectGlobal).toHaveBeenCalledWith(''); - expect(injectGlobal).toHaveBeenCalledWith('.styles-test{}'); }); describe('Helpers execution', () => { diff --git a/src/components/TextPanel/TextPanel.tsx b/src/components/TextPanel/TextPanel.tsx index 0594df0..38005cf 100644 --- a/src/components/TextPanel/TextPanel.tsx +++ b/src/components/TextPanel/TextPanel.tsx @@ -1,4 +1,5 @@ -import { css, cx, injectGlobal } from '@emotion/css'; +import { css, cx } from '@emotion/css'; +import { Global } from '@emotion/react'; import { PanelProps, SelectableValue } from '@grafana/data'; import { RefreshEvent } from '@grafana/runtime'; import { Select, useStyles2 } from '@grafana/ui'; @@ -41,11 +42,6 @@ export const TextPanel: React.FC = ({ const styles = useStyles2(getStyles); const panelStyles = options.styles ? replaceVariables(options.styles) : ''; - /** - * Injects styles into the global scope (need for dt-row-___ classes) - */ - injectGlobal(panelStyles); - /** * Change Frame */ @@ -110,52 +106,55 @@ export const TextPanel: React.FC = ({ * Return */ return ( -
- {isScriptsLoaded && ( - <> -
- -
- - {options.renderMode !== RenderMode.DATA && data.series.length > 1 && ( -
- +
+ )} + + )} +
+ ); }; From e75b9ee333f33b8dc90051de5ee8382b4be6c596 Mon Sep 17 00:00:00 2001 From: vitPinchuk Date: Tue, 27 Feb 2024 09:32:09 +0300 Subject: [PATCH 6/8] fix: Styles updated --- src/components/TextPanel/TextPanel.test.tsx | 6 -- src/components/TextPanel/TextPanel.tsx | 97 ++++++++++----------- 2 files changed, 46 insertions(+), 57 deletions(-) diff --git a/src/components/TextPanel/TextPanel.test.tsx b/src/components/TextPanel/TextPanel.test.tsx index 0859184..443046b 100644 --- a/src/components/TextPanel/TextPanel.test.tsx +++ b/src/components/TextPanel/TextPanel.test.tsx @@ -189,12 +189,6 @@ describe('Panel', () => { const panel = screen.getByTestId(TEST_IDS.panel.root); expect(panel).toBeInTheDocument(); - const rowContainerIdClass = panel.querySelectorAll('.dt-container-5'); - expect(rowContainerIdClass.length).toBeGreaterThan(0); - - const rowContainerClass = panel.querySelectorAll('.dt-container'); - expect(rowContainerClass.length).toBeGreaterThan(0); - const rowClass = panel.querySelectorAll('.dt-row'); expect(rowClass.length).toBeGreaterThan(0); }); diff --git a/src/components/TextPanel/TextPanel.tsx b/src/components/TextPanel/TextPanel.tsx index 38005cf..5a9ae72 100644 --- a/src/components/TextPanel/TextPanel.tsx +++ b/src/components/TextPanel/TextPanel.tsx @@ -1,5 +1,4 @@ import { css, cx } from '@emotion/css'; -import { Global } from '@emotion/react'; import { PanelProps, SelectableValue } from '@grafana/data'; import { RefreshEvent } from '@grafana/runtime'; import { Select, useStyles2 } from '@grafana/ui'; @@ -27,7 +26,6 @@ export const TextPanel: React.FC = ({ timeRange, timeZone, eventBus, - id, replaceVariables, }) => { /** @@ -40,7 +38,6 @@ export const TextPanel: React.FC = ({ * Styles */ const styles = useStyles2(getStyles); - const panelStyles = options.styles ? replaceVariables(options.styles) : ''; /** * Change Frame @@ -106,55 +103,53 @@ export const TextPanel: React.FC = ({ * Return */ return ( - <> - -
- {isScriptsLoaded && ( - <> -
- + {isScriptsLoaded && ( + <> +
+ +
+ + {options.renderMode !== RenderMode.DATA && data.series.length > 1 && ( +
+ -
- )} - - )} -
- + )} + + )} +
); }; From ab59b9f6a753b64b9f371d80b9e971cecdc7555b Mon Sep 17 00:00:00 2001 From: vitPinchuk Date: Thu, 29 Feb 2024 10:09:58 +0300 Subject: [PATCH 7/8] fix: remove options.styles from Text.tsx component for rows --- src/components/Text/Text.test.tsx | 28 --------------------- src/components/Text/Text.tsx | 11 ++------ src/components/TextPanel/TextPanel.test.tsx | 11 ++++++-- 3 files changed, 11 insertions(+), 39 deletions(-) diff --git a/src/components/Text/Text.test.tsx b/src/components/Text/Text.test.tsx index 9b16a5f..1861a37 100644 --- a/src/components/Text/Text.test.tsx +++ b/src/components/Text/Text.test.tsx @@ -56,34 +56,6 @@ describe('Text', () => { expect(screen.getByTestId(TEST_IDS.text.content)).toHaveTextContent('Test default content'); }); - it('Should apply styles', async () => { - const styles = ` - color: red; - `; - const replaceVariables = jest.fn((str: string) => str); - const props: Props = { - data: {} as any, - options: { - ...DEFAULT_OPTIONS, - content: 'Test content', - defaultContent: 'Test default content', - renderMode: RenderMode.EVERY_ROW, - styles, - }, - timeRange: {} as any, - timeZone: '', - replaceVariables, - eventBus: {} as any, - }; - - render(); - - expect(replaceVariables).toHaveBeenCalledWith(styles); - - expect(screen.getByTestId(TEST_IDS.text.content)).toBeInTheDocument(); - expect(screen.getByTestId(TEST_IDS.text.content)).toHaveStyle({ color: 'red' }); - }); - describe('After Render Function', () => { it('Should run after render function', async () => { const eventBus = { diff --git a/src/components/Text/Text.tsx b/src/components/Text/Text.tsx index af70027..c547909 100644 --- a/src/components/Text/Text.tsx +++ b/src/components/Text/Text.tsx @@ -1,4 +1,4 @@ -import { css, cx } from '@emotion/css'; +import { cx } from '@emotion/css'; import { AlertErrorPayload, AlertPayload, @@ -105,14 +105,7 @@ export const Text: React.FC = ({ * Styles */ const styles = useStyles2(getStyles); - const className = cx( - styles.highlight, - styles.frame, - css` - ${options.styles ? replaceVariables(options.styles) : ''} - `, - 'dt-row' - ); + const className = cx(styles.highlight, styles.frame, 'dt-row'); /** * Events diff --git a/src/components/TextPanel/TextPanel.test.tsx b/src/components/TextPanel/TextPanel.test.tsx index 443046b..95f993b 100644 --- a/src/components/TextPanel/TextPanel.test.tsx +++ b/src/components/TextPanel/TextPanel.test.tsx @@ -170,15 +170,17 @@ describe('Panel', () => { })), }; + const replaceVariables = jest.fn((str: string) => str); + await act(async () => render( getComponent({ options: { ...defaultOptions, defaultContent: 'hello', - styles: '.styles-test{}', + styles: '.styles-test{}; .dt-row{color:red}', }, - replaceVariables: (str: string) => str, + replaceVariables, data: { series: [] } as any, eventBus: eventBus as any, id: 5, @@ -186,11 +188,16 @@ describe('Panel', () => { ) ); + expect(replaceVariables).toHaveBeenCalledWith('.styles-test{}; .dt-row{color:red}'); + const panel = screen.getByTestId(TEST_IDS.panel.root); expect(panel).toBeInTheDocument(); const rowClass = panel.querySelectorAll('.dt-row'); expect(rowClass.length).toBeGreaterThan(0); + + expect(screen.getByTestId(TEST_IDS.text.content)).toBeInTheDocument(); + expect(screen.getByTestId(TEST_IDS.text.content)).toHaveStyle({ color: 'red' }); }); describe('Helpers execution', () => { From 6a0d806a8d410c6e51d20a796408824be3068b5b Mon Sep 17 00:00:00 2001 From: Mikhail Volkov Date: Wed, 6 Mar 2024 00:38:26 -0500 Subject: [PATCH 8/8] Update CHANGELOG.md --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 316d25c..2a36ea3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,7 @@ - Added theme object, notifySuccess & notifyError (#270) - Update dependencies and Actions (#271) - Replace custom code parameters with Code Parameters Builder (#285) +- Update CSS class for the Panel instead of a Row (#272) ## 4.3.0 (2023-12-25)