internationalisation: Mark up canvas panel edit options (#107118)

mark up canvas panel
pull/106618/head
Ashley Harrison 2 days ago committed by GitHub
parent d872a74d1c
commit 2837f8fb58
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
  1. 14
      public/app/features/canvas/elements/button.tsx
  2. 12
      public/app/features/canvas/elements/cloud.tsx
  3. 5
      public/app/features/canvas/elements/droneFront.tsx
  4. 5
      public/app/features/canvas/elements/droneSide.tsx
  5. 13
      public/app/features/canvas/elements/droneTop.tsx
  6. 12
      public/app/features/canvas/elements/ellipse.tsx
  7. 7
      public/app/features/canvas/elements/icon.tsx
  8. 12
      public/app/features/canvas/elements/metricValue.tsx
  9. 12
      public/app/features/canvas/elements/parallelogram.tsx
  10. 12
      public/app/features/canvas/elements/rectangle.tsx
  11. 19
      public/app/features/canvas/elements/server/server.tsx
  12. 12
      public/app/features/canvas/elements/text.tsx
  13. 12
      public/app/features/canvas/elements/triangle.tsx
  14. 5
      public/app/features/canvas/elements/windTurbine.tsx
  15. 22
      public/app/features/dimensions/editors/BackgroundSizeEditor.tsx
  16. 17
      public/app/features/dimensions/editors/ColorDimensionEditor.tsx
  17. 19
      public/app/features/dimensions/editors/ResourceDimensionEditor.tsx
  18. 41
      public/app/features/dimensions/editors/ScalarDimensionEditor.tsx
  19. 19
      public/app/features/dimensions/editors/TextDimensionEditor.tsx
  20. 40
      public/app/plugins/panel/canvas/editor/element/PlacementEditor.tsx
  21. 10
      public/app/plugins/panel/canvas/editor/element/elementEditor.tsx
  22. 6
      public/app/plugins/panel/canvas/editor/inline/InlineEditBody.tsx
  23. 9
      public/app/plugins/panel/canvas/editor/layer/layerEditor.tsx
  24. 57
      public/app/plugins/panel/canvas/editor/options.ts
  25. 35
      public/app/plugins/panel/canvas/module.tsx
  26. 182
      public/locales/en-US/grafana.json

@ -164,27 +164,27 @@ export const buttonItem: CanvasElementItem<ButtonConfig, ButtonData> = {
// Heatmap overlay options
registerOptionsUI: (builder) => {
const category = ['Button'];
const category = [t('canvas.button-item.category-button', 'Button')];
builder
.addCustomEditor({
category,
id: 'styleSelector',
path: 'config.style',
name: 'Style',
name: t('canvas.button-item.name-style', 'Style'),
editor: ButtonStyleEditor,
})
.addCustomEditor({
category,
id: 'textSelector',
path: 'config.text',
name: 'Text',
name: t('canvas.button-item.name-text', 'Text'),
editor: TextDimensionEditor,
})
.addCustomEditor({
category,
id: 'config.color',
path: 'config.color',
name: 'Text color',
name: t('canvas.button-item.name-text-color', 'Text color'),
editor: ColorDimensionEditor,
settings: {},
defaultValue: {},
@ -192,7 +192,7 @@ export const buttonItem: CanvasElementItem<ButtonConfig, ButtonData> = {
.addRadio({
category,
path: 'config.align',
name: 'Align text',
name: t('canvas.button-item.name-align-text', 'Align text'),
settings: {
options: [
{ value: Align.Left, label: t('canvas.button-item.label.left', 'Left') },
@ -205,7 +205,7 @@ export const buttonItem: CanvasElementItem<ButtonConfig, ButtonData> = {
.addNumberInput({
category,
path: 'config.size',
name: 'Text size',
name: t('canvas.button-item.name-text-size', 'Text size'),
settings: {
placeholder: t('canvas.button-item.placeholder.auto', 'Auto'),
},
@ -214,7 +214,7 @@ export const buttonItem: CanvasElementItem<ButtonConfig, ButtonData> = {
category,
id: 'apiSelector',
path: 'config.api',
name: 'API',
name: t('canvas.button-item.name-api', 'API'),
editor: APIEditor,
});
},

@ -130,20 +130,20 @@ export const cloudItem: CanvasElementItem = {
},
registerOptionsUI: (builder) => {
const category = ['Cloud'];
const category = [t('canvas.cloud-item.category-cloud', 'Cloud')];
builder
.addCustomEditor({
category,
id: 'textSelector',
path: 'config.text',
name: 'Text',
name: t('canvas.cloud-item.name-text', 'Text'),
editor: TextDimensionEditor,
})
.addCustomEditor({
category,
id: 'config.color',
path: 'config.color',
name: 'Text color',
name: t('canvas.cloud-item.name-text-color', 'Text color'),
editor: ColorDimensionEditor,
settings: {},
defaultValue: {},
@ -151,7 +151,7 @@ export const cloudItem: CanvasElementItem = {
.addRadio({
category,
path: 'config.align',
name: 'Align text',
name: t('canvas.cloud-item.name-align-text', 'Align text'),
settings: {
options: [
{ value: Align.Left, label: t('canvas.cloud-item.label.left', 'Left') },
@ -164,7 +164,7 @@ export const cloudItem: CanvasElementItem = {
.addRadio({
category,
path: 'config.valign',
name: 'Vertical align',
name: t('canvas.cloud-item.name-vertical-align', 'Vertical align'),
settings: {
options: [
{ value: VAlign.Top, label: t('canvas.cloud-item.label.top', 'Top') },
@ -177,7 +177,7 @@ export const cloudItem: CanvasElementItem = {
.addNumberInput({
category,
path: 'config.size',
name: 'Text size',
name: t('canvas.cloud-item.name-text-size', 'Text size'),
settings: {
placeholder: t('canvas.cloud-item.placeholder.auto', 'Auto'),
},

@ -1,6 +1,7 @@
import { css } from '@emotion/css';
import { GrafanaTheme2 } from '@grafana/data';
import { t } from '@grafana/i18n';
import { ScalarDimensionConfig } from '@grafana/schema';
import { useStyles2 } from '@grafana/ui';
import { DimensionContext } from 'app/features/dimensions';
@ -109,12 +110,12 @@ export const droneFrontItem: CanvasElementItem = {
},
registerOptionsUI: (builder) => {
const category = ['Drone Front'];
const category = [t('canvas.drone-front-item.category-drone-front', 'Drone Front')];
builder.addCustomEditor({
category,
id: 'rollAngle',
path: 'config.rollAngle',
name: 'Roll Angle',
name: t('canvas.drone-front-item.name-roll-angle', 'Roll Angle'),
editor: ScalarDimensionEditor,
});
},

@ -1,6 +1,7 @@
import { css } from '@emotion/css';
import { GrafanaTheme2 } from '@grafana/data';
import { t } from '@grafana/i18n';
import { ScalarDimensionConfig } from '@grafana/schema';
import { useStyles2 } from '@grafana/ui';
import { DimensionContext } from 'app/features/dimensions';
@ -108,12 +109,12 @@ export const droneSideItem: CanvasElementItem = {
},
registerOptionsUI: (builder) => {
const category = ['Drone Side'];
const category = [t('canvas.drone-side-item.category-drone-side', 'Drone Side')];
builder.addCustomEditor({
category,
id: 'pitchAngle',
path: 'config.pitchAngle',
name: 'Pitch Angle',
name: t('canvas.drone-side-item.name-pitch-angle', 'Pitch Angle'),
editor: ScalarDimensionEditor,
});
},

@ -1,6 +1,7 @@
import { css } from '@emotion/css';
import { GrafanaTheme2 } from '@grafana/data';
import { t } from '@grafana/i18n';
import { ScalarDimensionConfig } from '@grafana/schema';
import { useStyles2 } from '@grafana/ui';
import { DimensionContext } from 'app/features/dimensions';
@ -125,41 +126,41 @@ export const droneTopItem: CanvasElementItem = {
},
registerOptionsUI: (builder) => {
const category = ['Drone Top'];
const category = [t('canvas.drone-top-item.category-drone-top', 'Drone Top')];
builder
.addCustomEditor({
category,
id: 'yawAngle',
path: 'config.yawAngle',
name: 'Yaw Angle',
name: t('canvas.drone-top-item.name-yaw-angle', 'Yaw Angle'),
editor: ScalarDimensionEditor,
})
.addCustomEditor({
category,
id: 'fRightRotorRPM',
path: 'config.fRightRotorRPM',
name: 'Front Right Rotor RPM',
name: t('canvas.drone-top-item.name-front-right-rotor-rpm', 'Front Right Rotor RPM'),
editor: ScalarDimensionEditor,
})
.addCustomEditor({
category,
id: 'fLeftRotorRPM',
path: 'config.fLeftRotorRPM',
name: 'Front Left Rotor RPM',
name: t('canvas.drone-top-item.name-front-left-rotor-rpm', 'Front Left Rotor RPM'),
editor: ScalarDimensionEditor,
})
.addCustomEditor({
category,
id: 'bRightRotorRPM',
path: 'config.bRightRotorRPM',
name: 'Back Right Rotor RPM',
name: t('canvas.drone-top-item.name-back-right-rotor-rpm', 'Back Right Rotor RPM'),
editor: ScalarDimensionEditor,
})
.addCustomEditor({
category,
id: 'bLeftRotorRPM',
path: 'config.bLeftRotorRPM',
name: 'Back Left Rotor RPM',
name: t('canvas.drone-top-item.name-back-left-rotor-rpm', 'Back Left Rotor RPM'),
editor: ScalarDimensionEditor,
});
},

@ -136,20 +136,20 @@ export const ellipseItem: CanvasElementItem<CanvasElementConfig, CanvasElementDa
},
registerOptionsUI: (builder) => {
const category = ['Ellipse'];
const category = [t('canvas.ellipse-item.category-ellipse', 'Ellipse')];
builder
.addCustomEditor({
category,
id: 'textSelector',
path: 'config.text',
name: 'Text',
name: t('canvas.ellipse-item.name-text', 'Text'),
editor: TextDimensionEditor,
})
.addCustomEditor({
category,
id: 'config.color',
path: 'config.color',
name: 'Text color',
name: t('canvas.ellipse-item.name-text-color', 'Text color'),
editor: ColorDimensionEditor,
settings: {},
defaultValue: {},
@ -157,7 +157,7 @@ export const ellipseItem: CanvasElementItem<CanvasElementConfig, CanvasElementDa
.addRadio({
category,
path: 'config.align',
name: 'Align text',
name: t('canvas.ellipse-item.name-align-text', 'Align text'),
settings: {
options: [
{ value: Align.Left, label: t('canvas.ellipse-item.label.left', 'Left') },
@ -170,7 +170,7 @@ export const ellipseItem: CanvasElementItem<CanvasElementConfig, CanvasElementDa
.addRadio({
category,
path: 'config.valign',
name: 'Vertical align',
name: t('canvas.ellipse-item.name-vertical-align', 'Vertical align'),
settings: {
options: [
{ value: VAlign.Top, label: t('canvas.ellipse-item.label.top', 'Top') },
@ -183,7 +183,7 @@ export const ellipseItem: CanvasElementItem<CanvasElementConfig, CanvasElementDa
.addNumberInput({
category,
path: 'config.size',
name: 'Text size',
name: t('canvas.ellipse-item.name-text-size', 'Text size'),
settings: {
placeholder: t('canvas.ellipse-item.placeholder.auto', 'Auto'),
},

@ -3,6 +3,7 @@ import { isString } from 'lodash';
import { CSSProperties } from 'react';
import { LinkModel } from '@grafana/data';
import { t } from '@grafana/i18n';
import { ColorDimensionConfig, ResourceDimensionConfig, ResourceDimensionMode } from '@grafana/schema';
import { SanitizedSVG } from 'app/core/components/SVG/SanitizedSVG';
import { getPublicOrAbsoluteUrl } from 'app/features/dimensions';
@ -112,13 +113,13 @@ export const iconItem: CanvasElementItem<IconConfig, IconData> = {
// Heatmap overlay options
registerOptionsUI: (builder) => {
const category = ['Icon'];
const category = [t('canvas.icon-item.category-icon', 'Icon')];
builder
.addCustomEditor({
category,
id: 'iconSelector',
path: 'config.path',
name: 'SVG Path',
name: t('canvas.icon-item.name-svg-path', 'SVG Path'),
editor: ResourceDimensionEditor,
settings: {
resourceType: 'icon',
@ -129,7 +130,7 @@ export const iconItem: CanvasElementItem<IconConfig, IconData> = {
category,
id: 'config.fill',
path: 'config.fill',
name: 'Fill color',
name: t('canvas.icon-item.name-fill-color', 'Fill color'),
editor: ColorDimensionEditor,
settings: {},
defaultValue: {

@ -197,20 +197,20 @@ export const metricValueItem: CanvasElementItem<TextConfig, TextData> = {
},
registerOptionsUI: (builder) => {
const category = ['Metric value'];
const category = [t('canvas.category-metric-value', 'Metric value')];
builder
.addCustomEditor({
category,
id: 'textSelector',
path: 'config.text',
name: 'Text',
name: t('canvas.name-text', 'Text'),
editor: TextDimensionEditor,
})
.addCustomEditor({
category,
id: 'config.color',
path: 'config.color',
name: 'Text color',
name: t('canvas.name-color', 'Text color'),
editor: ColorDimensionEditor,
settings: {},
defaultValue: {},
@ -218,7 +218,7 @@ export const metricValueItem: CanvasElementItem<TextConfig, TextData> = {
.addRadio({
category,
path: 'config.align',
name: 'Align text',
name: t('canvas.name-align-text', 'Align text'),
settings: {
options: [
{ value: Align.Left, label: t('canvas.metric-value-item.label.left', 'Left') },
@ -231,7 +231,7 @@ export const metricValueItem: CanvasElementItem<TextConfig, TextData> = {
.addRadio({
category,
path: 'config.valign',
name: 'Vertical align',
name: t('canvas.name-vertical-align', 'Vertical align'),
settings: {
options: [
{ value: VAlign.Top, label: t('canvas.metric-value-item.label.top', 'Top') },
@ -244,7 +244,7 @@ export const metricValueItem: CanvasElementItem<TextConfig, TextData> = {
.addNumberInput({
category,
path: 'config.size',
name: 'Text size',
name: t('canvas.name-text-size', 'Text size'),
settings: {
placeholder: t('canvas.metric-value-item.placeholder.auto', 'Auto'),
},

@ -130,20 +130,20 @@ export const parallelogramItem: CanvasElementItem = {
},
registerOptionsUI: (builder) => {
const category = ['Parallelogram'];
const category = [t('canvas.parallelogram-item.category-parallelogram', 'Parallelogram')];
builder
.addCustomEditor({
category,
id: 'textSelector',
path: 'config.text',
name: 'Text',
name: t('canvas.parallelogram-item.name-text', 'Text'),
editor: TextDimensionEditor,
})
.addCustomEditor({
category,
id: 'config.color',
path: 'config.color',
name: 'Text color',
name: t('canvas.parallelogram-item.name-text-color', 'Text color'),
editor: ColorDimensionEditor,
settings: {},
defaultValue: {},
@ -151,7 +151,7 @@ export const parallelogramItem: CanvasElementItem = {
.addRadio({
category,
path: 'config.align',
name: 'Align text',
name: t('canvas.parallelogram-item.name-align-text', 'Align text'),
settings: {
options: [
{ value: Align.Left, label: t('canvas.parallelogram-item.label.left', 'Left') },
@ -164,7 +164,7 @@ export const parallelogramItem: CanvasElementItem = {
.addRadio({
category,
path: 'config.valign',
name: 'Vertical align',
name: t('canvas.parallelogram-item.name-vertical-align', 'Vertical align'),
settings: {
options: [
{ value: VAlign.Top, label: t('canvas.parallelogram-item.label.top', 'Top') },
@ -177,7 +177,7 @@ export const parallelogramItem: CanvasElementItem = {
.addNumberInput({
category,
path: 'config.size',
name: 'Text size',
name: t('canvas.parallelogram-item.name-text-size', 'Text size'),
settings: {
placeholder: t('canvas.parallelogram-item.placeholder.auto', 'Auto'),
},

@ -97,20 +97,20 @@ export const rectangleItem: CanvasElementItem<TextConfig, TextData> = {
// Heatmap overlay options
registerOptionsUI: (builder) => {
const category = ['Rectangle'];
const category = [t('canvas.rectangle-item.category-rectangle', 'Rectangle')];
builder
.addCustomEditor({
category,
id: 'textSelector',
path: 'config.text',
name: 'Text',
name: t('canvas.rectangle-item.name-text', 'Text'),
editor: TextDimensionEditor,
})
.addCustomEditor({
category,
id: 'config.color',
path: 'config.color',
name: 'Text color',
name: t('canvas.rectangle-item.name-text-color', 'Text color'),
editor: ColorDimensionEditor,
settings: {},
defaultValue: {},
@ -118,7 +118,7 @@ export const rectangleItem: CanvasElementItem<TextConfig, TextData> = {
.addRadio({
category,
path: 'config.align',
name: 'Align text',
name: t('canvas.rectangle-item.name-align-text', 'Align text'),
settings: {
options: [
{ value: Align.Left, label: t('canvas.rectangle-item.label.left', 'Left') },
@ -131,7 +131,7 @@ export const rectangleItem: CanvasElementItem<TextConfig, TextData> = {
.addRadio({
category,
path: 'config.valign',
name: 'Vertical align',
name: t('canvas.rectangle-item.name-vertical-align', 'Vertical align'),
settings: {
options: [
{ value: VAlign.Top, label: t('canvas.rectangle-item.label.top', 'Top') },
@ -144,7 +144,7 @@ export const rectangleItem: CanvasElementItem<TextConfig, TextData> = {
.addNumberInput({
category,
path: 'config.size',
name: 'Text size',
name: t('canvas.rectangle-item.name-text-size', 'Text size'),
settings: {
placeholder: t('canvas.rectangle-item.placeholder.auto', 'Auto'),
},

@ -1,6 +1,7 @@
import { css } from '@emotion/css';
import { GrafanaTheme2, LinkModel } from '@grafana/data';
import { t } from '@grafana/i18n';
import { ColorDimensionConfig, ScalarDimensionConfig } from '@grafana/schema';
import config from 'app/core/config';
import { DimensionContext } from 'app/features/dimensions';
@ -103,18 +104,18 @@ export const serverItem: CanvasElementItem<ServerConfig, ServerData> = {
},
registerOptionsUI: (builder) => {
const category = ['Server'];
const category = [t('canvas.server-item.category-server', 'Server')];
builder
.addSelect({
category,
path: 'config.type',
name: 'Type',
name: t('canvas.server-item.name-type', '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 },
{ value: ServerType.Single, label: t('canvas.server-item.type-options.label-single', 'Single') },
{ value: ServerType.Stack, label: t('canvas.server-item.type-options.label-stack', 'Stack') },
{ value: ServerType.Database, label: t('canvas.server-item.type-options.label-database', 'Database') },
{ value: ServerType.Terminal, label: t('canvas.server-item.type-options.label-terminal', 'Terminal') },
],
},
defaultValue: ServerType.Single,
@ -123,7 +124,7 @@ export const serverItem: CanvasElementItem<ServerConfig, ServerData> = {
category,
id: 'statusColor',
path: 'config.statusColor',
name: 'Status color',
name: t('canvas.server-item.name-status-color', 'Status color'),
editor: ColorDimensionEditor,
settings: {},
defaultValue: {
@ -134,7 +135,7 @@ export const serverItem: CanvasElementItem<ServerConfig, ServerData> = {
category,
id: 'bulbColor',
path: 'config.bulbColor',
name: 'Bulb color',
name: t('canvas.server-item.name-bulb-color', 'Bulb color'),
editor: ColorDimensionEditor,
settings: {},
defaultValue: {
@ -145,7 +146,7 @@ export const serverItem: CanvasElementItem<ServerConfig, ServerData> = {
category,
id: 'blinkRate',
path: 'config.blinkRate',
name: 'Blink rate [hz] (0 = off)',
name: t('canvas.server-item.name-blink-rate', 'Blink rate [hz] (0 = off)'),
editor: ScalarDimensionEditor,
settings: { min: 0, max: 100 },
});

@ -173,20 +173,20 @@ export const textItem: CanvasElementItem<TextConfig, TextData> = {
},
registerOptionsUI: (builder) => {
const category = ['Text'];
const category = [t('canvas.text-item.category-text', 'Text')];
builder
.addCustomEditor({
category,
id: 'textSelector',
path: 'config.text',
name: 'Text',
name: t('canvas.text-item.name-text', 'Text'),
editor: TextDimensionEditor,
})
.addCustomEditor({
category,
id: 'config.color',
path: 'config.color',
name: 'Text color',
name: t('canvas.text-item.name-text-color', 'Text color'),
editor: ColorDimensionEditor,
settings: {},
defaultValue: {},
@ -194,7 +194,7 @@ export const textItem: CanvasElementItem<TextConfig, TextData> = {
.addRadio({
category,
path: 'config.align',
name: 'Align text',
name: t('canvas.text-item.name-align-text', 'Align text'),
settings: {
options: [
{ value: Align.Left, label: t('canvas.text-item.label.left', 'Left') },
@ -207,7 +207,7 @@ export const textItem: CanvasElementItem<TextConfig, TextData> = {
.addRadio({
category,
path: 'config.valign',
name: 'Vertical align',
name: t('canvas.text-item.name-vertical-align', 'Vertical align'),
settings: {
options: [
{ value: VAlign.Top, label: t('canvas.text-item.label.top', 'Top') },
@ -220,7 +220,7 @@ export const textItem: CanvasElementItem<TextConfig, TextData> = {
.addNumberInput({
category,
path: 'config.size',
name: 'Text size',
name: t('canvas.text-item.name-text-size', 'Text size'),
settings: {
placeholder: t('canvas.text-item.placeholder.auto', 'Auto'),
},

@ -131,20 +131,20 @@ export const triangleItem: CanvasElementItem = {
},
registerOptionsUI: (builder) => {
const category = ['Triangle'];
const category = [t('canvas.triangle-item.category-triangle', 'Triangle')];
builder
.addCustomEditor({
category,
id: 'textSelector',
path: 'config.text',
name: 'Text',
name: t('canvas.triangle-item.name-text', 'Text'),
editor: TextDimensionEditor,
})
.addCustomEditor({
category,
id: 'config.color',
path: 'config.color',
name: 'Text color',
name: t('canvas.triangle-item.name-text-color', 'Text color'),
editor: ColorDimensionEditor,
settings: {},
defaultValue: {},
@ -152,7 +152,7 @@ export const triangleItem: CanvasElementItem = {
.addRadio({
category,
path: 'config.align',
name: 'Align text',
name: t('canvas.triangle-item.name-align-text', 'Align text'),
settings: {
options: [
{ value: Align.Left, label: t('canvas.triangle-item.label.left', 'Left') },
@ -165,7 +165,7 @@ export const triangleItem: CanvasElementItem = {
.addRadio({
category,
path: 'config.valign',
name: 'Vertical align',
name: t('canvas.triangle-item.name-vertical-align', 'Vertical align'),
settings: {
options: [
{ value: VAlign.Top, label: t('canvas.triangle-item.label.top', 'Top') },
@ -178,7 +178,7 @@ export const triangleItem: CanvasElementItem = {
.addNumberInput({
category,
path: 'config.size',
name: 'Text size',
name: t('canvas.triangle-item.name-text-size', 'Text size'),
settings: {
placeholder: t('canvas.triangle-item.placeholder.auto', 'Auto'),
},

@ -1,6 +1,7 @@
import { css } from '@emotion/css';
import { GrafanaTheme2, LinkModel } from '@grafana/data';
import { t } from '@grafana/i18n';
import { ScalarDimensionConfig } from '@grafana/schema';
import { useStyles2 } from '@grafana/ui';
import { DimensionContext } from 'app/features/dimensions';
@ -105,12 +106,12 @@ export const windTurbineItem: CanvasElementItem = {
},
registerOptionsUI: (builder) => {
const category = ['Wind Turbine'];
const category = [t('canvas.wind-turbine-item.category-wind-turbine', 'Wind Turbine')];
builder.addCustomEditor({
category,
id: 'rpm',
path: 'config.rpm',
name: 'RPM',
name: t('canvas.wind-turbine-item.name-rpm', 'RPM'),
editor: ScalarDimensionEditor,
});
},

@ -1,18 +1,24 @@
import { useCallback } from 'react';
import { SelectableValue, StandardEditorProps } from '@grafana/data';
import { t } from '@grafana/i18n';
import { InlineField, InlineFieldRow, RadioButtonGroup } from '@grafana/ui';
import { BackgroundImageSize } from 'app/plugins/panel/canvas/panelcfg.gen';
const options: Array<SelectableValue<BackgroundImageSize>> = [
{ value: BackgroundImageSize.Original, label: 'Original' },
{ value: BackgroundImageSize.Contain, label: 'Contain' },
{ value: BackgroundImageSize.Cover, label: 'Cover' },
{ value: BackgroundImageSize.Fill, label: 'Fill' },
{ value: BackgroundImageSize.Tile, label: 'Tile' },
];
export const BackgroundSizeEditor = ({ value, onChange }: StandardEditorProps<string, undefined, undefined>) => {
const options: Array<SelectableValue<BackgroundImageSize>> = [
{
value: BackgroundImageSize.Original,
label: t('dimensions.background-size-editor.options.label-original', 'Original'),
},
{
value: BackgroundImageSize.Contain,
label: t('dimensions.background-size-editor.options.label-contain', 'Contain'),
},
{ value: BackgroundImageSize.Cover, label: t('dimensions.background-size-editor.options.label-cover', 'Cover') },
{ value: BackgroundImageSize.Fill, label: t('dimensions.background-size-editor.options.label-fill', 'Fill') },
{ value: BackgroundImageSize.Tile, label: t('dimensions.background-size-editor.options.label-tile', 'Tile') },
];
const imageSize = value ?? BackgroundImageSize.Cover;
const onImageSizeChange = useCallback(

@ -1,16 +1,12 @@
import { css } from '@emotion/css';
import { useCallback } from 'react';
import { useCallback, useMemo } from 'react';
import { GrafanaTheme2, SelectableValue, StandardEditorProps, FieldNamePickerBaseNameMode } from '@grafana/data';
import { t } from '@grafana/i18n';
import { ColorDimensionConfig } from '@grafana/schema';
import { Select, ColorPicker, useStyles2 } from '@grafana/ui';
import { useFieldDisplayNames, useSelectOptions } from '@grafana/ui/internal';
const fixedColorOption: SelectableValue<string> = {
label: 'Fixed color',
value: '_____fixed_____',
};
interface ColorDimensionSettings {
isClearable?: boolean;
baseNameMode?: FieldNamePickerBaseNameMode;
@ -18,6 +14,13 @@ interface ColorDimensionSettings {
}
export const ColorDimensionEditor = (props: StandardEditorProps<ColorDimensionConfig, ColorDimensionSettings>) => {
const fixedColorOption: SelectableValue<string> = useMemo(
() => ({
label: t('dimensions.color-dimension-editor.label-fixed-color', 'Fixed color'),
value: '_____fixed_____',
}),
[]
);
const { value, context, onChange, item } = props;
const defaultColor = 'dark-green';
@ -50,7 +53,7 @@ export const ColorDimensionEditor = (props: StandardEditorProps<ColorDimensionCo
});
}
},
[onChange, value]
[fixedColorOption.value, onChange, value]
);
const onColorChange = useCallback(

@ -12,12 +12,6 @@ import { MediaType, ResourceDimensionOptions, ResourcePickerSize } from '../type
import { ResourcePicker } from './ResourcePicker';
const resourceOptions = [
{ label: 'Fixed', value: ResourceDimensionMode.Fixed, description: 'Fixed value' },
{ label: 'Field', value: ResourceDimensionMode.Field, description: 'Use a string field result' },
// { label: 'Mapping', value: ResourceDimensionMode.Mapping, description: 'Map the results of a value to an svg' },
];
const dummyFieldSettings = {
settings: {},
} as StandardEditorsRegistryItem<string, FieldNamePickerConfigSettings>;
@ -27,6 +21,19 @@ export const ResourceDimensionEditor = (
) => {
const { value, context, onChange, item } = props;
const labelWidth = 9;
const resourceOptions = [
{
label: t('dimensions.resource-dimension-editor.label-fixed', 'Fixed'),
value: ResourceDimensionMode.Fixed,
description: t('dimensions.resource-dimension-editor.description-fixed', 'Fixed value'),
},
{
label: t('dimensions.resource-dimension-editor.label-field', 'Field'),
value: ResourceDimensionMode.Field,
description: t('dimensions.resource-dimension-editor.description-field', 'Use a string field result'),
},
// { label: 'Mapping', value: ResourceDimensionMode.Mapping, description: 'Map the results of a value to an svg' },
];
const onModeChange = useCallback(
(mode: ResourceDimensionMode) => {

@ -1,5 +1,5 @@
import { css } from '@emotion/css';
import { useCallback } from 'react';
import { useCallback, useMemo } from 'react';
import { FieldType, GrafanaTheme2, SelectableValue, StandardEditorProps } from '@grafana/data';
import { t } from '@grafana/i18n';
@ -10,21 +10,38 @@ import { NumberInput } from 'app/core/components/OptionsUI/NumberInput';
import { ScalarDimensionOptions } from '../types';
const fixedValueOption: SelectableValue<string> = {
label: 'Fixed value',
value: '_____fixed_____',
};
const scalarOptions = [
{ label: 'Mod', value: ScalarDimensionMode.Mod, description: 'Use field values, mod from max' },
{ label: 'Clamped', value: ScalarDimensionMode.Clamped, description: 'Use field values, clamped to max and min' },
];
type Props = StandardEditorProps<ScalarDimensionConfig, ScalarDimensionOptions>;
export const ScalarDimensionEditor = ({ value, context, onChange, item }: Props) => {
const { settings } = item;
const fixedValueOption: SelectableValue<string> = useMemo(
() => ({
label: t('dimensions.scalar-dimension-editor.fixed-value-options.label-fixed-values', 'Fixed value'),
value: '_____fixed_____',
}),
[]
);
const scalarOptions = [
{
label: t('dimensions.scalar-dimension-editor.scalar-options.label-mod', 'Mod'),
value: ScalarDimensionMode.Mod,
description: t(
'dimensions.scalar-dimension-editor.scalar-options.description-mod',
'Use field values, mod from max'
),
},
{
label: t('dimensions.scalar-dimension-editor.scalar-options.label-clamped', 'Clamped'),
value: ScalarDimensionMode.Clamped,
description: t(
'dimensions.scalar-dimension-editor.scalar-options.description-clamped',
'Use field values, clamped to max and min'
),
},
];
const DEFAULT_VALUE = 0;
const fieldName = value?.field;
@ -51,7 +68,7 @@ export const ScalarDimensionEditor = ({ value, context, onChange, item }: Props)
});
}
},
[onChange, value]
[onChange, value, fixedValueOption.value]
);
const onModeChange = useCallback(

@ -14,12 +14,6 @@ import { StringValueEditor } from 'app/core/components/OptionsUI/string';
import { TextDimensionOptions } from '../types';
const textOptions = [
{ label: 'Fixed', value: TextDimensionMode.Fixed, description: 'Fixed value' },
{ label: 'Field', value: TextDimensionMode.Field, description: 'Display field value' },
// { label: 'Template', value: TextDimensionMode.Template, description: 'use template text' },
];
const dummyFieldSettings = {
settings: {},
} as StandardEditorsRegistryItem<string, FieldNamePickerConfigSettings>;
@ -31,6 +25,19 @@ const dummyStringSettings = {
type Props = StandardEditorProps<TextDimensionConfig, TextDimensionOptions>;
export const TextDimensionEditor = ({ value, context, onChange }: Props) => {
const textOptions = [
{
label: t('dimensions.text-dimension-editor.label-fixed', 'Fixed'),
value: TextDimensionMode.Fixed,
description: t('dimensions.text-dimension-editor.description-fixed', 'Fixed value'),
},
{
label: t('dimensions.text-dimension-editor.label-field', 'Field'),
value: TextDimensionMode.Field,
description: t('dimensions.text-dimension-editor.description-field', 'Display field value'),
},
// { label: 'Template', value: TextDimensionMode.Template, description: 'use template text' },
];
const labelWidth = 9;
const onModeChange = useCallback(

@ -14,26 +14,34 @@ import { CanvasEditorOptions } from './elementEditor';
const places: Array<keyof Placement> = ['top', 'left', 'bottom', 'right', 'width', 'height', 'rotation'];
const horizontalOptions: Array<SelectableValue<HorizontalConstraint>> = [
{ label: 'Left', value: HorizontalConstraint.Left },
{ label: 'Right', value: HorizontalConstraint.Right },
{ label: 'Left & right', value: HorizontalConstraint.LeftRight },
{ label: 'Center', value: HorizontalConstraint.Center },
{ label: 'Scale', value: HorizontalConstraint.Scale },
];
const verticalOptions: Array<SelectableValue<VerticalConstraint>> = [
{ label: 'Top', value: VerticalConstraint.Top },
{ label: 'Bottom', value: VerticalConstraint.Bottom },
{ label: 'Top & bottom', value: VerticalConstraint.TopBottom },
{ label: 'Center', value: VerticalConstraint.Center },
{ label: 'Scale', value: VerticalConstraint.Scale },
];
type Props = StandardEditorProps<unknown, CanvasEditorOptions, Options>;
export function PlacementEditor({ item }: Props) {
const settings = item.settings;
const horizontalOptions: Array<SelectableValue<HorizontalConstraint>> = [
{ label: t('canvas.placement-editor.horizontal-options.label-left', 'Left'), value: HorizontalConstraint.Left },
{ label: t('canvas.placement-editor.horizontal-options.label-right', 'Right'), value: HorizontalConstraint.Right },
{
label: t('canvas.placement-editor.horizontal-options.label-left-and-right', 'Left & right'),
value: HorizontalConstraint.LeftRight,
},
{
label: t('canvas.placement-editor.horizontal-options.label-center', 'Center'),
value: HorizontalConstraint.Center,
},
{ label: t('canvas.placement-editor.horizontal-options.label-scale', 'Scale'), value: HorizontalConstraint.Scale },
];
const verticalOptions: Array<SelectableValue<VerticalConstraint>> = [
{ label: t('canvas.placement-editor.vertical-options.label-top', 'Top'), value: VerticalConstraint.Top },
{ label: t('canvas.placement-editor.vertical-options.label-bottom', 'Bottom'), value: VerticalConstraint.Bottom },
{
label: t('canvas.placement-editor.vertical-options.label-top-and-bottom', 'Top & bottom'),
value: VerticalConstraint.TopBottom,
},
{ label: t('canvas.placement-editor.vertical-options.label-center', 'Center'), value: VerticalConstraint.Center },
{ label: t('canvas.placement-editor.vertical-options.label-scale', 'Scale'), value: VerticalConstraint.Scale },
];
// Will force a rerender whenever the subject changes
useObservable(settings?.scene ? settings.scene.moved : new Subject());

@ -1,6 +1,7 @@
import { get as lodashGet } from 'lodash';
import { NestedPanelOptions, NestedValueAccess } from '@grafana/data/internal';
import { t } from '@grafana/i18n';
import { CanvasElementOptions } from 'app/features/canvas/element';
import {
canvasElementRegistry,
@ -77,7 +78,10 @@ export function getElementEditor(opts: CanvasEditorOptions): NestedPanelOptions<
options: layerTypes,
},
description: isUnsupported
? 'Selected element type is not supported by current settings. Please enable advanced element types.'
? t(
'canvas.element-editor.description-unsupported',
'Selected element type is not supported by current settings. Please enable advanced element types.'
)
: '',
});
@ -100,10 +104,10 @@ export function getElementEditor(opts: CanvasEditorOptions): NestedPanelOptions<
const shouldAddLayoutEditor = opts.element.item.standardEditorConfig?.layout ?? true;
if (shouldAddLayoutEditor) {
builder.addCustomEditor({
category: ['Layout'],
category: [t('canvas.element-editor.category-layout', 'Layout')],
id: 'content',
path: '__', // not used
name: 'Quick placement',
name: t('canvas.element-editor.name-quick-placement', 'Quick placement'),
editor: PlacementEditor,
settings: opts,
});

@ -61,7 +61,11 @@ export function InlineEditBody() {
if (element && !(element instanceof FrameState)) {
builder.addNestedOptions(
getElementEditor({
category: [`Selected element (${element.options.name})`],
category: [
t('canvas.inline-edit-body.category-selected-element', 'Selected element ({{element}})', {
element: element.options.name,
}),
],
element,
scene: state.scene,
})

@ -1,6 +1,7 @@
import { get as lodashGet } from 'lodash';
import { NestedPanelOptions, NestedValueAccess } from '@grafana/data/internal';
import { t } from '@grafana/i18n';
import { ElementState } from 'app/features/canvas/runtime/element';
import { FrameState } from 'app/features/canvas/runtime/frame';
import { Scene } from 'app/features/canvas/runtime/scene';
@ -42,7 +43,7 @@ export function getLayerEditor(opts: InstanceState): NestedPanelOptions<LayerEdi
const options = scene.currentLayer.options || { elements: [] };
return {
category: ['Layer'],
category: [t('canvas.layer-editor.category-layer', 'Layer')],
path: '--', // not used!
// Note that canvas editor writes things to the scene!
@ -71,7 +72,7 @@ export function getLayerEditor(opts: InstanceState): NestedPanelOptions<LayerEdi
builder.addCustomEditor({
id: 'content',
path: 'root',
name: 'Elements',
name: t('canvas.layer-editor.name-elements', 'Elements'),
editor: TreeNavigationEditor,
settings: { scene, layer: scene.currentLayer, selected },
});
@ -84,10 +85,10 @@ export function getLayerEditor(opts: InstanceState): NestedPanelOptions<LayerEdi
if (currentLayer && !currentLayer.isRoot()) {
builder.addCustomEditor({
category: ['Layout'],
category: [t('canvas.layer-editor.category-layout', 'Layout')],
id: 'content',
path: '__', // not used
name: 'Constraints',
name: t('canvas.layer-editor.name-constraints', 'Constraints'),
editor: PlacementEditor,
settings: {
scene: opts.scene,

@ -1,7 +1,6 @@
import { capitalize } from 'lodash';
import { FieldType } from '@grafana/data';
import { PanelOptionsSupplier } from '@grafana/data/internal';
import { t } from '@grafana/i18n';
import { ConnectionDirection } from 'app/features/canvas/element';
import { SVGElements } from 'app/features/canvas/runtime/element';
import { ColorDimensionEditor, ResourceDimensionEditor, ScaleDimensionEditor } from 'app/features/dimensions/editors';
@ -35,13 +34,13 @@ const getCategoryName = (str: string, type: string | undefined) => {
export const optionBuilder: OptionSuppliers = {
addBackground: (builder, context) => {
const category = getCategoryName('Background', context.options?.type);
const category = getCategoryName(t('canvas.category-background', 'Background'), context.options?.type);
builder
.addCustomEditor({
category,
id: 'background.color',
path: 'background.color',
name: 'Color',
name: t('canvas.label-color', 'Color'),
editor: ColorDimensionEditor,
settings: {},
defaultValue: {
@ -53,7 +52,7 @@ export const optionBuilder: OptionSuppliers = {
category,
id: 'background.image',
path: 'background.image',
name: 'Image',
name: t('canvas.label-image', 'Image'),
editor: ResourceDimensionEditor,
settings: {
resourceType: 'image',
@ -63,7 +62,7 @@ export const optionBuilder: OptionSuppliers = {
category,
id: 'background.size',
path: 'background.size',
name: 'Image size',
name: t('canvas.label-image-size', 'Image size'),
editor: BackgroundSizeEditor,
settings: {
resourceType: 'image',
@ -81,11 +80,11 @@ export const optionBuilder: OptionSuppliers = {
},
addBorder: (builder, context) => {
const category = getCategoryName('Border', context.options?.type);
const category = getCategoryName(t('canvas.category-border', 'Border'), context.options?.type);
builder.addSliderInput({
category,
path: 'border.width',
name: 'Width',
name: t('canvas.label-width', 'Width'),
defaultValue: 2,
settings: {
min: 0,
@ -98,7 +97,7 @@ export const optionBuilder: OptionSuppliers = {
category,
id: 'border.color',
path: 'border.color',
name: 'Color',
name: t('canvas.label-color', 'Color'),
editor: ColorDimensionEditor,
settings: {},
defaultValue: {
@ -111,7 +110,7 @@ export const optionBuilder: OptionSuppliers = {
builder.addSliderInput({
category,
path: 'border.radius',
name: 'Radius',
name: t('canvas.label-radius', 'Radius'),
defaultValue: 0,
settings: {
min: 0,
@ -121,12 +120,12 @@ export const optionBuilder: OptionSuppliers = {
},
addColor: (builder, context) => {
const category = ['Color'];
const category = [t('canvas.category-color', 'Color')];
builder.addCustomEditor({
category,
id: 'color',
path: 'color',
name: 'Color',
name: t('canvas.label-color', 'Color'),
editor: ColorDimensionEditor,
settings: {},
defaultValue: {
@ -137,12 +136,12 @@ export const optionBuilder: OptionSuppliers = {
},
addSize: (builder, context) => {
const category = ['Size'];
const category = [t('canvas.category-size', 'Size')];
builder.addCustomEditor({
category,
id: 'size',
path: 'size',
name: 'Size',
name: t('canvas.label-size', 'Size'),
editor: ScaleDimensionEditor,
settings: {
min: 1,
@ -158,12 +157,12 @@ export const optionBuilder: OptionSuppliers = {
},
addRadius: (builder, context) => {
const category = ['Radius'];
const category = [t('canvas.category-radius', 'Radius')];
builder.addCustomEditor({
category,
id: 'radius',
path: 'radius',
name: 'Radius',
name: t('canvas.label-radius', 'Radius'),
editor: ScaleDimensionEditor,
settings: {
min: 0,
@ -180,17 +179,17 @@ export const optionBuilder: OptionSuppliers = {
},
addDirection: (builder, context) => {
const category = ['Arrow Direction'];
const category = [t('canvas.category-arrow-direction', 'Arrow Direction')];
builder.addRadio({
category,
path: 'direction',
name: 'Direction',
name: t('canvas.label-direction', 'Direction'),
settings: {
options: [
{ value: undefined, label: capitalize(ConnectionDirection.Forward) },
{ value: ConnectionDirection.Reverse, label: capitalize(ConnectionDirection.Reverse) },
{ value: ConnectionDirection.Both, label: capitalize(ConnectionDirection.Both) },
{ value: ConnectionDirection.None, label: capitalize(ConnectionDirection.None) },
{ value: undefined, label: t('canvas.direction-options.label-forward', 'Forward') },
{ value: ConnectionDirection.Reverse, label: t('canvas.direction-options.label-reverse', 'Reverse') },
{ value: ConnectionDirection.Both, label: t('canvas.direction-options.label-both', 'Both') },
{ value: ConnectionDirection.None, label: t('canvas.direction-options.label-none', 'None') },
],
},
defaultValue: ConnectionDirection.Forward,
@ -198,24 +197,24 @@ export const optionBuilder: OptionSuppliers = {
},
addLineStyle: (builder, context) => {
const category = ['Line style'];
const category = [t('canvas.category-line-style', 'Line style')];
builder.addCustomEditor({
category,
id: 'lineStyle',
path: 'lineStyle',
name: 'Line style',
name: t('canvas.label-line-style', 'Line style'),
editor: LineStyleEditor,
settings: {},
defaultValue: { value: LineStyle.Solid, label: 'Solid' },
defaultValue: { value: LineStyle.Solid, label: t('canvas.line-style-options.label-solid', 'Solid') },
});
},
addDataLinks: (builder, context) => {
builder.addCustomEditor({
category: ['Data links and actions'],
category: [t('canvas.category-data-links', 'Data links and actions')],
id: 'dataLinks',
path: 'links',
name: 'Links',
name: t('canvas.label-links', 'Links'),
editor: DataLinksEditor,
settings: context.options,
});
@ -223,10 +222,10 @@ export const optionBuilder: OptionSuppliers = {
addActions: (builder, context) => {
builder.addCustomEditor({
category: ['Data links and actions'],
category: [t('canvas.category-data-links', 'Data links and actions')],
id: 'actions',
path: 'actions',
name: 'Actions',
name: t('canvas.label-actions', 'Actions'),
editor: ActionsEditor,
settings: context.options,
});

@ -1,4 +1,5 @@
import { FieldConfigProperty, PanelOptionsEditorBuilder, PanelPlugin } from '@grafana/data';
import { t } from '@grafana/i18n';
import { config } from '@grafana/runtime';
import { FrameState } from 'app/features/canvas/runtime/frame';
@ -11,24 +12,28 @@ import { canvasMigrationHandler } from './migrations';
import { Options } from './panelcfg.gen';
export const addStandardCanvasEditorOptions = (builder: PanelOptionsEditorBuilder<Options>) => {
const category = [t('canvas.category-canvas', 'Canvas')];
builder.addBooleanSwitch({
path: 'inlineEditing',
name: 'Inline editing',
description: 'Enable editing the panel directly',
name: t('canvas.name-inline-editing', 'Inline editing'),
category,
description: t('canvas.description-inline-editing', 'Enable editing the panel directly'),
defaultValue: true,
});
builder.addBooleanSwitch({
path: 'showAdvancedTypes',
name: 'Experimental element types',
description: 'Enable selection of experimental element types',
name: t('canvas.name-experimental-types', 'Experimental element types'),
category,
description: t('canvas.description-experimental-types', 'Enable selection of experimental element types'),
defaultValue: true,
});
builder.addBooleanSwitch({
path: 'panZoom',
name: 'Pan and zoom',
description: 'Enable pan and zoom',
name: t('canvas.name-pan-zoom', 'Pan and zoom'),
category,
description: t('canvas.description-pan-zoom', 'Enable pan and zoom'),
defaultValue: false,
showIf: (opts) => config.featureToggles.canvasPanelPanZoom,
});
@ -36,14 +41,18 @@ export const addStandardCanvasEditorOptions = (builder: PanelOptionsEditorBuilde
id: 'panZoomHelp',
path: 'panZoomHelp',
name: '',
category,
editor: PanZoomHelp,
showIf: (opts) => config.featureToggles.canvasPanelPanZoom && opts.panZoom,
});
builder.addBooleanSwitch({
path: 'infinitePan',
name: 'Infinite panning',
description:
'Enable infinite panning - useful for expansive canvases. Warning: this is an experimental feature and currently only works well with elements that are top / left constrained',
name: t('canvas.name-infinite-panning', 'Infinite panning'),
category,
description: t(
'canvas.description-infinite-panning',
'Enable infinite panning - useful for expansive canvases. Warning: this is an experimental feature and currently only works well with elements that are top / left constrained'
),
defaultValue: false,
showIf: (opts) => config.featureToggles.canvasPanelPanZoom && opts.panZoom,
});
@ -87,7 +96,11 @@ export const plugin = new PanelPlugin<Options>(CanvasPanel)
if (!(element instanceof FrameState)) {
builder.addNestedOptions(
getElementEditor({
category: [`Selected element (${element.options.name})`],
category: [
t('canvas.category-selected-element', 'Selected element ({{element}})', {
element: element.options.name,
}),
],
element,
scene: state.scene,
})
@ -98,7 +111,7 @@ export const plugin = new PanelPlugin<Options>(CanvasPanel)
if (connectionSelection) {
builder.addNestedOptions(
getConnectionEditor({
category: ['Selected connection'],
category: [t('canvas.category-selected-connection', 'Selected connection')],
connection: connectionSelection,
scene: state.scene,
})

@ -3523,11 +3523,18 @@
}
},
"button-item": {
"category-button": "Button",
"label": {
"center": "Center",
"left": "Left",
"right": "Right"
},
"name-align-text": "Align text",
"name-api": "API",
"name-style": "Style",
"name-text": "Text",
"name-text-color": "Text color",
"name-text-size": "Text size",
"placeholder": {
"auto": "Auto"
}
@ -3554,7 +3561,20 @@
}
}
},
"category-arrow-direction": "Arrow Direction",
"category-background": "Background",
"category-border": "Border",
"category-canvas": "Canvas",
"category-color": "Color",
"category-data-links": "Data links and actions",
"category-line-style": "Line style",
"category-metric-value": "Metric value",
"category-radius": "Radius",
"category-selected-connection": "Selected connection",
"category-selected-element": "Selected element ({{element}})",
"category-size": "Size",
"cloud-item": {
"category-cloud": "Cloud",
"label": {
"bottom": "Bottom",
"center": "Center",
@ -3563,11 +3583,48 @@
"right": "Right",
"top": "Top"
},
"name-align-text": "Align text",
"name-text": "Text",
"name-text-color": "Text color",
"name-text-size": "Text size",
"name-vertical-align": "Vertical align",
"placeholder": {
"auto": "Auto"
}
},
"description-experimental-types": "Enable selection of experimental element types",
"description-infinite-panning": "Enable infinite panning - useful for expansive canvases. Warning: this is an experimental feature and currently only works well with elements that are top / left constrained",
"description-inline-editing": "Enable editing the panel directly",
"description-pan-zoom": "Enable pan and zoom",
"direction-options": {
"label-both": "Both",
"label-forward": "Forward",
"label-none": "None",
"label-reverse": "Reverse"
},
"drone-front-item": {
"category-drone-front": "Drone Front",
"name-roll-angle": "Roll Angle"
},
"drone-side-item": {
"category-drone-side": "Drone Side",
"name-pitch-angle": "Pitch Angle"
},
"drone-top-item": {
"category-drone-top": "Drone Top",
"name-back-left-rotor-rpm": "Back Left Rotor RPM",
"name-back-right-rotor-rpm": "Back Right Rotor RPM",
"name-front-left-rotor-rpm": "Front Left Rotor RPM",
"name-front-right-rotor-rpm": "Front Right Rotor RPM",
"name-yaw-angle": "Yaw Angle"
},
"element-editor": {
"category-layout": "Layout",
"description-unsupported": "Selected element type is not supported by current settings. Please enable advanced element types.",
"name-quick-placement": "Quick placement"
},
"ellipse-item": {
"category-ellipse": "Ellipse",
"label": {
"bottom": "Bottom",
"center": "Center",
@ -3576,21 +3633,51 @@
"right": "Right",
"top": "Top"
},
"name-align-text": "Align text",
"name-text": "Text",
"name-text-color": "Text color",
"name-text-size": "Text size",
"name-vertical-align": "Vertical align",
"placeholder": {
"auto": "Auto"
}
},
"icon-item": {
"category-icon": "Icon",
"name-fill-color": "Fill color",
"name-svg-path": "SVG Path"
},
"inline-edit": {
"canvas-inline-editor": "Canvas Inline Editor",
"tooltip-close-inline-editor": "Close inline editor"
},
"inline-edit-body": {
"category-selected-element": "Selected element ({{element}})",
"label-add-item": "Add item",
"please-select-an-element": "Please select an element"
},
"label-actions": "Actions",
"label-color": "Color",
"label-direction": "Direction",
"label-image": "Image",
"label-image-size": "Image size",
"label-line-style": "Line style",
"label-links": "Links",
"label-radius": "Radius",
"label-size": "Size",
"label-width": "Width",
"layer-editor": {
"category-layer": "Layer",
"category-layout": "Layout",
"name-constraints": "Constraints",
"name-elements": "Elements"
},
"line-style-editor": {
"label-animate": "Animate"
},
"line-style-options": {
"label-solid": "Solid"
},
"metric-value-item": {
"label": {
"bottom": "Bottom",
@ -3604,6 +3691,15 @@
"auto": "Auto"
}
},
"name-align-text": "Align text",
"name-color": "Text color",
"name-experimental-types": "Experimental element types",
"name-infinite-panning": "Infinite panning",
"name-inline-editing": "Inline editing",
"name-pan-zoom": "Pan and zoom",
"name-text": "Text",
"name-text-size": "Text size",
"name-vertical-align": "Vertical align",
"not-found-display": {
"not-found": "<0>Not found: </0><config />"
},
@ -3616,6 +3712,7 @@
"zoom-scroll-wheel": "Zoom: Scroll wheel"
},
"parallelogram-item": {
"category-parallelogram": "Parallelogram",
"label": {
"bottom": "Bottom",
"center": "Center",
@ -3624,6 +3721,11 @@
"right": "Right",
"top": "Top"
},
"name-align-text": "Align text",
"name-text": "Text",
"name-text-color": "Text color",
"name-text-size": "Text size",
"name-vertical-align": "Vertical align",
"placeholder": {
"auto": "Auto"
}
@ -3635,9 +3737,23 @@
"placeholder-value": "Value"
},
"placement-editor": {
"horizontal-options": {
"label-center": "Center",
"label-left": "Left",
"label-left-and-right": "Left & right",
"label-right": "Right",
"label-scale": "Scale"
},
"label-constraints": "Constraints",
"label-position": "Position",
"loading": "Loading..."
"loading": "Loading...",
"vertical-options": {
"label-bottom": "Bottom",
"label-center": "Center",
"label-scale": "Scale",
"label-top": "Top",
"label-top-and-bottom": "Top & bottom"
}
},
"quick-positioning": {
"tooltip-align-bottom": "Align bottom",
@ -3648,6 +3764,7 @@
"tooltip-align-vertical-centers": "Align vertical centers"
},
"rectangle-item": {
"category-rectangle": "Rectangle",
"label": {
"bottom": "Bottom",
"center": "Center",
@ -3656,14 +3773,33 @@
"right": "Right",
"top": "Top"
},
"name-align-text": "Align text",
"name-text": "Text",
"name-text-color": "Text color",
"name-text-size": "Text size",
"name-vertical-align": "Vertical align",
"placeholder": {
"auto": "Auto"
}
},
"server-item": {
"category-server": "Server",
"name-blink-rate": "Blink rate [hz] (0 = off)",
"name-bulb-color": "Bulb color",
"name-status-color": "Status color",
"name-type": "Type",
"type-options": {
"label-database": "Database",
"label-single": "Single",
"label-stack": "Stack",
"label-terminal": "Terminal"
}
},
"text-display": {
"double-click-to-set": "Double click to set text"
},
"text-item": {
"category-text": "Text",
"label": {
"bottom": "Bottom",
"center": "Center",
@ -3672,6 +3808,11 @@
"right": "Right",
"top": "Top"
},
"name-align-text": "Align text",
"name-text": "Text",
"name-text-color": "Text color",
"name-text-size": "Text size",
"name-vertical-align": "Vertical align",
"placeholder": {
"auto": "Auto"
}
@ -3693,6 +3834,7 @@
"tooltip-remove": "Remove"
},
"triangle-item": {
"category-triangle": "Triangle",
"label": {
"bottom": "Bottom",
"center": "Center",
@ -3701,9 +3843,18 @@
"right": "Right",
"top": "Top"
},
"name-align-text": "Align text",
"name-text": "Text",
"name-text-color": "Text color",
"name-text-size": "Text size",
"name-vertical-align": "Vertical align",
"placeholder": {
"auto": "Auto"
}
},
"wind-turbine-item": {
"category-wind-turbine": "Wind Turbine",
"name-rpm": "RPM"
}
},
"carousel": {
@ -6079,6 +6230,18 @@
}
},
"dimensions": {
"background-size-editor": {
"options": {
"label-contain": "Contain",
"label-cover": "Cover",
"label-fill": "Fill",
"label-original": "Original",
"label-tile": "Tile"
}
},
"color-dimension-editor": {
"label-fixed-color": "Fixed color"
},
"file-dropzone-custom-children": {
"upload": "Upload"
},
@ -6091,7 +6254,10 @@
"placeholder-search": "Search"
},
"resource-dimension-editor": {
"description-field": "Use a string field result",
"description-fixed": "Fixed value",
"label-field": "Field",
"label-fixed": "Fixed",
"label-mappings": "Mappings",
"label-source": "Source"
},
@ -6107,8 +6273,17 @@
"url": "URL"
},
"scalar-dimension-editor": {
"fixed-value-options": {
"label-fixed-values": "Fixed value"
},
"label-limit": "Limit",
"label-value": "Value"
"label-value": "Value",
"scalar-options": {
"description-clamped": "Use field values, clamped to max and min",
"description-mod": "Use field values, mod from max",
"label-clamped": "Clamped",
"label-mod": "Mod"
}
},
"scale-dimension-editor": {
"label-max": "Max",
@ -6116,7 +6291,10 @@
"label-value": "Value"
},
"text-dimension-editor": {
"description-field": "Display field value",
"description-fixed": "Fixed value",
"label-field": "Field",
"label-fixed": "Fixed",
"label-source": "Source",
"label-template": "Template",
"label-value": "Value"

Loading…
Cancel
Save