Skip to content

Commit

Permalink
Add Threshold option for Colors (#208)
Browse files Browse the repository at this point in the history
* colors option updated

* Update CHANGELOG.md

---------

Co-authored-by: Mikhail Volkov <mikhail@volkovlabs.io>
  • Loading branch information
vitPinchuk and mikhail-vl authored Jun 19, 2024
1 parent cc2dc3b commit e42c2cf
Show file tree
Hide file tree
Showing 13 changed files with 132 additions and 19 deletions.
3 changes: 2 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
# Changelog

## 3.3.0 (IN PROGRESS)
## 3.3.0 (2024-06-19)

### Features / Enhancements

- Update variables with static datasource for time range source dashboard (#205)
- Add multiple description fields (#206)
- Add Threshold option for Colors (#208)

## 3.2.0 (2024-06-11)

Expand Down
3 changes: 2 additions & 1 deletion src/constants/options.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,9 @@ export const LINK_OPTIONS = (t: TFunction) => [
* Color Options
*/
export const COLOR_OPTIONS = (t: TFunction) => [
{ value: ColorMode.FRAME, label: t('panelOptions.layout.colors.options.frame') },
{ value: ColorMode.FRAME, label: t('panelOptions.layout.colors.options.frame'), icon: 'database' },
{ value: ColorMode.EVENT, label: t('panelOptions.layout.colors.options.event'), icon: 'calendar-alt' },
{ value: ColorMode.THRESHOLDS, label: t('panelOptions.layout.colors.options.thresholds'), icon: 'circle-mono' },
];

/**
Expand Down
106 changes: 98 additions & 8 deletions src/hooks/useCalendarEvents.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { dateTime, FieldType, getLocaleData } from '@grafana/data';
import { renderHook } from '@testing-library/react';
import dayjs from 'dayjs';

import { ColorMode } from '../types';
import { useCalendarEvents } from './useCalendarEvents';

/**
Expand Down Expand Up @@ -50,7 +51,7 @@ describe('useCalendarEvents', () => {
},
];
const { result } = renderHook(() =>
useCalendarEvents(frames as any, { colors: 'frame' } as any, [], defaultTimeRange, 'browser')
useCalendarEvents(frames as any, { colors: ColorMode.FRAME } as any, [], defaultTimeRange, 'browser')
);

expect(result.current).toEqual(
Expand Down Expand Up @@ -85,7 +86,7 @@ describe('useCalendarEvents', () => {
},
];
const { result } = renderHook(() =>
useCalendarEvents(frames as any, { colors: 'frame' } as any, [], defaultTimeRange, 'browser')
useCalendarEvents(frames as any, { colors: ColorMode.FRAME } as any, [], defaultTimeRange, 'browser')
);

expect(result.current).toEqual(
Expand Down Expand Up @@ -124,7 +125,7 @@ describe('useCalendarEvents', () => {
* UTC-7:00
*/
const { result: result1 } = renderHook(() =>
useCalendarEvents(frames as any, { colors: 'frame' } as any, [], defaultTimeRange, 'America/Phoenix')
useCalendarEvents(frames as any, { colors: ColorMode.FRAME } as any, [], defaultTimeRange, 'America/Phoenix')
);

expect(result1.current).toEqual(
Expand All @@ -141,7 +142,7 @@ describe('useCalendarEvents', () => {
* UTC+10:00
*/
const { result: result2 } = renderHook(() =>
useCalendarEvents(frames as any, { colors: 'frame' } as any, [], defaultTimeRange, 'Australia/Brisbane')
useCalendarEvents(frames as any, { colors: ColorMode.FRAME } as any, [], defaultTimeRange, 'Australia/Brisbane')
);

expect(result2.current).toEqual(
Expand All @@ -158,7 +159,7 @@ describe('useCalendarEvents', () => {
* UTC
*/
const { result: result3 } = renderHook(() =>
useCalendarEvents(frames as any, { colors: 'frame' } as any, [], defaultTimeRange, 'utc')
useCalendarEvents(frames as any, { colors: ColorMode.FRAME } as any, [], defaultTimeRange, 'utc')
);

expect(result3.current).toEqual(
Expand Down Expand Up @@ -194,7 +195,7 @@ describe('useCalendarEvents', () => {
},
];
const { result } = renderHook(() =>
useCalendarEvents(frames as any, { colors: 'frame' } as any, [], defaultTimeRange, 'browser')
useCalendarEvents(frames as any, { colors: ColorMode.FRAME } as any, [], defaultTimeRange, 'browser')
);

expect(result.current).toEqual(
Expand All @@ -219,7 +220,7 @@ describe('useCalendarEvents', () => {
},
];
const { result } = renderHook(() =>
useCalendarEvents(frames as any, { colors: 'frame' } as any, [], defaultTimeRange, 'browser')
useCalendarEvents(frames as any, { colors: ColorMode.FRAME } as any, [], defaultTimeRange, 'browser')
);

expect(result.current).toHaveLength(0);
Expand Down Expand Up @@ -250,7 +251,7 @@ describe('useCalendarEvents', () => {
},
];
const { result } = renderHook(() =>
useCalendarEvents(frames as any, { colors: 'frame' } as any, [], defaultTimeRange, 'browser')
useCalendarEvents(frames as any, { colors: ColorMode.FRAME } as any, [], defaultTimeRange, 'browser')
);

expect(result.current).toEqual(
Expand Down Expand Up @@ -304,4 +305,93 @@ describe('useCalendarEvents', () => {
])
);
});

it('Should return event with override color if thresholds specified', () => {
const frames = [
{
text: {
type: FieldType.string,
name: 'text',
values: ['111'],
getLinks: () => null,
display: () => ({ text: 'displayed' }),
},
start: {
type: FieldType.string,
name: 'start',
values: [getSafeDate()],
},
end: {
type: FieldType.string,
name: 'end',
values: [getSafeDate()],
},
color: {
type: FieldType.number,
name: 'color',
values: ['50'],
getLinks: () => null,
display: () => ({ color: '#FF7383' }),
},
},
];
const { result } = renderHook(() =>
useCalendarEvents(
frames as any,
{ colors: ColorMode.THRESHOLDS } as any,
['#000000', '#ffffff'],
defaultTimeRange,
'browser'
)
);
expect(result.current).toEqual(
expect.arrayContaining([
expect.objectContaining({
color: frames[0].color.display().color,
}),
])
);
});

it('Should return event with color if thresholds is not specified', () => {
const colors = ['#000000', '#ffffff'];
const frames = [
{
text: {
type: FieldType.string,
name: 'text',
values: ['111'],
getLinks: () => null,
display: () => ({ text: 'displayed' }),
},
start: {
type: FieldType.string,
name: 'start',
values: [getSafeDate()],
},
end: {
type: FieldType.string,
name: 'end',
values: [getSafeDate()],
},
color: {
type: FieldType.number,
name: 'color',
values: ['50'],
getLinks: () => null,
display: () => ({ color: '#FF7383' }),
},
},
];
const { result } = renderHook(() =>
useCalendarEvents(frames as any, { colors: ColorMode.FRAME } as any, colors, defaultTimeRange, 'browser')
);
expect(result.current).toEqual(
expect.arrayContaining([
expect.objectContaining({
color: colors[0],
}),
])
);
});
});
4 changes: 3 additions & 1 deletion src/hooks/useCalendarEvents.ts
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,9 @@ export const useCalendarEvents = (
description,
labels,
start: dayjs(start).add(minutesOffset, 'minutes'),
color: colorFn?.(color).color ?? colors[Math.floor(idx % colors.length)],
color:
(options.colors === ColorMode.THRESHOLDS && colorFn?.(color).color) ||
colors[Math.floor(idx % colors.length)],
links,
end: frame.end ? (end ? dayjs(end).add(minutesOffset, 'minutes') : endOfRangeWeek) : undefined,
location,
Expand Down
3 changes: 2 additions & 1 deletion src/i18n/translations/de.json
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,8 @@
"label": "Farben",
"options": {
"event": "Ereignis",
"frame": "Rahmen"
"frame": "Rahmen",
"thresholds": "Schwellenwerte"
}
},
"dateFormat": {
Expand Down
3 changes: 2 additions & 1 deletion src/i18n/translations/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,8 @@
"label": "Colors",
"options": {
"event": "Event",
"frame": "Frame"
"frame": "Frame",
"thresholds": "Thresholds"
}
},
"dateFormat": {
Expand Down
3 changes: 2 additions & 1 deletion src/i18n/translations/es.json
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,8 @@
"label": "Colores",
"options": {
"event": "Evento",
"frame": "Marco"
"frame": "Marco",
"thresholds": "Umbrales"
}
},
"dateFormat": {
Expand Down
3 changes: 2 additions & 1 deletion src/i18n/translations/fr.json
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,8 @@
"label": "Couleurs",
"options": {
"event": "Événement",
"frame": "Cadre"
"frame": "Cadre",
"thresholds": "Seuils"
}
},
"dateFormat": {
Expand Down
3 changes: 2 additions & 1 deletion src/i18n/translations/pt.json
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,8 @@
"label": "Cores",
"options": {
"event": "Evento",
"frame": "Quadro"
"frame": "Quadro",
"thresholds": "Limiares"
}
},
"dateFormat": {
Expand Down
3 changes: 2 additions & 1 deletion src/i18n/translations/zh.json
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,8 @@
"label": "颜色",
"options": {
"event": "事件",
"frame": "框架"
"frame": "框架",
"thresholds": "阈值"
}
},
"dateFormat": {
Expand Down
13 changes: 12 additions & 1 deletion src/module.test.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Field, FieldType, PanelPlugin } from '@grafana/data';
import { CalendarOptions, TimeRangeType } from 'types';
import { CalendarOptions, ColorMode, TimeRangeType } from 'types';

import { plugin } from './module';

Expand Down Expand Up @@ -213,6 +213,17 @@ describe('plugin', () => {
);
});

it('Should show colorField if thresholds is selected', () => {
const shownOptionsPaths: string[] = [];

builder.addFieldNamePicker.mockImplementation(
addInputImplementation({ colors: ColorMode.THRESHOLDS }, shownOptionsPaths)
);
plugin['optionsSupplier'](builder, context);

expect(shownOptionsPaths).toEqual(expect.arrayContaining(['colorField']));
});

it('Should show preformattedDescription if quickLinks is false', () => {
const shownOptionsPaths: string[] = [];

Expand Down
3 changes: 2 additions & 1 deletion src/module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ import {
TIME_RANGE_TYPE_OPTIONS,
} from './constants';
import { getMigratedOptions } from './migration';
import { CalendarOptions, TimeRangeType } from './types';
import { CalendarOptions, ColorMode, TimeRangeType } from './types';
import { getLanguage } from './utils';

/**
Expand Down Expand Up @@ -274,6 +274,7 @@ export const plugin = new PanelPlugin<CalendarOptions>(CalendarPanel)
settings: {
filter: (f: Field) => [FieldType.string, FieldType.number].includes(f.type),
},
showIf: (config) => config.colors === ColorMode.THRESHOLDS,
});

/**
Expand Down
1 change: 1 addition & 0 deletions src/types/panel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ export type SupportedLanguage =
export const enum ColorMode {
FRAME = 'frame',
EVENT = 'event',
THRESHOLDS = 'thresholds',
}

/**
Expand Down

0 comments on commit e42c2cf

Please sign in to comment.