瀏覽代碼

Merge branch 'edge' into meteor-1.8

Lauri Ojansivu 6 年之前
父節點
當前提交
4356aaff23
共有 69 個文件被更改,包括 260 次插入177 次删除
  1. 22 0
      CHANGELOG.md
  2. 0 94
      Dockerfile
  3. 4 0
      README.md
  4. 1 1
      Stackerfile.yml
  5. 3 1
      client/components/boards/boardsList.jade
  6. 15 0
      client/components/boards/boardsList.js
  7. 13 0
      client/components/boards/boardsList.styl
  8. 2 1
      client/components/cards/cardDetails.styl
  9. 1 2
      client/components/rules/triggers/boardTriggers.jade
  10. 5 1
      client/components/rules/triggers/boardTriggers.js
  11. 2 1
      i18n/ar.i18n.json
  12. 2 1
      i18n/bg.i18n.json
  13. 2 1
      i18n/br.i18n.json
  14. 2 1
      i18n/ca.i18n.json
  15. 2 1
      i18n/cs.i18n.json
  16. 2 1
      i18n/da.i18n.json
  17. 6 5
      i18n/de.i18n.json
  18. 2 1
      i18n/el.i18n.json
  19. 2 1
      i18n/en-GB.i18n.json
  20. 2 1
      i18n/en.i18n.json
  21. 2 1
      i18n/eo.i18n.json
  22. 2 1
      i18n/es-AR.i18n.json
  23. 2 1
      i18n/es.i18n.json
  24. 2 1
      i18n/eu.i18n.json
  25. 2 1
      i18n/fa.i18n.json
  26. 2 1
      i18n/fi.i18n.json
  27. 2 1
      i18n/fr.i18n.json
  28. 2 1
      i18n/gl.i18n.json
  29. 2 1
      i18n/he.i18n.json
  30. 2 1
      i18n/hi.i18n.json
  31. 2 1
      i18n/hu.i18n.json
  32. 2 1
      i18n/hy.i18n.json
  33. 2 1
      i18n/id.i18n.json
  34. 2 1
      i18n/ig.i18n.json
  35. 2 1
      i18n/it.i18n.json
  36. 2 1
      i18n/ja.i18n.json
  37. 2 1
      i18n/ka.i18n.json
  38. 2 1
      i18n/km.i18n.json
  39. 2 1
      i18n/ko.i18n.json
  40. 2 1
      i18n/lv.i18n.json
  41. 2 1
      i18n/mk.i18n.json
  42. 2 1
      i18n/mn.i18n.json
  43. 2 1
      i18n/nb.i18n.json
  44. 2 1
      i18n/nl.i18n.json
  45. 2 1
      i18n/oc.i18n.json
  46. 2 1
      i18n/pl.i18n.json
  47. 2 1
      i18n/pt-BR.i18n.json
  48. 2 1
      i18n/pt.i18n.json
  49. 2 1
      i18n/ro.i18n.json
  50. 2 1
      i18n/ru.i18n.json
  51. 2 1
      i18n/sr.i18n.json
  52. 2 1
      i18n/sv.i18n.json
  53. 2 1
      i18n/sw.i18n.json
  54. 2 1
      i18n/ta.i18n.json
  55. 2 1
      i18n/th.i18n.json
  56. 2 1
      i18n/tr.i18n.json
  57. 2 1
      i18n/uk.i18n.json
  58. 2 1
      i18n/vi.i18n.json
  59. 2 1
      i18n/zh-CN.i18n.json
  60. 2 1
      i18n/zh-TW.i18n.json
  61. 4 0
      models/cards.js
  62. 9 16
      models/export.js
  63. 19 0
      models/import.js
  64. 25 0
      models/wekanCreator.js
  65. 24 0
      models/wekanmapper.js
  66. 1 1
      package.json
  67. 2 2
      sandstorm-pkgdef.capnp
  68. 3 1
      server/rulesHelper.js
  69. 3 3
      server/triggersDef.js

+ 22 - 0
CHANGELOG.md

