From 69e18a48da62cb2efe1646603235825b6bde8133 Mon Sep 17 00:00:00 2001 From: yflory Date: Tue, 15 Dec 2020 13:09:02 +0100 Subject: [PATCH 01/17] Admin support UI --- customize.dist/src/less2/include/support.less | 2 +- www/admin/app-admin.less | 23 +++- www/admin/inner.js | 118 ++++++++++++++---- 3 files changed, 119 insertions(+), 24 deletions(-) diff --git a/customize.dist/src/less2/include/support.less b/customize.dist/src/less2/include/support.less index d83746b51..105599ada 100644 --- a/customize.dist/src/less2/include/support.less +++ b/customize.dist/src/less2/include/support.less @@ -78,7 +78,7 @@ } &.cp-support-list-closed { .cp-support-list-actions { - display: block !important; + display: flex !important; .cp-support-answer, .cp-support-close { display: none; } diff --git a/www/admin/app-admin.less b/www/admin/app-admin.less index 651e9dddd..aad6ec0e7 100644 --- a/www/admin/app-admin.less +++ b/www/admin/app-admin.less @@ -62,11 +62,19 @@ .cp-support-container { display: flex; - flex-flow: column; + flex-wrap: wrap; + .cp-support-column { + min-width: 700px; + flex: 1 0 50%; + } } .cp-support-list-actions { margin: 10px 0px 10px 2px; + .cp-support-close { + order: 20; + margin-left: auto !important; + } } .cp-support-list-ticket:not(.cp-support-list-closed) { @@ -89,6 +97,19 @@ } } } + .cp-support-list-ticket:not(.cp-support-open) { + & > :not(h2):not(.cp-support-open-button) { + display: none; + } + .cp-support-list-actions .cp-support-collapse { + display: none; + } + } + .cp-support-list-ticket.cp-support-open { + .cp-support-open-button { + display: none; + } + } .cp-support-fromadmin { color: @colortheme_logo-2; diff --git a/www/admin/inner.js b/www/admin/inner.js index 955ba4faf..17f7f1ff4 100644 --- a/www/admin/inner.js +++ b/www/admin/inner.js @@ -552,7 +552,24 @@ define([ var $div = $(h('div.cp-support-container')).appendTo($container); var catContainer = h('div.cp-dropdown-container'); - $div.append(catContainer); + Messages.admin_support_premium = "Premium tickets"; // XXX + Messages.admin_support_normal = "Unanswered tickets"; + Messages.admin_support_answered = "Answered tickets"; + Messages.admin_support_closed = "Closed tickets"; + Messages.admin_support_open = "Show ticket"; + Messages.admin_support_collapse = "Collapse ticket"; + var col1 = h('div.cp-support-column', h('h1', Messages.admin_support_premium)); + var col2 = h('div.cp-support-column', h('h1', Messages.admin_support_normal)); + var col3 = h('div.cp-support-column', h('h1', Messages.admin_support_answered)); + var col4 = h('div.cp-support-column', h('h1', Messages.admin_support_closed)); + var $col1 = $(col1), $col2 = $(col2), $col3 = $(col3), $col4 = $(col4); + $div.append([ + //catContainer + col1, + col2, + col3, + col4 + ]); var category = 'all'; var $drop = APP.support.makeCategoryDropdown(catContainer, function (key) { category = key; @@ -572,34 +589,90 @@ define([ var hashesById = {}; + var getTicketData = function (id) { + var t = hashesById[id]; + if (!Array.isArray(t) || !t.length) { return; } + var ed = Util.find(t[0], ['content', 'msg', 'content', 'sender', 'edPublic']); + // If one of their ticket was sent as a premium user, mark them as premium + var premium = t.some(function (msg) { + var _ed = Util.find(msg, ['content', 'msg', 'content', 'sender', 'edPublic']); + if (ed !== _ed) { return; } + return Util.find(t[0], ['content', 'msg', 'content', 'sender', 'plan']); + }); + var lastMsg = t[t.length - 1]; + var lastMsgEd = Util.find(lastMsg, ['content', 'msg', 'content', 'sender', 'edPublic']); + return { + lastMsg: lastMsg, + time: Util.find(lastMsg, ['content', 'msg', 'content', 'time']), + lastMsgEd: lastMsgEd, + lastAdmin: lastMsgEd !== ed && ApiConfig.adminKeys.indexOf(lastMsgEd) !== -1, + premium: premium, + authorEd: ed, + closed: Util.find(lastMsg, ['content', 'msg', 'type']) === 'CLOSE' + }; + }; + + var makeOpenButton = function ($ticket) { + var button = h('button.btn.btn-primary', Messages.admin_support_open); + var collapse = h('button.btn.cp-support-collapse', Messages.admin_support_collapse); + $(button).click(function () { + $ticket.toggleClass('cp-support-open', true); + }); + $(collapse).click(function () { + $ticket.toggleClass('cp-support-open', false); + }); + $ticket.append(h('div.cp-support-open-button', button)); + $ticket.find('.cp-support-list-actions').append(collapse); + }; + + var sort = function (id1, id2) { + var t1 = getTicketData(id1); + var t2 = getTicketData(id2); + if (!t1) { return 1; } + if (!t2) { return -1; } + /* + // If one is answered and not the other, put the unanswered first + if (t1.lastAdmin && !t2.lastAdmin) { return 1; } + if (!t1.lastAdmin && t2.lastAdmin) { return -1; } + */ + // Otherwise, sort them by time + return t1.time - t2.time; + }; + var reorder = function () { - var order = Object.keys(hashesById); - order.sort(function (id1, id2) { - var t1 = hashesById[id1]; - var t2 = hashesById[id2]; - if (!Array.isArray(t1)) { return 1; } - if (!Array.isArray(t2)) { return -1; } - var lastMsg1 = t1[t1.length - 1]; - var lastMsg2 = t2[t2.length - 1]; - var time1 = Util.find(lastMsg1, ['content', 'msg', 'content', 'time']); - var time2 = Util.find(lastMsg2, ['content', 'msg', 'content', 'time']); - var authorEd1 = Util.find(lastMsg1, ['content', 'msg', 'content', 'sender', 'edPublic']); - var authorEd2 = Util.find(lastMsg2, ['content', 'msg', 'content', 'sender', 'edPublic']); - var admin1 = ApiConfig.adminKeys.indexOf(authorEd1) !== -1; - var admin2 = ApiConfig.adminKeys.indexOf(authorEd2) !== -1; - // If one is answered and not the other, put the unanswered first - if (admin1 && !admin2) { return 1; } - if (!admin1 && admin2) { return -1; } - // Otherwise, sort them by time - return time2 - time1; + var orderAnswered = Object.keys(hashesById).filter(function (id) { + var d = getTicketData(id); + return d && d.lastAdmin && !d.closed; + }).sort(sort); + var orderPremium = Object.keys(hashesById).filter(function (id) { + var d = getTicketData(id); + return d && d.premium && !d.lastAdmin && !d.closed; + }).sort(sort); + var orderNormal = Object.keys(hashesById).filter(function (id) { + var d = getTicketData(id); + return d && !d.premium && !d.lastAdmin && !d.closed; + }).sort(sort); + var orderClosed = Object.keys(hashesById).filter(function (id) { + var d = getTicketData(id); + return d && d.closed; + }).sort(sort); + orderAnswered.forEach(function (id, i) { + $div.find('[data-id="'+id+'"]').css('order', i).appendTo($col3); + }); + orderPremium.forEach(function (id, i) { + $div.find('[data-id="'+id+'"]').css('order', i).appendTo($col1); + }); + orderNormal.forEach(function (id, i) { + $div.find('[data-id="'+id+'"]').css('order', i).appendTo($col2); }); - order.forEach(function (id, i) { - $div.find('[data-id="'+id+'"]').css('order', i); + orderClosed.forEach(function (id, i) { + $div.find('[data-id="'+id+'"]').css('order', i).appendTo($col4); }); }; var to = Util.throttle(function () { var $ticket = $div.find('.cp-support-list-ticket[data-id="'+linkedId+'"]'); + $ticket.addClass('cp-support-open'); $ticket[0].scrollIntoView(); linkedId = undefined; }, 100); @@ -657,6 +730,7 @@ define([ UI.alert(Messages.error); }); }); + makeOpenButton($ticket); if (category !== 'all' && $ticket.attr('data-cat') !== category) { $ticket.hide(); } From b2ca3fa4483dea1ae25ce8790233a9e958dd7962 Mon Sep 17 00:00:00 2001 From: yflory Date: Tue, 15 Dec 2020 14:01:54 +0100 Subject: [PATCH 02/17] More admin support panel UI --- www/admin/app-admin.less | 23 +++++++++++++-- www/admin/inner.js | 60 ++++++++++++++++++++++++++++------------ www/support/ui.js | 2 +- 3 files changed, 63 insertions(+), 22 deletions(-) diff --git a/www/admin/app-admin.less b/www/admin/app-admin.less index aad6ec0e7..faed46bf4 100644 --- a/www/admin/app-admin.less +++ b/www/admin/app-admin.less @@ -77,6 +77,20 @@ } } + .cp-support-list-ticket { + h2 { + font-size: 1.5rem; + display: flex; + justify-content: space-between; + align-items: center; + } + .cp-support-collapsed { + display: flex; + justify-content: space-between; + flex-wrap: wrap; + } + } + .cp-support-list-ticket:not(.cp-support-list-closed) { .cp-support-list-message { &:last-child:not(.cp-support-fromadmin) { @@ -98,15 +112,18 @@ } } .cp-support-list-ticket:not(.cp-support-open) { - & > :not(h2):not(.cp-support-open-button) { + & > :not(h2):not(.cp-support-collapsed) { display: none; } - .cp-support-list-actions .cp-support-collapse { + .cp-support-collapse { display: none; } } .cp-support-list-ticket.cp-support-open { - .cp-support-open-button { + .cp-support-collapsed { + display: none; + } + .cp-support-expand { display: none; } } diff --git a/www/admin/inner.js b/www/admin/inner.js index 17f7f1ff4..c73fafa63 100644 --- a/www/admin/inner.js +++ b/www/admin/inner.js @@ -556,8 +556,10 @@ define([ Messages.admin_support_normal = "Unanswered tickets"; Messages.admin_support_answered = "Answered tickets"; Messages.admin_support_closed = "Closed tickets"; - Messages.admin_support_open = "Show ticket"; - Messages.admin_support_collapse = "Collapse ticket"; + Messages.admin_support_open = "Show"; + Messages.admin_support_collapse = "Collapse"; + Messages.admin_support_first = "Created on: "; + Messages.admin_support_last = "Updated on: "; var col1 = h('div.cp-support-column', h('h1', Messages.admin_support_premium)); var col2 = h('div.cp-support-column', h('h1', Messages.admin_support_normal)); var col3 = h('div.cp-support-column', h('h1', Messages.admin_support_answered)); @@ -613,7 +615,7 @@ define([ }; var makeOpenButton = function ($ticket) { - var button = h('button.btn.btn-primary', Messages.admin_support_open); + var button = h('button.btn.btn-primary.cp-support-expand', Messages.admin_support_open); var collapse = h('button.btn.cp-support-collapse', Messages.admin_support_collapse); $(button).click(function () { $ticket.toggleClass('cp-support-open', true); @@ -621,8 +623,28 @@ define([ $(collapse).click(function () { $ticket.toggleClass('cp-support-open', false); }); - $ticket.append(h('div.cp-support-open-button', button)); - $ticket.find('.cp-support-list-actions').append(collapse); + $ticket.find('.cp-support-title-buttons').prepend([button, collapse]); + $ticket.append(h('div.cp-support-collapsed')); + }; + var updateTicketDetails = function ($ticket) { + console.log($ticket.find('.cp-support-message-from')); + var $first = $ticket.find('.cp-support-message-from').first(); + var user = $first.find('span').first().html(); + var time = $first.find('.cp-support-message-time').text(); + var last = $ticket.find('.cp-support-message-from').last().find('.cp-support-message-time').text(); + var $c = $ticket.find('.cp-support-collapsed'); + $c.html('').append([ + UI.setHTML(h('span'), user), + h('span', [ + h('b', Messages.admin_support_first), + h('span', time) + ]), + h('span', [ + h('b', Messages.admin_support_last), + h('span', last) + ]) + ]); + }; var sort = function (id1, id2) { @@ -639,7 +661,7 @@ define([ return t1.time - t2.time; }; - var reorder = function () { + var _reorder = function () { var orderAnswered = Object.keys(hashesById).filter(function (id) { var d = getTicketData(id); return d && d.lastAdmin && !d.closed; @@ -656,26 +678,28 @@ define([ var d = getTicketData(id); return d && d.closed; }).sort(sort); - orderAnswered.forEach(function (id, i) { - $div.find('[data-id="'+id+'"]').css('order', i).appendTo($col3); - }); - orderPremium.forEach(function (id, i) { - $div.find('[data-id="'+id+'"]').css('order', i).appendTo($col1); - }); - orderNormal.forEach(function (id, i) { - $div.find('[data-id="'+id+'"]').css('order', i).appendTo($col2); - }); - orderClosed.forEach(function (id, i) { - $div.find('[data-id="'+id+'"]').css('order', i).appendTo($col4); + var cols = [$col1, $col2, $col3, $col4]; + [orderPremium, orderNormal, orderAnswered, orderClosed].forEach(function (list, j) { + list.forEach(function (id, i) { + var $t = $div.find('[data-id="'+id+'"]'); + $t.css('order', i).appendTo(cols[j]); + updateTicketDetails($t); + }); + if (!list.length) { + cols[j].hide(); + } else { + cols[j].show(); + } }); }; + var reorder = Util.throttle(_reorder, 150); var to = Util.throttle(function () { var $ticket = $div.find('.cp-support-list-ticket[data-id="'+linkedId+'"]'); $ticket.addClass('cp-support-open'); $ticket[0].scrollIntoView(); linkedId = undefined; - }, 100); + }, 200); // Register to the "support" mailbox common.mailbox.subscribe(['supportadmin'], { diff --git a/www/support/ui.js b/www/support/ui.js index a58fdf170..17def8896 100644 --- a/www/support/ui.js +++ b/www/support/ui.js @@ -269,7 +269,7 @@ define([ 'data-cat': content.category, 'data-id': content.id }, [ - h('h2', [ticketCategory, ticketTitle, url]), + h('h2', [ticketCategory, ticketTitle, h('span.cp-support-title-buttons',url)]), actions ])); From 687bb36e0e0f1fbd10aebb54cdd7d90a764b1a05 Mon Sep 17 00:00:00 2001 From: yflory Date: Tue, 15 Dec 2020 14:07:07 +0100 Subject: [PATCH 03/17] Handle long title in support tickets --- www/admin/app-admin.less | 8 ++++++++ www/support/ui.js | 5 ++++- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/www/admin/app-admin.less b/www/admin/app-admin.less index faed46bf4..1fe7a5699 100644 --- a/www/admin/app-admin.less +++ b/www/admin/app-admin.less @@ -83,6 +83,14 @@ display: flex; justify-content: space-between; align-items: center; + span:first-child { + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + } + .cp-support-title-buttons { + flex-shrink: 0; + } } .cp-support-collapsed { display: flex; diff --git a/www/support/ui.js b/www/support/ui.js index 17def8896..4ce6ec4e2 100644 --- a/www/support/ui.js +++ b/www/support/ui.js @@ -269,7 +269,10 @@ define([ 'data-cat': content.category, 'data-id': content.id }, [ - h('h2', [ticketCategory, ticketTitle, h('span.cp-support-title-buttons',url)]), + h('h2', [ + h('span', [ticketCategory, ticketTitle]), + h('span.cp-support-title-buttons',url) + ]), actions ])); From b1bf592265fb935aa7879e7506889f66163a5fdc Mon Sep 17 00:00:00 2001 From: yflory Date: Tue, 15 Dec 2020 14:15:25 +0100 Subject: [PATCH 04/17] Make it easier to open a ticket --- www/admin/app-admin.less | 1 + www/admin/inner.js | 14 ++++++++++++-- www/common/common-interface.js | 6 ++++-- 3 files changed, 17 insertions(+), 4 deletions(-) diff --git a/www/admin/app-admin.less b/www/admin/app-admin.less index 1fe7a5699..fe9121090 100644 --- a/www/admin/app-admin.less +++ b/www/admin/app-admin.less @@ -126,6 +126,7 @@ .cp-support-collapse { display: none; } + cursor: pointer; } .cp-support-list-ticket.cp-support-open { .cp-support-collapsed { diff --git a/www/admin/inner.js b/www/admin/inner.js index c73fafa63..bf139a870 100644 --- a/www/admin/inner.js +++ b/www/admin/inner.js @@ -614,20 +614,30 @@ define([ }; }; + var addClickHandler = function ($ticket) { + $ticket.on('click', function () { + $ticket.toggleClass('cp-support-open', true); + $ticket.off('click'); + }); + }; var makeOpenButton = function ($ticket) { var button = h('button.btn.btn-primary.cp-support-expand', Messages.admin_support_open); var collapse = h('button.btn.cp-support-collapse', Messages.admin_support_collapse); $(button).click(function () { $ticket.toggleClass('cp-support-open', true); }); - $(collapse).click(function () { + addClickHandler($ticket); + $(collapse).click(function (e) { $ticket.toggleClass('cp-support-open', false); + e.stopPropagation(); + setTimeout(function () { + addClickHandler($ticket); + }); }); $ticket.find('.cp-support-title-buttons').prepend([button, collapse]); $ticket.append(h('div.cp-support-collapsed')); }; var updateTicketDetails = function ($ticket) { - console.log($ticket.find('.cp-support-message-from')); var $first = $ticket.find('.cp-support-message-from').first(); var user = $first.find('span').first().html(); var time = $first.find('.cp-support-message-time').text(); diff --git a/www/common/common-interface.js b/www/common/common-interface.js index 3e9d848cd..bb84187b4 100644 --- a/www/common/common-interface.js +++ b/www/common/common-interface.js @@ -774,7 +774,8 @@ define([ $(originalBtn).show(); }; - $button.click(function () { + $button.click(function (e) { + e.stopPropagation(); done(true); }); @@ -792,7 +793,8 @@ define([ to = setTimeout(todo, INTERVAL); }; - $(originalBtn).addClass('cp-button-confirm-placeholder').click(function () { + $(originalBtn).addClass('cp-button-confirm-placeholder').click(function (e) { + e.stopPropagation(); // If we have a validation function, continue only if it's true if (config.validate && !config.validate()) { return; } i = 1; From a31394888d60d753bfcbf5c2f013d1b16371e904 Mon Sep 17 00:00:00 2001 From: yflory Date: Tue, 15 Dec 2020 16:49:52 +0100 Subject: [PATCH 05/17] Don't open ticket when copying its url --- www/support/ui.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/www/support/ui.js b/www/support/ui.js index 4ce6ec4e2..8a90446bb 100644 --- a/www/support/ui.js +++ b/www/support/ui.js @@ -258,7 +258,8 @@ define([ if (ctx.isAdmin) { ticketCategory = Messages['support_cat_'+(content.category || 'all')] + ' - '; url = h('button.btn.btn-primary.fa.fa-clipboard'); - $(url).click(function () { + $(url).click(function (e) { + e.stopPropagation(); var link = privateData.origin + privateData.pathname + '#' + 'support-' + content.id; var success = Clipboard.copy(link); if (success) { UI.log(Messages.shareSuccess); } From a918dd4f7d5047887d8c36b7665be428cad1444e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Benqu=C3=A9?= Date: Tue, 15 Dec 2020 16:10:26 +0000 Subject: [PATCH 06/17] Change copy button style in support ticket --- www/support/ui.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/www/support/ui.js b/www/support/ui.js index 8a90446bb..2b07dc346 100644 --- a/www/support/ui.js +++ b/www/support/ui.js @@ -257,7 +257,7 @@ define([ var url; if (ctx.isAdmin) { ticketCategory = Messages['support_cat_'+(content.category || 'all')] + ' - '; - url = h('button.btn.btn-primary.fa.fa-clipboard'); + url = h('button.btn.fa.fa-clipboard'); $(url).click(function (e) { e.stopPropagation(); var link = privateData.origin + privateData.pathname + '#' + 'support-' + content.id; From 17d9284a4c077422030958468f6765e33693769b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Benqu=C3=A9?= Date: Tue, 15 Dec 2020 16:10:54 +0000 Subject: [PATCH 07/17] Show full ticket title when opened --- www/admin/app-admin.less | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/www/admin/app-admin.less b/www/admin/app-admin.less index a7efc2dad..7ffc2a062 100644 --- a/www/admin/app-admin.less +++ b/www/admin/app-admin.less @@ -85,12 +85,7 @@ font-size: 1.5rem; display: flex; justify-content: space-between; - align-items: center; - span:first-child { - overflow: hidden; - text-overflow: ellipsis; - white-space: nowrap; - } + align-items: top; .cp-support-title-buttons { flex-shrink: 0; } @@ -123,6 +118,11 @@ } } .cp-support-list-ticket:not(.cp-support-open) { + span:first-child { + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + } & > :not(h2):not(.cp-support-collapsed) { display: none; } From e936045b7d1489d1c41b9a5b97abec6a098191f2 Mon Sep 17 00:00:00 2001 From: yflory Date: Wed, 16 Dec 2020 11:29:12 +0100 Subject: [PATCH 08/17] More support panel improvements --- www/admin/app-admin.less | 16 +++++++++++++++ www/admin/inner.js | 42 ++++++++++++++++++++++++++++++++-------- www/support/ui.js | 2 +- 3 files changed, 51 insertions(+), 9 deletions(-) diff --git a/www/admin/app-admin.less b/www/admin/app-admin.less index 7ffc2a062..7f8f2416c 100644 --- a/www/admin/app-admin.less +++ b/www/admin/app-admin.less @@ -69,6 +69,21 @@ .cp-support-column { min-width: 700px; flex: 1 0 50%; + h1 { + display: flex; + align-items: center; + button { + margin-left: 50px !important; + } + } + .cp-support-count { + margin-left: 10px; + } + &.cp-support-column-collapsed { + .cp-support-list-ticket { + display: none; + } + } } } @@ -94,6 +109,7 @@ display: flex; justify-content: space-between; flex-wrap: wrap; + color: #666; } } diff --git a/www/admin/inner.js b/www/admin/inner.js index bf139a870..afd743911 100644 --- a/www/admin/inner.js +++ b/www/admin/inner.js @@ -552,18 +552,34 @@ define([ var $div = $(h('div.cp-support-container')).appendTo($container); var catContainer = h('div.cp-dropdown-container'); - Messages.admin_support_premium = "Premium tickets"; // XXX - Messages.admin_support_normal = "Unanswered tickets"; - Messages.admin_support_answered = "Answered tickets"; - Messages.admin_support_closed = "Closed tickets"; + Messages.admin_support_premium = "Premium tickets:"; // XXX + Messages.admin_support_normal = "Unanswered tickets:"; + Messages.admin_support_answered = "Answered tickets:"; + Messages.admin_support_closed = "Closed tickets:"; Messages.admin_support_open = "Show"; Messages.admin_support_collapse = "Collapse"; Messages.admin_support_first = "Created on: "; Messages.admin_support_last = "Updated on: "; - var col1 = h('div.cp-support-column', h('h1', Messages.admin_support_premium)); - var col2 = h('div.cp-support-column', h('h1', Messages.admin_support_normal)); - var col3 = h('div.cp-support-column', h('h1', Messages.admin_support_answered)); - var col4 = h('div.cp-support-column', h('h1', Messages.admin_support_closed)); + var col1 = h('div.cp-support-column', h('h1', [ + h('span', Messages.admin_support_premium), + h('span.cp-support-count'), + h('button.btn.cp-support-column-button', Messages.admin_support_collapse) + ])); + var col2 = h('div.cp-support-column', h('h1', [ + h('span', Messages.admin_support_normal), + h('span.cp-support-count'), + h('button.btn.cp-support-column-button', Messages.admin_support_collapse) + ])); + var col3 = h('div.cp-support-column', h('h1', [ + h('span', Messages.admin_support_answered), + h('span.cp-support-count'), + h('button.btn.cp-support-column-button', Messages.admin_support_collapse) + ])); + var col4 = h('div.cp-support-column', h('h1', [ + h('span', Messages.admin_support_closed), + h('span.cp-support-count'), + h('button.btn.cp-support-column-button', Messages.admin_support_collapse) + ])); var $col1 = $(col1), $col2 = $(col2), $col3 = $(col3), $col4 = $(col4); $div.append([ //catContainer @@ -572,6 +588,15 @@ define([ col3, col4 ]); + $div.find('.cp-support-column-button').click(function (e) { + var $col = $(this).closest('.cp-support-column'); + $col.toggleClass('cp-support-column-collapsed'); + if ($col.hasClass('cp-support-column-collapsed')) { + $(this).text(Messages.admin_support_open); + } else { + $(this).text(Messages.admin_support_collapse); + } + }); var category = 'all'; var $drop = APP.support.makeCategoryDropdown(catContainer, function (key) { category = key; @@ -699,6 +724,7 @@ define([ cols[j].hide(); } else { cols[j].show(); + cols[j].find('.cp-support-count').text(list.length); } }); }; diff --git a/www/support/ui.js b/www/support/ui.js index 2b07dc346..6fd118d0d 100644 --- a/www/support/ui.js +++ b/www/support/ui.js @@ -230,7 +230,7 @@ define([ var form = h('div.cp-support-form-container', content); $(cancel).click(function () { - $(form).closest('.cp-support-list-ticket').find('.cp-support-list-actions').show(); + $(form).closest('.cp-support-list-ticket').find('.cp-support-list-actions').css('display', ''); $(form).remove(); }); From 54d46015de027a696a91ec4b626773b2cf786fb0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Benqu=C3=A9?= Date: Wed, 16 Dec 2020 10:46:05 +0000 Subject: [PATCH 09/17] Toggle support section button --- www/admin/inner.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/www/admin/inner.js b/www/admin/inner.js index afd743911..83ad814d6 100644 --- a/www/admin/inner.js +++ b/www/admin/inner.js @@ -593,8 +593,10 @@ define([ $col.toggleClass('cp-support-column-collapsed'); if ($col.hasClass('cp-support-column-collapsed')) { $(this).text(Messages.admin_support_open); + $(this).toggleClass('btn-primary'); } else { $(this).text(Messages.admin_support_collapse); + $(this).toggleClass('btn-primary'); } }); var category = 'all'; From 7fc60d90022be1d4678b5550b6f93f21f20ed9e5 Mon Sep 17 00:00:00 2001 From: yflory Date: Wed, 16 Dec 2020 12:17:20 +0100 Subject: [PATCH 10/17] Show premium tickets when they're collapsed --- www/admin/app-admin.less | 5 +++++ www/admin/inner.js | 8 +++++--- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/www/admin/app-admin.less b/www/admin/app-admin.less index 7f8f2416c..9f2c950a0 100644 --- a/www/admin/app-admin.less +++ b/www/admin/app-admin.less @@ -110,6 +110,11 @@ justify-content: space-between; flex-wrap: wrap; color: #666; + .cp-support-ispremium { + padding: 0 5px; + color: @colortheme_cp-red; + background-color: lighten(@colortheme_cp-red, 25%); + } } } diff --git a/www/admin/inner.js b/www/admin/inner.js index afd743911..cd4d068d7 100644 --- a/www/admin/inner.js +++ b/www/admin/inner.js @@ -662,14 +662,15 @@ define([ $ticket.find('.cp-support-title-buttons').prepend([button, collapse]); $ticket.append(h('div.cp-support-collapsed')); }; - var updateTicketDetails = function ($ticket) { + var updateTicketDetails = function ($ticket, isPremium) { var $first = $ticket.find('.cp-support-message-from').first(); var user = $first.find('span').first().html(); var time = $first.find('.cp-support-message-time').text(); var last = $ticket.find('.cp-support-message-from').last().find('.cp-support-message-time').text(); var $c = $ticket.find('.cp-support-collapsed'); + var txtClass = isPremium ? ".cp-support-ispremium" : ""; $c.html('').append([ - UI.setHTML(h('span'), user), + UI.setHTML(h('span'+ txtClass), user), h('span', [ h('b', Messages.admin_support_first), h('span', time) @@ -717,8 +718,9 @@ define([ [orderPremium, orderNormal, orderAnswered, orderClosed].forEach(function (list, j) { list.forEach(function (id, i) { var $t = $div.find('[data-id="'+id+'"]'); + var d = getTicketData(id); $t.css('order', i).appendTo(cols[j]); - updateTicketDetails($t); + updateTicketDetails($t, d.premium); }); if (!list.length) { cols[j].hide(); From dc44d8f33cadc88e5d81bef152234c5e49281cc4 Mon Sep 17 00:00:00 2001 From: yflory Date: Wed, 16 Dec 2020 12:18:18 +0100 Subject: [PATCH 11/17] lint compliance --- www/admin/inner.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/www/admin/inner.js b/www/admin/inner.js index d549c514b..eabd997ff 100644 --- a/www/admin/inner.js +++ b/www/admin/inner.js @@ -588,7 +588,7 @@ define([ col3, col4 ]); - $div.find('.cp-support-column-button').click(function (e) { + $div.find('.cp-support-column-button').click(function () { var $col = $(this).closest('.cp-support-column'); $col.toggleClass('cp-support-column-collapsed'); if ($col.hasClass('cp-support-column-collapsed')) { From b7ea099eabdfee58f48c59456cb7ff53e7e1a12a Mon Sep 17 00:00:00 2001 From: ansuz Date: Mon, 21 Dec 2020 15:02:13 +0530 Subject: [PATCH 12/17] re-enable indexedDB cache for testing --- www/common/outer/async-store.js | 4 ++-- www/common/outer/sharedfolder.js | 2 +- www/common/outer/team.js | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/www/common/outer/async-store.js b/www/common/outer/async-store.js index 2c008a09e..717097b32 100644 --- a/www/common/outer/async-store.js +++ b/www/common/outer/async-store.js @@ -1631,7 +1631,7 @@ define([ Store.leavePad(null, data, function () {}); }; var conf = { - //Cache: Cache, // XXX re-enable cache usage + Cache: Cache, // XXX re-enable cache usage onCacheStart: function () { postMessage(clientId, "PAD_CACHE"); }, @@ -2686,7 +2686,7 @@ define([ readOnly: false, validateKey: secret.keys.validateKey || undefined, crypto: Crypto.createEncryptor(secret.keys), - //Cache: Cache, // XXX re-enable cache usage + Cache: Cache, // XXX re-enable cache usage userName: 'fs', logLevel: 1, ChainPad: ChainPad, diff --git a/www/common/outer/sharedfolder.js b/www/common/outer/sharedfolder.js index 518367826..2ac98cdb7 100644 --- a/www/common/outer/sharedfolder.js +++ b/www/common/outer/sharedfolder.js @@ -175,7 +175,7 @@ define([ ChainPad: ChainPad, classic: true, network: network, - //Cache: Cache, // XXX re-enable cache usage + Cache: Cache, // XXX re-enable cache usage metadata: { validateKey: secret.keys.validateKey || undefined, owners: owners diff --git a/www/common/outer/team.js b/www/common/outer/team.js index 38e83608a..1099b4de7 100644 --- a/www/common/outer/team.js +++ b/www/common/outer/team.js @@ -427,7 +427,7 @@ define([ channel: secret.channel, crypto: crypto, ChainPad: ChainPad, - //Cache: Cache, // XXX re-enable cache usage + Cache: Cache, // XXX re-enable cache usage metadata: { validateKey: secret.keys.validateKey || undefined, }, From 7e1c7c481e3d0221a1b6233a2e4eb7aa17a6f54d Mon Sep 17 00:00:00 2001 From: yflory Date: Mon, 21 Dec 2020 15:15:08 +0100 Subject: [PATCH 13/17] Fix support panel UI issue --- www/support/ui.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/www/support/ui.js b/www/support/ui.js index 6fd118d0d..b85197f63 100644 --- a/www/support/ui.js +++ b/www/support/ui.js @@ -307,7 +307,7 @@ define([ var form = makeForm(ctx, function () { var sent = sendForm(ctx, content.id, form, content.sender); if (sent) { - $(actions).show(); + $(actions).css('display', ''); $(form).remove(); } }, content.title); From 9f02df0b314b29937b5bfb219dcd24063d3eca77 Mon Sep 17 00:00:00 2001 From: yflory Date: Mon, 21 Dec 2020 16:02:53 +0100 Subject: [PATCH 14/17] Correctly move tickets after closing them --- www/admin/app-admin.less | 10 ++++++---- www/admin/inner.js | 8 +++++++- 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/www/admin/app-admin.less b/www/admin/app-admin.less index 9f2c950a0..77e13af43 100644 --- a/www/admin/app-admin.less +++ b/www/admin/app-admin.less @@ -89,10 +89,6 @@ .cp-support-list-actions { margin: 10px 0px 10px 2px; - .cp-support-close { - order: 20; - margin-left: auto !important; - } } .cp-support-list-ticket { @@ -119,6 +115,12 @@ } .cp-support-list-ticket:not(.cp-support-list-closed) { + .cp-support-list-actions { + .cp-button-confirm, .cp-support-close { + order: 20; + margin-left: auto !important; + } + } .cp-support-list-message { &:last-child:not(.cp-support-fromadmin) { color: @colortheme_cp-red; diff --git a/www/admin/inner.js b/www/admin/inner.js index eabd997ff..755b60ddc 100644 --- a/www/admin/inner.js +++ b/www/admin/inner.js @@ -767,6 +767,7 @@ define([ if (!$ticket.length) { return; } $ticket.addClass('cp-support-list-closed'); $ticket.append(APP.support.makeCloseMessage(content, hash)); + reorder(); return; } if (msg.type !== 'TICKET') { return; } @@ -787,7 +788,12 @@ define([ })); }); }).nThen(function () { - if (!error) { return void $ticket.remove(); } + if (!error) { + $ticket.remove(); + delete hashesById[id]; + reorder(); + return; + } // if deletion failed then reactivate the button and warn hideButton.removeAttribute('disabled'); // and show a generic error message From 8cb19cdc764371b7de70661e0da9f50280a18f26 Mon Sep 17 00:00:00 2001 From: yflory Date: Wed, 23 Dec 2020 11:55:54 +0100 Subject: [PATCH 15/17] Fix invalid LKH in roster --- www/common/outer/roster.js | 18 +++++++++++++----- www/common/outer/team.js | 6 +++++- 2 files changed, 18 insertions(+), 6 deletions(-) diff --git a/www/common/outer/roster.js b/www/common/outer/roster.js index 2c2675037..7dbf544c2 100644 --- a/www/common/outer/roster.js +++ b/www/common/outer/roster.js @@ -1,5 +1,5 @@ (function () { -var factory = function (Util, Hash, CPNetflux, Sortify, nThen, Crypto) { +var factory = function (Util, Hash, CPNetflux, Sortify, nThen, Crypto, Feedback) { var Roster = {}; // this constant is somewhat arbitrary. @@ -587,6 +587,11 @@ var factory = function (Util, Hash, CPNetflux, Sortify, nThen, Crypto) { // deleted while you are open // emit an event var onChannelError = function (info) { + Feedback.send('ROSTER_CHANNEL_ERROR='+info.type); + if (info.type === "EUNKNOWN") { + // chainpad-netflux should recover by itself + return; + } if (!ready) { return void cb(info); } console.error("CHANNEL_ERROR", info); }; @@ -870,7 +875,8 @@ var factory = function (Util, Hash, CPNetflux, Sortify, nThen, Crypto) { require("../../bower_components/chainpad-netflux/chainpad-netflux.js"), require("../../bower_components/json.sortify"), require("nthen"), - require("../../bower_components/chainpad-crypto/crypto") + require("../../bower_components/chainpad-crypto/crypto"), + null // no feedback here ); } else if ((typeof(define) !== 'undefined' && define !== null) && (define.amd !== null)) { require.config({ paths: { 'json.sortify': '/bower_components/json.sortify/dist/JSON.sortify' } }); @@ -880,16 +886,18 @@ var factory = function (Util, Hash, CPNetflux, Sortify, nThen, Crypto) { '/bower_components/chainpad-netflux/chainpad-netflux.js', 'json.sortify', '/bower_components/nthen/index.js', - '/bower_components/chainpad-crypto/crypto.js' + '/bower_components/chainpad-crypto/crypto.js', + '/common/common-feedback.js', //'/bower_components/tweetnacl/nacl-fast.min.js', - ], function (Util, Hash, CPNF, Sortify, nThen, Crypto) { + ], function (Util, Hash, CPNF, Sortify, nThen, Crypto, Feedback) { return factory.apply(null, [ Util, Hash, CPNF, Sortify, nThen, - Crypto + Crypto, + Feedback ]); }); } else { diff --git a/www/common/outer/team.js b/www/common/outer/team.js index 1099b4de7..26bd32f3c 100644 --- a/www/common/outer/team.js +++ b/www/common/outer/team.js @@ -1796,7 +1796,11 @@ define([ teams[id].keys.mailbox = deriveMailbox(teams[id]); } openChannel(ctx, teams[id], id, waitFor(function (err) { - if (err) { return void console.error(err); } + if (err) { + var txt = typeof(err) === "string" ? err : (err.type || err.message); + Feedback.send("TEAM_LOADING_ERROR="+txt); + return void console.error(err); + } console.debug('Team '+id+' ready'); })); }); From 32669dc099b6e6d75d55c677b54c6934292cd0bf Mon Sep 17 00:00:00 2001 From: yflory Date: Wed, 23 Dec 2020 12:00:17 +0100 Subject: [PATCH 16/17] Fix type error --- www/common/outer/roster.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/www/common/outer/roster.js b/www/common/outer/roster.js index 7dbf544c2..72f343477 100644 --- a/www/common/outer/roster.js +++ b/www/common/outer/roster.js @@ -587,8 +587,8 @@ var factory = function (Util, Hash, CPNetflux, Sortify, nThen, Crypto, Feedback) // deleted while you are open // emit an event var onChannelError = function (info) { - Feedback.send('ROSTER_CHANNEL_ERROR='+info.type); - if (info.type === "EUNKNOWN") { + if (Feedback) { Feedback.send('ROSTER_CHANNEL_ERROR='+(info && info.type)); } + if (info && info.type === "EUNKNOWN") { // chainpad-netflux should recover by itself return; } From 31b2a5e4fe96c0590a7264a480ffabe2d7589cb6 Mon Sep 17 00:00:00 2001 From: ansuz Date: Thu, 24 Dec 2020 15:01:38 +0530 Subject: [PATCH 17/17] update chainpad-crypto dependency to fetch via https --- package-lock.json | 14 +++++++------- package.json | 6 +++--- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/package-lock.json b/package-lock.json index 775f42f68..2c64d8307 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "cryptpad", - "version": "3.24.0", + "version": "3.25.0", "lockfileVersion": 1, "requires": true, "dependencies": { @@ -181,16 +181,16 @@ "optional": true }, "chainpad-crypto": { - "version": "0.2.4", - "resolved": "https://registry.npmjs.org/chainpad-crypto/-/chainpad-crypto-0.2.4.tgz", - "integrity": "sha512-fWbVyeAv35vf/dkkQaefASlJcEfpEvfRI23Mtn+/TBBry7+LYNuJMXJiovVY35pfyw2+trKh1Py5Asg9vrmaVg==", + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/chainpad-crypto/-/chainpad-crypto-0.2.5.tgz", + "integrity": "sha512-K9vRsAspuX+uU1goXPz0CawpLIaOHq+1JP3WfDLqaz67LbCX/MLIUt9aMcSeIJcwZ9uMpqnbMGRktyVPoz6MCA==", "requires": { - "tweetnacl": "git://github.com/dchest/tweetnacl-js.git#v0.12.2" + "tweetnacl": "git+https://github.com/dchest/tweetnacl-js.git#v0.12.2" }, "dependencies": { "tweetnacl": { - "version": "git://github.com/dchest/tweetnacl-js.git#8a21381d696acdc4e99c9f706f1ad23285795f79", - "from": "git://github.com/dchest/tweetnacl-js.git#v0.12.2" + "version": "git+https://github.com/dchest/tweetnacl-js.git#8a21381d696acdc4e99c9f706f1ad23285795f79", + "from": "git+https://github.com/dchest/tweetnacl-js.git#v0.12.2" } } }, diff --git a/package.json b/package.json index 37fd6c686..86c7fc67b 100644 --- a/package.json +++ b/package.json @@ -1,11 +1,11 @@ { "name": "cryptpad", "description": "realtime collaborative visual editor with zero knowlege server", - "version": "3.24.0", + "version": "3.25.0", "license": "AGPL-3.0+", "repository": { "type": "git", - "url": "git://github.com/xwiki-labs/cryptpad.git" + "url": "git+https://github.com/xwiki-labs/cryptpad.git" }, "funding": { "type": "opencollective", @@ -13,7 +13,7 @@ }, "dependencies": { "@mcrowe/minibloom": "^0.2.0", - "chainpad-crypto": "^0.2.2", + "chainpad-crypto": "^0.2.5", "chainpad-server": "^4.0.9", "express": "~4.16.0", "fs-extra": "^7.0.0",