Skip to content

Commit

Permalink
feat: draggable icon
Browse files Browse the repository at this point in the history
  • Loading branch information
jazelly committed Aug 8, 2024
1 parent c85de61 commit 8134e81
Show file tree
Hide file tree
Showing 9 changed files with 106 additions and 77 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -40,12 +40,11 @@ export const AnimatedDropdown = ({
</div>

<div
className={`absolute right-0 mt-1 origin-top-right bg-white rounded-md shadow-lg ring-1 ring-black ring-opacity-5 focus:outline-none transition-all duration-200 ease-in-out ${
className={`absolute left-0 mt-1 origin-top-right shadow-lg ring-1 ring-black ring-opacity-5 focus:outline-none transition-all duration-200 ease-in-out ${
isOpen
? 'transform opacity-100 scale-100'
: 'transform opacity-0 scale-95 pointer-events-none'
}`}
style={{ width: divWidth }}
>
{children}
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ export const PortalToFollowElemTrigger = React.forwardRef<
return (
<div
ref={ref}
className={cn('inline-block', props.className)}
className={cn(props.className)}
// The user can style the trigger based on the state
data-state={context.open ? 'open' : 'closed'}
{...context.getReferenceProps(props)}
Expand Down
1 change: 1 addition & 0 deletions frontend/src/components/reusable/TooltipPlus.component.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ export const TooltipPlus: FC<TooltipProps> = ({
<PortalToFollowElemTrigger
onMouseEnter={handleTriggerMouseEnter}
onMouseLeave={handleTriggerMouseLeave}
className="w-full"
>
{children}
</PortalToFollowElemTrigger>
Expand Down
137 changes: 86 additions & 51 deletions frontend/src/components/workflow/NodeSelector.component.tsx
Original file line number Diff line number Diff line change
@@ -1,18 +1,45 @@
import { HouseLine, MathOperations, PlusCircle } from '@phosphor-icons/react';
import {
Database,
HouseLine,
MathOperations,
PlusCircle,
Question,
} from '@phosphor-icons/react';
import cn from 'classnames';
import { t } from 'i18next';
import React, { useEffect, useRef, useState } from 'react';
import { TooltipPlus } from '../reusable/TooltipPlus.component';
import { AnimatedDropdown } from '../reusable/AnimatedDropdown.component';
import { useDrag, useDragLayer } from 'react-dnd';
import { DragPreviewImage, useDrag, useDragLayer } from 'react-dnd';
import CustomNode from './nodes';
import { BlockEnum } from './types';
import styled from 'styled-components';
import { QuestionMarkCircleIcon } from '@heroicons/react/20/solid';

const DraggableNode = ({ type, children }) => {
const DraggableNode = ({ type, children, className }) => {
const ref = useRef(null);
const previewRef = useRef();
const [{ isDragging }, drag, preview] = useDrag(() => ({
type,
item: { type: 'customNode' },
item: { type },
collect: (monitor) => ({
isDragging: !!monitor.isDragging(),
isDragging: monitor.isDragging(),
}),
end: (item, monitor) => {
if (monitor.didDrop()) {
const x = monitor.getSourceClientOffset()?.x;
const y = monitor.getSourceClientOffset()?.y;
console.log('x, y', x, y);
}
},
options: {
dropEffect: 'move',
previewOptions: {
anchorX: 0.5,
anchorY: 0.5,
component: DragPreview,
},
},
}));

useEffect(() => {
Expand All @@ -22,10 +49,9 @@ const DraggableNode = ({ type, children }) => {
}, [preview]);

return (
<>
<div ref={drag} className={cn(isDragging ? 'cursor-move' : '', className)}>
{children}
{isDragging && <DragLayer type={type}/>}
</>
</div>
);
};

Expand Down Expand Up @@ -54,61 +80,70 @@ const DragLayer = ({ type }) => {

return (
<div style={layerStyles}>
<DragPreview type={type}/>
<DragPreview type={type} />
</div>
);
};

const DragPreview = ({ type }) => {
return (

);
// return <CustomNode data={{ type }} />
return <div className="h2 text-white">NMSL</div>;
};

export const NodeSelector = () => {
return (
<AnimatedDropdown size={30} color="#E5E7EB">
<div className="flex flex-col items-center pb-2 px-1 w-full">
<div className="mt-2">
<TooltipPlus
position="right"
offset={4}
hideArrow
popupClassName="!p-0 !bg-gray-25"
popupContent={
<div className="flex items-center gap-1 px-2 h-6 text-xs font-medium text-gray-700 rounded-lg border-[0.5px] border-black/5">
{t('workflow.blocks.start')}
</div>
}
<div className="flex flex-col items-center pb-2 px-1 w-32 bg-white rounded-md text-black">
<TooltipPlus
position="right"
offset={4}
hideArrow
popupClassName="!p-0 !bg-gray-25"
popupContent={
<div className="flex items-center gap-1 px-2 h-6 text-xs font-medium text-gray-700 rounded-lg border-[0.5px] border-black/5">
Use the Dataset node to specify your input data
</div>
}
>
<DraggableNode
type={BlockEnum.Dataset}
className="mt-2 flex items-center justify-between w-full cursor-pointer"
>
<HouseLine
size={22}
color="#6B7280"
weight="fill"
className="cursor-pointer"
/>
</TooltipPlus>
</div>
<div className="mt-2">
<TooltipPlus
position="right"
offset={4}
hideArrow
popupClassName="!p-0 !bg-gray-25"
popupContent={
<div className="flex items-center gap-1 px-2 h-6 text-xs font-medium text-gray-700 rounded-lg border-[0.5px] border-black/5">
{t('workflow.blocks.train')}
</div>
}
<div className="flex items-center">
<Database size={22} color="#9B7280" weight="fill" />
<span className="ml-1 text-sm">Dataset</span>
</div>
<Question size={18} color={'#1b1b1f'} />
</DraggableNode>
</TooltipPlus>

<TooltipPlus
position="right"
offset={4}
hideArrow
popupClassName="!p-0 !bg-gray-25"
popupContent={
<div className="flex items-center gap-1 px-2 h-6 text-xs font-medium text-gray-700 rounded-lg border-[0.5px] border-black/5">
Use the Train node to specify a model training job
</div>
}
>
<DraggableNode
type={BlockEnum.Train}
className="mt-2 flex items-center justify-between w-full cursor-pointer"
>
<MathOperations
size={22}
color="#6B7280"
weight="fill"
className="cursor-pointer"
/>
</TooltipPlus>
</div>
<div className="flex items-center">
<MathOperations
size={22}
color="#6B7280"
weight="fill"
className="cursor-pointer"
/>
<span className="ml-1 text-sm">Train</span>
</div>
<Question size={18} />
</DraggableNode>
</TooltipPlus>
</div>
</AnimatedDropdown>
);
Expand Down
2 changes: 1 addition & 1 deletion frontend/src/components/workflow/block-selector/blocks.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import React from 'react';
import { memo, useCallback, useMemo } from 'react';
import { useTranslation } from 'react-i18next';
import { groupBy } from 'lodash-es';
Expand All @@ -8,7 +9,6 @@ import { BLOCK_CLASSIFICATIONS } from './constants';
import { useBlocks } from './hooks';
import type { ToolDefaultValue } from './types';
import Tooltip from '@/components/reusable/Tooltip.component';
import React from 'react';

type BlocksProps = {
searchText: string;
Expand Down
18 changes: 11 additions & 7 deletions frontend/src/components/workflow/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,8 @@ import { TrainerMessageMapContext } from '@/contexts/TrainerMessageMap.context';
import { NodeDetailStateProvider } from '@/contexts/Workflow.context';
import { useNavigate } from 'react-router-dom';
import { v4 } from 'uuid';
import { DndProvider } from 'react-dnd';
import { HTML5Backend } from 'react-dnd-html5-backend';

const nodeTypes = {
custom: CustomNode,
Expand Down Expand Up @@ -290,13 +292,15 @@ const WorkflowWrap = memo(() => {
}

return (
<ReactFlowProvider>
<Workflow
nodes={nodesAndEdges.nodes}
edges={nodesAndEdges.edges}
viewport={data.viewport}
/>
</ReactFlowProvider>
<DndProvider backend={HTML5Backend}>
<ReactFlowProvider>
<Workflow
nodes={nodesAndEdges.nodes}
edges={nodesAndEdges.edges}
viewport={data.viewport}
/>
</ReactFlowProvider>
</DndProvider>
);
});
WorkflowWrap.displayName = 'WorkflowWrap';
Expand Down
7 changes: 4 additions & 3 deletions frontend/src/components/workflow/nodes/base/base.node.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@ import NodeControl from './components/node-control';

type BaseNodeProps = {
children: ReactElement;
} & NodeProps;
} & NodeProps & { className?: string };

const BaseNode: FC<BaseNodeProps> = ({ id, data, children }) => {
const BaseNode: FC<BaseNodeProps> = ({ id, data, children, className }) => {
const nodeRef = useRef<HTMLDivElement>(null);

const showSelectedBorder = data.selected || data._isEntering;
Expand All @@ -33,7 +33,8 @@ const BaseNode: FC<BaseNodeProps> = ({ id, data, children }) => {
<div
className={cn(
'flex border-[2px] rounded-2xl',
showSelectedBorder ? 'border-primary-600' : 'border-transparent'
showSelectedBorder ? 'border-primary-600' : 'border-transparent',
className
)}
ref={nodeRef}
>
Expand Down
2 changes: 1 addition & 1 deletion frontend/src/components/workflow/nodes/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import type { NodeProps } from 'reactflow';
import { NodeComponentMap } from '../constants';
import BaseNode from './base/base.node';

const CustomNode = (props: NodeProps) => {
const CustomNode = (props: NodeProps & { className: string }) => {
const nodeData = props.data;
const NodeComponent = NodeComponentMap[nodeData.type];
console.log('nodeData', nodeData);
Expand Down
11 changes: 0 additions & 11 deletions frontend/src/components/workflow/nodes/trainer.node.tsx

This file was deleted.

0 comments on commit 8134e81

Please sign in to comment.