├── LICENSE ├── README.md ├── database-designer.css ├── database-designer.html ├── draganddrop.html ├── img ├── logo.png └── tweet.png ├── index.html ├── js ├── app.js └── initial-state.js ├── main.css ├── reset.css └── style.css /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # To-do 2 | 3 | - CSS ile arkaplana bir grid uygulanacak, Kareler 1em boyutunda 4 | - Reset CSS eklenecek 5 | - ... 6 | 7 | # Contributors 8 | 9 | - 10 | -------------------------------------------------------------------------------- /database-designer.css: -------------------------------------------------------------------------------- 1 | body { 2 | background-size: 1em 1em; 3 | background-image: 4 | linear-gradient(to right, #dfdfdf 1px, transparent 1px), 5 | linear-gradient(to bottom, #dfdfdf 1px, transparent 1px); 6 | font-family: Helvetica, sans-serif; 7 | height: 100vh; 8 | } 9 | 10 | #app { 11 | position: relative; 12 | } 13 | 14 | #app h3 { 15 | font-size: 2em; 16 | position: fixed; 17 | width: 100%; 18 | text-align: center; 19 | padding: 0.5em; 20 | } 21 | 22 | .database-table { 23 | position: absolute; 24 | background: white; 25 | border: 1px solid black; 26 | width: 12em; 27 | } 28 | 29 | .database-table h4 { 30 | background-color: yellow; 31 | text-align: center; 32 | padding: 4px; 33 | cursor: move; 34 | } 35 | 36 | body.drag-and-drop h3 { 37 | display: none; 38 | } 39 | 40 | body.drag-and-drop { 41 | background-image: 42 | linear-gradient(to right, yellow 1px, transparent 1px), 43 | linear-gradient(to bottom, yellow 1px, transparent 1px); 44 | } 45 | 46 | body.drag-and-drop .idle { 47 | opacity: 0.7; 48 | } 49 | 50 | body.drag-and-drop .is_dragging { 51 | transform: scale(1.1); 52 | } 53 | -------------------------------------------------------------------------------- /database-designer.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 |

11 |
12 |
13 | 14 | 15 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /draganddrop.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Test 1 5 | 6 | 7 | 8 | 37 | 81 | 82 | 83 | 84 |
85 |
86 |

Table Title

87 | 97 |
98 |
99 | 100 | 101 | -------------------------------------------------------------------------------- /img/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oyk2018-frontend/database-designer/3729ab0735129b0838643df50746a3c1e5eb7ece/img/logo.png -------------------------------------------------------------------------------- /img/tweet.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oyk2018-frontend/database-designer/3729ab0735129b0838643df50746a3c1e5eb7ece/img/tweet.png -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 |
11 | 12 | 13 | 14 | 31 |
32 |

Dbdesigner is a service that allows you to create, share, explore database models on the web.

