Transformations: Support time format when converting time to strings (#63826)

pull/63997/head
Ryan McKinley 2 years ago committed by GitHub
parent bc1c54ca17
commit a4fc8b9fca
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 25
      packages/grafana-data/src/transformations/transformers/convertFieldType.test.ts
  2. 21
      packages/grafana-data/src/transformations/transformers/convertFieldType.ts
  3. 26
      packages/grafana-ui/src/types/icon.ts
  4. 18
      public/app/features/transformers/editors/ConvertFieldTypeTransformerEditor.tsx

@ -338,6 +338,31 @@ describe('field convert types transformer', () => {
}, },
]); ]);
}); });
it('will convert time fields to strings', () => {
const options = {
conversions: [{ targetField: 'time', destinationType: FieldType.string, dateFormat: 'YYYY-MM' }],
};
const stringified = convertFieldTypes(options, [
toDataFrame({
fields: [
{
name: 'time',
type: FieldType.time,
values: [1626674400000, 1627020000000, 1627192800000, 1627797600000, 1627884000000],
},
],
}),
])[0].fields[0];
expect(stringified.values.toArray()).toEqual([
'2021-07',
'2021-07',
'2021-07', // can group by month
'2021-08',
'2021-08',
]);
});
}); });
describe('ensureTimeField', () => { describe('ensureTimeField', () => {

@ -98,7 +98,7 @@ export function convertFieldType(field: Field, opts: ConvertFieldTypeOptions): F
case FieldType.number: case FieldType.number:
return fieldToNumberField(field); return fieldToNumberField(field);
case FieldType.string: case FieldType.string:
return fieldToStringField(field); return fieldToStringField(field, opts.dateFormat);
case FieldType.boolean: case FieldType.boolean:
return fieldToBooleanField(field); return fieldToBooleanField(field);
case FieldType.other: case FieldType.other:
@ -179,17 +179,26 @@ function fieldToBooleanField(field: Field): Field {
}; };
} }
function fieldToStringField(field: Field): Field { function fieldToStringField(field: Field, dateFormat?: string): Field {
const stringValues = field.values.toArray().slice(); let values = field.values.toArray();
for (let s = 0; s < stringValues.length; s++) { switch (field.type) {
stringValues[s] = `${stringValues[s]}`; case FieldType.time:
values = values.map((v) => dateTimeParse(v).format(dateFormat));
break;
case FieldType.other:
values = values.map((v) => JSON.stringify(v));
break;
default:
values = values.map((v) => `${v}`);
} }
return { return {
...field, ...field,
type: FieldType.string, type: FieldType.string,
values: new ArrayVector(stringValues), values: new ArrayVector(values),
}; };
} }

@ -12,7 +12,10 @@ export type IconSize = ComponentSize | 'xl' | 'xxl' | 'xxxl';
// function remains for backwards compatibility // function remains for backwards compatibility
export const getAvailableIcons = () => Object.keys(availableIconsIndex); export const getAvailableIcons = () => Object.keys(availableIconsIndex);
/** Get the icon for a given field type */ /**
* Get the icon for a given field type
* @deprecated use getFieldTypeIconName
*/
export function getFieldTypeIcon(field?: Field): IconName { export function getFieldTypeIcon(field?: Field): IconName {
if (field) { if (field) {
switch (field.type) { switch (field.type) {
@ -34,3 +37,24 @@ export function getFieldTypeIcon(field?: Field): IconName {
} }
return 'question-circle'; return 'question-circle';
} }
/** Get the icon for a given field type */
export function getFieldTypeIconName(fieldType?: FieldType): IconName {
switch (fieldType) {
case FieldType.time:
return 'clock-nine';
case FieldType.string:
return 'font';
case FieldType.number:
return 'calculator-alt';
case FieldType.boolean:
return 'toggle-on';
case FieldType.trace:
return 'info-circle';
case FieldType.geo:
return 'map-marker';
case FieldType.other:
return 'brackets-curly';
}
return 'question-circle';
}

@ -14,8 +14,9 @@ import {
ConvertFieldTypeOptions, ConvertFieldTypeOptions,
ConvertFieldTypeTransformerOptions, ConvertFieldTypeTransformerOptions,
} from '@grafana/data/src/transformations/transformers/convertFieldType'; } from '@grafana/data/src/transformations/transformers/convertFieldType';
import { Button, InlineField, InlineFieldRow, Input, Select } from '@grafana/ui'; import { Button, InlineField, InlineFieldRow, Input, Select, getFieldTypeIconName } from '@grafana/ui';
import { FieldNamePicker } from '@grafana/ui/src/components/MatchersUI/FieldNamePicker'; import { FieldNamePicker } from '@grafana/ui/src/components/MatchersUI/FieldNamePicker';
import { findField } from 'app/features/dimensions';
const fieldNamePickerSettings: StandardEditorsRegistryItem<string, FieldNamePickerConfigSettings> = { const fieldNamePickerSettings: StandardEditorsRegistryItem<string, FieldNamePickerConfigSettings> = {
settings: { width: 24, isClearable: false }, settings: { width: 24, isClearable: false },
@ -27,11 +28,11 @@ export const ConvertFieldTypeTransformerEditor = ({
onChange, onChange,
}: TransformerUIProps<ConvertFieldTypeTransformerOptions>) => { }: TransformerUIProps<ConvertFieldTypeTransformerOptions>) => {
const allTypes: Array<SelectableValue<FieldType>> = [ const allTypes: Array<SelectableValue<FieldType>> = [
{ value: FieldType.number, label: 'Numeric' }, { value: FieldType.number, label: 'Number', icon: getFieldTypeIconName(FieldType.number) },
{ value: FieldType.string, label: 'String' }, { value: FieldType.string, label: 'String', icon: getFieldTypeIconName(FieldType.string) },
{ value: FieldType.time, label: 'Time' }, { value: FieldType.time, label: 'Time', icon: getFieldTypeIconName(FieldType.time) },
{ value: FieldType.boolean, label: 'Boolean' }, { value: FieldType.boolean, label: 'Boolean', icon: getFieldTypeIconName(FieldType.boolean) },
{ value: FieldType.other, label: 'JSON' }, { value: FieldType.other, label: 'JSON', icon: getFieldTypeIconName(FieldType.other) },
]; ];
const onSelectField = useCallback( const onSelectField = useCallback(
@ -122,6 +123,11 @@ export const ConvertFieldTypeTransformerEditor = ({
<Input value={c.dateFormat} placeholder={'e.g. YYYY-MM-DD'} onChange={onInputFormat(idx)} width={24} /> <Input value={c.dateFormat} placeholder={'e.g. YYYY-MM-DD'} onChange={onInputFormat(idx)} width={24} />
</InlineField> </InlineField>
)} )}
{c.destinationType === FieldType.string && (c.dateFormat || findField(input?.[0], c.targetField)) && (
<InlineField label="Date format" tooltip="Specify the output format.">
<Input value={c.dateFormat} placeholder={'e.g. YYYY-MM-DD'} onChange={onInputFormat(idx)} width={24} />
</InlineField>
)}
<Button <Button
size="md" size="md"
icon="trash-alt" icon="trash-alt"

Loading…
Cancel
Save