Compare commits

...
106 Commits
Author SHA1 Message Date
Lauri Ojansivu df54863e72 v5.07 2021-03-19 11:12:32 +02:00
Lauri Ojansivu 8f340326b0 Updated translations. 2021-03-19 11:08:36 +02:00
Lauri Ojansivu 42975bc8ab Updated ChangeLog. 2021-03-19 11:05:29 +02:00
Lauri Ojansivu adb5487cdc Merge pull request #3662 from ednamaeG/sort-fix
Fixed sort cards feature
2021-03-19 11:03:10 +02:00
mae 4aad9ca498 fix sort cards feature 2021-03-19 12:13:20 +08:00
Lauri Ojansivu 972d023e95 v5.06 2021-03-18 18:36:13 +02:00
Lauri Ojansivu acabef4652 Updated translations. 2021-03-18 18:15:52 +02:00
Lauri Ojansivu f77651ba05 Updated ChangeLog. 2021-03-18 17:42:17 +02:00
Lauri Ojansivu 23e349d277 Merge pull request #3661 from Majed6/copy_href
Fixed Bug: copy to clipboard uses pathname
2021-03-18 17:41:47 +02:00
Lauri Ojansivu 37d9a6659a Merge pull request #3648 from Majed6/relative-url-fixes
Fixed Bug: Calendar & parent cards URLs used absolute URLs
2021-03-18 17:37:55 +02:00
Majed6 8796c46810 Fixed Bug: copy to clipboard uses pathname 2021-03-18 16:48:53 +03:00
Lauri Ojansivu 4960891bd9 Updated translations. 2021-03-16 17:33:03 +02:00
Majed6 43482d9e48 Fixed Bug: Calendar & parent cards URLs used absolute URLs 2021-03-13 15:08:28 +03:00
Lauri Ojansivu ee323d97b4 v5.05 2021-03-11 00:05:25 +02:00
Lauri Ojansivu d6b447f70a Updated translations. 2021-03-10 23:59:12 +02:00
Lauri Ojansivu 203fafdf7c Updated translations. 2021-03-08 22:16:18 +02:00
Lauri Ojansivu 62e90723d1 Updated ChangeLog. 2021-03-08 22:13:50 +02:00
Lauri Ojansivu 77372ccce1 Merge pull request #3641 from chrisi51/master
change url scheme recognition for allowing abasurl to link
2021-03-08 22:10:49 +02:00
Christian Hillebrand fdb4980b68 change url scheme recognition for allowing abasurl to link
autolinking is not working for abasurl as it contains not url conform characters so you would still have to link it manually but it is not sanitized anymore.
2021-03-08 10:48:50 +01:00
Lauri Ojansivu ff4f5e6c04 v5.04 2021-03-07 18:06:27 +02:00
Lauri Ojansivu 0bb3b67075 Fixed generating API docs and Wekan Custom Fields REST API.
Thanks to xet7 !
2021-03-07 17:57:24 +02:00
Lauri Ojansivu e16b06b44a Updated ChangeLog. 2021-03-07 16:19:17 +02:00
Lauri Ojansivu ac9b23f00f OpenPower MiniCloud emergency maintenance has finished, so can now build Wekan for ppc64le.
Thanks to OpenPower Minicloud !
2021-03-07 16:16:12 +02:00
Lauri Ojansivu f562bdd801 Updated translations. 2021-03-07 16:06:22 +02:00
Lauri Ojansivu 0c05942b45 Updated ChangeLog. 2021-03-07 16:03:29 +02:00
Lauri Ojansivu 9db3c93116 Speed improvement: Delete presences older than one week, and add index to presences serverId.
Thanks to xet7 !

Related #3345
2021-03-07 15:58:15 +02:00
Lauri Ojansivu ce1f3365bb Updated translations. 2021-03-07 12:38:04 +02:00
Lauri Ojansivu 3ce3612047 Updated ChangeLog. 2021-03-05 21:15:31 +02:00
Lauri Ojansivu 44c9eebc4c Merge branch 'flawless-execution-feat/edit-custom-field' 2021-03-05 21:13:52 +02:00
Lauri Ojansivu cf6cc0e59d Merge branch 'feat/edit-custom-field' of https://github.com/flawless-execution/wekan into flawless-execution-feat/edit-custom-field 2021-03-05 21:13:41 +02:00
Lauri Ojansivu 2b1fc8d07f Updated ChangeLog. 2021-03-05 21:13:13 +02:00
Lauri Ojansivu e7d7ddd698 Merge pull request #3635 from Majed6/originRelativeUrl
Fixed Bug: inconsistent use of relative/absolute URLs
2021-03-05 21:11:42 +02:00
Lauri Ojansivu 1d6bfc5dd6 Updated ChangeLog. 2021-03-05 20:54:40 +02:00
Lauri Ojansivu 0ccdbdcbe9 Merge pull request #3633 from chrisi51/autolink-settings
Added autolinking settings in admin backend - tbc
2021-03-05 20:52:13 +02:00
Lauri Ojansivu 463346b867 Updated ChangeLog. 2021-03-05 20:37:16 +02:00
Lauri Ojansivu f293700db3 Merge pull request #3634 from jrsupplee/issue-3587
Fix search on labels server error
2021-03-05 19:40:24 +02:00
Majed6 b4e343369a Fixed Bug: inconsistent use of relative/absolute URLs
Some pages use relative links such as boards link at the home page.
 Others use absolute url such as cards in boards' lists.
 This commits goal is to allow for consistent use of relative
  urls.

Origin relative URLs also helps decoupling Wekan from the infrastructure
 it's deployed on. i.e if it's being served, it should work.
2021-03-05 15:05:53 +03:00
John R. Supplee da1d94775c Fix search on labels crashing bug 2021-03-04 18:35:02 +02:00
Christian Hillebrand 28582b7e77 correction of a typo 2021-03-04 17:04:29 +01:00
Christian Hillebrand 0f4a97f3a6 add automatic-linked-url-schemes 2021-03-04 16:45:16 +01:00
Christian Hillebrand 0f75234ed2 add automaticLinkedUrlSchemes 2021-03-04 16:42:35 +01:00
Christian Hillebrand bc2556139a add automaticLinkedUrlSchemes 2021-03-04 16:40:03 +01:00
Christian Hillebrand c1f52a5e5a add automaticLinkedUrlSchemes 2021-03-04 16:38:47 +01:00
Christian Hillebrand ab24b3262c add automaticLinkedUrlSchemes 2021-03-04 16:36:48 +01:00
chrisi51 42994efa9d Added real autolinking and simpler adding of new url schemes
to add additional URL Schemes just put your scheme to urlschemes
2021-03-04 16:30:06 +01:00
Lauri Ojansivu 44cf82caab Updated ChangeLog. 2021-03-03 18:19:32 +02:00
Lauri Ojansivu a44ca39eb8 Try to fix Snap: Removed fibers multi arch from Snap, because Snap build servers do not build corretly with it.
Thanks to xet7.
2021-03-03 18:16:29 +02:00
Lauri Ojansivu 3f70c395e1 v5.03 2021-03-03 16:56:02 +02:00
Lauri Ojansivu 04383c0302 Removed temporary file. 2021-03-03 16:52:15 +02:00
Lauri Ojansivu 55d022eefc Updated ChangeLog. 2021-03-03 16:44:13 +02:00
Lauri Ojansivu 7d3917adb7 Fixed Bug: Link at board title can not be edited.
Thanks to jonesrussell42, aiac, bbyszio and xet7 !

Fixes #3622
2021-03-03 16:39:34 +02:00
Lauri Ojansivu 7eeeab8486 Updated translations. 2021-03-03 15:34:37 +02:00
Lauri Ojansivu 88a46ef59a Updated ChangeLog. 2021-03-03 15:26:20 +02:00
Lauri Ojansivu e4a9dc25ec Revert Removed extra imports of Meteor. Hopefully fixes email notifications
and rules on old cars not working.

Thanks to xet7 !
2021-03-03 15:23:43 +02:00
Lauri Ojansivu dfb563a330 Add link to issue template about email settings. 2021-03-03 15:18:04 +02:00
Lauri Ojansivu 16dbb88ee3 Updated ChangeLog. 2021-03-02 18:50:18 +02:00
Lauri Ojansivu 626f435edf Hide email settings from Sandstorm Wekan Admin Panel.
Thanks to ocdtrekkie and xet7 !

Related https://github.com/wekan/wekan/commit/65b8220fe53349695a335bdb8b9692f82d4b3329
2021-03-02 18:45:02 +02:00
Lauri Ojansivu d4dd5d7a61 v5.02 2021-03-02 16:40:50 +02:00
Lauri Ojansivu de13b8b9ba Removed extra imports of Meteor.
Thanks to xet7 !
2021-03-02 16:25:27 +02:00
Lauri Ojansivu 0aabb0b364 Fix lint. 2021-03-02 16:08:29 +02:00
Lauri Ojansivu 3605072650 Updated translations. 2021-03-02 16:04:25 +02:00
Lauri Ojansivu 6272aabefb Updated ChangeLog. 2021-03-02 15:56:28 +02:00
Lauri Ojansivu bf2446614c Merge pull request #3620 from n8ores/master
Add attachmentId to the Webhook data
2021-03-02 15:50:53 +02:00
Lauri Ojansivu 65b8220fe5 Fix SMTP port lost after upgrade. STMP settings are made only with environment variables on non-Sandstorm platforms.
Note: Sending email on Sandstorm Wekan does not work yet.

Thanks to jrsupplee and xet7 !

