summaryrefslogtreecommitdiff
path: root/assets
diff options
context:
space:
mode:
Diffstat (limited to 'assets')
-rw-r--r--assets/css/app.css540
-rw-r--r--assets/js/board.js197
2 files changed, 737 insertions, 0 deletions
diff --git a/assets/css/app.css b/assets/css/app.css
new file mode 100644
index 00000000..2e3e6987
--- /dev/null
+++ b/assets/css/app.css
@@ -0,0 +1,540 @@
+/* reset */
+figure,
+li,
+ul,
+ol,
+table,
+tr,
+td,
+th,
+p,
+blockquote,
+body {
+ margin: 0;
+ padding: 0;
+ font-size: 100%;
+}
+
+/* layout */
+body {
+ max-width: 1500px;
+ margin-left: 10px;
+ margin-right: 10px;
+ color: #333;
+ font-family: HelveticaNeue, "Helvetica Neue", Helvetica, Arial, sans-serif;
+ -webkit-font-smoothing: antialiased;
+ font-smoothing: antialiased;
+ text-rendering: optimizeLegibility;
+}
+
+/* links */
+a {
+ color: #3366CC;
+ border: 1px solid rgba(255, 255, 255, 0);
+}
+
+a:focus {
+ outline: 0;
+ color: red;
+ text-decoration: none;
+ border: 1px dotted #aaa;
+}
+
+a:hover {
+ color: #333;
+ text-decoration: none;
+}
+
+/* titles */
+h1, h2, h3 {
+ font-weight: normal;
+ color: #333;
+}
+
+h2 {
+ font-size: 1.6em;
+}
+
+h3 {
+ margin-top: 10px;
+ font-size: 1.2em;
+}
+
+/* tables */
+table {
+ width: 100%;
+ border-collapse: collapse;
+ border-spacing: 0;
+}
+
+table caption {
+ font-weight: bold;
+ font-size: 1.0em;
+ text-align: left;
+ padding-bottom: 0.5em;
+ padding-top: 0.5em;
+}
+
+th,
+td {
+ border: 1px solid #ccc;
+ padding-top: 0.5em;
+ padding-bottom: 0.5em;
+ padding-left: 5px;
+}
+
+th {
+ text-align: left;
+ background: #f0f0f0;
+}
+
+tr:nth-child(odd) td {
+ background: #fcfcfc;
+}
+
+td li {
+ margin-left: 20px;
+}
+
+/* forms */
+form {
+ padding-top: 5px;
+ padding-bottom: 5px;
+ padding-left: 15px;
+ margin-bottom: 20px;
+ border-left: 2px dotted #ddd;
+}
+
+label {
+ cursor: pointer;
+ display: block;
+ margin-top: 10px;
+}
+
+input[type="checkbox"] {
+ border: 1px solid #ccc;
+}
+
+input[type="date"],
+input[type="email"],
+input[type="tel"],
+input[type="password"],
+input[type="text"] {
+ border: 1px solid #ccc;
+ padding: 3px;
+ line-height: 15px;
+ width: 400px;
+ font-size: 99%;
+ margin-top: 5px;
+ -webkit-appearance: none;
+ appearance: none;
+}
+
+input[type="date"]:focus,
+input[type="email"]:focus,
+input[type="tel"]:focus,
+input[type="password"]:focus,
+input[type="text"]:focus,
+textarea:focus {
+ color: #000;
+ border-color: rgba(82, 168, 236, 0.8);
+ outline: 0;
+ box-shadow: 0 0 8px rgba(82, 168, 236, 0.6);
+}
+
+textarea {
+ border: 1px solid #ccc;
+ padding: 3px;
+ width: 400px;
+ height: 200px;
+ font-size: 99%;
+}
+
+select {
+}
+
+::-webkit-input-placeholder {
+ color: #bbb;
+ padding-top: 2px;
+}
+
+::-ms-input-placeholder {
+ color: #bbb;
+ padding-top: 2px;
+}
+
+::-moz-placeholder {
+ color: #bbb;
+ padding-top: 2px;
+}
+
+.form-actions {
+ margin-top: 20px;
+}
+
+input.form-error,
+textarea.form-error {
+ border: 2px solid #b94a48;
+}
+
+.form-errors {
+ color: #b94a48;
+ list-style-type: none;
+}
+
+.form-help {
+ font-size: 0.9em;
+ color: brown;
+ margin-bottom: 15px;
+}
+
+.form-inline {
+ padding: 0;
+ margin: 0;
+ border: none;
+}
+
+.form-inline label {
+ display: inline;
+}
+
+.form-inline input,
+.form-inline select {
+ margin: 0;
+ margin-right: 15px;
+}
+
+/* alerts */
+.alert {
+ padding: 8px 35px 8px 14px;
+ margin-bottom: 20px;
+ color: #c09853;
+ background-color: #fcf8e3;
+ border: 1px solid #fbeed5;
+ border-radius: 4px;
+}
+
+.alert-success {
+ color: #468847;
+ background-color: #dff0d8;
+ border-color: #d6e9c6;
+}
+
+.alert-error {
+ color: #b94a48;
+ background-color: #f2dede;
+ border-color: #eed3d7;
+}
+
+.alert-info {
+ color: #3a87ad;
+ background-color: #d9edf7;
+ border-color: #bce8f1;
+}
+
+.alert-normal {
+ color: #333;
+ background-color: #f0f0f0;
+ border-color: #ddd;
+}
+
+/* labels */
+a.label {
+ text-decoration: none;
+}
+
+a.label:hover,
+a.label:focus {
+ text-decoration: underline;
+}
+
+.label {
+ font-size: 0.9em;
+ border-radius: 5px 5px 5px 5px;
+ border: 1px solid #000;
+ border-color: rgba(0, 0, 0, 0.3);
+ background: #fff;
+ color: #000;
+ color: rgba(0, 0, 0, 0.8);
+ display: inline-block;
+ padding: 2px 5px;
+ vertical-align: top;
+ overflow: hidden;
+ text-overflow: ellipsis;
+}
+
+.label-yellow {
+ background-color: #ffee92;
+}
+
+.label-red {
+ background-color: #eea2a0;
+}
+
+.label-green {
+ background-color: #b3e494;
+}
+
+.label-blue {
+ background-color: #d5eeff;
+}
+
+.label-purple {
+ background-color: #dca9de;
+}
+
+/* buttons */
+.btn {
+ -webkit-appearance: none;
+ appearance: none;
+ display: inline-block;
+ color: #333;
+ border: 1px solid #ccc;
+ background: #efefef;
+ padding: 5px;
+ padding-left: 15px;
+ padding-right: 15px;
+ font-size: 0.9em;
+ cursor: pointer;
+ border-radius: 2px;
+}
+
+.btn-small {
+ padding: 2px;
+ padding-left: 5px;
+ padding-right: 5px;
+}
+
+a.btn {
+ text-decoration: none;
+ font-weight: bold;
+}
+
+.btn-red {
+ border-color: #b0281a;;
+ background: #d14836;
+ color: #fff;
+}
+
+a.btn-red:hover,
+.btn-red:hover,
+.btn-red:focus {
+ color: #fff;
+ background: #c53727;
+}
+
+.btn-blue {
+ border-color: #3079ed;
+ background: #4d90fe;
+ color: #fff;
+}
+
+.btn-blue:hover,
+.btn-blue:focus {
+ border-color: #2f5bb7;
+ background: #357ae8;
+}
+
+/* header */
+header {
+ margin-bottom: 25px;
+ margin-top: 10px;
+}
+
+header ul {
+ text-align: right;
+ font-size: 90%;
+}
+
+header li {
+ display: inline;
+ padding-left: 30px;
+}
+
+header a {
+ color: #777;
+ text-decoration: none;
+}
+
+nav .active a {
+ color: #333;
+ font-weight: bold;
+}
+
+.logo {
+ color: #DF5353;
+ letter-spacing: 1px;
+ float: left;
+}
+
+.page-section {
+ margin-top: 30px;
+}
+
+.page-section,
+.page-header {
+ margin-bottom: 25px;
+}
+
+.page-section h2,
+.page-header h2 {
+ margin: 0;
+ padding: 0;
+ font-size: 140%;
+ border-bottom: 1px dotted red;
+}
+
+.page-header ul {
+ text-align: left;
+ margin-top: 5px;
+}
+
+.page-header li {
+ display: inline;
+ padding-left: 10px;
+ padding-right: 10px;
+ border-left: 1px dotted #ccc;
+}
+
+.page-header li:first-child {
+ border: none;
+ padding-left: 0;
+}
+
+/* boards */
+#board th a {
+ text-decoration: none;
+ font-size: 150%;
+}
+
+#board td {
+ vertical-align: top;
+}
+
+.task-title {
+ margin-top: 10px;
+ font-size: 110%;
+}
+
+.task-user {
+ font-size: 80%;
+}
+
+.task-nobody {
+ font-style: italic;
+}
+
+.task {
+ border: 1px solid #000;
+ padding: 5px;
+ font-size: 95%;
+}
+
+td.over {
+ background-color: #f0f0f0;
+}
+
+td div.over {
+ border: 2px dashed #000;
+}
+
+.draggable-item {
+ margin-right: 5px;
+ margin-bottom: 10px;
+}
+
+[draggable] {
+ user-select: none;
+}
+
+[draggable=true]:hover {
+ box-shadow: 0 0 3px #333;
+}
+
+div.task a {
+ color: #000;
+ text-decoration: none;
+ font-weight: bold;
+}
+
+div.task a:focus,
+div.task a:hover {
+ text-decoration: underline;
+}
+
+article.task li {
+ margin-left: 20px;
+ list-style-type: square;
+}
+
+.task-blue {
+ background-color: rgb(219, 235, 255);
+ border-color: rgb(168, 207, 255);
+}
+
+.task-purple {
+ background-color: rgb(223, 176, 255);
+ border-color: rgb(205, 133, 254);
+}
+
+.task-grey {
+ background-color: rgb(238, 238, 238);
+ border-color: rgb(204, 204, 204);
+}
+
+.task-red {
+ background-color: rgb(255, 187, 187);
+ border-color: rgb(255, 151, 151);
+}
+
+.task-green {
+ background-color: rgb(189, 244, 203);
+ border-color: rgb(74, 227, 113);
+}
+
+.task-yellow {
+ background-color: rgb(245, 247, 196);
+ border-color: rgb(223, 227, 45);
+}
+
+.task-orange {
+ background-color: rgb(255, 215, 179);
+ border-color: rgb(255, 172, 98);
+}
+
+#description {
+ border-left: 5px solid #000;
+ background: #f0f0f0;
+ padding-left: 10px;
+ padding-top: 10px;
+ padding-bottom: 10px;
+}
+
+#description li {
+ margin-left: 25px;
+}
+
+/* config page */
+.settings {
+ border-radius: 4px;
+ padding: 8px 35px 8px 14px;
+ margin-bottom: 20px;
+ border: 1px solid #ddd;
+ color: #333;
+ background-color: #f0f0f0;
+}
+
+.settings li {
+ list-style-type: square;
+ margin-left: 20px;
+ margin-bottom: 3px;
+}
+
+/* confirmation box */
+.confirm {
+ max-width: 700px;
+ padding-top: 5px;
+ padding-bottom: 5px;
+ padding-left: 15px;
+ border-left: 2px dotted #ddd;
+}
diff --git a/assets/js/board.js b/assets/js/board.js
new file mode 100644
index 00000000..a9bd35d1
--- /dev/null
+++ b/assets/js/board.js
@@ -0,0 +1,197 @@
+(function () {
+
+ function handleItemDragStart(e)
+ {
+ this.style.opacity = '0.4';
+
+ dragSrcItem = this;
+ dragSrcColumn = this.parentNode;
+
+ e.dataTransfer.effectAllowed = 'copy';
+ e.dataTransfer.setData('text/plain', this.innerHTML);
+ }
+
+ function handleItemDragEnd(e)
+ {
+ // Restore styles
+ removeOver();
+ this.style.opacity = '1.0';
+
+ dragSrcColumn = null;
+ dragSrcItem = null;
+ }
+
+ function handleItemDragOver(e)
+ {
+ if (e.preventDefault) e.preventDefault();
+
+ e.dataTransfer.dropEffect = 'copy';
+
+ return false;
+ }
+
+ function handleItemDragEnter(e)
+ {
+ if (dragSrcItem != this) {
+ removeOver();
+ this.classList.add('over');
+ }
+ }
+
+ function handleItemDrop(e)
+ {
+ if (e.preventDefault) e.preventDefault();
+ if (e.stopPropagation) e.stopPropagation();
+
+ // Drop the element if the item is not the same
+ if (dragSrcItem != this) {
+
+ var position = getItemPosition(this);
+ var item = createItem(e.dataTransfer.getData('text/plain'));
+
+ if (countColumnItems(this.parentNode) == position) {
+ this.parentNode.appendChild(item);
+ }
+ else {
+ this.parentNode.insertBefore(item, this);
+ }
+
+ dragSrcItem.parentNode.removeChild(dragSrcItem);
+
+ saveBoard();
+ }
+
+ dragSrcColumn = null;
+ dragSrcItem = null;
+
+ return false;
+ }
+
+
+ function handleColumnDragOver(e)
+ {
+ if (e.preventDefault) e.preventDefault();
+
+ e.dataTransfer.dropEffect = 'copy';
+
+ return false;
+ }
+
+ function handleColumnDragEnter(e)
+ {
+ if (dragSrcColumn != this) {
+ removeOver();
+ this.classList.add('over');
+ }
+ }
+
+ function handleColumnDrop(e)
+ {
+ if (e.preventDefault) e.preventDefault();
+ if (e.stopPropagation) e.stopPropagation();
+
+ // Drop the element if the column is not the same
+ if (dragSrcColumn != this) {
+
+ var item = createItem(e.dataTransfer.getData('text/plain'));
+ this.appendChild(item);
+ dragSrcColumn.removeChild(dragSrcItem);
+
+ saveBoard();
+ }
+
+ return false;
+ }
+
+ function saveBoard()
+ {
+ var data = [];
+ var projectId = document.getElementById("board").getAttribute("data-project-id");
+ var cols = document.querySelectorAll('.column');
+
+ [].forEach.call(cols, function(col) {
+
+ [].forEach.call(col.children, function(item) {
+
+ data.push({
+ "task_id": item.firstElementChild.getAttribute("data-task-id"),
+ "position": getItemPosition(item),
+ "column_id": col.getAttribute("data-column-id")
+ })
+ });
+ });
+
+ var xhr = new XMLHttpRequest();
+ xhr.open("POST", "?controller=board&action=save&project_id=" + projectId, true);
+ xhr.send(JSON.stringify(data));
+ }
+
+ function getItemPosition(element)
+ {
+ var i = 0;
+
+ while ((element = element.previousSibling) != null) {
+
+ if (element.nodeName == "DIV" && element.className == "draggable-item") {
+ i++;
+ }
+ }
+
+ return i + 1;
+ }
+
+ function countColumnItems(element)
+ {
+ return element.children.length;
+ }
+
+ function createItem(html)
+ {
+ var item = document.createElement("div");
+ item.className = "draggable-item";
+ item.draggable = true;
+ item.innerHTML = html;
+ item.ondragstart = handleItemDragStart;
+ item.ondragend = handleItemDragEnd;
+ item.ondragenter = handleItemDragEnter;
+ item.ondragover = handleItemDragOver;
+ item.ondrop = handleItemDrop;
+
+ return item;
+ }
+
+ function removeOver()
+ {
+ // Remove column over
+ [].forEach.call(document.querySelectorAll('.column'), function (col) {
+ col.classList.remove('over');
+ });
+
+ // Remove item over
+ [].forEach.call(document.querySelectorAll('.draggable-item'), function (item) {
+ item.classList.remove('over');
+ });
+ }
+
+ var dragSrcItem = null;
+ var dragSrcColumn = null;
+
+ var items = document.querySelectorAll('.draggable-item');
+
+ [].forEach.call(items, function(item) {
+ item.addEventListener('dragstart', handleItemDragStart, false);
+ item.addEventListener('dragend', handleItemDragEnd, false);
+ item.addEventListener('dragenter', handleItemDragEnter, false);
+ item.addEventListener('dragover', handleItemDragOver, false);
+ item.addEventListener('drop', handleItemDrop, false);
+ });
+
+ var cols = document.querySelectorAll('.column');
+
+ [].forEach.call(cols, function(col) {
+ col.addEventListener('dragenter', handleColumnDragEnter, false);
+ col.addEventListener('dragover', handleColumnDragOver, false);
+ col.addEventListener('drop', handleColumnDrop, false);
+ });
+
+}()); \ No newline at end of file