mirror of
https://github.com/wekan/wekan.git
synced 2025-12-18 08:20:12 +01:00
Merge branch 'devel' into feature/import-board-members
This commit is contained in:
commit
658ef5ebe1
19 changed files with 61 additions and 32 deletions
|
|
@ -78,6 +78,7 @@ globals:
|
||||||
Avatars: true
|
Avatars: true
|
||||||
BlazeComponent: false
|
BlazeComponent: false
|
||||||
BlazeLayout: false
|
BlazeLayout: false
|
||||||
|
DocHead: false
|
||||||
ESSearchResults: false
|
ESSearchResults: false
|
||||||
FlowRouter: false
|
FlowRouter: false
|
||||||
FS: false
|
FS: false
|
||||||
|
|
|
||||||
|
|
@ -50,6 +50,7 @@ alethes:pages
|
||||||
arillo:flow-router-helpers
|
arillo:flow-router-helpers
|
||||||
audit-argument-checks
|
audit-argument-checks
|
||||||
kadira:blaze-layout
|
kadira:blaze-layout
|
||||||
|
kadira:dochead
|
||||||
kadira:flow-router
|
kadira:flow-router
|
||||||
meteorhacks:picker
|
meteorhacks:picker
|
||||||
meteorhacks:subs-manager
|
meteorhacks:subs-manager
|
||||||
|
|
|
||||||
|
|
@ -60,7 +60,9 @@ http@1.1.1
|
||||||
id-map@1.0.4
|
id-map@1.0.4
|
||||||
idmontie:migrations@1.0.0
|
idmontie:migrations@1.0.0
|
||||||
jquery@1.11.4
|
jquery@1.11.4
|
||||||
|
jsx@0.1.6
|
||||||
kadira:blaze-layout@2.2.0
|
kadira:blaze-layout@2.2.0
|
||||||
|
kadira:dochead@1.1.0
|
||||||
kadira:flow-router@2.7.0
|
kadira:flow-router@2.7.0
|
||||||
kenton:accounts-sandstorm@0.1.6
|
kenton:accounts-sandstorm@0.1.6
|
||||||
launch-screen@1.0.4
|
launch-screen@1.0.4
|
||||||
|
|
|
||||||
|
|
@ -62,7 +62,8 @@ BlazeComponent.extendComponent({
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
return [_.extend(events, {
|
return [{
|
||||||
|
...events,
|
||||||
'click .js-close-card-details'() {
|
'click .js-close-card-details'() {
|
||||||
Utils.goBoardId(this.data().boardId);
|
Utils.goBoardId(this.data().boardId);
|
||||||
},
|
},
|
||||||
|
|
@ -86,7 +87,7 @@ BlazeComponent.extendComponent({
|
||||||
this.parentComponent().showOverlay.set(true);
|
this.parentComponent().showOverlay.set(true);
|
||||||
this.parentComponent().mouseHasEnterCardDetails = true;
|
this.parentComponent().mouseHasEnterCardDetails = true;
|
||||||
},
|
},
|
||||||
})];
|
}];
|
||||||
},
|
},
|
||||||
}).register('cardDetails');
|
}).register('cardDetails');
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,7 @@ BlazeComponent.extendComponent({
|
||||||
},
|
},
|
||||||
|
|
||||||
labels() {
|
labels() {
|
||||||
return _.map(labelColors, (color) => {
|
return labelColors.map((color) => {
|
||||||
return { color, name: '' };
|
return { color, name: '' };
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -54,7 +54,7 @@ const at = HTML.CharRef({html: '@', str: '@'});
|
||||||
Blaze.Template.registerHelper('mentions', new Template('mentions', function() {
|
Blaze.Template.registerHelper('mentions', new Template('mentions', function() {
|
||||||
const view = this;
|
const view = this;
|
||||||
const currentBoard = Boards.findOne(Session.get('currentBoard'));
|
const currentBoard = Boards.findOne(Session.get('currentBoard'));
|
||||||
const knowedUsers = _.map(currentBoard.members, (member) => {
|
const knowedUsers = currentBoard.members.map((member) => {
|
||||||
member.username = Users.findOne(member.userId).username;
|
member.username = Users.findOne(member.userId).username;
|
||||||
return member;
|
return member;
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -95,10 +95,10 @@ BlazeComponent.extendComponent({
|
||||||
events() {
|
events() {
|
||||||
// XXX Hacky, we need some kind of `super`
|
// XXX Hacky, we need some kind of `super`
|
||||||
const mixinEvents = this.getMixin(Mixins.InfiniteScrolling).events();
|
const mixinEvents = this.getMixin(Mixins.InfiniteScrolling).events();
|
||||||
return mixinEvents.concat([{
|
return [...mixinEvents, {
|
||||||
'click .js-toggle-sidebar': this.toggle,
|
'click .js-toggle-sidebar': this.toggle,
|
||||||
'click .js-back-home': this.setView,
|
'click .js-back-home': this.setView,
|
||||||
}]);
|
}];
|
||||||
},
|
},
|
||||||
}).register('sidebar');
|
}).register('sidebar');
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -41,7 +41,7 @@ Template.changePasswordPopup.onRendered(function() {
|
||||||
|
|
||||||
Template.changeLanguagePopup.helpers({
|
Template.changeLanguagePopup.helpers({
|
||||||
languages() {
|
languages() {
|
||||||
return _.map(TAPi18n.getLanguages(), (lang, tag) => {
|
return TAPi18n.getLanguages().map((lang, tag) => {
|
||||||
const name = lang.name;
|
const name = lang.name;
|
||||||
return { tag, name };
|
return { tag, name };
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -25,7 +25,7 @@ AccountsTemplates.configure({
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
_.each(['signIn', 'signUp', 'resetPwd', 'forgotPwd', 'enrollAccount'],
|
['signIn', 'signUp', 'resetPwd', 'forgotPwd', 'enrollAccount'].forEach(
|
||||||
(routeName) => AccountsTemplates.configureRoute(routeName));
|
(routeName) => AccountsTemplates.configureRoute(routeName));
|
||||||
|
|
||||||
// We display the form to change the password in a popup window that already
|
// We display the form to change the password in a popup window that already
|
||||||
|
|
|
||||||
|
|
@ -88,3 +88,26 @@ _.each(redirections, (newPath, oldPath) => {
|
||||||
}],
|
}],
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// As it is not possible to use template helpers in the page <head> we create a
|
||||||
|
// reactive function whose role is to set any page-specific tag in the <head>
|
||||||
|
// using the `kadira:dochead` package. Currently we only use it to display the
|
||||||
|
// board title if we are in a board page (see #364) but we may want to support
|
||||||
|
// some <meta> tags in the future.
|
||||||
|
const appTitle = 'Wekan';
|
||||||
|
|
||||||
|
// XXX The `Meteor.startup` should not be necessary -- we don't need to wait for
|
||||||
|
// the complete DOM to be ready to call `DocHead.setTitle`. But the problem is
|
||||||
|
// that the global variable `Boards` is undefined when this file loads so we
|
||||||
|
// wait a bit until hopefully all files are loaded. This will be fixed in a
|
||||||
|
// clean way once Meteor will support ES6 modules -- hopefully in Meteor 1.3.
|
||||||
|
Meteor.startup(() => {
|
||||||
|
Tracker.autorun(() => {
|
||||||
|
const currentBoard = Boards.findOne(Session.get('currentBoard'));
|
||||||
|
const titleStack = [appTitle];
|
||||||
|
if (currentBoard) {
|
||||||
|
titleStack.push(currentBoard.title);
|
||||||
|
}
|
||||||
|
DocHead.setTitle(titleStack.reverse().join(' - '));
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
|
||||||
|
|
@ -95,7 +95,7 @@ Filter = {
|
||||||
return {};
|
return {};
|
||||||
|
|
||||||
const filterSelector = {};
|
const filterSelector = {};
|
||||||
_.forEach(this._fields, (fieldName) => {
|
this._fields.forEach((fieldName) => {
|
||||||
const filter = this[fieldName];
|
const filter = this[fieldName];
|
||||||
if (filter._isActive())
|
if (filter._isActive())
|
||||||
filterSelector[fieldName] = filter._getMongoSelector();
|
filterSelector[fieldName] = filter._getMongoSelector();
|
||||||
|
|
@ -116,7 +116,7 @@ Filter = {
|
||||||
},
|
},
|
||||||
|
|
||||||
reset() {
|
reset() {
|
||||||
_.forEach(this._fields, (fieldName) => {
|
this._fields.forEach((fieldName) => {
|
||||||
const filter = this[fieldName];
|
const filter = this[fieldName];
|
||||||
filter.reset();
|
filter.reset();
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -21,9 +21,9 @@ window.Modal = new class {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
open(modalName, options) {
|
open(modalName, { onCloseGoTo = ''}) {
|
||||||
this._currentModal.set(modalName);
|
this._currentModal.set(modalName);
|
||||||
this._onCloseGoTo = options && options.onCloseGoTo || '';
|
this._onCloseGoTo = onCloseGoTo;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -119,12 +119,13 @@ MultiSelection = {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
toggle(cardIds, options) {
|
toggle(cardIds, options = {}) {
|
||||||
cardIds = _.isString(cardIds) ? [cardIds] : cardIds;
|
cardIds = _.isString(cardIds) ? [cardIds] : cardIds;
|
||||||
options = _.extend({
|
options = {
|
||||||
add: true,
|
add: true,
|
||||||
remove: true,
|
remove: true,
|
||||||
}, options || {});
|
...options,
|
||||||
|
};
|
||||||
|
|
||||||
if (!this.isActive()) {
|
if (!this.isActive()) {
|
||||||
this.reset();
|
this.reset();
|
||||||
|
|
@ -133,7 +134,7 @@ MultiSelection = {
|
||||||
|
|
||||||
const selectedCards = this._selectedCards.get();
|
const selectedCards = this._selectedCards.get();
|
||||||
|
|
||||||
_.each(cardIds, (cardId) => {
|
cardIds.forEach((cardId) => {
|
||||||
const indexOfCard = selectedCards.indexOf(cardId);
|
const indexOfCard = selectedCards.indexOf(cardId);
|
||||||
|
|
||||||
if (options.remove && indexOfCard > -1)
|
if (options.remove && indexOfCard > -1)
|
||||||
|
|
|
||||||
|
|
@ -91,7 +91,7 @@ window.Popup = new class {
|
||||||
if (!self.isOpen()) {
|
if (!self.isOpen()) {
|
||||||
self.current = Blaze.renderWithData(self.template, () => {
|
self.current = Blaze.renderWithData(self.template, () => {
|
||||||
self._dep.depend();
|
self._dep.depend();
|
||||||
return _.extend(self._getTopStack(), { stack: self._stack });
|
return { ...self._getTopStack(), stack: self._stack };
|
||||||
}, document.body);
|
}, document.body);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -191,7 +191,7 @@ window.Popup = new class {
|
||||||
// We close a potential opened popup on any left click on the document, or go
|
// We close a potential opened popup on any left click on the document, or go
|
||||||
// one step back by pressing escape.
|
// one step back by pressing escape.
|
||||||
const escapeActions = ['back', 'close'];
|
const escapeActions = ['back', 'close'];
|
||||||
_.each(escapeActions, (actionName) => {
|
escapeActions.forEach((actionName) => {
|
||||||
EscapeActions.register(`popup-${actionName}`,
|
EscapeActions.register(`popup-${actionName}`,
|
||||||
() => Popup[actionName](),
|
() => Popup[actionName](),
|
||||||
() => Popup.isOpen(),
|
() => Popup.isOpen(),
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,7 @@
|
||||||
"activity-on": "on %s",
|
"activity-on": "on %s",
|
||||||
"activity-removed": "removed %s from %s",
|
"activity-removed": "removed %s from %s",
|
||||||
"activity-sent": "sent %s to %s",
|
"activity-sent": "sent %s to %s",
|
||||||
"activity-unjoined": "unjoinded %s",
|
"activity-unjoined": "unjoined %s",
|
||||||
"add": "Add",
|
"add": "Add",
|
||||||
"add-attachment": "Add an attachment",
|
"add-attachment": "Add an attachment",
|
||||||
"add-board": "Add a new board",
|
"add-board": "Add a new board",
|
||||||
|
|
|
||||||
|
|
@ -279,7 +279,7 @@ Boards.before.insert((userId, doc) => {
|
||||||
// Handle labels
|
// Handle labels
|
||||||
const colors = Boards.simpleSchema()._schema['labels.$.color'].allowedValues;
|
const colors = Boards.simpleSchema()._schema['labels.$.color'].allowedValues;
|
||||||
const defaultLabelsColors = _.clone(colors).splice(0, 6);
|
const defaultLabelsColors = _.clone(colors).splice(0, 6);
|
||||||
doc.labels = _.map(defaultLabelsColors, (color) => {
|
doc.labels = defaultLabelsColors.map((color) => {
|
||||||
return {
|
return {
|
||||||
color,
|
color,
|
||||||
_id: Random.id(6),
|
_id: Random.id(6),
|
||||||
|
|
|
||||||
|
|
@ -14,13 +14,13 @@ Users.helpers({
|
||||||
},
|
},
|
||||||
|
|
||||||
starredBoards() {
|
starredBoards() {
|
||||||
const starredBoardIds = this.profile.starredBoards || [];
|
const {starredBoards = []} = this.profile;
|
||||||
return Boards.find({archived: false, _id: {$in: starredBoardIds}});
|
return Boards.find({archived: false, _id: {$in: starredBoards}});
|
||||||
},
|
},
|
||||||
|
|
||||||
hasStarred(boardId) {
|
hasStarred(boardId) {
|
||||||
const starredBoardIds = this.profile.starredBoards || [];
|
const {starredBoards = []} = this.profile;
|
||||||
return _.contains(starredBoardIds, boardId);
|
return _.contains(starredBoards, boardId);
|
||||||
},
|
},
|
||||||
|
|
||||||
isBoardMember() {
|
isBoardMember() {
|
||||||
|
|
@ -54,9 +54,9 @@ Users.helpers({
|
||||||
return profile.initials;
|
return profile.initials;
|
||||||
|
|
||||||
else if (profile.fullname) {
|
else if (profile.fullname) {
|
||||||
return _.reduce(profile.fullname.split(/\s+/), (memo, word) => {
|
return profile.fullname.split(/\s+/).reduce((memo = '', word) => {
|
||||||
return memo + word[0];
|
return memo + word[0];
|
||||||
}, '').toUpperCase();
|
}).toUpperCase();
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
return this.username[0].toUpperCase();
|
return this.username[0].toUpperCase();
|
||||||
|
|
@ -130,7 +130,7 @@ if (Meteor.isServer) {
|
||||||
// b. We use it to find deleted and newly inserted ids by using it in one
|
// b. We use it to find deleted and newly inserted ids by using it in one
|
||||||
// direction and then in the other.
|
// direction and then in the other.
|
||||||
function incrementBoards(boardsIds, inc) {
|
function incrementBoards(boardsIds, inc) {
|
||||||
_.forEach(boardsIds, (boardId) => {
|
boardsIds.forEach((boardId) => {
|
||||||
Boards.update(boardId, {$inc: {stars: inc}});
|
Boards.update(boardId, {$inc: {stars: inc}});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
@ -149,7 +149,7 @@ if (Meteor.isServer) {
|
||||||
// Insert the Welcome Board
|
// Insert the Welcome Board
|
||||||
Boards.insert(ExampleBoard, (err, boardId) => {
|
Boards.insert(ExampleBoard, (err, boardId) => {
|
||||||
|
|
||||||
_.forEach(['Basics', 'Advanced'], (title) => {
|
['Basics', 'Advanced'].forEach((title) => {
|
||||||
const list = {
|
const list = {
|
||||||
title,
|
title,
|
||||||
boardId,
|
boardId,
|
||||||
|
|
|
||||||
|
|
@ -43,7 +43,7 @@ Migrations.add('board-background-color', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
Migrations.add('lowercase-board-permission', () => {
|
Migrations.add('lowercase-board-permission', () => {
|
||||||
_.forEach(['Public', 'Private'], (permission) => {
|
['Public', 'Private'].forEach((permission) => {
|
||||||
Boards.update(
|
Boards.update(
|
||||||
{ permission },
|
{ permission },
|
||||||
{ $set: { permission: permission.toLowerCase() } },
|
{ $set: { permission: permission.toLowerCase() } },
|
||||||
|
|
@ -116,11 +116,11 @@ Migrations.add('add-member-isactive-field', () => {
|
||||||
const formerUsers = _.difference(allUsersWithSomeActivity, currentUsers);
|
const formerUsers = _.difference(allUsersWithSomeActivity, currentUsers);
|
||||||
|
|
||||||
const newMemberSet = [];
|
const newMemberSet = [];
|
||||||
_.forEach(board.members, (member) => {
|
board.members.forEach((member) => {
|
||||||
member.isActive = true;
|
member.isActive = true;
|
||||||
newMemberSet.push(member);
|
newMemberSet.push(member);
|
||||||
});
|
});
|
||||||
_.forEach(formerUsers, (userId) => {
|
formerUsers.forEach((userId) => {
|
||||||
newMemberSet.push({
|
newMemberSet.push({
|
||||||
userId,
|
userId,
|
||||||
isAdmin: false,
|
isAdmin: false,
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@ Meteor.publish('boards', function() {
|
||||||
|
|
||||||
// Defensive programming to verify that starredBoards has the expected
|
// Defensive programming to verify that starredBoards has the expected
|
||||||
// format -- since the field is in the `profile` a user can modify it.
|
// format -- since the field is in the `profile` a user can modify it.
|
||||||
const starredBoards = Users.findOne(this.userId).profile.starredBoards || [];
|
const {starredBoards = []} = Users.findOne(this.userId).profile;
|
||||||
check(starredBoards, [String]);
|
check(starredBoards, [String]);
|
||||||
|
|
||||||
return Boards.find({
|
return Boards.find({
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue