From 1ea99a5dc8040fbfdc47fecac787f313ff849ef0 Mon Sep 17 00:00:00 2001 From: "John R. Supplee" Date: Wed, 6 Jan 2021 20:13:36 +0200 Subject: [PATCH] My Cards development * Add cards due view * Add input for selecting sort (not working) * Add methods to `Utils` to save sort to local browser storage * CSS updates to make lists display horizontally within swimlanes --- client/components/main/myCards.jade | 87 +++++++++++++++++++----- client/components/main/myCards.js | 102 +++++++++++++++++++++++----- client/components/main/myCards.styl | 28 +++++++- client/lib/utils.js | 17 +++++ i18n/en.i18n.json | 6 +- 5 files changed, 202 insertions(+), 38 deletions(-) diff --git a/client/components/main/myCards.jade b/client/components/main/myCards.jade index 3baa77662..9688f0967 100644 --- a/client/components/main/myCards.jade +++ b/client/components/main/myCards.jade @@ -1,9 +1,19 @@ 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 + 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 +21,63 @@ 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 + .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 + .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 + .list-title(class=list.colorClass) + +viewer + = list.title + each card in list.myCards + a.minicard-wrapper.card-title(href=card.absoluteUrl) + +minicard(card) + else + .my-cards-dueat-list-wrapper + each card in myCardsList + .my-cards-card + 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 + = ' ' + | {{_ '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="myCardsSortPopup") + 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 diff --git a/client/components/main/myCards.js b/client/components/main/myCards.js index cf2a7fe7c..c5e4dde33 100644 --- a/client/components/main/myCards.js +++ b/client/components/main/myCards.js @@ -1,22 +1,22 @@ -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'() { + Popup.open('myCardsSortPopup'); + // eslint-disable-next-line no-console + console.log('open sort'); + }, + }, + ]; }, -}); - -Template.myCardsHeaderBar.helpers({ - title() { - return FlowRouter.getRouteName() === 'home' ? 'my-boards' : 'public'; - }, - templatesUser() { - return Meteor.user(); - }, -}); +}).register('myCardsHeaderBar'); Template.myCards.helpers({ userId() { @@ -24,10 +24,34 @@ Template.myCards.helpers({ }, }); +Template.myCardsSortPopup.events({ + 'click .js-my-cards-sort-board'() { + Utils.setMyCardsSort('board'); + Popup.close(); + }, + + 'click .js-my-cards-sort-dueat'() { + Utils.setMyCardsSort('dueAt'); + Popup.close(); + }, +}); + 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,6 +169,48 @@ 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 [ { diff --git a/client/components/main/myCards.styl b/client/components/main/myCards.styl index 7075c6fbb..410f02395 100644 --- a/client/components/main/myCards.styl +++ b/client/components/main/myCards.styl @@ -22,7 +22,7 @@ .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 @@ -71,6 +71,30 @@ border-radius: 5px padding: 1.5rem padding-top: 0.75rem + display: inline-block + min-width: 250px + max-width: 350px .card-title - margin-top: 5px + 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-dueat-list + columns: 2 + +.my-cards-context + display: inline-block + +.my-cards-context-list + margin-bottom: 0.7rem + +.my-cards-context-item + display: inline-block diff --git a/client/lib/utils.js b/client/lib/utils.js index 2068e6d27..f697c84da 100644 --- a/client/lib/utils.js +++ b/client/lib/utils.js @@ -44,6 +44,23 @@ 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; + }, + + 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" }