mirror of
https://github.com/smartxworks/sunmao-ui.git
synced 2025-02-11 17:37:40 +08:00
can paste
This commit is contained in:
parent
ee058a7b0b
commit
bbe97dc486
@ -1,5 +1,5 @@
|
||||
import { css } from '@emotion/react';
|
||||
import React from 'react';
|
||||
import React, { useRef } from 'react';
|
||||
import { eventBus } from '../eventBus';
|
||||
import { genOperation } from '../operations';
|
||||
|
||||
@ -8,6 +8,7 @@ type Props = {
|
||||
};
|
||||
|
||||
export const KeyboardEventWrapper: React.FC<Props> = props => {
|
||||
const copyId = useRef('');
|
||||
const style = css`
|
||||
&:focus {
|
||||
outline: none;
|
||||
@ -41,6 +42,23 @@ export const KeyboardEventWrapper: React.FC<Props> = props => {
|
||||
eventBus.send('redo');
|
||||
}
|
||||
break;
|
||||
case 'c':
|
||||
// FIXME: detect os version and set redo/undo logic
|
||||
if (e.metaKey || e.ctrlKey) {
|
||||
// eventBus.send('copy', { componentId: props.selectedComponentId });
|
||||
copyId.current = props.selectedComponentId;
|
||||
}
|
||||
break;
|
||||
case 'v':
|
||||
eventBus.send(
|
||||
'operation',
|
||||
genOperation('pasteComponent', {
|
||||
componentId: copyId.current,
|
||||
parentId: props.selectedComponentId,
|
||||
slot: 'content',
|
||||
})
|
||||
);
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -6,13 +6,14 @@ export type EventNames = {
|
||||
operation: IOperation;
|
||||
redo: undefined;
|
||||
undo: undefined;
|
||||
copy: { componentId: string };
|
||||
// when switch app or module, current components refresh
|
||||
componentsRefresh: ApplicationComponent[];
|
||||
// components change by operation
|
||||
componentsChange: ApplicationComponent[];
|
||||
// it is only used for some operations' side effect
|
||||
selectComponent: string;
|
||||
}
|
||||
};
|
||||
|
||||
const emitter = mitt<EventNames>();
|
||||
|
||||
|
@ -0,0 +1,84 @@
|
||||
import { ApplicationComponent } from '@sunmao-ui/core';
|
||||
import { CreateComponentBranchOperation } from '../branch';
|
||||
import { BaseBranchOperation } from '../type';
|
||||
|
||||
export type PasteComponentBranchOperationContext = {
|
||||
parentId: string;
|
||||
slot: string;
|
||||
componentId: string;
|
||||
};
|
||||
|
||||
export class PasteComponentBranchOperation extends BaseBranchOperation<PasteComponentBranchOperationContext> {
|
||||
do(prev: ApplicationComponent[]): ApplicationComponent[] {
|
||||
console.log('paste', this.context)
|
||||
// find component to remove
|
||||
const targetComponent = prev.find(c => c.id === this.context.componentId);
|
||||
if (!targetComponent) {
|
||||
console.warn('paste component not found');
|
||||
return prev;
|
||||
}
|
||||
// TODO: Change slot to target Parent
|
||||
// this.operationStack.insert(
|
||||
// new CreateComponentBranchOperation({ componentId: component.id })
|
||||
// );
|
||||
|
||||
// TODO: O(n2) in worst case. Optimize in the future.
|
||||
const children = prev.filter(c => {
|
||||
const slotTrait = c.traits.find(t => t.type === 'core/v1/slot');
|
||||
return (
|
||||
slotTrait &&
|
||||
(slotTrait.properties.container as { id: string }).id === this.context.componentId
|
||||
);
|
||||
});
|
||||
|
||||
children.forEach(component => {
|
||||
this.operationStack.insert(
|
||||
new CreateComponentBranchOperation({
|
||||
componentId: `${component.id}_copy`,
|
||||
componentType: component.type,
|
||||
parentId: `${this.context.componentId}_copy`,
|
||||
slot: this.context.slot,
|
||||
})
|
||||
);
|
||||
});
|
||||
|
||||
// TODO: dont care about layout component
|
||||
// if (parentId) {
|
||||
// // modify layout property of parent grid layout component
|
||||
// this.operationStack.insert(
|
||||
// new ModifyComponentPropertiesLeafOperation({
|
||||
// componentId: parentId,
|
||||
// properties: {
|
||||
// layout: (prev: Array<ReactGridLayout.Layout>) => {
|
||||
// return produce(prev, draft => {
|
||||
// const removeIndex = draft.findIndex(
|
||||
// item => item.i === this.context.componentId
|
||||
// );
|
||||
// if (removeIndex === -1) {
|
||||
// console.warn("parent element doesn' contain specific child");
|
||||
// }
|
||||
// draft.splice(removeIndex, 1);
|
||||
// });
|
||||
// },
|
||||
// },
|
||||
// })
|
||||
// );
|
||||
// }
|
||||
|
||||
// free component from schema
|
||||
this.operationStack.insert(
|
||||
new CreateComponentBranchOperation({
|
||||
componentId: `${this.context.componentId}_copy`,
|
||||
componentType: targetComponent.type,
|
||||
parentId: this.context.parentId,
|
||||
slot: this.context.slot,
|
||||
})
|
||||
);
|
||||
|
||||
// do the operation in order
|
||||
return this.operationStack.reduce((prev, node) => {
|
||||
prev = node.do(prev);
|
||||
return prev;
|
||||
}, prev);
|
||||
}
|
||||
}
|
@ -6,6 +6,10 @@ import {
|
||||
RemoveComponentBranchOperation,
|
||||
RemoveComponentBranchOperationContext,
|
||||
} from './branch';
|
||||
import {
|
||||
PasteComponentBranchOperation,
|
||||
PasteComponentBranchOperationContext,
|
||||
} from './branch/pasteComponentBranchOperation';
|
||||
import {
|
||||
AdjustComponentOrderLeafOperation,
|
||||
AdjustComponentOrderLeafOperationContext,
|
||||
@ -35,6 +39,7 @@ const OperationConstructors: Record<
|
||||
removeTrait: RemoveTraitLeafOperation,
|
||||
modifyTraitProperty: ModifyTraitPropertiesLeafOperation,
|
||||
replaceApp: ReplaceAppLeafOperation,
|
||||
pasteComponent: PasteComponentBranchOperation,
|
||||
};
|
||||
|
||||
type OperationTypes = keyof OperationConfigMaps;
|
||||
@ -78,6 +83,11 @@ type OperationConfigMaps = {
|
||||
ModifyTraitPropertiesLeafOperationContext
|
||||
>;
|
||||
replaceApp: OperationConfigMap<ReplaceAppLeafOperation, ReplaceAppLeafOperationContext>;
|
||||
|
||||
pasteComponent: OperationConfigMap<
|
||||
PasteComponentBranchOperation,
|
||||
PasteComponentBranchOperationContext
|
||||
>;
|
||||
};
|
||||
|
||||
export const genOperation = <T extends OperationTypes>(
|
||||
|
Loading…
Reference in New Issue
Block a user