Skip to content

Commit

Permalink
drag and drop to reorder requests within the collection #23
Browse files Browse the repository at this point in the history
  • Loading branch information
Inchan Hwang committed Jul 27, 2020
1 parent 0dde147 commit 9284266
Show file tree
Hide file tree
Showing 6 changed files with 149 additions and 22 deletions.
51 changes: 51 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@
"node-fetch": "^2.6.0",
"protobufjs": "^6.8.8",
"react": "^16.12.0",
"react-beautiful-dnd": "^13.0.0",
"react-dom": "^16.12.0",
"react-redux": "^7.1.3",
"react-tooltip": "^4.1.0",
Expand All @@ -80,6 +81,7 @@
"@types/jest": "^25.1.4",
"@types/node-fetch": "^2.5.5",
"@types/react": "^16.9.19",
"@types/react-beautiful-dnd": "^13.0.0",
"@types/react-dom": "^16.9.5",
"@types/react-redux": "^7.1.7",
"@types/react-tooltip": "^3.11.0",
Expand Down
23 changes: 22 additions & 1 deletion src/renderer/components/Collection/CollectionActions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,15 @@ type CloseFM = {

const CLOSE_FM = 'CLOSE_FM';

type ReorderFlow = {
type: 'REORDER_FLOW';
collectionName: string;
src: number;
dst: number;
};

const REORDER_FLOW = 'REORDER_FLOW';

export const CollectionActionTypes = [
CREATE_COLLECTION,
CHANGE_COLLECTION_NAME,
Expand All @@ -74,7 +83,9 @@ export const CollectionActionTypes = [
DELETE_FLOW,
OPEN_FM,
CLOSE_FM,
REORDER_FLOW,
];

export type CollectionAction =
| CreateCollection
| ChangeCollectionName
Expand All @@ -84,7 +95,8 @@ export type CollectionAction =
| SelectFlow
| DeleteFlow
| OpenFM
| CloseFM;
| CloseFM
| ReorderFlow;

export function createCollection(collectionName: string): CreateCollection {
return {
Expand Down Expand Up @@ -151,3 +163,12 @@ export function closeFM(): CloseFM {
type: CLOSE_FM,
};
}

export function reorderFlow(collectionName: string, src: number, dst: number): ReorderFlow {
return {
type: REORDER_FLOW,
collectionName,
src,
dst,
};
}
8 changes: 8 additions & 0 deletions src/renderer/components/Collection/CollectionReducer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,14 @@ export default function CollectionReducer(s: AppState, action: AnyAction): AppSt
return produce(s, draft => {
draft.fmOpenCollection = undefined;
});
case 'REORDER_FLOW':
return produce(s, draft => {
const flows = getByKey(draft.collections, a.collectionName)?.flows;
if (!flows) return draft;

const [rm] = flows.splice(a.src, 1);
flows.splice(a.dst, 0, rm);
});
default:
return s;
}
Expand Down
2 changes: 1 addition & 1 deletion src/renderer/components/Collection/CollectionSider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ const CollectionSider: React.FunctionComponent<{}> = ({}) => {
{collections.map(([name]) => {
const header = <CollectionCell collectionName={name} />;
return (
<Panel key={name} header={header} style={{ paddingBottom: 4 }}>
<Panel key={name} header={header}>
<FlowList collectionName={name} />
</Panel>
);
Expand Down
85 changes: 65 additions & 20 deletions src/renderer/components/Collection/FlowList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,17 @@ import styled from 'styled-components';
import { prevent, getByKey } from '../../utils/utils';
import { useSelector, useDispatch } from 'react-redux';
import { AppState } from '../../models/AppState';
import { selectFlow, deleteFlow } from './CollectionActions';
import { selectFlow, deleteFlow, reorderFlow } from './CollectionActions';
import { DragDropContext, DropResult, Draggable, Droppable } from 'react-beautiful-dnd';

const ClickableItem = styled(List.Item)`
display: flex;
justify-content: space-between;
padding: 8px;
&:hover {
cursor: pointer;
background-color: #f7fcff;
}
padding: 0;
`;

type Props = {
Expand Down Expand Up @@ -42,29 +43,51 @@ const FlowList: React.FunctionComponent<Props> = ({ collectionName }) => {
}
}

function handleDragEnd(result: DropResult): void {
console.log(result);
if (!result.destination || result.source.droppableId != result.destination.droppableId) return;

const src = result.source.index;
const dst = result.destination.index;

dispatch(reorderFlow(collectionName, src, dst));
}

return (
<List
dataSource={flowNames}
renderItem={(flowName): React.ReactNode => (
<FlowCell
flowName={flowName}
emphasize={isCurrentCollection && currentFlow === flowName}
handleSelection={handleSelection}
handleDelete={handleDelete}
/>
)}
/>
<DragDropContext onDragEnd={handleDragEnd}>
<Droppable droppableId={collectionName}>
{(provided, snapshot): React.ReactElement => (
<div {...provided.droppableProps} ref={provided.innerRef}>
<List
dataSource={flowNames}
rowKey={(name): string => name}
renderItem={(flowName, idx): React.ReactNode => (
<FlowCell
idx={idx}
flowName={flowName}
emphasize={isCurrentCollection && currentFlow === flowName}
handleSelection={handleSelection}
handleDelete={handleDelete}
/>
)}
/>
{provided.placeholder}
</div>
)}
</Droppable>
</DragDropContext>
);
};

type CellProps = {
flowName: string;
emphasize: boolean;
idx: number;
handleSelection: (name: string) => void;
handleDelete: (name: string) => void;
};

const FlowCell: React.FC<CellProps> = ({ flowName, emphasize, handleSelection, handleDelete }) => {
const FlowCell: React.FC<CellProps> = ({ flowName, emphasize, handleSelection, handleDelete, idx }) => {
const [menuVisible, setMenuVisible] = React.useState(false);
function showMenu(): void {
setMenuVisible(true);
Expand Down Expand Up @@ -97,12 +120,34 @@ const FlowCell: React.FC<CellProps> = ({ flowName, emphasize, handleSelection, h
onVisibleChange={setMenuVisible}
>
<ClickableItem onClick={(): void => handleSelection(flowName)} onContextMenu={prevent(showMenu)}>
<Typography.Text
strong={emphasize}
style={{ userSelect: 'none', color: emphasize ? 'rgb(47, 93, 232)' : undefined }}
>
{flowName}
</Typography.Text>
<Draggable draggableId={flowName} index={idx}>
{(provided, snapshot): React.ReactElement => {
const style: React.CSSProperties = {
width: '100%',
height: '100%',
padding: 8,
boxSizing: 'border-box',
};

const { style: draggableStyle, ...draggableRest } = provided.draggableProps;

return (
<div
ref={provided.innerRef}
{...provided.dragHandleProps}
{...draggableRest}
style={{ ...style, ...draggableStyle }}
>
<Typography.Text
strong={emphasize}
style={{ userSelect: 'none', color: emphasize ? 'rgb(47, 93, 232)' : undefined }}
>
{flowName}
</Typography.Text>
</div>
);
}}
</Draggable>
</ClickableItem>
</Popover>
);
Expand Down

0 comments on commit 9284266

Please sign in to comment.