Fixes #3529,
Fixes #3016,
Fixes #2375,
Fixes #2598,
Fixes wekan/wekan-snap#78
2021-03-02 15:33:59 +02:00
n8ores d296918fcd Revert "Add startup script etc"
This reverts commit 3453690fc2.
2021-03-01 18:19:09 +13:00
n8ores c9a2d439e5 Merge remote-tracking branch 'upstream/master' 2021-03-01 18:13:41 +13:00
n8ores 73f36bcf33 Add AttachmentId to webhook data 2021-03-01 18:12:09 +13:00
Lauri Ojansivu 8f5089fd46 Updated translations. 2021-03-01 00:02:34 +02:00
n8ores ae8b17e0fb Merge remote-tracking branch 'upstream/master' 2021-03-01 10:57:07 +13:00
n8ores 3453690fc2 Add startup script etc 2021-03-01 10:56:51 +13:00
Lauri Ojansivu bc1f607c8e Updated ChangeLog. 2021-02-28 19:20:55 +02:00
Lauri Ojansivu e0382139b6 Merge pull request #3618 from ChrisMagnuson/master
Add sort to rest API
2021-02-28 19:13:26 +02:00
Chris Magnuson 65d280da8a Add sort to rest API 2021-02-27 16:24:12 -05:00
Lauri Ojansivu e618070068 Updated translations. 2021-02-27 18:51:34 +02:00
Lauri Ojansivu 8181074238 Merge pull request #3617 from jrsupplee/search
Global Search enhancements and fixes
2021-02-27 17:24:35 +02:00
John R. Supplee b0e4aedd3d Update search instructions 2021-02-27 17:02:42 +02:00
John R. Supplee faa101224a Add new has predicates for more fields 2021-02-27 02:26:58 +02:00
John R. Supplee eb7fc0fb26 Comment out debugging code 2021-02-27 00:56:12 +02:00
John Supplee a63a61e7fc Fix problem with dates in selector being unpickled as a String 2021-02-26 23:19:12 +02:00
John Supplee 223cc07139 Add instructions for limit operator 2021-02-26 18:51:54 +02:00
John Supplee 62b0d371ee Add new limit operator 2021-02-26 17:31:44 +02:00
Lauri Ojansivu 884b678bd0 Updated ChangeLog. 2021-02-26 15:01:18 +02:00
John Supplee 2930e9cadb Merge branch 'master' of https://github.com/wekan/wekan into search 2021-02-26 14:49:53 +02:00
Lauri Ojansivu 6103265488 v5.01 2021-02-26 14:24:19 +02:00
Lauri Ojansivu c1f5dfc02e Updated translations. 2021-02-26 14:19:20 +02:00
John Supplee 8e911a42f5 Fixes to due predicates 2021-02-26 14:11:24 +02:00
Lauri Ojansivu f41c1153d2 Updated ChangeLog. 2021-02-26 13:29:13 +02:00
Lauri Ojansivu ff03171f55 Merge pull request #3610 from n8ores/customFieldsFix
Fix syntax typo
2021-02-26 13:26:49 +02:00
John Supplee 5fe58dc9ae Add instructions for sort operator 2021-02-26 13:11:54 +02:00
John Supplee 0c1cff52b2 Update explanation of days predicate 2021-02-26 12:52:36 +02:00
n8ores 8e29a52d71 Correct typo 2021-02-26 20:44:03 +13:00
n8ores 12a0e73587 Fix syntax typo 2021-02-26 20:01:09 +13:00
John Supplee a3229ea965 Fixes for duration predicates 2021-02-26 01:13:45 +02:00
John R. Supplee 43f40c4085 Fix sort operator
* Add server publications for next and previous page
* Add ability to sort ascending or descending
2021-02-25 18:38:51 +02:00
Lauri Ojansivu 250e79f53c v5.00 2021-02-25 15:14:48 +02:00
Lauri Ojansivu c8b2c19010 Updated translations. 2021-02-25 15:12:47 +02:00
Lauri Ojansivu fe1add57f1 Updated ChangeLog. 2021-02-25 15:03:16 +02:00
Lauri Ojansivu 332f830cc2 Fixed Unable to remove old Board, reappears.
Thanks to chirrut2, uusijani, cimm, anicolaides, Philipoo0 and xet7.

Fixes #2613
2021-02-25 15:00:49 +02:00
Lauri Ojansivu ccd69dfcf7 Updated translations. 2021-02-25 12:09:31 +02:00
Louis Orleans 9cbef4ba4b 🔒 fix warning from deepcode 2021-02-20 14:11:17 -08:00
Louis Orleans 24035329b8 ✨ edit custom field dropdown item 2021-02-20 13:50:24 -08:00
Louis Orleans 457977f954 ✨ add and remove dropdown items 2021-02-20 12:46:29 -08:00
Louis Orleans 373dc5cadb ⏪ Revert "🎨 format with Prettier"
This reverts commit a35cfe660e.
2021-02-20 09:27:33 -08:00
Louis Orleans a35cfe660e 🎨 format with Prettier 2021-02-20 09:02:36 -08:00
Louis Orleans db666eec65 🐛 fix updating fields 2021-02-20 09:02:12 -08:00
Louis Orleans 586473aaa7 ✨ add custom field edit REST API 2021-02-19 11:21:13 -08:00
104 changed files with 69661 additions and 78925 deletions

No files matched your search