@@ -1,3 +1,25 @@
+# v2.58 2019-04-06 Wekan release
+
+This release adds the following new features:
+
+- [Duplicate Board](https://github.com/wekan/wekan/issues/2257). Related #2225.
+  Thanks to Angtrim.
+- [Add Duplicate Board tooltip, and remove adding text "Copy" to duplicated board](https://github.com/wekan/wekan/commit/0f15b6d1982c383f76e8411cb501ff27e8febd42).
+  Thanks to xet7.
+
+amd fixes the following bugs:
+
+- [Add proper variables for unjoin card](https://github.com/wekan/wekan/pull/2313).
+  Thanks to chotaire.
+- [Center reduce left margin in card view on mobile browser](https://github.com/wekan/wekan/pull/2314).
+  Thanks to hupptechnologies.
+- [Remove not needed ARGS from Dockerfile to reduce amount of Docker layers](https://github.com/wekan/wekan/issues/2301).
+  Thanks to folhabranca and xet7.
+- [Fix Swimlane Rules don't work](https://github.com/wekan/wekan/issues/2225).
+  Thanks to Angtrim.
+
+Thanks to above GitHub users for their contributions and translators for their translations.
+
 # v2.57 2019-04-02 Wekan release
 
 This release fixes the following bugs, thanks to justinr1234:

+ 0 - 94
Dockerfile

@@ -1,100 +1,6 @@
 FROM ubuntu:cosmic
 LABEL maintainer="wekan"
 
-# Declare Arguments
-ARG DEBUG
-ARG NODE_VERSION
-ARG METEOR_RELEASE
-ARG METEOR_EDGE
-ARG USE_EDGE
-ARG NPM_VERSION
-ARG FIBERS_VERSION
-ARG ARCHITECTURE
-ARG SRC_PATH
-ARG WITH_API
-ARG ACCOUNTS_LOCKOUT_KNOWN_USERS_FAILURES_BEFORE
-ARG ACCOUNTS_LOCKOUT_KNOWN_USERS_PERIOD
-ARG ACCOUNTS_LOCKOUT_KNOWN_USERS_FAILURE_WINDOW
-ARG ACCOUNTS_LOCKOUT_UNKNOWN_USERS_FAILURES_BERORE
-ARG ACCOUNTS_LOCKOUT_UNKNOWN_USERS_LOCKOUT_PERIOD
-ARG ACCOUNTS_LOCKOUT_UNKNOWN_USERS_FAILURE_WINDOW
-ARG EMAIL_NOTIFICATION_TIMEOUT
-ARG MATOMO_ADDRESS
-ARG MATOMO_SITE_ID
-ARG MATOMO_DO_NOT_TRACK
-ARG MATOMO_WITH_USERNAME
-ARG BROWSER_POLICY_ENABLED
-ARG TRUSTED_URL
-ARG WEBHOOKS_ATTRIBUTES
-ARG OAUTH2_ENABLED
-ARG OAUTH2_LOGIN_STYLE
-ARG OAUTH2_CLIENT_ID
-ARG OAUTH2_SECRET
-ARG OAUTH2_SERVER_URL
-ARG OAUTH2_AUTH_ENDPOINT
-ARG OAUTH2_USERINFO_ENDPOINT
-ARG OAUTH2_TOKEN_ENDPOINT
-ARG OAUTH2_ID_MAP
-ARG OAUTH2_USERNAME_MAP
-ARG OAUTH2_FULLNAME_MAP
-ARG OAUTH2_EMAIL_MAP
-ARG LDAP_ENABLE
-ARG LDAP_PORT
-ARG LDAP_HOST
-ARG LDAP_BASEDN
-ARG LDAP_LOGIN_FALLBACK
-ARG LDAP_RECONNECT
-ARG LDAP_TIMEOUT
-ARG LDAP_IDLE_TIMEOUT
-ARG LDAP_CONNECT_TIMEOUT
-ARG LDAP_AUTHENTIFICATION
-ARG LDAP_AUTHENTIFICATION_USERDN
-ARG LDAP_AUTHENTIFICATION_PASSWORD
-ARG LDAP_LOG_ENABLED
-ARG LDAP_BACKGROUND_SYNC
-ARG LDAP_BACKGROUND_SYNC_INTERVAL
-ARG LDAP_BACKGROUND_SYNC_KEEP_EXISTANT_USERS_UPDATED
-ARG LDAP_BACKGROUND_SYNC_IMPORT_NEW_USERS
-ARG LDAP_ENCRYPTION
-ARG LDAP_CA_CERT
-ARG LDAP_REJECT_UNAUTHORIZED
-ARG LDAP_USER_SEARCH_FILTER
-ARG LDAP_USER_SEARCH_SCOPE
-ARG LDAP_USER_SEARCH_FIELD
-ARG LDAP_SEARCH_PAGE_SIZE
-ARG LDAP_SEARCH_SIZE_LIMIT
-ARG LDAP_GROUP_FILTER_ENABLE
-ARG LDAP_GROUP_FILTER_OBJECTCLASS
-ARG LDAP_GROUP_FILTER_GROUP_ID_ATTRIBUTE
-ARG LDAP_GROUP_FILTER_GROUP_MEMBER_ATTRIBUTE
-ARG LDAP_GROUP_FILTER_GROUP_MEMBER_FORMAT
-ARG LDAP_GROUP_FILTER_GROUP_NAME
-ARG LDAP_UNIQUE_IDENTIFIER_FIELD
-ARG LDAP_UTF8_NAMES_SLUGIFY
-ARG LDAP_USERNAME_FIELD
-ARG LDAP_FULLNAME_FIELD
-ARG LDAP_EMAIL_FIELD
-ARG LDAP_EMAIL_MATCH_ENABLE
-ARG LDAP_EMAIL_MATCH_REQUIRE
-ARG LDAP_EMAIL_MATCH_VERIFIED
-ARG LDAP_MERGE_EXISTING_USERS
-ARG LDAP_SYNC_USER_DATA
-ARG LDAP_SYNC_USER_DATA_FIELDMAP
-ARG LDAP_SYNC_GROUP_ROLES
-ARG LDAP_DEFAULT_DOMAIN
-ARG LDAP_SYNC_ADMIN_STATUS
-ARG LDAP_SYNC_ADMIN_GROUPS
-ARG HEADER_LOGIN_ID
-ARG HEADER_LOGIN_FIRSTNAME
-ARG HEADER_LOGIN_LASTNAME
-ARG HEADER_LOGIN_EMAIL
-ARG LOGOUT_WITH_TIMER
-ARG LOGOUT_IN
-ARG LOGOUT_ON_HOURS
-ARG LOGOUT_ON_MINUTES
-ARG CORS
-ARG DEFAULT_AUTHENTICATION_METHOD
-
 # Set the environment variables (defaults where required)
 # DOES NOT WORK: paxctl fix for alpine linux: https://github.com/wekan/wekan/issues/1303
 # ENV BUILD_DEPS="paxctl"

+ 4 - 0
README.md

@@ -9,6 +9,7 @@
 [![Code Climate](https://codeclimate.com/github/wekan/wekan/badges/gpa.svg "Code Climate")](https://codeclimate.com/github/wekan/wekan)
 [![Project Dependencies](https://david-dm.org/wekan/wekan.svg "Project Dependencies")](https://david-dm.org/wekan/wekan)
 [![Code analysis at Open Hub](https://img.shields.io/badge/code%20analysis-at%20Open%20Hub-brightgreen.svg "Code analysis at Open Hub")](https://www.openhub.net/p/wekan)
+[![FOSSA Status](https://app.fossa.io/api/projects/git%2Bgithub.com%2Fwekan%2Fwekan.svg?type=shield)](https://app.fossa.io/projects/git%2Bgithub.com%2Fwekan%2Fwekan?ref=badge_shield)
 
 ## [Translate Wekan at Transifex](https://transifex.com/wekan/wekan)
 
@@ -133,3 +134,6 @@ with [Meteor](https://www.meteor.com).
 [free_software]: https://en.wikipedia.org/wiki/Free_software
 [vanila_badge]: https://vanila.io/img/join-chat-button2.png
 [wekan_chat]: https://community.vanila.io/wekan
+
+
+[![FOSSA Status](https://app.fossa.io/api/projects/git%2Bgithub.com%2Fwekan%2Fwekan.svg?type=large)](https://app.fossa.io/projects/git%2Bgithub.com%2Fwekan%2Fwekan?ref=badge_large)

+ 1 - 1
Stackerfile.yml

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

+ 3 - 1
client/components/boards/boardsList.jade

@@ -22,7 +22,9 @@ template(name="boardList")
                 i.fa.js-star-board(
                   class="fa-star{{#if isStarred}} is-star-active{{else}}-o{{/if}}"
                   title="{{_ 'star-board-title'}}")
-
+              i.fa.js-clone-board(
+                  class="fa-clone"
+                  title="{{_ 'duplicate-board'}}")
                 if hasSpentTimeCards
                   i.fa.js-has-spenttime-cards(
                     class="fa-circle{{#if hasOvertimeCards}} has-overtime-card-active{{else}} no-overtime-card-active{{/if}}"

+ 15 - 0
client/components/boards/boardsList.js

@@ -55,6 +55,21 @@ BlazeComponent.extendComponent({
         Meteor.user().toggleBoardStar(boardId);
         evt.preventDefault();
       },
+      'click .js-clone-board'(evt) {
+        Meteor.call('cloneBoard',
+          this.currentData()._id,
+          Session.get('fromBoard'),
+          (err, res) => {
+            if (err) {
+              this.setError(err.error);
+            } else {
+              Session.set('fromBoard', null);
+              Utils.goBoardId(res);
+            }
+          }
+        );
+        evt.preventDefault();
+      },
       'click .js-accept-invite'() {
         const boardId = this.currentData()._id;
         Meteor.user().removeInvite(boardId);

+ 13 - 0
client/components/boards/boardsList.styl

@@ -93,14 +93,27 @@ $spaceBetweenTiles = 16px
 
   .is-star-active
     color: white
+  .fa-clone
+    position: absolute;
+    bottom: 0
+    font-size: 14px
+    height: 18px
+    line-height: 18px
+    opacity: 0
+    right: 0
+    padding: 9px 9px
+    transition-duration: .15s
+    transition-property: color, font-size, background
 
   li:hover a
     &:hover
       .fa-star,
+      .fa-clone,
       .fa-star-o
         color: white
 
     .fa-star,
+    .fa-clone,
     .fa-star-o
       color: white
       opacity: .75

+ 2 - 1
client/components/cards/cardDetails.styl

@@ -133,7 +133,8 @@ input[type="submit"].attachment-add-link-submit
 
     .card-details-canvas
       width: 100%
-
+      padding-left: 0px;
+ 
     .card-details-header
       .close-card-details
         margin-right: 0px

+ 1 - 2
client/components/rules/triggers/boardTriggers.jade

@@ -64,8 +64,7 @@ template(name="boardTriggers")
       div.trigger-text 
         | {{_'r-in-swimlane'}}
       div.trigger-dropdown
-        input(id="create-swimlane-name",type=text,placeholder="{{_'r-swimlane-name'}}") 
-      div.trigger-button.trigger-button-person.js-show-user-field  
+        input(id="create-swimlane-name-2",type=text,placeholder="{{_'r-swimlane-name'}}") 
       div.trigger-button.trigger-button-person.js-show-user-field
         i.fa.fa-user
       div.user-details.hide-element

+ 5 - 1
client/components/rules/triggers/boardTriggers.js

@@ -39,15 +39,18 @@ BlazeComponent.extendComponent({
       'click .js-add-moved-trigger' (event) {
         const datas = this.data();
         const desc = Utils.getTriggerActionDesc(event, this);
-        const swimlaneName = this.find('#create-swimlane-name').value;
+        const swimlaneName = this.find('#create-swimlane-name-2').value;
         const actionSelected = this.find('#move-action').value;
         const listName = this.find('#move-list-name').value;
         const boardId = Session.get('currentBoard');
+        const divId = $(event.currentTarget.parentNode).attr('id');
+        const cardTitle = this.cardTitleFilters[divId];
         if (actionSelected === 'moved-to') {
           datas.triggerVar.set({
             activityType: 'moveCard',
             boardId,
             listName,
+            cardTitle,
             swimlaneName,
             'oldListName': '*',
             desc,
@@ -57,6 +60,7 @@ BlazeComponent.extendComponent({
           datas.triggerVar.set({
             activityType: 'moveCard',
             boardId,
+            cardTitle,
             swimlaneName,
             'listName': '*',
             'oldListName': listName,

+ 2 - 1
i18n/ar.i18n.json

@@ -682,5 +682,6 @@
     "error-undefined": "Something went wrong",
     "error-ldap-login": "An error occurred while trying to login",
     "display-authentication-method": "Display Authentication Method",
-    "default-authentication-method": "Default Authentication Method"
+    "default-authentication-method": "Default Authentication Method",
+    "duplicate-board": "Duplicate Board"
 }

+ 2 - 1
i18n/bg.i18n.json

@@ -682,5 +682,6 @@
     "error-undefined": "Something went wrong",
     "error-ldap-login": "An error occurred while trying to login",
     "display-authentication-method": "Display Authentication Method",
-    "default-authentication-method": "Default Authentication Method"
+    "default-authentication-method": "Default Authentication Method",
+    "duplicate-board": "Duplicate Board"
 }

+ 2 - 1
i18n/br.i18n.json

@@ -682,5 +682,6 @@
     "error-undefined": "Something went wrong",
     "error-ldap-login": "An error occurred while trying to login",
     "display-authentication-method": "Display Authentication Method",
-    "default-authentication-method": "Default Authentication Method"
+    "default-authentication-method": "Default Authentication Method",
+    "duplicate-board": "Duplicate Board"
 }

+ 2 - 1
i18n/ca.i18n.json

@@ -682,5 +682,6 @@
     "error-undefined": "Something went wrong",
     "error-ldap-login": "An error occurred while trying to login",
     "display-authentication-method": "Display Authentication Method",
-    "default-authentication-method": "Default Authentication Method"
+    "default-authentication-method": "Default Authentication Method",
+    "duplicate-board": "Duplicate Board"
 }

+ 2 - 1
i18n/cs.i18n.json

@@ -682,5 +682,6 @@
     "error-undefined": "Něco se pokazilo",
     "error-ldap-login": "Během přihlašování nastala chyba",
     "display-authentication-method": "Zobraz způsob ověřování",
-    "default-authentication-method": "Zobraz způsob ověřování"
+    "default-authentication-method": "Zobraz způsob ověřování",
+    "duplicate-board": "Duplicate Board"
 }

+ 2 - 1
i18n/da.i18n.json

@@ -682,5 +682,6 @@
     "error-undefined": "Something went wrong",
     "error-ldap-login": "An error occurred while trying to login",
     "display-authentication-method": "Display Authentication Method",
-    "default-authentication-method": "Default Authentication Method"
+    "default-authentication-method": "Default Authentication Method",
+    "duplicate-board": "Duplicate Board"
 }

+ 6 - 5
i18n/de.i18n.json

@@ -576,16 +576,16 @@
     "r-rule": "Regel",
     "r-add-trigger": "Auslöser hinzufügen",
     "r-add-action": "Aktion hinzufügen",
-    "r-board-rules": "Board Regeln",
+    "r-board-rules": "Boardregeln",
     "r-add-rule": "Regel hinzufügen",
     "r-view-rule": "Regel anzeigen",
     "r-delete-rule": "Regel löschen",
     "r-new-rule-name": "Neuer Regeltitel",
     "r-no-rules": "Keine Regeln",
-    "r-when-a-card": "Wenn eine Karte",
-    "r-is": "ist",
+    "r-when-a-card": "Wenn Karte",
+    "r-is": "wird",
     "r-is-moved": "verschoben wird",
-    "r-added-to": "hinzugefügt wird zu",
+    "r-added-to": "hinzugefügt zu",
     "r-removed-from": "Entfernt von",
     "r-the-board": "das Board",
     "r-list": "Liste",
@@ -682,5 +682,6 @@
     "error-undefined": "Etwas ist schief gelaufen",
     "error-ldap-login": "Es ist ein Fehler beim Anmelden aufgetreten",
     "display-authentication-method": "Anzeige Authentifizierungsverfahren",
-    "default-authentication-method": "Standardauthentifizierungsverfahren"
+    "default-authentication-method": "Standardauthentifizierungsverfahren",
+    "duplicate-board": "Duplicate Board"
 }

+ 2 - 1
i18n/el.i18n.json

@@ -682,5 +682,6 @@
     "error-undefined": "Something went wrong",
     "error-ldap-login": "An error occurred while trying to login",
     "display-authentication-method": "Display Authentication Method",
-    "default-authentication-method": "Default Authentication Method"
+    "default-authentication-method": "Default Authentication Method",
+    "duplicate-board": "Duplicate Board"
 }

+ 2 - 1
i18n/en-GB.i18n.json

@@ -682,5 +682,6 @@
     "error-undefined": "Something went wrong",
     "error-ldap-login": "An error occurred while trying to login",
     "display-authentication-method": "Display Authentication Method",
-    "default-authentication-method": "Default Authentication Method"
+    "default-authentication-method": "Default Authentication Method",
+    "duplicate-board": "Duplicate Board"
 }

+ 2 - 1
i18n/en.i18n.json

@@ -685,5 +685,6 @@
     "error-undefined": "Something went wrong",
     "error-ldap-login": "An error occurred while trying to login",
     "display-authentication-method": "Display Authentication Method",
-    "default-authentication-method": "Default Authentication Method"
+    "default-authentication-method": "Default Authentication Method",
+    "duplicate-board": "Duplicate Board"
 }

+ 2 - 1
i18n/eo.i18n.json

@@ -682,5 +682,6 @@
     "error-undefined": "Something went wrong",
     "error-ldap-login": "An error occurred while trying to login",
     "display-authentication-method": "Display Authentication Method",
-    "default-authentication-method": "Default Authentication Method"
+    "default-authentication-method": "Default Authentication Method",
+    "duplicate-board": "Duplicate Board"
 }

+ 2 - 1
i18n/es-AR.i18n.json

@@ -682,5 +682,6 @@
     "error-undefined": "Something went wrong",
     "error-ldap-login": "An error occurred while trying to login",
     "display-authentication-method": "Display Authentication Method",
-    "default-authentication-method": "Default Authentication Method"
+    "default-authentication-method": "Default Authentication Method",
+    "duplicate-board": "Duplicate Board"
 }

+ 2 - 1
i18n/es.i18n.json

@@ -682,5 +682,6 @@
     "error-undefined": "Algo no está bien",
     "error-ldap-login": "Ocurrió un error al intentar acceder",
     "display-authentication-method": "Mostrar el método de autenticación",
-    "default-authentication-method": "Método de autenticación por defecto"
+    "default-authentication-method": "Método de autenticación por defecto",
+    "duplicate-board": "Duplicar tablero"
 }

+ 2 - 1
i18n/eu.i18n.json

@@ -682,5 +682,6 @@
     "error-undefined": "Something went wrong",
     "error-ldap-login": "An error occurred while trying to login",
     "display-authentication-method": "Display Authentication Method",
-    "default-authentication-method": "Default Authentication Method"
+    "default-authentication-method": "Default Authentication Method",
+    "duplicate-board": "Duplicate Board"
 }

+ 2 - 1
i18n/fa.i18n.json

@@ -682,5 +682,6 @@
     "error-undefined": "یک اشتباه رخ داده شده است",
     "error-ldap-login": "هنگام تلاش برای ورود به یک خطا رخ داد",
     "display-authentication-method": "نمایش نوع اعتبارسنجی",
-    "default-authentication-method": "نوع اعتبارسنجی پیشفرض"
+    "default-authentication-method": "نوع اعتبارسنجی پیشفرض",
+    "duplicate-board": "Duplicate Board"
 }

+ 2 - 1
i18n/fi.i18n.json

@@ -682,5 +682,6 @@
     "error-undefined": "Jotain meni pieleen",
     "error-ldap-login": "Virhe tapahtui yrittäessä kirjautua sisään",
     "display-authentication-method": "Näytä kirjautumistapa",
-    "default-authentication-method": "Oletus kirjautumistapa"
+    "default-authentication-method": "Oletus kirjautumistapa",
+    "duplicate-board": "Tee kaksoiskappale taulusta"
 }

+ 2 - 1
i18n/fr.i18n.json

@@ -682,5 +682,6 @@
     "error-undefined": "Une erreur inconnue s'est produite",
     "error-ldap-login": "Une erreur s'est produite lors de la tentative de connexion",
     "display-authentication-method": "Afficher la méthode d'authentification",
-    "default-authentication-method": "Méthode d'authentification par défaut"
+    "default-authentication-method": "Méthode d'authentification par défaut",
+    "duplicate-board": "Duplicate Board"
 }

+ 2 - 1
i18n/gl.i18n.json

@@ -682,5 +682,6 @@
     "error-undefined": "Something went wrong",
     "error-ldap-login": "An error occurred while trying to login",
     "display-authentication-method": "Display Authentication Method",
-    "default-authentication-method": "Default Authentication Method"
+    "default-authentication-method": "Default Authentication Method",
+    "duplicate-board": "Duplicate Board"
 }

+ 2 - 1
i18n/he.i18n.json

@@ -682,5 +682,6 @@
     "error-undefined": "מהו השתבש",
     "error-ldap-login": "אירעה שגיאה בעת ניסיון הכניסה",
     "display-authentication-method": "הצגת שיטת אימות",
-    "default-authentication-method": "שיטת אימות כבררת מחדל"
+    "default-authentication-method": "שיטת אימות כבררת מחדל",
+    "duplicate-board": "Duplicate Board"
 }

+ 2 - 1
i18n/hi.i18n.json

@@ -682,5 +682,6 @@
     "error-undefined": "Something went wrong",
     "error-ldap-login": "An error occurred while trying to login",
     "display-authentication-method": "Display Authentication Method",
-    "default-authentication-method": "Default Authentication Method"
+    "default-authentication-method": "Default Authentication Method",
+    "duplicate-board": "Duplicate Board"
 }

+ 2 - 1
i18n/hu.i18n.json

@@ -682,5 +682,6 @@
     "error-undefined": "Valami hiba történt",
     "error-ldap-login": "Hiba történt bejelentkezés közben",
     "display-authentication-method": "Hitelelesítési mód mutatása",
-    "default-authentication-method": "Alapértelmezett hitelesítési mód"
+    "default-authentication-method": "Alapértelmezett hitelesítési mód",
+    "duplicate-board": "Duplicate Board"
 }

+ 2 - 1
i18n/hy.i18n.json

@@ -682,5 +682,6 @@
     "error-undefined": "Something went wrong",
     "error-ldap-login": "An error occurred while trying to login",
     "display-authentication-method": "Display Authentication Method",
-    "default-authentication-method": "Default Authentication Method"
+    "default-authentication-method": "Default Authentication Method",
+    "duplicate-board": "Duplicate Board"
 }

+ 2 - 1
i18n/id.i18n.json

@@ -682,5 +682,6 @@
     "error-undefined": "Something went wrong",
     "error-ldap-login": "An error occurred while trying to login",
     "display-authentication-method": "Display Authentication Method",
-    "default-authentication-method": "Default Authentication Method"
+    "default-authentication-method": "Default Authentication Method",
+    "duplicate-board": "Duplicate Board"
 }

+ 2 - 1
i18n/ig.i18n.json

@@ -682,5 +682,6 @@
     "error-undefined": "Something went wrong",
     "error-ldap-login": "An error occurred while trying to login",
     "display-authentication-method": "Display Authentication Method",
-    "default-authentication-method": "Default Authentication Method"
+    "default-authentication-method": "Default Authentication Method",
+    "duplicate-board": "Duplicate Board"
 }

+ 2 - 1
i18n/it.i18n.json

@@ -682,5 +682,6 @@
     "error-undefined": "Qualcosa è andato storto",
     "error-ldap-login": "C'è stato un errore mentre provavi ad effettuare il login",
     "display-authentication-method": "Mostra il metodo di autenticazione",
-    "default-authentication-method": "Metodo di autenticazione predefinito"
+    "default-authentication-method": "Metodo di autenticazione predefinito",
+    "duplicate-board": "Duplicate Board"
 }

+ 2 - 1
i18n/ja.i18n.json

@@ -682,5 +682,6 @@
     "error-undefined": "Something went wrong",
     "error-ldap-login": "An error occurred while trying to login",
     "display-authentication-method": "Display Authentication Method",
-    "default-authentication-method": "Default Authentication Method"
+    "default-authentication-method": "Default Authentication Method",
+    "duplicate-board": "Duplicate Board"
 }

+ 2 - 1
i18n/ka.i18n.json

@@ -682,5 +682,6 @@
     "error-undefined": "Something went wrong",
     "error-ldap-login": "An error occurred while trying to login",
     "display-authentication-method": "Display Authentication Method",
-    "default-authentication-method": "Default Authentication Method"
+    "default-authentication-method": "Default Authentication Method",
+    "duplicate-board": "Duplicate Board"
 }

+ 2 - 1
i18n/km.i18n.json

@@ -682,5 +682,6 @@
     "error-undefined": "Something went wrong",
     "error-ldap-login": "An error occurred while trying to login",
     "display-authentication-method": "Display Authentication Method",
-    "default-authentication-method": "Default Authentication Method"
+    "default-authentication-method": "Default Authentication Method",
+    "duplicate-board": "Duplicate Board"
 }

+ 2 - 1
i18n/ko.i18n.json

@@ -682,5 +682,6 @@
     "error-undefined": "Something went wrong",
     "error-ldap-login": "An error occurred while trying to login",
     "display-authentication-method": "Display Authentication Method",
-    "default-authentication-method": "Default Authentication Method"
+    "default-authentication-method": "Default Authentication Method",
+    "duplicate-board": "Duplicate Board"
 }

+ 2 - 1
i18n/lv.i18n.json

@@ -682,5 +682,6 @@
     "error-undefined": "Something went wrong",
     "error-ldap-login": "An error occurred while trying to login",
     "display-authentication-method": "Display Authentication Method",
-    "default-authentication-method": "Default Authentication Method"
+    "default-authentication-method": "Default Authentication Method",
+    "duplicate-board": "Duplicate Board"
 }

