mirror of
https://github.com/wekan/wekan.git
synced 2025-04-23 05:27:14 -04:00
Merge branch 'TNick-calendar' into devel
This commit is contained in:
commit
523ebea4dd
12 changed files with 148 additions and 26 deletions
|
@ -77,10 +77,11 @@ email@1.2.3
|
|||
horka:swipebox
|
||||
dynamic-import@0.2.0
|
||||
staringatlights:fast-render
|
||||
staringatlights:flow-router
|
||||
|
||||
mixmax:smart-disconnect
|
||||
accounts-password@1.5.0
|
||||
cfs:gridfs
|
||||
browser-policy
|
||||
eluck:accounts-lockout
|
||||
rzymek:fullcalendar
|
||||
momentjs:moment@2.22.2
|
||||
|
|
|
@ -103,6 +103,7 @@ mixmax:smart-disconnect@0.0.4
|
|||
mobile-status-bar@1.0.14
|
||||
modules@0.11.0
|
||||
modules-runtime@0.9.1
|
||||
momentjs:moment@2.22.2
|
||||
mongo@1.3.1
|
||||
mongo-dev-server@1.1.0
|
||||
mongo-id@1.0.6
|
||||
|
@ -139,6 +140,7 @@ reactive-var@1.0.11
|
|||
reload@1.1.11
|
||||
retry@1.0.9
|
||||
routepolicy@1.0.12
|
||||
rzymek:fullcalendar@3.8.0
|
||||
service-configuration@1.0.11
|
||||
session@1.1.7
|
||||
sha@1.0.9
|
||||
|
@ -155,7 +157,6 @@ srp@1.0.10
|
|||
standard-minifier-css@1.3.5
|
||||
standard-minifier-js@2.2.3
|
||||
staringatlights:fast-render@2.16.5
|
||||
staringatlights:flow-router@2.12.2
|
||||
staringatlights:inject-data@2.0.5
|
||||
stylus@2.513.13
|
||||
tap:i18n@1.8.2
|
||||
|
|
|
@ -1,6 +1,10 @@
|
|||
# Upcoming Wekan release
|
||||
|
||||
This release fixes the following bugs:
|
||||
This release adds the following new features:
|
||||
|
||||
* [Calendar](https://github.com/wekan/wekan/pull/1728).
|
||||
|
||||
and fixes the following bugs:
|
||||
|
||||
* To fix ["title is required"](https://github.com/wekan/wekan/issues/1576) fix only
|
||||
add-checklist-items and revert all other migration changes](https://github.com/wekan/wekan/issues/1734);
|
||||
|
|
|
@ -25,3 +25,5 @@ template(name="boardBody")
|
|||
+swimlane(this)
|
||||
if isViewLists
|
||||
+listsGroup
|
||||
if isViewCalendar
|
||||
+fullcalendar(calendarOptions)
|
||||
|
|
|
@ -98,6 +98,12 @@ BlazeComponent.extendComponent({
|
|||
return (currentUser.profile.boardView === 'board-view-lists');
|
||||
},
|
||||
|
||||
isViewCalendar() {
|
||||
const currentUser = Meteor.user();
|
||||
if (!currentUser) return true;
|
||||
return (currentUser.profile.boardView === 'board-view-cal');
|
||||
},
|
||||
|
||||
openNewListForm() {
|
||||
if (this.isViewSwimlanes()) {
|
||||
this.childComponents('swimlane')[0]
|
||||
|
@ -108,6 +114,62 @@ BlazeComponent.extendComponent({
|
|||
}
|
||||
},
|
||||
|
||||
calendarOptions() {
|
||||
return {
|
||||
id: 'calendar-view',
|
||||
defaultView: 'basicWeek',
|
||||
header: {
|
||||
left: 'title',
|
||||
center: 'agendaDay,listDay,timelineDay agendaWeek,listWeek,timelineWeek month,timelineMonth timelineYear',
|
||||
right: 'today prev,next',
|
||||
},
|
||||
views: {
|
||||
basic: {
|
||||
// options apply to basicWeek and basicDay views
|
||||
},
|
||||
agenda: {
|
||||
// options apply to agendaWeek and agendaDay views
|
||||
},
|
||||
week: {
|
||||
// options apply to basicWeek and agendaWeek views
|
||||
},
|
||||
day: {
|
||||
// options apply to basicDay and agendaDay views
|
||||
},
|
||||
},
|
||||
themeSystem: 'jquery-ui',
|
||||
height: 'parent',
|
||||
/* TODO: lists as resources: https://fullcalendar.io/docs/vertical-resource-view */
|
||||
navLinks: true,
|
||||
nowIndicator: true,
|
||||
businessHours: {
|
||||
// days of week. an array of zero-based day of week integers (0=Sunday)
|
||||
dow: [ 1, 2, 3, 4, 5 ], // Monday - Thursday
|
||||
start: '8:00',
|
||||
end: '18:00',
|
||||
},
|
||||
locale: TAPi18n.getLanguage(),
|
||||
events(start, end, timezone, callback) {
|
||||
const currentBoard = Boards.findOne(Session.get('currentBoard'));
|
||||
const events = [];
|
||||
currentBoard.cardsInInterval(start.toDate(), end.toDate()).forEach(function(card){
|
||||
events.push({
|
||||
id: card.id,
|
||||
title: card.title,
|
||||
start: card.startAt,
|
||||
end: card.endAt,
|
||||
url: FlowRouter.url('card', {
|
||||
boardId: currentBoard._id,
|
||||
slug: currentBoard.slug,
|
||||
cardId: card._id,
|
||||
}),
|
||||
});
|
||||
});
|
||||
callback(events);
|
||||
},
|
||||
};
|
||||
},
|
||||
|
||||
events() {
|
||||
return [{
|
||||
// XXX The board-overlay div should probably be moved to the parent
|
||||
|
|
|
@ -89,9 +89,11 @@ BlazeComponent.extendComponent({
|
|||
'click .js-toggle-board-view'() {
|
||||
const currentUser = Meteor.user();
|
||||
if (currentUser.profile.boardView === 'board-view-swimlanes') {
|
||||
currentUser.setBoardView('board-view-lists');
|
||||
currentUser.setBoardView('board-view-cal');
|
||||
} else if (currentUser.profile.boardView === 'board-view-lists') {
|
||||
currentUser.setBoardView('board-view-swimlanes');
|
||||
} else if (currentUser.profile.boardView === 'board-view-cal') {
|
||||
currentUser.setBoardView('board-view-lists');
|
||||
}
|
||||
},
|
||||
'click .js-open-filter-view'() {
|
||||
|
|
|
@ -218,10 +218,13 @@ class CardReceivedDate extends CardDate {
|
|||
}
|
||||
|
||||
classes() {
|
||||
let classes = 'received-date' + ' ';
|
||||
if (this.date.get().isBefore(this.now.get(), 'minute') &&
|
||||
this.now.get().isBefore(this.data().dueAt)) {
|
||||
classes += 'current';
|
||||
let classes = 'received-date ';
|
||||
const dueAt = this.data().dueAt;
|
||||
if (dueAt) {
|
||||
if (this.date.get().isBefore(this.now.get(), 'minute') &&
|
||||
this.now.get().isBefore(dueAt)) {
|
||||
classes += 'current';
|
||||
}
|
||||
}
|
||||
return classes;
|
||||
}
|
||||
|
@ -249,9 +252,12 @@ class CardStartDate extends CardDate {
|
|||
|
||||
classes() {
|
||||
let classes = 'start-date' + ' ';
|
||||
if (this.date.get().isBefore(this.now.get(), 'minute') &&
|
||||
this.now.get().isBefore(this.data().dueAt)) {
|
||||
classes += 'current';
|
||||
const dueAt = this.data().dueAt;
|
||||
if (dueAt) {
|
||||
if (this.date.get().isBefore(this.now.get(), 'minute') &&
|
||||
this.now.get().isBefore(dueAt)) {
|
||||
classes += 'current';
|
||||
}
|
||||
}
|
||||
return classes;
|
||||
}
|
||||
|
@ -279,18 +285,23 @@ class CardDueDate extends CardDate {
|
|||
|
||||
classes() {
|
||||
let classes = 'due-date' + ' ';
|
||||
|
||||
// if endAt exists & is < dueAt, dueAt doesn't need to be flagged
|
||||
if ((this.data().endAt !== 0) &&
|
||||
(this.data().endAt !== null) &&
|
||||
(this.data().endAt !== '') &&
|
||||
(this.data().endAt !== undefined) &&
|
||||
(this.date.get().isBefore(this.data().endAt)))
|
||||
const endAt = this.data().endAt;
|
||||
const theDate = this.date.get();
|
||||
const now = this.now.get();
|
||||
|
||||
if ((endAt !== 0) &&
|
||||
(endAt !== null) &&
|
||||
(endAt !== '') &&
|
||||
(endAt !== undefined) &&
|
||||
(theDate.isBefore(endAt)))
|
||||
classes += 'current';
|
||||
else if (this.now.get().diff(this.date.get(), 'days') >= 2)
|
||||
else if (now.diff(theDate, 'days') >= 2)
|
||||
classes += 'long-overdue';
|
||||
else if (this.now.get().diff(this.date.get(), 'minute') >= 0)
|
||||
else if (now.diff(theDate, 'minute') >= 0)
|
||||
classes += 'due';
|
||||
else if (this.now.get().diff(this.date.get(), 'days') >= -1)
|
||||
else if (now.diff(theDate, 'days') >= -1)
|
||||
classes += 'almost-due';
|
||||
return classes;
|
||||
}
|
||||
|
@ -318,12 +329,16 @@ class CardEndDate extends CardDate {
|
|||
|
||||
classes() {
|
||||
let classes = 'end-date' + ' ';
|
||||
if (this.data.dueAt.diff(this.date.get(), 'days') >= 2)
|
||||
classes += 'long-overdue';
|
||||
else if (this.data.dueAt.diff(this.date.get(), 'days') > 0)
|
||||
classes += 'due';
|
||||
else if (this.data.dueAt.diff(this.date.get(), 'days') <= 0)
|
||||
classes += 'current';
|
||||
const dueAt = this.data.dueAt;
|
||||
if (dueAt) {
|
||||
const diff = dueAt.diff(this.date.get(), 'days');
|
||||
if (diff >= 2)
|
||||
classes += 'long-overdue';
|
||||
else if (diff > 0)
|
||||
classes += 'due';
|
||||
else if (diff <= 0)
|
||||
classes += 'current';
|
||||
}
|
||||
return classes;
|
||||
}
|
||||
|
||||
|
|
|
@ -45,7 +45,7 @@ BlazeComponent.extendComponent({
|
|||
const boardView = Meteor.user().profile.boardView;
|
||||
if (boardView === 'board-view-swimlanes')
|
||||
swimlaneId = this.parentComponent().parentComponent().data()._id;
|
||||
else if (boardView === 'board-view-lists')
|
||||
else if ((boardView === 'board-view-lists') || (boardView === 'board-view-cal'))
|
||||
swimlaneId = Swimlanes.findOne({boardId})._id;
|
||||
|
||||
if (title) {
|
||||
|
|
|
@ -7,6 +7,8 @@ function currentCardIsInThisList(listId, swimlaneId) {
|
|||
return currentCard && currentCard.listId === listId;
|
||||
else if (currentUser.profile.boardView === 'board-view-swimlanes')
|
||||
return currentCard && currentCard.listId === listId && currentCard.swimlaneId === swimlaneId;
|
||||
else if (currentUser.profile.boardView === 'board-view-cal')
|
||||
return currentCard;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -100,6 +100,7 @@
|
|||
"boardMenuPopup-title": "Board Menu",
|
||||
"boards": "Boards",
|
||||
"board-view": "Board View",
|
||||
"board-view-cal": "Calendar",
|
||||
"board-view-swimlanes": "Swimlanes",
|
||||
"board-view-lists": "Lists",
|
||||
"bucket-example": "Like “Bucket List” for example",
|
||||
|
|
|
@ -284,6 +284,33 @@ Boards.helpers({
|
|||
|
||||
return Cards.find(query, projection);
|
||||
},
|
||||
|
||||
cardsInInterval(start, end) {
|
||||
return Cards.find({
|
||||
$or: [
|
||||
{
|
||||
startAt: {
|
||||
$lte: start,
|
||||
}, endAt: {
|
||||
$gte: start,
|
||||
},
|
||||
}, {
|
||||
startAt: {
|
||||
$lte: end,
|
||||
}, endAt: {
|
||||
$gte: end,
|
||||
},
|
||||
}, {
|
||||
startAt: {
|
||||
$gte: start,
|
||||
}, endAt: {
|
||||
$lte: end,
|
||||
},
|
||||
},
|
||||
],
|
||||
});
|
||||
},
|
||||
|
||||
});
|
||||
|
||||
Boards.mutations({
|
||||
|
|
|
@ -100,6 +100,11 @@ Users.attachSchema(new SimpleSchema({
|
|||
'profile.boardView': {
|
||||
type: String,
|
||||
optional: true,
|
||||
allowedValues: [
|
||||
'board-view-lists',
|
||||
'board-view-swimlanes',
|
||||
'board-view-cal',
|
||||
],
|
||||
},
|
||||
services: {
|
||||
type: Object,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue