Skip to content

Commit

Permalink
feat(widget-builder): Make visualize fields draggable for ordering (#…
Browse files Browse the repository at this point in the history
…84814)

One of the features we had left to implement was drag and drop ordering
of the visualize fields. On any non-bignumber widget will have the
draggable feature where there are 2 or more fields.

Here's what it looks like:



https://github.com/user-attachments/assets/7182b79d-65c5-4c39-912d-574413f7c8a1

Fair warning it looks like a lot of code changes but it's mostly
whitespace changes. I've created a general sortable component and a
"ghost" component to show when dragging.
  • Loading branch information
nikkikapadia authored Feb 10, 2025
1 parent 50f64f4 commit 3737e96
Show file tree
Hide file tree
Showing 4 changed files with 954 additions and 515 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
import {useSortable} from '@dnd-kit/sortable';
import {CSS} from '@dnd-kit/utilities';
import {useTheme} from '@emotion/react';
import styled from '@emotion/styled';

import {Button} from 'sentry/components/button';
import {IconGrabbable} from 'sentry/icons';
import {t} from 'sentry/locale';
import {space} from 'sentry/styles/space';

function SortableVisualizeFieldWrapper({
dragId,
canDrag,
children,
}: {
canDrag: boolean;
children: React.ReactNode;
dragId: string;
}) {
const theme = useTheme();
const {listeners, setNodeRef, transform, transition, attributes, isDragging} =
useSortable({
id: dragId,
transition: null,
disabled: !canDrag,
});

let style = {
transform: CSS.Transform.toString(transform),
transition,
zIndex: 'auto',
display: 'flex',
gap: space(1),
width: '100%',
} as React.CSSProperties;

if (isDragging) {
style = {
...style,
zIndex: 100,
height: theme.form.md.height,
border: `2px dashed ${theme.border}`,
borderRadius: theme.borderRadius,
};
}

return (
<div ref={setNodeRef} style={style}>
{canDrag && (
<DragAndReorderButton
{...listeners}
{...attributes}
aria-label={t('Drag to reorder')}
icon={<IconGrabbable size="xs" />}
size="zero"
borderless
isDragging={isDragging}
/>
)}
{children}
</div>
);
}

export default SortableVisualizeFieldWrapper;

const DragAndReorderButton = styled(Button)<{isDragging: boolean}>`
height: ${p => p.theme.form.md.height}px;
${p => p.isDragging && p.theme.visuallyHidden}
`;
Original file line number Diff line number Diff line change
Expand Up @@ -959,6 +959,30 @@ describe('Visualize', () => {
expect(removeButtons[1]).toBeDisabled();
});

it('shows draggable button when there is more than one field on non big number widgets', async () => {
render(
<WidgetBuilderProvider>
<Visualize />
</WidgetBuilderProvider>,
{
organization,
router: RouterFixture({
location: LocationFixture({
query: {
dataset: WidgetType.TRANSACTIONS,
field: ['transaction.duration', 'transaction.id'],
displayType: DisplayType.TABLE,
},
}),
}),
}
);

expect(await screen.findAllByRole('button', {name: 'Drag to reorder'})).toHaveLength(
2
);
});

describe('spans', () => {
beforeEach(() => {
jest.mocked(useSpanTags).mockImplementation((type?: 'string' | 'number') => {
Expand Down
Loading

0 comments on commit 3737e96

Please sign in to comment.