+ 2 - 1
i18n/mk.i18n.json

@@ -682,5 +682,6 @@
     "error-undefined": "Something went wrong",
     "error-ldap-login": "An error occurred while trying to login",
     "display-authentication-method": "Display Authentication Method",
-    "default-authentication-method": "Default Authentication Method"
+    "default-authentication-method": "Default Authentication Method",
+    "duplicate-board": "Duplicate Board"
 }

+ 2 - 1
i18n/mn.i18n.json

@@ -682,5 +682,6 @@
     "error-undefined": "Something went wrong",
     "error-ldap-login": "An error occurred while trying to login",
     "display-authentication-method": "Display Authentication Method",
-    "default-authentication-method": "Default Authentication Method"
+    "default-authentication-method": "Default Authentication Method",
+    "duplicate-board": "Duplicate Board"
 }

+ 2 - 1
i18n/nb.i18n.json

@@ -682,5 +682,6 @@
     "error-undefined": "Something went wrong",
     "error-ldap-login": "An error occurred while trying to login",
     "display-authentication-method": "Display Authentication Method",
-    "default-authentication-method": "Default Authentication Method"
+    "default-authentication-method": "Default Authentication Method",
+    "duplicate-board": "Duplicate Board"
 }

+ 2 - 1
i18n/nl.i18n.json

