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
This commit is contained in:
John R. Supplee 2021-01-06 20:13:36 +02:00
parent febc020cd3
commit 1ea99a5dc8
5 changed files with 202 additions and 38 deletions

View file

@ -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

View file

@ -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 [
{

View file

@ -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

View file

@ -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);

View file

@ -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"
}