Skip to content

Commit

Permalink
feat: relationship actions
Browse files Browse the repository at this point in the history
  • Loading branch information
dineug committed Nov 11, 2023
1 parent 28c30fc commit 847b499
Show file tree
Hide file tree
Showing 42 changed files with 757 additions and 239 deletions.
1 change: 1 addition & 0 deletions packages/erd-editor/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@
"@types/ua-parser-js": "^0.7.37",
"@types/uuid": "^9.0.2",
"color": "^4.2.3",
"deepmerge": "^4.3.1",
"html-to-image": "^1.11.11",
"lodash-es": "^4.17.21",
"luxon": "^3.3.0",
Expand Down
18 changes: 16 additions & 2 deletions packages/erd-editor/src/components/erd/Erd.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import {
} from '@/engine/modules/settings/atom.actions';
import { isMouseEvent } from '@/utils/domEvent';
import { drag$, DragMove } from '@/utils/globalEventObservable';
import { getRelationshipIcon } from '@/utils/icon';
import { isMod } from '@/utils/keyboard-shortcut';

import * as styles from './Erd.styles';
Expand Down Expand Up @@ -102,10 +103,22 @@ const Erd: FC<ErdProps> = (props, ctx) => {
state.dragSelect = false;
};

return () =>
html`
return () => {
const { store } = app.value;
const {
editor: { drawRelationship },
} = store.state;

const cursor = drawRelationship
? `url("${getRelationshipIcon(
drawRelationship.relationshipType
)}") 16 16, auto`
: '';

return html`
<div
class=${styles.root}
style=${{ cursor }}
${ref(root)}
@contextmenu=${handleContextmenu}
@mousedown=${contextMenu.onMousedown}
Expand All @@ -132,6 +145,7 @@ const Erd: FC<ErdProps> = (props, ctx) => {
/>
</div>
`;
};
};

export default Erd;
4 changes: 2 additions & 2 deletions packages/erd-editor/src/components/erd/canvas/table/Table.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import { SchemaV3Constants } from '@dineug/erd-editor-schema';
import { FC, html, repeat } from '@dineug/r-html';

