├── 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 |
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 |
88 | - id integer
89 | - username string
90 | - password string
91 | - first_name string
92 | - last_name string
93 | - email string
94 | - city string
95 | - role string
96 |
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 |
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 |
32 | -
33 |
${entity.name}
36 |
37 | ${mapFieldItems(entity.fields).join('\n')}
38 |
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 |
--------------------------------------------------------------------------------