@@ -682,5 +682,6 @@
     "error-undefined": "Something went wrong",
     "error-ldap-login": "An error occurred while trying to login",
     "display-authentication-method": "Display Authentication Method",
-    "default-authentication-method": "Default Authentication Method"
+    "default-authentication-method": "Default Authentication Method",
+    "duplicate-board": "Duplicate Board"
 }

+ 2 - 1
i18n/oc.i18n.json

@@ -682,5 +682,6 @@
     "error-undefined": "Something went wrong",
     "error-ldap-login": "An error occurred while trying to login",
     "display-authentication-method": "Display Authentication Method",
-    "default-authentication-method": "Default Authentication Method"
+    "default-authentication-method": "Default Authentication Method",
+    "duplicate-board": "Duplicate Board"
 }

+ 2 - 1
i18n/pl.i18n.json

@@ -682,5 +682,6 @@
     "error-undefined": "Coś poszło nie tak",
     "error-ldap-login": "Wystąpił błąd w trakcie logowania",
     "display-authentication-method": "Wyświetl metodę logowania",
-    "default-authentication-method": "Domyślna metoda logowania"
+    "default-authentication-method": "Domyślna metoda logowania",
+    "duplicate-board": "Duplicate Board"
 }

+ 2 - 1
i18n/pt-BR.i18n.json

