mirror of
https://github.com/IRBorisov/ConceptPortal.git
synced 2025-06-26 04:50:36 +03:00
F: Implementing block UI pt2
This commit is contained in:
parent
a69a26bb7b
commit
e71a5baf60
|
@ -9,7 +9,7 @@ import { useDialogsStore } from '@/stores/dialogs';
|
|||
import { NavigationState } from './navigation/navigation-context';
|
||||
import { Footer } from './footer';
|
||||
import { GlobalDialogs } from './global-dialogs';
|
||||
import { GlobalLoader } from './global-loader1';
|
||||
import { GlobalLoader } from './global-loader';
|
||||
import { ToasterThemed } from './global-toaster';
|
||||
import { GlobalTooltips } from './global-tooltips';
|
||||
import { MutationErrors } from './mutation-errors';
|
||||
|
|
|
@ -543,26 +543,26 @@ export function calculateNewBlockPosition(data: ICreateBlockDTO, layout: IOssLay
|
|||
let right = undefined;
|
||||
let bottom = undefined;
|
||||
|
||||
for (const node of block_nodes) {
|
||||
left = !left ? node.x - GRID_SIZE : Math.min(left, node.x - GRID_SIZE);
|
||||
top = !top ? node.y - GRID_SIZE : Math.min(top, node.y - GRID_SIZE);
|
||||
for (const block of block_nodes) {
|
||||
left = !left ? block.x - GRID_SIZE : Math.min(left, block.x - GRID_SIZE);
|
||||
top = !top ? block.y - GRID_SIZE : Math.min(top, block.y - GRID_SIZE);
|
||||
right = !right
|
||||
? Math.max(left + data.width, node.x + node.width + GRID_SIZE)
|
||||
: Math.max(right, node.x + node.width + GRID_SIZE);
|
||||
? Math.max(left + data.width, block.x + block.width + GRID_SIZE)
|
||||
: Math.max(right, block.x + block.width + GRID_SIZE);
|
||||
bottom = !bottom
|
||||
? Math.max(top + data.height, node.y + node.height + GRID_SIZE)
|
||||
: Math.max(bottom, node.y + node.height + GRID_SIZE);
|
||||
? Math.max(top + data.height, block.y + block.height + GRID_SIZE)
|
||||
: Math.max(bottom, block.y + block.height + GRID_SIZE);
|
||||
}
|
||||
|
||||
for (const node of operation_nodes) {
|
||||
left = !left ? node.x - GRID_SIZE : Math.min(left, node.x - GRID_SIZE);
|
||||
top = !top ? node.y - GRID_SIZE : Math.min(top, node.y - GRID_SIZE);
|
||||
for (const operation of operation_nodes) {
|
||||
left = !left ? operation.x - GRID_SIZE : Math.min(left, operation.x - GRID_SIZE);
|
||||
top = !top ? operation.y - GRID_SIZE : Math.min(top, operation.y - GRID_SIZE);
|
||||
right = !right
|
||||
? Math.max(left + data.width, node.x + OPERATION_NODE_WIDTH + GRID_SIZE)
|
||||
: Math.max(right, node.x + OPERATION_NODE_WIDTH + GRID_SIZE);
|
||||
? Math.max(left + data.width, operation.x + OPERATION_NODE_WIDTH + GRID_SIZE)
|
||||
: Math.max(right, operation.x + OPERATION_NODE_WIDTH + GRID_SIZE);
|
||||
bottom = !bottom
|
||||
? Math.max(top + data.height, node.y + OPERATION_NODE_HEIGHT + GRID_SIZE)
|
||||
: Math.max(bottom, node.y + OPERATION_NODE_HEIGHT + GRID_SIZE);
|
||||
? Math.max(top + data.height, operation.y + OPERATION_NODE_HEIGHT + GRID_SIZE)
|
||||
: Math.max(bottom, operation.y + OPERATION_NODE_HEIGHT + GRID_SIZE);
|
||||
}
|
||||
|
||||
return {
|
||||
|
|
|
@ -16,8 +16,9 @@ export const BLOCK_NODE_MIN_HEIGHT = 100;
|
|||
export function BlockNode(node: BlockInternalNode) {
|
||||
const showCoordinates = useOSSGraphStore(state => state.showCoordinates);
|
||||
const { selected, schema } = useOssEdit();
|
||||
const singleSelected = selected.length === 1 ? selected[0] : null;
|
||||
const isParent = !singleSelected ? false : schema.hierarchy.at(singleSelected)?.inputs.includes(node.data.block.id);
|
||||
const focus = selected.length === 1 ? selected[0] : null;
|
||||
const isParent = (!!focus && schema.hierarchy.at(focus)?.inputs.includes(-node.data.block.id)) ?? false;
|
||||
const isChild = (!!focus && schema.hierarchy.at(focus)?.outputs.includes(-node.data.block.id)) ?? false;
|
||||
return (
|
||||
<>
|
||||
<NodeResizeControl minWidth={BLOCK_NODE_MIN_WIDTH} minHeight={BLOCK_NODE_MIN_HEIGHT}>
|
||||
|
@ -34,7 +35,13 @@ export function BlockNode(node: BlockInternalNode) {
|
|||
{`X: ${node.xPos.toFixed(0)} Y: ${node.yPos.toFixed(0)}`}
|
||||
</div>
|
||||
) : null}
|
||||
<div className={clsx('cc-node-block h-full w-full', isParent && 'border-primary')}>
|
||||
<div
|
||||
className={clsx(
|
||||
'cc-node-block h-full w-full',
|
||||
isParent && 'border-primary',
|
||||
isChild && 'border-accent-orange50'
|
||||
)}
|
||||
>
|
||||
<div
|
||||
className={clsx(
|
||||
'w-fit mx-auto -translate-y-[14px]',
|
||||
|
|
|
@ -8,7 +8,7 @@ export function InputNode(node: OperationInternalNode) {
|
|||
return (
|
||||
<>
|
||||
<NodeCore node={node} />
|
||||
<Handle type='source' position={Position.Bottom} />
|
||||
<Handle type='source' position={Position.Bottom} className='-translate-y-[1px]' />
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -5,12 +5,14 @@ import clsx from 'clsx';
|
|||
import { useOSSGraphStore } from '@/features/oss/stores/oss-graph';
|
||||
|
||||
import { IconConsolidation, IconRSForm } from '@/components/icons';
|
||||
import { cn } from '@/components/utils';
|
||||
import { Indicator } from '@/components/view';
|
||||
import { globalIDs } from '@/utils/constants';
|
||||
|
||||
import { OperationType } from '../../../../backend/types';
|
||||
import { type OperationInternalNode } from '../../../../models/oss-layout';
|
||||
import { useOperationTooltipStore } from '../../../../stores/operation-tooltip';
|
||||
import { useOssEdit } from '../../oss-edit-context';
|
||||
|
||||
export const OPERATION_NODE_WIDTH = 150;
|
||||
export const OPERATION_NODE_HEIGHT = 40;
|
||||
|
@ -23,6 +25,10 @@ interface NodeCoreProps {
|
|||
}
|
||||
|
||||
export function NodeCore({ node }: NodeCoreProps) {
|
||||
const { selected, schema } = useOssEdit();
|
||||
const focus = selected.length === 1 ? selected[0] : null;
|
||||
const isChild = (!!focus && schema.hierarchy.at(focus)?.outputs.includes(node.data.operation.id)) ?? false;
|
||||
|
||||
const setHover = useOperationTooltipStore(state => state.setActiveOperation);
|
||||
const showCoordinates = useOSSGraphStore(state => state.showCoordinates);
|
||||
|
||||
|
@ -31,7 +37,11 @@ export function NodeCore({ node }: NodeCoreProps) {
|
|||
|
||||
return (
|
||||
<div
|
||||
className='relative h-[34px] w-[144px] flex items-center justify-center'
|
||||
className={cn(
|
||||
'cc-node-operation h-[40px] w-[150px]',
|
||||
'relative flex items-center justify-center p-[2px]',
|
||||
isChild && 'border-accent-orange50!'
|
||||
)}
|
||||
data-tooltip-id={globalIDs.operation_tooltip}
|
||||
data-tooltip-hidden={node.dragging}
|
||||
onMouseEnter={() => setHover(node.data.operation)}
|
||||
|
@ -55,7 +65,8 @@ export function NodeCore({ node }: NodeCoreProps) {
|
|||
className={clsx(
|
||||
'absolute top-full mt-1 right-[1px]',
|
||||
'text-[7px]/[8px] font-math',
|
||||
'text-muted-foreground hover:text-foreground'
|
||||
'text-muted-foreground hover:text-foreground',
|
||||
node.selected && 'translate-y-[6px]'
|
||||
)}
|
||||
>
|
||||
{`X: ${node.xPos.toFixed(0)} Y: ${node.yPos.toFixed(0)}`}
|
||||
|
@ -63,7 +74,7 @@ export function NodeCore({ node }: NodeCoreProps) {
|
|||
) : null}
|
||||
|
||||
{node.data.operation.operation_type === OperationType.INPUT ? (
|
||||
<div className='absolute top-[1px] right-1/2 translate-x-1/2 border-t w-[30px]' />
|
||||
<div className='absolute top-[3px] right-1/2 translate-x-1/2 border-t w-[30px]' />
|
||||
) : null}
|
||||
|
||||
{!node.data.operation.is_owned ? (
|
||||
|
|
|
@ -9,10 +9,10 @@ import { NodeCore } from './node-core';
|
|||
export function OperationNode(node: OperationInternalNode) {
|
||||
return (
|
||||
<>
|
||||
<Handle type='target' position={Position.Top} id='left' style={{ left: 40 }} />
|
||||
<Handle type='target' position={Position.Top} id='right' style={{ right: 40, left: 'auto' }} />
|
||||
<Handle type='target' position={Position.Top} id='left' style={{ left: 40, top: -2 }} />
|
||||
<Handle type='target' position={Position.Top} id='right' style={{ right: 40, left: 'auto', top: -2 }} />
|
||||
<NodeCore node={node} />
|
||||
<Handle type='source' position={Position.Bottom} />
|
||||
<Handle type='source' position={Position.Bottom} className='-translate-y-[1px]' />
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -4,16 +4,17 @@
|
|||
|
||||
.react-flow__resize-control.handle {
|
||||
background-color: transparent;
|
||||
border-color: transparent;
|
||||
|
||||
z-index: var(--z-index-navigation);
|
||||
color: var(--color-muted-foreground);
|
||||
|
||||
width: 0;
|
||||
height: 0;
|
||||
|
||||
&:hover {
|
||||
color: var(--color-foreground);
|
||||
}
|
||||
|
||||
width: 0;
|
||||
height: 0;
|
||||
}
|
||||
|
||||
.react-flow__node-input,
|
||||
|
@ -21,28 +22,15 @@
|
|||
cursor: pointer;
|
||||
|
||||
border-radius: 5px;
|
||||
padding: 2px;
|
||||
width: 150px;
|
||||
height: fit-content;
|
||||
border-width: 0;
|
||||
|
||||
outline-offset: -2px;
|
||||
outline-style: solid;
|
||||
outline-color: transparent;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
|
||||
transition-property: outline-offset;
|
||||
transition-timing-function: var(--transition-bezier);
|
||||
transition-duration: var(--duration-select);
|
||||
|
||||
&.selected {
|
||||
outline-offset: 4px;
|
||||
outline-color: var(--color-graph-selected);
|
||||
border-color: var(--color-foreground);
|
||||
}
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
.react-flow__node-block {
|
||||
cursor: auto;
|
||||
|
||||
border-radius: 5px;
|
||||
border-width: 0;
|
||||
|
||||
|
@ -53,7 +41,34 @@
|
|||
pointer-events: none;
|
||||
}
|
||||
|
||||
.cc-node-operation {
|
||||
cursor: pointer;
|
||||
|
||||
border-radius: 5px;
|
||||
border-color: var(--color-muted-foreground);
|
||||
border-width: 1px;
|
||||
|
||||
color: var(--color-foreground);
|
||||
background-color: var(--color-card);
|
||||
|
||||
outline-offset: -2px;
|
||||
outline-style: solid;
|
||||
outline-color: transparent;
|
||||
|
||||
transition-property: outline-offset;
|
||||
transition-timing-function: var(--transition-bezier);
|
||||
transition-duration: var(--duration-select);
|
||||
|
||||
.selected & {
|
||||
outline-offset: 4px;
|
||||
outline-color: var(--color-graph-selected);
|
||||
border-color: var(--color-foreground);
|
||||
}
|
||||
}
|
||||
|
||||
.cc-node-block {
|
||||
cursor: default;
|
||||
|
||||
border-radius: 5px;
|
||||
border-style: dashed;
|
||||
border-width: 2px;
|
||||
|
@ -61,6 +76,7 @@
|
|||
padding: 4px;
|
||||
|
||||
color: var(--color-muted-foreground);
|
||||
background-color: transparent;
|
||||
|
||||
.selected & {
|
||||
color: var(--color-foreground);
|
||||
|
|
|
@ -200,6 +200,10 @@ export function OssFlow() {
|
|||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
|
||||
if (node.type === 'block') {
|
||||
return;
|
||||
}
|
||||
|
||||
setMenuProps({
|
||||
operation: node.data.operation,
|
||||
cursorX: event.clientX,
|
||||
|
|
|
@ -3,9 +3,13 @@
|
|||
/* stylelint-disable selector-class-pattern */
|
||||
|
||||
.react-flow__node-token {
|
||||
font-size: 14px;
|
||||
cursor: default;
|
||||
|
||||
border: 1px solid;
|
||||
border-color: var(--color-border);
|
||||
border-radius: 100%;
|
||||
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
|
||||
|
|
|
@ -3,9 +3,14 @@
|
|||
/* stylelint-disable selector-class-pattern */
|
||||
|
||||
.react-flow__node-step {
|
||||
font-size: 14px;
|
||||
cursor: default;
|
||||
|
||||
color: var(--color-foreground);
|
||||
border: 1px solid;
|
||||
border-color: var(--color-border);
|
||||
border-radius: 100%;
|
||||
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
|
||||
|
|
|
@ -4,8 +4,12 @@
|
|||
|
||||
.react-flow__node-concept {
|
||||
cursor: default;
|
||||
font-size: 14px;
|
||||
|
||||
border: 1px solid;
|
||||
border-color: var(--color-border);
|
||||
border-radius: 100%;
|
||||
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
/* stylelint-disable selector-class-pattern */
|
||||
|
||||
.react-flow__handle {
|
||||
z-index: var(--z-index-navigation);
|
||||
cursor: default !important;
|
||||
border-radius: 9999px;
|
||||
|
||||
|
@ -36,13 +37,6 @@
|
|||
}
|
||||
|
||||
[class*='react-flow__node-'] {
|
||||
font-size: 14px;
|
||||
border: 1px solid;
|
||||
|
||||
color: var(--color-foreground);
|
||||
border-color: var(--color-border);
|
||||
background-color: var(--color-card);
|
||||
|
||||
&:hover:not(.selected) {
|
||||
box-shadow: 0 0 0 2px var(--color-selected) !important;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user