import { useAppContext } from '@/components/context';
import Column from '@/components/erd/canvas/table/column/Column';
import EditInput from '@/components/primitives/edit-input/EditInput';
import Icon from '@/components/primitives/icon/Icon';
import { Show } from '@/constants/schema';
import {
editTableAction,
editTableEndAction,
Expand Down Expand Up @@ -158,7 +158,7 @@ const Table: FC<TableProps> = (props, ctx) => {
}}
/>
</div>
${bHas(settings.show, SchemaV3Constants.Show.tableComment)
${bHas(settings.show, Show.tableComment)
? html`
<div
class="input-padding"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import { SchemaV3Constants } from '@dineug/erd-editor-schema';
import { DOMTemplateLiterals, FC, html, repeat } from '@dineug/r-html';

import { useAppContext } from '@/components/context';
Expand All @@ -11,6 +10,11 @@ import {
COLUMN_AUTO_INCREMENT_WIDTH,
COLUMN_UNIQUE_WIDTH,
} from '@/constants/layout';
import {
ColumnOption as ColumnOptionType,
ColumnType,
Show,
} from '@/constants/schema';
import {
editTableAction,
editTableEndAction,
Expand All @@ -29,9 +33,6 @@ import { isMod, simpleShortcutToString } from '@/utils/keyboard-shortcut';

import * as styles from './Column.styles';

const ColumnType = SchemaV3Constants.ColumnType;
const Show = SchemaV3Constants.Show;

export type ColumnProps = {
column: Column;
selected: boolean;
Expand Down Expand Up @@ -267,10 +268,7 @@ const Column: FC<ColumnProps> = (props, ctx) => {
}}
>
<${ColumnOption}
checked=${bHas(
column.options,
SchemaV3Constants.ColumnOption.unique
)}
checked=${bHas(column.options, ColumnOptionType.unique)}
width=${COLUMN_UNIQUE_WIDTH}
text="UQ"
title="Unique"
Expand All @@ -295,7 +293,7 @@ const Column: FC<ColumnProps> = (props, ctx) => {
<${ColumnOption}
checked=${bHas(
column.options,
SchemaV3Constants.ColumnOption.autoIncrement
ColumnOptionType.autoIncrement
)}
width=${COLUMN_AUTO_INCREMENT_WIDTH}
text="AI"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { SchemaV3Constants } from '@dineug/erd-editor-schema';
import { FC, html } from '@dineug/r-html';

import Icon from '@/components/primitives/icon/Icon';
import { ColumnUIKey } from '@/constants/schema';
import { bHas } from '@/utils/bit';

import * as styles from './ColumnKey.styles';
Expand All @@ -12,14 +12,8 @@ export type ColumnKeyProps = {

const ColumnKey: FC<ColumnKeyProps> = (props, ctx) => {
const className = () => {
const isPrimaryKey = bHas(
props.keys,
SchemaV3Constants.ColumnUIKey.primaryKey
);
const isForeignKey = bHas(
props.keys,
SchemaV3Constants.ColumnUIKey.foreignKey
);
const isPrimaryKey = bHas(props.keys, ColumnUIKey.primaryKey);
const isForeignKey = bHas(props.keys, ColumnUIKey.foreignKey);

return {
pk: isPrimaryKey && !isForeignKey,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { SchemaV3Constants } from '@dineug/erd-editor-schema';
import { FC, html } from '@dineug/r-html';

import { COLUMN_NOT_NULL_WIDTH } from '@/constants/layout';
import { ColumnOption } from '@/constants/schema';
import { bHas } from '@/utils/bit';

import * as styles from './ColumnNotNull.styles';
Expand All @@ -22,9 +22,7 @@ const ColumnNotNull: FC<ColumnNotNullProps> = (props, ctx) => {
}}
title="Not Null"
>
${bHas(props.options, SchemaV3Constants.ColumnOption.notNull)
? 'N-N'
: 'NULL'}
${bHas(props.options, ColumnOption.notNull) ? 'N-N' : 'NULL'}
</div>
`;
};
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { SchemaV3Constants } from '@dineug/erd-editor-schema';

import { AppContext } from '@/components/context';
import { Database } from '@/constants/schema';
import { changeDatabaseAction } from '@/engine/modules/settings/atom.actions';

type Menu = {
Expand All @@ -11,27 +10,27 @@ type Menu = {
const menus: Menu[] = [
{
name: 'MSSQL',
value: SchemaV3Constants.Database.MSSQL,
value: Database.MSSQL,
},
{
name: 'MariaDB',
value: SchemaV3Constants.Database.MariaDB,
value: Database.MariaDB,
},
{
name: 'MySQL',
value: SchemaV3Constants.Database.MySQL,
value: Database.MySQL,
},
{
name: 'Oracle',
value: SchemaV3Constants.Database.Oracle,
value: Database.Oracle,
},
{
name: 'PostgreSQL',
value: SchemaV3Constants.Database.PostgreSQL,
value: Database.PostgreSQL,
},
{
name: 'SQLite',
value: SchemaV3Constants.Database.SQLite,
value: Database.SQLite,
},
];

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { SchemaV3Constants } from '@dineug/erd-editor-schema';

import { AppContext } from '@/components/context';
import { RelationshipType } from '@/constants/schema';
import { drawStartRelationshipAction$ } from '@/engine/modules/editor/generator.actions';
import { KeyBindingName } from '@/utils/keyboard-shortcut';

type Menu = {
Expand All @@ -15,25 +15,25 @@ const menus: Menu[] = [
iconName: 'ZeroOne',
name: 'Zero One',
keyBindingName: KeyBindingName.relationshipZeroOne,
relationshipType: SchemaV3Constants.RelationshipType.ZeroOne,
relationshipType: RelationshipType.ZeroOne,
},
{
iconName: 'ZeroN',
name: 'Zero N',
keyBindingName: KeyBindingName.relationshipZeroN,
relationshipType: SchemaV3Constants.RelationshipType.ZeroN,
relationshipType: RelationshipType.ZeroN,
},
{
iconName: 'OneOnly',
name: 'One Only',
keyBindingName: KeyBindingName.relationshipOneOnly,
relationshipType: SchemaV3Constants.RelationshipType.OneOnly,
relationshipType: RelationshipType.OneOnly,
},
{
iconName: 'OneN',
name: 'One N',
keyBindingName: KeyBindingName.relationshipOneN,
relationshipType: SchemaV3Constants.RelationshipType.OneN,
relationshipType: RelationshipType.OneN,
},
];

Expand All @@ -46,8 +46,7 @@ export function createDrawRelationshipMenus(
name: menu.name,
shortcut: keyBindingMap[menu.keyBindingName][0]?.shortcut,
onClick: () => {
// TODO: drawStartRelationship$
console.log('drawStartRelationship$', menu.relationshipType);
store.dispatch(drawStartRelationshipAction$(menu.relationshipType));
onClose();
},
}));
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { SchemaV3Constants } from '@dineug/erd-editor-schema';

import { AppContext } from '@/components/context';
import { Show } from '@/constants/schema';
import { changeShowAction } from '@/engine/modules/settings/atom.actions';

type Menu = {
Expand All @@ -11,35 +10,35 @@ type Menu = {
const menus: Menu[] = [
{
name: 'Table Comment',
show: SchemaV3Constants.Show.tableComment,
show: Show.tableComment,
},
{
name: 'Column Comment',
show: SchemaV3Constants.Show.columnComment,
show: Show.columnComment,
},
{
name: 'DataType',
show: SchemaV3Constants.Show.columnDataType,
show: Show.columnDataType,
},
{
name: 'Default',
show: SchemaV3Constants.Show.columnDefault,
show: Show.columnDefault,
},
{
name: 'Not Null',
show: SchemaV3Constants.Show.columnNotNull,
show: Show.columnNotNull,
},
{
name: 'Unique',
show: SchemaV3Constants.Show.columnUnique,
show: Show.columnUnique,
},
{
name: 'Auto Increment',
show: SchemaV3Constants.Show.columnAutoIncrement,
show: Show.columnAutoIncrement,
},
{
name: 'Relationship',
show: SchemaV3Constants.Show.relationship,
show: Show.relationship,
},
];

Expand Down
27 changes: 23 additions & 4 deletions packages/erd-editor/src/components/erd/useErdShortcut.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,21 @@
import { SchemaV3Constants } from '@dineug/erd-editor-schema';
import { onMounted } from '@dineug/r-html';
import { arrayHas } from '@dineug/shared';

import { useAppContext } from '@/components/context';
import { CanvasType, RelationshipType } from '@/constants/schema';
import {
drawEndRelationshipAction,
editTableAction,
editTableEndAction,
focusMoveTableAction,
selectAllAction,
selectAllColumnAction,
} from '@/engine/modules/editor/atom.actions';
import {
drawStartRelationshipAction$,
focusMoveTableAction$,
removeSelectedAction$,
unselectAllAction$,
} from '@/engine/modules/editor/generator.actions';
import { hasMoveKeys, MoveKey } from '@/engine/modules/editor/state';
import { addMemoAction$ } from '@/engine/modules/memo/generator.actions';
Expand All @@ -27,7 +31,19 @@ import {
import { useUnmounted } from '@/hooks/useUnmounted';
import { KeyBindingName } from '@/utils/keyboard-shortcut';

const CanvasType = SchemaV3Constants.CanvasType;
const isRelationshipKeyBindingName = arrayHas<string>([
KeyBindingName.relationshipZeroOne,
KeyBindingName.relationshipZeroN,
KeyBindingName.relationshipOneOnly,
KeyBindingName.relationshipOneN,
]);

const keyBindingNameToRelationshipType: Record<string, number> = {
[KeyBindingName.relationshipZeroOne]: RelationshipType.ZeroOne,
[KeyBindingName.relationshipZeroN]: RelationshipType.ZeroN,
[KeyBindingName.relationshipOneOnly]: RelationshipType.OneOnly,
[KeyBindingName.relationshipOneN]: RelationshipType.OneN,
};

export function useErdShortcut(ctx: Parameters<typeof useAppContext>[0]) {
const app = useAppContext(ctx);
Expand Down Expand Up @@ -86,7 +102,10 @@ export function useErdShortcut(ctx: Parameters<typeof useAppContext>[0]) {
action === KeyBindingName.selectAllTable &&
store.dispatch(selectAllAction());

// drawStartRelationship
if (isRelationshipKeyBindingName(action)) {
const relationshipType = keyBindingNameToRelationshipType[action];
store.dispatch(drawStartRelationshipAction$(relationshipType));
}

action === KeyBindingName.removeTable &&
store.dispatch(removeSelectedAction$());
Expand Down Expand Up @@ -152,7 +171,7 @@ export function useErdShortcut(ctx: Parameters<typeof useAppContext>[0]) {
}

if (action === KeyBindingName.stop) {
// drawEndRelationship
store.dispatch(drawEndRelationshipAction(), unselectAllAction$());
}

action === KeyBindingName.undo && store.undo();
Expand Down
7 changes: 5 additions & 2 deletions packages/erd-editor/src/components/primitives/icon/icons.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,9 @@ import {
mdiXml,
} from '@mdi/js';

const base64Icons = {
import { ValuesType } from '@/internal-types';

export const BASE_64_ICON = {
/** @deprecated */
ZeroOneN:
'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyhpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuNi1jMTM4IDc5LjE1OTgyNCwgMjAxNi8wOS8xNC0wMTowOTowMSAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENDIDIwMTcgKE1hY2ludG9zaCkiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6Q0RFRDI1RjI0ODY0MTFFN0JEQTA4NTA5QjY4NEI4MzAiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6Q0RFRDI1RjM0ODY0MTFFN0JEQTA4NTA5QjY4NEI4MzAiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDpCQTE2QzQzRDQ4NjQxMUU3QkRBMDg1MDlCNjg0QjgzMCIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDpCQTE2QzQzRTQ4NjQxMUU3QkRBMDg1MDlCNjg0QjgzMCIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/PnTT5ywAAAJMSURBVHja7Fc9T2JBFB3MZq1IqLSgsRM6G6TcAmK7VNoRK4yBxE6XP/CsNxBohc6G5w+AoCU0aEWpBfAD4AeM55AZMjvvg2dClsRwkxOeb+7ce+6dmTPPmJRSbNP2xJZtR2DrBH6k0+ndEkSxBHAD9AGpMAJc4Lfh1zDGn4GLgHglNb8kqANhSKVSTiaTkY7jyMFgILWNx2PZ7XZluVyW8BkBJWA1PhwO+f7ZinUO9DmH8xl3XfIGnefzuQwzBsvlcjKIAH4PWAh9zCLq9Xp48mq16knGwASTmkaShULBQ0B1ZlSr1TyFtFqtwOS3xWLxH2eyZctUUOKVFTGRtslk4iHAODZZ/k2yLDKIwLsZjJ2gM3Bo+V0wieu6vsvCCu0ucS+RPHC1vId8kp+YrWRwvHsIWaosO7Nun3DDqn1yD+zr+RQiz3WYz+dXz6iCP82g84lKB4jxF0Rv0G7P+Gw2E6ha9Ho9/eoPsRJAucbUzl53Wi79NmwU25QSJuLx+ObugkqlInD+l8+oTsAny1aHxDlKJpOBgzhBot1ui8Vi4R3cwCY8jbIJeap4JOHvAmd6flDQj+l06ncMD/yktdPp+AoW59nEeBqUnjjAzyACd7YQUcnUxL7CyJZWk7QWIs6xdcLQg6cvSzETEl+Q4iyXkAWZBHU3/stlpLvKpaWkm0sb5Tq+19exqfvWdbyU1gjX8SGLIlnKNJ9jPGYRP0gugQLwS717Az6AB+DJ+CC5Vs8vSkEffeIdK79mVALf95swtvvXbEdg2wQ+BRgAvLABcxKvek4AAAAASUVORK5CYII=',
Expand All @@ -52,6 +54,7 @@ const base64Icons = {
/** @deprecated */
N: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyhpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuNi1jMTM4IDc5LjE1OTgyNCwgMjAxNi8wOS8xNC0wMTowOTowMSAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENDIDIwMTcgKE1hY2ludG9zaCkiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6NDc5MkNFMDg0ODY0MTFFN0JEQTA4NTA5QjY4NEI4MzAiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6NDc5MkNFMDk0ODY0MTFFN0JEQTA4NTA5QjY4NEI4MzAiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDozNDQwRjc3NTQ4M0MxMUU3QkRBMDg1MDlCNjg0QjgzMCIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDozNDQwRjc3NjQ4M0MxMUU3QkRBMDg1MDlCNjg0QjgzMCIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/PkbQDKwAAAGjSURBVHja7Jcxb4JQEMefLl272cjSUbYu0g+gSVemdpPZwKzRRSf4AGg70k8AfACTdqx+ibYJLp2MfoDr/wg0vJp2Al6TeskFeQ+4e/fufvdsEJFQKU2hWE4OKHeg0el0TlugQi6h5+kW1MkBXddbuMw0TRvu93txOBwumjUaH+Hy4jjOcLVaCcuyeHgmOAJVKpLcgAaDwYCSJKGi9Hq9yo273W6XwjCUDCP8NJlMCPP3VRm+hT6xETZWlCiKiJ3CvJfmX8mGW7wqDu16vZYMb7db4m3A/CP0On+HQTRHMpRVCiaS7Mq2bWlwuVyKxWLxjp/BEQkxQWWVYr/fF9/JipALrP5nFJPiA0EagbI+BsAI0zSlMV59HMe/NqN5mYg1DMPyPE+02+2vwc1mI6bTKTvzgNsP6Y0KSnAMfctySxLf97kKXqGj/PmqOJCWI7aDsHrJCaZhVo4BU7JqEt5Bn13XPQIS05GBVEcvOGPqsTE0IQnHtThQcOQGGnP4mYpZL/Bqc6CYpFkvGOcoVsEfPg3tVB7Jdn/nWH76b/jvHfgUYADeZNmzPgOYQQAAAABJRU5ErkJggg==',
} as const;
export type BASE_64_ICON = ValuesType<typeof BASE_64_ICON>;

export interface IconDefinition {
prefix: string;
Expand Down Expand Up @@ -111,7 +114,7 @@ const icons = [
createMDI('xml', mdiXml),
createMDI('vector-line', mdiVectorLine),
createMDI('atom', mdiAtom),
...Object.entries(base64Icons).map(([name, base64]) =>
...Object.entries(BASE_64_ICON).map(([name, base64]) =>
createBase64(name, base64)
),
] as IconDefinition[];
Expand Down
Loading

0 comments on commit 847b499

Please sign in to comment.