@@ -682,5 +682,6 @@
     "error-undefined": "Algo deu errado",
     "error-ldap-login": "Um erro ocorreu enquanto tentava entrar",
     "display-authentication-method": "Mostrar Método de Autenticação",
-    "default-authentication-method": "Método de Autenticação Padrão"
+    "default-authentication-method": "Método de Autenticação Padrão",
+    "duplicate-board": "Duplicate Board"
 }

+ 2 - 1
i18n/pt.i18n.json

@@ -682,5 +682,6 @@
     "error-undefined": "Something went wrong",
     "error-ldap-login": "An error occurred while trying to login",
     "display-authentication-method": "Display Authentication Method",
-    "default-authentication-method": "Default Authentication Method"
+    "default-authentication-method": "Default Authentication Method",
+    "duplicate-board": "Duplicate Board"
 }

+ 2 - 1
i18n/ro.i18n.json

@@ -682,5 +682,6 @@
     "error-undefined": "Something went wrong",
     "error-ldap-login": "An error occurred while trying to login",
     "display-authentication-method": "Display Authentication Method",
-    "default-authentication-method": "Default Authentication Method"
+    "default-authentication-method": "Default Authentication Method",
+    "duplicate-board": "Duplicate Board"
 }

+ 2 - 1
i18n/ru.i18n.json

