ResourceDimensionEditor.tsx 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136
  1. import React, { FC, useCallback } from 'react';
  2. import { FieldNamePickerConfigSettings, StandardEditorProps, StandardEditorsRegistryItem } from '@grafana/data';
  3. import { InlineField, InlineFieldRow, RadioButtonGroup } from '@grafana/ui';
  4. import { FieldNamePicker } from '@grafana/ui/src/components/MatchersUI/FieldNamePicker';
  5. import { getPublicOrAbsoluteUrl, ResourceFolderName } from '..';
  6. import {
  7. MediaType,
  8. ResourceDimensionConfig,
  9. ResourceDimensionMode,
  10. ResourceDimensionOptions,
  11. ResourcePickerSize,
  12. } from '../types';
  13. import { ResourcePicker } from './ResourcePicker';
  14. const resourceOptions = [
  15. { label: 'Fixed', value: ResourceDimensionMode.Fixed, description: 'Fixed value' },
  16. { label: 'Field', value: ResourceDimensionMode.Field, description: 'Use a string field result' },
  17. // { label: 'Mapping', value: ResourceDimensionMode.Mapping, description: 'Map the results of a value to an svg' },
  18. ];
  19. const dummyFieldSettings: StandardEditorsRegistryItem<string, FieldNamePickerConfigSettings> = {
  20. settings: {},
  21. } as any;
  22. export const ResourceDimensionEditor: FC<
  23. StandardEditorProps<ResourceDimensionConfig, ResourceDimensionOptions, any>
  24. > = (props) => {
  25. const { value, context, onChange, item } = props;
  26. const labelWidth = 9;
  27. const onModeChange = useCallback(
  28. (mode) => {
  29. onChange({
  30. ...value,
  31. mode,
  32. });
  33. },
  34. [onChange, value]
  35. );
  36. const onFieldChange = useCallback(
  37. (field) => {
  38. onChange({
  39. ...value,
  40. field,
  41. });
  42. },
  43. [onChange, value]
  44. );
  45. const onFixedChange = useCallback(
  46. (fixed?: string) => {
  47. onChange({
  48. ...value,
  49. fixed: fixed ?? '',
  50. });
  51. },
  52. [onChange, value]
  53. );
  54. const onClear = (event: React.MouseEvent) => {
  55. event.stopPropagation();
  56. onChange({ mode: ResourceDimensionMode.Fixed, fixed: '', field: '' });
  57. };
  58. const mode = value?.mode ?? ResourceDimensionMode.Fixed;
  59. const showSourceRadio = item.settings?.showSourceRadio ?? true;
  60. const mediaType = item.settings?.resourceType ?? MediaType.Icon;
  61. const folderName = item.settings?.folderName ?? ResourceFolderName.Icon;
  62. let srcPath = '';
  63. if (mediaType === MediaType.Icon) {
  64. if (value?.fixed) {
  65. srcPath = getPublicOrAbsoluteUrl(value.fixed);
  66. } else if (item.settings?.placeholderValue) {
  67. srcPath = getPublicOrAbsoluteUrl(item.settings.placeholderValue);
  68. }
  69. }
  70. return (
  71. <>
  72. {showSourceRadio && (
  73. <InlineFieldRow>
  74. <InlineField label="Source" labelWidth={labelWidth} grow={true}>
  75. <RadioButtonGroup value={mode} options={resourceOptions} onChange={onModeChange} fullWidth />
  76. </InlineField>
  77. </InlineFieldRow>
  78. )}
  79. {mode !== ResourceDimensionMode.Fixed && (
  80. <InlineFieldRow>
  81. <InlineField label="Field" labelWidth={labelWidth} grow={true}>
  82. <FieldNamePicker
  83. context={context}
  84. value={value.field ?? ''}
  85. onChange={onFieldChange}
  86. item={dummyFieldSettings}
  87. />
  88. </InlineField>
  89. </InlineFieldRow>
  90. )}
  91. {mode === ResourceDimensionMode.Fixed && (
  92. <ResourcePicker
  93. onChange={onFixedChange}
  94. onClear={onClear}
  95. value={value?.fixed}
  96. src={srcPath}
  97. placeholder={item.settings?.placeholderText ?? 'Select a value'}
  98. name={niceName(value?.fixed) ?? ''}
  99. mediaType={mediaType}
  100. folderName={folderName}
  101. size={ResourcePickerSize.NORMAL}
  102. />
  103. )}
  104. {mode === ResourceDimensionMode.Mapping && (
  105. <InlineFieldRow>
  106. <InlineField label="Mappings" labelWidth={labelWidth} grow={true}>
  107. <div>TODO mappings editor!</div>
  108. </InlineField>
  109. </InlineFieldRow>
  110. )}
  111. </>
  112. );
  113. };
  114. export function niceName(value?: string): string | undefined {
  115. if (!value) {
  116. return undefined;
  117. }
  118. const idx = value.lastIndexOf('/');
  119. if (idx > 0) {
  120. return value.substring(idx + 1);
  121. }
  122. return value;
  123. }