queryField.tsx 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990
  1. import {Fragment} from 'react';
  2. import {DraggableSyntheticListeners, UseDraggableArguments} from '@dnd-kit/core';
  3. import styled from '@emotion/styled';
  4. import {Button} from 'sentry/components/button';
  5. import {IconDelete, IconGrabbable} from 'sentry/icons';
  6. import {t} from 'sentry/locale';
  7. import {space} from 'sentry/styles/space';
  8. import {QueryFieldValue} from 'sentry/utils/discover/fields';
  9. import {QueryField as TableQueryField} from 'sentry/views/discover/table/queryField';
  10. import {FieldValueKind} from 'sentry/views/discover/table/types';
  11. export interface QueryFieldProps {
  12. fieldOptions: React.ComponentProps<typeof TableQueryField>['fieldOptions'];
  13. onChange: (newValue: QueryFieldValue) => void;
  14. value: QueryFieldValue;
  15. attributes?: UseDraggableArguments['attributes'];
  16. canDelete?: boolean;
  17. canDrag?: boolean;
  18. forwardRef?: React.Ref<HTMLDivElement>;
  19. isDragging?: boolean;
  20. listeners?: DraggableSyntheticListeners;
  21. onDelete?: () => void;
  22. style?: React.CSSProperties;
  23. }
  24. export function QueryField({
  25. onDelete,
  26. onChange,
  27. fieldOptions,
  28. value,
  29. forwardRef,
  30. listeners,
  31. attributes,
  32. canDelete,
  33. canDrag,
  34. style,
  35. isDragging,
  36. }: QueryFieldProps) {
  37. return (
  38. <QueryFieldWrapper ref={forwardRef} style={style}>
  39. {isDragging ? null : (
  40. <Fragment>
  41. {canDrag && (
  42. <DragAndReorderButton
  43. {...listeners}
  44. {...attributes}
  45. aria-label={t('Drag to reorder')}
  46. icon={<IconGrabbable size="xs" />}
  47. size="zero"
  48. borderless
  49. />
  50. )}
  51. <TableQueryField
  52. placeholder={t('Select group')}
  53. fieldValue={value}
  54. fieldOptions={fieldOptions}
  55. onChange={onChange}
  56. filterPrimaryOptions={option => option.value.kind !== FieldValueKind.FUNCTION}
  57. />
  58. {canDelete && (
  59. <Button
  60. size="zero"
  61. borderless
  62. onClick={onDelete}
  63. icon={<IconDelete />}
  64. title={t('Remove group')}
  65. aria-label={t('Remove group')}
  66. />
  67. )}
  68. </Fragment>
  69. )}
  70. </QueryFieldWrapper>
  71. );
  72. }
  73. const DragAndReorderButton = styled(Button)`
  74. height: ${p => p.theme.form.md.height}px;
  75. `;
  76. const QueryFieldWrapper = styled('div')`
  77. display: flex;
  78. align-items: center;
  79. justify-content: space-between;
  80. width: 100%;
  81. > * + * {
  82. margin-left: ${space(1)};
  83. }
  84. `;