add drag and drop capabilities for the order of cluster icons on the side bar (#623)

* add drag and drop capabilities for the order of cluster icons on the side bar

* add type annotations for better clarity

* fix clusters staying in previously icon reordered workspaces

* add some tests to cluster-store

Signed-off-by: Sebastian Malton <smalton@mirantis.com>

Co-authored-by: Sebastian Malton <smalton@mirantis.com>
This commit is contained in:
Sebastian MaltonandSebastian Malton authored and GitHub committed 2020-09-04 13:32:27 -04:00
1 parent 7d2215b5b4
commit 8f94f4a3da
7 files changed
+218 -28

No files matched your search

@@ -4,6 +4,7 @@
position: relative;
border-radius: $radius;
padding: $radius;
margin-bottom: $padding * 2;
user-select: none;
cursor: pointer;
@@ -10,7 +10,7 @@ import { ClusterId, clusterStore } from "../../../common/cluster-store";
import { workspaceStore } from "../../../common/workspace-store";
import { ClusterIcon } from "../cluster-icon";
import { Icon } from "../icon";
import { cssNames, IClassName } from "../../utils";
import { cssNames, IClassName, autobind } from "../../utils";
import { Badge } from "../badge";
import { navigate } from "../../navigation";
import { addClusterURL } from "../+add-cluster";
@@ -20,6 +20,7 @@ import { Tooltip } from "../tooltip";
import { ConfirmDialog } from "../confirm-dialog";
import { clusterIpc } from "../../../common/cluster-ipc";
import { clusterViewURL, getMatchedClusterId } from "./cluster-view.route";
import { DragDropContext, Droppable, Draggable, DropResult, DroppableProvided, DraggableProvided } from "react-beautiful-dnd";
// fixme: allow to rearrange clusters with drag&drop
@@ -87,6 +88,18 @@ export class ClustersMenu extends React.Component<Props> {
})
}
@autobind()
swapClusterIconOrder(result: DropResult) {
if (result.reason === "DROP") {
const { currentWorkspaceId } = workspaceStore;
const {
source: { index: from },
destination: { index: to },
} = result
clusterStore.swapIconOrders(currentWorkspaceId, from, to)
}
}
render() {
const { className } = this.props;
const { newContexts } = userStore;
@@ -94,26 +107,46 @@ export class ClustersMenu extends React.Component<Props> {
return (
<div className={cssNames("ClustersMenu flex column", className)}>
<div className="clusters flex column gaps">
{clusters.map(cluster => {
return (
<ClusterIcon
key={cluster.id}
showErrors={true}
cluster={cluster}
isActive={cluster.id === getMatchedClusterId()}
onClick={() => this.showCluster(cluster.id)}
onContextMenu={() => this.showContextMenu(cluster)}
/>
)
})}
<DragDropContext onDragEnd={this.swapClusterIconOrder}>
<Droppable droppableId="cluster-menu" type="CLUSTER">
{(provided: DroppableProvided) => (
<div
ref={provided.innerRef}
{...provided.droppableProps}
>
{clusters.map((cluster, index) => (
<Draggable draggableId={cluster.id} index={index} key={cluster.id}>
{(provided: DraggableProvided) => (
<div
ref={provided.innerRef}
{...provided.draggableProps}
{...provided.dragHandleProps}
>
<ClusterIcon
key={cluster.id}
showErrors={true}
cluster={cluster}
isActive={cluster.id === getMatchedClusterId()}
onClick={() => this.showCluster(cluster.id)}
onContextMenu={() => this.showContextMenu(cluster)}
/>
</div>
)}
</Draggable>
))}
{provided.placeholder}
</div>
)}
</Droppable>
</DragDropContext>
</div>
<div className="add-cluster" onClick={this.addCluster}>
<Tooltip targetId="add-cluster-icon">
<Trans>Add Cluster</Trans>
</Tooltip>
<Icon big material="add" id="add-cluster-icon"/>
<Icon big material="add" id="add-cluster-icon" />
{newContexts.size > 0 && (
<Badge className="counter" label={newContexts.size} tooltip={<Trans>new</Trans>}/>
<Badge className="counter" label={newContexts.size} tooltip={<Trans>new</Trans>} />
)}
</div>
</div>