diff --git a/client/components/main/myCards.jade b/client/components/main/myCards.jade index 3baa77662..e16fb8e98 100644 --- a/client/components/main/myCards.jade +++ b/client/components/main/myCards.jade @@ -1,9 +1,20 @@ template(name="myCardsHeaderBar") h1 - a.back-btn(href="{{pathFor 'home'}}") - i.fa.fa-chevron-left + //a.back-btn(href="{{pathFor 'home'}}") + // i.fa.fa-chevron-left | {{_ 'my-cards'}} + .board-header-btns.left + a.board-header-btn.js-toggle-my-cards-choose-sort(title="{{_ 'my-cards-sort'}}") + //i.fa.fa-caret-down + i.fa.fa-sort + if $eq myCardsSort 'board' + i.fa.fa-th-large + | {{_ 'my-cards-sort-board'}} + if $eq myCardsSort 'dueAt' + i.fa.fa-calendar + | {{_ 'my-cards-sort-dueat'}} + template(name="myCardsModalTitle") h2 i.fa.fa-keyboard-o @@ -11,20 +22,75 @@ template(name="myCardsModalTitle") template(name="myCards") .wrapper - each board in myBoards - .my-cards-board-wrapper - .board-title - +viewer - = board.title - each swimlane in board.mySwimlanes - .swimlane-title(class="{{#if swimlane.colorClass}}{{ swimlane.colorClass }}{{else}}swimlane-default-color{{/if}}") + if $eq myCardsSort 'board' + each board in myBoards + .my-cards-board-wrapper + .my-cards-board-title +viewer - = swimlane.title - each list in swimlane.myLists - .my-cards-list-wrapper - .list-title(class=list.colorClass) + = board.title + each swimlane in board.mySwimlanes + .my-cards-swimlane-title(class="{{#if swimlane.colorClass}}{{ swimlane.colorClass }}{{else}}swimlane-default-color{{/if}}") + +viewer + = swimlane.title + each list in swimlane.myLists + .my-cards-list-wrapper + .my-cards-list-title(class=list.colorClass) + +viewer + = list.title + each card in list.myCards + .my-cards-card-wrapper + a.minicard-wrapper(href=card.absoluteUrl) + +minicard(card) + else + .my-cards-dueat-list-wrapper + each card in myCardsList + .my-cards-card-wrapper + a.minicard-wrapper.card-title(href=card.absoluteUrl) + +minicard(card) + ul.my-cards-context-list + li.my-cards-context(title="{{_ 'board'}}") +viewer - = list.title - each card in list.myCards - a.minicard-wrapper.card-title(href=card.absoluteUrl) - +minicard(card) + = card.board.title + li.my-cards-context.my-cards-context-separator + = ' ' + | {{_ 'context-separator'}} + = ' ' + li.my-cards-context(title="{{_ 'swimlane'}}") + +viewer + = card.swimlane.title + li.my-cards-context + = ' ' + | {{_ 'context-separator'}} + = ' ' + li.my-cards-context(title="{{_ 'list'}}") + +viewer + = card.list.title + + +template(name="myCardsSortChangePopup") + ul.pop-over-list + li + with "my-cards-sort-board" + a.js-my-cards-sort-board + i.fa.fa-th-large.colorful + | {{_ 'my-cards-sort-board'}} + if $eq Utils.myCardsSort "board" + i.fa.fa-check + li + with "my-cards-sort-dueat" + a.js-my-cards-sort-dueat + i.fa.fa-calendar.colorful + | {{_ 'my-cards-sort-dueat'}} + if $eq Utils.myCardsSort "dueAt" + i.fa.fa-check + +//template(name="myCardsSortChangePopup") +// ul.pop-over-list +// li +// a.js-my-cards-sort-board +// i.fa.fa-th-large.colorful +// | {{_ 'my-cards-sort-board'}} +// li +// a.js-my-cards-sort-dueat +// i.fa.fa-calendar.colorful +// | {{_ 'my-cards-sort-dueat'}} diff --git a/client/components/main/myCards.js b/client/components/main/myCards.js index cf2a7fe7c..7b562c2e5 100644 --- a/client/components/main/myCards.js +++ b/client/components/main/myCards.js @@ -1,22 +1,23 @@ -const subManager = new SubsManager(); -Meteor.subscribe('myCards'); -Meteor.subscribe('mySwimlanes'); -Meteor.subscribe('myLists'); +BlazeComponent.extendComponent({ + myCardsSort() { + // eslint-disable-next-line no-console + // console.log('sort:', Utils.myCardsSort()); + return Utils.myCardsSort(); + }, -Template.myCardsHeaderBar.events({ - 'click .js-open-archived-board'() { - Modal.open('archivedBoards'); + events() { + return [ + { + 'click .js-toggle-my-cards-choose-sort'() { + // eslint-disable-next-line no-console + // console.log('open sort'); + // Popup.open('myCardsSortChange'); + Utils.myCardsSortToggle(); + }, + }, + ]; }, -}); - -Template.myCardsHeaderBar.helpers({ - title() { - return FlowRouter.getRouteName() === 'home' ? 'my-boards' : 'public'; - }, - templatesUser() { - return Meteor.user(); - }, -}); +}).register('myCardsHeaderBar'); Template.myCards.helpers({ userId() { @@ -24,10 +25,40 @@ Template.myCards.helpers({ }, }); +BlazeComponent.extendComponent({ + events() { + return [ + { + 'click .js-my-cards-sort-board'() { + Utils.setMyCardsSort('board'); + Popup.close(); + }, + + 'click .js-my-cards-sort-dueat'() { + Utils.setMyCardsSort('dueAt'); + Popup.close(); + }, + }, + ]; + }, +}).register('myCardsSortChangePopup'); + BlazeComponent.extendComponent({ onCreated() { Meteor.subscribe('setting'); - // subManager.subscribe('myCards'); + Meteor.subscribe('myCards'); + Meteor.subscribe('mySwimlanes'); + Meteor.subscribe('myLists'); + }, + + myCardsSort() { + // eslint-disable-next-line no-console + console.log('sort:', Utils.myCardsSort()); + return Utils.myCardsSort(); + }, + + sortByBoard() { + return this.myCardsSort() === 'board'; }, myBoards() { @@ -145,20 +176,62 @@ BlazeComponent.extendComponent({ return boards; }, + myCardsList() { + const userId = Meteor.userId(); + + const cursor = Cards.find( + { + $or: [{ members: userId }, { assignees: userId }], + archived: false, + }, + { + sort: { + dueAt: -1, + boardId: 1, + swimlaneId: 1, + listId: 1, + sort: 1, + }, + }, + ); + + // eslint-disable-next-line no-console + // console.log('cursor:', cursor); + + const cards = []; + cursor.forEach(card => { + cards.push(card); + }); + + cards.sort((a, b) => { + const x = a.dueAt === null ? Date('2100-12-31') : a.dueAt; + const y = b.dueAt === null ? Date('2100-12-31') : b.dueAt; + + if (x > y) return 1; + else if (x < y) return -1; + + return 0; + }); + + // eslint-disable-next-line no-console + // console.log('cursor:', cards); + return cards; + }, + events() { return [ { - 'click .js-my-card'(evt) { - const card = this.currentData().card; - // eslint-disable-next-line no-console - console.log('currentData():', this.currentData()); - // eslint-disable-next-line no-console - console.log('card:', card); - if (card) { - Utils.goCardId(card._id); - } - evt.preventDefault(); - }, + // 'click .js-my-card'(evt) { + // const card = this.currentData().card; + // // eslint-disable-next-line no-console + // console.log('currentData():', this.currentData()); + // // eslint-disable-next-line no-console + // console.log('card:', card); + // if (card) { + // Utils.goCardId(card._id); + // } + // evt.preventDefault(); + // }, }, ]; }, diff --git a/client/components/main/myCards.styl b/client/components/main/myCards.styl index 7075c6fbb..27cbdaa08 100644 --- a/client/components/main/myCards.styl +++ b/client/components/main/myCards.styl @@ -1,28 +1,7 @@ -.my-cards-list - .my-cards-list-item - border-bottom: 1px solid darken(white, 25%) - padding: 10px 5px - - &:last-child - border-bottom: none - - .my-cards-list-item-keys - margin-top: 5px - float: right - - kbd - padding: 5px 8px - margin: 5px - font-size: 18px - - .my-cards-list-item-action - font-size: 1.4em - margin: 5px - .my-cards-board-wrapper border-radius: 8px //padding: 0.5rem - max-width: 400px + min-width: 400px border-width: 8px border-color: grey border-style: solid @@ -30,14 +9,14 @@ margin-right: auto margin-left: auto -.board-title +.my-cards-board-title font-size: 1.4rem font-weight: bold padding: 0.5rem background-color: grey color: white -.swimlane-title +.my-cards-swimlane-title font-size: 1.1rem font-weight: bold padding: 0.5rem @@ -51,7 +30,7 @@ .swimlane-default-color background-color: lightgrey -.list-title +.my-cards-list-title font-weight: bold font-size: 1.1rem //padding-bottom: 0 @@ -59,18 +38,32 @@ text-align: center margin-bottom: 0.7rem -.list-color-bar - //height: 0.3rem - margin-bottom: 0.3rem - margin-top: 0 - padding-top: 0 - .my-cards-list-wrapper margin: 1rem - margin-top: 1rem border-radius: 5px padding: 1.5rem padding-top: 0.75rem + display: inline-block + min-width: 250px + max-width: 350px -.card-title - margin-top: 5px +.my-cards-card-wrapper + margin-top: 0 + margin-bottom: 10px + +.my-cards-dueat-list-wrapper + max-width: 500px + margin-right: auto + margin-left: auto + +.my-cards-field-name + font-weight: bold + +.my-cards-context + display: inline-block + +.my-cards-context-separator + font-weight: bold + +.my-cards-context-list + margin-bottom: 0.7rem diff --git a/client/lib/utils.js b/client/lib/utils.js index 2068e6d27..94d7ed017 100644 --- a/client/lib/utils.js +++ b/client/lib/utils.js @@ -44,6 +44,31 @@ Utils = { } }, + myCardsSort() { + let sort = window.localStorage.getItem('myCardsSort'); + + if (!sort || !['board', 'dueAt'].includes(sort)) { + window.localStorage.setItem('myCardsSort', 'board'); + location.reload(); + sort = 'board'; + } + + return sort; + }, + + myCardsSortToggle() { + if (this.myCardsSort() === 'board') { + this.setMyCardsSort('dueAt'); + } else { + this.setMyCardsSort('board'); + } + }, + + setMyCardsSort(sort) { + window.localStorage.setItem('myCardsSort', sort); + location.reload(); + }, + // XXX We should remove these two methods goBoardId(_id) { const board = Boards.findOne(_id); diff --git a/i18n/en.i18n.json b/i18n/en.i18n.json index 306abe799..ec62e6a75 100644 --- a/i18n/en.i18n.json +++ b/i18n/en.i18n.json @@ -852,5 +852,9 @@ "my-cards": "My Cards", "card": "Card", "list": "List", - "board": "Board" + "board": "Board", + "context-separator": "/", + "my-cards-sort": "My Cards Sort", + "my-cards-sort-board": "By Board", + "my-cards-sort-dueat": "By Due Date" }