Skip to content

Commit

Permalink
feat(Editor): not allowed to remove component that is used by others
Browse files Browse the repository at this point in the history
  • Loading branch information
MrWindlike committed Sep 6, 2023
1 parent f7bcbb2 commit 3aa08e3
Show file tree
Hide file tree
Showing 4 changed files with 79 additions and 10 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import {
ModalBody,
} from '@chakra-ui/react';
import { EditorServices } from '../../types';
import { ReplationshipView } from './RelationshipView';
import { RelationshipView } from './RelationshipView';

type Props = {
componentId: string;
Expand All @@ -28,7 +28,7 @@ export const RelationshipModal: React.FC<Props> = ({
<ModalHeader>Relationships of {componentId}</ModalHeader>
<ModalCloseButton />
<ModalBody flex="1 1 auto" height="75vh" alignItems="start" overflow="auto">
<ReplationshipView componentId={componentId} services={services} />
<RelationshipView componentId={componentId} services={services} />
</ModalBody>
</ModalContent>
</Modal>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ type MethodRelation = {
method: string;
};

export const ReplationshipView: React.FC<Props> = ({ componentId, services }) => {
export const RelationshipView: React.FC<Props> = ({ componentId, services }) => {
const { appModelManager, editorStore } = services;
const { appModel } = appModelManager;

Expand Down Expand Up @@ -128,7 +128,7 @@ export const ReplationshipView: React.FC<Props> = ({ componentId, services }) =>
);
};

function getRelations(componentId: ComponentId, appModel: AppModel) {
export function getRelations(componentId: ComponentId, appModel: AppModel) {
const expressionRelations: ExpressionRelation[] = [];
const methodRelations: MethodRelation[] = [];
appModel.traverseTree(c => {
Expand Down
29 changes: 23 additions & 6 deletions packages/editor/src/components/StructureTree/ComponentNode.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ import { RelationshipModal } from '../RelationshipModal';
import { ExplorerMenuTabs } from '../../constants/enum';
import { ExtractModuleModal } from '../ExtractModuleModal';
import { copyToClipboard } from '../../utils/copy';
import { getRelations } from '../RelationshipModal/RelationshipView';
import useModal from '../../hooks/useModal';

const IndextWidth = 24;

Expand Down Expand Up @@ -55,22 +57,36 @@ const ComponentNodeImpl = (props: Props) => {
} = props;
const toast = useToast();
const { registry, eventBus, appModelManager, editorStore, stateManager } = services;
const { appModel } = appModelManager;
const [isShowRelationshipModal, setIsShowRelationshipModal] = useState(false);
const [isShowExtractModuleModal, setIsShowExtractModuleModal] = useState(false);
const { modal: messageModal, open: openMessageModal } = useModal();
const slots = Object.keys(registry.getComponentByType(component.type).spec.slots);
const paddingLeft = depth * IndextWidth;

const onClickRemove = useCallback(
(e: React.MouseEvent) => {
e.stopPropagation();
eventBus.send(
'operation',
genOperation(registry, 'removeComponent', {
componentId: component.id,
})
const { expressionRelations, methodRelations } = getRelations(
component.id as ComponentId,
appModel
);

if (expressionRelations.length || methodRelations.length) {
openMessageModal({
title: 'Remove component failed',
message: 'Its state or methods are used by another component.',
});
} else {
eventBus.send(
'operation',
genOperation(registry, 'removeComponent', {
componentId: component.id,
})
);
}
},
[component.id, eventBus, registry]
[component.id, eventBus, registry, appModel, openMessageModal]
);
const onClickDuplicate = useCallback(
(e: React.MouseEvent) => {
Expand Down Expand Up @@ -307,6 +323,7 @@ const ComponentNodeImpl = (props: Props) => {
{emptyChildrenSlotsPlaceholder}
{relationshipViewModal}
{extractModuleModal}
{messageModal}
</VStack>
);
};
Expand Down
52 changes: 52 additions & 0 deletions packages/editor/src/hooks/useModal.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import React, { useCallback, useState } from 'react';
import {
Modal,
ModalOverlay,
ModalContent,
ModalHeader,
ModalCloseButton,
ModalBody,
ModalFooter,
Button,
useDisclosure,
} from '@chakra-ui/react';

export type OpenOptions = {
title?: string;
message?: string;
};

function useModal() {
const { isOpen, onOpen, onClose } = useDisclosure();
const [options, setOptions] = useState<Partial<OpenOptions>>({});
const { title, message } = options;
const open = useCallback(
(options: OpenOptions) => {
setOptions(options);
onOpen();
},
[onOpen]
);

const modal = (
<Modal onClose={onClose} size="md" isOpen={isOpen}>
<ModalOverlay />
<ModalContent>
{title ? <ModalHeader>{title}</ModalHeader> : null}
<ModalCloseButton />
<ModalBody>{message}</ModalBody>
<ModalFooter>
<Button onClick={onClose}>Close</Button>
</ModalFooter>
</ModalContent>
</Modal>
);

return {
modal,
open,
close: onClose,
};
}

export default useModal;

0 comments on commit 3aa08e3

Please sign in to comment.