mirror of
https://github.com/smartxworks/sunmao-ui.git
synced 2025-02-23 17:49:49 +08:00
Merge pull request #96 from webzard-io/ysj/dev
feat: component tree sorting is supported
This commit is contained in:
commit
7c30abf7c3
@ -1,4 +1,4 @@
|
||||
import { ChevronDownIcon, ChevronRightIcon, DeleteIcon } from '@chakra-ui/icons';
|
||||
import { ArrowDownIcon, ArrowUpIcon, ChevronDownIcon, ChevronRightIcon, DeleteIcon } from '@chakra-ui/icons';
|
||||
import { Box, HStack, IconButton, Text } from '@chakra-ui/react';
|
||||
import { useState } from 'react';
|
||||
|
||||
@ -11,6 +11,9 @@ type Props = {
|
||||
isExpanded?: boolean;
|
||||
onToggleExpanded?: () => void;
|
||||
isDroppable?: boolean;
|
||||
isSortable?: boolean;
|
||||
onMoveUp?: () => void;
|
||||
onMoveDown?: () => void;
|
||||
};
|
||||
|
||||
export const ComponentItemView: React.FC<Props> = props => {
|
||||
@ -23,6 +26,9 @@ export const ComponentItemView: React.FC<Props> = props => {
|
||||
onToggleExpanded,
|
||||
onClickRemove,
|
||||
isDroppable,
|
||||
isSortable = false,
|
||||
onMoveUp,
|
||||
onMoveDown
|
||||
} = props;
|
||||
|
||||
const [isDragOver, setIsDragOver] = useState(false);
|
||||
@ -60,15 +66,37 @@ export const ComponentItemView: React.FC<Props> = props => {
|
||||
<Text color={isSelected ? 'red.500' : 'black'} onClick={onClick} cursor="pointer">
|
||||
{title}
|
||||
</Text>
|
||||
{onClickRemove ? (
|
||||
<IconButton
|
||||
variant="ghost"
|
||||
size="smx"
|
||||
aria-label="remove"
|
||||
icon={<DeleteIcon />}
|
||||
onClick={onClickRemove}
|
||||
/>
|
||||
) : null}
|
||||
<Box display="flex" alignItems="center">
|
||||
{onClickRemove ? (
|
||||
<Box>
|
||||
<IconButton
|
||||
variant="ghost"
|
||||
size="smx"
|
||||
aria-label="remove"
|
||||
icon={<DeleteIcon />}
|
||||
onClick={onClickRemove}
|
||||
/>
|
||||
</Box>
|
||||
) : null}
|
||||
{isSortable ? (
|
||||
<Box>
|
||||
<IconButton
|
||||
variant="ghost"
|
||||
size="smx"
|
||||
aria-label="remove"
|
||||
icon={<ArrowUpIcon />}
|
||||
onClick={onMoveUp}
|
||||
/>
|
||||
<IconButton
|
||||
variant="ghost"
|
||||
size="smx"
|
||||
aria-label="remove"
|
||||
icon={<ArrowDownIcon />}
|
||||
onClick={onMoveDown}
|
||||
/>
|
||||
</Box>
|
||||
) : null}
|
||||
</Box>
|
||||
</HStack>
|
||||
</Box>
|
||||
);
|
||||
|
@ -6,6 +6,7 @@ import { registry } from '../../metaUI';
|
||||
import {
|
||||
CreateComponentOperation,
|
||||
RemoveComponentOperation,
|
||||
SortComponentOperation,
|
||||
} from '../../operations/Operations';
|
||||
import { ComponentItemView } from './ComponentItemView';
|
||||
import { DropComponentWrapper } from './DropComponentWrapper';
|
||||
@ -89,6 +90,14 @@ export const ComponentTree: React.FC<Props> = props => {
|
||||
);
|
||||
};
|
||||
|
||||
const onMoveUp = () => {
|
||||
eventBus.send('operation', new SortComponentOperation(component.id, 'up'));
|
||||
};
|
||||
|
||||
const onMoveDown = () => {
|
||||
eventBus.send('operation', new SortComponentOperation(component.id, 'down'));
|
||||
};
|
||||
|
||||
return (
|
||||
<VStack
|
||||
key={component.id}
|
||||
@ -109,6 +118,9 @@ export const ComponentTree: React.FC<Props> = props => {
|
||||
isExpanded={isExpanded}
|
||||
onToggleExpanded={() => setIsExpanded(prev => !prev)}
|
||||
isDroppable={slots.length > 0}
|
||||
isSortable={true}
|
||||
onMoveUp={onMoveUp}
|
||||
onMoveDown={onMoveDown}
|
||||
/>
|
||||
</DropComponentWrapper>
|
||||
{isExpanded ? slotsEle : null}
|
||||
|
@ -7,6 +7,7 @@ import {
|
||||
ModifyComponentPropertyOperation,
|
||||
ModifyTraitPropertyOperation,
|
||||
ModifyComponentIdOperation,
|
||||
SortComponentOperation,
|
||||
AddTraitOperation,
|
||||
RemoveTraitOperation,
|
||||
ModifyTraitPropertiesOperation,
|
||||
@ -227,6 +228,29 @@ export class AppModelManager {
|
||||
c.traits.splice(rto.traitIndex, 1);
|
||||
}
|
||||
});
|
||||
break;
|
||||
case 'sortComponent':
|
||||
const sortO = o as SortComponentOperation;
|
||||
newApp = produce(this.app, draft => {
|
||||
const iIndex = draft.spec.components.findIndex(c => c.id === sortO.componentId);
|
||||
const iComponent = this.app.spec.components[iIndex];
|
||||
const iSlotTrait = iComponent.traits.find(t => t.type === 'core/v1/slot');
|
||||
if (!iSlotTrait) return;
|
||||
|
||||
const findArray = sortO.direction === 'up' ? this.app.spec.components.slice(0, iIndex).reverse() : this.app.spec.components.slice(iIndex + 1);
|
||||
|
||||
const jComponent = findArray.find(c => {
|
||||
const jSlotTrait = c.traits.find(t => t.type === 'core/v1/slot');
|
||||
if (jSlotTrait){
|
||||
return _.isEqual(jSlotTrait, iSlotTrait);
|
||||
}
|
||||
});
|
||||
if (!jComponent) return;
|
||||
|
||||
const jIndex = this.app.spec.components.findIndex(c => c.id === jComponent.id);
|
||||
if (jIndex > -1) {
|
||||
[draft.spec.components[iIndex],draft.spec.components[jIndex]] = [draft.spec.components[jIndex],draft.spec.components[iIndex]];
|
||||
}
|
||||
});
|
||||
break;
|
||||
}
|
||||
|
@ -64,3 +64,10 @@ export class ModifyTraitPropertiesOperation {
|
||||
public properties: Record<string, any>
|
||||
) {}
|
||||
}
|
||||
export class SortComponentOperation {
|
||||
kind = 'sortComponent';
|
||||
constructor(
|
||||
public componentId: string,
|
||||
public direction: 'up' | 'down'
|
||||
) {}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user