Skip to content

Commit

Permalink
feat: relationship contextMenu
Browse files Browse the repository at this point in the history
  • Loading branch information
dineug committed Nov 22, 2023
1 parent 37cc25d commit fa4d426
Show file tree
Hide file tree
Showing 8 changed files with 167 additions and 8 deletions.
23 changes: 22 additions & 1 deletion packages/erd-editor/src/components/erd/Erd.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,9 @@ const Erd: FC<ErdProps> = (props, ctx) => {
dragSelect: false,
dragSelectX: 0,
dragSelectY: 0,
contextMenuType: ErdContextMenuType.ERD as ErdContextMenuType,
relationshipId: '',
tableId: '',
});
useErdShortcut(ctx);

Expand All @@ -44,6 +47,22 @@ const Erd: FC<ErdProps> = (props, ctx) => {
};

const handleContextmenu = (event: MouseEvent) => {
const el = event.target as HTMLElement | null;
if (!el) return;

const $table = el.closest('.table') as HTMLElement | null;
const $relationship = el.closest('.relationship') as HTMLElement | null;

if ($table) {
state.tableId = $table.dataset.id as string;
state.contextMenuType = ErdContextMenuType.table;
} else if ($relationship) {
state.relationshipId = $relationship.dataset.id as string;
state.contextMenuType = ErdContextMenuType.relationship;
} else {
state.contextMenuType = ErdContextMenuType.ERD;
}

contextMenu.onContextmenu(event);
};

