Skip to content

Commit b45858c

Browse files
committed
improve SortedFieldsEditor
1 parent b6ae599 commit b45858c

File tree

1 file changed

+35
-29
lines changed

1 file changed

+35
-29
lines changed

src/components/QueryEditor/QueryBuilder/Editors/SortedFieldsEditor.tsx

Lines changed: 35 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import React, { useState } from 'react';
22

33
import { SelectableValue } from '@grafana/data';
44
import { QueryBuilderOperationParamEditorProps } from '@grafana/plugin-ui';
5-
import { Icon, MultiSelect } from '@grafana/ui';
5+
import { FormatOptionLabelMeta, Icon, MultiSelect } from '@grafana/ui';
66

77
import { getValue, quoteString, unquoteString } from '../utils/stringHandler';
88
import { splitByUnescapedChar, SplitString, splitString } from '../utils/stringSplitter';
@@ -24,6 +24,10 @@ export default function SortedFieldsEditor(props: QueryBuilderOperationParamEdit
2424
const setFields = (values: FieldWithDirection[]) => {
2525
setValues(values);
2626
const newValue = values.map((field) => {
27+
const isRaw = field.isDesc === undefined;
28+
if (isRaw) {
29+
return quoteString(field as unknown as string);
30+
}
2731
return field.isDesc ? `${quoteString(field.name)} desc` : `${quoteString(field.name)}`;
2832
}).join(', ');
2933
onChange(index, newValue);
@@ -42,11 +46,39 @@ export default function SortedFieldsEditor(props: QueryBuilderOperationParamEdit
4246
setIsLoading(true);
4347
let options = await getFieldNameOptions(props);
4448
const selectedNames = values.map(v => v.name);
45-
options = options.filter((opt: SelectableValue<FieldWithDirection>) => opt.value && !selectedNames.includes(opt.value.name));
49+
options = options.filter((opt: SelectableValue<string>) => opt.value && !selectedNames.includes(opt.value));
4650
setOptions(options);
4751
setIsLoading(false);
4852
}
4953

54+
const handleFormatOptionLabel = (option: SelectableValue<FieldWithDirection>, { context }: FormatOptionLabelMeta<FieldWithDirection>) => {
55+
if (context === 'value') {
56+
const field = option as FieldWithDirection;
57+
const handleToggle = (e: React.SyntheticEvent) => {
58+
e.stopPropagation();
59+
const idx = values.findIndex((v) => (v).name === field.name);
60+
if (idx !== -1) {
61+
toggleDirection(idx);
62+
}
63+
};
64+
return (
65+
<span
66+
tabIndex={0}
67+
style={{ cursor: 'pointer' }}
68+
onMouseDown={handleToggle}
69+
title={field.isDesc ? 'Sorting descending' : 'Sorting ascending'}
70+
>
71+
{formatFieldLabel(field)}
72+
<Icon
73+
name={field.isDesc ? 'arrow-down' : 'arrow-up'}
74+
style={{ marginLeft: '4px', verticalAlign: 'middle' }}
75+
/>
76+
</span>
77+
);
78+
}
79+
return <>{option.label}</>;
80+
}
81+
5082
return (
5183
<MultiSelect<FieldWithDirection>
5284
openMenuOnFocus
@@ -59,33 +91,7 @@ export default function SortedFieldsEditor(props: QueryBuilderOperationParamEdit
5991
options={options}
6092
value={values}
6193
onChange={(values) => setFields(values.map((v) => v.value || v as FieldWithDirection))}
62-
formatOptionLabel={(option, { context }) => {
63-
if (context === 'value') {
64-
const field = option as FieldWithDirection;
65-
const handleToggle = (e: React.SyntheticEvent) => {
66-
e.stopPropagation();
67-
const idx = values.findIndex((v) => (v).name === field.name);
68-
if (idx !== -1) {
69-
toggleDirection(idx);
70-
}
71-
};
72-
return (
73-
<span
74-
tabIndex={0}
75-
style={{ cursor: 'pointer' }}
76-
onMouseDown={handleToggle}
77-
title={field.isDesc ? 'Sorting descending' : 'Sorting ascending'}
78-
>
79-
{formatFieldLabel(field)}
80-
<Icon
81-
name={field.isDesc ? 'arrow-down' : 'arrow-up'}
82-
style={{ marginLeft: '4px', verticalAlign: 'middle' }}
83-
/>
84-
</span>
85-
);
86-
}
87-
return <>{option.label}</>;
88-
}}
94+
formatOptionLabel={handleFormatOptionLabel}
8995
/>
9096
);
9197
}

0 commit comments

Comments
 (0)