10 changed files with 1802 additions and 2706 deletions
Split View
Diff Options
-
7customize.dist/pages.js
-
1customize.dist/src/less2/main.less
-
688www/kanban/app-kanban.less
-
41www/kanban/index.html
-
48www/kanban/inner.html
-
815www/kanban/inner.js
-
66www/kanban/jkanban.css
-
2774www/kanban/jkanban.js
-
25www/kanban/kanban.css
-
43www/kanban/main.js
@ -1,671 +1,39 @@ |
|||
@import (once) "../../customize/src/less2/include/browser.less"; |
|||
@import (once) "../../customize/src/less2/include/toolbar.less"; |
|||
@import (once) "../../customize/src/less2/include/markdown.less"; |
|||
@import (once) '../../customize/src/less2/include/fileupload.less'; |
|||
@import (once) '../../customize/src/less2/include/alertify.less'; |
|||
@import (once) '../../customize/src/less2/include/tokenfield.less'; |
|||
@import (once) '../../customize/src/less2/include/tools.less'; |
|||
@import (once) '../../customize/src/less2/include/avatar.less'; |
|||
@import (once) '../../customize/src/less2/include/creation.less'; |
|||
@import (once) "../../customize/src/less2/include/framework.less"; |
|||
|
|||
.toolbar_main( |
|||
@bg-color: @colortheme_kanban-bg, |
|||
@warn-color: @colortheme_kanban-warn, |
|||
@color: @colortheme_kanban-color |
|||
); |
|||
.fileupload_main(); |
|||
.alertify_main(); |
|||
.tokenfield_main(); |
|||
.creation_main(); |
|||
.framework_main( @bg-color: @colortheme_code-bg, |
|||
@warn-color: @colortheme_code-warn, |
|||
@color: @colortheme_code-color); |
|||
|
|||
@kanban-fore: #555; |
|||
|
|||
@kanban-th-bg: @colortheme_kanban-th-bg; |
|||
@kanban-th-fg: @colortheme_kanban-th-fg; |
|||
@kanban-th-user-bg: darken(@kanban-th-bg, 10%); |
|||
@kanban-editing: lighten(@kanban-th-bg, 10%); |
|||
@kanban-winner: darken(@kanban-th-bg, 15%); |
|||
@kanban-td-bg: @kanban-th-bg; |
|||
@kanban-td-fg: @kanban-th-fg; |
|||
|
|||
@kanban-help-bg: @colortheme_kanban-help-bg; |
|||
|
|||
@kanban-uncommitted-cell: #eee; |
|||
@kanban-uncommitted-bg: #ddd; //lighten(@kanban-th-bg, 50%); |
|||
@kanban-uncommitted-text: black; |
|||
|
|||
@kanban-placeholder: #fff; |
|||
@kanban-border-color: #555; |
|||
@kanban-cover-color: #000; |
|||
@kanban-fg: #000; |
|||
@kanban-option-yellow: #ff5; |
|||
@kanban-option-gray: #ccc; |
|||
|
|||
@kanban-add-color: #fff; |
|||
@kanban-add-bg: #777; |
|||
@kanban-add-bg-alt: #444; |
|||
|
|||
.bottom-left(@s: 5px) { border-bottom-left-radius: @s; } |
|||
.top-left(@s: 5px) { border-top-left-radius: @s; } |
|||
|
|||
display: flex; |
|||
flex-flow: column; |
|||
overflow-x: hidden; |
|||
|
|||
#cp-app-kanban-content { |
|||
// body |
|||
&.cp-app-kanban { |
|||
display: flex; |
|||
flex: 1; |
|||
min-height: 0; |
|||
#cp-app-kanban-form { |
|||
flex: 1; |
|||
overflow-y: auto; |
|||
&.cp-app-kanban-readonly { |
|||
#cp-app-kanban-table-scroll { |
|||
max-width: ~"calc(75% - 30px - 100px)"; |
|||
} |
|||
table { |
|||
width: 100%; |
|||
} |
|||
table tr td:last-child { |
|||
margin-left: 0; // uncommitted is hidden |
|||
} |
|||
td.cp-app-kanban-table-uncommitted { |
|||
display: none; |
|||
} |
|||
} |
|||
&.cp-app-kanban-published { |
|||
#cp-app-kanban-create-option { |
|||
display: none; |
|||
} |
|||
.cp-app-kanban-table-remove[data-rt-id^="y"], .cp-app-kanban-table-edit[data-rt-id^="y"] { |
|||
display: none; |
|||
} |
|||
tr.cp-app-kanban-table-uncommitted { |
|||
display: none; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
|
|||
input[type="text"], textarea { |
|||
background-color: white; |
|||
color: black; |
|||
border: 0; |
|||
} |
|||
|
|||
input[type="text"][disabled], textarea[disabled] { |
|||
background-color: transparent; |
|||
border: 0px; |
|||
} |
|||
|
|||
// The placeholder color only seems to effect Safari when not set |
|||
|
|||
input[type="text"][disabled]::placeholder { |
|||
color: @kanban-placeholder; |
|||
opacity: 1; |
|||
} |
|||
|
|||
table#cp-app-kanban-table { |
|||
margin: 0px; |
|||
overflow: hidden; |
|||
} |
|||
#cp-app-kanban-table-container { |
|||
position: relative; |
|||
margin: 20px; |
|||
} |
|||
#cp-app-kanban-table-container button { |
|||
border-radius: 0; |
|||
border: 0; |
|||
} |
|||
#cp-app-kanban-create-user { |
|||
display: inline-flex; |
|||
height: 20px; |
|||
padding: 0 5px; |
|||
margin: 2px auto; |
|||
width: auto; |
|||
overflow: hidden; |
|||
color: @kanban-add-color; |
|||
background: @kanban-add-bg; |
|||
&:hover { |
|||
background: @kanban-add-bg-alt; |
|||
} |
|||
} |
|||
#cp-app-kanban-create-option { |
|||
order: 3; |
|||
display: inline-flex; |
|||
width: 46px; |
|||
height: 20px; |
|||
margin: 2px; |
|||
padding: 0; |
|||
color: @kanban-add-color; |
|||
background: @kanban-add-bg; |
|||
&:hover { |
|||
background: @kanban-add-bg-alt; |
|||
} |
|||
} |
|||
#cp-app-kanban-table-scroll { |
|||
overflow-y: hidden; |
|||
overflow-x: auto; |
|||
margin-left: 25%; |
|||
max-width: ~"calc(75% - 100px - 100px)"; |
|||
width: auto; |
|||
display: inline-block; |
|||
} |
|||
.cp-markdown-toolbar { |
|||
margin: auto; |
|||
min-width: 80%; |
|||
width: 80%; |
|||
} |
|||
#cp-app-kanban-description { |
|||
&~ .CodeMirror { |
|||
margin: auto; |
|||
min-width: 80%; |
|||
width: 80%; |
|||
min-height: 200px; |
|||
height: 200px; |
|||
border: 1px solid black; |
|||
.CodeMirror-placeholder { |
|||
color: #777; |
|||
} |
|||
} |
|||
} |
|||
#cp-app-kanban-description-published { |
|||
display: none; |
|||
padding: 15px; |
|||
margin: auto; |
|||
|
|||
min-width: 80%; |
|||
width: 80%; |
|||
min-height: 7em; |
|||
color: #000; |
|||
border: 1px solid transparent; |
|||
background-color: #eeeeee; |
|||
font: @colortheme_app-font; |
|||
text-align: left; |
|||
media-tag > * { |
|||
max-width: 100%; |
|||
max-height: 20em; |
|||
} |
|||
} |
|||
div.cp-app-kanban-published { |
|||
div.cp-app-kanban-realtime { |
|||
#cp-app-kanban-description { |
|||
display: none; |
|||
&~ .CodeMirror { |
|||
display: none; |
|||
} |
|||
} |
|||
#cp-app-kanban-description-published { |
|||
display: block; |
|||
&:empty { |
|||
display: none; |
|||
} |
|||
} |
|||
#cp-app-kanban-nocomments { |
|||
display: none; |
|||
} |
|||
#cp-app-kanban-comments { |
|||
display: block; |
|||
} |
|||
} |
|||
} |
|||
|
|||
#cp-app-kanban-help { |
|||
width: 100%; |
|||
margin: auto; |
|||
padding: 20px 10%; |
|||
background: @kanban-help-bg; |
|||
} |
|||
|
|||
// from cryptpad.less |
|||
|
|||
table { |
|||
border-collapse: collapse; |
|||
border-spacing: 0; |
|||
margin: 20px; |
|||
} |
|||
tbody { |
|||
* { |
|||
box-sizing: border-box; |
|||
} |
|||
tr { |
|||
text-align: center; |
|||
} |
|||
|
|||
td { |
|||
.tools_unselectable(); |
|||
border-right: 1px solid @kanban-border-color; |
|||
padding: 12px; |
|||
padding-top: 0px; |
|||
padding-bottom: 0px; |
|||
&:last-child { |
|||
border-right: none; |
|||
} |
|||
} |
|||
} |
|||
|
|||
div.cp-app-kanban-realtime { |
|||
display: block; |
|||
flex-flow: column; |
|||
max-height: 100%; |
|||
max-width: 100%; |
|||
|
|||
input { |
|||
&[type="text"] { |
|||
height: 1em; |
|||
margin: 0px; |
|||
} |
|||
} |
|||
> textarea { |
|||
width: 50%; |
|||
height: 15vh; |
|||
} |
|||
|
|||
padding: 0px; |
|||
margin: 0px; |
|||
|
|||
.cp-app-kanban-table-scrolled { |
|||
tr td:last-child { |
|||
right: 0; |
|||
} |
|||
tr td:nth-last-child(2) { |
|||
right: 100px; |
|||
} |
|||
} |
|||
|
|||
table { |
|||
border-collapse: collapse; |
|||
width: ~"calc(100% - 1px)"; |
|||
.cp-app-kanban-table-editing { |
|||
background-color: @kanban-editing; |
|||
} |
|||
.cp-app-kanban-table-uncommitted { |
|||
.cp-app-kanban-table-cover { |
|||
background-color: @kanban-uncommitted-cell !important; |
|||
} |
|||
div.cp-app-kanban-table-text-cell { |
|||
background-color: @kanban-uncommitted-bg !important; |
|||
color: @kanban-uncommitted-text !important; |
|||
} |
|||
text-align: center; |
|||
background-color: @kanban-uncommitted-bg !important; |
|||
color: @kanban-uncommitted-text !important; |
|||
} |
|||
tr { |
|||
height: 28px; |
|||
/* Options */ |
|||
td:first-child { |
|||
position:absolute; |
|||
left: 0; |
|||
top: auto; |
|||
width: 25%; |
|||
} |
|||
/* Uncommitted column */ |
|||
td:nth-last-child(2) { |
|||
position: absolute; |
|||
top: auto; |
|||
width: 100px; |
|||
min-width: unset !important; |
|||
height: auto !important; |
|||
} |
|||
/* Results */ |
|||
td:last-child { |
|||
color: @kanban-th-fg; |
|||
position:absolute; |
|||
top: auto; |
|||
margin-left: 100px; |
|||
width: 100px; |
|||
min-width: unset !important; |
|||
background-color: @kanban-th-bg; |
|||
} |
|||
td { |
|||
padding: 0px; |
|||
margin: 0px; |
|||
|
|||
div.cp-app-kanban-table-text-cell { |
|||
height: 28px; |
|||
padding: 0px; |
|||
margin: 0px; |
|||
display: flex; |
|||
align-items: center; |
|||
.cp-app-kanban-table-remove { |
|||
order: 1; |
|||
} |
|||
.cp-app-kanban-table-edit { |
|||
order: 3; |
|||
} |
|||
input { |
|||
min-width: 0; |
|||
order: 2; |
|||
flex: 1; |
|||
height: 24px; |
|||
border: 0px; |
|||
margin: 2px; |
|||
&[disabled] { |
|||
background-color: transparent; |
|||
color: @kanban-td-fg; |
|||
//font-weight: bold; |
|||
} |
|||
} |
|||
} |
|||
|
|||
&.cp-app-kanban-table-checkbox-cell { |
|||
margin: 0px; |
|||
padding: 0px; |
|||
height: 100%; |
|||
min-width: 100px; |
|||
|
|||
div.cp-app-kanban-table-checkbox-contain { |
|||
display: inline-block; |
|||
height: 100%; |
|||
width: 100%; |
|||
position: relative; |
|||
|
|||
label { |
|||
background-color: transparent; |
|||
display: block; |
|||
position: absolute; |
|||
top: 0px; |
|||
left: 0px; |
|||
height: 100%; |
|||
width: 100%; |
|||
} |
|||
|
|||
input { |
|||
&[type="number"] { |
|||
&:not(.editable) { |
|||
display: none; |
|||
|
|||
~ .cp-app-kanban-table-cover { |
|||
line-height: 28px; |
|||
display: block; |
|||
font-weight: bold; |
|||
height: 100%; |
|||
display: block; |
|||
|
|||
color: @kanban-cover-color; |
|||
|
|||
&:after { |
|||
height: 100%; |
|||
} |
|||
|
|||
} |
|||
} |
|||
} |
|||
} |
|||
|
|||
input[type="number"][value="0"] { |
|||
~ .cp-app-kanban-table-cover { |
|||
background-color: @colortheme_cp-red; |
|||
&:after { content: "✖"; } |
|||
} |
|||
} |
|||
input[type="number"][value="1"] { |
|||
~ .cp-app-kanban-table-cover { |
|||
background-color: @colortheme_cp-green; |
|||
&:after { content: "✔"; } |
|||
} |
|||
} |
|||
input[type="number"][value="2"] { |
|||
~ .cp-app-kanban-table-cover { |
|||
background-color: @kanban-option-yellow; |
|||
&:after { content: "~"; } |
|||
} |
|||
} |
|||
input[type="number"][value="3"] { |
|||
~ .cp-app-kanban-table-cover { |
|||
background-color: @kanban-option-gray; |
|||
&:after { content: "?"; } |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
|||
|
|||
input { |
|||
&[type="text"] { |
|||
height: auto; |
|||
width: 80%; |
|||
} |
|||
} |
|||
span { |
|||
.tools_unselectable(); |
|||
} |
|||
thead { |
|||
height: 52px; |
|||
tr { |
|||
height: 52px; |
|||
} |
|||
td { |
|||
padding: 0px 5px; |
|||
background: @kanban-th-bg; |
|||
color: @kanban-th-fg; |
|||
&:not(:last-child) { |
|||
border-right: 1px solid rgba(255,255,255,0.2); |
|||
} |
|||
&:last-child { |
|||
height: 52px; |
|||
line-height: 52px; |
|||
text-align: center; |
|||
} |
|||
&:nth-last-child(2) { |
|||
border-right: 1px solid @kanban-border-color; |
|||
} |
|||
&.cp-app-kanban-table-own { |
|||
background: @kanban-th-user-bg; |
|||
.cp-app-kanban-table-lock { |
|||
cursor: default; |
|||
} |
|||
} |
|||
.cp-app-kanban-table-buttons { |
|||
display: flex; |
|||
justify-content: space-between; |
|||
flex-wrap: wrap; |
|||
align-items: center; |
|||
span { |
|||
cursor: pointer; |
|||
width: 1em; |
|||
text-align: center; |
|||
} |
|||
.cp-app-kanban-table-bookmark { |
|||
color: darken(@kanban-th-fg, 30%); |
|||
&.cp-app-kanban-table-bookmark-full { |
|||
color: @kanban-th-fg; |
|||
} |
|||
} |
|||
} |
|||
input { |
|||
&[type="text"] { |
|||
overflow: hidden; |
|||
text-overflow: ellipsis; |
|||
break-after: always; |
|||
width: ~"calc(100% - 2px)"; // borders... |
|||
box-sizing: border-box; |
|||
padding: 1px 5px; |
|||
margin: 1px; |
|||
&[disabled] { |
|||
color: @kanban-th-fg; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
|||
|
|||
tbody { |
|||
td:first-child { |
|||
background: @kanban-td-bg; |
|||
color: @kanban-td-fg; |
|||
} |
|||
td.cp-app-kanban-table-winner { |
|||
background-color: @kanban-winner; |
|||
&:last-child { font-weight: bold; } |
|||
} |
|||
.cp-app-kanban-table-text-cell { |
|||
input[type="text"] { |
|||
width: ~"calc(100% - 50px)"; |
|||
padding: 0 0.5em; |
|||
} |
|||
.cp-app-kanban-table-edit { |
|||
float:right; |
|||
margin: 2px 10px 0 0; |
|||
} |
|||
.cp-app-kanban-table-remove { |
|||
float: left; |
|||
margin: 2px 0 0 10px; |
|||
} |
|||
} |
|||
tr:not(:first-child) { |
|||
td:not(:first-child) { |
|||
label { |
|||
border-top: 1px solid @kanban-border-color; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
.cp-app-kanban-table-edit { |
|||
//color: @kanban-cover-color; |
|||
cursor: pointer; |
|||
float: left; |
|||
margin-left: 10px; |
|||
} |
|||
|
|||
thead { |
|||
tr { |
|||
th { |
|||
input[type="text"][disabled] { |
|||
background-color: transparent; |
|||
color: @kanban-fore; |
|||
font-weight: bold; |
|||
} |
|||
.cp-app-kanban-table-remove { |
|||
cursor: pointer; |
|||
font-size: 20px; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
tbody { |
|||
tr { |
|||
td { |
|||
|
|||
} |
|||
} |
|||
} |
|||
tfoot { |
|||
display: none; |
|||
} |
|||
} |
|||
#cp-app-kanban-nocomments { |
|||
color: #999; |
|||
text-align: center; |
|||
margin: 20px; |
|||
font: @colortheme_app-font; |
|||
} |
|||
#cp-app-kanban-comments { |
|||
width: 50%; |
|||
margin: 20px auto; |
|||
min-width: 400px; |
|||
padding-bottom: 5px; |
|||
display: none; |
|||
button { |
|||
border-radius: 0; |
|||
} |
|||
#cp-app-kanban-comments-add { |
|||
input, textarea { |
|||
border: 1px solid black; |
|||
width: 90%; |
|||
margin: 5px 5%; |
|||
} |
|||
input { |
|||
padding: 5px; |
|||
height: 26px; |
|||
&[disabled] { |
|||
background: #eee; |
|||
} |
|||
} |
|||
textarea { |
|||
padding: 5px; |
|||
height: 8em; |
|||
line-height: 1.5em; |
|||
} |
|||
button { |
|||
padding: 10px; |
|||
} |
|||
text-align: center; |
|||
} |
|||
#cp-app-kanban-comments-list { |
|||
.cp-app-kanban-comments-list-el { |
|||
width: 90%; |
|||
margin: 5px 5%; |
|||
} |
|||
.cp-app-kanban-comments-list-msg { |
|||
display: flex; |
|||
background: #eee; |
|||
padding: 5px 10px; |
|||
.cp-app-kanban-comments-list-msg-text { |
|||
flex: 1; |
|||
white-space: pre-wrap; |
|||
} |
|||
.cp-app-kanban-comments-list-msg-actions { |
|||
button { |
|||
padding: 0; |
|||
width: 25px; |
|||
line-height: 20px; |
|||
} |
|||
} |
|||
} |
|||
.cp-app-kanban-comments-list-data { |
|||
background: #ddd; |
|||
padding: 5px 10px; |
|||
display: flex; |
|||
align-items: center; |
|||
.cp-app-kanban-comments-list-data-name { |
|||
margin-left: 10px; |
|||
flex: 1; |
|||
} |
|||
.cp-app-kanban-comments-list-data-avatar { .avatar_main(30px); } |
|||
} |
|||
} |
|||
min-height: auto; |
|||
|
|||
#cp-app-kanban-container { |
|||
display: inline-flex; |
|||
flex-flow: column; |
|||
height: 100%; |
|||
min-height: 100%; |
|||
width: 200%; |
|||
resize: horizontal; |
|||
overflow: hidden; |
|||
} |
|||
#cp-app-kanban-editor { |
|||
flex: 1; |
|||
display: flex; |
|||
flex-flow: row; |
|||
height: 100%; |
|||
overflow: hidden; |
|||
} |
|||
|
|||
@media screen and (max-width: 500px) { |
|||
#cp-app-kanban-table-scroll { |
|||
@media (max-width: @browser_media-medium-screen) { |
|||
#cp-app-kanban-container { |
|||
flex: 1; |
|||
max-width: 100%; |
|||
padding: 0; |
|||
margin: 0; |
|||
table { |
|||
tr { |
|||
td { |
|||
&:first-child { |
|||
position: unset; |
|||
min-width: 100px; |
|||
&:hover:not(:empty) { |
|||
position: absolute; |
|||
min-width: 100px; |
|||
width: auto; |
|||
z-index: 100; |
|||
} |
|||
} |
|||
&:nth-last-child(2) { |
|||
position: unset; |
|||
} |
|||
&:last-child { |
|||
position: unset; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
|||
#cp-app-kanban-comments { |
|||
min-width: 90%; |
|||
resize: none; |
|||
} |
|||
} |
|||
} |
|||
|
|||
|
|||
.btn { |
|||
display: inline-flex; |
|||
align-items: center; |
|||
justify-content: center; |
|||
} |
|||
|
|||
@ -1,38 +1,37 @@ |
|||
<!DOCTYPE html> |
|||
<html> |
|||
|
|||
<head> |
|||
<title>CryptPad</title> |
|||
<meta content="text/html; charset=utf-8" http-equiv="content-type"/> |
|||
<meta content="text/html; charset=utf-8" http-equiv="content-type" /> |
|||
<meta name="viewport" content="width=device-width, initial-scale=1.0"> |
|||
<meta name="referrer" content="no-referrer" /> |
|||
<script async data-bootload="main.js" data-main="/common/boot.js?ver=1.0" src="/bower_components/requirejs/require.js?ver=2.3.5"></script> |
|||
<script async data-bootload="/common/sframe-app-outer.js" data-main="/common/boot.js?ver=1.0" src="/bower_components/requirejs/require.js?ver=2.3.5"></script> |
|||
<style> |
|||
html, body { |
|||
html, |
|||
body { |
|||
margin: 0px; |
|||
padding: 0px; |
|||
} |
|||
|
|||
#sbox-iframe { |
|||
position:fixed; |
|||
top:0px; |
|||
left:0px; |
|||
bottom:0px; |
|||
right:0px; |
|||
width:100%; |
|||
height:100%; |
|||
border:none; |
|||
margin:0; |
|||
padding:0; |
|||
overflow:hidden; |
|||
} |
|||
#sbox-filePicker-iframe { |
|||
position: fixed; |
|||
top:0; left:0; |
|||
bottom:0; right:0; |
|||
width:100%; |
|||
top: 0px; |
|||
left: 0px; |
|||
bottom: 0px; |
|||
right: 0px; |
|||
width: 100%; |
|||
height: 100%; |
|||
border: 0; |
|||
border: none; |
|||
margin: 0; |
|||
padding: 0; |
|||
overflow: hidden; |
|||
} |
|||
</style> |
|||
</head> |
|||
|
|||
<body> |
|||
<iframe id="sbox-iframe"> |
|||
<iframe id="sbox-iframe"> |
|||
</iframe> |
|||
</body> |
|||
</html> |
|||
@ -1,43 +1,23 @@ |
|||
<!DOCTYPE html> |
|||
<html class="cp-app-noscroll"> |
|||
|
|||
<head> |
|||
<meta name="viewport" content="width=device-width, initial-scale=1.0"/> |
|||
<meta content="text/html; charset=utf-8" http-equiv="content-type"/> |
|||
<meta content="text/html; charset=utf-8" http-equiv="content-type" /> |
|||
<script async data-bootload="/kanban/inner.js" data-main="/common/sframe-boot.js?ver=1.6" src="/bower_components/requirejs/require.js?ver=2.3.5"></script> |
|||
<style> |
|||
.loading-hidden { display: none; } |
|||
#editor1 { display: none; } |
|||
html, body { |
|||
width: 100%; |
|||
height: 100%; |
|||
margin: 0px; |
|||
padding: 0px; |
|||
border: 0px; |
|||
} |
|||
margin: 0; |
|||
padding: 0; |
|||
} |
|||
|
|||
#myKanban { |
|||
overflow-x: auto; |
|||
padding: 20px 0; |
|||
} |
|||
|
|||
.success { |
|||
background: #00B961; |
|||
} |
|||
|
|||
.info { |
|||
background: #2A92BF; |
|||
} |
|||
|
|||
.warning { |
|||
background: #F4CE46; |
|||
} |
|||
|
|||
.error { |
|||
background: #FB7D44; |
|||
.loading-hidden { |
|||
display: none; |
|||
} |
|||
</style> |
|||
</head> |
|||
|
|||
<body class="cp-app-kanban"> |
|||
<div id="cme_toolbox" class="cp-toolbar-container"></div> |
|||
<div id="cp-app-kanban-editor"> |
|||
<div id="cp-app-kanban-container"> |
|||
<div id="cp-app-kanban-content"></div> |
|||
</div> |
|||
</div> |
|||
</body> |
|||
|
|||
</html> |
|||
@ -1,627 +1,282 @@ |
|||
define([ |
|||
'jquery', |
|||
'/bower_components/chainpad-crypto/crypto.js', |
|||
'/common/toolbar3.js', |
|||
'json.sortify', |
|||
'/common/common-util.js', |
|||
'/bower_components/nthen/index.js', |
|||
'/common/sframe-common.js', |
|||
'/common/common-interface.js', |
|||
'/api/config', |
|||
'/common/common-realtime.js', |
|||
'/customize/pages.js', |
|||
'/common/sframe-app-framework.js', |
|||
'/common/common-util.js', |
|||
'/common/common-hash.js', |
|||
'/common/modes.js', |
|||
'/customize/messages.js', |
|||
'/customize/application_config.js', |
|||
'/common/common-thumbnail.js', |
|||
'/bower_components/chainpad/chainpad.dist.js', |
|||
|
|||
'/bower_components/secure-fabric.js/dist/fabric.min.js', |
|||
'/bower_components/file-saver/FileSaver.min.js', |
|||
|
|||
'css!/bower_components/bootstrap/dist/css/bootstrap.min.css', |
|||
'less!/bower_components/components-font-awesome/css/font-awesome.min.css', |
|||
'less!/customize/src/less2/main.less', |
|||
'css!/kanban/jkanban.css', |
|||
'/kanban/jkanban.js', |
|||
'css!/kanban/jkanban.css', |
|||
], function ( |
|||
$, |
|||
Crypto, |
|||
Toolbar, |
|||
JSONSortify, |
|||
Util, |
|||
nThen, |
|||
SFCommon, |
|||
UI, |
|||
ApiConfig, |
|||
CommonRealtime, |
|||
Pages, |
|||
Messages, |
|||
AppConfig, |
|||
Thumb, |
|||
ChainPad) |
|||
{ |
|||
var saveAs = window.saveAs; |
|||
|
|||
var APP = window.APP = { |
|||
$: $ |
|||
}; |
|||
var Fabric = APP.Fabric = window.fabric; |
|||
|
|||
var stringify = function (obj) { |
|||
return JSONSortify(obj); |
|||
}; |
|||
|
|||
var toolbar; |
|||
|
|||
var andThen = function (common) { |
|||
var config = {}; |
|||
/* Initialize Fabric */ |
|||
var canvas = APP.canvas = null; |
|||
var $canvas = $('canvas'); |
|||
var readOnly = false; |
|||
|
|||
var setEditable = function (bool) { |
|||
APP.editable = bool; |
|||
if (readOnly && bool) { return; } |
|||
}; |
|||
|
|||
var saveImage = APP.saveImage = function () { |
|||
}; |
|||
|
|||
APP.FM = common.createFileManager({}); |
|||
APP.upload = function (title) { |
|||
}; |
|||
|
|||
var initializing = true; |
|||
var $bar = $('#cp-toolbar'); |
|||
var Title; |
|||
var cpNfInner; |
|||
var metadataMgr; |
|||
|
|||
config = { |
|||
readOnly: readOnly, |
|||
patchTransformer: ChainPad.NaiveJSONTransformer, |
|||
// cryptpad debug logging (default is 1)
|
|||
// logLevel: 0,
|
|||
validateContent: function (content) { |
|||
try { |
|||
JSON.parse(content); |
|||
return true; |
|||
} catch (e) { |
|||
console.log("Failed to parse, rejecting patch"); |
|||
return true; |
|||
} |
|||
} |
|||
}; |
|||
|
|||
var stringifyInner = function (textValue) { |
|||
var obj = { |
|||
content: textValue, |
|||
metadata: metadataMgr.getMetadataLazy() |
|||
}; |
|||
// stringify the json and send it into chainpad
|
|||
return stringify(obj); |
|||
}; |
|||
|
|||
var onLocal = config.onLocal = function () { |
|||
if (initializing) { return; } |
|||
if (readOnly) { return; } |
|||
|
|||
var content = stringifyInner(Kanban.getBoardsJSON()); |
|||
console.log("Updating content " + content); |
|||
|
|||
try { |
|||
APP.realtime.contentUpdate(content); |
|||
} catch (e) { |
|||
APP.unrecoverable = true; |
|||
setEditable(false); |
|||
APP.toolbar.errorState(true, e.message); |
|||
var msg = Messages.chainpadError; |
|||
UI.errorLoadingScreen(msg, true, true); |
|||
console.error(e); |
|||
} |
|||
}; |
|||
|
|||
var initThumbnails = function () { |
|||
var oldThumbnailState; |
|||
var privateDat = metadataMgr.getPrivateData(); |
|||
if (!privateDat.thumbnails) { return; } |
|||
var hash = privateDat.availableHashes.editHash || |
|||
privateDat.availableHashes.viewHash; |
|||
var href = privateDat.pathname + '#' + hash; |
|||
var mkThumbnail = function () { |
|||
if (!hash) { return; } |
|||
if (initializing) { return; } |
|||
if (!APP.realtime) { return; } |
|||
var content = APP.realtime.getUserDoc(); |
|||
if (content === oldThumbnailState) { return; } |
|||
/* |
|||
var D = Thumb.getResizedDimensions($canvas[0], 'pad'); |
|||
Thumb.fromCanvas($canvas[0], D, function (err, b64) { |
|||
oldThumbnailState = content; |
|||
Thumb.setPadThumbnail(common, href, b64); |
|||
}); |
|||
*/ |
|||
}; |
|||
window.setInterval(mkThumbnail, Thumb.UPDATE_INTERVAL); |
|||
window.setTimeout(mkThumbnail, Thumb.UPDATE_FIRST); |
|||
}; |
|||
|
|||
config.onInit = function (info) { |
|||
readOnly = metadataMgr.getPrivateData().readOnly; |
|||
|
|||
Title = common.createTitle({}); |
|||
|
|||
var configTb = { |
|||
displayed: [ |
|||
'userlist', |
|||
'title', |
|||
'useradmin', |
|||
'spinner', |
|||
'newpad', |
|||
'share', |
|||
'limit', |
|||
'unpinnedWarning' |
|||
], |
|||
title: Title.getTitleConfig(), |
|||
metadataMgr: metadataMgr, |
|||
readOnly: readOnly, |
|||
realtime: info.realtime, |
|||
sfCommon: common, |
|||
$container: $bar, |
|||
$contentContainer: $('#cp-app-kanban-content') |
|||
}; |
|||
toolbar = APP.toolbar = Toolbar.create(configTb); |
|||
Title.setToolbar(toolbar); |
|||
|
|||
var $rightside = toolbar.$rightside; |
|||
var $drawer = toolbar.$drawer; |
|||
|
|||
/* save as template */ |
|||
if (!metadataMgr.getPrivateData().isTemplate) { |
|||
var templateObj = { |
|||
rt: info.realtime, |
|||
getTitle: function () { return metadataMgr.getMetadata().title; } |
|||
}; |
|||
var $templateButton = common.createButton('template', true, templateObj); |
|||
$rightside.append($templateButton); |
|||
} |
|||
|
|||
/* add an export button */ |
|||
var $export = common.createButton('export', true, {}, saveImage); |
|||
$drawer.append($export); |
|||
|
|||
if (common.isLoggedIn()) { |
|||
common.createButton('savetodrive', true, {}, function () {}) |
|||
.click(function () { |
|||
UI.prompt(Messages.exportPrompt, document.title + '.png', |
|||
function (name) { |
|||
if (name === null || !name.trim()) { return; } |
|||
APP.upload(name); |
|||
}); |
|||
}).appendTo($rightside); |
|||
|
|||
common.createButton('hashtag', true).appendTo($rightside); |
|||
} |
|||
|
|||
var $forget = common.createButton('forget', true, {}, function (err) { |
|||
if (err) { return; } |
|||
setEditable(false); |
|||
}); |
|||
$rightside.append($forget); |
|||
|
|||
var $properties = common.createButton('properties', true); |
|||
toolbar.$drawer.append($properties); |
|||
|
|||
var $appContainer = $('#cp-app-kanban-container'); |
|||
var helpMenu = common.createHelpMenu(['kanban']); |
|||
$appContainer.prepend(helpMenu.menu); |
|||
toolbar.$drawer.append(helpMenu.button); |
|||
|
|||
metadataMgr.onChange(function () { |
|||
var md = metadataMgr.getMetadata(); |
|||
}); |
|||
|
|||
}; |
|||
|
|||
config.onReady = function (info) { |
|||
if (APP.realtime !== info.realtime) { |
|||
APP.realtime = info.realtime; |
|||
} |
|||
|
|||
var userDoc = APP.realtime.getUserDoc(); |
|||
var isNew = false; |
|||
var newDoc = ''; |
|||
if (userDoc === "" || userDoc === "{}") { isNew = true; } |
|||
|
|||
if (userDoc !== "") { |
|||
var hjson = JSON.parse(userDoc); |
|||
|
|||
if (hjson && hjson.metadata) { |
|||
metadataMgr.updateMetadata(hjson.metadata); |
|||
} |
|||
if (typeof (hjson) !== 'object' || Array.isArray(hjson) || |
|||
(hjson.metadata && typeof(hjson.metadata.type) !== 'undefined' && |
|||
hjson.metadata.type !== 'kanban')) { |
|||
var errorText = Messages.typeError; |
|||
UI.errorLoadingScreen(errorText); |
|||
throw new Error(errorText); |
|||
} |
|||
newDoc = hjson.content; |
|||
|
|||
// launch the kanban code
|
|||
config.initKanban(newDoc); |
|||
|
|||
} else { |
|||
Title.updateTitle(Title.defaultTitle); |
|||
config.initKanban(); |
|||
} |
|||
|
|||
nThen(function (waitFor) { |
|||
if (newDoc) { |
|||
} |
|||
}).nThen(function () { |
|||
setEditable(!readOnly); |
|||
initializing = false; |
|||
config.onLocal(); |
|||
UI.removeLoadingScreen(); |
|||
|
|||
initThumbnails(); |
|||
|
|||
|
|||
if (readOnly) { return; } |
|||
|
|||
var privateDat = metadataMgr.getPrivateData(); |
|||
var skipTemp = Util.find(privateDat, |
|||
['settings', 'general', 'creation', 'noTemplate']); |
|||
var skipCreation = Util.find(privateDat, ['settings', 'general', 'creation', 'skip']); |
|||
if (isNew && (!AppConfig.displayCreationScreen || (!skipTemp && skipCreation))) { |
|||
common.openTemplatePicker(); |
|||
} |
|||
}); |
|||
}; |
|||
|
|||
config.onRemote = function () { |
|||
if (initializing) { return; } |
|||
var userDoc = APP.realtime.getUserDoc(); |
|||
|
|||
console.log("Received content: " + userDoc); |
|||
|
|||
var json = JSON.parse(userDoc); |
|||
var remoteDoc = json.content; |
|||
|
|||
var currentContent = stringify(Kanban.getBoardsJSON()); |
|||
var remoteContent = stringify(json.content); |
|||
|
|||
|
|||
if (currentContent !== remoteContent) { |
|||
// reinit kanban (TODO: optimize to diff only)
|
|||
console.log("Content is different.. Applying content"); |
|||
config.Kanban.setBoards(remoteDoc); |
|||
common.notify(); |
|||
} |
|||
if (readOnly) { setEditable(false); } |
|||
}; |
|||
|
|||
config.onAbort = function () { |
|||
if (APP.unrecoverable) { return; } |
|||
// inform of network disconnect
|
|||
setEditable(false); |
|||
toolbar.failed(); |
|||
UI.alert(Messages.common_connectionLost, undefined, true); |
|||
}; |
|||
|
|||
config.onConnectionChange = function (info) { |
|||
if (APP.unrecoverable) { return; } |
|||
setEditable(info.state); |
|||
if (info.state) { |
|||
initializing = true; |
|||
//UI.findOKButton().click();
|
|||
} else { |
|||
//UI.alert(Messages.common_connectionLost, undefined, true);
|
|||
} |
|||
}; |
|||
|
|||
config.onError = function (err) { |
|||
common.onServerError(err, toolbar, function () { |
|||
APP.unrecoverable = true; |
|||
setEditable(false); |
|||
}); |
|||
}; |
|||
|
|||
config.initKanban = function(boards) { |
|||
var defaultBoards = [ |
|||
{ |
|||
"id": "todo", |
|||
"title": "To Do", |
|||
"color": "blue", |
|||
"item": [ |
|||
{ |
|||
"title": "Item 1" |
|||
}, |
|||
{ |
|||
"title": "Item 2" |
|||
} |
|||
Framework, |
|||
Util, |
|||
Hash, |
|||
Modes, |
|||
Messages) { |
|||
|
|||
// Kanban code
|
|||
var initKanban = function (framework, boards) { |
|||
var defaultBoards = [ |
|||
{ |
|||
"id": "todo", |
|||
"title": "To Do", |
|||
"color": "blue", |
|||
"item": [ |
|||
{ |
|||
"title": "Item 1" |
|||
}, |
|||
{ |
|||
"title": "Item 2" |
|||
} |
|||
] |
|||
}, |
|||
{ |
|||
"id": "working", |
|||
"title": "Working", |
|||
"color": "orange", |
|||
"item": [ |
|||
{ |
|||
"title": "Item 3", |
|||
{ |
|||
"id": "working", |
|||
"title": "Working", |
|||
"color": "orange", |
|||
"item": [ |
|||
{ |
|||
"title": "Item 3", |
|||
}, |
|||
{ |
|||
"title": "Item 4", |
|||
{ |
|||
"title": "Item 4", |
|||
} |
|||
] |
|||
}, |
|||
{ |
|||
"id": "done", |
|||
"title": "Done", |
|||
"color": "green", |
|||
"item": [ |
|||
{ |
|||
"title": "Item 5", |
|||
{ |
|||
"id": "done", |
|||
"title": "Done", |
|||
"color": "green", |
|||
"item": [ |
|||
{ |
|||
"title": "Item 5", |
|||
}, |
|||
{ |
|||
"title": "Item 6", |
|||
{ |
|||
"title": "Item 6", |
|||
} |
|||
] |
|||
}]; |
|||
|
|||
if (boards==null) { |
|||
console.log("Initializing with default boards content"); |
|||
boards = defaultBoards; |
|||
} else { |
|||
console.log("Initializing with boards content " + boards); |
|||
} |
|||
|
|||
// Remove any existing elements
|
|||
$(".kanban-container-outer").remove(); |
|||
|
|||
window.Kanban = config.Kanban = new jKanban({ |
|||
element: '#cp-app-kanban-content', |
|||
gutter: '15px', |
|||
widthBoard: '300px', |
|||
onChange: function() { |
|||
console.log("Board object has changed"); |
|||
config.onLocal(); |
|||
} |
|||
,click: function (el) { |
|||
if (Kanban.inEditMode) { |
|||
console.log("An edit is already active"); |
|||
return; |
|||
} |
|||
Kanban.inEditMode = true; |
|||
var name = $(el).text(); |
|||
$(el).html(''); |
|||
$('<input></input>') |
|||
.attr({ |
|||
'type': 'text', |
|||
'name': 'text', |
|||
'id': 'kanban_edit', |
|||
'size': '30', |
|||
'value': name |
|||
}) |
|||
.appendTo(el); |
|||
$('#kanban_edit').focus(); |
|||
$('#kanban_edit').blur(function() { |
|||
var name = $('#kanban_edit').val(); |
|||
$(el).text(name); |
|||
var board = $(el.parentNode.parentNode).attr("data-id"); |
|||
var pos = Kanban.findElementPosition(el); |
|||
console.log(pos); |
|||
console.log(board); |
|||
Kanban.getBoardJSON(board).item[pos].title = name; |
|||
Kanban.onChange(); |
|||
Kanban.inEditMode = false; |
|||
}); |
|||
|
|||
}, |
|||
boardTitleClick: function (el) { |
|||
if (Kanban.inEditMode) { |
|||
console.log("An edit is already active"); |
|||
return; |
|||
} |
|||
Kanban.inEditMode = true; |
|||
var name = $(el).text(); |
|||
$(el).html(''); |
|||
$('<input></input>') |
|||
.attr({ |
|||
'type': 'text', |
|||
'name': 'text', |
|||
'id': 'kanban_edit', |
|||
'size': '30', |
|||
'value': name |
|||
}) |
|||
.appendTo(el); |
|||
$('#kanban_edit').focus(); |
|||
$('#kanban_edit').blur(function() { |
|||
var name = $('#kanban_edit').val(); |
|||
$(el).text(name); |
|||
var board = $(el.parentNode.parentNode).attr("data-id"); |
|||
Kanban.getBoardJSON(board).title = name; |
|||
Kanban.onChange(); |
|||
Kanban.inEditMode = false; |
|||
}); |
|||
if (boards == null) { |
|||
console.log("Initializing with default boards content"); |
|||
boards = defaultBoards; |
|||
} else { |
|||
console.log("Initializing with boards content " + boards); |
|||
} |
|||
|
|||
}, |
|||
colorClick: function (el, boardId) { |
|||
console.log("in color click"); |
|||
var board = $(el.parentNode).attr("data-id"); |
|||
var boardJSON = Kanban.getBoardJSON(board); |
|||
var currentColor = boardJSON.color; |
|||
console.log("Current color " + currentColor); |
|||
var index = Kanban.options.colors.findIndex(function(element) { return (element==currentColor) }) + 1; |
|||
console.log("Next index " + index); |
|||
if (index>=Kanban.options.colors.length) |
|||
index = 0; |
|||
var nextColor = Kanban.options.colors[index]; |
|||
console.log("Next color " + nextColor); |
|||
boardJSON.color = nextColor; |
|||
$(el).removeClass("kanban-header-" + currentColor); |
|||
$(el).addClass("kanban-header-" + nextColor); |
|||
Kanban.onChange(); |
|||
|
|||
}, |
|||
removeClick: function(el, boardId) { |
|||
if (confirm("Do you want to delete this board?")) { |
|||
console.log("Delete board"); |
|||
var boardName = $(el.parentNode.parentNode).attr("data-id"); |
|||
for (index in Kanban.options.boards) { |
|||
if (Kanban.options.boards[index].id == boardName) { |
|||
break; |
|||
} |
|||
index++; |
|||
} |
|||
Kanban.options.boards.splice(index, 1); |
|||
Kanban.removeBoard(boardName); |
|||
Kanban.onChange(); |
|||
} |
|||
}, |
|||
buttonClick: function (el, boardId) { |
|||
console.log(el); |
|||
console.log(boardId); |
|||
// create a form to enter element
|
|||
var formItem = document.createElement('form'); |
|||
formItem.setAttribute("class", "itemform"); |
|||
formItem.innerHTML = '<div class="form-group"><textarea class="form-control" rows="2" autofocus></textarea></div><div class="form-group"><button type="submit" class="btn btn-primary btn-xs">Submit</button><button type="button" id="CancelBtn" class="btn btn-default btn-xs pull-right">Cancel</button></div>' |
|||
// Remove any existing elements
|
|||
$(".kanban-container-outer").remove(); |
|||
|
|||
var kanban = new jKanban({ |
|||
element: '#cp-app-kanban-content', |
|||
gutter: '15px', |
|||
widthBoard: '300px', |
|||
onChange: function () { |
|||
console.log("Board object has changed"); |
|||
framework.localChange(); |
|||
}, |
|||
click: function (el) { |
|||
if (kanban.inEditMode) { |
|||
console.log("An edit is already active"); |
|||
return; |
|||
} |
|||
kanban.inEditMode = true; |
|||
var name = $(el).text(); |
|||
$(el).html(''); |
|||
$('<input></input>') |
|||
.attr({ |
|||
'type': 'text', |
|||
'name': 'text', |
|||
'id': 'kanban_edit', |
|||
'size': '30', |
|||
'value': name |
|||
}) |
|||
.appendTo(el); |
|||
$('#kanban_edit').focus(); |
|||
$('#kanban_edit').blur(function () { |
|||
var name = $('#kanban_edit').val(); |
|||
$(el).text(name); |
|||
var board = $(el.parentNode.parentNode).attr("data-id"); |
|||
var pos = kanban.findElementPosition(el); |
|||
console.log(pos); |
|||
console.log(board); |
|||
kanban.getBoardJSON(board).item[pos].title = name; |
|||
kanban.onChange(); |
|||
kanban.inEditMode = false; |
|||
}); |
|||
|
|||
Kanban.addForm(boardId, formItem); |
|||
formItem.addEventListener("submit", function (e) { |
|||
e.preventDefault(); |
|||
var text = e.target[0].value |
|||
Kanban.addElement(boardId, { |
|||
"title": text, |
|||
}) |
|||
formItem.parentNode.removeChild(formItem); |
|||
}); |
|||
document.getElementById('CancelBtn').onclick = function () { |
|||
formItem.parentNode.removeChild(formItem) |
|||
} |
|||
}, |
|||
addItemButton: true, |
|||
boards: boards |
|||
}); |
|||
}, |
|||
boardTitleClick: function (el) { |
|||
if (kanban.inEditMode) { |
|||
console.log("An edit is already active"); |
|||
return; |
|||
} |
|||
kanban.inEditMode = true; |
|||
var name = $(el).text(); |
|||
$(el).html(''); |
|||
$('<input></input>') |
|||
.attr({ |
|||
'type': 'text', |
|||
'name': 'text', |
|||
'id': 'kanban_edit', |
|||
'size': '30', |
|||
'value': name |
|||
}) |
|||
.appendTo(el); |
|||
$('#kanban_edit').focus(); |
|||
$('#kanban_edit').blur(function () { |
|||
var name = $('#kanban_edit').val(); |
|||
$(el).text(name); |
|||
var board = $(el.parentNode.parentNode).attr("data-id"); |
|||
kanban.getBoardJSON(board).title = name; |
|||
kanban.onChange(); |
|||
kanban.inEditMode = false; |
|||
}); |
|||
|
|||
var addBoardDefault = document.getElementById('kanban-addboard'); |
|||
addBoardDefault.addEventListener('click', function () { |
|||
var counter = 1; |
|||
found = false; |
|||
while (found) { |
|||
for (var board in Kanban.options.boards) { |
|||
if (board.id == "board" + counter) { |
|||
counter++; |
|||
break; |
|||
} |
|||
} |
|||
found = true; |
|||
} |
|||
}, |
|||
colorClick: function (el, boardId) { |
|||
console.log("in color click"); |
|||
var board = $(el.parentNode).attr("data-id"); |
|||
var boardJSON = kanban.getBoardJSON(board); |
|||
var currentColor = boardJSON.color; |
|||
console.log("Current color " + currentColor); |
|||
var index = kanban.options.colors.findIndex(function (element) { |
|||
return (element == currentColor) |
|||
}) + 1; |
|||
console.log("Next index " + index); |
|||
if (index >= kanban.options.colors.length) |
|||
index = 0; |
|||
var nextColor = kanban.options.colors[index]; |
|||
console.log("Next color " + nextColor); |
|||
boardJSON.color = nextColor; |
|||
$(el).removeClass("kanban-header-" + currentColor); |
|||
$(el).addClass("kanban-header-" + nextColor); |
|||
kanban.onChange(); |
|||
|
|||
}, |
|||
removeClick: function (el, boardId) { |
|||
if (confirm("Do you want to delete this board?")) { |
|||
console.log("Delete board"); |
|||
var boardName = $(el.parentNode.parentNode).attr("data-id"); |
|||
for (index in kanban.options.boards) { |
|||
if (kanban.options.boards[index].id == boardName) { |
|||
break; |
|||
} |
|||
index++; |
|||
} |
|||
kanban.options.boards.splice(index, 1); |
|||
kanban.removeBoard(boardName); |
|||
kanban.onChange(); |
|||
} |
|||
}, |
|||
buttonClick: function (el, boardId) { |
|||
console.log(el); |
|||
console.log(boardId); |
|||
// create a form to enter element
|
|||
var formItem = document.createElement('form'); |
|||
formItem.setAttribute("class", "itemform"); |
|||
formItem.innerHTML = '<div class="form-group"><textarea class="form-control" rows="2" autofocus></textarea></div><div class="form-group"><button type="submit" class="btn btn-primary btn-xs">Submit</button><button type="button" id="CancelBtn" class="btn btn-default btn-xs pull-right">Cancel</button></div>' |
|||
|
|||
kanban.addForm(boardId, formItem); |
|||
formItem.addEventListener("submit", function (e) { |
|||
e.preventDefault(); |
|||
var text = e.target[0].value |
|||
kanban.addElement(boardId, { |
|||
"title": text, |
|||
}) |
|||
formItem.parentNode.removeChild(formItem); |
|||
}); |
|||
document.getElementById('CancelBtn').onclick = function () { |
|||
formItem.parentNode.removeChild(formItem) |
|||
} |
|||
}, |
|||
addItemButton: true, |
|||
boards: boards |
|||
}); |
|||
|
|||
Kanban.addBoards( |
|||
[{ |
|||
"id" : "board" + counter, |
|||
"title": "New Board", |
|||
"color": "yellow", |
|||
"item": [ |
|||
{ |
|||
"title": "Item 1", |
|||
} |
|||
] |
|||
}] |
|||
) |
|||
Kanban.onChange(); |
|||
}); |
|||
|
|||
/* |
|||
var toDoButton = document.getElementById('addToDo'); |
|||
toDoButton.addEventListener('click', function () { |
|||
Kanban.addElement( |
|||
"_todo", |
|||
{ |
|||
"title": "Test Add", |
|||
} |
|||
); |
|||
}); |
|||
var addBoardDefault = document.getElementById('kanban-addboard'); |
|||
addBoardDefault.addEventListener('click', function () { |
|||
var counter = 1; |
|||
found = false; |
|||
while (found) { |
|||
for (var board in kanban.options.boards) { |
|||
if (board.id == "board" + counter) { |
|||
counter++; |
|||
break; |
|||
} |
|||
} |
|||
found = true; |
|||
} |
|||
|
|||
var addBoardDefault = document.getElementById('addDefault'); |
|||
addBoardDefault.addEventListener('click', function () { |
|||
Kanban.addBoards( |
|||
kanban.addBoards( |
|||
[{ |
|||
"id": "_default", |
|||
"title": "Kanban Default", |
|||
"item": [ |
|||
{ |
|||
"title": "Default Item", |
|||
}, |
|||
{ |
|||
"title": "Default Item 2", |
|||
}, |
|||
{ |
|||
"title": "Default Item 3", |
|||
"id": "board" + counter, |
|||
"title": "New Board", |
|||
"color": "yellow", |
|||
"item": [ |
|||
{ |
|||
"title": "Item 1", |
|||
} |
|||
] |
|||
}] |
|||
) |
|||
}); |
|||
|
|||
var removeBoard = document.getElementById('removeBoard'); |
|||
removeBoard.addEventListener('click', function () { |
|||
Kanban.removeBoard('_done'); |
|||
}); |
|||
) |
|||
kanban.onChange(); |
|||
}); |
|||
|
|||
var removeElement = document.getElementById('removeElement'); |
|||
removeElement.addEventListener('click', function () { |
|||
Kanban.removeElement('_test_delete'); |
|||
}); |
|||
return kanban; |
|||
}; |
|||
|
|||
var allEle = Kanban.getBoardElements('_todo'); |
|||
allEle.forEach(function (item, index) { |
|||
//console.log(item);
|
|||
}); |
|||
*/ |
|||
}; |
|||
// Start of the main loop
|
|||
var andThen2 = function (framework) { |
|||
|
|||
cpNfInner = common.startRealtime(config); |
|||
metadataMgr = cpNfInner.metadataMgr; |
|||
var kanban = initKanban(framework); |
|||
|
|||
cpNfInner.onInfiniteSpinner(function () { |
|||
if (APP.unrecoverable) { return; } |
|||
setEditable(false); |
|||
UI.confirm(Messages.realtime_unrecoverableError, function (yes) { |
|||
if (!yes) { return; } |
|||
common.gotoURL(); |
|||
}); |
|||
framework.onContentUpdate(function (newContent) { |
|||
// Need to update the content
|
|||
console.log("Content should be updated to " + newContent); |
|||
var currentContent = kanban.getBoardsJSON(); |
|||
var remoteContent = newContent.content; |
|||
|
|||
if (currentContent !== remoteContent) { |
|||
// reinit kanban (TODO: optimize to diff only)
|
|||
console.log("Content is different.. Applying content"); |
|||
kanban.setBoards(remoteContent); |
|||
} |
|||
}); |
|||
|
|||
$('#save').on('click', function () { |
|||
framework.setContentGetter(function () { |
|||
// var content = $("#cp-app-kanban-content").val();
|
|||
var content = kanban.getBoardsJSON(); |
|||
console.log("Content current value is " + content); |
|||
return { |
|||
content: content |
|||
}; |
|||
}); |
|||
|
|||
framework.onReady(function (newPad) { |
|||
$("#cp-app-kanban-content").focus(); |
|||
}); |
|||
|
|||
common.onLogout(function () { setEditable(false); }); |
|||
framework.start(); |
|||
}; |
|||
|
|||
|
|||
|
|||
var main = function () { |
|||
var common; |
|||
|
|||
// var framework;
|
|||
nThen(function (waitFor) { |
|||
$(waitFor(function () { |
|||
UI.addLoadingScreen(); |
|||
var $div = $('<div>').append(Pages['/kanban/']()); |
|||
$('body').append($div.html()); |
|||
$('body').addClass("cp-app-kanban"); |
|||
|
|||
// Framework initialization
|
|||
Framework.create({ |
|||
toolbarContainer: '#cme_toolbox', |
|||
contentContainer: '#cp-app-kanban-editor', |
|||
}, waitFor(function (fw) { |
|||
framework = fw; |
|||
andThen2(framework); |
|||
})); |
|||
SFCommon.create(waitFor(function (c) { APP.common = common = c; })); |
|||
}).nThen(function (waitFor) { |
|||
common.getSframeChannel().onReady(waitFor()); |
|||
}).nThen(function (waitFor) { |
|||
common.handleNewFile(waitFor); |
|||
}).nThen(function (/*waitFor*/) { |
|||
andThen(common); |
|||
}); |
|||
}; |
|||
main(); |
|||
|
|||
2774
www/kanban/jkanban.js
File diff suppressed because it is too large
View File
File diff suppressed because it is too large
View File
@ -1,25 +0,0 @@ |
|||
html, body { |
|||
margin: 0px; |
|||
padding: 0px; |
|||
} |
|||
#sbox-iframe { |
|||
position:fixed; |
|||
top:0px; |
|||
left:0px; |
|||
bottom:0px; |
|||
right:0px; |
|||
width:100%; |
|||
height:100%; |
|||
border:none; |
|||
margin:0; |
|||
padding:0; |
|||
overflow:hidden; |
|||
} |
|||
#sbox-filePicker-iframe { |
|||
position: fixed; |
|||
top:0; left:0; |
|||
bottom:0; right:0; |
|||
width:100%; |
|||
height: 100%; |
|||
border: 0; |
|||
} |
|||
@ -1,43 +0,0 @@ |
|||
// Load #1, load as little as possible because we are in a race to get the loading screen up.
|
|||
define([ |
|||
'/bower_components/nthen/index.js', |
|||
'/api/config', |
|||
'/common/dom-ready.js', |
|||
'/common/requireconfig.js', |
|||
'/common/sframe-common-outer.js', |
|||
], function (nThen, ApiConfig, DomReady, RequireConfig, SFCommonO) { |
|||
var requireConfig = RequireConfig(); |
|||
|
|||
// Loaded in load #2
|
|||
nThen(function (waitFor) { |
|||
DomReady.onReady(waitFor()); |
|||
}).nThen(function (waitFor) { |
|||
var req = { |
|||
cfg: requireConfig, |
|||
req: [ '/common/loading.js' ], |
|||
pfx: window.location.origin |
|||
}; |
|||
window.rc = requireConfig; |
|||
window.apiconf = ApiConfig; |
|||
document.getElementById('sbox-iframe').setAttribute('src', |
|||
ApiConfig.httpSafeOrigin + '/kanban/inner.html?' + requireConfig.urlArgs + |
|||
'#' + encodeURIComponent(JSON.stringify(req))); |
|||
|
|||
// This is a cheap trick to avoid loading sframe-channel in parallel with the
|
|||
// loading screen setup.
|
|||
var done = waitFor(); |
|||
var onMsg = function (msg) { |
|||
var data = JSON.parse(msg.data); |
|||
if (data.q !== 'READY') { return; } |
|||
window.removeEventListener('message', onMsg); |
|||
var _done = done; |
|||
done = function () { }; |
|||
_done(); |
|||
}; |
|||
window.addEventListener('message', onMsg); |
|||
}).nThen(function (/*waitFor*/) { |
|||
SFCommonO.start({ |
|||
useCreationScreen: true |
|||
}); |
|||
}); |
|||
}); |
|||
Write
Preview
Loading…
Cancel
Save