diff --git a/www/common/metadata-manager.js b/www/common/metadata-manager.js index 1c8994d00..e319c3ecb 100644 --- a/www/common/metadata-manager.js +++ b/www/common/metadata-manager.js @@ -68,6 +68,7 @@ define(['json.sortify'], function (Sortify) { }; var change = function (lazy) { dirty = true; + console.error('METADATA CHANGE CALLED'); setTimeout(function () { checkUpdate(lazy); }); diff --git a/www/common/sframe-common-title.js b/www/common/sframe-common-title.js index f07da43fa..b716c090e 100644 --- a/www/common/sframe-common-title.js +++ b/www/common/sframe-common-title.js @@ -17,6 +17,7 @@ define(['jquery'], function ($) { var $title; exp.setToolbar = function (toolbar) { $title = toolbar && (toolbar.title || toolbar.pageTitle); + console.log('SET TOOLBAR'); }; exp.getTitle = function () { return exp.title; }; @@ -40,6 +41,7 @@ define(['jquery'], function ($) { }; metadataMgr.onChange(function () { + console.error('METADATA CHANGE'); var md = metadataMgr.getMetadata(); if ($title) { $title.find('span.cp-toolbar-title-value').text(md.title || md.defaultTitle); diff --git a/www/poll/app-drive.less b/www/poll/app-drive.less deleted file mode 100644 index ea027d76e..000000000 --- a/www/poll/app-drive.less +++ /dev/null @@ -1,820 +0,0 @@ -@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/leftside-menu.less'; -@import (once) "../../customize/src/less2/include/tools.less"; -@import (once) "../../customize/src/less2/include/limit-bar.less"; - -.toolbar_main(); -.fileupload_main(); -.alertify_main(); -.limit-bar_main(); - -@drive_hover: #eee; -@drive_hover-light: lighten(@drive_hover, 20%); -@drive_info-box-bg: #d2e1f2; -@drive_info-box-border: #bbb; -@drive_table-header-fg: #555; -@drive_table-header-bg: #e8e8e8; -@drive_mobile-tree-border-col: #ccc; - -@drive_content-fg: @colortheme_sidebar-right-fg; -@drive_content-bg: @colortheme_sidebar-right-bg; -@drive_content-bg-ro: darken(@drive_content-bg, 10%); - - -/* PAGE */ - -display: flex; -flex-flow: column; -max-height: 100%; -min-height: auto; - -.cp-unselectable { - .tools_unselectable(); -} - -/* local mixins */ -.drive_fileIcon { - li { - display: inline-block; - margin: 10px 10px; - width: 140px; - height: 140px; - text-align: center; - vertical-align: top; - overflow: hidden; - text-overflow: ellipsis; - padding-top: 5px; - padding-bottom: 5px; - - &:not(.cp-app-drive-element-selected):not(.cp-app-drive-element-selected-tmp) { - border: 1px solid #CCC; - } - .cp-app-drive-element-name { - width: 100%; - height: 48px; - margin: 8px 0; - display: inline-block; - //align-items: center; - //justify-content: center; - overflow: hidden; - //text-overflow: ellipsis; - word-wrap: break-word; - } - .cp-app-drive-element-truncated { - display: block; - position: absolute; - bottom: 0px; - left: 0; right: 0; - text-align: center; - } - img.cp-app-drive-content-icon { - height: 48px; - max-height: none; - max-width: none; - margin: 8px 0; - } - .fa { - display: block; - margin: auto; - font-size: 48px; - margin: 8px 0; - text-align: center; - &.listonly { - display: none; - } - } - } -} - -img.cp-app-drive-icon { - max-width: 20px; - max-height: 16px; -} - -.cp-app-drive-container { - flex: 1; - overflow: auto; - width: 100%; - display: flex; - flex-flow: row; - @media screen and (max-width: @browser_media-medium-screen) { - display: block; - #cp-app-drive-toolbar { - .path .element { - display: none; - } - } - #cp-app-drive-tree { - resize: none; - width: 100%; - max-width: unset; - max-height: unset; - border-bottom: 1px solid @drive_mobile-tree-border-col; - .cp-app-drive-tree-category { - margin-top: 0.5em; - } - } - } -} - -div:focus { - outline: none; -} - -.fa { - font-family: FontAwesome; -} - -ul { - list-style: none; - padding-left: 0px; // Remove the default padding -} - -li { - padding: 0px 5px; - -webkit-user-select: none; - -moz-user-select: none; - -ms-user-select: none; - user-select: none; -} - -.cp-app-drive-context { - display: none; - position: absolute; - z-index: 500; - li { - padding: 0; - font-size: @colortheme_app-font-size; - a { - cursor: pointer; - } - } -} - -.cp-app-drive-element-droppable { - background-color: #FE9A2E; - color: #222; -} - -.cp-app-drive-element-selected { - background: #666 !important; - color: #eee; - margin: -1px; - .fa-minus-square-o, .fa-plus-square-o { - color: @colortheme_sidebar-left-fg; - } -} - -.cp-app-drive-element-selected-tmp { - border: 1px dotted #bbb; - background: #AAA; - color: #ddd; - margin: -1px; - .fa-minus-square-o, .fa-plus-square-o { - color: @colortheme_sidebar-left-fg; - } -} - -span { - &.fa-folder, &.fa-folder-open { - //color: #FEDE8B; - //text-shadow: -1px 0 black, 0 1px black, 1px 0 black, 0 -1px black; - } -} - -/* TREE */ - - -#cp-app-drive-tree { - font-size: @colortheme_app-font-size; - //border-right: 1px solid #ccc; - box-sizing: border-box; - background: @colortheme_sidebar-left-bg; - overflow: auto; - resize: horizontal; - width: auto; - white-space: nowrap; - max-width: 500px; - min-width: 200px; - padding: 0px; - color: @colortheme_sidebar-left-fg; - display: flex; - flex-flow: column; - max-height: 100%; - .cp-app-drive-tree-categories-container { - flex: 1; - max-width: 500px; - overflow: auto; - } - img.cp-app-drive-icon { - margin-bottom: 3px; - margin-left: -2px; - } - .cp-app-drive-tree-docs { - margin-top: 20px; - //padding: 0 0 0 20px; - padding: 0; - cursor: auto; - &li, li { - padding: 0; - &.cp-app-drive-element-collapsed ul { - display: none; - } - input { - width: ~"calc(100% - 30px)"; - padding: 0 10px; - border: 0; - color: lighten(@colortheme_sidebar-left-fg, 40%); - } - & > span.cp-app-drive-element-row { - overflow: hidden; - text-overflow: ellipsis; - //min-width: ~"calc(100% + 5px)"; - .leftside-menu-category_main(); - width: ~"calc(100% + 5px)"; - margin: 0; - margin-bottom: -6px; - display: inline-block; - cursor: pointer; - margin-left: -5px; - padding-left: 5px; - } - & > span.cp-app-drive-element-row:not(.cp-app-drive-element-selected):not(.cp-app-drive-element-active):hover { - } - } - } - span.cp-app-drive-element { - cursor: pointer; - } - .cp-app-drive-tree-category { - margin: 0; - margin-top: 15px; - .cp-app-drive-tree-root { - &> .fa { - min-width: 30px; - cursor: pointer; - } - } - li { - padding: 0; - .cp-app-drive-element-row { - display: block; - padding-left: 20px; - .leftside-menu-category_main(); - margin: 0; - .fa { - width: 25px; - } - } - } - } - .cp-app-drive-tree-category:last-child { - margin-bottom: 20px; - } - .limit-container { - margin-top: 0; - } - #cp-app-drive-tree-search { - text-align: center; - padding: 0; - position: relative; - input { - background: lighten(@colortheme_drive-bg, 8%); - color: @colortheme_drive-color; - .tools_placeholder-color(@colortheme_drive-color); - outline-width: 0px; - border-radius: 0; - width: 100%; - //border: 1px solid #ccc; - border: 0; - border-right: 1px solid lighten(@colortheme_drive-bg, 16%); - //border-right: 0; - height: @variables_bar-height; - padding: 0 5px; - padding-left: 45px; - &:focus { - outline-width: 0px; - } - } - .cp-app-drive-tree-search-con { - color: @colortheme_drive-color; - position: absolute; - left: 20px; // TODO align with drive categories - top: 8px; - } - } - .fa.cp-app-drive-icon-expcol { - margin-left: -10px; - font-size: 14px; - position: absolute; - left: -20px; - top: 10px; - width: 11px !important; - height: 11px !important; - padding: 0; - margin: 0; - background: white; - z-index: 10; - cursor: default; - &:before { - position:relative; - top: -1px; - } - } - .cp-app-drive-tree-docs { - .cp-app-drive-tree-root > .cp-app-drive-element-row > .cp-app-drive-icon-expcol { - position: relative; - top:0; - left: -10px; - } - .cp-app-drive-tree-root > .cp-app-drive-element-row > .cp-app-drive-icon-folder { - margin-left: -5px; - } - .cp-app-drive-tree-root { - &> .cp-app-drive-element-row { - padding-left: 20px; - } - &> ul { - padding-left: 30px; - } - } - } - - // Expand/collapse lines - .cp-app-drive-tree-docs ul { - margin: 0px 0px 0px 10px; - list-style: none; - padding-left: 10px; - li { - position: relative; - &:before { - position: absolute; - left: -15px; - top: -11px; - content: ''; - display: block; - border-left: 1px solid @colortheme_sidebar-left-branch; - height: ~"calc(1em + 11px)"; - border-bottom: 1px solid @colortheme_sidebar-left-branch; - width: 15px; - } - &:after { - position: absolute; - left: -15px; - bottom: -7px; - content: ''; - display: block; - border-left: 1px solid @colortheme_sidebar-left-branch; - height: 100%; - } - &.cp-app-drive-tree-root { - margin: 0px 0px 0px -10px; - &:before { - display: none; - } - &:after { - display: none; - } - } - &:last-child:after { - display: none; - } - } - } -} - -/* CONTENT */ -#cp-app-drive-content-container { - display: flex; - flex-flow: column; - flex: 1; - // Needed to avoid the folder's path to overflows - // https://stackoverflow.com/questions/38223879/white-space-nowrap-breaks-flexbox-layout - min-width: 0; -} -#cp-app-drive-content { - box-sizing: border-box; - background: @drive_content-bg; - color: @drive_content-fg; - overflow: auto; - flex: 1; - display: flex; - flex-flow: column; - position: relative; - .cp-app-drive-content-select-box { - display: none; - background-color: rgba(100, 100, 100, 0.7); - position: absolute; - z-index: 50; - } - &.cp-app-drive-readonly { - background: @drive_content-bg-ro; - } - h1 { - padding-left: 10px; - margin-top: 10px; - } - .cp-app-drive-content-info-box { - line-height: 2em; - padding: 0.25em 0.75em; - margin: 1em; - background: @drive_info-box-bg; - span { - cursor: pointer; - float: right; - margin-top: 0.5em; - } - } - li { - cursor: default; - &:not(.cp-app-drive-element-header) { - &:hover { - &:not(.-cp-app-drive-element-selected, .cp-app-drive-element-selected-tmp) { - background-color: @drive_hover; - } - } - } - } - #cp-app-drive-content-folder { - li { - &.cp-app-drive-search-result { - border-bottom: 1px solid @drive_info-box-border; - display: block; - &:hover { - background-color: initial; - } - table { - width: 100%; - .cp-app-drive-search-label2 { - width: 150px; - font-size: 15px; - text-align: right; - padding-right: 15px; - } - .cp-app-drive-search-opendir { - a { - cursor: pointer; - color: #41b7d8; - &:hover { - color: #014c8c; - text-decoration: underline; - } - } - } - .cp-app-drive-search-path { - font-style: italic; - direction: rtl; - .cp-app-drive-path-element { - display: inline-block; - margin-right: 5px; - } - } - .cp-app-drive-search-title { - font-weight: bold; - cursor: pointer; - &:hover { - background-color: @drive_hover; - } - } - .cp-app-drive-search-col2 { - width: 250px; - } - td.cp-app-drive-search-icon { - width: 50px; - font-size: 40px; - } - } - } - } - } - .cp-app-drive-element { - .cp-app-drive-element-truncated { display: none; } - } - div.cp-app-drive-content-grid { - padding: 20px; - .drive_fileIcon; - li { - &.cp-app-drive-element { - position: relative; - } - input { - width: 100%; - margin-top: 5px; - } - .cp-app-drive-element-state { - position: absolute; - top: 3px; - right: 3px; - .fa { - margin:0; - font-size: 18px; - } - } - } - .cp-app-drive-element-list { - display: none; - } - .cp-app-drive-new-ghost { - cursor: pointer; - opacity: 0.5; - padding: 0; - &:hover { - opacity: 0.7; - } - .fa { - cursor: pointer; - font-size: 90px; - margin-top: 5px; - margin-bottom: 0; - } - } - } - - .cp-app-drive-content-list { - .cp-app-drive-element-grid { - display: none; - } - // Make it act as a table! - padding-left: 20px; - ul { - display: table; - width: 100%; - padding: 0px 10px; - } - li { - display: table-row; - &> span { - padding: 0 5px; - display: table-cell; - } - &:not(.cp-app-drive-element-header) { - height: @variables_bar-height; - line-height: @variables_bar-height; - } - &.cp-app-drive-element-header { - cursor: default; - color: @drive_table-header-fg; - span { - &:not(.fa) { - text-align: left; - } - &.sortasc, &.sortdesc { - float: right; - } - } - &> span { - padding: 15px 5px; - &.cp-app-drive-sort-active { - font-weight: bold; - } - &.cp-app-drive-sort-clickable { - cursor: pointer; - &:hover { - background: @drive_table-header-bg; - } - } - } - } - } - .cp-app-drive-element { - span { - overflow: hidden; - white-space: nowrap; - box-sizing: border-box; - &.cp-app-drive-element-state { - .fa:not(:last-child) { - margin-right: 5px; - } - } - &.cp-app-drive-content-icon, &.cp-app-drive-element-state { - width: 30px; - } - &.cp-app-drive-element-type, &.cp-app-drive-element-atime, &.cp-app-drive-element-ctime { - width: 175px; - } - &.cp-app-drive-element-title { - width: 250px; - @media screen and (max-width: 1200px) { - display: none; - } - } - &.cp-app-drive-element-folders, &.cp-app-drive-element-files { - width: 150px; - } - } - } - } -} - -#cp-app-drive-content-folder { - padding-right: 10px; - flex: 1; -} - -#cp-app-drive-new-ghost-dialog.cp-modal-container { - .drive_fileIcon; - - li:not(.cp-app-drive-element-selected):hover { - border: 1px solid white; - } - .cp-modal { - display: flex; - flex-flow: column; - li, li .fa { - cursor: pointer; - } - &> p { - margin: 50px; - } - &> div { - display: flex; - flex-wrap: wrap; - justify-content: center; - align-content: center; - overflow-y: auto; - .cp-app-drive-new-upload { - break-after: always; - page-break-after: always; - } - } - } - - @media screen and (max-height: @browser_media-not-big) { - .cp-modal { - & > p { - display: none; - } - & > div { - align-content: unset; - li { - height: 40px; - width: 90%; - display: flex; - align-items: center; - .fa { - font-size: 32px; - } - .cp-app-drive-new-name { - height: auto; - } - } - } - } - } -} - - -/* Toolbar */ - -#cp-app-drive-toolbar { - background: lighten(@colortheme_drive-bg, 8%); - color: @colortheme_drive-color; - //height: 30px; - //display: flex; - //flex-flow: row; - z-index: 100; - box-sizing: border-box; - height: @variables_bar-height; - padding: 0; - display: flex; - flex-flow: row; - - * { - outline-width: 0; - &:focus { - outline-width: 0; - } - } - - .history { - float: right; - .cp-toolbar-drawer-element { - display: none; - } - } - - .cp-app-drive-toolbar-rightside, .cp-app-drive-toolbar-leftside { - display: inline-block; - margin: 0; - padding: 0; - .fa { - margin: 0; - } - button { - height: @variables_bar-height; - padding: 0 10px; - border: none; - border-radius: 0; - box-sizing: border-box; - background: transparent; - font-size: @colortheme_app-font-size; - color: @colortheme_drive-color; - transition: all 0.15s; - .drawer { - display: none; - } - .fa, span { - font-size: @colortheme_app-font-size; - } - &:hover { - background: @colortheme_drive-bg; - } - &.cp-app-drive-toolbar-active { - display: none; - } - } - } - .cp-app-drive-toolbar-rightside { - float: right; - & > * { - float: right; - } - #cp-app-drive-toolbar-contextbuttons { - display: inline-block; - height: 100%; - } - padding-left: 10px; - } - .cp-app-drive-toolbar-leftside { - & > span { - height: 100%; - margin: 0; - } - button { - padding: 0 10px; - .fa { - margin-right: 5px; - } - .cp-dropdown-button-title { - display: inline-flex; - height: @variables_bar-height; - align-items: center; - span:not(.fa) { - line-height: 23px; - } - } - } - } - - button { - font: @colortheme_app-font; - span { - font: @colortheme_app-font; - } - .fa, &.fa { - font-family: FontAwesome; - } - } - /* The container
- needed to position the dropdown content */ - .cp-dropdown-container { - margin: 2px 2px; - line-height: 1em; - position: relative; - display: inline-block; - } - .cp-dropdown-content { - margin-right: 2px; - } - - .cp-app-drive-path { - flex: 1; - width: 100%; - height: @variables_bar-height; - line-height: @variables_bar-height; - cursor: default; - width: auto; - overflow: hidden; - white-space: nowrap; - direction: rtl; - max-width: 100%; - text-align: left; - .cp-app-drive-path-element { - display: inline-block; - height: @variables_bar-height; - line-height: @variables_bar-height; - font-size: @colortheme_app-font-size; - padding: 0 5px; - border: 0; - background: darken(@colortheme_drive-bg, 10%); - color: @colortheme_drive-color; - box-sizing: border-box; - transition: all 0.15s; - &.cp-app-drive-path-separator { - color: #ccc; - } - &.cp-app-drive-path-lickable { - cursor: pointer; - &:hover { - background: darken(@colortheme_drive-bg, 15%); - } - } - } - } -} - - - diff --git a/www/poll/app-poll.less b/www/poll/app-poll.less index fd751249d..8960d1094 100644 --- a/www/poll/app-poll.less +++ b/www/poll/app-poll.less @@ -11,10 +11,19 @@ .tokenfield_main(); @poll-fore: #555; -@poll-th-bg: #aaa; -@poll-th-user-bg: #999; -@poll-td-bg: #aaa; -@poll-editing: #88b8cc; + +@poll-th-bg: #005bef; +@poll-th-fg: #fff; +@poll-th-user-bg: darken(@poll-th-bg, 10%); +@poll-editing: lighten(@poll-th-bg, 10%); +@poll-winner: darken(@poll-th-bg, 15%); +@poll-td-bg: @poll-th-bg; +@poll-td-fg: @poll-th-fg; + +@poll-uncommitted-cell: #eee; +@poll-uncommitted-bg: #ddd; //lighten(@poll-th-bg, 50%); +@poll-uncommitted-text: black; + @poll-placeholder: #666; @poll-border-color: #555; @poll-cover-color: #000; @@ -35,18 +44,20 @@ overflow-x: hidden; #cp-app-poll-form { flex: 1; overflow-y: auto; + &.cp-app-poll-published { + #cp-app-poll-create-option { + display: none; + } + .cp-app-poll-table-remove[data-rt-id^="y"], .cp-app-poll-table-edit[data-rt-id^="y"] { + display: none; + } + tr.cp-app-poll-table-uncommitted { + display: none; + } + } } } -/*.cp-toolbar-container h2 { - font: normal normal normal 12px Arial, Helvetica, Tahoma, Verdana, Sans-Serif; - color: #000; - line-height: auto; -} -.cp-toolbar-container { - display: block; -}*/ - .cp-app-poll-table-text-cell input[type="text"] { width: 400px; } @@ -64,8 +75,9 @@ input[type="text"][disabled], textarea[disabled] { // The placeholder color only seems to effect Safari when not set -input[type="text"]::placeholder { - color: @poll-placeholder; +input[type="text"][disabled]::placeholder { + //color: @poll-placeholder; + opacity: 1; } table#cp-app-poll-table { @@ -73,12 +85,13 @@ table#cp-app-poll-table { } #cp-app-poll-table-container { position: relative; - padding: 29px; - padding-right: 79px; + padding: 30px 0; + width: ~"calc(100% - 30px)"; } #cp-app-poll-table-container button { - height: 2rem; - display: none; + //display: none; + border-radius: 0; + border: 0; } #cp-app-poll-publish { display: none; @@ -88,21 +101,23 @@ table#cp-app-poll-table { margin-bottom: 15px; } #cp-app-poll-create-user { - position: absolute; - display: inline-block; - /*left: 0px;*/ - top: 55px; + display: inline-flex; + height: 24px; + padding: 0; width: 50px; overflow: hidden; } #cp-app-poll-create-option { + display: inline-flex; width: 50px; + height: 24px; + padding: 0; } #cp-app-poll-table-scroll { overflow-y: hidden; overflow-x: auto; - margin-left: calc(~"30% - 50px + 31px"); - max-width: 70%; + margin-left: ~"calc(25% + 30px)"; + max-width: ~"calc(75% - 30px - 100px - 100px)"; width: auto; display: inline-block; } @@ -145,45 +160,12 @@ table { margin: 20px; } tbody { - border: 1px solid @poll-border-color; + //border: 1px solid @poll-border-color; * { box-sizing: border-box; } tr { text-align: center; - &:first-of-type th{ - font-size: 20px; - border-top: 0px; - font-weight: bold; - padding: 10px; - text-decoration: underline; - &.table-refresh { - color: @colortheme_cp-green; - text-decoration: none; - cursor: pointer; - } - - } - &:nth-child(odd) { - background-color: @colortheme_light-base; - } - th:first-of-type { - border-left: 0px; - } - th { - box-sizing: border-box; - border: 1px solid @poll-border-color; - } - th, td { - color: @poll-fore; - - .cp-app-poll-table-remove { - cursor: pointer; - } - } - th:last-child { - border-right: 0px; - } } td { @@ -222,12 +204,48 @@ div.cp-app-poll-realtime { .cp-app-poll-table-editing { background-color: @poll-editing; } + .cp-app-poll-table-uncommitted { + .cp-app-poll-table-cover { + background-color: @poll-uncommitted-cell !important; + } + div.cp-app-poll-table-text-cell { + background-color: @poll-uncommitted-bg !important; + color: @poll-uncommitted-text !important; + input { + width: ~"calc(100% - 80px)" !important; + vertical-align: middle; + } + } + text-align: center; + background-color: @poll-uncommitted-bg !important; + color: @poll-uncommitted-text !important; + } tr { + height: 28px; + /* Options */ td:first-child { position:absolute; - left: 29px; + left: 30px; + 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: @poll-th-fg; + position:absolute; top: auto; - width: ~"calc(30% - 50px)"; + margin-left: 100px; + width: 100px; + min-width: unset !important; + background-color: @poll-th-bg; } td { padding: 0px; @@ -243,10 +261,11 @@ div.cp-app-poll-realtime { width: 90%; height: 100%; border: 0px; + margin: 2px; &[disabled] { background-color: transparent; - color: @poll-fg; - font-weight: bold; + color: @poll-td-fg; + //font-weight: bold; } } } @@ -279,8 +298,11 @@ div.cp-app-poll-realtime { display: none; ~ .cp-app-poll-table-cover { + line-height: 28px; display: block; font-weight: bold; + height: 100%; + display: block; color: @poll-cover-color; @@ -288,18 +310,6 @@ div.cp-app-poll-realtime { height: 100%; } - display: block; - &.yes { - background-color: @colortheme_cp-green; - } - - &.uncommitted { - background: #ddd; - } - - &.mine { - display: none; - } } } } @@ -350,22 +360,40 @@ div.cp-app-poll-realtime { td { padding: 0px 5px; background: @poll-th-bg; - border-radius: 20px 20px 0 0; + color: @poll-th-fg; + &:not(:last-child) { + border-right: 1px solid rgba(255,255,255,0.2); + } + &:nth-last-child(2) { + border-right: 1px solid @poll-border-color; + } //text-align: center; - &:nth-of-type(2) { + &.cp-app-poll-table-own { background: @poll-th-user-bg; .cp-app-poll-table-lock { cursor: default; } } + .cp-app-poll-table-buttons { + display: flex; + justify-content: space-between; + flex-wrap: wrap; + align-items: center; + span { + cursor: pointer; + width: 1em; + text-align: center; + } + } input { &[type="text"] { - width: 100%; + break-after: always; + width: ~"calc(100% - 2px)"; // borders... box-sizing: border-box; padding: 1px 5px; + margin: 1px; &[disabled] { - color: @poll-fg; - border: 1px solid transparent; + color: @poll-th-fg; } } } @@ -373,24 +401,26 @@ div.cp-app-poll-realtime { } tbody { - td:not(.cp-app-poll-table-editing) { - .cp-app-poll-table-text-cell { - background: @poll-td-bg; - } + td:first-child { + background: @poll-td-bg; + color: @poll-td-fg; + } + td.cp-app-poll-table-winner { + background-color: @poll-winner; + &:last-child { font-weight: bold; } } .cp-app-poll-table-text-cell { - //border-radius: 20px 0 0 20px; input[type="text"] { width: ~"calc(100% - 50px)"; padding: 0 0.5em; } .cp-app-poll-table-edit { float:right; - margin: 0 10px 0 0; + margin: 2px 10px 0 0; } .cp-app-poll-table-remove { float: left; - margin: 0 0 0 10px; + margin: 2px 0 0 10px; } } tr:not(:first-child) { @@ -402,23 +432,12 @@ div.cp-app-poll-realtime { } } .cp-app-poll-table-edit { - color: @poll-cover-color; + //color: @poll-cover-color; cursor: pointer; float: left; margin-left: 10px; } - .cp-app-poll-table-lock { - margin-left: ~"calc(50% - 0.5em)"; - cursor: pointer; - width: 1em; - text-align: center; - } - .cp-app-poll-table-remove { - float: right; - margin-right: 10px; - } - thead { tr { th { @@ -442,31 +461,9 @@ div.cp-app-poll-realtime { } } tfoot { - tr { - border: none; - td { - border: none; - text-align: center; - .save { - padding: 15px; - border-top-left-radius: 5px; - border-top-right-radius: 5px; - } - } - } + display: none; } } - - #adduser, - #addoption { - color: @colortheme_cp-green; - border: 1px solid @colortheme_cp-green; - padding: 15px; - cursor: pointer; - } - - #adduser { .top-left; } - #addoption { .bottom-left; } } .btn { diff --git a/www/poll/inner.js b/www/poll/inner.js index 371ce078a..57916294e 100644 --- a/www/poll/inner.js +++ b/www/poll/inner.js @@ -75,14 +75,51 @@ define([ + var copyObject = function (obj) { + return JSON.parse(JSON.stringify(obj)); + }; + /* + Make sure that the realtime data structure has all the required fields + */ + var prepareProxy = function (proxy, schema) { + if (proxy && proxy.version === 1) { return; } + debug("Configuring proxy schema..."); + + proxy.metadata = proxy.metadata || schema.metadata; + Object.keys(schema.metadata).forEach(function (k) { + if (!proxy.metadata[k]) { proxy.metadata[k] = schema.metadata[k]; } + }); + + proxy.content = proxy.content || schema.content; + Object.keys(schema.content).forEach(function (k) { + if (!proxy.content[k]) { proxy.content[k] = schema.content[k]; } + }); + + proxy.version = 1; + proxy.type = 'poll'; + }; + var setUserId = function (id, cb) { + cb =cb || $.noop; + APP.userid = id; + common.setPadAttribute('userid', id, function (e) { + if (e) { + console.error(e); + return void cb(e); + } + cb(); + }); + }; + var sortColumns = function (order, firstcol) { var colsOrder = order.slice(); + // Never put at the first position an uncommitted column + if (APP.proxy.content.colsOrder.indexOf(firstcol) === -1) { return colsOrder; } colsOrder.sort(function (a, b) { return (a === firstcol) ? -1 : ((b === firstcol) ? 1 : 0); @@ -90,8 +127,9 @@ define([ return colsOrder; }; - var isOwnColumnCommitted = function () { - return APP.proxy && APP.proxy.content.colsOrder.indexOf(APP.userid) !== -1; + var isUncommitted = function (id) { + return APP.uncommitted.content.colsOrder.indexOf(id) !== -1 || + APP.uncommitted.content.rowsOrder.indexOf(id) !== -1; }; var mergeUncommitted = function (proxy, uncommitted, commit) { @@ -101,11 +139,6 @@ define([ } else { newObj = $.extend(true, {}, proxy); } - // We have uncommitted data only if the user's column is not in the proxy - // If it is already is the proxy, nothing to merge - /*if (isOwnColumnCommitted()) { - return newObj; - }*/ // Merge uncommitted into the proxy uncommitted.content.colsOrder = uncommitted.content.colsOrder || []; @@ -129,9 +162,9 @@ define([ if (newObj.content.rowsOrder.indexOf(x) !== -1) { return; } newObj.content.rowsOrder.push(x); }); - for (var k in uncommitted.content.rows) { - if (!newObj.content.rows[k]) { - newObj.content.rows[k] = uncommitted.content.rows[k]; + for (var m in uncommitted.content.rows) { + if (!newObj.content.rows[m]) { + newObj.content.rows[m] = uncommitted.content.rows[m]; } } @@ -143,26 +176,46 @@ define([ }; var styleUncommittedColumn = function () { - var id = APP.userid; + var userid = APP.userid; // TODO: move? // Enable input for the userid column - $('input[disabled="disabled"][data-rt-id^="' + id + '"]').removeAttr('disabled'); - $('input[type="number"][data-rt-id^="' + id + '"]').addClass('enabled'); - $('.cp-app-poll-table-lock[data-rt-id="' + id + '"]').addClass('fa-unlock').removeClass('fa-lock').attr('title', Messages.poll_unlocked); - + $('input[disabled="disabled"][data-rt-id^="' + userid + '"]').removeAttr('disabled') + .attr('placeholder', Messages.poll_userPlaceholder); + $('input[type="number"][data-rt-id^="' + userid + '"]').addClass('enabled'); + $('.cp-app-poll-table-lock[data-rt-id="' + userid + '"]').remove(); + $('[data-rt-id^="' + userid + '"]').closest('td') + .addClass("cp-app-poll-table-own"); + $('.cp-app-poll-table-bookmark[data-rt-id="' + userid + '"]').css('visibility', '') + .removeClass('fa-bookmark-o').addClass('fa-bookmark') + .attr('title', 'TODO: this is your bookmarked column. It will always be unlocked and displayed at the beginning for you'); + //.addClass('fa-unlock').removeClass('fa-lock').attr('title', Messages.poll_unlocked); + //$('.cp-app-poll-table-remove[data-rt-id="' + userid + '"]').remove(); + + var $scroll = $('#cp-app-poll-table-scroll'); + var hasScroll = $scroll.width() < $scroll[0].scrollWidth; APP.uncommitted.content.colsOrder.forEach(function(id) { // Enable the checkboxes for the uncommitted column $('input[disabled="disabled"][data-rt-id^="' + id + '"]').removeAttr('disabled'); $('input[type="number"][data-rt-id^="' + id + '"]').addClass('enabled'); - $('.cp-app-poll-table-lock[data-rt-id="' + id + '"]').addClass('fa-unlock').removeClass('fa-lock').attr('title', Messages.poll_unlocked); + $('.cp-app-poll-table-lock[data-rt-id="' + id + '"]').remove(); + //.addClass('fa-unlock').removeClass('fa-lock').attr('title', Messages.poll_unlocked); + $('.cp-app-poll-table-remove[data-rt-id="' + id + '"]').remove(); + $('.cp-app-poll-table-bookmark[data-rt-id="' + id + '"]').remove(); - $('[data-rt-id^="' + id + '"]').closest('td').addClass("cp-app-poll-table-uncommitted"); $('td.cp-app-poll-table-uncommitted .cover').addClass("cp-app-poll-table-uncommitted"); + var $uncommittedCol = $('[data-rt-id^="' + id + '"]').closest('td'); + $uncommittedCol.addClass("cp-app-poll-table-uncommitted"); + + if (hasScroll) { + $uncommittedCol.css('right', '100px'); + } }); APP.uncommitted.content.rowsOrder.forEach(function(id) { // Enable the checkboxes for the uncommitted column $('input[disabled="disabled"][data-rt-id="' + id + '"]').removeAttr('disabled'); + $('.cp-app-poll-table-edit[data-rt-id="' + id + '"]').remove(); + $('.cp-app-poll-table-remove[data-rt-id="' + id + '"]').remove(); $('[data-rt-id="' + id + '"]').closest('tr').addClass("cp-app-poll-table-uncommitted"); //$('td.uncommitted .cover').addClass("uncommitted"); @@ -187,10 +240,20 @@ define([ }; var updateTableButtons = function () { - var $createOption = APP.$table.find('tfoot tr td:first-child'); + var uncomColId = APP.uncommitted.content.colsOrder[0]; + var uncomRowId = APP.uncommitted.content.rowsOrder[0]; + var $createOption = APP.$table.find('tbody input[data-rt-id="' + uncomRowId+'"]') + .closest('td').find('> div'); $createOption.append(APP.$createRow); + var $createUser = APP.$table.find('thead input[data-rt-id="' + uncomColId + '"]') + .closest('td'); + $createUser.prepend(APP.$createCol); + + if (APP.proxy.content.colsOrder.indexOf(APP.userid) === -1) { + APP.$table.find('.cp-app-poll-table-bookmark').css('visibility', ''); + } - $('#cp-app-poll-create-user, #cp-app-poll-create-option').css('display', 'inline-flex'); + //$('#cp-app-poll-create-user, #cp-app-poll-create-option').css('display', 'inline-flex'); if (!APP.proxy || !APP.proxy.content.rowsOrder || APP.proxy.content.rowsOrder.length === 0) { @@ -206,21 +269,64 @@ define([ if (bool) { if (APP.$publish) { APP.$publish.hide(); } if (APP.$admin) { APP.$admin.show(); } - $('#cp-app-poll-create-option').hide(); - $('.cp-app-poll-table-remove[data-rt-id^="y"], .cp-app-poll-table-edit[data-rt-id^="y"]').hide(); + $('#cp-app-poll-form').addClass('cp-app-poll-published'); } else { if (APP.$publish) { APP.$publish.show(); } if (APP.$admin) { APP.$admin.hide(); } - $('#cp-app-poll-create-option').show(); - $('.cp-app-poll-table-remove[data-rt-id^="y"], .cp-app-poll-table-edit[data-rt-id^="y"]').show(); + $('#cp-app-poll-form').removeClass('cp-app-poll-published'); } }; + var addCount = function () { + var $scroll = $('#cp-app-poll-table-scroll'); + var hasScroll = $scroll.width() < $scroll[0].scrollWidth; + var $countCol = $('tr td:last-child'); + if (hasScroll) { + $countCol.css('right', '0'); + } + var $thead = APP.$table.find('thead'); + var $tr = APP.$table.find('tbody tr').first(); + $thead.find('tr td').last() + .css({ + 'height': $thead.height()+'px', + 'text-align': 'center', + 'line-height': $thead.height()+'px' + }) + .text('TOTAL'); // TODO + var winner = { + v: 0, + ids: [] + }; + APP.proxy.content.rowsOrder.forEach(function (rId) { + var count = Object.keys(APP.proxy.content.cells) + .filter(function (k) { + return k.indexOf(rId) !== -1 && APP.proxy.content.cells[k] === 1; + }).length; + if (count > winner.v) { + winner.v = count; + winner.ids = [rId]; + } else if (count && count === winner.v) { + winner.ids.push(rId); + } + APP.$table.find('[data-rt-count-id="' + rId + '"]') + .text(count) + .css({ + 'height': $tr.height()+'px', + 'line-height': $tr.height()+'px' + }); + }); + winner.ids.forEach(function (rId) { + $('[data-rt-id="' + rId + '"]').closest('td').addClass('cp-app-poll-table-winner'); + $('[data-rt-count-id="' + rId + '"]').addClass('cp-app-poll-table-winner'); + }); + }; + var updateDisplayedTable = function () { styleUncommittedColumn(); unlockElements(); updateTableButtons(); setTablePublished(APP.proxy.published); + addCount(); /* APP.proxy.table.rowsOrder.forEach(function (rowId) { @@ -283,14 +389,6 @@ define([ readOnly: readOnly }; - //Render.updateTable(table, displayedObj, conf); - - /* FIXME browser autocomplete fills in new fields sometimes - calling updateTable twice removes the autofilled in values - setting autocomplete="off" is not reliable - - https://developer.mozilla.org/en-US/docs/Web/Security/Securing_your_site/Turning_off_form_autocompletion - */ common.notify(); var getFocus = function () { @@ -298,23 +396,36 @@ define([ if (!active) { return; } return { el: active, + id: $(active).attr('data-rt-id'), start: active.selectionStart, end: active.selectionEnd }; }; var setFocus = function (obj) { - if (obj.el) { obj.el.focus(); } + var el; + if (document.body.contains(obj.el)) { el = obj.el; } + else if($('input[data-rt-id="' + obj.id + '"]').length) { + el = $('input[data-rt-id="' + obj.id + '"]')[0]; + } else { return; } - if (obj.start) { obj.el.selectionStart = obj.start; } - if (obj.end) { obj.el.selectionEnd = obj.end; } + el.focus(); + if (obj.start) { el.selectionStart = obj.start; } + if (obj.end) { el.selectionEnd = obj.end; } }; var updateTable = function () { var displayedObj2 = mergeUncommitted(APP.proxy, APP.uncommitted); var f = getFocus(); + APP.$createRow.detach(); + APP.$createCol.detach(); Render.updateTable(table, displayedObj2, conf); - APP.proxy.content.rowsOrder.forEach(function (rowId) { - $('input[data-rt-id="' + rowId +'"]').val(APP.proxy.content.rows[rowId] || ''); + // Fix autocomplete bug: + displayedObj2.content.rowsOrder.forEach(function (rowId) { + $('input[data-rt-id="' + rowId +'"]').val(displayedObj2.content.rows[rowId] || ''); + }); + displayedObj2.content.colsOrder.forEach(function (rowId) { + $('input[data-rt-id="' + rowId +'"]') + .val(displayedObj2.content.cols[rowId] || ''); }); updateDisplayedTable(); setFocus(f); @@ -339,6 +450,10 @@ define([ return input.getAttribute && input.getAttribute('data-rt-id'); }; + var handleBookmark = function (id) { + setUserId(id === APP.userid ? '' : id, change); + }; + /* Called whenever an event is fired on an input element */ var handleInput = function (input) { var type = input.type.toLowerCase(); @@ -349,9 +464,7 @@ define([ var object = APP.proxy; var x = Render.getCoordinates(id)[0]; - if (type !== "row" && x === APP.userid && APP.proxy.content.colsOrder.indexOf(x) === -1) { - object = APP.uncommitted; - } + if (isUncommitted(id)) { object = APP.uncommitted; } switch (type) { case 'text': @@ -383,7 +496,6 @@ define([ var hideInputs = function (id) { if (APP.readOnly) { return; } - console.log(id); if (id) { var type = Render.typeofId(id); console.log(type); @@ -404,6 +516,8 @@ define([ .indexOf('cp-app-poll-table-remove') !== -1; var isEdit = span.className && span.className.split(' ') .indexOf('cp-app-poll-table-edit') !== -1; + var isBookmark = span.className && span.className.split(' ') + .indexOf('cp-app-poll-table-bookmark') !== -1; var isLock = span.className && span.className.split(' ') .indexOf('cp-app-poll-table-lock') !== -1; var isLocked = span.className && span.className.split(' ').indexOf('fa-lock') !== -1; @@ -431,6 +545,9 @@ define([ change(); }); }); + } else if (isBookmark) { + //hideInputs(span); + handleBookmark(id); } else if (isLock && isLocked) { //hideInputs(span); unlockColumn(id, function () { @@ -466,19 +583,30 @@ define([ var nodeName = target && target.nodeName; //var shouldLock = $(target).hasClass('fa-unlock'); - if ((!$(target).parents('#cp-app-poll-table tbody').length && + /*if ((!$(target).parents('#cp-app-poll-table tbody').length && $(target).hasClass('cp-app-poll-table-lock'))) { //hideInputs(e); - } + }*/ switch (nodeName) { case 'INPUT': if (isKeyup && (e.keyCode === 13 || e.keyCode === 27)) { var id = target.getAttribute('data-rt-id'); + if ($(target).parents('.cp-app-poll-table-uncommitted').length + && e.keyCode === 13) { + var type = Render.typeofId(id); + if (type === "row") { APP.$createRow.click(); } + else if (type === "col") { APP.$createCol.click(); } + break; + } hideInputs(id); break; } - if ($(target).is('input[type="number"]')) { console.error("number input focused?"); break; } + if ($(target).is('input[type="number"]')) { + // Nothing to do... + //console.error("number input focused?"); + break; + } handleInput(target); break; @@ -505,27 +633,6 @@ define([ } }; - /* - Make sure that the realtime data structure has all the required fields - */ - var prepareProxy = function (proxy, schema) { - if (proxy && proxy.version === 1) { return; } - debug("Configuring proxy schema..."); - - proxy.metadata = proxy.metadata || schema.metadata; - Object.keys(schema.metadata).forEach(function (k) { - if (!proxy.metadata[k]) { proxy.metadata[k] = schema.metadata[k]; } - }); - - proxy.content = proxy.content || schema.content; - Object.keys(schema.content).forEach(function (k) { - if (!proxy.content[k]) { proxy.content[k] = schema.content[k]; } - }); - - proxy.version = 1; - proxy.type = 'poll'; - }; - /* */ @@ -551,10 +658,6 @@ define([ $('#cp-app-poll-action-help').text(msg); }; - var copyObject = function (obj) { - return JSON.parse(JSON.stringify(obj)); - }; - @@ -588,9 +691,9 @@ define([ } }; - var updateDescription = function (n) { + var updateDescription = function (old, n) { var o = APP.$description.val(); - var op = TextPatcher.diff(o, n); + var op = TextPatcher.diff(o, n || ''); var el = APP.$description[0]; var selects = ['selectionStart', 'selectionEnd'].map(function (attr) { @@ -604,10 +707,7 @@ define([ common.notify(); }; var updateLocalDescription = function (n) { - var md = copyObject(metadataMgr.getMetadata()); - md.description = n; - metadataMgr.updateMetadata(md); - APP.proxy.metadata.description = n; + APP.proxy.description = n; }; var onReady = function (info, userid, readOnly) { @@ -639,7 +739,7 @@ define([ throw new Error(errorText); } } else { - //Title.updateTitle(Title.defaultTitle); + Title.updateTitle(Title.defaultTitle); } if (typeof(proxy.type) === 'undefined') { @@ -675,13 +775,13 @@ define([ var $table = APP.$table = $(Render.asHTML(displayedObj, null, colsOrder, readOnly)); var getUncommitted = function (type) { - var ret = {}; + var ret = {}, toRemove; var uncommitted = APP.uncommitted.content; if (type === 'col') { ret.colsOrder = uncommitted.colsOrder.slice(); ret.cols = copyObject(uncommitted.cols); // get only the cells corresponding to the committed rows - var toRemove = Object.keys(uncommitted.cells).filter(function (coor) { + toRemove = Object.keys(uncommitted.cells).filter(function (coor) { var c = Render.getCoordinates(coor); return APP.proxy.content.rowsOrder.indexOf(c[1]) !== -1; }); @@ -699,7 +799,7 @@ define([ ret.rowsOrder = uncommitted.rowsOrder.slice(); ret.rows = copyObject(uncommitted.rows); // get only the cells corresponding to the committed rows - var toRemove = Object.keys(uncommitted.cells).filter(function (coor) { + toRemove = Object.keys(uncommitted.cells).filter(function (coor) { var c = Render.getCoordinates(coor); return APP.proxy.content.colsOrder.indexOf(c[1]) !== -1; }); @@ -710,6 +810,7 @@ define([ }); uncommitted.rowsOrder = [Render.rowuid()]; uncommitted.rows = {}; + console.log(JSON.stringify(ret, 0, 2)); return ret; }; APP.$createCol = $('#cp-app-poll-create-user').click(function () { @@ -722,23 +823,13 @@ define([ }); APP.$createRow = $('#cp-app-poll-create-option').click(function () { var uncommittedCopy = { content: getUncommitted('row') }; - var id = uncommittedCopy.content.rowsOrder[0]; mergeUncommitted(proxy, uncommittedCopy, true); change(null, null, null, null, function() { - handleSpan($('.cp-app-poll-table-edit[data-rt-id="' + id + '"]')[0]); + var newId = APP.uncommitted.content.rowsOrder[0]; + $('input[data-rt-id="' + newId + '"]').focus(); }); }); - // Commit button - APP.$commit = $('#commit').click(function () { - var uncommittedCopy = copyObject(APP.uncommitted); - APP.uncommitted = {}; - prepareProxy(APP.uncommitted, copyObject(Render.Example)); - mergeUncommitted(proxy, uncommittedCopy, true); - APP.$commit.hide(); - change(); - }).remove(); // TODO - // #publish button is removed in readonly APP.$publish = $('#cp-app-poll-action-publish') .click(function () { @@ -756,9 +847,7 @@ define([ }); if (!readOnly) { - common.setPadAttribute('userid', userid, function (e) { - if (e) { console.error(e); } - }); + setUserId(userid); } // Description @@ -775,6 +864,7 @@ define([ $('#cp-app-poll-table-scroll').html('').prepend($table); updateDisplayedTable(); + updateDescription(null, APP.proxy.description); $table .click(handleClick) @@ -786,16 +876,19 @@ define([ }); proxy - .on('change', ['metadata'], function (o, n, p) { + .on('change', ['metadata'], function () { metadataMgr.updateMetadata(proxy.metadata); }) .on('change', ['content'], change) + .on('change', ['description'], updateDescription) .on('remove', [], change); // If the user's column is not committed, add his username var $userInput = $('.cp-app-poll-table-uncommitted > input[data-rt-id^='+ APP.userid +']'); if ($userInput.val() === '') { - $userInput.val(metadataMgr.getUserData().name); + var uname = metadataMgr.getUserData().name; + APP.uncommitted.content.cols[APP.userid] = uname; + $userInput.val(uname); } APP.ready = true; @@ -856,9 +949,6 @@ define([ metadataMgr.onChange(function () { var md = copyObject(metadataMgr.getMetadata()); - if (md.description) { - updateDescription(md.description); - } APP.proxy.metadata = md; }); return; // TODO diff --git a/www/poll/render.js b/www/poll/render.js index e5712aab9..c9f6f7c1f 100644 --- a/www/poll/render.js +++ b/www/poll/render.js @@ -217,11 +217,11 @@ var Renderer = function (Cryptpad) { 'data-rt-id': col, type: 'text', value: getColumnValue(obj, col) || "", - placeholder: Cryptpad.Messages.poll_userPlaceholder, + placeholder: Cryptpad.Messages.anonymous, disabled: 'disabled' }; return result; - })); + })).concat([null]); } if (i === rows.length) { return [null].concat(cols.map(function () { @@ -254,7 +254,9 @@ var Renderer = function (Cryptpad) { result.value = val; } return result; - })); + })).concat([{ + 'data-rt-count-id': row + }]); }); }; @@ -282,13 +284,25 @@ var Renderer = function (Cryptpad) { }, []]; }; + var makeBookmarkElement = Render.makeBookmarkElement = function (id) { + return ['SPAN', { + 'data-rt-id': id, + 'title': 'TODO: Bookmark this column so that it is always unlocked and displayed at the beginning for you.', + 'style': 'visibility: hidden;', + class: 'cp-app-poll-table-bookmark fa fa-bookmark-o', + }, []]; + }; + var makeHeadingCell = Render.makeHeadingCell = function (cell, readOnly) { if (!cell) { return ['TD', {}, []]; } if (cell.type === 'text') { var elements = [['INPUT', cell, []]]; if (!readOnly) { - elements.unshift(makeRemoveElement(cell['data-rt-id'])); - elements.unshift(makeLockElement(cell['data-rt-id'])); + var buttons = []; + buttons.unshift(makeRemoveElement(cell['data-rt-id'])); + buttons.unshift(makeLockElement(cell['data-rt-id'])); + buttons.unshift(makeBookmarkElement(cell['data-rt-id'])); + elements.unshift(['DIV', {'class': 'cp-app-poll-table-buttons'}, buttons]); } return ['TD', {}, elements]; }