Expand Down Expand Up @@ -139,8 +158,10 @@ const Erd: FC<ErdProps> = (props, ctx) => {
`
: null}
<${ErdContextMenu}
type=${ErdContextMenuType.ERD}
type=${state.contextMenuType}
root=${canvas}
relationshipId=${state.relationshipId}
tableId=${state.tableId}
.onClose=${handleContextmenuClose}
/>
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,10 +40,13 @@ const CanvasSvg: FC<CanvasSvgProps> = (props, ctx) => {
relationships,
relationship => relationship.id,
relationship => svg`
<g class=${[
'relationship',
{ identification: relationship.identification },
]}>
<g
class=${[
'relationship',
{ identification: relationship.identification },
]}
data-id=${relationship.id}
>
<${Relationship}
relationship=${relationship}
strokeWidth=${props.strokeWidth ?? 3}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ const HighLevelTable: FC<HighLevelTableProps> = (props, ctx) => {
height: `${height}px`,
}}
?data-selected=${selected}
data-id=${table.id}
@mousedown=${onMoveStart}
@touchstart=${onMoveStart}
>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,7 @@ const Table: FC<TableProps> = (props, ctx) => {
height: `${height}px`,
}}
?data-selected=${selected}
data-id=${table.id}
@mousedown=${onMoveStart}
@touchstart=${onMoveStart}
>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -322,7 +322,10 @@ const Column: FC<ColumnProps> = (props, ctx) => {
const { column, selected } = props;

return html`
<div class=${['column-row', styles.root, { selected }]}>
<div
class=${['column-row', styles.root, { selected }]}
data-id=${column.id}
>
<${ColumnKey} keys=${column.ui.keys} />
${repeat(
getColumnOrder(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,15 @@ import ContextMenu from '@/components/primitives/context-menu/ContextMenu';
import Icon from '@/components/primitives/icon/Icon';
import Kbd from '@/components/primitives/kbd/Kbd';
import { addMemoAction$ } from '@/engine/modules/memo/generator.actions';
import { removeRelationshipAction } from '@/engine/modules/relationship/atom.actions';
import { addTableAction$ } from '@/engine/modules/table/generator.actions';
import { ValuesType } from '@/internal-types';

import { createDatabaseMenus } from './databaseMenus';
import { createDrawRelationshipMenus } from './drawRelationshipMenus';
import { createExportMenus } from './exportMenus';
import { createImportMenus } from './importMenus';
import { createRelationshipMenus } from './relationshipMenus';
import { createShowMenus } from './showMenus';

export const ErdContextMenuType = {
Expand All @@ -24,6 +26,8 @@ export type ErdContextMenuType = ValuesType<typeof ErdContextMenuType>;
export type ErdContextMenuProps = {
type: ErdContextMenuType;
root: Ref<HTMLDivElement>;
relationshipId?: string;
tableId?: string;
onClose: () => void;
};

Expand All @@ -48,6 +52,16 @@ const ErdContextMenu: FC<ErdContextMenuProps> = (props, ctx) => {
props.onClose();
};

const handleRemoveRelationship = () => {
if (!props.relationshipId) return;
const { store } = app.value;
store.dispatch(
removeRelationshipAction({
id: props.relationshipId,
})
);
};

const chevronRightIcon = html`<${Icon} name="chevron-right" size=${14} />`;

return () => {
Expand All @@ -56,7 +70,57 @@ const ErdContextMenu: FC<ErdContextMenuProps> = (props, ctx) => {
return props.type === ErdContextMenuType.table
? html``
: props.type === ErdContextMenuType.relationship
? html``
? html`
<${ContextMenu.Root}
children=${html`
<${ContextMenu.Item}
children=${html`
<${ContextMenu.Menu}
icon=${html`
<${Icon} prefix="mdi" name="vector-line" size=${14} />
`}
name="Relationship Type"
right=${chevronRightIcon}
/>
`}
subChildren=${html`
${createRelationshipMenus(
app.value,
props.onClose,
props.relationshipId
).map(
menu => html`
<${ContextMenu.Item}
.onClick=${menu.onClick}
children=${html`
<${ContextMenu.Menu}
icon=${menu.checked
? html`<${Icon} name="check" size=${14} />`
: null}
name=${html`
<${ContextMenu.Menu}
icon=${html` <${Icon}
prefix="base64"
name=${menu.iconName}
size=${14}
/>`}
name=${menu.name}
/>
`}
/>
`}
/>
`
)}
`}
/>
<${ContextMenu.Item}
.onClick=${handleRemoveRelationship}
children=${html`<${ContextMenu.Menu} name="Delete" />`}
/>
`}
/>
`
: html`
<${ContextMenu.Root}
children=${html`
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
import { AppContext } from '@/components/appContext';
import { RelationshipType } from '@/constants/schema';
import { changeRelationshipTypeAction } from '@/engine/modules/relationship/atom.actions';
import { query } from '@/utils/collection/query';

type Menu = {
iconName: string;
name: string;
relationshipType: number;
};

const menus: Menu[] = [
{
iconName: 'ZeroOne',
name: 'Zero One',
relationshipType: RelationshipType.ZeroOne,
},
{
iconName: 'ZeroN',
name: 'Zero N',
relationshipType: RelationshipType.ZeroN,
},
{
iconName: 'OneOnly',
name: 'One Only',
relationshipType: RelationshipType.OneOnly,
},
{
iconName: 'OneN',
name: 'One N',
relationshipType: RelationshipType.OneN,
},
];

export function createRelationshipMenus(
{ store }: AppContext,
onClose: () => void,
relationshipId?: string
) {
if (!relationshipId) return [];

const { collections } = store.state;
const relationship = query(collections)
.collection('relationshipEntities')
.selectById(relationshipId);
if (!relationship) return [];

return menus.map(menu => {
const checked = menu.relationshipType === relationship.relationshipType;

return {
checked,
iconName: menu.iconName,
name: menu.name,
onClick: () => {
store.dispatch(
changeRelationshipTypeAction({
id: relationshipId,
value: menu.relationshipType,
})
);
onClose();
},
};
});
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import * as styles from './Menu.styles';

export type MenuProps = {
icon: DOMTemplateLiterals;
name: string;
name: DOMTemplateLiterals;
right?: DOMTemplateLiterals;
};

Expand Down

0 comments on commit fa4d426

Please sign in to comment.