Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4bc6ad3b4c | ||
|
|
7f558fede0 | ||
|
|
544bc1d6ad | ||
|
|
89d25f52fa | ||
|
|
2fd71d5be8 | ||
|
|
dc643f3d43 | ||
|
|
4469b12203 | ||
|
|
9cacaafb8f | ||
|
|
269382869e | ||
|
|
8648e32108 | ||
|
|
edf52bc438 | ||
|
|
58ce859368 | ||
|
|
e23aacedb3 | ||
|
|
7f02990626 | ||
|
|
c86155f1aa | ||
|
|
3fae5355d4 | ||
|
|
20e88159ae | ||
|
|
a81921382a | ||
|
|
8f28a409c7 | ||
|
|
7566f05b97 | ||
|
|
268d7fcb32 | ||
|
|
70edd44a01 | ||
|
|
6db717b9b3 | ||
|
|
f389fd95fb | ||
|
|
363bcab98b | ||
|
|
c4a7e53661 | ||
|
|
c6afe8d007 | ||
|
|
93eccffd44 | ||
|
|
fe66169415 | ||
|
|
6ced47aa8c | ||
|
|
e661d03e8d | ||
|
|
f09219cbfd | ||
|
|
7c25542976 | ||
|
|
121686a928 | ||
|
|
3563e0145d | ||
|
|
c630714245 | ||
|
|
5ebb47cb0e | ||
|
|
115701fa65 | ||
|
|
a182dde11f | ||
|
|
1e20e2601f | ||
|
|
4d066b1f30 | ||
|
|
7856692946 | ||
|
|
7e7c8fd001 | ||
|
|
feb602ecd4 | ||
|
|
6ed26e373a | ||
|
|
4fba0fb1a1 | ||
|
|
968ae122b0 | ||
|
|
06c32cb497 | ||
|
|
d2a4925cae | ||
|
|
9c97c301bd | ||
|
|
d4a91d30ff | ||
|
|
6a56a495ad | ||
|
|
3330aff12c | ||
|
|
43bdd56a41 | ||
|
|
a602f4b9ec | ||
|
|
053e47173f | ||
|
|
fe285c62e1 | ||
|
|
a3d44b0774 | ||
|
|
0e79bd25ed | ||
|
|
71f7a680b6 | ||
|
|
411b8d3f56 | ||
|
|
2bbc312ad0 | ||
|
|
14de17b667 | ||
|
|
9083c341c1 | ||
|
|
e0930c32a6 | ||
|
|
a376fb2fab | ||
|
|
e47ff25d45 | ||
|
|
7fa9603f9d |
No files matched your search
Vendored
+10
@@ -0,0 +1,10 @@
|
||||
FROM gitpod/workspace-mongodb
|
||||
|
||||
USER gitpod
|
||||
|
||||
# Install custom tools, runtime, etc. using apt-get
|
||||
# For example, the command below would install "bastet" - a command line tetris clone:
|
||||
#
|
||||
# RUN sudo apt-get -q update && # sudo apt-get install -yq bastet && # sudo rm -rf /var/lib/apt/lists/*
|
||||
#
|
||||
# More information: https://www.gitpod.io/docs/config-docker/
|
||||
@@ -0,0 +1,4 @@
|
||||
tasks:
|
||||
- init: npm install
|
||||
image:
|
||||
file: .gitpod.Dockerfile
|
||||
Generated
+1
-1
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "wekan",
|
||||
"version": "v3.90.0",
|
||||
"version": "v3.95.0",
|
||||
"lockfileVersion": 1,
|
||||
"requires": true,
|
||||
"dependencies": {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "wekan",
|
||||
"version": "v3.90.0",
|
||||
"version": "v3.95.0",
|
||||
"description": "Open-Source kanban",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
|
||||
+1
-1
@@ -3,7 +3,7 @@ sudo: required
|
||||
|
||||
env:
|
||||
TRAVIS_DOCKER_COMPOSE_VERSION: 1.24.0
|
||||
TRAVIS_NODE_VERSION: 12.15.0
|
||||
TRAVIS_NODE_VERSION: 12.16.2
|
||||
TRAVIS_NPM_VERSION: latest
|
||||
|
||||
before_install:
|
||||
|
||||
+91
-2
@@ -1,3 +1,92 @@
|
||||
# v3.95 2020-04-12 Wekan release
|
||||
|
||||
This release adds the following new features:
|
||||
|
||||
- [Add gitpod config](https://github.com/wekan/wekan/pull/3009).
|
||||
This adds support for Gitpod.io, a free automated
|
||||
dev environment that makes contributing and generally working on GitHub
|
||||
projects much easier. It allows anyone to start a ready-to-code dev
|
||||
environment for any branch, issue and pull request with a single click.
|
||||
Thanks to juniormendonca.
|
||||
- [Public boards overview](https://github.com/wekan/wekan/pull/3008).
|
||||
Thanks to NicoP-S.
|
||||
- Try to upgrade Sandstorm Wekan to Meteor 1.10.1 and Node 12.x.
|
||||
Thanks to kentonv and xet7.
|
||||
|
||||
and fixes the following bugs:
|
||||
|
||||
- [Fix styling issue in notifications drawer](https://github.com/wekan/wekan/pull/3012).
|
||||
Thanks to boeserwolf.
|
||||
- [Fix error in notifications cleanup cron](https://github.com/wekan/wekan/pull/3010).
|
||||
Thanks to jtbairdsr.
|
||||
|
||||
Thanks to above GitHub users for their contributions and translators for their translations.
|
||||
|
||||
# v3.94 2020-04-12 Wekan release
|
||||
|
||||
This release adds the following new features:
|
||||
|
||||
- [Public vote](https://github.com/wekan/wekan/pull/3006).
|
||||
Thanks to NicoP-S.
|
||||
- [Add robots.txt disallow all](https://github.com/wekan/wekan/commit/3fae5355d40055757bf4a5f0c503581195609720).
|
||||
Thanks to xet7.
|
||||
|
||||
Thanks to above GitHub users for their contributions and translators for their translations.
|
||||
|
||||
# v3.93 2020-04-10 Wekan release
|
||||
|
||||
This release adds the following new features:
|
||||
|
||||
- [Trello vote import & hide export button if with_api is
|
||||
disabled](https://github.com/wekan/wekan/pull/3000).
|
||||
Thanks to NicoP-S.
|
||||
- [When adding a user to a board that has subtasks, also add user to the subtask
|
||||
board](https://github.com/wekan/wekan/pull/3004).
|
||||
Thanks to slvrpdr.
|
||||
|
||||
and adds the following updates:
|
||||
|
||||
- Upgrade to Node v12.16.2 [Part1](https://github.com/wekan/wekan/commit/6db717b9b384fe1491063e507b80e67791a07e3a)
|
||||
and [Part2](https://github.com/wekan/wekan/commit/268d7fcb32186a902a84e7f6d80c50b1f3790bad).
|
||||
Thanks to Node developers and xet7.
|
||||
|
||||
and fixes the following bugs:
|
||||
|
||||
- [Fix bug that prevents editing or deleting
|
||||
comments](https://github.com/wekan/wekan/pull/3005).
|
||||
Thanks to jtbairdsr.
|
||||
|
||||
Thanks to above GitHub users for their contributions and translators for their translations.
|
||||
|
||||
# v3.92 2020-04-09 Wekan release
|
||||
|
||||
This release adds the following new features:
|
||||
|
||||
- [Scheduler to clean up read notifications. Also added a button to manually remove all
|
||||
read notifications, and a fix to prevent users form getting notifications for their own
|
||||
actions](https://github.com/wekan/wekan/pull/2998).
|
||||
Thanks to jtbairdsr.
|
||||
- [Add setting](https://github.com/wekan/wekan/commit/5ebb47cb0ec7272894a37d99579ede872251f55c)
|
||||
default [NOTIFICATION_TRAY_AFTER_READ_DAYS_BEFORE_REMOVE=2](https://github.com/wekan/wekan/pull/2998)
|
||||
to all Wekan platforms.
|
||||
Thanks to xet7.
|
||||
|
||||
Thanks to above GitHub users for their contributions and translators for their translations.
|
||||
|
||||
# v3.91 2020-04-08 Wekan release
|
||||
|
||||
This release adds the following new features:
|
||||
|
||||
- [OpenShift: Route template added to helm chart for Openshift v4x
|
||||
cluster](https://github.com/wekan/wekan/pull/2996).
|
||||
Thanks to ckavili.
|
||||
- [Filter by Assignee](https://github.com/wekan/wekan/pull/2997).
|
||||
Thanks to daniel-eder.
|
||||
- [Vote on Card](https://github.com/wekan/wekan/pull/2994).
|
||||
Thanks to NicoP-S and xet7.
|
||||
|
||||
Thanks to above GitHub users for their contributions and translators for their translations.
|
||||
|
||||
# v3.90 2020-04-06 Wekan release
|
||||
|
||||
This release makes the following updates:
|
||||
@@ -38,7 +127,7 @@ and fixes the following bugs:
|
||||
|
||||
- [Fix start-wekan.sh MongoDB port to 27017](https://github.com/wekan/wekan/commit/c60a092fc0ed9fe15c417bcb443b1e3e3aaedf7e).
|
||||
Thanks to Keelan and xet7.
|
||||
|
||||
|
||||
Thanks to above GitHub users for their contributions and translators for their translations.
|
||||
|
||||
# v3.87 2020-04-01 Wekan release
|
||||
@@ -78,7 +167,7 @@ This release fixes the following bugs:
|
||||
@member mention not close card, and disabling clicking of
|
||||
@member mention](https://github.com/wekan/wekan/commit/b9099a8b7ea6f63c79bdcbb871cb993b2cb7e325).
|
||||
Thanks to xet7 !
|
||||
|
||||
|
||||
Thanks to above GitHub users for their contributions and translators for their translations.
|
||||
|
||||
# v3.85 2020-03-23 Wekan release
|
||||
|
||||
+2
-1
@@ -6,7 +6,7 @@ LABEL maintainer="wekan"
|
||||
# ENV BUILD_DEPS="paxctl"
|
||||
ENV BUILD_DEPS="apt-utils libarchive-tools gnupg gosu wget curl bzip2 g++ build-essential git ca-certificates python3" \
|
||||
DEBUG=false \
|
||||
NODE_VERSION=v12.16.1 \
|
||||
NODE_VERSION=v12.16.2 \
|
||||
METEOR_RELEASE=1.10-rc.2 \
|
||||
USE_EDGE=false \
|
||||
METEOR_EDGE=1.5-beta.17 \
|
||||
@@ -26,6 +26,7 @@ ENV BUILD_DEPS="apt-utils libarchive-tools gnupg gosu wget curl bzip2 g++ build-
|
||||
ATTACHMENTS_STORE_PATH="" \
|
||||
MAX_IMAGE_PIXEL="" \
|
||||
IMAGE_COMPRESS_RATIO="" \
|
||||
NOTIFICATION_TRAY_AFTER_READ_DAYS_BEFORE_REMOVE="" \
|
||||
BIGEVENTS_PATTERN=NONE \
|
||||
NOTIFY_DUE_DAYS_BEFORE_AND_AFTER="" \
|
||||
NOTIFY_DUE_AT_HOUR_OF_DAY="" \
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
[](https://gitpod.io/#https://github.com/wekan/wekan)
|
||||
|
||||
# Wekan - Open Source kanban
|
||||
|
||||
[](https://github.com/wekan/wekan/graphs/contributors)
|
||||
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
appId: wekan-public/apps/77b94f60-dec9-0136-304e-16ff53095928
|
||||
appVersion: "v3.90.0"
|
||||
appVersion: "v3.95.0"
|
||||
files:
|
||||
userUploads:
|
||||
- README.md
|
||||
|
||||
@@ -180,7 +180,7 @@ BlazeComponent.extendComponent({
|
||||
{
|
||||
// XXX We should use Popup.afterConfirmation here
|
||||
'click .js-delete-comment'() {
|
||||
const commentId = this.currentData().commentId;
|
||||
const commentId = this.currentData().activity.commentId;
|
||||
CardComments.remove(commentId);
|
||||
},
|
||||
'submit .js-edit-comment'(evt) {
|
||||
@@ -188,7 +188,7 @@ BlazeComponent.extendComponent({
|
||||
const commentText = this.currentComponent()
|
||||
.getValue()
|
||||
.trim();
|
||||
const commentId = Template.parentData().commentId;
|
||||
const commentId = Template.parentData().activity.commentId;
|
||||
if (commentText) {
|
||||
CardComments.update(commentId, {
|
||||
$set: {
|
||||
|
||||
@@ -33,22 +33,6 @@ Template.boardMenuPopup.events({
|
||||
'click .js-card-settings': Popup.open('boardCardSettings'),
|
||||
});
|
||||
|
||||
Template.boardMenuPopup.helpers({
|
||||
exportUrl() {
|
||||
const params = {
|
||||
boardId: Session.get('currentBoard'),
|
||||
};
|
||||
const queryParams = {
|
||||
authToken: Accounts._storedLoginToken(),
|
||||
};
|
||||
return FlowRouter.path('/api/boards/:boardId/export', params, queryParams);
|
||||
},
|
||||
exportFilename() {
|
||||
const boardId = Session.get('currentBoard');
|
||||
return `wekan-export-board-${boardId}.json`;
|
||||
},
|
||||
});
|
||||
|
||||
Template.boardChangeTitlePopup.events({
|
||||
submit(event, templateInstance) {
|
||||
const newTitle = templateInstance
|
||||
|
||||
@@ -55,7 +55,7 @@ template(name="boardList")
|
||||
title="{{_ 'archive-board'}}")
|
||||
|
||||
template(name="boardListHeaderBar")
|
||||
h1 {{_ 'my-boards'}}
|
||||
h1 {{_ title }}
|
||||
.board-header-btns.right
|
||||
a.board-header-btn.js-open-archived-board
|
||||
i.fa.fa-archive
|
||||
|
||||
@@ -7,6 +7,9 @@ Template.boardListHeaderBar.events({
|
||||
});
|
||||
|
||||
Template.boardListHeaderBar.helpers({
|
||||
title(){
|
||||
return FlowRouter.getRouteName() == 'home' ? 'my-boards' :'public';
|
||||
},
|
||||
templatesBoardId() {
|
||||
return Meteor.user() && Meteor.user().getTemplatesBoardId();
|
||||
},
|
||||
@@ -21,12 +24,17 @@ BlazeComponent.extendComponent({
|
||||
},
|
||||
|
||||
boards() {
|
||||
let query = {
|
||||
archived: false,
|
||||
type: 'board',
|
||||
}
|
||||
if (FlowRouter.getRouteName() == 'home')
|
||||
query['members.userId'] = Meteor.userId()
|
||||
else
|
||||
query.permission = 'public'
|
||||
|
||||
return Boards.find(
|
||||
{
|
||||
archived: false,
|
||||
'members.userId': Meteor.userId(),
|
||||
type: 'board',
|
||||
},
|
||||
query,
|
||||
{ sort: ['title'] },
|
||||
);
|
||||
},
|
||||
|
||||
@@ -199,6 +199,24 @@ template(name="cardDetails")
|
||||
+viewer
|
||||
= getAssignedBy
|
||||
|
||||
if getVoteQuestion
|
||||
hr
|
||||
.vote-title
|
||||
h3
|
||||
i.fa.fa-thumbs-up
|
||||
card-details-item-title {{_ 'vote-question'}}
|
||||
.vote-result
|
||||
if votePublic
|
||||
a.card-label.card-label-green.js-show-positive-votes {{ voteCountPositive }}
|
||||
a.card-label.card-label-red.js-show-negative-votes {{ voteCountNegative }}
|
||||
else
|
||||
.card-label.card-label-green {{ voteCountPositive }}
|
||||
.card-label.card-label-red {{ voteCountNegative }}
|
||||
+viewer
|
||||
= getVoteQuestion
|
||||
button.card-details-green.js-vote.js-vote-positive(class="{{#if voteState}}voted{{/if}}") {{_ 'vote-for-it'}}
|
||||
button.card-details-red.js-vote.js-vote-negative(class="{{#if $eq voteState false}}voted{{/if}}") {{_ 'vote-against'}}
|
||||
|
||||
//- XXX We should use "editable" to avoid repetiting ourselves
|
||||
if canModifyCard
|
||||
unless currentUser.isWorker
|
||||
@@ -315,6 +333,16 @@ template(name="cardDetailsActionsPopup")
|
||||
//li: a.js-members {{_ 'card-edit-members'}}
|
||||
//li: a.js-labels {{_ 'card-edit-labels'}}
|
||||
//li: a.js-attachments {{_ 'card-edit-attachments'}}
|
||||
if getVoteQuestion
|
||||
li
|
||||
a.js-cancel-voting
|
||||
i.fa.fa-thumbs-up
|
||||
| {{_ 'card-cancel-voting'}}
|
||||
else
|
||||
li
|
||||
a.js-start-voting
|
||||
i.fa.fa-thumbs-up
|
||||
| {{_ 'card-start-voting'}}
|
||||
li
|
||||
a.js-custom-fields
|
||||
i.fa.fa-list-alt
|
||||
@@ -538,3 +566,35 @@ template(name="cardDeletePopup")
|
||||
unless archived
|
||||
p {{_ "card-delete-suggest-archive"}}
|
||||
button.js-confirm.negate.full(type="submit") {{_ 'delete'}}
|
||||
|
||||
template(name="cardStartVotingPopup")
|
||||
form.edit-vote-question
|
||||
.fields
|
||||
label(for="vote") {{_ 'vote-question'}}
|
||||
input.js-vote-field#vote(type="text" name="vote" value="{{card.getVoteQuestion}}" autofocus)
|
||||
label(for="vote-public") {{_ 'vote-public'}}
|
||||
a.js-toggle-vote-public
|
||||
.materialCheckBox#vote-public(name="vote-public")
|
||||
|
||||
button.primary.confirm.js-submit {{_ 'save'}}
|
||||
//- button.js-remove-color.negate.wide.right {{_ 'delete'}}
|
||||
|
||||
template(name="positiveVoteMembersPopup")
|
||||
ul.pop-over-list.js-card-member-list
|
||||
each m in voteMemberPositive
|
||||
li.item
|
||||
a.name
|
||||
+userAvatar(userId=m._id)
|
||||
span.full-name
|
||||
= m.profile.fullname
|
||||
| (<span class="username">{{ m.username }}</span>)
|
||||
|
||||
template(name="negativeVoteMembersPopup")
|
||||
ul.pop-over-list.js-card-member-list
|
||||
each m in voteMemberNegative
|
||||
li.item
|
||||
a.name
|
||||
+userAvatar(userId=m._id)
|
||||
span.full-name
|
||||
= m.profile.fullname
|
||||
| (<span class="username">{{ m.username }}</span>)
|
||||
@@ -38,6 +38,38 @@ BlazeComponent.extendComponent({
|
||||
Meteor.subscribe('unsaved-edits');
|
||||
},
|
||||
|
||||
voteState() {
|
||||
const card = this.currentData();
|
||||
const userId = Meteor.userId();
|
||||
let state;
|
||||
if (card.vote) {
|
||||
if (card.vote.positive) {
|
||||
state = _.contains(card.vote.positive, userId);
|
||||
if (state === true) return true;
|
||||
}
|
||||
if (card.vote.negative) {
|
||||
state = _.contains(card.vote.negative, userId);
|
||||
if (state === true) return false;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
},
|
||||
votePublic() {
|
||||
const card = this.currentData();
|
||||
if (card.vote)
|
||||
return card.vote.public
|
||||
return null
|
||||
},
|
||||
voteCountPositive() {
|
||||
const card = this.currentData();
|
||||
if (card.vote && card.vote.positive) return card.vote.positive.length;
|
||||
return null;
|
||||
},
|
||||
voteCountNegative() {
|
||||
const card = this.currentData();
|
||||
if (card.vote && card.vote.negative) return card.vote.negative.length;
|
||||
return null;
|
||||
},
|
||||
isWatching() {
|
||||
const card = this.currentData();
|
||||
return card.findWatcher(Meteor.userId());
|
||||
@@ -356,6 +388,8 @@ BlazeComponent.extendComponent({
|
||||
'click .js-start-date': Popup.open('editCardStartDate'),
|
||||
'click .js-due-date': Popup.open('editCardDueDate'),
|
||||
'click .js-end-date': Popup.open('editCardEndDate'),
|
||||
'click .js-show-positive-votes':Popup.open('positiveVoteMembers'),
|
||||
'click .js-show-negative-votes': Popup.open('negativeVoteMembers'),
|
||||
'mouseenter .js-card-details'() {
|
||||
const parentComponent = this.parentComponent().parentComponent();
|
||||
//on mobile view parent is Board, not BoardBody.
|
||||
@@ -379,6 +413,18 @@ BlazeComponent.extendComponent({
|
||||
'click #toggleButton'() {
|
||||
Meteor.call('toggleSystemMessages');
|
||||
},
|
||||
'click .js-vote'(e) {
|
||||
const forIt = $(e.target).hasClass('js-vote-positive');
|
||||
let newState = null;
|
||||
if (
|
||||
this.voteState() == null ||
|
||||
(this.voteState() == false && forIt) ||
|
||||
(this.voteState() == true && !forIt)
|
||||
) {
|
||||
newState = forIt;
|
||||
}
|
||||
this.data().setVote(Meteor.userId(), newState);
|
||||
},
|
||||
},
|
||||
];
|
||||
},
|
||||
@@ -560,6 +606,7 @@ Template.cardDetailsActionsPopup.events({
|
||||
'click .js-assignees': Popup.open('cardAssignees'),
|
||||
'click .js-labels': Popup.open('cardLabels'),
|
||||
'click .js-attachments': Popup.open('cardAttachments'),
|
||||
'click .js-start-voting': Popup.open('cardStartVoting'),
|
||||
'click .js-custom-fields': Popup.open('cardCustomFields'),
|
||||
'click .js-received-date': Popup.open('editCardReceivedDate'),
|
||||
'click .js-start-date': Popup.open('editCardStartDate'),
|
||||
@@ -570,6 +617,11 @@ Template.cardDetailsActionsPopup.events({
|
||||
'click .js-copy-card': Popup.open('copyCard'),
|
||||
'click .js-copy-checklist-cards': Popup.open('copyChecklistToManyCards'),
|
||||
'click .js-set-card-color': Popup.open('setCardColor'),
|
||||
'click .js-cancel-voting'(event) {
|
||||
event.preventDefault();
|
||||
this.unsetVote();
|
||||
Popup.close();
|
||||
},
|
||||
'click .js-move-card-to-top'(event) {
|
||||
event.preventDefault();
|
||||
const minOrder = _.min(
|
||||
@@ -603,7 +655,7 @@ Template.cardDetailsActionsPopup.events({
|
||||
},
|
||||
});
|
||||
|
||||
Template.editCardTitleForm.onRendered(function() {
|
||||
Template.editCardTitleForm.onRendered(function () {
|
||||
autosize(this.$('.js-edit-card-title'));
|
||||
});
|
||||
|
||||
@@ -617,7 +669,7 @@ Template.editCardTitleForm.events({
|
||||
},
|
||||
});
|
||||
|
||||
Template.editCardRequesterForm.onRendered(function() {
|
||||
Template.editCardRequesterForm.onRendered(function () {
|
||||
autosize(this.$('.js-edit-card-requester'));
|
||||
});
|
||||
|
||||
@@ -630,7 +682,7 @@ Template.editCardRequesterForm.events({
|
||||
},
|
||||
});
|
||||
|
||||
Template.editCardAssignerForm.onRendered(function() {
|
||||
Template.editCardAssignerForm.onRendered(function () {
|
||||
autosize(this.$('.js-edit-card-assigner'));
|
||||
});
|
||||
|
||||
@@ -770,7 +822,7 @@ Template.copyChecklistToManyCardsPopup.events({
|
||||
|
||||
// copy subtasks
|
||||
cursor = Cards.find({ parentId: oldId });
|
||||
cursor.forEach(function() {
|
||||
cursor.forEach(function () {
|
||||
'use strict';
|
||||
const subtask = arguments[0];
|
||||
subtask.parentId = _id;
|
||||
@@ -919,7 +971,7 @@ BlazeComponent.extendComponent({
|
||||
}
|
||||
}
|
||||
},
|
||||
'click .js-delete': Popup.afterConfirm('cardDelete', function() {
|
||||
'click .js-delete': Popup.afterConfirm('cardDelete', function () {
|
||||
Popup.close();
|
||||
Cards.remove(this._id);
|
||||
Utils.goBoardId(this.boardId);
|
||||
@@ -945,6 +997,31 @@ BlazeComponent.extendComponent({
|
||||
},
|
||||
}).register('cardMorePopup');
|
||||
|
||||
BlazeComponent.extendComponent({
|
||||
onCreated() {
|
||||
this.currentCard = this.currentData();
|
||||
this.voteQuestion = new ReactiveVar(this.currentCard.voteQuestion);
|
||||
},
|
||||
|
||||
events() {
|
||||
return [
|
||||
{
|
||||
'submit .edit-vote-question'(evt) {
|
||||
evt.preventDefault();
|
||||
const voteQuestion = evt.target.vote.value;
|
||||
const publicVote = $('#vote-public').hasClass('is-checked');
|
||||
this.currentCard.setVoteQuestion(voteQuestion, publicVote);
|
||||
Popup.close();
|
||||
},
|
||||
'click a.js-toggle-vote-public'(event) {
|
||||
event.preventDefault();
|
||||
$('#vote-public').toggleClass('is-checked');
|
||||
},
|
||||
},
|
||||
];
|
||||
},
|
||||
}).register('cardStartVotingPopup');
|
||||
|
||||
// Close the card details pane by pressing escape
|
||||
EscapeActions.register(
|
||||
'detailsPane',
|
||||
|
||||
@@ -100,11 +100,11 @@ avatar-radius = 50%
|
||||
|
||||
.ps-scrollbar-y-rail
|
||||
pointer-event: all
|
||||
position: absolute;
|
||||
position: absolute
|
||||
|
||||
.card-details-canvas
|
||||
width: 470px
|
||||
padding-left: 20px;
|
||||
padding-left: 20px
|
||||
|
||||
.card-details-header
|
||||
margin: 0 -20px 5px
|
||||
@@ -241,7 +241,7 @@ input[type="submit"].attachment-add-link-submit
|
||||
|
||||
.card-details-canvas
|
||||
width: 100%
|
||||
padding-left: 0px;
|
||||
padding-left: 0px
|
||||
|
||||
.card-details-header
|
||||
.close-card-details
|
||||
@@ -330,3 +330,13 @@ card-details-color(background, color...)
|
||||
|
||||
.card-details-indigo
|
||||
card-details-color(#4b0082, #ffffff) //White text for better visibility
|
||||
|
||||
.voted
|
||||
opacity: .7
|
||||
.vote-title
|
||||
display: flex
|
||||
justify-content: space-between
|
||||
.vote-result
|
||||
display: flex
|
||||
.js-show-positive-votes
|
||||
cursor: pointer
|
||||
@@ -100,6 +100,10 @@ template(name="minicard")
|
||||
if getDescription
|
||||
.badge.badge-state-image-only(title=getDescription)
|
||||
span.badge-icon.fa.fa-align-left
|
||||
if getVoteQuestion
|
||||
.badge.badge-state-image-only(title=getVoteQuestion)
|
||||
span.badge-icon.fa.fa-thumbs-up
|
||||
span.badge-icon.fa.fa-thumbs-down
|
||||
if attachments.count
|
||||
.badge
|
||||
span.badge-icon.fa.fa-paperclip
|
||||
|
||||
@@ -22,11 +22,20 @@ BlazeComponent.extendComponent({
|
||||
const listId = targetBoard.getDefaultSubtasksListId();
|
||||
|
||||
//Get the full swimlane data for the parent task.
|
||||
const parentSwimlane = Swimlanes.findOne({boardId: crtBoard._id, _id: card.swimlaneId});
|
||||
const parentSwimlane = Swimlanes.findOne({
|
||||
boardId: crtBoard._id,
|
||||
_id: card.swimlaneId,
|
||||
});
|
||||
//find the swimlane of the same name in the target board.
|
||||
const targetSwimlane = Swimlanes.findOne({boardId: targetBoard._id, title: parentSwimlane.title});
|
||||
const targetSwimlane = Swimlanes.findOne({
|
||||
boardId: targetBoard._id,
|
||||
title: parentSwimlane.title,
|
||||
});
|
||||
//If no swimlane with a matching title exists in the target board, fall back to the default swimlane.
|
||||
const swimlaneId = targetSwimlane === undefined ? targetBoard.getDefaultSwimline()._id : targetSwimlane._id;
|
||||
const swimlaneId =
|
||||
targetSwimlane === undefined
|
||||
? targetBoard.getDefaultSwimline()._id
|
||||
: targetSwimlane._id;
|
||||
|
||||
if (title) {
|
||||
const _id = Cards.insert({
|
||||
|
||||
@@ -24,6 +24,11 @@ template(name="header")
|
||||
a(href="{{pathFor 'home'}}")
|
||||
span.fa.fa-home
|
||||
| {{_ 'all-boards'}}
|
||||
li.separator -
|
||||
li
|
||||
a(href="{{pathFor 'public'}}")
|
||||
span.fa.fa-globe
|
||||
| {{_ 'public'}}
|
||||
each currentUser.starredBoards
|
||||
li.separator -
|
||||
li(class="{{#if $.Session.equals 'currentBoard' _id}}current{{/if}}")
|
||||
|
||||
@@ -127,7 +127,7 @@
|
||||
&.current
|
||||
color: darken(white, 5%)
|
||||
|
||||
&:first-child .fa-home
|
||||
&:first-child .fa-home,&:nth-child(3) .fa-globe
|
||||
margin-right: 5px
|
||||
|
||||
a.js-create-board
|
||||
|
||||
@@ -73,7 +73,7 @@ Template.userFormsLayout.helpers({
|
||||
name = 'Igbo';
|
||||
} else if (lang.name === 'oc') {
|
||||
name = 'Occitan';
|
||||
} else if (lang.name === 'zh-TW') {
|
||||
} else if (lang.name === '繁体中文(台湾)') {
|
||||
name = '繁體中文(台灣)';
|
||||
}
|
||||
return { tag, name };
|
||||
|
||||
@@ -14,3 +14,7 @@ template(name='notificationsDrawer')
|
||||
+notification(activityData=activity index=dbIndex read=read)
|
||||
if($gt unreadNotifications 0)
|
||||
a.all-read {{_ 'mark-all-as-read'}}
|
||||
if ($and ($.Session.get 'showReadNotifications') ($gt readNotifications 0))
|
||||
a.remove-read
|
||||
i.fa.fa-trash
|
||||
| {{_ 'remove-all-read'}}
|
||||
@@ -16,6 +16,13 @@ Template.notificationsDrawer.helpers({
|
||||
transformedProfile() {
|
||||
return Users.findOne(Meteor.userId());
|
||||
},
|
||||
readNotifications() {
|
||||
const readNotifications = _.filter(
|
||||
Meteor.user().profile.notifications,
|
||||
v => !!v.read,
|
||||
);
|
||||
return readNotifications.length;
|
||||
},
|
||||
});
|
||||
|
||||
Template.notificationsDrawer.events({
|
||||
@@ -35,4 +42,12 @@ Template.notificationsDrawer.events({
|
||||
'click .toggle-read'() {
|
||||
Session.set('showReadNotifications', !Session.get('showReadNotifications'));
|
||||
},
|
||||
'click .remove-read'() {
|
||||
const user = Meteor.user();
|
||||
for (const notification of user.profile.notifications) {
|
||||
if (notification.read) {
|
||||
user.removeNotification(notification.activity);
|
||||
}
|
||||
}
|
||||
},
|
||||
});
|
||||
@@ -10,8 +10,7 @@ section#notifications-drawer
|
||||
border-radius: 2px
|
||||
max-height: calc(100vh - 28px - 36px)
|
||||
color: black
|
||||
padding-top 36px;
|
||||
overflow: scroll
|
||||
padding-top 36px
|
||||
|
||||
a:hover
|
||||
color: belize !important
|
||||
@@ -45,13 +44,26 @@ section#notifications-drawer
|
||||
line-height: 24px
|
||||
opacity 1
|
||||
|
||||
.all-read
|
||||
.all-read,
|
||||
.remove-read
|
||||
color belize
|
||||
background-color: #fafafa
|
||||
margin 8px 16px 12px
|
||||
display inline-block
|
||||
|
||||
.remove-read
|
||||
float right
|
||||
|
||||
&:hover
|
||||
color #eb4646 !important
|
||||
|
||||
i.fa
|
||||
color inherit
|
||||
|
||||
|
||||
ul.notifications
|
||||
display: block
|
||||
padding: 0px 16px
|
||||
margin: 0
|
||||
height: calc(100vh - 102px)
|
||||
overflow-y: scroll
|
||||
@@ -298,10 +298,11 @@ template(name="boardMenuPopup")
|
||||
if currentUser.isBoardAdmin
|
||||
hr
|
||||
ul.pop-over-list
|
||||
li
|
||||
a(href="{{exportUrl}}", download="{{exportFilename}}")
|
||||
i.fa.fa-share-alt
|
||||
| {{_ 'export-board'}}
|
||||
if withApi
|
||||
li
|
||||
a(href="{{exportUrl}}", download="{{exportFilename}}")
|
||||
i.fa.fa-share-alt
|
||||
| {{_ 'export-board'}}
|
||||
li
|
||||
a.js-outgoing-webhooks
|
||||
i.fa.fa-globe
|
||||
@@ -326,11 +327,12 @@ template(name="boardMenuPopup")
|
||||
if isSandstorm
|
||||
hr
|
||||
ul.pop-over-list
|
||||
li
|
||||
a(href="{{exportUrl}}", download="{{exportFilename}}")
|
||||
i.fa.fa-share-alt
|
||||
i.fa.fa-sign-out
|
||||
| {{_ 'export-board'}}
|
||||
if withApi
|
||||
li
|
||||
a(href="{{exportUrl}}", download="{{exportFilename}}")
|
||||
i.fa.fa-share-alt
|
||||
i.fa.fa-sign-out
|
||||
| {{_ 'export-board'}}
|
||||
li
|
||||
a.js-import-board
|
||||
i.fa.fa-share-alt
|
||||
|
||||
@@ -196,14 +196,14 @@ Template.boardMenuPopup.events({
|
||||
},
|
||||
'click .js-change-board-color': Popup.open('boardChangeColor'),
|
||||
'click .js-change-language': Popup.open('changeLanguage'),
|
||||
'click .js-archive-board ': Popup.afterConfirm('archiveBoard', function() {
|
||||
'click .js-archive-board ': Popup.afterConfirm('archiveBoard', function () {
|
||||
const currentBoard = Boards.findOne(Session.get('currentBoard'));
|
||||
currentBoard.archive();
|
||||
// XXX We should have some kind of notification on top of the page to
|
||||
// confirm that the board was successfully archived.
|
||||
FlowRouter.go('home');
|
||||
}),
|
||||
'click .js-delete-board': Popup.afterConfirm('deleteBoard', function() {
|
||||
'click .js-delete-board': Popup.afterConfirm('deleteBoard', function () {
|
||||
const currentBoard = Boards.findOne(Session.get('currentBoard'));
|
||||
Popup.close();
|
||||
Boards.remove(currentBoard._id);
|
||||
@@ -215,7 +215,18 @@ Template.boardMenuPopup.events({
|
||||
'click .js-card-settings': Popup.open('boardCardSettings'),
|
||||
});
|
||||
|
||||
|
||||
Template.boardMenuPopup.onCreated(function () {
|
||||
this.apiEnabled = new ReactiveVar(false);
|
||||
Meteor.call('_isApiEnabled', (e, result) => {
|
||||
this.apiEnabled.set(result)
|
||||
})
|
||||
})
|
||||
|
||||
Template.boardMenuPopup.helpers({
|
||||
withApi() {
|
||||
return Template.instance().apiEnabled.get()
|
||||
},
|
||||
exportUrl() {
|
||||
const params = {
|
||||
boardId: Session.get('currentBoard'),
|
||||
@@ -237,7 +248,7 @@ Template.memberPopup.events({
|
||||
Popup.close();
|
||||
},
|
||||
'click .js-change-role': Popup.open('changePermissions'),
|
||||
'click .js-remove-member': Popup.afterConfirm('removeMember', function() {
|
||||
'click .js-remove-member': Popup.afterConfirm('removeMember', function () {
|
||||
const boardId = Session.get('currentBoard');
|
||||
const memberId = this.userId;
|
||||
Cards.find({ boardId, members: memberId }).forEach(card => {
|
||||
@@ -578,7 +589,7 @@ BlazeComponent.extendComponent({
|
||||
'subtext-with-parent',
|
||||
'no-parent',
|
||||
];
|
||||
options.forEach(function(element) {
|
||||
options.forEach(function (element) {
|
||||
if (element !== value) {
|
||||
$(`#${element} ${MCB}`).toggleClass(CKCLS, false);
|
||||
$(`#${element}`).toggleClass(CKCLS, false);
|
||||
|
||||
@@ -45,6 +45,24 @@ template(name="filterSidebar")
|
||||
if Filter.members.isSelected _id
|
||||
i.fa.fa-check
|
||||
hr
|
||||
ul.sidebar-list
|
||||
li(class="{{#if Filter.assignees.isSelected undefined}}active{{/if}}")
|
||||
a.name.js-toggle-assignee-filter
|
||||
span.sidebar-list-item-description
|
||||
| {{_ 'filter-no-assignee'}}
|
||||
if Filter.assignees.isSelected undefined
|
||||
i.fa.fa-check
|
||||
each currentBoard.activeMembers
|
||||
with getUser userId
|
||||
li(class="{{#if Filter.assignees.isSelected _id}}active{{/if}}")
|
||||
a.name.js-toggle-assignee-filter
|
||||
+userAvatar(userId=this._id)
|
||||
span.sidebar-list-item-description
|
||||
= profile.fullname
|
||||
| (<span class="username">{{ username }}</span>)
|
||||
if Filter.assignees.isSelected _id
|
||||
i.fa.fa-check
|
||||
hr
|
||||
ul.sidebar-list
|
||||
li(class="{{#if Filter.customFields.isSelected undefined}}active{{/if}}")
|
||||
a.name.js-toggle-custom-fields-filter
|
||||
|
||||
@@ -18,6 +18,11 @@ BlazeComponent.extendComponent({
|
||||
Filter.members.toggle(this.currentData()._id);
|
||||
Filter.resetExceptions();
|
||||
},
|
||||
'click .js-toggle-assignee-filter'(evt) {
|
||||
evt.preventDefault();
|
||||
Filter.assignees.toggle(this.currentData()._id);
|
||||
Filter.resetExceptions();
|
||||
},
|
||||
'click .js-toggle-archive-filter'(evt) {
|
||||
evt.preventDefault();
|
||||
Filter.archive.toggle(this.currentData()._id);
|
||||
|
||||
@@ -166,6 +166,8 @@ Template.changeLanguagePopup.helpers({
|
||||
name = 'Igbo';
|
||||
} else if (lang.name === 'oc') {
|
||||
name = 'Occitan';
|
||||
} else if (lang.name === '繁体中文(台湾)') {
|
||||
name = '繁體中文(台灣)';
|
||||
}
|
||||
return { tag, name };
|
||||
}).sort(function(a, b) {
|
||||
|
||||
@@ -459,13 +459,21 @@ Filter = {
|
||||
// before changing the schema.
|
||||
labelIds: new SetFilter(),
|
||||
members: new SetFilter(),
|
||||
assignees: new SetFilter(),
|
||||
archive: new SetFilter(),
|
||||
hideEmpty: new SetFilter(),
|
||||
customFields: new SetFilter('_id'),
|
||||
advanced: new AdvancedFilter(),
|
||||
lists: new AdvancedFilter(), // we need the ability to filter list by name as well
|
||||
|
||||
_fields: ['labelIds', 'members', 'archive', 'hideEmpty', 'customFields'],
|
||||
_fields: [
|
||||
'labelIds',
|
||||
'members',
|
||||
'assignees',
|
||||
'archive',
|
||||
'hideEmpty',
|
||||
'customFields',
|
||||
],
|
||||
|
||||
// We don't filter cards that have been added after the last filter change. To
|
||||
// implement this we keep the id of these cards in this `_exceptions` fields
|
||||
|
||||
@@ -26,6 +26,27 @@ FlowRouter.route('/', {
|
||||
},
|
||||
});
|
||||
|
||||
FlowRouter.route('/public', {
|
||||
name: 'public',
|
||||
triggersEnter: [AccountsTemplates.ensureSignedIn],
|
||||
action() {
|
||||
Session.set('currentBoard', null);
|
||||
Session.set('currentList', null);
|
||||
Session.set('currentCard', null);
|
||||
|
||||
Filter.reset();
|
||||
EscapeActions.executeAll();
|
||||
|
||||
Utils.manageCustomUI();
|
||||
Utils.manageMatomo();
|
||||
|
||||
BlazeLayout.render('defaultLayout', {
|
||||
headerBar: 'boardListHeaderBar',
|
||||
content: 'boardList',
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
FlowRouter.route('/b/:id/:slug', {
|
||||
name: 'board',
|
||||
action(params) {
|
||||
|
||||
@@ -254,6 +254,11 @@ services:
|
||||
#-MAX_IMAGE_PIXEL=1024
|
||||
#-IMAGE_COMPRESS_RATIO=80
|
||||
#---------------------------------------------------------------
|
||||
# ==== NOTIFICATION TRAY AFTER READ DAYS BEFORE REMOVE =====
|
||||
# Number of days after a notification is read before we remove it.
|
||||
# Default: 2
|
||||
#- NOTIFICATION_TRAY_AFTER_READ_DAYS_BEFORE_REMOVE=2
|
||||
#---------------------------------------------------------------
|
||||
# ==== BIGEVENTS DUE ETC NOTIFICATIONS =====
|
||||
# https://github.com/wekan/wekan/pull/2541
|
||||
# Introduced a system env var BIGEVENTS_PATTERN default as "NONE",
|
||||
|
||||
@@ -56,3 +56,10 @@ mongodb-replicaset:
|
||||
This section controls the scale of the MongoDB redundant Replica Set.
|
||||
|
||||
**replicas:** This is the number of MongoDB instances to include in the set. You can set this to 1 for a single server - this will still allow you to scale-up later with a helm upgrade.
|
||||
|
||||
### Install OCP route
|
||||
If you use this chart to deploy Wekan on an OCP cluster, you can create route instead of ingress with following command:
|
||||
|
||||
``` bash
|
||||
$ helm template --set route.enabled=true,ingress.enabled=false values.yaml . | oc apply -f-
|
||||
```
|
||||
@@ -0,0 +1,23 @@
|
||||
{{- if .Values.route.enabled -}}
|
||||
{{- $fullName := include "wekan.fullname" . -}}
|
||||
apiVersion: route.openshift.io/v1
|
||||
kind: Route
|
||||
metadata:
|
||||
annotations:
|
||||
haproxy.router.openshift.io/timeout: 4m
|
||||
openshift.io/host.generated: "true"
|
||||
labels:
|
||||
app: {{ template "wekan.name" . }}
|
||||
service: {{ template "wekan.name" . }}
|
||||
name: {{ template "wekan.name" . }}
|
||||
spec:
|
||||
port:
|
||||
targetPort: http
|
||||
tls:
|
||||
termination: edge
|
||||
to:
|
||||
kind: Service
|
||||
name: {{ template "wekan.name" . }}
|
||||
weight: 100
|
||||
wildcardPolicy: None
|
||||
{{- end }}
|
||||
@@ -59,6 +59,9 @@ ingress:
|
||||
# hosts:
|
||||
# - wekan-example.local
|
||||
|
||||
route:
|
||||
enabled: false
|
||||
|
||||
resources:
|
||||
requests:
|
||||
memory: 128Mi
|
||||
|
||||
+779
-768
File diff suppressed because it is too large.
Load diff
+779
-768
File diff suppressed because it is too large.
Load diff
+779
-768
File diff suppressed because it is too large.
Load diff
+779
-768
File diff suppressed because it is too large.
Load diff
+779
-768
File diff suppressed because it is too large.
Load diff
+779
-768
File diff suppressed because it is too large.
Load diff
+13
-2
@@ -152,6 +152,8 @@
|
||||
"card-spent": "Aufgewendete Zeit",
|
||||
"card-edit-attachments": "Anhänge ändern",
|
||||
"card-edit-custom-fields": "Benutzerdefinierte Felder editieren",
|
||||
"card-start-voting": "Abstimmung starten",
|
||||
"card-cancel-voting": "Abstimmung mit allen Stimmen löschen ",
|
||||
"card-edit-labels": "Labels ändern",
|
||||
"card-edit-members": "Mitglieder ändern",
|
||||
"card-labels-title": "Labels für diese Karte ändern.",
|
||||
@@ -161,6 +163,13 @@
|
||||
"cardAttachmentsPopup-title": "Anhängen von",
|
||||
"cardCustomField-datePopup-title": "Datum ändern",
|
||||
"cardCustomFieldsPopup-title": "Benutzerdefinierte Felder editieren",
|
||||
"cardStartVotingPopup-title": "Abstimmung starten",
|
||||
"positiveVoteMembersPopup-title": "Befürworter",
|
||||
"negativeVoteMembersPopup-title": "Gegner",
|
||||
"vote-question": "Abstimmen über",
|
||||
"vote-public": "Öffentliche Abstimmung",
|
||||
"vote-for-it": "Dafür",
|
||||
"vote-against": "Dagegen",
|
||||
"cardDeletePopup-title": "Karte löschen?",
|
||||
"cardDetailsActionsPopup-title": "Kartenaktionen",
|
||||
"cardLabelsPopup-title": "Labels",
|
||||
@@ -319,6 +328,7 @@
|
||||
"filter-clear": "Filter entfernen",
|
||||
"filter-no-label": "Kein Label",
|
||||
"filter-no-member": "Kein Mitglied",
|
||||
"filter-no-assignee": "No assignee",
|
||||
"filter-no-custom-fields": "Keine benutzerdefinierten Felder",
|
||||
"filter-show-archive": "Archivierte Listen anzeigen",
|
||||
"filter-hide-empty": "Leere Listen verstecken",
|
||||
@@ -762,8 +772,9 @@
|
||||
"newUserPopup-title": "Neuer Benutzer",
|
||||
"notifications": "Benachrichtigungen",
|
||||
"view-all": "Alle anzeigen",
|
||||
"filter-by-unread": "Nach Ungelesenen filtern",
|
||||
"mark-all-as-read": "Als ungelesen markieren",
|
||||
"filter-by-unread": "Nur ungelesene",
|
||||
"mark-all-as-read": "Alle als gelesen markieren",
|
||||
"remove-all-read": "Alle gelesenen entfernen",
|
||||
"allow-rename": "Umbenennen erlauben",
|
||||
"allowRenamePopup-title": "Umbenennen erlauben"
|
||||
}
|
||||
+779
-768
File diff suppressed because it is too large.
Load diff
+779
-768
File diff suppressed because it is too large.
Load diff
@@ -152,6 +152,8 @@
|
||||
"card-spent": "Spent Time",
|
||||
"card-edit-attachments": "Edit attachments",
|
||||
"card-edit-custom-fields": "Edit custom fields",
|
||||
"card-start-voting": "Start voting",
|
||||
"card-cancel-voting": "Delete voting and all votes",
|
||||
"card-edit-labels": "Edit labels",
|
||||
"card-edit-members": "Edit members",
|
||||
"card-labels-title": "Change the labels for the card.",
|
||||
@@ -161,6 +163,13 @@
|
||||
"cardAttachmentsPopup-title": "Attach From",
|
||||
"cardCustomField-datePopup-title": "Change date",
|
||||
"cardCustomFieldsPopup-title": "Edit custom fields",
|
||||
"cardStartVotingPopup-title": "Start a vote",
|
||||
"positiveVoteMembersPopup-title": "Proponents",
|
||||
"negativeVoteMembersPopup-title": "Opponents",
|
||||
"vote-question": "Voting question",
|
||||
"vote-public": "Public vote",
|
||||
"vote-for-it": "for it",
|
||||
"vote-against": "against",
|
||||
"cardDeletePopup-title": "Delete Card?",
|
||||
"cardDetailsActionsPopup-title": "Card Actions",
|
||||
"cardLabelsPopup-title": "Labels",
|
||||
@@ -319,6 +328,7 @@
|
||||
"filter-clear": "Clear filter",
|
||||
"filter-no-label": "No label",
|
||||
"filter-no-member": "No member",
|
||||
"filter-no-assignee": "No assignee",
|
||||
"filter-no-custom-fields": "No Custom Fields",
|
||||
"filter-show-archive": "Show archived lists",
|
||||
"filter-hide-empty": "Hide empty lists",
|
||||
@@ -767,6 +777,7 @@
|
||||
"view-all": "View All",
|
||||
"filter-by-unread": "Filter by Unread",
|
||||
"mark-all-as-read": "Mark all as read",
|
||||
"remove-all-read": "Remove all read",
|
||||
"allow-rename": "Allow Rename",
|
||||
"allowRenamePopup-title": "Allow Rename"
|
||||
}
|
||||
+779
-768
File diff suppressed because it is too large.
Load diff
+779
-768
File diff suppressed because it is too large.
Load diff
@@ -152,6 +152,8 @@
|
||||
"card-spent": "Tiempo consumido",
|
||||
"card-edit-attachments": "Editar los adjuntos",
|
||||
"card-edit-custom-fields": "Editar los campos personalizados",
|
||||
"card-start-voting": "Start voting",
|
||||
"card-cancel-voting": "Delete voting and all votes",
|
||||
"card-edit-labels": "Editar las etiquetas",
|
||||
"card-edit-members": "Editar los miembros",
|
||||
"card-labels-title": "Cambia las etiquetas de la tarjeta",
|
||||
@@ -161,6 +163,13 @@
|
||||
"cardAttachmentsPopup-title": "Adjuntar desde",
|
||||
"cardCustomField-datePopup-title": "Cambiar la fecha",
|
||||
"cardCustomFieldsPopup-title": "Editar los campos personalizados",
|
||||
"cardStartVotingPopup-title": "Start a vote",
|
||||
"positiveVoteMembersPopup-title": "Proponents",
|
||||
"negativeVoteMembersPopup-title": "Opponents",
|
||||
"vote-question": "Voting question",
|
||||
"vote-public": "Public vote",
|
||||
"vote-for-it": "for it",
|
||||
"vote-against": "against",
|
||||
"cardDeletePopup-title": "¿Eliminar la tarjeta?",
|
||||
"cardDetailsActionsPopup-title": "Acciones de la tarjeta",
|
||||
"cardLabelsPopup-title": "Etiquetas",
|
||||
@@ -319,6 +328,7 @@
|
||||
"filter-clear": "Limpiar el filtro",
|
||||
"filter-no-label": "Sin etiqueta",
|
||||
"filter-no-member": "Sin miembro",
|
||||
"filter-no-assignee": "No assignee",
|
||||
"filter-no-custom-fields": "Sin campos personalizados",
|
||||
"filter-show-archive": "Mostrar las listas archivadas",
|
||||
"filter-hide-empty": "Ocultar las listas vacías",
|
||||
@@ -764,6 +774,7 @@
|
||||
"view-all": "Ver todo",
|
||||
"filter-by-unread": "Filtrar por no leído",
|
||||
"mark-all-as-read": "Marcar todo como leido",
|
||||
"remove-all-read": "Remove all read",
|
||||
"allow-rename": "Permitir renombrar",
|
||||
"allowRenamePopup-title": "Permitir renombrar"
|
||||
}
|
||||
+779
-768
File diff suppressed because it is too large.
Load diff
+779
-768
File diff suppressed because it is too large.
Load diff
+779
-768
File diff suppressed because it is too large.
Load diff
+779
-768
File diff suppressed because it is too large.
Load diff
+779
-768
File diff suppressed because it is too large.
Load diff
+779
-768
File diff suppressed because it is too large.
Load diff
+779
-768
File diff suppressed because it is too large.
Load diff
+779
-768
File diff suppressed because it is too large.
Load diff
+779
-768
File diff suppressed because it is too large.
Load diff
+779
-768
File diff suppressed because it is too large.
Load diff
+779
-768
File diff suppressed because it is too large.
Load diff
@@ -152,6 +152,8 @@
|
||||
"card-spent": "Tempo trascorso",
|
||||
"card-edit-attachments": "Modifica allegati",
|
||||
"card-edit-custom-fields": "Modifica campo personalizzato",
|
||||
"card-start-voting": "Inizia a votare",
|
||||
"card-cancel-voting": "Cancella votazione e tutti i voti",
|
||||
"card-edit-labels": "Modifica etichette",
|
||||
"card-edit-members": "Modifica membri",
|
||||
"card-labels-title": "Cambia le etichette per questa scheda.",
|
||||
@@ -161,6 +163,13 @@
|
||||
"cardAttachmentsPopup-title": "Allega da",
|
||||
"cardCustomField-datePopup-title": "Cambia data",
|
||||
"cardCustomFieldsPopup-title": "Modifica campo personalizzato",
|
||||
"cardStartVotingPopup-title": "Inizia una votazione",
|
||||
"positiveVoteMembersPopup-title": "Proponents",
|
||||
"negativeVoteMembersPopup-title": "Opponents",
|
||||
"vote-question": "Domanda di votazione",
|
||||
"vote-public": "Public vote",
|
||||
"vote-for-it": "a favore",
|
||||
"vote-against": "contro",
|
||||
"cardDeletePopup-title": "Elimina scheda?",
|
||||
"cardDetailsActionsPopup-title": "Azioni scheda",
|
||||
"cardLabelsPopup-title": "Etichette",
|
||||
@@ -319,6 +328,7 @@
|
||||
"filter-clear": "Pulisci filtri",
|
||||
"filter-no-label": "Nessuna etichetta",
|
||||
"filter-no-member": "Nessun membro",
|
||||
"filter-no-assignee": "Nessun assegnatario",
|
||||
"filter-no-custom-fields": "Nessun campo personalizzato",
|
||||
"filter-show-archive": "Mostra le liste archiviate",
|
||||
"filter-hide-empty": "Nascondi liste vuote",
|
||||
@@ -764,6 +774,7 @@
|
||||
"view-all": "Mostra Tutto",
|
||||
"filter-by-unread": "Filtra per non letto",
|
||||
"mark-all-as-read": "Segna come letto",
|
||||
"remove-all-read": "Rimuovi tutti i già letti",
|
||||
"allow-rename": "Consenti Rinomina",
|
||||
"allowRenamePopup-title": "Consenti Rinomina"
|
||||
}
|
||||
+779
-768
File diff suppressed because it is too large.
Load diff
+779
-768
File diff suppressed because it is too large.
Load diff
+779
-768
File diff suppressed because it is too large.
Load diff
+779
-768
File diff suppressed because it is too large.
Load diff
+779
-768
File diff suppressed because it is too large.
Load diff
+779
-768
File diff suppressed because it is too large.
Load diff
+779
-768
File diff suppressed because it is too large.
Load diff
+779
-768
File diff suppressed because it is too large.
Load diff
@@ -152,6 +152,8 @@
|
||||
"card-spent": "Gespendeerde tijd",
|
||||
"card-edit-attachments": "Wijzig bijlagen",
|
||||
"card-edit-custom-fields": "Wijzig maatwerkvelden",
|
||||
"card-start-voting": "Start stemming",
|
||||
"card-cancel-voting": "Verwijder stemming en verwijder stemmen",
|
||||
"card-edit-labels": "Wijzig labels",
|
||||
"card-edit-members": "Wijzig leden",
|
||||
"card-labels-title": "Wijzig de labels van de kaart.",
|
||||
@@ -161,6 +163,13 @@
|
||||
"cardAttachmentsPopup-title": "Voeg bestand toe vanuit",
|
||||
"cardCustomField-datePopup-title": "Wijzigingsdatum",
|
||||
"cardCustomFieldsPopup-title": "Wijzig maatwerkvelden",
|
||||
"cardStartVotingPopup-title": "Start een stemming",
|
||||
"positiveVoteMembersPopup-title": "Proponents",
|
||||
"negativeVoteMembersPopup-title": "Opponents",
|
||||
"vote-question": "Stemvraag",
|
||||
"vote-public": "Public vote",
|
||||
"vote-for-it": "Voor",
|
||||
"vote-against": "tegen",
|
||||
"cardDeletePopup-title": "Kaart verwijderen?",
|
||||
"cardDetailsActionsPopup-title": "Kaart actie ondernemen",
|
||||
"cardLabelsPopup-title": "Labels",
|
||||
@@ -319,6 +328,7 @@
|
||||
"filter-clear": "Wis filter",
|
||||
"filter-no-label": "Geen label",
|
||||
"filter-no-member": "Geen lid",
|
||||
"filter-no-assignee": "Niemand toegewezen",
|
||||
"filter-no-custom-fields": "Geen maatwerkvelden",
|
||||
"filter-show-archive": "Toon gearchiveerde lijsten",
|
||||
"filter-hide-empty": "Verberg lege lijsten",
|
||||
@@ -764,6 +774,7 @@
|
||||
"view-all": "Bekijk alles",
|
||||
"filter-by-unread": "Filter op Ongelezen",
|
||||
"mark-all-as-read": "Markeer alles als gelezen",
|
||||
"remove-all-read": "verwijder alle gelezen",
|
||||
"allow-rename": "Sta Hernoemen toe",
|
||||
"allowRenamePopup-title": "Sta Hernoemen toe"
|
||||
}
|
||||
+779
-768
File diff suppressed because it is too large.
Load diff
+779
-768
File diff suppressed because it is too large.
Load diff
+779
-768
File diff suppressed because it is too large.
Load diff
+779
-768
File diff suppressed because it is too large.
Load diff
+779
-768
File diff suppressed because it is too large.
Load diff
+779
-768
File diff suppressed because it is too large.
Load diff
+779
-768
File diff suppressed because it is too large.
Load diff
+779
-768
File diff suppressed because it is too large.
Load diff
+779
-768
File diff suppressed because it is too large.
Load diff
+779
-768
File diff suppressed because it is too large.
Load diff
+779
-768
File diff suppressed because it is too large.
Load diff
+779
-768
File diff suppressed because it is too large.
Load diff
+779
-768
File diff suppressed because it is too large.
Load diff
+779
-768
File diff suppressed because it is too large.
Load diff
+779
-768
File diff suppressed because it is too large.
Load diff
+779
-768
File diff suppressed because it is too large.
Load diff
+779
-768
File diff suppressed because it is too large.
Load diff
+779
-768
File diff suppressed because it is too large.
Load diff
@@ -282,7 +282,10 @@ if (Meteor.isServer) {
|
||||
);
|
||||
}
|
||||
Notifications.getUsers(watchers).forEach(user => {
|
||||
Notifications.notify(user, title, description, params);
|
||||
// don't notify a user of their own behavior
|
||||
if (user._id !== userId) {
|
||||
Notifications.notify(user, title, description, params);
|
||||
}
|
||||
});
|
||||
|
||||
const integrations = Integrations.find({
|
||||
|
||||
+142
-11
@@ -304,6 +304,42 @@ Cards.attachSchema(
|
||||
optional: true,
|
||||
defaultValue: '',
|
||||
},
|
||||
vote: {
|
||||
/**
|
||||
* vote object, see below
|
||||
*/
|
||||
type: Object,
|
||||
optional: true,
|
||||
},
|
||||
'vote.question': {
|
||||
type: String,
|
||||
defaultValue: '',
|
||||
},
|
||||
'vote.positive': {
|
||||
/**
|
||||
* list of members (user IDs)
|
||||
*/
|
||||
type: [String],
|
||||
optional: true,
|
||||
defaultValue: [],
|
||||
},
|
||||
'vote.negative': {
|
||||
/**
|
||||
* list of members (user IDs)
|
||||
*/
|
||||
type: [String],
|
||||
optional: true,
|
||||
defaultValue: [],
|
||||
},
|
||||
'vote.end': {
|
||||
type: Date,
|
||||
optional: true,
|
||||
defaultValue: null,
|
||||
},
|
||||
'vote.public': {
|
||||
type: Boolean,
|
||||
defaultValue: false,
|
||||
},
|
||||
}),
|
||||
);
|
||||
|
||||
@@ -696,7 +732,7 @@ Cards.helpers({
|
||||
|
||||
parentString(sep) {
|
||||
return this.parentList()
|
||||
.map(function(elem) {
|
||||
.map(function (elem) {
|
||||
return elem.title;
|
||||
})
|
||||
.join(sep);
|
||||
@@ -980,6 +1016,49 @@ Cards.helpers({
|
||||
}
|
||||
},
|
||||
|
||||
getVoteQuestion() {
|
||||
if (this.isLinkedCard()) {
|
||||
const card = Cards.findOne({ _id: this.linkedId });
|
||||
if (card && card.vote) return card.vote.question;
|
||||
else return null;
|
||||
} else if (this.isLinkedBoard()) {
|
||||
const board = Boards.findOne({ _id: this.linkedId });
|
||||
if (board && board.vote) return board.vote.question;
|
||||
else return null;
|
||||
} else if (this.vote) {
|
||||
return this.vote.question;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
},
|
||||
|
||||
getVotePublic() {
|
||||
if (this.isLinkedCard()) {
|
||||
const card = Cards.findOne({ _id: this.linkedId });
|
||||
if (card && card.vote) return card.vote.public;
|
||||
else return null;
|
||||
} else if (this.isLinkedBoard()) {
|
||||
const board = Boards.findOne({ _id: this.linkedId });
|
||||
if (board && board.vote) return board.vote.public;
|
||||
else return null;
|
||||
} else if (this.vote) {
|
||||
return this.vote.public;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
},
|
||||
|
||||
voteMemberPositive() {
|
||||
if (this.vote && this.vote.positive)
|
||||
return Users.find({ _id: { $in: this.vote.positive } })
|
||||
return []
|
||||
},
|
||||
voteMemberNegative() {
|
||||
if (this.vote && this.vote.negative)
|
||||
return Users.find({ _id: { $in: this.vote.negative } })
|
||||
return []
|
||||
},
|
||||
|
||||
getId() {
|
||||
if (this.isLinked()) {
|
||||
return this.linkedId;
|
||||
@@ -1396,6 +1475,58 @@ Cards.mutations({
|
||||
},
|
||||
};
|
||||
},
|
||||
setVoteQuestion(question, public) {
|
||||
return {
|
||||
$set: {
|
||||
vote: {
|
||||
question,
|
||||
public,
|
||||
positive: [],
|
||||
negative: [],
|
||||
},
|
||||
},
|
||||
};
|
||||
},
|
||||
unsetVote() {
|
||||
return {
|
||||
$unset: {
|
||||
vote: '',
|
||||
},
|
||||
};
|
||||
},
|
||||
setVote(userId, forIt) {
|
||||
switch (forIt) {
|
||||
case true:
|
||||
// vote for it
|
||||
return {
|
||||
$pull: {
|
||||
'vote.negative': userId,
|
||||
},
|
||||
$addToSet: {
|
||||
'vote.positive': userId,
|
||||
},
|
||||
};
|
||||
case false:
|
||||
// vote against
|
||||
return {
|
||||
$pull: {
|
||||
'vote.positive': userId,
|
||||
},
|
||||
$addToSet: {
|
||||
'vote.negative': userId,
|
||||
},
|
||||
};
|
||||
|
||||
default:
|
||||
// Remove votes
|
||||
return {
|
||||
$pull: {
|
||||
'vote.positive': userId,
|
||||
'vote.negative': userId,
|
||||
},
|
||||
};
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
//FUNCTIONS FOR creation of Activities
|
||||
@@ -1798,7 +1929,7 @@ if (Meteor.isServer) {
|
||||
});
|
||||
|
||||
//New activity for card moves
|
||||
Cards.after.update(function(userId, doc, fieldNames) {
|
||||
Cards.after.update(function (userId, doc, fieldNames) {
|
||||
const oldListId = this.previous.listId;
|
||||
const oldSwimlaneId = this.previous.swimlaneId;
|
||||
const oldBoardId = this.previous.boardId;
|
||||
@@ -1844,7 +1975,7 @@ if (Meteor.isServer) {
|
||||
// change list modifiedAt, when user modified the key values in timingaction array, if it's endAt, put the modifiedAt of list back to one year ago for sorting purpose
|
||||
const modifiedAt = new Date(
|
||||
new Date(value).getTime() -
|
||||
(action === 'endAt' ? 365 * 24 * 3600 * 1e3 : 0),
|
||||
(action === 'endAt' ? 365 * 24 * 3600 * 1e3 : 0),
|
||||
); // set it as 1 year before
|
||||
const boardId = list.boardId;
|
||||
Lists.direct.update(
|
||||
@@ -1898,7 +2029,7 @@ if (Meteor.isServer) {
|
||||
JsonRoutes.add(
|
||||
'GET',
|
||||
'/api/boards/:boardId/swimlanes/:swimlaneId/cards',
|
||||
function(req, res) {
|
||||
function (req, res) {
|
||||
const paramBoardId = req.params.boardId;
|
||||
const paramSwimlaneId = req.params.swimlaneId;
|
||||
Authentication.checkBoardAccess(req.userId, paramBoardId);
|
||||
@@ -1908,7 +2039,7 @@ if (Meteor.isServer) {
|
||||
boardId: paramBoardId,
|
||||
swimlaneId: paramSwimlaneId,
|
||||
archived: false,
|
||||
}).map(function(doc) {
|
||||
}).map(function (doc) {
|
||||
return {
|
||||
_id: doc._id,
|
||||
title: doc.title,
|
||||
@@ -1932,7 +2063,7 @@ if (Meteor.isServer) {
|
||||
* title: string,
|
||||
* description: string}]
|
||||
*/
|
||||
JsonRoutes.add('GET', '/api/boards/:boardId/lists/:listId/cards', function(
|
||||
JsonRoutes.add('GET', '/api/boards/:boardId/lists/:listId/cards', function (
|
||||
req,
|
||||
res,
|
||||
) {
|
||||
@@ -1945,7 +2076,7 @@ if (Meteor.isServer) {
|
||||
boardId: paramBoardId,
|
||||
listId: paramListId,
|
||||
archived: false,
|
||||
}).map(function(doc) {
|
||||
}).map(function (doc) {
|
||||
return {
|
||||
_id: doc._id,
|
||||
title: doc.title,
|
||||
@@ -1967,7 +2098,7 @@ if (Meteor.isServer) {
|
||||
JsonRoutes.add(
|
||||
'GET',
|
||||
'/api/boards/:boardId/lists/:listId/cards/:cardId',
|
||||
function(req, res) {
|
||||
function (req, res) {
|
||||
const paramBoardId = req.params.boardId;
|
||||
const paramListId = req.params.listId;
|
||||
const paramCardId = req.params.cardId;
|
||||
@@ -1999,7 +2130,7 @@ if (Meteor.isServer) {
|
||||
* @param {string} [assignees] the array of maximum one ID of assignee of the new card
|
||||
* @return_type {_id: string}
|
||||
*/
|
||||
JsonRoutes.add('POST', '/api/boards/:boardId/lists/:listId/cards', function(
|
||||
JsonRoutes.add('POST', '/api/boards/:boardId/lists/:listId/cards', function (
|
||||
req,
|
||||
res,
|
||||
) {
|
||||
@@ -2106,7 +2237,7 @@ if (Meteor.isServer) {
|
||||
JsonRoutes.add(
|
||||
'PUT',
|
||||
'/api/boards/:boardId/lists/:listId/cards/:cardId',
|
||||
function(req, res) {
|
||||
function (req, res) {
|
||||
Authentication.checkUserId(req.userId);
|
||||
const paramBoardId = req.params.boardId;
|
||||
const paramCardId = req.params.cardId;
|
||||
@@ -2405,7 +2536,7 @@ if (Meteor.isServer) {
|
||||
JsonRoutes.add(
|
||||
'DELETE',
|
||||
'/api/boards/:boardId/lists/:listId/cards/:cardId',
|
||||
function(req, res) {
|
||||
function (req, res) {
|
||||
Authentication.checkUserId(req.userId);
|
||||
const paramBoardId = req.params.boardId;
|
||||
const paramListId = req.params.listId;
|
||||
|
||||
@@ -198,6 +198,10 @@ if (Meteor.isServer) {
|
||||
return process.env.CAS_ENABLED === 'true';
|
||||
}
|
||||
|
||||
function isApiEnabled() {
|
||||
return process.env.WITH_API === 'true';
|
||||
}
|
||||
|
||||
Meteor.methods({
|
||||
sendInvitation(emails, boards) {
|
||||
check(emails, [String]);
|
||||
@@ -314,6 +318,10 @@ if (Meteor.isServer) {
|
||||
return isCasEnabled();
|
||||
},
|
||||
|
||||
_isApiEnabled() {
|
||||
return isApiEnabled();
|
||||
},
|
||||
|
||||
// Gets all connection methods to use it in the Template
|
||||
getAuthenticationsEnabled() {
|
||||
return {
|
||||
|
||||
+26
-2
@@ -1,4 +1,4 @@
|
||||
const DateString = Match.Where(function(dateAsString) {
|
||||
const DateString = Match.Where(function (dateAsString) {
|
||||
check(dateAsString, String);
|
||||
return moment(dateAsString, moment.ISO_8601).isValid();
|
||||
});
|
||||
@@ -285,6 +285,30 @@ export class TrelloCreator {
|
||||
cardToCreate.members = wekanMembers;
|
||||
}
|
||||
}
|
||||
// add vote
|
||||
if (card.idMembersVoted) {
|
||||
// Trello only know's positive votes
|
||||
const positiveVotes = [];
|
||||
card.idMembersVoted.forEach(trelloId => {
|
||||
if (this.members[trelloId]) {
|
||||
const wekanId = this.members[trelloId];
|
||||
// we may map multiple Trello members to the same wekan user
|
||||
// in which case we risk adding the same user multiple times
|
||||
if (!positiveVotes.find(wId => wId === wekanId)) {
|
||||
positiveVotes.push(wekanId);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
})
|
||||
if (positiveVotes.length > 0) {
|
||||
cardToCreate.vote = {
|
||||
question: cardToCreate.title,
|
||||
public: true,
|
||||
positive: positiveVotes,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// insert card
|
||||
const cardId = Cards.direct.insert(cardToCreate);
|
||||
// keep track of Trello id => Wekan id
|
||||
@@ -345,7 +369,7 @@ export class TrelloCreator {
|
||||
// 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.attachData(att.url, function (error) {
|
||||
file.boardId = boardId;
|
||||
file.cardId = cardId;
|
||||
file.userId = self._user(att.idMemberCreator);
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import { SyncedCron } from 'meteor/percolate:synced-cron';
|
||||
|
||||
// Sandstorm context is detected using the METEOR_SETTINGS environment variable
|
||||
// in the package definition.
|
||||
const isSandstorm =
|
||||
@@ -812,6 +814,16 @@ if (Meteor.isServer) {
|
||||
board.addMember(user._id);
|
||||
user.addInvite(boardId);
|
||||
|
||||
//Check if there is a subtasks board
|
||||
if (board.subtasksDefaultBoardId) {
|
||||
const subBoard = Boards.findOne(board.subtasksDefaultBoardId);
|
||||
//If there is, also add user to that board
|
||||
if (subBoard) {
|
||||
subBoard.addMember(user._id);
|
||||
user.addInvite(subBoard._id);
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
const params = {
|
||||
user: user.username,
|
||||
@@ -926,6 +938,39 @@ if (Meteor.isServer) {
|
||||
});
|
||||
}
|
||||
|
||||
const addCronJob = _.debounce(
|
||||
Meteor.bindEnvironment(function notificationCleanupDebounced() {
|
||||
// passed in the removeAge has to be a number standing for the number of days after a notification is read before we remove it
|
||||
const envRemoveAge =
|
||||
process.env.NOTIFICATION_TRAY_AFTER_READ_DAYS_BEFORE_REMOVE;
|
||||
// default notifications will be removed 2 days after they are read
|
||||
const defaultRemoveAge = 2;
|
||||
const removeAge = parseInt(envRemoveAge, 10) || defaultRemoveAge;
|
||||
|
||||
SyncedCron.add({
|
||||
name: 'notification_cleanup',
|
||||
schedule: parser => parser.text('every 1 days'),
|
||||
job: () => {
|
||||
for (const user of Users.find()) {
|
||||
if (!user.profile || !user.profile.notifications) continue;
|
||||
for (const notification of user.profile.notifications) {
|
||||
if (notification.read) {
|
||||
const removeDate = new Date(notification.read);
|
||||
removeDate.setDate(removeDate.getDate() + removeAge);
|
||||
if (removeDate <= new Date()) {
|
||||
user.removeNotification(notification.activity);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
SyncedCron.start();
|
||||
}),
|
||||
500,
|
||||
);
|
||||
|
||||
if (Meteor.isServer) {
|
||||
// Let mongoDB ensure username unicity
|
||||
Meteor.startup(() => {
|
||||
@@ -939,6 +984,9 @@ if (Meteor.isServer) {
|
||||
},
|
||||
{ unique: true },
|
||||
);
|
||||
Meteor.defer(() => {
|
||||
addCronJob();
|
||||
});
|
||||
});
|
||||
|
||||
// OLD WAY THIS CODE DID WORK: When user is last admin of board,
|
||||
|
||||
Generated
+12
-12
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "wekan",
|
||||
"version": "v3.90.0",
|
||||
"version": "v3.95.0",
|
||||
"lockfileVersion": 1,
|
||||
"requires": true,
|
||||
"dependencies": {
|
||||
@@ -25,11 +25,11 @@
|
||||
}
|
||||
},
|
||||
"@babel/runtime": {
|
||||
"version": "7.8.4",
|
||||
"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.8.4.tgz",
|
||||
"integrity": "sha512-neAp3zt80trRVBI1x0azq6c57aNBqYZH8KhMm3TaB7wEI5Q4A2SHfBHE8w9gOhI/lrqxtEbXZgQIrHP+wvSGwQ==",
|
||||
"version": "7.9.2",
|
||||
"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.9.2.tgz",
|
||||
"integrity": "sha512-NE2DtOdufG7R5vnfQUTehdTfNycfUANEtCa9PssN9O/xmTzP4E08UI797ixaei6hBEVL9BI/PsdJS5x7mWoB9Q==",
|
||||
"requires": {
|
||||
"regenerator-runtime": "^0.13.2"
|
||||
"regenerator-runtime": "^0.13.4"
|
||||
}
|
||||
},
|
||||
"@samverschueren/stream-to-observable": {
|
||||
@@ -3149,11 +3149,11 @@
|
||||
}
|
||||
},
|
||||
"mkdirp": {
|
||||
"version": "0.5.1",
|
||||
"resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz",
|
||||
"integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=",
|
||||
"version": "0.5.5",
|
||||
"resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz",
|
||||
"integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==",
|
||||
"requires": {
|
||||
"minimist": "1.2.5"
|
||||
"minimist": "^1.2.5"
|
||||
}
|
||||
},
|
||||
"moment": {
|
||||
@@ -3882,9 +3882,9 @@
|
||||
}
|
||||
},
|
||||
"regenerator-runtime": {
|
||||
"version": "0.13.3",
|
||||
"resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.3.tgz",
|
||||
"integrity": "sha512-naKIZz2GQ8JWh///G7L3X6LaQUAMp2lvb1rvwwsURe/VXwD6VMfr+/1NuNw3ag8v2kY1aQ/go5SNn79O9JU7yw=="
|
||||
"version": "0.13.5",
|
||||
"resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.5.tgz",
|
||||
"integrity": "sha512-ZS5w8CpKFinUzOwW3c83oPeVXoNsrLsaCoLtJvAClH135j/R77RuymhiSErhm2lKcwSCIpmvIWSbDkIfAqKQlA=="
|
||||
},
|
||||
"regex-not": {
|
||||
"version": "1.0.2",
|
||||
|
||||
+2
-2
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "wekan",
|
||||
"version": "v3.90.0",
|
||||
"version": "v3.95.0",
|
||||
"description": "Open-Source kanban",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
@@ -53,7 +53,7 @@
|
||||
"prettier-eslint": "^9.0.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"@babel/runtime": "^7.8.4",
|
||||
"@babel/runtime": "^7.9.2",
|
||||
"ajv": "^5.0.0",
|
||||
"babel-runtime": "^6.26.0",
|
||||
"bcrypt": "^3.0.7",
|
||||
|
||||
+2
-1819
File diff suppressed because it is too large.
Load diff
+1
-500
@@ -1,7 +1,7 @@
|
||||
swagger: '2.0'
|
||||
info:
|
||||
title: Wekan REST API
|
||||
version: v3.90
|
||||
version: v3.94
|
||||
description: |
|
||||
The REST API allows you to control and extend Wekan with ease.
|
||||
|
||||
@@ -1221,296 +1221,6 @@ paths:
|
||||
properties:
|
||||
_id:
|
||||
type: string
|
||||
/api/boards/{board}/lists/{list}/cards:
|
||||
get:
|
||||
operationId: get_all_cards
|
||||
summary: Get all Cards attached to a List
|
||||
tags:
|
||||
- Cards
|
||||
parameters:
|
||||
- name: board
|
||||
in: path
|
||||
description: |
|
||||
the board ID
|
||||
type: string
|
||||
required: true
|
||||
- name: list
|
||||
in: path
|
||||
description: |
|
||||
the list ID
|
||||
type: string
|
||||
required: true
|
||||
produces:
|
||||
- application/json
|
||||
security:
|
||||
- UserSecurity: []
|
||||
responses:
|
||||
'200':
|
||||
description: |-
|
||||
200 response
|
||||
schema:
|
||||
type: array
|
||||
items:
|
||||
type: object
|
||||
properties:
|
||||
_id:
|
||||
type: string
|
||||
title:
|
||||
type: string
|
||||
description:
|
||||
type: string
|
||||
post:
|
||||
operationId: new_card
|
||||
summary: Create a new Card
|
||||
tags:
|
||||
- Cards
|
||||
consumes:
|
||||
- multipart/form-data
|
||||
- application/json
|
||||
parameters:
|
||||
- name: authorId
|
||||
in: formData
|
||||
description: the authorId value
|
||||
type: string
|
||||
required: true
|
||||
- name: members
|
||||
in: formData
|
||||
description: |
|
||||
the member IDs list of the new card
|
||||
type: string
|
||||
required: false
|
||||
- name: assignees
|
||||
in: formData
|
||||
description: |
|
||||
the array of maximum one ID of assignee of the new card
|
||||
type: string
|
||||
required: false
|
||||
- name: title
|
||||
in: formData
|
||||
description: |
|
||||
the title of the new card
|
||||
type: string
|
||||
required: true
|
||||
- name: description
|
||||
in: formData
|
||||
description: |
|
||||
the description of the new card
|
||||
type: string
|
||||
required: true
|
||||
- name: swimlaneId
|
||||
in: formData
|
||||
description: |
|
||||
the swimlane ID of the new card
|
||||
type: string
|
||||
required: true
|
||||
- name: board
|
||||
in: path
|
||||
description: |
|
||||
the board ID of the new card
|
||||
type: string
|
||||
required: true
|
||||
- name: list
|
||||
in: path
|
||||
description: |
|
||||
the list ID of the new card
|
||||
type: string
|
||||
required: true
|
||||
produces:
|
||||
- application/json
|
||||
security:
|
||||
- UserSecurity: []
|
||||
responses:
|
||||
'200':
|
||||
description: |-
|
||||
200 response
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
_id:
|
||||
type: string
|
||||
/api/boards/{board}/lists/{list}/cards/{card}:
|
||||
get:
|
||||
operationId: get_board_list_card
|
||||
tags:
|
||||
- Cards
|
||||
parameters:
|
||||
- name: board
|
||||
in: path
|
||||
description: the board value
|
||||
type: string
|
||||
required: true
|
||||
- name: list
|
||||
in: path
|
||||
description: the list value
|
||||
type: string
|
||||
required: true
|
||||
- name: card
|
||||
in: path
|
||||
description: the card value
|
||||
type: string
|
||||
required: true
|
||||
produces:
|
||||
- application/json
|
||||
security:
|
||||
- UserSecurity: []
|
||||
responses:
|
||||
'200':
|
||||
description: |-
|
||||
200 response
|
||||
put:
|
||||
operationId: put_board_list_card
|
||||
tags:
|
||||
- Cards
|
||||
consumes:
|
||||
- multipart/form-data
|
||||
- application/json
|
||||
parameters:
|
||||
- name: title
|
||||
in: formData
|
||||
description: the title value
|
||||
type: string
|
||||
required: true
|
||||
- name: listId
|
||||
in: formData
|
||||
description: the listId value
|
||||
type: string
|
||||
required: true
|
||||
- name: authorId
|
||||
in: formData
|
||||
description: the authorId value
|
||||
type: string
|
||||
required: true
|
||||
- name: parentId
|
||||
in: formData
|
||||
description: the parentId value
|
||||
type: string
|
||||
required: true
|
||||
- name: description
|
||||
in: formData
|
||||
description: the description value
|
||||
type: string
|
||||
required: true
|
||||
- name: color
|
||||
in: formData
|
||||
description: the color value
|
||||
type: string
|
||||
required: true
|
||||
- name: labelIds
|
||||
in: formData
|
||||
description: the labelIds value
|
||||
type: string
|
||||
required: true
|
||||
- name: requestedBy
|
||||
in: formData
|
||||
description: the requestedBy value
|
||||
type: string
|
||||
required: true
|
||||
- name: assignedBy
|
||||
in: formData
|
||||
description: the assignedBy value
|
||||
type: string
|
||||
required: true
|
||||
- name: receivedAt
|
||||
in: formData
|
||||
description: the receivedAt value
|
||||
type: string
|
||||
required: true
|
||||
- name: startAt
|
||||
in: formData
|
||||
description: the startAt value
|
||||
type: string
|
||||
required: true
|
||||
- name: dueAt
|
||||
in: formData
|
||||
description: the dueAt value
|
||||
type: string
|
||||
required: true
|
||||
- name: endAt
|
||||
in: formData
|
||||
description: the endAt value
|
||||
type: string
|
||||
required: true
|
||||
- name: spentTime
|
||||
in: formData
|
||||
description: the spentTime value
|
||||
type: string
|
||||
required: true
|
||||
- name: isOverTime
|
||||
in: formData
|
||||
description: the isOverTime value
|
||||
type: string
|
||||
required: true
|
||||
- name: customFields
|
||||
in: formData
|
||||
description: the customFields value
|
||||
type: string
|
||||
required: true
|
||||
- name: members
|
||||
in: formData
|
||||
description: the members value
|
||||
type: string
|
||||
required: true
|
||||
- name: assignees
|
||||
in: formData
|
||||
description: the assignees value
|
||||
type: string
|
||||
required: true
|
||||
- name: swimlaneId
|
||||
in: formData
|
||||
description: the swimlaneId value
|
||||
type: string
|
||||
required: true
|
||||
- name: board
|
||||
in: path
|
||||
description: the board value
|
||||
type: string
|
||||
required: true
|
||||
- name: list
|
||||
in: path
|
||||
description: the list value
|
||||
type: string
|
||||
required: true
|
||||
- name: card
|
||||
in: path
|
||||
description: the card value
|
||||
type: string
|
||||
required: true
|
||||
produces:
|
||||
- application/json
|
||||
security:
|
||||
- UserSecurity: []
|
||||
responses:
|
||||
'200':
|
||||
description: |-
|
||||
200 response
|
||||
delete:
|
||||
operationId: delete_board_list_card
|
||||
tags:
|
||||
- Cards
|
||||
parameters:
|
||||
- name: board
|
||||
in: path
|
||||
description: the board value
|
||||
type: string
|
||||
required: true
|
||||
- name: list
|
||||
in: path
|
||||
description: the list value
|
||||
type: string
|
||||
required: true
|
||||
- name: card
|
||||
in: path
|
||||
description: the card value
|
||||
type: string
|
||||
required: true
|
||||
produces:
|
||||
- application/json
|
||||
security:
|
||||
- UserSecurity: []
|
||||
responses:
|
||||
'200':
|
||||
description: |-
|
||||
200 response
|
||||
/api/boards/{board}/members/{member}:
|
||||
post:
|
||||
operationId: set_board_member_permission
|
||||
@@ -1780,30 +1490,6 @@ paths:
|
||||
'200':
|
||||
description: |-
|
||||
200 response
|
||||
/api/boards/{board}/swimlanes/{swimlane}/cards:
|
||||
get:
|
||||
operationId: get_board_swimlane_cards
|
||||
tags:
|
||||
- Cards
|
||||
parameters:
|
||||
- name: board
|
||||
in: path
|
||||
description: the board value
|
||||
type: string
|
||||
required: true
|
||||
- name: swimlane
|
||||
in: path
|
||||
description: the swimlane value
|
||||
type: string
|
||||
required: true
|
||||
produces:
|
||||
- application/json
|
||||
security:
|
||||
- UserSecurity: []
|
||||
responses:
|
||||
'200':
|
||||
description: |-
|
||||
200 response
|
||||
/api/user:
|
||||
get:
|
||||
operationId: get_current_user
|
||||
@@ -2349,191 +2035,6 @@ definitions:
|
||||
- createdAt
|
||||
- modifiedAt
|
||||
- userId
|
||||
Cards:
|
||||
type: object
|
||||
properties:
|
||||
title:
|
||||
description: |
|
||||
the title of the card
|
||||
type: string
|
||||
x-nullable: true
|
||||
archived:
|
||||
description: |
|
||||
is the card archived
|
||||
type: boolean
|
||||
parentId:
|
||||
description: |
|
||||
ID of the parent card
|
||||
type: string
|
||||
x-nullable: true
|
||||
listId:
|
||||
description: |
|
||||
List ID where the card is
|
||||
type: string
|
||||
x-nullable: true
|
||||
swimlaneId:
|
||||
description: |
|
||||
Swimlane ID where the card is
|
||||
type: string
|
||||
boardId:
|
||||
description: |
|
||||
Board ID of the card
|
||||
type: string
|
||||
x-nullable: true
|
||||
coverId:
|
||||
description: |
|
||||
Cover ID of the card
|
||||
type: string
|
||||
x-nullable: true
|
||||
color:
|
||||
type: string
|
||||
enum:
|
||||
- white
|
||||
- green
|
||||
- yellow
|
||||
- orange
|
||||
- red
|
||||
- purple
|
||||
- blue
|
||||
- sky
|
||||
- lime
|
||||
- pink
|
||||
- black
|
||||
- silver
|
||||
- peachpuff
|
||||
- crimson
|
||||
- plum
|
||||
- darkgreen
|
||||
- slateblue
|
||||
- magenta
|
||||
- gold
|
||||
- navy
|
||||
- gray
|
||||
- saddlebrown
|
||||
- paleturquoise
|
||||
- mistyrose
|
||||
- indigo
|
||||
x-nullable: true
|
||||
createdAt:
|
||||
description: |
|
||||
creation date
|
||||
type: string
|
||||
modifiedAt:
|
||||
type: string
|
||||
customFields:
|
||||
description: |
|
||||
list of custom fields
|
||||
type: array
|
||||
items:
|
||||
$ref: "#/definitions/CardsCustomfields"
|
||||
x-nullable: true
|
||||
dateLastActivity:
|
||||
description: |
|
||||
Date of last activity
|
||||
type: string
|
||||
description:
|
||||
description: |
|
||||
description of the card
|
||||
type: string
|
||||
x-nullable: true
|
||||
requestedBy:
|
||||
description: |
|
||||
who requested the card (ID of the user)
|
||||
type: string
|
||||
x-nullable: true
|
||||
assignedBy:
|
||||
description: |
|
||||
who assigned the card (ID of the user)
|
||||
type: string
|
||||
x-nullable: true
|
||||
labelIds:
|
||||
description: |
|
||||
list of labels ID the card has
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
x-nullable: true
|
||||
x-nullable: true
|
||||
members:
|
||||
description: |
|
||||
list of members (user IDs)
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
x-nullable: true
|
||||
x-nullable: true
|
||||
assignees:
|
||||
description: |
|
||||
who is assignee of the card (user ID),
|
||||
maximum one ID of assignee in array.
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
x-nullable: true
|
||||
x-nullable: true
|
||||
receivedAt:
|
||||
description: |
|
||||
Date the card was received
|
||||
type: string
|
||||
x-nullable: true
|
||||
startAt:
|
||||
description: |
|
||||
Date the card was started to be worked on
|
||||
type: string
|
||||
x-nullable: true
|
||||
dueAt:
|
||||
description: |
|
||||
Date the card is due
|
||||
type: string
|
||||
x-nullable: true
|
||||
endAt:
|
||||
description: |
|
||||
Date the card ended
|
||||
type: string
|
||||
x-nullable: true
|
||||
spentTime:
|
||||
description: |
|
||||
How much time has been spent on this
|
||||
type: number
|
||||
x-nullable: true
|
||||
isOvertime:
|
||||
description: |
|
||||
is the card over time?
|
||||
type: boolean
|
||||
x-nullable: true
|
||||
userId:
|
||||
description: |
|
||||
user ID of the author of the card
|
||||
type: string
|
||||
sort:
|
||||
description: |
|
||||
Sort value
|
||||
type: number
|
||||
subtaskSort:
|
||||
description: |
|
||||
subtask sort value
|
||||
type: number
|
||||
x-nullable: true
|
||||
type:
|
||||
description: |
|
||||
type of the card
|
||||
type: string
|
||||
linkedId:
|
||||
description: |
|
||||
ID of the linked card
|
||||
type: string
|
||||
x-nullable: true
|
||||
required:
|
||||
- archived
|
||||
- swimlaneId
|
||||
- createdAt
|
||||
- modifiedAt
|
||||
- dateLastActivity
|
||||
- userId
|
||||
- sort
|
||||
- type
|
||||
CardsCustomfields:
|
||||
type: object
|
||||
ChecklistItems:
|
||||
type: object
|
||||
description: An item in a checklist
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
User-agent: *
|
||||
Disallow: /
|
||||
+2
-2
@@ -18,8 +18,8 @@ REM Install chocolatey
|
||||
|
||||
choco install -y git curl python2 dotnet4.5.2 nano mongodb-3 mongoclient meteor
|
||||
|
||||
curl -O https://nodejs.org/dist/v12.16.1/node-v12.16.1-x64.msi
|
||||
call node-v12.16.1-x64.msi
|
||||
curl -O https://nodejs.org/dist/v12.16.2/node-v12.16.2-x64.msi
|
||||
call node-v12.16.2-x64.msi
|
||||
|
||||
call npm config -g set msvs_version 2015
|
||||
call meteor npm config -g set msvs_version 2015
|
||||
|
||||
+2
-2
@@ -5,7 +5,7 @@ echo " with 'sudo dpkg-reconfigure locales' , so that MongoDB works correct
|
||||
echo " You can still use any other locale as your main locale."
|
||||
|
||||
#Below script installs newest node 8.x for Debian/Ubuntu/Mint.
|
||||
#NODE_VERSION=12.16.1
|
||||
#NODE_VERSION=12.16.2
|
||||
#X64NODE="https://nodejs.org/dist/v${NODE_VERSION}/node-v${NODE_VERSION}-linux-x64.tar.gz"
|
||||
|
||||
function pause(){
|
||||
@@ -79,7 +79,7 @@ do
|
||||
curl -0 -L https://npmjs.org/install.sh | sudo sh
|
||||
sudo chown -R $(id -u):$(id -g) $HOME/.npm
|
||||
sudo npm -g install n
|
||||
sudo n 12.16.1
|
||||
sudo n 12.16.2
|
||||
#curl -sL https://deb.nodesource.com/setup_8.x | sudo -E bash -
|
||||
#sudo apt-get install -y nodejs
|
||||
elif [[ "$OSTYPE" == "darwin"* ]]; then
|
||||
|
||||
@@ -22,10 +22,10 @@ const pkgdef :Spk.PackageDefinition = (
|
||||
appTitle = (defaultText = "Wekan"),
|
||||
# The name of the app as it is displayed to the user.
|
||||
|
||||
appVersion = 390,
|
||||
appVersion = 395,
|
||||
# Increment this for every release.
|
||||
|
||||
appMarketingVersion = (defaultText = "3.90.0~2020-04-06"),
|
||||
appMarketingVersion = (defaultText = "3.95.0~2020-04-12"),
|
||||
# Human-readable presentation of the app version.
|
||||
|
||||
minUpgradableAppVersion = 0,
|
||||
@@ -242,6 +242,7 @@ const myCommand :Spk.Manifest.Command = (
|
||||
(key = "SCROLLINERTIA", value="0"),
|
||||
(key = "SCROLLAMOUNT", value="auto"),
|
||||
(key = "CARD_OPENED_WEBHOOK_ENABLED", value="false"),
|
||||
(key = "NOTIFICATION_TRAY_AFTER_READ_DAYS_BEFORE_REMOVE", value=""),
|
||||
(key = "BIGEVENTS_PATTERN", value="NONE"),
|
||||
(key = "MATOMO_ADDRESS", value=""),
|
||||
(key = "MATOMO_SITE_ID", value=""),
|
||||
|
||||
Loaded 100 of 108 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user