Skip to content

Commit 0a207c0

Browse files
author
Filip Vitas
committed
add attributes in different way and bump up the version to 1.1.0
1 parent cda37b6 commit 0a207c0

9 files changed

Lines changed: 249 additions & 12 deletions

File tree

‎package.json‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "erdesigner",
3-
"version": "1.0.0",
3+
"version": "1.1.0",
44
"description": "Create beautiful ER diagrams",
55
"main": "./main.js",
66
"scripts": {
@@ -63,6 +63,7 @@
6363
"highlight.js": "^9.12.0",
6464
"lodash": "^4.17.4",
6565
"preact": "^8.2.1",
66+
"preact-portal": "^1.1.2",
6667
"preact-redux": "^2.0.2",
6768
"redux": "^3.7.2",
6869
"uuid": "^3.1.0"

‎rollup.config.js‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ export default {
1111
uuid: 'uuid',
1212
lodash: 'lodash',
1313
'preact-redux': 'preact-redux',
14-
linkState: 'linkState'
14+
'preact-portal': 'preact-portal'
1515
},
1616
external: [
1717
'preact',
@@ -20,7 +20,7 @@ export default {
2020
'uuid',
2121
'lodash',
2222
'preact-redux',
23-
'linkState'
23+
'preact-portal'
2424
],
2525
plugins: [
2626
babel()

‎src/browser/js/components/er-diagram-canvas.js‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@ class ERDiagramCanvas extends Component {
107107

108108
@bind
109109
removeConnectionDestination(destinationNode) {
110-
if (!!this.state.temporaryConnection.destination && this.state.temporaryConnection.destination.nodeId === destinationNode.nodeId) {
110+
if (this.state.temporaryConnection && this.state.temporaryConnection.destination && this.state.temporaryConnection.destination.nodeId === destinationNode.nodeId) {
111111
this.setState({
112112
temporaryConnection: {
113113
source: this.state.temporaryConnection.source,

‎src/browser/js/components/node-picker.js‎

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import nodeStore from '../redux/store'
77
import NODE_TYPE from './../constants/node-type'
88

99
import Entity from './../components/svg/node-types/node-entity'
10-
import Attribute from './../components/svg/node-types/node-attribute'
10+
// import Attribute from './../components/svg/node-types/node-attribute'
1111
import AssociativeEntity from './../components/svg/node-types/node-associative-entity'
1212
import Relationship from './../components/svg/node-types/node-relationship'
1313
import WeakEntity from './../components/svg/node-types/node-weak-entity'
@@ -107,9 +107,9 @@ class NodePicker extends Component {
107107
<li class='node node-associative-entity' draggable='true' onDragStart={this.dragStartedAssociativeEntity} onDragEnd={this.addNodeAssociativeEntity}>
108108
<AssociativeEntity />
109109
li>
110-
<li class='node node-attribute' draggable='true' onDragStart={this.dragStartedAttribute} onDragEnd={this.addNodeAttribute}>
111-
<Attribute />
112-
li>
110+
{/*
  • */}
  • 111+
    {/* */}
    112+
    {/* */}
    113113
    <li class='node node-relationship' draggable='true' onDragStart={this.dragStartedRelationship} onDragEnd={this.addNodeRelationship}>
    114114
    <Relationship />
    115115
    li>
    @@ -122,7 +122,7 @@ class NodePicker extends Component {
    122122
    <div class='node' id='node-drag-tween-entity' style='position:absolute;left: -1000px'><Entity />div>
    123123
    <div class='node' id='node-drag-tween-weak-entity' style='position:absolute;left: -1100px'><WeakEntity />div>
    124124
    <div class='node' id='node-drag-tween-associative-entity' style='position:absolute;left: -1200px'><AssociativeEntity />div>
    125-
    <div class='node' id='node-drag-tween-attribute' style='position:absolute;left: -1300px'><Attribute />div>
    125+
    {/*
    */
    }
    126126
    <div class='node' id='node-drag-tween-relationship' style='position:absolute;left: -1400px'><Relationship />div>
    127127
    <div class='node' id='node-drag-tween-inheritance' style='position:absolute;left: -1500px'><Inheritance />div>
    128128
    div>
    Lines changed: 30 additions & 0 deletions
    Original file line numberDiff line numberDiff line change
    @@ -0,0 +1,30 @@
    1+
    import { h, Component } from 'preact'
    2+
    import { bind } from 'decko'
    3+
    import _ from 'lodash'
    4+
    // import nodeStore from '../../redux/store'
    5+
    // import {ACTION} from '../../redux/actions'
    6+
    7+
    class Attributes extends Component {
    8+
    @bind
    9+
    onAttributeDelete() {}
    10+
    11+
    render(props) {
    12+
    if (_.isEmpty(props.attributes)) {
    13+
    return null
    14+
    }
    15+
    16+
    return (
    17+
    <div>
    18+
    {
    19+
    props.attributes.map(attribute => (
    20+
    <div class='node-attribute'>
    21+
    <span class={attribute.isPrimary ? 'primary-key' : ''}>{attribute.name}span>
    22+
    div>
    23+
    ))
    24+
    }
    25+
    div>
    26+
    )
    27+
    }
    28+
    }
    29+
    30+
    export default Attributes

    ‎src/browser/js/components/svg/node.js‎

    Lines changed: 85 additions & 2 deletions
    Original file line numberDiff line numberDiff line change
    @@ -1,9 +1,12 @@
    11
    import { h, Component } from 'preact'
    22
    import { bind } from 'decko'
    3+
    import _ from 'lodash'
    34
    import nodeStore from '../../redux/store'
    45
    import {ACTION} from '../../redux/actions'
    56
    import getNodeTypeComponent from './../../constants/node-type-components'
    67
    import NodeResize from './node-resize'
    8+
    import Attributes from './attributes'
    9+
    import Portal from 'preact-portal'
    710

    811
    class Node extends Component {
    912
    constructor({nodeId, nodeName, x, y}) {
    @@ -308,6 +311,43 @@ class Node extends Component {
    308311
    event.preventDefault()
    309312
    }
    310313

    314+
    @bind
    315+
    open() {
    316+
    this.setState({ open: true })
    317+
    }
    318+
    319+
    @bind
    320+
    close() {
    321+
    this.setState({ open: false })
    322+
    }
    323+
    324+
    @bind
    325+
    submit(event) {
    326+
    event.preventDefault()
    327+
    328+
    let attributeName = event.target[0].value
    329+
    let attributeType = event.target[1].value
    330+
    let attributeIsPrimary = event.target[2].checked
    331+
    332+
    if (_.isEmpty(attributeName)) {
    333+
    this.close()
    334+
    return
    335+
    }
    336+
    337+
    nodeStore.dispatch({type: ACTION.ADD_ATTRIBUTE,
    338+
    value: {
    339+
    nodeId: this.nodeId,
    340+
    attribute: {
    341+
    name: attributeName,
    342+
    type: attributeType,
    343+
    isPrimary: attributeIsPrimary
    344+
    }
    345+
    }
    346+
    })
    347+
    348+
    this.close()
    349+
    }
    350+
    311351
    render(props, state) {
    312352
    let rootStyle = {
    313353
    transform: `translate(${state.dragX}px, ${state.dragY}px) scale(${props.zoom})`
    @@ -320,15 +360,14 @@ class Node extends Component {
    320360
    {/* */}
    321361
    div>
    322362

    323-
    { props.selected && <NodeResize onStartNodeResize={this.startNodeResize} /> }
    363+
    { <NodeResize onStartNodeResize={this.startNodeResize} ng-if='props.selected' /> }
    324364

    325365
    <div id='svg-rect' style={{width: state.width, height: state.height}}
    326366
    onMouseDown={this.onMouseDown}
    327367
    onMouseEnter={this.onConnectionEnterDestination}
    328368
    onMouseLeave={this.onConnectionLeaveDestination}
    329369
    onClick={this.selectNode}
    330370
    >
    331-
    332371
    { getNodeTypeComponent(props.type, {width: state.width, height: state.height, color: props.color}) }
    333372

    334373
    {
    @@ -344,6 +383,50 @@ class Node extends Component {
    344383
    div>
    345384
    }
    346385
    div>
    386+
    387+
    <div class='attributes-wrapper'>
    388+
    <Attributes attributes={props.attributes} />
    389+
    390+
    { props.selected && props.type !== 'inheritance' && <button class='button-add-attribute' onClick={this.open}>Add propertybutton> }
    391+
    div>
    392+
    393+
    {
    394+
    state.open &&
    395+
    <Portal into='body'>
    396+
    <div class='modal' >
    397+
    <form class='modal-form' name='attributeForm' onSubmit={this.submit} style='z-index: 101'>
    398+
    {/* */}
    399+
    <input type='text' value='' name='attributeName' onChange={this.preventDefault} placeholder='type name...' />
    400+
    401+
    <select name='attributeType'>
    402+
    <option value='CHAR'>CHARoption>
    403+
    <option value='INTEGER'>INTEGERoption>
    404+
    <option value='FLOAT'>FLOAToption>
    405+
    <option value='TIMESTAMP'>TIMESTAMPoption>
    406+
    select>
    407+
    408+
    <label class='label--checkbox'>
    409+
    <input type='checkbox' class='checkbox' name='attributeIsKey' />
    410+
    <span>Is primary keyspan>
    411+
    label>
    412+
    413+
    <div style='text-align: right; margin: 30px 5px 0px;'>
    414+
    <input type='submit' value='Submit' />
    415+
    <input type='button' value='Cancel' onClick={this.close} />
    416+
    div>
    417+
    form>
    418+
    419+
    <div class='modal-mask' style='
    420+
    width: 100vw;
    421+
    height: 100vh;
    422+
    position: absolute;
    423+
    top: 0;
    424+
    background: rgba(21, 21, 21, 0.32);
    425+
    z-index: 100;
    426+
    ' />
    427+
    div>
    428+
    Portal>
    429+
    }
    347430
    div>
    348431
    )
    349432
    }

    ‎src/browser/js/redux/actions.js‎

    Lines changed: 1 addition & 0 deletions
    Original file line numberDiff line numberDiff line change
    @@ -23,6 +23,7 @@ const ACTION = {
    2323
    NODE_TO_FRONT: 'NODE_TO_FRONT',
    2424
    NODE_TO_BACK: 'NODE_TO_BACK',
    2525
    MOVE_CANVAS: 'MOVE_CANVAS',
    26+
    ADD_ATTRIBUTE: 'ADD_ATTRIBUTE',
    2627
    UNDO: 'UNDO',
    2728
    REDO: 'REDO'
    2829
    }

    ‎src/browser/js/redux/reducers/node.reducer.js‎

    Lines changed: 11 additions & 0 deletions
    Original file line numberDiff line numberDiff line change
    @@ -12,6 +12,7 @@ const actions = {
    1212
    nodeId: v4(),
    1313
    nodeName: action.value.type.replace(/-/, ' '),
    1414
    type: action.value.type,
    15+
    attributes: [],
    1516
    x: action.value.x - 0,
    1617
    y: action.value.y - 50,
    1718
    selected: true,
    @@ -130,6 +131,15 @@ const actions = {
    130131
    node.y += action.value.y
    131132
    })
    132133

    134+
    return newState
    135+
    },
    136+
    137+
    addAttributeToNode(state, action) {
    138+
    let newState = _.cloneDeep(state)
    139+
    140+
    let nodeForUpdate = _.find(newState, { nodeId: action.value.nodeId })
    141+
    nodeForUpdate.attributes.push(action.value.attribute)
    142+
    133143
    return newState
    134144
    }
    135145
    }
    @@ -150,6 +160,7 @@ export default function nodeReducer(state = [], action) {
    150160
    case ACTION.NODE_TO_BACK: return actions.moveNodeToBack(state, action)
    151161
    case ACTION.IMPORT: return actions.importNodes(state, action)
    152162
    case ACTION.MOVE_CANVAS: return actions.moveNodesOnCanvas(state, action)
    163+
    case ACTION.ADD_ATTRIBUTE: return actions.addAttributeToNode(state, action)
    153164
    default: return state
    154165
    }
    155166
    }

    ‎src/browser/styl/main.styl‎

    Lines changed: 112 additions & 1 deletion
    Original file line numberDiff line numberDiff line change
    @@ -68,7 +68,7 @@ li
    6868
    ////////////////////////////////
    6969
    // prettier layout
    7070
    width: 164px
    71-
    height: 70vh
    71+
    height: 60vh
    7272
    position: absolute
    7373
    left: -1px
    7474
    top: 50vh
    @@ -242,3 +242,114 @@ label[for=connect-nodes] input
    242242
    fill: #ffffff
    243243
    stroke: #222222
    244244
    stroke-width: 1
    245+
    246+
    247+
    .attributes-wrapper
    248+
    width: 100%
    249+
    position: absolute
    250+
    overflow: hidden
    251+
    252+
    .button-add-attribute
    253+
    bottom: -30px
    254+
    width: 100%
    255+
    height: 25px
    256+
    margin: 0
    257+
    margin-top: 5px
    258+
    outline: none
    259+
    box-shadow: none
    260+
    border: 1px solid black
    261+
    262+
    .modal-form
    263+
    position: absolute
    264+
    left: 50%
    265+
    top: 50%
    266+
    transform: translate(-50%, -50%)
    267+
    padding: 10px
    268+
    box-shadow: 0 3px 10px 2px rgba(0, 0, 0, 0.42)
    269+
    background: #fff
    270+
    border-radius: 3px
    271+
    overflow: auto
    272+
    text-align: center
    273+
    cursor: pointer
    274+
    animation: zoom .4s forwards ease 1
    275+
    276+
    input[type=text]
    277+
    select
    278+
    width: 91%
    279+
    height: 25px
    280+
    padding: 6px 12px
    281+
    color: #555
    282+
    background-color: #fff
    283+
    border: 1px solid #ccc
    284+
    border-radius: 4px
    285+
    box-shadow: inset 0 1px 1px rgba(0,0,0,0.075)
    286+
    margin: 5px
    287+
    288+
    .label--checkbox
    289+
    display: block
    290+
    text-align: left
    291+
    margin: 5px 14px
    292+
    user-select: none
    293+
    294+
    span
    295+
    margin-left: 15px
    296+
    297+
    298+
    .checkbox
    299+
    position: relative
    300+
    cursor: pointer
    301+
    302+
    &:before
    303+
    content: ""
    304+
    position: absolute
    305+
    left: 0
    306+
    top: -1px
    307+
    width: .75rem
    308+
    height: .375rem
    309+
    border: 2px solid #17ad3e
    310+
    border-top-style: none
    311+
    border-right-style: none
    312+
    transition: transform 0.4s cubic-bezier(0.45, 1.8, 0.5, 0.75)
    313+
    transform: rotate(-45deg) scale(0,0)
    314+
    z-index: 1
    315+
    316+
    &:checked
    317+
    &:before
    318+
    transform: rotate(-45deg) scale(1, 1)
    319+
    320+
    &:after
    321+
    content: ""
    322+
    position: absolute
    323+
    top: -4px
    324+
    left: -2px
    325+
    width: 16px
    326+
    height: 16px
    327+
    background: #fff
    328+
    border: 1px solid #ccc
    329+
    border-radius: 3px
    330+
    cursor: pointer
    331+
    332+
    333+
    .node-attribute
    334+
    padding: 3px
    335+
    border-right: 1px solid black
    336+
    border-left: 1px solid black
    337+
    border-top: 1px dashed black
    338+
    background-color: $white
    339+
    user-select: none
    340+
    341+
    &:first-child
    342+
    margin-top: -1px
    343+
    border-top: 1px solid black
    344+
    345+
    &:last-child
    346+
    border-bottom: 1px solid black
    347+
    348+
    349+
    .primary-key
    350+
    border-bottom: 1px solid black
    351+
    352+
    span
    353+
    text-overflow: ellipsis
    354+
    overflow: hidden
    355+
    white-space: nowrap

    0 commit comments

    Comments
     (0)