Skip to content

Commit

Permalink
feat: Use beautiful drag and drop for facets
Browse files Browse the repository at this point in the history
  • Loading branch information
ptbrowne committed Jan 26, 2022
1 parent b769dcd commit a8cc140
Show file tree
Hide file tree
Showing 2 changed files with 70 additions and 12 deletions.
77 changes: 66 additions & 11 deletions app/configurator/components/chart-configurator.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,12 @@ import { Trans } from "@lingui/macro";
import { sortBy } from "lodash";
import * as React from "react";
import { useCallback } from "react";
import {
DragDropContext,
Droppable,
Draggable,
OnDragEndResponder,
} from "react-beautiful-dnd";
import { Box, Spinner } from "theme-ui";
import {
ChartConfig,
Expand All @@ -13,6 +19,7 @@ import { chartConfigOptionsUISpec } from "../../charts/chart-config-ui-options";
import { Loading } from "../../components/hint";
import { useDataCubeMetadataWithComponentValuesQuery } from "../../graphql/query-hooks";
import { DataCubeMetadata } from "../../graphql/types";
import { Icon } from "../../icons";
import { useLocale } from "../../locales/use-locale";
import {
ensureFilterValuesCorrect,
Expand Down Expand Up @@ -69,7 +76,7 @@ const DataFilterSelectGeneric = ({
</>
);
return (
<Box sx={{ px: 2, mb: 2 }}>
<Box sx={{ px: 2, mb: 2, flexGrow: 1 }}>
{dimension.__typename === "TemporalDimension" &&
dimension.timeUnit !== "Day" ? (
<DataFilterSelectTime
Expand Down Expand Up @@ -195,6 +202,20 @@ export const ChartConfigurator = ({
data?.dataCubeByIri.dimensions.filter((dim) => !mappedIris.has(dim.iri)),
[(x) => keysOrder[x.iri] ?? Infinity]
);

const handleDragEnd: OnDragEndResponder = (result) => {
const sourceIndex = result.source?.index;
const destinationIndex = result.destination?.index;
if (
typeof sourceIndex !== "number" ||
typeof destinationIndex !== "number" ||
result.source === result.destination
) {
return;
}
const delta = destinationIndex - sourceIndex;
handleMove(result.draggableId, delta);
};
return (
<>
<ControlSection>
Expand All @@ -212,24 +233,58 @@ export const ChartConfigurator = ({
/>
</ControlSectionContent>
</ControlSection>

<ControlSection sx={{ flexGrow: 1 }}>
<SectionTitle titleId="controls-data">
<Trans id="controls.section.data.filters">Filters</Trans>{" "}
{fetching ? (
<Spinner size={12} sx={{ display: "inline-block" }} />
) : null}
</SectionTitle>

<ControlSectionContent side="left" aria-labelledby="controls-data">
{filterDimensions.map((dimension, i) => (
<DataFilterSelectGeneric
key={dimension.iri}
dimension={dimension}
index={i}
onMove={(n) => handleMove(dimension.iri, n)}
disabled={fetching}
/>
))}
<DragDropContext onDragEnd={handleDragEnd}>
<Droppable droppableId="filters">
{(provided) => (
<div {...provided.droppableProps} ref={provided.innerRef}>
{filterDimensions.map((dimension, i) => (
<Draggable
draggableId={dimension.iri}
index={i}
key={dimension.iri}
>
{(provided) => (
<div
ref={provided.innerRef}
{...provided.dragHandleProps}
{...provided.draggableProps}
>
<Box
sx={{
display: "flex",
justifyContent: "stretch",
}}
>
<DataFilterSelectGeneric
key={dimension.iri}
dimension={dimension}
index={i}
onMove={(n) => handleMove(dimension.iri, n)}
disabled={fetching}
/>
<Icon
name="dragndrop"
style={{ flexShrink: 0 }}
/>
</Box>
</div>
)}
</Draggable>
))}
{provided.placeholder}
</div>
)}
</Droppable>
</DragDropContext>
</ControlSectionContent>
</ControlSection>
</>
Expand Down
5 changes: 4 additions & 1 deletion app/configurator/configurator-state.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -233,7 +233,10 @@ export const ensureFilterValuesCorrect = produce(

export const moveFilterField = produce(
(chartConfig: ChartConfig, { dimensionIri, delta, possibleValues }) => {
const keys = Object.keys(chartConfig.filters);
// Use getOwnPropertyNames instead of keys since the spec ensures that
// the order of the keys received is in insertion order
// https://262.ecma-international.org/6.0/#sec-ordinary-object-internal-methods-and-internal-slots-ownpropertykeys
const keys = Object.getOwnPropertyNames(chartConfig.filters);
const fieldIndex = Object.keys(chartConfig.filters).indexOf(dimensionIri);
if (fieldIndex === 0 && delta === -1) {
return;
Expand Down

0 comments on commit a8cc140

Please sign in to comment.