@@ -682,5 +682,6 @@
     "error-undefined": "Что-то пошло не так",
     "error-ldap-login": "Ошибка при попытке авторизации",
     "display-authentication-method": "Показывать способ авторизации",
-    "default-authentication-method": "Способ авторизации по умолчанию"
+    "default-authentication-method": "Способ авторизации по умолчанию",
+    "duplicate-board": "Duplicate Board"
 }

+ 2 - 1
i18n/sr.i18n.json

@@ -682,5 +682,6 @@
     "error-undefined": "Something went wrong",
     "error-ldap-login": "An error occurred while trying to login",
     "display-authentication-method": "Display Authentication Method",
-    "default-authentication-method": "Default Authentication Method"
+    "default-authentication-method": "Default Authentication Method",
+    "duplicate-board": "Duplicate Board"
 }

+ 2 - 1
i18n/sv.i18n.json

@@ -682,5 +682,6 @@
     "error-undefined": "Något gick fel",
     "error-ldap-login": "Ett fel uppstod när du försökte logga in",
     "display-authentication-method": "Visa autentiseringsmetod",
-    "default-authentication-method": "Standard autentiseringsmetod"
+    "default-authentication-method": "Standard autentiseringsmetod",
+    "duplicate-board": "Duplicate Board"
 }

