mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
183 lines
4.6 KiB
TypeScript
183 lines
4.6 KiB
TypeScript
import { css } from '@emotion/css';
|
|
import React from 'react';
|
|
|
|
import { GrafanaTheme2 } from '@grafana/data';
|
|
import { ColorDimensionConfig, ScalarDimensionConfig } from '@grafana/schema';
|
|
import config from 'app/core/config';
|
|
import { DimensionContext } from 'app/features/dimensions';
|
|
import { ColorDimensionEditor, ScalarDimensionEditor } from 'app/features/dimensions/editors';
|
|
|
|
import { CanvasElementItem, CanvasElementProps } from '../../element';
|
|
|
|
import { ServerDatabase } from './types/database';
|
|
import { ServerSingle } from './types/single';
|
|
import { ServerStack } from './types/stack';
|
|
import { ServerTerminal } from './types/terminal';
|
|
|
|
interface ServerConfig {
|
|
blinkRate?: ScalarDimensionConfig;
|
|
statusColor?: ColorDimensionConfig;
|
|
bulbColor?: ColorDimensionConfig;
|
|
type: ServerType;
|
|
}
|
|
|
|
export interface ServerData {
|
|
blinkRate?: number;
|
|
statusColor?: string;
|
|
bulbColor?: string;
|
|
type: ServerType;
|
|
}
|
|
|
|
enum ServerType {
|
|
Single = 'Single',
|
|
Stack = 'Stack',
|
|
Database = 'Database',
|
|
Terminal = 'Terminal',
|
|
}
|
|
|
|
type Props = CanvasElementProps<ServerConfig, ServerData>;
|
|
const outlineColor = config.theme2.colors.text.primary;
|
|
|
|
const ServerDisplay = ({ data }: Props) => {
|
|
return data ? (
|
|
<svg viewBox="0 0 75 75">
|
|
{data.type === ServerType.Single ? (
|
|
<ServerSingle {...data} />
|
|
) : data.type === ServerType.Stack ? (
|
|
<ServerStack {...data} />
|
|
) : data.type === ServerType.Database ? (
|
|
<ServerDatabase {...data} />
|
|
) : data.type === ServerType.Terminal ? (
|
|
<ServerTerminal {...data} />
|
|
) : null}
|
|
</svg>
|
|
) : null;
|
|
};
|
|
|
|
export const serverItem: CanvasElementItem<ServerConfig, ServerData> = {
|
|
id: 'server',
|
|
name: 'Server',
|
|
description: 'Basic server with status',
|
|
|
|
display: ServerDisplay,
|
|
|
|
defaultSize: {
|
|
width: 100,
|
|
height: 100,
|
|
},
|
|
|
|
getNewOptions: (options) => ({
|
|
...options,
|
|
background: {
|
|
color: {
|
|
fixed: 'transparent',
|
|
},
|
|
},
|
|
placement: {
|
|
width: options?.placement?.width ?? 100,
|
|
height: options?.placement?.height ?? 100,
|
|
top: options?.placement?.top,
|
|
left: options?.placement?.left,
|
|
},
|
|
config: {
|
|
type: ServerType.Single,
|
|
},
|
|
}),
|
|
|
|
// Called when data changes
|
|
prepareData: (ctx: DimensionContext, cfg: ServerConfig) => {
|
|
const data: ServerData = {
|
|
blinkRate: cfg?.blinkRate ? ctx.getScalar(cfg.blinkRate).value() : 0,
|
|
statusColor: cfg?.statusColor ? ctx.getColor(cfg.statusColor).value() : 'transparent',
|
|
bulbColor: cfg?.bulbColor ? ctx.getColor(cfg.bulbColor).value() : 'green',
|
|
type: cfg.type,
|
|
};
|
|
|
|
return data;
|
|
},
|
|
|
|
registerOptionsUI: (builder) => {
|
|
const category = ['Server'];
|
|
builder
|
|
.addSelect({
|
|
category,
|
|
path: 'config.type',
|
|
name: 'Type',
|
|
settings: {
|
|
options: [
|
|
{ value: ServerType.Single, label: ServerType.Single },
|
|
{ value: ServerType.Stack, label: ServerType.Stack },
|
|
{ value: ServerType.Database, label: ServerType.Database },
|
|
{ value: ServerType.Terminal, label: ServerType.Terminal },
|
|
],
|
|
},
|
|
defaultValue: ServerType.Single,
|
|
})
|
|
.addCustomEditor({
|
|
category,
|
|
id: 'statusColor',
|
|
path: 'config.statusColor',
|
|
name: 'Status color',
|
|
editor: ColorDimensionEditor,
|
|
settings: {},
|
|
defaultValue: {
|
|
fixed: 'transparent',
|
|
},
|
|
})
|
|
.addCustomEditor({
|
|
category,
|
|
id: 'bulbColor',
|
|
path: 'config.bulbColor',
|
|
name: 'Bulb color',
|
|
editor: ColorDimensionEditor,
|
|
settings: {},
|
|
defaultValue: {
|
|
fixed: 'green',
|
|
},
|
|
})
|
|
.addCustomEditor({
|
|
category,
|
|
id: 'blinkRate',
|
|
path: 'config.blinkRate',
|
|
name: 'Blink rate [hz] (0 = off)',
|
|
editor: ScalarDimensionEditor,
|
|
settings: { min: 0, max: 100 },
|
|
});
|
|
},
|
|
};
|
|
|
|
export const getServerStyles = (data: ServerData | undefined) => (theme: GrafanaTheme2) => ({
|
|
bulb: css({
|
|
'@keyframes blink': {
|
|
'0%': {
|
|
fillOpacity: 0,
|
|
},
|
|
'50%': {
|
|
fillOpacity: 1,
|
|
},
|
|
'100%': {
|
|
fillOpacity: 0,
|
|
},
|
|
},
|
|
}),
|
|
server: css({
|
|
fill: data?.statusColor ?? 'transparent',
|
|
}),
|
|
circle: css({
|
|
animation: `blink ${data?.blinkRate ? 1 / data.blinkRate : 0}s infinite step-end`,
|
|
fill: data?.bulbColor,
|
|
stroke: 'none',
|
|
}),
|
|
circleBack: css({
|
|
fill: outlineColor,
|
|
stroke: 'none',
|
|
opacity: 1,
|
|
}),
|
|
outline: css({
|
|
stroke: outlineColor,
|
|
strokeLinecap: 'round',
|
|
strokeLinejoin: 'round',
|
|
strokeWidth: '4px',
|
|
}),
|
|
});
|