Browse Source

Merge branch 'devel'

Lauri Ojansivu 7 years ago
parent
commit
6a0e4c9b21

+ 21 - 0
CHANGELOG.md

@@ -1,3 +1,24 @@
+# v1.19 2018-07-16 Wekan release
+
+This release adds the following new features:
+
+- [Build from source on macOS](https://github.com/wekan/wekan/wiki/Mac);
+- [Wekan integration with OpenShift](https://github.com/wekan/wekan/pull/1765);
+- [Snap Caddy: set -agree flag for Let's Encrypt](https://github.com/wekan/wekan-snap/issues/54).
+
+and fixes the following mobile bugs:
+
+- [Fix missing utility function](https://github.com/wekan/wekan/commit/5c774070617357c25c7bb35b43f4b122eb4b3e34);
+- [Avoid default behavior](https://github.com/wekan/wekan/commit/9c204d9bbe4845bc3e352e839615dfb782a753f4);
+- [Hotfix more sortable elements](https://github.com/wekan/wekan/commit/616dade81c25b10fc409aee1bcc9a93ddbfee81b);
+- [Hotfix for mobile device](https://github.com/wekan/wekan/commit/43d86d7d5d3f3b34b0500f6d5d3afe7bd86b0060).
+
+and fixes the following bugs:
+
+- [Fix invitation code](https://github.com/wekan/wekan/pull/1777).
+
+Thanks to GitHub users adyachok, Akuket, halunk3, Haocen and xet7 for their contributions.
+
 # v1.18 2018-07-06 Wekan release
 
 This release fixes the following bugs:

+ 0 - 1
README.md

@@ -14,7 +14,6 @@
 [![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)
-[![Greenkeeper badge](https://badges.greenkeeper.io/wekan/wekan.svg)](https://greenkeeper.io/)
 
 Please read [FAQ](https://github.com/wekan/wekan/wiki/FAQ).
 Please don't feed the trolls and spammers that are mentioned in the FAQ :)

+ 4 - 1
client/components/boards/boardBody.js

@@ -1,5 +1,5 @@
 const subManager = new SubsManager();
-const { calculateIndex } = Utils;
+const { calculateIndex, enableClickOnTouch } = Utils;
 
 BlazeComponent.extendComponent({
   onCreated() {
@@ -74,6 +74,9 @@ BlazeComponent.extendComponent({
       },
     });
 
+    // ugly touch event hotfix
+    enableClickOnTouch('.js-swimlane:not(.placeholder)');
+
     function userIsMember() {
       return Meteor.user() && Meteor.user().isBoardMember() && !Meteor.user().isCommentOnly();
     }

+ 7 - 1
client/components/cards/cardDetails.js

@@ -1,5 +1,5 @@
 const subManager = new SubsManager();
-const { calculateIndexData } = Utils;
+const { calculateIndexData, enableClickOnTouch } = Utils;
 
 BlazeComponent.extendComponent({
   mixins() {
@@ -132,6 +132,9 @@ BlazeComponent.extendComponent({
       },
     });
 
+    // ugly touch event hotfix
+    enableClickOnTouch('.card-checklist-items .js-checklist');
+
     const $subtasksDom = this.$('.card-subtasks-items');
 
     $subtasksDom.sortable({
@@ -167,6 +170,9 @@ BlazeComponent.extendComponent({
       },
     });
 
+    // ugly touch event hotfix
+    enableClickOnTouch('.card-subtasks-items .js-subtasks');
+
     function userIsMember() {
       return Meteor.user() && Meteor.user().isBoardMember();
     }

+ 4 - 1
client/components/cards/checklists.js

@@ -1,4 +1,4 @@
-const { calculateIndexData } = Utils;
+const { calculateIndexData, enableClickOnTouch } = Utils;
 
 function initSorting(items) {
   items.sortable({
@@ -36,6 +36,9 @@ function initSorting(items) {
       checklistItem.move(checklistId, sortIndex.base);
     },
   });
+
+  // ugly touch event hotfix
+  enableClickOnTouch('.js-checklist-item:not(.placeholder)');
 }
 
 BlazeComponent.extendComponent({

+ 4 - 1
client/components/lists/list.js

@@ -1,4 +1,4 @@
-const { calculateIndex } = Utils;
+const { calculateIndex, enableClickOnTouch } = Utils;
 
 BlazeComponent.extendComponent({
   // Proxy
@@ -83,6 +83,9 @@ BlazeComponent.extendComponent({
       },
     });
 
+    // ugly touch event hotfix
+    enableClickOnTouch(itemsSelector);
+
     // Disable drag-dropping if the current user is not a board member or is comment only
     this.autorun(() => {
       $cards.sortable('option', 'disabled', !userIsMember());

+ 1 - 1
client/components/main/header.styl

@@ -218,7 +218,7 @@
       position: absolute
       right: 0px
       padding: 10px
-      margin: -10px
+      margin: -10px 0 -10px -10px
 
 .announcement,
 .offline-warning

+ 11 - 7
client/components/mixins/perfectScrollbar.js

@@ -1,12 +1,16 @@
+const { isTouchDevice } = Utils;
+
 Mixins.PerfectScrollbar = BlazeComponent.extendComponent({
   onRendered() {
-    const component = this.mixinParent();
-    const domElement = component.find('.js-perfect-scrollbar');
-    Ps.initialize(domElement);
+    if (!isTouchDevice()) {
+      const component = this.mixinParent();
+      const domElement = component.find('.js-perfect-scrollbar');
+      Ps.initialize(domElement);
 
-    // XXX We should create an event map to be consistent with other components
-    // but since BlazeComponent doesn't merge Mixins events transparently I
-    // prefered to use a jQuery event (which is what an event map ends up doing)
-    component.$(domElement).on('mouseenter', () => Ps.update(domElement));
+      // XXX We should create an event map to be consistent with other components
+      // but since BlazeComponent doesn't merge Mixins events transparently I
+      // prefered to use a jQuery event (which is what an event map ends up doing)
+      component.$(domElement).on('mouseenter', () => Ps.update(domElement));
+    }
   },
 });

+ 12 - 5
client/components/settings/invitationCode.js

@@ -1,6 +1,13 @@
-Template.invitationCode.onRendered(() => {
-  const setting = Settings.findOne();
-  if (!setting || !setting.disableRegistration) {
-    $('#invitationcode').hide();
-  }
+Template.invitationCode.onRendered(function() {
+  Meteor.subscribe('setting', {
+    onReady() {
+      const setting = Settings.findOne();
+
+      if (!setting || !setting.disableRegistration) {
+        $('#invitationcode').hide();
+      }
+
+      return this.stop();
+    },
+  });
 });

+ 4 - 1
client/components/swimlanes/swimlanes.js

@@ -1,4 +1,4 @@
-const { calculateIndex } = Utils;
+const { calculateIndex, enableClickOnTouch } = Utils;
 
 function currentCardIsInThisList(listId, swimlaneId) {
   const currentCard = Cards.findOne(Session.get('currentCard'));
@@ -66,6 +66,9 @@ function initSortable(boardComponent, $listsDom) {
     },
   });
 
+  // ugly touch event hotfix
+  enableClickOnTouch('.js-list:not(.js-list-composer)');
+
   function userIsMember() {
     return Meteor.user() && Meteor.user().isBoardMember() && !Meteor.user().isCommentOnly();
   }

+ 49 - 0
client/lib/utils.js

@@ -95,6 +95,55 @@ Utils = {
       increment,
     };
   },
+
+  // Detect touch device
+  isTouchDevice() {
+    const isTouchable = (() => {
+      const prefixes = ' -webkit- -moz- -o- -ms- '.split(' ');
+      const mq = function(query) {
+        return window.matchMedia(query).matches;
+      };
+
+      if (('ontouchstart' in window) || window.DocumentTouch && document instanceof window.DocumentTouch) {
+        return true;
+      }
+
+      // include the 'heartz' as a way to have a non matching MQ to help terminate the join
+      // https://git.io/vznFH
+      const query = ['(', prefixes.join('touch-enabled),('), 'heartz', ')'].join('');
+      return mq(query);
+    })();
+    Utils.isTouchDevice = () => isTouchable;
+    return isTouchable;
+  },
+
+  calculateTouchDistance(touchA, touchB) {
+    return Math.sqrt(
+      Math.pow(touchA.screenX - touchB.screenX, 2) +
+      Math.pow(touchA.screenY - touchB.screenY, 2)
+    );
+  },
+
+  enableClickOnTouch(selector) {
+    let touchStart = null;
+    let lastTouch = null;
+
+    $(document).on('touchstart', selector, function(e) {
+      touchStart = e.originalEvent.touches[0];
+    });
+    $(document).on('touchmove', selector, function(e) {
+      const touches = e.originalEvent.touches;
+      lastTouch = touches[touches.length - 1];
+    });
+    $(document).on('touchend', selector, function(e) {
+      if (touchStart && lastTouch && Utils.calculateTouchDistance(touchStart, lastTouch) <= 20) {
+        e.preventDefault();
+        const clickEvent = document.createEvent('MouseEvents');
+        clickEvent.initEvent('click', true, true);
+        e.target.dispatchEvent(clickEvent);
+      }
+    });
+  },
 };
 
 // A simple tracker dependency that we invalidate every time the window is

+ 23 - 23
i18n/de.i18n.json

@@ -2,7 +2,7 @@
     "accept": "Akzeptieren",
     "act-activity-notify": "[Wekan] Aktivitätsbenachrichtigung",
     "act-addAttachment": "hat __attachment__ an __card__ angehängt",
-    "act-addSubtask": "added subtask __checklist__ to __card__",
+    "act-addSubtask": "hat die Teilaufgabe __checklist__ zu __card__ hinzugefügt",
     "act-addChecklist": "hat die Checkliste __checklist__ zu __card__ hinzugefügt",
     "act-addChecklistItem": "hat __checklistItem__ zur Checkliste __checklist__ in __card__ hinzugefügt",
     "act-addComment": "hat __card__ kommentiert: __comment__",
@@ -42,7 +42,7 @@
     "activity-removed": "hat %s von %s entfernt",
     "activity-sent": "hat %s an %s gesendet",
     "activity-unjoined": "hat %s verlassen",
-    "activity-subtask-added": "added subtask to %s",
+    "activity-subtask-added": "Teilaufgabe zu %s hinzugefügt",
     "activity-checklist-added": "hat eine Checkliste zu %s hinzugefügt",
     "activity-checklist-item-added": "hat eine Checklistenposition zu '%s' in %s hinzugefügt",
     "add": "Hinzufügen",
@@ -50,7 +50,7 @@
     "add-board": "neues Board",
     "add-card": "Karte hinzufügen",
     "add-swimlane": "Swimlane hinzufügen",
-    "add-subtask": "Add Subtask",
+    "add-subtask": "Teilaufgabe hinzufügen",
     "add-checklist": "Checkliste hinzufügen",
     "add-checklist-item": "Position zu einer Checkliste hinzufügen",
     "add-cover": "Cover hinzufügen",
@@ -134,7 +134,7 @@
     "cardMorePopup-title": "Mehr",
     "cards": "Karten",
     "cards-count": "Karten",
-    "casSignIn": "Sign In with CAS",
+    "casSignIn": "Mit CAS anmelden",
     "change": "Ändern",
     "change-avatar": "Profilbild ändern",
     "change-password": "Passwort ändern",
@@ -145,7 +145,7 @@
     "changePasswordPopup-title": "Passwort ändern",
     "changePermissionsPopup-title": "Berechtigungen ändern",
     "changeSettingsPopup-title": "Einstellungen ändern",
-    "subtasks": "Subtasks",
+    "subtasks": "Teilaufgaben",
     "checklists": "Checklisten",
     "click-to-star": "Klicken Sie, um das Board mit einem Stern zu markieren.",
     "click-to-unstar": "Klicken Sie, um den Stern vom Board zu entfernen.",
@@ -168,8 +168,8 @@
     "comment-only": "Nur kommentierbar",
     "comment-only-desc": "Kann Karten nur Kommentieren",
     "computer": "Computer",
-    "confirm-subtask-delete-dialog": "Are you sure you want to delete subtask?",
-    "confirm-checklist-delete-dialog": "Are you sure you want to delete checklist?",
+    "confirm-subtask-delete-dialog": "Teilaufgabe wirklich löschen?",
+    "confirm-checklist-delete-dialog": "Checkliste wirklich löschen?",
     "copy-card-link-to-clipboard": "Kopiere Link zur Karte in die Zwischenablage",
     "copyCardPopup-title": "Karte kopieren",
     "copyChecklistToManyCardsPopup-title": "Checklistenvorlage in mehrere Karten kopieren",
@@ -482,21 +482,21 @@
     "delete-board-confirm-popup": "Alle Listen, Karten, Labels und Akivitäten werden gelöscht und Sie können die Inhalte des Boards nicht wiederherstellen! Die Aktion kann nicht rückgängig gemacht werden.",
     "boardDeletePopup-title": "Board löschen?",
     "delete-board": "Board löschen",
-    "default-subtasks-board": "Subtasks for __board__ board",
-    "default": "Default",
+    "default-subtasks-board": "Teilaufgabe für __board__ Board",
+    "default": "Standard",
     "queue": "Queue",
-    "subtask-settings": "Subtasks Settings",
-    "boardSubtaskSettingsPopup-title": "Board Subtasks Settings",
-    "show-subtasks-field": "Cards can have subtasks",
-    "deposit-subtasks-board": "Deposit subtasks to this board:",
-    "deposit-subtasks-list": "Landing list for subtasks deposited here:",
-    "show-parent-in-minicard": "Show parent in minicard:",
-    "prefix-with-full-path": "Prefix with full path",
-    "prefix-with-parent": "Prefix with parent",
-    "subtext-with-full-path": "Subtext with full path",
-    "subtext-with-parent": "Subtext with parent",
-    "change-card-parent": "Change card's parent",
-    "parent-card": "Parent card",
-    "source-board": "Source board",
-    "no-parent": "Don't show parent"
+    "subtask-settings": "Teilaufgaben Einstellungen",
+    "boardSubtaskSettingsPopup-title": "Board Teilaufgaben Einstellungen",
+    "show-subtasks-field": "Karten können Teilaufgaben haben",
+    "deposit-subtasks-board": "Teilaufgaben zu diesem Board hinterlegen:",
+    "deposit-subtasks-list": "Landing-Liste für die hinterlegten Teilaufgaben:",
+    "show-parent-in-minicard": "Zeige übergeordnetes Element auf Minikarte",
+    "prefix-with-full-path": "Prefix mit vollständigem Pfad",
+    "prefix-with-parent": "Präfix mit übergeordneten Element",
+    "subtext-with-full-path": "Subtext mit vollständigem Pfad",
+    "subtext-with-parent": "Subtext mit übergeordneten Element",
+    "change-card-parent": "Ändere übergeordnete Karte",
+    "parent-card": "Übergeordnete Karte",
+    "source-board": "Quell Board",
+    "no-parent": "Eltern nicht zeigen"
 }

+ 23 - 23
i18n/fr.i18n.json

@@ -2,7 +2,7 @@
     "accept": "Accepter",
     "act-activity-notify": "[Wekan] Notification d'activité",
     "act-addAttachment": "a joint __attachment__ à __card__",
-    "act-addSubtask": "added subtask __checklist__ to __card__",
+    "act-addSubtask": "a ajouté une sous-tâche __checklist__ à __card__",
     "act-addChecklist": "a ajouté la checklist __checklist__ à __card__",
     "act-addChecklistItem": "a ajouté l'élément __checklistItem__ à la checklist __checklist__ de __card__",
     "act-addComment": "a commenté __card__ : __comment__",
@@ -42,7 +42,7 @@
     "activity-removed": "a supprimé %s de %s",
     "activity-sent": "a envoyé %s vers %s",
     "activity-unjoined": "a quitté %s",
-    "activity-subtask-added": "added subtask to %s",
+    "activity-subtask-added": "a ajouté une sous-tâche à %s",
     "activity-checklist-added": "a ajouté une checklist à %s",
     "activity-checklist-item-added": "a ajouté un élément à la checklist '%s' dans %s",
     "add": "Ajouter",
@@ -50,7 +50,7 @@
     "add-board": "Ajouter un tableau",
     "add-card": "Ajouter une carte",
     "add-swimlane": "Ajouter un couloir",
-    "add-subtask": "Add Subtask",
+    "add-subtask": "Ajouter une sous-tâche",
     "add-checklist": "Ajouter une checklist",
     "add-checklist-item": "Ajouter un élément à la checklist",
     "add-cover": "Ajouter la couverture",
@@ -134,7 +134,7 @@
     "cardMorePopup-title": "Plus",
     "cards": "Cartes",
     "cards-count": "Cartes",
-    "casSignIn": "Sign In with CAS",
+    "casSignIn": "Se connecter avec CAS",
     "change": "Modifier",
     "change-avatar": "Modifier l'avatar",
     "change-password": "Modifier le mot de passe",
@@ -145,7 +145,7 @@
     "changePasswordPopup-title": "Modifier le mot de passe",
     "changePermissionsPopup-title": "Modifier les permissions",
     "changeSettingsPopup-title": "Modifier les paramètres",
-    "subtasks": "Subtasks",
+    "subtasks": "Sous-tâches",
     "checklists": "Checklists",
     "click-to-star": "Cliquez pour ajouter ce tableau aux favoris.",
     "click-to-unstar": "Cliquez pour retirer ce tableau des favoris.",
@@ -168,8 +168,8 @@
     "comment-only": "Commentaire uniquement",
     "comment-only-desc": "Ne peut que commenter des cartes.",
     "computer": "Ordinateur",
-    "confirm-subtask-delete-dialog": "Are you sure you want to delete subtask?",
-    "confirm-checklist-delete-dialog": "Are you sure you want to delete checklist?",
+    "confirm-subtask-delete-dialog": "Êtes-vous sûr de vouloir supprimer la sous-tâche ?",
+    "confirm-checklist-delete-dialog": "Êtes-vous sûr de vouloir supprimer la checklist ?",
     "copy-card-link-to-clipboard": "Copier le lien vers la carte dans le presse-papier",
     "copyCardPopup-title": "Copier la carte",
     "copyChecklistToManyCardsPopup-title": "Copier le modèle de checklist vers plusieurs cartes",
@@ -482,21 +482,21 @@
     "delete-board-confirm-popup": "Toutes les listes, cartes, étiquettes et activités seront supprimées et vous ne pourrez pas retrouver le contenu du tableau. Il n'y a pas d'annulation possible.",
     "boardDeletePopup-title": "Supprimer le tableau ?",
     "delete-board": "Supprimer le tableau",
-    "default-subtasks-board": "Subtasks for __board__ board",
-    "default": "Default",
+    "default-subtasks-board": "Sous-tâches du tableau __board__",
+    "default": "Défaut",
     "queue": "Queue",
-    "subtask-settings": "Subtasks Settings",
-    "boardSubtaskSettingsPopup-title": "Board Subtasks Settings",
-    "show-subtasks-field": "Cards can have subtasks",
-    "deposit-subtasks-board": "Deposit subtasks to this board:",
-    "deposit-subtasks-list": "Landing list for subtasks deposited here:",
-    "show-parent-in-minicard": "Show parent in minicard:",
-    "prefix-with-full-path": "Prefix with full path",
-    "prefix-with-parent": "Prefix with parent",
-    "subtext-with-full-path": "Subtext with full path",
-    "subtext-with-parent": "Subtext with parent",
-    "change-card-parent": "Change card's parent",
-    "parent-card": "Parent card",
-    "source-board": "Source board",
-    "no-parent": "Don't show parent"
+    "subtask-settings": "Paramètres des sous-tâches",
+    "boardSubtaskSettingsPopup-title": "Paramètres des sous-tâches du tableau",
+    "show-subtasks-field": "Les cartes peuvent avoir des sous-tâches",
+    "deposit-subtasks-board": "Déposer des sous-tâches dans ce tableau :",
+    "deposit-subtasks-list": "Liste de destination pour les sous-tâches déposées ici :",
+    "show-parent-in-minicard": "Voir le parent dans la mini-carte :",
+    "prefix-with-full-path": "Préfixer avec le chemin complet",
+    "prefix-with-parent": "Préfixer avec le parent",
+    "subtext-with-full-path": "Sous-texte avec le chemin complet",
+    "subtext-with-parent": "Sous-texte avec le parent",
+    "change-card-parent": "Changer le parent de la carte",
+    "parent-card": "Carte parente",
+    "source-board": "Tableau source",
+    "no-parent": "Ne pas afficher le parent"
 }

+ 170 - 170
i18n/ka.i18n.json

@@ -1,12 +1,12 @@
 {
-    "accept": "Accept",
-    "act-activity-notify": "[Wekan] Activity Notification",
+    "accept": "დათანხმება",
+    "act-activity-notify": "[ვეკანი] აქტივობის შეტყობინება",
     "act-addAttachment": "attached __attachment__ to __card__",
     "act-addSubtask": "added subtask __checklist__ to __card__",
     "act-addChecklist": "added checklist __checklist__ to __card__",
     "act-addChecklistItem": "added __checklistItem__ to checklist __checklist__ on __card__",
     "act-addComment": "commented on __card__: __comment__",
-    "act-createBoard": "created __board__",
+    "act-createBoard": "შექმნილია __დაფა__",
     "act-createCard": "added __card__ to __list__",
     "act-createCustomField": "created custom field __customField__",
     "act-createList": "added __list__ to __board__",
@@ -25,13 +25,13 @@
     "act-unjoinMember": "removed __member__ from __card__",
     "act-withBoardTitle": "[Wekan] __board__",
     "act-withCardTitle": "[__board__] __card__",
-    "actions": "Actions",
-    "activities": "Activities",
-    "activity": "Activity",
-    "activity-added": "added %s to %s",
-    "activity-archived": "%s moved to Recycle Bin",
+    "actions": "მოქმედებები",
+    "activities": "აქტივეობები",
+    "activity": "აქტივობები",
+    "activity-added": "დამატებულია %s ზე %s",
+    "activity-archived": "%s-მა გადაინაცვლა წაშლილებში",
     "activity-attached": "attached %s to %s",
-    "activity-created": "created %s",
+    "activity-created": "შექმნილია %s",
     "activity-customfield-created": "created custom field %s",
     "activity-excluded": "excluded %s from %s",
     "activity-imported": "imported %s into %s from %s",
@@ -39,35 +39,35 @@
     "activity-joined": "joined %s",
     "activity-moved": "moved %s from %s to %s",
     "activity-on": "on %s",
-    "activity-removed": "removed %s from %s",
+    "activity-removed": "წაიშალა %s  %s-დან",
     "activity-sent": "sent %s to %s",
     "activity-unjoined": "unjoined %s",
     "activity-subtask-added": "added subtask to %s",
     "activity-checklist-added": "added checklist to %s",
     "activity-checklist-item-added": "added checklist item to '%s' in %s",
-    "add": "Add",
-    "add-attachment": "Add Attachment",
-    "add-board": "Add Board",
-    "add-card": "Add Card",
+    "add": "დამატება",
+    "add-attachment": "მიბმული ფაილის დამატება",
+    "add-board": "დაფის დამატება",
+    "add-card": "ბარათის დამატება",
     "add-swimlane": "Add Swimlane",
-    "add-subtask": "Add Subtask",
-    "add-checklist": "Add Checklist",
+    "add-subtask": "ქვესაქმიანობის დამატება",
+    "add-checklist": "კატალოგის დამატება",
     "add-checklist-item": "Add an item to checklist",
     "add-cover": "Add Cover",
     "add-label": "Add Label",
-    "add-list": "Add List",
-    "add-members": "Add Members",
-    "added": "Added",
-    "addMemberPopup-title": "Members",
-    "admin": "Admin",
-    "admin-desc": "Can view and edit cards, remove members, and change settings for the board.",
-    "admin-announcement": "Announcement",
+    "add-list": "ჩამონათვალის დამატება",
+    "add-members": "წევრების დამატება",
+    "added": "დამატებულია",
+    "addMemberPopup-title": "წევრები",
+    "admin": "ადმინი",
+    "admin-desc": "შეუძლია ნახოს და შეასწოროს ბარათები, წაშალოს წევრები და შეცვალოს დაფის პარამეტრები. ",
+    "admin-announcement": "განცხადება",
     "admin-announcement-active": "Active System-Wide Announcement",
     "admin-announcement-title": "Announcement from Administrator",
-    "all-boards": "All boards",
+    "all-boards": "ყველა დაფა",
     "and-n-other-card": "And __count__ other card",
     "and-n-other-card_plural": "And __count__ other cards",
-    "apply": "Apply",
+    "apply": "გამოყენება",
     "app-is-offline": "Wekan is loading, please wait. Refreshing the page will cause data loss. If Wekan does not load, please check that Wekan server has not stopped.",
     "archive": "Move to Recycle Bin",
     "archive-all": "Move All to Recycle Bin",
@@ -83,31 +83,31 @@
     "no-archived-boards": "No Boards in Recycle Bin.",
     "archives": "Recycle Bin",
     "assign-member": "Assign member",
-    "attached": "attached",
-    "attachment": "Attachment",
-    "attachment-delete-pop": "Deleting an attachment is permanent. There is no undo.",
-    "attachmentDeletePopup-title": "Delete Attachment?",
-    "attachments": "Attachments",
+    "attached": "მიბმული",
+    "attachment": "მიბმული ფიალი",
+    "attachment-delete-pop": "მიბმული ფაილის წაშლა მუდმივია. შეუძლებელია მისი უკან დაბრუნება. ",
+    "attachmentDeletePopup-title": "გსურთ მიბმული ფაილის წაშლა? ",
+    "attachments": "მიბმული ფაილები",
     "auto-watch": "Automatically watch boards when they are created",
-    "avatar-too-big": "The avatar is too large (70KB max)",
-    "back": "Back",
-    "board-change-color": "Change color",
-    "board-nb-stars": "%s stars",
-    "board-not-found": "Board not found",
-    "board-private-info": "This board will be <strong>private</strong>.",
-    "board-public-info": "This board will be <strong>public</strong>.",
-    "boardChangeColorPopup-title": "Change Board Background",
-    "boardChangeTitlePopup-title": "Rename Board",
-    "boardChangeVisibilityPopup-title": "Change Visibility",
+    "avatar-too-big": "დიდი მოცულობის სურათი (მაქსიმუმ 70KB)",
+    "back": "უკან",
+    "board-change-color": "ფერის შეცვლა",
+    "board-nb-stars": "%s ვარსკვლავი",
+    "board-not-found": "დაფა არ მოიძებნა",
+    "board-private-info": "ეს დაფა იქნება  <strong>პირადი</strong>.",
+    "board-public-info": "ეს დაფა იქნება <strong>საჯარო</strong>.",
+    "boardChangeColorPopup-title": "დაფის ფონის ცვლილება",
+    "boardChangeTitlePopup-title": "დაფის სახელის ცვლილება",
+    "boardChangeVisibilityPopup-title": "ხილვადობის შეცვლა",
     "boardChangeWatchPopup-title": "Change Watch",
-    "boardMenuPopup-title": "Board Menu",
-    "boards": "Boards",
-    "board-view": "Board View",
-    "board-view-cal": "Calendar",
+    "boardMenuPopup-title": "დაფის მენიუ",
+    "boards": "დაფები",
+    "board-view": "დაფის ნახვა",
+    "board-view-cal": "კალენდარი",
     "board-view-swimlanes": "Swimlanes",
-    "board-view-lists": "Lists",
+    "board-view-lists": "ჩამონათვალი",
     "bucket-example": "Like “Bucket List” for example",
-    "cancel": "Cancel",
+    "cancel": "გაუქმება",
     "card-archived": "This card is moved to Recycle Bin.",
     "card-comments-title": "This card has %s comment.",
     "card-delete-notice": "Deleting is permanent. You will lose all actions associated with this card.",
@@ -115,42 +115,42 @@
     "card-delete-suggest-archive": "You can move a card to Recycle Bin to remove it from the board and preserve the activity.",
     "card-due": "Due",
     "card-due-on": "Due on",
-    "card-spent": "Spent Time",
-    "card-edit-attachments": "Edit attachments",
+    "card-spent": "დახარჯული დრო",
+    "card-edit-attachments": "მიბმული ფაილის შესწორება",
     "card-edit-custom-fields": "Edit custom fields",
     "card-edit-labels": "Edit labels",
-    "card-edit-members": "Edit members",
+    "card-edit-members": "მომხმარებლების შესწორება",
     "card-labels-title": "Change the labels for the card.",
     "card-members-title": "Add or remove members of the board from the card.",
-    "card-start": "Start",
-    "card-start-on": "Starts on",
-    "cardAttachmentsPopup-title": "Attach From",
-    "cardCustomField-datePopup-title": "Change date",
+    "card-start": "დაწყება",
+    "card-start-on": "დაიწყება",
+    "cardAttachmentsPopup-title": "მიბმა შემდეგი წყაროდან: ",
+    "cardCustomField-datePopup-title": "დროის ცვლილება",
     "cardCustomFieldsPopup-title": "Edit custom fields",
-    "cardDeletePopup-title": "Delete Card?",
+    "cardDeletePopup-title": "წავშალოთ ბარათი? ",
     "cardDetailsActionsPopup-title": "Card Actions",
     "cardLabelsPopup-title": "Labels",
-    "cardMembersPopup-title": "Members",
-    "cardMorePopup-title": "More",
-    "cards": "Cards",
-    "cards-count": "Cards",
+    "cardMembersPopup-title": "წევრები",
+    "cardMorePopup-title": "მეტი",
+    "cards": "ბარათები",
+    "cards-count": "ბარათები",
     "casSignIn": "Sign In with CAS",
-    "change": "Change",
-    "change-avatar": "Change Avatar",
-    "change-password": "Change Password",
+    "change": "ცვლილება",
+    "change-avatar": "სურათის შეცვლა",
+    "change-password": "პაროლის შეცვლა",
     "change-permissions": "Change permissions",
     "change-settings": "Change Settings",
-    "changeAvatarPopup-title": "Change Avatar",
-    "changeLanguagePopup-title": "Change Language",
-    "changePasswordPopup-title": "Change Password",
+    "changeAvatarPopup-title": "სურათის შეცვლა",
+    "changeLanguagePopup-title": "ენის შეცვლა",
+    "changePasswordPopup-title": "პაროლის შეცვლა",
     "changePermissionsPopup-title": "Change Permissions",
     "changeSettingsPopup-title": "Change Settings",
-    "subtasks": "Subtasks",
-    "checklists": "Checklists",
-    "click-to-star": "Click to star this board.",
+    "subtasks": "ქვეამოცანა",
+    "checklists": "კატალოგი",
+    "click-to-star": "დააჭირეთ დაფის ვარსკვლავით მოსანიშნად",
     "click-to-unstar": "Click to unstar this board.",
     "clipboard": "Clipboard or drag & drop",
-    "close": "Close",
+    "close": "დახურვა",
     "close-board": "Close Board",
     "close-board-pop": "You will be able to restore the board by clicking the “Recycle Bin” button from the home header.",
     "color-black": "black",
@@ -175,60 +175,60 @@
     "copyChecklistToManyCardsPopup-title": "Copy Checklist Template to Many Cards",
     "copyChecklistToManyCardsPopup-instructions": "Destination Card Titles and Descriptions in this JSON format",
     "copyChecklistToManyCardsPopup-format": "[ {\"title\": \"First card title\", \"description\":\"First card description\"}, {\"title\":\"Second card title\",\"description\":\"Second card description\"},{\"title\":\"Last card title\",\"description\":\"Last card description\"} ]",
-    "create": "Create",
-    "createBoardPopup-title": "Create Board",
-    "chooseBoardSourcePopup-title": "Import board",
+    "create": "შექმნა",
+    "createBoardPopup-title": "დაფის შექმნა",
+    "chooseBoardSourcePopup-title": "დაფის იმპორტი",
     "createLabelPopup-title": "Create Label",
-    "createCustomField": "Create Field",
-    "createCustomFieldPopup-title": "Create Field",
-    "current": "current",
+    "createCustomField": "ველის შექმნა",
+    "createCustomFieldPopup-title": "ველის შექმნა",
+    "current": "მიმდინარე",
     "custom-field-delete-pop": "There is no undo. This will remove this custom field from all cards and destroy its history.",
     "custom-field-checkbox": "Checkbox",
-    "custom-field-date": "Date",
-    "custom-field-dropdown": "Dropdown List",
+    "custom-field-date": "თარიღი",
+    "custom-field-dropdown": "ჩამოსაშლელი სია",
     "custom-field-dropdown-none": "(none)",
     "custom-field-dropdown-options": "List Options",
     "custom-field-dropdown-options-placeholder": "Press enter to add more options",
-    "custom-field-dropdown-unknown": "(unknown)",
-    "custom-field-number": "Number",
-    "custom-field-text": "Text",
+    "custom-field-dropdown-unknown": "(უცნობი)",
+    "custom-field-number": "რიცხვი",
+    "custom-field-text": "ტექსტი",
     "custom-fields": "Custom Fields",
-    "date": "Date",
+    "date": "თარიღი",
     "decline": "Decline",
     "default-avatar": "Default avatar",
-    "delete": "Delete",
+    "delete": "წაშლა",
     "deleteCustomFieldPopup-title": "Delete Custom Field?",
     "deleteLabelPopup-title": "Delete Label?",
     "description": "Description",
     "disambiguateMultiLabelPopup-title": "Disambiguate Label Action",
     "disambiguateMultiMemberPopup-title": "Disambiguate Member Action",
     "discard": "Discard",
-    "done": "Done",
-    "download": "Download",
-    "edit": "Edit",
-    "edit-avatar": "Change Avatar",
-    "edit-profile": "Edit Profile",
-    "edit-wip-limit": "Edit WIP Limit",
+    "done": "დასრულებული",
+    "download": "ჩამოტვირთვა",
+    "edit": "შესწორება",
+    "edit-avatar": "სურათის შეცვლა",
+    "edit-profile": "პროფილის შესწორება",
+    "edit-wip-limit": " WIP ლიმიტის შესწორება",
     "soft-wip-limit": "Soft WIP Limit",
-    "editCardStartDatePopup-title": "Change start date",
+    "editCardStartDatePopup-title": "დაწყების დროის შეცვლა",
     "editCardDueDatePopup-title": "Change due date",
-    "editCustomFieldPopup-title": "Edit Field",
-    "editCardSpentTimePopup-title": "Change spent time",
+    "editCustomFieldPopup-title": "ველების შესწორება",
+    "editCardSpentTimePopup-title": "დახარჯული დროის შეცვლა",
     "editLabelPopup-title": "Change Label",
-    "editNotificationPopup-title": "Edit Notification",
-    "editProfilePopup-title": "Edit Profile",
-    "email": "Email",
+    "editNotificationPopup-title": "შეტყობინებების შესწორება",
+    "editProfilePopup-title": "პროფილის შესწორება",
+    "email": "ელ.ფოსტა",
     "email-enrollAccount-subject": "An account created for you on __siteName__",
     "email-enrollAccount-text": "Hello __user__,\n\nTo start using the service, simply click the link below.\n\n__url__\n\nThanks.",
-    "email-fail": "Sending email failed",
+    "email-fail": "ელ.ფოსტის გაგზავნა ვერ მოხერხდა",
     "email-fail-text": "Error trying to send email",
-    "email-invalid": "Invalid email",
-    "email-invite": "Invite via Email",
+    "email-invalid": "არასწორი ელ.ფოსტა",
+    "email-invite": "მოწვევა ელ.ფოსტის მეშვეობით",
     "email-invite-subject": "__inviter__ sent you an invitation",
     "email-invite-text": "Dear __user__,\n\n__inviter__ invites you to join board \"__board__\" for collaborations.\n\nPlease follow the link below:\n\n__url__\n\nThanks.",
     "email-resetPassword-subject": "Reset your password on __siteName__",
     "email-resetPassword-text": "Hello __user__,\n\nTo reset your password, simply click the link below.\n\n__url__\n\nThanks.",
-    "email-sent": "Email sent",
+    "email-sent": "ელ.ფოსტა გაგზავნილია",
     "email-verifyEmail-subject": "Verify your email address on __siteName__",
     "email-verifyEmail-text": "Hello __user__,\n\nTo verify your account email, simply click the link below.\n\n__url__\n\nThanks.",
     "enable-wip-limit": "Enable WIP Limit",
@@ -244,7 +244,7 @@
     "error-username-taken": "This username is already taken",
     "error-email-taken": "Email has already been taken",
     "export-board": "Export board",
-    "filter": "Filter",
+    "filter": "ფილტრი",
     "filter-cards": "Filter Cards",
     "filter-clear": "Clear filter",
     "filter-no-label": "No label",
@@ -258,11 +258,11 @@
     "fullname": "Full Name",
     "header-logo-title": "Go back to your boards page.",
     "hide-system-messages": "Hide system messages",
-    "headerBarCreateBoardPopup-title": "Create Board",
-    "home": "Home",
-    "import": "Import",
+    "headerBarCreateBoardPopup-title": "დაფის შექმნა",
+    "home": "სახლი",
+    "import": "იმპორტირება",
     "import-board": "import board",
-    "import-board-c": "Import board",
+    "import-board-c": "დაფის იმპორტი",
     "import-board-title-trello": "Import board from Trello",
     "import-board-title-wekan": "Import board from Wekan",
     "import-sandstorm-warning": "Imported board will delete all existing data on board and replace it with imported board.",
@@ -276,11 +276,11 @@
     "import-show-user-mapping": "Review members mapping",
     "import-user-select": "Pick the Wekan user you want to use as this member",
     "importMapMembersAddPopup-title": "Select Wekan member",
-    "info": "Version",
+    "info": "ვერსია",
     "initials": "Initials",
-    "invalid-date": "Invalid date",
-    "invalid-time": "Invalid time",
-    "invalid-user": "Invalid user",
+    "invalid-date": "არასწორი თარიღი",
+    "invalid-time": "არასწორი დრო",
+    "invalid-user": "არასწორი მომხმარებელი",
     "joined": "joined",
     "just-invited": "You are just invited to this board",
     "keyboard-shortcuts": "Keyboard shortcuts",
@@ -288,7 +288,7 @@
     "label-default": "%s label (default)",
     "label-delete-pop": "There is no undo. This will remove this label from all cards and destroy its history.",
     "labels": "Labels",
-    "language": "Language",
+    "language": "ენა",
     "last-admin-desc": "You can’t change roles because there must be at least one admin.",
     "leave-board": "Leave Board",
     "leave-board-pop": "Are you sure you want to leave __boardTitle__? You will be removed from all cards on this board.",
@@ -301,52 +301,52 @@
     "listActionPopup-title": "List Actions",
     "swimlaneActionPopup-title": "Swimlane Actions",
     "listImportCardPopup-title": "Import a Trello card",
-    "listMorePopup-title": "More",
+    "listMorePopup-title": "მეტი",
     "link-list": "Link to this list",
     "list-delete-pop": "All actions will be removed from the activity feed and you won't be able to recover the list. There is no undo.",
     "list-delete-suggest-archive": "You can move a list to Recycle Bin to remove it from the board and preserve the activity.",
-    "lists": "Lists",
+    "lists": "ჩამონათვალი",
     "swimlanes": "Swimlanes",
-    "log-out": "Log Out",
-    "log-in": "Log In",
-    "loginPopup-title": "Log In",
-    "memberMenuPopup-title": "Member Settings",
-    "members": "Members",
-    "menu": "Menu",
-    "move-selection": "Move selection",
+    "log-out": "გამოსვლა",
+    "log-in": "შესვლა",
+    "loginPopup-title": "შესვლა",
+    "memberMenuPopup-title": "მომხმარებლის პარამეტრები",
+    "members": "წევრები",
+    "menu": "მენიუ",
+    "move-selection": "მონიშნულის მოძრაობა",
     "moveCardPopup-title": "Move Card",
     "moveCardToBottom-title": "Move to Bottom",
-    "moveCardToTop-title": "Move to Top",
-    "moveSelectionPopup-title": "Move selection",
+    "moveCardToTop-title": "ზევით აწევა",
+    "moveSelectionPopup-title": "მონიშნულის მოძრაობა",
     "multi-selection": "Multi-Selection",
     "multi-selection-on": "Multi-Selection is on",
-    "muted": "Muted",
+    "muted": "ხმა გათიშულია",
     "muted-info": "You will never be notified of any changes in this board",
-    "my-boards": "My Boards",
-    "name": "Name",
+    "my-boards": "ჩემი დაფები",
+    "name": "სახელი",
     "no-archived-cards": "No cards in Recycle Bin.",
     "no-archived-lists": "No lists in Recycle Bin.",
     "no-archived-swimlanes": "No swimlanes in Recycle Bin.",
-    "no-results": "No results",
-    "normal": "Normal",
+    "no-results": "შედეგის გარეშე",
+    "normal": "ნორმალური",
     "normal-desc": "Can view and edit cards. Can't change settings.",
-    "not-accepted-yet": "Invitation not accepted yet",
+    "not-accepted-yet": "მოწვევა ჯერ არ დადასტურებულა",
     "notify-participate": "Receive updates to any cards you participate as creater or member",
     "notify-watch": "Receive updates to any boards, lists, or cards you’re watching",
-    "optional": "optional",
-    "or": "or",
+    "optional": "არჩევითი",
+    "or": "ან",
     "page-maybe-private": "This page may be private. You may be able to view it by <a href='%s'>logging in</a>.",
-    "page-not-found": "Page not found.",
-    "password": "Password",
+    "page-not-found": "გვერდი არ მოიძებნა.",
+    "password": "პაროლი",
     "paste-or-dragdrop": "to paste, or drag & drop image file to it (image only)",
     "participating": "Participating",
-    "preview": "Preview",
-    "previewAttachedImagePopup-title": "Preview",
-    "previewClipboardImagePopup-title": "Preview",
-    "private": "Private",
+    "preview": "წინასწარ ნახვა",
+    "previewAttachedImagePopup-title": "წინასწარ ნახვა",
+    "previewClipboardImagePopup-title": "წინასწარ ნახვა",
+    "private": "კერძო",
     "private-desc": "This board is private. Only people added to the board can view and edit it.",
-    "profile": "Profile",
-    "public": "Public",
+    "profile": "პროფილი",
+    "public": "საჯარო",
     "public-desc": "This board is public. It's visible to anyone with the link and will show up in search engines like Google. Only people added to the board can edit.",
     "quick-access-description": "Star a board to add a shortcut in this bar.",
     "remove-cover": "Remove Cover",
@@ -357,21 +357,21 @@
     "remove-member-from-card": "Remove from Card",
     "remove-member-pop": "Remove __name__ (__username__) from __boardTitle__? The member will be removed from all cards on this board. They will receive a notification.",
     "removeMemberPopup-title": "Remove Member?",
-    "rename": "Rename",
-    "rename-board": "Rename Board",
-    "restore": "Restore",
-    "save": "Save",
-    "search": "Search",
+    "rename": "სახელის შეცვლა",
+    "rename-board": "დაფის სახელის ცვლილება",
+    "restore": "აღდგენა",
+    "save": "დამახსოვრება",
+    "search": "ძებნა",
     "search-cards": "Search from card titles and descriptions on this board",
     "search-example": "Text to search for?",
-    "select-color": "Select Color",
+    "select-color": "ფერის მონიშვნა",
     "set-wip-limit-value": "Set a limit for the maximum number of tasks in this list",
     "setWipLimitPopup-title": "Set WIP Limit",
     "shortcut-assign-self": "Assign yourself to current card",
     "shortcut-autocomplete-emoji": "Autocomplete emoji",
     "shortcut-autocomplete-members": "Autocomplete members",
     "shortcut-clear-filters": "Clear all filters",
-    "shortcut-close-dialog": "Close Dialog",
+    "shortcut-close-dialog": "დიალოგის დახურვა",
     "shortcut-filter-my-cards": "Filter my cards",
     "shortcut-show-shortcuts": "Bring up this shortcuts list",
     "shortcut-toggle-filterbar": "Toggle Filter Sidebar",
@@ -383,66 +383,66 @@
     "star-board-title": "Click to star this board. It will show up at top of your boards list.",
     "starred-boards": "Starred Boards",
     "starred-boards-description": "Starred boards show up at the top of your boards list.",
-    "subscribe": "Subscribe",
-    "team": "Team",
+    "subscribe": "გამოწერა",
+    "team": "ჯგუფი",
     "this-board": "this board",
     "this-card": "this card",
-    "spent-time-hours": "Spent time (hours)",
-    "overtime-hours": "Overtime (hours)",
-    "overtime": "Overtime",
+    "spent-time-hours": "დახარჯული დრო (საათები)",
+    "overtime-hours": "ზედმეტი დრო (საათები) ",
+    "overtime": "ზედმეტი დრო",
     "has-overtime-cards": "Has overtime cards",
     "has-spenttime-cards": "Has spent time cards",
-    "time": "Time",
-    "title": "Title",
+    "time": "დრო",
+    "title": "სათაური",
     "tracking": "Tracking",
     "tracking-info": "You will be notified of any changes to those cards you are involved as creator or member.",
     "type": "Type",
     "unassign-member": "Unassign member",
     "unsaved-description": "You have an unsaved description.",
     "unwatch": "Unwatch",
-    "upload": "Upload",
-    "upload-avatar": "Upload an avatar",
-    "uploaded-avatar": "Uploaded an avatar",
-    "username": "Username",
+    "upload": "ატვირთვა",
+    "upload-avatar": "სურათის ატვირთვა",
+    "uploaded-avatar": "სურათი ატვირთულია",
+    "username": "მომხმარებლის სახელი",
     "view-it": "View it",
     "warn-list-archived": "warning: this card is in an list at Recycle Bin",
-    "watch": "Watch",
-    "watching": "Watching",
+    "watch": "ნახვა",
+    "watching": "ნახვის პროცესი",
     "watching-info": "You will be notified of any change in this board",
-    "welcome-board": "Welcome Board",
+    "welcome-board": "მისასალმებელი დაფა",
     "welcome-swimlane": "Milestone 1",
-    "welcome-list1": "Basics",
+    "welcome-list1": "ბაზისური ",
     "welcome-list2": "Advanced",
     "what-to-do": "What do you want to do?",
     "wipLimitErrorPopup-title": "Invalid WIP Limit",
     "wipLimitErrorPopup-dialog-pt1": "The number of tasks in this list is higher than the WIP limit you've defined.",
     "wipLimitErrorPopup-dialog-pt2": "Please move some tasks out of this list, or set a higher WIP limit.",
-    "admin-panel": "Admin Panel",
-    "settings": "Settings",
-    "people": "People",
-    "registration": "Registration",
+    "admin-panel": "ადმინის პანელი",
+    "settings": "პარამეტრები",
+    "people": "ხალხი",
+    "registration": "რეგისტრაცია",
     "disable-self-registration": "Disable Self-Registration",
-    "invite": "Invite",
-    "invite-people": "Invite People",
+    "invite": "მოწვევა",
+    "invite-people": "ხალხის მოწვევა",
     "to-boards": "To board(s)",
-    "email-addresses": "Email Addresses",
+    "email-addresses": "ელ.ფოსტის მისამართები",
     "smtp-host-description": "The address of the SMTP server that handles your emails.",
     "smtp-port-description": "The port your SMTP server uses for outgoing emails.",
     "smtp-tls-description": "Enable TLS support for SMTP server",
     "smtp-host": "SMTP Host",
     "smtp-port": "SMTP Port",
-    "smtp-username": "Username",
-    "smtp-password": "Password",
+    "smtp-username": "მომხმარებლის სახელი",
+    "smtp-password": "პაროლი",
     "smtp-tls": "TLS support",
-    "send-from": "From",
+    "send-from": "დან",
     "send-smtp-test": "Send a test email to yourself",
-    "invitation-code": "Invitation Code",
+    "invitation-code": "მოწვევის კოდი",
     "email-invite-register-subject": "__inviter__ sent you an invitation",
     "email-invite-register-text": "Dear __user__,\n\n__inviter__ invites you to Wekan for collaborations.\n\nPlease follow the link below:\n__url__\n\nAnd your invitation code is: __icode__\n\nThanks.",
     "email-smtp-test-subject": "SMTP Test Email From Wekan",
-    "email-smtp-test-text": "You have successfully sent an email",
-    "error-invitation-code-not-exist": "Invitation code doesn't exist",
-    "error-notAuthorized": "You are not authorized to view this page.",
+    "email-smtp-test-text": "თქვენ წარმატებით გააგზავნეთ ელ.ფოსტა.",
+    "error-invitation-code-not-exist": "მსგავსი მოსაწვევი კოდი არ არსებობს",
+    "error-notAuthorized": "თქვენ არ გაქვთ ამ გვერდის ნახვის უფლება",
     "outgoing-webhooks": "Outgoing Webhooks",
     "outgoingWebhooksPopup-title": "Outgoing Webhooks",
     "new-outgoing-webhook": "New Outgoing Webhook",

+ 10 - 10
i18n/sv.i18n.json

@@ -103,7 +103,7 @@
     "boardMenuPopup-title": "Anslagstavla meny",
     "boards": "Anslagstavlor",
     "board-view": "Anslagstavelsvy",
-    "board-view-cal": "Calendar",
+    "board-view-cal": "Kalender",
     "board-view-swimlanes": "Simbanor",
     "board-view-lists": "Listor",
     "bucket-example": "Gilla \"att-göra-innan-jag-dör-lista\" till exempel",
@@ -134,7 +134,7 @@
     "cardMorePopup-title": "Mera",
     "cards": "Kort",
     "cards-count": "Kort",
-    "casSignIn": "Sign In with CAS",
+    "casSignIn": "Logga in med CAS",
     "change": "Ändra",
     "change-avatar": "Ändra avatar",
     "change-password": "Ändra lösenord",
@@ -145,7 +145,7 @@
     "changePasswordPopup-title": "Ändra lösenord",
     "changePermissionsPopup-title": "Ändra behörigheter",
     "changeSettingsPopup-title": "Ändra inställningar",
-    "subtasks": "Subtasks",
+    "subtasks": "Deluppgifter",
     "checklists": "Kontrollistor",
     "click-to-star": "Klicka för att stjärnmärka denna anslagstavla.",
     "click-to-unstar": "Klicka för att ta bort stjärnmärkningen från denna anslagstavla.",
@@ -168,8 +168,8 @@
     "comment-only": "Kommentera endast",
     "comment-only-desc": "Kan endast kommentera kort.",
     "computer": "Dator",
-    "confirm-subtask-delete-dialog": "Are you sure you want to delete subtask?",
-    "confirm-checklist-delete-dialog": "Are you sure you want to delete checklist?",
+    "confirm-subtask-delete-dialog": "Är du säker på att du vill radera deluppgift?",
+    "confirm-checklist-delete-dialog": "Är du säker på att du vill radera checklista?",
     "copy-card-link-to-clipboard": "Kopiera kortlänk till urklipp",
     "copyCardPopup-title": "Kopiera kort",
     "copyChecklistToManyCardsPopup-title": "Kopiera checklist-mallen till flera kort",
@@ -482,12 +482,12 @@
     "delete-board-confirm-popup": "Alla listor, kort, etiketter och aktiviteter kommer tas bort och du kommer inte kunna återställa anslagstavlans innehåll. Det går inte att ångra.",
     "boardDeletePopup-title": "Ta bort anslagstavla?",
     "delete-board": "Ta bort anslagstavla",
-    "default-subtasks-board": "Subtasks for __board__ board",
-    "default": "Default",
-    "queue": "Queue",
-    "subtask-settings": "Subtasks Settings",
+    "default-subtasks-board": "Deluppgifter för __board__ board",
+    "default": "Standard",
+    "queue": "",
+    "subtask-settings": "Deluppgift inställningar",
     "boardSubtaskSettingsPopup-title": "Board Subtasks Settings",
-    "show-subtasks-field": "Cards can have subtasks",
+    "show-subtasks-field": "Kort kan ha deluppgifter",
     "deposit-subtasks-board": "Deposit subtasks to this board:",
     "deposit-subtasks-list": "Landing list for subtasks deposited here:",
     "show-parent-in-minicard": "Show parent in minicard:",

+ 19 - 0
openshift/README.md

@@ -0,0 +1,19 @@
+# Wekan on OpenShift
+ 
+OpenShift Template for Wekan backed by MongoDB
+ 
+#### Create Template
+```sh
+oc create -f wekan.yml
+```
+ 
+#### Delete Instance Resources
+Clean up all resources created. Note label filters assume single instance of template deployed in the current namespace.
+ 
+```sh
+oc delete all -l app=wekan
+oc delete pods -l app=wekan
+oc delete persistentvolumeclaim -l app=wekan
+oc delete serviceaccount -l app=wekan
+oc delete secret -l app=wekan
+```

+ 341 - 0
openshift/wekan.yml

@@ -0,0 +1,341 @@
+---
+apiVersion: v1
+kind: Template
+labels:
+  template: wekan-mongodb-persistent-template
+message: |-
+  The following service(s) have been created in your project: ${WEKAN_SERVICE_NAME}.
+metadata:
+  annotations:
+    description: |-
+      This template provides a Wekan instance backed by a standalone MongoDB
+      server. The database is stored on persistent storage.
+    iconClass: pficon-trend-up
+    openshift.io/display-name: Wekan backed by MongoDB
+    openshift.io/documentation-url: https://wekan.github.io/
+    openshift.io/long-description: This template provides a Wekan platform
+      with a MongoDB database created. The database is stored on persistent storage. The
+      database name, username, and password are chosen via parameters when provisioning
+      this service.
+    tags: wekan,kanban,mongodb
+  name: wekan-mongodb-persistent
+objects:
+- apiVersion: v1
+  kind: ServiceAccount
+  metadata:
+    name: ${WEKAN_SERVICE_NAME}
+    labels:
+      app: wekan
+      service: ${WEKAN_SERVICE_NAME}
+- apiVersion: v1
+  kind: Secret
+  metadata:
+    annotations:
+      template.openshift.io/expose-admin_password: "{.data['database-admin-password']}"
+      template.openshift.io/expose-database_name: "{.data['database-name']}"
+      template.openshift.io/expose-password: "{.data['database-password']}"
+      template.openshift.io/expose-username: "{.data['database-user']}"
+    name: "${DATABASE_SERVICE_NAME}"
+    labels:
+      app: wekan
+      service: ${WEKAN_SERVICE_NAME}
+  stringData:
+    database-admin-password: "${MONGODB_ADMIN_PASSWORD}"
+    database-name: "${MONGODB_DATABASE}"
+    database-password: "${MONGODB_PASSWORD}"
+    database-user: "${MONGODB_USER}"
+- apiVersion: v1
+  kind: Service
+  metadata:
+    annotations:
+      template.openshift.io/expose-uri: http://{.spec.clusterIP}:{.spec.ports[?(.name=="wekan")].port}
+    name: "${WEKAN_SERVICE_NAME}"
+    labels:
+      app: wekan
+      service: ${WEKAN_SERVICE_NAME}
+  spec:
+    ports:
+    - name: wekan
+      nodePort: 0
+      port: 8080
+      protocol: TCP
+      targetPort: 8080
+    selector:
+      name: "${WEKAN_SERVICE_NAME}"
+    sessionAffinity: None
+    type: ClusterIP
+  status:
+    loadBalancer: {}
+- apiVersion: v1
+  kind: Service
+  metadata:
+    annotations:
+      template.openshift.io/expose-uri: mongodb://{.spec.clusterIP}:{.spec.ports[?(.name=="mongo")].port}
+    name: "${DATABASE_SERVICE_NAME}"
+    labels:
+      app: wekan
+      service: ${WEKAN_SERVICE_NAME}
+  spec:
+    ports:
+    - name: mongo
+      nodePort: 0
+      port: 27017
+      protocol: TCP
+      targetPort: 27017
+    selector:
+      name: "${DATABASE_SERVICE_NAME}"
+    sessionAffinity: None
+    type: ClusterIP
+  status:
+    loadBalancer: {}
+- apiVersion: v1
+  kind: PersistentVolumeClaim
+  metadata:
+    name: "${DATABASE_SERVICE_NAME}"
+    labels:
+      app: wekan
+      service: ${WEKAN_SERVICE_NAME}
+  spec:
+    accessModes:
+    - ReadWriteOnce
+    resources:
+      requests:
+        storage: "${VOLUME_CAPACITY}"
+- apiVersion: image.openshift.io/v1
+  kind: ImageStream
+  metadata:
+    labels:
+      app: wekan
+    name: ${WEKAN_SERVICE_NAME}
+  spec:
+    tags:
+    - from:
+        kind: DockerImage
+        name: ${WEKAN_IMAGE}
+      generation: 2
+      name: latest
+      referencePolicy:
+        type: Source
+- apiVersion: v1
+  kind: DeploymentConfig
+  metadata:
+    name: ${WEKAN_SERVICE_NAME}
+    labels:
+      app: wekan
+      service: ${WEKAN_SERVICE_NAME}
+  spec:
+    replicas: 1
+    selector:
+      app: wekan
+      deploymentconfig: ${WEKAN_SERVICE_NAME}
+    strategy:
+      type: Recreate
+    template:
+      metadata:
+        labels:
+          app: wekan
+          service: ${WEKAN_SERVICE_NAME}
+          deploymentconfig: ${WEKAN_SERVICE_NAME}
+          template: wekan
+          name: ${WEKAN_SERVICE_NAME}
+      spec:
+        containers:
+        - name: ${WEKAN_SERVICE_NAME}
+          image: ${WEKAN_IMAGE}
+          imagePullPolicy: Always
+          env:
+          - name: MONGO_URL
+            value: mongodb://${MONGODB_USER}:${MONGODB_PASSWORD}@${DATABASE_SERVICE_NAME}:27017/${MONGODB_DATABASE}
+          - name: ROOT_URL
+            value: http://localhost
+          - name: PORT
+            value: "8080"
+          ports:
+          - containerPort: 8080
+            name: ${WEKAN_SERVICE_NAME}
+            protocol: TCP
+          terminationMessagePath: /dev/termination-log
+          livenessProbe:
+            failureThreshold: 30
+            httpGet:
+              path: /
+              port: 8080
+            initialDelaySeconds: 240
+            timeoutSeconds: 3
+          readinessProbe:
+            httpGet:
+              path: /
+              port: 8080
+            initialDelaySeconds: 3
+            timeoutSeconds: 3
+        dnsPolicy: ClusterFirst
+        restartPolicy: Always
+        serviceAccount: ${WEKAN_SERVICE_NAME}
+        serviceAccountName: ${WEKAN_SERVICE_NAME}
+        terminationGracePeriodSeconds: 30
+    triggers:
+    - type: ConfigChange
+    - type: ImageChange
+      imageChangeParams:
+        automatic: true
+        containerNames:
+        - ${WEKAN_SERVICE_NAME}
+        from:
+          kind: ImageStreamTag
+          name: ${WEKAN_SERVICE_NAME}:latest
+        lastTriggeredImage: ""
+- apiVersion: v1
+  kind: DeploymentConfig
+  metadata:
+    annotations:
+      template.alpha.openshift.io/wait-for-ready: 'true'
+    name: "${DATABASE_SERVICE_NAME}"
+    labels:
+      app: wekan
+      service: ${WEKAN_SERVICE_NAME}
+  spec:
+    replicas: 1
+    selector:
+      name: "${DATABASE_SERVICE_NAME}"
+    strategy:
+      type: Recreate
+    template:
+      metadata:
+        labels:
+          name: "${DATABASE_SERVICE_NAME}"
+      spec:
+        containers:
+        - capabilities: {}
+          env:
+          - name: MONGODB_USER
+            valueFrom:
+              secretKeyRef:
+                key: database-user
+                name: "${DATABASE_SERVICE_NAME}"
+          - name: MONGODB_PASSWORD
+            valueFrom:
+              secretKeyRef:
+                key: database-password
+                name: "${DATABASE_SERVICE_NAME}"
+          - name: MONGODB_ADMIN_PASSWORD
+            valueFrom:
+              secretKeyRef:
+                key: database-admin-password
+                name: "${DATABASE_SERVICE_NAME}"
+          - name: MONGODB_DATABASE
+            valueFrom:
+              secretKeyRef:
+                key: database-name
+                name: "${DATABASE_SERVICE_NAME}"
+          image: " "
+          imagePullPolicy: IfNotPresent
+          livenessProbe:
+            initialDelaySeconds: 30
+            tcpSocket:
+              port: 27017
+            timeoutSeconds: 1
+          name: mongodb
+          ports:
+          - containerPort: 27017
+            protocol: TCP
+          readinessProbe:
+            exec:
+              command:
+              - "/bin/sh"
+              - "-i"
+              - "-c"
+              - mongo 127.0.0.1:27017/$MONGODB_DATABASE -u $MONGODB_USER -p $MONGODB_PASSWORD
+                --eval="quit()"
+            initialDelaySeconds: 3
+            timeoutSeconds: 1
+          resources:
+            limits:
+              memory: "${MEMORY_LIMIT}"
+          securityContext:
+            capabilities: {}
+            privileged: false
+          terminationMessagePath: "/dev/termination-log"
+          volumeMounts:
+          - mountPath: "/var/lib/mongodb/data"
+            name: "${DATABASE_SERVICE_NAME}-data"
+        dnsPolicy: ClusterFirst
+        restartPolicy: Always
+        volumes:
+        - name: "${DATABASE_SERVICE_NAME}-data"
+          persistentVolumeClaim:
+            claimName: "${DATABASE_SERVICE_NAME}"
+    triggers:
+    - imageChangeParams:
+        automatic: true
+        containerNames:
+        - mongodb
+        from:
+          kind: ImageStreamTag
+          name: mongodb:${MONGODB_VERSION}
+          namespace: "${NAMESPACE}"
+        lastTriggeredImage: ''
+      type: ImageChange
+    - type: ConfigChange
+  status: {}
+parameters:
+- description: Maximum amount of memory the container can use.
+  displayName: Memory Limit
+  name: MEMORY_LIMIT
+  required: true
+  value: 512Mi
+- description: The OpenShift Namespace where the ImageStream resides.
+  displayName: Namespace
+  name: NAMESPACE
+  value: openshift
+- description: The name of the OpenShift Service exposed for the database.
+  displayName: Database Service Name
+  name: DATABASE_SERVICE_NAME
+  required: true
+  value: mongodb
+- description: Username for MongoDB user that will be used for accessing the database.
+  displayName: MongoDB Connection Username
+  from: user[A-Z0-9]{3}
+  generate: expression
+  name: MONGODB_USER
+  required: true
+- description: Password for the MongoDB connection user.
+  displayName: MongoDB Connection Password
+  from: "[a-zA-Z0-9]{16}"
+  generate: expression
+  name: MONGODB_PASSWORD
+  required: true
+- description: Name of the MongoDB database accessed.
+  displayName: MongoDB Database Name
+  name: MONGODB_DATABASE
+  required: true
+  value: wekan
+- description: Password for the database admin user.
+  displayName: MongoDB Admin Password
+  from: "[a-zA-Z0-9]{16}"
+  generate: expression
+  name: MONGODB_ADMIN_PASSWORD
+  required: true
+- description: Volume space available for data, e.g. 512Mi, 2Gi.
+  displayName: Volume Capacity
+  name: VOLUME_CAPACITY
+  required: true
+  value: 1Gi
+- description: Version of MongoDB image to be used (2.4, 2.6, 3.2 or latest).
+  displayName: Version of MongoDB Image
+  name: MONGODB_VERSION
+  required: true
+  value: '3.2'
+- name: WEKAN_SERVICE_NAME
+  displayName: WeKan Service Name
+  value: wekan
+  required: true
+- name: WEKAN_IMAGE
+  displayName: WeKan Docker Image
+  value: quay.io/wekan/wekan:latest
+  description: The metabase docker image to use
+  required: true
+- name: WEKAN_SERVICE_NAME
+  displayName: WeKan Service Name
+  value: wekan
+  required: true
+

+ 1 - 1
package.json

@@ -1,6 +1,6 @@
 {
   "name": "wekan",
-  "version": "1.18.0",
+  "version": "1.19.0",
   "description": "The open-source Trello-like 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 = 103,
+    appVersion = 104,
     # Increment this for every release.
 
-    appMarketingVersion = (defaultText = "1.18.0~2018-07-06"),
+    appMarketingVersion = (defaultText = "1.19.0~2018-07-16"),
     # Human-readable presentation of the app version.
 
     minUpgradableAppVersion = 0,

+ 1 - 1
snap-src/bin/caddy-control

@@ -4,7 +4,7 @@
 source $SNAP/bin/wekan-read-settings
 
 if [ "$CADDY_ENABLED" = "true" ]; then
-    env LC_ALL=C caddy -conf=$SNAP_COMMON/Caddyfile -host=localhost:${CADDY_PORT}
+    env LC_ALL=C caddy -conf=$SNAP_COMMON/Caddyfile -host=localhost:${CADDY_PORT} -agree
 else
     echo "caddy is disabled. Stop service"
     snapctl stop --disable ${SNAP_NAME}.caddy