Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update context; Added theme object, notifySuccess & notifyError #270

Merged
merged 5 commits into from
Feb 23, 2024
Merged
Show file tree
Hide file tree
Changes from 4 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
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.

83 changes: 76 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 {
/**
asimonok marked this conversation as resolved.
Show resolved Hide resolved
* Event Bus
*
Expand Down Expand Up @@ -43,17 +53,58 @@ 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 +119,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 +137,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', () => ({
asimonok marked this conversation as resolved.
Show resolved Hide resolved
...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} />);

asimonok marked this conversation as resolved.
Show resolved Hide resolved
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
Loading