+ 2 - 1
i18n/sw.i18n.json

@@ -682,5 +682,6 @@
     "error-undefined": "Something went wrong",
     "error-ldap-login": "An error occurred while trying to login",
     "display-authentication-method": "Display Authentication Method",
-    "default-authentication-method": "Default Authentication Method"
+    "default-authentication-method": "Default Authentication Method",
+    "duplicate-board": "Duplicate Board"
 }

+ 2 - 1
i18n/ta.i18n.json

@@ -682,5 +682,6 @@
     "error-undefined": "Something went wrong",
     "error-ldap-login": "An error occurred while trying to login",
     "display-authentication-method": "Display Authentication Method",
-    "default-authentication-method": "Default Authentication Method"
+    "default-authentication-method": "Default Authentication Method",
+    "duplicate-board": "Duplicate Board"
 }

+ 2 - 1
i18n/th.i18n.json

@@ -682,5 +682,6 @@
     "error-undefined": "Something went wrong",
     "error-ldap-login": "An error occurred while trying to login",
     "display-authentication-method": "Display Authentication Method",
-    "default-authentication-method": "Default Authentication Method"
+    "default-authentication-method": "Default Authentication Method",
+    "duplicate-board": "Duplicate Board"
 }

+ 2 - 1
i18n/tr.i18n.json

@@ -682,5 +682,6 @@
     "error-undefined": "Bir şeyler yanlış gitti",
     "error-ldap-login": "Giriş yapmaya çalışırken bir hata oluştu",
     "display-authentication-method": "Display Authentication Method",
-    "default-authentication-method": "Default Authentication Method"
+    "default-authentication-method": "Default Authentication Method",
+    "duplicate-board": "Duplicate Board"
 }

+ 2 - 1
i18n/uk.i18n.json

@@ -682,5 +682,6 @@
     "error-undefined": "Something went wrong",
     "error-ldap-login": "An error occurred while trying to login",
     "display-authentication-method": "Display Authentication Method",
-    "default-authentication-method": "Default Authentication Method"
+    "default-authentication-method": "Default Authentication Method",
+    "duplicate-board": "Duplicate Board"
 }

+ 2 - 1
i18n/vi.i18n.json

@@ -682,5 +682,6 @@
     "error-undefined": "Something went wrong",
     "error-ldap-login": "An error occurred while trying to login",
     "display-authentication-method": "Display Authentication Method",
-    "default-authentication-method": "Default Authentication Method"
+    "default-authentication-method": "Default Authentication Method",
+    "duplicate-board": "Duplicate Board"
 }

+ 2 - 1
i18n/zh-CN.i18n.json

@@ -682,5 +682,6 @@
     "error-undefined": "出了点问题",
     "error-ldap-login": "尝试登陆时出错",
     "display-authentication-method": "显示认证方式",
-    "default-authentication-method": "缺省认证方式"
+    "default-authentication-method": "缺省认证方式",
+    "duplicate-board": "Duplicate Board"
 }

+ 2 - 1
i18n/zh-TW.i18n.json

@@ -682,5 +682,6 @@
     "error-undefined": "Something went wrong",
     "error-ldap-login": "An error occurred while trying to login",
     "display-authentication-method": "Display Authentication Method",
-    "default-authentication-method": "Default Authentication Method"
+    "default-authentication-method": "Default Authentication Method",
+    "duplicate-board": "Duplicate Board"
 }

+ 4 - 0
models/cards.js

@@ -1338,6 +1338,7 @@ function cardMove(userId, doc, fieldNames, oldListId, oldSwimlaneId, oldBoardId)
       listId: doc.listId,
       boardId: doc.boardId,
       cardId: doc._id,
+      cardTitle:doc.title,
       swimlaneName: Swimlanes.findOne(doc.swimlaneId).title,
       swimlaneId: doc.swimlaneId,
       oldSwimlaneId,
@@ -1403,6 +1404,9 @@ function cardMembers(userId, doc, fieldNames, modifier) {
         activityType: 'unjoinMember',
         boardId: doc.boardId,
         cardId: doc._id,
+        memberId,
+        listId: doc.listId,
+        swimlaneId: doc.swimlaneId,
       });
     }
   }

+ 9 - 16
models/export.js

