diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile
index d355516b4..0adccae7a 100644
--- a/.devcontainer/Dockerfile
+++ b/.devcontainer/Dockerfile
@@ -1,11 +1,7 @@
-FROM quay.io/wekan/ubuntu:groovy-20201125.2
+FROM quay.io/wekan/ubuntu:groovy-20210115
LABEL maintainer="sgr"
-# 2020-12-03:
-# - Above Ubuntu base image copied from Docker Hub ubuntu:groovy-20201125.2
-# to Quay to avoid Docker Hub rate limits.
-
-ENV BUILD_DEPS="gnupg gosu bsdtar wget curl bzip2 g++ build-essential python git ca-certificates iproute2"
+ENV BUILD_DEPS="gnupg gosu libarchive-tools wget curl bzip2 g++ build-essential python git ca-certificates iproute2"
ENV DEBIAN_FRONTEND=noninteractive
ENV \
@@ -134,23 +130,24 @@ ENV \
SAML_PUBLIC_CERTFILE="" \
SAML_IDENTIFIER_FORMAT="" \
SAML_LOCAL_PROFILE_MATCH_ATTRIBUTE="" \
- SAML_ATTRIBUTES=""
+ SAML_ATTRIBUTES="" \
+ DEFAULT_WAIT_SPINNER=""
# Install OS
RUN set -o xtrace \
&& useradd --user-group -m --system --home-dir /home/wekan wekan \
&& apt-get update \
- && apt-get install --assume-yes --no-install-recommends apt-utils apt-transport-https ca-certificates 2>&1 \
- && apt-get install --assume-yes --no-install-recommends ${BUILD_DEPS}
+ && apt-get install --assume-yes --no-install-recommends apt-utils apt-transport-https ca-certificates 2>&1 \
+ && apt-get install --assume-yes --no-install-recommends ${BUILD_DEPS}
# Install NodeJS
RUN set -o xtrace \
&& cd /tmp \
- && curl -fsSLO --compressed "https://nodejs.org/dist/v$NODE_VERSION/node-v$NODE_VERSION-$ARCHITECTURE.tar.xz" \
- && curl -fsSLO --compressed "https://nodejs.org/dist/v$NODE_VERSION/SHASUMS256.txt.asc" \
- && grep " node-v$NODE_VERSION-$ARCHITECTURE.tar.xz\$" SHASUMS256.txt.asc | sha256sum -c - \
- && tar -xJf "node-v$NODE_VERSION-$ARCHITECTURE.tar.xz" -C /usr/local --strip-components=1 --no-same-owner \
- && rm "node-v$NODE_VERSION-$ARCHITECTURE.tar.xz" SHASUMS256.txt.asc \
+ && curl -fsSLO --compressed "https://nodejs.org/dist/$NODE_VERSION/node-$NODE_VERSION-$ARCHITECTURE.tar.xz" \
+ && curl -fsSLO --compressed "https://nodejs.org/dist/$NODE_VERSION/SHASUMS256.txt.asc" \
+ && grep " node-$NODE_VERSION-$ARCHITECTURE.tar.xz\$" SHASUMS256.txt.asc | sha256sum -c - \
+ && tar -xJf "node-$NODE_VERSION-$ARCHITECTURE.tar.xz" -C /usr/local --strip-components=1 --no-same-owner \
+ && rm "node-$NODE_VERSION-$ARCHITECTURE.tar.xz" SHASUMS256.txt.asc \
&& ln -s /usr/local/bin/node /usr/local/bin/nodejs \
&& mkdir -p /usr/local/lib/node_modules/fibers/.node-gyp /root/.node-gyp/${NODE_VERSION} /home/wekan/.config \
&& npm install -g npm@${NPM_VERSION} \
@@ -172,17 +169,65 @@ RUN set -o xtrace \
ENV PATH=$PATH:/home/wekan/.meteor/
-# Copy source dir
USER root
RUN echo "export PATH=$PATH" >> /etc/environment
-RUN set -o xtrace \
- && mkdir /home/wekan/app
+USER wekan
-COPY ${SRC_PATH} /home/wekan/app/
+# Copy source dir
+RUN set -o xtrace \
+ && mkdir -p /home/wekan/app/.meteor \
+ && mkdir -p /home/wekan/app/packages
+
+COPY \
+ .meteor/.finished-upgraders \
+ .meteor/.id \
+ .meteor/cordova-plugins \
+ .meteor/packages \
+ .meteor/platforms \
+ .meteor/release \
+ .meteor/versions \
+ /home/wekan/app/.meteor/
+
+COPY \
+ package.json \
+ settings.json \
+ /home/wekan/app/
+
+COPY \
+ packages \
+ /home/wekan/app/packages/
+
+USER root
RUN set -o xtrace \
&& chown -R wekan:wekan /home/wekan/app /home/wekan/.meteor
USER wekan
+
+RUN \
+ set -o xtrace && \
+ sed -i 's/api\.versionsFrom/\/\/api.versionsFrom/' /home/wekan/app/packages/meteor-useraccounts-core/package.js && \
+ cd /home/wekan/.meteor && \
+ /home/wekan/.meteor/meteor -- help;
+
+RUN \
+ set -o xtrace && \
+ # Build app
+ cd /home/wekan/app && \
+ /home/wekan/.meteor/meteor add standard-minifier-js && \
+ /home/wekan/.meteor/meteor npm install && \
+ /home/wekan/.meteor/meteor build --directory /home/wekan/app_build
+
+RUN \
+ set -o xtrace && \
+ cd /home/wekan/app_build/bundle/programs/server/ && \
+ chmod u+w package.json npm-shrinkwrap.json && \
+ npm install
+
+ENV PORT=3000
+EXPOSE $PORT
+WORKDIR /home/wekan/app
+
+CMD ["/home/wekan/.meteor/meteor", "run", "--verbose", "--settings", "settings.json"]
diff --git a/.devcontainer/docker-compose.yml b/.devcontainer/docker-compose.yml
index fab770560..d1e91b858 100644
--- a/.devcontainer/docker-compose.yml
+++ b/.devcontainer/docker-compose.yml
@@ -3,17 +3,18 @@ version: '3.7'
services:
wekandb-dev:
- image: mongo:4.0.12
+ image: mongo:4.4
container_name: wekan-dev-db
restart: unless-stopped
- command: mongod --smallfiles --oplogSize 128
+ command: mongod --oplogSize 128
networks:
- wekan-dev-tier
expose:
- 27017
volumes:
- - wekan-dev-db:/data/db
- - wekan-dev-db-dump:/dump
+ - ./volumes/wekan-db:/data/db
+ - ./volumes/wekan-db-dump:/dump
+ - /etc/localtime:/etc/localtime:ro
wekan-dev:
container_name: wekan-dev-app
@@ -35,9 +36,13 @@ services:
depends_on:
- wekandb-dev
volumes:
- - ..:/app:delegated
- command:
- sleep infinity
+ - ../client:/home/wekan/app/client
+ - ../models:/home/wekan/app/models
+ - ../config:/home/wekan/app/config
+ - ../i18n:/home/wekan/app/i18n
+ - ../server:/home/wekan/app/server
+ - ../public:/home/wekan/app/public
+ - /etc/localtime:/etc/localtime:ro
volumes:
wekan-dev-db:
diff --git a/.dockerignore b/.dockerignore
new file mode 100644
index 000000000..88a4b6897
--- /dev/null
+++ b/.dockerignore
@@ -0,0 +1,36 @@
+*~
+*.swp
+.meteor-spk
+*.sublime-workspace
+tmp/
+node_modules/
+npm-debug.log
+.gitmodules
+.vscode/
+.idea/
+.build/*
+**/parts/
+**/stage
+**/prime
+**/*.snap
+snap/.snapcraft/
+.idea
+.DS_Store
+.DS_Store?
+.build*
+*.browserify.js.cached
+*.browserify.js.map
+.build*
+versions.json
+.versions
+.npm
+.build*
+._*
+.Trashes
+Thumbs.db
+ehthumbs.db
+.eslintcache
+.meteor/local
+.devcontainer/docker-compose.extend.yml
+.devcontainer/volumes*/
+.git
diff --git a/.gitignore b/.gitignore
index 7037d0625..b108de038 100644
--- a/.gitignore
+++ b/.gitignore
@@ -32,3 +32,4 @@ ehthumbs.db
.eslintcache
.meteor/local
.devcontainer/docker-compose.extend.yml
+.devcontainer/volumes*/
diff --git a/.meteor/packages b/.meteor/packages
index d94755f7a..10ddbb158 100644
--- a/.meteor/packages
+++ b/.meteor/packages
@@ -83,7 +83,6 @@ mquandalle:moment
msavin:usercache
# Keep stylus in 1.1.0, because building v2 takes extra 52 minutes.
coagmano:stylus@1.1.0!
-lucasantoniassi:accounts-lockout
meteorhacks:subs-manager
meteorhacks:picker
lamhieu:unblock
@@ -144,3 +143,5 @@ rajit:bootstrap3-datepicker-zh-tw
staringatlights:fast-render
spacebars
easylogic:summernote
+pascoual:pdfkit
+wekan-accounts-lockout
diff --git a/.meteor/versions b/.meteor/versions
index 718c63b7c..c61075b8a 100644
--- a/.meteor/versions
+++ b/.meteor/versions
@@ -71,7 +71,6 @@ launch-screen@1.2.1
livedata@1.0.18
localstorage@1.2.0
logging@1.2.0
-lucasantoniassi:accounts-lockout@1.0.0
matb33:collection-hooks@0.9.1
matteodem:easy-search@1.6.4
mdg:validation-error@0.5.1
@@ -114,6 +113,7 @@ oauth2@1.3.0
observe-sequence@1.0.16
ongoworks:speakingurl@1.1.0
ordered-dict@1.1.0
+pascoual:pdfkit@1.0.7
peerlibrary:assert@0.3.0
peerlibrary:base-component@0.16.0
peerlibrary:blaze-components@0.15.1
@@ -219,6 +219,7 @@ verron:autosize@3.0.8
webapp@1.10.1
webapp-hashing@1.1.0
wekan-accounts-cas@0.1.0
+wekan-accounts-lockout@1.0.0
wekan-accounts-oidc@1.0.10
wekan-cfs-access-point@0.1.50
wekan-cfs-base-package@0.0.30
diff --git a/CHANGELOG.md b/CHANGELOG.md
index f57e1b603..a1ec03d18 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,84 @@
[Mac ChangeLog](https://github.com/wekan/wekan/wiki/Mac)
+# Upcoming Wekan release
+
+This release adds the following new features:
+
+- Wait Spinners can now be translated
+ [Part 1](https://github.com/wekan/wekan/commit/8703dd42296d531450eb21a3d3adea17558a8500),
+ [Part 1](https://github.com/wekan/wekan/commit/7f3f0825573b1f8a7b0388e4bacbb0bd2525e886).
+ Added Wait Spinners docs: https://github.com/wekan/wekan/wiki/Wait-Spinners .
+ Thanks to xet7.
+- [Maximize Card. In Progress](https://github.com/wekan/wekan/commit/8c572502436a2eb22bd1eb1e4069c1c9145e2070).
+ Thanks to xet7.
+- Export Card to PDF. In Progress.
+ [Part 1](https://github.com/wekan/wekan/commit/a2f2ce11354a8dbfdd6759e3b65797e4be4cc6ec),
+ [Part 2](https://github.com/wekan/wekan/commit/17acf1884850d8d95ae79493289adf18966df652).
+ Thanks to xet7.
+
+and removes some not needed files:
+
+- [Reduced Wekan bundle size from 636 MB to 467 MB by deleting all dependencies of lucasantoniassi:accounts-lockout and including
+ only required 10 files](https://github.com/wekan/wekan/commit/23e5e1e3bd081699ce39ce5887db7e612616014d).
+ Wekan Docker image size changed from 269.6 MB to 165.1 MB.
+ Thanks to xet7.
+
+and adds the following improvements:
+
+- [Add border and update label colors for better visibility](https://github.com/wekan/wekan/commit/2e1eb1e224c83f16a384316626d7a4183639d4cd).
+ Thanks to xet7.
+
+and fixes the following bugs:
+
+- [Manual sort number 0 accepted](https://github.com/wekan/wekan/pull/3861).
+ Thanks to mfilser.
+
+Thanks to above GitHub users for their contributions and translators for their translations.
+
+# v5.34 2021-06-11 Wekan release
+
+This release adds the following new features:
+
+- [View and change card sort number](https://github.com/wekan/wekan/pull/3857).
+ Thanks to mfilser.
+- [More spinners + configureable in admin panel](https://github.com/wekan/wekan/pull/3858).
+ Thanks to mfilser.
+- [Added remaining spinner settings](https://github.com/wekan/wekan/commit/488b765f95ad67b19630cd125543836c04eaa24f).
+ Thanks to xet7.
+
+and adds the following new improvements:
+
+- [Card Description has now the same color on view and editing](https://github.com/wekan/wekan/pull/3851).
+ Thanks to mfilser.
+- [Development in docker container](https://github.com/wekan/wekan/pull/3852).
+ Thanks to mfilser.
+
+and fixes the following bugs:
+
+- [Fix Google SSO to access Wekan has not been working by reverting Wekan v5.31 not-working fixes
+ to OAUTH2_LOGIN_STYLE=redirect Has No Effect](https://github.com/wekan/wekan/commit/1e837dec11dc5cb266b83efcff4f462aa02d733d).
+ Thanks to unpokitodxfavor and xet7.
+- [CustomFields were not created after adding 1 card](https://github.com/wekan/wekan/pull/3856).
+ Thanks to mfilser.
+- [Try to fix BUG: Database error attempting to change a account](https://github.com/wekan/wekan/commit/762391965e6ae3cd5682d5b164131500e7d92338).
+ Thanks to bbyszio and xet7.
+
+Thanks to above GitHub users for their contributions and translators for their translations.
+
+# v5.33 2021-06-10 Wekan release
+
+This release adds the following new features:
+
+- [Assigning a user to a team or an organization](https://github.com/wekan/wekan/pull/3850).
+ Thanks to Emile840.
+
+and adds the following new improvements:
+
+- [Custom Fields stringtemplate, autofocus the last input box](https://github.com/wekan/wekan/pull/3849).
+ Thanks to mfilser.
+
+Thanks to above GitHub users for their contributions and translators for their translations.
+
# v5.32 2021-06-09 Wekan release
This release adds the following new features:
diff --git a/Dockerfile b/Dockerfile
index 6ba008bad..57c53e746 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -137,7 +137,8 @@ ENV BUILD_DEPS="apt-utils libarchive-tools gnupg gosu wget curl bzip2 g++ build-
SAML_IDENTIFIER_FORMAT="" \
SAML_LOCAL_PROFILE_MATCH_ATTRIBUTE="" \
SAML_ATTRIBUTES="" \
- ORACLE_OIM_ENABLED=false
+ ORACLE_OIM_ENABLED=false \
+ WAIT_SPINNER=""
# Copy the app to the image
COPY ${SRC_PATH} /home/wekan/app
diff --git a/Stackerfile.yml b/Stackerfile.yml
index 18a99946c..bb95699c8 100644
--- a/Stackerfile.yml
+++ b/Stackerfile.yml
@@ -1,5 +1,5 @@
appId: wekan-public/apps/77b94f60-dec9-0136-304e-16ff53095928
-appVersion: "v5.32.0"
+appVersion: "v5.34.0"
files:
userUploads:
- README.md
diff --git a/client/components/cards/cardCustomFields.jade b/client/components/cards/cardCustomFields.jade
index 6fa1ac90e..8acf9f5e9 100644
--- a/client/components/cards/cardCustomFields.jade
+++ b/client/components/cards/cardCustomFields.jade
@@ -125,7 +125,7 @@ template(name="cardCustomField-stringtemplate")
+inlinedForm(classNames="js-card-customfield-stringtemplate")
each item in stringtemplateItems.get
input.js-card-customfield-stringtemplate-item(type="text" value=item placeholder="")
- input.js-card-customfield-stringtemplate-item.last(type="text" value="" placeholder="{{_ 'custom-field-stringtemplate-item-placeholder'}}")
+ input.js-card-customfield-stringtemplate-item.last(type="text" value="" placeholder="{{_ 'custom-field-stringtemplate-item-placeholder'}}" autofocus)
.edit-controls.clearfix
button.primary(type="submit") {{_ 'save'}}
a.fa.fa-times-thin.js-close-inlined-form
diff --git a/client/components/cards/cardDescription.styl b/client/components/cards/cardDescription.styl
index 5af497c77..fb4cbf23d 100644
--- a/client/components/cards/cardDescription.styl
+++ b/client/components/cards/cardDescription.styl
@@ -23,7 +23,6 @@
background-color: #fff
border: 0
box-shadow: 0 1px 2px rgba(0, 0, 0, .23)
- color: #8c8c8c
height: 36px
margin: 4px 4px 6px 0
padding: 9px 11px
diff --git a/client/components/cards/cardDetails.jade b/client/components/cards/cardDetails.jade
index da8bf5120..4aabf2eed 100644
--- a/client/components/cards/cardDetails.jade
+++ b/client/components/cards/cardDetails.jade
@@ -6,6 +6,10 @@ template(name="cardDetails")
else
unless isMiniScreen
a.fa.fa-times-thin.close-card-details.js-close-card-details(title="{{_ 'close-card'}}")
+ unless cardMaximized
+ a.fa.fa-window-maximize.maximize-card-details.js-maximize-card-details(title="{{_ 'maximize-card'}}")
+ if cardMaximized
+ a.fa.fa-window-minimize.minimize-card-details.js-minimize-card-details(title="{{_ 'minimize-card'}}")
if currentUser.isBoardMember
a.fa.fa-navicon.card-details-menu.js-open-card-details-menu(title="{{_ 'cardDetailsActionsPopup-title'}}")
input.inline-input(type="text" id="cardURL_copy" value="{{ originRelativeUrl }}")
@@ -41,485 +45,501 @@ template(name="cardDetails")
else
p.warning {{_ 'card-archived'}}
- .card-details-items
- if currentBoard.allowsLabels
- .card-details-item.card-details-item-labels
- h3.card-details-item-title
- i.fa.fa-tags
- | {{_ 'labels'}}
- a(class="{{#if canModifyCard}}js-add-labels{{else}}is-disabled{{/if}}" title="{{_ 'card-labels-title'}}")
- each labels
- span.card-label(class="card-label-{{color}}" title=name)
- +viewer
- = name
- if canModifyCard
- unless currentUser.isWorker
- a.card-label.add-label.js-add-labels(title="{{_ 'card-labels-title'}}")
- i.fa.fa-plus
+ .card-details-left
+
+ .card-details-items
+ if currentBoard.allowsLabels
+ .card-details-item.card-details-item-labels
+ h3.card-details-item-title
+ i.fa.fa-tags
+ | {{_ 'labels'}}
+ a(class="{{#if canModifyCard}}js-add-labels{{else}}is-disabled{{/if}}" title="{{_ 'card-labels-title'}}")
+ each labels
+ span.card-label(class="card-label-{{color}}" title=name)
+ +viewer
+ = name
+ if canModifyCard
+ unless currentUser.isWorker
+ a.card-label.add-label.js-add-labels(title="{{_ 'card-labels-title'}}")
+ i.fa.fa-plus
+
+ if currentBoard.allowsReceivedDate
+ hr
+ .card-details-item.card-details-item-received
+ h3.card-details-item-title
+ i.fa.fa-sign-out
+ | {{_ 'card-received'}}
+ if getReceived
+ +cardReceivedDate
+ else
+ if canModifyCard
+ unless currentUser.isWorker
+ a.card-label.add-label.js-received-date
+ i.fa.fa-plus
+
+ if currentBoard.allowsStartDate
+ .card-details-item.card-details-item-start
+ h3.card-details-item-title
+ i.fa.fa-hourglass-start
+ | {{_ 'card-start'}}
+ if getStart
+ +cardStartDate
+ else
+ if canModifyCard
+ unless currentUser.isWorker
+ a.card-label.add-label.js-start-date
+ i.fa.fa-plus
+
+ if currentBoard.allowsDueDate
+ .card-details-item.card-details-item-due
+ h3.card-details-item-title
+ i.fa.fa-sign-in
+ | {{_ 'card-due'}}
+ if getDue
+ +cardDueDate
+ else
+ if canModifyCard
+ unless currentUser.isWorker
+ a.card-label.add-label.js-due-date
+ i.fa.fa-plus
+
+ if currentBoard.allowsEndDate
+ .card-details-item.card-details-item-end
+ h3.card-details-item-title
+ i.fa.fa-hourglass-end
+ | {{_ 'card-end'}}
+ if getEnd
+ +cardEndDate
+ else
+ if canModifyCard
+ unless currentUser.isWorker
+ a.card-label.add-label.js-end-date
+ i.fa.fa-plus
- if currentBoard.allowsReceivedDate
hr
- .card-details-item.card-details-item-received
- h3.card-details-item-title
- i.fa.fa-sign-out
- | {{_ 'card-received'}}
- if getReceived
- +cardReceivedDate
- else
- if canModifyCard
- unless currentUser.isWorker
- a.card-label.add-label.js-received-date
- i.fa.fa-plus
+ if currentBoard.allowsCreator
+ .card-details-item.card-details-item-creator
+ h3.card-details-item-title
+ i.fa.fa-user
+ | {{_ 'creator'}}
- if currentBoard.allowsStartDate
- .card-details-item.card-details-item-start
- h3.card-details-item-title
- i.fa.fa-hourglass-start
- | {{_ 'card-start'}}
- if getStart
- +cardStartDate
- else
- if canModifyCard
- unless currentUser.isWorker
- a.card-label.add-label.js-start-date
- i.fa.fa-plus
-
- if currentBoard.allowsDueDate
- .card-details-item.card-details-item-due
- h3.card-details-item-title
- i.fa.fa-sign-in
- | {{_ 'card-due'}}
- if getDue
- +cardDueDate
- else
- if canModifyCard
- unless currentUser.isWorker
- a.card-label.add-label.js-due-date
- i.fa.fa-plus
-
- if currentBoard.allowsEndDate
- .card-details-item.card-details-item-end
- h3.card-details-item-title
- i.fa.fa-hourglass-end
- | {{_ 'card-end'}}
- if getEnd
- +cardEndDate
- else
- if canModifyCard
- unless currentUser.isWorker
- a.card-label.add-label.js-end-date
- i.fa.fa-plus
-
- hr
- if currentBoard.allowsCreator
- .card-details-item.card-details-item-creator
- h3.card-details-item-title
- i.fa.fa-user
- | {{_ 'creator'}}
-
- +userAvatar(userId=userId noRemove=true)
- | {{! XXX Hack to hide syntaxic coloration /// }}
-
- //.card-details-items
- if currentBoard.allowsMembers
- .card-details-item.card-details-item-members
- h3.card-details-item-title
- i.fa.fa-users
- | {{_ 'members'}}
- each userId in getMembers
- +userAvatar(userId=userId cardId=_id)
+ +userAvatar(userId=userId noRemove=true)
| {{! XXX Hack to hide syntaxic coloration /// }}
- if canModifyCard
- unless currentUser.isWorker
- a.member.add-member.card-details-item-add-button.js-add-members(title="{{_ 'card-members-title'}}")
- i.fa.fa-plus
- //if assigneeSelected
- if currentBoard.allowsAssignee
- .card-details-item.card-details-item-assignees
- h3.card-details-item-title
- i.fa.fa-user
- | {{_ 'assignee'}}
- each userId in getAssignees
- +userAvatar(userId=userId cardId=_id assignee=true)
- | {{! XXX Hack to hide syntaxic coloration /// }}
- if canModifyCard
- a.assignee.add-assignee.card-details-item-add-button.js-add-assignees(title="{{_ 'assignee'}}")
- i.fa.fa-plus
- if currentUser.isWorker
- unless assigneeSelected
+ //.card-details-items
+ if currentBoard.allowsMembers
+ .card-details-item.card-details-item-members
+ h3.card-details-item-title
+ i.fa.fa-users
+ | {{_ 'members'}}
+ each userId in getMembers
+ +userAvatar(userId=userId cardId=_id)
+ | {{! XXX Hack to hide syntaxic coloration /// }}
+ if canModifyCard
+ unless currentUser.isWorker
+ a.member.add-member.card-details-item-add-button.js-add-members(title="{{_ 'card-members-title'}}")
+ i.fa.fa-plus
+
+ //if assigneeSelected
+ if currentBoard.allowsAssignee
+ .card-details-item.card-details-item-assignees
+ h3.card-details-item-title
+ i.fa.fa-user
+ | {{_ 'assignee'}}
+ each userId in getAssignees
+ +userAvatar(userId=userId cardId=_id assignee=true)
+ | {{! XXX Hack to hide syntaxic coloration /// }}
+ if canModifyCard
a.assignee.add-assignee.card-details-item-add-button.js-add-assignees(title="{{_ 'assignee'}}")
i.fa.fa-plus
+ if currentUser.isWorker
+ unless assigneeSelected
+ a.assignee.add-assignee.card-details-item-add-button.js-add-assignees(title="{{_ 'assignee'}}")
+ i.fa.fa-plus
- //.card-details-items
- if getSpentTime
- .card-details-item.card-details-item-spent
- if getIsOvertime
- h3.card-details-item-title
- | {{_ 'overtime-hours'}}
- else
- h3.card-details-item-title
- | {{_ 'spent-time-hours'}}
- +cardSpentTime
+ //.card-details-items
+ if getSpentTime
+ .card-details-item.card-details-item-spent
+ if getIsOvertime
+ h3.card-details-item-title
+ | {{_ 'overtime-hours'}}
+ else
+ h3.card-details-item-title
+ | {{_ 'spent-time-hours'}}
+ +cardSpentTime
- //.card-details-items
- if currentBoard.allowsRequestedBy
- .card-details-item.card-details-item-name
- h3.card-details-item-title
- i.fa.fa-shopping-cart
- | {{_ 'requested-by'}}
- if canModifyCard
- unless currentUser.isWorker
- +inlinedForm(classNames="js-card-details-requester")
- +editCardRequesterForm
+ //.card-details-items
+ if currentBoard.allowsRequestedBy
+ .card-details-item.card-details-item-name
+ h3.card-details-item-title
+ i.fa.fa-shopping-cart
+ | {{_ 'requested-by'}}
+ if canModifyCard
+ unless currentUser.isWorker
+ +inlinedForm(classNames="js-card-details-requester")
+ +editCardRequesterForm
+ else
+ a.js-open-inlined-form
+ if getRequestedBy
+ +viewer
+ = getRequestedBy
+ else
+ | {{_ 'add'}}
+ else if getRequestedBy
+ +viewer
+ = getRequestedBy
+
+ if currentBoard.allowsAssignedBy
+ .card-details-item.card-details-item-name
+ h3.card-details-item-title
+ i.fa.fa-user-plus
+ | {{_ 'assigned-by'}}
+ if canModifyCard
+ unless currentUser.isWorker
+ +inlinedForm(classNames="js-card-details-assigner")
+ +editCardAssignerForm
+ else
+ a.js-open-inlined-form
+ if getAssignedBy
+ +viewer
+ = getAssignedBy
+ else
+ | {{_ 'add'}}
+ else if getRequestedBy
+ +viewer
+ = getAssignedBy
+
+ if currentBoard.allowsCardSortingByNumber
+ .card-details-item.card-details-sort-order
+ h3.card-details-item-title
+ i.fa.fa-sort
+ | {{_ 'sort'}}
+ if canModifyCard
+ +inlinedForm(classNames="js-card-details-sort")
+ +editCardSortOrderForm
else
a.js-open-inlined-form
- if getRequestedBy
- +viewer
- = getRequestedBy
- else
- | {{_ 'add'}}
- else if getRequestedBy
- +viewer
- = getRequestedBy
+ +viewer
+ = sort
- if currentBoard.allowsAssignedBy
- .card-details-item.card-details-item-name
- h3.card-details-item-title
- i.fa.fa-user-plus
- | {{_ 'assigned-by'}}
- if canModifyCard
- unless currentUser.isWorker
- +inlinedForm(classNames="js-card-details-assigner")
- +editCardAssignerForm
- else
- a.js-open-inlined-form
- if getAssignedBy
- +viewer
- = getAssignedBy
- else
- | {{_ 'add'}}
- else if getRequestedBy
- +viewer
- = getAssignedBy
+ //.card-details-items
+ if customFieldsWD
+ hr
+ each customFieldsWD
+ .card-details-item.card-details-item-customfield
+ h3.card-details-item-title
+ i.fa.fa-list-alt
+ = definition.name
+ +cardCustomField
- //.card-details-items
- if customFieldsWD
+ if getVoteQuestion
hr
- each customFieldsWD
- .card-details-item.card-details-item-customfield
- h3.card-details-item-title
- i.fa.fa-list-alt
- = definition.name
- +cardCustomField
+ .vote-title
+ div.flex
+ h3
+ i.fa.fa-thumbs-up
+ | {{_ 'vote-question'}}
+ if getVoteEnd
+ +voteEndDate
+ .vote-result
+ if votePublic
+ a.card-label.card-label-green.js-show-positive-votes {{ voteCountPositive }}
+ a.card-label.card-label-red.js-show-negative-votes {{ voteCountNegative }}
+ else
+ .card-label.card-label-green {{ voteCountPositive }}
+ .card-label.card-label-red {{ voteCountNegative }}
+ unless ($and currentBoard.isPublic voteAllowNonBoardMembers )
+ .card-label.card-label-gray {{ voteCount }} {{_ 'r-of' }} {{ currentBoard.activeMembers.length }}
+ +viewer
+ = getVoteQuestion
+ if showVotingButtons
+ button.card-details-green.js-vote.js-vote-positive(class="{{#if voteState}}voted{{/if}}")
+ if voteState
+ i.fa.fa-thumbs-up
+ | {{_ 'vote-for-it'}}
+ button.card-details-red.js-vote.js-vote-negative(class="{{#if $eq voteState false}}voted{{/if}}")
+ if $eq voteState false
+ i.fa.fa-thumbs-down
+ | {{_ 'vote-against'}}
- if getVoteQuestion
- hr
- .vote-title
- div.flex
- h3
- i.fa.fa-thumbs-up
- | {{_ 'vote-question'}}
- if getVoteEnd
- +voteEndDate
- .vote-result
- if votePublic
- a.card-label.card-label-green.js-show-positive-votes {{ voteCountPositive }}
- a.card-label.card-label-red.js-show-negative-votes {{ voteCountNegative }}
- else
- .card-label.card-label-green {{ voteCountPositive }}
- .card-label.card-label-red {{ voteCountNegative }}
- unless ($and currentBoard.isPublic voteAllowNonBoardMembers )
- .card-label.card-label-gray {{ voteCount }} {{_ 'r-of' }} {{ currentBoard.activeMembers.length }}
- +viewer
- = getVoteQuestion
- if showVotingButtons
- button.card-details-green.js-vote.js-vote-positive(class="{{#if voteState}}voted{{/if}}")
- if voteState
- i.fa.fa-thumbs-up
- | {{_ 'vote-for-it'}}
- button.card-details-red.js-vote.js-vote-negative(class="{{#if $eq voteState false}}voted{{/if}}")
- if $eq voteState false
- i.fa.fa-thumbs-down
- | {{_ 'vote-against'}}
-
- if getPokerQuestion
- hr
- .poker-title
- div.flex
- h3
- i.fa.fa-thumbs-up
- | {{_ 'poker-question'}}
- if getPokerEnd
- +pokerEndDate
- div.flex
+ if getPokerQuestion
+ hr
+ .poker-title
+ div.flex
+ h3
+ i.fa.fa-thumbs-up
+ | {{_ 'poker-question'}}
+ if getPokerEnd
+ +pokerEndDate
+ div.flex
+ .poker-result
+ if expiredPoker
+ unless ($and currentBoard.isPublic pokerAllowNonBoardMembers )
+ .card-label.card-label-gray {{ pokerCount }} {{_ 'r-of' }} {{ currentBoard.activeMembers.length }}
+ if showPlanningPokerButtons
.poker-result
- if expiredPoker
- unless ($and currentBoard.isPublic pokerAllowNonBoardMembers )
- .card-label.card-label-gray {{ pokerCount }} {{_ 'r-of' }} {{ currentBoard.activeMembers.length }}
- if showPlanningPokerButtons
- .poker-result
- .poker-deck
- .poker-card
- span.inner.js-poker.js-poker-vote-one(class="{{#if $eq pokerState 'one'}}poker-voted{{/if}}") {{_ 'poker-one'}}
- if $eq pokerState "one"
- i.fa.fa-check
- .poker-deck
- .poker-card
- span.inner.js-poker.js-poker-vote-two(class="{{#if $eq pokerState 'two'}}poker-voted{{/if}}") {{_ 'poker-two'}}
- if $eq pokerState "two"
- i.fa.fa-check
- .poker-deck
- .poker-card
- span.inner.js-poker.js-poker-vote-three(class="{{#if $eq pokerState 'three'}}poker-voted{{/if}}") {{_ 'poker-three'}}
- if $eq pokerState "three"
- i.fa.fa-check
- .poker-deck
- .poker-card
- span.inner.js-poker.js-poker-vote-five(class="{{#if $eq pokerState 'five'}}poker-voted{{/if}}") {{_ 'poker-five'}}
- if $eq pokerState "five"
- i.fa.fa-check
- .poker-deck
- .poker-card
- span.inner.js-poker.js-poker-vote-eight(class="{{#if $eq pokerState 'eight'}}poker-voted{{/if}}") {{_ 'poker-eight'}}
- if $eq pokerState "eight"
- i.fa.fa-check
- .poker-deck
- .poker-card
- span.inner.js-poker.js-poker-vote-thirteen(class="{{#if $eq pokerState 'thirteen'}}poker-voted{{/if}}") {{_ 'poker-thirteen'}}
- if $eq pokerState "thirteen"
- i.fa.fa-check
- .poker-deck
- .poker-card
- span.inner.js-poker.js-poker-vote-twenty(class="{{#if $eq pokerState 'twenty'}}poker-voted{{/if}}") {{_ 'poker-twenty'}}
- if $eq pokerState "twenty"
- i.fa.fa-check
- .poker-deck
- .poker-card
- span.inner.js-poker.js-poker-vote-forty(class="{{#if $eq pokerState 'forty'}}poker-voted{{/if}}") {{_ 'poker-forty'}}
- if $eq pokerState "forty"
- i.fa.fa-check
- .poker-deck
- .poker-card
- span.inner.js-poker.js-poker-vote-one-hundred(class="{{#if $eq pokerState 'oneHundred'}}poker-voted{{/if}}") {{_ 'poker-oneHundred'}}
- if $eq pokerState "oneHundred"
- i.fa.fa-check
- .poker-deck
- .poker-card
- span.inner.js-poker.js-poker-vote-unsure(class="{{#if $eq pokerState 'unsure'}}poker-voted{{/if}}") {{_ 'poker-unsure'}}
- if $eq pokerState "unsure"
- i.fa.fa-check
+ .poker-deck
+ .poker-card
+ span.inner.js-poker.js-poker-vote-one(class="{{#if $eq pokerState 'one'}}poker-voted{{/if}}") {{_ 'poker-one'}}
+ if $eq pokerState "one"
+ i.fa.fa-check
+ .poker-deck
+ .poker-card
+ span.inner.js-poker.js-poker-vote-two(class="{{#if $eq pokerState 'two'}}poker-voted{{/if}}") {{_ 'poker-two'}}
+ if $eq pokerState "two"
+ i.fa.fa-check
+ .poker-deck
+ .poker-card
+ span.inner.js-poker.js-poker-vote-three(class="{{#if $eq pokerState 'three'}}poker-voted{{/if}}") {{_ 'poker-three'}}
+ if $eq pokerState "three"
+ i.fa.fa-check
+ .poker-deck
+ .poker-card
+ span.inner.js-poker.js-poker-vote-five(class="{{#if $eq pokerState 'five'}}poker-voted{{/if}}") {{_ 'poker-five'}}
+ if $eq pokerState "five"
+ i.fa.fa-check
+ .poker-deck
+ .poker-card
+ span.inner.js-poker.js-poker-vote-eight(class="{{#if $eq pokerState 'eight'}}poker-voted{{/if}}") {{_ 'poker-eight'}}
+ if $eq pokerState "eight"
+ i.fa.fa-check
+ .poker-deck
+ .poker-card
+ span.inner.js-poker.js-poker-vote-thirteen(class="{{#if $eq pokerState 'thirteen'}}poker-voted{{/if}}") {{_ 'poker-thirteen'}}
+ if $eq pokerState "thirteen"
+ i.fa.fa-check
+ .poker-deck
+ .poker-card
+ span.inner.js-poker.js-poker-vote-twenty(class="{{#if $eq pokerState 'twenty'}}poker-voted{{/if}}") {{_ 'poker-twenty'}}
+ if $eq pokerState "twenty"
+ i.fa.fa-check
+ .poker-deck
+ .poker-card
+ span.inner.js-poker.js-poker-vote-forty(class="{{#if $eq pokerState 'forty'}}poker-voted{{/if}}") {{_ 'poker-forty'}}
+ if $eq pokerState "forty"
+ i.fa.fa-check
+ .poker-deck
+ .poker-card
+ span.inner.js-poker.js-poker-vote-one-hundred(class="{{#if $eq pokerState 'oneHundred'}}poker-voted{{/if}}") {{_ 'poker-oneHundred'}}
+ if $eq pokerState "oneHundred"
+ i.fa.fa-check
+ .poker-deck
+ .poker-card
+ span.inner.js-poker.js-poker-vote-unsure(class="{{#if $eq pokerState 'unsure'}}poker-voted{{/if}}") {{_ 'poker-unsure'}}
+ if $eq pokerState "unsure"
+ i.fa.fa-check
- if currentUser.isBoardAdmin
- button.card-details-blue.js-poker-finish(class="{{#if $eq voteState false}}poker-voted{{/if}}") {{_ 'poker-finish'}}
+ if currentUser.isBoardAdmin
+ button.card-details-blue.js-poker-finish(class="{{#if $eq voteState false}}poker-voted{{/if}}") {{_ 'poker-finish'}}
- if expiredPoker
- .poker-table
- .poker-table-side-left
- .poker-table-heading-left
- .poker-table-row
- .poker-table-cell
- .poker-table-cell
- | {{_ 'poker-result-votes' }}
- .poker-table-cell.poker-table-cell-who
- | {{_ 'poker-result-who' }}
- .poker-table-body
- .poker-table-row
- .poker-table-cell
- button.card-details-gray.js-poker.poker-card-result(class="{{#if $eq pokerWinner 1}}winner{{else}}loser{{/if}}") {{_ 'poker-one'}}
- .poker-table-cell {{ pokerCountOne }}
- .poker-table-cell.poker-table-cell-who
- .poker-result
- each m in pokerMemberOne
- a.name
- +userAvatar(userId=m._id noRemove=true)
+ if expiredPoker
+ .poker-table
+ .poker-table-side-left
+ .poker-table-heading-left
+ .poker-table-row
+ .poker-table-cell
+ .poker-table-cell
+ | {{_ 'poker-result-votes' }}
+ .poker-table-cell.poker-table-cell-who
+ | {{_ 'poker-result-who' }}
+ .poker-table-body
+ .poker-table-row
+ .poker-table-cell
+ button.card-details-gray.js-poker.poker-card-result(class="{{#if $eq pokerWinner 1}}winner{{else}}loser{{/if}}") {{_ 'poker-one'}}
+ .poker-table-cell {{ pokerCountOne }}
+ .poker-table-cell.poker-table-cell-who
+ .poker-result
+ each m in pokerMemberOne
+ a.name
+ +userAvatar(userId=m._id noRemove=true)
- .poker-table-row
- .poker-table-cell
- button.card-details-gray.js-poker.poker-card-result(class="{{#if $eq pokerWinner 2}}winner{{else}}loser{{/if}}") {{_ 'poker-two'}}
- .poker-table-cell {{ pokerCountTwo }}
- .poker-table-cell.poker-table-cell-who
- .poker-result
- each m in pokerMemberTwo
- a.name
- +userAvatar(userId=m._id noRemove=true)
+ .poker-table-row
+ .poker-table-cell
+ button.card-details-gray.js-poker.poker-card-result(class="{{#if $eq pokerWinner 2}}winner{{else}}loser{{/if}}") {{_ 'poker-two'}}
+ .poker-table-cell {{ pokerCountTwo }}
+ .poker-table-cell.poker-table-cell-who
+ .poker-result
+ each m in pokerMemberTwo
+ a.name
+ +userAvatar(userId=m._id noRemove=true)
- .poker-table-row
- .poker-table-cell
- button.card-details-gray.js-poker.poker-card-result(class="{{#if $eq pokerWinner 3}}winner{{else}}loser{{/if}}") {{_ 'poker-three'}}
- .poker-table-cell {{ pokerCountThree }}
- .poker-table-cell.poker-table-cell-who
- .poker-result
- each m in pokerMemberThree
- a.name
- +userAvatar(userId=m._id noRemove=true)
+ .poker-table-row
+ .poker-table-cell
+ button.card-details-gray.js-poker.poker-card-result(class="{{#if $eq pokerWinner 3}}winner{{else}}loser{{/if}}") {{_ 'poker-three'}}
+ .poker-table-cell {{ pokerCountThree }}
+ .poker-table-cell.poker-table-cell-who
+ .poker-result
+ each m in pokerMemberThree
+ a.name
+ +userAvatar(userId=m._id noRemove=true)
- .poker-table-row
- .poker-table-cell
- button.card-details-gray.js-poker.poker-card-result(class="{{#if $eq pokerWinner 5}}winner{{else}}loser{{/if}}") {{_ 'poker-five'}}
- .poker-table-cell {{ pokerCountFive }}
- .poker-table-cell.poker-table-cell-who
- .poker-result
- each m in pokerMemberFive
- a.name
- +userAvatar(userId=m._id noRemove=true)
+ .poker-table-row
+ .poker-table-cell
+ button.card-details-gray.js-poker.poker-card-result(class="{{#if $eq pokerWinner 5}}winner{{else}}loser{{/if}}") {{_ 'poker-five'}}
+ .poker-table-cell {{ pokerCountFive }}
+ .poker-table-cell.poker-table-cell-who
+ .poker-result
+ each m in pokerMemberFive
+ a.name
+ +userAvatar(userId=m._id noRemove=true)
- .poker-table-row
- .poker-table-cell
- button.card-details-gray.js-poker.poker-card-result(class="{{#if $eq pokerWinner 8}}winner{{else}}loser{{/if}}") {{_ 'poker-eight'}}
- .poker-table-cell {{ pokerCountEight }}
- .poker-table-cell.poker-table-cell-who
- .poker-result
- each m in pokerMemberEight
- a.name
- +userAvatar(userId=m._id noRemove=true)
+ .poker-table-row
+ .poker-table-cell
+ button.card-details-gray.js-poker.poker-card-result(class="{{#if $eq pokerWinner 8}}winner{{else}}loser{{/if}}") {{_ 'poker-eight'}}
+ .poker-table-cell {{ pokerCountEight }}
+ .poker-table-cell.poker-table-cell-who
+ .poker-result
+ each m in pokerMemberEight
+ a.name
+ +userAvatar(userId=m._id noRemove=true)
- .poker-table-side-right
- .poker-table-heading-right
- .poker-table-row
- .poker-table-cell
- .poker-table-cell
- | {{_ 'poker-result-votes' }}
- .poker-table-cell.poker-table-cell-who
- | {{_ 'poker-result-who' }}
- .poker-table-body
- .poker-table-row
- .poker-table-cell
- button.card-details-gray.js-poker.poker-card-result(class="{{#if $eq pokerWinner 13}}winner{{else}}loser{{/if}}") {{_ 'poker-thirteen'}}
- .poker-table-cell {{ pokerCountThirteen }}
- .poker-table-cell.poker-table-cell-who
- .poker-result
- each m in pokerMemberThirteen
- a.name
- +userAvatar(userId=m._id noRemove=true)
+ .poker-table-side-right
+ .poker-table-heading-right
+ .poker-table-row
+ .poker-table-cell
+ .poker-table-cell
+ | {{_ 'poker-result-votes' }}
+ .poker-table-cell.poker-table-cell-who
+ | {{_ 'poker-result-who' }}
+ .poker-table-body
+ .poker-table-row
+ .poker-table-cell
+ button.card-details-gray.js-poker.poker-card-result(class="{{#if $eq pokerWinner 13}}winner{{else}}loser{{/if}}") {{_ 'poker-thirteen'}}
+ .poker-table-cell {{ pokerCountThirteen }}
+ .poker-table-cell.poker-table-cell-who
+ .poker-result
+ each m in pokerMemberThirteen
+ a.name
+ +userAvatar(userId=m._id noRemove=true)
- .poker-table-row
- .poker-table-cell
- button.card-details-gray.js-poker.poker-card-result(class="{{#if $eq pokerWinner 20}}winner{{else}}loser{{/if}}") {{_ 'poker-twenty'}}
- .poker-table-cell {{ pokerCountTwenty }}
- .poker-table-cell.poker-table-cell-who
- .poker-result
- each m in pokerMemberTwenty
- a.name
- +userAvatar(userId=m._id noRemove=true)
+ .poker-table-row
+ .poker-table-cell
+ button.card-details-gray.js-poker.poker-card-result(class="{{#if $eq pokerWinner 20}}winner{{else}}loser{{/if}}") {{_ 'poker-twenty'}}
+ .poker-table-cell {{ pokerCountTwenty }}
+ .poker-table-cell.poker-table-cell-who
+ .poker-result
+ each m in pokerMemberTwenty
+ a.name
+ +userAvatar(userId=m._id noRemove=true)
- .poker-table-row
- .poker-table-cell
- button.card-details-gray.js-poker.poker-card-result(class="{{#if $eq pokerWinner 40}}winner{{else}}loser{{/if}}") {{_ 'poker-forty'}}
- .poker-table-cell {{ pokerCountForty }}
- .poker-table-cell.poker-table-cell-who
- .poker-result
- each m in pokerMemberForty
- a.name
- +userAvatar(userId=m._id noRemove=true)
+ .poker-table-row
+ .poker-table-cell
+ button.card-details-gray.js-poker.poker-card-result(class="{{#if $eq pokerWinner 40}}winner{{else}}loser{{/if}}") {{_ 'poker-forty'}}
+ .poker-table-cell {{ pokerCountForty }}
+ .poker-table-cell.poker-table-cell-who
+ .poker-result
+ each m in pokerMemberForty
+ a.name
+ +userAvatar(userId=m._id noRemove=true)
- .poker-table-row
- .poker-table-cell
- button.card-details-gray.js-poker.poker-card-result(class="{{#if $eq pokerWinner 100}}winner{{else}}loser{{/if}}") {{_ 'poker-oneHundred'}}
- .poker-table-cell {{ pokerCountOneHundred }}
- .poker-table-cell.poker-table-cell-who
- .poker-result
- each m in pokerMemberOneHundred
- a.name
- +userAvatar(userId=m._id noRemove=true)
+ .poker-table-row
+ .poker-table-cell
+ button.card-details-gray.js-poker.poker-card-result(class="{{#if $eq pokerWinner 100}}winner{{else}}loser{{/if}}") {{_ 'poker-oneHundred'}}
+ .poker-table-cell {{ pokerCountOneHundred }}
+ .poker-table-cell.poker-table-cell-who
+ .poker-result
+ each m in pokerMemberOneHundred
+ a.name
+ +userAvatar(userId=m._id noRemove=true)
- .poker-table-row
- .poker-table-cell
- button.card-details-gray.js-poker.poker-card-result(class="{{#if $eq pokerWinner 'unsure'}}winner{{else}}loser{{/if}}") {{_ 'poker-unsure'}}
- .poker-table-cell {{ pokerCountUnsure }}
- .poker-table-cell.poker-table-cell-who
- .poker-result
- each m in pokerMemberUnsure
- a.name
- +userAvatar(userId=m._id noRemove=true)
+ .poker-table-row
+ .poker-table-cell
+ button.card-details-gray.js-poker.poker-card-result(class="{{#if $eq pokerWinner 'unsure'}}winner{{else}}loser{{/if}}") {{_ 'poker-unsure'}}
+ .poker-table-cell {{ pokerCountUnsure }}
+ .poker-table-cell.poker-table-cell-who
+ .poker-result
+ each m in pokerMemberUnsure
+ a.name
+ +userAvatar(userId=m._id noRemove=true)
- if currentUser.isBoardAdmin
- div.estimation-add
- button.card-details-red.js-poker-replay(class="{{#if $eq voteState false}}voted{{/if}}") {{_ 'poker-replay'}}
- div.estimation-add
- button.js-poker-estimation
- i.fa.fa-plus
- | {{_ 'set-estimation'}}
- input(type=text,autofocus value=getPokerEstimation,id="pokerEstimation")
+ if currentUser.isBoardAdmin
+ div.estimation-add
+ button.card-details-red.js-poker-replay(class="{{#if $eq voteState false}}voted{{/if}}") {{_ 'poker-replay'}}
+ div.estimation-add
+ button.js-poker-estimation
+ i.fa.fa-plus
+ | {{_ 'set-estimation'}}
+ input(type=text,autofocus value=getPokerEstimation,id="pokerEstimation")
- //- XXX We should use "editable" to avoid repetiting ourselves
- if canModifyCard
- unless currentUser.isWorker
+ //- XXX We should use "editable" to avoid repetiting ourselves
+ if canModifyCard
+ unless currentUser.isWorker
+ if currentBoard.allowsDescriptionTitle
+ hr
+ h3.card-details-item-title
+ i.fa.fa-align-left
+ | {{_ 'description'}}
+ if currentBoard.allowsDescriptionText
+ +inlinedCardDescription(classNames="card-description js-card-description")
+ +descriptionForm
+ .edit-controls.clearfix
+ button.primary(type="submit") {{_ 'save'}}
+ a.fa.fa-times-thin.js-close-inlined-form
+ else
+ if currentBoard.allowsDescriptionText
+ a.js-open-inlined-form
+ if getDescription
+ +viewer
+ = getDescription
+ else
+ | {{_ 'edit'}}
+ if (hasUnsavedValue 'cardDescription' _id)
+ p.quiet
+ | {{_ 'unsaved-description'}}
+ a.js-open-inlined-form {{_ 'view-it'}}
+ = ' - '
+ a.js-close-inlined-form {{_ 'discard'}}
+ else if getDescription
if currentBoard.allowsDescriptionTitle
hr
- h3.card-details-item-title
- i.fa.fa-align-left
- | {{_ 'description'}}
+ h3.card-details-item-title {{_ 'description'}}
if currentBoard.allowsDescriptionText
- +inlinedCardDescription(classNames="card-description js-card-description")
- +descriptionForm
- .edit-controls.clearfix
- button.primary(type="submit") {{_ 'save'}}
- a.fa.fa-times-thin.js-close-inlined-form
- else
- if currentBoard.allowsDescriptionText
- a.js-open-inlined-form
- if getDescription
- +viewer
- = getDescription
- else
- | {{_ 'edit'}}
- if (hasUnsavedValue 'cardDescription' _id)
- p.quiet
- | {{_ 'unsaved-description'}}
- a.js-open-inlined-form {{_ 'view-it'}}
- = ' - '
- a.js-close-inlined-form {{_ 'discard'}}
- else if getDescription
- if currentBoard.allowsDescriptionTitle
- hr
- h3.card-details-item-title {{_ 'description'}}
- if currentBoard.allowsDescriptionText
- +viewer
- = getDescription
+ +viewer
+ = getDescription
- .card-checklist-attachmentGalerys
- .card-checklist-attachmentGalery.card-checklists
- if currentBoard.allowsChecklists
+ .card-checklist-attachmentGalerys
+ .card-checklist-attachmentGalery.card-checklists
+ if currentBoard.allowsChecklists
+ hr
+ +checklists(cardId = _id)
+ if currentBoard.allowsSubtasks
+ hr
+ +subtasks(cardId = _id)
+ if currentBoard.allowsAttachments
hr
- +checklists(cardId = _id)
- if currentBoard.allowsSubtasks
- hr
- +subtasks(cardId = _id)
- if currentBoard.allowsAttachments
- hr
- h3.card-details-item-title
- i.fa.fa-paperclip
- | {{_ 'attachments'}}
- .card-checklist-attachmentGalery.card-attachmentGalery
- +attachmentsGalery
+ h3.card-details-item-title
+ i.fa.fa-paperclip
+ | {{_ 'attachments'}}
+ .card-checklist-attachmentGalery.card-attachmentGalery
+ +attachmentsGalery
- hr
- unless currentUser.isNoComments
- .activity-title
- h3.card-details-item-title
- i.fa.fa-history
- | {{ _ 'activity'}}
+ .card-details-right
+
+ unless currentUser.isNoComments
+ .activity-title
+ h3.card-details-item-title
+ i.fa.fa-history
+ | {{ _ 'activity'}}
+ if currentUser.isBoardMember
+ .material-toggle-switch(title="{{_ 'hide-system-messages'}}")
+ //span.toggle-switch-title
+ if hiddenSystemMessages
+ input.toggle-switch(type="checkbox" id="toggleButton" checked="checked")
+ else
+ input.toggle-switch(type="checkbox" id="toggleButton")
+ label.toggle-label(for="toggleButton")
+ if currentBoard.allowsComments
if currentUser.isBoardMember
- .material-toggle-switch(title="{{_ 'hide-system-messages'}}")
- //span.toggle-switch-title
- if hiddenSystemMessages
- input.toggle-switch(type="checkbox" id="toggleButton" checked="checked")
- else
- input.toggle-switch(type="checkbox" id="toggleButton")
- label.toggle-label(for="toggleButton")
- if currentBoard.allowsComments
- if currentUser.isBoardMember
- unless currentUser.isNoComments
- +commentForm
- unless currentUser.isNoComments
- if isLoaded.get
- if isLinkedCard
- +activities(card=this mode="linkedcard")
- else if isLinkedBoard
- +activities(card=this mode="linkedboard")
- else
- +activities(card=this mode="card")
+ unless currentUser.isNoComments
+ +commentForm
+ unless currentUser.isNoComments
+ if isLoaded.get
+ if isLinkedCard
+ +activities(card=this mode="linkedcard")
+ else if isLinkedBoard
+ +activities(card=this mode="linkedboard")
+ else
+ +activities(card=this mode="card")
template(name="editCardTitleForm")
textarea.js-edit-card-title(rows='1' autofocus dir="auto")
@@ -540,6 +560,12 @@ template(name="editCardAssignerForm")
button.primary.confirm.js-submit-edit-card-assigner-form(type="submit") {{_ 'save'}}
a.fa.fa-times-thin.js-close-inlined-form
+template(name="editCardSortOrderForm")
+ input.js-edit-card-sort(type='text' autofocus value=sort dir="auto")
+ .edit-controls.clearfix
+ button.primary.confirm.js-submit-edit-card-sort-form(type="submit") {{_ 'save'}}
+ a.fa.fa-times-thin.js-close-inlined-form
+
template(name="cardDetailsActionsPopup")
ul.pop-over-list
li
@@ -550,9 +576,9 @@ template(name="cardDetailsActionsPopup")
else
i.fa.fa-eye-slash
| {{_ 'watch'}}
+ hr
if canModifyCard
unless currentUser.isWorker
- hr
ul.pop-over-list
//li: a.js-members {{_ 'card-edit-members'}}
//li: a.js-labels {{_ 'card-edit-labels'}}
@@ -582,50 +608,63 @@ template(name="cardDetailsActionsPopup")
a.js-set-card-color
i.fa.fa-paint-brush
| {{_ 'setCardColorPopup-title'}}
- hr
- ul.pop-over-list
+ hr
+ ul.pop-over-list
+ li
+ a.js-export-card
+ i.fa.fa-share-alt
+ | {{_ 'export-card'}}
+ hr
+ ul.pop-over-list
+ li
+ a.js-move-card-to-top
+ i.fa.fa-arrow-up
+ | {{_ 'moveCardToTop-title'}}
+ li
+ a.js-move-card-to-bottom
+ i.fa.fa-arrow-down
+ | {{_ 'moveCardToBottom-title'}}
+ hr
+ ul.pop-over-list
+ if currentUser.isBoardAdmin
li
- a.js-move-card-to-top
- i.fa.fa-arrow-up
- | {{_ 'moveCardToTop-title'}}
- li
- a.js-move-card-to-bottom
- i.fa.fa-arrow-down
- | {{_ 'moveCardToBottom-title'}}
- hr
- ul.pop-over-list
- if currentUser.isBoardAdmin
- li
- a.js-move-card
- i.fa.fa-arrow-right
- | {{_ 'moveCardPopup-title'}}
- unless currentUser.isWorker
- li
- a.js-copy-card
- i.fa.fa-copy
- | {{_ 'copyCardPopup-title'}}
+ a.js-move-card
+ i.fa.fa-arrow-right
+ | {{_ 'moveCardPopup-title'}}
unless currentUser.isWorker
+ li
+ a.js-copy-card
+ i.fa.fa-copy
+ | {{_ 'copyCardPopup-title'}}
+ unless currentUser.isWorker
+ hr
+ ul.pop-over-list
+ li
+ a.js-copy-checklist-cards
+ i.fa.fa-list
+ i.fa.fa-copy
+ | {{_ 'copyChecklistToManyCardsPopup-title'}}
+ unless archived
hr
ul.pop-over-list
li
- a.js-copy-checklist-cards
- i.fa.fa-list
- i.fa.fa-copy
- | {{_ 'copyChecklistToManyCardsPopup-title'}}
- unless archived
- hr
- ul.pop-over-list
- li
- a.js-archive
- i.fa.fa-arrow-right
- i.fa.fa-archive
- | {{_ 'archive-card'}}
- hr
- ul.pop-over-list
- li
- a.js-more
- i.fa.fa-link
- | {{_ 'cardMorePopup-title'}}
+ a.js-archive
+ i.fa.fa-arrow-right
+ i.fa.fa-archive
+ | {{_ 'archive-card'}}
+ hr
+ ul.pop-over-list
+ li
+ a.js-more
+ i.fa.fa-link
+ | {{_ 'cardMorePopup-title'}}
+
+template(name="exportCardPopup")
+ ul.pop-over-list
+ li
+ a(href="{{exportUrlCardPDF}}",, download="{{exportFilenameCardPDF}}")
+ i.fa.fa-share-alt
+ | {{_ 'export-card-pdf'}}
template(name="moveCardPopup")
+boardsAndLists
diff --git a/client/components/cards/cardDetails.js b/client/components/cards/cardDetails.js
index 8345460f0..10d5a9511 100644
--- a/client/components/cards/cardDetails.js
+++ b/client/components/cards/cardDetails.js
@@ -54,6 +54,10 @@ BlazeComponent.extendComponent({
return Meteor.user().hasHiddenSystemMessages();
},
+ cardMaximized() {
+ return Meteor.user().hasCardMaximized();
+ },
+
canModifyCard() {
return (
Meteor.user() &&
@@ -361,6 +365,16 @@ BlazeComponent.extendComponent({
this.data().setRequestedBy('');
}
},
+ 'submit .js-card-details-sort'(event) {
+ event.preventDefault();
+ const sort = parseFloat(this.currentComponent()
+ .getValue()
+ .trim());
+ if (!Number.isNaN(sort)) {
+ let card = this.data();
+ card.move(card.boardId, card.swimlaneId, card.listId, sort);
+ }
+ },
'click .js-go-to-linked-card'() {
Utils.goCardId(this.data().linkedId);
},
@@ -398,6 +412,14 @@ BlazeComponent.extendComponent({
'click #toggleButton'() {
Meteor.call('toggleSystemMessages');
},
+ 'click #js-maximize-card-details'() {
+ Meteor.call('toggleCardMaximized');
+ autosize($('.card-details'));
+ },
+ 'click #js-minimize-card-details'() {
+ Meteor.call('toggleCardMaximized');
+ autosize($('.card-details'));
+ },
'click .js-vote'(e) {
const forIt = $(e.target).hasClass('js-vote-positive');
let newState = null;
@@ -489,6 +511,47 @@ BlazeComponent.extendComponent({
},
}).register('cardDetails');
+BlazeComponent.extendComponent({
+ template() {
+ return 'exportCard';
+ },
+ withApi() {
+ return Template.instance().apiEnabled.get();
+ },
+ exportUrlCardPDF() {
+ const params = {
+ boardId: Session.get('currentBoard'),
+ listId: this.listId,
+ cardId: this.cardId,
+ };
+ const queryParams = {
+ authToken: Accounts._storedLoginToken(),
+ };
+ return FlowRouter.path(
+ '/api/boards/:boardId/lists/:listId/cards/:cardId/exportPDF',
+ params,
+ queryParams,
+ );
+ },
+ exportFilenameCardPDF() {
+ //const boardId = Session.get('currentBoard');
+ //return `export-card-pdf-${boardId}.xlsx`;
+ return `export-card.pdf`;
+ },
+}).register('exportCardPopup');
+
+// only allow number input
+Template.editCardSortOrderForm.onRendered(function() {
+ this.$('input').on("keypress paste", function(event) {
+ let keyCode = event.keyCode;
+ let charCode = String.fromCharCode(keyCode);
+ let regex = new RegExp('[-0-9.]');
+ let ret = regex.test(charCode);
+ // only working here, defining in events() doesn't handle the return value correctly
+ return ret;
+ });
+});
+
// We extends the normal InlinedForm component to support UnsavedEdits draft
// feature.
(class extends InlinedForm {
@@ -549,6 +612,7 @@ Template.cardDetailsActionsPopup.helpers({
});
Template.cardDetailsActionsPopup.events({
+ 'click .js-export-card': Popup.open('exportCard'),
'click .js-members': Popup.open('cardMembers'),
'click .js-assignees': Popup.open('cardAssignees'),
'click .js-labels': Popup.open('cardLabels'),
diff --git a/client/components/cards/cardDetails.styl b/client/components/cards/cardDetails.styl
index fe5c50bf6..9a57a25bd 100644
--- a/client/components/cards/cardDetails.styl
+++ b/client/components/cards/cardDetails.styl
@@ -86,21 +86,62 @@ avatar-radius = 50%
// Other card details
-.card-details
- padding: 0
- flex-shrink: 0
- flex-basis: 600px
- will-change: flex-basis
- overflow-y: scroll
- overflow-x: hidden
- background: darken(white, 3%)
- border-radius: bottom 3px
- z-index: 20 !important
- animation: flexGrowIn 0.1s
- box-shadow: 0 0 7px 0 darken(white, 30%)
- transition: flex-basis 0.1s
- box-sizing: border-box
+unless isMiniScreen
+ if cardMaximized
+ .card-details
+ padding: 0
+ flex-shrink: 0
+ flex-basis: calc(100% - 20px)
+ will-change: flex-basis
+ overflow-y: scroll
+ overflow-x: scroll
+ background: darken(white, 3%)
+ border-radius: bottom 3px
+ z-index: 1000 !important
+ animation: flexGrowIn 0.1s
+ box-shadow: 0 0 7px 0 darken(white, 30%)
+ transition: flex-basis 0.1s
+ box-sizing: border-box
+ position: absolute
+ top: 0
+ left: 0
+ height: calc(100% - 20px)
+ width: calc(100% - 20px)
+ float: left
+ .card-details-left
+ position: absolute
+ float: left
+ top: 60px
+ left: 20px
+ width: 47%
+
+ .card-details-right
+ position: absolute
+ float: right
+ top: 20px
+ left: 50%
+
+ .card-details-header
+ width: 47%
+
+if isMiniScreen
+ .card-details
+ padding: 0
+ flex-shrink: 0
+ flex-basis: 600px
+ will-change: flex-basis
+ overflow-y: scroll
+ overflow-x: hidden
+ background: darken(white, 3%)
+ border-radius: bottom 3px
+ z-index: 20 !important
+ animation: flexGrowIn 0.1s
+ box-shadow: 0 0 7px 0 darken(white, 30%)
+ transition: flex-basis 0.1s
+ box-sizing: border-box
+
+.card-details
.mCustomScrollBox
padding-left: 0
@@ -110,11 +151,13 @@ avatar-radius = 50%
.card-details-header
margin: 0 -20px 5px
- padding 7px 20px
+ padding: 7px 20px
background: darken(white, 7%)
border-bottom: 1px solid darken(white, 14%)
.close-card-details,
+ .maximize-card-details,
+ .minimize-card-details,
.card-details-menu,
.card-copy-button,
.card-copy-mobile-button,
@@ -122,7 +165,9 @@ avatar-radius = 50%
.card-details-menu-mobile-web
float: right
- .close-card-details
+ .close-card-details,
+ .maximize-card-details,
+ .minimize-card-details
font-size: 24px
padding: 5px
margin-right: -8px
@@ -260,7 +305,13 @@ input[type="submit"].attachment-add-link-submit
margin-right: 0px
.card-details-menu
- margin-right: 10px
+ margin-right: 40px
+
+ .maximize-card-details
+ margin-right: 40px
+
+ .minimize-card-details
+ margin-right: 40px
card-details-color(background, color...)
background: background !important
diff --git a/client/components/cards/labels.styl b/client/components/cards/labels.styl
index ee9466567..0e192e59f 100644
--- a/client/components/cards/labels.styl
+++ b/client/components/cards/labels.styl
@@ -44,9 +44,20 @@
align-items: center
justify-content: center
+.card-label-white
+ background-color: #ffffff
+ color: #000000 //Black text for better visibility
+ border: 1px solid #c0c0c0
+
+.card-label-white:hover
+ color: #aaaaaa //grey text for better visibility
+
.card-label-green
background-color: #3cb500
+.card-label-green:hover
+ color: #000000 //Black hover text for better visibility
+
.card-label-yellow
background-color: #fad900
color: #000000 //Black text for better visibility
diff --git a/client/components/cards/minicard.jade b/client/components/cards/minicard.jade
index 60d240a7c..925afec76 100644
--- a/client/components/cards/minicard.jade
+++ b/client/components/cards/minicard.jade
@@ -139,3 +139,7 @@ template(name="minicard")
span.badge-icon.fa.fa-sitemap
span.badge-text.check-list-text {{subtasksFinishedCount}}/{{allSubtasksCount}}
//{{subtasksFinishedCount}}/{{subtasksCount}} does not work because when a subtaks is archived, the count goes down
+ if currentBoard.allowsCardSortingByNumber
+ .badge
+ span.badge-icon.fa.fa-sort
+ span.badge-text {{ sort }}
diff --git a/client/components/lists/listBody.jade b/client/components/lists/listBody.jade
index ce671cdef..b286347a9 100644
--- a/client/components/lists/listBody.jade
+++ b/client/components/lists/listBody.jade
@@ -23,14 +23,10 @@ template(name="listBody")
i.fa.fa-plus
template(name="spinnerList")
- .sk-spinner.sk-spinner-wave.sk-spinner-list(
- class=currentBoard.colorClass
+ .sk-spinner.sk-spinner-list(
+ class="{{currentBoard.colorClass}} {{getSkSpinnerName}}"
id="showMoreResults")
- .sk-rect1
- .sk-rect2
- .sk-rect3
- .sk-rect4
- .sk-rect5
+ +spinnerRaw
template(name="addCardForm")
.minicard.minicard-composer.js-composer
diff --git a/client/components/lists/listBody.js b/client/components/lists/listBody.js
index 283034703..6073f3900 100644
--- a/client/components/lists/listBody.js
+++ b/client/components/lists/listBody.js
@@ -1,3 +1,5 @@
+import { Spinner } from '/client/lib/spinner';
+
const subManager = new SubsManager();
const InfiniteScrollIter = 10;
@@ -116,8 +118,6 @@ BlazeComponent.extendComponent({
if (position === 'bottom') {
this.scrollToBottom();
}
-
- formComponent.reset();
}
},
@@ -698,7 +698,7 @@ BlazeComponent.extendComponent({
},
}).register('searchElementPopup');
-BlazeComponent.extendComponent({
+(class extends Spinner {
onCreated() {
this.cardlimit = this.parentComponent().cardlimit;
@@ -726,7 +726,7 @@ BlazeComponent.extendComponent({
.parentComponent()
.data()._id;
}
- },
+ }
onRendered() {
this.spinner = this.find('.sk-spinner-list');
@@ -741,47 +741,58 @@ BlazeComponent.extendComponent({
);
this.updateList();
- },
+ }
onDestroyed() {
$(this.container).off(`scroll.spinner_${this.swimlaneId}_${this.listId}`);
$(window).off(`resize.spinner_${this.swimlaneId}_${this.listId}`);
- },
+ }
+
+ checkIdleTime() {
+ return window.requestIdleCallback ||
+ function(handler) {
+ const startTime = Date.now();
+ return setTimeout(function() {
+ handler({
+ didTimeout: false,
+ timeRemaining() {
+ return Math.max(0, 50.0 - (Date.now() - startTime));
+ },
+ });
+ }, 1);
+ };
+ }
updateList() {
// Use fallback when requestIdleCallback is not available on iOS and Safari
// https://www.afasterweb.com/2017/11/20/utilizing-idle-moments/
- checkIdleTime =
- window.requestIdleCallback ||
- function(handler) {
- const startTime = Date.now();
- return setTimeout(function() {
- handler({
- didTimeout: false,
- timeRemaining() {
- return Math.max(0, 50.0 - (Date.now() - startTime));
- },
- });
- }, 1);
- };
if (this.spinnerInView()) {
this.cardlimit.set(this.cardlimit.get() + InfiniteScrollIter);
- checkIdleTime(() => this.updateList());
+ this.checkIdleTime(() => this.updateList());
}
- },
+ }
spinnerInView() {
- const parentViewHeight = this.container.clientHeight;
- const bottomViewPosition = this.container.scrollTop + parentViewHeight;
-
- const threshold = this.spinner.offsetTop;
-
// spinner deleted
if (!this.spinner.offsetTop) {
return false;
}
- return bottomViewPosition > threshold;
- },
-}).register('spinnerList');
+ const parentViewHeight = this.container.clientHeight;
+ const bottomViewPosition = this.container.scrollTop + parentViewHeight;
+
+ let spinnerOffsetTop = this.spinner.offsetTop;
+
+ const addCard = $(this.container).find("a.open-minicard-composer").first()[0];
+ if (addCard !== undefined) {
+ spinnerOffsetTop -= addCard.clientHeight;
+ }
+
+ return bottomViewPosition > spinnerOffsetTop;
+ }
+
+ getSkSpinnerName() {
+ return "sk-spinner-" + super.getSpinnerName().toLowerCase();
+ }
+}.register('spinnerList'));
diff --git a/client/components/main/spinner.jade b/client/components/main/spinner.jade
new file mode 100644
index 000000000..1b4d6dad0
--- /dev/null
+++ b/client/components/main/spinner.jade
@@ -0,0 +1,5 @@
+template(name="spinner")
+ +Template.dynamic(template=getSpinnerTemplate)
+
+template(name="spinnerRaw")
+ +Template.dynamic(template=getSpinnerTemplateRaw)
diff --git a/client/components/main/spinner.js b/client/components/main/spinner.js
new file mode 100644
index 000000000..2d7ab35f7
--- /dev/null
+++ b/client/components/main/spinner.js
@@ -0,0 +1,11 @@
+import { Spinner } from '/client/lib/spinner';
+
+(class extends Spinner {
+}.register('spinner'));
+
+(class extends Spinner {
+ getSpinnerTemplateRaw() {
+ let ret = super.getSpinnerTemplate() + 'Raw';
+ return ret;
+ }
+}.register('spinnerRaw'));
diff --git a/client/components/main/spinner.tpl.jade b/client/components/main/spinner.tpl.jade
deleted file mode 100644
index 9310a6e5b..000000000
--- a/client/components/main/spinner.tpl.jade
+++ /dev/null
@@ -1,6 +0,0 @@
-.sk-spinner.sk-spinner-wave(class=currentBoard.colorClass)
- .sk-rect1
- .sk-rect2
- .sk-rect3
- .sk-rect4
- .sk-rect5
diff --git a/client/components/main/spinner_bounce.jade b/client/components/main/spinner_bounce.jade
new file mode 100644
index 000000000..5eda2295a
--- /dev/null
+++ b/client/components/main/spinner_bounce.jade
@@ -0,0 +1,11 @@
+template(name="spinnerBounce")
+ .sk-spinner.sk-spinner-bounce(class=currentBoard.colorClass)
+ +spinnerBounceRaw
+
+template(name="spinnerBounceRaw")
+ .sk-bounce1
+ |
+ .sk-bounce2
+ |
+ .sk-bounce3
+ |
diff --git a/client/components/main/spinner_bounce.styl b/client/components/main/spinner_bounce.styl
new file mode 100644
index 000000000..7d9ab0248
--- /dev/null
+++ b/client/components/main/spinner_bounce.styl
@@ -0,0 +1,44 @@
+@import 'nib'
+
+// From https://github.com/tobiasahlin/SpinKit
+.sk-spinner-bounce {
+ margin: 100px auto 0;
+ width: 70px;
+ text-align: center;
+
+ div {
+ width: 18px;
+ height: 18px;
+ background-color: #333;
+
+ border-radius: 100%;
+ display: inline-block;
+ -webkit-animation: sk-bouncedelay 1.4s infinite ease-in-out both;
+ animation: sk-bouncedelay 1.4s infinite ease-in-out both;
+ }
+
+ .sk-bounce1 {
+ -webkit-animation-delay: -0.32s;
+ animation-delay: -0.32s;
+ }
+
+ .sk-bounce2 {
+ -webkit-animation-delay: -0.16s;
+ animation-delay: -0.16s;
+ }
+}
+
+@-webkit-keyframes sk-bouncedelay {
+ 0%, 80%, 100% { -webkit-transform: scale(0) }
+ 40% { -webkit-transform: scale(1.0) }
+}
+
+@keyframes sk-bouncedelay {
+ 0%, 80%, 100% {
+ -webkit-transform: scale(0);
+ transform: scale(0);
+ } 40% {
+ -webkit-transform: scale(1.0);
+ transform: scale(1.0);
+ }
+}
diff --git a/client/components/main/spinner_cube.jade b/client/components/main/spinner_cube.jade
new file mode 100644
index 000000000..696d2f5ad
--- /dev/null
+++ b/client/components/main/spinner_cube.jade
@@ -0,0 +1,8 @@
+template(name="spinnerCube")
+ .sk-spinner.sk-spinner-cube(class=currentBoard.colorClass)
+ +spinnerCubeRaw
+
+template(name="spinnerCubeRaw")
+ .sk-cube1
+ .sk-cube2
+ .sk-cube3
diff --git a/client/components/main/spinner_cube.styl b/client/components/main/spinner_cube.styl
new file mode 100644
index 000000000..92e6e2a11
--- /dev/null
+++ b/client/components/main/spinner_cube.styl
@@ -0,0 +1,52 @@
+@import 'nib'
+
+// From https://github.com/tobiasahlin/SpinKit
+.sk-spinner-cube {
+ margin: 100px auto;
+ width: 40px;
+ height: 40px;
+ position: relative;
+}
+
+.sk-cube1, .sk-cube2 {
+ background-color: #333;
+ width: 15px;
+ height: 15px;
+ position: absolute;
+ top: 0;
+ left: 0;
+
+ -webkit-animation: sk-cubemove 1.8s infinite ease-in-out;
+ animation: sk-cubemove 1.8s infinite ease-in-out;
+}
+
+.sk-cube2 {
+ -webkit-animation-delay: -0.9s;
+ animation-delay: -0.9s;
+}
+
+@-webkit-keyframes sk-cubemove {
+ 25% { -webkit-transform: translateX(35px) rotate(-90deg) scale(0.5) }
+ 50% { -webkit-transform: translateX(35px) translateY(35px) rotate(-180deg) }
+ 75% { -webkit-transform: translateX(0px) translateY(35px) rotate(-270deg) scale(0.5) }
+ 100% { -webkit-transform: rotate(-360deg) }
+}
+
+@keyframes sk-cubemove {
+ 25% {
+ transform: translateX(35px) rotate(-90deg) scale(0.5);
+ -webkit-transform: translateX(35px) rotate(-90deg) scale(0.5);
+ } 50% {
+ transform: translateX(35px) translateY(35px) rotate(-179deg);
+ -webkit-transform: translateX(35px) translateY(35px) rotate(-179deg);
+ } 50.1% {
+ transform: translateX(35px) translateY(35px) rotate(-180deg);
+ -webkit-transform: translateX(35px) translateY(35px) rotate(-180deg);
+ } 75% {
+ transform: translateX(0px) translateY(35px) rotate(-270deg) scale(0.5);
+ -webkit-transform: translateX(0px) translateY(35px) rotate(-270deg) scale(0.5);
+ } 100% {
+ transform: rotate(-360deg);
+ -webkit-transform: rotate(-360deg);
+ }
+}
diff --git a/client/components/main/spinner_cube_grid.jade b/client/components/main/spinner_cube_grid.jade
new file mode 100644
index 000000000..55faf11af
--- /dev/null
+++ b/client/components/main/spinner_cube_grid.jade
@@ -0,0 +1,14 @@
+template(name="spinnerCubeGrid")
+ .sk-spinner.sk-spinner-cube-grid(class=currentBoard.colorClass)
+ +spinnerCubeGridRaw
+
+template(name="spinnerCubeGridRaw")
+ .sk-cube-grid.sk-cube-grid1
+ .sk-cube-grid.sk-cube-grid2
+ .sk-cube-grid.sk-cube-grid3
+ .sk-cube-grid.sk-cube-grid4
+ .sk-cube-grid.sk-cube-grid5
+ .sk-cube-grid.sk-cube-grid6
+ .sk-cube-grid.sk-cube-grid7
+ .sk-cube-grid.sk-cube-grid8
+ .sk-cube-grid.sk-cube-grid9
diff --git a/client/components/main/spinner_cube_grid.styl b/client/components/main/spinner_cube_grid.styl
new file mode 100644
index 000000000..042aa10fe
--- /dev/null
+++ b/client/components/main/spinner_cube_grid.styl
@@ -0,0 +1,64 @@
+@import 'nib'
+
+// From https://github.com/tobiasahlin/SpinKit
+.sk-spinner-cube-grid {
+ width: 40px;
+ height: 40px;
+ margin: 100px auto;
+}
+
+.sk-spinner-cube-grid .sk-cube-grid {
+ width: 33%;
+ height: 33%;
+ background-color: #333;
+ float: left;
+ -webkit-animation: sk-cubeGridScaleDelay 1.3s infinite ease-in-out;
+ animation: sk-cubeGridScaleDelay 1.3s infinite ease-in-out;
+}
+.sk-spinner-cube-grid .sk-cube-grid1 {
+ -webkit-animation-delay: 0.2s;
+ animation-delay: 0.2s; }
+.sk-spinner-cube-grid .sk-cube-grid2 {
+ -webkit-animation-delay: 0.3s;
+ animation-delay: 0.3s; }
+.sk-spinner-cube-grid .sk-cube-grid3 {
+ -webkit-animation-delay: 0.4s;
+ animation-delay: 0.4s; }
+.sk-spinner-cube-grid .sk-cube-grid4 {
+ -webkit-animation-delay: 0.1s;
+ animation-delay: 0.1s; }
+.sk-spinner-cube-grid .sk-cube-grid5 {
+ -webkit-animation-delay: 0.2s;
+ animation-delay: 0.2s; }
+.sk-spinner-cube-grid .sk-cube-grid6 {
+ -webkit-animation-delay: 0.3s;
+ animation-delay: 0.3s; }
+.sk-spinner-cube-grid .sk-cube-grid7 {
+ -webkit-animation-delay: 0s;
+ animation-delay: 0s; }
+.sk-spinner-cube-grid .sk-cube-grid8 {
+ -webkit-animation-delay: 0.1s;
+ animation-delay: 0.1s; }
+.sk-spinner-cube-grid .sk-cube-grid9 {
+ -webkit-animation-delay: 0.2s;
+ animation-delay: 0.2s; }
+
+@-webkit-keyframes sk-cubeGridScaleDelay {
+ 0%, 70%, 100% {
+ -webkit-transform: scale3D(1, 1, 1);
+ transform: scale3D(1, 1, 1);
+ } 35% {
+ -webkit-transform: scale3D(0, 0, 1);
+ transform: scale3D(0, 0, 1);
+ }
+}
+
+@keyframes sk-cubeGridScaleDelay {
+ 0%, 70%, 100% {
+ -webkit-transform: scale3D(1, 1, 1);
+ transform: scale3D(1, 1, 1);
+ } 35% {
+ -webkit-transform: scale3D(0, 0, 1);
+ transform: scale3D(0, 0, 1);
+ }
+}
diff --git a/client/components/main/spinner_dot.jade b/client/components/main/spinner_dot.jade
new file mode 100644
index 000000000..187511116
--- /dev/null
+++ b/client/components/main/spinner_dot.jade
@@ -0,0 +1,7 @@
+template(name="spinnerDot")
+ .sk-spinner.sk-spinner-dot(class=currentBoard.colorClass)
+ +spinnerDotRaw
+
+template(name="spinnerDotRaw")
+ .sk-dot1
+ .sk-dot2
diff --git a/client/components/main/spinner_dot.styl b/client/components/main/spinner_dot.styl
new file mode 100644
index 000000000..5f2e36da4
--- /dev/null
+++ b/client/components/main/spinner_dot.styl
@@ -0,0 +1,51 @@
+@import 'nib'
+
+// From https://github.com/tobiasahlin/SpinKit
+.sk-spinner-dot {
+ margin: 100px auto;
+ width: 40px;
+ height: 40px;
+ position: relative;
+ text-align: center;
+
+ -webkit-animation: sk-rotate 2.0s infinite linear;
+ animation: sk-rotate 2.0s infinite linear;
+}
+
+.sk-dot1, .sk-dot2 {
+ width: 40%;
+ height: 40%;
+ display: inline-block;
+ position: absolute;
+ top: 0;
+ background-color: #333;
+ border-radius: 100%;
+
+ -webkit-animation: sk-bounce 2.0s infinite ease-in-out;
+ animation: sk-bounce 2.0s infinite ease-in-out;
+}
+
+.sk-dot2 {
+ top: auto;
+ bottom: 0;
+ -webkit-animation-delay: -1.0s;
+ animation-delay: -1.0s;
+}
+
+@-webkit-keyframes sk-rotate { 100% { -webkit-transform: rotate(360deg) }}
+@keyframes sk-rotate { 100% { transform: rotate(360deg); -webkit-transform: rotate(360deg) }}
+
+@-webkit-keyframes sk-bounce {
+ 0%, 100% { -webkit-transform: scale(0.0) }
+ 50% { -webkit-transform: scale(1.0) }
+}
+
+@keyframes sk-bounce {
+ 0%, 100% {
+ transform: scale(0.0);
+ -webkit-transform: scale(0.0);
+ } 50% {
+ transform: scale(1.0);
+ -webkit-transform: scale(1.0);
+ }
+}
diff --git a/client/components/main/spinner_double_bounce.jade b/client/components/main/spinner_double_bounce.jade
new file mode 100644
index 000000000..206a468d2
--- /dev/null
+++ b/client/components/main/spinner_double_bounce.jade
@@ -0,0 +1,7 @@
+template(name="spinnerDoubleBounce")
+ .sk-spinner.sk-spinner-double-bounce(class=currentBoard.colorClass)
+ +spinnerDoubleBounceRaw
+
+template(name="spinnerDoubleBounceRaw")
+ .sk-double-bounce1
+ .sk-double-bounce2
diff --git a/client/components/main/spinner_double_bounce.styl b/client/components/main/spinner_double_bounce.styl
new file mode 100644
index 000000000..2ef000361
--- /dev/null
+++ b/client/components/main/spinner_double_bounce.styl
@@ -0,0 +1,44 @@
+@import 'nib'
+
+// From https://github.com/tobiasahlin/SpinKit
+.sk-spinner-double-bounce {
+ width: 40px;
+ height: 40px;
+
+ position: relative;
+ margin: 100px auto;
+}
+
+.sk-double-bounce1, .sk-double-bounce2 {
+ width: 100%;
+ height: 100%;
+ border-radius: 50%;
+ background-color: #333;
+ opacity: 0.6;
+ position: absolute;
+ top: 0;
+ left: 0;
+
+ -webkit-animation: sk-bounce 2.0s infinite ease-in-out;
+ animation: sk-bounce 2.0s infinite ease-in-out;
+}
+
+.sk-double-bounce2 {
+ -webkit-animation-delay: -1.0s;
+ animation-delay: -1.0s;
+}
+
+@-webkit-keyframes sk-bounce {
+ 0%, 100% { -webkit-transform: scale(0.0) }
+ 50% { -webkit-transform: scale(1.0) }
+}
+
+@keyframes sk-bounce {
+ 0%, 100% {
+ transform: scale(0.0);
+ -webkit-transform: scale(0.0);
+ } 50% {
+ transform: scale(1.0);
+ -webkit-transform: scale(1.0);
+ }
+}
diff --git a/client/components/main/spinner_rotateplane.jade b/client/components/main/spinner_rotateplane.jade
new file mode 100644
index 000000000..35afeda81
--- /dev/null
+++ b/client/components/main/spinner_rotateplane.jade
@@ -0,0 +1,6 @@
+template(name="spinnerRotateplane")
+ .sk-spinner.sk-spinner-rotateplane(class=currentBoard.colorClass)
+ +spinnerRotateplaneRaw
+
+template(name="spinnerRotateplaneRaw")
+ .sk-rotateplane1
diff --git a/client/components/main/spinner_rotateplane.styl b/client/components/main/spinner_rotateplane.styl
new file mode 100644
index 000000000..1f43d37e3
--- /dev/null
+++ b/client/components/main/spinner_rotateplane.styl
@@ -0,0 +1,38 @@
+@import 'nib'
+
+// From https://github.com/tobiasahlin/SpinKit
+.sk-spinner-rotateplane {
+ width: 40px;
+ height: 40px;
+ text-align: center;
+
+ margin: 100px auto;
+ -webkit-animation: sk-rotateplane 1.2s infinite ease-in-out;
+ animation: sk-rotateplane 1.2s infinite ease-in-out;
+
+ div {
+ background-color: #333;
+ height: 100%;
+ width: 100%;
+ display: inline-block;
+ }
+}
+
+@-webkit-keyframes sk-rotateplane {
+ 0% { -webkit-transform: perspective(120px) }
+ 50% { -webkit-transform: perspective(120px) rotateY(180deg) }
+ 100% { -webkit-transform: perspective(120px) rotateY(180deg) rotateX(180deg) }
+}
+
+@keyframes sk-rotateplane {
+ 0% {
+ transform: perspective(120px) rotateX(0deg) rotateY(0deg);
+ -webkit-transform: perspective(120px) rotateX(0deg) rotateY(0deg)
+ } 50% {
+ transform: perspective(120px) rotateX(-180.1deg) rotateY(0deg);
+ -webkit-transform: perspective(120px) rotateX(-180.1deg) rotateY(0deg)
+ } 100% {
+ transform: perspective(120px) rotateX(-180deg) rotateY(-179.9deg);
+ -webkit-transform: perspective(120px) rotateX(-180deg) rotateY(-179.9deg);
+ }
+}
diff --git a/client/components/main/spinner_scaleout.jade b/client/components/main/spinner_scaleout.jade
new file mode 100644
index 000000000..2cb21d156
--- /dev/null
+++ b/client/components/main/spinner_scaleout.jade
@@ -0,0 +1,6 @@
+template(name="spinnerScaleout")
+ .sk-spinner.sk-spinner-scaleout(class=currentBoard.colorClass)
+ +spinnerScaleoutRaw
+
+template(name="spinnerScaleoutRaw")
+ .sk-scaleout1
diff --git a/client/components/main/spinner_scaleout.styl b/client/components/main/spinner_scaleout.styl
new file mode 100644
index 000000000..deb73b68e
--- /dev/null
+++ b/client/components/main/spinner_scaleout.styl
@@ -0,0 +1,40 @@
+@import 'nib'
+
+// From https://github.com/tobiasahlin/SpinKit
+.sk-spinner-scaleout {
+ width: 40px;
+ height: 40px;
+ text-align: center;
+
+ margin: 100px auto;
+
+ border-radius: 100%;
+ -webkit-animation: sk-scaleout 1.0s infinite ease-in-out;
+ animation: sk-scaleout 1.0s infinite ease-in-out;
+
+ div {
+ background-color: #333;
+ height: 100%;
+ width: 100%;
+ display: inline-block;
+ }
+}
+
+@-webkit-keyframes sk-scaleout {
+ 0% { -webkit-transform: scale(0) }
+ 100% {
+ -webkit-transform: scale(1.0);
+ opacity: 0;
+ }
+}
+
+@keyframes sk-scaleout {
+ 0% {
+ -webkit-transform: scale(0);
+ transform: scale(0);
+ } 100% {
+ -webkit-transform: scale(1.0);
+ transform: scale(1.0);
+ opacity: 0;
+ }
+}
diff --git a/client/components/main/spinner_wave.jade b/client/components/main/spinner_wave.jade
new file mode 100644
index 000000000..fe5a26b0d
--- /dev/null
+++ b/client/components/main/spinner_wave.jade
@@ -0,0 +1,15 @@
+template(name="spinnerWave")
+ .sk-spinner.sk-spinner-wave(class=currentBoard.colorClass)
+ +spinnerWaveRaw
+
+template(name="spinnerWaveRaw")
+ .sk-rect1
+ |
+ .sk-rect2
+ |
+ .sk-rect3
+ |
+ .sk-rect4
+ |
+ .sk-rect5
+ |
diff --git a/client/components/main/spinner.styl b/client/components/main/spinner_wave.styl
similarity index 61%
rename from client/components/main/spinner.styl
rename to client/components/main/spinner_wave.styl
index 65c5fe62e..a82d39496 100644
--- a/client/components/main/spinner.styl
+++ b/client/components/main/spinner_wave.styl
@@ -1,21 +1,7 @@
@import 'nib'
-/*
- * From https://github.com/tobiasahlin/SpinKit
- *
- * Usage:
- *
- *
- *
- */
-
-.sk-spinner {
+// From https://github.com/tobiasahlin/SpinKit
+.sk-spinner-wave {
width: 50px;
height: 50px;
margin: auto;
diff --git a/client/components/settings/peopleBody.jade b/client/components/settings/peopleBody.jade
index 6291b9779..e985fb11f 100644
--- a/client/components/settings/peopleBody.jade
+++ b/client/components/settings/peopleBody.jade
@@ -531,6 +531,9 @@ template(name="settingsOrgPopup")
ul.pop-over-list
li
form
+ label#deleteOrgWarningMessage.hide
+ | {{_ 'delete-org-warning-message'}}
+ br
label
| {{_ 'delete-org-confirm-popup'}}
br
@@ -552,6 +555,9 @@ template(name="settingsTeamPopup")
ul.pop-over-list
li
form
+ label#deleteTeamWarningMessage.hide
+ | {{_ 'delete-team-warning-message'}}
+ br
label
| {{_ 'delete-team-confirm-popup'}}
br
diff --git a/client/components/settings/peopleBody.js b/client/components/settings/peopleBody.js
index 399b13373..8a1e29635 100644
--- a/client/components/settings/peopleBody.js
+++ b/client/components/settings/peopleBody.js
@@ -329,8 +329,13 @@ Template.newUserPopup.helpers({
},
isSelected(match) {
const userId = Template.instance().data.userId;
- const selected = Users.findOne(userId).authenticationMethod;
- return selected === match;
+ if(userId){
+ const selected = Users.findOne(userId).authenticationMethod;
+ return selected === match;
+ }
+ else{
+ false;
+ }
},
isLdap() {
const userId = Template.instance().data.userId;
@@ -515,15 +520,13 @@ Template.editUserPopup.events({
const isAdmin = templateInstance.find('.js-profile-isadmin').value.trim();
const isActive = templateInstance.find('.js-profile-isactive').value.trim();
const email = templateInstance.find('.js-profile-email').value.trim();
- const verified = templateInstance
- .find('.js-profile-email-verified')
- .value.trim();
- const authentication = templateInstance
- .find('.js-authenticationMethod')
- .value.trim();
- const importUsernames = templateInstance
- .find('.js-import-usernames')
- .value.trim();
+ const verified = templateInstance.find('.js-profile-email-verified').value.trim();
+ const authentication = templateInstance.find('.js-authenticationMethod').value.trim();
+ const importUsernames = templateInstance.find('.js-import-usernames').value.trim();
+ const userOrgs = templateInstance.find('.js-userOrgs').value.trim();
+ const userOrgsIds = templateInstance.find('.js-userOrgIds').value.trim();
+ const userTeams = templateInstance.find('.js-userteams').value.trim();
+ const userTeamsIds = templateInstance.find('.js-userteamIds').value.trim();
const isChangePassword = password.length > 0;
const isChangeUserName = username !== user.username;
@@ -555,12 +558,24 @@ Template.editUserPopup.events({
let userTeamsList = userTeams.split(",");
let userTeamsIdsList = userTeamsIds.split(",");
let userTms = [];
+<<<<<<< HEAD
for(let i = 0; i < userTeamsList.length; i++){
userTms.push({
"teamId": userTeamsIdsList[i],
"teamDisplayName": userTeamsList[i],
})
}
+=======
+ if(userTeams != ''){
+ for(let i = 0; i < userTeamsList.length; i++){
+ userTms.push({
+ "teamId": userTeamsIdsList[i],
+ "teamDisplayName": userTeamsList[i],
+ })
+ }
+ }
+
+>>>>>>> feature/250f95de
Users.update(this.userId, {
$set:{
teams: userTms
@@ -570,12 +585,24 @@ Template.editUserPopup.events({
let userOrgsList = userOrgs.split(",");
let userOrgsIdsList = userOrgsIds.split(",");
let userOrganizations = [];
+<<<<<<< HEAD
for(let i = 0; i < userOrgsList.length; i++){
userOrganizations.push({
"orgId": userOrgsIdsList[i],
"orgDisplayName": userOrgsList[i],
})
}
+=======
+ if(userOrgs != ''){
+ for(let i = 0; i < userOrgsList.length; i++){
+ userOrganizations.push({
+ "orgId": userOrgsIdsList[i],
+ "orgDisplayName": userOrgsList[i],
+ })
+ }
+ }
+
+>>>>>>> feature/250f95de
Users.update(this.userId, {
$set:{
orgs: userOrganizations
@@ -725,7 +752,11 @@ UpdateUserOrgsOrTeamsElement = function(isNewUser = false){
lstInputValuesIds = [];
}
index = lstInputValues.indexOf(selectedEltValue);
+<<<<<<< HEAD
indexId = lstInputValuesIds.indexOf(selectedEltValue);
+=======
+ indexId = lstInputValuesIds.indexOf(selectedEltValueId);
+>>>>>>> feature/250f95de
if(userOrgsTeamsAction == "addOrg" || userOrgsTeamsAction == "addTeam"){
if(index <= -1 && selectedEltValueId != "-1"){
lstInputValues.push(selectedEltValue);
@@ -883,6 +914,8 @@ Template.newUserPopup.events({
},
'click #addUserOrgNewUser'(event) {
event.preventDefault();
+<<<<<<< HEAD
+=======
userOrgsTeamsAction = "addOrg";
document.getElementById("jsOrgsNewUser").style.display = 'block';
@@ -918,6 +951,75 @@ Template.newUserPopup.events({
UpdateUserOrgsOrTeamsElement(true);
},
});
+>>>>>>> feature/250f95de
+
+ userOrgsTeamsAction = "addOrg";
+ document.getElementById("jsOrgsNewUser").style.display = 'block';
+ document.getElementById("jsTeamsNewUser").style.display = 'none';
+ },
+ 'click #removeUserOrgNewUser'(event) {
+ event.preventDefault();
+<<<<<<< HEAD
+=======
+ if(Users.find({"orgs.orgId": this.orgId}).count() > 0)
+ {
+ let orgClassList = document.getElementById("deleteOrgWarningMessage").classList;
+ if(orgClassList.contains('hide'))
+ {
+ orgClassList.remove('hide');
+ document.getElementById("deleteOrgWarningMessage").style.color = "red";
+ }
+ return;
+ }
+ Org.remove(this.orgId);
+ Popup.close();
+ }
+});
+>>>>>>> feature/250f95de
+
+ userOrgsTeamsAction = "removeOrg";
+ document.getElementById("jsOrgsNewUser").style.display = 'block';
+ document.getElementById("jsTeamsNewUser").style.display = 'none';
+ },
+ 'click #addUserTeamNewUser'(event) {
+ event.preventDefault();
+<<<<<<< HEAD
+
+ userOrgsTeamsAction = "addTeam";
+ document.getElementById("jsTeamsNewUser").style.display = 'block';
+ document.getElementById("jsOrgsNewUser").style.display = 'none';
+ },
+ 'click #removeUserTeamNewUser'(event) {
+ event.preventDefault();
+
+ userOrgsTeamsAction = "removeTeam";
+ document.getElementById("jsTeamsNewUser").style.display = 'block';
+ document.getElementById("jsOrgsNewUser").style.display = 'none';
+ },
+ 'change #jsOrgsNewUser'(event) {
+ event.preventDefault();
+ UpdateUserOrgsOrTeamsElement(true);
+ },
+ 'change #jsTeamsNewUser'(event) {
+ event.preventDefault();
+ UpdateUserOrgsOrTeamsElement(true);
+ },
+=======
+ if(Users.find({"teams.teamId": this.teamId}).count() > 0)
+ {
+ let teamClassList = document.getElementById("deleteTeamWarningMessage").classList;
+ if(teamClassList.contains('hide'))
+ {
+ teamClassList.remove('hide');
+ document.getElementById("deleteTeamWarningMessage").style.color = "red";
+ }
+ return;
+ }
+ Team.remove(this.teamId);
+ Popup.close();
+ }
+>>>>>>> feature/250f95de
+});
Template.settingsUserPopup.events({
'click .impersonate-user'(event) {
diff --git a/client/components/settings/settingBody.jade b/client/components/settings/settingBody.jade
index f8cfc3a59..76f8ae95c 100644
--- a/client/components/settings/settingBody.jade
+++ b/client/components/settings/settingBody.jade
@@ -173,6 +173,9 @@ template(name='layoutSettings')
li.layout-form
.title {{_ 'default-authentication-method'}}
+selectAuthenticationMethod(authenticationMethod=currentSetting.defaultAuthenticationMethod)
+ li.layout-form
+ .title {{_ 'wait-spinner'}}
+ +selectSpinnerName(spinnerName=currentSetting.spinnerName)
li.layout-form
.title {{_ 'custom-product-name'}}
.form-group
@@ -222,3 +225,11 @@ template(name='selectAuthenticationMethod')
option(value="{{value}}" selected) {{_ value}}
else
option(value="{{value}}") {{_ value}}
+
+template(name='selectSpinnerName')
+ select#spinnerName
+ each spinner in spinners
+ if isSelected spinner
+ option(value="{{spinner}}" selected) {{_ spinner}}
+ else
+ option(value="{{spinner}}") {{_ spinner}}
diff --git a/client/components/settings/settingBody.js b/client/components/settings/settingBody.js
index 596b40613..e55e2db6b 100644
--- a/client/components/settings/settingBody.js
+++ b/client/components/settings/settingBody.js
@@ -1,3 +1,5 @@
+import { ALLOWED_WAIT_SPINNERS } from '/config/const';
+
BlazeComponent.extendComponent({
onCreated() {
this.error = new ReactiveVar('');
@@ -199,6 +201,8 @@ BlazeComponent.extendComponent({
$('input[name=displayAuthenticationMethod]:checked').val() === 'true';
const defaultAuthenticationMethod = $('#defaultAuthenticationMethod').val();
+ const spinnerName = $('#spinnerName').val();
+
try {
Settings.update(Settings.findOne()._id, {
$set: {
@@ -213,6 +217,7 @@ BlazeComponent.extendComponent({
displayAuthenticationMethod,
defaultAuthenticationMethod,
automaticLinkedUrlSchemes,
+ spinnerName,
},
});
} catch (e) {
@@ -384,3 +389,12 @@ Template.selectAuthenticationMethod.helpers({
return Template.instance().data.authenticationMethod === match;
},
});
+
+Template.selectSpinnerName.helpers({
+ spinners() {
+ return ALLOWED_WAIT_SPINNERS;
+ },
+ isSelected(match) {
+ return Template.instance().data.spinnerName === match;
+ },
+});
diff --git a/client/components/sidebar/sidebar.jade b/client/components/sidebar/sidebar.jade
index f0bd05ac7..dcf33dfac 100644
--- a/client/components/sidebar/sidebar.jade
+++ b/client/components/sidebar/sidebar.jade
@@ -133,6 +133,12 @@ template(name="boardCardSettingsPopup")
span
i.fa.fa-user-plus
| {{_ 'requested-by'}}
+ div.check-div
+ a.flex.js-field-has-card-sorting-by-number(class="{{#if allowsCardSortingByNumber}}is-checked{{/if}}")
+ .materialCheckBox(class="{{#if allowsCardSortingByNumber}}is-checked{{/if}}")
+ span
+ i.fa.fa-sort
+ | {{_ 'card-sorting-by-number'}}
div.check-div
a.flex.js-field-has-labels(class="{{#if allowsLabels}}is-checked{{/if}}")
.materialCheckBox(class="{{#if allowsLabels}}is-checked{{/if}}")
diff --git a/client/components/sidebar/sidebar.js b/client/components/sidebar/sidebar.js
index 5c1026c12..a97016898 100644
--- a/client/components/sidebar/sidebar.js
+++ b/client/components/sidebar/sidebar.js
@@ -754,6 +754,10 @@ BlazeComponent.extendComponent({
return this.currentBoard.allowsRequestedBy;
},
+ allowsCardSortingByNumber() {
+ return this.currentBoard.allowsCardSortingByNumber;
+ },
+
allowsLabels() {
return this.currentBoard.allowsLabels;
},
@@ -968,6 +972,22 @@ BlazeComponent.extendComponent({
this.currentBoard.allowsRequestedBy,
);
},
+ 'click .js-field-has-card-sorting-by-number'(evt) {
+ evt.preventDefault();
+ this.currentBoard.allowsCardSortingByNumber = !this.currentBoard
+ .allowsCardSortingByNumber;
+ this.currentBoard.setAllowsCardSortingByNumber(
+ this.currentBoard.allowsCardSortingByNumber,
+ );
+ $(`.js-field-has-card-sorting-by-number ${MCB}`).toggleClass(
+ CKCLS,
+ this.currentBoard.allowsCardSortingByNumber,
+ );
+ $('.js-field-has-card-sorting-by-number').toggleClass(
+ CKCLS,
+ this.currentBoard.allowsCardSortingByNumber,
+ );
+ },
'click .js-field-has-labels'(evt) {
evt.preventDefault();
this.currentBoard.allowsLabels = !this.currentBoard.allowsLabels;
diff --git a/client/lib/spinner.js b/client/lib/spinner.js
new file mode 100644
index 000000000..d7078bda4
--- /dev/null
+++ b/client/lib/spinner.js
@@ -0,0 +1,27 @@
+Meteor.subscribe('setting');
+
+import { ALLOWED_WAIT_SPINNERS } from '/config/const';
+
+export class Spinner extends BlazeComponent {
+ currentSettings() {
+ return Settings.findOne();
+ }
+
+ getSpinnerName() {
+ let ret = 'Bounce';
+ let defaultWaitSpinner = Meteor.settings.public.WAIT_SPINNER;
+ if (defaultWaitSpinner && ALLOWED_WAIT_SPINNERS.includes(defaultWaitSpinner)) {
+ ret = defaultWaitSpinner;
+ }
+ let settings = this.currentSettings();
+
+ if (settings && settings.spinnerName) {
+ ret = settings.spinnerName;
+ }
+ return ret;
+ }
+
+ getSpinnerTemplate() {
+ return 'spinner' + this.getSpinnerName().replace(/-/, '');
+ }
+}
diff --git a/config/const.js b/config/const.js
index 0c9c71c7c..a275ffa6b 100644
--- a/config/const.js
+++ b/config/const.js
@@ -49,3 +49,13 @@ export const TYPE_LINKED_BOARD = 'cardType-linkedBoard';
export const TYPE_LINKED_CARD = 'cardType-linkedCard';
export const TYPE_TEMPLATE_BOARD = 'template-board';
export const TYPE_TEMPLATE_CONTAINER = 'template-container';
+export const ALLOWED_WAIT_SPINNERS = [
+ 'Bounce',
+ 'Cube',
+ 'Cube-Grid',
+ 'Dot',
+ 'Double-Bounce',
+ 'Rotateplane',
+ 'Scaleout',
+ 'Wave'
+];
diff --git a/docker-compose.yml b/docker-compose.yml
index bfcff6f24..57eff3b4f 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -618,6 +618,9 @@ services:
#- SAML_LOCAL_PROFILE_MATCH_ATTRIBUTE=
#- SAML_ATTRIBUTES=
#---------------------------------------------------------------------
+ # Wait spinner to use
+ # - WAIT_SPINNER=Bounce
+ #---------------------------------------------------------------------
depends_on:
- wekandb
diff --git a/i18n/ar-EG.i18n.json b/i18n/ar-EG.i18n.json
index 5f2e4e0e5..9ef52fe39 100644
--- a/i18n/ar-EG.i18n.json
+++ b/i18n/ar-EG.i18n.json
@@ -358,7 +358,11 @@
"export-board-excel": "Export board to Excel",
"user-can-not-export-excel": "User can not export Excel",
"export-board-html": "Export board to HTML",
+ "export-card": "Export card",
+ "export-card-pdf": "Export card to PDF",
+ "user-can-not-export-card-to-pdf": "User can not export card to PDF",
"exportBoardPopup-title": "Export board",
+ "exportCardPopup-title": "Export card",
"sort": "Sort",
"sort-desc": "Click to Sort List",
"list-sort-by": "Sort the List By:",
@@ -664,6 +668,7 @@
"setListColorPopup-title": "Choose a color",
"assigned-by": "Assigned By",
"requested-by": "Requested By",
+ "card-sorting-by-number": "Card sorting by number",
"board-delete-notice": "Deleting is permanent. You will lose all lists, cards and actions associated with this board.",
"delete-board-confirm-popup": "All lists, cards, labels, and activities will be deleted and you won't be able to recover the board contents. There is no undo.",
"boardDeletePopup-title": "Delete Board?",
@@ -1037,5 +1042,18 @@
"rulesReportTitle": "Rules Report",
"copy-swimlane": "Copy Swimlane",
"copySwimlanePopup-title": "Copy Swimlane",
- "display-card-creator": "Display Card Creator"
-}
\ No newline at end of file
+ "display-card-creator": "Display Card Creator",
+ "wait-spinner": "Wait Spinner",
+ "Bounce": "Bounce Wait Spinner",
+ "Cube": "Cube Wait Spinner",
+ "Cube-Grid": "Cube-Grid Wait Spinner",
+ "Dot": "Dot Wait Spinner",
+ "Double-Bounce": "Double Bounce Wait Spinner",
+ "Rotateplane": "Rotateplane Wait Spinner",
+ "Scaleout": "Scaleout Wait Spinner",
+ "Wave": "Wave Wait Spinner",
+ "maximize-card": "Maximize Card",
+ "minimize-card": "Minimize Card",
+ "delete-org-warning-message": "Can not delete this organization, there is at least one user belongs to is",
+ "delete-team-warning-message": "Can not delete this team, there is at least one user belongs to is"
+}
diff --git a/i18n/ar.i18n.json b/i18n/ar.i18n.json
index 61dac78ae..460d0a3af 100644
--- a/i18n/ar.i18n.json
+++ b/i18n/ar.i18n.json
@@ -358,7 +358,11 @@
"export-board-excel": "Export board to Excel",
"user-can-not-export-excel": "User can not export Excel",
"export-board-html": "Export board to HTML",
+ "export-card": "Export card",
+ "export-card-pdf": "Export card to PDF",
+ "user-can-not-export-card-to-pdf": "User can not export card to PDF",
"exportBoardPopup-title": "Export board",
+ "exportCardPopup-title": "Export card",
"sort": "Sort",
"sort-desc": "Click to Sort List",
"list-sort-by": "Sort the List By:",
@@ -664,6 +668,7 @@
"setListColorPopup-title": "اختر لوناً",
"assigned-by": "Assigned By",
"requested-by": "Requested By",
+ "card-sorting-by-number": "Card sorting by number",
"board-delete-notice": "Deleting is permanent. You will lose all lists, cards and actions associated with this board.",
"delete-board-confirm-popup": "All lists, cards, labels, and activities will be deleted and you won't be able to recover the board contents. There is no undo.",
"boardDeletePopup-title": "Delete Board?",
@@ -1037,5 +1042,18 @@
"rulesReportTitle": "Rules Report",
"copy-swimlane": "Copy Swimlane",
"copySwimlanePopup-title": "Copy Swimlane",
- "display-card-creator": "Display Card Creator"
-}
\ No newline at end of file
+ "display-card-creator": "Display Card Creator",
+ "wait-spinner": "Wait Spinner",
+ "Bounce": "Bounce Wait Spinner",
+ "Cube": "Cube Wait Spinner",
+ "Cube-Grid": "Cube-Grid Wait Spinner",
+ "Dot": "Dot Wait Spinner",
+ "Double-Bounce": "Double Bounce Wait Spinner",
+ "Rotateplane": "Rotateplane Wait Spinner",
+ "Scaleout": "Scaleout Wait Spinner",
+ "Wave": "Wave Wait Spinner",
+ "maximize-card": "Maximize Card",
+ "minimize-card": "Minimize Card",
+ "delete-org-warning-message": "Can not delete this organization, there is at least one user belongs to is",
+ "delete-team-warning-message": "Can not delete this team, there is at least one user belongs to is"
+}
diff --git a/i18n/bg.i18n.json b/i18n/bg.i18n.json
index 5e9183aba..291d4cf92 100644
--- a/i18n/bg.i18n.json
+++ b/i18n/bg.i18n.json
@@ -358,7 +358,11 @@
"export-board-excel": "Export board to Excel",
"user-can-not-export-excel": "User can not export Excel",
"export-board-html": "Export board to HTML",
+ "export-card": "Export card",
+ "export-card-pdf": "Export card to PDF",
+ "user-can-not-export-card-to-pdf": "User can not export card to PDF",
"exportBoardPopup-title": "Експортиране на Табло",
+ "exportCardPopup-title": "Export card",
"sort": "Сортирай",
"sort-desc": "Click to Sort List",
"list-sort-by": "Sort the List By:",
@@ -664,6 +668,7 @@
"setListColorPopup-title": "Избери цвят",
"assigned-by": "Разпределена от",
"requested-by": "Поискан от",
+ "card-sorting-by-number": "Card sorting by number",
"board-delete-notice": "Изтриването е перманентно. Ще загубите всички списъци, карти и действия асоциирани с тази дъска.",
"delete-board-confirm-popup": "Всички списъци, карти, имена и действия ще бъдат изтрити и няма да можете да възстановите съдържанието на дъската. Няма връщане назад.",
"boardDeletePopup-title": "Изтриване на Таблото?",
@@ -1037,5 +1042,18 @@
"rulesReportTitle": "Rules Report",
"copy-swimlane": "Copy Swimlane",
"copySwimlanePopup-title": "Copy Swimlane",
- "display-card-creator": "Display Card Creator"
-}
\ No newline at end of file
+ "display-card-creator": "Display Card Creator",
+ "wait-spinner": "Wait Spinner",
+ "Bounce": "Bounce Wait Spinner",
+ "Cube": "Cube Wait Spinner",
+ "Cube-Grid": "Cube-Grid Wait Spinner",
+ "Dot": "Dot Wait Spinner",
+ "Double-Bounce": "Double Bounce Wait Spinner",
+ "Rotateplane": "Rotateplane Wait Spinner",
+ "Scaleout": "Scaleout Wait Spinner",
+ "Wave": "Wave Wait Spinner",
+ "maximize-card": "Maximize Card",
+ "minimize-card": "Minimize Card",
+ "delete-org-warning-message": "Can not delete this organization, there is at least one user belongs to is",
+ "delete-team-warning-message": "Can not delete this team, there is at least one user belongs to is"
+}
diff --git a/i18n/br.i18n.json b/i18n/br.i18n.json
index b7488c9e0..c8c7c3582 100644
--- a/i18n/br.i18n.json
+++ b/i18n/br.i18n.json
@@ -358,7 +358,11 @@
"export-board-excel": "Export board to Excel",
"user-can-not-export-excel": "User can not export Excel",
"export-board-html": "Export board to HTML",
+ "export-card": "Export card",
+ "export-card-pdf": "Export card to PDF",
+ "user-can-not-export-card-to-pdf": "User can not export card to PDF",
"exportBoardPopup-title": "Export board",
+ "exportCardPopup-title": "Export card",
"sort": "Sort",
"sort-desc": "Click to Sort List",
"list-sort-by": "Sort the List By:",
@@ -664,6 +668,7 @@
"setListColorPopup-title": "Choose a color",
"assigned-by": "Assigned By",
"requested-by": "Requested By",
+ "card-sorting-by-number": "Card sorting by number",
"board-delete-notice": "Deleting is permanent. You will lose all lists, cards and actions associated with this board.",
"delete-board-confirm-popup": "All lists, cards, labels, and activities will be deleted and you won't be able to recover the board contents. There is no undo.",
"boardDeletePopup-title": "Delete Board?",
@@ -1037,5 +1042,18 @@
"rulesReportTitle": "Rules Report",
"copy-swimlane": "Copy Swimlane",
"copySwimlanePopup-title": "Copy Swimlane",
- "display-card-creator": "Display Card Creator"
-}
\ No newline at end of file
+ "display-card-creator": "Display Card Creator",
+ "wait-spinner": "Wait Spinner",
+ "Bounce": "Bounce Wait Spinner",
+ "Cube": "Cube Wait Spinner",
+ "Cube-Grid": "Cube-Grid Wait Spinner",
+ "Dot": "Dot Wait Spinner",
+ "Double-Bounce": "Double Bounce Wait Spinner",
+ "Rotateplane": "Rotateplane Wait Spinner",
+ "Scaleout": "Scaleout Wait Spinner",
+ "Wave": "Wave Wait Spinner",
+ "maximize-card": "Maximize Card",
+ "minimize-card": "Minimize Card",
+ "delete-org-warning-message": "Can not delete this organization, there is at least one user belongs to is",
+ "delete-team-warning-message": "Can not delete this team, there is at least one user belongs to is"
+}
diff --git a/i18n/ca.i18n.json b/i18n/ca.i18n.json
index ef21296ad..373aeb0ad 100644
--- a/i18n/ca.i18n.json
+++ b/i18n/ca.i18n.json
@@ -358,7 +358,11 @@
"export-board-excel": "Export board to Excel",
"user-can-not-export-excel": "User can not export Excel",
"export-board-html": "Export board to HTML",
+ "export-card": "Export card",
+ "export-card-pdf": "Export card to PDF",
+ "user-can-not-export-card-to-pdf": "User can not export card to PDF",
"exportBoardPopup-title": "Exporta tauler",
+ "exportCardPopup-title": "Export card",
"sort": "Sort",
"sort-desc": "Click to Sort List",
"list-sort-by": "Sort the List By:",
@@ -664,6 +668,7 @@
"setListColorPopup-title": "Choose a color",
"assigned-by": "Assignat Per",
"requested-by": "Demanat Per",
+ "card-sorting-by-number": "Card sorting by number",
"board-delete-notice": "Deleting is permanent. You will lose all lists, cards and actions associated with this board.",
"delete-board-confirm-popup": "All lists, cards, labels, and activities will be deleted and you won't be able to recover the board contents. There is no undo.",
"boardDeletePopup-title": "Delete Board?",
@@ -1037,5 +1042,18 @@
"rulesReportTitle": "Rules Report",
"copy-swimlane": "Copy Swimlane",
"copySwimlanePopup-title": "Copy Swimlane",
- "display-card-creator": "Display Card Creator"
-}
\ No newline at end of file
+ "display-card-creator": "Display Card Creator",
+ "wait-spinner": "Wait Spinner",
+ "Bounce": "Bounce Wait Spinner",
+ "Cube": "Cube Wait Spinner",
+ "Cube-Grid": "Cube-Grid Wait Spinner",
+ "Dot": "Dot Wait Spinner",
+ "Double-Bounce": "Double Bounce Wait Spinner",
+ "Rotateplane": "Rotateplane Wait Spinner",
+ "Scaleout": "Scaleout Wait Spinner",
+ "Wave": "Wave Wait Spinner",
+ "maximize-card": "Maximize Card",
+ "minimize-card": "Minimize Card",
+ "delete-org-warning-message": "Can not delete this organization, there is at least one user belongs to is",
+ "delete-team-warning-message": "Can not delete this team, there is at least one user belongs to is"
+}
diff --git a/i18n/cs.i18n.json b/i18n/cs.i18n.json
index 87c2f4838..b82ad11b1 100644
--- a/i18n/cs.i18n.json
+++ b/i18n/cs.i18n.json
@@ -82,8 +82,8 @@
"add-attachment": "Přidat přílohu",
"add-board": "Přidat tablo",
"add-card": "Přidat kartu",
- "add-card-to-top-of-list": "Add Card to Top of List",
- "add-card-to-bottom-of-list": "Add Card to Bottom of List",
+ "add-card-to-top-of-list": "Přidat kartu na začátek seznamu",
+ "add-card-to-bottom-of-list": "Přidat kartu na konec seznamu",
"add-swimlane": "Přidat Swimlane",
"add-subtask": "Přidat Podúkol",
"add-checklist": "Přidat zaškrtávací seznam",
@@ -133,7 +133,7 @@
"board-not-found": "Tablo nenalezeno",
"board-private-info": "Toto tablo bude soukromé.",
"board-public-info": "Toto tablo bude veřejné.",
- "board-drag-drop-reorder-or-click-open": "Drag and drop to reorder board icons. Click board icon to open board.",
+ "board-drag-drop-reorder-or-click-open": "Přetažením změníte pořadí ikon tabel. Kliknutím otevřete tablo.",
"boardChangeColorPopup-title": "Změnit pozadí tabla",
"boardChangeTitlePopup-title": "Přejmenovat tablo",
"boardChangeVisibilityPopup-title": "Upravit viditelnost",
@@ -181,10 +181,10 @@
"vote-against": "proti",
"deleteVotePopup-title": "Smazat hlas?",
"vote-delete-pop": "Smazání je nevratné. Ztratíte vše spojené s tímto hlasováním.",
- "cardStartPlanningPokerPopup-title": "Start a Planning Poker",
- "card-edit-planning-poker": "Edit Planning Poker",
- "editPokerEndDatePopup-title": "Change Planning Poker vote end date",
- "poker-question": "Planning Poker",
+ "cardStartPlanningPokerPopup-title": "Zahájit plánovací poker",
+ "card-edit-planning-poker": "Upravit plánovací poker",
+ "editPokerEndDatePopup-title": "Změnit datum konce plánovacího pokeru",
+ "poker-question": "Plánovací poker",
"poker-one": "1",
"poker-two": "2",
"poker-three": "3",
@@ -195,13 +195,13 @@
"poker-forty": "40",
"poker-oneHundred": "100",
"poker-unsure": "?",
- "poker-finish": "Finish",
- "poker-result-votes": "Votes",
- "poker-result-who": "Who",
- "poker-replay": "Replay",
- "set-estimation": "Set Estimation",
- "deletePokerPopup-title": "Delete planning poker?",
- "poker-delete-pop": "Deleting is permanent. You will lose all actions associated with this planning poker.",
+ "poker-finish": "Hotovo",
+ "poker-result-votes": "Hlasů",
+ "poker-result-who": "Kdo",
+ "poker-replay": "Zopakovat",
+ "set-estimation": "Nastavit odhad",
+ "deletePokerPopup-title": "Smazat plánovací poker?",
+ "poker-delete-pop": "Smazání je trvalé. Přijdete o všechny akce asociované s tímto plánovacím pokerem.",
"cardDeletePopup-title": "Smazat kartu?",
"cardDetailsActionsPopup-title": "Akce karty",
"cardLabelsPopup-title": "Štítky",
@@ -233,7 +233,7 @@
"close": "Zavřít",
"close-board": "Zavřít tablo",
"close-board-pop": "Budete moci obnovit tablo kliknutím na tlačítko \"Archiv\" v hlavním menu.",
- "close-card": "Close Card",
+ "close-card": "Zavřít kartu",
"color-black": "černá",
"color-blue": "modrá",
"color-crimson": "karmínová",
@@ -358,7 +358,11 @@
"export-board-excel": "Exportovat tablo do Excelu",
"user-can-not-export-excel": "Uživatel nemůže exportovat do Excelu",
"export-board-html": "Exportovat tablo do HTML",
+ "export-card": "Exportovat kartu",
+ "export-card-pdf": "Exportovat kartu do PDF",
+ "user-can-not-export-card-to-pdf": "Uživatel nemůže exportovat kartu do PDF",
"exportBoardPopup-title": "Exportovat tablo",
+ "exportCardPopup-title": "Exportovat kartu",
"sort": "řadit",
"sort-desc": "Kliknout pro třídění seznamu",
"list-sort-by": "řadit seznam podle",
@@ -447,8 +451,8 @@
"set-color-list": "Nastavit barvu",
"listActionPopup-title": "Vypsat akce",
"settingsUserPopup-title": "Nastavení uživatele",
- "settingsTeamPopup-title": "Team Settings",
- "settingsOrgPopup-title": "Organization Settings",
+ "settingsTeamPopup-title": "Nastavení týmu",
+ "settingsOrgPopup-title": "Nastavení organizace",
"swimlaneActionPopup-title": "Akce swimlane",
"swimlaneAddPopup-title": "Přidat swimlane dolů",
"listImportCardPopup-title": "Importovat Trello kartu",
@@ -664,6 +668,7 @@
"setListColorPopup-title": "Vyber barvu",
"assigned-by": "Přidělil(a)",
"requested-by": "Vyžádal(a)",
+ "card-sorting-by-number": "Řazení karet podle čísla",
"board-delete-notice": "Smazání je trvalé. Přijdete o všechny sloupce, karty a akce spojené s tímto tablem.",
"delete-board-confirm-popup": "Všechny sloupce, štítky a aktivity budou smazány a obsah tabla nebude možné obnovit. Toto nelze vrátit zpět.",
"boardDeletePopup-title": "Smazat tablo?",
@@ -845,8 +850,8 @@
"act-duenow": "připomínal(a), že stávající termín dokončení (__timeValue__) __card__ je teď",
"act-atUserComment": "Byli jste zmíněni v [__board__] __list__/__card__",
"delete-user-confirm-popup": "Jste si jisti, že chcete smazat tento účet? Tuto akci nelze vrátit zpět.",
- "delete-team-confirm-popup": "Are you sure you want to delete this team? There is no undo.",
- "delete-org-confirm-popup": "Are you sure you want to delete this organization? There is no undo.",
+ "delete-team-confirm-popup": "Jste si jisti, že chcete smazat tento tým? Tuto akci nelze vrátit zpět.",
+ "delete-org-confirm-popup": "Jste si jisti, že chcete smazat tuto organizaci? Tuto akci nelze vrátit zpět.",
"accounts-allowUserDelete": "Dovolit uživatelům smazat vlastní účet",
"hide-minicard-label-text": "Skrýt text popisku minikarty",
"show-desktop-drag-handles": "Zobrazit okraje pro přesun plochy",
@@ -1037,5 +1042,18 @@
"rulesReportTitle": "Report pravidel",
"copy-swimlane": "Kopírovat dráhu",
"copySwimlanePopup-title": "Kopírovat dráhu",
- "display-card-creator": "Display Card Creator"
-}
\ No newline at end of file
+ "display-card-creator": "Zobrazovat tvůrce karet",
+ "wait-spinner": "Wait Spinner",
+ "Bounce": "Bounce Wait Spinner",
+ "Cube": "Cube Wait Spinner",
+ "Cube-Grid": "Cube-Grid Wait Spinner",
+ "Dot": "Dot Wait Spinner",
+ "Double-Bounce": "Double Bounce Wait Spinner",
+ "Rotateplane": "Rotateplane Wait Spinner",
+ "Scaleout": "Scaleout Wait Spinner",
+ "Wave": "Wave Wait Spinner",
+ "maximize-card": "Maximalizovat kartu",
+ "minimize-card": "Minimalizovat kartu",
+ "delete-org-warning-message": "Can not delete this organization, there is at least one user belongs to is",
+ "delete-team-warning-message": "Can not delete this team, there is at least one user belongs to is"
+}
diff --git a/i18n/da.i18n.json b/i18n/da.i18n.json
index 1b429c4ca..9fa5fdb6d 100644
--- a/i18n/da.i18n.json
+++ b/i18n/da.i18n.json
@@ -358,7 +358,11 @@
"export-board-excel": "Export board to Excel",
"user-can-not-export-excel": "User can not export Excel",
"export-board-html": "Eksportér tavle til HTML",
+ "export-card": "Export card",
+ "export-card-pdf": "Export card to PDF",
+ "user-can-not-export-card-to-pdf": "User can not export card to PDF",
"exportBoardPopup-title": "Eksportér tavle",
+ "exportCardPopup-title": "Export card",
"sort": "Sortér",
"sort-desc": "Klik for at sortere listen",
"list-sort-by": "Sortér listen efter:",
@@ -664,6 +668,7 @@
"setListColorPopup-title": "Vælg en farve",
"assigned-by": "Tildelt af",
"requested-by": "Anmodet af",
+ "card-sorting-by-number": "Card sorting by number",
"board-delete-notice": "Sletning er permanent. Du vil miste alle lister, kort og handlinger knyttet til denne tavle.",
"delete-board-confirm-popup": "Alle lister, kort, etiketter og aktiviteter vil blive slettet og du får ikke mulighed for at genskabe tavlens indhold. Dette kan ikke fortrydes.",
"boardDeletePopup-title": "Slet tavle?",
@@ -1037,5 +1042,18 @@
"rulesReportTitle": "Rules Report",
"copy-swimlane": "Copy Swimlane",
"copySwimlanePopup-title": "Copy Swimlane",
- "display-card-creator": "Display Card Creator"
-}
\ No newline at end of file
+ "display-card-creator": "Display Card Creator",
+ "wait-spinner": "Wait Spinner",
+ "Bounce": "Bounce Wait Spinner",
+ "Cube": "Cube Wait Spinner",
+ "Cube-Grid": "Cube-Grid Wait Spinner",
+ "Dot": "Dot Wait Spinner",
+ "Double-Bounce": "Double Bounce Wait Spinner",
+ "Rotateplane": "Rotateplane Wait Spinner",
+ "Scaleout": "Scaleout Wait Spinner",
+ "Wave": "Wave Wait Spinner",
+ "maximize-card": "Maximize Card",
+ "minimize-card": "Minimize Card",
+ "delete-org-warning-message": "Can not delete this organization, there is at least one user belongs to is",
+ "delete-team-warning-message": "Can not delete this team, there is at least one user belongs to is"
+}
diff --git a/i18n/de-CH.i18n.json b/i18n/de-CH.i18n.json
index dc4e9578c..2804e1dfb 100644
--- a/i18n/de-CH.i18n.json
+++ b/i18n/de-CH.i18n.json
@@ -358,7 +358,11 @@
"export-board-excel": "Board nach Excel exportieren",
"user-can-not-export-excel": "Benutzer kann nicht nach Excel exportieren",
"export-board-html": "Board als HTML exportieren",
+ "export-card": "Export card",
+ "export-card-pdf": "Export card to PDF",
+ "user-can-not-export-card-to-pdf": "User can not export card to PDF",
"exportBoardPopup-title": "Board exportieren",
+ "exportCardPopup-title": "Export card",
"sort": "Sortieren",
"sort-desc": "Zum Sortieren der Liste klicken",
"list-sort-by": "Sortieren der Liste nach:",
@@ -664,6 +668,7 @@
"setListColorPopup-title": "Farbe wählen",
"assigned-by": "Zugewiesen von",
"requested-by": "Angefordert von",
+ "card-sorting-by-number": "Card sorting by number",
"board-delete-notice": "Löschen kann nicht rückgängig gemacht werden. Sie werden alle Listen, Karten und Aktionen, die mit diesem Board verbunden sind, verlieren.",
"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?",
@@ -1037,5 +1042,18 @@
"rulesReportTitle": "Regeln-Bericht",
"copy-swimlane": "Swimlane kopieren",
"copySwimlanePopup-title": "Swimlane kopieren",
- "display-card-creator": "Zeige Karten-Erstellung"
-}
\ No newline at end of file
+ "display-card-creator": "Zeige Karten-Erstellung",
+ "wait-spinner": "Wait Spinner",
+ "Bounce": "Bounce Wait Spinner",
+ "Cube": "Cube Wait Spinner",
+ "Cube-Grid": "Cube-Grid Wait Spinner",
+ "Dot": "Dot Wait Spinner",
+ "Double-Bounce": "Double Bounce Wait Spinner",
+ "Rotateplane": "Rotateplane Wait Spinner",
+ "Scaleout": "Scaleout Wait Spinner",
+ "Wave": "Wave Wait Spinner",
+ "maximize-card": "Maximize Card",
+ "minimize-card": "Minimize Card",
+ "delete-org-warning-message": "Can not delete this organization, there is at least one user belongs to is",
+ "delete-team-warning-message": "Can not delete this team, there is at least one user belongs to is"
+}
diff --git a/i18n/de.i18n.json b/i18n/de.i18n.json
index 7b0c3c325..5ec558cb6 100644
--- a/i18n/de.i18n.json
+++ b/i18n/de.i18n.json
@@ -82,8 +82,8 @@
"add-attachment": "Datei anhängen",
"add-board": "neues Board",
"add-card": "Karte hinzufügen",
- "add-card-to-top-of-list": "Add Card to Top of List",
- "add-card-to-bottom-of-list": "Add Card to Bottom of List",
+ "add-card-to-top-of-list": "Karte am Anfang der Liste hinzufügen",
+ "add-card-to-bottom-of-list": "Karte am Ende der Liste hinzufügen",
"add-swimlane": "Swimlane hinzufügen",
"add-subtask": "Teilaufgabe hinzufügen",
"add-checklist": "Checkliste hinzufügen",
@@ -133,7 +133,7 @@
"board-not-found": "Board nicht gefunden",
"board-private-info": "Dieses Board wird privat sein.",
"board-public-info": "Dieses Board wird öffentlich sein.",
- "board-drag-drop-reorder-or-click-open": "Drag and drop to reorder board icons. Click board icon to open board.",
+ "board-drag-drop-reorder-or-click-open": "Benutze Drag-and-Drop, um Board-Icons neu anzuordnen. Klicke auf ein Board-Icon, um das Board zu öffnen.",
"boardChangeColorPopup-title": "Farbe des Boards ändern",
"boardChangeTitlePopup-title": "Board umbenennen",
"boardChangeVisibilityPopup-title": "Sichtbarkeit ändern",
@@ -181,10 +181,10 @@
"vote-against": "Dagegen",
"deleteVotePopup-title": "Wahl löschen?",
"vote-delete-pop": "Löschen ist unwiderruflich. Alle Aktionen die dieser Karte zugeordnet sind werden ebenfalls gelöscht.",
- "cardStartPlanningPokerPopup-title": "Start a Planning Poker",
- "card-edit-planning-poker": "Edit Planning Poker",
- "editPokerEndDatePopup-title": "Change Planning Poker vote end date",
- "poker-question": "Planning Poker",
+ "cardStartPlanningPokerPopup-title": "Planungspoker starten",
+ "card-edit-planning-poker": "Planungspoker ändern",
+ "editPokerEndDatePopup-title": "Enddatum für Planungspoker-Stimme ändern",
+ "poker-question": "Planungspoker",
"poker-one": "1",
"poker-two": "2",
"poker-three": "3",
@@ -195,13 +195,13 @@
"poker-forty": "40",
"poker-oneHundred": "100",
"poker-unsure": "?",
- "poker-finish": "Finish",
- "poker-result-votes": "Votes",
- "poker-result-who": "Who",
- "poker-replay": "Replay",
- "set-estimation": "Set Estimation",
- "deletePokerPopup-title": "Delete planning poker?",
- "poker-delete-pop": "Deleting is permanent. You will lose all actions associated with this planning poker.",
+ "poker-finish": "Beenden",
+ "poker-result-votes": "Werte",
+ "poker-result-who": "Wer",
+ "poker-replay": "Wiederholen",
+ "set-estimation": "Schätzung vornehmen",
+ "deletePokerPopup-title": "Planungspoker löschen?",
+ "poker-delete-pop": "Die Löschung ist permanent. Sie werden alles im Zusammenhang mit diesem Planungspoker verlieren.",
"cardDeletePopup-title": "Karte löschen?",
"cardDetailsActionsPopup-title": "Kartenaktionen",
"cardLabelsPopup-title": "Labels",
@@ -233,7 +233,7 @@
"close": "Schließen",
"close-board": "Board schließen",
"close-board-pop": "Sie können das Board wiederherstellen, indem Sie die Schaltfläche \"Archiv\" in der Kopfzeile der Startseite anklicken.",
- "close-card": "Close Card",
+ "close-card": "Karte schließen",
"color-black": "schwarz",
"color-blue": "blau",
"color-crimson": "Karminrot",
@@ -358,7 +358,11 @@
"export-board-excel": "Board nach Excel exportieren",
"user-can-not-export-excel": "Benutzer kann nicht nach Excel exportieren",
"export-board-html": "Board als HTML exportieren",
+ "export-card": "Karte exportieren",
+ "export-card-pdf": "Karte in ein PDF exportieren",
+ "user-can-not-export-card-to-pdf": "Benutzer kann Karte nicht in ein PDF exportieren",
"exportBoardPopup-title": "Board exportieren",
+ "exportCardPopup-title": "Karte exportieren",
"sort": "Sortieren",
"sort-desc": "Zum Sortieren der Liste klicken",
"list-sort-by": "Sortieren der Liste nach:",
@@ -447,8 +451,8 @@
"set-color-list": "Lege Farbe fest",
"listActionPopup-title": "Listenaktionen",
"settingsUserPopup-title": "Benutzereinstellungen",
- "settingsTeamPopup-title": "Team Settings",
- "settingsOrgPopup-title": "Organization Settings",
+ "settingsTeamPopup-title": "Team-Einstellungen",
+ "settingsOrgPopup-title": "Organisations-Einstellungen",
"swimlaneActionPopup-title": "Swimlaneaktionen",
"swimlaneAddPopup-title": "Swimlane unterhalb einfügen",
"listImportCardPopup-title": "Eine Trello-Karte importieren",
@@ -664,6 +668,7 @@
"setListColorPopup-title": "Farbe wählen",
"assigned-by": "Zugewiesen von",
"requested-by": "Angefordert von",
+ "card-sorting-by-number": "Kartensortierung nach Nummer",
"board-delete-notice": "Löschen kann nicht rückgängig gemacht werden. Sie werden alle Listen, Karten und Aktionen, die mit diesem Board verbunden sind, verlieren.",
"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?",
@@ -845,8 +850,8 @@
"act-duenow": "erinnernd an das aktuelle Fälligkeitszeitpunkt (__timeValue__) von __card__ ist jetzt",
"act-atUserComment": "Sie wurden in [__board__] __list__/__card__ erwähnt",
"delete-user-confirm-popup": "Sind Sie sicher, dass Sie diesen Account löschen wollen? Die Aktion kann nicht rückgängig gemacht werden.",
- "delete-team-confirm-popup": "Are you sure you want to delete this team? There is no undo.",
- "delete-org-confirm-popup": "Are you sure you want to delete this organization? There is no undo.",
+ "delete-team-confirm-popup": "Sind Sie sicher, daß Sie dieses Team löschen wollen? Es gibt keine Möglichkeit, das rückgängig zu machen.",
+ "delete-org-confirm-popup": "Sind Sie sicher, daß Sie diese Organisation löschen wollen? Es gibt keine Möglichkeit, das rückgängig zu machen.",
"accounts-allowUserDelete": "Erlaube Benutzern ihren eigenen Account zu löschen",
"hide-minicard-label-text": "Labeltext auf Minikarte ausblenden",
"show-desktop-drag-handles": "Desktop-Ziehpunkte anzeigen",
@@ -1037,5 +1042,18 @@
"rulesReportTitle": "Regeln-Bericht",
"copy-swimlane": "Kopiere Swimlane",
"copySwimlanePopup-title": "Swimlane kopieren",
- "display-card-creator": "Display Card Creator"
-}
\ No newline at end of file
+ "display-card-creator": "Karten-Ersteller anzeigen",
+ "wait-spinner": "Warte-Symbol",
+ "Bounce": "Puls-Warte-Symbol",
+ "Cube": "Würfel-Warte-Symbol",
+ "Cube-Grid": "Würfel-Gitter-Warte-Symbol",
+ "Dot": "Punkt-Warte-Symbol",
+ "Double-Bounce": "Doppelpuls-Warte-Symbol",
+ "Rotateplane": "Drehscheibe-Warte-Symbol",
+ "Scaleout": "Scaleout-Warte-Symbol",
+ "Wave": "Wellen-Warte-Symbol",
+ "maximize-card": "Karte maximieren",
+ "minimize-card": "Karte minimieren",
+ "delete-org-warning-message": "Can not delete this organization, there is at least one user belongs to is",
+ "delete-team-warning-message": "Can not delete this team, there is at least one user belongs to is"
+}
diff --git a/i18n/el.i18n.json b/i18n/el.i18n.json
index dea22da2c..44e8f8efb 100644
--- a/i18n/el.i18n.json
+++ b/i18n/el.i18n.json
@@ -358,7 +358,11 @@
"export-board-excel": "Εξαγωγή πίνακα σε Excel",
"user-can-not-export-excel": "Ο χρήστης δε μπορεί να εξάγει σε Excel",
"export-board-html": "Εξαγωγή πίνακα σε HTML",
+ "export-card": "Export card",
+ "export-card-pdf": "Export card to PDF",
+ "user-can-not-export-card-to-pdf": "User can not export card to PDF",
"exportBoardPopup-title": "Εξαγωγή πίνακα",
+ "exportCardPopup-title": "Export card",
"sort": "Ταξινόμηση",
"sort-desc": "Κάντε κλικ για να ταξινομήστε τη λίστα",
"list-sort-by": "Ταξινόμηση λίστας βάσει:",
@@ -664,6 +668,7 @@
"setListColorPopup-title": "Επιλέξτε ένα χρώμα",
"assigned-by": "Ανατέθηκε Από",
"requested-by": "Αιτήθηκε Από",
+ "card-sorting-by-number": "Card sorting by number",
"board-delete-notice": "Deleting is permanent. You will lose all lists, cards and actions associated with this board.",
"delete-board-confirm-popup": "All lists, cards, labels, and activities will be deleted and you won't be able to recover the board contents. There is no undo.",
"boardDeletePopup-title": "Διαγραφή Πίνακα;",
@@ -1037,5 +1042,18 @@
"rulesReportTitle": "Rules Report",
"copy-swimlane": "Copy Swimlane",
"copySwimlanePopup-title": "Copy Swimlane",
- "display-card-creator": "Display Card Creator"
-}
\ No newline at end of file
+ "display-card-creator": "Display Card Creator",
+ "wait-spinner": "Wait Spinner",
+ "Bounce": "Bounce Wait Spinner",
+ "Cube": "Cube Wait Spinner",
+ "Cube-Grid": "Cube-Grid Wait Spinner",
+ "Dot": "Dot Wait Spinner",
+ "Double-Bounce": "Double Bounce Wait Spinner",
+ "Rotateplane": "Rotateplane Wait Spinner",
+ "Scaleout": "Scaleout Wait Spinner",
+ "Wave": "Wave Wait Spinner",
+ "maximize-card": "Maximize Card",
+ "minimize-card": "Minimize Card",
+ "delete-org-warning-message": "Can not delete this organization, there is at least one user belongs to is",
+ "delete-team-warning-message": "Can not delete this team, there is at least one user belongs to is"
+}
diff --git a/i18n/en-GB.i18n.json b/i18n/en-GB.i18n.json
index e4ef111eb..cdb42f63e 100644
--- a/i18n/en-GB.i18n.json
+++ b/i18n/en-GB.i18n.json
@@ -358,7 +358,11 @@
"export-board-excel": "Export board to Excel",
"user-can-not-export-excel": "User can not export Excel",
"export-board-html": "Export board to HTML",
+ "export-card": "Export card",
+ "export-card-pdf": "Export card to PDF",
+ "user-can-not-export-card-to-pdf": "User can not export card to PDF",
"exportBoardPopup-title": "Export board",
+ "exportCardPopup-title": "Export card",
"sort": "Sort",
"sort-desc": "Click to Sort List",
"list-sort-by": "Sort the List By:",
@@ -664,6 +668,7 @@
"setListColorPopup-title": "Choose a color",
"assigned-by": "Assigned By",
"requested-by": "Requested By",
+ "card-sorting-by-number": "Card sorting by number",
"board-delete-notice": "Deleting is permanent. You will lose all lists, cards and actions associated with this board.",
"delete-board-confirm-popup": "All lists, cards, labels, and activities will be deleted and you won't be able to recover the board contents. There is no undo.",
"boardDeletePopup-title": "Delete Board?",
@@ -1037,5 +1042,18 @@
"rulesReportTitle": "Rules Report",
"copy-swimlane": "Copy Swimlane",
"copySwimlanePopup-title": "Copy Swimlane",
- "display-card-creator": "Display Card Creator"
-}
\ No newline at end of file
+ "display-card-creator": "Display Card Creator",
+ "wait-spinner": "Wait Spinner",
+ "Bounce": "Bounce Wait Spinner",
+ "Cube": "Cube Wait Spinner",
+ "Cube-Grid": "Cube-Grid Wait Spinner",
+ "Dot": "Dot Wait Spinner",
+ "Double-Bounce": "Double Bounce Wait Spinner",
+ "Rotateplane": "Rotateplane Wait Spinner",
+ "Scaleout": "Scaleout Wait Spinner",
+ "Wave": "Wave Wait Spinner",
+ "maximize-card": "Maximize Card",
+ "minimize-card": "Minimize Card",
+ "delete-org-warning-message": "Can not delete this organization, there is at least one user belongs to is",
+ "delete-team-warning-message": "Can not delete this team, there is at least one user belongs to is"
+}
diff --git a/i18n/en.i18n.json b/i18n/en.i18n.json
index f28d62ad3..facd0a31a 100644
--- a/i18n/en.i18n.json
+++ b/i18n/en.i18n.json
@@ -358,7 +358,11 @@
"export-board-excel": "Export board to Excel",
"user-can-not-export-excel": "User can not export Excel",
"export-board-html": "Export board to HTML",
+ "export-card": "Export card",
+ "export-card-pdf": "Export card to PDF",
+ "user-can-not-export-card-to-pdf": "User can not export card to PDF",
"exportBoardPopup-title": "Export board",
+ "exportCardPopup-title": "Export card",
"sort": "Sort",
"sort-desc": "Click to Sort List",
"list-sort-by": "Sort the List By:",
@@ -664,6 +668,7 @@
"setListColorPopup-title": "Choose a color",
"assigned-by": "Assigned By",
"requested-by": "Requested By",
+ "card-sorting-by-number": "Card sorting by number",
"board-delete-notice": "Deleting is permanent. You will lose all lists, cards and actions associated with this board.",
"delete-board-confirm-popup": "All lists, cards, labels, and activities will be deleted and you won't be able to recover the board contents. There is no undo.",
"boardDeletePopup-title": "Delete Board?",
@@ -1038,5 +1043,18 @@
"rulesReportTitle": "Rules Report",
"copy-swimlane": "Copy Swimlane",
"copySwimlanePopup-title": "Copy Swimlane",
- "display-card-creator": "Display Card Creator"
+ "display-card-creator": "Display Card Creator",
+ "wait-spinner": "Wait Spinner",
+ "Bounce": "Bounce Wait Spinner",
+ "Cube": "Cube Wait Spinner",
+ "Cube-Grid": "Cube-Grid Wait Spinner",
+ "Dot": "Dot Wait Spinner",
+ "Double-Bounce": "Double Bounce Wait Spinner",
+ "Rotateplane": "Rotateplane Wait Spinner",
+ "Scaleout": "Scaleout Wait Spinner",
+ "Wave": "Wave Wait Spinner",
+ "maximize-card": "Maximize Card",
+ "minimize-card": "Minimize Card",
+ "delete-org-warning-message": "Can not delete this organization, there is at least one user belongs to is",
+ "delete-team-warning-message": "Can not delete this team, there is at least one user belongs to is"
}
diff --git a/i18n/eo.i18n.json b/i18n/eo.i18n.json
index 1afcd1945..153a6deb6 100644
--- a/i18n/eo.i18n.json
+++ b/i18n/eo.i18n.json
@@ -358,7 +358,11 @@
"export-board-excel": "Export board to Excel",
"user-can-not-export-excel": "User can not export Excel",
"export-board-html": "Export board to HTML",
+ "export-card": "Export card",
+ "export-card-pdf": "Export card to PDF",
+ "user-can-not-export-card-to-pdf": "User can not export card to PDF",
"exportBoardPopup-title": "Export board",
+ "exportCardPopup-title": "Export card",
"sort": "Sort",
"sort-desc": "Click to Sort List",
"list-sort-by": "Sort the List By:",
@@ -664,6 +668,7 @@
"setListColorPopup-title": "Choose a color",
"assigned-by": "Assigned By",
"requested-by": "Requested By",
+ "card-sorting-by-number": "Card sorting by number",
"board-delete-notice": "Deleting is permanent. You will lose all lists, cards and actions associated with this board.",
"delete-board-confirm-popup": "All lists, cards, labels, and activities will be deleted and you won't be able to recover the board contents. There is no undo.",
"boardDeletePopup-title": "Delete Board?",
@@ -1037,5 +1042,18 @@
"rulesReportTitle": "Rules Report",
"copy-swimlane": "Copy Swimlane",
"copySwimlanePopup-title": "Copy Swimlane",
- "display-card-creator": "Display Card Creator"
-}
\ No newline at end of file
+ "display-card-creator": "Display Card Creator",
+ "wait-spinner": "Wait Spinner",
+ "Bounce": "Bounce Wait Spinner",
+ "Cube": "Cube Wait Spinner",
+ "Cube-Grid": "Cube-Grid Wait Spinner",
+ "Dot": "Dot Wait Spinner",
+ "Double-Bounce": "Double Bounce Wait Spinner",
+ "Rotateplane": "Rotateplane Wait Spinner",
+ "Scaleout": "Scaleout Wait Spinner",
+ "Wave": "Wave Wait Spinner",
+ "maximize-card": "Maximize Card",
+ "minimize-card": "Minimize Card",
+ "delete-org-warning-message": "Can not delete this organization, there is at least one user belongs to is",
+ "delete-team-warning-message": "Can not delete this team, there is at least one user belongs to is"
+}
diff --git a/i18n/es-AR.i18n.json b/i18n/es-AR.i18n.json
index 054899f01..1c40d8e84 100644
--- a/i18n/es-AR.i18n.json
+++ b/i18n/es-AR.i18n.json
@@ -358,7 +358,11 @@
"export-board-excel": "Export board to Excel",
"user-can-not-export-excel": "User can not export Excel",
"export-board-html": "Export board to HTML",
+ "export-card": "Export card",
+ "export-card-pdf": "Export card to PDF",
+ "user-can-not-export-card-to-pdf": "User can not export card to PDF",
"exportBoardPopup-title": "Exportar tablero",
+ "exportCardPopup-title": "Export card",
"sort": "Sort",
"sort-desc": "Click to Sort List",
"list-sort-by": "Sort the List By:",
@@ -664,6 +668,7 @@
"setListColorPopup-title": "Choose a color",
"assigned-by": "Assigned By",
"requested-by": "Requested By",
+ "card-sorting-by-number": "Card sorting by number",
"board-delete-notice": "Deleting is permanent. You will lose all lists, cards and actions associated with this board.",
"delete-board-confirm-popup": "All lists, cards, labels, and activities will be deleted and you won't be able to recover the board contents. There is no undo.",
"boardDeletePopup-title": "Delete Board?",
@@ -1037,5 +1042,18 @@
"rulesReportTitle": "Rules Report",
"copy-swimlane": "Copy Swimlane",
"copySwimlanePopup-title": "Copy Swimlane",
- "display-card-creator": "Display Card Creator"
-}
\ No newline at end of file
+ "display-card-creator": "Display Card Creator",
+ "wait-spinner": "Wait Spinner",
+ "Bounce": "Bounce Wait Spinner",
+ "Cube": "Cube Wait Spinner",
+ "Cube-Grid": "Cube-Grid Wait Spinner",
+ "Dot": "Dot Wait Spinner",
+ "Double-Bounce": "Double Bounce Wait Spinner",
+ "Rotateplane": "Rotateplane Wait Spinner",
+ "Scaleout": "Scaleout Wait Spinner",
+ "Wave": "Wave Wait Spinner",
+ "maximize-card": "Maximize Card",
+ "minimize-card": "Minimize Card",
+ "delete-org-warning-message": "Can not delete this organization, there is at least one user belongs to is",
+ "delete-team-warning-message": "Can not delete this team, there is at least one user belongs to is"
+}
diff --git a/i18n/es-CL.i18n.json b/i18n/es-CL.i18n.json
index a6fb5ce50..3ac377c65 100644
--- a/i18n/es-CL.i18n.json
+++ b/i18n/es-CL.i18n.json
@@ -358,7 +358,11 @@
"export-board-excel": "Export board to Excel",
"user-can-not-export-excel": "User can not export Excel",
"export-board-html": "Export board to HTML",
+ "export-card": "Export card",
+ "export-card-pdf": "Export card to PDF",
+ "user-can-not-export-card-to-pdf": "User can not export card to PDF",
"exportBoardPopup-title": "Exportar el tablero",
+ "exportCardPopup-title": "Export card",
"sort": "Ordenar",
"sort-desc": "Click para ordenar la lista",
"list-sort-by": "Ordenar la lista por:",
@@ -664,6 +668,7 @@
"setListColorPopup-title": "Elegir un color",
"assigned-by": "Asignado por",
"requested-by": "Solicitado por",
+ "card-sorting-by-number": "Card sorting by number",
"board-delete-notice": "Se eliminarán todas las listas, tarjetas y acciones asociadas a este tablero. Esta acción no puede deshacerse.",
"delete-board-confirm-popup": "Se eliminarán todas las listas, tarjetas, etiquetas y actividades, y no podrás recuperar los contenidos del tablero. Esta acción no puede deshacerse.",
"boardDeletePopup-title": "¿Eliminar el tablero?",
@@ -1037,5 +1042,18 @@
"rulesReportTitle": "Rules Report",
"copy-swimlane": "Copy Swimlane",
"copySwimlanePopup-title": "Copy Swimlane",
- "display-card-creator": "Display Card Creator"
-}
\ No newline at end of file
+ "display-card-creator": "Display Card Creator",
+ "wait-spinner": "Wait Spinner",
+ "Bounce": "Bounce Wait Spinner",
+ "Cube": "Cube Wait Spinner",
+ "Cube-Grid": "Cube-Grid Wait Spinner",
+ "Dot": "Dot Wait Spinner",
+ "Double-Bounce": "Double Bounce Wait Spinner",
+ "Rotateplane": "Rotateplane Wait Spinner",
+ "Scaleout": "Scaleout Wait Spinner",
+ "Wave": "Wave Wait Spinner",
+ "maximize-card": "Maximize Card",
+ "minimize-card": "Minimize Card",
+ "delete-org-warning-message": "Can not delete this organization, there is at least one user belongs to is",
+ "delete-team-warning-message": "Can not delete this team, there is at least one user belongs to is"
+}
diff --git a/i18n/es-LA.i18n.json b/i18n/es-LA.i18n.json
index 5f2e4e0e5..9ef52fe39 100644
--- a/i18n/es-LA.i18n.json
+++ b/i18n/es-LA.i18n.json
@@ -358,7 +358,11 @@
"export-board-excel": "Export board to Excel",
"user-can-not-export-excel": "User can not export Excel",
"export-board-html": "Export board to HTML",
+ "export-card": "Export card",
+ "export-card-pdf": "Export card to PDF",
+ "user-can-not-export-card-to-pdf": "User can not export card to PDF",
"exportBoardPopup-title": "Export board",
+ "exportCardPopup-title": "Export card",
"sort": "Sort",
"sort-desc": "Click to Sort List",
"list-sort-by": "Sort the List By:",
@@ -664,6 +668,7 @@
"setListColorPopup-title": "Choose a color",
"assigned-by": "Assigned By",
"requested-by": "Requested By",
+ "card-sorting-by-number": "Card sorting by number",
"board-delete-notice": "Deleting is permanent. You will lose all lists, cards and actions associated with this board.",
"delete-board-confirm-popup": "All lists, cards, labels, and activities will be deleted and you won't be able to recover the board contents. There is no undo.",
"boardDeletePopup-title": "Delete Board?",
@@ -1037,5 +1042,18 @@
"rulesReportTitle": "Rules Report",
"copy-swimlane": "Copy Swimlane",
"copySwimlanePopup-title": "Copy Swimlane",
- "display-card-creator": "Display Card Creator"
-}
\ No newline at end of file
+ "display-card-creator": "Display Card Creator",
+ "wait-spinner": "Wait Spinner",
+ "Bounce": "Bounce Wait Spinner",
+ "Cube": "Cube Wait Spinner",
+ "Cube-Grid": "Cube-Grid Wait Spinner",
+ "Dot": "Dot Wait Spinner",
+ "Double-Bounce": "Double Bounce Wait Spinner",
+ "Rotateplane": "Rotateplane Wait Spinner",
+ "Scaleout": "Scaleout Wait Spinner",
+ "Wave": "Wave Wait Spinner",
+ "maximize-card": "Maximize Card",
+ "minimize-card": "Minimize Card",
+ "delete-org-warning-message": "Can not delete this organization, there is at least one user belongs to is",
+ "delete-team-warning-message": "Can not delete this team, there is at least one user belongs to is"
+}
diff --git a/i18n/es-MX.i18n.json b/i18n/es-MX.i18n.json
index 527e6a01b..e2c91dc9a 100644
--- a/i18n/es-MX.i18n.json
+++ b/i18n/es-MX.i18n.json
@@ -358,7 +358,11 @@
"export-board-excel": "Export board to Excel",
"user-can-not-export-excel": "User can not export Excel",
"export-board-html": "Export board to HTML",
+ "export-card": "Export card",
+ "export-card-pdf": "Export card to PDF",
+ "user-can-not-export-card-to-pdf": "User can not export card to PDF",
"exportBoardPopup-title": "Export board",
+ "exportCardPopup-title": "Export card",
"sort": "Sort",
"sort-desc": "Click to Sort List",
"list-sort-by": "Sort the List By:",
@@ -664,6 +668,7 @@
"setListColorPopup-title": "Choose a color",
"assigned-by": "Assigned By",
"requested-by": "Requested By",
+ "card-sorting-by-number": "Card sorting by number",
"board-delete-notice": "Deleting is permanent. You will lose all lists, cards and actions associated with this board.",
"delete-board-confirm-popup": "All lists, cards, labels, and activities will be deleted and you won't be able to recover the board contents. There is no undo.",
"boardDeletePopup-title": "Delete Board?",
@@ -1037,5 +1042,18 @@
"rulesReportTitle": "Rules Report",
"copy-swimlane": "Copy Swimlane",
"copySwimlanePopup-title": "Copy Swimlane",
- "display-card-creator": "Display Card Creator"
-}
\ No newline at end of file
+ "display-card-creator": "Display Card Creator",
+ "wait-spinner": "Wait Spinner",
+ "Bounce": "Bounce Wait Spinner",
+ "Cube": "Cube Wait Spinner",
+ "Cube-Grid": "Cube-Grid Wait Spinner",
+ "Dot": "Dot Wait Spinner",
+ "Double-Bounce": "Double Bounce Wait Spinner",
+ "Rotateplane": "Rotateplane Wait Spinner",
+ "Scaleout": "Scaleout Wait Spinner",
+ "Wave": "Wave Wait Spinner",
+ "maximize-card": "Maximize Card",
+ "minimize-card": "Minimize Card",
+ "delete-org-warning-message": "Can not delete this organization, there is at least one user belongs to is",
+ "delete-team-warning-message": "Can not delete this team, there is at least one user belongs to is"
+}
diff --git a/i18n/es-PE.i18n.json b/i18n/es-PE.i18n.json
index 9105f160c..4c2c07176 100644
--- a/i18n/es-PE.i18n.json
+++ b/i18n/es-PE.i18n.json
@@ -358,7 +358,11 @@
"export-board-excel": "Export board to Excel",
"user-can-not-export-excel": "User can not export Excel",
"export-board-html": "Exportar tablero a HTML",
+ "export-card": "Export card",
+ "export-card-pdf": "Export card to PDF",
+ "user-can-not-export-card-to-pdf": "User can not export card to PDF",
"exportBoardPopup-title": "Exportar tablero",
+ "exportCardPopup-title": "Export card",
"sort": "Ordenar",
"sort-desc": "Clic para ordenar lista",
"list-sort-by": "Ordenar la lista por:",
@@ -664,6 +668,7 @@
"setListColorPopup-title": "Elegir un color",
"assigned-by": "Asignado por",
"requested-by": "Solicitado por",
+ "card-sorting-by-number": "Card sorting by number",
"board-delete-notice": "Se eliminarán todas las listas, tarjetas y acciones asociadas a este tablero. Esta acción no puede deshacerse.",
"delete-board-confirm-popup": "Se eliminarán todas las listas, tarjetas, etiquetas y actividades, y no podrás recuperar los contenidos del tablero. Esta acción no puede deshacerse.",
"boardDeletePopup-title": "¿Eliminar el tablero?",
@@ -1037,5 +1042,18 @@
"rulesReportTitle": "Rules Report",
"copy-swimlane": "Copy Swimlane",
"copySwimlanePopup-title": "Copy Swimlane",
- "display-card-creator": "Display Card Creator"
-}
\ No newline at end of file
+ "display-card-creator": "Display Card Creator",
+ "wait-spinner": "Wait Spinner",
+ "Bounce": "Bounce Wait Spinner",
+ "Cube": "Cube Wait Spinner",
+ "Cube-Grid": "Cube-Grid Wait Spinner",
+ "Dot": "Dot Wait Spinner",
+ "Double-Bounce": "Double Bounce Wait Spinner",
+ "Rotateplane": "Rotateplane Wait Spinner",
+ "Scaleout": "Scaleout Wait Spinner",
+ "Wave": "Wave Wait Spinner",
+ "maximize-card": "Maximize Card",
+ "minimize-card": "Minimize Card",
+ "delete-org-warning-message": "Can not delete this organization, there is at least one user belongs to is",
+ "delete-team-warning-message": "Can not delete this team, there is at least one user belongs to is"
+}
diff --git a/i18n/es-PY.i18n.json b/i18n/es-PY.i18n.json
index 5f2e4e0e5..9ef52fe39 100644
--- a/i18n/es-PY.i18n.json
+++ b/i18n/es-PY.i18n.json
@@ -358,7 +358,11 @@
"export-board-excel": "Export board to Excel",
"user-can-not-export-excel": "User can not export Excel",
"export-board-html": "Export board to HTML",
+ "export-card": "Export card",
+ "export-card-pdf": "Export card to PDF",
+ "user-can-not-export-card-to-pdf": "User can not export card to PDF",
"exportBoardPopup-title": "Export board",
+ "exportCardPopup-title": "Export card",
"sort": "Sort",
"sort-desc": "Click to Sort List",
"list-sort-by": "Sort the List By:",
@@ -664,6 +668,7 @@
"setListColorPopup-title": "Choose a color",
"assigned-by": "Assigned By",
"requested-by": "Requested By",
+ "card-sorting-by-number": "Card sorting by number",
"board-delete-notice": "Deleting is permanent. You will lose all lists, cards and actions associated with this board.",
"delete-board-confirm-popup": "All lists, cards, labels, and activities will be deleted and you won't be able to recover the board contents. There is no undo.",
"boardDeletePopup-title": "Delete Board?",
@@ -1037,5 +1042,18 @@
"rulesReportTitle": "Rules Report",
"copy-swimlane": "Copy Swimlane",
"copySwimlanePopup-title": "Copy Swimlane",
- "display-card-creator": "Display Card Creator"
-}
\ No newline at end of file
+ "display-card-creator": "Display Card Creator",
+ "wait-spinner": "Wait Spinner",
+ "Bounce": "Bounce Wait Spinner",
+ "Cube": "Cube Wait Spinner",
+ "Cube-Grid": "Cube-Grid Wait Spinner",
+ "Dot": "Dot Wait Spinner",
+ "Double-Bounce": "Double Bounce Wait Spinner",
+ "Rotateplane": "Rotateplane Wait Spinner",
+ "Scaleout": "Scaleout Wait Spinner",
+ "Wave": "Wave Wait Spinner",
+ "maximize-card": "Maximize Card",
+ "minimize-card": "Minimize Card",
+ "delete-org-warning-message": "Can not delete this organization, there is at least one user belongs to is",
+ "delete-team-warning-message": "Can not delete this team, there is at least one user belongs to is"
+}
diff --git a/i18n/es.i18n.json b/i18n/es.i18n.json
index 44401e722..fd27f2427 100644
--- a/i18n/es.i18n.json
+++ b/i18n/es.i18n.json
@@ -358,7 +358,11 @@
"export-board-excel": "Exportar tablero a Excel",
"user-can-not-export-excel": "El usuario no puede exportar Excel",
"export-board-html": "Exportar tablero a HTML",
+ "export-card": "Export card",
+ "export-card-pdf": "Export card to PDF",
+ "user-can-not-export-card-to-pdf": "User can not export card to PDF",
"exportBoardPopup-title": "Exportar el tablero",
+ "exportCardPopup-title": "Export card",
"sort": "Ordenar",
"sort-desc": "Click para ordenar la lista",
"list-sort-by": "Ordenar la lista por:",
@@ -664,6 +668,7 @@
"setListColorPopup-title": "Elegir un color",
"assigned-by": "Asignado por",
"requested-by": "Solicitado por",
+ "card-sorting-by-number": "Card sorting by number",
"board-delete-notice": "Se eliminarán todas las listas, tarjetas y acciones asociadas a este tablero. Esta acción no puede deshacerse.",
"delete-board-confirm-popup": "Se eliminarán todas las listas, tarjetas, etiquetas y actividades, y no podrás recuperar los contenidos del tablero. Esta acción no puede deshacerse.",
"boardDeletePopup-title": "¿Eliminar el tablero?",
@@ -1037,5 +1042,18 @@
"rulesReportTitle": "Rules Report",
"copy-swimlane": "Copy Swimlane",
"copySwimlanePopup-title": "Copy Swimlane",
- "display-card-creator": "Display Card Creator"
-}
\ No newline at end of file
+ "display-card-creator": "Display Card Creator",
+ "wait-spinner": "Wait Spinner",
+ "Bounce": "Bounce Wait Spinner",
+ "Cube": "Cube Wait Spinner",
+ "Cube-Grid": "Cube-Grid Wait Spinner",
+ "Dot": "Dot Wait Spinner",
+ "Double-Bounce": "Double Bounce Wait Spinner",
+ "Rotateplane": "Rotateplane Wait Spinner",
+ "Scaleout": "Scaleout Wait Spinner",
+ "Wave": "Wave Wait Spinner",
+ "maximize-card": "Maximize Card",
+ "minimize-card": "Minimize Card",
+ "delete-org-warning-message": "Can not delete this organization, there is at least one user belongs to is",
+ "delete-team-warning-message": "Can not delete this team, there is at least one user belongs to is"
+}
diff --git a/i18n/eu.i18n.json b/i18n/eu.i18n.json
index 48bdbf589..0c473d418 100644
--- a/i18n/eu.i18n.json
+++ b/i18n/eu.i18n.json
@@ -358,7 +358,11 @@
"export-board-excel": "Export board to Excel",
"user-can-not-export-excel": "User can not export Excel",
"export-board-html": "Export board to HTML",
+ "export-card": "Export card",
+ "export-card-pdf": "Export card to PDF",
+ "user-can-not-export-card-to-pdf": "User can not export card to PDF",
"exportBoardPopup-title": "Esportatu arbela",
+ "exportCardPopup-title": "Export card",
"sort": "Sort",
"sort-desc": "Click to Sort List",
"list-sort-by": "Sort the List By:",
@@ -664,6 +668,7 @@
"setListColorPopup-title": "Choose a color",
"assigned-by": "Assigned By",
"requested-by": "Requested By",
+ "card-sorting-by-number": "Card sorting by number",
"board-delete-notice": "Deleting is permanent. You will lose all lists, cards and actions associated with this board.",
"delete-board-confirm-popup": "All lists, cards, labels, and activities will be deleted and you won't be able to recover the board contents. There is no undo.",
"boardDeletePopup-title": "Delete Board?",
@@ -1037,5 +1042,18 @@
"rulesReportTitle": "Rules Report",
"copy-swimlane": "Copy Swimlane",
"copySwimlanePopup-title": "Copy Swimlane",
- "display-card-creator": "Display Card Creator"
-}
\ No newline at end of file
+ "display-card-creator": "Display Card Creator",
+ "wait-spinner": "Wait Spinner",
+ "Bounce": "Bounce Wait Spinner",
+ "Cube": "Cube Wait Spinner",
+ "Cube-Grid": "Cube-Grid Wait Spinner",
+ "Dot": "Dot Wait Spinner",
+ "Double-Bounce": "Double Bounce Wait Spinner",
+ "Rotateplane": "Rotateplane Wait Spinner",
+ "Scaleout": "Scaleout Wait Spinner",
+ "Wave": "Wave Wait Spinner",
+ "maximize-card": "Maximize Card",
+ "minimize-card": "Minimize Card",
+ "delete-org-warning-message": "Can not delete this organization, there is at least one user belongs to is",
+ "delete-team-warning-message": "Can not delete this team, there is at least one user belongs to is"
+}
diff --git a/i18n/fa-IR.i18n.json b/i18n/fa-IR.i18n.json
index 219e7132a..221c25527 100644
--- a/i18n/fa-IR.i18n.json
+++ b/i18n/fa-IR.i18n.json
@@ -358,7 +358,11 @@
"export-board-excel": "Export board to Excel",
"user-can-not-export-excel": "User can not export Excel",
"export-board-html": "Export board to HTML",
+ "export-card": "Export card",
+ "export-card-pdf": "Export card to PDF",
+ "user-can-not-export-card-to-pdf": "User can not export card to PDF",
"exportBoardPopup-title": "Export board",
+ "exportCardPopup-title": "Export card",
"sort": "Sort",
"sort-desc": "Click to Sort List",
"list-sort-by": "Sort the List By:",
@@ -664,6 +668,7 @@
"setListColorPopup-title": "Choose a color",
"assigned-by": "Assigned By",
"requested-by": "Requested By",
+ "card-sorting-by-number": "Card sorting by number",
"board-delete-notice": "Deleting is permanent. You will lose all lists, cards and actions associated with this board.",
"delete-board-confirm-popup": "All lists, cards, labels, and activities will be deleted and you won't be able to recover the board contents. There is no undo.",
"boardDeletePopup-title": "Delete Board?",
@@ -1037,5 +1042,18 @@
"rulesReportTitle": "Rules Report",
"copy-swimlane": "Copy Swimlane",
"copySwimlanePopup-title": "Copy Swimlane",
- "display-card-creator": "Display Card Creator"
-}
\ No newline at end of file
+ "display-card-creator": "Display Card Creator",
+ "wait-spinner": "Wait Spinner",
+ "Bounce": "Bounce Wait Spinner",
+ "Cube": "Cube Wait Spinner",
+ "Cube-Grid": "Cube-Grid Wait Spinner",
+ "Dot": "Dot Wait Spinner",
+ "Double-Bounce": "Double Bounce Wait Spinner",
+ "Rotateplane": "Rotateplane Wait Spinner",
+ "Scaleout": "Scaleout Wait Spinner",
+ "Wave": "Wave Wait Spinner",
+ "maximize-card": "Maximize Card",
+ "minimize-card": "Minimize Card",
+ "delete-org-warning-message": "Can not delete this organization, there is at least one user belongs to is",
+ "delete-team-warning-message": "Can not delete this team, there is at least one user belongs to is"
+}
diff --git a/i18n/fa.i18n.json b/i18n/fa.i18n.json
index ba265e601..9c4dee1f8 100644
--- a/i18n/fa.i18n.json
+++ b/i18n/fa.i18n.json
@@ -358,7 +358,11 @@
"export-board-excel": "خروجی برد به اکسل",
"user-can-not-export-excel": "کاربر قادر به گرفتن خروجی اکسلب نیست",
"export-board-html": "اکسپورت برد به HTML",
+ "export-card": "Export card",
+ "export-card-pdf": "Export card to PDF",
+ "user-can-not-export-card-to-pdf": "User can not export card to PDF",
"exportBoardPopup-title": "انتقال به بیرون برد",
+ "exportCardPopup-title": "Export card",
"sort": "مرتب سازی",
"sort-desc": "برای مرتب سازی لیست کلیک کنید",
"list-sort-by": "مرتب سازی لیست بر اساس:",
@@ -664,6 +668,7 @@
"setListColorPopup-title": "انتخاب کردن رنگ",
"assigned-by": "محول شده توسط",
"requested-by": "تقاضا شده توسط",
+ "card-sorting-by-number": "Card sorting by number",
"board-delete-notice": "حذف دائمی است شما تمام لیست ها، کارت ها و اقدامات مرتبط با این برد را از دست خواهید داد.",
"delete-board-confirm-popup": "تمام لیست ها، کارت ها، لیبل ها و فعالیت ها حذف خواهند شد و شما نمی توانید محتوای برد را بازیابی کنید. هیچ واکنشی وجود ندارد",
"boardDeletePopup-title": "حذف برد؟",
@@ -1037,5 +1042,18 @@
"rulesReportTitle": "گزارش قوانین",
"copy-swimlane": "کپی از مسیر",
"copySwimlanePopup-title": "کپی از مسیر",
- "display-card-creator": "Display Card Creator"
-}
\ No newline at end of file
+ "display-card-creator": "Display Card Creator",
+ "wait-spinner": "Wait Spinner",
+ "Bounce": "Bounce Wait Spinner",
+ "Cube": "Cube Wait Spinner",
+ "Cube-Grid": "Cube-Grid Wait Spinner",
+ "Dot": "Dot Wait Spinner",
+ "Double-Bounce": "Double Bounce Wait Spinner",
+ "Rotateplane": "Rotateplane Wait Spinner",
+ "Scaleout": "Scaleout Wait Spinner",
+ "Wave": "Wave Wait Spinner",
+ "maximize-card": "Maximize Card",
+ "minimize-card": "Minimize Card",
+ "delete-org-warning-message": "Can not delete this organization, there is at least one user belongs to is",
+ "delete-team-warning-message": "Can not delete this team, there is at least one user belongs to is"
+}
diff --git a/i18n/fi.i18n.json b/i18n/fi.i18n.json
index cf3929db3..06e0cd76e 100644
--- a/i18n/fi.i18n.json
+++ b/i18n/fi.i18n.json
@@ -358,7 +358,11 @@
"export-board-excel": "Vie taulu Excel",
"user-can-not-export-excel": "Käyttäjä ei voi viedä Excel tiedostoon",
"export-board-html": "Vie taulu HTML",
+ "export-card": "Vie kortti",
+ "export-card-pdf": "Vie kortti PDF",
+ "user-can-not-export-card-to-pdf": "Käyttäjä ei voi viedä korttia PDF tiedostoon",
"exportBoardPopup-title": "Vie taulu",
+ "exportCardPopup-title": "Vie kortti",
"sort": "Lajittele",
"sort-desc": "Klikkaa lajitellaksesi listan",
"list-sort-by": "Lajittele lista:",
@@ -664,6 +668,7 @@
"setListColorPopup-title": "Valitse väri",
"assigned-by": "Tehtävänantaja",
"requested-by": "Pyytäjä",
+ "card-sorting-by-number": "Korttien lajittelu numeroiden mukaan",
"board-delete-notice": "Poistaminen on lopullista. Menetät kaikki listat, kortit ja toimet tällä taululla.",
"delete-board-confirm-popup": "Kaikki listat, kortit, nimilaput ja toimet poistetaan ja et pysty palauttamaan taulun sisältöä. Tätä ei voi peruuttaa.",
"boardDeletePopup-title": "Poista taulu?",
@@ -1037,5 +1042,18 @@
"rulesReportTitle": "Säännöt raportti",
"copy-swimlane": "Kopioi Swimlane",
"copySwimlanePopup-title": "Kopioi Swimlane",
- "display-card-creator": "Näytä kortin luoja"
-}
\ No newline at end of file
+ "display-card-creator": "Näytä kortin luoja",
+ "wait-spinner": "Odotus pyörijä",
+ "Bounce": "Pomppu odotus pyörijä",
+ "Cube": "Kuutio odotus pyörijä",
+ "Cube-Grid": "Kuutio ristikko odotus pyörijä",
+ "Dot": "Piste odotus pyörijä",
+ "Double-Bounce": "Tupla pomppu odotus pyörijä",
+ "Rotateplane": "Pyöritä tasoa odotus pyörijä",
+ "Scaleout": "Skaalaus ulos odotus pyörijä",
+ "Wave": "Aalto odotus pyörijä",
+ "maximize-card": "Suurenna kortti",
+ "minimize-card": "Pienennä kortti",
+ "delete-org-warning-message": "Can not delete this organization, there is at least one user belongs to is",
+ "delete-team-warning-message": "Can not delete this team, there is at least one user belongs to is"
+}
diff --git a/i18n/fr.i18n.json b/i18n/fr.i18n.json
index 8c42f32ba..12d3bbea0 100644
--- a/i18n/fr.i18n.json
+++ b/i18n/fr.i18n.json
@@ -82,8 +82,8 @@
"add-attachment": "Ajouter une pièce jointe",
"add-board": "Ajouter un tableau",
"add-card": "Ajouter une carte",
- "add-card-to-top-of-list": "Add Card to Top of List",
- "add-card-to-bottom-of-list": "Add Card to Bottom of List",
+ "add-card-to-top-of-list": "Ajouter la carte en haut de la liste",
+ "add-card-to-bottom-of-list": "Ajouter la carte en bas de la liste",
"add-swimlane": "Ajouter un couloir",
"add-subtask": "Ajouter une sous-tâche",
"add-checklist": "Ajouter une checklist",
@@ -133,7 +133,7 @@
"board-not-found": "Tableau non trouvé",
"board-private-info": "Ce tableau sera privé",
"board-public-info": "Ce tableau sera public.",
- "board-drag-drop-reorder-or-click-open": "Drag and drop to reorder board icons. Click board icon to open board.",
+ "board-drag-drop-reorder-or-click-open": "Glisser-déposer les icônes de tableau pour les réordonner. Cliquer sur l'icône du tableau pour l'ouvrir.",
"boardChangeColorPopup-title": "Change la couleur de fond du tableau",
"boardChangeTitlePopup-title": "Renommer le tableau",
"boardChangeVisibilityPopup-title": "Changer la visibilité",
@@ -233,7 +233,7 @@
"close": "Fermer",
"close-board": "Fermer le tableau",
"close-board-pop": "Vous pouvez restaurer le tableau en cliquant sur le bouton « Archives » depuis le menu en entête.",
- "close-card": "Close Card",
+ "close-card": "Fermer la carte",
"color-black": "noir",
"color-blue": "bleu",
"color-crimson": "rouge cramoisi",
@@ -358,7 +358,11 @@
"export-board-excel": "Exporter le tableau vers Excel",
"user-can-not-export-excel": "L'utilisateur ne peut pas exporter vers Excel",
"export-board-html": "Exporter le tableau en HTML",
+ "export-card": "Exporter la carte",
+ "export-card-pdf": "Exporter la carte en PDF",
+ "user-can-not-export-card-to-pdf": "L'utilisateur ne peut pas exporter de carte en PDF",
"exportBoardPopup-title": "Exporter le tableau",
+ "exportCardPopup-title": "Exporter la carte",
"sort": "Tri",
"sort-desc": "Cliquez pour trier la liste",
"list-sort-by": "Trier la liste par:",
@@ -664,6 +668,7 @@
"setListColorPopup-title": "Choisissez une couleur",
"assigned-by": "Assigné par",
"requested-by": "Demandé par",
+ "card-sorting-by-number": "Tri numérique des cartes",
"board-delete-notice": "La suppression est définitive. Vous perdrez toutes les listes, cartes et actions associées à ce tableau.",
"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 ?",
@@ -1037,5 +1042,18 @@
"rulesReportTitle": "Rapports sur les règles",
"copy-swimlane": "Copier le couloir",
"copySwimlanePopup-title": "Copie de Couloir",
- "display-card-creator": "Afficher le créateur de la carte"
-}
\ No newline at end of file
+ "display-card-creator": "Afficher le créateur de la carte",
+ "wait-spinner": "Icône d'attente",
+ "Bounce": "Icône d'attente rebond",
+ "Cube": "Icône d'attente cube",
+ "Cube-Grid": "Icône d'attente cube filaire",
+ "Dot": "Icône d'attente point",
+ "Double-Bounce": "Icône d'attente double rebond",
+ "Rotateplane": "Icône d'attente plan rotatif",
+ "Scaleout": "Icône d'attente mise à l'échelle",
+ "Wave": "Icône d'attente onde",
+ "maximize-card": "Maximiser la carte",
+ "minimize-card": "Minimiser la carte",
+ "delete-org-warning-message": "Impossible de supprimer cette organisation, il y a au moins un utilisateur qui appartient à cette organisation",
+ "delete-team-warning-message": "Impossible de supprimer cette équipe, il y a au moins un utilisateur qui appartient à cette équipe"
+}
diff --git a/i18n/gl.i18n.json b/i18n/gl.i18n.json
index 91c421035..4db0b6ca1 100644
--- a/i18n/gl.i18n.json
+++ b/i18n/gl.i18n.json
@@ -358,7 +358,11 @@
"export-board-excel": "Export board to Excel",
"user-can-not-export-excel": "User can not export Excel",
"export-board-html": "Export board to HTML",
+ "export-card": "Export card",
+ "export-card-pdf": "Export card to PDF",
+ "user-can-not-export-card-to-pdf": "User can not export card to PDF",
"exportBoardPopup-title": "Exportar taboleiro",
+ "exportCardPopup-title": "Export card",
"sort": "Sort",
"sort-desc": "Click to Sort List",
"list-sort-by": "Sort the List By:",
@@ -664,6 +668,7 @@
"setListColorPopup-title": "Choose a color",
"assigned-by": "Assigned By",
"requested-by": "Requested By",
+ "card-sorting-by-number": "Card sorting by number",
"board-delete-notice": "Deleting is permanent. You will lose all lists, cards and actions associated with this board.",
"delete-board-confirm-popup": "All lists, cards, labels, and activities will be deleted and you won't be able to recover the board contents. There is no undo.",
"boardDeletePopup-title": "Delete Board?",
@@ -1037,5 +1042,18 @@
"rulesReportTitle": "Rules Report",
"copy-swimlane": "Copy Swimlane",
"copySwimlanePopup-title": "Copy Swimlane",
- "display-card-creator": "Display Card Creator"
-}
\ No newline at end of file
+ "display-card-creator": "Display Card Creator",
+ "wait-spinner": "Wait Spinner",
+ "Bounce": "Bounce Wait Spinner",
+ "Cube": "Cube Wait Spinner",
+ "Cube-Grid": "Cube-Grid Wait Spinner",
+ "Dot": "Dot Wait Spinner",
+ "Double-Bounce": "Double Bounce Wait Spinner",
+ "Rotateplane": "Rotateplane Wait Spinner",
+ "Scaleout": "Scaleout Wait Spinner",
+ "Wave": "Wave Wait Spinner",
+ "maximize-card": "Maximize Card",
+ "minimize-card": "Minimize Card",
+ "delete-org-warning-message": "Can not delete this organization, there is at least one user belongs to is",
+ "delete-team-warning-message": "Can not delete this team, there is at least one user belongs to is"
+}
diff --git a/i18n/he.i18n.json b/i18n/he.i18n.json
index bc8fd4dd8..bd1032f00 100644
--- a/i18n/he.i18n.json
+++ b/i18n/he.i18n.json
@@ -82,8 +82,8 @@
"add-attachment": "הוספת קובץ מצורף",
"add-board": "הוספת לוח",
"add-card": "הוספת כרטיס",
- "add-card-to-top-of-list": "Add Card to Top of List",
- "add-card-to-bottom-of-list": "Add Card to Bottom of List",
+ "add-card-to-top-of-list": "הוספת כרטיס לראש הרשימה",
+ "add-card-to-bottom-of-list": "הוספת כרטיס לתחתית הרשימה",
"add-swimlane": "הוספת מסלול",
"add-subtask": "הוסף תת משימה",
"add-checklist": "הוספת רשימת מטלות",
@@ -133,7 +133,7 @@
"board-not-found": "לוח לא נמצא",
"board-private-info": "לוח זה יהיה פרטי.",
"board-public-info": "לוח זה יהיה ציבורי.",
- "board-drag-drop-reorder-or-click-open": "Drag and drop to reorder board icons. Click board icon to open board.",
+ "board-drag-drop-reorder-or-click-open": "יש לגרור ולסדר מחדש את סמלי הלוח. לחיצה על סמל הלוח תפתח אותו.",
"boardChangeColorPopup-title": "שינוי רקע ללוח",
"boardChangeTitlePopup-title": "שינוי שם הלוח",
"boardChangeVisibilityPopup-title": "שינוי מצב הצגה",
@@ -233,7 +233,7 @@
"close": "סגירה",
"close-board": "סגירת לוח",
"close-board-pop": "ניתן לשחזר את הלוח בלחיצה על כפתור „ארכיונים“ מהכותרת העליונה.",
- "close-card": "Close Card",
+ "close-card": "סגירת כרטיס",
"color-black": "שחור",
"color-blue": "כחול",
"color-crimson": "שני",
@@ -358,7 +358,11 @@
"export-board-excel": "ייצוא לוח ל־Excel",
"user-can-not-export-excel": "המשתמש לא יכול לייצא ל־Excel",
"export-board-html": "ייצוא לוח ל־HTML",
+ "export-card": "ייצוא כרטיס",
+ "export-card-pdf": "ייצוא כרטיס ל־PDF",
+ "user-can-not-export-card-to-pdf": "המשתמש לא יכול לייצא כרטיס ל־PDF",
"exportBoardPopup-title": "ייצוא לוח",
+ "exportCardPopup-title": "ייצוא כרטיס",
"sort": "מיון",
"sort-desc": "לחיצה למיון הרשימה",
"list-sort-by": "מיון הרשימה לפי:",
@@ -664,6 +668,7 @@
"setListColorPopup-title": "בחירת צבע",
"assigned-by": "הוקצה על ידי",
"requested-by": "התבקש על ידי",
+ "card-sorting-by-number": "מיון כרטיסים לפי מספר",
"board-delete-notice": "מחיקה היא לצמיתות. כל הרשימות, הכרטיבים והפעולות שקשורים בלוח הזה ילכו לאיבוד.",
"delete-board-confirm-popup": "כל הרשימות, הכרטיסים, התווית והפעולות יימחקו ולא תהיה לך דרך לשחזר את תכני הלוח. אין אפשרות לבטל.",
"boardDeletePopup-title": "למחוק את הלוח?",
@@ -1037,5 +1042,18 @@
"rulesReportTitle": "דוח כללים",
"copy-swimlane": "העתקת מסלול",
"copySwimlanePopup-title": "העתקת מסלול",
- "display-card-creator": "להציג את יוצר הכרטיסים"
-}
\ No newline at end of file
+ "display-card-creator": "להציג את יוצר הכרטיסים",
+ "wait-spinner": "שבשבת המתנה",
+ "Bounce": "שבשבת המתנה קופצת",
+ "Cube": "שבשבת המתנה קוביה",
+ "Cube-Grid": "שבשבת המתנה קוביית קשת",
+ "Dot": "שבשבת המתנה נקודה",
+ "Double-Bounce": "שבשבת המתנה קפיצה כפולה",
+ "Rotateplane": "שבשבת המתנה משטח נוטה",
+ "Scaleout": "שבשבת המתנה התרחקות",
+ "Wave": "שבשבת המתנה גל",
+ "maximize-card": "הגדלת כרטיס",
+ "minimize-card": "מזעור כרטיס",
+ "delete-org-warning-message": "Can not delete this organization, there is at least one user belongs to is",
+ "delete-team-warning-message": "Can not delete this team, there is at least one user belongs to is"
+}
diff --git a/i18n/hi.i18n.json b/i18n/hi.i18n.json
index 26d1eac2d..05a0f945e 100644
--- a/i18n/hi.i18n.json
+++ b/i18n/hi.i18n.json
@@ -358,7 +358,11 @@
"export-board-excel": "Export board to Excel",
"user-can-not-export-excel": "User can not export Excel",
"export-board-html": "HTML को निर्यात बोर्ड",
+ "export-card": "Export card",
+ "export-card-pdf": "Export card to PDF",
+ "user-can-not-export-card-to-pdf": "User can not export card to PDF",
"exportBoardPopup-title": "Export बोर्ड",
+ "exportCardPopup-title": "Export card",
"sort": "भांति",
"sort-desc": "क्रमबद्ध सूची पर क्लिक करें",
"list-sort-by": "सूची क्रमबद्ध करें:",
@@ -664,6 +668,7 @@
"setListColorPopup-title": "Choose a color",
"assigned-by": "Assigned By",
"requested-by": "Requested By",
+ "card-sorting-by-number": "Card sorting by number",
"board-delete-notice": "Deleting is permanent. You will lose संपूर्ण lists, कार्ड और actions associated साथ में यह बोर्ड.",
"delete-board-confirm-popup": "All lists, कार्ड,नामपत्र , और activities हो जाएगा deleted और you won't be able तक recover the बोर्ड contents. There is no undo.",
"boardDeletePopup-title": "मिटाएँ बोर्ड?",
@@ -1037,5 +1042,18 @@
"rulesReportTitle": "Rules Report",
"copy-swimlane": "Copy Swimlane",
"copySwimlanePopup-title": "Copy Swimlane",
- "display-card-creator": "Display Card Creator"
-}
\ No newline at end of file
+ "display-card-creator": "Display Card Creator",
+ "wait-spinner": "Wait Spinner",
+ "Bounce": "Bounce Wait Spinner",
+ "Cube": "Cube Wait Spinner",
+ "Cube-Grid": "Cube-Grid Wait Spinner",
+ "Dot": "Dot Wait Spinner",
+ "Double-Bounce": "Double Bounce Wait Spinner",
+ "Rotateplane": "Rotateplane Wait Spinner",
+ "Scaleout": "Scaleout Wait Spinner",
+ "Wave": "Wave Wait Spinner",
+ "maximize-card": "Maximize Card",
+ "minimize-card": "Minimize Card",
+ "delete-org-warning-message": "Can not delete this organization, there is at least one user belongs to is",
+ "delete-team-warning-message": "Can not delete this team, there is at least one user belongs to is"
+}
diff --git a/i18n/hr.i18n.json b/i18n/hr.i18n.json
index 2a6ce32b2..5add4161e 100644
--- a/i18n/hr.i18n.json
+++ b/i18n/hr.i18n.json
@@ -358,7 +358,11 @@
"export-board-excel": "Export board to Excel",
"user-can-not-export-excel": "User can not export Excel",
"export-board-html": "Export board to HTML",
+ "export-card": "Export card",
+ "export-card-pdf": "Export card to PDF",
+ "user-can-not-export-card-to-pdf": "User can not export card to PDF",
"exportBoardPopup-title": "Export board",
+ "exportCardPopup-title": "Export card",
"sort": "Sort",
"sort-desc": "Click to Sort List",
"list-sort-by": "Sort the List By:",
@@ -664,6 +668,7 @@
"setListColorPopup-title": "Choose a color",
"assigned-by": "Zadano od",
"requested-by": "Zatraženo od",
+ "card-sorting-by-number": "Card sorting by number",
"board-delete-notice": "Deleting is permanent. You will lose all lists, cards and actions associated with this board.",
"delete-board-confirm-popup": "All lists, cards, labels, and activities will be deleted and you won't be able to recover the board contents. There is no undo.",
"boardDeletePopup-title": "Obrisati ploču?",
@@ -1037,5 +1042,18 @@
"rulesReportTitle": "Rules Report",
"copy-swimlane": "Copy Swimlane",
"copySwimlanePopup-title": "Copy Swimlane",
- "display-card-creator": "Display Card Creator"
-}
\ No newline at end of file
+ "display-card-creator": "Display Card Creator",
+ "wait-spinner": "Wait Spinner",
+ "Bounce": "Bounce Wait Spinner",
+ "Cube": "Cube Wait Spinner",
+ "Cube-Grid": "Cube-Grid Wait Spinner",
+ "Dot": "Dot Wait Spinner",
+ "Double-Bounce": "Double Bounce Wait Spinner",
+ "Rotateplane": "Rotateplane Wait Spinner",
+ "Scaleout": "Scaleout Wait Spinner",
+ "Wave": "Wave Wait Spinner",
+ "maximize-card": "Maximize Card",
+ "minimize-card": "Minimize Card",
+ "delete-org-warning-message": "Can not delete this organization, there is at least one user belongs to is",
+ "delete-team-warning-message": "Can not delete this team, there is at least one user belongs to is"
+}
diff --git a/i18n/hu.i18n.json b/i18n/hu.i18n.json
index 460fae527..60179289f 100644
--- a/i18n/hu.i18n.json
+++ b/i18n/hu.i18n.json
@@ -358,7 +358,11 @@
"export-board-excel": "Exportáld a Táblát Excelbe",
"user-can-not-export-excel": "Felhasználó nem tud Excelbe exportálni",
"export-board-html": "Exportáld a táblát HTML (webes) formátumba",
+ "export-card": "Export card",
+ "export-card-pdf": "Export card to PDF",
+ "user-can-not-export-card-to-pdf": "User can not export card to PDF",
"exportBoardPopup-title": "Tábla exportálása",
+ "exportCardPopup-title": "Export card",
"sort": "Rendezés",
"sort-desc": "Kattints a lista rendezéséhez",
"list-sort-by": "Rendezd a Listát e szerint:",
@@ -664,6 +668,7 @@
"setListColorPopup-title": "Válassz színt",
"assigned-by": "Hozzárendelte ",
"requested-by": "Igényelte",
+ "card-sorting-by-number": "Card sorting by number",
"board-delete-notice": "A törlés végleges. Minden Lista, Kártya és kapcsolódó esemény megsemmisül ezen a Táblán.",
"delete-board-confirm-popup": "Minden Lista, Kártya, Címke és Esemény véglegesen törlésre kerül és nincs rá mód, hogy visszanyerd a Tábla tartalmát. Nincs visszavonási lehetőség sem.",
"boardDeletePopup-title": "TÖRLÖD a Táblát?",
@@ -1037,5 +1042,18 @@
"rulesReportTitle": "Rules Report",
"copy-swimlane": "Copy Swimlane",
"copySwimlanePopup-title": "Copy Swimlane",
- "display-card-creator": "Display Card Creator"
-}
\ No newline at end of file
+ "display-card-creator": "Display Card Creator",
+ "wait-spinner": "Wait Spinner",
+ "Bounce": "Bounce Wait Spinner",
+ "Cube": "Cube Wait Spinner",
+ "Cube-Grid": "Cube-Grid Wait Spinner",
+ "Dot": "Dot Wait Spinner",
+ "Double-Bounce": "Double Bounce Wait Spinner",
+ "Rotateplane": "Rotateplane Wait Spinner",
+ "Scaleout": "Scaleout Wait Spinner",
+ "Wave": "Wave Wait Spinner",
+ "maximize-card": "Maximize Card",
+ "minimize-card": "Minimize Card",
+ "delete-org-warning-message": "Can not delete this organization, there is at least one user belongs to is",
+ "delete-team-warning-message": "Can not delete this team, there is at least one user belongs to is"
+}
diff --git a/i18n/hy.i18n.json b/i18n/hy.i18n.json
index 8aa7c0ef9..53432aeda 100644
--- a/i18n/hy.i18n.json
+++ b/i18n/hy.i18n.json
@@ -358,7 +358,11 @@
"export-board-excel": "Export board to Excel",
"user-can-not-export-excel": "User can not export Excel",
"export-board-html": "Export board to HTML",
+ "export-card": "Export card",
+ "export-card-pdf": "Export card to PDF",
+ "user-can-not-export-card-to-pdf": "User can not export card to PDF",
"exportBoardPopup-title": "Export board",
+ "exportCardPopup-title": "Export card",
"sort": "Sort",
"sort-desc": "Click to Sort List",
"list-sort-by": "Sort the List By:",
@@ -664,6 +668,7 @@
"setListColorPopup-title": "Choose a color",
"assigned-by": "Assigned By",
"requested-by": "Requested By",
+ "card-sorting-by-number": "Card sorting by number",
"board-delete-notice": "Deleting is permanent. You will lose all lists, cards and actions associated with this board.",
"delete-board-confirm-popup": "All lists, cards, labels, and activities will be deleted and you won't be able to recover the board contents. There is no undo.",
"boardDeletePopup-title": "Delete Board?",
@@ -1037,5 +1042,18 @@
"rulesReportTitle": "Rules Report",
"copy-swimlane": "Copy Swimlane",
"copySwimlanePopup-title": "Copy Swimlane",
- "display-card-creator": "Display Card Creator"
-}
\ No newline at end of file
+ "display-card-creator": "Display Card Creator",
+ "wait-spinner": "Wait Spinner",
+ "Bounce": "Bounce Wait Spinner",
+ "Cube": "Cube Wait Spinner",
+ "Cube-Grid": "Cube-Grid Wait Spinner",
+ "Dot": "Dot Wait Spinner",
+ "Double-Bounce": "Double Bounce Wait Spinner",
+ "Rotateplane": "Rotateplane Wait Spinner",
+ "Scaleout": "Scaleout Wait Spinner",
+ "Wave": "Wave Wait Spinner",
+ "maximize-card": "Maximize Card",
+ "minimize-card": "Minimize Card",
+ "delete-org-warning-message": "Can not delete this organization, there is at least one user belongs to is",
+ "delete-team-warning-message": "Can not delete this team, there is at least one user belongs to is"
+}
diff --git a/i18n/id.i18n.json b/i18n/id.i18n.json
index 31a71eca5..f222a97e5 100644
--- a/i18n/id.i18n.json
+++ b/i18n/id.i18n.json
@@ -358,7 +358,11 @@
"export-board-excel": "Export board to Excel",
"user-can-not-export-excel": "User can not export Excel",
"export-board-html": "Export board to HTML",
+ "export-card": "Export card",
+ "export-card-pdf": "Export card to PDF",
+ "user-can-not-export-card-to-pdf": "User can not export card to PDF",
"exportBoardPopup-title": "Exspor Panel",
+ "exportCardPopup-title": "Export card",
"sort": "Sort",
"sort-desc": "Click to Sort List",
"list-sort-by": "Sort the List By:",
@@ -664,6 +668,7 @@
"setListColorPopup-title": "Pilih warna",
"assigned-by": "Ditandatangani Oleh",
"requested-by": "Diminta Oleh",
+ "card-sorting-by-number": "Card sorting by number",
"board-delete-notice": "Deleting is permanent. You will lose all lists, cards and actions associated with this board.",
"delete-board-confirm-popup": "All lists, cards, labels, and activities will be deleted and you won't be able to recover the board contents. There is no undo.",
"boardDeletePopup-title": "Hapus Papan?",
@@ -1037,5 +1042,18 @@
"rulesReportTitle": "Rules Report",
"copy-swimlane": "Copy Swimlane",
"copySwimlanePopup-title": "Copy Swimlane",
- "display-card-creator": "Display Card Creator"
-}
\ No newline at end of file
+ "display-card-creator": "Display Card Creator",
+ "wait-spinner": "Wait Spinner",
+ "Bounce": "Bounce Wait Spinner",
+ "Cube": "Cube Wait Spinner",
+ "Cube-Grid": "Cube-Grid Wait Spinner",
+ "Dot": "Dot Wait Spinner",
+ "Double-Bounce": "Double Bounce Wait Spinner",
+ "Rotateplane": "Rotateplane Wait Spinner",
+ "Scaleout": "Scaleout Wait Spinner",
+ "Wave": "Wave Wait Spinner",
+ "maximize-card": "Maximize Card",
+ "minimize-card": "Minimize Card",
+ "delete-org-warning-message": "Can not delete this organization, there is at least one user belongs to is",
+ "delete-team-warning-message": "Can not delete this team, there is at least one user belongs to is"
+}
diff --git a/i18n/ig.i18n.json b/i18n/ig.i18n.json
index 547a5a7f2..6f9dc48d6 100644
--- a/i18n/ig.i18n.json
+++ b/i18n/ig.i18n.json
@@ -358,7 +358,11 @@
"export-board-excel": "Export board to Excel",
"user-can-not-export-excel": "User can not export Excel",
"export-board-html": "Export board to HTML",
+ "export-card": "Export card",
+ "export-card-pdf": "Export card to PDF",
+ "user-can-not-export-card-to-pdf": "User can not export card to PDF",
"exportBoardPopup-title": "Export board",
+ "exportCardPopup-title": "Export card",
"sort": "Sort",
"sort-desc": "Click to Sort List",
"list-sort-by": "Sort the List By:",
@@ -664,6 +668,7 @@
"setListColorPopup-title": "Choose a color",
"assigned-by": "Assigned By",
"requested-by": "Requested By",
+ "card-sorting-by-number": "Card sorting by number",
"board-delete-notice": "Deleting is permanent. You will lose all lists, cards and actions associated with this board.",
"delete-board-confirm-popup": "All lists, cards, labels, and activities will be deleted and you won't be able to recover the board contents. There is no undo.",
"boardDeletePopup-title": "Delete Board?",
@@ -1037,5 +1042,18 @@
"rulesReportTitle": "Rules Report",
"copy-swimlane": "Copy Swimlane",
"copySwimlanePopup-title": "Copy Swimlane",
- "display-card-creator": "Display Card Creator"
-}
\ No newline at end of file
+ "display-card-creator": "Display Card Creator",
+ "wait-spinner": "Wait Spinner",
+ "Bounce": "Bounce Wait Spinner",
+ "Cube": "Cube Wait Spinner",
+ "Cube-Grid": "Cube-Grid Wait Spinner",
+ "Dot": "Dot Wait Spinner",
+ "Double-Bounce": "Double Bounce Wait Spinner",
+ "Rotateplane": "Rotateplane Wait Spinner",
+ "Scaleout": "Scaleout Wait Spinner",
+ "Wave": "Wave Wait Spinner",
+ "maximize-card": "Maximize Card",
+ "minimize-card": "Minimize Card",
+ "delete-org-warning-message": "Can not delete this organization, there is at least one user belongs to is",
+ "delete-team-warning-message": "Can not delete this team, there is at least one user belongs to is"
+}
diff --git a/i18n/it.i18n.json b/i18n/it.i18n.json
index 9ffcd4744..c812b08cb 100644
--- a/i18n/it.i18n.json
+++ b/i18n/it.i18n.json
@@ -82,8 +82,8 @@
"add-attachment": "Aggiungi allegato",
"add-board": "Aggiungi bacheca",
"add-card": "Aggiungi scheda",
- "add-card-to-top-of-list": "Add Card to Top of List",
- "add-card-to-bottom-of-list": "Add Card to Bottom of List",
+ "add-card-to-top-of-list": "Aggiungi Scheda in cima alla Lista",
+ "add-card-to-bottom-of-list": "Aggiungi Scheda in fondo alla Lista",
"add-swimlane": "Aggiungi swimlane",
"add-subtask": "Aggiungi sotto-compito",
"add-checklist": "Aggiungi Checklist",
@@ -195,11 +195,11 @@
"poker-forty": "40",
"poker-oneHundred": "100",
"poker-unsure": "?",
- "poker-finish": "Finish",
- "poker-result-votes": "Votes",
- "poker-result-who": "Who",
+ "poker-finish": "Fine",
+ "poker-result-votes": "Voti",
+ "poker-result-who": "Chi",
"poker-replay": "Replay",
- "set-estimation": "Set Estimation",
+ "set-estimation": "Imposta la stima",
"deletePokerPopup-title": "Delete planning poker?",
"poker-delete-pop": "Deleting is permanent. You will lose all actions associated with this planning poker.",
"cardDeletePopup-title": "Eliminare scheda?",
@@ -233,7 +233,7 @@
"close": "Chiudi",
"close-board": "Chiudi bacheca",
"close-board-pop": "Potrai ripristinare la bacheca cliccando sul tasto \"Archivio\" presente nell'intestazione della home.",
- "close-card": "Close Card",
+ "close-card": "Chiudi Scheda",
"color-black": "nero",
"color-blue": "blu",
"color-crimson": "Rosso cremisi",
@@ -358,7 +358,11 @@
"export-board-excel": "Esporta bacheca in Excel",
"user-can-not-export-excel": "L'utente non può effettuare l'esportazione in Excel",
"export-board-html": "Esporta bacheca in HTML",
+ "export-card": "Export card",
+ "export-card-pdf": "Export card to PDF",
+ "user-can-not-export-card-to-pdf": "User can not export card to PDF",
"exportBoardPopup-title": "Esporta bacheca",
+ "exportCardPopup-title": "Export card",
"sort": "Ordina",
"sort-desc": "Clicca per ordinare la lista",
"list-sort-by": "Ordina lista per:",
@@ -370,12 +374,12 @@
"list-label-short-sort": "(M)",
"filter": "Filtra",
"filter-cards": "Filtra schede o liste",
- "filter-dates-label": "Filter by date",
- "filter-no-due-date": "No due date",
- "filter-overdue": "Overdue",
- "filter-due-today": "Due today",
- "filter-due-this-week": "Due this week",
- "filter-due-tomorrow": "Due tomorrow",
+ "filter-dates-label": "Filtra per data",
+ "filter-no-due-date": "Senza data scadenza",
+ "filter-overdue": "Scaduta",
+ "filter-due-today": "Scade oggi",
+ "filter-due-this-week": "Scade questa settimana",
+ "filter-due-tomorrow": "Scade domani",
"list-filter-label": "Filtra lista per titolo",
"filter-clear": "Pulisci filtri",
"filter-labels-label": "Filtra secondo l'etichetta",
@@ -664,6 +668,7 @@
"setListColorPopup-title": "Scegli un colore",
"assigned-by": "Assegnato da",
"requested-by": "Richiesto da",
+ "card-sorting-by-number": "Card sorting by number",
"board-delete-notice": "L'eliminazione è permanente. Tutte le azioni, liste e schede associate a questa bacheca andranno perse.",
"delete-board-confirm-popup": "Tutte le liste, schede, etichette e azioni saranno rimosse e non sarai più in grado di recuperare il contenuto della bacheca. L'azione non è annullabile.",
"boardDeletePopup-title": "Eliminare la bacheca?",
@@ -1037,5 +1042,18 @@
"rulesReportTitle": "Rules Report",
"copy-swimlane": "Copy Swimlane",
"copySwimlanePopup-title": "Copy Swimlane",
- "display-card-creator": "Display Card Creator"
-}
\ No newline at end of file
+ "display-card-creator": "Display Card Creator",
+ "wait-spinner": "Wait Spinner",
+ "Bounce": "Bounce Wait Spinner",
+ "Cube": "Cube Wait Spinner",
+ "Cube-Grid": "Cube-Grid Wait Spinner",
+ "Dot": "Dot Wait Spinner",
+ "Double-Bounce": "Double Bounce Wait Spinner",
+ "Rotateplane": "Rotateplane Wait Spinner",
+ "Scaleout": "Scaleout Wait Spinner",
+ "Wave": "Wave Wait Spinner",
+ "maximize-card": "Maximize Card",
+ "minimize-card": "Minimize Card",
+ "delete-org-warning-message": "Can not delete this organization, there is at least one user belongs to is",
+ "delete-team-warning-message": "Can not delete this team, there is at least one user belongs to is"
+}
diff --git a/i18n/ja.i18n.json b/i18n/ja.i18n.json
index cc2e23d93..2a90efee6 100644
--- a/i18n/ja.i18n.json
+++ b/i18n/ja.i18n.json
@@ -358,7 +358,11 @@
"export-board-excel": "ボードをExcelにエクスポート",
"user-can-not-export-excel": "ユーザーはExcelにエクスポートできません ",
"export-board-html": "ボードをHTMLにエクスポート",
+ "export-card": "Export card",
+ "export-card-pdf": "Export card to PDF",
+ "user-can-not-export-card-to-pdf": "User can not export card to PDF",
"exportBoardPopup-title": "ボードのエクスポート",
+ "exportCardPopup-title": "Export card",
"sort": "並べ替え",
"sort-desc": "クリックでリストをソート",
"list-sort-by": "次によりリストを並べ替え:",
@@ -664,6 +668,7 @@
"setListColorPopup-title": "色を選択",
"assigned-by": "任命者",
"requested-by": "依頼者",
+ "card-sorting-by-number": "Card sorting by number",
"board-delete-notice": "永久に削除されます。このボードに関連するリスト、カード、アクションはすべて失われます。",
"delete-board-confirm-popup": "すべてのリスト、カード、ラベル、アクティビティは削除され、ボードの内容を元に戻すことができません。",
"boardDeletePopup-title": "ボードを削除しますか?",
@@ -1037,5 +1042,18 @@
"rulesReportTitle": "ルールレポート",
"copy-swimlane": "スイムレーンをコピーする",
"copySwimlanePopup-title": "スイムレーンをコピーする",
- "display-card-creator": "Display Card Creator"
-}
\ No newline at end of file
+ "display-card-creator": "Display Card Creator",
+ "wait-spinner": "Wait Spinner",
+ "Bounce": "Bounce Wait Spinner",
+ "Cube": "Cube Wait Spinner",
+ "Cube-Grid": "Cube-Grid Wait Spinner",
+ "Dot": "Dot Wait Spinner",
+ "Double-Bounce": "Double Bounce Wait Spinner",
+ "Rotateplane": "Rotateplane Wait Spinner",
+ "Scaleout": "Scaleout Wait Spinner",
+ "Wave": "Wave Wait Spinner",
+ "maximize-card": "Maximize Card",
+ "minimize-card": "Minimize Card",
+ "delete-org-warning-message": "Can not delete this organization, there is at least one user belongs to is",
+ "delete-team-warning-message": "Can not delete this team, there is at least one user belongs to is"
+}
diff --git a/i18n/ka.i18n.json b/i18n/ka.i18n.json
index 55256f824..658bcd764 100644
--- a/i18n/ka.i18n.json
+++ b/i18n/ka.i18n.json
@@ -358,7 +358,11 @@
"export-board-excel": "Export board to Excel",
"user-can-not-export-excel": "User can not export Excel",
"export-board-html": "Export board to HTML",
+ "export-card": "Export card",
+ "export-card-pdf": "Export card to PDF",
+ "user-can-not-export-card-to-pdf": "User can not export card to PDF",
"exportBoardPopup-title": "დაფის ექსპორტი",
+ "exportCardPopup-title": "Export card",
"sort": "Sort",
"sort-desc": "Click to Sort List",
"list-sort-by": "Sort the List By:",
@@ -664,6 +668,7 @@
"setListColorPopup-title": "Choose a color",
"assigned-by": "უფლებამოსილების გამცემი ",
"requested-by": "მომთხოვნი",
+ "card-sorting-by-number": "Card sorting by number",
"board-delete-notice": "წაშლის შემთხვევაში თქვენ დაკარგავთ ამ დაფასთან ასოცირებულ ყველა მონაცემს მათ შორის : ჩამონათვალს, ბარათებს და მოქმედებებს. ",
"delete-board-confirm-popup": "ყველა ჩამონათვალი, ბარათი, ნიშანი და აქტივობა წაიშლება და თქვენ ვეღარ შეძლებთ მის აღდგენას. ",
"boardDeletePopup-title": "წავშალოთ დაფა? ",
@@ -1037,5 +1042,18 @@
"rulesReportTitle": "Rules Report",
"copy-swimlane": "Copy Swimlane",
"copySwimlanePopup-title": "Copy Swimlane",
- "display-card-creator": "Display Card Creator"
-}
\ No newline at end of file
+ "display-card-creator": "Display Card Creator",
+ "wait-spinner": "Wait Spinner",
+ "Bounce": "Bounce Wait Spinner",
+ "Cube": "Cube Wait Spinner",
+ "Cube-Grid": "Cube-Grid Wait Spinner",
+ "Dot": "Dot Wait Spinner",
+ "Double-Bounce": "Double Bounce Wait Spinner",
+ "Rotateplane": "Rotateplane Wait Spinner",
+ "Scaleout": "Scaleout Wait Spinner",
+ "Wave": "Wave Wait Spinner",
+ "maximize-card": "Maximize Card",
+ "minimize-card": "Minimize Card",
+ "delete-org-warning-message": "Can not delete this organization, there is at least one user belongs to is",
+ "delete-team-warning-message": "Can not delete this team, there is at least one user belongs to is"
+}
diff --git a/i18n/km.i18n.json b/i18n/km.i18n.json
index e3c8c7dc8..1f46ae99d 100644
--- a/i18n/km.i18n.json
+++ b/i18n/km.i18n.json
@@ -358,7 +358,11 @@
"export-board-excel": "Export board to Excel",
"user-can-not-export-excel": "User can not export Excel",
"export-board-html": "Export board to HTML",
+ "export-card": "Export card",
+ "export-card-pdf": "Export card to PDF",
+ "user-can-not-export-card-to-pdf": "User can not export card to PDF",
"exportBoardPopup-title": "Export board",
+ "exportCardPopup-title": "Export card",
"sort": "Sort",
"sort-desc": "Click to Sort List",
"list-sort-by": "Sort the List By:",
@@ -664,6 +668,7 @@
"setListColorPopup-title": "Choose a color",
"assigned-by": "Assigned By",
"requested-by": "Requested By",
+ "card-sorting-by-number": "Card sorting by number",
"board-delete-notice": "Deleting is permanent. You will lose all lists, cards and actions associated with this board.",
"delete-board-confirm-popup": "All lists, cards, labels, and activities will be deleted and you won't be able to recover the board contents. There is no undo.",
"boardDeletePopup-title": "Delete Board?",
@@ -1037,5 +1042,18 @@
"rulesReportTitle": "Rules Report",
"copy-swimlane": "Copy Swimlane",
"copySwimlanePopup-title": "Copy Swimlane",
- "display-card-creator": "Display Card Creator"
-}
\ No newline at end of file
+ "display-card-creator": "Display Card Creator",
+ "wait-spinner": "Wait Spinner",
+ "Bounce": "Bounce Wait Spinner",
+ "Cube": "Cube Wait Spinner",
+ "Cube-Grid": "Cube-Grid Wait Spinner",
+ "Dot": "Dot Wait Spinner",
+ "Double-Bounce": "Double Bounce Wait Spinner",
+ "Rotateplane": "Rotateplane Wait Spinner",
+ "Scaleout": "Scaleout Wait Spinner",
+ "Wave": "Wave Wait Spinner",
+ "maximize-card": "Maximize Card",
+ "minimize-card": "Minimize Card",
+ "delete-org-warning-message": "Can not delete this organization, there is at least one user belongs to is",
+ "delete-team-warning-message": "Can not delete this team, there is at least one user belongs to is"
+}
diff --git a/i18n/ko.i18n.json b/i18n/ko.i18n.json
index 7ffb6d202..4769fa2d6 100644
--- a/i18n/ko.i18n.json
+++ b/i18n/ko.i18n.json
@@ -358,7 +358,11 @@
"export-board-excel": "Export board to Excel",
"user-can-not-export-excel": "User can not export Excel",
"export-board-html": "Export board to HTML",
+ "export-card": "Export card",
+ "export-card-pdf": "Export card to PDF",
+ "user-can-not-export-card-to-pdf": "User can not export card to PDF",
"exportBoardPopup-title": "보드 내보내기",
+ "exportCardPopup-title": "Export card",
"sort": "분류",
"sort-desc": "Click to Sort List",
"list-sort-by": "Sort the List By:",
@@ -664,6 +668,7 @@
"setListColorPopup-title": "색상 선택",
"assigned-by": "Assigned By",
"requested-by": "Requested By",
+ "card-sorting-by-number": "Card sorting by number",
"board-delete-notice": "Deleting is permanent. You will lose all lists, cards and actions associated with this board.",
"delete-board-confirm-popup": "모든 목록, 카드, 레이블 및 활동이 삭제되고 보드 내용을 복구할 수 없습니다. 실행 취소는 불가능합니다.",
"boardDeletePopup-title": "보드 삭제?",
@@ -1037,5 +1042,18 @@
"rulesReportTitle": "Rules Report",
"copy-swimlane": "Copy Swimlane",
"copySwimlanePopup-title": "Copy Swimlane",
- "display-card-creator": "Display Card Creator"
-}
\ No newline at end of file
+ "display-card-creator": "Display Card Creator",
+ "wait-spinner": "Wait Spinner",
+ "Bounce": "Bounce Wait Spinner",
+ "Cube": "Cube Wait Spinner",
+ "Cube-Grid": "Cube-Grid Wait Spinner",
+ "Dot": "Dot Wait Spinner",
+ "Double-Bounce": "Double Bounce Wait Spinner",
+ "Rotateplane": "Rotateplane Wait Spinner",
+ "Scaleout": "Scaleout Wait Spinner",
+ "Wave": "Wave Wait Spinner",
+ "maximize-card": "Maximize Card",
+ "minimize-card": "Minimize Card",
+ "delete-org-warning-message": "Can not delete this organization, there is at least one user belongs to is",
+ "delete-team-warning-message": "Can not delete this team, there is at least one user belongs to is"
+}
diff --git a/i18n/lt.i18n.json b/i18n/lt.i18n.json
index 5f2e4e0e5..9ef52fe39 100644
--- a/i18n/lt.i18n.json
+++ b/i18n/lt.i18n.json
@@ -358,7 +358,11 @@
"export-board-excel": "Export board to Excel",
"user-can-not-export-excel": "User can not export Excel",
"export-board-html": "Export board to HTML",
+ "export-card": "Export card",
+ "export-card-pdf": "Export card to PDF",
+ "user-can-not-export-card-to-pdf": "User can not export card to PDF",
"exportBoardPopup-title": "Export board",
+ "exportCardPopup-title": "Export card",
"sort": "Sort",
"sort-desc": "Click to Sort List",
"list-sort-by": "Sort the List By:",
@@ -664,6 +668,7 @@
"setListColorPopup-title": "Choose a color",
"assigned-by": "Assigned By",
"requested-by": "Requested By",
+ "card-sorting-by-number": "Card sorting by number",
"board-delete-notice": "Deleting is permanent. You will lose all lists, cards and actions associated with this board.",
"delete-board-confirm-popup": "All lists, cards, labels, and activities will be deleted and you won't be able to recover the board contents. There is no undo.",
"boardDeletePopup-title": "Delete Board?",
@@ -1037,5 +1042,18 @@
"rulesReportTitle": "Rules Report",
"copy-swimlane": "Copy Swimlane",
"copySwimlanePopup-title": "Copy Swimlane",
- "display-card-creator": "Display Card Creator"
-}
\ No newline at end of file
+ "display-card-creator": "Display Card Creator",
+ "wait-spinner": "Wait Spinner",
+ "Bounce": "Bounce Wait Spinner",
+ "Cube": "Cube Wait Spinner",
+ "Cube-Grid": "Cube-Grid Wait Spinner",
+ "Dot": "Dot Wait Spinner",
+ "Double-Bounce": "Double Bounce Wait Spinner",
+ "Rotateplane": "Rotateplane Wait Spinner",
+ "Scaleout": "Scaleout Wait Spinner",
+ "Wave": "Wave Wait Spinner",
+ "maximize-card": "Maximize Card",
+ "minimize-card": "Minimize Card",
+ "delete-org-warning-message": "Can not delete this organization, there is at least one user belongs to is",
+ "delete-team-warning-message": "Can not delete this team, there is at least one user belongs to is"
+}
diff --git a/i18n/lv.i18n.json b/i18n/lv.i18n.json
index 6281ca026..07cb5a148 100644
--- a/i18n/lv.i18n.json
+++ b/i18n/lv.i18n.json
@@ -358,7 +358,11 @@
"export-board-excel": "Export board to Excel",
"user-can-not-export-excel": "User can not export Excel",
"export-board-html": "Eksportēt dēli kā HTML",
+ "export-card": "Export card",
+ "export-card-pdf": "Export card to PDF",
+ "user-can-not-export-card-to-pdf": "User can not export card to PDF",
"exportBoardPopup-title": "Eksportēt dēli",
+ "exportCardPopup-title": "Export card",
"sort": "Kārtot",
"sort-desc": "Spiediet, lai kārtotu sarakstu",
"list-sort-by": "Kārtot sarakstu pēc:",
@@ -664,6 +668,7 @@
"setListColorPopup-title": "Izvēlieties krāsu",
"assigned-by": "Īpašnieks",
"requested-by": "Pieprasītājs",
+ "card-sorting-by-number": "Card sorting by number",
"board-delete-notice": "Dzēšana nav atsaucama. Zaudēsiet visus sarakstus, kartiņas un darbības šajā dēlī.",
"delete-board-confirm-popup": "Visi saraksti, kartiņas, birkas un darbības tiks dzēstas un dēli nevarēs atgūt. Darbība nav atsaucama.",
"boardDeletePopup-title": "Dzēst dēli?",
@@ -1037,5 +1042,18 @@
"rulesReportTitle": "Rules Report",
"copy-swimlane": "Copy Swimlane",
"copySwimlanePopup-title": "Copy Swimlane",
- "display-card-creator": "Display Card Creator"
-}
\ No newline at end of file
+ "display-card-creator": "Display Card Creator",
+ "wait-spinner": "Wait Spinner",
+ "Bounce": "Bounce Wait Spinner",
+ "Cube": "Cube Wait Spinner",
+ "Cube-Grid": "Cube-Grid Wait Spinner",
+ "Dot": "Dot Wait Spinner",
+ "Double-Bounce": "Double Bounce Wait Spinner",
+ "Rotateplane": "Rotateplane Wait Spinner",
+ "Scaleout": "Scaleout Wait Spinner",
+ "Wave": "Wave Wait Spinner",
+ "maximize-card": "Maximize Card",
+ "minimize-card": "Minimize Card",
+ "delete-org-warning-message": "Can not delete this organization, there is at least one user belongs to is",
+ "delete-team-warning-message": "Can not delete this team, there is at least one user belongs to is"
+}
diff --git a/i18n/mk.i18n.json b/i18n/mk.i18n.json
index 3f6f957c8..843bd806c 100644
--- a/i18n/mk.i18n.json
+++ b/i18n/mk.i18n.json
@@ -358,7 +358,11 @@
"export-board-excel": "Export board to Excel",
"user-can-not-export-excel": "User can not export Excel",
"export-board-html": "Export board to HTML",
+ "export-card": "Export card",
+ "export-card-pdf": "Export card to PDF",
+ "user-can-not-export-card-to-pdf": "User can not export card to PDF",
"exportBoardPopup-title": "Експортиране на Табло",
+ "exportCardPopup-title": "Export card",
"sort": "Sort",
"sort-desc": "Click to Sort List",
"list-sort-by": "Sort the List By:",
@@ -664,6 +668,7 @@
"setListColorPopup-title": "Choose a color",
"assigned-by": "Разпределена от",
"requested-by": "Поискан от",
+ "card-sorting-by-number": "Card sorting by number",
"board-delete-notice": "Deleting is permanent. You will lose all lists, cards and actions associated with this board.",
"delete-board-confirm-popup": "All lists, cards, labels, and activities will be deleted and you won't be able to recover the board contents. There is no undo.",
"boardDeletePopup-title": "Изтриване на Таблото?",
@@ -1037,5 +1042,18 @@
"rulesReportTitle": "Rules Report",
"copy-swimlane": "Copy Swimlane",
"copySwimlanePopup-title": "Copy Swimlane",
- "display-card-creator": "Display Card Creator"
-}
\ No newline at end of file
+ "display-card-creator": "Display Card Creator",
+ "wait-spinner": "Wait Spinner",
+ "Bounce": "Bounce Wait Spinner",
+ "Cube": "Cube Wait Spinner",
+ "Cube-Grid": "Cube-Grid Wait Spinner",
+ "Dot": "Dot Wait Spinner",
+ "Double-Bounce": "Double Bounce Wait Spinner",
+ "Rotateplane": "Rotateplane Wait Spinner",
+ "Scaleout": "Scaleout Wait Spinner",
+ "Wave": "Wave Wait Spinner",
+ "maximize-card": "Maximize Card",
+ "minimize-card": "Minimize Card",
+ "delete-org-warning-message": "Can not delete this organization, there is at least one user belongs to is",
+ "delete-team-warning-message": "Can not delete this team, there is at least one user belongs to is"
+}
diff --git a/i18n/mn.i18n.json b/i18n/mn.i18n.json
index d078184b5..00041ebec 100644
--- a/i18n/mn.i18n.json
+++ b/i18n/mn.i18n.json
@@ -358,7 +358,11 @@
"export-board-excel": "Export board to Excel",
"user-can-not-export-excel": "User can not export Excel",
"export-board-html": "Export board to HTML",
+ "export-card": "Export card",
+ "export-card-pdf": "Export card to PDF",
+ "user-can-not-export-card-to-pdf": "User can not export card to PDF",
"exportBoardPopup-title": "Export board",
+ "exportCardPopup-title": "Export card",
"sort": "Sort",
"sort-desc": "Click to Sort List",
"list-sort-by": "Sort the List By:",
@@ -664,6 +668,7 @@
"setListColorPopup-title": "Choose a color",
"assigned-by": "Assigned By",
"requested-by": "Requested By",
+ "card-sorting-by-number": "Card sorting by number",
"board-delete-notice": "Deleting is permanent. You will lose all lists, cards and actions associated with this board.",
"delete-board-confirm-popup": "All lists, cards, labels, and activities will be deleted and you won't be able to recover the board contents. There is no undo.",
"boardDeletePopup-title": "Delete Board?",
@@ -1037,5 +1042,18 @@
"rulesReportTitle": "Rules Report",
"copy-swimlane": "Copy Swimlane",
"copySwimlanePopup-title": "Copy Swimlane",
- "display-card-creator": "Display Card Creator"
-}
\ No newline at end of file
+ "display-card-creator": "Display Card Creator",
+ "wait-spinner": "Wait Spinner",
+ "Bounce": "Bounce Wait Spinner",
+ "Cube": "Cube Wait Spinner",
+ "Cube-Grid": "Cube-Grid Wait Spinner",
+ "Dot": "Dot Wait Spinner",
+ "Double-Bounce": "Double Bounce Wait Spinner",
+ "Rotateplane": "Rotateplane Wait Spinner",
+ "Scaleout": "Scaleout Wait Spinner",
+ "Wave": "Wave Wait Spinner",
+ "maximize-card": "Maximize Card",
+ "minimize-card": "Minimize Card",
+ "delete-org-warning-message": "Can not delete this organization, there is at least one user belongs to is",
+ "delete-team-warning-message": "Can not delete this team, there is at least one user belongs to is"
+}
diff --git a/i18n/nb.i18n.json b/i18n/nb.i18n.json
index c27a28fba..c8e5c5b28 100644
--- a/i18n/nb.i18n.json
+++ b/i18n/nb.i18n.json
@@ -82,8 +82,8 @@
"add-attachment": "Legg til Vedlegg",
"add-board": "Legg til Tavle",
"add-card": "Legg til Kort",
- "add-card-to-top-of-list": "Add Card to Top of List",
- "add-card-to-bottom-of-list": "Add Card to Bottom of List",
+ "add-card-to-top-of-list": "Legg til Kort på Toppen av Listen",
+ "add-card-to-bottom-of-list": "Legg til Kort på Bunnen av Listen",
"add-swimlane": "Legg til Svømmebane",
"add-subtask": "Legg til Underoppgave",
"add-checklist": "Legg til Sjekkliste",
@@ -133,7 +133,7 @@
"board-not-found": "Kunne ikke finne tavlen",
"board-private-info": "Denne tavlen vil være privat.",
"board-public-info": "Denne tavlen vil være offentlig.",
- "board-drag-drop-reorder-or-click-open": "Drag and drop to reorder board icons. Click board icon to open board.",
+ "board-drag-drop-reorder-or-click-open": "Klikk og Dra for å omorganisere ikoner på tavlen. Klikk på ikon for å åpne tavlen.",
"boardChangeColorPopup-title": "Ende tavlens bakgrunnsfarge",
"boardChangeTitlePopup-title": "Endre navn på tavlen",
"boardChangeVisibilityPopup-title": "Endre synlighet",
@@ -181,10 +181,10 @@
"vote-against": "mot",
"deleteVotePopup-title": "Slett stemme?",
"vote-delete-pop": "Sletting er permanent. Du vil miste alle aksjoner som har en sammenheng med denne stemmen.",
- "cardStartPlanningPokerPopup-title": "Start a Planning Poker",
- "card-edit-planning-poker": "Edit Planning Poker",
- "editPokerEndDatePopup-title": "Change Planning Poker vote end date",
- "poker-question": "Planning Poker",
+ "cardStartPlanningPokerPopup-title": "Start en Planpeker",
+ "card-edit-planning-poker": "Endre en Planpeker",
+ "editPokerEndDatePopup-title": "Endre Stemming og Dato for Planpeker ",
+ "poker-question": "Planpeker",
"poker-one": "1",
"poker-two": "2",
"poker-three": "3",
@@ -195,13 +195,13 @@
"poker-forty": "40",
"poker-oneHundred": "100",
"poker-unsure": "?",
- "poker-finish": "Finish",
- "poker-result-votes": "Votes",
- "poker-result-who": "Who",
- "poker-replay": "Replay",
- "set-estimation": "Set Estimation",
- "deletePokerPopup-title": "Delete planning poker?",
- "poker-delete-pop": "Deleting is permanent. You will lose all actions associated with this planning poker.",
+ "poker-finish": "Ferdig",
+ "poker-result-votes": "Stemmer",
+ "poker-result-who": "Hvem",
+ "poker-replay": "Spill på nytt",
+ "set-estimation": "Angi Estimat",
+ "deletePokerPopup-title": "Slett Planpeker",
+ "poker-delete-pop": "Sletting er permanent. Du vil miste alle aksjoner som er assosiert med denne planpekeren.",
"cardDeletePopup-title": "Slett kort?",
"cardDetailsActionsPopup-title": "Kort-handlinger",
"cardLabelsPopup-title": "Etiketter",
@@ -233,7 +233,7 @@
"close": "Lukk",
"close-board": "Lukk Tavle",
"close-board-pop": "Du vil ha muligheten til å gjenopprette Tavle ved å klikke på 'Arkiv'-knappen i hjem-menyen.",
- "close-card": "Close Card",
+ "close-card": "Lukk Kort",
"color-black": "svart",
"color-blue": "blå",
"color-crimson": "høyrød",
@@ -358,7 +358,11 @@
"export-board-excel": "Eksporter Tavle til Excel",
"user-can-not-export-excel": "Bruker kan ikke eksportere til Excel",
"export-board-html": "Eksporter tavle til HTML",
+ "export-card": "Export card",
+ "export-card-pdf": "Export card to PDF",
+ "user-can-not-export-card-to-pdf": "User can not export card to PDF",
"exportBoardPopup-title": "Eksporter tavle",
+ "exportCardPopup-title": "Export card",
"sort": "Sorter",
"sort-desc": "Klikk for sortering liste",
"list-sort-by": "Sorter liten etter:",
@@ -447,8 +451,8 @@
"set-color-list": "Sett farge",
"listActionPopup-title": "List aksjoner",
"settingsUserPopup-title": "Brukerinnstillinger",
- "settingsTeamPopup-title": "Team Settings",
- "settingsOrgPopup-title": "Organization Settings",
+ "settingsTeamPopup-title": "Innstillinger Team",
+ "settingsOrgPopup-title": "Innstillinger Organisasjon",
"swimlaneActionPopup-title": "Svømmebane-aksjoner",
"swimlaneAddPopup-title": "Legg til en Svømmebane under",
"listImportCardPopup-title": "Importer et Trello-kort",
@@ -664,6 +668,7 @@
"setListColorPopup-title": "Velg en farge",
"assigned-by": "Tildelt av",
"requested-by": "Forespurt av",
+ "card-sorting-by-number": "Kort sorter etter nummer",
"board-delete-notice": "Sletting er permanent. Du vil miste alle lister, kort og aksjoner assosiert med denne tavlen,",
"delete-board-confirm-popup": "Alle lister, kort, etiketter og aktiviteter vil bli slettet og du vil ikke kunne gjenopprette innholdet på tavlen. Det er ikke mulig å angre.",
"boardDeletePopup-title": "Slett Tavle?",
@@ -845,8 +850,8 @@
"act-duenow": "minnet om at nåværende forfallstid (__timeValue__) for __card__ er nå",
"act-atUserComment": "Du ble nevnt i [__board__] __list__/__card__",
"delete-user-confirm-popup": "Er du sikker på at du vil slette denne kontoen?",
- "delete-team-confirm-popup": "Are you sure you want to delete this team? There is no undo.",
- "delete-org-confirm-popup": "Are you sure you want to delete this organization? There is no undo.",
+ "delete-team-confirm-popup": "Er du sikker på at du vil slette Teamet? Du kan ikke angre.",
+ "delete-org-confirm-popup": "Er du sikker på at du vil slette denne Organisasjonen? Du kan ikke angre.",
"accounts-allowUserDelete": "Tillat brukere å slette egen konto",
"hide-minicard-label-text": "Skjul tekst på etikett",
"show-desktop-drag-handles": "Vis ikon for flytting av kort",
@@ -1037,5 +1042,18 @@
"rulesReportTitle": "Rapportering Regler",
"copy-swimlane": "Kopiér Svømmebane",
"copySwimlanePopup-title": "Kopiér Svømmebane",
- "display-card-creator": "Display Card Creator"
-}
\ No newline at end of file
+ "display-card-creator": "Vis etablerer av Kort",
+ "wait-spinner": "Ventehjul",
+ "Bounce": "Ventehjul - Hoppende",
+ "Cube": "Ventehjul - Kubisk",
+ "Cube-Grid": "Ventehjul - Kubisk med akser",
+ "Dot": "Ventehjul - Prikk",
+ "Double-Bounce": "Ventehjul - Dobbelt - Hoppende",
+ "Rotateplane": "Ventehjul - Rotasjonsplan",
+ "Scaleout": "Ventehjul - Utskaliering",
+ "Wave": "Ventehjul - Bølge",
+ "maximize-card": "Maksimer Kort",
+ "minimize-card": "Minimer Kort",
+ "delete-org-warning-message": "Can not delete this organization, there is at least one user belongs to is",
+ "delete-team-warning-message": "Can not delete this team, there is at least one user belongs to is"
+}
diff --git a/i18n/nl.i18n.json b/i18n/nl.i18n.json
index aca15cd31..69f6f8e3e 100644
--- a/i18n/nl.i18n.json
+++ b/i18n/nl.i18n.json
@@ -82,8 +82,8 @@
"add-attachment": "Bijlage Toevoegen",
"add-board": "Bord Toevoegen",
"add-card": "Kaart Toevoegen",
- "add-card-to-top-of-list": "Add Card to Top of List",
- "add-card-to-bottom-of-list": "Add Card to Bottom of List",
+ "add-card-to-top-of-list": "Voeg Kaart Boven Aan de Lijst Toe",
+ "add-card-to-bottom-of-list": "Voeg Kaart Onder Aan de Lijst Toe",
"add-swimlane": "Swimlane Toevoegen",
"add-subtask": "Subtaak Toevoegen",
"add-checklist": "Checklist toevoegen",
@@ -133,7 +133,7 @@
"board-not-found": "Bord is niet gevonden",
"board-private-info": "Dit bord is nu privé.",
"board-public-info": "Dit bord is nu openbaar.",
- "board-drag-drop-reorder-or-click-open": "Drag and drop to reorder board icons. Click board icon to open board.",
+ "board-drag-drop-reorder-or-click-open": "Sleep en verplaats om iconen te herordenen. Klik bord-icoon om het bord te openen,",
"boardChangeColorPopup-title": "Verander achtergrond van bord",
"boardChangeTitlePopup-title": "Hernoem bord",
"boardChangeVisibilityPopup-title": "Verander zichtbaarheid",
@@ -233,7 +233,7 @@
"close": "Sluiten",
"close-board": "Sluit bord",
"close-board-pop": "Je kunt het bord terughalen door de \"Archief\" knop te klikken in de menubalk \"Mijn Borden\".",
- "close-card": "Close Card",
+ "close-card": "Sluit Kaart",
"color-black": "zwart",
"color-blue": "blauw",
"color-crimson": "karmijn",
@@ -358,7 +358,11 @@
"export-board-excel": "Exporteer bord naar Excel",
"user-can-not-export-excel": "Gebruiker kan niet exporteren naar Excel",
"export-board-html": "Exporteer bord naar HTML",
+ "export-card": "Exporteer kaart",
+ "export-card-pdf": "Exporteer kaart naar PDF",
+ "user-can-not-export-card-to-pdf": "Gebruiker kan kaart niet naar PDF exporteren",
"exportBoardPopup-title": "Exporteer bord",
+ "exportCardPopup-title": "Exporteer kaart",
"sort": "Sorteer",
"sort-desc": "Klik om lijst te sorteren",
"list-sort-by": "Sorteer lijst op",
@@ -447,8 +451,8 @@
"set-color-list": "Wijzig kleur in",
"listActionPopup-title": "Lijst acties",
"settingsUserPopup-title": "Gebruiker Instellingen",
- "settingsTeamPopup-title": "Team Settings",
- "settingsOrgPopup-title": "Organization Settings",
+ "settingsTeamPopup-title": "Team Instellingen",
+ "settingsOrgPopup-title": "Organisatie Instellingen",
"swimlaneActionPopup-title": "Swimlane handelingen",
"swimlaneAddPopup-title": "Voeg hieronder een Swimlane toe",
"listImportCardPopup-title": "Importeer een Trello kaart",
@@ -664,6 +668,7 @@
"setListColorPopup-title": "Kies een kleur",
"assigned-by": "Toegewezen door",
"requested-by": "Aangevraagd door",
+ "card-sorting-by-number": "Kaarten sorteren op nummer",
"board-delete-notice": "Verwijdering kan niet ongedaan gemaakt worden. Je raakt alle met dit bord gerelateerde lijsten, kaarten en acties kwijt.",
"delete-board-confirm-popup": "Alle lijsten, kaarten, labels en activiteiten zullen worden verwijderd en je kunt de bordinhoud niet terughalen. Er is geen herstelmogelijkheid. ",
"boardDeletePopup-title": "Bord verwijderen?",
@@ -845,8 +850,8 @@
"act-duenow": "wil je herinneren aan het vandaag verlopen van de huidige vervaldatum (__timeValue__) van __card__ ",
"act-atUserComment": "Je werd genoemd in [__board__] __list__/__card__",
"delete-user-confirm-popup": "Weet je zeker dat je dit account wilt verwijderen? Er is geen herstelmogelijkheid.",
- "delete-team-confirm-popup": "Are you sure you want to delete this team? There is no undo.",
- "delete-org-confirm-popup": "Are you sure you want to delete this organization? There is no undo.",
+ "delete-team-confirm-popup": "Weet je zeker dat je dit team wilt verwijderen? Er is geen herstelmogelijkheid.",
+ "delete-org-confirm-popup": "Weet je zeker dat je deze organisatie wilt verwijderen? Er is geen herstelmogelijkheid.",
"accounts-allowUserDelete": "Sta gebruikers toe om hun eigen account te verwijderen",
"hide-minicard-label-text": "Verberg minikaart labeltekst",
"show-desktop-drag-handles": "Toon sleep gereedschap op werkblad",
@@ -857,8 +862,8 @@
"new": "Nieuw",
"editOrgPopup-title": "Wijzig organisatie",
"newOrgPopup-title": "Nieuwe organisatie",
- "editTeamPopup-title": "Wijzig team",
- "newTeamPopup-title": "Nieuw team",
+ "editTeamPopup-title": "Wijzig Team",
+ "newTeamPopup-title": "Nieuw Team",
"editUserPopup-title": "Wijzig gebruiker",
"newUserPopup-title": "Nieuwe gebruiker",
"notifications": "Meldingen",
@@ -1037,5 +1042,18 @@
"rulesReportTitle": "Regels Rapportage",
"copy-swimlane": "Kopieer Swimlane",
"copySwimlanePopup-title": "Kopieer Swimlane",
- "display-card-creator": "Toon Aanmaker Kaart"
-}
\ No newline at end of file
+ "display-card-creator": "Toon Aanmaker Kaart",
+ "wait-spinner": "Wacht Spinner",
+ "Bounce": "Stuiterende Wacht Spinner",
+ "Cube": "Kubus Wacht Spinner",
+ "Cube-Grid": "Raster-Kubus Wacht Spinner",
+ "Dot": "Stip Wacht Spinner",
+ "Double-Bounce": "Dubbel Stuiterende Wacht Spinner",
+ "Rotateplane": "Roterend Vlak Wacht Spinner",
+ "Scaleout": "Vergrotende Wacht Spinner",
+ "Wave": "Golvende Wacht Spinner",
+ "maximize-card": "Maximaliseer Kaart",
+ "minimize-card": "Minimaliseer Kaart",
+ "delete-org-warning-message": "Can not delete this organization, there is at least one user belongs to is",
+ "delete-team-warning-message": "Can not delete this team, there is at least one user belongs to is"
+}
diff --git a/i18n/oc.i18n.json b/i18n/oc.i18n.json
index 03ae1f12d..9a6ff9260 100644
--- a/i18n/oc.i18n.json
+++ b/i18n/oc.i18n.json
@@ -358,7 +358,11 @@
"export-board-excel": "Export board to Excel",
"user-can-not-export-excel": "User can not export Excel",
"export-board-html": "Export board to HTML",
+ "export-card": "Export card",
+ "export-card-pdf": "Export card to PDF",
+ "user-can-not-export-card-to-pdf": "User can not export card to PDF",
"exportBoardPopup-title": "Exportar lo tablèu",
+ "exportCardPopup-title": "Export card",
"sort": "Sort",
"sort-desc": "Click to Sort List",
"list-sort-by": "Sort the List By:",
@@ -664,6 +668,7 @@
"setListColorPopup-title": "Causir una color",
"assigned-by": "Assigned By",
"requested-by": "Requested By",
+ "card-sorting-by-number": "Card sorting by number",
"board-delete-notice": "Deleting is permanent. You will lose all lists, cards and actions associated with this board.",
"delete-board-confirm-popup": "All lists, cards, labels, and activities will be deleted and you won't be able to recover the board contents. There is no undo.",
"boardDeletePopup-title": "Suprimir lo tablèu ?",
@@ -1037,5 +1042,18 @@
"rulesReportTitle": "Rules Report",
"copy-swimlane": "Copy Swimlane",
"copySwimlanePopup-title": "Copy Swimlane",
- "display-card-creator": "Display Card Creator"
-}
\ No newline at end of file
+ "display-card-creator": "Display Card Creator",
+ "wait-spinner": "Wait Spinner",
+ "Bounce": "Bounce Wait Spinner",
+ "Cube": "Cube Wait Spinner",
+ "Cube-Grid": "Cube-Grid Wait Spinner",
+ "Dot": "Dot Wait Spinner",
+ "Double-Bounce": "Double Bounce Wait Spinner",
+ "Rotateplane": "Rotateplane Wait Spinner",
+ "Scaleout": "Scaleout Wait Spinner",
+ "Wave": "Wave Wait Spinner",
+ "maximize-card": "Maximize Card",
+ "minimize-card": "Minimize Card",
+ "delete-org-warning-message": "Can not delete this organization, there is at least one user belongs to is",
+ "delete-team-warning-message": "Can not delete this team, there is at least one user belongs to is"
+}
diff --git a/i18n/pa.i18n.json b/i18n/pa.i18n.json
index 5f2e4e0e5..9ef52fe39 100644
--- a/i18n/pa.i18n.json
+++ b/i18n/pa.i18n.json
@@ -358,7 +358,11 @@
"export-board-excel": "Export board to Excel",
"user-can-not-export-excel": "User can not export Excel",
"export-board-html": "Export board to HTML",
+ "export-card": "Export card",
+ "export-card-pdf": "Export card to PDF",
+ "user-can-not-export-card-to-pdf": "User can not export card to PDF",
"exportBoardPopup-title": "Export board",
+ "exportCardPopup-title": "Export card",
"sort": "Sort",
"sort-desc": "Click to Sort List",
"list-sort-by": "Sort the List By:",
@@ -664,6 +668,7 @@
"setListColorPopup-title": "Choose a color",
"assigned-by": "Assigned By",
"requested-by": "Requested By",
+ "card-sorting-by-number": "Card sorting by number",
"board-delete-notice": "Deleting is permanent. You will lose all lists, cards and actions associated with this board.",
"delete-board-confirm-popup": "All lists, cards, labels, and activities will be deleted and you won't be able to recover the board contents. There is no undo.",
"boardDeletePopup-title": "Delete Board?",
@@ -1037,5 +1042,18 @@
"rulesReportTitle": "Rules Report",
"copy-swimlane": "Copy Swimlane",
"copySwimlanePopup-title": "Copy Swimlane",
- "display-card-creator": "Display Card Creator"
-}
\ No newline at end of file
+ "display-card-creator": "Display Card Creator",
+ "wait-spinner": "Wait Spinner",
+ "Bounce": "Bounce Wait Spinner",
+ "Cube": "Cube Wait Spinner",
+ "Cube-Grid": "Cube-Grid Wait Spinner",
+ "Dot": "Dot Wait Spinner",
+ "Double-Bounce": "Double Bounce Wait Spinner",
+ "Rotateplane": "Rotateplane Wait Spinner",
+ "Scaleout": "Scaleout Wait Spinner",
+ "Wave": "Wave Wait Spinner",
+ "maximize-card": "Maximize Card",
+ "minimize-card": "Minimize Card",
+ "delete-org-warning-message": "Can not delete this organization, there is at least one user belongs to is",
+ "delete-team-warning-message": "Can not delete this team, there is at least one user belongs to is"
+}
diff --git a/i18n/pl.i18n.json b/i18n/pl.i18n.json
index 0b9425c7f..b192553fb 100644
--- a/i18n/pl.i18n.json
+++ b/i18n/pl.i18n.json
@@ -358,7 +358,11 @@
"export-board-excel": "Eksportuj tablicę w formacie Excel",
"user-can-not-export-excel": "Użytkownik nie może wyeksportować tablicy w formacie Excel",
"export-board-html": "Eksportuj tablicę do HTML",
+ "export-card": "Export card",
+ "export-card-pdf": "Export card to PDF",
+ "user-can-not-export-card-to-pdf": "User can not export card to PDF",
"exportBoardPopup-title": "Eksportuj tablicę",
+ "exportCardPopup-title": "Export card",
"sort": "Sortuj",
"sort-desc": "Kliknij by sortować listę",
"list-sort-by": "Sortuj listę przez:",
@@ -664,6 +668,7 @@
"setListColorPopup-title": "Wybierz barwę",
"assigned-by": "Przypisane przez",
"requested-by": "Zlecone przez",
+ "card-sorting-by-number": "Card sorting by number",
"board-delete-notice": "Usunięcie jest nieodwracalne. Stracisz wszystkie listy, karty oraz reguły przypisane do tej tablicy.",
"delete-board-confirm-popup": "Wszystkie listy, etykiety oraz aktywności zostaną usunięte i nie będziesz w stanie przywrócić zawartości tablicy. Tego nie da się cofnąć.",
"boardDeletePopup-title": "Usunąć tablicę?",
@@ -1037,5 +1042,18 @@
"rulesReportTitle": "Wykaz reguł",
"copy-swimlane": "Skopiuj ścieżkę",
"copySwimlanePopup-title": "Kopiowanie ścieżki",
- "display-card-creator": "Display Card Creator"
-}
\ No newline at end of file
+ "display-card-creator": "Display Card Creator",
+ "wait-spinner": "Wait Spinner",
+ "Bounce": "Bounce Wait Spinner",
+ "Cube": "Cube Wait Spinner",
+ "Cube-Grid": "Cube-Grid Wait Spinner",
+ "Dot": "Dot Wait Spinner",
+ "Double-Bounce": "Double Bounce Wait Spinner",
+ "Rotateplane": "Rotateplane Wait Spinner",
+ "Scaleout": "Scaleout Wait Spinner",
+ "Wave": "Wave Wait Spinner",
+ "maximize-card": "Maximize Card",
+ "minimize-card": "Minimize Card",
+ "delete-org-warning-message": "Can not delete this organization, there is at least one user belongs to is",
+ "delete-team-warning-message": "Can not delete this team, there is at least one user belongs to is"
+}
diff --git a/i18n/pt-BR.i18n.json b/i18n/pt-BR.i18n.json
index c401858b2..2b3681b37 100644
--- a/i18n/pt-BR.i18n.json
+++ b/i18n/pt-BR.i18n.json
@@ -82,8 +82,8 @@
"add-attachment": "Adicionar Anexos",
"add-board": "Adicionar Quadro",
"add-card": "Adicionar Cartão",
- "add-card-to-top-of-list": "Add Card to Top of List",
- "add-card-to-bottom-of-list": "Add Card to Bottom of List",
+ "add-card-to-top-of-list": "Adicionar Cartão no Topo da Lista",
+ "add-card-to-bottom-of-list": "Adicionar Cartão no Final da Lista",
"add-swimlane": "Adicionar Raia",
"add-subtask": "Adicionar subtarefa",
"add-checklist": "Adicionar lista de verificação",
@@ -133,7 +133,7 @@
"board-not-found": "Quadro não encontrado",
"board-private-info": "Este quadro será privado.",
"board-public-info": "Este quadro será público.",
- "board-drag-drop-reorder-or-click-open": "Drag and drop to reorder board icons. Click board icon to open board.",
+ "board-drag-drop-reorder-or-click-open": "Arraste e solte para reordenar os ícones do quadro. Clique no ícone do quadro para abri-lo. ",
"boardChangeColorPopup-title": "Alterar Tela de Fundo",
"boardChangeTitlePopup-title": "Renomear Quadro",
"boardChangeVisibilityPopup-title": "Alterar Visibilidade",
@@ -233,7 +233,7 @@
"close": "Fechar",
"close-board": "Fechar Quadro",
"close-board-pop": "Você será capaz de restaurar o quadro clicando no botão “Arquivo morto” a partir do cabeçalho do Início.",
- "close-card": "Close Card",
+ "close-card": "Fechar Cartão",
"color-black": "preto",
"color-blue": "azul",
"color-crimson": "carmesim",
@@ -358,7 +358,11 @@
"export-board-excel": "Exportar quadro para Excel",
"user-can-not-export-excel": "Usuário não pode exportar Excel",
"export-board-html": "Exportar quadro para HTML",
+ "export-card": "Exportar cartão",
+ "export-card-pdf": "Exportar cartão para PDF",
+ "user-can-not-export-card-to-pdf": "Usuário não pode exportar cartão para PDF",
"exportBoardPopup-title": "Exportar quadro",
+ "exportCardPopup-title": "Exportar cartão",
"sort": "Ordenar",
"sort-desc": "Clique para Ordenar Lista",
"list-sort-by": "Ordenar a Lista por:",
@@ -447,8 +451,8 @@
"set-color-list": "Definir Cor",
"listActionPopup-title": "Listar Ações",
"settingsUserPopup-title": "Configurações do usuário",
- "settingsTeamPopup-title": "Team Settings",
- "settingsOrgPopup-title": "Organization Settings",
+ "settingsTeamPopup-title": "Configurações do Time",
+ "settingsOrgPopup-title": "Configurações da Organização",
"swimlaneActionPopup-title": "Ações de Raia",
"swimlaneAddPopup-title": "Adicionar uma Raia abaixo",
"listImportCardPopup-title": "Importe um cartão do Trello",
@@ -664,6 +668,7 @@
"setListColorPopup-title": "Escolha uma cor",
"assigned-by": "Atribuído por",
"requested-by": "Solicitado por",
+ "card-sorting-by-number": "Ordenar cartões por número",
"board-delete-notice": "Excluir é permanente. Você perderá todas as listas, cartões e ações associados nesse quadro.",
"delete-board-confirm-popup": "Todas as listas, cartões, etiquetas e atividades serão excluídas e você não poderá recuperar o conteúdo do quadro. Não há como desfazer.",
"boardDeletePopup-title": "Excluir quadro?",
@@ -845,8 +850,8 @@
"act-duenow": "está lembrando que o prazo final (__timeValue__) do __card__ é agora",
"act-atUserComment": "Você foi mencionado no [__board__] __list__/__card__",
"delete-user-confirm-popup": "Você realmente quer apagar esta conta? Não há como desfazer.",
- "delete-team-confirm-popup": "Are you sure you want to delete this team? There is no undo.",
- "delete-org-confirm-popup": "Are you sure you want to delete this organization? There is no undo.",
+ "delete-team-confirm-popup": "Você tem certeza que quer excluir este time? Não há como desfazer.",
+ "delete-org-confirm-popup": "Você tem certeza que quer excluir esta organização? Não há como desfazer.",
"accounts-allowUserDelete": "Permitir que usuários apaguem a própria conta",
"hide-minicard-label-text": "Esconder rótulo da etiqueta do mini cartão",
"show-desktop-drag-handles": "Mostrar alças de arrasto da área de trabalho",
@@ -1037,5 +1042,18 @@
"rulesReportTitle": "Regras de Relatório",
"copy-swimlane": "Copiar Raia",
"copySwimlanePopup-title": "Copiar Raia",
- "display-card-creator": "Exibir Criador do Cartão"
-}
\ No newline at end of file
+ "display-card-creator": "Exibir Criador do Cartão",
+ "wait-spinner": "Aguarde o carregamento",
+ "Bounce": "Bounce Wait Spinner",
+ "Cube": "Cube Wait Spinner",
+ "Cube-Grid": "Cube-Grid Wait Spinner",
+ "Dot": "Dot Wait Spinner",
+ "Double-Bounce": "Double Bounce Wait Spinner",
+ "Rotateplane": "Rotateplane Wait Spinner",
+ "Scaleout": "Scaleout Wait Spinner",
+ "Wave": "Wave Wait Spinner",
+ "maximize-card": "Maximizar Cartão",
+ "minimize-card": "Minimizar Cartão",
+ "delete-org-warning-message": "Can not delete this organization, there is at least one user belongs to is",
+ "delete-team-warning-message": "Can not delete this team, there is at least one user belongs to is"
+}
diff --git a/i18n/pt.i18n.json b/i18n/pt.i18n.json
index 6757c30af..f0f50a866 100644
--- a/i18n/pt.i18n.json
+++ b/i18n/pt.i18n.json
@@ -358,7 +358,11 @@
"export-board-excel": "Exportar quadro para Excel",
"user-can-not-export-excel": "Utilizador não pode exportar Excel",
"export-board-html": "Exportar quadro para HTML",
+ "export-card": "Export card",
+ "export-card-pdf": "Export card to PDF",
+ "user-can-not-export-card-to-pdf": "User can not export card to PDF",
"exportBoardPopup-title": "Exportar quadro",
+ "exportCardPopup-title": "Export card",
"sort": "Ordenar",
"sort-desc": "Clique para ordenar a Lista",
"list-sort-by": "Ordenar a Lista por:",
@@ -664,6 +668,7 @@
"setListColorPopup-title": "Escolha uma cor",
"assigned-by": "Atribuído Por",
"requested-by": "Solicitado Por",
+ "card-sorting-by-number": "Card sorting by number",
"board-delete-notice": "Apagar é permanente. Irá perder todas as listas, cartões e acções associadas a este quadro.",
"delete-board-confirm-popup": "Todas as listas, cartões, etiquetas e atividades serão apagadas e não poderá recuperar o conteúdo do quadro. Não é reversível.",
"boardDeletePopup-title": "Apagar Quadro?",
@@ -1037,5 +1042,18 @@
"rulesReportTitle": "Relatório de Regras",
"copy-swimlane": "Copiar Pista",
"copySwimlanePopup-title": "Copiar Pista",
- "display-card-creator": "Display Card Creator"
-}
\ No newline at end of file
+ "display-card-creator": "Display Card Creator",
+ "wait-spinner": "Wait Spinner",
+ "Bounce": "Bounce Wait Spinner",
+ "Cube": "Cube Wait Spinner",
+ "Cube-Grid": "Cube-Grid Wait Spinner",
+ "Dot": "Dot Wait Spinner",
+ "Double-Bounce": "Double Bounce Wait Spinner",
+ "Rotateplane": "Rotateplane Wait Spinner",
+ "Scaleout": "Scaleout Wait Spinner",
+ "Wave": "Wave Wait Spinner",
+ "maximize-card": "Maximize Card",
+ "minimize-card": "Minimize Card",
+ "delete-org-warning-message": "Can not delete this organization, there is at least one user belongs to is",
+ "delete-team-warning-message": "Can not delete this team, there is at least one user belongs to is"
+}
diff --git a/i18n/ro.i18n.json b/i18n/ro.i18n.json
index 325b67733..7bb11cbfe 100644
--- a/i18n/ro.i18n.json
+++ b/i18n/ro.i18n.json
@@ -358,7 +358,11 @@
"export-board-excel": "Export board to Excel",
"user-can-not-export-excel": "User can not export Excel",
"export-board-html": "Export board to HTML",
+ "export-card": "Export card",
+ "export-card-pdf": "Export card to PDF",
+ "user-can-not-export-card-to-pdf": "User can not export card to PDF",
"exportBoardPopup-title": "Export board",
+ "exportCardPopup-title": "Export card",
"sort": "Sort",
"sort-desc": "Click to Sort List",
"list-sort-by": "Sort the List By:",
@@ -664,6 +668,7 @@
"setListColorPopup-title": "Choose a color",
"assigned-by": "Assigned By",
"requested-by": "Requested By",
+ "card-sorting-by-number": "Card sorting by number",
"board-delete-notice": "Deleting is permanent. You will lose all lists, cards and actions associated with this board.",
"delete-board-confirm-popup": "All lists, cards, labels, and activities will be deleted and you won't be able to recover the board contents. There is no undo.",
"boardDeletePopup-title": "Delete Board?",
@@ -1037,5 +1042,18 @@
"rulesReportTitle": "Rules Report",
"copy-swimlane": "Copy Swimlane",
"copySwimlanePopup-title": "Copy Swimlane",
- "display-card-creator": "Display Card Creator"
-}
\ No newline at end of file
+ "display-card-creator": "Display Card Creator",
+ "wait-spinner": "Wait Spinner",
+ "Bounce": "Bounce Wait Spinner",
+ "Cube": "Cube Wait Spinner",
+ "Cube-Grid": "Cube-Grid Wait Spinner",
+ "Dot": "Dot Wait Spinner",
+ "Double-Bounce": "Double Bounce Wait Spinner",
+ "Rotateplane": "Rotateplane Wait Spinner",
+ "Scaleout": "Scaleout Wait Spinner",
+ "Wave": "Wave Wait Spinner",
+ "maximize-card": "Maximize Card",
+ "minimize-card": "Minimize Card",
+ "delete-org-warning-message": "Can not delete this organization, there is at least one user belongs to is",
+ "delete-team-warning-message": "Can not delete this team, there is at least one user belongs to is"
+}
diff --git a/i18n/ru.i18n.json b/i18n/ru.i18n.json
index 2ae26a30a..69d4c1468 100644
--- a/i18n/ru.i18n.json
+++ b/i18n/ru.i18n.json
@@ -82,8 +82,8 @@
"add-attachment": "Добавить вложение",
"add-board": "Добавить доску",
"add-card": "Добавить карточку",
- "add-card-to-top-of-list": "Add Card to Top of List",
- "add-card-to-bottom-of-list": "Add Card to Bottom of List",
+ "add-card-to-top-of-list": "Добавить карточку в начало списка",
+ "add-card-to-bottom-of-list": "Добавить карточку в конец списка",
"add-swimlane": "Добавить дорожку",
"add-subtask": "Добавить подзадачу",
"add-checklist": "Добавить контрольный список",
@@ -133,7 +133,7 @@
"board-not-found": "Доска не найдена",
"board-private-info": "Это доска будет частной.",
"board-public-info": "Эта доска будет доступной всем.",
- "board-drag-drop-reorder-or-click-open": "Drag and drop to reorder board icons. Click board icon to open board.",
+ "board-drag-drop-reorder-or-click-open": "Перетаскивайте, чтобы упорядочить значки доски. Нажмите значок доски чтобы открыть доску.",
"boardChangeColorPopup-title": "Изменить фон доски",
"boardChangeTitlePopup-title": "Переименовать доску",
"boardChangeVisibilityPopup-title": "Изменить настройки видимости",
@@ -181,10 +181,10 @@
"vote-against": "против",
"deleteVotePopup-title": "Удалить голосование?",
"vote-delete-pop": "Это действие невозможно будет отменить. Все связанные с голосованием действия будут потеряны.",
- "cardStartPlanningPokerPopup-title": "Start a Planning Poker",
- "card-edit-planning-poker": "Edit Planning Poker",
- "editPokerEndDatePopup-title": "Change Planning Poker vote end date",
- "poker-question": "Planning Poker",
+ "cardStartPlanningPokerPopup-title": "Начать покер планирования",
+ "card-edit-planning-poker": "Редактировать покер планирования.",
+ "editPokerEndDatePopup-title": "Изменить дату окончания голосования покера планирования.",
+ "poker-question": "Покер планирования",
"poker-one": "1",
"poker-two": "2",
"poker-three": "3",
@@ -195,13 +195,13 @@
"poker-forty": "40",
"poker-oneHundred": "100",
"poker-unsure": "?",
- "poker-finish": "Finish",
- "poker-result-votes": "Votes",
- "poker-result-who": "Who",
- "poker-replay": "Replay",
- "set-estimation": "Set Estimation",
- "deletePokerPopup-title": "Delete planning poker?",
- "poker-delete-pop": "Deleting is permanent. You will lose all actions associated with this planning poker.",
+ "poker-finish": "Закончить",
+ "poker-result-votes": "Голоса",
+ "poker-result-who": "Кто",
+ "poker-replay": "Переиграть",
+ "set-estimation": "Задать оценку",
+ "deletePokerPopup-title": "Удалить покер планирования?",
+ "poker-delete-pop": "Удаление необратимо. Вы потеряете действия ассоциированные с этим покером планирования.",
"cardDeletePopup-title": "Удалить карточку?",
"cardDetailsActionsPopup-title": "Действия в карточке",
"cardLabelsPopup-title": "Метки",
@@ -233,7 +233,7 @@
"close": "Закрыть",
"close-board": "Закрыть доску",
"close-board-pop": "Вы сможете восстановить доску, нажав \"Архив\" в заголовке домашней страницы.",
- "close-card": "Close Card",
+ "close-card": "Закрыть карточку",
"color-black": "черный",
"color-blue": "синий",
"color-crimson": "малиновый",
@@ -358,7 +358,11 @@
"export-board-excel": "Экспортировать доску в Excel",
"user-can-not-export-excel": "Пользователь не может экспортировать в Excel",
"export-board-html": "Экспортировать доску в HTML",
+ "export-card": "Export card",
+ "export-card-pdf": "Export card to PDF",
+ "user-can-not-export-card-to-pdf": "User can not export card to PDF",
"exportBoardPopup-title": "Экспортировать доску",
+ "exportCardPopup-title": "Export card",
"sort": "Сортировать",
"sort-desc": "Нажмите, чтобы отсортировать список",
"list-sort-by": "Сортировать список по:",
@@ -447,8 +451,8 @@
"set-color-list": "Задать цвет",
"listActionPopup-title": "Список действий",
"settingsUserPopup-title": "Пользовательские настройки",
- "settingsTeamPopup-title": "Team Settings",
- "settingsOrgPopup-title": "Organization Settings",
+ "settingsTeamPopup-title": "Настройки команды",
+ "settingsOrgPopup-title": "Настройки организации",
"swimlaneActionPopup-title": "Действия с дорожкой",
"swimlaneAddPopup-title": "Добавить дорожку ниже",
"listImportCardPopup-title": "Импортировать Trello карточку",
@@ -664,6 +668,7 @@
"setListColorPopup-title": "Выберите цвет",
"assigned-by": "Поручил",
"requested-by": "Запросил",
+ "card-sorting-by-number": "Сортировка карточек по номеру",
"board-delete-notice": "Удаление является постоянным. Вы потеряете все списки, карты и действия, связанные с этой доской.",
"delete-board-confirm-popup": "Все списки, карточки, метки и действия будут удалены, и вы не сможете восстановить содержимое доски. Отменить нельзя.",
"boardDeletePopup-title": "Удалить доску?",
@@ -845,8 +850,8 @@
"act-duenow": "напомнил, что срок выполнения (__timeValue__) карточки __card__ — это уже сейчас",
"act-atUserComment": "Вас упомянули в [__board__] __list__/__card__",
"delete-user-confirm-popup": "Вы уверены, что хотите удалить аккаунт? Данное действие необратимо.",
- "delete-team-confirm-popup": "Are you sure you want to delete this team? There is no undo.",
- "delete-org-confirm-popup": "Are you sure you want to delete this organization? There is no undo.",
+ "delete-team-confirm-popup": "Вы уверены, что хотите удалить эту команду? Эту операцию нельзя отменить.",
+ "delete-org-confirm-popup": "Вы уверены, что хотите удалить эту организацию? Эту операцию нельзя отменить.",
"accounts-allowUserDelete": "Разрешить пользователям удалять собственные аккаунты",
"hide-minicard-label-text": "Скрыть текст меток на карточках",
"show-desktop-drag-handles": "Показать ярлыки для перетаскивания",
@@ -933,7 +938,7 @@
"operator-user": "пользователь",
"operator-user-abbrev": "@",
"operator-member": "участника",
- "operator-member-abbrev": "m",
+ "operator-member-abbrev": "м",
"operator-assignee": "Кому назначено",
"operator-assignee-abbrev": "a",
"operator-creator": "автор",
@@ -1037,5 +1042,18 @@
"rulesReportTitle": "Отчёт по правилам",
"copy-swimlane": "Скопировать дорожку",
"copySwimlanePopup-title": "Скопировать дорожку",
- "display-card-creator": "Display Card Creator"
-}
\ No newline at end of file
+ "display-card-creator": "Показать создателя карты",
+ "wait-spinner": "Спинер ожидания",
+ "Bounce": "Прыгающий спинер ожидания",
+ "Cube": "Кубический спинер ожидания",
+ "Cube-Grid": "Сетка кубиков",
+ "Dot": "Точки",
+ "Double-Bounce": "Двойной прыгающий спинер ожидания",
+ "Rotateplane": "Rotateplane Wait Spinner",
+ "Scaleout": "Scaleout Wait Spinner",
+ "Wave": "Wave Wait Spinner",
+ "maximize-card": "Maximize Card",
+ "minimize-card": "Minimize Card",
+ "delete-org-warning-message": "Can not delete this organization, there is at least one user belongs to is",
+ "delete-team-warning-message": "Can not delete this team, there is at least one user belongs to is"
+}
diff --git a/i18n/sk.i18n.json b/i18n/sk.i18n.json
index 97f89bfd0..2abbad846 100644
--- a/i18n/sk.i18n.json
+++ b/i18n/sk.i18n.json
@@ -358,7 +358,11 @@
"export-board-excel": "Export board to Excel",
"user-can-not-export-excel": "User can not export Excel",
"export-board-html": "Export board to HTML",
+ "export-card": "Export card",
+ "export-card-pdf": "Export card to PDF",
+ "user-can-not-export-card-to-pdf": "User can not export card to PDF",
"exportBoardPopup-title": "Export board",
+ "exportCardPopup-title": "Export card",
"sort": "Sort",
"sort-desc": "Click to Sort List",
"list-sort-by": "Sort the List By:",
@@ -664,6 +668,7 @@
"setListColorPopup-title": "Choose a color",
"assigned-by": "Assigned By",
"requested-by": "Requested By",
+ "card-sorting-by-number": "Card sorting by number",
"board-delete-notice": "Deleting is permanent. You will lose all lists, cards and actions associated with this board.",
"delete-board-confirm-popup": "All lists, cards, labels, and activities will be deleted and you won't be able to recover the board contents. There is no undo.",
"boardDeletePopup-title": "Delete Board?",
@@ -1037,5 +1042,18 @@
"rulesReportTitle": "Rules Report",
"copy-swimlane": "Copy Swimlane",
"copySwimlanePopup-title": "Copy Swimlane",
- "display-card-creator": "Display Card Creator"
-}
\ No newline at end of file
+ "display-card-creator": "Display Card Creator",
+ "wait-spinner": "Wait Spinner",
+ "Bounce": "Bounce Wait Spinner",
+ "Cube": "Cube Wait Spinner",
+ "Cube-Grid": "Cube-Grid Wait Spinner",
+ "Dot": "Dot Wait Spinner",
+ "Double-Bounce": "Double Bounce Wait Spinner",
+ "Rotateplane": "Rotateplane Wait Spinner",
+ "Scaleout": "Scaleout Wait Spinner",
+ "Wave": "Wave Wait Spinner",
+ "maximize-card": "Maximize Card",
+ "minimize-card": "Minimize Card",
+ "delete-org-warning-message": "Can not delete this organization, there is at least one user belongs to is",
+ "delete-team-warning-message": "Can not delete this team, there is at least one user belongs to is"
+}
diff --git a/i18n/sl.i18n.json b/i18n/sl.i18n.json
index f12b56a3a..e9ff70837 100644
--- a/i18n/sl.i18n.json
+++ b/i18n/sl.i18n.json
@@ -358,7 +358,11 @@
"export-board-excel": "Export board to Excel",
"user-can-not-export-excel": "User can not export Excel",
"export-board-html": "Export board to HTML",
+ "export-card": "Export card",
+ "export-card-pdf": "Export card to PDF",
+ "user-can-not-export-card-to-pdf": "User can not export card to PDF",
"exportBoardPopup-title": "Izvozi tablo",
+ "exportCardPopup-title": "Export card",
"sort": "Sortiraj",
"sort-desc": "Klikni za sortiranje seznama",
"list-sort-by": "Sortiraj po:",
@@ -664,6 +668,7 @@
"setListColorPopup-title": "Izberi barvo",
"assigned-by": "Dodelil",
"requested-by": "Zahteval",
+ "card-sorting-by-number": "Card sorting by number",
"board-delete-notice": "Brisanje je trajno. Izgubili boste vse sezname, kartice in akcije, povezane z desko.",
"delete-board-confirm-popup": "Vsi seznami, kartice, oznake in dejavnosti bodo izbrisani in vsebine table ne boste mogli obnoviti. Razveljavitve ni.",
"boardDeletePopup-title": "Izbriši tablo?",
@@ -1037,5 +1042,18 @@
"rulesReportTitle": "Rules Report",
"copy-swimlane": "Copy Swimlane",
"copySwimlanePopup-title": "Copy Swimlane",
- "display-card-creator": "Display Card Creator"
-}
\ No newline at end of file
+ "display-card-creator": "Display Card Creator",
+ "wait-spinner": "Wait Spinner",
+ "Bounce": "Bounce Wait Spinner",
+ "Cube": "Cube Wait Spinner",
+ "Cube-Grid": "Cube-Grid Wait Spinner",
+ "Dot": "Dot Wait Spinner",
+ "Double-Bounce": "Double Bounce Wait Spinner",
+ "Rotateplane": "Rotateplane Wait Spinner",
+ "Scaleout": "Scaleout Wait Spinner",
+ "Wave": "Wave Wait Spinner",
+ "maximize-card": "Maximize Card",
+ "minimize-card": "Minimize Card",
+ "delete-org-warning-message": "Can not delete this organization, there is at least one user belongs to is",
+ "delete-team-warning-message": "Can not delete this team, there is at least one user belongs to is"
+}
diff --git a/i18n/sr.i18n.json b/i18n/sr.i18n.json
index 955ac1862..1c494890e 100644
--- a/i18n/sr.i18n.json
+++ b/i18n/sr.i18n.json
@@ -358,7 +358,11 @@
"export-board-excel": "Export board to Excel",
"user-can-not-export-excel": "User can not export Excel",
"export-board-html": "Export board to HTML",
+ "export-card": "Export card",
+ "export-card-pdf": "Export card to PDF",
+ "user-can-not-export-card-to-pdf": "User can not export card to PDF",
"exportBoardPopup-title": "Export board",
+ "exportCardPopup-title": "Export card",
"sort": "Sortiraj",
"sort-desc": "Kliknite da biste sortirali listu",
"list-sort-by": "Poredaj listu po:",
@@ -664,6 +668,7 @@
"setListColorPopup-title": "Izaberi boju",
"assigned-by": "Dodeljeno od strane",
"requested-by": "Requested By",
+ "card-sorting-by-number": "Card sorting by number",
"board-delete-notice": "Deleting is permanent. You will lose all lists, cards and actions associated with this board.",
"delete-board-confirm-popup": "All lists, cards, labels, and activities will be deleted and you won't be able to recover the board contents. There is no undo.",
"boardDeletePopup-title": "Delete Board?",
@@ -1037,5 +1042,18 @@
"rulesReportTitle": "Rules Report",
"copy-swimlane": "Copy Swimlane",
"copySwimlanePopup-title": "Copy Swimlane",
- "display-card-creator": "Display Card Creator"
-}
\ No newline at end of file
+ "display-card-creator": "Display Card Creator",
+ "wait-spinner": "Wait Spinner",
+ "Bounce": "Bounce Wait Spinner",
+ "Cube": "Cube Wait Spinner",
+ "Cube-Grid": "Cube-Grid Wait Spinner",
+ "Dot": "Dot Wait Spinner",
+ "Double-Bounce": "Double Bounce Wait Spinner",
+ "Rotateplane": "Rotateplane Wait Spinner",
+ "Scaleout": "Scaleout Wait Spinner",
+ "Wave": "Wave Wait Spinner",
+ "maximize-card": "Maximize Card",
+ "minimize-card": "Minimize Card",
+ "delete-org-warning-message": "Can not delete this organization, there is at least one user belongs to is",
+ "delete-team-warning-message": "Can not delete this team, there is at least one user belongs to is"
+}
diff --git a/i18n/sv.i18n.json b/i18n/sv.i18n.json
index 34c02703b..9454e116e 100644
--- a/i18n/sv.i18n.json
+++ b/i18n/sv.i18n.json
@@ -358,7 +358,11 @@
"export-board-excel": "Exportera tavla till Excel",
"user-can-not-export-excel": "Användare kan inte exportera till Excel",
"export-board-html": "Exportera tavla till HTML",
+ "export-card": "Export card",
+ "export-card-pdf": "Export card to PDF",
+ "user-can-not-export-card-to-pdf": "User can not export card to PDF",
"exportBoardPopup-title": "Exportera tavla",
+ "exportCardPopup-title": "Export card",
"sort": "Sortera",
"sort-desc": "Klicka för att sortera listan",
"list-sort-by": "Sortera listan efter:",
@@ -664,6 +668,7 @@
"setListColorPopup-title": "Välj en färg",
"assigned-by": "Tilldelad av",
"requested-by": "Efterfrågad av",
+ "card-sorting-by-number": "Card sorting by number",
"board-delete-notice": "Radering är permanent. Du kommer förlora alla listor, kort och händelser kopplade till den här tavlan.",
"delete-board-confirm-popup": "Alla listor, kort, etiketter och aktiviteter kommer tas bort och du kommer inte kunna återställa tavlans innehåll. Det går inte att ångra.",
"boardDeletePopup-title": "Ta bort tavla?",
@@ -1037,5 +1042,18 @@
"rulesReportTitle": "Regelrapport",
"copy-swimlane": "Copy Swimlane",
"copySwimlanePopup-title": "Copy Swimlane",
- "display-card-creator": "Display Card Creator"
-}
\ No newline at end of file
+ "display-card-creator": "Display Card Creator",
+ "wait-spinner": "Wait Spinner",
+ "Bounce": "Bounce Wait Spinner",
+ "Cube": "Cube Wait Spinner",
+ "Cube-Grid": "Cube-Grid Wait Spinner",
+ "Dot": "Dot Wait Spinner",
+ "Double-Bounce": "Double Bounce Wait Spinner",
+ "Rotateplane": "Rotateplane Wait Spinner",
+ "Scaleout": "Scaleout Wait Spinner",
+ "Wave": "Wave Wait Spinner",
+ "maximize-card": "Maximize Card",
+ "minimize-card": "Minimize Card",
+ "delete-org-warning-message": "Can not delete this organization, there is at least one user belongs to is",
+ "delete-team-warning-message": "Can not delete this team, there is at least one user belongs to is"
+}
diff --git a/i18n/sw.i18n.json b/i18n/sw.i18n.json
index 80f820d51..00af3bcf6 100644
--- a/i18n/sw.i18n.json
+++ b/i18n/sw.i18n.json
@@ -358,7 +358,11 @@
"export-board-excel": "Export board to Excel",
"user-can-not-export-excel": "User can not export Excel",
"export-board-html": "Export board to HTML",
+ "export-card": "Export card",
+ "export-card-pdf": "Export card to PDF",
+ "user-can-not-export-card-to-pdf": "User can not export card to PDF",
"exportBoardPopup-title": "Export board",
+ "exportCardPopup-title": "Export card",
"sort": "Sort",
"sort-desc": "Click to Sort List",
"list-sort-by": "Sort the List By:",
@@ -664,6 +668,7 @@
"setListColorPopup-title": "Choose a color",
"assigned-by": "Assigned By",
"requested-by": "Requested By",
+ "card-sorting-by-number": "Card sorting by number",
"board-delete-notice": "Deleting is permanent. You will lose all lists, cards and actions associated with this board.",
"delete-board-confirm-popup": "All lists, cards, labels, and activities will be deleted and you won't be able to recover the board contents. There is no undo.",
"boardDeletePopup-title": "Delete Board?",
@@ -1037,5 +1042,18 @@
"rulesReportTitle": "Rules Report",
"copy-swimlane": "Copy Swimlane",
"copySwimlanePopup-title": "Copy Swimlane",
- "display-card-creator": "Display Card Creator"
-}
\ No newline at end of file
+ "display-card-creator": "Display Card Creator",
+ "wait-spinner": "Wait Spinner",
+ "Bounce": "Bounce Wait Spinner",
+ "Cube": "Cube Wait Spinner",
+ "Cube-Grid": "Cube-Grid Wait Spinner",
+ "Dot": "Dot Wait Spinner",
+ "Double-Bounce": "Double Bounce Wait Spinner",
+ "Rotateplane": "Rotateplane Wait Spinner",
+ "Scaleout": "Scaleout Wait Spinner",
+ "Wave": "Wave Wait Spinner",
+ "maximize-card": "Maximize Card",
+ "minimize-card": "Minimize Card",
+ "delete-org-warning-message": "Can not delete this organization, there is at least one user belongs to is",
+ "delete-team-warning-message": "Can not delete this team, there is at least one user belongs to is"
+}
diff --git a/i18n/ta.i18n.json b/i18n/ta.i18n.json
index 1167185d4..2fa2e9800 100644
--- a/i18n/ta.i18n.json
+++ b/i18n/ta.i18n.json
@@ -358,7 +358,11 @@
"export-board-excel": "Export board to Excel",
"user-can-not-export-excel": "User can not export Excel",
"export-board-html": "Export board to HTML",
+ "export-card": "Export card",
+ "export-card-pdf": "Export card to PDF",
+ "user-can-not-export-card-to-pdf": "User can not export card to PDF",
"exportBoardPopup-title": "Export board",
+ "exportCardPopup-title": "Export card",
"sort": "Sort",
"sort-desc": "Click to Sort List",
"list-sort-by": "Sort the List By:",
@@ -664,6 +668,7 @@
"setListColorPopup-title": "Choose a color",
"assigned-by": "Assigned By",
"requested-by": "Requested By",
+ "card-sorting-by-number": "Card sorting by number",
"board-delete-notice": "Deleting is permanent. You will lose all lists, cards and actions associated with this board.",
"delete-board-confirm-popup": "All lists, cards, labels, and activities will be deleted and you won't be able to recover the board contents. There is no undo.",
"boardDeletePopup-title": "Delete Board?",
@@ -1037,5 +1042,18 @@
"rulesReportTitle": "Rules Report",
"copy-swimlane": "Copy Swimlane",
"copySwimlanePopup-title": "Copy Swimlane",
- "display-card-creator": "Display Card Creator"
-}
\ No newline at end of file
+ "display-card-creator": "Display Card Creator",
+ "wait-spinner": "Wait Spinner",
+ "Bounce": "Bounce Wait Spinner",
+ "Cube": "Cube Wait Spinner",
+ "Cube-Grid": "Cube-Grid Wait Spinner",
+ "Dot": "Dot Wait Spinner",
+ "Double-Bounce": "Double Bounce Wait Spinner",
+ "Rotateplane": "Rotateplane Wait Spinner",
+ "Scaleout": "Scaleout Wait Spinner",
+ "Wave": "Wave Wait Spinner",
+ "maximize-card": "Maximize Card",
+ "minimize-card": "Minimize Card",
+ "delete-org-warning-message": "Can not delete this organization, there is at least one user belongs to is",
+ "delete-team-warning-message": "Can not delete this team, there is at least one user belongs to is"
+}
diff --git a/i18n/th.i18n.json b/i18n/th.i18n.json
index 9fa38866f..62f8e9e8d 100644
--- a/i18n/th.i18n.json
+++ b/i18n/th.i18n.json
@@ -358,7 +358,11 @@
"export-board-excel": "Export board to Excel",
"user-can-not-export-excel": "User can not export Excel",
"export-board-html": "Export board to HTML",
+ "export-card": "Export card",
+ "export-card-pdf": "Export card to PDF",
+ "user-can-not-export-card-to-pdf": "User can not export card to PDF",
"exportBoardPopup-title": "ส่งออกกระดาน",
+ "exportCardPopup-title": "Export card",
"sort": "Sort",
"sort-desc": "Click to Sort List",
"list-sort-by": "Sort the List By:",
@@ -664,6 +668,7 @@
"setListColorPopup-title": "Choose a color",
"assigned-by": "Assigned By",
"requested-by": "Requested By",
+ "card-sorting-by-number": "Card sorting by number",
"board-delete-notice": "Deleting is permanent. You will lose all lists, cards and actions associated with this board.",
"delete-board-confirm-popup": "All lists, cards, labels, and activities will be deleted and you won't be able to recover the board contents. There is no undo.",
"boardDeletePopup-title": "Delete Board?",
@@ -1037,5 +1042,18 @@
"rulesReportTitle": "Rules Report",
"copy-swimlane": "Copy Swimlane",
"copySwimlanePopup-title": "Copy Swimlane",
- "display-card-creator": "Display Card Creator"
-}
\ No newline at end of file
+ "display-card-creator": "Display Card Creator",
+ "wait-spinner": "Wait Spinner",
+ "Bounce": "Bounce Wait Spinner",
+ "Cube": "Cube Wait Spinner",
+ "Cube-Grid": "Cube-Grid Wait Spinner",
+ "Dot": "Dot Wait Spinner",
+ "Double-Bounce": "Double Bounce Wait Spinner",
+ "Rotateplane": "Rotateplane Wait Spinner",
+ "Scaleout": "Scaleout Wait Spinner",
+ "Wave": "Wave Wait Spinner",
+ "maximize-card": "Maximize Card",
+ "minimize-card": "Minimize Card",
+ "delete-org-warning-message": "Can not delete this organization, there is at least one user belongs to is",
+ "delete-team-warning-message": "Can not delete this team, there is at least one user belongs to is"
+}
diff --git a/i18n/tr.i18n.json b/i18n/tr.i18n.json
index f4191351a..af8c896ba 100644
--- a/i18n/tr.i18n.json
+++ b/i18n/tr.i18n.json
@@ -358,7 +358,11 @@
"export-board-excel": "Export board to Excel",
"user-can-not-export-excel": "User can not export Excel",
"export-board-html": "Panoyu HTML olarak dışarı aktar",
+ "export-card": "Export card",
+ "export-card-pdf": "Export card to PDF",
+ "user-can-not-export-card-to-pdf": "User can not export card to PDF",
"exportBoardPopup-title": "Panoyu dışarı aktar",
+ "exportCardPopup-title": "Export card",
"sort": "Sırala",
"sort-desc": "Listeyi Sıralamak için Tıklayın",
"list-sort-by": "Listeyi Sırala:",
@@ -664,6 +668,7 @@
"setListColorPopup-title": "Renk seçimi yap",
"assigned-by": "Atamayı yapan",
"requested-by": "Talep Eden",
+ "card-sorting-by-number": "Card sorting by number",
"board-delete-notice": "Silme kalıcıdır. Bu kartla ilişkili tüm listeleri, kartları ve işlemleri kaybedeceksiniz.",
"delete-board-confirm-popup": "Tüm listeler, kartlar, etiketler ve etkinlikler silinecek ve pano içeriğini kurtaramayacaksınız. Geri dönüş yok.",
"boardDeletePopup-title": "Panoyu Sil?",
@@ -1037,5 +1042,18 @@
"rulesReportTitle": "Rules Report",
"copy-swimlane": "Copy Swimlane",
"copySwimlanePopup-title": "Copy Swimlane",
- "display-card-creator": "Display Card Creator"
-}
\ No newline at end of file
+ "display-card-creator": "Display Card Creator",
+ "wait-spinner": "Wait Spinner",
+ "Bounce": "Bounce Wait Spinner",
+ "Cube": "Cube Wait Spinner",
+ "Cube-Grid": "Cube-Grid Wait Spinner",
+ "Dot": "Dot Wait Spinner",
+ "Double-Bounce": "Double Bounce Wait Spinner",
+ "Rotateplane": "Rotateplane Wait Spinner",
+ "Scaleout": "Scaleout Wait Spinner",
+ "Wave": "Wave Wait Spinner",
+ "maximize-card": "Maximize Card",
+ "minimize-card": "Minimize Card",
+ "delete-org-warning-message": "Can not delete this organization, there is at least one user belongs to is",
+ "delete-team-warning-message": "Can not delete this team, there is at least one user belongs to is"
+}
diff --git a/i18n/uk.i18n.json b/i18n/uk.i18n.json
index 3b681ebc2..18e51812a 100644
--- a/i18n/uk.i18n.json
+++ b/i18n/uk.i18n.json
@@ -358,7 +358,11 @@
"export-board-excel": "Export board to Excel",
"user-can-not-export-excel": "User can not export Excel",
"export-board-html": "Export board to HTML",
+ "export-card": "Export card",
+ "export-card-pdf": "Export card to PDF",
+ "user-can-not-export-card-to-pdf": "User can not export card to PDF",
"exportBoardPopup-title": "Export board",
+ "exportCardPopup-title": "Export card",
"sort": "Sort",
"sort-desc": "Click to Sort List",
"list-sort-by": "Sort the List By:",
@@ -664,6 +668,7 @@
"setListColorPopup-title": "Оберіть колір",
"assigned-by": "Assigned By",
"requested-by": "Запитано",
+ "card-sorting-by-number": "Card sorting by number",
"board-delete-notice": "Це видалення назавжди. Ви втратите всі листи, картки та дії, пов'язані з цією дошкою.",
"delete-board-confirm-popup": "All lists, cards, labels, and activities will be deleted and you won't be able to recover the board contents. There is no undo.",
"boardDeletePopup-title": "Delete Board?",
@@ -1037,5 +1042,18 @@
"rulesReportTitle": "Rules Report",
"copy-swimlane": "Copy Swimlane",
"copySwimlanePopup-title": "Copy Swimlane",
- "display-card-creator": "Display Card Creator"
-}
\ No newline at end of file
+ "display-card-creator": "Display Card Creator",
+ "wait-spinner": "Wait Spinner",
+ "Bounce": "Bounce Wait Spinner",
+ "Cube": "Cube Wait Spinner",
+ "Cube-Grid": "Cube-Grid Wait Spinner",
+ "Dot": "Dot Wait Spinner",
+ "Double-Bounce": "Double Bounce Wait Spinner",
+ "Rotateplane": "Rotateplane Wait Spinner",
+ "Scaleout": "Scaleout Wait Spinner",
+ "Wave": "Wave Wait Spinner",
+ "maximize-card": "Maximize Card",
+ "minimize-card": "Minimize Card",
+ "delete-org-warning-message": "Can not delete this organization, there is at least one user belongs to is",
+ "delete-team-warning-message": "Can not delete this team, there is at least one user belongs to is"
+}
diff --git a/i18n/vi.i18n.json b/i18n/vi.i18n.json
index 860a87174..9ab06a66e 100644
--- a/i18n/vi.i18n.json
+++ b/i18n/vi.i18n.json
@@ -358,7 +358,11 @@
"export-board-excel": "Xuất bảng sang Excel",
"user-can-not-export-excel": "Người dùng không thể xuất Excel",
"export-board-html": "Xuất bảng sang HTML",
+ "export-card": "Export card",
+ "export-card-pdf": "Export card to PDF",
+ "user-can-not-export-card-to-pdf": "User can not export card to PDF",
"exportBoardPopup-title": "Xuất bảng",
+ "exportCardPopup-title": "Export card",
"sort": "Sắp xếp",
"sort-desc": "Nhấp để sắp xếp danh sách",
"list-sort-by": "Sắp xếp Danh sách bởi:",
@@ -664,6 +668,7 @@
"setListColorPopup-title": "Chọn một màu",
"assigned-by": "Được chỉ định bởi",
"requested-by": "Yêu cầu bởi",
+ "card-sorting-by-number": "Card sorting by number",
"board-delete-notice": "Việc xóa là vĩnh viễn. Bạn sẽ mất tất cả danh sách, thẻ và hành động liên quan đến bảng này.",
"delete-board-confirm-popup": "Tất cả danh sách, thẻ, nhãn và hoạt động sẽ bị xóa và bạn sẽ không thể khôi phục nội dung bảng. Không thể hoàn tác.",
"boardDeletePopup-title": "Xoá Bảng?",
@@ -1037,5 +1042,18 @@
"rulesReportTitle": "Quy tắc Báo cáo",
"copy-swimlane": "Sao chép Làn ngang",
"copySwimlanePopup-title": "Sao chép Làn ngang",
- "display-card-creator": "Display Card Creator"
-}
\ No newline at end of file
+ "display-card-creator": "Display Card Creator",
+ "wait-spinner": "Wait Spinner",
+ "Bounce": "Bounce Wait Spinner",
+ "Cube": "Cube Wait Spinner",
+ "Cube-Grid": "Cube-Grid Wait Spinner",
+ "Dot": "Dot Wait Spinner",
+ "Double-Bounce": "Double Bounce Wait Spinner",
+ "Rotateplane": "Rotateplane Wait Spinner",
+ "Scaleout": "Scaleout Wait Spinner",
+ "Wave": "Wave Wait Spinner",
+ "maximize-card": "Maximize Card",
+ "minimize-card": "Minimize Card",
+ "delete-org-warning-message": "Can not delete this organization, there is at least one user belongs to is",
+ "delete-team-warning-message": "Can not delete this team, there is at least one user belongs to is"
+}
diff --git a/i18n/zh-CN.i18n.json b/i18n/zh-CN.i18n.json
index 7826328b0..f12029557 100644
--- a/i18n/zh-CN.i18n.json
+++ b/i18n/zh-CN.i18n.json
@@ -358,7 +358,11 @@
"export-board-excel": "看板导出为Excel",
"user-can-not-export-excel": "用户无法导出Excel",
"export-board-html": "看板导出为HTML",
+ "export-card": "Export card",
+ "export-card-pdf": "Export card to PDF",
+ "user-can-not-export-card-to-pdf": "User can not export card to PDF",
"exportBoardPopup-title": "导出看板",
+ "exportCardPopup-title": "Export card",
"sort": "排序",
"sort-desc": "点此来将列表排序",
"list-sort-by": "按此来将列表排序:",
@@ -664,6 +668,7 @@
"setListColorPopup-title": "选择一种颜色",
"assigned-by": "指派人",
"requested-by": "需求人",
+ "card-sorting-by-number": "Card sorting by number",
"board-delete-notice": "删除时永久操作,将会丢失此看板上的所有列表、卡片和动作。",
"delete-board-confirm-popup": "所有列表、卡片、标签和活动都回被删除,将无法恢复看板内容。不支持撤销。",
"boardDeletePopup-title": "删除看板?",
@@ -1037,5 +1042,18 @@
"rulesReportTitle": "规则报告",
"copy-swimlane": "复制泳道",
"copySwimlanePopup-title": "复制泳道",
- "display-card-creator": "Display Card Creator"
-}
\ No newline at end of file
+ "display-card-creator": "Display Card Creator",
+ "wait-spinner": "Wait Spinner",
+ "Bounce": "Bounce Wait Spinner",
+ "Cube": "Cube Wait Spinner",
+ "Cube-Grid": "Cube-Grid Wait Spinner",
+ "Dot": "Dot Wait Spinner",
+ "Double-Bounce": "Double Bounce Wait Spinner",
+ "Rotateplane": "Rotateplane Wait Spinner",
+ "Scaleout": "Scaleout Wait Spinner",
+ "Wave": "Wave Wait Spinner",
+ "maximize-card": "Maximize Card",
+ "minimize-card": "Minimize Card",
+ "delete-org-warning-message": "Can not delete this organization, there is at least one user belongs to is",
+ "delete-team-warning-message": "Can not delete this team, there is at least one user belongs to is"
+}
diff --git a/i18n/zh-HK.i18n.json b/i18n/zh-HK.i18n.json
index dba10bb9a..9b6e0982f 100644
--- a/i18n/zh-HK.i18n.json
+++ b/i18n/zh-HK.i18n.json
@@ -358,7 +358,11 @@
"export-board-excel": "Export board to Excel",
"user-can-not-export-excel": "User can not export Excel",
"export-board-html": "Export board to HTML",
+ "export-card": "Export card",
+ "export-card-pdf": "Export card to PDF",
+ "user-can-not-export-card-to-pdf": "User can not export card to PDF",
"exportBoardPopup-title": "Export board",
+ "exportCardPopup-title": "Export card",
"sort": "Sort",
"sort-desc": "Click to Sort List",
"list-sort-by": "Sort the List By:",
@@ -664,6 +668,7 @@
"setListColorPopup-title": "Choose a color",
"assigned-by": "Assigned By",
"requested-by": "Requested By",
+ "card-sorting-by-number": "Card sorting by number",
"board-delete-notice": "Deleting is permanent. You will lose all lists, cards and actions associated with this board.",
"delete-board-confirm-popup": "All lists, cards, labels, and activities will be deleted and you won't be able to recover the board contents. There is no undo.",
"boardDeletePopup-title": "Delete Board?",
@@ -1037,5 +1042,18 @@
"rulesReportTitle": "Rules Report",
"copy-swimlane": "Copy Swimlane",
"copySwimlanePopup-title": "Copy Swimlane",
- "display-card-creator": "Display Card Creator"
-}
\ No newline at end of file
+ "display-card-creator": "Display Card Creator",
+ "wait-spinner": "Wait Spinner",
+ "Bounce": "Bounce Wait Spinner",
+ "Cube": "Cube Wait Spinner",
+ "Cube-Grid": "Cube-Grid Wait Spinner",
+ "Dot": "Dot Wait Spinner",
+ "Double-Bounce": "Double Bounce Wait Spinner",
+ "Rotateplane": "Rotateplane Wait Spinner",
+ "Scaleout": "Scaleout Wait Spinner",
+ "Wave": "Wave Wait Spinner",
+ "maximize-card": "Maximize Card",
+ "minimize-card": "Minimize Card",
+ "delete-org-warning-message": "Can not delete this organization, there is at least one user belongs to is",
+ "delete-team-warning-message": "Can not delete this team, there is at least one user belongs to is"
+}
diff --git a/i18n/zh-TW.i18n.json b/i18n/zh-TW.i18n.json
index 1ff87757b..4125f851d 100644
--- a/i18n/zh-TW.i18n.json
+++ b/i18n/zh-TW.i18n.json
@@ -358,7 +358,11 @@
"export-board-excel": "匯出看板至 Excel",
"user-can-not-export-excel": "使用者無法匯出至 Excel",
"export-board-html": "匯出看板為HTML格式\n ",
+ "export-card": "Export card",
+ "export-card-pdf": "Export card to PDF",
+ "user-can-not-export-card-to-pdf": "User can not export card to PDF",
"exportBoardPopup-title": "匯出看板",
+ "exportCardPopup-title": "Export card",
"sort": "排序",
"sort-desc": "點選排序清單",
"list-sort-by": "清單排序依照:",
@@ -664,6 +668,7 @@
"setListColorPopup-title": "選擇顏色",
"assigned-by": "分配者",
"requested-by": "請求者",
+ "card-sorting-by-number": "Card sorting by number",
"board-delete-notice": "永久刪除是無法復原的,你將會失去這個看板上的所有清單、卡片和動作。",
"delete-board-confirm-popup": "所有清單、卡片、標籤和活動都會被刪除,將無法恢覆看板內容。不支援撤銷。",
"boardDeletePopup-title": "刪除看板?",
@@ -1037,5 +1042,18 @@
"rulesReportTitle": "Rules Report",
"copy-swimlane": "Copy Swimlane",
"copySwimlanePopup-title": "Copy Swimlane",
- "display-card-creator": "Display Card Creator"
-}
\ No newline at end of file
+ "display-card-creator": "Display Card Creator",
+ "wait-spinner": "Wait Spinner",
+ "Bounce": "Bounce Wait Spinner",
+ "Cube": "Cube Wait Spinner",
+ "Cube-Grid": "Cube-Grid Wait Spinner",
+ "Dot": "Dot Wait Spinner",
+ "Double-Bounce": "Double Bounce Wait Spinner",
+ "Rotateplane": "Rotateplane Wait Spinner",
+ "Scaleout": "Scaleout Wait Spinner",
+ "Wave": "Wave Wait Spinner",
+ "maximize-card": "Maximize Card",
+ "minimize-card": "Minimize Card",
+ "delete-org-warning-message": "Can not delete this organization, there is at least one user belongs to is",
+ "delete-team-warning-message": "Can not delete this team, there is at least one user belongs to is"
+}
diff --git a/models/boards.js b/models/boards.js
index 9cda643b1..0364dd9f7 100644
--- a/models/boards.js
+++ b/models/boards.js
@@ -373,6 +373,14 @@ Boards.attachSchema(
defaultValue: true,
},
+ allowsCardSortingByNumber: {
+ /**
+ * Does the board allows card sorting by number?
+ */
+ type: Boolean,
+ defaultValue: true,
+ },
+
allowsAssignedBy: {
/**
* Does the board allows requested by?
@@ -1190,6 +1198,10 @@ Boards.mutations({
return { $set: { allowsRequestedBy } };
},
+ setAllowsCardSortingByNumber(allowsCardSortingByNumber) {
+ return { $set: { allowsCardSortingByNumber } };
+ },
+
setAllowsAttachments(allowsAttachments) {
return { $set: { allowsAttachments } };
},
diff --git a/models/exportPDF.js b/models/exportPDF.js
new file mode 100644
index 000000000..e9236304d
--- /dev/null
+++ b/models/exportPDF.js
@@ -0,0 +1,691 @@
+if (Meteor.isServer) {
+ // todo XXX once we have a real API in place, move that route there
+ // todo XXX also share the route definition between the client and the server
+ // so that we could use something like
+ // `ApiRoutes.path('boards/exportExcel', boardId)``
+ // on the client instead of copy/pasting the route path manually between the
+ // client and the server.
+ /**
+ * @operation exportExcel
+ * @tag Boards
+ *
+ * @summary This route is used to export the board Excel.
+ *
+ * @description If user is already logged-in, pass loginToken as param
+ * "authToken": '/api/boards/:boardId/exportExcel?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
+ */
+ const Excel = require('exceljs');
+ Picker.route('/api/boards/:boardId/lists/:listId/cards/:cardId/exportPDF', function (params, req, res) {
+ const boardId = params.boardId;
+ const paramListId = req.params.listId;
+ const paramCardId = req.params.cardId;
+ let user = null;
+ let impersonateDone = false;
+ let adminId = null;
+ const loginToken = params.query.authToken;
+ if (loginToken) {
+ const hashToken = Accounts._hashLoginToken(loginToken);
+ user = Meteor.users.findOne({
+ 'services.resume.loginTokens.hashedToken': hashToken,
+ });
+ adminId = user._id.toString();
+ impersonateDone = ImpersonatedUsers.findOne({
+ adminId: adminId,
+ });
+ } else if (!Meteor.settings.public.sandstorm) {
+ Authentication.checkUserId(req.userId);
+ user = Users.findOne({
+ _id: req.userId,
+ isAdmin: true,
+ });
+ }
+ const exporterExcel = new ExporterCardPDF(boardId);
+ if (exporterCardPDF.canExport(user) || impersonateDone) {
+ if (impersonateDone) {
+ ImpersonatedUsers.insert({
+ adminId: adminId,
+ boardId: boardId,
+ reason: 'exportCardPDF',
+ });
+ }
+
+ exporterCardPDF.build(res);
+ } else {
+ res.end(TAPi18n.__('user-can-not-export-card-to-pdf'));
+ }
+ });
+}
+
+// exporter maybe is broken since Gridfs introduced, add fs and path
+
+export class ExporterCardPDF {
+ constructor(boardId) {
+ this._boardId = boardId;
+ }
+
+ build(res) {
+
+/*
+ const fs = Npm.require('fs');
+ const os = Npm.require('os');
+ const path = Npm.require('path');
+
+ const byBoard = {
+ boardId: this._boardId,
+ };
+ const byBoardNoLinked = {
+ boardId: this._boardId,
+ linkedId: {
+ $in: ['', null],
+ },
+ };
+ // we do not want to retrieve boardId in related elements
+ const noBoardId = {
+ fields: {
+ boardId: 0,
+ },
+ };
+ const result = {
+ _format: 'wekan-board-1.0.0',
+ };
+ _.extend(
+ result,
+ Boards.findOne(this._boardId, {
+ fields: {
+ stars: 0,
+ },
+ }),
+ );
+ result.lists = Lists.find(byBoard, noBoardId).fetch();
+ result.cards = Cards.find(byBoardNoLinked, noBoardId).fetch();
+ result.swimlanes = Swimlanes.find(byBoard, noBoardId).fetch();
+ result.customFields = CustomFields.find(
+ {
+ boardIds: {
+ $in: [this.boardId],
+ },
+ },
+ {
+ fields: {
+ boardId: 0,
+ },
+ },
+ ).fetch();
+ result.comments = CardComments.find(byBoard, noBoardId).fetch();
+ result.activities = Activities.find(byBoard, noBoardId).fetch();
+ result.rules = Rules.find(byBoard, noBoardId).fetch();
+ result.checklists = [];
+ result.checklistItems = [];
+ result.subtaskItems = [];
+ result.triggers = [];
+ result.actions = [];
+ result.cards.forEach((card) => {
+ result.checklists.push(
+ ...Checklists.find({
+ cardId: card._id,
+ }).fetch(),
+ );
+ result.checklistItems.push(
+ ...ChecklistItems.find({
+ cardId: card._id,
+ }).fetch(),
+ );
+ result.subtaskItems.push(
+ ...Cards.find({
+ parentId: card._id,
+ }).fetch(),
+ );
+ });
+ result.rules.forEach((rule) => {
+ result.triggers.push(
+ ...Triggers.find(
+ {
+ _id: rule.triggerId,
+ },
+ noBoardId,
+ ).fetch(),
+ );
+ result.actions.push(
+ ...Actions.find(
+ {
+ _id: rule.actionId,
+ },
+ noBoardId,
+ ).fetch(),
+ );
+ });
+
+ // we also have to export some user data - as the other elements only
+ // include id but we have to be careful:
+ // 1- only exports users that are linked somehow to that board
+ // 2- do not export any sensitive information
+ const users = {};
+ result.members.forEach((member) => {
+ users[member.userId] = true;
+ });
+ result.lists.forEach((list) => {
+ users[list.userId] = true;
+ });
+ result.cards.forEach((card) => {
+ users[card.userId] = true;
+ if (card.members) {
+ card.members.forEach((memberId) => {
+ users[memberId] = true;
+ });
+ }
+ if (card.assignees) {
+ card.assignees.forEach((memberId) => {
+ users[memberId] = true;
+ });
+ }
+ });
+ result.comments.forEach((comment) => {
+ users[comment.userId] = true;
+ });
+ result.activities.forEach((activity) => {
+ users[activity.userId] = true;
+ });
+ result.checklists.forEach((checklist) => {
+ users[checklist.userId] = true;
+ });
+ const byUserIds = {
+ _id: {
+ $in: Object.getOwnPropertyNames(users),
+ },
+ };
+ // we use whitelist to be sure we do not expose inadvertently
+ // some secret fields that gets added to User later.
+ const userFields = {
+ fields: {
+ _id: 1,
+ username: 1,
+ 'profile.initials': 1,
+ 'profile.avatarUrl': 1,
+ },
+ };
+ result.users = Users.find(byUserIds, userFields)
+ .fetch()
+ .map((user) => {
+ // user avatar is stored as a relative url, we export absolute
+ if ((user.profile || {}).avatarUrl) {
+ user.profile.avatarUrl = FlowRouter.url(user.profile.avatarUrl);
+ }
+ return user;
+ });
+
+ //init exceljs workbook
+ const Excel = require('exceljs');
+ const workbook = new Excel.Workbook();
+ workbook.creator = TAPi18n.__('export-board');
+ workbook.lastModifiedBy = TAPi18n.__('export-board');
+ workbook.created = new Date();
+ workbook.modified = new Date();
+ workbook.lastPrinted = new Date();
+ const filename = `${result.title}.xlsx`;
+ //init worksheet
+ const worksheet = workbook.addWorksheet(result.title, {
+ properties: {
+ tabColor: {
+ argb: 'FFC0000',
+ },
+ },
+ pageSetup: {
+ paperSize: 9,
+ orientation: 'landscape',
+ },
+ });
+ //get worksheet
+ const ws = workbook.getWorksheet(result.title);
+ ws.properties.defaultRowHeight = 20;
+ //init columns
+ //Excel font. Western: Arial. zh-CN: 宋体
+ ws.columns = [
+ {
+ key: 'a',
+ width: 14,
+ },
+ {
+ key: 'b',
+ width: 40,
+ },
+ {
+ key: 'c',
+ width: 60,
+ },
+ {
+ key: 'd',
+ width: 40,
+ },
+ {
+ key: 'e',
+ width: 20,
+ },
+ {
+ key: 'f',
+ width: 20,
+ style: {
+ font: {
+ name: TAPi18n.__('excel-font'),
+ size: '10',
+ },
+ numFmt: 'yyyy/mm/dd hh:mm:ss',
+ },
+ },
+ {
+ key: 'g',
+ width: 20,
+ style: {
+ font: {
+ name: TAPi18n.__('excel-font'),
+ size: '10',
+ },
+ numFmt: 'yyyy/mm/dd hh:mm:ss',
+ },
+ },
+ {
+ key: 'h',
+ width: 20,
+ style: {
+ font: {
+ name: TAPi18n.__('excel-font'),
+ size: '10',
+ },
+ numFmt: 'yyyy/mm/dd hh:mm:ss',
+ },
+ },
+ {
+ key: 'i',
+ width: 20,
+ style: {
+ font: {
+ name: TAPi18n.__('excel-font'),
+ size: '10',
+ },
+ numFmt: 'yyyy/mm/dd hh:mm:ss',
+ },
+ },
+ {
+ key: 'j',
+ width: 20,
+ style: {
+ font: {
+ name: TAPi18n.__('excel-font'),
+ size: '10',
+ },
+ numFmt: 'yyyy/mm/dd hh:mm:ss',
+ },
+ },
+ {
+ key: 'k',
+ width: 20,
+ style: {
+ font: {
+ name: TAPi18n.__('excel-font'),
+ size: '10',
+ },
+ numFmt: 'yyyy/mm/dd hh:mm:ss',
+ },
+ },
+ {
+ key: 'l',
+ width: 20,
+ },
+ {
+ key: 'm',
+ width: 20,
+ },
+ {
+ key: 'n',
+ width: 20,
+ },
+ {
+ key: 'o',
+ width: 20,
+ },
+ {
+ key: 'p',
+ width: 20,
+ },
+ {
+ key: 'q',
+ width: 20,
+ },
+ {
+ key: 'r',
+ width: 20,
+ },
+ ];
+
+ //add title line
+ ws.mergeCells('A1:H1');
+ ws.getCell('A1').value = result.title;
+ ws.getCell('A1').style = {
+ font: {
+ name: TAPi18n.__('excel-font'),
+ size: '20',
+ },
+ };
+ ws.getCell('A1').alignment = {
+ vertical: 'middle',
+ horizontal: 'center',
+ };
+ ws.getRow(1).height = 40;
+ //get member and assignee info
+ let jmem = '';
+ let jassig = '';
+ const jmeml = {};
+ const jassigl = {};
+ for (const i in result.users) {
+ jmem = `${jmem + result.users[i].username},`;
+ jmeml[result.users[i]._id] = result.users[i].username;
+ }
+ jmem = jmem.substr(0, jmem.length - 1);
+ for (const ia in result.users) {
+ jassig = `${jassig + result.users[ia].username},`;
+ jassigl[result.users[ia]._id] = result.users[ia].username;
+ }
+ jassig = jassig.substr(0, jassig.length - 1);
+ //get kanban list info
+ const jlist = {};
+ for (const klist in result.lists) {
+ jlist[result.lists[klist]._id] = result.lists[klist].title;
+ }
+ //get kanban swimlanes info
+ const jswimlane = {};
+ for (const kswimlane in result.swimlanes) {
+ jswimlane[result.swimlanes[kswimlane]._id] =
+ result.swimlanes[kswimlane].title;
+ }
+ //get kanban label info
+ const jlabel = {};
+ var isFirst = 1;
+ for (const klabel in result.labels) {
+ // console.log(klabel);
+ if (isFirst == 0) {
+ jlabel[result.labels[klabel]._id] = `,${result.labels[klabel].name}`;
+ } else {
+ isFirst = 0;
+ jlabel[result.labels[klabel]._id] = result.labels[klabel].name;
+ }
+ }
+ //add data +8 hours
+ function addTZhours(jdate) {
+ const curdate = new Date(jdate);
+ const checkCorrectDate = moment(curdate);
+ if (checkCorrectDate.isValid()) {
+ return curdate;
+ } else {
+ return ' ';
+ }
+ ////Do not add 8 hours to GMT. Use GMT instead.
+ ////Could not yet figure out how to get localtime.
+ //return new Date(curdate.setHours(curdate.getHours() + 8));
+ //return curdate;
+ }
+ //add blank row
+ ws.addRow().values = ['', '', '', '', '', ''];
+ //add kanban info
+ ws.addRow().values = [
+ TAPi18n.__('createdAt'),
+ addTZhours(result.createdAt),
+ TAPi18n.__('modifiedAt'),
+ addTZhours(result.modifiedAt),
+ TAPi18n.__('members'),
+ jmem,
+ ];
+ ws.getRow(3).font = {
+ name: TAPi18n.__('excel-font'),
+ size: 10,
+ bold: true,
+ };
+ ws.mergeCells('F3:R3');
+ ws.getCell('B3').style = {
+ font: {
+ name: TAPi18n.__('excel-font'),
+ size: '10',
+ bold: true,
+ },
+ numFmt: 'yyyy/mm/dd hh:mm:ss',
+ };
+ //cell center
+ function cellCenter(cellno) {
+ ws.getCell(cellno).alignment = {
+ vertical: 'middle',
+ horizontal: 'center',
+ wrapText: true,
+ };
+ }
+ function cellLeft(cellno) {
+ ws.getCell(cellno).alignment = {
+ vertical: 'middle',
+ horizontal: 'left',
+ wrapText: true,
+ };
+ }
+ cellCenter('A3');
+ cellCenter('B3');
+ cellCenter('C3');
+ cellCenter('D3');
+ cellCenter('E3');
+ cellLeft('F3');
+ ws.getRow(3).height = 20;
+ //all border
+ function allBorder(cellno) {
+ ws.getCell(cellno).border = {
+ top: {
+ style: 'thin',
+ },
+ left: {
+ style: 'thin',
+ },
+ bottom: {
+ style: 'thin',
+ },
+ right: {
+ style: 'thin',
+ },
+ };
+ }
+ allBorder('A3');
+ allBorder('B3');
+ allBorder('C3');
+ allBorder('D3');
+ allBorder('E3');
+ allBorder('F3');
+ //add blank row
+ ws.addRow().values = [
+ '',
+ '',
+ '',
+ '',
+ '',
+ '',
+ '',
+ '',
+ '',
+ '',
+ '',
+ '',
+ '',
+ '',
+ '',
+ ];
+ //add card title
+ //ws.addRow().values = ['编号', '标题', '创建人', '创建时间', '更新时间', '列表', '成员', '描述', '标签'];
+ //this is where order in which the excel file generates
+ ws.addRow().values = [
+ TAPi18n.__('number'),
+ TAPi18n.__('title'),
+ TAPi18n.__('description'),
+ TAPi18n.__('parent-card'),
+ TAPi18n.__('owner'),
+ TAPi18n.__('createdAt'),
+ TAPi18n.__('last-modified-at'),
+ TAPi18n.__('card-received'),
+ TAPi18n.__('card-start'),
+ TAPi18n.__('card-due'),
+ TAPi18n.__('card-end'),
+ TAPi18n.__('list'),
+ TAPi18n.__('swimlane'),
+ TAPi18n.__('assignee'),
+ TAPi18n.__('members'),
+ TAPi18n.__('labels'),
+ TAPi18n.__('overtime-hours'),
+ TAPi18n.__('spent-time-hours'),
+ ];
+ ws.getRow(5).height = 20;
+ allBorder('A5');
+ allBorder('B5');
+ allBorder('C5');
+ allBorder('D5');
+ allBorder('E5');
+ allBorder('F5');
+ allBorder('G5');
+ allBorder('H5');
+ allBorder('I5');
+ allBorder('J5');
+ allBorder('K5');
+ allBorder('L5');
+ allBorder('M5');
+ allBorder('N5');
+ allBorder('O5');
+ allBorder('P5');
+ allBorder('Q5');
+ allBorder('R5');
+ cellCenter('A5');
+ cellCenter('B5');
+ cellCenter('C5');
+ cellCenter('D5');
+ cellCenter('E5');
+ cellCenter('F5');
+ cellCenter('G5');
+ cellCenter('H5');
+ cellCenter('I5');
+ cellCenter('J5');
+ cellCenter('K5');
+ cellCenter('L5');
+ cellCenter('M5');
+ cellCenter('N5');
+ cellCenter('O5');
+ cellCenter('P5');
+ cellCenter('Q5');
+ cellCenter('R5');
+ ws.getRow(5).font = {
+ name: TAPi18n.__('excel-font'),
+ size: 12,
+ bold: true,
+ };
+ //add blank row
+ //add card info
+ for (const i in result.cards) {
+ const jcard = result.cards[i];
+ //get member info
+ let jcmem = '';
+ for (const j in jcard.members) {
+ jcmem += jmeml[jcard.members[j]];
+ jcmem += ' ';
+ }
+ //get assignee info
+ let jcassig = '';
+ for (const ja in jcard.assignees) {
+ jcassig += jassigl[jcard.assignees[ja]];
+ jcassig += ' ';
+ }
+ //get card label info
+ let jclabel = '';
+ for (const jl in jcard.labelIds) {
+ jclabel += jlabel[jcard.labelIds[jl]];
+ jclabel += ' ';
+ }
+ //get parent name
+ if (jcard.parentId) {
+ const parentCard = result.cards.find(
+ (card) => card._id === jcard.parentId,
+ );
+ jcard.parentCardTitle = parentCard ? parentCard.title : '';
+ }
+
+ //add card detail
+ const t = Number(i) + 1;
+ ws.addRow().values = [
+ t.toString(),
+ jcard.title,
+ jcard.description,
+ jcard.parentCardTitle,
+ jmeml[jcard.userId],
+ addTZhours(jcard.createdAt),
+ addTZhours(jcard.dateLastActivity),
+ addTZhours(jcard.receivedAt),
+ addTZhours(jcard.startAt),
+ addTZhours(jcard.dueAt),
+ addTZhours(jcard.endAt),
+ jlist[jcard.listId],
+ jswimlane[jcard.swimlaneId],
+ jcassig,
+ jcmem,
+ jclabel,
+ jcard.isOvertime ? 'true' : 'false',
+ jcard.spentTime,
+ ];
+ const y = Number(i) + 6;
+ //ws.getRow(y).height = 25;
+ allBorder(`A${y}`);
+ allBorder(`B${y}`);
+ allBorder(`C${y}`);
+ allBorder(`D${y}`);
+ allBorder(`E${y}`);
+ allBorder(`F${y}`);
+ allBorder(`G${y}`);
+ allBorder(`H${y}`);
+ allBorder(`I${y}`);
+ allBorder(`J${y}`);
+ allBorder(`K${y}`);
+ allBorder(`L${y}`);
+ allBorder(`M${y}`);
+ allBorder(`N${y}`);
+ allBorder(`O${y}`);
+ allBorder(`P${y}`);
+ allBorder(`Q${y}`);
+ allBorder(`R${y}`);
+ cellCenter(`A${y}`);
+ ws.getCell(`B${y}`).alignment = {
+ wrapText: true,
+ };
+ ws.getCell(`C${y}`).alignment = {
+ wrapText: true,
+ };
+ ws.getCell(`M${y}`).alignment = {
+ wrapText: true,
+ };
+ ws.getCell(`N${y}`).alignment = {
+ wrapText: true,
+ };
+ ws.getCell(`O${y}`).alignment = {
+ wrapText: true,
+ };
+ }
+ workbook.xlsx.write(res).then(function () {});
+ */
+
+ var doc = new PDFDocument({size: 'A4', margin: 50});
+ doc.fontSize(12);
+ doc.text('Some test text', 10, 30, {align: 'center', width: 200});
+ this.response.writeHead(200, {
+ 'Content-type': 'application/pdf',
+ 'Content-Disposition': "attachment; filename=test.pdf"
+ });
+ this.response.end( doc.outputSync() );
+
+ }
+
+ canExport(user) {
+ const board = Boards.findOne(this._boardId);
+ return board && board.isVisibleBy(user);
+ }
+}
diff --git a/models/org.js b/models/org.js
index a4ffffd80..8efa9b64b 100644
--- a/models/org.js
+++ b/models/org.js
@@ -113,6 +113,7 @@ if (Meteor.isServer) {
fetch: [],
});
+
Meteor.methods({
setCreateOrg(
orgDisplayName,
diff --git a/models/settings.js b/models/settings.js
index db69644fb..286ef29f9 100644
--- a/models/settings.js
+++ b/models/settings.js
@@ -46,6 +46,10 @@ Settings.attachSchema(
type: String,
optional: false,
},
+ spinnerName: {
+ type: String,
+ optional: true,
+ },
hideLogo: {
type: Boolean,
optional: true,
diff --git a/models/users.js b/models/users.js
index 58cad3bf7..c1c9c7b91 100644
--- a/models/users.js
+++ b/models/users.js
@@ -164,7 +164,7 @@ Users.attachSchema(
},
'profile.showDesktopDragHandles': {
/**
- * does the user want to hide system messages?
+ * does the user want to show desktop drag handles?
*/
type: Boolean,
optional: true,
@@ -176,6 +176,13 @@ Users.attachSchema(
type: Boolean,
optional: true,
},
+ 'profile.cardMaximized': {
+ /**
+ * has user clicked maximize card?
+ */
+ type: Boolean,
+ optional: true,
+ },
'profile.hiddenSystemMessages': {
/**
* does the user want to hide system messages?
@@ -641,6 +648,11 @@ Users.helpers({
return profile.hiddenSystemMessages || false;
},
+ hasCardMaximized() {
+ const profile = this.profile || {};
+ return profile.cardMaximized || false;
+ },
+
hasHiddenMinicardLabelText() {
const profile = this.profile || {};
return profile.hiddenMinicardLabelText || false;
@@ -793,6 +805,14 @@ Users.mutations({
};
},
+ toggleCardMaximized(value = false) {
+ return {
+ $set: {
+ 'profile.cardMaximized': !value,
+ },
+ };
+ },
+
toggleLabelText(value = false) {
return {
$set: {
@@ -887,6 +907,10 @@ Meteor.methods({
const user = Meteor.user();
user.toggleSystem(user.hasHiddenSystemMessages());
},
+ toggleCardMaximized() {
+ const user = Meteor.user();
+ user.toggleCardMaximized(user.hasCardMaximized());
+ },
toggleMinicardLabelText() {
const user = Meteor.user();
user.toggleLabelText(user.hasHiddenMinicardLabelText());
@@ -952,7 +976,18 @@ if (Meteor.isServer) {
userOrgsArray,
userTeamsArray,
) {
+ check(fullname, String);
+ check(username, String);
+ check(initials, String);
+ check(password, String);
+ check(isAdmin, String);
+ check(isActive, String);
+ check(email, String);
+ check(importUsernames, Array);
+ check(userOrgsArray, Array);
+ check(userTeamsArray, Array);
if (Meteor.user() && Meteor.user().isAdmin) {
+<<<<<<< HEAD
check(fullname, String);
check(username, String);
check(initials, String);
@@ -964,6 +999,8 @@ if (Meteor.isServer) {
check(userOrgsArray, Array);
check(userTeamsArray, Array);
+=======
+>>>>>>> feature/250f95de
const nUsersWithUsername = Users.find({
username,
}).count();
@@ -1003,9 +1040,9 @@ if (Meteor.isServer) {
}
},
setUsername(username, userId) {
+ check(username, String);
+ check(userId, String);
if (Meteor.user() && Meteor.user().isAdmin) {
- check(username, String);
- check(userId, String);
const nUsersWithUsername = Users.find({
username,
}).count();
@@ -1021,11 +1058,12 @@ if (Meteor.isServer) {
}
},
setEmail(email, userId) {
+ check(email, String);
+ check(username, String);
if (Meteor.user() && Meteor.user().isAdmin) {
if (Array.isArray(email)) {
email = email.shift();
}
- check(email, String);
const existingUser = Users.findOne(
{
'emails.address': email,
@@ -1053,31 +1091,31 @@ if (Meteor.isServer) {
}
},
setUsernameAndEmail(username, email, userId) {
+ check(username, String);
+ check(email, String);
+ check(userId, String);
if (Meteor.user() && Meteor.user().isAdmin) {
- check(username, String);
if (Array.isArray(email)) {
email = email.shift();
}
- check(email, String);
- check(userId, String);
Meteor.call('setUsername', username, userId);
Meteor.call('setEmail', email, userId);
}
},
setPassword(newPassword, userId) {
+ check(userId, String);
+ check(newPassword, String);
if (Meteor.user() && Meteor.user().isAdmin) {
- check(userId, String);
- check(newPassword, String);
if (Meteor.user().isAdmin) {
Accounts.setPassword(userId, newPassword);
}
}
},
setEmailVerified(email, verified, userId) {
+ check(email, String);
+ check(verified, Boolean);
+ check(userId, String);
if (Meteor.user() && Meteor.user().isAdmin) {
- check(email, String);
- check(verified, Boolean);
- check(userId, String);
Users.update(userId, {
$set: {
emails: [
@@ -1091,9 +1129,9 @@ if (Meteor.isServer) {
}
},
setInitials(initials, userId) {
+ check(initials, String);
+ check(userId, String);
if (Meteor.user() && Meteor.user().isAdmin) {
- check(initials, String);
- check(userId, String);
Users.update(userId, {
$set: {
'profile.initials': initials,
diff --git a/package-lock.json b/package-lock.json
index 281baa4fa..3bb1163f3 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,6 +1,6 @@
{
"name": "wekan",
- "version": "v5.32.0",
+ "version": "v5.34.0",
"lockfileVersion": 2,
"requires": true,
"packages": {
diff --git a/package.json b/package.json
index ee8208d7b..3c7ec3af7 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "wekan",
- "version": "v5.32.0",
+ "version": "v5.34.0",
"description": "Open-Source kanban",
"private": true,
"repository": {
diff --git a/packages/wekan-accounts-lockout/CONTRIBUTING.md b/packages/wekan-accounts-lockout/CONTRIBUTING.md
new file mode 100644
index 000000000..c72e88f69
--- /dev/null
+++ b/packages/wekan-accounts-lockout/CONTRIBUTING.md
@@ -0,0 +1,25 @@
+# Contributing guide
+
+Want to contribute to Accounts-Lockout? Awesome!
+There are many ways you can contribute, see below.
+
+## Opening issues
+
+Open an issue to report bugs or to propose new features.
+
+- Reporting bugs: describe the bug as clearly as you can, including steps to reproduce, what happened and what you were expecting to happen. Also include browser version, OS and other related software's (npm, Node.js, etc) versions when applicable.
+
+- Proposing features: explain the proposed feature, what it should do, why it is useful, how users should use it. Give us as much info as possible so it will be easier to discuss, access and implement the proposed feature. When you're unsure about a certain aspect of the feature, feel free to leave it open for others to discuss and find an appropriate solution.
+
+## Proposing pull requests
+
+Pull requests are very welcome. Note that if you are going to propose drastic changes, be sure to open an issue for discussion first, to make sure that your PR will be accepted before you spend effort coding it.
+
+Fork the Accounts-Lockout repository, clone it locally and create a branch for your proposed bug fix or new feature. Avoid working directly on the master branch.
+
+Implement your bug fix or feature, write tests to cover it and make sure all tests are passing (run a final `npm test` to make sure everything is correct). Then commit your changes, push your bug fix/feature branch to the origin (your forked repo) and open a pull request to the upstream (the repository you originally forked)'s master branch.
+
+## Documentation
+
+Documentation is extremely important and takes a fair deal of time and effort to write and keep updated.
+Please submit any and all improvements you can make to the repository's docs.
diff --git a/packages/wekan-accounts-lockout/LICENSE b/packages/wekan-accounts-lockout/LICENSE
new file mode 100644
index 000000000..a5298594c
--- /dev/null
+++ b/packages/wekan-accounts-lockout/LICENSE
@@ -0,0 +1,21 @@
+The MIT License (MIT)
+
+Copyright (c) 2017 Lucas Antoniassi de Paiva
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/packages/wekan-accounts-lockout/README.md b/packages/wekan-accounts-lockout/README.md
new file mode 100644
index 000000000..8d9c6897c
--- /dev/null
+++ b/packages/wekan-accounts-lockout/README.md
@@ -0,0 +1,126 @@
+# Meteor - Accounts - Lockout
+
+[](https://travis-ci.org/LucasAntoniassi/meteor-accounts-lockout)
+[](https://www.codacy.com/app/lucasantoniassi/meteor-accounts-lockout?utm_source=github.com&utm_medium=referral&utm_content=LucasAntoniassi/meteor-accounts-lockout&utm_campaign=Badge_Grade)
+[](https://codeclimate.com/github/LucasAntoniassi/meteor-accounts-lockout)
+
+## What it is
+
+Seamless Meteor apps accounts protection from password brute-force attacks.
+Users won't notice it. Hackers shall not pass.
+
+
+
+## Installation
+
+```
+meteor add lucasantoniassi:accounts-lockout
+```
+
+## Usage via ES6 import
+
+```javascript
+// server
+import { AccountsLockout } from 'meteor/lucasantoniassi:accounts-lockout';
+```
+
+## How to use
+
+Default settings:
+
+```javascript
+ "knownUsers": {
+ "failuresBeforeLockout": 3, // positive integer greater than 0
+ "lockoutPeriod": 60, // in seconds
+ "failureWindow": 10 // in seconds
+ },
+ "unknownUsers": {
+ "failuresBeforeLockout": 3, // positive integer greater than 0
+ "lockoutPeriod": 60, // in seconds
+ "failureWindow": 10 // in seconds
+ }
+```
+
+`knownUsers` are users where already belongs to your `Meteor.users` collections,
+these rules are applied if they attempt to login with an incorrect password but a know email.
+
+`unknownUsers` are users where **not** belongs to your `Meteor.users` collections,
+these rules are applied if they attempt to login with a unknown email.
+
+`failuresBeforeLockout` should be a positive integer greater than 0.
+
+`lockoutPeriod` should be in seconds.
+
+`failureWindow` should be in seconds.
+
+If the `default` is nice to you, you can do that.
+
+```javascript
+(new AccountsLockout()).startup();
+```
+
+You can overwrite passing an `object` as argument.
+
+```javascript
+(new AccountsLockout({
+ knownUsers: {
+ failuresBeforeLockout: 3,
+ lockoutPeriod: 60,
+ failureWindow: 15,
+ },
+ unknownUsers: {
+ failuresBeforeLockout: 3,
+ lockoutPeriod: 60,
+ failureWindow: 15,
+ },
+})).startup();
+```
+
+If you prefer, you can pass a `function` as argument.
+
+```javascript
+const knownUsersRules = (user) => {
+ // apply some logic with this user
+ return {
+ failuresBeforeLockout,
+ lockoutPeriod,
+ failureWindow,
+ };
+};
+
+const unknownUsersRules = (connection) => {
+ // apply some logic with this connection
+ return {
+ failuresBeforeLockout,
+ lockoutPeriod,
+ failureWindow,
+ };
+};
+
+(new AccountsLockout({
+ knownUsers: knownUsersRules,
+ unknownUsers: unknownUsersRules,
+})).startup();
+```
+
+If you prefer, you can use `Meteor.settings`. It will overwrite any previous case.
+
+```javascript
+"accounts-lockout": {
+ "knownUsers": {
+ "failuresBeforeLockout": 3,
+ "lockoutPeriod": 60,
+ "failureWindow": 10
+ },
+ "unknownUsers": {
+ "failuresBeforeLockout": 3,
+ "lockoutPeriod": 60,
+ "failureWindow": 10
+ }
+}
+```
+
+## License
+
+This package is open-sourced software licensed under the [MIT license](http://opensource.org/licenses/MIT).
+
diff --git a/packages/wekan-accounts-lockout/accounts-lockout.js b/packages/wekan-accounts-lockout/accounts-lockout.js
new file mode 100644
index 000000000..0c781c802
--- /dev/null
+++ b/packages/wekan-accounts-lockout/accounts-lockout.js
@@ -0,0 +1,5 @@
+import AccountsLockout from './src/accountsLockout';
+
+const Name = 'wekan-accounts-lockout';
+
+export { Name, AccountsLockout };
diff --git a/packages/wekan-accounts-lockout/package.js b/packages/wekan-accounts-lockout/package.js
new file mode 100644
index 000000000..e2bda76a6
--- /dev/null
+++ b/packages/wekan-accounts-lockout/package.js
@@ -0,0 +1,18 @@
+/* global Package */
+
+Package.describe({
+ name: 'wekan-accounts-lockout',
+ version: '1.0.0',
+ summary: 'Meteor package for locking user accounts and stopping brute force attacks',
+ git: 'https://github.com/lucasantoniassi/meteor-accounts-lockout.git',
+ documentation: 'README.md',
+});
+
+Package.onUse((api) => {
+ api.versionsFrom('1.4.2.3');
+ api.use([
+ 'ecmascript',
+ 'accounts-password',
+ ]);
+ api.mainModule('accounts-lockout.js');
+});
diff --git a/packages/wekan-accounts-lockout/package.json b/packages/wekan-accounts-lockout/package.json
new file mode 100644
index 000000000..bbff88655
--- /dev/null
+++ b/packages/wekan-accounts-lockout/package.json
@@ -0,0 +1,4 @@
+{
+ "name": "wekan-accounts-lockout",
+ "private": true
+}
diff --git a/packages/wekan-accounts-lockout/src/accountsLockout.js b/packages/wekan-accounts-lockout/src/accountsLockout.js
new file mode 100644
index 000000000..8a1f05ea1
--- /dev/null
+++ b/packages/wekan-accounts-lockout/src/accountsLockout.js
@@ -0,0 +1,29 @@
+import KnownUser from './knownUser';
+import UnknownUser from './unknownUser';
+
+class AccountsLockout {
+ constructor({
+ knownUsers = {
+ failuresBeforeLockout: 3,
+ lockoutPeriod: 60,
+ failureWindow: 15,
+ },
+ unknownUsers = {
+ failuresBeforeLockout: 3,
+ lockoutPeriod: 60,
+ failureWindow: 15,
+ },
+ }) {
+ this.settings = {
+ knownUsers,
+ unknownUsers,
+ };
+ }
+
+ startup() {
+ (new KnownUser(this.settings.knownUsers)).startup();
+ (new UnknownUser(this.settings.unknownUsers)).startup();
+ }
+}
+
+export default AccountsLockout;
diff --git a/packages/wekan-accounts-lockout/src/accountsLockoutCollection.js b/packages/wekan-accounts-lockout/src/accountsLockoutCollection.js
new file mode 100644
index 000000000..9a885a0f7
--- /dev/null
+++ b/packages/wekan-accounts-lockout/src/accountsLockoutCollection.js
@@ -0,0 +1,3 @@
+import { Meteor } from 'meteor/meteor';
+
+export default new Meteor.Collection('AccountsLockout.Connections');
diff --git a/packages/wekan-accounts-lockout/src/knownUser.js b/packages/wekan-accounts-lockout/src/knownUser.js
new file mode 100644
index 000000000..81558e1b8
--- /dev/null
+++ b/packages/wekan-accounts-lockout/src/knownUser.js
@@ -0,0 +1,321 @@
+/* eslint-disable no-underscore-dangle */
+
+import { Meteor } from 'meteor/meteor';
+import { Accounts } from 'meteor/accounts-base';
+
+class KnownUser {
+ constructor(settings) {
+ this.unchangedSettings = settings;
+ this.settings = settings;
+ }
+
+ startup() {
+ if (!(this.unchangedSettings instanceof Function)) {
+ this.updateSettings();
+ }
+ this.scheduleUnlocksForLockedAccounts();
+ KnownUser.unlockAccountsIfLockoutAlreadyExpired();
+ this.hookIntoAccounts();
+ }
+
+ updateSettings() {
+ const settings = KnownUser.knownUsers();
+ if (settings) {
+ settings.forEach(function updateSetting({ key, value }) {
+ this.settings[key] = value;
+ });
+ }
+ this.validateSettings();
+ }
+
+ validateSettings() {
+ if (
+ !this.settings.failuresBeforeLockout ||
+ this.settings.failuresBeforeLockout < 0
+ ) {
+ throw new Error('"failuresBeforeLockout" is not positive integer');
+ }
+ if (
+ !this.settings.lockoutPeriod ||
+ this.settings.lockoutPeriod < 0
+ ) {
+ throw new Error('"lockoutPeriod" is not positive integer');
+ }
+ if (
+ !this.settings.failureWindow ||
+ this.settings.failureWindow < 0
+ ) {
+ throw new Error('"failureWindow" is not positive integer');
+ }
+ }
+
+ scheduleUnlocksForLockedAccounts() {
+ const lockedAccountsCursor = Meteor.users.find(
+ {
+ 'services.accounts-lockout.unlockTime': {
+ $gt: Number(new Date()),
+ },
+ },
+ {
+ fields: {
+ 'services.accounts-lockout.unlockTime': 1,
+ },
+ },
+ );
+ const currentTime = Number(new Date());
+ lockedAccountsCursor.forEach((user) => {
+ let lockDuration = KnownUser.unlockTime(user) - currentTime;
+ if (lockDuration >= this.settings.lockoutPeriod) {
+ lockDuration = this.settings.lockoutPeriod * 1000;
+ }
+ if (lockDuration <= 1) {
+ lockDuration = 1;
+ }
+ Meteor.setTimeout(
+ KnownUser.unlockAccount.bind(null, user._id),
+ lockDuration,
+ );
+ });
+ }
+
+ static unlockAccountsIfLockoutAlreadyExpired() {
+ const currentTime = Number(new Date());
+ const query = {
+ 'services.accounts-lockout.unlockTime': {
+ $lt: currentTime,
+ },
+ };
+ const data = {
+ $unset: {
+ 'services.accounts-lockout.unlockTime': 0,
+ 'services.accounts-lockout.failedAttempts': 0,
+ },
+ };
+ Meteor.users.update(query, data);
+ }
+
+ hookIntoAccounts() {
+ Accounts.validateLoginAttempt(this.validateLoginAttempt.bind(this));
+ Accounts.onLogin(KnownUser.onLogin);
+ }
+
+
+ validateLoginAttempt(loginInfo) {
+ if (
+ // don't interrupt non-password logins
+ loginInfo.type !== 'password' ||
+ loginInfo.user === undefined ||
+ // Don't handle errors unless they are due to incorrect password
+ (loginInfo.error !== undefined && loginInfo.error.reason !== 'Incorrect password')
+ ) {
+ return loginInfo.allowed;
+ }
+
+ // If there was no login error and the account is NOT locked, don't interrupt
+ const unlockTime = KnownUser.unlockTime(loginInfo.user);
+ if (loginInfo.error === undefined && unlockTime === 0) {
+ return loginInfo.allowed;
+ }
+
+ if (this.unchangedSettings instanceof Function) {
+ this.settings = this.unchangedSettings(loginInfo.user);
+ this.validateSettings();
+ }
+
+ const userId = loginInfo.user._id;
+ let failedAttempts = 1 + KnownUser.failedAttempts(loginInfo.user);
+ const firstFailedAttempt = KnownUser.firstFailedAttempt(loginInfo.user);
+ const currentTime = Number(new Date());
+
+ const canReset = (currentTime - firstFailedAttempt) > (1000 * this.settings.failureWindow);
+ if (canReset) {
+ failedAttempts = 1;
+ KnownUser.resetAttempts(failedAttempts, userId);
+ }
+
+ const canIncrement = failedAttempts < this.settings.failuresBeforeLockout;
+ if (canIncrement) {
+ KnownUser.incrementAttempts(failedAttempts, userId);
+ }
+
+ const maxAttemptsAllowed = this.settings.failuresBeforeLockout;
+ const attemptsRemaining = maxAttemptsAllowed - failedAttempts;
+ if (unlockTime > currentTime) {
+ let duration = unlockTime - currentTime;
+ duration = Math.ceil(duration / 1000);
+ duration = duration > 1 ? duration : 1;
+ KnownUser.tooManyAttempts(duration);
+ }
+ if (failedAttempts === maxAttemptsAllowed) {
+ this.setNewUnlockTime(failedAttempts, userId);
+
+ let duration = this.settings.lockoutPeriod;
+ duration = Math.ceil(duration);
+ duration = duration > 1 ? duration : 1;
+ return KnownUser.tooManyAttempts(duration);
+ }
+ return KnownUser.incorrectPassword(
+ failedAttempts,
+ maxAttemptsAllowed,
+ attemptsRemaining,
+ );
+ }
+
+ static resetAttempts(
+ failedAttempts,
+ userId,
+ ) {
+ const currentTime = Number(new Date());
+ const query = { _id: userId };
+ const data = {
+ $set: {
+ 'services.accounts-lockout.failedAttempts': failedAttempts,
+ 'services.accounts-lockout.lastFailedAttempt': currentTime,
+ 'services.accounts-lockout.firstFailedAttempt': currentTime,
+ },
+ };
+ Meteor.users.update(query, data);
+ }
+
+ static incrementAttempts(
+ failedAttempts,
+ userId,
+ ) {
+ const currentTime = Number(new Date());
+ const query = { _id: userId };
+ const data = {
+ $set: {
+ 'services.accounts-lockout.failedAttempts': failedAttempts,
+ 'services.accounts-lockout.lastFailedAttempt': currentTime,
+ },
+ };
+ Meteor.users.update(query, data);
+ }
+
+ setNewUnlockTime(
+ failedAttempts,
+ userId,
+ ) {
+ const currentTime = Number(new Date());
+ const newUnlockTime = (1000 * this.settings.lockoutPeriod) + currentTime;
+ const query = { _id: userId };
+ const data = {
+ $set: {
+ 'services.accounts-lockout.failedAttempts': failedAttempts,
+ 'services.accounts-lockout.lastFailedAttempt': currentTime,
+ 'services.accounts-lockout.unlockTime': newUnlockTime,
+ },
+ };
+ Meteor.users.update(query, data);
+ Meteor.setTimeout(
+ KnownUser.unlockAccount.bind(null, userId),
+ this.settings.lockoutPeriod * 1000,
+ );
+ }
+
+ static onLogin(loginInfo) {
+ if (loginInfo.type !== 'password') {
+ return;
+ }
+ const userId = loginInfo.user._id;
+ const query = { _id: userId };
+ const data = {
+ $unset: {
+ 'services.accounts-lockout.unlockTime': 0,
+ 'services.accounts-lockout.failedAttempts': 0,
+ },
+ };
+ Meteor.users.update(query, data);
+ }
+
+ static incorrectPassword(
+ failedAttempts,
+ maxAttemptsAllowed,
+ attemptsRemaining,
+ ) {
+ throw new Meteor.Error(
+ 403,
+ 'Incorrect password',
+ JSON.stringify({
+ message: 'Incorrect password',
+ failedAttempts,
+ maxAttemptsAllowed,
+ attemptsRemaining,
+ }),
+ );
+ }
+
+ static tooManyAttempts(duration) {
+ throw new Meteor.Error(
+ 403,
+ 'Too many attempts',
+ JSON.stringify({
+ message: 'Wrong passwords were submitted too many times. Account is locked for a while.',
+ duration,
+ }),
+ );
+ }
+
+ static knownUsers() {
+ let knownUsers;
+ try {
+ knownUsers = Meteor.settings['accounts-lockout'].knownUsers;
+ } catch (e) {
+ knownUsers = false;
+ }
+ return knownUsers || false;
+ }
+
+ static unlockTime(user) {
+ let unlockTime;
+ try {
+ unlockTime = user.services['accounts-lockout'].unlockTime;
+ } catch (e) {
+ unlockTime = 0;
+ }
+ return unlockTime || 0;
+ }
+
+ static failedAttempts(user) {
+ let failedAttempts;
+ try {
+ failedAttempts = user.services['accounts-lockout'].failedAttempts;
+ } catch (e) {
+ failedAttempts = 0;
+ }
+ return failedAttempts || 0;
+ }
+
+ static lastFailedAttempt(user) {
+ let lastFailedAttempt;
+ try {
+ lastFailedAttempt = user.services['accounts-lockout'].lastFailedAttempt;
+ } catch (e) {
+ lastFailedAttempt = 0;
+ }
+ return lastFailedAttempt || 0;
+ }
+
+ static firstFailedAttempt(user) {
+ let firstFailedAttempt;
+ try {
+ firstFailedAttempt = user.services['accounts-lockout'].firstFailedAttempt;
+ } catch (e) {
+ firstFailedAttempt = 0;
+ }
+ return firstFailedAttempt || 0;
+ }
+
+ static unlockAccount(userId) {
+ const query = { _id: userId };
+ const data = {
+ $unset: {
+ 'services.accounts-lockout.unlockTime': 0,
+ 'services.accounts-lockout.failedAttempts': 0,
+ },
+ };
+ Meteor.users.update(query, data);
+ }
+}
+
+export default KnownUser;
diff --git a/packages/wekan-accounts-lockout/src/unknownUser.js b/packages/wekan-accounts-lockout/src/unknownUser.js
new file mode 100644
index 000000000..443507c82
--- /dev/null
+++ b/packages/wekan-accounts-lockout/src/unknownUser.js
@@ -0,0 +1,329 @@
+import { Meteor } from 'meteor/meteor';
+import { Accounts } from 'meteor/accounts-base';
+import _AccountsLockoutCollection from './accountsLockoutCollection';
+
+class UnknownUser {
+ constructor(
+ settings,
+ {
+ AccountsLockoutCollection = _AccountsLockoutCollection,
+ } = {},
+ ) {
+ this.AccountsLockoutCollection = AccountsLockoutCollection;
+ this.settings = settings;
+ }
+
+ startup() {
+ if (!(this.settings instanceof Function)) {
+ this.updateSettings();
+ }
+ this.scheduleUnlocksForLockedAccounts();
+ this.unlockAccountsIfLockoutAlreadyExpired();
+ this.hookIntoAccounts();
+ }
+
+ updateSettings() {
+ const settings = UnknownUser.unknownUsers();
+ if (settings) {
+ settings.forEach(function updateSetting({ key, value }) {
+ this.settings[key] = value;
+ });
+ }
+ this.validateSettings();
+ }
+
+ validateSettings() {
+ if (
+ !this.settings.failuresBeforeLockout ||
+ this.settings.failuresBeforeLockout < 0
+ ) {
+ throw new Error('"failuresBeforeLockout" is not positive integer');
+ }
+ if (
+ !this.settings.lockoutPeriod ||
+ this.settings.lockoutPeriod < 0
+ ) {
+ throw new Error('"lockoutPeriod" is not positive integer');
+ }
+ if (
+ !this.settings.failureWindow ||
+ this.settings.failureWindow < 0
+ ) {
+ throw new Error('"failureWindow" is not positive integer');
+ }
+ }
+
+ scheduleUnlocksForLockedAccounts() {
+ const lockedAccountsCursor = this.AccountsLockoutCollection.find(
+ {
+ 'services.accounts-lockout.unlockTime': {
+ $gt: Number(new Date()),
+ },
+ },
+ {
+ fields: {
+ 'services.accounts-lockout.unlockTime': 1,
+ },
+ },
+ );
+ const currentTime = Number(new Date());
+ lockedAccountsCursor.forEach((connection) => {
+ let lockDuration = this.unlockTime(connection) - currentTime;
+ if (lockDuration >= this.settings.lockoutPeriod) {
+ lockDuration = this.settings.lockoutPeriod * 1000;
+ }
+ if (lockDuration <= 1) {
+ lockDuration = 1;
+ }
+ Meteor.setTimeout(
+ this.unlockAccount.bind(this, connection.clientAddress),
+ lockDuration,
+ );
+ });
+ }
+
+ unlockAccountsIfLockoutAlreadyExpired() {
+ const currentTime = Number(new Date());
+ const query = {
+ 'services.accounts-lockout.unlockTime': {
+ $lt: currentTime,
+ },
+ };
+ const data = {
+ $unset: {
+ 'services.accounts-lockout.unlockTime': 0,
+ 'services.accounts-lockout.failedAttempts': 0,
+ },
+ };
+ this.AccountsLockoutCollection.update(query, data);
+ }
+
+ hookIntoAccounts() {
+ Accounts.validateLoginAttempt(this.validateLoginAttempt.bind(this));
+ Accounts.onLogin(this.onLogin.bind(this));
+ }
+
+ validateLoginAttempt(loginInfo) {
+ // don't interrupt non-password logins
+ if (
+ loginInfo.type !== 'password' ||
+ loginInfo.user !== undefined ||
+ loginInfo.error === undefined ||
+ loginInfo.error.reason !== 'User not found'
+ ) {
+ return loginInfo.allowed;
+ }
+
+ if (this.settings instanceof Function) {
+ this.settings = this.settings(loginInfo.connection);
+ this.validateSettings();
+ }
+
+ const clientAddress = loginInfo.connection.clientAddress;
+ const unlockTime = this.unlockTime(loginInfo.connection);
+ let failedAttempts = 1 + this.failedAttempts(loginInfo.connection);
+ const firstFailedAttempt = this.firstFailedAttempt(loginInfo.connection);
+ const currentTime = Number(new Date());
+
+ const canReset = (currentTime - firstFailedAttempt) > (1000 * this.settings.failureWindow);
+ if (canReset) {
+ failedAttempts = 1;
+ this.resetAttempts(failedAttempts, clientAddress);
+ }
+
+ const canIncrement = failedAttempts < this.settings.failuresBeforeLockout;
+ if (canIncrement) {
+ this.incrementAttempts(failedAttempts, clientAddress);
+ }
+
+ const maxAttemptsAllowed = this.settings.failuresBeforeLockout;
+ const attemptsRemaining = maxAttemptsAllowed - failedAttempts;
+ if (unlockTime > currentTime) {
+ let duration = unlockTime - currentTime;
+ duration = Math.ceil(duration / 1000);
+ duration = duration > 1 ? duration : 1;
+ UnknownUser.tooManyAttempts(duration);
+ }
+ if (failedAttempts === maxAttemptsAllowed) {
+ this.setNewUnlockTime(failedAttempts, clientAddress);
+
+ let duration = this.settings.lockoutPeriod;
+ duration = Math.ceil(duration);
+ duration = duration > 1 ? duration : 1;
+ return UnknownUser.tooManyAttempts(duration);
+ }
+ return UnknownUser.userNotFound(
+ failedAttempts,
+ maxAttemptsAllowed,
+ attemptsRemaining,
+ );
+ }
+
+ resetAttempts(
+ failedAttempts,
+ clientAddress,
+ ) {
+ const currentTime = Number(new Date());
+ const query = { clientAddress };
+ const data = {
+ $set: {
+ 'services.accounts-lockout.failedAttempts': failedAttempts,
+ 'services.accounts-lockout.lastFailedAttempt': currentTime,
+ 'services.accounts-lockout.firstFailedAttempt': currentTime,
+ },
+ };
+ this.AccountsLockoutCollection.upsert(query, data);
+ }
+
+ incrementAttempts(
+ failedAttempts,
+ clientAddress,
+ ) {
+ const currentTime = Number(new Date());
+ const query = { clientAddress };
+ const data = {
+ $set: {
+ 'services.accounts-lockout.failedAttempts': failedAttempts,
+ 'services.accounts-lockout.lastFailedAttempt': currentTime,
+ },
+ };
+ this.AccountsLockoutCollection.upsert(query, data);
+ }
+
+ setNewUnlockTime(
+ failedAttempts,
+ clientAddress,
+ ) {
+ const currentTime = Number(new Date());
+ const newUnlockTime = (1000 * this.settings.lockoutPeriod) + currentTime;
+ const query = { clientAddress };
+ const data = {
+ $set: {
+ 'services.accounts-lockout.failedAttempts': failedAttempts,
+ 'services.accounts-lockout.lastFailedAttempt': currentTime,
+ 'services.accounts-lockout.unlockTime': newUnlockTime,
+ },
+ };
+ this.AccountsLockoutCollection.upsert(query, data);
+ Meteor.setTimeout(
+ this.unlockAccount.bind(this, clientAddress),
+ this.settings.lockoutPeriod * 1000,
+ );
+ }
+
+ onLogin(loginInfo) {
+ if (loginInfo.type !== 'password') {
+ return;
+ }
+ const clientAddress = loginInfo.connection.clientAddress;
+ const query = { clientAddress };
+ const data = {
+ $unset: {
+ 'services.accounts-lockout.unlockTime': 0,
+ 'services.accounts-lockout.failedAttempts': 0,
+ },
+ };
+ this.AccountsLockoutCollection.update(query, data);
+ }
+
+ static userNotFound(
+ failedAttempts,
+ maxAttemptsAllowed,
+ attemptsRemaining,
+ ) {
+ throw new Meteor.Error(
+ 403,
+ 'User not found',
+ JSON.stringify({
+ message: 'User not found',
+ failedAttempts,
+ maxAttemptsAllowed,
+ attemptsRemaining,
+ }),
+ );
+ }
+
+ static tooManyAttempts(duration) {
+ throw new Meteor.Error(
+ 403,
+ 'Too many attempts',
+ JSON.stringify({
+ message: 'Wrong emails were submitted too many times. Account is locked for a while.',
+ duration,
+ }),
+ );
+ }
+
+ static unknownUsers() {
+ let unknownUsers;
+ try {
+ unknownUsers = Meteor.settings['accounts-lockout'].unknownUsers;
+ } catch (e) {
+ unknownUsers = false;
+ }
+ return unknownUsers || false;
+ }
+
+ findOneByConnection(connection) {
+ return this.AccountsLockoutCollection.findOne({
+ clientAddress: connection.clientAddress,
+ });
+ }
+
+ unlockTime(connection) {
+ connection = this.findOneByConnection(connection);
+ let unlockTime;
+ try {
+ unlockTime = connection.services['accounts-lockout'].unlockTime;
+ } catch (e) {
+ unlockTime = 0;
+ }
+ return unlockTime || 0;
+ }
+
+ failedAttempts(connection) {
+ connection = this.findOneByConnection(connection);
+ let failedAttempts;
+ try {
+ failedAttempts = connection.services['accounts-lockout'].failedAttempts;
+ } catch (e) {
+ failedAttempts = 0;
+ }
+ return failedAttempts || 0;
+ }
+
+ lastFailedAttempt(connection) {
+ connection = this.findOneByConnection(connection);
+ let lastFailedAttempt;
+ try {
+ lastFailedAttempt = connection.services['accounts-lockout'].lastFailedAttempt;
+ } catch (e) {
+ lastFailedAttempt = 0;
+ }
+ return lastFailedAttempt || 0;
+ }
+
+ firstFailedAttempt(connection) {
+ connection = this.findOneByConnection(connection);
+ let firstFailedAttempt;
+ try {
+ firstFailedAttempt = connection.services['accounts-lockout'].firstFailedAttempt;
+ } catch (e) {
+ firstFailedAttempt = 0;
+ }
+ return firstFailedAttempt || 0;
+ }
+
+ unlockAccount(clientAddress) {
+ const query = { clientAddress };
+ const data = {
+ $unset: {
+ 'services.accounts-lockout.unlockTime': 0,
+ 'services.accounts-lockout.failedAttempts': 0,
+ },
+ };
+ this.AccountsLockoutCollection.update(query, data);
+ }
+}
+
+export default UnknownUser;
diff --git a/packages/wekan-oidc/oidc_client.js b/packages/wekan-oidc/oidc_client.js
index 6b859f11e..6da9d9f0e 100644
--- a/packages/wekan-oidc/oidc_client.js
+++ b/packages/wekan-oidc/oidc_client.js
@@ -32,8 +32,6 @@ Oidc.requestCredential = function (options, credentialRequestCompleteCallback) {
if (config.loginStyle && config.loginStyle == 'popup') {
options.display = 'popup';
- } else if (config.loginStyle && config.loginStyle == 'redirect') {
- options.display = 'redirect';
}
var loginUrl = config.serverUrl + config.authorizationEndpoint;
@@ -52,28 +50,18 @@ Oidc.requestCredential = function (options, credentialRequestCompleteCallback) {
//console.log('XXX: loginURL: ' + loginUrl)
- if (config.loginStyle && config.loginStyle == 'popup') {
- options.popupOptions = options.popupOptions || {};
- var popupOptions = {
- width: options.popupOptions.width || 320,
- height: options.popupOptions.height || 450
- };
+ options.popupOptions = options.popupOptions || {};
+ var popupOptions = {
+ width: options.popupOptions.width || 320,
+ height: options.popupOptions.height || 450
+ };
- OAuth.launchLogin({
- loginService: 'oidc',
- loginStyle: loginStyle,
- loginUrl: loginUrl,
- credentialRequestCompleteCallback: credentialRequestCompleteCallback,
- credentialToken: credentialToken,
- popupOptions: popupOptions,
- });
- } else if (config.loginStyle && config.loginStyle == 'redirect') {
- OAuth.launchLogin({
- loginService: 'oidc',
- loginStyle: loginStyle,
- loginUrl: loginUrl,
- credentialRequestCompleteCallback: credentialRequestCompleteCallback,
- credentialToken: credentialToken,
- });
- }
+ OAuth.launchLogin({
+ loginService: 'oidc',
+ loginStyle: loginStyle,
+ loginUrl: loginUrl,
+ credentialRequestCompleteCallback: credentialRequestCompleteCallback,
+ credentialToken: credentialToken,
+ popupOptions: popupOptions,
+ });
};
diff --git a/public/api/wekan.html b/public/api/wekan.html
index abfb472d5..da2758133 100644
--- a/public/api/wekan.html
+++ b/public/api/wekan.html
@@ -7,7 +7,7 @@
- Wekan REST API v5.32
+ Wekan REST API v5.34
@@ -1488,6 +1488,8 @@ var n=this.pipeline.run(e.tokenizer(t)),r=new e.Vector,i=[],o=this._fields.reduc
+
+
@@ -1551,7 +1553,7 @@ var n=this.pipeline.run(e.tokenizer(t)),r=new e.Vector,i=[],o=this._fields.reduc
-
- Wekan REST API v5.32
+ Wekan REST API v5.34
@@ -2079,6 +2081,16 @@ var n=this.pipeline.run(e.tokenizer(t)),r=new e.Vector,i=[],o=this._fields.reduc
+ -
+ UsersOrgs
+
+
+
+ -
+ UsersTeams
+
+
+
-
UsersEmails
@@ -2104,7 +2116,7 @@ var n=this.pipeline.run(e.tokenizer(t)),r=new e.Vector,i=[],o=this._fields.reduc
-
Wekan REST API v5.32
+
Wekan REST API v5.34
Scroll down for code samples, example requests and responses. Select a language for code samples from the tabs above or the mobile navigation menu.
@@ -3522,6 +3534,7 @@ System.out.println(response.toString());
"allowsAssignee":
true,
"allowsMembers":
true,
"allowsRequestedBy":
true,
+
"allowsCardSortingByNumber":
true,
"allowsAssignedBy":
true,
"allowsReceivedDate":
true,
"allowsStartDate":
true,
@@ -15959,6 +15972,18 @@ System.out.println(response.toString());
{
"username": "string",
+ "orgs": [
+ {
+ "orgId": "string",
+ "orgDisplayName": "string"
+ }
+ ],
+ "teams": [
+ {
+ "teamId": "string",
+ "teamDisplayName": "string"
+ }
+ ],
"emails": [
{
"address": "string",
@@ -16008,8 +16033,7 @@ System.out.println(response.toString());
"loginDisabled": true,
"authenticationMethod": "string",
"sessionData": {
- "totalHits": 0,
- "lastHit": 0
+ "totalHits": 0
},
"importUsernames": [
"string"
@@ -16700,6 +16724,18 @@ System.out.println(response.toString());
{
"username": "string",
+ "orgs": [
+ {
+ "orgId": "string",
+ "orgDisplayName": "string"
+ }
+ ],
+ "teams": [
+ {
+ "teamId": "string",
+ "teamDisplayName": "string"
+ }
+ ],
"emails": [
{
"address": "string",
@@ -16749,8 +16785,7 @@ System.out.println(response.toString());
"loginDisabled": true,
"authenticationMethod": "string",
"sessionData": {
- "totalHits": 0,
- "lastHit": 0
+ "totalHits": 0
},
"importUsernames": [
"string"
@@ -18275,6 +18310,7 @@ UserSecurity
"allowsAssignee": true,
"allowsMembers": true,
"allowsRequestedBy": true,
+ "allowsCardSortingByNumber": true,
"allowsAssignedBy": true,
"allowsReceivedDate": true,
"allowsStartDate": true,
@@ -18501,6 +18537,13 @@ UserSecurity
| Does the board allows requested by? |
+| allowsCardSortingByNumber |
+boolean |
+true |
+none |
+Does the board allows card sorting by number? |
+
+
| allowsAssignedBy |
boolean |
true |
@@ -20712,6 +20755,18 @@ UserSecurity
{
"username": "string",
+ "orgs": [
+ {
+ "orgId": "string",
+ "orgDisplayName": "string"
+ }
+ ],
+ "teams": [
+ {
+ "teamId": "string",
+ "teamDisplayName": "string"
+ }
+ ],
"emails": [
{
"address": "string",
@@ -20761,8 +20816,7 @@ UserSecurity
"loginDisabled": true,
"authenticationMethod": "string",
"sessionData": {
- "totalHits": 0,
- "lastHit": 0
+ "totalHits": 0
},
"importUsernames": [
"string"
@@ -20791,6 +20845,20 @@ UserSecurity
| the username of the user |
+| orgs |
+[UsersOrgs]¦null |
+false |
+none |
+the list of organizations that a user belongs to |
+
+
+| teams |
+[UsersTeams]¦null |
+false |
+none |
+the list of teams that a user belongs to |
+
+
| emails |
[UsersEmails]¦null |
false |
@@ -21131,8 +21199,7 @@ UserSecurity
{
- "totalHits": 0,
- "lastHit": 0
+ "totalHits": 0
}
@@ -21153,14 +21220,85 @@ UserSecurity
number |
false |
none |
-Total hits from last search |
+Total hits from last searchquery['members.userId'] = Meteor.userId(); last hit that was returned |
+
+
+
+UsersOrgs
+
+
+
+
+{
+ "orgId": "string",
+ "orgDisplayName": "string"
+}
+
+
+Properties
+
+
+
+| Name |
+Type |
+Required |
+Restrictions |
+Description |
+
+
+
+
+| orgId |
+string |
+true |
+none |
+The uniq ID of the organization |
-| lastHit |
-number |
-false |
+orgDisplayName |
+string |
+true |
none |
-last hit that was returned |
+The display name of the organization |
+
+
+
+UsersTeams
+
+
+
+
+{
+ "teamId": "string",
+ "teamDisplayName": "string"
+}
+
+
+Properties
+
+
+
+| Name |
+Type |
+Required |
+Restrictions |
+Description |
+
+
+
+
+| teamId |
+string |
+true |
+none |
+The uniq ID of the team |
+
+
+| teamDisplayName |
+string |
+true |
+none |
+The display name of the team |
@@ -21175,7 +21313,7 @@ UserSecurity
}
-Properties
+Properties
@@ -21214,7 +21352,7 @@ UserSecurity
}
-Properties
+Properties
@@ -21265,6 +21403,8 @@ UserSecurity
+
+
diff --git a/public/api/wekan.yml b/public/api/wekan.yml
index b06a9bc0a..1c4d703d3 100644
--- a/public/api/wekan.yml
+++ b/public/api/wekan.yml
@@ -1,7 +1,7 @@
swagger: '2.0'
info:
title: Wekan REST API
- version: v5.32
+ version: v5.34
description: |
The REST API allows you to control and extend Wekan with ease.
@@ -2780,6 +2780,10 @@ definitions:
description: |
Does the board allows requested by?
type: boolean
+ allowsCardSortingByNumber:
+ description: |
+ Does the board allows card sorting by number?
+ type: boolean
allowsAssignedBy:
description: |
Does the board allows requested by?
@@ -2876,6 +2880,7 @@ definitions:
- allowsAssignee
- allowsMembers
- allowsRequestedBy
+ - allowsCardSortingByNumber
- allowsAssignedBy
- allowsReceivedDate
- allowsStartDate
@@ -3738,6 +3743,20 @@ definitions:
the username of the user
type: string
x-nullable: true
+ orgs:
+ description: |
+ the list of organizations that a user belongs to
+ type: array
+ items:
+ $ref: "#/definitions/UsersOrgs"
+ x-nullable: true
+ teams:
+ description: |
+ the list of teams that a user belongs to
+ type: array
+ items:
+ $ref: "#/definitions/UsersTeams"
+ x-nullable: true
emails:
description: |
the list of emails attached to a user
@@ -3921,12 +3940,37 @@ definitions:
properties:
totalHits:
description: |
- Total hits from last search
- type: number
- lastHit:
- description: |
+ Total hits from last searchquery['members.userId'] = Meteor.userId();
last hit that was returned
type: number
+ UsersOrgs:
+ type: object
+ properties:
+ orgId:
+ description: |
+ The uniq ID of the organization
+ type: string
+ orgDisplayName:
+ description: |
+ The display name of the organization
+ type: string
+ required:
+ - orgId
+ - orgDisplayName
+ UsersTeams:
+ type: object
+ properties:
+ teamId:
+ description: |
+ The uniq ID of the team
+ type: string
+ teamDisplayName:
+ description: |
+ The display name of the team
+ type: string
+ required:
+ - teamId
+ - teamDisplayName
UsersEmails:
type: object
properties:
diff --git a/releases/virtualbox/start-wekan.sh b/releases/virtualbox/start-wekan.sh
index 728358d7f..9ee48e671 100755
--- a/releases/virtualbox/start-wekan.sh
+++ b/releases/virtualbox/start-wekan.sh
@@ -382,6 +382,9 @@
#export SAML_LOCAL_PROFILE_MATCH_ATTRIBUTE=
#export SAML_ATTRIBUTES=
#---------------------------------------------------------------------
+ # Wait spinner to use
+ #export WAIT_SPINNER=Bounce
+ #---------------------------------------------------------------------
node main.js & >> ~/repos/wekan.log
cd ~/repos
diff --git a/sandstorm-pkgdef.capnp b/sandstorm-pkgdef.capnp
index 954d6ba88..f8e423f50 100644
--- a/sandstorm-pkgdef.capnp
+++ b/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 = 532,
+ appVersion = 534,
# Increment this for every release.
- appMarketingVersion = (defaultText = "5.32.0~2021-06-09"),
+ appMarketingVersion = (defaultText = "5.34.0~2021-06-11"),
# Human-readable presentation of the app version.
minUpgradableAppVersion = 0,
diff --git a/server/accounts-lockout.js b/server/accounts-lockout.js
index 2eb0409bf..4b9854cfb 100644
--- a/server/accounts-lockout.js
+++ b/server/accounts-lockout.js
@@ -1,21 +1,26 @@
-// https://atmospherejs.com/lucasantoniassi/accounts-lockout
-// server
-import { AccountsLockout } from 'meteor/lucasantoniassi:accounts-lockout';
+Meteor.startup(() => {
+ // https://atmospherejs.com/lucasantoniassi/accounts-lockout
+ // server
-new AccountsLockout({
- knownUsers: {
- failuresBeforeLockout:
- process.env.ACCOUNTS_LOCKOUT_KNOWN_USERS_FAILURES_BEFORE || 3,
- lockoutPeriod: process.env.ACCOUNTS_LOCKOUT_KNOWN_USERS_PERIOD || 60,
- failureWindow:
- process.env.ACCOUNTS_LOCKOUT_KNOWN_USERS_FAILURE_WINDOW || 15,
- },
- unknownUsers: {
- failuresBeforeLockout:
- process.env.ACCOUNTS_LOCKOUT_UNKNOWN_USERS_FAILURES_BERORE || 3,
- lockoutPeriod:
- process.env.ACCOUNTS_LOCKOUT_UNKNOWN_USERS_LOCKOUT_PERIOD || 60,
- failureWindow:
- process.env.ACCOUNTS_LOCKOUT_UNKNOWN_USERS_FAILURE_WINDOW || 15,
- },
-}).startup();
+ if (Meteor.isServer) {
+ import { AccountsLockout } from 'meteor/wekan-accounts-lockout';
+
+ new AccountsLockout({
+ knownUsers: {
+ failuresBeforeLockout:
+ process.env.ACCOUNTS_LOCKOUT_KNOWN_USERS_FAILURES_BEFORE || 3,
+ lockoutPeriod: process.env.ACCOUNTS_LOCKOUT_KNOWN_USERS_PERIOD || 60,
+ failureWindow:
+ process.env.ACCOUNTS_LOCKOUT_KNOWN_USERS_FAILURE_WINDOW || 15,
+ },
+ unknownUsers: {
+ failuresBeforeLockout:
+ process.env.ACCOUNTS_LOCKOUT_UNKNOWN_USERS_FAILURES_BERORE || 3,
+ lockoutPeriod:
+ process.env.ACCOUNTS_LOCKOUT_UNKNOWN_USERS_LOCKOUT_PERIOD || 60,
+ failureWindow:
+ process.env.ACCOUNTS_LOCKOUT_UNKNOWN_USERS_FAILURE_WINDOW || 15,
+ },
+ }).startup();
+ }
+});
diff --git a/server/publications/settings.js b/server/publications/settings.js
index 829824dba..84234e31b 100644
--- a/server/publications/settings.js
+++ b/server/publications/settings.js
@@ -23,6 +23,7 @@ Meteor.publish('setting', () => {
customHTMLbeforeBodyEnd: 1,
displayAuthenticationMethod: 1,
defaultAuthenticationMethod: 1,
+ spinnerName: 1,
},
},
);
diff --git a/server/spinner.js b/server/spinner.js
new file mode 100644
index 000000000..3697ae232
--- /dev/null
+++ b/server/spinner.js
@@ -0,0 +1,3 @@
+Meteor.startup(() => {
+ Meteor.settings.public.WAIT_SPINNER = process.env.WAIT_SPINNER;
+});
diff --git a/snap-src/bin/config b/snap-src/bin/config
index 52c46f365..83ce687be 100755
--- a/snap-src/bin/config
+++ b/snap-src/bin/config
@@ -3,7 +3,7 @@
# All supported keys are defined here together with descriptions and default values
# list of supported keys
-keys="DEBUG MONGO_LOG_DESTINATION MONGO_URL MONGODB_BIND_UNIX_SOCKET MONGO_URL MONGODB_BIND_IP MONGODB_PORT MAIL_URL MAIL_FROM ROOT_URL PORT DISABLE_MONGODB CADDY_ENABLED CADDY_BIND_PORT WITH_API RICHER_CARD_COMMENT_EDITOR CARD_OPENED_WEBHOOK_ENABLED ACCOUNTS_LOCKOUT_KNOWN_USERS_FAILURES_BEFORE ACCOUNTS_LOCKOUT_KNOWN_USERS_PERIOD ACCOUNTS_LOCKOUT_KNOWN_USERS_FAILURE_WINDOW ACCOUNTS_LOCKOUT_UNKNOWN_USERS_FAILURES_BERORE ACCOUNTS_LOCKOUT_UNKNOWN_USERS_LOCKOUT_PERIOD ACCOUNTS_LOCKOUT_UNKNOWN_USERS_FAILURE_WINDOW MAX_IMAGE_PIXEL IMAGE_COMPRESS_RATIO BIGEVENTS_PATTERN NOTIFICATION_TRAY_AFTER_READ_DAYS_BEFORE_REMOVE NOTIFY_DUE_DAYS_BEFORE_AND_AFTER NOTIFY_DUE_AT_HOUR_OF_DAY EMAIL_NOTIFICATION_TIMEOUT CORS CORS_ALLOW_HEADERS CORS_EXPOSE_HEADERS MATOMO_ADDRESS MATOMO_SITE_ID MATOMO_DO_NOT_TRACK MATOMO_WITH_USERNAME BROWSER_POLICY_ENABLED TRUSTED_URL WEBHOOKS_ATTRIBUTES OAUTH2_ENABLED OAUTH2_CA_CERT OAUTH2_LOGIN_STYLE OAUTH2_CLIENT_ID OAUTH2_SECRET OAUTH2_SERVER_URL OAUTH2_AUTH_ENDPOINT OAUTH2_USERINFO_ENDPOINT OAUTH2_TOKEN_ENDPOINT OAUTH2_ID_MAP OAUTH2_USERNAME_MAP OAUTH2_FULLNAME_MAP OAUTH2_ID_TOKEN_WHITELIST_FIELDS OAUTH2_EMAIL_MAP OAUTH2_REQUEST_PERMISSIONS OAUTH2_ADFS_ENABLED LDAP_ENABLE LDAP_PORT LDAP_HOST LDAP_BASEDN LDAP_LOGIN_FALLBACK LDAP_RECONNECT LDAP_TIMEOUT LDAP_IDLE_TIMEOUT LDAP_CONNECT_TIMEOUT LDAP_AUTHENTIFICATION LDAP_AUTHENTIFICATION_USERDN LDAP_AUTHENTIFICATION_PASSWORD LDAP_LOG_ENABLED LDAP_BACKGROUND_SYNC LDAP_BACKGROUND_SYNC_INTERVAL LDAP_BACKGROUND_SYNC_KEEP_EXISTANT_USERS_UPDATED LDAP_BACKGROUND_SYNC_IMPORT_NEW_USERS LDAP_ENCRYPTION LDAP_CA_CERT LDAP_REJECT_UNAUTHORIZED LDAP_USER_AUTHENTICATION LDAP_USER_AUTHENTICATION_FIELD LDAP_USER_SEARCH_FILTER LDAP_USER_SEARCH_SCOPE LDAP_USER_SEARCH_FIELD LDAP_SEARCH_PAGE_SIZE LDAP_SEARCH_SIZE_LIMIT LDAP_GROUP_FILTER_ENABLE LDAP_GROUP_FILTER_OBJECTCLASS LDAP_GROUP_FILTER_GROUP_ID_ATTRIBUTE LDAP_GROUP_FILTER_GROUP_MEMBER_ATTRIBUTE LDAP_GROUP_FILTER_GROUP_MEMBER_FORMAT LDAP_GROUP_FILTER_GROUP_NAME LDAP_UNIQUE_IDENTIFIER_FIELD LDAP_UTF8_NAMES_SLUGIFY LDAP_USERNAME_FIELD LDAP_FULLNAME_FIELD LDAP_MERGE_EXISTING_USERS LDAP_SYNC_USER_DATA LDAP_SYNC_USER_DATA_FIELDMAP LDAP_SYNC_GROUP_ROLES LDAP_DEFAULT_DOMAIN LDAP_EMAIL_MATCH_ENABLE LDAP_EMAIL_MATCH_REQUIRE LDAP_EMAIL_MATCH_VERIFIED LDAP_EMAIL_FIELD LDAP_SYNC_ADMIN_STATUS LDAP_SYNC_ADMIN_GROUPS HEADER_LOGIN_ID HEADER_LOGIN_FIRSTNAME HEADER_LOGIN_LASTNAME HEADER_LOGIN_EMAIL LOGOUT_WITH_TIMER LOGOUT_IN LOGOUT_ON_HOURS LOGOUT_ON_MINUTES DEFAULT_AUTHENTICATION_METHOD ATTACHMENTS_STORE_PATH PASSWORD_LOGIN_ENABLED CAS_ENABLED CAS_BASE_URL CAS_LOGIN_URL CAS_VALIDATE_URL SAML_ENABLED SAML_PROVIDER SAML_ENTRYPOINT SAML_ISSUER SAML_CERT SAML_IDPSLO_REDIRECTURL SAML_PRIVATE_KEYFILE SAML_PUBLIC_CERTFILE SAML_IDENTIFIER_FORMAT SAML_LOCAL_PROFILE_MATCH_ATTRIBUTE SAML_ATTRIBUTES ORACLE_OIM_ENABLED RESULTS_PER_PAGE"
+keys="DEBUG MONGO_LOG_DESTINATION MONGO_URL MONGODB_BIND_UNIX_SOCKET MONGO_URL MONGODB_BIND_IP MONGODB_PORT MAIL_URL MAIL_FROM ROOT_URL PORT DISABLE_MONGODB CADDY_ENABLED CADDY_BIND_PORT WITH_API RICHER_CARD_COMMENT_EDITOR CARD_OPENED_WEBHOOK_ENABLED ACCOUNTS_LOCKOUT_KNOWN_USERS_FAILURES_BEFORE ACCOUNTS_LOCKOUT_KNOWN_USERS_PERIOD ACCOUNTS_LOCKOUT_KNOWN_USERS_FAILURE_WINDOW ACCOUNTS_LOCKOUT_UNKNOWN_USERS_FAILURES_BERORE ACCOUNTS_LOCKOUT_UNKNOWN_USERS_LOCKOUT_PERIOD ACCOUNTS_LOCKOUT_UNKNOWN_USERS_FAILURE_WINDOW MAX_IMAGE_PIXEL IMAGE_COMPRESS_RATIO BIGEVENTS_PATTERN NOTIFICATION_TRAY_AFTER_READ_DAYS_BEFORE_REMOVE NOTIFY_DUE_DAYS_BEFORE_AND_AFTER NOTIFY_DUE_AT_HOUR_OF_DAY EMAIL_NOTIFICATION_TIMEOUT CORS CORS_ALLOW_HEADERS CORS_EXPOSE_HEADERS MATOMO_ADDRESS MATOMO_SITE_ID MATOMO_DO_NOT_TRACK MATOMO_WITH_USERNAME BROWSER_POLICY_ENABLED TRUSTED_URL WEBHOOKS_ATTRIBUTES OAUTH2_ENABLED OAUTH2_CA_CERT OAUTH2_LOGIN_STYLE OAUTH2_CLIENT_ID OAUTH2_SECRET OAUTH2_SERVER_URL OAUTH2_AUTH_ENDPOINT OAUTH2_USERINFO_ENDPOINT OAUTH2_TOKEN_ENDPOINT OAUTH2_ID_MAP OAUTH2_USERNAME_MAP OAUTH2_FULLNAME_MAP OAUTH2_ID_TOKEN_WHITELIST_FIELDS OAUTH2_EMAIL_MAP OAUTH2_REQUEST_PERMISSIONS OAUTH2_ADFS_ENABLED LDAP_ENABLE LDAP_PORT LDAP_HOST LDAP_BASEDN LDAP_LOGIN_FALLBACK LDAP_RECONNECT LDAP_TIMEOUT LDAP_IDLE_TIMEOUT LDAP_CONNECT_TIMEOUT LDAP_AUTHENTIFICATION LDAP_AUTHENTIFICATION_USERDN LDAP_AUTHENTIFICATION_PASSWORD LDAP_LOG_ENABLED LDAP_BACKGROUND_SYNC LDAP_BACKGROUND_SYNC_INTERVAL LDAP_BACKGROUND_SYNC_KEEP_EXISTANT_USERS_UPDATED LDAP_BACKGROUND_SYNC_IMPORT_NEW_USERS LDAP_ENCRYPTION LDAP_CA_CERT LDAP_REJECT_UNAUTHORIZED LDAP_USER_AUTHENTICATION LDAP_USER_AUTHENTICATION_FIELD LDAP_USER_SEARCH_FILTER LDAP_USER_SEARCH_SCOPE LDAP_USER_SEARCH_FIELD LDAP_SEARCH_PAGE_SIZE LDAP_SEARCH_SIZE_LIMIT LDAP_GROUP_FILTER_ENABLE LDAP_GROUP_FILTER_OBJECTCLASS LDAP_GROUP_FILTER_GROUP_ID_ATTRIBUTE LDAP_GROUP_FILTER_GROUP_MEMBER_ATTRIBUTE LDAP_GROUP_FILTER_GROUP_MEMBER_FORMAT LDAP_GROUP_FILTER_GROUP_NAME LDAP_UNIQUE_IDENTIFIER_FIELD LDAP_UTF8_NAMES_SLUGIFY LDAP_USERNAME_FIELD LDAP_FULLNAME_FIELD LDAP_MERGE_EXISTING_USERS LDAP_SYNC_USER_DATA LDAP_SYNC_USER_DATA_FIELDMAP LDAP_SYNC_GROUP_ROLES LDAP_DEFAULT_DOMAIN LDAP_EMAIL_MATCH_ENABLE LDAP_EMAIL_MATCH_REQUIRE LDAP_EMAIL_MATCH_VERIFIED LDAP_EMAIL_FIELD LDAP_SYNC_ADMIN_STATUS LDAP_SYNC_ADMIN_GROUPS HEADER_LOGIN_ID HEADER_LOGIN_FIRSTNAME HEADER_LOGIN_LASTNAME HEADER_LOGIN_EMAIL LOGOUT_WITH_TIMER LOGOUT_IN LOGOUT_ON_HOURS LOGOUT_ON_MINUTES DEFAULT_AUTHENTICATION_METHOD ATTACHMENTS_STORE_PATH PASSWORD_LOGIN_ENABLED CAS_ENABLED CAS_BASE_URL CAS_LOGIN_URL CAS_VALIDATE_URL SAML_ENABLED SAML_PROVIDER SAML_ENTRYPOINT SAML_ISSUER SAML_CERT SAML_IDPSLO_REDIRECTURL SAML_PRIVATE_KEYFILE SAML_PUBLIC_CERTFILE SAML_IDENTIFIER_FORMAT SAML_LOCAL_PROFILE_MATCH_ATTRIBUTE SAML_ATTRIBUTES ORACLE_OIM_ENABLED RESULTS_PER_PAGE WAIT_SPINNER"
# default values
DESCRIPTION_DEBUG="Debug OIDC OAuth2 etc. Example: sudo snap set wekan debug='true'"
@@ -547,3 +547,7 @@ KEY_SAML_ATTRIBUTES="saml-attributes"
DESCRIPTION_RESULTS_PER_PAGE="Number of search results to show per page by default"
DEFAULT_RESULTS_PER_PAGE=""
KEY_RESULTS_PER_PAGE="results-per-page"
+
+DESCRIPTION_WAIT_SPINNER="Default wait spinner to use"
+DEFAULT_WAIT_SPINNER="Bounce"
+KEY_WAIT_SPINNER="wait-spinner"
diff --git a/snap-src/bin/wekan-help b/snap-src/bin/wekan-help
index b544046f6..3f7a4c91c 100755
--- a/snap-src/bin/wekan-help
+++ b/snap-src/bin/wekan-help
@@ -544,6 +544,9 @@ echo -e "\n"
echo -e "SAML Attributes."
echo -e "\t$ snap set $SNAP_NAME saml-attributes=''"
echo -e "\n"
+echo -e "Wait spinner to use."
+echo -e "\t$ snap set $SNAP_NAME wait-spinner='Bounce'"
+echo -e "\n"
# parse config file for supported settings keys
echo -e "wekan supports settings keys"
echo -e "values can be changed by calling\n$ snap set $SNAP_NAME =''"
diff --git a/snapcraft.yaml b/snapcraft.yaml
index ebcddc7dc..e8bdb8005 100644
--- a/snapcraft.yaml
+++ b/snapcraft.yaml
@@ -1,5 +1,5 @@
name: wekan
-version: '5.32'
+version: '5.34'
summary: The open-source kanban
description: |
Wekan is an open-source and collaborative kanban board application.
diff --git a/start-wekan.bat b/start-wekan.bat
index 5779fd6fc..64eeb405d 100644
--- a/start-wekan.bat
+++ b/start-wekan.bat
@@ -418,4 +418,7 @@ REM SET SAML_IDENTIFIER_FORMAT=
REM SET SAML_LOCAL_PROFILE_MATCH_ATTRIBUTE=
REM SET SAML_ATTRIBUTES=
+REM # Wait spinner to use
+REM SET WAIT_SPINNER=Bounce
+
node main.js
diff --git a/start-wekan.sh b/start-wekan.sh
index bbdb4e26c..a4eeb31ae 100755
--- a/start-wekan.sh
+++ b/start-wekan.sh
@@ -388,6 +388,9 @@
#export SAML_LOCAL_PROFILE_MATCH_ATTRIBUTE=
#export SAML_ATTRIBUTES=
#---------------------------------------------------------------------
+ # Wait spinner to use
+ #export WAIT_SPINNER=Bounce
+ #---------------------------------------------------------------------
node main.js
# & >> ../../wekan.log
cd ../..
diff --git a/torodb-postgresql/docker-compose.yml b/torodb-postgresql/docker-compose.yml
index d6497ac4d..29b7effc7 100644
--- a/torodb-postgresql/docker-compose.yml
+++ b/torodb-postgresql/docker-compose.yml
@@ -559,6 +559,9 @@ services:
#- SAML_LOCAL_PROFILE_MATCH_ATTRIBUTE=
#- SAML_ATTRIBUTES=
#---------------------------------------------------------------------
+ # Wait spinner to use
+ #- WAIT_SPINNER=Bounce
+ #---------------------------------------------------------------------
depends_on:
- mongodb