Skip to content

Commit

Permalink
Update context; Added theme object, notifySuccess & notifyError (#270)
Browse files Browse the repository at this point in the history
* ft: added notifySuccess & notifyError and theme object; added tests; refactoring

* fix: added test for before function

* fix: PR feedback: formating, comments, types

* fix: type Props in Text  import/export fixed

* Formatting

---------

Co-authored-by: Mikhail Volkov <mikhail@volkovlabs.io>
  • Loading branch information
vitPinchuk and mikhail-vl authored Feb 23, 2024
1 parent a1a159d commit 1e902ab
Show file tree
Hide file tree
Showing 9 changed files with 330 additions and 40 deletions.
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
# Changelog

## 4.4.0 (IN PROGRESS)

### Features / Enhancements

- Update context (#270)
- Added theme object, notifySuccess & notifyError (#270)

## 4.3.0 (2023-12-25)

### Features / Enhancements
Expand Down
28 changes: 19 additions & 9 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -81,5 +81,5 @@
"test:ci": "jest --maxWorkers 4 --coverage",
"upgrade": "npm upgrade --save"
},
"version": "4.3.0"
"version": "4.4.0"
}
84 changes: 77 additions & 7 deletions src/components/Row/Row.tsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,24 @@
import { EventBus, InterpolateFunction } from '@grafana/data';
import { locationService } from '@grafana/runtime';
import React, { useEffect, useRef } from 'react';
import {
AlertErrorPayload,
AlertPayload,
AppEvents,
EventBus,
getLocale,
InterpolateFunction,
TimeRange,
} from '@grafana/data';
import { getAppEvents, locationService } from '@grafana/runtime';
import { TimeZone } from '@grafana/schema';
import { useTheme2 } from '@grafana/ui';
import React, { useCallback, useEffect, useRef } from 'react';
import { RowItem } from 'types';

import { TEST_IDS } from '../../constants';
import { RowItem } from '../../types';

/**
* Properties
*/
interface Props {
export interface Props {
/**
* Event Bus
*
Expand Down Expand Up @@ -43,17 +53,59 @@ interface Props {
* @type {string}
*/
afterRender: string;

/**
* Time range of the current dashboard
*
* @type {TimeRange}
*/
timeRange: TimeRange;

/**
* Time zone of the current dashboard
*
* @type {TimeZone}
*/
timeZone: TimeZone;
}

/**
* Row
*/
export const Row: React.FC<Props> = ({ className, item, afterRender, replaceVariables, eventBus }) => {
export const Row: React.FC<Props> = ({
className,
item,
afterRender,
replaceVariables,
eventBus,
timeRange,
timeZone,
}) => {
/**
* Row Ref
*/
const ref = useRef<HTMLDivElement>(null);

/**
* Theme and Styles
*/
const theme = useTheme2();

/**
* Events
*/
const appEvents = getAppEvents();

const notifySuccess = useCallback(
(payload: AlertPayload) => appEvents.publish({ type: AppEvents.alertSuccess.name, payload }),
[appEvents]
);

const notifyError = useCallback(
(payload: AlertErrorPayload) => appEvents.publish({ type: AppEvents.alertError.name, payload }),
[appEvents]
);

/**
* Run After Render Function
*/
Expand All @@ -68,6 +120,12 @@ export const Row: React.FC<Props> = ({ className, item, afterRender, replaceVari
panelData: item.panelData,
dataFrame: item.dataFrame,
grafana: {
theme,
notifySuccess,
notifyError,
timeRange,
timeZone,
getLocale,
replaceVariables,
eventBus,
locationService,
Expand All @@ -80,7 +138,19 @@ export const Row: React.FC<Props> = ({ className, item, afterRender, replaceVari
unsubscribe();
}
};
}, [afterRender, eventBus, item.data, item.dataFrame, item.panelData, replaceVariables]);
}, [
afterRender,
eventBus,
item.data,
item.dataFrame,
item.panelData,
notifyError,
notifySuccess,
replaceVariables,
theme,
timeRange,
timeZone,
]);

return (
<div
Expand Down
112 changes: 110 additions & 2 deletions src/components/Text/Text.test.tsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,37 @@
import { FieldType, toDataFrame } from '@grafana/data';
import { AppEvents, FieldType, toDataFrame } from '@grafana/data';
import { render, screen } from '@testing-library/react';
import React from 'react';

import { DEFAULT_OPTIONS, TEST_IDS } from '../../constants';
import { RenderMode } from '../../types';
import { Props, Text } from './Text';
import { Text } from './Text';
import { getAppEvents } from '@grafana/runtime';

/**
* Mock @grafana/runtime
*/
const appEvents = {
publish: jest.fn(),
};

jest.mock('@grafana/runtime', () => ({
...jest.requireActual('@grafana/runtime'),
getAppEvents: jest.fn().mockImplementation(() => appEvents),
}));

/**
* Props
*/
type Props = React.ComponentProps<typeof Text>;

/**
* Text
*/
describe('Text', () => {
beforeEach(() => {
jest.clearAllMocks();
});

/**
* Default Content
*/
Expand Down Expand Up @@ -90,6 +112,48 @@ describe('Text', () => {
expect(eventBus.publish).toHaveBeenCalledWith('ready', expect.any(HTMLDivElement));
});

it('Should run notify Events', async () => {
const eventBus = {
publish: jest.fn(() => {}),
};
const replaceVariables = jest.fn((str: string) => str);

const publish = jest.fn();
const appEvents = {
publish,
};
jest.mocked(getAppEvents).mockImplementation(() => appEvents as any); // we need only these options

const props: Props = {
data: {} as any,
options: {
...DEFAULT_OPTIONS,
defaultContent: '<div id="element"></div>',
afterRender: `
context.grafana.notifyError(['error']);
context.grafana.notifySuccess(['success'])
`,
renderMode: RenderMode.EVERY_ROW,
},
timeRange: {} as any,
timeZone: '',
replaceVariables,
eventBus: eventBus as any,
};

render(<Text {...props} />);

expect(publish).toHaveBeenCalledTimes(2);
expect(publish).toHaveBeenCalledWith({
type: AppEvents.alertError.name,
payload: ['error'],
});
expect(publish).toHaveBeenCalledWith({
type: AppEvents.alertSuccess.name,
payload: ['success'],
});
});

it('Should call unsubscribe function', async () => {
const eventBus = {
publish: jest.fn(() => {}),
Expand Down Expand Up @@ -123,6 +187,50 @@ describe('Text', () => {
});
});

describe('Before Render Function', () => {
it('Should run notify Events', async () => {
const eventBus = {
publish: jest.fn(() => {}),
};
const replaceVariables = jest.fn((str: string) => str);

const publish = jest.fn();
const appEvents = {
publish,
};
jest.mocked(getAppEvents).mockImplementation(() => appEvents as any); // we need only these options

const props: Props = {
data: {} as any,
options: {
...DEFAULT_OPTIONS,
defaultContent: '<div id="element"></div>',
helpers: `
context.grafana.notifyError(['error']);
context.grafana.notifySuccess(['success'])
`,
renderMode: RenderMode.EVERY_ROW,
},
timeRange: {} as any,
timeZone: '',
replaceVariables,
eventBus: eventBus as any,
};

render(<Text {...props} />);

expect(publish).toHaveBeenCalledTimes(2);
expect(publish).toHaveBeenCalledWith({
type: AppEvents.alertError.name,
payload: ['error'],
});
expect(publish).toHaveBeenCalledWith({
type: AppEvents.alertSuccess.name,
payload: ['success'],
});
});
});

it('Should apply status field', async () => {
const replaceVariables = jest.fn((str: string) => str);
const dataFrame = toDataFrame({
Expand Down
Loading

0 comments on commit 1e902ab

Please sign in to comment.