@@ -6,34 +6,27 @@ if (Meteor.isServer) {
   // `ApiRoutes.path('boards/export', boardId)``
   // on the client instead of copy/pasting the route path manually between the
   // client and the server.
-  /**
-   * @operation export
-   * @tag Boards
-   *
-   * @summary This route is used to export the board.
-   *
-   * @description If user is already logged-in, pass loginToken as param
-   * "authToken": '/api/boards/:boardId/export?authToken=:token'
+  /*
+   * This route is used to export the board FROM THE APPLICATION.
+   * If user is already logged-in, pass loginToken as param "authToken":
+   * '/api/boards/:boardId/export?authToken=:token'
    *
    * See https://blog.kayla.com.au/server-side-route-authentication-in-meteor/
    * for detailed explanations
-   *
-   * @param {string} boardId the ID of the board we are exporting
-   * @param {string} authToken the loginToken
    */
+
+
   JsonRoutes.add('get', '/api/boards/:boardId/export', function(req, res) {
     const boardId = req.params.boardId;
     let user = null;
-
+    // todo XXX for real API, first look for token in Authentication: header
+    // then fallback to parameter
     const loginToken = req.query.authToken;
     if (loginToken) {
       const hashToken = Accounts._hashLoginToken(loginToken);
       user = Meteor.users.findOne({
         'services.resume.loginTokens.hashedToken': hashToken,
       });
-    } else if (!Meteor.settings.public.sandstorm) {
-      Authentication.checkUserId(req.userId);
-      user = Users.findOne({ _id: req.userId, isAdmin: true });
     }
 
     const exporter = new Exporter(boardId);
@@ -50,7 +43,7 @@ if (Meteor.isServer) {
   });
 }
 
-class Exporter {
+export class Exporter {
   constructor(boardId) {
     this._boardId = boardId;
   }

+ 19 - 0
models/import.js

@@ -1,5 +1,7 @@
 import { TrelloCreator } from './trelloCreator';
 import { WekanCreator } from './wekanCreator';
+import {Exporter} from './export';
+import wekanMembersMapper from './wekanmapper';
 
 Meteor.methods({
   importBoard(board, data, importSource, currentBoard) {
@@ -27,3 +29,20 @@ Meteor.methods({
     return creator.create(board, currentBoard);
   },
 });
+
+Meteor.methods({
+  cloneBoard(sourceBoardId, currentBoardId) {
+    check(sourceBoardId, String);
+    check(currentBoardId, Match.Maybe(String));
+    const exporter = new Exporter(sourceBoardId);
+    const data = exporter.build();
+    const addData = {};
+    addData.membersMapping = wekanMembersMapper.getMembersToMap(data);
+    const creator =  new WekanCreator(addData);
+    //data.title = `${data.title  } - ${  TAPi18n.__('copy-tag')}`;
+    data.title = `${data.title}`;
+    return creator.create(data, currentBoardId);
+  },
+});
+
+

+ 25 - 0
models/wekanCreator.js

@@ -169,6 +169,31 @@ export class WekanCreator {
     })]);
   }
 
+  getMembersToMap(data) {
+  // we will work on the list itself (an ordered array of objects) when a
+  // mapping is done, we add a 'wekan' field to the object representing the
+  // imported member
+    const membersToMap = data.members;
+    const users = data.users;
+    // auto-map based on username
+    membersToMap.forEach((importedMember) => {
+      importedMember.id = importedMember.userId;
+      delete importedMember.userId;
+      const user = users.filter((user) => {
+        return user._id === importedMember.id;
+      })[0];
+      if (user.profile && user.profile.fullname) {
+        importedMember.fullName = user.profile.fullname;
+      }
+      importedMember.username = user.username;
+      const wekanUser = Users.findOne({ username: importedMember.username });
+      if (wekanUser) {
+        importedMember.wekanId = wekanUser._id;
+      }
+    });
+    return membersToMap;
+  }
+
   checkActions(wekanActions) {
     // XXX More check based on action type
     check(wekanActions, [Match.ObjectIncluding({

+ 24 - 0
models/wekanmapper.js

@@ -0,0 +1,24 @@
+export function getMembersToMap(data) {
+  // we will work on the list itself (an ordered array of objects) when a
+  // mapping is done, we add a 'wekan' field to the object representing the
+  // imported member
+  const membersToMap = data.members;
+  const users = data.users;
+  // auto-map based on username
+  membersToMap.forEach((importedMember) => {
+    importedMember.id = importedMember.userId;
+    delete importedMember.userId;
+    const user = users.filter((user) => {
+      return user._id === importedMember.id;
+    })[0];
+    if (user.profile && user.profile.fullname) {
+      importedMember.fullName = user.profile.fullname;
+    }
+    importedMember.username = user.username;
+    const wekanUser = Users.findOne({ username: importedMember.username });
+    if (wekanUser) {
+      importedMember.wekanId = wekanUser._id;
+    }
+  });
+  return membersToMap;
+}

+ 1 - 1
package.json

@@ -1,6 +1,6 @@
 {
   "name": "wekan",
-  "version": "v2.57.0",
+  "version": "v2.58.0",
   "description": "Open-Source kanban",
   "private": true,
   "scripts": {

+ 2 - 2
sandstorm-pkgdef.capnp

@@ -22,10 +22,10 @@ const pkgdef :Spk.PackageDefinition = (
     appTitle = (defaultText = "Wekan"),
     # The name of the app as it is displayed to the user.
 
-    appVersion = 259,
+    appVersion = 260,
     # Increment this for every release.
 
-    appMarketingVersion = (defaultText = "2.57.0~2019-04-02"),
+    appMarketingVersion = (defaultText = "2.58.0~2019-04-06"),
     # Human-readable presentation of the app version.
 
     minUpgradableAppVersion = 0,

+ 3 - 1
server/rulesHelper.js

@@ -141,13 +141,15 @@ RulesHelper = {
       Swimlanes.insert({
         title: action.swimlaneName,
         boardId,
+        sort: 0,
       });
     }
     if(action.actionType === 'addChecklistWithItems'){
       const checkListId = Checklists.insert({'title':action.checklistName, 'cardId':card._id, 'sort':0});
       const itemsArray = action.checklistItems.split(',');
+      const checkList = Checklists.findOne({_id:checkListId});
       for(let i = 0; i <itemsArray.length; i++){
-        ChecklistItems.insert({title:itemsArray[i], checklistId:checkListId, cardId:card._id, 'sort':0});
+        ChecklistItems.insert({title:itemsArray[i], checklistId:checkListId, cardId:card._id, 'sort':checkList.itemCount()});
       }
     }
     if(action.actionType === 'createCard'){

+ 3 - 3
server/triggersDef.js

@@ -3,13 +3,13 @@ TriggersDef = {
     matchingFields: ['boardId', 'listName', 'userId', 'swimlaneName', 'cardTitle'],
   },
   moveCard:{
-    matchingFields: ['boardId', 'listName', 'oldListName', 'userId', 'swimlaneName'],
+    matchingFields: ['boardId', 'listName', 'oldListName', 'userId', 'swimlaneName', 'cardTitle'],
   },
   archivedCard:{
-    matchingFields: ['boardId', 'userId'],
+    matchingFields: ['boardId', 'userId', 'cardTitle'],
   },
   restoredCard:{
-    matchingFields: ['boardId', 'userId'],
+    matchingFields: ['boardId', 'userId', 'cardTitle'],
   },
   joinMember:{
     matchingFields: ['boardId', 'username', 'userId'],