summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Dockerfile1
-rw-r--r--client/components/cards/cardDetails.js49
-rw-r--r--client/components/cards/subtasks.js15
-rw-r--r--docker-compose.yml5
-rw-r--r--models/cards.js62
-rw-r--r--models/users.js3
-rw-r--r--sandstorm-pkgdef.capnp1
-rwxr-xr-xsnap-src/bin/config6
-rwxr-xr-xsnap-src/bin/wekan-help5
-rwxr-xr-xstart-wekan.bat5
-rwxr-xr-xstart-wekan.sh5
-rw-r--r--torodb-postgresql/docker-compose.yml5
12 files changed, 100 insertions, 62 deletions
diff --git a/Dockerfile b/Dockerfile
index d9ccfcda..29248ca1 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -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="" \
diff --git a/client/components/cards/cardDetails.js b/client/components/cards/cardDetails.js
index 8492393c..84ba21b1 100644
--- a/client/components/cards/cardDetails.js
+++ b/client/components/cards/cardDetails.js
@@ -40,31 +40,29 @@ BlazeComponent.extendComponent({
voteState() {
const card = this.currentData();
- const userId = Meteor.userId()
- let state
+ 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 (state === true) return true;
}
if (card.vote.negative) {
state = _.contains(card.vote.negative, userId);
- if (state === true) return false
+ if (state === true) return false;
}
}
- return null
+ return null;
},
voteCountPositive() {
const card = this.currentData();
- if (card.vote && card.vote.positive)
- return card.vote.positive.length
- return null
+ 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
+ if (card.vote && card.vote.negative) return card.vote.negative.length;
+ return null;
},
isWatching() {
const card = this.currentData();
@@ -408,17 +406,17 @@ BlazeComponent.extendComponent({
Meteor.call('toggleSystemMessages');
},
'click .js-vote'(e) {
- const forIt = $(e.target).hasClass('js-vote-positive')
- let newState = null
+ const forIt = $(e.target).hasClass('js-vote-positive');
+ let newState = null;
if (
this.voteState() == null ||
- this.voteState() == false && forIt ||
- this.voteState() == true && !forIt
+ (this.voteState() == false && forIt) ||
+ (this.voteState() == true && !forIt)
) {
- newState = forIt
+ newState = forIt;
}
- this.data().setVote(Meteor.userId(), newState)
- }
+ this.data().setVote(Meteor.userId(), newState);
+ },
},
];
},
@@ -613,7 +611,7 @@ Template.cardDetailsActionsPopup.events({
'click .js-set-card-color': Popup.open('setCardColor'),
'click .js-cancel-voting'(event) {
event.preventDefault();
- this.unsetVote()
+ this.unsetVote();
Popup.close();
},
'click .js-move-card-to-top'(event) {
@@ -649,7 +647,7 @@ Template.cardDetailsActionsPopup.events({
},
});
-Template.editCardTitleForm.onRendered(function () {
+Template.editCardTitleForm.onRendered(function() {
autosize(this.$('.js-edit-card-title'));
});
@@ -663,7 +661,7 @@ Template.editCardTitleForm.events({
},
});
-Template.editCardRequesterForm.onRendered(function () {
+Template.editCardRequesterForm.onRendered(function() {
autosize(this.$('.js-edit-card-requester'));
});
@@ -676,7 +674,7 @@ Template.editCardRequesterForm.events({
},
});
-Template.editCardAssignerForm.onRendered(function () {
+Template.editCardAssignerForm.onRendered(function() {
autosize(this.$('.js-edit-card-assigner'));
});
@@ -816,7 +814,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;
@@ -965,7 +963,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);
@@ -1003,9 +1001,8 @@ BlazeComponent.extendComponent({
'submit .edit-vote-question'(evt) {
evt.preventDefault();
const voteQuestion = evt.target.vote.value;
- this.currentCard.setVoteQuestion(voteQuestion)
+ this.currentCard.setVoteQuestion(voteQuestion);
Popup.close();
-
},
},
];
diff --git a/client/components/cards/subtasks.js b/client/components/cards/subtasks.js
index cdc227fc..4cd15c11 100644
--- a/client/components/cards/subtasks.js
+++ b/client/components/cards/subtasks.js
@@ -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({
diff --git a/docker-compose.yml b/docker-compose.yml
index 54e50ce2..fe037add 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -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",
diff --git a/models/cards.js b/models/cards.js
index 1ee4ba68..94b174bb 100644
--- a/models/cards.js
+++ b/models/cards.js
@@ -334,8 +334,8 @@ Cards.attachSchema(
'vote.end': {
type: Date,
optional: true,
- defaultValue: null
- }
+ defaultValue: null,
+ },
}),
);
@@ -728,7 +728,7 @@ Cards.helpers({
parentString(sep) {
return this.parentList()
- .map(function (elem) {
+ .map(function(elem) {
return elem.title;
})
.join(sep);
@@ -1449,11 +1449,11 @@ Cards.mutations({
$set: {
vote: {
question,
- positive:[],
- negative:[]
+ positive: [],
+ negative: [],
},
- }
- }
+ },
+ };
},
unsetVote() {
return {
@@ -1467,32 +1467,32 @@ Cards.mutations({
case true:
// vote for it
return {
- $pull:{
- "vote.negative": userId
+ $pull: {
+ 'vote.negative': userId,
},
$addToSet: {
- "vote.positive": userId
- }
- }
+ 'vote.positive': userId,
+ },
+ };
case false:
// vote against
return {
- $pull:{
- "vote.positive": userId
+ $pull: {
+ 'vote.positive': userId,
},
$addToSet: {
- "vote.negative" : userId
- }
- }
+ 'vote.negative': userId,
+ },
+ };
default:
// Remove votes
return {
- $pull:{
- "vote.positive": userId,
- "vote.negative" : userId
+ $pull: {
+ 'vote.positive': userId,
+ 'vote.negative': userId,
},
- }
+ };
}
},
});
@@ -1897,7 +1897,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;
@@ -1943,7 +1943,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(
@@ -1997,7 +1997,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);
@@ -2007,7 +2007,7 @@ if (Meteor.isServer) {
boardId: paramBoardId,
swimlaneId: paramSwimlaneId,
archived: false,
- }).map(function (doc) {
+ }).map(function(doc) {
return {
_id: doc._id,
title: doc.title,
@@ -2031,7 +2031,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,
) {
@@ -2044,7 +2044,7 @@ if (Meteor.isServer) {
boardId: paramBoardId,
listId: paramListId,
archived: false,
- }).map(function (doc) {
+ }).map(function(doc) {
return {
_id: doc._id,
title: doc.title,
@@ -2066,7 +2066,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;
@@ -2098,7 +2098,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,
) {
@@ -2205,7 +2205,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;
@@ -2504,7 +2504,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;
diff --git a/models/users.js b/models/users.js
index 9b2a5465..8a05a0d2 100644
--- a/models/users.js
+++ b/models/users.js
@@ -931,7 +931,8 @@ 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_REMOVAL_AGE;
+ 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;
diff --git a/sandstorm-pkgdef.capnp b/sandstorm-pkgdef.capnp
index d1ed3967..cc2d8d84 100644
--- a/sandstorm-pkgdef.capnp
+++ b/sandstorm-pkgdef.capnp
@@ -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=""),
diff --git a/snap-src/bin/config b/snap-src/bin/config
index 3fc786fb..90c70c91 100755
--- a/snap-src/bin/config
+++ b/snap-src/bin/config
@@ -3,7 +3,7 @@
# All supported keys are defined here together with descriptions and default values
# list of supported keys
-keys="DEBUG MONGO_URL MONGODB_BIND_UNIX_SOCKET MONGO_URL MONGODB_BIND_IP MONGODB_PORT MAIL_URL MAIL_FROM ROOT_URL PORT DISABLE_MONGODB CADDY_ENABLED CADDY_BIND_PORT WITH_API RICHER_CARD_COMMENT_EDITOR CARD_OPENED_WEBHOOK_ENABLED ACCOUNTS_LOCKOUT_KNOWN_USERS_FAILURES_BEFORE ACCOUNTS_LOCKOUT_KNOWN_USERS_PERIOD ACCOUNTS_LOCKOUT_KNOWN_USERS_FAILURE_WINDOW ACCOUNTS_LOCKOUT_UNKNOWN_USERS_FAILURES_BERORE ACCOUNTS_LOCKOUT_UNKNOWN_USERS_LOCKOUT_PERIOD ACCOUNTS_LOCKOUT_UNKNOWN_USERS_FAILURE_WINDOW MAX_IMAGE_PIXEL IMAGE_COMPRESS_RATIO BIGEVENTS_PATTERN NOTIFY_DUE_DAYS_BEFORE_AND_AFTER NOTIFY_DUE_AT_HOUR_OF_DAY EMAIL_NOTIFICATION_TIMEOUT CORS CORS_ALLOW_HEADERS CORS_EXPOSE_HEADERS MATOMO_ADDRESS MATOMO_SITE_ID MATOMO_DO_NOT_TRACK MATOMO_WITH_USERNAME BROWSER_POLICY_ENABLED TRUSTED_URL WEBHOOKS_ATTRIBUTES OAUTH2_ENABLED OAUTH2_LOGIN_STYLE OAUTH2_CLIENT_ID OAUTH2_SECRET OAUTH2_SERVER_URL OAUTH2_AUTH_ENDPOINT OAUTH2_USERINFO_ENDPOINT OAUTH2_TOKEN_ENDPOINT OAUTH2_ID_MAP OAUTH2_USERNAME_MAP OAUTH2_FULLNAME_MAP OAUTH2_ID_TOKEN_WHITELIST_FIELDS OAUTH2_EMAIL_MAP OAUTH2_REQUEST_PERMISSIONS LDAP_ENABLE LDAP_PORT LDAP_HOST LDAP_BASEDN LDAP_LOGIN_FALLBACK LDAP_RECONNECT LDAP_TIMEOUT LDAP_IDLE_TIMEOUT LDAP_CONNECT_TIMEOUT LDAP_AUTHENTIFICATION LDAP_AUTHENTIFICATION_USERDN LDAP_AUTHENTIFICATION_PASSWORD LDAP_LOG_ENABLED LDAP_BACKGROUND_SYNC LDAP_BACKGROUND_SYNC_INTERVAL LDAP_BACKGROUND_SYNC_KEEP_EXISTANT_USERS_UPDATED LDAP_BACKGROUND_SYNC_IMPORT_NEW_USERS LDAP_ENCRYPTION LDAP_CA_CERT LDAP_REJECT_UNAUTHORIZED LDAP_USER_AUTHENTICATION LDAP_USER_AUTHENTICATION_FIELD LDAP_USER_SEARCH_FILTER LDAP_USER_SEARCH_SCOPE LDAP_USER_SEARCH_FIELD LDAP_SEARCH_PAGE_SIZE LDAP_SEARCH_SIZE_LIMIT LDAP_GROUP_FILTER_ENABLE LDAP_GROUP_FILTER_OBJECTCLASS LDAP_GROUP_FILTER_GROUP_ID_ATTRIBUTE LDAP_GROUP_FILTER_GROUP_MEMBER_ATTRIBUTE LDAP_GROUP_FILTER_GROUP_MEMBER_FORMAT LDAP_GROUP_FILTER_GROUP_NAME LDAP_UNIQUE_IDENTIFIER_FIELD LDAP_UTF8_NAMES_SLUGIFY LDAP_USERNAME_FIELD LDAP_FULLNAME_FIELD LDAP_MERGE_EXISTING_USERS LDAP_SYNC_USER_DATA LDAP_SYNC_USER_DATA_FIELDMAP LDAP_SYNC_GROUP_ROLES LDAP_DEFAULT_DOMAIN LDAP_EMAIL_MATCH_ENABLE LDAP_EMAIL_MATCH_REQUIRE LDAP_EMAIL_MATCH_VERIFIED LDAP_EMAIL_FIELD LDAP_SYNC_ADMIN_STATUS LDAP_SYNC_ADMIN_GROUPS HEADER_LOGIN_ID HEADER_LOGIN_FIRSTNAME HEADER_LOGIN_LASTNAME HEADER_LOGIN_EMAIL LOGOUT_WITH_TIMER LOGOUT_IN LOGOUT_ON_HOURS LOGOUT_ON_MINUTES DEFAULT_AUTHENTICATION_METHOD ATTACHMENTS_STORE_PATH SCROLLINERTIA SCROLLAMOUNT"
+keys="DEBUG MONGO_URL MONGODB_BIND_UNIX_SOCKET MONGO_URL MONGODB_BIND_IP MONGODB_PORT MAIL_URL MAIL_FROM ROOT_URL PORT DISABLE_MONGODB CADDY_ENABLED CADDY_BIND_PORT WITH_API RICHER_CARD_COMMENT_EDITOR CARD_OPENED_WEBHOOK_ENABLED ACCOUNTS_LOCKOUT_KNOWN_USERS_FAILURES_BEFORE ACCOUNTS_LOCKOUT_KNOWN_USERS_PERIOD ACCOUNTS_LOCKOUT_KNOWN_USERS_FAILURE_WINDOW ACCOUNTS_LOCKOUT_UNKNOWN_USERS_FAILURES_BERORE ACCOUNTS_LOCKOUT_UNKNOWN_USERS_LOCKOUT_PERIOD ACCOUNTS_LOCKOUT_UNKNOWN_USERS_FAILURE_WINDOW MAX_IMAGE_PIXEL IMAGE_COMPRESS_RATIO BIGEVENTS_PATTERN NOTIFICATION_TRAY_AFTER_READ_DAYS_BEFORE_REMOVE NOTIFY_DUE_DAYS_BEFORE_AND_AFTER NOTIFY_DUE_AT_HOUR_OF_DAY EMAIL_NOTIFICATION_TIMEOUT CORS CORS_ALLOW_HEADERS CORS_EXPOSE_HEADERS MATOMO_ADDRESS MATOMO_SITE_ID MATOMO_DO_NOT_TRACK MATOMO_WITH_USERNAME BROWSER_POLICY_ENABLED TRUSTED_URL WEBHOOKS_ATTRIBUTES OAUTH2_ENABLED OAUTH2_LOGIN_STYLE OAUTH2_CLIENT_ID OAUTH2_SECRET OAUTH2_SERVER_URL OAUTH2_AUTH_ENDPOINT OAUTH2_USERINFO_ENDPOINT OAUTH2_TOKEN_ENDPOINT OAUTH2_ID_MAP OAUTH2_USERNAME_MAP OAUTH2_FULLNAME_MAP OAUTH2_ID_TOKEN_WHITELIST_FIELDS OAUTH2_EMAIL_MAP OAUTH2_REQUEST_PERMISSIONS LDAP_ENABLE LDAP_PORT LDAP_HOST LDAP_BASEDN LDAP_LOGIN_FALLBACK LDAP_RECONNECT LDAP_TIMEOUT LDAP_IDLE_TIMEOUT LDAP_CONNECT_TIMEOUT LDAP_AUTHENTIFICATION LDAP_AUTHENTIFICATION_USERDN LDAP_AUTHENTIFICATION_PASSWORD LDAP_LOG_ENABLED LDAP_BACKGROUND_SYNC LDAP_BACKGROUND_SYNC_INTERVAL LDAP_BACKGROUND_SYNC_KEEP_EXISTANT_USERS_UPDATED LDAP_BACKGROUND_SYNC_IMPORT_NEW_USERS LDAP_ENCRYPTION LDAP_CA_CERT LDAP_REJECT_UNAUTHORIZED LDAP_USER_AUTHENTICATION LDAP_USER_AUTHENTICATION_FIELD LDAP_USER_SEARCH_FILTER LDAP_USER_SEARCH_SCOPE LDAP_USER_SEARCH_FIELD LDAP_SEARCH_PAGE_SIZE LDAP_SEARCH_SIZE_LIMIT LDAP_GROUP_FILTER_ENABLE LDAP_GROUP_FILTER_OBJECTCLASS LDAP_GROUP_FILTER_GROUP_ID_ATTRIBUTE LDAP_GROUP_FILTER_GROUP_MEMBER_ATTRIBUTE LDAP_GROUP_FILTER_GROUP_MEMBER_FORMAT LDAP_GROUP_FILTER_GROUP_NAME LDAP_UNIQUE_IDENTIFIER_FIELD LDAP_UTF8_NAMES_SLUGIFY LDAP_USERNAME_FIELD LDAP_FULLNAME_FIELD LDAP_MERGE_EXISTING_USERS LDAP_SYNC_USER_DATA LDAP_SYNC_USER_DATA_FIELDMAP LDAP_SYNC_GROUP_ROLES LDAP_DEFAULT_DOMAIN LDAP_EMAIL_MATCH_ENABLE LDAP_EMAIL_MATCH_REQUIRE LDAP_EMAIL_MATCH_VERIFIED LDAP_EMAIL_FIELD LDAP_SYNC_ADMIN_STATUS LDAP_SYNC_ADMIN_GROUPS HEADER_LOGIN_ID HEADER_LOGIN_FIRSTNAME HEADER_LOGIN_LASTNAME HEADER_LOGIN_EMAIL LOGOUT_WITH_TIMER LOGOUT_IN LOGOUT_ON_HOURS LOGOUT_ON_MINUTES DEFAULT_AUTHENTICATION_METHOD ATTACHMENTS_STORE_PATH SCROLLINERTIA SCROLLAMOUNT"
# default values
DESCRIPTION_DEBUG="Debug OIDC OAuth2 etc. Example: sudo snap set wekan debug='true'"
@@ -104,6 +104,10 @@ DESCRIPTION_IMAGE_COMPRESS_RATIO="Image compress ratio: Allow to shrink attached
DEFAULT_IMAGE_COMPRESS_RATIO=""
KEY_IMAGE_COMPRESS_RATIO="image-compress-ratio"
+DESCRIPTION_NOTIFICATION_TRAY_AFTER_READ_DAYS_BEFORE_REMOVE="Number of days after a notification is read before we remove it. Default: 2."
+DEFAULT_NOTIFICATION_TRAY_AFTER_READ_DAYS_BEFORE_REMOVE=""
+KEY_NOTIFICATION_TRAY_AFTER_READ_DAYS_BEFORE_REMOVE="notification-tray-after-read-days-before-remove"
+
DESCRIPTION_BIGEVENTS_PATTERN="Big events pattern: Notify always due etc regardless of notification settings. Default: NONE, All: received|start|due|end, Disabled: NONE"
DEFAULT_BIGEVENTS_PATTERN="NONE"
KEY_BIGEVENTS_PATTERN="bigevents-pattern"
diff --git a/snap-src/bin/wekan-help b/snap-src/bin/wekan-help
index 1d6d87a1..008a4de1 100755
--- a/snap-src/bin/wekan-help
+++ b/snap-src/bin/wekan-help
@@ -105,6 +105,11 @@ echo -e "\t$ snap set $SNAP_NAME attachments-store-path='/var/snap/wekan/common/
echo -e "Disabled:"
echo -e "\t$ snap set $SNAP_NAME attachments-store-path=''"
echo -e "\n"
+echo -e "NOTIFICATION TRAY AFTER READ DAYS BEFORE REMOVE https://github.com/wekan/wekan/pull/2998"
+echo -e "Number of days after a notification is read before we remove it. Default: 2."
+echo -e "Default:"
+echo -e "\t$ snap set $SNAP_NAME notification-tray-after-read-days-before-remove='2'"
+echo -e "\n"
echo -e "BIGEVENTS DUE ETC NOTIFICATIONS https://github.com/wekan/wekan/pull/2541"
echo -e "Big events pattern: Notify always due etc regardless of notification settings. Default: due, All: received|start|due|end, Disabled: NONE"
echo -e "Default:"
diff --git a/start-wekan.bat b/start-wekan.bat
index bb5b883c..61c242ee 100755
--- a/start-wekan.bat
+++ b/start-wekan.bat
@@ -48,6 +48,11 @@ REM SET ACCOUNTS_LOCKOUT_UNKNOWN_USERS_FAILURES_BERORE=3
REM SET ACCOUNTS_LOCKOUT_UNKNOWN_USERS_LOCKOUT_PERIOD=60
REM SET ACCOUNTS_LOCKOUT_UNKNOWN_USERS_FAILURE_WINDOW=15
+REM # ==== NOTIFICATION TRAY AFTER READ DAYS BEFORE REMOVE =====
+REM # Number of days after a notification is read before we remove it.
+REM # Default: 2
+REM SET NOTIFICATION_TRAY_AFTER_READ_DAYS_BEFORE_REMOVE=2
+
REM # ==== BIGEVENTS DUE ETC NOTIFICATIONS =====
REM # https://github.com/wekan/wekan/pull/2541
REM # Introduced a system env var BIGEVENTS_PATTERN default as "NONE",
diff --git a/start-wekan.sh b/start-wekan.sh
index bb9249a6..bf598e39 100755
--- a/start-wekan.sh
+++ b/start-wekan.sh
@@ -54,6 +54,11 @@
#export MAX_IMAGE_PIXEL=1024
#export 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",
diff --git a/torodb-postgresql/docker-compose.yml b/torodb-postgresql/docker-compose.yml
index d741d1a1..e742402f 100644
--- a/torodb-postgresql/docker-compose.yml
+++ b/torodb-postgresql/docker-compose.yml
@@ -244,6 +244,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",