mirror of
https://github.com/wekan/wekan.git
synced 2026-03-13 17:06:13 +01:00
Merge branch 'master' of https://github.com/wekan/wekan into move-swimlane
This commit is contained in:
commit
be9e98b2a1
92 changed files with 3489 additions and 21379 deletions
|
|
@ -307,7 +307,8 @@ if (Meteor.isServer) {
|
|||
*
|
||||
* @param {string} boardID the ID of the board
|
||||
* @param {string} customFieldId the ID of the custom field
|
||||
* @return_type CustomFields
|
||||
* @return_type [{_id: string,
|
||||
* boardIds: string}]
|
||||
*/
|
||||
JsonRoutes.add(
|
||||
'GET',
|
||||
|
|
@ -377,9 +378,9 @@ if (Meteor.isServer) {
|
|||
* @param {string} name the name of the custom field
|
||||
* @param {string} type the type of the custom field
|
||||
* @param {string} settings the settings object of the custom field
|
||||
* @param {boolean} showOnCard should we show the custom field on cards?
|
||||
* @param {boolean} automaticallyOnCard should the custom fields automatically be added on cards?
|
||||
* @param {boolean} showLabelOnMiniCard should the label of the custom field be shown on minicards?
|
||||
* @param {boolean} showOnCard should we show the custom field on cards
|
||||
* @param {boolean} automaticallyOnCard should the custom fields automatically be added on cards
|
||||
* @param {boolean} showLabelOnMiniCard should the label of the custom field be shown on minicards
|
||||
* @return_type {_id: string}
|
||||
*/
|
||||
JsonRoutes.add(
|
||||
|
|
@ -444,7 +445,7 @@ if (Meteor.isServer) {
|
|||
* @operation add_custom_field_dropdown_items
|
||||
* @summary Update a Custom Field's dropdown items
|
||||
*
|
||||
* @param {string[]} items names of the custom field
|
||||
* @param {string} [items] names of the custom field
|
||||
* @return_type {_id: string}
|
||||
*/
|
||||
JsonRoutes.add(
|
||||
|
|
@ -453,27 +454,32 @@ if (Meteor.isServer) {
|
|||
(req, res) => {
|
||||
Authentication.checkUserId(req.userId);
|
||||
|
||||
if (req.body.hasOwnProperty('items') && Array.isArray(req.body.items)) {
|
||||
CustomFields.direct.update(
|
||||
{ _id: req.params.customFieldId },
|
||||
{
|
||||
$push: {
|
||||
'settings.dropdownItems': {
|
||||
$each: req.body.items
|
||||
.filter(name => typeof name === 'string')
|
||||
.map(name => ({
|
||||
_id: Random.id(6),
|
||||
name,
|
||||
})),
|
||||
const paramCustomFieldId = req.params.customFieldId;
|
||||
const paramItems = req.body.items;
|
||||
|
||||
if (req.body.hasOwnProperty('items')) {
|
||||
if (Array.isArray(paramItems)) {
|
||||
CustomFields.direct.update(
|
||||
{ _id: paramCustomFieldId },
|
||||
{
|
||||
$push: {
|
||||
'settings.dropdownItems': {
|
||||
$each: paramItems
|
||||
.filter(name => typeof name === 'string')
|
||||
.map(name => ({
|
||||
_id: Random.id(6),
|
||||
name,
|
||||
})),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
);
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
JsonRoutes.sendResult(res, {
|
||||
code: 200,
|
||||
data: { _id: req.params.customFieldId },
|
||||
data: { _id: paramCustomFieldId },
|
||||
});
|
||||
},
|
||||
);
|
||||
|
|
@ -491,17 +497,21 @@ if (Meteor.isServer) {
|
|||
(req, res) => {
|
||||
Authentication.checkUserId(req.userId);
|
||||
|
||||
const paramDropdownItemId = req.params.dropdownItemId;
|
||||
const paramCustomFieldId = req.params.customFieldId;
|
||||
const paramName = req.body.name;
|
||||
|
||||
if (req.body.hasOwnProperty('name')) {
|
||||
CustomFields.direct.update(
|
||||
{
|
||||
_id: req.params.customFieldId,
|
||||
'settings.dropdownItems._id': req.params.dropdownItemId,
|
||||
_id: paramCustomFieldId,
|
||||
'settings.dropdownItems._id': paramDropdownItemId,
|
||||
},
|
||||
{
|
||||
$set: {
|
||||
'settings.dropdownItems.$': {
|
||||
_id: req.params.dropdownItemId,
|
||||
name: req.body.name,
|
||||
_id: paramDropdownItemId,
|
||||
name: paramName,
|
||||
},
|
||||
},
|
||||
},
|
||||
|
|
@ -510,7 +520,7 @@ if (Meteor.isServer) {
|
|||
|
||||
JsonRoutes.sendResult(res, {
|
||||
code: 200,
|
||||
data: { _id: req.params.customFieldId },
|
||||
data: { _id: customFieldId },
|
||||
});
|
||||
},
|
||||
);
|
||||
|
|
@ -528,18 +538,21 @@ if (Meteor.isServer) {
|
|||
(req, res) => {
|
||||
Authentication.checkUserId(req.userId);
|
||||
|
||||
paramCustomFieldId = req.params.customFieldId;
|
||||
paramDropdownItemId = req.params.dropdownItemId;
|
||||
|
||||
CustomFields.direct.update(
|
||||
{ _id: req.params.customFieldId },
|
||||
{ _id: paramCustomFieldId },
|
||||
{
|
||||
$pull: {
|
||||
'settings.dropdownItems': { _id: req.params.dropdownItemId },
|
||||
'settings.dropdownItems': { _id: paramDropdownItemId },
|
||||
},
|
||||
},
|
||||
);
|
||||
|
||||
JsonRoutes.sendResult(res, {
|
||||
code: 200,
|
||||
data: { _id: req.params.customFieldId },
|
||||
data: { _id: paramCustomFieldId },
|
||||
});
|
||||
},
|
||||
);
|
||||
|
|
|
|||
12
models/presences.js
Normal file
12
models/presences.js
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
if (Meteor.isServer) {
|
||||
Meteor.startup(() => {
|
||||
// Date of 7 days ago
|
||||
let lastWeek = new Date();
|
||||
lastWeek.setDate(lastWeek.getDate() - 7);
|
||||
|
||||
presences.remove({ ttl: { $lte: lastWeek } });
|
||||
|
||||
// Create index for serverId that is queried often
|
||||
presences._collection._ensureIndex({ serverId: -1 });
|
||||
});
|
||||
}
|
||||
|
|
@ -416,39 +416,62 @@ export class TrelloCreator {
|
|||
const attachments = this.attachments[card.id];
|
||||
const trelloCoverId = card.idAttachmentCover;
|
||||
if (attachments) {
|
||||
const links = [];
|
||||
attachments.forEach(att => {
|
||||
const file = new FS.File();
|
||||
// Simulating file.attachData on the client generates multiple errors
|
||||
// - HEAD returns null, which causes exception down the line
|
||||
// - the template then tries to display the url to the attachment which causes other errors
|
||||
// so we make it server only, and let UI catch up once it is done, forget about latency comp.
|
||||
const self = this;
|
||||
if (Meteor.isServer) {
|
||||
file.attachData(att.url, function(error) {
|
||||
file.boardId = boardId;
|
||||
file.cardId = cardId;
|
||||
file.userId = self._user(att.idMemberCreator);
|
||||
// The field source will only be used to prevent adding
|
||||
// attachments' related activities automatically
|
||||
file.source = 'import';
|
||||
if (error) {
|
||||
throw error;
|
||||
} else {
|
||||
const wekanAtt = Attachments.insert(file, () => {
|
||||
// we do nothing
|
||||
});
|
||||
self.attachmentIds[att.id] = wekanAtt._id;
|
||||
//
|
||||
if (trelloCoverId === att.id) {
|
||||
Cards.direct.update(cardId, {
|
||||
$set: { coverId: wekanAtt._id },
|
||||
// if the attachment `name` and `url` are the same, then the
|
||||
// attachment is an attached link
|
||||
if (att.name === att.url) {
|
||||
links.push(att.url);
|
||||
} else {
|
||||
const file = new FS.File();
|
||||
// Simulating file.attachData on the client generates multiple errors
|
||||
// - HEAD returns null, which causes exception down the line
|
||||
// - the template then tries to display the url to the attachment which causes other errors
|
||||
// so we make it server only, and let UI catch up once it is done, forget about latency comp.
|
||||
const self = this;
|
||||
if (Meteor.isServer) {
|
||||
file.attachData(att.url, function(error) {
|
||||
file.boardId = boardId;
|
||||
file.cardId = cardId;
|
||||
file.userId = self._user(att.idMemberCreator);
|
||||
// The field source will only be used to prevent adding
|
||||
// attachments' related activities automatically
|
||||
file.source = 'import';
|
||||
if (error) {
|
||||
throw error;
|
||||
} else {
|
||||
const wekanAtt = Attachments.insert(file, () => {
|
||||
// we do nothing
|
||||
});
|
||||
self.attachmentIds[att.id] = wekanAtt._id;
|
||||
//
|
||||
if (trelloCoverId === att.id) {
|
||||
Cards.direct.update(cardId, {
|
||||
$set: { coverId: wekanAtt._id },
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
// todo XXX set cover - if need be
|
||||
});
|
||||
|
||||
if (links.length) {
|
||||
let desc = cardToCreate.description.trim();
|
||||
if (desc) {
|
||||
desc += '\n\n';
|
||||
}
|
||||
desc += `## ${TAPi18n.__('links-heading')}\n`;
|
||||
links.forEach(link => {
|
||||
desc += `* ${link}\n`;
|
||||
});
|
||||
Cards.direct.update(cardId, {
|
||||
$set: {
|
||||
description: desc,
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
result.push(cardId);
|
||||
});
|
||||
|
|
|
|||
|
|
@ -797,6 +797,25 @@ Meteor.methods({
|
|||
|
||||
if (Meteor.isServer) {
|
||||
Meteor.methods({
|
||||
setAllUsersHideSystemMessages() {
|
||||
if (Meteor.user() && Meteor.user().isAdmin) {
|
||||
// If setting is missing, add it
|
||||
Users.update(
|
||||
{ 'profile.hiddenSystemMessages': { $exists: false } },
|
||||
{ $set: { 'profile.hiddenSystemMessages': true } },
|
||||
{ multi: true },
|
||||
);
|
||||
// If setting is false, set it to true
|
||||
Users.update(
|
||||
{ 'profile.hiddenSystemMessages': false },
|
||||
{ $set: { 'profile.hiddenSystemMessages': true } },
|
||||
{ multi: true },
|
||||
);
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
},
|
||||
setCreateUser(
|
||||
fullname,
|
||||
username,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue