Merge pull request #96 from webzard-io/ysj/dev

feat: component tree sorting is supported
This commit is contained in:
tanbowensg 2021-10-26 11:02:25 +08:00 committed by GitHub
commit 7c30abf7c3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 81 additions and 10 deletions

View File

@ -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>
);

View File

@ -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}

View File

@ -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;
}

View File

@ -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'
) {}
}