From db3a3c68373a0c5bc1f56718c3da197b83f4f4fe Mon Sep 17 00:00:00 2001 From: Utkarsh Barsaiyan Date: Tue, 2 Jul 2019 04:13:47 +0530 Subject: [PATCH] WIP --- .../imports/components/contextual-bar.css | 158 +++++++++--------- app/theme/client/imports/general/base.css | 4 - app/webdav/client/index.js | 1 + .../client/startup/messageBoxActions.js | 3 +- app/webdav/client/webdavFilePicker.css | 134 +++++++++++++++ app/webdav/client/webdavFilePicker.html | 91 +++++++--- app/webdav/client/webdavFilePicker.js | 109 +++++++++--- 7 files changed, 368 insertions(+), 132 deletions(-) create mode 100644 app/webdav/client/webdavFilePicker.css diff --git a/app/theme/client/imports/components/contextual-bar.css b/app/theme/client/imports/components/contextual-bar.css index 81659afb9a244..9c53099942d43 100644 --- a/app/theme/client/imports/components/contextual-bar.css +++ b/app/theme/client/imports/components/contextual-bar.css @@ -163,123 +163,125 @@ } } -.attachments { - &__item { - position: relative; +.flex-tab__result { + .attachments { + &__item { + position: relative; - margin-bottom: 10px; + margin-bottom: 10px; - transition: background-color 300ms linear; + transition: background-color 300ms linear; - &.active, - &:hover { - cursor: pointer; + &.active, + &:hover { + cursor: pointer; - background-color: #f7f8fa; + background-color: #f7f8fa; - .attachments-menu { - display: inline-block; + .attachments-menu { + display: inline-block; + } } - } - &-link { - display: flex; - flex-direction: row; + &-link { + display: flex; + flex-direction: row; - padding: 8px 0; - align-items: center; + padding: 8px 0; + align-items: center; + } } - } - &__file, - &__thumb { - display: inline-block; - display: flex; - flex-direction: column; - flex: 0 0 auto; + &__file, + &__thumb { + display: inline-block; + display: flex; + flex-direction: column; + flex: 0 0 auto; - width: 50px; + width: 50px; - height: 50px; - margin: 0 8px; + height: 50px; + margin: 0 8px; - border-radius: 2px; + border-radius: 2px; - background: radial-gradient(ellipse at center, rgba(155, 169, 186, 1) 0%, rgba(131, 143, 158, 1) 100%); - background-size: cover; + background: radial-gradient(ellipse at center, rgba(155, 169, 186, 1) 0%, rgba(131, 143, 158, 1) 100%); + background-size: cover; - font-size: 24px; + font-size: 24px; - align-items: center; - justify-content: center; - } - - &__file { - &--pdf { - background: radial-gradient(ellipse at center, rgba(250, 97, 97, 1) 0%, rgba(251, 19, 19, 1) 100%); + align-items: center; + justify-content: center; } - &--sheets { - background: radial-gradient(ellipse at center, rgba(0, 163, 82, 1) 0%, rgba(2, 114, 59, 1) 100%); - } + &__file { + &--pdf { + background: radial-gradient(ellipse at center, rgba(250, 97, 97, 1) 0%, rgba(251, 19, 19, 1) 100%); + } - &--ppt { - background: radial-gradient(ellipse at center, rgba(250, 109, 77, 1) 0%, rgba(208, 71, 40, 1) 100%); + &--sheets { + background: radial-gradient(ellipse at center, rgba(0, 163, 82, 1) 0%, rgba(2, 114, 59, 1) 100%); + } + + &--ppt { + background: radial-gradient(ellipse at center, rgba(250, 109, 77, 1) 0%, rgba(208, 71, 40, 1) 100%); + } } - } - &__type { - overflow: hidden; - flex: 0 0 auto; + &__type { + overflow: hidden; + flex: 0 0 auto; - max-width: 100%; - padding: 0 10px; + max-width: 100%; + padding: 0 10px; - text-overflow: ellipsis; + text-overflow: ellipsis; - color: white; + color: white; - font-size: 10px; - } + font-size: 10px; + } - &__name { + &__name { - overflow: hidden; + overflow: hidden; - min-width: 0; - margin: 0 8px; + min-width: 0; + margin: 0 8px; - white-space: nowrap; - text-overflow: ellipsis; + white-space: nowrap; + text-overflow: ellipsis; - color: #2f343d; + color: #2f343d; - font-size: 14px; - line-height: 1.5; - } + font-size: 14px; + line-height: 1.5; + } - &__details { - margin: 0 8px 2px; + &__details { + margin: 0 8px 2px; - white-space: nowrap; - text-overflow: ellipsis; + white-space: nowrap; + text-overflow: ellipsis; - font-size: 12px; - } + font-size: 12px; + } - &__bold { - font-weight: 600; - } + &__bold { + font-weight: 600; + } - &__content { - display: flex; + &__content { + display: flex; - overflow: hidden; - flex-direction: column; + overflow: hidden; + flex-direction: column; - flex: 1 1 100%; + flex: 1 1 100%; - color: #9ea2a8; + color: #9ea2a8; + } } } diff --git a/app/theme/client/imports/general/base.css b/app/theme/client/imports/general/base.css index 4c54677467432..eaea675afe08d 100644 --- a/app/theme/client/imports/general/base.css +++ b/app/theme/client/imports/general/base.css @@ -257,10 +257,6 @@ button { animation-delay: -0.16s; } -.file-picker-loading .loading-animation > .bounce { - background-color: #444444; -} - @keyframes loading-bouncedelay { 0%, 80%, diff --git a/app/webdav/client/index.js b/app/webdav/client/index.js index f98661ff626f9..592f18ad60aeb 100644 --- a/app/webdav/client/index.js +++ b/app/webdav/client/index.js @@ -2,6 +2,7 @@ import './actionButton'; import './addWebdavAccount.html'; import './addWebdavAccount'; import './webdavFilePicker.html'; +import './webdavFilePicker.css'; import './webdavFilePicker'; import './selectWebdavAccount.html'; import './selectWebdavAccount'; diff --git a/app/webdav/client/startup/messageBoxActions.js b/app/webdav/client/startup/messageBoxActions.js index 0ccfcb1760ac9..4ca3e60e5b948 100644 --- a/app/webdav/client/startup/messageBoxActions.js +++ b/app/webdav/client/startup/messageBoxActions.js @@ -49,8 +49,9 @@ Meteor.startup(function() { accountId: account._id, }, title, + modifier: 'modal', content: 'webdavFilePicker', - showCancelButton: true, + showCancelButton: false, showFooter: false, showConfirmButton: false, closeOnCancel: true, diff --git a/app/webdav/client/webdavFilePicker.css b/app/webdav/client/webdavFilePicker.css new file mode 100644 index 0000000000000..6188103f0d6da --- /dev/null +++ b/app/webdav/client/webdavFilePicker.css @@ -0,0 +1,134 @@ +.webdav { + display: flex; + flex-direction: column; + + height: 60vh; + + padding: 0; + + & &__file-icon, + & &__file-name, + & &__file-date { + overflow: hidden; + + white-space: nowrap; + text-overflow: ellipsis; + } + + & &__file-name, + & &__file-size, + & &__file-date { + min-width: 80px; + } + + & &__file-icon { + width: 36px; + } + + .file-picker-loading .loading-animation > .bounce { + background-color: #444444; + } + + .current-folder-path { + display: flex; + flex-direction: row; + + height: 25px; + + .webdav_parent_folder { + padding: 0 5px; + + cursor: pointer; + + border-radius: 5px; + background-color: #e0e0e0; + } + } + + .webdav-path-breadcrumb { + overflow: hidden; + + margin-bottom: 12px; + padding-bottom: 3px; + + list-style: none; + + font-size: 16px; + + .webdav-breadcrumb-item { + display: block; + float: left; + + .webdav-breadcrumb-folder { + padding: 3px; + + cursor: pointer; + + &:hover { + border-radius: 5px; + background: #f1f3f4; + } + } + } + } + + .rc-table-content { + display: flex; + overflow-x: auto; + flex-direction: column; + flex: 1 1 100%; + + border-top: 1px solid rgba(216, 216, 216, 0.4); + + & tr { + color: #444444; + } + + & .js-sort { + cursor: pointer; + + &.is-sorting .table-fake-th .rc-icon { + opacity: 1; + } + } + + & .table-fake-th { + color: #444444; + + &:hover .rc-icon { + opacity: 1; + } + + & .rc-icon { + transition: opacity 0.3s; + + opacity: 0; + + font-size: 1rem; + } + + & #webdav-go-back .rc-icon { + cursor: pointer; + + opacity: 1; + } + } + + & .table-tr-dummy { + height: 10px; + } + + & .center-cell { + text-align: center; + } + } + + @media (width <= 980px) { + .rc-table-content { + & th:not(:first-child), + & td:not(:first-child) { + display: none; + } + } + } +} diff --git a/app/webdav/client/webdavFilePicker.html b/app/webdav/client/webdavFilePicker.html index 79ebe7556be5a..cebbfa6c8742d 100644 --- a/app/webdav/client/webdavFilePicker.html +++ b/app/webdav/client/webdavFilePicker.html @@ -1,35 +1,76 @@ diff --git a/app/webdav/client/webdavFilePicker.js b/app/webdav/client/webdavFilePicker.js index ccbd3919177ce..a6ee6e4064e45 100644 --- a/app/webdav/client/webdavFilePicker.js +++ b/app/webdav/client/webdavFilePicker.js @@ -6,6 +6,7 @@ import { Session } from 'meteor/session'; import { Handlebars } from 'meteor/ui'; import { ReactiveVar } from 'meteor/reactive-var'; +import { timeAgo } from '../../ui/client/views/app/helpers'; import { modal, call } from '../../ui-utils'; import { t } from '../../utils'; import { fileUploadHandler } from '../../file-upload'; @@ -26,6 +27,36 @@ Template.webdavFilePicker.destroyed = function() { Session.set('webdavNodes', []); }; +function sortTable(data, sortBy, sortDirection) { + if (sortDirection === 'desc') { + if (sortBy === 'name') { data.sort((a, b) => b.basename.localeCompare(a.basename)); } + if (sortBy === 'size') { data.sort((a, b) => b.size - a.size); } + if (sortBy === 'date') { data.sort((a, b) => new Date(b.lastmod) - new Date(a.lastmod)); } + } else { + if (sortBy === 'name') { data.sort((a, b) => a.basename.localeCompare(b.basename)); } + if (sortBy === 'size') { data.sort((a, b) => a.size - b.size); } + if (sortBy === 'date') { data.sort((a, b) => new Date(a.lastmod) - new Date(b.lastmod)); } + } + return data; +} + +async function showWebdavFileList(directory) { + const instance = Template.instance(); + const { sortDirection, sortBy } = instance; + const { accountId } = instance.data; + instance.isLoading.set(true); + Session.set('webdavCurrentFolder', directory); + Session.set('webdavNodes', []); + const response = await call('getWebdavFileList', accountId, directory); + instance.isLoading.set(false); + if (!response.success) { + modal.close(); + return toastr.error(t(response.message)); + } + const data = sortTable(response.data, sortBy.get(), sortDirection.get()); + Session.set('webdavNodes', data); +} + Template.webdavFilePicker.helpers({ iconType() { // add icon for different types @@ -42,7 +73,7 @@ Template.webdavFilePicker.helpers({ type = 'directory'; } else if (this.mime.match(/application\/pdf/)) { icon = 'file-pdf'; - type = 'ppt'; + type = 'pdf'; } else if (['application/vnd.oasis.opendocument.text', 'application/vnd.oasis.opendocument.presentation'].includes(this.mime)) { icon = 'file-document'; type = 'document'; @@ -59,6 +90,44 @@ Template.webdavFilePicker.helpers({ isLoading() { return Template.instance().isLoading.get(); }, + sortBy(key) { + return Template.instance().sortBy.get() === key; + }, + getSize() { + if (this.type === 'directory') { return ''; } + const bytes = this.size; + if (bytes === 0) { return '0 B'; } + const k = 1024; + const sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB']; + const i = Math.floor(Math.log(bytes) / Math.log(k)); + return `${ parseFloat((bytes / Math.pow(k, i)).toFixed(2)) } ${ sizes[i] }`; + }, + getDate() { + return timeAgo(new Date(this.lastmod), t); + }, + sortIcon(key) { + const { sortDirection, sortBy } = Template.instance(); + return key === sortBy.get() && sortDirection.get() === 'asc' + ? 'sort-up' + : 'sort-down'; + }, + onTableSort() { + const { sortDirection, sortBy } = Template.instance(); + return function(type) { + if (sortBy.get() === type) { + sortDirection.set(sortDirection.get() === 'asc' ? 'desc' : 'asc'); + } else { + sortBy.set(type); + sortDirection.set('asc'); + } + const data = sortTable(Session.get('webdavNodes'), sortBy.get(), sortDirection.get()); + Session.set('webdavNodes', data); + }; + }, + parentFolders() { + const currentFolder = Session.get('webdavCurrentFolder'); + return currentFolder.split('/').filter((s) => s); + }, webdavNodes() { return Session.get('webdavNodes'); }, @@ -69,11 +138,7 @@ Template.webdavFilePicker.helpers({ Template.webdavFilePicker.events({ async 'click #webdav-go-back'() { - const instance = Template.instance(); - const { accountId } = instance.data; - instance.isLoading.set(true); let currentFolder = Session.get('webdavCurrentFolder'); - // determine parent directory to go back let parentFolder = '/'; if (currentFolder && currentFolder !== '/') { @@ -82,28 +147,22 @@ Template.webdavFilePicker.events({ } parentFolder = currentFolder.substr(0, currentFolder.lastIndexOf('/') + 1); } - Session.set('webdavCurrentFolder', parentFolder); - Session.set('webdavNodes', []); - const response = await call('getWebdavFileList', accountId, parentFolder); - instance.isLoading.set(false); - if (!response.success) { - return toastr.error(t(response.message)); - } - Session.set('webdavNodes', response.data); + showWebdavFileList(parentFolder); }, async 'click .webdav_directory'() { - const instance = Template.instance(); - const { accountId } = instance.data; - instance.isLoading.set(true); - Session.set('webdavCurrentFolder', this.filename); - Session.set('webdavNodes', []); - const response = await call('getWebdavFileList', accountId, this.filename); - instance.isLoading.set(false); - if (!response.success) { - modal.close(); - return toastr.error(t(response.message)); + showWebdavFileList(this.filename); + }, + async 'click .webdav-breadcrumb-folder'(event) { + const index = $(event.target).data('index'); + const currentFolder = Session.get('webdavCurrentFolder'); + const parentFolders = currentFolder.split('/').filter((s) => s); + // determine parent directory to go to + let targetFolder = '/'; + for (let i = 0; i <= index; i++) { + targetFolder += parentFolders[i]; + targetFolder += '/'; } - Session.set('webdavNodes', response.data); + showWebdavFileList(targetFolder); }, async 'click .webdav_file'() { const roomId = Session.get('openedRoom'); @@ -218,4 +277,6 @@ Template.webdavFilePicker.events({ Template.webdavFilePicker.onCreated(function() { this.isLoading = new ReactiveVar(true); + this.sortBy = new ReactiveVar('name'); + this.sortDirection = new ReactiveVar('asc'); });