Merge pull request #5 from wekan/master

Update
This commit is contained in:
NicoP-S 2020-04-08 23:22:49 +02:00 committed by GitHub
commit 7c25542976
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
83 changed files with 36895 additions and 36179 deletions

View file

@ -1,6 +1,6 @@
{ {
"name": "wekan", "name": "wekan",
"version": "v3.90.0", "version": "v3.92.0",
"lockfileVersion": 1, "lockfileVersion": 1,
"requires": true, "requires": true,
"dependencies": { "dependencies": {

View file

@ -1,6 +1,6 @@
{ {
"name": "wekan", "name": "wekan",
"version": "v3.90.0", "version": "v3.92.0",
"description": "Open-Source kanban", "description": "Open-Source kanban",
"private": true, "private": true,
"scripts": { "scripts": {

View file

@ -1,3 +1,32 @@
# 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 # v3.90 2020-04-06 Wekan release
This release makes the following updates: This release makes the following updates:

View file

@ -26,6 +26,7 @@ ENV BUILD_DEPS="apt-utils libarchive-tools gnupg gosu wget curl bzip2 g++ build-
ATTACHMENTS_STORE_PATH="" \ ATTACHMENTS_STORE_PATH="" \
MAX_IMAGE_PIXEL="" \ MAX_IMAGE_PIXEL="" \
IMAGE_COMPRESS_RATIO="" \ IMAGE_COMPRESS_RATIO="" \
NOTIFICATION_TRAY_AFTER_READ_DAYS_BEFORE_REMOVE="" \
BIGEVENTS_PATTERN=NONE \ BIGEVENTS_PATTERN=NONE \
NOTIFY_DUE_DAYS_BEFORE_AND_AFTER="" \ NOTIFY_DUE_DAYS_BEFORE_AND_AFTER="" \
NOTIFY_DUE_AT_HOUR_OF_DAY="" \ NOTIFY_DUE_AT_HOUR_OF_DAY="" \

View file

@ -1,5 +1,5 @@
appId: wekan-public/apps/77b94f60-dec9-0136-304e-16ff53095928 appId: wekan-public/apps/77b94f60-dec9-0136-304e-16ff53095928
appVersion: "v3.90.0" appVersion: "v3.92.0"
files: files:
userUploads: userUploads:
- README.md - README.md

View file

@ -40,31 +40,29 @@ BlazeComponent.extendComponent({
voteState() { voteState() {
const card = this.currentData(); const card = this.currentData();
const userId = Meteor.userId() const userId = Meteor.userId();
let state let state;
if (card.vote) { if (card.vote) {
if (card.vote.positive) { if (card.vote.positive) {
state = _.contains(card.vote.positive, userId); state = _.contains(card.vote.positive, userId);
if (state === true) return true if (state === true) return true;
} }
if (card.vote.negative) { if (card.vote.negative) {
state = _.contains(card.vote.negative, userId); state = _.contains(card.vote.negative, userId);
if (state === true) return false if (state === true) return false;
} }
} }
return null return null;
}, },
voteCountPositive() { voteCountPositive() {
const card = this.currentData(); const card = this.currentData();
if (card.vote && card.vote.positive) if (card.vote && card.vote.positive) return card.vote.positive.length;
return card.vote.positive.length return null;
return null
}, },
voteCountNegative() { voteCountNegative() {
const card = this.currentData(); const card = this.currentData();
if (card.vote && card.vote.negative) if (card.vote && card.vote.negative) return card.vote.negative.length;
return card.vote.negative.length return null;
return null
}, },
isWatching() { isWatching() {
const card = this.currentData(); const card = this.currentData();
@ -408,17 +406,17 @@ BlazeComponent.extendComponent({
Meteor.call('toggleSystemMessages'); Meteor.call('toggleSystemMessages');
}, },
'click .js-vote'(e) { 'click .js-vote'(e) {
const forIt = $(e.target).hasClass('js-vote-positive') const forIt = $(e.target).hasClass('js-vote-positive');
let newState = null let newState = null;
if ( if (
this.voteState() == null || this.voteState() == null ||
this.voteState() == false && forIt || (this.voteState() == false && forIt) ||
this.voteState() == true && !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-set-card-color': Popup.open('setCardColor'),
'click .js-cancel-voting'(event) { 'click .js-cancel-voting'(event) {
event.preventDefault(); event.preventDefault();
this.unsetVote() this.unsetVote();
Popup.close(); Popup.close();
}, },
'click .js-move-card-to-top'(event) { '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')); 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')); 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')); autosize(this.$('.js-edit-card-assigner'));
}); });
@ -816,7 +814,7 @@ Template.copyChecklistToManyCardsPopup.events({
// copy subtasks // copy subtasks
cursor = Cards.find({ parentId: oldId }); cursor = Cards.find({ parentId: oldId });
cursor.forEach(function () { cursor.forEach(function() {
'use strict'; 'use strict';
const subtask = arguments[0]; const subtask = arguments[0];
subtask.parentId = _id; 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(); Popup.close();
Cards.remove(this._id); Cards.remove(this._id);
Utils.goBoardId(this.boardId); Utils.goBoardId(this.boardId);
@ -1003,9 +1001,8 @@ BlazeComponent.extendComponent({
'submit .edit-vote-question'(evt) { 'submit .edit-vote-question'(evt) {
evt.preventDefault(); evt.preventDefault();
const voteQuestion = evt.target.vote.value; const voteQuestion = evt.target.vote.value;
this.currentCard.setVoteQuestion(voteQuestion) this.currentCard.setVoteQuestion(voteQuestion);
Popup.close(); Popup.close();
}, },
}, },
]; ];

View file

@ -100,11 +100,11 @@ avatar-radius = 50%
.ps-scrollbar-y-rail .ps-scrollbar-y-rail
pointer-event: all pointer-event: all
position: absolute; position: absolute
.card-details-canvas .card-details-canvas
width: 470px width: 470px
padding-left: 20px; padding-left: 20px
.card-details-header .card-details-header
margin: 0 -20px 5px margin: 0 -20px 5px
@ -241,7 +241,7 @@ input[type="submit"].attachment-add-link-submit
.card-details-canvas .card-details-canvas
width: 100% width: 100%
padding-left: 0px; padding-left: 0px
.card-details-header .card-details-header
.close-card-details .close-card-details
@ -334,7 +334,7 @@ card-details-color(background, color...)
.voted .voted
opacity: .7 opacity: .7
.vote-title .vote-title
display: flex; display: flex
justify-content: space-between; justify-content: space-between
.vote-result .vote-result
display: flex; display: flex

View file

@ -22,11 +22,20 @@ BlazeComponent.extendComponent({
const listId = targetBoard.getDefaultSubtasksListId(); const listId = targetBoard.getDefaultSubtasksListId();
//Get the full swimlane data for the parent task. //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. //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. //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) { if (title) {
const _id = Cards.insert({ const _id = Cards.insert({

View file

@ -14,3 +14,7 @@ template(name='notificationsDrawer')
+notification(activityData=activity index=dbIndex read=read) +notification(activityData=activity index=dbIndex read=read)
if($gt unreadNotifications 0) if($gt unreadNotifications 0)
a.all-read {{_ 'mark-all-as-read'}} 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'}}

View file

@ -16,6 +16,13 @@ Template.notificationsDrawer.helpers({
transformedProfile() { transformedProfile() {
return Users.findOne(Meteor.userId()); return Users.findOne(Meteor.userId());
}, },
readNotifications() {
const readNotifications = _.filter(
Meteor.user().profile.notifications,
v => !!v.read,
);
return readNotifications.length;
},
}); });
Template.notificationsDrawer.events({ Template.notificationsDrawer.events({
@ -35,4 +42,12 @@ Template.notificationsDrawer.events({
'click .toggle-read'() { 'click .toggle-read'() {
Session.set('showReadNotifications', !Session.get('showReadNotifications')); 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);
}
}
},
}); });

View file

@ -45,12 +45,23 @@ section#notifications-drawer
line-height: 24px line-height: 24px
opacity 1 opacity 1
.all-read .all-read,
.remove-read
color belize color belize
background-color: #fafafa background-color: #fafafa
margin 8px 16px 12px margin 8px 16px 12px
display inline-block display inline-block
.remove-read
float right
&:hover
color #eb4646 !important
i.fa
color inherit
ul.notifications ul.notifications
display: block display: block
padding: 0px 16px padding: 0px 16px

View file

@ -45,6 +45,24 @@ template(name="filterSidebar")
if Filter.members.isSelected _id if Filter.members.isSelected _id
i.fa.fa-check i.fa.fa-check
hr 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 ul.sidebar-list
li(class="{{#if Filter.customFields.isSelected undefined}}active{{/if}}") li(class="{{#if Filter.customFields.isSelected undefined}}active{{/if}}")
a.name.js-toggle-custom-fields-filter a.name.js-toggle-custom-fields-filter

View file

@ -18,6 +18,11 @@ BlazeComponent.extendComponent({
Filter.members.toggle(this.currentData()._id); Filter.members.toggle(this.currentData()._id);
Filter.resetExceptions(); Filter.resetExceptions();
}, },
'click .js-toggle-assignee-filter'(evt) {
evt.preventDefault();
Filter.assignees.toggle(this.currentData()._id);
Filter.resetExceptions();
},
'click .js-toggle-archive-filter'(evt) { 'click .js-toggle-archive-filter'(evt) {
evt.preventDefault(); evt.preventDefault();
Filter.archive.toggle(this.currentData()._id); Filter.archive.toggle(this.currentData()._id);

View file

@ -459,13 +459,21 @@ Filter = {
// before changing the schema. // before changing the schema.
labelIds: new SetFilter(), labelIds: new SetFilter(),
members: new SetFilter(), members: new SetFilter(),
assignees: new SetFilter(),
archive: new SetFilter(), archive: new SetFilter(),
hideEmpty: new SetFilter(), hideEmpty: new SetFilter(),
customFields: new SetFilter('_id'), customFields: new SetFilter('_id'),
advanced: new AdvancedFilter(), advanced: new AdvancedFilter(),
lists: new AdvancedFilter(), // we need the ability to filter list by name as well 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 // 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 // implement this we keep the id of these cards in this `_exceptions` fields

View file

@ -254,6 +254,11 @@ services:
#-MAX_IMAGE_PIXEL=1024 #-MAX_IMAGE_PIXEL=1024
#-IMAGE_COMPRESS_RATIO=80 #-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 ===== # ==== BIGEVENTS DUE ETC NOTIFICATIONS =====
# https://github.com/wekan/wekan/pull/2541 # https://github.com/wekan/wekan/pull/2541
# Introduced a system env var BIGEVENTS_PATTERN default as "NONE", # Introduced a system env var BIGEVENTS_PATTERN default as "NONE",

View file

@ -56,3 +56,10 @@ mongodb-replicaset:
This section controls the scale of the MongoDB redundant Replica Set. 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. **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-
```

View file

@ -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 }}

View file

@ -59,6 +59,9 @@ ingress:
# hosts: # hosts:
# - wekan-example.local # - wekan-example.local
route:
enabled: false
resources: resources:
requests: requests:
memory: 128Mi memory: 128Mi

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -152,6 +152,8 @@
"card-spent": "Aufgewendete Zeit", "card-spent": "Aufgewendete Zeit",
"card-edit-attachments": "Anhänge ändern", "card-edit-attachments": "Anhänge ändern",
"card-edit-custom-fields": "Benutzerdefinierte Felder editieren", "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-labels": "Labels ändern",
"card-edit-members": "Mitglieder ändern", "card-edit-members": "Mitglieder ändern",
"card-labels-title": "Labels für diese Karte ändern.", "card-labels-title": "Labels für diese Karte ändern.",
@ -161,6 +163,10 @@
"cardAttachmentsPopup-title": "Anhängen von", "cardAttachmentsPopup-title": "Anhängen von",
"cardCustomField-datePopup-title": "Datum ändern", "cardCustomField-datePopup-title": "Datum ändern",
"cardCustomFieldsPopup-title": "Benutzerdefinierte Felder editieren", "cardCustomFieldsPopup-title": "Benutzerdefinierte Felder editieren",
"cardStartVotingPopup-title": "Abstimmung starten",
"vote-question": "Abstimmen über",
"vote-for-it": "Dafür",
"vote-against": "Dagegen",
"cardDeletePopup-title": "Karte löschen?", "cardDeletePopup-title": "Karte löschen?",
"cardDetailsActionsPopup-title": "Kartenaktionen", "cardDetailsActionsPopup-title": "Kartenaktionen",
"cardLabelsPopup-title": "Labels", "cardLabelsPopup-title": "Labels",
@ -319,6 +325,7 @@
"filter-clear": "Filter entfernen", "filter-clear": "Filter entfernen",
"filter-no-label": "Kein Label", "filter-no-label": "Kein Label",
"filter-no-member": "Kein Mitglied", "filter-no-member": "Kein Mitglied",
"filter-no-assignee": "No assignee",
"filter-no-custom-fields": "Keine benutzerdefinierten Felder", "filter-no-custom-fields": "Keine benutzerdefinierten Felder",
"filter-show-archive": "Archivierte Listen anzeigen", "filter-show-archive": "Archivierte Listen anzeigen",
"filter-hide-empty": "Leere Listen verstecken", "filter-hide-empty": "Leere Listen verstecken",
@ -763,7 +770,8 @@
"notifications": "Benachrichtigungen", "notifications": "Benachrichtigungen",
"view-all": "Alle anzeigen", "view-all": "Alle anzeigen",
"filter-by-unread": "Nach Ungelesenen filtern", "filter-by-unread": "Nach Ungelesenen filtern",
"mark-all-as-read": "Als ungelesen markieren", "mark-all-as-read": "Alle als gelesen markieren",
"remove-all-read": "Alle gelesenen entfernen",
"allow-rename": "Umbenennen erlauben", "allow-rename": "Umbenennen erlauben",
"allowRenamePopup-title": "Umbenennen erlauben" "allowRenamePopup-title": "Umbenennen erlauben"
} }

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -153,7 +153,7 @@
"card-edit-attachments": "Edit attachments", "card-edit-attachments": "Edit attachments",
"card-edit-custom-fields": "Edit custom fields", "card-edit-custom-fields": "Edit custom fields",
"card-start-voting": "Start voting", "card-start-voting": "Start voting",
"card-cancel-voting": "Delete voting", "card-cancel-voting": "Delete voting and all votes",
"card-edit-labels": "Edit labels", "card-edit-labels": "Edit labels",
"card-edit-members": "Edit members", "card-edit-members": "Edit members",
"card-labels-title": "Change the labels for the card.", "card-labels-title": "Change the labels for the card.",
@ -325,6 +325,7 @@
"filter-clear": "Clear filter", "filter-clear": "Clear filter",
"filter-no-label": "No label", "filter-no-label": "No label",
"filter-no-member": "No member", "filter-no-member": "No member",
"filter-no-assignee": "No assignee",
"filter-no-custom-fields": "No Custom Fields", "filter-no-custom-fields": "No Custom Fields",
"filter-show-archive": "Show archived lists", "filter-show-archive": "Show archived lists",
"filter-hide-empty": "Hide empty lists", "filter-hide-empty": "Hide empty lists",
@ -773,6 +774,7 @@
"view-all": "View All", "view-all": "View All",
"filter-by-unread": "Filter by Unread", "filter-by-unread": "Filter by Unread",
"mark-all-as-read": "Mark all as read", "mark-all-as-read": "Mark all as read",
"remove-all-read": "Remove all read",
"allow-rename": "Allow Rename", "allow-rename": "Allow Rename",
"allowRenamePopup-title": "Allow Rename" "allowRenamePopup-title": "Allow Rename"
} }

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -152,6 +152,8 @@
"card-spent": "Tiempo consumido", "card-spent": "Tiempo consumido",
"card-edit-attachments": "Editar los adjuntos", "card-edit-attachments": "Editar los adjuntos",
"card-edit-custom-fields": "Editar los campos personalizados", "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-labels": "Editar las etiquetas",
"card-edit-members": "Editar los miembros", "card-edit-members": "Editar los miembros",
"card-labels-title": "Cambia las etiquetas de la tarjeta", "card-labels-title": "Cambia las etiquetas de la tarjeta",
@ -161,6 +163,10 @@
"cardAttachmentsPopup-title": "Adjuntar desde", "cardAttachmentsPopup-title": "Adjuntar desde",
"cardCustomField-datePopup-title": "Cambiar la fecha", "cardCustomField-datePopup-title": "Cambiar la fecha",
"cardCustomFieldsPopup-title": "Editar los campos personalizados", "cardCustomFieldsPopup-title": "Editar los campos personalizados",
"cardStartVotingPopup-title": "Start a vote",
"vote-question": "Voting question",
"vote-for-it": "for it",
"vote-against": "against",
"cardDeletePopup-title": "¿Eliminar la tarjeta?", "cardDeletePopup-title": "¿Eliminar la tarjeta?",
"cardDetailsActionsPopup-title": "Acciones de la tarjeta", "cardDetailsActionsPopup-title": "Acciones de la tarjeta",
"cardLabelsPopup-title": "Etiquetas", "cardLabelsPopup-title": "Etiquetas",
@ -319,6 +325,7 @@
"filter-clear": "Limpiar el filtro", "filter-clear": "Limpiar el filtro",
"filter-no-label": "Sin etiqueta", "filter-no-label": "Sin etiqueta",
"filter-no-member": "Sin miembro", "filter-no-member": "Sin miembro",
"filter-no-assignee": "No assignee",
"filter-no-custom-fields": "Sin campos personalizados", "filter-no-custom-fields": "Sin campos personalizados",
"filter-show-archive": "Mostrar las listas archivadas", "filter-show-archive": "Mostrar las listas archivadas",
"filter-hide-empty": "Ocultar las listas vacías", "filter-hide-empty": "Ocultar las listas vacías",
@ -764,6 +771,7 @@
"view-all": "Ver todo", "view-all": "Ver todo",
"filter-by-unread": "Filtrar por no leído", "filter-by-unread": "Filtrar por no leído",
"mark-all-as-read": "Marcar todo como leido", "mark-all-as-read": "Marcar todo como leido",
"remove-all-read": "Remove all read",
"allow-rename": "Permitir renombrar", "allow-rename": "Permitir renombrar",
"allowRenamePopup-title": "Permitir renombrar" "allowRenamePopup-title": "Permitir renombrar"
} }

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -152,6 +152,8 @@
"card-spent": "Tempo trascorso", "card-spent": "Tempo trascorso",
"card-edit-attachments": "Modifica allegati", "card-edit-attachments": "Modifica allegati",
"card-edit-custom-fields": "Modifica campo personalizzato", "card-edit-custom-fields": "Modifica campo personalizzato",
"card-start-voting": "Start voting",
"card-cancel-voting": "Delete voting and all votes",
"card-edit-labels": "Modifica etichette", "card-edit-labels": "Modifica etichette",
"card-edit-members": "Modifica membri", "card-edit-members": "Modifica membri",
"card-labels-title": "Cambia le etichette per questa scheda.", "card-labels-title": "Cambia le etichette per questa scheda.",
@ -161,6 +163,10 @@
"cardAttachmentsPopup-title": "Allega da", "cardAttachmentsPopup-title": "Allega da",
"cardCustomField-datePopup-title": "Cambia data", "cardCustomField-datePopup-title": "Cambia data",
"cardCustomFieldsPopup-title": "Modifica campo personalizzato", "cardCustomFieldsPopup-title": "Modifica campo personalizzato",
"cardStartVotingPopup-title": "Start a vote",
"vote-question": "Voting question",
"vote-for-it": "for it",
"vote-against": "against",
"cardDeletePopup-title": "Elimina scheda?", "cardDeletePopup-title": "Elimina scheda?",
"cardDetailsActionsPopup-title": "Azioni scheda", "cardDetailsActionsPopup-title": "Azioni scheda",
"cardLabelsPopup-title": "Etichette", "cardLabelsPopup-title": "Etichette",
@ -319,6 +325,7 @@
"filter-clear": "Pulisci filtri", "filter-clear": "Pulisci filtri",
"filter-no-label": "Nessuna etichetta", "filter-no-label": "Nessuna etichetta",
"filter-no-member": "Nessun membro", "filter-no-member": "Nessun membro",
"filter-no-assignee": "No assignee",
"filter-no-custom-fields": "Nessun campo personalizzato", "filter-no-custom-fields": "Nessun campo personalizzato",
"filter-show-archive": "Mostra le liste archiviate", "filter-show-archive": "Mostra le liste archiviate",
"filter-hide-empty": "Nascondi liste vuote", "filter-hide-empty": "Nascondi liste vuote",
@ -764,6 +771,7 @@
"view-all": "Mostra Tutto", "view-all": "Mostra Tutto",
"filter-by-unread": "Filtra per non letto", "filter-by-unread": "Filtra per non letto",
"mark-all-as-read": "Segna come letto", "mark-all-as-read": "Segna come letto",
"remove-all-read": "Remove all read",
"allow-rename": "Consenti Rinomina", "allow-rename": "Consenti Rinomina",
"allowRenamePopup-title": "Consenti Rinomina" "allowRenamePopup-title": "Consenti Rinomina"
} }

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -152,6 +152,8 @@
"card-spent": "Gespendeerde tijd", "card-spent": "Gespendeerde tijd",
"card-edit-attachments": "Wijzig bijlagen", "card-edit-attachments": "Wijzig bijlagen",
"card-edit-custom-fields": "Wijzig maatwerkvelden", "card-edit-custom-fields": "Wijzig maatwerkvelden",
"card-start-voting": "Start voting",
"card-cancel-voting": "Delete voting and all votes",
"card-edit-labels": "Wijzig labels", "card-edit-labels": "Wijzig labels",
"card-edit-members": "Wijzig leden", "card-edit-members": "Wijzig leden",
"card-labels-title": "Wijzig de labels van de kaart.", "card-labels-title": "Wijzig de labels van de kaart.",
@ -161,6 +163,10 @@
"cardAttachmentsPopup-title": "Voeg bestand toe vanuit", "cardAttachmentsPopup-title": "Voeg bestand toe vanuit",
"cardCustomField-datePopup-title": "Wijzigingsdatum", "cardCustomField-datePopup-title": "Wijzigingsdatum",
"cardCustomFieldsPopup-title": "Wijzig maatwerkvelden", "cardCustomFieldsPopup-title": "Wijzig maatwerkvelden",
"cardStartVotingPopup-title": "Start a vote",
"vote-question": "Voting question",
"vote-for-it": "for it",
"vote-against": "against",
"cardDeletePopup-title": "Kaart verwijderen?", "cardDeletePopup-title": "Kaart verwijderen?",
"cardDetailsActionsPopup-title": "Kaart actie ondernemen", "cardDetailsActionsPopup-title": "Kaart actie ondernemen",
"cardLabelsPopup-title": "Labels", "cardLabelsPopup-title": "Labels",
@ -319,6 +325,7 @@
"filter-clear": "Wis filter", "filter-clear": "Wis filter",
"filter-no-label": "Geen label", "filter-no-label": "Geen label",
"filter-no-member": "Geen lid", "filter-no-member": "Geen lid",
"filter-no-assignee": "No assignee",
"filter-no-custom-fields": "Geen maatwerkvelden", "filter-no-custom-fields": "Geen maatwerkvelden",
"filter-show-archive": "Toon gearchiveerde lijsten", "filter-show-archive": "Toon gearchiveerde lijsten",
"filter-hide-empty": "Verberg lege lijsten", "filter-hide-empty": "Verberg lege lijsten",
@ -764,6 +771,7 @@
"view-all": "Bekijk alles", "view-all": "Bekijk alles",
"filter-by-unread": "Filter op Ongelezen", "filter-by-unread": "Filter op Ongelezen",
"mark-all-as-read": "Markeer alles als gelezen", "mark-all-as-read": "Markeer alles als gelezen",
"remove-all-read": "Remove all read",
"allow-rename": "Sta Hernoemen toe", "allow-rename": "Sta Hernoemen toe",
"allowRenamePopup-title": "Sta Hernoemen toe" "allowRenamePopup-title": "Sta Hernoemen toe"
} }

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -282,7 +282,10 @@ if (Meteor.isServer) {
); );
} }
Notifications.getUsers(watchers).forEach(user => { 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({ const integrations = Integrations.find({

View file

@ -334,8 +334,8 @@ Cards.attachSchema(
'vote.end': { 'vote.end': {
type: Date, type: Date,
optional: true, optional: true,
defaultValue: null defaultValue: null,
} },
}), }),
); );
@ -728,7 +728,7 @@ Cards.helpers({
parentString(sep) { parentString(sep) {
return this.parentList() return this.parentList()
.map(function (elem) { .map(function(elem) {
return elem.title; return elem.title;
}) })
.join(sep); .join(sep);
@ -1449,11 +1449,11 @@ Cards.mutations({
$set: { $set: {
vote: { vote: {
question, question,
positive:[], positive: [],
negative:[] negative: [],
}, },
} },
} };
}, },
unsetVote() { unsetVote() {
return { return {
@ -1467,32 +1467,32 @@ Cards.mutations({
case true: case true:
// vote for it // vote for it
return { return {
$pull:{ $pull: {
"vote.negative": userId 'vote.negative': userId,
}, },
$addToSet: { $addToSet: {
"vote.positive": userId 'vote.positive': userId,
} },
} };
case false: case false:
// vote against // vote against
return { return {
$pull:{ $pull: {
"vote.positive": userId 'vote.positive': userId,
}, },
$addToSet: { $addToSet: {
"vote.negative" : userId 'vote.negative': userId,
} },
} };
default: default:
// Remove votes // Remove votes
return { return {
$pull:{ $pull: {
"vote.positive": userId, 'vote.positive': userId,
"vote.negative" : userId 'vote.negative': userId,
}, },
} };
} }
}, },
}); });
@ -1897,7 +1897,7 @@ if (Meteor.isServer) {
}); });
//New activity for card moves //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 oldListId = this.previous.listId;
const oldSwimlaneId = this.previous.swimlaneId; const oldSwimlaneId = this.previous.swimlaneId;
const oldBoardId = this.previous.boardId; 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 // 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( const modifiedAt = new Date(
new Date(value).getTime() - new Date(value).getTime() -
(action === 'endAt' ? 365 * 24 * 3600 * 1e3 : 0), (action === 'endAt' ? 365 * 24 * 3600 * 1e3 : 0),
); // set it as 1 year before ); // set it as 1 year before
const boardId = list.boardId; const boardId = list.boardId;
Lists.direct.update( Lists.direct.update(
@ -1997,7 +1997,7 @@ if (Meteor.isServer) {
JsonRoutes.add( JsonRoutes.add(
'GET', 'GET',
'/api/boards/:boardId/swimlanes/:swimlaneId/cards', '/api/boards/:boardId/swimlanes/:swimlaneId/cards',
function (req, res) { function(req, res) {
const paramBoardId = req.params.boardId; const paramBoardId = req.params.boardId;
const paramSwimlaneId = req.params.swimlaneId; const paramSwimlaneId = req.params.swimlaneId;
Authentication.checkBoardAccess(req.userId, paramBoardId); Authentication.checkBoardAccess(req.userId, paramBoardId);
@ -2007,7 +2007,7 @@ if (Meteor.isServer) {
boardId: paramBoardId, boardId: paramBoardId,
swimlaneId: paramSwimlaneId, swimlaneId: paramSwimlaneId,
archived: false, archived: false,
}).map(function (doc) { }).map(function(doc) {
return { return {
_id: doc._id, _id: doc._id,
title: doc.title, title: doc.title,
@ -2031,7 +2031,7 @@ if (Meteor.isServer) {
* title: string, * title: string,
* description: string}] * description: string}]
*/ */
JsonRoutes.add('GET', '/api/boards/:boardId/lists/:listId/cards', function ( JsonRoutes.add('GET', '/api/boards/:boardId/lists/:listId/cards', function(
req, req,
res, res,
) { ) {
@ -2044,7 +2044,7 @@ if (Meteor.isServer) {
boardId: paramBoardId, boardId: paramBoardId,
listId: paramListId, listId: paramListId,
archived: false, archived: false,
}).map(function (doc) { }).map(function(doc) {
return { return {
_id: doc._id, _id: doc._id,
title: doc.title, title: doc.title,
@ -2066,7 +2066,7 @@ if (Meteor.isServer) {
JsonRoutes.add( JsonRoutes.add(
'GET', 'GET',
'/api/boards/:boardId/lists/:listId/cards/:cardId', '/api/boards/:boardId/lists/:listId/cards/:cardId',
function (req, res) { function(req, res) {
const paramBoardId = req.params.boardId; const paramBoardId = req.params.boardId;
const paramListId = req.params.listId; const paramListId = req.params.listId;
const paramCardId = req.params.cardId; 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 * @param {string} [assignees] the array of maximum one ID of assignee of the new card
* @return_type {_id: string} * @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, req,
res, res,
) { ) {
@ -2205,7 +2205,7 @@ if (Meteor.isServer) {
JsonRoutes.add( JsonRoutes.add(
'PUT', 'PUT',
'/api/boards/:boardId/lists/:listId/cards/:cardId', '/api/boards/:boardId/lists/:listId/cards/:cardId',
function (req, res) { function(req, res) {
Authentication.checkUserId(req.userId); Authentication.checkUserId(req.userId);
const paramBoardId = req.params.boardId; const paramBoardId = req.params.boardId;
const paramCardId = req.params.cardId; const paramCardId = req.params.cardId;
@ -2504,7 +2504,7 @@ if (Meteor.isServer) {
JsonRoutes.add( JsonRoutes.add(
'DELETE', 'DELETE',
'/api/boards/:boardId/lists/:listId/cards/:cardId', '/api/boards/:boardId/lists/:listId/cards/:cardId',
function (req, res) { function(req, res) {
Authentication.checkUserId(req.userId); Authentication.checkUserId(req.userId);
const paramBoardId = req.params.boardId; const paramBoardId = req.params.boardId;
const paramListId = req.params.listId; const paramListId = req.params.listId;

View file

@ -1,3 +1,5 @@
import { SyncedCron } from 'meteor/percolate:synced-cron';
// Sandstorm context is detected using the METEOR_SETTINGS environment variable // Sandstorm context is detected using the METEOR_SETTINGS environment variable
// in the package definition. // in the package definition.
const isSandstorm = const isSandstorm =
@ -926,6 +928,38 @@ 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()) {
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) { if (Meteor.isServer) {
// Let mongoDB ensure username unicity // Let mongoDB ensure username unicity
Meteor.startup(() => { Meteor.startup(() => {
@ -939,6 +973,9 @@ if (Meteor.isServer) {
}, },
{ unique: true }, { unique: true },
); );
Meteor.defer(() => {
addCronJob();
});
}); });
// OLD WAY THIS CODE DID WORK: When user is last admin of board, // OLD WAY THIS CODE DID WORK: When user is last admin of board,

2
package-lock.json generated
View file

@ -1,6 +1,6 @@
{ {
"name": "wekan", "name": "wekan",
"version": "v3.90.0", "version": "v3.92.0",
"lockfileVersion": 1, "lockfileVersion": 1,
"requires": true, "requires": true,
"dependencies": { "dependencies": {

View file

@ -1,6 +1,6 @@
{ {
"name": "wekan", "name": "wekan",
"version": "v3.90.0", "version": "v3.92.0",
"description": "Open-Source kanban", "description": "Open-Source kanban",
"private": true, "private": true,
"scripts": { "scripts": {

View file

@ -1524,7 +1524,7 @@ var n=this.pipeline.run(e.tokenizer(t)),r=new e.Vector,i=[],o=this._fields.reduc
<ul class="toc-list-h1"> <ul class="toc-list-h1">
<li> <li>
<a href="#wekan-rest-api" class="toc-h1 toc-link" data-title="Wekan REST API v3.90">Wekan REST API v3.90</a> <a href="#wekan-rest-api" class="toc-h1 toc-link" data-title="Wekan REST API v3.92">Wekan REST API v3.92</a>
</li> </li>
@ -1937,6 +1937,11 @@ var n=this.pipeline.run(e.tokenizer(t)),r=new e.Vector,i=[],o=this._fields.reduc
</li> </li>
<li>
<a href="#tocscardsvote" class="toc-h2 toc-link" data-title="CardsVote">CardsVote</a>
</li>
<li> <li>
<a href="#tocscardscustomfields" class="toc-h2 toc-link" data-title="CardsCustomfields">CardsCustomfields</a> <a href="#tocscardscustomfields" class="toc-h2 toc-link" data-title="CardsCustomfields">CardsCustomfields</a>
@ -2017,7 +2022,7 @@ var n=this.pipeline.run(e.tokenizer(t)),r=new e.Vector,i=[],o=this._fields.reduc
<div class="page-wrapper"> <div class="page-wrapper">
<div class="dark-box"></div> <div class="dark-box"></div>
<div class="content"> <div class="content">
<h1 id="wekan-rest-api">Wekan REST API v3.90</h1> <h1 id="wekan-rest-api">Wekan REST API v3.92</h1>
<blockquote> <blockquote>
<p>Scroll down for code samples, example requests and responses. Select a language for code samples from the tabs above or the mobile navigation menu.</p> <p>Scroll down for code samples, example requests and responses. Select a language for code samples from the tabs above or the mobile navigation menu.</p>
</blockquote> </blockquote>
@ -14376,7 +14381,17 @@ UserSecurity
<span class="hljs-attr">"sort"</span>: <span class="hljs-number">0</span>, <span class="hljs-attr">"sort"</span>: <span class="hljs-number">0</span>,
<span class="hljs-attr">"subtaskSort"</span>: <span class="hljs-number">0</span>, <span class="hljs-attr">"subtaskSort"</span>: <span class="hljs-number">0</span>,
<span class="hljs-attr">"type"</span>: <span class="hljs-string">"string"</span>, <span class="hljs-attr">"type"</span>: <span class="hljs-string">"string"</span>,
<span class="hljs-attr">"linkedId"</span>: <span class="hljs-string">"string"</span> <span class="hljs-attr">"linkedId"</span>: <span class="hljs-string">"string"</span>,
<span class="hljs-attr">"vote"</span>: {
<span class="hljs-attr">"question"</span>: <span class="hljs-string">"string"</span>,
<span class="hljs-attr">"positive"</span>: [
<span class="hljs-string">"string"</span>
],
<span class="hljs-attr">"negative"</span>: [
<span class="hljs-string">"string"</span>
],
<span class="hljs-attr">"end"</span>: <span class="hljs-string">"string"</span>
}
} }
</code></pre> </code></pre>
@ -14595,6 +14610,13 @@ UserSecurity
<td>none</td> <td>none</td>
<td>ID of the linked card</td> <td>ID of the linked card</td>
</tr> </tr>
<tr>
<td>vote</td>
<td><a href="#schemacardsvote">CardsVote</a></td>
<td>false</td>
<td>none</td>
<td>vote object, see below</td>
</tr>
</tbody> </tbody>
</table> </table>
<h4 id="enumerated-values">Enumerated Values</h4> <h4 id="enumerated-values">Enumerated Values</h4>
@ -14708,6 +14730,62 @@ UserSecurity
</tr> </tr>
</tbody> </tbody>
</table> </table>
<h2 id="tocscardsvote">CardsVote</h2>
<p><a id="schemacardsvote"></a></p>
<pre class="highlight tab tab-json"><code>{
<span class="hljs-attr">"question"</span>: <span class="hljs-string">"string"</span>,
<span class="hljs-attr">"positive"</span>: [
<span class="hljs-string">"string"</span>
],
<span class="hljs-attr">"negative"</span>: [
<span class="hljs-string">"string"</span>
],
<span class="hljs-attr">"end"</span>: <span class="hljs-string">"string"</span>
}
</code></pre>
<h3 id="properties">Properties</h3>
<table>
<thead>
<tr>
<th>Name</th>
<th>Type</th>
<th>Required</th>
<th>Restrictions</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td>question</td>
<td>string</td>
<td>true</td>
<td>none</td>
<td>none</td>
</tr>
<tr>
<td>positive</td>
<td>[string]</td>
<td>false</td>
<td>none</td>
<td>list of members (user IDs)</td>
</tr>
<tr>
<td>negative</td>
<td>[string]</td>
<td>false</td>
<td>none</td>
<td>list of members (user IDs)</td>
</tr>
<tr>
<td>end</td>
<td>string</td>
<td>false</td>
<td>none</td>
<td>none</td>
</tr>
</tbody>
</table>
<h2 id="tocscardscustomfields">CardsCustomfields</h2> <h2 id="tocscardscustomfields">CardsCustomfields</h2>
<p><a id="schemacardscustomfields"></a></p> <p><a id="schemacardscustomfields"></a></p>
<pre class="highlight tab tab-json"><code>{} <pre class="highlight tab tab-json"><code>{}

View file

@ -1,7 +1,7 @@
swagger: '2.0' swagger: '2.0'
info: info:
title: Wekan REST API title: Wekan REST API
version: v3.90 version: v3.92
description: | description: |
The REST API allows you to control and extend Wekan with ease. The REST API allows you to control and extend Wekan with ease.
@ -2523,6 +2523,11 @@ definitions:
ID of the linked card ID of the linked card
type: string type: string
x-nullable: true x-nullable: true
vote:
description: |
vote object, see below
$ref: "#/definitions/CardsVote"
x-nullable: true
required: required:
- archived - archived
- swimlaneId - swimlaneId
@ -2532,6 +2537,29 @@ definitions:
- userId - userId
- sort - sort
- type - type
CardsVote:
type: object
properties:
question:
type: string
positive:
description: |
list of members (user IDs)
type: array
items:
type: string
x-nullable: true
negative:
description: |
list of members (user IDs)
type: array
items:
type: string
x-nullable: true
end:
type: string
required:
- question
CardsCustomfields: CardsCustomfields:
type: object type: object
ChecklistItems: ChecklistItems:

View file

@ -22,10 +22,10 @@ const pkgdef :Spk.PackageDefinition = (
appTitle = (defaultText = "Wekan"), appTitle = (defaultText = "Wekan"),
# The name of the app as it is displayed to the user. # The name of the app as it is displayed to the user.
appVersion = 390, appVersion = 392,
# Increment this for every release. # Increment this for every release.
appMarketingVersion = (defaultText = "3.90.0~2020-04-06"), appMarketingVersion = (defaultText = "3.92.0~2020-04-09"),
# Human-readable presentation of the app version. # Human-readable presentation of the app version.
minUpgradableAppVersion = 0, minUpgradableAppVersion = 0,
@ -242,6 +242,7 @@ const myCommand :Spk.Manifest.Command = (
(key = "SCROLLINERTIA", value="0"), (key = "SCROLLINERTIA", value="0"),
(key = "SCROLLAMOUNT", value="auto"), (key = "SCROLLAMOUNT", value="auto"),
(key = "CARD_OPENED_WEBHOOK_ENABLED", value="false"), (key = "CARD_OPENED_WEBHOOK_ENABLED", value="false"),
(key = "NOTIFICATION_TRAY_AFTER_READ_DAYS_BEFORE_REMOVE", value=""),
(key = "BIGEVENTS_PATTERN", value="NONE"), (key = "BIGEVENTS_PATTERN", value="NONE"),
(key = "MATOMO_ADDRESS", value=""), (key = "MATOMO_ADDRESS", value=""),
(key = "MATOMO_SITE_ID", value=""), (key = "MATOMO_SITE_ID", value=""),

View file

@ -3,7 +3,7 @@
# All supported keys are defined here together with descriptions and default values # All supported keys are defined here together with descriptions and default values
# list of supported keys # 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 # default values
DESCRIPTION_DEBUG="Debug OIDC OAuth2 etc. Example: sudo snap set wekan debug='true'" 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="" DEFAULT_IMAGE_COMPRESS_RATIO=""
KEY_IMAGE_COMPRESS_RATIO="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" 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" DEFAULT_BIGEVENTS_PATTERN="NONE"
KEY_BIGEVENTS_PATTERN="bigevents-pattern" KEY_BIGEVENTS_PATTERN="bigevents-pattern"

View file

@ -105,6 +105,11 @@ echo -e "\t$ snap set $SNAP_NAME attachments-store-path='/var/snap/wekan/common/
echo -e "Disabled:" echo -e "Disabled:"
echo -e "\t$ snap set $SNAP_NAME attachments-store-path=''" echo -e "\t$ snap set $SNAP_NAME attachments-store-path=''"
echo -e "\n" 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 "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 "Big events pattern: Notify always due etc regardless of notification settings. Default: due, All: received|start|due|end, Disabled: NONE"
echo -e "Default:" echo -e "Default:"

View file

@ -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_LOCKOUT_PERIOD=60
REM SET ACCOUNTS_LOCKOUT_UNKNOWN_USERS_FAILURE_WINDOW=15 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 # ==== BIGEVENTS DUE ETC NOTIFICATIONS =====
REM # https://github.com/wekan/wekan/pull/2541 REM # https://github.com/wekan/wekan/pull/2541
REM # Introduced a system env var BIGEVENTS_PATTERN default as "NONE", REM # Introduced a system env var BIGEVENTS_PATTERN default as "NONE",

View file

@ -54,6 +54,11 @@
#export MAX_IMAGE_PIXEL=1024 #export MAX_IMAGE_PIXEL=1024
#export IMAGE_COMPRESS_RATIO=80 #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 ===== # ==== BIGEVENTS DUE ETC NOTIFICATIONS =====
# https://github.com/wekan/wekan/pull/2541 # https://github.com/wekan/wekan/pull/2541
# Introduced a system env var BIGEVENTS_PATTERN default as "NONE", # Introduced a system env var BIGEVENTS_PATTERN default as "NONE",

View file

@ -244,6 +244,11 @@ services:
#-MAX_IMAGE_PIXEL=1024 #-MAX_IMAGE_PIXEL=1024
#-IMAGE_COMPRESS_RATIO=80 #-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 ===== # ==== BIGEVENTS DUE ETC NOTIFICATIONS =====
# https://github.com/wekan/wekan/pull/2541 # https://github.com/wekan/wekan/pull/2541
# Introduced a system env var BIGEVENTS_PATTERN default as "NONE", # Introduced a system env var BIGEVENTS_PATTERN default as "NONE",