2021-05-28 13:13:21 +10:00
|
|
|
import React from "react";
|
2021-05-27 17:19:36 +10:00
|
|
|
import { SortableContext } from "@dnd-kit/sortable";
|
2021-05-13 16:26:59 +10:00
|
|
|
|
2021-05-28 13:13:21 +10:00
|
|
|
import { moveGroupsInto } from "../../helpers/group";
|
2021-05-25 15:47:52 +10:00
|
|
|
import { keyBy } from "../../helpers/shared";
|
2021-05-21 15:12:25 +10:00
|
|
|
|
|
|
|
|
import SortableTile from "./SortableTile";
|
|
|
|
|
|
2021-05-28 13:13:21 +10:00
|
|
|
import {
|
2021-06-15 20:08:45 +10:00
|
|
|
useTileDragId,
|
|
|
|
|
useTileDragCursor,
|
|
|
|
|
useTileOverGroupId,
|
2021-05-28 13:13:21 +10:00
|
|
|
BASE_SORTABLE_ID,
|
|
|
|
|
GROUP_SORTABLE_ID,
|
|
|
|
|
} from "../../contexts/TileDragContext";
|
|
|
|
|
import { useGroup } from "../../contexts/GroupContext";
|
|
|
|
|
|
|
|
|
|
function SortableTiles({ renderTile, subgroup }) {
|
2021-06-15 20:08:45 +10:00
|
|
|
const dragId = useTileDragId();
|
|
|
|
|
const dragCursor = useTileDragCursor();
|
|
|
|
|
const overGroupId = useTileOverGroupId();
|
2021-05-28 13:13:21 +10:00
|
|
|
const {
|
2021-06-05 16:38:01 +10:00
|
|
|
groups,
|
2021-05-28 13:13:21 +10:00
|
|
|
selectedGroupIds: allSelectedIds,
|
2021-06-05 16:38:01 +10:00
|
|
|
filter,
|
2021-05-28 13:13:21 +10:00
|
|
|
openGroupId,
|
|
|
|
|
openGroupItems,
|
2021-06-05 16:38:01 +10:00
|
|
|
filteredGroupItems,
|
2021-05-28 13:13:21 +10:00
|
|
|
} = useGroup();
|
|
|
|
|
|
2021-06-05 16:38:01 +10:00
|
|
|
const activeGroups = subgroup
|
|
|
|
|
? openGroupItems
|
|
|
|
|
: filter
|
|
|
|
|
? filteredGroupItems
|
|
|
|
|
: groups;
|
|
|
|
|
|
2021-05-28 13:13:21 +10:00
|
|
|
const sortableId = subgroup ? GROUP_SORTABLE_ID : BASE_SORTABLE_ID;
|
|
|
|
|
|
|
|
|
|
// Only populate selected groups if needed
|
|
|
|
|
let selectedGroupIds = [];
|
|
|
|
|
if ((subgroup && openGroupId) || (!subgroup && !openGroupId)) {
|
|
|
|
|
selectedGroupIds = allSelectedIds;
|
2021-05-13 16:26:59 +10:00
|
|
|
}
|
2021-06-05 16:38:01 +10:00
|
|
|
const disableSorting = (openGroupId && !subgroup) || filter;
|
|
|
|
|
const disableGrouping = subgroup || disableSorting || filter;
|
2021-05-13 16:26:59 +10:00
|
|
|
|
2021-05-25 15:47:52 +10:00
|
|
|
function renderSortableGroup(group, selectedGroups) {
|
2021-05-24 13:34:21 +10:00
|
|
|
if (overGroupId === group.id && dragId && group.id !== dragId) {
|
|
|
|
|
// If dragging over a group render a preview of that group
|
2021-05-27 17:19:36 +10:00
|
|
|
const previewGroup = moveGroupsInto(
|
2021-05-25 15:47:52 +10:00
|
|
|
[group, ...selectedGroups],
|
|
|
|
|
0,
|
|
|
|
|
selectedGroups.map((_, i) => i + 1)
|
|
|
|
|
)[0];
|
|
|
|
|
return renderTile(previewGroup);
|
2021-05-24 13:34:21 +10:00
|
|
|
}
|
|
|
|
|
return renderTile(group);
|
|
|
|
|
}
|
|
|
|
|
|
2021-05-25 15:47:52 +10:00
|
|
|
function renderTiles() {
|
2021-06-05 16:38:01 +10:00
|
|
|
const groupsByIds = keyBy(activeGroups, "id");
|
2021-05-25 15:47:52 +10:00
|
|
|
const selectedGroupIdsSet = new Set(selectedGroupIds);
|
|
|
|
|
let selectedGroups = [];
|
|
|
|
|
let hasSelectedContainerGroup = false;
|
|
|
|
|
for (let groupId of selectedGroupIds) {
|
|
|
|
|
const group = groupsByIds[groupId];
|
|
|
|
|
if (group) {
|
|
|
|
|
selectedGroups.push(group);
|
|
|
|
|
if (group.type === "group") {
|
|
|
|
|
hasSelectedContainerGroup = true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2021-06-05 16:38:01 +10:00
|
|
|
return activeGroups.map((group) => {
|
2021-05-25 15:47:52 +10:00
|
|
|
const isDragging = dragId && selectedGroupIdsSet.has(group.id);
|
|
|
|
|
const disableTileGrouping =
|
|
|
|
|
disableGrouping || isDragging || hasSelectedContainerGroup;
|
|
|
|
|
return (
|
|
|
|
|
<SortableTile
|
|
|
|
|
id={group.id}
|
|
|
|
|
key={group.id}
|
|
|
|
|
disableGrouping={disableTileGrouping}
|
2021-05-28 13:13:21 +10:00
|
|
|
disableSorting={disableSorting}
|
2021-05-25 15:47:52 +10:00
|
|
|
hidden={group.id === openGroupId}
|
|
|
|
|
isDragging={isDragging}
|
2021-05-28 17:06:20 +10:00
|
|
|
cursor={dragCursor}
|
2021-05-25 15:47:52 +10:00
|
|
|
>
|
|
|
|
|
{renderSortableGroup(group, selectedGroups)}
|
|
|
|
|
</SortableTile>
|
|
|
|
|
);
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
2021-05-13 16:26:59 +10:00
|
|
|
return (
|
2021-06-05 16:38:01 +10:00
|
|
|
<SortableContext items={activeGroups} id={sortableId}>
|
2021-05-28 13:13:21 +10:00
|
|
|
{renderTiles()}
|
|
|
|
|
</SortableContext>
|
2021-05-13 16:26:59 +10:00
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export default SortableTiles;
|