+3
View File
@@ -1,5 +1,8 @@
## Issue
Email settings:
- https://github.com/wekan/wekan/wiki/Troubleshooting-Mail
Add these issues to elsewhere:
- SECURITY ISSUES: https://github.com/wekan/wekan/blob/master/SECURITY.md
- UCS: https://github.com/wekan/univention/issues
+119
View File
@@ -1,3 +1,122 @@
# v5.07 2021-03-19 Wekan release
This release fixes the following bugs:
- [Fixed sort cards feature](https://github.com/wekan/wekan/pull/3662).
Thanks to ednamaeG.
Thanks to above GitHub users for their contributions and translators for their translations.
# v5.06 2021-03-18 Wekan release
This release fixes the following bugs:
- [Fixed Bug: Calendar & parent cards URLs used absolute URLs](https://github.com/wekan/wekan/pull/3648).
Thanks to Majed6.
- [Fixed Bug: copy to clipboard uses pathname](https://github.com/wekan/wekan/pull/3661).
Thanks to Majed6.
Thanks to above GitHub users for their contributions and translators for their translations.
# v5.05 2021-03-11 Wekan release
This release fixes the following bugs:
- [Change URL scheme recognition for allowing abasurl to link](https://github.com/wekan/wekan/pull/3641).
Thanks to tod31 and chrisi51.
Thanks to above GitHub users for their contributions and translators for their translations.
# v5.04 2021-03-07 Wekan release
This release adds the following speed improvements:
- [Speed improvement: Delete presences older than one week, and add database index to presences
serverId](https://github.com/wekan/wekan/commit/9db3c931161adfbeb6fc52d3e4cf621fb9a4955f).
Thanks to xet7.
and adds the following new features:
- [Added autolinking settings in Admin Panel](https://github.com/wekan/wekan/pull/3633).
Thanks to chrisi51.
- [Add custom field editing to the REST API](https://github.com/wekan/wekan/pull/3593).
Thanks to dudeofawesome.
- [Related to custom field editing, Fixed generating API docs and Wekan Custom Fields
REST API](https://github.com/wekan/wekan/commit/0bb3b670753c6ba20b0ad63f63d273036f609ee5).
Thanks to xet7.
and adds back the following platforms:
- [OpenPower Minicloud emergency maintenance has finished, so can now build Wekan for
ppc64le](https://github.com/wekan/wekan/commit/ac9b23f00f10b0170b8693e1e997bfb54f807adc).
Thanks to OpenPower Minicloud.
and fixes the following bugs:
- [Try to fix Snap: Removed fibers multi arch from Snap, because Snap build servers do not build correctly with
it](https://github.com/wekan/wekan/commit/a44ca39eb84508441f0f8bdac852745f417f12e7).
Thanks to xet7.
- [Fix search on labels server error](https://github.com/wekan/wekan/pull/3634).
Thanks to jrsupplee.
- [Fixed Bug: inconsistent use of relative/absolute URLs](https://github.com/wekan/wekan/pull/3635).
Thanks to Majed6.
Thanks to above GitHub users for their contributions and translators for their translations.
# v5.03 2021-03-03 Wekan release
This release adds the following changes:
- [Hide email settings from Sandstorm Wekan Admin Panel](https://github.com/wekan/wekan/commit/626f435edf75fac68448ba2e14c62acb749f9c9b).
Thanks to ocdtrekkie and xet7.
and fixes the following bugs:
- [Revert Removed extra imports of Meteor. Hopefully fixes email notifications and rules
on old cars not working](https://github.com/wekan/wekan/commit/e4a9dc25ecc230829afea07dbb3915b96115f7f7).
Thanks to xet7.
- [Fixed Bug: Link at board title can not be edited](https://github.com/wekan/wekan/commit/7d3917adb79be09356d32612585029392bac1e49).
Thanks to jonesrussell42, aiac, bbyszio and xet7.
Thanks to above GitHub and Wekan vanila.io community users for their contributions and translators for their translations.
# v5.02 2021-03-02 Wekan release
This release adds the following improvements:
- [Added sort to edit card REST API](https://github.com/wekan/wekan/pull/3618).
Thanks to ChrisMagnuson.
- [Add attachmentId to the Webhook data](https://github.com/wekan/wekan/pull/3620).
Thanks to n8ores.
and fixes the following bugs:
- [Fix SMTP port lost after upgrade. STMP settings are made only with environment variables on non-Sandstorm platforms.
Note: Sending email on Sandstorm Wekan does not work yet](https://github.com/wekan/wekan/commit/65b8220fe53349695a335bdb8b9692f82d4b3329).
Thanks to jrsupplee and xet7.
- [Removed extra imports of Meteor](https://github.com/wekan/wekan/commit/de13b8b9bafbfb186a037ae20e845846b296ac69).
Thanks to xet7.
Thanks to above GitHub users for their contributions and translators for their translations.
# v5.01 2021-02-26 Wekan release
This release fixes the following bugs:
- [Fix typo in activities code. Fixes can not edit Custom Field](https://github.com/wekan/wekan/pull/3610).
Thanks to n8ores.
Thanks to above GitHub users for their contributions and translators for their translations.
# v5.00 2021-02-25 Wekan release
This release fixes the following bugs:
- [Fixed Unable to remove old Board, reappears](https://github.com/wekan/wekan/commit/332f830cc2e44ab66ca891690b09a425b9fd7e68).
Thanks to chirrut2, uusijani, cimm, anicolaides, Philipoo0 and xet7.
Thanks to above GitHub users for their contributions and translators for their translations.
# v4.99 2021-02-25 Wekan release
This release fixes the following CRITICAL SECURITY ISSUES:
+1 -1
View File
@@ -1,5 +1,5 @@
appId: wekan-public/apps/77b94f60-dec9-0136-304e-16ff53095928
appVersion: "v4.99.0"
appVersion: "v5.07.0"
files:
userUploads:
- README.md
+3 -3
View File
@@ -82,7 +82,7 @@ template(name="activity")
+viewer
= activity.checklist.title
else
a.activity-checklist(href="{{ activity.card.absoluteUrl }}")
a.activity-checklist(href="{{ activity.card.originRelativeUrl }}")
+viewer
= activity.checklist.title
@@ -103,7 +103,7 @@ template(name="activity")
if($eq activity.activityType 'addChecklistItem')
| {{{_ 'activity-checklist-item-added' (sanitize activity.checklist.title) cardLink}}}.
.activity-checklist(href="{{ activity.card.absoluteUrl }}")
.activity-checklist(href="{{ activity.card.originRelativeUrl }}")
+viewer
= activity.checklistItem.title
@@ -139,7 +139,7 @@ template(name="activity")
//- if we are not in card mode we only display a summary of the comment
if($eq activity.activityType 'addComment')
| {{{_ 'activity-on' cardLink}}}
a.activity-comment(href="{{ activity.card.absoluteUrl }}")
a.activity-comment(href="{{ activity.card.originRelativeUrl }}")
+viewer
= activity.comment.text
+2 -2
View File
@@ -243,7 +243,7 @@ function createCardLink(card) {
Blaze.toHTML(
HTML.A(
{
href: card.absoluteUrl(),
href: card.originRelativeUrl(),
class: 'action-card',
},
sanitizeXss(card.title),
@@ -260,7 +260,7 @@ function createBoardLink(board, list) {
Blaze.toHTML(
HTML.A(
{
href: board.absoluteUrl(),
href: board.originRelativeUrl(),
class: 'action-board',
},
sanitizeXss(text),
+1 -1
View File
@@ -360,7 +360,7 @@ BlazeComponent.extendComponent({
end: end || card.endAt,
allDay:
Math.abs(end.getTime() - start.getTime()) / 1000 === 24 * 3600,
url: FlowRouter.url('card', {
url: FlowRouter.path('card', {
boardId: currentBoard._id,
slug: currentBoard.slug,
cardId: card._id,
+15 -5
View File
@@ -1,14 +1,17 @@
template(name="boardHeaderBar")
h1.header-board-menu
with currentBoard
a(class="{{#if currentUser.isBoardAdmin}}js-edit-board-title{{else}}is-disabled{{/if}}")
+viewer
= title
+viewer
= title
.board-header-btns.left
unless isMiniScreen
if currentBoard
if currentUser
with currentBoard
a.board-header-btn(class="{{#if currentUser.isBoardAdmin}}js-edit-board-title{{else}}is-disabled{{/if}}" title="{{_ 'edit'}}" value=title)
i.fa.fa-pencil-square-o
a.board-header-btn.js-star-board(class="{{#if isStarred}}is-active{{/if}}"
title="{{#if isStarred}}{{_ 'click-to-unstar'}}{{else}}{{_ 'click-to-star'}}{{/if}} {{_ 'starred-boards-description'}}")
i.fa(class="fa-star{{#unless isStarred}}-o{{/unless}}")
@@ -31,9 +34,12 @@ template(name="boardHeaderBar")
if $eq watchLevel "muted"
i.fa.fa-bell-slash
span {{_ watchLevel}}
a.board-header-btn.js-sort-cards(title="{{_ 'sort-cards'}}")
a.board-header-btn(title="{{_ 'sort-cards'}}" class="{{#if isSortActive }}emphasis{{else}} js-sort-cards {{/if}}")
i.fa.fa-sort
| {{_ 'sort-cards'}} {{sortCardsBy.get}}
span {{#if isSortActive }}{{_ 'Sort is on'}}{{else}}{{_ 'sort-cards'}}{{/if}}
if isSortActive
a.board-header-btn-close.js-sort-reset(title="Remove Sort")
i.fa.fa-times-thin
else
a.board-header-btn.js-log-in(
@@ -45,6 +51,10 @@ template(name="boardHeaderBar")
if currentBoard
if isMiniScreen
if currentUser
with currentBoard
a.board-header-btn(class="{{#if currentUser.isBoardAdmin}}js-edit-board-title{{else}}is-disabled{{/if}}" title="{{_ 'edit'}}" value=title)
i.fa.fa-pencil-square-o
a.board-header-btn.js-star-board(class="{{#if isStarred}}is-active{{/if}}"
title="{{#if isStarred}}{{_ 'click-to-unstar'}}{{else}}{{_ 'click-to-star'}}{{/if}} {{_ 'starred-boards-description'}}")
i.fa(class="fa-star{{#unless isStarred}}-o{{/unless}}")
+11 -9
View File
@@ -54,6 +54,10 @@ Template.boardChangeTitlePopup.events({
});
BlazeComponent.extendComponent({
onCreated(){
// set sort to default
Session.set('sortBy','')
},
watchLevel() {
const currentBoard = Boards.findOne(Session.get('currentBoard'));
return currentBoard && currentBoard.getWatchLevel(Meteor.userId());
@@ -129,6 +133,9 @@ BlazeComponent.extendComponent({
Sidebar.setView();
Filter.reset();
},
'click .js-sort-reset'() {
Session.set('sortBy','')
},
'click .js-open-search-view'() {
Sidebar.setView('search');
},
@@ -162,6 +169,9 @@ Template.boardHeaderBar.helpers({
boardView() {
return Utils.boardView();
},
isSortActive(){
return Session.get('sortBy') ? true : false;
}
});
Template.boardChangeViewPopup.events({
@@ -406,15 +416,7 @@ BlazeComponent.extendComponent({
Session.set('sortBy', sortBy);
sortCardsBy.set(TAPi18n.__('date-created-oldest-first'));
Popup.close();
},
'click .js-sort-default'() {
const sortBy = {
sort: 1,
};
Session.set('sortBy', sortBy);
sortCardsBy.set(TAPi18n.__('default'));
Popup.close();
},
}
},
];
},
+2 -3
View File
@@ -8,11 +8,10 @@ template(name="cardDetails")
a.fa.fa-times-thin.close-card-details.js-close-card-details
if currentUser.isBoardMember
a.fa.fa-navicon.card-details-menu.js-open-card-details-menu
input.inline-input(type="text" id="cardURL_copy" value="{{ absoluteUrl }}")
input.inline-input(type="text" id="cardURL_copy" value="{{ originRelativeUrl }}")
a.fa.fa-link.card-copy-button.js-copy-link(
class="fa-link"
title="{{_ 'copy-card-link-to-clipboard'}}"
value="{{ absoluteUrl }}"
)
if isMiniScreen
a.fa.fa-times-thin.close-card-details-mobile-web.js-close-card-details
@@ -533,7 +532,7 @@ template(name="cardMorePopup")
span {{_ 'link-card'}}
= ' '
i.fa.colorful(class="{{#if board.isPublic}}fa-globe{{else}}fa-lock{{/if}}")
input.inline-input(type="text" id="cardURL" readonly value="{{ absoluteUrl }}" autofocus="autofocus")
input.inline-input(type="text" id="cardURL" readonly value="{{ originRelativeUrl }}" autofocus="autofocus")
button.js-copy-card-link-to-clipboard(class="btn" id="clipboard") {{_ 'copy-card-link-to-clipboard'}}
span.clearfix
br
+3 -1
View File
@@ -114,7 +114,7 @@ BlazeComponent.extendComponent({
if (card) {
const board = Boards.findOne(card.boardId);
if (board) {
result = FlowRouter.url('card', {
result = FlowRouter.path('card', {
boardId: card.boardId,
slug: board.slug,
cardId: card._id,
@@ -291,6 +291,8 @@ BlazeComponent.extendComponent({
},
'click .js-copy-link'() {
StringToCopyElement = document.getElementById('cardURL_copy');
StringToCopyElement.value =
window.location.origin + window.location.pathname;
StringToCopyElement.select();
if (document.execCommand('copy')) {
StringToCopyElement.blur();
+1 -1
View File
@@ -1,6 +1,6 @@
template(name="resultCard")
.result-card-wrapper
a.minicard-wrapper.card-title(href=absoluteUrl)
a.minicard-wrapper.card-title(href=originRelativeUrl)
+minicard(this)
//= card.title
ul.result-card-context-list
+1 -1
View File
@@ -5,7 +5,7 @@ template(name="listBody")
+inlinedForm(autoclose=false position="top")
+addCardForm(listId=_id position="top")
each (cardsWithLimit (idOrNull ../../_id))
a.minicard-wrapper.js-minicard(href=absoluteUrl
a.minicard-wrapper.js-minicard(href=originRelativeUrl
class="{{#if cardIsSelected}}is-selected{{/if}}"
class="{{#if MultiSelection.isSelected _id}}is-checked{{/if}}")
if MultiSelection.isActive
+25 -23
View File
@@ -13,7 +13,7 @@ template(name="globalSearchModalTitle")
template(name="globalSearch")
if currentUser
.wrapper
form.global-search-instructions.js-search-query-form
form.global-search-page.js-search-query-form
input.global-search-query-input(
id="global-search-input"
type="text"
@@ -48,29 +48,31 @@ template(name="globalSearch")
button.js-next-page
| {{_ 'next-page' }}
else
.global-search-instructions
h2 {{_ 'boards' }}
.lists-wrapper
each title in myBoardNames.get
span.card-label.list-title.js-board-title
= title
h2 {{_ 'lists' }}
.lists-wrapper
each title in myLists.get
span.card-label.list-title.js-list-title
= title
h2 {{_ 'label-colors' }}
.palette-colors: each label in labelColors
span.card-label.palette-color.js-label-color(class="card-label-{{label.color}}")
= label.name
if myLabelNames.get.length
h2 {{_ 'label-names' }}
.global-search-page
.global-search-help
h2 {{_ 'boards' }}
.lists-wrapper
each name in myLabelNames.get
span.card-label.list-title.js-label-name
= name
+viewer
= searchInstructions
each title in myBoardNames.get
span.card-label.list-title.js-board-title
= title
h2 {{_ 'lists' }}
.lists-wrapper
each title in myLists.get
span.card-label.list-title.js-list-title
= title
h2 {{_ 'label-colors' }}
.palette-colors: each label in labelColors
span.card-label.palette-color.js-label-color(class="card-label-{{label.color}}")
= label.name
if myLabelNames.get.length
h2 {{_ 'label-names' }}
.lists-wrapper
each name in myLabelNames.get
span.card-label.list-title.js-label-name
= name
.global-search-instructions
+viewer
= searchInstructions
template(name="globalSearchViewChangePopup")
if currentUser
+171 -120
View File
@@ -116,7 +116,9 @@ BlazeComponent.extendComponent({
// eslint-disable-next-line no-console
// console.log('selector:', sessionData.getSelector());
// console.log('session data:', sessionData);
const cards = Cards.find({ _id: { $in: sessionData.cards } });
const projection = sessionData.getProjection();
projection.skip = 0;
const cards = Cards.find({ _id: { $in: sessionData.cards } }, projection);
this.queryErrors = sessionData.errors;
if (this.queryErrors.length) {
this.hasQueryErrors.set(true);
@@ -201,6 +203,7 @@ BlazeComponent.extendComponent({
'^(?<quote>["\'])(?<text>.*?)\\k<quote>(\\s+|$)',
'u',
);
const reNegatedOperator = new RegExp('^-(?<operator>.*)$');
const operators = {
'operator-board': 'boards',
@@ -223,6 +226,8 @@ BlazeComponent.extendComponent({
'operator-modified': 'modifiedAt',
'operator-comment': 'comments',
'operator-has': 'has',
'operator-sort': 'sort',
'operator-limit': 'limit',
};
const predicates = {
@@ -238,6 +243,7 @@ BlazeComponent.extendComponent({
status: {
'predicate-archived': 'archived',
'predicate-all': 'all',
'predicate-open': 'open',
'predicate-ended': 'ended',
'predicate-public': 'public',
'predicate-private': 'private',
@@ -251,6 +257,11 @@ BlazeComponent.extendComponent({
'predicate-description': 'description',
'predicate-checklist': 'checklist',
'predicate-attachment': 'attachment',
'predicate-start': 'startAt',
'predicate-end': 'endAt',
'predicate-due': 'dueAt',
'predicate-assignee': 'assignees',
'predicate-member': 'members',
},
};
const predicateTranslations = {};
@@ -307,25 +318,65 @@ BlazeComponent.extendComponent({
}
// eslint-disable-next-line no-prototype-builtins
if (operatorMap.hasOwnProperty(op)) {
const operator = operatorMap[op];
let value = m.groups.value;
if (operatorMap[op] === 'labels') {
if (operator === 'labels') {
if (value in this.colorMap) {
value = this.colorMap[value];
// console.log('found color:', value);
}
} else if (
['dueAt', 'createdAt', 'modifiedAt'].includes(operatorMap[op])
) {
} else if (['dueAt', 'createdAt', 'modifiedAt'].includes(operator)) {
let days = parseInt(value, 10);
let duration = null;
if (isNaN(days)) {
// duration was specified as text
if (predicateTranslations.durations[value]) {
duration = predicateTranslations.durations[value];
value = moment();
} else if (predicateTranslations.due[value] === 'overdue') {
value = moment();
duration = 'days';
days = 0;
let date = null;
switch (duration) {
case 'week':
let week = moment().week();
if (week === 52) {
date = moment(1, 'W');
date.set('year', date.year() + 1);
} else {
date = moment(week + 1, 'W');
}
break;
case 'month':
let month = moment().month();
// .month() is zero indexed
if (month === 11) {
date = moment(1, 'M');
date.set('year', date.year() + 1);
} else {
date = moment(month + 2, 'M');
}
break;
case 'quarter':
let quarter = moment().quarter();
if (quarter === 4) {
date = moment(1, 'Q');
date.set('year', date.year() + 1);
} else {
date = moment(quarter + 1, 'Q');
}
break;
case 'year':
date = moment(moment().year() + 1, 'YYYY');
break;
}
if (date) {
value = {
operator: '$lt',
value: date.format('YYYY-MM-DD'),
};
}
} else if (operator === 'dueAt' && value === 'overdue') {
value = {
operator: '$lt',
value: moment().format('YYYY-MM-DD'),
};
} else {
this.parsingErrors.push({
tag: 'operator-number-expected',
@@ -334,27 +385,41 @@ BlazeComponent.extendComponent({
value = null;
}
} else {
value = moment();
}
if (value) {
if (operatorMap[op] === 'dueAt') {
value = value.add(days, duration ? duration : 'days').format();
if (operator === 'dueAt') {
value = {
operator: '$lt',
value: moment(moment().format('YYYY-MM-DD'))
.add(days + 1, duration ? duration : 'days')
.format(),
};
} else {
value = value
.subtract(days, duration ? duration : 'days')
.format();
value = {
operator: '$gte',
value: moment(moment().format('YYYY-MM-DD'))
.subtract(days, duration ? duration : 'days')
.format(),
};
}
}
} else if (operatorMap[op] === 'sort') {
} else if (operator === 'sort') {
let negated = false;
const m = value.match(reNegatedOperator);
if (m) {
value = m.groups.operator;
negated = true;
}
if (!predicateTranslations.sorts[value]) {
this.parsingErrors.push({
tag: 'operator-sort-invalid',
value,
});
} else {
value = predicateTranslations.sorts[value];
value = {
name: predicateTranslations.sorts[value],
order: negated ? 'des' : 'asc',
};
}
} else if (operatorMap[op] === 'status') {
} else if (operator === 'status') {
if (!predicateTranslations.status[value]) {
this.parsingErrors.push({
tag: 'operator-status-invalid',
@@ -363,20 +428,39 @@ BlazeComponent.extendComponent({
} else {
value = predicateTranslations.status[value];
}
} else if (operatorMap[op] === 'has') {
} else if (operator === 'has') {
let negated = false;
const m = value.match(reNegatedOperator);
if (m) {
value = m.groups.operator;
negated = true;
}
if (!predicateTranslations.has[value]) {
this.parsingErrors.push({
tag: 'operator-has-invalid',
value,
});
} else {
value = predicateTranslations.has[value];
value = {
field: predicateTranslations.has[value],
exists: !negated,
};
}
} else if (operator === 'limit') {
const limit = parseInt(value, 10);
if (isNaN(limit) || limit < 1) {
this.parsingErrors.push({
tag: 'operator-limit-invalid',
value,
});
} else {
value = limit;
}
}
if (Array.isArray(params[operatorMap[op]])) {
params[operatorMap[op]].push(value);
if (Array.isArray(params[operator])) {
params[operator].push(value);
} else {
params[operatorMap[op]] = value;
params[operator] = value;
}
} else {
this.parsingErrors.push({
@@ -437,20 +521,10 @@ BlazeComponent.extendComponent({
},
nextPage() {
sessionData = this.getSessionData();
const params = {
limit: this.resultsPerPage,
selector: sessionData.getSelector(),
skip: sessionData.lastHit,
};
const sessionData = this.getSessionData();
this.autorun(() => {
const handle = Meteor.subscribe(
'globalSearch',
SessionData.getSessionId(),
params,
);
const handle = Meteor.subscribe('nextPage', sessionData.sessionId);
Tracker.nonreactive(() => {
Tracker.autorun(() => {
if (handle.ready()) {
@@ -464,21 +538,10 @@ BlazeComponent.extendComponent({
},
previousPage() {
sessionData = this.getSessionData();
const params = {
limit: this.resultsPerPage,
selector: sessionData.getSelector(),
skip:
sessionData.lastHit - sessionData.resultsCount - this.resultsPerPage,
};
const sessionData = this.getSessionData();
this.autorun(() => {
const handle = Meteor.subscribe(
'globalSearch',
SessionData.getSessionId(),
params,
);
const handle = Meteor.subscribe('previousPage', sessionData.sessionId);
Tracker.nonreactive(() => {
Tracker.autorun(() => {
if (handle.ready()) {
@@ -531,6 +594,8 @@ BlazeComponent.extendComponent({
operator_modified: TAPi18n.__('operator-modified'),
operator_status: TAPi18n.__('operator-status'),
operator_has: TAPi18n.__('operator-has'),
operator_sort: TAPi18n.__('operator-sort'),
operator_limit: TAPi18n.__('operator-limit'),
predicate_overdue: TAPi18n.__('predicate-overdue'),
predicate_archived: TAPi18n.__('predicate-archived'),
predicate_all: TAPi18n.__('predicate-all'),
@@ -544,81 +609,67 @@ BlazeComponent.extendComponent({
predicate_checklist: TAPi18n.__('predicate-checklist'),
predicate_public: TAPi18n.__('predicate-public'),
predicate_private: TAPi18n.__('predicate-private'),
predicate_due: TAPi18n.__('predicate-due'),
predicate_created: TAPi18n.__('predicate-created'),
predicate_modified: TAPi18n.__('predicate-modified'),
predicate_start: TAPi18n.__('predicate-start'),
predicate_end: TAPi18n.__('predicate-end'),
predicate_assignee: TAPi18n.__('predicate-assignee'),
predicate_member: TAPi18n.__('predicate-member'),
};
text = `# ${TAPi18n.__('globalSearch-instructions-heading')}`;
let text = `# ${TAPi18n.__('globalSearch-instructions-heading')}`;
text += `\n${TAPi18n.__('globalSearch-instructions-description', tags)}`;
text += `\n${TAPi18n.__('globalSearch-instructions-operators', tags)}`;
text += `\n* ${TAPi18n.__(
'globalSearch-instructions-operator-board',
tags,
)}`;
text += `\n* ${TAPi18n.__(
'globalSearch-instructions-operator-list',
tags,
)}`;
text += `\n* ${TAPi18n.__(
'globalSearch-instructions-operator-swimlane',
tags,
)}`;
text += `\n* ${TAPi18n.__(
'globalSearch-instructions-operator-comment',
tags,
)}`;
text += `\n* ${TAPi18n.__(
'globalSearch-instructions-operator-label',
tags,
)}`;
text += `\n* ${TAPi18n.__(
'globalSearch-instructions-operator-hash',
tags,
)}`;
text += `\n* ${TAPi18n.__(
'globalSearch-instructions-operator-user',
tags,
)}`;
text += `\n* ${TAPi18n.__('globalSearch-instructions-operator-at', tags)}`;
text += `\n* ${TAPi18n.__(
'globalSearch-instructions-operator-member',
tags,
)}`;
text += `\n* ${TAPi18n.__(
'globalSearch-instructions-operator-assignee',
tags,
)}`;
text += `\n* ${TAPi18n.__('globalSearch-instructions-operator-due', tags)}`;
text += `\n* ${TAPi18n.__(
'globalSearch-instructions-operator-created',
tags,
)}`;
text += `\n* ${TAPi18n.__(
'globalSearch-instructions-operator-modified',
tags,
)}`;
text += `\n* ${TAPi18n.__(
'globalSearch-instructions-status-archived',
tags,
)}`;
text += `\n* ${TAPi18n.__(
'globalSearch-instructions-status-public',
tags,
)}`;
text += `\n* ${TAPi18n.__(
'globalSearch-instructions-status-private',
tags,
)}`;
text += `\n* ${TAPi18n.__('globalSearch-instructions-status-all', tags)}`;
text += `\n* ${TAPi18n.__('globalSearch-instructions-status-ended', tags)}`;
text += `\n\n${TAPi18n.__('globalSearch-instructions-operators', tags)}`;
text += `\n* ${TAPi18n.__('globalSearch-instructions-operator-has', tags)}`;
[
'globalSearch-instructions-operator-board',
'globalSearch-instructions-operator-list',
'globalSearch-instructions-operator-swimlane',
'globalSearch-instructions-operator-comment',
'globalSearch-instructions-operator-label',
'globalSearch-instructions-operator-hash',
'globalSearch-instructions-operator-user',
'globalSearch-instructions-operator-at',
'globalSearch-instructions-operator-member',
'globalSearch-instructions-operator-assignee',
'globalSearch-instructions-operator-due',
'globalSearch-instructions-operator-created',
'globalSearch-instructions-operator-modified',
'globalSearch-instructions-operator-status',
].forEach(instruction => {
text += `\n* ${TAPi18n.__(instruction, tags)}`;
});
[
'globalSearch-instructions-status-archived',
'globalSearch-instructions-status-public',
'globalSearch-instructions-status-private',
'globalSearch-instructions-status-all',
'globalSearch-instructions-status-ended',
].forEach(instruction => {
text += `\n * ${TAPi18n.__(instruction, tags)}`;
});
[
'globalSearch-instructions-operator-has',
'globalSearch-instructions-operator-sort',
'globalSearch-instructions-operator-limit',
].forEach(instruction => {
text += `\n* ${TAPi18n.__(instruction, tags)}`;
});
text += `\n## ${TAPi18n.__('heading-notes')}`;
text += `\n* ${TAPi18n.__('globalSearch-instructions-notes-1', tags)}`;
text += `\n* ${TAPi18n.__('globalSearch-instructions-notes-2', tags)}`;
text += `\n* ${TAPi18n.__('globalSearch-instructions-notes-3', tags)}`;
text += `\n* ${TAPi18n.__('globalSearch-instructions-notes-3-2', tags)}`;
text += `\n* ${TAPi18n.__('globalSearch-instructions-notes-4', tags)}`;
text += `\n* ${TAPi18n.__('globalSearch-instructions-notes-5', tags)}`;
[
'globalSearch-instructions-notes-1',
'globalSearch-instructions-notes-2',
'globalSearch-instructions-notes-3',
'globalSearch-instructions-notes-3-2',
'globalSearch-instructions-notes-4',
'globalSearch-instructions-notes-5',
].forEach(instruction => {
text += `\n* ${TAPi18n.__(instruction, tags)}`;
});
return text;
},
+7 -4
View File
@@ -71,17 +71,17 @@
.global-search-error-messages
color: darkred
.global-search-instructions
.global-search-page
width: 40%
min-width: 400px
margin-right: auto
margin-left: auto
line-height: 150%
.global-search-instructions h1
.global-search-page h1
margin-top: 2rem;
.global-search-instructions h2
.global-search-page h2
margin-top: 1rem;
.global-search-query-input
@@ -100,7 +100,7 @@ code
color: black
background-color: lightgrey
padding: 0.1rem !important
font-size: 0.7rem !important
font-size: 0.8rem !important
.list-title
background-color: darkgray
@@ -116,3 +116,6 @@ code
.global-search-previous-page
border: none
text-align: left;
.global-search-instructions li
margin-bottom: 0.3rem
+3 -3
View File
@@ -30,8 +30,8 @@ template(name="myCards")
each board in myCardsList
.my-cards-board-wrapper
.my-cards-board-title(class=board.colorClass, id="header")
a(href=board.absoluteUrl)
+viewer
a(href=board.originRelativeUrl)
+viewer
= board.title
each swimlane in board.mySwimlanes
.my-cards-swimlane-title(class="{{#if swimlane.colorClass}}{{ swimlane.colorClass }}{{else}}swimlane-default-color{{/if}}")
@@ -44,7 +44,7 @@ template(name="myCards")
= list.title
each card in list.myCards
.my-cards-card-wrapper
a.minicard-wrapper(href=card.absoluteUrl)
a.minicard-wrapper(href=card.originRelativeUrl)
+minicard(card)
else
.my-cards-dueat-list-wrapper
Binary file not shown.
+45 -38
View File
@@ -13,10 +13,11 @@ template(name="setting")
a.js-setting-menu(data-id="registration-setting")
i.fa.fa-sign-in
| {{_ 'registration'}}
li
a.js-setting-menu(data-id="email-setting")
i.fa.fa-envelope
| {{_ 'email'}}
unless isSandstorm
li
a.js-setting-menu(data-id="email-setting")
i.fa.fa-envelope
| {{_ 'email'}}
li
a.js-setting-menu(data-id="account-setting")
i.fa.fa-users
@@ -39,7 +40,8 @@ template(name="setting")
else if generalSetting.get
+general
else if emailSetting.get
+email
unless isSandstorm
+email
else if accountSetting.get
+accountSettings
else if announcementSetting.get
@@ -80,39 +82,40 @@ template(name="general")
template(name='email')
ul#email-setting.setting-detail
li.smtp-form
.title {{_ 'smtp-host'}}
.description {{_ 'smtp-host-description'}}
.form-group
input.wekan-form-control#mail-server-host(type="text", placeholder="smtp.domain.com" value="{{currentSetting.mailServer.host}}")
li.smtp-form
.title {{_ 'smtp-port'}}
.description {{_ 'smtp-port-description'}}
.form-group
input.wekan-form-control#mail-server-port(type="text", placeholder="25" value="{{currentSetting.mailServer.port}}")
li.smtp-form
.title {{_ 'smtp-username'}}
.form-group
input.wekan-form-control#mail-server-username(type="text", placeholder="{{_ 'username'}}" value="{{currentSetting.mailServer.username}}")
li.smtp-form
.title {{_ 'smtp-password'}}
.form-group
input.wekan-form-control#mail-server-password(type="password", placeholder="{{_ 'password'}}" value="")
li.smtp-form
.title {{_ 'smtp-tls'}}
.form-group
a.flex.js-toggle-tls
.materialCheckBox#mail-server-tls(class="{{#if currentSetting.mailServer.enableTLS}}is-checked{{/if}}")
span {{_ 'smtp-tls-description'}}
li.smtp-form
.title {{_ 'send-from'}}
.form-group
input.wekan-form-control#mail-server-from(type="email", placeholder="no-reply@domain.com" value="{{currentSetting.mailServer.from}}")
li
button.js-save.primary {{_ 'save'}}
//if isSandstorm
// li.smtp-form
// .title {{_ 'smtp-host'}}
// .description {{_ 'smtp-host-description'}}
// .form-group
// input.wekan-form-control#mail-server-host(type="text", placeholder="smtp.domain.com" value="{{currentSetting.mailServer.host}}")
// li.smtp-form
// .title {{_ 'smtp-port'}}
// .description {{_ 'smtp-port-description'}}
// .form-group
// input.wekan-form-control#mail-server-port(type="text", placeholder="25" value="{{currentSetting.mailServer.port}}")
// li.smtp-form
// .title {{_ 'smtp-username'}}
// .form-group
// input.wekan-form-control#mail-server-username(type="text", placeholder="{{_ 'username'}}" value="{{currentSetting.mailServer.username}}")
// li.smtp-form
// .title {{_ 'smtp-password'}}
// .form-group
// input.wekan-form-control#mail-server-password(type="password", placeholder="{{_ 'password'}}" value="")
// li.smtp-form
// .title {{_ 'smtp-tls'}}
// .form-group
// a.flex.js-toggle-tls
// .materialCheckBox#mail-server-tls(class="{{#if currentSetting.mailServer.enableTLS}}is-checked{{/if}}")
//
// span {{_ 'smtp-tls-description'}}
//
// li.smtp-form
// .title {{_ 'send-from'}}
// .form-group
// input.wekan-form-control#mail-server-from(type="email", placeholder="no-reply@domain.com" value="{{currentSetting.mailServer.from}}")
//
// li
// button.js-save.primary {{_ 'save'}}
li
button.js-send-smtp-test-email.primary {{_ 'send-smtp-test'}}
@@ -208,6 +211,10 @@ template(name='layoutSettings')
.title {{_ 'custom-top-left-corner-logo-height'}}
.form-group
input.wekan-form-control#custom-top-left-corner-logo-height(type="text", placeholder="" value="{{currentSetting.customTopLeftCornerLogoHeight}}")
li.layout-form
.title {{_ 'automatic-linked-url-schemes'}}
.form-group
textarea#automatic-linked-url-schemes.wekan-form-control= currentSetting.automaticLinkedUrlSchemes
li
button.js-save-layout.primary {{_ 'save'}}
@@ -176,6 +176,9 @@ BlazeComponent.extendComponent({
const textBelowCustomLoginLogo = $('#text-below-custom-login-logo')
.val()
.trim();
const automaticLinkedUrlSchemes = $('#automatic-linked-url-schemes')
.val()
.trim();
const customTopLeftCornerLogoImageUrl = $(
'#custom-top-left-corner-logo-image-url',
)
@@ -209,6 +212,7 @@ BlazeComponent.extendComponent({
customTopLeftCornerLogoHeight,
displayAuthenticationMethod,
defaultAuthenticationMethod,
automaticLinkedUrlSchemes,
},
});
} catch (e) {
@@ -4,9 +4,9 @@ template(name="searchSidebar")
.list-body
.minilists.clearfix.js-minilists
each (lists)
a.minilist-wrapper.js-minilist(href=absoluteUrl)
a.minilist-wrapper.js-minilist(href=originRelativeUrl)
+minilist(this)
.minicards.clearfix.js-minicards
each (results)
a.minicard-wrapper.js-minicard(href=absoluteUrl)
a.minicard-wrapper.js-minicard(href=originRelativeUrl)
+minicard(this)
+983 -972
View File
File diff suppressed because it is too large. Load diff
+983 -972
View File
File diff suppressed because it is too large. Load diff
+983 -972
View File
File diff suppressed because it is too large. Load diff
+983 -972
View File
File diff suppressed because it is too large. Load diff
+983 -972
View File
File diff suppressed because it is too large. Load diff
+983 -972
View File
File diff suppressed because it is too large. Load diff
+983 -972
View File
File diff suppressed because it is too large. Load diff
+983 -972
View File
File diff suppressed because it is too large. Load diff
+983 -972
View File
File diff suppressed because it is too large. Load diff
+983 -972
View File
File diff suppressed because it is too large. Load diff
+31 -20
View File
@@ -532,6 +532,7 @@
"custom-login-logo-image-url": "Custom Login Logo Image URL",
"custom-login-logo-link-url": "Custom Login Logo Link URL",
"text-below-custom-login-logo": "Text below Custom Login Logo",
"automatic-linked-url-schemes": "Custom URL Schemes which should automatically be clickable. One URL Scheme per line",
"username": "Username",
"import-usernames": "Import Usernames",
"view-it": "View it",
@@ -907,7 +908,9 @@
"operator-sort": "sort",
"operator-comment": "comment",
"operator-has": "has",
"operator-limit": "limit",
"predicate-archived": "archived",
"predicate-open": "open",
"predicate-ended": "ended",
"predicate-all": "all",
"predicate-overdue": "overdue",
@@ -921,6 +924,10 @@
"predicate-attachment": "attachment",
"predicate-description": "description",
"predicate-checklist": "checklist",
"predicate-start": "start",
"predicate-end": "end",
"predicate-assignee": "assignee",
"predicate-member": "member",
"predicate-public": "public",
"predicate-private": "private",
"operator-unknown-error": "%s is not an operator",
@@ -928,35 +935,39 @@
"operator-sort-invalid": "sort of '%s' is invalid",
"operator-status-invalid": "'%s' is not a valid status",
"operator-has-invalid": "%s is not a valid existence check",
"operator-limit-invalid": "%s is not a valid limit. Limit should be a positive integer.",
"next-page": "Next Page",
"previous-page": "Previous Page",
"heading-notes": "Notes",
"globalSearch-instructions-heading": "Search Instructions",
"globalSearch-instructions-description": "Searches can include operators to refine the search. Operators are specified by writing the operator name and value separated by a colon. For example, an operator specification of `list:Blocked` would limit the search to cards that are contained in a list named *Blocked*. If the value contains spaces or special characters it must be enclosed in quotation marks (e.g. `__operator_list__:\"To Review\"`).",
"globalSearch-instructions-operators": "Available operators:",
"globalSearch-instructions-operator-board": "`__operator_board__:title` - cards in boards matching the specified title",
"globalSearch-instructions-operator-list": "`__operator_list__:title` - cards in lists matching the specified title",
"globalSearch-instructions-operator-swimlane": "`__operator_swimlane__:title` - cards in swimlanes matching the specified title",
"globalSearch-instructions-operator-comment": "`__operator_comment__:text` - cards with a comment containing *text*.",
"globalSearch-instructions-operator-label": "`__operator_label__:color` `__operator_label__:name` - cards that have a label matching the given color or name",
"globalSearch-instructions-operator-hash": "`__operator_label_abbrev__label` - shorthand for `__operator_label__:label`",
"globalSearch-instructions-operator-user": "`__operator_user__:username` - cards where the specified user is a *member* or *assignee*",
"globalSearch-instructions-operator-at": "`__operator_user_abbrev__username` - shorthand for `user:username`",
"globalSearch-instructions-operator-member": "`__operator_member__:username` - cards where the specified user is a *member*",
"globalSearch-instructions-operator-assignee": "`__operator_assignee__:username` - cards where the specified user is an *assignee*",
"globalSearch-instructions-operator-due": "`__operator_due__:n` - cards which are due *n* days from now. `__operator_due__:__predicate_overdue__ lists all cards past their due date.",
"globalSearch-instructions-operator-created": "`__operator_created__:n` - cards which were created *n* days ago",
"globalSearch-instructions-operator-modified": "`__operator_modified__:n` - cards which were modified *n* days ago",
"globalSearch-instructions-status-archived": "`__operator_status__:__predicate_archived__` - cards that are archived.",
"globalSearch-instructions-status-all": "`__operator_status__:__predicate_all__` - all archived and unarchived cards.",
"globalSearch-instructions-status-ended": "`__operator_status__:__predicate_ended__` - cards with an end date.",
"globalSearch-instructions-status-public": "`__operator_status__:__predicate_public__` - cards only in public boards.",
"globalSearch-instructions-status-private": "`__operator_status__:__predicate_private__` - cards only in private boards.",
"globalSearch-instructions-operator-has": "`__operator_has__:field` - where *field* is one of `__predicate_attachment__`, `__predicate_checklist__` or `__predicate_description__`",
"globalSearch-instructions-operator-board": "`__operator_board__:<title>` - cards in boards matching the specified *<title>*",
"globalSearch-instructions-operator-list": "`__operator_list__:<title>` - cards in lists matching the specified *<title>*",
"globalSearch-instructions-operator-swimlane": "`__operator_swimlane__:<title>` - cards in swimlanes matching the specified *<title>*",
"globalSearch-instructions-operator-comment": "`__operator_comment__:<text>` - cards with a comment containing *<text>*.",
"globalSearch-instructions-operator-label": "`__operator_label__:<color>` `__operator_label__:<name>` - cards that have a label matching *<color>* or *<name>",
"globalSearch-instructions-operator-hash": "`__operator_label_abbrev__<name | color>` - shorthand for `__operator_label__:<color>` or `__operator_label__:<name>`",
"globalSearch-instructions-operator-user": "`__operator_user__:<username>` - cards where *<username>* is a *member* or *assignee*",
"globalSearch-instructions-operator-at": "`__operator_user_abbrev__username` - shorthand for `user:<username>`",
"globalSearch-instructions-operator-member": "`__operator_member__:<username>` - cards where *<username>* is a *member*",
"globalSearch-instructions-operator-assignee": "`__operator_assignee__:<username>` - cards where *<username>* is an *assignee*",
"globalSearch-instructions-operator-due": "`__operator_due__:<n>` - cards which are due up to *<n>* days from now. `__operator_due__:__predicate_overdue__ lists all cards past their due date.",
"globalSearch-instructions-operator-created": "`__operator_created__:<n>` - cards which were created *<n>* days ago or less",
"globalSearch-instructions-operator-modified": "`__operator_modified__:<n>` - cards which were modified *<n>* days ago or less",
"globalSearch-instructions-operator-status": "`__operator_status__:<status>` - where *<status>* is one of the following:",
"globalSearch-instructions-status-archived": "`__predicate_archived__` - archived cards",
"globalSearch-instructions-status-all": "`__predicate_all__` - all archived and unarchived cards",
"globalSearch-instructions-status-ended": "`__predicate_ended__` - cards with an end date",
"globalSearch-instructions-status-public": "`__predicate_public__` - cards only in public boards",
"globalSearch-instructions-status-private": "`__predicate_private__` - cards only in private boards",
"globalSearch-instructions-operator-has": "`__operator_has__:<field>` - where *<field>* is one of `__predicate_attachment__`, `__predicate_checklist__`, `__predicate_description__`, `__predicate_start__`, `__predicate_due__`, `__predicate_end__`, `__predicate_assignee__` or `__predicate_member__`. Placing a `-` in front of *<field>* searches for the absence of a value in that field (e.g. `has:-due` searches for cards without a due date).",
"globalSearch-instructions-operator-sort": "`__operator_sort__:<sort-name>` - where *<sort-name>* is one of `__predicate_due__`, `__predicate_created__` or `__predicate_modified__`. For a descending sort, place a `-` in front of the sort name.",
"globalSearch-instructions-operator-limit": "`__operator_limit__:<n>` - where *<n>* is a positive integer expressing the number of cards to be displayed per page.",
"globalSearch-instructions-notes-1": "Multiple operators may be specified.",
"globalSearch-instructions-notes-2": "Similar operators are *OR*ed together. Cards that match any of the conditions will be returned.\n`__operator_list__:Available __operator_list__:Blocked` would return cards contained in any list named *Blocked* or *Available*.",
"globalSearch-instructions-notes-3": "Differing operators are *AND*ed together. Only cards that match all of the differing operators are returned. `__operator_list__:Available __operator_label__:red` returns only cards in the list *Available* with a *red* label.",
"globalSearch-instructions-notes-3-2": "Days can be specified as an integer or using `__predicate_week__`, `__predicate_month__`, `__predicate_quarter__` or `__predicate_year__`",
"globalSearch-instructions-notes-3-2": "Days can be specified as a positive or negative integer or using `__predicate_week__`, `__predicate_month__`, `__predicate_quarter__` or `__predicate_year__` for the current period.",
"globalSearch-instructions-notes-4": "Text searches are case insensitive.",
"globalSearch-instructions-notes-5": "By default archived cards are not searched.",
"link-to-search": "Link to this search",
+983 -972
View File
File diff suppressed because it is too large. Load diff
+983 -972
View File
File diff suppressed because it is too large. Load diff
+983 -972
View File
File diff suppressed because it is too large. Load diff
+983 -972
View File
File diff suppressed because it is too large. Load diff
+983 -972
View File
File diff suppressed because it is too large. Load diff
+983 -972
View File
File diff suppressed because it is too large. Load diff
+983 -972
View File
File diff suppressed because it is too large. Load diff
+983 -972
View File
File diff suppressed because it is too large. Load diff
+983 -972
View File
File diff suppressed because it is too large. Load diff
+983 -972
View File
File diff suppressed because it is too large. Load diff
+983 -972
View File
File diff suppressed because it is too large. Load diff
+983 -972
View File
File diff suppressed because it is too large. Load diff
+983 -972
View File
File diff suppressed because it is too large. Load diff
+983 -972
View File
File diff suppressed because it is too large. Load diff
+983 -972
View File
File diff suppressed because it is too large. Load diff
+983 -972
View File
File diff suppressed because it is too large. Load diff
+983 -972
View File
File diff suppressed because it is too large. Load diff
+983 -972
View File
File diff suppressed because it is too large. Load diff
+983 -972
View File
File diff suppressed because it is too large. Load diff
+983 -972
View File
File diff suppressed because it is too large. Load diff
+983 -972
View File
File diff suppressed because it is too large. Load diff
+983 -972
View File
File diff suppressed because it is too large. Load diff
+983 -972
View File
File diff suppressed because it is too large. Load diff
+983 -972
View File
File diff suppressed because it is too large. Load diff
+983 -972
View File
File diff suppressed because it is too large. Load diff
+983 -972
View File
File diff suppressed because it is too large. Load diff
+983 -972
View File
File diff suppressed because it is too large. Load diff
+983 -972
View File
File diff suppressed because it is too large. Load diff
+983 -972
View File
File diff suppressed because it is too large. Load diff
+983 -972
View File
File diff suppressed because it is too large. Load diff
+983 -972
View File
File diff suppressed because it is too large. Load diff
+983 -972
View File
File diff suppressed because it is too large. Load diff
+983 -972
View File
File diff suppressed because it is too large. Load diff
+983 -972
View File
File diff suppressed because it is too large. Load diff
+983 -972
View File
File diff suppressed because it is too large. Load diff
+983 -972
View File
File diff suppressed because it is too large. Load diff
+983 -972
View File
File diff suppressed because it is too large. Load diff
+983 -972
View File
File diff suppressed because it is too large. Load diff
+983 -972
View File
File diff suppressed because it is too large. Load diff
+983 -972
View File
File diff suppressed because it is too large. Load diff
+983 -972
View File
File diff suppressed because it is too large. Load diff
+983 -972
View File
File diff suppressed because it is too large. Load diff
+983 -972
View File
File diff suppressed because it is too large. Load diff
+983 -972
View File
File diff suppressed because it is too large. Load diff
+983 -972
View File
File diff suppressed because it is too large. Load diff
+983 -972
View File
File diff suppressed because it is too large. Load diff
+983 -972
View File
File diff suppressed because it is too large. Load diff
+983 -972
View File
File diff suppressed because it is too large. Load diff
+983 -972
View File
File diff suppressed because it is too large. Load diff
+983 -972
View File
File diff suppressed because it is too large. Load diff
+29 -7
View File
@@ -117,9 +117,17 @@ if (Meteor.isServer) {
// No need send notification to user of activity
// participants = _.union(participants, [activity.userId]);
const user = activity.user();
params.user = user.getName();
params.userEmails = user.emails;
params.userId = activity.userId;
if (user) {
if (user.getName()) {
params.user = user.getName();
}
if (user.emails) {
params.userEmails = user.emails;
}
if (activity.userId) {
params.userId = activity.userId;
}
}
}
if (activity.boardId) {
if (board.title.length > 0) {
@@ -222,16 +230,30 @@ if (Meteor.isServer) {
}
if (activity.checklistId) {
const checklist = activity.checklist();
params.checklist = checklist.title;
if (checklist) {
if (checklist.title) {
params.checklist = checklist.title;
}
}
}
if (activity.checklistItemId) {
const checklistItem = activity.checklistItem();
params.checklistItem = checklistItem.title;
if (checklistItem) {
if (checklistItem.title) {
params.checklistItem = checklistItem.title;
}
}
}
if (activity.customFieldId) {
const customField = activity.customField();
params.customField = customField.name;
params.customFieldValue = activity.value;
if (customField) {
if (customField.name) {
params.customField = customField.name;
}
if (activity.value) {
params.customFieldValue = activity.value;
}
}
}
// Label activity did not work yet, unable to edit labels when tried this.
//if (activity.labelId) {
+3
View File
@@ -777,6 +777,9 @@ Boards.helpers({
absoluteUrl() {
return FlowRouter.url('board', { id: this._id, slug: this.slug });
},
originRelativeUrl() {
return FlowRouter.path('board', { id: this._id, slug: this.slug });
},
colorClass() {
return `board-color-${this.color}`;
+1 -1
View File
@@ -117,7 +117,7 @@ CardComments.textSearch = (userId, textArray) => {
};
for (const text of textArray) {
selector.$and.push({ text: new RegExp(escapeForRegex(text)) });
selector.$and.push({ text: new RegExp(escapeForRegex(text), 'i') });
}
// eslint-disable-next-line no-console
+25
View File
@@ -758,6 +758,14 @@ Cards.helpers({
cardId: this._id,
});
},
originRelativeUrl() {
const board = this.board();
return FlowRouter.path('card', {
boardId: board._id,
slug: board.slug,
cardId: this._id,
});
},
canBeRestored() {
const list = Lists.findOne({
@@ -2575,6 +2583,7 @@ if (Meteor.isServer) {
* @param {string} list the list ID of the card
* @param {string} cardId the ID of the card
* @param {string} [title] the new title of the card
* @param {string} [sort] the new sort value of the card
* @param {string} [listId] the new list ID of the card (move operation)
* @param {string} [description] the new description of the card
* @param {string} [authorId] change the owner of the card
@@ -2625,6 +2634,22 @@ if (Meteor.isServer) {
},
);
}
if (req.body.hasOwnProperty('sort')) {
const newSort = req.body.sort;
Cards.direct.update(
{
_id: paramCardId,
listId: paramListId,
boardId: paramBoardId,
archived: false,
},
{
$set: {
sort: newSort,
},
},
);
}
if (req.body.hasOwnProperty('parentId')) {
const newParentId = req.body.parentId;
Cards.direct.update(
+188 -1
View File
@@ -307,7 +307,8 @@ if (Meteor.isServer) {
*
* @param {string} boardID the ID of the board
* @param {string} customFieldId the ID of the custom field
* @return_type CustomFields
* @return_type [{_id: string,
* boardIds: string}]
*/
JsonRoutes.add(
'GET',
@@ -370,6 +371,192 @@ if (Meteor.isServer) {
});
});
/**
* @operation edit_custom_field
* @summary Update a Custom Field
*
* @param {string} name the name of the custom field
* @param {string} type the type of the custom field
* @param {string} settings the settings object of the custom field
* @param {boolean} showOnCard should we show the custom field on cards
* @param {boolean} automaticallyOnCard should the custom fields automatically be added on cards
* @param {boolean} showLabelOnMiniCard should the label of the custom field be shown on minicards
* @return_type {_id: string}
*/
JsonRoutes.add(
'PUT',
'/api/boards/:boardId/custom-fields/:customFieldId',
(req, res) => {
Authentication.checkUserId(req.userId);
const paramFieldId = req.params.customFieldId;
if (req.body.hasOwnProperty('name')) {
CustomFields.direct.update(
{ _id: paramFieldId },
{ $set: { name: req.body.name } },
);
}
if (req.body.hasOwnProperty('type')) {
CustomFields.direct.update(
{ _id: paramFieldId },
{ $set: { type: req.body.type } },
);
}
if (req.body.hasOwnProperty('settings')) {
CustomFields.direct.update(
{ _id: paramFieldId },
{ $set: { settings: req.body.settings } },
);
}
if (req.body.hasOwnProperty('showOnCard')) {
CustomFields.direct.update(
{ _id: paramFieldId },
{ $set: { showOnCard: req.body.showOnCard } },
);
}
if (req.body.hasOwnProperty('automaticallyOnCard')) {
CustomFields.direct.update(
{ _id: paramFieldId },
{ $set: { automaticallyOnCard: req.body.automaticallyOnCard } },
);
}
if (req.body.hasOwnProperty('alwaysOnCard')) {
CustomFields.direct.update(
{ _id: paramFieldId },
{ $set: { alwaysOnCard: req.body.alwaysOnCard } },
);
}
if (req.body.hasOwnProperty('showLabelOnMiniCard')) {
CustomFields.direct.update(
{ _id: paramFieldId },
{ $set: { showLabelOnMiniCard: req.body.showLabelOnMiniCard } },
);
}
JsonRoutes.sendResult(res, {
code: 200,
data: { _id: paramFieldId },
});
},
);
/**
* @operation add_custom_field_dropdown_items
* @summary Update a Custom Field's dropdown items
*
* @param {string} [items] names of the custom field
* @return_type {_id: string}
*/
JsonRoutes.add(
'POST',
'/api/boards/:boardId/custom-fields/:customFieldId/dropdown-items',
(req, res) => {
Authentication.checkUserId(req.userId);
const paramCustomFieldId = req.params.customFieldId;
const paramItems = req.body.items;
if (req.body.hasOwnProperty('items')) {
if (Array.isArray(paramItems)) {
CustomFields.direct.update(
{ _id: paramCustomFieldId },
{
$push: {
'settings.dropdownItems': {
$each: paramItems
.filter(name => typeof name === 'string')
.map(name => ({
_id: Random.id(6),
name,
})),
},
},
},
);
}
}
JsonRoutes.sendResult(res, {
code: 200,
data: { _id: paramCustomFieldId },
});
},
);
/**
* @operation edit_custom_field_dropdown_item
* @summary Update a Custom Field's dropdown item
*
* @param {string} name names of the custom field
* @return_type {_id: string}
*/
JsonRoutes.add(
'PUT',
'/api/boards/:boardId/custom-fields/:customFieldId/dropdown-items/:dropdownItemId',
(req, res) => {
Authentication.checkUserId(req.userId);
const paramDropdownItemId = req.params.dropdownItemId;
const paramCustomFieldId = req.params.customFieldId;
const paramName = req.body.name;
if (req.body.hasOwnProperty('name')) {
CustomFields.direct.update(
{
_id: paramCustomFieldId,
'settings.dropdownItems._id': paramDropdownItemId,
},
{
$set: {
'settings.dropdownItems.$': {
_id: paramDropdownItemId,
name: paramName,
},
},
},
);
}
JsonRoutes.sendResult(res, {
code: 200,
data: { _id: customFieldId },
});
},
);
/**
* @operation delete_custom_field_dropdown_item
* @summary Update a Custom Field's dropdown items
*
* @param {string} itemId ID of the dropdown item
* @return_type {_id: string}
*/
JsonRoutes.add(
'DELETE',
'/api/boards/:boardId/custom-fields/:customFieldId/dropdown-items/:dropdownItemId',
(req, res) => {
Authentication.checkUserId(req.userId);
paramCustomFieldId = req.params.customFieldId;
paramDropdownItemId = req.params.dropdownItemId;
CustomFields.direct.update(
{ _id: paramCustomFieldId },
{
$pull: {
'settings.dropdownItems': { _id: paramDropdownItemId },
},
},
);
JsonRoutes.sendResult(res, {
code: 200,
data: { _id: paramCustomFieldId },
});
},
);
/**
* @operation delete_custom_field
* @summary Delete a Custom Fields attached to a board
+4
View File
@@ -280,6 +280,10 @@ Lists.helpers({
const card = Cards.findOne({ listId: this._id });
return card && card.absoluteUrl();
},
originRelativeUrl() {
const card = Cards.findOne({ listId: this._id });
return card && card.originRelativeUrl();
},
remove() {
Lists.remove({ _id: this._id });
},
+12
View File
@@ -0,0 +1,12 @@
if (Meteor.isServer) {
Meteor.startup(() => {
// Date of 7 days ago
let lastWeek = new Date();
lastWeek.setDate(lastWeek.getDate() - 7);
presences.remove({ ttl: { $lte: lastWeek } });
// Create index for serverId that is queried often
presences._collection._ensureIndex({ serverId: -1 });
});
}
+39 -21
View File
@@ -1,3 +1,8 @@
// Sandstorm context is detected using the METEOR_SETTINGS environment variable
// in the package definition.
const isSandstorm =
Meteor.settings && Meteor.settings.public && Meteor.settings.public.sandstorm;
Settings = new Mongo.Collection('settings');
Settings.attachSchema(
@@ -57,6 +62,10 @@ Settings.attachSchema(
type: String,
optional: true,
},
automaticLinkedUrlSchemes: {
type: String,
optional: true,
},
customTopLeftCornerLogoImageUrl: {
type: String,
optional: true,
@@ -144,29 +153,38 @@ if (Meteor.isServer) {
};
Settings.insert(defaultSetting);
}
const newSetting = Settings.findOne();
if (!process.env.MAIL_URL && newSetting.mailUrl())
process.env.MAIL_URL = newSetting.mailUrl();
Accounts.emailTemplates.from = process.env.MAIL_FROM
? process.env.MAIL_FROM
: newSetting.mailServer.from;
});
Settings.after.update((userId, doc, fieldNames) => {
// assign new values to mail-from & MAIL_URL in environment
if (_.contains(fieldNames, 'mailServer') && doc.mailServer.host) {
const protocol = doc.mailServer.enableTLS ? 'smtps://' : 'smtp://';
if (!doc.mailServer.username && !doc.mailServer.password) {
process.env.MAIL_URL = `${protocol}${doc.mailServer.host}:${doc.mailServer.port}/`;
} else {
process.env.MAIL_URL = `${protocol}${
doc.mailServer.username
}:${encodeURIComponent(doc.mailServer.password)}@${
doc.mailServer.host
}:${doc.mailServer.port}/`;
}
Accounts.emailTemplates.from = doc.mailServer.from;
if (isSandstorm) {
// At Sandstorm, Admin Panel has SMTP settings
const newSetting = Settings.findOne();
if (!process.env.MAIL_URL && newSetting.mailUrl())
process.env.MAIL_URL = newSetting.mailUrl();
Accounts.emailTemplates.from = process.env.MAIL_FROM
? process.env.MAIL_FROM
: newSetting.mailServer.from;
} else {
// Not running on Sandstorm, so using environment variables
Accounts.emailTemplates.from = process.env.MAIL_FROM;
}
});
if (isSandstorm) {
// At Sandstorm Wekan Admin Panel, save SMTP settings.
Settings.after.update((userId, doc, fieldNames) => {
// assign new values to mail-from & MAIL_URL in environment
if (_.contains(fieldNames, 'mailServer') && doc.mailServer.host) {
const protocol = doc.mailServer.enableTLS ? 'smtps://' : 'smtp://';
if (!doc.mailServer.username && !doc.mailServer.password) {
process.env.MAIL_URL = `${protocol}${doc.mailServer.host}:${doc.mailServer.port}/`;
} else {
process.env.MAIL_URL = `${protocol}${
doc.mailServer.username
}:${encodeURIComponent(doc.mailServer.password)}@${
doc.mailServer.host
}:${doc.mailServer.port}/`;
}
Accounts.emailTemplates.from = doc.mailServer.from;
}
});
}
function getRandomNum(min, max) {
const range = max - min;
+64 -18
View File
@@ -62,6 +62,12 @@ SessionData.attachSchema(
optional: true,
blackbox: true,
},
projection: {
type: String,
optional: true,
blackbox: true,
defaultValue: {},
},
errorMessages: {
type: [String],
optional: true,
@@ -130,40 +136,80 @@ SessionData.helpers({
getSelector() {
return SessionData.unpickle(this.selector);
},
getProjection() {
return SessionData.unpickle(this.projection);
},
});
SessionData.unpickle = pickle => {
return JSON.parse(pickle, (key, value) => {
if (value === null) {
return null;
} else if (typeof value === 'object') {
// eslint-disable-next-line no-prototype-builtins
if (value.hasOwnProperty('$$class')) {
if (value.$$class === 'RegExp') {
return new RegExp(value.source, value.flags);
}
}
}
return value;
return unpickleValue(value);
});
};
function unpickleValue(value) {
if (value === null) {
return null;
} else if (typeof value === 'object') {
// eslint-disable-next-line no-prototype-builtins
if (value.hasOwnProperty('$$class')) {
switch (value.$$class) {
case 'RegExp':
return new RegExp(value.source, value.flags);
case 'Date':
return new Date(value.stringValue);
case 'Object':
return unpickleObject(value);
}
}
}
return value;
}
function unpickleObject(obj) {
const newObject = {};
Object.entries(obj).forEach(([key, value]) => {
newObject[key] = unpickleValue(value);
});
return newObject;
}
SessionData.pickle = value => {
return JSON.stringify(value, (key, value) => {
if (value === null) {
return null;
} else if (typeof value === 'object') {
if (value.constructor.name === 'RegExp') {
return pickleValue(value);
});
};
function pickleValue(value) {
if (value === null) {
return null;
} else if (typeof value === 'object') {
switch (value.constructor.name) {
case 'RegExp':
return {
$$class: 'RegExp',
source: value.source,
flags: value.flags,
};
}
case 'Date':
return {
$$class: 'Date',
stringValue: String(value),
};
case 'Object':
return pickleObject(value);
}
return value;
}
return value;
}
function pickleObject(obj) {
const newObject = {};
Object.entries(obj).forEach(([key, value]) => {
newObject[key] = pickleValue(value);
});
};
return newObject;
}
if (!Meteor.isServer) {
SessionData.getSessionId = () => {
-1
View File
@@ -1,7 +1,6 @@
#!/bin/env python3
import argparse
import esprima
import json
import logging
import os
+9405 -523
View File
File diff suppressed because it is too large. Load diff
+2 -2
View File
@@ -1,6 +1,6 @@
{
"name": "wekan",
"version": "v4.99.0",
"version": "v5.07.0",
"description": "Open-Source kanban",
"private": true,
"scripts": {
@@ -72,7 +72,7 @@
"ldapjs": "^2.2.3",
"markdown-it": "^12.0.4",
"markdown-it-emoji": "^2.0.0",
"meteor-node-stubs": "^1.0.1",
"meteor-node-stubs": "^1.0.2",
"mongodb": "^3.6.4",
"os": "^0.1.1",
"page": "^1.11.5",
+28 -11
View File
@@ -6,23 +6,40 @@ var Markdown = require('markdown-it')({
breaks: true,
});
// Static URL Scheme Listing
var urlschemes = [
"aodroplink",
"thunderlink",
"cbthunderlink",
"onenote",
"file",
"abasurl",
"conisio",
"mailspring"
];
// Better would be a field in the admin backend to set this dynamically
// instead of putting all known or wanted url schemes here hard into code
// but i was not able to access those settings
// var urlschemes = currentSetting.automaticLinkedUrlSchemes.split('\n');
// put all url schemes into the linkify configuration to automatically make it clickable
for(var i=0; i<urlschemes.length;i++){
//console.log("adding autolink for "+urlschemes[i]);
Markdown.linkify.add(urlschemes[i]+":",'http:');
}
// Additional safeAttrValue function to allow for other specific protocols
// See https://github.com/leizongmin/js-xss/issues/52#issuecomment-241354114
function mySafeAttrValue(tag, name, value, cssFilter) {
// only when the tag is 'a' and attribute is 'href'
// then use your custom function
if (tag === 'a' && name === 'href') {
// only filter the value if starts with 'cbthunderlink:' or 'aodroplink'
if (/^thunderlink:/ig.test(value) ||
/^cbthunderlink:/ig.test(value) ||
/^aodroplink:/ig.test(value) ||
/^onenote:/ig.test(value) ||
/^file:/ig.test(value) ||
/^abasurl:/ig.test(value) ||
/^conisio:/ig.test(value) ||
/^mailspring:/ig.test(value)) {
return value;
}
// only filter the value if starts with an registered url scheme
urlscheme = value.split(/:/);
//console.log("validating "+urlscheme[0]);
if(urlschemes.includes(urlscheme[0])) return value;
else {
// use the default safeAttrValue function to process all non cbthunderlinks
return sanitizeXss.safeAttrValue(tag, name, value, cssFilter);
+178 -16150
View File
File diff suppressed because it is too large. Load diff
+1 -3444
View File
File diff suppressed because it is too large. Load diff
+5 -11
View File
@@ -1,21 +1,15 @@
# Generate docs.
# Extract the OpenAPI specification.
# extract the OpenAPI specification
# Install dependencies.
sudo apt-get install python3-pip
sudo pip3 install -U setuptools wheel
sudo npm install -g api2html@0.3.3
sudo npm install -g --unsafe-perm api2html@0.3.0
sudo npm install -g --unsafe-perm mkdirp
mkdir -p ~/python
cd ~/python
git clone --depth 1 -b master https://github.com/Kronuz/esprima-python
cd ~/python/esprima-python
sudo python3 setup.py install --record files.txt
sudo npm install -g api2html
cd ~/repos/wekan
mkdir -p public/api
# Generate docs.
python3 ./openapi/generate_openapi.py --release $(git describe --tags --abbrev=0) > ./public/api/wekan.yml
api2html -c ./public/logo-header.png -o ./public/api/wekan.html ./public/api/wekan.yml
# Copy docs to bundle
#cp -pR ./public/api ~/repos/wekan/.build/bundle/programs/web.browser/app/
#cp -pR ./public/api ~/repos/wekan/.build/bundle/programs/web.browser.legacy/app/
+2 -7
View File
@@ -5,18 +5,13 @@ sudo apt-get -y install parallel
cd ~/repos/wekan/.build
zip -r wekan-$1.zip bundle
# Can not build ppc64le version because
# OpenPower Minicloud is having
# emergency maintenance.
# scp wekan-$1.zip o:/home/ubuntu/
# echo "Bundle uploaded to x2/a/s/o."
{
scp wekan-$1.zip x2:/var/snap/wekan/common/releases.wekan.team/
scp wekan-$1.zip a:/home/wekan/repos/
scp wekan-$1.zip s:/home/linux1/
scp wekan-$1.zip o:/home/ubuntu/
} | parallel -k
cd ..
echo "Bundle uploaded to x2/a/s."
echo "Bundle uploaded to x2/a/s/o."
+1 -5
View File
@@ -2,12 +2,8 @@
sudo apt-get -y install parallel
# Can not build ppc64le version because
# OpenPower Minicloud is having
# emergency maintenance.
# ~/repos/wekan/releases/up-o.sh $1
{
~/repos/wekan/releases/up-a.sh $1
~/repos/wekan/releases/up-s.sh $1
~/repos/wekan/releases/up-o.sh $1
} | parallel -k
+2 -2
View File
@@ -22,10 +22,10 @@ const pkgdef :Spk.PackageDefinition = (
appTitle = (defaultText = "Wekan"),
# The name of the app as it is displayed to the user.
appVersion = 499,
appVersion = 507,
# Increment this for every release.
appMarketingVersion = (defaultText = "4.99.0~2021-02-25"),
appMarketingVersion = (defaultText = "5.07.0~2021-03-19"),
# Human-readable presentation of the app version.
minUpgradableAppVersion = 0,
Loaded 100 of 104 files, more files were not shown because too many files have changed in this diff. Show more