33 | 34 | 35 | 36 |
37 |
38 | 39 |
40 |
41 | 42 | -------------------------------------------------------------------------------- /js/app.js: -------------------------------------------------------------------------------- 1 | (function (root) { 2 | const state = root.__INITIAL_STATE__; 3 | 4 | function renderTitle() { 5 | const titleElement = document.getElementById("document-title"); 6 | titleElement.innerHTML = state.title; 7 | } 8 | 9 | function mapFieldItems(fields) { 10 | return fields.map(function (field) { 11 | return ` 12 |
  • ${field.name}
  • 13 | `; 14 | }); 15 | } 16 | 17 | function mapEntityItems(entities) { 18 | return entities.map(function (entity) { 19 | const styles = `top: ${entity.top}px; left: ${entity.left}px`; 20 | 21 | const modifier = ( 22 | entity.name === state.UI.relatedEntity 23 | ? "is_dragging" 24 | : "idle" 25 | ); 26 | 27 | return ` 28 | 39 | `; 40 | }); 41 | } 42 | 43 | function renderEntityContainer() { 44 | const entityList = document.getElementById("entity-list"); 45 | entityList.innerHTML = mapEntityItems( 46 | state.entities 47 | ).join( 48 | "\n" 49 | ); 50 | 51 | const entityTitles = entityList.querySelectorAll(".database-table h4"); 52 | for (let i = 0; i < entityTitles.length; i++) { 53 | const title = entityTitles[i]; 54 | title.addEventListener( 55 | 'mousedown', 56 | handleMouseDown 57 | ); 58 | } 59 | } 60 | 61 | function render() { 62 | document.body.setAttribute("class", state.UI.mode); 63 | 64 | renderTitle(); 65 | renderEntityContainer(); 66 | 67 | // todo: detach this event listener before re-render 68 | document.body.addEventListener( 69 | 'mousemove', 70 | handleMouseMove 71 | ); 72 | 73 | // todo: detach this event listener before re-render 74 | document.body.addEventListener( 75 | 'mouseup', 76 | handleMouseUp 77 | ); 78 | } 79 | 80 | function handleMouseDown(event) { 81 | const entityName = event.target.dataset.entity; 82 | 83 | const entityHeaderReact = ( 84 | event.target.getBoundingClientRect() 85 | ); 86 | 87 | const diffX = event.clientX - entityHeaderReact.left; 88 | const diffY = event.clientY - entityHeaderReact.top; 89 | 90 | state.UI.mode = 'drag-and-drop'; 91 | state.UI.relatedEntity = entityName; 92 | state.UI.startX = diffX; 93 | state.UI.startY = diffY; 94 | } 95 | 96 | function handleMouseMove(event) { 97 | if (state.UI.mode === 'drag-and-drop') { 98 | // TODO: Don't mutate the state directly 99 | // Create a new state 100 | state.entities.forEach(function (entity) { 101 | if (entity.name === state.UI.relatedEntity) { 102 | entity.top = event.clientY - state.UI.startY; 103 | entity.left = event.clientX - state.UI.startX; 104 | } 105 | }); 106 | 107 | render(); 108 | } 109 | } 110 | 111 | function handleMouseUp(event) { 112 | if (state.UI.mode === 'drag-and-drop') { 113 | state.UI.mode = 'designing'; 114 | state.UI.relatedEntity = null; 115 | render(); 116 | } 117 | } 118 | 119 | root.__STATE__ = state; 120 | root.renderApp = render; 121 | })(window); 122 | -------------------------------------------------------------------------------- /js/initial-state.js: -------------------------------------------------------------------------------- 1 | (function (root) { 2 | root.__INITIAL_STATE__ = { 3 | title: "Untitled Document", 4 | UI: { 5 | mode: "designing", // or drag-and-drop 6 | relatedEntity: null, 7 | startX: 0, 8 | startY: 0, 9 | }, 10 | entities: [{ 11 | name: "users", 12 | top: 150, 13 | left: 300, 14 | fields: [{ 15 | name: "id", 16 | type: "integer", 17 | }, { 18 | name: "username", 19 | type: "charfield", 20 | }, { 21 | name: "email", 22 | type: "charfield", 23 | }, { 24 | name: "password", 25 | type: "charfield", 26 | }], 27 | }, { 28 | name: "posts", 29 | top: 140, 30 | left: 600, 31 | fields: [{ 32 | name: "id", 33 | type: "integer", 34 | }, { 35 | name: "username", 36 | type: "charfield", 37 | }, { 38 | name: "email", 39 | type: "charfield", 40 | }, { 41 | name: "password", 42 | type: "charfield", 43 | }], 44 | }, { 45 | name: "contents", 46 | top: 300, 47 | left: 200, 48 | fields: [{ 49 | name: "id", 50 | type: "integer", 51 | }, { 52 | name: "username", 53 | type: "charfield", 54 | }, { 55 | name: "email", 56 | type: "charfield", 57 | }, { 58 | name: "password", 59 | type: "charfield", 60 | }], 61 | }, { 62 | name: "images", 63 | top: 500, 64 | left: 200, 65 | fields: [{ 66 | name: "id", 67 | type: "integer", 68 | }, { 69 | name: "username", 70 | type: "charfield", 71 | }, { 72 | name: "email", 73 | type: "charfield", 74 | }, { 75 | name: "password", 76 | type: "charfield", 77 | }], 78 | }], 79 | }; 80 | })(window); 81 | -------------------------------------------------------------------------------- /main.css: -------------------------------------------------------------------------------- 1 | body { 2 | background-size: 1em 1em; 3 | background-image: 4 | linear-gradient(to right, #dfdfdf 1px, transparent 1px), 5 | linear-gradient(to bottom, #dfdfdf 1px, transparent 1px); 6 | font-family: Helvetica, sans-serif; 7 | } 8 | 9 | .clear { 10 | clear: both; 11 | } 12 | 13 | #container { 14 | width: 960px; 15 | margin-right: auto; 16 | margin-left: auto; 17 | } 18 | 19 | .header { 20 | margin-top: 1em; 21 | } 22 | 23 | .header img { 24 | float: left; 25 | } 26 | 27 | .header ul { 28 | float: right; 29 | margin-top: 0.8em; 30 | } 31 | 32 | .header ul li { 33 | display: inline-block; 34 | } 35 | 36 | .header ul li a { 37 | padding: 10px 20px 10px 20px; 38 | font-size: 24px; 39 | color: white; 40 | margin-left: 20px; 41 | text-decoration: none; 42 | background-color: #742525; 43 | } 44 | 45 | .header h1 { 46 | float: left; 47 | font-size: 1.2em; 48 | color: #565656; 49 | margin-top: 2em; 50 | } 51 | 52 | #tweet { 53 | float: right; 54 | margin-top: 2.3em; 55 | } 56 | -------------------------------------------------------------------------------- /reset.css: -------------------------------------------------------------------------------- 1 | 2 | html, body, div, span, applet, object, iframe, 3 | h1, h2, h3, h4, h5, h6, p, blockquote, pre, 4 | a, abbr, acronym, address, big, cite, code, 5 | del, dfn, em, img, ins, kbd, q, s, samp, 6 | small, strike, strong, sub, sup, tt, var, 7 | b, u, i, center, 8 | dl, dt, dd, ol, ul, li, 9 | fieldset, form, label, legend, 10 | table, caption, tbody, tfoot, thead, tr, th, td, 11 | article, aside, canvas, details, embed, 12 | figure, figcaption, footer, header, hgroup, 13 | menu, nav, output, ruby, section, summary, 14 | time, mark, audio, video { 15 | margin: 0; 16 | padding: 0; 17 | border: 0; 18 | font-size: 100%; 19 | font: inherit; 20 | vertical-align: baseline; 21 | } 22 | /* HTML5 display-role reset for older browsers */ 23 | article, aside, details, figcaption, figure, 24 | footer, header, hgroup, menu, nav, section { 25 | display: block; 26 | } 27 | body { 28 | line-height: 1; 29 | } 30 | ol, ul { 31 | list-style: none; 32 | } 33 | blockquote, q { 34 | quotes: none; 35 | } 36 | blockquote:before, blockquote:after, 37 | q:before, q:after { 38 | content: ''; 39 | content: none; 40 | } 41 | table { 42 | border-collapse: collapse; 43 | border-spacing: 0; 44 | } 45 | -------------------------------------------------------------------------------- /style.css: -------------------------------------------------------------------------------- 1 | * { 2 | -webkit-box-sizing: border-box; 3 | -moz-box-sizing: border-box; 4 | -o-box-sizing: border-box; 5 | box-sizing: border-box; 6 | } 7 | 8 | body { 9 | margin: 0; 10 | padding: 0; 11 | 12 | width: 100%; 13 | height: 100vh; 14 | 15 | background: #fff; 16 | background-image: linear-gradient(rgba(0, 0, 0, .1) .1em, transparent .1em), linear-gradient(90deg, rgba(0, 0, 0, .1) .1em, transparent .1em); 17 | background-size: 1.5em 1.5em; 18 | } 19 | 20 | .clear { 21 | clear: both; 22 | } 23 | --------------------------------------------------------------------------------